From 03c867cdbfba2db4d9da1cebacec7aa283e5f859 Mon Sep 17 00:00:00 2001 From: Xiong Ju Date: Wed, 14 Sep 2022 13:25:52 +0900 Subject: [PATCH 01/12] Update trefTest.c fix typo: reson -> reason --- source/util/test/trefTest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/util/test/trefTest.c b/source/util/test/trefTest.c index 89561e61fe..5a6790ef1d 100644 --- a/source/util/test/trefTest.c +++ b/source/util/test/trefTest.c @@ -94,7 +94,7 @@ void *openRefSpace(void *param) { pSpace->rsetId = taosOpenRef(50, myfree); if (pSpace->rsetId < 0) { - printf("failed to open ref, reson:%s\n", tstrerror(pSpace->rsetId)); + printf("failed to open ref, reason:%s\n", tstrerror(pSpace->rsetId)); return NULL; } From ab3f6619b979e01144c8692d984f3c90baabe2e9 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Wed, 14 Sep 2022 23:29:38 +0800 Subject: [PATCH 02/12] enh(tsc): handle deadlock --- source/client/src/clientHb.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index 84a827ed78..fc03a66655 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -173,7 +173,8 @@ static int32_t hbQueryHbRspHandle(SAppHbMgr *pAppHbMgr, SClientHbRsp *pRsp) { pTscObj->pAppInfo->totalDnodes = pRsp->query->totalDnodes; pTscObj->pAppInfo->onlineDnodes = pRsp->query->onlineDnodes; pTscObj->connId = pRsp->query->connId; - tscTrace("conn %p hb rsp, dnodes %d/%d", pTscObj->connId, pTscObj->pAppInfo->onlineDnodes, pTscObj->pAppInfo->totalDnodes); + tscTrace("conn %p hb rsp, dnodes %d/%d", pTscObj->connId, pTscObj->pAppInfo->onlineDnodes, + pTscObj->pAppInfo->totalDnodes); if (pRsp->query->killRid) { tscDebug("request rid %" PRIx64 " need to be killed now", pRsp->query->killRid); @@ -297,7 +298,8 @@ static int32_t hbAsyncCallBack(void *param, SDataBuf *pMsg, int32_t code) { if (code != 0) { (*pInst)->onlineDnodes = ((*pInst)->totalDnodes ? 0 : -1); - tscDebug("hb rsp error %s, update server status %d/%d", tstrerror(code), (*pInst)->onlineDnodes, (*pInst)->totalDnodes); + tscDebug("hb rsp error %s, update server status %d/%d", tstrerror(code), (*pInst)->onlineDnodes, + (*pInst)->totalDnodes); } if (rspNum) { @@ -654,6 +656,8 @@ int32_t hbGatherAppInfo(void) { for (int32_t i = 0; i < sz; ++i) { SAppHbMgr *pAppHbMgr = taosArrayGetP(clientHbMgr.appHbMgrs, i); + if (pAppHbMgr == NULL) continue; + uint64_t clusterId = pAppHbMgr->pAppInstInfo->clusterId; SAppHbReq *pApp = taosHashGet(clientHbMgr.appSummary, &clusterId, sizeof(clusterId)); if (NULL == pApp) { @@ -691,15 +695,20 @@ static void *hbThreadFunc(void *param) { hbGatherAppInfo(); } + SArray *mgr = taosArrayInit(sz, sizeof(void *)); for (int i = 0; i < sz; i++) { SAppHbMgr *pAppHbMgr = taosArrayGetP(clientHbMgr.appHbMgrs, i); + if (pAppHbMgr == NULL) { + continue; + } int32_t connCnt = atomic_load_32(&pAppHbMgr->connKeyCnt); if (connCnt == 0) { continue; } SClientHbBatchReq *pReq = hbGatherAllInfo(pAppHbMgr); - if (pReq == NULL) { + if (pReq == NULL || taosArrayGetP(clientHbMgr.appHbMgrs, i) == NULL) { + tFreeClientHbBatchReq(pReq); continue; } int tlen = tSerializeSClientHbBatchReq(NULL, 0, pReq); @@ -726,7 +735,7 @@ static void *hbThreadFunc(void *param) { pInfo->msgInfo.len = tlen; pInfo->msgType = TDMT_MND_HEARTBEAT; pInfo->param = strdup(pAppHbMgr->key); - pInfo->paramFreeFp = taosMemoryFree; + pInfo->paramFreeFp = taosMemoryFree; pInfo->requestId = generateRequestId(); pInfo->requestObjRefId = 0; @@ -738,8 +747,12 @@ static void *hbThreadFunc(void *param) { // hbClearReqInfo(pAppHbMgr); atomic_add_fetch_32(&pAppHbMgr->reportCnt, 1); + taosArrayPush(mgr, &pAppHbMgr); } + taosArrayDestroy(clientHbMgr.appHbMgrs); + clientHbMgr.appHbMgrs = mgr; + taosThreadMutexUnlock(&clientHbMgr.lock); taosMsleep(HEARTBEAT_INTERVAL); @@ -831,7 +844,7 @@ void hbRemoveAppHbMrg(SAppHbMgr **pAppHbMgr) { if (pItem == *pAppHbMgr) { hbFreeAppHbMgr(*pAppHbMgr); *pAppHbMgr = NULL; - taosArrayRemove(clientHbMgr.appHbMgrs, i); + taosArraySet(clientHbMgr.appHbMgrs, i, NULL); break; } } @@ -856,7 +869,15 @@ int hbMgrInit() { clientHbMgr.appSummary = taosHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); clientHbMgr.appHbMgrs = taosArrayInit(0, sizeof(void *)); - taosThreadMutexInit(&clientHbMgr.lock, NULL); + + TdThreadMutexAttr attr = {0}; + taosThreadMutexAttrSetType(&attr, PTHREAD_MUTEX_RECURSIVE); + + int ret = taosThreadMutexAttrInit(&attr); + assert(ret == 0); + + taosThreadMutexInit(&clientHbMgr.lock, &attr); + taosThreadMutexAttrDestroy(&attr); // init handle funcs hbMgrInitHandle(); From ef18966fa95ffbe23dcff2a1c520ad8517b89dae Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 15 Sep 2022 09:53:32 +0800 Subject: [PATCH 03/12] enh(tsc): handle deadlock --- source/client/src/clientHb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index fc03a66655..cf968937ac 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -844,7 +844,7 @@ void hbRemoveAppHbMrg(SAppHbMgr **pAppHbMgr) { if (pItem == *pAppHbMgr) { hbFreeAppHbMgr(*pAppHbMgr); *pAppHbMgr = NULL; - taosArraySet(clientHbMgr.appHbMgrs, i, NULL); + taosArraySet(clientHbMgr.appHbMgrs, i, pAppHbMgr); break; } } From f4be9a60c348a7d17771d36a9cb5ecc53bb705b0 Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Thu, 15 Sep 2022 10:04:30 +0800 Subject: [PATCH 04/12] os: mac exit error --- source/os/src/osSemaphore.c | 11 +++--- source/os/src/osSysinfo.c | 35 +++++++++---------- tests/system-test/0-others/taosShellNetChk.py | 2 +- tests/system-test/1-insert/mutil_stage.py | 3 ++ 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/source/os/src/osSemaphore.c b/source/os/src/osSemaphore.c index 8cc6f0ef2e..5baba5af1e 100644 --- a/source/os/src/osSemaphore.c +++ b/source/os/src/osSemaphore.c @@ -400,6 +400,9 @@ int tsem_init(tsem_t *psem, int flags, unsigned int count) { } int tsem_destroy(tsem_t *psem) { + if (psem == NULL || *psem == NULL) return -1; + dispatch_release(*psem); + *psem = NULL; return 0; } @@ -421,13 +424,7 @@ int tsem_timewait(tsem_t *psem, int64_t nanosecs) { return 0; } -bool taosCheckPthreadValid(TdThread thread) { - int32_t ret = taosThreadKill(thread, 0); - if (ret == ESRCH) return false; - if (ret == EINVAL) return false; - // alive - return true; -} +bool taosCheckPthreadValid(TdThread thread) { return thread != 0; } int64_t taosGetSelfPthreadId() { TdThread thread = taosThreadSelf(); diff --git a/source/os/src/osSysinfo.c b/source/os/src/osSysinfo.c index 19e9568bbe..0614b2a4c3 100644 --- a/source/os/src/osSysinfo.c +++ b/source/os/src/osSysinfo.c @@ -344,30 +344,27 @@ int32_t taosGetCpuInfo(char *cpuModel, int32_t maxLen, float *numOfCores) { *numOfCores = si.dwNumberOfProcessors; return 0; #elif defined(_TD_DARWIN_64) - char *line = NULL; - size_t size = 0; + char buf[16]; int32_t done = 0; int32_t code = -1; - TdFilePtr pFile = taosOpenFile("/proc/cpuinfo", TD_FILE_READ | TD_FILE_STREAM); - if (pFile == NULL) return false; - - while (done != 3 && (size = taosGetLineFile(pFile, &line)) != -1) { - line[size - 1] = '\0'; - if (((done & 1) == 0) && strncmp(line, "model name", 10) == 0) { - const char *v = strchr(line, ':') + 2; - tstrncpy(cpuModel, v, maxLen); - code = 0; - done |= 1; - } else if (((done & 2) == 0) && strncmp(line, "cpu cores", 9) == 0) { - const char *v = strchr(line, ':') + 2; - *numOfCores = atof(v); - done |= 2; - } + TdCmdPtr pCmd = taosOpenCmd("sysctl -n machdep.cpu.brand_string"); + if (pCmd == NULL) return code; + if (taosGetsCmd(pCmd, maxLen, cpuModel) > 0) { + code = 0; + done |= 1; } + taosCloseCmd(&pCmd); - if (line != NULL) taosMemoryFree(line); - taosCloseFile(&pFile); + pCmd = taosOpenCmd("sysctl -n machdep.cpu.core_count"); + if (pCmd == NULL) return code; + memset(buf, 0, sizeof(buf)); + if (taosGetsCmd(pCmd, maxLen, cpuModel) > 0) { + code = 0; + done |= 2; + *numOfCores = atof(buf); + } + taosCloseCmd(&pCmd); return code; #else diff --git a/tests/system-test/0-others/taosShellNetChk.py b/tests/system-test/0-others/taosShellNetChk.py index dd44852d49..80f6a6bc30 100644 --- a/tests/system-test/0-others/taosShellNetChk.py +++ b/tests/system-test/0-others/taosShellNetChk.py @@ -231,7 +231,7 @@ class TDTestCase: if platform.system().lower() == 'windows': os.system('ps -a | grep taos | awk \'{print $2}\' | xargs kill -9') else: - os.system('pkill taos') + os.system('pkill -9 taos') def stop(self): tdSql.close() diff --git a/tests/system-test/1-insert/mutil_stage.py b/tests/system-test/1-insert/mutil_stage.py index 764da1f166..63317e8036 100644 --- a/tests/system-test/1-insert/mutil_stage.py +++ b/tests/system-test/1-insert/mutil_stage.py @@ -1,4 +1,5 @@ from datetime import datetime +from platform import platform import time from typing import List, Any, Tuple @@ -83,6 +84,8 @@ class TDTestCase: def del_old_datadir(self, filename): cmd = f"sed -i '/^dataDir/d' {filename}" + if platform.system().lower() == 'darwin': + cmd = f"sed -i '' '/^dataDir/d' {filename}" if os.system(cmd) != 0: tdLog.exit(cmd) From 1091302e8d948737c101d1cd1e0d4e2062d23ab3 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 15 Sep 2022 10:30:17 +0800 Subject: [PATCH 05/12] fix: fix mem leak --- source/client/src/clientHb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index cf968937ac..9b85d403be 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -855,6 +855,7 @@ void appHbMgrCleanup(void) { int sz = taosArrayGetSize(clientHbMgr.appHbMgrs); for (int i = 0; i < sz; i++) { SAppHbMgr *pTarget = taosArrayGetP(clientHbMgr.appHbMgrs, i); + if (pTarget == NULL) continue; hbFreeAppHbMgr(pTarget); } } From 091c8ecfcd07f716873ecbcad3d5970c438cdfef Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 15 Sep 2022 11:30:27 +0800 Subject: [PATCH 06/12] enh(tsc): handle deadlock --- source/client/src/clientHb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index 9b85d403be..1cf53881a8 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -873,7 +873,6 @@ int hbMgrInit() { TdThreadMutexAttr attr = {0}; taosThreadMutexAttrSetType(&attr, PTHREAD_MUTEX_RECURSIVE); - int ret = taosThreadMutexAttrInit(&attr); assert(ret == 0); From fe29f000193f79977b79b45fe33194c988e1078c Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 15 Sep 2022 17:23:48 +0800 Subject: [PATCH 07/12] fix: fix deadlock --- source/client/src/clientHb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index a7e42a01a3..7ce80553a0 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -707,6 +707,7 @@ static void *hbThreadFunc(void *param) { int32_t connCnt = atomic_load_32(&pAppHbMgr->connKeyCnt); if (connCnt == 0) { + taosArrayPush(mgr, &pAppHbMgr); continue; } SClientHbBatchReq *pReq = hbGatherAllInfo(pAppHbMgr); @@ -720,6 +721,7 @@ static void *hbThreadFunc(void *param) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; tFreeClientHbBatchReq(pReq); // hbClearReqInfo(pAppHbMgr); + taosArrayPush(mgr, &pAppHbMgr); break; } @@ -731,6 +733,7 @@ static void *hbThreadFunc(void *param) { tFreeClientHbBatchReq(pReq); // hbClearReqInfo(pAppHbMgr); taosMemoryFree(buf); + taosArrayPush(mgr, &pAppHbMgr); break; } pInfo->fp = hbAsyncCallBack; From 3ee376c2c098f4cfe23f57038bf65eba9c5820e0 Mon Sep 17 00:00:00 2001 From: Cary Xu Date: Thu, 15 Sep 2022 18:37:26 +0800 Subject: [PATCH 08/12] fix: revert the code change --- source/dnode/vnode/src/tsdb/tsdbRetention.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index eb4151079b..2c68c57176 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -16,19 +16,9 @@ #include "tsdb.h" static bool tsdbShouldDoRetention(STsdb *pTsdb, int64_t now) { - STsdbKeepCfg *keepCfg = &pTsdb->keepCfg; - - if ((keepCfg->keep0 == keepCfg->keep1) && (keepCfg->keep1 == keepCfg->keep2)) { - return false; - } - - if (tfsGetLevel(pTsdb->pVnode->pTfs) <= 1) { - return false; - } - for (int32_t iSet = 0; iSet < taosArrayGetSize(pTsdb->fs.aDFileSet); iSet++) { SDFileSet *pSet = (SDFileSet *)taosArrayGet(pTsdb->fs.aDFileSet, iSet); - int32_t expLevel = tsdbFidLevel(pSet->fid, keepCfg, now); + int32_t expLevel = tsdbFidLevel(pSet->fid, &pTsdb->keepCfg, now); SDiskID did; if (expLevel == pSet->diskId.level) continue; From 16ed1f3e2d12e1e57f0b48a89c8e3659b1dd73b8 Mon Sep 17 00:00:00 2001 From: Chait Diwadkar <94201190+cdiwadkar16@users.noreply.github.com> Date: Thu, 15 Sep 2022 11:28:02 -0700 Subject: [PATCH 09/12] docs:cdiwadkar16-patch-1 - create Jupyterlab tech doc for 3.0 This is the Juptyerlab doc for 3.0 --- docs/en/20-third-party/13-Jupyter.md | 98 ++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 docs/en/20-third-party/13-Jupyter.md diff --git a/docs/en/20-third-party/13-Jupyter.md b/docs/en/20-third-party/13-Jupyter.md new file mode 100644 index 0000000000..fbd7e530f0 --- /dev/null +++ b/docs/en/20-third-party/13-Jupyter.md @@ -0,0 +1,98 @@ +--- +sidebar_label: JupyterLab +title: Connect JupyterLab to TDengine +--- + +JupyterLab is the next generation of the ubiquitous Jupyter Notebook. In this note we show you how to install the TDengine Python connector to connect to TDengine in JupyterLab. You can then insert data and perform queries against the TDengine instance within JupyterLab. + +## Install JupyterLab +Installing JupyterLab is very easy. Installation instructions can be found at: + +https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html. + +If you don't feel like clicking on the link here are the instructions. +Jupyter's preferred Python package manager is pip, so we show the instructions for pip. +You can also use **conda** or **pipenv** if you are managing Python environments. +```` +pip install jupyterlab +```` + +For **conda** you can run: +```` +conda install -c conda-forge jupyterlab +```` + +For **pipenv** you can run: +```` +pipenv install jupyterlab +pipenv shell +```` + +## Run JupyterLab +You can start JupyterLab from the command line by running: +```` +jupyter lab +```` +This will automatically launch your default browser and connect to your JupyterLab instance, usually on port 8888. + +## Install the TDengine Python connector +You can now install the TDengine Python connector as follows. + +Start a new Python kernel in JupyterLab. + +If using **conda** run the following: +```` +# Install a conda package in the current Jupyter kernel +import sys +!conda install --yes --prefix {sys.prefix} taospy +```` +If using **pip** run the following: +```` +# Install a pip package in the current Jupyter kernel +import sys +!{sys.executable} -m pip install taospy +```` + +## Connect to TDengine +You can find detailed examples to use the Python connector, in the TDengine documentation here. +Once you have installed the TDengine Python connector in your JupyterLab kernel, the process of connecting to TDengine is the same as that you would use if you weren't using JupyterLab. +Each TDengine instance, has a database called "log" which has monitoring information about the TDengine instance. +In the "log" database there is a [supertable](https://docs.tdengine.com/taos-sql/stable/) called "disks_info". + +The structure of this table is as follows: +```` +taos> desc disks_info; + Field | Type | Length | Note | +================================================================================= + ts | TIMESTAMP | 8 | | + datadir_l0_used | FLOAT | 4 | | + datadir_l0_total | FLOAT | 4 | | + datadir_l1_used | FLOAT | 4 | | + datadir_l1_total | FLOAT | 4 | | + datadir_l2_used | FLOAT | 4 | | + datadir_l2_total | FLOAT | 4 | | + dnode_id | INT | 4 | TAG | + dnode_ep | BINARY | 134 | TAG | +Query OK, 9 row(s) in set (0.000238s) +```` + +The code below is used to fetch data from this table into a pandas DataFrame. + +```` +import sys +import taos +import pandas + +def sqlQuery(conn): + df: pandas.DataFrame = pandas.read_sql("select * from log.disks_info limit 500", conn) + print(df) + return df + +conn = taos.connect() + +result = sqlQuery(conn) + +print(result) +```` + +TDengine has connectors for various languages including Node.js, Go, PHP and there are kernels for these languages which can be found [here](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels). From c77aa7004d0f0f34b1af489424ba8814eb47215a Mon Sep 17 00:00:00 2001 From: Jeff Tao Date: Thu, 15 Sep 2022 13:06:56 -0700 Subject: [PATCH 10/12] Update 01-index.md --- docs/en/01-index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/01-index.md b/docs/en/01-index.md index 5265be42f8..13552ea9dc 100644 --- a/docs/en/01-index.md +++ b/docs/en/01-index.md @@ -4,7 +4,7 @@ sidebar_label: Documentation Home slug: / --- -TDengine is an [open-source](https://tdengine.com/tdengine/open-source-time-series-database/), [cloud-native](https://tdengine.com/tdengine/cloud-native-time-series-database/) time-series database optimized for the Internet of Things (IoT), Connected Cars, and Industrial IoT. It enables efficient, real-time data ingestion, processing, and monitoring of TB and even PB scale data per day, generated by billions of sensors and data collectors. This document is the TDengine user manual. It introduces the basic, as well as novel concepts, in TDengine, and also talks in detail about installation, features, SQL, APIs, operation, maintenance, kernel design, and other topics. It’s written mainly for architects, developers, and system administrators. +TDengine is an [open-source](https://tdengine.com/tdengine/open-source-time-series-database/), [cloud-native](https://tdengine.com/tdengine/cloud-native-time-series-database/) [time-series database](https://tdengine.com/tsdb/) optimized for the Internet of Things (IoT), Connected Cars, and Industrial IoT. It enables efficient, real-time data ingestion, processing, and monitoring of TB and even PB scale data per day, generated by billions of sensors and data collectors. This document is the TDengine user manual. It introduces the basic, as well as novel concepts, in TDengine, and also talks in detail about installation, features, SQL, APIs, operation, maintenance, kernel design, and other topics. It’s written mainly for architects, developers, and system administrators. To get an overview of TDengine, such as a feature list, benchmarks, and competitive advantages, please browse through the [Introduction](./intro) section. @@ -22,6 +22,8 @@ If you want to know more about TDengine tools, the REST API, and connectors for If you are very interested in the internal design of TDengine, please read the chapter [Inside TDengine](./tdinternal), which introduces the cluster design, data partitioning, sharding, writing, and reading processes in detail. If you want to study TDengine code or even contribute code, please read this chapter carefully. +To get more general introduction about time series database, please read through [a series of articles](https://tdengine.com/tsdb/). To lean more competitive advantages about TDengine, please read through [a series of blogs](https://tdengine.com/tdengine/). + TDengine is an open-source database, and we would love for you to be a part of TDengine. If you find any errors in the documentation or see parts where more clarity or elaboration is needed, please click "Edit this page" at the bottom of each page to edit it directly. Together, we make a difference! From 9506603bb82e0edcdf08d058e23ca85f758c9754 Mon Sep 17 00:00:00 2001 From: Jeff Tao Date: Thu, 15 Sep 2022 13:11:12 -0700 Subject: [PATCH 11/12] Update index.md --- docs/en/02-intro/index.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index d385845d7c..3d1b505732 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -3,7 +3,7 @@ title: Introduction toc_max_heading_level: 2 --- -TDengine is an open source, high-performance, cloud native [time-series database](https://tdengine.com/tsdb/) optimized for Internet of Things (IoT), Connected Cars, and Industrial IoT. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](../develop/cache), [stream processing](../develop/stream), [data subscription](../develop/tmq) and other functionalities to reduce the system complexity and cost of development and operation. +TDengine is an [open source](https://tdengine.com/tdengine/open-source-time-series-database/), [high-performance](https://tdengine.com/tdengine/high-performance-time-series-database/), cloud native [time-series database](https://tdengine.com/tsdb/) optimized for Internet of Things (IoT), Connected Cars, and Industrial IoT. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](../develop/cache), [stream processing](../develop/stream), [data subscription](../develop/tmq) and other functionalities to reduce the system complexity and cost of development and operation. This section introduces the major features, competitive advantages, typical use-cases and benchmarks to help you get a high level overview of TDengine. @@ -43,7 +43,7 @@ For more details on features, please read through the entire documentation. ## Competitive Advantages -By making full use of [characteristics of time series data](https://tdengine.com/tsdb/characteristics-of-time-series-data/), TDengine differentiates itself from other time series databases, with the following advantages. +By making full use of [characteristics of time series data](https://tdengine.com/tsdb/characteristics-of-time-series-data/), TDengine differentiates itself from other [time series databases](https://tdengine.com/tsdb), with the following advantages. - **[High-Performance](https://tdengine.com/tdengine/high-performance-time-series-database/)**: TDengine is the only time-series database to solve the high cardinality issue to support billions of data collection points while out performing other time-series databases for data ingestion, querying and data compression. @@ -127,3 +127,8 @@ As a high-performance, scalable and SQL supported time-series database, TDengine - [TDengine vs OpenTSDB](https://tdengine.com/2019/09/12/710.html) - [TDengine vs Cassandra](https://tdengine.com/2019/09/12/708.html) - [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) + +## More readings +- [Introduction to Time-Series Database](https://tdengine.com/tsdb/) +- [Introduction to TDengine competitive advantages](https://tdengine.com/tdengine/) + From de05b2cf3cb57f89fe8b80144ed28e84546e4559 Mon Sep 17 00:00:00 2001 From: Jeff Tao Date: Thu, 15 Sep 2022 13:12:07 -0700 Subject: [PATCH 12/12] Update index.md --- docs/en/02-intro/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index 3d1b505732..2084088352 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -3,7 +3,7 @@ title: Introduction toc_max_heading_level: 2 --- -TDengine is an [open source](https://tdengine.com/tdengine/open-source-time-series-database/), [high-performance](https://tdengine.com/tdengine/high-performance-time-series-database/), cloud native [time-series database](https://tdengine.com/tsdb/) optimized for Internet of Things (IoT), Connected Cars, and Industrial IoT. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](../develop/cache), [stream processing](../develop/stream), [data subscription](../develop/tmq) and other functionalities to reduce the system complexity and cost of development and operation. +TDengine is an [open source](https://tdengine.com/tdengine/open-source-time-series-database/), [high-performance](https://tdengine.com/tdengine/high-performance-time-series-database/), [cloud native](https://tdengine.com/tdengine/cloud-native-time-series-database/) [time-series database](https://tdengine.com/tsdb/) optimized for Internet of Things (IoT), Connected Cars, and Industrial IoT. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](../develop/cache), [stream processing](../develop/stream), [data subscription](../develop/tmq) and other functionalities to reduce the system complexity and cost of development and operation. This section introduces the major features, competitive advantages, typical use-cases and benchmarks to help you get a high level overview of TDengine.