From c86bda4a1bbd7ec15c9a25ca92caefdea36d35d0 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sun, 15 Aug 2021 23:01:57 +0800 Subject: [PATCH 01/35] [TD-6054]: Filtered by tag with nchar value not as expected --- src/util/src/tcompare.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index a3c01d2be7..1043ee4c37 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -152,11 +152,18 @@ int32_t compareLenPrefixedStr(const void *pLeft, const void *pRight) { int32_t compareLenPrefixedWStr(const void *pLeft, const void *pRight) { int32_t len1 = varDataLen(pLeft); int32_t len2 = varDataLen(pRight); - + if (len1 != len2) { return len1 > len2? 1:-1; } else { - int32_t ret = wcsncmp(varDataVal(pLeft), varDataVal(pRight), len1/TSDB_NCHAR_SIZE); + char pLeftTerm[len1 + 1]; + char pRightTerm[len2 + 1]; + memset(pLeftTerm, 0, len1 + 1); + memset(pRightTerm, 0, len2 + 1); + memcpy(pLeftTerm, varDataVal(pLeft), len1); + memcpy(pRightTerm, varDataVal(pRight), len2); + + int32_t ret = wcsncmp((void *)pLeftTerm, (void *)pRightTerm, len1/TSDB_NCHAR_SIZE); if (ret == 0) { return 0; } else { From c859b1ff7f47f186c4c20feb64fd5e6a048e09d2 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sun, 15 Aug 2021 23:01:57 +0800 Subject: [PATCH 02/35] [TD-6054]: Filtered by tag with nchar value not as expected --- src/util/src/tcompare.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 1043ee4c37..ee367b459c 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -156,14 +156,16 @@ int32_t compareLenPrefixedWStr(const void *pLeft, const void *pRight) { if (len1 != len2) { return len1 > len2? 1:-1; } else { - char pLeftTerm[len1 + 1]; - char pRightTerm[len2 + 1]; - memset(pLeftTerm, 0, len1 + 1); - memset(pRightTerm, 0, len2 + 1); + char *pLeftTerm = (char *)tcalloc(len1 + 1, sizeof(char)); + char *pRightTerm = (char *)tcalloc(len1 + 1, sizeof(char)); memcpy(pLeftTerm, varDataVal(pLeft), len1); memcpy(pRightTerm, varDataVal(pRight), len2); int32_t ret = wcsncmp((void *)pLeftTerm, (void *)pRightTerm, len1/TSDB_NCHAR_SIZE); + + tfree(pLeftTerm); + tfree(pRightTerm); + if (ret == 0) { return 0; } else { From be09ee1411d6d21ffa405a307002055077c8b981 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sun, 15 Aug 2021 23:01:57 +0800 Subject: [PATCH 03/35] [TD-6054]: Filtered by tag with nchar value not as expected --- src/util/src/tcompare.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index ee367b459c..dbb4c87369 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -475,7 +475,16 @@ int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) { return t1->len > t2->len? 1:-1; } - int32_t ret = wcsncmp((wchar_t*) t1->data, (wchar_t*) t2->data, t2->len/TSDB_NCHAR_SIZE); + char *t1_term = (char *)tcalloc(t1->len + 1, sizeof(char)); + char *t2_term = (char *)tcalloc(t2->len + 1, sizeof(char)); + memcpy(t1_term, t1->data, t1->len); + memcpy(t2_term, t2->data, t2->len); + + int32_t ret = wcsncmp((wchar_t*) t1_term, (wchar_t*) t2_term, t2->len/TSDB_NCHAR_SIZE); + + tfree(t1_term); + tfree(t2_term); + if (ret == 0) { return ret; } From d22530a7f2d10c02c7537873ad222271b556749c Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sun, 15 Aug 2021 23:01:57 +0800 Subject: [PATCH 04/35] [TD-6054]: Filtered by tag with nchar value not as expected --- src/util/src/tcompare.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index dbb4c87369..56d03cc394 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -161,7 +161,7 @@ int32_t compareLenPrefixedWStr(const void *pLeft, const void *pRight) { memcpy(pLeftTerm, varDataVal(pLeft), len1); memcpy(pRightTerm, varDataVal(pRight), len2); - int32_t ret = wcsncmp((void *)pLeftTerm, (void *)pRightTerm, len1/TSDB_NCHAR_SIZE); + int32_t ret = wcsncmp((wchar_t*) pLeftTerm, (wchar_t*) pRightTerm, len1/TSDB_NCHAR_SIZE); tfree(pLeftTerm); tfree(pRightTerm); From 7e9c7e77ac7b3e0eebaac01c5098300138368445 Mon Sep 17 00:00:00 2001 From: zhaoyanggh Date: Mon, 16 Aug 2021 09:53:19 +0800 Subject: [PATCH 05/35] [TD-6081] add test case for filter within multiple nchar tags --- tests/pytest/query/filterWithinMultiNchar.py | 45 ++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/pytest/query/filterWithinMultiNchar.py diff --git a/tests/pytest/query/filterWithinMultiNchar.py b/tests/pytest/query/filterWithinMultiNchar.py new file mode 100644 index 0000000000..3a43785e69 --- /dev/null +++ b/tests/pytest/query/filterWithinMultiNchar.py @@ -0,0 +1,45 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import tdLog +from util.cases import tdCases +from util.sql import tdSql + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + tdSql.prepare() + + print("==============step1") + tdSql.execute( + "create stable t6 (ts timestamp,val int,flow nchar(36)) tags(dev nchar(36),gr nchar(36))") + tdSql.execute("insert into t6004 using t6 (dev,gr) tags ('b50c79bc-b102-48e6-bda1-4212263e46d0','b50c79bc-b102-48e6-bda1-4212263e46d0') values(now,1,'b50c79bc-b102-48e6-bda1-4212263e46d0')") + + + print("==============step2") + tdSql.query("select * from t6 where dev='b50c79bc-b102-48e6-bda1-4212263e46d0'") + tdSql.checkRows(1) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) From 07c007fc364879d4bcdc2e79ccbcd9ab41b507b1 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Mon, 16 Aug 2021 10:25:29 +0800 Subject: [PATCH 06/35] [TD-6081] add test case for filter within multiple nchar tags --- tests/pytest/query/filterWithinMultiNchar.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/pytest/query/filterWithinMultiNchar.py b/tests/pytest/query/filterWithinMultiNchar.py index 3a43785e69..15fcf4e24b 100644 --- a/tests/pytest/query/filterWithinMultiNchar.py +++ b/tests/pytest/query/filterWithinMultiNchar.py @@ -28,14 +28,20 @@ class TDTestCase: print("==============step1") tdSql.execute( - "create stable t6 (ts timestamp,val int,flow nchar(36)) tags(dev nchar(36),gr nchar(36))") - tdSql.execute("insert into t6004 using t6 (dev,gr) tags ('b50c79bc-b102-48e6-bda1-4212263e46d0','b50c79bc-b102-48e6-bda1-4212263e46d0') values(now,1,'b50c79bc-b102-48e6-bda1-4212263e46d0')") + "create stable t6 (ts timestamp,val int,flow nchar(36)) tags(dev nchar(36),dev1 nchar(36),dev2 nchar(36))") + tdSql.execute("insert into t6004 using t6 (dev,dev1,dev2) tags ('b50c79bc-b102-48e6-bda1-4212263e46d0','b50c79bc-b102-48e6-bda1-4212263e46d0', 'b50c79bc-b102-48e6-bda1-4212263e46d0') values(now,1,'b50c79bc-b102-48e6-bda1-4212263e46d0')") - print("==============step2") + print("==============step2") tdSql.query("select * from t6 where dev='b50c79bc-b102-48e6-bda1-4212263e46d0'") tdSql.checkRows(1) + tdSql.query("select * from t6 where dev1='b50c79bc-b102-48e6-bda1-4212263e46d0'") + tdSql.checkRows(1) + + tdSql.query("select * from t6 where dev2='b50c79bc-b102-48e6-bda1-4212263e46d0'") + tdSql.checkRows(1) + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) From 88eab6e357de8be65f94e71c2704cad6b38e8d6c Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 16 Aug 2021 15:38:31 +0800 Subject: [PATCH 07/35] [TD-5838] add description and split speed test and fqdn test --- src/kit/shell/src/shellLinux.c | 2 +- src/kit/shell/src/shellWindows.c | 2 +- src/util/src/tnettest.c | 15 +++------------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c index fcba3a4426..50c68ac343 100644 --- a/src/kit/shell/src/shellLinux.c +++ b/src/kit/shell/src/shellLinux.c @@ -48,7 +48,7 @@ static struct argp_option options[] = { {"check", 'k', "CHECK", 0, "Check tables."}, {"database", 'd', "DATABASE", 0, "Database to use when connecting to the server."}, {"timezone", 't', "TIMEZONE", 0, "Time zone of the shell, default is local."}, - {"netrole", 'n', "NETROLE", 0, "Net role when network connectivity test, default is startup, options: client|server|rpc|startup|sync."}, + {"netrole", 'n', "NETROLE", 0, "Net role when network connectivity test, default is startup, options: client|server|rpc|startup|sync|speen|fqdn."}, {"pktlen", 'l', "PKTLEN", 0, "Packet length used for net test, default is 1000 bytes."}, {"pktnum", 'N', "PKTNUM", 0, "Packet numbers used for net test, default is 100."}, {"pkttype", 'S', "PKTTYPE", 0, "Packet type used for net test, default is TCP."}, diff --git a/src/kit/shell/src/shellWindows.c b/src/kit/shell/src/shellWindows.c index ce161d89b7..271f440fe9 100644 --- a/src/kit/shell/src/shellWindows.c +++ b/src/kit/shell/src/shellWindows.c @@ -52,7 +52,7 @@ void printHelp() { printf("%s%s\n", indent, "-t"); printf("%s%s%s\n", indent, indent, "Time zone of the shell, default is local."); printf("%s%s\n", indent, "-n"); - printf("%s%s%s\n", indent, indent, "Net role when network connectivity test, default is startup, options: client|server|rpc|startup|sync."); + printf("%s%s%s\n", indent, indent, "Net role when network connectivity test, default is startup, options: client|server|rpc|startup|sync|speed|fqdn."); printf("%s%s\n", indent, "-l"); printf("%s%s%s\n", indent, indent, "Packet length used for net test, default is 1000 bytes."); printf("%s%s\n", indent, "-N"); diff --git a/src/util/src/tnettest.c b/src/util/src/tnettest.c index 153ad346db..42fa1f1b9f 100644 --- a/src/util/src/tnettest.c +++ b/src/util/src/tnettest.c @@ -639,17 +639,6 @@ static void taosNetCheckSpeed(char *host, int32_t port, int32_t pkgLen, return; } -static void taosNetTestSpeed(char *host, int32_t port, int32_t pkgLen, - int32_t pkgNum, char *pkgType) { - if (0 == strcmp("fqdn", pkgType)){ - taosNetTestFqdn(host); - return; - } - - taosNetCheckSpeed(host, port, pkgLen, pkgNum, pkgType); - return; -} - void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen, int32_t pkgNum, char *pkgType) { tscEmbedded = 1; @@ -679,7 +668,9 @@ void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen, } else if (0 == strcmp("speed", role)) { tscEmbedded = 0; char type[10] = {0}; - taosNetTestSpeed(host, port, pkgLen, pkgNum, strtolower(type, pkgType)); + taosNetCheckSpeed(host, port, pkgLen, pkgNum, strtolower(type, pkgType)); + }else if (0 == strcmp("fqdn", role)) { + taosNetTestFqdn(host); }else { taosNetTestStartup(host, port); } From cd233bf9e88b9a1ede88a33b8ddb0b41f8e4734a Mon Sep 17 00:00:00 2001 From: bryanchang0603 Date: Mon, 16 Aug 2021 16:19:33 +0800 Subject: [PATCH 08/35] [TD-5838] for testing nettools --- tests/nettest/fqdn.sh | 3 +++ tests/nettest/tcpudp.sh | 13 +++++++++++++ 2 files changed, 16 insertions(+) create mode 100755 tests/nettest/fqdn.sh create mode 100755 tests/nettest/tcpudp.sh diff --git a/tests/nettest/fqdn.sh b/tests/nettest/fqdn.sh new file mode 100755 index 0000000000..f4ee5d56bc --- /dev/null +++ b/tests/nettest/fqdn.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +taos -n fqdn diff --git a/tests/nettest/tcpudp.sh b/tests/nettest/tcpudp.sh new file mode 100755 index 0000000000..b7c3c00301 --- /dev/null +++ b/tests/nettest/tcpudp.sh @@ -0,0 +1,13 @@ +#!/bin/bash + + +for N in -1 0 1 10000 10001 +do + for l in 1023 1024 + do + for S in udp tcp + do + taos -n speed -h BCC-2 -P 6030 -N $N -l $l -S $S 2>&1 | tee -a result.txt + done + done +done From bf20f82a52acda8052dbc9f89a06eb15bf2ec414 Mon Sep 17 00:00:00 2001 From: jiacy-jcy Date: Mon, 16 Aug 2021 16:29:44 +0800 Subject: [PATCH 09/35] [TD-5838]:the case of nettest tool --- tests/nettest/tcpudp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/nettest/tcpudp.sh b/tests/nettest/tcpudp.sh index b7c3c00301..f0f924584b 100755 --- a/tests/nettest/tcpudp.sh +++ b/tests/nettest/tcpudp.sh @@ -3,7 +3,7 @@ for N in -1 0 1 10000 10001 do - for l in 1023 1024 + for l in 1023 1024 1073741824 1073741825 do for S in udp tcp do From 281b0ea271e392d508d1b28c3ab99ff87eb6a308 Mon Sep 17 00:00:00 2001 From: liuyq-617 Date: Mon, 16 Aug 2021 16:53:42 +0800 Subject: [PATCH 10/35] stop taosd using kill -9 --- tests/pytest/util/dnodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pytest/util/dnodes.py b/tests/pytest/util/dnodes.py index ae4ba97eb3..698c3caa55 100644 --- a/tests/pytest/util/dnodes.py +++ b/tests/pytest/util/dnodes.py @@ -556,7 +556,7 @@ class TDDnodes: psCmd = "ps -ef|grep -w taosd| grep -v grep| grep -v defunct | awk '{print $2}'" processID = subprocess.check_output(psCmd, shell=True).decode("utf-8") while(processID): - killCmd = "kill -TERM %s > /dev/null 2>&1" % processID + killCmd = "kill -9 %s > /dev/null 2>&1" % processID os.system(killCmd) time.sleep(1) processID = subprocess.check_output( From 486446ad8f1d5a31a3525379b5b535aae21a9114 Mon Sep 17 00:00:00 2001 From: liuyq-617 Date: Mon, 16 Aug 2021 18:03:24 +0800 Subject: [PATCH 11/35] test --- tests/pytest/util/dnodes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pytest/util/dnodes.py b/tests/pytest/util/dnodes.py index 698c3caa55..0f4919ba96 100644 --- a/tests/pytest/util/dnodes.py +++ b/tests/pytest/util/dnodes.py @@ -436,7 +436,7 @@ class TDDnodes: psCmd = "ps -ef|grep -w taosd| grep -v grep| grep -v defunct | awk '{print $2}'" processID = subprocess.check_output(psCmd, shell=True).decode("utf-8") while(processID): - killCmd = "kill -TERM %s > /dev/null 2>&1" % processID + killCmd = "kill -9 %s > /dev/null 2>&1" % processID os.system(killCmd) time.sleep(1) processID = subprocess.check_output( @@ -445,7 +445,7 @@ class TDDnodes: psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'" processID = subprocess.check_output(psCmd, shell=True).decode("utf-8") while(processID): - killCmd = "kill -TERM %s > /dev/null 2>&1" % processID + killCmd = "kill -9 %s > /dev/null 2>&1" % processID os.system(killCmd) time.sleep(1) processID = subprocess.check_output( From 92e0af3c9e7ec6784e5b1e8a82a1416709b6cfc5 Mon Sep 17 00:00:00 2001 From: liuyq-617 Date: Tue, 17 Aug 2021 10:23:56 +0800 Subject: [PATCH 12/35] update --- tests/pytest/client/client.py | 2 +- tests/pytest/fulltest.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/pytest/client/client.py b/tests/pytest/client/client.py index 0fc6741131..9a155a4df9 100644 --- a/tests/pytest/client/client.py +++ b/tests/pytest/client/client.py @@ -67,7 +67,7 @@ class TDTestCase: tdSql.execute('create table ct1 using st tags(1)'); tdSql.execute('create table ct2 using st tags(2)'); - time.sleep(1) + time.sleep(3) ret = tdSql.query('show vnodes "{}"'.format(dnodeEndpoint)) tdSql.checkRows(1) diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index 4ea9d9d495..f6e799998b 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -155,6 +155,7 @@ python3 ./test.py -f import_merge/importCSV.py python3 ./test.py -f import_merge/import_update_0.py python3 ./test.py -f import_merge/import_update_1.py python3 ./test.py -f import_merge/import_update_2.py +python3 ./test.py -f update/merge_commit_data.py #======================p1-end=============== #======================p2-start=============== # tools @@ -183,7 +184,7 @@ python3 ./test.py -f update/allow_update-0.py python3 ./test.py -f update/append_commit_data.py python3 ./test.py -f update/append_commit_last-0.py python3 ./test.py -f update/append_commit_last.py -python3 ./test.py -f update/merge_commit_data.py + python3 ./test.py -f update/merge_commit_data2.py python3 ./test.py -f update/merge_commit_data2_update0.py From 0701a7b5acf31f6fa2cbab2f0ad2ea13a552babd Mon Sep 17 00:00:00 2001 From: liuyq-617 Date: Tue, 17 Aug 2021 11:16:11 +0800 Subject: [PATCH 13/35] rebalance --- tests/pytest/test.py | 3 +-- tests/script/jenkins/basic.txt | 13 +++++++------ tests/test-all.sh | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/pytest/test.py b/tests/pytest/test.py index 65abd3ef93..97dca6be18 100644 --- a/tests/pytest/test.py +++ b/tests/pytest/test.py @@ -87,7 +87,7 @@ if __name__ == "__main__": else: toBeKilled = "valgrind.bin" - killCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs kill -HUP > /dev/null 2>&1" % toBeKilled + killCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs kill -TERM > /dev/null 2>&1" % toBeKilled psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled processID = subprocess.check_output(psCmd, shell=True) @@ -110,7 +110,6 @@ if __name__ == "__main__": time.sleep(2) tdLog.info('stop All dnodes') - sys.exit(0) tdDnodes.init(deployPath) tdDnodes.setTestCluster(testCluster) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 6ad6a74eed..b087c734f3 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -134,6 +134,13 @@ cd ../../../debug; make ./test.sh -f unique/cluster/alter.sim ./test.sh -f unique/cluster/cache.sim +./test.sh -f unique/http/admin.sim +./test.sh -f unique/http/opentsdb.sim + +./test.sh -f unique/import/replica2.sim +./test.sh -f unique/import/replica3.sim + +./test.sh -f general/alter/cached_schema_after_alter.sim #======================b2-end=============== @@ -198,13 +205,7 @@ cd ../../../debug; make #======================b3-end=============== #======================b4-start=============== -./test.sh -f unique/http/admin.sim -./test.sh -f unique/http/opentsdb.sim -./test.sh -f unique/import/replica2.sim -./test.sh -f unique/import/replica3.sim - -./test.sh -f general/alter/cached_schema_after_alter.sim ./test.sh -f general/alter/count.sim ./test.sh -f general/alter/dnode.sim ./test.sh -f general/alter/import.sim diff --git a/tests/test-all.sh b/tests/test-all.sh index 8dd1ade9be..fb5b5c4830 100755 --- a/tests/test-all.sh +++ b/tests/test-all.sh @@ -179,6 +179,9 @@ function runPyCaseOneByOnefq() { start_time=`date +%s` date +%F\ %T | tee -a pytest-out.log echo -n $case + if [[ $1 =~ full ]] ; then + line=$line" -s" + fi $line > case.log 2>&1 && \ echo -e "${GREEN} success${NC}" | tee -a pytest-out.log || \ echo -e "${RED} failed${NC}" | tee -a pytest-out.log From e94bcaf7aa7ebe1ac004f6ae244299b92a9d0d43 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 17 Aug 2021 04:18:48 +0000 Subject: [PATCH 14/35] [TD-6131] handle mem corrupt --- src/mnode/src/mnodeDnode.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c index 73be7ea045..335f9af528 100644 --- a/src/mnode/src/mnodeDnode.c +++ b/src/mnode/src/mnodeDnode.c @@ -298,7 +298,7 @@ void *mnodeGetDnodeByEp(char *ep) { while (1) { pIter = mnodeGetNextDnode(pIter, &pDnode); if (pDnode == NULL) break; - if (strcmp(ep, pDnode->dnodeEp) == 0) { + if (strncasecmp(ep, pDnode->dnodeEp, TSDB_EP_LEN) == 0) { mnodeCancelGetNextDnode(pIter); return pDnode; } @@ -1199,7 +1199,12 @@ static int32_t mnodeGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC SDnodeObj *pDnode = NULL; if (pShow->payloadLen > 0 ) { - pDnode = mnodeGetDnodeByEp(pShow->payload); + char ep[TSDB_EP_LEN] = {0}; + // not use tstrncpy to make runtime happy + uint16_t len = (pShow->payloadLen + 1) > TSDB_EP_LEN ? TSDB_EP_LEN :(pShow->payloadLen + 1); + strncpy(ep, pShow->payload, len - 1); + + pDnode = mnodeGetDnodeByEp(ep); } else { void *pIter = mnodeGetNextDnode(NULL, (SDnodeObj **)&pDnode); mnodeCancelGetNextDnode(pIter); From 47e784cec0f572535b86d9693acca40f65c98ec4 Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Tue, 17 Aug 2021 13:44:03 +0800 Subject: [PATCH 15/35] [TD-2639] : fix typo. --- documentation20/cn/08.connector/docs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 72fd89c274..90170c593b 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -287,7 +287,7 @@ typedef struct taosField { 异步API都需要应用提供相应的回调函数,回调函数参数设置如下:前两个参数都是一致的,第三个参数依不同的API而定。第一个参数param是应用调用异步API时提供给系统的,用于回调时,应用能够找回具体操作的上下文,依具体实现而定。第二个参数是SQL操作的结果集,如果为空,比如insert操作,表示没有记录返回,如果不为空,比如select操作,表示有记录返回。 -异步API对于使用者的要求相对较高,用户可根据具体应用场景选择性使用。下面是三个重要的异步API: +异步API对于使用者的要求相对较高,用户可根据具体应用场景选择性使用。下面是两个重要的异步API: - `void taos_query_a(TAOS *taos, const char *sql, void (*fp)(void *param, TAOS_RES *, int code), void *param);` From 7ced6eba83d709e1141f7d20712e957155dabd6d Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Tue, 17 Aug 2021 14:02:17 +0800 Subject: [PATCH 16/35] [TD-2639] : clarify project of DotNet & C#. --- documentation20/cn/08.connector/docs.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 90170c593b..5ee2bd1372 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -903,7 +903,7 @@ C#连接器支持的系统有:Linux 64/Windows x64/Windows x86 ### 安装准备 * 应用驱动安装请参考[安装连接器驱动步骤](https://www.taosdata.com/cn/documentation/connector#driver)。 -* .NET接口文件TDengineDrivercs.cs和参考程序示例TDengineTest.cs均位于Windows客户端install_directory/examples/C#目录下。 +* 接口文件TDengineDrivercs.cs和参考程序示例TDengineTest.cs均位于Windows客户端install_directory/examples/C#目录下。 * 在Windows系统上,C#应用程序可以使用TDengine的原生C接口来执行所有数据库操作,后续版本将提供ORM(Dapper)框架驱动。 ### 示例程序 @@ -924,17 +924,17 @@ C#Checker.exe -h ### C#连接器的使用 -在Windows系统上,.NET应用程序可以使用TDengine的.NET接口来执行所有数据库的操作。使用.NET接口的步骤如下所示: +在Windows系统上,C#应用程序可以使用TDengine的C#连接器接口来执行所有数据库的操作。使用的具体步骤如下所示: -1. 将.NET接口文件TDengineDrivercs.cs加入到应用程序所在.NET项目中。 +1. 将接口文件TDengineDrivercs.cs加入到应用程序所在的项目空间中。 2. 用户可以参考TDengineTest.cs来定义数据库连接参数,以及如何执行数据插入、查询等操作; -此.NET接口需要用到taos.dll文件,所以在执行应用程序前,拷贝Windows客户端install_directory/driver目录中的taos.dll文件到.NET项目最后生成.exe可执行文件所在文件夹。之后运行exe文件,即可访问TDengine数据库并做插入、查询等操作。 +此接口需要用到taos.dll文件,所以在执行应用程序前,拷贝Windows客户端install_directory/driver目录中的taos.dll文件到项目最后生成.exe可执行文件所在的文件夹。之后运行exe文件,即可访问TDengine数据库并做插入、查询等操作。 **注意:** -1. TDengine V2.0.3.0之后同时支持32位和64位Windows系统,所以.NET项目在生成.exe文件时,“解决方案”/“项目”的“平台”请选择对应的“X86” 或“x64”。 -2. 此.NET接口目前已经在Visual Studio 2015/2017中验证过,其它VS版本尚待验证。 +1. TDengine V2.0.3.0之后同时支持32位和64位Windows系统,所以C#项目在生成.exe文件时,“解决方案”/“项目”的“平台”请选择对应的“X86” 或“x64”。 +2. 此接口目前已经在Visual Studio 2015/2017中验证过,其它VS版本尚待验证。 ### 第三方驱动 From 36c693e1ebf33bfc1c5efbc347bc233c68441fc2 Mon Sep 17 00:00:00 2001 From: cpwu Date: Tue, 17 Aug 2021 15:19:02 +0800 Subject: [PATCH 17/35] [TD-6113] fix case of TD-6113 --- tests/pytest/query/distinctOneColTb.py | 46 ++++++++++++++------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/tests/pytest/query/distinctOneColTb.py b/tests/pytest/query/distinctOneColTb.py index 1570d3b4a5..eedeb19938 100644 --- a/tests/pytest/query/distinctOneColTb.py +++ b/tests/pytest/query/distinctOneColTb.py @@ -47,10 +47,10 @@ class TDTestCase: tdSql.checkRows(num) tdSql.query( f"select distinct cbool from {sql} {where}") - if num < 2: + if num < 3: tdSql.checkRows(num) else: - tdSql.checkRows(2) + tdSql.checkRows(3) tdSql.query( f"select distinct cbinary from {sql} {where}") tdSql.checkRows(num) @@ -81,10 +81,10 @@ class TDTestCase: tdSql.checkRows(num) tdSql.query( f"select distinct cbool as a from {sql} {where}") - if num < 2: + if num < 3: tdSql.checkRows(num) else: - tdSql.checkRows(2) + tdSql.checkRows(3) tdSql.query( f"select distinct cbinary as a from {sql} {where}") tdSql.checkRows(num) @@ -147,11 +147,11 @@ class TDTestCase: self.tb_all_query(num=inNum,where="where cnchar in ('双','双精度浮')",sql=tbName) self.tb_all_query(num=inNum,where="where cbool in (0, 1)",sql=tbName) self.tb_all_query(num=whereNum,where="where cnchar like '双__浮'",sql=tbName) - self.tb_all_query(num=maxNum,where="where cnchar like '双%'",sql=tbName) - self.tb_all_query(num=maxNum,where="where cbinary like 'adc_'",sql=tbName) - self.tb_all_query(num=maxNum,where="where cbinary like 'a%'",sql=tbName) - self.tb_all_query(num=whereNum,where="limit 1",sql=tbName) - self.tb_all_query(num=whereNum,where="limit 1 offset 1",sql=tbName) + # self.tb_all_query(num=maxNum,where="where cnchar like '双%'",sql=tbName) + # self.tb_all_query(num=maxNum,where="where cbinary like 'adc_'",sql=tbName) + # self.tb_all_query(num=maxNum,where="where cbinary like 'a%'",sql=tbName) + # self.tb_all_query(num=whereNum,where="limit 1",sql=tbName) + # self.tb_all_query(num=whereNum,where="limit 1 offset 1",sql=tbName) #subquery self.tb_all_query(num=maxNum,sql=f'(select * from {tbName})') @@ -178,11 +178,11 @@ class TDTestCase: self.tb_all_query(num=inNum,where="where cnchar in ('双','双精度浮')",sql=f'(select * from {tbName})') self.tb_all_query(num=inNum,where="where cbool in (0, 1)",sql=f'(select * from {tbName})') self.tb_all_query(num=whereNum,where="where cnchar like '双__浮'",sql=f'(select * from {tbName})') - self.tb_all_query(num=maxNum,where="where cnchar like '双%'",sql=f'(select * from {tbName})') - self.tb_all_query(num=maxNum,where="where cbinary like 'adc_'",sql=f'(select * from {tbName})') - self.tb_all_query(num=maxNum,where="where cbinary like 'a%'",sql=f'(select * from {tbName})') - self.tb_all_query(num=whereNum,where="limit 1",sql=f'(select * from {tbName})') - self.tb_all_query(num=whereNum,where="limit 1 offset 1",sql=f'(select * from {tbName})') + # self.tb_all_query(num=maxNum,where="where cnchar like '双%'",sql=f'(select * from {tbName})') + # self.tb_all_query(num=maxNum,where="where cbinary like 'adc_'",sql=f'(select * from {tbName})') + # self.tb_all_query(num=maxNum,where="where cbinary like 'a%'",sql=f'(select * from {tbName})') + # self.tb_all_query(num=whereNum,where="limit 1",sql=f'(select * from {tbName})') + # self.tb_all_query(num=whereNum,where="limit 1 offset 1",sql=f'(select * from {tbName})') #table query with inner query has error tdSql.error('select distinct ts2 from (select )') #table query with error option @@ -195,8 +195,7 @@ class TDTestCase: tdLog.notice( "==============phase1 distinct col1 with no values==========") tdSql.execute("create stable if not exists stb_all (ts timestamp, ts2 timestamp, cint int, cbigint bigint, csmallint smallint, ctinyint tinyint,cfloat float, cdouble double, cbool bool, cbinary binary(32), cnchar nchar(32)) tags(tint int)") - tdSql.execute( - "create table if not exists tb_all using stb_all tags(1)") + tdSql.execute("create table if not exists tb_all using stb_all tags(1)") self.query_all_tb() tdLog.notice( @@ -212,11 +211,13 @@ class TDTestCase: "insert into tb_all values(now,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)") # normal query - self.query_all_tb() + self.query_all_tb(maxNum=1, inNum=0, whereNum=0) - tdLog.notice( - "==============phase2 finished ==========\n\n\n") + tdLog.notice("==============phase2 finished ==========\n\n\n") + tdSql.prepare() + tdSql.execute("create stable if not exists stb_all (ts timestamp, ts2 timestamp, cint int, cbigint bigint, csmallint smallint, ctinyint tinyint,cfloat float, cdouble double, cbool bool, cbinary binary(32), cnchar nchar(32)) tags(tint int)") + tdSql.execute("create table if not exists tb_all using stb_all tags(1)") tdLog.notice( "==============phase3 distinct with distinct values ==========\n\n\n") @@ -234,8 +235,11 @@ class TDTestCase: # normal query self.query_all_tb(maxNum=5,inNum=2,whereNum=1) - tdLog.notice( - "==============phase3 finishes ==========\n\n\n") + tdLog.notice("==============phase3 finishes ==========\n\n\n") + + tdSql.prepare() + tdSql.execute("create stable if not exists stb_all (ts timestamp, ts2 timestamp, cint int, cbigint bigint, csmallint smallint, ctinyint tinyint,cfloat float, cdouble double, cbool bool, cbinary binary(32), cnchar nchar(32)) tags(tint int)") + tdSql.execute("create table if not exists tb_all using stb_all tags(1)") tdLog.notice( "==============phase4 distinct with some values the same values ==========\n\n\n") From 3fd9efacd95d8241b6ffe1eb21e3a7f6d6f6a3bc Mon Sep 17 00:00:00 2001 From: cpwu Date: Tue, 17 Aug 2021 15:25:07 +0800 Subject: [PATCH 18/35] [TD-6113] fix the fulltest.sh --- tests/pytest/fulltest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index 241286a3bd..d9c2fad6ad 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -212,7 +212,7 @@ python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py #query -#python3 test.py -f query/distinctOneColTb.py +python3 test.py -f query/distinctOneColTb.py python3 ./test.py -f query/filter.py python3 ./test.py -f query/filterCombo.py python3 ./test.py -f query/queryNormal.py From 230bbacbcf1bc8c5ede25262edb89c202a38471b Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Tue, 17 Aug 2021 16:09:54 +0800 Subject: [PATCH 19/35] [TD-6135] : fix usage limitation for function INTERP. --- documentation20/cn/12.taos-sql/docs.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index 6c4bc7f503..07ed1a5eae 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -1230,7 +1230,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 - **INTERP** ```mysql - SELECT INTERP(field_name) FROM { tb_name | stb_name } WHERE ts='timestamp' [FILL ({ VALUE | PREV | NULL | LINEAR})]; + SELECT INTERP(field_name) FROM { tb_name | stb_name } WHERE ts='timestamp' [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})]; ``` 功能说明:返回表/超级表的指定时间截面、指定字段的记录。 @@ -1242,8 +1242,6 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 说明:(从 2.0.15.0 版本开始新增此函数)INTERP 必须指定时间断面,如果该时间断面不存在直接对应的数据,那么会根据 FILL 参数的设定进行插值。其中,条件语句里面可以附带更多的筛选条件,例如标签、tbname。 - 限制:INTERP 目前不支持 FILL(NEXT)。 - 示例: ```mysql taos> select interp(*) from meters where ts='2017-7-14 10:42:00.005' fill(prev); From 356865a9fd56cac296b52570e5beb50a9c616783 Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Tue, 17 Aug 2021 17:39:42 +0800 Subject: [PATCH 20/35] [TD-2639] : fix description of function "taos_options". --- documentation20/cn/08.connector/docs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 5ee2bd1372..0397c61f75 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -189,7 +189,7 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine - `int taos_options(TSDB_OPTION option, const void * arg, ...)` - 设置客户端选项,目前只支持时区设置(_TSDB_OPTION_TIMEZONE_)和编码设置(_TSDB_OPTION_LOCALE_)。时区和编码默认为操作系统当前设置。 + 设置客户端选项,目前支持区域设置(`TSDB_OPTION_LOCALE`)、字符集设置(`TSDB_OPTION_CHARSET`)、时区设置(`TSDB_OPTION_TIMEZONE`)、配置文件路径设置(`TSDB_OPTION_CONFIGDIR`)。区域设置、字符集、时区默认为操作系统当前设置。 - `char *taos_get_client_info()` From 25d2e2e9036138f1475cb207263981275cd31075 Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Tue, 17 Aug 2021 18:27:19 +0800 Subject: [PATCH 21/35] [TD-4181] : update Architecture related doc. --- documentation20/cn/03.architecture/docs.md | 142 +++++++++++++-------- documentation20/cn/04.model/docs.md | 4 +- 2 files changed, 88 insertions(+), 58 deletions(-) diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md index b481bea9f8..b4a39283bd 100644 --- a/documentation20/cn/03.architecture/docs.md +++ b/documentation20/cn/03.architecture/docs.md @@ -6,6 +6,8 @@ 在典型的物联网、车联网、运维监测场景中,往往有多种不同类型的数据采集设备,采集一个到多个不同的物理量。而同一种采集设备类型,往往又有多个具体的采集设备分布在不同的地点。大数据处理系统就是要将各种采集的数据汇总,然后进行计算和分析。对于同一类设备,其采集的数据都是很规则的。以智能电表为例,假设每个智能电表采集电流、电压、相位三个量,其采集的数据类似如下的表格: + +
@@ -162,7 +164,7 @@ TDengine 分布式架构的逻辑结构图如下: **物理节点(pnode):** pnode是一独立运行、拥有自己的计算、存储和网络能力的计算机,可以是安装有OS的物理机、虚拟机或Docker容器。物理节点由其配置的 FQDN(Fully Qualified Domain Name)来标识。TDengine完全依赖FQDN来进行网络通讯,如果不了解FQDN,请看博文[《一篇文章说清楚TDengine的FQDN》](https://www.taosdata.com/blog/2020/09/11/1824.html)。 -**数据节点(dnode):** dnode 是 TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例,一个工作的系统必须有至少一个数据节点。dnode包含零到多个逻辑的虚拟节点(VNODE),零或者至多一个逻辑的管理节点(mnode)。dnode在系统中的唯一标识由实例的End Point (EP )决定。EP是dnode所在物理节点的FQDN (Fully Qualified Domain Name)和系统所配置的网络端口号(Port)的组合。通过配置不同的端口,一个物理节点(一台物理机、虚拟机或容器)可以运行多个实例,或有多个数据节点。 +**数据节点(dnode):** dnode 是 TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例,一个工作的系统必须有至少一个数据节点。dnode包含零到多个逻辑的虚拟节点(vnode),零或者至多一个逻辑的管理节点(mnode)。dnode在系统中的唯一标识由实例的End Point (EP)决定。EP是dnode所在物理节点的FQDN (Fully Qualified Domain Name)和系统所配置的网络端口号(Port)的组合。通过配置不同的端口,一个物理节点(一台物理机、虚拟机或容器)可以运行多个实例,或有多个数据节点。 **虚拟节点(vnode)**: 为更好的支持数据分片、负载均衡,防止数据过热或倾斜,数据节点被虚拟化成多个虚拟节点(vnode,图中V2, V3, V4等)。每个 vnode 都是一个相对独立的工作单元,是时序数据存储的基本单元,具有独立的运行线程、内存空间与持久化存储的路径。一个 vnode 包含一定数量的表(数据采集点)。当创建一张新表时,系统会检查是否需要创建新的 vnode。一个数据节点上能创建的 vnode 的数量取决于该数据节点所在物理节点的硬件资源。一个 vnode 只属于一个DB,但一个DB可以有多个 vnode。一个 vnode 除存储的时序数据外,也保存有所包含的表的schema、标签值等。一个虚拟节点由所属的数据节点的EP,以及所属的VGroup ID在系统内唯一标识,由管理节点创建并管理。 @@ -176,23 +178,39 @@ TDengine 分布式架构的逻辑结构图如下: **通讯方式:**TDengine系统的各个数据节点之间,以及应用驱动与各数据节点之间的通讯是通过TCP/UDP进行的。因为考虑到物联网场景,数据写入的包一般不大,因此TDengine 除采用TCP做传输之外,还采用UDP方式,因为UDP 更加高效,而且不受连接数的限制。TDengine实现了自己的超时、重传、确认等机制,以确保UDP的可靠传输。对于数据量不到15K的数据包,采取UDP的方式进行传输,超过15K的,或者是查询类的操作,自动采取TCP的方式进行传输。同时,TDengine根据配置和数据包,会自动对数据进行压缩/解压缩,数字签名/认证等处理。对于数据节点之间的数据复制,只采用TCP方式进行数据传输。 -**FQDN配置**:一个数据节点有一个或多个FQDN,可以在系统配置文件taos.cfg通过参数“fqdn"进行指定,如果没有指定,系统将自动获取计算机的hostname作为其FQDN。如果节点没有配置FQDN,可以直接将该节点的配置参数fqdn设置为它的IP地址。但不建议使用IP,因为IP地址可变,一旦变化,将让集群无法正常工作。一个数据节点的EP(End Point)由FQDN + Port组成。采用FQDN,需要保证DNS服务正常工作,或者在节点以及应用所在的节点配置好hosts文件。另外,这个参数值的长度需要控制在 96 个字符以内。 +**FQDN配置:**一个数据节点有一个或多个FQDN,可以在系统配置文件taos.cfg通过参数"fqdn"进行指定,如果没有指定,系统将自动获取计算机的hostname作为其FQDN。如果节点没有配置FQDN,可以直接将该节点的配置参数fqdn设置为它的IP地址。但不建议使用IP,因为IP地址可变,一旦变化,将让集群无法正常工作。一个数据节点的EP(End Point)由FQDN + Port组成。采用FQDN,需要保证DNS服务正常工作,或者在节点以及应用所在的节点配置好hosts文件。另外,这个参数值的长度需要控制在 96 个字符以内。 -**端口配置:**一个数据节点对外的端口由TDengine的系统配置参数serverPort决定,对集群内部通讯的端口是serverPort+5。集群内数据节点之间的数据复制操作还占有一个TCP端口,是serverPort+10. 为支持多线程高效的处理UDP数据,每个对内和对外的UDP连接,都需要占用5个连续的端口。因此一个数据节点总的端口范围为serverPort到serverPort + 10,总共11个TCP/UDP端口。(另外还可能有 RESTful、Arbitrator 所使用的端口,那样的话就一共是 13 个。)使用时,需要确保防火墙将这些端口打开,以备使用。每个数据节点可以配置不同的serverPort。(详细的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port)) +**端口配置:**一个数据节点对外的端口由TDengine的系统配置参数serverPort决定,对集群内部通讯的端口是serverPort+5。为支持多线程高效的处理UDP数据,每个对内和对外的UDP连接,都需要占用5个连续的端口。 -**集群对外连接:** TDengine集群可以容纳单个、多个甚至几千个数据节点。应用只需要向集群中任何一个数据节点发起连接即可,连接需要提供的网络参数是一数据节点的End Point(FQDN加配置的端口号)。通过命令行CLI启动应用taos时,可以通过选项-h来指定数据节点的FQDN, -P来指定其配置的端口号,如果端口不配置,将采用TDengine的系统配置参数serverPort。 +集群内数据节点之间的数据复制操作占用一个TCP端口,是serverPort+10。 -**集群内部通讯**: 各个数据节点之间通过TCP/UDP进行连接。一个数据节点启动时,将获取mnode所在的dnode的EP信息,然后与系统中的mnode建立起连接,交换信息。获取mnode的EP信息有三步,1:检查mnodeEpSet文件是否存在,如果不存在或不能正常打开获得mnode EP信息,进入第二步;2:检查系统配置文件taos.cfg, 获取节点配置参数firstEp, secondEp,(这两个参数指定的节点可以是不带mnode的普通节点,这样的话,节点被连接时会尝试重定向到mnode节点)如果不存在或者taos.cfg里没有这两个配置参数,或无效,进入第三步;3:将自己的EP设为mnode EP, 并独立运行起来。获取mnode EP列表后,数据节点发起连接,如果连接成功,则成功加入进工作的集群,如果不成功,则尝试mnode EP列表中的下一个。如果都尝试了,但连接都仍然失败,则休眠几秒后,再进行尝试。 +集群数据节点对外提供RESTful服务占用一个TCP端口,是serverPort+11。 -**MNODE的选择:** TDengine逻辑上有管理节点,但没有单独的执行代码,服务器侧只有一套执行代码taosd。那么哪个数据节点会是管理节点呢?这是系统自动决定的,无需任何人工干预。原则如下:一个数据节点启动时,会检查自己的End Point, 并与获取的mnode EP List进行比对,如果在其中,该数据节点认为自己应该启动mnode模块,成为mnode。如果自己的EP不在mnode EP List里,则不启动mnode模块。在系统的运行过程中,由于负载均衡、宕机等原因,mnode有可能迁移至新的dnode,但一切都是透明的,无需人工干预,配置参数的修改,是mnode自己根据资源做出的决定。 +集群内数据节点与Arbitrator节点之间通讯占用一个TCP端口,是serverPort+12。 -**新数据节点的加入**:系统有了一个数据节点后,就已经成为一个工作的系统。添加新的节点进集群时,有两个步骤,第一步:使用TDengine CLI连接到现有工作的数据节点,然后用命令”create dnode"将新的数据节点的End Point添加进去; 第二步:在新的数据节点的系统配置参数文件taos.cfg里,将firstEp, secondEp参数设置为现有集群中任意两个数据节点的EP即可。具体添加的详细步骤请见详细的用户手册。这样就把集群一步一步的建立起来。 +因此一个数据节点总的端口范围为serverPort到serverPort+12,总共13个TCP/UDP端口。使用时,需要确保防火墙将这些端口打开。每个数据节点可以配置不同的serverPort。(详细的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port)) -**重定向**:无论是dnode还是taosc,最先都是要发起与mnode的连接,但mnode是系统自动创建并维护的,因此对于用户来说,并不知道哪个dnode在运行mnode。TDengine只要求向系统中任何一个工作的dnode发起连接即可。因为任何一个正在运行的dnode,都维护有目前运行的mnode EP List。当收到一个来自新启动的dnode或taosc的连接请求,如果自己不是mnode,则将mnode EP List回复给对方,taosc或新启动的dnode收到这个list, 就重新尝试建立连接。当mnode EP List发生改变,通过节点之间的消息交互,各个数据节点就很快获取最新列表,并通知taosc。 +**集群对外连接:**TDengine集群可以容纳单个、多个甚至几千个数据节点。应用只需要向集群中任何一个数据节点发起连接即可,连接需要提供的网络参数是一数据节点的End Point(FQDN加配置的端口号)。通过命令行CLI启动应用taos时,可以通过选项-h来指定数据节点的FQDN, -P来指定其配置的端口号,如果端口不配置,将采用TDengine的系统配置参数serverPort。 + +**集群内部通讯:**各个数据节点之间通过TCP/UDP进行连接。一个数据节点启动时,将获取mnode所在的dnode的EP信息,然后与系统中的mnode建立起连接,交换信息。获取mnode的EP信息有三步: + +1:检查mnodeEpSet.json文件是否存在,如果不存在或不能正常打开获得mnode EP信息,进入第二步; + +2:检查系统配置文件taos.cfg,获取节点配置参数firstEp、secondEp(这两个参数指定的节点可以是不带mnode的普通节点,这样的话,节点被连接时会尝试重定向到mnode节点),如果不存在或者taos.cfg里没有这两个配置参数,或无效,进入第三步; + +3:将自己的EP设为mnode EP,并独立运行起来。 + +获取mnode EP列表后,数据节点发起连接,如果连接成功,则成功加入进工作的集群,如果不成功,则尝试mnode EP列表中的下一个。如果都尝试了,但连接都仍然失败,则休眠几秒后,再进行尝试。 + +**MNODE的选择:**TDengine逻辑上有管理节点,但没有单独的执行代码,服务器侧只有一套执行代码taosd。那么哪个数据节点会是管理节点呢?这是系统自动决定的,无需任何人工干预。原则如下:一个数据节点启动时,会检查自己的End Point, 并与获取的mnode EP List进行比对,如果在其中,该数据节点认为自己应该启动mnode模块,成为mnode。如果自己的EP不在mnode EP List里,则不启动mnode模块。在系统的运行过程中,由于负载均衡、宕机等原因,mnode有可能迁移至新的dnode,但一切都是透明的,无需人工干预,配置参数的修改,是mnode自己根据资源做出的决定。 + +**新数据节点的加入:**系统有了一个数据节点后,就已经成为一个工作的系统。添加新的节点进集群时,有两个步骤,第一步:使用TDengine CLI连接到现有工作的数据节点,然后用命令”create dnode"将新的数据节点的End Point添加进去; 第二步:在新的数据节点的系统配置参数文件taos.cfg里,将firstEp, secondEp参数设置为现有集群中任意两个数据节点的EP即可。具体添加的详细步骤请见详细的用户手册。这样就把集群一步一步的建立起来。 + +**重定向:**无论是dnode还是taosc,最先都是要发起与mnode的连接,但mnode是系统自动创建并维护的,因此对于用户来说,并不知道哪个dnode在运行mnode。TDengine只要求向系统中任何一个工作的dnode发起连接即可。因为任何一个正在运行的dnode,都维护有目前运行的mnode EP List。当收到一个来自新启动的dnode或taosc的连接请求,如果自己不是mnode,则将mnode EP List回复给对方,taosc或新启动的dnode收到这个list, 就重新尝试建立连接。当mnode EP List发生改变,通过节点之间的消息交互,各个数据节点就很快获取最新列表,并通知taosc。 ### 一个典型的消息流程 -为解释vnode, mnode, taosc和应用之间的关系以及各自扮演的角色,下面对写入数据这个典型操作的流程进行剖析。 +为解释vnode、mnode、taosc和应用之间的关系以及各自扮演的角色,下面对写入数据这个典型操作的流程进行剖析。 ![TDengine典型的操作流程](page://images/architecture/message.png)
图 2 TDengine典型的操作流程
@@ -249,7 +267,7 @@ TDengine除vnode分片之外,还对时序数据按照时间段进行分区。 每个dnode都定时向 mnode(虚拟管理节点)报告其状态(包括硬盘空间、内存大小、CPU、网络、虚拟节点个数等),因此mnode了解整个集群的状态。基于整体状态,当mnode发现某个dnode负载过重,它会将dnode上的一个或多个vnode挪到其他dnode。在挪动过程中,对外服务继续进行,数据插入、查询和计算操作都不受影响。 -如果mnode一段时间没有收到dnode的状态报告,mnode会认为这个dnode已经离线。如果离线时间超过一定时长(时长由配置参数offlineThreshold决定),该dnode将被mnode强制剔除出集群。该dnode上的vnodes如果副本数大于一,系统将自动在其他dnode上创建新的副本,以保证数据的副本数。如果该dnode上还有mnode, 而且mnode的副本数大于一,系统也将自动在其他dnode上创建新的mnode, 以保证mnode的副本数。 +如果mnode一段时间没有收到dnode的状态报告,mnode会认为这个dnode已经离线。如果离线时间超过一定时长(时长由配置参数offlineThreshold决定),该dnode将被mnode强制剔除出集群。该dnode上的vnodes如果副本数大于1,系统将自动在其他dnode上创建新的副本,以保证数据的副本数。如果该dnode上还有mnode, 而且mnode的副本数大于1,系统也将自动在其他dnode上创建新的mnode, 以保证mnode的副本数。 当新的数据节点被添加进集群,因为新的计算和存储被添加进来,系统也将自动启动负载均衡流程。 @@ -258,55 +276,52 @@ TDengine除vnode分片之外,还对时序数据按照时间段进行分区。 ## 数据写入与复制流程 -如果一个数据库有N个副本,那一个虚拟节点组就有N个虚拟节点,但是只有一个是Master,其他都是slave。当应用将新的记录写入系统时,只有Master vnode能接受写的请求。如果slave vnode收到写的请求,系统将通知taosc需要重新定向。 +如果一个数据库有N个副本,那一个虚拟节点组就有N个虚拟节点,但是只有一个是master,其他都是slave。当应用将新的记录写入系统时,只有master vnode能接受写的请求。如果slave vnode收到写的请求,系统将通知taosc需要重新定向。 -### Master vnode写入流程 +### Master Vnode写入流程 Master Vnode遵循下面的写入流程: ![TDengine Master写入流程](page://images/architecture/write_master.png)
图 3 TDengine Master写入流程
-1. Master vnode收到应用的数据插入请求,验证OK,进入下一步; +1. master vnode收到应用的数据插入请求,验证OK,进入下一步; 2. 如果系统配置参数walLevel大于0,vnode将把该请求的原始数据包写入数据库日志文件WAL。如果walLevel设置为2,而且fsync设置为0,TDengine还将WAL数据立即落盘,以保证即使宕机,也能从数据库日志文件中恢复数据,避免数据的丢失; -3. 如果有多个副本,vnode将把数据包转发给同一虚拟节点组内slave vnodes, 该转发包带有数据的版本号(version); +3. 如果有多个副本,vnode将把数据包转发给同一虚拟节点组内的slave vnodes, 该转发包带有数据的版本号(version); 4. 写入内存,并将记录加入到skip list; -5. Master vnode返回确认信息给应用,表示写入成功。 +5. master vnode返回确认信息给应用,表示写入成功。 6. 如果第2,3,4步中任何一步失败,将直接返回错误给应用。 -### Slave vnode写入流程 +### Slave Vnode写入流程 对于slave vnode, 写入流程是: ![TDengine Slave写入流程](page://images/architecture/write_slave.png)
图 4 TDengine Slave写入流程
-1. Slave vnode收到Master vnode转发了的数据插入请求。 +1. slave vnode收到Master vnode转发了的数据插入请求。检查last version是否与master一致,如果一致,进入下一步。如果不一致,需要进入同步状态。 2. 如果系统配置参数walLevel大于0,vnode将把该请求的原始数据包写入数据库日志文件WAL。如果walLevel设置为2,而且fsync设置为0,TDengine还将WAL数据立即落盘,以保证即使宕机,也能从数据库日志文件中恢复数据,避免数据的丢失; 3. 写入内存,更新内存中的skip list。 -与Master vnode相比,slave vnode不存在转发环节,也不存在回复确认环节,少了两步。但写内存与WAL是完全一样的。 +与master vnode相比,slave vnode不存在转发环节,也不存在回复确认环节,少了两步。但写内存与WAL是完全一样的。 ### 异地容灾、IDC迁移 -从上述Master和Slave流程可以看出,TDengine采用的是异步复制的方式进行数据同步。这种方式能够大幅提高写入性能,网络延时对写入速度不会有大的影响。通过配置每个物理节点的IDC和机架号,可以保证对于一个虚拟节点组,虚拟节点由来自不同IDC、不同机架的物理节点组成,从而实现异地容灾。因此TDengine原生支持异地容灾,无需再使用其他工具。 +从上述master和slave流程可以看出,TDengine采用的是异步复制的方式进行数据同步。这种方式能够大幅提高写入性能,网络延时对写入速度不会有大的影响。通过配置每个物理节点的IDC和机架号,可以保证对于一个虚拟节点组,虚拟节点由来自不同IDC、不同机架的物理节点组成,从而实现异地容灾。因此TDengine原生支持异地容灾,无需再使用其他工具。 -另外一方面,TDengine支持动态修改副本数,一旦副本数增加,新加入的虚拟节点将立即进入数据同步流程,同步结束后,新加入的虚拟节点即可提供服务。而在同步过程中,master以及其他已经同步的虚拟节点都可以对外提供服务。利用这一特性,TDengine可以实现无服务中断的IDC机房迁移。只需要将新IDC的物理节点加入现有集群,等数据同步完成后,再将老的IDC的物理节点从集群中剔除即可。 +另一方面,TDengine支持动态修改副本数,一旦副本数增加,新加入的虚拟节点将立即进入数据同步流程,同步结束后,新加入的虚拟节点即可提供服务。而在同步过程中,master以及其他已经同步的虚拟节点都可以对外提供服务。利用这一特性,TDengine可以实现无服务中断的IDC机房迁移。只需要将新IDC的物理节点加入现有集群,等数据同步完成后,再将老的IDC的物理节点从集群中剔除即可。 但是,这种异步复制的方式,存在极小的时间窗口,丢失写入的数据。具体场景如下: -1. Master vnode完成了它的5步操作,已经给APP确认写入成功,然后宕机; -2. Slave vnode收到写入请求后,在第2步写入日志之前,处理失败 -3. Slave vnode将成为新的master, 从而丢失了一条记录 +1. master vnode完成了它的5步操作,已经给APP确认写入成功,然后宕机 +2. slave vnode收到写入请求后,在第2步写入日志之前,处理失败 +3. slave vnode将成为新的master,从而丢失了一条记录 -理论上,只要是异步复制,就无法保证100%不丢失。但是这个窗口极小,mater与slave要同时发生故障,而且发生在刚给应用确认写入成功之后。 - -注:异地容灾、IDC无中断迁移,仅仅企业版支持。 -**提示:该功能暂未提供** +理论上,只要是异步复制,就无法保证100%不丢失。但是这个窗口极小,master与slave要同时发生故障,而且发生在刚给应用确认写入成功之后。 ### 主从选择 -Vnode会保持一个数据版本号(Version),对内存数据进行持久化存储时,对该版本号也进行持久化存储。每个数据更新操作,无论是采集的时序数据还是元数据,这个版本号将增一。 +Vnode会保持一个数据版本号(version),对内存数据进行持久化存储时,对该版本号也进行持久化存储。每个数据更新操作,无论是采集的时序数据还是元数据,这个版本号将增加1。 一个vnode启动时,角色(master、slave) 是不定的,数据是处于未同步状态,它需要与虚拟节点组内其他节点建立TCP连接,并互相交换status,其中包括version和自己的角色。通过status的交换,系统进入选主流程,规则如下: @@ -319,7 +334,7 @@ Vnode会保持一个数据版本号(Version),对内存数据进行持久化存 ### 同步复制 -对于数据一致性要求更高的场景,异步数据复制无法满足要求,因为有极小的概率丢失数据,因此TDengine提供同步复制的机制供用户选择。在创建数据库时,除指定副本数replica之外,用户还需要指定新的参数quorum。如果quorum大于一,它表示每次Master转发给副本时,需要等待quorum-1个回复确认,才能通知应用,数据在slave已经写入成功。如果在一定的时间内,得不到quorum-1个回复确认,master vnode将返回错误给应用。 +对于数据一致性要求更高的场景,异步数据复制无法满足要求,因为有极小的概率丢失数据,因此TDengine提供同步复制的机制供用户选择。在创建数据库时,除指定副本数replica之外,用户还需要指定新的参数quorum。如果quorum大于1,它表示每次master转发给副本时,需要等待quorum-1个回复确认,才能通知应用,数据在slave已经写入成功。如果在一定的时间内,得不到quorum-1个回复确认,master vnode将返回错误给应用。 采用同步复制,系统的性能会有所下降,而且latency会增加。因为元数据要强一致,mnode之间的数据同步缺省就是采用的同步复制。 @@ -329,19 +344,19 @@ Vnode会保持一个数据版本号(Version),对内存数据进行持久化存 TDengine采用时间驱动缓存管理策略(First-In-First-Out,FIFO),又称为写驱动的缓存管理机制。这种策略有别于读驱动的数据缓存模式(Least-Recent-Used,LRU),直接将最近写入的数据保存在系统的缓存中。当缓存达到临界值的时候,将最早的数据批量写入磁盘。一般意义上来说,对于物联网数据的使用,用户最为关心的是刚产生的数据,即当前状态。TDengine充分利用这一特性,将最近到达的(当前状态)数据保存在缓存中。 -TDengine通过查询函数向用户提供毫秒级的数据获取能力。直接将最近到达的数据保存在缓存中,可以更加快速地响应用户针对最近一条或一批数据的查询分析,整体上提供更快的数据库查询响应能力。从这个意义上来说,**可通过设置合适的配置参数将TDengine作为数据缓存来使用,而不需要再部署Redis或其他额外的缓存系统**,可有效地简化系统架构,降低运维的成本。需要注意的是,TDengine重启以后系统的缓存将被清空,之前缓存的数据均会被批量写入磁盘,缓存的数据将不会像专门的Key-value缓存系统再将之前缓存的数据重新加载到缓存中。 +TDengine通过查询函数向用户提供毫秒级的数据获取能力。直接将最近到达的数据保存在缓存中,可以更加快速地响应用户针对最近一条或一批数据的查询分析,整体上提供更快的数据库查询响应能力。从这个意义上来说,**可通过设置合适的配置参数将TDengine作为数据缓存来使用,而不需要再部署Redis或其他额外的缓存系统**,可有效地简化系统架构,降低运维的成本。需要注意的是,TDengine重启以后系统的缓存将被清空,之前缓存的数据均会被批量写入磁盘,缓存的数据将不会像专门的key-value缓存系统再将之前缓存的数据重新加载到缓存中。 每个vnode有自己独立的内存,而且由多个固定大小的内存块组成,不同vnode之间完全隔离。数据写入时,类似于日志的写法,数据被顺序追加写入内存,但每个vnode维护有自己的skip list,便于迅速查找。当三分之一以上的内存块写满时,启动落盘操作,而且后续写的操作在新的内存块进行。这样,一个vnode里有三分之一内存块是保留有最近的数据的,以达到缓存、快速查找的目的。一个vnode的内存块的个数由配置参数blocks决定,内存块的大小由配置参数cache决定。 ### 持久化存储 -TDengine采用数据驱动的方式让缓存中的数据写入硬盘进行持久化存储。当vnode中缓存的数据达到一定规模时,为了不阻塞后续数据的写入,TDengine也会拉起落盘线程将缓存的数据写入持久化存储。TDengine在数据落盘时会打开新的数据库日志文件,在落盘成功后则会删除老的数据库日志文件,避免日志文件无限制的增长。 +TDengine采用数据驱动的方式让缓存中的数据写入硬盘进行持久化存储。当vnode中缓存的数据达到一定规模时,为了不阻塞后续数据的写入,TDengine也会拉起落盘线程将缓存的数据写入持久化存储。TDengine在数据落盘时会打开新的数据库日志文件,在落盘成功后则会删除老的数据库日志文件,避免日志文件无限制地增长。 为充分利用时序数据特点,TDengine将一个vnode保存在持久化存储的数据切分成多个文件,每个文件只保存固定天数的数据,这个天数由系统配置参数days决定。切分成多个文件后,给定查询的起止日期,无需任何索引,就可以立即定位需要打开哪些数据文件,大大加快读取速度。 对于采集的数据,一般有保留时长,这个时长由系统配置参数keep决定。超过这个设置天数的数据文件,将被系统自动删除,释放存储空间。 -给定days与keep两个参数,一个典型工作状态的vnode中总的数据文件数为:`向上取整(keep/days)+1`个。总的数据文件个数不宜过大,也不宜过小。10到100以内合适。基于这个原则,可以设置合理的days。 目前的版本,参数keep可以修改,但对于参数days,一但设置后,不可修改。 +给定days与keep两个参数,一个典型工作状态的vnode中总的数据文件数为:`向上取整(keep/days)+1`个。总的数据文件个数不宜过大,也不宜过小。10到100以内合适。基于这个原则,可以设置合理的days。目前的版本,参数keep可以修改,但对于参数days,一旦设置后,不可修改。 在每个数据文件里,一张表的数据是一块一块存储的。一张表可以有一到多个数据文件块。在一个文件块里,数据是列式存储的,占用的是一片连续的存储空间,这样大大提高读取速度。文件块的大小由系统参数maxRows(每块最大记录条数)决定,缺省值为4096。这个值不宜过大,也不宜过小。过大,定位具体时间段的数据的搜索时间会变长,影响读取速度;过小,数据块的索引太大,压缩效率偏低,也影响读取速度。 @@ -351,32 +366,47 @@ TDengine采用数据驱动的方式让缓存中的数据写入硬盘进行持久 ### 多级存储 -在默认配置下,TDengine会将所有数据保存在/var/lib/taos目录下,而且每个vnode的数据文件保存在该目录下的不同目录。为扩大存储空间,尽量减少文件读取的瓶颈,提高数据吞吐率 TDengine可通过配置系统参数dataDir让多个挂载的硬盘被系统同时使用。除此之外,TDengine也提供了数据分级存储的功能,即根据数据文件的新老程度存储在不同的存储介质上。比如最新的数据存储在SSD上,超过一周的数据存储在本地硬盘上,超过4周的数据存储在网络存储设备上,这样来降低存储成本,而又保证高效的访问数据。数据在不同存储介质上的移动是由系统自动完成的,对应用是完全透明的。数据的分级存储也是通过系统参数dataDir来配置。 +说明:多级存储功能仅企业版支持,从 2.0.16.0 版本开始提供。 -dataDir的配置格式如下: -``` -dataDir data_path [tier_level] -``` -其中data_path为挂载点的文件夹路径,tier_level为介质存储等级。介质存储等级越高,盛放数据文件越老。同一存储等级可挂载多个硬盘,同一存储等级上的数据文件分布在该存储等级的所有硬盘上。TDengine最多支持3级存储,所以tier_level的取值为0、1和2。在配置dataDir时,必须存在且只有一个挂载路径不指定tier_level,称之为特殊挂载盘(路径)。该挂载路径默认为0级存储介质,且包含特殊文件链接,不可被移除,否则会对写入的数据产生毁灭性影响。 +在默认配置下,TDengine会将所有数据保存在/var/lib/taos目录下,而且每个vnode的数据文件保存在该目录下的不同目录。为扩大存储空间,尽量减少文件读取的瓶颈,提高数据吞吐率 TDengine可通过配置系统参数dataDir让多个挂载的硬盘被系统同时使用。 -假设一物理节点有六个可挂载的硬盘/mnt/disk1、/mnt/disk2、…、/mnt/disk6,其中disk1和disk2需要被指定为0级存储介质,disk3和disk4为1级存储介质, disk5和disk6为2级存储介质。disk1为特殊挂载盘,则可在/etc/taos/taos.cfg中做如下配置: +除此之外,TDengine也提供了数据分级存储的功能,将不同时间段的数据存储在挂载的不同介质上的目录里,从而实现不同“热度”的数据存储在不同的存储介质上,充分利用存储,节约成本。比如,最新采集的数据需要经常访问,对硬盘的读取性能要求高,那么用户可以配置将这些数据存储在SSD盘上。超过一定期限的数据,查询需求量没有那么高,那么可以存储在相对便宜的HDD盘上。 + +多级存储支持3级,每级最多可配置16个挂载点。 + +TDengine多级存储配置方式如下(在配置文件/etc/taos/taos.cfg中): ``` -dataDir /mnt/disk1/taos -dataDir /mnt/disk2/taos 0 -dataDir /mnt/disk3/taos 1 -dataDir /mnt/disk4/taos 1 -dataDir /mnt/disk5/taos 2 -dataDir /mnt/disk6/taos 2 +dataDir [path] ``` -挂载的盘也可以是非本地的网络盘,只要系统能访问即可。 +- path: 挂载点的文件夹路径 +- level: 介质存储等级,取值为0,1,2。 + 0级存储最新的数据,1级存储次新的数据,2级存储最老的数据,省略默认为0。 + 各级存储之间的数据流向:0级存储 -> 1级存储 -> 2级存储。 + 同一存储等级可挂载多个硬盘,同一存储等级上的数据文件分布在该存储等级的所有硬盘上。 + 需要说明的是,数据在不同级别的存储介质上的移动,是由系统自动完成的,用户无需干预。 +- primary: 是否为主挂载点,0(是)或1(否),省略默认为1。 -注:多级存储功能仅企业版支持 +在配置中,只允许一个主挂载点的存在(level=0, primary=0),例如采用如下的配置方式: + +``` +dataDir /mnt/data1 0 0 +dataDir /mnt/data2 0 1 +dataDir /mnt/data3 1 1 +dataDir /mnt/data4 1 1 +dataDir /mnt/data5 2 1 +dataDir /mnt/data6 2 1 +``` + +注意: +1. 多级存储不允许跨级配置,合法的配置方案有:仅0级,仅0级+1级,以及0级+1级+2级。而不允许只配置level=0和level=2,而不配置level=1。 +2. 禁止手动移除使用中的挂载盘,挂载盘目前不支持非本地的网络盘。 +3. 多级存储目前不支持删除已经挂载的硬盘的功能。 ## 数据查询 -TDengine提供了多种多样针对表和超级表的查询处理功能,除了常规的聚合查询之外,还提供针对时序数据的窗口查询、统计聚合等功能。TDengine的查询处理需要客户端、vnode, mnode节点协同完成。 +TDengine提供了多种多样针对表和超级表的查询处理功能,除了常规的聚合查询之外,还提供针对时序数据的窗口查询、统计聚合等功能。TDengine的查询处理需要客户端、vnode、mnode节点协同完成。 ### 单表查询 @@ -388,31 +418,31 @@ SQL语句的解析和校验工作在客户端完成。解析SQL语句并生成 ### 按时间轴聚合、降采样、插值 -时序数据有别于普通数据的显著特征是每条记录均具有时间戳,因此针对具有时间戳数据在时间轴上进行聚合是不同于普通数据库的重要功能。从这点上来看,与流计算引擎的窗口查询有相似的地方。 +时序数据有别于普通数据的显著特征是每条记录均具有时间戳,因此针对具有时间戳的数据在时间轴上进行聚合是不同于普通数据库的重要功能。从这点上来看,与流计算引擎的窗口查询有相似的地方。 在TDengine中引入关键词interval来进行时间轴上固定长度时间窗口的切分,并按照时间窗口对数据进行聚合,对窗口范围内的数据按需进行聚合。例如: -```mysql -select count(*) from d1001 interval(1h); +```sql +SELECT COUNT(*) FROM d1001 INTERVAL(1h); ``` 针对d1001设备采集的数据,按照1小时的时间窗口返回每小时存储的记录数量。 -在需要连续获得查询结果的应用场景下,如果给定的时间区间存在数据缺失,会导致该区间数据结果也丢失。TDengine提供策略针对时间轴聚合计算的结果进行插值,通过使用关键词Fill就能够对时间轴聚合结果进行插值。例如: -```mysql -select count(*) from d1001 interval(1h) fill(prev); +在需要连续获得查询结果的应用场景下,如果给定的时间区间存在数据缺失,会导致该区间数据结果也丢失。TDengine提供策略针对时间轴聚合计算的结果进行插值,通过使用关键词fill就能够对时间轴聚合结果进行插值。例如: +```sql +SELECT COUNT(*) FROM d1001 WHERE ts >= '2017-7-14 00:00:00' AND ts < '2017-7-14 23:59:59' INTERVAL(1h) FILL(PREV); ``` 针对d1001设备采集数据统计每小时记录数,如果某一个小时不存在数据,则返回之前一个小时的统计数据。TDengine提供前向插值(prev)、线性插值(linear)、NULL值填充(NULL)、特定值填充(value)。 ### 多表聚合查询 -TDengine对每个数据采集点单独建表,但在实际应用中经常需要对不同的采集点数据进行聚合。为高效的进行聚合操作,TDengine引入超级表(STable)的概念。超级表用来代表一特定类型的数据采集点,它是包含多张表的表集合,集合里每张表的模式(schema)完全一致,但每张表都带有自己的静态标签,标签可以多个,可以随时增加、删除和修改。 应用可通过指定标签的过滤条件,对一个STable下的全部或部分表进行聚合或统计操作,这样大大简化应用的开发。其具体流程如下图所示: +TDengine对每个数据采集点单独建表,但在实际应用中经常需要对不同的采集点数据进行聚合。为高效的进行聚合操作,TDengine引入超级表(STable)的概念。超级表用来代表一特定类型的数据采集点,它是包含多张表的表集合,集合里每张表的模式(schema)完全一致,但每张表都带有自己的静态标签,标签可以有多个,可以随时增加、删除和修改。应用可通过指定标签的过滤条件,对一个STable下的全部或部分表进行聚合或统计操作,这样大大简化应用的开发。其具体流程如下图所示: ![多表聚合查询原理图](page://images/architecture/multi_tables.png)
图 5 多表聚合查询原理图
1. 应用将一个查询条件发往系统; -2. taosc将超级表的名字发往 Meta Node(管理节点); +2. taosc将超级表的名字发往 meta node(管理节点); 3. 管理节点将超级表所拥有的 vnode 列表发回 taosc; 4. taosc将计算的请求连同标签过滤条件发往这些vnode对应的多个数据节点; 5. 每个vnode先在内存里查找出自己节点里符合标签过滤条件的表的集合,然后扫描存储的时序数据,完成相应的聚合计算,将结果返回给taosc; diff --git a/documentation20/cn/04.model/docs.md b/documentation20/cn/04.model/docs.md index fd73474517..af4f85b5eb 100644 --- a/documentation20/cn/04.model/docs.md +++ b/documentation20/cn/04.model/docs.md @@ -31,7 +31,7 @@ USE power; ## 创建超级表 -一个物联网系统,往往存在多种类型的设备,比如对于电网,存在智能电表、变压器、母线、开关等等。为便于多表之间的聚合,使用TDengine, 需要对每个类型的数据采集点创建一个超级表。以表1中的智能电表为例,可以使用如下的SQL命令创建超级表: +一个物联网系统,往往存在多种类型的设备,比如对于电网,存在智能电表、变压器、母线、开关等等。为便于多表之间的聚合,使用TDengine, 需要对每个类型的数据采集点创建一个超级表。以[表1](https://www.taosdata.com/cn/documentation/architecture#model_table1)中的智能电表为例,可以使用如下的SQL命令创建超级表: ```mysql CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int); @@ -47,7 +47,7 @@ CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAG ## 创建表 -TDengine对每个数据采集点需要独立建表。与标准的关系型数据库一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以表1中的智能电表为例,可以使用如下的SQL命令建表: +TDengine对每个数据采集点需要独立建表。与标准的关系型数据库一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以[表1](https://www.taosdata.com/cn/documentation/architecture#model_table1)中的智能电表为例,可以使用如下的SQL命令建表: ```mysql CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2); From b01275d5db8fc23f0bae731eb3e52f97c6b8b004 Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Tue, 17 Aug 2021 18:41:14 +0800 Subject: [PATCH 22/35] [TD-4181] : update Model example doc in Architecture section. --- documentation20/cn/03.architecture/docs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md index b4a39283bd..38ab64fe7e 100644 --- a/documentation20/cn/03.architecture/docs.md +++ b/documentation20/cn/03.architecture/docs.md @@ -104,7 +104,7 @@
表1:智能电表数据示例
-每一条记录都有设备ID,时间戳,采集的物理量(如上图中的电流、电压、相位),还有与每个设备相关的静态标签(如上述表一中的位置Location和分组groupId)。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。 +每一条记录都有设备ID,时间戳,采集的物理量(如上图中的电流、电压、相位),还有与每个设备相关的静态标签(如上述表1中的位置Location和分组groupId)。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。 ### 数据特征 @@ -143,7 +143,7 @@ TDengine 建议用数据采集点的名字(如上表中的D1001)来做表名。 由于一个数据采集点一张表,导致表的数量巨增,难以管理,而且应用经常需要做采集点之间的聚合操作,聚合的操作也变得复杂起来。为解决这个问题,TDengine引入超级表(Super Table,简称为STable)的概念。 -超级表是指某一特定类型的数据采集点的集合。同一类型的数据采集点,其表的结构是完全一样的,但每个表(数据采集点)的静态属性(标签)是不一样的。描述一个超级表(某一特定类型的数据采集点的结合),除需要定义采集量的表结构之外,还需要定义其标签的schema,标签的数据类型可以是整数、浮点数、字符串,标签可以有多个,可以事后增加、删除或修改。 如果整个系统有N个不同类型的数据采集点,就需要建立N个超级表。 +超级表是指某一特定类型的数据采集点的集合。同一类型的数据采集点,其表的结构是完全一样的,但每个表(数据采集点)的静态属性(标签)是不一样的。描述一个超级表(某一特定类型的数据采集点的集合),除需要定义采集量的表结构之外,还需要定义其标签的schema,标签的数据类型可以是整数、浮点数、字符串,标签可以有多个,可以事后增加、删除或修改。如果整个系统有N个不同类型的数据采集点,就需要建立N个超级表。 在TDengine的设计里,**表用来代表一个具体的数据采集点,超级表用来代表一组相同类型的数据采集点集合**。当为某个具体数据采集点创建表时,用户使用超级表的定义做模板,同时指定该具体采集点(表)的标签值。与传统的关系型数据库相比,表(一个数据采集点)是带有静态标签的,而且这些标签可以事后增加、删除、修改。**一张超级表包含有多张表,这些表具有相同的时序数据schema,但带有不同的标签值**。 From 40f76a4cf7d6c9a5a0178a6ada2f49e45f767d97 Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Tue, 17 Aug 2021 22:02:46 +0800 Subject: [PATCH 23/35] [TD-4181] : update Getting-started related doc. --- documentation20/cn/02.getting-started/docs.md | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/documentation20/cn/02.getting-started/docs.md b/documentation20/cn/02.getting-started/docs.md index 4ae4ebf4d0..f376d1b30c 100644 --- a/documentation20/cn/02.getting-started/docs.md +++ b/documentation20/cn/02.getting-started/docs.md @@ -22,7 +22,8 @@ TDengine 的安装非常简单,从下载到安装成功仅仅只要几秒钟 具体的安装过程,请参见 [TDengine 多种安装包的安装和卸载](https://www.taosdata.com/blog/2019/08/09/566.html) 以及 [视频教程](https://www.taosdata.com/blog/2020/11/11/1941.html)。 -## 轻松启动 + +## 轻松启动 安装成功后,用户可使用 `systemctl` 命令来启动 TDengine 的服务进程。 @@ -30,7 +31,7 @@ TDengine 的安装非常简单,从下载到安装成功仅仅只要几秒钟 $ systemctl start taosd ``` -检查服务是否正常工作。 +检查服务是否正常工作: ```bash $ systemctl status taosd ``` @@ -40,20 +41,20 @@ $ systemctl status taosd **注意:** - systemctl 命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo 。 -- 为更好的获得产品反馈,改善产品,TDengine 会采集基本的使用信息,但您可以修改系统配置文件 taos.cfg 里的配置参数 telemetryReporting, 将其设为 0,就可将其关闭。 +- 为更好的获得产品反馈,改善产品,TDengine 会采集基本的使用信息,但您可以修改系统配置文件 taos.cfg 里的配置参数 telemetryReporting,将其设为 0,就可将其关闭。 - TDengine 采用 FQDN (一般就是 hostname )作为节点的 ID,为保证正常运行,需要给运行 taosd 的服务器配置好 hostname,在客户端应用运行的机器配置好 DNS 服务或 hosts 文件,保证 FQDN 能够解析。 - `systemctl stop taosd` 指令在执行后并不会马上停止 TDengine 服务,而是会等待系统中必要的落盘工作正常完成。在数据量很大的情况下,这可能会消耗较长时间。 -* TDengine 支持在使用 [`systemd`](https://en.wikipedia.org/wiki/Systemd) 做进程服务管理的 linux 系统上安装,用 `which systemctl` 命令来检测系统中是否存在 `systemd` 包: +* TDengine 支持在使用 [`systemd`](https://en.wikipedia.org/wiki/Systemd) 做进程服务管理的 Linux 系统上安装,用 `which systemctl` 命令来检测系统中是否存在 `systemd` 包: ```bash $ which systemctl ``` - 如果系统中不支持 systemd,也可以用手动运行 /usr/local/taos/bin/taosd 方式启动 TDengine 服务。 + 如果系统中不支持 `systemd`,也可以用手动运行 /usr/local/taos/bin/taosd 方式启动 TDengine 服务。 - -## TDengine 命令行程序 + +## TDengine 命令行程序 执行 TDengine 命令行程序,您只要在 Linux 终端执行 `taos` 即可。 @@ -83,14 +84,14 @@ select * from t; Query OK, 2 row(s) in set (0.003128s) ``` -除执行 SQL 语句外,系统管理员还可以从 TDengine 终端检查系统运行状态,添加删除用户账号等。 +除执行 SQL 语句外,系统管理员还可以从 TDengine 终端进行检查系统运行状态、添加删除用户账号等操作。 -### 命令行参数 +**命令行参数** 您可通过配置命令行参数来改变 TDengine 终端的行为。以下为常用的几个命令行参数: -- -c, --config-dir: 指定配置文件目录,默认为 _/etc/taos_ -- -h, --host: 指定服务的 FQDN 地址(也可以使用 IP),默认为连接本地服务 +- -c, --config-dir: 指定配置文件目录,默认为 `/etc/taos` +- -h, --host: 指定服务的 FQDN 地址或 IP 地址,默认为连接本地服务 - -s, --commands: 在不进入终端的情况下运行 TDengine 命令 - -u, --user: 连接 TDengine 服务器的用户名,缺省为 root - -p, --password: 连接TDengine服务器的密码,缺省为 taosdata @@ -99,10 +100,10 @@ Query OK, 2 row(s) in set (0.003128s) 示例: ```bash -$ taos -h 192.168.0.1 -s "use db; show tables;" +$ taos -h h1.taos.com -s "use db; show tables;" ``` -### 运行 SQL 命令脚本 +**运行 SQL 命令脚本** TDengine 终端可以通过 `source` 命令来运行 SQL 命令脚本. @@ -110,13 +111,14 @@ TDengine 终端可以通过 `source` 命令来运行 SQL 命令脚本. taos> source ; ``` -### Shell 小技巧 +**Shell 小技巧** - 可以使用上下光标键查看历史输入的指令 -- 修改用户密码,在 shell 中使用 alter user 指令 +- 修改用户密码:在 shell 中使用 `alter user` 命令,缺省密码为 taosdata - ctrl+c 中止正在进行中的查询 -- 执行 `RESET QUERY CACHE` 清空本地缓存的表 schema - +- 执行 `RESET QUERY CACHE` 可清除本地缓存的表 schema +- 批量执行 SQL 语句。可以将一系列的 shell 命令(以英文 ; 结尾,每个 SQL 语句为一行)按行存放在文件里,在 shell 里执行命令 `source ` 自动执行该文件里所有的 SQL 语句 +- 输入 q 回车,退出 taos shell ## TDengine 极速体验 From e4fe2ebbfbe8bebc7c123e70958b29f01ef5f5fb Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Tue, 17 Aug 2021 22:15:33 +0800 Subject: [PATCH 24/35] [TD-4181] : update Evaluation related doc. --- documentation20/cn/01.evaluation/docs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation20/cn/01.evaluation/docs.md b/documentation20/cn/01.evaluation/docs.md index 7f70ccec56..f7cdc31034 100644 --- a/documentation20/cn/01.evaluation/docs.md +++ b/documentation20/cn/01.evaluation/docs.md @@ -10,8 +10,8 @@ TDengine的模块之一是时序数据库。但除此之外,为减少研发的 * __硬件或云服务成本降至1/5__:由于超强性能,计算资源不到通用大数据方案的1/5;通过列式存储和先进的压缩算法,存储空间不到通用数据库的1/10。 * __全栈时序数据处理引擎__:将数据库、消息队列、缓存、流式计算等功能融为一体,应用无需再集成Kafka/Redis/HBase/Spark/HDFS等软件,大幅降低应用开发和维护的复杂度成本。 * __强大的分析功能__:无论是十年前还是一秒钟前的数据,指定时间范围即可查询。数据可在时间轴上或多个设备上进行聚合。即席查询可通过Shell, Python, R, MATLAB随时进行。 -* __与第三方工具无缝连接__:不用一行代码,即可与Telegraf, Grafana, EMQ, HiveMQ, Prometheus, MATLAB, R等集成。后续将支持OPC, Hadoop, Spark等, BI工具也将无缝连接。 -* __零运维成本、零学习成本__:安装集群简单快捷,无需分库分表,实时备份。类似标准SQL,支持RESTful, 支持Python/Java/C/C++/C#/Go/Node.js, 与MySQL相似,零学习成本。 +* __与第三方工具无缝连接__:不用一行代码,即可与Telegraf, Grafana, EMQ, HiveMQ, Prometheus, MATLAB, R等集成。后续将支持OPC, Hadoop, Spark等,BI工具也将无缝连接。 +* __零运维成本、零学习成本__:安装集群简单快捷,无需分库分表,实时备份。类标准SQL,支持RESTful,支持Python/Java/C/C++/C#/Go/Node.js, 与MySQL相似,零学习成本。 采用TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。但需要指出的是,因充分利用了物联网时序数据的特点,它无法用来处理网络爬虫、微博、微信、电商、ERP、CRM等通用型数据。 From 858be72da7c6f931c6e0885dc7284ec1bcc57608 Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Wed, 18 Aug 2021 02:30:07 +0800 Subject: [PATCH 25/35] [TD-4181] : fix html table code. --- documentation20/cn/03.architecture/docs.md | 5 ++--- documentation20/cn/08.connector/01.java/docs.md | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md index 38ab64fe7e..b53938dbec 100644 --- a/documentation20/cn/03.architecture/docs.md +++ b/documentation20/cn/03.architecture/docs.md @@ -8,14 +8,13 @@ -
设备ID
+
- @@ -100,7 +99,7 @@ -
设备ID 时间戳 采集量 标签
Device ID Time Stamp2
+
表1:智能电表数据示例
diff --git a/documentation20/cn/08.connector/01.java/docs.md b/documentation20/cn/08.connector/01.java/docs.md index f22a1a3803..e1a5654871 100644 --- a/documentation20/cn/08.connector/01.java/docs.md +++ b/documentation20/cn/08.connector/01.java/docs.md @@ -88,7 +88,7 @@ TDengine 的 JDBC 驱动实现尽可能与关系型数据库驱动保持一致 ### JDBC-JNI和JDBC-RESTful的对比 - +
From 121e0bc0332695e137e80ee68673e316ade8668b Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 17 Aug 2021 19:34:43 +0000 Subject: [PATCH 26/35] [TD-6131] show vnodes crash --- src/mnode/src/mnodeDnode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c index 335f9af528..89bc0169d5 100644 --- a/src/mnode/src/mnodeDnode.c +++ b/src/mnode/src/mnodeDnode.c @@ -1238,7 +1238,7 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo pIter = mnodeGetNextVgroup(pIter, &pVgroup); if (pVgroup == NULL) break; - for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { + for (int32_t i = pShow->index; i < pVgroup->numOfVnodes && numOfRows < rows; ++i) { SVnodeGid *pVgid = &pVgroup->vnodeGid[i]; if (pVgid->pDnode == pDnode) { cols = 0; @@ -1250,9 +1250,12 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; STR_TO_VARSTR(pWrite, syncRole[pVgid->role]); cols++; - numOfRows++; } + pShow->index = i; + } + if (numOfRows >= rows) { + break; } mnodeDecVgroupRef(pVgroup); From c4136b1b39b0da6b340e4457a20a5f2a117f1af2 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 17 Aug 2021 20:11:47 +0000 Subject: [PATCH 27/35] [TD-6131] show vnodes crash --- src/mnode/inc/mnodeDef.h | 1 + src/mnode/src/mnodeDnode.c | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mnode/inc/mnodeDef.h b/src/mnode/inc/mnodeDef.h index 5521267841..5acc8dd85e 100644 --- a/src/mnode/inc/mnodeDef.h +++ b/src/mnode/inc/mnodeDef.h @@ -274,6 +274,7 @@ typedef struct { int32_t rowSize; int32_t numOfRows; void * pIter; + void * pVgIter; void ** ppShow; int16_t offset[TSDB_MAX_COLUMNS]; int32_t bytes[TSDB_MAX_COLUMNS]; diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c index 89bc0169d5..320aa44ca6 100644 --- a/src/mnode/src/mnodeDnode.c +++ b/src/mnode/src/mnodeDnode.c @@ -1232,13 +1232,12 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo pDnode = (SDnodeObj *)(pShow->pIter); if (pDnode != NULL) { - void *pIter = NULL; SVgObj *pVgroup; while (1) { - pIter = mnodeGetNextVgroup(pIter, &pVgroup); + pShow->pVgIter = mnodeGetNextVgroup(pShow->pVgIter, &pVgroup); if (pVgroup == NULL) break; - for (int32_t i = pShow->index; i < pVgroup->numOfVnodes && numOfRows < rows; ++i) { + for (int32_t i = 0; i < pVgroup->numOfVnodes && numOfRows < rows; ++i) { SVnodeGid *pVgid = &pVgroup->vnodeGid[i]; if (pVgid->pDnode == pDnode) { cols = 0; @@ -1251,8 +1250,8 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo STR_TO_VARSTR(pWrite, syncRole[pVgid->role]); cols++; numOfRows++; + } - pShow->index = i; } if (numOfRows >= rows) { break; From 584666056604327a5c3ecbf6fda1a02fc48a1a85 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 17 Aug 2021 21:13:03 +0000 Subject: [PATCH 28/35] [TD-6131] show vnodes crash --- src/mnode/src/mnodeDnode.c | 6 ++++++ src/mnode/src/mnodeShow.c | 9 +++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c index 320aa44ca6..7dd199cca4 100644 --- a/src/mnode/src/mnodeDnode.c +++ b/src/mnode/src/mnodeDnode.c @@ -196,14 +196,20 @@ int32_t mnodeInitDnodes() { mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_CREATE_DNODE, mnodeProcessCreateDnodeMsg); mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_DROP_DNODE, mnodeProcessDropDnodeMsg); mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_CONFIG_DNODE, mnodeProcessCfgDnodeMsg); + mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_CONFIG_DNODE_RSP, mnodeProcessCfgDnodeMsgRsp); mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_STATUS, mnodeProcessDnodeStatusMsg); + mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_MODULE, mnodeGetModuleMeta); mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_MODULE, mnodeRetrieveModules); + mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_VARIABLES, mnodeGetConfigMeta); mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_VARIABLES, mnodeRetrieveConfigs); + mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_VNODES, mnodeGetVnodeMeta); mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_VNODES, mnodeRetrieveVnodes); + mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_VNODES, mnodeCancelGetNextVgroup); + mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_DNODE, mnodeGetDnodeMeta); mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_DNODE, mnodeRetrieveDnodes); mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_DNODE, mnodeCancelGetNextDnode); diff --git a/src/mnode/src/mnodeShow.c b/src/mnode/src/mnodeShow.c index 570f5c344b..bbfdb52e05 100644 --- a/src/mnode/src/mnodeShow.c +++ b/src/mnode/src/mnodeShow.c @@ -422,8 +422,13 @@ static void* mnodePutShowObj(SShowObj *pShow) { static void mnodeFreeShowObj(void *data) { SShowObj *pShow = *(SShowObj **)data; - if (tsMnodeShowFreeIterFp[pShow->type] != NULL && pShow->pIter != NULL) { - (*tsMnodeShowFreeIterFp[pShow->type])(pShow->pIter); + if (tsMnodeShowFreeIterFp[pShow->type] != NULL) { + if (pShow->pVgIter != NULL) { + // only used in 'show vnodes "ep"' + (*tsMnodeShowFreeIterFp[pShow->type])(pShow->pVgIter); + } else { + if (pShow->pIter != NULL) (*tsMnodeShowFreeIterFp[pShow->type])(pShow->pIter); + } } mDebug("%p, show is destroyed, data:%p index:%d", pShow, data, pShow->index); From 11996d25768daadf15f95007c41b95482ff3cff9 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 17 Aug 2021 21:42:23 +0000 Subject: [PATCH 29/35] [TD-6131] show vnodes crash --- src/common/inc/tglobal.h | 3 +++ src/common/src/tglobal.c | 5 +++++ src/tsdb/src/tsdbFS.c | 4 +--- src/util/inc/tconfig.h | 1 - 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 947fed60e4..4b8347ead0 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -107,6 +107,9 @@ extern int32_t tsQuorum; extern int8_t tsUpdate; extern int8_t tsCacheLastRow; +//tsdb +extern bool tsdbForceKeepFile; + // balance extern int8_t tsEnableBalance; extern int8_t tsAlternativeRole; diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 44b3e87e7d..b7930dd43e 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -151,6 +151,11 @@ int32_t tsMinTablePerVnode = TSDB_TABLES_STEP; int32_t tsMaxTablePerVnode = TSDB_DEFAULT_TABLES; int32_t tsTableIncStepPerVnode = TSDB_TABLES_STEP; +// tsdb config + +// For backward compatibility +bool tsdbForceKeepFile = false; + // balance int8_t tsEnableBalance = 1; int8_t tsAlternativeRole = 0; diff --git a/src/tsdb/src/tsdbFS.c b/src/tsdb/src/tsdbFS.c index 68450301d8..63f89c1957 100644 --- a/src/tsdb/src/tsdbFS.c +++ b/src/tsdb/src/tsdbFS.c @@ -37,8 +37,6 @@ static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo, int32_t *nExpired); static int tsdbProcessExpiredFS(STsdbRepo *pRepo); static int tsdbCreateMeta(STsdbRepo *pRepo); -// For backward compatibility -bool tsdbForceKeepFile = false; // ================== CURRENT file header info static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) { int tlen = 0; @@ -1354,4 +1352,4 @@ static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo, int32_t *nExpired) { tsdbCloseDFileSet(&fset); } -} \ No newline at end of file +} diff --git a/src/util/inc/tconfig.h b/src/util/inc/tconfig.h index f146ec0b8b..d03ce6e0f1 100644 --- a/src/util/inc/tconfig.h +++ b/src/util/inc/tconfig.h @@ -81,7 +81,6 @@ typedef struct { extern SGlobalCfg tsGlobalConfig[]; extern int32_t tsGlobalConfigNum; extern char * tsCfgStatusStr[]; -extern bool tsdbForceKeepFile; void taosReadGlobalLogCfg(); bool taosReadGlobalCfg(); From 0e0e727eaf3a9cb8d0b189d717a6e955ed6fabcb Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Wed, 18 Aug 2021 01:08:22 +0000 Subject: [PATCH 30/35] [TD-6088] handle bigint sum --- src/common/src/ttypes.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/common/src/ttypes.c b/src/common/src/ttypes.c index 13c4160e7f..08bfc2e9aa 100644 --- a/src/common/src/ttypes.c +++ b/src/common/src/ttypes.c @@ -38,11 +38,7 @@ const int32_t TYPE_BYTES[15] = { #define DO_STATICS(__sum, __min, __max, __minIndex, __maxIndex, _list, _index) \ do { \ - if (_list[(_index)] >= (INT64_MAX - (__sum))) { \ - __sum = INT64_MAX; \ - } else { \ - (__sum) += (_list)[(_index)]; \ - } \ + (__sum) += (_list)[(_index)]; \ if ((__min) > (_list)[(_index)]) { \ (__min) = (_list)[(_index)]; \ (__minIndex) = (_index); \ From 5c400d72560d0d17f04659241db8bc5a8df9e6da Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 18 Aug 2021 13:55:23 +0800 Subject: [PATCH 31/35] Feature/sangshuduo/td 5136 taosdemo rework (#7432) * [TD-5136]: taosdemo simulate real senario. * update test case according to taosdemo change * adjust range of semi-random data. * make demo mode use different tag name and value. * change malloc to calloc for pid allocation. * fix typo. * fix binary length default value and group id logic. Co-authored-by: Shuduo Sang --- src/kit/taosdemo/taosdemo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 07dbc5e022..7cee96b54b 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -626,7 +626,7 @@ SArguments g_args = { "INT", // datatype "FLOAT", // datatype. DEFAULT_DATATYPE_NUM is 3 }, - 16, // len_of_binary + 64, // len_of_binary 4, // num_of_CPR 10, // num_of_connections/thread 0, // insert_interval @@ -2600,7 +2600,7 @@ static char* generateTagValuesForStb(SSuperTable* stbInfo, int64_t tableSeq) { if ((g_args.demo_mode) && (i == 0)) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%"PRId64",", tableSeq % 10); + "%"PRId64",", (tableSeq % 10) + 1); } else { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, From 796538a8690eee87309fa79e685829ca6027202e Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Wed, 18 Aug 2021 14:34:46 +0800 Subject: [PATCH 32/35] [TD-5532] : resolve unsigned problem of Grafana plugin. --- documentation20/cn/09.connections/docs.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/documentation20/cn/09.connections/docs.md b/documentation20/cn/09.connections/docs.md index 03ab201815..d5a2f27635 100644 --- a/documentation20/cn/09.connections/docs.md +++ b/documentation20/cn/09.connections/docs.md @@ -19,6 +19,13 @@ TDengine 的 Grafana 插件在安装包的 /usr/local/taos/connector/grafanaplug sudo cp -rf /usr/local/taos/connector/grafanaplugin /var/lib/grafana/plugins/tdengine ``` +Grafana 8.x 版本会对插件进行签名检查,因此还需要在 grafana.ini 文件中增加如下行,才能正确使用插件: +``` +[plugins] +enable_alpha = true +allow_loading_unsigned_plugins = taosdata-tdengine-datasource +``` + ### 使用 Grafana #### 配置数据源 From 6dde4a6b36a78f71bbfa2308918be517d4bc31b5 Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Wed, 18 Aug 2021 16:59:25 +0800 Subject: [PATCH 33/35] [TD-2639] : update parameter BLOCKS value in example to be 6. --- documentation20/cn/04.model/docs.md | 2 +- documentation20/cn/11.administrator/docs.md | 2 +- documentation20/en/04.model/docs.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation20/cn/04.model/docs.md b/documentation20/cn/04.model/docs.md index af4f85b5eb..e44de69024 100644 --- a/documentation20/cn/04.model/docs.md +++ b/documentation20/cn/04.model/docs.md @@ -11,7 +11,7 @@ TDengine采用关系型数据模型,需要建库、建表。因此对于一个 不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为了在各种场景下TDengine都能最大效率的工作,TDengine建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。创建一个库时,除SQL标准的选项外,应用还可以指定保留时长、副本数、内存块个数、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如: ```mysql -CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 4 UPDATE 1; +CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 6 UPDATE 1; ``` 上述语句将创建一个名为power的库,这个库的数据将保留365天(超过365天将被自动删除),每10天一个数据文件,内存块数为4,允许更新数据。详细的语法及参数请见 [TAOS SQL 的数据管理](https://www.taosdata.com/cn/documentation/taos-sql#management) 章节。 diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md index a5a916d346..ad4e17b7f0 100644 --- a/documentation20/cn/11.administrator/docs.md +++ b/documentation20/cn/11.administrator/docs.md @@ -230,7 +230,7 @@ taosd -C | 1 | days | 天 | 一个数据文件存储数据的时间跨度 | | 10 | | 2 | keep | 天 | (可通过 alter database 修改)数据库中数据保留的天数。 | 3650 | | 3 | cache | MB | 内存块的大小 | | 16 | -| 4 | blocks | | (可通过 alter database 修改)每个 VNODE(TSDB)中有多少个 cache 大小的内存块。因此一个 VNODE 使用的内存大小粗略为(cache * blocks)。 | | 4 | +| 4 | blocks | | (可通过 alter database 修改)每个 VNODE(TSDB)中有多少个 cache 大小的内存块。因此一个 VNODE 使用的内存大小粗略为(cache * blocks)。 | | 6 | | 5 | quorum | | (可通过 alter database 修改)多副本环境下指令执行的确认数要求 | 1-2 | 1 | | 6 | minRows | | 文件块中记录的最小条数 | | 100 | | 7 | maxRows | | 文件块中记录的最大条数 | | 4096 | diff --git a/documentation20/en/04.model/docs.md b/documentation20/en/04.model/docs.md index 2e69054fa1..1bf6c67878 100644 --- a/documentation20/en/04.model/docs.md +++ b/documentation20/en/04.model/docs.md @@ -9,7 +9,7 @@ Please watch the [video tutorial](https://www.taosdata.com/blog/2020/11/11/1945. Different types of data collection points often have different data characteristics, including frequency of data collecting, length of data retention time, number of replicas, size of data blocks, whether to update data or not, and so on. To ensure TDengine working with great efficiency in various scenarios, TDengine suggests creating tables with different data characteristics in different databases, because each database can be configured with different storage strategies. When creating a database, in addition to SQL standard options, the application can also specify a variety of parameters such as retention duration, number of replicas, number of memory blocks, time accuracy, max and min number of records in a file block, whether it is compressed or not, and number of days a data file will be overwritten. For example: ```mysql -CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 4 UPDATE 1; +CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 6 UPDATE 1; ``` The above statement will create a database named “power”. The data of this database will be kept for 365 days (it will be automatically deleted 365 days later), one data file created per 10 days, and the number of memory blocks is 4 for data updating. For detailed syntax and parameters, please refer to [Data Management section of TAOS SQL](https://www.taosdata.com/en/documentation/taos-sql#management). From e41ae9090835b2db841bebac824333f2cc858534 Mon Sep 17 00:00:00 2001 From: Elias Soong Date: Wed, 18 Aug 2021 19:23:42 +0800 Subject: [PATCH 34/35] [TD-4181] : fix some minor format things. --- documentation20/cn/02.getting-started/docs.md | 6 +-- documentation20/cn/03.architecture/docs.md | 33 ++++++------ documentation20/cn/04.model/docs.md | 2 +- documentation20/cn/05.insert/docs.md | 32 ++++++------ .../cn/07.advanced-features/docs.md | 4 +- .../cn/08.connector/01.java/docs.md | 19 ++----- documentation20/cn/08.connector/docs.md | 52 +++++++++---------- documentation20/cn/10.cluster/docs.md | 4 +- documentation20/cn/11.administrator/docs.md | 12 ++--- documentation20/cn/12.taos-sql/docs.md | 34 ++++-------- documentation20/cn/13.faq/docs.md | 18 +++---- 11 files changed, 91 insertions(+), 125 deletions(-) diff --git a/documentation20/cn/02.getting-started/docs.md b/documentation20/cn/02.getting-started/docs.md index f376d1b30c..dd7c20fe18 100644 --- a/documentation20/cn/02.getting-started/docs.md +++ b/documentation20/cn/02.getting-started/docs.md @@ -105,7 +105,7 @@ $ taos -h h1.taos.com -s "use db; show tables;" **运行 SQL 命令脚本** -TDengine 终端可以通过 `source` 命令来运行 SQL 命令脚本. +TDengine 终端可以通过 `source` 命令来运行 SQL 命令脚本。 ```mysql taos> source ; @@ -166,14 +166,12 @@ taos> select avg(current), max(voltage), min(phase) from test.d10 interval(10s); **Note:** taosdemo 命令本身带有很多选项,配置表的数目、记录条数等等,请执行 `taosdemo --help` 详细列出。您可以设置不同参数进行体验。 - ## 客户端和报警模块 如果客户端和服务端运行在不同的电脑上,可以单独安装客户端。Linux 和 Windows 安装包可以在 [这里](https://www.taosdata.com/cn/getting-started/#客户端) 下载。 报警模块的 Linux 和 Windows 安装包请在 [所有下载链接](https://www.taosdata.com/cn/all-downloads/) 页面搜索“TDengine Alert Linux”章节或“TDengine Alert Windows”章节进行下载。使用方法请参考 [报警模块的使用方法](https://github.com/taosdata/TDengine/blob/master/alert/README_cn.md)。 - ## 支持平台列表 ### TDengine 服务器支持的平台列表 @@ -193,8 +191,6 @@ taos> select avg(current), max(voltage), min(phase) from test.d10 interval(10s); 注: ● 表示经过官方测试验证, ○ 表示非官方测试验证。 - - ### TDengine 客户端和连接器支持的平台列表 目前 TDengine 的连接器可支持的平台广泛,目前包括:X64/X86/ARM64/ARM32/MIPS/Alpha 等硬件平台,以及 Linux/Win64/Win32 等开发环境。 diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md index b53938dbec..8adafc73c2 100644 --- a/documentation20/cn/03.architecture/docs.md +++ b/documentation20/cn/03.architecture/docs.md @@ -161,17 +161,17 @@ TDengine 分布式架构的逻辑结构图如下: 一个完整的 TDengine 系统是运行在一到多个物理节点上的,逻辑上,它包含数据节点(dnode)、TDengine应用驱动(taosc)以及应用(app)。系统中存在一到多个数据节点,这些数据节点组成一个集群(cluster)。应用通过taosc的API与TDengine集群进行互动。下面对每个逻辑单元进行简要介绍。 -**物理节点(pnode):** pnode是一独立运行、拥有自己的计算、存储和网络能力的计算机,可以是安装有OS的物理机、虚拟机或Docker容器。物理节点由其配置的 FQDN(Fully Qualified Domain Name)来标识。TDengine完全依赖FQDN来进行网络通讯,如果不了解FQDN,请看博文[《一篇文章说清楚TDengine的FQDN》](https://www.taosdata.com/blog/2020/09/11/1824.html)。 +**物理节点(pnode):** pnode是一独立运行、拥有自己的计算、存储和网络能力的计算机,可以是安装有OS的物理机、虚拟机或Docker容器。物理节点由其配置的 FQDN(Fully Qualified Domain Name)来标识。TDengine完全依赖FQDN来进行网络通讯,如果不了解FQDN,请看博文[《一篇文章说清楚TDengine的FQDN》](https://www.taosdata.com/blog/2020/09/11/1824.html)。 -**数据节点(dnode):** dnode 是 TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例,一个工作的系统必须有至少一个数据节点。dnode包含零到多个逻辑的虚拟节点(vnode),零或者至多一个逻辑的管理节点(mnode)。dnode在系统中的唯一标识由实例的End Point (EP)决定。EP是dnode所在物理节点的FQDN (Fully Qualified Domain Name)和系统所配置的网络端口号(Port)的组合。通过配置不同的端口,一个物理节点(一台物理机、虚拟机或容器)可以运行多个实例,或有多个数据节点。 +**数据节点(dnode):** dnode 是 TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例,一个工作的系统必须有至少一个数据节点。dnode包含零到多个逻辑的虚拟节点(vnode),零或者至多一个逻辑的管理节点(mnode)。dnode在系统中的唯一标识由实例的End Point (EP)决定。EP是dnode所在物理节点的FQDN (Fully Qualified Domain Name)和系统所配置的网络端口号(Port)的组合。通过配置不同的端口,一个物理节点(一台物理机、虚拟机或容器)可以运行多个实例,或有多个数据节点。 -**虚拟节点(vnode)**: 为更好的支持数据分片、负载均衡,防止数据过热或倾斜,数据节点被虚拟化成多个虚拟节点(vnode,图中V2, V3, V4等)。每个 vnode 都是一个相对独立的工作单元,是时序数据存储的基本单元,具有独立的运行线程、内存空间与持久化存储的路径。一个 vnode 包含一定数量的表(数据采集点)。当创建一张新表时,系统会检查是否需要创建新的 vnode。一个数据节点上能创建的 vnode 的数量取决于该数据节点所在物理节点的硬件资源。一个 vnode 只属于一个DB,但一个DB可以有多个 vnode。一个 vnode 除存储的时序数据外,也保存有所包含的表的schema、标签值等。一个虚拟节点由所属的数据节点的EP,以及所属的VGroup ID在系统内唯一标识,由管理节点创建并管理。 +**虚拟节点(vnode):** 为更好的支持数据分片、负载均衡,防止数据过热或倾斜,数据节点被虚拟化成多个虚拟节点(vnode,图中V2, V3, V4等)。每个 vnode 都是一个相对独立的工作单元,是时序数据存储的基本单元,具有独立的运行线程、内存空间与持久化存储的路径。一个 vnode 包含一定数量的表(数据采集点)。当创建一张新表时,系统会检查是否需要创建新的 vnode。一个数据节点上能创建的 vnode 的数量取决于该数据节点所在物理节点的硬件资源。一个 vnode 只属于一个DB,但一个DB可以有多个 vnode。一个 vnode 除存储的时序数据外,也保存有所包含的表的schema、标签值等。一个虚拟节点由所属的数据节点的EP,以及所属的VGroup ID在系统内唯一标识,由管理节点创建并管理。 -**管理节点(mnode):** 一个虚拟的逻辑单元,负责所有数据节点运行状态的监控和维护,以及节点之间的负载均衡(图中M)。同时,管理节点也负责元数据(包括用户、数据库、表、静态标签等)的存储和管理,因此也称为 Meta Node。TDengine 集群中可配置多个(开源版最多不超过3个) mnode,它们自动构建成为一个虚拟管理节点组(图中M0, M1, M2)。mnode 间采用 master/slave 的机制进行管理,而且采取强一致方式进行数据同步, 任何数据更新操作只能在 Master 上进行。mnode 集群的创建由系统自动完成,无需人工干预。每个dnode上至多有一个mnode,由所属的数据节点的EP来唯一标识。每个dnode通过内部消息交互自动获取整个集群中所有 mnode 所在的 dnode 的EP。 +**管理节点(mnode):** 一个虚拟的逻辑单元,负责所有数据节点运行状态的监控和维护,以及节点之间的负载均衡(图中M)。同时,管理节点也负责元数据(包括用户、数据库、表、静态标签等)的存储和管理,因此也称为 Meta Node。TDengine 集群中可配置多个(开源版最多不超过3个) mnode,它们自动构建成为一个虚拟管理节点组(图中M0, M1, M2)。mnode 间采用 master/slave 的机制进行管理,而且采取强一致方式进行数据同步, 任何数据更新操作只能在 Master 上进行。mnode 集群的创建由系统自动完成,无需人工干预。每个dnode上至多有一个mnode,由所属的数据节点的EP来唯一标识。每个dnode通过内部消息交互自动获取整个集群中所有 mnode 所在的 dnode 的EP。 -**虚拟节点组(VGroup):** 不同数据节点上的 vnode 可以组成一个虚拟节点组(vnode group)来保证系统的高可靠。虚拟节点组内采取master/slave的方式进行管理。写操作只能在 master vnode 上进行,系统采用异步复制的方式将数据同步到 slave vnode,这样确保了一份数据在多个物理节点上有拷贝。一个 vgroup 里虚拟节点个数就是数据的副本数。如果一个DB的副本数为N,系统必须有至少N个数据节点。副本数在创建DB时通过参数 replica 可以指定,缺省为1。使用 TDengine 的多副本特性,可以不再需要昂贵的磁盘阵列等存储设备,就可以获得同样的数据高可靠性。虚拟节点组由管理节点创建、管理,并且由管理节点分配一个系统唯一的ID,VGroup ID。如果两个虚拟节点的vnode group ID相同,说明他们属于同一个组,数据互为备份。虚拟节点组里虚拟节点的个数是可以动态改变的,容许只有一个,也就是没有数据复制。VGroup ID是永远不变的,即使一个虚拟节点组被删除,它的ID也不会被收回重复利用。 +**虚拟节点组(VGroup):** 不同数据节点上的 vnode 可以组成一个虚拟节点组(vnode group)来保证系统的高可靠。虚拟节点组内采取master/slave的方式进行管理。写操作只能在 master vnode 上进行,系统采用异步复制的方式将数据同步到 slave vnode,这样确保了一份数据在多个物理节点上有拷贝。一个 vgroup 里虚拟节点个数就是数据的副本数。如果一个DB的副本数为N,系统必须有至少N个数据节点。副本数在创建DB时通过参数 replica 可以指定,缺省为1。使用 TDengine 的多副本特性,可以不再需要昂贵的磁盘阵列等存储设备,就可以获得同样的数据高可靠性。虚拟节点组由管理节点创建、管理,并且由管理节点分配一个系统唯一的ID,VGroup ID。如果两个虚拟节点的vnode group ID相同,说明他们属于同一个组,数据互为备份。虚拟节点组里虚拟节点的个数是可以动态改变的,容许只有一个,也就是没有数据复制。VGroup ID是永远不变的,即使一个虚拟节点组被删除,它的ID也不会被收回重复利用。 -**TAOSC:** taosc是TDengine给应用提供的驱动程序(driver),负责处理应用与集群的接口交互,提供C/C++语言原生接口,内嵌于JDBC、C#、Python、Go、Node.js语言连接库里。应用都是通过taosc而不是直接连接集群中的数据节点与整个集群进行交互的。这个模块负责获取并缓存元数据;将插入、查询等请求转发到正确的数据节点;在把结果返回给应用时,还需要负责最后一级的聚合、排序、过滤等操作。对于JDBC, C/C++/C#/Python/Go/Node.js接口而言,这个模块是在应用所处的物理节点上运行。同时,为支持全分布式的RESTful接口,taosc在TDengine集群的每个dnode上都有一运行实例。 +**TAOSC:** taosc是TDengine给应用提供的驱动程序(driver),负责处理应用与集群的接口交互,提供C/C++语言原生接口,内嵌于JDBC、C#、Python、Go、Node.js语言连接库里。应用都是通过taosc而不是直接连接集群中的数据节点与整个集群进行交互的。这个模块负责获取并缓存元数据;将插入、查询等请求转发到正确的数据节点;在把结果返回给应用时,还需要负责最后一级的聚合、排序、过滤等操作。对于JDBC、C/C++、C#、Python、Go、Node.js接口而言,这个模块是在应用所处的物理节点上运行。同时,为支持全分布式的RESTful接口,taosc在TDengine集群的每个dnode上都有一运行实例。 ### 节点之间的通讯 @@ -181,11 +181,9 @@ TDengine 分布式架构的逻辑结构图如下: **端口配置:**一个数据节点对外的端口由TDengine的系统配置参数serverPort决定,对集群内部通讯的端口是serverPort+5。为支持多线程高效的处理UDP数据,每个对内和对外的UDP连接,都需要占用5个连续的端口。 -集群内数据节点之间的数据复制操作占用一个TCP端口,是serverPort+10。 - -集群数据节点对外提供RESTful服务占用一个TCP端口,是serverPort+11。 - -集群内数据节点与Arbitrator节点之间通讯占用一个TCP端口,是serverPort+12。 +- 集群内数据节点之间的数据复制操作占用一个TCP端口,是serverPort+10。 +- 集群数据节点对外提供RESTful服务占用一个TCP端口,是serverPort+11。 +- 集群内数据节点与Arbitrator节点之间通讯占用一个TCP端口,是serverPort+12。 因此一个数据节点总的端口范围为serverPort到serverPort+12,总共13个TCP/UDP端口。使用时,需要确保防火墙将这些端口打开。每个数据节点可以配置不同的serverPort。(详细的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port)) @@ -193,11 +191,9 @@ TDengine 分布式架构的逻辑结构图如下: **集群内部通讯:**各个数据节点之间通过TCP/UDP进行连接。一个数据节点启动时,将获取mnode所在的dnode的EP信息,然后与系统中的mnode建立起连接,交换信息。获取mnode的EP信息有三步: -1:检查mnodeEpSet.json文件是否存在,如果不存在或不能正常打开获得mnode EP信息,进入第二步; - -2:检查系统配置文件taos.cfg,获取节点配置参数firstEp、secondEp(这两个参数指定的节点可以是不带mnode的普通节点,这样的话,节点被连接时会尝试重定向到mnode节点),如果不存在或者taos.cfg里没有这两个配置参数,或无效,进入第三步; - -3:将自己的EP设为mnode EP,并独立运行起来。 +1. 检查mnodeEpSet.json文件是否存在,如果不存在或不能正常打开获得mnode EP信息,进入第二步; +2. 检查系统配置文件taos.cfg,获取节点配置参数firstEp、secondEp(这两个参数指定的节点可以是不带mnode的普通节点,这样的话,节点被连接时会尝试重定向到mnode节点),如果不存在或者taos.cfg里没有这两个配置参数,或无效,进入第三步; +3. 将自己的EP设为mnode EP,并独立运行起来。 获取mnode EP列表后,数据节点发起连接,如果连接成功,则成功加入进工作的集群,如果不成功,则尝试mnode EP列表中的下一个。如果都尝试了,但连接都仍然失败,则休眠几秒后,再进行尝试。 @@ -271,6 +267,7 @@ TDengine除vnode分片之外,还对时序数据按照时间段进行分区。 当新的数据节点被添加进集群,因为新的计算和存储被添加进来,系统也将自动启动负载均衡流程。 负载均衡过程无需任何人工干预,应用也无需重启,将自动连接新的节点,完全透明。 + **提示:负载均衡由参数balance控制,决定开启/关闭自动负载均衡。** ## 数据写入与复制流程 @@ -293,13 +290,13 @@ Master Vnode遵循下面的写入流程: ### Slave Vnode写入流程 -对于slave vnode, 写入流程是: +对于slave vnode,写入流程是: ![TDengine Slave写入流程](page://images/architecture/write_slave.png)
图 4 TDengine Slave写入流程
1. slave vnode收到Master vnode转发了的数据插入请求。检查last version是否与master一致,如果一致,进入下一步。如果不一致,需要进入同步状态。 -2. 如果系统配置参数walLevel大于0,vnode将把该请求的原始数据包写入数据库日志文件WAL。如果walLevel设置为2,而且fsync设置为0,TDengine还将WAL数据立即落盘,以保证即使宕机,也能从数据库日志文件中恢复数据,避免数据的丢失; +2. 如果系统配置参数walLevel大于0,vnode将把该请求的原始数据包写入数据库日志文件WAL。如果walLevel设置为2,而且fsync设置为0,TDengine还将WAL数据立即落盘,以保证即使宕机,也能从数据库日志文件中恢复数据,避免数据的丢失。 3. 写入内存,更新内存中的skip list。 与master vnode相比,slave vnode不存在转发环节,也不存在回复确认环节,少了两步。但写内存与WAL是完全一样的。 diff --git a/documentation20/cn/04.model/docs.md b/documentation20/cn/04.model/docs.md index e44de69024..ccdca64c10 100644 --- a/documentation20/cn/04.model/docs.md +++ b/documentation20/cn/04.model/docs.md @@ -65,7 +65,7 @@ TDengine建议将数据采集点的全局唯一ID作为表名(比如设备序列 INSERT INTO d1001 USING meters TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32); ``` -上述SQL语句将记录 (now, 10.2, 219, 0.32) 插入表d1001。如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值“Beijing.Chaoyang", 2。 +上述SQL语句将记录 (now, 10.2, 219, 0.32) 插入表d1001。如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值 `“Beijing.Chaoyang", 2`。 关于自动建表的详细语法请参见 [插入记录时自动建表](https://www.taosdata.com/cn/documentation/taos-sql#auto_create_table) 章节。 diff --git a/documentation20/cn/05.insert/docs.md b/documentation20/cn/05.insert/docs.md index b20b1e111d..f055b0c25b 100644 --- a/documentation20/cn/05.insert/docs.md +++ b/documentation20/cn/05.insert/docs.md @@ -35,7 +35,7 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, 用户需要从github下载[Bailongma](https://github.com/taosdata/Bailongma)的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件: - Linux操作系统的服务器 -- 安装好Golang, 1.10版本以上 +- 安装好Golang,1.10版本以上 - 对应的TDengine版本。因为用到了TDengine的客户端动态链接库,因此需要安装好和服务端相同版本的TDengine程序;比如服务端版本是TDengine 2.0.0, 则在Bailongma所在的Linux服务器(可以与TDengine在同一台服务器,或者不同服务器) Bailongma项目中有一个文件夹blm_prometheus,存放了prometheus的写入API程序。编译过程如下: @@ -48,13 +48,15 @@ go build ### 安装Prometheus -通过Prometheus的官网下载安装。[下载地址](https://prometheus.io/download/) +通过Prometheus的官网下载安装。具体请见:[下载地址](https://prometheus.io/download/)。 ### 配置Prometheus -参考Prometheus的[配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/),在Prometheus的配置文件中的部分,增加以下配置 +参考Prometheus的[配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/),在Prometheus的配置文件中的部分,增加以下配置: -- url: bailongma API服务提供的URL,参考下面的blm_prometheus启动示例章节 +``` + - url: "bailongma API服务提供的URL"(参考下面的blm_prometheus启动示例章节) +``` 启动Prometheus后,可以通过taos客户端查询确认数据是否成功写入。 @@ -62,7 +64,7 @@ go build blm_prometheus程序有以下选项,在启动blm_prometheus程序时可以通过设定这些选项来设定blm_prometheus的配置。 ```bash --tdengine-name -如果TDengine安装在一台具备域名的服务器上,也可以通过配置TDengine的域名来访问TDengine。在K8S环境下,可以配置成TDengine所运行的service name +如果TDengine安装在一台具备域名的服务器上,也可以通过配置TDengine的域名来访问TDengine。在K8S环境下,可以配置成TDengine所运行的service name。 --batch-size blm_prometheus会将收到的prometheus的数据拼装成TDengine的写入请求,这个参数控制一次发给TDengine的写入请求中携带的数据条数。 @@ -71,10 +73,10 @@ blm_prometheus会将收到的prometheus的数据拼装成TDengine的写入请求 设置在TDengine中创建的数据库名称,blm_prometheus会自动在TDengine中创建一个以dbname为名称的数据库,缺省值是prometheus。 --dbuser -设置访问TDengine的用户名,缺省值是'root' +设置访问TDengine的用户名,缺省值是'root'。 --dbpassword -设置访问TDengine的密码,缺省值是'taosdata' +设置访问TDengine的密码,缺省值是'taosdata'。 --port blm_prometheus对prometheus提供服务的端口号。 @@ -125,7 +127,7 @@ select * from apiserver_request_latencies_bucket; 用户需要从github下载[Bailongma](https://github.com/taosdata/Bailongma)的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件: - Linux操作系统的服务器 -- 安装好Golang, 1.10版本以上 +- 安装好Golang,1.10版本以上 - 对应的TDengine版本。因为用到了TDengine的客户端动态链接库,因此需要安装好和服务端相同版本的TDengine程序;比如服务端版本是TDengine 2.0.0, 则在Bailongma所在的Linux服务器(可以与TDengine在同一台服务器,或者不同服务器) Bailongma项目中有一个文件夹blm_telegraf,存放了Telegraf的写入API程序。编译过程如下: @@ -139,7 +141,7 @@ go build ### 安装Telegraf -目前TDengine支持Telegraf 1.7.4以上的版本。用户可以根据当前的操作系统,到Telegraf官网下载安装包,并执行安装。下载地址如下:https://portal.influxdata.com/downloads +目前TDengine支持Telegraf 1.7.4以上的版本。用户可以根据当前的操作系统,到Telegraf官网下载安装包,并执行安装。下载地址如下:https://portal.influxdata.com/downloads 。 ### 配置Telegraf @@ -153,7 +155,7 @@ go build 在agent部分: -- hostname: 区分不同采集设备的机器名称,需确保其唯一性 +- hostname: 区分不同采集设备的机器名称,需确保其唯一性。 - metric_batch_size: 100,允许Telegraf每批次写入记录最大数量,增大其数量可以降低Telegraf的请求发送频率。 关于如何使用Telegraf采集数据以及更多有关使用Telegraf的信息,请参考Telegraf官方的[文档](https://docs.influxdata.com/telegraf/v1.11/)。 @@ -163,7 +165,7 @@ blm_telegraf程序有以下选项,在启动blm_telegraf程序时可以通过 ```bash --host -TDengine服务端的IP地址,缺省值为空 +TDengine服务端的IP地址,缺省值为空。 --batch-size blm_telegraf会将收到的telegraf的数据拼装成TDengine的写入请求,这个参数控制一次发给TDengine的写入请求中携带的数据条数。 @@ -172,10 +174,10 @@ blm_telegraf会将收到的telegraf的数据拼装成TDengine的写入请求, 设置在TDengine中创建的数据库名称,blm_telegraf会自动在TDengine中创建一个以dbname为名称的数据库,缺省值是prometheus。 --dbuser -设置访问TDengine的用户名,缺省值是'root' +设置访问TDengine的用户名,缺省值是'root'。 --dbpassword -设置访问TDengine的密码,缺省值是'taosdata' +设置访问TDengine的密码,缺省值是'taosdata'。 --port blm_telegraf对telegraf提供服务的端口号。 @@ -183,12 +185,12 @@ blm_telegraf对telegraf提供服务的端口号。 ### 启动示例 -通过以下命令启动一个blm_telegraf的API服务 +通过以下命令启动一个blm_telegraf的API服务: ```bash ./blm_telegraf -host 127.0.0.1 -port 8089 ``` -假设blm_telegraf所在服务器的IP地址为"10.1.2.3",则在telegraf的配置文件中, 在output plugins部分,增加[[outputs.http]]配置项: +假设blm_telegraf所在服务器的IP地址为"10.1.2.3",则在telegraf的配置文件中, 在output plugins部分,增加[[outputs.http]]配置项: ```yaml url = "http://10.1.2.3:8089/telegraf" diff --git a/documentation20/cn/07.advanced-features/docs.md b/documentation20/cn/07.advanced-features/docs.md index 3661d68427..32e7a2aabd 100644 --- a/documentation20/cn/07.advanced-features/docs.md +++ b/documentation20/cn/07.advanced-features/docs.md @@ -35,13 +35,13 @@ select avg(voltage) from meters interval(1m) sliding(30s); select avg(voltage) from meters where ts > {startTime} interval(1m) sliding(30s); ``` -这样做没有问题,但TDengine提供了更简单的方法,只要在最初的查询语句前面加上 `create table {tableName} as ` 就可以了, 例如: +这样做没有问题,但TDengine提供了更简单的方法,只要在最初的查询语句前面加上 `create table {tableName} as ` 就可以了,例如: ```sql create table avg_vol as select avg(voltage) from meters interval(1m) sliding(30s); ``` -会自动创建一个名为 `avg_vol` 的新表,然后每隔30秒,TDengine会增量执行 `as` 后面的 SQL 语句,并将查询结果写入这个表中,用户程序后续只要从 `avg_vol` 中查询数据即可。 例如: +会自动创建一个名为 `avg_vol` 的新表,然后每隔30秒,TDengine会增量执行 `as` 后面的 SQL 语句,并将查询结果写入这个表中,用户程序后续只要从 `avg_vol` 中查询数据即可。例如: ```mysql taos> select * from avg_vol; diff --git a/documentation20/cn/08.connector/01.java/docs.md b/documentation20/cn/08.connector/01.java/docs.md index e1a5654871..ab9af42cf8 100644 --- a/documentation20/cn/08.connector/01.java/docs.md +++ b/documentation20/cn/08.connector/01.java/docs.md @@ -52,7 +52,6 @@ JDBCConnectorChecker JDBC安装校验源程序及jar包 Springbootdemo springboot示例源程序 SpringJdbcTemplate SpringJDBC模板 - ### 安装验证 @@ -65,7 +64,6 @@ java -jar JDBCConnectorChecker.jar -host 验证通过将打印出成功信息。 - ## Java连接器的使用 `taos-jdbcdriver` 的实现包括 2 种形式: JDBC-JNI 和 JDBC-RESTful(taos-jdbcdriver-2.0.18 开始支持 JDBC-RESTful)。 JDBC-JNI 通过调用客户端 libtaos.so(或 taos.dll )的本地方法实现, JDBC-RESTful 则在内部封装了 RESTful 接口实现。 @@ -85,7 +83,6 @@ TDengine 的 JDBC 驱动实现尽可能与关系型数据库驱动保持一致 * 目前不支持嵌套查询(nested query)。 * 对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet 还没关闭的情况下执行了新的查询,taos-jdbcdriver 会自动关闭上一个 ResultSet。 - ### JDBC-JNI和JDBC-RESTful的对比
对比项JDBC-JNIJDBC-RESTful
支持的操作系统
@@ -199,8 +196,6 @@ url中的配置参数如下: * locale:客户端语言环境,默认值系统当前 locale。 * timezone:客户端使用的时区,默认值为系统当前时区。 - - #### 指定URL和Properties获取连接 除了通过指定的 URL 获取连接,还可以使用 Properties 指定建立连接时的参数,如下所示: @@ -229,8 +224,6 @@ properties 中的配置参数如下: * TSDBDriver.PROPERTY_KEY_LOCALE:客户端语言环境,默认值系统当前 locale。 * TSDBDriver.PROPERTY_KEY_TIME_ZONE:客户端使用的时区,默认值为系统当前时区。 - - #### 使用客户端配置文件建立连接 当使用 JDBC-JNI 连接 TDengine 集群时,可以使用客户端配置文件,在客户端配置文件中指定集群的 firstEp、secondEp参数。如下所示: @@ -484,8 +477,6 @@ conn.close(); > `注意务必要将 connection 进行关闭`,否则会出现连接泄露。 - - ## 与连接池使用 **HikariCP** @@ -530,7 +521,7 @@ conn.close(); ``` > 通过 HikariDataSource.getConnection() 获取连接后,使用完成后需要调用 close() 方法,实际上它并不会关闭连接,只是放回连接池中。 -> 更多 HikariCP 使用问题请查看[官方说明](https://github.com/brettwooldridge/HikariCP) +> 更多 HikariCP 使用问题请查看[官方说明](https://github.com/brettwooldridge/HikariCP)。 **Druid** @@ -571,9 +562,9 @@ public static void main(String[] args) throws Exception { } ``` -> 更多 druid 使用问题请查看[官方说明](https://github.com/alibaba/druid) +> 更多 druid 使用问题请查看[官方说明](https://github.com/alibaba/druid)。 -**注意事项** +**注意事项:** * TDengine `v1.6.4.1` 版本开始提供了一个专门用于心跳检测的函数 `select server_status()`,所以在使用连接池时推荐使用 `select server_status()` 进行 Validation Query。 如下所示,`select server_status()` 执行成功会返回 `1`。 @@ -585,15 +576,11 @@ server_status()| Query OK, 1 row(s) in set (0.000141s) ``` - - ## 在框架中使用 * Spring JdbcTemplate 中使用 taos-jdbcdriver,可参考 [SpringJdbcTemplate](https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/SpringJdbcTemplate) * Springboot + Mybatis 中使用,可参考 [springbootdemo](https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/springbootdemo) - - ## 常见问题 * java.lang.UnsatisfiedLinkError: no taos in java.library.path diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 0397c61f75..364961ca63 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -58,7 +58,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 ​ *connector*: 各种编程语言连接器(go/grafanaplugin/nodejs/python/JDBC) ​ *examples*: 各种编程语言的示例程序(c/C#/go/JDBC/MATLAB/python/R) -运行install_client.sh进行安装 +运行install_client.sh进行安装。 **4. 配置taos.cfg** @@ -95,9 +95,8 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 **提示:** -**1. 如利用FQDN连接服务器,必须确认本机网络环境DNS已配置好,或在hosts文件中添加FQDN寻址记录,如编辑C:\Windows\system32\drivers\etc\hosts,添加如下的记录:** **192.168.1.99 h1.taos.com** - -**2.卸载:运行unins000.exe可卸载TDengine应用驱动。** +1. **如利用FQDN连接服务器,必须确认本机网络环境DNS已配置好,或在hosts文件中添加FQDN寻址记录,如编辑C:\Windows\system32\drivers\etc\hosts,添加如下的记录:`192.168.1.99 h1.taos.com` ** +2.**卸载:运行unins000.exe可卸载TDengine应用驱动。** ### 安装验证 @@ -408,11 +407,11 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 - `TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sql, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), int64_t stime, void *param, void (*callback)(void *))` 该API用来创建数据流,其中: - * taos:已经建立好的数据库连接 - * sql:SQL查询语句(仅能使用查询语句) + * taos:已经建立好的数据库连接。 + * sql:SQL查询语句(仅能使用查询语句)。 * fp:用户定义的回调函数指针,每次流式计算完成后,TDengine将查询的结果(TAOS_ROW)、查询状态(TAOS_RES)、用户定义参数(PARAM)传递给回调函数,在回调函数内,用户可以使用taos_num_fields获取结果集列数,taos_fetch_fields获取结果集每列数据的类型。 * stime:是流式计算开始的时间。如果是“64位整数最小值”,表示从现在开始;如果不为“64位整数最小值”,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)。 - * param:是应用提供的用于回调的一个参数,回调时,提供给应用 + * param:是应用提供的用于回调的一个参数,回调时,提供给应用。 * callback: 第二个回调函数,会在连续查询自动停止时被调用。 返回值为NULL,表示创建失败;返回值不为空,表示成功。 @@ -458,7 +457,6 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 - ## Python Connector Python连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020/11/11/1963.html) @@ -513,13 +511,12 @@ python -m pip install . - 通过TDengineConnection对象的 .cursor()方法获取一个新的游标对象,这个游标对象必须保证每个线程独享。 -- 通过游标对象的execute()方法,执行写入或查询的SQL语句 +- 通过游标对象的execute()方法,执行写入或查询的SQL语句。 -- 如果执行的是写入语句,execute返回的是成功写入的行数信息affected rows +- 如果执行的是写入语句,execute返回的是成功写入的行数信息affected rows。 - 如果执行的是查询语句,则execute执行成功后,需要通过fetchall方法去拉取结果集。 具体方法可以参考示例代码。 - ### 安装验证 运行如下指令: @@ -531,7 +528,6 @@ python3 PythonChecker.py -host 验证通过将打印出成功信息。 - ### Python连接器的使用 #### 代码示例 @@ -649,8 +645,8 @@ conn.close() - 通过taos.connect获取TDengineConnection对象,这个对象可以一个程序只申请一个,在多线程中共享。 - 通过TDengineConnection对象的 .cursor()方法获取一个新的游标对象,这个游标对象必须保证每个线程独享。 -- 通过游标对象的execute()方法,执行写入或查询的SQL语句 -- 如果执行的是写入语句,execute返回的是成功写入的行数信息affected rows +- 通过游标对象的execute()方法,执行写入或查询的SQL语句。 +- 如果执行的是写入语句,execute返回的是成功写入的行数信息affected rows。 - 如果执行的是查询语句,则execute执行成功后,需要通过fetchall方法去拉取结果集。 具体方法可以参考示例代码。 @@ -888,7 +884,7 @@ HTTP请求URL采用`sqlutc`时,返回结果集的时间戳将采用UTC时间 ### 重要配置项 -下面仅列出一些与RESTful接口有关的配置参数,其他系统参数请看配置文件里的说明。注意:配置修改后,需要重启taosd服务才能生效 +下面仅列出一些与RESTful接口有关的配置参数,其他系统参数请看配置文件里的说明。(注意:配置修改后,需要重启taosd服务才能生效) - 对外提供RESTful服务的端口号,默认绑定到 6041(实际取值是 serverPort + 11,因此可以通过修改 serverPort 参数的设置来修改) - httpMaxThreads: 启动的线程数量,默认为2(2.0.17.0版本开始,默认值改为CPU核数的一半向下取整) @@ -927,7 +923,7 @@ C#Checker.exe -h 在Windows系统上,C#应用程序可以使用TDengine的C#连接器接口来执行所有数据库的操作。使用的具体步骤如下所示: 1. 将接口文件TDengineDrivercs.cs加入到应用程序所在的项目空间中。 -2. 用户可以参考TDengineTest.cs来定义数据库连接参数,以及如何执行数据插入、查询等操作; +2. 用户可以参考TDengineTest.cs来定义数据库连接参数,以及如何执行数据插入、查询等操作。 此接口需要用到taos.dll文件,所以在执行应用程序前,拷贝Windows客户端install_directory/driver目录中的taos.dll文件到项目最后生成.exe可执行文件所在的文件夹。之后运行exe文件,即可访问TDengine数据库并做插入、查询等操作。 @@ -960,13 +956,13 @@ Go连接器支持的系统有: 安装前准备: -- 已安装好TDengine应用驱动,参考[安装连接器驱动步骤](https://www.taosdata.com/cn/documentation/connector#driver) +- 已安装好TDengine应用驱动,参考[安装连接器驱动步骤](https://www.taosdata.com/cn/documentation/connector#driver)。 ### 示例程序 使用 Go 连接器的示例代码请参考 https://github.com/taosdata/TDengine/tree/develop/tests/examples/go 以及[视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。 -示例程序源码也位于安装目录下的 examples/go/taosdemo.go 文件中 +示例程序源码也位于安装目录下的 examples/go/taosdemo.go 文件中。 **提示:建议Go版本是1.13及以上,并开启模块支持:** ```sh @@ -1035,7 +1031,7 @@ Node.js连接器支持的系统有: | **OS类型** | Linux | Win64 | Win32 | Linux | Linux | | **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** | -Node.js连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020/11/11/1957.html) +Node.js连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020/11/11/1957.html)。 ### 安装准备 @@ -1045,14 +1041,14 @@ Node.js连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020 用户可以通过[npm](https://www.npmjs.com/)来进行安装,也可以通过源代码*src/connector/nodejs/* 来进行安装。具体安装步骤如下: -首先,通过[npm](https://www.npmjs.com/)安装node.js 连接器. +首先,通过[npm](https://www.npmjs.com/)安装node.js 连接器。 ```bash npm install td2.0-connector ``` -我们建议用户使用npm 安装node.js连接器。如果您没有安装npm, 可以将*src/connector/nodejs/*拷贝到您的nodejs 项目目录下 +我们建议用户使用npm 安装node.js连接器。如果您没有安装npm,可以将*src/connector/nodejs/*拷贝到您的nodejs 项目目录下。 -我们使用[node-gyp](https://github.com/nodejs/node-gyp)和TDengine服务端进行交互。安装node.js 连接器之前,还需安装以下软件: +我们使用[node-gyp](https://github.com/nodejs/node-gyp)和TDengine服务端进行交互。安装node.js连接器之前,还需要根据具体操作系统来安装下文提到的一些依赖工具。 ### Linux @@ -1065,17 +1061,17 @@ npm install td2.0-connector #### 安装方法1 -使用微软的[windows-build-tools](https://github.com/felixrieseberg/windows-build-tools)在`cmd` 命令行界面执行`npm install --global --production windows-build-tools` 即可安装所有的必备工具 +使用微软的[windows-build-tools](https://github.com/felixrieseberg/windows-build-tools)在`cmd` 命令行界面执行`npm install --global --production windows-build-tools` 即可安装所有的必备工具。 #### 安装方法2 -手动安装以下工具: +手动安装以下工具: - 安装Visual Studio相关:[Visual Studio Build 工具](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) 或者 [Visual Studio 2017 Community](https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community) - 安装 [Python](https://www.python.org/downloads/) 2.7(`v3.x.x` 暂不支持) 并执行 `npm config set python python2.7` - 进入`cmd`命令行界面,`npm config set msvs_version 2017` -如果以上步骤不能成功执行,可以参考微软的node.js用户手册[Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) +如果以上步骤不能成功执行,可以参考微软的node.js用户手册[Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules)。 如果在Windows 10 ARM 上使用ARM64 Node.js,还需添加 "Visual C++ compilers and libraries for ARM64" 和 "Visual C++ ATL for ARM64"。 @@ -1148,7 +1144,7 @@ TDengine目前还不支持update和delete语句。 var query = cursor.query('show databases;') ``` -查询的结果可以通过 `query.execute()` 函数获取并打印出来 +查询的结果可以通过 `query.execute()` 函数获取并打印出来。 ```javascript var promise = query.execute(); @@ -1196,6 +1192,6 @@ promise2.then(function(result) { ### 示例 -[node-example.js](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js)提供了一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例 +[node-example.js](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js)提供了一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例。 -[node-example-raw.js](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js)同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`cursor`. +[node-example-raw.js](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js)同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`cursor`。 diff --git a/documentation20/cn/10.cluster/docs.md b/documentation20/cn/10.cluster/docs.md index ecc9352ba6..f995597db0 100644 --- a/documentation20/cn/10.cluster/docs.md +++ b/documentation20/cn/10.cluster/docs.md @@ -12,7 +12,7 @@ TDengine的集群管理极其简单,除添加和删除节点需要人工干预 **第零步**:规划集群所有物理节点的FQDN,将规划好的FQDN分别添加到每个物理节点的/etc/hostname;修改每个物理节点的/etc/hosts,将所有集群物理节点的IP与FQDN的对应添加好。【如部署了DNS,请联系网络管理员在DNS上做好相关配置】 -**第一步**:如果搭建集群的物理节点中,存有之前的测试数据、装过1.X的版本,或者装过其他版本的TDengine,请先将其删除,并清空所有数据(如果需要保留原有数据,请联系涛思交付团队进行旧版本升级、数据迁移),具体步骤请参考博客[《TDengine多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html ) +**第一步**:如果搭建集群的物理节点中,存有之前的测试数据、装过1.X的版本,或者装过其他版本的TDengine,请先将其删除,并清空所有数据(如果需要保留原有数据,请联系涛思交付团队进行旧版本升级、数据迁移),具体步骤请参考博客[《TDengine多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html)。 **注意1:**因为FQDN的信息会写进文件,如果之前没有配置或者更改FQDN,且启动了TDengine。请一定在确保数据无用或者备份的前提下,清理一下之前的数据(`rm -rf /var/lib/taos/*`); **注意2:**客户端也需要配置,确保它可以正确解析每个节点的FQDN配置,不管是通过DNS服务,还是 Host 文件。 @@ -25,7 +25,7 @@ TDengine的集群管理极其简单,除添加和删除节点需要人工干预 1. 每个物理节点上执行命令`hostname -f`,查看和确认所有节点的hostname是不相同的(应用驱动所在节点无需做此项检查); 2. 每个物理节点上执行`ping host`,其中host是其他物理节点的hostname,看能否ping通其它物理节点;如果不能ping通,需要检查网络设置,或/etc/hosts文件(Windows系统默认路径为C:\Windows\system32\drivers\etc\hosts),或DNS的配置。如果无法ping通,是无法组成集群的; 3. 从应用运行的物理节点,ping taosd运行的数据节点,如果无法ping通,应用是无法连接taosd的,请检查应用所在物理节点的DNS设置或hosts文件; -4. 每个数据节点的End Point就是输出的hostname外加端口号,比如h1.taosdata.com:6030 +4. 每个数据节点的End Point就是输出的hostname外加端口号,比如`h1.taosdata.com:6030`。 **第五步**:修改TDengine的配置文件(所有节点的文件/etc/taos/taos.cfg都需要修改)。假设准备启动的第一个数据节点End Point为 h1.taosdata.com:6030,其与集群配置相关参数如下: diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md index ad4e17b7f0..c4bdecf294 100644 --- a/documentation20/cn/11.administrator/docs.md +++ b/documentation20/cn/11.administrator/docs.md @@ -73,7 +73,7 @@ Raw DataSize = numOfTables * rowSizePerTable * rowsPerTable 因为 TDengine 具有很好的水平扩展能力,根据总量,再根据单个物理机或虚拟机的资源,就可以轻松决定需要购置多少台物理机或虚拟机了。 -**立即计算 CPU、内存、存储,请参见:[资源估算方法](https://www.taosdata.com/config/config.html)** +**立即计算 CPU、内存、存储,请参见:[资源估算方法](https://www.taosdata.com/config/config.html)。** ## 容错和灾备 @@ -433,7 +433,7 @@ SHOW USERS; 显示所有用户 -**注意:**SQL 语法中,< >表示需要用户输入的部分,但请不要输入< >本身 +**注意:**SQL 语法中,< >表示需要用户输入的部分,但请不要输入< >本身。 ## 数据导入 @@ -445,7 +445,7 @@ TDengine的shell支持source filename命令,用于批量运行文件中的SQL **按数据文件导入** -TDengine也支持在shell对已存在的表从CSV文件中进行数据导入。CSV文件只属于一张表且CSV文件中的数据格式需与要导入表的结构相同, 在导入的时候,其语法如下 +TDengine也支持在shell对已存在的表从CSV文件中进行数据导入。CSV文件只属于一张表且CSV文件中的数据格式需与要导入表的结构相同,在导入的时候,其语法如下: ```mysql insert into tb1 file 'path/data.csv'; @@ -487,7 +487,7 @@ Query OK, 9 row(s) affected (0.004763s) **taosdump工具导入** -TDengine提供了方便的数据库导入导出工具taosdump。用户可以将taosdump从一个系统导出的数据,导入到其他系统中。具体使用方法,请参见博客:[TDengine DUMP工具使用指南](https://www.taosdata.com/blog/2020/03/09/1334.html) +TDengine提供了方便的数据库导入导出工具taosdump。用户可以将taosdump从一个系统导出的数据,导入到其他系统中。具体使用方法,请参见博客:[TDengine DUMP工具使用指南](https://www.taosdata.com/blog/2020/03/09/1334.html)。 ## 数据导出 @@ -627,7 +627,7 @@ Active: inactive (dead) ...... ``` -卸载 TDengine,只需要执行如下命令 +卸载 TDengine,只需要执行如下命令: ``` rmtaos ``` @@ -724,7 +724,7 @@ rmtaos 2. 服务端命令行输入:`taos -n server -P ` 以服务端身份启动对端口 port 为基准端口的监听 3. 客户端命令行输入:`taos -n client -h -P ` 以客户端身份启动对指定的服务器、指定的端口发送测试包 -服务端运行正常的话会输出以下信息 +服务端运行正常的话会输出以下信息: ```bash # taos -n server -P 6000 diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index 07ed1a5eae..372070d081 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -9,7 +9,7 @@ TAOS SQL 不支持关键字的缩写,例如 DESCRIBE 不能缩写为 DESC。 本章节 SQL 语法遵循如下约定: - < > 里的内容是用户需要输入的,但不要输入 <> 本身 -- [ ] 表示内容为可选项,但不能输入 [] 本身 +- \[ \] 表示内容为可选项,但不能输入 [] 本身 - | 表示多选一,选择其中一个即可,但不能输入 | 本身 - … 表示前面的项可重复多个 @@ -265,7 +265,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传 ```mysql CREATE STABLE [IF NOT EXISTS] stb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]) TAGS (tag1_name tag_type1, tag2_name tag_type2 [, tag3_name tag_type3]); ``` - 创建 STable,与创建表的 SQL 语法相似,但需要指定 TAGS 字段的名称和类型 + 创建 STable,与创建表的 SQL 语法相似,但需要指定 TAGS 字段的名称和类型。 说明: @@ -728,18 +728,6 @@ Query OK, 1 row(s) in set (0.001091s) 4. 从 2.0.17.0 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。 5. 从 2.1.4.0 版本开始,条件过滤开始支持 IN 算子,例如 `WHERE city IN ('Beijing', 'Shanghai')`。说明:BOOL 类型写作 `{true, false}` 或 `{0, 1}` 均可,但不能写作 0、1 之外的整数;FLOAT 和 DOUBLE 类型会受到浮点数精度影响,集合内的值在精度范围内认为和数据行的值完全相等才能匹配成功;TIMESTAMP 类型支持非主键的列。 - - ### UNION ALL 操作符 @@ -1025,9 +1013,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(\*); - 2) 如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL; + 2)如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL; - 3) 如果结果集中所有列全部为NULL值,则不返回结果。 + 3)如果结果集中所有列全部为NULL值,则不返回结果。 示例: ```mysql @@ -1187,7 +1175,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 适用于:**表、超级表**。 - 说明:*P*值取值范围0≤*P*≤100,为0的时候等同于MIN,为100的时候等同于MAX。推荐使用```APERCENTILE```函数,该函数性能远胜于```PERCENTILE```函数 + 说明:*P*值取值范围0≤*P*≤100,为0的时候等同于MIN,为100的时候等同于MAX。推荐使用```APERCENTILE```函数,该函数性能远胜于```PERCENTILE```函数。 ```mysql taos> SELECT APERCENTILE(current, 20) FROM d1001; @@ -1416,13 +1404,13 @@ SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), P ## TAOS SQL 边界限制 -- 数据库名最大长度为 32 -- 表名最大长度为 192,每行数据最大长度 16k 个字符(注意:数据行内每个 BINARY/NCHAR 类型的列还会额外占用 2 个字节的存储位置) -- 列名最大长度为 64,最多允许 1024 列,最少需要 2 列,第一列必须是时间戳 -- 标签名最大长度为 64,最多允许 128 个,可以 1 个,一个表中标签值的总长度不超过 16k 个字符 -- SQL 语句最大长度 65480 个字符,但可通过系统配置参数 maxSQLLength 修改,最长可配置为 1M +- 数据库名最大长度为 32。 +- 表名最大长度为 192,每行数据最大长度 16k 个字符(注意:数据行内每个 BINARY/NCHAR 类型的列还会额外占用 2 个字节的存储位置)。 +- 列名最大长度为 64,最多允许 1024 列,最少需要 2 列,第一列必须是时间戳。 +- 标签名最大长度为 64,最多允许 128 个,可以 1 个,一个表中标签值的总长度不超过 16k 个字符。 +- SQL 语句最大长度 65480 个字符,但可通过系统配置参数 maxSQLLength 修改,最长可配置为 1M。 - SELECT 语句的查询结果,最多允许返回 1024 列(语句中的函数调用可能也会占用一些列空间),超限时需要显式指定较少的返回数据列,以避免语句执行报错。 -- 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制 +- 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制。 ## TAOS SQL其他约定 diff --git a/documentation20/cn/13.faq/docs.md b/documentation20/cn/13.faq/docs.md index 300ff27fe4..d89b2adeb8 100644 --- a/documentation20/cn/13.faq/docs.md +++ b/documentation20/cn/13.faq/docs.md @@ -26,15 +26,15 @@ ## 2. Windows平台下JDBCDriver找不到动态链接库,怎么办? -请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/950.html) +请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/950.html)。 ## 3. 创建数据表时提示more dnodes are needed -请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/965.html) +请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/965.html)。 ## 4. 如何让TDengine crash时生成core文件? -请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/06/974.html) +请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/06/974.html)。 ## 5. 遇到错误“Unable to establish connection”, 我怎么办? @@ -49,7 +49,7 @@ 3. 在服务器,执行 `systemctl status taosd` 检查*taosd*运行状态。如果没有运行,启动*taosd* -4. 确认客户端连接时指定了正确的服务器FQDN (Fully Qualified Domain Name(可在服务器上执行Linux命令hostname -f获得)),FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。 +4. 确认客户端连接时指定了正确的服务器FQDN (Fully Qualified Domain Name —— 可在服务器上执行Linux命令hostname -f获得),FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。 5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件。如果部署的是TDengine集群,客户端需要能ping通所有集群节点的FQDN。 @@ -74,16 +74,16 @@ 产生这个错误,是由于客户端或数据节点无法解析FQDN(Fully Qualified Domain Name)导致。对于TAOS Shell或客户端应用,请做如下检查: -1. 请检查连接的服务器的FQDN是否正确,FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。 -2. 如果网络配置有DNS server, 请检查是否正常工作 -3. 如果网络没有配置DNS server, 请检查客户端所在机器的hosts文件,查看该FQDN是否配置,并是否有正确的IP地址。 +1. 请检查连接的服务器的FQDN是否正确,FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html) +2. 如果网络配置有DNS server,请检查是否正常工作 +3. 如果网络没有配置DNS server,请检查客户端所在机器的hosts文件,查看该FQDN是否配置,并是否有正确的IP地址 4. 如果网络配置OK,从客户端所在机器,你需要能Ping该连接的FQDN,否则客户端是无法连接服务器的 ## 7. 虽然语法正确,为什么我还是得到 "Invalid SQL" 错误 如果你确认语法正确,2.0之前版本,请检查SQL语句长度是否超过64K。如果超过,也会返回这个错误。 -## 8. 是否支持validation queries? +## 8. 是否支持validation queries? TDengine还没有一组专用的validation queries。然而建议你使用系统监测的数据库”log"来做。 @@ -137,7 +137,7 @@ Connection = DriverManager.getConnection(url, properties); TDengine是根据hostname唯一标志一台机器的,在数据文件从机器A移动机器B时,注意如下两件事: -- 2.0.0.0 至 2.0.6.x 的版本,重新配置机器B的hostname为机器A的hostname +- 2.0.0.0 至 2.0.6.x 的版本,重新配置机器B的hostname为机器A的hostname。 - 2.0.7.0 及以后的版本,到/var/lib/taos/dnode下,修复dnodeEps.json的dnodeId对应的FQDN,重启。确保机器内所有机器的此文件是完全相同的。 - 1.x 和 2.x 版本的存储结构不兼容,需要使用迁移工具或者自己开发应用导出导入数据。 From 47625967d22a1f2f44dbeff87194360e5ba7b41e Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 19 Aug 2021 10:02:07 +0800 Subject: [PATCH 35/35] Feature/sangshuduo/td 5844 cmdline parameters align (#7442) * [TD-5844]: make cmd line parameter similar. * fix test case align with taosdemo change. * fix windows stack overflow issue. * fix mac compile error. * fix taosdemo cmdline parameter in tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestSupportNanoInsert.py * fix windows compiler options. * make taos.exe use mysql style password input. * make taos shell and taosdump use mysql style password input. * determine scanf return value. * make console echo off during password input. --- src/kit/taosdemo/taosdemo.c | 4 +++- src/kit/taosdump/taosdump.c | 2 ++ src/os/inc/osSystem.h | 2 ++ src/os/src/darwin/darwinSystem.c | 26 ++++++++++++++++++++++++++ src/os/src/linux/osSystem.c | 24 ++++++++++++++++++++++++ src/os/src/windows/wSystem.c | 14 ++++++++++++++ 6 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 7cee96b54b..a1c68b2f3c 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -866,10 +866,12 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { arguments->user = argv[++i]; } else if (strncmp(argv[i], "-p", 2) == 0) { if (strlen(argv[i]) == 2) { - printf("Enter password:"); + printf("Enter password: "); + taosSetConsoleEcho(false); if (scanf("%s", arguments->password) > 1) { fprintf(stderr, "password read error!\n"); } + taosSetConsoleEcho(true); } else { tstrncpy(arguments->password, (char *)(argv[i] + 2), MAX_PASSWORD_SIZE); } diff --git a/src/kit/taosdump/taosdump.c b/src/kit/taosdump/taosdump.c index b7073c28a7..c54b8da1b7 100644 --- a/src/kit/taosdump/taosdump.c +++ b/src/kit/taosdump/taosdump.c @@ -561,9 +561,11 @@ static void parse_password( if (strncmp(argv[i], "-p", 2) == 0) { if (strlen(argv[i]) == 2) { printf("Enter password: "); + taosSetConsoleEcho(false); if(scanf("%20s", arguments->password) > 1) { errorPrint("%s() LN%d, password read error!\n", __func__, __LINE__); } + taosSetConsoleEcho(true); } else { tstrncpy(arguments->password, (char *)(argv[i] + 2), MAX_PASSWORD_SIZE); } diff --git a/src/os/inc/osSystem.h b/src/os/inc/osSystem.h index e7a3ec13ae..4b79250740 100644 --- a/src/os/inc/osSystem.h +++ b/src/os/inc/osSystem.h @@ -24,6 +24,8 @@ void* taosLoadDll(const char *filename); void* taosLoadSym(void* handle, char* name); void taosCloseDll(void *handle); +int taosSetConsoleEcho(bool on); + #ifdef __cplusplus } #endif diff --git a/src/os/src/darwin/darwinSystem.c b/src/os/src/darwin/darwinSystem.c index 17cafdd664..6f296c9fef 100644 --- a/src/os/src/darwin/darwinSystem.c +++ b/src/os/src/darwin/darwinSystem.c @@ -29,4 +29,30 @@ void* taosLoadSym(void* handle, char* name) { void taosCloseDll(void *handle) { } +int taosSetConsoleEcho(bool on) +{ +#if 0 +#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL) + int err; + struct termios term; + + if (tcgetattr(STDIN_FILENO, &term) == -1) { + perror("Cannot get the attribution of the terminal"); + return -1; + } + + if (on) + term.c_lflag|=ECHOFLAGS; + else + term.c_lflag &=~ECHOFLAGS; + + err = tcsetattr(STDIN_FILENO,TCSAFLUSH,&term); + if (err == -1 && err == EINTR) { + perror("Cannot set the attribution of the terminal"); + return -1; + } + +#endif + return 0; +} diff --git a/src/os/src/linux/osSystem.c b/src/os/src/linux/osSystem.c index 052b7a22a8..0cdb20dbdb 100644 --- a/src/os/src/linux/osSystem.c +++ b/src/os/src/linux/osSystem.c @@ -51,4 +51,28 @@ void taosCloseDll(void *handle) { } } +int taosSetConsoleEcho(bool on) +{ +#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL) + int err; + struct termios term; + + if (tcgetattr(STDIN_FILENO, &term) == -1) { + perror("Cannot get the attribution of the terminal"); + return -1; + } + + if (on) + term.c_lflag|=ECHOFLAGS; + else + term.c_lflag &=~ECHOFLAGS; + + err = tcsetattr(STDIN_FILENO,TCSAFLUSH,&term); + if (err == -1 && err == EINTR) { + perror("Cannot set the attribution of the terminal"); + return -1; + } + + return 0; +} diff --git a/src/os/src/windows/wSystem.c b/src/os/src/windows/wSystem.c index 17cafdd664..564005f79b 100644 --- a/src/os/src/windows/wSystem.c +++ b/src/os/src/windows/wSystem.c @@ -30,3 +30,17 @@ void taosCloseDll(void *handle) { } +int taosSetConsoleEcho(bool on) +{ + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + GetConsoleMode(hStdin, &mode ); + if (on) { + mode |= ENABLE_ECHO_INPUT; + } else { + mode &= ~ENABLE_ECHO_INPUT; + } + SetConsoleMode(hStdin, mode); + + return 0; +}