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);