diff --git a/documentation20/webdocs/markdowndocs/Documentation-ch.md b/documentation20/webdocs/markdowndocs/Documentation-ch.md
index 766a428f1bfa8559dfb86701195868a8b6821ebc..20f9bcb7307c68f1330519d8f6ed249419bf46db 100644
--- a/documentation20/webdocs/markdowndocs/Documentation-ch.md
+++ b/documentation20/webdocs/markdowndocs/Documentation-ch.md
@@ -128,5 +128,18 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
## [培训和FAQ](https://www.taosdata.com/cn/faq)
-- [FAQ](https://www.taosdata.com/cn/documentation20/faq):常见问题与答案
-- [应用案列](https://www.taosdata.com/cn/blog/?categories=4):一些使用实例来解释如何使用TDengine
+
+
diff --git a/documentation20/webdocs/markdowndocs/Getting Started-ch.md b/documentation20/webdocs/markdowndocs/Getting Started-ch.md
index 9f9d3a2ec292af8745cde58f7467a63ab4de33fe..b53c014ba64fb203cb8e6943297fe6117034385c 100644
--- a/documentation20/webdocs/markdowndocs/Getting Started-ch.md
+++ b/documentation20/webdocs/markdowndocs/Getting Started-ch.md
@@ -20,7 +20,7 @@ TDengine的安装非常简单,从下载到安装成功仅仅只要几秒钟。
- TDengine-server-2.0.10.0-Linux-x64.deb (2.7M)
- TDengine-server-2.0.10.0-Linux-x64.tar.gz (4.5M)
-具体的安装过程,请参见TDengine多种安装包的安装和卸载。
+具体的安装过程,请参见TDengine多种安装包的安装和卸载以及视频教程。
## 轻松启动
diff --git a/documentation20/webdocs/markdowndocs/Model-ch.md b/documentation20/webdocs/markdowndocs/Model-ch.md
index 27105bdb901842d1960528de0050d84a66923fb5..dce7819423661a3748c4c5cd4402777e21b16a89 100644
--- a/documentation20/webdocs/markdowndocs/Model-ch.md
+++ b/documentation20/webdocs/markdowndocs/Model-ch.md
@@ -59,3 +59,5 @@ INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 21
TDengine支持多列模型,只要物理量是一个数据采集点同时采集的(时间戳一致),这些量就可以作为不同列放在一张超级表里。但还有一种极限的设计,单列模型,每个采集的物理量都单独建表,因此每种类型的物理量都单独建立一超级表。比如电流、电压、相位,就建三张超级表。
TDengine建议尽可能采用多列模型,因为插入效率以及存储效率更高。但对于有些场景,一个采集点的采集量的种类经常变化,这个时候,如果采用多列模型,就需要频繁修改超级表的结构定义,让应用变的复杂,这个时候,采用单列模型会显得简单。
+
+关于数据建模请参考视频教程。
diff --git a/documentation20/webdocs/markdowndocs/cluster-ch.md b/documentation20/webdocs/markdowndocs/cluster-ch.md
index 60ac6e4c2edb67fffcc2a729b452e75323505fab..f1c275ab0c4c986766fa8d33c71fe65777c90848 100644
--- a/documentation20/webdocs/markdowndocs/cluster-ch.md
+++ b/documentation20/webdocs/markdowndocs/cluster-ch.md
@@ -226,3 +226,5 @@ SHOW MNODES;
如果副本数为偶数,当一个vnode group里一半vnode不工作时,是无法从中选出master的。同理,一半mnode不工作时,是无法选出mnode的master的,因为存在“split brain”问题。为解决这个问题,TDengine引入了arbitrator的概念。Arbitrator模拟一个vnode或mnode在工作,但只简单的负责网络连接,不处理任何数据插入或访问。只要包含arbitrator在内,超过半数的vnode或mnode工作,那么该vnode group或mnode组就可以正常的提供数据插入或查询服务。比如对于副本数为2的情形,如果一个节点A离线,但另外一个节点B正常,而且能连接到arbitrator, 那么节点B就能正常工作。
TDengine提供一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。请点击[安装包下载](https://www.taosdata.com/cn/all-downloads/),在TDengine Arbitrator Linux一节中,选择适合的版本下载并安装。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6042。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的arbitrator。如果副本数为奇数,即使配置了arbitrator, 系统也不会去建立连接。
+
+关于集群搭建请参考视频教程。
diff --git a/documentation20/webdocs/markdowndocs/connector-ch.md b/documentation20/webdocs/markdowndocs/connector-ch.md
index 821b4c23bff5409995c216e05cc3bde41ca6a717..cc6287953ad0561841d7435148ecae07d28b6ca8 100644
--- a/documentation20/webdocs/markdowndocs/connector-ch.md
+++ b/documentation20/webdocs/markdowndocs/connector-ch.md
@@ -187,7 +187,7 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
- pass:密码
- db:数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库
- port:端口号
-
+
返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。
- `char *taos_get_server_info(TAOS *taos)`
@@ -336,7 +336,7 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线
- `TAOS_RES* taos_stmt_use_result(TAOS_STMT *stmt)`
获取语句的结果集。结果集的使用方式与非参数化调用时一致,使用完成后,应对此结果集调用 `taos_free_result`以释放资源。
-
+
- `int taos_stmt_close(TAOS_STMT *stmt)`
执行完毕,释放所有资源。
@@ -354,7 +354,7 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
* stime:是流式计算开始的时间,如果是0,表示从现在开始,如果不为零,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)
* param:是应用提供的用于回调的一个参数,回调时,提供给应用
* callback: 第二个回调函数,会在连续查询自动停止时被调用。
-
+
返回值为NULL,表示创建成功,返回值不为空,表示成功。
- `void taos_close_stream (TAOS_STREAM *tstr)`
@@ -394,6 +394,8 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
## Python Connector
+Python连接器的使用参见视频教程
+
### 安装准备
* 应用驱动安装请参考安装连接器驱动步骤。
* 已安装python 2.7 or >= 3.4
@@ -433,7 +435,7 @@ python -m pip install python3\
* 导入TDengine客户端模块
```python
-import taos
+import taos
```
* 获取连接并获取游标对象
```python
@@ -445,7 +447,7 @@ c1 = conn.cursor()
* 写入数据
```python
import datetime
-
+
# 创建数据库
c1.execute('create database db')
c1.execute('use db')
@@ -473,7 +475,7 @@ numOfRows = c1.rowcount
numOfCols = len(c1.description)
for irow in range(numOfRows):
print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2]))
-
+
# 直接使用cursor 循环拉取查询结果
c1.execute('select * from tb')
for data in c1:
@@ -534,7 +536,7 @@ conn.close()
## RESTful Connector
-为支持各种不同类型平台的开发,TDengine提供符合REST设计标准的API,即RESTful API。为最大程度降低学习成本,不同于其他数据库RESTful API的设计方法,TDengine直接通过HTTP POST 请求BODY中包含的SQL语句来操作数据库,仅需要一个URL。
+为支持各种不同类型平台的开发,TDengine提供符合REST设计标准的API,即RESTful API。为最大程度降低学习成本,不同于其他数据库RESTful API的设计方法,TDengine直接通过HTTP POST 请求BODY中包含的SQL语句来操作数据库,仅需要一个URL。RESTful连接器的使用参见视频教程。
### HTTP请求格式
@@ -779,7 +781,7 @@ https://www.taosdata.com/blog/2020/11/02/1901.html
TDengine提供了GO驱动程序`taosSql`。 `taosSql`实现了GO语言的内置接口`database/sql/driver`。用户只需按如下方式引入包就可以在应用程序中访问TDengine, 详见`https://github.com/taosdata/driver-go/blob/develop/taosSql/driver_test.go`。
-使用 Go 连接器的示例代码请参考 https://github.com/taosdata/TDengine/tree/develop/tests/examples/go。
+使用 Go 连接器的示例代码请参考 https://github.com/taosdata/TDengine/tree/develop/tests/examples/go 以及视频教程。
```Go
import (
@@ -796,7 +798,7 @@ go env -w GOPROXY=https://goproxy.io,direct
### 常用API
-- sql.Open(DRIVER_NAME string, dataSourceName string) *DB`
+- `sql.Open(DRIVER_NAME string, dataSourceName string) *DB`
该API用来打开DB,返回一个类型为*DB的对象,一般情况下,DRIVER_NAME设置为字符串`taosSql`, dataSourceName设置为字符串`user:password@/tcp(host:port)/dbname`,如果客户想要用多个goroutine并发访问TDengine, 那么需要在各个goroutine中分别创建一个sql.Open对象并用之访问TDengine
@@ -835,6 +837,8 @@ Node.js连接器支持的系统有:
| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
| **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** |
+Node.js连接器的使用参见视频教程
+
### 安装准备
* 应用驱动安装请参考安装连接器驱动步骤。
@@ -909,7 +913,7 @@ node nodejsChecker.js host=localhost
#### 建立连接
-使用node.js连接器时,必须先require ```td2.0-connector```,然后使用 ```taos.connect``` 函数。```taos.connect``` 函数必须提供的参数是```host```,其它参数在没有提供的情况下会使用如下的默认值。最后需要初始化```cursor``` 来和TDengine服务端通信
+使用node.js连接器时,必须先require `td2.0-connector`,然后使用 `taos.connect` 函数。`taos.connect` 函数必须提供的参数是`host`,其它参数在没有提供的情况下会使用如下的默认值。最后需要初始化`cursor` 来和TDengine服务端通信
```javascript
const taos = require('td2.0-connector');
@@ -945,13 +949,13 @@ TDengine目前还不支持update和delete语句。
#### 查询
-可通过 ```cursor.query``` 函数来查询数据库。
+可通过 `cursor.query` 函数来查询数据库。
```javascript
var query = cursor.query('show databases;')
```
-查询的结果可以通过 ```query.execute()``` 函数获取并打印出来
+查询的结果可以通过 `query.execute()` 函数获取并打印出来
```javascript
var promise = query.execute();
@@ -959,7 +963,7 @@ promise.then(function(result) {
result.pretty();
});
```
-格式化查询语句还可以使用```query```的```bind```方法。如下面的示例:```query```会自动将提供的数值填入查询语句的```?```里。
+格式化查询语句还可以使用`query`的`bind`方法。如下面的示例:`query`会自动将提供的数值填入查询语句的`?`里。
```javascript
var query = cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?;').bind(new Date(), 5);
@@ -967,7 +971,7 @@ query.execute().then(function(result) {
result.pretty();
})
```
-如果在```query```语句里提供第二个参数并设为```true```也可以立即获取查询结果。如下:
+如果在`query`语句里提供第二个参数并设为`true`也可以立即获取查询结果。如下:
```javascript
var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true)
@@ -991,4 +995,4 @@ promise2.then(function(result) {
### 示例
这里提供了一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例
-这里同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`cursor`.
\ No newline at end of file
+这里同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`cursor`.
diff --git a/documentation20/webdocs/markdowndocs/connector-java-ch.md b/documentation20/webdocs/markdowndocs/connector-java-ch.md
index fe029ba269c3b3784ae50f7d5a8708da9aa7d426..7ba573d2e44bb3848d13a2f6b7cb81038843a291 100644
--- a/documentation20/webdocs/markdowndocs/connector-java-ch.md
+++ b/documentation20/webdocs/markdowndocs/connector-java-ch.md
@@ -6,6 +6,8 @@ Java连接器支持的系统有:
| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
| **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** |
+Java连接器的使用请参见视频教程。
+
TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现。目前可以通过 [Sonatype Repository][1] 搜索并下载。
由于 TDengine 是使用 c 语言开发的,使用 taos-jdbcdriver 驱动包时需要依赖系统对应的本地函数库。
diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h
index 33ea06ba9c03df9b4d7dd2fd67fca4cbabf95707..dcbbefd26d57b21ec04db391bc2c3ca43d6be55a 100644
--- a/src/client/inc/tsclient.h
+++ b/src/client/inc/tsclient.h
@@ -419,7 +419,7 @@ void tscCloseTscObj(void *pObj);
// todo move to taos? or create a new file: taos_internal.h
TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int),
void *param, TAOS **taos);
-TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, TAOS_RES** res);
+TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, int64_t* res);
void waitForQueryRsp(void *param, TAOS_RES *tres, int code);
void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, __async_cb_func_t fp, void *param, const char *sqlstr, size_t sqlLen);
diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c
index ded04388f41d0f783f2379ebf6b09327de4204fb..45e10ac402df5a271e0f9816604a2c3d6dcba1b2 100644
--- a/src/client/src/tscServer.c
+++ b/src/client/src/tscServer.c
@@ -1247,7 +1247,7 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pShowMsg->payloadLen = htons(pEpAddr->n);
}
- pCmd->payloadLen = sizeof(SShowMsg) + pShowMsg->payloadLen;
+ pCmd->payloadLen = sizeof(SShowMsg) + htons(pShowMsg->payloadLen);
return TSDB_CODE_SUCCESS;
}
diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c
index bb0d8005c2d7234b5a9dca1cc788239ece088965..fa7bc99a9f304c45db46891f444509ec4c72e97f 100644
--- a/src/client/src/tscSql.c
+++ b/src/client/src/tscSql.c
@@ -314,7 +314,7 @@ static void waitForRetrieveRsp(void *param, TAOS_RES *tres, int numOfRows) {
tsem_post(&pSql->rspSem);
}
-TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, TAOS_RES** res) {
+TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, int64_t* res) {
STscObj *pObj = (STscObj *)taos;
if (pObj == NULL || pObj->signature != pObj) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
@@ -340,7 +340,7 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, TAOS_RES
doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen);
if (res != NULL) {
- *res = pSql;
+ atomic_store_64(res, pSql->self);
}
tsem_wait(&pSql->rspSem);
@@ -351,7 +351,7 @@ TAOS_RES* taos_query(TAOS *taos, const char *sqlstr) {
return taos_query_c(taos, sqlstr, (uint32_t)strlen(sqlstr), NULL);
}
-TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, TAOS_RES** res) {
+TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, int64_t* res) {
return taos_query_c(taos, sqlstr, (uint32_t) strlen(sqlstr), res);
}
diff --git a/src/dnode/inc/dnodeCfg.h b/src/dnode/inc/dnodeCfg.h
index d74303f3252e1fa54e174876bab5758be541955e..896b3f574c2e0d02a0d62048a411fa484d16130b 100644
--- a/src/dnode/inc/dnodeCfg.h
+++ b/src/dnode/inc/dnodeCfg.h
@@ -25,6 +25,7 @@ int32_t dnodeInitCfg();
void dnodeCleanupCfg();
void dnodeUpdateCfg(SDnodeCfg *cfg);
int32_t dnodeGetDnodeId();
+void dnodeGetClusterId(char *clusterId);
void dnodeGetCfg(int32_t *dnodeId, char *clusterId);
#ifdef __cplusplus
diff --git a/src/dnode/src/dnodeCfg.c b/src/dnode/src/dnodeCfg.c
index 89249d773b7c67b8939a7a70f65882f89f8f5190..f495dbe285c196f3e32d8a0ace8736c8f44d668d 100644
--- a/src/dnode/src/dnodeCfg.c
+++ b/src/dnode/src/dnodeCfg.c
@@ -51,6 +51,12 @@ int32_t dnodeGetDnodeId() {
return dnodeId;
}
+void dnodeGetClusterId(char *clusterId) {
+ pthread_mutex_lock(&tsCfgMutex);
+ tstrncpy(clusterId, tsCfg.clusterId, TSDB_CLUSTER_ID_LEN);
+ pthread_mutex_unlock(&tsCfgMutex);
+}
+
void dnodeGetCfg(int32_t *dnodeId, char *clusterId) {
pthread_mutex_lock(&tsCfgMutex);
*dnodeId = tsCfg.dnodeId;
diff --git a/src/inc/dnode.h b/src/inc/dnode.h
index dd41360e68e1868dc1b947cfc5ab4188e96fc320..877738778b022c9c7d38a3801beb5cdc86ff9f4d 100644
--- a/src/inc/dnode.h
+++ b/src/inc/dnode.h
@@ -36,6 +36,8 @@ bool dnodeIsMasterEp(char *ep);
void dnodeGetEpSetForPeer(SRpcEpSet *epSet);
void dnodeGetEpSetForShell(SRpcEpSet *epSet);
int32_t dnodeGetDnodeId();
+void dnodeGetClusterId(char *clusterId);
+
void dnodeUpdateEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr);
bool dnodeStartMnode(SMInfos *pMinfos);
@@ -80,4 +82,4 @@ void dnodeReportStep(char *name, char *desc, int8_t finished);
}
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h
index aa0c2fcaf9219640dc1d5c00b3b5072d7143e52f..200fe2b0f97869ba5b73881188493718181bb82d 100644
--- a/src/inc/taosmsg.h
+++ b/src/inc/taosmsg.h
@@ -324,6 +324,7 @@ typedef struct {
typedef struct {
char acctId[TSDB_ACCT_LEN];
char serverVersion[TSDB_VERSION_LEN];
+ char clusterId[TSDB_CLUSTER_ID_LEN];
int8_t writeAuth;
int8_t superAuth;
int8_t reserved1;
diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c
index 627d06ac2e59ec2bdb222998ea05018c038830ab..fca0e93472a350e8a6fddb8acc5ff54af67fa833 100644
--- a/src/kit/shell/src/shellEngine.c
+++ b/src/kit/shell/src/shellEngine.c
@@ -302,14 +302,12 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
st = taosGetTimestampUs();
- TAOS_RES* tmpSql = NULL;
- TAOS_RES* pSql = taos_query_h(con, command, &tmpSql);
+ TAOS_RES* pSql = taos_query_h(con, command, &result);
if (taos_errno(pSql)) {
taos_error(pSql, st);
return;
}
- atomic_store_64(&result, ((SSqlObj*)tmpSql)->self);
int64_t oresult = atomic_load_64(&result);
if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) {
diff --git a/src/mnode/src/mnodeShow.c b/src/mnode/src/mnodeShow.c
index 3c1c92226a26d0d0195020c05b579c0b6c326fa3..6b9f0e26a762092cfae02b5724d6cfedd24194d2 100644
--- a/src/mnode/src/mnodeShow.c
+++ b/src/mnode/src/mnodeShow.c
@@ -351,6 +351,8 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
mnodeGetMnodeEpSetForShell(&pConnectRsp->epSet, false);
+ dnodeGetClusterId(pConnectRsp->clusterId);
+
connect_over:
if (code != TSDB_CODE_SUCCESS) {
if (pConnectRsp) rpcFreeCont(pConnectRsp);