Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
d1bd4b12
T
TDengine
项目概览
慢慢CG
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
d1bd4b12
编写于
12月 23, 2020
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
差异文件
[TD-225]merge develop
上级
4c04ce09
a0981ed7
变更
52
显示空白变更内容
内联
并排
Showing
52 changed file
with
694 addition
and
567 deletion
+694
-567
Jenkinsfile
Jenkinsfile
+9
-8
cmake/version.inc
cmake/version.inc
+1
-1
documentation20/webdocs/markdowndocs/Super Table-ch.md
documentation20/webdocs/markdowndocs/Super Table-ch.md
+2
-2
documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
+78
-97
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
+0
-1
documentation20/webdocs/markdowndocs/administrator-ch.md
documentation20/webdocs/markdowndocs/administrator-ch.md
+12
-18
documentation20/webdocs/markdowndocs/architecture-ch.md
documentation20/webdocs/markdowndocs/architecture-ch.md
+5
-5
documentation20/webdocs/markdowndocs/connector-ch.md
documentation20/webdocs/markdowndocs/connector-ch.md
+235
-80
documentation20/webdocs/markdowndocs/connector-java-ch.md
documentation20/webdocs/markdowndocs/connector-java-ch.md
+22
-22
documentation20/webdocs/markdowndocs/faq-ch.md
documentation20/webdocs/markdowndocs/faq-ch.md
+12
-21
documentation20/webdocs/markdowndocs/insert-ch.md
documentation20/webdocs/markdowndocs/insert-ch.md
+13
-16
documentation20/webdocs/markdowndocs/replica-ch.md
documentation20/webdocs/markdowndocs/replica-ch.md
+8
-8
snap/snapcraft.yaml
snap/snapcraft.yaml
+2
-2
src/balance/src/bnMain.c
src/balance/src/bnMain.c
+47
-103
src/balance/src/bnScore.c
src/balance/src/bnScore.c
+1
-1
src/client/src/tscServer.c
src/client/src/tscServer.c
+3
-1
src/client/src/tscSubquery.c
src/client/src/tscSubquery.c
+3
-1
src/client/src/tscUtil.c
src/client/src/tscUtil.c
+3
-0
src/common/src/tglobal.c
src/common/src/tglobal.c
+6
-0
src/dnode/src/dnodeTelemetry.c
src/dnode/src/dnodeTelemetry.c
+2
-2
src/dnode/src/dnodeVMgmt.c
src/dnode/src/dnodeVMgmt.c
+2
-1
src/inc/taosmsg.h
src/inc/taosmsg.h
+6
-4
src/mnode/inc/mnodeDef.h
src/mnode/inc/mnodeDef.h
+3
-2
src/mnode/inc/mnodeDnode.h
src/mnode/inc/mnodeDnode.h
+3
-3
src/mnode/src/mnodeDb.c
src/mnode/src/mnodeDb.c
+1
-1
src/mnode/src/mnodeDnode.c
src/mnode/src/mnodeDnode.c
+17
-21
src/mnode/src/mnodeVgroup.c
src/mnode/src/mnodeVgroup.c
+9
-5
src/rpc/src/rpcMain.c
src/rpc/src/rpcMain.c
+1
-1
src/sync/src/syncMain.c
src/sync/src/syncMain.c
+4
-2
src/util/inc/tsocket.h
src/util/inc/tsocket.h
+1
-1
src/util/src/tnettest.c
src/util/src/tnettest.c
+1
-1
src/util/src/tsocket.c
src/util/src/tsocket.c
+2
-2
src/vnode/inc/vnodeInt.h
src/vnode/inc/vnodeInt.h
+2
-1
src/vnode/src/vnodeCfg.c
src/vnode/src/vnodeCfg.c
+14
-5
src/vnode/src/vnodeMain.c
src/vnode/src/vnodeMain.c
+1
-1
src/vnode/src/vnodeMgmt.c
src/vnode/src/vnodeMgmt.c
+2
-1
tests/Jenkinsfile
tests/Jenkinsfile
+3
-3
tests/pytest/concurrent_inquiry.py
tests/pytest/concurrent_inquiry.py
+43
-12
tests/pytest/fulltest.sh
tests/pytest/fulltest.sh
+2
-2
tests/pytest/functions/function_twa.py
tests/pytest/functions/function_twa.py
+10
-52
tests/pytest/functions/function_twa_restart.py
tests/pytest/functions/function_twa_restart.py
+17
-54
tests/pytest/functions/function_twa_test2.py
tests/pytest/functions/function_twa_test2.py
+4
-0
tests/script/jenkins/basic_3.txt
tests/script/jenkins/basic_3.txt
+1
-1
tests/script/unique/big/maxvnodes.sim
tests/script/unique/big/maxvnodes.sim
+2
-1
tests/script/unique/db/replica_add12.sim
tests/script/unique/db/replica_add12.sim
+4
-0
tests/script/unique/db/replica_add13.sim
tests/script/unique/db/replica_add13.sim
+1
-0
tests/script/unique/db/replica_add23.sim
tests/script/unique/db/replica_add23.sim
+1
-0
tests/script/unique/db/replica_part.sim
tests/script/unique/db/replica_part.sim
+3
-0
tests/script/unique/db/replica_reduce21.sim
tests/script/unique/db/replica_reduce21.sim
+5
-0
tests/script/unique/db/replica_reduce31.sim
tests/script/unique/db/replica_reduce31.sim
+4
-0
tests/script/unique/db/replica_reduce32.sim
tests/script/unique/db/replica_reduce32.sim
+3
-0
tests/test-all.sh
tests/test-all.sh
+58
-1
未找到文件。
Jenkinsfile
浏览文件 @
d1bd4b12
...
...
@@ -40,14 +40,15 @@ def pre_test(){
sh
'''
cd ${WKC}
rm -rf *
git checkout develop
git pull
git fetch
git checkout ${CHANGE_BRANCH}
git merge develop
cd ${WK}
git reset --hard
git checkout develop
git pull
cd ${WKC}
rm -rf *
mv ${WORKSPACE}/* .
cd ${WK}
export TZ=Asia/Harbin
date
...
...
@@ -85,7 +86,7 @@ pipeline {
pre_test
()
sh
'''
cd ${WKC}/tests
./test-all.sh pytest
./test-all.sh pytest
fq
date'''
}
}
...
...
@@ -95,7 +96,7 @@ pipeline {
pre_test
()
sh
'''
cd ${WKC}/tests
./test-all.sh b1
./test-all.sh b1
fq
date'''
}
}
...
...
@@ -119,7 +120,7 @@ pipeline {
sh
'''
date
cd ${WKC}/tests
./test-all.sh b2
./test-all.sh b2
fq
date
'''
}
...
...
@@ -140,7 +141,7 @@ pipeline {
sh
'''
date
cd ${WKC}/tests
./test-all.sh b3
./test-all.sh b3
fq
date'''
}
}
...
...
cmake/version.inc
浏览文件 @
d1bd4b12
...
...
@@ -4,7 +4,7 @@ PROJECT(TDengine)
IF
(
DEFINED
VERNUMBER
)
SET
(
TD_VER_NUMBER
$
{
VERNUMBER
})
ELSE
()
SET
(
TD_VER_NUMBER
"2.0.1
0
.0"
)
SET
(
TD_VER_NUMBER
"2.0.1
1
.0"
)
ENDIF
()
IF
(
DEFINED
VERCOMPATIBLE
)
...
...
documentation20/webdocs/markdowndocs/Super Table-ch.md
浏览文件 @
d1bd4b12
documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
浏览文件 @
d1bd4b12
...
...
@@ -77,7 +77,6 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
SHOW VARIABLES;
```
-
**使用数据库**
```mysql
...
...
@@ -85,7 +84,6 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```
使用/切换数据库
-
**删除数据库**
```
mysql
DROP DATABASE [IF EXISTS] db_name;
...
...
@@ -120,7 +118,6 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
**Tips**: 以上所有参数修改后都可以用show databases来确认是否修改成功。
-
**显示系统所有数据库**
```
mysql
SHOW DATABASES;
...
...
@@ -153,7 +150,6 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
显示当前数据库下的所有数据表信息。说明:可在like中使用通配符进行名称的匹配。 通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’_’下划线匹配一个字符。
-
**在线修改显示字符宽度**
```mysql
...
...
@@ -234,7 +230,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```mysql
ALTER TABLE stb_name ADD TAG new_tag_name tag_type;
```
为STable增加一个新的标签,并指定新标签的类型。标签总数不能超过128个,总长度不超过16k个字符
.
为STable增加一个新的标签,并指定新标签的类型。标签总数不能超过128个,总长度不超过16k个字符
。
-
**删除标签**
...
...
@@ -265,28 +261,24 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```
向表tb_name中插入一条记录
-
**插入一条记录,数据对应到指定的列**
```
mysql
INSERT INTO tb_name (field1_name, ...) VALUES(field1_value, ...)
```
向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。
-
**插入多条记录**
```
mysql
INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...)...;
```
向表tb_name中插入多条记录
-
**按指定的列插入多条记录**
```
mysql
INSERT INTO tb_name (field1_name, ...) VALUES(field1_value1, ...) (field1_value2, ...)
```
向表tb_name中按指定的列插入多条记录
-
**向多个表插入多条记录**
```
mysql
INSERT INTO tb1_name VALUES (field1_value1, ...)(field1_value2, ...)...
...
...
@@ -294,7 +286,6 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```
同时向表tb1_name和tb2_name中分别插入多条记录
-
**同时向多个表按列插入多条记录**
```
mysql
INSERT INTO tb1_name (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...)
...
...
@@ -382,7 +373,6 @@ taos> SELECT * FROM meters;
Query OK, 9 row(s) in set (0.002022s)
```
通配符支持表名前缀,以下两个SQL语句均为返回全部的列:
```
mysql
SELECT * FROM d1001;
...
...
@@ -613,7 +603,6 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
Query OK, 1 row(s) in set (0.001075s)
```
- **AVG**
```mysql
SELECT AVG(field_name) FROM tb_name [WHERE clause];
...
...
@@ -757,7 +746,6 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
Query OK, 1 row(s) in set (0.000987s)
```
- **FIRST**
```mysql
SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
...
...
@@ -937,7 +925,6 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
Query OK, 2 row(s) in set (0.001162s)
```
- **SPREAD**
```mysql
SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
...
...
@@ -962,7 +949,6 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
Query OK, 1 row(s) in set (0.000836s)
```
- **四则运算**
```mysql
...
...
@@ -1010,7 +996,6 @@ SELECT function_list FROM stb_name
4. PREV填充:使用前一个非NULL值填充数据。例如:fill(prev)。
说明:
1. 使用FILL语句的时候可能生成大量的填充输出,务必指定查询的时间区间。针对每次查询,系统可返回不超过1千万条具有插值的结果。
2. 在时间维度聚合中,返回的结果中时间序列严格单调递增。
...
...
@@ -1040,8 +1025,6 @@ SELECT AVG(current),MAX(current),LEASTSQUARES(current, start_val, step_val), PER
- SQL语句最大长度65480个字符,但可通过系统配置参数maxSQLLength修改,最长可配置为1M
- 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制
## TAOS SQL其他约定
**group by的限制**
...
...
@@ -1055,5 +1038,3 @@ TAOS SQL支持表之间按主键时间戳来join两张表的列,暂不支持
**is not null与不为空的表达式适用范围**
is not null支持所有类型的列。不为空的表达式为 <>"",仅对非数值类型的列适用。
\ No newline at end of file
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
浏览文件 @
d1bd4b12
# TDengine 2.0 错误码以及对应的十进制码
| 状态码 | 模 | 错误码(十六进制) | 错误描述 | 错误码(十进制) |
|-----------------------| :---: | :---------: | :------------------------ | ---------------- |
|TSDB_CODE_RPC_ACTION_IN_PROGRESS| 0 | 0x0001| "Action in progress"| -2147483647|
...
...
documentation20/webdocs/markdowndocs/administrator-ch.md
浏览文件 @
d1bd4b12
...
...
@@ -159,7 +159,7 @@ ALTER DNODE <dnode_id> <config>
## 客户端配置
TDengine系统的前台交互客户端应用程序为taos,以及应用驱动,它与taosd共享同一个配置文件taos.cfg。运行taos时,使用参数-c指定配置文件目录,如taos -c /home/cfg,表示使用/home/cfg/目录下的taos.cfg配置文件中的参数,缺省目录是/etc/taos。更多taos的使用方法请见
[
Shell命令行程序
](
https://www.taosdata.com/cn/documentation/administrator/#_TDengine_Shell命令行程序
)
。本节主要说明 taos 客户端应用在配置文件 taos.cfg 文件中使用到的参数。
TDengine系统的前台交互客户端应用程序为taos,以及应用驱动,它与taosd共享同一个配置文件taos.cfg。运行taos时,使用参数-c指定配置文件目录,如taos -c /home/cfg,表示使用/home/cfg/目录下的taos.cfg配置文件中的参数,缺省目录是/etc/taos。更多taos的使用方法请见
<a
href=
"https://www.taosdata.com/cn/documentation/administrator/#_TDengine_Shell命令行程序"
>
Shell命令行程序
</a>
。本节主要说明 taos 客户端应用在配置文件 taos.cfg 文件中使用到的参数。
**2.0.10.0 之后版本支持命令行以下参数显示当前客户端参数的配置**
...
...
@@ -247,7 +247,6 @@ taos -C 或 taos --dump-config
Shell中binary 和 nchar字段的显示宽度上限,超过此限制的部分将被隐藏。默认值:30。可在 shell 中通过命令 set max_binary_display_width nn 动态修改此选项。
## 用户管理
系统管理员可以在CLI界面里添加、删除用户,也可以修改密码。CLI里SQL语法如下:
...
...
@@ -428,8 +427,6 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
您可以通过修改系统配置文件taos.cfg来配置不同的数据目录和日志目录。
## TDengine参数限制与保留关键字
-
数据库名:不能包含“.”以及特殊字符,不能超过32个字符
...
...
@@ -448,8 +445,6 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
-
库的个数:仅受节点个数限制
-
单个库上虚拟节点个数:不能超过64个
目前TDengine有将近200个内部保留关键字,这些关键字无论大小写均不可以用作库名、表名、STable名、数据列名及标签列名等。这些关键字列表如下:
| 关键字列表 | | | | |
...
...
@@ -490,4 +485,3 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
| CONCAT | GLOB | METRICS | SEMI | WAVG |
| CONFIGS | GRANTS | MIN | SET | WHERE |
| CONFLICT | GROUP | | | |
\ No newline at end of file
documentation20/webdocs/markdowndocs/architecture-ch.md
浏览文件 @
d1bd4b12
#
数据模型和整体架构
#
数据模型和整体架构
## 数据模型
### 物联网典型场景
...
...
@@ -150,7 +150,7 @@ TDengine 分布式架构的逻辑结构图如下:
<center>
图 1 TDengine架构示意图
</center>
一个完整的 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,请看博文
<a
href=
"https://www.taosdata.com/blog/2020/09/11/1824.html"
>
《一篇文章说清楚TDengine的FQDN》
</a>
。
**数据节点(dnode):**
dnode 是 TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例,一个工作的系统必须有至少一个数据节点。dnode包含零到多个逻辑的虚拟节点(VNODE),零或者至多一个逻辑的管理节点(mnode)。dnode在系统中的唯一标识由实例的End Point (EP )决定。EP是dnode所在物理节点的FQDN (Fully Qualified Domain Name)和系统所配置的网络端口号(Port)的组合。通过配置不同的端口,一个物理节点(一台物理机、虚拟机或容器)可以运行多个实例,或有多个数据节点。
...
...
documentation20/webdocs/markdowndocs/connector-ch.md
浏览文件 @
d1bd4b12
# 连接器
TDengine提供了丰富的应用程序开发接口,其中包括C/C++、
C# 、Java、Python、Go、Node.js
、RESTful 等,便于用户快速开发应用。
TDengine提供了丰富的应用程序开发接口,其中包括C/C++、
Java、Python、Go、Node.js、C#
、RESTful 等,便于用户快速开发应用。

目前TDengine的连接器可支持的平台广泛,
目前
包括:X64/X86/ARM64/ARM32/MIPS/Alpha等硬件平台,以及Linux/Win64/Win32等开发环境。对照矩阵如下:
目前TDengine的连接器可支持的平台广泛,包括:X64/X86/ARM64/ARM32/MIPS/Alpha等硬件平台,以及Linux/Win64/Win32等开发环境。对照矩阵如下:
|
**CPU**
|
**X64 64bit**
|
**X64 64bit**
|
**X64 64bit**
|
**X86 32bit**
|
**ARM64**
|
**ARM32**
|
**MIPS 龙芯**
|
**Alpha 申威**
|
**X64 海光**
|
| ----------- | --------------- | --------------- | --------------- | --------------- | --------- | --------- | --------------- | ---------------- | -------------- |
|
**OS**
|
**Linux**
|
**Win64**
|
**Win32**
|
**Win32**
|
**Linux**
|
**Linux**
|
**Linux**
|
**Linux**
|
**Linux**
|
|
**C/C++**
| ● | ● | ● | ○ | ● | ● |
● | ● | ●
|
|
**JDBC**
| ● | ● | ● | ○ | ● | ● |
● | ● | ●
|
|
**Python**
| ● | ● | ● | ○ | ● | ● |
● | -- | ●
|
|
**C/C++**
| ● | ● | ● | ○ | ● | ● |
○ | ○ | ○
|
|
**JDBC**
| ● | ● | ● | ○ | ● | ● |
○ | ○ | ○
|
|
**Python**
| ● | ● | ● | ○ | ● | ● |
○ | -- | ○
|
|
**Go**
| ● | ● | ● | ○ | ● | ● | ○ | -- | -- |
|
**NodeJs**
| ● | ● | ○ | ○ | ● | ● | ○ | -- | -- |
|
**C#**
| ○ | ● | ● | ○ | ○ | ○ | ○ | -- | -- |
|
**RESTful**
| ● | ● | ● | ● | ● | ● |
● | ● | ●
|
|
**RESTful**
| ● | ● | ● | ● | ● | ● |
○ | ○ | ○
|
其中 ● 表示经过官方测试验证, ○ 表示非官方测试验证。
注意:
*
在没有安装TDengine服务端软件的系统中使用连接器(除RESTful外)访问 TDengine 数据库,需要安装相应版本的客户端安装包来使应用驱动(Linux系统中文件名为libtaos.so,Windows系统中为taos.dll)被安装在系统中,否则会产生无法找到相应库文件的错误。
*
所有执行 SQL 语句的 API,例如 C/C++ Connector 中的
`tao_query`
、
`taos_query_a`
、
`taos_subscribe`
等,以及其它语言中与它们对应的API,每次都只能执行一条 SQL 语句,如果实际参数中包含了多条语句,它们的行为是未定义的。
*
升级到TDengine到2.0.8.0版本的用户,必须更新JDBC连接TDengine必须升级taos-jdbcdriver到2.0.12及以上。
## 安装连接器驱动步骤
服务器应该已经安装TDengine服务端安装包。连接器驱动安装步骤如下:
**Linux**
**1. 从涛思官网(https://www.taosdata.com/cn/all-downloads/)下载**
*
X64硬件环境:TDengine-client-2.x.x.x-Linux-x64.tar.gz
*
ARM64硬件环境:TDengine-client-2.x.x.x-Linux-aarch64.tar.gz
*
ARM32硬件环境:TDengine-client-2.x.x.x-Linux-aarch32.tar.gz
**2. 解压缩软件包**
将软件包放置在当前用户可读写的任意目录下,然后执行下面的命令:
`tar -xzvf TDengine-client-xxxxxxxxx.tar.gz`
其中xxxxxxx需要替换为实际版本的字符串。
**3. 执行安装脚本**
解压软件包之后,会在解压目录下看到以下文件(目录):
*install_client.sh*
:安装脚本,用于应用驱动程序
*taos.tar.gz*
:应用驱动安装包
*driver*
:TDengine应用驱动driver
*connector*
: 各种编程语言连接器(go/grafanaplugin/nodejs/python/JDBC)
*examples*
: 各种编程语言的示例程序(c/C#/go/JDBC/matlab/python/R)
运行install_client.sh进行安装
**4. 配置taos.cfg**
编辑taos.cfg文件(默认路径/etc/taos/taos.cfg),将firstEP修改为TDengine服务器的End Point,例如:h1.taos.com:6030
**提示: 如本机没有部署TDengine服务,仅安装了应用驱动,则taos.cfg中仅需配置firstEP,无需配置FQDN。**
**Windows x64/x86**
**1. 从涛思官网(https://www.taosdata.com/cn/all-downloads/)下载 :**
*
X64硬件环境:TDengine-client-2.X.X.X-Windows-x64.exe
*
X86硬件环境:TDengine-client-2.X.X.X-Windows-x86.exe
**2. 执行安装程序,按提示选择默认值,完成安装**
**3. 安装路径**
默认安装路径为:C:
\T
Dengine,其中包括以下文件(目录):
*taos.exe*
:taos shell命令行程序
*cfg*
: 配置文件目录
*driver*
: 应用驱动动态链接库
*examples*
: 示例程序 bash/C/C#/go/JDBC/Python/Node.js
*include*
: 头文件
*log*
: 日志文件
*unins000.exe*
: 卸载程序
**4. 配置taos.cfg**
编辑taos.cfg文件(默认路径C:
\T
Dengine
\c
fg
\t
aos.cfg),将firstEP修改为TDengine服务器的End Point,例如:h1.taos.com:6030
**提示:**
**1. 如利用FQDN连接服务器,必须确认本机网络环境DNS已配置好,或在hosts文件中添加FQDN寻址记录,如编辑C:\Windows\system32\drivers\etc\hosts,添加如下的记录:**
**192.168.1.99 h1.taos.com**
**2.卸载:运行unins000.exe可卸载TDengine应用驱动。**
**安装验证**
以上安装和配置完成后,并确认TDengine服务已经正常启动运行,此时可以执行taos客户端进行登录。
**Linux环境:**
在linux shell下直接执行 taos,应该就能正常链接到tdegine服务,进入到taos shell界面,示例如下:
```
mysql
$ taos
Welcome to the TDengine shell from Linux, Client Version:2.0.5.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos> show databases;
name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB)| blocks | minrows | maxrows | wallevel | fsync | comp | precision | status |
=========================================================================================================================================================================================================================
test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16| 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready |
log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1| 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready |
Query OK, 2 row(s) in set (0.001198s)
taos>
```
**Windows(x64/x86)环境:**
在cmd下进入到c:
\T
Dengine目录下直接执行 taos.exe,应该就能正常链接到tdegine服务,进入到taos shell界面,示例如下:
```
mysql
C:\TDengine>taos
Welcome to the TDengine shell from Linux, Client Version:2.0.5.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos> show databases;
name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status |
===================================================================================================================================================================================================================================================================
test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready |
log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready |
Query OK, 2 row(s) in set (0.045000s)
taos>
```
## C/C++ Connector
**C/C++连接器支持的系统有**
:
|
**CPU类型**
| x64(64bit) | | | ARM64 | ARM32 |
| ------------ | ------------ | -------- | -------- | -------- | ---------- |
|
**OS类型**
| Linux | Win64 | Win32 | Linux | Linux |
|
**支持与否**
|
**支持**
|
**支持**
|
**支持**
|
**支持**
|
**开发中**
|
C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine头文件 _taos.h_(安装后,位于 _/usr/local/taos/include_):
```
C
#include <taos.h>
```
在编译时需要链接TDengine动态库 _libtaos.so_ (安装后,位于 _/usr/local/taos/driver_,gcc编译时,请加上 -ltaos)。
注意:
如未特别说明,当API的返回值是整数时,_0_ 代表成功,其它是代表失败原因的错误码,当返回值是指针时, _NULL_ 表示失败。
*
在编译时需要链接TDengine动态库。Linux 为
*libtaos.so*
,安装后,位于 _/usr/local/taos/driver_。Windows为 taos.dll,安装后位于
*C:\TDengine*
。
*
如未特别说明,当API的返回值是整数时,_0_ 代表成功,其它是代表失败原因的错误码,当返回值是指针时, _NULL_ 表示失败。
使用C/C++连接器的示例代码请参见 https://github.com/taosdata/TDengine/tree/develop/tests/examples/c。
### 基础API
...
...
@@ -45,22 +166,18 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
初始化运行环境。如果应用没有主动调用该API,那么应用在调用
`taos_connect`
时将自动调用,故应用程序一般无需手动调用该API。
-
`void taos_cleanup()`
清理运行环境,应用退出前应调用此API。
-
`int taos_options(TSDB_OPTION option, const void * arg, ...)`
设置客户端选项,目前只支持时区设置(_TSDB_OPTION_TIMEZONE_)和编码设置(_TSDB_OPTION_LOCALE_)。时区和编码默认为操作系统当前设置。
-
`char *taos_get_client_info()`
获取客户端版本信息。
-
`TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, int port)`
创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含:
...
...
@@ -73,23 +190,18 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。
-
`char *taos_get_server_info(TAOS *taos)`
获取服务端版本信息。
-
`int taos_select_db(TAOS *taos, const char *db)`
将当前的缺省数据库设置为
`db`
。
-
`void taos_close(TAOS *taos)`
关闭连接, 其中
`taos`
是
`taos_connect`
函数返回的指针。
### 同步查询API
传统的数据库操作API,都属于同步操作。应用调用API后,一直处于阻塞状态,直到服务器返回结果。TDengine支持如下API:
...
...
@@ -98,37 +210,30 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
该API用来执行SQL语句,可以是DQL、DML或DDL语句。 其中的
`taos`
参数是通过
`taos_connect`
获得的指针。返回值 NULL 表示失败。
-
`int taos_result_precision(TAOS_RES *res)`
返回结果集时间戳字段的精度,
`0`
代表毫秒,
`1`
代表微秒,
`2`
代表纳秒。
-
`TAOS_ROW taos_fetch_row(TAOS_RES *res)`
按行获取查询结果集中的数据。
-
`int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)`
批量获取查询结果集中的数据,返回值为获取到的数据的行数。
-
`int taos_num_fields(TAOS_RES *res)`
和
`int taos_field_count(TAOS_RES *res)`
这两个API等价,用于获取查询结果集中的列数。
-
`int* taos_fetch_lengths(TAOS_RES *res)`
获取结果集中每个字段的长度。 返回值是一个数组,其长度为结果集的列数。
-
`int taos_affected_rows(TAOS_RES *res)`
获取被所执行的 SQL 语句影响的行数。
-
`TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)`
获取查询结果集每列数据的属性(数据类型、名字、字节数),与taos_num_fileds配合使用,可用来解析
`taos_fetch_row`
返回的一个元组(一行)的数据。
`TAOS_FIELD`
的结构如下:
...
...
@@ -141,30 +246,24 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
}
TAOS_FIELD
;
```
-
`void taos_stop_query(TAOS_RES *res)`
停止一个查询的执行。
-
`void taos_free_result(TAOS_RES *res)`
释放查询结果集以及相关的资源。查询完成后,务必调用该API释放资源,否则可能导致应用内存泄露。
-
`char *taos_errstr(TAOS_RES *res)`
获取最近一次API调用失败的原因,返回值为字符串。
-
`char *taos_errno(TAOS_RES *res)`
获取最近一次API调用失败的原因,返回值为错误代码。
**注意**
:对于每个数据库应用,2.0及以上版本 TDengine 推荐只建立一个连接。同时在应用中将该连接 (TAOS
*
) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性。C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。
### 异步查询API
同步API之外,TDengine还提供性能更高的异步调用API处理数据插入、查询操作。在软硬件环境相同的情况下,异步API处理数据插入的速度比同步API快2~4倍。异步API采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步API在网络延迟严重的情况下,优点尤为突出。
...
...
@@ -189,7 +288,6 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
*
res:
`taos_query_a`
回调时返回的结果集
*
fp:回调函数。其参数
`param`
是用户可定义的传递给回调函数的参数结构体;
`numOfRows`
是获取到的数据的行数(不是整个查询结果集的函数)。 在回调函数中,应用可以通过调用
`taos_fetch_row`
前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用
`taos_fetch_rows_a`
获取下一批记录进行处理,直到返回的记录数(numOfRows)为零(结果返回完成)或记录数为负值(查询出错)。
-
`void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), void *param);`
异步获取一条记录。其中:
...
...
@@ -199,7 +297,6 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,
**客户端应用必须确保对同一张表的操作完全串行化**
,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。
### 参数绑定API
除了直接调用
`taos_query`
进行查询,TDengine也提供了支持参数绑定的Prepare API,与 MySQL 一样,这些API目前也仅支持用问号
`?`
来代表待绑定的参数,具体如下:
...
...
@@ -244,7 +341,6 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线
执行完毕,释放所有资源。
### 连续查询接口
TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时间段,对一张或多张数据库的表(数据流)进行各种实时聚合计算操作。操作简单,仅有打开、关闭流的API。具体如下:
...
...
@@ -261,12 +357,10 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
返回值为NULL,表示创建成功,返回值不为空,表示成功。
-
`void taos_close_stream (TAOS_STREAM *tstr)`
关闭数据流,其中提供的参数是taos_open_stream的返回值。用户停止流式计算的时候,务必关闭该数据流。
### 数据订阅接口
订阅API目前支持订阅一张或多张表,并通过定期轮询的方式不断获取写入表中的最新数据。
...
...
@@ -290,7 +384,6 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
*
param:调用
`taos_subscribe`
时客户程序提供的附加参数
*
code:错误码
*
`TAOS_RES *taos_consume(TAOS_SUB *tsub)`
同步模式下,该函数用来获取订阅的结果。 用户应用程序将其置于一个循环之中。 如两次调用
`taos_consume`
的间隔小于订阅的轮询周期,API将会阻塞,直到时间间隔超过此周期。 如果数据库有新记录到达,该API将返回该最新的记录,否则返回一个没有记录的空结果集。 如果返回值为
`NULL`
,说明系统出错。 异步模式下,用户程序不应调用此API。
...
...
@@ -299,11 +392,10 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
取消订阅。 如参数
`keepProgress`
不为0,API会保留订阅的进度信息,后续调用
`taos_subscribe`
时可以基于此进度继续;否则将删除进度信息,后续只能重新开始读取数据。
## Python Connector
### 安装准备
*
已安装TDengine, 如果客户端在Windows上,需要安装Windows 版本的TDengine客户端
[
(Windows TDengine 客户端安装)
][
4
]
*
应用驱动安装请参考
<a
href=
"https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤"
>
安装连接器驱动步骤
</a>
。
*
已安装python 2.7 or >= 3.4
*
已安装pip 或 pip3
...
...
@@ -323,12 +415,12 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
在已安装Windows TDengine 客户端的情况下, 将文件"C:
\T
Dengine
\d
river
\t
aos.dll" 拷贝到 "C:
\w
indows
\s
ystem32" 目录下, 然后进入Windwos
<em>
cmd
</em>
命令行界面
```
cmd
cd C:\TDengine\connector\python\windows
pip install python2\
p
ython -m p
ip install python2\
```
或
```
cmd
cd C:\TDengine\connector\python\windows
pip install python3\
p
ython -m p
ip install python3\
```
*
如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。
...
...
@@ -407,7 +499,6 @@ for d in data:
sub
.
close
()
```
*
关闭连接
```
python
c1
.
close
()
...
...
@@ -431,7 +522,6 @@ conn.close()
用于生成taos.TDengineConnection的实例。
### Python客户端使用示例代码
在tests/examples/python中,我们提供了一个示例Python程序read_example.py,可以参考这个程序来设计用户自己的写入、查询程序。在安装了对应的客户端后,通过import taos引入taos类。主要步骤如下
...
...
@@ -638,31 +728,39 @@ HTTP请求URL采用`sqlutc`时,返回结果集的时间戳将采用UTC时间
## CSharp Connector
在Windows系统上,C#应用程序可以使用TDengine的原生C接口来执行所有数据库操作,后续版本将提供ORM(dapper)框架驱动。
C#连接器支持的系统有:Linux 64/Windows x64/Windows x86
###
# 安装TDengine客户端
###
安装准备
C#连接器需要使用
`libtaos.so`
和
`taos.h`
。因此,在使用C#连接器之前,需在程序运行的Windows环境安装TDengine的Windows客户端,以便获得相关驱动文件。
*
应用驱动安装请参考
<a
href=
"https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤"
>
安装连接器驱动步骤
</a>
。
*
.NET接口文件TDengineDrivercs.cs和参考程序示例TDengineTest.cs均位于Windows客户端install_directory/examples/C#目录下。
*
在Windows系统上,C#应用程序可以使用TDengine的原生C接口来执行所有数据库操作,后续版本将提供ORM(dapper)框架驱动。
安装完成后,在文件夹
`C:/TDengine/examples/C#`
中,将会看到两个文件
### 安装验证
-
TDengineDriver.cs 调用taos.dll文件的Native C方法
-
TDengineTest.cs 参考程序示例
运行install_directory/examples/C#/C#Checker/C#Checker.exe
在文件夹
`C:\Windows\System32`
,将会看到
`taos.dll`
文件
```
cmd
cd {install_directory}/examples/C#/C#Checker
csc /optimize *.cs
C#Checker.exe -h <fqdn>
```
### C#连接器的使用
在Windows系统上,.NET应用程序可以使用TDengine的.NET接口来执行所有数据库的操作。使用.NET接口的步骤如下所示:
#### 使用方法
1.
将.NET接口文件TDengineDrivercs.cs加入到应用程序所在.NET项目中。
2.
用户可以参考TDengineTest.cs来定义数据库连接参数,以及如何执行数据插入、查询等操作;
-
将C#接口文件TDengineDriver.cs加入到应用程序所在.NET项目中
-
参考TDengineTest.cs来定义数据库连接参数,及执行数据插入、查询等操作的方法
-
因为C#接口需要用到
`taos.dll`
文件,用户可以将
`taos.dll`
文件加入.NET解决方案中
此.NET接口需要用到taos.dll文件,所以在执行应用程序前,拷贝Windows客户端install_directory/driver目录中的taos.dll文件到.NET项目最后生成.exe可执行文件所在文件夹。之后运行exe文件,即可访问TDengine数据库并做插入、查询等操作。
#### 注意事项
**注意:**
-
`taos.dll`
文件使用x64平台编译,所以.NET项目在生成.exe文件时,“解决方案”/“项目”的“平台”请均选择
“x64”。
-
此.NET接口目前已经在Visual Studio 2013/
2015/2017中验证过,其它VS版本尚待验证。
1.
TDengine V2.0.3.0之后同时支持32位和64位Windows系统,所以.NET项目在生成.exe文件时,“解决方案”/“项目”的“平台”请选择对应的“X86” 或
“x64”。
2.
此.NET接口目前已经在Visual Studio
2015/2017中验证过,其它VS版本尚待验证。
###
#
第三方驱动
### 第三方驱动
Maikebing.Data.Taos是一个TDengine的ADO.Net提供器,支持linux,windows。该开发包由热心贡献者
`麦壳饼@@maikebing`
提供,具体请参考
...
...
@@ -673,10 +771,15 @@ https://github.com/maikebing/Maikebing.EntityFrameworkCore.Taos
https://www.taosdata.com/blog/2020/11/02/1901.html
```
## Go Connector
TDengine提供了GO驱动程序
`taosSql`
.
`taosSql`
实现了GO语言的内置接口
`database/sql/driver`
。用户只需按如下方式引入包就可以在应用程序中访问TDengine, 详见
`https://github.com/taosdata/driver-go/blob/develop/taosSql/driver_test.go`
### 安装准备
*
应用驱动安装请参考
<a
href=
"https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤"
>
安装连接器驱动步骤
</a>
。
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
import (
...
...
@@ -684,9 +787,9 @@ import (
_ "github.com/taosdata/driver-go/taosSql"
)
```
**建议
Go版本是
1.13或以上,并开启模块支持:**
**建议
使用Go版本
1.13或以上,并开启模块支持:**
```
```
bash
go
env
-w
GO111MODULE
=
on
go
env
-w
GOPROXY
=
https://goproxy.io,direct
```
...
...
@@ -725,48 +828,86 @@ go env -w GOPROXY=https://goproxy.io,direct
## Node.js Connector
TDengine 同时也提供了node.js 的连接器。用户可以通过[npm](https://www.npmjs.com/)来进行安装,也可以通过源代码*src/connector/nodejs/* 来进行安装。[具体安装步骤如下](https://github.com/taosdata/tdengine/tree/master/src/connector/nodejs):
Node.js连接器支持的系统有:
| **CPU类型** | x64(64bit) | | | aarch64 | aarch32 |
| ------------ | ------------ | -------- | -------- | -------- | -------- |
| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
| **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** |
### 安装准备
* 应用驱动安装请参考<a href="https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤">安装连接器驱动步骤</a>。
首先,通过[npm](https://www.npmjs.com/)安装node.js 连接器.
### 安装Node.js连接器
用户可以通过<a href="https://www.npmjs.com/">npm</a>来进行安装,也可以通过源代码*src/connector/nodejs/* 来进行安装。具体安装步骤如下:
首先,通过<a href="https://www.npmjs.com/">npm</a>安装node.js 连接器.
```bash
npm install td2.0-connector
```
我们建议用户使用npm 安装node.js连接器。如果您没有安装npm, 可以将*src/connector/nodejs/*拷贝到您的nodejs 项目目录下
我们使用
[node-gyp](https://github.com/nodejs/node-gyp)
和TDengine服务端进行交互。安装node.js 连接器之前,还需安装以下软件:
我们使用
<a href="https://github.com/nodejs/node-gyp">node-gyp</a>
和TDengine服务端进行交互。安装node.js 连接器之前,还需安装以下软件:
### Linux
- `
python
` (建议`
v2.7
` , `
v3.x.x
` 目前还不支持)
- `
node
` 必须采用v10.x版本,其他版本存在包兼容性的问题。
- `
make
`
- c语言编译器比如
[GCC](https://gcc.gnu.org)
- c语言编译器比如
<a href="https://gcc.gnu.org">GCC</a>
### Windows
#### 安装方法1
使用微软的
[windows-build-tools](https://github.com/felixrieseberg/windows-build-tools)
在`
cmd
` 命令行界面执行`
npm install --global --production windows-build-tools
` 即可安装所有的必备工具
使用微软的
<a href="https://github.com/felixrieseberg/windows-build-tools">windows-build-tools</a>
在`
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 2.7](https://www.python.org/downloads/)
(`
v3.x.x
` 暂不支持) 并执行 `
npm config set python python2.7
`
- 安装Visual Studio相关:
<a href="https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools>Visual Studio Build 工具</a> 或者 <a href="https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community">Visual Studio 2017 Community</a>
- 安装
<a href="https://www.python.org/downloads/">Python</a> 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用户手册
<a href="https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules">Microsoft's Node.js Guidelines for Windows</a>
如果在Windows 10 ARM 上使用ARM64 Node.js, 还需添加 "Visual C++ compilers and libraries for ARM64" 和 "Visual C++ ATL for ARM64".
### 使用方法
### 示例程序
示例程序源码位于install_directory/examples/nodejs,有:
Node-example.js node.js示例源程序
Node-example-raw.js
### 安装验证
在安装好TDengine客户端后,使用nodejsChecker.js程序能够验证当前环境是否支持nodejs方式访问Tdengine。
验证方法:
1. 新建安装验证目录,例如:~/tdengine-test,拷贝github上nodejsChecker.js源程序。下载地址:(https://github.com/taosdata/TDengine/tree/develop/tests/examples/nodejs/nodejsChecker.js)。
2. 在命令中执行以下命令:
```bash
npm init -y
npm install td2.0-connector
node nodejsChecker.js host=localhost
```
3. 执行以上步骤后,在命令行会输出nodejs连接Tdengine实例,并执行简答插入和查询的结果。
### Node.js连接器的使用
(http://docs.taosdata.com/node)
以下是node.js 连接器的一些基本使用方法,详细的使用方法可参考
[该文档](http://docs.taosdata.com/node)
以下是node.js 连接器的一些基本使用方法,详细的使用方法可参考
<a href="http://docs.taosdata.com/node">该文档</a>
#### 连接
####
建立
连接
使用node.js连接器时,必须先<em>require</em> ```td2.0-connector```,然后使用 ```taos.connect``` 函数。```taos.connect``` 函数必须提供的参数是```host```,其它参数在没有提供的情况下会使用如下的默认值。最后需要初始化```cursor``` 来和TDengine服务端通信
...
...
@@ -782,6 +923,26 @@ var cursor = conn.cursor(); // Initializing a new cursor
conn.close();
```
#### 执行SQL和插入数据
对于DDL语句(例如create database、create table、use等),可以使用cursor的execute方法。代码如下:
```js
cursor.execute('create database if not exists test;')
```
以上代码创建了一个名称为test的数据库。对于DDL语句,一般没有返回值,cursor的execute返回值为0。
对于Insert语句,代码如下:
```js
var affectRows = cursor.execute('insert into test.weather values(now, 22.3, 34);')
```
execute方法的返回值为该语句影响的行数,上面的sql向test库的weather表中,插入了一条数据,则返回值affectRows为1。
TDengine目前还不支持update和delete语句。
#### 查询
可通过 ```cursor.query``` 函数来查询数据库。
...
...
@@ -808,7 +969,6 @@ query.execute().then(function(result) {
```
如果在```query```语句里提供第二个参数并设为```true```也可以立即获取查询结果。如下:
```javascript
var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true)
promise.then(function(result) {
...
...
@@ -828,12 +988,7 @@ promise2.then(function(result) {
})
```
### 示例
[这里](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js)提供了一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例
[这里](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js)同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`
cursor
`
.
[
4
]:
https://www.taosdata.com/cn/all-downloads/#TDengine-Windows-Client
<a href="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js">这里</a>提供了一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例
<a href="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js">这里</a>同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`
cursor
`
.
\ No newline at end of file
documentation20/webdocs/markdowndocs/connector-java-ch.md
浏览文件 @
d1bd4b12
# Java Connector
Java连接器支持的系统有: Linux 64/Windows x64/Windows x86。
Java连接器支持的系统有:
|
**CPU类型**
| x64(64bit) | | | ARM64 | ARM32 |
| ------------ | ------------ | -------- | -------- | -------- | -------- |
|
**OS类型**
| Linux | Win64 | Win32 | Linux | Linux |
|
**支持与否**
|
**支持**
|
**支持**
|
**支持**
|
**支持**
|
**支持**
|
TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的
`taos-jdbcdriver`
实现。目前可以通过
[
Sonatype Repository
][
1
]
搜索并下载。
...
...
@@ -21,7 +25,6 @@ TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一
*
目前不支持表间的 union 操作。
*
目前不支持嵌套查询(nested query),对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver 则会自动关闭上一个 ResultSet。
## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
...
...
@@ -70,7 +73,6 @@ maven 项目中使用如下 pom.xml 配置即可:
下载
[
TDengine
][
3
]
源码之后,进入 taos-jdbcdriver 源码目录
`src/connector/jdbc`
执行
`mvn clean package`
即可生成相应 jar 包。
## 使用说明
### 获取连接
...
...
@@ -212,7 +214,6 @@ while(resultSet.next()){
```
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
### 订阅
#### 创建
...
...
@@ -227,7 +228,7 @@ TSDBSubscribe sub = ((TSDBConnection)conn).subscribe("topic", "select * from met
*
sql:订阅的查询语句,此语句只能是
`select`
语句,只应查询原始数据,只能按时间正序查询数据
*
restart:如果订阅已经存在,是重新开始,还是继续之前的订阅
如上面的例子将使用 SQL 语句
`select * from meters`
创建一个名为
`topic
'
的订阅,如果这个订阅已经存在,将继续之前的查询进度,而不是从头开始消费所有的数据。
如上面的例子将使用 SQL 语句
`select * from meters`
创建一个名为
`topic
`
的订阅,如果这个订阅已经存在,将继续之前的查询进度,而不是从头开始消费所有的数据。
#### 消费数据
...
...
@@ -255,7 +256,6 @@ sub.close(true);
`close`
方法关闭一个订阅。如果其参数为
`true`
表示保留订阅进度信息,后续可以创建同名订阅继续消费数据;如为
`false`
则不保留订阅进度。
### 关闭资源
```
java
...
...
documentation20/webdocs/markdowndocs/faq-ch.md
浏览文件 @
d1bd4b12
...
...
@@ -32,7 +32,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配置参考:
<a
href=
"https://www.taosdata.com/blog/2020/09/11/1824.html"
>
一篇文章说清楚TDengine的FQDN
</a>
。
5.
ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件
...
...
@@ -51,19 +51,16 @@
*
Windows 系统请使用 PowerShell 命令 Net-TestConnection -ComputerName {fqdn} -Port {port} 检测服务段端口是否访问
10.
也可以使用taos程序内嵌的网络连通检测功能,来验证服务器和客户端之间指定的端口连接是否通畅(包括TCP和UDP):
[
TDengine 内嵌网络检测工具使用指南
](
https://www.taosdata.com/blog/2020/09/08/1816.html
)
。
10.
也可以使用taos程序内嵌的网络连通检测功能,来验证服务器和客户端之间指定的端口连接是否通畅(包括TCP和UDP):
<a
href=
"https://www.taosdata.com/blog/2020/09/08/1816.html"
>
TDengine 内嵌网络检测工具使用指南
</a>
。
## 6. 遇到错误“Unexpected generic error in RPC”或者"TDengine Error: Unable to resolve FQDN", 我怎么办?
产生这个错误,是由于客户端或数据节点无法解析FQDN(Fully Qualified Domain Name)导致。对于TAOS Shell或客户端应用,请做如下检查:
1.
请检查连接的服务器的FQDN是否正确,FQDN配置参考:
[
一篇文章说清楚TDengine的FQDN
](
https://www.taosdata.com/blog/2020/09/11/1824.html
)
。
1.
请检查连接的服务器的FQDN是否正确,FQDN配置参考:
<a
href=
"https://www.taosdata.com/blog/2020/09/11/1824.html"
>
一篇文章说清楚TDengine的FQDN
</a>
。
2.
如果网络配置有DNS server, 请检查是否正常工作
3.
如果网络没有配置DNS server, 请检查客户端所在机器的hosts文件,查看该FQDN是否配置,并是否有正确的IP地址。
4.
如果网络配置OK,从客户端所在机器,你需要能Ping该连接的FQDN,否则客户端是无法连接服务器的
## 7. 虽然语法正确,为什么我还是得到 "Invalid SQL" 错误
如果你确认语法正确,2.0之前版本,请检查SQL语句长度是否超过64K。如果超过,也会返回这个错误。
...
...
@@ -86,7 +83,7 @@ TDengine还没有一组专用的validation queries。然而建议你使用系统
## 11. 最有效的写入数据的方法是什么?windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决?
w
indows下插入nchar类的数据中如果有中文,请先确认系统的地区设置成了中国(在Control Panel里可以设置),这时cmd中的
`taos`
客户端应该已经可以正常工作了;如果是在IDE里开发Java应用,比如Eclipse, Intellij,请确认IDE里的文件编码为GBK(这是Java默认的编码类型),然后在生成Connection时,初始化客户端的配置,具体语句如下:
W
indows下插入nchar类的数据中如果有中文,请先确认系统的地区设置成了中国(在Control Panel里可以设置),这时cmd中的
`taos`
客户端应该已经可以正常工作了;如果是在IDE里开发Java应用,比如Eclipse, Intellij,请确认IDE里的文件编码为GBK(这是Java默认的编码类型),然后在生成Connection时,初始化客户端的配置,具体语句如下:
```
JAVA
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties();
...
...
@@ -94,7 +91,7 @@ properties.setProperty(TSDBDriver.LOCALE_KEY, "UTF-8");
Connection = DriverManager.getConnection(url, properties);
```
## 12.TDengine GO windows驱动的如何编译?
请看为此问题撰写的
<a
href=
'blog/2020/01/06/tdengine-go-windows驱动的编译/'
>
技术博客
请看为此问题撰写的
<a
href=
'blog/2020/01/06/tdengine-go-windows驱动的编译/'
>
技术博客
</a>
## 13.JDBC报错: the excuted SQL is not a DML or a DDL?
请更新至最新的JDBC驱动
...
...
@@ -109,14 +106,10 @@ Connection = DriverManager.getConnection(url, properties);
常见原因是服务器和客户端时间没有校准,可以通过和时间服务器同步的方式(Linux 下使用 ntpdate 命令,Windows 在系统时间设置中选择自动同步)校准。
## 15. 表名显示不全
由于 taos shell 在终端中显示宽度有限,有可能比较长的表名显示不全,如果按照显示的不全的表名进行相关操作会发生 Table does not exist 错误。解决方法可以是通过修改 taos.cfg 文件中的设置项 maxBinaryDisplayWidth, 或者直接输入命令 set max_binary_display_width 100。或者在命令结尾使用
\G
参数来调整结果的显示方式。
## 16. 如何进行数据迁移?
TDengine是根据hostname唯一标志一台机器的,在数据文件从机器A移动机器B时,注意如下两件事:
...
...
@@ -125,11 +118,9 @@ TDengine是根据hostname唯一标志一台机器的,在数据文件从机器A
-
2.0.7.0 及以后的版本,到/var/lib/taos/dnode下,修复dnodeEps.json的dnodeId对应的FQDN,重启。确保机器内所有机器的此文件是完全相同的。
-
1.x 和 2.x 版本的存储结构不兼容,需要使用迁移工具或者自己开发应用导出导入数据。
## 17. 怎么报告问题?
如果 FAQ 中的信息不能够帮到您,需要 TDengine 技术团队的技术支持与协助,请将以下两个目录中内容打包
:
如果 FAQ 中的信息不能够帮到您,需要 TDengine 技术团队的技术支持与协助,请将以下两个目录中内容打包
:
1.
/var/log/taos
2.
/etc/taos
...
...
documentation20/webdocs/markdowndocs/insert-ch.md
浏览文件 @
d1bd4b12
...
...
@@ -28,10 +28,10 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6,
-
写入的数据的时间戳必须大于当前时间减去配置参数keep的时间。如果keep配置为3650天,那么无法写入比3650天还老的数据。写入数据的时间戳也不能大于当前时间加配置参数days。如果days配置为2,那么无法写入比当前时间还晚2天的数据。
## Prometheus直接写入
[
Prometheus
](
https://www.prometheus.io/
)
作为Cloud Native Computing Fundation毕业的项目,在性能监控以及K8S性能监控领域有着非常广泛的应用。TDengine提供一个小工具
[
Bailongma
](
https://github.com/taosdata/Bailongma
)
,只需在Prometheus做简单配置,无需任何代码,就可将Prometheus采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文
[
用Docker容器快速搭建一个Devops监控Demo
](
https://www.taosdata.com/blog/2020/02/03/1189.html
)
即是采用bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。
<a
href=
"https://www.prometheus.io/"
>
Prometheus
</a>
作为Cloud Native Computing Fundation毕业的项目,在性能监控以及K8S性能监控领域有着非常广泛的应用。TDengine提供一个小工具
<a
href=
"https://github.com/taosdata/Bailongma"
>
Bailongma
</a>
,只需在Prometheus做简单配置,无需任何代码,就可将Prometheus采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文
<a
href=
"https://www.taosdata.com/blog/2020/02/03/1189.html"
>
用Docker容器快速搭建一个Devops监控Demo
</a>
即是采用bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。
### 从源代码编译blm_prometheus
用户需要从github下载
[
Bailongma
](
https://github.com/taosdata/Bailongma
)
的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件:
用户需要从github下载
<a
href=
"https://github.com/taosdata/Bailongma"
>
Bailongma
</a>
的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件:
-
Linux操作系统的服务器
-
安装好Golang, 1.10版本以上
-
对应的TDengine版本。因为用到了TDengine的客户端动态链接库,因此需要安装好和服务端相同版本的TDengine程序;比如服务端版本是TDengine 2.0.0, 则在bailongma所在的linux服务器(可以与TDengine在同一台服务器,或者不同服务器)
...
...
@@ -45,10 +45,10 @@ go build
一切正常的情况下,就会在对应的目录下生成一个blm_prometheus的可执行程序。
### 安装Prometheus
通过Prometheus的官网下载安装。
[
下载地址
](
https://prometheus.io/download/
)
通过Prometheus的官网下载安装。
<a
href=
"https://prometheus.io/download/"
>
下载地址
</a>
### 配置Prometheus
参考Prometheus的
[
配置文档
](
https://prometheus.io/docs/prometheus/latest/configuration/configuration/
)
,
在Prometheus的配置文件中的
<remote_write>
部分,增加以下配置
参考Prometheus的
<a
href=
"https://prometheus.io/docs/prometheus/latest/configuration/configuration/"
>
配置文档
</a>
,
在Prometheus的配置文件中的
<remote_write>
部分,增加以下配置
-
url: bailongma API服务提供的URL, 参考下面的blm_prometheus启动示例章节
...
...
@@ -113,10 +113,10 @@ select * from apiserver_request_latencies_bucket;
```
## Telegraf直接写入
[
Telegraf
](
https://www.influxdata.com/time-series-platform/telegraf/
)
是一流行的IT运维数据采集开源工具,TDengine提供一个小工具
[
Bailongma
](
https://github.com/taosdata/Bailongma
)
,只需在Telegraf做简单配置,无需任何代码,就可将Telegraf采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文
[
用Docker容器快速搭建一个Devops监控Demo
](
https://www.taosdata.com/blog/2020/02/03/1189.html
)
即是采用bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。
<a
href=
"https://www.influxdata.com/time-series-platform/telegraf/"
Telegraf
</
a
>
是一流行的IT运维数据采集开源工具,TDengine提供一个小工具
<a
href=
"https://github.com/taosdata/Bailongma"
>
Bailongma
</a>
,只需在Telegraf做简单配置,无需任何代码,就可将Telegraf采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文
<a
href=
"https://www.taosdata.com/blog/2020/02/03/1189.html"
>
用Docker容器快速搭建一个Devops监控Demo
</a>
即是采用bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。
### 从源代码编译blm_telegraf
用户需要从github下载
[
Bailongma
](
https://github.com/taosdata/Bailongma
)
的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件:
用户需要从github下载
<a
href=
"https://github.com/taosdata/Bailongma"
>
Bailongma
</a>
的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件:
-
Linux操作系统的服务器
-
安装好Golang, 1.10版本以上
...
...
@@ -148,7 +148,7 @@ go build
-
hostname: 区分不同采集设备的机器名称,需确保其唯一性
-
metric_batch_size: 100,允许Telegraf每批次写入记录最大数量,增大其数量可以降低Telegraf的请求发送频率。
关于如何使用Telegraf采集数据以及更多有关使用Telegraf的信息,请参考Telegraf官方的
[
文档
](
https://docs.influxdata.com/telegraf/v1.11/
)
。
关于如何使用Telegraf采集数据以及更多有关使用Telegraf的信息,请参考Telegraf官方的
<a
href=
"https://docs.influxdata.com/telegraf/v1.11/"
>
文档
</a>
。
### 启动blm_telegraf程序
blm_telegraf程序有以下选项,在启动blm_telegraf程序时可以通过设定这些选项来设定blm_telegraf的配置。
...
...
@@ -218,15 +218,12 @@ use telegraf;
select * from cpu;
```
MQTT是一流行的物联网数据传输协议,TDengine 可以很方便的接入 MQTT Broker 接受的数据并写入到 TDengine。
## EMQ Broker 直接写入
[
EMQ
](
https://github.com/emqx/emqx
)
是一开源的MQTT Broker软件,无需任何代码,只需要在EMQ Dashboard里使用“规则”做简单配置,即可将MQTT的数据直接写入TDengine。EMQ X 支持通过 发送到 Web 服务 的方式保存数据到 TDengine,也在企业版上提供原生的 TDEngine 驱动实现直接保存。详细使用方法请参考
[
EMQ 官方文档
](
https://docs.emqx.io/broker/latest/cn/rule/rule-example.html#%E4%BF%9D%E5%AD%98%E6%95%B0%E6%8D%AE%E5%88%B0-tdengine
)
。
<a
href=
"https://github.com/emqx/emqx"
>
EMQ
</a>
是一开源的MQTT Broker软件,无需任何代码,只需要在EMQ Dashboard里使用“规则”做简单配置,即可将MQTT的数据直接写入TDengine。EMQ X 支持通过 发送到 Web 服务 的方式保存数据到 TDengine,也在企业版上提供原生的 TDEngine 驱动实现直接保存。详细使用方法请参考
<a
href=
"https://docs.emqx.io/broker/latest/cn/rule/rule-example.html#%E4%BF%9D%E5%AD%98%E6%95%B0%E6%8D%AE%E5%88%B0-tdengine"
>
EMQ 官方文档
</a>
。
## HiveMQ Broker 直接写入
[
HiveMQ
](
https://www.hivemq.com/
)
是一个提供免费个人版和企业版的 MQTT 代理,主要用于企业和新兴的机器到机器M2M通讯和内部传输,满足可伸缩性、易管理和安全特性。HiveMQ 提供了开源的插件开发包。可以通过 HiveMQ extension - TDengine 保存数据到 TDengine。详细使用方法请参考
[
HiveMQ extension - TDengine 说明文档
](
https://github.com/huskar-t/hivemq-tdengine-extension/blob/b62a26ecc164a310104df57691691b237e091c89/README.md
)
。
<a
href=
"https://www.hivemq.com/"
>
HiveMQ
</a>
是一个提供免费个人版和企业版的 MQTT 代理,主要用于企业和新兴的机器到机器M2M通讯和内部传输,满足可伸缩性、易管理和安全特性。HiveMQ 提供了开源的插件开发包。可以通过 HiveMQ extension - TDengine 保存数据到 TDengine。详细使用方法请参考
<a
href=
"https://github.com/huskar-t/hivemq-tdengine-extension/blob/b62a26ecc164a310104df57691691b237e091c89/README.md"
>
HiveMQ extension - TDengine 说明文档
</a>
。
documentation20/webdocs/markdowndocs/replica-ch.md
浏览文件 @
d1bd4b12
...
...
@@ -30,7 +30,7 @@ TDengine里存在vnode, mnode, vnode用来存储时序数据,mnode用来存储
-
master: 具有最新的数据,容许客户端往里写入数据,一个虚拟节点组,至多一个master.
-
slave:与master是同步的,但不容许客户端往里写入数据,根据配置,可以容许客户端对其进行查询。
-
unsynced: 节点处于非同步状态,比如虚拟节点刚启动、或与其他虚拟节点的连接出现故障等。处于该状态时,该虚拟节点既不能提供写入,也不能提供查询服务
-
unsynced: 节点处于非同步状态,比如虚拟节点刚启动、或与其他虚拟节点的连接出现故障等。处于该状态时,该虚拟节点既不能提供写入,也不能提供查询服务
。
-
offline: 由于宕机或网络原因,无法访问到某虚拟节点时,其他虚拟节点将该虚拟节点标为离线。但请注意,该虚拟节点本身的状态可能是unsynced或其他,但不会是离线。
**Quorum:**
...
...
@@ -83,10 +83,10 @@ TDengine采取的是Master-Slave模式进行同步,与流行的RAFT一致性
如果一个虚拟节点(vnode A)检测到与同一虚拟节点组内另外一虚拟节点(vnode B)的连接中断,vnode A将立即把vnode B的role设置为offline。无论是接收到另外一虚拟节点发来的status消息,还是检测与另外一虚拟节点的连接中断,该虚拟节点都将进入状态处理流程。状态处理流程的规则如下:
1.
如果检测到在线的节点数没有超过一半,则将自己的状态设置为unsynced.
2.
如果在线的虚拟节点数超过一半,会检查master节点是否存在,如果存在,则会决定是否将自己状态改为slave或启动数据恢复流程
2.
如果在线的虚拟节点数超过一半,会检查master节点是否存在,如果存在,则会决定是否将自己状态改为slave或启动数据恢复流程
。
3.
如果master不存在,则会检查自己保存的各虚拟节点的状态信息与从另一节点接收到的是否一致,如果一致,说明节点组里状态已经稳定一致,则会触发选举流程。如果不一致,说明状态还没趋于一致,即使master不存在,也不进行选主。由于要求状态信息一致才进行选举,每个虚拟节点根据同样的信息,会选出同一个虚拟节点做master,无需投票表决。
4.
自己的状态是根据规则自己决定并修改的,并不需要其他节点同意,包括成为master。一个节点无权修改其他节点的状态。
5.
如果一个虚拟节点检测到自己或其他虚拟节点的role发生改变,该节点会广播它自己保存的各个虚拟节点的状态信息(role和version)
.
5.
如果一个虚拟节点检测到自己或其他虚拟节点的role发生改变,该节点会广播它自己保存的各个虚拟节点的状态信息(role和version)
。
具体的流程图如下:
...
...
@@ -124,7 +124,7 @@ TDengine采取的是Master-Slave模式进行同步,与流行的RAFT一致性
如果一虚拟节点(vnode B) 处于unsynced状态,master存在(vnode A),而且其版本号比master的低,它将立即启动数据恢复流程。在理解恢复流程时,需要澄清几个关于文件的概念和处理规则。
1.
每个文件(无论是archived data的file还是wal)都有一个index, 这需要应用来维护(vnode里,该index就是fileId
*
3 + 0/1/2, 对应data, head与last三个文件)。如果index为0,表示系统里最老的数据文件。对于m
n
ode里的文件,数量是固定的,对应于acct, user, db, table等文件。
1.
每个文件(无论是archived data的file还是wal)都有一个index, 这需要应用来维护(vnode里,该index就是fileId
*
3 + 0/1/2, 对应data, head与last三个文件)。如果index为0,表示系统里最老的数据文件。对于mode里的文件,数量是固定的,对应于acct, user, db, table等文件。
2.
任何一个数据文件(file)有名字、大小,还有一个magic number。只有文件名、大小与magic number一致时,两个文件才判断是一样的,无需同步。Magic number可以是checksum, 也可以是简单的文件大小。怎么计算magic,换句话说,如何检测数据文件是否有效,完全由应用决定。
3.
文件名的处理有点复杂,因为每台服务器的路径可能不一致。比如node A的TDengine的数据文件存放在 /etc/taos目录下,而node B的数据存放在 /home/jhtao目录下。因此同步模块需要应用在启动一个同步实例时提供一个path,这样两台服务器的绝对路径可以不一样,但仍然可以做对比,做同步。
4.
当sync模块调用回调函数getFileInfo获得数据文件信息时,有如下的规则
...
...
@@ -212,10 +212,10 @@ Arbitrator的程序tarbitrator.c在复制模块的同一目录, 编译整个系
相同之处:
-
三大流程一致:Raft里有Leader election, replication, safety,完全对应TDengine的选举、数据转发、数据恢复三个流程
-
节点状态定义一致:Raft里每个节点有Leader, Follower, Candidate三个状态,TDengine里是Master, Slave, Unsynced, Offline。多了一个offlince, 但本质上是一样的,因为offline是外界看一个节点的状态,但该节点本身是处于master, slave 或unsynced的
-
三大流程一致:Raft里有Leader election, replication, safety,完全对应TDengine的选举、数据转发、数据恢复三个流程
。
-
节点状态定义一致:Raft里每个节点有Leader, Follower, Candidate三个状态,TDengine里是Master, Slave, Unsynced, Offline。多了一个offlince, 但本质上是一样的,因为offline是外界看一个节点的状态,但该节点本身是处于master, slave 或unsynced的
。
-
数据转发流程完全一样,Master(leader)需要等待回复确认。
-
数据恢复流程几乎一样,Raft没有涉及历史数据同步问题,只考虑了WAL数据同步
-
数据恢复流程几乎一样,Raft没有涉及历史数据同步问题,只考虑了WAL数据同步
。
不同之处:
...
...
@@ -226,7 +226,7 @@ Arbitrator的程序tarbitrator.c在复制模块的同一目录, 编译整个系
## Meta Data的数据复制
TDengine里存在时序数据,也存在Meta Data。Meta Data对数据的可靠性要求更高,那么TDengine设计能否满足要求呢?下面做个仔细分析
TDengine里存在时序数据,也存在Meta Data。Meta Data对数据的可靠性要求更高,那么TDengine设计能否满足要求呢?下面做个仔细分析
。
TDengine里Meta Data包括以下:
...
...
snap/snapcraft.yaml
浏览文件 @
d1bd4b12
name
:
tdengine
base
:
core18
version
:
'
2.0.1
0
.0'
version
:
'
2.0.1
1
.0'
icon
:
snap/gui/t-dengine.svg
summary
:
an open-source big data platform designed and optimized for IoT.
description
:
|
...
...
@@ -72,7 +72,7 @@ parts:
-
usr/bin/taosd
-
usr/bin/taos
-
usr/bin/taosdemo
-
usr/lib/libtaos.so.2.0.1
0
.0
-
usr/lib/libtaos.so.2.0.1
1
.0
-
usr/lib/libtaos.so.1
-
usr/lib/libtaos.so
...
...
src/balance/src/bnMain.c
浏览文件 @
d1bd4b12
...
...
@@ -44,7 +44,7 @@ static void bnUnLock() {
static
bool
bnCheckFree
(
SDnodeObj
*
pDnode
)
{
if
(
pDnode
->
status
==
TAOS_DN_STATUS_DROPPING
||
pDnode
->
status
==
TAOS_DN_STATUS_OFFLINE
)
{
mError
(
"dnode:%d, status:%s not available"
,
pDnode
->
dnodeId
,
mnodeGetDnodeStatusStr
(
pDnode
->
status
)
);
mError
(
"dnode:%d, status:%s not available"
,
pDnode
->
dnodeId
,
dnodeStatus
[
pDnode
->
status
]
);
return
false
;
}
...
...
@@ -92,13 +92,12 @@ static void bnDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
}
static
void
bnSwapVnodeGid
(
SVnodeGid
*
pVnodeGid1
,
SVnodeGid
*
pVnodeGid2
)
{
//
SVnodeGid tmp = *pVnodeGid1;
//
*pVnodeGid1 = *pVnodeGid2;
//
*pVnodeGid2 = tmp;
SVnodeGid
tmp
=
*
pVnodeGid1
;
*
pVnodeGid1
=
*
pVnodeGid2
;
*
pVnodeGid2
=
tmp
;
}
int32_t
bnAllocVnodes
(
SVgObj
*
pVgroup
)
{
static
int32_t
randIndex
=
0
;
int32_t
dnode
=
0
;
int32_t
vnodes
=
0
;
...
...
@@ -120,8 +119,7 @@ int32_t bnAllocVnodes(SVgObj *pVgroup) {
break
;
}
else
{
mDebug
(
"dnode:%d, is not selected, status:%s vnodes:%d disk:%fGB role:%d"
,
pDnode
->
dnodeId
,
mnodeGetDnodeStatusStr
(
pDnode
->
status
),
pDnode
->
openVnodes
,
pDnode
->
diskAvailable
,
pDnode
->
alternativeRole
);
dnodeStatus
[
pDnode
->
status
],
pDnode
->
openVnodes
,
pDnode
->
diskAvailable
,
pDnode
->
alternativeRole
);
}
}
}
...
...
@@ -137,7 +135,7 @@ int32_t bnAllocVnodes(SVgObj *pVgroup) {
while
(
1
)
{
pIter
=
mnodeGetNextDnode
(
pIter
,
&
pDnode
);
if
(
pDnode
==
NULL
)
break
;
mDebug
(
"dnode:%d, status:%s vnodes:%d disk:%fGB role:%d"
,
pDnode
->
dnodeId
,
mnodeGetDnodeStatusStr
(
pDnode
->
status
)
,
mDebug
(
"dnode:%d, status:%s vnodes:%d disk:%fGB role:%d"
,
pDnode
->
dnodeId
,
dnodeStatus
[
pDnode
->
status
]
,
pDnode
->
openVnodes
,
pDnode
->
diskAvailable
,
pDnode
->
alternativeRole
);
mnodeDecDnodeRef
(
pDnode
);
}
...
...
@@ -149,36 +147,6 @@ int32_t bnAllocVnodes(SVgObj *pVgroup) {
}
}
/*
* make the choice more random.
* replica 1: no choice
* replica 2: there are 2 combinations
* replica 3 or larger: there are 6 combinations
*/
if
(
pVgroup
->
numOfVnodes
==
1
)
{
}
else
if
(
pVgroup
->
numOfVnodes
==
2
)
{
if
(
randIndex
++
%
2
==
0
)
{
bnSwapVnodeGid
(
pVgroup
->
vnodeGid
,
pVgroup
->
vnodeGid
+
1
);
}
}
else
{
int32_t
randVal
=
randIndex
++
%
6
;
if
(
randVal
==
1
)
{
// 1, 0, 2
bnSwapVnodeGid
(
pVgroup
->
vnodeGid
+
0
,
pVgroup
->
vnodeGid
+
1
);
}
else
if
(
randVal
==
2
)
{
// 1, 2, 0
bnSwapVnodeGid
(
pVgroup
->
vnodeGid
+
0
,
pVgroup
->
vnodeGid
+
1
);
bnSwapVnodeGid
(
pVgroup
->
vnodeGid
+
1
,
pVgroup
->
vnodeGid
+
2
);
}
else
if
(
randVal
==
3
)
{
// 2, 1, 0
bnSwapVnodeGid
(
pVgroup
->
vnodeGid
+
0
,
pVgroup
->
vnodeGid
+
2
);
}
else
if
(
randVal
==
4
)
{
// 2, 0, 1
bnSwapVnodeGid
(
pVgroup
->
vnodeGid
+
0
,
pVgroup
->
vnodeGid
+
2
);
bnSwapVnodeGid
(
pVgroup
->
vnodeGid
+
1
,
pVgroup
->
vnodeGid
+
2
);
}
if
(
randVal
==
5
)
{
// 0, 2, 1
bnSwapVnodeGid
(
pVgroup
->
vnodeGid
+
1
,
pVgroup
->
vnodeGid
+
2
);
}
else
{
}
// 0, 1, 2
}
bnReleaseDnodes
();
bnUnLock
();
return
TSDB_CODE_SUCCESS
;
...
...
@@ -214,44 +182,8 @@ static bool bnCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
static
int32_t
bnRemoveVnode
(
SVgObj
*
pVgroup
)
{
if
(
pVgroup
->
numOfVnodes
<=
1
)
return
-
1
;
SVnodeGid
*
pRmVnode
=
NULL
;
SVnodeGid
*
pSelVnode
=
NULL
;
int32_t
maxScore
=
0
;
for
(
int32_t
i
=
0
;
i
<
pVgroup
->
numOfVnodes
;
++
i
)
{
SVnodeGid
*
pVnode
=
&
(
pVgroup
->
vnodeGid
[
i
]);
SDnodeObj
*
pDnode
=
mnodeGetDnode
(
pVnode
->
dnodeId
);
if
(
pDnode
==
NULL
)
{
mError
(
"vgId:%d, dnode:%d not exist, remove it"
,
pVgroup
->
vgId
,
pVnode
->
dnodeId
);
pRmVnode
=
pVnode
;
break
;
}
if
(
pDnode
->
status
==
TAOS_DN_STATUS_DROPPING
)
{
mDebug
(
"vgId:%d, dnode:%d in dropping state"
,
pVgroup
->
vgId
,
pVnode
->
dnodeId
);
pRmVnode
=
pVnode
;
}
else
if
(
pVnode
->
dnodeId
==
pVgroup
->
lbDnodeId
)
{
mDebug
(
"vgId:%d, dnode:%d in updating state"
,
pVgroup
->
vgId
,
pVnode
->
dnodeId
);
pRmVnode
=
pVnode
;
}
else
{
if
(
pSelVnode
==
NULL
)
{
pSelVnode
=
pVnode
;
maxScore
=
pDnode
->
score
;
}
else
{
if
(
maxScore
<
pDnode
->
score
)
{
pSelVnode
=
pVnode
;
maxScore
=
pDnode
->
score
;
}
}
}
mnodeDecDnodeRef
(
pDnode
);
}
if
(
pRmVnode
!=
NULL
)
{
pSelVnode
=
pRmVnode
;
}
SVnodeGid
*
pSelVnode
=
&
pVgroup
->
vnodeGid
[
pVgroup
->
numOfVnodes
-
1
];
mDebug
(
"vgId:%d, vnode in dnode:%d will be dropped"
,
pVgroup
->
vgId
,
pSelVnode
->
dnodeId
);
if
(
!
bnCheckVgroupReady
(
pVgroup
,
pSelVnode
))
{
mDebug
(
"vgId:%d, is not ready"
,
pVgroup
->
vgId
);
...
...
@@ -275,36 +207,42 @@ static bool bnCheckDnodeInVgroup(SDnodeObj *pDnode, SVgObj *pVgroup) {
return
false
;
}
/**
* desc: add vnode to vgroup, find a new one if dest dnode is null
**/
static
int32_t
bnAddVnode
(
SVgObj
*
pVgroup
,
SDnodeObj
*
pSrcDnode
,
SDnodeObj
*
pDestDnode
)
{
if
(
pDestDnode
==
NULL
)
{
static
SDnodeObj
*
bnGetAvailDnode
(
SVgObj
*
pVgroup
)
{
for
(
int32_t
i
=
0
;
i
<
tsBnDnodes
.
size
;
++
i
)
{
SDnodeObj
*
pDnode
=
tsBnDnodes
.
list
[
i
];
if
(
pDnode
==
pSrcDnode
)
continue
;
if
(
bnCheckDnodeInVgroup
(
pDnode
,
pVgroup
))
continue
;
if
(
!
bnCheckFree
(
pDnode
))
continue
;
pDestDnode
=
pDnode
;
mDebug
(
"vgId:%d, add vnode to dnode:%d"
,
pVgroup
->
vgId
,
pDnode
->
dnodeId
);
break
;
}
return
pDnode
;
}
if
(
pDestDnode
==
NULL
)
{
return
NULL
;
}
static
int32_t
bnAddVnode
(
SVgObj
*
pVgroup
,
SDnodeObj
*
pSrcDnode
,
SDnodeObj
*
pDestDnode
)
{
if
(
pDestDnode
==
NULL
||
pSrcDnode
==
pDestDnode
)
{
return
TSDB_CODE_MND_DNODE_NOT_EXIST
;
}
SVnodeGid
*
pVnodeGid
=
pVgroup
->
vnodeGid
+
pVgroup
->
numOfVnodes
;
pVnodeGid
->
dnodeId
=
pDestDnode
->
dnodeId
;
pVnodeGid
->
pDnode
=
pDestDnode
;
pVgroup
->
numOfVnodes
++
;
SVnodeGid
vnodeGids
[
TSDB_MAX_REPLICA
];
memcpy
(
&
vnodeGids
,
&
pVgroup
->
vnodeGid
,
sizeof
(
SVnodeGid
)
*
TSDB_MAX_REPLICA
);
if
(
pSrcDnode
!=
NULL
)
{
int32_t
numOfVnodes
=
pVgroup
->
numOfVnodes
;
vnodeGids
[
numOfVnodes
].
dnodeId
=
pDestDnode
->
dnodeId
;
vnodeGids
[
numOfVnodes
].
pDnode
=
pDestDnode
;
numOfVnodes
++
;
for
(
int32_t
v
=
0
;
v
<
numOfVnodes
;
++
v
)
{
if
(
pSrcDnode
!=
NULL
&&
pSrcDnode
->
dnodeId
==
vnodeGids
[
v
].
dnodeId
)
{
bnSwapVnodeGid
(
&
vnodeGids
[
v
],
&
vnodeGids
[
numOfVnodes
-
1
]);
pVgroup
->
lbDnodeId
=
pSrcDnode
->
dnodeId
;
break
;
}
}
memcpy
(
&
pVgroup
->
vnodeGid
,
&
vnodeGids
,
sizeof
(
SVnodeGid
)
*
TSDB_MAX_REPLICA
);
pVgroup
->
numOfVnodes
=
numOfVnodes
;
atomic_add_fetch_32
(
&
pDestDnode
->
openVnodes
,
1
);
mnodeUpdateVgroup
(
pVgroup
);
...
...
@@ -315,16 +253,16 @@ static int32_t bnAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj *pDes
static
bool
bnMonitorBalance
()
{
if
(
tsBnDnodes
.
size
<
2
)
return
false
;
mDebug
(
"monitor dnodes for balance, avail:%d"
,
tsBnDnodes
.
size
);
for
(
int32_t
src
=
tsBnDnodes
.
size
-
1
;
src
>=
0
;
--
src
)
{
SDnodeObj
*
pDnode
=
tsBnDnodes
.
list
[
src
];
mDebug
(
"%d-dnode:%d, state:%s, score:%.1f, numOfCores:%d, openVnodes:%d"
,
tsBnDnodes
.
size
-
src
-
1
,
pDnode
->
dnodeId
,
mnodeGetDnodeStatusStr
(
pDnode
->
status
),
pDnode
->
score
,
pDnode
->
numOfCores
,
pDnode
->
openVnodes
);
mDebug
(
"%d-dnode:%d, state:%s, score:%.1f, cores:%d, vnodes:%d"
,
tsBnDnodes
.
size
-
src
-
1
,
pDnode
->
dnodeId
,
dnodeStatus
[
pDnode
->
status
],
pDnode
->
score
,
pDnode
->
numOfCores
,
pDnode
->
openVnodes
);
}
float
scoresDiff
=
tsBnDnodes
.
list
[
tsBnDnodes
.
size
-
1
]
->
score
-
tsBnDnodes
.
list
[
0
]
->
score
;
if
(
scoresDiff
<
0
.
01
)
{
mDebug
(
"all dnodes:%d is already balanced, score
sDiff:%
f"
,
tsBnDnodes
.
size
,
scoresDiff
);
mDebug
(
"all dnodes:%d is already balanced, score
Diff:%.1
f"
,
tsBnDnodes
.
size
,
scoresDiff
);
return
false
;
}
...
...
@@ -412,7 +350,13 @@ static int32_t bnMonitorVgroups() {
}
else
if
(
vgReplica
<
dbReplica
)
{
mInfo
(
"vgId:%d, replica:%d numOfVnodes:%d, try add one vnode"
,
pVgroup
->
vgId
,
dbReplica
,
vgReplica
);
hasUpdatingVgroup
=
true
;
code
=
bnAddVnode
(
pVgroup
,
NULL
,
NULL
);
SDnodeObj
*
pAvailDnode
=
bnGetAvailDnode
(
pVgroup
);
if
(
pAvailDnode
==
NULL
)
{
code
=
TSDB_CODE_MND_DNODE_NOT_EXIST
;
}
else
{
code
=
bnAddVnode
(
pVgroup
,
NULL
,
pAvailDnode
);
}
}
mnodeDecVgroupRef
(
pVgroup
);
...
...
src/balance/src/bnScore.c
浏览文件 @
d1bd4b12
...
...
@@ -299,7 +299,7 @@ static int32_t bnRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void
cols
++
;
pWrite
=
data
+
pShow
->
offset
[
cols
]
*
rows
+
pShow
->
bytes
[
cols
]
*
numOfRows
;
STR_TO_VARSTR
(
pWrite
,
mnodeGetDnodeStatusStr
(
pDnode
->
status
)
);
STR_TO_VARSTR
(
pWrite
,
dnodeStatus
[
pDnode
->
status
]
);
cols
++
;
numOfRows
++
;
...
...
src/client/src/tscServer.c
浏览文件 @
d1bd4b12
...
...
@@ -326,7 +326,9 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
rpcMsg
->
code
==
TSDB_CODE_VND_INVALID_VGROUP_ID
||
rpcMsg
->
code
==
TSDB_CODE_RPC_NETWORK_UNAVAIL
||
rpcMsg
->
code
==
TSDB_CODE_APP_NOT_READY
))
{
tscWarn
(
"%p it shall renew table meta, code:%s, retry:%d"
,
pSql
,
tstrerror
(
rpcMsg
->
code
),
++
pSql
->
retry
);
pSql
->
retry
++
;
tscWarn
(
"%p it shall renew table meta, code:%s, retry:%d"
,
pSql
,
tstrerror
(
rpcMsg
->
code
),
pSql
->
retry
);
pSql
->
res
.
code
=
rpcMsg
->
code
;
// keep the previous error code
if
(
pSql
->
retry
>
pSql
->
maxRetry
)
{
...
...
src/client/src/tscSubquery.c
浏览文件 @
d1bd4b12
...
...
@@ -2256,7 +2256,9 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
// in case of insert, redo parsing the sql string and build new submit data block for two reasons:
// 1. the table Id(tid & uid) may have been update, the submit block needs to be updated accordingly.
// 2. vnode may need the schema information along with submit block to update its local table schema.
tscDebug
(
"%p re-parse sql to generate submit data, retry:%d"
,
pParentObj
,
pParentObj
->
retry
++
);
tscDebug
(
"%p re-parse sql to generate submit data, retry:%d"
,
pParentObj
,
pParentObj
->
retry
);
pParentObj
->
retry
++
;
int32_t
code
=
tsParseSql
(
pParentObj
,
true
);
if
(
code
==
TSDB_CODE_TSC_ACTION_IN_PROGRESS
)
return
;
...
...
src/client/src/tscUtil.c
浏览文件 @
d1bd4b12
...
...
@@ -2577,6 +2577,9 @@ void* tscVgroupInfoClear(SVgroupsInfo *vgroupList) {
for
(
int32_t
j
=
0
;
j
<
pVgroupInfo
->
numOfEps
;
++
j
)
{
tfree
(
pVgroupInfo
->
epAddr
[
j
].
fqdn
);
}
for
(
int32_t
j
=
pVgroupInfo
->
numOfEps
;
j
<
TSDB_MAX_REPLICA
;
j
++
)
{
assert
(
pVgroupInfo
->
epAddr
[
j
].
fqdn
==
NULL
);
}
}
tfree
(
vgroupList
);
...
...
src/common/src/tglobal.c
浏览文件 @
d1bd4b12
...
...
@@ -1443,6 +1443,12 @@ int32_t taosCheckGlobalCfg() {
tsNumOfCores
=
1
;
}
if
(
tsMaxTablePerVnode
<
tsMinTablePerVnode
)
{
uError
(
"maxTablesPerVnode(%d) < minTablesPerVnode(%d), reset to minTablesPerVnode(%d)"
,
tsMaxTablePerVnode
,
tsMinTablePerVnode
,
tsMinTablePerVnode
);
tsMaxTablePerVnode
=
tsMinTablePerVnode
;
}
// todo refactor
tsVersion
=
0
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
...
...
src/dnode/src/dnodeTelemetry.c
浏览文件 @
d1bd4b12
...
...
@@ -195,7 +195,7 @@ static void addRuntimeInfo(SBufferWriter* bw) {
static
void
sendTelemetryReport
()
{
char
buf
[
128
];
uint32_t
ip
=
taosGetIpFromFqdn
(
TELEMETRY_SERVER
);
uint32_t
ip
=
taosGetIp
v4
FromFqdn
(
TELEMETRY_SERVER
);
if
(
ip
==
0xffffffff
)
{
dTrace
(
"failed to get IP address of "
TELEMETRY_SERVER
", reason:%s"
,
strerror
(
errno
));
return
;
...
...
src/dnode/src/dnodeVMgmt.c
浏览文件 @
d1bd4b12
...
...
@@ -129,7 +129,8 @@ static void *dnodeProcessMgmtQueue(void *wparam) {
static
SCreateVnodeMsg
*
dnodeParseVnodeMsg
(
SRpcMsg
*
rpcMsg
)
{
SCreateVnodeMsg
*
pCreate
=
rpcMsg
->
pCont
;
pCreate
->
cfg
.
vgId
=
htonl
(
pCreate
->
cfg
.
vgId
);
pCreate
->
cfg
.
cfgVersion
=
htonl
(
pCreate
->
cfg
.
cfgVersion
);
pCreate
->
cfg
.
dbCfgVersion
=
htonl
(
pCreate
->
cfg
.
dbCfgVersion
);
pCreate
->
cfg
.
vgCfgVersion
=
htonl
(
pCreate
->
cfg
.
vgCfgVersion
);
pCreate
->
cfg
.
maxTables
=
htonl
(
pCreate
->
cfg
.
maxTables
);
pCreate
->
cfg
.
cacheBlockSize
=
htonl
(
pCreate
->
cfg
.
cacheBlockSize
);
pCreate
->
cfg
.
totalBlocks
=
htonl
(
pCreate
->
cfg
.
totalBlocks
);
...
...
src/inc/taosmsg.h
浏览文件 @
d1bd4b12
...
...
@@ -518,14 +518,15 @@ typedef struct SRetrieveTableRsp {
typedef
struct
{
int32_t
vgId
;
int32_t
c
fgVersion
;
int32_t
dbC
fgVersion
;
int64_t
totalStorage
;
int64_t
compStorage
;
int64_t
pointsWritten
;
uint8_t
status
;
uint8_t
role
;
uint8_t
replica
;
uint8_t
reserved
[
5
];
uint8_t
reserved
;
int32_t
vgCfgVersion
;
}
SVnodeLoad
;
typedef
struct
{
...
...
@@ -641,7 +642,7 @@ typedef struct {
typedef
struct
{
uint32_t
vgId
;
int32_t
c
fgVersion
;
int32_t
dbC
fgVersion
;
int32_t
maxTables
;
int32_t
cacheBlockSize
;
int32_t
totalBlocks
;
...
...
@@ -660,7 +661,8 @@ typedef struct {
int8_t
wals
;
int8_t
quorum
;
int8_t
update
;
int8_t
reserved
[
15
];
int8_t
reserved
[
11
];
int32_t
vgCfgVersion
;
}
SVnodeCfg
;
typedef
struct
{
...
...
src/mnode/inc/mnodeDef.h
浏览文件 @
d1bd4b12
...
...
@@ -144,7 +144,8 @@ typedef struct SVgObj {
int8_t
status
;
int8_t
reserved0
[
4
];
SVnodeGid
vnodeGid
[
TSDB_MAX_REPLICA
];
int8_t
reserved1
[
12
];
int32_t
vgCfgVersion
;
int8_t
reserved1
[
8
];
int8_t
updateEnd
[
4
];
int32_t
refCount
;
int32_t
numOfTables
;
...
...
@@ -181,7 +182,7 @@ typedef struct SDbObj {
int8_t
reserved0
[
4
];
char
acct
[
TSDB_USER_LEN
];
int64_t
createdTime
;
int32_t
c
fgVersion
;
int32_t
dbC
fgVersion
;
SDbCfg
cfg
;
int8_t
status
;
int8_t
reserved1
[
11
];
...
...
src/mnode/inc/mnodeDnode.h
浏览文件 @
d1bd4b12
...
...
@@ -55,12 +55,12 @@ typedef enum EDnodeOfflineReason {
TAOS_DN_OFF_OTHERS
}
EDnodeOfflineReason
;
extern
char
*
dnodeStatus
[];
extern
char
*
dnodeRoles
[];
int32_t
mnodeInitDnodes
();
void
mnodeCleanupDnodes
();
char
*
mnodeGetDnodeStatusStr
(
int32_t
dnodeStatus
);
void
mgmtMonitorDnodeModule
();
int32_t
mnodeGetDnodesNum
();
int32_t
mnodeGetOnlinDnodesCpuCoreNum
();
int32_t
mnodeGetOnlineDnodesNum
();
...
...
src/mnode/src/mnodeDb.c
浏览文件 @
d1bd4b12
...
...
@@ -1015,7 +1015,7 @@ static int32_t mnodeAlterDb(SDbObj *pDb, SAlterDbMsg *pAlter, void *pMsg) {
if
(
memcmp
(
&
newCfg
,
&
pDb
->
cfg
,
sizeof
(
SDbCfg
))
!=
0
)
{
pDb
->
cfg
=
newCfg
;
pDb
->
c
fgVersion
++
;
pDb
->
dbC
fgVersion
++
;
SSdbRow
row
=
{
.
type
=
SDB_OPER_GLOBAL
,
.
pTable
=
tsDbSdb
,
...
...
src/mnode/src/mnodeDnode.c
浏览文件 @
d1bd4b12
...
...
@@ -63,7 +63,6 @@ static int32_t mnodeGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
static
int32_t
mnodeRetrieveVnodes
(
SShowObj
*
pShow
,
char
*
data
,
int32_t
rows
,
void
*
pConn
);
static
int32_t
mnodeGetDnodeMeta
(
STableMetaMsg
*
pMeta
,
SShowObj
*
pShow
,
void
*
pConn
);
static
int32_t
mnodeRetrieveDnodes
(
SShowObj
*
pShow
,
char
*
data
,
int32_t
rows
,
void
*
pConn
);
static
char
*
mnodeGetDnodeAlternativeRoleStr
(
int32_t
alternativeRole
);
static
void
mnodeUpdateDnodeEps
();
static
char
*
offlineReason
[]
=
{
...
...
@@ -557,7 +556,8 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
for
(
int32_t
j
=
0
;
j
<
openVnodes
;
++
j
)
{
SVnodeLoad
*
pVload
=
&
pStatus
->
load
[
j
];
pVload
->
vgId
=
htonl
(
pVload
->
vgId
);
pVload
->
cfgVersion
=
htonl
(
pVload
->
cfgVersion
);
pVload
->
dbCfgVersion
=
htonl
(
pVload
->
dbCfgVersion
);
pVload
->
vgCfgVersion
=
htonl
(
pVload
->
vgCfgVersion
);
SVgObj
*
pVgroup
=
mnodeGetVgroup
(
pVload
->
vgId
);
if
(
pVgroup
==
NULL
)
{
...
...
@@ -833,12 +833,12 @@ static int32_t mnodeRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, vo
cols
++
;
pWrite
=
data
+
pShow
->
offset
[
cols
]
*
rows
+
pShow
->
bytes
[
cols
]
*
numOfRows
;
char
*
status
=
mnodeGetDnodeStatusStr
(
pDnode
->
status
)
;
char
*
status
=
dnodeStatus
[
pDnode
->
status
]
;
STR_TO_VARSTR
(
pWrite
,
status
);
cols
++
;
pWrite
=
data
+
pShow
->
offset
[
cols
]
*
rows
+
pShow
->
bytes
[
cols
]
*
numOfRows
;
char
*
role
=
mnodeGetDnodeAlternativeRoleStr
(
pDnode
->
alternativeRole
)
;
char
*
role
=
dnodeRoles
[
pDnode
->
alternativeRole
]
;
STR_TO_VARSTR
(
pWrite
,
role
);
cols
++
;
...
...
@@ -1154,21 +1154,17 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo
return
numOfRows
;
}
char
*
mnodeGetDnodeStatusStr
(
int32_t
dnodeStatus
)
{
switch
(
dnodeStatus
)
{
case
TAOS_DN_STATUS_OFFLINE
:
return
"offline"
;
case
TAOS_DN_STATUS_DROPPING
:
return
"dropping"
;
case
TAOS_DN_STATUS_BALANCING
:
return
"balancing"
;
case
TAOS_DN_STATUS_READY
:
return
"ready"
;
default:
return
"undefined"
;
}
}
char
*
dnodeStatus
[]
=
{
"offline"
,
"dropping"
,
"balancing"
,
"ready"
,
"undefined"
};
static
char
*
mnodeGetDnodeAlternativeRoleStr
(
int32_t
alternativeRole
)
{
switch
(
alternativeRole
)
{
case
TAOS_DN_ALTERNATIVE_ROLE_ANY
:
return
"any"
;
case
TAOS_DN_ALTERNATIVE_ROLE_MNODE
:
return
"mnode"
;
case
TAOS_DN_ALTERNATIVE_ROLE_VNODE
:
return
"vnode"
;
default:
return
"any"
;
}
}
char
*
dnodeRoles
[]
=
{
"any"
,
"mnode"
,
"vnode"
,
"any"
};
src/mnode/src/mnodeVgroup.c
浏览文件 @
d1bd4b12
...
...
@@ -256,6 +256,8 @@ SVgObj *mnodeGetVgroup(int32_t vgId) {
}
void
mnodeUpdateVgroup
(
SVgObj
*
pVgroup
)
{
pVgroup
->
vgCfgVersion
++
;
SSdbRow
row
=
{
.
type
=
SDB_OPER_GLOBAL
,
.
pTable
=
tsVgroupSdb
,
...
...
@@ -339,10 +341,11 @@ void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVl
pVgroup
->
pointsWritten
=
htobe64
(
pVload
->
pointsWritten
);
}
if
(
pVload
->
cfgVersion
!=
pVgroup
->
pDb
->
cfgVersion
||
pVload
->
replica
!=
pVgroup
->
numOfVnodes
)
{
mError
(
"dnode:%d, vgId:%d, vnode cfgVersion:%d repica:%d not match with mnode cfgVersion:%d replica:%d"
,
pDnode
->
dnodeId
,
pVload
->
vgId
,
pVload
->
cfgVersion
,
pVload
->
replica
,
pVgroup
->
pDb
->
cfgVersion
,
pVgroup
->
numOfVnodes
);
if
(
pVload
->
dbCfgVersion
!=
pVgroup
->
pDb
->
dbCfgVersion
||
pVload
->
replica
!=
pVgroup
->
numOfVnodes
||
pVload
->
vgCfgVersion
!=
pVgroup
->
vgCfgVersion
)
{
mError
(
"dnode:%d, vgId:%d, vnode cfgVersion:%d:%d repica:%d not match with mnode cfgVersion:%d:%d replica:%d"
,
pDnode
->
dnodeId
,
pVload
->
vgId
,
pVload
->
dbCfgVersion
,
pVload
->
vgCfgVersion
,
pVload
->
replica
,
pVgroup
->
pDb
->
dbCfgVersion
,
pVgroup
->
vgCfgVersion
,
pVgroup
->
numOfVnodes
);
mnodeSendAlterVgroupMsg
(
pVgroup
);
}
}
...
...
@@ -840,7 +843,8 @@ static SCreateVnodeMsg *mnodeBuildVnodeMsg(SVgObj *pVgroup) {
SVnodeCfg
*
pCfg
=
&
pVnode
->
cfg
;
pCfg
->
vgId
=
htonl
(
pVgroup
->
vgId
);
pCfg
->
cfgVersion
=
htonl
(
pDb
->
cfgVersion
);
pCfg
->
dbCfgVersion
=
htonl
(
pDb
->
dbCfgVersion
);
pCfg
->
vgCfgVersion
=
htonl
(
pVgroup
->
vgCfgVersion
);
pCfg
->
cacheBlockSize
=
htonl
(
pDb
->
cfg
.
cacheBlockSize
);
pCfg
->
totalBlocks
=
htonl
(
pDb
->
cfg
.
totalBlocks
);
pCfg
->
maxTables
=
htonl
(
maxTables
+
1
);
...
...
src/rpc/src/rpcMain.c
浏览文件 @
d1bd4b12
...
...
@@ -576,7 +576,7 @@ static void rpcFreeMsg(void *msg) {
static
SRpcConn
*
rpcOpenConn
(
SRpcInfo
*
pRpc
,
char
*
peerFqdn
,
uint16_t
peerPort
,
int8_t
connType
)
{
SRpcConn
*
pConn
;
uint32_t
peerIp
=
taosGetIpFromFqdn
(
peerFqdn
);
uint32_t
peerIp
=
taosGetIp
v4
FromFqdn
(
peerFqdn
);
if
(
peerIp
==
0xFFFFFFFF
)
{
tError
(
"%s, failed to resolve FQDN:%s"
,
pRpc
->
label
,
peerFqdn
);
terrno
=
TSDB_CODE_RPC_FQDN_ERROR
;
...
...
src/sync/src/syncMain.c
浏览文件 @
d1bd4b12
...
...
@@ -486,7 +486,7 @@ static void syncRemovePeer(SSyncPeer *pPeer) {
}
static
SSyncPeer
*
syncAddPeer
(
SSyncNode
*
pNode
,
const
SNodeInfo
*
pInfo
)
{
uint32_t
ip
=
taosGetIpFromFqdn
(
pInfo
->
nodeFqdn
);
uint32_t
ip
=
taosGetIp
v4
FromFqdn
(
pInfo
->
nodeFqdn
);
if
(
ip
==
0xFFFFFFFF
)
{
sError
(
"failed to add peer, can resolve fqdn:%s since %s"
,
pInfo
->
nodeFqdn
,
strerror
(
errno
));
terrno
=
TSDB_CODE_RPC_FQDN_ERROR
;
...
...
@@ -1266,8 +1266,10 @@ static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle
}
}
if
(
pNode
->
replica
!=
1
)
{
return
TSDB_CODE_SYN_INVALID_VERSION
;
}
}
// always update version
sTrace
(
"vgId:%d, update version, replica:%d role:%s qtype:%s hver:%"
PRIu64
,
pNode
->
vgId
,
pNode
->
replica
,
...
...
src/util/inc/tsocket.h
浏览文件 @
d1bd4b12
...
...
@@ -33,7 +33,7 @@ SOCKET taosOpenTcpServerSocket(uint32_t ip, uint16_t port);
int32_t
taosKeepTcpAlive
(
SOCKET
sockFd
);
int32_t
taosGetFqdn
(
char
*
);
uint32_t
taosGetIpFromFqdn
(
const
char
*
);
uint32_t
taosGetIp
v4
FromFqdn
(
const
char
*
);
void
tinet_ntoa
(
char
*
ipstr
,
uint32_t
ip
);
uint32_t
ip2uint
(
const
char
*
const
ip_addr
);
...
...
src/util/src/tnettest.c
浏览文件 @
d1bd4b12
...
...
@@ -449,7 +449,7 @@ static void taosNetTestClient(char *host, int32_t startPort, int32_t pkgLen) {
int32_t
endPort
=
startPort
+
11
;
uInfo
(
"work as client, host:%s startPort:%d endPort:%d pkgLen:%d
\n
"
,
host
,
startPort
,
endPort
,
pkgLen
);
uint32_t
serverIp
=
taosGetIpFromFqdn
(
host
);
uint32_t
serverIp
=
taosGetIp
v4
FromFqdn
(
host
);
if
(
serverIp
==
0xFFFFFFFF
)
{
uError
(
"failed to resolve fqdn:%s"
,
host
);
exit
(
-
1
);
...
...
src/util/src/tsocket.c
浏览文件 @
d1bd4b12
...
...
@@ -40,9 +40,9 @@ int32_t taosGetFqdn(char *fqdn) {
return
0
;
}
uint32_t
taosGetIpFromFqdn
(
const
char
*
fqdn
)
{
uint32_t
taosGetIp
v4
FromFqdn
(
const
char
*
fqdn
)
{
struct
addrinfo
hints
=
{
0
};
hints
.
ai_family
=
AF_
UNSPEC
;
hints
.
ai_family
=
AF_
INET
;
hints
.
ai_socktype
=
SOCK_STREAM
;
struct
addrinfo
*
result
=
NULL
;
...
...
src/vnode/inc/vnodeInt.h
浏览文件 @
d1bd4b12
...
...
@@ -56,7 +56,8 @@ typedef struct {
int64_t
sync
;
void
*
events
;
void
*
cq
;
// continuous query
int32_t
cfgVersion
;
int32_t
dbCfgVersion
;
int32_t
vgCfgVersion
;
STsdbCfg
tsdbCfg
;
SSyncCfg
syncCfg
;
SWalCfg
walCfg
;
...
...
src/vnode/src/vnodeCfg.c
浏览文件 @
d1bd4b12
...
...
@@ -22,7 +22,8 @@
static
void
vnodeLoadCfg
(
SVnodeObj
*
pVnode
,
SCreateVnodeMsg
*
vnodeMsg
)
{
tstrncpy
(
pVnode
->
db
,
vnodeMsg
->
db
,
sizeof
(
pVnode
->
db
));
pVnode
->
cfgVersion
=
vnodeMsg
->
cfg
.
cfgVersion
;
pVnode
->
dbCfgVersion
=
vnodeMsg
->
cfg
.
dbCfgVersion
;
pVnode
->
vgCfgVersion
=
vnodeMsg
->
cfg
.
vgCfgVersion
;
pVnode
->
tsdbCfg
.
cacheBlockSize
=
vnodeMsg
->
cfg
.
cacheBlockSize
;
pVnode
->
tsdbCfg
.
totalBlocks
=
vnodeMsg
->
cfg
.
totalBlocks
;
pVnode
->
tsdbCfg
.
daysPerFile
=
vnodeMsg
->
cfg
.
daysPerFile
;
...
...
@@ -95,12 +96,19 @@ int32_t vnodeReadCfg(SVnodeObj *pVnode) {
}
tstrncpy
(
vnodeMsg
.
db
,
db
->
valuestring
,
sizeof
(
vnodeMsg
.
db
));
cJSON
*
c
fgVersion
=
cJSON_GetObjectItem
(
root
,
"cfgVersion"
);
if
(
!
cfgVersion
||
c
fgVersion
->
type
!=
cJSON_Number
)
{
cJSON
*
dbC
fgVersion
=
cJSON_GetObjectItem
(
root
,
"cfgVersion"
);
if
(
!
dbCfgVersion
||
dbC
fgVersion
->
type
!=
cJSON_Number
)
{
vError
(
"vgId:%d, failed to read %s, cfgVersion not found"
,
pVnode
->
vgId
,
file
);
goto
PARSE_VCFG_ERROR
;
}
vnodeMsg
.
cfg
.
cfgVersion
=
cfgVersion
->
valueint
;
vnodeMsg
.
cfg
.
dbCfgVersion
=
dbCfgVersion
->
valueint
;
cJSON
*
vgCfgVersion
=
cJSON_GetObjectItem
(
root
,
"vgCfgVersion"
);
if
(
!
vgCfgVersion
||
vgCfgVersion
->
type
!=
cJSON_Number
)
{
vError
(
"vgId:%d, failed to read %s, vgCfgVersion not found"
,
pVnode
->
vgId
,
file
);
goto
PARSE_VCFG_ERROR
;
}
vnodeMsg
.
cfg
.
vgCfgVersion
=
vgCfgVersion
->
valueint
;
cJSON
*
cacheBlockSize
=
cJSON_GetObjectItem
(
root
,
"cacheBlockSize"
);
if
(
!
cacheBlockSize
||
cacheBlockSize
->
type
!=
cJSON_Number
)
{
...
...
@@ -278,7 +286,8 @@ int32_t vnodeWriteCfg(SCreateVnodeMsg *pMsg) {
len
+=
snprintf
(
content
+
len
,
maxLen
-
len
,
"{
\n
"
);
len
+=
snprintf
(
content
+
len
,
maxLen
-
len
,
"
\"
db
\"
:
\"
%s
\"
,
\n
"
,
pMsg
->
db
);
len
+=
snprintf
(
content
+
len
,
maxLen
-
len
,
"
\"
cfgVersion
\"
: %d,
\n
"
,
pMsg
->
cfg
.
cfgVersion
);
len
+=
snprintf
(
content
+
len
,
maxLen
-
len
,
"
\"
cfgVersion
\"
: %d,
\n
"
,
pMsg
->
cfg
.
dbCfgVersion
);
len
+=
snprintf
(
content
+
len
,
maxLen
-
len
,
"
\"
vgCfgVersion
\"
: %d,
\n
"
,
pMsg
->
cfg
.
vgCfgVersion
);
len
+=
snprintf
(
content
+
len
,
maxLen
-
len
,
"
\"
cacheBlockSize
\"
: %d,
\n
"
,
pMsg
->
cfg
.
cacheBlockSize
);
len
+=
snprintf
(
content
+
len
,
maxLen
-
len
,
"
\"
totalBlocks
\"
: %d,
\n
"
,
pMsg
->
cfg
.
totalBlocks
);
len
+=
snprintf
(
content
+
len
,
maxLen
-
len
,
"
\"
daysPerFile
\"
: %d,
\n
"
,
pMsg
->
cfg
.
daysPerFile
);
...
...
src/vnode/src/vnodeMain.c
浏览文件 @
d1bd4b12
...
...
@@ -154,7 +154,7 @@ int32_t vnodeAlter(void *vparam, SCreateVnodeMsg *pVnodeCfg) {
SVnodeObj
*
pVnode
=
vparam
;
// vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS
//
c
fgVersion can be corrected by status msg
//
dbC
fgVersion can be corrected by status msg
if
(
!
vnodeSetUpdatingStatus
(
pVnode
))
{
vDebug
(
"vgId:%d, vnode is not ready, do alter operation later"
,
pVnode
->
vgId
);
return
TSDB_CODE_SUCCESS
;
...
...
src/vnode/src/vnodeMgmt.c
浏览文件 @
d1bd4b12
...
...
@@ -134,7 +134,8 @@ static void vnodeBuildVloadMsg(SVnodeObj *pVnode, SStatusMsg *pStatus) {
SVnodeLoad
*
pLoad
=
&
pStatus
->
load
[
pStatus
->
openVnodes
++
];
pLoad
->
vgId
=
htonl
(
pVnode
->
vgId
);
pLoad
->
cfgVersion
=
htonl
(
pVnode
->
cfgVersion
);
pLoad
->
dbCfgVersion
=
htonl
(
pVnode
->
dbCfgVersion
);
pLoad
->
vgCfgVersion
=
htonl
(
pVnode
->
vgCfgVersion
);
pLoad
->
totalStorage
=
htobe64
(
totalStorage
);
pLoad
->
compStorage
=
htobe64
(
compStorage
);
pLoad
->
pointsWritten
=
htobe64
(
pointsWritten
);
...
...
tests/Jenkinsfile
浏览文件 @
d1bd4b12
...
...
@@ -7,12 +7,12 @@ def pre_test(){
sh
'''
cd ${WKC}
git reset --hard
git checkout $
{BRANCH}
git checkout $
BRANCH_NAME
git pull
git submodule update
cd ${WK}
git reset --hard
git checkout $
{BRANCH}
git checkout $
BRANCH_NAME
git pull
export TZ=Asia/Harbin
date
...
...
@@ -28,7 +28,7 @@ def pre_test(){
pipeline
{
agent
none
environment
{
BRANCH
=
'develop'
WK
=
'/var/lib/jenkins/workspace/TDinternal'
WKC
=
'/var/lib/jenkins/workspace/TDinternal/community'
}
...
...
tests/pytest/concurrent_inquiry.py
浏览文件 @
d1bd4b12
...
...
@@ -38,7 +38,7 @@ class ConcurrentInquiry:
# stableNum = 2,subtableNum = 1000,insertRows = 100):
def
__init__
(
self
,
ts
,
host
,
user
,
password
,
dbname
,
stb_prefix
,
subtb_prefix
,
n_Therads
,
r_Therads
,
probabilities
,
loop
,
stableNum
,
subtableNum
,
insertRows
):
stableNum
,
subtableNum
,
insertRows
,
mix_table
):
self
.
n_numOfTherads
=
n_Therads
self
.
r_numOfTherads
=
r_Therads
self
.
ts
=
ts
...
...
@@ -60,6 +60,7 @@ class ConcurrentInquiry:
self
.
stableNum
=
stableNum
self
.
subtableNum
=
subtableNum
self
.
insertRows
=
insertRows
self
.
mix_table
=
mix_table
def
SetThreadsNum
(
self
,
num
):
self
.
numOfTherads
=
num
...
...
@@ -195,7 +196,13 @@ class ConcurrentInquiry:
pick_func
+=
alias
sel_col_list
.
append
(
pick_func
)
sql
=
sql
+
','
.
join
(
sel_col_list
)
+
' from '
+
random
.
choice
(
self
.
stb_list
+
self
.
subtb_list
)
+
' '
#select col & func
sql
=
sql
+
','
.
join
(
sel_col_list
)
#select col & func
if
self
.
mix_table
==
0
:
sql
=
sql
+
' from '
+
random
.
choice
(
self
.
stb_list
+
self
.
subtb_list
)
+
' '
elif
self
.
mix_table
==
1
:
sql
=
sql
+
' from '
+
random
.
choice
(
self
.
subtb_list
)
+
' '
else
:
sql
=
sql
+
' from '
+
random
.
choice
(
self
.
stb_list
)
+
' '
con_func
=
[
self
.
con_where
,
self
.
con_interval
,
self
.
con_limit
,
self
.
con_group
,
self
.
con_order
,
self
.
con_fill
]
sel_con
=
random
.
sample
(
con_func
,
random
.
randint
(
0
,
len
(
con_func
)))
sel_con_list
=
[]
...
...
@@ -212,7 +219,7 @@ class ConcurrentInquiry:
col_intersection
=
[]
tag_intersection
=
[]
subtable
=
None
if
self
.
mix_table
==
0
:
if
bool
(
random
.
getrandbits
(
1
)):
subtable
=
True
tbname
=
random
.
sample
(
self
.
subtb_list
,
2
)
...
...
@@ -228,12 +235,24 @@ class ConcurrentInquiry:
tag_list
.
append
(
self
.
stb_stru_list
[
self
.
stb_list
.
index
(
i
)])
col_intersection
=
list
(
set
(
col_list
[
0
]).
intersection
(
set
(
col_list
[
1
])))
tag_intersection
=
list
(
set
(
tag_list
[
0
]).
intersection
(
set
(
tag_list
[
1
])))
elif
self
.
mix_table
==
1
:
subtable
=
True
tbname
=
random
.
sample
(
self
.
subtb_list
,
2
)
for
i
in
tbname
:
col_list
.
append
(
self
.
subtb_stru_list
[
self
.
subtb_list
.
index
(
i
)])
tag_list
.
append
(
self
.
subtb_stru_list
[
self
.
subtb_list
.
index
(
i
)])
col_intersection
=
list
(
set
(
col_list
[
0
]).
intersection
(
set
(
col_list
[
1
])))
tag_intersection
=
list
(
set
(
tag_list
[
0
]).
intersection
(
set
(
tag_list
[
1
])))
else
:
tbname
=
random
.
sample
(
self
.
stb_list
,
2
)
for
i
in
tbname
:
col_list
.
append
(
self
.
stb_stru_list
[
self
.
stb_list
.
index
(
i
)])
tag_list
.
append
(
self
.
stb_stru_list
[
self
.
stb_list
.
index
(
i
)])
col_intersection
=
list
(
set
(
col_list
[
0
]).
intersection
(
set
(
col_list
[
1
])))
tag_intersection
=
list
(
set
(
tag_list
[
0
]).
intersection
(
set
(
tag_list
[
1
])))
con_rand
=
random
.
randint
(
0
,
len
(
condition_list
))
col_rand
=
random
.
randint
(
0
,
len
(
col_list
))
tag_rand
=
random
.
randint
(
0
,
len
(
tag_list
))
sql
=
'select '
#select
sel_col_tag
=
[]
...
...
@@ -247,12 +266,16 @@ class ConcurrentInquiry:
sql
=
sql
+
' from '
+
str
(
tbname
[
0
])
+
' t1,'
+
str
(
tbname
[
1
])
+
' t2 '
#select col & func
join_section
=
None
temp
=
None
if
subtable
:
join_section
=
''
.
join
(
random
.
choices
(
col_intersection
))
sql
+=
'where t1._c0 = t2._c0 and '
+
't1.'
+
join_section
+
'=t2.'
+
join_section
temp
=
random
.
choices
(
col_intersection
)
join_section
=
temp
.
pop
()
sql
+=
'where t1._c0 = t2._c0 and '
+
't1.'
+
str
(
join_section
)
+
'=t2.'
+
str
(
join_section
)
else
:
join_section
=
''
.
join
(
random
.
choices
(
col_intersection
+
tag_intersection
))
sql
+=
'where t1._c0 = t2._c0 and '
+
't1.'
+
join_section
+
'=t2.'
+
join_section
temp
=
random
.
choices
(
col_intersection
+
tag_intersection
)
join_section
=
temp
.
pop
()
print
(
random
.
choices
(
col_intersection
))
sql
+=
'where t1._c0 = t2._c0 and '
+
't1.'
+
str
(
join_section
)
+
'=t2.'
+
str
(
join_section
)
return
sql
def
random_pick
(
self
):
...
...
@@ -516,12 +539,20 @@ parser.add_argument(
default
=
2
,
type
=
int
,
help
=
'Number of stables (default: 2)'
)
parser
.
add_argument
(
'-m'
,
'--mix-stable-subtable'
,
action
=
'store'
,
default
=
0
,
type
=
int
,
help
=
'0:stable & substable ,1:subtable ,2:stable (default: 0)'
)
args
=
parser
.
parse_args
()
q
=
ConcurrentInquiry
(
args
.
ts
,
args
.
host_name
,
args
.
user
,
args
.
password
,
args
.
db_name
,
args
.
stb_name_prefix
,
args
.
subtb_name_prefix
,
args
.
number_of_native_threads
,
args
.
number_of_rest_threads
,
args
.
probabilities
,
args
.
loop_per_thread
,
args
.
number_of_stables
,
args
.
number_of_tables
,
args
.
number_of_records
)
args
.
probabilities
,
args
.
loop_per_thread
,
args
.
number_of_stables
,
args
.
number_of_tables
,
args
.
number_of_records
,
args
.
mix_stable_subtable
)
if
args
.
create_table
:
q
.
gen_data
()
...
...
tests/pytest/fulltest.sh
浏览文件 @
d1bd4b12
...
...
@@ -19,7 +19,7 @@ python3 ./test.py -f insert/randomNullCommit.py
python3 insert/retentionpolicy.py
python3 ./test.py
-f
insert/alterTableAndInsert.py
python3 ./test.py
-f
insert/insertIntoTwoTables.py
python3 ./test.py
-f
insert/before_1970.py
#
python3 ./test.py -f insert/before_1970.py
python3 bug2265.py
#table
...
...
@@ -215,7 +215,7 @@ python3 ./test.py -f functions/function_spread.py -r 1
python3 ./test.py
-f
functions/function_stddev.py
-r
1
python3 ./test.py
-f
functions/function_sum.py
-r
1
python3 ./test.py
-f
functions/function_top.py
-r
1
#
python3 ./test.py -f functions/function_twa.py -r 1
python3 ./test.py
-f
functions/function_twa.py
-r
1
python3 ./test.py
-f
functions/function_twa_test2.py
python3 queryCount.py
python3 ./test.py
-f
query/queryGroupbyWithInterval.py
...
...
tests/pytest/functions/function_twa.py
浏览文件 @
d1bd4b12
...
...
@@ -47,22 +47,16 @@ class TDTestCase:
tdSql
.
error
(
"select twa(ts) from test1"
)
tdSql
.
error
(
"select twa(col1) from test"
)
tdSql
.
error
(
"select twa(col1) from test1"
)
tdSql
.
error
(
"select twa(col2) from test"
)
tdSql
.
error
(
"select twa(col2) from test1"
)
tdSql
.
error
(
"select twa(col3) from test"
)
tdSql
.
error
(
"select twa(col3) from test1"
)
tdSql
.
error
(
"select twa(col4) from test"
)
tdSql
.
error
(
"select twa(col4) from test1"
)
tdSql
.
error
(
"select twa(col5) from test"
)
tdSql
.
error
(
"select twa(col5) from test1"
)
tdSql
.
error
(
"select twa(col6) from test"
)
tdSql
.
error
(
"select twa(col6) from test1"
)
tdSql
.
error
(
"select twa(col7) from test"
)
tdSql
.
error
(
"select twa(col7) from test1"
)
...
...
@@ -73,58 +67,22 @@ class TDTestCase:
tdSql
.
error
(
"select twa(col9) from test"
)
tdSql
.
error
(
"select twa(col9) from test1"
)
tdSql
.
error
(
"select twa(col1) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col1) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col2) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col2) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col3) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col3) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col4) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col4) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col5) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col5) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col6) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col6) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col1) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col1) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col2) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col2) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col3) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col3) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col4) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col4) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col5) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col5) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col6) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col6) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col1) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col1) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col1) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col2) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col2) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col2) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col3) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col3) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col3) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col4) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col4) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col4) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col5) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col5) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col5) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col6) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col6) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col6) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
def
stop
(
self
):
...
...
tests/pytest/functions/function_twa_restart.py
浏览文件 @
d1bd4b12
...
...
@@ -28,12 +28,17 @@ class TDTestCase:
self
.
ts
=
1537146000000
def
run
(
self
):
tdSql
.
execute
(
"use db"
)
tdSql
.
prepare
(
)
intData
=
[]
floatData
=
[]
tdSql
.
execute
(
'''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))'''
)
tdSql
.
execute
(
"create table test1 using test tags('beijing')"
)
for
i
in
range
(
self
.
rowNum
):
tdSql
.
execute
(
"insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
%
(
self
.
ts
+
i
,
i
+
1
,
i
+
1
,
i
+
1
,
i
+
1
,
i
+
0.1
,
i
+
0.1
,
i
%
2
,
i
+
1
,
i
+
1
))
intData
.
append
(
i
+
1
)
floatData
.
append
(
i
+
0.1
)
...
...
@@ -42,22 +47,16 @@ class TDTestCase:
tdSql
.
error
(
"select twa(ts) from test1"
)
tdSql
.
error
(
"select twa(col1) from test"
)
tdSql
.
error
(
"select twa(col1) from test1"
)
tdSql
.
error
(
"select twa(col2) from test"
)
tdSql
.
error
(
"select twa(col2) from test1"
)
tdSql
.
error
(
"select twa(col3) from test"
)
tdSql
.
error
(
"select twa(col3) from test1"
)
tdSql
.
error
(
"select twa(col4) from test"
)
tdSql
.
error
(
"select twa(col4) from test1"
)
tdSql
.
error
(
"select twa(col5) from test"
)
tdSql
.
error
(
"select twa(col5) from test1"
)
tdSql
.
error
(
"select twa(col6) from test"
)
tdSql
.
error
(
"select twa(col6) from test1"
)
tdSql
.
error
(
"select twa(col7) from test"
)
tdSql
.
error
(
"select twa(col7) from test1"
)
...
...
@@ -68,58 +67,22 @@ class TDTestCase:
tdSql
.
error
(
"select twa(col9) from test"
)
tdSql
.
error
(
"select twa(col9) from test1"
)
tdSql
.
error
(
"select twa(col1) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col1) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col2) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col2) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col3) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col3) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col4) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col4) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col5) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col5) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col6) from test where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col6) from test1 where ts > %d"
%
self
.
ts
)
tdSql
.
error
(
"select twa(col1) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col1) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col2) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col2) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col3) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col3) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col4) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col4) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col5) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col5) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col6) from test where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col6) from test1 where ts < %d"
%
(
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col1) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col1) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col1) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col2) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col2) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col2) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col3) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col3) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col3) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col4) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col4) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col4) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col5) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col5) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col5) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col6) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
error
(
"select twa(col6) from test where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
tdSql
.
query
(
"select twa(col6) from test1 where ts > %d and ts < %d"
%
(
self
.
ts
,
self
.
ts
+
self
.
rowNum
))
def
stop
(
self
):
...
...
tests/pytest/functions/function_twa_test2.py
浏览文件 @
d1bd4b12
...
...
@@ -39,6 +39,10 @@ class TDTestCase:
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
5.5
)
tdSql
.
query
(
"select twa(c) from t1"
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
5.5
)
tdSql
.
query
(
"select twa(c) from t1 where ts >= '2018-09-17 09:00:00.000' and ts <= '2018-09-17 09:01:30.000' interval(10s)"
)
tdSql
.
checkRows
(
10
)
tdSql
.
checkData
(
0
,
1
,
1.49995
)
...
...
tests/script/jenkins/basic_3.txt
浏览文件 @
d1bd4b12
...
...
@@ -70,7 +70,7 @@
./test.sh -f unique/arbitrator/sync_replica2_dropDb.sim
./test.sh -f unique/arbitrator/sync_replica2_dropTable.sim
./test.sh -f unique/arbitrator/sync_replica3_alterTable_add.sim
#
./test.sh -f unique/arbitrator/sync_replica3_alterTable_add.sim
./test.sh -f unique/arbitrator/sync_replica3_alterTable_drop.sim
./test.sh -f unique/arbitrator/sync_replica3_dropDb.sim
./test.sh -f unique/arbitrator/sync_replica3_dropTable.sim
...
...
tests/script/unique/big/maxvnodes.sim
浏览文件 @
d1bd4b12
...
...
@@ -9,10 +9,11 @@ $totalRows = $totalVnodes * $maxTables
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c walLevel -v 2
system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v $totalVnodes
system sh/cfg.sh -n dnode1 -c balanceInterval -v 1
system sh/deploy.sh -n dnode2 -i 2
system sh/cfg.sh -n dnode2 -c walLevel -v 2
system sh/cfg.sh -n dnode2 -c maxVgroupsPerDb -v $totalVnodes
system sh/cfg.sh -n dnode2 -c balanceInterval -v 1
print ========== prepare data
system sh/exec.sh -n dnode1 -s start
...
...
tests/script/unique/db/replica_add12.sim
浏览文件 @
d1bd4b12
...
...
@@ -115,6 +115,7 @@ sql insert into d1.t1 values(now, 2)
sql insert into d2.t2 values(now, 2)
sql insert into d3.t3 values(now, 2)
sql insert into d4.t4 values(now, 2)
sleep 1000
sql select * from d1.t1
if $rows != 2 then
...
...
@@ -154,6 +155,7 @@ sql_error insert into d1.t1 values(now, 3)
sql_error insert into d2.t2 values(now, 3)
sql_error insert into d3.t3 values(now, 3)
sql_error insert into d4.t4 values(now, 3)
sleep 1000
print ========= step6
system sh/exec.sh -n dnode2 -s start
...
...
@@ -193,6 +195,7 @@ sql_error insert into d1.t1 values(now, 3)
sql_error insert into d2.t2 values(now, 3)
sql_error insert into d3.t3 values(now, 3)
sql_error insert into d4.t4 values(now, 3)
sleep 1000
sql_error select * from d1.t1
sql_error select * from d2.t2
...
...
@@ -207,6 +210,7 @@ sql insert into d1.t1 values(now, 5)
sql insert into d2.t2 values(now, 5)
sql insert into d3.t3 values(now, 5)
sql insert into d4.t4 values(now, 5)
sleep 1000
sql select * from d1.t1
if $rows != 4 then
...
...
tests/script/unique/db/replica_add13.sim
浏览文件 @
d1bd4b12
...
...
@@ -46,6 +46,7 @@ sql insert into d1.t1 values(1589529000011, 1)
sql insert into d2.t2 values(1589529000021, 1)
sql insert into d3.t3 values(1589529000031, 1)
sql insert into d4.t4 values(1589529000041, 1)
sleep 1000
sql select * from d1.t1
if $rows != 1 then
...
...
tests/script/unique/db/replica_add23.sim
浏览文件 @
d1bd4b12
...
...
@@ -46,6 +46,7 @@ sql insert into d1.t1 values(1588262400001, 1)
sql insert into d2.t2 values(1588262400001, 1)
sql insert into d3.t3 values(1588262400001, 1)
sql insert into d4.t4 values(1588262400001, 1)
sleep 1000
sql select * from d1.t1
if $rows != 1 then
...
...
tests/script/unique/db/replica_part.sim
浏览文件 @
d1bd4b12
...
...
@@ -38,6 +38,7 @@ sql insert into d2.t2 values(now, 1)
sql insert into d1.t1 values(now, 1)
sql insert into d3.t3 values(now, 1)
sql insert into d4.t4 values(now, 1)
sleep 1000
sql select * from d1.t1
if $rows != 1 then
...
...
@@ -77,6 +78,7 @@ sql insert into d1.t1 values(now, 2)
sql insert into d2.t2 values(now, 2)
sql insert into d3.t3 values(now, 2)
sql insert into d4.t4 values(now, 2)
sleep 1000
sql select * from d1.t1
if $rows != 2 then
...
...
@@ -137,6 +139,7 @@ sql insert into d1.t1 values(now, 5)
sql insert into d2.t2 values(now, 5)
sql insert into d3.t3 values(now, 5)
sql insert into d4.t4 values(now, 5)
sleep 1000
sql select * from d1.t1
sql select * from d2.t2
...
...
tests/script/unique/db/replica_reduce21.sim
浏览文件 @
d1bd4b12
...
...
@@ -36,6 +36,7 @@ sql insert into d2.t2 values(now, 1)
sql insert into d1.t1 values(now, 1)
sql insert into d3.t3 values(now, 1)
sql insert into d4.t4 values(now, 1)
sleep 1000
sql select * from d1.t1
if $rows != 1 then
...
...
@@ -67,6 +68,7 @@ sleep 12000
print ========= step4 query d1
sql insert into d1.t1 values(now, 2)
sql select * from d1.t1
sleep 1000
if $rows != 2 then
return -1
endi
...
...
@@ -75,6 +77,7 @@ print ========= step5 query d5
sql create table d5.t5 (ts timestamp, i int)
sql insert into d5.t5 values(now, 1);
sql select * from d5.t5
sleep 1000
if $rows != 1 then
return -1
endi
...
...
@@ -89,6 +92,7 @@ sql insert into d5.t5 values(now, 2)
sql insert into d2.t2 values(now, 2)
sql insert into d3.t3 values(now, 2)
sql insert into d4.t4 values(now, 2)
sleep 1000
sql select * from d5.t5
if $rows != 2 then
...
...
@@ -118,6 +122,7 @@ sql insert into d5.t5 values(now, 3)
sql insert into d2.t2 values(now, 3)
sql insert into d3.t3 values(now, 3)
sql insert into d4.t4 values(now, 3)
sleep 1000
sql select * from d5.t5
if $rows != 3 then
...
...
tests/script/unique/db/replica_reduce31.sim
浏览文件 @
d1bd4b12
...
...
@@ -38,6 +38,7 @@ sql insert into d1.t1 values(now, 1)
sql insert into d2.t2 values(now, 1)
sql insert into d3.t3 values(now, 1)
sql insert into d4.t4 values(now, 1)
sleep 1000
sql select * from d1.t1
if $rows != 1 then
...
...
@@ -83,6 +84,7 @@ sql insert into d1.t1 values(now, 2)
sql insert into d2.t2 values(now, 2)
sql insert into d3.t3 values(now, 2)
sql insert into d4.t4 values(now, 2)
sleep 1000
sql select * from d1.t1
if $rows != 2 then
...
...
@@ -114,6 +116,7 @@ sql insert into d1.t1 values(now, 3)
sql insert into d2.t2 values(now, 3)
sql insert into d3.t3 values(now, 3)
sql insert into d4.t4 values(now, 3)
sleep 1000
sql select * from d1.t1
if $rows != 3 then
...
...
@@ -174,6 +177,7 @@ sql insert into d1.t1 values(now, 6)
sql insert into d2.t2 values(now, 6)
sql insert into d3.t3 values(now, 6)
sql insert into d4.t4 values(now, 6)
sleep 1000
sql select * from d1.t1
sql select * from d2.t2
...
...
tests/script/unique/db/replica_reduce32.sim
浏览文件 @
d1bd4b12
...
...
@@ -38,6 +38,7 @@ sql insert into d2.t2 values(now, 1)
sql insert into d1.t1 values(now, 1)
sql insert into d3.t3 values(now, 1)
sql insert into d4.t4 values(now, 1)
sleep 1000
sql select * from d1.t1
if $rows != 1 then
...
...
@@ -71,6 +72,7 @@ sql insert into d1.t1 values(now, 2)
sql insert into d2.t2 values(now, 2)
sql insert into d3.t3 values(now, 2)
sql insert into d4.t4 values(now, 2)
sleep 1000
sql select * from d1.t1
if $rows != 2 then
...
...
@@ -132,6 +134,7 @@ sql insert into d1.t1 values(now, 5)
sql insert into d2.t2 values(now, 5)
sql insert into d3.t3 values(now, 5)
sql insert into d4.t4 values(now, 5)
sleep 1000
sql select * from d1.t1
print d1.t1 $rows
...
...
tests/test-all.sh
浏览文件 @
d1bd4b12
...
...
@@ -25,6 +25,26 @@ function runSimCaseOneByOne {
fi
done
<
$1
}
function
runSimCaseOneByOnefq
{
while
read
-r
line
;
do
if
[[
$line
=
~ ^./test.sh
*
]]
||
[[
$line
=
~ ^run
*
]]
;
then
case
=
`
echo
$line
|
grep
sim
$
|awk
'{print $NF}'
`
start_time
=
`
date
+%s
`
./test.sh
-f
$case
>
/dev/null 2>&1
&&
\
echo
-e
"
${
GREEN
}
$case
success
${
NC
}
"
|
tee
-a
out.log
||
\
(
grep
'script.*success.*m$'
../../../sim/tsim/log/taoslog0.0
&&
echo
-e
"
${
GREEN
}
$case
success
${
NC
}
"
|
tee
-a
out.log
)
||
echo
-e
"
${
RED
}
$case
failed
${
NC
}
"
|
tee
-a
out.log
out_log
=
`
tail
-1
out.log
`
if
[[
$out_log
=
~
'failed'
]]
;
then
exit
8
fi
end_time
=
`
date
+%s
`
echo
execution
time
of
$case
was
`
expr
$end_time
-
$start_time
`
s. |
tee
-a
out.log
fi
done
<
$1
}
function
runPyCaseOneByOne
{
while
read
-r
line
;
do
...
...
@@ -52,7 +72,32 @@ function runPyCaseOneByOne {
fi
done
<
$1
}
function
runPyCaseOneByOnefq
{
while
read
-r
line
;
do
if
[[
$line
=
~ ^python.
*
]]
;
then
if
[[
$line
!=
*
sleep
*
]]
;
then
if
[[
$line
=
~
'-r'
]]
;
then
case
=
`
echo
$line
|awk
'{print $4}'
`
else
case
=
`
echo
$line
|awk
'{print $NF}'
`
fi
start_time
=
`
date
+%s
`
$line
>
/dev/null 2>&1
&&
\
echo
-e
"
${
GREEN
}
$case
success
${
NC
}
"
|
tee
-a
pytest-out.log
||
\
echo
-e
"
${
RED
}
$case
failed
${
NC
}
"
|
tee
-a
pytest-out.log
end_time
=
`
date
+%s
`
out_log
=
`
tail
-1
pytest-out.log
`
if
[[
$out_log
=
~
'failed'
]]
;
then
exit
8
fi
echo
execution
time
of
$case
was
`
expr
$end_time
-
$start_time
`
s.
|
tee
-a
pytest-out.log
else
$line
>
/dev/null 2>&1
fi
fi
done
<
$1
}
totalFailed
=
0
totalPyFailed
=
0
...
...
@@ -78,6 +123,15 @@ if [ "$2" != "python" ]; then
elif
[
"
$1
"
==
"b3"
]
;
then
echo
"### run TSIM b3 test ###"
runSimCaseOneByOne jenkins/basic_3.txt
elif
[
"
$1
"
==
"b1fq"
]
;
then
echo
"### run TSIM b1 test ###"
runSimCaseOneByOnefq jenkins/basic_1.txt
elif
[
"
$1
"
==
"b2fq"
]
;
then
echo
"### run TSIM b2 test ###"
runSimCaseOneByOnefq jenkins/basic_2.txt
elif
[
"
$1
"
==
"b3fq"
]
;
then
echo
"### run TSIM b3 test ###"
runSimCaseOneByOnefq jenkins/basic_3.txt
elif
[
"
$1
"
==
"smoke"
]
||
[
-z
"
$1
"
]
;
then
echo
"### run TSIM smoke test ###"
runSimCaseOneByOne basicSuite.sim
...
...
@@ -137,6 +191,9 @@ if [ "$2" != "sim" ]; then
elif
[
"
$1
"
==
"pytest"
]
;
then
echo
"### run Python full test ###"
runPyCaseOneByOne fulltest.sh
elif
[
"
$1
"
==
"pytestfq"
]
;
then
echo
"### run Python full test ###"
runPyCaseOneByOnefq fulltest.sh
elif
[
"
$1
"
==
"p1"
]
;
then
echo
"### run Python_1 test ###"
runPyCaseOneByOne pytest_1.sh
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录