diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 65d0b1915c..b258a2a252 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,13 +6,17 @@ "dockerfile": "Dockerfile", // Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-11, debian-10, debian-9, ubuntu-21.04, ubuntu-20.04, ubuntu-18.04 // Use Debian 11, Debian 9, Ubuntu 18.04 or Ubuntu 21.04 on local arm64/Apple Silicon - "args": { "VARIANT": "ubuntu-21.04" } + "args": { + "VARIANT": "ubuntu-21.04" + } }, - "runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"], - + "runArgs": [ + "--cap-add=SYS_PTRACE", + "--security-opt", + "seccomp=unconfined" + ], // Set *default* container specific settings.json values on container create. "settings": {}, - // Add the IDs of extensions you want installed when the container is created. "extensions": [ "ms-vscode.cpptools", @@ -21,15 +25,13 @@ "visualstudioexptteam.vscodeintel", "eamodio.gitlens", "matepek.vscode-catch2-test-adapter", - "spmeesseman.vscode-taskexplorer" + "spmeesseman.vscode-taskexplorer", + "cschlosser.doxdocgen" ], - // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], - // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "gcc -v", - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "root" -} +} \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile index c47d37a9a0..fc2b3562c1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -105,232 +105,19 @@ pipeline { abort_previous() abortPreviousBuilds() } - pre_test() - sh''' - cd ${WKC}/tests - ./test-all.sh b1fq - ''' + timeout(time: 45, unit: 'MINUTES'){ + pre_test() + sh''' + cd ${WKC}/tests + ./test-all.sh b1fq + ''' + sh''' + cd ${WKC}/debug + ctest + ''' + } } } - // stage('Parallel test stage') { - // skip defaultCheckout - // options { skipDefaultCheckout() } - // when { - // allOf{ - // changeRequest() - - // } - // } - // parallel { - // stage('python_1_s1') { - // agent{label " slave1 || slave11 "} - // steps { - - // pre_test() - // // timeout(time: 55, unit: 'MINUTES'){ - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh p1 - // // date''' - // // } - - // } - // } - // stage('python_2_s5') { - // agent{label " slave5 || slave15 "} - // steps { - - // pre_test() - // // timeout(time: 55, unit: 'MINUTES'){ - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh p2 - // // date''' - // // } - // } - // } - // stage('python_3_s6') { - // agent{label " slave6 || slave16 "} - // steps { - // pre_test() - // // timeout(time: 55, unit: 'MINUTES'){ - - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh p3 - // // date''' - // // } - // } - // } - // stage('test_b1_s2') { - // agent{label " slave2 || slave12 "} - // steps { - // pre_test() - // // timeout(time: 55, unit: 'MINUTES'){ - - // // sh ''' - // // rm -rf /var/lib/taos/* - // // rm -rf /var/log/taos/* - // // nohup taosd >/dev/null & - // // sleep 10 - // // ''' - // // sh ''' - // // cd ${WKC}/tests/examples/nodejs - // // npm install td2.0-connector > /dev/null 2>&1 - // // node nodejsChecker.js host=localhost - // // node test1970.js - // // cd ${WKC}/tests/connectorTest/nodejsTest/nanosupport - // // npm install td2.0-connector > /dev/null 2>&1 - // // node nanosecondTest.js - - // // ''' - // // sh ''' - // // cd ${WKC}/tests/examples/C#/taosdemo - // // mcs -out:taosdemo *.cs > /dev/null 2>&1 - // // echo '' |./taosdemo -c /etc/taos - // // cd ${WKC}/tests/connectorTest/C#Test/nanosupport - // // mcs -out:nano *.cs > /dev/null 2>&1 - // // echo '' |./nano - // // ''' - // // sh ''' - // // cd ${WKC}/tests/gotest - // // bash batchtest.sh - // // ''' - // // sh ''' - // // cd ${WKC}/tests - // // ./test-all.sh b1fq - // // date''' - // // } - // } - // } - // stage('test_crash_gen_s3') { - // agent{label " slave3 || slave13 "} - - // steps { - // pre_test() - // // timeout(time: 60, unit: 'MINUTES'){ - // // sh ''' - // // cd ${WKC}/tests/pytest - // // ./crash_gen.sh -a -p -t 4 -s 2000 - // // ''' - // // } - // // timeout(time: 60, unit: 'MINUTES'){ - // // // sh ''' - // // // cd ${WKC}/tests/pytest - // // // rm -rf /var/lib/taos/* - // // // rm -rf /var/log/taos/* - // // // ./handle_crash_gen_val_log.sh - // // // ''' - // // sh ''' - // // cd ${WKC}/tests/pytest - // // rm -rf /var/lib/taos/* - // // rm -rf /var/log/taos/* - // // ./handle_taosd_val_log.sh - // // ''' - // // } - // // timeout(time: 55, unit: 'MINUTES'){ - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh b2fq - // // date - // // ''' - // // } - // } - // } - // stage('test_valgrind_s4') { - // agent{label " slave4 || slave14 "} - - // steps { - // pre_test() - // // catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - // // sh ''' - // // cd ${WKC}/tests/pytest - // // ./valgrind-test.sh 2>&1 > mem-error-out.log - // // ./handle_val_log.sh - // // ''' - // // } - // // timeout(time: 55, unit: 'MINUTES'){ - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh b3fq - // // date''' - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh full example - // // date''' - // // } - // } - // } - // stage('test_b4_s7') { - // agent{label " slave7 || slave17 "} - // steps { - // pre_test() - // // timeout(time: 55, unit: 'MINUTES'){ - - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh b4fq - // // cd ${WKC}/tests - // // ./test-all.sh p4 - // // cd ${WKC}/tests - // // ./test-all.sh full jdbc - // // cd ${WKC}/tests - // // ./test-all.sh full unit - // // date''' - // // } - // } - // } - // stage('test_b5_s8') { - // agent{label " slave8 || slave18 "} - // steps { - // pre_test() - // // timeout(time: 55, unit: 'MINUTES'){ - - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh b5fq - // // date''' - // // } - // } - // } - // stage('test_b6_s9') { - // agent{label " slave9 || slave19 "} - // steps { - // pre_test() - // // timeout(time: 55, unit: 'MINUTES'){ - - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh b6fq - // // date''' - // // } - // } - // } - // stage('test_b7_s10') { - // agent{label " slave10 || slave20 "} - // steps { - // pre_test() - // // timeout(time: 55, unit: 'MINUTES'){ - - // // sh ''' - // // date - // // cd ${WKC}/tests - // // ./test-all.sh b7fq - // // date''' - // // } - // } - // } - // } - // } } post { success { diff --git a/contrib/test/craft/raftServer.h b/contrib/test/craft/raftServer.h index 5fccde6bf2..f4087cf1a9 100644 --- a/contrib/test/craft/raftServer.h +++ b/contrib/test/craft/raftServer.h @@ -48,10 +48,11 @@ int32_t raftServerInit(SRaftServer *pRaftServer, const SRaftServerConfig *pConf, int32_t raftServerStart(SRaftServer *pRaftServer); void raftServerClose(SRaftServer *pRaftServer); - int initFsm(struct raft_fsm *fsm); - +const char* state2String(unsigned short state); +void printRaftConfiguration(struct raft_configuration *c); +void printRaftState(struct raft *r); #ifdef __cplusplus diff --git a/contrib/test/traft/CMakeLists.txt b/contrib/test/traft/CMakeLists.txt index e29fea04f1..d165c6d4dc 100644 --- a/contrib/test/traft/CMakeLists.txt +++ b/contrib/test/traft/CMakeLists.txt @@ -1,7 +1,3 @@ -add_executable(raftMain "") -target_sources(raftMain - PRIVATE - "raftMain.c" - "raftServer.c" -) -target_link_libraries(raftMain PUBLIC traft lz4 uv_a) +add_subdirectory(rebalance_leader) +add_subdirectory(make_cluster) + diff --git a/contrib/test/traft/make_cluster/CMakeLists.txt b/contrib/test/traft/make_cluster/CMakeLists.txt new file mode 100644 index 0000000000..afd19d5435 --- /dev/null +++ b/contrib/test/traft/make_cluster/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(makeCluster "") +target_sources(makeCluster + PRIVATE + "raftMain.c" + "raftServer.c" + "config.c" + "console.c" + "simpleHash.c" + "util.c" +) +target_link_libraries(makeCluster PUBLIC traft lz4 uv_a) diff --git a/contrib/test/traft/clear.sh b/contrib/test/traft/make_cluster/clear.sh similarity index 100% rename from contrib/test/traft/clear.sh rename to contrib/test/traft/make_cluster/clear.sh diff --git a/contrib/test/traft/make_cluster/common.h b/contrib/test/traft/make_cluster/common.h new file mode 100644 index 0000000000..df7422033a --- /dev/null +++ b/contrib/test/traft/make_cluster/common.h @@ -0,0 +1,23 @@ +#ifndef TRAFT_COMMON_H +#define TRAFT_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define COMMAND_LEN 512 +#define MAX_CMD_COUNT 10 +#define TOKEN_LEN 128 +#define MAX_PEERS_COUNT 19 + +#define HOST_LEN 64 +#define ADDRESS_LEN (HOST_LEN * 2) +#define BASE_DIR_LEN 128 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/test/traft/make_cluster/config.c b/contrib/test/traft/make_cluster/config.c new file mode 100644 index 0000000000..3b96839fd9 --- /dev/null +++ b/contrib/test/traft/make_cluster/config.c @@ -0,0 +1,64 @@ +#include "config.h" +#include +#include +#include + +void addrToString(const char *host, uint16_t port, char *addr, int len) { snprintf(addr, len, "%s:%hu", host, port); } + +void parseAddr(const char *addr, char *host, int len, uint16_t *port) { + char *tmp = (char *)malloc(strlen(addr) + 1); + strcpy(tmp, addr); + + char *context; + char *separator = ":"; + char *token = strtok_r(tmp, separator, &context); + if (token) { + snprintf(host, len, "%s", token); + } + + token = strtok_r(NULL, separator, &context); + if (token) { + sscanf(token, "%hu", port); + } + + free(tmp); +} + +int parseConf(int argc, char **argv, RaftServerConfig *pConf) { + memset(pConf, 0, sizeof(*pConf)); + + int option_index, option_value; + option_index = 0; + static struct option long_options[] = {{"help", no_argument, NULL, 'h'}, + {"addr", required_argument, NULL, 'a'}, + {"dir", required_argument, NULL, 'd'}, + {NULL, 0, NULL, 0}}; + + while ((option_value = getopt_long(argc, argv, "ha:d:", long_options, &option_index)) != -1) { + switch (option_value) { + case 'a': { + parseAddr(optarg, pConf->me.host, sizeof(pConf->me.host), &pConf->me.port); + break; + } + + case 'd': { + snprintf(pConf->baseDir, sizeof(pConf->baseDir), "%s", optarg); + break; + } + + case 'h': { + return -2; + } + + default: { return -2; } + } + } + + return 0; +} + +void printConf(RaftServerConfig *pConf) { + printf("\n---printConf: \n"); + printf("me: [%s:%hu] \n", pConf->me.host, pConf->me.port); + printf("dataDir: [%s] \n\n", pConf->baseDir); +} diff --git a/contrib/test/traft/make_cluster/config.h b/contrib/test/traft/make_cluster/config.h new file mode 100644 index 0000000000..13c43d0d28 --- /dev/null +++ b/contrib/test/traft/make_cluster/config.h @@ -0,0 +1,31 @@ +#ifndef TRAFT_CONFIG_H +#define TRAFT_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "common.h" + +typedef struct { + char host[HOST_LEN]; + uint16_t port; +} Addr; + +typedef struct { + Addr me; + char baseDir[BASE_DIR_LEN]; +} RaftServerConfig; + +void addrToString(const char *host, uint16_t port, char *addr, int len); +void parseAddr(const char *addr, char *host, int len, uint16_t *port); +int parseConf(int argc, char **argv, RaftServerConfig *pConf); +void printConf(RaftServerConfig *pConf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/test/traft/make_cluster/console.c b/contrib/test/traft/make_cluster/console.c new file mode 100644 index 0000000000..b00550c681 --- /dev/null +++ b/contrib/test/traft/make_cluster/console.c @@ -0,0 +1,202 @@ +#include "console.h" +#include +#include +#include +#include "raftServer.h" +#include "util.h" + +void printHelp() { + printf("---------------------\n"); + printf("help: \n\n"); + printf("create a vgroup with 3 replicas: \n"); + printf("create vnode voter vid 100 peers 127.0.0.1:10001 127.0.0.1:10002 \n"); + printf("create vnode voter vid 100 peers 127.0.0.1:10000 127.0.0.1:10002 \n"); + printf("create vnode voter vid 100 peers 127.0.0.1:10000 127.0.0.1:10001 \n"); + printf("\n"); + printf("create a vgroup with only one replica: \n"); + printf("create vnode voter vid 200 \n"); + printf("\n"); + printf("add vnode into vgroup: \n"); + printf("create vnode spare vid 100 ---- run at 127.0.0.1:10003\n"); + printf("join vnode vid 100 addr 127.0.0.1:10003 ---- run at leader of vgroup 100\n"); + printf("\n"); + printf("run \n"); + printf("put 0 key value \n"); + printf("get 0 key \n"); + printf("---------------------\n"); +} + +void console(RaftServer *pRaftServer) { + while (1) { + int ret; + char cmdBuf[COMMAND_LEN]; + memset(cmdBuf, 0, sizeof(cmdBuf)); + printf("(console)> "); + char *retp = fgets(cmdBuf, COMMAND_LEN, stdin); + if (!retp) { + exit(-1); + } + + int pos = strlen(cmdBuf); + if (cmdBuf[pos - 1] == '\n') { + cmdBuf[pos - 1] = '\0'; + } + + if (strncmp(cmdBuf, "", COMMAND_LEN) == 0) { + continue; + } + + char cmds[MAX_CMD_COUNT][TOKEN_LEN]; + memset(cmds, 0, sizeof(cmds)); + + int cmdCount; + cmdCount = splitString(cmdBuf, " ", cmds, MAX_CMD_COUNT); + + if (strcmp(cmds[0], "create") == 0 && strcmp(cmds[1], "vnode") == 0 && strcmp(cmds[3], "vid") == 0) { + uint16_t vid; + sscanf(cmds[4], "%hu", &vid); + + if (strcmp(cmds[2], "voter") == 0) { + char peers[MAX_PEERS_COUNT][ADDRESS_LEN]; + memset(peers, 0, sizeof(peers)); + uint32_t peersCount = 0; + + if (strcmp(cmds[5], "peers") == 0 && cmdCount > 6) { + // create vnode voter vid 100 peers 127.0.0.1:10001 127.0.0.1:10002 + for (int i = 6; i < cmdCount; ++i) { + snprintf(peers[i - 6], ADDRESS_LEN, "%s", cmds[i]); + peersCount++; + } + } else { + // create vnode voter vid 200 + } + ret = addRaftVoter(pRaftServer, peers, peersCount, vid); + if (ret == 0) { + printf("create vnode voter ok \n"); + } else { + printf("create vnode voter error \n"); + } + } else if (strcmp(cmds[2], "spare") == 0) { + ret = addRaftSpare(pRaftServer, vid); + if (ret == 0) { + printf("create vnode spare ok \n"); + } else { + printf("create vnode spare error \n"); + } + } else { + printHelp(); + } + + } else if (strcmp(cmds[0], "join") == 0 && strcmp(cmds[1], "vnode") == 0 && strcmp(cmds[2], "vid") == 0 && + strcmp(cmds[4], "addr") == 0 && cmdCount == 6) { + // join vnode vid 100 addr 127.0.0.1:10004 + + char * address = cmds[5]; + char host[64]; + uint16_t port; + parseAddr(address, host, sizeof(host), &port); + + uint16_t vid; + sscanf(cmds[3], "%hu", &vid); + + HashNode **pp = pRaftServer->raftInstances.find(&pRaftServer->raftInstances, vid); + if (*pp == NULL) { + printf("vid:%hu not found \n", vid); + break; + } + RaftInstance *pRaftInstance = (*pp)->data; + + uint64_t destRaftId = encodeRaftId(host, port, vid); + + struct raft_change *req = raft_malloc(sizeof(*req)); + RaftJoin * pRaftJoin = raft_malloc(sizeof(*pRaftJoin)); + pRaftJoin->r = &pRaftInstance->raft; + pRaftJoin->joinId = destRaftId; + req->data = pRaftJoin; + ret = raft_add(&pRaftInstance->raft, req, destRaftId, address, raftChangeAddCb); + if (ret != 0) { + printf("raft_add error: %s \n", raft_errmsg(&pRaftInstance->raft)); + } + + } else if (strcmp(cmds[0], "dropnode") == 0) { + } else if (strcmp(cmds[0], "state") == 0) { + pRaftServer->raftInstances.print(&pRaftServer->raftInstances); + for (size_t i = 0; i < pRaftServer->raftInstances.length; ++i) { + HashNode *ptr = pRaftServer->raftInstances.table[i]; + if (ptr != NULL) { + while (ptr != NULL) { + RaftInstance *pRaftInstance = ptr->data; + printf("instance vid:%hu raftId:%llu \n", ptr->vgroupId, pRaftInstance->raftId); + printRaftState(&pRaftInstance->raft); + printf("\n"); + ptr = ptr->next; + } + printf("\n"); + } + } + + } else if (strcmp(cmds[0], "put") == 0 && cmdCount == 4) { + uint16_t vid; + sscanf(cmds[1], "%hu", &vid); + char * key = cmds[2]; + char * value = cmds[3]; + HashNode **pp = pRaftServer->raftInstances.find(&pRaftServer->raftInstances, vid); + if (*pp == NULL) { + printf("vid:%hu not found \n", vid); + break; + } + RaftInstance *pRaftInstance = (*pp)->data; + + char *raftValue = malloc(TOKEN_LEN * 2 + 3); + snprintf(raftValue, TOKEN_LEN * 2 + 3, "%s--%s", key, value); + putValue(&pRaftInstance->raft, raftValue); + free(raftValue); + + } else if (strcmp(cmds[0], "run") == 0) { + pthread_t tidRaftServer; + pthread_create(&tidRaftServer, NULL, startServerFunc, pRaftServer); + + } else if (strcmp(cmds[0], "get") == 0 && cmdCount == 3) { + uint16_t vid; + sscanf(cmds[1], "%hu", &vid); + char * key = cmds[2]; + HashNode **pp = pRaftServer->raftInstances.find(&pRaftServer->raftInstances, vid); + if (*pp == NULL) { + printf("vid:%hu not found \n", vid); + break; + } + RaftInstance * pRaftInstance = (*pp)->data; + SimpleHash * pKV = pRaftInstance->fsm.data; + SimpleHashNode **ppNode = pKV->find_cstr(pKV, key); + if (*ppNode == NULL) { + printf("key:%s not found \n", key); + } else { + printf("find key:%s value:%s \n", key, (char *)((*ppNode)->data)); + } + + } else if (strcmp(cmds[0], "transfer") == 0) { + } else if (strcmp(cmds[0], "state") == 0) { + } else if (strcmp(cmds[0], "snapshot") == 0) { + } else if (strcmp(cmds[0], "exit") == 0) { + exit(0); + + } else if (strcmp(cmds[0], "quit") == 0) { + exit(0); + + } else if (strcmp(cmds[0], "help") == 0) { + printHelp(); + + } else { + printf("unknown command: %s \n", cmdBuf); + printHelp(); + } + + /* + printf("cmdBuf: [%s] \n", cmdBuf); + printf("cmdCount : %d \n", cmdCount); + for (int i = 0; i < MAX_CMD_COUNT; ++i) { + printf("cmd%d : %s \n", i, cmds[i]); + } + */ + } +} diff --git a/contrib/test/traft/make_cluster/console.h b/contrib/test/traft/make_cluster/console.h new file mode 100644 index 0000000000..f9ed12baf5 --- /dev/null +++ b/contrib/test/traft/make_cluster/console.h @@ -0,0 +1,19 @@ +#ifndef TRAFT_CONSOLE_H +#define TRAFT_CONSOLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "common.h" +#include "raftServer.h" + +void console(RaftServer *pRaftServer); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/test/traft/make_cluster/raftMain.c b/contrib/test/traft/make_cluster/raftMain.c new file mode 100644 index 0000000000..e25636de91 --- /dev/null +++ b/contrib/test/traft/make_cluster/raftMain.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "config.h" +#include "console.h" +#include "raftServer.h" +#include "simpleHash.h" +#include "util.h" + +const char *exe_name; + +void *startConsoleFunc(void *param) { + RaftServer *pRaftServer = (RaftServer *)param; + console(pRaftServer); + return NULL; +} + +void usage() { + printf("\nusage: \n"); + printf("%s --addr=127.0.0.1:10000 --dir=./data \n", exe_name); + printf("\n"); +} + +RaftServerConfig gConfig; +RaftServer gRaftServer; + +int main(int argc, char **argv) { + srand(time(NULL)); + int32_t ret; + + exe_name = argv[0]; + if (argc < 3) { + usage(); + exit(-1); + } + + ret = parseConf(argc, argv, &gConfig); + if (ret != 0) { + usage(); + exit(-1); + } + printConf(&gConfig); + + if (!dirOK(gConfig.baseDir)) { + ret = mkdir(gConfig.baseDir, 0775); + if (ret != 0) { + fprintf(stderr, "mkdir error, %s \n", gConfig.baseDir); + exit(-1); + } + } + + ret = raftServerInit(&gRaftServer, &gConfig); + if (ret != 0) { + fprintf(stderr, "raftServerInit error \n"); + exit(-1); + } + + /* + pthread_t tidRaftServer; + pthread_create(&tidRaftServer, NULL, startServerFunc, &gRaftServer); + */ + + pthread_t tidConsole; + pthread_create(&tidConsole, NULL, startConsoleFunc, &gRaftServer); + + while (1) { + sleep(10); + } + + return 0; +} diff --git a/contrib/test/traft/make_cluster/raftServer.c b/contrib/test/traft/make_cluster/raftServer.c new file mode 100644 index 0000000000..bbf67b9420 --- /dev/null +++ b/contrib/test/traft/make_cluster/raftServer.c @@ -0,0 +1,286 @@ +#include "raftServer.h" +#include +#include +#include "common.h" +#include "simpleHash.h" +#include "util.h" + +void *startServerFunc(void *param) { + RaftServer *pRaftServer = (RaftServer *)param; + int32_t r = raftServerStart(pRaftServer); + assert(r == 0); + return NULL; +} + +void raftChangeAssignCb(struct raft_change *req, int status) { + struct raft *r = req->data; + if (status != 0) { + printf("raftChangeAssignCb error: %s \n", raft_errmsg(r)); + } else { + printf("raftChangeAssignCb ok \n"); + } + raft_free(req); +} + +void raftChangeAddCb(struct raft_change *req, int status) { + RaftJoin *pRaftJoin = req->data; + if (status != 0) { + printf("raftChangeAddCb error: %s \n", raft_errmsg(pRaftJoin->r)); + } else { + struct raft_change *req2 = raft_malloc(sizeof(*req2)); + req2->data = pRaftJoin->r; + int ret = raft_assign(pRaftJoin->r, req2, pRaftJoin->joinId, RAFT_VOTER, raftChangeAssignCb); + if (ret != 0) { + printf("raftChangeAddCb error: %s \n", raft_errmsg(pRaftJoin->r)); + } + } + raft_free(req->data); + raft_free(req); +} + +int fsmApplyCb(struct raft_fsm *pFsm, const struct raft_buffer *buf, void **result) { + // get fsm data + SimpleHash *sh = pFsm->data; + + // get commit value + char *msg = (char *)buf->base; + printf("fsm apply: [%s] \n", msg); + char arr[2][TOKEN_LEN]; + int r = splitString(msg, "--", arr, 2); + assert(r == 2); + + // do the value on fsm + sh->insert_cstr(sh, arr[0], arr[1]); + + raft_free(buf->base); + return 0; +} + +void putValueCb(struct raft_apply *req, int status, void *result) { + struct raft *r = req->data; + if (status != 0) { + printf("putValueCb error: %s \n", raft_errmsg(r)); + } else { + printf("putValueCb: %s \n", "ok"); + } + raft_free(req); +} + +void putValue(struct raft *r, const char *value) { + struct raft_buffer buf; + + buf.len = strlen(value) + 1; + buf.base = raft_malloc(buf.len); + snprintf(buf.base, buf.len, "%s", value); + + struct raft_apply *req = raft_malloc(sizeof(*req)); + req->data = r; + int ret = raft_apply(r, req, &buf, 1, putValueCb); + if (ret == 0) { + printf("put %s \n", (char *)buf.base); + } else { + printf("put error: %s \n", raft_errmsg(r)); + } +} + +const char *state2String(unsigned short state) { + if (state == RAFT_UNAVAILABLE) { + return "RAFT_UNAVAILABLE"; + + } else if (state == RAFT_FOLLOWER) { + return "RAFT_FOLLOWER"; + + } else if (state == RAFT_CANDIDATE) { + return "RAFT_CANDIDATE"; + + } else if (state == RAFT_LEADER) { + return "RAFT_LEADER"; + } + return "UNKNOWN_RAFT_STATE"; +} + +void printRaftConfiguration(struct raft_configuration *c) { + printf("configuration: \n"); + for (int i = 0; i < c->n; ++i) { + printf("%llu -- %d -- %s\n", c->servers[i].id, c->servers[i].role, c->servers[i].address); + } +} + +void printRaftState(struct raft *r) { + printf("----Raft State: -----------\n"); + printf("mem_addr: %p \n", r); + printf("my_id: %llu \n", r->id); + printf("address: %s \n", r->address); + printf("current_term: %llu \n", r->current_term); + printf("voted_for: %llu \n", r->voted_for); + printf("role: %s \n", state2String(r->state)); + printf("commit_index: %llu \n", r->commit_index); + printf("last_applied: %llu \n", r->last_applied); + printf("last_stored: %llu \n", r->last_stored); + + printf("configuration_index: %llu \n", r->configuration_index); + printf("configuration_uncommitted_index: %llu \n", r->configuration_uncommitted_index); + printRaftConfiguration(&r->configuration); + + printf("----------------------------\n"); +} + +int32_t addRaftVoter(RaftServer *pRaftServer, char peers[][ADDRESS_LEN], uint32_t peersCount, uint16_t vid) { + int ret; + + RaftInstance *pRaftInstance = malloc(sizeof(*pRaftInstance)); + assert(pRaftInstance != NULL); + + // init raftId + pRaftInstance->raftId = encodeRaftId(pRaftServer->host, pRaftServer->port, vid); + + // init dir + snprintf(pRaftInstance->dir, sizeof(pRaftInstance->dir), "%s/%s_%hu_%hu_%llu", pRaftServer->baseDir, + pRaftServer->host, pRaftServer->port, vid, pRaftInstance->raftId); + + if (!dirOK(pRaftInstance->dir)) { + ret = mkdir(pRaftInstance->dir, 0775); + if (ret != 0) { + fprintf(stderr, "mkdir error, %s \n", pRaftInstance->dir); + assert(0); + } + } + + // init fsm + pRaftInstance->fsm.data = newSimpleHash(2); + pRaftInstance->fsm.apply = fsmApplyCb; + + // init io + ret = raft_uv_init(&pRaftInstance->io, &pRaftServer->loop, pRaftInstance->dir, &pRaftServer->transport); + if (ret != 0) { + fprintf(stderr, "raft_uv_init error, %s \n", raft_errmsg(&pRaftInstance->raft)); + assert(0); + } + + // init raft + ret = raft_init(&pRaftInstance->raft, &pRaftInstance->io, &pRaftInstance->fsm, pRaftInstance->raftId, + pRaftServer->address); + if (ret != 0) { + fprintf(stderr, "raft_init error, %s \n", raft_errmsg(&pRaftInstance->raft)); + assert(0); + } + + // init raft_configuration + struct raft_configuration conf; + raft_configuration_init(&conf); + raft_configuration_add(&conf, pRaftInstance->raftId, pRaftServer->address, RAFT_VOTER); + for (int i = 0; i < peersCount; ++i) { + char * peerAddress = peers[i]; + char host[64]; + uint16_t port; + parseAddr(peerAddress, host, sizeof(host), &port); + uint64_t raftId = encodeRaftId(host, port, vid); + raft_configuration_add(&conf, raftId, peers[i], RAFT_VOTER); + } + raft_bootstrap(&pRaftInstance->raft, &conf); + + // start raft + ret = raft_start(&pRaftInstance->raft); + if (ret != 0) { + fprintf(stderr, "raft_start error, %s \n", raft_errmsg(&pRaftInstance->raft)); + assert(0); + } + + // add raft instance into raft server + pRaftServer->raftInstances.insert(&pRaftServer->raftInstances, vid, pRaftInstance); + + return 0; +} + +int32_t addRaftSpare(RaftServer *pRaftServer, uint16_t vid) { + int ret; + + RaftInstance *pRaftInstance = malloc(sizeof(*pRaftInstance)); + assert(pRaftInstance != NULL); + + // init raftId + pRaftInstance->raftId = encodeRaftId(pRaftServer->host, pRaftServer->port, vid); + + // init dir + snprintf(pRaftInstance->dir, sizeof(pRaftInstance->dir), "%s/%s_%hu_%hu_%llu", pRaftServer->baseDir, + pRaftServer->host, pRaftServer->port, vid, pRaftInstance->raftId); + ret = mkdir(pRaftInstance->dir, 0775); + if (ret != 0) { + fprintf(stderr, "mkdir error, %s \n", pRaftInstance->dir); + assert(0); + } + + // init fsm + pRaftInstance->fsm.data = newSimpleHash(2); + pRaftInstance->fsm.apply = fsmApplyCb; + + // init io + ret = raft_uv_init(&pRaftInstance->io, &pRaftServer->loop, pRaftInstance->dir, &pRaftServer->transport); + if (ret != 0) { + fprintf(stderr, "raft_uv_init error, %s \n", raft_errmsg(&pRaftInstance->raft)); + assert(0); + } + + // init raft + ret = raft_init(&pRaftInstance->raft, &pRaftInstance->io, &pRaftInstance->fsm, pRaftInstance->raftId, + pRaftServer->address); + if (ret != 0) { + fprintf(stderr, "raft_init error, %s \n", raft_errmsg(&pRaftInstance->raft)); + assert(0); + } + + // init raft_configuration + struct raft_configuration conf; + raft_configuration_init(&conf); + raft_configuration_add(&conf, pRaftInstance->raftId, pRaftServer->address, RAFT_SPARE); + raft_bootstrap(&pRaftInstance->raft, &conf); + + // start raft + ret = raft_start(&pRaftInstance->raft); + if (ret != 0) { + fprintf(stderr, "raft_start error, %s \n", raft_errmsg(&pRaftInstance->raft)); + assert(0); + } + + // add raft instance into raft server + pRaftServer->raftInstances.insert(&pRaftServer->raftInstances, vid, pRaftInstance); + + return 0; +} + +int32_t raftServerInit(RaftServer *pRaftServer, const RaftServerConfig *pConf) { + int ret; + + // init host, port, address, dir + snprintf(pRaftServer->host, sizeof(pRaftServer->host), "%s", pConf->me.host); + pRaftServer->port = pConf->me.port; + snprintf(pRaftServer->address, sizeof(pRaftServer->address), "%s:%u", pRaftServer->host, pRaftServer->port); + snprintf(pRaftServer->baseDir, sizeof(pRaftServer->baseDir), "%s", pConf->baseDir); + + // init loop + ret = uv_loop_init(&pRaftServer->loop); + if (ret != 0) { + fprintf(stderr, "uv_loop_init error: %s \n", uv_strerror(ret)); + assert(0); + } + + // init network + ret = raft_uv_tcp_init(&pRaftServer->transport, &pRaftServer->loop); + if (ret != 0) { + fprintf(stderr, "raft_uv_tcp_init: error %d \n", ret); + assert(0); + } + + // init raft instance container + initIdHash(&pRaftServer->raftInstances, 2); + + return 0; +} + +int32_t raftServerStart(RaftServer *pRaftServer) { + // start loop + uv_run(&pRaftServer->loop, UV_RUN_DEFAULT); + return 0; +} + +void raftServerStop(RaftServer *pRaftServer) {} diff --git a/contrib/test/traft/make_cluster/raftServer.h b/contrib/test/traft/make_cluster/raftServer.h new file mode 100644 index 0000000000..b6dbddb2b7 --- /dev/null +++ b/contrib/test/traft/make_cluster/raftServer.h @@ -0,0 +1,66 @@ +#ifndef TDENGINE_RAFT_SERVER_H +#define TDENGINE_RAFT_SERVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include "common.h" +#include "config.h" +#include "raft.h" +#include "raft/uv.h" +#include "simpleHash.h" + +typedef struct RaftJoin { + struct raft *r; + raft_id joinId; +} RaftJoin; + +typedef struct { + raft_id raftId; + char dir[BASE_DIR_LEN * 2]; + struct raft_fsm fsm; + struct raft_io io; + struct raft raft; +} RaftInstance; + +typedef struct { + char host[HOST_LEN]; + uint16_t port; + char address[ADDRESS_LEN]; /* Raft instance address */ + char baseDir[BASE_DIR_LEN]; /* Raft instance address */ + + struct uv_loop_s loop; /* UV loop */ + struct raft_uv_transport transport; /* UV I/O backend transport */ + + IdHash raftInstances; /* multi raft instances. traft use IdHash to manager multi vgroup inside, here we can use IdHash + too. */ +} RaftServer; + +void * startServerFunc(void *param); +int32_t addRaftVoter(RaftServer *pRaftServer, char peers[][ADDRESS_LEN], uint32_t peersCount, uint16_t vid); +int32_t addRaftSpare(RaftServer *pRaftServer, uint16_t vid); + +int32_t raftServerInit(RaftServer *pRaftServer, const RaftServerConfig *pConf); +int32_t raftServerStart(RaftServer *pRaftServer); +void raftServerStop(RaftServer *pRaftServer); + +int fsmApplyCb(struct raft_fsm *pFsm, const struct raft_buffer *buf, void **result); +void putValueCb(struct raft_apply *req, int status, void *result); +void putValue(struct raft *r, const char *value); + +void raftChangeAddCb(struct raft_change *req, int status); + +const char *state2String(unsigned short state); +void printRaftConfiguration(struct raft_configuration *c); +void printRaftState(struct raft *r); + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_RAFT_SERVER_H diff --git a/contrib/test/traft/make_cluster/simpleHash.c b/contrib/test/traft/make_cluster/simpleHash.c new file mode 100644 index 0000000000..6694843874 --- /dev/null +++ b/contrib/test/traft/make_cluster/simpleHash.c @@ -0,0 +1,218 @@ +#include "simpleHash.h" + +uint32_t mySimpleHash(const char* data, size_t n, uint32_t seed) { + // Similar to murmur hash + const uint32_t m = 0xc6a4a793; + const uint32_t r = 24; + const char* limit = data + n; + uint32_t h = seed ^ (n * m); + + // Pick up four bytes at a time + while (data + 4 <= limit) { + // uint32_t w = DecodeFixed32(data); + uint32_t w; + memcpy(&w, data, 4); + + data += 4; + h += w; + h *= m; + h ^= (h >> 16); + } + + // Pick up remaining bytes + switch (limit - data) { + case 3: + h += (unsigned char)(data[2]) << 16; + do { + } while (0); + case 2: + h += (unsigned char)(data[1]) << 8; + do { + } while (0); + case 1: + h += (unsigned char)(data[0]); + h *= m; + h ^= (h >> r); + break; + } + return h; +} + +int insertCStrSimpleHash(struct SimpleHash* ths, char* key, char* data) { + return insertSimpleHash(ths, key, strlen(key) + 1, data, strlen(data) + 1); +} + +int removeCStrSimpleHash(struct SimpleHash* ths, char* key) { return removeSimpleHash(ths, key, strlen(key) + 1); } + +SimpleHashNode** findCStrSimpleHash(struct SimpleHash* ths, char* key) { + return findSimpleHash(ths, key, strlen(key) + 1); +} + +int insertSimpleHash(struct SimpleHash* ths, char* key, size_t keyLen, char* data, size_t dataLen) { + SimpleHashNode** pp = ths->find(ths, key, keyLen); + if (*pp != NULL) { + fprintf(stderr, "insertSimpleHash, already has key \n"); + return -1; + } + + SimpleHashNode* node = malloc(sizeof(*node)); + node->hashCode = ths->hashFunc(key, keyLen); + node->key = malloc(keyLen); + node->keyLen = keyLen; + memcpy(node->key, key, keyLen); + node->data = malloc(dataLen); + node->dataLen = dataLen; + memcpy(node->data, data, dataLen); + node->next = NULL; + + // printf("insertSimpleHash: <%s, %ld, %s, %ld, %u> \n", node->key, node->keyLen, node->data, node->dataLen, + // node->hashCode); + + size_t index = node->hashCode & (ths->length - 1); + + SimpleHashNode* ptr = ths->table[index]; + if (ptr != NULL) { + node->next = ptr; + ths->table[index] = node; + + } else { + ths->table[index] = node; + } + ths->elems++; + if (ths->elems > 2 * ths->length) { + ths->resize(ths); + } + + return 0; +} + +int removeSimpleHash(struct SimpleHash* ths, char* key, size_t keyLen) { + SimpleHashNode** pp = ths->find(ths, key, keyLen); + if (*pp == NULL) { + fprintf(stderr, "removeSimpleHash, key not exist \n"); + return -1; + } + + SimpleHashNode* del = *pp; + *pp = del->next; + free(del->key); + free(del->data); + free(del); + ths->elems--; + + return 0; +} + +SimpleHashNode** findSimpleHash(struct SimpleHash* ths, char* key, size_t keyLen) { + uint32_t hashCode = ths->hashFunc(key, keyLen); + // size_t index = hashCode % ths->length; + size_t index = hashCode & (ths->length - 1); + + // printf("findSimpleHash: %s %ld %u \n", key, keyLen, hashCode); + + SimpleHashNode** pp = &(ths->table[index]); + while (*pp != NULL && ((*pp)->hashCode != hashCode || memcmp(key, (*pp)->key, keyLen) != 0)) { + pp = &((*pp)->next); + } + + return pp; +} + +void printCStrSimpleHash(struct SimpleHash* ths) { + printf("\n--- printCStrSimpleHash: elems:%d length:%d \n", ths->elems, ths->length); + for (size_t i = 0; i < ths->length; ++i) { + SimpleHashNode* ptr = ths->table[i]; + if (ptr != NULL) { + printf("%zu: ", i); + while (ptr != NULL) { + printf("<%u, %s, %ld, %s, %ld> ", ptr->hashCode, (char*)ptr->key, ptr->keyLen, (char*)ptr->data, ptr->dataLen); + ptr = ptr->next; + } + printf("\n"); + } + } + printf("---------------\n"); +} + +void destroySimpleHash(struct SimpleHash* ths) { + for (size_t i = 0; i < ths->length; ++i) { + SimpleHashNode* ptr = ths->table[i]; + while (ptr != NULL) { + SimpleHashNode* tmp = ptr; + ptr = ptr->next; + free(tmp->key); + free(tmp->data); + free(tmp); + } + } + + ths->length = 0; + ths->elems = 0; + free(ths->table); + free(ths); +} + +void resizeSimpleHash(struct SimpleHash* ths) { + uint32_t new_length = ths->length; + while (new_length < ths->elems) { + new_length *= 2; + } + + printf("resizeSimpleHash: %p from %u to %u \n", ths, ths->length, new_length); + + SimpleHashNode** new_table = malloc(new_length * sizeof(SimpleHashNode*)); + memset(new_table, 0, new_length * sizeof(SimpleHashNode*)); + + uint32_t count = 0; + for (uint32_t i = 0; i < ths->length; i++) { + if (ths->table[i] == NULL) { + continue; + } + + SimpleHashNode* it = ths->table[i]; + while (it != NULL) { + SimpleHashNode* move_node = it; + it = it->next; + + // move move_node + move_node->next = NULL; + size_t index = move_node->hashCode & (new_length - 1); + + SimpleHashNode* ptr = new_table[index]; + if (ptr != NULL) { + move_node->next = ptr; + new_table[index] = move_node; + } else { + new_table[index] = move_node; + } + count++; + } + } + + assert(ths->elems == count); + free(ths->table); + ths->table = new_table; + ths->length = new_length; +} + +uint32_t simpleHashFunc(const char* key, size_t keyLen) { return mySimpleHash(key, keyLen, 1); } + +struct SimpleHash* newSimpleHash(size_t length) { + struct SimpleHash* ths = malloc(sizeof(*ths)); + + ths->length = length; + ths->elems = 0; + ths->table = malloc(length * sizeof(SimpleHashNode*)); + memset(ths->table, 0, length * sizeof(SimpleHashNode*)); + + ths->insert = insertSimpleHash; + ths->remove = removeSimpleHash; + ths->find = findSimpleHash; + ths->insert_cstr = insertCStrSimpleHash; + ths->remove_cstr = removeCStrSimpleHash; + ths->find_cstr = findCStrSimpleHash; + ths->print_cstr = printCStrSimpleHash; + ths->destroy = destroySimpleHash; + ths->resize = resizeSimpleHash; + ths->hashFunc = simpleHashFunc; +} diff --git a/contrib/test/traft/make_cluster/simpleHash.h b/contrib/test/traft/make_cluster/simpleHash.h new file mode 100644 index 0000000000..c6fcd93888 --- /dev/null +++ b/contrib/test/traft/make_cluster/simpleHash.h @@ -0,0 +1,61 @@ +#ifndef __SIMPLE_HASH_H__ +#define __SIMPLE_HASH_H__ + +#include +#include +#include +#include +#include + +uint32_t mySimpleHash(const char* data, size_t n, uint32_t seed); + +typedef struct SimpleHashNode { + uint32_t hashCode; + void* key; + size_t keyLen; + void* data; + size_t dataLen; + struct SimpleHashNode* next; +} SimpleHashNode; + +typedef struct SimpleHash { + // public: + + int (*insert)(struct SimpleHash* ths, char* key, size_t keyLen, char* data, size_t dataLen); + int (*remove)(struct SimpleHash* ths, char* key, size_t keyLen); + SimpleHashNode** (*find)(struct SimpleHash* ths, char* key, size_t keyLen); + + // wrapper + int (*insert_cstr)(struct SimpleHash* ths, char* key, char* data); + int (*remove_cstr)(struct SimpleHash* ths, char* key); + SimpleHashNode** (*find_cstr)(struct SimpleHash* ths, char* key); + + void (*print_cstr)(struct SimpleHash* ths); + void (*destroy)(struct SimpleHash* ths); + + uint32_t length; + uint32_t elems; + + // private: + void (*resize)(struct SimpleHash* ths); + uint32_t (*hashFunc)(const char* key, size_t keyLen); + + SimpleHashNode** table; + +} SimpleHash; + +int insertCStrSimpleHash(struct SimpleHash* ths, char* key, char* data); +int removeCStrSimpleHash(struct SimpleHash* ths, char* key); +SimpleHashNode** findCStrSimpleHash(struct SimpleHash* ths, char* key); +void printCStrSimpleHash(struct SimpleHash* ths); + +int insertSimpleHash(struct SimpleHash* ths, char* key, size_t keyLen, char* data, size_t dataLen); +int removeSimpleHash(struct SimpleHash* ths, char* key, size_t keyLen); +SimpleHashNode** findSimpleHash(struct SimpleHash* ths, char* key, size_t keyLen); +void destroySimpleHash(struct SimpleHash* ths); +void resizeSimpleHash(struct SimpleHash* ths); +uint32_t simpleHashFunc(const char* key, size_t keyLen); + +struct SimpleHash* newSimpleHash(size_t length); + +#endif diff --git a/contrib/test/traft/make_cluster/util.c b/contrib/test/traft/make_cluster/util.c new file mode 100644 index 0000000000..ff704f3660 --- /dev/null +++ b/contrib/test/traft/make_cluster/util.c @@ -0,0 +1,45 @@ +#include "util.h" +#include +#include +#include + +int dirOK(const char *path) { + DIR *dir = opendir(path); + if (dir != NULL) { + closedir(dir); + return 1; + } else { + return 0; + } +} + +int splitString(const char *str, char *separator, char (*arr)[TOKEN_LEN], int n_arr) { + if (n_arr <= 0) { + return -1; + } + + char *tmp = (char *)malloc(strlen(str) + 1); + strcpy(tmp, str); + char *context; + int n = 0; + + char *token = strtok_r(tmp, separator, &context); + if (!token) { + goto ret; + } + strncpy(arr[n], token, TOKEN_LEN); + n++; + + while (1) { + token = strtok_r(NULL, separator, &context); + if (!token || n >= n_arr) { + goto ret; + } + strncpy(arr[n], token, TOKEN_LEN); + n++; + } + +ret: + free(tmp); + return n; +} diff --git a/contrib/test/traft/make_cluster/util.h b/contrib/test/traft/make_cluster/util.h new file mode 100644 index 0000000000..fb4ccb9c5c --- /dev/null +++ b/contrib/test/traft/make_cluster/util.h @@ -0,0 +1,17 @@ +#ifndef TRAFT_UTIL_H +#define TRAFT_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" + +int dirOK(const char *path); +int splitString(const char *str, char *separator, char (*arr)[TOKEN_LEN], int n_arr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/test/traft/rebalance_leader/CMakeLists.txt b/contrib/test/traft/rebalance_leader/CMakeLists.txt new file mode 100644 index 0000000000..92640bdd80 --- /dev/null +++ b/contrib/test/traft/rebalance_leader/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable(rebalanceLeader "") +target_sources(rebalanceLeader + PRIVATE + "raftMain.c" + "raftServer.c" +) +target_link_libraries(rebalanceLeader PUBLIC traft lz4 uv_a) diff --git a/contrib/test/traft/rebalance_leader/clear.sh b/contrib/test/traft/rebalance_leader/clear.sh new file mode 100644 index 0000000000..398b3088f2 --- /dev/null +++ b/contrib/test/traft/rebalance_leader/clear.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +rm -rf 127.0.0.1* +rm -rf ./data diff --git a/contrib/test/traft/common.h b/contrib/test/traft/rebalance_leader/common.h similarity index 100% rename from contrib/test/traft/common.h rename to contrib/test/traft/rebalance_leader/common.h diff --git a/contrib/test/traft/raftMain.c b/contrib/test/traft/rebalance_leader/raftMain.c similarity index 94% rename from contrib/test/traft/raftMain.c rename to contrib/test/traft/rebalance_leader/raftMain.c index 24ad93856c..70dc191997 100644 --- a/contrib/test/traft/raftMain.c +++ b/contrib/test/traft/rebalance_leader/raftMain.c @@ -60,9 +60,9 @@ void raftTransferCb(struct raft_transfer *req) { SRaftServer *pRaftServer = req->data; raft_free(req); - printf("raftTransferCb: \n"); + //printf("raftTransferCb: \n"); updateLeaderStates(pRaftServer); - printLeaderCount(); + //printLeaderCount(); int myLeaderCount; for (int i = 0; i < NODE_COUNT; ++i) { @@ -71,12 +71,13 @@ void raftTransferCb(struct raft_transfer *req) { } } - printf("myLeaderCount:%d waterLevel:%d \n", myLeaderCount, pRaftServer->instanceCount / NODE_COUNT); + //printf("myLeaderCount:%d waterLevel:%d \n", myLeaderCount, pRaftServer->instanceCount / NODE_COUNT); if (myLeaderCount > pRaftServer->instanceCount / NODE_COUNT) { struct raft *r; for (int j = 0; j < pRaftServer->instanceCount; ++j) { if (pRaftServer->instance[j].raft.state == RAFT_LEADER) { r = &pRaftServer->instance[j].raft; + break; } } @@ -87,17 +88,25 @@ void raftTransferCb(struct raft_transfer *req) { int minIndex = -1; int minLeaderCount = myLeaderCount; for (int j = 0; j < NODE_COUNT; ++j) { - if (strcmp(leaderStates[j].address, pRaftServer->address) == 0) continue; + if (strcmp(leaderStates[j].address, pRaftServer->address) == 0) { + continue; + } + if (leaderStates[j].leaderCount <= minLeaderCount) { + minLeaderCount = leaderStates[j].leaderCount; minIndex = j; } } + char myHost[48]; uint16_t myPort; uint16_t myVid; decodeRaftId(r->id, myHost, sizeof(myHost), &myPort, &myVid); - + + + //printf("raftTransferCb transfer leader: vid[%u] choose: index:%d, leaderStates[%d].address:%s, leaderStates[%d].leaderCount:%d \n", minIndex, minIndex, leaderStates[minIndex].address, minIndex, leaderStates[minIndex].leaderCount); + char *destAddress = leaderStates[minIndex].address; char tokens[MAX_PEERS][MAX_TOKEN_LEN]; @@ -106,6 +115,9 @@ void raftTransferCb(struct raft_transfer *req) { uint16_t destPort = atoi(tokens[1]); destRaftId = encodeRaftId(destHost, destPort, myVid); + printf("\nraftTransferCb transfer leader: vgroupId:%u from:%s:%u --> to:%s:%u ", myVid, myHost, myPort, destHost, destPort); + fflush(stdout); + raft_transfer(r, transfer, destRaftId, raftTransferCb); } @@ -252,7 +264,6 @@ const char* state2String(unsigned short state) { void printRaftState2(struct raft *r) { - char leaderAddress[128]; memset(leaderAddress, 0, sizeof(leaderAddress)); @@ -350,6 +361,7 @@ void console(SRaftServer *pRaftServer) { while (1) { char cmd_buf[COMMAND_LEN]; memset(cmd_buf, 0, sizeof(cmd_buf)); + printf("(console)> "); char *ret = fgets(cmd_buf, COMMAND_LEN, stdin); if (!ret) { exit(-1); @@ -403,7 +415,10 @@ void console(SRaftServer *pRaftServer) { } else if (strcmp(cmd, "dropnode") == 0) { printf("not support \n"); - } else if (strcmp(cmd, "rebalance") == 0) { + } else if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "exit") == 0) { + exit(0); + + } else if (strcmp(cmd, "rebalance") == 0 && strcmp(param1, "leader") == 0) { /* updateLeaderStates(pRaftServer); @@ -511,10 +526,14 @@ void console(SRaftServer *pRaftServer) { printRaftState(&pRaftServer->instance[i].raft); } - } else if (strcmp(cmd, "state2") == 0) { + } else if (strcmp(cmd, "leader") == 0 && strcmp(param1, "state") == 0) { + updateLeaderStates(pRaftServer); + printf("\n--------------------------------------------\n"); + printLeaderCount(); for (int i = 0; i < pRaftServer->instanceCount; ++i) { printRaftState2(&pRaftServer->instance[i].raft); } + printf("--------------------------------------------\n"); } else if (strcmp(cmd, "snapshot") == 0) { printf("not support \n"); diff --git a/contrib/test/traft/raftServer.c b/contrib/test/traft/rebalance_leader/raftServer.c similarity index 92% rename from contrib/test/traft/raftServer.c rename to contrib/test/traft/rebalance_leader/raftServer.c index 94de49cd0f..165d3c9023 100644 --- a/contrib/test/traft/raftServer.c +++ b/contrib/test/traft/rebalance_leader/raftServer.c @@ -3,32 +3,34 @@ #include "common.h" #include "raftServer.h" -char *keys; -char *values; +//char *keys = malloc(MAX_RECORD_COUNT * MAX_KV_LEN);; +//char *values = malloc(MAX_RECORD_COUNT * MAX_KV_LEN); + + +char keys[MAX_KV_LEN][MAX_RECORD_COUNT]; +char values[MAX_KV_LEN][MAX_RECORD_COUNT]; +int writeIndex = 0; void initStore() { - keys = malloc(MAX_RECORD_COUNT * MAX_KV_LEN); - values = malloc(MAX_RECORD_COUNT * MAX_KV_LEN); - writeIndex = 0; } void destroyStore() { - free(keys); - free(values); + //free(keys); + //free(values); } void putKV(const char *key, const char *value) { if (writeIndex < MAX_RECORD_COUNT) { - strncpy(&keys[writeIndex], key, MAX_KV_LEN); - strncpy(&values[writeIndex], value, MAX_KV_LEN); + strncpy(keys[writeIndex], key, MAX_KV_LEN); + strncpy(values[writeIndex], value, MAX_KV_LEN); writeIndex++; } } char *getKV(const char *key) { for (int i = 0; i < MAX_RECORD_COUNT; ++i) { - if (strcmp(&keys[i], key) == 0) { - return &values[i]; + if (strcmp(keys[i], key) == 0) { + return values[i]; } } return NULL; diff --git a/contrib/test/traft/raftServer.h b/contrib/test/traft/rebalance_leader/raftServer.h similarity index 93% rename from contrib/test/traft/raftServer.h rename to contrib/test/traft/rebalance_leader/raftServer.h index b1f62caac5..5ea43985c9 100644 --- a/contrib/test/traft/raftServer.h +++ b/contrib/test/traft/rebalance_leader/raftServer.h @@ -15,11 +15,13 @@ extern "C" { // simulate a db store, just for test -#define MAX_KV_LEN 100 -#define MAX_RECORD_COUNT 500 -char *keys; -char *values; -int writeIndex; +#define MAX_KV_LEN 20 +#define MAX_RECORD_COUNT 16 + + +//char *keys; +//char *values; +//int writeIndex; void initStore(); void destroyStore(); diff --git a/source/libs/tkv/inc/tkvRocksdb.h b/include/common/tcfg.h similarity index 78% rename from source/libs/tkv/inc/tkvRocksdb.h rename to include/common/tcfg.h index 658deb335f..7ccfd4b0f5 100644 --- a/source/libs/tkv/inc/tkvRocksdb.h +++ b/include/common/tcfg.h @@ -13,15 +13,23 @@ * along with this program. If not, see . */ -#ifndef _TD_TVK_ROCKSDB_H_ -#define _TD_TVK_ROCKSDB_H_ +#ifndef _TD_COMMON_CFG_H_ +#define _TD_COMMON_CFG_H_ #ifdef __cplusplus extern "C" { #endif +#include "tdef.h" + +typedef struct { + char dir[TSDB_FILENAME_LEN]; + int level; + int primary; +} SDiskCfg; + #ifdef __cplusplus } #endif -#endif /*_TD_TVK_ROCKSDB_H_*/ \ No newline at end of file +#endif /*_TD_COMMON_CFG_H_*/ diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index c6ef6c513f..cc30cd78f5 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -31,13 +31,12 @@ extern "C" { memcpy(varDataVal(x), (str), __len); \ } while (0); -#define STR_TO_NET_VARSTR(x, str) \ - do { \ - VarDataLenT __len = (VarDataLenT)strlen(str); \ - *(VarDataLenT *)(x) = htons(__len); \ - memcpy(varDataVal(x), (str), __len); \ - } while (0); - +#define STR_TO_NET_VARSTR(x, str) \ + do { \ + VarDataLenT __len = (VarDataLenT)strlen(str); \ + *(VarDataLenT *)(x) = htons(__len); \ + memcpy(varDataVal(x), (str), __len); \ + } while (0); #define STR_WITH_MAXSIZE_TO_VARSTR(x, str, _maxs) \ do { \ @@ -71,11 +70,12 @@ typedef struct { // ----------------- TSDB SCHEMA DEFINITION typedef struct { - int version; // version - int numOfCols; // Number of columns appended - int tlen; // maximum length of a SDataRow without the header part (sizeof(VarDataOffsetT) + sizeof(VarDataLenT) + (bytes)) - uint16_t flen; // First part length in a SDataRow after the header part - uint16_t vlen; // pure value part length, excluded the overhead (bytes only) + int version; // version + int numOfCols; // Number of columns appended + int tlen; // maximum length of a SDataRow without the header part (sizeof(VarDataOffsetT) + sizeof(VarDataLenT) + + // (bytes)) + uint16_t flen; // First part length in a SDataRow after the header part + uint16_t vlen; // pure value part length, excluded the overhead (bytes only) STColumn columns[]; } STSchema; @@ -202,7 +202,6 @@ void tdFreeDataRow(SDataRow row); void tdInitDataRow(SDataRow row, STSchema *pSchema); SDataRow tdDataRowDup(SDataRow row); - // offset here not include dataRow header length static FORCE_INLINE int tdAppendDataColVal(SDataRow row, const void *value, bool isCopyVarData, int8_t type, int32_t offset) { @@ -228,7 +227,6 @@ static FORCE_INLINE int tdAppendDataColVal(SDataRow row, const void *value, bool return 0; } - // offset here not include dataRow header length static FORCE_INLINE int tdAppendColVal(SDataRow row, const void *value, int8_t type, int32_t offset) { return tdAppendDataColVal(row, value, true, type, offset); @@ -249,27 +247,28 @@ static FORCE_INLINE void *tdGetPtrToCol(SDataRow row, STSchema *pSchema, int idx static FORCE_INLINE void *tdGetColOfRowBySchema(SDataRow row, STSchema *pSchema, int idx) { int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset; - int8_t type = pSchema->columns[idx].type; + int8_t type = pSchema->columns[idx].type; return tdGetRowDataOfCol(row, type, offset); } static FORCE_INLINE bool tdIsColOfRowNullBySchema(SDataRow row, STSchema *pSchema, int idx) { int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset; - int8_t type = pSchema->columns[idx].type; + int8_t type = pSchema->columns[idx].type; return isNull(tdGetRowDataOfCol(row, type, offset), type); } static FORCE_INLINE void tdSetColOfRowNullBySchema(SDataRow row, STSchema *pSchema, int idx) { int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset; - int8_t type = pSchema->columns[idx].type; + int8_t type = pSchema->columns[idx].type; int16_t bytes = pSchema->columns[idx].bytes; setNull(tdGetRowDataOfCol(row, type, offset), type, bytes); } -static FORCE_INLINE void tdCopyColOfRowBySchema(SDataRow dst, STSchema *pDstSchema, int dstIdx, SDataRow src, STSchema *pSrcSchema, int srcIdx) { +static FORCE_INLINE void tdCopyColOfRowBySchema(SDataRow dst, STSchema *pDstSchema, int dstIdx, SDataRow src, + STSchema *pSrcSchema, int srcIdx) { int8_t type = pDstSchema->columns[dstIdx].type; assert(type == pSrcSchema->columns[srcIdx].type); void *pData = tdGetPtrToCol(dst, pDstSchema, dstIdx); @@ -319,7 +318,6 @@ static FORCE_INLINE void tdCopyColOfRowBySchema(SDataRow dst, STSchema *pDstSche } } - // ----------------- Data column structure typedef struct SDataCol { int8_t type; // column type @@ -339,7 +337,7 @@ static FORCE_INLINE void dataColReset(SDataCol *pDataCol) { pDataCol->len = 0; } int tdAllocMemForCol(SDataCol *pCol, int maxPoints); void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints); -int dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints); +int dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints); void dataColSetOffset(SDataCol *pCol, int nEle); bool isNEleNull(SDataCol *pCol, int nEle); @@ -367,15 +365,15 @@ static FORCE_INLINE int32_t dataColGetNEleLen(SDataCol *pDataCol, int rows) { } typedef struct { - int maxCols; // max number of columns - int maxPoints; // max number of points - int numOfRows; - int numOfCols; // Total number of cols - int sversion; // TODO: set sversion + int maxCols; // max number of columns + int maxPoints; // max number of points + int numOfRows; + int numOfCols; // Total number of cols + int sversion; // TODO: set sversion SDataCol *cols; } SDataCols; -#define keyCol(pCols) (&((pCols)->cols[0])) // Key column +#define keyCol(pCols) (&((pCols)->cols[0])) // Key column #define dataColsTKeyAt(pCols, idx) ((TKEY *)(keyCol(pCols)->pData))[(idx)] // the idx row of column-wised data #define dataColsKeyAt(pCols, idx) tdGetKey(dataColsTKeyAt(pCols, idx)) static FORCE_INLINE TKEY dataColsTKeyFirst(SDataCols *pCols) { @@ -454,6 +452,7 @@ typedef struct { #define kvRowValLen(r) (kvRowLen(r) - TD_KV_ROW_HEAD_SIZE - sizeof(SColIdx) * kvRowNCols(r)) #define kvRowTKey(r) (*(TKEY *)(kvRowValues(r))) #define kvRowKey(r) tdGetKey(kvRowTKey(r)) +#define kvRowKeys(r) POINTER_SHIFT(r, *(uint16_t *)POINTER_SHIFT(r, TD_KV_ROW_HEAD_SIZE + sizeof(int16_t))) #define kvRowDeleted(r) TKEY_IS_DELETED(kvRowTKey(r)) SKVRow tdKVRowDup(SKVRow row); @@ -547,7 +546,7 @@ SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder); static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, int8_t type, const void *value) { if (pBuilder->nCols >= pBuilder->tCols) { pBuilder->tCols *= 2; - SColIdx* pColIdx = (SColIdx *)realloc((void *)(pBuilder->pColIdx), sizeof(SColIdx) * pBuilder->tCols); + SColIdx *pColIdx = (SColIdx *)realloc((void *)(pBuilder->pColIdx), sizeof(SColIdx) * pBuilder->tCols); if (pColIdx == NULL) return -1; pBuilder->pColIdx = pColIdx; } @@ -562,7 +561,7 @@ static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, while (tlen > pBuilder->alloc - pBuilder->size) { pBuilder->alloc *= 2; } - void* buf = realloc(pBuilder->buf, pBuilder->alloc); + void *buf = realloc(pBuilder->buf, pBuilder->alloc); if (buf == NULL) return -1; pBuilder->buf = buf; } @@ -654,6 +653,7 @@ static FORCE_INLINE char *memRowEnd(SMemRow row) { #define memRowTKey(r) (isDataRow(r) ? dataRowTKey(memRowDataBody(r)) : kvRowTKey(memRowKvBody(r))) #define memRowKey(r) (isDataRow(r) ? dataRowKey(memRowDataBody(r)) : kvRowKey(memRowKvBody(r))) +#define memRowKeys(r) (isDataRow(r) ? dataRowTuple(memRowDataBody(r)) : kvRowKeys(memRowKvBody(r))) #define memRowSetTKey(r, k) \ do { \ if (isDataRow(r)) { \ @@ -750,10 +750,10 @@ static FORCE_INLINE void tdGetColAppendDeltaLen(const void *value, int8_t colTyp typedef struct { int16_t colId; uint8_t colType; - char* colVal; + char * colVal; } SColInfo; -static FORCE_INLINE void setSColInfo(SColInfo* colInfo, int16_t colId, uint8_t colType, char* colVal) { +static FORCE_INLINE void setSColInfo(SColInfo *colInfo, int16_t colId, uint8_t colType, char *colVal) { colInfo->colId = colId; colInfo->colType = colType; colInfo->colVal = colVal; @@ -813,4 +813,4 @@ static FORCE_INLINE char *payloadNextCol(char *pCol) { return (char *)POINTER_SH } #endif -#endif /*_TD_COMMON_DATA_FORMAT_H_*/ +#endif /*_TD_COMMON_DATA_FORMAT_H_*/ diff --git a/include/common/tglobal.h b/include/common/tglobal.h index e8a56b77c9..1b96cbdc78 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -21,6 +21,7 @@ extern "C" { #endif #include "tdef.h" +#include "tcfg.h" // cluster extern char tsFirst[]; @@ -105,11 +106,6 @@ extern uint32_t tsMaxRange; extern uint32_t tsCurRange; extern char tsCompressor[]; -typedef struct { - char dir[TSDB_FILENAME_LEN]; - int level; - int primary; -} SDiskCfg; extern int32_t tsDiskCfgNum; extern SDiskCfg tsDiskCfg[]; diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 19897ecb24..fdf64b7af2 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -26,6 +26,7 @@ extern "C" { #include "tarray.h" #include "tcoding.h" #include "tdataformat.h" +#include "thash.h" #include "tlist.h" /* ------------------------ MESSAGE DEFINITIONS ------------------------ */ @@ -132,13 +133,100 @@ typedef enum _mgmt_table { #define TSDB_COL_IS_UD_COL(f) ((f & (~(TSDB_COL_NULL))) == TSDB_COL_UDC) #define TSDB_COL_REQ_NULL(f) (((f)&TSDB_COL_NULL) != 0) -typedef struct SBuildTableMetaInput { +typedef struct { + int32_t keyLen; + int32_t valueLen; + void* key; + void* value; +} SKv; + +typedef struct { + int32_t connId; + int32_t hbType; +} SClientHbKey; + +typedef struct { + SClientHbKey connKey; + SHashObj* info; // hash +} SClientHbReq; + +typedef struct { + int64_t reqId; + SArray* reqs; // SArray +} SClientHbBatchReq; + +typedef struct { + SClientHbKey connKey; + int32_t status; + int32_t bodyLen; + void* body; +} SClientHbRsp; + +typedef struct { + int64_t reqId; + int64_t rspId; + SArray* rsps; // SArray +} SClientHbBatchRsp; + +static FORCE_INLINE uint32_t hbKeyHashFunc(const char* key, uint32_t keyLen) { + return taosIntHash_64(key, keyLen); +} + +int tSerializeSClientHbReq(void** buf, const SClientHbReq* pReq); +void* tDeserializeClientHbReq(void* buf, SClientHbReq* pReq); + +static FORCE_INLINE void tFreeClientHbReq(void *pReq) { + SClientHbReq* req = (SClientHbReq*)pReq; + taosHashCleanup(req->info); + free(pReq); +} + +int tSerializeSClientHbBatchReq(void** buf, const SClientHbBatchReq* pReq); +void* tDeserializeClientHbBatchReq(void* buf, SClientHbBatchReq* pReq); + +static FORCE_INLINE void tFreeClientHbBatchReq(void* pReq) { + SClientHbBatchReq *req = (SClientHbBatchReq*)pReq; + taosArrayDestroyEx(req->reqs, tFreeClientHbReq); + free(pReq); +} + +static FORCE_INLINE int taosEncodeSKv(void** buf, const SKv* pKv) { + int tlen = 0; + tlen += taosEncodeFixedI32(buf, pKv->keyLen); + tlen += taosEncodeFixedI32(buf, pKv->valueLen); + tlen += taosEncodeBinary(buf, pKv->key, pKv->keyLen); + tlen += taosEncodeBinary(buf, pKv->value, pKv->valueLen); + return tlen; +} + +static FORCE_INLINE void* taosDecodeSKv(void* buf, SKv* pKv) { + buf = taosDecodeFixedI32(buf, &pKv->keyLen); + buf = taosDecodeFixedI32(buf, &pKv->valueLen); + buf = taosDecodeBinary(buf, &pKv->key, pKv->keyLen); + buf = taosDecodeBinary(buf, &pKv->value, pKv->valueLen); + return buf; +} + +static FORCE_INLINE int taosEncodeSClientHbKey(void** buf, const SClientHbKey* pKey) { + int tlen = 0; + tlen += taosEncodeFixedI32(buf, pKey->connId); + tlen += taosEncodeFixedI32(buf, pKey->hbType); + return tlen; +} + +static FORCE_INLINE void* taosDecodeSClientHbKey(void* buf, SClientHbKey* pKey) { + buf = taosDecodeFixedI32(buf, &pKey->connId); + buf = taosDecodeFixedI32(buf, &pKey->hbType); + return buf; +} + +typedef struct { int32_t vgId; char* dbName; char* tableFullName; } SBuildTableMetaInput; -typedef struct SBuildUseDBInput { +typedef struct { char db[TSDB_TABLE_FNAME_LEN]; int32_t vgVersion; } SBuildUseDBInput; @@ -146,21 +234,12 @@ typedef struct SBuildUseDBInput { #pragma pack(push, 1) // null-terminated string instead of char array to avoid too many memory consumption in case of more than 1M tableMeta -typedef struct { - char fqdn[TSDB_FQDN_LEN]; - uint16_t port; -} SEpAddrMsg; - typedef struct { char fqdn[TSDB_FQDN_LEN]; uint16_t port; } SEpAddr; typedef struct { - int32_t numOfVnodes; -} SMsgDesc; - -typedef struct SMsgHead { int32_t contLen; int32_t vgId; } SMsgHead; @@ -178,13 +257,31 @@ typedef struct SSubmitBlk { } SSubmitBlk; // Submit message for this TSDB -typedef struct SSubmitMsg { +typedef struct { SMsgHead header; + int64_t version; int32_t length; int32_t numOfBlocks; char blocks[]; } SSubmitMsg; +typedef struct { + int32_t totalLen; + int32_t len; + SMemRow row; +} SSubmitBlkIter; + +typedef struct { + int32_t totalLen; + int32_t len; + void* pMsg; +} SSubmitMsgIter; + +int tInitSubmitMsgIter(SSubmitMsg* pMsg, SSubmitMsgIter* pIter); +int tGetSubmitMsgNext(SSubmitMsgIter* pIter, SSubmitBlk** pPBlock); +int tInitSubmitBlkIter(SSubmitBlk* pBlock, SSubmitBlkIter* pIter); +SMemRow tGetSubmitBlkNext(SSubmitBlkIter* pIter); + typedef struct { int32_t index; // index of failed block in submit blocks int32_t vnode; // vnode index of failed block @@ -199,7 +296,7 @@ typedef struct { int32_t failedRows; // number of failed records (exclude duplicate records) int32_t numOfFailedBlocks; SShellSubmitRspBlock failedBlocks[]; -} SShellSubmitRspMsg; +} SShellSubmitRsp; typedef struct SSchema { int8_t type; @@ -208,105 +305,31 @@ typedef struct SSchema { char name[TSDB_COL_NAME_LEN]; } SSchema; -typedef struct { - int32_t contLen; - int32_t vgId; - int8_t tableType; - int16_t numOfColumns; - int16_t numOfTags; - int32_t tid; - int32_t sversion; - int32_t tversion; - int32_t tagDataLen; - int32_t sqlDataLen; - uint64_t uid; - uint64_t superTableUid; - uint64_t createdTime; - char tableFname[TSDB_TABLE_FNAME_LEN]; - char stbFname[TSDB_TABLE_FNAME_LEN]; - char data[]; -} SMDCreateTableMsg; - -// typedef struct { -// int32_t len; // one create table message -// char tableName[TSDB_TABLE_FNAME_LEN]; -// int16_t numOfColumns; -// int16_t sqlLen; // the length of SQL, it starts after schema , sql is a null-terminated string -// int8_t igExists; -// int8_t rspMeta; -// int8_t reserved[16]; -// char schema[]; -//} SCreateTableMsg; - -typedef struct { - char tableName[TSDB_TABLE_FNAME_LEN]; - int16_t numOfColumns; - int16_t numOfTags; - int8_t igExists; - int8_t rspMeta; - char schema[]; -} SCreateCTableMsg; - typedef struct { char name[TSDB_TABLE_FNAME_LEN]; int8_t igExists; int32_t numOfTags; int32_t numOfColumns; SSchema pSchema[]; -} SCreateStbMsg, SCreateTableMsg; +} SMCreateStbReq; typedef struct { char name[TSDB_TABLE_FNAME_LEN]; int8_t igNotExists; -} SDropStbMsg; +} SMDropStbReq; typedef struct { char name[TSDB_TABLE_FNAME_LEN]; int8_t alterType; SSchema schema; -} SAlterStbMsg; - -typedef struct { - SMsgHead head; - char name[TSDB_TABLE_FNAME_LEN]; - uint64_t suid; -} SVDropStbReq; - -typedef struct { - SMsgHead head; - char name[TSDB_TABLE_FNAME_LEN]; - int8_t type; /* operation type */ - int32_t numOfCols; /* number of schema */ - int32_t numOfTags; - char data[]; -} SAlterTableMsg; - -typedef struct { - SMsgHead head; - char name[TSDB_TABLE_FNAME_LEN]; - int8_t ignoreNotExists; -} SDropTableMsg; - -typedef struct { - SMsgHead head; - int64_t uid; - int32_t tid; - int16_t tversion; - int16_t colId; - int8_t type; - int16_t bytes; - int32_t tagValLen; - int16_t numOfTags; - int32_t schemaLen; - char data[]; -} SUpdateTableTagValMsg; +} SMAlterStbReq; typedef struct { int32_t pid; char app[TSDB_APP_NAME_LEN]; char db[TSDB_DB_NAME_LEN]; int64_t startTime; -} SConnectMsg; +} SConnectReq; typedef struct SEpSet { int8_t inUse; @@ -316,14 +339,23 @@ typedef struct SEpSet { } SEpSet; static FORCE_INLINE int taosEncodeSEpSet(void** buf, const SEpSet* pEp) { - if (buf == NULL) return sizeof(SEpSet); - memcpy(buf, pEp, sizeof(SEpSet)); - // TODO: endian conversion - return sizeof(SEpSet); + int tlen = 0; + tlen += taosEncodeFixedI8(buf, pEp->inUse); + tlen += taosEncodeFixedI8(buf, pEp->numOfEps); + for (int i = 0; i < TSDB_MAX_REPLICA; i++) { + tlen += taosEncodeFixedU16(buf, pEp->port[i]); + tlen += taosEncodeString(buf, pEp->fqdn[i]); + } + return tlen; } -static FORCE_INLINE void* taosDecodeSEpSet(void* buf, SEpSet* pEpSet) { - memcpy(pEpSet, buf, sizeof(SEpSet)); +static FORCE_INLINE void* taosDecodeSEpSet(void* buf, SEpSet* pEp) { + buf = taosDecodeFixedI8(buf, &pEp->inUse); + buf = taosDecodeFixedI8(buf, &pEp->numOfEps); + for (int i = 0; i < TSDB_MAX_REPLICA; i++) { + buf = taosDecodeFixedU16(buf, &pEp->port[i]); + buf = taosDecodeStringTo(buf, pEp->fqdn[i]); + } return buf; } @@ -345,42 +377,27 @@ typedef struct { int32_t maxStreams; int32_t accessState; // Configured only by command int64_t maxStorage; // In unit of GB -} SCreateAcctMsg, SAlterAcctMsg; +} SCreateAcctReq, SAlterAcctReq; typedef struct { char user[TSDB_USER_LEN]; -} SDropUserMsg, SDropAcctMsg; +} SDropUserReq, SDropAcctReq; typedef struct { int8_t type; char user[TSDB_USER_LEN]; char pass[TSDB_PASSWORD_LEN]; int8_t superUser; // denote if it is a super user or not -} SCreateUserMsg, SAlterUserMsg; +} SCreateUserReq, SAlterUserReq; typedef struct { - int32_t contLen; - int32_t vgId; - int32_t tid; - uint64_t uid; - char tableFname[TSDB_TABLE_FNAME_LEN]; -} SMDDropTableMsg; - -typedef struct { - int32_t contLen; - int32_t vgId; - uint64_t uid; - char tableFname[TSDB_TABLE_FNAME_LEN]; -} SDropSTableMsg; - -typedef struct SColIndex { int16_t colId; // column id int16_t colIndex; // column index in colList if it is a normal column or index in tagColList if a tag int16_t flag; // denote if it is a tag or a normal column char name[TSDB_DB_FNAME_LEN]; } SColIndex; -typedef struct SColumnFilterInfo { +typedef struct { int16_t lowerRelOptr; int16_t upperRelOptr; int16_t filterstr; // denote if current column is char(binary/nchar) @@ -401,7 +418,7 @@ typedef struct SColumnFilterInfo { }; } SColumnFilterInfo; -typedef struct SColumnFilterList { +typedef struct { int16_t numOfFilters; union { int64_t placeholder; @@ -412,14 +429,14 @@ typedef struct SColumnFilterList { * for client side struct, we only need the column id, type, bytes are not necessary * But for data in vnode side, we need all the following information. */ -typedef struct SColumnInfo { +typedef struct { int16_t colId; int16_t type; int16_t bytes; SColumnFilterList flist; } SColumnInfo; -typedef struct STableIdInfo { +typedef struct { uint64_t uid; TSKEY key; // last accessed ts, for subscription } STableIdInfo; @@ -436,7 +453,7 @@ typedef struct { int32_t tsOrder; // ts comp block order } STsBufInfo; -typedef struct SInterval { +typedef struct { int32_t tz; // query client timezone char intervalUnit; char slidingUnit; @@ -495,7 +512,7 @@ typedef struct { int32_t udfContentOffset; int32_t udfContentLen; SColumnInfo tableCols[]; -} SQueryTableMsg; +} SQueryTableReq; typedef struct { int32_t code; @@ -510,9 +527,9 @@ typedef struct { int64_t qId; }; // query handle int8_t free; -} SRetrieveTableMsg; +} SRetrieveTableReq; -typedef struct SRetrieveTableRsp { +typedef struct { int64_t useconds; int8_t completed; // all results are returned to client int8_t precision; @@ -544,7 +561,7 @@ typedef struct { int8_t update; int8_t cacheLastRow; int8_t ignoreExist; -} SCreateDbMsg; +} SCreateDbReq; typedef struct { char db[TSDB_DB_FNAME_LEN]; @@ -556,25 +573,25 @@ typedef struct { int8_t walLevel; int8_t quorum; int8_t cacheLastRow; -} SAlterDbMsg; +} SAlterDbReq; typedef struct { char db[TSDB_TABLE_FNAME_LEN]; int8_t ignoreNotExists; -} SDropDbMsg; +} SDropDbReq; typedef struct { char db[TSDB_TABLE_FNAME_LEN]; int32_t vgVersion; -} SUseDbMsg; +} SUseDbReq; typedef struct { char db[TSDB_TABLE_FNAME_LEN]; -} SSyncDbMsg; +} SSyncDbReq; typedef struct { char db[TSDB_TABLE_FNAME_LEN]; -} SCompactDbMsg; +} SCompactDbReq; typedef struct { char name[TSDB_FUNC_NAME_LEN]; @@ -588,16 +605,16 @@ typedef struct { int32_t commentSize; int32_t codeSize; char pCont[]; -} SCreateFuncMsg; +} SCreateFuncReq; typedef struct { char name[TSDB_FUNC_NAME_LEN]; -} SDropFuncMsg; +} SDropFuncReq; typedef struct { int32_t numOfFuncs; char pFuncNames[]; -} SRetrieveFuncMsg; +} SRetrieveFuncReq; typedef struct { char name[TSDB_FUNC_NAME_LEN]; @@ -645,6 +662,7 @@ typedef struct { int32_t sver; int32_t dnodeId; int64_t clusterId; + int64_t dver; int64_t rebootTime; int64_t updateTime; int32_t numOfCores; @@ -652,11 +670,11 @@ typedef struct { char dnodeEp[TSDB_EP_LEN]; SClusterCfg clusterCfg; SVnodeLoads vnodeLoads; -} SStatusMsg; +} SStatusReq; typedef struct { int32_t reserved; -} STransMsg; +} STransReq; typedef struct { int32_t dnodeId; @@ -677,6 +695,7 @@ typedef struct { } SDnodeEps; typedef struct { + int64_t dver; SDnodeCfg dnodeCfg; SDnodeEps dnodeEps; } SStatusRsp; @@ -712,25 +731,25 @@ typedef struct { int8_t replica; int8_t selfIndex; SReplica replicas[TSDB_MAX_REPLICA]; -} SCreateVnodeMsg, SAlterVnodeMsg; +} SCreateVnodeReq, SAlterVnodeReq; typedef struct { int32_t vgId; int32_t dnodeId; - char db[TSDB_DB_FNAME_LEN]; uint64_t dbUid; -} SDropVnodeMsg, SSyncVnodeMsg, SCompactVnodeMsg; + char db[TSDB_DB_FNAME_LEN]; +} SDropVnodeReq, SSyncVnodeReq, SCompactVnodeReq; typedef struct { int32_t vgId; int8_t accessState; -} SAuthVnodeMsg; +} SAuthVnodeReq; typedef struct { SMsgHead header; char dbFname[TSDB_DB_FNAME_LEN]; char tableFname[TSDB_TABLE_FNAME_LEN]; -} STableInfoMsg; +} STableInfoReq; typedef struct { int8_t metaClone; // create local clone of the cached table meta @@ -738,7 +757,7 @@ typedef struct { int32_t numOfTables; int32_t numOfUdfs; char tableNames[]; -} SMultiTableInfoMsg; +} SMultiTableInfoReq; typedef struct SVgroupInfo { int32_t vgId; @@ -746,19 +765,19 @@ typedef struct SVgroupInfo { uint32_t hashEnd; int8_t inUse; int8_t numOfEps; - SEpAddrMsg epAddr[TSDB_MAX_REPLICA]; + SEpAddr epAddr[TSDB_MAX_REPLICA]; } SVgroupInfo; typedef struct { int32_t vgId; int8_t numOfEps; - SEpAddrMsg epAddr[TSDB_MAX_REPLICA]; + SEpAddr epAddr[TSDB_MAX_REPLICA]; } SVgroupMsg; typedef struct { int32_t numOfVgroups; SVgroupMsg vgroups[]; -} SVgroupsMsg, SVgroupsInfo; +} SVgroupsInfo; typedef struct { char tbFname[TSDB_TABLE_FNAME_LEN]; // table full name @@ -775,9 +794,9 @@ typedef struct { uint64_t tuid; int32_t vgId; SSchema pSchema[]; -} STableMetaMsg; +} STableMetaRsp; -typedef struct SMultiTableMeta { +typedef struct { int32_t numOfTables; int32_t numOfVgroup; int32_t numOfUdf; @@ -796,6 +815,7 @@ typedef struct { typedef struct { char db[TSDB_DB_FNAME_LEN]; + int64_t uid; int32_t vgVersion; int32_t vgNum; int8_t hashMethod; @@ -812,65 +832,54 @@ typedef struct { char db[TSDB_DB_FNAME_LEN]; int16_t payloadLen; char payload[]; -} SShowMsg; +} SShowReq; typedef struct { char db[TSDB_DB_FNAME_LEN]; int32_t numOfVgroup; int32_t vgid[]; -} SCompactMsg; +} SCompactReq; -typedef struct SShowRsp { +typedef struct { int64_t showId; - STableMetaMsg tableMeta; + STableMetaRsp tableMeta; } SShowRsp; typedef struct { char fqdn[TSDB_FQDN_LEN]; // end point, hostname:port int32_t port; -} SCreateDnodeMsg; +} SCreateDnodeReq; typedef struct { int32_t dnodeId; -} SDropDnodeMsg; +} SDropDnodeReq; typedef struct { int32_t dnodeId; char config[TSDB_DNODE_CONFIG_LEN]; -} SCfgDnodeMsg; +} SMCfgDnodeReq, SDCfgDnodeReq; typedef struct { int32_t dnodeId; -} SMCreateMnodeMsg, SMDropMnodeMsg, SDDropMnodeMsg; +} SMCreateMnodeReq, SMDropMnodeReq, SDDropMnodeReq; typedef struct { int32_t dnodeId; int8_t replica; SReplica replicas[TSDB_MAX_REPLICA]; -} SDCreateMnodeMsg, SDAlterMnodeMsg; +} SDCreateMnodeReq, SDAlterMnodeReq; typedef struct { int32_t dnodeId; -} SMCreateQnodeMsg, SMDropQnodeMsg, SDCreateQnodeMsg, SDDropQnodeMsg; +} SMCreateQnodeReq, SMDropQnodeReq, SDCreateQnodeReq, SDDropQnodeReq; typedef struct { int32_t dnodeId; -} SMCreateSnodeMsg, SMDropSnodeMsg, SDCreateSnodeMsg, SDDropSnodeMsg; +} SMCreateSnodeReq, SMDropSnodeReq, SDCreateSnodeReq, SDDropSnodeReq; typedef struct { int32_t dnodeId; -} SMCreateBnodeMsg, SMDropBnodeMsg, SDCreateBnodeMsg, SDDropBnodeMsg; - -typedef struct { - int32_t dnodeId; - int32_t vgId; - int32_t tid; -} SConfigTableMsg; - -typedef struct { - int32_t dnodeId; - int32_t vgId; -} SConfigVnodeMsg; +} SMCreateBnodeReq, SMDropBnodeReq, SDCreateBnodeReq, SDDropBnodeReq; typedef struct { char sql[TSDB_SHOW_SQL_LEN]; @@ -893,7 +902,7 @@ typedef struct { int32_t numOfStreams; char app[TSDB_APP_NAME_LEN]; char pData[]; -} SHeartBeatMsg; +} SHeartBeatReq; typedef struct { int32_t connId; @@ -906,19 +915,14 @@ typedef struct { SEpSet epSet; } SHeartBeatRsp; -typedef struct { - int32_t connId; - int32_t streamId; -} SKillStreamMsg; - typedef struct { int32_t connId; int32_t queryId; -} SKillQueryMsg; +} SKillQueryReq; typedef struct { int32_t connId; -} SKillConnMsg; +} SKillConnReq; typedef struct { char user[TSDB_USER_LEN]; @@ -926,14 +930,14 @@ typedef struct { char encrypt; char secret[TSDB_PASSWORD_LEN]; char ckey[TSDB_PASSWORD_LEN]; -} SAuthMsg, SAuthRsp; +} SAuthReq, SAuthRsp; typedef struct { int8_t finished; int8_t align[7]; char name[TSDB_STEP_NAME_LEN]; char desc[TSDB_STEP_DESC_LEN]; -} SStartupMsg; +} SStartupReq; // mq related typedef struct { @@ -974,46 +978,6 @@ typedef struct { } SSubmitReqReader; typedef struct { - /* data */ -} SCreateTableReq; - -typedef struct { - /* data */ -} SCreateTableRsp; - -typedef struct { - /* data */ -} SDropTableReq; - -typedef struct { - /* data */ -} SDropTableRsp; - -typedef struct { - /* data */ -} SAlterTableReq; - -typedef struct { - /* data */ -} SAlterTableRsp; - -typedef struct { - /* data */ -} SDropStableReq; - -typedef struct { - /* data */ -} SDropStableRsp; - -typedef struct { - /* data */ -} SUpdateTagValReq; - -typedef struct { - /* data */ -} SUpdateTagValRsp; - -typedef struct SSubQueryMsg { SMsgHead header; uint64_t sId; uint64_t queryId; @@ -1022,59 +986,59 @@ typedef struct SSubQueryMsg { char msg[]; } SSubQueryMsg; -typedef struct SResReadyMsg { +typedef struct { SMsgHead header; uint64_t sId; uint64_t queryId; uint64_t taskId; -} SResReadyMsg; +} SResReadyReq; -typedef struct SResReadyRsp { +typedef struct { int32_t code; } SResReadyRsp; -typedef struct SResFetchMsg { +typedef struct { SMsgHead header; uint64_t sId; uint64_t queryId; uint64_t taskId; -} SResFetchMsg; +} SResFetchReq; -typedef struct SSchTasksStatusMsg { +typedef struct { SMsgHead header; uint64_t sId; -} SSchTasksStatusMsg; +} SSchTasksStatusReq; -typedef struct STaskStatus { +typedef struct { uint64_t queryId; uint64_t taskId; int8_t status; } STaskStatus; -typedef struct SSchedulerStatusRsp { +typedef struct { uint32_t num; STaskStatus status[]; } SSchedulerStatusRsp; -typedef struct STaskCancelMsg { +typedef struct { SMsgHead header; uint64_t sId; uint64_t queryId; uint64_t taskId; -} STaskCancelMsg; +} STaskCancelReq; -typedef struct STaskCancelRsp { +typedef struct { int32_t code; } STaskCancelRsp; -typedef struct STaskDropMsg { +typedef struct { SMsgHead header; uint64_t sId; uint64_t queryId; uint64_t taskId; -} STaskDropMsg; +} STaskDropReq; -typedef struct STaskDropRsp { +typedef struct { int32_t code; } STaskDropRsp; @@ -1087,8 +1051,8 @@ typedef struct { static FORCE_INLINE int tSerializeSCMCreateTopicReq(void** buf, const SCMCreateTopicReq* pReq) { int tlen = 0; - tlen += taosEncodeString(buf, pReq->name); tlen += taosEncodeFixedI8(buf, pReq->igExists); + tlen += taosEncodeString(buf, pReq->name); tlen += taosEncodeString(buf, pReq->physicalPlan); tlen += taosEncodeString(buf, pReq->logicalPlan); return tlen; @@ -1118,41 +1082,66 @@ static FORCE_INLINE void* tDeserializeSCMCreateTopicRsp(void* buf, SCMCreateTopi } typedef struct { - char* topicName; - char* consumerGroup; + int32_t topicNum; int64_t consumerId; + char* consumerGroup; + SArray* topicNames; // SArray } SCMSubscribeReq; static FORCE_INLINE int tSerializeSCMSubscribeReq(void** buf, const SCMSubscribeReq* pReq) { int tlen = 0; - tlen += taosEncodeString(buf, pReq->topicName); - tlen += taosEncodeString(buf, pReq->consumerGroup); + tlen += taosEncodeFixedI32(buf, pReq->topicNum); tlen += taosEncodeFixedI64(buf, pReq->consumerId); + tlen += taosEncodeString(buf, pReq->consumerGroup); + + for (int i = 0; i < pReq->topicNum; i++) { + tlen += taosEncodeString(buf, (char*)taosArrayGetP(pReq->topicNames, i)); + } return tlen; } static FORCE_INLINE void* tDeserializeSCMSubscribeReq(void* buf, SCMSubscribeReq* pReq) { - buf = taosDecodeString(buf, &pReq->topicName); - buf = taosDecodeString(buf, &pReq->consumerGroup); + buf = taosDecodeFixedI32(buf, &pReq->topicNum); buf = taosDecodeFixedI64(buf, &pReq->consumerId); + buf = taosDecodeString(buf, &pReq->consumerGroup); + pReq->topicNames = taosArrayInit(pReq->topicNum, sizeof(void*)); + for (int i = 0; i < pReq->topicNum; i++) { + char* name = NULL; + buf = taosDecodeString(buf, &name); + taosArrayPush(pReq->topicNames, &name); + } return buf; } -typedef struct { +typedef struct SMqSubTopic { int32_t vgId; - SEpSet pEpSet; + int64_t topicId; + SEpSet epSet; +} SMqSubTopic; + +typedef struct { + int32_t topicNum; + SMqSubTopic topics[]; } SCMSubscribeRsp; static FORCE_INLINE int tSerializeSCMSubscribeRsp(void** buf, const SCMSubscribeRsp* pRsp) { int tlen = 0; - tlen += taosEncodeFixedI32(buf, pRsp->vgId); - tlen += taosEncodeSEpSet(buf, &pRsp->pEpSet); + tlen += taosEncodeFixedI32(buf, pRsp->topicNum); + for (int i = 0; i < pRsp->topicNum; i++) { + tlen += taosEncodeFixedI32(buf, pRsp->topics[i].vgId); + tlen += taosEncodeFixedI64(buf, pRsp->topics[i].topicId); + tlen += taosEncodeSEpSet(buf, &pRsp->topics[i].epSet); + } return tlen; } static FORCE_INLINE void* tDeserializeSCMSubscribeRsp(void* buf, SCMSubscribeRsp* pRsp) { - buf = taosDecodeFixedI32(buf, &pRsp->vgId); - buf = taosDecodeSEpSet(buf, &pRsp->pEpSet); + buf = taosDecodeFixedI32(buf, &pRsp->topicNum); + for (int i = 0; i < pRsp->topicNum; i++) { + buf = taosDecodeFixedI32(buf, &pRsp->topics[i].vgId); + buf = taosDecodeFixedI64(buf, &pRsp->topics[i].topicId); + buf = taosDecodeSEpSet(buf, &pRsp->topics[i].epSet); + } return buf; } @@ -1161,10 +1150,36 @@ typedef struct { int64_t consumerId; int64_t consumerGroupId; int64_t offset; + char* sql; + char* logicalPlan; + char* physicalPlan; } SMVSubscribeReq; +static FORCE_INLINE int tSerializeSMVSubscribeReq(void** buf, SMVSubscribeReq* pReq) { + int tlen = 0; + tlen += taosEncodeFixedI64(buf, pReq->topicId); + tlen += taosEncodeFixedI64(buf, pReq->consumerId); + tlen += taosEncodeFixedI64(buf, pReq->consumerGroupId); + tlen += taosEncodeFixedI64(buf, pReq->offset); + tlen += taosEncodeString(buf, pReq->sql); + tlen += taosEncodeString(buf, pReq->logicalPlan); + tlen += taosEncodeString(buf, pReq->physicalPlan); + return tlen; +} + +static FORCE_INLINE void* tDeserializeSMVSubscribeReq(void* buf, SMVSubscribeReq* pReq) { + buf = taosDecodeFixedI64(buf, &pReq->topicId); + buf = taosDecodeFixedI64(buf, &pReq->consumerId); + buf = taosDecodeFixedI64(buf, &pReq->consumerGroupId); + buf = taosDecodeFixedI64(buf, &pReq->offset); + buf = taosDecodeString(buf, &pReq->sql); + buf = taosDecodeString(buf, &pReq->logicalPlan); + buf = taosDecodeString(buf, &pReq->physicalPlan); + return buf; +} + typedef struct { - int64_t newOffset; + int64_t status; } SMVSubscribeRsp; typedef struct { @@ -1174,18 +1189,18 @@ typedef struct { void* executor; int32_t sqlLen; char* sql; -} SCreateTopicMsg; +} SCreateTopicReq; typedef struct { char name[TSDB_TABLE_FNAME_LEN]; int8_t igNotExists; -} SDropTopicMsg; +} SDropTopicReq; typedef struct { char name[TSDB_TABLE_FNAME_LEN]; int8_t alterType; SSchema schema; -} SAlterTopicMsg; +} SAlterTopicReq; typedef struct { SMsgHead head; @@ -1196,13 +1211,13 @@ typedef struct { char* executor; int32_t sqlLen; char* sql; -} SDCreateTopicMsg; +} SDCreateTopicReq; typedef struct { SMsgHead head; char name[TSDB_TABLE_FNAME_LEN]; uint64_t tuid; -} SDDropTopicMsg; +} SDDropTopicReq; typedef struct SVCreateTbReq { uint64_t ver; // use a general definition @@ -1242,24 +1257,63 @@ void* tDeserializeSVCreateTbReq(void* buf, SVCreateTbReq* pReq); int tSVCreateTbBatchReqSerialize(void** buf, SVCreateTbBatchReq* pReq); void* tSVCreateTbBatchReqDeserialize(void* buf, SVCreateTbBatchReq* pReq); -typedef struct SVCreateTbRsp { +typedef struct { + SMsgHead head; } SVCreateTbRsp; -typedef struct SVShowTablesReq { +typedef struct { + SMsgHead head; + char name[TSDB_TABLE_FNAME_LEN]; + int8_t ignoreNotExists; +} SVAlterTbReq; + +typedef struct { + SMsgHead head; +} SVAlterTbRsp; + +typedef struct { + SMsgHead head; + char name[TSDB_TABLE_FNAME_LEN]; + int8_t ignoreNotExists; +} SVDropTbReq; + +typedef struct { + SMsgHead head; +} SVDropTbRsp; + +typedef struct { + SMsgHead head; + int64_t uid; + int32_t tid; + int16_t tversion; + int16_t colId; + int8_t type; + int16_t bytes; + int32_t tagValLen; + int16_t numOfTags; + int32_t schemaLen; + char data[]; +} SUpdateTagValReq; + +typedef struct { + SMsgHead head; +} SUpdateTagValRsp; + +typedef struct { SMsgHead head; } SVShowTablesReq; -typedef struct SVShowTablesRsp { +typedef struct { int64_t id; - STableMetaMsg metaInfo; + STableMetaRsp metaInfo; } SVShowTablesRsp; -typedef struct SVShowTablesFetchReq { +typedef struct { SMsgHead head; int32_t id; } SVShowTablesFetchReq; -typedef struct SVShowTablesFetchRsp { +typedef struct { int64_t useconds; int8_t completed; // all results are returned to client int8_t precision; diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index d6071ebcf3..592672b32b 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -159,6 +159,7 @@ enum { TD_DEF_MSG_TYPE(TDMT_VND_MQ_QUERY, "vnode-mq-query", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_MQ_CONNECT, "vnode-mq-connect", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_MQ_DISCONNECT, "vnode-mq-disconnect", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_VND_MQ_SET_CONN, "vnode-mq-set-conn", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_MQ_SET_CUR, "vnode-mq-set-cur", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_RES_READY, "vnode-res-ready", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_TASKS_STATUS, "vnode-tasks-status", NULL, NULL) diff --git a/include/dnode/bnode/bnode.h b/include/dnode/bnode/bnode.h index 23cc3ca617..3cc26861ab 100644 --- a/include/dnode/bnode/bnode.h +++ b/include/dnode/bnode/bnode.h @@ -23,9 +23,9 @@ extern "C" { /* ------------------------ TYPES EXPOSED ------------------------ */ typedef struct SDnode SDnode; typedef struct SBnode SBnode; -typedef void (*SendMsgToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg); -typedef void (*SendMsgToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); -typedef void (*SendRedirectMsgFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef int32_t (*SendReqToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg); +typedef int32_t (*SendReqToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef void (*SendRedirectRspFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); typedef struct { int64_t numOfErrors; @@ -40,9 +40,9 @@ typedef struct { int64_t clusterId; SBnodeCfg cfg; SDnode *pDnode; - SendMsgToDnodeFp sendMsgToDnodeFp; - SendMsgToMnodeFp sendMsgToMnodeFp; - SendRedirectMsgFp sendRedirectMsgFp; + SendReqToDnodeFp sendReqToDnodeFp; + SendReqToMnodeFp sendReqToMnodeFp; + SendRedirectRspFp sendRedirectRspFp; } SBnodeOpt; /* ------------------------ SBnode ------------------------ */ diff --git a/include/dnode/mnode/mnode.h b/include/dnode/mnode/mnode.h index a288e3e630..de4b4e4e89 100644 --- a/include/dnode/mnode/mnode.h +++ b/include/dnode/mnode/mnode.h @@ -24,9 +24,10 @@ extern "C" { typedef struct SDnode SDnode; typedef struct SMnode SMnode; typedef struct SMnodeMsg SMnodeMsg; -typedef void (*SendMsgToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg); -typedef void (*SendMsgToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); -typedef void (*SendRedirectMsgFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef int32_t (*SendReqToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg); +typedef int32_t (*SendReqToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef int32_t (*PutReqToMWriteQFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef void (*SendRedirectRspFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); typedef struct SMnodeLoad { int64_t numOfDnode; @@ -62,9 +63,10 @@ typedef struct { SReplica replicas[TSDB_MAX_REPLICA]; SMnodeCfg cfg; SDnode *pDnode; - SendMsgToDnodeFp sendMsgToDnodeFp; - SendMsgToMnodeFp sendMsgToMnodeFp; - SendRedirectMsgFp sendRedirectMsgFp; + PutReqToMWriteQFp putReqToMWriteQFp; + SendReqToDnodeFp sendReqToDnodeFp; + SendReqToMnodeFp sendReqToMnodeFp; + SendRedirectRspFp sendRedirectRspFp; } SMnodeOpt; /* ------------------------ SMnode ------------------------ */ diff --git a/include/dnode/mnode/sdb/sdb.h b/include/dnode/mnode/sdb/sdb.h index 497da71c13..5a4ac6a96f 100644 --- a/include/dnode/mnode/sdb/sdb.h +++ b/include/dnode/mnode/sdb/sdb.h @@ -94,6 +94,7 @@ typedef struct SSdbRaw SSdbRaw; typedef struct SSdbRow SSdbRow; typedef enum { SDB_KEY_BINARY = 1, SDB_KEY_INT32 = 2, SDB_KEY_INT64 = 3 } EKeyType; typedef enum { + SDB_STATUS_INIT = 0, SDB_STATUS_CREATING = 1, SDB_STATUS_UPDATING = 2, SDB_STATUS_DROPPING = 3, @@ -280,6 +281,15 @@ int32_t sdbGetSize(SSdb *pSdb, ESdbType type); */ int32_t sdbGetMaxId(SSdb *pSdb, ESdbType type); +/** + * @brief Get the version of the table + * + * @param pSdb The sdb object. + * @param pIter The type of the table. + * @return int32_t The version of the table + */ +int64_t sdbGetTableVer(SSdb *pSdb, ESdbType type); + /** * @brief Update the version of sdb * diff --git a/include/dnode/qnode/qnode.h b/include/dnode/qnode/qnode.h index 8084175a90..554c57a045 100644 --- a/include/dnode/qnode/qnode.h +++ b/include/dnode/qnode/qnode.h @@ -23,9 +23,9 @@ extern "C" { /* ------------------------ TYPES EXPOSED ------------------------ */ typedef struct SDnode SDnode; typedef struct SQnode SQnode; -typedef void (*SendMsgToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg); -typedef void (*SendMsgToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); -typedef void (*SendRedirectMsgFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef int32_t (*SendReqToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg); +typedef int32_t (*SendReqToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef void (*SendRedirectRspFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); typedef struct { int64_t numOfStartTask; @@ -47,9 +47,9 @@ typedef struct { int64_t clusterId; SQnodeCfg cfg; SDnode *pDnode; - SendMsgToDnodeFp sendMsgToDnodeFp; - SendMsgToMnodeFp sendMsgToMnodeFp; - SendRedirectMsgFp sendRedirectMsgFp; + SendReqToDnodeFp sendReqToDnodeFp; + SendReqToMnodeFp sendReqToMnodeFp; + SendRedirectRspFp sendRedirectRspFp; } SQnodeOpt; /* ------------------------ SQnode ------------------------ */ diff --git a/include/dnode/snode/snode.h b/include/dnode/snode/snode.h index 4913d2572f..43d3dd9b4b 100644 --- a/include/dnode/snode/snode.h +++ b/include/dnode/snode/snode.h @@ -23,9 +23,9 @@ extern "C" { /* ------------------------ TYPES EXPOSED ------------------------ */ typedef struct SDnode SDnode; typedef struct SSnode SSnode; -typedef void (*SendMsgToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg); -typedef void (*SendMsgToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); -typedef void (*SendRedirectMsgFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef int32_t (*SendReqToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg); +typedef int32_t (*SendReqToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); +typedef void (*SendRedirectRspFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); typedef struct { int64_t numOfErrors; @@ -40,9 +40,9 @@ typedef struct { int64_t clusterId; SSnodeCfg cfg; SDnode *pDnode; - SendMsgToDnodeFp sendMsgToDnodeFp; - SendMsgToMnodeFp sendMsgToMnodeFp; - SendRedirectMsgFp sendRedirectMsgFp; + SendReqToDnodeFp sendReqToDnodeFp; + SendReqToMnodeFp sendReqToMnodeFp; + SendRedirectRspFp sendRedirectRspFp; } SSnodeOpt; /* ------------------------ SSnode ------------------------ */ diff --git a/include/dnode/vnode/meta/meta.h b/include/dnode/vnode/meta/meta.h index 86ebb643a4..031ed178f0 100644 --- a/include/dnode/vnode/meta/meta.h +++ b/include/dnode/vnode/meta/meta.h @@ -58,6 +58,7 @@ int metaCommit(SMeta *pMeta); STbCfg * metaGetTbInfoByUid(SMeta *pMeta, tb_uid_t uid); STbCfg * metaGetTbInfoByName(SMeta *pMeta, char *tbname, tb_uid_t *uid); SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, bool isinline); +STSchema * metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver); SMTbCursor *metaOpenTbCursor(SMeta *pMeta); void metaCloseTbCursor(SMTbCursor *pTbCur); diff --git a/include/dnode/vnode/tsdb/tsdb.h b/include/dnode/vnode/tsdb/tsdb.h index e5522ddbd3..3aeef4d013 100644 --- a/include/dnode/vnode/tsdb/tsdb.h +++ b/include/dnode/vnode/tsdb/tsdb.h @@ -17,26 +17,52 @@ #define _TD_TSDB_H_ #include "mallocator.h" +#include "meta.h" #ifdef __cplusplus extern "C" { #endif +typedef struct SDataStatis { + int16_t colId; + int64_t sum; + int64_t max; + int64_t min; + int16_t maxIndex; + int16_t minIndex; + int16_t numOfNull; +} SDataStatis; + +typedef struct STable { + uint64_t tid; + uint64_t uid; + STSchema *pSchema; +} STable; + +#define TABLE_TID(t) (t)->tid +#define TABLE_UID(t) (t)->uid + // TYPES EXPOSED typedef struct STsdb STsdb; typedef struct STsdbCfg { + int8_t precision; uint64_t lruCacheSize; - uint32_t keep0; - uint32_t keep1; - uint32_t keep2; + int32_t daysPerFile; + int32_t minRowsPerFileBlock; + int32_t maxRowsPerFileBlock; + int32_t keep; + int32_t keep1; + int32_t keep2; + int8_t update; + int8_t compression; } STsdbCfg; // STsdb -STsdb *tsdbOpen(const char *path, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory *pMAF); +STsdb *tsdbOpen(const char *path, int32_t vgId, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory *pMAF, SMeta *pMeta); void tsdbClose(STsdb *); void tsdbRemove(const char *path); -int tsdbInsertData(STsdb *pTsdb, SSubmitMsg *pMsg); +int tsdbInsertData(STsdb *pTsdb, SSubmitMsg *pMsg, SSubmitRsp *pRsp); int tsdbPrepareCommit(STsdb *pTsdb); int tsdbCommit(STsdb *pTsdb); diff --git a/include/dnode/vnode/vnode.h b/include/dnode/vnode/vnode.h index af56d69b11..2212a8c29a 100644 --- a/include/dnode/vnode/vnode.h +++ b/include/dnode/vnode/vnode.h @@ -32,6 +32,8 @@ extern "C" { /* ------------------------ TYPES EXPOSED ------------------------ */ typedef struct SVnode SVnode; typedef struct SVnodeCfg { + int32_t vgId; + /** vnode buffer pool options */ struct { /** write buffer size */ @@ -87,7 +89,7 @@ void vnodeClear(); * @param pVnodeCfg options of the vnode * @return SVnode* The vnode object */ -SVnode *vnodeOpen(const char *path, const SVnodeCfg *pVnodeCfg); +SVnode *vnodeOpen(const char *path, const SVnodeCfg *pVnodeCfg, int32_t vid); /** * @brief Close a VNODE diff --git a/include/libs/catalog/catalog.h b/include/libs/catalog/catalog.h index 3916898829..70cff7ed1a 100644 --- a/include/libs/catalog/catalog.h +++ b/include/libs/catalog/catalog.h @@ -48,8 +48,22 @@ typedef struct SMetaData { typedef struct SCatalogCfg { uint32_t maxTblCacheNum; uint32_t maxDBCacheNum; + uint32_t dbRentSec; + uint32_t stableRentSec; } SCatalogCfg; +typedef struct SSTableMetaVersion { + uint64_t suid; + int16_t sversion; + int16_t tversion; +} SSTableMetaVersion; + +typedef struct SDbVgVersion { + int64_t dbId; + int32_t vgVersion; +} SDbVgVersion; + + int32_t catalogInit(SCatalogCfg *cfg); /** @@ -60,19 +74,27 @@ int32_t catalogInit(SCatalogCfg *cfg); */ int32_t catalogGetHandle(uint64_t clusterId, struct SCatalog** catalogHandle); +/** + * Free a cluster's all catalog info, usually it's not necessary, until the application is closing. + * no current or future usage should be guaranteed by application + * @param pCatalog (input, NO more usage) + * @return error code + */ +void catalogFreeHandle(struct SCatalog* pCatalog); + int32_t catalogGetDBVgroupVersion(struct SCatalog* pCatalog, const char* dbName, int32_t* version); /** * Get a DB's all vgroup info. * @param pCatalog (input, got with catalogGetHandle) - * @param pRpc (input, rpc object) + * @param pTransporter (input, rpc object) * @param pMgmtEps (input, mnode EPs) * @param pDBName (input, full db name) * @param forceUpdate (input, force update db vgroup info from mnode) * @param pVgroupList (output, vgroup info list, element is SVgroupInfo, NEED to simply free the array by caller) * @return error code */ -int32_t catalogGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, int32_t forceUpdate, SArray** pVgroupList); +int32_t catalogGetDBVgroup(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const char* pDBName, bool forceUpdate, SArray** pVgroupList); int32_t catalogUpdateDBVgroup(struct SCatalog* pCatalog, const char* dbName, SDBVgroupInfo* dbInfo); @@ -87,15 +109,28 @@ int32_t catalogUpdateDBVgroup(struct SCatalog* pCatalog, const char* dbName, SDB */ int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void * pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta); +/** + * Get a super table's meta data. + * @param pCatalog (input, got with catalogGetHandle) + * @param pTransporter (input, rpc object) + * @param pMgmtEps (input, mnode EPs) + * @param pTableName (input, table name, NOT including db name) + * @param pTableMeta(output, table meta data, NEED to free it by calller) + * @return error code + */ +int32_t catalogGetSTableMeta(struct SCatalog* pCatalog, void * pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta); + + /** * Force renew a table's local cached meta data. * @param pCatalog (input, got with catalogGetHandle) * @param pTransporter (input, rpc object) * @param pMgmtEps (input, mnode EPs) * @param pTableName (input, table name, NOT including db name) + * @param isSTable (input, is super table or not, 1:supposed to be stable, 0: supposed not to be stable, -1:not sure) * @return error code */ -int32_t catalogRenewTableMeta(struct SCatalog* pCatalog, void * pTransporter, const SEpSet* pMgmtEps, const SName* pTableName); + int32_t catalogRenewTableMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, int32_t isSTable); /** * Force renew a table's local cached meta data and get the new one. @@ -104,21 +139,23 @@ int32_t catalogRenewTableMeta(struct SCatalog* pCatalog, void * pTransporter, co * @param pMgmtEps (input, mnode EPs) * @param pTableName (input, table name, NOT including db name) * @param pTableMeta(output, table meta data, NEED to free it by calller) + * @param isSTable (input, is super table or not, 1:supposed to be stable, 0: supposed not to be stable, -1:not sure) * @return error code */ -int32_t catalogRenewAndGetTableMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta); + int32_t catalogRenewAndGetTableMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta, int32_t isSTable); + /** * Get a table's actual vgroup, for stable it's all possible vgroup list. * @param pCatalog (input, got with catalogGetHandle) - * @param pRpc (input, rpc object) + * @param pTransporter (input, rpc object) * @param pMgmtEps (input, mnode EPs) * @param pTableName (input, table name, NOT including db name) * @param pVgroupList (output, vgroup info list, element is SVgroupInfo, NEED to simply free the array by caller) * @return error code */ -int32_t catalogGetTableDistVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, SArray** pVgroupList); +int32_t catalogGetTableDistVgroup(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, SArray** pVgroupList); /** * Get a table's vgroup from its name's hash value. @@ -135,17 +172,20 @@ int32_t catalogGetTableHashVgroup(struct SCatalog* pCatalog, void * pTransporter /** * Get all meta data required in pReq. * @param pCatalog (input, got with catalogGetHandle) - * @param pRpc (input, rpc object) + * @param pTransporter (input, rpc object) * @param pMgmtEps (input, mnode EPs) * @param pReq (input, reqest info) * @param pRsp (output, response data) * @return error code */ -int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SMetaData* pRsp); +int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SMetaData* pRsp); -int32_t catalogGetQnodeList(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, SArray* pQnodeList); +int32_t catalogGetQnodeList(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, SArray* pQnodeList); +int32_t catalogGetExpiredSTables(struct SCatalog* pCatalog, SSTableMetaVersion **stables, uint32_t *num); + +int32_t catalogGetExpiredDBs(struct SCatalog* pCatalog, SDbVgVersion **dbs, uint32_t *num); /** diff --git a/include/libs/executor/executor.h b/include/libs/executor/executor.h index c3c7d740f7..17c11b5d09 100644 --- a/include/libs/executor/executor.h +++ b/include/libs/executor/executor.h @@ -20,16 +20,16 @@ extern "C" { #endif -typedef void* qinfo_t; +typedef void* qTaskInfo_t; /** * create the qinfo object according to QueryTableMsg * @param tsdb * @param pQueryTableMsg - * @param qinfo + * @param pTaskInfo * @return */ -int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableInfo* pQueryTableMsg, qinfo_t* qinfo, uint64_t qId); +int32_t qCreateTask(void* tsdb, int32_t vgId, void* pQueryTableMsg, qTaskInfo_t* pTaskInfo, uint64_t qId); /** * the main query execution function, including query on both table and multiple tables, @@ -38,7 +38,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableInfo* pQueryTableM * @param qinfo * @return */ -bool qTableQuery(qinfo_t qinfo, uint64_t *qId); +bool qExecTask(qTaskInfo_t qinfo, uint64_t *qId); /** * Retrieve the produced results information, if current query is not paused or completed, @@ -48,7 +48,7 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId); * @param qinfo * @return */ -int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContext); +int32_t qRetrieveQueryResultInfo(qTaskInfo_t qinfo, bool* buildRes, void* pRspContext); /** * @@ -60,41 +60,41 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex * @param contLen payload length * @return */ -int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp** pRsp, int32_t* contLen, bool* continueExec); +int32_t qDumpRetrieveResult(qTaskInfo_t qinfo, SRetrieveTableRsp** pRsp, int32_t* contLen, bool* continueExec); /** * return the transporter context (RPC) * @param qinfo * @return */ -void* qGetResultRetrieveMsg(qinfo_t qinfo); +void* qGetResultRetrieveMsg(qTaskInfo_t qinfo); /** * kill the ongoing query and free the query handle and corresponding resources automatically * @param qinfo qhandle * @return */ -int32_t qKillQuery(qinfo_t qinfo); +int32_t qKillTask(qTaskInfo_t qinfo); /** * return whether query is completed or not * @param qinfo * @return */ -int32_t qIsQueryCompleted(qinfo_t qinfo); +int32_t qIsQueryCompleted(qTaskInfo_t qinfo); /** * destroy query info structure * @param qHandle */ -void qDestroyQueryInfo(qinfo_t qHandle); +void qDestroyTask(qTaskInfo_t qHandle); /** * Get the queried table uid * @param qHandle * @return */ -int64_t qGetQueriedTableUid(qinfo_t qHandle); +int64_t qGetQueriedTableUid(qTaskInfo_t qHandle); /** * Extract the qualified table id list, and than pass them to the TSDB driver to load the required table data blocks. @@ -121,7 +121,7 @@ int32_t qCreateTableGroupByGroupExpr(SArray* pTableIdList, TSKEY skey, STableGro * @param type operation type: ADD|DROP * @return */ -int32_t qUpdateQueriedTableIdList(qinfo_t qinfo, int64_t uid, int32_t type); +int32_t qUpdateQueriedTableIdList(qTaskInfo_t qinfo, int64_t uid, int32_t type); //================================================================================================ // query handle management @@ -130,13 +130,13 @@ int32_t qUpdateQueriedTableIdList(qinfo_t qinfo, int64_t uid, int32_t type); * @param vgId * @return */ -void* qOpenQueryMgmt(int32_t vgId); +void* qOpenTaskMgmt(int32_t vgId); /** * broadcast the close information and wait for all query stop. * @param pExecutor */ -void qQueryMgmtNotifyClosed(void* pExecutor); +void qTaskMgmtNotifyClosing(void* pExecutor); /** * Re-open the query handle management module when opening the vnode again. @@ -148,7 +148,7 @@ void qQueryMgmtReOpen(void *pExecutor); * Close query mgmt and clean up resources. * @param pExecutor */ -void qCleanupQueryMgmt(void* pExecutor); +void qCleanupTaskMgmt(void* pExecutor); /** * Add the query into the query mgmt object @@ -157,7 +157,7 @@ void qCleanupQueryMgmt(void* pExecutor); * @param qInfo * @return */ -void** qRegisterQInfo(void* pMgmt, uint64_t qId, void *qInfo); +void** qRegisterTask(void* pMgmt, uint64_t qId, void *qInfo); /** * acquire the query handle according to the key from query mgmt object. @@ -165,7 +165,7 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qId, void *qInfo); * @param key * @return */ -void** qAcquireQInfo(void* pMgmt, uint64_t key); +void** qAcquireTask(void* pMgmt, uint64_t key); /** * release the query handle and decrease the reference count in cache @@ -174,7 +174,7 @@ void** qAcquireQInfo(void* pMgmt, uint64_t key); * @param freeHandle * @return */ -void** qReleaseQInfo(void* pMgmt, void* pQInfo); +void** qReleaseTask(void* pMgmt, void* pQInfo, bool freeHandle); /** * De-register the query handle from the management module and free it immediately. diff --git a/include/libs/function/function.h b/include/libs/function/function.h index d7360a81bc..bf2937a220 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -89,7 +89,7 @@ enum { }; enum { - MASTER_SCAN = 0x0u, + MAIN_SCAN = 0x0u, REVERSE_SCAN = 0x1u, REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan MERGE_STAGE = 0x20u, @@ -183,7 +183,6 @@ typedef struct tExprNode { struct {// function node char functionName[FUNCTIONS_NAME_MAX_LENGTH]; -// int32_t functionId; int32_t num; // Note that the attribute of pChild is not the parameter of function, it is the columns that involved in the diff --git a/include/libs/parser/parsenodes.h b/include/libs/parser/parsenodes.h index 18596a9e18..ac8a10067d 100644 --- a/include/libs/parser/parsenodes.h +++ b/include/libs/parser/parsenodes.h @@ -135,9 +135,8 @@ typedef struct SQueryStmtInfo { SArray *pUdfInfo; struct SQueryStmtInfo *sibling; // sibling - struct SQueryStmtInfo *pDownstream; SMultiFunctionsDesc info; - SArray *pUpstream; // SArray + SArray *pDownstream; // SArray int32_t havingFieldNum; int32_t exprListLevelIndex; } SQueryStmtInfo; diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index a9e1f26d20..edf9cf461f 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -24,7 +24,6 @@ extern "C" { typedef struct SParseContext { SParseBasicCtx ctx; - int8_t schemaAttached; // denote if submit block is built with table schema or not const char *pSql; // sql string size_t sqlLen; // length of the sql string char *pMsg; // extended error message if exists to help identifying the problem in sql statement. @@ -41,9 +40,18 @@ typedef struct SParseContext { */ int32_t qParseQuerySql(SParseContext* pContext, SQueryNode** pQuery); -bool qIsDdlQuery(const SQueryNode* pQuery); +/** + * Return true if it is a ddl/dcl sql statement + * @param pQuery + * @return + */ +bool qIsDdlQuery(const SQueryNode* pQueryNode); -void qDestroyQuery(SQueryNode* pQuery); +/** + * Destroy logic query plan + * @param pQueryNode + */ +void qDestroyQuery(SQueryNode* pQueryNode); /** * Convert a normal sql statement to only query tags information to enable that the subscribe client can be aware quickly of the true vgroup ids that @@ -62,8 +70,8 @@ void columnListDestroy(SArray* pColumnList); void dropAllExprInfo(SArray** pExprInfo, int32_t numOfLevel); typedef struct SSourceParam { - SArray *pExprNodeList; //Array - SArray *pColumnList; //Array + SArray *pExprNodeList; //Array + SArray *pColumnList; //Array int32_t num; } SSourceParam; diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index a55a4fedab..da70f21498 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -23,6 +23,7 @@ extern "C" { #include "query.h" #include "tmsg.h" #include "tarray.h" +#include "trpc.h" #define QUERY_TYPE_MERGE 1 #define QUERY_TYPE_PARTIAL 2 @@ -50,8 +51,10 @@ struct SQueryStmtInfo; typedef SSchema SSlotSchema; typedef struct SDataBlockSchema { - SSlotSchema *pSchema; - int32_t numOfCols; // number of columns + SSlotSchema *pSchema; + int32_t numOfCols; // number of columns + int32_t resultRowSize; + int16_t precision; } SDataBlockSchema; typedef struct SQueryNodeBasicInfo { @@ -61,6 +64,7 @@ typedef struct SQueryNodeBasicInfo { typedef struct SDataSink { SQueryNodeBasicInfo info; + SDataBlockSchema schema; } SDataSink; typedef struct SDataDispatcher { @@ -110,7 +114,7 @@ typedef struct SProjectPhyNode { typedef struct SExchangePhyNode { SPhyNode node; uint64_t srcTemplateId; // template id of datasource suplans - SArray *pSrcEndPoints; // SEpAddrMsg, scheduler fill by calling qSetSuplanExecutionNode + SArray *pSrcEndPoints; // SEpAddr, scheduler fill by calling qSetSuplanExecutionNode } SExchangePhyNode; typedef struct SSubplanId { @@ -139,16 +143,20 @@ typedef struct SQueryDag { struct SQueryNode; -/** - * Create the physical plan for the query, according to the AST. - */ + /** + * Create the physical plan for the query, according to the AST. + * @param pQueryInfo + * @param pDag + * @param requestId + * @return + */ int32_t qCreateQueryDag(const struct SQueryNode* pQueryInfo, struct SQueryDag** pDag, uint64_t requestId); // Set datasource of this subplan, multiple calls may be made to a subplan. // @subplan subplan to be schedule // @templateId templateId of a group of datasource subplans of this @subplan // @ep one execution location of this group of datasource subplans -int32_t qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep); +void qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep); int32_t qExplainQuery(const struct SQueryNode* pQueryInfo, struct SEpSet* pQnode, char** str); diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index 4bfb774435..3d5c74d093 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -35,6 +35,7 @@ enum { JOB_TASK_STATUS_CANCELLING, JOB_TASK_STATUS_CANCELLED, JOB_TASK_STATUS_DROPPING, + JOB_TASK_STATUS_FREEING, }; typedef struct STableComInfo { @@ -76,6 +77,7 @@ typedef struct STableMeta { typedef struct SDBVgroupInfo { SRWLatch lock; + int64_t dbId; int32_t vgVersion; int8_t hashMethod; SHashObj *vgInfo; //key:vgId, value:SVgroupInfo @@ -86,69 +88,33 @@ typedef struct SUseDbOutput { SDBVgroupInfo dbVgroup; } SUseDbOutput; +enum { + META_TYPE_NON_TABLE = 1, + META_TYPE_CTABLE, + META_TYPE_TABLE, + META_TYPE_BOTH_TABLE +}; + + typedef struct STableMetaOutput { - int32_t metaNum; + int32_t metaType; char ctbFname[TSDB_TABLE_FNAME_LEN]; char tbFname[TSDB_TABLE_FNAME_LEN]; SCTableMeta ctbMeta; STableMeta *tbMeta; } STableMetaOutput; -typedef struct SDataBuf { - void *pData; - uint32_t len; -} SDataBuf; - -typedef int32_t (*__async_send_cb_fn_t)(void* param, const SDataBuf* pMsg, int32_t code); -typedef int32_t (*__async_exec_fn_t)(void* param); - -typedef struct SMsgSendInfo { - __async_send_cb_fn_t fp; //async callback function - void *param; - uint64_t requestId; - uint64_t requestObjRefId; - int32_t msgType; - SDataBuf msgInfo; -} SMsgSendInfo; - -typedef struct SQueryNodeAddr{ - int32_t nodeId; //vgId or qnodeId - int8_t inUse; - int8_t numOfEps; - SEpAddrMsg epAddr[TSDB_MAX_REPLICA]; -} SQueryNodeAddr; - -bool tIsValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_t numOfTags); - -int32_t initTaskQueue(); -int32_t cleanupTaskQueue(); - -/** - * - * @param execFn The asynchronously execution function - * @param execParam The parameters of the execFn - * @param code The response code during execution the execFn - * @return - */ -int32_t taosAsyncExec(__async_exec_fn_t execFn, void* execParam, int32_t* code); - -/** - * Asynchronously send message to server, after the response received, the callback will be incured. - * - * @param pTransporter - * @param epSet - * @param pTransporterId - * @param pInfo - * @return - */ -int32_t asyncSendMsgToServer(void *pTransporter, SEpSet* epSet, int64_t* pTransporterId, const SMsgSendInfo* pInfo); - const SSchema* tGetTbnameColumnSchema(); void initQueryModuleMsgHandle(); extern int32_t (*queryBuildMsg[TDMT_MAX])(void* input, char **msg, int32_t msgSize, int32_t *msgLen); extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char *msg, int32_t msgSize); +#define SET_META_TYPE_NONE(t) (t) = META_TYPE_NON_TABLE +#define SET_META_TYPE_CTABLE(t) (t) = META_TYPE_CTABLE +#define SET_META_TYPE_TABLE(t) (t) = META_TYPE_TABLE +#define SET_META_TYPE_BOTH_TABLE(t) (t) = META_TYPE_BOTH_TABLE + #define qFatal(...) do { if (qDebugFlag & DEBUG_FATAL) { taosPrintLog("QRY FATAL ", qDebugFlag, __VA_ARGS__); }} while(0) #define qError(...) do { if (qDebugFlag & DEBUG_ERROR) { taosPrintLog("QRY ERROR ", qDebugFlag, __VA_ARGS__); }} while(0) #define qWarn(...) do { if (qDebugFlag & DEBUG_WARN) { taosPrintLog("QRY WARN ", qDebugFlag, __VA_ARGS__); }} while(0) diff --git a/include/libs/scheduler/scheduler.h b/include/libs/scheduler/scheduler.h index b2ba7acebf..74b7813465 100644 --- a/include/libs/scheduler/scheduler.h +++ b/include/libs/scheduler/scheduler.h @@ -24,7 +24,7 @@ extern "C" { #include "catalog.h" typedef struct SSchedulerCfg { - int32_t maxJobNum; + uint32_t maxJobNum; } SSchedulerCfg; typedef struct SQueryProfileSummary { @@ -75,6 +75,12 @@ int32_t scheduleExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, void */ int32_t scheduleAsyncExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, void** pJob); +/** + * Fetch query result from the remote query executor + * @param pJob + * @param data + * @return + */ int32_t scheduleFetchRows(void *pJob, void **data); @@ -85,6 +91,10 @@ int32_t scheduleFetchRows(void *pJob, void **data); */ int32_t scheduleCancelJob(void *pJob); +/** + * Free the query job + * @param pJob + */ void scheduleFreeJob(void *pJob); void schedulerDestroy(void); diff --git a/include/libs/tfs/tfs.h b/include/libs/tfs/tfs.h new file mode 100644 index 0000000000..6c850d1016 --- /dev/null +++ b/include/libs/tfs/tfs.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef TD_TFS_H +#define TD_TFS_H + +#include "tglobal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int level; + int id; +} SDiskID; + +#define TFS_UNDECIDED_LEVEL -1 +#define TFS_UNDECIDED_ID -1 +#define TFS_PRIMARY_LEVEL 0 +#define TFS_PRIMARY_ID 0 +#define TFS_MIN_LEVEL 0 +#define TFS_MAX_LEVEL (TSDB_MAX_TIERS - 1) + +// FS APIs ==================================== +typedef struct { + int64_t tsize; + int64_t used; + int64_t avail; +} SFSMeta; + +typedef struct { + int64_t size; + int64_t used; + int64_t free; + int16_t nAvailDisks; // # of Available disks +} STierMeta; + +int tfsInit(SDiskCfg *pDiskCfg, int ndisk); +void tfsDestroy(); +void tfsUpdateInfo(SFSMeta *pFSMeta, STierMeta *tierMetas, int8_t numLevels); +void tfsGetMeta(SFSMeta *pMeta); +void tfsAllocDisk(int expLevel, int *level, int *id); + +const char *TFS_PRIMARY_PATH(); +const char *TFS_DISK_PATH(int level, int id); + +// TFILE APIs ==================================== +typedef struct { + int level; + int id; + char rname[TSDB_FILENAME_LEN]; // REL name + char aname[TSDB_FILENAME_LEN]; // ABS name +} TFILE; + +#define TFILE_LEVEL(pf) ((pf)->level) +#define TFILE_ID(pf) ((pf)->id) +#define TFILE_NAME(pf) ((pf)->aname) +#define TFILE_REL_NAME(pf) ((pf)->rname) + +#define tfsopen(pf, flags) open(TFILE_NAME(pf), flags) +#define tfsclose(fd) close(fd) +#define tfsremove(pf) remove(TFILE_NAME(pf)) +#define tfscopy(sf, df) taosCopyFile(TFILE_NAME(sf), TFILE_NAME(df)) +#define tfsrename(sf, df) taosRename(TFILE_NAME(sf), TFILE_NAME(df)) + +void tfsInitFile(TFILE *pf, int level, int id, const char *bname); +bool tfsIsSameFile(const TFILE *pf1, const TFILE *pf2); +int tfsEncodeFile(void **buf, TFILE *pf); +void *tfsDecodeFile(void *buf, TFILE *pf); +void tfsbasename(const TFILE *pf, char *dest); +void tfsdirname(const TFILE *pf, char *dest); + +// DIR APIs ==================================== +int tfsMkdirAt(const char *rname, int level, int id); +int tfsMkdirRecurAt(const char *rname, int level, int id); +int tfsMkdir(const char *rname); +int tfsRmdir(const char *rname); +int tfsRename(char *orname, char *nrname); + +typedef struct TDIR TDIR; + +TDIR * tfsOpendir(const char *rname); +const TFILE *tfsReaddir(TDIR *tdir); +void tfsClosedir(TDIR *tdir); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libs/tkv/tkv.h b/include/libs/tkv/tkv.h index edade1dc36..98194f090c 100644 --- a/include/libs/tkv/tkv.h +++ b/include/libs/tkv/tkv.h @@ -16,6 +16,7 @@ #ifndef _TD_TKV_H_ #define _TD_TKV_H_ +#if 0 #include "os.h" #ifdef __cplusplus @@ -59,4 +60,5 @@ void tkvWriteOptsDestroy(STkvWriteOpts *); } #endif +#endif #endif /*_TD_TKV_H_*/ \ No newline at end of file diff --git a/include/libs/transport/trpc.h b/include/libs/transport/trpc.h index b88d45fbd6..25e295f980 100644 --- a/include/libs/transport/trpc.h +++ b/include/libs/transport/trpc.h @@ -84,6 +84,55 @@ void rpcSendRecv(void *shandle, SEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp) int rpcReportProgress(void *pConn, char *pCont, int contLen); void rpcCancelRequest(int64_t rid); +typedef struct SDataBuf { + void *pData; + uint32_t len; +} SDataBuf; + +typedef int32_t (*__async_send_cb_fn_t)(void* param, const SDataBuf* pMsg, int32_t code); +typedef int32_t (*__async_exec_fn_t)(void* param); + +typedef struct SMsgSendInfo { + __async_send_cb_fn_t fp; //async callback function + void *param; + uint64_t requestId; + uint64_t requestObjRefId; + int32_t msgType; + SDataBuf msgInfo; +} SMsgSendInfo; + +typedef struct SQueryNodeAddr { + int32_t nodeId; // vgId or qnodeId + int8_t inUse; + int8_t numOfEps; + SEpAddr epAddr[TSDB_MAX_REPLICA]; +} SQueryNodeAddr; + +bool tIsValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_t numOfTags); + +int32_t initTaskQueue(); +int32_t cleanupTaskQueue(); + +/** + * + * @param execFn The asynchronously execution function + * @param execParam The parameters of the execFn + * @param code The response code during execution the execFn + * @return + */ +int32_t taosAsyncExec(__async_exec_fn_t execFn, void* execParam, int32_t* code); + +/** + * Asynchronously send message to server, after the response received, the callback will be incured. + * + * @param pTransporter + * @param epSet + * @param pTransporterId + * @param pInfo + * @return + */ +int32_t asyncSendMsgToServer(void *pTransporter, SEpSet* epSet, int64_t* pTransporterId, const SMsgSendInfo* pInfo); + #ifdef __cplusplus } #endif diff --git a/include/os/os.h b/include/os/os.h index 972880da9c..9112b4922f 100644 --- a/include/os/os.h +++ b/include/os/os.h @@ -24,10 +24,13 @@ extern "C" { #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -44,6 +47,8 @@ extern "C" { #include #include #include +#include +#include #include diff --git a/include/os/osDef.h b/include/os/osDef.h index bb5395f548..040c4bc7e7 100644 --- a/include/os/osDef.h +++ b/include/os/osDef.h @@ -73,6 +73,12 @@ extern "C" { #endif +#ifndef WINDOWS + #ifndef O_BINARY + #define O_BINARY 0 + #endif +#endif + #define POINTER_SHIFT(p, b) ((void *)((char *)(p) + (b))) #define POINTER_DISTANCE(p1, p2) ((char *)(p1) - (char *)(p2)) diff --git a/include/os/osFile.h b/include/os/osFile.h index 8d03759d82..2b0abc60ae 100644 --- a/include/os/osFile.h +++ b/include/os/osFile.h @@ -54,7 +54,7 @@ int32_t taosFtruncateFile(FileFd fd, int64_t length); int32_t taosFsyncFile(FileFd fd); int64_t taosReadFile(FileFd fd, void *buf, int64_t count); -int64_t taosWriteFile(FileFd fd, void *buf, int64_t count); +int64_t taosWriteFile(FileFd fd, const void *buf, int64_t count); void taosCloseFile(FileFd fd); diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 2dcc74213c..80241405a6 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -253,37 +253,36 @@ int32_t* taosGetErrno(); // dnode #define TSDB_CODE_DND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0400) -#define TSDB_CODE_DND_EXITING TAOS_DEF_ERROR_CODE(0, 0x0401) +#define TSDB_CODE_DND_OFFLINE TAOS_DEF_ERROR_CODE(0, 0x0401) #define TSDB_CODE_DND_INVALID_MSG_LEN TAOS_DEF_ERROR_CODE(0, 0x0402) #define TSDB_CODE_DND_DNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0410) #define TSDB_CODE_DND_DNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0411) #define TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0420) #define TSDB_CODE_DND_MNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0421) -#define TSDB_CODE_DND_MNODE_ID_INVALID TAOS_DEF_ERROR_CODE(0, 0x0422) -#define TSDB_CODE_DND_MNODE_ID_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0423) -#define TSDB_CODE_DND_MNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0424) -#define TSDB_CODE_DND_MNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0425) +#define TSDB_CODE_DND_MNODE_INVALID_OPTION TAOS_DEF_ERROR_CODE(0, 0x0422) +#define TSDB_CODE_DND_MNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0423) +#define TSDB_CODE_DND_MNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0424) #define TSDB_CODE_DND_QNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0430) #define TSDB_CODE_DND_QNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0431) -#define TSDB_CODE_DND_QNODE_ID_INVALID TAOS_DEF_ERROR_CODE(0, 0x0432) -#define TSDB_CODE_DND_QNODE_ID_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0433) -#define TSDB_CODE_DND_QNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0434) -#define TSDB_CODE_DND_QNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0435) +#define TSDB_CODE_DND_QNODE_INVALID_OPTION TAOS_DEF_ERROR_CODE(0, 0x0432) +#define TSDB_CODE_DND_QNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0433) +#define TSDB_CODE_DND_QNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0434) #define TSDB_CODE_DND_SNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0440) #define TSDB_CODE_DND_SNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0441) -#define TSDB_CODE_DND_SNODE_ID_INVALID TAOS_DEF_ERROR_CODE(0, 0x0442) -#define TSDB_CODE_DND_SNODE_ID_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0443) -#define TSDB_CODE_DND_SNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0444) -#define TSDB_CODE_DND_SNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0445) +#define TSDB_CODE_DND_SNODE_INVALID_OPTION TAOS_DEF_ERROR_CODE(0, 0x0442) +#define TSDB_CODE_DND_SNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0443) +#define TSDB_CODE_DND_SNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0444) #define TSDB_CODE_DND_BNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0450) #define TSDB_CODE_DND_BNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0451) -#define TSDB_CODE_DND_BNODE_ID_INVALID TAOS_DEF_ERROR_CODE(0, 0x0452) -#define TSDB_CODE_DND_BNODE_ID_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0453) -#define TSDB_CODE_DND_BNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0454) -#define TSDB_CODE_DND_BNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0455) -#define TSDB_CODE_DND_VNODE_TOO_MANY_VNODES TAOS_DEF_ERROR_CODE(0, 0x0460) -#define TSDB_CODE_DND_VNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0461) -#define TSDB_CODE_DND_VNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0462) +#define TSDB_CODE_DND_BNODE_INVALID_OPTION TAOS_DEF_ERROR_CODE(0, 0x0452) +#define TSDB_CODE_DND_BNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0453) +#define TSDB_CODE_DND_BNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0454) +#define TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0460) +#define TSDB_CODE_DND_VNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0461) +#define TSDB_CODE_DND_VNODE_INVALID_OPTION TAOS_DEF_ERROR_CODE(0, 0x0462) +#define TSDB_CODE_DND_VNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0463) +#define TSDB_CODE_DND_VNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0464) +#define TSDB_CODE_DND_VNODE_TOO_MANY_VNODES TAOS_DEF_ERROR_CODE(0, 0x0465) // vnode #define TSDB_CODE_VND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0500) //"Action in progress") @@ -401,6 +400,8 @@ int32_t* taosGetErrno(); #define TSDB_CODE_WAL_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x1000) //"Unexpected generic error in wal") #define TSDB_CODE_WAL_FILE_CORRUPTED TAOS_DEF_ERROR_CODE(0, 0x1001) //"WAL file is corrupted") #define TSDB_CODE_WAL_SIZE_LIMIT TAOS_DEF_ERROR_CODE(0, 0x1002) //"WAL size exceeds limit") +#define TSDB_CODE_WAL_INVALID_VER TAOS_DEF_ERROR_CODE(0, 0x1003) //"WAL invalid version") +#define TSDB_CODE_WAL_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x1004) //"WAL out of memory") // tfs #define TSDB_CODE_FS_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x2200) //"tfs out of memory") diff --git a/include/util/tcoding.h b/include/util/tcoding.h index e1edf0d792..226856901f 100644 --- a/include/util/tcoding.h +++ b/include/util/tcoding.h @@ -370,10 +370,33 @@ static FORCE_INLINE void *taosDecodeStringTo(void *buf, char *value) { return POINTER_SHIFT(buf, size); } +// ---- binary +static FORCE_INLINE int taosEncodeBinary(void **buf, const void *value, int valueLen) { + int tlen = 0; + + if (buf != NULL) { + memcpy(*buf, value, valueLen); + *buf = POINTER_SHIFT(*buf, valueLen); + } + tlen += (int)valueLen; + + return tlen; +} + +static FORCE_INLINE void *taosDecodeBinary(void *buf, void **value, int valueLen) { + uint64_t size = 0; + + *value = malloc((size_t)valueLen); + if (*value == NULL) return NULL; + memcpy(*value, buf, (size_t)size); + + return POINTER_SHIFT(buf, size); +} + #endif #ifdef __cplusplus } #endif -#endif /*_TD_UTIL_CODING_H*/ \ No newline at end of file +#endif /*_TD_UTIL_CODING_H*/ diff --git a/include/util/tdef.h b/include/util/tdef.h index 233e9f0f55..9f16b58e0d 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -177,6 +177,7 @@ do { \ #define TSDB_TYPE_STR_MAX_LEN 32 #define TSDB_TABLE_FNAME_LEN (TSDB_DB_FNAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_NAME_DELIMITER_LEN) #define TSDB_TOPIC_FNAME_LEN TSDB_TABLE_FNAME_LEN +#define TSDB_CONSUMER_GROUP_LEN 192 #define TSDB_COL_NAME_LEN 65 #define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64 #define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE diff --git a/include/util/thash.h b/include/util/thash.h index a736fc26af..3a614a73a6 100644 --- a/include/util/thash.h +++ b/include/util/thash.h @@ -124,6 +124,9 @@ int32_t taosHashGetSize(const SHashObj *pHashObj); */ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size); +int32_t taosHashPutExt(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size, bool *newAdded); + + /** * return the payload data with the specified key * @@ -210,6 +213,32 @@ void taosHashCancelIterate(SHashObj *pHashObj, void *p); */ int32_t taosHashGetKey(void *data, void** key, size_t* keyLen); + +/** + * Get the corresponding key information for a given data in hash table, using memcpy + * @param data + * @param dst + * @return + */ +static FORCE_INLINE int32_t taosHashCopyKey(void *data, void* dst) { + if (NULL == data || NULL == dst) { + return -1; + } + + SHashNode * node = GET_HASH_PNODE(data); + void* key = GET_HASH_NODE_KEY(node); + memcpy(dst, key, node->keyLen); + + return 0; +} + +/** + * Get the corresponding data length for a given data in hash table + * @param data + * @return + */ +int32_t taosHashGetDataLen(void *data); + /** * return the payload data with the specified key(reference number added) * diff --git a/include/util/tlog.h b/include/util/tlog.h index a367243a46..26a5417320 100644 --- a/include/util/tlog.h +++ b/include/util/tlog.h @@ -44,7 +44,6 @@ extern int32_t tsdbDebugFlag; extern int32_t tqDebugFlag; extern int32_t cqDebugFlag; extern int32_t debugFlag; -extern int32_t ctgDebugFlag; #define DEBUG_FATAL 1U #define DEBUG_ERROR DEBUG_FATAL diff --git a/include/util/tmacro.h b/include/util/tmacro.h index 5ed051c021..297c37d62a 100644 --- a/include/util/tmacro.h +++ b/include/util/tmacro.h @@ -26,14 +26,10 @@ extern "C" { #define TD_MOD_UNINITIALIZED 0 #define TD_MOD_INITIALIZED 1 -#define TD_MOD_UNCLEARD 0 -#define TD_MOD_CLEARD 1 - typedef int8_t td_mode_flag_t; #define TD_CHECK_AND_SET_MODE_INIT(FLAG) atomic_val_compare_exchange_8((FLAG), TD_MOD_UNINITIALIZED, TD_MOD_INITIALIZED) - -#define TD_CHECK_AND_SET_MOD_CLEAR(FLAG) atomic_val_compare_exchange_8((FLAG), TD_MOD_UNCLEARD, TD_MOD_CLEARD) +#define TD_CHECK_AND_SET_MOD_CLEAR(FLAG) atomic_val_compare_exchange_8((FLAG), TD_MOD_INITIALIZED, TD_MOD_UNINITIALIZED) #define TD_IS_NULL(PTR) ((PTR) == NULL) diff --git a/include/util/tqueue.h b/include/util/tqueue.h index a57bdb5ce8..63ba460d39 100644 --- a/include/util/tqueue.h +++ b/include/util/tqueue.h @@ -51,6 +51,7 @@ void taosFreeQitem(void *pItem); int32_t taosWriteQitem(STaosQueue *queue, void *pItem); int32_t taosReadQitem(STaosQueue *queue, void **ppItem); bool taosQueueEmpty(STaosQueue *queue); +int32_t taosQueueSize(STaosQueue *queue); STaosQall *taosAllocateQall(); void taosFreeQall(STaosQall *qall); diff --git a/source/client/inc/clientHb.h b/source/client/inc/clientHb.h new file mode 100644 index 0000000000..7bc4311b29 --- /dev/null +++ b/source/client/inc/clientHb.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "os.h" +#include "tarray.h" +#include "thash.h" +#include "tmsg.h" + +#define HEARTBEAT_INTERVAL 1500 // ms + +typedef enum { + HEARTBEAT_TYPE_MQ = 0, + // types can be added here + // + HEARTBEAT_TYPE_MAX +} EHbType; + +typedef int32_t (*FHbRspHandle)(SClientHbRsp* pReq); + +typedef struct SAppHbMgr { + // statistics + int32_t reportCnt; + int32_t connKeyCnt; + int64_t reportBytes; // not implemented + int64_t startTime; + // ctl + SRWLatch lock; // lock is used in serialization + // connection + void* transporter; + SEpSet epSet; + // info + SHashObj* activeInfo; // hash + SHashObj* getInfoFuncs; // hash +} SAppHbMgr; + +typedef struct SClientHbMgr { + int8_t inited; + // ctl + int8_t threadStop; + pthread_t thread; + pthread_mutex_t lock; // used when app init and cleanup + SArray* appHbMgrs; // SArray one for each cluster + FHbRspHandle handle[HEARTBEAT_TYPE_MAX]; +} SClientHbMgr; + +// TODO: embed param into function +// return type: SArray +typedef SArray* (*FGetConnInfo)(SClientHbKey connKey, void* param); + +// global, called by mgmt +int hbMgrInit(); +void hbMgrCleanUp(); +int hbHandleRsp(SClientHbBatchRsp* hbRsp); + +// cluster level +SAppHbMgr* appHbMgrInit(void* transporter, SEpSet epSet); +void appHbMgrCleanup(SAppHbMgr* pAppHbMgr); + +// conn level +int hbRegisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, FGetConnInfo func); +void hbDeregisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey); + +int hbAddConnInfo(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, void* key, void* value, int32_t keyLen, int32_t valueLen); + +// mq +void hbMgrInitMqHbRspHandle(); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 705d6ef786..26afe237c9 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -62,6 +62,7 @@ typedef struct SAppInstInfo { SList *pConnList; // STscObj linked list int64_t clusterId; void *pTransporter; + SHeartBeatInfo hb; } SAppInstInfo; typedef struct SAppInfo { @@ -70,7 +71,7 @@ typedef struct SAppInfo { char *ep; int32_t pid; int32_t numOfThreads; - SHeartBeatInfo hb; + SHashObj *pInstMap; } SAppInfo; diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 47d0e517d5..0e3afb60c0 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -180,6 +180,14 @@ void* createRequest(STscObj* pObj, __taos_async_fn_t fp, void* param, int32_t ty return pRequest; } +static void doFreeReqResultInfo(SReqResultInfo* pResInfo) { + tfree(pResInfo->pRspMsg); + tfree(pResInfo->length); + tfree(pResInfo->row); + tfree(pResInfo->pCol); + tfree(pResInfo->fields); +} + static void doDestroyRequest(void* p) { assert(p != NULL); SRequestObj* pRequest = (SRequestObj*)p; @@ -190,7 +198,7 @@ static void doDestroyRequest(void* p) { tfree(pRequest->sqlstr); tfree(pRequest->pInfo); - tfree(pRequest->body.resInfo.pRspMsg); + doFreeReqResultInfo(&pRequest->body.resInfo); deregisterRequest(pRequest); tfree(pRequest); @@ -415,7 +423,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { *+------------+-----+-----------+---------------+ *| uid|localIp| PId | timestamp | serial number | *+------------+-----+-----------+---------------+ - *| 16bit |12bit|20bit |16bit | + *| 12bit |12bit|24bit |16bit | *+------------+-----+-----------+---------------+ * @return */ @@ -435,11 +443,11 @@ uint64_t generateRequestId() { } } - int64_t ts = taosGetTimestampUs(); + int64_t ts = taosGetTimestampMs(); uint64_t pid = taosGetPId(); int32_t val = atomic_add_fetch_32(&requestSerialId, 1); - uint64_t id = ((hashId & 0xFFFF) << 48) | ((pid & 0x0FFF) << 36) | ((ts & 0xFFFFF) << 16) | (val & 0xFFFF); + uint64_t id = ((hashId & 0x0FFF) << 52) | ((pid & 0x0FFF) << 40) | ((ts & 0xFFFFFF) << 16) | (val & 0xFFFF); return id; } diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c new file mode 100644 index 0000000000..9bbd62c1d9 --- /dev/null +++ b/source/client/src/clientHb.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "clientHb.h" +#include "trpc.h" + +static SClientHbMgr clientHbMgr = {0}; + +static int32_t hbCreateThread(); +static void hbStopThread(); + +static int32_t hbMqHbRspHandle(SClientHbRsp* pReq) { + return 0; +} + +void hbMgrInitMqHbRspHandle() { + clientHbMgr.handle[HEARTBEAT_TYPE_MQ] = hbMqHbRspHandle; +} + +static FORCE_INLINE void hbMgrInitHandle() { + // init all handle + hbMgrInitMqHbRspHandle(); +} + +SClientHbBatchReq* hbGatherAllInfo(SAppHbMgr *pAppHbMgr) { + SClientHbBatchReq* pReq = malloc(sizeof(SClientHbBatchReq)); + if (pReq == NULL) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; + return NULL; + } + int32_t connKeyCnt = atomic_load_32(&pAppHbMgr->connKeyCnt); + pReq->reqs = taosArrayInit(connKeyCnt, sizeof(SClientHbReq)); + + void *pIter = taosHashIterate(pAppHbMgr->activeInfo, NULL); + while (pIter != NULL) { + taosArrayPush(pReq->reqs, pIter); + SClientHbReq* pOneReq = pIter; + taosHashClear(pOneReq->info); + + pIter = taosHashIterate(pAppHbMgr->activeInfo, pIter); + } + + pIter = taosHashIterate(pAppHbMgr->getInfoFuncs, NULL); + while (pIter != NULL) { + FGetConnInfo getConnInfoFp = (FGetConnInfo)pIter; + SClientHbKey connKey; + taosHashCopyKey(pIter, &connKey); + getConnInfoFp(connKey, NULL); + + pIter = taosHashIterate(pAppHbMgr->activeInfo, pIter); + } + + return pReq; +} + +static void* hbThreadFunc(void* param) { + setThreadName("hb"); + while (1) { + int8_t threadStop = atomic_load_8(&clientHbMgr.threadStop); + if(threadStop) { + break; + } + + int sz = taosArrayGetSize(clientHbMgr.appHbMgrs); + for(int i = 0; i < sz; i++) { + SAppHbMgr* pAppHbMgr = taosArrayGet(clientHbMgr.appHbMgrs, i); + SClientHbBatchReq* pReq = hbGatherAllInfo(pAppHbMgr); + void* reqStr = NULL; + int tlen = tSerializeSClientHbBatchReq(&reqStr, pReq); + SMsgSendInfo info; + /*info.fp = hbHandleRsp;*/ + + int64_t transporterId = 0; + asyncSendMsgToServer(pAppHbMgr->transporter, &pAppHbMgr->epSet, &transporterId, &info); + tFreeClientHbBatchReq(pReq); + + atomic_add_fetch_32(&pAppHbMgr->reportCnt, 1); + taosMsleep(HEARTBEAT_INTERVAL); + } + } + return NULL; +} + +static int32_t hbCreateThread() { + pthread_attr_t thAttr; + pthread_attr_init(&thAttr); + pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE); + + if (pthread_create(&clientHbMgr.thread, &thAttr, hbThreadFunc, NULL) != 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + return -1; + } + pthread_attr_destroy(&thAttr); + return 0; +} + +static void hbStopThread() { + atomic_store_8(&clientHbMgr.threadStop, 1); +} + +SAppHbMgr* appHbMgrInit(void* transporter, SEpSet epSet) { + SAppHbMgr* pAppHbMgr = malloc(sizeof(SAppHbMgr)); + if (pAppHbMgr == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return NULL; + } + // init stat + pAppHbMgr->startTime = taosGetTimestampMs(); + + // init connection info + pAppHbMgr->transporter = transporter; + pAppHbMgr->epSet = epSet; + + // init hash info + pAppHbMgr->activeInfo = taosHashInit(64, hbKeyHashFunc, 1, HASH_ENTRY_LOCK); + pAppHbMgr->activeInfo->freeFp = tFreeClientHbReq; + // init getInfoFunc + pAppHbMgr->getInfoFuncs = taosHashInit(64, hbKeyHashFunc, 1, HASH_ENTRY_LOCK); + + taosArrayPush(clientHbMgr.appHbMgrs, &pAppHbMgr); + return pAppHbMgr; +} + +void appHbMgrCleanup(SAppHbMgr* pAppHbMgr) { + pthread_mutex_lock(&clientHbMgr.lock); + + int sz = taosArrayGetSize(clientHbMgr.appHbMgrs); + for (int i = 0; i < sz; i++) { + SAppHbMgr* pTarget = taosArrayGet(clientHbMgr.appHbMgrs, i); + if (pAppHbMgr == pTarget) { + taosHashCleanup(pTarget->activeInfo); + taosHashCleanup(pTarget->getInfoFuncs); + } + } + + pthread_mutex_unlock(&clientHbMgr.lock); +} + +int hbMgrInit() { + // init once + int8_t old = atomic_val_compare_exchange_8(&clientHbMgr.inited, 0, 1); + if (old == 1) return 0; + + clientHbMgr.appHbMgrs = taosArrayInit(0, sizeof(void*)); + pthread_mutex_init(&clientHbMgr.lock, NULL); + + // init handle funcs + hbMgrInitHandle(); + + // init backgroud thread + hbCreateThread(); + + return 0; +} + +void hbMgrCleanUp() { + // destroy all appHbMgr + int8_t old = atomic_val_compare_exchange_8(&clientHbMgr.inited, 1, 0); + if (old == 0) return; + + taosArrayDestroy(clientHbMgr.appHbMgrs); + +} + +int hbHandleRsp(SClientHbBatchRsp* hbRsp) { + int64_t reqId = hbRsp->reqId; + int64_t rspId = hbRsp->rspId; + + SArray* rsps = hbRsp->rsps; + int32_t sz = taosArrayGetSize(rsps); + for (int i = 0; i < sz; i++) { + SClientHbRsp* pRsp = taosArrayGet(rsps, i); + if (pRsp->connKey.hbType < HEARTBEAT_TYPE_MAX) { + clientHbMgr.handle[pRsp->connKey.hbType](pRsp); + } else { + // discard rsp + } + } + return 0; +} + +int hbRegisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, FGetConnInfo func) { + // init hash in activeinfo + void* data = taosHashGet(pAppHbMgr->activeInfo, &connKey, sizeof(SClientHbKey)); + if (data != NULL) { + return 0; + } + SClientHbReq hbReq; + hbReq.connKey = connKey; + hbReq.info = taosHashInit(64, hbKeyHashFunc, 1, HASH_ENTRY_LOCK); + taosHashPut(pAppHbMgr->activeInfo, &connKey, sizeof(SClientHbKey), &hbReq, sizeof(SClientHbReq)); + // init hash + if (func != NULL) { + taosHashPut(pAppHbMgr->getInfoFuncs, &connKey, sizeof(SClientHbKey), func, sizeof(FGetConnInfo)); + } + + atomic_add_fetch_32(&pAppHbMgr->connKeyCnt, 1); + return 0; +} + +void hbDeregisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey) { + taosHashRemove(pAppHbMgr->activeInfo, &connKey, sizeof(SClientHbKey)); + taosHashRemove(pAppHbMgr->getInfoFuncs, &connKey, sizeof(SClientHbKey)); + atomic_sub_fetch_32(&pAppHbMgr->connKeyCnt, 1); +} + +int hbAddConnInfo(SAppHbMgr *pAppHbMgr, SClientHbKey connKey, void* key, void* value, int32_t keyLen, int32_t valueLen) { + // find req by connection id + SClientHbReq* pReq = taosHashGet(pAppHbMgr->activeInfo, &connKey, sizeof(SClientHbKey)); + ASSERT(pReq != NULL); + + taosHashPut(pReq->info, key, keyLen, value, valueLen); + + return 0; +} diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index a967a65c44..d18142cebf 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -140,7 +140,7 @@ int32_t buildRequest(STscObj *pTscObj, const char *sql, int sqlLen, SRequestObj* (*pRequest)->sqlstr[sqlLen] = 0; (*pRequest)->sqlLen = sqlLen; - tscDebugL("0x%"PRIx64" SQL: %s, reqId:0x"PRIx64, (*pRequest)->self, (*pRequest)->sqlstr, (*pRequest)->requestId); + tscDebugL("0x%"PRIx64" SQL: %s, reqId:0x%"PRIx64, (*pRequest)->self, (*pRequest)->sqlstr, (*pRequest)->requestId); return TSDB_CODE_SUCCESS; } @@ -181,7 +181,7 @@ int32_t execDdlQuery(SRequestObj* pRequest, SQueryNode* pQuery) { if (pDcl->msgType == TDMT_VND_SHOW_TABLES) { SShowReqInfo* pShowReqInfo = &pRequest->body.showInfo; if (pShowReqInfo->pArray == NULL) { - pShowReqInfo->currentIndex = 0; + pShowReqInfo->currentIndex = 0; // set the first vnode/ then iterate the next vnode pShowReqInfo->pArray = pDcl->pExtension; } } @@ -192,24 +192,32 @@ int32_t execDdlQuery(SRequestObj* pRequest, SQueryNode* pQuery) { } tsem_wait(&pRequest->body.rspSem); - destroySendMsgInfo(pSendMsg); return TSDB_CODE_SUCCESS; } -int32_t getPlan(SRequestObj* pRequest, SQueryNode* pQuery, SQueryDag** pDag) { - pRequest->type = pQuery->type; - return qCreateQueryDag(pQuery, pDag, pRequest->requestId); +int32_t getPlan(SRequestObj* pRequest, SQueryNode* pQueryNode, SQueryDag** pDag) { + pRequest->type = pQueryNode->type; + return qCreateQueryDag(pQueryNode, pDag, pRequest->requestId); } int32_t scheduleQuery(SRequestObj* pRequest, SQueryDag* pDag, void** pJob) { if (TSDB_SQL_INSERT == pRequest->type || TSDB_SQL_CREATE_TABLE == pRequest->type) { SQueryResult res = {.code = 0, .numOfRows = 0, .msgSize = ERROR_MSG_BUF_DEFAULT_SIZE, .msg = pRequest->msgBuf}; + int32_t code = scheduleExecJob(pRequest->pTscObj->pTransporter, NULL, pDag, pJob, &res); + if (code != TSDB_CODE_SUCCESS) { + // handle error and retry + } else { + if (*pJob != NULL) { + scheduleFreeJob(*pJob); + } + } + pRequest->affectedRows = res.numOfRows; return res.code; } - return scheduleAsyncExecJob(pRequest->pTscObj->pTransporter, NULL/*todo appInfo.xxx*/, pDag, pJob); + return scheduleAsyncExecJob(pRequest->pTscObj->pTransporter, NULL /*todo appInfo.xxx*/, pDag, pJob); } TAOS_RES *tmq_create_topic(TAOS* taos, const char* name, const char* sql, int sqlLen) { @@ -283,10 +291,10 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) { nPrintTsc("%s", sql) - SRequestObj* pRequest = NULL; - SQueryNode* pQuery = NULL; - SQueryDag* pDag = NULL; - void* pJob = NULL; + SRequestObj *pRequest = NULL; + SQueryNode *pQuery = NULL; + SQueryDag *pDag = NULL; + void *pJob = NULL; terrno = TSDB_CODE_SUCCESS; CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return); @@ -297,6 +305,8 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) { } else { CHECK_CODE_GOTO(getPlan(pRequest, pQuery, &pDag), _return); CHECK_CODE_GOTO(scheduleQuery(pRequest, pDag, &pJob), _return); + pRequest->code = terrno; + return pRequest; } _return: @@ -364,8 +374,6 @@ STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, con asyncSendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); tsem_wait(&pRequest->body.rspSem); - destroySendMsgInfo(body); - if (pRequest->code != TSDB_CODE_SUCCESS) { const char *errorMsg = (pRequest->code == TSDB_CODE_RPC_FQDN_ERROR) ? taos_errstr(pRequest) : tstrerror(terrno); printf("failed to connect to server, reason: %s\n\n", errorMsg); @@ -389,13 +397,13 @@ static SMsgSendInfo* buildConnectMsg(SRequestObj *pRequest) { } pMsgSendInfo->msgType = TDMT_MND_CONNECT; - pMsgSendInfo->msgInfo.len = sizeof(SConnectMsg); + pMsgSendInfo->msgInfo.len = sizeof(SConnectReq); pMsgSendInfo->requestObjRefId = pRequest->self; pMsgSendInfo->requestId = pRequest->requestId; pMsgSendInfo->fp = handleRequestRspFp[TMSG_INDEX(pMsgSendInfo->msgType)]; pMsgSendInfo->param = pRequest; - SConnectMsg *pConnect = calloc(1, sizeof(SConnectMsg)); + SConnectReq *pConnect = calloc(1, sizeof(SConnectReq)); if (pConnect == NULL) { tfree(pMsgSendInfo); terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -456,17 +464,21 @@ void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) { taosReleaseRef(clientReqRefPool, pSendInfo->requestObjRefId); } - SDataBuf buf = {.len = pMsg->contLen}; - buf.pData = calloc(1, pMsg->contLen); - if (buf.pData == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - pMsg->code = TSDB_CODE_OUT_OF_MEMORY; - } else { - memcpy(buf.pData, pMsg->pCont, pMsg->contLen); + SDataBuf buf = {.len = pMsg->contLen, .pData = NULL}; + + if (pMsg->contLen > 0) { + buf.pData = calloc(1, pMsg->contLen); + if (buf.pData == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + pMsg->code = TSDB_CODE_OUT_OF_MEMORY; + } else { + memcpy(buf.pData, pMsg->pCont, pMsg->contLen); + } } pSendInfo->fp(pSendInfo->param, &buf, pMsg->code); rpcFreeCont(pMsg->pCont); + destroySendMsgInfo(pSendInfo); } TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port) { @@ -525,9 +537,7 @@ void* doFetchRow(SRequestObj* pRequest) { int64_t transporterId = 0; STscObj *pTscObj = pRequest->pTscObj; asyncSendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); - tsem_wait(&pRequest->body.rspSem); - destroySendMsgInfo(body); pRequest->type = TDMT_VND_SHOW_TABLES_FETCH; } @@ -539,7 +549,6 @@ void* doFetchRow(SRequestObj* pRequest) { asyncSendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); tsem_wait(&pRequest->body.rspSem); - destroySendMsgInfo(body); pResultInfo->current = 0; if (pResultInfo->numOfRows <= pResultInfo->current) { diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 2b875b3eb5..1238976b97 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -1,11 +1,12 @@ #include "os.h" +#include "tref.h" +#include "trpc.h" #include "clientInt.h" #include "clientLog.h" #include "query.h" #include "tmsg.h" #include "tglobal.h" -#include "tref.h" -#include "trpc.h" +#include "catalog.h" #define TSC_VAR_NOT_RELEASE 1 #define TSC_VAR_RELEASED 0 @@ -46,6 +47,7 @@ void taos_cleanup(void) { taosCloseRef(id); rpcCleanup(); + catalogDestroy(); taosCloseLog(); tscInfo("all local resources released"); diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index e402403496..85f3fb06a7 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -30,6 +30,7 @@ int genericRspCallback(void* param, const SDataBuf* pMsg, int32_t code) { SRequestObj* pRequest = param; setErrno(pRequest, code); + free(pMsg->pData); sem_post(&pRequest->body.rspSem); return code; } @@ -37,6 +38,7 @@ int genericRspCallback(void* param, const SDataBuf* pMsg, int32_t code) { int processConnectRsp(void* param, const SDataBuf* pMsg, int32_t code) { SRequestObj* pRequest = param; if (code != TSDB_CODE_SUCCESS) { + free(pMsg->pData); setErrno(pRequest, code); sem_post(&pRequest->body.rspSem); return code; @@ -73,6 +75,7 @@ int processConnectRsp(void* param, const SDataBuf* pMsg, int32_t code) { tscDebug("0x%" PRIx64 " clusterId:%" PRId64 ", totalConn:%" PRId64, pRequest->requestId, pConnect->clusterId, pTscObj->pAppInfo->numOfConns); + free(pMsg->pData); sem_post(&pRequest->body.rspSem); return 0; } @@ -87,14 +90,14 @@ SMsgSendInfo* buildMsgInfoImpl(SRequestObj *pRequest) { if (pRequest->type == TDMT_MND_SHOW_RETRIEVE || pRequest->type == TDMT_VND_SHOW_TABLES_FETCH) { if (pRequest->type == TDMT_MND_SHOW_RETRIEVE) { - SRetrieveTableMsg* pRetrieveMsg = calloc(1, sizeof(SRetrieveTableMsg)); + SRetrieveTableReq* pRetrieveMsg = calloc(1, sizeof(SRetrieveTableReq)); if (pRetrieveMsg == NULL) { return NULL; } pRetrieveMsg->showId = htobe64(pRequest->body.showInfo.execId); pMsgSendInfo->msgInfo.pData = pRetrieveMsg; - pMsgSendInfo->msgInfo.len = sizeof(SRetrieveTableMsg); + pMsgSendInfo->msgInfo.len = sizeof(SRetrieveTableReq); } else { SVShowTablesFetchReq* pFetchMsg = calloc(1, sizeof(SVShowTablesFetchReq)); if (pFetchMsg == NULL) { @@ -127,7 +130,7 @@ int32_t processShowRsp(void* param, const SDataBuf* pMsg, int32_t code) { SShowRsp* pShow = (SShowRsp *)pMsg->pData; pShow->showId = htobe64(pShow->showId); - STableMetaMsg *pMetaMsg = &(pShow->tableMeta); + STableMetaRsp *pMetaMsg = &(pShow->tableMeta); pMetaMsg->numOfColumns = htonl(pMetaMsg->numOfColumns); SSchema* pSchema = pMetaMsg->pSchema; @@ -238,6 +241,7 @@ int32_t processRetrieveVndRsp(void* param, const SDataBuf* pMsg, int32_t code) { int32_t processCreateDbRsp(void* param, const SDataBuf* pMsg, int32_t code) { // todo rsp with the vnode id list SRequestObj* pRequest = param; + free(pMsg->pData); tsem_post(&pRequest->body.rspSem); } @@ -245,6 +249,7 @@ int32_t processUseDbRsp(void* param, const SDataBuf* pMsg, int32_t code) { SRequestObj* pRequest = param; if (code != TSDB_CODE_SUCCESS) { + free(pMsg->pData); setErrno(pRequest, code); tsem_post(&pRequest->body.rspSem); return code; @@ -258,6 +263,7 @@ int32_t processUseDbRsp(void* param, const SDataBuf* pMsg, int32_t code) { tNameGetDbName(&name, db); setConnectionDB(pRequest->pTscObj, db); + free(pMsg->pData); tsem_post(&pRequest->body.rspSem); return 0; } @@ -266,6 +272,7 @@ int32_t processCreateTableRsp(void* param, const SDataBuf* pMsg, int32_t code) { assert(pMsg != NULL && param != NULL); SRequestObj* pRequest = param; + free(pMsg->pData); if (code != TSDB_CODE_SUCCESS) { setErrno(pRequest, code); tsem_post(&pRequest->body.rspSem); diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index 26f1141cc0..73c9fc5e9f 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -101,17 +101,18 @@ TEST(testCase, show_user_Test) { assert(pConn != NULL); TAOS_RES* pRes = taos_query(pConn, "show users"); - TAOS_ROW pRow = NULL; + TAOS_ROW pRow = NULL; TAOS_FIELD* pFields = taos_fetch_fields(pRes); - int32_t numOfFields = taos_num_fields(pRes); + int32_t numOfFields = taos_num_fields(pRes); char str[512] = {0}; - while((pRow = taos_fetch_row(pRes)) != NULL) { + while ((pRow = taos_fetch_row(pRes)) != NULL) { int32_t code = taos_print_row(str, pRow, pFields, numOfFields); printf("%s\n", str); } + taos_free_result(pRes); taos_close(pConn); } @@ -130,16 +131,16 @@ TEST(testCase, drop_user_Test) { TEST(testCase, show_db_Test) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); + assert(pConn != NULL); TAOS_RES* pRes = taos_query(pConn, "show databases"); - TAOS_ROW pRow = NULL; + TAOS_ROW pRow = NULL; TAOS_FIELD* pFields = taos_fetch_fields(pRes); - int32_t numOfFields = taos_num_fields(pRes); + int32_t numOfFields = taos_num_fields(pRes); char str[512] = {0}; - while((pRow = taos_fetch_row(pRes)) != NULL) { + while ((pRow = taos_fetch_row(pRes)) != NULL) { int32_t code = taos_print_row(str, pRow, pFields, numOfFields); printf("%s\n", str); } @@ -151,7 +152,7 @@ TEST(testCase, create_db_Test) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); assert(pConn != NULL); - TAOS_RES* pRes = taos_query(pConn, "create database abc1"); + TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2"); if (taos_errno(pRes) != 0) { printf("error in create db, reason:%s\n", taos_errstr(pRes)); } @@ -170,90 +171,90 @@ TEST(testCase, create_db_Test) { } taos_close(pConn); } -// -//TEST(testCase, create_dnode_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "create dnode abc1 port 7000"); -// if (taos_errno(pRes) != 0) { -// printf("error in create dnode, reason:%s\n", taos_errstr(pRes)); -// } -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "create dnode 1.1.1.1 port 9000"); -// if (taos_errno(pRes) != 0) { -// printf("failed to create dnode, reason:%s\n", taos_errstr(pRes)); -// } -// taos_free_result(pRes); -// -// taos_close(pConn); -//} -// -//TEST(testCase, drop_dnode_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "drop dnode 2"); -// if (taos_errno(pRes) != 0) { -// printf("error in drop dnode, reason:%s\n", taos_errstr(pRes)); -// } -// -// TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// ASSERT_TRUE(pFields == NULL); -// -// int32_t numOfFields = taos_num_fields(pRes); -// ASSERT_EQ(numOfFields, 0); -// -// taos_free_result(pRes); -// taos_close(pConn); -//} -// -//TEST(testCase, use_db_test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "use abc1"); -// if (taos_errno(pRes) != 0) { -// printf("error in use db, reason:%s\n", taos_errstr(pRes)); -// } -// -// TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// ASSERT_TRUE(pFields == NULL); -// -// int32_t numOfFields = taos_num_fields(pRes); -// ASSERT_EQ(numOfFields, 0); -// -// taos_close(pConn); -//} -//TEST(testCase, drop_db_test) { -//// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -//// assert(pConn != NULL); -//// -//// showDB(pConn); -//// -//// TAOS_RES* pRes = taos_query(pConn, "drop database abc1"); -//// if (taos_errno(pRes) != 0) { -//// printf("failed to drop db, reason:%s\n", taos_errstr(pRes)); -//// } -//// taos_free_result(pRes); -//// -//// showDB(pConn); -//// -//// pRes = taos_query(pConn, "create database abc1"); -//// if (taos_errno(pRes) != 0) { -//// printf("create to drop db, reason:%s\n", taos_errstr(pRes)); -//// } -//// taos_free_result(pRes); -//// taos_close(pConn); -//} - - TEST(testCase, create_stable_Test) { +TEST(testCase, create_dnode_Test) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); assert(pConn != NULL); - TAOS_RES* pRes = taos_query(pConn, "create database abc1"); + TAOS_RES* pRes = taos_query(pConn, "create dnode abc1 port 7000"); + if (taos_errno(pRes) != 0) { + printf("error in create dnode, reason:%s\n", taos_errstr(pRes)); + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "create dnode 1.1.1.1 port 9000"); + if (taos_errno(pRes) != 0) { + printf("failed to create dnode, reason:%s\n", taos_errstr(pRes)); + } + taos_free_result(pRes); + + taos_close(pConn); +} + +TEST(testCase, drop_dnode_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); + + TAOS_RES* pRes = taos_query(pConn, "drop dnode 2"); + if (taos_errno(pRes) != 0) { + printf("error in drop dnode, reason:%s\n", taos_errstr(pRes)); + } + + TAOS_FIELD* pFields = taos_fetch_fields(pRes); + ASSERT_TRUE(pFields == NULL); + + int32_t numOfFields = taos_num_fields(pRes); + ASSERT_EQ(numOfFields, 0); + + taos_free_result(pRes); + taos_close(pConn); +} + +TEST(testCase, use_db_test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); + + TAOS_RES* pRes = taos_query(pConn, "use abc1"); + if (taos_errno(pRes) != 0) { + printf("error in use db, reason:%s\n", taos_errstr(pRes)); + } + + TAOS_FIELD* pFields = taos_fetch_fields(pRes); + ASSERT_TRUE(pFields == NULL); + + int32_t numOfFields = taos_num_fields(pRes); + ASSERT_EQ(numOfFields, 0); + + taos_close(pConn); +} + +// TEST(testCase, drop_db_test) { +// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); +// assert(pConn != NULL); +// +// showDB(pConn); +// +// TAOS_RES* pRes = taos_query(pConn, "drop database abc1"); +// if (taos_errno(pRes) != 0) { +// printf("failed to drop db, reason:%s\n", taos_errstr(pRes)); +// } +// taos_free_result(pRes); +// +// showDB(pConn); +// +// pRes = taos_query(pConn, "create database abc1"); +// if (taos_errno(pRes) != 0) { +// printf("create to drop db, reason:%s\n", taos_errstr(pRes)); +// } +// taos_free_result(pRes); +// taos_close(pConn); +//} + +TEST(testCase, create_stable_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); + + TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2"); if (taos_errno(pRes) != 0) { printf("error in create db, reason:%s\n", taos_errstr(pRes)); } @@ -280,128 +281,227 @@ TEST(testCase, create_db_Test) { taos_close(pConn); } -//TEST(testCase, create_table_Test) { -// // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// // assert(pConn != NULL); -// // -// // TAOS_RES* pRes = taos_query(pConn, "use abc1"); -// // taos_free_result(pRes); -// // -// // pRes = taos_query(pConn, "create table tm0(ts timestamp, k int)"); -// // taos_free_result(pRes); -// // -// // taos_close(pConn); -//} -// -//TEST(testCase, create_ctable_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "use abc1"); -// if (taos_errno(pRes) != 0) { -// printf("failed to use db, reason:%s\n", taos_errstr(pRes)); -// } -// taos_free_result(pRes); -// -//// pRes = taos_query(pConn, "create table tm0 using st1 tags(1)"); -//// if (taos_errno(pRes) != 0) { -//// printf("failed to create child table tm0, reason:%s\n", taos_errstr(pRes)); -//// } -//// -//// taos_free_result(pRes); -// taos_close(pConn); -//} -// -//TEST(testCase, show_stable_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "use abc1"); -// if (taos_errno(pRes) != 0) { -// printf("failed to use db, reason:%s\n", taos_errstr(pRes)); -// } -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "show stables"); -// if (taos_errno(pRes) != 0) { -// printf("failed to show stables, reason:%s\n", taos_errstr(pRes)); -// taos_free_result(pRes); -// ASSERT_TRUE(false); -// } -// -// TAOS_ROW pRow = NULL; -// TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// int32_t numOfFields = taos_num_fields(pRes); -// -// char str[512] = {0}; -// while((pRow = taos_fetch_row(pRes)) != NULL) { -// int32_t code = taos_print_row(str, pRow, pFields, numOfFields); -// printf("%s\n", str); -// } -// -// taos_free_result(pRes); -// taos_close(pConn); -//} -// -//TEST(testCase, show_vgroup_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "use abc1"); -// if (taos_errno(pRes) != 0) { -// printf("failed to use db, reason:%s\n", taos_errstr(pRes)); -// } -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "show vgroups"); -// if (taos_errno(pRes) != 0) { -// printf("failed to show vgroups, reason:%s\n", taos_errstr(pRes)); -// taos_free_result(pRes); -// ASSERT_TRUE(false); -// } -// -// TAOS_ROW pRow = NULL; -// -// TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// int32_t numOfFields = taos_num_fields(pRes); -// -// char str[512] = {0}; -// while((pRow = taos_fetch_row(pRes)) != NULL) { -// int32_t code = taos_print_row(str, pRow, pFields, numOfFields); -// printf("%s\n", str); -// } -// -// taos_free_result(pRes); -// -// taos_close(pConn); -//} -// -//TEST(testCase, drop_stable_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "create database abc1"); -// if (taos_errno(pRes) != 0) { -// printf("error in creating db, reason:%s\n", taos_errstr(pRes)); -// } -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "use abc1"); -// if (taos_errno(pRes) != 0) { -// printf("error in using db, reason:%s\n", taos_errstr(pRes)); -// } -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "drop stable st1"); -// if (taos_errno(pRes) != 0) { -// printf("failed to drop stable, reason:%s\n", taos_errstr(pRes)); -// } -// -// taos_free_result(pRes); -// taos_close(pConn); -//} +TEST(testCase, create_table_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); -//TEST(testCase, create_topic_Test) { + TAOS_RES* pRes = taos_query(pConn, "use abc1"); + taos_free_result(pRes); + + pRes = taos_query(pConn, "create table tm0(ts timestamp, k int)"); + taos_free_result(pRes); + + taos_close(pConn); +} + +TEST(testCase, create_ctable_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); + + TAOS_RES* pRes = taos_query(pConn, "use abc1"); + if (taos_errno(pRes) != 0) { + printf("failed to use db, reason:%s\n", taos_errstr(pRes)); + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "create table tm0 using st1 tags(1)"); + if (taos_errno(pRes) != 0) { + printf("failed to create child table tm0, reason:%s\n", taos_errstr(pRes)); + } + + taos_free_result(pRes); + taos_close(pConn); +} + +TEST(testCase, show_stable_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); + + TAOS_RES* pRes = taos_query(pConn, "use abc1"); + if (taos_errno(pRes) != 0) { + printf("failed to use db, reason:%s\n", taos_errstr(pRes)); + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "show stables"); + if (taos_errno(pRes) != 0) { + printf("failed to show stables, reason:%s\n", taos_errstr(pRes)); + taos_free_result(pRes); + ASSERT_TRUE(false); + } + + TAOS_ROW pRow = NULL; + TAOS_FIELD* pFields = taos_fetch_fields(pRes); + int32_t numOfFields = taos_num_fields(pRes); + + char str[512] = {0}; + while ((pRow = taos_fetch_row(pRes)) != NULL) { + int32_t code = taos_print_row(str, pRow, pFields, numOfFields); + printf("%s\n", str); + } + + taos_free_result(pRes); + taos_close(pConn); +} + +TEST(testCase, show_vgroup_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); + + TAOS_RES* pRes = taos_query(pConn, "use abc1"); + if (taos_errno(pRes) != 0) { + printf("failed to use db, reason:%s\n", taos_errstr(pRes)); + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "show vgroups"); + if (taos_errno(pRes) != 0) { + printf("failed to show vgroups, reason:%s\n", taos_errstr(pRes)); + taos_free_result(pRes); + ASSERT_TRUE(false); + } + + TAOS_ROW pRow = NULL; + + TAOS_FIELD* pFields = taos_fetch_fields(pRes); + int32_t numOfFields = taos_num_fields(pRes); + + char str[512] = {0}; + while ((pRow = taos_fetch_row(pRes)) != NULL) { + int32_t code = taos_print_row(str, pRow, pFields, numOfFields); + printf("%s\n", str); + } + + taos_free_result(pRes); + taos_close(pConn); +} + +TEST(testCase, create_multiple_tables) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(pConn, nullptr); + + TAOS_RES* pRes = taos_query(pConn, "use abc1"); + if (taos_errno(pRes) != 0) { + printf("failed to use db, reason:%s", taos_errstr(pRes)); + taos_free_result(pRes); + taos_close(pConn); + return; + } + + taos_free_result(pRes); + + pRes = taos_query(pConn, "create table t_2 using st1 tags(1)"); + if (taos_errno(pRes) != 0) { + printf("failed to create multiple tables, reason:%s\n", taos_errstr(pRes)); + taos_free_result(pRes); + ASSERT_TRUE(false); + } + + taos_free_result(pRes); + pRes = taos_query(pConn, "create table t_3 using st1 tags(2)"); + if (taos_errno(pRes) != 0) { + printf("failed to create multiple tables, reason:%s\n", taos_errstr(pRes)); + taos_free_result(pRes); + ASSERT_TRUE(false); + } + + TAOS_ROW pRow = NULL; + TAOS_FIELD* pFields = taos_fetch_fields(pRes); + int32_t numOfFields = taos_num_fields(pRes); + + char str[512] = {0}; + while ((pRow = taos_fetch_row(pRes)) != NULL) { + int32_t code = taos_print_row(str, pRow, pFields, numOfFields); + printf("%s\n", str); + } + + taos_free_result(pRes); + + for (int32_t i = 0; i < 20; ++i) { + char sql[512] = {0}; + snprintf(sql, tListLen(sql), + "create table t_x_%d using st1 tags(2) t_x_%d using st1 tags(5) t_x_%d using st1 tags(911)", i, + (i + 1) * 30, (i + 2) * 40); + TAOS_RES* pres = taos_query(pConn, sql); + if (taos_errno(pres) != 0) { + printf("failed to create table %d\n, reason:%s", i, taos_errstr(pres)); + } + taos_free_result(pres); + } + + taos_close(pConn); +} + +TEST(testCase, show_table_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); + + TAOS_RES* pRes = taos_query(pConn, "use abc1"); + taos_free_result(pRes); + + pRes = taos_query(pConn, "show tables"); + if (taos_errno(pRes) != 0) { + printf("failed to show vgroups, reason:%s\n", taos_errstr(pRes)); + taos_free_result(pRes); + ASSERT_TRUE(false); + } + + TAOS_ROW pRow = NULL; + TAOS_FIELD* pFields = taos_fetch_fields(pRes); + int32_t numOfFields = taos_num_fields(pRes); + + char str[512] = {0}; + while ((pRow = taos_fetch_row(pRes)) != NULL) { + int32_t code = taos_print_row(str, pRow, pFields, numOfFields); + printf("%s\n", str); + } + + taos_free_result(pRes); + taos_close(pConn); +} + +TEST(testCase, drop_stable_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != NULL); + + TAOS_RES* pRes = taos_query(pConn, "create database abc1"); + if (taos_errno(pRes) != 0) { + printf("error in creating db, reason:%s\n", taos_errstr(pRes)); + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "use abc1"); + if (taos_errno(pRes) != 0) { + printf("error in using db, reason:%s\n", taos_errstr(pRes)); + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "drop stable st1"); + if (taos_errno(pRes) != 0) { + printf("failed to drop stable, reason:%s\n", taos_errstr(pRes)); + } + + taos_free_result(pRes); + taos_close(pConn); +} + +TEST(testCase, generated_request_id_test) { + SHashObj* phash = taosHashInit(10000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK); + + for (int32_t i = 0; i < 50000; ++i) { + uint64_t v = generateRequestId(); + void* result = taosHashGet(phash, &v, sizeof(v)); + if (result != nullptr) { + printf("0x%lx, index:%d\n", v, i); + } + assert(result == nullptr); + taosHashPut(phash, &v, sizeof(v), NULL, 0); + } + + taosHashCleanup(phash); +} + +// TEST(testCase, create_topic_Test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); // assert(pConn != NULL); // @@ -434,120 +534,55 @@ TEST(testCase, create_db_Test) { // tmq_create_topic(pConn, "test_topic_1", sql, strlen(sql)); // taos_close(pConn); //} - -//TEST(testCase, show_table_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "use abc1"); -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "show tables"); -// if (taos_errno(pRes) != 0) { -// printf("failed to show vgroups, reason:%s\n", taos_errstr(pRes)); -// taos_free_result(pRes); -// ASSERT_TRUE(false); -// } -// -// TAOS_ROW pRow = NULL; -// TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// int32_t numOfFields = taos_num_fields(pRes); -// -// char str[512] = {0}; -// while((pRow = taos_fetch_row(pRes)) != NULL) { -// int32_t code = taos_print_row(str, pRow, pFields, numOfFields); -// printf("%s\n", str); -// } -// -// taos_free_result(pRes); -// taos_close(pConn); -//} - -TEST(testCase, create_multiple_tables) { - TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); - ASSERT_NE(pConn, nullptr); - - TAOS_RES* pRes = taos_query(pConn, "use abc1"); - taos_free_result(pRes); - - pRes = taos_query(pConn, "create table t_2 using st1 tags(1)"); - if (taos_errno(pRes) != 0) { - printf("failed to create multiple tables, reason:%s\n", taos_errstr(pRes)); - taos_free_result(pRes); - ASSERT_TRUE(false); - } - - taos_free_result(pRes); - pRes = taos_query(pConn, "create table t_3 using st1 tags(2)"); - if (taos_errno(pRes) != 0) { - printf("failed to create multiple tables, reason:%s\n", taos_errstr(pRes)); - taos_free_result(pRes); - ASSERT_TRUE(false); - } - - TAOS_ROW pRow = NULL; - TAOS_FIELD* pFields = taos_fetch_fields(pRes); - int32_t numOfFields = taos_num_fields(pRes); - - char str[512] = {0}; - while((pRow = taos_fetch_row(pRes)) != NULL) { - int32_t code = taos_print_row(str, pRow, pFields, numOfFields); - printf("%s\n", str); - } - - taos_free_result(pRes); - -// for(int32_t i = 0; i < 10000; ++i) { -// char sql[512] = {0}; -// snprintf(sql, tListLen(sql), "create table t_x_%d using st1 tags(2)", i); -// TAOS_RES* pres = taos_query(pConn, sql); -// if (taos_errno(pres) != 0) { -// printf("failed to create table %d\n, reason:%s", i, taos_errstr(pres)); -// } -// taos_free_result(pres); -// } - - taos_close(pConn); -} - -TEST(testCase, generated_request_id_test) { - SHashObj *phash = taosHashInit(10000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK); - - for(int32_t i = 0; i < 1000000; ++i) { - uint64_t v = generateRequestId(); - void* result = taosHashGet(phash, &v, sizeof(v)); - ASSERT_EQ(result, nullptr); - taosHashPut(phash, &v, sizeof(v), NULL, 0); - } - - taosHashClear(phash); -} - -//TEST(testCase, projection_query_tables) { +//TEST(testCase, insert_test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); // ASSERT_EQ(pConn, nullptr); // // TAOS_RES* pRes = taos_query(pConn, "use abc1"); // taos_free_result(pRes); // -// pRes = taos_query(pConn, "select * from t_2"); +// pRes = taos_query(pConn, "insert into t_2 values(now, 1)"); // if (taos_errno(pRes) != 0) { // printf("failed to create multiple tables, reason:%s\n", taos_errstr(pRes)); // taos_free_result(pRes); // ASSERT_TRUE(false); // } // -// TAOS_ROW pRow = NULL; -// TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// int32_t numOfFields = taos_num_fields(pRes); -// -// char str[512] = {0}; -// while((pRow = taos_fetch_row(pRes)) != NULL) { -// int32_t code = taos_print_row(str, pRow, pFields, numOfFields); -// printf("%s\n", str); -// } -// // taos_free_result(pRes); // taos_close(pConn); //} +//#endif +TEST(testCase, projection_query_tables) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(pConn, nullptr); + + TAOS_RES* pRes = taos_query(pConn, "use test1"); + if (taos_errno(pRes) != 0) { + printf("failed to use db, reason:%s", taos_errstr(pRes)); + taos_free_result(pRes); + return; + } + + taos_free_result(pRes); + + pRes = taos_query(pConn, "select * from tm0"); + if (taos_errno(pRes) != 0) { + printf("failed to create multiple tables, reason:%s\n", taos_errstr(pRes)); + taos_free_result(pRes); + ASSERT_TRUE(false); + } + + TAOS_ROW pRow = NULL; + TAOS_FIELD* pFields = taos_fetch_fields(pRes); + int32_t numOfFields = taos_num_fields(pRes); + + char str[512] = {0}; + while ((pRow = taos_fetch_row(pRes)) != NULL) { + int32_t code = taos_print_row(str, pRow, pFields, numOfFields); + printf("%s\n", str); + } + + taos_free_result(pRes); + taos_close(pConn); +} diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 9ddadc9ba6..9a20fadbfb 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -910,7 +910,7 @@ static void doInitGlobalConfig(void) { cfg.option = "tsdbDebugFlag"; cfg.ptr = &tsdbDebugFlag; cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG | TSDB_CFG_CTYPE_B_CLIENT; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG; cfg.minValue = 0; cfg.maxValue = 255; cfg.ptrLength = 0; diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index c1048f8482..53f59c7d57 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -27,6 +27,109 @@ #undef TD_MSG_SEG_CODE_ #include "tmsgdef.h" +int tInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter) { + if (pMsg == NULL) { + terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP; + return -1; + } + + pIter->totalLen = pMsg->length; + pIter->len = 0; + pIter->pMsg = pMsg; + if (pMsg->length <= sizeof(SSubmitMsg)) { + terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP; + return -1; + } + + return 0; +} + +int tGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock) { + if (pIter->len == 0) { + pIter->len += sizeof(SSubmitMsg); + } else { + SSubmitBlk *pSubmitBlk = (SSubmitBlk *)POINTER_SHIFT(pIter->pMsg, pIter->len); + pIter->len += (sizeof(SSubmitBlk) + pSubmitBlk->dataLen + pSubmitBlk->schemaLen); + } + + if (pIter->len > pIter->totalLen) { + terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP; + *pPBlock = NULL; + return -1; + } + + *pPBlock = (pIter->len == pIter->totalLen) ? NULL : (SSubmitBlk *)POINTER_SHIFT(pIter->pMsg, pIter->len); + + return 0; +} + +int tInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter) { + if (pBlock->dataLen <= 0) return -1; + pIter->totalLen = pBlock->dataLen; + pIter->len = 0; + pIter->row = (SMemRow)(pBlock->data + pBlock->schemaLen); + return 0; +} + +SMemRow tGetSubmitBlkNext(SSubmitBlkIter *pIter) { + SMemRow row = pIter->row; + + if (pIter->len >= pIter->totalLen) { + return NULL; + } else { + pIter->len += memRowTLen(row); + if (pIter->len < pIter->totalLen) { + pIter->row = POINTER_SHIFT(row, memRowTLen(row)); + } + return row; + } +} + +int tSerializeSClientHbReq(void **buf, const SClientHbReq *pReq) { + int tlen = 0; + tlen += taosEncodeSClientHbKey(buf, &pReq->connKey); + + int kvNum = taosHashGetSize(pReq->info); + tlen += taosEncodeFixedI32(buf, kvNum); + SKv kv; + void* pIter = taosHashIterate(pReq->info, pIter); + while (pIter != NULL) { + taosHashGetKey(pIter, &kv.key, (size_t *)&kv.keyLen); + kv.valueLen = taosHashGetDataLen(pIter); + kv.value = pIter; + tlen += taosEncodeSKv(buf, &kv); + + pIter = taosHashIterate(pReq->info, pIter); + } + return tlen; +} + +void *tDeserializeClientHbReq(void *buf, SClientHbReq *pReq) { + ASSERT(pReq->info != NULL); + buf = taosDecodeSClientHbKey(buf, &pReq->connKey); + + // TODO: error handling + int kvNum; + taosDecodeFixedI32(buf, &kvNum); + pReq->info = taosHashInit(kvNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); + for(int i = 0; i < kvNum; i++) { + SKv kv; + buf = taosDecodeSKv(buf, &kv); + taosHashPut(pReq->info, kv.key, kv.keyLen, kv.value, kv.valueLen); + } + + return buf; +} + +int tSerializeSClientHbBatchReq(void** buf, const SClientHbBatchReq* pReq) { + int tlen = 0; + return tlen; +} + +void* tDeserializeClientHbBatchReq(void* buf, SClientHbBatchReq* pReq) { + return buf; +} + int tSerializeSVCreateTbReq(void **buf, SVCreateTbReq *pReq) { int tlen = 0; @@ -148,4 +251,4 @@ void *tSVCreateTbBatchReqDeserialize(void *buf, SVCreateTbBatchReq *pReq) { } return buf; -} \ No newline at end of file +} diff --git a/source/dnode/bnode/inc/bndInt.h b/source/dnode/bnode/inc/bndInt.h index d44c520a26..cddb1e50f1 100644 --- a/source/dnode/bnode/inc/bndInt.h +++ b/source/dnode/bnode/inc/bndInt.h @@ -33,9 +33,9 @@ typedef struct SBnode { int32_t dnodeId; int64_t clusterId; SBnodeCfg cfg; - SendMsgToDnodeFp sendMsgToDnodeFp; - SendMsgToMnodeFp sendMsgToMnodeFp; - SendRedirectMsgFp sendRedirectMsgFp; + SendReqToDnodeFp sendReqToDnodeFp; + SendReqToMnodeFp sendReqToMnodeFp; + SendRedirectRspFp sendRedirectRspFp; } SBnode; #ifdef __cplusplus diff --git a/source/dnode/mgmt/impl/CMakeLists.txt b/source/dnode/mgmt/impl/CMakeLists.txt index 866eced51a..171f9649fb 100644 --- a/source/dnode/mgmt/impl/CMakeLists.txt +++ b/source/dnode/mgmt/impl/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries( PUBLIC wal PUBLIC sync PUBLIC taos + PUBLIC tfs ) target_include_directories( dnode diff --git a/source/dnode/mgmt/impl/inc/dndInt.h b/source/dnode/mgmt/impl/inc/dndInt.h index 07c8ce5d02..afdd678213 100644 --- a/source/dnode/mgmt/impl/inc/dndInt.h +++ b/source/dnode/mgmt/impl/inc/dndInt.h @@ -80,20 +80,20 @@ typedef struct { } SDnodeDir; typedef struct { - int32_t dnodeId; - int32_t dropped; - int64_t clusterId; - int64_t rebootTime; - int64_t updateTime; - int8_t statusSent; - SEpSet mnodeEpSet; - char *file; - SHashObj *dnodeHash; - SDnodeEps *dnodeEps; - pthread_t *threadId; - SRWLatch latch; - STaosQueue *pMgmtQ; - SWorkerPool mgmtPool; + int32_t dnodeId; + int32_t dropped; + int64_t clusterId; + int64_t dver; + int64_t rebootTime; + int64_t updateTime; + int8_t statusSent; + SEpSet mnodeEpSet; + char *file; + SHashObj *dnodeHash; + SDnodeEps *dnodeEps; + pthread_t *threadId; + SRWLatch latch; + SDnodeWorker mgmtWorker; } SDnodeMgmt; typedef struct { @@ -167,7 +167,7 @@ typedef struct SDnode { SBnodeMgmt bmgmt; SVnodesMgmt vmgmt; STransMgmt tmgmt; - SStartupMsg startup; + SStartupReq startup; } SDnode; EStat dndGetStat(SDnode *pDnode); @@ -175,7 +175,7 @@ void dndSetStat(SDnode *pDnode, EStat stat); char *dndStatStr(EStat stat); void dndReportStartup(SDnode *pDnode, char *pName, char *pDesc); -void dndGetStartup(SDnode *pDnode, SStartupMsg *pStartup); +void dndGetStartup(SDnode *pDnode, SStartupReq *pStartup); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/impl/inc/dndDnode.h b/source/dnode/mgmt/impl/inc/dndMgmt.h similarity index 84% rename from source/dnode/mgmt/impl/inc/dndDnode.h rename to source/dnode/mgmt/impl/inc/dndMgmt.h index a2015913a7..0df3af23d5 100644 --- a/source/dnode/mgmt/impl/inc/dndDnode.h +++ b/source/dnode/mgmt/impl/inc/dndMgmt.h @@ -21,16 +21,17 @@ extern "C" { #endif #include "dndInt.h" -int32_t dndInitDnode(SDnode *pDnode); -void dndCleanupDnode(SDnode *pDnode); +int32_t dndInitMgmt(SDnode *pDnode); +void dndStopMgmt(SDnode *pDnode); +void dndCleanupMgmt(SDnode *pDnode); int32_t dndGetDnodeId(SDnode *pDnode); int64_t dndGetClusterId(SDnode *pDnode); void dndGetDnodeEp(SDnode *pDnode, int32_t dnodeId, char *pEp, char *pFqdn, uint16_t *pPort); void dndGetMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet); -void dndSendRedirectMsg(SDnode *pDnode, SRpcMsg *pMsg); -void dndSendStatusMsg(SDnode *pDnode); +void dndSendRedirectRsp(SDnode *pDnode, SRpcMsg *pMsg); +void dndSendStatusReq(SDnode *pDnode); void dndProcessMgmtMsg(SDnode *pDnode, SRpcMsg *pRpcMsg, SEpSet *pEpSet); void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pMsg); diff --git a/source/dnode/mgmt/impl/inc/dndTransport.h b/source/dnode/mgmt/impl/inc/dndTransport.h index 312da69fa2..42fb379fc1 100644 --- a/source/dnode/mgmt/impl/inc/dndTransport.h +++ b/source/dnode/mgmt/impl/inc/dndTransport.h @@ -23,8 +23,8 @@ extern "C" { int32_t dndInitTrans(SDnode *pDnode); void dndCleanupTrans(SDnode *pDnode); -void dndSendMsgToMnode(SDnode *pDnode, SRpcMsg *pRpcMsg); -void dndSendMsgToDnode(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pRpcMsg); +int32_t dndSendReqToMnode(SDnode *pDnode, SRpcMsg *pRpcMsg); +int32_t dndSendReqToDnode(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pRpcMsg); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/impl/inc/dndVnodes.h b/source/dnode/mgmt/impl/inc/dndVnodes.h index bf5f0122c1..b5fae62959 100644 --- a/source/dnode/mgmt/impl/inc/dndVnodes.h +++ b/source/dnode/mgmt/impl/inc/dndVnodes.h @@ -29,12 +29,12 @@ void dndProcessVnodeSyncMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet); void dndProcessVnodeQueryMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet); void dndProcessVnodeFetchMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet); -int32_t dndProcessCreateVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg); -int32_t dndProcessAlterVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg); -int32_t dndProcessDropVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg); -int32_t dndProcessAuthVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg); -int32_t dndProcessSyncVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg); -int32_t dndProcessCompactVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg); +int32_t dndProcessCreateVnodeReq(SDnode *pDnode, SRpcMsg *pReq); +int32_t dndProcessAlterVnodeReq(SDnode *pDnode, SRpcMsg *pReq); +int32_t dndProcessDropVnodeReq(SDnode *pDnode, SRpcMsg *pReq); +int32_t dndProcessAuthVnodeReq(SDnode *pDnode, SRpcMsg *pReq); +int32_t dndProcessSyncVnodeReq(SDnode *pDnode, SRpcMsg *pReq); +int32_t dndProcessCompactVnodeReq(SDnode *pDnode, SRpcMsg *pReq); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/impl/src/dndBnode.c b/source/dnode/mgmt/impl/src/dndBnode.c index c12d449517..15be59a419 100644 --- a/source/dnode/mgmt/impl/src/dndBnode.c +++ b/source/dnode/mgmt/impl/src/dndBnode.c @@ -15,7 +15,7 @@ #define _DEFAULT_SOURCE #include "dndBnode.h" -#include "dndDnode.h" +#include "dndMgmt.h" #include "dndTransport.h" #include "dndWorker.h" @@ -27,7 +27,7 @@ static SBnode *dndAcquireBnode(SDnode *pDnode) { int32_t refCount = 0; taosRLockLatch(&pMgmt->latch); - if (pMgmt->deployed && !pMgmt->dropped) { + if (pMgmt->deployed && !pMgmt->dropped && pMgmt->pBnode != NULL) { refCount = atomic_add_fetch_32(&pMgmt->refCount, 1); pBnode = pMgmt->pBnode; } else { @@ -42,25 +42,20 @@ static SBnode *dndAcquireBnode(SDnode *pDnode) { } static void dndReleaseBnode(SDnode *pDnode, SBnode *pBnode) { + if (pBnode == NULL) return; + SBnodeMgmt *pMgmt = &pDnode->bmgmt; - int32_t refCount = 0; - taosRLockLatch(&pMgmt->latch); - if (pBnode != NULL) { - refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1); - } + int32_t refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1); taosRUnLockLatch(&pMgmt->latch); - - if (pBnode != NULL) { - dTrace("release bnode, refCount:%d", refCount); - } + dTrace("release bnode, refCount:%d", refCount); } static int32_t dndReadBnodeFile(SDnode *pDnode) { SBnodeMgmt *pMgmt = &pDnode->bmgmt; int32_t code = TSDB_CODE_DND_BNODE_READ_FILE_ERROR; int32_t len = 0; - int32_t maxLen = 4096; + int32_t maxLen = 1024; char *content = calloc(1, maxLen + 1); cJSON *root = NULL; @@ -127,7 +122,7 @@ static int32_t dndWriteBnodeFile(SDnode *pDnode) { } int32_t len = 0; - int32_t maxLen = 4096; + int32_t maxLen = 1024; char *content = calloc(1, maxLen + 1); len += snprintf(content + len, maxLen - len, "{\n"); @@ -170,7 +165,7 @@ static void dndStopBnodeWorker(SDnode *pDnode) { pMgmt->deployed = 0; taosWUnLockLatch(&pMgmt->latch); - while (pMgmt->refCount > 1) { + while (pMgmt->refCount > 0) { taosMsleep(10); } @@ -179,9 +174,9 @@ static void dndStopBnodeWorker(SDnode *pDnode) { static void dndBuildBnodeOption(SDnode *pDnode, SBnodeOpt *pOption) { pOption->pDnode = pDnode; - pOption->sendMsgToDnodeFp = dndSendMsgToDnode; - pOption->sendMsgToMnodeFp = dndSendMsgToMnode; - pOption->sendRedirectMsgFp = dndSendRedirectMsg; + pOption->sendReqToDnodeFp = dndSendReqToDnode; + pOption->sendReqToMnodeFp = dndSendReqToMnode; + pOption->sendRedirectRspFp = dndSendRedirectRsp; pOption->dnodeId = dndGetDnodeId(pDnode); pOption->clusterId = dndGetClusterId(pDnode); pOption->cfg.sver = pDnode->opt.sver; @@ -189,10 +184,18 @@ static void dndBuildBnodeOption(SDnode *pDnode, SBnodeOpt *pOption) { static int32_t dndOpenBnode(SDnode *pDnode) { SBnodeMgmt *pMgmt = &pDnode->bmgmt; - SBnodeOpt option = {0}; + SBnode *pBnode = dndAcquireBnode(pDnode); + if (pBnode != NULL) { + dndReleaseBnode(pDnode, pBnode); + terrno = TSDB_CODE_DND_BNODE_ALREADY_DEPLOYED; + dError("failed to create bnode since %s", terrstr()); + return -1; + } + + SBnodeOpt option = {0}; dndBuildBnodeOption(pDnode, &option); - SBnode *pBnode = bndOpen(pDnode->dir.bnode, &option); + pBnode = bndOpen(pDnode->dir.bnode, &option); if (pBnode == NULL) { dError("failed to open bnode since %s", terrstr()); return -1; @@ -256,11 +259,12 @@ static int32_t dndDropBnode(SDnode *pDnode) { } int32_t dndProcessCreateBnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDCreateBnodeMsg *pMsg = pRpcMsg->pCont; + SDCreateBnodeReq *pMsg = pRpcMsg->pCont; pMsg->dnodeId = htonl(pMsg->dnodeId); if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_BNODE_ID_INVALID; + terrno = TSDB_CODE_DND_BNODE_INVALID_OPTION; + dError("failed to create bnode since %s", terrstr()); return -1; } else { return dndOpenBnode(pDnode); @@ -268,11 +272,12 @@ int32_t dndProcessCreateBnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { } int32_t dndProcessDropBnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDDropBnodeMsg *pMsg = pRpcMsg->pCont; + SDDropBnodeReq *pMsg = pRpcMsg->pCont; pMsg->dnodeId = htonl(pMsg->dnodeId); if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_BNODE_ID_INVALID; + terrno = TSDB_CODE_DND_BNODE_INVALID_OPTION; + dError("failed to drop bnode since %s", terrstr()); return -1; } else { return dndDropBnode(pDnode); diff --git a/source/dnode/mgmt/impl/src/dndDnode.c b/source/dnode/mgmt/impl/src/dndMgmt.c similarity index 82% rename from source/dnode/mgmt/impl/src/dndDnode.c rename to source/dnode/mgmt/impl/src/dndMgmt.c index 30b069f349..f252bffbbf 100644 --- a/source/dnode/mgmt/impl/src/dndDnode.c +++ b/source/dnode/mgmt/impl/src/dndMgmt.c @@ -14,28 +14,25 @@ */ #define _DEFAULT_SOURCE -#include "dndDnode.h" +#include "dndMgmt.h" #include "dndBnode.h" #include "dndMnode.h" #include "dndQnode.h" #include "dndSnode.h" #include "dndTransport.h" #include "dndVnodes.h" +#include "dndWorker.h" -static int32_t dndInitMgmtWorker(SDnode *pDnode); -static void dndCleanupMgmtWorker(SDnode *pDnode); -static int32_t dndAllocMgmtQueue(SDnode *pDnode); -static void dndFreeMgmtQueue(SDnode *pDnode); -static void dndProcessMgmtQueue(SDnode *pDnode, SRpcMsg *pMsg); +static void dndProcessMgmtQueue(SDnode *pDnode, SRpcMsg *pMsg); static int32_t dndReadDnodes(SDnode *pDnode); static int32_t dndWriteDnodes(SDnode *pDnode); static void *dnodeThreadRoutine(void *param); -static int32_t dndProcessConfigDnodeReq(SDnode *pDnode, SRpcMsg *pMsg); -static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pMsg); -static void dndProcessAuthRsp(SDnode *pDnode, SRpcMsg *pMsg); -static void dndProcessGrantRsp(SDnode *pDnode, SRpcMsg *pMsg); +static int32_t dndProcessConfigDnodeReq(SDnode *pDnode, SRpcMsg *pReq); +static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pRsp); +static void dndProcessAuthRsp(SDnode *pDnode, SRpcMsg *pRsp); +static void dndProcessGrantRsp(SDnode *pDnode, SRpcMsg *pRsp); int32_t dndGetDnodeId(SDnode *pDnode) { SDnodeMgmt *pMgmt = &pDnode->dmgmt; @@ -80,13 +77,13 @@ void dndGetMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet) { taosRUnLockLatch(&pMgmt->latch); } -void dndSendRedirectMsg(SDnode *pDnode, SRpcMsg *pMsg) { - tmsg_t msgType = pMsg->msgType; +void dndSendRedirectRsp(SDnode *pDnode, SRpcMsg *pReq) { + tmsg_t msgType = pReq->msgType; SEpSet epSet = {0}; dndGetMnodeEpSet(pDnode, &epSet); - dDebug("RPC %p, msg:%s is redirected, num:%d use:%d", pMsg->handle, TMSG_INFO(msgType), epSet.numOfEps, epSet.inUse); + dDebug("RPC %p, req:%s is redirected, num:%d use:%d", pReq->handle, TMSG_INFO(msgType), epSet.numOfEps, epSet.inUse); for (int32_t i = 0; i < epSet.numOfEps; ++i) { dDebug("mnode index:%d %s:%u", i, epSet.fqdn[i], epSet.port[i]); if (strcmp(epSet.fqdn[i], pDnode->opt.localFqdn) == 0 && epSet.port[i] == pDnode->opt.serverPort) { @@ -96,7 +93,7 @@ void dndSendRedirectMsg(SDnode *pDnode, SRpcMsg *pMsg) { epSet.port[i] = htons(epSet.port[i]); } - rpcSendRedirectRsp(pMsg->handle, &epSet); + rpcSendRedirectRsp(pReq->handle, &epSet); } static void dndUpdateMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet) { @@ -350,14 +347,14 @@ static int32_t dndWriteDnodes(SDnode *pDnode) { terrno = 0; pMgmt->updateTime = taosGetTimestampMs(); - dInfo("successed to write %s", pMgmt->file); + dDebug("successed to write %s", pMgmt->file); return 0; } -void dndSendStatusMsg(SDnode *pDnode) { - int32_t contLen = sizeof(SStatusMsg) + TSDB_MAX_VNODES * sizeof(SVnodeLoad); +void dndSendStatusReq(SDnode *pDnode) { + int32_t contLen = sizeof(SStatusReq) + TSDB_MAX_VNODES * sizeof(SVnodeLoad); - SStatusMsg *pStatus = rpcMallocCont(contLen); + SStatusReq *pStatus = rpcMallocCont(contLen); if (pStatus == NULL) { dError("failed to malloc status message"); return; @@ -366,6 +363,7 @@ void dndSendStatusMsg(SDnode *pDnode) { SDnodeMgmt *pMgmt = &pDnode->dmgmt; taosRLockLatch(&pMgmt->latch); pStatus->sver = htonl(pDnode->opt.sver); + pStatus->dver = htobe64(pMgmt->dver); pStatus->dnodeId = htonl(pMgmt->dnodeId); pStatus->clusterId = htobe64(pMgmt->clusterId); pStatus->rebootTime = htobe64(pMgmt->rebootTime); @@ -385,13 +383,13 @@ void dndSendStatusMsg(SDnode *pDnode) { taosRUnLockLatch(&pMgmt->latch); dndGetVnodeLoads(pDnode, &pStatus->vnodeLoads); - contLen = sizeof(SStatusMsg) + pStatus->vnodeLoads.num * sizeof(SVnodeLoad); + contLen = sizeof(SStatusReq) + pStatus->vnodeLoads.num * sizeof(SVnodeLoad); SRpcMsg rpcMsg = {.pCont = pStatus, .contLen = contLen, .msgType = TDMT_MND_STATUS, .ahandle = (void *)9527}; pMgmt->statusSent = 1; - dTrace("pDnode:%p, send status msg to mnode", pDnode); - dndSendMsgToMnode(pDnode, &rpcMsg); + dTrace("pDnode:%p, send status req to mnode", pDnode); + dndSendReqToMnode(pDnode, &rpcMsg); } static void dndUpdateDnodeCfg(SDnode *pDnode, SDnodeCfg *pCfg) { @@ -426,12 +424,12 @@ static void dndUpdateDnodeEps(SDnode *pDnode, SDnodeEps *pDnodeEps) { taosWUnLockLatch(&pMgmt->latch); } -static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pMsg) { +static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pRsp) { SDnodeMgmt *pMgmt = &pDnode->dmgmt; - if (pMsg->code != TSDB_CODE_SUCCESS) { + if (pRsp->code != TSDB_CODE_SUCCESS) { pMgmt->statusSent = 0; - if (pMsg->code == TSDB_CODE_MND_DNODE_NOT_EXIST && !pMgmt->dropped && pMgmt->dnodeId > 0) { + if (pRsp->code == TSDB_CODE_MND_DNODE_NOT_EXIST && !pMgmt->dropped && pMgmt->dnodeId > 0) { dInfo("dnode:%d, set to dropped since not exist in mnode", pMgmt->dnodeId); pMgmt->dropped = 1; dndWriteDnodes(pDnode); @@ -439,14 +437,16 @@ static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pMsg) { return; } - SStatusRsp *pRsp = pMsg->pCont; - if (pMsg->pCont != NULL && pMsg->contLen != 0) { - SDnodeCfg *pCfg = &pRsp->dnodeCfg; + if (pRsp->pCont != NULL && pRsp->contLen != 0) { + SStatusRsp *pStatus = pRsp->pCont; + pMgmt->dver = htobe64(pStatus->dver); + + SDnodeCfg *pCfg = &pStatus->dnodeCfg; pCfg->dnodeId = htonl(pCfg->dnodeId); pCfg->clusterId = htobe64(pCfg->clusterId); dndUpdateDnodeCfg(pDnode, pCfg); - SDnodeEps *pDnodeEps = &pRsp->dnodeEps; + SDnodeEps *pDnodeEps = &pStatus->dnodeEps; pDnodeEps->num = htonl(pDnodeEps->num); for (int32_t i = 0; i < pDnodeEps->num; ++i) { pDnodeEps->eps[i].id = htonl(pDnodeEps->eps[i].id); @@ -458,26 +458,27 @@ static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pMsg) { pMgmt->statusSent = 0; } -static void dndProcessAuthRsp(SDnode *pDnode, SRpcMsg *pMsg) { assert(1); } +static void dndProcessAuthRsp(SDnode *pDnode, SRpcMsg *pReq) { dError("auth rsp is received, but not supported yet"); } -static void dndProcessGrantRsp(SDnode *pDnode, SRpcMsg *pMsg) { assert(1); } - -static int32_t dndProcessConfigDnodeReq(SDnode *pDnode, SRpcMsg *pMsg) { - dError("config msg is received, but not supported yet"); - SCfgDnodeMsg *pCfg = pMsg->pCont; +static void dndProcessGrantRsp(SDnode *pDnode, SRpcMsg *pReq) { + dError("grant rsp is received, but not supported yet"); +} +static int32_t dndProcessConfigDnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + dError("config req is received, but not supported yet"); + SDCfgDnodeReq *pCfg = pReq->pCont; return TSDB_CODE_OPS_NOT_SUPPORT; } -void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pMsg) { - dDebug("startup msg is received"); +void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pReq) { + dDebug("startup req is received"); - SStartupMsg *pStartup = rpcMallocCont(sizeof(SStartupMsg)); + SStartupReq *pStartup = rpcMallocCont(sizeof(SStartupReq)); dndGetStartup(pDnode, pStartup); - dDebug("startup msg is sent, step:%s desc:%s finished:%d", pStartup->name, pStartup->desc, pStartup->finished); + dDebug("startup req is sent, step:%s desc:%s finished:%d", pStartup->name, pStartup->desc, pStartup->finished); - SRpcMsg rpcRsp = {.handle = pMsg->handle, .pCont = pStartup, .contLen = sizeof(SStartupMsg)}; + SRpcMsg rpcRsp = {.handle = pReq->handle, .pCont = pStartup, .contLen = sizeof(SStartupReq)}; rpcSendResponse(&rpcRsp); } @@ -491,12 +492,12 @@ static void *dnodeThreadRoutine(void *param) { taosMsleep(ms); if (dndGetStat(pDnode) == DND_STAT_RUNNING && !pMgmt->statusSent && !pMgmt->dropped) { - dndSendStatusMsg(pDnode); + dndSendStatusReq(pDnode); } } } -int32_t dndInitDnode(SDnode *pDnode) { +int32_t dndInitMgmt(SDnode *pDnode) { SDnodeMgmt *pMgmt = &pDnode->dmgmt; pMgmt->dnodeId = 0; @@ -530,13 +531,8 @@ int32_t dndInitDnode(SDnode *pDnode) { return -1; } - if (dndInitMgmtWorker(pDnode) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - if (dndAllocMgmtQueue(pDnode) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; + if (dndInitWorker(pDnode, &pMgmt->mgmtWorker, DND_WORKER_SINGLE, "dnode-mgmt", 1, 1, dndProcessMgmtQueue) != 0) { + dError("failed to start dnode mgmt worker since %s", terrstr()); return -1; } @@ -547,21 +543,22 @@ int32_t dndInitDnode(SDnode *pDnode) { return -1; } - dInfo("dnode-dnode is initialized"); + dInfo("dnode-mgmt is initialized"); return 0; } -void dndCleanupDnode(SDnode *pDnode) { +void dndStopMgmt(SDnode *pDnode) { SDnodeMgmt *pMgmt = &pDnode->dmgmt; - - dndCleanupMgmtWorker(pDnode); - dndFreeMgmtQueue(pDnode); + dndCleanupWorker(&pMgmt->mgmtWorker); if (pMgmt->threadId != NULL) { taosDestoryThread(pMgmt->threadId); pMgmt->threadId = NULL; } +} +void dndCleanupMgmt(SDnode *pDnode) { + SDnodeMgmt *pMgmt = &pDnode->dmgmt; taosWLockLatch(&pMgmt->latch); if (pMgmt->dnodeEps != NULL) { @@ -580,62 +577,22 @@ void dndCleanupDnode(SDnode *pDnode) { } taosWUnLockLatch(&pMgmt->latch); - dInfo("dnode-dnode is cleaned up"); + dInfo("dnode-mgmt is cleaned up"); } -static int32_t dndInitMgmtWorker(SDnode *pDnode) { - SDnodeMgmt *pMgmt = &pDnode->dmgmt; - SWorkerPool *pPool = &pMgmt->mgmtPool; - pPool->name = "dnode-mgmt"; - pPool->min = 1; - pPool->max = 1; - if (tWorkerInit(pPool) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - dDebug("dnode mgmt worker is initialized"); - return 0; -} - -static void dndCleanupMgmtWorker(SDnode *pDnode) { - SDnodeMgmt *pMgmt = &pDnode->dmgmt; - tWorkerCleanup(&pMgmt->mgmtPool); - dDebug("dnode mgmt worker is closed"); -} - -static int32_t dndAllocMgmtQueue(SDnode *pDnode) { - SDnodeMgmt *pMgmt = &pDnode->dmgmt; - pMgmt->pMgmtQ = tWorkerAllocQueue(&pMgmt->mgmtPool, pDnode, (FProcessItem)dndProcessMgmtQueue); - if (pMgmt->pMgmtQ == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - return 0; -} - -static void dndFreeMgmtQueue(SDnode *pDnode) { - SDnodeMgmt *pMgmt = &pDnode->dmgmt; - tWorkerFreeQueue(&pMgmt->mgmtPool, pMgmt->pMgmtQ); - pMgmt->pMgmtQ = NULL; -} - -void dndProcessMgmtMsg(SDnode *pDnode, SRpcMsg *pRpcMsg, SEpSet *pEpSet) { +void dndProcessMgmtMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { SDnodeMgmt *pMgmt = &pDnode->dmgmt; - if (pEpSet && pEpSet->numOfEps > 0 && pRpcMsg->msgType == TDMT_MND_STATUS_RSP) { + if (pEpSet && pEpSet->numOfEps > 0 && pMsg->msgType == TDMT_MND_STATUS_RSP) { dndUpdateMnodeEpSet(pDnode, pEpSet); } - SRpcMsg *pMsg = taosAllocateQitem(sizeof(SRpcMsg)); - if (pMsg != NULL) *pMsg = *pRpcMsg; - - if (pMsg == NULL || taosWriteQitem(pMgmt->pMgmtQ, pMsg) != 0) { - if (pRpcMsg->msgType & 1u) { - SRpcMsg rsp = {.handle = pRpcMsg->handle, .code = TSDB_CODE_OUT_OF_MEMORY}; + if (dndWriteMsgToWorker(&pMgmt->mgmtWorker, pMsg, sizeof(SRpcMsg)) != 0) { + if (pMsg->msgType & 1u) { + SRpcMsg rsp = {.handle = pMsg->handle, .code = TSDB_CODE_OUT_OF_MEMORY}; rpcSendResponse(&rsp); } - rpcFreeCont(pRpcMsg->pCont); + rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } } @@ -704,7 +661,7 @@ static void dndProcessMgmtQueue(SDnode *pDnode, SRpcMsg *pMsg) { default: terrno = TSDB_CODE_MSG_NOT_PROCESSED; code = -1; - dError("RPC %p, dnode req:%s not processed", pMsg->handle, TMSG_INFO(pMsg->msgType)); + dError("RPC %p, dnode msg:%s not processed", pMsg->handle, TMSG_INFO(pMsg->msgType)); break; } diff --git a/source/dnode/mgmt/impl/src/dndMnode.c b/source/dnode/mgmt/impl/src/dndMnode.c index 577cb0c3b0..6c23af7f00 100644 --- a/source/dnode/mgmt/impl/src/dndMnode.c +++ b/source/dnode/mgmt/impl/src/dndMnode.c @@ -15,10 +15,11 @@ #define _DEFAULT_SOURCE #include "dndMnode.h" -#include "dndDnode.h" +#include "dndMgmt.h" #include "dndTransport.h" #include "dndWorker.h" +static void dndWriteMnodeMsgToWorker(SDnode *pDnode, SDnodeWorker *pWorker, SRpcMsg *pRpcMsg); static void dndProcessMnodeQueue(SDnode *pDnode, SMnodeMsg *pMsg); static SMnode *dndAcquireMnode(SDnode *pDnode) { @@ -42,18 +43,13 @@ static SMnode *dndAcquireMnode(SDnode *pDnode) { } static void dndReleaseMnode(SDnode *pDnode, SMnode *pMnode) { + if (pMnode == NULL) return; + SMnodeMgmt *pMgmt = &pDnode->mmgmt; - int32_t refCount = 0; - taosRLockLatch(&pMgmt->latch); - if (pMnode != NULL) { - refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1); - } + int32_t refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1); taosRUnLockLatch(&pMgmt->latch); - - if (pMnode != NULL) { - dTrace("release mnode, refCount:%d", refCount); - } + dTrace("release mnode, refCount:%d", refCount); } static int32_t dndReadMnodeFile(SDnode *pDnode) { @@ -258,11 +254,16 @@ static bool dndNeedDeployMnode(SDnode *pDnode) { return true; } +static int32_t dndPutMsgToMWriteQ(SDnode *pDnode, SRpcMsg *pRpcMsg) { + dndWriteMnodeMsgToWorker(pDnode, &pDnode->mmgmt.writeWorker, pRpcMsg); +} + static void dndInitMnodeOption(SDnode *pDnode, SMnodeOpt *pOption) { pOption->pDnode = pDnode; - pOption->sendMsgToDnodeFp = dndSendMsgToDnode; - pOption->sendMsgToMnodeFp = dndSendMsgToMnode; - pOption->sendRedirectMsgFp = dndSendRedirectMsg; + pOption->sendReqToDnodeFp = dndSendReqToDnode; + pOption->sendReqToMnodeFp = dndSendReqToMnode; + pOption->sendRedirectRspFp = dndSendRedirectRsp; + pOption->putReqToMWriteQFp = dndPutMsgToMWriteQ; pOption->dnodeId = dndGetDnodeId(pDnode); pOption->clusterId = dndGetClusterId(pDnode); pOption->cfg.sver = pDnode->opt.sver; @@ -299,25 +300,24 @@ static void dndBuildMnodeOpenOption(SDnode *pDnode, SMnodeOpt *pOption) { memcpy(&pOption->replicas, pMgmt->replicas, sizeof(SReplica) * TSDB_MAX_REPLICA); } -static int32_t dndBuildMnodeOptionFromMsg(SDnode *pDnode, SMnodeOpt *pOption, SDCreateMnodeMsg *pMsg) { +static int32_t dndBuildMnodeOptionFromReq(SDnode *pDnode, SMnodeOpt *pOption, SDCreateMnodeReq *pCreate) { dndInitMnodeOption(pDnode, pOption); pOption->dnodeId = dndGetDnodeId(pDnode); pOption->clusterId = dndGetClusterId(pDnode); - pOption->replica = pMsg->replica; + pOption->replica = pCreate->replica; pOption->selfIndex = -1; - for (int32_t i = 0; i < pMsg->replica; ++i) { + for (int32_t i = 0; i < pCreate->replica; ++i) { SReplica *pReplica = &pOption->replicas[i]; - pReplica->id = pMsg->replicas[i].id; - pReplica->port = pMsg->replicas[i].port; - memcpy(pReplica->fqdn, pMsg->replicas[i].fqdn, TSDB_FQDN_LEN); + pReplica->id = pCreate->replicas[i].id; + pReplica->port = pCreate->replicas[i].port; + memcpy(pReplica->fqdn, pCreate->replicas[i].fqdn, TSDB_FQDN_LEN); if (pReplica->id == pOption->dnodeId) { pOption->selfIndex = i; } } if (pOption->selfIndex == -1) { - terrno = TSDB_CODE_DND_MNODE_ID_NOT_FOUND; dError("failed to build mnode options since %s", terrstr()); return -1; } @@ -417,63 +417,97 @@ static int32_t dndDropMnode(SDnode *pDnode) { return 0; } -static SDCreateMnodeMsg *dndParseCreateMnodeMsg(SRpcMsg *pRpcMsg) { - SDCreateMnodeMsg *pMsg = pRpcMsg->pCont; - pMsg->dnodeId = htonl(pMsg->dnodeId); - for (int32_t i = 0; i < pMsg->replica; ++i) { - pMsg->replicas[i].id = htonl(pMsg->replicas[i].id); - pMsg->replicas[i].port = htons(pMsg->replicas[i].port); +static SDCreateMnodeReq *dndParseCreateMnodeReq(SRpcMsg *pReq) { + SDCreateMnodeReq *pCreate = pReq->pCont; + pCreate->dnodeId = htonl(pCreate->dnodeId); + for (int32_t i = 0; i < pCreate->replica; ++i) { + pCreate->replicas[i].id = htonl(pCreate->replicas[i].id); + pCreate->replicas[i].port = htons(pCreate->replicas[i].port); } - return pMsg; + return pCreate; } -int32_t dndProcessCreateMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDCreateMnodeMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg); +int32_t dndProcessCreateMnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SDCreateMnodeReq *pCreate = dndParseCreateMnodeReq(pReq); - if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_MNODE_ID_INVALID; - return -1; - } else { - SMnodeOpt option = {0}; - if (dndBuildMnodeOptionFromMsg(pDnode, &option, pMsg) != 0) { - return -1; - } - - return dndOpenMnode(pDnode, &option); - } -} - -int32_t dndProcessAlterMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDAlterMnodeMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg); - - if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_MNODE_ID_INVALID; + if (pCreate->replica <= 1 || pCreate->dnodeId != dndGetDnodeId(pDnode)) { + terrno = TSDB_CODE_DND_MNODE_INVALID_OPTION; + dError("failed to create mnode since %s", terrstr()); return -1; } SMnodeOpt option = {0}; - if (dndBuildMnodeOptionFromMsg(pDnode, &option, pMsg) != 0) { + if (dndBuildMnodeOptionFromReq(pDnode, &option, pCreate) != 0) { + terrno = TSDB_CODE_DND_MNODE_INVALID_OPTION; + dError("failed to create mnode since %s", terrstr()); return -1; } - if (dndAlterMnode(pDnode, &option) != 0) { + SMnode *pMnode = dndAcquireMnode(pDnode); + if (pMnode != NULL) { + dndReleaseMnode(pDnode, pMnode); + terrno = TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED; + dError("failed to create mnode since %s", terrstr()); return -1; } - return dndWriteMnodeFile(pDnode); + dDebug("start to create mnode"); + return dndOpenMnode(pDnode, &option); } -int32_t dndProcessDropMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDDropMnodeMsg *pMsg = pRpcMsg->pCont; - pMsg->dnodeId = htonl(pMsg->dnodeId); +int32_t dndProcessAlterMnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SDAlterMnodeReq *pAlter = dndParseCreateMnodeReq(pReq); - if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_MNODE_ID_INVALID; + if (pAlter->dnodeId != dndGetDnodeId(pDnode)) { + terrno = TSDB_CODE_DND_MNODE_INVALID_OPTION; + dError("failed to alter mnode since %s", terrstr()); return -1; - } else { - return dndDropMnode(pDnode); } + + SMnodeOpt option = {0}; + if (dndBuildMnodeOptionFromReq(pDnode, &option, pAlter) != 0) { + terrno = TSDB_CODE_DND_MNODE_INVALID_OPTION; + dError("failed to alter mnode since %s", terrstr()); + return -1; + } + + SMnode *pMnode = dndAcquireMnode(pDnode); + if (pMnode == NULL) { + terrno = TSDB_CODE_DND_MNODE_NOT_DEPLOYED; + dError("failed to alter mnode since %s", terrstr()); + return -1; + } + + dDebug("start to alter mnode"); + int32_t code = dndAlterMnode(pDnode, &option); + dndReleaseMnode(pDnode, pMnode); + + return code; +} + +int32_t dndProcessDropMnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SDDropMnodeReq *pDrop = pReq->pCont; + pDrop->dnodeId = htonl(pDrop->dnodeId); + + if (pDrop->dnodeId != dndGetDnodeId(pDnode)) { + terrno = TSDB_CODE_DND_MNODE_INVALID_OPTION; + dError("failed to drop mnode since %s", terrstr()); + return -1; + } + + SMnode *pMnode = dndAcquireMnode(pDnode); + if (pMnode == NULL) { + terrno = TSDB_CODE_DND_MNODE_NOT_DEPLOYED; + dError("failed to drop mnode since %s", terrstr()); + return -1; + } + + dDebug("start to drop mnode"); + int32_t code = dndDropMnode(pDnode); + dndReleaseMnode(pDnode, pMnode); + + return code; } static void dndProcessMnodeQueue(SDnode *pDnode, SMnodeMsg *pMsg) { @@ -500,6 +534,7 @@ static void dndWriteMnodeMsgToWorker(SDnode *pDnode, SDnodeWorker *pWorker, SRpc code = TSDB_CODE_OUT_OF_MEMORY; } else { code = dndWriteMsgToWorker(pWorker, pMsg, 0); + if (code != 0) code = terrno; } if (code != 0) { diff --git a/source/dnode/mgmt/impl/src/dndQnode.c b/source/dnode/mgmt/impl/src/dndQnode.c index 1f3d6ee371..9d2f623c45 100644 --- a/source/dnode/mgmt/impl/src/dndQnode.c +++ b/source/dnode/mgmt/impl/src/dndQnode.c @@ -15,7 +15,7 @@ #define _DEFAULT_SOURCE #include "dndQnode.h" -#include "dndDnode.h" +#include "dndMgmt.h" #include "dndTransport.h" #include "dndWorker.h" @@ -27,7 +27,7 @@ static SQnode *dndAcquireQnode(SDnode *pDnode) { int32_t refCount = 0; taosRLockLatch(&pMgmt->latch); - if (pMgmt->deployed && !pMgmt->dropped) { + if (pMgmt->deployed && !pMgmt->dropped && pMgmt->pQnode != NULL) { refCount = atomic_add_fetch_32(&pMgmt->refCount, 1); pQnode = pMgmt->pQnode; } else { @@ -42,25 +42,20 @@ static SQnode *dndAcquireQnode(SDnode *pDnode) { } static void dndReleaseQnode(SDnode *pDnode, SQnode *pQnode) { + if (pQnode == NULL) return; + SQnodeMgmt *pMgmt = &pDnode->qmgmt; - int32_t refCount = 0; - taosRLockLatch(&pMgmt->latch); - if (pQnode != NULL) { - refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1); - } + int32_t refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1); taosRUnLockLatch(&pMgmt->latch); - - if (pQnode != NULL) { - dTrace("release qnode, refCount:%d", refCount); - } + dTrace("release qnode, refCount:%d", refCount); } static int32_t dndReadQnodeFile(SDnode *pDnode) { SQnodeMgmt *pMgmt = &pDnode->qmgmt; int32_t code = TSDB_CODE_DND_QNODE_READ_FILE_ERROR; int32_t len = 0; - int32_t maxLen = 4096; + int32_t maxLen = 1024; char *content = calloc(1, maxLen + 1); cJSON *root = NULL; @@ -127,7 +122,7 @@ static int32_t dndWriteQnodeFile(SDnode *pDnode) { } int32_t len = 0; - int32_t maxLen = 4096; + int32_t maxLen = 1024; char *content = calloc(1, maxLen + 1); len += snprintf(content + len, maxLen - len, "{\n"); @@ -175,7 +170,7 @@ static void dndStopQnodeWorker(SDnode *pDnode) { pMgmt->deployed = 0; taosWUnLockLatch(&pMgmt->latch); - while (pMgmt->refCount > 1) { + while (pMgmt->refCount > 0) { taosMsleep(10); } @@ -185,9 +180,9 @@ static void dndStopQnodeWorker(SDnode *pDnode) { static void dndBuildQnodeOption(SDnode *pDnode, SQnodeOpt *pOption) { pOption->pDnode = pDnode; - pOption->sendMsgToDnodeFp = dndSendMsgToDnode; - pOption->sendMsgToMnodeFp = dndSendMsgToMnode; - pOption->sendRedirectMsgFp = dndSendRedirectMsg; + pOption->sendReqToDnodeFp = dndSendReqToDnode; + pOption->sendReqToMnodeFp = dndSendReqToMnode; + pOption->sendRedirectRspFp = dndSendRedirectRsp; pOption->dnodeId = dndGetDnodeId(pDnode); pOption->clusterId = dndGetClusterId(pDnode); pOption->cfg.sver = pDnode->opt.sver; @@ -195,10 +190,19 @@ static void dndBuildQnodeOption(SDnode *pDnode, SQnodeOpt *pOption) { static int32_t dndOpenQnode(SDnode *pDnode) { SQnodeMgmt *pMgmt = &pDnode->qmgmt; - SQnodeOpt option = {0}; + + SQnode *pQnode = dndAcquireQnode(pDnode); + if (pQnode != NULL) { + dndReleaseQnode(pDnode, pQnode); + terrno = TSDB_CODE_DND_QNODE_ALREADY_DEPLOYED; + dError("failed to create qnode since %s", terrstr()); + return -1; + } + + SQnodeOpt option = {0}; dndBuildQnodeOption(pDnode, &option); - SQnode *pQnode = qndOpen(&option); + pQnode = qndOpen(&option); if (pQnode == NULL) { dError("failed to open qnode since %s", terrstr()); return -1; @@ -261,11 +265,12 @@ static int32_t dndDropQnode(SDnode *pDnode) { } int32_t dndProcessCreateQnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDCreateQnodeMsg *pMsg = pRpcMsg->pCont; + SDCreateQnodeReq *pMsg = pRpcMsg->pCont; pMsg->dnodeId = htonl(pMsg->dnodeId); if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_QNODE_ID_INVALID; + terrno = TSDB_CODE_DND_QNODE_INVALID_OPTION; + dError("failed to create qnode since %s", terrstr()); return -1; } else { return dndOpenQnode(pDnode); @@ -273,11 +278,12 @@ int32_t dndProcessCreateQnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { } int32_t dndProcessDropQnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDDropQnodeMsg *pMsg = pRpcMsg->pCont; + SDDropQnodeReq *pMsg = pRpcMsg->pCont; pMsg->dnodeId = htonl(pMsg->dnodeId); if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_QNODE_ID_INVALID; + terrno = TSDB_CODE_DND_QNODE_INVALID_OPTION; + dError("failed to drop qnode since %s", terrstr()); return -1; } else { return dndDropQnode(pDnode); @@ -293,15 +299,18 @@ static void dndProcessQnodeQueue(SDnode *pDnode, SRpcMsg *pMsg) { if (pQnode != NULL) { code = qndProcessMsg(pQnode, pMsg, &pRsp); } + dndReleaseQnode(pDnode, pQnode); - if (pRsp != NULL) { - pRsp->ahandle = pMsg->ahandle; - rpcSendResponse(pRsp); - free(pRsp); - } else { - if (code != 0) code = terrno; - SRpcMsg rpcRsp = {.handle = pMsg->handle, .ahandle = pMsg->ahandle, .code = code}; - rpcSendResponse(&rpcRsp); + if (pMsg->msgType & 1u) { + if (pRsp != NULL) { + pRsp->ahandle = pMsg->ahandle; + rpcSendResponse(pRsp); + free(pRsp); + } else { + if (code != 0) code = terrno; + SRpcMsg rpcRsp = {.handle = pMsg->handle, .ahandle = pMsg->ahandle, .code = code}; + rpcSendResponse(&rpcRsp); + } } rpcFreeCont(pMsg->pCont); diff --git a/source/dnode/mgmt/impl/src/dndSnode.c b/source/dnode/mgmt/impl/src/dndSnode.c index ab4ca191a9..00435d4c3e 100644 --- a/source/dnode/mgmt/impl/src/dndSnode.c +++ b/source/dnode/mgmt/impl/src/dndSnode.c @@ -15,7 +15,7 @@ #define _DEFAULT_SOURCE #include "dndSnode.h" -#include "dndDnode.h" +#include "dndMgmt.h" #include "dndTransport.h" #include "dndWorker.h" @@ -27,7 +27,7 @@ static SSnode *dndAcquireSnode(SDnode *pDnode) { int32_t refCount = 0; taosRLockLatch(&pMgmt->latch); - if (pMgmt->deployed && !pMgmt->dropped) { + if (pMgmt->deployed && !pMgmt->dropped && pMgmt->pSnode != NULL) { refCount = atomic_add_fetch_32(&pMgmt->refCount, 1); pSnode = pMgmt->pSnode; } else { @@ -42,25 +42,20 @@ static SSnode *dndAcquireSnode(SDnode *pDnode) { } static void dndReleaseSnode(SDnode *pDnode, SSnode *pSnode) { + if (pSnode == NULL) return; + SSnodeMgmt *pMgmt = &pDnode->smgmt; - int32_t refCount = 0; - taosRLockLatch(&pMgmt->latch); - if (pSnode != NULL) { - refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1); - } + int32_t refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1); taosRUnLockLatch(&pMgmt->latch); - - if (pSnode != NULL) { - dTrace("release snode, refCount:%d", refCount); - } + dTrace("release snode, refCount:%d", refCount); } static int32_t dndReadSnodeFile(SDnode *pDnode) { SSnodeMgmt *pMgmt = &pDnode->smgmt; int32_t code = TSDB_CODE_DND_SNODE_READ_FILE_ERROR; int32_t len = 0; - int32_t maxLen = 4096; + int32_t maxLen = 1024; char *content = calloc(1, maxLen + 1); cJSON *root = NULL; @@ -127,7 +122,7 @@ static int32_t dndWriteSnodeFile(SDnode *pDnode) { } int32_t len = 0; - int32_t maxLen = 4096; + int32_t maxLen = 1024; char *content = calloc(1, maxLen + 1); len += snprintf(content + len, maxLen - len, "{\n"); @@ -170,18 +165,18 @@ static void dndStopSnodeWorker(SDnode *pDnode) { pMgmt->deployed = 0; taosWUnLockLatch(&pMgmt->latch); - while (pMgmt->refCount > 1) { + while (pMgmt->refCount > 0) { taosMsleep(10); - } + } dndCleanupWorker(&pMgmt->writeWorker); } static void dndBuildSnodeOption(SDnode *pDnode, SSnodeOpt *pOption) { pOption->pDnode = pDnode; - pOption->sendMsgToDnodeFp = dndSendMsgToDnode; - pOption->sendMsgToMnodeFp = dndSendMsgToMnode; - pOption->sendRedirectMsgFp = dndSendRedirectMsg; + pOption->sendReqToDnodeFp = dndSendReqToDnode; + pOption->sendReqToMnodeFp = dndSendReqToMnode; + pOption->sendRedirectRspFp = dndSendRedirectRsp; pOption->dnodeId = dndGetDnodeId(pDnode); pOption->clusterId = dndGetClusterId(pDnode); pOption->cfg.sver = pDnode->opt.sver; @@ -189,10 +184,18 @@ static void dndBuildSnodeOption(SDnode *pDnode, SSnodeOpt *pOption) { static int32_t dndOpenSnode(SDnode *pDnode) { SSnodeMgmt *pMgmt = &pDnode->smgmt; - SSnodeOpt option = {0}; + SSnode *pSnode = dndAcquireSnode(pDnode); + if (pSnode != NULL) { + dndReleaseSnode(pDnode, pSnode); + terrno = TSDB_CODE_DND_SNODE_ALREADY_DEPLOYED; + dError("failed to create snode since %s", terrstr()); + return -1; + } + + SSnodeOpt option = {0}; dndBuildSnodeOption(pDnode, &option); - SSnode *pSnode = sndOpen(pDnode->dir.snode, &option); + pSnode = sndOpen(pDnode->dir.snode, &option); if (pSnode == NULL) { dError("failed to open snode since %s", terrstr()); return -1; @@ -256,11 +259,12 @@ static int32_t dndDropSnode(SDnode *pDnode) { } int32_t dndProcessCreateSnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDCreateSnodeMsg *pMsg = pRpcMsg->pCont; + SDCreateSnodeReq *pMsg = pRpcMsg->pCont; pMsg->dnodeId = htonl(pMsg->dnodeId); if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_SNODE_ID_INVALID; + terrno = TSDB_CODE_DND_SNODE_INVALID_OPTION; + dError("failed to create snode since %s", terrstr()); return -1; } else { return dndOpenSnode(pDnode); @@ -268,11 +272,12 @@ int32_t dndProcessCreateSnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { } int32_t dndProcessDropSnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SDDropSnodeMsg *pMsg = pRpcMsg->pCont; + SDDropSnodeReq *pMsg = pRpcMsg->pCont; pMsg->dnodeId = htonl(pMsg->dnodeId); if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { - terrno = TSDB_CODE_DND_SNODE_ID_INVALID; + terrno = TSDB_CODE_DND_SNODE_INVALID_OPTION; + dError("failed to drop snode since %s", terrstr()); return -1; } else { return dndDropSnode(pDnode); @@ -288,15 +293,18 @@ static void dndProcessSnodeQueue(SDnode *pDnode, SRpcMsg *pMsg) { if (pSnode != NULL) { code = sndProcessMsg(pSnode, pMsg, &pRsp); } + dndReleaseSnode(pDnode, pSnode); - if (pRsp != NULL) { - pRsp->ahandle = pMsg->ahandle; - rpcSendResponse(pRsp); - free(pRsp); - } else { - if (code != 0) code = terrno; - SRpcMsg rpcRsp = {.handle = pMsg->handle, .ahandle = pMsg->ahandle, .code = code}; - rpcSendResponse(&rpcRsp); + if (pMsg->msgType & 1u) { + if (pRsp != NULL) { + pRsp->ahandle = pMsg->ahandle; + rpcSendResponse(pRsp); + free(pRsp); + } else { + if (code != 0) code = terrno; + SRpcMsg rpcRsp = {.handle = pMsg->handle, .ahandle = pMsg->ahandle, .code = code}; + rpcSendResponse(&rpcRsp); + } } rpcFreeCont(pMsg->pCont); diff --git a/source/dnode/mgmt/impl/src/dndTransport.c b/source/dnode/mgmt/impl/src/dndTransport.c index bb16ef0b77..509e8f4cab 100644 --- a/source/dnode/mgmt/impl/src/dndTransport.c +++ b/source/dnode/mgmt/impl/src/dndTransport.c @@ -21,7 +21,7 @@ #define _DEFAULT_SOURCE #include "dndTransport.h" -#include "dndDnode.h" +#include "dndMgmt.h" #include "dndMnode.h" #include "dndVnodes.h" @@ -105,8 +105,6 @@ static void dndInitMsgFp(STransMgmt *pMgmt) { pMgmt->msgFp[TMSG_INDEX(TDMT_MND_SHOW_RETRIEVE)] = dndProcessMnodeReadMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_STATUS)] = dndProcessMnodeReadMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_STATUS_RSP)] = dndProcessMgmtMsg; - pMgmt->msgFp[TMSG_INDEX(TDMT_MND_TRANS)] = dndProcessMnodeWriteMsg; - pMgmt->msgFp[TMSG_INDEX(TDMT_MND_TRANS_RSP)] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_GRANT)] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_GRANT_RSP)] = dndProcessMgmtMsg; pMgmt->msgFp[TMSG_INDEX(TDMT_MND_AUTH)] = dndProcessMnodeReadMsg; @@ -145,26 +143,26 @@ static void dndInitMsgFp(STransMgmt *pMgmt) { pMgmt->msgFp[TMSG_INDEX(TDMT_VND_SHOW_TABLES_FETCH)] = dndProcessVnodeFetchMsg; } -static void dndProcessResponse(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) { +static void dndProcessResponse(void *parent, SRpcMsg *pRsp, SEpSet *pEpSet) { SDnode *pDnode = parent; STransMgmt *pMgmt = &pDnode->tmgmt; - tmsg_t msgType = pMsg->msgType; + tmsg_t msgType = pRsp->msgType; if (dndGetStat(pDnode) == DND_STAT_STOPPED) { - if (pMsg == NULL || pMsg->pCont == NULL) return; - dTrace("RPC %p, rsp:%s is ignored since dnode is stopping", pMsg->handle, TMSG_INFO(msgType)); - rpcFreeCont(pMsg->pCont); + if (pRsp == NULL || pRsp->pCont == NULL) return; + dTrace("RPC %p, rsp:%s is ignored since dnode is stopping", pRsp->handle, TMSG_INFO(msgType)); + rpcFreeCont(pRsp->pCont); return; } DndMsgFp fp = pMgmt->msgFp[TMSG_INDEX(msgType)]; if (fp != NULL) { - dTrace("RPC %p, rsp:%s will be processed, code:0x%x", pMsg->handle, TMSG_INFO(msgType), pMsg->code & 0XFFFF); - (*fp)(pDnode, pMsg, pEpSet); + dTrace("RPC %p, rsp:%s will be processed, code:0x%x", pRsp->handle, TMSG_INFO(msgType), pRsp->code & 0XFFFF); + (*fp)(pDnode, pRsp, pEpSet); } else { - dError("RPC %p, rsp:%s not processed", pMsg->handle, TMSG_INFO(msgType)); - rpcFreeCont(pMsg->pCont); + dError("RPC %p, rsp:%s not processed", pRsp->handle, TMSG_INFO(msgType)); + rpcFreeCont(pRsp->pCont); } } @@ -203,48 +201,48 @@ static void dndCleanupClient(SDnode *pDnode) { } } -static void dndProcessRequest(void *param, SRpcMsg *pMsg, SEpSet *pEpSet) { +static void dndProcessRequest(void *param, SRpcMsg *pReq, SEpSet *pEpSet) { SDnode *pDnode = param; STransMgmt *pMgmt = &pDnode->tmgmt; - tmsg_t msgType = pMsg->msgType; + tmsg_t msgType = pReq->msgType; if (msgType == TDMT_DND_NETWORK_TEST) { - dTrace("RPC %p, network test req, app:%p will be processed, code:0x%x", pMsg->handle, pMsg->ahandle, pMsg->code); - dndProcessStartupReq(pDnode, pMsg); + dTrace("RPC %p, network test req, app:%p will be processed, code:0x%x", pReq->handle, pReq->ahandle, pReq->code); + dndProcessStartupReq(pDnode, pReq); return; } if (dndGetStat(pDnode) == DND_STAT_STOPPED) { - dError("RPC %p, req:%s app:%p is ignored since dnode exiting", pMsg->handle, TMSG_INFO(msgType), pMsg->ahandle); - SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_DND_EXITING}; + dError("RPC %p, req:%s app:%p is ignored since dnode exiting", pReq->handle, TMSG_INFO(msgType), pReq->ahandle); + SRpcMsg rspMsg = {.handle = pReq->handle, .code = TSDB_CODE_DND_OFFLINE}; rpcSendResponse(&rspMsg); - rpcFreeCont(pMsg->pCont); + rpcFreeCont(pReq->pCont); return; } else if (dndGetStat(pDnode) != DND_STAT_RUNNING) { - dError("RPC %p, req:%s app:%p is ignored since dnode not running", pMsg->handle, TMSG_INFO(msgType), pMsg->ahandle); - SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_APP_NOT_READY}; + dError("RPC %p, req:%s app:%p is ignored since dnode not running", pReq->handle, TMSG_INFO(msgType), pReq->ahandle); + SRpcMsg rspMsg = {.handle = pReq->handle, .code = TSDB_CODE_APP_NOT_READY}; rpcSendResponse(&rspMsg); - rpcFreeCont(pMsg->pCont); + rpcFreeCont(pReq->pCont); return; } - if (pMsg->pCont == NULL) { - dTrace("RPC %p, req:%s app:%p not processed since content is null", pMsg->handle, TMSG_INFO(msgType), - pMsg->ahandle); - SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_DND_INVALID_MSG_LEN}; + if (pReq->pCont == NULL) { + dTrace("RPC %p, req:%s app:%p not processed since content is null", pReq->handle, TMSG_INFO(msgType), + pReq->ahandle); + SRpcMsg rspMsg = {.handle = pReq->handle, .code = TSDB_CODE_DND_INVALID_MSG_LEN}; rpcSendResponse(&rspMsg); return; } DndMsgFp fp = pMgmt->msgFp[TMSG_INDEX(msgType)]; if (fp != NULL) { - dTrace("RPC %p, req:%s app:%p will be processed", pMsg->handle, TMSG_INFO(msgType), pMsg->ahandle); - (*fp)(pDnode, pMsg, pEpSet); + dTrace("RPC %p, req:%s app:%p will be processed", pReq->handle, TMSG_INFO(msgType), pReq->ahandle); + (*fp)(pDnode, pReq, pEpSet); } else { - dError("RPC %p, req:%s app:%p is not processed since no handle", pMsg->handle, TMSG_INFO(msgType), pMsg->ahandle); - SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_MSG_NOT_PROCESSED}; + dError("RPC %p, req:%s app:%p is not processed since no handle", pReq->handle, TMSG_INFO(msgType), pReq->ahandle); + SRpcMsg rspMsg = {.handle = pReq->handle, .code = TSDB_CODE_MSG_NOT_PROCESSED}; rpcSendResponse(&rspMsg); - rpcFreeCont(pMsg->pCont); + rpcFreeCont(pReq->pCont); } } @@ -256,7 +254,7 @@ static void dndSendMsgToMnodeRecv(SDnode *pDnode, SRpcMsg *pRpcMsg, SRpcMsg *pRp rpcSendRecv(pMgmt->clientRpc, &epSet, pRpcMsg, pRpcRsp); } -static int32_t dndAuthInternalMsg(SDnode *pDnode, char *user, char *spi, char *encrypt, char *secret, char *ckey) { +static int32_t dndAuthInternalReq(SDnode *pDnode, char *user, char *spi, char *encrypt, char *secret, char *ckey) { if (strcmp(user, INTERNAL_USER) == 0) { // A simple temporary implementation char pass[TSDB_PASSWORD_LEN] = {0}; @@ -283,7 +281,7 @@ static int32_t dndAuthInternalMsg(SDnode *pDnode, char *user, char *spi, char *e static int32_t dndRetrieveUserAuthInfo(void *parent, char *user, char *spi, char *encrypt, char *secret, char *ckey) { SDnode *pDnode = parent; - if (dndAuthInternalMsg(parent, user, spi, encrypt, secret, ckey) == 0) { + if (dndAuthInternalReq(parent, user, spi, encrypt, secret, ckey) == 0) { // dTrace("get internal auth success"); return 0; } @@ -300,10 +298,10 @@ static int32_t dndRetrieveUserAuthInfo(void *parent, char *user, char *spi, char // dDebug("user:%s, send auth msg to other mnodes", user); - SAuthMsg *pMsg = rpcMallocCont(sizeof(SAuthMsg)); - tstrncpy(pMsg->user, user, TSDB_USER_LEN); + SAuthReq *pReq = rpcMallocCont(sizeof(SAuthReq)); + tstrncpy(pReq->user, user, TSDB_USER_LEN); - SRpcMsg rpcMsg = {.pCont = pMsg, .contLen = sizeof(SAuthMsg), .msgType = TDMT_MND_AUTH}; + SRpcMsg rpcMsg = {.pCont = pReq, .contLen = sizeof(SAuthReq), .msgType = TDMT_MND_AUTH}; SRpcMsg rpcRsp = {0}; dndSendMsgToMnodeRecv(pDnode, &rpcMsg, &rpcRsp); @@ -383,14 +381,19 @@ void dndCleanupTrans(SDnode *pDnode) { dInfo("dnode-transport is cleaned up"); } -void dndSendMsgToDnode(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pMsg) { +int32_t dndSendReqToDnode(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pReq) { STransMgmt *pMgmt = &pDnode->tmgmt; - if (pMgmt->clientRpc == NULL) return; - rpcSendRequest(pMgmt->clientRpc, pEpSet, pMsg, NULL); + if (pMgmt->clientRpc == NULL) { + terrno = TSDB_CODE_DND_OFFLINE; + return -1; + } + + rpcSendRequest(pMgmt->clientRpc, pEpSet, pReq, NULL); + return 0; } -void dndSendMsgToMnode(SDnode *pDnode, SRpcMsg *pMsg) { +int32_t dndSendReqToMnode(SDnode *pDnode, SRpcMsg *pReq) { SEpSet epSet = {0}; dndGetMnodeEpSet(pDnode, &epSet); - dndSendMsgToDnode(pDnode, &epSet, pMsg); + return dndSendReqToDnode(pDnode, &epSet, pReq); } diff --git a/source/dnode/mgmt/impl/src/dndVnodes.c b/source/dnode/mgmt/impl/src/dndVnodes.c index 8835e0ba65..bf27a542ae 100644 --- a/source/dnode/mgmt/impl/src/dndVnodes.c +++ b/source/dnode/mgmt/impl/src/dndVnodes.c @@ -33,14 +33,14 @@ typedef struct { int8_t dropped; int8_t accessState; uint64_t dbUid; - char *db; - char *path; - SVnode *pImpl; + char * db; + char * path; + SVnode * pImpl; STaosQueue *pWriteQ; STaosQueue *pSyncQ; STaosQueue *pApplyQ; STaosQueue *pQueryQ; - STaosQueue* pFetchQ; + STaosQueue *pFetchQ; } SVnodeObj; typedef struct { @@ -49,26 +49,12 @@ typedef struct { int32_t failed; int32_t threadIndex; pthread_t thread; - SDnode *pDnode; + SDnode * pDnode; SWrapperCfg *pCfgs; } SVnodeThread; -static int32_t dndInitVnodeReadWorker(SDnode *pDnode); -static int32_t dndInitVnodeWriteWorker(SDnode *pDnode); -static int32_t dndInitVnodeSyncWorker(SDnode *pDnode); -static void dndCleanupVnodeReadWorker(SDnode *pDnode); -static void dndCleanupVnodeWriteWorker(SDnode *pDnode); -static void dndCleanupVnodeSyncWorker(SDnode *pDnode); -static int32_t dndAllocVnodeQueryQueue(SDnode *pDnode, SVnodeObj *pVnode); -static int32_t dndAllocVnodeFetchQueue(SDnode *pDnode, SVnodeObj *pVnode); -static int32_t dndAllocVnodeWriteQueue(SDnode *pDnode, SVnodeObj *pVnode); -static int32_t dndAllocVnodeApplyQueue(SDnode *pDnode, SVnodeObj *pVnode); -static int32_t dndAllocVnodeSyncQueue(SDnode *pDnode, SVnodeObj *pVnode); -static void dndFreeVnodeQueryQueue(SDnode *pDnode, SVnodeObj *pVnode); -static void dndFreeVnodeFetchQueue(SDnode *pDnode, SVnodeObj *pVnode); -static void dndFreeVnodeWriteQueue(SDnode *pDnode, SVnodeObj *pVnode); -static void dndFreeVnodeApplyQueue(SDnode *pDnode, SVnodeObj *pVnode); -static void dndFreeVnodeSyncQueue(SDnode *pDnode, SVnodeObj *pVnode); +static int32_t dndAllocVnodeQueue(SDnode *pDnode, SVnodeObj *pVnode); +static void dndFreeVnodeQueue(SDnode *pDnode, SVnodeObj *pVnode); static void dndProcessVnodeQueryQueue(SVnodeObj *pVnode, SRpcMsg *pMsg); static void dndProcessVnodeFetchQueue(SVnodeObj *pVnode, SRpcMsg *pMsg); @@ -81,7 +67,7 @@ void dndProcessVnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pE void dndProcessVnodeSyncMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet); static int32_t dndPutMsgIntoVnodeApplyQueue(SDnode *pDnode, int32_t vgId, SRpcMsg *pMsg); -static SVnodeObj *dndAcquireVnode(SDnode *pDnode, int32_t vgId); +static SVnodeObj * dndAcquireVnode(SDnode *pDnode, int32_t vgId); static void dndReleaseVnode(SDnode *pDnode, SVnodeObj *pVnode); static int32_t dndOpenVnode(SDnode *pDnode, SWrapperCfg *pCfg, SVnode *pImpl); static void dndCloseVnode(SDnode *pDnode, SVnodeObj *pVnode); @@ -94,7 +80,7 @@ static void dndCloseVnodes(SDnode *pDnode); static SVnodeObj *dndAcquireVnode(SDnode *pDnode, int32_t vgId) { SVnodesMgmt *pMgmt = &pDnode->vmgmt; - SVnodeObj *pVnode = NULL; + SVnodeObj * pVnode = NULL; int32_t refCount = 0; taosRLockLatch(&pMgmt->latch); @@ -117,24 +103,22 @@ static void dndReleaseVnode(SDnode *pDnode, SVnodeObj *pVnode) { if (pVnode == NULL) return; SVnodesMgmt *pMgmt = &pDnode->vmgmt; - taosRLockLatch(&pMgmt->latch); int32_t refCount = atomic_sub_fetch_32(&pVnode->refCount, 1); taosRUnLockLatch(&pMgmt->latch); - dTrace("vgId:%d, release vnode, refCount:%d", pVnode->vgId, refCount); } static int32_t dndOpenVnode(SDnode *pDnode, SWrapperCfg *pCfg, SVnode *pImpl) { SVnodesMgmt *pMgmt = &pDnode->vmgmt; - SVnodeObj *pVnode = calloc(1, sizeof(SVnodeObj)); + SVnodeObj * pVnode = calloc(1, sizeof(SVnodeObj)); if (pVnode == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } pVnode->vgId = pCfg->vgId; - pVnode->refCount = 1; + pVnode->refCount = 0; pVnode->dropped = 0; pVnode->accessState = TSDB_VN_ALL_ACCCESS; pVnode->pImpl = pImpl; @@ -148,23 +132,8 @@ static int32_t dndOpenVnode(SDnode *pDnode, SWrapperCfg *pCfg, SVnode *pImpl) { return -1; } - if (dndAllocVnodeQueryQueue(pDnode, pVnode) != 0) { - return -1; - } - - if (dndAllocVnodeFetchQueue(pDnode, pVnode) != 0) { - return -1; - } - - if (dndAllocVnodeWriteQueue(pDnode, pVnode) != 0) { - return -1; - } - - if (dndAllocVnodeApplyQueue(pDnode, pVnode) != 0) { - return -1; - } - - if (dndAllocVnodeSyncQueue(pDnode, pVnode) != 0) { + if (dndAllocVnodeQueue(pDnode, pVnode) != 0) { + terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } @@ -192,11 +161,17 @@ static void dndCloseVnode(SDnode *pDnode, SVnodeObj *pVnode) { while (!taosQueueEmpty(pVnode->pQueryQ)) taosMsleep(10); while (!taosQueueEmpty(pVnode->pFetchQ)) taosMsleep(10); - dndFreeVnodeQueryQueue(pDnode, pVnode); - dndFreeVnodeFetchQueue(pDnode, pVnode); - dndFreeVnodeWriteQueue(pDnode, pVnode); - dndFreeVnodeApplyQueue(pDnode, pVnode); - dndFreeVnodeSyncQueue(pDnode, pVnode); + dndFreeVnodeQueue(pDnode, pVnode); + vnodeClose(pVnode->pImpl); + pVnode->pImpl = NULL; + + dDebug("vgId:%d, vnode is closed", pVnode->vgId); + + if (pVnode->dropped) { + dDebug("vgId:%d, vnode is destroyed for dropped:%d", pVnode->vgId, pVnode->dropped); + vnodeDestroy(pVnode->path); + } + free(pVnode->path); free(pVnode->db); free(pVnode); @@ -213,7 +188,7 @@ static SVnodeObj **dndGetVnodesFromHash(SDnode *pDnode, int32_t *numOfVnodes) { void *pIter = taosHashIterate(pMgmt->hash, NULL); while (pIter) { SVnodeObj **ppVnode = pIter; - SVnodeObj *pVnode = *ppVnode; + SVnodeObj * pVnode = *ppVnode; if (pVnode && num < size) { int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1); dTrace("vgId:%d, acquire vnode, refCount:%d", pVnode->vgId, refCount); @@ -235,9 +210,9 @@ static int32_t dndGetVnodesFromFile(SDnode *pDnode, SWrapperCfg **ppCfgs, int32_ int32_t code = TSDB_CODE_DND_VNODE_READ_FILE_ERROR; int32_t len = 0; int32_t maxLen = 30000; - char *content = calloc(1, maxLen + 1); - cJSON *root = NULL; - FILE *fp = NULL; + char * content = calloc(1, maxLen + 1); + cJSON * root = NULL; + FILE * fp = NULL; char file[PATH_MAX + 20] = {0}; SWrapperCfg *pCfgs = NULL; @@ -270,59 +245,57 @@ static int32_t dndGetVnodesFromFile(SDnode *pDnode, SWrapperCfg **ppCfgs, int32_ } int32_t vnodesNum = cJSON_GetArraySize(vnodes); - if (vnodesNum <= 0) { - dError("failed to read %s since vnodes size:%d invalid", file, vnodesNum); - goto PRASE_VNODE_OVER; + if (vnodesNum > 0) { + pCfgs = calloc(vnodesNum, sizeof(SWrapperCfg)); + if (pCfgs == NULL) { + dError("failed to read %s since out of memory", file); + goto PRASE_VNODE_OVER; + } + + for (int32_t i = 0; i < vnodesNum; ++i) { + cJSON *vnode = cJSON_GetArrayItem(vnodes, i); + SWrapperCfg *pCfg = &pCfgs[i]; + + cJSON *vgId = cJSON_GetObjectItem(vnode, "vgId"); + if (!vgId || vgId->type != cJSON_Number) { + dError("failed to read %s since vgId not found", file); + goto PRASE_VNODE_OVER; + } + pCfg->vgId = vgId->valueint; + snprintf(pCfg->path, sizeof(pCfg->path), "%s/vnode%d", pDnode->dir.vnodes, pCfg->vgId); + + cJSON *dropped = cJSON_GetObjectItem(vnode, "dropped"); + if (!dropped || dropped->type != cJSON_Number) { + dError("failed to read %s since dropped not found", file); + goto PRASE_VNODE_OVER; + } + pCfg->dropped = dropped->valueint; + + cJSON *vgVersion = cJSON_GetObjectItem(vnode, "vgVersion"); + if (!vgVersion || vgVersion->type != cJSON_Number) { + dError("failed to read %s since vgVersion not found", file); + goto PRASE_VNODE_OVER; + } + pCfg->vgVersion = vgVersion->valueint; + + cJSON *dbUid = cJSON_GetObjectItem(vnode, "dbUid"); + if (!dbUid || dbUid->type != cJSON_String) { + dError("failed to read %s since dbUid not found", file); + goto PRASE_VNODE_OVER; + } + pCfg->dbUid = atoll(dbUid->valuestring); + + cJSON *db = cJSON_GetObjectItem(vnode, "db"); + if (!db || db->type != cJSON_String) { + dError("failed to read %s since db not found", file); + goto PRASE_VNODE_OVER; + } + tstrncpy(pCfg->db, db->valuestring, TSDB_DB_FNAME_LEN); + } + + *ppCfgs = pCfgs; } - pCfgs = calloc(vnodesNum, sizeof(SWrapperCfg)); - if (pCfgs == NULL) { - dError("failed to read %s since out of memory", file); - goto PRASE_VNODE_OVER; - } - - for (int32_t i = 0; i < vnodesNum; ++i) { - cJSON *vnode = cJSON_GetArrayItem(vnodes, i); - SWrapperCfg *pCfg = &pCfgs[i]; - - cJSON *vgId = cJSON_GetObjectItem(vnode, "vgId"); - if (!vgId || vgId->type != cJSON_Number) { - dError("failed to read %s since vgId not found", file); - goto PRASE_VNODE_OVER; - } - pCfg->vgId = vgId->valueint; - snprintf(pCfg->path, sizeof(pCfg->path), "%s/vnode%d", pDnode->dir.vnodes, pCfg->vgId); - - cJSON *dropped = cJSON_GetObjectItem(vnode, "dropped"); - if (!dropped || dropped->type != cJSON_Number) { - dError("failed to read %s since dropped not found", file); - goto PRASE_VNODE_OVER; - } - pCfg->dropped = dropped->valueint; - - cJSON *vgVersion = cJSON_GetObjectItem(vnode, "vgVersion"); - if (!vgVersion || vgVersion->type != cJSON_Number) { - dError("failed to read %s since vgVersion not found", file); - goto PRASE_VNODE_OVER; - } - pCfg->vgVersion = vgVersion->valueint; - - cJSON *dbUid = cJSON_GetObjectItem(vnode, "dbUid"); - if (!dbUid || dbUid->type != cJSON_String) { - dError("failed to read %s since dbUid not found", file); - goto PRASE_VNODE_OVER; - } - pCfg->dbUid = atoll(dbUid->valuestring); - - cJSON *db = cJSON_GetObjectItem(vnode, "db"); - if (!db || db->type != cJSON_String) { - dError("failed to read %s since db not found", file); - goto PRASE_VNODE_OVER; - } - tstrncpy(pCfg->db, db->valuestring, TSDB_DB_FNAME_LEN); - } - - *ppCfgs = pCfgs; *numOfVnodes = vnodesNum; code = 0; dInfo("succcessed to read file %s", file); @@ -352,7 +325,7 @@ static int32_t dndWriteVnodesToFile(SDnode *pDnode) { int32_t len = 0; int32_t maxLen = 65536; - char *content = calloc(1, maxLen + 1); + char * content = calloc(1, maxLen + 1); len += snprintf(content + len, maxLen - len, "{\n"); len += snprintf(content + len, maxLen - len, " \"vnodes\": [\n"); @@ -388,14 +361,14 @@ static int32_t dndWriteVnodesToFile(SDnode *pDnode) { free(pVnodes); } - dInfo("successed to write %s", file); + dDebug("successed to write %s", realfile); return taosRenameFile(file, realfile); } static void *dnodeOpenVnodeFunc(void *param) { SVnodeThread *pThread = param; - SDnode *pDnode = pThread->pDnode; - SVnodesMgmt *pMgmt = &pDnode->vmgmt; + SDnode * pDnode = pThread->pDnode; + SVnodesMgmt * pMgmt = &pDnode->vmgmt; dDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum); setThreadName("open-vnodes"); @@ -408,7 +381,7 @@ static void *dnodeOpenVnodeFunc(void *param) { pMgmt->openVnodes, pMgmt->totalVnodes); dndReportStartup(pDnode, "open-vnodes", stepDesc); - SVnode *pImpl = vnodeOpen(pCfg->path, NULL); + SVnode *pImpl = vnodeOpen(pCfg->path, NULL, pCfg->vgId); if (pImpl == NULL) { dError("vgId:%d, failed to open vnode by thread:%d", pCfg->vgId, pThread->threadIndex); pThread->failed++; @@ -498,13 +471,13 @@ static int32_t dndOpenVnodes(SDnode *pDnode) { } static void dndCloseVnodes(SDnode *pDnode) { + dInfo("start to close all vnodes"); SVnodesMgmt *pMgmt = &pDnode->vmgmt; int32_t numOfVnodes = 0; SVnodeObj **pVnodes = dndGetVnodesFromHash(pDnode, &numOfVnodes); for (int32_t i = 0; i < numOfVnodes; ++i) { - dndReleaseVnode(pDnode, pVnodes[i]); dndCloseVnode(pDnode, pVnodes[i]); } @@ -520,8 +493,8 @@ static void dndCloseVnodes(SDnode *pDnode) { dInfo("total vnodes:%d are all closed", numOfVnodes); } -static SCreateVnodeMsg *dndParseCreateVnodeReq(SRpcMsg *rpcMsg) { - SCreateVnodeMsg *pCreate = rpcMsg->pCont; +static SCreateVnodeReq *dndParseCreateVnodeReq(SRpcMsg *pReq) { + SCreateVnodeReq *pCreate = pReq->pCont; pCreate->vgId = htonl(pCreate->vgId); pCreate->dnodeId = htonl(pCreate->dnodeId); pCreate->dbUid = htobe64(pCreate->dbUid); @@ -545,7 +518,8 @@ static SCreateVnodeMsg *dndParseCreateVnodeReq(SRpcMsg *rpcMsg) { return pCreate; } -static void dndGenerateVnodeCfg(SCreateVnodeMsg *pCreate, SVnodeCfg *pCfg) { +static void dndGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) { + pCfg->vgId = pCreate->vgId; pCfg->wsize = pCreate->cacheBlockSize; pCfg->ssize = pCreate->cacheBlockSize; pCfg->wsize = pCreate->cacheBlockSize; @@ -554,7 +528,7 @@ static void dndGenerateVnodeCfg(SCreateVnodeMsg *pCreate, SVnodeCfg *pCfg) { pCfg->ttl = 4; pCfg->keep = pCreate->daysToKeep0; pCfg->isWeak = true; - pCfg->tsdbCfg.keep0 = pCreate->daysToKeep0; + pCfg->tsdbCfg.keep = pCreate->daysToKeep0; pCfg->tsdbCfg.keep1 = pCreate->daysToKeep2; pCfg->tsdbCfg.keep2 = pCreate->daysToKeep0; pCfg->tsdbCfg.lruCacheSize = pCreate->cacheBlockSize; @@ -568,7 +542,7 @@ static void dndGenerateVnodeCfg(SCreateVnodeMsg *pCreate, SVnodeCfg *pCfg) { pCfg->walCfg.vgId = pCreate->vgId; } -static void dndGenerateWrapperCfg(SDnode *pDnode, SCreateVnodeMsg *pCreate, SWrapperCfg *pCfg) { +static void dndGenerateWrapperCfg(SDnode *pDnode, SCreateVnodeReq *pCreate, SWrapperCfg *pCfg) { memcpy(pCfg->db, pCreate->db, TSDB_DB_FNAME_LEN); pCfg->dbUid = pCreate->dbUid; pCfg->dropped = 0; @@ -577,20 +551,20 @@ static void dndGenerateWrapperCfg(SDnode *pDnode, SCreateVnodeMsg *pCreate, SWra pCfg->vgVersion = pCreate->vgVersion; } -static SDropVnodeMsg *vnodeParseDropVnodeReq(SRpcMsg *rpcMsg) { - SDropVnodeMsg *pDrop = rpcMsg->pCont; +static SDropVnodeReq *dndParseDropVnodeReq(SRpcMsg *pReq) { + SDropVnodeReq *pDrop = pReq->pCont; pDrop->vgId = htonl(pDrop->vgId); return pDrop; } -static SAuthVnodeMsg *vnodeParseAuthVnodeReq(SRpcMsg *rpcMsg) { - SAuthVnodeMsg *pAuth = rpcMsg->pCont; +static SAuthVnodeReq *dndParseAuthVnodeReq(SRpcMsg *pReq) { + SAuthVnodeReq *pAuth = pReq->pCont; pAuth->vgId = htonl(pAuth->vgId); return pAuth; } -int32_t dndProcessCreateVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { - SCreateVnodeMsg *pCreate = dndParseCreateVnodeReq(rpcMsg); +int32_t dndProcessCreateVnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SCreateVnodeReq *pCreate = dndParseCreateVnodeReq(pReq); dDebug("vgId:%d, create vnode req is received", pCreate->vgId); SVnodeCfg vnodeCfg = {0}; @@ -601,18 +575,21 @@ int32_t dndProcessCreateVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { SVnodeObj *pVnode = dndAcquireVnode(pDnode, pCreate->vgId); if (pVnode != NULL) { - dDebug("vgId:%d, already exist, return success", pCreate->vgId); + dDebug("vgId:%d, already exist", pCreate->vgId); dndReleaseVnode(pDnode, pVnode); - return 0; + terrno = TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED; + return -1; } - SVnode *pImpl = vnodeOpen(wrapperCfg.path, NULL /*pCfg*/); + SVnode *pImpl = vnodeOpen(wrapperCfg.path, NULL /*pCfg*/, pCreate->vgId); if (pImpl == NULL) { + dError("vgId:%d, failed to create vnode since %s", pCreate->vgId, terrstr()); return -1; } int32_t code = dndOpenVnode(pDnode, &wrapperCfg, pImpl); if (code != 0) { + dError("vgId:%d, failed to open vnode since %s", pCreate->vgId, terrstr()); vnodeClose(pImpl); vnodeDestroy(wrapperCfg.path); terrno = code; @@ -630,23 +607,20 @@ int32_t dndProcessCreateVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { return 0; } -int32_t dndProcessAlterVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { - SAlterVnodeMsg *pAlter = (SAlterVnodeMsg *)dndParseCreateVnodeReq(rpcMsg); +int32_t dndProcessAlterVnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SAlterVnodeReq *pAlter = (SAlterVnodeReq *)dndParseCreateVnodeReq(pReq); dDebug("vgId:%d, alter vnode req is received", pAlter->vgId); SVnodeCfg vnodeCfg = {0}; dndGenerateVnodeCfg(pAlter, &vnodeCfg); - SWrapperCfg wrapperCfg = {0}; - dndGenerateWrapperCfg(pDnode, pAlter, &wrapperCfg); - SVnodeObj *pVnode = dndAcquireVnode(pDnode, pAlter->vgId); if (pVnode == NULL) { dDebug("vgId:%d, failed to alter vnode since %s", pAlter->vgId, terrstr()); - return terrno; + return -1; } - if (wrapperCfg.vgVersion == pVnode->vgVersion) { + if (pAlter->vgVersion == pVnode->vgVersion) { dndReleaseVnode(pDnode, pVnode); dDebug("vgId:%d, no need to alter vnode cfg for version unchanged ", pAlter->vgId); return 0; @@ -655,11 +629,11 @@ int32_t dndProcessAlterVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { if (vnodeAlter(pVnode->pImpl, &vnodeCfg) != 0) { dError("vgId:%d, failed to alter vnode since %s", pAlter->vgId, terrstr()); dndReleaseVnode(pDnode, pVnode); - return terrno; + return -1; } int32_t oldVersion = pVnode->vgVersion; - pVnode->vgVersion = wrapperCfg.vgVersion; + pVnode->vgVersion = pAlter->vgVersion; int32_t code = dndWriteVnodesToFile(pDnode); if (code != 0) { pVnode->vgVersion = oldVersion; @@ -669,8 +643,8 @@ int32_t dndProcessAlterVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { return code; } -int32_t dndProcessDropVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { - SDropVnodeMsg *pDrop = vnodeParseDropVnodeReq(rpcMsg); +int32_t dndProcessDropVnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SDropVnodeReq *pDrop = dndParseDropVnodeReq(pReq); int32_t vgId = pDrop->vgId; dDebug("vgId:%d, drop vnode req is received", vgId); @@ -678,35 +652,33 @@ int32_t dndProcessDropVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { SVnodeObj *pVnode = dndAcquireVnode(pDnode, vgId); if (pVnode == NULL) { dDebug("vgId:%d, failed to drop since %s", vgId, terrstr()); - return 0; + terrno = TSDB_CODE_DND_VNODE_NOT_DEPLOYED; + return -1; } pVnode->dropped = 1; if (dndWriteVnodesToFile(pDnode) != 0) { pVnode->dropped = 0; - return terrno; + dndReleaseVnode(pDnode, pVnode); + return -1; } - dndReleaseVnode(pDnode, pVnode); dndCloseVnode(pDnode, pVnode); - vnodeClose(pVnode->pImpl); - vnodeDestroy(pVnode->path); dndWriteVnodesToFile(pDnode); return 0; } -int32_t dndProcessAuthVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { - SAuthVnodeMsg *pAuth = (SAuthVnodeMsg *)vnodeParseAuthVnodeReq(rpcMsg); +int32_t dndProcessAuthVnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SAuthVnodeReq *pAuth = (SAuthVnodeReq *)dndParseAuthVnodeReq(pReq); - int32_t code = 0; int32_t vgId = pAuth->vgId; dDebug("vgId:%d, auth vnode req is received", vgId); SVnodeObj *pVnode = dndAcquireVnode(pDnode, vgId); if (pVnode == NULL) { dDebug("vgId:%d, failed to auth since %s", vgId, terrstr()); - return terrno; + return -1; } pVnode->accessState = pAuth->accessState; @@ -714,30 +686,30 @@ int32_t dndProcessAuthVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { return 0; } -int32_t dndProcessSyncVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { - SAuthVnodeMsg *pAuth = (SAuthVnodeMsg *)vnodeParseAuthVnodeReq(rpcMsg); +int32_t dndProcessSyncVnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SSyncVnodeReq *pSync = (SSyncVnodeReq *)dndParseDropVnodeReq(pReq); - int32_t vgId = pAuth->vgId; - dDebug("vgId:%d, auth vnode req is received", vgId); + int32_t vgId = pSync->vgId; + dDebug("vgId:%d, sync vnode req is received", vgId); SVnodeObj *pVnode = dndAcquireVnode(pDnode, vgId); if (pVnode == NULL) { - dDebug("vgId:%d, failed to auth since %s", vgId, terrstr()); - return terrno; + dDebug("vgId:%d, failed to sync since %s", vgId, terrstr()); + return -1; } if (vnodeSync(pVnode->pImpl) != 0) { - dError("vgId:%d, failed to auth vnode since %s", vgId, terrstr()); + dError("vgId:%d, failed to sync vnode since %s", vgId, terrstr()); dndReleaseVnode(pDnode, pVnode); - return terrno; + return -1; } dndReleaseVnode(pDnode, pVnode); return 0; } -int32_t dndProcessCompactVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { - SCompactVnodeMsg *pCompact = (SCompactVnodeMsg *)vnodeParseDropVnodeReq(rpcMsg); +int32_t dndProcessCompactVnodeReq(SDnode *pDnode, SRpcMsg *pReq) { + SCompactVnodeReq *pCompact = (SCompactVnodeReq *)dndParseDropVnodeReq(pReq); int32_t vgId = pCompact->vgId; dDebug("vgId:%d, compact vnode req is received", vgId); @@ -745,13 +717,13 @@ int32_t dndProcessCompactVnodeReq(SDnode *pDnode, SRpcMsg *rpcMsg) { SVnodeObj *pVnode = dndAcquireVnode(pDnode, vgId); if (pVnode == NULL) { dDebug("vgId:%d, failed to compact since %s", vgId, terrstr()); - return terrno; + return -1; } if (vnodeCompact(pVnode->pImpl) != 0) { dError("vgId:%d, failed to compact vnode since %s", vgId, terrstr()); dndReleaseVnode(pDnode, pVnode); - return terrno; + return -1; } dndReleaseVnode(pDnode, pVnode); @@ -810,6 +782,7 @@ static void dndProcessVnodeApplyQueue(SVnodeObj *pVnode, STaosQall *qall, int32_ for (int32_t i = 0; i < numOfMsgs; ++i) { taosGetQitem(qall, (void **)&pMsg); + // todo SRpcMsg *pRsp = NULL; (void)vnodeApplyWMsg(pVnode->pImpl, pMsg, &pRsp); } @@ -821,6 +794,7 @@ static void dndProcessVnodeSyncQueue(SVnodeObj *pVnode, STaosQall *qall, int32_t for (int32_t i = 0; i < numOfMsgs; ++i) { taosGetQitem(qall, (void **)&pMsg); + // todo SRpcMsg *pRsp = NULL; (void)vnodeProcessSyncReq(pVnode->pImpl, pMsg, &pRsp); } @@ -844,21 +818,25 @@ static int32_t dndWriteRpcMsgToVnodeQueue(STaosQueue *pQueue, SRpcMsg *pRpcMsg) } if (code != TSDB_CODE_SUCCESS) { - SRpcMsg rsp = {.handle = pRpcMsg->handle, .code = code}; - rpcSendResponse(&rsp); + if (pRpcMsg->msgType & 1u) { + SRpcMsg rsp = {.handle = pRpcMsg->handle, .code = code}; + rpcSendResponse(&rsp); + } rpcFreeCont(pRpcMsg->pCont); } } static SVnodeObj *dndAcquireVnodeFromMsg(SDnode *pDnode, SRpcMsg *pMsg) { - SMsgHead *pHead = (SMsgHead *)pMsg->pCont; + SMsgHead *pHead = pMsg->pCont; pHead->contLen = htonl(pHead->contLen); pHead->vgId = htonl(pHead->vgId); SVnodeObj *pVnode = dndAcquireVnode(pDnode, pHead->vgId); if (pVnode == NULL) { - SRpcMsg rsp = {.handle = pMsg->handle, .code = TSDB_CODE_VND_INVALID_VGROUP_ID}; - rpcSendResponse(&rsp); + if (pMsg->msgType & 1u) { + SRpcMsg rsp = {.handle = pMsg->handle, .code = TSDB_CODE_VND_INVALID_VGROUP_ID}; + rpcSendResponse(&rsp); + } rpcFreeCont(pMsg->pCont); } @@ -899,193 +877,96 @@ void dndProcessVnodeFetchMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { static int32_t dndPutMsgIntoVnodeApplyQueue(SDnode *pDnode, int32_t vgId, SRpcMsg *pMsg) { SVnodeObj *pVnode = dndAcquireVnode(pDnode, vgId); - if (pVnode == NULL) { - return -1; - } + if (pVnode == NULL) return -1; int32_t code = taosWriteQitem(pVnode->pApplyQ, pMsg); dndReleaseVnode(pDnode, pVnode); return code; } -static int32_t dndAllocVnodeQueryQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - pVnode->pQueryQ = tWorkerAllocQueue(&pMgmt->queryPool, pVnode, (FProcessItem)dndProcessVnodeQueryQueue); - if (pVnode->pQueryQ == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - return 0; -} - -static void dndFreeVnodeQueryQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - tWorkerFreeQueue(&pMgmt->queryPool, pVnode->pQueryQ); - pVnode->pQueryQ = NULL; -} - -static int32_t dndAllocVnodeFetchQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - pVnode->pFetchQ = tWorkerAllocQueue(&pMgmt->fetchPool, pVnode, (FProcessItem)dndProcessVnodeFetchQueue); - if (pVnode->pFetchQ == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - return 0; -} - -static void dndFreeVnodeFetchQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - tWorkerFreeQueue(&pMgmt->fetchPool, pVnode->pFetchQ); - pVnode->pFetchQ = NULL; -} - -static int32_t dndInitVnodeReadWorker(SDnode *pDnode) { +static int32_t dndInitVnodeWorkers(SDnode *pDnode) { SVnodesMgmt *pMgmt = &pDnode->vmgmt; int32_t maxFetchThreads = 4; - float threadsForQuery = MAX(pDnode->opt.numOfCores * pDnode->opt.ratioOfQueryCores, 1); + int32_t minFetchThreads = MIN(maxFetchThreads, pDnode->opt.numOfCores); + int32_t minQueryThreads = MAX((int32_t)(pDnode->opt.numOfCores * pDnode->opt.ratioOfQueryCores), 1); + int32_t maxQueryThreads = minQueryThreads; + int32_t maxWriteThreads = MAX(pDnode->opt.numOfCores, 1); + int32_t maxSyncThreads = MAX(pDnode->opt.numOfCores / 2, 1); SWorkerPool *pPool = &pMgmt->queryPool; pPool->name = "vnode-query"; - pPool->min = (int32_t)threadsForQuery; - pPool->max = pPool->min; - if (tWorkerInit(pPool) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } + pPool->min = minQueryThreads; + pPool->max = maxQueryThreads; + if (tWorkerInit(pPool) != 0) return -1; pPool = &pMgmt->fetchPool; pPool->name = "vnode-fetch"; - pPool->min = MIN(maxFetchThreads, pDnode->opt.numOfCores); - pPool->max = pPool->min; - if (tWorkerInit(pPool) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } + pPool->min = minFetchThreads; + pPool->max = maxFetchThreads; + if (tWorkerInit(pPool) != 0) return -1; - dDebug("vnode read worker is initialized"); + SMWorkerPool *pMPool = &pMgmt->writePool; + pMPool->name = "vnode-write"; + pMPool->max = maxWriteThreads; + if (tMWorkerInit(pMPool) != 0) return -1; + + pMPool = &pMgmt->syncPool; + pMPool->name = "vnode-sync"; + pMPool->max = maxSyncThreads; + if (tMWorkerInit(pMPool) != 0) return -1; + + dDebug("vnode workers is initialized"); return 0; } -static void dndCleanupVnodeReadWorker(SDnode *pDnode) { +static void dndCleanupVnodeWorkers(SDnode *pDnode) { SVnodesMgmt *pMgmt = &pDnode->vmgmt; tWorkerCleanup(&pMgmt->fetchPool); tWorkerCleanup(&pMgmt->queryPool); - dDebug("vnode close worker is initialized"); -} - -static int32_t dndAllocVnodeWriteQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - pVnode->pWriteQ = tMWorkerAllocQueue(&pMgmt->writePool, pVnode, (FProcessItems)dndProcessVnodeWriteQueue); - if (pVnode->pWriteQ == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - return 0; -} - -static void dndFreeVnodeWriteQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - tMWorkerFreeQueue(&pMgmt->writePool, pVnode->pWriteQ); - pVnode->pWriteQ = NULL; -} - -static int32_t dndAllocVnodeApplyQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - pVnode->pApplyQ = tMWorkerAllocQueue(&pMgmt->writePool, pVnode, (FProcessItems)dndProcessVnodeApplyQueue); - if (pVnode->pApplyQ == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - return 0; -} - -static void dndFreeVnodeApplyQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - tMWorkerFreeQueue(&pMgmt->writePool, pVnode->pApplyQ); - pVnode->pApplyQ = NULL; -} - -static int32_t dndInitVnodeWriteWorker(SDnode *pDnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - SMWorkerPool *pPool = &pMgmt->writePool; - pPool->name = "vnode-write"; - pPool->max = pDnode->opt.numOfCores; - if (tMWorkerInit(pPool) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - dDebug("vnode write worker is initialized"); - return 0; -} - -static void dndCleanupVnodeWriteWorker(SDnode *pDnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; tMWorkerCleanup(&pMgmt->writePool); - dDebug("vnode write worker is closed"); -} - -static int32_t dndAllocVnodeSyncQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - pVnode->pSyncQ = tMWorkerAllocQueue(&pMgmt->syncPool, pVnode, (FProcessItems)dndProcessVnodeSyncQueue); - if (pVnode->pSyncQ == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - return 0; -} - -static void dndFreeVnodeSyncQueue(SDnode *pDnode, SVnodeObj *pVnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - tMWorkerFreeQueue(&pMgmt->syncPool, pVnode->pSyncQ); - pVnode->pSyncQ = NULL; -} - -static int32_t dndInitVnodeSyncWorker(SDnode *pDnode) { - int32_t maxThreads = pDnode->opt.numOfCores / 2; - if (maxThreads < 1) maxThreads = 1; - - SVnodesMgmt *pMgmt = &pDnode->vmgmt; - SMWorkerPool *pPool = &pMgmt->syncPool; - pPool->name = "vnode-sync"; - pPool->max = maxThreads; - if (tMWorkerInit(pPool) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - dDebug("vnode sync worker is initialized"); - return 0; -} - -static void dndCleanupVnodeSyncWorker(SDnode *pDnode) { - SVnodesMgmt *pMgmt = &pDnode->vmgmt; tMWorkerCleanup(&pMgmt->syncPool); - dDebug("vnode sync worker is closed"); + dDebug("vnode workers is closed"); +} + +static int32_t dndAllocVnodeQueue(SDnode *pDnode, SVnodeObj *pVnode) { + SVnodesMgmt *pMgmt = &pDnode->vmgmt; + + pVnode->pWriteQ = tMWorkerAllocQueue(&pMgmt->writePool, pVnode, (FProcessItems)dndProcessVnodeWriteQueue); + pVnode->pApplyQ = tMWorkerAllocQueue(&pMgmt->writePool, pVnode, (FProcessItems)dndProcessVnodeApplyQueue); + pVnode->pSyncQ = tMWorkerAllocQueue(&pMgmt->syncPool, pVnode, (FProcessItems)dndProcessVnodeSyncQueue); + pVnode->pFetchQ = tWorkerAllocQueue(&pMgmt->fetchPool, pVnode, (FProcessItem)dndProcessVnodeFetchQueue); + pVnode->pQueryQ = tWorkerAllocQueue(&pMgmt->queryPool, pVnode, (FProcessItem)dndProcessVnodeQueryQueue); + + if (pVnode->pApplyQ == NULL || pVnode->pWriteQ == NULL || pVnode->pSyncQ == NULL || pVnode->pFetchQ == NULL || + pVnode->pQueryQ == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + return 0; +} + +static void dndFreeVnodeQueue(SDnode *pDnode, SVnodeObj *pVnode) { + SVnodesMgmt *pMgmt = &pDnode->vmgmt; + tWorkerFreeQueue(&pMgmt->queryPool, pVnode->pQueryQ); + tWorkerFreeQueue(&pMgmt->fetchPool, pVnode->pFetchQ); + tMWorkerFreeQueue(&pMgmt->writePool, pVnode->pWriteQ); + tMWorkerFreeQueue(&pMgmt->writePool, pVnode->pApplyQ); + tMWorkerFreeQueue(&pMgmt->syncPool, pVnode->pSyncQ); + pVnode->pWriteQ = NULL; + pVnode->pApplyQ = NULL; + pVnode->pSyncQ = NULL; + pVnode->pFetchQ = NULL; + pVnode->pQueryQ = NULL; } int32_t dndInitVnodes(SDnode *pDnode) { dInfo("dnode-vnodes start to init"); - if (dndInitVnodeReadWorker(pDnode) != 0) { - dError("failed to init vnodes read worker since %s", terrstr()); - return -1; - } - - if (dndInitVnodeWriteWorker(pDnode) != 0) { - dError("failed to init vnodes write worker since %s", terrstr()); - return -1; - } - - if (dndInitVnodeSyncWorker(pDnode) != 0) { - dError("failed to init vnodes sync worker since %s", terrstr()); + if (dndInitVnodeWorkers(pDnode) != 0) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + dError("failed to init vnode workers since %s", terrstr()); return -1; } @@ -1101,9 +982,7 @@ int32_t dndInitVnodes(SDnode *pDnode) { void dndCleanupVnodes(SDnode *pDnode) { dInfo("dnode-vnodes start to clean up"); dndCloseVnodes(pDnode); - dndCleanupVnodeReadWorker(pDnode); - dndCleanupVnodeWriteWorker(pDnode); - dndCleanupVnodeSyncWorker(pDnode); + dndCleanupVnodeWorkers(pDnode); dInfo("dnode-vnodes is cleaned up"); } @@ -1114,12 +993,12 @@ void dndGetVnodeLoads(SDnode *pDnode, SVnodeLoads *pLoads) { pLoads->num = taosHashGetSize(pMgmt->hash); int32_t v = 0; - void *pIter = taosHashIterate(pMgmt->hash, NULL); + void * pIter = taosHashIterate(pMgmt->hash, NULL); while (pIter) { SVnodeObj **ppVnode = pIter; if (ppVnode == NULL || *ppVnode == NULL) continue; - SVnodeObj *pVnode = *ppVnode; + SVnodeObj * pVnode = *ppVnode; SVnodeLoad *pLoad = &pLoads->data[v++]; vnodeGetLoad(pVnode->pImpl, pLoad); diff --git a/source/dnode/mgmt/impl/src/dndWorker.c b/source/dnode/mgmt/impl/src/dndWorker.c index b1107fd185..e0db262f89 100644 --- a/source/dnode/mgmt/impl/src/dndWorker.c +++ b/source/dnode/mgmt/impl/src/dndWorker.c @@ -101,7 +101,9 @@ int32_t dndWriteMsgToWorker(SDnodeWorker *pWorker, void *pCont, int32_t contLen) } if (taosWriteQitem(pWorker->queue, pMsg) != 0) { - taosFreeQitem(pMsg); + if (contLen != 0) { + taosFreeQitem(pMsg); + } terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } diff --git a/source/dnode/mgmt/impl/src/dnode.c b/source/dnode/mgmt/impl/src/dnode.c index 88a96dadc4..cd27781df3 100644 --- a/source/dnode/mgmt/impl/src/dnode.c +++ b/source/dnode/mgmt/impl/src/dnode.c @@ -14,12 +14,16 @@ */ #define _DEFAULT_SOURCE -#include "dndDnode.h" +#include "dndBnode.h" +#include "dndMgmt.h" #include "dndMnode.h" +#include "dndQnode.h" +#include "dndSnode.h" #include "dndTransport.h" #include "dndVnodes.h" #include "sync.h" #include "wal.h" +#include "tfs.h" EStat dndGetStat(SDnode *pDnode) { return pDnode->stat; } @@ -42,14 +46,14 @@ char *dndStatStr(EStat stat) { } void dndReportStartup(SDnode *pDnode, char *pName, char *pDesc) { - SStartupMsg *pStartup = &pDnode->startup; + SStartupReq *pStartup = &pDnode->startup; tstrncpy(pStartup->name, pName, TSDB_STEP_NAME_LEN); tstrncpy(pStartup->desc, pDesc, TSDB_STEP_DESC_LEN); pStartup->finished = 0; } -void dndGetStartup(SDnode *pDnode, SStartupMsg *pStartup) { - memcpy(pStartup, &pDnode->startup, sizeof(SStartupMsg)); +void dndGetStartup(SDnode *pDnode, SStartupReq *pStartup) { + memcpy(pStartup, &pDnode->startup, sizeof(SStartupReq)); pStartup->finished = (dndGetStat(pDnode) == DND_STAT_RUNNING); } @@ -182,13 +186,23 @@ SDnode *dndInit(SDnodeOpt *pOption) { return NULL; } + SDiskCfg dCfg; + strcpy(dCfg.dir, pDnode->opt.dataDir); + dCfg.level = 0; + dCfg.primary = 1; + if (tfsInit(&dCfg, 1) != 0) { + dError("failed to init tfs env"); + dndCleanup(pDnode); + return NULL; + } + if (vnodeInit(pDnode->opt.numOfCommitThreads) != 0) { dError("failed to init vnode env"); dndCleanup(pDnode); return NULL; } - if (dndInitDnode(pDnode) != 0) { + if (dndInitMgmt(pDnode) != 0) { dError("failed to init dnode"); dndCleanup(pDnode); return NULL; @@ -200,6 +214,24 @@ SDnode *dndInit(SDnodeOpt *pOption) { return NULL; } + if (dndInitQnode(pDnode) != 0) { + dError("failed to init qnode"); + dndCleanup(pDnode); + return NULL; + } + + if (dndInitSnode(pDnode) != 0) { + dError("failed to init snode"); + dndCleanup(pDnode); + return NULL; + } + + if (dndInitBnode(pDnode) != 0) { + dError("failed to init bnode"); + dndCleanup(pDnode); + return NULL; + } + if (dndInitMnode(pDnode) != 0) { dError("failed to init mnode"); dndCleanup(pDnode); @@ -213,7 +245,7 @@ SDnode *dndInit(SDnodeOpt *pOption) { } dndSetStat(pDnode, DND_STAT_RUNNING); - dndSendStatusMsg(pDnode); + dndSendStatusReq(pDnode); dndReportStartup(pDnode, "TDengine", "initialized successfully"); dInfo("TDengine is initialized successfully, pDnode:%p", pDnode); @@ -231,10 +263,15 @@ void dndCleanup(SDnode *pDnode) { dInfo("start to cleanup TDengine"); dndSetStat(pDnode, DND_STAT_STOPPED); dndCleanupTrans(pDnode); + dndStopMgmt(pDnode); dndCleanupMnode(pDnode); + dndCleanupBnode(pDnode); + dndCleanupSnode(pDnode); + dndCleanupQnode(pDnode); dndCleanupVnodes(pDnode); - dndCleanupDnode(pDnode); + dndCleanupMgmt(pDnode); vnodeClear(); + tfsDestroy(); walCleanUp(); rpcCleanup(); diff --git a/source/dnode/mgmt/impl/test/CMakeLists.txt b/source/dnode/mgmt/impl/test/CMakeLists.txt index b36cdbd690..ce93a14d3f 100644 --- a/source/dnode/mgmt/impl/test/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/CMakeLists.txt @@ -1,21 +1,8 @@ enable_testing() -# add_subdirectory(auth) -# add_subdirectory(balance) -add_subdirectory(cluster) -add_subdirectory(db) -add_subdirectory(dnode) -# add_subdirectory(func) -add_subdirectory(mnode) add_subdirectory(qnode) -add_subdirectory(snode) add_subdirectory(bnode) -add_subdirectory(profile) -add_subdirectory(show) -add_subdirectory(stb) -# add_subdirectory(sync) -# add_subdirectory(telem) -# add_subdirectory(trans) -add_subdirectory(vgroup) - +add_subdirectory(snode) +add_subdirectory(mnode) +add_subdirectory(vnode) add_subdirectory(sut) diff --git a/source/dnode/mgmt/impl/test/bnode/CMakeLists.txt b/source/dnode/mgmt/impl/test/bnode/CMakeLists.txt index ea769a701c..22edc9b257 100644 --- a/source/dnode/mgmt/impl/test/bnode/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/bnode/CMakeLists.txt @@ -1,5 +1,5 @@ -aux_source_directory(. STEST_SRC) -add_executable(dnode_test_bnode ${STEST_SRC}) +aux_source_directory(. BQTEST_SRC) +add_executable(dnode_test_bnode ${BQTEST_SRC}) target_link_libraries( dnode_test_bnode PUBLIC sut diff --git a/source/dnode/mgmt/impl/test/bnode/bnode.cpp b/source/dnode/mgmt/impl/test/bnode/bnode.cpp deleted file mode 100644 index b1a85522c4..0000000000 --- a/source/dnode/mgmt/impl/test/bnode/bnode.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file dnode.cpp - * @author slguan (slguan@taosdata.com) - * @brief DNODE module dnode-msg tests - * @version 0.1 - * @date 2021-12-15 - * - * @copyright Copyright (c) 2021 - * - */ - -#include "base.h" - -class DndTestBnode : public ::testing::Test { - public: - void SetUp() override {} - void TearDown() override {} - - public: - static void SetUpTestSuite() { - test.Init("/tmp/dnode_test_bnode1", 9068); - const char* fqdn = "localhost"; - const char* firstEp = "localhost:9068"; - - server2.Start("/tmp/dnode_test_bnode2", fqdn, 9069, firstEp); - taosMsleep(300); - } - - static void TearDownTestSuite() { - server2.Stop(); - test.Cleanup(); - } - - static Testbase test; - static TestServer server2; -}; - -Testbase DndTestBnode::test; -TestServer DndTestBnode::server2; - -TEST_F(DndTestBnode, 01_ShowBnode) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_BNODE, ""); - CHECK_META("show bnodes", 3); - - CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 0); -} - -TEST_F(DndTestBnode, 02_Create_Bnode_Invalid_Id) { - { - int32_t contLen = sizeof(SMCreateBnodeMsg); - - SMCreateBnodeMsg* pReq = (SMCreateBnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(1); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_BNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_BNODE, ""); - CHECK_META("show bnodes", 3); - - CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9068", TSDB_EP_LEN); - CheckTimestamp(); - } -} - -TEST_F(DndTestBnode, 03_Create_Bnode_Invalid_Id) { - { - int32_t contLen = sizeof(SMCreateBnodeMsg); - - SMCreateBnodeMsg* pReq = (SMCreateBnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_BNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_DNODE_NOT_EXIST); - } -} - -TEST_F(DndTestBnode, 04_Create_Bnode) { - { - // create dnode - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->fqdn, "localhost"); - pReq->port = htonl(9069); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - taosMsleep(1300); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - } - - { - // create bnode - int32_t contLen = sizeof(SMCreateBnodeMsg); - - SMCreateBnodeMsg* pReq = (SMCreateBnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_BNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_BNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - - CheckInt16(1); - CheckInt16(2); - CheckBinary("localhost:9068", TSDB_EP_LEN); - CheckBinary("localhost:9069", TSDB_EP_LEN); - CheckTimestamp(); - CheckTimestamp(); - } - - { - // drop bnode - int32_t contLen = sizeof(SMDropBnodeMsg); - - SMDropBnodeMsg* pReq = (SMDropBnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_BNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_BNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9068", TSDB_EP_LEN); - CheckTimestamp(); - } -} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/bnode/dbnode.cpp b/source/dnode/mgmt/impl/test/bnode/dbnode.cpp new file mode 100644 index 0000000000..398d530648 --- /dev/null +++ b/source/dnode/mgmt/impl/test/bnode/dbnode.cpp @@ -0,0 +1,133 @@ +/** + * @file dbnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief DNODE module bnode tests + * @version 1.0 + * @date 2022-01-05 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class DndTestBnode : public ::testing::Test { + protected: + static void SetUpTestSuite() { test.Init("/tmp/dnode_test_snode", 9112); } + static void TearDownTestSuite() { test.Cleanup(); } + + static Testbase test; + + public: + void SetUp() override {} + void TearDown() override {} +}; + +Testbase DndTestBnode::test; + +TEST_F(DndTestBnode, 01_Create_Bnode) { + { + int32_t contLen = sizeof(SDCreateBnodeReq); + + SDCreateBnodeReq* pReq = (SDCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_BNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDCreateBnodeReq); + + SDCreateBnodeReq* pReq = (SDCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDCreateBnodeReq); + + SDCreateBnodeReq* pReq = (SDCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_BNODE_ALREADY_DEPLOYED); + } + + test.Restart(); + + { + int32_t contLen = sizeof(SDCreateBnodeReq); + + SDCreateBnodeReq* pReq = (SDCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_BNODE_ALREADY_DEPLOYED); + } +} + +TEST_F(DndTestBnode, 01_Drop_Bnode) { + { + int32_t contLen = sizeof(SDDropBnodeReq); + + SDDropBnodeReq* pReq = (SDDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_BNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDDropBnodeReq); + + SDDropBnodeReq* pReq = (SDDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDDropBnodeReq); + + SDDropBnodeReq* pReq = (SDDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_BNODE_NOT_DEPLOYED); + } + + test.Restart(); + + { + int32_t contLen = sizeof(SDDropBnodeReq); + + SDDropBnodeReq* pReq = (SDDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_BNODE_NOT_DEPLOYED); + } + + { + int32_t contLen = sizeof(SDCreateBnodeReq); + + SDCreateBnodeReq* pReq = (SDCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } +} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/cluster/CMakeLists.txt b/source/dnode/mgmt/impl/test/cluster/CMakeLists.txt deleted file mode 100644 index a63f3106e6..0000000000 --- a/source/dnode/mgmt/impl/test/cluster/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -aux_source_directory(. CLUSTER_SRC) -add_executable(dnode_test_cluster ${CLUSTER_SRC}) -target_link_libraries( - dnode_test_cluster - PUBLIC sut -) - -add_test( - NAME dnode_test_cluster - COMMAND dnode_test_cluster -) diff --git a/source/dnode/mgmt/impl/test/cluster/cluster.cpp b/source/dnode/mgmt/impl/test/cluster/cluster.cpp deleted file mode 100644 index 7734826789..0000000000 --- a/source/dnode/mgmt/impl/test/cluster/cluster.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file cluster.cpp - * @author slguan (slguan@taosdata.com) - * @brief DNODE module cluster-msg tests - * @version 0.1 - * @date 2021-12-15 - * - * @copyright Copyright (c) 2021 - * - */ - -#include "base.h" - -class DndTestCluster : public ::testing::Test { - protected: - static void SetUpTestSuite() { test.Init("/tmp/dnode_test_cluster", 9030); } - static void TearDownTestSuite() { test.Cleanup(); } - - static Testbase test; - - public: - void SetUp() override {} - void TearDown() override {} -}; - -Testbase DndTestCluster::test; - -TEST_F(DndTestCluster, 01_ShowCluster) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_CLUSTER, ""); - CHECK_META( "show cluster", 3); - CHECK_SCHEMA(0, TSDB_DATA_TYPE_BIGINT, 8, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_CLUSTER_ID_LEN + VARSTR_HEADER_SIZE, "name"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - IgnoreInt64(); - IgnoreBinary(TSDB_CLUSTER_ID_LEN); - CheckTimestamp(); -} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/db/CMakeLists.txt b/source/dnode/mgmt/impl/test/db/CMakeLists.txt deleted file mode 100644 index cb9f1600fc..0000000000 --- a/source/dnode/mgmt/impl/test/db/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -aux_source_directory(. DB_SRC) -add_executable(dnode_test_db ${DB_SRC}) -target_link_libraries( - dnode_test_db - PUBLIC sut -) - -add_test( - NAME dnode_test_db - COMMAND dnode_test_db -) diff --git a/source/dnode/mgmt/impl/test/dnode/CMakeLists.txt b/source/dnode/mgmt/impl/test/dnode/CMakeLists.txt deleted file mode 100644 index 5796590865..0000000000 --- a/source/dnode/mgmt/impl/test/dnode/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -aux_source_directory(. DTEST_SRC) -add_executable(dnode_test_dnode ${DTEST_SRC}) -target_link_libraries( - dnode_test_dnode - PUBLIC sut -) - -add_test( - NAME dnode_test_dnode - COMMAND dnode_test_dnode -) diff --git a/source/dnode/mgmt/impl/test/dnode/dnode.cpp b/source/dnode/mgmt/impl/test/dnode/dnode.cpp deleted file mode 100644 index 54d7e73be6..0000000000 --- a/source/dnode/mgmt/impl/test/dnode/dnode.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/** - * @file dnode.cpp - * @author slguan (slguan@taosdata.com) - * @brief DNODE module dnode-msg tests - * @version 0.1 - * @date 2021-12-15 - * - * @copyright Copyright (c) 2021 - * - */ - -#include "base.h" - -class DndTestDnode : public ::testing::Test { - public: - void SetUp() override {} - void TearDown() override {} - - public: - static void SetUpTestSuite() { - test.Init("/tmp/dnode_test_dnode1", 9041); - const char* fqdn = "localhost"; - const char* firstEp = "localhost:9041"; - - server2.Start("/tmp/dnode_test_dnode2", fqdn, 9042, firstEp); - server3.Start("/tmp/dnode_test_dnode3", fqdn, 9043, firstEp); - server4.Start("/tmp/dnode_test_dnode4", fqdn, 9044, firstEp); - server5.Start("/tmp/dnode_test_dnode5", fqdn, 9045, firstEp); - taosMsleep(300); - } - - static void TearDownTestSuite() { - server2.Stop(); - server3.Stop(); - server4.Stop(); - server5.Stop(); - test.Cleanup(); - } - - static Testbase test; - static TestServer server2; - static TestServer server3; - static TestServer server4; - static TestServer server5; -}; - -Testbase DndTestDnode::test; -TestServer DndTestDnode::server2; -TestServer DndTestDnode::server3; -TestServer DndTestDnode::server4; -TestServer DndTestDnode::server5; - -TEST_F(DndTestDnode, 01_ShowDnode) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - - CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_SMALLINT, 2, "vnodes"); - CHECK_SCHEMA(3, TSDB_DATA_TYPE_SMALLINT, 2, "support_vnodes"); - CHECK_SCHEMA(4, TSDB_DATA_TYPE_BINARY, 10 + VARSTR_HEADER_SIZE, "status"); - CHECK_SCHEMA(5, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - CHECK_SCHEMA(6, TSDB_DATA_TYPE_BINARY, 24 + VARSTR_HEADER_SIZE, "offline_reason"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9041", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(16); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckBinary("", 24); -} - -TEST_F(DndTestDnode, 02_ConfigDnode) { - int32_t contLen = sizeof(SCfgDnodeMsg); - - SCfgDnodeMsg* pReq = (SCfgDnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(1); - strcpy(pReq->config, "ddebugflag 131"); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CONFIG_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); -} - -TEST_F(DndTestDnode, 03_Create_Drop_Restart_Dnode) { - { - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->fqdn, "localhost"); - pReq->port = htonl(9042); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } - - taosMsleep(1300); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - - CheckInt16(1); - CheckInt16(2); - CheckBinary("localhost:9041", TSDB_EP_LEN); - CheckBinary("localhost:9042", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(0); - CheckInt16(16); - CheckInt16(16); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckTimestamp(); - CheckBinary("", 24); - CheckBinary("", 24); - - { - int32_t contLen = sizeof(SDropDnodeMsg); - - SDropDnodeMsg* pReq = (SDropDnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9041", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(16); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckBinary("", 24); - - { - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->fqdn, "localhost"); - pReq->port = htonl(9043); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } - - { - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->fqdn, "localhost"); - pReq->port = htonl(9044); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } - - { - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->fqdn, "localhost"); - pReq->port = htonl(9045); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } - - taosMsleep(1300); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 4); - - CheckInt16(1); - CheckInt16(3); - CheckInt16(4); - CheckInt16(5); - CheckBinary("localhost:9041", TSDB_EP_LEN); - CheckBinary("localhost:9043", TSDB_EP_LEN); - CheckBinary("localhost:9044", TSDB_EP_LEN); - CheckBinary("localhost:9045", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(0); - CheckInt16(0); - CheckInt16(0); - CheckInt16(16); - CheckInt16(16); - CheckInt16(16); - CheckInt16(16); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckTimestamp(); - CheckTimestamp(); - CheckTimestamp(); - CheckBinary("", 24); - CheckBinary("", 24); - CheckBinary("", 24); - CheckBinary("", 24); - - // restart - uInfo("stop all server"); - test.Restart(); - server2.Restart(); - server3.Restart(); - server4.Restart(); - server5.Restart(); - - taosMsleep(1300); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 4); - - CheckInt16(1); - CheckInt16(3); - CheckInt16(4); - CheckInt16(5); - CheckBinary("localhost:9041", TSDB_EP_LEN); - CheckBinary("localhost:9043", TSDB_EP_LEN); - CheckBinary("localhost:9044", TSDB_EP_LEN); - CheckBinary("localhost:9045", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(0); - CheckInt16(0); - CheckInt16(0); - CheckInt16(16); - CheckInt16(16); - CheckInt16(16); - CheckInt16(16); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckTimestamp(); - CheckTimestamp(); - CheckTimestamp(); - CheckBinary("", 24); - CheckBinary("", 24); - CheckBinary("", 24); - CheckBinary("", 24); -} diff --git a/source/dnode/mgmt/impl/test/mnode/CMakeLists.txt b/source/dnode/mgmt/impl/test/mnode/CMakeLists.txt index d6b3b16fb6..be29b93b02 100644 --- a/source/dnode/mgmt/impl/test/mnode/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/mnode/CMakeLists.txt @@ -1,5 +1,5 @@ -aux_source_directory(. MTEST_SRC) -add_executable(dnode_test_mnode ${MTEST_SRC}) +aux_source_directory(. DMTEST_SRC) +add_executable(dnode_test_mnode ${DMTEST_SRC}) target_link_libraries( dnode_test_mnode PUBLIC sut diff --git a/source/dnode/mgmt/impl/test/mnode/dmnode.cpp b/source/dnode/mgmt/impl/test/mnode/dmnode.cpp new file mode 100644 index 0000000000..edaecef49e --- /dev/null +++ b/source/dnode/mgmt/impl/test/mnode/dmnode.cpp @@ -0,0 +1,189 @@ +/** + * @file dmnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief DNODE module mnode tests + * @version 1.0 + * @date 2022-01-07 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class DndTestMnode : public ::testing::Test { + protected: + static void SetUpTestSuite() { test.Init("/tmp/dnode_test_mnode", 9114); } + static void TearDownTestSuite() { test.Cleanup(); } + + static Testbase test; + + public: + void SetUp() override {} + void TearDown() override {} +}; + +Testbase DndTestMnode::test; + +TEST_F(DndTestMnode, 01_Create_Mnode) { + { + int32_t contLen = sizeof(SDCreateMnodeReq); + + SDCreateMnodeReq* pReq = (SDCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + pReq->replica = 1; + pReq->replicas[0].id = htonl(1); + pReq->replicas[0].port = htonl(9113); + strcpy(pReq->replicas[0].fqdn, "localhost"); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_MNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDCreateMnodeReq); + + SDCreateMnodeReq* pReq = (SDCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + pReq->replica = 1; + pReq->replicas[0].id = htonl(2); + pReq->replicas[0].port = htonl(9113); + strcpy(pReq->replicas[0].fqdn, "localhost"); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_MNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDCreateMnodeReq); + + SDCreateMnodeReq* pReq = (SDCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + pReq->replica = 2; + pReq->replicas[0].id = htonl(1); + pReq->replicas[0].port = htonl(9113); + strcpy(pReq->replicas[0].fqdn, "localhost"); + pReq->replicas[1].id = htonl(1); + pReq->replicas[1].port = htonl(9114); + strcpy(pReq->replicas[1].fqdn, "localhost"); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED); + } +} + +TEST_F(DndTestMnode, 02_Alter_Mnode) { + { + int32_t contLen = sizeof(SDAlterMnodeReq); + + SDAlterMnodeReq* pReq = (SDAlterMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + pReq->replica = 1; + pReq->replicas[0].id = htonl(1); + pReq->replicas[0].port = htonl(9113); + strcpy(pReq->replicas[0].fqdn, "localhost"); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_ALTER_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_MNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDAlterMnodeReq); + + SDAlterMnodeReq* pReq = (SDAlterMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + pReq->replica = 1; + pReq->replicas[0].id = htonl(2); + pReq->replicas[0].port = htonl(9113); + strcpy(pReq->replicas[0].fqdn, "localhost"); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_ALTER_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_MNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDAlterMnodeReq); + + SDAlterMnodeReq* pReq = (SDAlterMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + pReq->replica = 1; + pReq->replicas[0].id = htonl(1); + pReq->replicas[0].port = htonl(9113); + strcpy(pReq->replicas[0].fqdn, "localhost"); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_ALTER_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } +} + +TEST_F(DndTestMnode, 03_Drop_Mnode) { + { + int32_t contLen = sizeof(SDDropMnodeReq); + + SDDropMnodeReq* pReq = (SDDropMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_MNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDDropMnodeReq); + + SDDropMnodeReq* pReq = (SDDropMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDDropMnodeReq); + + SDDropMnodeReq* pReq = (SDDropMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_MNODE_NOT_DEPLOYED); + } + + { + int32_t contLen = sizeof(SDAlterMnodeReq); + + SDAlterMnodeReq* pReq = (SDAlterMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + pReq->replica = 1; + pReq->replicas[0].id = htonl(1); + pReq->replicas[0].port = htonl(9113); + strcpy(pReq->replicas[0].fqdn, "localhost"); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_ALTER_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_MNODE_NOT_DEPLOYED); + } + + + { + int32_t contLen = sizeof(SDCreateMnodeReq); + + SDCreateMnodeReq* pReq = (SDCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + pReq->replica = 2; + pReq->replicas[0].id = htonl(1); + pReq->replicas[0].port = htonl(9113); + strcpy(pReq->replicas[0].fqdn, "localhost"); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } +} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/mnode/mnode.cpp b/source/dnode/mgmt/impl/test/mnode/mnode.cpp deleted file mode 100644 index e9b1ef45bd..0000000000 --- a/source/dnode/mgmt/impl/test/mnode/mnode.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/** - * @file dnode.cpp - * @author slguan (slguan@taosdata.com) - * @brief DNODE module dnode-msg tests - * @version 0.1 - * @date 2021-12-15 - * - * @copyright Copyright (c) 2021 - * - */ - -#include "base.h" - -class DndTestMnode : public ::testing::Test { - public: - void SetUp() override {} - void TearDown() override {} - - public: - static void SetUpTestSuite() { - test.Init("/tmp/dnode_test_mnode1", 9061); - const char* fqdn = "localhost"; - const char* firstEp = "localhost:9061"; - - server2.Start("/tmp/dnode_test_mnode2", fqdn, 9062, firstEp); - server3.Start("/tmp/dnode_test_mnode3", fqdn, 9063, firstEp); - server4.Start("/tmp/dnode_test_mnode4", fqdn, 9064, firstEp); - server5.Start("/tmp/dnode_test_mnode5", fqdn, 9065, firstEp); - taosMsleep(300); - } - - static void TearDownTestSuite() { - server2.Stop(); - server3.Stop(); - server4.Stop(); - server5.Stop(); - test.Cleanup(); - } - - static Testbase test; - static TestServer server2; - static TestServer server3; - static TestServer server4; - static TestServer server5; -}; - -Testbase DndTestMnode::test; -TestServer DndTestMnode::server2; -TestServer DndTestMnode::server3; -TestServer DndTestMnode::server4; -TestServer DndTestMnode::server5; - -TEST_F(DndTestMnode, 01_ShowDnode) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_MNODE, ""); - CHECK_META("show mnodes", 5); - - CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_BINARY, 12 + VARSTR_HEADER_SIZE, "role"); - CHECK_SCHEMA(3, TSDB_DATA_TYPE_TIMESTAMP, 8, "role_time"); - CHECK_SCHEMA(4, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9061", TSDB_EP_LEN); - CheckBinary("master", 12); - CheckInt64(0); - CheckTimestamp(); -} - -TEST_F(DndTestMnode, 02_Create_Mnode_Invalid_Id) { - { - int32_t contLen = sizeof(SMCreateMnodeMsg); - - SMCreateMnodeMsg* pReq = (SMCreateMnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(1); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_MNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_MNODE_ALREADY_EXIST); - } -} - -TEST_F(DndTestMnode, 03_Create_Mnode_Invalid_Id) { - { - int32_t contLen = sizeof(SMCreateMnodeMsg); - - SMCreateMnodeMsg* pReq = (SMCreateMnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_MNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_DNODE_NOT_EXIST); - } -} - -TEST_F(DndTestMnode, 04_Create_Mnode) { - { - // create dnode - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->fqdn, "localhost"); - pReq->port = htonl(9062); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - taosMsleep(1300); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - } - - { - // create mnode - int32_t contLen = sizeof(SMCreateMnodeMsg); - - SMCreateMnodeMsg* pReq = (SMCreateMnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_MNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_MNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - - CheckInt16(1); - CheckInt16(2); - CheckBinary("localhost:9061", TSDB_EP_LEN); - CheckBinary("localhost:9062", TSDB_EP_LEN); - CheckBinary("master", 12); - CheckBinary("slave", 12); - CheckInt64(0); - CheckInt64(0); - CheckTimestamp(); - CheckTimestamp(); - } - - { - // drop mnode - int32_t contLen = sizeof(SMDropMnodeMsg); - - SMDropMnodeMsg* pReq = (SMDropMnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_MNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_MNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9061", TSDB_EP_LEN); - CheckBinary("master", 12); - CheckInt64(0); - CheckTimestamp(); - } -} -// { -// int32_t contLen = sizeof(SDropDnodeMsg); - -// SDropDnodeMsg* pReq = (SDropDnodeMsg*)rpcMallocCont(contLen); -// pReq->dnodeId = htonl(2); - -// SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_DNODE, pReq, contLen); -// ASSERT_NE(pMsg, nullptr); -// ASSERT_EQ(pMsg->code, 0); -// } - -// test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); -// CHECK_META("show dnodes", 7); -// test.SendShowRetrieveMsg(); -// EXPECT_EQ(test.GetShowRows(), 1); - -// CheckInt16(1); -// CheckBinary("localhost:9061", TSDB_EP_LEN); -// CheckInt16(0); -// CheckInt16(1); -// CheckBinary("ready", 10); -// CheckTimestamp(); -// CheckBinary("", 24); - -// { -// int32_t contLen = sizeof(SCreateDnodeMsg); - -// SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); -// strcpy(pReq->ep, "localhost:9063"); - -// SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); -// ASSERT_NE(pMsg, nullptr); -// ASSERT_EQ(pMsg->code, 0); -// } - -// { -// int32_t contLen = sizeof(SCreateDnodeMsg); - -// SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); -// strcpy(pReq->ep, "localhost:9064"); - -// SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); -// ASSERT_NE(pMsg, nullptr); -// ASSERT_EQ(pMsg->code, 0); -// } - -// { -// int32_t contLen = sizeof(SCreateDnodeMsg); - -// SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); -// strcpy(pReq->ep, "localhost:9065"); - -// SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); -// ASSERT_NE(pMsg, nullptr); -// ASSERT_EQ(pMsg->code, 0); -// } - -// taosMsleep(1300); -// test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); -// CHECK_META("show dnodes", 7); -// test.SendShowRetrieveMsg(); -// EXPECT_EQ(test.GetShowRows(), 4); - -// CheckInt16(1); -// CheckInt16(3); -// CheckInt16(4); -// CheckInt16(5); -// CheckBinary("localhost:9061", TSDB_EP_LEN); -// CheckBinary("localhost:9063", TSDB_EP_LEN); -// CheckBinary("localhost:9064", TSDB_EP_LEN); -// CheckBinary("localhost:9065", TSDB_EP_LEN); -// CheckInt16(0); -// CheckInt16(0); -// CheckInt16(0); -// CheckInt16(0); -// CheckInt16(1); -// CheckInt16(1); -// CheckInt16(1); -// CheckInt16(1); -// CheckBinary("ready", 10); -// CheckBinary("ready", 10); -// CheckBinary("ready", 10); -// CheckBinary("ready", 10); -// CheckTimestamp(); -// CheckTimestamp(); -// CheckTimestamp(); -// CheckTimestamp(); -// CheckBinary("", 24); -// CheckBinary("", 24); -// CheckBinary("", 24); -// CheckBinary("", 24); - -// // restart -// uInfo("stop all server"); -// test.Restart(); -// server2.Restart(); -// server3.Restart(); -// server4.Restart(); -// server5.Restart(); - -// taosMsleep(1300); -// test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); -// CHECK_META("show dnodes", 7); -// test.SendShowRetrieveMsg(); -// EXPECT_EQ(test.GetShowRows(), 4); - -// CheckInt16(1); -// CheckInt16(3); -// CheckInt16(4); -// CheckInt16(5); -// CheckBinary("localhost:9061", TSDB_EP_LEN); -// CheckBinary("localhost:9063", TSDB_EP_LEN); -// CheckBinary("localhost:9064", TSDB_EP_LEN); -// CheckBinary("localhost:9065", TSDB_EP_LEN); -// CheckInt16(0); -// CheckInt16(0); -// CheckInt16(0); -// CheckInt16(0); -// CheckInt16(1); -// CheckInt16(1); -// CheckInt16(1); -// CheckInt16(1); -// CheckBinary("ready", 10); -// CheckBinary("ready", 10); -// CheckBinary("ready", 10); -// CheckBinary("ready", 10); -// CheckTimestamp(); -// CheckTimestamp(); -// CheckTimestamp(); -// CheckTimestamp(); -// CheckBinary("", 24); -// CheckBinary("", 24); -// CheckBinary("", 24); -// CheckBinary("", 24); -// } diff --git a/source/dnode/mgmt/impl/test/profile/CMakeLists.txt b/source/dnode/mgmt/impl/test/profile/CMakeLists.txt deleted file mode 100644 index 0edd631720..0000000000 --- a/source/dnode/mgmt/impl/test/profile/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -aux_source_directory(. PROFILE_SRC) -add_executable(dnode_test_profile ${PROFILE_SRC}) -target_link_libraries( - dnode_test_profile - PUBLIC sut -) - -add_test( - NAME dnode_test_profile - COMMAND dnode_test_profile -) diff --git a/source/dnode/mgmt/impl/test/qnode/CMakeLists.txt b/source/dnode/mgmt/impl/test/qnode/CMakeLists.txt index 2edb6de8b8..2536001231 100644 --- a/source/dnode/mgmt/impl/test/qnode/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/qnode/CMakeLists.txt @@ -1,5 +1,5 @@ -aux_source_directory(. QTEST_SRC) -add_executable(dnode_test_qnode ${QTEST_SRC}) +aux_source_directory(. DQTEST_SRC) +add_executable(dnode_test_qnode ${DQTEST_SRC}) target_link_libraries( dnode_test_qnode PUBLIC sut diff --git a/source/dnode/mgmt/impl/test/qnode/dqnode.cpp b/source/dnode/mgmt/impl/test/qnode/dqnode.cpp new file mode 100644 index 0000000000..19fd6b4b12 --- /dev/null +++ b/source/dnode/mgmt/impl/test/qnode/dqnode.cpp @@ -0,0 +1,133 @@ +/** + * @file dqnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief DNODE module qnode tests + * @version 1.0 + * @date 2022-01-05 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class DndTestQnode : public ::testing::Test { + protected: + static void SetUpTestSuite() { test.Init("/tmp/dnode_test_qnode", 9111); } + static void TearDownTestSuite() { test.Cleanup(); } + + static Testbase test; + + public: + void SetUp() override {} + void TearDown() override {} +}; + +Testbase DndTestQnode::test; + +TEST_F(DndTestQnode, 01_Create_Qnode) { + { + int32_t contLen = sizeof(SDCreateQnodeReq); + + SDCreateQnodeReq* pReq = (SDCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_QNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDCreateQnodeReq); + + SDCreateQnodeReq* pReq = (SDCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDCreateQnodeReq); + + SDCreateQnodeReq* pReq = (SDCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_QNODE_ALREADY_DEPLOYED); + } + + test.Restart(); + + { + int32_t contLen = sizeof(SDCreateQnodeReq); + + SDCreateQnodeReq* pReq = (SDCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_QNODE_ALREADY_DEPLOYED); + } +} + +TEST_F(DndTestQnode, 02_Drop_Qnode) { + { + int32_t contLen = sizeof(SDDropQnodeReq); + + SDDropQnodeReq* pReq = (SDDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_QNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDDropQnodeReq); + + SDDropQnodeReq* pReq = (SDDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDDropQnodeReq); + + SDDropQnodeReq* pReq = (SDDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_QNODE_NOT_DEPLOYED); + } + + test.Restart(); + + { + int32_t contLen = sizeof(SDDropQnodeReq); + + SDDropQnodeReq* pReq = (SDDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_QNODE_NOT_DEPLOYED); + } + + { + int32_t contLen = sizeof(SDCreateQnodeReq); + + SDCreateQnodeReq* pReq = (SDCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } +} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/qnode/qnode.cpp b/source/dnode/mgmt/impl/test/qnode/qnode.cpp deleted file mode 100644 index 40464de816..0000000000 --- a/source/dnode/mgmt/impl/test/qnode/qnode.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file dnode.cpp - * @author slguan (slguan@taosdata.com) - * @brief DNODE module dnode-msg tests - * @version 0.1 - * @date 2021-12-15 - * - * @copyright Copyright (c) 2021 - * - */ - -#include "base.h" - -class DndTestQnode : public ::testing::Test { - public: - void SetUp() override {} - void TearDown() override {} - - public: - static void SetUpTestSuite() { - test.Init("/tmp/dnode_test_qnode1", 9064); - const char* fqdn = "localhost"; - const char* firstEp = "localhost:9064"; - - server2.Start("/tmp/dnode_test_qnode2", fqdn, 9065, firstEp); - taosMsleep(300); - } - - static void TearDownTestSuite() { - server2.Stop(); - test.Cleanup(); - } - - static Testbase test; - static TestServer server2; -}; - -Testbase DndTestQnode::test; -TestServer DndTestQnode::server2; - -TEST_F(DndTestQnode, 01_ShowQnode) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_QNODE, ""); - CHECK_META("show qnodes", 3); - - CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 0); -} - -TEST_F(DndTestQnode, 02_Create_Qnode_Invalid_Id) { - { - int32_t contLen = sizeof(SMCreateQnodeMsg); - - SMCreateQnodeMsg* pReq = (SMCreateQnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(1); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_QNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_QNODE, ""); - CHECK_META("show qnodes", 3); - - CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9064", TSDB_EP_LEN); - CheckTimestamp(); - } -} - -TEST_F(DndTestQnode, 03_Create_Qnode_Invalid_Id) { - { - int32_t contLen = sizeof(SMCreateQnodeMsg); - - SMCreateQnodeMsg* pReq = (SMCreateQnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_QNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_DNODE_NOT_EXIST); - } -} - -TEST_F(DndTestQnode, 04_Create_Qnode) { - { - // create dnode - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->fqdn, "localhost"); - pReq->port = htonl(9065); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - taosMsleep(1300); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - } - - { - // create qnode - int32_t contLen = sizeof(SMCreateQnodeMsg); - - SMCreateQnodeMsg* pReq = (SMCreateQnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_QNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_QNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - - CheckInt16(1); - CheckInt16(2); - CheckBinary("localhost:9064", TSDB_EP_LEN); - CheckBinary("localhost:9065", TSDB_EP_LEN); - CheckTimestamp(); - CheckTimestamp(); - } - - { - // drop qnode - int32_t contLen = sizeof(SMDropQnodeMsg); - - SMDropQnodeMsg* pReq = (SMDropQnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_QNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_QNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9064", TSDB_EP_LEN); - CheckTimestamp(); - } -} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/show/CMakeLists.txt b/source/dnode/mgmt/impl/test/show/CMakeLists.txt deleted file mode 100644 index 9786f65605..0000000000 --- a/source/dnode/mgmt/impl/test/show/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -aux_source_directory(. SHOW_SRC) -add_executable(dnode_test_show ${SHOW_SRC}) -target_link_libraries( - dnode_test_show - PUBLIC sut -) - -add_test( - NAME dnode_test_show - COMMAND dnode_test_show -) diff --git a/source/dnode/mgmt/impl/test/show/show.cpp b/source/dnode/mgmt/impl/test/show/show.cpp deleted file mode 100644 index a0df0f2921..0000000000 --- a/source/dnode/mgmt/impl/test/show/show.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file show.cpp - * @author slguan (slguan@taosdata.com) - * @brief DNODE module show-msg tests - * @version 0.1 - * @date 2021-12-15 - * - * @copyright Copyright (c) 2021 - * - */ - -#include "base.h" - -class DndTestShow : public ::testing::Test { - protected: - static void SetUpTestSuite() { test.Init("/tmp/dnode_test_show", 9091); } - static void TearDownTestSuite() { test.Cleanup(); } - - static Testbase test; - - public: - void SetUp() override {} - void TearDown() override {} -}; - -Testbase DndTestShow::test; - -TEST_F(DndTestShow, 01_ShowMsg_InvalidMsgMax) { - int32_t contLen = sizeof(SShowMsg); - - SShowMsg* pReq = (SShowMsg*)rpcMallocCont(contLen); - pReq->type = TSDB_MGMT_TABLE_MAX; - strcpy(pReq->db, ""); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_SHOW, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_MSG_TYPE); -} - -TEST_F(DndTestShow, 02_ShowMsg_InvalidMsgStart) { - int32_t contLen = sizeof(SShowMsg); - - SShowMsg* pReq = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg)); - pReq->type = TSDB_MGMT_TABLE_START; - strcpy(pReq->db, ""); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_SHOW, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_MSG_TYPE); -} - -TEST_F(DndTestShow, 02_ShowMsg_Conn) { - int32_t contLen = sizeof(SConnectMsg); - - SConnectMsg* pReq = (SConnectMsg*)rpcMallocCont(contLen); - pReq->pid = htonl(1234); - strcpy(pReq->app, "dnode_test_show"); - strcpy(pReq->db, ""); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CONNECT, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_CONNS, ""); - - STableMetaMsg* pMeta = test.GetShowMeta(); - EXPECT_STREQ(pMeta->tbFname, "show connections"); - EXPECT_EQ(pMeta->numOfTags, 0); - EXPECT_EQ(pMeta->numOfColumns, 7); - EXPECT_EQ(pMeta->precision, 0); - EXPECT_EQ(pMeta->tableType, 0); - EXPECT_EQ(pMeta->update, 0); - EXPECT_EQ(pMeta->sversion, 0); - EXPECT_EQ(pMeta->tversion, 0); - EXPECT_EQ(pMeta->tuid, 0); - EXPECT_EQ(pMeta->suid, 0); - - test.SendShowRetrieveMsg(); - - SRetrieveTableRsp* pRetrieveRsp = test.GetRetrieveRsp(); - EXPECT_EQ(pRetrieveRsp->numOfRows, 1); - EXPECT_EQ(pRetrieveRsp->useconds, 0); - EXPECT_EQ(pRetrieveRsp->completed, 1); - EXPECT_EQ(pRetrieveRsp->precision, TSDB_TIME_PRECISION_MILLI); - EXPECT_EQ(pRetrieveRsp->compressed, 0); - EXPECT_EQ(pRetrieveRsp->compLen, 0); -} diff --git a/source/dnode/mgmt/impl/test/snode/CMakeLists.txt b/source/dnode/mgmt/impl/test/snode/CMakeLists.txt index 180b1ec163..9c163d1999 100644 --- a/source/dnode/mgmt/impl/test/snode/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/snode/CMakeLists.txt @@ -1,5 +1,5 @@ -aux_source_directory(. STEST_SRC) -add_executable(dnode_test_snode ${STEST_SRC}) +aux_source_directory(. SQTEST_SRC) +add_executable(dnode_test_snode ${SQTEST_SRC}) target_link_libraries( dnode_test_snode PUBLIC sut diff --git a/source/dnode/mgmt/impl/test/snode/dsnode.cpp b/source/dnode/mgmt/impl/test/snode/dsnode.cpp new file mode 100644 index 0000000000..019aa1cbbc --- /dev/null +++ b/source/dnode/mgmt/impl/test/snode/dsnode.cpp @@ -0,0 +1,133 @@ +/** + * @file dsnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief DNODE module snode tests + * @version 1.0 + * @date 2022-01-05 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class DndTestSnode : public ::testing::Test { + protected: + static void SetUpTestSuite() { test.Init("/tmp/dnode_test_snode", 9113); } + static void TearDownTestSuite() { test.Cleanup(); } + + static Testbase test; + + public: + void SetUp() override {} + void TearDown() override {} +}; + +Testbase DndTestSnode::test; + +TEST_F(DndTestSnode, 01_Create_Snode) { + { + int32_t contLen = sizeof(SDCreateSnodeReq); + + SDCreateSnodeReq* pReq = (SDCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_SNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDCreateSnodeReq); + + SDCreateSnodeReq* pReq = (SDCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDCreateSnodeReq); + + SDCreateSnodeReq* pReq = (SDCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_SNODE_ALREADY_DEPLOYED); + } + + test.Restart(); + + { + int32_t contLen = sizeof(SDCreateSnodeReq); + + SDCreateSnodeReq* pReq = (SDCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_SNODE_ALREADY_DEPLOYED); + } +} + +TEST_F(DndTestSnode, 01_Drop_Snode) { + { + int32_t contLen = sizeof(SDDropSnodeReq); + + SDDropSnodeReq* pReq = (SDDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_SNODE_INVALID_OPTION); + } + + { + int32_t contLen = sizeof(SDDropSnodeReq); + + SDDropSnodeReq* pReq = (SDDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDDropSnodeReq); + + SDDropSnodeReq* pReq = (SDDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_SNODE_NOT_DEPLOYED); + } + + test.Restart(); + + { + int32_t contLen = sizeof(SDDropSnodeReq); + + SDDropSnodeReq* pReq = (SDDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_SNODE_NOT_DEPLOYED); + } + + { + int32_t contLen = sizeof(SDCreateSnodeReq); + + SDCreateSnodeReq* pReq = (SDCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } +} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/snode/snode.cpp b/source/dnode/mgmt/impl/test/snode/snode.cpp deleted file mode 100644 index a14a575beb..0000000000 --- a/source/dnode/mgmt/impl/test/snode/snode.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file dnode.cpp - * @author slguan (slguan@taosdata.com) - * @brief DNODE module dnode-msg tests - * @version 0.1 - * @date 2021-12-15 - * - * @copyright Copyright (c) 2021 - * - */ - -#include "base.h" - -class DndTestSnode : public ::testing::Test { - public: - void SetUp() override {} - void TearDown() override {} - - public: - static void SetUpTestSuite() { - test.Init("/tmp/dnode_test_snode1", 9066); - const char* fqdn = "localhost"; - const char* firstEp = "localhost:9066"; - - server2.Start("/tmp/dnode_test_snode2", fqdn, 9067, firstEp); - taosMsleep(300); - } - - static void TearDownTestSuite() { - server2.Stop(); - test.Cleanup(); - } - - static Testbase test; - static TestServer server2; -}; - -Testbase DndTestSnode::test; -TestServer DndTestSnode::server2; - -TEST_F(DndTestSnode, 01_ShowSnode) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_SNODE, ""); - CHECK_META("show snodes", 3); - - CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 0); -} - -TEST_F(DndTestSnode, 02_Create_Snode_Invalid_Id) { - { - int32_t contLen = sizeof(SMCreateSnodeMsg); - - SMCreateSnodeMsg* pReq = (SMCreateSnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(1); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_SNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_SNODE, ""); - CHECK_META("show snodes", 3); - - CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); - CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9066", TSDB_EP_LEN); - CheckTimestamp(); - } -} - -TEST_F(DndTestSnode, 03_Create_Snode_Invalid_Id) { - { - int32_t contLen = sizeof(SMCreateSnodeMsg); - - SMCreateSnodeMsg* pReq = (SMCreateSnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_SNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_DNODE_NOT_EXIST); - } -} - -TEST_F(DndTestSnode, 04_Create_Snode) { - { - // create dnode - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->fqdn, "localhost"); - pReq->port = htonl(9067); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - taosMsleep(1300); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - } - - { - // create snode - int32_t contLen = sizeof(SMCreateSnodeMsg); - - SMCreateSnodeMsg* pReq = (SMCreateSnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_SNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_SNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - - CheckInt16(1); - CheckInt16(2); - CheckBinary("localhost:9066", TSDB_EP_LEN); - CheckBinary("localhost:9067", TSDB_EP_LEN); - CheckTimestamp(); - CheckTimestamp(); - } - - { - // drop snode - int32_t contLen = sizeof(SMDropSnodeMsg); - - SMDropSnodeMsg* pReq = (SMDropSnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(2); - - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_SNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_SNODE, ""); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9066", TSDB_EP_LEN); - CheckTimestamp(); - } -} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/sut/inc/client.h b/source/dnode/mgmt/impl/test/sut/inc/client.h index e1e430318e..9cf688fc02 100644 --- a/source/dnode/mgmt/impl/test/sut/inc/client.h +++ b/source/dnode/mgmt/impl/test/sut/inc/client.h @@ -21,7 +21,7 @@ class TestClient { bool Init(const char* user, const char* pass, const char* fqdn, uint16_t port); void Cleanup(); - SRpcMsg* SendMsg(SRpcMsg* pMsg); + SRpcMsg* SendReq(SRpcMsg* pReq); void SetRpcRsp(SRpcMsg* pRsp); tsem_t* GetSem(); diff --git a/source/dnode/mgmt/impl/test/sut/inc/base.h b/source/dnode/mgmt/impl/test/sut/inc/sut.h similarity index 93% rename from source/dnode/mgmt/impl/test/sut/inc/base.h rename to source/dnode/mgmt/impl/test/sut/inc/sut.h index 24278a73f7..9f724faeb9 100644 --- a/source/dnode/mgmt/impl/test/sut/inc/base.h +++ b/source/dnode/mgmt/impl/test/sut/inc/sut.h @@ -39,7 +39,7 @@ class Testbase { void Restart(); void ServerStop(); void ServerStart(); - SRpcMsg* SendMsg(tmsg_t msgType, void* pCont, int32_t contLen); + SRpcMsg* SendReq(tmsg_t msgType, void* pCont, int32_t contLen); private: void InitLog(const char* path); @@ -50,10 +50,10 @@ class Testbase { int32_t connId; public: - void SendShowMetaMsg(int8_t showType, const char* db); - void SendShowRetrieveMsg(); + void SendShowMetaReq(int8_t showType, const char* db); + void SendShowRetrieveReq(); - STableMetaMsg* GetShowMeta(); + STableMetaRsp* GetShowMeta(); SRetrieveTableRsp* GetRetrieveRsp(); int32_t GetMetaNum(); @@ -74,7 +74,7 @@ class Testbase { private: int64_t showId; - STableMetaMsg* pMeta; + STableMetaRsp* pMeta; SRetrieveTableRsp* pRetrieveRsp; char* pData; int32_t pos; diff --git a/source/dnode/mgmt/impl/test/sut/src/client.cpp b/source/dnode/mgmt/impl/test/sut/src/client.cpp index 13429cec28..fd5dcd77d9 100644 --- a/source/dnode/mgmt/impl/test/sut/src/client.cpp +++ b/source/dnode/mgmt/impl/test/sut/src/client.cpp @@ -13,12 +13,12 @@ * along with this program. If not, see . */ -#include "base.h" +#include "sut.h" -static void processClientRsp(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) { +static void processClientRsp(void* parent, SRpcMsg* pRsp, SEpSet* pEpSet) { TestClient* client = (TestClient*)parent; - client->SetRpcRsp(pMsg); - uInfo("response:%s from dnode, code:0x%x", TMSG_INFO(pMsg->msgType), pMsg->code); + client->SetRpcRsp(pRsp); + uInfo("response:%s from dnode, code:0x%x", TMSG_INFO(pRsp->msgType), pRsp->code); tsem_post(client->GetSem()); } @@ -59,14 +59,14 @@ void TestClient::Cleanup() { rpcClose(clientRpc); } -SRpcMsg* TestClient::SendMsg(SRpcMsg* pMsg) { +SRpcMsg* TestClient::SendReq(SRpcMsg* pReq) { SEpSet epSet = {0}; epSet.inUse = 0; epSet.numOfEps = 1; epSet.port[0] = port; memcpy(epSet.fqdn[0], fqdn, TSDB_FQDN_LEN); - rpcSendRequest(clientRpc, &epSet, pMsg, NULL); + rpcSendRequest(clientRpc, &epSet, pReq, NULL); tsem_wait(&sem); return pRsp; diff --git a/source/dnode/mgmt/impl/test/sut/src/server.cpp b/source/dnode/mgmt/impl/test/sut/src/server.cpp index 8ac5f62144..fb2974294c 100644 --- a/source/dnode/mgmt/impl/test/sut/src/server.cpp +++ b/source/dnode/mgmt/impl/test/sut/src/server.cpp @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "base.h" +#include "sut.h" void* serverLoop(void* param) { while (1) { diff --git a/source/dnode/mgmt/impl/test/sut/src/base.cpp b/source/dnode/mgmt/impl/test/sut/src/sut.cpp similarity index 85% rename from source/dnode/mgmt/impl/test/sut/src/base.cpp rename to source/dnode/mgmt/impl/test/sut/src/sut.cpp index e1b6664e9f..ba530dbdd0 100644 --- a/source/dnode/mgmt/impl/test/sut/src/base.cpp +++ b/source/dnode/mgmt/impl/test/sut/src/sut.cpp @@ -13,10 +13,10 @@ * along with this program. If not, see . */ -#include "base.h" +#include "sut.h" void Testbase::InitLog(const char* path) { - dDebugFlag = 0; + dDebugFlag = 143; vDebugFlag = 0; mDebugFlag = 143; cDebugFlag = 0; @@ -64,23 +64,23 @@ void Testbase::ServerStop() { server.Stop(); } void Testbase::ServerStart() { server.DoStart(); } -SRpcMsg* Testbase::SendMsg(tmsg_t msgType, void* pCont, int32_t contLen) { +SRpcMsg* Testbase::SendReq(tmsg_t msgType, void* pCont, int32_t contLen) { SRpcMsg rpcMsg = {0}; rpcMsg.pCont = pCont; rpcMsg.contLen = contLen; rpcMsg.msgType = msgType; - return client.SendMsg(&rpcMsg); + return client.SendReq(&rpcMsg); } -void Testbase::SendShowMetaMsg(int8_t showType, const char* db) { - int32_t contLen = sizeof(SShowMsg); - SShowMsg* pShow = (SShowMsg*)rpcMallocCont(contLen); +void Testbase::SendShowMetaReq(int8_t showType, const char* db) { + int32_t contLen = sizeof(SShowReq); + SShowReq* pShow = (SShowReq*)rpcMallocCont(contLen); pShow->type = showType; strcpy(pShow->db, db); - SRpcMsg* pMsg = SendMsg(TDMT_MND_SHOW, pShow, contLen); - SShowRsp* pShowRsp = (SShowRsp*)pMsg->pCont; + SRpcMsg* pRsp = SendReq(TDMT_MND_SHOW, pShow, contLen); + SShowRsp* pShowRsp = (SShowRsp*)pRsp->pCont; ASSERT(pShowRsp != nullptr); pShowRsp->showId = htobe64(pShowRsp->showId); @@ -121,15 +121,15 @@ int32_t Testbase::GetMetaNum() { return pMeta->numOfColumns; } const char* Testbase::GetMetaTbName() { return pMeta->tbFname; } -void Testbase::SendShowRetrieveMsg() { - int32_t contLen = sizeof(SRetrieveTableMsg); +void Testbase::SendShowRetrieveReq() { + int32_t contLen = sizeof(SRetrieveTableReq); - SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(contLen); + SRetrieveTableReq* pRetrieve = (SRetrieveTableReq*)rpcMallocCont(contLen); pRetrieve->showId = htobe64(showId); pRetrieve->free = 0; - SRpcMsg* pMsg = SendMsg(TDMT_MND_SHOW_RETRIEVE, pRetrieve, contLen); - pRetrieveRsp = (SRetrieveTableRsp*)pMsg->pCont; + SRpcMsg* pRsp = SendReq(TDMT_MND_SHOW_RETRIEVE, pRetrieve, contLen); + pRetrieveRsp = (SRetrieveTableRsp*)pRsp->pCont; pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows); pRetrieveRsp->useconds = htobe64(pRetrieveRsp->useconds); pRetrieveRsp->compLen = htonl(pRetrieveRsp->compLen); @@ -179,6 +179,6 @@ const char* Testbase::GetShowBinary(int32_t len) { int32_t Testbase::GetShowRows() { return pRetrieveRsp->numOfRows; } -STableMetaMsg* Testbase::GetShowMeta() { return pMeta; } +STableMetaRsp* Testbase::GetShowMeta() { return pMeta; } SRetrieveTableRsp* Testbase::GetRetrieveRsp() { return pRetrieveRsp; } \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/vgroup/CMakeLists.txt b/source/dnode/mgmt/impl/test/vgroup/CMakeLists.txt deleted file mode 100644 index b864b0593c..0000000000 --- a/source/dnode/mgmt/impl/test/vgroup/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -aux_source_directory(. VGROUP_SRC) -add_executable(dnode_test_vgroup ${VGROUP_SRC}) -target_link_libraries( - dnode_test_vgroup - PUBLIC sut -) - -add_test( - NAME dnode_test_vgroup - COMMAND dnode_test_vgroup -) diff --git a/source/dnode/mgmt/impl/test/vnode/CMakeLists.txt b/source/dnode/mgmt/impl/test/vnode/CMakeLists.txt new file mode 100644 index 0000000000..6fb8bb4ba4 --- /dev/null +++ b/source/dnode/mgmt/impl/test/vnode/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. VNODE_SRC) +add_executable(dnode_test_vnode ${VNODE_SRC}) +target_link_libraries( + dnode_test_vnode + PUBLIC sut +) + +add_test( + NAME dnode_test_vnode + COMMAND dnode_test_vnode +) diff --git a/source/dnode/mgmt/impl/test/vgroup/vgroup.cpp b/source/dnode/mgmt/impl/test/vnode/vnode.cpp similarity index 64% rename from source/dnode/mgmt/impl/test/vgroup/vgroup.cpp rename to source/dnode/mgmt/impl/test/vnode/vnode.cpp index 718fbea50d..6b042c3ce6 100644 --- a/source/dnode/mgmt/impl/test/vgroup/vgroup.cpp +++ b/source/dnode/mgmt/impl/test/vnode/vnode.cpp @@ -1,7 +1,7 @@ /** * @file db.cpp * @author slguan (slguan@taosdata.com) - * @brief DNODE module vgroup-msg tests + * @brief DNODE module vnode tests * @version 0.1 * @date 2021-12-20 * @@ -9,11 +9,11 @@ * */ -#include "base.h" +#include "sut.h" -class DndTestVgroup : public ::testing::Test { +class DndTestVnode : public ::testing::Test { protected: - static void SetUpTestSuite() { test.Init("/tmp/dnode_test_vgroup", 9150); } + static void SetUpTestSuite() { test.Init("/tmp/dnode_test_vnode", 9115); } static void TearDownTestSuite() { test.Cleanup(); } static Testbase test; @@ -23,14 +23,14 @@ class DndTestVgroup : public ::testing::Test { void TearDown() override {} }; -Testbase DndTestVgroup::test; +Testbase DndTestVnode::test; -TEST_F(DndTestVgroup, 01_Create_Restart_Drop_Vnode) { +TEST_F(DndTestVnode, 01_Create_Restart_Drop_Vnode) { { for (int i = 0; i < 3; ++i) { - int32_t contLen = sizeof(SCreateVnodeMsg); + int32_t contLen = sizeof(SCreateVnodeReq); - SCreateVnodeMsg* pReq = (SCreateVnodeMsg*)rpcMallocCont(contLen); + SCreateVnodeReq* pReq = (SCreateVnodeReq*)rpcMallocCont(contLen); pReq->vgId = htonl(2); pReq->dnodeId = htonl(1); strcpy(pReq->db, "1.d1"); @@ -57,20 +57,25 @@ TEST_F(DndTestVgroup, 01_Create_Restart_Drop_Vnode) { for (int r = 0; r < pReq->replica; ++r) { SReplica* pReplica = &pReq->replicas[r]; pReplica->id = htonl(1); - pReplica->port = htons(9150); + pReplica->port = htons(9527); } - SRpcMsg* pMsg = test.SendMsg(TDMT_DND_CREATE_VNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_VNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (i == 0) { + ASSERT_EQ(pRsp->code, 0); + test.Restart(); + } else { + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED); + } } } { for (int i = 0; i < 3; ++i) { - int32_t contLen = sizeof(SAlterVnodeMsg); + int32_t contLen = sizeof(SAlterVnodeReq); - SAlterVnodeMsg* pReq = (SAlterVnodeMsg*)rpcMallocCont(contLen); + SAlterVnodeReq* pReq = (SAlterVnodeReq*)rpcMallocCont(contLen); pReq->vgId = htonl(2); pReq->dnodeId = htonl(1); strcpy(pReq->db, "1.d1"); @@ -97,20 +102,20 @@ TEST_F(DndTestVgroup, 01_Create_Restart_Drop_Vnode) { for (int r = 0; r < pReq->replica; ++r) { SReplica* pReplica = &pReq->replicas[r]; pReplica->id = htonl(1); - pReplica->port = htons(9150); + pReplica->port = htons(9527); } - SRpcMsg* pMsg = test.SendMsg(TDMT_DND_ALTER_VNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_DND_ALTER_VNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } } { for (int i = 0; i < 3; ++i) { - int32_t contLen = sizeof(SDropVnodeMsg); + int32_t contLen = sizeof(SDropVnodeReq); - SDropVnodeMsg* pReq = (SDropVnodeMsg*)rpcMallocCont(contLen); + SDropVnodeReq* pReq = (SDropVnodeReq*)rpcMallocCont(contLen); pReq->vgId = htonl(2); pReq->dnodeId = htonl(1); strcpy(pReq->db, "1.d1"); @@ -118,12 +123,17 @@ TEST_F(DndTestVgroup, 01_Create_Restart_Drop_Vnode) { SRpcMsg rpcMsg = {0}; rpcMsg.pCont = pReq; - rpcMsg.contLen = sizeof(SDropVnodeMsg); + rpcMsg.contLen = sizeof(SDropVnodeReq); rpcMsg.msgType = TDMT_DND_DROP_VNODE; - SRpcMsg* pMsg = test.SendMsg(TDMT_DND_DROP_VNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_VNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (i == 0) { + ASSERT_EQ(pRsp->code, 0); + test.Restart(); + } else { + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_VNODE_NOT_DEPLOYED); + } } } } diff --git a/source/dnode/mnode/impl/inc/mndConsumer.h b/source/dnode/mnode/impl/inc/mndConsumer.h index 60f186d7d2..68ba08b66e 100644 --- a/source/dnode/mnode/impl/inc/mndConsumer.h +++ b/source/dnode/mnode/impl/inc/mndConsumer.h @@ -25,11 +25,8 @@ extern "C" { int32_t mndInitConsumer(SMnode *pMnode); void mndCleanupConsumer(SMnode *pMnode); -SConsumerObj *mndAcquireConsumer(SMnode *pMnode, int32_t consumerId); -void mndReleaseConsumer(SMnode *pMnode, SConsumerObj *pConsumer); - -SCGroupObj *mndAcquireCGroup(SMnode *pMnode, char *consumerGroup); -void mndReleaseCGroup(SMnode *pMnode, SCGroupObj *pCGroup); +SMqConsumerObj *mndAcquireConsumer(SMnode *pMnode, int32_t consumerId); +void mndReleaseConsumer(SMnode *pMnode, SMqConsumerObj *pConsumer); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 267a3f6cf5..a55e0dd2b2 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -22,6 +22,7 @@ #include "sync.h" #include "tmsg.h" #include "thash.h" +#include "tlist.h" #include "tlog.h" #include "trpc.h" #include "ttimer.h" @@ -64,10 +65,10 @@ typedef enum { TRN_STAGE_PREPARE = 0, TRN_STAGE_REDO_LOG = 1, TRN_STAGE_REDO_ACTION = 2, - TRN_STAGE_UNDO_LOG = 3, - TRN_STAGE_UNDO_ACTION = 4, - TRN_STAGE_COMMIT_LOG = 5, - TRN_STAGE_COMMIT = 6, + TRN_STAGE_COMMIT = 3, + TRN_STAGE_COMMIT_LOG = 4, + TRN_STAGE_UNDO_ACTION = 5, + TRN_STAGE_UNDO_LOG = 6, TRN_STAGE_ROLLBACK = 7, TRN_STAGE_FINISHED = 8 } ETrnStage; @@ -307,46 +308,117 @@ typedef struct { char payload[]; } SShowObj; -typedef struct { - char name[TSDB_TOPIC_FNAME_LEN]; - char db[TSDB_DB_FNAME_LEN]; - int64_t createTime; - int64_t updateTime; - uint64_t uid; - uint64_t dbUid; - int32_t version; - SRWLatch lock; - int32_t execLen; - void* executor; - int32_t sqlLen; - char* sql; - char* logicalPlan; - char* physicalPlan; -} STopicObj; - -typedef struct { - char name[TSDB_TOPIC_FNAME_LEN]; - char db[TSDB_DB_FNAME_LEN]; - int64_t createTime; - int64_t updateTime; +#if 0 +typedef struct SConsumerObj { uint64_t uid; + int64_t createTime; + int64_t updateTime; //uint64_t dbUid; - int32_t version; + int32_t version; SRWLatch lock; - + SArray* topics; } SConsumerObj; -typedef struct { - char name[TSDB_TOPIC_FNAME_LEN]; - char db[TSDB_DB_FNAME_LEN]; - int64_t createTime; - int64_t updateTime; +typedef struct SMqTopicConsumer { + int64_t consumerId; + SList* topicList; +} SMqTopicConsumer; +#endif + +typedef struct SMqCGroup { + char name[TSDB_CONSUMER_GROUP_LEN]; + int32_t status; // 0 - uninitialized, 1 - wait rebalance, 2- normal + SList *consumerIds; // SList + SList *idleVGroups; // SList +} SMqCGroup; + +typedef struct SMqTopicObj { + char name[TSDB_TOPIC_FNAME_LEN]; + char db[TSDB_DB_FNAME_LEN]; + int64_t createTime; + int64_t updateTime; + uint64_t uid; + uint64_t dbUid; + int32_t version; + SRWLatch lock; + int32_t sqlLen; + char *sql; + char *logicalPlan; + char *physicalPlan; + SHashObj *cgroups; // SHashObj +} SMqTopicObj; + +// TODO: add cache and change name to id +typedef struct SMqConsumerTopic { + char name[TSDB_TOPIC_FNAME_LEN]; + SList *vgroups; // SList +} SMqConsumerTopic; + +typedef struct SMqConsumerObj { + SRWLatch lock; + int64_t consumerId; + char cgroup[TSDB_CONSUMER_GROUP_LEN]; + SArray *topics; // SArray +} SMqConsumerObj; + +typedef struct SMqSubConsumerObj { + int64_t consumerUid; // if -1, unassigned + SList *vgId; // SList +} SMqSubConsumerObj; + +typedef struct SMqSubCGroupObj { + char name[TSDB_CONSUMER_GROUP_LEN]; + SList *consumers; // SList +} SMqSubCGroupObj; + +typedef struct SMqSubTopicObj { + char name[TSDB_TOPIC_FNAME_LEN]; + char db[TSDB_DB_FNAME_LEN]; + int64_t createTime; + int64_t updateTime; + int64_t uid; + int64_t dbUid; + int32_t version; + SRWLatch lock; + int32_t sqlLen; + char *sql; + char *logicalPlan; + char *physicalPlan; + SList *cgroups; // SList +} SMqSubTopicObj; + +typedef struct SMqConsumerSubObj { + int64_t topicUid; + SList *vgIds; // SList +} SMqConsumerSubObj; + +typedef struct SMqConsumerHbObj { + int64_t consumerId; + SList *consumerSubs; // SList +} SMqConsumerHbObj; + +typedef struct SMqVGroupSubObj { + int64_t topicUid; + SList *consumerIds; // SList +} SMqVGroupSubObj; + +typedef struct SMqVGroupHbObj { + int64_t vgId; + SList *vgSubs; // SList +} SMqVGroupHbObj; + +#if 0 +typedef struct SCGroupObj { + char name[TSDB_TOPIC_FNAME_LEN]; + int64_t createTime; + int64_t updateTime; uint64_t uid; //uint64_t dbUid; - int32_t version; + int32_t version; SRWLatch lock; - + SList* consumerIds; } SCGroupObj; +#endif typedef struct SMnodeMsg { char user[TSDB_USER_LEN]; diff --git a/source/dnode/mnode/impl/inc/mndInt.h b/source/dnode/mnode/impl/inc/mndInt.h index 5c8d409d90..d2107b9d07 100644 --- a/source/dnode/mnode/impl/inc/mndInt.h +++ b/source/dnode/mnode/impl/inc/mndInt.h @@ -32,7 +32,7 @@ extern "C" { typedef int32_t (*MndMsgFp)(SMnodeMsg *pMsg); typedef int32_t (*MndInitFp)(SMnode *pMnode); typedef void (*MndCleanupFp)(SMnode *pMnode); -typedef int32_t (*ShowMetaFp)(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); +typedef int32_t (*ShowMetaFp)(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta); typedef int32_t (*ShowRetrieveFp)(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); typedef void (*ShowFreeIterFp)(SMnode *pMnode, void *pIter); @@ -91,15 +91,16 @@ typedef struct SMnode { STelemMgmt telemMgmt; SSyncMgmt syncMgmt; MndMsgFp msgFp[TDMT_MAX]; - SendMsgToDnodeFp sendMsgToDnodeFp; - SendMsgToMnodeFp sendMsgToMnodeFp; - SendRedirectMsgFp sendRedirectMsgFp; + SendReqToDnodeFp sendReqToDnodeFp; + SendReqToMnodeFp sendReqToMnodeFp; + SendRedirectRspFp sendRedirectRspFp; + PutReqToMWriteQFp putReqToMWriteQFp; } SMnode; -void mndSendMsgToDnode(SMnode *pMnode, SEpSet *pEpSet, SRpcMsg *rpcMsg); -void mndSendMsgToMnode(SMnode *pMnode, SRpcMsg *pMsg); -void mndSendRedirectMsg(SMnode *pMnode, SRpcMsg *pMsg); -void mndSetMsgHandle(SMnode *pMnode, tmsg_t msgType, MndMsgFp fp); +int32_t mndSendReqToDnode(SMnode *pMnode, SEpSet *pEpSet, SRpcMsg *rpcMsg); +int32_t mndSendReqToMnode(SMnode *pMnode, SRpcMsg *pMsg); +void mndSendRedirectRsp(SMnode *pMnode, SRpcMsg *pMsg); +void mndSetMsgHandle(SMnode *pMnode, tmsg_t msgType, MndMsgFp fp); uint64_t mndGenerateUid(char *name, int32_t len) ; diff --git a/source/dnode/mnode/impl/inc/mndTopic.h b/source/dnode/mnode/impl/inc/mndTopic.h index d092f47d4b..fd82c60d37 100644 --- a/source/dnode/mnode/impl/inc/mndTopic.h +++ b/source/dnode/mnode/impl/inc/mndTopic.h @@ -25,8 +25,11 @@ extern "C" { int32_t mndInitTopic(SMnode *pMnode); void mndCleanupTopic(SMnode *pMnode); -STopicObj *mndAcquireTopic(SMnode *pMnode, char *topicName); -void mndReleaseTopic(SMnode *pMnode, STopicObj *pTopic); +SMqTopicObj *mndAcquireTopic(SMnode *pMnode, char *topicName); +void mndReleaseTopic(SMnode *pMnode, SMqTopicObj *pTopic); + +SSdbRaw *mndTopicActionEncode(SMqTopicObj *pTopic); +SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndTrans.h b/source/dnode/mnode/impl/inc/mndTrans.h index 201fcde1a9..fda3fed13d 100644 --- a/source/dnode/mnode/impl/inc/mndTrans.h +++ b/source/dnode/mnode/impl/inc/mndTrans.h @@ -28,6 +28,7 @@ typedef struct { int8_t msgSent; int8_t msgReceived; int32_t errCode; + int32_t acceptableCode; int32_t contLen; void *pCont; } STransAction; @@ -45,6 +46,7 @@ int32_t mndTransAppendUndoAction(STrans *pTrans, STransAction *pAction); int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans); void mndTransProcessRsp(SMnodeMsg *pMsg); +void mndTransPullup(SMnode *pMnode); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndVgroup.h b/source/dnode/mnode/impl/inc/mndVgroup.h index 6d391450b7..6ab11aa1b4 100644 --- a/source/dnode/mnode/impl/inc/mndVgroup.h +++ b/source/dnode/mnode/impl/inc/mndVgroup.h @@ -31,8 +31,8 @@ int32_t mndAllocVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj **ppVgroups); SEpSet mndGetVgroupEpset(SMnode *pMnode, SVgObj *pVgroup); int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId); -SCreateVnodeMsg *mndBuildCreateVnodeMsg(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup); -SDropVnodeMsg *mndBuildDropVnodeMsg(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup); +SCreateVnodeReq *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup); +SDropVnodeReq *mndBuildDropVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/src/mndAcct.c b/source/dnode/mnode/impl/src/mndAcct.c index 2847d19bea..aa87eb43a1 100644 --- a/source/dnode/mnode/impl/src/mndAcct.c +++ b/source/dnode/mnode/impl/src/mndAcct.c @@ -25,10 +25,10 @@ static SSdbRaw *mndAcctActionEncode(SAcctObj *pAcct); static SSdbRow *mndAcctActionDecode(SSdbRaw *pRaw); static int32_t mndAcctActionInsert(SSdb *pSdb, SAcctObj *pAcct); static int32_t mndAcctActionDelete(SSdb *pSdb, SAcctObj *pAcct); -static int32_t mndAcctActionUpdate(SSdb *pSdb, SAcctObj *pOldAcct, SAcctObj *pNewAcct); -static int32_t mndProcessCreateAcctMsg(SMnodeMsg *pMnodeMsg); -static int32_t mndProcessAlterAcctMsg(SMnodeMsg *pMnodeMsg); -static int32_t mndProcessDropAcctMsg(SMnodeMsg *pMnodeMsg); +static int32_t mndAcctActionUpdate(SSdb *pSdb, SAcctObj *pOld, SAcctObj *pNew); +static int32_t mndProcessCreateAcctReq(SMnodeMsg *pReq); +static int32_t mndProcessAlterAcctReq(SMnodeMsg *pReq); +static int32_t mndProcessDropAcctReq(SMnodeMsg *pReq); int32_t mndInitAcct(SMnode *pMnode) { SSdbTable table = {.sdbType = SDB_ACCT, @@ -40,9 +40,9 @@ int32_t mndInitAcct(SMnode *pMnode) { .updateFp = (SdbUpdateFp)mndAcctActionUpdate, .deleteFp = (SdbDeleteFp)mndAcctActionDelete}; - mndSetMsgHandle(pMnode, TDMT_MND_CREATE_ACCT, mndProcessCreateAcctMsg); - mndSetMsgHandle(pMnode, TDMT_MND_ALTER_ACCT, mndProcessAlterAcctMsg); - mndSetMsgHandle(pMnode, TDMT_MND_DROP_ACCT, mndProcessDropAcctMsg); + mndSetMsgHandle(pMnode, TDMT_MND_CREATE_ACCT, mndProcessCreateAcctReq); + mndSetMsgHandle(pMnode, TDMT_MND_ALTER_ACCT, mndProcessAlterAcctReq); + mndSetMsgHandle(pMnode, TDMT_MND_DROP_ACCT, mndProcessDropAcctReq); return sdbSetTable(pMnode->pSdb, table); } @@ -176,29 +176,29 @@ static int32_t mndAcctActionDelete(SSdb *pSdb, SAcctObj *pAcct) { return 0; } -static int32_t mndAcctActionUpdate(SSdb *pSdb, SAcctObj *pOldAcct, SAcctObj *pNewAcct) { - mTrace("acct:%s, perform update action, old_row:%p new_row:%p", pOldAcct->acct, pOldAcct, pNewAcct); +static int32_t mndAcctActionUpdate(SSdb *pSdb, SAcctObj *pOld, SAcctObj *pNew) { + mTrace("acct:%s, perform update action, old row:%p new row:%p", pOld->acct, pOld, pNew); - pOldAcct->updateTime = pNewAcct->updateTime; - pOldAcct->status = pNewAcct->status; - memcpy(&pOldAcct->cfg, &pNewAcct->cfg, sizeof(SAcctCfg)); + pOld->updateTime = pNew->updateTime; + pOld->status = pNew->status; + memcpy(&pOld->cfg, &pNew->cfg, sizeof(SAcctCfg)); return 0; } -static int32_t mndProcessCreateAcctMsg(SMnodeMsg *pMnodeMsg) { +static int32_t mndProcessCreateAcctReq(SMnodeMsg *pReq) { terrno = TSDB_CODE_MND_MSG_NOT_PROCESSED; - mError("failed to process create acct msg since %s", terrstr()); + mError("failed to process create acct request since %s", terrstr()); return -1; } -static int32_t mndProcessAlterAcctMsg(SMnodeMsg *pMnodeMsg) { +static int32_t mndProcessAlterAcctReq(SMnodeMsg *pReq) { terrno = TSDB_CODE_MND_MSG_NOT_PROCESSED; - mError("failed to process create acct msg since %s", terrstr()); + mError("failed to process create acct request since %s", terrstr()); return -1; } -static int32_t mndProcessDropAcctMsg(SMnodeMsg *pMnodeMsg) { +static int32_t mndProcessDropAcctReq(SMnodeMsg *pReq) { terrno = TSDB_CODE_MND_MSG_NOT_PROCESSED; - mError("failed to process create acct msg since %s", terrstr()); + mError("failed to process create acct request since %s", terrstr()); return -1; } \ No newline at end of file diff --git a/source/dnode/mnode/impl/src/mndAuth.c b/source/dnode/mnode/impl/src/mndAuth.c index bcefbfde21..a2fc7a57b3 100644 --- a/source/dnode/mnode/impl/src/mndAuth.c +++ b/source/dnode/mnode/impl/src/mndAuth.c @@ -14,7 +14,6 @@ */ #define _DEFAULT_SOURCE -#include "os.h" #include "mndAuth.h" int32_t mndInitAuth(SMnode *pMnode) { return 0; } diff --git a/source/dnode/mnode/impl/src/mndBnode.c b/source/dnode/mnode/impl/src/mndBnode.c index ceaebe3f6d..189cbfea6d 100644 --- a/source/dnode/mnode/impl/src/mndBnode.c +++ b/source/dnode/mnode/impl/src/mndBnode.c @@ -26,13 +26,13 @@ static SSdbRaw *mndBnodeActionEncode(SBnodeObj *pObj); static SSdbRow *mndBnodeActionDecode(SSdbRaw *pRaw); static int32_t mndBnodeActionInsert(SSdb *pSdb, SBnodeObj *pObj); static int32_t mndBnodeActionDelete(SSdb *pSdb, SBnodeObj *pObj); -static int32_t mndBnodeActionUpdate(SSdb *pSdb, SBnodeObj *pOldBnode, SBnodeObj *pNewBnode); -static int32_t mndProcessCreateBnodeReq(SMnodeMsg *pMsg); -static int32_t mndProcessDropBnodeReq(SMnodeMsg *pMsg); -static int32_t mndProcessCreateBnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessDropBnodeRsp(SMnodeMsg *pMsg); -static int32_t mndGetBnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveBnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndBnodeActionUpdate(SSdb *pSdb, SBnodeObj *pOld, SBnodeObj *pNew); +static int32_t mndProcessCreateBnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessDropBnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessCreateBnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessDropBnodeRsp(SMnodeMsg *pRsp); +static int32_t mndGetBnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveBnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextBnode(SMnode *pMnode, void *pIter); int32_t mndInitBnode(SMnode *pMnode) { @@ -59,9 +59,8 @@ int32_t mndInitBnode(SMnode *pMnode) { void mndCleanupBnode(SMnode *pMnode) {} static SBnodeObj *mndAcquireBnode(SMnode *pMnode, int32_t bnodeId) { - SSdb *pSdb = pMnode->pSdb; - SBnodeObj *pObj = sdbAcquire(pSdb, SDB_BNODE, &bnodeId); - if (pObj == NULL) { + SBnodeObj *pObj = sdbAcquire(pMnode->pSdb, SDB_BNODE, &bnodeId); + if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) { terrno = TSDB_CODE_MND_BNODE_NOT_EXIST; } return pObj; @@ -155,9 +154,9 @@ static int32_t mndBnodeActionDelete(SSdb *pSdb, SBnodeObj *pObj) { return 0; } -static int32_t mndBnodeActionUpdate(SSdb *pSdb, SBnodeObj *pOldBnode, SBnodeObj *pNewBnode) { - mTrace("bnode:%d, perform update action, old_row:%p new_row:%p", pOldBnode->id, pOldBnode, pNewBnode); - pOldBnode->updateTime = pNewBnode->updateTime; +static int32_t mndBnodeActionUpdate(SSdb *pSdb, SBnodeObj *pOld, SBnodeObj *pNew) { + mTrace("bnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew); + pOld->updateTime = pNew->updateTime; return 0; } @@ -169,6 +168,14 @@ static int32_t mndSetCreateBnodeRedoLogs(STrans *pTrans, SBnodeObj *pObj) { return 0; } +static int32_t mndSetCreateBnodeUndoLogs(STrans *pTrans, SBnodeObj *pObj) { + SSdbRaw *pUndoRaw = mndBnodeActionEncode(pObj); + if (pUndoRaw == NULL) return -1; + if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) return -1; + if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1; + return 0; +} + static int32_t mndSetCreateBnodeCommitLogs(STrans *pTrans, SBnodeObj *pObj) { SSdbRaw *pCommitRaw = mndBnodeActionEncode(pObj); if (pCommitRaw == NULL) return -1; @@ -178,60 +185,69 @@ static int32_t mndSetCreateBnodeCommitLogs(STrans *pTrans, SBnodeObj *pObj) { } static int32_t mndSetCreateBnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SBnodeObj *pObj) { - SDCreateBnodeMsg *pMsg = malloc(sizeof(SDCreateBnodeMsg)); - if (pMsg == NULL) { + SDCreateBnodeReq *pReq = malloc(sizeof(SDCreateBnodeReq)); + if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pMsg->dnodeId = htonl(pDnode->id); + pReq->dnodeId = htonl(pDnode->id); STransAction action = {0}; action.epSet = mndGetDnodeEpset(pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDCreateBnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDCreateBnodeReq); action.msgType = TDMT_DND_CREATE_BNODE; + action.acceptableCode = TSDB_CODE_DND_BNODE_ALREADY_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } return 0; } -static int32_t mndCreateBnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode, SMCreateBnodeMsg *pCreate) { +static int32_t mndSetCreateBnodeUndoActions(STrans *pTrans, SDnodeObj *pDnode, SBnodeObj *pObj) { + SDDropBnodeReq *pReq = malloc(sizeof(SDDropBnodeReq)); + if (pReq == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + pReq->dnodeId = htonl(pDnode->id); + + STransAction action = {0}; + action.epSet = mndGetDnodeEpset(pDnode); + action.pCont = pReq; + action.contLen = sizeof(SDDropBnodeReq); + action.msgType = TDMT_DND_DROP_BNODE; + action.acceptableCode = TSDB_CODE_DND_BNODE_NOT_DEPLOYED; + + if (mndTransAppendUndoAction(pTrans, &action) != 0) { + free(pReq); + return -1; + } + + return 0; +} + +static int32_t mndCreateBnode(SMnode *pMnode, SMnodeMsg *pReq, SDnodeObj *pDnode, SMCreateBnodeReq *pCreate) { + int32_t code = -1; + SBnodeObj bnodeObj = {0}; bnodeObj.id = pDnode->id; bnodeObj.createdTime = taosGetTimestampMs(); bnodeObj.updateTime = bnodeObj.createdTime; - int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("bnode:%d, failed to create since %s", pCreate->dnodeId, terrstr()); - goto CREATE_BNODE_OVER; - } + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); + if (pTrans == NULL) goto CREATE_BNODE_OVER; + mDebug("trans:%d, used to create bnode:%d", pTrans->id, pCreate->dnodeId); - - if (mndSetCreateBnodeRedoLogs(pTrans, &bnodeObj) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto CREATE_BNODE_OVER; - } - - if (mndSetCreateBnodeCommitLogs(pTrans, &bnodeObj) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto CREATE_BNODE_OVER; - } - - if (mndSetCreateBnodeRedoActions(pTrans, pDnode, &bnodeObj) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto CREATE_BNODE_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto CREATE_BNODE_OVER; - } + if (mndSetCreateBnodeRedoLogs(pTrans, &bnodeObj) != 0) goto CREATE_BNODE_OVER; + if (mndSetCreateBnodeUndoLogs(pTrans, &bnodeObj) != 0) goto CREATE_BNODE_OVER; + if (mndSetCreateBnodeCommitLogs(pTrans, &bnodeObj) != 0) goto CREATE_BNODE_OVER; + if (mndSetCreateBnodeRedoActions(pTrans, pDnode, &bnodeObj) != 0) goto CREATE_BNODE_OVER; + if (mndSetCreateBnodeUndoActions(pTrans, pDnode, &bnodeObj) != 0) goto CREATE_BNODE_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto CREATE_BNODE_OVER; code = 0; @@ -240,9 +256,9 @@ CREATE_BNODE_OVER: return code; } -static int32_t mndProcessCreateBnodeReq(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SMCreateBnodeMsg *pCreate = pMsg->rpcMsg.pCont; +static int32_t mndProcessCreateBnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMCreateBnodeReq *pCreate = pReq->rpcMsg.pCont; pCreate->dnodeId = htonl(pCreate->dnodeId); @@ -251,8 +267,12 @@ static int32_t mndProcessCreateBnodeReq(SMnodeMsg *pMsg) { SBnodeObj *pObj = mndAcquireBnode(pMnode, pCreate->dnodeId); if (pObj != NULL) { mError("bnode:%d, bnode already exist", pObj->id); + terrno = TSDB_CODE_MND_BNODE_ALREADY_EXIST; mndReleaseBnode(pMnode, pObj); return -1; + } else if (terrno != TSDB_CODE_MND_BNODE_NOT_EXIST) { + mError("bnode:%d, failed to create bnode since %s", pCreate->dnodeId, terrstr()); + return -1; } SDnodeObj *pDnode = mndAcquireDnode(pMnode, pCreate->dnodeId); @@ -262,7 +282,7 @@ static int32_t mndProcessCreateBnodeReq(SMnodeMsg *pMsg) { return -1; } - int32_t code = mndCreateBnode(pMnode, pMsg, pDnode, pCreate); + int32_t code = mndCreateBnode(pMnode, pReq, pDnode, pCreate); mndReleaseDnode(pMnode, pDnode); if (code != 0) { @@ -290,56 +310,39 @@ static int32_t mndSetDropBnodeCommitLogs(STrans *pTrans, SBnodeObj *pObj) { } static int32_t mndSetDropBnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SBnodeObj *pObj) { - SDDropBnodeMsg *pMsg = malloc(sizeof(SDDropBnodeMsg)); - if (pMsg == NULL) { + SDDropBnodeReq *pReq = malloc(sizeof(SDDropBnodeReq)); + if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pMsg->dnodeId = htonl(pDnode->id); + pReq->dnodeId = htonl(pDnode->id); STransAction action = {0}; action.epSet = mndGetDnodeEpset(pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDDropBnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDDropBnodeReq); action.msgType = TDMT_DND_DROP_BNODE; + action.acceptableCode = TSDB_CODE_DND_BNODE_NOT_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } return 0; } -static int32_t mndDropBnode(SMnode *pMnode, SMnodeMsg *pMsg, SBnodeObj *pObj) { +static int32_t mndDropBnode(SMnode *pMnode, SMnodeMsg *pReq, SBnodeObj *pObj) { int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("bnode:%d, failed to drop since %s", pObj->id, terrstr()); - goto DROP_BNODE_OVER; - } + + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg); + if (pTrans == NULL) goto DROP_BNODE_OVER; mDebug("trans:%d, used to drop bnode:%d", pTrans->id, pObj->id); - - if (mndSetDropBnodeRedoLogs(pTrans, pObj) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto DROP_BNODE_OVER; - } - - if (mndSetDropBnodeCommitLogs(pTrans, pObj) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto DROP_BNODE_OVER; - } - - if (mndSetDropBnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto DROP_BNODE_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto DROP_BNODE_OVER; - } + if (mndSetDropBnodeRedoLogs(pTrans, pObj) != 0) goto DROP_BNODE_OVER; + if (mndSetDropBnodeCommitLogs(pTrans, pObj) != 0) goto DROP_BNODE_OVER; + if (mndSetDropBnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) goto DROP_BNODE_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_BNODE_OVER; code = 0; @@ -348,9 +351,9 @@ DROP_BNODE_OVER: return code; } -static int32_t mndProcessDropBnodeReq(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SMDropBnodeMsg *pDrop = pMsg->rpcMsg.pCont; +static int32_t mndProcessDropBnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMDropBnodeReq *pDrop = pReq->rpcMsg.pCont; pDrop->dnodeId = htonl(pDrop->dnodeId); mDebug("bnode:%d, start to drop", pDrop->dnodeId); @@ -363,33 +366,33 @@ static int32_t mndProcessDropBnodeReq(SMnodeMsg *pMsg) { SBnodeObj *pObj = mndAcquireBnode(pMnode, pDrop->dnodeId); if (pObj == NULL) { - mError("bnode:%d, not exist", pDrop->dnodeId); - terrno = TSDB_CODE_MND_BNODE_NOT_EXIST; + mError("bnode:%d, failed to drop since %s", pDrop->dnodeId, terrstr()); return -1; } - int32_t code = mndDropBnode(pMnode, pMsg, pObj); + int32_t code = mndDropBnode(pMnode, pReq, pObj); if (code != 0) { + sdbRelease(pMnode->pSdb, pObj); mError("bnode:%d, failed to drop since %s", pMnode->dnodeId, terrstr()); return -1; } - sdbRelease(pMnode->pSdb, pMnode); + sdbRelease(pMnode->pSdb, pObj); return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessCreateBnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessCreateBnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndProcessDropBnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessDropBnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndGetBnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetBnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -428,8 +431,8 @@ static int32_t mndGetBnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * return 0; } -static int32_t mndRetrieveBnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveBnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; int32_t cols = 0; diff --git a/source/dnode/mnode/impl/src/mndCluster.c b/source/dnode/mnode/impl/src/mndCluster.c index b29f8276fe..5f80672369 100644 --- a/source/dnode/mnode/impl/src/mndCluster.c +++ b/source/dnode/mnode/impl/src/mndCluster.c @@ -16,7 +16,6 @@ #define _DEFAULT_SOURCE #include "mndCluster.h" #include "mndShow.h" -#include "mndTrans.h" #define TSDB_CLUSTER_VER_NUMBE 1 #define TSDB_CLUSTER_RESERVE_SIZE 64 @@ -27,7 +26,7 @@ static int32_t mndClusterActionInsert(SSdb *pSdb, SClusterObj *pCluster); static int32_t mndClusterActionDelete(SSdb *pSdb, SClusterObj *pCluster); static int32_t mndClusterActionUpdate(SSdb *pSdb, SClusterObj *pOldCluster, SClusterObj *pNewCluster); static int32_t mndCreateDefaultCluster(SMnode *pMnode); -static int32_t mndGetClusterMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); +static int32_t mndGetClusterMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta); static int32_t mndRetrieveClusters(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextCluster(SMnode *pMnode, void *pIter); @@ -136,7 +135,7 @@ static int32_t mndClusterActionDelete(SSdb *pSdb, SClusterObj *pCluster) { } static int32_t mndClusterActionUpdate(SSdb *pSdb, SClusterObj *pOld, SClusterObj *pNew) { - mTrace("cluster:%" PRId64 ", perform update action, old_row:%p new_row:%p", pOld->id, pOld, pNew); + mTrace("cluster:%" PRId64 ", perform update action, old row:%p new row:%p", pOld->id, pOld, pNew); return 0; } @@ -164,7 +163,7 @@ static int32_t mndCreateDefaultCluster(SMnode *pMnode) { return sdbWrite(pMnode->pSdb, pRaw); } -static int32_t mndGetClusterMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { +static int32_t mndGetClusterMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta) { int32_t cols = 0; SSchema *pSchema = pMeta->pSchema; diff --git a/source/dnode/mnode/impl/src/mndConsumer.c b/source/dnode/mnode/impl/src/mndConsumer.c index 32a044fe09..54e640d8b7 100644 --- a/source/dnode/mnode/impl/src/mndConsumer.c +++ b/source/dnode/mnode/impl/src/mndConsumer.c @@ -24,21 +24,22 @@ #include "mndTrans.h" #include "mndUser.h" #include "mndVgroup.h" +#include "tcompare.h" #include "tname.h" #define MND_CONSUMER_VER_NUMBER 1 #define MND_CONSUMER_RESERVE_SIZE 64 -static SSdbRaw *mndConsumerActionEncode(SConsumerObj *pConsumer); +static SSdbRaw *mndConsumerActionEncode(SMqConsumerObj *pConsumer); static SSdbRow *mndConsumerActionDecode(SSdbRaw *pRaw); -static int32_t mndConsumerActionInsert(SSdb *pSdb, SConsumerObj *pConsumer); -static int32_t mndConsumerActionDelete(SSdb *pSdb, SConsumerObj *pConsumer); -static int32_t mndConsumerActionUpdate(SSdb *pSdb, SConsumerObj *pConsumer, SConsumerObj *pNewConsumer); +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); static int32_t mndProcessCreateConsumerMsg(SMnodeMsg *pMsg); static int32_t mndProcessDropConsumerMsg(SMnodeMsg *pMsg); static int32_t mndProcessDropConsumerInRsp(SMnodeMsg *pMsg); static int32_t mndProcessConsumerMetaMsg(SMnodeMsg *pMsg); -static int32_t mndGetConsumerMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); +static int32_t mndGetConsumerMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta); static int32_t mndRetrieveConsumer(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextConsumer(SMnode *pMnode, void *pIter); @@ -57,8 +58,8 @@ int32_t mndInitConsumer(SMnode *pMnode) { .deleteFp = (SdbDeleteFp)mndConsumerActionDelete}; mndSetMsgHandle(pMnode, TDMT_MND_SUBSCRIBE, mndProcessSubscribeReq); - mndSetMsgHandle(pMnode, TDMT_MND_SUBSCRIBE_RSP, mndProcessSubscribeRsp); - mndSetMsgHandle(pMnode, TDMT_VND_SUBSCRIBE, mndProcessSubscribeInternalReq); + /*mndSetMsgHandle(pMnode, TDMT_MND_SUBSCRIBE_RSP, mndProcessSubscribeRsp);*/ + /*mndSetMsgHandle(pMnode, TDMT_VND_SUBSCRIBE, mndProcessSubscribeInternalReq);*/ mndSetMsgHandle(pMnode, TDMT_VND_SUBSCRIBE_RSP, mndProcessSubscribeInternalRsp); return sdbSetTable(pMnode->pSdb, table); @@ -66,33 +67,52 @@ int32_t mndInitConsumer(SMnode *pMnode) { void mndCleanupConsumer(SMnode *pMnode) {} -static SSdbRaw *mndConsumerActionEncode(SConsumerObj *pConsumer) { - terrno = TSDB_CODE_OUT_OF_MEMORY; +static void *mndBuildMqVGroupSetReq(SMnode *pMnode, char *topicName, int32_t vgId, int64_t consumerId, char *cgroup) { + return 0; +} - int32_t size = sizeof(SConsumerObj) + MND_CONSUMER_RESERVE_SIZE; +static SSdbRaw *mndConsumerActionEncode(SMqConsumerObj *pConsumer) { + int32_t size = sizeof(SMqConsumerObj) + MND_CONSUMER_RESERVE_SIZE; SSdbRaw *pRaw = sdbAllocRaw(SDB_CONSUMER, MND_CONSUMER_VER_NUMBER, size); if (pRaw == NULL) goto CM_ENCODE_OVER; int32_t dataPos = 0; - SDB_SET_BINARY(pRaw, dataPos, pConsumer->name, TSDB_TABLE_FNAME_LEN, CM_ENCODE_OVER) - SDB_SET_BINARY(pRaw, dataPos, pConsumer->db, TSDB_DB_FNAME_LEN, CM_ENCODE_OVER) - SDB_SET_INT64(pRaw, dataPos, pConsumer->createTime, CM_ENCODE_OVER) - SDB_SET_INT64(pRaw, dataPos, pConsumer->updateTime, CM_ENCODE_OVER) - SDB_SET_INT64(pRaw, dataPos, pConsumer->uid, CM_ENCODE_OVER) - /*SDB_SET_INT64(pRaw, dataPos, pConsumer->dbUid);*/ - SDB_SET_INT32(pRaw, dataPos, pConsumer->version, CM_ENCODE_OVER) + int32_t topicNum = taosArrayGetSize(pConsumer->topics); + SDB_SET_INT64(pRaw, dataPos, pConsumer->consumerId, CM_ENCODE_OVER); + int32_t len = strlen(pConsumer->cgroup); + SDB_SET_INT32(pRaw, dataPos, len, CM_ENCODE_OVER); + SDB_SET_BINARY(pRaw, dataPos, pConsumer->cgroup, len, CM_ENCODE_OVER); + SDB_SET_INT32(pRaw, dataPos, topicNum, CM_ENCODE_OVER); + for (int i = 0; i < topicNum; i++) { + int32_t len; + SMqConsumerTopic *pConsumerTopic = taosArrayGet(pConsumer->topics, i); + len = strlen(pConsumerTopic->name); + SDB_SET_INT32(pRaw, dataPos, len, CM_ENCODE_OVER); + SDB_SET_BINARY(pRaw, dataPos, pConsumerTopic->name, len, CM_ENCODE_OVER); + int vgSize; + if (pConsumerTopic->vgroups == NULL) { + vgSize = 0; + } else { + vgSize = listNEles(pConsumerTopic->vgroups); + } + SDB_SET_INT32(pRaw, dataPos, vgSize, CM_ENCODE_OVER); + for (int j = 0; j < vgSize; j++) { + // SList* head; + /*SDB_SET_INT64(pRaw, dataPos, 0[> change to list item <]);*/ + } + } - SDB_SET_RESERVE(pRaw, dataPos, MND_CONSUMER_RESERVE_SIZE, CM_ENCODE_OVER) - SDB_SET_DATALEN(pRaw, dataPos, CM_ENCODE_OVER) + SDB_SET_RESERVE(pRaw, dataPos, MND_CONSUMER_RESERVE_SIZE, CM_ENCODE_OVER); + SDB_SET_DATALEN(pRaw, dataPos, CM_ENCODE_OVER); CM_ENCODE_OVER: if (terrno != 0) { - mError("consumer:%s, failed to encode to raw:%p since %s", pConsumer->name, pRaw, terrstr()); + mError("consumer:%ld, failed to encode to raw:%p since %s", pConsumer->consumerId, pRaw, terrstr()); sdbFreeRaw(pRaw); return NULL; } - mTrace("consumer:%s, encode to raw:%p, row:%p", pConsumer->name, pRaw, pConsumer); + mTrace("consumer:%ld, encode to raw:%p, row:%p", pConsumer->consumerId, pRaw, pConsumer); return pRaw; } @@ -107,68 +127,76 @@ static SSdbRow *mndConsumerActionDecode(SSdbRaw *pRaw) { goto CONSUME_DECODE_OVER; } - int32_t size = sizeof(SConsumerObj) + TSDB_MAX_COLUMNS * sizeof(SSchema); + int32_t size = sizeof(SMqConsumerObj); SSdbRow *pRow = sdbAllocRow(size); if (pRow == NULL) goto CONSUME_DECODE_OVER; - SConsumerObj *pConsumer = sdbGetRowObj(pRow); + SMqConsumerObj *pConsumer = sdbGetRowObj(pRow); if (pConsumer == NULL) goto CONSUME_DECODE_OVER; int32_t dataPos = 0; - SDB_GET_BINARY(pRaw, dataPos, pConsumer->name, TSDB_TABLE_FNAME_LEN, CONSUME_DECODE_OVER) - SDB_GET_BINARY(pRaw, dataPos, pConsumer->db, TSDB_DB_FNAME_LEN, CONSUME_DECODE_OVER) - SDB_GET_INT64(pRaw, dataPos, &pConsumer->createTime, CONSUME_DECODE_OVER) - SDB_GET_INT64(pRaw, dataPos, &pConsumer->updateTime, CONSUME_DECODE_OVER) - SDB_GET_INT64(pRaw, dataPos, &pConsumer->uid, CONSUME_DECODE_OVER) - /*SDB_GET_INT64(pRaw, pRow, dataPos, &pConsumer->dbUid);*/ - SDB_GET_INT32(pRaw, dataPos, &pConsumer->version, CONSUME_DECODE_OVER) - SDB_GET_RESERVE(pRaw, dataPos, MND_CONSUMER_RESERVE_SIZE, CONSUME_DECODE_OVER) - terrno = 0; + SDB_GET_INT64(pRaw, dataPos, &pConsumer->consumerId, CONSUME_DECODE_OVER); + int32_t len, topicNum; + SDB_GET_INT32(pRaw, dataPos, &len, CONSUME_DECODE_OVER); + SDB_GET_BINARY(pRaw, dataPos, pConsumer->cgroup, len, CONSUME_DECODE_OVER); + SDB_GET_INT32(pRaw, dataPos, &topicNum, CONSUME_DECODE_OVER); + for (int i = 0; i < topicNum; i++) { + int32_t topicLen; + SMqConsumerTopic *pConsumerTopic = malloc(sizeof(SMqConsumerTopic)); + if (pConsumerTopic == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + // TODO + return NULL; + } + /*pConsumerTopic->vgroups = taosArrayInit(topicNum, sizeof(SMqConsumerTopic));*/ + SDB_GET_INT32(pRaw, dataPos, &topicLen, CONSUME_DECODE_OVER); + SDB_GET_BINARY(pRaw, dataPos, pConsumerTopic->name, topicLen, CONSUME_DECODE_OVER); + int32_t vgSize; + SDB_GET_INT32(pRaw, dataPos, &vgSize, CONSUME_DECODE_OVER); + } CONSUME_DECODE_OVER: if (terrno != 0) { - mError("consumer:%s, failed to decode from raw:%p since %s", pConsumer->name, pRaw, terrstr()); + mError("consumer:%ld, failed to decode from raw:%p since %s", pConsumer->consumerId, pRaw, terrstr()); tfree(pRow); return NULL; } - mTrace("consumer:%s, decode from raw:%p, row:%p", pConsumer->name, pRaw, pConsumer); + /*SDB_GET_RESERVE(pRaw, dataPos, MND_CONSUMER_RESERVE_SIZE);*/ + return pRow; } -static int32_t mndConsumerActionInsert(SSdb *pSdb, SConsumerObj *pConsumer) { - mTrace("consumer:%s, perform insert action, row:%p", pConsumer->name, pConsumer); +static int32_t mndConsumerActionInsert(SSdb *pSdb, SMqConsumerObj *pConsumer) { + mTrace("consumer:%ld, perform insert action", pConsumer->consumerId); return 0; } -static int32_t mndConsumerActionDelete(SSdb *pSdb, SConsumerObj *pConsumer) { - mTrace("consumer:%s, perform delete action, row:%p", pConsumer->name, pConsumer); +static int32_t mndConsumerActionDelete(SSdb *pSdb, SMqConsumerObj *pConsumer) { + mTrace("consumer:%ld, perform delete action", pConsumer->consumerId); return 0; } -static int32_t mndConsumerActionUpdate(SSdb *pSdb, SConsumerObj *pOldConsumer, SConsumerObj *pNewConsumer) { - mTrace("consumer:%s, perform update action, old_row:%p new_row:%p", pOldConsumer->name, pOldConsumer, pNewConsumer); - atomic_exchange_32(&pOldConsumer->updateTime, pNewConsumer->updateTime); - atomic_exchange_32(&pOldConsumer->version, pNewConsumer->version); - - taosWLockLatch(&pOldConsumer->lock); +static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, SMqConsumerObj *pNewConsumer) { + mTrace("consumer:%ld, perform update action", pOldConsumer->consumerId); // TODO handle update + /*taosWLockLatch(&pOldConsumer->lock);*/ + /*taosWUnLockLatch(&pOldConsumer->lock);*/ - taosWUnLockLatch(&pOldConsumer->lock); return 0; } -SConsumerObj *mndAcquireConsumer(SMnode *pMnode, int32_t consumerId) { - SSdb *pSdb = pMnode->pSdb; - SConsumerObj *pConsumer = sdbAcquire(pSdb, SDB_CONSUMER, &consumerId); +SMqConsumerObj *mndAcquireConsumer(SMnode *pMnode, int32_t consumerId) { + SSdb *pSdb = pMnode->pSdb; + SMqConsumerObj *pConsumer = sdbAcquire(pSdb, SDB_CONSUMER, &consumerId); if (pConsumer == NULL) { /*terrno = TSDB_CODE_MND_CONSUMER_NOT_EXIST;*/ } return pConsumer; } -void mndReleaseConsumer(SMnode *pMnode, SConsumerObj *pConsumer) { +void mndReleaseConsumer(SMnode *pMnode, SMqConsumerObj *pConsumer) { SSdb *pSdb = pMnode->pSdb; sdbRelease(pSdb, pConsumer); } @@ -178,26 +206,196 @@ static int32_t mndProcessSubscribeReq(SMnodeMsg *pMsg) { char *msgStr = pMsg->rpcMsg.pCont; SCMSubscribeReq *pSubscribe; tDeserializeSCMSubscribeReq(msgStr, pSubscribe); - // add consumerGroupId -> list to sdb - // add consumerId -> list to sdb - // add consumer -> list to sdb + int64_t consumerId = pSubscribe->consumerId; + char *consumerGroup = pSubscribe->consumerGroup; + int32_t cgroupLen = strlen(consumerGroup); + + SArray *newSub = NULL; + int newTopicNum = pSubscribe->topicNum; + if (newTopicNum) { + newSub = taosArrayInit(newTopicNum, sizeof(SMqConsumerTopic)); + } + for (int i = 0; i < newTopicNum; i++) { + char *newTopicName = taosArrayGetP(newSub, i); + SMqConsumerTopic *pConsumerTopic = malloc(sizeof(SMqConsumerTopic)); + if (pConsumerTopic == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + // TODO: free + return -1; + } + strcpy(pConsumerTopic->name, newTopicName); + pConsumerTopic->vgroups = tdListNew(sizeof(int64_t)); + taosArrayPush(newSub, pConsumerTopic); + free(pConsumerTopic); + } + taosArraySortString(newSub, taosArrayCompareString); + + SArray *oldSub = NULL; + int oldTopicNum = 0; + SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, consumerId); + if (pConsumer == NULL) { + // create consumer + pConsumer = malloc(sizeof(SMqConsumerObj)); + if (pConsumer == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + pConsumer->consumerId = consumerId; + strcpy(pConsumer->cgroup, consumerGroup); + + } else { + oldSub = pConsumer->topics; + oldTopicNum = taosArrayGetSize(oldSub); + } + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); + if (pTrans == NULL) { + return -1; + } + + int i = 0, j = 0; + while (i < newTopicNum || j < oldTopicNum) { + SMqConsumerTopic *pOldTopic = NULL; + SMqConsumerTopic *pNewTopic = NULL; + if (i >= newTopicNum) { + // encode unset topic msg to all vnodes related to that topic + pOldTopic = taosArrayGet(oldSub, j); + j++; + } else if (j >= oldTopicNum) { + pNewTopic = taosArrayGet(newSub, i); + i++; + } else { + pNewTopic = taosArrayGet(newSub, i); + pOldTopic = taosArrayGet(oldSub, j); + + char *newName = pNewTopic->name; + char *oldName = pOldTopic->name; + int comp = compareLenPrefixedStr(newName, oldName); + if (comp == 0) { + // do nothing + pOldTopic = pNewTopic = NULL; + i++; + j++; + continue; + } else if (comp < 0) { + pOldTopic = NULL; + i++; + } else { + pNewTopic = NULL; + j++; + } + } + + if (pOldTopic != NULL) { + ASSERT(pNewTopic == NULL); + char *oldTopicName = pOldTopic->name; + SList *vgroups = pOldTopic->vgroups; + SListIter iter; + tdListInitIter(vgroups, &iter, TD_LIST_FORWARD); + SListNode *pn; + + SMqTopicObj *pTopic = mndAcquireTopic(pMnode, oldTopicName); + ASSERT(pTopic != NULL); + SMqCGroup *pGroup = taosHashGet(pTopic->cgroups, consumerGroup, cgroupLen); + while ((pn = tdListNext(&iter)) != NULL) { + int32_t vgId = *(int64_t *)pn->data; + SVgObj *pVgObj = mndAcquireVgroup(pMnode, vgId); + // TODO release + if (pVgObj == NULL) { + // TODO handle error + continue; + } + // acquire and get epset + void *pMqVgSetReq = mndBuildMqVGroupSetReq(pMnode, oldTopicName, vgId, consumerId, consumerGroup); + // TODO:serialize + if (pMsg == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + STransAction action = {0}; + action.epSet = mndGetVgroupEpset(pMnode, pVgObj); + action.pCont = pMqVgSetReq; + action.contLen = 0; // TODO + action.msgType = TDMT_VND_MQ_SET_CONN; + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + free(pMqVgSetReq); + mndTransDrop(pTrans); + // TODO free + return -1; + } + } + taosHashRemove(pTopic->cgroups, consumerGroup, cgroupLen); + mndReleaseTopic(pMnode, pTopic); + + } else if (pNewTopic != NULL) { + ASSERT(pOldTopic == NULL); + + char *newTopicName = pNewTopic->name; + SMqTopicObj *pTopic = mndAcquireTopic(pMnode, newTopicName); + ASSERT(pTopic != NULL); + + SMqCGroup *pGroup = taosHashGet(pTopic->cgroups, consumerGroup, cgroupLen); + if (pGroup == NULL) { + // add new group + pGroup = malloc(sizeof(SMqCGroup)); + if (pGroup == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + pGroup->consumerIds = tdListNew(sizeof(int64_t)); + if (pGroup->consumerIds == NULL) { + free(pGroup); + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + pGroup->status = 0; + // add into cgroups + taosHashPut(pTopic->cgroups, consumerGroup, cgroupLen, pGroup, sizeof(SMqCGroup)); + } + + // put the consumer into list + // rebalance will be triggered by timer + tdListAppend(pGroup->consumerIds, &consumerId); + + SSdbRaw *pTopicRaw = mndTopicActionEncode(pTopic); + sdbSetRawStatus(pTopicRaw, SDB_STATUS_READY); + // TODO: error handling + mndTransAppendRedolog(pTrans, pTopicRaw); + + mndReleaseTopic(pMnode, pTopic); + + } else { + ASSERT(0); + } + } + // destroy old sub + taosArrayDestroy(oldSub); + // put new sub into consumerobj + pConsumer->topics = newSub; + + // persist consumerObj + SSdbRaw *pConsumerRaw = mndConsumerActionEncode(pConsumer); + sdbSetRawStatus(pConsumerRaw, SDB_STATUS_READY); + // TODO: error handling + mndTransAppendRedolog(pTrans, pConsumerRaw); + + if (mndTransPrepare(pMnode, pTrans) != 0) { + mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); + mndTransDrop(pTrans); + mndReleaseConsumer(pMnode, pConsumer); + return -1; + } + + // TODO: free memory + mndTransDrop(pTrans); + mndReleaseConsumer(pMnode, pConsumer); return 0; } -static int32_t mndProcessSubscribeRsp(SMnodeMsg *pMsg) { return 0; } - -static int32_t mndProcessSubscribeInternalReq(SMnodeMsg *pMsg) { return 0; } - static int32_t mndProcessSubscribeInternalRsp(SMnodeMsg *pMsg) { return 0; } -static int32_t mndProcessDropConsumerInRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); - return 0; -} - static int32_t mndProcessConsumerMetaMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - STableInfoMsg *pInfo = pMsg->rpcMsg.pCont; + STableInfoReq *pInfo = pMsg->rpcMsg.pCont; mDebug("consumer:%s, start to retrieve meta", pInfo->tableFname); @@ -219,9 +417,9 @@ static int32_t mndProcessConsumerMetaMsg(SMnodeMsg *pMsg) { taosRLockLatch(&pConsumer->lock); int32_t totalCols = pConsumer->numOfColumns + pConsumer->numOfTags; - int32_t contLen = sizeof(STableMetaMsg) + totalCols * sizeof(SSchema); + int32_t contLen = sizeof(STableMetaRsp) + totalCols * sizeof(SSchema); - STableMetaMsg *pMeta = rpcMallocCont(contLen); + STableMetaRsp *pMeta = rpcMallocCont(contLen); if (pMeta == NULL) { taosRUnLockLatch(&pConsumer->lock); mndReleaseDb(pMnode, pDb); @@ -272,13 +470,11 @@ static int32_t mndGetNumOfConsumers(SMnode *pMnode, char *dbName, int32_t *pNumO int32_t numOfConsumers = 0; void *pIter = NULL; while (1) { - SConsumerObj *pConsumer = NULL; + SMqConsumerObj *pConsumer = NULL; pIter = sdbFetch(pSdb, SDB_CONSUMER, pIter, (void **)&pConsumer); if (pIter == NULL) break; - if (strcmp(pConsumer->db, dbName) == 0) { - numOfConsumers++; - } + numOfConsumers++; sdbRelease(pSdb, pConsumer); } @@ -287,7 +483,7 @@ static int32_t mndGetNumOfConsumers(SMnode *pMnode, char *dbName, int32_t *pNumO return 0; } -static int32_t mndGetConsumerMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { +static int32_t mndGetConsumerMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta) { SMnode *pMnode = pMsg->pMnode; SSdb *pSdb = pMnode->pSdb; @@ -337,57 +533,6 @@ static int32_t mndGetConsumerMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMs return 0; } -static int32_t mndRetrieveConsumer(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; - SSdb *pSdb = pMnode->pSdb; - int32_t numOfRows = 0; - SConsumerObj *pConsumer = NULL; - int32_t cols = 0; - char *pWrite; - char prefix[64] = {0}; - - tstrncpy(prefix, pShow->db, 64); - strcat(prefix, TS_PATH_DELIMITER); - int32_t prefixLen = (int32_t)strlen(prefix); - - while (numOfRows < rows) { - pShow->pIter = sdbFetch(pSdb, SDB_CONSUMER, pShow->pIter, (void **)&pConsumer); - if (pShow->pIter == NULL) break; - - if (strncmp(pConsumer->name, prefix, prefixLen) != 0) { - sdbRelease(pSdb, pConsumer); - continue; - } - - cols = 0; - - char consumerName[TSDB_TABLE_NAME_LEN] = {0}; - tstrncpy(consumerName, pConsumer->name + prefixLen, TSDB_TABLE_NAME_LEN); - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - STR_TO_VARSTR(pWrite, consumerName); - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int64_t *)pWrite = pConsumer->createTime; - cols++; - - /*pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;*/ - /**(int32_t *)pWrite = pConsumer->numOfColumns;*/ - /*cols++;*/ - - /*pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;*/ - /**(int32_t *)pWrite = pConsumer->numOfTags;*/ - /*cols++;*/ - - numOfRows++; - sdbRelease(pSdb, pConsumer); - } - - pShow->numOfReads += numOfRows; - mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); - return numOfRows; -} - static void mndCancelGetNextConsumer(SMnode *pMnode, void *pIter) { SSdb *pSdb = pMnode->pSdb; sdbCancelFetch(pSdb, pIter); diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index 410368f130..f2f8931aa1 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -28,15 +28,15 @@ static SSdbRaw *mndDbActionEncode(SDbObj *pDb); static SSdbRow *mndDbActionDecode(SSdbRaw *pRaw); static int32_t mndDbActionInsert(SSdb *pSdb, SDbObj *pDb); static int32_t mndDbActionDelete(SSdb *pSdb, SDbObj *pDb); -static int32_t mndDbActionUpdate(SSdb *pSdb, SDbObj *pOldDb, SDbObj *pNewDb); -static int32_t mndProcessCreateDbMsg(SMnodeMsg *pMsg); -static int32_t mndProcessAlterDbMsg(SMnodeMsg *pMsg); -static int32_t mndProcessDropDbMsg(SMnodeMsg *pMsg); -static int32_t mndProcessUseDbMsg(SMnodeMsg *pMsg); -static int32_t mndProcessSyncDbMsg(SMnodeMsg *pMsg); -static int32_t mndProcessCompactDbMsg(SMnodeMsg *pMsg); -static int32_t mndGetDbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveDbs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndDbActionUpdate(SSdb *pSdb, SDbObj *pOld, SDbObj *pNew); +static int32_t mndProcessCreateDbReq(SMnodeMsg *pReq); +static int32_t mndProcessAlterDbReq(SMnodeMsg *pReq); +static int32_t mndProcessDropDbReq(SMnodeMsg *pReq); +static int32_t mndProcessUseDbReq(SMnodeMsg *pReq); +static int32_t mndProcessSyncDbReq(SMnodeMsg *pReq); +static int32_t mndProcessCompactDbReq(SMnodeMsg *pReq); +static int32_t mndGetDbMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveDbs(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextDb(SMnode *pMnode, void *pIter); int32_t mndInitDb(SMnode *pMnode) { @@ -48,12 +48,12 @@ int32_t mndInitDb(SMnode *pMnode) { .updateFp = (SdbUpdateFp)mndDbActionUpdate, .deleteFp = (SdbDeleteFp)mndDbActionDelete}; - mndSetMsgHandle(pMnode, TDMT_MND_CREATE_DB, mndProcessCreateDbMsg); - mndSetMsgHandle(pMnode, TDMT_MND_ALTER_DB, mndProcessAlterDbMsg); - mndSetMsgHandle(pMnode, TDMT_MND_DROP_DB, mndProcessDropDbMsg); - mndSetMsgHandle(pMnode, TDMT_MND_USE_DB, mndProcessUseDbMsg); - mndSetMsgHandle(pMnode, TDMT_MND_SYNC_DB, mndProcessSyncDbMsg); - mndSetMsgHandle(pMnode, TDMT_MND_COMPACT_DB, mndProcessCompactDbMsg); + mndSetMsgHandle(pMnode, TDMT_MND_CREATE_DB, mndProcessCreateDbReq); + mndSetMsgHandle(pMnode, TDMT_MND_ALTER_DB, mndProcessAlterDbReq); + mndSetMsgHandle(pMnode, TDMT_MND_DROP_DB, mndProcessDropDbReq); + mndSetMsgHandle(pMnode, TDMT_MND_USE_DB, mndProcessUseDbReq); + mndSetMsgHandle(pMnode, TDMT_MND_SYNC_DB, mndProcessSyncDbReq); + mndSetMsgHandle(pMnode, TDMT_MND_COMPACT_DB, mndProcessCompactDbReq); mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_DB, mndGetDbMeta); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_DB, mndRetrieveDbs); @@ -182,19 +182,19 @@ static int32_t mndDbActionDelete(SSdb *pSdb, SDbObj *pDb) { return 0; } -static int32_t mndDbActionUpdate(SSdb *pSdb, SDbObj *pOldDb, SDbObj *pNewDb) { - mTrace("db:%s, perform update action, old_row:%p new_row:%p", pOldDb->name, pOldDb, pNewDb); - pOldDb->updateTime = pNewDb->updateTime; - pOldDb->cfgVersion = pNewDb->cfgVersion; - pOldDb->vgVersion = pNewDb->vgVersion; - memcpy(&pOldDb->cfg, &pNewDb->cfg, sizeof(SDbCfg)); +static int32_t mndDbActionUpdate(SSdb *pSdb, SDbObj *pOld, SDbObj *pNew) { + mTrace("db:%s, perform update action, old row:%p new row:%p", pOld->name, pOld, pNew); + pOld->updateTime = pNew->updateTime; + pOld->cfgVersion = pNew->cfgVersion; + pOld->vgVersion = pNew->vgVersion; + memcpy(&pOld->cfg, &pNew->cfg, sizeof(SDbCfg)); return 0; } SDbObj *mndAcquireDb(SMnode *pMnode, char *db) { SSdb *pSdb = pMnode->pSdb; SDbObj *pDb = sdbAcquire(pSdb, SDB_DB, db); - if (pDb == NULL) { + if (pDb == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) { terrno = TSDB_CODE_MND_DB_NOT_EXIST; } return pDb; @@ -331,14 +331,15 @@ static int32_t mndSetCreateDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj action.epSet = mndGetDnodeEpset(pDnode); mndReleaseDnode(pMnode, pDnode); - SCreateVnodeMsg *pMsg = mndBuildCreateVnodeMsg(pMnode, pDnode, pDb, pVgroup); - if (pMsg == NULL) return -1; + SCreateVnodeReq *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup); + if (pReq == NULL) return -1; - action.pCont = pMsg; - action.contLen = sizeof(SCreateVnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SCreateVnodeReq); action.msgType = TDMT_DND_CREATE_VNODE; + action.acceptableCode = TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } } @@ -360,14 +361,15 @@ static int32_t mndSetCreateDbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj action.epSet = mndGetDnodeEpset(pDnode); mndReleaseDnode(pMnode, pDnode); - SDropVnodeMsg *pMsg = mndBuildDropVnodeMsg(pMnode, pDnode, pDb, pVgroup); - if (pMsg == NULL) return -1; + SDropVnodeReq *pReq = mndBuildDropVnodeReq(pMnode, pDnode, pDb, pVgroup); + if (pReq == NULL) return -1; - action.pCont = pMsg; - action.contLen = sizeof(SDropVnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDropVnodeReq); action.msgType = TDMT_DND_DROP_VNODE; + action.acceptableCode = TSDB_CODE_DND_VNODE_NOT_DEPLOYED; if (mndTransAppendUndoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } } @@ -376,7 +378,7 @@ static int32_t mndSetCreateDbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj return 0; } -static int32_t mndCreateDb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDbMsg *pCreate, SUserObj *pUser) { +static int32_t mndCreateDb(SMnode *pMnode, SMnodeMsg *pReq, SCreateDbReq *pCreate, SUserObj *pUser) { SDbObj dbObj = {0}; memcpy(dbObj.name, pCreate->db, TSDB_DB_FNAME_LEN); memcpy(dbObj.acct, pUser->acct, TSDB_USER_LEN); @@ -425,43 +427,17 @@ static int32_t mndCreateDb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDbMsg *pCreat } int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("db:%s, failed to create since %s", pCreate->db, terrstr()); - goto CREATE_DB_OVER; - } + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); + if (pTrans == NULL) goto CREATE_DB_OVER; mDebug("trans:%d, used to create db:%s", pTrans->id, pCreate->db); - if (mndSetCreateDbRedoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto CREATE_DB_OVER; - } - - if (mndSetCreateDbUndoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) { - mError("trans:%d, failed to set undo log since %s", pTrans->id, terrstr()); - goto CREATE_DB_OVER; - } - - if (mndSetCreateDbCommitLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto CREATE_DB_OVER; - } - - if (mndSetCreateDbRedoActions(pMnode, pTrans, &dbObj, pVgroups) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto CREATE_DB_OVER; - } - - if (mndSetCreateDbUndoActions(pMnode, pTrans, &dbObj, pVgroups) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto CREATE_DB_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto CREATE_DB_OVER; - } + if (mndSetCreateDbRedoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto CREATE_DB_OVER; + if (mndSetCreateDbUndoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto CREATE_DB_OVER; + if (mndSetCreateDbCommitLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto CREATE_DB_OVER; + if (mndSetCreateDbRedoActions(pMnode, pTrans, &dbObj, pVgroups) != 0) goto CREATE_DB_OVER; + if (mndSetCreateDbUndoActions(pMnode, pTrans, &dbObj, pVgroups) != 0) goto CREATE_DB_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto CREATE_DB_OVER; code = 0; @@ -471,9 +447,9 @@ CREATE_DB_OVER: return code; } -static int32_t mndProcessCreateDbMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SCreateDbMsg *pCreate = pMsg->rpcMsg.pCont; +static int32_t mndProcessCreateDbReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SCreateDbReq *pCreate = pReq->rpcMsg.pCont; pCreate->numOfVgroups = htonl(pCreate->numOfVgroups); pCreate->cacheBlockSize = htonl(pCreate->cacheBlockSize); @@ -502,13 +478,13 @@ static int32_t mndProcessCreateDbMsg(SMnodeMsg *pMsg) { } } - SUserObj *pOperUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pOperUser = mndAcquireUser(pMnode, pReq->user); if (pOperUser == NULL) { mError("db:%s, failed to create since %s", pCreate->db, terrstr()); return -1; } - int32_t code = mndCreateDb(pMnode, pMsg, pCreate, pOperUser); + int32_t code = mndCreateDb(pMnode, pReq, pCreate, pOperUser); mndReleaseUser(pMnode, pOperUser); if (code != 0) { @@ -519,7 +495,7 @@ static int32_t mndProcessCreateDbMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndSetDbCfgFromAlterDbMsg(SDbObj *pDb, SAlterDbMsg *pAlter) { +static int32_t mndSetDbCfgFromAlterDbMsg(SDbObj *pDb, SAlterDbReq *pAlter) { terrno = TSDB_CODE_MND_DB_OPTION_UNCHANGED; if (pAlter->totalBlocks >= 0 && pAlter->totalBlocks != pDb->cfg.totalBlocks) { @@ -565,8 +541,8 @@ static int32_t mndSetDbCfgFromAlterDbMsg(SDbObj *pDb, SAlterDbMsg *pAlter) { return terrno; } -static int32_t mndSetUpdateDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb) { - SSdbRaw *pRedoRaw = mndDbActionEncode(pOldDb); +static int32_t mndSetUpdateDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pOld, SDbObj *pNew) { + SSdbRaw *pRedoRaw = mndDbActionEncode(pOld); if (pRedoRaw == NULL) return -1; if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1; if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_UPDATING) != 0) return -1; @@ -574,8 +550,8 @@ static int32_t mndSetUpdateDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pO return 0; } -static int32_t mndSetUpdateDbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb) { - SSdbRaw *pCommitRaw = mndDbActionEncode(pNewDb); +static int32_t mndSetUpdateDbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pOld, SDbObj *pNew) { + SSdbRaw *pCommitRaw = mndDbActionEncode(pNew); if (pCommitRaw == NULL) return -1; if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1; if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1; @@ -593,14 +569,14 @@ static int32_t mndBuildUpdateVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj action.epSet = mndGetDnodeEpset(pDnode); mndReleaseDnode(pMnode, pDnode); - SAlterVnodeMsg *pMsg = (SAlterVnodeMsg *)mndBuildCreateVnodeMsg(pMnode, pDnode, pDb, pVgroup); - if (pMsg == NULL) return -1; + SAlterVnodeReq *pReq = (SAlterVnodeReq *)mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup); + if (pReq == NULL) return -1; - action.pCont = pMsg; - action.contLen = sizeof(SAlterVnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SAlterVnodeReq); action.msgType = TDMT_DND_ALTER_VNODE; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } } @@ -608,7 +584,7 @@ static int32_t mndBuildUpdateVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj return 0; } -static int32_t mndSetUpdateDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb) { +static int32_t mndSetUpdateDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pOld, SDbObj *pNew) { SSdb *pSdb = pMnode->pSdb; void *pIter = NULL; @@ -617,8 +593,8 @@ static int32_t mndSetUpdateDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup); if (pIter == NULL) break; - if (pVgroup->dbUid == pNewDb->uid) { - if (mndBuildUpdateVgroupAction(pMnode, pTrans, pNewDb, pVgroup) != 0) { + if (pVgroup->dbUid == pNew->uid) { + if (mndBuildUpdateVgroupAction(pMnode, pTrans, pNew, pVgroup) != 0) { sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pVgroup); return -1; @@ -631,27 +607,27 @@ static int32_t mndSetUpdateDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj return 0; } -static int32_t mndUpdateDb(SMnode *pMnode, SMnodeMsg *pMsg, SDbObj *pOldDb, SDbObj *pNewDb) { +static int32_t mndUpdateDb(SMnode *pMnode, SMnodeMsg *pReq, SDbObj *pOld, SDbObj *pNew) { int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg); if (pTrans == NULL) { - mError("db:%s, failed to update since %s", pOldDb->name, terrstr()); + mError("db:%s, failed to update since %s", pOld->name, terrstr()); return terrno; } - mDebug("trans:%d, used to update db:%s", pTrans->id, pOldDb->name); + mDebug("trans:%d, used to update db:%s", pTrans->id, pOld->name); - if (mndSetUpdateDbRedoLogs(pMnode, pTrans, pOldDb, pNewDb) != 0) { + if (mndSetUpdateDbRedoLogs(pMnode, pTrans, pOld, pNew) != 0) { mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); goto UPDATE_DB_OVER; } - if (mndSetUpdateDbCommitLogs(pMnode, pTrans, pOldDb, pNewDb) != 0) { + if (mndSetUpdateDbCommitLogs(pMnode, pTrans, pOld, pNew) != 0) { mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); goto UPDATE_DB_OVER; } - if (mndSetUpdateDbRedoActions(pMnode, pTrans, pOldDb, pNewDb) != 0) { + if (mndSetUpdateDbRedoActions(pMnode, pTrans, pOld, pNew) != 0) { mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); goto UPDATE_DB_OVER; } @@ -668,9 +644,9 @@ UPDATE_DB_OVER: return code; } -static int32_t mndProcessAlterDbMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SAlterDbMsg *pAlter = pMsg->rpcMsg.pCont; +static int32_t mndProcessAlterDbReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SAlterDbReq *pAlter = pReq->rpcMsg.pCont; pAlter->totalBlocks = htonl(pAlter->totalBlocks); pAlter->daysToKeep0 = htonl(pAlter->daysToKeep0); pAlter->daysToKeep1 = htonl(pAlter->daysToKeep1); @@ -697,7 +673,7 @@ static int32_t mndProcessAlterDbMsg(SMnodeMsg *pMsg) { dbObj.cfgVersion++; dbObj.updateTime = taosGetTimestampMs(); - code = mndUpdateDb(pMnode, pMsg, pDb, &dbObj); + code = mndUpdateDb(pMnode, pReq, pDb, &dbObj); mndReleaseDb(pMnode, pDb); if (code != 0) { @@ -757,14 +733,15 @@ static int32_t mndBuildDropVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj * action.epSet = mndGetDnodeEpset(pDnode); mndReleaseDnode(pMnode, pDnode); - SDropVnodeMsg *pMsg = mndBuildDropVnodeMsg(pMnode, pDnode, pDb, pVgroup); - if (pMsg == NULL) return -1; + SDropVnodeReq *pReq = mndBuildDropVnodeReq(pMnode, pDnode, pDb, pVgroup); + if (pReq == NULL) return -1; - action.pCont = pMsg; - action.contLen = sizeof(SCreateVnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SCreateVnodeReq); action.msgType = TDMT_DND_DROP_VNODE; + action.acceptableCode = TSDB_CODE_DND_VNODE_NOT_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } } @@ -795,35 +772,17 @@ static int32_t mndSetDropDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *p return 0; } -static int32_t mndDropDb(SMnode *pMnode, SMnodeMsg *pMsg, SDbObj *pDb) { +static int32_t mndDropDb(SMnode *pMnode, SMnodeMsg *pReq, SDbObj *pDb) { int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("db:%s, failed to drop since %s", pDb->name, terrstr()); - return -1; - } + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg); + if (pTrans == NULL) goto DROP_DB_OVER; mDebug("trans:%d, used to drop db:%s", pTrans->id, pDb->name); - if (mndSetDropDbRedoLogs(pMnode, pTrans, pDb) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto DROP_DB_OVER; - } - - if (mndSetDropDbCommitLogs(pMnode, pTrans, pDb) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto DROP_DB_OVER; - } - - if (mndSetDropDbRedoActions(pMnode, pTrans, pDb) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto DROP_DB_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto DROP_DB_OVER; - } + if (mndSetDropDbRedoLogs(pMnode, pTrans, pDb) != 0) goto DROP_DB_OVER; + if (mndSetDropDbCommitLogs(pMnode, pTrans, pDb) != 0) goto DROP_DB_OVER; + if (mndSetDropDbRedoActions(pMnode, pTrans, pDb) != 0) goto DROP_DB_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_DB_OVER; code = 0; @@ -832,9 +791,9 @@ DROP_DB_OVER: return code; } -static int32_t mndProcessDropDbMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SDropDbMsg *pDrop = pMsg->rpcMsg.pCont; +static int32_t mndProcessDropDbReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SDropDbReq *pDrop = pReq->rpcMsg.pCont; mDebug("db:%s, start to drop", pDrop->db); @@ -850,7 +809,7 @@ static int32_t mndProcessDropDbMsg(SMnodeMsg *pMsg) { } } - int32_t code = mndDropDb(pMnode, pMsg, pDb); + int32_t code = mndDropDb(pMnode, pReq, pDb); mndReleaseDb(pMnode, pDb); if (code != 0) { @@ -861,22 +820,23 @@ static int32_t mndProcessDropDbMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessUseDbMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndProcessUseDbReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; - SUseDbMsg *pUse = pMsg->rpcMsg.pCont; + SUseDbReq *pUse = pReq->rpcMsg.pCont; pUse->vgVersion = htonl(pUse->vgVersion); SDbObj *pDb = mndAcquireDb(pMnode, pUse->db); if (pDb == NULL) { terrno = TSDB_CODE_MND_DB_NOT_EXIST; - mError("db:%s, failed to process use db msg since %s", pUse->db, terrstr()); + mError("db:%s, failed to process use db req since %s", pUse->db, terrstr()); return -1; } int32_t contLen = sizeof(SUseDbRsp) + pDb->cfg.numOfVgroups * sizeof(SVgroupInfo); SUseDbRsp *pRsp = rpcMallocCont(contLen); if (pRsp == NULL) { + mndReleaseDb(pMnode, pDb); terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } @@ -898,7 +858,7 @@ static int32_t mndProcessUseDbMsg(SMnodeMsg *pMsg) { pInfo->numOfEps = pVgroup->replica; for (int32_t gid = 0; gid < pVgroup->replica; ++gid) { SVnodeGid *pVgid = &pVgroup->vnodeGid[gid]; - SEpAddrMsg *pEpArrr = &pInfo->epAddr[gid]; + SEpAddr *pEpArrr = &pInfo->epAddr[gid]; SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId); if (pDnode != NULL) { memcpy(pEpArrr->fqdn, pDnode->fqdn, TSDB_FQDN_LEN); @@ -917,23 +877,24 @@ static int32_t mndProcessUseDbMsg(SMnodeMsg *pMsg) { } memcpy(pRsp->db, pDb->name, TSDB_DB_FNAME_LEN); + pRsp->uid = htobe64(pDb->uid); pRsp->vgVersion = htonl(pDb->vgVersion); pRsp->vgNum = htonl(vindex); pRsp->hashMethod = pDb->hashMethod; - pMsg->pCont = pRsp; - pMsg->contLen = contLen; + pReq->pCont = pRsp; + pReq->contLen = contLen; mndReleaseDb(pMnode, pDb); return 0; } -static int32_t mndProcessSyncDbMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SSyncDbMsg *pSync = pMsg->rpcMsg.pCont; +static int32_t mndProcessSyncDbReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SSyncDbReq *pSync = pReq->rpcMsg.pCont; SDbObj *pDb = mndAcquireDb(pMnode, pSync->db); if (pDb == NULL) { - mError("db:%s, failed to process sync db msg since %s", pSync->db, terrstr()); + mError("db:%s, failed to process sync db req since %s", pSync->db, terrstr()); return -1; } @@ -941,12 +902,12 @@ static int32_t mndProcessSyncDbMsg(SMnodeMsg *pMsg) { return 0; } -static int32_t mndProcessCompactDbMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SCompactDbMsg *pCompact = pMsg->rpcMsg.pCont; +static int32_t mndProcessCompactDbReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SCompactDbReq *pCompact = pReq->rpcMsg.pCont; SDbObj *pDb = mndAcquireDb(pMnode, pCompact->db); if (pDb == NULL) { - mError("db:%s, failed to process compact db msg since %s", pCompact->db, terrstr()); + mError("db:%s, failed to process compact db req since %s", pCompact->db, terrstr()); return -1; } @@ -954,8 +915,8 @@ static int32_t mndProcessCompactDbMsg(SMnodeMsg *pMsg) { return 0; } -static int32_t mndGetDbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetDbMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -1095,8 +1056,8 @@ char *mnGetDbStr(char *src) { return pos; } -static int32_t mndRetrieveDbs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveDbs(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; SDbObj *pDb = NULL; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 1d78359015..4bc570c11d 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -45,19 +45,19 @@ static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode); static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw); static int32_t mndDnodeActionInsert(SSdb *pSdb, SDnodeObj *pDnode); static int32_t mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode); -static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOldDnode, SDnodeObj *pNewDnode); +static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOld, SDnodeObj *pNew); -static int32_t mndProcessCreateDnodeMsg(SMnodeMsg *pMsg); -static int32_t mndProcessDropDnodeMsg(SMnodeMsg *pMsg); -static int32_t mndProcessConfigDnodeMsg(SMnodeMsg *pMsg); -static int32_t mndProcessConfigDnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg); +static int32_t mndProcessCreateDnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessDropDnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessConfigDnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessConfigDnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessStatusReq(SMnodeMsg *pReq); -static int32_t mndGetConfigMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveConfigs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndGetConfigMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveConfigs(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextConfig(SMnode *pMnode, void *pIter); -static int32_t mndGetDnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveDnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndGetDnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveDnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextDnode(SMnode *pMnode, void *pIter); int32_t mndInitDnode(SMnode *pMnode) { @@ -70,11 +70,11 @@ int32_t mndInitDnode(SMnode *pMnode) { .updateFp = (SdbUpdateFp)mndDnodeActionUpdate, .deleteFp = (SdbDeleteFp)mndDnodeActionDelete}; - mndSetMsgHandle(pMnode, TDMT_MND_CREATE_DNODE, mndProcessCreateDnodeMsg); - mndSetMsgHandle(pMnode, TDMT_MND_DROP_DNODE, mndProcessDropDnodeMsg); - mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeMsg); + mndSetMsgHandle(pMnode, TDMT_MND_CREATE_DNODE, mndProcessCreateDnodeReq); + mndSetMsgHandle(pMnode, TDMT_MND_DROP_DNODE, mndProcessDropDnodeReq); + mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq); mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp); - mndSetMsgHandle(pMnode, TDMT_MND_STATUS, mndProcessStatusMsg); + mndSetMsgHandle(pMnode, TDMT_MND_STATUS, mndProcessStatusReq); mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_VARIABLES, mndGetConfigMeta); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_VARIABLES, mndRetrieveConfigs); @@ -182,9 +182,9 @@ static int32_t mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode) { return 0; } -static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOldDnode, SDnodeObj *pNewDnode) { - mTrace("dnode:%d, perform update action, old_row:%p new_row:%p", pOldDnode->id, pOldDnode, pNewDnode); - pOldDnode->updateTime = pNewDnode->updateTime; +static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOld, SDnodeObj *pNew) { + mTrace("dnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew); + pOld->updateTime = pNew->updateTime; return 0; } @@ -244,22 +244,22 @@ bool mndIsDnodeOnline(SMnode *pMnode, SDnodeObj *pDnode, int64_t curMs) { return true; } -static void mndGetDnodeData(SMnode *pMnode, SDnodeEps *pEps, int32_t numOfEps) { +static void mndGetDnodeData(SMnode *pMnode, SDnodeEps *pEps, int32_t maxEps) { SSdb *pSdb = pMnode->pSdb; - int32_t i = 0; + int32_t numOfEps = 0; void *pIter = NULL; while (1) { SDnodeObj *pDnode = NULL; pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode); if (pIter == NULL) break; - if (i >= numOfEps) { + if (numOfEps >= maxEps) { sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pDnode); break; } - SDnodeEp *pEp = &pEps->eps[i]; + SDnodeEp *pEp = &pEps->eps[numOfEps]; pEp->id = htonl(pDnode->id); pEp->port = htons(pDnode->port); memcpy(pEp->fqdn, pDnode->fqdn, TSDB_FQDN_LEN); @@ -267,11 +267,11 @@ static void mndGetDnodeData(SMnode *pMnode, SDnodeEps *pEps, int32_t numOfEps) { if (mndIsMnode(pMnode, pDnode->id)) { pEp->isMnode = 1; } - i++; + numOfEps++; sdbRelease(pSdb, pDnode); } - pEps->num = htonl(i); + pEps->num = htonl(numOfEps); } static int32_t mndCheckClusterCfgPara(SMnode *pMnode, const SClusterCfg *pCfg) { @@ -299,8 +299,9 @@ static int32_t mndCheckClusterCfgPara(SMnode *pMnode, const SClusterCfg *pCfg) { return 0; } -static void mndParseStatusMsg(SStatusMsg *pStatus) { +static void mndParseStatusMsg(SStatusReq *pStatus) { pStatus->sver = htonl(pStatus->sver); + pStatus->dver = htobe64(pStatus->dver); pStatus->dnodeId = htonl(pStatus->dnodeId); pStatus->clusterId = htobe64(pStatus->clusterId); pStatus->rebootTime = htobe64(pStatus->rebootTime); @@ -309,11 +310,19 @@ static void mndParseStatusMsg(SStatusMsg *pStatus) { pStatus->numOfSupportVnodes = htonl(pStatus->numOfSupportVnodes); pStatus->clusterCfg.statusInterval = htonl(pStatus->clusterCfg.statusInterval); pStatus->clusterCfg.checkTime = htobe64(pStatus->clusterCfg.checkTime); + for (int32_t v = 0; v < pStatus->vnodeLoads.num; ++v) { + SVnodeLoad *pVload = &pStatus->vnodeLoads.data[v]; + pVload->vgId = htonl(pVload->vgId); + pVload->totalStorage = htobe64(pVload->totalStorage); + pVload->compStorage = htobe64(pVload->compStorage); + pVload->pointsWritten = htobe64(pVload->pointsWritten); + pVload->tablesNum = htobe64(pVload->tablesNum); + } } -static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SStatusMsg *pStatus = pMsg->rpcMsg.pCont; +static int32_t mndProcessStatusReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SStatusReq *pStatus = pReq->rpcMsg.pCont; SDnodeObj *pDnode = NULL; int32_t code = -1; @@ -341,9 +350,11 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) { int64_t curMs = taosGetTimestampMs(); bool online = mndIsDnodeOnline(pMnode, pDnode, curMs); - bool needCheckCfg = !(online && pDnode->rebootTime == pStatus->rebootTime); + bool dnodeChanged = (pStatus->dver != sdbGetTableVer(pMnode->pSdb, SDB_DNODE)); + bool reboot = (pDnode->rebootTime != pStatus->rebootTime); + bool needCheck = !online || dnodeChanged || reboot; - if (needCheckCfg) { + if (needCheck) { if (pStatus->sver != pMnode->cfg.sver) { if (pDnode != NULL) { pDnode->offlineReason = DND_REASON_VERSION_NOT_MATCH; @@ -379,7 +390,11 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) { goto PROCESS_STATUS_MSG_OVER; } - mInfo("dnode:%d, from offline to online", pDnode->id); + if (!online) { + mInfo("dnode:%d, from offline to online", pDnode->id); + } else { + mDebug("dnode:%d, send dnode eps", pDnode->id); + } pDnode->rebootTime = pStatus->rebootTime; pDnode->numOfCores = pStatus->numOfCores; @@ -393,12 +408,13 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) { goto PROCESS_STATUS_MSG_OVER; } + pRsp->dver = htobe64(sdbGetTableVer(pMnode->pSdb, SDB_DNODE)); pRsp->dnodeCfg.dnodeId = htonl(pDnode->id); pRsp->dnodeCfg.clusterId = htobe64(pMnode->clusterId); mndGetDnodeData(pMnode, &pRsp->dnodeEps, numOfEps); - pMsg->contLen = contLen; - pMsg->pCont = pRsp; + pReq->contLen = contLen; + pReq->pCont = pRsp; } pDnode->lastAccessTime = curMs; @@ -409,7 +425,7 @@ PROCESS_STATUS_MSG_OVER: return code; } -static int32_t mndCreateDnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDnodeMsg *pCreate) { +static int32_t mndCreateDnode(SMnode *pMnode, SMnodeMsg *pReq, SCreateDnodeReq *pCreate) { SDnodeObj dnodeObj = {0}; dnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_DNODE); dnodeObj.createdTime = taosGetTimestampMs(); @@ -418,7 +434,7 @@ static int32_t mndCreateDnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDnodeMsg * memcpy(dnodeObj.fqdn, pCreate->fqdn, TSDB_FQDN_LEN); snprintf(dnodeObj.ep, TSDB_EP_LEN, "%s:%u", dnodeObj.fqdn, dnodeObj.port); - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg); + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); if (pTrans == NULL) { mError("dnode:%s, failed to create since %s", dnodeObj.ep, terrstr()); return -1; @@ -443,9 +459,9 @@ static int32_t mndCreateDnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDnodeMsg * return 0; } -static int32_t mndProcessCreateDnodeMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SCreateDnodeMsg *pCreate = pMsg->rpcMsg.pCont; +static int32_t mndProcessCreateDnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SCreateDnodeReq *pCreate = pReq->rpcMsg.pCont; pCreate->port = htonl(pCreate->port); mDebug("dnode:%s:%d, start to create", pCreate->fqdn, pCreate->port); @@ -465,7 +481,7 @@ static int32_t mndProcessCreateDnodeMsg(SMnodeMsg *pMsg) { return -1; } - int32_t code = mndCreateDnode(pMnode, pMsg, pCreate); + int32_t code = mndCreateDnode(pMnode, pReq, pCreate); if (code != 0) { mError("dnode:%s:%d, failed to create since %s", pCreate->fqdn, pCreate->port, terrstr()); @@ -475,8 +491,8 @@ static int32_t mndProcessCreateDnodeMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndDropDnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode) { - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg); +static int32_t mndDropDnode(SMnode *pMnode, SMnodeMsg *pReq, SDnodeObj *pDnode) { + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); if (pTrans == NULL) { mError("dnode:%d, failed to drop since %s", pDnode->id, terrstr()); return -1; @@ -501,9 +517,9 @@ static int32_t mndDropDnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode) return 0; } -static int32_t mndProcessDropDnodeMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SDropDnodeMsg *pDrop = pMsg->rpcMsg.pCont; +static int32_t mndProcessDropDnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SDropDnodeReq *pDrop = pReq->rpcMsg.pCont; pDrop->dnodeId = htonl(pDrop->dnodeId); mDebug("dnode:%d, start to drop", pDrop->dnodeId); @@ -521,7 +537,7 @@ static int32_t mndProcessDropDnodeMsg(SMnodeMsg *pMsg) { return -1; } - int32_t code = mndDropDnode(pMnode, pMsg, pDnode); + int32_t code = mndDropDnode(pMnode, pReq, pDnode); if (code != 0) { mndReleaseDnode(pMnode, pDnode); mError("dnode:%d, failed to drop since %s", pDrop->dnodeId, terrstr()); @@ -532,9 +548,9 @@ static int32_t mndProcessDropDnodeMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessConfigDnodeMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SCfgDnodeMsg *pCfg = pMsg->rpcMsg.pCont; +static int32_t mndProcessConfigDnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMCfgDnodeReq *pCfg = pReq->rpcMsg.pCont; pCfg->dnodeId = htonl(pCfg->dnodeId); SDnodeObj *pDnode = mndAcquireDnode(pMnode, pCfg->dnodeId); @@ -547,26 +563,26 @@ static int32_t mndProcessConfigDnodeMsg(SMnodeMsg *pMsg) { SEpSet epSet = mndGetDnodeEpset(pDnode); mndReleaseDnode(pMnode, pDnode); - SCfgDnodeMsg *pCfgDnode = rpcMallocCont(sizeof(SCfgDnodeMsg)); + SDCfgDnodeReq *pCfgDnode = rpcMallocCont(sizeof(SDCfgDnodeReq)); pCfgDnode->dnodeId = htonl(pCfg->dnodeId); memcpy(pCfgDnode->config, pCfg->config, TSDB_DNODE_CONFIG_LEN); SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pCfgDnode, - .contLen = sizeof(SCfgDnodeMsg), - .ahandle = pMsg->rpcMsg.ahandle}; + .contLen = sizeof(SDCfgDnodeReq), + .ahandle = pReq->rpcMsg.ahandle}; mInfo("dnode:%d, app:%p config:%s req send to dnode", pCfg->dnodeId, rpcMsg.ahandle, pCfg->config); - mndSendMsgToDnode(pMnode, &epSet, &rpcMsg); + mndSendReqToDnode(pMnode, &epSet, &rpcMsg); return 0; } -static int32_t mndProcessConfigDnodeRsp(SMnodeMsg *pMsg) { - mInfo("app:%p config rsp from dnode", pMsg->rpcMsg.ahandle); +static int32_t mndProcessConfigDnodeRsp(SMnodeMsg *pRsp) { + mInfo("app:%p config rsp from dnode", pRsp->rpcMsg.ahandle); } -static int32_t mndGetConfigMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { +static int32_t mndGetConfigMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { int32_t cols = 0; SSchema *pSchema = pMeta->pSchema; @@ -597,8 +613,8 @@ static int32_t mndGetConfigMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg return 0; } -static int32_t mndRetrieveConfigs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveConfigs(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; int32_t numOfRows = 0; char *cfgOpts[TSDB_CONFIG_NUMBER] = {0}; char cfgVals[TSDB_CONFIG_NUMBER][TSDB_CONIIG_VALUE_LEN + 1] = {0}; @@ -640,8 +656,8 @@ static int32_t mndRetrieveConfigs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, static void mndCancelGetNextConfig(SMnode *pMnode, void *pIter) {} -static int32_t mndGetDnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetDnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -704,8 +720,8 @@ static int32_t mndGetDnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * return 0; } -static int32_t mndRetrieveDnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveDnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; int32_t cols = 0; diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index f7a39ce9e5..d406247bc1 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -26,12 +26,12 @@ static SSdbRow *mndFuncActionDecode(SSdbRaw *pRaw); static int32_t mndFuncActionInsert(SSdb *pSdb, SFuncObj *pFunc); static int32_t mndFuncActionDelete(SSdb *pSdb, SFuncObj *pFunc); static int32_t mndFuncActionUpdate(SSdb *pSdb, SFuncObj *pOldFunc, SFuncObj *pNewFunc); -static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pMsg, SCreateFuncMsg *pCreate); +static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pMsg, SCreateFuncReq *pCreate); static int32_t mndDropFunc(SMnode *pMnode, SMnodeMsg *pMsg, SFuncObj *pFunc); static int32_t mndProcessCreateFuncMsg(SMnodeMsg *pMsg); static int32_t mndProcessDropFuncMsg(SMnodeMsg *pMsg); static int32_t mndProcessRetrieveFuncMsg(SMnodeMsg *pMsg); -static int32_t mndGetFuncMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); +static int32_t mndGetFuncMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta); static int32_t mndRetrieveFuncs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextFunc(SMnode *pMnode, void *pIter); @@ -152,11 +152,11 @@ static int32_t mndFuncActionDelete(SSdb *pSdb, SFuncObj *pFunc) { } static int32_t mndFuncActionUpdate(SSdb *pSdb, SFuncObj *pOldFunc, SFuncObj *pNewFunc) { - mTrace("func:%s, perform update action, old_row:%p new_row:%p", pOldFunc->name, pOldFunc, pNewFunc); + mTrace("func:%s, perform update action, old row:%p new row:%p", pOldFunc->name, pOldFunc, pNewFunc); return 0; } -static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pMsg, SCreateFuncMsg *pCreate) { +static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pMsg, SCreateFuncReq *pCreate) { SFuncObj *pFunc = calloc(1, sizeof(SFuncObj) + pCreate->commentSize + pCreate->codeSize); pFunc->createdTime = taosGetTimestampMs(); pFunc->funcType = pCreate->funcType; @@ -264,7 +264,7 @@ static int32_t mndDropFunc(SMnode *pMnode, SMnodeMsg *pMsg, SFuncObj *pFunc) { static int32_t mndProcessCreateFuncMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - SCreateFuncMsg *pCreate = pMsg->rpcMsg.pCont; + SCreateFuncReq *pCreate = pMsg->rpcMsg.pCont; pCreate->outputLen = htonl(pCreate->outputLen); pCreate->bufSize = htonl(pCreate->bufSize); pCreate->sigature = htobe64(pCreate->sigature); @@ -323,7 +323,7 @@ static int32_t mndProcessCreateFuncMsg(SMnodeMsg *pMsg) { static int32_t mndProcessDropFuncMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - SDropFuncMsg *pDrop = pMsg->rpcMsg.pCont; + SDropFuncReq *pDrop = pMsg->rpcMsg.pCont; mDebug("func:%s, start to drop", pDrop->name); @@ -353,7 +353,7 @@ static int32_t mndProcessDropFuncMsg(SMnodeMsg *pMsg) { static int32_t mndProcessRetrieveFuncMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - SRetrieveFuncMsg *pRetrieve = pMsg->rpcMsg.pCont; + SRetrieveFuncReq *pRetrieve = pMsg->rpcMsg.pCont; pRetrieve->numOfFuncs = htonl(pRetrieve->numOfFuncs); int32_t size = sizeof(SRetrieveFuncRsp) + (sizeof(SFuncInfo) + TSDB_FUNC_CODE_LEN) * pRetrieve->numOfFuncs + 16384; @@ -395,7 +395,7 @@ static int32_t mndProcessRetrieveFuncMsg(SMnodeMsg *pMsg) { return 0; } -static int32_t mndGetFuncMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { +static int32_t mndGetFuncMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta) { SMnode *pMnode = pMsg->pMnode; SSdb *pSdb = pMnode->pSdb; diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index df1848f2f1..75ed5b0a1e 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -27,14 +27,14 @@ static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pObj); static SSdbRow *mndMnodeActionDecode(SSdbRaw *pRaw); static int32_t mndMnodeActionInsert(SSdb *pSdb, SMnodeObj *pObj); static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pObj); -static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOldMnode, SMnodeObj *pNewMnode); -static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg); -static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg); -static int32_t mndProcessCreateMnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessAlterMnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessDropMnodeRsp(SMnodeMsg *pMsg); -static int32_t mndGetMnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveMnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOld, SMnodeObj *pNew); +static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessDropMnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessCreateMnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessAlterMnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessDropMnodeRsp(SMnodeMsg *pRsp); +static int32_t mndGetMnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveMnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextMnode(SMnode *pMnode, void *pIter); int32_t mndInitMnode(SMnode *pMnode) { @@ -65,7 +65,7 @@ void mndCleanupMnode(SMnode *pMnode) {} static SMnodeObj *mndAcquireMnode(SMnode *pMnode, int32_t mnodeId) { SSdb *pSdb = pMnode->pSdb; SMnodeObj *pObj = sdbAcquire(pSdb, SDB_MNODE, &mnodeId); - if (pObj == NULL) { + if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) { terrno = TSDB_CODE_MND_MNODE_NOT_EXIST; } return pObj; @@ -207,9 +207,9 @@ static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pObj) { return 0; } -static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOldMnode, SMnodeObj *pNewMnode) { - mTrace("mnode:%d, perform update action, old_row:%p new_row:%p", pOldMnode->id, pOldMnode, pNewMnode); - pOldMnode->updateTime = pNewMnode->updateTime; +static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOld, SMnodeObj *pNew) { + mTrace("mnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew); + pOld->updateTime = pNew->updateTime; return 0; } @@ -277,13 +277,13 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno void *pIter = NULL; int32_t numOfReplicas = 0; - SDCreateMnodeMsg createMsg = {0}; + SDCreateMnodeReq createReq = {0}; while (1) { SMnodeObj *pMObj = NULL; pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); if (pIter == NULL) break; - SReplica *pReplica = &createMsg.replicas[numOfReplicas]; + SReplica *pReplica = &createReq.replicas[numOfReplicas]; pReplica->id = htonl(pMObj->id); pReplica->port = htons(pMObj->pDnode->port); memcpy(pReplica->fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); @@ -292,13 +292,13 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno sdbRelease(pSdb, pMObj); } - SReplica *pReplica = &createMsg.replicas[numOfReplicas]; + SReplica *pReplica = &createReq.replicas[numOfReplicas]; pReplica->id = htonl(pDnode->id); pReplica->port = htons(pDnode->port); memcpy(pReplica->fqdn, pDnode->fqdn, TSDB_FQDN_LEN); numOfReplicas++; - createMsg.replica = numOfReplicas; + createReq.replica = numOfReplicas; while (1) { SMnodeObj *pMObj = NULL; @@ -307,22 +307,23 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno STransAction action = {0}; - SDAlterMnodeMsg *pMsg = malloc(sizeof(SDAlterMnodeMsg)); - if (pMsg == NULL) { + SDAlterMnodeReq *pReq = malloc(sizeof(SDAlterMnodeReq)); + if (pReq == NULL) { sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pMObj); return -1; } - memcpy(pMsg, &createMsg, sizeof(SDAlterMnodeMsg)); + memcpy(pReq, &createReq, sizeof(SDAlterMnodeReq)); - pMsg->dnodeId = htonl(pMObj->id); + pReq->dnodeId = htonl(pMObj->id); action.epSet = mndGetDnodeEpset(pMObj->pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDAlterMnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDAlterMnodeReq); action.msgType = TDMT_DND_ALTER_MNODE; + action.acceptableCode = TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pMObj); return -1; @@ -335,17 +336,18 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno STransAction action = {0}; action.epSet = mndGetDnodeEpset(pDnode); - SDCreateMnodeMsg *pMsg = malloc(sizeof(SDCreateMnodeMsg)); - if (pMsg == NULL) return -1; - memcpy(pMsg, &createMsg, sizeof(SDAlterMnodeMsg)); - pMsg->dnodeId = htonl(pObj->id); + SDCreateMnodeReq *pReq = malloc(sizeof(SDCreateMnodeReq)); + if (pReq == NULL) return -1; + memcpy(pReq, &createReq, sizeof(SDAlterMnodeReq)); + pReq->dnodeId = htonl(pObj->id); action.epSet = mndGetDnodeEpset(pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDCreateMnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDCreateMnodeReq); action.msgType = TDMT_DND_CREATE_MNODE; + action.acceptableCode = TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } } @@ -353,39 +355,23 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno return 0; } -static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode, SMCreateMnodeMsg *pCreate) { +static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pReq, SDnodeObj *pDnode, SMCreateMnodeReq *pCreate) { + int32_t code = -1; + SMnodeObj mnodeObj = {0}; mnodeObj.id = pDnode->id; mnodeObj.createdTime = taosGetTimestampMs(); mnodeObj.updateTime = mnodeObj.createdTime; - int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("mnode:%d, failed to create since %s", pCreate->dnodeId, terrstr()); - goto CREATE_MNODE_OVER; - } + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg); + if (pTrans == NULL) goto CREATE_MNODE_OVER; + mDebug("trans:%d, used to create mnode:%d", pTrans->id, pCreate->dnodeId); + if (mndSetCreateMnodeRedoLogs(pMnode, pTrans, &mnodeObj) != 0) goto CREATE_MNODE_OVER; + if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, &mnodeObj) != 0) goto CREATE_MNODE_OVER; + if (mndSetCreateMnodeRedoActions(pMnode, pTrans, pDnode, &mnodeObj) != 0) goto CREATE_MNODE_OVER; - if (mndSetCreateMnodeRedoLogs(pMnode, pTrans, &mnodeObj) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto CREATE_MNODE_OVER; - } - - if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, &mnodeObj) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto CREATE_MNODE_OVER; - } - - if (mndSetCreateMnodeRedoActions(pMnode, pTrans, pDnode, &mnodeObj) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto CREATE_MNODE_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto CREATE_MNODE_OVER; - } + if (mndTransPrepare(pMnode, pTrans) != 0) goto CREATE_MNODE_OVER; code = 0; @@ -394,9 +380,9 @@ CREATE_MNODE_OVER: return code; } -static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SMCreateMnodeMsg *pCreate = pMsg->rpcMsg.pCont; +static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMCreateMnodeReq *pCreate = pReq->rpcMsg.pCont; pCreate->dnodeId = htonl(pCreate->dnodeId); @@ -408,6 +394,9 @@ static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg) { mError("mnode:%d, mnode already exist", pObj->id); terrno = TSDB_CODE_MND_MNODE_ALREADY_EXIST; return -1; + } else if (terrno != TSDB_CODE_MND_MNODE_NOT_EXIST) { + mError("qnode:%d, failed to create mnode since %s", pCreate->dnodeId, terrstr()); + return -1; } SDnodeObj *pDnode = mndAcquireDnode(pMnode, pCreate->dnodeId); @@ -417,7 +406,7 @@ static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg) { return -1; } - int32_t code = mndCreateMnode(pMnode, pMsg, pDnode, pCreate); + int32_t code = mndCreateMnode(pMnode, pReq, pDnode, pCreate); mndReleaseDnode(pMnode, pDnode); if (code != 0) { @@ -449,14 +438,14 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode void *pIter = NULL; int32_t numOfReplicas = 0; - SDAlterMnodeMsg alterMsg = {0}; + SDAlterMnodeReq alterReq = {0}; while (1) { SMnodeObj *pMObj = NULL; pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); if (pIter == NULL) break; if (pMObj->id != pObj->id) { - SReplica *pReplica = &alterMsg.replicas[numOfReplicas]; + SReplica *pReplica = &alterReq.replicas[numOfReplicas]; pReplica->id = htonl(pMObj->id); pReplica->port = htons(pMObj->pDnode->port); memcpy(pReplica->fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); @@ -466,7 +455,7 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode sdbRelease(pSdb, pMObj); } - alterMsg.replica = numOfReplicas; + alterReq.replica = numOfReplicas; while (1) { SMnodeObj *pMObj = NULL; @@ -475,22 +464,23 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode if (pMObj->id != pObj->id) { STransAction action = {0}; - SDAlterMnodeMsg *pMsg = malloc(sizeof(SDAlterMnodeMsg)); - if (pMsg == NULL) { + SDAlterMnodeReq *pReq = malloc(sizeof(SDAlterMnodeReq)); + if (pReq == NULL) { sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pMObj); return -1; } - memcpy(pMsg, &alterMsg, sizeof(SDAlterMnodeMsg)); + memcpy(pReq, &alterReq, sizeof(SDAlterMnodeReq)); - pMsg->dnodeId = htonl(pMObj->id); + pReq->dnodeId = htonl(pMObj->id); action.epSet = mndGetDnodeEpset(pMObj->pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDAlterMnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDAlterMnodeReq); action.msgType = TDMT_DND_ALTER_MNODE; + action.acceptableCode = TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pMObj); return -1; @@ -504,19 +494,20 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode STransAction action = {0}; action.epSet = mndGetDnodeEpset(pDnode); - SDDropMnodeMsg *pMsg = malloc(sizeof(SDDropMnodeMsg)); - if (pMsg == NULL) { + SDDropMnodeReq *pReq = malloc(sizeof(SDDropMnodeReq)); + if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pMsg->dnodeId = htonl(pObj->id); + pReq->dnodeId = htonl(pObj->id); action.epSet = mndGetDnodeEpset(pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDDropMnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDDropMnodeReq); action.msgType = TDMT_DND_DROP_MNODE; + action.acceptableCode = TSDB_CODE_DND_MNODE_NOT_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } } @@ -524,35 +515,18 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode return 0; } -static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pObj) { +static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pReq, SMnodeObj *pObj) { int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("mnode:%d, failed to drop since %s", pObj->id, terrstr()); - goto DROP_MNODE_OVER; - } + + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg); + if (pTrans == NULL) goto DROP_MNODE_OVER; mDebug("trans:%d, used to drop mnode:%d", pTrans->id, pObj->id); - if (mndSetDropMnodeRedoLogs(pMnode, pTrans, pObj) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto DROP_MNODE_OVER; - } - - if (mndSetDropMnodeCommitLogs(pMnode, pTrans, pObj) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto DROP_MNODE_OVER; - } - - if (mndSetDropMnodeRedoActions(pMnode, pTrans, pObj->pDnode, pObj) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto DROP_MNODE_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto DROP_MNODE_OVER; - } + if (mndSetDropMnodeRedoLogs(pMnode, pTrans, pObj) != 0) goto DROP_MNODE_OVER; + if (mndSetDropMnodeCommitLogs(pMnode, pTrans, pObj) != 0) goto DROP_MNODE_OVER; + if (mndSetDropMnodeRedoActions(pMnode, pTrans, pObj->pDnode, pObj) != 0) goto DROP_MNODE_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_MNODE_OVER; code = 0; @@ -561,9 +535,9 @@ DROP_MNODE_OVER: return code; } -static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SMDropMnodeMsg *pDrop = pMsg->rpcMsg.pCont; +static int32_t mndProcessDropMnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMDropMnodeReq *pDrop = pReq->rpcMsg.pCont; pDrop->dnodeId = htonl(pDrop->dnodeId); mDebug("mnode:%d, start to drop", pDrop->dnodeId); @@ -577,12 +551,10 @@ static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg) { SMnodeObj *pObj = mndAcquireMnode(pMnode, pDrop->dnodeId); if (pObj == NULL) { mError("mnode:%d, not exist", pDrop->dnodeId); - terrno = TSDB_CODE_MND_DNODE_NOT_EXIST; return -1; } - int32_t code = mndDropMnode(pMnode, pMsg, pObj); - + int32_t code = mndDropMnode(pMnode, pReq, pObj); if (code != 0) { mError("mnode:%d, failed to drop since %s", pMnode->dnodeId, terrstr()); return -1; @@ -592,23 +564,23 @@ static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessCreateMnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessCreateMnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndProcessAlterMnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessAlterMnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndProcessDropMnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessDropMnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndGetMnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetMnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -660,8 +632,8 @@ static int32_t mndGetMnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * return 0; } -static int32_t mndRetrieveMnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveMnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; int32_t cols = 0; diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 77efeb8481..fced3facbe 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -47,14 +47,14 @@ static SConnObj *mndAcquireConn(SMnode *pMnode, int32_t connId); static void mndReleaseConn(SMnode *pMnode, SConnObj *pConn); static void *mndGetNextConn(SMnode *pMnode, void *pIter, SConnObj **pConn); static void mndCancelGetNextConn(SMnode *pMnode, void *pIter); -static int32_t mndProcessHeartBeatMsg(SMnodeMsg *pMsg); -static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg); -static int32_t mndProcessKillQueryMsg(SMnodeMsg *pMsg); -static int32_t mndProcessKillConnectionMsg(SMnodeMsg *pMsg); -static int32_t mndGetConnsMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveConns(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); -static int32_t mndGetQueryMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveQueries(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndProcessHeartBeatReq(SMnodeMsg *pReq); +static int32_t mndProcessConnectReq(SMnodeMsg *pReq); +static int32_t mndProcessKillQueryReq(SMnodeMsg *pReq); +static int32_t mndProcessKillConnReq(SMnodeMsg *pReq); +static int32_t mndGetConnsMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveConns(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndGetQueryMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveQueries(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextQuery(SMnode *pMnode, void *pIter); int32_t mndInitProfile(SMnode *pMnode) { @@ -68,10 +68,10 @@ int32_t mndInitProfile(SMnode *pMnode) { return -1; } - mndSetMsgHandle(pMnode, TDMT_MND_HEARTBEAT, mndProcessHeartBeatMsg); - mndSetMsgHandle(pMnode, TDMT_MND_CONNECT, mndProcessConnectMsg); - mndSetMsgHandle(pMnode, TDMT_MND_KILL_QUERY, mndProcessKillQueryMsg); - mndSetMsgHandle(pMnode, TDMT_MND_KILL_CONN, mndProcessKillConnectionMsg); + mndSetMsgHandle(pMnode, TDMT_MND_HEARTBEAT, mndProcessHeartBeatReq); + mndSetMsgHandle(pMnode, TDMT_MND_CONNECT, mndProcessConnectReq); + mndSetMsgHandle(pMnode, TDMT_MND_KILL_QUERY, mndProcessKillQueryReq); + mndSetMsgHandle(pMnode, TDMT_MND_KILL_CONN, mndProcessKillConnReq); mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_CONNS, mndGetConnsMeta); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_CONNS, mndRetrieveConns); @@ -178,35 +178,35 @@ static void mndCancelGetNextConn(SMnode *pMnode, void *pIter) { taosHashCancelIterate(pMgmt->cache->pHashTable, pIter); } -static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SConnectMsg *pReq = pMsg->rpcMsg.pCont; - pReq->pid = htonl(pReq->pid); - pReq->startTime = htobe64(pReq->startTime); +static int32_t mndProcessConnectReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SConnectReq *pConnReq = pReq->rpcMsg.pCont; + pConnReq->pid = htonl(pConnReq->pid); + pConnReq->startTime = htobe64(pConnReq->startTime); SRpcConnInfo info = {0}; - if (rpcGetConnInfo(pMsg->rpcMsg.handle, &info) != 0) { - mError("user:%s, failed to login while get connection info since %s", pMsg->user, terrstr()); + if (rpcGetConnInfo(pReq->rpcMsg.handle, &info) != 0) { + mError("user:%s, failed to login while get connection info since %s", pReq->user, terrstr()); return -1; } char ip[30]; taosIp2String(info.clientIp, ip); - if (pReq->db[0]) { - snprintf(pMsg->db, TSDB_DB_FNAME_LEN, "%d%s%s", pMsg->acctId, TS_PATH_DELIMITER, pReq->db); - SDbObj *pDb = mndAcquireDb(pMnode, pMsg->db); + if (pConnReq->db[0]) { + snprintf(pReq->db, TSDB_DB_FNAME_LEN, "%d%s%s", pReq->acctId, TS_PATH_DELIMITER, pConnReq->db); + SDbObj *pDb = mndAcquireDb(pMnode, pReq->db); if (pDb == NULL) { terrno = TSDB_CODE_MND_INVALID_DB; - mError("user:%s, failed to login from %s while use db:%s since %s", pMsg->user, ip, pReq->db, terrstr()); + mError("user:%s, failed to login from %s while use db:%s since %s", pReq->user, ip, pConnReq->db, terrstr()); return -1; } mndReleaseDb(pMnode, pDb); } - SConnObj *pConn = mndCreateConn(pMnode, &info, pReq->pid, pReq->app, pReq->startTime); + SConnObj *pConn = mndCreateConn(pMnode, &info, pConnReq->pid, pConnReq->app, pConnReq->startTime); if (pConn == NULL) { - mError("user:%s, failed to login from %s while create connection since %s", pMsg->user, ip, terrstr()); + mError("user:%s, failed to login from %s while create connection since %s", pReq->user, ip, terrstr()); return -1; } @@ -214,11 +214,11 @@ static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg) { if (pRsp == NULL) { mndReleaseConn(pMnode, pConn); terrno = TSDB_CODE_OUT_OF_MEMORY; - mError("user:%s, failed to login from %s while create rsp since %s", pMsg->user, ip, terrstr()); + mError("user:%s, failed to login from %s while create rsp since %s", pReq->user, ip, terrstr()); return -1; } - SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pUser = mndAcquireUser(pMnode, pReq->user); if (pUser != NULL) { pRsp->acctId = htonl(pUser->acctId); pRsp->superUser = pUser->superUser; @@ -230,16 +230,16 @@ static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg) { mndGetMnodeEpSet(pMnode, &pRsp->epSet); mndReleaseConn(pMnode, pConn); - pMsg->contLen = sizeof(SConnectRsp); - pMsg->pCont = pRsp; + pReq->contLen = sizeof(SConnectRsp); + pReq->pCont = pRsp; - mDebug("user:%s, login from %s, conn:%d, app:%s", info.user, ip, pConn->id, pReq->app); + mDebug("user:%s, login from %s, conn:%d, app:%s", info.user, ip, pConn->id, pConnReq->app); return 0; } -static int32_t mndSaveQueryStreamList(SConnObj *pConn, SHeartBeatMsg *pMsg) { +static int32_t mndSaveQueryStreamList(SConnObj *pConn, SHeartBeatReq *pReq) { pConn->numOfQueries = 0; - int32_t numOfQueries = htonl(pMsg->numOfQueries); + int32_t numOfQueries = htonl(pReq->numOfQueries); if (numOfQueries > 0) { if (pConn->pQueries == NULL) { @@ -250,38 +250,38 @@ static int32_t mndSaveQueryStreamList(SConnObj *pConn, SHeartBeatMsg *pMsg) { int32_t saveSize = pConn->numOfQueries * sizeof(SQueryDesc); if (saveSize > 0 && pConn->pQueries != NULL) { - memcpy(pConn->pQueries, pMsg->pData, saveSize); + memcpy(pConn->pQueries, pReq->pData, saveSize); } } return TSDB_CODE_SUCCESS; } -static int32_t mndProcessHeartBeatMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndProcessHeartBeatReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; SProfileMgmt *pMgmt = &pMnode->profileMgmt; - SHeartBeatMsg *pReq = pMsg->rpcMsg.pCont; - pReq->connId = htonl(pReq->connId); - pReq->pid = htonl(pReq->pid); + SHeartBeatReq *pHeartbeat = pReq->rpcMsg.pCont; + pHeartbeat->connId = htonl(pHeartbeat->connId); + pHeartbeat->pid = htonl(pHeartbeat->pid); SRpcConnInfo info = {0}; - if (rpcGetConnInfo(pMsg->rpcMsg.handle, &info) != 0) { - mError("user:%s, connId:%d failed to process hb since %s", pMsg->user, pReq->connId, terrstr()); + if (rpcGetConnInfo(pReq->rpcMsg.handle, &info) != 0) { + mError("user:%s, connId:%d failed to process hb since %s", pReq->user, pHeartbeat->connId, terrstr()); return -1; } - SConnObj *pConn = mndAcquireConn(pMnode, pReq->connId); + SConnObj *pConn = mndAcquireConn(pMnode, pHeartbeat->connId); if (pConn == NULL) { - pConn = mndCreateConn(pMnode, &info, pReq->pid, pReq->app, 0); + pConn = mndCreateConn(pMnode, &info, pHeartbeat->pid, pHeartbeat->app, 0); if (pConn == NULL) { - mError("user:%s, conn:%d is freed and failed to create new conn since %s", pMsg->user, pReq->connId, terrstr()); + mError("user:%s, conn:%d is freed and failed to create new since %s", pReq->user, pHeartbeat->connId, terrstr()); return -1; } else { - mDebug("user:%s, conn:%d is freed and create a new conn:%d", pMsg->user, pReq->connId, pConn->id); + mDebug("user:%s, conn:%d is freed and create a new conn:%d", pReq->user, pHeartbeat->connId, pConn->id); } } else if (pConn->killed) { - mError("user:%s, conn:%d is already killed", pMsg->user, pConn->id); + mError("user:%s, conn:%d is already killed", pReq->user, pConn->id); terrno = TSDB_CODE_MND_INVALID_CONNECTION; return -1; } else { @@ -304,11 +304,11 @@ static int32_t mndProcessHeartBeatMsg(SMnodeMsg *pMsg) { if (pRsp == NULL) { mndReleaseConn(pMnode, pConn); terrno = TSDB_CODE_OUT_OF_MEMORY; - mError("user:%s, conn:%d failed to process hb while create rsp since %s", pMsg->user, pReq->connId, terrstr()); + mError("user:%s, conn:%d failed to process hb while since %s", pReq->user, pHeartbeat->connId, terrstr()); return -1; } - mndSaveQueryStreamList(pConn, pReq); + mndSaveQueryStreamList(pConn, pHeartbeat); if (pConn->killed != 0) { pRsp->killConnection = 1; } @@ -324,16 +324,16 @@ static int32_t mndProcessHeartBeatMsg(SMnodeMsg *pMsg) { mndGetMnodeEpSet(pMnode, &pRsp->epSet); mndReleaseConn(pMnode, pConn); - pMsg->contLen = sizeof(SConnectRsp); - pMsg->pCont = pRsp; + pReq->contLen = sizeof(SConnectRsp); + pReq->pCont = pRsp; return 0; } -static int32_t mndProcessKillQueryMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndProcessKillQueryReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; SProfileMgmt *pMgmt = &pMnode->profileMgmt; - SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pUser = mndAcquireUser(pMnode, pReq->user); if (pUser == NULL) return 0; if (!pUser->superUser) { mndReleaseUser(pMnode, pUser); @@ -342,7 +342,7 @@ static int32_t mndProcessKillQueryMsg(SMnodeMsg *pMsg) { } mndReleaseUser(pMnode, pUser); - SKillQueryMsg *pKill = pMsg->rpcMsg.pCont; + SKillQueryReq *pKill = pReq->rpcMsg.pCont; int32_t connId = htonl(pKill->connId); int32_t queryId = htonl(pKill->queryId); mInfo("kill query msg is received, queryId:%d", pKill->queryId); @@ -353,18 +353,18 @@ static int32_t mndProcessKillQueryMsg(SMnodeMsg *pMsg) { terrno = TSDB_CODE_MND_INVALID_CONN_ID; return -1; } else { - mInfo("connId:%d, queryId:%d is killed by user:%s", connId, queryId, pMsg->user); + mInfo("connId:%d, queryId:%d is killed by user:%s", connId, queryId, pReq->user); pConn->queryId = queryId; taosCacheRelease(pMgmt->cache, (void **)&pConn, false); return 0; } } -static int32_t mndProcessKillConnectionMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndProcessKillConnReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; SProfileMgmt *pMgmt = &pMnode->profileMgmt; - SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pUser = mndAcquireUser(pMnode, pReq->user); if (pUser == NULL) return 0; if (!pUser->superUser) { mndReleaseUser(pMnode, pUser); @@ -373,7 +373,7 @@ static int32_t mndProcessKillConnectionMsg(SMnodeMsg *pMsg) { } mndReleaseUser(pMnode, pUser); - SKillConnMsg *pKill = pMsg->rpcMsg.pCont; + SKillConnReq *pKill = pReq->rpcMsg.pCont; int32_t connId = htonl(pKill->connId); SConnObj *pConn = taosCacheAcquireByKey(pMgmt->cache, &connId, sizeof(int32_t)); @@ -382,18 +382,18 @@ static int32_t mndProcessKillConnectionMsg(SMnodeMsg *pMsg) { terrno = TSDB_CODE_MND_INVALID_CONN_ID; return -1; } else { - mInfo("connId:%d, is killed by user:%s", connId, pMsg->user); + mInfo("connId:%d, is killed by user:%s", connId, pReq->user); pConn->killed = 1; taosCacheRelease(pMgmt->cache, (void **)&pConn, false); return TSDB_CODE_SUCCESS; } } -static int32_t mndGetConnsMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetConnsMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SProfileMgmt *pMgmt = &pMnode->profileMgmt; - SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pUser = mndAcquireUser(pMnode, pReq->user); if (pUser == NULL) return 0; if (!pUser->superUser) { mndReleaseUser(pMnode, pUser); @@ -464,8 +464,8 @@ static int32_t mndGetConnsMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * return 0; } -static int32_t mndRetrieveConns(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveConns(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; int32_t numOfRows = 0; SConnObj *pConn = NULL; int32_t cols = 0; @@ -518,11 +518,11 @@ static int32_t mndRetrieveConns(SMnodeMsg *pMsg, SShowObj *pShow, char *data, in return numOfRows; } -static int32_t mndGetQueryMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetQueryMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SProfileMgmt *pMgmt = &pMnode->profileMgmt; - SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pUser = mndAcquireUser(pMnode, pReq->user); if (pUser == NULL) return 0; if (!pUser->superUser) { mndReleaseUser(pMnode, pUser); @@ -633,8 +633,8 @@ static int32_t mndGetQueryMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * return 0; } -static int32_t mndRetrieveQueries(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveQueries(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; int32_t numOfRows = 0; SConnObj *pConn = NULL; int32_t cols = 0; diff --git a/source/dnode/mnode/impl/src/mndQnode.c b/source/dnode/mnode/impl/src/mndQnode.c index a0c4ff8218..6077a95a7b 100644 --- a/source/dnode/mnode/impl/src/mndQnode.c +++ b/source/dnode/mnode/impl/src/mndQnode.c @@ -26,13 +26,13 @@ static SSdbRaw *mndQnodeActionEncode(SQnodeObj *pObj); static SSdbRow *mndQnodeActionDecode(SSdbRaw *pRaw); static int32_t mndQnodeActionInsert(SSdb *pSdb, SQnodeObj *pObj); static int32_t mndQnodeActionDelete(SSdb *pSdb, SQnodeObj *pObj); -static int32_t mndQnodeActionUpdate(SSdb *pSdb, SQnodeObj *pOldQnode, SQnodeObj *pNewQnode); -static int32_t mndProcessCreateQnodeReq(SMnodeMsg *pMsg); -static int32_t mndProcessDropQnodeReq(SMnodeMsg *pMsg); -static int32_t mndProcessCreateQnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessDropQnodeRsp(SMnodeMsg *pMsg); -static int32_t mndGetQnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveQnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndQnodeActionUpdate(SSdb *pSdb, SQnodeObj *pOld, SQnodeObj *pNew); +static int32_t mndProcessCreateQnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessDropQnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessCreateQnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessDropQnodeRsp(SMnodeMsg *pRsp); +static int32_t mndGetQnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveQnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextQnode(SMnode *pMnode, void *pIter); int32_t mndInitQnode(SMnode *pMnode) { @@ -59,9 +59,8 @@ int32_t mndInitQnode(SMnode *pMnode) { void mndCleanupQnode(SMnode *pMnode) {} static SQnodeObj *mndAcquireQnode(SMnode *pMnode, int32_t qnodeId) { - SSdb *pSdb = pMnode->pSdb; - SQnodeObj *pObj = sdbAcquire(pSdb, SDB_QNODE, &qnodeId); - if (pObj == NULL) { + SQnodeObj *pObj = sdbAcquire(pMnode->pSdb, SDB_QNODE, &qnodeId); + if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) { terrno = TSDB_CODE_MND_QNODE_NOT_EXIST; } return pObj; @@ -155,9 +154,9 @@ static int32_t mndQnodeActionDelete(SSdb *pSdb, SQnodeObj *pObj) { return 0; } -static int32_t mndQnodeActionUpdate(SSdb *pSdb, SQnodeObj *pOldQnode, SQnodeObj *pNewQnode) { - mTrace("qnode:%d, perform update action, old_row:%p new_row:%p", pOldQnode->id, pOldQnode, pNewQnode); - pOldQnode->updateTime = pNewQnode->updateTime; +static int32_t mndQnodeActionUpdate(SSdb *pSdb, SQnodeObj *pOld, SQnodeObj *pNew) { + mTrace("qnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew); + pOld->updateTime = pNew->updateTime; return 0; } @@ -169,6 +168,14 @@ static int32_t mndSetCreateQnodeRedoLogs(STrans *pTrans, SQnodeObj *pObj) { return 0; } +static int32_t mndSetCreateQnodeUndoLogs(STrans *pTrans, SQnodeObj *pObj) { + SSdbRaw *pUndoRaw = mndQnodeActionEncode(pObj); + if (pUndoRaw == NULL) return -1; + if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) return -1; + if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1; + return 0; +} + static int32_t mndSetCreateQnodeCommitLogs(STrans *pTrans, SQnodeObj *pObj) { SSdbRaw *pCommitRaw = mndQnodeActionEncode(pObj); if (pCommitRaw == NULL) return -1; @@ -178,60 +185,69 @@ static int32_t mndSetCreateQnodeCommitLogs(STrans *pTrans, SQnodeObj *pObj) { } static int32_t mndSetCreateQnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SQnodeObj *pObj) { - SDCreateQnodeMsg *pMsg = malloc(sizeof(SDCreateQnodeMsg)); - if (pMsg == NULL) { + SDCreateQnodeReq *pReq = malloc(sizeof(SDCreateQnodeReq)); + if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pMsg->dnodeId = htonl(pDnode->id); + pReq->dnodeId = htonl(pDnode->id); STransAction action = {0}; action.epSet = mndGetDnodeEpset(pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDCreateQnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDCreateQnodeReq); action.msgType = TDMT_DND_CREATE_QNODE; + action.acceptableCode = TSDB_CODE_DND_QNODE_ALREADY_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } return 0; } -static int32_t mndCreateQnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode, SMCreateQnodeMsg *pCreate) { +static int32_t mndSetCreateQnodeUndoActions(STrans *pTrans, SDnodeObj *pDnode, SQnodeObj *pObj) { + SDDropQnodeReq *pReq = malloc(sizeof(SDDropQnodeReq)); + if (pReq == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + pReq->dnodeId = htonl(pDnode->id); + + STransAction action = {0}; + action.epSet = mndGetDnodeEpset(pDnode); + action.pCont = pReq; + action.contLen = sizeof(SDDropQnodeReq); + action.msgType = TDMT_DND_DROP_QNODE; + action.acceptableCode = TSDB_CODE_DND_QNODE_NOT_DEPLOYED; + + if (mndTransAppendUndoAction(pTrans, &action) != 0) { + free(pReq); + return -1; + } + + return 0; +} + +static int32_t mndCreateQnode(SMnode *pMnode, SMnodeMsg *pReq, SDnodeObj *pDnode, SMCreateQnodeReq *pCreate) { + int32_t code = -1; + SQnodeObj qnodeObj = {0}; qnodeObj.id = pDnode->id; qnodeObj.createdTime = taosGetTimestampMs(); qnodeObj.updateTime = qnodeObj.createdTime; - int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("qnode:%d, failed to create since %s", pCreate->dnodeId, terrstr()); - goto CREATE_QNODE_OVER; - } + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); + if (pTrans == NULL) goto CREATE_QNODE_OVER; + mDebug("trans:%d, used to create qnode:%d", pTrans->id, pCreate->dnodeId); - - if (mndSetCreateQnodeRedoLogs(pTrans, &qnodeObj) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto CREATE_QNODE_OVER; - } - - if (mndSetCreateQnodeCommitLogs(pTrans, &qnodeObj) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto CREATE_QNODE_OVER; - } - - if (mndSetCreateQnodeRedoActions(pTrans, pDnode, &qnodeObj) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto CREATE_QNODE_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto CREATE_QNODE_OVER; - } + if (mndSetCreateQnodeRedoLogs(pTrans, &qnodeObj) != 0) goto CREATE_QNODE_OVER; + if (mndSetCreateQnodeUndoLogs(pTrans, &qnodeObj) != 0) goto CREATE_QNODE_OVER; + if (mndSetCreateQnodeCommitLogs(pTrans, &qnodeObj) != 0) goto CREATE_QNODE_OVER; + if (mndSetCreateQnodeRedoActions(pTrans, pDnode, &qnodeObj) != 0) goto CREATE_QNODE_OVER; + if (mndSetCreateQnodeUndoActions(pTrans, pDnode, &qnodeObj) != 0) goto CREATE_QNODE_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto CREATE_QNODE_OVER; code = 0; @@ -240,9 +256,9 @@ CREATE_QNODE_OVER: return code; } -static int32_t mndProcessCreateQnodeReq(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SMCreateQnodeMsg *pCreate = pMsg->rpcMsg.pCont; +static int32_t mndProcessCreateQnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMCreateQnodeReq *pCreate = pReq->rpcMsg.pCont; pCreate->dnodeId = htonl(pCreate->dnodeId); @@ -251,8 +267,12 @@ static int32_t mndProcessCreateQnodeReq(SMnodeMsg *pMsg) { SQnodeObj *pObj = mndAcquireQnode(pMnode, pCreate->dnodeId); if (pObj != NULL) { mError("qnode:%d, qnode already exist", pObj->id); + terrno = TSDB_CODE_MND_QNODE_ALREADY_EXIST; mndReleaseQnode(pMnode, pObj); return -1; + } else if (terrno != TSDB_CODE_MND_QNODE_NOT_EXIST) { + mError("qnode:%d, failed to create qnode since %s", pCreate->dnodeId, terrstr()); + return -1; } SDnodeObj *pDnode = mndAcquireDnode(pMnode, pCreate->dnodeId); @@ -262,7 +282,7 @@ static int32_t mndProcessCreateQnodeReq(SMnodeMsg *pMsg) { return -1; } - int32_t code = mndCreateQnode(pMnode, pMsg, pDnode, pCreate); + int32_t code = mndCreateQnode(pMnode, pReq, pDnode, pCreate); mndReleaseDnode(pMnode, pDnode); if (code != 0) { @@ -290,56 +310,39 @@ static int32_t mndSetDropQnodeCommitLogs(STrans *pTrans, SQnodeObj *pObj) { } static int32_t mndSetDropQnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SQnodeObj *pObj) { - SDDropQnodeMsg *pMsg = malloc(sizeof(SDDropQnodeMsg)); - if (pMsg == NULL) { + SDDropQnodeReq *pReq = malloc(sizeof(SDDropQnodeReq)); + if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pMsg->dnodeId = htonl(pDnode->id); + pReq->dnodeId = htonl(pDnode->id); STransAction action = {0}; action.epSet = mndGetDnodeEpset(pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDDropQnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDDropQnodeReq); action.msgType = TDMT_DND_DROP_QNODE; + action.acceptableCode = TSDB_CODE_DND_QNODE_NOT_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } return 0; } -static int32_t mndDropQnode(SMnode *pMnode, SMnodeMsg *pMsg, SQnodeObj *pObj) { +static int32_t mndDropQnode(SMnode *pMnode, SMnodeMsg *pReq, SQnodeObj *pObj) { int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("qnode:%d, failed to drop since %s", pObj->id, terrstr()); - goto DROP_QNODE_OVER; - } + + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg); + if (pTrans == NULL) goto DROP_QNODE_OVER; mDebug("trans:%d, used to drop qnode:%d", pTrans->id, pObj->id); - - if (mndSetDropQnodeRedoLogs(pTrans, pObj) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto DROP_QNODE_OVER; - } - - if (mndSetDropQnodeCommitLogs(pTrans, pObj) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto DROP_QNODE_OVER; - } - - if (mndSetDropQnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto DROP_QNODE_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto DROP_QNODE_OVER; - } + if (mndSetDropQnodeRedoLogs(pTrans, pObj) != 0) goto DROP_QNODE_OVER; + if (mndSetDropQnodeCommitLogs(pTrans, pObj) != 0) goto DROP_QNODE_OVER; + if (mndSetDropQnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) goto DROP_QNODE_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_QNODE_OVER; code = 0; @@ -348,9 +351,9 @@ DROP_QNODE_OVER: return code; } -static int32_t mndProcessDropQnodeReq(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SMDropQnodeMsg *pDrop = pMsg->rpcMsg.pCont; +static int32_t mndProcessDropQnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMDropQnodeReq *pDrop = pReq->rpcMsg.pCont; pDrop->dnodeId = htonl(pDrop->dnodeId); mDebug("qnode:%d, start to drop", pDrop->dnodeId); @@ -363,33 +366,33 @@ static int32_t mndProcessDropQnodeReq(SMnodeMsg *pMsg) { SQnodeObj *pObj = mndAcquireQnode(pMnode, pDrop->dnodeId); if (pObj == NULL) { - mError("qnode:%d, not exist", pDrop->dnodeId); - terrno = TSDB_CODE_MND_QNODE_NOT_EXIST; + mError("qnode:%d, failed to drop since %s", pDrop->dnodeId, terrstr()); return -1; } - int32_t code = mndDropQnode(pMnode, pMsg, pObj); + int32_t code = mndDropQnode(pMnode, pReq, pObj); if (code != 0) { + sdbRelease(pMnode->pSdb, pObj); mError("qnode:%d, failed to drop since %s", pMnode->dnodeId, terrstr()); return -1; } - sdbRelease(pMnode->pSdb, pMnode); + sdbRelease(pMnode->pSdb, pObj); return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessCreateQnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessCreateQnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndProcessDropQnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessDropQnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndGetQnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetQnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -428,8 +431,8 @@ static int32_t mndGetQnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * return 0; } -static int32_t mndRetrieveQnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveQnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; int32_t cols = 0; diff --git a/source/dnode/mnode/impl/src/mndShow.c b/source/dnode/mnode/impl/src/mndShow.c index 125c250614..28fe0551c2 100644 --- a/source/dnode/mnode/impl/src/mndShow.c +++ b/source/dnode/mnode/impl/src/mndShow.c @@ -18,12 +18,12 @@ #define SHOW_STEP_SIZE 100 -static SShowObj *mndCreateShowObj(SMnode *pMnode, SShowMsg *pMsg); +static SShowObj *mndCreateShowObj(SMnode *pMnode, SShowReq *pReq); static void mndFreeShowObj(SShowObj *pShow); static SShowObj *mndAcquireShowObj(SMnode *pMnode, int64_t showId); static void mndReleaseShowObj(SShowObj *pShow, bool forceRemove); -static int32_t mndProcessShowMsg(SMnodeMsg *pMnodeMsg); -static int32_t mndProcessRetrieveMsg(SMnodeMsg *pMsg); +static int32_t mndProcessShowReq(SMnodeMsg *pReq); +static int32_t mndProcessRetrieveReq(SMnodeMsg *pReq); static bool mndCheckRetrieveFinished(SShowObj *pShow); int32_t mndInitShow(SMnode *pMnode) { @@ -36,8 +36,8 @@ int32_t mndInitShow(SMnode *pMnode) { return -1; } - mndSetMsgHandle(pMnode, TDMT_MND_SHOW, mndProcessShowMsg); - mndSetMsgHandle(pMnode, TDMT_MND_SHOW_RETRIEVE, mndProcessRetrieveMsg); + mndSetMsgHandle(pMnode, TDMT_MND_SHOW, mndProcessShowReq); + mndSetMsgHandle(pMnode, TDMT_MND_SHOW_RETRIEVE, mndProcessRetrieveReq); return 0; } @@ -49,20 +49,20 @@ void mndCleanupShow(SMnode *pMnode) { } } -static SShowObj *mndCreateShowObj(SMnode *pMnode, SShowMsg *pMsg) { +static SShowObj *mndCreateShowObj(SMnode *pMnode, SShowReq *pReq) { SShowMgmt *pMgmt = &pMnode->showMgmt; int64_t showId = atomic_add_fetch_64(&pMgmt->showId, 1); if (showId == 0) atomic_add_fetch_64(&pMgmt->showId, 1); - int32_t size = sizeof(SShowObj) + pMsg->payloadLen; + int32_t size = sizeof(SShowObj) + pReq->payloadLen; SShowObj showObj = {0}; showObj.id = showId; showObj.pMnode = pMnode; - showObj.type = pMsg->type; - showObj.payloadLen = pMsg->payloadLen; - memcpy(showObj.db, pMsg->db, TSDB_DB_FNAME_LEN); - memcpy(showObj.payload, pMsg->payload, pMsg->payloadLen); + showObj.type = pReq->type; + showObj.payloadLen = pReq->payloadLen; + memcpy(showObj.db, pReq->db, TSDB_DB_FNAME_LEN); + memcpy(showObj.payload, pReq->payload, pReq->payloadLen); int32_t keepTime = pMnode->cfg.shellActivityTimer * 6 * 1000; SShowObj *pShow = taosCachePut(pMgmt->cache, &showId, sizeof(int64_t), &showObj, size, keepTime); @@ -115,29 +115,29 @@ static void mndReleaseShowObj(SShowObj *pShow, bool forceRemove) { taosCacheRelease(pMgmt->cache, (void **)(&pShow), forceRemove); } -static int32_t mndProcessShowMsg(SMnodeMsg *pMnodeMsg) { - SMnode *pMnode = pMnodeMsg->pMnode; +static int32_t mndProcessShowReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; SShowMgmt *pMgmt = &pMnode->showMgmt; - SShowMsg *pMsg = pMnodeMsg->rpcMsg.pCont; - int8_t type = pMsg->type; - int16_t payloadLen = htonl(pMsg->payloadLen); + SShowReq *pShowReq = pReq->rpcMsg.pCont; + int8_t type = pShowReq->type; + int16_t payloadLen = htonl(pShowReq->payloadLen); if (type <= TSDB_MGMT_TABLE_START || type >= TSDB_MGMT_TABLE_MAX) { terrno = TSDB_CODE_MND_INVALID_MSG_TYPE; - mError("failed to process show msg since %s", terrstr()); + mError("failed to process show-meta req since %s", terrstr()); return -1; } ShowMetaFp metaFp = pMgmt->metaFps[type]; if (metaFp == NULL) { terrno = TSDB_CODE_MND_INVALID_MSG_TYPE; - mError("failed to process show-meta msg:%s since %s", mndShowStr(type), terrstr()); + mError("failed to process show-meta req:%s since %s", mndShowStr(type), terrstr()); return -1; } - SShowObj *pShow = mndCreateShowObj(pMnode, pMsg); + SShowObj *pShow = mndCreateShowObj(pMnode, pShowReq); if (pShow == NULL) { - mError("failed to process show-meta msg:%s since %s", mndShowStr(type), terrstr()); + mError("failed to process show-meta req:%s since %s", mndShowStr(type), terrstr()); return -1; } @@ -146,18 +146,18 @@ static int32_t mndProcessShowMsg(SMnodeMsg *pMnodeMsg) { if (pRsp == NULL) { mndReleaseShowObj(pShow, true); terrno = TSDB_CODE_OUT_OF_MEMORY; - mError("show:0x%" PRIx64 ", failed to process show-meta msg:%s since malloc rsp error", pShow->id, + mError("show:0x%" PRIx64 ", failed to process show-meta req:%s since malloc rsp error", pShow->id, mndShowStr(type)); return -1; } - int32_t code = (*metaFp)(pMnodeMsg, pShow, &pRsp->tableMeta); + int32_t code = (*metaFp)(pReq, pShow, &pRsp->tableMeta); mDebug("show:0x%" PRIx64 ", get meta finished, numOfRows:%d cols:%d type:%s, result:%s", pShow->id, pShow->numOfRows, pShow->numOfColumns, mndShowStr(type), tstrerror(code)); if (code == TSDB_CODE_SUCCESS) { - pMnodeMsg->contLen = sizeof(SShowRsp) + sizeof(SSchema) * pShow->numOfColumns; - pMnodeMsg->pCont = pRsp; + pReq->contLen = sizeof(SShowRsp) + sizeof(SSchema) * pShow->numOfColumns; + pReq->pCont = pRsp; pRsp->showId = htobe64(pShow->id); mndReleaseShowObj(pShow, false); return TSDB_CODE_SUCCESS; @@ -168,20 +168,20 @@ static int32_t mndProcessShowMsg(SMnodeMsg *pMnodeMsg) { } } -static int32_t mndProcessRetrieveMsg(SMnodeMsg *pMnodeMsg) { - SMnode *pMnode = pMnodeMsg->pMnode; +static int32_t mndProcessRetrieveReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; SShowMgmt *pMgmt = &pMnode->showMgmt; int32_t rowsToRead = 0; int32_t size = 0; int32_t rowsRead = 0; - SRetrieveTableMsg *pRetrieve = pMnodeMsg->rpcMsg.pCont; + SRetrieveTableReq *pRetrieve = pReq->rpcMsg.pCont; int64_t showId = htobe64(pRetrieve->showId); SShowObj *pShow = mndAcquireShowObj(pMnode, showId); if (pShow == NULL) { terrno = TSDB_CODE_MND_INVALID_SHOWOBJ; - mError("failed to process show-retrieve msg:%p since %s", pShow, terrstr()); + mError("failed to process show-retrieve req:%p since %s", pShow, terrstr()); return -1; } @@ -227,7 +227,7 @@ static int32_t mndProcessRetrieveMsg(SMnodeMsg *pMnodeMsg) { // if free flag is set, client wants to clean the resources if ((pRetrieve->free & TSDB_QUERY_TYPE_FREE_RESOURCE) != TSDB_QUERY_TYPE_FREE_RESOURCE) { - rowsRead = (*retrieveFp)(pMnodeMsg, pShow, pRsp->data, rowsToRead); + rowsRead = (*retrieveFp)(pReq, pShow, pRsp->data, rowsToRead); } mDebug("show:0x%" PRIx64 ", stop retrieve data, rowsRead:%d rowsToRead:%d", pShow->id, rowsRead, rowsToRead); @@ -235,8 +235,8 @@ static int32_t mndProcessRetrieveMsg(SMnodeMsg *pMnodeMsg) { pRsp->numOfRows = htonl(rowsRead); pRsp->precision = TSDB_TIME_PRECISION_MILLI; // millisecond time precision - pMnodeMsg->pCont = pRsp; - pMnodeMsg->contLen = size; + pReq->pCont = pRsp; + pReq->contLen = size; if (rowsRead == 0 || rowsToRead == 0 || (rowsRead == rowsToRead && pShow->numOfRows == pShow->numOfReads)) { pRsp->completed = 1; diff --git a/source/dnode/mnode/impl/src/mndSnode.c b/source/dnode/mnode/impl/src/mndSnode.c index ac03e1659c..7688ea76ab 100644 --- a/source/dnode/mnode/impl/src/mndSnode.c +++ b/source/dnode/mnode/impl/src/mndSnode.c @@ -26,13 +26,13 @@ static SSdbRaw *mndSnodeActionEncode(SSnodeObj *pObj); static SSdbRow *mndSnodeActionDecode(SSdbRaw *pRaw); static int32_t mndSnodeActionInsert(SSdb *pSdb, SSnodeObj *pObj); static int32_t mndSnodeActionDelete(SSdb *pSdb, SSnodeObj *pObj); -static int32_t mndSnodeActionUpdate(SSdb *pSdb, SSnodeObj *pOldSnode, SSnodeObj *pNewSnode); -static int32_t mndProcessCreateSnodeReq(SMnodeMsg *pMsg); -static int32_t mndProcessDropSnodeReq(SMnodeMsg *pMsg); -static int32_t mndProcessCreateSnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessDropSnodeRsp(SMnodeMsg *pMsg); -static int32_t mndGetSnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveSnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndSnodeActionUpdate(SSdb *pSdb, SSnodeObj *pOld, SSnodeObj *pNew); +static int32_t mndProcessCreateSnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessDropSnodeReq(SMnodeMsg *pReq); +static int32_t mndProcessCreateSnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessDropSnodeRsp(SMnodeMsg *pRsp); +static int32_t mndGetSnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveSnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextSnode(SMnode *pMnode, void *pIter); int32_t mndInitSnode(SMnode *pMnode) { @@ -59,9 +59,8 @@ int32_t mndInitSnode(SMnode *pMnode) { void mndCleanupSnode(SMnode *pMnode) {} static SSnodeObj *mndAcquireSnode(SMnode *pMnode, int32_t snodeId) { - SSdb *pSdb = pMnode->pSdb; - SSnodeObj *pObj = sdbAcquire(pSdb, SDB_SNODE, &snodeId); - if (pObj == NULL) { + SSnodeObj *pObj = sdbAcquire(pMnode->pSdb, SDB_SNODE, &snodeId); + if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) { terrno = TSDB_CODE_MND_SNODE_NOT_EXIST; } return pObj; @@ -155,9 +154,9 @@ static int32_t mndSnodeActionDelete(SSdb *pSdb, SSnodeObj *pObj) { return 0; } -static int32_t mndSnodeActionUpdate(SSdb *pSdb, SSnodeObj *pOldSnode, SSnodeObj *pNewSnode) { - mTrace("snode:%d, perform update action, old_row:%p new_row:%p", pOldSnode->id, pOldSnode, pNewSnode); - pOldSnode->updateTime = pNewSnode->updateTime; +static int32_t mndSnodeActionUpdate(SSdb *pSdb, SSnodeObj *pOld, SSnodeObj *pNew) { + mTrace("snode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew); + pOld->updateTime = pNew->updateTime; return 0; } @@ -169,6 +168,14 @@ static int32_t mndSetCreateSnodeRedoLogs(STrans *pTrans, SSnodeObj *pObj) { return 0; } +static int32_t mndSetCreateSnodeUndoLogs(STrans *pTrans, SSnodeObj *pObj) { + SSdbRaw *pUndoRaw = mndSnodeActionEncode(pObj); + if (pUndoRaw == NULL) return -1; + if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) return -1; + if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1; + return 0; +} + static int32_t mndSetCreateSnodeCommitLogs(STrans *pTrans, SSnodeObj *pObj) { SSdbRaw *pCommitRaw = mndSnodeActionEncode(pObj); if (pCommitRaw == NULL) return -1; @@ -178,60 +185,70 @@ static int32_t mndSetCreateSnodeCommitLogs(STrans *pTrans, SSnodeObj *pObj) { } static int32_t mndSetCreateSnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SSnodeObj *pObj) { - SDCreateSnodeMsg *pMsg = malloc(sizeof(SDCreateSnodeMsg)); - if (pMsg == NULL) { + SDCreateSnodeReq *pReq = malloc(sizeof(SDCreateSnodeReq)); + if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pMsg->dnodeId = htonl(pDnode->id); + pReq->dnodeId = htonl(pDnode->id); STransAction action = {0}; action.epSet = mndGetDnodeEpset(pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDCreateSnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDCreateSnodeReq); action.msgType = TDMT_DND_CREATE_SNODE; + action.acceptableCode = TSDB_CODE_DND_SNODE_ALREADY_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } return 0; } -static int32_t mndCreateSnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode, SMCreateSnodeMsg *pCreate) { +static int32_t mndSetCreateSnodeUndoActions(STrans *pTrans, SDnodeObj *pDnode, SSnodeObj *pObj) { + SDDropSnodeReq *pReq = malloc(sizeof(SDDropSnodeReq)); + if (pReq == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + pReq->dnodeId = htonl(pDnode->id); + + STransAction action = {0}; + action.epSet = mndGetDnodeEpset(pDnode); + action.pCont = pReq; + action.contLen = sizeof(SDDropSnodeReq); + action.msgType = TDMT_DND_DROP_SNODE; + action.acceptableCode = TSDB_CODE_DND_SNODE_NOT_DEPLOYED; + + if (mndTransAppendUndoAction(pTrans, &action) != 0) { + free(pReq); + return -1; + } + + return 0; +} + +static int32_t mndCreateSnode(SMnode *pMnode, SMnodeMsg *pReq, SDnodeObj *pDnode, SMCreateSnodeReq *pCreate) { + int32_t code = -1; + SSnodeObj snodeObj = {0}; snodeObj.id = pDnode->id; snodeObj.createdTime = taosGetTimestampMs(); snodeObj.updateTime = snodeObj.createdTime; - int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("snode:%d, failed to create since %s", pCreate->dnodeId, terrstr()); - goto CREATE_SNODE_OVER; - } + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); + if (pTrans == NULL) goto CREATE_SNODE_OVER; + mDebug("trans:%d, used to create snode:%d", pTrans->id, pCreate->dnodeId); - if (mndSetCreateSnodeRedoLogs(pTrans, &snodeObj) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto CREATE_SNODE_OVER; - } - - if (mndSetCreateSnodeCommitLogs(pTrans, &snodeObj) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto CREATE_SNODE_OVER; - } - - if (mndSetCreateSnodeRedoActions(pTrans, pDnode, &snodeObj) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto CREATE_SNODE_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto CREATE_SNODE_OVER; - } + if (mndSetCreateSnodeRedoLogs(pTrans, &snodeObj) != 0) goto CREATE_SNODE_OVER; + if (mndSetCreateSnodeUndoLogs(pTrans, &snodeObj) != 0) goto CREATE_SNODE_OVER; + if (mndSetCreateSnodeCommitLogs(pTrans, &snodeObj) != 0) goto CREATE_SNODE_OVER; + if (mndSetCreateSnodeRedoActions(pTrans, pDnode, &snodeObj) != 0) goto CREATE_SNODE_OVER; + if (mndSetCreateSnodeUndoActions(pTrans, pDnode, &snodeObj) != 0) goto CREATE_SNODE_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto CREATE_SNODE_OVER; code = 0; @@ -240,9 +257,9 @@ CREATE_SNODE_OVER: return code; } -static int32_t mndProcessCreateSnodeReq(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SMCreateSnodeMsg *pCreate = pMsg->rpcMsg.pCont; +static int32_t mndProcessCreateSnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMCreateSnodeReq *pCreate = pReq->rpcMsg.pCont; pCreate->dnodeId = htonl(pCreate->dnodeId); @@ -251,8 +268,12 @@ static int32_t mndProcessCreateSnodeReq(SMnodeMsg *pMsg) { SSnodeObj *pObj = mndAcquireSnode(pMnode, pCreate->dnodeId); if (pObj != NULL) { mError("snode:%d, snode already exist", pObj->id); + terrno = TSDB_CODE_MND_SNODE_ALREADY_EXIST; mndReleaseSnode(pMnode, pObj); return -1; + } else if (terrno != TSDB_CODE_MND_SNODE_NOT_EXIST) { + mError("snode:%d, failed to create snode since %s", pCreate->dnodeId, terrstr()); + return -1; } SDnodeObj *pDnode = mndAcquireDnode(pMnode, pCreate->dnodeId); @@ -262,7 +283,7 @@ static int32_t mndProcessCreateSnodeReq(SMnodeMsg *pMsg) { return -1; } - int32_t code = mndCreateSnode(pMnode, pMsg, pDnode, pCreate); + int32_t code = mndCreateSnode(pMnode, pReq, pDnode, pCreate); mndReleaseDnode(pMnode, pDnode); if (code != 0) { @@ -290,56 +311,40 @@ static int32_t mndSetDropSnodeCommitLogs(STrans *pTrans, SSnodeObj *pObj) { } static int32_t mndSetDropSnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SSnodeObj *pObj) { - SDDropSnodeMsg *pMsg = malloc(sizeof(SDDropSnodeMsg)); - if (pMsg == NULL) { + SDDropSnodeReq *pReq = malloc(sizeof(SDDropSnodeReq)); + if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pMsg->dnodeId = htonl(pDnode->id); + pReq->dnodeId = htonl(pDnode->id); STransAction action = {0}; action.epSet = mndGetDnodeEpset(pDnode); - action.pCont = pMsg; - action.contLen = sizeof(SDDropSnodeMsg); + action.pCont = pReq; + action.contLen = sizeof(SDDropSnodeReq); action.msgType = TDMT_DND_DROP_SNODE; + action.acceptableCode = TSDB_CODE_DND_SNODE_NOT_DEPLOYED; if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); + free(pReq); return -1; } return 0; } -static int32_t mndDropSnode(SMnode *pMnode, SMnodeMsg *pMsg, SSnodeObj *pObj) { +static int32_t mndDropSnode(SMnode *pMnode, SMnodeMsg *pReq, SSnodeObj *pObj) { int32_t code = -1; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pMsg->rpcMsg); - if (pTrans == NULL) { - mError("snode:%d, failed to drop since %s", pObj->id, terrstr()); - goto DROP_SNODE_OVER; - } + + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg); + if (pTrans == NULL) goto DROP_SNODE_OVER; mDebug("trans:%d, used to drop snode:%d", pTrans->id, pObj->id); - if (mndSetDropSnodeRedoLogs(pTrans, pObj) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto DROP_SNODE_OVER; - } - - if (mndSetDropSnodeCommitLogs(pTrans, pObj) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto DROP_SNODE_OVER; - } - - if (mndSetDropSnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto DROP_SNODE_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto DROP_SNODE_OVER; - } + if (mndSetDropSnodeRedoLogs(pTrans, pObj) != 0) goto DROP_SNODE_OVER; + if (mndSetDropSnodeCommitLogs(pTrans, pObj) != 0) goto DROP_SNODE_OVER; + if (mndSetDropSnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) goto DROP_SNODE_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_SNODE_OVER; code = 0; @@ -348,9 +353,9 @@ DROP_SNODE_OVER: return code; } -static int32_t mndProcessDropSnodeReq(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SMDropSnodeMsg *pDrop = pMsg->rpcMsg.pCont; +static int32_t mndProcessDropSnodeReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SMDropSnodeReq *pDrop = pReq->rpcMsg.pCont; pDrop->dnodeId = htonl(pDrop->dnodeId); mDebug("snode:%d, start to drop", pDrop->dnodeId); @@ -363,33 +368,33 @@ static int32_t mndProcessDropSnodeReq(SMnodeMsg *pMsg) { SSnodeObj *pObj = mndAcquireSnode(pMnode, pDrop->dnodeId); if (pObj == NULL) { - mError("snode:%d, not exist", pDrop->dnodeId); - terrno = TSDB_CODE_MND_SNODE_NOT_EXIST; + mError("snode:%d, failed to drop since %s", pDrop->dnodeId, terrstr()); return -1; } - int32_t code = mndDropSnode(pMnode, pMsg, pObj); + int32_t code = mndDropSnode(pMnode, pReq, pObj); if (code != 0) { + sdbRelease(pMnode->pSdb, pObj); mError("snode:%d, failed to drop since %s", pMnode->dnodeId, terrstr()); return -1; } - sdbRelease(pMnode->pSdb, pMnode); + sdbRelease(pMnode->pSdb, pObj); return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessCreateSnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessCreateSnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndProcessDropSnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessDropSnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndGetSnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetSnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -428,8 +433,8 @@ static int32_t mndGetSnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * return 0; } -static int32_t mndRetrieveSnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveSnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; int32_t cols = 0; diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 2609faa41a..7d77e29d74 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -32,14 +32,14 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw); static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb); static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb); static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOldStb, SStbObj *pNewStb); -static int32_t mndProcessCreateStbMsg(SMnodeMsg *pMsg); -static int32_t mndProcessAlterStbMsg(SMnodeMsg *pMsg); -static int32_t mndProcessDropStbMsg(SMnodeMsg *pMsg); +static int32_t mndProcesSMCreateStbReq(SMnodeMsg *pMsg); +static int32_t mndProcesSMAlterStbReq(SMnodeMsg *pMsg); +static int32_t mndProcesSMDropStbReq(SMnodeMsg *pMsg); static int32_t mndProcessCreateStbInRsp(SMnodeMsg *pMsg); static int32_t mndProcessAlterStbInRsp(SMnodeMsg *pMsg); static int32_t mndProcessDropStbInRsp(SMnodeMsg *pMsg); static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg); -static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); +static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta); static int32_t mndRetrieveStb(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextStb(SMnode *pMnode, void *pIter); @@ -52,9 +52,9 @@ int32_t mndInitStb(SMnode *pMnode) { .updateFp = (SdbUpdateFp)mndStbActionUpdate, .deleteFp = (SdbDeleteFp)mndStbActionDelete}; - mndSetMsgHandle(pMnode, TDMT_MND_CREATE_STB, mndProcessCreateStbMsg); - mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcessAlterStbMsg); - mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcessDropStbMsg); + mndSetMsgHandle(pMnode, TDMT_MND_CREATE_STB, mndProcesSMCreateStbReq); + mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcesSMAlterStbReq); + mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcesSMDropStbReq); mndSetMsgHandle(pMnode, TDMT_VND_CREATE_STB_RSP, mndProcessCreateStbInRsp); mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndProcessAlterStbInRsp); mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndProcessDropStbInRsp); @@ -178,7 +178,7 @@ static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) { } static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOldStb, SStbObj *pNewStb) { - mTrace("stb:%s, perform update action, old_row:%p new_row:%p", pOldStb->name, pOldStb, pNewStb); + mTrace("stb:%s, perform update action, old row:%p new row:%p", pOldStb->name, pOldStb, pNewStb); atomic_exchange_32(&pOldStb->updateTime, pNewStb->updateTime); atomic_exchange_32(&pOldStb->version, pNewStb->version); @@ -264,10 +264,10 @@ static void *mndBuildCreateStbMsg(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb return buf; } -static SVDropStbReq *mndBuildDropStbMsg(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb) { - int32_t contLen = sizeof(SVDropStbReq); +static SVDropTbReq *mndBuildDropStbMsg(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb) { + int32_t contLen = sizeof(SVDropTbReq); - SVDropStbReq *pDrop = calloc(1, contLen); + SVDropTbReq *pDrop = calloc(1, contLen); if (pDrop == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; @@ -276,12 +276,12 @@ static SVDropStbReq *mndBuildDropStbMsg(SMnode *pMnode, SVgObj *pVgroup, SStbObj pDrop->head.contLen = htonl(contLen); pDrop->head.vgId = htonl(pVgroup->vgId); memcpy(pDrop->name, pStb->name, TSDB_TABLE_FNAME_LEN); - pDrop->suid = htobe64(pStb->uid); + // pDrop->suid = htobe64(pStb->uid); return pDrop; } -static int32_t mndCheckCreateStbMsg(SCreateStbMsg *pCreate) { +static int32_t mndCheckCreateStbMsg(SMCreateStbReq *pCreate) { pCreate->numOfColumns = htonl(pCreate->numOfColumns); pCreate->numOfTags = htonl(pCreate->numOfTags); int32_t totalCols = pCreate->numOfColumns + pCreate->numOfTags; @@ -398,7 +398,7 @@ static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj if (pIter == NULL) break; if (pVgroup->dbUid != pDb->uid) continue; - SVDropStbReq *pMsg = mndBuildDropStbMsg(pMnode, pVgroup, pStb); + SVDropTbReq *pMsg = mndBuildDropStbMsg(pMnode, pVgroup, pStb); if (pMsg == NULL) { sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pVgroup); @@ -409,7 +409,7 @@ static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj STransAction action = {0}; action.epSet = mndGetVgroupEpset(pMnode, pVgroup); action.pCont = pMsg; - action.contLen = sizeof(SVDropStbReq); + action.contLen = sizeof(SVDropTbReq); action.msgType = TDMT_VND_DROP_STB; if (mndTransAppendUndoAction(pTrans, &action) != 0) { free(pMsg); @@ -423,7 +423,7 @@ static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj return 0; } -static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateStbMsg *pCreate, SDbObj *pDb) { +static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pMsg, SMCreateStbReq *pCreate, SDbObj *pDb) { SStbObj stbObj = {0}; tstrncpy(stbObj.name, pCreate->name, TSDB_TABLE_FNAME_LEN); tstrncpy(stbObj.db, pDb->name, TSDB_DB_FNAME_LEN); @@ -494,9 +494,9 @@ CREATE_STB_OVER: return code; } -static int32_t mndProcessCreateStbMsg(SMnodeMsg *pMsg) { +static int32_t mndProcesSMCreateStbReq(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - SCreateStbMsg *pCreate = pMsg->rpcMsg.pCont; + SMCreateStbReq *pCreate = pMsg->rpcMsg.pCont; mDebug("stb:%s, start to create", pCreate->name); @@ -551,7 +551,7 @@ static int32_t mndProcessCreateStbInRsp(SMnodeMsg *pMsg) { return 0; } -static int32_t mndCheckAlterStbMsg(SAlterStbMsg *pAlter) { +static int32_t mndCheckAlterStbMsg(SMAlterStbReq *pAlter) { SSchema *pSchema = &pAlter->schema; pSchema->colId = htonl(pSchema->colId); pSchema->bytes = htonl(pSchema->bytes); @@ -578,9 +578,9 @@ static int32_t mndCheckAlterStbMsg(SAlterStbMsg *pAlter) { static int32_t mndUpdateStb(SMnode *pMnode, SMnodeMsg *pMsg, SStbObj *pOldStb, SStbObj *pNewStb) { return 0; } -static int32_t mndProcessAlterStbMsg(SMnodeMsg *pMsg) { +static int32_t mndProcesSMAlterStbReq(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - SAlterStbMsg *pAlter = pMsg->rpcMsg.pCont; + SMAlterStbReq *pAlter = pMsg->rpcMsg.pCont; mDebug("stb:%s, start to alter", pAlter->name); @@ -692,9 +692,9 @@ DROP_STB_OVER: return 0; } -static int32_t mndProcessDropStbMsg(SMnodeMsg *pMsg) { +static int32_t mndProcesSMDropStbReq(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - SDropStbMsg *pDrop = pMsg->rpcMsg.pCont; + SMDropStbReq *pDrop = pMsg->rpcMsg.pCont; mDebug("stb:%s, start to drop", pDrop->name); @@ -729,7 +729,7 @@ static int32_t mndProcessDropStbInRsp(SMnodeMsg *pMsg) { static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - STableInfoMsg *pInfo = pMsg->rpcMsg.pCont; + STableInfoReq *pInfo = pMsg->rpcMsg.pCont; mDebug("stb:%s, start to retrieve meta", pInfo->tableFname); @@ -750,9 +750,9 @@ static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg) { taosRLockLatch(&pStb->lock); int32_t totalCols = pStb->numOfColumns + pStb->numOfTags; - int32_t contLen = sizeof(STableMetaMsg) + totalCols * sizeof(SSchema); + int32_t contLen = sizeof(STableMetaRsp) + totalCols * sizeof(SSchema); - STableMetaMsg *pMeta = rpcMallocCont(contLen); + STableMetaRsp *pMeta = rpcMallocCont(contLen); if (pMeta == NULL) { taosRUnLockLatch(&pStb->lock); mndReleaseDb(pMnode, pDb); @@ -769,7 +769,8 @@ static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg) { pMeta->tableType = TSDB_SUPER_TABLE; pMeta->update = pDb->cfg.update; pMeta->sversion = htonl(pStb->version); - pMeta->suid = htonl(pStb->uid); + pMeta->suid = htobe64(pStb->uid); + pMeta->tuid = htobe64(pStb->uid); for (int32_t i = 0; i < totalCols; ++i) { SSchema *pSchema = &pMeta->pSchema[i]; @@ -817,7 +818,7 @@ static int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs return 0; } -static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { +static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta) { SMnode *pMnode = pMsg->pMnode; SSdb *pSdb = pMnode->pSdb; diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c index 19fb89454e..591367c519 100644 --- a/source/dnode/mnode/impl/src/mndSync.c +++ b/source/dnode/mnode/impl/src/mndSync.c @@ -54,7 +54,7 @@ static int32_t mndRestoreWal(SMnode *pMnode) { int64_t first = walGetFirstVer(pWal); int64_t last = walGetLastVer(pWal); - mDebug("restore sdb wal start, sdb ver:%" PRId64 ", wal first:%" PRId64 " last:%" PRId64, lastSdbVer, first, last); + mDebug("start to restore sdb wal, sdb ver:%" PRId64 ", wal first:%" PRId64 " last:%" PRId64, lastSdbVer, first, last); first = MAX(lastSdbVer + 1, first); for (int64_t ver = first; ver >= 0 && ver <= last; ++ver) { @@ -71,6 +71,7 @@ static int32_t mndRestoreWal(SMnode *pMnode) { goto WAL_RESTORE_OVER; } + mTrace("wal:%" PRId64 ", will be restored, content:%p", ver, pHead->head.body); if (sdbWriteNotFree(pSdb, (void *)pHead->head.body) < 0) { mError("failed to read wal from sdb since %s, ver:%" PRId64, terrstr(), ver); goto WAL_RESTORE_OVER; @@ -83,19 +84,22 @@ static int32_t mndRestoreWal(SMnode *pMnode) { int64_t sdbVer = sdbUpdateVer(pSdb, 0); mDebug("restore sdb wal finished, sdb ver:%" PRId64, sdbVer); - if (walBeginSnapshot(pWal, sdbVer) < 0) { - goto WAL_RESTORE_OVER; - } + mndTransPullup(pMnode); if (sdbVer != lastSdbVer) { mInfo("sdb restored from %" PRId64 " to %" PRId64 ", write file", lastSdbVer, sdbVer); if (sdbWriteFile(pSdb) != 0) { goto WAL_RESTORE_OVER; } - } - if (walEndSnapshot(pWal) < 0) { - goto WAL_RESTORE_OVER; + if (walBeginSnapshot(pWal, sdbVer) < 0) { + goto WAL_RESTORE_OVER; + } + + if (walEndSnapshot(pWal) < 0) { + goto WAL_RESTORE_OVER; + } + } code = 0; @@ -178,4 +182,4 @@ int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw) { bool mndIsMaster(SMnode *pMnode) { SSyncMgmt *pMgmt = &pMnode->syncMgmt; return pMgmt->state == TAOS_SYNC_STATE_LEADER; -} \ No newline at end of file +} diff --git a/source/dnode/mnode/impl/src/mndTopic.c b/source/dnode/mnode/impl/src/mndTopic.c index 9fb63f6f58..acdc718f20 100644 --- a/source/dnode/mnode/impl/src/mndTopic.c +++ b/source/dnode/mnode/impl/src/mndTopic.c @@ -14,6 +14,7 @@ */ #define _DEFAULT_SOURCE +#include "mndTopic.h" #include "mndDb.h" #include "mndDnode.h" #include "mndMnode.h" @@ -27,18 +28,16 @@ #define MND_TOPIC_VER_NUMBER 1 #define MND_TOPIC_RESERVE_SIZE 64 -static SSdbRaw *mndTopicActionEncode(STopicObj *pTopic); -static SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw); -static int32_t mndTopicActionInsert(SSdb *pSdb, STopicObj *pTopic); -static int32_t mndTopicActionDelete(SSdb *pSdb, STopicObj *pTopic); -static int32_t mndTopicActionUpdate(SSdb *pSdb, STopicObj *pTopic, STopicObj *pNewTopic); -static int32_t mndProcessCreateTopicMsg(SMnodeMsg *pMsg); -static int32_t mndProcessDropTopicMsg(SMnodeMsg *pMsg); -static int32_t mndProcessDropTopicInRsp(SMnodeMsg *pMsg); -static int32_t mndProcessTopicMetaMsg(SMnodeMsg *pMsg); -static int32_t mndGetTopicMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveTopic(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); -static void mndCancelGetNextTopic(SMnode *pMnode, void *pIter); +static int32_t mndTopicActionInsert(SSdb *pSdb, SMqTopicObj *pTopic); +static int32_t mndTopicActionDelete(SSdb *pSdb, SMqTopicObj *pTopic); +static int32_t mndTopicActionUpdate(SSdb *pSdb, SMqTopicObj *pTopic, SMqTopicObj *pNewTopic); +static int32_t mndProcessCreateTopicMsg(SMnodeMsg *pMsg); +static int32_t mndProcessDropTopicMsg(SMnodeMsg *pMsg); +static int32_t mndProcessDropTopicInRsp(SMnodeMsg *pMsg); +static int32_t mndProcessTopicMetaMsg(SMnodeMsg *pMsg); +static int32_t mndGetTopicMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveTopic(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static void mndCancelGetNextTopic(SMnode *pMnode, void *pIter); int32_t mndInitTopic(SMnode *pMnode) { SSdbTable table = {.sdbType = SDB_TOPIC, @@ -58,33 +57,31 @@ int32_t mndInitTopic(SMnode *pMnode) { void mndCleanupTopic(SMnode *pMnode) {} -static SSdbRaw *mndTopicActionEncode(STopicObj *pTopic) { +SSdbRaw *mndTopicActionEncode(SMqTopicObj *pTopic) { terrno = TSDB_CODE_OUT_OF_MEMORY; - int32_t size = sizeof(STopicObj) + MND_TOPIC_RESERVE_SIZE; + int32_t size = sizeof(SMqTopicObj) + MND_TOPIC_RESERVE_SIZE; SSdbRaw *pRaw = sdbAllocRaw(SDB_TOPIC, MND_TOPIC_VER_NUMBER, size); if (pRaw == NULL) goto TOPIC_ENCODE_OVER; int32_t dataPos = 0; - SDB_SET_BINARY(pRaw, dataPos, pTopic->name, TSDB_TABLE_FNAME_LEN, TOPIC_ENCODE_OVER) - SDB_SET_BINARY(pRaw, dataPos, pTopic->db, TSDB_DB_FNAME_LEN, TOPIC_ENCODE_OVER) - SDB_SET_INT64(pRaw, dataPos, pTopic->createTime, TOPIC_ENCODE_OVER) - SDB_SET_INT64(pRaw, dataPos, pTopic->updateTime, TOPIC_ENCODE_OVER) - SDB_SET_INT64(pRaw, dataPos, pTopic->uid, TOPIC_ENCODE_OVER) - SDB_SET_INT64(pRaw, dataPos, pTopic->dbUid, TOPIC_ENCODE_OVER) - SDB_SET_INT32(pRaw, dataPos, pTopic->version, TOPIC_ENCODE_OVER) - SDB_SET_INT32(pRaw, dataPos, pTopic->execLen, TOPIC_ENCODE_OVER) - SDB_SET_BINARY(pRaw, dataPos, pTopic->executor, pTopic->execLen, TOPIC_ENCODE_OVER) - SDB_SET_INT32(pRaw, dataPos, pTopic->sqlLen, TOPIC_ENCODE_OVER) - SDB_SET_BINARY(pRaw, dataPos, pTopic->sql, pTopic->sqlLen, TOPIC_ENCODE_OVER) + SDB_SET_BINARY(pRaw, dataPos, pTopic->name, TSDB_TABLE_FNAME_LEN, TOPIC_ENCODE_OVER); + SDB_SET_BINARY(pRaw, dataPos, pTopic->db, TSDB_DB_FNAME_LEN, TOPIC_ENCODE_OVER); + SDB_SET_INT64(pRaw, dataPos, pTopic->createTime, TOPIC_ENCODE_OVER); + SDB_SET_INT64(pRaw, dataPos, pTopic->updateTime, TOPIC_ENCODE_OVER); + SDB_SET_INT64(pRaw, dataPos, pTopic->uid, TOPIC_ENCODE_OVER); + SDB_SET_INT64(pRaw, dataPos, pTopic->dbUid, TOPIC_ENCODE_OVER); + SDB_SET_INT32(pRaw, dataPos, pTopic->version, TOPIC_ENCODE_OVER); + SDB_SET_INT32(pRaw, dataPos, pTopic->sqlLen, TOPIC_ENCODE_OVER); + SDB_SET_BINARY(pRaw, dataPos, pTopic->sql, pTopic->sqlLen, TOPIC_ENCODE_OVER); - SDB_SET_RESERVE(pRaw, dataPos, MND_TOPIC_RESERVE_SIZE, TOPIC_ENCODE_OVER) - SDB_SET_DATALEN(pRaw, dataPos, TOPIC_ENCODE_OVER) + SDB_SET_RESERVE(pRaw, dataPos, MND_TOPIC_RESERVE_SIZE, TOPIC_ENCODE_OVER); + SDB_SET_DATALEN(pRaw, dataPos, TOPIC_ENCODE_OVER); - terrno = 0; + terrno = TSDB_CODE_SUCCESS; TOPIC_ENCODE_OVER: - if (terrno != 0) { + if (terrno != TSDB_CODE_SUCCESS) { mError("topic:%s, failed to encode to raw:%p since %s", pTopic->name, pRaw, terrstr()); sdbFreeRaw(pRaw); return NULL; @@ -94,9 +91,8 @@ TOPIC_ENCODE_OVER: return pRaw; } -static SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) { +SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) { terrno = TSDB_CODE_OUT_OF_MEMORY; - int8_t sver = 0; if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto TOPIC_DECODE_OVER; @@ -105,32 +101,35 @@ static SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) { goto TOPIC_DECODE_OVER; } - int32_t size = sizeof(STopicObj) + TSDB_MAX_COLUMNS * sizeof(SSchema); + int32_t size = sizeof(SMqTopicObj); SSdbRow *pRow = sdbAllocRow(size); if (pRow == NULL) goto TOPIC_DECODE_OVER; - STopicObj *pTopic = sdbGetRowObj(pRow); + SMqTopicObj *pTopic = sdbGetRowObj(pRow); if (pTopic == NULL) goto TOPIC_DECODE_OVER; + int32_t len; int32_t dataPos = 0; - SDB_GET_BINARY(pRaw, dataPos, pTopic->name, TSDB_TABLE_FNAME_LEN, TOPIC_DECODE_OVER) - SDB_GET_BINARY(pRaw, dataPos, pTopic->db, TSDB_DB_FNAME_LEN, TOPIC_DECODE_OVER) - SDB_GET_INT64(pRaw, dataPos, &pTopic->createTime, TOPIC_DECODE_OVER) - SDB_GET_INT64(pRaw, dataPos, &pTopic->updateTime, TOPIC_DECODE_OVER) - SDB_GET_INT64(pRaw, dataPos, &pTopic->uid, TOPIC_DECODE_OVER) - SDB_GET_INT64(pRaw, dataPos, &pTopic->dbUid, TOPIC_DECODE_OVER) - SDB_GET_INT32(pRaw, dataPos, &pTopic->version, TOPIC_DECODE_OVER) - SDB_GET_INT32(pRaw, dataPos, &pTopic->execLen, TOPIC_DECODE_OVER) - SDB_GET_BINARY(pRaw, dataPos, pTopic->executor, pTopic->execLen, TOPIC_DECODE_OVER) - SDB_GET_INT32(pRaw, dataPos, &pTopic->sqlLen, TOPIC_DECODE_OVER) - SDB_GET_BINARY(pRaw, dataPos, pTopic->sql, pTopic->sqlLen, TOPIC_DECODE_OVER) + SDB_GET_BINARY(pRaw, dataPos, pTopic->name, TSDB_TABLE_FNAME_LEN, TOPIC_DECODE_OVER); + SDB_GET_BINARY(pRaw, dataPos, pTopic->db, TSDB_DB_FNAME_LEN, TOPIC_DECODE_OVER); + SDB_GET_INT64(pRaw, dataPos, &pTopic->createTime, TOPIC_DECODE_OVER); + SDB_GET_INT64(pRaw, dataPos, &pTopic->updateTime, TOPIC_DECODE_OVER); + SDB_GET_INT64(pRaw, dataPos, &pTopic->uid, TOPIC_DECODE_OVER); + SDB_GET_INT64(pRaw, dataPos, &pTopic->dbUid, TOPIC_DECODE_OVER); + SDB_GET_INT32(pRaw, dataPos, &pTopic->version, TOPIC_DECODE_OVER); + SDB_GET_INT32(pRaw, dataPos, &pTopic->sqlLen, TOPIC_DECODE_OVER); + SDB_GET_BINARY(pRaw, dataPos, pTopic->sql, pTopic->sqlLen, TOPIC_DECODE_OVER); + SDB_GET_INT32(pRaw, dataPos, &len, TOPIC_DECODE_OVER); + SDB_GET_BINARY(pRaw, dataPos, pTopic->logicalPlan, len, TOPIC_DECODE_OVER); + SDB_GET_INT32(pRaw, dataPos, &len, TOPIC_DECODE_OVER); + SDB_GET_BINARY(pRaw, dataPos, pTopic->physicalPlan, len, TOPIC_DECODE_OVER); SDB_GET_RESERVE(pRaw, dataPos, MND_TOPIC_RESERVE_SIZE, TOPIC_DECODE_OVER) - terrno = 0; + terrno = TSDB_CODE_SUCCESS; TOPIC_DECODE_OVER: - if (terrno != 0) { + if (terrno != TSDB_CODE_SUCCESS) { mError("topic:%s, failed to decode from raw:%p since %s", pTopic->name, pRaw, terrstr()); tfree(pRow); return NULL; @@ -140,18 +139,18 @@ TOPIC_DECODE_OVER: return pRow; } -static int32_t mndTopicActionInsert(SSdb *pSdb, STopicObj *pTopic) { - mTrace("topic:%s, perform insert action, row:%p", pTopic->name, pTopic); +static int32_t mndTopicActionInsert(SSdb *pSdb, SMqTopicObj *pTopic) { + mTrace("topic:%s, perform insert action", pTopic->name); return 0; } -static int32_t mndTopicActionDelete(SSdb *pSdb, STopicObj *pTopic) { - mTrace("topic:%s, perform delete action, row:%p", pTopic->name, pTopic); +static int32_t mndTopicActionDelete(SSdb *pSdb, SMqTopicObj *pTopic) { + mTrace("topic:%s, perform delete action", pTopic->name); return 0; } -static int32_t mndTopicActionUpdate(SSdb *pSdb, STopicObj *pOldTopic, STopicObj *pNewTopic) { - mTrace("topic:%s, perform update action, old_row:%p new_row:%p", pOldTopic->name, pOldTopic, pNewTopic); +static int32_t mndTopicActionUpdate(SSdb *pSdb, SMqTopicObj *pOldTopic, SMqTopicObj *pNewTopic) { + mTrace("topic:%s, perform update action", pOldTopic->name); atomic_exchange_32(&pOldTopic->updateTime, pNewTopic->updateTime); atomic_exchange_32(&pOldTopic->version, pNewTopic->version); @@ -163,16 +162,16 @@ static int32_t mndTopicActionUpdate(SSdb *pSdb, STopicObj *pOldTopic, STopicObj return 0; } -STopicObj *mndAcquireTopic(SMnode *pMnode, char *topicName) { - SSdb *pSdb = pMnode->pSdb; - STopicObj *pTopic = sdbAcquire(pSdb, SDB_TOPIC, topicName); +SMqTopicObj *mndAcquireTopic(SMnode *pMnode, char *topicName) { + SSdb *pSdb = pMnode->pSdb; + SMqTopicObj *pTopic = sdbAcquire(pSdb, SDB_TOPIC, topicName); if (pTopic == NULL) { terrno = TSDB_CODE_MND_TOPIC_NOT_EXIST; } return pTopic; } -void mndReleaseTopic(SMnode *pMnode, STopicObj *pTopic) { +void mndReleaseTopic(SMnode *pMnode, SMqTopicObj *pTopic) { SSdb *pSdb = pMnode->pSdb; sdbRelease(pSdb, pTopic); } @@ -187,10 +186,10 @@ static SDbObj *mndAcquireDbByTopic(SMnode *pMnode, char *topicName) { return mndAcquireDb(pMnode, db); } -static SDDropTopicMsg *mndBuildDropTopicMsg(SMnode *pMnode, SVgObj *pVgroup, STopicObj *pTopic) { - int32_t contLen = sizeof(SDDropTopicMsg); +static SDDropTopicReq *mndBuildDropTopicMsg(SMnode *pMnode, SVgObj *pVgroup, SMqTopicObj *pTopic) { + int32_t contLen = sizeof(SDDropTopicReq); - SDDropTopicMsg *pDrop = calloc(1, contLen); + SDDropTopicReq *pDrop = calloc(1, contLen); if (pDrop == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; @@ -210,7 +209,7 @@ static int32_t mndCheckCreateTopicMsg(SCMCreateTopicReq *pCreate) { } static int32_t mndCreateTopic(SMnode *pMnode, SMnodeMsg *pMsg, SCMCreateTopicReq *pCreate, SDbObj *pDb) { - STopicObj topicObj = {0}; + SMqTopicObj topicObj = {0}; tstrncpy(topicObj.name, pCreate->name, TSDB_TABLE_FNAME_LEN); tstrncpy(topicObj.db, pDb->name, TSDB_DB_FNAME_LEN); topicObj.createTime = taosGetTimestampMs(); @@ -222,6 +221,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SMnodeMsg *pMsg, SCMCreateTopicReq SSdbRaw *pTopicRaw = mndTopicActionEncode(&topicObj); if (pTopicRaw == NULL) return -1; if (sdbSetRawStatus(pTopicRaw, SDB_STATUS_READY) != 0) return -1; + // TODO: replace with trans to support recovery return sdbWrite(pMnode->pSdb, pTopicRaw); } @@ -238,7 +238,7 @@ static int32_t mndProcessCreateTopicMsg(SMnodeMsg *pMsg) { return -1; } - STopicObj *pTopic = mndAcquireTopic(pMnode, pCreate->name); + SMqTopicObj *pTopic = mndAcquireTopic(pMnode, pCreate->name); if (pTopic != NULL) { sdbRelease(pMnode->pSdb, pTopic); if (pCreate->igExists) { @@ -270,15 +270,15 @@ static int32_t mndProcessCreateTopicMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndDropTopic(SMnode *pMnode, SMnodeMsg *pMsg, STopicObj *pTopic) { return 0; } +static int32_t mndDropTopic(SMnode *pMnode, SMnodeMsg *pMsg, SMqTopicObj *pTopic) { return 0; } static int32_t mndProcessDropTopicMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - SDropTopicMsg *pDrop = pMsg->rpcMsg.pCont; + SDropTopicReq *pDrop = pMsg->rpcMsg.pCont; mDebug("topic:%s, start to drop", pDrop->name); - STopicObj *pTopic = mndAcquireTopic(pMnode, pDrop->name); + SMqTopicObj *pTopic = mndAcquireTopic(pMnode, pDrop->name); if (pTopic == NULL) { if (pDrop->igNotExists) { mDebug("topic:%s, not exist, ignore not exist is set", pDrop->name); @@ -309,7 +309,7 @@ static int32_t mndProcessDropTopicInRsp(SMnodeMsg *pMsg) { static int32_t mndProcessTopicMetaMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; - STableInfoMsg *pInfo = pMsg->rpcMsg.pCont; + STableInfoReq *pInfo = pMsg->rpcMsg.pCont; mDebug("topic:%s, start to retrieve meta", pInfo->tableFname); @@ -331,9 +331,9 @@ static int32_t mndProcessTopicMetaMsg(SMnodeMsg *pMsg) { taosRLockLatch(&pTopic->lock); int32_t totalCols = pTopic->numOfColumns + pTopic->numOfTags; - int32_t contLen = sizeof(STableMetaMsg) + totalCols * sizeof(SSchema); + int32_t contLen = sizeof(STableMetaRsp) + totalCols * sizeof(SSchema); - STableMetaMsg *pMeta = rpcMallocCont(contLen); + STableMetaRsp *pMeta = rpcMallocCont(contLen); if (pMeta == NULL) { taosRUnLockLatch(&pTopic->lock); mndReleaseDb(pMnode, pDb); @@ -384,13 +384,11 @@ static int32_t mndGetNumOfTopics(SMnode *pMnode, char *dbName, int32_t *pNumOfTo int32_t numOfTopics = 0; void *pIter = NULL; while (1) { - STopicObj *pTopic = NULL; + SMqTopicObj *pTopic = NULL; pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pTopic); if (pIter == NULL) break; - if (strcmp(pTopic->db, dbName) == 0) { - numOfTopics++; - } + numOfTopics++; sdbRelease(pSdb, pTopic); } @@ -399,7 +397,7 @@ static int32_t mndGetNumOfTopics(SMnode *pMnode, char *dbName, int32_t *pNumOfTo return 0; } -static int32_t mndGetTopicMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { +static int32_t mndGetTopicMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *pMeta) { SMnode *pMnode = pMsg->pMnode; SSdb *pSdb = pMnode->pSdb; @@ -463,13 +461,13 @@ static void mndExtractTableName(char *tableId, char *name) { } static int32_t mndRetrieveTopic(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; - SSdb *pSdb = pMnode->pSdb; - int32_t numOfRows = 0; - STopicObj *pTopic = NULL; - int32_t cols = 0; - char *pWrite; - char prefix[64] = {0}; + SMnode *pMnode = pMsg->pMnode; + SSdb *pSdb = pMnode->pSdb; + int32_t numOfRows = 0; + SMqTopicObj *pTopic = NULL; + int32_t cols = 0; + char *pWrite; + char prefix[64] = {0}; tstrncpy(prefix, pShow->db, 64); strcat(prefix, TS_PATH_DELIMITER); diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index bf472a504c..4a42133ce3 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -24,7 +24,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 *pOldTrans); +static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *OldTrans, STrans *pOld); static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans); static int32_t mndTransAppendLog(SArray *pArray, SSdbRaw *pRaw); @@ -52,7 +52,6 @@ static bool mndTransPerfromFinishedStage(SMnode *pMnode, STrans *pTrans); static void mndTransExecute(SMnode *pMnode, STrans *pTrans); static void mndTransSendRpcRsp(STrans *pTrans); static int32_t mndProcessTransMsg(SMnodeMsg *pMsg); -static int32_t mndProcessTransRsp(SMnodeMsg *pMsg); int32_t mndInitTrans(SMnode *pMnode) { SSdbTable table = {.sdbType = SDB_TRANS, @@ -64,7 +63,6 @@ int32_t mndInitTrans(SMnode *pMnode) { .deleteFp = (SdbDeleteFp)mndTransActionDelete}; mndSetMsgHandle(pMnode, TDMT_MND_TRANS, mndProcessTransMsg); - mndSetMsgHandle(pMnode, TDMT_MND_TRANS_RSP, mndProcessTransRsp); return sdbSetTable(pMnode->pSdb, table); } @@ -114,6 +112,7 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) { int32_t dataPos = 0; SDB_SET_INT32(pRaw, dataPos, pTrans->id, TRANS_ENCODE_OVER) SDB_SET_INT8(pRaw, dataPos, pTrans->policy, TRANS_ENCODE_OVER) + SDB_SET_INT8(pRaw, dataPos, pTrans->stage, TRANS_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, redoLogNum, TRANS_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, undoLogNum, TRANS_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, commitLogNum, TRANS_ENCODE_OVER) @@ -145,6 +144,7 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) { STransAction *pAction = taosArrayGet(pTrans->redoActions, i); SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), TRANS_ENCODE_OVER) SDB_SET_INT16(pRaw, dataPos, pAction->msgType, TRANS_ENCODE_OVER) + SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, TRANS_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, pAction->contLen, TRANS_ENCODE_OVER) SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, TRANS_ENCODE_OVER) } @@ -153,6 +153,7 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) { STransAction *pAction = taosArrayGet(pTrans->undoActions, i); SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), TRANS_ENCODE_OVER) SDB_SET_INT16(pRaw, dataPos, pAction->msgType, TRANS_ENCODE_OVER) + SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, TRANS_ENCODE_OVER) SDB_SET_INT32(pRaw, dataPos, pAction->contLen, TRANS_ENCODE_OVER) SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pCont, pAction->contLen, TRANS_ENCODE_OVER) } @@ -216,6 +217,7 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) { SDB_GET_INT32(pRaw, dataPos, &pTrans->id, TRANS_DECODE_OVER) SDB_GET_INT8(pRaw, dataPos, (int8_t *)&pTrans->policy, TRANS_DECODE_OVER) + SDB_GET_INT8(pRaw, dataPos, (int8_t *)&pTrans->stage, TRANS_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &redoLogNum, TRANS_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &undoLogNum, TRANS_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &commitLogNum, TRANS_DECODE_OVER) @@ -255,6 +257,7 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) { for (int32_t i = 0; i < redoActionNum; ++i) { SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), TRANS_DECODE_OVER); SDB_GET_INT16(pRaw, dataPos, &action.msgType, TRANS_DECODE_OVER) + SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, TRANS_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &action.contLen, TRANS_DECODE_OVER) action.pCont = malloc(action.contLen); if (action.pCont == NULL) goto TRANS_DECODE_OVER; @@ -266,6 +269,7 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) { for (int32_t i = 0; i < undoActionNum; ++i) { SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), TRANS_DECODE_OVER); SDB_GET_INT16(pRaw, dataPos, &action.msgType, TRANS_DECODE_OVER) + SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, TRANS_DECODE_OVER) SDB_GET_INT32(pRaw, dataPos, &action.contLen, TRANS_DECODE_OVER) action.pCont = malloc(action.contLen); if (action.pCont == NULL) goto TRANS_DECODE_OVER; @@ -312,9 +316,12 @@ static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans) { return 0; } -static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOldTrans, STrans *pNewTrans) { - mTrace("trans:%d, perform update action, old_row:%p new_row:%p", pOldTrans->id, pOldTrans, pNewTrans); - pOldTrans->stage = pNewTrans->stage; +static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOld, STrans *pNew) { + if (pNew->stage == TRN_STAGE_COMMIT) pNew->stage = TRN_STAGE_COMMIT_LOG; + + mTrace("trans:%d, perform update action, old row:%p stage:%d, new row:%p stage:%d", pOld->id, pOld, pOld->stage, pNew, + pNew->stage); + pOld->stage = pNew->stage; return 0; } @@ -462,16 +469,16 @@ int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) { } mDebug("trans:%d, prepare finished", pTrans->id); - STrans *pNewTrans = mndAcquireTrans(pMnode, pTrans->id); - if (pNewTrans == NULL) { + STrans *pNew = mndAcquireTrans(pMnode, pTrans->id); + if (pNew == NULL) { mError("trans:%d, failed to read from sdb since %s", pTrans->id, terrstr()); return -1; } - pNewTrans->rpcHandle = pTrans->rpcHandle; - pNewTrans->rpcAHandle = pTrans->rpcAHandle; - mndTransExecute(pMnode, pNewTrans); - mndReleaseTrans(pMnode, pNewTrans); + pNew->rpcHandle = pTrans->rpcHandle; + pNew->rpcAHandle = pTrans->rpcAHandle; + mndTransExecute(pMnode, pNew); + mndReleaseTrans(pMnode, pNew); return 0; } @@ -498,10 +505,31 @@ static int32_t mndTransRollback(SMnode *pMnode, STrans *pTrans) { } static void mndTransSendRpcRsp(STrans *pTrans) { - if (pTrans->rpcHandle != NULL) { - mDebug("trans:%d, send rsp, ahandle:%p code:0x%x", pTrans->id, pTrans->rpcAHandle, pTrans->code & 0xFFFF); + bool sendRsp = false; + + if (pTrans->stage == TRN_STAGE_FINISHED) { + sendRsp = true; + } + + if (pTrans->policy == TRN_POLICY_ROLLBACK) { + if (pTrans->stage == TRN_STAGE_UNDO_LOG || pTrans->stage == TRN_STAGE_UNDO_ACTION || + pTrans->stage == TRN_STAGE_ROLLBACK) { + sendRsp = true; + } + } + + if (pTrans->policy == TRN_POLICY_RETRY) { + if (pTrans->stage == TRN_STAGE_REDO_ACTION && pTrans->failedTimes > 0) { + sendRsp = true; + } + } + + if (sendRsp && pTrans->rpcHandle != NULL) { + mDebug("trans:%d, send rsp, code:0x%x stage:%d app:%p", pTrans->id, pTrans->code & 0xFFFF, pTrans->stage, + pTrans->rpcAHandle); SRpcMsg rspMsg = {.handle = pTrans->rpcHandle, .code = pTrans->code, .ahandle = pTrans->rpcAHandle}; rpcSendResponse(&rspMsg); + pTrans->rpcHandle = NULL; } } @@ -544,7 +572,8 @@ void mndTransProcessRsp(SMnodeMsg *pMsg) { pAction->errCode = pMsg->rpcMsg.code; } - mDebug("trans:%d, action:%d response is received, code:0x%x", transId, action, pMsg->rpcMsg.code); + mDebug("trans:%d, action:%d response is received, code:0x%x, accept:0x%x", transId, action, pMsg->rpcMsg.code, + pAction->acceptableCode); mndTransExecute(pMnode, pTrans); HANDLE_ACTION_RSP_OVER: @@ -615,12 +644,15 @@ static int32_t mndTransSendActionMsg(SMnode *pMnode, STrans *pTrans, SArray *pAr } memcpy(rpcMsg.pCont, pAction->pCont, pAction->contLen); - pAction->msgSent = 1; - pAction->msgReceived = 0; - pAction->errCode = 0; - - mDebug("trans:%d, action:%d is sent", pTrans->id, action); - mndSendMsgToDnode(pMnode, &pAction->epSet, &rpcMsg); + if (mndSendReqToDnode(pMnode, &pAction->epSet, &rpcMsg) == 0) { + mDebug("trans:%d, action:%d is sent", pTrans->id, action); + pAction->msgSent = 1; + pAction->msgReceived = 0; + pAction->errCode = 0; + } else { + mDebug("trans:%d, action:%d not send since %s", pTrans->id, action, terrstr()); + return -1; + } } return 0; @@ -641,7 +673,7 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA if (pAction == NULL) continue; if (pAction->msgSent && pAction->msgReceived) { numOfReceived++; - if (pAction->errCode != 0) { + if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) { errCode = pAction->errCode; } } @@ -689,7 +721,7 @@ static bool mndTransPerformRedoLogStage(SMnode *pMnode, STrans *pTrans) { } else { pTrans->code = terrno; pTrans->stage = TRN_STAGE_UNDO_LOG; - mError("trans:%d, stage from redoLog to undoLog", pTrans->id); + mError("trans:%d, stage from redoLog to undoLog since %s", pTrans->id, terrstr()); } return continueExec; @@ -763,7 +795,6 @@ static bool mndTransPerformCommitLogStage(SMnode *pMnode, STrans *pTrans) { pTrans->failedTimes++; mError("trans:%d, stage keep on commitLog since %s", pTrans->id, terrstr()); continueExec = false; - ; } return continueExec; @@ -790,7 +821,7 @@ static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans) { int32_t code = mndTransExecuteUndoActions(pMnode, pTrans); if (code == 0) { - pTrans->stage = TRN_STAGE_REDO_LOG; + pTrans->stage = TRN_STAGE_UNDO_LOG; mDebug("trans:%d, stage from undoAction to undoLog", pTrans->id); continueExec = true; } else if (code == TSDB_CODE_MND_ACTION_IN_PROGRESS) { @@ -813,7 +844,6 @@ static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans) { pTrans->stage = TRN_STAGE_FINISHED; mDebug("trans:%d, stage from rollback to finished", pTrans->id); continueExec = true; - ; } else { pTrans->failedTimes++; mError("trans:%d, stage keep on rollback since %s", pTrans->id, terrstr()); @@ -879,13 +909,15 @@ static void mndTransExecute(SMnode *pMnode, STrans *pTrans) { } } - if (pTrans->stage == TRN_STAGE_FINISHED) { - mndTransSendRpcRsp(pTrans); - } + mndTransSendRpcRsp(pTrans); } static int32_t mndProcessTransMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; + mndTransPullup(pMsg->pMnode); + return 0; +} + +void mndTransPullup(SMnode *pMnode) { STrans *pTrans = NULL; void *pIter = NULL; @@ -897,5 +929,3 @@ static int32_t mndProcessTransMsg(SMnodeMsg *pMsg) { sdbRelease(pMnode->pSdb, pTrans); } } - -static int32_t mndProcessTransRsp(SMnodeMsg *pMsg) { return 0; } \ No newline at end of file diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 6311d3e8da..ad378953eb 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -16,7 +16,6 @@ #define _DEFAULT_SOURCE #include "mndUser.h" #include "mndShow.h" -#include "mndSync.h" #include "mndTrans.h" #include "tkey.h" @@ -28,13 +27,13 @@ static SSdbRaw *mndUserActionEncode(SUserObj *pUser); static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw); static int32_t mndUserActionInsert(SSdb *pSdb, SUserObj *pUser); static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser); -static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOldUser, SUserObj *pNewUser); -static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, SMnodeMsg *pMsg); -static int32_t mndProcessCreateUserMsg(SMnodeMsg *pMsg); -static int32_t mndProcessAlterUserMsg(SMnodeMsg *pMsg); -static int32_t mndProcessDropUserMsg(SMnodeMsg *pMsg); -static int32_t mndGetUserMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveUsers(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew); +static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, SMnodeMsg *pReq); +static int32_t mndProcessCreateUserReq(SMnodeMsg *pReq); +static int32_t mndProcessAlterUserReq(SMnodeMsg *pReq); +static int32_t mndProcessDropUserReq(SMnodeMsg *pReq); +static int32_t mndGetUserMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveUsers(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextUser(SMnode *pMnode, void *pIter); int32_t mndInitUser(SMnode *pMnode) { @@ -47,9 +46,9 @@ int32_t mndInitUser(SMnode *pMnode) { .updateFp = (SdbUpdateFp)mndUserActionUpdate, .deleteFp = (SdbDeleteFp)mndUserActionDelete}; - mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserMsg); - mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserMsg); - mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserMsg); + mndSetMsgHandle(pMnode, TDMT_MND_CREATE_USER, mndProcessCreateUserReq); + mndSetMsgHandle(pMnode, TDMT_MND_ALTER_USER, mndProcessAlterUserReq); + mndSetMsgHandle(pMnode, TDMT_MND_DROP_USER, mndProcessDropUserReq); mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_USER, mndGetUserMeta); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_USER, mndRetrieveUsers); @@ -192,10 +191,10 @@ static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) { return 0; } -static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOldUser, SUserObj *pNewUser) { - mTrace("user:%s, perform update action, old_row:%p new_row:%p", pOldUser->user, pOldUser, pNewUser); - memcpy(pOldUser->pass, pNewUser->pass, TSDB_PASSWORD_LEN); - pOldUser->updateTime = pNewUser->updateTime; +static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) { + mTrace("user:%s, perform update action, old row:%p new row:%p", pOld->user, pOld, pNew); + memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN); + pOld->updateTime = pNew->updateTime; return 0; } @@ -213,7 +212,7 @@ void mndReleaseUser(SMnode *pMnode, SUserObj *pUser) { sdbRelease(pSdb, pUser); } -static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, SMnodeMsg *pMsg) { +static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, SMnodeMsg *pReq) { SUserObj userObj = {0}; tstrncpy(userObj.user, user, TSDB_USER_LEN); tstrncpy(userObj.acct, acct, TSDB_USER_LEN); @@ -222,7 +221,7 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, userObj.updateTime = userObj.createdTime; userObj.superUser = 0; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg); + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); if (pTrans == NULL) { mError("user:%s, failed to create since %s", user, terrstr()); return -1; @@ -247,9 +246,9 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, return 0; } -static int32_t mndProcessCreateUserMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SCreateUserMsg *pCreate = pMsg->rpcMsg.pCont; +static int32_t mndProcessCreateUserReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SCreateUserReq *pCreate = pReq->rpcMsg.pCont; mDebug("user:%s, start to create", pCreate->user); @@ -273,14 +272,14 @@ static int32_t mndProcessCreateUserMsg(SMnodeMsg *pMsg) { return -1; } - SUserObj *pOperUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pOperUser = mndAcquireUser(pMnode, pReq->user); if (pOperUser == NULL) { terrno = TSDB_CODE_MND_NO_USER_FROM_CONN; mError("user:%s, failed to create since %s", pCreate->user, terrstr()); return -1; } - int32_t code = mndCreateUser(pMnode, pOperUser->acct, pCreate->user, pCreate->pass, pMsg); + int32_t code = mndCreateUser(pMnode, pOperUser->acct, pCreate->user, pCreate->pass, pReq); mndReleaseUser(pMnode, pOperUser); if (code != 0) { @@ -291,15 +290,15 @@ static int32_t mndProcessCreateUserMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndUpdateUser(SMnode *pMnode, SUserObj *pOldUser, SUserObj *pNewUser, SMnodeMsg *pMsg) { - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg); +static int32_t mndUpdateUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SMnodeMsg *pReq) { + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); if (pTrans == NULL) { - mError("user:%s, failed to update since %s", pOldUser->user, terrstr()); + mError("user:%s, failed to update since %s", pOld->user, terrstr()); return -1; } - mDebug("trans:%d, used to update user:%s", pTrans->id, pOldUser->user); + mDebug("trans:%d, used to update user:%s", pTrans->id, pOld->user); - SSdbRaw *pRedoRaw = mndUserActionEncode(pNewUser); + SSdbRaw *pRedoRaw = mndUserActionEncode(pNew); if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); @@ -317,9 +316,9 @@ static int32_t mndUpdateUser(SMnode *pMnode, SUserObj *pOldUser, SUserObj *pNewU return 0; } -static int32_t mndProcessAlterUserMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SAlterUserMsg *pAlter = pMsg->rpcMsg.pCont; +static int32_t mndProcessAlterUserReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SAlterUserReq *pAlter = pReq->rpcMsg.pCont; mDebug("user:%s, start to alter", pAlter->user); @@ -342,7 +341,7 @@ static int32_t mndProcessAlterUserMsg(SMnodeMsg *pMsg) { return -1; } - SUserObj *pOperUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pOperUser = mndAcquireUser(pMnode, pReq->user); if (pOperUser == NULL) { mndReleaseUser(pMnode, pUser); terrno = TSDB_CODE_MND_NO_USER_FROM_CONN; @@ -356,7 +355,7 @@ static int32_t mndProcessAlterUserMsg(SMnodeMsg *pMsg) { taosEncryptPass((uint8_t *)pAlter->pass, strlen(pAlter->pass), pUser->pass); newUser.updateTime = taosGetTimestampMs(); - int32_t code = mndUpdateUser(pMnode, pUser, &newUser, pMsg); + int32_t code = mndUpdateUser(pMnode, pUser, &newUser, pReq); mndReleaseUser(pMnode, pOperUser); mndReleaseUser(pMnode, pUser); @@ -368,8 +367,8 @@ static int32_t mndProcessAlterUserMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndDropUser(SMnode *pMnode, SMnodeMsg *pMsg, SUserObj *pUser) { - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pMsg->rpcMsg); +static int32_t mndDropUser(SMnode *pMnode, SMnodeMsg *pReq, SUserObj *pUser) { + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, &pReq->rpcMsg); if (pTrans == NULL) { mError("user:%s, failed to drop since %s", pUser->user, terrstr()); return -1; @@ -394,9 +393,9 @@ static int32_t mndDropUser(SMnode *pMnode, SMnodeMsg *pMsg, SUserObj *pUser) { return 0; } -static int32_t mndProcessDropUserMsg(SMnodeMsg *pMsg) { - SMnode *pMnode = pMsg->pMnode; - SDropUserMsg *pDrop = pMsg->rpcMsg.pCont; +static int32_t mndProcessDropUserReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + SDropUserReq *pDrop = pReq->rpcMsg.pCont; mDebug("user:%s, start to drop", pDrop->user); @@ -413,7 +412,7 @@ static int32_t mndProcessDropUserMsg(SMnodeMsg *pMsg) { return -1; } - SUserObj *pOperUser = mndAcquireUser(pMnode, pMsg->user); + SUserObj *pOperUser = mndAcquireUser(pMnode, pReq->user); if (pOperUser == NULL) { mndReleaseUser(pMnode, pUser); terrno = TSDB_CODE_MND_NO_USER_FROM_CONN; @@ -421,7 +420,7 @@ static int32_t mndProcessDropUserMsg(SMnodeMsg *pMsg) { return -1; } - int32_t code = mndDropUser(pMnode, pMsg, pUser); + int32_t code = mndDropUser(pMnode, pReq, pUser); mndReleaseUser(pMnode, pOperUser); mndReleaseUser(pMnode, pUser); @@ -433,8 +432,8 @@ static int32_t mndProcessDropUserMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndGetUserMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetUserMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -479,8 +478,8 @@ static int32_t mndGetUserMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *p return 0; } -static int32_t mndRetrieveUsers(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveUsers(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; SUserObj *pUser = NULL; diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index bd17c6d150..4b7b370371 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -27,19 +27,19 @@ static SSdbRow *mndVgroupActionDecode(SSdbRaw *pRaw); static int32_t mndVgroupActionInsert(SSdb *pSdb, SVgObj *pVgroup); static int32_t mndVgroupActionDelete(SSdb *pSdb, SVgObj *pVgroup); -static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOldVgroup, SVgObj *pNewVgroup); +static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew); -static int32_t mndProcessCreateVnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessAlterVnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessDropVnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessSyncVnodeRsp(SMnodeMsg *pMsg); -static int32_t mndProcessCompactVnodeRsp(SMnodeMsg *pMsg); +static int32_t mndProcessCreateVnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessAlterVnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessDropVnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessSyncVnodeRsp(SMnodeMsg *pRsp); +static int32_t mndProcessCompactVnodeRsp(SMnodeMsg *pRsp); -static int32_t mndGetVgroupMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveVgroups(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndGetVgroupMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveVgroups(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextVgroup(SMnode *pMnode, void *pIter); -static int32_t mndGetVnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); -static int32_t mndRetrieveVnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); +static int32_t mndGetVnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta); +static int32_t mndRetrieveVnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows); static void mndCancelGetNextVnode(SMnode *pMnode, void *pIter); int32_t mndInitVgroup(SMnode *pMnode) { @@ -164,14 +164,14 @@ static int32_t mndVgroupActionDelete(SSdb *pSdb, SVgObj *pVgroup) { return 0; } -static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOldVgroup, SVgObj *pNewVgroup) { - mTrace("vgId:%d, perform update action, old_row:%p new_row:%p", pOldVgroup->vgId, pOldVgroup, pNewVgroup); - pOldVgroup->updateTime = pNewVgroup->updateTime; - pOldVgroup->version = pNewVgroup->version; - pOldVgroup->hashBegin = pNewVgroup->hashBegin; - pOldVgroup->hashEnd = pNewVgroup->hashEnd; - pOldVgroup->replica = pNewVgroup->replica; - memcpy(pOldVgroup->vnodeGid, pNewVgroup->vnodeGid, TSDB_MAX_REPLICA * sizeof(SVnodeGid)); +static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew) { + mTrace("vgId:%d, perform update action, old row:%p new row:%p", pOld->vgId, pOld, pNew); + pOld->updateTime = pNew->updateTime; + pOld->version = pNew->version; + pOld->hashBegin = pNew->hashBegin; + pOld->hashEnd = pNew->hashEnd; + pOld->replica = pNew->replica; + memcpy(pOld->vnodeGid, pNew->vnodeGid, TSDB_MAX_REPLICA * sizeof(SVnodeGid)); return 0; } @@ -189,8 +189,8 @@ void mndReleaseVgroup(SMnode *pMnode, SVgObj *pVgroup) { sdbRelease(pSdb, pVgroup); } -SCreateVnodeMsg *mndBuildCreateVnodeMsg(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup) { - SCreateVnodeMsg *pCreate = calloc(1, sizeof(SCreateVnodeMsg)); +SCreateVnodeReq *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup) { + SCreateVnodeReq *pCreate = calloc(1, sizeof(SCreateVnodeReq)); if (pCreate == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; @@ -248,8 +248,8 @@ SCreateVnodeMsg *mndBuildCreateVnodeMsg(SMnode *pMnode, SDnodeObj *pDnode, SDbOb return pCreate; } -SDropVnodeMsg *mndBuildDropVnodeMsg(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup) { - SDropVnodeMsg *pDrop = calloc(1, sizeof(SDropVnodeMsg)); +SDropVnodeReq *mndBuildDropVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup) { + SDropVnodeReq *pDrop = calloc(1, sizeof(SDropVnodeReq)); if (pDrop == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; @@ -427,24 +427,24 @@ SEpSet mndGetVgroupEpset(SMnode *pMnode, SVgObj *pVgroup) { return epset; } -static int32_t mndProcessCreateVnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessCreateVnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndProcessAlterVnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessAlterVnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndProcessDropVnodeRsp(SMnodeMsg *pMsg) { - mndTransProcessRsp(pMsg); +static int32_t mndProcessDropVnodeRsp(SMnodeMsg *pRsp) { + mndTransProcessRsp(pRsp); return 0; } -static int32_t mndProcessSyncVnodeRsp(SMnodeMsg *pMsg) { return 0; } +static int32_t mndProcessSyncVnodeRsp(SMnodeMsg *pRsp) { return 0; } -static int32_t mndProcessCompactVnodeRsp(SMnodeMsg *pMsg) { return 0; } +static int32_t mndProcessCompactVnodeRsp(SMnodeMsg *pRsp) { return 0; } static bool mndGetVgroupMaxReplicaFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) { SVgObj *pVgroup = pObj; @@ -475,8 +475,8 @@ static int32_t mndGetVgroupMaxReplica(SMnode *pMnode, char *dbName, int8_t *pRep return 0; } -static int32_t mndGetVgroupMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetVgroupMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; if (mndGetVgroupMaxReplica(pMnode, pShow->db, &pShow->replica, &pShow->numOfRows) != 0) { @@ -526,8 +526,8 @@ static int32_t mndGetVgroupMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg return 0; } -static int32_t mndRetrieveVgroups(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveVgroups(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; SVgObj *pVgroup = NULL; @@ -593,8 +593,8 @@ int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId) { return numOfVnodes; } -static int32_t mndGetVnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndGetVnodeMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t cols = 0; @@ -633,8 +633,8 @@ static int32_t mndGetVnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * return 0; } -static int32_t mndRetrieveVnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) { - SMnode *pMnode = pMsg->pMnode; +static int32_t mndRetrieveVnodes(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) { + SMnode *pMnode = pReq->pMnode; SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; SVgObj *pVgroup = NULL; diff --git a/source/dnode/mnode/impl/src/mnode.c b/source/dnode/mnode/impl/src/mnode.c index abc86a7d35..d70c93e758 100644 --- a/source/dnode/mnode/impl/src/mnode.c +++ b/source/dnode/mnode/impl/src/mnode.c @@ -34,33 +34,36 @@ #include "mndUser.h" #include "mndVgroup.h" -void mndSendMsgToDnode(SMnode *pMnode, SEpSet *pEpSet, SRpcMsg *pMsg) { - if (pMnode != NULL && pMnode->sendMsgToDnodeFp != NULL) { - (*pMnode->sendMsgToDnodeFp)(pMnode->pDnode, pEpSet, pMsg); +int32_t mndSendReqToDnode(SMnode *pMnode, SEpSet *pEpSet, SRpcMsg *pMsg) { + if (pMnode == NULL || pMnode->sendReqToDnodeFp == NULL) { + terrno = TSDB_CODE_MND_NOT_READY; + return -1; } + + return (*pMnode->sendReqToDnodeFp)(pMnode->pDnode, pEpSet, pMsg); } -void mndSendMsgToMnode(SMnode *pMnode, SRpcMsg *pMsg) { - if (pMnode != NULL && pMnode->sendMsgToMnodeFp != NULL) { - (*pMnode->sendMsgToMnodeFp)(pMnode->pDnode, pMsg); +int32_t mndSendReqToMnode(SMnode *pMnode, SRpcMsg *pMsg) { + if (pMnode == NULL || pMnode->sendReqToDnodeFp == NULL) { + terrno = TSDB_CODE_MND_NOT_READY; + return -1; } + + return (*pMnode->sendReqToMnodeFp)(pMnode->pDnode, pMsg); } -void mndSendRedirectMsg(SMnode *pMnode, SRpcMsg *pMsg) { - if (pMnode != NULL && pMnode->sendRedirectMsgFp != NULL) { - (*pMnode->sendRedirectMsgFp)(pMnode->pDnode, pMsg); +void mndSendRedirectRsp(SMnode *pMnode, SRpcMsg *pMsg) { + if (pMnode != NULL && pMnode->sendRedirectRspFp != NULL) { + (*pMnode->sendRedirectRspFp)(pMnode->pDnode, pMsg); } } static void mndTransReExecute(void *param, void *tmrId) { SMnode *pMnode = param; if (mndIsMaster(pMnode)) { - STransMsg *pMsg = rpcMallocCont(sizeof(STransMsg)); - SEpSet epSet = {.inUse = 0, .numOfEps = 1}; - epSet.port[0] = pMnode->replicas[pMnode->selfIndex].port; - memcpy(epSet.fqdn[0], pMnode->replicas[pMnode->selfIndex].fqdn, TSDB_FQDN_LEN); - SRpcMsg rpcMsg = {.msgType = TDMT_MND_TRANS, .pCont = pMsg, .contLen = sizeof(STransMsg)}; - mndSendMsgToDnode(pMnode, &epSet, &rpcMsg); + STransReq *pMsg = rpcMallocCont(sizeof(STransReq)); + SRpcMsg rpcMsg = {.msgType = TDMT_MND_TRANS, .pCont = pMsg, .contLen = sizeof(STransReq)}; + pMnode->putReqToMWriteQFp(pMnode->pDnode, &rpcMsg); } taosTmrReset(mndTransReExecute, 3000, pMnode, pMnode->timer, &pMnode->transTimer); @@ -76,7 +79,7 @@ static int32_t mndInitTimer(SMnode *pMnode) { return -1; } - if (taosTmrReset(mndTransReExecute, 1000, pMnode, pMnode->timer, &pMnode->transTimer)) { + if (taosTmrReset(mndTransReExecute, 6000, pMnode, pMnode->timer, &pMnode->transTimer)) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } @@ -223,9 +226,10 @@ static int32_t mndSetOptions(SMnode *pMnode, const SMnodeOpt *pOption) { pMnode->selfIndex = pOption->selfIndex; memcpy(&pMnode->replicas, pOption->replicas, sizeof(SReplica) * TSDB_MAX_REPLICA); pMnode->pDnode = pOption->pDnode; - pMnode->sendMsgToDnodeFp = pOption->sendMsgToDnodeFp; - pMnode->sendMsgToMnodeFp = pOption->sendMsgToMnodeFp; - pMnode->sendRedirectMsgFp = pOption->sendRedirectMsgFp; + pMnode->putReqToMWriteQFp = pOption->putReqToMWriteQFp; + pMnode->sendReqToDnodeFp = pOption->sendReqToDnodeFp; + pMnode->sendReqToMnodeFp = pOption->sendReqToMnodeFp; + pMnode->sendRedirectRspFp = pOption->sendRedirectRspFp; pMnode->cfg.sver = pOption->cfg.sver; pMnode->cfg.enableTelem = pOption->cfg.enableTelem; pMnode->cfg.statusInterval = pOption->cfg.statusInterval; @@ -236,8 +240,9 @@ static int32_t mndSetOptions(SMnode *pMnode, const SMnodeOpt *pOption) { pMnode->cfg.gitinfo = strdup(pOption->cfg.gitinfo); pMnode->cfg.buildinfo = strdup(pOption->cfg.buildinfo); - if (pMnode->sendMsgToDnodeFp == NULL || pMnode->sendMsgToMnodeFp == NULL || pMnode->sendRedirectMsgFp == NULL || - pMnode->dnodeId < 0 || pMnode->clusterId < 0 || pMnode->cfg.statusInterval < 1) { + if (pMnode->sendReqToDnodeFp == NULL || pMnode->sendReqToMnodeFp == NULL || pMnode->sendRedirectRspFp == NULL || + pMnode->putReqToMWriteQFp == NULL || pMnode->dnodeId < 0 || pMnode->clusterId < 0 || + pMnode->cfg.statusInterval < 1) { terrno = TSDB_CODE_MND_INVALID_OPTIONS; return -1; } @@ -361,14 +366,16 @@ SMnodeMsg *mndInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg) { return NULL; } - SRpcConnInfo connInfo = {0}; - if ((pRpcMsg->msgType & 1U) && rpcGetConnInfo(pRpcMsg->handle, &connInfo) != 0) { - taosFreeQitem(pMsg); - terrno = TSDB_CODE_MND_NO_USER_FROM_CONN; - mError("failed to create msg since %s, app:%p RPC:%p", terrstr(), pRpcMsg->ahandle, pRpcMsg->handle); - return NULL; + if (pRpcMsg->msgType != TDMT_MND_TRANS) { + SRpcConnInfo connInfo = {0}; + if ((pRpcMsg->msgType & 1U) && rpcGetConnInfo(pRpcMsg->handle, &connInfo) != 0) { + taosFreeQitem(pMsg); + terrno = TSDB_CODE_MND_NO_USER_FROM_CONN; + mError("failed to create msg since %s, app:%p RPC:%p", terrstr(), pRpcMsg->ahandle, pRpcMsg->handle); + return NULL; + } + memcpy(pMsg->user, connInfo.user, TSDB_USER_LEN); } - memcpy(pMsg->user, connInfo.user, TSDB_USER_LEN); pMsg->pMnode = pMnode; pMsg->rpcMsg = *pRpcMsg; @@ -433,7 +440,7 @@ void mndProcessMsg(SMnodeMsg *pMsg) { PROCESS_RPC_END: if (isReq) { if (code == TSDB_CODE_APP_NOT_READY) { - mndSendRedirectMsg(pMnode, &pMsg->rpcMsg); + mndSendRedirectRsp(pMnode, &pMsg->rpcMsg); } else if (code != 0) { SRpcMsg rpcRsp = {.handle = pMsg->rpcMsg.handle, .code = code}; rpcSendResponse(&rpcRsp); diff --git a/source/dnode/mnode/impl/test/CMakeLists.txt b/source/dnode/mnode/impl/test/CMakeLists.txt index dfac7a76c9..3ca35d58a7 100644 --- a/source/dnode/mnode/impl/test/CMakeLists.txt +++ b/source/dnode/mnode/impl/test/CMakeLists.txt @@ -1,5 +1,14 @@ enable_testing() -add_subdirectory(acct) add_subdirectory(user) +add_subdirectory(acct) add_subdirectory(trans) +add_subdirectory(qnode) +add_subdirectory(snode) +add_subdirectory(bnode) +add_subdirectory(show) +add_subdirectory(profile) +add_subdirectory(dnode) +add_subdirectory(mnode) +add_subdirectory(db) +add_subdirectory(stb) diff --git a/source/dnode/mnode/impl/test/acct/acct.cpp b/source/dnode/mnode/impl/test/acct/acct.cpp index 5f105d99f3..315f23f798 100644 --- a/source/dnode/mnode/impl/test/acct/acct.cpp +++ b/source/dnode/mnode/impl/test/acct/acct.cpp @@ -3,15 +3,15 @@ * @author slguan (slguan@taosdata.com) * @brief MNODE module acct tests * @version 1.0 - * @date 2021-12-15 + * @date 2022-01-04 * * @copyright Copyright (c) 2022 * */ -#include "base.h" +#include "sut.h" -class DndTestAcct : public ::testing::Test { +class MndTestAcct : public ::testing::Test { protected: static void SetUpTestSuite() { test.Init("/tmp/mnode_test_acct", 9012); } static void TearDownTestSuite() { test.Cleanup(); } @@ -23,45 +23,45 @@ class DndTestAcct : public ::testing::Test { void TearDown() override {} }; -Testbase DndTestAcct::test; +Testbase MndTestAcct::test; -TEST_F(DndTestAcct, 01_CreateAcct) { - int32_t contLen = sizeof(SCreateAcctMsg); +TEST_F(MndTestAcct, 01_Create_Acct) { + int32_t contLen = sizeof(SCreateAcctReq); - SCreateAcctMsg* pReq = (SCreateAcctMsg*)rpcMallocCont(contLen); + SCreateAcctReq* pReq = (SCreateAcctReq*)rpcMallocCont(contLen); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_ACCT, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_MSG_NOT_PROCESSED); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_ACCT, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_MSG_NOT_PROCESSED); } -TEST_F(DndTestAcct, 02_AlterAcct) { - int32_t contLen = sizeof(SCreateAcctMsg); +TEST_F(MndTestAcct, 02_Alter_Acct) { + int32_t contLen = sizeof(SCreateAcctReq); - SAlterAcctMsg* pReq = (SAlterAcctMsg*)rpcMallocCont(contLen); + SAlterAcctReq* pReq = (SAlterAcctReq*)rpcMallocCont(contLen); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_ALTER_ACCT, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_MSG_NOT_PROCESSED); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_ALTER_ACCT, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_MSG_NOT_PROCESSED); } -TEST_F(DndTestAcct, 03_DropAcct) { - int32_t contLen = sizeof(SDropAcctMsg); +TEST_F(MndTestAcct, 03_Drop_Acct) { + int32_t contLen = sizeof(SDropAcctReq); - SDropAcctMsg* pReq = (SDropAcctMsg*)rpcMallocCont(contLen); + SDropAcctReq* pReq = (SDropAcctReq*)rpcMallocCont(contLen); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_ACCT, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_MSG_NOT_PROCESSED); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_ACCT, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_MSG_NOT_PROCESSED); } -TEST_F(DndTestAcct, 04_ShowAcct) { - int32_t contLen = sizeof(SShowMsg); +TEST_F(MndTestAcct, 04_Show_Acct) { + int32_t contLen = sizeof(SShowReq); - SShowMsg* pReq = (SShowMsg*)rpcMallocCont(contLen); + SShowReq* pReq = (SShowReq*)rpcMallocCont(contLen); pReq->type = TSDB_MGMT_TABLE_ACCT; - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_SHOW, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_MSG_TYPE); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_SHOW, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_MSG_TYPE); } \ No newline at end of file diff --git a/source/dnode/mnode/impl/test/bnode/CMakeLists.txt b/source/dnode/mnode/impl/test/bnode/CMakeLists.txt new file mode 100644 index 0000000000..b58b1a856b --- /dev/null +++ b/source/dnode/mnode/impl/test/bnode/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. STEST_SRC) +add_executable(mnode_test_bnode ${STEST_SRC}) +target_link_libraries( + mnode_test_bnode + PUBLIC sut +) + +add_test( + NAME mnode_test_bnode + COMMAND mnode_test_bnode +) diff --git a/source/dnode/mnode/impl/test/bnode/bnode.cpp b/source/dnode/mnode/impl/test/bnode/bnode.cpp new file mode 100644 index 0000000000..0b54a9bf4a --- /dev/null +++ b/source/dnode/mnode/impl/test/bnode/bnode.cpp @@ -0,0 +1,290 @@ +/** + * @file bnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief MNODE module bnode tests + * @version 1.0 + * @date 2022-01-05 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class MndTestBnode : public ::testing::Test { + public: + void SetUp() override {} + void TearDown() override {} + + public: + static void SetUpTestSuite() { + test.Init("/tmp/mnode_test_bnode1", 9018); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9018"; + + server2.Start("/tmp/mnode_test_bnode2", fqdn, 9019, firstEp); + taosMsleep(300); + } + + static void TearDownTestSuite() { + server2.Stop(); + test.Cleanup(); + } + + static Testbase test; + static TestServer server2; +}; + +Testbase MndTestBnode::test; +TestServer MndTestBnode::server2; + +TEST_F(MndTestBnode, 01_Show_Bnode) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_BNODE, ""); + CHECK_META("show bnodes", 3); + + CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); + CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 0); +} + +TEST_F(MndTestBnode, 02_Create_Bnode) { + { + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_DNODE_NOT_EXIST); + } + + { + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_BNODE, ""); + CHECK_META("show bnodes", 3); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9018", TSDB_EP_LEN); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_BNODE_ALREADY_EXIST); + } +} + +TEST_F(MndTestBnode, 03_Drop_Bnode) { + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9019); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + taosMsleep(1300); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + } + + { + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_BNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + + CheckInt16(1); + CheckInt16(2); + CheckBinary("localhost:9018", TSDB_EP_LEN); + CheckBinary("localhost:9019", TSDB_EP_LEN); + CheckTimestamp(); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMDropBnodeReq); + + SMDropBnodeReq* pReq = (SMDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_BNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9018", TSDB_EP_LEN); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMDropBnodeReq); + + SMDropBnodeReq* pReq = (SMDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_BNODE_NOT_EXIST); + } +} + +TEST_F(MndTestBnode, 03_Create_Bnode_Rollback) { + { + // send message first, then dnode2 crash, result is returned, and rollback is started + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + { + // continue send message, bnode is creating + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_CREATING); + } + + { + // continue send message, bnode is creating + int32_t contLen = sizeof(SMDropBnodeReq); + + SMDropBnodeReq* pReq = (SMDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_CREATING); + } + + { + // server start, wait until the rollback finished + server2.DoStart(); + taosMsleep(1000); + + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == 0) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + } +} + +TEST_F(MndTestBnode, 04_Drop_Bnode_Rollback) { + { + // send message first, then dnode2 crash, result is returned, and rollback is started + int32_t contLen = sizeof(SMDropBnodeReq); + + SMDropBnodeReq* pReq = (SMDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + { + // continue send message, bnode is dropping + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_DROPPING); + } + + { + // continue send message, bnode is dropping + int32_t contLen = sizeof(SMDropBnodeReq); + + SMDropBnodeReq* pReq = (SMDropBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_DROPPING); + } + + { + // server start, wait until the rollback finished + server2.DoStart(); + taosMsleep(1000); + + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateBnodeReq); + + SMCreateBnodeReq* pReq = (SMCreateBnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_BNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == 0) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + } +} \ No newline at end of file diff --git a/source/dnode/mnode/impl/test/db/CMakeLists.txt b/source/dnode/mnode/impl/test/db/CMakeLists.txt new file mode 100644 index 0000000000..f0abdf152c --- /dev/null +++ b/source/dnode/mnode/impl/test/db/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. DB_SRC) +add_executable(mnode_test_db ${DB_SRC}) +target_link_libraries( + mnode_test_db + PUBLIC sut +) + +add_test( + NAME mnode_test_db + COMMAND mnode_test_db +) diff --git a/source/dnode/mgmt/impl/test/db/db.cpp b/source/dnode/mnode/impl/test/db/db.cpp similarity index 72% rename from source/dnode/mgmt/impl/test/db/db.cpp rename to source/dnode/mnode/impl/test/db/db.cpp index 7ba19677fd..4f0ba9b0e7 100644 --- a/source/dnode/mgmt/impl/test/db/db.cpp +++ b/source/dnode/mnode/impl/test/db/db.cpp @@ -1,32 +1,43 @@ /** * @file db.cpp * @author slguan (slguan@taosdata.com) - * @brief DNODE module db-msg tests - * @version 0.1 - * @date 2021-12-15 + * @brief MNODE module db tests + * @version 1.0 + * @date 2022-01-11 * - * @copyright Copyright (c) 2021 + * @copyright Copyright (c) 2022 * */ -#include "base.h" +#include "sut.h" -class DndTestDb : public ::testing::Test { +class MndTestDb : public ::testing::Test { protected: - static void SetUpTestSuite() { test.Init("/tmp/dnode_test_db", 9040); } - static void TearDownTestSuite() { test.Cleanup(); } + static void SetUpTestSuite() { + test.Init("/tmp/mnode_test_db", 9030); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9030"; - static Testbase test; + server2.Start("/tmp/mnode_test_db2", fqdn, 9031, firstEp); + } + static void TearDownTestSuite() { + server2.Stop(); + test.Cleanup(); + } + + static Testbase test; + static TestServer server2; public: void SetUp() override {} void TearDown() override {} }; -Testbase DndTestDb::test; +Testbase MndTestDb::test; +TestServer MndTestDb::server2; -TEST_F(DndTestDb, 01_ShowDb) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); +TEST_F(MndTestDb, 01_ShowDb) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); CHECK_META("show databases", 18); CHECK_SCHEMA(0, TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN - 1 + VARSTR_HEADER_SIZE, "name"); CHECK_SCHEMA(1, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); @@ -47,15 +58,15 @@ TEST_F(DndTestDb, 01_ShowDb) { CHECK_SCHEMA(16, TSDB_DATA_TYPE_BINARY, 3 + VARSTR_HEADER_SIZE, "precision"); CHECK_SCHEMA(17, TSDB_DATA_TYPE_TINYINT, 1, "update"); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 0); } -TEST_F(DndTestDb, 02_Create_Alter_Drop_Db) { +TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) { { - int32_t contLen = sizeof(SCreateDbMsg); + int32_t contLen = sizeof(SCreateDbReq); - SCreateDbMsg* pReq = (SCreateDbMsg*)rpcMallocCont(contLen); + SCreateDbReq* pReq = (SCreateDbReq*)rpcMallocCont(contLen); strcpy(pReq->db, "1.d1"); pReq->numOfVgroups = htonl(2); pReq->cacheBlockSize = htonl(16); @@ -77,15 +88,15 @@ TEST_F(DndTestDb, 02_Create_Alter_Drop_Db) { pReq->cacheLastRow = 0; pReq->ignoreExist = 1; - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DB, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DB, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); CHECK_META("show databases", 18); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); CheckBinary("d1", TSDB_DB_NAME_LEN - 1); CheckTimestamp(); @@ -106,14 +117,14 @@ TEST_F(DndTestDb, 02_Create_Alter_Drop_Db) { CheckBinary("ms", 3); // precision CheckInt8(0); // update - test.SendShowMetaMsg(TSDB_MGMT_TABLE_VGROUP, "1.d1"); + test.SendShowMetaReq(TSDB_MGMT_TABLE_VGROUP, "1.d1"); CHECK_META("show vgroups", 4); CHECK_SCHEMA(0, TSDB_DATA_TYPE_INT, 4, "vgId"); CHECK_SCHEMA(1, TSDB_DATA_TYPE_INT, 4, "tables"); CHECK_SCHEMA(2, TSDB_DATA_TYPE_SMALLINT, 2, "v1_dnode"); CHECK_SCHEMA(3, TSDB_DATA_TYPE_BINARY, 9 + VARSTR_HEADER_SIZE, "v1_status"); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 2); CheckInt32(2); CheckInt32(3); @@ -125,9 +136,9 @@ TEST_F(DndTestDb, 02_Create_Alter_Drop_Db) { CheckBinary("master", 9); { - int32_t contLen = sizeof(SAlterDbMsg); + int32_t contLen = sizeof(SAlterDbReq); - SAlterDbMsg* pReq = (SAlterDbMsg*)rpcMallocCont(contLen); + SAlterDbReq* pReq = (SAlterDbReq*)rpcMallocCont(contLen); strcpy(pReq->db, "1.d1"); pReq->totalBlocks = htonl(12); pReq->daysToKeep0 = htonl(300); @@ -138,18 +149,18 @@ TEST_F(DndTestDb, 02_Create_Alter_Drop_Db) { pReq->quorum = 2; pReq->cacheLastRow = 1; - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_ALTER_DB, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_ALTER_DB, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); - test.SendShowRetrieveMsg(); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); CheckBinary("d1", TSDB_DB_NAME_LEN - 1); CheckTimestamp(); CheckInt16(2); // vgroups - CheckInt32(0); + CheckInt32(0); // tables CheckInt16(1); // replica CheckInt16(2); // quorum CheckInt16(10); // days @@ -168,16 +179,16 @@ TEST_F(DndTestDb, 02_Create_Alter_Drop_Db) { // restart test.Restart(); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); CHECK_META("show databases", 18); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); CheckBinary("d1", TSDB_DB_NAME_LEN - 1); CheckTimestamp(); CheckInt16(2); // vgroups - CheckInt32(0); + CheckInt32(0); // tables CheckInt16(1); // replica CheckInt16(2); // quorum CheckInt16(10); // days @@ -194,28 +205,28 @@ TEST_F(DndTestDb, 02_Create_Alter_Drop_Db) { CheckInt8(0); // update { - int32_t contLen = sizeof(SDropDbMsg); + int32_t contLen = sizeof(SDropDbReq); - SDropDbMsg* pReq = (SDropDbMsg*)rpcMallocCont(contLen); + SDropDbReq* pReq = (SDropDbReq*)rpcMallocCont(contLen); strcpy(pReq->db, "1.d1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_DB, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_DB, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); CHECK_META("show databases", 18); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 0); } -TEST_F(DndTestDb, 03_Create_Use_Restart_Use_Db) { +TEST_F(MndTestDb, 03_Create_Use_Restart_Use_Db) { { - int32_t contLen = sizeof(SCreateDbMsg); + int32_t contLen = sizeof(SCreateDbReq); - SCreateDbMsg* pReq = (SCreateDbMsg*)rpcMallocCont(contLen); + SCreateDbReq* pReq = (SCreateDbReq*)rpcMallocCont(contLen); strcpy(pReq->db, "1.d2"); pReq->numOfVgroups = htonl(2); pReq->cacheBlockSize = htonl(16); @@ -237,26 +248,26 @@ TEST_F(DndTestDb, 03_Create_Use_Restart_Use_Db) { pReq->cacheLastRow = 0; pReq->ignoreExist = 1; - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DB, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DB, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, ""); CHECK_META("show databases", 18); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); CheckBinary("d2", TSDB_DB_NAME_LEN - 1); { - int32_t contLen = sizeof(SUseDbMsg); + int32_t contLen = sizeof(SUseDbReq); - SUseDbMsg* pReq = (SUseDbMsg*)rpcMallocCont(contLen); + SUseDbReq* pReq = (SUseDbReq*)rpcMallocCont(contLen); strcpy(pReq->db, "1.d2"); pReq->vgVersion = htonl(-1); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_USE_DB, pReq, contLen); + SRpcMsg* pMsg = test.SendReq(TDMT_MND_USE_DB, pReq, contLen); ASSERT_NE(pMsg, nullptr); ASSERT_EQ(pMsg->code, 0); @@ -279,9 +290,9 @@ TEST_F(DndTestDb, 03_Create_Use_Restart_Use_Db) { EXPECT_EQ(pInfo->hashEnd, UINT32_MAX / 2 - 1); EXPECT_EQ(pInfo->inUse, 0); EXPECT_EQ(pInfo->numOfEps, 1); - SEpAddrMsg* pAddr = &pInfo->epAddr[0]; + SEpAddr* pAddr = &pInfo->epAddr[0]; pAddr->port = htons(pAddr->port); - EXPECT_EQ(pAddr->port, 9040); + EXPECT_EQ(pAddr->port, 9030); EXPECT_STREQ(pAddr->fqdn, "localhost"); } @@ -295,10 +306,21 @@ TEST_F(DndTestDb, 03_Create_Use_Restart_Use_Db) { EXPECT_EQ(pInfo->hashEnd, UINT32_MAX); EXPECT_EQ(pInfo->inUse, 0); EXPECT_EQ(pInfo->numOfEps, 1); - SEpAddrMsg* pAddr = &pInfo->epAddr[0]; + SEpAddr* pAddr = &pInfo->epAddr[0]; pAddr->port = htons(pAddr->port); - EXPECT_EQ(pAddr->port, 9040); + EXPECT_EQ(pAddr->port, 9030); EXPECT_STREQ(pAddr->fqdn, "localhost"); } } + + { + int32_t contLen = sizeof(SDropDbReq); + + SDropDbReq* pReq = (SDropDbReq*)rpcMallocCont(contLen); + strcpy(pReq->db, "1.d2"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_DB, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } } diff --git a/source/dnode/mnode/impl/test/dnode/CMakeLists.txt b/source/dnode/mnode/impl/test/dnode/CMakeLists.txt new file mode 100644 index 0000000000..e29c5e8f3d --- /dev/null +++ b/source/dnode/mnode/impl/test/dnode/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. DTEST_SRC) +add_executable(mnode_test_dnode ${DTEST_SRC}) +target_link_libraries( + mnode_test_dnode + PUBLIC sut +) + +add_test( + NAME mnode_test_dnode + COMMAND mnode_test_dnode +) diff --git a/source/dnode/mnode/impl/test/dnode/dnode.cpp b/source/dnode/mnode/impl/test/dnode/dnode.cpp new file mode 100644 index 0000000000..1c0cfb7bfc --- /dev/null +++ b/source/dnode/mnode/impl/test/dnode/dnode.cpp @@ -0,0 +1,350 @@ +/** + * @file dnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief MNODE module dnode tests + * @version 1.0 + * @date 2022-01-06 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class MndTestDnode : public ::testing::Test { + public: + void SetUp() override {} + void TearDown() override {} + + public: + static void SetUpTestSuite() { + test.Init("/tmp/dnode_test_dnode1", 9023); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9023"; + + server2.Start("/tmp/dnode_test_dnode2", fqdn, 9024, firstEp); + server3.Start("/tmp/dnode_test_dnode3", fqdn, 9025, firstEp); + server4.Start("/tmp/dnode_test_dnode4", fqdn, 9026, firstEp); + server5.Start("/tmp/dnode_test_dnode5", fqdn, 9027, firstEp); + taosMsleep(300); + } + + static void TearDownTestSuite() { + server2.Stop(); + server3.Stop(); + server4.Stop(); + server5.Stop(); + test.Cleanup(); + } + + static Testbase test; + static TestServer server2; + static TestServer server3; + static TestServer server4; + static TestServer server5; +}; + +Testbase MndTestDnode::test; +TestServer MndTestDnode::server2; +TestServer MndTestDnode::server3; +TestServer MndTestDnode::server4; +TestServer MndTestDnode::server5; + +TEST_F(MndTestDnode, 01_ShowDnode) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + + CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); + CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_SMALLINT, 2, "vnodes"); + CHECK_SCHEMA(3, TSDB_DATA_TYPE_SMALLINT, 2, "support_vnodes"); + CHECK_SCHEMA(4, TSDB_DATA_TYPE_BINARY, 10 + VARSTR_HEADER_SIZE, "status"); + CHECK_SCHEMA(5, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); + CHECK_SCHEMA(6, TSDB_DATA_TYPE_BINARY, 24 + VARSTR_HEADER_SIZE, "offline_reason"); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9023", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(16); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckBinary("", 24); +} + +TEST_F(MndTestDnode, 02_ConfigDnode) { + int32_t contLen = sizeof(SMCfgDnodeReq); + + SMCfgDnodeReq* pReq = (SMCfgDnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + strcpy(pReq->config, "ddebugflag 131"); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CONFIG_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); +} + +TEST_F(MndTestDnode, 03_Create_Dnode) { + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, ""); + pReq->port = htonl(9024); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_DNODE_EP); + } + + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(-1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_DNODE_EP); + } + + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(123456); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_DNODE_EP); + } + + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9024); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9024); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_DNODE_ALREADY_EXIST); + } + + taosMsleep(1300); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + + CheckInt16(1); + CheckInt16(2); + CheckBinary("localhost:9023", TSDB_EP_LEN); + CheckBinary("localhost:9024", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(0); + CheckInt16(16); + CheckInt16(16); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckTimestamp(); + CheckBinary("", 24); + CheckBinary("", 24); +} + +TEST_F(MndTestDnode, 04_Drop_Dnode) { + { + int32_t contLen = sizeof(SDropDnodeReq); + + SDropDnodeReq* pReq = (SDropDnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(-3); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_DNODE_ID); + } + + { + int32_t contLen = sizeof(SDropDnodeReq); + + SDropDnodeReq* pReq = (SDropDnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(5); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_DNODE_NOT_EXIST); + } + + { + int32_t contLen = sizeof(SDropDnodeReq); + + SDropDnodeReq* pReq = (SDropDnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SDropDnodeReq); + + SDropDnodeReq* pReq = (SDropDnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_DNODE_NOT_EXIST); + } + + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9023", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(16); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckBinary("", 24); + + taosMsleep(2000); + server2.Stop(); + server2.DoStart(); +} + +TEST_F(MndTestDnode, 05_Create_Drop_Restart_Dnode) { + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9025); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9026); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9027); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + + taosMsleep(1300); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 4); + + CheckInt16(1); + CheckInt16(3); + CheckInt16(4); + CheckInt16(5); + CheckBinary("localhost:9023", TSDB_EP_LEN); + CheckBinary("localhost:9025", TSDB_EP_LEN); + CheckBinary("localhost:9026", TSDB_EP_LEN); + CheckBinary("localhost:9027", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(16); + CheckInt16(16); + CheckInt16(16); + CheckInt16(16); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); + + // restart + uInfo("stop all server"); + test.Restart(); + server2.Restart(); + server3.Restart(); + server4.Restart(); + server5.Restart(); + + taosMsleep(1300); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 4); + + CheckInt16(1); + CheckInt16(3); + CheckInt16(4); + CheckInt16(5); + CheckBinary("localhost:9023", TSDB_EP_LEN); + CheckBinary("localhost:9025", TSDB_EP_LEN); + CheckBinary("localhost:9026", TSDB_EP_LEN); + CheckBinary("localhost:9027", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(16); + CheckInt16(16); + CheckInt16(16); + CheckInt16(16); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); +} diff --git a/source/dnode/mnode/impl/test/mnode/CMakeLists.txt b/source/dnode/mnode/impl/test/mnode/CMakeLists.txt new file mode 100644 index 0000000000..4d9b473291 --- /dev/null +++ b/source/dnode/mnode/impl/test/mnode/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. MTEST_SRC) +add_executable(mnode_test_mnode ${MTEST_SRC}) +target_link_libraries( + mnode_test_mnode + PUBLIC sut +) + +add_test( + NAME mnode_test_mnode + COMMAND mnode_test_mnode +) diff --git a/source/dnode/mnode/impl/test/mnode/mnode.cpp b/source/dnode/mnode/impl/test/mnode/mnode.cpp new file mode 100644 index 0000000000..f56b864cad --- /dev/null +++ b/source/dnode/mnode/impl/test/mnode/mnode.cpp @@ -0,0 +1,290 @@ +/** + * @file mnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief MNODE module mnode tests + * @version 1.0 + * @date 2022-01-07 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class MndTestMnode : public ::testing::Test { + public: + void SetUp() override {} + void TearDown() override {} + + public: + static void SetUpTestSuite() { + test.Init("/tmp/mnode_test_mnode1", 9028); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9028"; + + server2.Start("/tmp/mnode_test_mnode2", fqdn, 9029, firstEp); + taosMsleep(300); + } + + static void TearDownTestSuite() { + server2.Stop(); + test.Cleanup(); + } + + static Testbase test; + static TestServer server2; +}; + +Testbase MndTestMnode::test; +TestServer MndTestMnode::server2; + +TEST_F(MndTestMnode, 01_ShowDnode) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_MNODE, ""); + CHECK_META("show mnodes", 5); + + CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); + CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_BINARY, 12 + VARSTR_HEADER_SIZE, "role"); + CHECK_SCHEMA(3, TSDB_DATA_TYPE_TIMESTAMP, 8, "role_time"); + CHECK_SCHEMA(4, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9028", TSDB_EP_LEN); + CheckBinary("master", 12); + CheckInt64(0); + CheckTimestamp(); +} + +TEST_F(MndTestMnode, 02_Create_Mnode_Invalid_Id) { + { + int32_t contLen = sizeof(SMCreateMnodeReq); + + SMCreateMnodeReq* pReq = (SMCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_MNODE_ALREADY_EXIST); + } +} + +TEST_F(MndTestMnode, 03_Create_Mnode_Invalid_Id) { + { + int32_t contLen = sizeof(SMCreateMnodeReq); + + SMCreateMnodeReq* pReq = (SMCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_DNODE_NOT_EXIST); + } +} + +TEST_F(MndTestMnode, 04_Create_Mnode) { + { + // create dnode + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9029); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + taosMsleep(1300); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + } + + { + // create mnode + int32_t contLen = sizeof(SMCreateMnodeReq); + + SMCreateMnodeReq* pReq = (SMCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_MNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + + CheckInt16(1); + CheckInt16(2); + CheckBinary("localhost:9028", TSDB_EP_LEN); + CheckBinary("localhost:9029", TSDB_EP_LEN); + CheckBinary("master", 12); + CheckBinary("slave", 12); + CheckInt64(0); + CheckInt64(0); + CheckTimestamp(); + CheckTimestamp(); + } + + { + // drop mnode + int32_t contLen = sizeof(SMDropMnodeReq); + + SMDropMnodeReq* pReq = (SMDropMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_MNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9028", TSDB_EP_LEN); + CheckBinary("master", 12); + CheckInt64(0); + CheckTimestamp(); + } + + { + // drop mnode + int32_t contLen = sizeof(SMDropMnodeReq); + + SMDropMnodeReq* pReq = (SMDropMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_MNODE_NOT_EXIST); + } +} + +TEST_F(MndTestMnode, 03_Create_Mnode_Rollback) { + { + // send message first, then dnode2 crash, result is returned, and rollback is started + int32_t contLen = sizeof(SMCreateMnodeReq); + + SMCreateMnodeReq* pReq = (SMCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + { + // continue send message, mnode is creating + int32_t contLen = sizeof(SMCreateMnodeReq); + + SMCreateMnodeReq* pReq = (SMCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_CREATING); + } + + { + // continue send message, mnode is creating + int32_t contLen = sizeof(SMDropMnodeReq); + + SMDropMnodeReq* pReq = (SMDropMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_CREATING); + } + + { + // server start, wait until the rollback finished + server2.DoStart(); + taosMsleep(1000); + + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateMnodeReq); + + SMCreateMnodeReq* pReq = (SMCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == TSDB_CODE_MND_MNODE_ALREADY_EXIST) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + } +} + +TEST_F(MndTestMnode, 04_Drop_Mnode_Rollback) { + { + // send message first, then dnode2 crash, result is returned, and rollback is started + int32_t contLen = sizeof(SMDropMnodeReq); + + SMDropMnodeReq* pReq = (SMDropMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + { + // continue send message, mnode is dropping + int32_t contLen = sizeof(SMCreateMnodeReq); + + SMCreateMnodeReq* pReq = (SMCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_DROPPING); + } + + { + // continue send message, mnode is dropping + int32_t contLen = sizeof(SMDropMnodeReq); + + SMDropMnodeReq* pReq = (SMDropMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_DROPPING); + } + + { + // server start, wait until the rollback finished + server2.DoStart(); + taosMsleep(1000); + + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateMnodeReq); + + SMCreateMnodeReq* pReq = (SMCreateMnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == 0) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + } +} \ No newline at end of file diff --git a/source/dnode/mnode/impl/test/profile/CMakeLists.txt b/source/dnode/mnode/impl/test/profile/CMakeLists.txt new file mode 100644 index 0000000000..88d7366b7d --- /dev/null +++ b/source/dnode/mnode/impl/test/profile/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. PROFILE_SRC) +add_executable(mnode_test_profile ${PROFILE_SRC}) +target_link_libraries( + mnode_test_profile + PUBLIC sut +) + +add_test( + NAME mnode_test_profile + COMMAND mnode_test_profile +) diff --git a/source/dnode/mgmt/impl/test/profile/profile.cpp b/source/dnode/mnode/impl/test/profile/profile.cpp similarity index 60% rename from source/dnode/mgmt/impl/test/profile/profile.cpp rename to source/dnode/mnode/impl/test/profile/profile.cpp index 87e6bfde74..bdffb6c72a 100644 --- a/source/dnode/mgmt/impl/test/profile/profile.cpp +++ b/source/dnode/mnode/impl/test/profile/profile.cpp @@ -1,41 +1,41 @@ /** * @file profile.cpp * @author slguan (slguan@taosdata.com) - * @brief DNODE module profile-msg tests - * @version 0.1 - * @date 2021-12-15 + * @brief MNODE module profile tests + * @version 1.0 + * @date 2022-01-06 * - * @copyright Copyright (c) 2021 + * @copyright Copyright (c) 2022 * */ -#include "base.h" +#include "sut.h" -class DndTestProfile : public ::testing::Test { +class MndTestProfile : public ::testing::Test { protected: - static void SetUpTestSuite() { test.Init("/tmp/dnode_test_profile", 9080); } + static void SetUpTestSuite() { test.Init("/tmp/mnode_test_profile", 9022); } static void TearDownTestSuite() { test.Cleanup(); } static Testbase test; + static int32_t connId; public: void SetUp() override {} void TearDown() override {} - - int32_t connId; }; -Testbase DndTestProfile::test; +Testbase MndTestProfile::test; +int32_t MndTestProfile::connId; -TEST_F(DndTestProfile, 01_ConnectMsg) { - int32_t contLen = sizeof(SConnectMsg); +TEST_F(MndTestProfile, 01_ConnectMsg) { + int32_t contLen = sizeof(SConnectReq); - SConnectMsg* pReq = (SConnectMsg*)rpcMallocCont(contLen); + SConnectReq* pReq = (SConnectReq*)rpcMallocCont(contLen); pReq->pid = htonl(1234); - strcpy(pReq->app, "dnode_test_profile"); + strcpy(pReq->app, "mnode_test_profile"); strcpy(pReq->db, ""); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CONNECT, pReq, contLen); + SRpcMsg* pMsg = test.SendReq(TDMT_MND_CONNECT, pReq, contLen); ASSERT_NE(pMsg, nullptr); ASSERT_EQ(pMsg->code, 0); @@ -53,28 +53,28 @@ TEST_F(DndTestProfile, 01_ConnectMsg) { EXPECT_EQ(pRsp->epSet.inUse, 0); EXPECT_EQ(pRsp->epSet.numOfEps, 1); - EXPECT_EQ(pRsp->epSet.port[0], 9080); + EXPECT_EQ(pRsp->epSet.port[0], 9022); EXPECT_STREQ(pRsp->epSet.fqdn[0], "localhost"); connId = pRsp->connId; } -TEST_F(DndTestProfile, 02_ConnectMsg_InvalidDB) { - int32_t contLen = sizeof(SConnectMsg); +TEST_F(MndTestProfile, 02_ConnectMsg_InvalidDB) { + int32_t contLen = sizeof(SConnectReq); - SConnectMsg* pReq = (SConnectMsg*)rpcMallocCont(contLen); + SConnectReq* pReq = (SConnectReq*)rpcMallocCont(contLen); pReq->pid = htonl(1234); - strcpy(pReq->app, "dnode_test_profile"); + strcpy(pReq->app, "mnode_test_profile"); strcpy(pReq->db, "invalid_db"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CONNECT, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_DB); - ASSERT_EQ(pMsg->contLen, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CONNECT, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_DB); + ASSERT_EQ(pRsp->contLen, 0); } -TEST_F(DndTestProfile, 03_ConnectMsg_Show) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_CONNS, ""); +TEST_F(MndTestProfile, 03_ConnectMsg_Show) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_CONNS, ""); CHECK_META("show connections", 7); CHECK_SCHEMA(0, TSDB_DATA_TYPE_INT, 4, "connId"); CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_USER_LEN + VARSTR_HEADER_SIZE, "user"); @@ -84,28 +84,28 @@ TEST_F(DndTestProfile, 03_ConnectMsg_Show) { CHECK_SCHEMA(5, TSDB_DATA_TYPE_TIMESTAMP, 8, "login_time"); CHECK_SCHEMA(6, TSDB_DATA_TYPE_TIMESTAMP, 8, "last_access"); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); CheckInt32(1); CheckBinary("root", TSDB_USER_LEN); - CheckBinary("dnode_test_profile", TSDB_APP_NAME_LEN); + CheckBinary("mnode_test_profile", TSDB_APP_NAME_LEN); CheckInt32(1234); IgnoreBinary(TSDB_IPv4ADDR_LEN + 6); CheckTimestamp(); CheckTimestamp(); } -TEST_F(DndTestProfile, 04_HeartBeatMsg) { - int32_t contLen = sizeof(SHeartBeatMsg); +TEST_F(MndTestProfile, 04_HeartBeatMsg) { + int32_t contLen = sizeof(SHeartBeatReq); - SHeartBeatMsg* pReq = (SHeartBeatMsg*)rpcMallocCont(contLen); + SHeartBeatReq* pReq = (SHeartBeatReq*)rpcMallocCont(contLen); pReq->connId = htonl(connId); pReq->pid = htonl(1234); pReq->numOfQueries = htonl(0); pReq->numOfStreams = htonl(0); - strcpy(pReq->app, "dnode_test_profile"); + strcpy(pReq->app, "mnode_test_profile"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_HEARTBEAT, pReq, contLen); + SRpcMsg* pMsg = test.SendReq(TDMT_MND_HEARTBEAT, pReq, contLen); ASSERT_NE(pMsg, nullptr); ASSERT_EQ(pMsg->code, 0); @@ -127,47 +127,47 @@ TEST_F(DndTestProfile, 04_HeartBeatMsg) { EXPECT_EQ(pRsp->epSet.inUse, 0); EXPECT_EQ(pRsp->epSet.numOfEps, 1); - EXPECT_EQ(pRsp->epSet.port[0], 9080); + EXPECT_EQ(pRsp->epSet.port[0], 9022); EXPECT_STREQ(pRsp->epSet.fqdn[0], "localhost"); } -TEST_F(DndTestProfile, 05_KillConnMsg) { +TEST_F(MndTestProfile, 05_KillConnMsg) { { - int32_t contLen = sizeof(SKillConnMsg); + int32_t contLen = sizeof(SKillConnReq); - SKillConnMsg* pReq = (SKillConnMsg*)rpcMallocCont(contLen); + SKillConnReq* pReq = (SKillConnReq*)rpcMallocCont(contLen); pReq->connId = htonl(connId); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_KILL_CONN, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_KILL_CONN, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } { - int32_t contLen = sizeof(SHeartBeatMsg); + int32_t contLen = sizeof(SHeartBeatReq); - SHeartBeatMsg* pReq = (SHeartBeatMsg*)rpcMallocCont(contLen); + SHeartBeatReq* pReq = (SHeartBeatReq*)rpcMallocCont(contLen); pReq->connId = htonl(connId); pReq->pid = htonl(1234); pReq->numOfQueries = htonl(0); pReq->numOfStreams = htonl(0); - strcpy(pReq->app, "dnode_test_profile"); + strcpy(pReq->app, "mnode_test_profile"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_HEARTBEAT, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_CONNECTION); - ASSERT_EQ(pMsg->contLen, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_HEARTBEAT, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_CONNECTION); + ASSERT_EQ(pRsp->contLen, 0); } { - int32_t contLen = sizeof(SConnectMsg); + int32_t contLen = sizeof(SConnectReq); - SConnectMsg* pReq = (SConnectMsg*)rpcMallocCont(contLen); + SConnectReq* pReq = (SConnectReq*)rpcMallocCont(contLen); pReq->pid = htonl(1234); - strcpy(pReq->app, "dnode_test_profile"); + strcpy(pReq->app, "mnode_test_profile"); strcpy(pReq->db, ""); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CONNECT, pReq, contLen); + SRpcMsg* pMsg = test.SendReq(TDMT_MND_CONNECT, pReq, contLen); ASSERT_NE(pMsg, nullptr); ASSERT_EQ(pMsg->code, 0); @@ -185,49 +185,49 @@ TEST_F(DndTestProfile, 05_KillConnMsg) { EXPECT_EQ(pRsp->epSet.inUse, 0); EXPECT_EQ(pRsp->epSet.numOfEps, 1); - EXPECT_EQ(pRsp->epSet.port[0], 9080); + EXPECT_EQ(pRsp->epSet.port[0], 9022); EXPECT_STREQ(pRsp->epSet.fqdn[0], "localhost"); connId = pRsp->connId; } } -TEST_F(DndTestProfile, 06_KillConnMsg_InvalidConn) { - int32_t contLen = sizeof(SKillConnMsg); +TEST_F(MndTestProfile, 06_KillConnMsg_InvalidConn) { + int32_t contLen = sizeof(SKillConnReq); - SKillConnMsg* pReq = (SKillConnMsg*)rpcMallocCont(contLen); + SKillConnReq* pReq = (SKillConnReq*)rpcMallocCont(contLen); pReq->connId = htonl(2345); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_KILL_CONN, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_CONN_ID); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_KILL_CONN, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_CONN_ID); } -TEST_F(DndTestProfile, 07_KillQueryMsg) { +TEST_F(MndTestProfile, 07_KillQueryMsg) { { - int32_t contLen = sizeof(SKillQueryMsg); + int32_t contLen = sizeof(SKillQueryReq); - SKillQueryMsg* pReq = (SKillQueryMsg*)rpcMallocCont(contLen); + SKillQueryReq* pReq = (SKillQueryReq*)rpcMallocCont(contLen); pReq->connId = htonl(connId); pReq->queryId = htonl(1234); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_KILL_QUERY, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - ASSERT_EQ(pMsg->contLen, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_KILL_QUERY, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + ASSERT_EQ(pRsp->contLen, 0); } { - int32_t contLen = sizeof(SHeartBeatMsg); + int32_t contLen = sizeof(SHeartBeatReq); - SHeartBeatMsg* pReq = (SHeartBeatMsg*)rpcMallocCont(contLen); + SHeartBeatReq* pReq = (SHeartBeatReq*)rpcMallocCont(contLen); pReq->connId = htonl(connId); pReq->pid = htonl(1234); pReq->numOfQueries = htonl(0); pReq->numOfStreams = htonl(0); - strcpy(pReq->app, "dnode_test_profile"); + strcpy(pReq->app, "mnode_test_profile"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_HEARTBEAT, pReq, contLen); + SRpcMsg* pMsg = test.SendReq(TDMT_MND_HEARTBEAT, pReq, contLen); ASSERT_NE(pMsg, nullptr); ASSERT_EQ(pMsg->code, 0); @@ -249,25 +249,25 @@ TEST_F(DndTestProfile, 07_KillQueryMsg) { EXPECT_EQ(pRsp->epSet.inUse, 0); EXPECT_EQ(pRsp->epSet.numOfEps, 1); - EXPECT_EQ(pRsp->epSet.port[0], 9080); + EXPECT_EQ(pRsp->epSet.port[0], 9022); EXPECT_STREQ(pRsp->epSet.fqdn[0], "localhost"); } } -TEST_F(DndTestProfile, 08_KillQueryMsg_InvalidConn) { - int32_t contLen = sizeof(SKillQueryMsg); +TEST_F(MndTestProfile, 08_KillQueryMsg_InvalidConn) { + int32_t contLen = sizeof(SKillQueryReq); - SKillQueryMsg* pReq = (SKillQueryMsg*)rpcMallocCont(contLen); + SKillQueryReq* pReq = (SKillQueryReq*)rpcMallocCont(contLen); pReq->connId = htonl(2345); pReq->queryId = htonl(1234); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_KILL_QUERY, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_CONN_ID); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_KILL_QUERY, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_CONN_ID); } -TEST_F(DndTestProfile, 09_KillQueryMsg) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_QUERIES, ""); +TEST_F(MndTestProfile, 09_KillQueryMsg) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_QUERIES, ""); CHECK_META("show queries", 14); CHECK_SCHEMA(0, TSDB_DATA_TYPE_INT, 4, "queryId"); @@ -285,6 +285,6 @@ TEST_F(DndTestProfile, 09_KillQueryMsg) { CHECK_SCHEMA(12, TSDB_DATA_TYPE_BINARY, TSDB_SHOW_SUBQUERY_LEN + VARSTR_HEADER_SIZE, "sub_query_info"); CHECK_SCHEMA(13, TSDB_DATA_TYPE_BINARY, TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE, "sql"); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 0); } diff --git a/source/dnode/mnode/impl/test/qnode/CMakeLists.txt b/source/dnode/mnode/impl/test/qnode/CMakeLists.txt new file mode 100644 index 0000000000..77ac39e409 --- /dev/null +++ b/source/dnode/mnode/impl/test/qnode/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. QTEST_SRC) +add_executable(mnode_test_qnode ${QTEST_SRC}) +target_link_libraries( + mnode_test_qnode + PUBLIC sut +) + +add_test( + NAME mnode_test_qnode + COMMAND mnode_test_qnode +) diff --git a/source/dnode/mnode/impl/test/qnode/qnode.cpp b/source/dnode/mnode/impl/test/qnode/qnode.cpp new file mode 100644 index 0000000000..8a9e087e7f --- /dev/null +++ b/source/dnode/mnode/impl/test/qnode/qnode.cpp @@ -0,0 +1,290 @@ +/** + * @file qnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief MNODE module qnode tests + * @version 1.0 + * @date 2022-01-05 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class MndTestQnode : public ::testing::Test { + public: + void SetUp() override {} + void TearDown() override {} + + public: + static void SetUpTestSuite() { + test.Init("/tmp/mnode_test_qnode1", 9014); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9014"; + + server2.Start("/tmp/mnode_test_qnode2", fqdn, 9015, firstEp); + taosMsleep(300); + } + + static void TearDownTestSuite() { + server2.Stop(); + test.Cleanup(); + } + + static Testbase test; + static TestServer server2; +}; + +Testbase MndTestQnode::test; +TestServer MndTestQnode::server2; + +TEST_F(MndTestQnode, 01_Show_Qnode) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_QNODE, ""); + CHECK_META("show qnodes", 3); + + CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); + CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 0); +} + +TEST_F(MndTestQnode, 02_Create_Qnode) { + { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_DNODE_NOT_EXIST); + } + + { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_QNODE, ""); + CHECK_META("show qnodes", 3); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9014", TSDB_EP_LEN); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_QNODE_ALREADY_EXIST); + } +} + +TEST_F(MndTestQnode, 03_Drop_Qnode) { + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9015); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + taosMsleep(1300); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + } + + { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_QNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + + CheckInt16(1); + CheckInt16(2); + CheckBinary("localhost:9014", TSDB_EP_LEN); + CheckBinary("localhost:9015", TSDB_EP_LEN); + CheckTimestamp(); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMDropQnodeReq); + + SMDropQnodeReq* pReq = (SMDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_QNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9014", TSDB_EP_LEN); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMDropQnodeReq); + + SMDropQnodeReq* pReq = (SMDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_QNODE_NOT_EXIST); + } +} + +TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) { + { + // send message first, then dnode2 crash, result is returned, and rollback is started + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + { + // continue send message, qnode is creating + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_CREATING); + } + + { + // continue send message, qnode is creating + int32_t contLen = sizeof(SMDropQnodeReq); + + SMDropQnodeReq* pReq = (SMDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_CREATING); + } + + { + // server start, wait until the rollback finished + server2.DoStart(); + taosMsleep(1000); + + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == 0) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + } +} + +TEST_F(MndTestQnode, 04_Drop_Qnode_Rollback) { + { + // send message first, then dnode2 crash, result is returned, and rollback is started + int32_t contLen = sizeof(SMDropQnodeReq); + + SMDropQnodeReq* pReq = (SMDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + { + // continue send message, qnode is dropping + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_DROPPING); + } + + { + // continue send message, qnode is dropping + int32_t contLen = sizeof(SMDropQnodeReq); + + SMDropQnodeReq* pReq = (SMDropQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_DROPPING); + } + + { + // server start, wait until the rollback finished + server2.DoStart(); + taosMsleep(1000); + + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == 0) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + } +} \ No newline at end of file diff --git a/source/dnode/mnode/impl/test/show/CMakeLists.txt b/source/dnode/mnode/impl/test/show/CMakeLists.txt new file mode 100644 index 0000000000..cc0706ca50 --- /dev/null +++ b/source/dnode/mnode/impl/test/show/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. SHOW_SRC) +add_executable(mnode_test_show ${SHOW_SRC}) +target_link_libraries( + mnode_test_show + PUBLIC sut +) + +add_test( + NAME mnode_test_show + COMMAND mnode_test_show +) diff --git a/source/dnode/mnode/impl/test/show/show.cpp b/source/dnode/mnode/impl/test/show/show.cpp new file mode 100644 index 0000000000..bfdc0f42b6 --- /dev/null +++ b/source/dnode/mnode/impl/test/show/show.cpp @@ -0,0 +1,102 @@ +/** + * @file show.cpp + * @author slguan (slguan@taosdata.com) + * @brief MNODE module show tests + * @version 1.0 + * @date 2022-01-06 + * + * @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) { + int32_t contLen = sizeof(SShowReq); + + SShowReq* pReq = (SShowReq*)rpcMallocCont(contLen); + pReq->type = TSDB_MGMT_TABLE_MAX; + strcpy(pReq->db, ""); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_SHOW, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_MSG_TYPE); +} + +TEST_F(MndTestShow, 02_ShowMsg_InvalidMsgStart) { + int32_t contLen = sizeof(SShowReq); + + SShowReq* pReq = (SShowReq*)rpcMallocCont(sizeof(SShowReq)); + pReq->type = TSDB_MGMT_TABLE_START; + strcpy(pReq->db, ""); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_SHOW, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_MSG_TYPE); +} + +TEST_F(MndTestShow, 03_ShowMsg_Conn) { + int32_t contLen = sizeof(SConnectReq); + + SConnectReq* pReq = (SConnectReq*)rpcMallocCont(contLen); + pReq->pid = htonl(1234); + strcpy(pReq->app, "mnode_test_show"); + strcpy(pReq->db, ""); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CONNECT, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_CONNS, ""); + + STableMetaRsp* pMeta = test.GetShowMeta(); + EXPECT_STREQ(pMeta->tbFname, "show connections"); + EXPECT_EQ(pMeta->numOfTags, 0); + EXPECT_EQ(pMeta->numOfColumns, 7); + EXPECT_EQ(pMeta->precision, 0); + EXPECT_EQ(pMeta->tableType, 0); + EXPECT_EQ(pMeta->update, 0); + EXPECT_EQ(pMeta->sversion, 0); + EXPECT_EQ(pMeta->tversion, 0); + EXPECT_EQ(pMeta->tuid, 0); + EXPECT_EQ(pMeta->suid, 0); + + test.SendShowRetrieveReq(); + + SRetrieveTableRsp* pRetrieveRsp = test.GetRetrieveRsp(); + EXPECT_EQ(pRetrieveRsp->numOfRows, 1); + EXPECT_EQ(pRetrieveRsp->useconds, 0); + EXPECT_EQ(pRetrieveRsp->completed, 1); + EXPECT_EQ(pRetrieveRsp->precision, TSDB_TIME_PRECISION_MILLI); + EXPECT_EQ(pRetrieveRsp->compressed, 0); + EXPECT_EQ(pRetrieveRsp->compLen, 0); +} + +TEST_F(MndTestShow, 04_ShowMsg_Cluster) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_CLUSTER, ""); + CHECK_META( "show cluster", 3); + CHECK_SCHEMA(0, TSDB_DATA_TYPE_BIGINT, 8, "id"); + CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_CLUSTER_ID_LEN + VARSTR_HEADER_SIZE, "name"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + IgnoreInt64(); + IgnoreBinary(TSDB_CLUSTER_ID_LEN); + CheckTimestamp(); +} \ No newline at end of file diff --git a/source/dnode/mnode/impl/test/snode/CMakeLists.txt b/source/dnode/mnode/impl/test/snode/CMakeLists.txt new file mode 100644 index 0000000000..44a5f35f94 --- /dev/null +++ b/source/dnode/mnode/impl/test/snode/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. STEST_SRC) +add_executable(mnode_test_snode ${STEST_SRC}) +target_link_libraries( + mnode_test_snode + PUBLIC sut +) + +add_test( + NAME mnode_test_snode + COMMAND mnode_test_snode +) diff --git a/source/dnode/mnode/impl/test/snode/snode.cpp b/source/dnode/mnode/impl/test/snode/snode.cpp new file mode 100644 index 0000000000..3a38b9ede6 --- /dev/null +++ b/source/dnode/mnode/impl/test/snode/snode.cpp @@ -0,0 +1,290 @@ +/** + * @file snode.cpp + * @author slguan (slguan@taosdata.com) + * @brief MNODE module snode tests + * @version 1.0 + * @date 2022-01-05 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "sut.h" + +class MndTestSnode : public ::testing::Test { + public: + void SetUp() override {} + void TearDown() override {} + + public: + static void SetUpTestSuite() { + test.Init("/tmp/mnode_test_snode1", 9016); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9016"; + + server2.Start("/tmp/mnode_test_snode2", fqdn, 9017, firstEp); + taosMsleep(300); + } + + static void TearDownTestSuite() { + server2.Stop(); + test.Cleanup(); + } + + static Testbase test; + static TestServer server2; +}; + +Testbase MndTestSnode::test; +TestServer MndTestSnode::server2; + +TEST_F(MndTestSnode, 01_Show_Snode) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_SNODE, ""); + CHECK_META("show snodes", 3); + + CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); + CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); + + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 0); +} + +TEST_F(MndTestSnode, 02_Create_Snode) { + { + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_DNODE_NOT_EXIST); + } + + { + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_SNODE, ""); + CHECK_META("show snodes", 3); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9016", TSDB_EP_LEN); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_SNODE_ALREADY_EXIST); + } +} + +TEST_F(MndTestSnode, 03_Drop_Snode) { + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9017); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + taosMsleep(1300); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + } + + { + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_SNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + + CheckInt16(1); + CheckInt16(2); + CheckBinary("localhost:9016", TSDB_EP_LEN); + CheckBinary("localhost:9017", TSDB_EP_LEN); + CheckTimestamp(); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMDropSnodeReq); + + SMDropSnodeReq* pReq = (SMDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_SNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9016", TSDB_EP_LEN); + CheckTimestamp(); + } + + { + int32_t contLen = sizeof(SMDropSnodeReq); + + SMDropSnodeReq* pReq = (SMDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_SNODE_NOT_EXIST); + } +} + +TEST_F(MndTestSnode, 03_Create_Snode_Rollback) { + { + // send message first, then dnode2 crash, result is returned, and rollback is started + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + { + // continue send message, snode is creating + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_CREATING); + } + + { + // continue send message, snode is creating + int32_t contLen = sizeof(SMDropSnodeReq); + + SMDropSnodeReq* pReq = (SMDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_CREATING); + } + + { + // server start, wait until the rollback finished + server2.DoStart(); + taosMsleep(1000); + + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == 0) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + } +} + +TEST_F(MndTestSnode, 04_Drop_Snode_Rollback) { + { + // send message first, then dnode2 crash, result is returned, and rollback is started + int32_t contLen = sizeof(SMDropSnodeReq); + + SMDropSnodeReq* pReq = (SMDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + { + // continue send message, snode is dropping + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_DROPPING); + } + + { + // continue send message, snode is dropping + int32_t contLen = sizeof(SMDropSnodeReq); + + SMDropSnodeReq* pReq = (SMDropSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_SDB_OBJ_DROPPING); + } + + { + // server start, wait until the rollback finished + server2.DoStart(); + taosMsleep(1000); + + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateSnodeReq); + + SMCreateSnodeReq* pReq = (SMCreateSnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_SNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == 0) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + } +} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/stb/CMakeLists.txt b/source/dnode/mnode/impl/test/stb/CMakeLists.txt similarity index 100% rename from source/dnode/mgmt/impl/test/stb/CMakeLists.txt rename to source/dnode/mnode/impl/test/stb/CMakeLists.txt diff --git a/source/dnode/mgmt/impl/test/stb/stb.cpp b/source/dnode/mnode/impl/test/stb/stb.cpp similarity index 74% rename from source/dnode/mgmt/impl/test/stb/stb.cpp rename to source/dnode/mnode/impl/test/stb/stb.cpp index dca0f48516..beb52d68c1 100644 --- a/source/dnode/mgmt/impl/test/stb/stb.cpp +++ b/source/dnode/mnode/impl/test/stb/stb.cpp @@ -1,19 +1,19 @@ /** * @file stb.cpp * @author slguan (slguan@taosdata.com) - * @brief DNODE module db-msg tests - * @version 0.1 - * @date 2021-12-17 + * @brief MNODE module stb tests + * @version 1.0 + * @date 2022-01-12 * - * @copyright Copyright (c) 2021 + * @copyright Copyright (c) 2022 * */ -#include "base.h" +#include "sut.h" -class DndTestStb : public ::testing::Test { +class MndTestStb : public ::testing::Test { protected: - static void SetUpTestSuite() { test.Init("/tmp/dnode_test_stb", 9101); } + static void SetUpTestSuite() { test.Init("/tmp/mnode_test_stb", 9034); } static void TearDownTestSuite() { test.Cleanup(); } static Testbase test; @@ -23,13 +23,13 @@ class DndTestStb : public ::testing::Test { void TearDown() override {} }; -Testbase DndTestStb::test; +Testbase MndTestStb::test; -TEST_F(DndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { +TEST_F(MndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { { - int32_t contLen = sizeof(SCreateDbMsg); + int32_t contLen = sizeof(SCreateDbReq); - SCreateDbMsg* pReq = (SCreateDbMsg*)rpcMallocCont(contLen); + SCreateDbReq* pReq = (SCreateDbReq*)rpcMallocCont(contLen); strcpy(pReq->db, "1.d1"); pReq->numOfVgroups = htonl(2); pReq->cacheBlockSize = htonl(16); @@ -51,17 +51,17 @@ TEST_F(DndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { pReq->cacheLastRow = 0; pReq->ignoreExist = 1; - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_DB, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DB, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } { int32_t cols = 2; int32_t tags = 3; - int32_t contLen = (tags + cols) * sizeof(SSchema) + sizeof(SCreateStbMsg); + int32_t contLen = (tags + cols) * sizeof(SSchema) + sizeof(SMCreateStbReq); - SCreateStbMsg* pReq = (SCreateStbMsg*)rpcMallocCont(contLen); + SMCreateStbReq* pReq = (SMCreateStbReq*)rpcMallocCont(contLen); strcpy(pReq->name, "1.d1.stb"); pReq->numOfTags = htonl(tags); pReq->numOfColumns = htonl(cols); @@ -101,12 +101,12 @@ TEST_F(DndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { strcpy(pSchema->name, "tag3"); } - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_STB, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_STB, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_STB, "1.d1"); + test.SendShowMetaReq(TSDB_MGMT_TABLE_STB, "1.d1"); CHECK_META("show stables", 4); CHECK_SCHEMA(0, TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE, "name"); @@ -114,7 +114,7 @@ TEST_F(DndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { CHECK_SCHEMA(2, TSDB_DATA_TYPE_INT, 4, "columns"); CHECK_SCHEMA(3, TSDB_DATA_TYPE_INT, 4, "tags"); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); CheckBinary("stb", TSDB_TABLE_NAME_LEN); CheckTimestamp(); @@ -123,23 +123,23 @@ TEST_F(DndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { // ----- meta ------ { - int32_t contLen = sizeof(STableInfoMsg); + int32_t contLen = sizeof(STableInfoReq); - STableInfoMsg* pReq = (STableInfoMsg*)rpcMallocCont(contLen); + STableInfoReq* pReq = (STableInfoReq*)rpcMallocCont(contLen); strcpy(pReq->tableFname, "1.d1.stb"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_STB_META, pReq, contLen); + SRpcMsg* pMsg = test.SendReq(TDMT_MND_STB_META, pReq, contLen); ASSERT_NE(pMsg, nullptr); ASSERT_EQ(pMsg->code, 0); - STableMetaMsg* pRsp = (STableMetaMsg*)pMsg->pCont; + STableMetaRsp* pRsp = (STableMetaRsp*)pMsg->pCont; pRsp->numOfTags = htonl(pRsp->numOfTags); pRsp->numOfColumns = htonl(pRsp->numOfColumns); pRsp->sversion = htonl(pRsp->sversion); pRsp->tversion = htonl(pRsp->tversion); - pRsp->suid = htobe64(pRsp->suid); - pRsp->tuid = htobe64(pRsp->tuid); - pRsp->vgId = htobe64(pRsp->vgId); + pRsp->suid = be64toh(pRsp->suid); + pRsp->tuid = be64toh(pRsp->tuid); + pRsp->vgId = be64toh(pRsp->vgId); for (int32_t i = 0; i < pRsp->numOfTags + pRsp->numOfColumns; ++i) { SSchema* pSchema = &pRsp->pSchema[i]; pSchema->colId = htonl(pSchema->colId); @@ -156,7 +156,7 @@ TEST_F(DndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { EXPECT_EQ(pRsp->sversion, 1); EXPECT_EQ(pRsp->tversion, 0); EXPECT_GT(pRsp->suid, 0); - EXPECT_EQ(pRsp->tuid, 0); + EXPECT_GT(pRsp->tuid, 0); EXPECT_EQ(pRsp->vgId, 0); { @@ -203,9 +203,9 @@ TEST_F(DndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { // restart test.Restart(); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_STB, "1.d1"); + test.SendShowMetaReq(TSDB_MGMT_TABLE_STB, "1.d1"); CHECK_META("show stables", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); CheckBinary("stb", TSDB_TABLE_NAME_LEN); @@ -214,18 +214,18 @@ TEST_F(DndTestStb, 01_Create_Show_Meta_Drop_Restart_Stb) { CheckInt32(3); { - int32_t contLen = sizeof(SDropStbMsg); + int32_t contLen = sizeof(SMDropStbReq); - SDropStbMsg* pReq = (SDropStbMsg*)rpcMallocCont(contLen); + SMDropStbReq* pReq = (SMDropStbReq*)rpcMallocCont(contLen); strcpy(pReq->name, "1.d1.stb"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_STB, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_STB, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_STB, "1.d1"); + test.SendShowMetaReq(TSDB_MGMT_TABLE_STB, "1.d1"); CHECK_META("show stables", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 0); } diff --git a/source/dnode/mnode/impl/test/trans/trans.cpp b/source/dnode/mnode/impl/test/trans/trans.cpp index 1400ad897f..a0c4c539fb 100644 --- a/source/dnode/mnode/impl/test/trans/trans.cpp +++ b/source/dnode/mnode/impl/test/trans/trans.cpp @@ -1,5 +1,5 @@ /** - * @file user.cpp + * @file trans.cpp * @author slguan (slguan@taosdata.com) * @brief MNODE module trans tests * @version 1.0 @@ -9,13 +9,22 @@ * */ -#include "base.h" -#include "os.h" +#include "sut.h" -class DndTestTrans : public ::testing::Test { +class MndTestTrans : public ::testing::Test { protected: - static void SetUpTestSuite() { test.Init("/tmp/mnode_test_trans", 9013); } - static void TearDownTestSuite() { test.Cleanup(); } + static void SetUpTestSuite() { + test.Init("/tmp/mnode_test_trans", 9013); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9013"; + server2.Start("/tmp/mnode_test_trans2", fqdn, 9020, firstEp); + } + + static void TearDownTestSuite() { + server2.Stop(); + test.Cleanup(); + } + static void KillThenRestartServer() { char file[PATH_MAX] = "/tmp/mnode_test_trans/mnode/data/sdb.data"; FileFd fd = taosOpenFileRead(file); @@ -41,46 +50,142 @@ class DndTestTrans : public ::testing::Test { test.ServerStart(); } - static Testbase test; + static Testbase test; + static TestServer server2; public: void SetUp() override {} void TearDown() override {} }; -Testbase DndTestTrans::test; +Testbase MndTestTrans::test; +TestServer MndTestTrans::server2; -TEST_F(DndTestTrans, 01_CreateUser_Crash) { +TEST_F(MndTestTrans, 01_Create_User_Crash) { { - int32_t contLen = sizeof(SCreateUserMsg); + int32_t contLen = sizeof(SCreateUserReq); - SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(contLen); + SCreateUserReq* pReq = (SCreateUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); strcpy(pReq->pass, "p1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 2); KillThenRestartServer(); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 2); - // CheckBinary("root", TSDB_USER_LEN); - // CheckBinary("u2", TSDB_USER_LEN); - // CheckBinary("super", 10); - // CheckBinary("normal", 10); - // CheckTimestamp(); - // CheckTimestamp(); - // CheckBinary("root", TSDB_USER_LEN); - // CheckBinary("root", TSDB_USER_LEN); + CheckBinary("u1", TSDB_USER_LEN); + CheckBinary("root", TSDB_USER_LEN); + CheckBinary("normal", 10); + CheckBinary("super", 10); + CheckTimestamp(); + CheckTimestamp(); + CheckBinary("root", TSDB_USER_LEN); + CheckBinary("root", TSDB_USER_LEN); +} + +TEST_F(MndTestTrans, 02_Create_Qnode1_Crash) { + { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_QNODE, ""); + CHECK_META("show qnodes", 3); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + } + + KillThenRestartServer(); + { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_QNODE_ALREADY_EXIST); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_QNODE, ""); + CHECK_META("show qnodes", 3); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 1); + } +} + +TEST_F(MndTestTrans, 03_Create_Qnode2_Crash) { + { + int32_t contLen = sizeof(SCreateDnodeReq); + + SCreateDnodeReq* pReq = (SCreateDnodeReq*)rpcMallocCont(contLen); + strcpy(pReq->fqdn, "localhost"); + pReq->port = htonl(9020); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + + taosMsleep(1300); + test.SendShowMetaReq(TSDB_MGMT_TABLE_DNODE, ""); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + } + + { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + server2.Stop(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); + } + + KillThenRestartServer(); + + server2.DoStart(); + + { + int32_t retry = 0; + int32_t retryMax = 20; + + for (retry = 0; retry < retryMax; retry++) { + int32_t contLen = sizeof(SMCreateQnodeReq); + + SMCreateQnodeReq* pReq = (SMCreateQnodeReq*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (pRsp->code == 0) break; + taosMsleep(1000); + } + + ASSERT_NE(retry, retryMax); + + test.SendShowMetaReq(TSDB_MGMT_TABLE_QNODE, ""); + CHECK_META("show qnodes", 3); + test.SendShowRetrieveReq(); + EXPECT_EQ(test.GetShowRows(), 2); + } } \ No newline at end of file diff --git a/source/dnode/mnode/impl/test/user/user.cpp b/source/dnode/mnode/impl/test/user/user.cpp index 536150ccfd..a696158d2b 100644 --- a/source/dnode/mnode/impl/test/user/user.cpp +++ b/source/dnode/mnode/impl/test/user/user.cpp @@ -3,15 +3,15 @@ * @author slguan (slguan@taosdata.com) * @brief MNODE module user tests * @version 1.0 - * @date 2021-12-15 + * @date 2022-01-04 * - * @copyright Copyright (c) 2021 + * @copyright Copyright (c) 2022 * */ -#include "base.h" +#include "sut.h" -class DndTestUser : public ::testing::Test { +class MndTestUser : public ::testing::Test { protected: static void SetUpTestSuite() { test.Init("/tmp/mnode_test_user", 9011); } static void TearDownTestSuite() { test.Cleanup(); } @@ -23,10 +23,10 @@ class DndTestUser : public ::testing::Test { void TearDown() override {} }; -Testbase DndTestUser::test; +Testbase MndTestUser::test; -TEST_F(DndTestUser, 01_ShowUser) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); +TEST_F(MndTestUser, 01_Show_User) { + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); CHECK_SCHEMA(0, TSDB_DATA_TYPE_BINARY, TSDB_USER_LEN + VARSTR_HEADER_SIZE, "name"); @@ -34,7 +34,7 @@ TEST_F(DndTestUser, 01_ShowUser) { CHECK_SCHEMA(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); CHECK_SCHEMA(3, TSDB_DATA_TYPE_BINARY, TSDB_USER_LEN + VARSTR_HEADER_SIZE, "account"); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); CheckBinary("root", TSDB_USER_LEN); @@ -43,182 +43,182 @@ TEST_F(DndTestUser, 01_ShowUser) { CheckBinary("root", TSDB_USER_LEN); } -TEST_F(DndTestUser, 02_Create_User) { +TEST_F(MndTestUser, 02_Create_User) { { - int32_t contLen = sizeof(SCreateUserMsg); + int32_t contLen = sizeof(SCreateUserReq); - SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(contLen); + SCreateUserReq* pReq = (SCreateUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, ""); strcpy(pReq->pass, "p1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_USER_FORMAT); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_USER_FORMAT); } { - int32_t contLen = sizeof(SCreateUserMsg); + int32_t contLen = sizeof(SCreateUserReq); - SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(contLen); + SCreateUserReq* pReq = (SCreateUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); strcpy(pReq->pass, ""); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_PASS_FORMAT); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_PASS_FORMAT); } { - int32_t contLen = sizeof(SCreateUserMsg); + int32_t contLen = sizeof(SCreateUserReq); - SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(contLen); + SCreateUserReq* pReq = (SCreateUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "root"); strcpy(pReq->pass, "1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_USER_ALREADY_EXIST); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_USER_ALREADY_EXIST); } { - int32_t contLen = sizeof(SCreateUserMsg); + int32_t contLen = sizeof(SCreateUserReq); - SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(contLen); + SCreateUserReq* pReq = (SCreateUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); strcpy(pReq->pass, "p1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 2); } -TEST_F(DndTestUser, 03_Alter_User) { +TEST_F(MndTestUser, 03_Alter_User) { { - int32_t contLen = sizeof(SAlterUserMsg); + int32_t contLen = sizeof(SAlterUserReq); - SAlterUserMsg* pReq = (SAlterUserMsg*)rpcMallocCont(contLen); + SAlterUserReq* pReq = (SAlterUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, ""); strcpy(pReq->pass, "p1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_ALTER_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_USER_FORMAT); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_ALTER_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_USER_FORMAT); } { - int32_t contLen = sizeof(SAlterUserMsg); + int32_t contLen = sizeof(SAlterUserReq); - SAlterUserMsg* pReq = (SAlterUserMsg*)rpcMallocCont(contLen); + SAlterUserReq* pReq = (SAlterUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); strcpy(pReq->pass, ""); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_ALTER_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_PASS_FORMAT); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_ALTER_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_PASS_FORMAT); } { - int32_t contLen = sizeof(SAlterUserMsg); + int32_t contLen = sizeof(SAlterUserReq); - SAlterUserMsg* pReq = (SAlterUserMsg*)rpcMallocCont(contLen); + SAlterUserReq* pReq = (SAlterUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u4"); strcpy(pReq->pass, "1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_ALTER_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_USER_NOT_EXIST); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_ALTER_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_USER_NOT_EXIST); } { - int32_t contLen = sizeof(SAlterUserMsg); + int32_t contLen = sizeof(SAlterUserReq); - SAlterUserMsg* pReq = (SAlterUserMsg*)rpcMallocCont(contLen); + SAlterUserReq* pReq = (SAlterUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); strcpy(pReq->pass, "1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_ALTER_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_ALTER_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } } -TEST_F(DndTestUser, 04_Drop_User) { +TEST_F(MndTestUser, 04_Drop_User) { { - int32_t contLen = sizeof(SDropUserMsg); + int32_t contLen = sizeof(SDropUserReq); - SDropUserMsg* pReq = (SDropUserMsg*)rpcMallocCont(contLen); + SDropUserReq* pReq = (SDropUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, ""); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_INVALID_USER_FORMAT); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_INVALID_USER_FORMAT); } { - int32_t contLen = sizeof(SDropUserMsg); + int32_t contLen = sizeof(SDropUserReq); - SDropUserMsg* pReq = (SDropUserMsg*)rpcMallocCont(contLen); + SDropUserReq* pReq = (SDropUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u4"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, TSDB_CODE_MND_USER_NOT_EXIST); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, TSDB_CODE_MND_USER_NOT_EXIST); } { - int32_t contLen = sizeof(SDropUserMsg); + int32_t contLen = sizeof(SDropUserReq); - SDropUserMsg* pReq = (SDropUserMsg*)rpcMallocCont(contLen); + SDropUserReq* pReq = (SDropUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 1); } -TEST_F(DndTestUser, 05_Create_Drop_Alter_User) { +TEST_F(MndTestUser, 05_Create_Drop_Alter_User) { { - int32_t contLen = sizeof(SCreateUserMsg); + int32_t contLen = sizeof(SCreateUserReq); - SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(contLen); + SCreateUserReq* pReq = (SCreateUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); strcpy(pReq->pass, "p1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } { - int32_t contLen = sizeof(SCreateUserMsg); + int32_t contLen = sizeof(SCreateUserReq); - SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(contLen); + SCreateUserReq* pReq = (SCreateUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u2"); strcpy(pReq->pass, "p2"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_CREATE_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 3); CheckBinary("u1", TSDB_USER_LEN); @@ -235,21 +235,21 @@ TEST_F(DndTestUser, 05_Create_Drop_Alter_User) { CheckBinary("root", TSDB_USER_LEN); { - int32_t contLen = sizeof(SAlterUserMsg); + int32_t contLen = sizeof(SAlterUserReq); - SAlterUserMsg* pReq = (SAlterUserMsg*)rpcMallocCont(contLen); + SAlterUserReq* pReq = (SAlterUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); strcpy(pReq->pass, "p2"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_ALTER_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_ALTER_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 3); CheckBinary("u1", TSDB_USER_LEN); @@ -266,20 +266,20 @@ TEST_F(DndTestUser, 05_Create_Drop_Alter_User) { CheckBinary("root", TSDB_USER_LEN); { - int32_t contLen = sizeof(SDropUserMsg); + int32_t contLen = sizeof(SDropUserReq); - SDropUserMsg* pReq = (SDropUserMsg*)rpcMallocCont(contLen); + SDropUserReq* pReq = (SDropUserReq*)rpcMallocCont(contLen); strcpy(pReq->user, "u1"); - SRpcMsg* pMsg = test.SendMsg(TDMT_MND_DROP_USER, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_DROP_USER, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 2); CheckBinary("root", TSDB_USER_LEN); @@ -294,10 +294,10 @@ TEST_F(DndTestUser, 05_Create_Drop_Alter_User) { // restart test.Restart(); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_USER, ""); + test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); - test.SendShowRetrieveMsg(); + test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 2); CheckBinary("root", TSDB_USER_LEN); diff --git a/source/dnode/mnode/sdb/src/sdb.c b/source/dnode/mnode/sdb/src/sdb.c index ef5bb6f16f..39b5bb4d5b 100644 --- a/source/dnode/mnode/sdb/src/sdb.c +++ b/source/dnode/mnode/sdb/src/sdb.c @@ -64,8 +64,9 @@ SSdb *sdbInit(SSdbOpt *pOption) { void sdbCleanup(SSdb *pSdb) { mDebug("start to cleanup sdb"); - if (pSdb->curVer != pSdb->lastCommitVer) { - mDebug("write sdb file for current ver:%" PRId64 " != last commit ver:%" PRId64, pSdb->curVer, pSdb->lastCommitVer); + if (pSdb->curVer > pSdb->lastCommitVer) { + mDebug("write sdb file for current ver:%" PRId64 " larger than last commit ver:%" PRId64, pSdb->curVer, + pSdb->lastCommitVer); sdbWriteFile(pSdb); } diff --git a/source/dnode/mnode/sdb/src/sdbHash.c b/source/dnode/mnode/sdb/src/sdbHash.c index 733075757f..8fdb6b1657 100644 --- a/source/dnode/mnode/sdb/src/sdbHash.c +++ b/source/dnode/mnode/sdb/src/sdbHash.c @@ -69,6 +69,8 @@ static const char *sdbStatusStr(ESdbStatus status) { return "ready"; case SDB_STATUS_DROPPED: return "dropped"; + case SDB_STATUS_INIT: + return "init"; default: return "undefine"; } @@ -261,6 +263,8 @@ int32_t sdbWrite(SSdb *pSdb, SSdbRaw *pRaw) { } void *sdbAcquire(SSdb *pSdb, ESdbType type, void *pKey) { + terrno = 0; + SHashObj *hash = sdbGetHash(pSdb, type); if (hash == NULL) return NULL; @@ -425,3 +429,12 @@ int32_t sdbGetMaxId(SSdb *pSdb, ESdbType type) { maxId = MAX(maxId, pSdb->maxId[type]); return maxId + 1; } + +int64_t sdbGetTableVer(SSdb *pSdb, ESdbType type) { + if (type >= SDB_MAX || type < 0) { + terrno = TSDB_CODE_SDB_INVALID_TABLE_TYPE; + return -1; + } + + return pSdb->tableVer[type]; +} diff --git a/source/dnode/qnode/inc/qndInt.h b/source/dnode/qnode/inc/qndInt.h index e9f1229a9d..529c407efa 100644 --- a/source/dnode/qnode/inc/qndInt.h +++ b/source/dnode/qnode/inc/qndInt.h @@ -32,9 +32,9 @@ typedef struct SQnode { int32_t dnodeId; int64_t clusterId; SQnodeCfg cfg; - SendMsgToDnodeFp sendMsgToDnodeFp; - SendMsgToMnodeFp sendMsgToMnodeFp; - SendRedirectMsgFp sendRedirectMsgFp; + SendReqToDnodeFp sendReqToDnodeFp; + SendReqToMnodeFp sendReqToMnodeFp; + SendRedirectRspFp sendRedirectRspFp; } SQnode; #ifdef __cplusplus diff --git a/source/dnode/snode/inc/sndInt.h b/source/dnode/snode/inc/sndInt.h index 8827c92eef..3b41c7f4b1 100644 --- a/source/dnode/snode/inc/sndInt.h +++ b/source/dnode/snode/inc/sndInt.h @@ -32,9 +32,9 @@ typedef struct SSnode { int32_t dnodeId; int64_t clusterId; SSnodeCfg cfg; - SendMsgToDnodeFp sendMsgToDnodeFp; - SendMsgToMnodeFp sendMsgToMnodeFp; - SendRedirectMsgFp sendRedirectMsgFp; + SendReqToDnodeFp sendReqToDnodeFp; + SendReqToMnodeFp sendReqToMnodeFp; + SendRedirectRspFp sendRedirectRspFp; } SSnode; #ifdef __cplusplus diff --git a/source/dnode/vnode/impl/inc/vnodeCommit.h b/source/dnode/vnode/impl/inc/vnodeCommit.h index 031089ba14..e6568fbd52 100644 --- a/source/dnode/vnode/impl/inc/vnodeCommit.h +++ b/source/dnode/vnode/impl/inc/vnodeCommit.h @@ -23,8 +23,8 @@ extern "C" { #endif #define vnodeShouldCommit vnodeBufPoolIsFull +int vnodeSyncCommit(SVnode *pVnode); int vnodeAsyncCommit(SVnode *pVnode); -int vnodeCommit(void *arg); #ifdef __cplusplus } diff --git a/source/dnode/vnode/impl/inc/vnodeDef.h b/source/dnode/vnode/impl/inc/vnodeDef.h index fdb9837292..e70e891794 100644 --- a/source/dnode/vnode/impl/inc/vnodeDef.h +++ b/source/dnode/vnode/impl/inc/vnodeDef.h @@ -23,6 +23,7 @@ #include "tlockfree.h" #include "tmacro.h" #include "wal.h" +#include "tfs.h" #include "vnode.h" @@ -48,7 +49,6 @@ typedef struct SVnodeTask { typedef struct SVnodeMgr { td_mode_flag_t vnodeInitFlag; - td_mode_flag_t vnodeClearFlag; // For commit bool stop; uint16_t nthreads; diff --git a/source/dnode/vnode/impl/inc/vnodeRequest.h b/source/dnode/vnode/impl/inc/vnodeRequest.h index 93b4589bad..52f4281eea 100644 --- a/source/dnode/vnode/impl/inc/vnodeRequest.h +++ b/source/dnode/vnode/impl/inc/vnodeRequest.h @@ -22,9 +22,9 @@ extern "C" { #endif -// SVDropTableReq -// int vnodeBuildDropTableReq(void **buf, const SVDropTableReq *pReq); -// void *vnodeParseDropTableReq(void *buf, SVDropTableReq *pReq); +// SVDropTbReq +// int vnodeBuildDropTableReq(void **buf, const SVDropTbReq *pReq); +// void *vnodeParseDropTableReq(void *buf, SVDropTbReq *pReq); #ifdef __cplusplus } diff --git a/source/dnode/vnode/impl/src/vnodeBufferPool.c b/source/dnode/vnode/impl/src/vnodeBufferPool.c index 228df6c0a4..c2040501e8 100644 --- a/source/dnode/vnode/impl/src/vnodeBufferPool.c +++ b/source/dnode/vnode/impl/src/vnodeBufferPool.c @@ -97,14 +97,17 @@ int vnodeBufPoolSwitch(SVnode *pVnode) { pVnode->pBufPool->inuse = NULL; - TD_DLIST_APPEND(&(pVnode->pBufPool->incycle), pvma); + if (pvma) { + TD_DLIST_APPEND(&(pVnode->pBufPool->incycle), pvma); + } return 0; } int vnodeBufPoolRecycle(SVnode *pVnode) { SVBufPool * pBufPool = pVnode->pBufPool; SVMemAllocator *pvma = TD_DLIST_HEAD(&(pBufPool->incycle)); - ASSERT(pvma != NULL); + if (pvma == NULL) return 0; + // ASSERT(pvma != NULL); TD_DLIST_POP(&(pBufPool->incycle), pvma); vmaReset(pvma); diff --git a/source/dnode/vnode/impl/src/vnodeCommit.c b/source/dnode/vnode/impl/src/vnodeCommit.c index f5bf60a7e3..fbea827ec7 100644 --- a/source/dnode/vnode/impl/src/vnodeCommit.c +++ b/source/dnode/vnode/impl/src/vnodeCommit.c @@ -15,10 +15,14 @@ #include "vnodeDef.h" -static int vnodeStartCommit(SVnode *pVnode); -static int vnodeEndCommit(SVnode *pVnode); +static int vnodeStartCommit(SVnode *pVnode); +static int vnodeEndCommit(SVnode *pVnode); +static int vnodeCommit(void *arg); +static void vnodeWaitCommit(SVnode *pVnode); int vnodeAsyncCommit(SVnode *pVnode) { + vnodeWaitCommit(pVnode); + vnodeBufPoolSwitch(pVnode); SVnodeTask *pTask = (SVnodeTask *)malloc(sizeof(*pTask)); @@ -33,7 +37,14 @@ int vnodeAsyncCommit(SVnode *pVnode) { return 0; } -int vnodeCommit(void *arg) { +int vnodeSyncCommit(SVnode *pVnode) { + vnodeAsyncCommit(pVnode); + vnodeWaitCommit(pVnode); + tsem_post(&(pVnode->canCommit)); + return 0; +} + +static int vnodeCommit(void *arg) { SVnode *pVnode = (SVnode *)arg; metaCommit(pVnode->pMeta); @@ -42,7 +53,6 @@ int vnodeCommit(void *arg) { vnodeBufPoolRecycle(pVnode); tsem_post(&(pVnode->canCommit)); - // TODO return 0; } @@ -54,4 +64,6 @@ static int vnodeStartCommit(SVnode *pVnode) { static int vnodeEndCommit(SVnode *pVnode) { // TODO return 0; -} \ No newline at end of file +} + +static FORCE_INLINE void vnodeWaitCommit(SVnode *pVnode) { tsem_wait(&pVnode->canCommit); } \ No newline at end of file diff --git a/source/dnode/vnode/impl/src/vnodeMain.c b/source/dnode/vnode/impl/src/vnodeMain.c index 2b0363c97f..eb4b45bc20 100644 --- a/source/dnode/vnode/impl/src/vnodeMain.c +++ b/source/dnode/vnode/impl/src/vnodeMain.c @@ -15,18 +15,18 @@ #include "vnodeDef.h" -static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg); +static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg, int32_t vid); static void vnodeFree(SVnode *pVnode); static int vnodeOpenImpl(SVnode *pVnode); static void vnodeCloseImpl(SVnode *pVnode); -SVnode *vnodeOpen(const char *path, const SVnodeCfg *pVnodeCfg) { +SVnode *vnodeOpen(const char *path, const SVnodeCfg *pVnodeCfg, int32_t vid) { SVnode *pVnode = NULL; // Set default options - if (pVnodeCfg == NULL) { + //if (pVnodeCfg == NULL) { pVnodeCfg = &defaultVnodeOptions; - } + //} // Validate options if (vnodeValidateOptions(pVnodeCfg) < 0) { @@ -35,7 +35,7 @@ SVnode *vnodeOpen(const char *path, const SVnodeCfg *pVnodeCfg) { } // Create the handle - pVnode = vnodeNew(path, pVnodeCfg); + pVnode = vnodeNew(path, pVnodeCfg, vid); if (pVnode == NULL) { // TODO: handle error return NULL; @@ -62,7 +62,7 @@ void vnodeClose(SVnode *pVnode) { void vnodeDestroy(const char *path) { taosRemoveDir(path); } /* ------------------------ STATIC METHODS ------------------------ */ -static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg) { +static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg, int32_t vid) { SVnode *pVnode = NULL; pVnode = (SVnode *)calloc(1, sizeof(*pVnode)); @@ -71,6 +71,7 @@ static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg) { return NULL; } + pVnode->vgId = vid; pVnode->path = strdup(path); vnodeOptionsCopy(&(pVnode->config), pVnodeCfg); @@ -105,7 +106,7 @@ static int vnodeOpenImpl(SVnode *pVnode) { // Open tsdb sprintf(dir, "%s/tsdb", pVnode->path); - pVnode->pTsdb = tsdbOpen(dir, &(pVnode->config.tsdbCfg), vBufPoolGetMAF(pVnode)); + pVnode->pTsdb = tsdbOpen(dir, pVnode->vgId, &(pVnode->config.tsdbCfg), vBufPoolGetMAF(pVnode), pVnode->pMeta); if (pVnode->pTsdb == NULL) { // TODO: handle error return -1; @@ -137,6 +138,7 @@ static int vnodeOpenImpl(SVnode *pVnode) { } static void vnodeCloseImpl(SVnode *pVnode) { + vnodeSyncCommit(pVnode); if (pVnode) { vnodeCloseBufPool(pVnode); metaClose(pVnode->pMeta); diff --git a/source/dnode/vnode/impl/src/vnodeMgr.c b/source/dnode/vnode/impl/src/vnodeMgr.c index fae96ae22c..784d1abb60 100644 --- a/source/dnode/vnode/impl/src/vnodeMgr.c +++ b/source/dnode/vnode/impl/src/vnodeMgr.c @@ -15,7 +15,7 @@ #include "vnodeDef.h" -SVnodeMgr vnodeMgr = {.vnodeInitFlag = TD_MOD_UNINITIALIZED, .vnodeClearFlag = TD_MOD_UNCLEARD, .stop = false}; +SVnodeMgr vnodeMgr = {.vnodeInitFlag = TD_MOD_UNINITIALIZED}; static void* loop(void* arg); @@ -24,6 +24,8 @@ int vnodeInit(uint16_t nthreads) { return 0; } + vnodeMgr.stop = false; + // Start commit handers if (nthreads > 0) { vnodeMgr.nthreads = nthreads; @@ -38,6 +40,7 @@ int vnodeInit(uint16_t nthreads) { for (uint16_t i = 0; i < nthreads; i++) { pthread_create(&(vnodeMgr.threads[i]), NULL, loop, NULL); + pthread_setname_np(vnodeMgr.threads[i], "VND Commit Thread"); } } else { // TODO: if no commit thread is set, then another mechanism should be @@ -53,7 +56,7 @@ int vnodeInit(uint16_t nthreads) { } void vnodeClear() { - if (TD_CHECK_AND_SET_MOD_CLEAR(&(vnodeMgr.vnodeClearFlag)) == TD_MOD_CLEARD) { + if (TD_CHECK_AND_SET_MOD_CLEAR(&(vnodeMgr.vnodeInitFlag)) == TD_MOD_UNINITIALIZED) { return; } diff --git a/source/dnode/vnode/impl/src/vnodeQuery.c b/source/dnode/vnode/impl/src/vnodeQuery.c index 5f850f0112..29b6984937 100644 --- a/source/dnode/vnode/impl/src/vnodeQuery.c +++ b/source/dnode/vnode/impl/src/vnodeQuery.c @@ -22,12 +22,12 @@ static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp); int vnodeQueryOpen(SVnode *pVnode) { return qWorkerInit(NULL, &pVnode->pQuery); } int vnodeProcessQueryReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { - vInfo("query message is processed"); + vTrace("query message is processed"); return qWorkerProcessQueryMsg(pVnode, pVnode->pQuery, pMsg); } int vnodeProcessFetchReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { - vInfo("fetch message is processed"); + vTrace("fetch message is processed"); switch (pMsg->msgType) { case TDMT_VND_FETCH: return qWorkerProcessFetchMsg(pVnode, pVnode->pQuery, pMsg); @@ -53,14 +53,14 @@ int vnodeProcessFetchReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { } static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { - STableInfoMsg * pReq = (STableInfoMsg *)(pMsg->pCont); + STableInfoReq * pReq = (STableInfoReq *)(pMsg->pCont); STbCfg * pTbCfg = NULL; STbCfg * pStbCfg = NULL; tb_uid_t uid; int32_t nCols; int32_t nTagCols; SSchemaWrapper *pSW; - STableMetaMsg * pTbMetaMsg = NULL; + STableMetaRsp * pTbMetaMsg = NULL; SSchema * pTagSchema; SRpcMsg rpcMsg; int msgLen = 0; @@ -94,8 +94,8 @@ static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { pTagSchema = NULL; } - msgLen = sizeof(STableMetaMsg) + sizeof(SSchema) * (nCols + nTagCols); - pTbMetaMsg = (STableMetaMsg *)rpcMallocCont(msgLen); + msgLen = sizeof(STableMetaRsp) + sizeof(SSchema) * (nCols + nTagCols); + pTbMetaMsg = (STableMetaRsp *)rpcMallocCont(msgLen); if (pTbMetaMsg == NULL) { goto _exit; } @@ -105,6 +105,9 @@ static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { if (pTbCfg->type == META_CHILD_TABLE) { strcpy(pTbMetaMsg->stbFname, pStbCfg->name); pTbMetaMsg->suid = htobe64(pTbCfg->ctbCfg.suid); + } else if (pTbCfg->type == META_SUPER_TABLE) { + strcpy(pTbMetaMsg->stbFname, pTbCfg->name); + pTbMetaMsg->suid = htobe64(uid); } pTbMetaMsg->numOfTags = htonl(nTagCols); pTbMetaMsg->numOfColumns = htonl(nCols); @@ -164,7 +167,7 @@ static int32_t vnodeGetTableList(SVnode *pVnode, SRpcMsg *pMsg) { // SVShowTablesFetchReq *pFetchReq = pMsg->pCont; SVShowTablesFetchRsp *pFetchRsp = (SVShowTablesFetchRsp *)rpcMallocCont(sizeof(SVShowTablesFetchRsp) + payloadLen); - memset(pFetchRsp, 0, sizeof(struct SVShowTablesFetchRsp) + payloadLen); + memset(pFetchRsp, 0, sizeof(SVShowTablesFetchRsp) + payloadLen); char *p = pFetchRsp->data; for (int32_t i = 0; i < numOfTables; ++i) { diff --git a/source/dnode/vnode/impl/src/vnodeRequest.c b/source/dnode/vnode/impl/src/vnodeRequest.c index 4b481bf399..5367c9e091 100644 --- a/source/dnode/vnode/impl/src/vnodeRequest.c +++ b/source/dnode/vnode/impl/src/vnodeRequest.c @@ -108,12 +108,12 @@ static void *vnodeParseCreateTableReq(void *buf, SVCreateTableReq *pReq) { return buf; } -int vnodeBuildDropTableReq(void **buf, const SVDropTableReq *pReq) { +int vnodeBuildDropTableReq(void **buf, const SVDropTbReq *pReq) { // TODO return 0; } -void *vnodeParseDropTableReq(void *buf, SVDropTableReq *pReq) { +void *vnodeParseDropTableReq(void *buf, SVDropTbReq *pReq) { // TODO } #endif \ No newline at end of file diff --git a/source/dnode/vnode/impl/src/vnodeWrite.c b/source/dnode/vnode/impl/src/vnodeWrite.c index 88a73ca174..ddcb93863a 100644 --- a/source/dnode/vnode/impl/src/vnodeWrite.c +++ b/source/dnode/vnode/impl/src/vnodeWrite.c @@ -92,7 +92,7 @@ int vnodeApplyWMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { // } break; case TDMT_VND_SUBMIT: - if (tsdbInsertData(pVnode->pTsdb, (SSubmitMsg *)ptr) < 0) { + if (tsdbInsertData(pVnode->pTsdb, (SSubmitMsg *)ptr, NULL) < 0) { // TODO: handle error } break; diff --git a/source/dnode/vnode/meta/src/metaBDBImpl.c b/source/dnode/vnode/meta/src/metaBDBImpl.c index ae6693f973..ae13d9fddc 100644 --- a/source/dnode/vnode/meta/src/metaBDBImpl.c +++ b/source/dnode/vnode/meta/src/metaBDBImpl.c @@ -255,7 +255,7 @@ static int metaOpenBDBEnv(DB_ENV **ppEnv, const char *path) { return -1; } - ret = pEnv->open(pEnv, path, DB_CREATE | DB_INIT_MPOOL, 0); + ret = pEnv->open(pEnv, path, DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL, 0); if (ret != 0) { BDB_PERR("Failed to open META env", ret); return -1; @@ -589,4 +589,36 @@ char *metaTbCursorNext(SMTbCursor *pTbCur) { return NULL; } } +} + +STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver) { + STSchemaBuilder sb; + STSchema * pTSchema = NULL; + SSchema * pSchema; + SSchemaWrapper *pSW; + STbCfg * pTbCfg; + tb_uid_t quid; + + pTbCfg = metaGetTbInfoByUid(pMeta, uid); + if (pTbCfg->type == META_CHILD_TABLE) { + quid = pTbCfg->ctbCfg.suid; + } else { + quid = uid; + } + + pSW = metaGetTableSchema(pMeta, quid, sver, true); + if (pSW == NULL) { + return NULL; + } + + // Rebuild a schema + tdInitTSchemaBuilder(&sb, 0); + for (int32_t i = 0; i < pSW->nCols; i++) { + pSchema = pSW->pSchema + i; + tdAddColToSchema(&sb, pSchema->type, pSchema->colId, pSchema->bytes); + } + pTSchema = tdGetSchemaFromBuilder(&sb); + tdDestroyTSchemaBuilder(&sb); + + return pTSchema; } \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/CMakeLists.txt b/source/dnode/vnode/tsdb/CMakeLists.txt index 30e9d70f12..65dc95a9d8 100644 --- a/source/dnode/vnode/tsdb/CMakeLists.txt +++ b/source/dnode/vnode/tsdb/CMakeLists.txt @@ -2,7 +2,7 @@ aux_source_directory(src TSDB_SRC) if(0) add_library(tsdb ${TSDB_SRC}) else(0) - add_library(tsdb "") + add_library(tsdb STATIC "") target_sources(tsdb PRIVATE "src/tsdbCommit.c" @@ -10,6 +10,9 @@ else(0) "src/tsdbMemTable.c" "src/tsdbOptions.c" "src/tsdbWrite.c" + "src/tsdbReadImpl.c" + "src/tsdbFile.c" + "src/tsdbFS.c" ) endif(0) @@ -25,4 +28,6 @@ target_link_libraries( PUBLIC util PUBLIC common PUBLIC tkv + PUBLIC tfs + PUBLIC meta ) \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/inc/tsdbCommit.h b/source/dnode/vnode/tsdb/inc/tsdbCommit.h index 82ba1c9dff..9c35d06880 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbCommit.h +++ b/source/dnode/vnode/tsdb/inc/tsdbCommit.h @@ -16,7 +16,6 @@ #ifndef _TD_TSDB_COMMIT_H_ #define _TD_TSDB_COMMIT_H_ -#if 0 typedef struct { int minFid; int midFid; @@ -30,18 +29,15 @@ typedef struct { int64_t size; } SKVRecord; -#define TSDB_DEFAULT_BLOCK_ROWS(maxRows) ((maxRows)*4 / 5) +void tsdbGetRtnSnap(STsdb *pRepo, SRtn *pRtn); -void tsdbGetRtnSnap(STsdbRepo *pRepo, SRtn *pRtn); -int tsdbEncodeKVRecord(void **buf, SKVRecord *pRecord); -void *tsdbDecodeKVRecord(void *buf, SKVRecord *pRecord); -void *tsdbCommitData(STsdbRepo *pRepo); -int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn); -int tsdbWriteBlockInfoImpl(SDFile *pHeadf, STable *pTable, SArray *pSupA, SArray *pSubA, void **ppBuf, SBlockIdx *pIdx); -int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf); -int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, - bool isLast, bool isSuper, void **ppBuf, void **ppCBuf); -int tsdbApplyRtn(STsdbRepo *pRepo); +static FORCE_INLINE int TSDB_KEY_FID(TSKEY key, int32_t days, int8_t precision) { + if (key < 0) { + return (int)((key + 1) / tsTickPerDay[precision] / days - 1); + } else { + return (int)((key / tsTickPerDay[precision] / days)); + } +} static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) { if (fid >= pRtn->maxFid) { @@ -54,6 +50,20 @@ static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) { return -1; } } + +#if 0 +#define TSDB_DEFAULT_BLOCK_ROWS(maxRows) ((maxRows)*4 / 5) + +int tsdbEncodeKVRecord(void **buf, SKVRecord *pRecord); +void *tsdbDecodeKVRecord(void *buf, SKVRecord *pRecord); +void *tsdbCommitData(STsdbRepo *pRepo); +int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn); +int tsdbWriteBlockInfoImpl(SDFile *pHeadf, STable *pTable, SArray *pSupA, SArray *pSubA, void **ppBuf, SBlockIdx *pIdx); +int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf); +int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, + bool isLast, bool isSuper, void **ppBuf, void **ppCBuf); +int tsdbApplyRtn(STsdbRepo *pRepo); + #endif #endif /* _TD_TSDB_COMMIT_H_ */ \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/inc/tsdbCompact.h b/source/dnode/vnode/tsdb/inc/tsdbCompact.h index 441dfda6ad..c5df4e27ac 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbCompact.h +++ b/source/dnode/vnode/tsdb/inc/tsdbCompact.h @@ -12,6 +12,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +#if 0 + #ifndef _TD_TSDB_COMPACT_H_ #define _TD_TSDB_COMPACT_H_ @@ -19,14 +21,12 @@ extern "C" { #endif -#if 0 - void *tsdbCompactImpl(STsdbRepo *pRepo); -#endif - #ifdef __cplusplus } #endif -#endif /* _TD_TSDB_COMPACT_H_ */ \ No newline at end of file +#endif /* _TD_TSDB_COMPACT_H_ */ + +#endif \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/inc/tsdbDef.h b/source/dnode/vnode/tsdb/inc/tsdbDef.h index ded28727e4..51ddbe80aa 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbDef.h +++ b/source/dnode/vnode/tsdb/inc/tsdbDef.h @@ -17,27 +17,49 @@ #define _TD_TSDB_DEF_H_ #include "mallocator.h" -#include "tmsg.h" -#include "tlist.h" +#include "meta.h" +#include "tcompression.h" +#include "tglobal.h" #include "thash.h" +#include "tlist.h" +#include "tmsg.h" #include "tskiplist.h" +#include "ttime.h" #include "tsdb.h" +#include "tsdbCommit.h" +#include "tsdbFS.h" +#include "tsdbFile.h" +#include "tsdbLog.h" #include "tsdbMemTable.h" +#include "tsdbMemory.h" #include "tsdbOptions.h" +#include "tsdbReadImpl.h" #ifdef __cplusplus extern "C" { #endif struct STsdb { + int32_t vgId; char * path; - STsdbCfg options; + STsdbCfg config; STsdbMemTable * mem; STsdbMemTable * imem; + SRtn rtn; SMemAllocatorFactory *pmaf; + STsdbFS * fs; + SMeta * pMeta; }; +#define REPO_ID(r) ((r)->vgId) +#define REPO_CFG(r) (&(r)->config) +#define REPO_FS(r) (r)->fs + +static FORCE_INLINE STSchema *tsdbGetTableSchemaImpl(STable *pTable, bool lock, bool copy, int32_t version) { + return pTable->pSchema; +} + #ifdef __cplusplus } #endif diff --git a/source/dnode/vnode/tsdb/inc/tsdbFS.h b/source/dnode/vnode/tsdb/inc/tsdbFS.h index 0320756783..af432aa9d9 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbFS.h +++ b/source/dnode/vnode/tsdb/inc/tsdbFS.h @@ -16,7 +16,7 @@ #ifndef _TD_TSDB_FS_H_ #define _TD_TSDB_FS_H_ -#if 0 +#include "tsdbFile.h" #define TSDB_FS_VERSION 0 @@ -39,19 +39,17 @@ typedef struct { // ================== typedef struct { STsdbFSMeta meta; // FS meta - SMFile* pmf; // meta file pointer - SMFile mf; // meta file - SArray* df; // data file array + SArray * df; // data file array } SFSStatus; typedef struct { pthread_rwlock_t lock; - SFSStatus* cstatus; // current status - SHashObj* metaCache; // meta cache - SHashObj* metaCacheComp; // meta cache for compact + SFSStatus *cstatus; // current status + SHashObj * metaCache; // meta cache + SHashObj * metaCacheComp; // meta cache for compact bool intxn; - SFSStatus* nstatus; // new status + SFSStatus *nstatus; // new status } STsdbFS; #define FS_CURRENT_STATUS(pfs) ((pfs)->cstatus) @@ -63,32 +61,32 @@ typedef struct { typedef struct { int direction; uint64_t version; // current FS version - STsdbFS* pfs; + STsdbFS * pfs; int index; // used to position next fset when version the same int fid; // used to seek when version is changed - SDFileSet* pSet; + SDFileSet *pSet; } SFSIter; #define TSDB_FS_ITER_FORWARD TSDB_ORDER_ASC #define TSDB_FS_ITER_BACKWARD TSDB_ORDER_DESC -STsdbFS *tsdbNewFS(STsdbCfg *pCfg); +STsdbFS *tsdbNewFS(const STsdbCfg *pCfg); void * tsdbFreeFS(STsdbFS *pfs); -int tsdbOpenFS(STsdbRepo *pRepo); -void tsdbCloseFS(STsdbRepo *pRepo); -void tsdbStartFSTxn(STsdbRepo *pRepo, int64_t pointsAdd, int64_t storageAdd); -int tsdbEndFSTxn(STsdbRepo *pRepo); +int tsdbOpenFS(STsdb *pRepo); +void tsdbCloseFS(STsdb *pRepo); +void tsdbStartFSTxn(STsdb *pRepo, int64_t pointsAdd, int64_t storageAdd); +int tsdbEndFSTxn(STsdb *pRepo); int tsdbEndFSTxnWithError(STsdbFS *pfs); void tsdbUpdateFSTxnMeta(STsdbFS *pfs, STsdbFSMeta *pMeta); -void tsdbUpdateMFile(STsdbFS *pfs, const SMFile *pMFile); -int tsdbUpdateDFileSet(STsdbFS *pfs, const SDFileSet *pSet); +// void tsdbUpdateMFile(STsdbFS *pfs, const SMFile *pMFile); +int tsdbUpdateDFileSet(STsdbFS *pfs, const SDFileSet *pSet); void tsdbFSIterInit(SFSIter *pIter, STsdbFS *pfs, int direction); void tsdbFSIterSeek(SFSIter *pIter, int fid); SDFileSet *tsdbFSIterNext(SFSIter *pIter); -int tsdbLoadMetaCache(STsdbRepo *pRepo, bool recoverMeta); +int tsdbLoadMetaCache(STsdb *pRepo, bool recoverMeta); -static FORCE_INLINE int tsdbRLockFS(STsdbFS* pFs) { +static FORCE_INLINE int tsdbRLockFS(STsdbFS *pFs) { int code = pthread_rwlock_rdlock(&(pFs->lock)); if (code != 0) { terrno = TAOS_SYSTEM_ERROR(code); @@ -97,7 +95,7 @@ static FORCE_INLINE int tsdbRLockFS(STsdbFS* pFs) { return 0; } -static FORCE_INLINE int tsdbWLockFS(STsdbFS* pFs) { +static FORCE_INLINE int tsdbWLockFS(STsdbFS *pFs) { int code = pthread_rwlock_wrlock(&(pFs->lock)); if (code != 0) { terrno = TAOS_SYSTEM_ERROR(code); @@ -106,7 +104,7 @@ static FORCE_INLINE int tsdbWLockFS(STsdbFS* pFs) { return 0; } -static FORCE_INLINE int tsdbUnLockFS(STsdbFS* pFs) { +static FORCE_INLINE int tsdbUnLockFS(STsdbFS *pFs) { int code = pthread_rwlock_unlock(&(pFs->lock)); if (code != 0) { terrno = TAOS_SYSTEM_ERROR(code); @@ -115,6 +113,4 @@ static FORCE_INLINE int tsdbUnLockFS(STsdbFS* pFs) { return 0; } -#endif - #endif /* _TD_TSDB_FS_H_ */ diff --git a/source/dnode/vnode/tsdb/inc/tsdbFile.h b/source/dnode/vnode/tsdb/inc/tsdbFile.h index 73a7de0249..fb21ef56a7 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbFile.h +++ b/source/dnode/vnode/tsdb/inc/tsdbFile.h @@ -16,7 +16,8 @@ #ifndef _TS_TSDB_FILE_H_ #define _TS_TSDB_FILE_H_ -#if 0 +#include "tchecksum.h" +#include "tfs.h" #define TSDB_FILE_HEAD_SIZE 512 #define TSDB_FILE_DELIMITER 0xF00AFA0F @@ -34,7 +35,7 @@ #define TSDB_FILE_SET_CLOSED(f) (TSDB_FILE_FD(f) = -1) #define TSDB_FILE_LEVEL(tf) TFILE_LEVEL(TSDB_FILE_F(tf)) #define TSDB_FILE_ID(tf) TFILE_ID(TSDB_FILE_F(tf)) -#define TSDB_FILE_FSYNC(tf) taosFsync(TSDB_FILE_FD(tf)) +#define TSDB_FILE_FSYNC(tf) taosFsyncFile(TSDB_FILE_FD(tf)) #define TSDB_FILE_STATE(tf) ((tf)->state) #define TSDB_FILE_SET_STATE(tf, s) ((tf)->state = (s)) #define TSDB_FILE_IS_OK(tf) (TSDB_FILE_STATE(tf) == TSDB_FILE_STATE_OK) @@ -42,6 +43,7 @@ typedef enum { TSDB_FILE_HEAD = 0, TSDB_FILE_DATA, TSDB_FILE_LAST, TSDB_FILE_MAX, TSDB_FILE_META } TSDB_FILE_T; +#if 0 // =============== SMFile typedef struct { int64_t size; @@ -68,7 +70,7 @@ int tsdbApplyMFileChange(SMFile* from, SMFile* to); int tsdbCreateMFile(SMFile* pMFile, bool updateHeader); int tsdbUpdateMFileHeader(SMFile* pMFile); int tsdbLoadMFileHeader(SMFile* pMFile, SMFInfo* pInfo); -int tsdbScanAndTryFixMFile(STsdbRepo* pRepo); +int tsdbScanAndTryFixMFile(STsdb* pRepo); int tsdbEncodeMFInfo(void** buf, SMFInfo* pInfo); void* tsdbDecodeMFInfo(void* buf, SMFInfo* pInfo); @@ -96,7 +98,7 @@ static FORCE_INLINE void tsdbCloseMFile(SMFile* pMFile) { static FORCE_INLINE int64_t tsdbSeekMFile(SMFile* pMFile, int64_t offset, int whence) { ASSERT(TSDB_FILE_OPENED(pMFile)); - int64_t loffset = taosLSeek(TSDB_FILE_FD(pMFile), offset, whence); + int64_t loffset = taosLSeekFile(TSDB_FILE_FD(pMFile), offset, whence); if (loffset < 0) { terrno = TAOS_SYSTEM_ERROR(errno); return -1; @@ -108,7 +110,7 @@ static FORCE_INLINE int64_t tsdbSeekMFile(SMFile* pMFile, int64_t offset, int wh static FORCE_INLINE int64_t tsdbWriteMFile(SMFile* pMFile, void* buf, int64_t nbyte) { ASSERT(TSDB_FILE_OPENED(pMFile)); - int64_t nwrite = taosWrite(pMFile->fd, buf, nbyte); + int64_t nwrite = taosWriteFile(pMFile->fd, buf, nbyte); if (nwrite < nbyte) { terrno = TAOS_SYSTEM_ERROR(errno); return -1; @@ -150,7 +152,7 @@ static FORCE_INLINE int tsdbRemoveMFile(SMFile* pMFile) { return tfsremove(TSDB_ static FORCE_INLINE int64_t tsdbReadMFile(SMFile* pMFile, void* buf, int64_t nbyte) { ASSERT(TSDB_FILE_OPENED(pMFile)); - int64_t nread = taosRead(pMFile->fd, buf, nbyte); + int64_t nread = taosReadFile(pMFile->fd, buf, nbyte); if (nread < 0) { terrno = TAOS_SYSTEM_ERROR(errno); return -1; @@ -159,6 +161,8 @@ static FORCE_INLINE int64_t tsdbReadMFile(SMFile* pMFile, void* buf, int64_t nby return nread; } +#endif + // =============== SDFile typedef struct { uint32_t magic; @@ -210,7 +214,7 @@ static FORCE_INLINE void tsdbCloseDFile(SDFile* pDFile) { static FORCE_INLINE int64_t tsdbSeekDFile(SDFile* pDFile, int64_t offset, int whence) { ASSERT(TSDB_FILE_OPENED(pDFile)); - int64_t loffset = taosLSeek(TSDB_FILE_FD(pDFile), offset, whence); + int64_t loffset = taosLSeekFile(TSDB_FILE_FD(pDFile), offset, whence); if (loffset < 0) { terrno = TAOS_SYSTEM_ERROR(errno); return -1; @@ -222,7 +226,7 @@ static FORCE_INLINE int64_t tsdbSeekDFile(SDFile* pDFile, int64_t offset, int wh static FORCE_INLINE int64_t tsdbWriteDFile(SDFile* pDFile, void* buf, int64_t nbyte) { ASSERT(TSDB_FILE_OPENED(pDFile)); - int64_t nwrite = taosWrite(pDFile->fd, buf, nbyte); + int64_t nwrite = taosWriteFile(pDFile->fd, buf, nbyte); if (nwrite < nbyte) { terrno = TAOS_SYSTEM_ERROR(errno); return -1; @@ -264,7 +268,7 @@ static FORCE_INLINE int tsdbRemoveDFile(SDFile* pDFile) { return tfsremove(TSDB_ static FORCE_INLINE int64_t tsdbReadDFile(SDFile* pDFile, void* buf, int64_t nbyte) { ASSERT(TSDB_FILE_OPENED(pDFile)); - int64_t nread = taosRead(pDFile->fd, buf, nbyte); + int64_t nread = taosReadFile(pDFile->fd, buf, nbyte); if (nread < 0) { terrno = TAOS_SYSTEM_ERROR(errno); return -1; @@ -316,7 +320,7 @@ void* tsdbDecodeDFileSetEx(void* buf, SDFileSet* pSet); int tsdbApplyDFileSetChange(SDFileSet* from, SDFileSet* to); int tsdbCreateDFileSet(SDFileSet* pSet, bool updateHeader); int tsdbUpdateDFileSetHeader(SDFileSet* pSet); -int tsdbScanAndTryFixDFileSet(STsdbRepo *pRepo, SDFileSet* pSet); +int tsdbScanAndTryFixDFileSet(STsdb* pRepo, SDFileSet* pSet); static FORCE_INLINE void tsdbCloseDFileSet(SDFileSet* pSet) { for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { @@ -366,5 +370,4 @@ static FORCE_INLINE bool tsdbFSetIsOk(SDFileSet* pSet) { return true; } -#endif #endif /* _TS_TSDB_FILE_H_ */ \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/inc/tsdbLog.h b/source/dnode/vnode/tsdb/inc/tsdbLog.h new file mode 100644 index 0000000000..bde9b338a2 --- /dev/null +++ b/source/dnode/vnode/tsdb/inc/tsdbLog.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_TSDB_LOG_H_ +#define _TD_TSDB_LOG_H_ + +#include "tlog.h" + +extern int32_t tsdbDebugFlag; + +#define tsdbFatal(...) do { if (tsdbDebugFlag & DEBUG_FATAL) { taosPrintLog("TDB FATAL ", 255, __VA_ARGS__); }} while(0) +#define tsdbError(...) do { if (tsdbDebugFlag & DEBUG_ERROR) { taosPrintLog("TDB ERROR ", 255, __VA_ARGS__); }} while(0) +#define tsdbWarn(...) do { if (tsdbDebugFlag & DEBUG_WARN) { taosPrintLog("TDB WARN ", 255, __VA_ARGS__); }} while(0) +#define tsdbInfo(...) do { if (tsdbDebugFlag & DEBUG_INFO) { taosPrintLog("TDB ", 255, __VA_ARGS__); }} while(0) +#define tsdbDebug(...) do { if (tsdbDebugFlag & DEBUG_DEBUG) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }} while(0) +#define tsdbTrace(...) do { if (tsdbDebugFlag & DEBUG_TRACE) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }} while(0) + +#endif /* _TD_TSDB_LOG_H_ */ \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/inc/tsdbMemTable.h b/source/dnode/vnode/tsdb/inc/tsdbMemTable.h index e7787af7cf..d2e3d488d0 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbMemTable.h +++ b/source/dnode/vnode/tsdb/inc/tsdbMemTable.h @@ -22,11 +22,57 @@ extern "C" { #endif -typedef struct STsdbMemTable STsdbMemTable; +typedef struct { + int rowsInserted; + int rowsUpdated; + int rowsDeleteSucceed; + int rowsDeleteFailed; + int nOperations; + TSKEY keyFirst; + TSKEY keyLast; +} SMergeInfo; -STsdbMemTable *tsdbNewMemTable(SMemAllocatorFactory *pMAF); -void tsdbFreeMemTable(SMemAllocatorFactory *pMAF, STsdbMemTable *pMemTable); -int tsdbInsertDataToMemTable(STsdbMemTable *pMemTable, SSubmitMsg *pMsg); +typedef struct STbData { + tb_uid_t uid; + TSKEY keyMin; + TSKEY keyMax; + int64_t nrows; + SSkipList *pData; +} STbData; + +typedef struct STsdbMemTable { + T_REF_DECLARE() + SRWLatch latch; + TSKEY keyMin; + TSKEY keyMax; + uint64_t nRow; + SMemAllocator *pMA; + // Container + SSkipList *pSlIdx; // SSkiplist + SHashObj * pHashIdx; +} STsdbMemTable; + +STsdbMemTable *tsdbNewMemTable(STsdb *pTsdb); +void tsdbFreeMemTable(STsdb *pTsdb, STsdbMemTable *pMemTable); +int tsdbMemTableInsert(STsdb *pTsdb, STsdbMemTable *pMemTable, SSubmitMsg *pMsg, SShellSubmitRsp *pRsp); +int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead, SDataCols *pCols, + TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo); + +static FORCE_INLINE SMemRow tsdbNextIterRow(SSkipListIterator *pIter) { + if (pIter == NULL) return NULL; + + SSkipListNode *node = tSkipListIterGet(pIter); + if (node == NULL) return NULL; + + return (SMemRow)SL_GET_NODE_DATA(node); +} + +static FORCE_INLINE TSKEY tsdbNextIterKey(SSkipListIterator *pIter) { + SMemRow row = tsdbNextIterRow(pIter); + if (row == NULL) return TSDB_DATA_TIMESTAMP_NULL; + + return memRowKey(row); +} #ifdef __cplusplus } diff --git a/source/dnode/vnode/tsdb/inc/tsdbMemory.h b/source/dnode/vnode/tsdb/inc/tsdbMemory.h new file mode 100644 index 0000000000..1fc4cd9e52 --- /dev/null +++ b/source/dnode/vnode/tsdb/inc/tsdbMemory.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_TSDB_MEMORY_H_ +#define _TD_TSDB_MEMORY_H_ + +static void * taosTMalloc(size_t size); +static void * taosTCalloc(size_t nmemb, size_t size); +static void * taosTRealloc(void *ptr, size_t size); +static void * taosTZfree(void *ptr); +static size_t taosTSizeof(void *ptr); +static void taosTMemset(void *ptr, int c); + +static FORCE_INLINE void *taosTMalloc(size_t size) { + if (size <= 0) return NULL; + + void *ret = malloc(size + sizeof(size_t)); + if (ret == NULL) return NULL; + + *(size_t *)ret = size; + + return (void *)((char *)ret + sizeof(size_t)); +} + +static FORCE_INLINE void *taosTCalloc(size_t nmemb, size_t size) { + size_t tsize = nmemb * size; + void * ret = taosTMalloc(tsize); + if (ret == NULL) return NULL; + + taosTMemset(ret, 0); + return ret; +} + +static FORCE_INLINE size_t taosTSizeof(void *ptr) { return (ptr) ? (*(size_t *)((char *)ptr - sizeof(size_t))) : 0; } + +static FORCE_INLINE void taosTMemset(void *ptr, int c) { memset(ptr, c, taosTSizeof(ptr)); } + +static FORCE_INLINE void * taosTRealloc(void *ptr, size_t size) { + if (ptr == NULL) return taosTMalloc(size); + + if (size <= taosTSizeof(ptr)) return ptr; + + void * tptr = (void *)((char *)ptr - sizeof(size_t)); + size_t tsize = size + sizeof(size_t); + void* tptr1 = realloc(tptr, tsize); + if (tptr1 == NULL) return NULL; + tptr = tptr1; + + *(size_t *)tptr = size; + + return (void *)((char *)tptr + sizeof(size_t)); +} + +static FORCE_INLINE void* taosTZfree(void* ptr) { + if (ptr) { + free((void*)((char*)ptr - sizeof(size_t))); + } + return NULL; +} + + +#endif /* _TD_TSDB_MEMORY_H_ */ \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/inc/tsdbReadImpl.h b/source/dnode/vnode/tsdb/inc/tsdbReadImpl.h index a9bd76c2b1..3fb235e7dd 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbReadImpl.h +++ b/source/dnode/vnode/tsdb/inc/tsdbReadImpl.h @@ -15,14 +15,14 @@ #ifndef _TD_TSDB_READ_IMPL_H_ #define _TD_TSDB_READ_IMPL_H_ -#if 0 +#include "os.h" #include "tfs.h" #include "tsdb.h" -#include "os.h" #include "tsdbFile.h" #include "tskiplist.h" -#include "tsdbMeta.h" +#include "tsdbMemory.h" +#include "common.h" typedef struct SReadH SReadH; @@ -91,7 +91,7 @@ typedef struct { } SBlockData; struct SReadH { - STsdbRepo * pRepo; + STsdb * pRepo; SDFileSet rSet; // FSET to read SArray * aBlkIdx; // SBlockIdx array STable * pTable; // table to read @@ -116,7 +116,7 @@ struct SReadH { #define TSDB_BLOCK_STATIS_SIZE(ncols) (sizeof(SBlockData) + sizeof(SBlockCol) * (ncols) + sizeof(TSCKSUM)) -int tsdbInitReadH(SReadH *pReadh, STsdbRepo *pRepo); +int tsdbInitReadH(SReadH *pReadh, STsdb *pRepo); void tsdbDestroyReadH(SReadH *pReadh); int tsdbSetAndOpenReadFSet(SReadH *pReadh, SDFileSet *pSet); void tsdbCloseAndUnsetFSet(SReadH *pReadh); @@ -151,6 +151,4 @@ static FORCE_INLINE int tsdbMakeRoom(void **ppBuf, size_t size) { return 0; } -#endif - #endif /*_TD_TSDB_READ_IMPL_H_*/ diff --git a/source/dnode/vnode/tsdb/src/tsdbCommit.c b/source/dnode/vnode/tsdb/src/tsdbCommit.c index 1247dcd728..2be032a335 100644 --- a/source/dnode/vnode/tsdb/src/tsdbCommit.c +++ b/source/dnode/vnode/tsdb/src/tsdbCommit.c @@ -15,57 +15,19 @@ #include "tsdbDef.h" -int tsdbPrepareCommit(STsdb *pTsdb) { - if (pTsdb->mem == NULL) return 0; - - // tsem_wait(&(pTsdb->canCommit)); - ASSERT(pTsdb->imem == NULL); - - pTsdb->imem = pTsdb->mem; - pTsdb->mem = NULL; -} - -int tsdbCommit(STsdb *pTsdb) { - // TODO - pTsdb->imem = NULL; - // tsem_post(&(pTsdb->canCommit)); - return 0; -} - -#if 0 -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include "tsdbint.h" - -extern int32_t tsTsdbMetaCompactRatio; - #define TSDB_MAX_SUBBLOCKS 8 -static FORCE_INLINE int TSDB_KEY_FID(TSKEY key, int32_t days, int8_t precision) { - if (key < 0) { - return (int)((key + 1) / tsTickPerDay[precision] / days - 1); - } else { - return (int)((key / tsTickPerDay[precision] / days)); - } -} + +typedef struct { + STable * pTable; + SSkipListIterator *pIter; +} SCommitIter; typedef struct { SRtn rtn; // retention snapshot SFSIter fsIter; // tsdb file iterator int niters; // memory iterators SCommitIter *iters; - bool isRFileSet; // read and commit FSET + bool isRFileSet; // read and commit FSET SReadH readh; SDFileSet wSet; bool isDFileSame; @@ -79,6 +41,8 @@ typedef struct { SDataCols * pDataCols; } SCommitH; +#define TSDB_DEFAULT_BLOCK_ROWS(maxRows) ((maxRows)*4 / 5) + #define TSDB_COMMIT_REPO(ch) TSDB_READ_REPO(&(ch->readh)) #define TSDB_COMMIT_REPO_ID(ch) REPO_ID(TSDB_READ_REPO(&(ch->readh))) #define TSDB_COMMIT_WRITE_FSET(ch) (&((ch)->wSet)) @@ -91,21 +55,21 @@ typedef struct { #define TSDB_COMMIT_DEFAULT_ROWS(ch) TSDB_DEFAULT_BLOCK_ROWS(TSDB_COMMIT_REPO(ch)->config.maxRowsPerFileBlock) #define TSDB_COMMIT_TXN_VERSION(ch) FS_TXN_VERSION(REPO_FS(TSDB_COMMIT_REPO(ch))) -static int tsdbCommitMeta(STsdbRepo *pRepo); -static int tsdbUpdateMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid, void *cont, int contLen, bool compact); -static int tsdbDropMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid); -static int tsdbCompactMetaFile(STsdbRepo *pRepo, STsdbFS *pfs, SMFile *pMFile); -static int tsdbCommitTSData(STsdbRepo *pRepo); -static void tsdbStartCommit(STsdbRepo *pRepo); -static void tsdbEndCommit(STsdbRepo *pRepo, int eno); -static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid); +static void tsdbStartCommit(STsdb *pRepo); +static void tsdbEndCommit(STsdb *pTsdb, int eno); +static int tsdbInitCommitH(SCommitH *pCommith, STsdb *pRepo); +static void tsdbSeekCommitIter(SCommitH *pCommith, TSKEY key); +static int tsdbNextCommitFid(SCommitH *pCommith); +static void tsdbDestroyCommitH(SCommitH *pCommith); static int tsdbCreateCommitIters(SCommitH *pCommith); static void tsdbDestroyCommitIters(SCommitH *pCommith); -static void tsdbSeekCommitIter(SCommitH *pCommith, TSKEY key); -static int tsdbInitCommitH(SCommitH *pCommith, STsdbRepo *pRepo); -static void tsdbDestroyCommitH(SCommitH *pCommith); -static int tsdbGetFidLevel(int fid, SRtn *pRtn); -static int tsdbNextCommitFid(SCommitH *pCommith); +static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid); +static void tsdbResetCommitFile(SCommitH *pCommith); +static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid); +// static int tsdbCommitMeta(STsdbRepo *pRepo); +// static int tsdbUpdateMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid, void *cont, int contLen, bool compact); +// static int tsdbDropMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid); +// static int tsdbCompactMetaFile(STsdbRepo *pRepo, STsdbFS *pfs, SMFile *pMFile); static int tsdbCommitToTable(SCommitH *pCommith, int tid); static int tsdbSetCommitTable(SCommitH *pCommith, STable *pTable); static int tsdbComparKeyBlock(const void *arg1, const void *arg2); @@ -116,44 +80,14 @@ static int tsdbMoveBlock(SCommitH *pCommith, int bidx); static int tsdbCommitAddBlock(SCommitH *pCommith, const SBlock *pSupBlock, const SBlock *pSubBlocks, int nSubBlocks); static int tsdbMergeBlockData(SCommitH *pCommith, SCommitIter *pIter, SDataCols *pDataCols, TSKEY keyLimit, bool isLastOneBlock); -static void tsdbResetCommitFile(SCommitH *pCommith); static void tsdbResetCommitTable(SCommitH *pCommith); -static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid); static void tsdbCloseCommitFile(SCommitH *pCommith, bool hasError); static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *pInfo); static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIter *pCommitIter, SDataCols *pTarget, TSKEY maxKey, int maxRows, int8_t update); +int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf); -void *tsdbCommitData(STsdbRepo *pRepo) { - if (pRepo->imem == NULL) { - return NULL; - } - tsdbStartCommit(pRepo); - - // Commit to update meta file - if (tsdbCommitMeta(pRepo) < 0) { - tsdbError("vgId:%d error occurs while committing META data since %s", REPO_ID(pRepo), tstrerror(terrno)); - goto _err; - } - - // Create the iterator to read from cache - if (tsdbCommitTSData(pRepo) < 0) { - tsdbError("vgId:%d error occurs while committing TS data since %s", REPO_ID(pRepo), tstrerror(terrno)); - goto _err; - } - - tsdbEndCommit(pRepo, TSDB_CODE_SUCCESS); - return NULL; - -_err: - ASSERT(terrno != TSDB_CODE_SUCCESS); - pRepo->code = terrno; - - tsdbEndCommit(pRepo, terrno); - return NULL; -} - -int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn) { +int tsdbApplyRtnOnFSet(STsdb *pRepo, SDFileSet *pSet, SRtn *pRtn) { SDiskID did; SDFileSet nSet; STsdbFS * pfs = REPO_FS(pRepo); @@ -195,460 +129,24 @@ int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn) { return 0; } -int tsdbWriteBlockInfoImpl(SDFile *pHeadf, STable *pTable, SArray *pSupA, SArray *pSubA, void **ppBuf, - SBlockIdx *pIdx) { - size_t nSupBlocks; - size_t nSubBlocks; - uint32_t tlen; - SBlockInfo *pBlkInfo; - int64_t offset; - SBlock * pBlock; +int tsdbPrepareCommit(STsdb *pTsdb) { + if (pTsdb->mem == NULL) return 0; - memset(pIdx, 0, sizeof(*pIdx)); + ASSERT(pTsdb->imem == NULL); - nSupBlocks = taosArrayGetSize(pSupA); - nSubBlocks = (pSubA == NULL) ? 0 : taosArrayGetSize(pSubA); - - if (nSupBlocks <= 0) { - // No data (data all deleted) - return 0; - } - - tlen = (uint32_t)(sizeof(SBlockInfo) + sizeof(SBlock) * (nSupBlocks + nSubBlocks) + sizeof(TSCKSUM)); - if (tsdbMakeRoom(ppBuf, tlen) < 0) return -1; - pBlkInfo = *ppBuf; - - pBlkInfo->delimiter = TSDB_FILE_DELIMITER; - pBlkInfo->tid = TABLE_TID(pTable); - pBlkInfo->uid = TABLE_UID(pTable); - - memcpy((void *)(pBlkInfo->blocks), taosArrayGet(pSupA, 0), nSupBlocks * sizeof(SBlock)); - if (nSubBlocks > 0) { - memcpy((void *)(pBlkInfo->blocks + nSupBlocks), taosArrayGet(pSubA, 0), nSubBlocks * sizeof(SBlock)); - - for (int i = 0; i < nSupBlocks; i++) { - pBlock = pBlkInfo->blocks + i; - - if (pBlock->numOfSubBlocks > 1) { - pBlock->offset += (sizeof(SBlockInfo) + sizeof(SBlock) * nSupBlocks); - } - } - } - - taosCalcChecksumAppend(0, (uint8_t *)pBlkInfo, tlen); - - if (tsdbAppendDFile(pHeadf, (void *)pBlkInfo, tlen, &offset) < 0) { - return -1; - } - - tsdbUpdateDFileMagic(pHeadf, POINTER_SHIFT(pBlkInfo, tlen - sizeof(TSCKSUM))); - - // Set pIdx - pBlock = taosArrayGetLast(pSupA); - - pIdx->tid = TABLE_TID(pTable); - pIdx->uid = TABLE_UID(pTable); - pIdx->hasLast = pBlock->last ? 1 : 0; - pIdx->maxKey = pBlock->keyLast; - pIdx->numOfBlocks = (uint32_t)nSupBlocks; - pIdx->len = tlen; - pIdx->offset = (uint32_t)offset; - - return 0; + pTsdb->imem = pTsdb->mem; + pTsdb->mem = NULL; } -int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf) { - SBlockIdx *pBlkIdx; - size_t nidx = taosArrayGetSize(pIdxA); - int tlen = 0, size; - int64_t offset; +int tsdbCommit(STsdb *pRepo) { + STsdbMemTable *pMem = pRepo->imem; + SCommitH commith = {0}; + SDFileSet * pSet = NULL; + int fid; - if (nidx <= 0) { - // All data are deleted - pHeadf->info.offset = 0; - pHeadf->info.len = 0; - return 0; - } - - for (size_t i = 0; i < nidx; i++) { - pBlkIdx = (SBlockIdx *)taosArrayGet(pIdxA, i); - - size = tsdbEncodeSBlockIdx(NULL, pBlkIdx); - if (tsdbMakeRoom(ppBuf, tlen + size) < 0) return -1; - - void *ptr = POINTER_SHIFT(*ppBuf, tlen); - tsdbEncodeSBlockIdx(&ptr, pBlkIdx); - - tlen += size; - } - - tlen += sizeof(TSCKSUM); - if (tsdbMakeRoom(ppBuf, tlen) < 0) return -1; - taosCalcChecksumAppend(0, (uint8_t *)(*ppBuf), tlen); - - if (tsdbAppendDFile(pHeadf, *ppBuf, tlen, &offset) < tlen) { - return -1; - } - - tsdbUpdateDFileMagic(pHeadf, POINTER_SHIFT(*ppBuf, tlen - sizeof(TSCKSUM))); - pHeadf->info.offset = (uint32_t)offset; - pHeadf->info.len = tlen; - - 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; -} - -void tsdbGetRtnSnap(STsdbRepo *pRepo, SRtn *pRtn) { - STsdbCfg *pCfg = REPO_CFG(pRepo); - TSKEY minKey, midKey, maxKey, now; - - now = taosGetTimestamp(pCfg->precision); - minKey = now - pCfg->keep * tsTickPerDay[pCfg->precision]; - midKey = now - pCfg->keep2 * tsTickPerDay[pCfg->precision]; - maxKey = now - pCfg->keep1 * tsTickPerDay[pCfg->precision]; - - pRtn->minKey = minKey; - pRtn->minFid = (int)(TSDB_KEY_FID(minKey, pCfg->daysPerFile, pCfg->precision)); - pRtn->midFid = (int)(TSDB_KEY_FID(midKey, pCfg->daysPerFile, pCfg->precision)); - pRtn->maxFid = (int)(TSDB_KEY_FID(maxKey, pCfg->daysPerFile, pCfg->precision)); - tsdbDebug("vgId:%d now:%" PRId64 " minKey:%" PRId64 " minFid:%d, midFid:%d, maxFid:%d", REPO_ID(pRepo), now, minKey, - pRtn->minFid, pRtn->midFid, pRtn->maxFid); -} - -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 = malloc((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 = realloc(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 - remove(mf.f.aname); - taosHashCleanup(pfs->metaCacheComp); - pfs->metaCacheComp = NULL; - } - - tfree(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 -static int tsdbCommitTSData(STsdbRepo *pRepo) { - SMemTable *pMem = pRepo->imem; - SCommitH commith; - SDFileSet *pSet = NULL; - int fid; - - memset(&commith, 0, sizeof(commith)); - - if (pMem->numOfRows <= 0) { - // No memory data, just apply retention on each file on disk - if (tsdbApplyRtn(pRepo) < 0) { - return -1; - } - return 0; - } + if (pRepo->imem == NULL) return 0; + tsdbStartCommit(pRepo); // Resource initialization if (tsdbInitCommitH(&commith, pRepo) < 0) { return -1; @@ -706,171 +204,44 @@ static int tsdbCommitTSData(STsdbRepo *pRepo) { } tsdbDestroyCommitH(&commith); - return 0; -} - -static void tsdbStartCommit(STsdbRepo *pRepo) { - SMemTable *pMem = pRepo->imem; - - ASSERT(pMem->numOfRows > 0 || listNEles(pMem->actList) > 0); - - tsdbInfo("vgId:%d start to commit! keyFirst %" PRId64 " keyLast %" PRId64 " numOfRows %" PRId64 " meta rows: %d", - REPO_ID(pRepo), pMem->keyFirst, pMem->keyLast, pMem->numOfRows, listNEles(pMem->actList)); - - tsdbStartFSTxn(pRepo, pMem->pointsAdd, pMem->storageAdd); - - pRepo->code = TSDB_CODE_SUCCESS; -} - -static void tsdbEndCommit(STsdbRepo *pRepo, int eno) { - if (eno != TSDB_CODE_SUCCESS) { - tsdbEndFSTxnWithError(REPO_FS(pRepo)); - } else { - tsdbEndFSTxn(pRepo); - } - - tsdbInfo("vgId:%d commit over, %s", REPO_ID(pRepo), (eno == TSDB_CODE_SUCCESS) ? "succeed" : "failed"); - - if (pRepo->appH.notifyStatus) pRepo->appH.notifyStatus(pRepo->appH.appH, TSDB_STATUS_COMMIT_OVER, eno); - - SMemTable *pIMem = pRepo->imem; - (void)tsdbLockRepo(pRepo); - pRepo->imem = NULL; - (void)tsdbUnlockRepo(pRepo); - tsdbUnRefMemTable(pRepo, pIMem); - tsem_post(&(pRepo->readyToCommit)); -} - -#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 - -static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) { - STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith); - STsdbCfg * pCfg = REPO_CFG(pRepo); - - ASSERT(pSet == NULL || pSet->fid == fid); - - tsdbResetCommitFile(pCommith); - tsdbGetFidKeyRange(pCfg->daysPerFile, pCfg->precision, fid, &(pCommith->minKey), &(pCommith->maxKey)); - - // Set and open files - if (tsdbSetAndOpenCommitFile(pCommith, pSet, fid) < 0) { - return -1; - } - - // Loop to commit each table data - for (int tid = 1; tid < pCommith->niters; tid++) { - SCommitIter *pIter = pCommith->iters + tid; - - if (pIter->pTable == NULL) continue; - - if (tsdbCommitToTable(pCommith, tid) < 0) { - tsdbCloseCommitFile(pCommith, true); - // revert the file change - tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet); - return -1; - } - } - - if (tsdbWriteBlockIdx(TSDB_COMMIT_HEAD_FILE(pCommith), pCommith->aBlkIdx, (void **)(&(TSDB_COMMIT_BUF(pCommith)))) < - 0) { - tsdbError("vgId:%d failed to write SBlockIdx part to FSET %d since %s", REPO_ID(pRepo), fid, tstrerror(terrno)); - tsdbCloseCommitFile(pCommith, true); - // revert the file change - tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet); - return -1; - } - - if (tsdbUpdateDFileSetHeader(&(pCommith->wSet)) < 0) { - tsdbError("vgId:%d failed to update FSET %d header since %s", REPO_ID(pRepo), fid, tstrerror(terrno)); - tsdbCloseCommitFile(pCommith, true); - // revert the file change - tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet); - return -1; - } - - // Close commit file - tsdbCloseCommitFile(pCommith, false); - - if (tsdbUpdateDFileSet(REPO_FS(pRepo), &(pCommith->wSet)) < 0) { - return -1; - } + tsdbEndCommit(pRepo, TSDB_CODE_SUCCESS); return 0; } -static int tsdbCreateCommitIters(SCommitH *pCommith) { - STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith); - SMemTable *pMem = pRepo->imem; - STsdbMeta *pMeta = pRepo->tsdbMeta; +void tsdbGetRtnSnap(STsdb *pRepo, SRtn *pRtn) { + STsdbCfg *pCfg = REPO_CFG(pRepo); + TSKEY minKey, midKey, maxKey, now; - pCommith->niters = pMem->maxTables; - pCommith->iters = (SCommitIter *)calloc(pMem->maxTables, sizeof(SCommitIter)); - if (pCommith->iters == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } + now = taosGetTimestamp(pCfg->precision); + minKey = now - pCfg->keep * tsTickPerDay[pCfg->precision]; + midKey = now - pCfg->keep2 * tsTickPerDay[pCfg->precision]; + maxKey = now - pCfg->keep1 * tsTickPerDay[pCfg->precision]; - if (tsdbRLockRepoMeta(pRepo) < 0) return -1; - - // reference all tables - for (int i = 0; i < pMem->maxTables; i++) { - if (pMeta->tables[i] != NULL) { - tsdbRefTable(pMeta->tables[i]); - pCommith->iters[i].pTable = pMeta->tables[i]; - } - } - - if (tsdbUnlockRepoMeta(pRepo) < 0) return -1; - - for (int i = 0; i < pMem->maxTables; i++) { - if ((pCommith->iters[i].pTable != NULL) && (pMem->tData[i] != NULL) && - (TABLE_UID(pCommith->iters[i].pTable) == pMem->tData[i]->uid)) { - if ((pCommith->iters[i].pIter = tSkipListCreateIter(pMem->tData[i]->pData)) == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } - - tSkipListIterNext(pCommith->iters[i].pIter); - } - } - - return 0; + pRtn->minKey = minKey; + pRtn->minFid = (int)(TSDB_KEY_FID(minKey, pCfg->daysPerFile, pCfg->precision)); + pRtn->midFid = (int)(TSDB_KEY_FID(midKey, pCfg->daysPerFile, pCfg->precision)); + pRtn->maxFid = (int)(TSDB_KEY_FID(maxKey, pCfg->daysPerFile, pCfg->precision)); + tsdbDebug("vgId:%d now:%" PRId64 " minKey:%" PRId64 " minFid:%d, midFid:%d, maxFid:%d", REPO_ID(pRepo), now, minKey, + pRtn->minFid, pRtn->midFid, pRtn->maxFid); } -static void tsdbDestroyCommitIters(SCommitH *pCommith) { - if (pCommith->iters == NULL) return; +static void tsdbStartCommit(STsdb *pRepo) { + STsdbMemTable *pMem = pRepo->imem; - for (int i = 1; i < pCommith->niters; i++) { - if (pCommith->iters[i].pTable != NULL) { - tsdbUnRefTable(pCommith->iters[i].pTable); - tSkipListDestroyIter(pCommith->iters[i].pIter); - } - } + tsdbInfo("vgId:%d start to commit", REPO_ID(pRepo)); - free(pCommith->iters); - pCommith->iters = NULL; - pCommith->niters = 0; + tsdbStartFSTxn(pRepo, 0, 0); } -// Skip all keys until key (not included) -static void tsdbSeekCommitIter(SCommitH *pCommith, TSKEY key) { - for (int i = 0; i < pCommith->niters; i++) { - SCommitIter *pIter = pCommith->iters + i; - if (pIter->pTable == NULL || pIter->pIter == NULL) continue; - - tsdbLoadDataFromCache(pIter->pTable, pIter->pIter, key - 1, INT32_MAX, NULL, NULL, 0, true, NULL); - } +static void tsdbEndCommit(STsdb *pTsdb, int eno) { + tsdbEndFSTxn(pTsdb); + tsdbFreeMemTable(pTsdb, pTsdb->imem); + pTsdb->imem = NULL; + tsdbInfo("vgId:%d commit over, %s", REPO_ID(pTsdb), (eno == TSDB_CODE_SUCCESS) ? "succeed" : "failed"); } -static int tsdbInitCommitH(SCommitH *pCommith, STsdbRepo *pRepo) { +static int tsdbInitCommitH(SCommitH *pCommith, STsdb *pRepo) { STsdbCfg *pCfg = REPO_CFG(pRepo); memset(pCommith, 0, sizeof(*pCommith)); @@ -922,25 +293,25 @@ static int tsdbInitCommitH(SCommitH *pCommith, STsdbRepo *pRepo) { return 0; } -static void tsdbDestroyCommitH(SCommitH *pCommith) { - pCommith->pDataCols = tdFreeDataCols(pCommith->pDataCols); - pCommith->aSubBlk = taosArrayDestroy(pCommith->aSubBlk); - pCommith->aSupBlk = taosArrayDestroy(pCommith->aSupBlk); - pCommith->aBlkIdx = taosArrayDestroy(pCommith->aBlkIdx); - tsdbDestroyCommitIters(pCommith); - tsdbDestroyReadH(&(pCommith->readh)); - tsdbCloseDFileSet(TSDB_COMMIT_WRITE_FSET(pCommith)); -} - -static int tsdbNextCommitFid(SCommitH *pCommith) { - STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith); - STsdbCfg * pCfg = REPO_CFG(pRepo); - int fid = TSDB_IVLD_FID; - +// Skip all keys until key (not included) +static void tsdbSeekCommitIter(SCommitH *pCommith, TSKEY key) { for (int i = 0; i < pCommith->niters; i++) { SCommitIter *pIter = pCommith->iters + i; if (pIter->pTable == NULL || pIter->pIter == NULL) continue; + tsdbLoadDataFromCache(pIter->pTable, pIter->pIter, key - 1, INT32_MAX, NULL, NULL, 0, true, NULL); + } +} + +static int tsdbNextCommitFid(SCommitH *pCommith) { + STsdb * pRepo = TSDB_COMMIT_REPO(pCommith); + STsdbCfg *pCfg = REPO_CFG(pRepo); + int fid = TSDB_IVLD_FID; + + for (int i = 0; i < pCommith->niters; i++) { + SCommitIter *pIter = pCommith->iters + i; + // if (pIter->pTable == NULL || pIter->pIter == NULL) continue; + TSKEY nextKey = tsdbNextIterKey(pIter->pIter); if (nextKey == TSDB_DATA_TIMESTAMP_NULL) { continue; @@ -955,557 +326,122 @@ static int tsdbNextCommitFid(SCommitH *pCommith) { return fid; } -static int tsdbCommitToTable(SCommitH *pCommith, int tid) { - SCommitIter *pIter = pCommith->iters + tid; - TSKEY nextKey = tsdbNextIterKey(pIter->pIter); +static void tsdbDestroyCommitH(SCommitH *pCommith) { + pCommith->pDataCols = tdFreeDataCols(pCommith->pDataCols); + pCommith->aSubBlk = taosArrayDestroy(pCommith->aSubBlk); + pCommith->aSupBlk = taosArrayDestroy(pCommith->aSupBlk); + pCommith->aBlkIdx = taosArrayDestroy(pCommith->aBlkIdx); + tsdbDestroyCommitIters(pCommith); + tsdbDestroyReadH(&(pCommith->readh)); + tsdbCloseDFileSet(TSDB_COMMIT_WRITE_FSET(pCommith)); +} - tsdbResetCommitTable(pCommith); +static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) { + STsdb * pRepo = TSDB_COMMIT_REPO(pCommith); + STsdbCfg *pCfg = REPO_CFG(pRepo); - TSDB_RLOCK_TABLE(pIter->pTable); + ASSERT(pSet == NULL || pSet->fid == fid); - // Set commit table - if (tsdbSetCommitTable(pCommith, pIter->pTable) < 0) { - TSDB_RUNLOCK_TABLE(pIter->pTable); + tsdbResetCommitFile(pCommith); + tsdbGetFidKeyRange(pCfg->daysPerFile, pCfg->precision, fid, &(pCommith->minKey), &(pCommith->maxKey)); + + // Set and open files + if (tsdbSetAndOpenCommitFile(pCommith, pSet, fid) < 0) { return -1; } - // No disk data and no memory data, just return - if (pCommith->readh.pBlkIdx == NULL && (nextKey == TSDB_DATA_TIMESTAMP_NULL || nextKey > pCommith->maxKey)) { - TSDB_RUNLOCK_TABLE(pIter->pTable); - return 0; - } + // Loop to commit each table data + for (int tid = 0; tid < pCommith->niters; tid++) { + SCommitIter *pIter = pCommith->iters + tid; - // Must has disk data or has memory data - int nBlocks; - int bidx = 0; - SBlock *pBlock; + if (pIter->pTable == NULL) continue; - if (pCommith->readh.pBlkIdx) { - if (tsdbLoadBlockInfo(&(pCommith->readh), NULL) < 0) { - TSDB_RUNLOCK_TABLE(pIter->pTable); + if (tsdbCommitToTable(pCommith, tid) < 0) { + tsdbCloseCommitFile(pCommith, true); + // revert the file change + tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet); return -1; } - - nBlocks = pCommith->readh.pBlkIdx->numOfBlocks; - } else { - nBlocks = 0; } - if (bidx < nBlocks) { - pBlock = pCommith->readh.pBlkInfo->blocks + bidx; - } else { - pBlock = NULL; + if (tsdbWriteBlockIdx(TSDB_COMMIT_HEAD_FILE(pCommith), pCommith->aBlkIdx, (void **)(&(TSDB_COMMIT_BUF(pCommith)))) < + 0) { + tsdbError("vgId:%d failed to write SBlockIdx part to FSET %d since %s", REPO_ID(pRepo), fid, tstrerror(terrno)); + tsdbCloseCommitFile(pCommith, true); + // revert the file change + tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet); + return -1; } - while (true) { - if (pBlock == NULL && (nextKey == TSDB_DATA_TIMESTAMP_NULL || nextKey > pCommith->maxKey)) break; - - if ((nextKey == TSDB_DATA_TIMESTAMP_NULL || nextKey > pCommith->maxKey) || - (pBlock && (!pBlock->last) && tsdbComparKeyBlock((void *)(&nextKey), pBlock) > 0)) { - if (tsdbMoveBlock(pCommith, bidx) < 0) { - TSDB_RUNLOCK_TABLE(pIter->pTable); - return -1; - } - - bidx++; - if (bidx < nBlocks) { - pBlock = pCommith->readh.pBlkInfo->blocks + bidx; - } else { - pBlock = NULL; - } - } else if (pBlock && (pBlock->last || tsdbComparKeyBlock((void *)(&nextKey), pBlock) == 0)) { - // merge pBlock data and memory data - if (tsdbMergeMemData(pCommith, pIter, bidx) < 0) { - TSDB_RUNLOCK_TABLE(pIter->pTable); - return -1; - } - - bidx++; - if (bidx < nBlocks) { - pBlock = pCommith->readh.pBlkInfo->blocks + bidx; - } else { - pBlock = NULL; - } - nextKey = tsdbNextIterKey(pIter->pIter); - } else { - // Only commit memory data - if (pBlock == NULL) { - if (tsdbCommitMemData(pCommith, pIter, pCommith->maxKey, false) < 0) { - TSDB_RUNLOCK_TABLE(pIter->pTable); - return -1; - } - } else { - if (tsdbCommitMemData(pCommith, pIter, pBlock->keyFirst - 1, true) < 0) { - TSDB_RUNLOCK_TABLE(pIter->pTable); - return -1; - } - } - nextKey = tsdbNextIterKey(pIter->pIter); - } + if (tsdbUpdateDFileSetHeader(&(pCommith->wSet)) < 0) { + tsdbError("vgId:%d failed to update FSET %d header since %s", REPO_ID(pRepo), fid, tstrerror(terrno)); + tsdbCloseCommitFile(pCommith, true); + // revert the file change + tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet); + return -1; } - TSDB_RUNLOCK_TABLE(pIter->pTable); + // Close commit file + tsdbCloseCommitFile(pCommith, false); - if (tsdbWriteBlockInfo(pCommith) < 0) { - tsdbError("vgId:%d failed to write SBlockInfo part into file %s since %s", TSDB_COMMIT_REPO_ID(pCommith), - TSDB_FILE_FULL_NAME(TSDB_COMMIT_HEAD_FILE(pCommith)), tstrerror(terrno)); + if (tsdbUpdateDFileSet(REPO_FS(pRepo), &(pCommith->wSet)) < 0) { return -1; } return 0; } -static int tsdbSetCommitTable(SCommitH *pCommith, STable *pTable) { - STSchema *pSchema = tsdbGetTableSchemaImpl(pTable, false, false, -1); +static int tsdbCreateCommitIters(SCommitH *pCommith) { + STsdb * pRepo = TSDB_COMMIT_REPO(pCommith); + STsdbMemTable * pMem = pRepo->imem; + SSkipListIterator *pSlIter; + SCommitIter * pCommitIter; + SSkipListNode * pNode; + STbData * pTbData; - pCommith->pTable = pTable; - - if (tdInitDataCols(pCommith->pDataCols, pSchema) < 0) { + pCommith->niters = SL_SIZE(pMem->pSlIdx); + pCommith->iters = (SCommitIter *)calloc(pCommith->niters, sizeof(SCommitIter)); + if (pCommith->iters == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; return -1; } - if (pCommith->isRFileSet) { - if (tsdbSetReadTable(&(pCommith->readh), pTable) < 0) { - return -1; - } - } else { - pCommith->readh.pBlkIdx = NULL; - } - return 0; -} - -static int tsdbComparKeyBlock(const void *arg1, const void *arg2) { - TSKEY key = *(TSKEY *)arg1; - SBlock *pBlock = (SBlock *)arg2; - - if (key < pBlock->keyFirst) { - return -1; - } else if (key > pBlock->keyLast) { - return 1; - } else { - return 0; - } -} - -int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, - bool isLast, bool isSuper, void **ppBuf, void **ppCBuf) { - STsdbCfg * pCfg = REPO_CFG(pRepo); - SBlockData *pBlockData; - int64_t offset = 0; - int rowsToWrite = pDataCols->numOfRows; - - ASSERT(rowsToWrite > 0 && rowsToWrite <= pCfg->maxRowsPerFileBlock); - ASSERT((!isLast) || rowsToWrite < pCfg->minRowsPerFileBlock); - - // Make buffer space - if (tsdbMakeRoom(ppBuf, TSDB_BLOCK_STATIS_SIZE(pDataCols->numOfCols)) < 0) { - return -1; - } - pBlockData = (SBlockData *)(*ppBuf); - - // Get # of cols not all NULL(not including key column) - int nColsNotAllNull = 0; - for (int ncol = 1; ncol < pDataCols->numOfCols; ncol++) { // ncol from 1, we skip the timestamp column - SDataCol * pDataCol = pDataCols->cols + ncol; - SBlockCol *pBlockCol = pBlockData->cols + nColsNotAllNull; - - if (isAllRowsNull(pDataCol)) { // all data to commit are NULL, just ignore it - continue; - } - - memset(pBlockCol, 0, sizeof(*pBlockCol)); - - pBlockCol->colId = pDataCol->colId; - pBlockCol->type = pDataCol->type; - if (tDataTypes[pDataCol->type].statisFunc) { - (*tDataTypes[pDataCol->type].statisFunc)(pDataCol->pData, rowsToWrite, &(pBlockCol->min), &(pBlockCol->max), - &(pBlockCol->sum), &(pBlockCol->minIndex), &(pBlockCol->maxIndex), - &(pBlockCol->numOfNull)); - } - nColsNotAllNull++; - } - - ASSERT(nColsNotAllNull >= 0 && nColsNotAllNull <= pDataCols->numOfCols); - - // Compress the data if neccessary - int tcol = 0; // counter of not all NULL and written columns - uint32_t toffset = 0; - int32_t tsize = TSDB_BLOCK_STATIS_SIZE(nColsNotAllNull); - int32_t lsize = tsize; - int32_t keyLen = 0; - for (int ncol = 0; ncol < pDataCols->numOfCols; ncol++) { - // All not NULL columns finish - if (ncol != 0 && tcol >= nColsNotAllNull) break; - - SDataCol * pDataCol = pDataCols->cols + ncol; - SBlockCol *pBlockCol = pBlockData->cols + tcol; - - if (ncol != 0 && (pDataCol->colId != pBlockCol->colId)) continue; - - int32_t flen; // final length - int32_t tlen = dataColGetNEleLen(pDataCol, rowsToWrite); - void * tptr; - - // Make room - if (tsdbMakeRoom(ppBuf, lsize + tlen + COMP_OVERFLOW_BYTES + sizeof(TSCKSUM)) < 0) { - return -1; - } - pBlockData = (SBlockData *)(*ppBuf); - pBlockCol = pBlockData->cols + tcol; - tptr = POINTER_SHIFT(pBlockData, lsize); - - if (pCfg->compression == TWO_STAGE_COMP && - tsdbMakeRoom(ppCBuf, tlen + COMP_OVERFLOW_BYTES) < 0) { - return -1; - } - - // Compress or just copy - if (pCfg->compression) { - flen = (*(tDataTypes[pDataCol->type].compFunc))((char *)pDataCol->pData, tlen, rowsToWrite, tptr, - tlen + COMP_OVERFLOW_BYTES, pCfg->compression, *ppCBuf, - tlen + COMP_OVERFLOW_BYTES); - } else { - flen = tlen; - memcpy(tptr, pDataCol->pData, flen); - } - - // Add checksum - ASSERT(flen > 0); - flen += sizeof(TSCKSUM); - taosCalcChecksumAppend(0, (uint8_t *)tptr, flen); - tsdbUpdateDFileMagic(pDFile, POINTER_SHIFT(tptr, flen - sizeof(TSCKSUM))); - - if (ncol != 0) { - tsdbSetBlockColOffset(pBlockCol, toffset); - pBlockCol->len = flen; - tcol++; - } else { - keyLen = flen; - } - - toffset += flen; - lsize += flen; - } - - pBlockData->delimiter = TSDB_FILE_DELIMITER; - pBlockData->uid = TABLE_UID(pTable); - pBlockData->numOfCols = nColsNotAllNull; - - taosCalcChecksumAppend(0, (uint8_t *)pBlockData, tsize); - tsdbUpdateDFileMagic(pDFile, POINTER_SHIFT(pBlockData, tsize - sizeof(TSCKSUM))); - - // Write the whole block to file - if (tsdbAppendDFile(pDFile, (void *)pBlockData, lsize, &offset) < lsize) { - return -1; - } - - // Update pBlock membership vairables - pBlock->last = isLast; - pBlock->offset = offset; - pBlock->algorithm = pCfg->compression; - pBlock->numOfRows = rowsToWrite; - pBlock->len = lsize; - pBlock->keyLen = keyLen; - pBlock->numOfSubBlocks = isSuper ? 1 : 0; - pBlock->numOfCols = nColsNotAllNull; - pBlock->keyFirst = dataColsKeyFirst(pDataCols); - pBlock->keyLast = dataColsKeyLast(pDataCols); - - tsdbDebug("vgId:%d tid:%d a block of data is written to file %s, offset %" PRId64 - " numOfRows %d len %d numOfCols %" PRId16 " keyFirst %" PRId64 " keyLast %" PRId64, - REPO_ID(pRepo), TABLE_TID(pTable), TSDB_FILE_FULL_NAME(pDFile), offset, rowsToWrite, pBlock->len, - pBlock->numOfCols, pBlock->keyFirst, pBlock->keyLast); - - return 0; -} - -static int tsdbWriteBlock(SCommitH *pCommith, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, bool isLast, - bool isSuper) { - return tsdbWriteBlockImpl(TSDB_COMMIT_REPO(pCommith), TSDB_COMMIT_TABLE(pCommith), pDFile, pDataCols, pBlock, isLast, - isSuper, (void **)(&(TSDB_COMMIT_BUF(pCommith))), - (void **)(&(TSDB_COMMIT_COMP_BUF(pCommith)))); -} - - -static int tsdbWriteBlockInfo(SCommitH *pCommih) { - SDFile * pHeadf = TSDB_COMMIT_HEAD_FILE(pCommih); - SBlockIdx blkIdx; - STable * pTable = TSDB_COMMIT_TABLE(pCommih); - - if (tsdbWriteBlockInfoImpl(pHeadf, pTable, pCommih->aSupBlk, pCommih->aSubBlk, (void **)(&(TSDB_COMMIT_BUF(pCommih))), - &blkIdx) < 0) { - return -1; - } - - if (blkIdx.numOfBlocks == 0) { - return 0; - } - - if (taosArrayPush(pCommih->aBlkIdx, (void *)(&blkIdx)) == NULL) { + // Loop to create iters for each skiplist + pSlIter = tSkipListCreateIter(pMem->pSlIdx); + if (pSlIter == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; return -1; } + for (int i = 0; i < pCommith->niters; i++) { + tSkipListIterNext(pSlIter); + pNode = tSkipListIterGet(pSlIter); + pTbData = (STbData *)pNode->pData; - return 0; -} + pCommitIter = pCommith->iters + i; + pCommitIter->pIter = tSkipListCreateIter(pTbData->pData); + tSkipListIterNext(pCommitIter->pIter); -static int tsdbCommitMemData(SCommitH *pCommith, SCommitIter *pIter, TSKEY keyLimit, bool toData) { - STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith); - STsdbCfg * pCfg = REPO_CFG(pRepo); - SMergeInfo mInfo; - int32_t defaultRows = TSDB_COMMIT_DEFAULT_ROWS(pCommith); - SDFile * pDFile; - bool isLast; - SBlock block; - - while (true) { - tsdbLoadDataFromCache(pIter->pTable, pIter->pIter, keyLimit, defaultRows, pCommith->pDataCols, NULL, 0, - pCfg->update, &mInfo); - - if (pCommith->pDataCols->numOfRows <= 0) break; - - if (toData || pCommith->pDataCols->numOfRows >= pCfg->minRowsPerFileBlock) { - pDFile = TSDB_COMMIT_DATA_FILE(pCommith); - isLast = false; - } else { - pDFile = TSDB_COMMIT_LAST_FILE(pCommith); - isLast = true; - } - - if (tsdbWriteBlock(pCommith, pDFile, pCommith->pDataCols, &block, isLast, true) < 0) return -1; - - if (tsdbCommitAddBlock(pCommith, &block, NULL, 0) < 0) { - return -1; - } + pCommitIter->pTable = (STable *)malloc(sizeof(STable)); + pCommitIter->pTable->uid = pTbData->uid; + pCommitIter->pTable->tid = pTbData->uid; + pCommitIter->pTable->pSchema = metaGetTbTSchema(pRepo->pMeta, pTbData->uid, 0); } return 0; } -static int tsdbMergeMemData(SCommitH *pCommith, SCommitIter *pIter, int bidx) { - STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith); - STsdbCfg * pCfg = REPO_CFG(pRepo); - int nBlocks = pCommith->readh.pBlkIdx->numOfBlocks; - SBlock * pBlock = pCommith->readh.pBlkInfo->blocks + bidx; - TSKEY keyLimit; - int16_t colId = 0; - SMergeInfo mInfo; - SBlock subBlocks[TSDB_MAX_SUBBLOCKS]; - SBlock block, supBlock; - SDFile * pDFile; +static void tsdbDestroyCommitIters(SCommitH *pCommith) { + if (pCommith->iters == NULL) return; - if (bidx == nBlocks - 1) { - keyLimit = pCommith->maxKey; - } else { - keyLimit = pBlock[1].keyFirst - 1; + for (int i = 1; i < pCommith->niters; i++) { + tSkipListDestroyIter(pCommith->iters[i].pIter); + tdFreeSchema(pCommith->iters[i].pTable->pSchema); + free(pCommith->iters[i].pTable); } - SSkipListIterator titer = *(pIter->pIter); - if (tsdbLoadBlockDataCols(&(pCommith->readh), pBlock, NULL, &colId, 1) < 0) return -1; - - tsdbLoadDataFromCache(pIter->pTable, &titer, keyLimit, INT32_MAX, NULL, pCommith->readh.pDCols[0]->cols[0].pData, - pCommith->readh.pDCols[0]->numOfRows, pCfg->update, &mInfo); - - if (mInfo.nOperations == 0) { - // no new data to insert (all updates denied) - if (tsdbMoveBlock(pCommith, bidx) < 0) { - return -1; - } - *(pIter->pIter) = titer; - } else if (pBlock->numOfRows + mInfo.rowsInserted - mInfo.rowsDeleteSucceed == 0) { - // Ignore the block - ASSERT(0); - *(pIter->pIter) = titer; - } else if (tsdbCanAddSubBlock(pCommith, pBlock, &mInfo)) { - // Add a sub-block - tsdbLoadDataFromCache(pIter->pTable, pIter->pIter, keyLimit, INT32_MAX, pCommith->pDataCols, - pCommith->readh.pDCols[0]->cols[0].pData, pCommith->readh.pDCols[0]->numOfRows, pCfg->update, - &mInfo); - if (pBlock->last) { - pDFile = TSDB_COMMIT_LAST_FILE(pCommith); - } else { - pDFile = TSDB_COMMIT_DATA_FILE(pCommith); - } - - if (tsdbWriteBlock(pCommith, pDFile, pCommith->pDataCols, &block, pBlock->last, false) < 0) return -1; - - if (pBlock->numOfSubBlocks == 1) { - subBlocks[0] = *pBlock; - subBlocks[0].numOfSubBlocks = 0; - } else { - memcpy(subBlocks, POINTER_SHIFT(pCommith->readh.pBlkInfo, pBlock->offset), - sizeof(SBlock) * pBlock->numOfSubBlocks); - } - subBlocks[pBlock->numOfSubBlocks] = block; - supBlock = *pBlock; - supBlock.keyFirst = mInfo.keyFirst; - supBlock.keyLast = mInfo.keyLast; - supBlock.numOfSubBlocks++; - supBlock.numOfRows = pBlock->numOfRows + mInfo.rowsInserted - mInfo.rowsDeleteSucceed; - supBlock.offset = taosArrayGetSize(pCommith->aSubBlk) * sizeof(SBlock); - - if (tsdbCommitAddBlock(pCommith, &supBlock, subBlocks, supBlock.numOfSubBlocks) < 0) return -1; - } else { - if (tsdbLoadBlockData(&(pCommith->readh), pBlock, NULL) < 0) return -1; - if (tsdbMergeBlockData(pCommith, pIter, pCommith->readh.pDCols[0], keyLimit, bidx == (nBlocks - 1)) < 0) return -1; - } - - return 0; -} - -static int tsdbMoveBlock(SCommitH *pCommith, int bidx) { - SBlock *pBlock = pCommith->readh.pBlkInfo->blocks + bidx; - SDFile *pDFile; - SBlock block; - bool isSameFile; - - ASSERT(pBlock->numOfSubBlocks > 0); - - if (pBlock->last) { - pDFile = TSDB_COMMIT_LAST_FILE(pCommith); - isSameFile = pCommith->isLFileSame; - } else { - pDFile = TSDB_COMMIT_DATA_FILE(pCommith); - isSameFile = pCommith->isDFileSame; - } - - if (isSameFile) { - if (pBlock->numOfSubBlocks == 1) { - if (tsdbCommitAddBlock(pCommith, pBlock, NULL, 0) < 0) { - return -1; - } - } else { - block = *pBlock; - block.offset = sizeof(SBlock) * taosArrayGetSize(pCommith->aSubBlk); - - if (tsdbCommitAddBlock(pCommith, &block, POINTER_SHIFT(pCommith->readh.pBlkInfo, pBlock->offset), - pBlock->numOfSubBlocks) < 0) { - return -1; - } - } - } else { - if (tsdbLoadBlockData(&(pCommith->readh), pBlock, NULL) < 0) return -1; - if (tsdbWriteBlock(pCommith, pDFile, pCommith->readh.pDCols[0], &block, pBlock->last, true) < 0) return -1; - if (tsdbCommitAddBlock(pCommith, &block, NULL, 0) < 0) return -1; - } - - return 0; -} - -static int tsdbCommitAddBlock(SCommitH *pCommith, const SBlock *pSupBlock, const SBlock *pSubBlocks, int nSubBlocks) { - if (taosArrayPush(pCommith->aSupBlk, pSupBlock) == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } - - if (pSubBlocks && taosArrayAddBatch(pCommith->aSubBlk, pSubBlocks, nSubBlocks) == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } - - return 0; -} - -static int tsdbMergeBlockData(SCommitH *pCommith, SCommitIter *pIter, SDataCols *pDataCols, TSKEY keyLimit, bool isLastOneBlock) { - STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith); - STsdbCfg * pCfg = REPO_CFG(pRepo); - SBlock block; - SDFile * pDFile; - bool isLast; - int32_t defaultRows = TSDB_COMMIT_DEFAULT_ROWS(pCommith); - - int biter = 0; - while (true) { - tsdbLoadAndMergeFromCache(pCommith->readh.pDCols[0], &biter, pIter, pCommith->pDataCols, keyLimit, defaultRows, - pCfg->update); - - if (pCommith->pDataCols->numOfRows == 0) break; - - if (isLastOneBlock) { - if (pCommith->pDataCols->numOfRows < pCfg->minRowsPerFileBlock) { - pDFile = TSDB_COMMIT_LAST_FILE(pCommith); - isLast = true; - } else { - pDFile = TSDB_COMMIT_DATA_FILE(pCommith); - isLast = false; - } - } else { - pDFile = TSDB_COMMIT_DATA_FILE(pCommith); - isLast = false; - } - - if (tsdbWriteBlock(pCommith, pDFile, pCommith->pDataCols, &block, isLast, true) < 0) return -1; - if (tsdbCommitAddBlock(pCommith, &block, NULL, 0) < 0) return -1; - } - - return 0; -} - -static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIter *pCommitIter, SDataCols *pTarget, - TSKEY maxKey, int maxRows, int8_t update) { - TSKEY key1 = INT64_MAX; - TSKEY key2 = INT64_MAX; - STSchema *pSchema = NULL; - - ASSERT(maxRows > 0 && dataColsKeyLast(pDataCols) <= maxKey); - tdResetDataCols(pTarget); - - while (true) { - key1 = (*iter >= pDataCols->numOfRows) ? INT64_MAX : dataColsKeyAt(pDataCols, *iter); - SMemRow row = tsdbNextIterRow(pCommitIter->pIter); - if (row == NULL || memRowKey(row) > maxKey) { - key2 = INT64_MAX; - } else { - key2 = memRowKey(row); - } - - if (key1 == INT64_MAX && key2 == INT64_MAX) break; - - if (key1 < key2) { - for (int i = 0; i < pDataCols->numOfCols; i++) { - //TODO: dataColAppendVal may fail - dataColAppendVal(pTarget->cols + i, tdGetColDataOfRow(pDataCols->cols + i, *iter), pTarget->numOfRows, - pTarget->maxPoints); - } - - pTarget->numOfRows++; - (*iter)++; - } else if (key1 > key2) { - if (pSchema == NULL || schemaVersion(pSchema) != memRowVersion(row)) { - pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, memRowVersion(row)); - ASSERT(pSchema != NULL); - } - - tdAppendMemRowToDataCol(row, pSchema, pTarget, true); - - tSkipListIterNext(pCommitIter->pIter); - } else { - if (update != TD_ROW_OVERWRITE_UPDATE) { - //copy disk data - for (int i = 0; i < pDataCols->numOfCols; i++) { - //TODO: dataColAppendVal may fail - dataColAppendVal(pTarget->cols + i, tdGetColDataOfRow(pDataCols->cols + i, *iter), pTarget->numOfRows, - pTarget->maxPoints); - } - - if(update == TD_ROW_DISCARD_UPDATE) pTarget->numOfRows++; - } - if (update != TD_ROW_DISCARD_UPDATE) { - //copy mem data - if (pSchema == NULL || schemaVersion(pSchema) != memRowVersion(row)) { - pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, memRowVersion(row)); - ASSERT(pSchema != NULL); - } - - tdAppendMemRowToDataCol(row, pSchema, pTarget, update == TD_ROW_OVERWRITE_UPDATE); - } - (*iter)++; - tSkipListIterNext(pCommitIter->pIter); - } - - if (pTarget->numOfRows >= maxRows) break; - } + free(pCommith->iters); + pCommith->iters = NULL; + pCommith->niters = 0; } static void tsdbResetCommitFile(SCommitH *pCommith) { @@ -1515,15 +451,9 @@ static void tsdbResetCommitFile(SCommitH *pCommith) { taosArrayClear(pCommith->aBlkIdx); } -static void tsdbResetCommitTable(SCommitH *pCommith) { - taosArrayClear(pCommith->aSubBlk); - taosArrayClear(pCommith->aSupBlk); - pCommith->pTable = NULL; -} - static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid) { SDiskID did; - STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith); + STsdb * pRepo = TSDB_COMMIT_REPO(pCommith); SDFileSet *pWSet = TSDB_COMMIT_WRITE_FSET(pCommith); tfsAllocDisk(tsdbGetFidLevel(fid, &(pCommith->rtn)), &(did.level), &(did.id)); @@ -1646,6 +576,985 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid return 0; } +// extern int32_t tsTsdbMetaCompactRatio; + +int tsdbWriteBlockInfoImpl(SDFile *pHeadf, STable *pTable, SArray *pSupA, SArray *pSubA, void **ppBuf, + SBlockIdx *pIdx) { + size_t nSupBlocks; + size_t nSubBlocks; + uint32_t tlen; + SBlockInfo *pBlkInfo; + int64_t offset; + SBlock * pBlock; + + memset(pIdx, 0, sizeof(*pIdx)); + + nSupBlocks = taosArrayGetSize(pSupA); + nSubBlocks = (pSubA == NULL) ? 0 : taosArrayGetSize(pSubA); + + if (nSupBlocks <= 0) { + // No data (data all deleted) + return 0; + } + + tlen = (uint32_t)(sizeof(SBlockInfo) + sizeof(SBlock) * (nSupBlocks + nSubBlocks) + sizeof(TSCKSUM)); + if (tsdbMakeRoom(ppBuf, tlen) < 0) return -1; + pBlkInfo = *ppBuf; + + pBlkInfo->delimiter = TSDB_FILE_DELIMITER; + pBlkInfo->tid = TABLE_TID(pTable); + pBlkInfo->uid = TABLE_UID(pTable); + + memcpy((void *)(pBlkInfo->blocks), taosArrayGet(pSupA, 0), nSupBlocks * sizeof(SBlock)); + if (nSubBlocks > 0) { + memcpy((void *)(pBlkInfo->blocks + nSupBlocks), taosArrayGet(pSubA, 0), nSubBlocks * sizeof(SBlock)); + + for (int i = 0; i < nSupBlocks; i++) { + pBlock = pBlkInfo->blocks + i; + + if (pBlock->numOfSubBlocks > 1) { + pBlock->offset += (sizeof(SBlockInfo) + sizeof(SBlock) * nSupBlocks); + } + } + } + + taosCalcChecksumAppend(0, (uint8_t *)pBlkInfo, tlen); + + if (tsdbAppendDFile(pHeadf, (void *)pBlkInfo, tlen, &offset) < 0) { + return -1; + } + + tsdbUpdateDFileMagic(pHeadf, POINTER_SHIFT(pBlkInfo, tlen - sizeof(TSCKSUM))); + + // Set pIdx + pBlock = taosArrayGetLast(pSupA); + + pIdx->tid = TABLE_TID(pTable); + pIdx->uid = TABLE_UID(pTable); + pIdx->hasLast = pBlock->last ? 1 : 0; + pIdx->maxKey = pBlock->keyLast; + pIdx->numOfBlocks = (uint32_t)nSupBlocks; + pIdx->len = tlen; + pIdx->offset = (uint32_t)offset; + + return 0; +} + +int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf) { + SBlockIdx *pBlkIdx; + size_t nidx = taosArrayGetSize(pIdxA); + int tlen = 0, size; + int64_t offset; + + if (nidx <= 0) { + // All data are deleted + pHeadf->info.offset = 0; + pHeadf->info.len = 0; + return 0; + } + + for (size_t i = 0; i < nidx; i++) { + pBlkIdx = (SBlockIdx *)taosArrayGet(pIdxA, i); + + size = tsdbEncodeSBlockIdx(NULL, pBlkIdx); + if (tsdbMakeRoom(ppBuf, tlen + size) < 0) return -1; + + void *ptr = POINTER_SHIFT(*ppBuf, tlen); + tsdbEncodeSBlockIdx(&ptr, pBlkIdx); + + tlen += size; + } + + tlen += sizeof(TSCKSUM); + if (tsdbMakeRoom(ppBuf, tlen) < 0) return -1; + taosCalcChecksumAppend(0, (uint8_t *)(*ppBuf), tlen); + + if (tsdbAppendDFile(pHeadf, *ppBuf, tlen, &offset) < tlen) { + return -1; + } + + tsdbUpdateDFileMagic(pHeadf, POINTER_SHIFT(*ppBuf, tlen - sizeof(TSCKSUM))); + pHeadf->info.offset = (uint32_t)offset; + pHeadf->info.len = tlen; + + 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 = malloc((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 = realloc(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 +// remove(mf.f.aname); +// taosHashCleanup(pfs->metaCacheComp); +// pfs->metaCacheComp = NULL; +// } + +// tfree(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 + +static int tsdbCommitToTable(SCommitH *pCommith, int tid) { + SCommitIter *pIter = pCommith->iters + tid; + TSKEY nextKey = tsdbNextIterKey(pIter->pIter); + + tsdbResetCommitTable(pCommith); + + // Set commit table + if (tsdbSetCommitTable(pCommith, pIter->pTable) < 0) { + return -1; + } + + // No disk data and no memory data, just return + if (pCommith->readh.pBlkIdx == NULL && (nextKey == TSDB_DATA_TIMESTAMP_NULL || nextKey > pCommith->maxKey)) { + return 0; + } + + // Must has disk data or has memory data + int nBlocks; + int bidx = 0; + SBlock *pBlock; + + if (pCommith->readh.pBlkIdx) { + if (tsdbLoadBlockInfo(&(pCommith->readh), NULL) < 0) { + return -1; + } + + nBlocks = pCommith->readh.pBlkIdx->numOfBlocks; + } else { + nBlocks = 0; + } + + if (bidx < nBlocks) { + pBlock = pCommith->readh.pBlkInfo->blocks + bidx; + } else { + pBlock = NULL; + } + + while (true) { + if (pBlock == NULL && (nextKey == TSDB_DATA_TIMESTAMP_NULL || nextKey > pCommith->maxKey)) break; + + if ((nextKey == TSDB_DATA_TIMESTAMP_NULL || nextKey > pCommith->maxKey) || + (pBlock && (!pBlock->last) && tsdbComparKeyBlock((void *)(&nextKey), pBlock) > 0)) { + if (tsdbMoveBlock(pCommith, bidx) < 0) { + return -1; + } + + bidx++; + if (bidx < nBlocks) { + pBlock = pCommith->readh.pBlkInfo->blocks + bidx; + } else { + pBlock = NULL; + } + } else if (pBlock && (pBlock->last || tsdbComparKeyBlock((void *)(&nextKey), pBlock) == 0)) { + // merge pBlock data and memory data + if (tsdbMergeMemData(pCommith, pIter, bidx) < 0) { + return -1; + } + + bidx++; + if (bidx < nBlocks) { + pBlock = pCommith->readh.pBlkInfo->blocks + bidx; + } else { + pBlock = NULL; + } + nextKey = tsdbNextIterKey(pIter->pIter); + } else { + // Only commit memory data + if (pBlock == NULL) { + if (tsdbCommitMemData(pCommith, pIter, pCommith->maxKey, false) < 0) { + return -1; + } + } else { + if (tsdbCommitMemData(pCommith, pIter, pBlock->keyFirst - 1, true) < 0) { + return -1; + } + } + nextKey = tsdbNextIterKey(pIter->pIter); + } + } + + if (tsdbWriteBlockInfo(pCommith) < 0) { + tsdbError("vgId:%d failed to write SBlockInfo part into file %s since %s", TSDB_COMMIT_REPO_ID(pCommith), + TSDB_FILE_FULL_NAME(TSDB_COMMIT_HEAD_FILE(pCommith)), tstrerror(terrno)); + return -1; + } + + return 0; +} + +static int tsdbSetCommitTable(SCommitH *pCommith, STable *pTable) { + STSchema *pSchema = tsdbGetTableSchemaImpl(pTable, false, false, -1); + + pCommith->pTable = pTable; + + if (tdInitDataCols(pCommith->pDataCols, pSchema) < 0) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + return -1; + } + + if (pCommith->isRFileSet) { + if (tsdbSetReadTable(&(pCommith->readh), pTable) < 0) { + return -1; + } + } else { + pCommith->readh.pBlkIdx = NULL; + } + return 0; +} + +static int tsdbComparKeyBlock(const void *arg1, const void *arg2) { + TSKEY key = *(TSKEY *)arg1; + SBlock *pBlock = (SBlock *)arg2; + + if (key < pBlock->keyFirst) { + return -1; + } else if (key > pBlock->keyLast) { + return 1; + } else { + return 0; + } +} + +int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, bool isLast, + bool isSuper, void **ppBuf, void **ppCBuf) { + STsdbCfg * pCfg = REPO_CFG(pRepo); + SBlockData *pBlockData; + int64_t offset = 0; + int rowsToWrite = pDataCols->numOfRows; + + ASSERT(rowsToWrite > 0 && rowsToWrite <= pCfg->maxRowsPerFileBlock); + ASSERT((!isLast) || rowsToWrite < pCfg->minRowsPerFileBlock); + + // Make buffer space + if (tsdbMakeRoom(ppBuf, TSDB_BLOCK_STATIS_SIZE(pDataCols->numOfCols)) < 0) { + return -1; + } + pBlockData = (SBlockData *)(*ppBuf); + + // Get # of cols not all NULL(not including key column) + int nColsNotAllNull = 0; + for (int ncol = 1; ncol < pDataCols->numOfCols; ncol++) { // ncol from 1, we skip the timestamp column + SDataCol * pDataCol = pDataCols->cols + ncol; + SBlockCol *pBlockCol = pBlockData->cols + nColsNotAllNull; + + if (isAllRowsNull(pDataCol)) { // all data to commit are NULL, just ignore it + continue; + } + + memset(pBlockCol, 0, sizeof(*pBlockCol)); + + pBlockCol->colId = pDataCol->colId; + pBlockCol->type = pDataCol->type; + if (tDataTypes[pDataCol->type].statisFunc) { + (*tDataTypes[pDataCol->type].statisFunc)(pDataCol->pData, rowsToWrite, &(pBlockCol->min), &(pBlockCol->max), + &(pBlockCol->sum), &(pBlockCol->minIndex), &(pBlockCol->maxIndex), + &(pBlockCol->numOfNull)); + } + nColsNotAllNull++; + } + + ASSERT(nColsNotAllNull >= 0 && nColsNotAllNull <= pDataCols->numOfCols); + + // Compress the data if neccessary + int tcol = 0; // counter of not all NULL and written columns + uint32_t toffset = 0; + int32_t tsize = TSDB_BLOCK_STATIS_SIZE(nColsNotAllNull); + int32_t lsize = tsize; + int32_t keyLen = 0; + for (int ncol = 0; ncol < pDataCols->numOfCols; ncol++) { + // All not NULL columns finish + if (ncol != 0 && tcol >= nColsNotAllNull) break; + + SDataCol * pDataCol = pDataCols->cols + ncol; + SBlockCol *pBlockCol = pBlockData->cols + tcol; + + if (ncol != 0 && (pDataCol->colId != pBlockCol->colId)) continue; + + int32_t flen; // final length + int32_t tlen = dataColGetNEleLen(pDataCol, rowsToWrite); + void * tptr; + + // Make room + if (tsdbMakeRoom(ppBuf, lsize + tlen + COMP_OVERFLOW_BYTES + sizeof(TSCKSUM)) < 0) { + return -1; + } + pBlockData = (SBlockData *)(*ppBuf); + pBlockCol = pBlockData->cols + tcol; + tptr = POINTER_SHIFT(pBlockData, lsize); + + if (pCfg->compression == TWO_STAGE_COMP && tsdbMakeRoom(ppCBuf, tlen + COMP_OVERFLOW_BYTES) < 0) { + return -1; + } + + // Compress or just copy + if (pCfg->compression) { + flen = (*(tDataTypes[pDataCol->type].compFunc))((char *)pDataCol->pData, tlen, rowsToWrite, tptr, + tlen + COMP_OVERFLOW_BYTES, pCfg->compression, *ppCBuf, + tlen + COMP_OVERFLOW_BYTES); + } else { + flen = tlen; + memcpy(tptr, pDataCol->pData, flen); + } + + // Add checksum + ASSERT(flen > 0); + flen += sizeof(TSCKSUM); + taosCalcChecksumAppend(0, (uint8_t *)tptr, flen); + tsdbUpdateDFileMagic(pDFile, POINTER_SHIFT(tptr, flen - sizeof(TSCKSUM))); + + if (ncol != 0) { + tsdbSetBlockColOffset(pBlockCol, toffset); + pBlockCol->len = flen; + tcol++; + } else { + keyLen = flen; + } + + toffset += flen; + lsize += flen; + } + + pBlockData->delimiter = TSDB_FILE_DELIMITER; + pBlockData->uid = TABLE_UID(pTable); + pBlockData->numOfCols = nColsNotAllNull; + + taosCalcChecksumAppend(0, (uint8_t *)pBlockData, tsize); + tsdbUpdateDFileMagic(pDFile, POINTER_SHIFT(pBlockData, tsize - sizeof(TSCKSUM))); + + // Write the whole block to file + if (tsdbAppendDFile(pDFile, (void *)pBlockData, lsize, &offset) < lsize) { + return -1; + } + + // Update pBlock membership vairables + pBlock->last = isLast; + pBlock->offset = offset; + pBlock->algorithm = pCfg->compression; + pBlock->numOfRows = rowsToWrite; + pBlock->len = lsize; + pBlock->keyLen = keyLen; + pBlock->numOfSubBlocks = isSuper ? 1 : 0; + pBlock->numOfCols = nColsNotAllNull; + pBlock->keyFirst = dataColsKeyFirst(pDataCols); + pBlock->keyLast = dataColsKeyLast(pDataCols); + + tsdbDebug("vgId:%d tid:%d a block of data is written to file %s, offset %" PRId64 + " numOfRows %d len %d numOfCols %" PRId16 " keyFirst %" PRId64 " keyLast %" PRId64, + REPO_ID(pRepo), TABLE_TID(pTable), TSDB_FILE_FULL_NAME(pDFile), offset, rowsToWrite, pBlock->len, + pBlock->numOfCols, pBlock->keyFirst, pBlock->keyLast); + + return 0; +} + +static int tsdbWriteBlock(SCommitH *pCommith, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, bool isLast, + bool isSuper) { + return tsdbWriteBlockImpl(TSDB_COMMIT_REPO(pCommith), TSDB_COMMIT_TABLE(pCommith), pDFile, pDataCols, pBlock, isLast, + isSuper, (void **)(&(TSDB_COMMIT_BUF(pCommith))), + (void **)(&(TSDB_COMMIT_COMP_BUF(pCommith)))); +} + +static int tsdbWriteBlockInfo(SCommitH *pCommih) { + SDFile * pHeadf = TSDB_COMMIT_HEAD_FILE(pCommih); + SBlockIdx blkIdx; + STable * pTable = TSDB_COMMIT_TABLE(pCommih); + + if (tsdbWriteBlockInfoImpl(pHeadf, pTable, pCommih->aSupBlk, pCommih->aSubBlk, (void **)(&(TSDB_COMMIT_BUF(pCommih))), + &blkIdx) < 0) { + return -1; + } + + if (blkIdx.numOfBlocks == 0) { + return 0; + } + + if (taosArrayPush(pCommih->aBlkIdx, (void *)(&blkIdx)) == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + return -1; + } + + return 0; +} + +static int tsdbCommitMemData(SCommitH *pCommith, SCommitIter *pIter, TSKEY keyLimit, bool toData) { + STsdb * pRepo = TSDB_COMMIT_REPO(pCommith); + STsdbCfg * pCfg = REPO_CFG(pRepo); + SMergeInfo mInfo; + int32_t defaultRows = TSDB_COMMIT_DEFAULT_ROWS(pCommith); + SDFile * pDFile; + bool isLast; + SBlock block; + + while (true) { + tsdbLoadDataFromCache(pIter->pTable, pIter->pIter, keyLimit, defaultRows, pCommith->pDataCols, NULL, 0, + pCfg->update, &mInfo); + + if (pCommith->pDataCols->numOfRows <= 0) break; + + if (toData || pCommith->pDataCols->numOfRows >= pCfg->minRowsPerFileBlock) { + pDFile = TSDB_COMMIT_DATA_FILE(pCommith); + isLast = false; + } else { + pDFile = TSDB_COMMIT_LAST_FILE(pCommith); + isLast = true; + } + + if (tsdbWriteBlock(pCommith, pDFile, pCommith->pDataCols, &block, isLast, true) < 0) return -1; + + if (tsdbCommitAddBlock(pCommith, &block, NULL, 0) < 0) { + return -1; + } + } + + return 0; +} + +static int tsdbMergeMemData(SCommitH *pCommith, SCommitIter *pIter, int bidx) { + STsdb * pRepo = TSDB_COMMIT_REPO(pCommith); + STsdbCfg * pCfg = REPO_CFG(pRepo); + int nBlocks = pCommith->readh.pBlkIdx->numOfBlocks; + SBlock * pBlock = pCommith->readh.pBlkInfo->blocks + bidx; + TSKEY keyLimit; + int16_t colId = 0; + SMergeInfo mInfo; + SBlock subBlocks[TSDB_MAX_SUBBLOCKS]; + SBlock block, supBlock; + SDFile * pDFile; + + if (bidx == nBlocks - 1) { + keyLimit = pCommith->maxKey; + } else { + keyLimit = pBlock[1].keyFirst - 1; + } + + SSkipListIterator titer = *(pIter->pIter); + if (tsdbLoadBlockDataCols(&(pCommith->readh), pBlock, NULL, &colId, 1) < 0) return -1; + + tsdbLoadDataFromCache(pIter->pTable, &titer, keyLimit, INT32_MAX, NULL, pCommith->readh.pDCols[0]->cols[0].pData, + pCommith->readh.pDCols[0]->numOfRows, pCfg->update, &mInfo); + + if (mInfo.nOperations == 0) { + // no new data to insert (all updates denied) + if (tsdbMoveBlock(pCommith, bidx) < 0) { + return -1; + } + *(pIter->pIter) = titer; + } else if (pBlock->numOfRows + mInfo.rowsInserted - mInfo.rowsDeleteSucceed == 0) { + // Ignore the block + ASSERT(0); + *(pIter->pIter) = titer; + } else if (tsdbCanAddSubBlock(pCommith, pBlock, &mInfo)) { + // Add a sub-block + tsdbLoadDataFromCache(pIter->pTable, pIter->pIter, keyLimit, INT32_MAX, pCommith->pDataCols, + pCommith->readh.pDCols[0]->cols[0].pData, pCommith->readh.pDCols[0]->numOfRows, pCfg->update, + &mInfo); + if (pBlock->last) { + pDFile = TSDB_COMMIT_LAST_FILE(pCommith); + } else { + pDFile = TSDB_COMMIT_DATA_FILE(pCommith); + } + + if (tsdbWriteBlock(pCommith, pDFile, pCommith->pDataCols, &block, pBlock->last, false) < 0) return -1; + + if (pBlock->numOfSubBlocks == 1) { + subBlocks[0] = *pBlock; + subBlocks[0].numOfSubBlocks = 0; + } else { + memcpy(subBlocks, POINTER_SHIFT(pCommith->readh.pBlkInfo, pBlock->offset), + sizeof(SBlock) * pBlock->numOfSubBlocks); + } + subBlocks[pBlock->numOfSubBlocks] = block; + supBlock = *pBlock; + supBlock.keyFirst = mInfo.keyFirst; + supBlock.keyLast = mInfo.keyLast; + supBlock.numOfSubBlocks++; + supBlock.numOfRows = pBlock->numOfRows + mInfo.rowsInserted - mInfo.rowsDeleteSucceed; + supBlock.offset = taosArrayGetSize(pCommith->aSubBlk) * sizeof(SBlock); + + if (tsdbCommitAddBlock(pCommith, &supBlock, subBlocks, supBlock.numOfSubBlocks) < 0) return -1; + } else { + if (tsdbLoadBlockData(&(pCommith->readh), pBlock, NULL) < 0) return -1; + if (tsdbMergeBlockData(pCommith, pIter, pCommith->readh.pDCols[0], keyLimit, bidx == (nBlocks - 1)) < 0) return -1; + } + + return 0; +} + +static int tsdbMoveBlock(SCommitH *pCommith, int bidx) { + SBlock *pBlock = pCommith->readh.pBlkInfo->blocks + bidx; + SDFile *pDFile; + SBlock block; + bool isSameFile; + + ASSERT(pBlock->numOfSubBlocks > 0); + + if (pBlock->last) { + pDFile = TSDB_COMMIT_LAST_FILE(pCommith); + isSameFile = pCommith->isLFileSame; + } else { + pDFile = TSDB_COMMIT_DATA_FILE(pCommith); + isSameFile = pCommith->isDFileSame; + } + + if (isSameFile) { + if (pBlock->numOfSubBlocks == 1) { + if (tsdbCommitAddBlock(pCommith, pBlock, NULL, 0) < 0) { + return -1; + } + } else { + block = *pBlock; + block.offset = sizeof(SBlock) * taosArrayGetSize(pCommith->aSubBlk); + + if (tsdbCommitAddBlock(pCommith, &block, POINTER_SHIFT(pCommith->readh.pBlkInfo, pBlock->offset), + pBlock->numOfSubBlocks) < 0) { + return -1; + } + } + } else { + if (tsdbLoadBlockData(&(pCommith->readh), pBlock, NULL) < 0) return -1; + if (tsdbWriteBlock(pCommith, pDFile, pCommith->readh.pDCols[0], &block, pBlock->last, true) < 0) return -1; + if (tsdbCommitAddBlock(pCommith, &block, NULL, 0) < 0) return -1; + } + + return 0; +} + +static int tsdbCommitAddBlock(SCommitH *pCommith, const SBlock *pSupBlock, const SBlock *pSubBlocks, int nSubBlocks) { + if (taosArrayPush(pCommith->aSupBlk, pSupBlock) == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + return -1; + } + + if (pSubBlocks && taosArrayAddBatch(pCommith->aSubBlk, pSubBlocks, nSubBlocks) == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + return -1; + } + + return 0; +} + +static int tsdbMergeBlockData(SCommitH *pCommith, SCommitIter *pIter, SDataCols *pDataCols, TSKEY keyLimit, + bool isLastOneBlock) { + STsdb * pRepo = TSDB_COMMIT_REPO(pCommith); + STsdbCfg *pCfg = REPO_CFG(pRepo); + SBlock block; + SDFile * pDFile; + bool isLast; + int32_t defaultRows = TSDB_COMMIT_DEFAULT_ROWS(pCommith); + + int biter = 0; + while (true) { + tsdbLoadAndMergeFromCache(pCommith->readh.pDCols[0], &biter, pIter, pCommith->pDataCols, keyLimit, defaultRows, + pCfg->update); + + if (pCommith->pDataCols->numOfRows == 0) break; + + if (isLastOneBlock) { + if (pCommith->pDataCols->numOfRows < pCfg->minRowsPerFileBlock) { + pDFile = TSDB_COMMIT_LAST_FILE(pCommith); + isLast = true; + } else { + pDFile = TSDB_COMMIT_DATA_FILE(pCommith); + isLast = false; + } + } else { + pDFile = TSDB_COMMIT_DATA_FILE(pCommith); + isLast = false; + } + + if (tsdbWriteBlock(pCommith, pDFile, pCommith->pDataCols, &block, isLast, true) < 0) return -1; + if (tsdbCommitAddBlock(pCommith, &block, NULL, 0) < 0) return -1; + } + + return 0; +} + +static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIter *pCommitIter, SDataCols *pTarget, + TSKEY maxKey, int maxRows, int8_t update) { + TSKEY key1 = INT64_MAX; + TSKEY key2 = INT64_MAX; + STSchema *pSchema = NULL; + + ASSERT(maxRows > 0 && dataColsKeyLast(pDataCols) <= maxKey); + tdResetDataCols(pTarget); + + while (true) { + key1 = (*iter >= pDataCols->numOfRows) ? INT64_MAX : dataColsKeyAt(pDataCols, *iter); + SMemRow row = tsdbNextIterRow(pCommitIter->pIter); + if (row == NULL || memRowKey(row) > maxKey) { + key2 = INT64_MAX; + } else { + key2 = memRowKey(row); + } + + if (key1 == INT64_MAX && key2 == INT64_MAX) break; + + if (key1 < key2) { + for (int i = 0; i < pDataCols->numOfCols; i++) { + // TODO: dataColAppendVal may fail + dataColAppendVal(pTarget->cols + i, tdGetColDataOfRow(pDataCols->cols + i, *iter), pTarget->numOfRows, + pTarget->maxPoints); + } + + pTarget->numOfRows++; + (*iter)++; + } else if (key1 > key2) { + if (pSchema == NULL || schemaVersion(pSchema) != memRowVersion(row)) { + pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, memRowVersion(row)); + ASSERT(pSchema != NULL); + } + + tdAppendMemRowToDataCol(row, pSchema, pTarget, true); + + tSkipListIterNext(pCommitIter->pIter); + } else { + if (update != TD_ROW_OVERWRITE_UPDATE) { + // copy disk data + for (int i = 0; i < pDataCols->numOfCols; i++) { + // TODO: dataColAppendVal may fail + dataColAppendVal(pTarget->cols + i, tdGetColDataOfRow(pDataCols->cols + i, *iter), pTarget->numOfRows, + pTarget->maxPoints); + } + + if (update == TD_ROW_DISCARD_UPDATE) pTarget->numOfRows++; + } + if (update != TD_ROW_DISCARD_UPDATE) { + // copy mem data + if (pSchema == NULL || schemaVersion(pSchema) != memRowVersion(row)) { + pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, memRowVersion(row)); + ASSERT(pSchema != NULL); + } + + tdAppendMemRowToDataCol(row, pSchema, pTarget, update == TD_ROW_OVERWRITE_UPDATE); + } + (*iter)++; + tSkipListIterNext(pCommitIter->pIter); + } + + if (pTarget->numOfRows >= maxRows) break; + } +} + +static void tsdbResetCommitTable(SCommitH *pCommith) { + taosArrayClear(pCommith->aSubBlk); + taosArrayClear(pCommith->aSupBlk); + pCommith->pTable = NULL; +} + static void tsdbCloseCommitFile(SCommitH *pCommith, bool hasError) { if (pCommith->isRFileSet) { tsdbCloseAndUnsetFSet(&(pCommith->readh)); @@ -1658,9 +1567,9 @@ static void tsdbCloseCommitFile(SCommitH *pCommith, bool hasError) { } static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *pInfo) { - STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith); - STsdbCfg * pCfg = REPO_CFG(pRepo); - int mergeRows = pBlock->numOfRows + pInfo->rowsInserted - pInfo->rowsDeleteSucceed; + STsdb * pRepo = TSDB_COMMIT_REPO(pCommith); + STsdbCfg *pCfg = REPO_CFG(pRepo); + int mergeRows = pBlock->numOfRows + pInfo->rowsInserted - pInfo->rowsDeleteSucceed; ASSERT(mergeRows > 0); @@ -1675,28 +1584,27 @@ static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *p return false; } -int tsdbApplyRtn(STsdbRepo *pRepo) { - SRtn rtn; - SFSIter fsiter; - STsdbFS * pfs = REPO_FS(pRepo); - SDFileSet *pSet; +// int tsdbApplyRtn(STsdbRepo *pRepo) { +// SRtn rtn; +// SFSIter fsiter; +// STsdbFS * pfs = REPO_FS(pRepo); +// SDFileSet *pSet; - // Get retention snapshot - tsdbGetRtnSnap(pRepo, &rtn); +// // Get retention snapshot +// tsdbGetRtnSnap(pRepo, &rtn); - tsdbFSIterInit(&fsiter, pfs, TSDB_FS_ITER_FORWARD); - while ((pSet = tsdbFSIterNext(&fsiter))) { - if (pSet->fid < rtn.minFid) { - tsdbInfo("vgId:%d FSET %d at level %d disk id %d expires, remove it", REPO_ID(pRepo), pSet->fid, - TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet)); - continue; - } +// tsdbFSIterInit(&fsiter, pfs, TSDB_FS_ITER_FORWARD); +// while ((pSet = tsdbFSIterNext(&fsiter))) { +// if (pSet->fid < rtn.minFid) { +// tsdbInfo("vgId:%d FSET %d at level %d disk id %d expires, remove it", REPO_ID(pRepo), pSet->fid, +// TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet)); +// continue; +// } - if (tsdbApplyRtnOnFSet(pRepo, pSet, &rtn) < 0) { - return -1; - } - } +// if (tsdbApplyRtnOnFSet(pRepo, pSet, &rtn) < 0) { +// return -1; +// } +// } - return 0; -} -#endif \ No newline at end of file +// return 0; +// } \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/src/tsdbCompact.c b/source/dnode/vnode/tsdb/src/tsdbCompact.c index 5ccb9e90f2..d890faea9b 100644 --- a/source/dnode/vnode/tsdb/src/tsdbCompact.c +++ b/source/dnode/vnode/tsdb/src/tsdbCompact.c @@ -12,6 +12,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +#if 0 #include "tsdbint.h" typedef struct { @@ -528,3 +529,5 @@ static int tsdbCompactMeta(STsdbRepo *pRepo) { return 0; } +#endif + diff --git a/source/dnode/vnode/tsdb/src/tsdbFS.c b/source/dnode/vnode/tsdb/src/tsdbFS.c index a40e67ca59..b874da03f4 100644 --- a/source/dnode/vnode/tsdb/src/tsdbFS.c +++ b/source/dnode/vnode/tsdb/src/tsdbFS.c @@ -13,9 +13,9 @@ * along with this program. If not, see . */ -#include "os.h" -#include "tsdbint.h" #include +#include "os.h" +#include "tsdbDef.h" typedef enum { TSDB_TXN_TEMP_FILE = 0, TSDB_TXN_CURR_FILE } TSDB_TXN_FILE_T; static const char *tsdbTxnFname[] = {"current.t", "current"}; @@ -26,16 +26,24 @@ static void tsdbResetFSStatus(SFSStatus *pStatus); static int tsdbSaveFSStatus(SFSStatus *pStatus, int vid); static void tsdbApplyFSTxnOnDisk(SFSStatus *pFrom, SFSStatus *pTo); static void tsdbGetTxnFname(int repoid, TSDB_TXN_FILE_T ftype, char fname[]); -static int tsdbOpenFSFromCurrent(STsdbRepo *pRepo); -static int tsdbScanAndTryFixFS(STsdbRepo *pRepo); -static int tsdbScanRootDir(STsdbRepo *pRepo); -static int tsdbScanDataDir(STsdbRepo *pRepo); +static int tsdbOpenFSFromCurrent(STsdb *pRepo); +static int tsdbScanAndTryFixFS(STsdb *pRepo); +static int tsdbScanRootDir(STsdb *pRepo); +static int tsdbScanDataDir(STsdb *pRepo); static bool tsdbIsTFileInFS(STsdbFS *pfs, const TFILE *pf); -static int tsdbRestoreCurrent(STsdbRepo *pRepo); +static int tsdbRestoreCurrent(STsdb *pRepo); static int tsdbComparTFILE(const void *arg1, const void *arg2); -static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo, int32_t *nExpired); -static int tsdbProcessExpiredFS(STsdbRepo *pRepo); -static int tsdbCreateMeta(STsdbRepo *pRepo); +static void tsdbScanAndTryFixDFilesHeader(STsdb *pRepo, int32_t *nExpired); +// static int tsdbProcessExpiredFS(STsdb *pRepo); +// static int tsdbCreateMeta(STsdb *pRepo); + +static void tsdbGetRootDir(int repoid, char dirName[]) { + snprintf(dirName, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb", repoid); +} + +static void tsdbGetDataDir(int repoid, char dirName[]) { + snprintf(dirName, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/data", repoid); +} // For backward compatibility // ================== CURRENT file header info @@ -104,11 +112,11 @@ static void *tsdbDecodeDFileSetArray(void *buf, SArray *pArray) { } static int tsdbEncodeFSStatus(void **buf, SFSStatus *pStatus) { - ASSERT(pStatus->pmf); + // ASSERT(pStatus->pmf); int tlen = 0; - tlen += tsdbEncodeSMFile(buf, pStatus->pmf); + // tlen += tsdbEncodeSMFile(buf, pStatus->pmf); tlen += tsdbEncodeDFileSetArray(buf, pStatus->df); return tlen; @@ -117,9 +125,9 @@ static int tsdbEncodeFSStatus(void **buf, SFSStatus *pStatus) { static void *tsdbDecodeFSStatus(void *buf, SFSStatus *pStatus) { tsdbResetFSStatus(pStatus); - pStatus->pmf = &(pStatus->mf); + // pStatus->pmf = &(pStatus->mf); - buf = tsdbDecodeSMFile(buf, pStatus->pmf); + // buf = tsdbDecodeSMFile(buf, pStatus->pmf); buf = tsdbDecodeDFileSetArray(buf, pStatus->df); return buf; @@ -132,7 +140,7 @@ static SFSStatus *tsdbNewFSStatus(int maxFSet) { return NULL; } - TSDB_FILE_SET_CLOSED(&(pStatus->mf)); + // TSDB_FILE_SET_CLOSED(&(pStatus->mf)); pStatus->df = taosArrayInit(maxFSet, sizeof(SDFileSet)); if (pStatus->df == NULL) { @@ -158,18 +166,18 @@ static void tsdbResetFSStatus(SFSStatus *pStatus) { return; } - TSDB_FILE_SET_CLOSED(&(pStatus->mf)); + // TSDB_FILE_SET_CLOSED(&(pStatus->mf)); - pStatus->pmf = NULL; + // pStatus->pmf = NULL; taosArrayClear(pStatus->df); } -static void tsdbSetStatusMFile(SFSStatus *pStatus, const SMFile *pMFile) { - ASSERT(pStatus->pmf == NULL); +// static void tsdbSetStatusMFile(SFSStatus *pStatus, const SMFile *pMFile) { +// ASSERT(pStatus->pmf == NULL); - pStatus->pmf = &(pStatus->mf); - tsdbInitMFileEx(pStatus->pmf, (SMFile *)pMFile); -} +// pStatus->pmf = &(pStatus->mf); +// tsdbInitMFileEx(pStatus->pmf, (SMFile *)pMFile); +// } static int tsdbAddDFileSetToStatus(SFSStatus *pStatus, const SDFileSet *pSet) { if (taosArrayPush(pStatus->df, (void *)pSet) == NULL) { @@ -183,7 +191,7 @@ static int tsdbAddDFileSetToStatus(SFSStatus *pStatus, const SDFileSet *pSet) { } // ================== STsdbFS -STsdbFS *tsdbNewFS(STsdbCfg *pCfg) { +STsdbFS *tsdbNewFS(const STsdbCfg *pCfg) { int keep = pCfg->keep; int days = pCfg->daysPerFile; int maxFSet = TSDB_MAX_FSETS(keep, days); @@ -240,63 +248,63 @@ void *tsdbFreeFS(STsdbFS *pfs) { return NULL; } -static int tsdbProcessExpiredFS(STsdbRepo *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; - } +// 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; -} +// 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(STsdbRepo *pRepo) { - STsdbFS *pfs = REPO_FS(pRepo); - SMFile * pOMFile = pfs->cstatus->pmf; - SMFile mf; - SDiskID did; +// 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; - } +// 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))); +// // 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; - } +// 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)); +// 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; - } +// 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); +// TSDB_FILE_FSYNC(&mf); +// tsdbCloseMFile(&mf); +// tsdbUpdateMFile(pfs, &mf); - return 0; -} +// return 0; +// } -int tsdbOpenFS(STsdbRepo *pRepo) { +int tsdbOpenFS(STsdb *pRepo) { STsdbFS *pfs = REPO_FS(pRepo); char current[TSDB_FILENAME_LEN] = "\0"; int nExpired = 0; @@ -313,9 +321,9 @@ int tsdbOpenFS(STsdbRepo *pRepo) { } tsdbScanAndTryFixDFilesHeader(pRepo, &nExpired); - if (nExpired > 0) { - tsdbProcessExpiredFS(pRepo); - } + // if (nExpired > 0) { + // tsdbProcessExpiredFS(pRepo); + // } } else { // should skip expired fileset inside of the function if (tsdbRestoreCurrent(pRepo) < 0) { @@ -329,39 +337,39 @@ int tsdbOpenFS(STsdbRepo *pRepo) { return -1; } - // Load meta cache if has meta file - if ((!(pRepo->state & TSDB_STATE_BAD_META)) && tsdbLoadMetaCache(pRepo, true) < 0) { - tsdbError("vgId:%d failed to open FS while loading meta cache since %s", REPO_ID(pRepo), tstrerror(terrno)); - return -1; - } + // // Load meta cache if has meta file + // if ((!(pRepo->state & TSDB_STATE_BAD_META)) && tsdbLoadMetaCache(pRepo, true) < 0) { + // tsdbError("vgId:%d failed to open FS while loading meta cache since %s", REPO_ID(pRepo), tstrerror(terrno)); + // return -1; + // } return 0; } -void tsdbCloseFS(STsdbRepo *pRepo) { +void tsdbCloseFS(STsdb *pRepo) { // Do nothing } // Start a new transaction to modify the file system -void tsdbStartFSTxn(STsdbRepo *pRepo, int64_t pointsAdd, int64_t storageAdd) { +void tsdbStartFSTxn(STsdb *pRepo, int64_t pointsAdd, int64_t storageAdd) { STsdbFS *pfs = REPO_FS(pRepo); ASSERT(pfs->intxn == false); pfs->intxn = true; tsdbResetFSStatus(pfs->nstatus); pfs->nstatus->meta = pfs->cstatus->meta; - if (pfs->cstatus->pmf == NULL) { - pfs->nstatus->meta.version = 0; - } else { - pfs->nstatus->meta.version = pfs->cstatus->meta.version + 1; - } + // if (pfs->cstatus->pmf == NULL) { + pfs->nstatus->meta.version = 0; + // } else { + // pfs->nstatus->meta.version = pfs->cstatus->meta.version + 1; + // } pfs->nstatus->meta.totalPoints = pfs->cstatus->meta.totalPoints + pointsAdd; pfs->nstatus->meta.totalStorage = pfs->cstatus->meta.totalStorage += storageAdd; } void tsdbUpdateFSTxnMeta(STsdbFS *pfs, STsdbFSMeta *pMeta) { pfs->nstatus->meta = *pMeta; } -int tsdbEndFSTxn(STsdbRepo *pRepo) { +int tsdbEndFSTxn(STsdb *pRepo) { STsdbFS *pfs = REPO_FS(pRepo); ASSERT(FS_IN_TXN(pfs)); SFSStatus *pStatus; @@ -372,7 +380,7 @@ int tsdbEndFSTxn(STsdbRepo *pRepo) { return -1; } - // Make new + // Make new tsdbWLockFS(pfs); pStatus = pfs->cstatus; pfs->cstatus = pfs->nstatus; @@ -393,7 +401,7 @@ int tsdbEndFSTxnWithError(STsdbFS *pfs) { return 0; } -void tsdbUpdateMFile(STsdbFS *pfs, const SMFile *pMFile) { tsdbSetStatusMFile(pfs->nstatus, pMFile); } +// void tsdbUpdateMFile(STsdbFS *pfs, const SMFile *pMFile) { tsdbSetStatusMFile(pfs->nstatus, pMFile); } int tsdbUpdateDFileSet(STsdbFS *pfs, const SDFileSet *pSet) { return tsdbAddDFileSetToStatus(pfs->nstatus, pSet); } @@ -415,8 +423,7 @@ static int tsdbSaveFSStatus(SFSStatus *pStatus, int vid) { } fsheader.version = TSDB_FS_VERSION; - if (pStatus->pmf == NULL) { - ASSERT(taosArrayGetSize(pStatus->df) == 0); + if (taosArrayGetSize(pStatus->df) == 0) { fsheader.len = 0; } else { fsheader.len = tsdbEncodeFSStatus(NULL, pStatus) + sizeof(TSCKSUM); @@ -429,7 +436,7 @@ static int tsdbSaveFSStatus(SFSStatus *pStatus, int vid) { taosCalcChecksumAppend(0, (uint8_t *)hbuf, TSDB_FILE_HEAD_SIZE); - if (taosWrite(fd, hbuf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) { + if (taosWriteFile(fd, hbuf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) { terrno = TAOS_SYSTEM_ERROR(errno); close(fd); remove(tfname); @@ -448,7 +455,7 @@ static int tsdbSaveFSStatus(SFSStatus *pStatus, int vid) { tsdbEncodeFSStatus(&ptr, pStatus); taosCalcChecksumAppend(0, (uint8_t *)pBuf, fsheader.len); - if (taosWrite(fd, pBuf, fsheader.len) < fsheader.len) { + if (taosWriteFile(fd, pBuf, fsheader.len) < fsheader.len) { terrno = TAOS_SYSTEM_ERROR(errno); close(fd); (void)remove(tfname); @@ -458,7 +465,7 @@ static int tsdbSaveFSStatus(SFSStatus *pStatus, int vid) { } // fsync, close and rename - if (taosFsync(fd) < 0) { + if (taosFsyncFile(fd) < 0) { terrno = TAOS_SYSTEM_ERROR(errno); close(fd); remove(tfname); @@ -467,7 +474,7 @@ static int tsdbSaveFSStatus(SFSStatus *pStatus, int vid) { } (void)close(fd); - (void)taosRename(tfname, cfname); + (void)taosRenameFile(tfname, cfname); taosTZfree(pBuf); return 0; @@ -484,7 +491,7 @@ static void tsdbApplyFSTxnOnDisk(SFSStatus *pFrom, SFSStatus *pTo) { sizeTo = taosArrayGetSize(pTo->df); // Apply meta file change - (void)tsdbApplyMFileChange(pFrom->pmf, pTo->pmf); + // (void)tsdbApplyMFileChange(pFrom->pmf, pTo->pmf); // Apply SDFileSet change if (ifrom >= sizeFrom) { @@ -642,7 +649,7 @@ static void tsdbGetTxnFname(int repoid, TSDB_TXN_FILE_T ftype, char fname[]) { snprintf(fname, TSDB_FILENAME_LEN, "%s/vnode/vnode%d/tsdb/%s", TFS_PRIMARY_PATH(), repoid, tsdbTxnFname[ftype]); } -static int tsdbOpenFSFromCurrent(STsdbRepo *pRepo) { +static int tsdbOpenFSFromCurrent(STsdb *pRepo) { STsdbFS * pfs = REPO_FS(pRepo); int fd = -1; void * buffer = NULL; @@ -664,7 +671,7 @@ static int tsdbOpenFSFromCurrent(STsdbRepo *pRepo) { goto _err; } - int nread = (int)taosRead(fd, buffer, TSDB_FILE_HEAD_SIZE); + int nread = (int)taosReadFile(fd, buffer, TSDB_FILE_HEAD_SIZE); if (nread < 0) { tsdbError("vgId:%d failed to read %d bytes from file %s since %s", REPO_ID(pRepo), TSDB_FILENAME_LEN, current, strerror(errno)); @@ -698,7 +705,7 @@ static int tsdbOpenFSFromCurrent(STsdbRepo *pRepo) { goto _err; } - nread = (int)taosRead(fd, buffer, fsheader.len); + nread = (int)taosReadFile(fd, buffer, fsheader.len); if (nread < 0) { tsdbError("vgId:%d failed to read file %s since %s", REPO_ID(pRepo), current, strerror(errno)); terrno = TAOS_SYSTEM_ERROR(errno); @@ -737,14 +744,14 @@ _err: } // Scan and try to fix incorrect files -static int tsdbScanAndTryFixFS(STsdbRepo *pRepo) { +static int tsdbScanAndTryFixFS(STsdb *pRepo) { STsdbFS * pfs = REPO_FS(pRepo); SFSStatus *pStatus = pfs->cstatus; - if (tsdbScanAndTryFixMFile(pRepo) < 0) { - tsdbError("vgId:%d failed to fix MFile since %s", REPO_ID(pRepo), tstrerror(terrno)); - return -1; - } + // if (tsdbScanAndTryFixMFile(pRepo) < 0) { + // tsdbError("vgId:%d failed to fix MFile since %s", REPO_ID(pRepo), tstrerror(terrno)); + // return -1; + // } size_t size = taosArrayGetSize(pStatus->df); @@ -763,143 +770,143 @@ static int tsdbScanAndTryFixFS(STsdbRepo *pRepo) { return 0; } -int tsdbLoadMetaCache(STsdbRepo *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; +// 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); +// taosHashClear(pfs->metaCache); - // No meta file, just return - if (pfs->cstatus->pmf == NULL) return 0; +// // 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; - } +// mf = pfs->cstatus->mf; +// // Load cache first +// if (tsdbOpenMFile(pMFile, O_RDONLY) < 0) { +// return -1; +// } - if (tsdbLoadMFileHeader(pMFile, &minfo) < 0) { - tsdbCloseMFile(pMFile); - 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; +// 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 < 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; - } +// 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); +// 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; - } +// 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 = MAX(maxBufSize, rInfo.size); +// maxBufSize = MAX(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 (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 0 +// pStore->info.size += (sizeof(SKVRecord) + rInfo.size); +// pStore->info.nRecords++; +// #endif +// } +// } - if (recoverMeta) { - pBuf = malloc((size_t)maxBufSize); - if (pBuf == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - tsdbCloseMFile(pMFile); - return -1; - } +// if (recoverMeta) { +// pBuf = malloc((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)); - tfree(pBuf); - 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)); +// tfree(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)); - tfree(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)); +// tfree(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; - tfree(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; +// tfree(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)); - tfree(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)); +// tfree(pBuf); +// tsdbCloseMFile(pMFile); +// return -1; +// } - pRecord = taosHashIterate(pfs->metaCache, pRecord); - } +// pRecord = taosHashIterate(pfs->metaCache, pRecord); +// } - tsdbOrgMeta(pRepo); - } +// tsdbOrgMeta(pRepo); +// } - tsdbCloseMFile(pMFile); - tfree(pBuf); - return 0; -} +// tsdbCloseMFile(pMFile); +// tfree(pBuf); +// return 0; +// } -static int tsdbScanRootDir(STsdbRepo *pRepo) { +static int tsdbScanRootDir(STsdb *pRepo) { char rootDir[TSDB_FILENAME_LEN]; char bname[TSDB_FILENAME_LEN]; STsdbFS * pfs = REPO_FS(pRepo); @@ -920,9 +927,9 @@ static int tsdbScanRootDir(STsdbRepo *pRepo) { continue; } - if (pfs->cstatus->pmf && tfsIsSameFile(pf, &(pfs->cstatus->pmf->f))) { - continue; - } + // if (/*pfs->cstatus->pmf && */ tfsIsSameFile(pf, &(pfs->cstatus->pmf->f))) { + // continue; + // } (void)tfsremove(pf); tsdbDebug("vgId:%d invalid file %s is removed", REPO_ID(pRepo), TFILE_NAME(pf)); @@ -933,7 +940,7 @@ static int tsdbScanRootDir(STsdbRepo *pRepo) { return 0; } -static int tsdbScanDataDir(STsdbRepo *pRepo) { +static int tsdbScanDataDir(STsdb *pRepo) { char dataDir[TSDB_FILENAME_LEN]; char bname[TSDB_FILENAME_LEN]; STsdbFS * pfs = REPO_FS(pRepo); @@ -977,128 +984,128 @@ static bool tsdbIsTFileInFS(STsdbFS *pfs, const TFILE *pf) { return false; } -static int tsdbRestoreMeta(STsdbRepo *pRepo) { - char rootDir[TSDB_FILENAME_LEN]; - char bname[TSDB_FILENAME_LEN]; - TDIR * tdir = NULL; - const TFILE *pf = NULL; - const char * pattern = "^meta(-ver[0-9]+)?$"; - regex_t regex; - STsdbFS * pfs = REPO_FS(pRepo); +// static int tsdbRestoreMeta(STsdb *pRepo) { +// char rootDir[TSDB_FILENAME_LEN]; +// char bname[TSDB_FILENAME_LEN]; +// TDIR * tdir = NULL; +// const TFILE *pf = NULL; +// const char * pattern = "^meta(-ver[0-9]+)?$"; +// regex_t regex; +// STsdbFS * pfs = REPO_FS(pRepo); - regcomp(®ex, pattern, REG_EXTENDED); +// regcomp(®ex, pattern, REG_EXTENDED); - tsdbInfo("vgId:%d try to restore meta", REPO_ID(pRepo)); +// tsdbInfo("vgId:%d try to restore meta", REPO_ID(pRepo)); - tsdbGetRootDir(REPO_ID(pRepo), rootDir); +// 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; - } +// 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); +// while ((pf = tfsReaddir(tdir))) { +// tfsbasename(pf, bname); - if (strcmp(bname, "data") == 0) { - // Skip the data/ directory - continue; - } +// 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), TFILE_NAME(pf)); - (void)tfsremove(pf); - 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), TFILE_NAME(pf)); +// (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), TFILE_NAME(pf)); - 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; - } +// 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), TFILE_NAME(pf)); +// 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); +// 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 (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 (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; +// 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; - } +// // 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); - } - } +// 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), TFILE_NAME(pf)); - 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; - } - } +// tsdbCloseMFile(pfs->cstatus->pmf); +// } +// } else if (code == REG_NOMATCH) { +// // Not match +// tsdbInfo("vgId:%d invalid file %s exists, remove it", REPO_ID(pRepo), TFILE_NAME(pf)); +// 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)); - } +// 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; -} +// tfsClosedir(tdir); +// regfree(®ex); +// return 0; +// } -static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { +static int tsdbRestoreDFileSet(STsdb *pRepo) { char dataDir[TSDB_FILENAME_LEN]; char bname[TSDB_FILENAME_LEN]; TDIR * tdir = NULL; @@ -1220,9 +1227,10 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { } pDFile->f = *pf; - + if (tsdbOpenDFile(pDFile, O_RDONLY) < 0) { - tsdbError("vgId:%d failed to open DFile %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile), tstrerror(terrno)); + tsdbError("vgId:%d failed to open DFile %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile), + tstrerror(terrno)); taosArrayDestroy(fArray); return -1; } @@ -1266,12 +1274,12 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { return 0; } -static int tsdbRestoreCurrent(STsdbRepo *pRepo) { - // Loop to recover mfile - if (tsdbRestoreMeta(pRepo) < 0) { - tsdbError("vgId:%d failed to restore current since %s", REPO_ID(pRepo), tstrerror(terrno)); - return -1; - } +static int tsdbRestoreCurrent(STsdb *pRepo) { + // // Loop to recover mfile + // if (tsdbRestoreMeta(pRepo) < 0) { + // tsdbError("vgId:%d failed to restore current since %s", REPO_ID(pRepo), tstrerror(terrno)); + // return -1; + // } // Loop to recover dfile set if (tsdbRestoreDFileSet(pRepo) < 0) { @@ -1317,7 +1325,7 @@ static int tsdbComparTFILE(const void *arg1, const void *arg2) { } } -static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo, int32_t *nExpired) { +static void tsdbScanAndTryFixDFilesHeader(STsdb *pRepo, int32_t *nExpired) { STsdbFS * pfs = REPO_FS(pRepo); SFSStatus *pStatus = pfs->cstatus; SDFInfo info; diff --git a/source/dnode/vnode/tsdb/src/tsdbFile.c b/source/dnode/vnode/tsdb/src/tsdbFile.c index 0f13b6108f..a1c1b57b44 100644 --- a/source/dnode/vnode/tsdb/src/tsdbFile.c +++ b/source/dnode/vnode/tsdb/src/tsdbFile.c @@ -13,22 +13,23 @@ * along with this program. If not, see . */ -#include "tsdbint.h" +#include "tsdbDef.h" static const char *TSDB_FNAME_SUFFIX[] = { - "head", // TSDB_FILE_HEAD - "data", // TSDB_FILE_DATA - "last", // TSDB_FILE_LAST - "", // TSDB_FILE_MAX - "meta", // TSDB_FILE_META + "head", // TSDB_FILE_HEAD + "data", // TSDB_FILE_DATA + "last", // TSDB_FILE_LAST + "", // TSDB_FILE_MAX + "meta", // TSDB_FILE_META }; -static void tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, char *fname); -static int tsdbRollBackMFile(SMFile *pMFile); +static void tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, char *fname); +// static int tsdbRollBackMFile(SMFile *pMFile); 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]; @@ -185,7 +186,7 @@ int tsdbLoadMFileHeader(SMFile *pMFile, SMFInfo *pInfo) { return 0; } -int tsdbScanAndTryFixMFile(STsdbRepo *pRepo) { +int tsdbScanAndTryFixMFile(STsdb *pRepo) { SMFile * pMFile = pRepo->fs->cstatus->pmf; struct stat mfstat; SMFile mf; @@ -291,6 +292,8 @@ static int tsdbRollBackMFile(SMFile *pMFile) { return 0; } +#endif + // ============== Operations on SDFile void tsdbInitDFile(SDFile *pDFile, SDiskID did, int vid, int fid, uint32_t ver, TSDB_FILE_T ftype) { char fname[TSDB_FILENAME_LEN]; @@ -397,7 +400,7 @@ int tsdbUpdateDFileHeader(SDFile *pDFile) { } void *ptr = buf; - taosEncodeFixedU32(&ptr, TSDB_FS_VERSION); + taosEncodeFixedU32(&ptr, 0); tsdbEncodeDFInfo(&ptr, &(pDFile->info)); taosCalcChecksumAppend(0, (uint8_t *)buf, TSDB_FILE_HEAD_SIZE); @@ -433,7 +436,7 @@ int tsdbLoadDFileHeader(SDFile *pDFile, SDFInfo *pInfo) { return 0; } -static int tsdbScanAndTryFixDFile(STsdbRepo *pRepo, SDFile *pDFile) { +static int tsdbScanAndTryFixDFile(STsdb *pRepo, SDFile *pDFile) { struct stat dfstat; SDFile df; @@ -442,7 +445,7 @@ static int tsdbScanAndTryFixDFile(STsdbRepo *pRepo, SDFile *pDFile) { if (access(TSDB_FILE_FULL_NAME(pDFile), F_OK) != 0) { tsdbError("vgId:%d data file %s not exit, report to upper layer to fix it", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile)); - pRepo->state |= TSDB_STATE_BAD_DATA; + // pRepo->state |= TSDB_STATE_BAD_DATA; TSDB_FILE_SET_STATE(pDFile, TSDB_FILE_STATE_BAD); return 0; } @@ -457,7 +460,7 @@ static int tsdbScanAndTryFixDFile(STsdbRepo *pRepo, SDFile *pDFile) { return -1; } - if (taosFtruncate(df.fd, df.info.size) < 0) { + if (taosFtruncateFile(df.fd, df.info.size) < 0) { terrno = TAOS_SYSTEM_ERROR(errno); tsdbCloseDFile(&df); return -1; @@ -474,7 +477,7 @@ static int tsdbScanAndTryFixDFile(STsdbRepo *pRepo, SDFile *pDFile) { } else if (pDFile->info.size > dfstat.st_size) { tsdbError("vgId:%d data file %s has wrong size %" PRId64 " expected %" PRId64 ", report to upper layer to fix it", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile), dfstat.st_size, pDFile->info.size); - pRepo->state |= TSDB_STATE_BAD_DATA; + // pRepo->state |= TSDB_STATE_BAD_DATA; TSDB_FILE_SET_STATE(pDFile, TSDB_FILE_STATE_BAD); terrno = TSDB_CODE_TDB_FILE_CORRUPTED; return 0; @@ -538,7 +541,7 @@ static int tsdbRollBackDFile(SDFile *pDFile) { return -1; } - if (taosFtruncate(TSDB_FILE_FD(&df), pDFile->info.size) < 0) { + if (taosFtruncateFile(TSDB_FILE_FD(&df), pDFile->info.size) < 0) { terrno = TAOS_SYSTEM_ERROR(errno); tsdbCloseDFile(&df); return -1; @@ -651,7 +654,7 @@ int tsdbUpdateDFileSetHeader(SDFileSet *pSet) { return 0; } -int tsdbScanAndTryFixDFileSet(STsdbRepo *pRepo, SDFileSet *pSet) { +int tsdbScanAndTryFixDFileSet(STsdb *pRepo, SDFileSet *pSet) { for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { if (tsdbScanAndTryFixDFile(pRepo, TSDB_DFILE_IN_SET(pSet, ftype)) < 0) { return -1; diff --git a/source/dnode/vnode/tsdb/src/tsdbMain.c b/source/dnode/vnode/tsdb/src/tsdbMain.c index c8bcfc6906..ab1f0294bf 100644 --- a/source/dnode/vnode/tsdb/src/tsdbMain.c +++ b/source/dnode/vnode/tsdb/src/tsdbMain.c @@ -15,18 +15,19 @@ #include "tsdbDef.h" -static STsdb *tsdbNew(const char *path, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory *pMAF); +static STsdb *tsdbNew(const char *path, int32_t vgId, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory *pMAF, + SMeta *pMeta); static void tsdbFree(STsdb *pTsdb); static int tsdbOpenImpl(STsdb *pTsdb); static void tsdbCloseImpl(STsdb *pTsdb); -STsdb *tsdbOpen(const char *path, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory *pMAF) { +STsdb *tsdbOpen(const char *path, int32_t vgId, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory *pMAF, SMeta *pMeta) { STsdb *pTsdb = NULL; // Set default TSDB Options - if (pTsdbCfg == NULL) { - pTsdbCfg = &defautlTsdbOptions; - } + // if (pTsdbCfg == NULL) { + pTsdbCfg = &defautlTsdbOptions; + // } // Validate the options if (tsdbValidateOptions(pTsdbCfg) < 0) { @@ -35,7 +36,7 @@ STsdb *tsdbOpen(const char *path, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory } // Create the handle - pTsdb = tsdbNew(path, pTsdbCfg, pMAF); + pTsdb = tsdbNew(path, vgId, pTsdbCfg, pMAF, pMeta); if (pTsdb == NULL) { // TODO: handle error return NULL; @@ -62,7 +63,8 @@ void tsdbClose(STsdb *pTsdb) { void tsdbRemove(const char *path) { taosRemoveDir(path); } /* ------------------------ STATIC METHODS ------------------------ */ -static STsdb *tsdbNew(const char *path, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory *pMAF) { +static STsdb *tsdbNew(const char *path, int32_t vgId, const STsdbCfg *pTsdbCfg, SMemAllocatorFactory *pMAF, + SMeta *pMeta) { STsdb *pTsdb = NULL; pTsdb = (STsdb *)calloc(1, sizeof(STsdb)); @@ -72,25 +74,32 @@ static STsdb *tsdbNew(const char *path, const STsdbCfg *pTsdbCfg, SMemAllocatorF } pTsdb->path = strdup(path); - tsdbOptionsCopy(&(pTsdb->options), pTsdbCfg); + pTsdb->vgId = vgId; + tsdbOptionsCopy(&(pTsdb->config), pTsdbCfg); pTsdb->pmaf = pMAF; + pTsdb->pMeta = pMeta; + + pTsdb->fs = tsdbNewFS(pTsdbCfg); return pTsdb; } static void tsdbFree(STsdb *pTsdb) { if (pTsdb) { + tsdbFreeFS(pTsdb->fs); tfree(pTsdb->path); free(pTsdb); } } static int tsdbOpenImpl(STsdb *pTsdb) { + tsdbOpenFS(pTsdb); // TODO return 0; } static void tsdbCloseImpl(STsdb *pTsdb) { + tsdbCloseFS(pTsdb); // TODO } #if 0 @@ -112,8 +121,8 @@ static void tsdbCloseImpl(STsdb *pTsdb) { // no test file errors here #include "taosdef.h" #include "tsdbint.h" -#include "ttimer.h" #include "tthread.h" +#include "ttimer.h" #define IS_VALID_PRECISION(precision) \ (((precision) >= TSDB_TIME_PRECISION_MILLI) && ((precision) <= TSDB_TIME_PRECISION_NANO)) diff --git a/source/dnode/vnode/tsdb/src/tsdbMemTable.c b/source/dnode/vnode/tsdb/src/tsdbMemTable.c index 7b0df18f5a..b16b3581df 100644 --- a/source/dnode/vnode/tsdb/src/tsdbMemTable.c +++ b/source/dnode/vnode/tsdb/src/tsdbMemTable.c @@ -15,70 +15,446 @@ #include "tsdbDef.h" -#if 1 -typedef struct STbData { - TD_SLIST_NODE(STbData); - SSubmitMsg *pMsg; -} STbData; -#else -typedef struct STbData { - TD_SLIST_NODE(STbData); - uint64_t uid; // TODO: change here as tb_uid_t - TSKEY keyMin; - TSKEY keyMax; - uint64_t nRows; - SSkipList *pData; // Here need a container, may not use the SL - T_REF_DECLARE() -} STbData; -#endif +static int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitMsg *pMsg); +static int tsdbMemTableInsertTbData(STsdb *pRepo, SSubmitBlk *pBlock, int32_t *pAffectedRows); +static STbData *tsdbNewTbData(tb_uid_t uid); +static void tsdbFreeTbData(STbData *pTbData); +static char * tsdbGetTsTupleKey(const void *data); +static int tsdbTbDataComp(const void *arg1, const void *arg2); +static char * tsdbTbDataGetUid(const void *arg); +static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SMemRow row); -struct STsdbMemTable { - T_REF_DECLARE() - SRWLatch latch; - TSKEY keyMin; - TSKEY keyMax; - uint64_t nRow; - SMemAllocator *pMA; - // Container - TD_SLIST(STbData) list; -}; - -STsdbMemTable *tsdbNewMemTable(SMemAllocatorFactory *pMAF) { - STsdbMemTable *pMemTable; - SMemAllocator *pMA; - - pMA = (*pMAF->create)(pMAF); - ASSERT(pMA != NULL); - - pMemTable = (STsdbMemTable *)TD_MA_MALLOC(pMA, sizeof(*pMemTable)); +STsdbMemTable *tsdbNewMemTable(STsdb *pTsdb) { + STsdbMemTable *pMemTable = (STsdbMemTable *)calloc(1, sizeof(*pMemTable)); if (pMemTable == NULL) { - (*pMAF->destroy)(pMAF, pMA); + terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; } T_REF_INIT_VAL(pMemTable, 1); taosInitRWLatch(&(pMemTable->latch)); - pMemTable->keyMin = TSKEY_MAX; pMemTable->keyMax = TSKEY_MIN; + pMemTable->keyMin = TSKEY_MAX; pMemTable->nRow = 0; - pMemTable->pMA = pMA; - TD_SLIST_INIT(&(pMemTable->list)); + pMemTable->pMA = pTsdb->pmaf->create(pTsdb->pmaf); + if (pMemTable->pMA == NULL) { + free(pMemTable); + return NULL; + } + + // Initialize the container + pMemTable->pSlIdx = + tSkipListCreate(5, TSDB_DATA_TYPE_BIGINT, sizeof(tb_uid_t), tsdbTbDataComp, SL_DISCARD_DUP_KEY, tsdbTbDataGetUid); + if (pMemTable->pSlIdx == NULL) { + pTsdb->pmaf->destroy(pTsdb->pmaf, pMemTable->pMA); + free(pMemTable); + return NULL; + } + + pMemTable->pHashIdx = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); + if (pMemTable->pHashIdx == NULL) { + pTsdb->pmaf->destroy(pTsdb->pmaf, pMemTable->pMA); + tSkipListDestroy(pMemTable->pSlIdx); + free(pMemTable); + return NULL; + } - // TODO return pMemTable; } -void tsdbFreeMemTable(SMemAllocatorFactory *pMAF, STsdbMemTable *pMemTable) { - SMemAllocator *pMA = pMemTable->pMA; - - if (TD_MA_FREE_FUNC(pMA) != NULL) { - // TODO - ASSERT(0); +void tsdbFreeMemTable(STsdb *pTsdb, STsdbMemTable *pMemTable) { + if (pMemTable) { + taosHashCleanup(pMemTable->pHashIdx); + tSkipListDestroy(pMemTable->pSlIdx); + if (pMemTable->pMA) { + pTsdb->pmaf->destroy(pTsdb->pmaf, pMemTable->pMA); + } + free(pMemTable); } - - (*pMAF->destroy)(pMAF, pMA); } +int tsdbMemTableInsert(STsdb *pTsdb, STsdbMemTable *pMemTable, SSubmitMsg *pMsg, SShellSubmitRsp *pRsp) { + SSubmitBlk * pBlock = NULL; + SSubmitMsgIter msgIter = {0}; + int32_t affectedrows = 0, numOfRows = 0; + + if (tsdbScanAndConvertSubmitMsg(pTsdb, pMsg) < 0) { + if (terrno != TSDB_CODE_TDB_TABLE_RECONFIGURE) { + tsdbError("vgId:%d failed to insert data since %s", REPO_ID(pTsdb), tstrerror(terrno)); + } + return -1; + } + + tInitSubmitMsgIter(pMsg, &msgIter); + while (true) { + tGetSubmitMsgNext(&msgIter, &pBlock); + if (pBlock == NULL) break; + if (tsdbMemTableInsertTbData(pTsdb, pBlock, &affectedrows) < 0) { + return -1; + } + + numOfRows += pBlock->numOfRows; + } + + if (pRsp != NULL) { + pRsp->affectedRows = htonl(affectedrows); + pRsp->numOfRows = htonl(numOfRows); + } + + return 0; +} + +/** + * This is an important function to load data or try to load data from memory skiplist iterator. + * + * This function load memory data until: + * 1. iterator ends + * 2. data key exceeds maxKey + * 3. rowsIncreased = rowsInserted - rowsDeleteSucceed >= maxRowsToRead + * 4. operations in pCols not exceeds its max capacity if pCols is given + * + * The function tries to procceed AS MUCH AS POSSIBLE. + */ +int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead, SDataCols *pCols, + TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo) { + ASSERT(maxRowsToRead > 0 && nFilterKeys >= 0); + if (pIter == NULL) return 0; + STSchema * pSchema = NULL; + TSKEY rowKey = 0; + TSKEY fKey = 0; + bool isRowDel = false; + int filterIter = 0; + SMemRow row = NULL; + SMergeInfo mInfo; + + if (pMergeInfo == NULL) pMergeInfo = &mInfo; + + memset(pMergeInfo, 0, sizeof(*pMergeInfo)); + pMergeInfo->keyFirst = INT64_MAX; + pMergeInfo->keyLast = INT64_MIN; + if (pCols) tdResetDataCols(pCols); + + row = tsdbNextIterRow(pIter); + if (row == NULL || memRowKey(row) > maxKey) { + rowKey = INT64_MAX; + isRowDel = false; + } else { + rowKey = memRowKey(row); + isRowDel = memRowDeleted(row); + } + + if (filterIter >= nFilterKeys) { + fKey = INT64_MAX; + } else { + fKey = tdGetKey(filterKeys[filterIter]); + } + + while (true) { + if (fKey == INT64_MAX && rowKey == INT64_MAX) break; + + if (fKey < rowKey) { + pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, fKey); + pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, fKey); + + filterIter++; + if (filterIter >= nFilterKeys) { + fKey = INT64_MAX; + } else { + fKey = tdGetKey(filterKeys[filterIter]); + } + } else if (fKey > rowKey) { + if (isRowDel) { + pMergeInfo->rowsDeleteFailed++; + } else { + if (pMergeInfo->rowsInserted - pMergeInfo->rowsDeleteSucceed >= maxRowsToRead) break; + if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; + pMergeInfo->rowsInserted++; + pMergeInfo->nOperations++; + pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, rowKey); + pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, rowKey); + tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); + } + + tSkipListIterNext(pIter); + row = tsdbNextIterRow(pIter); + if (row == NULL || memRowKey(row) > maxKey) { + rowKey = INT64_MAX; + isRowDel = false; + } else { + rowKey = memRowKey(row); + isRowDel = memRowDeleted(row); + } + } else { + if (isRowDel) { + ASSERT(!keepDup); + if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; + pMergeInfo->rowsDeleteSucceed++; + pMergeInfo->nOperations++; + tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); + } else { + if (keepDup) { + if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; + pMergeInfo->rowsUpdated++; + pMergeInfo->nOperations++; + pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, rowKey); + pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, rowKey); + tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); + } else { + pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, fKey); + pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, fKey); + } + } + + tSkipListIterNext(pIter); + row = tsdbNextIterRow(pIter); + if (row == NULL || memRowKey(row) > maxKey) { + rowKey = INT64_MAX; + isRowDel = false; + } else { + rowKey = memRowKey(row); + isRowDel = memRowDeleted(row); + } + + filterIter++; + if (filterIter >= nFilterKeys) { + fKey = INT64_MAX; + } else { + fKey = tdGetKey(filterKeys[filterIter]); + } + } + } + + return 0; +} + +static int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitMsg *pMsg) { + ASSERT(pMsg != NULL); + // STsdbMeta * pMeta = pTsdb->tsdbMeta; + SSubmitMsgIter msgIter = {0}; + SSubmitBlk * pBlock = NULL; + SSubmitBlkIter blkIter = {0}; + SMemRow row = NULL; + TSKEY now = taosGetTimestamp(pTsdb->config.precision); + TSKEY minKey = now - tsTickPerDay[pTsdb->config.precision] * pTsdb->config.keep; + TSKEY maxKey = now + tsTickPerDay[pTsdb->config.precision] * pTsdb->config.daysPerFile; + + terrno = TSDB_CODE_SUCCESS; + pMsg->length = htonl(pMsg->length); + pMsg->numOfBlocks = htonl(pMsg->numOfBlocks); + + if (tInitSubmitMsgIter(pMsg, &msgIter) < 0) return -1; + while (true) { + if (tGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1; + if (pBlock == NULL) break; + + pBlock->uid = htobe64(pBlock->uid); + pBlock->tid = htonl(pBlock->tid); + pBlock->sversion = htonl(pBlock->sversion); + pBlock->dataLen = htonl(pBlock->dataLen); + pBlock->schemaLen = htonl(pBlock->schemaLen); + pBlock->numOfRows = htons(pBlock->numOfRows); + +#if 0 + if (pBlock->tid <= 0 || pBlock->tid >= pMeta->maxTables) { + tsdbError("vgId:%d failed to get table to insert data, uid %" PRIu64 " tid %d", REPO_ID(pTsdb), pBlock->uid, + pBlock->tid); + terrno = TSDB_CODE_TDB_INVALID_TABLE_ID; + return -1; + } + + STable *pTable = pMeta->tables[pBlock->tid]; + if (pTable == NULL || TABLE_UID(pTable) != pBlock->uid) { + tsdbError("vgId:%d failed to get table to insert data, uid %" PRIu64 " tid %d", REPO_ID(pTsdb), pBlock->uid, + pBlock->tid); + terrno = TSDB_CODE_TDB_INVALID_TABLE_ID; + return -1; + } + + if (TABLE_TYPE(pTable) == TSDB_SUPER_TABLE) { + tsdbError("vgId:%d invalid action trying to insert a super table %s", REPO_ID(pTsdb), TABLE_CHAR_NAME(pTable)); + terrno = TSDB_CODE_TDB_INVALID_ACTION; + return -1; + } + + // Check schema version and update schema if needed + if (tsdbCheckTableSchema(pTsdb, pBlock, pTable) < 0) { + if (terrno == TSDB_CODE_TDB_TABLE_RECONFIGURE) { + continue; + } else { + return -1; + } + } + + tsdbInitSubmitBlkIter(pBlock, &blkIter); + while ((row = tsdbGetSubmitBlkNext(&blkIter)) != NULL) { + if (tsdbCheckRowRange(pTsdb, pTable, row, minKey, maxKey, now) < 0) { + return -1; + } + } +#endif + } + + if (terrno != TSDB_CODE_SUCCESS) return -1; + return 0; +} + +static int tsdbMemTableInsertTbData(STsdb *pTsdb, SSubmitBlk *pBlock, int32_t *pAffectedRows) { + // STsdbMeta *pMeta = pRepo->tsdbMeta; + // int32_t points = 0; + // STable *pTable = NULL; + SSubmitBlkIter blkIter = {0}; + STsdbMemTable *pMemTable = pTsdb->mem; + void * tptr; + STbData * pTbData; + SMemRow row; + TSKEY keyMin; + TSKEY keyMax; + + // SMemTable *pMemTable = NULL; + // STableData *pTableData = NULL; + // STsdbCfg *pCfg = &(pRepo->config); + + tptr = taosHashGet(pMemTable->pHashIdx, &(pBlock->uid), sizeof(pBlock->uid)); + if (tptr == NULL) { + pTbData = tsdbNewTbData(pBlock->uid); + if (pTbData == NULL) { + return -1; + } + + // Put into hash + taosHashPut(pMemTable->pHashIdx, &(pBlock->uid), sizeof(pBlock->uid), &(pTbData), sizeof(pTbData)); + + // Put into skiplist + tSkipListPut(pMemTable->pSlIdx, pTbData); + } else { + pTbData = *(STbData **)tptr; + } + + tInitSubmitBlkIter(pBlock, &blkIter); + if (blkIter.row == NULL) return 0; + keyMin = memRowKey(blkIter.row); + + tSkipListPutBatchByIter(pTbData->pData, &blkIter, (iter_next_fn_t)tGetSubmitBlkNext); + + // Set statistics + keyMax = memRowKey(blkIter.row); + + pTbData->nrows += pBlock->numOfRows; + if (pTbData->keyMin > keyMin) pTbData->keyMin = keyMin; + if (pTbData->keyMax < keyMax) pTbData->keyMax = keyMax; + + pMemTable->nRow += pBlock->numOfRows; + if (pMemTable->keyMin > keyMin) pMemTable->keyMin = keyMin; + if (pMemTable->keyMax < keyMax) pMemTable->keyMax = keyMax; + + // SMemRow lastRow = NULL; + // int64_t osize = SL_SIZE(pTableData->pData); + // tsdbSetupSkipListHookFns(pTableData->pData, pRepo, pTable, &points, &lastRow); + // tSkipListPutBatchByIter(pTableData->pData, &blkIter, (iter_next_fn_t)tsdbGetSubmitBlkNext); + // int64_t dsize = SL_SIZE(pTableData->pData) - osize; + // (*pAffectedRows) += points; + + // if(lastRow != NULL) { + // TSKEY lastRowKey = memRowKey(lastRow); + // if (pMemTable->keyFirst > firstRowKey) pMemTable->keyFirst = firstRowKey; + // pMemTable->numOfRows += dsize; + + // if (pTableData->keyFirst > firstRowKey) pTableData->keyFirst = firstRowKey; + // pTableData->numOfRows += dsize; + // if (pMemTable->keyLast < lastRowKey) pMemTable->keyLast = lastRowKey; + // if (pTableData->keyLast < lastRowKey) pTableData->keyLast = lastRowKey; + // if (tsdbUpdateTableLatestInfo(pRepo, pTable, lastRow) < 0) { + // return -1; + // } + // } + + // STSchema *pSchema = tsdbGetTableSchemaByVersion(pTable, pBlock->sversion, -1); + // pRepo->stat.pointsWritten += points * schemaNCols(pSchema); + // pRepo->stat.totalStorage += points * schemaVLen(pSchema); + + return 0; +} + +static STbData *tsdbNewTbData(tb_uid_t uid) { + STbData *pTbData = (STbData *)calloc(1, sizeof(*pTbData)); + if (pTbData == NULL) { + return NULL; + } + + pTbData->uid = uid; + pTbData->keyMin = TSKEY_MAX; + 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; + // free(pTableData); + // return NULL; + // } + + pTbData->pData = tSkipListCreate(5, TSDB_DATA_TYPE_TIMESTAMP, sizeof(int64_t), tkeyComparFn, SL_DISCARD_DUP_KEY, + tsdbGetTsTupleKey); + if (pTbData->pData == NULL) { + free(pTbData); + return NULL; + } + + return pTbData; +} + +static void tsdbFreeTbData(STbData *pTbData) { + if (pTbData) { + tSkipListDestroy(pTbData->pData); + free(pTbData); + } +} + +static char *tsdbGetTsTupleKey(const void *data) { return memRowKeys((SMemRow)data); } + +static int tsdbTbDataComp(const void *arg1, const void *arg2) { + STbData *pTbData1 = (STbData *)arg1; + STbData *pTbData2 = (STbData *)arg2; + + if (pTbData1->uid > pTbData2->uid) { + return 1; + } else if (pTbData1->uid == pTbData2->uid) { + return 0; + } else { + return -1; + } +} + +static char *tsdbTbDataGetUid(const void *arg) { + STbData *pTbData = (STbData *)arg; + return (char *)(&(pTbData->uid)); +} +static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SMemRow row) { + if (pCols) { + if (*ppSchema == NULL || schemaVersion(*ppSchema) != memRowVersion(row)) { + *ppSchema = tsdbGetTableSchemaImpl(pTable, false, false, memRowVersion(row)); + if (*ppSchema == NULL) { + ASSERT(false); + return -1; + } + } + + tdAppendMemRowToDataCol(row, *ppSchema, pCols, true); + } + + return 0; +} + +/* ------------------------ REFACTORING ------------------------ */ +#if 0 int tsdbInsertDataToMemTable(STsdbMemTable *pMemTable, SSubmitMsg *pMsg) { SMemAllocator *pMA = pMemTable->pMA; STbData * pTbData = (STbData *)TD_MA_MALLOC(pMA, sizeof(*pTbData)); @@ -91,4 +467,594 @@ int tsdbInsertDataToMemTable(STsdbMemTable *pMemTable, SSubmitMsg *pMsg) { return 0; } -/* ------------------------ STATIC METHODS ------------------------ */ \ No newline at end of file +#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; + SMemRow row; +} SSubmitBlkIter; + +typedef struct { + int32_t totalLen; + int32_t len; + void * pMsg; +} SSubmitMsgIter; + +static SMemTable * tsdbNewMemTable(STsdbRepo *pRepo); +static void tsdbFreeMemTable(SMemTable *pMemTable); +static STableData* tsdbNewTableData(STsdbCfg *pCfg, STable *pTable); +static void tsdbFreeTableData(STableData *pTableData); +static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables); +static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SMemRow row); +static int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter); +static SMemRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter); +static int tsdbScanAndConvertSubmitMsg(STsdbRepo *pRepo, SSubmitMsg *pMsg); +static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *affectedrows); +static int tsdbInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter); +static int tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock); +static int tsdbCheckTableSchema(STsdbRepo *pRepo, SSubmitBlk *pBlock, STable *pTable); +static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SMemRow row); + +static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SMemRow row, TSKEY minKey, TSKEY maxKey, + TSKEY now); + + +// ---------------- INTERNAL FUNCTIONS ---------------- +int tsdbRefMemTable(STsdbRepo *pRepo, SMemTable *pMemTable) { + if (pMemTable == NULL) return 0; + int ref = T_REF_INC(pMemTable); + tsdbDebug("vgId:%d ref memtable %p ref %d", REPO_ID(pRepo), pMemTable, ref); + return 0; +} + +// Need to lock the repository +int tsdbUnRefMemTable(STsdbRepo *pRepo, SMemTable *pMemTable) { + if (pMemTable == NULL) return 0; + + int ref = T_REF_DEC(pMemTable); + tsdbDebug("vgId:%d unref memtable %p ref %d", REPO_ID(pRepo), pMemTable, ref); + if (ref == 0) { + STsdbBufPool *pBufPool = pRepo->pPool; + + SListNode *pNode = NULL; + bool addNew = false; + if (tsdbLockRepo(pRepo) < 0) return -1; + while ((pNode = tdListPopHead(pMemTable->bufBlockList)) != NULL) { + if (pBufPool->nRecycleBlocks > 0) { + tsdbRecycleBufferBlock(pBufPool, pNode, false); + pBufPool->nRecycleBlocks -= 1; + } else { + if(pBufPool->nElasticBlocks > 0 && listNEles(pBufPool->bufBlockList) > 2) { + tsdbRecycleBufferBlock(pBufPool, pNode, true); + } else { + tdListAppendNode(pBufPool->bufBlockList, pNode); + addNew = true; + } + } + } + if (addNew) { + int code = pthread_cond_signal(&pBufPool->poolNotEmpty); + if (code != 0) { + if (tsdbUnlockRepo(pRepo) < 0) return -1; + tsdbError("vgId:%d failed to signal pool not empty since %s", REPO_ID(pRepo), strerror(code)); + terrno = TAOS_SYSTEM_ERROR(code); + return -1; + } + } + + if (tsdbUnlockRepo(pRepo) < 0) return -1; + + for (int i = 0; i < pMemTable->maxTables; i++) { + if (pMemTable->tData[i] != NULL) { + tsdbFreeTableData(pMemTable->tData[i]); + } + } + + tdListDiscard(pMemTable->actList); + tdListDiscard(pMemTable->bufBlockList); + tsdbFreeMemTable(pMemTable); + } + return 0; +} + +int tsdbTakeMemSnapshot(STsdbRepo *pRepo, SMemSnapshot *pSnapshot, SArray *pATable) { + memset(pSnapshot, 0, sizeof(*pSnapshot)); + + if (tsdbLockRepo(pRepo) < 0) return -1; + + pSnapshot->omem = pRepo->mem; + pSnapshot->imem = pRepo->imem; + tsdbRefMemTable(pRepo, pRepo->mem); + tsdbRefMemTable(pRepo, pRepo->imem); + + if (tsdbUnlockRepo(pRepo) < 0) return -1; + + if (pSnapshot->omem) { + taosRLockLatch(&(pSnapshot->omem->latch)); + + pSnapshot->mem = &(pSnapshot->mtable); + + pSnapshot->mem->tData = (STableData **)calloc(pSnapshot->omem->maxTables, sizeof(STableData *)); + if (pSnapshot->mem->tData == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + taosRUnLockLatch(&(pSnapshot->omem->latch)); + tsdbUnRefMemTable(pRepo, pSnapshot->omem); + tsdbUnRefMemTable(pRepo, pSnapshot->imem); + pSnapshot->mem = NULL; + pSnapshot->imem = NULL; + pSnapshot->omem = NULL; + return -1; + } + + pSnapshot->mem->keyFirst = pSnapshot->omem->keyFirst; + pSnapshot->mem->keyLast = pSnapshot->omem->keyLast; + pSnapshot->mem->numOfRows = pSnapshot->omem->numOfRows; + pSnapshot->mem->maxTables = pSnapshot->omem->maxTables; + + for (size_t i = 0; i < taosArrayGetSize(pATable); i++) { + STable * pTable = *(STable **)taosArrayGet(pATable, i); + int32_t tid = TABLE_TID(pTable); + STableData *pTableData = (tid < pSnapshot->omem->maxTables) ? pSnapshot->omem->tData[tid] : NULL; + + if ((pTableData == NULL) || (TABLE_UID(pTable) != pTableData->uid)) continue; + + pSnapshot->mem->tData[tid] = pTableData; + T_REF_INC(pTableData); + } + + taosRUnLockLatch(&(pSnapshot->omem->latch)); + } + + tsdbDebug("vgId:%d take memory snapshot, pMem %p pIMem %p", REPO_ID(pRepo), pSnapshot->omem, pSnapshot->imem); + return 0; +} + +void tsdbUnTakeMemSnapShot(STsdbRepo *pRepo, SMemSnapshot *pSnapshot) { + tsdbDebug("vgId:%d untake memory snapshot, pMem %p pIMem %p", REPO_ID(pRepo), pSnapshot->omem, pSnapshot->imem); + + if (pSnapshot->mem) { + ASSERT(pSnapshot->omem != NULL); + + for (size_t i = 0; i < pSnapshot->mem->maxTables; i++) { + STableData *pTableData = pSnapshot->mem->tData[i]; + if (pTableData) { + tsdbFreeTableData(pTableData); + } + } + tfree(pSnapshot->mem->tData); + + tsdbUnRefMemTable(pRepo, pSnapshot->omem); + } + + tsdbUnRefMemTable(pRepo, pSnapshot->imem); + + pSnapshot->mem = NULL; + pSnapshot->imem = NULL; + pSnapshot->omem = NULL; +} + +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; + SMemRow row = NULL; + SMergeInfo mInfo; + + if (pMergeInfo == NULL) pMergeInfo = &mInfo; + + memset(pMergeInfo, 0, sizeof(*pMergeInfo)); + pMergeInfo->keyFirst = INT64_MAX; + pMergeInfo->keyLast = INT64_MIN; + if (pCols) tdResetDataCols(pCols); + + row = tsdbNextIterRow(pIter); + if (row == NULL || memRowKey(row) > maxKey) { + rowKey = INT64_MAX; + isRowDel = false; + } else { + rowKey = memRowKey(row); + isRowDel = memRowDeleted(row); + } + + if (filterIter >= nFilterKeys) { + fKey = INT64_MAX; + } else { + fKey = tdGetKey(filterKeys[filterIter]); + } + + while (true) { + if (fKey == INT64_MAX && rowKey == INT64_MAX) break; + + if (fKey < rowKey) { + pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, fKey); + pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, fKey); + + filterIter++; + if (filterIter >= nFilterKeys) { + fKey = INT64_MAX; + } else { + fKey = tdGetKey(filterKeys[filterIter]); + } + } else if (fKey > rowKey) { + if (isRowDel) { + pMergeInfo->rowsDeleteFailed++; + } else { + if (pMergeInfo->rowsInserted - pMergeInfo->rowsDeleteSucceed >= maxRowsToRead) break; + if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; + pMergeInfo->rowsInserted++; + pMergeInfo->nOperations++; + pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, rowKey); + pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, rowKey); + tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); + } + + tSkipListIterNext(pIter); + row = tsdbNextIterRow(pIter); + if (row == NULL || memRowKey(row) > maxKey) { + rowKey = INT64_MAX; + isRowDel = false; + } else { + rowKey = memRowKey(row); + isRowDel = memRowDeleted(row); + } + } else { + if (isRowDel) { + ASSERT(!keepDup); + if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; + pMergeInfo->rowsDeleteSucceed++; + pMergeInfo->nOperations++; + tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); + } else { + if (keepDup) { + if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; + pMergeInfo->rowsUpdated++; + pMergeInfo->nOperations++; + pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, rowKey); + pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, rowKey); + tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); + } else { + pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, fKey); + pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, fKey); + } + } + + tSkipListIterNext(pIter); + row = tsdbNextIterRow(pIter); + if (row == NULL || memRowKey(row) > maxKey) { + rowKey = INT64_MAX; + isRowDel = false; + } else { + rowKey = memRowKey(row); + isRowDel = memRowDeleted(row); + } + + filterIter++; + if (filterIter >= nFilterKeys) { + fKey = INT64_MAX; + } else { + fKey = tdGetKey(filterKeys[filterIter]); + } + } + } + + return 0; +} + +// ---------------- LOCAL FUNCTIONS ---------------- + +static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SMemRow row, TSKEY minKey, TSKEY maxKey, + TSKEY now) { + TSKEY rowKey = memRowKey(row); + if (rowKey < minKey || rowKey > maxKey) { + tsdbError("vgId:%d table %s tid %d uid %" PRIu64 " timestamp is out of range! now %" PRId64 " minKey %" PRId64 + " maxKey %" PRId64 " row key %" PRId64, + REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable), now, minKey, maxKey, + rowKey); + terrno = TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE; + return -1; + } + + return 0; +} + + +//row1 has higher priority +static SMemRow tsdbInsertDupKeyMerge(SMemRow row1, SMemRow row2, STsdbRepo* pRepo, + STSchema **ppSchema1, STSchema **ppSchema2, + STable* pTable, int32_t* pPoints, SMemRow* pLastRow) { + + //for compatiblity, duplicate key inserted when update=0 should be also calculated as affected rows! + if(row1 == NULL && row2 == NULL && pRepo->config.update == TD_ROW_DISCARD_UPDATE) { + (*pPoints)++; + return NULL; + } + + 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), + memRowKey(row1)); + + if(row2 == NULL || pRepo->config.update != TD_ROW_PARTIAL_UPDATE) { + void* pMem = tsdbAllocBytes(pRepo, memRowTLen(row1)); + if(pMem == NULL) return NULL; + memRowCpy(pMem, row1); + (*pPoints)++; + *pLastRow = pMem; + return pMem; + } + + STSchema *pSchema1 = *ppSchema1; + STSchema *pSchema2 = *ppSchema2; + SMergeBuf * pBuf = &pRepo->mergeBuf; + int dv1 = memRowVersion(row1); + int dv2 = memRowVersion(row2); + if(pSchema1 == NULL || schemaVersion(pSchema1) != dv1) { + if(pSchema2 != NULL && schemaVersion(pSchema2) == dv1) { + *ppSchema1 = pSchema2; + } else { + *ppSchema1 = tsdbGetTableSchemaImpl(pTable, false, false, memRowVersion(row1), (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; + } + } + + SMemRow tmp = tsdbMergeTwoRows(pBuf, row1, row2, pSchema1, pSchema2); + + void* pMem = tsdbAllocBytes(pRepo, memRowTLen(tmp)); + if(pMem == NULL) return NULL; + memRowCpy(pMem, tmp); + + (*pPoints)++; + *pLastRow = pMem; + return pMem; +} + +static void* tsdbInsertDupKeyMergePacked(void** args) { + return tsdbInsertDupKeyMerge(args[0], args[1], args[2], (STSchema**)&args[3], (STSchema**)&args[4], args[5], args[6], args[7]); +} + +static void tsdbSetupSkipListHookFns(SSkipList* pSkipList, STsdbRepo *pRepo, STable *pTable, int32_t* pPoints, SMemRow* pLastRow) { + + if(pSkipList->insertHandleFn == NULL) { + tGenericSavedFunc *dupHandleSavedFunc = genericSavedFuncInit((GenericVaFunc)&tsdbInsertDupKeyMergePacked, 9); + dupHandleSavedFunc->args[2] = pRepo; + dupHandleSavedFunc->args[3] = NULL; + dupHandleSavedFunc->args[4] = NULL; + dupHandleSavedFunc->args[5] = pTable; + pSkipList->insertHandleFn = dupHandleSavedFunc; + } + pSkipList->insertHandleFn->args[6] = pPoints; + pSkipList->insertHandleFn->args[7] = pLastRow; +} + +static int 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, SMemRow row) { + tsdbDebug("vgId:%d updateTableLatestColumn, %s row version:%d", REPO_ID(pRepo), pTable->name->data, + memRowVersion(row)); + + STSchema* pSchema = tsdbGetTableLatestSchema(pTable); + if (tsdbUpdateLastColSchema(pTable, pSchema) < 0) { + return; + } + + pSchema = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row), (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 = malloc(pTCol->bytes); + pDataCol->bytes = pTCol->bytes; + } else if (pDataCol->bytes < pTCol->bytes) { + pDataCol->pData = realloc(pDataCol->pData, pTCol->bytes); + pDataCol->bytes = pTCol->bytes; + } + // the actual value size + uint16_t bytes = IS_VAR_DATA_TYPE(pTCol->type) ? varDataTLen(value) : pTCol->bytes; + // the actual data size CANNOT larger than column size + assert(pTCol->bytes >= bytes); + memcpy(pDataCol->pData, value, bytes); + //tsdbInfo("updateTableLatestColumn vgId:%d cache column %d for %d,%s", REPO_ID(pRepo), j, pDataCol->bytes, (char*)pDataCol->pData); + pDataCol->ts = memRowKey(row); + // unlock + TSDB_WUNLOCK_TABLE(pTable); + } +} + +static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SMemRow row) { + STsdbCfg *pCfg = &pRepo->config; + + // if cacheLastRow config has been reset, free the lastRow + if (!pCfg->cacheLastRow && pTable->lastRow != NULL) { + SMemRow cachedLastRow = pTable->lastRow; + TSDB_WLOCK_TABLE(pTable); + pTable->lastRow = NULL; + TSDB_WUNLOCK_TABLE(pTable); + taosTZfree(cachedLastRow); + } + + if (tsdbGetTableLastKeyImpl(pTable) <= memRowKey(row)) { + if (CACHE_LAST_ROW(pCfg) || pTable->lastRow != NULL) { + SMemRow nrow = pTable->lastRow; + if (taosTSizeof(nrow) < memRowTLen(row)) { + SMemRow orow = nrow; + nrow = taosTMalloc(memRowTLen(row)); + if (nrow == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + return -1; + } + + memRowCpy(nrow, row); + TSDB_WLOCK_TABLE(pTable); + pTable->lastKey = memRowKey(row); + pTable->lastRow = nrow; + TSDB_WUNLOCK_TABLE(pTable); + taosTZfree(orow); + } else { + TSDB_WLOCK_TABLE(pTable); + pTable->lastKey = memRowKey(row); + memRowCpy(nrow, row); + TSDB_WUNLOCK_TABLE(pTable); + } + } else { + pTable->lastKey = memRowKey(row); + } + + if (CACHE_LAST_NULL_COLUMN(pCfg)) { + updateTableLatestColumn(pRepo, pTable, row); + } + } + + pTable->cacheLastConfigVersion = pRepo->cacheLastConfigVersion; + + return 0; +} + +#endif \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/src/tsdbOptions.c b/source/dnode/vnode/tsdb/src/tsdbOptions.c index 1c2b3c640a..6bca2e3028 100644 --- a/source/dnode/vnode/tsdb/src/tsdbOptions.c +++ b/source/dnode/vnode/tsdb/src/tsdbOptions.c @@ -15,7 +15,16 @@ #include "tsdbDef.h" -const STsdbCfg defautlTsdbOptions = {.lruCacheSize = 0}; +const STsdbCfg defautlTsdbOptions = {.precision = 0, + .lruCacheSize = 0, + .daysPerFile = 10, + .minRowsPerFileBlock = 100, + .maxRowsPerFileBlock = 4096, + .keep = 3650, + .keep1 = 3650, + .keep2 = 3650, + .update = 0, + .compression = TWO_STAGE_COMP}; int tsdbOptionsInit(STsdbCfg *pTsdbOptions) { // TODO diff --git a/source/dnode/vnode/tsdb/src/tsdbReadImpl.c b/source/dnode/vnode/tsdb/src/tsdbReadImpl.c index 74d41cce19..c4beac452d 100644 --- a/source/dnode/vnode/tsdb/src/tsdbReadImpl.c +++ b/source/dnode/vnode/tsdb/src/tsdbReadImpl.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "tsdbint.h" +#include "tsdbDef.h" #define TSDB_KEY_COL_OFFSET 0 @@ -26,7 +26,7 @@ static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols int numOfColIds); static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBlockCol *pBlockCol, SDataCol *pDataCol); -int tsdbInitReadH(SReadH *pReadh, STsdbRepo *pRepo) { +int tsdbInitReadH(SReadH *pReadh, STsdb *pRepo) { ASSERT(pReadh != NULL && pRepo != NULL); STsdbCfg *pCfg = REPO_CFG(pRepo); @@ -259,7 +259,9 @@ int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) { for (int i = 1; i < pBlock->numOfSubBlocks; i++) { iBlock++; if (tsdbLoadBlockDataImpl(pReadh, iBlock, pReadh->pDCols[1]) < 0) return -1; - if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows, NULL, update != TD_ROW_PARTIAL_UPDATE) < 0) return -1; + if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows, NULL, + update != TD_ROW_PARTIAL_UPDATE) < 0) + return -1; } ASSERT(pReadh->pDCols[0]->numOfRows == pBlock->numOfRows); @@ -286,7 +288,9 @@ int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo, for (int i = 1; i < pBlock->numOfSubBlocks; i++) { iBlock++; if (tsdbLoadBlockDataColsImpl(pReadh, iBlock, pReadh->pDCols[1], colIds, numOfColsIds) < 0) return -1; - if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows, NULL, update != TD_ROW_PARTIAL_UPDATE) < 0) return -1; + if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows, NULL, + update != TD_ROW_PARTIAL_UPDATE) < 0) + return -1; } ASSERT(pReadh->pDCols[0]->numOfRows == pBlock->numOfRows); @@ -524,7 +528,7 @@ static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32 if (comp) { // Need to decompress int tlen = (*(tDataTypes[pDataCol->type].decompFunc))(content, len - sizeof(TSCKSUM), numOfRows, pDataCol->pData, - pDataCol->spaceSize, comp, buffer, bufferSize); + pDataCol->spaceSize, comp, buffer, bufferSize); if (tlen <= 0) { tsdbError("Failed to decompress column, file corrupted, len:%d comp:%d numOfRows:%d maxPoints:%d bufferSize:%d", len, comp, numOfRows, maxPoints, bufferSize); @@ -624,9 +628,9 @@ static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols * static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBlockCol *pBlockCol, SDataCol *pDataCol) { ASSERT(pDataCol->colId == pBlockCol->colId); - STsdbRepo *pRepo = TSDB_READ_REPO(pReadh); - STsdbCfg * pCfg = REPO_CFG(pRepo); - int tsize = pDataCol->bytes * pBlock->numOfRows + COMP_OVERFLOW_BYTES; + STsdb * pRepo = TSDB_READ_REPO(pReadh); + STsdbCfg *pCfg = REPO_CFG(pRepo); + int tsize = pDataCol->bytes * pBlock->numOfRows + COMP_OVERFLOW_BYTES; if (tsdbMakeRoom((void **)(&TSDB_READ_BUF(pReadh)), pBlockCol->len) < 0) return -1; if (tsdbMakeRoom((void **)(&TSDB_READ_COMP_BUF(pReadh)), tsize) < 0) return -1; diff --git a/source/dnode/vnode/tsdb/src/tsdbWrite.c b/source/dnode/vnode/tsdb/src/tsdbWrite.c index f9441cbe44..570e821af0 100644 --- a/source/dnode/vnode/tsdb/src/tsdbWrite.c +++ b/source/dnode/vnode/tsdb/src/tsdbWrite.c @@ -15,11 +15,11 @@ #include "tsdbDef.h" -int tsdbInsertData(STsdb *pTsdb, SSubmitMsg *pMsg) { +int tsdbInsertData(STsdb *pTsdb, SSubmitMsg *pMsg, SSubmitRsp *pRsp) { // Check if mem is there. If not, create one. - pTsdb->mem = tsdbNewMemTable(pTsdb->pmaf); + pTsdb->mem = tsdbNewMemTable(pTsdb); if (pTsdb->mem == NULL) { return -1; } - return tsdbInsertDataToMemTable(pTsdb->mem, pMsg); + return tsdbMemTableInsert(pTsdb, pTsdb->mem, pMsg, NULL); } \ No newline at end of file diff --git a/source/libs/CMakeLists.txt b/source/libs/CMakeLists.txt index 027532bbb1..1dc16c74f7 100644 --- a/source/libs/CMakeLists.txt +++ b/source/libs/CMakeLists.txt @@ -12,3 +12,4 @@ add_subdirectory(planner) add_subdirectory(function) add_subdirectory(qcom) add_subdirectory(qworker) +add_subdirectory(tfs) diff --git a/source/libs/catalog/inc/catalogInt.h b/source/libs/catalog/inc/catalogInt.h index f426139c14..91a9c5248c 100644 --- a/source/libs/catalog/inc/catalogInt.h +++ b/source/libs/catalog/inc/catalogInt.h @@ -22,20 +22,31 @@ extern "C" { #include "catalog.h" #include "common.h" -#include "tlog.h" +#include "query.h" #define CTG_DEFAULT_CACHE_CLUSTER_NUMBER 6 #define CTG_DEFAULT_CACHE_VGROUP_NUMBER 100 #define CTG_DEFAULT_CACHE_DB_NUMBER 20 #define CTG_DEFAULT_CACHE_TABLEMETA_NUMBER 100000 +#define CTG_DEFAULT_RENT_SECOND 10 +#define CTG_DEFAULT_RENT_SLOT_SIZE 10 + +#define CTG_RENT_SLOT_SECOND 2 #define CTG_DEFAULT_INVALID_VERSION (-1) +#define CTG_ERR_CODE_TABLE_NOT_EXIST TSDB_CODE_TDB_INVALID_TABLE_ID + enum { CTG_READ = 1, CTG_WRITE, }; +enum { + CTG_RENT_DB = 1, + CTG_RENT_STABLE, +}; + typedef struct SVgroupListCache { int32_t vgroupVersion; SHashObj *cache; // key:vgId, value:SVgroupInfo @@ -51,30 +62,76 @@ typedef struct STableMetaCache { SHashObj *stableCache; //key:suid, value:STableMeta* } STableMetaCache; +typedef struct SRentSlotInfo { + SRWLatch lock; + bool needSort; + SArray *meta; // element is SDbVgVersion or SSTableMetaVersion +} SRentSlotInfo; + +typedef struct SMetaRentMgmt { + int8_t type; + uint16_t slotNum; + uint16_t slotRIdx; + int64_t lastReadMsec; + SRentSlotInfo *slots; +} SMetaRentMgmt; + typedef struct SCatalog { + uint64_t clusterId; SDBVgroupCache dbCache; STableMetaCache tableCache; + SMetaRentMgmt dbRent; + SMetaRentMgmt stableRent; } SCatalog; +typedef struct SCtgApiStat { + +} SCtgApiStat; + +typedef struct SCtgResourceStat { + +} SCtgResourceStat; + +typedef struct SCtgCacheStat { + +} SCtgCacheStat; + +typedef struct SCatalogStat { + SCtgApiStat api; + SCtgResourceStat resource; + SCtgCacheStat cache; +} SCatalogStat; + typedef struct SCatalogMgmt { - void *pMsgSender; // used to send messsage to mnode to fetch necessary metadata - SHashObj *pCluster; // items cached for each cluster, the hash key is the cluster-id got from mgmt node - SCatalogCfg cfg; + SHashObj *pCluster; //key: clusterId, value: SCatalog* + SCatalogStat stat; + SCatalogCfg cfg; } SCatalogMgmt; typedef uint32_t (*tableNameHashFp)(const char *, uint32_t); -#define ctgFatal(...) do { if (ctgDebugFlag & DEBUG_FATAL) { taosPrintLog("CTG FATAL ", ctgDebugFlag, __VA_ARGS__); }} while(0) -#define ctgError(...) do { if (ctgDebugFlag & DEBUG_ERROR) { taosPrintLog("CTG ERROR ", ctgDebugFlag, __VA_ARGS__); }} while(0) -#define ctgWarn(...) do { if (ctgDebugFlag & DEBUG_WARN) { taosPrintLog("CTG WARN ", ctgDebugFlag, __VA_ARGS__); }} while(0) -#define ctgInfo(...) do { if (ctgDebugFlag & DEBUG_INFO) { taosPrintLog("CTG ", ctgDebugFlag, __VA_ARGS__); }} while(0) -#define ctgDebug(...) do { if (ctgDebugFlag & DEBUG_DEBUG) { taosPrintLog("CTG ", ctgDebugFlag, __VA_ARGS__); }} while(0) -#define ctgTrace(...) do { if (ctgDebugFlag & DEBUG_TRACE) { taosPrintLog("CTG ", ctgDebugFlag, __VA_ARGS__); }} while(0) -#define ctgDebugL(...) do { if (ctgDebugFlag & DEBUG_DEBUG) { taosPrintLongString("CTG ", ctgDebugFlag, __VA_ARGS__); }} while(0) +#define CTG_IS_META_NONE(type) ((type) == META_TYPE_NON_TABLE) +#define CTG_IS_META_CTABLE(type) ((type) == META_TYPE_CTABLE) +#define CTG_IS_META_TABLE(type) ((type) == META_TYPE_TABLE) +#define CTG_IS_META_BOTH(type) ((type) == META_TYPE_BOTH_TABLE) + +#define CTG_IS_STABLE(isSTable) (1 == (isSTable)) +#define CTG_IS_NOT_STABLE(isSTable) (0 == (isSTable)) +#define CTG_IS_UNKNOWN_STABLE(isSTable) ((isSTable) < 0) +#define CTG_SET_STABLE(isSTable, tbType) do { (isSTable) = ((tbType) == TSDB_SUPER_TABLE) ? 1 : ((tbType) > TSDB_SUPER_TABLE ? 0 : -1); } while (0) +#define CTG_TBTYPE_MATCH(isSTable, tbType) (CTG_IS_UNKNOWN_STABLE(isSTable) || (CTG_IS_STABLE(isSTable) && (tbType) == TSDB_SUPER_TABLE) || (CTG_IS_NOT_STABLE(isSTable) && (tbType) != TSDB_SUPER_TABLE)) + +#define CTG_TABLE_NOT_EXIST(code) (code == CTG_ERR_CODE_TABLE_NOT_EXIST) + +#define ctgFatal(param, ...) qFatal("CTG:%p " param, pCatalog, __VA_ARGS__) +#define ctgError(param, ...) qError("CTG:%p " param, pCatalog, __VA_ARGS__) +#define ctgWarn(param, ...) qWarn("CTG:%p " param, pCatalog, __VA_ARGS__) +#define ctgInfo(param, ...) qInfo("CTG:%p " param, pCatalog, __VA_ARGS__) +#define ctgDebug(param, ...) qDebug("CTG:%p " param, pCatalog, __VA_ARGS__) +#define ctgTrace(param, ...) qTrace("CTG:%p " param, pCatalog, __VA_ARGS__) #define CTG_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; return _code; } } while (0) #define CTG_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; } return _code; } while (0) -#define CTG_ERR_LRET(c,...) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { ctgError(__VA_ARGS__); terrno = _code; return _code; } } while (0) #define CTG_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0) #define TD_RWLATCH_WRITE_FLAG_COPY 0x40000000 @@ -82,15 +139,15 @@ typedef uint32_t (*tableNameHashFp)(const char *, uint32_t); #define CTG_LOCK(type, _lock) do { \ if (CTG_READ == (type)) { \ assert(atomic_load_32((_lock)) >= 0); \ - ctgDebug("CTG RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ + qDebug("CTG RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ taosRLockLatch(_lock); \ - ctgDebug("CTG RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ + qDebug("CTG RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ assert(atomic_load_32((_lock)) > 0); \ } else { \ assert(atomic_load_32((_lock)) >= 0); \ - ctgDebug("CTG WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ + qDebug("CTG WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ taosWLockLatch(_lock); \ - ctgDebug("CTG WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ + qDebug("CTG WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ assert(atomic_load_32((_lock)) == TD_RWLATCH_WRITE_FLAG_COPY); \ } \ } while (0) @@ -98,15 +155,15 @@ typedef uint32_t (*tableNameHashFp)(const char *, uint32_t); #define CTG_UNLOCK(type, _lock) do { \ if (CTG_READ == (type)) { \ assert(atomic_load_32((_lock)) > 0); \ - ctgDebug("CTG RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ + qDebug("CTG RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ taosRUnLockLatch(_lock); \ - ctgDebug("CTG RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ + qDebug("CTG RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ assert(atomic_load_32((_lock)) >= 0); \ } else { \ assert(atomic_load_32((_lock)) == TD_RWLATCH_WRITE_FLAG_COPY); \ - ctgDebug("CTG WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ + qDebug("CTG WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ taosWUnLockLatch(_lock); \ - ctgDebug("CTG WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ + qDebug("CTG WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \ assert(atomic_load_32((_lock)) >= 0); \ } \ } while (0) diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index abcfafa786..94f34b8e17 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -23,7 +23,7 @@ SCatalogMgmt ctgMgmt = {0}; int32_t ctgGetDBVgroupFromCache(struct SCatalog* pCatalog, const char *dbName, SDBVgroupInfo **dbInfo, bool *inCache) { if (NULL == pCatalog->dbCache.cache) { *inCache = false; - ctgWarn("no db cache"); + ctgWarn("empty db cache, dbName:%s", dbName); return TSDB_CODE_SUCCESS; } @@ -34,7 +34,7 @@ int32_t ctgGetDBVgroupFromCache(struct SCatalog* pCatalog, const char *dbName, S if (NULL == info) { *inCache = false; - ctgWarn("no db cache, dbName:%s", dbName); + ctgWarn("not in db vgroup cache, dbName:%s", dbName); return TSDB_CODE_SUCCESS; } @@ -52,6 +52,8 @@ int32_t ctgGetDBVgroupFromCache(struct SCatalog* pCatalog, const char *dbName, S *dbInfo = info; *inCache = true; + + ctgDebug("Got db vgroup from cache, dbName:%s", dbName); return TSDB_CODE_SUCCESS; } @@ -63,7 +65,13 @@ int32_t ctgGetDBVgroupFromMnode(struct SCatalog* pCatalog, void *pRpc, const SEp SEpSet *pVnodeEpSet = NULL; int32_t msgLen = 0; - CTG_ERR_RET(queryBuildMsg[TMSG_INDEX(TDMT_MND_USE_DB)](input, &msg, 0, &msgLen)); + ctgDebug("try to get db vgroup from mnode, db:%s", input->db); + + int32_t code = queryBuildMsg[TMSG_INDEX(TDMT_MND_USE_DB)](input, &msg, 0, &msgLen); + if (code) { + ctgError("Build use db msg failed, code:%x, db:%s", code, input->db); + CTG_ERR_RET(code); + } SRpcMsg rpcMsg = { .msgType = TDMT_MND_USE_DB, @@ -75,19 +83,47 @@ int32_t ctgGetDBVgroupFromMnode(struct SCatalog* pCatalog, void *pRpc, const SEp rpcSendRecv(pRpc, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp); if (TSDB_CODE_SUCCESS != rpcRsp.code) { - ctgError("error rsp for use db, code:%x", rpcRsp.code); + ctgError("error rsp for use db, code:%x, db:%s", rpcRsp.code, input->db); CTG_ERR_RET(rpcRsp.code); } - CTG_ERR_RET(queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_USE_DB)](out, rpcRsp.pCont, rpcRsp.contLen)); + code = queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_USE_DB)](out, rpcRsp.pCont, rpcRsp.contLen); + if (code) { + ctgError("Process use db rsp failed, code:%x, db:%s", code, input->db); + CTG_ERR_RET(code); + } return TSDB_CODE_SUCCESS; } +int32_t ctgIsTableMetaExistInCache(struct SCatalog* pCatalog, const char* tbFullName, int32_t *exist) { + if (NULL == pCatalog->tableCache.cache) { + *exist = 0; + ctgWarn("empty tablemeta cache, tbName:%s", tbFullName); + return TSDB_CODE_SUCCESS; + } + + size_t sz = 0; + STableMeta *tbMeta = taosHashGet(pCatalog->tableCache.cache, tbFullName, strlen(tbFullName)); + + if (NULL == tbMeta) { + *exist = 0; + ctgDebug("tablemeta not in cache, tbName:%s", tbFullName); + return TSDB_CODE_SUCCESS; + } + + *exist = 1; + + ctgDebug("tablemeta is in cache, tbName:%s", tbFullName); + + return TSDB_CODE_SUCCESS; +} + int32_t ctgGetTableMetaFromCache(struct SCatalog* pCatalog, const SName* pTableName, STableMeta** pTableMeta, int32_t *exist) { if (NULL == pCatalog->tableCache.cache) { *exist = 0; + ctgWarn("empty tablemeta cache, tbName:%s", pTableName->tname); return TSDB_CODE_SUCCESS; } @@ -101,12 +137,17 @@ int32_t ctgGetTableMetaFromCache(struct SCatalog* pCatalog, const SName* pTableN if (NULL == *pTableMeta) { *exist = 0; + ctgDebug("tablemeta not in cache, tbName:%s", tbFullName); return TSDB_CODE_SUCCESS; } *exist = 1; + + tbMeta = *pTableMeta; if (tbMeta->tableType != TSDB_CHILD_TABLE) { + ctgDebug("Got tablemeta from cache, tbName:%s", tbFullName); + return TSDB_CODE_SUCCESS; } @@ -115,7 +156,7 @@ int32_t ctgGetTableMetaFromCache(struct SCatalog* pCatalog, const SName* pTableN STableMeta **stbMeta = taosHashGet(pCatalog->tableCache.stableCache, &tbMeta->suid, sizeof(tbMeta->suid)); if (NULL == stbMeta || NULL == *stbMeta) { CTG_UNLOCK(CTG_READ, &pCatalog->tableCache.stableLock); - qError("no stable:%"PRIx64 " meta in cache", tbMeta->suid); + ctgError("stable not in stableCache, suid:%"PRIx64, tbMeta->suid); tfree(*pTableMeta); *exist = 0; return TSDB_CODE_SUCCESS; @@ -124,7 +165,7 @@ int32_t ctgGetTableMetaFromCache(struct SCatalog* pCatalog, const SName* pTableN if ((*stbMeta)->suid != tbMeta->suid) { CTG_UNLOCK(CTG_READ, &pCatalog->tableCache.stableLock); tfree(*pTableMeta); - ctgError("stable cache error, expected suid:%"PRId64 ",actual suid:%"PRId64, tbMeta->suid, (*stbMeta)->suid); + ctgError("stable suid in stableCache mis-match, expected suid:%"PRIx64 ",actual suid:%"PRIx64, tbMeta->suid, (*stbMeta)->suid); CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); } @@ -132,17 +173,47 @@ int32_t ctgGetTableMetaFromCache(struct SCatalog* pCatalog, const SName* pTableN *pTableMeta = realloc(*pTableMeta, metaSize); if (NULL == *pTableMeta) { CTG_UNLOCK(CTG_READ, &pCatalog->tableCache.stableLock); - ctgError("calloc size[%d] failed", metaSize); + ctgError("realloc size[%d] failed", metaSize); CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); } memcpy(&(*pTableMeta)->sversion, &(*stbMeta)->sversion, metaSize - sizeof(SCTableMeta)); CTG_UNLOCK(CTG_READ, &pCatalog->tableCache.stableLock); + + ctgDebug("Got tablemeta from cache, tbName:%s", tbFullName); return TSDB_CODE_SUCCESS; } +int32_t ctgGetTableTypeFromCache(struct SCatalog* pCatalog, const SName* pTableName, int32_t *tbType) { + if (NULL == pCatalog->tableCache.cache) { + ctgWarn("empty tablemeta cache, tbName:%s", pTableName->tname); + return TSDB_CODE_SUCCESS; + } + + char tbFullName[TSDB_TABLE_FNAME_LEN]; + tNameExtractFullName(pTableName, tbFullName); + + size_t sz = 0; + STableMeta *pTableMeta = NULL; + + taosHashGetCloneExt(pCatalog->tableCache.cache, tbFullName, strlen(tbFullName), NULL, (void **)&pTableMeta, &sz); + + if (NULL == pTableMeta) { + ctgWarn("tablemeta not in cache, tbName:%s", tbFullName); + + return TSDB_CODE_SUCCESS; + } + + *tbType = pTableMeta->tableType; + + ctgDebug("Got tabletype from cache, tbName:%s, type:%d", tbFullName, *tbType); + + return TSDB_CODE_SUCCESS; +} + + void ctgGenEpSet(SEpSet *epSet, SVgroupInfo *vgroupInfo) { epSet->inUse = 0; epSet->numOfEps = vgroupInfo->numOfEps; @@ -153,20 +224,19 @@ void ctgGenEpSet(SEpSet *epSet, SVgroupInfo *vgroupInfo) { } } -int32_t ctgGetTableMetaFromMnode(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, STableMetaOutput* output) { - if (NULL == pCatalog || NULL == pRpc || NULL == pMgmtEps || NULL == pTableName || NULL == output) { - CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); - } - - char tbFullName[TSDB_TABLE_FNAME_LEN]; - tNameExtractFullName(pTableName, tbFullName); - +int32_t ctgGetTableMetaFromMnodeImpl(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, char* tbFullName, STableMetaOutput* output) { SBuildTableMetaInput bInput = {.vgId = 0, .dbName = NULL, .tableFullName = tbFullName}; char *msg = NULL; SEpSet *pVnodeEpSet = NULL; int32_t msgLen = 0; - CTG_ERR_RET(queryBuildMsg[TMSG_INDEX(TDMT_MND_STB_META)](&bInput, &msg, 0, &msgLen)); + ctgDebug("try to get table meta from mnode, tbName:%s", tbFullName); + + int32_t code = queryBuildMsg[TMSG_INDEX(TDMT_MND_STB_META)](&bInput, &msg, 0, &msgLen); + if (code) { + ctgError("Build mnode stablemeta msg failed, code:%x", code); + CTG_ERR_RET(code); + } SRpcMsg rpcMsg = { .msgType = TDMT_MND_STB_META, @@ -176,33 +246,57 @@ int32_t ctgGetTableMetaFromMnode(struct SCatalog* pCatalog, void *pRpc, const SE SRpcMsg rpcRsp = {0}; - rpcSendRecv(pRpc, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp); + rpcSendRecv(pTransporter, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp); if (TSDB_CODE_SUCCESS != rpcRsp.code) { - ctgError("error rsp for table meta, code:%x", rpcRsp.code); + if (CTG_TABLE_NOT_EXIST(rpcRsp.code)) { + SET_META_TYPE_NONE(output->metaType); + ctgDebug("stablemeta not exist in mnode, tbName:%s", tbFullName); + return TSDB_CODE_SUCCESS; + } + + ctgError("error rsp for stablemeta from mnode, code:%x, tbName:%s", rpcRsp.code, tbFullName); CTG_ERR_RET(rpcRsp.code); } - CTG_ERR_RET(queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_STB_META)](output, rpcRsp.pCont, rpcRsp.contLen)); + code = queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_STB_META)](output, rpcRsp.pCont, rpcRsp.contLen); + if (code) { + ctgError("Process mnode stablemeta rsp failed, code:%x, tbName:%s", code, tbFullName); + CTG_ERR_RET(code); + } + + ctgDebug("Got table meta from mnode, tbName:%s", tbFullName); return TSDB_CODE_SUCCESS; } +int32_t ctgGetTableMetaFromMnode(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMetaOutput* output) { + char tbFullName[TSDB_TABLE_FNAME_LEN]; + tNameExtractFullName(pTableName, tbFullName); -int32_t ctgGetTableMetaFromVnode(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, SVgroupInfo *vgroupInfo, STableMetaOutput* output) { - if (NULL == pCatalog || NULL == pRpc || NULL == pMgmtEps || NULL == pTableName || NULL == vgroupInfo || NULL == output) { + return ctgGetTableMetaFromMnodeImpl(pCatalog, pTransporter, pMgmtEps, tbFullName, output); +} + +int32_t ctgGetTableMetaFromVnode(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, SVgroupInfo *vgroupInfo, STableMetaOutput* output) { + if (NULL == pCatalog || NULL == pTransporter || NULL == pMgmtEps || NULL == pTableName || NULL == vgroupInfo || NULL == output) { CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); } char dbFullName[TSDB_DB_FNAME_LEN]; tNameGetFullDbName(pTableName, dbFullName); - SBuildTableMetaInput bInput = {.vgId = vgroupInfo->vgId, .dbName = dbFullName, .tableFullName = pTableName->tname}; + ctgDebug("try to get table meta from vnode, db:%s, tbName:%s", dbFullName, pTableName->tname); + + SBuildTableMetaInput bInput = {.vgId = vgroupInfo->vgId, .dbName = dbFullName, .tableFullName = (char *)pTableName->tname}; char *msg = NULL; SEpSet *pVnodeEpSet = NULL; int32_t msgLen = 0; - CTG_ERR_RET(queryBuildMsg[TMSG_INDEX(TDMT_VND_TABLE_META)](&bInput, &msg, 0, &msgLen)); + int32_t code = queryBuildMsg[TMSG_INDEX(TDMT_VND_TABLE_META)](&bInput, &msg, 0, &msgLen); + if (code) { + ctgError("Build vnode tablemeta msg failed, code:%x, tbName:%s", code, pTableName->tname); + CTG_ERR_RET(code); + } SRpcMsg rpcMsg = { .msgType = TDMT_VND_TABLE_META, @@ -214,15 +308,26 @@ int32_t ctgGetTableMetaFromVnode(struct SCatalog* pCatalog, void *pRpc, const SE SEpSet epSet; ctgGenEpSet(&epSet, vgroupInfo); - - rpcSendRecv(pRpc, &epSet, &rpcMsg, &rpcRsp); + rpcSendRecv(pTransporter, &epSet, &rpcMsg, &rpcRsp); if (TSDB_CODE_SUCCESS != rpcRsp.code) { - ctgError("error rsp for table meta, code:%x", rpcRsp.code); + if (CTG_TABLE_NOT_EXIST(rpcRsp.code)) { + SET_META_TYPE_NONE(output->metaType); + ctgDebug("tablemeta not exist in vnode, tbName:%s", pTableName->tname); + return TSDB_CODE_SUCCESS; + } + + ctgError("error rsp for table meta from vnode, code:%x, tbName:%s", rpcRsp.code, pTableName->tname); CTG_ERR_RET(rpcRsp.code); } - CTG_ERR_RET(queryProcessMsgRsp[TMSG_INDEX(TDMT_VND_TABLE_META)](output, rpcRsp.pCont, rpcRsp.contLen)); + code = queryProcessMsgRsp[TMSG_INDEX(TDMT_VND_TABLE_META)](output, rpcRsp.pCont, rpcRsp.contLen); + if (code) { + ctgError("Process vnode tablemeta rsp failed, code:%x, tbName:%s", code, pTableName->tname); + CTG_ERR_RET(code); + } + + ctgDebug("Got table meta from vnode, db:%s, tbName:%s", dbFullName, pTableName->tname); return TSDB_CODE_SUCCESS; } @@ -243,10 +348,11 @@ int32_t ctgGetVgInfoFromDB(struct SCatalog *pCatalog, void *pRpc, const SEpSet * SVgroupInfo *vgInfo = NULL; SArray *vgList = NULL; int32_t code = 0; + int32_t vgNum = taosHashGetSize(dbInfo->vgInfo); - vgList = taosArrayInit(taosHashGetSize(dbInfo->vgInfo), sizeof(SVgroupInfo)); + vgList = taosArrayInit(vgNum, sizeof(SVgroupInfo)); if (NULL == vgList) { - ctgError("taosArrayInit failed"); + ctgError("taosArrayInit failed, num:%d", vgNum); CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); } @@ -255,7 +361,7 @@ int32_t ctgGetVgInfoFromDB(struct SCatalog *pCatalog, void *pRpc, const SEpSet * vgInfo = pIter; if (NULL == taosArrayPush(vgList, vgInfo)) { - ctgError("taosArrayPush failed"); + ctgError("taosArrayPush failed, vgId:%d", vgInfo->vgId); CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } @@ -266,6 +372,8 @@ int32_t ctgGetVgInfoFromDB(struct SCatalog *pCatalog, void *pRpc, const SEpSet * *vgroupList = vgList; vgList = NULL; + ctgDebug("Got vg list from DB, vgNum:%d", vgNum); + return TSDB_CODE_SUCCESS; _return: @@ -277,7 +385,7 @@ _return: CTG_RET(code); } -int32_t ctgGetVgInfoFromHashValue(SDBVgroupInfo *dbInfo, const SName *pTableName, SVgroupInfo *pVgroup) { +int32_t ctgGetVgInfoFromHashValue(struct SCatalog *pCatalog, SDBVgroupInfo *dbInfo, const SName *pTableName, SVgroupInfo *pVgroup) { int32_t code = 0; int32_t vgNum = taosHashGetSize(dbInfo->vgInfo); @@ -285,7 +393,7 @@ int32_t ctgGetVgInfoFromHashValue(SDBVgroupInfo *dbInfo, const SName *pTableName tNameGetFullDbName(pTableName, db); if (vgNum <= 0) { - ctgError("db[%s] vgroup cache invalid, vgroup number:%d", db, vgNum); + ctgError("db vgroup cache invalid, db:%s, vgroup number:%d", db, vgNum); CTG_ERR_RET(TSDB_CODE_TSC_DB_NOT_SELECTED); } @@ -303,6 +411,7 @@ int32_t ctgGetVgInfoFromHashValue(SDBVgroupInfo *dbInfo, const SName *pTableName while (pIter) { vgInfo = pIter; if (hashValue >= vgInfo->hashBegin && hashValue <= vgInfo->hashEnd) { + taosHashCancelIterate(dbInfo->vgInfo, pIter); break; } @@ -311,140 +420,311 @@ int32_t ctgGetVgInfoFromHashValue(SDBVgroupInfo *dbInfo, const SName *pTableName } if (NULL == vgInfo) { - ctgError("no hash range found for hashvalue[%u]", hashValue); + ctgError("no hash range found for hash value [%u], db:%s, numOfVgId:%d", hashValue, db, taosHashGetSize(dbInfo->vgInfo)); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); } *pVgroup = *vgInfo; _return: - - CTG_RET(TSDB_CODE_SUCCESS); + CTG_RET(code); } -int32_t ctgGetTableMetaImpl(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, bool forceUpdate, STableMeta** pTableMeta) { - if (NULL == pCatalog || NULL == pRpc || NULL == pMgmtEps || NULL == pTableName || NULL == pTableMeta) { - CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); +int32_t ctgSTableVersionCompare(const void* key1, const void* key2) { + if (((SSTableMetaVersion*)key1)->suid < ((SSTableMetaVersion*)key2)->suid) { + return -1; + } else if (((SSTableMetaVersion*)key1)->suid > ((SSTableMetaVersion*)key2)->suid) { + return 1; + } else { + return 0; } +} + +int32_t ctgDbVgVersionCompare(const void* key1, const void* key2) { + if (((SDbVgVersion*)key1)->dbId < ((SDbVgVersion*)key2)->dbId) { + return -1; + } else if (((SDbVgVersion*)key1)->dbId > ((SDbVgVersion*)key2)->dbId) { + return 1; + } else { + return 0; + } +} + + +int32_t ctgMetaRentInit(SMetaRentMgmt *mgmt, uint32_t rentSec, int8_t type) { + mgmt->slotRIdx = 0; + mgmt->slotNum = rentSec / CTG_RENT_SLOT_SECOND; + mgmt->type = type; + + size_t msgSize = sizeof(SRentSlotInfo) * mgmt->slotNum; - int32_t exist = 0; - - if (!forceUpdate) { - CTG_ERR_RET(ctgGetTableMetaFromCache(pCatalog, pTableName, pTableMeta, &exist)); - - if (exist) { - return TSDB_CODE_SUCCESS; - } + mgmt->slots = calloc(1, msgSize); + if (NULL == mgmt->slots) { + qError("calloc %d failed", (int32_t)msgSize); + return TSDB_CODE_CTG_MEM_ERROR; } - CTG_ERR_RET(catalogRenewTableMeta(pCatalog, pRpc, pMgmtEps, pTableName)); - - CTG_ERR_RET(ctgGetTableMetaFromCache(pCatalog, pTableName, pTableMeta, &exist)); - - if (0 == exist) { - ctgError("get table meta from cache failed, but fetch succeed"); - CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); - } + qDebug("meta rent initialized, type:%d, slotNum:%d", type, mgmt->slotNum); return TSDB_CODE_SUCCESS; } -int32_t ctgUpdateTableMetaCache(struct SCatalog *pCatalog, STableMetaOutput *output) { +int32_t ctgMetaRentAdd(SMetaRentMgmt *mgmt, void *meta, int64_t id, int32_t size) { + int16_t widx = abs(id % mgmt->slotNum); + + SRentSlotInfo *slot = &mgmt->slots[widx]; int32_t code = 0; - if (output->metaNum != 1 && output->metaNum != 2) { - ctgError("invalid table meta number[%d] got from meta rsp", output->metaNum); - CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); - } - - if (NULL == output->tbMeta) { - ctgError("no valid table meta got from meta rsp"); - CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); - } - - if (NULL == pCatalog->tableCache.cache) { - pCatalog->tableCache.cache = taosHashInit(ctgMgmt.cfg.maxTblCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); - if (NULL == pCatalog->tableCache.cache) { - ctgError("init hash[%d] for tablemeta cache failed", ctgMgmt.cfg.maxTblCacheNum); - CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + CTG_LOCK(CTG_WRITE, &slot->lock); + if (NULL == slot->meta) { + slot->meta = taosArrayInit(CTG_DEFAULT_RENT_SLOT_SIZE, size); + if (NULL == slot->meta) { + qError("taosArrayInit %d failed, id:%"PRIx64", slot idx:%d, type:%d", CTG_DEFAULT_RENT_SLOT_SIZE, id, widx, mgmt->type); + CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } } - if (NULL == pCatalog->tableCache.stableCache) { - pCatalog->tableCache.stableCache = taosHashInit(ctgMgmt.cfg.maxTblCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), true, HASH_ENTRY_LOCK); - if (NULL == pCatalog->tableCache.stableCache) { - ctgError("init hash[%d] for stablemeta cache failed", ctgMgmt.cfg.maxTblCacheNum); - CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); - } + if (NULL == taosArrayPush(slot->meta, meta)) { + qError("taosArrayPush meta to rent failed, id:%"PRIx64", slot idx:%d, type:%d", id, widx, mgmt->type); + CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } - if (output->metaNum == 2) { - if (taosHashPut(pCatalog->tableCache.cache, output->ctbFname, strlen(output->ctbFname), &output->ctbMeta, sizeof(output->ctbMeta)) != 0) { - ctgError("push ctable[%s] to table cache failed", output->ctbFname); - CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); - } + slot->needSort = true; - if (TSDB_SUPER_TABLE != output->tbMeta->tableType) { - ctgError("table type[%d] error, expected:%d", output->tbMeta->tableType, TSDB_SUPER_TABLE); - CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); - } + qDebug("add meta to rent, id:%"PRIx64", slot idx:%d, type:%d", id, widx, mgmt->type); + +_return: + + CTG_UNLOCK(CTG_WRITE, &slot->lock); + CTG_RET(code); +} + +int32_t ctgMetaRentUpdate(SMetaRentMgmt *mgmt, void *meta, int64_t id, int32_t size, __compar_fn_t compare) { + int16_t widx = abs(id % mgmt->slotNum); + + SRentSlotInfo *slot = &mgmt->slots[widx]; + int32_t code = 0; + + CTG_LOCK(CTG_WRITE, &slot->lock); + if (NULL == slot->meta) { + qError("meta in slot is empty, id:%"PRIx64", slot idx:%d, type:%d", id, widx, mgmt->type); + CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } - int32_t tbSize = sizeof(*output->tbMeta) + sizeof(SSchema) * (output->tbMeta->tableInfo.numOfColumns + output->tbMeta->tableInfo.numOfTags); + if (slot->needSort) { + taosArraySort(slot->meta, compare); + slot->needSort = false; + qDebug("slot meta sorted, slot idx:%d, type:%d", widx, mgmt->type); + } - if (TSDB_SUPER_TABLE == output->tbMeta->tableType) { - CTG_LOCK(CTG_WRITE, &pCatalog->tableCache.stableLock); - if (taosHashPut(pCatalog->tableCache.cache, output->tbFname, strlen(output->tbFname), output->tbMeta, tbSize) != 0) { - CTG_UNLOCK(CTG_WRITE, &pCatalog->tableCache.stableLock); - ctgError("push table[%s] to table cache failed", output->tbFname); - CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); - } + void *orig = taosArraySearch(slot->meta, &id, compare, TD_EQ); + if (NULL == orig) { + qError("meta not found in slot, id:%"PRIx64", slot idx:%d, type:%d", id, widx, mgmt->type); + CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); + } - STableMeta *tbMeta = taosHashGet(pCatalog->tableCache.cache, output->tbFname, strlen(output->tbFname)); - if (taosHashPut(pCatalog->tableCache.stableCache, &output->tbMeta->suid, sizeof(output->tbMeta->suid), &tbMeta, POINTER_BYTES) != 0) { - CTG_UNLOCK(CTG_WRITE, &pCatalog->tableCache.stableLock); - ctgError("push suid[%"PRIu64"] to stable cache failed", output->tbMeta->suid); - CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); - } - CTG_UNLOCK(CTG_WRITE, &pCatalog->tableCache.stableLock); - } else { - if (taosHashPut(pCatalog->tableCache.cache, output->tbFname, strlen(output->tbFname), output->tbMeta, tbSize) != 0) { - ctgError("push table[%s] to table cache failed", output->tbFname); - CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); - } + memcpy(orig, meta, size); + + qDebug("meta in rent updated, id:%"PRIx64", slot idx:%d, type:%d", id, widx, mgmt->type); + +_return: + + CTG_UNLOCK(CTG_WRITE, &slot->lock); + + if (code) { + qWarn("meta in rent update failed, will try to add it, code:%x, id:%"PRIx64", slot idx:%d, type:%d", code, id, widx, mgmt->type); + CTG_RET(ctgMetaRentAdd(mgmt, meta, id, size)); } CTG_RET(code); } +int32_t ctgMetaRentGetImpl(SMetaRentMgmt *mgmt, void **res, uint32_t *num, int32_t size) { + int16_t ridx = atomic_add_fetch_16(&mgmt->slotRIdx, 1); + if (ridx >= mgmt->slotNum) { + ridx %= mgmt->slotNum; + atomic_store_16(&mgmt->slotRIdx, ridx); + } -int32_t ctgGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* dbName, int32_t forceUpdate, SDBVgroupInfo** dbInfo) { + SRentSlotInfo *slot = &mgmt->slots[ridx]; + int32_t code = 0; + + CTG_LOCK(CTG_READ, &slot->lock); + if (NULL == slot->meta) { + qDebug("empty meta in slot:%d, type:%d", ridx, mgmt->type); + *num = 0; + goto _return; + } + + size_t metaNum = taosArrayGetSize(slot->meta); + if (metaNum <= 0) { + qDebug("no meta in slot:%d, type:%d", ridx, mgmt->type); + *num = 0; + goto _return; + } + + size_t msize = metaNum * size; + *res = malloc(msize); + if (NULL == *res) { + qError("malloc %d failed", (int32_t)msize); + CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); + } + + void *meta = taosArrayGet(slot->meta, 0); + + memcpy(*res, meta, msize); + + *num = (uint32_t)metaNum; + + qDebug("Got %d meta from rent, type:%d", (int32_t)metaNum, mgmt->type); + +_return: + + CTG_UNLOCK(CTG_READ, &slot->lock); + + CTG_RET(code); +} + +int32_t ctgMetaRentGet(SMetaRentMgmt *mgmt, void **res, uint32_t *num, int32_t size) { + while (true) { + int64_t msec = taosGetTimestampMs(); + int64_t lsec = atomic_load_64(&mgmt->lastReadMsec); + if ((msec - lsec) < CTG_RENT_SLOT_SECOND * 1000) { + *res = NULL; + *num = 0; + qDebug("too short time period to get expired meta, type:%d", mgmt->type); + return TSDB_CODE_SUCCESS; + } + + if (lsec != atomic_val_compare_exchange_64(&mgmt->lastReadMsec, lsec, msec)) { + continue; + } + + break; + } + + CTG_ERR_RET(ctgMetaRentGetImpl(mgmt, res, num, size)); + + return TSDB_CODE_SUCCESS; +} + + + +int32_t ctgUpdateTableMetaCache(struct SCatalog *pCatalog, STableMetaOutput *output) { + int32_t code = 0; + + if (NULL == output->tbMeta) { + ctgError("no valid table meta got from meta rsp, tbName:%s", output->tbFname); + CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); + } + + if (NULL == pCatalog->tableCache.cache) { + SHashObj *cache = taosHashInit(ctgMgmt.cfg.maxTblCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + if (NULL == cache) { + ctgError("taosHashInit failed, num:%d", ctgMgmt.cfg.maxTblCacheNum); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + + if (NULL != atomic_val_compare_exchange_ptr(&pCatalog->tableCache.cache, NULL, cache)) { + taosHashCleanup(cache); + } + } + + if (NULL == pCatalog->tableCache.stableCache) { + SHashObj *cache = taosHashInit(ctgMgmt.cfg.maxTblCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), true, HASH_ENTRY_LOCK); + if (NULL == cache) { + ctgError("taosHashInit failed, num:%d", ctgMgmt.cfg.maxTblCacheNum); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + + if (NULL != atomic_val_compare_exchange_ptr(&pCatalog->tableCache.stableCache, NULL, cache)) { + taosHashCleanup(cache); + } + } + + if (CTG_IS_META_CTABLE(output->metaType) || CTG_IS_META_BOTH(output->metaType)) { + if (taosHashPut(pCatalog->tableCache.cache, output->ctbFname, strlen(output->ctbFname), &output->ctbMeta, sizeof(output->ctbMeta)) != 0) { + ctgError("taosHashPut ctablemeta to cache failed, ctbName:%s", output->ctbFname); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + + ctgDebug("update child tablemeta to cache, tbName:%s", output->ctbFname); + } + + if (CTG_IS_META_CTABLE(output->metaType)) { + return TSDB_CODE_SUCCESS; + } + + if (CTG_IS_META_BOTH(output->metaType) && TSDB_SUPER_TABLE != output->tbMeta->tableType) { + ctgError("table type error, expected:%d, actual:%d", TSDB_SUPER_TABLE, output->tbMeta->tableType); + CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); + } + + int32_t tbSize = sizeof(*output->tbMeta) + sizeof(SSchema) * (output->tbMeta->tableInfo.numOfColumns + output->tbMeta->tableInfo.numOfTags); + + if (TSDB_SUPER_TABLE == output->tbMeta->tableType) { + bool newAdded = false; + SSTableMetaVersion metaRent = {.suid = output->tbMeta->suid, .sversion = output->tbMeta->sversion, .tversion = output->tbMeta->tversion}; + + CTG_LOCK(CTG_WRITE, &pCatalog->tableCache.stableLock); + if (taosHashPut(pCatalog->tableCache.cache, output->tbFname, strlen(output->tbFname), output->tbMeta, tbSize) != 0) { + CTG_UNLOCK(CTG_WRITE, &pCatalog->tableCache.stableLock); + ctgError("taosHashPut tablemeta to cache failed, tbName:%s", output->tbFname); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + + STableMeta *tbMeta = taosHashGet(pCatalog->tableCache.cache, output->tbFname, strlen(output->tbFname)); + if (taosHashPutExt(pCatalog->tableCache.stableCache, &output->tbMeta->suid, sizeof(output->tbMeta->suid), &tbMeta, POINTER_BYTES, &newAdded) != 0) { + CTG_UNLOCK(CTG_WRITE, &pCatalog->tableCache.stableLock); + ctgError("taosHashPutExt stable to stable cache failed, suid:%"PRIx64, output->tbMeta->suid); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + CTG_UNLOCK(CTG_WRITE, &pCatalog->tableCache.stableLock); + + ctgDebug("update stable to cache, suid:%"PRIx64, output->tbMeta->suid); + + if (newAdded) { + CTG_ERR_RET(ctgMetaRentAdd(&pCatalog->stableRent, &metaRent, metaRent.suid, sizeof(SSTableMetaVersion))); + } else { + CTG_ERR_RET(ctgMetaRentUpdate(&pCatalog->stableRent, &metaRent, metaRent.suid, sizeof(SSTableMetaVersion), ctgSTableVersionCompare)); + } + } else { + if (taosHashPut(pCatalog->tableCache.cache, output->tbFname, strlen(output->tbFname), output->tbMeta, tbSize) != 0) { + ctgError("taosHashPut tablemeta to cache failed, tbName:%s", output->tbFname); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + } + + ctgDebug("update tablemeta to cache, tbName:%s", output->tbFname); + + CTG_RET(code); +} + +int32_t ctgGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* dbName, bool forceUpdate, SDBVgroupInfo** dbInfo) { bool inCache = false; - if (0 == forceUpdate) { + if (!forceUpdate) { CTG_ERR_RET(ctgGetDBVgroupFromCache(pCatalog, dbName, dbInfo, &inCache)); - if (inCache) { return TSDB_CODE_SUCCESS; } + + ctgDebug("failed to get DB vgroupInfo from cache, dbName:%s, load it from mnode, update:%d", dbName, forceUpdate); } SUseDbOutput DbOut = {0}; SBuildUseDBInput input = {0}; - strncpy(input.db, dbName, sizeof(input.db)); - input.db[sizeof(input.db) - 1] = 0; + tstrncpy(input.db, dbName, tListLen(input.db)); input.vgVersion = CTG_DEFAULT_INVALID_VERSION; while (true) { CTG_ERR_RET(ctgGetDBVgroupFromMnode(pCatalog, pRpc, pMgmtEps, &input, &DbOut)); - CTG_ERR_RET(catalogUpdateDBVgroup(pCatalog, dbName, &DbOut.dbVgroup)); - CTG_ERR_RET(ctgGetDBVgroupFromCache(pCatalog, dbName, dbInfo, &inCache)); if (!inCache) { - ctgWarn("get db vgroup from cache failed, db:%s", dbName); + ctgWarn("can't get db vgroup from cache, will retry, db:%s", dbName); continue; } @@ -460,7 +740,7 @@ int32_t ctgValidateAndRemoveDb(struct SCatalog* pCatalog, const char* dbName, SD if (oldInfo) { CTG_LOCK(CTG_WRITE, &oldInfo->lock); if (dbInfo->vgVersion <= oldInfo->vgVersion) { - ctgInfo("dbName:%s vg will not update, vgVersion:%d , current:%d", dbName, dbInfo->vgVersion, oldInfo->vgVersion); + ctgInfo("db vgVersion is not new, db:%s, vgVersion:%d, current:%d", dbName, dbInfo->vgVersion, oldInfo->vgVersion); CTG_UNLOCK(CTG_WRITE, &oldInfo->lock); taosHashRelease(pCatalog->dbCache.cache, oldInfo); @@ -468,7 +748,7 @@ int32_t ctgValidateAndRemoveDb(struct SCatalog* pCatalog, const char* dbName, SD } if (oldInfo->vgInfo) { - ctgInfo("dbName:%s vg will be cleanup", dbName); + ctgInfo("cleanup db vgInfo, db:%s", dbName); taosHashCleanup(oldInfo->vgInfo); oldInfo->vgInfo = NULL; } @@ -481,10 +761,174 @@ int32_t ctgValidateAndRemoveDb(struct SCatalog* pCatalog, const char* dbName, SD return TSDB_CODE_SUCCESS; } +int32_t ctgRenewTableMetaImpl(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, int32_t isSTable) { + if (NULL == pCatalog || NULL == pTransporter || NULL == pMgmtEps || NULL == pTableName) { + CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); + } + + SVgroupInfo vgroupInfo = {0}; + int32_t code = 0; + + CTG_ERR_RET(catalogGetTableHashVgroup(pCatalog, pTransporter, pMgmtEps, pTableName, &vgroupInfo)); + + STableMetaOutput voutput = {0}; + STableMetaOutput moutput = {0}; + STableMetaOutput *output = &voutput; + + if (CTG_IS_STABLE(isSTable)) { + ctgDebug("will renew table meta, supposed to be stable, tbName:%s", pTableName->tname); + + // if get from mnode failed, will not try vnode + CTG_ERR_JRET(ctgGetTableMetaFromMnode(pCatalog, pTransporter, pMgmtEps, pTableName, &moutput)); + + if (CTG_IS_META_NONE(moutput.metaType)) { + CTG_ERR_JRET(ctgGetTableMetaFromVnode(pCatalog, pTransporter, pMgmtEps, pTableName, &vgroupInfo, &voutput)); + } else { + output = &moutput; + } + } else { + ctgDebug("will renew table meta, not supposed to be stable, tbName:%s, isStable:%d", pTableName->tname, isSTable); + + // if get from vnode failed or no table meta, will not try mnode + CTG_ERR_JRET(ctgGetTableMetaFromVnode(pCatalog, pTransporter, pMgmtEps, pTableName, &vgroupInfo, &voutput)); + + if (CTG_IS_META_TABLE(voutput.metaType) && TSDB_SUPER_TABLE == voutput.tbMeta->tableType) { + ctgDebug("will continue to renew table meta since got stable, tbName:%s, metaType:%d", pTableName->tname, voutput.metaType); + + CTG_ERR_JRET(ctgGetTableMetaFromMnodeImpl(pCatalog, pTransporter, pMgmtEps, voutput.tbFname, &moutput)); + + tfree(voutput.tbMeta); + voutput.tbMeta = moutput.tbMeta; + moutput.tbMeta = NULL; + } else if (CTG_IS_META_BOTH(voutput.metaType)) { + int32_t exist = 0; + CTG_ERR_JRET(ctgIsTableMetaExistInCache(pCatalog, voutput.tbFname, &exist)); + if (0 == exist) { + CTG_ERR_JRET(ctgGetTableMetaFromMnodeImpl(pCatalog, pTransporter, pMgmtEps, voutput.tbFname, &moutput)); + + if (CTG_IS_META_NONE(moutput.metaType)) { + SET_META_TYPE_NONE(voutput.metaType); + } + + tfree(voutput.tbMeta); + voutput.tbMeta = moutput.tbMeta; + moutput.tbMeta = NULL; + } else { + SET_META_TYPE_CTABLE(voutput.metaType); + } + } + } + + if (CTG_IS_META_NONE(output->metaType)) { + ctgError("no tablemeta got, tbNmae:%s", pTableName->tname); + CTG_ERR_JRET(CTG_ERR_CODE_TABLE_NOT_EXIST); + } + + CTG_ERR_JRET(ctgUpdateTableMetaCache(pCatalog, output)); + +_return: + + tfree(voutput.tbMeta); + tfree(moutput.tbMeta); + + CTG_RET(code); +} + +int32_t ctgGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, bool forceUpdate, STableMeta** pTableMeta, int32_t isSTable) { + if (NULL == pCatalog || NULL == pRpc || NULL == pMgmtEps || NULL == pTableName || NULL == pTableMeta) { + CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); + } + + int32_t exist = 0; + + if (!forceUpdate) { + CTG_ERR_RET(ctgGetTableMetaFromCache(pCatalog, pTableName, pTableMeta, &exist)); + + if (exist && CTG_TBTYPE_MATCH(isSTable, (*pTableMeta)->tableType)) { + return TSDB_CODE_SUCCESS; + } + } else if (CTG_IS_UNKNOWN_STABLE(isSTable)) { + int32_t tbType = 0; + + CTG_ERR_RET(ctgGetTableTypeFromCache(pCatalog, pTableName, &tbType)); + + CTG_SET_STABLE(isSTable, tbType); + } + + CTG_ERR_RET(ctgRenewTableMetaImpl(pCatalog, pRpc, pMgmtEps, pTableName, isSTable)); + + CTG_ERR_RET(ctgGetTableMetaFromCache(pCatalog, pTableName, pTableMeta, &exist)); + + if (0 == exist) { + ctgError("renew tablemeta succeed but get from cache failed, may be deleted, tbName:%s", pTableName->tname); + CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); + } + + return TSDB_CODE_SUCCESS; +} + +void ctgFreeMetaRent(SMetaRentMgmt *mgmt) { + if (NULL == mgmt->slots) { + return; + } + + for (int32_t i = 0; i < mgmt->slotNum; ++i) { + SRentSlotInfo *slot = &mgmt->slots[i]; + if (slot->meta) { + taosArrayDestroy(slot->meta); + slot->meta = NULL; + } + } + + tfree(mgmt->slots); +} + +void ctgFreeDbCache(SDBVgroupCache *db) { + if (NULL == db->cache) { + return; + } + + SDBVgroupInfo *dbInfo = NULL; + void *pIter = taosHashIterate(db->cache, NULL); + while (pIter) { + dbInfo = pIter; + + if (dbInfo->vgInfo) { + taosHashCleanup(dbInfo->vgInfo); + dbInfo->vgInfo = NULL; + } + + pIter = taosHashIterate(db->cache, pIter); + } + + taosHashCleanup(db->cache); + db->cache = NULL; +} + +void ctgFreeTableMetaCache(STableMetaCache *table) { + if (table->stableCache) { + taosHashCleanup(table->stableCache); + table->stableCache = NULL; + } + + if (table->cache) { + taosHashCleanup(table->cache); + table->cache = NULL; + } +} + +void ctgFreeHandle(struct SCatalog* pCatalog) { + ctgFreeMetaRent(&pCatalog->dbRent); + ctgFreeMetaRent(&pCatalog->stableRent); + ctgFreeDbCache(&pCatalog->dbCache); + ctgFreeTableMetaCache(&pCatalog->tableCache); + + free(pCatalog); +} int32_t catalogInit(SCatalogCfg *cfg) { if (ctgMgmt.pCluster) { - ctgError("catalog already init"); + qError("catalog already init"); CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); } @@ -498,16 +942,29 @@ int32_t catalogInit(SCatalogCfg *cfg) { if (ctgMgmt.cfg.maxTblCacheNum == 0) { ctgMgmt.cfg.maxTblCacheNum = CTG_DEFAULT_CACHE_TABLEMETA_NUMBER; } + + if (ctgMgmt.cfg.dbRentSec == 0) { + ctgMgmt.cfg.dbRentSec = CTG_DEFAULT_RENT_SECOND; + } + + if (ctgMgmt.cfg.stableRentSec == 0) { + ctgMgmt.cfg.stableRentSec = CTG_DEFAULT_RENT_SECOND; + } } else { ctgMgmt.cfg.maxDBCacheNum = CTG_DEFAULT_CACHE_DB_NUMBER; ctgMgmt.cfg.maxTblCacheNum = CTG_DEFAULT_CACHE_TABLEMETA_NUMBER; + ctgMgmt.cfg.dbRentSec = CTG_DEFAULT_RENT_SECOND; + ctgMgmt.cfg.stableRentSec = CTG_DEFAULT_RENT_SECOND; } - ctgMgmt.pCluster = taosHashInit(CTG_DEFAULT_CACHE_CLUSTER_NUMBER, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_ENTRY_LOCK); + ctgMgmt.pCluster = taosHashInit(CTG_DEFAULT_CACHE_CLUSTER_NUMBER, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK); if (NULL == ctgMgmt.pCluster) { - CTG_ERR_LRET(TSDB_CODE_CTG_INTERNAL_ERROR, "init %d cluster cache failed", CTG_DEFAULT_CACHE_CLUSTER_NUMBER); + qError("taosHashInit %d cluster cache failed", CTG_DEFAULT_CACHE_CLUSTER_NUMBER); + CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); } + qDebug("catalog initialized, maxDb:%u, maxTbl:%u, dbRentSec:%u, stableRentSec:%u", ctgMgmt.cfg.maxDBCacheNum, ctgMgmt.cfg.maxTblCacheNum, ctgMgmt.cfg.dbRentSec, ctgMgmt.cfg.stableRentSec); + return TSDB_CODE_SUCCESS; } @@ -517,32 +974,75 @@ int32_t catalogGetHandle(uint64_t clusterId, struct SCatalog** catalogHandle) { } if (NULL == ctgMgmt.pCluster) { - ctgError("cluster cache are not ready"); + qError("cluster cache are not ready, clusterId:%"PRIx64, clusterId); CTG_ERR_RET(TSDB_CODE_CTG_NOT_READY); } - SCatalog **ctg = (SCatalog **)taosHashGet(ctgMgmt.pCluster, (char*)&clusterId, sizeof(clusterId)); + int32_t code = 0; + SCatalog *clusterCtg = NULL; - if (ctg && (*ctg)) { - *catalogHandle = *ctg; - return TSDB_CODE_SUCCESS; - } + while (true) { + SCatalog **ctg = (SCatalog **)taosHashGet(ctgMgmt.pCluster, (char*)&clusterId, sizeof(clusterId)); - SCatalog *clusterCtg = calloc(1, sizeof(SCatalog)); - if (NULL == clusterCtg) { - ctgError("calloc %d failed", (int32_t)sizeof(SCatalog)); - CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); - } + if (ctg && (*ctg)) { + *catalogHandle = *ctg; + qDebug("got catalog handle from cache, clusterId:%"PRIx64", CTG:%p", clusterId, *ctg); + return TSDB_CODE_SUCCESS; + } - if (taosHashPut(ctgMgmt.pCluster, &clusterId, sizeof(clusterId), &clusterCtg, POINTER_BYTES)) { - ctgError("put cluster %"PRIx64" cache to hash failed", clusterId); - tfree(clusterCtg); - CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); + clusterCtg = calloc(1, sizeof(SCatalog)); + if (NULL == clusterCtg) { + qError("calloc %d failed", (int32_t)sizeof(SCatalog)); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + + clusterCtg->clusterId = clusterId; + + CTG_ERR_JRET(ctgMetaRentInit(&clusterCtg->dbRent, ctgMgmt.cfg.dbRentSec, CTG_RENT_DB)); + CTG_ERR_JRET(ctgMetaRentInit(&clusterCtg->stableRent, ctgMgmt.cfg.stableRentSec, CTG_RENT_STABLE)); + + code = taosHashPut(ctgMgmt.pCluster, &clusterId, sizeof(clusterId), &clusterCtg, POINTER_BYTES); + if (code) { + if (HASH_NODE_EXIST(code)) { + ctgFreeHandle(clusterCtg); + continue; + } + + qError("taosHashPut CTG to cache failed, clusterId:%"PRIx64, clusterId); + CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); + } + + qDebug("add CTG to cache, clusterId:%"PRIx64", CTG:%p", clusterId, clusterCtg); + + break; } *catalogHandle = clusterCtg; return TSDB_CODE_SUCCESS; + +_return: + + ctgFreeHandle(clusterCtg); + + CTG_RET(code); +} + +void catalogFreeHandle(struct SCatalog* pCatalog) { + if (NULL == pCatalog) { + return; + } + + if (taosHashRemove(ctgMgmt.pCluster, &pCatalog->clusterId, sizeof(pCatalog->clusterId))) { + ctgWarn("taosHashRemove from cluster failed, may already be freed, clusterId:%"PRIx64, pCatalog->clusterId); + return; + } + + uint64_t clusterId = pCatalog->clusterId; + + ctgFreeHandle(pCatalog); + + ctgInfo("handle freed, culsterId:%"PRIx64, clusterId); } int32_t catalogGetDBVgroupVersion(struct SCatalog* pCatalog, const char* dbName, int32_t* version) { @@ -552,36 +1052,40 @@ int32_t catalogGetDBVgroupVersion(struct SCatalog* pCatalog, const char* dbName, if (NULL == pCatalog->dbCache.cache) { *version = CTG_DEFAULT_INVALID_VERSION; + ctgInfo("empty db cache, dbName:%s", dbName); return TSDB_CODE_SUCCESS; } SDBVgroupInfo * dbInfo = taosHashAcquire(pCatalog->dbCache.cache, dbName, strlen(dbName)); if (NULL == dbInfo) { *version = CTG_DEFAULT_INVALID_VERSION; + ctgInfo("db not in cache, dbName:%s", dbName); return TSDB_CODE_SUCCESS; } *version = dbInfo->vgVersion; taosHashRelease(pCatalog->dbCache.cache, dbInfo); + ctgDebug("Got db vgVersion from cache, dbName:%s, vgVersion:%d", dbName, *version); + return TSDB_CODE_SUCCESS; } -int32_t catalogGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* dbName, int32_t forceUpdate, SArray** vgroupList) { +int32_t catalogGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* dbName, bool forceUpdate, SArray** vgroupList) { if (NULL == pCatalog || NULL == dbName || NULL == pRpc || NULL == pMgmtEps || NULL == vgroupList) { CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); } - SDBVgroupInfo* db = NULL; - int32_t code = 0; + SDBVgroupInfo* db = NULL; SVgroupInfo *vgInfo = NULL; + + int32_t code = 0; SArray *vgList = NULL; - CTG_ERR_JRET(ctgGetDBVgroup(pCatalog, pRpc, pMgmtEps, dbName, forceUpdate, &db)); vgList = taosArrayInit(taosHashGetSize(db->vgInfo), sizeof(SVgroupInfo)); if (NULL == vgList) { - ctgError("taosArrayInit failed"); + ctgError("taosArrayInit %d failed", taosHashGetSize(db->vgInfo)); CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } @@ -590,7 +1094,7 @@ int32_t catalogGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* vgInfo = pIter; if (NULL == taosArrayPush(vgList, vgInfo)) { - ctgError("taosArrayPush failed"); + ctgError("taosArrayPush failed, vgId:%d", vgInfo->vgId); CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } @@ -602,7 +1106,6 @@ int32_t catalogGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* vgList = NULL; _return: - if (db) { CTG_UNLOCK(CTG_READ, &db->lock); taosHashRelease(pCatalog->dbCache.cache, db); @@ -625,12 +1128,12 @@ int32_t catalogUpdateDBVgroup(struct SCatalog* pCatalog, const char* dbName, SDB } if (NULL == dbInfo->vgInfo || dbInfo->vgVersion < 0 || taosHashGetSize(dbInfo->vgInfo) <= 0) { - ctgError("invalid db vg, dbName:%s", dbName); + ctgError("invalid db vgInfo, dbName:%s, vgInfo:%p, vgVersion:%d", dbName, dbInfo->vgInfo, dbInfo->vgVersion); CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } if (dbInfo->vgVersion < 0) { - ctgWarn("invalid db vgVersion:%d, dbName:%s", dbInfo->vgVersion, dbName); + ctgWarn("db vgVersion less than 0, dbName:%s, vgVersion:%d", dbName, dbInfo->vgVersion); if (pCatalog->dbCache.cache) { CTG_ERR_JRET(ctgValidateAndRemoveDb(pCatalog, dbName, dbInfo)); @@ -638,28 +1141,41 @@ int32_t catalogUpdateDBVgroup(struct SCatalog* pCatalog, const char* dbName, SDB CTG_ERR_JRET(taosHashRemove(pCatalog->dbCache.cache, dbName, strlen(dbName))); } - ctgWarn("remove db [%s] from cache", dbName); + ctgWarn("db removed from cache, db:%s", dbName); goto _return; } if (NULL == pCatalog->dbCache.cache) { - pCatalog->dbCache.cache = taosHashInit(ctgMgmt.cfg.maxDBCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); - if (NULL == pCatalog->dbCache.cache) { - ctgError("init hash[%d] for db cache failed", CTG_DEFAULT_CACHE_DB_NUMBER); + SHashObj *cache = taosHashInit(ctgMgmt.cfg.maxDBCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + if (NULL == cache) { + ctgError("taosHashInit %d failed", CTG_DEFAULT_CACHE_DB_NUMBER); CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } + + if (NULL != atomic_val_compare_exchange_ptr(&pCatalog->dbCache.cache, NULL, cache)) { + taosHashCleanup(cache); + } } else { CTG_ERR_JRET(ctgValidateAndRemoveDb(pCatalog, dbName, dbInfo)); } - if (taosHashPut(pCatalog->dbCache.cache, dbName, strlen(dbName), dbInfo, sizeof(*dbInfo)) != 0) { - ctgError("push to vgroup hash cache failed"); + bool newAdded = false; + if (taosHashPutExt(pCatalog->dbCache.cache, dbName, strlen(dbName), dbInfo, sizeof(*dbInfo), &newAdded) != 0) { + ctgError("taosHashPutExt db vgroup to cache failed, db:%s", dbName); CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } + dbInfo->vgInfo = NULL; + + SDbVgVersion vgVersion = {.dbId = dbInfo->dbId, .vgVersion = dbInfo->vgVersion}; + if (newAdded) { + CTG_ERR_JRET(ctgMetaRentAdd(&pCatalog->dbRent, &vgVersion, dbInfo->dbId, sizeof(SDbVgVersion))); + } else { + CTG_ERR_JRET(ctgMetaRentUpdate(&pCatalog->dbRent, &vgVersion, dbInfo->dbId, sizeof(SDbVgVersion), ctgDbVgVersionCompare)); + } + ctgDebug("dbName:%s vgroup updated, vgVersion:%d", dbName, dbInfo->vgVersion); - dbInfo->vgInfo = NULL; _return: @@ -672,34 +1188,23 @@ _return: } int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta) { - return ctgGetTableMetaImpl(pCatalog, pTransporter, pMgmtEps, pTableName, false, pTableMeta); + return ctgGetTableMeta(pCatalog, pTransporter, pMgmtEps, pTableName, false, pTableMeta, -1); } -int32_t catalogRenewTableMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName) { +int32_t catalogGetSTableMeta(struct SCatalog* pCatalog, void * pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta) { + return ctgGetTableMeta(pCatalog, pTransporter, pMgmtEps, pTableName, false, pTableMeta, 1); +} + +int32_t catalogRenewTableMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, int32_t isSTable) { if (NULL == pCatalog || NULL == pTransporter || NULL == pMgmtEps || NULL == pTableName) { CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); } - SVgroupInfo vgroupInfo = {0}; - int32_t code = 0; - - CTG_ERR_RET(catalogGetTableHashVgroup(pCatalog, pTransporter, pMgmtEps, pTableName, &vgroupInfo)); - - STableMetaOutput output = {0}; - - CTG_ERR_RET(ctgGetTableMetaFromVnode(pCatalog, pTransporter, pMgmtEps, pTableName, &vgroupInfo, &output)); - - //CTG_ERR_RET(ctgGetTableMetaFromMnode(pCatalog, pRpc, pMgmtEps, pTableName, &output)); - - CTG_ERR_JRET(ctgUpdateTableMetaCache(pCatalog, &output)); - -_return: - tfree(output.tbMeta); - CTG_RET(code); + return ctgRenewTableMetaImpl(pCatalog, pTransporter, pMgmtEps, pTableName, isSTable); } -int32_t catalogRenewAndGetTableMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta) { - return ctgGetTableMetaImpl(pCatalog, pTransporter, pMgmtEps, pTableName, true, pTableMeta); +int32_t catalogRenewAndGetTableMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta, int32_t isSTable) { + return ctgGetTableMeta(pCatalog, pTransporter, pMgmtEps, pTableName, true, pTableMeta, isSTable); } int32_t catalogGetTableDistVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, SArray** pVgroupList) { @@ -715,29 +1220,39 @@ int32_t catalogGetTableDistVgroup(struct SCatalog* pCatalog, void *pRpc, const S *pVgroupList = NULL; - CTG_ERR_JRET(catalogGetTableMeta(pCatalog, pRpc, pMgmtEps, pTableName, &tbMeta)); + CTG_ERR_JRET(ctgGetTableMeta(pCatalog, pRpc, pMgmtEps, pTableName, false, &tbMeta, -1)); char db[TSDB_DB_FNAME_LEN] = {0}; tNameGetFullDbName(pTableName, db); CTG_ERR_JRET(ctgGetDBVgroup(pCatalog, pRpc, pMgmtEps, db, false, &dbVgroup)); + // REMOEV THIS .... + if (0 == tbMeta->vgId) { + SVgroupInfo vgroup = {0}; + + catalogGetTableHashVgroup(pCatalog, pRpc, pMgmtEps, pTableName, &vgroup); + + tbMeta->vgId = vgroup.vgId; + } + // REMOVE THIS .... + if (tbMeta->tableType == TSDB_SUPER_TABLE) { CTG_ERR_JRET(ctgGetVgInfoFromDB(pCatalog, pRpc, pMgmtEps, dbVgroup, pVgroupList)); } else { int32_t vgId = tbMeta->vgId; if (NULL == taosHashGetClone(dbVgroup->vgInfo, &vgId, sizeof(vgId), &vgroupInfo)) { - ctgError("vgId[%d] not found in vgroup list", vgId); + ctgError("table's vgId not found in vgroup list, vgId:%d, tbName:%s", vgId, pTableName->tname); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); } vgList = taosArrayInit(1, sizeof(SVgroupInfo)); if (NULL == vgList) { - ctgError("taosArrayInit failed"); + ctgError("taosArrayInit %d failed", (int32_t)sizeof(SVgroupInfo)); CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); } if (NULL == taosArrayPush(vgList, &vgroupInfo)) { - ctgError("push vgroupInfo to array failed"); + ctgError("taosArrayPush vgroupInfo to array failed, vgId:%d, tbName:%s", vgId, pTableName->tname); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); } @@ -771,10 +1286,9 @@ int32_t catalogGetTableHashVgroup(struct SCatalog *pCatalog, void *pTransporter, CTG_ERR_RET(ctgGetDBVgroup(pCatalog, pTransporter, pMgmtEps, db, false, &dbInfo)); - CTG_ERR_JRET(ctgGetVgInfoFromHashValue(dbInfo, pTableName, pVgroup)); + CTG_ERR_JRET(ctgGetVgInfoFromHashValue(pCatalog, dbInfo, pTableName, pVgroup)); _return: - if (dbInfo) { CTG_UNLOCK(CTG_READ, &dbInfo->lock); taosHashRelease(pCatalog->dbCache.cache, dbInfo); @@ -784,8 +1298,8 @@ _return: } -int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SMetaData* pRsp) { - if (NULL == pCatalog || NULL == pRpc || NULL == pMgmtEps || NULL == pReq || NULL == pRsp) { +int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SMetaData* pRsp) { + if (NULL == pCatalog || NULL == pTransporter || NULL == pMgmtEps || NULL == pReq || NULL == pRsp) { CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); } @@ -794,13 +1308,13 @@ int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* p if (pReq->pTableName) { int32_t tbNum = (int32_t)taosArrayGetSize(pReq->pTableName); if (tbNum <= 0) { - ctgError("empty table name list"); + ctgError("empty table name list, tbNum:%d", tbNum); CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); } pRsp->pTableMeta = taosArrayInit(tbNum, POINTER_BYTES); if (NULL == pRsp->pTableMeta) { - ctgError("taosArrayInit num[%d] failed", tbNum); + ctgError("taosArrayInit %d failed", tbNum); CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); } @@ -808,7 +1322,7 @@ int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* p SName *name = taosArrayGet(pReq->pTableName, i); STableMeta *pTableMeta = NULL; - CTG_ERR_JRET(catalogGetTableMeta(pCatalog, pRpc, pMgmtEps, name, &pTableMeta)); + CTG_ERR_JRET(ctgGetTableMeta(pCatalog, pTransporter, pMgmtEps, name, false, &pTableMeta, -1)); if (NULL == taosArrayPush(pRsp->pTableMeta, &pTableMeta)) { ctgError("taosArrayPush failed, idx:%d", i); @@ -821,7 +1335,6 @@ int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* p return TSDB_CODE_SUCCESS; _return: - if (pRsp->pTableMeta) { int32_t aSize = taosArrayGetSize(pRsp->pTableMeta); for (int32_t i = 0; i < aSize; ++i) { @@ -841,16 +1354,49 @@ int32_t catalogGetQnodeList(struct SCatalog* pCatalog, void *pRpc, const SEpSet* CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); } + //TODO return TSDB_CODE_SUCCESS; } +int32_t catalogGetExpiredSTables(struct SCatalog* pCatalog, SSTableMetaVersion **stables, uint32_t *num) { + if (NULL == pCatalog || NULL == stables || NULL == num) { + CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); + } + + CTG_RET(ctgMetaRentGet(&pCatalog->stableRent, (void **)stables, num, sizeof(SSTableMetaVersion))); +} + +int32_t catalogGetExpiredDBs(struct SCatalog* pCatalog, SDbVgVersion **dbs, uint32_t *num) { + if (NULL == pCatalog || NULL == dbs || NULL == num) { + CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); + } + + CTG_RET(ctgMetaRentGet(&pCatalog->dbRent, (void **)dbs, num, sizeof(SDbVgVersion))); +} + void catalogDestroy(void) { - if (ctgMgmt.pCluster) { - taosHashCleanup(ctgMgmt.pCluster); //TBD - ctgMgmt.pCluster = NULL; + if (NULL == ctgMgmt.pCluster) { + return; } + + SCatalog *pCatalog = NULL; + void *pIter = taosHashIterate(ctgMgmt.pCluster, NULL); + while (pIter) { + pCatalog = *(SCatalog **)pIter; + + if (pCatalog) { + catalogFreeHandle(pCatalog); + } + + pIter = taosHashIterate(ctgMgmt.pCluster, pIter); + } + + taosHashCleanup(ctgMgmt.pCluster); + ctgMgmt.pCluster = NULL; + + qInfo("catalog destroyed"); } diff --git a/source/libs/catalog/test/CMakeLists.txt b/source/libs/catalog/test/CMakeLists.txt index 3c7418bdcc..d12e0f310c 100644 --- a/source/libs/catalog/test/CMakeLists.txt +++ b/source/libs/catalog/test/CMakeLists.txt @@ -16,3 +16,8 @@ TARGET_INCLUDE_DIRECTORIES( PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/catalog/" PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/catalog/inc" ) + +add_test( + NAME catalogTest + COMMAND catalogTest +) diff --git a/source/libs/catalog/test/catalogTests.cpp b/source/libs/catalog/test/catalogTests.cpp index 1d8a48dfcb..87a3000d09 100644 --- a/source/libs/catalog/test/catalogTests.cpp +++ b/source/libs/catalog/test/catalogTests.cpp @@ -42,10 +42,13 @@ extern "C" int32_t ctgUpdateTableMetaCache(struct SCatalog *pCatalog, STableMeta void ctgTestSetPrepareTableMeta(); void ctgTestSetPrepareCTableMeta(); void ctgTestSetPrepareSTableMeta(); +void ctgTestSetPrepareMultiSTableMeta(); bool ctgTestStop = false; bool ctgTestEnableSleep = false; -bool ctgTestDeadLoop = true; +bool ctgTestDeadLoop = false; +int32_t ctgTestPrintNum = 200000; +int32_t ctgTestMTRunSec = 30; int32_t ctgTestCurrentVgVersion = 0; int32_t ctgTestVgVersion = 1; @@ -54,6 +57,8 @@ int32_t ctgTestColNum = 2; int32_t ctgTestTagNum = 1; int32_t ctgTestSVersion = 1; int32_t ctgTestTVersion = 1; +int32_t ctgTestSuid = 2; +int64_t ctgTestDbId = 33; uint64_t ctgTestClusterId = 0x1; char *ctgTestDbname = "1.db1"; @@ -63,7 +68,7 @@ char *ctgTestSTablename = "stable1"; void sendCreateDbMsg(void *shandle, SEpSet *pEpSet) { - SCreateDbMsg* pReq = (SCreateDbMsg*)rpcMallocCont(sizeof(SCreateDbMsg)); + SCreateDbReq* pReq = (SCreateDbReq*)rpcMallocCont(sizeof(SCreateDbReq)); strcpy(pReq->db, "1.db1"); pReq->numOfVgroups = htonl(2); pReq->cacheBlockSize = htonl(16); @@ -87,7 +92,7 @@ void sendCreateDbMsg(void *shandle, SEpSet *pEpSet) { SRpcMsg rpcMsg = {0}; rpcMsg.pCont = pReq; - rpcMsg.contLen = sizeof(SCreateDbMsg); + rpcMsg.contLen = sizeof(SCreateDbReq); rpcMsg.msgType = TDMT_MND_CREATE_DB; SRpcMsg rpcRsp = {0}; @@ -101,7 +106,6 @@ void ctgTestInitLogFile() { const char *defaultLogFileNamePrefix = "taoslog"; const int32_t maxLogFileNum = 10; - ctgDebugFlag = 159; tsAsyncLog = 0; char temp[128] = {0}; @@ -128,7 +132,7 @@ void ctgTestBuildCTableMetaOutput(STableMetaOutput *output) { char tbFullName[TSDB_TABLE_FNAME_LEN]; tNameExtractFullName(&cn, tbFullName); - output->metaNum = 2; + SET_META_TYPE_BOTH_TABLE(output->metaType); strcpy(output->ctbFname, tbFullName); @@ -183,6 +187,7 @@ void ctgTestBuildDBVgroup(SDBVgroupInfo *dbVgroup) { ctgTestCurrentVgVersion = dbVgroup->vgVersion; dbVgroup->hashMethod = 0; + dbVgroup->dbId = ctgTestDbId; dbVgroup->vgInfo = taosHashInit(ctgTestVgNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); vgNum = ctgTestGetVgNumFromVgVersion(dbVgroup->vgVersion); @@ -195,7 +200,7 @@ void ctgTestBuildDBVgroup(SDBVgroupInfo *dbVgroup) { vgInfo.numOfEps = i % TSDB_MAX_REPLICA + 1; vgInfo.inUse = i % vgInfo.numOfEps; for (int32_t n = 0; n < vgInfo.numOfEps; ++n) { - SEpAddrMsg *addr = &vgInfo.epAddr[n]; + SEpAddr *addr = &vgInfo.epAddr[n]; strcpy(addr->fqdn, "a0"); addr->port = htons(n + 22); } @@ -216,6 +221,7 @@ void ctgTestPrepareDbVgroups(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcM ctgTestCurrentVgVersion = ctgTestVgVersion; rspMsg->vgNum = htonl(ctgTestVgNum); rspMsg->hashMethod = 0; + rspMsg->uid = htobe64(ctgTestDbId); SVgroupInfo *vg = NULL; uint32_t hashUnit = UINT32_MAX / ctgTestVgNum; @@ -228,7 +234,7 @@ void ctgTestPrepareDbVgroups(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcM vg->numOfEps = i % TSDB_MAX_REPLICA + 1; vg->inUse = i % vg->numOfEps; for (int32_t n = 0; n < vg->numOfEps; ++n) { - SEpAddrMsg *addr = &vg->epAddr[n]; + SEpAddr *addr = &vg->epAddr[n]; strcpy(addr->fqdn, "a0"); addr->port = htons(n + 22); } @@ -243,12 +249,12 @@ void ctgTestPrepareDbVgroups(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcM void ctgTestPrepareTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { - STableMetaMsg *rspMsg = NULL; //todo + STableMetaRsp *rspMsg = NULL; //todo pRsp->code =0; - pRsp->contLen = sizeof(STableMetaMsg) + (ctgTestColNum + ctgTestTagNum) * sizeof(SSchema); + pRsp->contLen = sizeof(STableMetaRsp) + (ctgTestColNum + ctgTestTagNum) * sizeof(SSchema); pRsp->pCont = calloc(1, pRsp->contLen); - rspMsg = (STableMetaMsg *)pRsp->pCont; + rspMsg = (STableMetaRsp *)pRsp->pCont; sprintf(rspMsg->tbFname, "%s.%s", ctgTestDbname, ctgTestTablename); rspMsg->numOfTags = 0; rspMsg->numOfColumns = htonl(ctgTestColNum); @@ -279,12 +285,12 @@ void ctgTestPrepareTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcM void ctgTestPrepareCTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { - STableMetaMsg *rspMsg = NULL; //todo + STableMetaRsp *rspMsg = NULL; //todo pRsp->code =0; - pRsp->contLen = sizeof(STableMetaMsg) + (ctgTestColNum + ctgTestTagNum) * sizeof(SSchema); + pRsp->contLen = sizeof(STableMetaRsp) + (ctgTestColNum + ctgTestTagNum) * sizeof(SSchema); pRsp->pCont = calloc(1, pRsp->contLen); - rspMsg = (STableMetaMsg *)pRsp->pCont; + rspMsg = (STableMetaRsp *)pRsp->pCont; sprintf(rspMsg->tbFname, "%s.%s", ctgTestDbname, ctgTestCTablename); sprintf(rspMsg->stbFname, "%s.%s", ctgTestDbname, ctgTestSTablename); rspMsg->numOfTags = htonl(ctgTestTagNum); @@ -323,12 +329,12 @@ void ctgTestPrepareCTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpc void ctgTestPrepareSTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { - STableMetaMsg *rspMsg = NULL; //todo + STableMetaRsp *rspMsg = NULL; //todo pRsp->code =0; - pRsp->contLen = sizeof(STableMetaMsg) + (ctgTestColNum + ctgTestTagNum) * sizeof(SSchema); + pRsp->contLen = sizeof(STableMetaRsp) + (ctgTestColNum + ctgTestTagNum) * sizeof(SSchema); pRsp->pCont = calloc(1, pRsp->contLen); - rspMsg = (STableMetaMsg *)pRsp->pCont; + rspMsg = (STableMetaRsp *)pRsp->pCont; sprintf(rspMsg->tbFname, "%s.%s", ctgTestDbname, ctgTestSTablename); sprintf(rspMsg->stbFname, "%s.%s", ctgTestDbname, ctgTestSTablename); rspMsg->numOfTags = htonl(ctgTestTagNum); @@ -338,8 +344,8 @@ void ctgTestPrepareSTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpc rspMsg->update = 1; rspMsg->sversion = htonl(ctgTestSVersion); rspMsg->tversion = htonl(ctgTestTVersion); - rspMsg->suid = htobe64(0x0000000000000002); - rspMsg->tuid = htobe64(0x0000000000000003); + rspMsg->suid = htobe64(ctgTestSuid); + rspMsg->tuid = htobe64(ctgTestSuid); rspMsg->vgId = 0; SSchema *s = NULL; @@ -365,6 +371,53 @@ void ctgTestPrepareSTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpc return; } +void ctgTestPrepareMultiSTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { + STableMetaRsp *rspMsg = NULL; //todo + static int32_t idx = 1; + + pRsp->code =0; + pRsp->contLen = sizeof(STableMetaRsp) + (ctgTestColNum + ctgTestTagNum) * sizeof(SSchema); + pRsp->pCont = calloc(1, pRsp->contLen); + rspMsg = (STableMetaRsp *)pRsp->pCont; + sprintf(rspMsg->tbFname, "%s.%s_%d", ctgTestDbname, ctgTestSTablename, idx); + sprintf(rspMsg->stbFname, "%s.%s_%d", ctgTestDbname, ctgTestSTablename, idx); + rspMsg->numOfTags = htonl(ctgTestTagNum); + rspMsg->numOfColumns = htonl(ctgTestColNum); + rspMsg->precision = 1; + rspMsg->tableType = TSDB_SUPER_TABLE; + rspMsg->update = 1; + rspMsg->sversion = htonl(ctgTestSVersion); + rspMsg->tversion = htonl(ctgTestTVersion); + rspMsg->suid = htobe64(ctgTestSuid + idx); + rspMsg->tuid = htobe64(ctgTestSuid + idx); + rspMsg->vgId = 0; + + SSchema *s = NULL; + s = &rspMsg->pSchema[0]; + s->type = TSDB_DATA_TYPE_TIMESTAMP; + s->colId = htonl(1); + s->bytes = htonl(8); + strcpy(s->name, "ts"); + + s = &rspMsg->pSchema[1]; + s->type = TSDB_DATA_TYPE_INT; + s->colId = htonl(2); + s->bytes = htonl(4); + strcpy(s->name, "col1s"); + + s = &rspMsg->pSchema[2]; + s->type = TSDB_DATA_TYPE_BINARY; + s->colId = htonl(3); + s->bytes = htonl(12); + strcpy(s->name, "tag1s"); + + ++idx; + + return; +} + + + void ctgTestPrepareDbVgroupsAndNormalMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { ctgTestPrepareDbVgroups(shandle, pEpSet, pMsg, pRsp); @@ -390,6 +443,14 @@ void ctgTestPrepareDbVgroupsAndSuperMeta(void *shandle, SEpSet *pEpSet, SRpcMsg return; } +void ctgTestPrepareDbVgroupsAndMultiSuperMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { + ctgTestPrepareDbVgroups(shandle, pEpSet, pMsg, pRsp); + + ctgTestSetPrepareMultiSTableMeta(); + + return; +} + void ctgTestSetPrepareDbVgroups() { @@ -444,6 +505,20 @@ void ctgTestSetPrepareSTableMeta() { } } +void ctgTestSetPrepareMultiSTableMeta() { + static Stub stub; + stub.set(rpcSendRecv, ctgTestPrepareMultiSTableMeta); + { + AddrAny any("libtransport.so"); + std::map result; + any.get_global_func_addr_dynsym("^rpcSendRecv$", result); + for (const auto& f : result) { + stub.set(f.second, ctgTestPrepareMultiSTableMeta); + } + } +} + + void ctgTestSetPrepareDbVgroupsAndNormalMeta() { static Stub stub; stub.set(rpcSendRecv, ctgTestPrepareDbVgroupsAndNormalMeta); @@ -484,6 +559,19 @@ void ctgTestSetPrepareDbVgroupsAndSuperMeta() { } } +void ctgTestSetPrepareDbVgroupsAndMultiSuperMeta() { + static Stub stub; + stub.set(rpcSendRecv, ctgTestPrepareDbVgroupsAndMultiSuperMeta); + { + AddrAny any("libtransport.so"); + std::map result; + any.get_global_func_addr_dynsym("^rpcSendRecv$", result); + for (const auto& f : result) { + stub.set(f.second, ctgTestPrepareDbVgroupsAndMultiSuperMeta); + } + } +} + } @@ -507,7 +595,7 @@ void *ctgTestGetDbVgroupThread(void *param) { if (ctgTestEnableSleep) { usleep(rand()%5); } - if (++n % 50000 == 0) { + if (++n % ctgTestPrintNum == 0) { printf("Get:%d\n", n); } } @@ -531,7 +619,7 @@ void *ctgTestSetDbVgroupThread(void *param) { if (ctgTestEnableSleep) { usleep(rand()%5); } - if (++n % 50000 == 0) { + if (++n % ctgTestPrintNum == 0) { printf("Set:%d\n", n); } } @@ -563,7 +651,7 @@ void *ctgTestGetCtableMetaThread(void *param) { usleep(rand()%5); } - if (++n % 50000 == 0) { + if (++n % ctgTestPrintNum == 0) { printf("Get:%d\n", n); } } @@ -589,7 +677,7 @@ void *ctgTestSetCtableMetaThread(void *param) { if (ctgTestEnableSleep) { usleep(rand()%5); } - if (++n % 50000 == 0) { + if (++n % ctgTestPrintNum == 0) { printf("Set:%d\n", n); } } @@ -600,7 +688,6 @@ void *ctgTestSetCtableMetaThread(void *param) { } -#if 0 TEST(tableMeta, normalTable) { struct SCatalog* pCtg = NULL; @@ -628,6 +715,7 @@ TEST(tableMeta, normalTable) { ASSERT_EQ(vgInfo.vgId, 8); ASSERT_EQ(vgInfo.numOfEps, 3); + ctgTestSetPrepareTableMeta(); STableMeta *tableMeta = NULL; @@ -654,6 +742,41 @@ TEST(tableMeta, normalTable) { ASSERT_EQ(tableMeta->tableInfo.precision, 1); ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + SDbVgVersion *dbs = NULL; + SSTableMetaVersion *stb = NULL; + uint32_t dbNum = 0, stbNum = 0, allDbNum = 0, allStbNum = 0; + int32_t i = 0; + while (i < 5) { + ++i; + code = catalogGetExpiredDBs(pCtg, &dbs, &dbNum); + ASSERT_EQ(code, 0); + code = catalogGetExpiredSTables(pCtg, &stb, &stbNum); + ASSERT_EQ(code, 0); + + if (dbNum) { + printf("got expired db,dbId:%"PRId64"\n", dbs->dbId); + free(dbs); + dbs = NULL; + } else { + printf("no expired db\n"); + } + + if (stbNum) { + printf("got expired stb,suid:%"PRId64"\n", stb->suid); + free(stb); + stb = NULL; + } else { + printf("no expired stb\n"); + } + + allDbNum += dbNum; + allStbNum += stbNum; + sleep(2); + } + + ASSERT_EQ(allDbNum, 1); + ASSERT_EQ(allStbNum, 0); + catalogDestroy(); } @@ -715,6 +838,42 @@ TEST(tableMeta, childTableCase) { ASSERT_EQ(tableMeta->tableInfo.precision, 1); ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + SDbVgVersion *dbs = NULL; + SSTableMetaVersion *stb = NULL; + uint32_t dbNum = 0, stbNum = 0, allDbNum = 0, allStbNum = 0; + int32_t i = 0; + while (i < 5) { + ++i; + code = catalogGetExpiredDBs(pCtg, &dbs, &dbNum); + ASSERT_EQ(code, 0); + code = catalogGetExpiredSTables(pCtg, &stb, &stbNum); + ASSERT_EQ(code, 0); + + if (dbNum) { + printf("got expired db,dbId:%"PRId64"\n", dbs->dbId); + free(dbs); + dbs = NULL; + } else { + printf("no expired db\n"); + } + + if (stbNum) { + printf("got expired stb,suid:%"PRId64"\n", stb->suid); + free(stb); + stb = NULL; + } else { + printf("no expired stb\n"); + } + + allDbNum += dbNum; + allStbNum += stbNum; + sleep(2); + } + + ASSERT_EQ(allDbNum, 1); + ASSERT_EQ(allStbNum, 1); + + catalogDestroy(); } @@ -745,6 +904,8 @@ TEST(tableMeta, superTableCase) { ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->uid, ctgTestSuid); + ASSERT_EQ(tableMeta->suid, ctgTestSuid); ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); ASSERT_EQ(tableMeta->tableInfo.precision, 1); @@ -768,7 +929,7 @@ TEST(tableMeta, superTableCase) { ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); tableMeta = NULL; - code = catalogRenewAndGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); + code = catalogRenewAndGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta, 0); ASSERT_EQ(code, 0); ASSERT_EQ(tableMeta->vgId, 9); ASSERT_EQ(tableMeta->tableType, TSDB_CHILD_TABLE); @@ -779,6 +940,40 @@ TEST(tableMeta, superTableCase) { ASSERT_EQ(tableMeta->tableInfo.precision, 1); ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + SDbVgVersion *dbs = NULL; + SSTableMetaVersion *stb = NULL; + uint32_t dbNum = 0, stbNum = 0, allDbNum = 0, allStbNum = 0; + int32_t i = 0; + while (i < 5) { + ++i; + code = catalogGetExpiredDBs(pCtg, &dbs, &dbNum); + ASSERT_EQ(code, 0); + code = catalogGetExpiredSTables(pCtg, &stb, &stbNum); + ASSERT_EQ(code, 0); + + if (dbNum) { + printf("got expired db,dbId:%"PRId64"\n", dbs->dbId); + free(dbs); + dbs = NULL; + } else { + printf("no expired db\n"); + } + + if (stbNum) { + printf("got expired stb,suid:%"PRId64"\n", stb->suid); + free(stb); + stb = NULL; + } else { + printf("no expired stb\n"); + } + + allDbNum += dbNum; + allStbNum += stbNum; + sleep(2); + } + + ASSERT_EQ(allDbNum, 1); + ASSERT_EQ(allStbNum, 1); catalogDestroy(); @@ -948,7 +1143,6 @@ TEST(dbVgroup, getSetDbVgroupCase) { catalogDestroy(); } - TEST(multiThread, getSetDbVgroupCase) { struct SCatalog* pCtg = NULL; void *mockPointer = (void *)0x1; @@ -956,6 +1150,7 @@ TEST(multiThread, getSetDbVgroupCase) { SVgroupInfo *pvgInfo = NULL; SDBVgroupInfo dbVgroup = {0}; SArray *vgList = NULL; + ctgTestStop = false; ctgTestInitLogFile(); @@ -988,7 +1183,7 @@ TEST(multiThread, getSetDbVgroupCase) { if (ctgTestDeadLoop) { sleep(1); } else { - sleep(600); + sleep(ctgTestMTRunSec); break; } } @@ -999,9 +1194,6 @@ TEST(multiThread, getSetDbVgroupCase) { catalogDestroy(); } -#endif - - TEST(multiThread, ctableMeta) { struct SCatalog* pCtg = NULL; void *mockPointer = (void *)0x1; @@ -1009,6 +1201,7 @@ TEST(multiThread, ctableMeta) { SVgroupInfo *pvgInfo = NULL; SDBVgroupInfo dbVgroup = {0}; SArray *vgList = NULL; + ctgTestStop = false; ctgTestSetPrepareDbVgroupsAndChildMeta(); @@ -1038,7 +1231,7 @@ TEST(multiThread, ctableMeta) { if (ctgTestDeadLoop) { sleep(1); } else { - sleep(600); + sleep(ctgTestMTRunSec); break; } } @@ -1050,6 +1243,78 @@ TEST(multiThread, ctableMeta) { } +TEST(rentTest, allRent) { + struct SCatalog* pCtg = NULL; + void *mockPointer = (void *)0x1; + SVgroupInfo vgInfo = {0}; + SVgroupInfo *pvgInfo = NULL; + SDBVgroupInfo dbVgroup = {0}; + SArray *vgList = NULL; + ctgTestStop = false; + SDbVgVersion *dbs = NULL; + SSTableMetaVersion *stable = NULL; + uint32_t num = 0; + + ctgTestSetPrepareDbVgroupsAndMultiSuperMeta(); + + initQueryModuleMsgHandle(); + + int32_t code = catalogInit(NULL); + ASSERT_EQ(code, 0); + + code = catalogGetHandle(ctgTestClusterId, &pCtg); + ASSERT_EQ(code, 0); + + + SName n = {.type = TSDB_TABLE_NAME_T, .acctId = 1}; + strcpy(n.dbname, "db1"); + + for (int32_t i = 1; i <= 10; ++i) { + sprintf(n.tname, "%s_%d", ctgTestSTablename, i); + + STableMeta *tableMeta = NULL; + code = catalogGetSTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 0); + ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->uid, ctgTestSuid + i); + ASSERT_EQ(tableMeta->suid, ctgTestSuid + i); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + + code = catalogGetExpiredDBs(pCtg, &dbs, &num); + ASSERT_EQ(code, 0); + printf("%d - expired dbNum:%d\n", i, num); + if (dbs) { + printf("%d - expired dbId:%"PRId64", vgVersion:%d\n", i, dbs->dbId, dbs->vgVersion); + free(dbs); + dbs = NULL; + } + + code = catalogGetExpiredSTables(pCtg, &stable, &num); + ASSERT_EQ(code, 0); + printf("%d - expired stableNum:%d\n", i, num); + if (stable) { + for (int32_t n = 0; n < num; ++n) { + printf("suid:%"PRId64", sversion:%d, tversion:%d\n", stable[n].suid, stable[n].sversion, stable[n].tversion); + } + free(stable); + stable = NULL; + } + printf("*************************************************\n"); + + sleep(2); + } + + catalogDestroy(); +} + + + int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/source/libs/executor/CMakeLists.txt b/source/libs/executor/CMakeLists.txt index a6f70b9e83..ba941ab22d 100644 --- a/source/libs/executor/CMakeLists.txt +++ b/source/libs/executor/CMakeLists.txt @@ -8,5 +8,5 @@ target_include_directories( target_link_libraries( executor - PRIVATE os util common function parser + PRIVATE os util common function parser planner qcom ) \ No newline at end of file diff --git a/source/libs/executor/inc/dataSinkInt.h b/source/libs/executor/inc/dataSinkInt.h new file mode 100644 index 0000000000..1bbf5494dd --- /dev/null +++ b/source/libs/executor/inc/dataSinkInt.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _DATA_SINK_INT_H +#define _DATA_SINK_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" +#include "dataSinkMgt.h" + +struct SDataSink; +struct SDataSinkHandle; + +typedef struct SDataSinkManager { + SDataSinkMgtCfg cfg; + pthread_mutex_t mutex; +} SDataSinkManager; + +typedef int32_t (*FPutDataBlock)(struct SDataSinkHandle* pHandle, const SInputData* pInput, int32_t* pStatus); +typedef void (*FEndPut)(struct SDataSinkHandle* pHandle); +typedef int32_t (*FGetDataLength)(struct SDataSinkHandle* pHandle, int32_t* pStatus); +typedef int32_t (*FGetDataBlock)(struct SDataSinkHandle* pHandle, SOutPutData* pOutput, int32_t* pStatus); +typedef int32_t (*FDestroyDataSinker)(struct SDataSinkHandle* pHandle); + +typedef struct SDataSinkHandle { + FPutDataBlock fPut; + FEndPut fEndPut; + FGetDataLength fGetLen; + FGetDataBlock fGetData; + FDestroyDataSinker fDestroy; +} SDataSinkHandle; + +int32_t createDataDispatcher(SDataSinkManager* pManager, const struct SDataSink* pDataSink, DataSinkHandle* pHandle); + +#ifdef __cplusplus +} +#endif + +#endif /*_DATA_SINK_INT_H*/ diff --git a/source/libs/executor/inc/dataSinkMgt.h b/source/libs/executor/inc/dataSinkMgt.h new file mode 100644 index 0000000000..d13423b25d --- /dev/null +++ b/source/libs/executor/inc/dataSinkMgt.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _DATA_SINK_MGT_H +#define _DATA_SINK_MGT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os.h" +#include "executorimpl.h" + +#define DS_CAPACITY_ENOUGH 1 +#define DS_CAPACITY_FULL 2 +#define DS_NEED_SCHEDULE 3 +#define DS_END 4 +#define DS_IN_PROCESS 5 + +struct SDataSink; +struct SSDataBlock; + +typedef struct SDataSinkMgtCfg { + uint32_t maxDataBlockNum; + uint32_t maxDataBlockNumPerQuery; +} SDataSinkMgtCfg; + +int32_t dsDataSinkMgtInit(SDataSinkMgtCfg *cfg); + +typedef void* DataSinkHandle; + +typedef struct SInputData { + const SSDataBlock* pData; + SHashObj* pTableRetrieveTsMap; +} SInputData; + +typedef struct SOutPutData { + int32_t numOfRows; + int8_t compressed; + char* pData; +} SOutPutData; + +/** + * Create a subplan's datasinker handle for all later operations. + * @param pDataSink + * @param pHandle output + * @return error code + */ +int32_t dsCreateDataSinker(const struct SDataSink *pDataSink, DataSinkHandle* pHandle); + +/** + * Put the result set returned by the executor into datasinker. + * @param handle + * @param pRes + * @return error code + */ +int32_t dsPutDataBlock(DataSinkHandle handle, const SInputData* pInput, int32_t* pStatus); + +void dsEndPut(DataSinkHandle handle); + +/** + * Get the length of the data returned by the next call to dsGetDataBlock. + * @param handle + * @return data length + */ +int32_t dsGetDataLength(DataSinkHandle handle, int32_t* pStatus); + +/** + * Get data, the caller needs to allocate data memory. + * @param handle + * @param pOutput output + * @param pStatus output + * @return error code + */ +int32_t dsGetDataBlock(DataSinkHandle handle, SOutPutData* pOutput, int32_t* pStatus); + +/** + * After dsGetStatus returns DS_NEED_SCHEDULE, the caller need to put this into the work queue. + * @param ahandle + * @param pItem + */ +void dsScheduleProcess(void* ahandle, void* pItem); + +/** + * Destroy the datasinker handle. + * @param handle + */ +void dsDestroyDataSinker(DataSinkHandle handle); + +#ifdef __cplusplus +} +#endif + +#endif /*_DATA_SINK_MGT_H*/ diff --git a/source/libs/executor/inc/executil.h b/source/libs/executor/inc/executil.h index 7e910d5674..2c1bf71638 100644 --- a/source/libs/executor/inc/executil.h +++ b/source/libs/executor/inc/executil.h @@ -88,37 +88,37 @@ typedef struct SResultRowPool { SArray* pData; // SArray } SResultRowPool; -struct SQueryAttr; -struct SQueryRuntimeEnv; +struct STaskAttr; +struct STaskRuntimeEnv; struct SUdfInfo; -int32_t getOutputInterResultBufSize(struct SQueryAttr* pQueryAttr); +int32_t getOutputInterResultBufSize(struct STaskAttr* pQueryAttr); -size_t getResultRowSize(struct SQueryRuntimeEnv* pRuntimeEnv); +size_t getResultRowSize(struct STaskRuntimeEnv* pRuntimeEnv); int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size, int16_t type); void cleanupResultRowInfo(SResultRowInfo* pResultRowInfo); -void resetResultRowInfo(struct SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo); +void resetResultRowInfo(struct STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo); int32_t numOfClosedResultRows(SResultRowInfo* pResultRowInfo); void closeAllResultRows(SResultRowInfo* pResultRowInfo); int32_t initResultRow(SResultRow *pResultRow); void closeResultRow(SResultRowInfo* pResultRowInfo, int32_t slot); bool isResultRowClosed(SResultRowInfo *pResultRowInfo, int32_t slot); -void clearResultRow(struct SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, int16_t type); +void clearResultRow(struct STaskRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, int16_t type); struct SResultRowEntryInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset); void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr); void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols); -int32_t getRowNumForMultioutput(struct SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable); +int32_t getRowNumForMultioutput(struct STaskAttr* pQueryAttr, bool topBottomQuery, bool stable); static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) { assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size); return pResultRowInfo->pResult[slot]; } -static FORCE_INLINE char* getPosInResultPage(struct SQueryAttr* pQueryAttr, SFilePage* page, int32_t rowOffset, +static FORCE_INLINE char* getPosInResultPage(struct STaskAttr* pQueryAttr, SFilePage* page, int32_t rowOffset, int32_t offset) { assert(rowOffset >= 0 && pQueryAttr != NULL); @@ -155,7 +155,7 @@ bool hasRemainData(SGroupResInfo* pGroupResInfo); bool incNextGroup(SGroupResInfo* pGroupResInfo); int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo); -int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, struct SQueryRuntimeEnv *pRuntimeEnv, int32_t* offset); +int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, struct STaskRuntimeEnv *pRuntimeEnv, int32_t* offset); int32_t initUdfInfo(struct SUdfInfo* pUdfInfo); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 907fb4d2bf..74ee4637c1 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -21,13 +21,14 @@ #include "tvariant.h" #include "thash.h" -//#include "parser.h" #include "executil.h" #include "taosdef.h" #include "tarray.h" #include "tfilter.h" #include "tlockfree.h" #include "tpagedfile.h" +#include "planner.h" + struct SColumnFilterElem; @@ -65,7 +66,6 @@ enum { QUERY_OVER = 0x4u, }; - typedef struct SResultRowCell { uint64_t groupId; SResultRow *pRow; @@ -100,7 +100,7 @@ typedef struct STableQueryInfo { TSKEY lastKey; int32_t groupIndex; // group id in table list SVariant tag; - STimeWindow win; + STimeWindow win; // todo remove it later STSCursor cur; void* pTable; // for retrieve the page id list SResultRowInfo resInfo; @@ -128,31 +128,34 @@ typedef struct { int64_t sumRunTimes; } SOperatorProfResult; -typedef struct SQueryCostInfo { - uint64_t loadStatisTime; - uint64_t loadFileBlockTime; - uint64_t loadDataInCacheTime; - uint64_t loadStatisSize; - uint64_t loadFileBlockSize; - uint64_t loadDataInCacheSize; - - uint64_t loadDataTime; - uint64_t totalRows; - uint64_t totalCheckedRows; - uint32_t totalBlocks; - uint32_t loadBlocks; - uint32_t loadBlockStatis; - uint32_t discardBlocks; - uint64_t elapsedTime; - uint64_t firstStageMergeTime; - uint64_t winInfoSize; - uint64_t tableInfoSize; - uint64_t hashSize; - uint64_t numOfTimeWindows; +typedef struct STaskCostInfo { + int64_t start; + int64_t end; - SArray* queryProfEvents; //SArray - SHashObj* operatorProfResults; //map -} SQueryCostInfo; + uint64_t loadStatisTime; + uint64_t loadFileBlockTime; + uint64_t loadDataInCacheTime; + uint64_t loadStatisSize; + uint64_t loadFileBlockSize; + uint64_t loadDataInCacheSize; + + uint64_t loadDataTime; + uint64_t totalRows; + uint64_t totalCheckedRows; + uint32_t totalBlocks; + uint32_t loadBlocks; + uint32_t loadBlockStatis; + uint32_t discardBlocks; + uint64_t elapsedTime; + uint64_t firstStageMergeTime; + uint64_t winInfoSize; + uint64_t tableInfoSize; + uint64_t hashSize; + uint64_t numOfTimeWindows; + + SArray *queryProfEvents; //SArray + SHashObj *operatorProfResults; //map +} STaskCostInfo; typedef struct { int64_t vgroupLimit; @@ -166,7 +169,7 @@ typedef struct { // The basic query information extracted from the SQueryInfo tree to support the // execution of query in a data node. -typedef struct SQueryAttr { +typedef struct STaskAttr { SLimit limit; SLimit slimit; @@ -229,16 +232,40 @@ typedef struct SQueryAttr { STableGroupInfo tableGroupInfo; // table list SArray int32_t vgId; SArray *pUdfInfo; // no need to free -} SQueryAttr; +} STaskAttr; typedef SSDataBlock* (*__operator_fn_t)(void* param, bool* newgroup); typedef void (*__optr_cleanup_fn_t)(void* param, int32_t num); struct SOperatorInfo; -typedef struct SQueryRuntimeEnv { +typedef struct STaskIdInfo { + uint64_t queryId; // this is also a request id + uint64_t subplanId; + uint64_t templateId; + uint64_t taskId; // this is a subplan id +} STaskIdInfo; + +typedef struct STaskInfo { + STaskIdInfo id; + char *content; + uint32_t status; + STimeWindow window; + STaskCostInfo cost; + int64_t owner; // if it is in execution + + STableGroupInfo tableqinfoGroupInfo; // this is a group array list, including SArray structure + pthread_mutex_t lock; // used to synchronize the rsp/query threads +// tsem_t ready; +// int32_t dataReady; // denote if query result is ready or not +// void* rspContext; // response context + char *sql; // query sql string + jmp_buf env; +} STaskInfo; + +typedef struct STaskRuntimeEnv { jmp_buf env; - SQueryAttr* pQueryAttr; + STaskAttr* pQueryAttr; uint32_t status; // query status void* qinfo; uint8_t scanFlag; // denotes reversed scan of data or not @@ -271,7 +298,7 @@ typedef struct SQueryRuntimeEnv { SRspResultInfo resultInfo; SHashObj *pTableRetrieveTsMap; struct SUdfInfo *pUdfInfo; -} SQueryRuntimeEnv; +} STaskRuntimeEnv; enum { OP_IN_EXECUTING = 1, @@ -287,10 +314,11 @@ typedef struct SOperatorInfo { char *name; // name, used to show the query execution plan void *info; // extension attribution SExprInfo *pExpr; - SQueryRuntimeEnv *pRuntimeEnv; + STaskRuntimeEnv *pRuntimeEnv; + STaskInfo *pTaskInfo; - struct SOperatorInfo **upstream; // upstream pointer list - int32_t numOfUpstream; // number of upstream. The value is always ONE expect for join operator + struct SOperatorInfo **pDownstream; // downstram pointer list + int32_t numOfDownstream; // number of downstream. The value is always ONE expect for join operator __operator_fn_t exec; __optr_cleanup_fn_t cleanup; } SOperatorInfo; @@ -312,8 +340,8 @@ typedef struct SQInfo { int32_t code; // error code to returned to client int64_t owner; // if it is in execution - SQueryRuntimeEnv runtimeEnv; - SQueryAttr query; + STaskRuntimeEnv runtimeEnv; + STaskAttr query; void* pBuf; // allocated buffer for STableQueryInfo, sizeof(STableQueryInfo)*numOfTables; pthread_mutex_t lock; // used to synchronize the rsp/query threads @@ -322,10 +350,10 @@ typedef struct SQInfo { void* rspContext; // response context int64_t startExecTs; // start to exec timestamp char* sql; // query sql string - SQueryCostInfo summary; + STaskCostInfo summary; } SQInfo; -typedef struct SQueryParam { +typedef struct STaskParam { char *sql; char *tagCond; char *colCond; @@ -345,7 +373,7 @@ typedef struct SQueryParam { int32_t tableScanOperator; SArray *pOperator; struct SUdfInfo *pUdfInfo; -} SQueryParam; +} STaskParam; typedef struct STableScanInfo { void *pQueryHandle; @@ -366,9 +394,12 @@ typedef struct STableScanInfo { SSDataBlock block; int32_t numOfOutput; int64_t elapsedTime; - int32_t tableIndex; - int32_t prevGroupId; // previous table group id + + int32_t prevGroupId; // previous table group id + + int32_t scanFlag; // table scan flag to denote if it is a repeat/reverse/main scan + STimeWindow window; } STableScanInfo; typedef struct STagScanInfo { @@ -512,34 +543,34 @@ typedef struct SOrderOperatorInfo { void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream); -SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime); -SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime); -SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); +SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime); +SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime); +SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv); -SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createProjectOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); -SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createAllTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult); -SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); -SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, +SOperatorInfo* createAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createProjectOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); +SOperatorInfo* createTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createFillOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult); +SOperatorInfo* createGroupbyOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createMultiTableAggOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createTagScanOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createDistinctOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv); +SOperatorInfo* createMultiwaySortOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows, void* merger); -SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo, bool groupResultMixedUp); -SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger, bool multigroupResult); -SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, +SOperatorInfo* createGlobalAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo, bool groupResultMixedUp); +SOperatorInfo* createStatewindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger, bool multigroupResult); +SOperatorInfo* createFilterOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter); SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput); -SOperatorInfo* createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, SOrder* pOrderVal); +SOperatorInfo* createOrderOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, SOrder* pOrderVal); SSDataBlock* doGlobalAggregate(void* param, bool* newgroup); SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup); @@ -561,27 +592,27 @@ void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOf void clearOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity); void copyTsColoum(SSDataBlock* pRes, SQLFunctionCtx* pCtx, int32_t numOfOutput); -void freeParam(SQueryParam *param); -int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param); +void freeParam(STaskParam *param); +int32_t convertQueryMsg(SQueryTableReq *pQueryMsg, STaskParam* param); int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo, SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg, struct SUdfInfo* pUdfInfo); -int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, +int32_t createIndirectQueryFuncExprFromMsg(SQueryTableReq *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, SSqlExpr **pExpr, SExprInfo *prevExpr, struct SUdfInfo *pUdfInfo); int32_t createQueryFilter(char *data, uint16_t len, SFilterInfo** pFilters); -SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code); -SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs, +SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableReq *pQueryMsg, SColIndex *pColIndex, int32_t *code); +SQInfo *createQInfoImpl(SQueryTableReq *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs, SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, SFilterInfo* pFilters, int32_t vgId, char* sql, uint64_t qId, struct SUdfInfo* pUdfInfo); -int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start, +int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, STaskParam* param, char* start, int32_t prevResultLen, void* merger); -int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId); +int32_t createFilterInfo(STaskAttr* pQueryAttr, uint64_t qId); void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters); -STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf); +STableQueryInfo *createTableQueryInfo(STaskAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf); STableQueryInfo* createTmpTableQueryInfo(STimeWindow win); int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, void *pQueryMsg); @@ -590,9 +621,9 @@ bool isQueryKilled(SQInfo *pQInfo); int32_t checkForQueryBuf(size_t numOfTables); bool checkNeedToCompressQueryCol(SQInfo *pQInfo); bool doBuildResCheck(SQInfo* pQInfo); -void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status); +void setQueryStatus(STaskRuntimeEnv *pRuntimeEnv, int8_t status); -bool onlyQueryTags(SQueryAttr* pQueryAttr); +bool onlyQueryTags(STaskAttr* pQueryAttr); void destroyUdfInfo(struct SUdfInfo* pUdfInfo); bool isValidQInfo(void *param); @@ -607,8 +638,8 @@ void publishQueryAbortEvent(SQInfo* pQInfo, int32_t code); void calculateOperatorProfResults(SQInfo* pQInfo); void queryCostStatis(SQInfo *pQInfo); -void freeQInfo(SQInfo *pQInfo); -void freeQueryAttr(SQueryAttr *pQuery); +void doDestroyTask(SQInfo *pQInfo); +void freeQueryAttr(STaskAttr *pQuery); int32_t getMaximumIdleDurationSec(); diff --git a/source/libs/executor/src/dataDispatcher.c b/source/libs/executor/src/dataDispatcher.c new file mode 100644 index 0000000000..3d8e51d04d --- /dev/null +++ b/source/libs/executor/src/dataDispatcher.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "dataSinkInt.h" +#include "dataSinkMgt.h" +#include "planner.h" +#include "tcompression.h" +#include "tglobal.h" +#include "tqueue.h" + +#define DATA_META_LENGTH(tables) (sizeof(int32_t) + sizeof(STableIdInfo) * taosHashGetSize(tables) + sizeof(SRetrieveTableRsp)) + +typedef struct SDataDispatchBuf { + int32_t useSize; + int32_t allocSize; + char* pData; +} SDataDispatchBuf; + +typedef struct SDataCacheEntry { + int32_t dataLen; + int32_t numOfRows; + int8_t compressed; + char data[]; +} SDataCacheEntry; + +typedef struct SDataDispatchHandle { + SDataSinkHandle sink; + SDataSinkManager* pManager; + SDataBlockSchema schema; + STaosQueue* pDataBlocks; + SDataDispatchBuf nextOutput; + int32_t status; + pthread_mutex_t mutex; +} SDataDispatchHandle; + +static bool needCompress(const SSDataBlock* pData, const SDataBlockSchema* pSchema) { + if (tsCompressColData < 0 || 0 == pData->info.rows) { + return false; + } + + for (int32_t col = 0; col < pSchema->numOfCols; ++col) { + SColumnInfoData* pColRes = taosArrayGet(pData->pDataBlock, col); + int32_t colSize = pColRes->info.bytes * pData->info.rows; + if (NEEDTO_COMPRESS_QUERY(colSize)) { + return true; + } + } + + return false; +} + +static int32_t compressColData(SColumnInfoData *pColRes, int32_t numOfRows, char *data, int8_t compressed) { + int32_t colSize = pColRes->info.bytes * numOfRows; + return (*(tDataTypes[pColRes->info.type].compFunc))( + pColRes->pData, colSize, numOfRows, data, colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0); +} + +static void copyData(const SInputData* pInput, const SDataBlockSchema* pSchema, char* data, int8_t compressed, int32_t *compLen) { + int32_t *compSizes = (int32_t*)data; + if (compressed) { + data += pSchema->numOfCols * sizeof(int32_t); + } + + for (int32_t col = 0; col < pSchema->numOfCols; ++col) { + SColumnInfoData* pColRes = taosArrayGet(pInput->pData->pDataBlock, col); + if (compressed) { + compSizes[col] = compressColData(pColRes, pInput->pData->info.rows, data, compressed); + data += compSizes[col]; + *compLen += compSizes[col]; + compSizes[col] = htonl(compSizes[col]); + } else { + memmove(data, pColRes->pData, pColRes->info.bytes * pInput->pData->info.rows); + data += pColRes->info.bytes * pInput->pData->info.rows; + } + } + + int32_t numOfTables = (int32_t) taosHashGetSize(pInput->pTableRetrieveTsMap); + *(int32_t*)data = htonl(numOfTables); + data += sizeof(int32_t); + + STableIdInfo* item = taosHashIterate(pInput->pTableRetrieveTsMap, NULL); + while (item) { + STableIdInfo* pDst = (STableIdInfo*)data; + pDst->uid = htobe64(item->uid); + pDst->key = htobe64(item->key); + data += sizeof(STableIdInfo); + item = taosHashIterate(pInput->pTableRetrieveTsMap, item); + } +} + +// data format with compress: SDataCacheEntry | cols_data_offset | col1_data col2_data ... | numOfTables | STableIdInfo STableIdInfo ... +// data format: SDataCacheEntry | col1_data col2_data ... | numOfTables | STableIdInfo STableIdInfo ... +static void toDataCacheEntry(const SDataDispatchHandle* pHandle, const SInputData* pInput, SDataDispatchBuf* pBuf) { + SDataCacheEntry* pEntry = (SDataCacheEntry*)pBuf->pData; + pEntry->compressed = (int8_t)needCompress(pInput->pData, &(pHandle->schema)); + pEntry->numOfRows = pInput->pData->info.rows; + + pBuf->useSize = DATA_META_LENGTH(pInput->pTableRetrieveTsMap); + copyData(pInput, &pHandle->schema, pEntry->data, pEntry->compressed, &pEntry->dataLen); + pBuf->useSize += (pEntry->compressed ? pEntry->dataLen : pHandle->schema.resultRowSize * pInput->pData->info.rows); + // todo completed +} + +static bool allocBuf(SDataDispatchHandle* pDispatcher, const SInputData* pInput, SDataDispatchBuf* pBuf) { + if (taosQueueSize(pDispatcher->pDataBlocks) >= pDispatcher->pManager->cfg.maxDataBlockNumPerQuery) { + return false; + } + pBuf->allocSize = DATA_META_LENGTH(pInput->pTableRetrieveTsMap) + pDispatcher->schema.resultRowSize * pInput->pData->info.rows; + pBuf->pData = malloc(pBuf->allocSize); + return NULL != pBuf->pData; +} + +static int32_t updateStatus(SDataDispatchHandle* pDispatcher) { + pthread_mutex_lock(&pDispatcher->mutex); + int32_t status = taosQueueSize(pDispatcher->pDataBlocks) < pDispatcher->pManager->cfg.maxDataBlockNumPerQuery ? DS_CAPACITY_ENOUGH : DS_CAPACITY_FULL; + pDispatcher->status = status; + pthread_mutex_unlock(&pDispatcher->mutex); + return status; +} + +static int32_t getStatus(SDataDispatchHandle* pDispatcher) { + pthread_mutex_lock(&pDispatcher->mutex); + int32_t status = pDispatcher->status; + pthread_mutex_unlock(&pDispatcher->mutex); + return status; +} + +static int32_t putDataBlock(SDataSinkHandle* pHandle, const SInputData* pInput, int32_t* pStatus) { + SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle; + SDataDispatchBuf* pBuf = taosAllocateQitem(sizeof(SDataDispatchBuf)); + if (NULL == pBuf || !allocBuf(pDispatcher, pInput, pBuf)) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + toDataCacheEntry(pDispatcher, pInput, pBuf); + taosWriteQitem(pDispatcher->pDataBlocks, pBuf); + *pStatus = updateStatus(pDispatcher); + return TSDB_CODE_SUCCESS; +} + +static void endPut(struct SDataSinkHandle* pHandle) { + SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle; + pthread_mutex_lock(&pDispatcher->mutex); + pDispatcher->status = DS_END; + pthread_mutex_unlock(&pDispatcher->mutex); +} + +static int32_t getDataLength(SDataSinkHandle* pHandle, int32_t* pStatus) { + SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle; + if (taosQueueEmpty(pDispatcher->pDataBlocks)) { + *pStatus = getStatus(pDispatcher) ? DS_END : DS_IN_PROCESS; + return 0; + } + SDataDispatchBuf* pBuf = NULL; + taosReadQitem(pDispatcher->pDataBlocks, (void**)&pBuf); + memcpy(&pDispatcher->nextOutput, pBuf, sizeof(SDataDispatchBuf)); + taosFreeQitem(pBuf); + return ((SDataCacheEntry*)(pDispatcher->nextOutput.pData))->dataLen; +} + +static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutPutData* pOutput, int32_t* pStatus) { + SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle; + SDataCacheEntry* pEntry = (SDataCacheEntry*)(pDispatcher->nextOutput.pData); + memcpy(pOutput->pData, pEntry->data, pEntry->dataLen); + pOutput->numOfRows = pEntry->numOfRows; + pOutput->compressed = pEntry->compressed; + tfree(pDispatcher->nextOutput.pData); // todo persistent + *pStatus = updateStatus(pDispatcher); + return TSDB_CODE_SUCCESS; +} + +static int32_t destroyDataSinker(SDataSinkHandle* pHandle) { + SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle; + tfree(pDispatcher->nextOutput.pData); + while (!taosQueueEmpty(pDispatcher->pDataBlocks)) { + SDataDispatchBuf* pBuf = NULL; + taosReadQitem(pDispatcher->pDataBlocks, (void**)&pBuf); + tfree(pBuf->pData); + taosFreeQitem(pBuf); + } + taosCloseQueue(pDispatcher->pDataBlocks); + pthread_mutex_destroy(&pDispatcher->mutex); +} + +int32_t createDataDispatcher(SDataSinkManager* pManager, const SDataSink* pDataSink, DataSinkHandle* pHandle) { + SDataDispatchHandle* dispatcher = calloc(1, sizeof(SDataDispatchHandle)); + if (NULL == dispatcher) { + terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + dispatcher->sink.fPut = putDataBlock; + dispatcher->sink.fGetLen = getDataLength; + dispatcher->sink.fGetData = getDataBlock; + dispatcher->sink.fDestroy = destroyDataSinker; + dispatcher->pManager = pManager; + dispatcher->schema = pDataSink->schema; + dispatcher->status = DS_CAPACITY_ENOUGH; + dispatcher->pDataBlocks = taosOpenQueue(); + pthread_mutex_init(&dispatcher->mutex, NULL); + if (NULL == dispatcher->pDataBlocks) { + terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + *pHandle = dispatcher; + return TSDB_CODE_SUCCESS; +} diff --git a/source/libs/executor/src/dataSinkMgt.c b/source/libs/executor/src/dataSinkMgt.c new file mode 100644 index 0000000000..8a96c5d05f --- /dev/null +++ b/source/libs/executor/src/dataSinkMgt.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "dataSinkMgt.h" +#include "dataSinkInt.h" +#include "planner.h" + +static SDataSinkManager gDataSinkManager = {0}; + +int32_t dsDataSinkMgtInit(SDataSinkMgtCfg *cfg) { + gDataSinkManager.cfg = *cfg; + pthread_mutex_init(&gDataSinkManager.mutex, NULL); +} + +int32_t dsCreateDataSinker(const struct SDataSink *pDataSink, DataSinkHandle* pHandle) { + if (DSINK_Dispatch == pDataSink->info.type) { + return createDataDispatcher(&gDataSinkManager, pDataSink, pHandle); + } + return TSDB_CODE_FAILED; +} + +int32_t dsPutDataBlock(DataSinkHandle handle, const SInputData* pInput, int32_t* pStatus) { + SDataSinkHandle* pHandleImpl = (SDataSinkHandle*)handle; + return pHandleImpl->fPut(pHandleImpl, pInput, pStatus); +} + +void dsEndPut(DataSinkHandle handle) { + SDataSinkHandle* pHandleImpl = (SDataSinkHandle*)handle; + return pHandleImpl->fEndPut(pHandleImpl); +} + +int32_t dsGetDataLength(DataSinkHandle handle, int32_t* pStatus) { + SDataSinkHandle* pHandleImpl = (SDataSinkHandle*)handle; + return pHandleImpl->fGetLen(pHandleImpl, pStatus); +} + +int32_t dsGetDataBlock(DataSinkHandle handle, SOutPutData* pOutput, int32_t* pStatus) { + SDataSinkHandle* pHandleImpl = (SDataSinkHandle*)handle; + return pHandleImpl->fGetData(pHandleImpl, pOutput, pStatus); +} + +void dsScheduleProcess(void* ahandle, void* pItem) { + // todo +} + +void dsDestroyDataSinker(DataSinkHandle handle) { + SDataSinkHandle* pHandleImpl = (SDataSinkHandle*)handle; + pHandleImpl->fDestroy(pHandleImpl); +} diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index ac91f906c7..e8ecffb72c 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -30,7 +30,7 @@ typedef struct SCompSupporter { int32_t order; } SCompSupporter; -int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable) { +int32_t getRowNumForMultioutput(STaskAttr* pQueryAttr, bool topBottomQuery, bool stable) { if (pQueryAttr && (!stable)) { for (int16_t i = 0; i < pQueryAttr->numOfOutput; ++i) { // if (pQueryAttr->pExpr1[i].base. == FUNCTION_TOP || pQueryAttr->pExpr1[i].base.functionId == FUNCTION_BOTTOM) { @@ -42,7 +42,7 @@ int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, boo return 1; } -int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr) { +int32_t getOutputInterResultBufSize(STaskAttr* pQueryAttr) { int32_t size = 0; for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { @@ -86,7 +86,7 @@ void cleanupResultRowInfo(SResultRowInfo *pResultRowInfo) { tfree(pResultRowInfo->pResult); } -void resetResultRowInfo(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo) { +void resetResultRowInfo(STaskRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo) { if (pResultRowInfo == NULL || pResultRowInfo->capacity == 0) { return; } @@ -136,7 +136,7 @@ void closeResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) { getResultRow(pResultRowInfo, slot)->closed = true; } -void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16_t type) { +void clearResultRow(STaskRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16_t type) { if (pResultRow == NULL) { return; } @@ -174,8 +174,8 @@ struct SResultRowEntryInfo* getResultCell(const SResultRow* pRow, int32_t index, return NULL; } -size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; +size_t getResultRowSize(STaskRuntimeEnv* pRuntimeEnv) { + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; return 0; // return (pQueryAttr->numOfOutput * sizeof(SResultRowEntryInfo)) + pQueryAttr->interBufSize + sizeof(SResultRow); } @@ -393,8 +393,8 @@ int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo) { return (int32_t) taosArrayGetSize(pGroupResInfo->pRows); } -static int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow *pResultRow, int32_t* rowCellInfoOffset) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; +static int64_t getNumOfResultWindowRes(STaskRuntimeEnv* pRuntimeEnv, SResultRow *pResultRow, int32_t* rowCellInfoOffset) { + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) { int32_t functionId = 0;//pQueryAttr->pExpr1[j].base.functionId; @@ -488,7 +488,7 @@ int32_t tsDescOrder(const void* p1, const void* p2) { } } -void orderTheResultRows(SQueryRuntimeEnv* pRuntimeEnv) { +void orderTheResultRows(STaskRuntimeEnv* pRuntimeEnv) { __compar_fn_t fn = NULL; if (pRuntimeEnv->pQueryAttr->order.order == TSDB_ORDER_ASC) { fn = tsAscOrder; @@ -499,7 +499,7 @@ void orderTheResultRows(SQueryRuntimeEnv* pRuntimeEnv) { taosArraySort(pRuntimeEnv->pResultRowArrayList, fn); } -static int32_t mergeIntoGroupResultImplRv(SQueryRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, uint64_t groupId, int32_t* rowCellInfoOffset) { +static int32_t mergeIntoGroupResultImplRv(STaskRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, uint64_t groupId, int32_t* rowCellInfoOffset) { if (!pGroupResInfo->ordered) { orderTheResultRows(pRuntimeEnv); pGroupResInfo->ordered = true; @@ -528,7 +528,7 @@ static int32_t mergeIntoGroupResultImplRv(SQueryRuntimeEnv *pRuntimeEnv, SGroupR return TSDB_CODE_SUCCESS; } -static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, SArray *pTableList, +static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(STaskRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, SArray *pTableList, int32_t* rowCellInfoOffset) { bool ascQuery = QUERY_IS_ASC_QUERY(pRuntimeEnv->pQueryAttr); @@ -630,7 +630,7 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn return code; } -int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv* pRuntimeEnv, int32_t* offset) { +int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, STaskRuntimeEnv* pRuntimeEnv, int32_t* offset) { int64_t st = taosGetTimestampUs(); while (pGroupResInfo->currentGroup < pGroupResInfo->totalGroup) { diff --git a/source/libs/executor/src/executorMain.c b/source/libs/executor/src/executorMain.c new file mode 100644 index 0000000000..968380ea01 --- /dev/null +++ b/source/libs/executor/src/executorMain.c @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "os.h" +#include "tcache.h" +#include "tglobal.h" +#include "tmsg.h" +#include "exception.h" + +#include "thash.h" +#include "executorimpl.h" +#include "executor.h" +#include "tlosertree.h" +#include "ttypes.h" +#include "query.h" + +typedef struct STaskMgmt { + pthread_mutex_t lock; + SCacheObj *qinfoPool; // query handle pool + int32_t vgId; + bool closed; +} STaskMgmt; + +static void taskMgmtKillTaskFn(void* handle, void* param1) { + void** fp = (void**)handle; + qKillTask(*fp); +} + +static void freeqinfoFn(void *qhandle) { + void** handle = qhandle; + if (handle == NULL || *handle == NULL) { + return; + } + + qKillTask(*handle); + qDestroyTask(*handle); +} + +void freeParam(STaskParam *param) { + tfree(param->sql); + tfree(param->tagCond); + tfree(param->tbnameCond); + tfree(param->pTableIdList); + taosArrayDestroy(param->pOperator); + tfree(param->pExprs); + tfree(param->pSecExprs); + + tfree(param->pExpr); + tfree(param->pSecExpr); + + tfree(param->pGroupColIndex); + tfree(param->pTagColumnInfo); + tfree(param->pGroupbyExpr); + tfree(param->prevResult); +} + +// todo parse json to get the operator tree. + +int32_t qCreateTask(void* tsdb, int32_t vgId, void* pQueryMsg, qTaskInfo_t* pTaskInfo, uint64_t taskId) { + assert(pQueryMsg != NULL && tsdb != NULL); + + int32_t code = TSDB_CODE_SUCCESS; +#if 0 + STaskParam param = {0}; + code = convertQueryMsg(pQueryMsg, ¶m); + if (code != TSDB_CODE_SUCCESS) { + goto _over; + } + + if (pQueryMsg->numOfTables <= 0) { + qError("Invalid number of tables to query, numOfTables:%d", pQueryMsg->numOfTables); + code = TSDB_CODE_QRY_INVALID_MSG; + goto _over; + } + + if (param.pTableIdList == NULL || taosArrayGetSize(param.pTableIdList) == 0) { + qError("qmsg:%p, SQueryTableReq wrong format", pQueryMsg); + code = TSDB_CODE_QRY_INVALID_MSG; + goto _over; + } + + SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols}; + if ((code = createQueryFunc(&info, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExpr, param.pTagColumnInfo, + pQueryMsg->queryType, pQueryMsg, param.pUdfInfo)) != TSDB_CODE_SUCCESS) { + goto _over; + } + + if (param.pSecExpr != NULL) { + if ((code = createIndirectQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExpr, param.pExprs, param.pUdfInfo)) != TSDB_CODE_SUCCESS) { + goto _over; + } + } + + if (param.colCond != NULL) { + if ((code = createQueryFilter(param.colCond, pQueryMsg->colCondLen, ¶m.pFilters)) != TSDB_CODE_SUCCESS) { + goto _over; + } + } + + param.pGroupbyExpr = createGroupbyExprFromMsg(pQueryMsg, param.pGroupColIndex, &code); + if ((param.pGroupbyExpr == NULL && pQueryMsg->numOfGroupCols != 0) || code != TSDB_CODE_SUCCESS) { + goto _over; + } + + bool isSTableQuery = false; + STableGroupInfo tableGroupInfo = {0}; + int64_t st = taosGetTimestampUs(); + + if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_TABLE_QUERY)) { + STableIdInfo *id = taosArrayGet(param.pTableIdList, 0); + + qDebug("qmsg:%p query normal table, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid); + if ((code = tsdbGetOneTableGroup(tsdb, id->uid, pQueryMsg->window.skey, &tableGroupInfo)) != TSDB_CODE_SUCCESS) { + goto _over; + } + } else if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY|TSDB_QUERY_TYPE_STABLE_QUERY)) { + isSTableQuery = true; + + // also note there's possibility that only one table in the super table + if (!TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY)) { + STableIdInfo *id = taosArrayGet(param.pTableIdList, 0); + + // group by normal column, do not pass the group by condition to tsdb to group table into different group + int32_t numOfGroupByCols = pQueryMsg->numOfGroupCols; + if (pQueryMsg->numOfGroupCols == 1 && !TSDB_COL_IS_TAG(param.pGroupColIndex->flag)) { + numOfGroupByCols = 0; + } + + qDebug("qmsg:%p query stable, uid:%"PRIu64", tid:%d", pQueryMsg, id->uid, id->tid); + code = tsdbQuerySTableByTagCond(tsdb, id->uid, pQueryMsg->window.skey, param.tagCond, pQueryMsg->tagCondLen, + pQueryMsg->tagNameRelType, param.tbnameCond, &tableGroupInfo, param.pGroupColIndex, numOfGroupByCols); + + if (code != TSDB_CODE_SUCCESS) { + qError("qmsg:%p failed to query stable, reason: %s", pQueryMsg, tstrerror(code)); + goto _over; + } + } else { + code = tsdbGetTableGroupFromIdList(tsdb, param.pTableIdList, &tableGroupInfo); + if (code != TSDB_CODE_SUCCESS) { + goto _over; + } + + qDebug("qmsg:%p query on %u tables in one group from client", pQueryMsg, tableGroupInfo.numOfTables); + } + + int64_t el = taosGetTimestampUs() - st; + qDebug("qmsg:%p tag filter completed, numOfTables:%u, elapsed time:%"PRId64"us", pQueryMsg, tableGroupInfo.numOfTables, el); + } else { + assert(0); + } + + code = checkForQueryBuf(tableGroupInfo.numOfTables); + if (code != TSDB_CODE_SUCCESS) { // not enough query buffer, abort + goto _over; + } + + assert(pQueryMsg->stableQuery == isSTableQuery); + (*pTaskInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo, + param.pTagColumnInfo, param.pFilters, vgId, param.sql, qId, param.pUdfInfo); + + param.sql = NULL; + param.pExprs = NULL; + param.pSecExprs = NULL; + param.pGroupbyExpr = NULL; + param.pTagColumnInfo = NULL; + param.pFilters = NULL; + + if ((*pTaskInfo) == NULL) { + code = TSDB_CODE_QRY_OUT_OF_MEMORY; + goto _over; + } + param.pUdfInfo = NULL; + + code = initQInfo(&pQueryMsg->tsBuf, tsdb, NULL, *pTaskInfo, ¶m, (char*)pQueryMsg, pQueryMsg->prevResultLen, NULL); + + _over: + if (param.pGroupbyExpr != NULL) { + taosArrayDestroy(param.pGroupbyExpr->columnInfo); + } + + tfree(param.colCond); + + destroyUdfInfo(param.pUdfInfo); + + taosArrayDestroy(param.pTableIdList); + param.pTableIdList = NULL; + + freeParam(¶m); + + for (int32_t i = 0; i < pQueryMsg->numOfCols; i++) { + SColumnInfo* column = pQueryMsg->tableCols + i; + freeColumnFilterInfo(column->flist.filterInfo, column->flist.numOfFilters); + } + + filterFreeInfo(param.pFilters); + + //pTaskInfo already freed in initQInfo, but *pTaskInfo may not pointer to null; + if (code != TSDB_CODE_SUCCESS) { + *pTaskInfo = NULL; + } +#endif + + // if failed to add ref for all tables in this query, abort current query + return code; +} + +#ifdef TEST_IMPL +// wait moment +int waitMoment(SQInfo* pQInfo){ + if(pQInfo->sql) { + int ms = 0; + char* pcnt = strstr(pQInfo->sql, " count(*)"); + if(pcnt) return 0; + + char* pos = strstr(pQInfo->sql, " t_"); + if(pos){ + pos += 3; + ms = atoi(pos); + while(*pos >= '0' && *pos <= '9'){ + pos ++; + } + char unit_char = *pos; + if(unit_char == 'h'){ + ms *= 3600*1000; + } else if(unit_char == 'm'){ + ms *= 60*1000; + } else if(unit_char == 's'){ + ms *= 1000; + } + } + if(ms == 0) return 0; + printf("test wait sleep %dms. sql=%s ...\n", ms, pQInfo->sql); + + if(ms < 1000) { + taosMsleep(ms); + } else { + int used_ms = 0; + while(used_ms < ms) { + taosMsleep(1000); + used_ms += 1000; + if(isQueryKilled(pQInfo)){ + printf("test check query is canceled, sleep break.%s\n", pQInfo->sql); + break; + } + } + } + } + return 1; +} +#endif + +bool qExecTask(qTaskInfo_t qinfo, uint64_t *qId) { + SQInfo *pQInfo = (SQInfo *)qinfo; + assert(pQInfo && pQInfo->signature == pQInfo); + int64_t threadId = taosGetSelfPthreadId(); + + int64_t curOwner = 0; + if ((curOwner = atomic_val_compare_exchange_64(&pQInfo->owner, 0, threadId)) != 0) { + qError("QInfo:0x%"PRIx64"-%p qhandle is now executed by thread:%p", pQInfo->qId, pQInfo, (void*) curOwner); + pQInfo->code = TSDB_CODE_QRY_IN_EXEC; + return false; + } + + *qId = pQInfo->qId; + if(pQInfo->startExecTs == 0) + pQInfo->startExecTs = taosGetTimestampMs(); + + if (isQueryKilled(pQInfo)) { + qDebug("QInfo:0x%"PRIx64" it is already killed, abort", pQInfo->qId); + return doBuildResCheck(pQInfo); + } + + STaskRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; + if (pRuntimeEnv->tableqinfoGroupInfo.numOfTables == 0) { + qDebug("QInfo:0x%"PRIx64" no table exists for query, abort", pQInfo->qId); +// setTaskStatus(pRuntimeEnv, QUERY_COMPLETED); + return doBuildResCheck(pQInfo); + } + + // error occurs, record the error code and return to client + int32_t ret = setjmp(pQInfo->runtimeEnv.env); + if (ret != TSDB_CODE_SUCCESS) { + publishQueryAbortEvent(pQInfo, ret); + pQInfo->code = ret; + qDebug("QInfo:0x%"PRIx64" query abort due to error/cancel occurs, code:%s", pQInfo->qId, tstrerror(pQInfo->code)); + return doBuildResCheck(pQInfo); + } + + qDebug("QInfo:0x%"PRIx64" query task is launched", pQInfo->qId); + + bool newgroup = false; + publishOperatorProfEvent(pRuntimeEnv->proot, QUERY_PROF_BEFORE_OPERATOR_EXEC); + + int64_t st = taosGetTimestampUs(); + pRuntimeEnv->outputBuf = pRuntimeEnv->proot->exec(pRuntimeEnv->proot, &newgroup); + pQInfo->summary.elapsedTime += (taosGetTimestampUs() - st); +#ifdef TEST_IMPL + waitMoment(pQInfo); +#endif + publishOperatorProfEvent(pRuntimeEnv->proot, QUERY_PROF_AFTER_OPERATOR_EXEC); + pRuntimeEnv->resultInfo.total += GET_NUM_OF_RESULTS(pRuntimeEnv); + + if (isQueryKilled(pQInfo)) { + qDebug("QInfo:0x%"PRIx64" query is killed", pQInfo->qId); + } else if (GET_NUM_OF_RESULTS(pRuntimeEnv) == 0) { + qDebug("QInfo:0x%"PRIx64" over, %u tables queried, total %"PRId64" rows returned", pQInfo->qId, pRuntimeEnv->tableqinfoGroupInfo.numOfTables, + pRuntimeEnv->resultInfo.total); + } else { + qDebug("QInfo:0x%"PRIx64" query paused, %d rows returned, total:%" PRId64 " rows", pQInfo->qId, + GET_NUM_OF_RESULTS(pRuntimeEnv), pRuntimeEnv->resultInfo.total); + } + + return doBuildResCheck(pQInfo); +} + +int32_t qRetrieveQueryResultInfo(qTaskInfo_t qinfo, bool* buildRes, void* pRspContext) { + SQInfo *pQInfo = (SQInfo *)qinfo; + + if (pQInfo == NULL || !isValidQInfo(pQInfo)) { + qError("QInfo invalid qhandle"); + return TSDB_CODE_QRY_INVALID_QHANDLE; + } + + *buildRes = false; + if (IS_QUERY_KILLED(pQInfo)) { + qDebug("QInfo:0x%"PRIx64" query is killed, code:0x%08x", pQInfo->qId, pQInfo->code); + return pQInfo->code; + } + + int32_t code = TSDB_CODE_SUCCESS; + + if (tsRetrieveBlockingModel) { + pQInfo->rspContext = pRspContext; + tsem_wait(&pQInfo->ready); + *buildRes = true; + code = pQInfo->code; + } else { + STaskRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; + STaskAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; + + pthread_mutex_lock(&pQInfo->lock); + + assert(pQInfo->rspContext == NULL); + if (pQInfo->dataReady == QUERY_RESULT_READY) { + *buildRes = true; + qDebug("QInfo:0x%"PRIx64" retrieve result info, rowsize:%d, rows:%d, code:%s", pQInfo->qId, pQueryAttr->resultRowSize, + GET_NUM_OF_RESULTS(pRuntimeEnv), tstrerror(pQInfo->code)); + } else { + *buildRes = false; + qDebug("QInfo:0x%"PRIx64" retrieve req set query return result after paused", pQInfo->qId); + pQInfo->rspContext = pRspContext; + assert(pQInfo->rspContext != NULL); + } + + code = pQInfo->code; + pthread_mutex_unlock(&pQInfo->lock); + } + + return code; +} + +void* qGetResultRetrieveMsg(qTaskInfo_t qinfo) { + SQInfo* pQInfo = (SQInfo*) qinfo; + assert(pQInfo != NULL); + + return pQInfo->rspContext; +} + +int32_t qKillTask(qTaskInfo_t qinfo) { + SQInfo *pQInfo = (SQInfo *)qinfo; + + if (pQInfo == NULL || !isValidQInfo(pQInfo)) { + return TSDB_CODE_QRY_INVALID_QHANDLE; + } + + qDebug("QInfo:0x%"PRIx64" query killed", pQInfo->qId); + setQueryKilled(pQInfo); + + // Wait for the query executing thread being stopped/ + // Once the query is stopped, the owner of qHandle will be cleared immediately. + while (pQInfo->owner != 0) { + taosMsleep(100); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t qIsTaskCompleted(qTaskInfo_t qinfo) { + SQInfo *pQInfo = (SQInfo *)qinfo; + + if (pQInfo == NULL || !isValidQInfo(pQInfo)) { + return TSDB_CODE_QRY_INVALID_QHANDLE; + } + + return isQueryKilled(pQInfo) || Q_STATUS_EQUAL(pQInfo->runtimeEnv.status, QUERY_OVER); +} + +void qDestroyTask(qTaskInfo_t qHandle) { + SQInfo* pQInfo = (SQInfo*) qHandle; + if (!isValidQInfo(pQInfo)) { + return; + } + + qDebug("QInfo:0x%"PRIx64" query completed", pQInfo->qId); + queryCostStatis(pQInfo); // print the query cost summary + doDestroyTask(pQInfo); +} + +void* qOpenTaskMgmt(int32_t vgId) { + const int32_t refreshHandleInterval = 30; // every 30 seconds, refresh handle pool + + char cacheName[128] = {0}; + sprintf(cacheName, "qhandle_%d", vgId); + + STaskMgmt* pTaskMgmt = calloc(1, sizeof(STaskMgmt)); + if (pTaskMgmt == NULL) { + terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; + return NULL; + } + + pTaskMgmt->qinfoPool = taosCacheInit(TSDB_CACHE_PTR_KEY, refreshHandleInterval, true, freeqinfoFn, cacheName); + pTaskMgmt->closed = false; + pTaskMgmt->vgId = vgId; + + pthread_mutex_init(&pTaskMgmt->lock, NULL); + + qDebug("vgId:%d, open queryTaskMgmt success", vgId); + return pTaskMgmt; +} + +void qTaskMgmtNotifyClosing(void* pQMgmt) { + if (pQMgmt == NULL) { + return; + } + + STaskMgmt* pQueryMgmt = pQMgmt; + qInfo("vgId:%d, set querymgmt closed, wait for all queries cancelled", pQueryMgmt->vgId); + + pthread_mutex_lock(&pQueryMgmt->lock); + pQueryMgmt->closed = true; + pthread_mutex_unlock(&pQueryMgmt->lock); + + taosCacheRefresh(pQueryMgmt->qinfoPool, taskMgmtKillTaskFn, NULL); +} + +void qQueryMgmtReOpen(void *pQMgmt) { + if (pQMgmt == NULL) { + return; + } + + STaskMgmt *pQueryMgmt = pQMgmt; + qInfo("vgId:%d, set querymgmt reopen", pQueryMgmt->vgId); + + pthread_mutex_lock(&pQueryMgmt->lock); + pQueryMgmt->closed = false; + pthread_mutex_unlock(&pQueryMgmt->lock); +} + +void qCleanupTaskMgmt(void* pQMgmt) { + if (pQMgmt == NULL) { + return; + } + + STaskMgmt* pQueryMgmt = pQMgmt; + int32_t vgId = pQueryMgmt->vgId; + + assert(pQueryMgmt->closed); + + SCacheObj* pqinfoPool = pQueryMgmt->qinfoPool; + pQueryMgmt->qinfoPool = NULL; + + taosCacheCleanup(pqinfoPool); + pthread_mutex_destroy(&pQueryMgmt->lock); + tfree(pQueryMgmt); + + qDebug("vgId:%d, queryMgmt cleanup completed", vgId); +} + +void** qRegisterTask(void* pMgmt, uint64_t qId, void *qInfo) { + if (pMgmt == NULL) { + terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; + return NULL; + } + + STaskMgmt *pQueryMgmt = pMgmt; + if (pQueryMgmt->qinfoPool == NULL) { + qError("QInfo:0x%"PRIx64"-%p failed to add qhandle into qMgmt, since qMgmt is closed", qId, (void*)qInfo); + terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; + return NULL; + } + + pthread_mutex_lock(&pQueryMgmt->lock); + if (pQueryMgmt->closed) { + pthread_mutex_unlock(&pQueryMgmt->lock); + qError("QInfo:0x%"PRIx64"-%p failed to add qhandle into cache, since qMgmt is colsing", qId, (void*)qInfo); + terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; + return NULL; + } else { + void** handle = taosCachePut(pQueryMgmt->qinfoPool, &qId, sizeof(qId), &qInfo, sizeof(TSDB_CACHE_PTR_TYPE), + (getMaximumIdleDurationSec()*1000)); + pthread_mutex_unlock(&pQueryMgmt->lock); + + return handle; + } +} + +void** qAcquireTask(void* pMgmt, uint64_t _key) { + STaskMgmt *pQueryMgmt = pMgmt; + + if (pQueryMgmt->closed) { + terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; + return NULL; + } + + if (pQueryMgmt->qinfoPool == NULL) { + terrno = TSDB_CODE_QRY_INVALID_QHANDLE; + return NULL; + } + + void** handle = taosCacheAcquireByKey(pQueryMgmt->qinfoPool, &_key, sizeof(_key)); + if (handle == NULL || *handle == NULL) { + terrno = TSDB_CODE_QRY_INVALID_QHANDLE; + return NULL; + } else { + return handle; + } +} + +void** qReleaseTask(void* pMgmt, void* pQInfo, bool freeHandle) { + STaskMgmt *pQueryMgmt = pMgmt; + if (pQueryMgmt->qinfoPool == NULL) { + return NULL; + } + + taosCacheRelease(pQueryMgmt->qinfoPool, pQInfo, freeHandle); + return 0; +} + +#if 0 +//kill by qid +int32_t qKillQueryByQId(void* pMgmt, int64_t qId, int32_t waitMs, int32_t waitCount) { + int32_t error = TSDB_CODE_SUCCESS; + void** handle = qAcquireTask(pMgmt, qId); + if(handle == NULL) return terrno; + + SQInfo* pQInfo = (SQInfo*)(*handle); + if (pQInfo == NULL || !isValidQInfo(pQInfo)) { + return TSDB_CODE_QRY_INVALID_QHANDLE; + } + qWarn("QId:0x%"PRIx64" be killed(no memory commit).", pQInfo->qId); + setQueryKilled(pQInfo); + + // wait query stop + int32_t loop = 0; + while (pQInfo->owner != 0) { + taosMsleep(waitMs); + if(loop++ > waitCount){ + error = TSDB_CODE_FAILED; + break; + } + } + + qReleaseTask(pMgmt, (void **)&handle, true); + return error; +} + +#endif \ No newline at end of file diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index f119627c69..b00d37f828 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -12,24 +12,25 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#include #include "os.h" #include "tmsg.h" #include "tglobal.h" #include "ttime.h" - #include "exception.h" + +#include "../../../../contrib/cJson/cJSON.h" #include "executorimpl.h" -#include "thash.h" #include "function.h" #include "tcompare.h" #include "tcompression.h" +#include "thash.h" #include "ttypes.h" +#include "query.h" -#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN) +#define IS_MAIN_SCAN(runtime) ((runtime)->scanFlag == MAIN_SCAN) #define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN) #define IS_REPEAT_SCAN(runtime) ((runtime)->scanFlag == REPEAT_SCAN) -#define SET_MASTER_SCAN_FLAG(runtime) ((runtime)->scanFlag = MASTER_SCAN) +#define SET_MAIN_SCAN_FLAG(runtime) ((runtime)->scanFlag = MAIN_SCAN) #define SET_REVERSE_SCAN_FLAG(runtime) ((runtime)->scanFlag = REVERSE_SCAN) #define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey)) @@ -41,11 +42,6 @@ #define MULTI_KEY_DELIM "-" -#define TIME_WINDOW_COPY(_dst, _src) do {\ - (_dst).skey = (_src).skey;\ - (_dst).ekey = (_src).ekey;\ -} while (0) - enum { TS_JOIN_TS_EQUAL = 0, TS_JOIN_TS_NOT_EQUALS = 1, @@ -131,40 +127,16 @@ do { \ } \ } while (0) -uint64_t queryHandleId = 0; - int32_t getMaximumIdleDurationSec() { return tsShellActivityTimer * 2; } -int64_t genQueryId(void) { - int64_t uid = 0; - int64_t did = 0;//tsDnodeId; - - uid = did << 54; - - int64_t pid = ((int64_t)taosGetPId()) & 0x3FF; - - uid |= pid << 44; - - int64_t ts = taosGetTimestampMs() & 0x1FFFFFFFF; - - uid |= ts << 11; - - int64_t sid = atomic_add_fetch_64(&queryHandleId, 1) & 0x7FF; - - uid |= sid; - -// //qDebug("gen qid:0x%"PRIx64, uid); - - return uid; -} static int32_t getExprFunctionId(SExprInfo *pExprInfo) { assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_UNARYEXPR_NODE); return 0; } -static void getNextTimeWindow(SQueryAttr* pQueryAttr, STimeWindow* tw) { +static void getNextTimeWindow(STaskAttr* pQueryAttr, STimeWindow* tw) { int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); if (pQueryAttr->interval.intervalUnit != 'n' && pQueryAttr->interval.intervalUnit != 'y') { tw->skey += pQueryAttr->interval.sliding * factor; @@ -198,28 +170,28 @@ static void getNextTimeWindow(SQueryAttr* pQueryAttr, STimeWindow* tw) { } static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type, int16_t bytes); -static void setResultOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResult, SQLFunctionCtx* pCtx, +static void setResultOutputBuf(STaskRuntimeEnv* pRuntimeEnv, SResultRow* pResult, SQLFunctionCtx* pCtx, int32_t numOfCols, int32_t* rowCellInfoOffset); -void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset); -static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx); +void setResultRowOutputBufInitCtx(STaskRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset); +static bool functionNeedToExecute(STaskRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx); static void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, SColIndex* pColIndex); static void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo); -static bool hasMainOutput(SQueryAttr *pQueryAttr); +static bool hasMainOutput(STaskAttr *pQueryAttr); static SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int32_t* numOfFilterCols); -static int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, SVariant* pTag, STableQueryInfo *pTableQueryInfo); +static int32_t setTimestampListJoinInfo(STaskRuntimeEnv* pRuntimeEnv, SVariant* pTag, STableQueryInfo *pTableQueryInfo); static void releaseQueryBuf(size_t numOfTables); static int32_t binarySearchForKey(char *pValue, int num, TSKEY key, int order); -//static STsdbQueryCond createTsdbQueryCond(SQueryAttr* pQueryAttr, STimeWindow* win); +//static STsdbQueryCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win); static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo); static void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInfo* pDownstream); -static int32_t getNumOfScanTimes(SQueryAttr* pQueryAttr); +static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr); static void destroyBasicOperatorInfo(void* param, int32_t numOfOutput); static void destroySFillOperatorInfo(void* param, int32_t numOfOutput); @@ -232,32 +204,34 @@ static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput); static void destroyAggOperatorInfo(void* param, int32_t numOfOutput); static void destroyOperatorInfo(SOperatorInfo* pOperator); +void setTaskStatus(STaskInfo *pTaskInfo, int8_t status); + static void doSetOperatorCompleted(SOperatorInfo* pOperator) { pOperator->status = OP_EXEC_DONE; - if (pOperator->pRuntimeEnv != NULL) { - setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + if (pOperator->pTaskInfo != NULL) { + setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); } } -static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock); +static int32_t doCopyToSDataBlock(STaskRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock); static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock); -static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binf, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex); +static int32_t setGroupResultOutputBuf(STaskRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binf, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex); static void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size); -static void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win); -static void setResultBufSize(SQueryAttr* pQueryAttr, SRspResultInfo* pResultInfo); -static void setCtxTagForJoin(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable); -static void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr); -static void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr, char* val, int16_t bytes); -static void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, +static void getAlignQueryTimeWindow(STaskAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win); +static void setResultBufSize(STaskAttr* pQueryAttr, SRspResultInfo* pResultInfo); +static void setCtxTagForJoin(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable); +static void setParamForStableStddev(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr); +static void setParamForStableStddevByColData(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr, char* val, int16_t bytes); +static void doSetTableGroupOutputBuf(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, SQLFunctionCtx* pCtx, int32_t* rowCellInfoOffset, int32_t numOfOutput, int32_t tableGroupId); -SArray* getOrderCheckColumns(SQueryAttr* pQuery); +SArray* getOrderCheckColumns(STaskAttr* pQuery); typedef struct SRowCompSupporter { - SQueryRuntimeEnv *pRuntimeEnv; + STaskRuntimeEnv *pRuntimeEnv; int16_t dataOffset; __compar_fn_t comFunc; } SRowCompSupporter; @@ -267,7 +241,7 @@ static int compareRowData(const void *a, const void *b, const void *userData) { const SResultRow *pRow2 = (const SResultRow *)b; SRowCompSupporter *supporter = (SRowCompSupporter *)userData; - SQueryRuntimeEnv* pRuntimeEnv = supporter->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = supporter->pRuntimeEnv; SFilePage *page1 = getResBufPage(pRuntimeEnv->pResultBuf, pRow1->pageId); SFilePage *page2 = getResBufPage(pRuntimeEnv->pResultBuf, pRow2->pageId); @@ -279,7 +253,7 @@ static int compareRowData(const void *a, const void *b, const void *userData) { return (in1 != NULL && in2 != NULL) ? supporter->comFunc(in1, in2) : 0; } -static void sortGroupResByOrderList(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv *pRuntimeEnv, SSDataBlock* pDataBlock) { +static void sortGroupResByOrderList(SGroupResInfo *pGroupResInfo, STaskRuntimeEnv *pRuntimeEnv, SSDataBlock* pDataBlock) { SArray *columnOrderList = getOrderCheckColumns(pRuntimeEnv->pQueryAttr); size_t size = taosArrayGetSize(columnOrderList); taosArrayDestroy(columnOrderList); @@ -375,7 +349,7 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput // return (numOfSelectivity > 0 && hasTags); } -static bool isProjQuery(SQueryAttr *pQueryAttr) { +static bool isProjQuery(STaskAttr *pQueryAttr) { for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functId = getExprFunctionId(&pQueryAttr->pExpr1[i]); if (functId != FUNCTION_PRJ && functId != FUNCTION_TAGPRJ) { @@ -398,7 +372,7 @@ static bool hasNull(SColIndex* pColIndex, SColumnDataAgg *pStatis) { return true; } -static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, SQueryRuntimeEnv* pRuntimeEnv) { +static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, STaskRuntimeEnv* pRuntimeEnv) { // more than the capacity, reallocate the resources if (pResultRowInfo->size < pResultRowInfo->capacity) { return; @@ -424,7 +398,7 @@ static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, SQueryRuntim pResultRowInfo->capacity = (int32_t)newCapacity; } -static bool chkResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, char *pData, +static bool chkResultRowFromKey(STaskRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, char *pData, int16_t bytes, bool masterscan, uint64_t uid) { bool existed = false; SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid); @@ -462,7 +436,7 @@ static bool chkResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *p } -static SResultRow* doSetResultOutBufByKey(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, int64_t tid, +static SResultRow* doSetResultOutBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, int64_t tid, char* pData, int16_t bytes, bool masterscan, uint64_t tableGroupId) { bool existed = false; SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, tableGroupId); @@ -536,7 +510,7 @@ static SResultRow* doSetResultOutBufByKey(SQueryRuntimeEnv* pRuntimeEnv, SResult return pResultRowInfo->pResult[pResultRowInfo->curPos]; } -static void getInitialStartTimeWindow(SQueryAttr* pQueryAttr, TSKEY ts, STimeWindow* w) { +static void getInitialStartTimeWindow(STaskAttr* pQueryAttr, TSKEY ts, STimeWindow* w) { if (QUERY_IS_ASC_QUERY(pQueryAttr)) { getAlignQueryTimeWindow(pQueryAttr, ts, ts, pQueryAttr->window.ekey, w); } else { @@ -561,7 +535,7 @@ static void getInitialStartTimeWindow(SQueryAttr* pQueryAttr, TSKEY ts, STimeWin } // get the correct time window according to the handled timestamp -static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, SQueryAttr *pQueryAttr) { +static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, STaskAttr *pQueryAttr) { STimeWindow w = {0}; if (pResultRowInfo->curPos == -1) { // the first window, from the previous stored value @@ -609,7 +583,7 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t } // get the correct time window according to the handled timestamp -static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, SQueryAttr *pQueryAttr) { +static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, STaskAttr *pQueryAttr) { STimeWindow w = {0}; if (pResultRowInfo->curPos == -1) { // the first window, from the previous stored value @@ -680,14 +654,14 @@ static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedResultBuf return 0; } -static bool chkWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, STimeWindow *win, +static bool chkWindowOutputBufByKey(STaskRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, STimeWindow *win, bool masterscan, SResultRow **pResult, int64_t groupId, SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset) { assert(win->skey <= win->ekey); return chkResultRowFromKey(pRuntimeEnv, pResultRowInfo, (char *)&win->skey, TSDB_KEYSIZE, masterscan, groupId); } -static int32_t setResultOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, int64_t tid, STimeWindow *win, +static int32_t setResultOutputBufByKey(STaskRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, int64_t tid, STimeWindow *win, bool masterscan, SResultRow **pResult, int64_t tableGroupId, SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset) { assert(win->skey <= win->ekey); @@ -816,7 +790,7 @@ static void doUpdateResultRowIndex(SResultRowInfo*pResultRowInfo, TSKEY lastKey, } } -static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, SQueryAttr* pQueryAttr, TSKEY lastKey) { +static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, STaskAttr* pQueryAttr, TSKEY lastKey) { bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); if ((lastKey > pQueryAttr->window.ekey && ascQuery) || (lastKey < pQueryAttr->window.ekey && (!ascQuery))) { closeAllResultRows(pResultRowInfo); @@ -827,10 +801,10 @@ static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, SQuer } } -static int32_t getNumOfRowsInTimeWindow(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo *pDataBlockInfo, TSKEY *pPrimaryColumn, +static int32_t getNumOfRowsInTimeWindow(STaskRuntimeEnv* pRuntimeEnv, SDataBlockInfo *pDataBlockInfo, TSKEY *pPrimaryColumn, int32_t startPos, TSKEY ekey, __block_search_fn_t searchFn, bool updateLastKey) { assert(startPos >= 0 && startPos < pDataBlockInfo->rows); - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; STableQueryInfo* item = pRuntimeEnv->current; int32_t num = -1; @@ -867,9 +841,9 @@ static int32_t getNumOfRowsInTimeWindow(SQueryRuntimeEnv* pRuntimeEnv, SDataBloc return num; } -static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, +static void doApplyFunctions(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) { - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; bool hasAggregates = pCtx[0].isAggSet; for (int32_t k = 0; k < numOfOutput; ++k) { @@ -904,7 +878,7 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx } } -static int32_t getNextQualifiedWindow(SQueryAttr* pQueryAttr, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, +static int32_t getNextQualifiedWindow(STaskAttr* pQueryAttr, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, TSKEY* primaryKeys, __block_search_fn_t searchFn, int32_t prevPosition) { getNextTimeWindow(pQueryAttr, pNext); @@ -983,7 +957,7 @@ static int32_t getNextQualifiedWindow(SQueryAttr* pQueryAttr, STimeWindow* pNext return startPos; } -static FORCE_INLINE TSKEY reviseWindowEkey(SQueryAttr *pQueryAttr, STimeWindow *pWindow) { +static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr *pQueryAttr, STimeWindow *pWindow) { TSKEY ekey = -1; if (QUERY_IS_ASC_QUERY(pQueryAttr)) { ekey = pWindow->ekey; @@ -1012,20 +986,20 @@ static void setNotInterpoWindowKey(SQLFunctionCtx* pCtx, int32_t numOfOutput, in } } -static void saveDataBlockLastRow(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pDataBlockInfo, SArray* pDataBlock, +static void saveDataBlockLastRow(STaskRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pDataBlockInfo, SArray* pDataBlock, int32_t rowIndex) { if (pDataBlock == NULL) { return; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; for (int32_t k = 0; k < pQueryAttr->numOfCols; ++k) { SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, k); memcpy(pRuntimeEnv->prevRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * rowIndex), pColInfo->info.bytes); } } -static TSKEY getStartTsKey(SQueryAttr* pQueryAttr, STimeWindow* win, const TSKEY* tsCols, int32_t rows) { +static TSKEY getStartTsKey(STaskAttr* pQueryAttr, STimeWindow* win, const TSKEY* tsCols, int32_t rows) { TSKEY ts = TSKEY_INITIAL_VAL; bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); @@ -1126,7 +1100,7 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, } static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunctionCtx* pCtx, SSDataBlock* pSDataBlock) { - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; for (int32_t k = 0; k < pOperator->numOfOutput; ++k) { if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) { @@ -1136,8 +1110,8 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction } } -static void projectApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t numOfOutput) { - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +static void projectApplyFunctions(STaskRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t numOfOutput) { + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; for (int32_t k = 0; k < numOfOutput; ++k) { pCtx[k].startTs = pQueryAttr->window.skey; @@ -1161,7 +1135,7 @@ static void projectApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, SArray* pDataBlock, TSKEY prevTs, int32_t prevRowIndex, TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type) { - SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; SExprInfo* pExpr = pOperator->pExpr; SQLFunctionCtx* pCtx = pInfo->pCtx; @@ -1226,8 +1200,8 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SQLFunctionCtx* pCtx, int32_t pos, int32_t numOfRows, SArray* pDataBlock, const TSKEY* tsCols, STimeWindow* win) { - SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); @@ -1257,8 +1231,8 @@ static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SQLF static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SQLFunctionCtx* pCtx, int32_t endRowIndex, SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey, STimeWindow* win) { - SQueryRuntimeEnv *pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskRuntimeEnv *pRuntimeEnv = pOperatorInfo->pRuntimeEnv; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfOutput = pOperatorInfo->numOfOutput; TSKEY actualEndKey = tsCols[endRowIndex]; @@ -1289,8 +1263,8 @@ static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SQLFun static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlock, SQLFunctionCtx* pCtx, SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardStep) { - SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; if (!pQueryAttr->timeWindowInterpo) { return; } @@ -1340,9 +1314,9 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pSDataBlock, int32_t tableGroupId) { STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*) pOperatorInfo->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; int32_t numOfOutput = pOperatorInfo->numOfOutput; - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); @@ -1361,7 +1335,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul TSKEY ts = getStartTsKey(pQueryAttr, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows); STimeWindow win = getActiveTimeWindow(pResultRowInfo, ts, pQueryAttr); - bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); + bool masterScan = IS_MAIN_SCAN(pRuntimeEnv); SResultRow* pResult = NULL; int32_t ret = setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId, pInfo->pCtx, @@ -1450,9 +1424,9 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul static void hashAllIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pSDataBlock, int32_t tableGroupId) { STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*) pOperatorInfo->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; int32_t numOfOutput = pOperatorInfo->numOfOutput; - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); @@ -1469,7 +1443,7 @@ static void hashAllIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pRe TSKEY ts = getStartTsKey(pQueryAttr, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows); STimeWindow win = getCurrentActiveTimeWindow(pResultRowInfo, ts, pQueryAttr); - bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); + bool masterScan = IS_MAIN_SCAN(pRuntimeEnv); SResultRow* pResult = NULL; int32_t forwardStep = 0; @@ -1525,12 +1499,12 @@ static void hashAllIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pRe static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; STableQueryInfo* item = pRuntimeEnv->current; SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex); - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int16_t bytes = pColInfoData->info.bytes; int16_t type = pColInfoData->info.type; @@ -1607,13 +1581,13 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn } static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; STableQueryInfo* item = pRuntimeEnv->current; // primary timestamp column SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, 0); - bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); + bool masterScan = IS_MAIN_SCAN(pRuntimeEnv); SOptrBasicInfo* pBInfo = &pInfo->binfo; int64_t gap = pOperator->pRuntimeEnv->pQueryAttr->sw.gap; @@ -1692,7 +1666,7 @@ static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) { } } -static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex) { +static int32_t setGroupResultOutputBuf(STaskRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex) { SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf; int32_t *rowCellInfoOffset = binfo->rowCellInfoOffset; @@ -1746,9 +1720,9 @@ static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pD return -1; } -static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx) { +static bool functionNeedToExecute(STaskRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx) { struct SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx); - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; // in case of timestamp column, always generated results. int32_t functionId = pCtx->functionId; @@ -1843,9 +1817,9 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { return TSDB_CODE_SUCCESS; } -static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, +static SQLFunctionCtx* createSQLFunctionCtx(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, int32_t** rowCellInfoOffset) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; SQLFunctionCtx * pFuncCtx = (SQLFunctionCtx *)calloc(numOfOutput, sizeof(SQLFunctionCtx)); if (pFuncCtx == NULL) { @@ -1965,9 +1939,9 @@ static void* destroySQLFunctionCtx(SQLFunctionCtx* pCtx, int32_t numOfOutput) { return NULL; } -static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfTables, SArray* pOperator, void* merger) { +static int32_t setupQueryRuntimeEnv(STaskRuntimeEnv *pRuntimeEnv, int32_t numOfTables, SArray* pOperator, void* merger) { //qDebug("QInfo:0x%"PRIx64" setup runtime env", GET_QID(pRuntimeEnv)); - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; pRuntimeEnv->prevGroupId = INT32_MIN; pRuntimeEnv->pQueryAttr = pQueryAttr; @@ -2019,30 +1993,30 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf // case OP_MultiTableTimeInterval: { // pRuntimeEnv->proot = // createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // break; // } // case OP_AllMultiTableTimeInterval: { // pRuntimeEnv->proot = // createAllMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // break; // } // case OP_TimeWindow: { // pRuntimeEnv->proot = // createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); -// int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType; +// int32_t opType = pRuntimeEnv->proot->downstream[0]->operatorType; // if (opType != OP_DummyInput && opType != OP_Join) { -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // } // break; // } // case OP_AllTimeWindow: { // pRuntimeEnv->proot = // createAllTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); -// int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType; +// int32_t opType = pRuntimeEnv->proot->downstream[0]->operatorType; // if (opType != OP_DummyInput && opType != OP_Join) { -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // } // break; // } @@ -2050,34 +2024,34 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf // pRuntimeEnv->proot = // createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); // -// int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType; +// int32_t opType = pRuntimeEnv->proot->downstream[0]->operatorType; // if (opType != OP_DummyInput) { -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // } // break; // } // case OP_SessionWindow: { // pRuntimeEnv->proot = // createSWindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); -// int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType; +// int32_t opType = pRuntimeEnv->proot->downstream[0]->operatorType; // if (opType != OP_DummyInput) { -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // } // break; // } // case OP_MultiTableAggregate: { // pRuntimeEnv->proot = // createMultiTableAggOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // break; // } // case OP_Aggregate: { // pRuntimeEnv->proot = // createAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); // -// int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType; +// int32_t opType = pRuntimeEnv->proot->downstream[0]->operatorType; // if (opType != OP_DummyInput && opType != OP_Join) { -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // } // break; // } @@ -2099,9 +2073,9 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf // // case OP_StateWindow: { // pRuntimeEnv->proot = createStatewindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); -// int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType; +// int32_t opType = pRuntimeEnv->proot->downstream[0]->operatorType; // if (opType != OP_DummyInput) { -// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); +// setTableScanFilterOperatorInfo(pRuntimeEnv->proot->downstream[0]->info, pRuntimeEnv->proot); // } // break; // } @@ -2187,8 +2161,8 @@ _clean: return TSDB_CODE_QRY_OUT_OF_MEMORY; } -static void doFreeQueryHandle(SQueryRuntimeEnv* pRuntimeEnv) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; +static void doFreeQueryHandle(STaskRuntimeEnv* pRuntimeEnv) { + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; // tsdbCleanupQueryHandle(pRuntimeEnv->pQueryHandle); pRuntimeEnv->pQueryHandle = NULL; @@ -2197,7 +2171,7 @@ static void doFreeQueryHandle(SQueryRuntimeEnv* pRuntimeEnv) { // assert(pMemRef->ref == 0 && pMemRef->snapshot.imem == NULL && pMemRef->snapshot.mem == NULL); } -static void destroyTsComp(SQueryRuntimeEnv *pRuntimeEnv, SQueryAttr *pQueryAttr) { +static void destroyTsComp(STaskRuntimeEnv *pRuntimeEnv, STaskAttr *pQueryAttr) { if (pQueryAttr->tsCompQuery && pRuntimeEnv->outputBuf && pRuntimeEnv->outputBuf->pDataBlock && taosArrayGetSize(pRuntimeEnv->outputBuf->pDataBlock) > 0) { SColumnInfoData* pColInfoData = taosArrayGet(pRuntimeEnv->outputBuf->pDataBlock, 0); if (pColInfoData) { @@ -2210,8 +2184,8 @@ static void destroyTsComp(SQueryRuntimeEnv *pRuntimeEnv, SQueryAttr *pQueryAttr) } } -static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +static void teardownQueryRuntimeEnv(STaskRuntimeEnv *pRuntimeEnv) { + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SQInfo* pQInfo = (SQInfo*) pRuntimeEnv->qinfo; //qDebug("QInfo:0x%"PRIx64" teardown runtime env", pQInfo->qId); @@ -2271,7 +2245,7 @@ bool isQueryKilled(SQInfo *pQInfo) { void setQueryKilled(SQInfo *pQInfo) { pQInfo->code = TSDB_CODE_TSC_QUERY_CANCELLED;} -//static bool isFixedOutputQuery(SQueryAttr* pQueryAttr) { +//static bool isFixedOutputQuery(STaskAttr* pQueryAttr) { // if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { // return false; // } @@ -2297,7 +2271,7 @@ void setQueryKilled(SQInfo *pQInfo) { pQInfo->code = TSDB_CODE_TSC_QUERY_CANCELL //} // todo refactor with isLastRowQuery -//bool isPointInterpoQuery(SQueryAttr *pQueryAttr) { +//bool isPointInterpoQuery(STaskAttr *pQueryAttr) { // for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { // int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; // if (functionId == FUNCTION_INTERP) { @@ -2308,7 +2282,7 @@ void setQueryKilled(SQInfo *pQInfo) { pQInfo->code = TSDB_CODE_TSC_QUERY_CANCELL // return false; //} -static bool isFirstLastRowQuery(SQueryAttr *pQueryAttr) { +static bool isFirstLastRowQuery(STaskAttr *pQueryAttr) { for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functionID = getExprFunctionId(&pQueryAttr->pExpr1[i]); if (functionID == FUNCTION_LAST_ROW) { @@ -2319,7 +2293,7 @@ static bool isFirstLastRowQuery(SQueryAttr *pQueryAttr) { return false; } -static bool isCachedLastQuery(SQueryAttr *pQueryAttr) { +static bool isCachedLastQuery(STaskAttr *pQueryAttr) { for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]); if (functionId == FUNCTION_LAST || functionId == FUNCTION_LAST_DST) { @@ -2354,7 +2328,7 @@ static bool isCachedLastQuery(SQueryAttr *pQueryAttr) { * The following 4 kinds of query are treated as the tags query * tagprj, tid_tag query, count(tbname), 'abc' (user defined constant value column) query */ -bool onlyQueryTags(SQueryAttr* pQueryAttr) { +bool onlyQueryTags(STaskAttr* pQueryAttr) { for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { SExprInfo* pExprInfo = &pQueryAttr->pExpr1[i]; @@ -2373,7 +2347,7 @@ bool onlyQueryTags(SQueryAttr* pQueryAttr) { ///////////////////////////////////////////////////////////////////////////////////////////// -void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win) { +void getAlignQueryTimeWindow(STaskAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win) { assert(key >= keyFirst && key <= keyLast && pQueryAttr->interval.sliding <= pQueryAttr->interval.interval); win->skey = taosTimeTruncate(key, &pQueryAttr->interval, pQueryAttr->precision); @@ -2394,7 +2368,7 @@ void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFir /* * todo add more parameters to check soon.. */ -bool colIdCheck(SQueryAttr *pQueryAttr, uint64_t qId) { +bool colIdCheck(STaskAttr *pQueryAttr, uint64_t qId) { // load data column information is incorrect for (int32_t i = 0; i < pQueryAttr->numOfCols - 1; ++i) { if (pQueryAttr->tableCols[i].colId == pQueryAttr->tableCols[i + 1].colId) { @@ -2408,7 +2382,7 @@ bool colIdCheck(SQueryAttr *pQueryAttr, uint64_t qId) { // todo ignore the avg/sum/min/max/count/stddev/top/bottom functions, of which // the scan order is not matter -static bool onlyOneQueryType(SQueryAttr *pQueryAttr, int32_t functId, int32_t functIdDst) { +static bool onlyOneQueryType(STaskAttr *pQueryAttr, int32_t functId, int32_t functIdDst) { for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]); @@ -2425,13 +2399,13 @@ static bool onlyOneQueryType(SQueryAttr *pQueryAttr, int32_t functId, int32_t fu return true; } -static bool onlyFirstQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, FUNCTION_FIRST, FUNCTION_FIRST_DST); } +static bool onlyFirstQuery(STaskAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, FUNCTION_FIRST, FUNCTION_FIRST_DST); } -static bool onlyLastQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, FUNCTION_LAST, FUNCTION_LAST_DST); } +static bool onlyLastQuery(STaskAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, FUNCTION_LAST, FUNCTION_LAST_DST); } -static bool notContainSessionOrStateWindow(SQueryAttr *pQueryAttr) { return !(pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow); } +static bool notContainSessionOrStateWindow(STaskAttr *pQueryAttr) { return !(pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow); } -static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { +static int32_t updateBlockLoadStatus(STaskAttr *pQuery, int32_t status) { bool hasFirstLastFunc = false; bool hasOtherFunc = false; @@ -2465,7 +2439,7 @@ static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { return status; } -static void doUpdateLastKey(SQueryAttr* pQueryAttr) { +static void doUpdateLastKey(STaskAttr* pQueryAttr) { STimeWindow* win = &pQueryAttr->window; size_t num = taosArrayGetSize(pQueryAttr->tableGroupInfo.pGroupList); @@ -2484,8 +2458,8 @@ static void doUpdateLastKey(SQueryAttr* pQueryAttr) { } } -static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool stableQuery) { - SQueryAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; +static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableReq* pQueryMsg, bool stableQuery) { + STaskAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; // in case of point-interpolation query, use asc order scan char msg[] = "QInfo:0x%"PRIx64" scan order changed for %s query, old:%d, new:%d, qrange exchanged, old qrange:%" PRId64 @@ -2580,8 +2554,8 @@ static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool } } -static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; +static void getIntermediateBufInfo(STaskRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) { + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t MIN_ROWS_PER_PAGE = 4; *rowsize = (int32_t)(pQueryAttr->resultRowSize * getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); @@ -2596,8 +2570,8 @@ static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, i #define IS_PREFILTER_TYPE(_t) ((_t) != TSDB_DATA_TYPE_BINARY && (_t) != TSDB_DATA_TYPE_NCHAR) -//static FORCE_INLINE bool doFilterByBlockStatistics(SQueryRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis, SQLFunctionCtx *pCtx, int32_t numOfRows) { -// SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; +//static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis, SQLFunctionCtx *pCtx, int32_t numOfRows) { +// STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; // // if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) { // return true; @@ -2606,7 +2580,7 @@ static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, i // return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows); //} -static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlockInfo) { +static bool overlapWithTimeWindow(STaskAttr* pQueryAttr, SDataBlockInfo* pBlockInfo) { STimeWindow w = {0}; TSKEY sk = MIN(pQueryAttr->window.skey, pQueryAttr->window.ekey); @@ -2655,7 +2629,7 @@ static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlock return false; } -static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key, bool ascQuery) { +static int32_t doTSJoinFilter(STaskRuntimeEnv *pRuntimeEnv, TSKEY key, bool ascQuery) { STSElem elem = tsBufGetElem(pRuntimeEnv->pTsBuf); #if defined(_DEBUG_VIEW) @@ -2781,7 +2755,7 @@ void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p) { } } -void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, +void filterRowsInDataBlock(STaskRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock, bool ascQuery) { int32_t numOfRows = pBlock->info.rows; @@ -2823,7 +2797,7 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf tfree(p); } -void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock, bool ascQuery) { +void filterColRowsInDataBlock(STaskRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock, bool ascQuery) { int32_t numOfRows = pBlock->info.rows; int8_t *p = NULL; @@ -2913,22 +2887,35 @@ void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFi } } -int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock, - uint32_t* status) { - *status = BLK_DATA_NO_NEEDED; - pBlock->pDataBlock = NULL; - pBlock->pBlockAgg = NULL; - - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - int64_t groupId = pRuntimeEnv->current->groupIndex; - bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); - - SQInfo* pQInfo = pRuntimeEnv->qinfo; - SQueryCostInfo* pCost = &pQInfo->summary; +int32_t loadDataBlock(STaskInfo *pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock, uint32_t* status) { + STaskCostInfo* pCost = &pTaskInfo->cost; pCost->totalBlocks += 1; pCost->totalRows += pBlock->info.rows; + pCost->totalCheckedRows += pBlock->info.rows; + pCost->loadBlocks += 1; + +// pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pQueryHandle, NULL); + if (pBlock->pDataBlock == NULL) { + return terrno; + } +} + +int32_t loadDataBlockOnDemand(STaskInfo *pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock, uint32_t* status) { + *status = BLK_DATA_NO_NEEDED; + + pBlock->pDataBlock = NULL; + pBlock->pBlockAgg = NULL; + +// int64_t groupId = pRuntimeEnv->current->groupIndex; +// bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); + + STaskCostInfo* pCost = &pTaskInfo->cost; + + pCost->totalBlocks += 1; + pCost->totalRows += pBlock->info.rows; +#if 0 if (pRuntimeEnv->pTsBuf != NULL) { (*status) = BLK_DATA_ALL_NEEDED; @@ -2953,7 +2940,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa // Calculate all time windows that are overlapping or contain current data block. // If current data block is contained by all possible time window, do not load current data block. if (/*pQueryAttr->pFilters || */pQueryAttr->groupbyColumn || pQueryAttr->sw.gap > 0 || - (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pQueryAttr, &pBlock->info))) { + (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pTaskInfo, &pBlock->info))) { (*status) = BLK_DATA_ALL_NEEDED; } @@ -2966,7 +2953,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { SResultRow* pResult = NULL; - bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); + bool masterScan = IS_MAIN_SCAN(pRuntimeEnv); TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey; STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr); @@ -2995,7 +2982,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa } SDataBlockInfo* pBlockInfo = &pBlock->info; - *status = updateBlockLoadStatus(pRuntimeEnv->pQueryAttr, *status); +// *status = updateBlockLoadStatus(pRuntimeEnv->pQueryAttr, *status); if ((*status) == BLK_DATA_NO_NEEDED || (*status) == BLK_DATA_DISCARD) { //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey, @@ -3022,7 +3009,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { SResultRow* pResult = NULL; - bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); + bool masterScan = IS_MAIN_SCAN(pRuntimeEnv); TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey; STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr); @@ -3074,7 +3061,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa // filterColRowsInDataBlock(pRuntimeEnv, pBlock, ascQuery); // } } - +#endif return TSDB_CODE_SUCCESS; } @@ -3184,10 +3171,10 @@ static SColumnInfo* doGetTagColumnInfoById(SColumnInfo* pTagColList, int32_t num } void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCtx, int32_t numOfOutput) { - SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; SExprInfo *pExpr = pOperatorInfo->pExpr; - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SExprInfo* pExprInfo = &pExpr[0]; int32_t functionId = getExprFunctionId(pExprInfo); @@ -3242,7 +3229,7 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt } } -void copyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, int32_t threshold, SSDataBlock* pBlock, int32_t* offset) { +void copyToSDataBlock(STaskRuntimeEnv* pRuntimeEnv, int32_t threshold, SSDataBlock* pBlock, int32_t* offset) { SGroupResInfo* pGroupResInfo = &pRuntimeEnv->groupResInfo; pBlock->info.rows = 0; @@ -3293,9 +3280,8 @@ static void updateTableQueryInfoForReverseScan(STableQueryInfo *pTableQueryInfo) } } -static void setupQueryRangeForReverseScan(SQueryRuntimeEnv* pRuntimeEnv) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - +static void setupQueryRangeForReverseScan(STableScanInfo* pTableScanInfo) { +#if 0 int32_t numOfGroups = (int32_t)(GET_NUM_OF_TABLEGROUP(pRuntimeEnv)); for(int32_t i = 0; i < numOfGroups; ++i) { SArray *group = GET_TABLEGROUP(pRuntimeEnv, i); @@ -3314,6 +3300,8 @@ static void setupQueryRangeForReverseScan(SQueryRuntimeEnv* pRuntimeEnv) { // assert(pCheckInfo->pTable == pTableKeyInfo->pTable); } } +#endif + } void switchCtxOrder(SQLFunctionCtx* pCtx, int32_t numOfOutput) { @@ -3337,7 +3325,7 @@ int32_t initResultRow(SResultRow *pResultRow) { * +------------+-------------------------------------------+-------------------------------------------+ * offset[0] offset[1] offset[2] */ -void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, int64_t uid, int32_t stage) { +void setDefaultOutputBuf(STaskRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, int64_t uid, int32_t stage) { SQLFunctionCtx* pCtx = pInfo->pCtx; SSDataBlock* pDataBlock = pInfo->pRes; int32_t* rowCellInfoOffset = pInfo->rowCellInfoOffset; @@ -3461,40 +3449,38 @@ void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size) { } } -void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status) { +void setTaskStatus(STaskInfo *pTaskInfo, int8_t status) { if (status == QUERY_NOT_COMPLETED) { - pRuntimeEnv->status = status; + pTaskInfo->status = status; } else { // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first - CLEAR_QUERY_STATUS(pRuntimeEnv, QUERY_NOT_COMPLETED); - pRuntimeEnv->status |= status; + CLEAR_QUERY_STATUS(pTaskInfo, QUERY_NOT_COMPLETED); + pTaskInfo->status |= status; } } -static void setupEnvForReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, SQLFunctionCtx* pCtx, int32_t numOfOutput) { - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; - - if (pRuntimeEnv->pTsBuf) { - SWITCH_ORDER(pRuntimeEnv->pTsBuf->cur.order); - bool ret = tsBufNextPos(pRuntimeEnv->pTsBuf); - assert(ret); - } +static void setupEnvForReverseScan(STableScanInfo *pTableScanInfo, SQLFunctionCtx* pCtx, int32_t numOfOutput) { +// if (pRuntimeEnv->pTsBuf) { +// SWITCH_ORDER(pRuntimeEnv->pTsBuf->cur.order); +// bool ret = tsBufNextPos(pRuntimeEnv->pTsBuf); +// assert(ret); +// } // reverse order time range - SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + SWAP(pTableScanInfo->window.skey, pTableScanInfo->window.ekey, TSKEY); - SET_REVERSE_SCAN_FLAG(pRuntimeEnv); - setQueryStatus(pRuntimeEnv, QUERY_NOT_COMPLETED); + SET_REVERSE_SCAN_FLAG(pTableScanInfo); +// setTaskStatus(pTableScanInfo, QUERY_NOT_COMPLETED); switchCtxOrder(pCtx, numOfOutput); - SWITCH_ORDER(pQueryAttr->order.order); - setupQueryRangeForReverseScan(pRuntimeEnv); + SWITCH_ORDER(pTableScanInfo->order); + setupQueryRangeForReverseScan(pTableScanInfo); } void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { - SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfOutput = pOperator->numOfOutput; if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow) { @@ -3539,7 +3525,7 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult } } -static bool hasMainOutput(SQueryAttr *pQueryAttr) { +static bool hasMainOutput(STaskAttr *pQueryAttr) { for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]); @@ -3551,7 +3537,7 @@ static bool hasMainOutput(SQueryAttr *pQueryAttr) { return false; } -STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf) { +STableQueryInfo *createTableQueryInfo(STaskAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf) { STableQueryInfo *pTableQueryInfo = buf; pTableQueryInfo->win = win; @@ -3602,7 +3588,7 @@ void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo) { cleanupResultRowInfo(&pTableQueryInfo->resInfo); } -void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, +void setResultRowOutputBufInitCtx(STaskRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset) { // Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group SFilePage* bufPage = getResBufPage(pRuntimeEnv->pResultBuf, pResult->pageId); @@ -3635,7 +3621,7 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe } } -void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, SQLFunctionCtx* pCtx, +void doSetTableGroupOutputBuf(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, SQLFunctionCtx* pCtx, int32_t* rowCellInfoOffset, int32_t numOfOutput, int32_t tableGroupId) { // for simple group by query without interval, all the tables belong to one group result. int64_t uid = 0; @@ -3659,7 +3645,7 @@ void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pRe setResultRowOutputBufInitCtx(pRuntimeEnv, pResultRow, pCtx, numOfOutput, rowCellInfoOffset); } -void setExecutionContext(SQueryRuntimeEnv* pRuntimeEnv, SOptrBasicInfo* pInfo, int32_t numOfOutput, int32_t tableGroupId, +void setExecutionContext(STaskRuntimeEnv* pRuntimeEnv, SOptrBasicInfo* pInfo, int32_t numOfOutput, int32_t tableGroupId, TSKEY nextKey) { STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current; @@ -3675,7 +3661,7 @@ void setExecutionContext(SQueryRuntimeEnv* pRuntimeEnv, SOptrBasicInfo* pInfo, i pRuntimeEnv->prevGroupId = tableGroupId; } -void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, +void setResultOutputBuf(STaskRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, int32_t numOfCols, int32_t* rowCellInfoOffset) { // Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group SFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResult->pageId); @@ -3698,8 +3684,8 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLF } } -void setCtxTagForJoin(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; +void setCtxTagForJoin(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable) { + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; SSqlExpr* pExpr = &pExprInfo->base; // if (pQueryAttr->stableQuery && (pRuntimeEnv->pTsBuf != NULL) && @@ -3723,8 +3709,8 @@ void setCtxTagForJoin(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExpr // } } -int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, SVariant* pTag, STableQueryInfo *pTableQueryInfo) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; +int32_t setTimestampListJoinInfo(STaskRuntimeEnv* pRuntimeEnv, SVariant* pTag, STableQueryInfo *pTableQueryInfo) { + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; assert(pRuntimeEnv->pTsBuf != NULL); @@ -3766,9 +3752,9 @@ int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, SVariant* pTag, } // TODO refactor: this funciton should be merged with setparamForStableStddevColumnData function. -void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExprInfo) { +void setParamForStableStddev(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExprInfo) { #if 0 - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfExprs = pQueryAttr->numOfOutput; for(int32_t i = 0; i < numOfExprs; ++i) { @@ -3801,8 +3787,8 @@ void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx #endif } -void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr, char* val, int16_t bytes) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; +void setParamForStableStddevByColData(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr, char* val, int16_t bytes) { + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; #if 0 int32_t numOfExprs = pQueryAttr->numOfOutput; for(int32_t i = 0; i < numOfExprs; ++i) { @@ -3842,8 +3828,8 @@ void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunction * merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there * is a previous result generated or not. */ -void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +void setIntervalQueryRange(STaskRuntimeEnv *pRuntimeEnv, TSKEY key) { + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current; SResultRowInfo *pResultRowInfo = &pTableQueryInfo->resInfo; @@ -3887,8 +3873,8 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { * @param result */ -static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock) { - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +static int32_t doCopyToSDataBlock(STaskRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock) { + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); int32_t numOfResult = pBlock->info.rows; // there are already exists result rows @@ -3946,7 +3932,7 @@ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* return 0; } -static void toSSDataBlock(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock) { +static void toSSDataBlock(SGroupResInfo *pGroupResInfo, STaskRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock) { assert(pGroupResInfo->currentGroup <= pGroupResInfo->totalGroup); pBlock->info.rows = 0; @@ -3954,7 +3940,7 @@ static void toSSDataBlock(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv* pRunti return; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t orderType = TSDB_ORDER_ASC;//(pQueryAttr->pGroupbyExpr != NULL) ? pQueryAttr->pGroupbyExpr->orderType : TSDB_ORDER_ASC; doCopyToSDataBlock(pRuntimeEnv, pGroupResInfo, orderType, pBlock); @@ -3969,9 +3955,9 @@ static void toSSDataBlock(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv* pRunti } } -static void updateNumOfRowsInResultRows(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, +static void updateNumOfRowsInResultRows(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; // update the number of result for each, only update the number of rows for the corresponding window result. if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { @@ -4000,8 +3986,8 @@ static int32_t compressQueryColData(SColumnInfoData *pColRes, int32_t numOfRows, } static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data, int8_t compressed, int32_t *compLen) { - SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SSDataBlock* pRes = pRuntimeEnv->outputBuf; @@ -4070,7 +4056,7 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data // Check if query is completed or not for stable query or normal table query respectively. if (Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED) && pRuntimeEnv->proot->status == OP_EXEC_DONE) { - setQueryStatus(pRuntimeEnv, QUERY_OVER); +// setTaskStatus(pOperator->pTaskInfo, QUERY_OVER); } } @@ -4187,8 +4173,8 @@ void calculateOperatorProfResults(SQInfo* pQInfo) { } void queryCostStatis(SQInfo *pQInfo) { - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; - SQueryCostInfo *pSummary = &pQInfo->summary; + STaskRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; + STaskCostInfo *pSummary = &pQInfo->summary; uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable); hashSize += taosHashGetMemSize(pRuntimeEnv->tableqinfoGroupInfo.map); @@ -4226,8 +4212,8 @@ void queryCostStatis(SQInfo *pQInfo) { } } -//static void updateOffsetVal(SQueryRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) { -// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +//static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) { +// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; // // int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); @@ -4262,8 +4248,8 @@ void queryCostStatis(SQInfo *pQInfo) { // pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, pQuery->current->lastKey); //} -//void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) { -// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +//void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) { +// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // // if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) { // return; @@ -4301,8 +4287,8 @@ void queryCostStatis(SQInfo *pQInfo) { // } //} -//static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* win, SDataBlockInfo* pBlockInfo, STableQueryInfo* pTableQueryInfo) { -// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +//static TSKEY doSkipIntervalProcess(STaskRuntimeEnv* pRuntimeEnv, STimeWindow* win, SDataBlockInfo* pBlockInfo, STableQueryInfo* pTableQueryInfo) { +// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo; // // assert(pQueryAttr->limit.offset == 0); @@ -4352,8 +4338,8 @@ void queryCostStatis(SQInfo *pQInfo) { // return true; //} -//static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) { -// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +//static bool skipTimeInterval(STaskRuntimeEnv *pRuntimeEnv, TSKEY* start) { +// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // if (QUERY_IS_ASC_QUERY(pQueryAttr)) { // assert(*start <= pRuntimeEnv->current->lastKey); // } else { @@ -4463,18 +4449,18 @@ void queryCostStatis(SQInfo *pQInfo) { //} void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream) { - if (p->upstream == NULL) { - assert(p->numOfUpstream == 0); + if (p->pDownstream == NULL) { + assert(p->numOfDownstream == 0); } - p->upstream = realloc(p->upstream, POINTER_BYTES * (p->numOfUpstream + 1)); - p->upstream[p->numOfUpstream++] = pUpstream; + p->pDownstream = realloc(p->pDownstream, POINTER_BYTES * (p->numOfDownstream + 1)); + p->pDownstream[p->numOfDownstream++] = pUpstream; } static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo); -static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64_t qId, bool isSTableQuery) { - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +static int32_t setupQueryHandle(void* tsdb, STaskRuntimeEnv* pRuntimeEnv, int64_t qId, bool isSTableQuery) { + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; #if 0 // TODO set the tags scan handle if (onlyQueryTags(pQueryAttr)) { @@ -4533,9 +4519,9 @@ static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64 int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr, int32_t tbScanner, SArray* pOperator, void* param) { - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; + STaskRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; - SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; + STaskAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; pQueryAttr->tsdb = tsdb; if (tsdb != NULL) { @@ -4616,25 +4602,25 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr return code; } - setQueryStatus(pRuntimeEnv, QUERY_NOT_COMPLETED); +// setTaskStatus(pOperator->pTaskInfo, QUERY_NOT_COMPLETED); return TSDB_CODE_SUCCESS; } -static void doTableQueryInfoTimeWindowCheck(SQueryAttr* pQueryAttr, STableQueryInfo* pTableQueryInfo) { - if (QUERY_IS_ASC_QUERY(pQueryAttr)) { +static void doTableQueryInfoTimeWindowCheck(STaskInfo* pTaskInfo, STableQueryInfo* pTableQueryInfo, int32_t order) { + if (order == TSDB_ORDER_ASC) { assert( (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) && - (pTableQueryInfo->lastKey >= pTableQueryInfo->win.skey) && - (pTableQueryInfo->win.skey >= pQueryAttr->window.skey && pTableQueryInfo->win.ekey <= pQueryAttr->window.ekey)); + (pTableQueryInfo->lastKey >= pTaskInfo->window.skey) && + (pTableQueryInfo->win.skey >= pTaskInfo->window.skey && pTableQueryInfo->win.ekey <= pTaskInfo->window.ekey)); } else { assert( (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) && - (pTableQueryInfo->lastKey <= pTableQueryInfo->win.skey) && - (pTableQueryInfo->win.skey <= pQueryAttr->window.skey && pTableQueryInfo->win.ekey >= pQueryAttr->window.ekey)); + (pTableQueryInfo->lastKey <= pTaskInfo->window.skey) && + (pTableQueryInfo->win.skey <= pTaskInfo->window.skey && pTableQueryInfo->win.ekey >= pTaskInfo->window.ekey)); } } -//STsdbQueryCond createTsdbQueryCond(SQueryAttr* pQueryAttr, STimeWindow* win) { +//STsdbQueryCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win) { // STsdbQueryCond cond = { // .colList = pQueryAttr->tableCols, // .order = pQueryAttr->order.order, @@ -4676,7 +4662,7 @@ static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo) { // } //} -static void doCloseAllTimeWindow(SQueryRuntimeEnv* pRuntimeEnv) { +static void doCloseAllTimeWindow(STaskRuntimeEnv* pRuntimeEnv) { size_t numOfGroup = GET_NUM_OF_TABLEGROUP(pRuntimeEnv); for (int32_t i = 0; i < numOfGroup; ++i) { SArray* group = GET_TABLEGROUP(pRuntimeEnv, i); @@ -4693,44 +4679,37 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { SOperatorInfo *pOperator = (SOperatorInfo*) param; STableScanInfo *pTableScanInfo = pOperator->info; + STaskInfo *pTaskInfo = pOperator->pTaskInfo; + SSDataBlock *pBlock = &pTableScanInfo->block; - SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; - STableGroupInfo *pTableGroupInfo = &pOperator->pRuntimeEnv->tableqinfoGroupInfo; + STableGroupInfo *pTableGroupInfo = &pOperator->pTaskInfo->tableqinfoGroupInfo; *newgroup = false; -#if 0 - while (tsdbNextDataBlock(pTableScanInfo->pQueryHandle)) { + + while (/*tsdbNextDataBlock(pTableScanInfo->pQueryHandle)*/1) { if (isQueryKilled(pOperator->pRuntimeEnv->qinfo)) { longjmp(pOperator->pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED); } pTableScanInfo->numOfBlocks += 1; - tsdbRetrieveDataBlockInfo(pTableScanInfo->pQueryHandle, &pBlock->info); +// tsdbRetrieveDataBlockInfo(pTableScanInfo->pQueryHandle, &pBlock->info); // todo opt - if (pTableGroupInfo->numOfTables > 1 || (pRuntimeEnv->current == NULL && pTableGroupInfo->numOfTables == 1)) { - STableQueryInfo** pTableQueryInfo = - (STableQueryInfo**)taosHashGet(pTableGroupInfo->map, &pBlock->info.uid, sizeof(pBlock->info.uid)); - if (pTableQueryInfo == NULL) { - break; - } - - pRuntimeEnv->current = *pTableQueryInfo; - doTableQueryInfoTimeWindowCheck(pQueryAttr, *pTableQueryInfo); - - if (pRuntimeEnv->enableGroupData) { - if(pTableScanInfo->prevGroupId != -1 && pTableScanInfo->prevGroupId != (*pTableQueryInfo)->groupIndex) { - *newgroup = true; - } - } - - pTableScanInfo->prevGroupId = (*pTableQueryInfo)->groupIndex; - } +// if (pTableGroupInfo->numOfTables > 1 || (pRuntimeEnv->current == NULL && pTableGroupInfo->numOfTables == 1)) { +// STableQueryInfo** pTableQueryInfo = +// (STableQueryInfo**)taosHashGet(pTableGroupInfo->map, &pBlock->info.uid, sizeof(pBlock->info.uid)); +// if (pTableQueryInfo == NULL) { +// break; +// } +// +// pRuntimeEnv->current = *pTableQueryInfo; +// doTableQueryInfoTimeWindowCheck(pTaskInfo, *pTableQueryInfo, pTableScanInfo->order); +// } // this function never returns error? uint32_t status; - int32_t code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status); + int32_t code = loadDataBlock(pTaskInfo, pTableScanInfo, pBlock, &status); +// int32_t code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status); if (code != TSDB_CODE_SUCCESS) { longjmp(pOperator->pRuntimeEnv->env, code); } @@ -4742,7 +4721,6 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { return pBlock; } -#endif return NULL; } @@ -4750,9 +4728,8 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { static SSDataBlock* doTableScan(void* param, bool *newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; - STableScanInfo *pTableScanInfo = pOperator->info; - SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STableScanInfo *pTableScanInfo = pOperator->info; + STaskInfo *pTaskInfo = pOperator->pTaskInfo; SResultRowInfo* pResultRowInfo = pTableScanInfo->pResultRowInfo; *newgroup = false; @@ -4775,14 +4752,14 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) { // STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window); // tsdbResetQueryHandle(pTableScanInfo->pQueryHandle, &cond); - setQueryStatus(pRuntimeEnv, QUERY_NOT_COMPLETED); - pRuntimeEnv->scanFlag = REPEAT_SCAN; - - if (pRuntimeEnv->pTsBuf) { - bool ret = tsBufNextPos(pRuntimeEnv->pTsBuf); - assert(ret); - } + setTaskStatus(pTaskInfo, QUERY_NOT_COMPLETED); + pTableScanInfo->scanFlag = REPEAT_SCAN; +// if (pTaskInfo->pTsBuf) { +// bool ret = tsBufNextPos(pRuntimeEnv->pTsBuf); +// assert(ret); +// } +// if (pResultRowInfo->size > 0) { pResultRowInfo->curPos = 0; } @@ -4792,17 +4769,15 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) { } SSDataBlock *p = NULL; + // todo refactor if (pTableScanInfo->reverseTimes > 0) { - setupEnvForReverseScan(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput); - + setupEnvForReverseScan(pTableScanInfo, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput); // STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window); // tsdbResetQueryHandle(pTableScanInfo->pQueryHandle, &cond); //qDebug("QInfo:0x%"PRIx64" start to reverse scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64, // GET_QID(pRuntimeEnv), cond.twindow.skey, cond.twindow.ekey); - pRuntimeEnv->scanFlag = REVERSE_SCAN; - pTableScanInfo->times = 1; pTableScanInfo->current = 0; pTableScanInfo->reverseTimes = 0; @@ -4867,31 +4842,31 @@ static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) { } -SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime) { - assert(repeatTime > 0); +SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime) { + assert(repeatTime > 0 && numOfOutput > 0); STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); - pInfo->pQueryHandle = pTsdbQueryHandle; - pInfo->times = repeatTime; - pInfo->reverseTimes = 0; - pInfo->order = pRuntimeEnv->pQueryAttr->order.order; - pInfo->current = 0; -// pInfo->prevGroupId = -1; + pInfo->pQueryHandle = pTsdbQueryHandle; + pInfo->times = repeatTime; + pInfo->reverseTimes = 0; + pInfo->order = order; + pInfo->current = 0; + pInfo->scanFlag = MAIN_SCAN; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableScanOperator"; -// pOperator->operatorType = OP_TableScan; + pOperator->operatorType = OP_TableScan; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; - pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = NULL; pOperator->exec = doTableScan; return pOperator; } -SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv) { +SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv) { STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); pInfo->pQueryHandle = pTsdbQueryHandle; @@ -4915,7 +4890,7 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeE return pOperator; } -SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv) { +SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv) { STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); pInfo->pQueryHandle = pTsdbQueryHandle; @@ -4998,7 +4973,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf } -SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime) { +SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime) { assert(repeatTime > 0); STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); @@ -5019,7 +4994,7 @@ SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntime return pOptr; } -SArray* getOrderCheckColumns(SQueryAttr* pQuery) { +SArray* getOrderCheckColumns(STaskAttr* pQuery) { int32_t numOfCols = (pQuery->pGroupbyExpr == NULL)? 0: taosArrayGetSize(pQuery->pGroupbyExpr->columnInfo); SArray* pOrderColumns = NULL; @@ -5058,7 +5033,7 @@ SArray* getOrderCheckColumns(SQueryAttr* pQuery) { return pOrderColumns; } -SArray* getResultGroupCheckColumns(SQueryAttr* pQuery) { +SArray* getResultGroupCheckColumns(STaskAttr* pQuery) { int32_t numOfCols = (pQuery->pGroupbyExpr == NULL)? 0 : taosArrayGetSize(pQuery->pGroupbyExpr->columnInfo); SArray* pOrderColumns = NULL; @@ -5109,7 +5084,7 @@ static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) { tfree(pInfo->prevRow); } -SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, +SOperatorInfo* createGlobalAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo, bool groupResultMixedUp) { SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo)); @@ -5172,12 +5147,12 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, pOperator->exec = doGlobalAggregate; pOperator->cleanup = destroyGlobalAggOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo *createMultiwaySortOperatorInfo(SQueryRuntimeEnv *pRuntimeEnv, SExprInfo *pExpr, int32_t numOfOutput, +SOperatorInfo *createMultiwaySortOperatorInfo(STaskRuntimeEnv *pRuntimeEnv, SExprInfo *pExpr, int32_t numOfOutput, int32_t numOfRows, void *merger) { SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo)); @@ -5252,9 +5227,9 @@ static SSDataBlock* doSort(void* param, bool* newgroup) { SSDataBlock* pBlock = NULL; while(1) { - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); - pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); + pBlock = pOperator->pDownstream[0]->exec(pOperator->pDownstream[0], newgroup); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); // start to flush data into disk and try do multiway merge sort if (pBlock == NULL) { @@ -5288,7 +5263,7 @@ static SSDataBlock* doSort(void* param, bool* newgroup) { return (pInfo->pDataBlock->info.rows > 0)? pInfo->pDataBlock:NULL; } -SOperatorInfo *createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, SOrder* pOrderVal) { +SOperatorInfo *createOrderOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, SOrder* pOrderVal) { SOrderOperatorInfo* pInfo = calloc(1, sizeof(SOrderOperatorInfo)); { @@ -5321,7 +5296,7 @@ SOperatorInfo *createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI pOperator->cleanup = destroyOrderOperatorInfo; pOperator->pRuntimeEnv = pRuntimeEnv; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } @@ -5339,17 +5314,17 @@ static SSDataBlock* doAggregate(void* param, bool* newgroup) { SAggOperatorInfo* pAggInfo = pOperator->info; SOptrBasicInfo* pInfo = &pAggInfo->binfo; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; @@ -5359,8 +5334,8 @@ static SSDataBlock* doAggregate(void* param, bool* newgroup) { setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput); } -// if (upstream->operatorType == OP_DataBlocksOptScan) { -// STableScanInfo* pScanInfo = upstream->info; +// if (downstream->operatorType == OP_DataBlocksOptScan) { +// STableScanInfo* pScanInfo = downstream->info; // order = getTableScanOrder(pScanInfo); // } @@ -5386,7 +5361,7 @@ static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) { SAggOperatorInfo* pAggInfo = pOperator->info; SOptrBasicInfo* pInfo = &pAggInfo->binfo; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pInfo->pRes); @@ -5398,15 +5373,15 @@ static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) { return pInfo->pRes; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; @@ -5414,8 +5389,8 @@ static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) { setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput); -// if (upstream->operatorType == OP_DataBlocksOptScan) { -// STableScanInfo* pScanInfo = upstream->info; +// if (downstream->operatorType == OP_DataBlocksOptScan) { +// STableScanInfo* pScanInfo = downstream->info; // order = getTableScanOrder(pScanInfo); // } @@ -5455,7 +5430,7 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; SProjectOperatorInfo* pProjectInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; SOptrBasicInfo *pInfo = &pProjectInfo->binfo; SSDataBlock* pRes = pInfo->pRes; @@ -5492,16 +5467,16 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { while(1) { bool prevVal = *newgroup; - // The upstream exec may change the value of the newgroup, so use a local variable instead. - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + // The downstream exec may change the value of the newgroup, so use a local variable instead. + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = pOperator->pDownstream[0]->exec(pOperator->pDownstream[0], newgroup); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { assert(*newgroup == false); *newgroup = prevVal; - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); break; } @@ -5547,13 +5522,13 @@ static SSDataBlock* doLimit(void* param, bool* newgroup) { } SLimitOperatorInfo* pInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; SSDataBlock* pBlock = NULL; while (1) { - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); - pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); + pBlock = pOperator->pDownstream[0]->exec(pOperator->pDownstream[0], newgroup); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { doSetOperatorCompleted(pOperator); @@ -5599,12 +5574,12 @@ static SSDataBlock* doFilter(void* param, bool* newgroup) { } SFilterOperatorInfo* pCondInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; while (1) { - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock *pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock *pBlock = pOperator->pDownstream[0]->exec(pOperator->pDownstream[0], newgroup); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; @@ -5631,7 +5606,7 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { STableIntervalOperatorInfo* pIntervalInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes); if (pIntervalInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) { @@ -5641,16 +5616,16 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { return pIntervalInfo->pRes; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; STimeWindow win = pQueryAttr->window; - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; @@ -5669,7 +5644,7 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pIntervalInfo->resultRowInfo); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); finalizeQueryResult(pOperator, pIntervalInfo->pCtx, &pIntervalInfo->resultRowInfo, pIntervalInfo->rowCellInfoOffset); initGroupResInfo(&pRuntimeEnv->groupResInfo, &pIntervalInfo->resultRowInfo); @@ -5690,7 +5665,7 @@ static SSDataBlock* doAllIntervalAgg(void* param, bool* newgroup) { STableIntervalOperatorInfo* pIntervalInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes); @@ -5701,16 +5676,16 @@ static SSDataBlock* doAllIntervalAgg(void* param, bool* newgroup) { return pIntervalInfo->pRes; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; STimeWindow win = pQueryAttr->window; - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; @@ -5729,7 +5704,7 @@ static SSDataBlock* doAllIntervalAgg(void* param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pIntervalInfo->resultRowInfo); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); finalizeQueryResult(pOperator, pIntervalInfo->pCtx, &pIntervalInfo->resultRowInfo, pIntervalInfo->rowCellInfoOffset); initGroupResInfo(&pRuntimeEnv->groupResInfo, &pIntervalInfo->resultRowInfo); @@ -5749,7 +5724,7 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { } STableIntervalOperatorInfo* pIntervalInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { int64_t st = taosGetTimestampUs(); @@ -5765,15 +5740,15 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { return pIntervalInfo->pRes; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; @@ -5792,7 +5767,7 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; pQueryAttr->order.order = order; // TODO : restore the order doCloseAllTimeWindow(pRuntimeEnv); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); copyToSDataBlock(pRuntimeEnv, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset); if (pIntervalInfo->pRes->info.rows == 0 || !hasRemainData(&pRuntimeEnv->groupResInfo)) { @@ -5809,7 +5784,7 @@ static SSDataBlock* doAllSTableIntervalAgg(void* param, bool* newgroup) { } STableIntervalOperatorInfo* pIntervalInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { copyToSDataBlock(pRuntimeEnv, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset); @@ -5820,15 +5795,15 @@ static SSDataBlock* doAllSTableIntervalAgg(void* param, bool* newgroup) { return pIntervalInfo->pRes; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; @@ -5847,7 +5822,7 @@ static SSDataBlock* doAllSTableIntervalAgg(void* param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; pQueryAttr->order.order = order; // TODO : restore the order doCloseAllTimeWindow(pRuntimeEnv); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); int64_t st = taosGetTimestampUs(); copyToSDataBlock(pRuntimeEnv, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset); @@ -5862,13 +5837,13 @@ static SSDataBlock* doAllSTableIntervalAgg(void* param, bool* newgroup) { } static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; STableQueryInfo* item = pRuntimeEnv->current; SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex); SOptrBasicInfo* pBInfo = &pInfo->binfo; - bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); + bool masterScan = IS_MAIN_SCAN(pRuntimeEnv); int16_t bytes = pColInfoData->info.bytes; int16_t type = pColInfoData->info.type; @@ -5945,7 +5920,7 @@ static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) { SStateWindowOperatorInfo* pWindowInfo = pOperator->info; SOptrBasicInfo* pBInfo = &pWindowInfo->binfo; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes); @@ -5956,14 +5931,14 @@ static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) { return pBInfo->pRes; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; STimeWindow win = pQueryAttr->window; - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while (1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; @@ -5981,7 +5956,7 @@ static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pBInfo->resultRowInfo); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); finalizeQueryResult(pOperator, pBInfo->pCtx, &pBInfo->resultRowInfo, pBInfo->rowCellInfoOffset); initGroupResInfo(&pRuntimeEnv->groupResInfo, &pBInfo->resultRowInfo); @@ -6004,7 +5979,7 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { SOptrBasicInfo* pBInfo = &pWindowInfo->binfo; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes); @@ -6015,17 +5990,17 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { return pBInfo->pRes; } - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; //pQueryAttr->order.order = TSDB_ORDER_ASC; int32_t order = pQueryAttr->order.order; STimeWindow win = pQueryAttr->window; - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; } @@ -6041,7 +6016,7 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pBInfo->resultRowInfo); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); +// setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); finalizeQueryResult(pOperator, pBInfo->pCtx, &pBInfo->resultRowInfo, pBInfo->rowCellInfoOffset); initGroupResInfo(&pRuntimeEnv->groupResInfo, &pBInfo->resultRowInfo); @@ -6062,7 +6037,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { SGroupbyOperatorInfo *pInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pInfo->binfo.pRes); @@ -6073,12 +6048,12 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { return pInfo->binfo.pRes; } - SOperatorInfo* upstream = pOperator->upstream[0]; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while(1) { - publishOperatorProfEvent(upstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = upstream->exec(upstream, newgroup); - publishOperatorProfEvent(upstream, QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = downstream->exec(downstream, newgroup); + publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { break; } @@ -6095,7 +6070,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pInfo->binfo.resultRowInfo); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); +// setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); if (!pRuntimeEnv->pQueryAttr->stableQuery) { // finalize include the update of result rows finalizeQueryResult(pOperator, pInfo->binfo.pCtx, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); @@ -6117,7 +6092,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { return pInfo->binfo.pRes; } -static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo *pInfo, SQueryRuntimeEnv* pRuntimeEnv, bool* newgroup) { +static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo *pInfo, STaskRuntimeEnv* pRuntimeEnv, bool* newgroup) { pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows; int64_t ekey = Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED)?pRuntimeEnv->pQueryAttr->window.ekey:pInfo->existNewGroupBlock->info.window.ekey; taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo)); @@ -6130,7 +6105,7 @@ static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo *pInfo, SQueryR *newgroup = true; } -static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo *pInfo, SQueryRuntimeEnv *pRuntimeEnv, bool *newgroup) { +static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo *pInfo, STaskRuntimeEnv *pRuntimeEnv, bool *newgroup) { if (taosFillHasMoreResults(pInfo->pFillInfo)) { *newgroup = false; doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pRuntimeEnv->resultInfo.capacity, pInfo->p); @@ -6155,16 +6130,16 @@ static SSDataBlock* doFill(void* param, bool* newgroup) { return NULL; } - SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; doHandleRemainBlockFromNewGroup(pInfo, pRuntimeEnv, newgroup); if (pInfo->pRes->info.rows > pRuntimeEnv->resultInfo.threshold || (!pInfo->multigroupResult && pInfo->pRes->info.rows > 0)) { return pInfo->pRes; } while(1) { - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); - SSDataBlock* pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); + SSDataBlock* pBlock = pOperator->pDownstream[0]->exec(pOperator->pDownstream[0], newgroup); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); if (*newgroup) { assert(pBlock != NULL); @@ -6220,7 +6195,7 @@ static SSDataBlock* doFill(void* param, bool* newgroup) { } // todo set the attribute of query scan count -static int32_t getNumOfScanTimes(SQueryAttr* pQueryAttr) { +static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) { for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]); if (functionId == FUNCTION_STDDEV || functionId == FUNCTION_PERCT) { @@ -6240,23 +6215,23 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) { pOperator->cleanup(pOperator->info, pOperator->numOfOutput); } - if (pOperator->upstream != NULL) { - for(int32_t i = 0; i < pOperator->numOfUpstream; ++i) { - destroyOperatorInfo(pOperator->upstream[i]); + if (pOperator->pDownstream != NULL) { + for(int32_t i = 0; i < pOperator->numOfDownstream; ++i) { + destroyOperatorInfo(pOperator->pDownstream[i]); } - tfree(pOperator->upstream); - pOperator->numOfUpstream = 0; + tfree(pOperator->pDownstream); + pOperator->numOfDownstream = 0; } tfree(pOperator->info); tfree(pOperator); } -SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo)); - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfRows = (int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, numOfRows); @@ -6265,7 +6240,7 @@ SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); pInfo->seed = rand(); - setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MASTER_SCAN); + setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MAIN_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableAggregate"; @@ -6279,7 +6254,7 @@ SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera pOperator->exec = doAggregate; pOperator->cleanup = destroyAggOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } @@ -6353,7 +6328,7 @@ static void destroyDistinctOperatorInfo(void* param, int32_t numOfOutput) { pInfo->pRes = destroyOutputBuf(pInfo->pRes); } -SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createMultiTableAggOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo)); size_t tableGroup = GET_NUM_OF_TABLEGROUP(pRuntimeEnv); @@ -6374,12 +6349,12 @@ SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SO pOperator->exec = doSTableAggregate; pOperator->cleanup = destroyAggOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createProjectOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createProjectOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SProjectOperatorInfo* pInfo = calloc(1, sizeof(SProjectOperatorInfo)); pInfo->seed = rand(); @@ -6390,7 +6365,7 @@ SOperatorInfo* createProjectOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pBInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pBInfo->rowCellInfoOffset); initResultRowInfo(&pBInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT); - setDefaultOutputBuf(pRuntimeEnv, pBInfo, pInfo->seed, MASTER_SCAN); + setDefaultOutputBuf(pRuntimeEnv, pBInfo, pInfo->seed, MAIN_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "ProjectOperator"; @@ -6404,7 +6379,7 @@ SOperatorInfo* createProjectOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pOperator->exec = doProjectOperation; pOperator->cleanup = destroyProjectOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } @@ -6442,7 +6417,7 @@ SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int3 return 0; } -SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, +SOperatorInfo* createFilterOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter) { SFilterOperatorInfo* pInfo = calloc(1, sizeof(SFilterOperatorInfo)); @@ -6462,12 +6437,12 @@ SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->cleanup = destroyConditionOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream) { +SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream) { SLimitOperatorInfo* pInfo = calloc(1, sizeof(SLimitOperatorInfo)); pInfo->limit = pRuntimeEnv->pQueryAttr->limit.limit; @@ -6480,12 +6455,12 @@ SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI pOperator->exec = doLimit; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); @@ -6505,12 +6480,12 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp pOperator->exec = doIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createAllTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); @@ -6530,11 +6505,11 @@ SOperatorInfo* createAllTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, pOperator->exec = doAllIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createStatewindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SStateWindowOperatorInfo* pInfo = calloc(1, sizeof(SStateWindowOperatorInfo)); pInfo->colIndex = -1; pInfo->reptScan = false; @@ -6554,10 +6529,10 @@ SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpe pOperator->exec = doStateWindowAgg; pOperator->cleanup = destroyStateWindowOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo)); pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); @@ -6579,11 +6554,11 @@ SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pOperator->exec = doSessionWindowAgg; pOperator->cleanup = destroySWindowOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); @@ -6603,11 +6578,11 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRunti pOperator->exec = doSTableIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); @@ -6627,20 +6602,20 @@ SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRu pOperator->exec = doAllSTableIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createGroupbyOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SGroupbyOperatorInfo* pInfo = calloc(1, sizeof(SGroupbyOperatorInfo)); pInfo->colIndex = -1; // group by column index pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; pQueryAttr->resultRowSize = (pQueryAttr->resultRowSize * (int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery))); @@ -6660,17 +6635,17 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pOperator->exec = hashGroupbyAggregate; pOperator->cleanup = destroyGroupbyOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult) { +SOperatorInfo* createFillOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult) { SFillOperatorInfo* pInfo = calloc(1, sizeof(SFillOperatorInfo)); pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); pInfo->multigroupResult = multigroupResult; { - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; struct SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfOutput, pQueryAttr->fillVal); STimeWindow w = TSWINDOW_INITIALIZER; @@ -6699,14 +6674,14 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn pOperator->exec = doFill; pOperator->cleanup = destroySFillOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } -SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* pMerger, bool multigroupResult) { +SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, void* pMerger, bool multigroupResult) { SSLimitOperatorInfo* pInfo = calloc(1, sizeof(SSLimitOperatorInfo)); - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; pInfo->orderColumnList = getResultGroupCheckColumns(pQueryAttr); pInfo->slimit = pQueryAttr->slimit; @@ -6747,7 +6722,7 @@ SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->cleanup = destroySlimitOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } @@ -6758,7 +6733,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) { return NULL; } - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; int32_t maxNumOfTables = (int32_t)pRuntimeEnv->resultInfo.capacity; STagScanInfo *pInfo = pOperator->info; @@ -6770,7 +6745,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) { int32_t functionId = getExprFunctionId(&pOperator->pExpr[0]); if (functionId == FUNCTION_TID_TAG) { // return the tags & table Id - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; assert(pQueryAttr->numOfOutput == 1); SExprInfo* pExprInfo = &pOperator->pExpr[0]; @@ -6874,7 +6849,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) { } if (pOperator->status == OP_EXEC_DONE) { - setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + setTaskStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); } pRes->info.rows = count; @@ -6883,7 +6858,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) { #endif } -SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createTagScanOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput) { STagScanInfo* pInfo = calloc(1, sizeof(STagScanInfo)); pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); @@ -6968,9 +6943,9 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) { SSDataBlock* pBlock = NULL; while(1) { - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); - pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); - publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_BEFORE_OPERATOR_EXEC); + pBlock = pOperator->pDownstream[0]->exec(pOperator->pDownstream[0], newgroup); + publishOperatorProfEvent(pOperator->pDownstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); if (pBlock == NULL) { doSetOperatorCompleted(pOperator); @@ -7021,7 +6996,7 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) { return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; } -SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createDistinctOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SDistinctOperatorInfo* pInfo = calloc(1, sizeof(SDistinctOperatorInfo)); pInfo->totalBytes = 0; pInfo->buf = NULL; @@ -7045,7 +7020,7 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat pOperator->pExpr = pExpr; pOperator->cleanup = destroyDistinctOperatorInfo; - appendUpstream(pOperator, upstream); + appendUpstream(pOperator, downstream); return pOperator; } @@ -7085,7 +7060,7 @@ bool validateExprColumnInfo(SQueriedTableInfo *pTableInfo, SSqlExpr *pExpr, SCol return j != INT32_MIN; } -static bool validateQueryMsg(SQueryTableMsg *pQueryMsg) { +static bool validateQueryMsg(SQueryTableReq *pQueryMsg) { if (pQueryMsg->interval.interval < 0) { //qError("qmsg:%p illegal value of interval time %" PRId64, pQueryMsg, pQueryMsg->interval.interval); return false; @@ -7151,7 +7126,7 @@ static bool validateQueryTableCols(SQueriedTableInfo* pTableInfo, SSqlExpr** pEx return true; } -static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **pTableIdList) { +static char *createTableIdList(SQueryTableReq *pQueryMsg, char *pMsg, SArray **pTableIdList) { assert(pQueryMsg->numOfTables > 0); *pTableIdList = taosArrayInit(pQueryMsg->numOfTables, sizeof(STableIdInfo)); @@ -7199,6 +7174,92 @@ static int32_t deserializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t return TSDB_CODE_SUCCESS; } +/** + * { + "Id": { + "QueryId": 20, + "TemplateId": 0, + "SubplanId": 0 + }, + "Node": { + "Name": "TableScan", + "InputSchema": [{ + "Type": 9, + "ColId": 1, + "Bytes": 8 + }, { + "Type": 4, + "ColId": 2, + "Bytes": 4 + }, { + "Type": 8, + "ColId": 3, + "Bytes": 20 + }], + "TableScan": { + "TableId": 1, + "TableType": 3, + "Flag": 0, + "Window": { + "StartKey": 0, + "EndKey": 0 + } + } + }, + "DataSink": { + "Name": "Dispatch", + "Dispatch": { + } + } +} + */ +int32_t parseTaskInfo(const char* msg, int32_t len) { + cJSON* pJson = cJSON_Parse(msg); + if (NULL == pJson) { + return TSDB_CODE_INVALID_MSG; + } + + cJSON* pSub = cJSON_GetObjectItem(pJson, "ID"); + if (NULL != pSub) { + printf("Id : %s\n", pSub->valuestring); + } + + cJSON* pNode = cJSON_GetObjectItem(pJson, "Node"); + if (pNode == NULL) { + return TSDB_CODE_INVALID_MSG; + } + + cJSON* pNodeName = cJSON_GetObjectItem(pNode, "name"); + if (pNodeName == NULL) { + return TSDB_CODE_INVALID_MSG; + } + + printf("node name is: %s\n", pNodeName->valuestring); + + cJSON* pNodeSchema = cJSON_GetObjectItem(pNode, "InputSchema"); + if (pNodeSchema == NULL) { + return TSDB_CODE_INVALID_MSG; + } + + cJSON* pOperator = cJSON_GetObjectItem(pNode, pNodeName->valuestring); + if (pOperator == NULL) { + return TSDB_CODE_INVALID_MSG; + } + + cJSON* pTableId = cJSON_GetObjectItem(pOperator, "tableId"); + if (pTableId == NULL) { + return TSDB_CODE_INVALID_MSG; + } + + cJSON* pTimeWindow = cJSON_GetObjectItem(pOperator, "window"); + if (pTimeWindow == NULL) { + return TSDB_CODE_INVALID_MSG; + } + + + +} + /** * pQueryMsg->head has been converted before this function is called. * @@ -7207,7 +7268,7 @@ static int32_t deserializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t * @param pExpr * @return */ -int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { +int32_t convertQueryMsg(SQueryTableReq *pQueryMsg, STaskParam* param) { int32_t code = TSDB_CODE_SUCCESS; // if (taosCheckVersion(pQueryMsg->version, version, 3) != 0) { @@ -7782,7 +7843,7 @@ int32_t createQueryFilter(char *data, uint16_t len, SFilterInfo** pFilters) { // todo refactor -int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutput, SExprInfo** pExprInfo, +int32_t createIndirectQueryFuncExprFromMsg(SQueryTableReq* pQueryMsg, int32_t numOfOutput, SExprInfo** pExprInfo, SSqlExpr** pExpr, SExprInfo* prevExpr, struct SUdfInfo *pUdfInfo) { // *pExprInfo = NULL; // int32_t code = TSDB_CODE_SUCCESS; @@ -7840,7 +7901,7 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t nu return TSDB_CODE_SUCCESS; } -SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code) { +SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableReq *pQueryMsg, SColIndex *pColIndex, int32_t *code) { if (pQueryMsg->numOfGroupCols == 0) { return NULL; } @@ -7924,7 +7985,7 @@ void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFil return NULL; } -int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId) { +int32_t createFilterInfo(STaskAttr* pQueryAttr, uint64_t qId) { for (int32_t i = 0; i < pQueryAttr->numOfCols; ++i) { // if (pQueryAttr->tableCols[i].flist.numOfFilters > 0 && pQueryAttr->tableCols[i].flist.filterInfo != NULL) { // pQueryAttr->numOfFilterCols++; @@ -7943,7 +8004,7 @@ int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId) { return TSDB_CODE_SUCCESS; } -static void doUpdateExprColumnIndex(SQueryAttr *pQueryAttr) { +static void doUpdateExprColumnIndex(STaskAttr *pQueryAttr) { assert(pQueryAttr->pExpr1 != NULL && pQueryAttr != NULL); for (int32_t k = 0; k < pQueryAttr->numOfOutput; ++k) { @@ -7980,7 +8041,7 @@ static void doUpdateExprColumnIndex(SQueryAttr *pQueryAttr) { } } -void setResultBufSize(SQueryAttr* pQueryAttr, SRspResultInfo* pResultInfo) { +void setResultBufSize(STaskAttr* pQueryAttr, SRspResultInfo* pResultInfo) { const int32_t DEFAULT_RESULT_MSG_SIZE = 1024 * (1024 + 512); // the minimum number of rows for projection query @@ -8008,7 +8069,7 @@ FORCE_INLINE bool checkQIdEqual(void *qHandle, uint64_t qId) { return ((SQInfo *)qHandle)->qId == qId; } -SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs, +SQInfo* createQInfoImpl(SQueryTableReq* pQueryMsg, SGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs, SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, SFilterInfo* pFilters, int32_t vgId, char* sql, uint64_t qId, struct SUdfInfo* pUdfInfo) { int16_t numOfCols = pQueryMsg->numOfCols; @@ -8026,7 +8087,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S // to make sure third party won't overwrite this structure pQInfo->signature = pQInfo; - SQueryAttr* pQueryAttr = &pQInfo->query; + STaskAttr* pQueryAttr = &pQInfo->query; pQInfo->runtimeEnv.pQueryAttr = pQueryAttr; pQueryAttr->tableGroupInfo = *pTableGroupInfo; @@ -8145,7 +8206,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S pQueryAttr->window = pQueryMsg->window; updateDataCheckOrder(pQInfo, pQueryMsg, pQueryAttr->stableQuery); - SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; + STaskRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; STimeWindow window = pQueryAttr->window; int32_t index = 0; @@ -8213,7 +8274,7 @@ _cleanup_qinfo: // filterFreeInfo(pFilters); _cleanup: - freeQInfo(pQInfo); + doDestroyTask(pQInfo); return NULL; } @@ -8231,14 +8292,14 @@ bool isValidQInfo(void *param) { return (sig == (uint64_t)pQInfo); } -int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start, +int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, STaskParam* param, char* start, int32_t prevResultLen, void* merger) { int32_t code = TSDB_CODE_SUCCESS; - SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; + STaskRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; pRuntimeEnv->qinfo = pQInfo; - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; STSBuf *pTsBuf = NULL; @@ -8271,7 +8332,7 @@ int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* (!QUERY_IS_ASC_QUERY(pQueryAttr) && (pQueryAttr->window.ekey > pQueryAttr->window.skey))) { //qDebug("QInfo:0x%"PRIx64" no result in time range %" PRId64 "-%" PRId64 ", order %d", pQInfo->qId, pQueryAttr->window.skey, // pQueryAttr->window.ekey, pQueryAttr->order.order); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); +// setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); pRuntimeEnv->tableqinfoGroupInfo.numOfTables = 0; // todo free memory return TSDB_CODE_SUCCESS; @@ -8279,7 +8340,7 @@ int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* if (pRuntimeEnv->tableqinfoGroupInfo.numOfTables == 0) { //qDebug("QInfo:0x%"PRIx64" no table qualified for tag filter, abort query", pQInfo->qId); - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); +// setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED); return TSDB_CODE_SUCCESS; } @@ -8292,7 +8353,7 @@ int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* _error: // table query ref will be decrease during error handling - freeQInfo(pQInfo); + doDestroyTask(pQInfo); return code; } @@ -8373,20 +8434,20 @@ void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols) { return NULL; } -void freeQInfo(SQInfo *pQInfo) { +void doDestroyTask(SQInfo *pQInfo) { if (!isValidQInfo(pQInfo)) { return; } //qDebug("QInfo:0x%"PRIx64" start to free QInfo", pQInfo->qId); - SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; + STaskRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; releaseQueryBuf(pRuntimeEnv->tableqinfoGroupInfo.numOfTables); doDestroyTableQueryInfo(&pRuntimeEnv->tableqinfoGroupInfo); teardownQueryRuntimeEnv(&pQInfo->runtimeEnv); - SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; + STaskAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; freeQueryAttr(pQueryAttr); // tsdbDestroyTableGroup(&pQueryAttr->tableGroupInfo); @@ -8407,8 +8468,8 @@ void freeQInfo(SQInfo *pQInfo) { int32_t doDumpQueryResult(SQInfo *pQInfo, char *data, int8_t compressed, int32_t *compLen) { // the remained number of retrieved rows, not the interpolated result - SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; + STaskRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; + STaskAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; // load data from file to msg buffer if (pQueryAttr->tsCompQuery) { @@ -8445,7 +8506,7 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data, int8_t compressed, int32_t // all data returned, set query over if (Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED)) { - setQueryStatus(pRuntimeEnv, QUERY_OVER); +// setTaskStatus(pOperator->pTaskInfo, QUERY_OVER); } } else { doCopyQueryResultToMsg(pQInfo, (int32_t)pRuntimeEnv->outputBuf->info.rows, data, compressed, compLen); @@ -8456,7 +8517,7 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data, int8_t compressed, int32_t if (pQueryAttr->limit.limit > 0 && pQueryAttr->limit.limit == pRuntimeEnv->resultInfo.total) { //qDebug("QInfo:0x%"PRIx64" results limitation reached, limitation:%"PRId64, pQInfo->qId, pQueryAttr->limit.limit); - setQueryStatus(pRuntimeEnv, QUERY_OVER); +// setTaskStatus(pOperator->pTaskInfo, QUERY_OVER); } return TSDB_CODE_SUCCESS; @@ -8535,8 +8596,8 @@ int32_t checkForQueryBuf(size_t numOfTables) { } bool checkNeedToCompressQueryCol(SQInfo *pQInfo) { - SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STaskRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; + STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SSDataBlock* pRes = pRuntimeEnv->outputBuf; @@ -8569,7 +8630,7 @@ void releaseQueryBuf(size_t numOfTables) { atomic_add_fetch_64(&tsQueryBufferSizeBytes, t); } -void freeQueryAttr(SQueryAttr* pQueryAttr) { +void freeQueryAttr(STaskAttr* pQueryAttr) { if (pQueryAttr != NULL) { if (pQueryAttr->fillVal != NULL) { tfree(pQueryAttr->fillVal); diff --git a/source/libs/parser/inc/astGenerator.h b/source/libs/parser/inc/astGenerator.h index 22806969af..7f357a2bbd 100644 --- a/source/libs/parser/inc/astGenerator.h +++ b/source/libs/parser/inc/astGenerator.h @@ -123,7 +123,7 @@ typedef struct SCreatedTableInfo { SToken name; // table name token SToken stbName; // super table name token , for using clause SArray *pTagNames; // create by using super table, tag name - SArray *pTagVals; // create by using super table, tag value + SArray *pTagVals; // create by using super table, tag value. SArray char *fullname; // table full name int8_t igExist; // ignore if exists } SCreatedTableInfo; diff --git a/source/libs/parser/inc/astToMsg.h b/source/libs/parser/inc/astToMsg.h index ba33767a05..83683c2bfc 100644 --- a/source/libs/parser/inc/astToMsg.h +++ b/source/libs/parser/inc/astToMsg.h @@ -5,14 +5,14 @@ #include "tmsg.h" -SCreateUserMsg* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); -SCreateAcctMsg* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); -SDropUserMsg* buildDropUserMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); -SShowMsg* buildShowMsg(SShowInfo* pShowInfo, SParseBasicCtx* pParseCtx, char* msgBuf, int32_t msgLen); -SCreateDbMsg* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, SParseBasicCtx *pCtx, SMsgBuf* pMsgBuf); -SCreateStbMsg* buildCreateTableMsg(SCreateTableSql* pCreateTableSql, int32_t* len, SParseBasicCtx* pParseCtx, SMsgBuf* pMsgBuf); -SDropStbMsg* buildDropStableMsg(SSqlInfo* pInfo, int32_t* len, SParseBasicCtx* pParseCtx, SMsgBuf* pMsgBuf); -SCreateDnodeMsg *buildCreateDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMsgBuf); -SDropDnodeMsg *buildDropDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMsgBuf); +SCreateUserReq* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); +SCreateAcctReq* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); +SDropUserReq* buildDropUserMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); +SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseBasicCtx* pParseCtx, char* msgBuf, int32_t msgLen); +SCreateDbReq* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, SParseBasicCtx *pCtx, SMsgBuf* pMsgBuf); +SMCreateStbReq* buildCreateStbMsg(SCreateTableSql* pCreateTableSql, int32_t* len, SParseBasicCtx* pParseCtx, SMsgBuf* pMsgBuf); +SMDropStbReq* buildDropStableMsg(SSqlInfo* pInfo, int32_t* len, SParseBasicCtx* pParseCtx, SMsgBuf* pMsgBuf); +SCreateDnodeReq *buildCreateDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMsgBuf); +SDropDnodeReq *buildDropDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMsgBuf); #endif // TDENGINE_ASTTOMSG_H diff --git a/source/libs/parser/inc/parserInt.h b/source/libs/parser/inc/parserInt.h index d1629a2a3e..10ec335fc8 100644 --- a/source/libs/parser/inc/parserInt.h +++ b/source/libs/parser/inc/parserInt.h @@ -38,28 +38,20 @@ typedef struct SMsgBuf { char *buf; } SMsgBuf; -// create table operation type -enum TSQL_CREATE_TABLE_TYPE { - TSQL_CREATE_TABLE = 0x1, - TSQL_CREATE_STABLE = 0x2, - TSQL_CREATE_CTABLE = 0x3, - TSQL_CREATE_STREAM = 0x4, -}; - void clearTableMetaInfo(STableMetaInfo* pTableMetaInfo); void clearAllTableMetaInfo(SQueryStmtInfo* pQueryInfo, bool removeMeta, uint64_t id); /** * Validate the sql info, according to the corresponding metadata info from catalog. - * @param pCatalog - * @param pSqlInfo - * @param pQueryInfo a bounded AST with essential meta data from local buffer or mgmt node - * @param id - * @param msg + * @param pCtx + * @param pInfo + * @param pQueryInfo + * @param msgBuf + * @param msgBufLen * @return */ -int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQueryStmtInfo* pQueryInfo, int64_t id, char* msg, int32_t msgLen); +int32_t qParserValidateSqlNode(SParseBasicCtx *pCtx, SSqlInfo* pInfo, SQueryStmtInfo* pQueryInfo, char* msgBuf, int32_t msgBufLen); /** * validate the ddl ast, and convert the ast to the corresponding message format @@ -70,6 +62,14 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ */ SDclStmtInfo* qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, char* msgBuf, int32_t msgBufLen); +/** + * + * @param pInfo + * @param pCtx + * @param msgBuf + * @param msgBufLen + * @return + */ SVnodeModifOpStmtInfo* qParserValidateCreateTbSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, char* msgBuf, int32_t msgBufLen); /** @@ -98,7 +98,7 @@ int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf); * @param msgBufLen * @return */ -int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SCatalogReq* pMetaInfo, char* msg, int32_t msgBufLen); +int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SCatalogReq* pMetaInfo, SParseBasicCtx *pCtx, char* msg, int32_t msgBufLen); /** * Destroy the meta data request structure. diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index c6e1c004e3..6e91ad997c 100644 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -370,7 +370,7 @@ create_table_list(A) ::= create_from_stable(Z). { pCreateTable->childTableInfo = taosArrayInit(4, sizeof(SCreatedTableInfo)); taosArrayPush(pCreateTable->childTableInfo, &Z); - pCreateTable->type = TSQL_CREATE_CTABLE; + pCreateTable->type = TSDB_SQL_CREATE_TABLE; A = pCreateTable; } @@ -381,7 +381,7 @@ create_table_list(A) ::= create_table_list(X) create_from_stable(Z). { %type create_table_args{SCreateTableSql*} create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) LP columnlist(X) RP. { - A = tSetCreateTableInfo(X, NULL, NULL, TSQL_CREATE_TABLE); + A = tSetCreateTableInfo(X, NULL, NULL, TSDB_SQL_CREATE_TABLE); setSqlInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE); V.n += Z.n; @@ -391,7 +391,7 @@ create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) LP columnlist(X) RP. { // create super table %type create_stable_args{SCreateTableSql*} create_stable_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) LP columnlist(X) RP TAGS LP columnlist(Y) RP. { - A = tSetCreateTableInfo(X, Y, NULL, TSQL_CREATE_STABLE); + A = tSetCreateTableInfo(X, Y, NULL, TSDB_SQL_CREATE_STABLE); setSqlInfo(pInfo, A, NULL, TSDB_SQL_CREATE_STABLE); V.n += Z.n; @@ -421,11 +421,11 @@ tagNamelist(A) ::= ids(X). {A = taosArrayInit(4, sizeof(STo // create stream // create table table_name as select count(*) from super_table_name interval(time) create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) AS select(S). { - A = tSetCreateTableInfo(NULL, NULL, S, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE); - - V.n += Z.n; - setCreatedTableName(pInfo, &V, &U); +// A = tSetCreateTableInfo(NULL, NULL, S, TSQL_CREATE_STREAM); +// setSqlInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE); +// +// V.n += Z.n; +// setCreatedTableName(pInfo, &V, &U); } %type column{SField} diff --git a/source/libs/parser/src/astGenerator.c b/source/libs/parser/src/astGenerator.c index 3f45012405..34ed8bd355 100644 --- a/source/libs/parser/src/astGenerator.c +++ b/source/libs/parser/src/astGenerator.c @@ -579,25 +579,21 @@ SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SSqlNode *pSe SCreateTableSql *pCreate = calloc(1, sizeof(SCreateTableSql)); switch (type) { - case TSQL_CREATE_TABLE: { + case TSDB_SQL_CREATE_TABLE: { pCreate->colInfo.pColumns = pCols; assert(pTags == NULL); break; } - case TSQL_CREATE_STABLE: { + case TSDB_SQL_CREATE_STABLE: { pCreate->colInfo.pColumns = pCols; pCreate->colInfo.pTagColumns = pTags; assert(pTags != NULL && pCols != NULL); break; } - case TSQL_CREATE_STREAM: { - pCreate->pSelect = pSelect; - break; - } - - case TSQL_CREATE_CTABLE: { - assert(0); - } +// case TSQL_CREATE_STREAM: { +// pCreate->pSelect = pSelect; +// break; +// } default: assert(false); @@ -690,7 +686,7 @@ void destroySqlNode(SSqlNode *pSqlNode) { void freeCreateTableInfo(void* p) { SCreatedTableInfo* pInfo = (SCreatedTableInfo*) p; taosArrayDestroy(pInfo->pTagNames); - taosArrayDestroyEx(pInfo->pTagVals, freeItem); + taosArrayDestroy(pInfo->pTagVals); tfree(pInfo->fullname); } @@ -785,7 +781,7 @@ void destroySqlInfo(SSqlInfo *pInfo) { taosArrayDestroy(pInfo->funcs); if (pInfo->type == TSDB_SQL_SELECT) { destroyAllSqlNode(&pInfo->sub); - } else if (pInfo->type == TSDB_SQL_CREATE_STABLE) { + } else if (pInfo->type == TSDB_SQL_CREATE_STABLE || pInfo->type == TSDB_SQL_CREATE_TABLE) { pInfo->pCreateTableInfo = destroyCreateTableSql(pInfo->pCreateTableInfo); } else if (pInfo->type == TSDB_SQL_ALTER_TABLE) { taosArrayDestroyEx(pInfo->pAlterInfo->varList, freeItem); diff --git a/source/libs/parser/src/astToMsg.c b/source/libs/parser/src/astToMsg.c index 792c0db266..5f45ce824e 100644 --- a/source/libs/parser/src/astToMsg.c +++ b/source/libs/parser/src/astToMsg.c @@ -2,8 +2,8 @@ #include "astGenerator.h" #include "parserUtil.h" -SCreateUserMsg* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen) { - SCreateUserMsg* pMsg = (SCreateUserMsg*)calloc(1, sizeof(SCreateUserMsg)); +SCreateUserReq* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen) { + SCreateUserReq* pMsg = (SCreateUserReq*)calloc(1, sizeof(SCreateUserReq)); if (pMsg == NULL) { // tscError("0x%" PRIx64 " failed to malloc for query msg", id); terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -25,8 +25,8 @@ SCreateUserMsg* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, in return pMsg; } -SCreateAcctMsg* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen) { - SCreateAcctMsg *pCreateMsg = (SCreateAcctMsg *) calloc(1, sizeof(SCreateAcctMsg)); +SCreateAcctReq* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen) { + SCreateAcctReq *pCreateMsg = (SCreateAcctReq *) calloc(1, sizeof(SCreateAcctReq)); if (pCreateMsg == NULL) { qError("0x%" PRIx64 " failed to malloc for query msg", id); terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; @@ -64,29 +64,29 @@ SCreateAcctMsg* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, in } } - *outputLen = sizeof(SCreateAcctMsg); + *outputLen = sizeof(SCreateAcctReq); return pCreateMsg; } -SDropUserMsg* buildDropUserMsg(SSqlInfo* pInfo, int32_t *msgLen, int64_t id, char* msgBuf, int32_t msgBufLen) { +SDropUserReq* buildDropUserMsg(SSqlInfo* pInfo, int32_t *msgLen, int64_t id, char* msgBuf, int32_t msgBufLen) { SToken* pName = taosArrayGet(pInfo->pMiscInfo->a, 0); if (pName->n >= TSDB_USER_LEN) { return NULL; } - SDropUserMsg* pMsg = calloc(1, sizeof(SDropUserMsg)); + SDropUserReq* pMsg = calloc(1, sizeof(SDropUserReq)); if (pMsg == NULL) { terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; return NULL; } strncpy(pMsg->user, pName->z, pName->n); - *msgLen = sizeof(SDropUserMsg); + *msgLen = sizeof(SDropUserReq); return pMsg; } -SShowMsg* buildShowMsg(SShowInfo* pShowInfo, SParseBasicCtx *pCtx, char* msgBuf, int32_t msgLen) { - SShowMsg* pShowMsg = calloc(1, sizeof(SShowMsg)); +SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseBasicCtx *pCtx, char* msgBuf, int32_t msgLen) { + SShowReq* pShowMsg = calloc(1, sizeof(SShowReq)); pShowMsg->type = pShowInfo->showType; if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) { @@ -112,7 +112,7 @@ SShowMsg* buildShowMsg(SShowInfo* pShowInfo, SParseBasicCtx *pCtx, char* msgBuf, return pShowMsg; } -static int32_t setKeepOption(SCreateDbMsg* pMsg, const SCreateDbInfo* pCreateDb, SMsgBuf* pMsgBuf) { +static int32_t setKeepOption(SCreateDbReq* pMsg, const SCreateDbInfo* pCreateDb, SMsgBuf* pMsgBuf) { const char* msg1 = "invalid number of keep options"; const char* msg2 = "invalid keep value"; const char* msg3 = "invalid keep value, should be keep0 <= keep1 <= keep2"; @@ -151,7 +151,7 @@ static int32_t setKeepOption(SCreateDbMsg* pMsg, const SCreateDbInfo* pCreateDb, return TSDB_CODE_SUCCESS; } -static int32_t setTimePrecision(SCreateDbMsg* pMsg, const SCreateDbInfo* pCreateDbInfo, SMsgBuf* pMsgBuf) { +static int32_t setTimePrecision(SCreateDbReq* pMsg, const SCreateDbInfo* pCreateDbInfo, SMsgBuf* pMsgBuf) { const char* msg = "invalid time precision"; pMsg->precision = TSDB_TIME_PRECISION_MILLI; // millisecond by default @@ -178,7 +178,7 @@ static int32_t setTimePrecision(SCreateDbMsg* pMsg, const SCreateDbInfo* pCreate return TSDB_CODE_SUCCESS; } -static void doSetDbOptions(SCreateDbMsg* pMsg, const SCreateDbInfo* pCreateDb) { +static void doSetDbOptions(SCreateDbReq* pMsg, const SCreateDbInfo* pCreateDb) { pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize); pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks); pMsg->daysPerFile = htonl(pCreateDb->daysPerFile); @@ -196,7 +196,7 @@ static void doSetDbOptions(SCreateDbMsg* pMsg, const SCreateDbInfo* pCreateDb) { pMsg->numOfVgroups = htonl(pCreateDb->numOfVgroups); } -int32_t setDbOptions(SCreateDbMsg* pCreateDbMsg, const SCreateDbInfo* pCreateDbSql, SMsgBuf* pMsgBuf) { +int32_t setDbOptions(SCreateDbReq* pCreateDbMsg, const SCreateDbInfo* pCreateDbSql, SMsgBuf* pMsgBuf) { doSetDbOptions(pCreateDbMsg, pCreateDbSql); if (setKeepOption(pCreateDbMsg, pCreateDbSql, pMsgBuf) != TSDB_CODE_SUCCESS) { @@ -210,8 +210,8 @@ int32_t setDbOptions(SCreateDbMsg* pCreateDbMsg, const SCreateDbInfo* pCreateDbS return TSDB_CODE_SUCCESS; } -SCreateDbMsg* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, SParseBasicCtx *pCtx, SMsgBuf* pMsgBuf) { - SCreateDbMsg* pCreateMsg = calloc(1, sizeof(SCreateDbMsg)); +SCreateDbReq* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, SParseBasicCtx *pCtx, SMsgBuf* pMsgBuf) { + SCreateDbReq* pCreateMsg = calloc(1, sizeof(SCreateDbReq)); if (setDbOptions(pCreateMsg, pCreateDbInfo, pMsgBuf) != TSDB_CODE_SUCCESS) { tfree(pCreateMsg); terrno = TSDB_CODE_TSC_INVALID_OPERATION; @@ -230,7 +230,7 @@ SCreateDbMsg* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, SParseBasicCtx *pCt return pCreateMsg; } -SCreateStbMsg* buildCreateTableMsg(SCreateTableSql* pCreateTableSql, int32_t* len, SParseBasicCtx* pParseCtx, SMsgBuf* pMsgBuf) { +SMCreateStbReq* buildCreateStbMsg(SCreateTableSql* pCreateTableSql, int32_t* len, SParseBasicCtx* pParseCtx, SMsgBuf* pMsgBuf) { SSchema* pSchema; int32_t numOfTags = 0; @@ -239,16 +239,16 @@ SCreateStbMsg* buildCreateTableMsg(SCreateTableSql* pCreateTableSql, int32_t* le numOfTags = (int32_t) taosArrayGetSize(pCreateTableSql->colInfo.pTagColumns); } - SCreateStbMsg* pCreateTableMsg = (SCreateStbMsg*)calloc(1, sizeof(SCreateStbMsg) + (numOfCols + numOfTags) * sizeof(SSchema)); + SMCreateStbReq* pCreateStbMsg = (SMCreateStbReq*)calloc(1, sizeof(SMCreateStbReq) + (numOfCols + numOfTags) * sizeof(SSchema)); char* pMsg = NULL; +#if 0 int32_t tableType = pCreateTableSql->type; if (tableType != TSQL_CREATE_TABLE && tableType != TSQL_CREATE_STABLE) { // create by using super table, tags value -#if 0 SArray* list = pInfo->pCreateTableInfo->childTableInfo; int32_t numOfTables = (int32_t)taosArrayGetSize(list); - pCreateTableMsg->numOfTables = htonl(numOfTables); + pCreateStbMsg->numOfTables = htonl(numOfTables); pMsg = (char*)pCreateMsg; for (int32_t i = 0; i < numOfTables; ++i) { @@ -268,25 +268,27 @@ SCreateStbMsg* buildCreateTableMsg(SCreateTableSql* pCreateTableSql, int32_t* le int32_t len = (int32_t)(pMsg - (char*)pCreate); pCreate->len = htonl(len); } + + } else { #endif - } else { // create (super) table + // create (super) table SName n = {0}; int32_t code = createSName(&n, &pCreateTableSql->name, pParseCtx, pMsgBuf); if (code != 0) { return NULL; } - code = tNameExtractFullName(&n, pCreateTableMsg->name); + code = tNameExtractFullName(&n, pCreateStbMsg->name); if (code != 0) { buildInvalidOperationMsg(pMsgBuf, "invalid table name or database not specified"); return NULL; } - pCreateTableMsg->igExists = pCreateTableSql->existCheck ? 1 : 0; - pCreateTableMsg->numOfColumns = htonl(numOfCols); - pCreateTableMsg->numOfTags = htonl(numOfTags); + pCreateStbMsg->igExists = pCreateTableSql->existCheck ? 1 : 0; + pCreateStbMsg->numOfColumns = htonl(numOfCols); + pCreateStbMsg->numOfTags = htonl(numOfTags); - pSchema = (SSchema*) pCreateTableMsg->pSchema; + pSchema = (SSchema*)pCreateStbMsg->pSchema; for (int i = 0; i < numOfCols; ++i) { SField* pField = taosArrayGet(pCreateTableSql->colInfo.pColumns, i); pSchema->type = pField->type; @@ -306,15 +308,14 @@ SCreateStbMsg* buildCreateTableMsg(SCreateTableSql* pCreateTableSql, int32_t* le } pMsg = (char*)pSchema; - } - int32_t msgLen = (int32_t)(pMsg - (char*)pCreateTableMsg); + int32_t msgLen = (int32_t)(pMsg - (char*)pCreateStbMsg); *len = msgLen; - return pCreateTableMsg; + return pCreateStbMsg; } -SDropStbMsg* buildDropStableMsg(SSqlInfo* pInfo, int32_t* len, SParseBasicCtx* pParseCtx, SMsgBuf* pMsgBuf) { +SMDropStbReq* buildDropStableMsg(SSqlInfo* pInfo, int32_t* len, SParseBasicCtx* pParseCtx, SMsgBuf* pMsgBuf) { SToken* tableName = taosArrayGet(pInfo->pMiscInfo->a, 0); SName name = {0}; @@ -324,17 +325,17 @@ SDropStbMsg* buildDropStableMsg(SSqlInfo* pInfo, int32_t* len, SParseBasicCtx* p return NULL; } - SDropStbMsg *pDropTableMsg = (SDropStbMsg*) calloc(1, sizeof(SDropStbMsg)); + SMDropStbReq *pDropTableMsg = (SMDropStbReq*) calloc(1, sizeof(SMDropStbReq)); code = tNameExtractFullName(&name, pDropTableMsg->name); assert(code == TSDB_CODE_SUCCESS && name.type == TSDB_TABLE_NAME_T); pDropTableMsg->igNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0; - *len = sizeof(SDropTableMsg); + *len = sizeof(SMDropStbReq); return pDropTableMsg; } -SCreateDnodeMsg *buildCreateDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMsgBuf) { +SCreateDnodeReq *buildCreateDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMsgBuf) { const char* msg1 = "invalid host name (name too long, maximum length 128)"; const char* msg2 = "dnode name can not be string"; const char* msg3 = "port should be an integer that is less than 65535 and greater than 0"; @@ -366,7 +367,7 @@ SCreateDnodeMsg *buildCreateDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMs return NULL; } - SCreateDnodeMsg *pCreate = (SCreateDnodeMsg *) calloc(1, sizeof(SCreateDnodeMsg)); + SCreateDnodeReq *pCreate = (SCreateDnodeReq *) calloc(1, sizeof(SCreateDnodeReq)); if (pCreate == NULL) { buildInvalidOperationMsg(pMsgBuf, msg4); return NULL; @@ -375,18 +376,18 @@ SCreateDnodeMsg *buildCreateDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMs strncpy(pCreate->fqdn, id->z, id->n); pCreate->port = htonl(val); - *len = sizeof(SCreateDnodeMsg); + *len = sizeof(SCreateDnodeReq); return pCreate; } -SDropDnodeMsg *buildDropDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMsgBuf) { +SDropDnodeReq *buildDropDnodeMsg(SSqlInfo* pInfo, int32_t* len, SMsgBuf* pMsgBuf) { SToken* pzName = taosArrayGet(pInfo->pMiscInfo->a, 0); char* end = NULL; - SDropDnodeMsg * pDrop = (SDropDnodeMsg *)calloc(1, sizeof(SDropDnodeMsg)); + SDropDnodeReq * pDrop = (SDropDnodeReq *)calloc(1, sizeof(SDropDnodeReq)); pDrop->dnodeId = strtoll(pzName->z, &end, 10); pDrop->dnodeId = htonl(pDrop->dnodeId); - *len = sizeof(SDropDnodeMsg); + *len = sizeof(SDropDnodeReq); if (end - pzName->z != pzName->n) { buildInvalidOperationMsg(pMsgBuf, "invalid dnode id"); diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c index b2466fd2dc..faa8c526a0 100644 --- a/source/libs/parser/src/astValidate.c +++ b/source/libs/parser/src/astValidate.c @@ -213,7 +213,7 @@ SQueryStmtInfo *createQueryInfo() { pQueryInfo->slimit.limit = -1; pQueryInfo->slimit.offset = 0; - pQueryInfo->pUpstream = taosArrayInit(4, POINTER_BYTES); + pQueryInfo->pDownstream = taosArrayInit(4, POINTER_BYTES); pQueryInfo->window = TSWINDOW_INITIALIZER; pQueryInfo->exprList = calloc(10, POINTER_BYTES); @@ -247,8 +247,8 @@ static void destroyQueryInfoImpl(SQueryStmtInfo* pQueryInfo) { tfree(pQueryInfo->fillVal); tfree(pQueryInfo->buf); - taosArrayDestroy(pQueryInfo->pUpstream); - pQueryInfo->pUpstream = NULL; + taosArrayDestroy(pQueryInfo->pDownstream); + pQueryInfo->pDownstream = NULL; pQueryInfo->bufLen = 0; } @@ -256,9 +256,9 @@ void destroyQueryInfo(SQueryStmtInfo* pQueryInfo) { while (pQueryInfo != NULL) { SQueryStmtInfo* p = pQueryInfo->sibling; - size_t numOfUpstream = taosArrayGetSize(pQueryInfo->pUpstream); + size_t numOfUpstream = taosArrayGetSize(pQueryInfo->pDownstream); for (int32_t i = 0; i < numOfUpstream; ++i) { - SQueryStmtInfo* pUpQueryInfo = taosArrayGetP(pQueryInfo->pUpstream, i); + SQueryStmtInfo* pUpQueryInfo = taosArrayGetP(pQueryInfo->pDownstream, i); destroyQueryInfoImpl(pUpQueryInfo); clearAllTableMetaInfo(pUpQueryInfo, false, 0); tfree(pUpQueryInfo); @@ -288,7 +288,6 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI } pSub->pUdfInfo = pUdfInfo; - pSub->pDownstream = pQueryInfo; int32_t code = validateSqlNode(p, pSub, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { return code; @@ -311,7 +310,7 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI tstrncpy(pTableMetaInfo1->aliasName, subInfo->aliasName.z, subInfo->aliasName.n + 1); } - taosArrayPush(pQueryInfo->pUpstream, &pSub); + taosArrayPush(pQueryInfo->pDownstream, &pSub); // NOTE: order mix up in subquery not support yet. pQueryInfo->order = pSub->order; @@ -600,7 +599,7 @@ int32_t checkForUnsupportedQuery(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) { return buildInvalidOperationMsg(pMsgBuf, msg1); } - if (f == FUNCTION_BLKINFO && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { + if (f == FUNCTION_BLKINFO && taosArrayGetSize(pQueryInfo->pDownstream) > 0) { return buildInvalidOperationMsg(pMsgBuf, msg1); } @@ -1584,7 +1583,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* } pushDownAggFuncExprInfo(pQueryInfo); -// addColumnNodeFromLowerLevel(pQueryInfo); for(int32_t i = 0; i < 1; ++i) { SArray* functionList = extractFunctionList(pQueryInfo->exprList[i]); @@ -3630,12 +3628,39 @@ int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf) return TSDB_CODE_SUCCESS; } -int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQueryStmtInfo* pQueryInfo, int64_t id, char* msgBuf, int32_t msgBufLen) { - assert(pCatalog != NULL && pInfo != NULL); +int32_t setTableVgroupList(SParseBasicCtx *pCtx, SName* name, SVgroupsInfo **pVgList) { + SArray* vgroupList = NULL; + int32_t code = catalogGetTableDistVgroup(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, name, &vgroupList); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + int32_t vgroupNum = taosArrayGetSize(vgroupList); + + SVgroupsInfo *vgList = calloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupMsg) * vgroupNum); + + vgList->numOfVgroups = vgroupNum; + + for (int32_t i = 0; i < vgroupNum; ++i) { + SVgroupInfo *vg = taosArrayGet(vgroupList, i); + vgList->vgroups[i].vgId = vg->vgId; + vgList->vgroups[i].numOfEps = vg->numOfEps; + memcpy(vgList->vgroups[i].epAddr, vg->epAddr, sizeof(vgList->vgroups[i].epAddr)); + } + + *pVgList = vgList; + + taosArrayDestroy(vgroupList); + + return TSDB_CODE_SUCCESS; +} + +int32_t qParserValidateSqlNode(SParseBasicCtx *pCtx, SSqlInfo* pInfo, SQueryStmtInfo* pQueryInfo, char* msgBuf, int32_t msgBufLen) { + assert(pCtx != NULL && pInfo != NULL); int32_t code = 0; - SMsgBuf m = {.buf = msgBuf, .len = msgBufLen}; - SMsgBuf *pMsgBuf = &m; + SMsgBuf m = {.buf = msgBuf, .len = msgBufLen}; + SMsgBuf* pMsgBuf = &m; switch (pInfo->type) { #if 0 @@ -3682,22 +3707,6 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer break; } - case TSDB_SQL_USE_DB: { - const char* msg = "invalid db name"; - SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); - - if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { - return buildInvalidOperationMsg(pMsgBuf, msg); - } - - int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken); - if (ret != TSDB_CODE_SUCCESS) { - return buildInvalidOperationMsg(pMsgBuf, msg); - } - - break; - } - case TSDB_SQL_RESET_CACHE: { return TSDB_CODE_SUCCESS; } @@ -3712,55 +3721,6 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer break; } - case TSDB_SQL_CREATE_DNODE: { - const char* msg = "invalid host name (ip address)"; - - if (taosArrayGetSize(pInfo->pMiscInfo->a) > 1) { - return buildInvalidOperationMsg(pMsgBuf, msg); - } - - SToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0); - if (id->type == TK_STRING) { - id->n = strdequote(id->z); - } - break; - } - - case TSDB_SQL_CREATE_ACCT: - case TSDB_SQL_ALTER_ACCT: { - const char* msg1 = "invalid state option, available options[no, r, w, all]"; - const char* msg2 = "invalid user/account name"; - const char* msg3 = "name too long"; - - SToken* pName = &pInfo->pMiscInfo->user.user; - SToken* pPwd = &pInfo->pMiscInfo->user.passwd; - - if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_OPERATION; - } - - if (pName->n >= TSDB_USER_LEN) { - return buildInvalidOperationMsg(pMsgBuf, msg3); - } - - if (tscValidateName(pName) != TSDB_CODE_SUCCESS) { - return buildInvalidOperationMsg(pMsgBuf, msg2); - } - - SCreateAcctInfo* pAcctOpt = &pInfo->pMiscInfo->acctOpt; - if (pAcctOpt->stat.n > 0) { - if (pAcctOpt->stat.z[0] == 'r' && pAcctOpt->stat.n == 1) { - } else if (pAcctOpt->stat.z[0] == 'w' && pAcctOpt->stat.n == 1) { - } else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) { - } else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) { - } else { - return buildInvalidOperationMsg(pMsgBuf, msg1); - } - } - - break; - } - case TSDB_SQL_DESCRIBE_TABLE: { const char* msg1 = "invalid table name"; @@ -3819,7 +3779,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer char* pMsg = pCmd->payload; - SCfgDnodeMsg* pCfg = (SCfgDnodeMsg*)pMsg; + SMCfgDnodeReq* pCfg = (SMCfgDnodeReq*)pMsg; SToken* t0 = taosArrayGet(pMiscInfo->a, 0); SToken* t1 = taosArrayGet(pMiscInfo->a, 1); @@ -3865,29 +3825,6 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer return TSDB_CODE_SUCCESS; } - case TSDB_SQL_CREATE_TABLE: { - SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; - - if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) { - if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) { - return code; - } - - } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) { - assert(pCmd->numOfCols == 0); - if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) { - return code; - } - - } else if (pCreateTable->type == TSQL_CREATE_STREAM) { - if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) { - return code; - } - } - - break; - } - case TSDB_SQL_SELECT: { const char * msg1 = "no nested query supported in union clause"; code = loadAllTableMeta(pSql, pInfo); @@ -3981,26 +3918,47 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer } break; } - #endif default: return buildInvalidOperationMsg(pMsgBuf, "not support sql expression"); } +#endif + } - SCatalogReq req = {0}; - SMetaData data = {0}; + SCatalogReq req = {0}; + SMetaData data = {0}; // TODO: check if the qnode info has been cached already req.qNodeRequired = true; - code = qParserExtractRequestedMetaInfo(pInfo, &req, msgBuf, msgBufLen); + code = qParserExtractRequestedMetaInfo(pInfo, &req, pCtx, msgBuf, msgBufLen); if (code != TSDB_CODE_SUCCESS) { return code; } // load the meta data from catalog - code = catalogGetAllMeta(pCatalog, NULL, NULL, &req, &data); +// code = catalogGetAllMeta(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, &req, &data); + STableMeta* pmt = NULL; + + SName* name = taosArrayGet(req.pTableName, 0); + code = catalogGetTableMeta(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, name, &pmt); if (code != TSDB_CODE_SUCCESS) { return code; } + + data.pTableMeta = taosArrayInit(1, POINTER_BYTES); + taosArrayPush(data.pTableMeta, &pmt); + + pQueryInfo->pTableMetaInfo = calloc(1, POINTER_BYTES); + pQueryInfo->pTableMetaInfo[0] = calloc(1, sizeof(STableMetaInfo)); + pQueryInfo->pTableMetaInfo[0]->pTableMeta = pmt; + pQueryInfo->pTableMetaInfo[0]->name = *name; + pQueryInfo->numOfTables = 1; + pQueryInfo->pTableMetaInfo[0]->tagColList = taosArrayInit(4, POINTER_BYTES); + + code = setTableVgroupList(pCtx, name, &pQueryInfo->pTableMetaInfo[0]->vgroupList); + if (code != TSDB_CODE_SUCCESS) { + taosArrayDestroy(data.pTableMeta); + return code; + } // evaluate the sqlnode STableMeta* pTableMeta = (STableMeta*) taosArrayGetP(data.pTableMeta, 0); diff --git a/source/libs/parser/src/dCDAstProcess.c b/source/libs/parser/src/dCDAstProcess.c index 6007fc300c..6676e1ebf6 100644 --- a/source/libs/parser/src/dCDAstProcess.c +++ b/source/libs/parser/src/dCDAstProcess.c @@ -1,10 +1,11 @@ -#include -#include -#include "astToMsg.h" +#include "tmsg.h" +#include "tglobal.h" #include "parserInt.h" +#include "ttime.h" +#include "astToMsg.h" +#include "astGenerator.h" #include "parserUtil.h" #include "queryInfoUtil.h" -#include "tglobal.h" /* is contained in pFieldList or not */ static bool has(SArray* pFieldList, int32_t startIndex, const char* name) { @@ -41,7 +42,7 @@ static int32_t setShowInfo(SShowInfo* pShowInfo, SParseBasicCtx* pCtx, void** ou char dbFname[TSDB_DB_FNAME_LEN] = {0}; tNameGetFullDbName(&name, dbFname); - catalogGetDBVgroup(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, dbFname, 0, &array); + catalogGetDBVgroup(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, dbFname, false, &array); SVgroupInfo* info = taosArrayGet(array, 0); pShowReq->head.vgId = htonl(info->vgId); @@ -109,14 +110,14 @@ static int32_t setShowInfo(SShowInfo* pShowInfo, SParseBasicCtx* pCtx, void** ou *pEpSet = pCtx->mgmtEpSet; *output = buildShowMsg(pShowInfo, pCtx, pMsgBuf->buf, pMsgBuf->len); - *outputLen = sizeof(SShowMsg) /* + htons(pShowMsg->payloadLen)*/; + *outputLen = sizeof(SShowReq) /* + htons(pShowMsg->payloadLen)*/; } return TSDB_CODE_SUCCESS; } // can only perform the parameters based on the macro definitation -static int32_t doCheckDbOptions(SCreateDbMsg* pCreate, SMsgBuf* pMsgBuf) { +static int32_t doCheckDbOptions(SCreateDbReq* pCreate, SMsgBuf* pMsgBuf) { char msg[512] = {0}; if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) { @@ -193,6 +194,18 @@ static int32_t doCheckDbOptions(SCreateDbMsg* pCreate, SMsgBuf* pMsgBuf) { TSDB_MIN_VNODES_PER_DB, TSDB_MAX_VNODES_PER_DB); } + val = htonl(pCreate->maxRows); + if (val < TSDB_MIN_MAX_ROW_FBLOCK || val > TSDB_MAX_MAX_ROW_FBLOCK) { + snprintf(msg, tListLen(msg), "invalid number of max rows in file block for DB:%d valid range: [%d, %d]", val, + TSDB_MIN_MAX_ROW_FBLOCK, TSDB_MAX_MAX_ROW_FBLOCK); + } + + val = htonl(pCreate->minRows); + if (val < TSDB_MIN_MIN_ROW_FBLOCK || val > TSDB_MAX_MIN_ROW_FBLOCK) { + snprintf(msg, tListLen(msg), "invalid number of min rows in file block for DB:%d valid range: [%d, %d]", val, + TSDB_MIN_MIN_ROW_FBLOCK, TSDB_MAX_MIN_ROW_FBLOCK); + } + return TSDB_CODE_SUCCESS; } @@ -248,16 +261,10 @@ static int32_t validateTableColumns(SArray* pFieldList, int32_t maxRowLength, in } static int32_t validateTableColumnInfo(SArray* pFieldList, SMsgBuf* pMsgBuf) { - assert(pFieldList != NULL); + assert(pFieldList != NULL && pMsgBuf != NULL); const char* msg1 = "first column must be timestamp"; - const char* msg2 = "row length exceeds max length"; - const char* msg3 = "duplicated column names"; - const char* msg4 = "invalid data type"; - const char* msg5 = "invalid binary/nchar column length"; - const char* msg6 = "invalid column name"; - const char* msg7 = "too many columns"; - const char* msg8 = "illegal number of columns"; + const char* msg2 = "illegal number of columns"; // first column must be timestamp SField* pField = taosArrayGet(pFieldList, 0); @@ -268,7 +275,7 @@ static int32_t validateTableColumnInfo(SArray* pFieldList, SMsgBuf* pMsgBuf) { // number of fields no less than 2 size_t numOfCols = taosArrayGetSize(pFieldList); if (numOfCols <= 1) { - return buildInvalidOperationMsg(pMsgBuf, msg8); + return buildInvalidOperationMsg(pMsgBuf, msg2); } return validateTableColumns(pFieldList, TSDB_MAX_BYTES_PER_ROW, TSDB_MAX_COLUMNS, pMsgBuf); @@ -297,11 +304,9 @@ static int32_t validateTagParams(SArray* pTagsList, SArray* pFieldList, SMsgBuf* return validateTableColumns(pFieldList, TSDB_MAX_TAGS_LEN, TSDB_MAX_TAGS, pMsgBuf); } -int32_t doCheckForCreateTable(SSqlInfo* pInfo, SMsgBuf* pMsgBuf) { +int32_t doCheckForCreateTable(SCreateTableSql* pCreateTable, SMsgBuf* pMsgBuf) { const char* msg1 = "invalid table name"; - SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; - SArray* pFieldList = pCreateTable->colInfo.pColumns; SArray* pTagList = pCreateTable->colInfo.pTagColumns; assert(pFieldList != NULL); @@ -326,6 +331,8 @@ typedef struct SVgroupTablesBatch { SVgroupInfo info; } SVgroupTablesBatch; +static SArray* doSerializeVgroupCreateTableInfo(SHashObj* pVgroupHashmap); + static int32_t doParseSerializeTagValue(SSchema* pTagSchema, int32_t numOfInputTag, SKVRowBuilder* pKvRowBuilder, SArray* pTagValList, int32_t tsPrecision, SMsgBuf* pMsgBuf) { const char* msg1 = "illegal value or data overflow"; @@ -336,14 +343,12 @@ static int32_t doParseSerializeTagValue(SSchema* pTagSchema, int32_t numOfInputT char* endPtr = NULL; char tmpTokenBuf[TSDB_MAX_TAGS_LEN] = {0}; - SKvParam param = {.builder = pKvRowBuilder, .schema = pSchema}; SToken* pItem = taosArrayGet(pTagValList, i); code = parseValueToken(&endPtr, pItem, pSchema, tsPrecision, tmpTokenBuf, KvRowAppend, ¶m, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { - tdDestroyKVRowBuilder(pKvRowBuilder); return buildInvalidOperationMsg(pMsgBuf, msg1); } } @@ -351,13 +356,54 @@ static int32_t doParseSerializeTagValue(SSchema* pTagSchema, int32_t numOfInputT return code; } -int32_t doCheckForCreateCTable(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SMsgBuf* pMsgBuf, char** pOutput, int32_t* len) { +static void addCreateTbReqIntoVgroup(SHashObj* pVgroupHashmap, const SName* pTableName, SKVRow row, uint64_t suid, SVgroupInfo* pVgInfo) { + struct SVCreateTbReq req = {0}; + req.type = TD_CHILD_TABLE; + req.name = strdup(tNameGetTableName(pTableName)); + req.ctbCfg.suid = suid; + req.ctbCfg.pTag = row; + + SVgroupTablesBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId)); + if (pTableBatch == NULL) { + SVgroupTablesBatch tBatch = {0}; + tBatch.info = *pVgInfo; + + tBatch.req.pArray = taosArrayInit(4, sizeof(struct SVCreateTbReq)); + taosArrayPush(tBatch.req.pArray, &req); + + taosHashPut(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId), &tBatch, sizeof(tBatch)); + } else { // add to the correct vgroup + assert(pVgInfo->vgId == pTableBatch->info.vgId); + taosArrayPush(pTableBatch->req.pArray, &req); + } +} + +static void destroyCreateTbReqBatch(SVgroupTablesBatch* pTbBatch) { + size_t size = taosArrayGetSize(pTbBatch->req.pArray); + for(int32_t i = 0; i < size; ++i) { + SVCreateTbReq* pTableReq = taosArrayGet(pTbBatch->req.pArray, i); + tfree(pTableReq->name); + + if (pTableReq->type == TSDB_NORMAL_TABLE) { + tfree(pTableReq->ntbCfg.pSchema); + } else if (pTableReq->type == TSDB_CHILD_TABLE) { + tfree(pTableReq->ctbCfg.pTag); + } else { + assert(0); + } + } + + taosArrayDestroy(pTbBatch->req.pArray); +} + +static int32_t doCheckAndBuildCreateCTableReq(SCreateTableSql* pCreateTable, SParseBasicCtx* pCtx, SMsgBuf* pMsgBuf, SArray** pBufArray) { const char* msg1 = "invalid table name"; const char* msg2 = "tags number not matched"; const char* msg3 = "tag value too long"; const char* msg4 = "illegal value or data overflow"; - SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; + int32_t code = 0; + STableMeta* pSuperTableMeta = NULL; SHashObj* pVgroupHashmap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); @@ -367,24 +413,30 @@ int32_t doCheckForCreateCTable(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SMsgBuf* p SCreatedTableInfo* pCreateTableInfo = taosArrayGet(pCreateTable->childTableInfo, j); SToken* pSTableNameToken = &pCreateTableInfo->stbName; - int32_t code = parserValidateNameToken(pSTableNameToken); + code = parserValidateNameToken(pSTableNameToken); if (code != TSDB_CODE_SUCCESS) { - return buildInvalidOperationMsg(pMsgBuf, msg1); + code = buildInvalidOperationMsg(pMsgBuf, msg1); + goto _error; } SName name = {0}; code = createSName(&name, pSTableNameToken, pCtx, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { - return code; + goto _error; + } + + SKVRowBuilder kvRowBuilder = {0}; + if (tdInitKVRowBuilder(&kvRowBuilder) < 0) { + code = TSDB_CODE_TSC_OUT_OF_MEMORY; + goto _error; } SArray* pValList = pCreateTableInfo->pTagVals; size_t numOfInputTag = taosArrayGetSize(pValList); - STableMeta* pSuperTableMeta = NULL; code = catalogGetTableMeta(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, &name, &pSuperTableMeta); if (code != TSDB_CODE_SUCCESS) { - return code; + goto _error; } assert(pSuperTableMeta != NULL); @@ -393,26 +445,22 @@ int32_t doCheckForCreateCTable(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SMsgBuf* p SSchema* pTagSchema = getTableTagSchema(pSuperTableMeta); STableComInfo tinfo = getTableInfo(pSuperTableMeta); - SKVRowBuilder kvRowBuilder = {0}; - if (tdInitKVRowBuilder(&kvRowBuilder) < 0) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - SArray* pNameList = NULL; - size_t nameSize = 0; + size_t numOfBoundTags = 0; int32_t schemaSize = getNumOfTags(pSuperTableMeta); if (pCreateTableInfo->pTagNames) { pNameList = pCreateTableInfo->pTagNames; - nameSize = taosArrayGetSize(pNameList); + numOfBoundTags = taosArrayGetSize(pNameList); - if (numOfInputTag != nameSize || schemaSize < numOfInputTag) { + if (numOfInputTag != numOfBoundTags || schemaSize < numOfInputTag) { tdDestroyKVRowBuilder(&kvRowBuilder); - return buildInvalidOperationMsg(pMsgBuf, msg2); + code = buildInvalidOperationMsg(pMsgBuf, msg2); + goto _error; } bool findColumnIndex = false; - for (int32_t i = 0; i < nameSize; ++i) { + for (int32_t i = 0; i < numOfBoundTags; ++i) { SToken* sToken = taosArrayGet(pNameList, i); char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr @@ -440,7 +488,8 @@ int32_t doCheckForCreateCTable(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SMsgBuf* p if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) { if (pItem->pVar.nLen > pSchema->bytes) { tdDestroyKVRowBuilder(&kvRowBuilder); - return buildInvalidOperationMsg(pMsgBuf, msg3); + code = buildInvalidOperationMsg(pMsgBuf, msg3); + goto _error; } } else if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) { if (pItem->pVar.nType == TSDB_DATA_TYPE_BINARY) { @@ -456,17 +505,19 @@ int32_t doCheckForCreateCTable(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SMsgBuf* p code = taosVariantDump(&(pItem->pVar), tagVal, pSchema->type, true); // check again after the convert since it may be converted from binary to nchar. - if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) { + if (IS_VAR_DATA_TYPE(pSchema->type)) { int16_t len = varDataTLen(tagVal); if (len > pSchema->bytes) { tdDestroyKVRowBuilder(&kvRowBuilder); - return buildInvalidOperationMsg(pMsgBuf, msg3); + code = buildInvalidOperationMsg(pMsgBuf, msg3); + goto _error; } } if (code != TSDB_CODE_SUCCESS) { tdDestroyKVRowBuilder(&kvRowBuilder); - return buildInvalidOperationMsg(pMsgBuf, msg4); + code = buildInvalidOperationMsg(pMsgBuf, msg4); + goto _error; } tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal); @@ -484,25 +535,119 @@ int32_t doCheckForCreateCTable(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SMsgBuf* p } else { if (schemaSize != numOfInputTag) { tdDestroyKVRowBuilder(&kvRowBuilder); - return buildInvalidOperationMsg(pMsgBuf, msg2); + code = buildInvalidOperationMsg(pMsgBuf, msg2); + goto _error; } code = doParseSerializeTagValue(pTagSchema, numOfInputTag, &kvRowBuilder, pValList, tinfo.precision, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { - return code; + tdDestroyKVRowBuilder(&kvRowBuilder); + goto _error; } } SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder); tdDestroyKVRowBuilder(&kvRowBuilder); if (row == NULL) { - return TSDB_CODE_QRY_OUT_OF_MEMORY; + code = TSDB_CODE_QRY_OUT_OF_MEMORY; + goto _error; } tdSortKVRowByColIdx(row); SName tableName = {0}; code = createSName(&tableName, &pCreateTableInfo->name, pCtx, pMsgBuf); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + // Find a appropriate vgroup to accommodate this table , according to the table name + SVgroupInfo info = {0}; + code = catalogGetTableHashVgroup(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, &tableName, &info); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + addCreateTbReqIntoVgroup(pVgroupHashmap, &tableName, row, pSuperTableMeta->uid, &info); + tfree(pSuperTableMeta); + } + + *pBufArray = doSerializeVgroupCreateTableInfo(pVgroupHashmap); + if (*pBufArray == NULL) { + code = terrno; + goto _error; + } + + taosHashCleanup(pVgroupHashmap); + return TSDB_CODE_SUCCESS; + + _error: + taosHashCleanup(pVgroupHashmap); + tfree(pSuperTableMeta); + terrno = code; + return code; +} + +static int32_t serializeVgroupTablesBatchImpl(SVgroupTablesBatch* pTbBatch, SArray* pBufArray) { + int tlen = sizeof(SMsgHead) + tSVCreateTbBatchReqSerialize(NULL, &(pTbBatch->req)); + void* buf = malloc(tlen); + if (buf == NULL) { + // TODO: handle error + } + + ((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId); + ((SMsgHead*)buf)->contLen = htonl(tlen); + + void* pBuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); + tSVCreateTbBatchReqSerialize(&pBuf, &(pTbBatch->req)); + + SVgDataBlocks* pVgData = calloc(1, sizeof(SVgDataBlocks)); + pVgData->vg = pTbBatch->info; + pVgData->pData = buf; + pVgData->size = tlen; + pVgData->numOfTables = (int32_t) taosArrayGetSize(pTbBatch->req.pArray); + + taosArrayPush(pBufArray, &pVgData); +} + +static int32_t doBuildSingleTableBatchReq(SName* pTableName, SArray* pColumns, SVgroupInfo* pVgroupInfo, SVgroupTablesBatch* pBatch) { + struct SVCreateTbReq req = {0}; + req.type = TD_NORMAL_TABLE; + req.name = strdup(tNameGetTableName(pTableName)); + + req.ntbCfg.nCols = taosArrayGetSize(pColumns); + int32_t num = req.ntbCfg.nCols; + + req.ntbCfg.pSchema = calloc(num, sizeof(SSchema)); + for(int32_t i = 0; i < num; ++i) { + SSchema* pSchema = taosArrayGet(pColumns, i); + memcpy(&req.ntbCfg.pSchema[i], pSchema, sizeof(SSchema)); + } + + pBatch->info = *pVgroupInfo; + pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq)); + if (pBatch->req.pArray == NULL) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + taosArrayPush(pBatch->req.pArray, &req); + return TSDB_CODE_SUCCESS; +} + +int32_t doCheckAndBuildCreateTableReq(SCreateTableSql* pCreateTable, SParseBasicCtx* pCtx, SMsgBuf* pMsgBuf, char** pOutput, int32_t* len) { + SArray* pBufArray = NULL; + int32_t code = 0; + + // it is a sql statement to create a normal table + if (pCreateTable->childTableInfo == NULL) { + assert(taosArrayGetSize(pCreateTable->colInfo.pColumns) > 0 && pCreateTable->colInfo.pTagColumns == NULL); + code = doCheckForCreateTable(pCreateTable, pMsgBuf); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + SName tableName = {0}; + code = createSName(&tableName, &pCreateTable->name, pCtx, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -510,64 +655,52 @@ int32_t doCheckForCreateCTable(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SMsgBuf* p SVgroupInfo info = {0}; catalogGetTableHashVgroup(pCtx->pCatalog, pCtx->pTransporter, &pCtx->mgmtEpSet, &tableName, &info); - struct SVCreateTbReq req = {0}; - req.type = TD_CHILD_TABLE; - req.name = strdup(tNameGetTableName(&tableName)); - req.ctbCfg.suid = pSuperTableMeta->uid; - req.ctbCfg.pTag = row; + SVgroupTablesBatch tbatch = {0}; + code = doBuildSingleTableBatchReq(&tableName, pCreateTable->colInfo.pColumns, &info, &tbatch); + if (code != TSDB_CODE_SUCCESS) { + return code; + } - SVgroupTablesBatch* pTableBatch = taosHashGet(pVgroupHashmap, &info.vgId, sizeof(info.vgId)); - if (pTableBatch == NULL) { - SVgroupTablesBatch tBatch = {0}; - tBatch.info = info; + pBufArray = taosArrayInit(1, POINTER_BYTES); + if (pBufArray == NULL) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } - tBatch.req.pArray = taosArrayInit(4, sizeof(struct SVCreateTbReq)); - taosArrayPush(tBatch.req.pArray, &req); + serializeVgroupTablesBatchImpl(&tbatch, pBufArray); + destroyCreateTbReqBatch(&tbatch); - taosHashPut(pVgroupHashmap, &info.vgId, sizeof(info.vgId), &tBatch, sizeof(tBatch)); - } else { // add to the correct vgroup - assert(info.vgId == pTableBatch->info.vgId); - taosArrayPush(pTableBatch->req.pArray, &req); + } else { // it is a child table, created according to a super table + code = doCheckAndBuildCreateCTableReq(pCreateTable, pCtx, pMsgBuf, &pBufArray); + if (code != 0) { + return code; } } - // TODO: serialize and + SVnodeModifOpStmtInfo* pStmtInfo = calloc(1, sizeof(SVnodeModifOpStmtInfo)); + pStmtInfo->nodeType = TSDB_SQL_CREATE_TABLE; + pStmtInfo->pDataBlocks = pBufArray; + + *pOutput = (char*) pStmtInfo; + *len = sizeof(SVnodeModifOpStmtInfo); + + return TSDB_CODE_SUCCESS; +} + +SArray* doSerializeVgroupCreateTableInfo(SHashObj* pVgroupHashmap) { SArray* pBufArray = taosArrayInit(taosHashGetSize(pVgroupHashmap), sizeof(void*)); SVgroupTablesBatch* pTbBatch = NULL; do { pTbBatch = taosHashIterate(pVgroupHashmap, pTbBatch); - if (pTbBatch == NULL) break; - - int tlen = sizeof(SMsgHead) + tSVCreateTbBatchReqSerialize(NULL, &(pTbBatch->req)); - void* buf = malloc(tlen); - if (buf == NULL) { - // TODO: handle error + if (pTbBatch == NULL) { + break; } - ((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId); - ((SMsgHead*)buf)->contLen = htonl(tlen); - - void* pBuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); - tSVCreateTbBatchReqSerialize(&pBuf, &(pTbBatch->req)); - - SVgDataBlocks* pVgData = calloc(1, sizeof(SVgDataBlocks)); - pVgData->vg = pTbBatch->info; - pVgData->pData = buf; - pVgData->size = tlen; - pVgData->numOfTables = (int32_t) taosArrayGetSize(pTbBatch->req.pArray); - - taosArrayPush(pBufArray, &pVgData); + /*int32_t code = */serializeVgroupTablesBatchImpl(pTbBatch, pBufArray); + destroyCreateTbReqBatch(pTbBatch); } while (true); - SVnodeModifOpStmtInfo* pStmtInfo = calloc(1, sizeof(SVnodeModifOpStmtInfo)); - pStmtInfo->nodeType = TSDB_SQL_CREATE_TABLE; - pStmtInfo->pDataBlocks = pBufArray; - - *pOutput = (char*) pStmtInfo; - *len = sizeof(SVnodeModifOpStmtInfo); - - return TSDB_CODE_SUCCESS; + return pBufArray; } SDclStmtInfo* qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, char* msgBuf, int32_t msgBufLen) { @@ -709,11 +842,11 @@ SDclStmtInfo* qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, c goto _error; } - SUseDbMsg* pUseDbMsg = (SUseDbMsg*)calloc(1, sizeof(SUseDbMsg)); + SUseDbReq* pUseDbMsg = (SUseDbReq*)calloc(1, sizeof(SUseDbReq)); tNameExtractFullName(&n, pUseDbMsg->db); pDcl->pMsg = (char*)pUseDbMsg; - pDcl->msgLen = sizeof(SUseDbMsg); + pDcl->msgLen = sizeof(SUseDbReq); pDcl->msgType = TDMT_MND_USE_DB; break; } @@ -737,14 +870,14 @@ SDclStmtInfo* qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, c goto _error; } - SCreateDbMsg* pCreateMsg = buildCreateDbMsg(pCreateDB, pCtx, pMsgBuf); + SCreateDbReq* pCreateMsg = buildCreateDbMsg(pCreateDB, pCtx, pMsgBuf); if (doCheckDbOptions(pCreateMsg, pMsgBuf) != TSDB_CODE_SUCCESS) { code = TSDB_CODE_TSC_INVALID_OPERATION; goto _error; } pDcl->pMsg = (char*)pCreateMsg; - pDcl->msgLen = sizeof(SCreateDbMsg); + pDcl->msgLen = sizeof(SCreateDbReq); pDcl->msgType = (pInfo->type == TSDB_SQL_CREATE_DB) ? TDMT_MND_CREATE_DB : TDMT_MND_ALTER_DB; break; } @@ -762,35 +895,27 @@ SDclStmtInfo* qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, c goto _error; } - SDropDbMsg* pDropDbMsg = (SDropDbMsg*)calloc(1, sizeof(SDropDbMsg)); + SDropDbReq* pDropDbMsg = (SDropDbReq*)calloc(1, sizeof(SDropDbReq)); code = tNameExtractFullName(&name, pDropDbMsg->db); pDropDbMsg->ignoreNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0; assert(code == TSDB_CODE_SUCCESS && name.type == TSDB_DB_NAME_T); pDcl->msgType = TDMT_MND_DROP_DB; - pDcl->msgLen = sizeof(SDropDbMsg); + pDcl->msgLen = sizeof(SDropDbReq); pDcl->pMsg = (char*)pDropDbMsg; break; } case TSDB_SQL_CREATE_STABLE: { SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; - assert(pCreateTable->type != TSQL_CREATE_CTABLE); - - if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) { - if ((code = doCheckForCreateTable(pInfo, pMsgBuf)) != TSDB_CODE_SUCCESS) { - terrno = code; - goto _error; - } - - pDcl->pMsg = (char*)buildCreateTableMsg(pCreateTable, &pDcl->msgLen, pCtx, pMsgBuf); - pDcl->msgType = (pCreateTable->type == TSQL_CREATE_TABLE) ? TDMT_VND_CREATE_TABLE : TDMT_MND_CREATE_STB; - } else if (pCreateTable->type == TSQL_CREATE_STREAM) { - // if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) { - // return code; + if ((code = doCheckForCreateTable(pCreateTable, pMsgBuf)) != TSDB_CODE_SUCCESS) { + terrno = code; + goto _error; } + pDcl->pMsg = (char*)buildCreateStbMsg(pCreateTable, &pDcl->msgLen, pCtx, pMsgBuf); + pDcl->msgType = TDMT_MND_CREATE_STB; break; } @@ -838,19 +963,19 @@ SDclStmtInfo* qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, c SVnodeModifOpStmtInfo* qParserValidateCreateTbSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, char* msgBuf, int32_t msgBufLen) { SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; - assert(pCreateTable->type == TSQL_CREATE_CTABLE); + assert(pCreateTable->type == TSDB_SQL_CREATE_TABLE); SMsgBuf m = {.buf = msgBuf, .len = msgBufLen}; SMsgBuf* pMsgBuf = &m; - SVnodeModifOpStmtInfo* pInsertStmt = NULL; + SVnodeModifOpStmtInfo* pModifSqlStmt = NULL; int32_t msgLen = 0; - int32_t code = doCheckForCreateCTable(pInfo, pCtx, pMsgBuf, (char**) &pInsertStmt, &msgLen); + int32_t code = doCheckAndBuildCreateTableReq(pCreateTable, pCtx, pMsgBuf, (char**) &pModifSqlStmt, &msgLen); if (code != TSDB_CODE_SUCCESS) { - tfree(pInsertStmt); + tfree(pModifSqlStmt); return NULL; } - return pInsertStmt; + return pModifSqlStmt; } \ No newline at end of file diff --git a/source/libs/parser/src/dataBlockMgt.c b/source/libs/parser/src/dataBlockMgt.c index b315ea613f..bc4eae7ae9 100644 --- a/source/libs/parser/src/dataBlockMgt.c +++ b/source/libs/parser/src/dataBlockMgt.c @@ -467,7 +467,7 @@ static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, SB } int32_t mergeTableDataBlocks(SHashObj* pHashObj, int8_t schemaAttached, uint8_t payloadType, SArray** pVgDataBlocks) { - const int INSERT_HEAD_SIZE = sizeof(SMsgDesc) + sizeof(SSubmitMsg); + const int INSERT_HEAD_SIZE = sizeof(SSubmitMsg); int code = 0; bool isRawPayload = IS_RAW_PAYLOAD(payloadType); SHashObj* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); diff --git a/source/libs/parser/src/insertParser.c b/source/libs/parser/src/insertParser.c index c63e854051..04c287baf1 100644 --- a/source/libs/parser/src/insertParser.c +++ b/source/libs/parser/src/insertParser.c @@ -121,11 +121,9 @@ static int32_t findCol(SToken* pColname, int32_t start, int32_t end, SSchema* pS } static void buildMsgHeader(SVgDataBlocks* blocks) { - SMsgDesc* desc = (SMsgDesc*)blocks->pData; - desc->numOfVnodes = htonl(1); - SSubmitMsg* submit = (SSubmitMsg*)(desc + 1); + SSubmitMsg* submit = (SSubmitMsg*)blocks->pData; submit->header.vgId = htonl(blocks->vg.vgId); - submit->header.contLen = htonl(blocks->size - sizeof(SMsgDesc)); + submit->header.contLen = htonl(blocks->size); submit->length = submit->header.contLen; submit->numOfBlocks = htonl(blocks->numOfTables); SSubmitBlk* blk = (SSubmitBlk*)(submit + 1); @@ -626,12 +624,11 @@ int32_t parseInsertSql(SParseContext* pContext, SVnodeModifOpStmtInfo** pInfo) { if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj || NULL == context.pOutput) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; - return TSDB_CODE_FAILED; + return TSDB_CODE_TSC_OUT_OF_MEMORY; } *pInfo = context.pOutput; context.pOutput->nodeType = TSDB_SQL_INSERT; - context.pOutput->schemaAttache = pContext->schemaAttached; context.pOutput->payloadType = PAYLOAD_TYPE_KV; int32_t code = skipInsertInto(&context); @@ -640,5 +637,5 @@ int32_t parseInsertSql(SParseContext* pContext, SVnodeModifOpStmtInfo** pInfo) { } destroyInsertParseContext(&context); terrno = code; - return (TSDB_CODE_SUCCESS == code ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED); + return code; } diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index 9455d23a1c..f440e6cdfe 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -31,8 +31,8 @@ bool isInsertSql(const char* pStr, size_t length) { } while (1); } -bool qIsDdlQuery(const SQueryNode* pQuery) { - return TSDB_SQL_INSERT != pQuery->type && TSDB_SQL_SELECT != pQuery->type && TSDB_SQL_CREATE_TABLE != pQuery->type; +bool qIsDdlQuery(const SQueryNode* pQueryNode) { + return TSDB_SQL_INSERT != pQueryNode->type && TSDB_SQL_SELECT != pQueryNode->type && TSDB_SQL_CREATE_TABLE != pQueryNode->type; } int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { @@ -44,21 +44,13 @@ int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { } if (!isDqlSqlStatement(&info)) { - bool toVnode = false; if (info.type == TSDB_SQL_CREATE_TABLE) { - SCreateTableSql* pCreateSql = info.pCreateTableInfo; - if (pCreateSql->type == TSQL_CREATE_CTABLE || pCreateSql->type == TSQL_CREATE_TABLE) { - toVnode = true; - } - } - - if (toVnode) { - SVnodeModifOpStmtInfo *pInsertInfo = qParserValidateCreateTbSqlNode(&info, &pCxt->ctx, pCxt->pMsg, pCxt->msgLen); - if (pInsertInfo == NULL) { + SVnodeModifOpStmtInfo * pModifStmtInfo = qParserValidateCreateTbSqlNode(&info, &pCxt->ctx, pCxt->pMsg, pCxt->msgLen); + if (pModifStmtInfo == NULL) { return terrno; } - *pQuery = (SQueryNode*) pInsertInfo; + *pQuery = (SQueryNode*)pModifStmtInfo; } else { SDclStmtInfo* pDcl = qParserValidateDclSqlNode(&info, &pCxt->ctx, pCxt->pMsg, pCxt->msgLen); if (pDcl == NULL) { @@ -69,13 +61,13 @@ int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { pDcl->nodeType = info.type; } } else { - SQueryStmtInfo* pQueryInfo = calloc(1, sizeof(SQueryStmtInfo)); + SQueryStmtInfo* pQueryInfo = createQueryInfo(); if (pQueryInfo == NULL) { terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; // set correct error code. return terrno; } - int32_t code = qParserValidateSqlNode(pCxt->ctx.pCatalog, &info, pQueryInfo, pCxt->ctx.requestId, pCxt->pMsg, pCxt->msgLen); + int32_t code = qParserValidateSqlNode(&pCxt->ctx, &info, pQueryInfo, pCxt->pMsg, pCxt->msgLen); if (code == TSDB_CODE_SUCCESS) { *pQuery = (SQueryNode*)pQueryInfo; } @@ -97,7 +89,7 @@ int32_t qParserConvertSql(const char* pStr, size_t length, char** pConvertSql) { return 0; } -static int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SMsgBuf* pMsgBuf); +static int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SParseBasicCtx *pCtx, SMsgBuf* pMsgBuf); static int32_t tnameComparFn(const void* p1, const void* p2) { SName* pn1 = (SName*)p1; @@ -121,7 +113,7 @@ static int32_t tnameComparFn(const void* p1, const void* p2) { } } -static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameList, SMsgBuf* pMsgBuf) { +static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameList, SParseBasicCtx *pCtx, SMsgBuf* pMsgBuf) { int32_t numOfSub = (int32_t)taosArrayGetSize(pSqlNode->from->list); for (int32_t j = 0; j < numOfSub; ++j) { @@ -131,12 +123,12 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis for (int32_t i = 0; i < num; ++i) { SSqlNode* p = taosArrayGetP(sub->pSubquery->node, i); if (p->from->type == SQL_FROM_NODE_TABLES) { - int32_t code = getTableNameFromSqlNode(p, tableNameList, pMsgBuf); + int32_t code = getTableNameFromSqlNode(p, tableNameList, pCtx, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { return code; } } else { - getTableNameFromSubquery(p, tableNameList, pMsgBuf); + getTableNameFromSubquery(p, tableNameList, pCtx, pMsgBuf); } } } @@ -144,7 +136,7 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis return TSDB_CODE_SUCCESS; } -int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SMsgBuf* pMsgBuf) { +int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SParseBasicCtx *pParseCtx, SMsgBuf* pMsgBuf) { const char* msg1 = "invalid table name"; int32_t numOfTables = (int32_t) taosArrayGetSize(pSqlNode->from->list); @@ -163,7 +155,11 @@ int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SMsgB } SName name = {0}; - strndequote(name.tname, t->z, t->n); + int32_t code = createSName(&name, t, pParseCtx, pMsgBuf); + if (code != TSDB_CODE_SUCCESS) { + return buildInvalidOperationMsg(pMsgBuf, msg1); + } + taosArrayPush(tableNameList, &name); } @@ -174,7 +170,7 @@ static void freePtrElem(void* p) { tfree(*(char**)p); } -int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SCatalogReq* pMetaInfo, char* msg, int32_t msgBufLen) { +int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SCatalogReq* pMetaInfo, SParseBasicCtx *pCtx, char* msg, int32_t msgBufLen) { int32_t code = TSDB_CODE_SUCCESS; SMsgBuf msgBuf = {.buf = msg, .len = msgBufLen}; @@ -190,12 +186,12 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SCatalogReq* p // load the table meta in the FROM clause if (pSqlNode->from->type == SQL_FROM_NODE_TABLES) { - code = getTableNameFromSqlNode(pSqlNode, pMetaInfo->pTableName, &msgBuf); + code = getTableNameFromSqlNode(pSqlNode, pMetaInfo->pTableName, pCtx, &msgBuf); if (code != TSDB_CODE_SUCCESS) { return code; } } else { - code = getTableNameFromSubquery(pSqlNode, pMetaInfo->pTableName, &msgBuf); + code = getTableNameFromSubquery(pSqlNode, pMetaInfo->pTableName, pCtx, &msgBuf); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -240,6 +236,13 @@ void qParserCleanupMetaRequestInfo(SCatalogReq* pMetaReq) { taosArrayDestroy(pMetaReq->pUdf); } -void qDestroyQuery(SQueryNode* pQuery) { - // todo +void qDestroyQuery(SQueryNode* pQueryNode) { + if (NULL == pQueryNode) { + return; + } + if (nodeType(pQueryNode) == TSDB_SQL_INSERT || nodeType(pQueryNode) == TSDB_SQL_CREATE_TABLE) { + SVnodeModifOpStmtInfo* pModifInfo = (SVnodeModifOpStmtInfo*)pQueryNode; + taosArrayDestroy(pModifInfo->pDataBlocks); + } + tfree(pQueryNode); } diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index d265031a81..a6537998f7 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -2642,7 +2642,7 @@ static void yy_reduce( pCreateTable->childTableInfo = taosArrayInit(4, sizeof(SCreatedTableInfo)); taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy150); - pCreateTable->type = TSQL_CREATE_CTABLE; + pCreateTable->type = TSDB_SQL_CREATE_TABLE; yylhsminor.yy326 = pCreateTable; } yymsp[0].minor.yy326 = yylhsminor.yy326; @@ -2656,7 +2656,7 @@ static void yy_reduce( break; case 140: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ { - yylhsminor.yy326 = tSetCreateTableInfo(yymsp[-1].minor.yy165, NULL, NULL, TSQL_CREATE_TABLE); + yylhsminor.yy326 = tSetCreateTableInfo(yymsp[-1].minor.yy165, NULL, NULL, TSDB_SQL_CREATE_TABLE); setSqlInfo(pInfo, yylhsminor.yy326, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -2666,7 +2666,7 @@ static void yy_reduce( break; case 141: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ { - yylhsminor.yy326 = tSetCreateTableInfo(yymsp[-5].minor.yy165, yymsp[-1].minor.yy165, NULL, TSQL_CREATE_STABLE); + yylhsminor.yy326 = tSetCreateTableInfo(yymsp[-5].minor.yy165, yymsp[-1].minor.yy165, NULL, TSDB_SQL_CREATE_STABLE); setSqlInfo(pInfo, yylhsminor.yy326, NULL, TSDB_SQL_CREATE_STABLE); yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; @@ -2700,11 +2700,11 @@ static void yy_reduce( break; case 146: /* create_table_args ::= ifnotexists ids cpxName AS select */ { - yylhsminor.yy326 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy278, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy326, NULL, TSDB_SQL_CREATE_TABLE); - - yymsp[-3].minor.yy0.n += yymsp[-2].minor.yy0.n; - setCreatedTableName(pInfo, &yymsp[-3].minor.yy0, &yymsp[-4].minor.yy0); +// yylhsminor.yy326 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy278, TSQL_CREATE_STREAM); +// setSqlInfo(pInfo, yylhsminor.yy326, NULL, TSDB_SQL_CREATE_TABLE); +// +// yymsp[-3].minor.yy0.n += yymsp[-2].minor.yy0.n; +// setCreatedTableName(pInfo, &yymsp[-3].minor.yy0, &yymsp[-4].minor.yy0); } yymsp[-4].minor.yy326 = yylhsminor.yy326; break; diff --git a/source/libs/parser/test/insertParserTest.cpp b/source/libs/parser/test/insertParserTest.cpp index 5c175cd023..9b007fb36d 100644 --- a/source/libs/parser/test/insertParserTest.cpp +++ b/source/libs/parser/test/insertParserTest.cpp @@ -70,9 +70,7 @@ protected: for (size_t i = 0; i < num; ++i) { SVgDataBlocks* vg = (SVgDataBlocks*)taosArrayGetP(res_->pDataBlocks, i); cout << "vgId:" << vg->vg.vgId << ", numOfTables:" << vg->numOfTables << ", dataSize:" << vg->size << endl; - SMsgDesc* desc = (SMsgDesc*)(vg->pData); - cout << "numOfVnodes:" << ntohl(desc->numOfVnodes) << endl; - SSubmitMsg* submit = (SSubmitMsg*)(desc + 1); + SSubmitMsg* submit = (SSubmitMsg*)vg->pData; cout << "length:" << ntohl(submit->length) << ", numOfBlocks:" << ntohl(submit->numOfBlocks) << endl; int32_t numOfBlocks = ntohl(submit->numOfBlocks); SSubmitBlk* blk = (SSubmitBlk*)(submit + 1); @@ -95,9 +93,7 @@ protected: SVgDataBlocks* vg = (SVgDataBlocks*)taosArrayGetP(res_->pDataBlocks, i); ASSERT_EQ(vg->numOfTables, numOfTables); ASSERT_GE(vg->size, 0); - SMsgDesc* desc = (SMsgDesc*)(vg->pData); - ASSERT_EQ(ntohl(desc->numOfVnodes), 1); - SSubmitMsg* submit = (SSubmitMsg*)(desc + 1); + SSubmitMsg* submit = (SSubmitMsg*)vg->pData; ASSERT_GE(ntohl(submit->length), 0); ASSERT_GE(ntohl(submit->numOfBlocks), 0); int32_t numOfBlocks = ntohl(submit->numOfBlocks); diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index 3be358fec8..e2b8766700 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -27,8 +27,8 @@ std::unique_ptr mockCatalogService; class TableBuilder : public ITableBuilder { public: virtual TableBuilder& addColumn(const std::string& name, int8_t type, int32_t bytes) { - assert(colId_ < schema()->tableInfo.numOfTags + schema()->tableInfo.numOfColumns); - SSchema* col = schema()->schema + colId_; + assert(colId_ <= schema()->tableInfo.numOfTags + schema()->tableInfo.numOfColumns); + SSchema* col = schema()->schema + (colId_ - 1); col->type = type; col->colId = colId_++; col->bytes = bytes; @@ -66,7 +66,7 @@ private: return std::unique_ptr(new TableBuilder(meta)); } - TableBuilder(STableMeta* schemaMeta) : colId_(0), rowsize_(0), meta_(new MockTableMeta()) { + TableBuilder(STableMeta* schemaMeta) : colId_(1), rowsize_(0), meta_(new MockTableMeta()) { meta_->schema.reset(schemaMeta); } @@ -112,6 +112,9 @@ public: int32_t catalogGetTableHashVgroup(const SName* pTableName, SVgroupInfo* vgInfo) const { // todo vgInfo->vgId = 1; + vgInfo->numOfEps = 1; + vgInfo->epAddr[0].port = 6030; + strcpy(vgInfo->epAddr[0].fqdn, "node1"); return 0; } diff --git a/source/libs/parser/test/parserTests.cpp b/source/libs/parser/test/parserTests.cpp index fe430c5f5e..8758fdbc71 100644 --- a/source/libs/parser/test/parserTests.cpp +++ b/source/libs/parser/test/parserTests.cpp @@ -77,12 +77,15 @@ void sqlCheck(const char* sql, bool valid) { buf.len = 128; buf.buf = msg; + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0); int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -119,7 +122,11 @@ TEST(testCase, validateAST_test) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -177,7 +184,11 @@ TEST(testCase, function_Test) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -223,7 +234,11 @@ TEST(testCase, function_Test2) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -269,7 +284,11 @@ TEST(testCase, function_Test3) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -314,7 +333,11 @@ TEST(testCase, function_Test4) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -362,7 +385,11 @@ TEST(testCase, function_Test5) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -447,7 +474,11 @@ TEST(testCase, function_Test6) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -525,7 +556,11 @@ TEST(testCase, function_Test6) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -587,7 +622,11 @@ TEST(testCase, function_Test6) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); + ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -636,7 +675,7 @@ TEST(testCase, function_Test6) { code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -666,7 +705,10 @@ TEST(testCase, function_Test6) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -688,7 +730,7 @@ TEST(testCase, function_Test6) { code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); diff --git a/source/libs/parser/test/plannerTest.cpp b/source/libs/parser/test/plannerTest.cpp index 04c3a7d81a..8d9fbadfad 100644 --- a/source/libs/parser/test/plannerTest.cpp +++ b/source/libs/parser/test/plannerTest.cpp @@ -81,7 +81,8 @@ void generateLogicplan(const char* sql) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -121,7 +122,9 @@ TEST(testCase, planner_test) { ASSERT_EQ(code, 0); SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + SParseBasicCtx ctx = {0}; + + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); diff --git a/source/libs/parser/test/tokenizerTest.cpp b/source/libs/parser/test/tokenizerTest.cpp index 3ab6a6531c..ee01a50148 100644 --- a/source/libs/parser/test/tokenizerTest.cpp +++ b/source/libs/parser/test/tokenizerTest.cpp @@ -710,7 +710,11 @@ TEST(testCase, extractMeta_test) { char msg[128] = {0}; SCatalogReq req = {0}; - int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + + SParseBasicCtx ctx = {0}; + ctx.db = "db1"; + ctx.acctId = 1; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, &ctx, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); diff --git a/source/libs/planner/CMakeLists.txt b/source/libs/planner/CMakeLists.txt index 6234dbe0ac..8d8c148fde 100644 --- a/source/libs/planner/CMakeLists.txt +++ b/source/libs/planner/CMakeLists.txt @@ -8,7 +8,8 @@ target_include_directories( target_link_libraries( planner - PRIVATE os util catalog cjson parser transport function qcom + PRIVATE os util catalog cjson parser function qcom + PUBLIC transport ) if(${BUILD_TEST}) diff --git a/source/libs/planner/inc/plannerInt.h b/source/libs/planner/inc/plannerInt.h index 31e057f4c0..2a50752c88 100644 --- a/source/libs/planner/inc/plannerInt.h +++ b/source/libs/planner/inc/plannerInt.h @@ -53,8 +53,8 @@ typedef struct SQueryDistPlanNodeInfo { typedef struct SQueryTableInfo { char *tableName; // to be deleted uint64_t uid; // to be deleted - STableMetaInfo* pMeta; - STimeWindow window; + STableMetaInfo *pMeta; + STimeWindow window; } SQueryTableInfo; typedef struct SQueryPlanNode { @@ -106,7 +106,7 @@ int32_t queryPlanToString(struct SQueryPlanNode* pQueryNode, char** str); int32_t queryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql); int32_t createDag(SQueryPlanNode* pQueryNode, struct SCatalog* pCatalog, SQueryDag** pDag, uint64_t requestId); -int32_t setSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep); +void setSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep); int32_t subPlanToString(const SSubplan *pPhyNode, char** str, int32_t* len); int32_t stringToSubplan(const char* str, SSubplan** subplan); diff --git a/source/libs/planner/src/logicPlan.c b/source/libs/planner/src/logicPlan.c index d04fd716c2..9a9b40473b 100644 --- a/source/libs/planner/src/logicPlan.c +++ b/source/libs/planner/src/logicPlan.c @@ -64,10 +64,11 @@ static int32_t createModificationOpPlan(const SQueryNode* pNode, SQueryPlanNode* } int32_t createSelectPlan(const SQueryStmtInfo* pSelect, SQueryPlanNode** pQueryPlan) { - SArray* upstream = createQueryPlanImpl(pSelect); - assert(taosArrayGetSize(upstream) == 1); - *pQueryPlan = taosArrayGetP(upstream, 0); - taosArrayDestroy(upstream); + SArray* pDownstream = createQueryPlanImpl(pSelect); + assert(taosArrayGetSize(pDownstream) == 1); + + *pQueryPlan = taosArrayGetP(pDownstream, 0); + taosArrayDestroy(pDownstream); return TSDB_CODE_SUCCESS; } @@ -100,23 +101,21 @@ void destroyQueryPlan(SQueryPlanNode* pQueryNode) { //====================================================================================================================== -static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPlanNode** prev, int32_t numOfPrev, +static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPlanNode** pChildrenNode, int32_t numOfChildren, SExprInfo** pExpr, int32_t numOfOutput, const void* pExtInfo) { SQueryPlanNode* pNode = calloc(1, sizeof(SQueryPlanNode)); pNode->info.type = type; pNode->info.name = strdup(name); - pNode->numOfExpr = numOfOutput; - pNode->pExpr = taosArrayInit(numOfOutput, POINTER_BYTES); - for(int32_t i = 0; i < numOfOutput; ++i) { - taosArrayPush(pNode->pExpr, &pExpr[i]); - } + pNode->pExpr = taosArrayInit(numOfOutput, POINTER_BYTES); + taosArrayAddBatch(pNode->pExpr, pExpr, numOfOutput); + assert(pNode->numOfExpr == numOfOutput); pNode->pChildren = taosArrayInit(4, POINTER_BYTES); - for(int32_t i = 0; i < numOfPrev; ++i) { - taosArrayPush(pNode->pChildren, &prev[i]); + for(int32_t i = 0; i < numOfChildren; ++i) { + taosArrayPush(pNode->pChildren, &pChildrenNode[i]); } switch(type) { @@ -184,8 +183,7 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla return pNode; } -static SQueryPlanNode* doAddTableColumnNode(const SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SQueryTableInfo* info, - SArray* pExprs, SArray* tableCols) { +static SQueryPlanNode* doAddTableColumnNode(const SQueryStmtInfo* pQueryInfo, SQueryTableInfo* info, SArray* pExprs, SArray* tableCols) { if (pQueryInfo->info.onlyTagQuery) { int32_t num = (int32_t) taosArrayGetSize(pExprs); SQueryPlanNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info); @@ -193,16 +191,12 @@ static SQueryPlanNode* doAddTableColumnNode(const SQueryStmtInfo* pQueryInfo, ST if (pQueryInfo->info.distinct) { pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, NULL); } - return pNode; } SQueryPlanNode* pNode = createQueryNode(QNODE_TABLESCAN, "TableScan", NULL, 0, NULL, 0, info); - if (pQueryInfo->info.projectionQuery) { - int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs); - pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExprs->pData, numOfOutput, NULL); - } else { + if (!pQueryInfo->info.projectionQuery) { STableMetaInfo* pTableMetaInfo1 = getMetaInfo(pQueryInfo, 0); // table source column projection, generate the projection expr @@ -262,7 +256,11 @@ static SQueryPlanNode* doCreateQueryPlanForSingleTableImpl(const SQueryStmtInfo* pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, p->pData, num, NULL); } } else { - pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, p->pData, num, NULL); + // here we can push down the projection to tablescan operator. + pNode->numOfExpr = num; + pNode->pExpr = taosArrayInit(num, POINTER_BYTES); + taosArrayAddAll(pNode->pExpr, p); +// pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, p->pData, num, NULL); } } @@ -299,9 +297,11 @@ static SQueryPlanNode* doCreateQueryPlanForSingleTable(const SQueryStmtInfo* pQu tstrncpy(name, pTableMetaInfo->name.tname, TSDB_TABLE_FNAME_LEN); SQueryTableInfo info = {.tableName = strdup(name), .uid = pTableMetaInfo->pTableMeta->uid,}; + info.window = pQueryInfo->window; + info.pMeta = pTableMetaInfo; // handle the only tag query - SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, pExprs, tableCols); + SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, &info, pExprs, tableCols); if (pQueryInfo->info.onlyTagQuery) { tfree(info.tableName); return pNode; @@ -326,23 +326,23 @@ static bool isAllAggExpr(SArray* pList) { } SArray* createQueryPlanImpl(const SQueryStmtInfo* pQueryInfo) { - SArray* upstream = NULL; + SArray* pDownstream = NULL; - if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // subquery in the from clause - upstream = taosArrayInit(4, POINTER_BYTES); + if (pQueryInfo->pDownstream != NULL && taosArrayGetSize(pQueryInfo->pDownstream) > 0) { // subquery in the from clause + pDownstream = taosArrayInit(4, POINTER_BYTES); - size_t size = taosArrayGetSize(pQueryInfo->pUpstream); + size_t size = taosArrayGetSize(pQueryInfo->pDownstream); for(int32_t i = 0; i < size; ++i) { - SQueryStmtInfo* pq = taosArrayGet(pQueryInfo->pUpstream, i); + SQueryStmtInfo* pq = taosArrayGet(pQueryInfo->pDownstream, i); SArray* p = createQueryPlanImpl(pq); - taosArrayAddBatch(upstream, p->pData, (int32_t) taosArrayGetSize(p)); + taosArrayAddBatch(pDownstream, p->pData, (int32_t) taosArrayGetSize(p)); } } if (pQueryInfo->numOfTables > 1) { // it is a join query // 1. separate the select clause according to table - taosArrayDestroy(upstream); - upstream = taosArrayInit(5, POINTER_BYTES); + taosArrayDestroy(pDownstream); + pDownstream = taosArrayInit(5, POINTER_BYTES); for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[i]; @@ -365,33 +365,45 @@ SArray* createQueryPlanImpl(const SQueryStmtInfo* pQueryInfo) { columnListCopy(tableColumnList, pQueryInfo->colList, uid); // 4. add the projection query node - SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList); + SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, &info, exprList, tableColumnList); columnListDestroy(tableColumnList); // dropAllExprInfo(exprList); - taosArrayPush(upstream, &pNode); + taosArrayPush(pDownstream, &pNode); } // 3. add the join node here SQueryTableInfo info = {0}; int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList[0]); - SQueryPlanNode* pNode = createQueryNode(QNODE_JOIN, "Join", upstream->pData, pQueryInfo->numOfTables, + SQueryPlanNode* pNode = createQueryNode(QNODE_JOIN, "Join", pDownstream->pData, pQueryInfo->numOfTables, pQueryInfo->exprList[0]->pData, num, NULL); // 4. add the aggregation or projection execution node pNode = doCreateQueryPlanForSingleTableImpl(pQueryInfo, pNode, &info); - upstream = taosArrayInit(5, POINTER_BYTES); - taosArrayPush(upstream, &pNode); + pDownstream = taosArrayInit(5, POINTER_BYTES); + taosArrayPush(pDownstream, &pNode); } else { // only one table, normal query process STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; SQueryPlanNode* pNode = doCreateQueryPlanForSingleTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList[0], pQueryInfo->colList); - upstream = taosArrayInit(5, POINTER_BYTES); - taosArrayPush(upstream, &pNode); + pDownstream = taosArrayInit(5, POINTER_BYTES); + taosArrayPush(pDownstream, &pNode); } - return upstream; + return pDownstream; } static void doDestroyQueryNode(SQueryPlanNode* pQueryNode) { + if (pQueryNode->info.type == QNODE_MODIFY) { + SDataPayloadInfo* pInfo = pQueryNode->pExtInfo; + + size_t size = taosArrayGetSize(pInfo->payload); + for (int32_t i = 0; i < size; ++i) { + SVgDataBlocks* pBlock = taosArrayGetP(pInfo->payload, i); + tfree(pBlock); + } + + taosArrayDestroy(pInfo->payload); + } + tfree(pQueryNode->pExtInfo); tfree(pQueryNode->pSchema); tfree(pQueryNode->info.name); @@ -422,22 +434,23 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, switch(pQueryNode->info.type) { case QNODE_TABLESCAN: { SQueryTableInfo* pInfo = (SQueryTableInfo*)pQueryNode->pExtInfo; - len1 = sprintf(buf + len, "%s #%" PRIu64 ") time_range: %" PRId64 " - %" PRId64, pInfo->tableName, pInfo->uid, - pInfo->window.skey, pInfo->window.ekey); + len1 = sprintf(buf + len, "%s #%" PRIu64, pInfo->tableName, pInfo->uid); assert(len1 > 0); len += len1; - for (int32_t i = 0; i < pQueryNode->numOfExpr; ++i) { - SColumn* pCol = taosArrayGetP(pQueryNode->pExpr, i); - len1 = sprintf(buf + len, " [%s #%d] ", pCol->name, pCol->info.colId); + len1 = sprintf(buf + len, " , cols:"); + assert(len1 > 0); + len += len1; - assert(len1 > 0); - len += len1; - } - - len1 = sprintf(buf + len, "\n"); + len = printExprInfo(buf, pQueryNode, len); + len1 = sprintf(buf + len, ")"); assert(len1 > 0); + // todo print filter info + len1 = sprintf(buf + len, ") filters:(nil)"); + len += len1; + + len1 = sprintf(buf + len, " time_range: %" PRId64 " - %" PRId64"\n", pInfo->window.skey, pInfo->window.ekey); len += len1; break; } diff --git a/source/libs/planner/src/physicalPlan.c b/source/libs/planner/src/physicalPlan.c index 7f472be756..a38d110d5f 100644 --- a/source/libs/planner/src/physicalPlan.c +++ b/source/libs/planner/src/physicalPlan.c @@ -75,24 +75,16 @@ int32_t dsinkNameToDsinkType(const char* name) { return DSINK_Unknown; } -static SDataSink* initDataSink(int32_t type, int32_t size) { - SDataSink* sink = (SDataSink*)validPointer(calloc(1, size)); - sink->info.type = type; - sink->info.name = dsinkTypeToDsinkName(type); - return sink; -} - -static SDataSink* createDataDispatcher(SPlanContext* pCxt, SQueryPlanNode* pPlanNode) { - SDataDispatcher* dispatcher = (SDataDispatcher*)initDataSink(DSINK_Dispatch, sizeof(SDataDispatcher)); - return (SDataSink*)dispatcher; -} - -static SDataSink* createDataInserter(SPlanContext* pCxt, SVgDataBlocks* pBlocks) { - SDataInserter* inserter = (SDataInserter*)initDataSink(DSINK_Insert, sizeof(SDataInserter)); - inserter->numOfTables = pBlocks->numOfTables; - inserter->size = pBlocks->size; - SWAP(inserter->pData, pBlocks->pData, char*); - return (SDataSink*)inserter; +static bool copySchema(SDataBlockSchema* dst, const SDataBlockSchema* src) { + dst->pSchema = malloc(sizeof(SSlotSchema) * src->numOfCols); + if (NULL == dst->pSchema) { + return false; + } + memcpy(dst->pSchema, src->pSchema, sizeof(SSlotSchema) * src->numOfCols); + dst->numOfCols = src->numOfCols; + dst->resultRowSize = src->resultRowSize; + dst->precision = src->precision; + return true; } static bool toDataBlockSchema(SQueryPlanNode* pPlanNode, SDataBlockSchema* dataBlockSchema) { @@ -102,6 +94,10 @@ static bool toDataBlockSchema(SQueryPlanNode* pPlanNode, SDataBlockSchema* dataB return false; } memcpy(dataBlockSchema->pSchema, pPlanNode->pSchema, sizeof(SSlotSchema) * pPlanNode->numOfCols); + dataBlockSchema->resultRowSize = 0; + for (int32_t i = 0; i < dataBlockSchema->numOfCols; ++i) { + dataBlockSchema->resultRowSize += dataBlockSchema->pSchema[i].bytes; + } return true; } @@ -120,13 +116,37 @@ static bool cloneExprArray(SArray** dst, SArray* src) { return (TSDB_CODE_SUCCESS == copyAllExprInfo(*dst, src, true) ? true : false); } +static SDataSink* initDataSink(int32_t type, int32_t size, const SPhyNode* pRoot) { + SDataSink* sink = (SDataSink*)validPointer(calloc(1, size)); + sink->info.type = type; + sink->info.name = dsinkTypeToDsinkName(type); + if (NULL !=pRoot && !copySchema(&sink->schema, &pRoot->targetSchema)) { + tfree(sink); + THROW(TSDB_CODE_TSC_OUT_OF_MEMORY); + } + return sink; +} + +static SDataSink* createDataInserter(SPlanContext* pCxt, SVgDataBlocks* pBlocks, const SPhyNode* pRoot) { + SDataInserter* inserter = (SDataInserter*)initDataSink(DSINK_Insert, sizeof(SDataInserter), pRoot); + inserter->numOfTables = pBlocks->numOfTables; + inserter->size = pBlocks->size; + SWAP(inserter->pData, pBlocks->pData, char*); + return (SDataSink*)inserter; +} + +static SDataSink* createDataDispatcher(SPlanContext* pCxt, SQueryPlanNode* pPlanNode, const SPhyNode* pRoot) { + SDataDispatcher* dispatcher = (SDataDispatcher*)initDataSink(DSINK_Dispatch, sizeof(SDataDispatcher), pRoot); + return (SDataSink*)dispatcher; +} + static SPhyNode* initPhyNode(SQueryPlanNode* pPlanNode, int32_t type, int32_t size) { SPhyNode* node = (SPhyNode*)validPointer(calloc(1, size)); node->info.type = type; node->info.name = opTypeToOpName(type); if (!cloneExprArray(&node->pTargets, pPlanNode->pExpr) || !toDataBlockSchema(pPlanNode, &(node->targetSchema))) { free(node); - return NULL; + THROW(TSDB_CODE_TSC_OUT_OF_MEMORY); } return node; } @@ -149,7 +169,7 @@ static SPhyNode* createTagScanNode(SQueryPlanNode* pPlanNode) { static uint8_t getScanFlag(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable) { // todo - return MASTER_SCAN; + return MAIN_SCAN; } static SPhyNode* createUserTableScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable, int32_t op) { @@ -160,9 +180,6 @@ static SPhyNode* createUserTableScanNode(SQueryPlanNode* pPlanNode, SQueryTableI return (SPhyNode*)node; } -static SPhyNode* createSingleTableScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable) { - return createUserTableScanNode(pPlanNode, pTable, OP_TableScan); -} static bool isSystemTable(SQueryTableInfo* pTable) { // todo @@ -187,7 +204,8 @@ static SSubplan* initSubplan(SPlanContext* pCxt, int32_t type) { SSubplan* subplan = validPointer(calloc(1, sizeof(SSubplan))); subplan->id = pCxt->nextId; ++(pCxt->nextId.subplanId); - subplan->type = type; + + subplan->type = type; subplan->level = 0; if (NULL != pCxt->pCurrentSubplan) { subplan->level = pCxt->pCurrentSubplan->level + 1; @@ -216,7 +234,7 @@ static SSubplan* initSubplan(SPlanContext* pCxt, int32_t type) { static void vgroupInfoToEpSet(const SVgroupInfo* vg, SQueryNodeAddr* execNode) { execNode->nodeId = vg->vgId; - execNode->inUse = 0; // todo + execNode->inUse = vg->inUse; execNode->numOfEps = vg->numOfEps; for (int8_t i = 0; i < vg->numOfEps; ++i) { execNode->epAddr[i] = vg->epAddr[i]; @@ -239,9 +257,10 @@ static uint64_t splitSubplanByTable(SPlanContext* pCxt, SQueryPlanNode* pPlanNod for (int32_t i = 0; i < pTable->pMeta->vgroupList->numOfVgroups; ++i) { STORE_CURRENT_SUBPLAN(pCxt); SSubplan* subplan = initSubplan(pCxt, QUERY_TYPE_SCAN); + subplan->msgType = TDMT_VND_QUERY; vgroupMsgToEpSet(&(pTable->pMeta->vgroupList->vgroups[i]), &subplan->execNode); subplan->pNode = createMultiTableScanNode(pPlanNode, pTable); - subplan->pDataSink = createDataDispatcher(pCxt, pPlanNode); + subplan->pDataSink = createDataDispatcher(pCxt, pPlanNode, subplan->pNode); RECOVERY_CURRENT_SUBPLAN(pCxt); } return pCxt->nextId.templateId++; @@ -250,6 +269,7 @@ static uint64_t splitSubplanByTable(SPlanContext* pCxt, SQueryPlanNode* pPlanNod static SPhyNode* createExchangeNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode, uint64_t srcTemplateId) { SExchangePhyNode* node = (SExchangePhyNode*)initPhyNode(pPlanNode, OP_Exchange, sizeof(SExchangePhyNode)); node->srcTemplateId = srcTemplateId; + node->pSrcEndPoints = validPointer(taosArrayInit(TARRAY_MIN_SIZE, sizeof(SQueryNodeAddr))); return (SPhyNode*)node; } @@ -258,12 +278,20 @@ static bool needMultiNodeScan(SQueryTableInfo* pTable) { return (TSDB_SUPER_TABLE == pTable->pMeta->pTableMeta->tableType); } +static SPhyNode* createSingleTableScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable, SSubplan* subplan) { + vgroupMsgToEpSet(&(pTable->pMeta->vgroupList->vgroups[0]), &subplan->execNode); + + return createUserTableScanNode(pPlanNode, pTable, OP_TableScan); +} + + static SPhyNode* createTableScanNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode) { SQueryTableInfo* pTable = (SQueryTableInfo*)pPlanNode->pExtInfo; + if (needMultiNodeScan(pTable)) { return createExchangeNode(pCxt, pPlanNode, splitSubplanByTable(pCxt, pPlanNode, pTable)); } - return createSingleTableScanNode(pPlanNode, pTable); + return createSingleTableScanNode(pPlanNode, pTable, pCxt->pCurrentSubplan); } static SPhyNode* createPhyNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode) { @@ -275,6 +303,8 @@ static SPhyNode* createPhyNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode) { case QNODE_TABLESCAN: node = createTableScanNode(pCxt, pPlanNode); break; + case QNODE_PROJECT: +// node = create case QNODE_MODIFY: // Insert is not an operator in a physical plan. break; @@ -305,10 +335,10 @@ static void splitModificationOpSubPlan(SPlanContext* pCxt, SQueryPlanNode* pPlan SVgDataBlocks* blocks = (SVgDataBlocks*)taosArrayGetP(pPayload->payload, i); vgroupInfoToEpSet(&blocks->vg, &subplan->execNode); - subplan->pDataSink = createDataInserter(pCxt, blocks); - subplan->pNode = NULL; - subplan->type = QUERY_TYPE_MODIFY; - subplan->msgType = pPayload->msgType; + subplan->pDataSink = createDataInserter(pCxt, blocks, NULL); + subplan->pNode = NULL; + subplan->type = QUERY_TYPE_MODIFY; + subplan->msgType = pPayload->msgType; subplan->id.queryId = pCxt->pDag->queryId; RECOVERY_CURRENT_SUBPLAN(pCxt); @@ -319,12 +349,12 @@ static void createSubplanByLevel(SPlanContext* pCxt, SQueryPlanNode* pRoot) { if (QNODE_MODIFY == pRoot->info.type) { splitModificationOpSubPlan(pCxt, pRoot); } else { - SSubplan* subplan = initSubplan(pCxt, QUERY_TYPE_MERGE); + SSubplan* subplan = initSubplan(pCxt, QUERY_TYPE_SCAN); ++(pCxt->nextId.templateId); subplan->msgType = TDMT_VND_QUERY; subplan->pNode = createPhyNode(pCxt, pRoot); - subplan->pDataSink = createDataDispatcher(pCxt, pRoot); + subplan->pDataSink = createDataDispatcher(pCxt, pRoot, subplan->pNode); } // todo deal subquery } @@ -335,7 +365,7 @@ int32_t createDag(SQueryPlanNode* pQueryNode, struct SCatalog* pCatalog, SQueryD .pCatalog = pCatalog, .pDag = validPointer(calloc(1, sizeof(SQueryDag))), .pCurrentSubplan = NULL, - .nextId = {0} // todo queryid + .nextId = {.queryId = requestId}, }; *pDag = context.pDag; @@ -351,6 +381,24 @@ int32_t createDag(SQueryPlanNode* pQueryNode, struct SCatalog* pCatalog, SQueryD return TSDB_CODE_SUCCESS; } -int32_t setSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep) { - //todo +void setExchangSourceNode(uint64_t templateId, SQueryNodeAddr* pEp, SPhyNode* pNode) { + if (NULL == pNode) { + return; + } + if (OP_Exchange == pNode->info.type) { + SExchangePhyNode* pExchange = (SExchangePhyNode*)pNode; + if (templateId == pExchange->srcTemplateId) { + taosArrayPush(pExchange->pSrcEndPoints, pEp); + } + } + if (pNode->pChildren != NULL) { + size_t size = taosArrayGetSize(pNode->pChildren); + for(int32_t i = 0; i < size; ++i) { + setExchangSourceNode(templateId, pEp, taosArrayGetP(pNode->pChildren, i)); + } + } +} + +void setSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* pEp) { + setExchangSourceNode(templateId, pEp, subplan->pNode); } diff --git a/source/libs/planner/src/physicalPlanJson.c b/source/libs/planner/src/physicalPlanJson.c index b25d9a3627..d8918d27de 100644 --- a/source/libs/planner/src/physicalPlanJson.c +++ b/source/libs/planner/src/physicalPlanJson.c @@ -62,7 +62,7 @@ static bool fromObjectWithAlloc(const cJSON* json, const char* name, FFromJson f return func(jObj, *obj); } -static bool addArray(cJSON* json, const char* name, FToJson func, const SArray* array) { +static bool addTarray(cJSON* json, const char* name, FToJson func, const SArray* array, bool isPoint) { size_t size = (NULL == array) ? 0 : taosArrayGetSize(array); if (size > 0) { cJSON* jArray = cJSON_AddArrayToObject(json, name); @@ -70,7 +70,7 @@ static bool addArray(cJSON* json, const char* name, FToJson func, const SArray* return false; } for (size_t i = 0; i < size; ++i) { - if (!addItem(jArray, func, taosArrayGetP(array, i))) { + if (!addItem(jArray, func, isPoint ? taosArrayGetP(array, i) : taosArrayGet(array, i))) { return false; } } @@ -78,11 +78,19 @@ static bool addArray(cJSON* json, const char* name, FToJson func, const SArray* return true; } -static bool fromArray(const cJSON* json, const char* name, FFromJson func, SArray** array, int32_t itemSize) { +static bool addInlineArray(cJSON* json, const char* name, FToJson func, const SArray* array) { + return addTarray(json, name, func, array, false); +} + +static bool addArray(cJSON* json, const char* name, FToJson func, const SArray* array) { + return addTarray(json, name, func, array, true); +} + +static bool fromTarray(const cJSON* json, const char* name, FFromJson func, SArray** array, int32_t itemSize, bool isPoint) { const cJSON* jArray = cJSON_GetObjectItem(json, name); int32_t size = (NULL == jArray ? 0 : cJSON_GetArraySize(jArray)); if (size > 0) { - *array = taosArrayInit(size, POINTER_BYTES); + *array = taosArrayInit(size, isPoint ? POINTER_BYTES : itemSize); if (NULL == *array) { return false; } @@ -92,11 +100,19 @@ static bool fromArray(const cJSON* json, const char* name, FFromJson func, SArra if (NULL == item || !func(cJSON_GetArrayItem(jArray, i), item)) { return false; } - taosArrayPush(*array, &item); + taosArrayPush(*array, isPoint ? &item : item); } return true; } +static bool fromInlineArray(const cJSON* json, const char* name, FFromJson func, SArray** array, int32_t itemSize) { + return fromTarray(json, name, func, array, itemSize, false); +} + +static bool fromArray(const cJSON* json, const char* name, FFromJson func, SArray** array, int32_t itemSize) { + return fromTarray(json, name, func, array, itemSize, true); +} + static bool addRawArray(cJSON* json, const char* name, FToJson func, const void* array, int32_t itemSize, int32_t size) { if (size > 0) { cJSON* jArray = cJSON_AddArrayToObject(json, name); @@ -182,6 +198,29 @@ static bool schemaFromJson(const cJSON* json, void* obj) { return true; } +static const char* jkDataBlockSchemaSlotSchema = "SlotSchema"; +static const char* jkDataBlockSchemaResultRowSize = "resultRowSize"; +static const char* jkDataBlockSchemaPrecision = "Precision"; + +static bool dataBlockSchemaToJson(const void* obj, cJSON* json) { + const SDataBlockSchema* schema = (const SDataBlockSchema*)obj; + bool res = addRawArray(json, jkDataBlockSchemaSlotSchema, schemaToJson, schema->pSchema, sizeof(SSlotSchema), schema->numOfCols); + if (res) { + res = cJSON_AddNumberToObject(json, jkDataBlockSchemaResultRowSize, schema->resultRowSize); + } + if (res) { + res = cJSON_AddNumberToObject(json, jkDataBlockSchemaPrecision, schema->precision); + } + return res; +} + +static bool dataBlockSchemaFromJson(const cJSON* json, void* obj) { + SDataBlockSchema* schema = (SDataBlockSchema*)obj; + schema->resultRowSize = getNumber(json, jkDataBlockSchemaResultRowSize); + schema->precision = getNumber(json, jkDataBlockSchemaPrecision); + return fromRawArray(json, jkDataBlockSchemaSlotSchema, schemaFromJson, schema->pSchema, sizeof(SSlotSchema), &schema->numOfCols); +} + static const char* jkColumnFilterInfoLowerRelOptr = "LowerRelOptr"; static const char* jkColumnFilterInfoUpperRelOptr = "UpperRelOptr"; static const char* jkColumnFilterInfoFilterstr = "Filterstr"; @@ -230,9 +269,11 @@ static bool columnInfoToJson(const void* obj, cJSON* jCol) { if (res) { res = cJSON_AddNumberToObject(jCol, jkColumnInfoBytes, col->bytes); } - if (res) { - res = addRawArray(jCol, jkColumnInfoFilterList, columnFilterInfoToJson, col->flist.filterInfo, sizeof(SColumnFilterInfo), col->flist.numOfFilters); + + if (res) { // TODO: temporarily disable it +// res = addRawArray(jCol, jkColumnInfoFilterList, columnFilterInfoToJson, col->flist.filterInfo, sizeof(SColumnFilterInfo), col->flist.numOfFilters); } + return res; } @@ -396,7 +437,7 @@ static bool exprNodeFromJson(const cJSON* json, void* obj) { case TEXPR_FUNCTION_NODE: return fromObject(json, jkExprNodeFunction, functionFromJson, exprInfo, false); case TEXPR_COL_NODE: - return fromObject(json, jkExprNodeColumn, schemaFromJson, exprInfo->pSchema, false); + return fromObjectWithAlloc(json, jkExprNodeColumn, schemaFromJson, (void**)&exprInfo->pSchema, sizeof(SSchema), false); case TEXPR_VALUE_NODE: return fromObject(json, jkExprNodeValue, variantFromJson, exprInfo->pVal, false); default: @@ -539,7 +580,7 @@ static const char* jkEpAddrFqdn = "Fqdn"; static const char* jkEpAddrPort = "Port"; static bool epAddrToJson(const void* obj, cJSON* json) { - const SEpAddrMsg* ep = (const SEpAddrMsg*)obj; + const SEpAddr* ep = (const SEpAddr*)obj; bool res = cJSON_AddStringToObject(json, jkEpAddrFqdn, ep->fqdn); if (res) { res = cJSON_AddNumberToObject(json, jkEpAddrPort, ep->port); @@ -548,12 +589,38 @@ static bool epAddrToJson(const void* obj, cJSON* json) { } static bool epAddrFromJson(const cJSON* json, void* obj) { - SEpAddrMsg* ep = (SEpAddrMsg*)obj; + SEpAddr* ep = (SEpAddr*)obj; copyString(json, jkEpAddrFqdn, ep->fqdn); ep->port = getNumber(json, jkEpAddrPort); return true; } +static const char* jkNodeAddrId = "NodeId"; +static const char* jkNodeAddrInUse = "InUse"; +static const char* jkNodeAddrEpAddrs = "EpAddrs"; + +static bool nodeAddrToJson(const void* obj, cJSON* json) { + const SQueryNodeAddr* ep = (const SQueryNodeAddr*)obj; + bool res = cJSON_AddNumberToObject(json, jkNodeAddrId, ep->nodeId); + if (res) { + res = cJSON_AddNumberToObject(json, jkNodeAddrInUse, ep->inUse); + } + if (res) { + res = addRawArray(json, jkNodeAddrEpAddrs, epAddrToJson, ep->epAddr, ep->numOfEps, sizeof(SEpAddr)); + } + return res; +} + +static bool nodeAddrFromJson(const cJSON* json, void* obj) { + SQueryNodeAddr* ep = (SQueryNodeAddr*)obj; + ep->nodeId = getNumber(json, jkNodeAddrId); + ep->inUse = getNumber(json, jkNodeAddrInUse); + int32_t numOfEps = 0; + bool res = fromRawArray(json, jkNodeAddrEpAddrs, nodeAddrFromJson, &ep->epAddr, sizeof(SEpAddr), &numOfEps); + ep->numOfEps = numOfEps; + return res; +} + static const char* jkExchangeNodeSrcTemplateId = "SrcTemplateId"; static const char* jkExchangeNodeSrcEndPoints = "SrcEndPoints"; @@ -561,7 +628,7 @@ static bool exchangeNodeToJson(const void* obj, cJSON* json) { const SExchangePhyNode* exchange = (const SExchangePhyNode*)obj; bool res = cJSON_AddNumberToObject(json, jkExchangeNodeSrcTemplateId, exchange->srcTemplateId); if (res) { - res = addArray(json, jkExchangeNodeSrcEndPoints, epAddrToJson, exchange->pSrcEndPoints); + res = addInlineArray(json, jkExchangeNodeSrcEndPoints, nodeAddrToJson, exchange->pSrcEndPoints); } return res; } @@ -569,7 +636,7 @@ static bool exchangeNodeToJson(const void* obj, cJSON* json) { static bool exchangeNodeFromJson(const cJSON* json, void* obj) { SExchangePhyNode* exchange = (SExchangePhyNode*)obj; exchange->srcTemplateId = getNumber(json, jkExchangeNodeSrcTemplateId); - return fromArray(json, jkExchangeNodeSrcEndPoints, epAddrFromJson, &exchange->pSrcEndPoints, sizeof(SEpAddrMsg)); + return fromInlineArray(json, jkExchangeNodeSrcEndPoints, nodeAddrFromJson, &exchange->pSrcEndPoints, sizeof(SQueryNodeAddr)); } static bool specificPhyNodeToJson(const void* obj, cJSON* json) { @@ -664,7 +731,7 @@ static bool phyNodeToJson(const void* obj, cJSON* jNode) { res = addArray(jNode, jkPnodeConditions, exprInfoToJson, phyNode->pConditions); } if (res) { - res = addRawArray(jNode, jkPnodeSchema, schemaToJson, phyNode->targetSchema.pSchema, sizeof(SSlotSchema), phyNode->targetSchema.numOfCols); + res = addObject(jNode, jkPnodeSchema, dataBlockSchemaToJson, &phyNode->targetSchema); } if (res) { res = addArray(jNode, jkPnodeChildren, phyNodeToJson, phyNode->pChildren); @@ -684,7 +751,7 @@ static bool phyNodeFromJson(const cJSON* json, void* obj) { res = fromArray(json, jkPnodeConditions, exprInfoFromJson, &node->pConditions, sizeof(SExprInfo)); } if (res) { - res = fromRawArray(json, jkPnodeSchema, schemaFromJson, node->targetSchema.pSchema, sizeof(SSlotSchema), &node->targetSchema.numOfCols); + res = fromObject(json, jkPnodeSchema, dataBlockSchemaFromJson, &node->targetSchema, true); } if (res) { res = fromArray(json, jkPnodeChildren, phyNodeFromJson, &node->pChildren, sizeof(SSlotSchema)); @@ -742,6 +809,7 @@ static bool specificDataSinkFromJson(const cJSON* json, void* obj) { } static const char* jkDataSinkName = "Name"; +static const char* jkDataSinkSchema = "Schema"; static bool dataSinkToJson(const void* obj, cJSON* json) { const SDataSink* dsink = (const SDataSink*)obj; @@ -749,6 +817,9 @@ static bool dataSinkToJson(const void* obj, cJSON* json) { if (res) { res = addObject(json, dsink->info.name, specificDataSinkToJson, dsink); } + if (res) { + res = addObject(json, jkDataSinkSchema, dataBlockSchemaToJson, &dsink->schema); + } return res; } @@ -756,7 +827,11 @@ static bool dataSinkFromJson(const cJSON* json, void* obj) { SDataSink* dsink = (SDataSink*)obj; dsink->info.name = getString(json, jkDataSinkName); dsink->info.type = dsinkNameToDsinkType(dsink->info.name); - return fromObject(json, dsink->info.name, specificDataSinkFromJson, dsink, true); + bool res = fromObject(json, jkDataSinkSchema, dataBlockSchemaFromJson, &dsink->schema, true); + if (res) { + res = fromObject(json, dsink->info.name, specificDataSinkFromJson, dsink, true); + } + return res; } static const char* jkIdQueryId = "QueryId"; @@ -794,7 +869,6 @@ static cJSON* subplanToJson(const SSubplan* subplan) { } // The 'type', 'level', 'execEpSet', 'pChildren' and 'pParents' fields do not need to be serialized. - bool res = addObject(jSubplan, jkSubplanId, subplanIdToJson, &subplan->id); if (res) { res = addObject(jSubplan, jkSubplanNode, phyNodeToJson, subplan->pNode); @@ -802,11 +876,11 @@ static cJSON* subplanToJson(const SSubplan* subplan) { if (res) { res = addObject(jSubplan, jkSubplanDataSink, dataSinkToJson, subplan->pDataSink); } - if (!res) { cJSON_Delete(jSubplan); return NULL; } + return jSubplan; } diff --git a/source/libs/planner/src/planner.c b/source/libs/planner/src/planner.c index e50f4d02b9..f80a631413 100644 --- a/source/libs/planner/src/planner.c +++ b/source/libs/planner/src/planner.c @@ -16,12 +16,44 @@ #include "parser.h" #include "plannerInt.h" +static void destroyDataSinkNode(SDataSink* pSinkNode) { + if (pSinkNode == NULL) { + return; + } + tfree(pSinkNode); +} + void qDestroySubplan(SSubplan* pSubplan) { - // todo + if (pSubplan == NULL) { + return; + } + + taosArrayDestroy(pSubplan->pChildren); + taosArrayDestroy(pSubplan->pParents); + destroyDataSinkNode(pSubplan->pDataSink); + // todo destroy pNode + tfree(pSubplan); } void qDestroyQueryDag(struct SQueryDag* pDag) { - // todo + if (pDag == NULL) { + return; + } + + size_t size = taosArrayGetSize(pDag->pSubplans); + for(size_t i = 0; i < size; ++i) { + SArray* pa = taosArrayGetP(pDag->pSubplans, i); + + size_t t = taosArrayGetSize(pa); + for(int32_t j = 0; j < t; ++j) { + SSubplan* pSubplan = taosArrayGetP(pa, j); + qDestroySubplan(pSubplan); + } + taosArrayDestroy(pa); + } + + taosArrayDestroy(pDag->pSubplans); + tfree(pDag); } int32_t qCreateQueryDag(const struct SQueryNode* pNode, struct SQueryDag** pDag, uint64_t requestId) { @@ -32,6 +64,13 @@ int32_t qCreateQueryDag(const struct SQueryNode* pNode, struct SQueryDag** pDag, return code; } + // + if (logicPlan->info.type != QNODE_MODIFY) { +// char* str = NULL; +// queryPlanToString(logicPlan, &str); +// printf("%s\n", str); + } + code = optimizeQueryPlan(logicPlan); if (TSDB_CODE_SUCCESS != code) { destroyQueryPlan(logicPlan); @@ -49,8 +88,8 @@ int32_t qCreateQueryDag(const struct SQueryNode* pNode, struct SQueryDag** pDag, return TSDB_CODE_SUCCESS; } -int32_t qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep) { - return setSubplanExecutionNode(subplan, templateId, ep); +void qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep) { + setSubplanExecutionNode(subplan, templateId, ep); } int32_t qSubPlanToString(const SSubplan *subplan, char** str, int32_t* len) { diff --git a/source/libs/planner/test/phyPlanTests.cpp b/source/libs/planner/test/phyPlanTests.cpp index b6f9612653..3f6f5ab77b 100644 --- a/source/libs/planner/test/phyPlanTests.cpp +++ b/source/libs/planner/test/phyPlanTests.cpp @@ -33,7 +33,7 @@ protected: void pushScan(const string& db, const string& table, int32_t scanOp) { shared_ptr meta = mockCatalogService->getTableMeta(db, table); EXPECT_TRUE(meta); - unique_ptr scan((SQueryPlanNode*)calloc(1, sizeof(SQueryPlanNode))); + unique_ptr scan((SQueryPlanNode*)myCalloc(1, sizeof(SQueryPlanNode))); scan->info.type = scanOp; scan->numOfCols = meta->schema->tableInfo.numOfColumns; scan->pSchema = (SSchema*)myCalloc(1, sizeof(SSchema) * scan->numOfCols); diff --git a/source/libs/qcom/src/querymsg.c b/source/libs/qcom/src/querymsg.c index 507650159f..2cde28baf9 100644 --- a/source/libs/qcom/src/querymsg.c +++ b/source/libs/qcom/src/querymsg.c @@ -29,7 +29,7 @@ int32_t queryBuildTableMetaReqMsg(void* input, char **msg, int32_t msgSize, int3 SBuildTableMetaInput* bInput = (SBuildTableMetaInput *)input; - int32_t estimateSize = sizeof(STableInfoMsg); + int32_t estimateSize = sizeof(STableInfoReq); if (NULL == *msg || msgSize < estimateSize) { tfree(*msg); *msg = rpcMallocCont(estimateSize); @@ -38,7 +38,7 @@ int32_t queryBuildTableMetaReqMsg(void* input, char **msg, int32_t msgSize, int3 } } - STableInfoMsg *bMsg = (STableInfoMsg *)*msg; + STableInfoReq *bMsg = (STableInfoReq *)*msg; bMsg->header.vgId = htonl(bInput->vgId); @@ -59,7 +59,7 @@ int32_t queryBuildUseDbMsg(void* input, char **msg, int32_t msgSize, int32_t *ms SBuildUseDBInput* bInput = (SBuildUseDBInput *)input; - int32_t estimateSize = sizeof(SUseDbMsg); + int32_t estimateSize = sizeof(SUseDbReq); if (NULL == *msg || msgSize < estimateSize) { tfree(*msg); *msg = rpcMallocCont(estimateSize); @@ -68,7 +68,7 @@ int32_t queryBuildUseDbMsg(void* input, char **msg, int32_t msgSize, int32_t *ms } } - SUseDbMsg *bMsg = (SUseDbMsg *)*msg; + SUseDbReq *bMsg = (SUseDbReq *)*msg; strncpy(bMsg->db, bInput->db, sizeof(bMsg->db)); bMsg->db[sizeof(bMsg->db) - 1] = 0; @@ -97,6 +97,7 @@ int32_t queryProcessUseDBRsp(void* output, char *msg, int32_t msgSize) { pRsp->vgVersion = ntohl(pRsp->vgVersion); pRsp->vgNum = ntohl(pRsp->vgNum); + pRsp->uid = be64toh(pRsp->uid); if (pRsp->vgNum < 0) { qError("invalid db[%s] vgroup number[%d]", pRsp->db, pRsp->vgNum); @@ -111,6 +112,7 @@ int32_t queryProcessUseDBRsp(void* output, char *msg, int32_t msgSize) { pOut->dbVgroup.vgVersion = pRsp->vgVersion; pOut->dbVgroup.hashMethod = pRsp->hashMethod; + pOut->dbVgroup.dbId = pRsp->uid; pOut->dbVgroup.vgInfo = taosHashInit(pRsp->vgNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); if (NULL == pOut->dbVgroup.vgInfo) { qError("hash init[%d] failed", pRsp->vgNum); @@ -144,13 +146,13 @@ _return: return code; } -static int32_t queryConvertTableMetaMsg(STableMetaMsg* pMetaMsg) { +static int32_t queryConvertTableMetaMsg(STableMetaRsp* pMetaMsg) { pMetaMsg->numOfTags = ntohl(pMetaMsg->numOfTags); pMetaMsg->numOfColumns = ntohl(pMetaMsg->numOfColumns); pMetaMsg->sversion = ntohl(pMetaMsg->sversion); pMetaMsg->tversion = ntohl(pMetaMsg->tversion); - pMetaMsg->tuid = htobe64(pMetaMsg->tuid); - pMetaMsg->suid = htobe64(pMetaMsg->suid); + pMetaMsg->tuid = be64toh(pMetaMsg->tuid); + pMetaMsg->suid = be64toh(pMetaMsg->suid); pMetaMsg->vgId = ntohl(pMetaMsg->vgId); if (pMetaMsg->numOfTags < 0 || pMetaMsg->numOfTags > TSDB_MAX_TAGS) { @@ -196,7 +198,7 @@ static int32_t queryConvertTableMetaMsg(STableMetaMsg* pMetaMsg) { return TSDB_CODE_SUCCESS; } -int32_t queryCreateTableMetaFromMsg(STableMetaMsg* msg, bool isSuperTable, STableMeta **pMeta) { +int32_t queryCreateTableMetaFromMsg(STableMetaRsp* msg, bool isSuperTable, STableMeta **pMeta) { int32_t total = msg->numOfColumns + msg->numOfTags; int32_t metaSize = sizeof(STableMeta) + sizeof(SSchema) * total; @@ -208,7 +210,7 @@ int32_t queryCreateTableMetaFromMsg(STableMetaMsg* msg, bool isSuperTable, STabl pTableMeta->vgId = isSuperTable ? 0 : msg->vgId; pTableMeta->tableType = isSuperTable ? TSDB_SUPER_TABLE : msg->tableType; - pTableMeta->uid = msg->tuid; + pTableMeta->uid = isSuperTable ? msg->suid : msg->tuid; pTableMeta->suid = msg->suid; pTableMeta->sversion = msg->sversion; pTableMeta->tversion = msg->tversion; @@ -230,7 +232,7 @@ int32_t queryCreateTableMetaFromMsg(STableMetaMsg* msg, bool isSuperTable, STabl int32_t queryProcessTableMetaRsp(void* output, char *msg, int32_t msgSize) { - STableMetaMsg *pMetaMsg = (STableMetaMsg *)msg; + STableMetaRsp *pMetaMsg = (STableMetaRsp *)msg; int32_t code = queryConvertTableMetaMsg(pMetaMsg); if (code != TSDB_CODE_SUCCESS) { return code; @@ -244,7 +246,7 @@ int32_t queryProcessTableMetaRsp(void* output, char *msg, int32_t msgSize) { } if (pMetaMsg->tableType == TSDB_CHILD_TABLE) { - pOut->metaNum = 2; + SET_META_TYPE_BOTH_TABLE(pOut->metaType); if (pMetaMsg->dbFname[0]) { snprintf(pOut->ctbFname, sizeof(pOut->ctbFname), "%s.%s", pMetaMsg->dbFname, pMetaMsg->tbFname); @@ -261,7 +263,7 @@ int32_t queryProcessTableMetaRsp(void* output, char *msg, int32_t msgSize) { code = queryCreateTableMetaFromMsg(pMetaMsg, true, &pOut->tbMeta); } else { - pOut->metaNum = 1; + SET_META_TYPE_TABLE(pOut->metaType); if (pMetaMsg->dbFname[0]) { snprintf(pOut->tbFname, sizeof(pOut->tbFname), "%s.%s", pMetaMsg->dbFname, pMetaMsg->tbFname); diff --git a/source/libs/qcom/test/CMakeLists.txt b/source/libs/qcom/test/CMakeLists.txt index 7adec3752a..e3a0e11a32 100644 --- a/source/libs/qcom/test/CMakeLists.txt +++ b/source/libs/qcom/test/CMakeLists.txt @@ -15,5 +15,5 @@ TARGET_INCLUDE_DIRECTORIES( TARGET_LINK_LIBRARIES( queryUtilTest - PUBLIC os util gtest qcom common + PUBLIC os util gtest qcom common transport ) diff --git a/source/libs/qcom/test/queryTest.cpp b/source/libs/qcom/test/queryTest.cpp index ddf89c6272..8fc6b7e529 100644 --- a/source/libs/qcom/test/queryTest.cpp +++ b/source/libs/qcom/test/queryTest.cpp @@ -17,6 +17,7 @@ #include #include "tmsg.h" #include "query.h" +#include "trpc.h" #pragma GCC diagnostic ignored "-Wwrite-strings" #pragma GCC diagnostic ignored "-Wunused-function" @@ -80,4 +81,4 @@ TEST(testCase, error_in_async_test) { taosAsyncExec(testPrintError, p, &code); usleep(1000); printf("Error code:%d after asynchronously exec function\n", code); -} \ No newline at end of file +} diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index 808c1e19f9..15e894fd61 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -1080,7 +1080,7 @@ int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg){ return TSDB_CODE_QRY_INVALID_INPUT; } - SResReadyMsg *msg = pMsg->pCont; + SResReadyReq *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen < sizeof(*msg)) { qError("invalid task status msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); @@ -1101,7 +1101,7 @@ int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { } int32_t code = 0; - SSchTasksStatusMsg *msg = pMsg->pCont; + SSchTasksStatusReq *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen < sizeof(*msg)) { qError("invalid task status msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); @@ -1125,7 +1125,7 @@ int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { return TSDB_CODE_QRY_INVALID_INPUT; } - SResFetchMsg *msg = pMsg->pCont; + SResFetchReq *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen < sizeof(*msg)) { QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } @@ -1157,7 +1157,7 @@ int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { } int32_t code = 0; - STaskCancelMsg *msg = pMsg->pCont; + STaskCancelReq *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen < sizeof(*msg)) { qError("invalid task cancel msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); @@ -1182,7 +1182,7 @@ int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { } int32_t code = 0; - STaskDropMsg *msg = pMsg->pCont; + STaskDropReq *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen < sizeof(*msg)) { qError("invalid task drop msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); diff --git a/source/libs/qworker/test/qworkerTests.cpp b/source/libs/qworker/test/qworkerTests.cpp index 7bc1c4ff40..eaa79fd39a 100644 --- a/source/libs/qworker/test/qworkerTests.cpp +++ b/source/libs/qworker/test/qworkerTests.cpp @@ -113,12 +113,12 @@ void *readyThread(void *param) { uint32_t n = 0; void *mockPointer = (void *)0x1; void *mgmt = param; - SResReadyMsg readyMsg = {0}; + SResReadyReq readyMsg = {0}; readyMsg.sId = htobe64(1); readyMsg.queryId = htobe64(1); readyMsg.taskId = htobe64(1); readyRpc.pCont = &readyMsg; - readyRpc.contLen = sizeof(SResReadyMsg); + readyRpc.contLen = sizeof(SResReadyReq); while (!testStop) { code = qWorkerProcessReadyMsg(mockPointer, mgmt, &readyRpc); @@ -137,12 +137,12 @@ void *fetchThread(void *param) { uint32_t n = 0; void *mockPointer = (void *)0x1; void *mgmt = param; - SResFetchMsg fetchMsg = {0}; + SResFetchReq fetchMsg = {0}; fetchMsg.sId = htobe64(1); fetchMsg.queryId = htobe64(1); fetchMsg.taskId = htobe64(1); fetchRpc.pCont = &fetchMsg; - fetchRpc.contLen = sizeof(SResFetchMsg); + fetchRpc.contLen = sizeof(SResFetchReq); while (!testStop) { code = qWorkerProcessFetchMsg(mockPointer, mgmt, &fetchRpc); @@ -161,12 +161,12 @@ void *dropThread(void *param) { uint32_t n = 0; void *mockPointer = (void *)0x1; void *mgmt = param; - STaskDropMsg dropMsg = {0}; + STaskDropReq dropMsg = {0}; dropMsg.sId = htobe64(1); dropMsg.queryId = htobe64(1); dropMsg.taskId = htobe64(1); dropRpc.pCont = &dropMsg; - dropRpc.contLen = sizeof(STaskDropMsg); + dropRpc.contLen = sizeof(STaskDropReq); while (!testStop) { code = qWorkerProcessDropMsg(mockPointer, mgmt, &dropRpc); @@ -185,10 +185,10 @@ void *statusThread(void *param) { uint32_t n = 0; void *mockPointer = (void *)0x1; void *mgmt = param; - SSchTasksStatusMsg statusMsg = {0}; + SSchTasksStatusReq statusMsg = {0}; statusMsg.sId = htobe64(1); statusRpc.pCont = &statusMsg; - statusRpc.contLen = sizeof(SSchTasksStatusMsg); + statusRpc.contLen = sizeof(SSchTasksStatusReq); statusRpc.msgType = TDMT_VND_TASKS_STATUS; while (!testStop) { @@ -228,31 +228,31 @@ TEST(seqTest, normalCase) { queryRpc.pCont = queryMsg; queryRpc.contLen = sizeof(SSubQueryMsg) + 100; - SResReadyMsg readyMsg = {0}; + SResReadyReq readyMsg = {0}; readyMsg.sId = htobe64(1); readyMsg.queryId = htobe64(1); readyMsg.taskId = htobe64(1); readyRpc.pCont = &readyMsg; - readyRpc.contLen = sizeof(SResReadyMsg); + readyRpc.contLen = sizeof(SResReadyReq); - SResFetchMsg fetchMsg = {0}; + SResFetchReq fetchMsg = {0}; fetchMsg.sId = htobe64(1); fetchMsg.queryId = htobe64(1); fetchMsg.taskId = htobe64(1); fetchRpc.pCont = &fetchMsg; - fetchRpc.contLen = sizeof(SResFetchMsg); + fetchRpc.contLen = sizeof(SResFetchReq); - STaskDropMsg dropMsg = {0}; + STaskDropReq dropMsg = {0}; dropMsg.sId = htobe64(1); dropMsg.queryId = htobe64(1); dropMsg.taskId = htobe64(1); dropRpc.pCont = &dropMsg; - dropRpc.contLen = sizeof(STaskDropMsg); + dropRpc.contLen = sizeof(STaskDropReq); - SSchTasksStatusMsg statusMsg = {0}; + SSchTasksStatusReq statusMsg = {0}; statusMsg.sId = htobe64(1); statusRpc.pCont = &statusMsg; - statusRpc.contLen = sizeof(SSchTasksStatusMsg); + statusRpc.contLen = sizeof(SSchTasksStatusReq); statusRpc.msgType = TDMT_VND_TASKS_STATUS; stubSetStringToPlan(); @@ -312,17 +312,17 @@ TEST(seqTest, cancelFirst) { queryRpc.pCont = queryMsg; queryRpc.contLen = sizeof(SSubQueryMsg) + 100; - STaskDropMsg dropMsg = {0}; + STaskDropReq dropMsg = {0}; dropMsg.sId = htobe64(1); dropMsg.queryId = htobe64(1); dropMsg.taskId = htobe64(1); dropRpc.pCont = &dropMsg; - dropRpc.contLen = sizeof(STaskDropMsg); + dropRpc.contLen = sizeof(STaskDropReq); - SSchTasksStatusMsg statusMsg = {0}; + SSchTasksStatusReq statusMsg = {0}; statusMsg.sId = htobe64(1); statusRpc.pCont = &statusMsg; - statusRpc.contLen = sizeof(SSchTasksStatusMsg); + statusRpc.contLen = sizeof(SSchTasksStatusReq); statusRpc.msgType = TDMT_VND_TASKS_STATUS; stubSetStringToPlan(); @@ -370,31 +370,31 @@ TEST(seqTest, randCase) { queryRpc.pCont = queryMsg; queryRpc.contLen = sizeof(SSubQueryMsg) + 100; - SResReadyMsg readyMsg = {0}; + SResReadyReq readyMsg = {0}; readyMsg.sId = htobe64(1); readyMsg.queryId = htobe64(1); readyMsg.taskId = htobe64(1); readyRpc.pCont = &readyMsg; - readyRpc.contLen = sizeof(SResReadyMsg); + readyRpc.contLen = sizeof(SResReadyReq); - SResFetchMsg fetchMsg = {0}; + SResFetchReq fetchMsg = {0}; fetchMsg.sId = htobe64(1); fetchMsg.queryId = htobe64(1); fetchMsg.taskId = htobe64(1); fetchRpc.pCont = &fetchMsg; - fetchRpc.contLen = sizeof(SResFetchMsg); + fetchRpc.contLen = sizeof(SResFetchReq); - STaskDropMsg dropMsg = {0}; + STaskDropReq dropMsg = {0}; dropMsg.sId = htobe64(1); dropMsg.queryId = htobe64(1); dropMsg.taskId = htobe64(1); dropRpc.pCont = &dropMsg; - dropRpc.contLen = sizeof(STaskDropMsg); + dropRpc.contLen = sizeof(STaskDropReq); - SSchTasksStatusMsg statusMsg = {0}; + SSchTasksStatusReq statusMsg = {0}; statusMsg.sId = htobe64(1); statusRpc.pCont = &statusMsg; - statusRpc.contLen = sizeof(SSchTasksStatusMsg); + statusRpc.contLen = sizeof(SSchTasksStatusReq); statusRpc.msgType = TDMT_VND_TASKS_STATUS; stubSetStringToPlan(); diff --git a/source/libs/scheduler/inc/schedulerInt.h b/source/libs/scheduler/inc/schedulerInt.h index fa4ae0d152..d127adbcfa 100644 --- a/source/libs/scheduler/inc/schedulerInt.h +++ b/source/libs/scheduler/inc/schedulerInt.h @@ -37,10 +37,10 @@ enum { }; typedef struct SSchedulerMgmt { - uint64_t taskId; - uint64_t sId; + uint64_t taskId; // sequential taksId + uint64_t sId; // schedulerId SSchedulerCfg cfg; - SHashObj *jobs; // key: queryId, value: SQueryJob* + SHashObj *jobs; // key: queryId, value: SQueryJob* } SSchedulerMgmt; typedef struct SSchCallbackParam { @@ -61,14 +61,17 @@ typedef struct SSchLevel { typedef struct SSchTask { uint64_t taskId; // task id + SRWLatch lock; // task lock SSchLevel *level; // level SSubplan *plan; // subplan char *msg; // operator tree int32_t msgLen; // msg length int8_t status; // task status - SQueryNodeAddr execAddr; // task actual executed node address - int8_t condidateIdx; // current try condidation index - SArray *condidateAddrs; // condidate node addresses, element is SQueryNodeAddr + int32_t lastMsgType; // last sent msg type + SQueryNodeAddr succeedAddr; // task executed success node address + int8_t candidateIdx; // current try condidation index + SArray *candidateAddrs; // condidate node addresses, element is SQueryNodeAddr + SArray *execAddrs; // all tried node for current task, element is SQueryNodeAddr SQueryProfileSummary summary; // task execution summary int32_t childReady; // child task ready number SArray *children; // the datasource tasks,from which to fetch the result, element is SQueryTask* @@ -82,52 +85,65 @@ typedef struct SSchJobAttr { } SSchJobAttr; typedef struct SSchJob { - uint64_t queryId; - int32_t levelNum; - int32_t levelIdx; - int8_t status; - SSchJobAttr attr; - SQueryProfileSummary summary; - SEpSet dataSrcEps; - SEpAddr resEp; + uint64_t queryId; + SSchJobAttr attr; + int32_t levelNum; void *transport; SArray *nodeList; // qnode/vnode list, element is SQueryNodeAddr - tsem_t rspSem; - int32_t userFetch; - int32_t remoteFetch; + SArray *levels; // Element is SQueryLevel, starting from 0. SArray + SArray *subPlans; // subplan pointer copied from DAG, no need to free it in scheduler + int32_t levelIdx; + SEpSet dataSrcEps; + SHashObj *execTasks; // executing tasks, key:taskid, value:SQueryTask* + SHashObj *succTasks; // succeed tasks, key:taskid, value:SQueryTask* + SHashObj *failTasks; // failed tasks, key:taskid, value:SQueryTask* + + int32_t ref; + int8_t status; + SQueryNodeAddr resNode; + tsem_t rspSem; + int8_t userFetch; + int32_t remoteFetch; SSchTask *fetchTask; int32_t errCode; - void *res; + void *res; //TODO free it or not int32_t resNumOfRows; - - SHashObj *execTasks; // executing tasks, key:taskid, value:SQueryTask* - SHashObj *succTasks; // succeed tasks, key:taskid, value:SQueryTask* - SHashObj *failTasks; // failed tasks, key:taskid, value:SQueryTask* - - SArray *levels; // Element is SQueryLevel, starting from 0. - SArray *subPlans; // Element is SArray*, and nested element is SSubplan. The execution level of subplan, starting from 0. + SQueryProfileSummary summary; } SSchJob; -#define SCH_HAS_QNODE_IN_CLUSTER(type) (false) //TODO CLUSTER TYPE -#define SCH_TASK_READY_TO_LUNCH(task) ((task)->childReady >= taosArrayGetSize((task)->children)) // MAY NEED TO ENHANCE +#define SCH_TASK_READY_TO_LUNCH(task) (atomic_load_32(&(task)->childReady) >= taosArrayGetSize((task)->children)) + #define SCH_IS_DATA_SRC_TASK(task) ((task)->plan->type == QUERY_TYPE_SCAN) #define SCH_TASK_NEED_WAIT_ALL(task) ((task)->plan->type == QUERY_TYPE_MODIFY) +#define SCH_TASK_NO_NEED_DROP(task) ((task)->plan->type == QUERY_TYPE_MODIFY) -#define SCH_JOB_ERR_LOG(param, ...) qError("QID:%"PRIx64 param, job->queryId, __VA_ARGS__) -#define SCH_TASK_ERR_LOG(param, ...) qError("QID:%"PRIx64",TID:%"PRIx64 param, job->queryId, task->taskId, __VA_ARGS__) +#define SCH_SET_TASK_STATUS(task, st) atomic_store_8(&(task)->status, st) +#define SCH_GET_TASK_STATUS(task) atomic_load_8(&(task)->status) + +#define SCH_SET_JOB_STATUS(job, st) atomic_store_8(&(job)->status, st) +#define SCH_GET_JOB_STATUS(job) atomic_load_8(&(job)->status) + +#define SCH_SET_JOB_TYPE(pAttr, type) (pAttr)->queryJob = ((type) != QUERY_TYPE_MODIFY) +#define SCH_JOB_NEED_FETCH(pAttr) ((pAttr)->queryJob) + +#define SCH_JOB_ELOG(param, ...) qError("QID:%"PRIx64" " param, pJob->queryId, __VA_ARGS__) +#define SCH_JOB_DLOG(param, ...) qDebug("QID:%"PRIx64" " param, pJob->queryId, __VA_ARGS__) + +#define SCH_TASK_ELOG(param, ...) qError("QID:%"PRIx64",TID:%"PRId64" " param, pJob->queryId, pTask->taskId, __VA_ARGS__) +#define SCH_TASK_DLOG(param, ...) qDebug("QID:%"PRIx64",TID:%"PRId64" " param, pJob->queryId, pTask->taskId, __VA_ARGS__) +#define SCH_TASK_WLOG(param, ...) qWarn("QID:%"PRIx64",TID:%"PRId64" " param, pJob->queryId, pTask->taskId, __VA_ARGS__) #define SCH_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; return _code; } } while (0) #define SCH_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; } return _code; } while (0) -#define SCH_ERR_LRET(c,...) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { qError(__VA_ARGS__); terrno = _code; return _code; } } while (0) #define SCH_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0) #define SCH_LOCK(type, _lock) (SCH_READ == (type) ? taosRLockLatch(_lock) : taosWLockLatch(_lock)) #define SCH_UNLOCK(type, _lock) (SCH_READ == (type) ? taosRUnLockLatch(_lock) : taosWUnLockLatch(_lock)) -extern int32_t schLaunchTask(SSchJob *job, SSchTask *task); -extern int32_t schBuildAndSendMsg(SSchJob *job, SSchTask *task, int32_t msgType); +static int32_t schLaunchTask(SSchJob *job, SSchTask *task); +static int32_t schBuildAndSendMsg(SSchJob *job, SSchTask *task, SQueryNodeAddr *addr, int32_t msgType); #ifdef __cplusplus } diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index 9079912c40..d478e80af0 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -18,196 +18,351 @@ #include "query.h" #include "catalog.h" -SSchedulerMgmt schMgmt = {0}; +static SSchedulerMgmt schMgmt = {0}; -int32_t schBuildTaskRalation(SSchJob *job, SHashObj *planToTask) { - for (int32_t i = 0; i < job->levelNum; ++i) { - SSchLevel *level = taosArrayGet(job->levels, i); - - for (int32_t m = 0; m < level->taskNum; ++m) { - SSchTask *task = taosArrayGet(level->subTasks, m); - SSubplan *plan = task->plan; - int32_t childNum = plan->pChildren ? (int32_t)taosArrayGetSize(plan->pChildren) : 0; - int32_t parentNum = plan->pParents ? (int32_t)taosArrayGetSize(plan->pParents) : 0; - - if (childNum > 0) { - task->children = taosArrayInit(childNum, POINTER_BYTES); - if (NULL == task->children) { - qError("taosArrayInit %d failed", childNum); - SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } - } - - for (int32_t n = 0; n < childNum; ++n) { - SSubplan **child = taosArrayGet(plan->pChildren, n); - SSchTask **childTask = taosHashGet(planToTask, child, POINTER_BYTES); - if (NULL == childTask || NULL == *childTask) { - qError("subplan relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n); - SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); - } - - if (NULL == taosArrayPush(task->children, childTask)) { - qError("taosArrayPush failed"); - SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } - } - - if (parentNum > 0) { - task->parents = taosArrayInit(parentNum, POINTER_BYTES); - if (NULL == task->parents) { - qError("taosArrayInit %d failed", parentNum); - SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } - } - - for (int32_t n = 0; n < parentNum; ++n) { - SSubplan **parent = taosArrayGet(plan->pParents, n); - SSchTask **parentTask = taosHashGet(planToTask, parent, POINTER_BYTES); - if (NULL == parentTask || NULL == *parentTask) { - qError("subplan relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n); - SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); - } - - if (NULL == taosArrayPush(task->parents, parentTask)) { - qError("taosArrayPush failed"); - SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } - } - } +int32_t schInitTask(SSchJob* pJob, SSchTask *pTask, SSubplan* pPlan, SSchLevel *pLevel) { + pTask->plan = pPlan; + pTask->level = pLevel; + SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_NOT_START); + pTask->taskId = atomic_add_fetch_64(&schMgmt.taskId, 1); + pTask->execAddrs = taosArrayInit(SCH_MAX_CONDIDATE_EP_NUM, sizeof(SQueryNodeAddr)); + if (NULL == pTask->execAddrs) { + SCH_TASK_ELOG("taosArrayInit %d exec addrs failed", SCH_MAX_CONDIDATE_EP_NUM); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - SSchLevel *level = taosArrayGet(job->levels, 0); - if (job->attr.queryJob && level->taskNum > 1) { - qError("invalid plan info, level 0, taskNum:%d", level->taskNum); - SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + return TSDB_CODE_SUCCESS; +} + +void schFreeTask(SSchTask* pTask) { + if (pTask->candidateAddrs) { + taosArrayDestroy(pTask->candidateAddrs); } - SSchTask *task = taosArrayGet(level->subTasks, 0); - if (task->parents && taosArrayGetSize(task->parents) > 0) { - qError("invalid plan info, level 0, parentNum:%d", (int32_t)taosArrayGetSize(task->parents)); - SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + // TODO NEED TO VERFY WITH ASYNC_SEND MEMORY FREE + //tfree(pTask->msg); + + if (pTask->children) { + taosArrayDestroy(pTask->children); } + if (pTask->parents) { + taosArrayDestroy(pTask->parents); + } +} + + +int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgType) { + int32_t lastMsgType = atomic_load_32(&pTask->lastMsgType); + + switch (msgType) { + case TDMT_VND_CREATE_TABLE_RSP: + case TDMT_VND_SUBMIT_RSP: + case TDMT_VND_QUERY_RSP: + case TDMT_VND_RES_READY_RSP: + case TDMT_VND_FETCH_RSP: + case TDMT_VND_DROP_TASK: + if (lastMsgType != (msgType - 1)) { + SCH_TASK_ELOG("rsp msg type mis-match, last sent msgType:%d, rspType:%d", lastMsgType, msgType); + SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); + } + + if (SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_EXECUTING) { + SCH_TASK_ELOG("rsp msg conflicted with task status, status:%d, rspType:%d", SCH_GET_TASK_STATUS(pTask), msgType); + SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); + } + + break; + default: + SCH_TASK_ELOG("unknown rsp msg, type:%d, status:%d", msgType, SCH_GET_TASK_STATUS(pTask)); + + SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } return TSDB_CODE_SUCCESS; } -int32_t schValidateAndBuildJob(SQueryDag *dag, SSchJob *job) { +int32_t schCheckAndUpdateJobStatus(SSchJob *pJob, int8_t newStatus) { int32_t code = 0; - job->queryId = dag->queryId; + int8_t oriStatus = SCH_GET_JOB_STATUS(pJob); + +/* + if (oriStatus == newStatus) { + SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } - if (dag->numOfSubplans <= 0) { - qError("invalid subplan num:%d", dag->numOfSubplans); + switch (oriStatus) { + case JOB_TASK_STATUS_NULL: + if (newStatus != JOB_TASK_STATUS_EXECUTING + && newStatus != JOB_TASK_STATUS_FAILED + && newStatus != JOB_TASK_STATUS_NOT_START) { + SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_NOT_START: + if (newStatus != JOB_TASK_STATUS_CANCELLED) { + SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_EXECUTING: + if (newStatus != JOB_TASK_STATUS_PARTIAL_SUCCEED + && newStatus != JOB_TASK_STATUS_FAILED + && newStatus != JOB_TASK_STATUS_CANCELLING + && newStatus != JOB_TASK_STATUS_CANCELLED + && newStatus != JOB_TASK_STATUS_DROPPING) { + SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_PARTIAL_SUCCEED: + if (newStatus != JOB_TASK_STATUS_EXECUTING + && newStatus != JOB_TASK_STATUS_SUCCEED + && newStatus != JOB_TASK_STATUS_CANCELLED) { + SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_SUCCEED: + case JOB_TASK_STATUS_FAILED: + case JOB_TASK_STATUS_CANCELLING: + if (newStatus != JOB_TASK_STATUS_CANCELLED) { + SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_CANCELLED: + case JOB_TASK_STATUS_DROPPING: + SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + break; + + default: + qError("invalid task status:%d", oriStatus); + return TSDB_CODE_QRY_APP_ERROR; + } +*/ + + SCH_SET_JOB_STATUS(pJob, newStatus); + + SCH_JOB_DLOG("status updated from %d to %d", oriStatus, newStatus); + + return TSDB_CODE_SUCCESS; + +_return: + + SCH_JOB_ELOG("invalid job status update, from %d to %d", oriStatus, newStatus); + SCH_ERR_RET(code); +} + + +int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) { + for (int32_t i = 0; i < pJob->levelNum; ++i) { + SSchLevel *pLevel = taosArrayGet(pJob->levels, i); + + for (int32_t m = 0; m < pLevel->taskNum; ++m) { + SSchTask *pTask = taosArrayGet(pLevel->subTasks, m); + SSubplan *pPlan = pTask->plan; + int32_t childNum = pPlan->pChildren ? (int32_t)taosArrayGetSize(pPlan->pChildren) : 0; + int32_t parentNum = pPlan->pParents ? (int32_t)taosArrayGetSize(pPlan->pParents) : 0; + + if (childNum > 0) { + if (pJob->levelIdx == pLevel->level) { + SCH_JOB_ELOG("invalid query plan, lowest level, childNum:%d", childNum); + SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + } + + pTask->children = taosArrayInit(childNum, POINTER_BYTES); + if (NULL == pTask->children) { + SCH_TASK_ELOG("taosArrayInit %d children failed", childNum); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + } + + for (int32_t n = 0; n < childNum; ++n) { + SSubplan **child = taosArrayGet(pPlan->pChildren, n); + SSchTask **childTask = taosHashGet(planToTask, child, POINTER_BYTES); + if (NULL == childTask || NULL == *childTask) { + SCH_TASK_ELOG("subplan children relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n); + SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + } + + if (NULL == taosArrayPush(pTask->children, childTask)) { + SCH_TASK_ELOG("taosArrayPush childTask failed, level:%d, taskIdx:%d, childIdx:%d", i, m, n); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + } + + if (parentNum > 0) { + if (0 == pLevel->level) { + SCH_TASK_ELOG("invalid task info, level:0, parentNum:%d", parentNum); + SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + } + + pTask->parents = taosArrayInit(parentNum, POINTER_BYTES); + if (NULL == pTask->parents) { + SCH_TASK_ELOG("taosArrayInit %d parents failed", parentNum); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + } else { + if (0 != pLevel->level) { + SCH_TASK_ELOG("invalid task info, level:%d, parentNum:%d", pLevel->level, parentNum); + SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + } + } + + for (int32_t n = 0; n < parentNum; ++n) { + SSubplan **parent = taosArrayGet(pPlan->pParents, n); + SSchTask **parentTask = taosHashGet(planToTask, parent, POINTER_BYTES); + if (NULL == parentTask || NULL == *parentTask) { + SCH_TASK_ELOG("subplan parent relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n); + SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + } + + if (NULL == taosArrayPush(pTask->parents, parentTask)) { + SCH_TASK_ELOG("taosArrayPush parentTask failed, level:%d, taskIdx:%d, childIdx:%d", i, m, n); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + } + + SCH_TASK_DLOG("level:%d, parentNum:%d, childNum:%d", i, parentNum, childNum); + } + } + + SSchLevel *pLevel = taosArrayGet(pJob->levels, 0); + if (pJob->attr.queryJob && pLevel->taskNum > 1) { + SCH_JOB_ELOG("invalid query plan, level:0, taskNum:%d", pLevel->taskNum); + SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t schRecordTaskSucceedNode(SSchTask *pTask) { + SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, atomic_load_8(&pTask->candidateIdx)); + + assert(NULL != addr); + + pTask->succeedAddr = *addr; + + return TSDB_CODE_SUCCESS; +} + + +int32_t schRecordTaskExecNode(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr) { + if (NULL == taosArrayPush(pTask->execAddrs, addr)) { + SCH_TASK_ELOG("taosArrayPush addr to execAddr list failed, errno:%d", errno); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t schValidateAndBuildJob(SQueryDag *pDag, SSchJob *pJob) { + int32_t code = 0; + + pJob->queryId = pDag->queryId; + + if (pDag->numOfSubplans <= 0) { + SCH_JOB_ELOG("invalid subplan num:%d", pDag->numOfSubplans); SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - int32_t levelNum = (int32_t)taosArrayGetSize(dag->pSubplans); + int32_t levelNum = (int32_t)taosArrayGetSize(pDag->pSubplans); if (levelNum <= 0) { - qError("invalid level num:%d", levelNum); + SCH_JOB_ELOG("invalid level num:%d", levelNum); SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } SHashObj *planToTask = taosHashInit(SCHEDULE_DEFAULT_TASK_NUMBER, taosGetDefaultHashFunction(POINTER_BYTES == sizeof(int64_t) ? TSDB_DATA_TYPE_BIGINT : TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); if (NULL == planToTask) { - qError("taosHashInit %d failed", SCHEDULE_DEFAULT_TASK_NUMBER); + SCH_JOB_ELOG("taosHashInit %d failed", SCHEDULE_DEFAULT_TASK_NUMBER); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - - job->levels = taosArrayInit(levelNum, sizeof(SSchLevel)); - if (NULL == job->levels) { - qError("taosArrayInit %d failed", levelNum); + + pJob->levels = taosArrayInit(levelNum, sizeof(SSchLevel)); + if (NULL == pJob->levels) { + SCH_JOB_ELOG("taosArrayInit %d failed", levelNum); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - //?? - job->attr.needFetch = true; - - job->levelNum = levelNum; - job->levelIdx = levelNum - 1; + pJob->levelNum = levelNum; + pJob->levelIdx = levelNum - 1; - job->subPlans = dag->pSubplans; + pJob->subPlans = pDag->pSubplans; SSchLevel level = {0}; - SArray *levelPlans = NULL; - int32_t levelPlanNum = 0; + SArray *plans = NULL; + int32_t taskNum = 0; SSchLevel *pLevel = NULL; level.status = JOB_TASK_STATUS_NOT_START; for (int32_t i = 0; i < levelNum; ++i) { - if (NULL == taosArrayPush(job->levels, &level)) { - qError("taosArrayPush failed"); + if (NULL == taosArrayPush(pJob->levels, &level)) { + SCH_JOB_ELOG("taosArrayPush level failed, level:%d", i); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - pLevel = taosArrayGet(job->levels, i); + pLevel = taosArrayGet(pJob->levels, i); pLevel->level = i; - levelPlans = taosArrayGetP(dag->pSubplans, i); - if (NULL == levelPlans) { - qError("no level plans for level %d", i); - SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); - } - - levelPlanNum = (int32_t)taosArrayGetSize(levelPlans); - if (levelPlanNum <= 0) { - qError("invalid level plans number:%d, level:%d", levelPlanNum, i); - SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); - } - - pLevel->taskNum = levelPlanNum; - pLevel->subTasks = taosArrayInit(levelPlanNum, sizeof(SSchTask)); + plans = taosArrayGetP(pDag->pSubplans, i); + if (NULL == plans) { + SCH_JOB_ELOG("empty level plan, level:%d", i); + SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); + } + + taskNum = (int32_t)taosArrayGetSize(plans); + if (taskNum <= 0) { + SCH_JOB_ELOG("invalid level plan number:%d, level:%d", taskNum, i); + SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); + } + + pLevel->taskNum = taskNum; + + pLevel->subTasks = taosArrayInit(taskNum, sizeof(SSchTask)); if (NULL == pLevel->subTasks) { - qError("taosArrayInit %d failed", levelPlanNum); + SCH_JOB_ELOG("taosArrayInit %d failed", taskNum); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - for (int32_t n = 0; n < levelPlanNum; ++n) { - SSubplan *plan = taosArrayGetP(levelPlans, n); - SSchTask task = {0}; + for (int32_t n = 0; n < taskNum; ++n) { + SSubplan *plan = taosArrayGetP(plans, n); - if (plan->type == QUERY_TYPE_MODIFY) { - job->attr.needFetch = false; - } else { - job->attr.queryJob = true; - } + SCH_SET_JOB_TYPE(&pJob->attr, plan->type); + SSchTask task = {0}; + SSchTask *pTask = &task; + + SCH_ERR_JRET(schInitTask(pJob, &task, plan, pLevel)); - task.taskId = atomic_add_fetch_64(&schMgmt.taskId, 1); - task.plan = plan; - task.level = pLevel; - task.status = JOB_TASK_STATUS_NOT_START; - void *p = taosArrayPush(pLevel->subTasks, &task); if (NULL == p) { - qError("taosArrayPush failed"); + SCH_TASK_ELOG("taosArrayPush task to level failed, level:%d, taskIdx:%d", pLevel->level, n); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } if (0 != taosHashPut(planToTask, &plan, POINTER_BYTES, &p, POINTER_BYTES)) { - qError("taosHashPut failed"); + SCH_TASK_ELOG("taosHashPut to planToTaks failed, taskIdx:%d", n); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } + + SCH_TASK_DLOG("task initialized, level:%d", pLevel->level); } + SCH_JOB_DLOG("level initialized, taskNum:%d", taskNum); } - SCH_ERR_JRET(schBuildTaskRalation(job, planToTask)); - - if (planToTask) { - taosHashCleanup(planToTask); - } - - return TSDB_CODE_SUCCESS; + SCH_ERR_JRET(schBuildTaskRalation(pJob, planToTask)); _return: - if (pLevel->subTasks) { - taosArrayDestroy(pLevel->subTasks); - } if (planToTask) { taosHashCleanup(planToTask); @@ -216,39 +371,47 @@ _return: SCH_RET(code); } -int32_t schSetTaskCondidateAddrs(SSchJob *job, SSchTask *task) { - if (task->condidateAddrs) { +int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) { + if (NULL != pTask->candidateAddrs) { return TSDB_CODE_SUCCESS; } - task->condidateIdx = 0; - task->condidateAddrs = taosArrayInit(SCH_MAX_CONDIDATE_EP_NUM, sizeof(SQueryNodeAddr)); - if (NULL == task->condidateAddrs) { - qError("taosArrayInit failed"); + pTask->candidateIdx = 0; + pTask->candidateAddrs = taosArrayInit(SCH_MAX_CONDIDATE_EP_NUM, sizeof(SQueryNodeAddr)); + if (NULL == pTask->candidateAddrs) { + SCH_TASK_ELOG("taosArrayInit %d condidate addrs failed", SCH_MAX_CONDIDATE_EP_NUM); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - if (task->plan->execNode.numOfEps > 0) { - if (NULL == taosArrayPush(task->condidateAddrs, &task->plan->execNode)) { - qError("taosArrayPush failed"); + if (pTask->plan->execNode.numOfEps > 0) { + if (NULL == taosArrayPush(pTask->candidateAddrs, &pTask->plan->execNode)) { + SCH_TASK_ELOG("taosArrayPush execNode to candidate addrs failed, errno:%d", errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } + SCH_TASK_DLOG("use execNode from plan as candidate addr, numOfEps:%d", pTask->plan->execNode.numOfEps); + return TSDB_CODE_SUCCESS; } int32_t addNum = 0; - int32_t nodeNum = taosArrayGetSize(job->nodeList); - - for (int32_t i = 0; i < nodeNum && addNum < SCH_MAX_CONDIDATE_EP_NUM; ++i) { - SQueryNodeAddr *naddr = taosArrayGet(job->nodeList, i); + int32_t nodeNum = 0; + if (pJob->nodeList) { + nodeNum = taosArrayGetSize(pJob->nodeList); - if (NULL == taosArrayPush(task->condidateAddrs, &task->plan->execNode)) { - qError("taosArrayPush failed"); - SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + for (int32_t i = 0; i < nodeNum && addNum < SCH_MAX_CONDIDATE_EP_NUM; ++i) { + SQueryNodeAddr *naddr = taosArrayGet(pJob->nodeList, i); + + if (NULL == taosArrayPush(pTask->candidateAddrs, &pTask->plan->execNode)) { + SCH_TASK_ELOG("taosArrayPush execNode to candidate addrs failed, addNum:%d, errno:%d", addNum, errno); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } } - - ++addNum; + } + + if (addNum <= 0) { + SCH_TASK_ELOG("no available execNode as condidate addr, nodeNum:%d", nodeNum); + return TSDB_CODE_QRY_INVALID_INPUT; } /* @@ -263,43 +426,71 @@ int32_t schSetTaskCondidateAddrs(SSchJob *job, SSchTask *task) { return TSDB_CODE_SUCCESS; } - -int32_t schPushTaskToExecList(SSchJob *job, SSchTask *task) { - if (0 != taosHashPut(job->execTasks, &task->taskId, sizeof(task->taskId), &task, POINTER_BYTES)) { - qError("taosHashPut failed"); +int32_t schPushTaskToExecList(SSchJob *pJob, SSchTask *pTask) { + int32_t code = taosHashPut(pJob->execTasks, &pTask->taskId, sizeof(pTask->taskId), &pTask, POINTER_BYTES); + if (0 != code) { + if (HASH_NODE_EXIST(code)) { + SCH_TASK_ELOG("task already in execTask list, code:%x", code); + SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + } + + SCH_TASK_ELOG("taosHashPut task to execTask list failed, errno:%d", errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } + SCH_TASK_DLOG("task added to execTask list, numOfTasks:%d", taosHashGetSize(pJob->execTasks)); + return TSDB_CODE_SUCCESS; } -int32_t schMoveTaskToSuccList(SSchJob *job, SSchTask *task, bool *moved) { - if (0 != taosHashRemove(job->execTasks, &task->taskId, sizeof(task->taskId))) { - qWarn("remove task[%"PRIx64"] from execTasks failed", task->taskId); - return TSDB_CODE_SUCCESS; +int32_t schMoveTaskToSuccList(SSchJob *pJob, SSchTask *pTask, bool *moved) { + if (0 != taosHashRemove(pJob->execTasks, &pTask->taskId, sizeof(pTask->taskId))) { + SCH_TASK_WLOG("remove task from execTask list failed, may not exist, status:%d", SCH_GET_TASK_STATUS(pTask)); } - if (0 != taosHashPut(job->succTasks, &task->taskId, sizeof(task->taskId), &task, POINTER_BYTES)) { - qError("taosHashPut failed"); + int32_t code = taosHashPut(pJob->succTasks, &pTask->taskId, sizeof(pTask->taskId), &pTask, POINTER_BYTES); + if (0 != code) { + if (HASH_NODE_EXIST(code)) { + *moved = true; + + SCH_TASK_ELOG("task already in succTask list, status:%d", SCH_GET_TASK_STATUS(pTask)); + SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); + } + + SCH_TASK_ELOG("taosHashPut task to succTask list failed, errno:%d", errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } *moved = true; + + SCH_TASK_DLOG("task moved to succTask list, numOfTasks:%d", taosHashGetSize(pJob->succTasks)); return TSDB_CODE_SUCCESS; } -int32_t schMoveTaskToFailList(SSchJob *job, SSchTask *task, bool *moved) { - if (0 != taosHashRemove(job->execTasks, &task->taskId, sizeof(task->taskId))) { - qWarn("remove task[%"PRIx64"] from execTasks failed, it may not exist", task->taskId); +int32_t schMoveTaskToFailList(SSchJob *pJob, SSchTask *pTask, bool *moved) { + *moved = false; + + if (0 != taosHashRemove(pJob->execTasks, &pTask->taskId, sizeof(pTask->taskId))) { + SCH_TASK_WLOG("remove task from execTask list failed, may not exist, status:%d", SCH_GET_TASK_STATUS(pTask)); } - if (0 != taosHashPut(job->failTasks, &task->taskId, sizeof(task->taskId), &task, POINTER_BYTES)) { - qError("taosHashPut failed"); + int32_t code = taosHashPut(pJob->failTasks, &pTask->taskId, sizeof(pTask->taskId), &pTask, POINTER_BYTES); + if (0 != code) { + if (HASH_NODE_EXIST(code)) { + *moved = true; + + SCH_TASK_WLOG("task already in failTask list, status:%d", SCH_GET_TASK_STATUS(pTask)); + SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); + } + + SCH_TASK_ELOG("taosHashPut task to failTask list failed, errno:%d", errno); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } *moved = true; + + SCH_TASK_DLOG("task moved to failTask list, numOfTasks:%d", taosHashGetSize(pJob->failTasks)); return TSDB_CODE_SUCCESS; } @@ -307,6 +498,8 @@ int32_t schMoveTaskToFailList(SSchJob *job, SSchTask *task, bool *moved) { int32_t schTaskCheckAndSetRetry(SSchJob *job, SSchTask *task, int32_t errCode, bool *needRetry) { // TODO set retry or not based on task type/errCode/retry times/job status/available eps... // TODO if needRetry, set task retry info + // TODO set condidateIdx + // TODO record failed but tried task *needRetry = false; @@ -314,51 +507,69 @@ int32_t schTaskCheckAndSetRetry(SSchJob *job, SSchTask *task, int32_t errCode, b } -int32_t schFetchFromRemote(SSchJob *job) { +int32_t schFetchFromRemote(SSchJob *pJob) { int32_t code = 0; - if (atomic_val_compare_exchange_32(&job->remoteFetch, 0, 1) != 0) { - qInfo("prior fetching not finished"); + if (atomic_val_compare_exchange_32(&pJob->remoteFetch, 0, 1) != 0) { + SCH_JOB_ELOG("prior fetching not finished, remoteFetch:%d", atomic_load_32(&pJob->remoteFetch)); return TSDB_CODE_SUCCESS; } - SCH_ERR_JRET(schBuildAndSendMsg(job, job->fetchTask, TDMT_VND_FETCH)); + if (atomic_load_ptr(&pJob->res)) + + SCH_ERR_JRET(schBuildAndSendMsg(pJob, pJob->fetchTask, &pJob->resNode, TDMT_VND_FETCH)); return TSDB_CODE_SUCCESS; _return: - atomic_val_compare_exchange_32(&job->remoteFetch, 1, 0); + + atomic_val_compare_exchange_32(&pJob->remoteFetch, 1, 0); return code; } -int32_t schProcessOnJobPartialSuccess(SSchJob *job) { - job->status = JOB_TASK_STATUS_PARTIAL_SUCCEED; +// Note: no more error processing, handled in function internal +int32_t schProcessOnJobFailure(SSchJob *pJob, int32_t errCode) { + SCH_ERR_RET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_FAILED)); + + if (errCode) { + atomic_store_32(&pJob->errCode, errCode); + } - if ((!job->attr.needFetch) && job->attr.syncSchedule) { - tsem_post(&job->rspSem); + if (atomic_load_8(&pJob->userFetch) || ((!SCH_JOB_NEED_FETCH(&pJob->attr)) && pJob->attr.syncSchedule)) { + tsem_post(&pJob->rspSem); + } + + SCH_ERR_RET(atomic_load_32(&pJob->errCode)); + + assert(0); +} + + +// Note: no more error processing, handled in function internal +int32_t schProcessOnJobPartialSuccess(SSchJob *pJob) { + int32_t code = 0; + + SCH_ERR_RET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_PARTIAL_SUCCEED)); + + if ((!SCH_JOB_NEED_FETCH(&pJob->attr)) && pJob->attr.syncSchedule) { + tsem_post(&pJob->rspSem); } - if (job->userFetch) { - SCH_ERR_RET(schFetchFromRemote(job)); + if (atomic_load_8(&pJob->userFetch)) { + SCH_ERR_JRET(schFetchFromRemote(pJob)); } return TSDB_CODE_SUCCESS; + +_return: + + SCH_ERR_RET(schProcessOnJobFailure(pJob, code)); + + SCH_RET(code); } -int32_t schProcessOnJobFailure(SSchJob *job, int32_t errCode) { - job->status = JOB_TASK_STATUS_FAILED; - job->errCode = errCode; - - atomic_val_compare_exchange_32(&job->remoteFetch, 1, 0); - - if (job->userFetch || ((!job->attr.needFetch) && job->attr.syncSchedule)) { - tsem_post(&job->rspSem); - } - - return TSDB_CODE_SUCCESS; -} int32_t schProcessOnDataFetched(SSchJob *job) { atomic_val_compare_exchange_32(&job->remoteFetch, 1, 0); @@ -367,51 +578,105 @@ int32_t schProcessOnDataFetched(SSchJob *job) { } -int32_t schProcessOnTaskSuccess(SSchJob *job, SSchTask *task) { + +// Note: no more error processing, handled in function internal +int32_t schProcessOnTaskFailure(SSchJob *pJob, SSchTask *pTask, int32_t errCode) { + bool needRetry = false; bool moved = false; + int32_t taskDone = 0; + int32_t code = 0; + + SCH_TASK_DLOG("taskOnFailure, code:%x", errCode); - SCH_ERR_RET(schMoveTaskToSuccList(job, task, &moved)); - if (!moved) { - SCH_TASK_ERR_LOG(" task may already moved, status:%d", task->status); + SCH_ERR_JRET(schTaskCheckAndSetRetry(pJob, pTask, errCode, &needRetry)); + + if (!needRetry) { + SCH_TASK_ELOG("task failed and no more retry, code:%x", errCode); + + if (SCH_GET_TASK_STATUS(pTask) == JOB_TASK_STATUS_EXECUTING) { + code = schMoveTaskToFailList(pJob, pTask, &moved); + if (code && moved) { + SCH_ERR_RET(errCode); + } + } + + SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_FAILED); + + if (SCH_TASK_NEED_WAIT_ALL(pTask)) { + SCH_LOCK(SCH_WRITE, &pTask->level->lock); + pTask->level->taskFailed++; + taskDone = pTask->level->taskSucceed + pTask->level->taskFailed; + SCH_UNLOCK(SCH_WRITE, &pTask->level->lock); + + atomic_store_32(&pJob->errCode, errCode); + + if (taskDone < pTask->level->taskNum) { + SCH_TASK_DLOG("not all tasks done, done:%d, all:%d", taskDone, pTask->level->taskNum); + SCH_ERR_RET(errCode); + } + } + } else { + // Note: no more error processing, already handled + SCH_ERR_RET(schLaunchTask(pJob, pTask)); + return TSDB_CODE_SUCCESS; } - task->status = JOB_TASK_STATUS_SUCCEED; - - int32_t parentNum = task->parents ? (int32_t)taosArrayGetSize(task->parents) : 0; - if (parentNum == 0) { - if (task->plan->level != 0) { - qError("level error"); - SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); - } +_return: + SCH_ERR_RET(schProcessOnJobFailure(pJob, errCode)); + + SCH_ERR_RET(errCode); +} + + +// Note: no more error processing, handled in function internal +int32_t schProcessOnTaskSuccess(SSchJob *pJob, SSchTask *pTask) { + bool moved = false; + int32_t code = 0; + SSchTask *pErrTask = pTask; + + SCH_TASK_DLOG("taskOnSuccess, status:%d", SCH_GET_TASK_STATUS(pTask)); + + code = schMoveTaskToSuccList(pJob, pTask, &moved); + if (code && moved) { + SCH_ERR_RET(code); + } + + SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_SUCCEED); + + SCH_ERR_JRET(schRecordTaskSucceedNode(pTask)); + + int32_t parentNum = pTask->parents ? (int32_t)taosArrayGetSize(pTask->parents) : 0; + if (parentNum == 0) { int32_t taskDone = 0; - if (SCH_TASK_NEED_WAIT_ALL(task)) { - SCH_LOCK(SCH_WRITE, &task->level->lock); - task->level->taskSucceed++; - taskDone = task->level->taskSucceed + task->level->taskFailed; - SCH_UNLOCK(SCH_WRITE, &task->level->lock); + if (SCH_TASK_NEED_WAIT_ALL(pTask)) { + SCH_LOCK(SCH_WRITE, &pTask->level->lock); + pTask->level->taskSucceed++; + taskDone = pTask->level->taskSucceed + pTask->level->taskFailed; + SCH_UNLOCK(SCH_WRITE, &pTask->level->lock); - if (taskDone < task->level->taskNum) { - qDebug("wait all tasks, done:%d, all:%d", taskDone, task->level->taskNum); + if (taskDone < pTask->level->taskNum) { + SCH_TASK_ELOG("wait all tasks, done:%d, all:%d", taskDone, pTask->level->taskNum); + return TSDB_CODE_SUCCESS; + } else if (taskDone > pTask->level->taskNum) { + assert(0); } - if (task->level->taskFailed > 0) { - job->status = JOB_TASK_STATUS_FAILED; - SCH_ERR_RET(schProcessOnJobFailure(job, TSDB_CODE_QRY_APP_ERROR)); - - return TSDB_CODE_SUCCESS; + if (pTask->level->taskFailed > 0) { + SCH_RET(schProcessOnJobFailure(pJob, 0)); + } else { + SCH_RET(schProcessOnJobPartialSuccess(pJob)); } } else { - strncpy(job->resEp.fqdn, task->execAddr.epAddr[task->execAddr.inUse].fqdn, sizeof(job->resEp.fqdn)); - job->resEp.port = task->execAddr.epAddr[task->execAddr.inUse].port; + pJob->resNode = pTask->succeedAddr; } - job->fetchTask = task; + pJob->fetchTask = pTask; - SCH_ERR_RET(schProcessOnJobPartialSuccess(job)); + SCH_ERR_RET(schProcessOnJobPartialSuccess(pJob)); return TSDB_CODE_SUCCESS; } @@ -426,163 +691,157 @@ int32_t schProcessOnTaskSuccess(SSchJob *job, SSchTask *task) { */ for (int32_t i = 0; i < parentNum; ++i) { - SSchTask *par = *(SSchTask **)taosArrayGet(task->parents, i); + SSchTask *par = *(SSchTask **)taosArrayGet(pTask->parents, i); + pErrTask = par; + + atomic_add_fetch_32(&par->childReady, 1); - ++par->childReady; - - SCH_ERR_RET(qSetSubplanExecutionNode(par->plan, task->plan->id.templateId, &task->execAddr)); + SCH_LOCK(SCH_WRITE, &par->lock); + qSetSubplanExecutionNode(par->plan, pTask->plan->id.templateId, &pTask->succeedAddr); + SCH_UNLOCK(SCH_WRITE, &par->lock); if (SCH_TASK_READY_TO_LUNCH(par)) { - SCH_ERR_RET(schLaunchTask(job, par)); + SCH_ERR_RET(schLaunchTask(pJob, par)); } } return TSDB_CODE_SUCCESS; + +_return: + + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pErrTask, code)); + + SCH_ERR_RET(code); } -int32_t schProcessOnTaskFailure(SSchJob *job, SSchTask *task, int32_t errCode) { - bool needRetry = false; - bool moved = false; - int32_t taskDone = 0; - SCH_ERR_RET(schTaskCheckAndSetRetry(job, task, errCode, &needRetry)); - - if (!needRetry) { - SCH_TASK_ERR_LOG("task failed[%x], no more retry", errCode); - - SCH_ERR_RET(schMoveTaskToFailList(job, task, &moved)); - if (!moved) { - SCH_TASK_ERR_LOG("task may already moved, status:%d", task->status); - } - - if (SCH_TASK_NEED_WAIT_ALL(task)) { - SCH_LOCK(SCH_WRITE, &task->level->lock); - task->level->taskFailed++; - taskDone = task->level->taskSucceed + task->level->taskFailed; - SCH_UNLOCK(SCH_WRITE, &task->level->lock); - - if (taskDone < task->level->taskNum) { - qDebug("wait all tasks, done:%d, all:%d", taskDone, task->level->taskNum); - return TSDB_CODE_SUCCESS; - } - } - - job->status = JOB_TASK_STATUS_FAILED; - SCH_ERR_RET(schProcessOnJobFailure(job, errCode)); - - return TSDB_CODE_SUCCESS; - } - - SCH_ERR_RET(schLaunchTask(job, task)); - - return TSDB_CODE_SUCCESS; -} - -int32_t schProcessRspMsg(SSchJob *job, SSchTask *task, int32_t msgType, char *msg, int32_t msgSize, int32_t rspCode) { +int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, char *msg, int32_t msgSize, int32_t rspCode) { int32_t code = 0; + SCH_ERR_JRET(schValidateTaskReceivedMsgType(pJob, pTask, msgType)); + switch (msgType) { case TDMT_VND_CREATE_TABLE_RSP: { - if (rspCode != TSDB_CODE_SUCCESS) { - SCH_ERR_JRET(schProcessOnTaskFailure(job, task, rspCode)); - } else { -// job->resNumOfRows += rsp->affectedRows; - code = schProcessOnTaskSuccess(job, task); - if (code) { - goto _task_error; - } - } - - break; - } - case TDMT_VND_SUBMIT_RSP: { if (rspCode != TSDB_CODE_SUCCESS) { - SCH_ERR_JRET(schProcessOnTaskFailure(job, task, rspCode)); - } else { - SShellSubmitRspMsg *rsp = (SShellSubmitRspMsg *)msg; - job->resNumOfRows += rsp->affectedRows; - - code = schProcessOnTaskSuccess(job, task); - if (code) { - goto _task_error; - } + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pTask, rspCode)); } + + SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); + + break; + } + case TDMT_VND_SUBMIT_RSP: { + #if 0 //TODO OPEN THIS + SShellSubmitRspMsg *rsp = (SShellSubmitRspMsg *)msg; + + if (rspCode != TSDB_CODE_SUCCESS || NULL == msg || rsp->code != TSDB_CODE_SUCCESS) { + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pTask, rspCode)); + } + + pJob->resNumOfRows += rsp->affectedRows; + #else + if (rspCode != TSDB_CODE_SUCCESS) { + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pTask, rspCode)); + } + #endif + + SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); + break; } case TDMT_VND_QUERY_RSP: { SQueryTableRsp *rsp = (SQueryTableRsp *)msg; - if (rsp->code != TSDB_CODE_SUCCESS) { - SCH_ERR_JRET(schProcessOnTaskFailure(job, task, rsp->code)); - } else { - code = schBuildAndSendMsg(job, task, TDMT_VND_RES_READY); - if (code) { - goto _task_error; - } + if (rspCode != TSDB_CODE_SUCCESS || NULL == msg || rsp->code != TSDB_CODE_SUCCESS) { + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pTask, rsp->code)); } + + SCH_ERR_JRET(schBuildAndSendMsg(pJob, pTask, NULL, TDMT_VND_RES_READY)); + break; } case TDMT_VND_RES_READY_RSP: { SResReadyRsp *rsp = (SResReadyRsp *)msg; - if (rsp->code != TSDB_CODE_SUCCESS) { - SCH_ERR_JRET(schProcessOnTaskFailure(job, task, rsp->code)); - } else { - code = schProcessOnTaskSuccess(job, task); - if (code) { - goto _task_error; - } + if (rspCode != TSDB_CODE_SUCCESS || NULL == msg || rsp->code != TSDB_CODE_SUCCESS) { + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pTask, rsp->code)); } + + SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); + break; } case TDMT_VND_FETCH_RSP: { - SCH_ERR_JRET(rspCode); SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)msg; - job->res = rsp; - job->resNumOfRows = rsp->numOfRows; + if (rspCode != TSDB_CODE_SUCCESS || NULL == msg) { + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pTask, rspCode)); + } + + atomic_store_ptr(&pJob->res, rsp); + atomic_store_32(&pJob->resNumOfRows, rsp->numOfRows); + + SCH_ERR_JRET(schProcessOnDataFetched(pJob)); - SCH_ERR_JRET(schProcessOnDataFetched(job)); break; } case TDMT_VND_DROP_TASK: { - + // SHOULD NEVER REACH HERE + assert(0); + break; } default: - qError("unknown msg type:%d received", msgType); - return TSDB_CODE_QRY_INVALID_INPUT; + SCH_TASK_ELOG("unknown rsp msg, type:%d, status:%d", msgType, SCH_GET_TASK_STATUS(pTask)); + + SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); } return TSDB_CODE_SUCCESS; -_task_error: - SCH_ERR_JRET(schProcessOnTaskFailure(job, task, code)); - return TSDB_CODE_SUCCESS; - _return: - code = schProcessOnJobFailure(job, code); - return code; + + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pTask, code)); + + SCH_RET(code); } int32_t schHandleCallback(void* param, const SDataBuf* pMsg, int32_t msgType, int32_t rspCode) { int32_t code = 0; SSchCallbackParam *pParam = (SSchCallbackParam *)param; + SSchJob *pJob = NULL; + SSchTask *pTask = NULL; SSchJob **job = taosHashGet(schMgmt.jobs, &pParam->queryId, sizeof(pParam->queryId)); if (NULL == job || NULL == (*job)) { - qError("taosHashGet queryId:%"PRIx64" not exist", pParam->queryId); + qError("QID:%"PRIx64" taosHashGet queryId not exist", pParam->queryId); SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); } - SSchTask **task = taosHashGet((*job)->execTasks, &pParam->taskId, sizeof(pParam->taskId)); + pJob = *job; + + atomic_add_fetch_32(&pJob->ref, 1); + + int32_t s = taosHashGetSize(pJob->execTasks); + assert(s != 0); + + SSchTask **task = taosHashGet(pJob->execTasks, &pParam->taskId, sizeof(pParam->taskId)); if (NULL == task || NULL == (*task)) { - qError("taosHashGet taskId:%"PRIx64" not exist", pParam->taskId); + qError("QID:%"PRIx64",TID:%"PRIx64" taosHashGet taskId not exist", pParam->queryId, pParam->taskId); SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); } - - schProcessRspMsg(*job, *task, msgType, pMsg->pData, pMsg->len, rspCode); -_return: + pTask = *task; + + SCH_TASK_DLOG("rsp msg received, type:%d, code:%x", msgType, rspCode); + + SCH_ERR_JRET(schHandleResponseMsg(pJob, pTask, msgType, pMsg->pData, pMsg->len, rspCode)); + +_return: + + if (pJob) { + atomic_sub_fetch_32(&pJob->ref, 1); + } + tfree(param); SCH_RET(code); } @@ -609,7 +868,7 @@ int32_t schHandleReadyCallback(void* param, const SDataBuf* pMsg, int32_t code) int32_t schHandleDropCallback(void* param, const SDataBuf* pMsg, int32_t code) { SSchCallbackParam *pParam = (SSchCallbackParam *)param; - qDebug("drop task rsp received, queryId:%"PRIx64 ",taksId:%"PRIx64 ",code:%d", pParam->queryId, pParam->taskId, code); + qDebug("QID:%"PRIx64",TID:%"PRIx64" drop task rsp received, code:%x", pParam->queryId, pParam->taskId, code); } int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) { @@ -633,7 +892,7 @@ int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) { *fp = schHandleDropCallback; break; default: - qError("unknown msg type:%d", msgType); + qError("unknown msg type for callback, msgType:%d", msgType); SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); } @@ -645,13 +904,13 @@ int32_t schAsyncSendMsg(void *transport, SEpSet* epSet, uint64_t qId, uint64_t t int32_t code = 0; SMsgSendInfo* pMsgSendInfo = calloc(1, sizeof(SMsgSendInfo)); if (NULL == pMsgSendInfo) { - qError("calloc %d failed", (int32_t)sizeof(SMsgSendInfo)); + qError("QID:%"PRIx64 ",TID:%"PRIx64 " calloc %d failed", qId, tId, (int32_t)sizeof(SMsgSendInfo)); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } SSchCallbackParam *param = calloc(1, sizeof(SSchCallbackParam)); if (NULL == param) { - qError("calloc %d failed", (int32_t)sizeof(SSchCallbackParam)); + qError("QID:%"PRIx64 ",TID:%"PRIx64 " calloc %d failed", qId, tId, (int32_t)sizeof(SSchCallbackParam)); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -665,15 +924,20 @@ int32_t schAsyncSendMsg(void *transport, SEpSet* epSet, uint64_t qId, uint64_t t pMsgSendInfo->msgInfo.pData = msg; pMsgSendInfo->msgInfo.len = msgSize; pMsgSendInfo->msgType = msgType; - pMsgSendInfo->fp = fp; int64_t transporterId = 0; - SCH_ERR_JRET(asyncSendMsgToServer(transport, epSet, &transporterId, pMsgSendInfo)); + + code = asyncSendMsgToServer(transport, epSet, &transporterId, pMsgSendInfo); + if (code) { + qError("QID:%"PRIx64 ",TID:%"PRIx64 " asyncSendMsgToServer failed, code:%x", qId, tId, code); + SCH_ERR_JRET(code); + } return TSDB_CODE_SUCCESS; _return: + tfree(param); tfree(pMsgSendInfo); @@ -690,192 +954,321 @@ void schConvertAddrToEpSet(SQueryNodeAddr *addr, SEpSet *epSet) { } } - -int32_t schBuildAndSendMsg(SSchJob *job, SSchTask *task, int32_t msgType) { +int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, int32_t msgType) { uint32_t msgSize = 0; void *msg = NULL; int32_t code = 0; + bool isCandidateAddr = false; + SEpSet epSet; + + if (NULL == addr) { + addr = taosArrayGet(pTask->candidateAddrs, atomic_load_8(&pTask->candidateIdx)); + + isCandidateAddr = true; + } + + schConvertAddrToEpSet(addr, &epSet); switch (msgType) { case TDMT_VND_CREATE_TABLE: case TDMT_VND_SUBMIT: { - if (NULL == task->msg || task->msgLen <= 0) { - qError("submit msg is NULL"); - SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); - } - - msgSize = task->msgLen; - msg = task->msg; + msgSize = pTask->msgLen; + msg = pTask->msg; break; } case TDMT_VND_QUERY: { - if (NULL == task->msg) { - qError("query msg is NULL"); - SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); - } - - msgSize = sizeof(SSubQueryMsg) + task->msgLen; + msgSize = sizeof(SSubQueryMsg) + pTask->msgLen; msg = calloc(1, msgSize); if (NULL == msg) { - qError("calloc %d failed", msgSize); + SCH_TASK_ELOG("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } SSubQueryMsg *pMsg = msg; - pMsg->header.vgId = htonl(task->plan->execNode.nodeId); + pMsg->header.vgId = htonl(addr->nodeId); + pMsg->sId = htobe64(schMgmt.sId); - pMsg->queryId = htobe64(job->queryId); - pMsg->taskId = htobe64(task->taskId); - pMsg->contentLen = htonl(task->msgLen); - memcpy(pMsg->msg, task->msg, task->msgLen); + pMsg->queryId = htobe64(pJob->queryId); + pMsg->taskId = htobe64(pTask->taskId); + pMsg->contentLen = htonl(pTask->msgLen); + memcpy(pMsg->msg, pTask->msg, pTask->msgLen); break; } case TDMT_VND_RES_READY: { - msgSize = sizeof(SResReadyMsg); + msgSize = sizeof(SResReadyReq); msg = calloc(1, msgSize); if (NULL == msg) { - qError("calloc %d failed", msgSize); + SCH_TASK_ELOG("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - SResReadyMsg *pMsg = msg; + SResReadyReq *pMsg = msg; + + pMsg->header.vgId = htonl(addr->nodeId); - pMsg->header.vgId = htonl(task->plan->execNode.nodeId); pMsg->sId = htobe64(schMgmt.sId); - pMsg->queryId = htobe64(job->queryId); - pMsg->taskId = htobe64(task->taskId); + pMsg->queryId = htobe64(pJob->queryId); + pMsg->taskId = htobe64(pTask->taskId); break; } case TDMT_VND_FETCH: { - if (NULL == task) { - SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); - } - msgSize = sizeof(SResFetchMsg); + msgSize = sizeof(SResFetchReq); msg = calloc(1, msgSize); if (NULL == msg) { - qError("calloc %d failed", msgSize); + SCH_TASK_ELOG("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - SResFetchMsg *pMsg = msg; + SResFetchReq *pMsg = msg; + + pMsg->header.vgId = htonl(addr->nodeId); - pMsg->header.vgId = htonl(task->plan->execNode.nodeId); pMsg->sId = htobe64(schMgmt.sId); - pMsg->queryId = htobe64(job->queryId); - pMsg->taskId = htobe64(task->taskId); + pMsg->queryId = htobe64(pJob->queryId); + pMsg->taskId = htobe64(pTask->taskId); break; } case TDMT_VND_DROP_TASK:{ - msgSize = sizeof(STaskDropMsg); + msgSize = sizeof(STaskDropReq); msg = calloc(1, msgSize); if (NULL == msg) { - qError("calloc %d failed", msgSize); + SCH_TASK_ELOG("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - STaskDropMsg *pMsg = msg; + STaskDropReq *pMsg = msg; + + pMsg->header.vgId = htonl(addr->nodeId); - pMsg->header.vgId = htonl(task->plan->execNode.nodeId); pMsg->sId = htobe64(schMgmt.sId); - pMsg->queryId = htobe64(job->queryId); - pMsg->taskId = htobe64(task->taskId); + pMsg->queryId = htobe64(pJob->queryId); + pMsg->taskId = htobe64(pTask->taskId); break; } default: - qError("unknown msg type:%d", msgType); + SCH_TASK_ELOG("unknown msg type to send, msgType:%d", msgType); SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); break; } - SEpSet epSet; - SQueryNodeAddr *addr = taosArrayGet(task->condidateAddrs, task->condidateIdx); + atomic_store_32(&pTask->lastMsgType, msgType); + + SCH_ERR_JRET(schAsyncSendMsg(pJob->transport, &epSet, pJob->queryId, pTask->taskId, msgType, msg, msgSize)); + + if (isCandidateAddr) { + SCH_ERR_RET(schRecordTaskExecNode(pJob, pTask, addr)); + } - schConvertAddrToEpSet(addr, &epSet); - - SCH_ERR_JRET(schAsyncSendMsg(job->transport, &epSet, job->queryId, task->taskId, msgType, msg, msgSize)); - return TSDB_CODE_SUCCESS; _return: + atomic_store_32(&pTask->lastMsgType, -1); + tfree(msg); SCH_RET(code); } - -int32_t schLaunchTask(SSchJob *job, SSchTask *task) { - SSubplan *plan = task->plan; - SCH_ERR_RET(qSubPlanToString(plan, &task->msg, &task->msgLen)); - SCH_ERR_RET(schSetTaskCondidateAddrs(job, task)); - - if (NULL == task->condidateAddrs || taosArrayGetSize(task->condidateAddrs) <= 0) { - SCH_TASK_ERR_LOG("no valid condidate node for task:%"PRIx64, task->taskId); - SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); +static FORCE_INLINE bool schJobNeedToStop(SSchJob *pJob, int8_t *pStatus) { + int8_t status = SCH_GET_JOB_STATUS(pJob); + if (pStatus) { + *pStatus = status; } -// int32_t msgType = (plan->type == QUERY_TYPE_MODIFY)? TDMT_VND_SUBMIT : TDMT_VND_QUERY; - - SCH_ERR_RET(schBuildAndSendMsg(job, task, plan->msgType)); - SCH_ERR_RET(schPushTaskToExecList(job, task)); - - task->status = JOB_TASK_STATUS_EXECUTING; - return TSDB_CODE_SUCCESS; + return (status == JOB_TASK_STATUS_FAILED || status == JOB_TASK_STATUS_CANCELLED + || status == JOB_TASK_STATUS_CANCELLING || status == JOB_TASK_STATUS_DROPPING); } -int32_t schLaunchJob(SSchJob *job) { - SSchLevel *level = taosArrayGet(job->levels, job->levelIdx); + +// Note: no more error processing, handled in function internal +int32_t schLaunchTask(SSchJob *pJob, SSchTask *pTask) { + int8_t status = 0; + int32_t code = 0; + + if (schJobNeedToStop(pJob, &status)) { + SCH_TASK_ELOG("no need to launch task cause of job status, job status:%d", status); + + code = atomic_load_32(&pJob->errCode); + SCH_ERR_RET(code); + + SCH_RET(TSDB_CODE_SCH_STATUS_ERROR); + } + + SSubplan *plan = pTask->plan; + + if (NULL == pTask->msg) { + code = qSubPlanToString(plan, &pTask->msg, &pTask->msgLen); + if (TSDB_CODE_SUCCESS != code || NULL == pTask->msg || pTask->msgLen <= 0) { + SCH_TASK_ELOG("subplanToString error, code:%x, msg:%p, len:%d", code, pTask->msg, pTask->msgLen); + SCH_ERR_JRET(code); + } + } + + SCH_ERR_JRET(schSetTaskCandidateAddrs(pJob, pTask)); + + // NOTE: race condition: the task should be put into the hash table before send msg to server + if (SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_EXECUTING) { + SCH_ERR_JRET(schPushTaskToExecList(pJob, pTask)); + + SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_EXECUTING); + } + + SCH_ERR_JRET(schBuildAndSendMsg(pJob, pTask, NULL, plan->msgType)); + + return TSDB_CODE_SUCCESS; + +_return: + + SCH_ERR_RET(schProcessOnTaskFailure(pJob, pTask, code)); + + SCH_RET(code); +} + +int32_t schLaunchJob(SSchJob *pJob) { + SSchLevel *level = taosArrayGet(pJob->levels, pJob->levelIdx); + + SCH_ERR_RET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_EXECUTING)); + for (int32_t i = 0; i < level->taskNum; ++i) { - SSchTask *task = taosArrayGet(level->subTasks, i); - SCH_ERR_RET(schLaunchTask(job, task)); + SSchTask *pTask = taosArrayGet(level->subTasks, i); + SCH_ERR_RET(schLaunchTask(pJob, pTask)); } - - job->status = JOB_TASK_STATUS_EXECUTING; return TSDB_CODE_SUCCESS; } -void schDropJobAllTasks(SSchJob *job) { - void *pIter = taosHashIterate(job->succTasks, NULL); - while (pIter) { - SSchTask *task = *(SSchTask **)pIter; - - schBuildAndSendMsg(job, task, TDMT_VND_DROP_TASK); - - pIter = taosHashIterate(job->succTasks, pIter); - } +void schDropTaskOnExecutedNode(SSchJob *pJob, SSchTask *pTask) { + if (NULL == pTask->execAddrs) { + SCH_TASK_DLOG("no exec address, status:%d", SCH_GET_TASK_STATUS(pTask)); + return; + } - pIter = taosHashIterate(job->failTasks, NULL); - while (pIter) { - SSchTask *task = *(SSchTask **)pIter; + int32_t size = (int32_t)taosArrayGetSize(pTask->execAddrs); - schBuildAndSendMsg(job, task, TDMT_VND_DROP_TASK); - - pIter = taosHashIterate(job->succTasks, pIter); - } + if (size <= 0) { + SCH_TASK_DLOG("empty exec address, status:%d", SCH_GET_TASK_STATUS(pTask)); + return; + } + + SQueryNodeAddr *addr = NULL; + for (int32_t i = 0; i < size; ++i) { + addr = (SQueryNodeAddr *)taosArrayGet(pTask->execAddrs, i); + + schBuildAndSendMsg(pJob, pTask, addr, TDMT_VND_DROP_TASK); + } } -uint64_t schGenSchId(void) { - uint64_t sId = 0; +void schDropTaskInHashList(SSchJob *pJob, SHashObj *list) { + void *pIter = taosHashIterate(list, NULL); + while (pIter) { + SSchTask *pTask = *(SSchTask **)pIter; - // TODO + if (!SCH_TASK_NO_NEED_DROP(pTask)) { + schDropTaskOnExecutedNode(pJob, pTask); + } + + pIter = taosHashIterate(list, pIter); + } +} - qDebug("Gen sId:0x%"PRIx64, sId); +void schDropJobAllTasks(SSchJob *pJob) { + schDropTaskInHashList(pJob, pJob->execTasks); + schDropTaskInHashList(pJob, pJob->succTasks); + schDropTaskInHashList(pJob, pJob->failTasks); +} + +int32_t schExecJobImpl(void *transport, SArray *nodeList, SQueryDag* pDag, void** job, bool syncSchedule) { + if (nodeList && taosArrayGetSize(nodeList) <= 0) { + qInfo("QID:%"PRIx64" input nodeList is empty", pDag->queryId); + } + + int32_t code = 0; + SSchJob *pJob = calloc(1, sizeof(SSchJob)); + if (NULL == pJob) { + qError("QID:%"PRIx64" calloc %d failed", pDag->queryId, (int32_t)sizeof(SSchJob)); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + pJob->attr.syncSchedule = syncSchedule; + pJob->transport = transport; + pJob->nodeList = nodeList; + + SCH_ERR_JRET(schValidateAndBuildJob(pDag, pJob)); + + pJob->execTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); + if (NULL == pJob->execTasks) { + SCH_JOB_ELOG("taosHashInit %d execTasks failed", pDag->numOfSubplans); + SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + pJob->succTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); + if (NULL == pJob->succTasks) { + SCH_JOB_ELOG("taosHashInit %d succTasks failed", pDag->numOfSubplans); + SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + pJob->failTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); + if (NULL == pJob->failTasks) { + SCH_JOB_ELOG("taosHashInit %d failTasks failed", pDag->numOfSubplans); + SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + tsem_init(&pJob->rspSem, 0, 0); + + code = taosHashPut(schMgmt.jobs, &pJob->queryId, sizeof(pJob->queryId), &pJob, POINTER_BYTES); + if (0 != code) { + if (HASH_NODE_EXIST(code)) { + SCH_JOB_ELOG("job already exist, isQueryJob:%d", pJob->attr.queryJob); + SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); + } else { + SCH_JOB_ELOG("taosHashPut job failed, errno:%d", errno); + SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + } + + pJob->status = JOB_TASK_STATUS_NOT_START; + + SCH_ERR_JRET(schLaunchJob(pJob)); + + *(SSchJob **)job = pJob; + + if (syncSchedule) { + SCH_JOB_DLOG("will wait for rsp now, job status:%d", SCH_GET_JOB_STATUS(pJob)); + tsem_wait(&pJob->rspSem); + } + + SCH_JOB_DLOG("job exec done, job status:%d", SCH_GET_JOB_STATUS(pJob)); + + return TSDB_CODE_SUCCESS; + +_return: + + *(SSchJob **)job = NULL; + + scheduleFreeJob(pJob); + + SCH_RET(code); +} + +int32_t schCancelJob(SSchJob *pJob) { + //TODO + + //TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST - return sId; } int32_t schedulerInit(SSchedulerCfg *cfg) { if (schMgmt.jobs) { - qError("scheduler already init"); + qError("scheduler already initialized"); return TSDB_CODE_QRY_INVALID_INPUT; } if (cfg) { schMgmt.cfg = *cfg; - if (schMgmt.cfg.maxJobNum <= 0) { + if (schMgmt.cfg.maxJobNum == 0) { schMgmt.cfg.maxJobNum = SCHEDULE_DEFAULT_JOB_NUMBER; } } else { @@ -884,194 +1277,190 @@ int32_t schedulerInit(SSchedulerCfg *cfg) { schMgmt.jobs = taosHashInit(schMgmt.cfg.maxJobNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); if (NULL == schMgmt.jobs) { - SCH_ERR_LRET(TSDB_CODE_QRY_OUT_OF_MEMORY, "init %d schduler jobs failed", schMgmt.cfg.maxJobNum); - } - - schMgmt.sId = schGenSchId(); - - return TSDB_CODE_SUCCESS; -} - - -int32_t scheduleExecJobImpl(void *transport, SArray *nodeList, SQueryDag* pDag, void** pJob, bool syncSchedule) { - if (nodeList && taosArrayGetSize(nodeList) <= 0) { - qInfo("qnodeList is empty"); - } - - int32_t code = 0; - SSchJob *job = calloc(1, sizeof(SSchJob)); - if (NULL == job) { + qError("init schduler jobs failed, num:%u", schMgmt.cfg.maxJobNum); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - job->attr.syncSchedule = syncSchedule; - job->transport = transport; - job->nodeList = nodeList; - - SCH_ERR_JRET(schValidateAndBuildJob(pDag, job)); - - job->execTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); - if (NULL == job->execTasks) { - qError("taosHashInit %d failed", pDag->numOfSubplans); - SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); + if (taosGetSystemUUID((char *)&schMgmt.sId, sizeof(schMgmt.sId))) { + qError("generate schdulerId failed, errno:%d", errno); + SCH_ERR_RET(TSDB_CODE_QRY_SYS_ERROR); } - job->succTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); - if (NULL == job->succTasks) { - qError("taosHashInit %d failed", pDag->numOfSubplans); - SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } - - job->failTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); - if (NULL == job->failTasks) { - qError("taosHashInit %d failed", pDag->numOfSubplans); - SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } - - tsem_init(&job->rspSem, 0, 0); - - code = taosHashPut(schMgmt.jobs, &job->queryId, sizeof(job->queryId), &job, POINTER_BYTES); - if (0 != code) { - if (HASH_NODE_EXIST(code)) { - qError("taosHashPut queryId:%"PRIx64" already exist", job->queryId); - SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); - } else { - qError("taosHashPut queryId:%"PRIx64" failed", job->queryId); - SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); - } - } - - job->status = JOB_TASK_STATUS_NOT_START; + qInfo("scheduler %"PRIx64" initizlized, maxJob:%u", schMgmt.sId, schMgmt.cfg.maxJobNum); - SCH_ERR_JRET(schLaunchJob(job)); - - *(SSchJob **)pJob = job; - - if (syncSchedule) { - tsem_wait(&job->rspSem); - } - return TSDB_CODE_SUCCESS; - -_return: - - *(SSchJob **)pJob = NULL; - scheduleFreeJob(job); - - SCH_RET(code); } int32_t scheduleExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, void** pJob, SQueryResult *pRes) { - if (NULL == transport || /* NULL == nodeList || */ NULL == pDag || NULL == pDag->pSubplans || NULL == pJob || NULL == pRes) { + if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob || NULL == pRes) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - SCH_ERR_RET(scheduleExecJobImpl(transport, nodeList, pDag, pJob, true)); + SSchJob *job = NULL; - SSchJob *job = *(SSchJob **)pJob; - - pRes->code = job->errCode; + SCH_ERR_RET(schExecJobImpl(transport, nodeList, pDag, (void **)&job, true)); + + *pJob = job; + + pRes->code = atomic_load_32(&job->errCode); pRes->numOfRows = job->resNumOfRows; return TSDB_CODE_SUCCESS; } int32_t scheduleAsyncExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, void** pJob) { - if (NULL == transport || NULL == nodeList ||NULL == pDag || NULL == pDag->pSubplans || NULL == pJob) { + if (NULL == transport || /*NULL == nodeList || */NULL == pDag || NULL == pDag->pSubplans || NULL == pJob) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - return scheduleExecJobImpl(transport, nodeList, pDag, pJob, false); -} + SSchJob *job = NULL; + SCH_ERR_RET(schExecJobImpl(transport, nodeList, pDag, (void **)&job, false)); -int32_t scheduleFetchRows(void *pJob, void **data) { - if (NULL == pJob || NULL == data) { - SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); - } - - SSchJob *job = pJob; - int32_t code = 0; - - if (!job->attr.needFetch) { - qError("no need to fetch data"); - SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); - } - - if (job->status == JOB_TASK_STATUS_FAILED) { - job->res = NULL; - SCH_RET(job->errCode); - } - - if (job->status == JOB_TASK_STATUS_SUCCEED) { - job->res = NULL; - return TSDB_CODE_SUCCESS; - } - - if (atomic_val_compare_exchange_32(&job->userFetch, 0, 1) != 0) { - qError("prior fetching not finished"); - SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); - } - - if (job->status == JOB_TASK_STATUS_PARTIAL_SUCCEED) { - SCH_ERR_JRET(schFetchFromRemote(job)); - } - - tsem_wait(&job->rspSem); - - if (job->status == JOB_TASK_STATUS_FAILED) { - code = job->errCode; - } - - if (job->res && ((SRetrieveTableRsp *)job->res)->completed) { - job->status = JOB_TASK_STATUS_SUCCEED; - } - - *data = job->res; - job->res = NULL; - -_return: - atomic_val_compare_exchange_32(&job->userFetch, 1, 0); - - SCH_RET(code); -} - -int32_t scheduleCancelJob(void *pJob) { - //TODO - - //TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST + *pJob = job; return TSDB_CODE_SUCCESS; } -void scheduleFreeJob(void *pJob) { - if (NULL == pJob) { + +int32_t scheduleFetchRows(void *job, void **data) { + if (NULL == job || NULL == data) { + SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } + + SSchJob *pJob = job; + int32_t code = 0; + + atomic_add_fetch_32(&pJob->ref, 1); + + if (!SCH_JOB_NEED_FETCH(&pJob->attr)) { + SCH_JOB_ELOG("no need to fetch data, status:%d", SCH_GET_JOB_STATUS(pJob)); + atomic_sub_fetch_32(&pJob->ref, 1); + SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + if (atomic_val_compare_exchange_8(&pJob->userFetch, 0, 1) != 0) { + SCH_JOB_ELOG("prior fetching not finished, userFetch:%d", atomic_load_8(&pJob->userFetch)); + atomic_sub_fetch_32(&pJob->ref, 1); + SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + int8_t status = SCH_GET_JOB_STATUS(pJob); + + if (status == JOB_TASK_STATUS_FAILED) { + *data = atomic_load_ptr(&pJob->res); + atomic_store_ptr(&pJob->res, NULL); + SCH_ERR_JRET(atomic_load_32(&pJob->errCode)); + } else if (status == JOB_TASK_STATUS_SUCCEED) { + *data = atomic_load_ptr(&pJob->res); + atomic_store_ptr(&pJob->res, NULL); + goto _return; + } else if (status == JOB_TASK_STATUS_PARTIAL_SUCCEED) { + SCH_ERR_JRET(schFetchFromRemote(pJob)); + } + + tsem_wait(&pJob->rspSem); + + status = SCH_GET_JOB_STATUS(pJob); + + if (status == JOB_TASK_STATUS_FAILED) { + code = atomic_load_32(&pJob->errCode); + } + + if (pJob->res && ((SRetrieveTableRsp *)pJob->res)->completed) { + SCH_ERR_JRET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_SUCCEED)); + } + + while (true) { + *data = atomic_load_ptr(&pJob->res); + + if (*data != atomic_val_compare_exchange_ptr(&pJob->res, *data, NULL)) { + continue; + } + + break; + } + +_return: + + atomic_val_compare_exchange_8(&pJob->userFetch, 1, 0); + + atomic_sub_fetch_32(&pJob->ref, 1); + + SCH_RET(code); +} + +int32_t scheduleCancelJob(void *job) { + SSchJob *pJob = (SSchJob *)job; + + atomic_add_fetch_32(&pJob->ref, 1); + + int32_t code = schCancelJob(pJob); + + atomic_sub_fetch_32(&pJob->ref, 1); + + SCH_RET(code); +} + +void scheduleFreeJob(void *job) { + if (NULL == job) { return; } - SSchJob *job = pJob; + SSchJob *pJob = job; - if (job->status > 0) { - if (0 != taosHashRemove(schMgmt.jobs, &job->queryId, sizeof(job->queryId))) { - qError("remove job:%"PRIx64"from mgmt failed", job->queryId); // maybe already freed - return; + if (0 != taosHashRemove(schMgmt.jobs, &pJob->queryId, sizeof(pJob->queryId))) { + SCH_JOB_ELOG("taosHashRemove job from list failed, may already freed, pJob:%p", pJob); + return; + } + + while (true) { + int32_t ref = atomic_load_32(&pJob->ref); + if (0 == ref) { + break; + } else if (ref > 0) { + usleep(1); + } else { + assert(0); + } + } + + if (pJob->status == JOB_TASK_STATUS_EXECUTING) { + schCancelJob(pJob); + } + + schDropJobAllTasks(pJob); + + pJob->subPlans = NULL; // it is a reference to pDag->pSubplans + + int32_t numOfLevels = taosArrayGetSize(pJob->levels); + for(int32_t i = 0; i < numOfLevels; ++i) { + SSchLevel *pLevel = taosArrayGet(pJob->levels, i); + + int32_t numOfTasks = taosArrayGetSize(pLevel->subTasks); + for(int32_t j = 0; j < numOfTasks; ++j) { + SSchTask* pTask = taosArrayGet(pLevel->subTasks, j); + schFreeTask(pTask); } - if (job->status == JOB_TASK_STATUS_EXECUTING) { - scheduleCancelJob(pJob); - } - - schDropJobAllTasks(job); + taosArrayDestroy(pLevel->subTasks); } - //TODO free job -} - -void schedulerDestroy(void) { - if (schMgmt.jobs) { - taosHashCleanup(schMgmt.jobs); //TODO - schMgmt.jobs = NULL; + taosHashCleanup(pJob->execTasks); + taosHashCleanup(pJob->failTasks); + taosHashCleanup(pJob->succTasks); + + taosArrayDestroy(pJob->levels); + + tfree(pJob->res); + + tfree(pJob); + } + + void schedulerDestroy(void) { + if (schMgmt.jobs) { + taosHashCleanup(schMgmt.jobs); //TODO + schMgmt.jobs = NULL; + } } -} - diff --git a/source/libs/scheduler/test/schedulerTests.cpp b/source/libs/scheduler/test/schedulerTests.cpp index 790778b736..70e49e6b45 100644 --- a/source/libs/scheduler/test/schedulerTests.cpp +++ b/source/libs/scheduler/test/schedulerTests.cpp @@ -36,7 +36,7 @@ namespace { -extern "C" int32_t schProcessRspMsg(SSchJob *job, SSchTask *task, int32_t msgType, char *msg, int32_t msgSize, int32_t rspCode); +extern "C" int32_t schHandleResponseMsg(SSchJob *job, SSchTask *task, int32_t msgType, char *msg, int32_t msgSize, int32_t rspCode); void schtBuildQueryDag(SQueryDag *dag) { uint64_t qId = 0x0000000000000001; @@ -186,9 +186,9 @@ void *schtSendRsp(void *param) { while (pIter) { SSchTask *task = *(SSchTask **)pIter; - SShellSubmitRspMsg rsp = {0}; + SShellSubmitRsp rsp = {0}; rsp.affectedRows = 10; - schProcessRspMsg(job, task, TDMT_VND_SUBMIT, (char *)&rsp, sizeof(rsp), 0); + schHandleResponseMsg(job, task, TDMT_VND_SUBMIT, (char *)&rsp, sizeof(rsp), 0); pIter = taosHashIterate(job->execTasks, pIter); } @@ -233,7 +233,7 @@ TEST(queryTest, normalCase) { SSchTask *task = *(SSchTask **)pIter; SQueryTableRsp rsp = {0}; - code = schProcessRspMsg(job, task, TDMT_VND_QUERY, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(job, task, TDMT_VND_QUERY, (char *)&rsp, sizeof(rsp), 0); ASSERT_EQ(code, 0); pIter = taosHashIterate(job->execTasks, pIter); @@ -244,7 +244,7 @@ TEST(queryTest, normalCase) { SSchTask *task = *(SSchTask **)pIter; SResReadyRsp rsp = {0}; - code = schProcessRspMsg(job, task, TDMT_VND_RES_READY, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(job, task, TDMT_VND_RES_READY, (char *)&rsp, sizeof(rsp), 0); ASSERT_EQ(code, 0); pIter = taosHashIterate(job->execTasks, pIter); @@ -255,7 +255,7 @@ TEST(queryTest, normalCase) { SSchTask *task = *(SSchTask **)pIter; SQueryTableRsp rsp = {0}; - code = schProcessRspMsg(job, task, TDMT_VND_QUERY, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(job, task, TDMT_VND_QUERY, (char *)&rsp, sizeof(rsp), 0); ASSERT_EQ(code, 0); pIter = taosHashIterate(job->execTasks, pIter); @@ -266,7 +266,7 @@ TEST(queryTest, normalCase) { SSchTask *task = *(SSchTask **)pIter; SResReadyRsp rsp = {0}; - code = schProcessRspMsg(job, task, TDMT_VND_RES_READY, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(job, task, TDMT_VND_RES_READY, (char *)&rsp, sizeof(rsp), 0); ASSERT_EQ(code, 0); pIter = taosHashIterate(job->execTasks, pIter); @@ -275,7 +275,7 @@ TEST(queryTest, normalCase) { SRetrieveTableRsp rsp = {0}; rsp.completed = 1; rsp.numOfRows = 10; - code = schProcessRspMsg(job, NULL, TDMT_VND_FETCH, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(job, NULL, TDMT_VND_FETCH, (char *)&rsp, sizeof(rsp), 0); ASSERT_EQ(code, 0); diff --git a/source/libs/tfs/CMakeLists.txt b/source/libs/tfs/CMakeLists.txt new file mode 100644 index 0000000000..1b6f662507 --- /dev/null +++ b/source/libs/tfs/CMakeLists.txt @@ -0,0 +1,9 @@ +aux_source_directory(src TFS_SRC) +add_library(tfs STATIC ${TFS_SRC}) +target_include_directories( + tfs + PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/tfs" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" +) + +target_link_libraries(tfs os util common) \ No newline at end of file diff --git a/src/tfs/inc/tfsint.h b/source/libs/tfs/inc/tfsint.h similarity index 100% rename from src/tfs/inc/tfsint.h rename to source/libs/tfs/inc/tfsint.h diff --git a/src/tfs/src/tdisk.c b/source/libs/tfs/src/tdisk.c similarity index 100% rename from src/tfs/src/tdisk.c rename to source/libs/tfs/src/tdisk.c diff --git a/src/tfs/src/tfs.c b/source/libs/tfs/src/tfs.c similarity index 97% rename from src/tfs/src/tfs.c rename to source/libs/tfs/src/tfs.c index 547f862c20..83d9905511 100644 --- a/src/tfs/src/tfs.c +++ b/source/libs/tfs/src/tfs.c @@ -15,11 +15,11 @@ #include "os.h" -#include "hash.h" #include "taosdef.h" #include "taoserror.h" #include "tfs.h" #include "tfsint.h" +#include "thash.h" #define TMPNAME_LEN (TSDB_FILENAME_LEN * 2 + 32) @@ -270,7 +270,8 @@ int tfsMkdirRecurAt(const char *rname, int level, int id) { // Some platform may modify the contents of the string passed into dirname(). Others may return a pointer to // internal static storage space that will be overwritten by next call. For case like that, we should not use // the pointer directly in this recursion. - // See https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dirname.3.html + // See + // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dirname.3.html char *dir = strdup(dirname(s)); if (tfsMkdirRecurAt(dir, level, id) < 0) { @@ -334,7 +335,7 @@ int tfsRename(char *orname, char *nrname) { snprintf(oaname, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), orname); snprintf(naname, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), nrname); - taosRename(oaname, naname); + taosRenameFile(oaname, naname); } } @@ -504,7 +505,6 @@ static int tfsFormatDir(char *idir, char *odir) { wordfree(&wep); return 0; - } static int tfsCheck() { @@ -599,12 +599,10 @@ void taosGetDisk() { SysDiskSize diskSize; SFSMeta fsMeta; - if (tscEmbedded) { - tfsUpdateInfo(&fsMeta, NULL, 0); - tsTotalDataDirGB = (float)(fsMeta.tsize / unit); - tsUsedDataDirGB = (float)(fsMeta.used / unit); - tsAvailDataDirGB = (float)(fsMeta.avail / unit); - } + tfsUpdateInfo(&fsMeta, NULL, 0); + tsTotalDataDirGB = (float)(fsMeta.tsize / unit); + tsUsedDataDirGB = (float)(fsMeta.used / unit); + tsAvailDataDirGB = (float)(fsMeta.avail / unit); if (taosGetDiskSize(tsLogDir, &diskSize) == 0) { tsTotalLogDirGB = (float)(diskSize.tsize / unit); diff --git a/src/tfs/src/ttier.c b/source/libs/tfs/src/ttier.c similarity index 100% rename from src/tfs/src/ttier.c rename to source/libs/tfs/src/ttier.c diff --git a/source/libs/tkv/CMakeLists.txt b/source/libs/tkv/CMakeLists.txt index 529b2703f7..0620e12f55 100644 --- a/source/libs/tkv/CMakeLists.txt +++ b/source/libs/tkv/CMakeLists.txt @@ -8,10 +8,4 @@ target_include_directories( target_link_libraries( tkv PUBLIC os -) -if(${BUILD_WITH_ROCKSDB}) - target_link_libraries( - tkv - PUBLIC rocksdb - ) -endif(${BUILD_WITH_ROCKSDB}) +) \ No newline at end of file diff --git a/source/libs/tkv/inc/tDiskMgr.h b/source/libs/tkv/inc/tDiskMgr.h new file mode 100644 index 0000000000..03622284f4 --- /dev/null +++ b/source/libs/tkv/inc/tDiskMgr.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_TDISK_MGR_H_ +#define _TD_TDISK_MGR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os.h" + +#include "tkvDef.h" + +typedef struct SDiskMgr SDiskMgr; + +int tdmOpen(SDiskMgr **ppDiskMgr, const char *fname, uint16_t pgsize); +int tdmClose(SDiskMgr *pDiskMgr); +int tdmReadPage(SDiskMgr *pDiskMgr, pgid_t pgid, void *pData); +int tdmWritePage(SDiskMgr *pDiskMgr, pgid_t pgid, const void *pData); +int32_t tdmAllocPage(SDiskMgr *pDiskMgr); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_TDISK_MGR_H_*/ \ No newline at end of file diff --git a/source/libs/tkv/src/tkvRocksdb.c b/source/libs/tkv/inc/tPage.h similarity index 59% rename from source/libs/tkv/src/tkvRocksdb.c rename to source/libs/tkv/inc/tPage.h index 6dea4a4e57..0546f6184f 100644 --- a/source/libs/tkv/src/tkvRocksdb.c +++ b/source/libs/tkv/inc/tPage.h @@ -11,4 +11,31 @@ * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . - */ \ No newline at end of file + */ + +#ifndef _TD_TKV_PAGE_H_ +#define _TD_TKV_PAGE_H_ + +#include "os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint16_t dbver; + uint16_t pgsize; + uint32_t cksm; +} SPgHdr; + +typedef struct { + SPgHdr chdr; + uint16_t used; // number of used slots + uint16_t loffset; // the offset of the starting location of the last slot used +} SSlottedPgHdr; + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_TKV_PAGE_H_*/ \ No newline at end of file diff --git a/source/libs/tkv/inc/tkvDef.h b/source/libs/tkv/inc/tkvDef.h index 7433b1a4dd..6f1072abd5 100644 --- a/source/libs/tkv/inc/tkvDef.h +++ b/source/libs/tkv/inc/tkvDef.h @@ -16,40 +16,15 @@ #ifndef _TD_TKV_DEF_H_ #define _TD_TKV_DEF_H_ -#ifdef USE_ROCKSDB -#include -#endif +#include "os.h" #ifdef __cplusplus extern "C" { #endif -struct STkvDb { -#ifdef USE_ROCKSDB - rocksdb_t *db; -#endif -}; -struct STkvOpts { -#ifdef USE_ROCKSDB - rocksdb_options_t *opts; -#endif -}; - -struct STkvCache { - // TODO -}; - -struct STkvReadOpts { -#ifdef USE_ROCKSDB - rocksdb_readoptions_t *ropts; -#endif -}; - -struct STkvWriteOpts { -#ifdef USE_ROCKSDB - rocksdb_writeoptions_t *wopts; -#endif -}; +// pgid_t +typedef int32_t pgid_t; +#define TKV_IVLD_PGID ((pgid_t)-1) #ifdef __cplusplus } diff --git a/source/libs/tkv/src/tDiskMgr.c b/source/libs/tkv/src/tDiskMgr.c new file mode 100644 index 0000000000..d759171f85 --- /dev/null +++ b/source/libs/tkv/src/tDiskMgr.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "tDiskMgr.h" + +struct SDiskMgr { + const char *fname; + uint16_t pgsize; + FileFd fd; + int32_t npgid; +}; + +#define PAGE_OFFSET(PGID, PGSIZE) ((PGID) * (PGSIZE)) + +int tdmOpen(SDiskMgr **ppDiskMgr, const char *fname, uint16_t pgsize) { + // TODO + return 0; +} + +int tdmClose(SDiskMgr *pDiskMgr) { + // TODO + return 0; +} + +int tdmReadPage(SDiskMgr *pDiskMgr, pgid_t pgid, void *pData) { + taosLSeekFile(pDiskMgr->fd, PAGE_OFFSET(pgid, pDiskMgr->pgsize), SEEK_SET); + taosReadFile(pDiskMgr->fd, pData, pDiskMgr->pgsize); + return 0; +} + +int tdmWritePage(SDiskMgr *pDiskMgr, pgid_t pgid, const void *pData) { + taosLSeekFile(pDiskMgr->fd, PAGE_OFFSET(pgid, pDiskMgr->pgsize), SEEK_SET); + taosWriteFile(pDiskMgr->fd, pData, pDiskMgr->pgsize); + return 0; +} + +int32_t tdmAllocPage(SDiskMgr *pDiskMgr) { return pDiskMgr->npgid++; } \ No newline at end of file diff --git a/source/libs/tkv/src/tkv.c b/source/libs/tkv/src/tkv.c deleted file mode 100644 index 0c6f896d56..0000000000 --- a/source/libs/tkv/src/tkv.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include "tkv.h" -#include "tkvDef.h" - -static pthread_once_t isInit = PTHREAD_ONCE_INIT; -static STkvReadOpts defaultReadOpts; -static STkvWriteOpts defaultWriteOpts; - -static void tkvInit(); - -STkvDb *tkvOpen(const STkvOpts *options, const char *path) { - pthread_once(&isInit, tkvInit); - STkvDb *pDb = NULL; - - pDb = (STkvDb *)malloc(sizeof(*pDb)); - if (pDb == NULL) { - return NULL; - } - -#ifdef USE_ROCKSDB - char *err = NULL; - - pDb->db = rocksdb_open(options->opts, path, &err); - // TODO: check err -#endif - - return pDb; -} - -void tkvClose(STkvDb *pDb) { - if (pDb) { -#ifdef USE_ROCKSDB - rocksdb_close(pDb->db); -#endif - free(pDb); - } -} - -void tkvPut(STkvDb *pDb, const STkvWriteOpts *pwopts, const char *key, size_t keylen, const char *val, size_t vallen) { -#ifdef USE_ROCKSDB - char *err = NULL; - rocksdb_put(pDb->db, pwopts ? pwopts->wopts : defaultWriteOpts.wopts, key, keylen, val, vallen, &err); - // TODO: check error -#endif -} - -char *tkvGet(STkvDb *pDb, const STkvReadOpts *propts, const char *key, size_t keylen, size_t *vallen) { - char *ret = NULL; - -#ifdef USE_ROCKSDB - char *err = NULL; - ret = rocksdb_get(pDb->db, propts ? propts->ropts : defaultReadOpts.ropts, key, keylen, vallen, &err); - // TODD: check error -#endif - - return ret; -} - -STkvOpts *tkvOptsCreate() { - STkvOpts *pOpts = NULL; - - pOpts = (STkvOpts *)malloc(sizeof(*pOpts)); - if (pOpts == NULL) { - return NULL; - } - -#ifdef USE_ROCKSDB - pOpts->opts = rocksdb_options_create(); - // TODO: check error -#endif - - return pOpts; -} - -void tkvOptsDestroy(STkvOpts *pOpts) { - if (pOpts) { -#ifdef USE_ROCKSDB - rocksdb_options_destroy(pOpts->opts); -#endif - free(pOpts); - } -} - -void tkvOptionsSetCache(STkvOpts *popts, STkvCache *pCache) { - // TODO -} - -void tkvOptsSetCreateIfMissing(STkvOpts *pOpts, unsigned char c) { -#ifdef USE_ROCKSDB - rocksdb_options_set_create_if_missing(pOpts->opts, c); -#endif -} - -STkvReadOpts *tkvReadOptsCreate() { - STkvReadOpts *pReadOpts = NULL; - - pReadOpts = (STkvReadOpts *)malloc(sizeof(*pReadOpts)); - if (pReadOpts == NULL) { - return NULL; - } - -#ifdef USE_ROCKSDB - pReadOpts->ropts = rocksdb_readoptions_create(); -#endif - - return pReadOpts; -} - -void tkvReadOptsDestroy(STkvReadOpts *pReadOpts) { - if (pReadOpts) { -#ifdef USE_ROCKSDB - rocksdb_readoptions_destroy(pReadOpts->ropts); -#endif - free(pReadOpts); - } -} - -STkvWriteOpts *tkvWriteOptsCreate() { - STkvWriteOpts *pWriteOpts = NULL; - - pWriteOpts = (STkvWriteOpts *)malloc(sizeof(*pWriteOpts)); - if (pWriteOpts == NULL) { - return NULL; - } - -#ifdef USE_ROCKSDB - pWriteOpts->wopts = rocksdb_writeoptions_create(); -#endif - - return pWriteOpts; -} - -void tkvWriteOptsDestroy(STkvWriteOpts *pWriteOpts) { - if (pWriteOpts) { -#ifdef USE_ROCKSDB - rocksdb_writeoptions_destroy(pWriteOpts->wopts); -#endif - free(pWriteOpts); - } -} - -/* ------------------------ STATIC METHODS ------------------------ */ -static void tkvInit() { -#ifdef USE_ROCKSDB - defaultReadOpts.ropts = rocksdb_readoptions_create(); - defaultWriteOpts.wopts = rocksdb_writeoptions_create(); - rocksdb_writeoptions_disable_WAL(defaultWriteOpts.wopts, true); - -#endif -} - -static void tkvClear() { -#ifdef USE_ROCKSDB - rocksdb_readoptions_destroy(defaultReadOpts.ropts); - rocksdb_writeoptions_destroy(defaultWriteOpts.wopts); -#endif -} diff --git a/source/libs/tkv/test/tDiskMgrTest.cpp b/source/libs/tkv/test/tDiskMgrTest.cpp new file mode 100644 index 0000000000..a735fdb33d --- /dev/null +++ b/source/libs/tkv/test/tDiskMgrTest.cpp @@ -0,0 +1,10 @@ +#include "gtest/gtest.h" + +#include "iostream" + +#include "tDiskMgr.h" + +TEST(tDiskMgrTest, simple_test) { + // TODO + std::cout << "This is in tDiskMgrTest::simple_test" << std::endl; +} \ No newline at end of file diff --git a/source/libs/transport/src/rpcMain.c b/source/libs/transport/src/rpcMain.c index a7b9bfedbe..d58ea63c4f 100644 --- a/source/libs/transport/src/rpcMain.c +++ b/source/libs/transport/src/rpcMain.c @@ -423,6 +423,8 @@ void rpcSendRequest(void *shandle, const SEpSet *pEpSet, SRpcMsg *pMsg, int64_t } void rpcSendResponse(const SRpcMsg *pRsp) { + if (pRsp->handle == NULL) return; + int msgLen = 0; SRpcConn *pConn = (SRpcConn *)pRsp->handle; SRpcMsg rpcMsg = *pRsp; @@ -1198,7 +1200,7 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqConte } rpcSendReqToServer(pRpc, pContext); rpcFreeCont(rpcMsg.pCont); - } else if (pHead->code == TSDB_CODE_RPC_NOT_READY || pHead->code == TSDB_CODE_APP_NOT_READY || pHead->code == TSDB_CODE_DND_EXITING) { + } else if (pHead->code == TSDB_CODE_RPC_NOT_READY || pHead->code == TSDB_CODE_APP_NOT_READY || pHead->code == TSDB_CODE_DND_OFFLINE) { pContext->code = pHead->code; rpcProcessConnError(pContext, NULL); rpcFreeCont(rpcMsg.pCont); diff --git a/source/libs/wal/inc/walInt.h b/source/libs/wal/inc/walInt.h index 871c95193f..7631593dd8 100644 --- a/source/libs/wal/inc/walInt.h +++ b/source/libs/wal/inc/walInt.h @@ -131,6 +131,7 @@ int walMetaDeserialize(SWal* pWal, const char* bytes); // seek section int walChangeFile(SWal* pWal, int64_t ver); +int walChangeFileToLast(SWal* pWal); // seek section end int64_t walGetSeq(); diff --git a/source/libs/wal/src/walMeta.c b/source/libs/wal/src/walMeta.c index 0f155f9553..270a26bf80 100644 --- a/source/libs/wal/src/walMeta.c +++ b/source/libs/wal/src/walMeta.c @@ -184,6 +184,7 @@ int walMetaDeserialize(SWal* pWal, const char* bytes) { } taosArraySetSize(pArray, sz); pWal->fileInfoSet = pArray; + pWal->writeCur = sz - 1; cJSON_Delete(pRoot); return 0; } @@ -261,15 +262,18 @@ int walLoadMeta(SWal* pWal) { memset(buf, 0, size + 5); int tfd = tfOpenRead(fnameStr); if (tfRead(tfd, buf, size) != size) { + tfClose(tfd); free(buf); return -1; } // load into fileInfoSet int code = walMetaDeserialize(pWal, buf); if (code != 0) { + tfClose(tfd); free(buf); return -1; } + tfClose(tfd); free(buf); return 0; } diff --git a/source/libs/wal/src/walMgmt.c b/source/libs/wal/src/walMgmt.c index 189881c86d..d12acb52c6 100644 --- a/source/libs/wal/src/walMgmt.c +++ b/source/libs/wal/src/walMgmt.c @@ -232,7 +232,8 @@ static int32_t walCreateThread() { if (pthread_create(&tsWal.thread, &thAttr, walThreadFunc, NULL) != 0) { wError("failed to create wal thread since %s", strerror(errno)); - return TAOS_SYSTEM_ERROR(errno); + terrno = TAOS_SYSTEM_ERROR(errno); + return -1; } pthread_attr_destroy(&thAttr); diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index b5a30e4397..96d0c6c385 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -15,6 +15,7 @@ #include "tfile.h" #include "walInt.h" +#include "taoserror.h" SWalReadHandle *walOpenReadHandle(SWal *pWal) { SWalReadHandle *pRead = malloc(sizeof(SWalReadHandle)); @@ -32,6 +33,7 @@ SWalReadHandle *walOpenReadHandle(SWal *pWal) { pRead->status = 0; pRead->pHead = malloc(sizeof(SWalHead)); if (pRead->pHead == NULL) { + terrno = TSDB_CODE_WAL_OUT_OF_MEMORY; free(pRead); return NULL; } @@ -57,16 +59,19 @@ static int32_t walReadSeekFilePos(SWalReadHandle *pRead, int64_t fileFirstVer, i int64_t offset = (ver - fileFirstVer) * sizeof(SWalIdxEntry); code = tfLseek(idxTfd, offset, SEEK_SET); if (code < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } SWalIdxEntry entry; if (tfRead(idxTfd, &entry, sizeof(SWalIdxEntry)) != sizeof(SWalIdxEntry)) { + terrno = TSDB_CODE_WAL_FILE_CORRUPTED; return -1; } // TODO:deserialize ASSERT(entry.ver == ver); code = tfLseek(logTfd, entry.offset, SEEK_SET); if (code < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } return code; @@ -81,6 +86,7 @@ static int32_t walReadChangeFile(SWalReadHandle *pRead, int64_t fileFirstVer) { walBuildLogName(pRead->pWal, fileFirstVer, fnameStr); int64_t logTfd = tfOpenRead(fnameStr); if (logTfd < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } @@ -102,6 +108,7 @@ static int32_t walReadSeekVer(SWalReadHandle *pRead, int64_t ver) { return 0; } if (ver > pWal->vers.lastVer || ver < pWal->vers.firstVer) { + terrno = TSDB_CODE_WAL_INVALID_VER; return -1; } if (ver < pWal->vers.snapshotVer) { @@ -115,7 +122,6 @@ static int32_t walReadSeekVer(SWalReadHandle *pRead, int64_t ver) { if (pRead->curFileFirstVer != pRet->firstVer) { code = walReadChangeFile(pRead, pRet->firstVer); if (code < 0) { - // TODO: set error flag return -1; } } @@ -134,7 +140,7 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) { // TODO: check wal life if (pRead->curVersion != ver) { code = walReadSeekVer(pRead, ver); - if (code != 0) { + if (code < 0) { return -1; } } @@ -147,11 +153,13 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) { } code = walValidHeadCksum(pRead->pHead); if (code != 0) { + terrno = TSDB_CODE_WAL_FILE_CORRUPTED; return -1; } if (pRead->capacity < pRead->pHead->head.len) { void *ptr = realloc(pRead->pHead, sizeof(SWalHead) + pRead->pHead->head.len); if (ptr == NULL) { + terrno = TSDB_CODE_WAL_OUT_OF_MEMORY; return -1; } pRead->pHead = ptr; @@ -165,6 +173,7 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) { code = walValidBodyCksum(pRead->pHead); if (code != 0) { + terrno = TSDB_CODE_WAL_FILE_CORRUPTED; return -1; } pRead->curVersion++; diff --git a/source/libs/wal/src/walSeek.c b/source/libs/wal/src/walSeek.c index 1f9b7b6e58..1d9f7bdf4d 100644 --- a/source/libs/wal/src/walSeek.c +++ b/source/libs/wal/src/walSeek.c @@ -30,17 +30,20 @@ static int walSeekFilePos(SWal* pWal, int64_t ver) { int64_t idxOff = walGetVerIdxOffset(pWal, ver); code = tfLseek(idxTfd, idxOff, SEEK_SET); if (code != 0) { + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } SWalIdxEntry entry; // TODO:deserialize code = tfRead(idxTfd, &entry, sizeof(SWalIdxEntry)); if (code != 0) { + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } ASSERT(entry.ver == ver); code = tfLseek(logTfd, entry.offset, SEEK_CUR); if (code < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } return code; @@ -56,11 +59,13 @@ int walChangeFileToLast(SWal* pWal) { walBuildIdxName(pWal, fileFirstVer, fnameStr); idxTfd = tfOpenReadWrite(fnameStr); if (idxTfd < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } walBuildLogName(pWal, fileFirstVer, fnameStr); logTfd = tfOpenReadWrite(fnameStr); if (logTfd < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } // switch file @@ -76,11 +81,12 @@ int walChangeFile(SWal* pWal, int64_t ver) { code = tfClose(pWal->writeLogTfd); if (code != 0) { // TODO + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } code = tfClose(pWal->writeIdxTfd); if (code != 0) { - // TODO + terrno = TAOS_SYSTEM_ERROR(errno); return -1; } SWalFileInfo tmpInfo; @@ -113,6 +119,7 @@ int walSeekVer(SWal* pWal, int64_t ver) { return 0; } if (ver > pWal->vers.lastVer || ver < pWal->vers.firstVer) { + terrno = TSDB_CODE_WAL_INVALID_VER; return -1; } if (ver < pWal->vers.snapshotVer) { diff --git a/source/libs/wal/src/walWrite.c b/source/libs/wal/src/walWrite.c index 05750d6446..975f232e3d 100644 --- a/source/libs/wal/src/walWrite.c +++ b/source/libs/wal/src/walWrite.c @@ -25,6 +25,7 @@ int32_t walCommit(SWal *pWal, int64_t ver) { ASSERT(pWal->vers.commitVer >= pWal->vers.snapshotVer); ASSERT(pWal->vers.commitVer <= pWal->vers.lastVer); if (ver < pWal->vers.commitVer || ver > pWal->vers.lastVer) { + terrno = TSDB_CODE_WAL_INVALID_VER; return -1; } pWal->vers.commitVer = ver; @@ -38,6 +39,7 @@ int32_t walRollback(SWal *pWal, int64_t ver) { return 0; } if (ver > pWal->vers.lastVer || ver < pWal->vers.commitVer) { + terrno = TSDB_CODE_WAL_INVALID_VER; return -1; } pthread_mutex_lock(&pWal->mutex); @@ -242,6 +244,7 @@ int walRoll(SWal *pWal) { pWal->writeIdxTfd = idxTfd; pWal->writeLogTfd = logTfd; pWal->writeCur = taosArrayGetSize(pWal->fileInfoSet) - 1; + ASSERT(pWal->writeCur >= 0); pWal->lastRollSeq = walGetSeq(); return 0; @@ -251,6 +254,7 @@ static int walWriteIndex(SWal *pWal, int64_t ver, int64_t offset) { SWalIdxEntry entry = {.ver = ver, .offset = offset}; int size = tfWrite(pWal->writeIdxTfd, &entry, sizeof(SWalIdxEntry)); if (size != sizeof(SWalIdxEntry)) { + terrno = TAOS_SYSTEM_ERROR(errno); // TODO truncate return -1; } @@ -284,7 +288,13 @@ int64_t walWrite(SWal *pWal, int64_t index, uint8_t msgType, const void *body, i } /*if (!tfValid(pWal->writeLogTfd)) return -1;*/ + ASSERT(pWal->writeCur >= 0); + pthread_mutex_lock(&pWal->mutex); + if (pWal->writeIdxTfd == -1 || pWal->writeLogTfd == -1) { + walChangeFileToLast(pWal); + } + pWal->writeHead.head.version = index; int64_t offset = walGetCurFileOffset(pWal); @@ -306,6 +316,7 @@ int64_t walWrite(SWal *pWal, int64_t index, uint8_t msgType, const void *body, i wError("vgId:%d, file:%" PRId64 ".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal), strerror(errno)); } + code = walWriteIndex(pWal, index, offset); if (code != 0) { // TODO diff --git a/source/os/src/osFile.c b/source/os/src/osFile.c index bdf3a53dcb..60155c8fb9 100644 --- a/source/os/src/osFile.c +++ b/source/os/src/osFile.c @@ -120,7 +120,7 @@ int64_t taosReadFile(FileFd fd, void *buf, int64_t count) { return count; } -int64_t taosWriteFile(FileFd fd, void *buf, int64_t n) { +int64_t taosWriteFile(FileFd fd, const void *buf, int64_t n) { int64_t nleft = n; int64_t nwritten = 0; char * tbuf = (char *)buf; diff --git a/source/util/src/terror.c b/source/util/src/terror.c index e821f1f803..3ea564722b 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -253,37 +253,36 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_NOT_EXIST, "Transaction not exis // dnode TAOS_DEFINE_ERROR(TSDB_CODE_DND_ACTION_IN_PROGRESS, "Action in progress") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_EXITING, "Dnode is exiting") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_OFFLINE, "Dnode is offline") TAOS_DEFINE_ERROR(TSDB_CODE_DND_INVALID_MSG_LEN, "Invalid message length") TAOS_DEFINE_ERROR(TSDB_CODE_DND_DNODE_READ_FILE_ERROR, "Read dnode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_DNODE_WRITE_FILE_ERROR, "Write dnode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED, "Mnode already deployed") TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_NOT_DEPLOYED, "Mnode not deployed") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_ID_INVALID, "Mnode Id invalid") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_ID_NOT_FOUND, "Mnode Id not found") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_INVALID_OPTION, "Mnode option invalid") TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_READ_FILE_ERROR, "Read mnode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_WRITE_FILE_ERROR, "Write mnode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_QNODE_ALREADY_DEPLOYED, "Qnode already deployed") TAOS_DEFINE_ERROR(TSDB_CODE_DND_QNODE_NOT_DEPLOYED, "Qnode not deployed") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_QNODE_ID_INVALID, "Qnode Id invalid") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_QNODE_ID_NOT_FOUND, "Qnode Id not found") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_QNODE_INVALID_OPTION, "Qnode option invalid") TAOS_DEFINE_ERROR(TSDB_CODE_DND_QNODE_READ_FILE_ERROR, "Read qnode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_QNODE_WRITE_FILE_ERROR, "Write qnode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_SNODE_ALREADY_DEPLOYED, "Snode already deployed") TAOS_DEFINE_ERROR(TSDB_CODE_DND_SNODE_NOT_DEPLOYED, "Snode not deployed") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_SNODE_ID_INVALID, "Snode Id invalid") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_SNODE_ID_NOT_FOUND, "Snode Id not found") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_SNODE_INVALID_OPTION, "Snode option invalid") TAOS_DEFINE_ERROR(TSDB_CODE_DND_SNODE_READ_FILE_ERROR, "Read snode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_SNODE_WRITE_FILE_ERROR, "Write snode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_BNODE_ALREADY_DEPLOYED, "Bnode already deployed") TAOS_DEFINE_ERROR(TSDB_CODE_DND_BNODE_NOT_DEPLOYED, "Bnode not deployed") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_BNODE_ID_INVALID, "Bnode Id invalid") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_BNODE_ID_NOT_FOUND, "Bnode Id not found") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_BNODE_INVALID_OPTION, "Bnode option invalid") TAOS_DEFINE_ERROR(TSDB_CODE_DND_BNODE_READ_FILE_ERROR, "Read bnode.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_BNODE_WRITE_FILE_ERROR, "Write bnode.json error") -TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_TOO_MANY_VNODES, "Too many vnode directories") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED, "Vnode already deployed") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_NOT_DEPLOYED, "Vnode not deployed") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_INVALID_OPTION, "Vnode option invalid") TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_READ_FILE_ERROR, "Read vnodes.json error") TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_WRITE_FILE_ERROR, "Write vnodes.json error") +TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_TOO_MANY_VNODES, "Too many vnodes") // vnode TAOS_DEFINE_ERROR(TSDB_CODE_VND_ACTION_IN_PROGRESS, "Action in progress") diff --git a/source/util/src/thash.c b/source/util/src/thash.c index f90b157558..2b013bfdd0 100644 --- a/source/util/src/thash.c +++ b/source/util/src/thash.c @@ -19,8 +19,9 @@ #include "taos.h" #include "tdef.h" -#define EXT_SIZE 1024 - +// the add ref count operation may trigger the warning if the reference count is greater than the MAX_WARNING_REF_COUNT +#define MAX_WARNING_REF_COUNT 10000 +#define EXT_SIZE 1024 #define HASH_NEED_RESIZE(_h) ((_h)->size >= (_h)->capacity * HASH_DEFAULT_LOAD_FACTOR) #define DO_FREE_HASH_NODE(_n) \ @@ -214,7 +215,7 @@ static FORCE_INLINE bool taosHashTableEmpty(const SHashObj *pHashObj) { return taosHashGetSize(pHashObj) == 0; } -int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size) { +int32_t taosHashPutImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size, bool *newAdded) { uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen); SHashNode *pNewNode = doCreateHashNode(key, keyLen, data, size, hashVal); if (pNewNode == NULL) { @@ -273,6 +274,10 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da __rd_unlock((void*) &pHashObj->lock, pHashObj->type); atomic_add_fetch_32(&pHashObj->size, 1); + if (newAdded) { + *newAdded = true; + } + return 0; } else { // not support the update operation, return error @@ -289,10 +294,23 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da // enable resize __rd_unlock((void*) &pHashObj->lock, pHashObj->type); + if (newAdded) { + *newAdded = false; + } + return pHashObj->enableUpdate ? 0 : -2; } } +int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size) { + return taosHashPutImpl(pHashObj, key, keyLen, data, size, NULL); +} + +int32_t taosHashPutExt(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size, bool *newAdded) { + return taosHashPutImpl(pHashObj, key, keyLen, data, size, newAdded); +} + + void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen) { return taosHashGetClone(pHashObj, key, keyLen, NULL); } @@ -794,11 +812,18 @@ FORCE_INLINE int32_t taosHashGetKey(void *data, void** key, size_t* keyLen) { SHashNode * node = GET_HASH_PNODE(data); *key = GET_HASH_NODE_KEY(node); - *keyLen = node->keyLen; + if (keyLen) { + *keyLen = node->keyLen; + } return 0; } +FORCE_INLINE int32_t taosHashGetDataLen(void *data) { + SHashNode * node = GET_HASH_PNODE(data); + return node->keyLen; +} + FORCE_INLINE uint32_t taosHashGetDataKeyLen(SHashObj *pHashObj, void *data) { SHashNode * node = GET_HASH_PNODE(data); return node->keyLen; @@ -902,8 +927,24 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) { if (pNode) { SHashEntry *pe = pHashObj->hashList[slot]; - pNode->count++; - data = GET_HASH_NODE_DATA(pNode); + + uint16_t prevRef = atomic_load_16(&pNode->count); + uint16_t afterRef = atomic_add_fetch_16(&pNode->count, 1); + + // the reference count value is overflow, which will cause the delete node operation immediately. + if (prevRef > afterRef) { + uError("hash entry ref count overflow, prev ref:%d, current ref:%d", prevRef, afterRef); + // restore the value + atomic_sub_fetch_16(&pNode->count, 1); + data = NULL; + } else { + data = GET_HASH_NODE_DATA(pNode); + } + + if (afterRef >= MAX_WARNING_REF_COUNT) { + uWarn("hash entry ref count is abnormally high: %d", afterRef); + } + if (pHashObj->type == HASH_ENTRY_LOCK) { taosWUnLockLatch(&pe->latch); } @@ -911,7 +952,6 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) { __rd_unlock((void*) &pHashObj->lock, pHashObj->type); return data; - } void taosHashCancelIterate(SHashObj *pHashObj, void *p) { diff --git a/source/util/src/tlog.c b/source/util/src/tlog.c index 95f2fe76e6..c284efbcd4 100644 --- a/source/util/src/tlog.c +++ b/source/util/src/tlog.c @@ -95,7 +95,6 @@ int32_t tsdbDebugFlag = 131; int32_t tqDebugFlag = 131; int32_t cqDebugFlag = 131; int32_t fsDebugFlag = 135; -int32_t ctgDebugFlag = 131; int64_t dbgEmptyW = 0; int64_t dbgWN = 0; diff --git a/source/util/src/tqueue.c b/source/util/src/tqueue.c index 75f5e9cdbc..5cb149d53c 100644 --- a/source/util/src/tqueue.c +++ b/source/util/src/tqueue.c @@ -112,6 +112,13 @@ bool taosQueueEmpty(STaosQueue *queue) { return empty; } +int32_t taosQueueSize(STaosQueue *queue) { + pthread_mutex_lock(&queue->mutex); + int32_t numOfItems = queue->numOfItems; + pthread_mutex_unlock(&queue->mutex); + return numOfItems; +} + void *taosAllocateQitem(int32_t size) { STaosQnode *pNode = (STaosQnode *)calloc(sizeof(STaosQnode) + size, 1); diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index e4b1602661..43e7365a59 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -226,7 +226,7 @@ void tscKillStream(STscObj *pObj, uint32_t killId) { } int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) { - SHeartBeatMsg *pHeartbeat = pMsg; + SHeartBeatReq *pHeartbeat = pMsg; int allocedQueriesNum = pHeartbeat->numOfQueries; int allocedStreamsNum = pHeartbeat->numOfStreams; @@ -327,7 +327,7 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) { } int32_t msgLen = pHeartbeat->numOfQueries * sizeof(SQueryDesc) + pHeartbeat->numOfStreams * sizeof(SStreamDesc) + - sizeof(SHeartBeatMsg); + sizeof(SHeartBeatReq); pHeartbeat->connId = htonl(pObj->connId); pHeartbeat->numOfQueries = htonl(pHeartbeat->numOfQueries); pHeartbeat->numOfStreams = htonl(pHeartbeat->numOfStreams); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index eb3f8be25a..c68d7cef06 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -776,7 +776,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { char* pMsg = pCmd->payload; - SCfgDnodeMsg* pCfg = (SCfgDnodeMsg*)pMsg; + SMCfgDnodeReq* pCfg = (SMCfgDnodeReq*)pMsg; SStrToken* t0 = taosArrayGet(pMiscInfo->a, 0); SStrToken* t1 = taosArrayGet(pMiscInfo->a, 1); diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 42799927e6..41a55869e6 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -603,7 +603,7 @@ int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo) { } int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg *) pSql->cmd.payload; + SRetrieveTableReq *pRetrieveMsg = (SRetrieveTableReq *) pSql->cmd.payload; SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); @@ -638,10 +638,10 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pSql->res.qId); } - pSql->cmd.payloadLen = sizeof(SRetrieveTableMsg); + pSql->cmd.payloadLen = sizeof(SRetrieveTableReq); pSql->cmd.msgType = TDMT_VND_FETCH; - pRetrieveMsg->header.contLen = htonl(sizeof(SRetrieveTableMsg)); + pRetrieveMsg->header.contLen = htonl(sizeof(SRetrieveTableReq)); return TSDB_CODE_SUCCESS; } @@ -1192,13 +1192,13 @@ int32_t tscBuildCreateFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; - pCmd->payloadLen = sizeof(SCreateDnodeMsg); + pCmd->payloadLen = sizeof(SCreateDnodeReq); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self); return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SCreateDnodeMsg *pCreate = (SCreateDnodeMsg *)pCmd->payload; + SCreateDnodeReq *pCreate = (SCreateDnodeReq *)pCmd->payload; SStrToken* t0 = taosArrayGet(pInfo->pMiscInfo->a, 0); strncpy(pCreate->ep, t0->z, t0->n); @@ -1210,13 +1210,13 @@ int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int32_t tscBuildAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; - pCmd->payloadLen = sizeof(SCreateAcctMsg); + pCmd->payloadLen = sizeof(SCreateAcctReq); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self); return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SCreateAcctMsg *pAlterMsg = (SCreateAcctMsg *)pCmd->payload; + SCreateAcctReq *pAlterMsg = (SCreateAcctReq *)pCmd->payload; SStrToken *pName = &pInfo->pMiscInfo->user.user; SStrToken *pPwd = &pInfo->pMiscInfo->user.passwd; @@ -1255,14 +1255,14 @@ int32_t tscBuildAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; - pCmd->payloadLen = sizeof(SCreateUserMsg); + pCmd->payloadLen = sizeof(SCreateUserReq); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self); return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SCreateUserMsg *pAlterMsg = (SCreateUserMsg *)pCmd->payload; + SCreateUserReq *pAlterMsg = (SCreateUserReq *)pCmd->payload; SUserInfo *pUser = &pInfo->pMiscInfo->user; strncpy(pAlterMsg->user, pUser->user.z, pUser->user.n); @@ -1287,7 +1287,7 @@ int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int32_t tscBuildCfgDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; - pCmd->payloadLen = sizeof(SCfgDnodeMsg); + pCmd->payloadLen = sizeof(SMCfgDnodeReq); pCmd->msgType = TDMT_MND_CONFIG_DNODE; return TSDB_CODE_SUCCESS; } @@ -1350,13 +1350,13 @@ int32_t tscBuildDropDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { char dnodeEp[TSDB_EP_LEN] = {0}; tstrncpy(dnodeEp, pCmd->payload, TSDB_EP_LEN); - pCmd->payloadLen = sizeof(SDropDnodeMsg); + pCmd->payloadLen = sizeof(SDropDnodeReq); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self); return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SDropDnodeMsg * pDrop = (SDropDnodeMsg *)pCmd->payload; + SDropDnodeReq * pDrop = (SDropDnodeReq *)pCmd->payload; tstrncpy(pDrop->ep, dnodeEp, tListLen(pDrop->ep)); pCmd->msgType = TDMT_MND_DROP_DNODE; @@ -1369,7 +1369,7 @@ int32_t tscBuildDropUserAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) { char user[TSDB_USER_LEN] = {0}; tstrncpy(user, pCmd->payload, TSDB_USER_LEN); - pCmd->payloadLen = sizeof(SDropUserMsg); + pCmd->payloadLen = sizeof(SDropUserReq); pCmd->msgType = (pInfo->type == TSDB_SQL_DROP_USER)? TDMT_MND_DROP_USER:TDMT_MND_DROP_ACCT; if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { @@ -1377,7 +1377,7 @@ int32_t tscBuildDropUserAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SDropUserMsg *pDropMsg = (SDropUserMsg *)pCmd->payload; + SDropUserReq *pDropMsg = (SDropUserReq *)pCmd->payload; tstrncpy(pDropMsg->user, user, tListLen(user)); return TSDB_CODE_SUCCESS; @@ -1420,7 +1420,7 @@ int32_t tscBuildSyncDbReplicaMsg(SSqlObj* pSql, SSqlInfo *pInfo) { int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; pCmd->msgType = TDMT_MND_SHOW; - pCmd->payloadLen = sizeof(SShowMsg) + 100; + pCmd->payloadLen = sizeof(SShowReq) + 100; if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self); @@ -1428,13 +1428,13 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } SShowInfo *pShowInfo = &pInfo->pMiscInfo->showOpt; - SShowMsg *pShowMsg = (SShowMsg *)pCmd->payload; + SShowReq *pShowMsg = (SShowReq *)pCmd->payload; STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); if (pShowInfo->showType == TSDB_MGMT_TABLE_FUNCTION) { pShowMsg->type = pShowInfo->showType; pShowMsg->payloadLen = 0; - pCmd->payloadLen = sizeof(SShowMsg); + pCmd->payloadLen = sizeof(SShowReq); return TSDB_CODE_SUCCESS; } @@ -1463,13 +1463,13 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pShowMsg->payloadLen = htons(pEpAddr->n); } - pCmd->payloadLen = sizeof(SShowMsg) + htons(pShowMsg->payloadLen); + pCmd->payloadLen = sizeof(SShowReq) + htons(pShowMsg->payloadLen); return TSDB_CODE_SUCCESS; } int32_t tscBuildKillMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; - pCmd->payloadLen = sizeof(SKillQueryMsg); + pCmd->payloadLen = sizeof(SKillQueryReq); switch (pCmd->command) { case TSDB_SQL_KILL_QUERY: @@ -1742,7 +1742,7 @@ int tscBuildCompactMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; pCmd->msgType = TDMT_MND_SHOW_RETRIEVE; - pCmd->payloadLen = sizeof(SRetrieveTableMsg); + pCmd->payloadLen = sizeof(SRetrieveTableReq); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self); @@ -1750,7 +1750,7 @@ int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); - SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg*)pCmd->payload; + SRetrieveTableReq *pRetrieveMsg = (SRetrieveTableReq*)pCmd->payload; pRetrieveMsg->qId = htobe64(pSql->res.qId); pRetrieveMsg->free = htons(pQueryInfo->type); @@ -1862,14 +1862,14 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) { STscObj *pObj = pSql->pTscObj; SSqlCmd *pCmd = &pSql->cmd; pCmd->msgType = TDMT_MND_CONNECT; - pCmd->payloadLen = sizeof(SConnectMsg); + pCmd->payloadLen = sizeof(SConnectReq); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self); return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SConnectMsg *pConnect = (SConnectMsg*)pCmd->payload; + SConnectReq *pConnect = (SConnectReq*)pCmd->payload; // TODO refactor full_name char *db; // ugly code to move the space @@ -1974,7 +1974,7 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) { numOfStreams++; } - int size = numOfQueries * sizeof(SQueryDesc) + numOfStreams * sizeof(SStreamDesc) + sizeof(SHeartBeatMsg) + 100; + int size = numOfQueries * sizeof(SQueryDesc) + numOfStreams * sizeof(SStreamDesc) + sizeof(SHeartBeatReq) + 100; if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) { pthread_mutex_unlock(&pObj->mutex); tscError("0x%"PRIx64" failed to create heartbeat msg", pSql->self); @@ -1982,7 +1982,7 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } // TODO the expired hb and client can not be identified by server till now. - SHeartBeatMsg *pHeartbeat = (SHeartBeatMsg *)pCmd->payload; + SHeartBeatReq *pHeartbeat = (SHeartBeatReq *)pCmd->payload; tstrncpy(pHeartbeat->clientVer, version, tListLen(pHeartbeat->clientVer)); pHeartbeat->numOfQueries = numOfQueries; diff --git a/src/tfs/CMakeLists.txt b/src/tfs/CMakeLists.txt deleted file mode 100644 index 7f956f07a2..0000000000 --- a/src/tfs/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8...3.20) -PROJECT(TDengine) - -INCLUDE_DIRECTORIES(inc) -AUX_SOURCE_DIRECTORY(src SRC) -ADD_LIBRARY(tfs ${SRC}) -TARGET_LINK_LIBRARIES(tfs tutil) - -IF (TD_LINUX) - # Someone has no gtest directory, so comment it - # ADD_SUBDIRECTORY(tests) -ENDIF () diff --git a/tests/script/general/db/basic1.sim b/tests/script/general/db/basic1.sim index 44d53917f2..52af7d93ea 100644 --- a/tests/script/general/db/basic1.sim +++ b/tests/script/general/db/basic1.sim @@ -85,4 +85,23 @@ if $data02 != 2 then return -1 endi +return +system sh/exec.sh -n dnode1 -s stop -x SIGKILL +system sh/exec.sh -n dnode1 -s start + +sql show databases + +if $rows != 1 then + return -1 +endi + +sql_error use d1 + +sql use d4 +sql show vgroups + +if $rows != 2 then + return -1 +endi + system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/general/table/basic1.sim b/tests/script/general/table/basic1.sim index 298f663822..b5393a03dc 100644 --- a/tests/script/general/table/basic1.sim +++ b/tests/script/general/table/basic1.sim @@ -44,24 +44,30 @@ print $data10 $data11 $data12 print =============== create child table sql create table c1 using st tags(1) -sql create table c2 using st tags(2) +sql create table c2 using st tags(2) sql show tables if $rows != 2 then return -1 endi +sql create table c3 using st tags(3) c4 using st tags(4) c5 using st tags(5) c6 using st tags(6) c7 using st tags(7) + +sql show tables +if $rows != 7 then + return -1 +endi + print $data00 $data01 $data02 print $data10 $data11 $data22 print $data20 $data11 $data22 -return - print =============== insert data sql insert into c1 values(now+1s, 1) sql insert into c1 values(now+2s, 2) sql insert into c1 values(now+3s, 3) +return print =============== query data sql select * from c1 if $rows != 3 then diff --git a/tests/test/c/create_table.c b/tests/test/c/create_table.c index 96c7f87392..f2db9d0a0c 100644 --- a/tests/test/c/create_table.c +++ b/tests/test/c/create_table.c @@ -15,43 +15,39 @@ #define _DEFAULT_SOURCE #include "os.h" - #include "taos.h" -#include "taosdef.h" #include "taoserror.h" -#include "thash.h" -#include "tutil.h" #include "ulog.h" -#define MAX_RANDOM_POINTS 20000 #define GREEN "\033[1;32m" #define NC "\033[0m" char dbName[32] = "db"; char stbName[64] = "st"; -int32_t numOfThreads = 2; -int32_t numOfTables = 10000; +int32_t numOfThreads = 1; +int64_t numOfTables = 200000; int32_t createTable = 1; int32_t insertData = 0; -int32_t batchNum = 1; +int32_t batchNum = 100; int32_t numOfVgroups = 2; typedef struct { - int32_t tableBeginIndex; - int32_t tableEndIndex; + int64_t tableBeginIndex; + int64_t tableEndIndex; int32_t threadIndex; char dbName[32]; char stbName[64]; float createTableSpeed; float insertDataSpeed; + int64_t startMs; pthread_t thread; } SThreadInfo; -void parseArgument(int argc, char *argv[]); +void parseArgument(int32_t argc, char *argv[]); void *threadFunc(void *param); void createDbAndStb(); -int main(int argc, char *argv[]) { +int32_t main(int32_t argc, char *argv[]) { parseArgument(argc, argv); createDbAndStb(); @@ -62,9 +58,9 @@ int main(int argc, char *argv[]) { pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); SThreadInfo *pInfo = (SThreadInfo *)calloc(numOfThreads, sizeof(SThreadInfo)); - int32_t numOfTablesPerThread = numOfTables / numOfThreads; + int64_t numOfTablesPerThread = numOfTables / numOfThreads; numOfTables = numOfTablesPerThread * numOfThreads; - for (int i = 0; i < numOfThreads; ++i) { + for (int32_t i = 0; i < numOfThreads; ++i) { pInfo[i].tableBeginIndex = i * numOfTablesPerThread; pInfo[i].tableEndIndex = (i + 1) * numOfTablesPerThread; pInfo[i].threadIndex = i; @@ -74,22 +70,24 @@ int main(int argc, char *argv[]) { } taosMsleep(300); - for (int i = 0; i < numOfThreads; i++) { + for (int32_t i = 0; i < numOfThreads; i++) { pthread_join(pInfo[i].thread, NULL); } float createTableSpeed = 0; - for (int i = 0; i < numOfThreads; ++i) { + for (int32_t i = 0; i < numOfThreads; ++i) { createTableSpeed += pInfo[i].createTableSpeed; } float insertDataSpeed = 0; - for (int i = 0; i < numOfThreads; ++i) { + for (int32_t i = 0; i < numOfThreads; ++i) { insertDataSpeed += pInfo[i].insertDataSpeed; } - pPrint("%s total %.1f tables/second, threads:%d %s", GREEN, createTableSpeed, numOfThreads, NC); - pPrint("%s total %.1f rows/second, threads:%d %s", GREEN, insertDataSpeed, numOfThreads, NC); + pPrint("%s total %" PRId64 " tables, %.1f tables/second, threads:%d %s", GREEN, numOfTables, createTableSpeed, + numOfThreads, NC); + pPrint("%s total %" PRId64 " tables, %.1f rows/second, threads:%d %s", GREEN, numOfTables, insertDataSpeed, + numOfThreads, NC); pthread_attr_destroy(&thattr); free(pInfo); @@ -135,10 +133,30 @@ void createDbAndStb() { taos_close(con); } +void printCreateProgress(SThreadInfo *pInfo, int64_t t) { + int64_t endMs = taosGetTimestampMs(); + int64_t totalTables = t - pInfo->tableBeginIndex; + float seconds = (endMs - pInfo->startMs) / 1000.0; + float speed = totalTables / seconds; + pInfo->createTableSpeed = speed; + pPrint("thread:%d, %" PRId64 " tables created, time:%.2f sec, speed:%.1f tables/second, ", pInfo->threadIndex, + totalTables, seconds, speed); +} + +void printInsertProgress(SThreadInfo *pInfo, int64_t t) { + int64_t endMs = taosGetTimestampMs(); + int64_t totalTables = t - pInfo->tableBeginIndex; + float seconds = (endMs - pInfo->startMs) / 1000.0; + float speed = totalTables / seconds; + pInfo->insertDataSpeed = speed; + pPrint("thread:%d, %" PRId64 " rows inserted, time:%.2f sec, speed:%.1f rows/second, ", pInfo->threadIndex, + totalTables, seconds, speed); +} + void *threadFunc(void *param) { SThreadInfo *pInfo = (SThreadInfo *)param; - char qstr[65000]; - int code; + char *qstr = malloc(2000 * 1000); + int32_t code = 0; TAOS *con = taos_connect(NULL, "root", "taosdata", NULL, 0); if (con == NULL) { @@ -151,44 +169,59 @@ void *threadFunc(void *param) { taos_free_result(pSql); if (createTable) { - int64_t startMs = taosGetTimestampMs(); - for (int32_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) { - sprintf(qstr, "create table t%d using %s tags(%d)", t, stbName, t); + pInfo->startMs = taosGetTimestampMs(); + for (int64_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) { + int64_t batch = (pInfo->tableEndIndex - t); + batch = MIN(batch, batchNum); + + int32_t len = sprintf(qstr, "create table"); + for (int32_t i = 0; i < batch; ++i) { + len += sprintf(qstr + len, " t%" PRId64 " using %s tags(%" PRId64 ")", t + i, stbName, t + i); + } + TAOS_RES *pSql = taos_query(con, qstr); code = taos_errno(pSql); if (code != 0) { - pError("failed to create table t%d, reason:%s", t, tstrerror(code)); + pError("failed to create table t%" PRId64 ", reason:%s", t, tstrerror(code)); } taos_free_result(pSql); + + if (t % 100000 == 0) { + printCreateProgress(pInfo, t); + } + t += (batch - 1); } - int64_t endMs = taosGetTimestampMs(); - int32_t totalTables = pInfo->tableEndIndex - pInfo->tableBeginIndex; - float seconds = (endMs - startMs) / 1000.0; - float speed = totalTables / seconds; - pInfo->createTableSpeed = speed; - pPrint("thread:%d, time:%.2f sec, speed:%.1f tables/second, ", pInfo->threadIndex, seconds, speed); + printCreateProgress(pInfo, pInfo->tableEndIndex); } if (insertData) { - int64_t startMs = taosGetTimestampMs(); - for (int32_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) { - sprintf(qstr, "insert into %s%d values(now, 1)", stbName, t); + pInfo->startMs = taosGetTimestampMs(); + for (int64_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) { + int64_t batch = (pInfo->tableEndIndex - t); + batch = MIN(batch, batchNum); + + int32_t len = sprintf(qstr, "insert into"); + for (int32_t i = 0; i < batch; ++i) { + len += sprintf(qstr + len, " t%" PRId64 " values(now, %" PRId64 ")", t + i, t + i); + } + TAOS_RES *pSql = taos_query(con, qstr); code = taos_errno(pSql); if (code != 0) { - pError("failed to create table %s%d, reason:%s", stbName, t, tstrerror(code)); + pError("failed to insert table t%" PRId64 ", reason:%s", t, tstrerror(code)); } taos_free_result(pSql); + + if (t % 100000 == 0) { + printInsertProgress(pInfo, t); + } + t += (batch - 1); } - int64_t endMs = taosGetTimestampMs(); - int32_t totalTables = pInfo->tableEndIndex - pInfo->tableBeginIndex; - float seconds = (endMs - startMs) / 1000.0; - float speed = totalTables / seconds; - pInfo->insertDataSpeed = speed; - pPrint("thread:%d, time:%.2f sec, speed:%.1f rows/second, ", pInfo->threadIndex, seconds, speed); + printInsertProgress(pInfo, pInfo->tableEndIndex); } taos_close(con); + free(qstr); return 0; } @@ -205,7 +238,7 @@ void printHelp() { printf("%s%s\n", indent, "-t"); printf("%s%s%s%d\n", indent, indent, "numOfThreads, default is ", numOfThreads); printf("%s%s\n", indent, "-n"); - printf("%s%s%s%d\n", indent, indent, "numOfTables, default is ", numOfTables); + printf("%s%s%s%" PRId64 "\n", indent, indent, "numOfTables, default is ", numOfTables); printf("%s%s\n", indent, "-v"); printf("%s%s%s%d\n", indent, indent, "numOfVgroups, default is ", numOfVgroups); printf("%s%s\n", indent, "-a"); @@ -218,8 +251,8 @@ void printHelp() { exit(EXIT_SUCCESS); } -void parseArgument(int argc, char *argv[]) { - for (int i = 1; i < argc; i++) { +void parseArgument(int32_t argc, char *argv[]) { + for (int32_t i = 1; i < argc; i++) { if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { printHelp(); exit(0); @@ -232,7 +265,7 @@ void parseArgument(int argc, char *argv[]) { } else if (strcmp(argv[i], "-t") == 0) { numOfThreads = atoi(argv[++i]); } else if (strcmp(argv[i], "-n") == 0) { - numOfTables = atoi(argv[++i]); + numOfTables = atoll(argv[++i]); } else if (strcmp(argv[i], "-n") == 0) { numOfVgroups = atoi(argv[++i]); } else if (strcmp(argv[i], "-a") == 0) { @@ -248,7 +281,7 @@ void parseArgument(int argc, char *argv[]) { pPrint("%s dbName:%s %s", GREEN, dbName, NC); pPrint("%s stbName:%s %s", GREEN, stbName, NC); pPrint("%s configDir:%s %s", GREEN, configDir, NC); - pPrint("%s numOfTables:%d %s", GREEN, numOfTables, NC); + pPrint("%s numOfTables:%" PRId64 " %s", GREEN, numOfTables, NC); pPrint("%s numOfThreads:%d %s", GREEN, numOfThreads, NC); pPrint("%s numOfVgroups:%d %s", GREEN, numOfVgroups, NC); pPrint("%s createTable:%d %s", GREEN, createTable, NC); diff --git a/tools/shell/src/backup/tnettest.c b/tools/shell/src/backup/tnettest.c index d6904ddc04..7b5dbd2405 100644 --- a/tools/shell/src/backup/tnettest.c +++ b/tools/shell/src/backup/tnettest.c @@ -338,7 +338,7 @@ void *taosNetInitRpc(char *secretEncrypt, char spi) { return pRpcConn; } -static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t pktLen, char spi, SStartupMsg *pStep) { +static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t pktLen, char spi, SStartupReq *pStep) { SRpcEpSet epSet; SRpcMsg reqMsg; SRpcMsg rspMsg; @@ -374,7 +374,7 @@ static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t p } int32_t code = 0; - if (pStep != NULL && rspMsg.pCont != NULL && rspMsg.contLen > 0 && rspMsg.contLen <= sizeof(SStartupMsg)) { + if (pStep != NULL && rspMsg.pCont != NULL && rspMsg.contLen > 0 && rspMsg.contLen <= sizeof(SStartupReq)) { memcpy(pStep, rspMsg.pCont, rspMsg.contLen); code = 1; } @@ -384,8 +384,8 @@ static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t p return code; } -static int32_t taosNetParseStartup(SStartupMsg *pCont) { - SStartupMsg *pStep = pCont; +static int32_t taosNetParseStartup(SStartupReq *pCont) { + SStartupReq *pStep = pCont; uInfo("step:%s desc:%s", pStep->name, pStep->desc); if (pStep->finished) { @@ -398,7 +398,7 @@ static int32_t taosNetParseStartup(SStartupMsg *pCont) { static void taosNetTestStartup(char *host, int32_t port) { uInfo("check startup, host:%s port:%d\n", host, port); - SStartupMsg *pStep = malloc(sizeof(SStartupMsg)); + SStartupReq *pStep = malloc(sizeof(SStartupReq)); while (1) { int32_t code = taosNetCheckRpc(host, port + TSDB_PORT_DNODEDNODE, 20, 0, pStep); if (code > 0) {