Merge branch 'develop' into coverity_scan
This commit is contained in:
commit
bf9d36e592
|
@ -119,7 +119,7 @@ WantedBy=multi-user.target
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const version = "TDengine alert v2.0.0.0"
|
const version = "TDengine alert v2.0.0.1"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -131,23 +131,83 @@ TDengine集群中加入一个新的dnode时,涉及集群相关的一些参数
|
||||||
- maxTablesPerVnode: 每个vnode中能够创建的最大表个数。默认值:1000000。
|
- maxTablesPerVnode: 每个vnode中能够创建的最大表个数。默认值:1000000。
|
||||||
- maxVgroupsPerDb: 每个数据库中能够使用的最大vnode个数。
|
- maxVgroupsPerDb: 每个数据库中能够使用的最大vnode个数。
|
||||||
- arbitrator: 系统中裁决器的end point,缺省为空
|
- arbitrator: 系统中裁决器的end point,缺省为空
|
||||||
- timezone:时区。从系统中动态获取当前的时区设置。
|
- timezone、locale、charset 的配置见客户端配置。
|
||||||
- locale:系统区位信息及编码格式。系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置。
|
|
||||||
- charset:字符集编码。系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置。
|
|
||||||
|
|
||||||
## 客户端配置
|
## 客户端配置
|
||||||
|
|
||||||
TDengine系统的前台交互客户端应用程序为taos,它与taosd共享同一个配置文件taos.cfg。运行taos时,使用参数-c指定配置文件目录,如taos -c /home/cfg,表示使用/home/cfg/目录下的taos.cfg配置文件中的参数,缺省目录是/etc/taos。更多taos的使用方法请见[Shell命令行程序](#_TDengine_Shell命令行程序)。本节主要讲解taos客户端应用在配置文件taos.cfg文件中使用到的参数。
|
TDengine系统的前台交互客户端应用程序为taos,它与taosd共享同一个配置文件taos.cfg。运行taos时,使用参数-c指定配置文件目录,如taos -c /home/cfg,表示使用/home/cfg/目录下的taos.cfg配置文件中的参数,缺省目录是/etc/taos。本节主要说明 taos 客户端应用在配置文件 taos.cfg 文件中使用到的参数。
|
||||||
|
|
||||||
客户端配置参数列表及解释
|
客户端配置参数
|
||||||
|
|
||||||
- firstEp: taos启动时,主动连接的集群中第一个taosd实例的end point, 缺省值为 localhost:6030。
|
- firstEp: taos启动时,主动连接的集群中第一个taosd实例的end point, 缺省值为 localhost:6030。
|
||||||
- secondEp: taos启动时,如果first连接不上,尝试连接集群中第二个taosd实例的end point, 缺省值为空。
|
- secondEp: taos启动时,如果first连接不上,尝试连接集群中第二个taosd实例的end point, 缺省值为空。
|
||||||
- charset:字符集编码。系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置。
|
- locale
|
||||||
- locale:系统区位信息及编码格式。系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置。
|
|
||||||
- maxBinaryDisplayWidth:Shell中binary 和 nchar字段的显示宽度上限,超过此限制的部分将被隐藏。默认值:30。可在 shell 中通过命令 set max_binary_display_width *nn* 动态修改此选项。
|
|
||||||
|
|
||||||
日志的配置参数,与server的配置参数完全一样。
|
> 默认值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置
|
||||||
|
|
||||||
|
TDengine为存储中文、日文、韩文等非ASCII编码的宽字符,提供一种专门的字段类型nchar。写入nchar字段的数据将统一采用UCS4-LE格式进行编码并发送到服务器。需要注意的是,编码正确性是客户端来保证。因此,如果用户想要正常使用nchar字段来存储诸如中文、日文、韩文等非ASCII字符,需要正确设置客户端的编码格式。
|
||||||
|
|
||||||
|
客户端的输入的字符均采用操作系统当前默认的编码格式,在Linux系统上多为UTF-8,部分中文系统编码则可能是GB18030或GBK等。在docker环境中默认的编码是POSIX。在中文版Windows系统中,编码则是CP936。客户端需要确保正确设置自己所使用的字符集,即客户端运行的操作系统当前编码字符集,才能保证nchar中的数据正确转换为UCS4-LE编码格式。
|
||||||
|
|
||||||
|
在 Linux 中 locale 的命名规则为: <语言>_<地区>.<字符集编码> 如:zh_CN.UTF-8,zh代表中文,CN代表大陆地区,UTF-8表示字符集。字符集编码为客户端正确解析本地字符串提供编码转换的说明。Linux系统与 Mac OSX 系统可以通过设置locale来确定系统的字符编码,由于Windows使用的locale中不是POSIX标准的locale格式,因此在Windows下需要采用另一个配置参数charset来指定字符编码。在Linux 系统中也可以使用charset来指定字符编码。
|
||||||
|
|
||||||
|
- charset
|
||||||
|
|
||||||
|
> 默认值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置
|
||||||
|
|
||||||
|
如果配置文件中不设置charset,在Linux系统中,taos在启动时候,自动读取系统当前的locale信息,并从locale信息中解析提取charset编码格式。如果自动读取locale信息失败,则尝试读取charset配置,如果读取charset配置也失败,则中断启动过程。
|
||||||
|
|
||||||
|
在Linux系统中,locale信息包含了字符编码信息,因此正确设置了Linux系统locale以后可以不用再单独设置charset。例如:
|
||||||
|
```
|
||||||
|
locale zh_CN.UTF-8
|
||||||
|
```
|
||||||
|
在Windows系统中,无法从locale获取系统当前编码。如果无法从配置文件中读取字符串编码信息,taos默认设置为字符编码为CP936。其等效在配置文件中添加如下配置:
|
||||||
|
```
|
||||||
|
charset CP936
|
||||||
|
```
|
||||||
|
如果需要调整字符编码,请查阅当前操作系统使用的编码,并在配置文件中正确设置。
|
||||||
|
|
||||||
|
在Linux系统中,如果用户同时设置了locale和字符集编码charset,并且locale和charset的不一致,后设置的值将覆盖前面设置的值。
|
||||||
|
```
|
||||||
|
locale zh_CN.UTF-8
|
||||||
|
charset GBK
|
||||||
|
```
|
||||||
|
则charset的有效值是GBK。
|
||||||
|
```
|
||||||
|
charset GBK
|
||||||
|
locale zh_CN.UTF-8
|
||||||
|
```
|
||||||
|
charset的有效值是UTF-8。
|
||||||
|
|
||||||
|
日志的配置参数,与server 的配置参数完全一样。
|
||||||
|
|
||||||
|
- timezone
|
||||||
|
|
||||||
|
默认值:从系统中动态获取当前的时区设置
|
||||||
|
|
||||||
|
客户端运行系统所在的时区。为应对多时区的数据写入和查询问题,TDengine 采用 Unix 时间戳(Unix Timestamp)来记录和存储时间戳。Unix 时间戳的特点决定了任一时刻不论在任何时区,产生的时间戳均一致。需要注意的是,Unix时间戳是在客户端完成转换和记录。为了确保客户端其他形式的时间转换为正确的 Unix 时间戳,需要设置正确的时区。
|
||||||
|
|
||||||
|
在Linux系统中,客户端会自动读取系统设置的时区信息。用户也可以采用多种方式在配置文件设置时区。例如:
|
||||||
|
```
|
||||||
|
timezone UTC-8
|
||||||
|
timezone GMT-8
|
||||||
|
timezone Asia/Shanghai
|
||||||
|
```
|
||||||
|
均是合法的设置东八区时区的格式。
|
||||||
|
|
||||||
|
时区的设置对于查询和写入SQL语句中非Unix时间戳的内容(时间戳字符串、关键词now的解析)产生影响。例如:
|
||||||
|
```
|
||||||
|
SELECT count(*) FROM table_name WHERE TS<'2019-04-11 12:01:08';
|
||||||
|
```
|
||||||
|
在东八区,SQL语句等效于
|
||||||
|
```
|
||||||
|
SELECT count(*) FROM table_name WHERE TS<1554955268000;
|
||||||
|
```
|
||||||
|
在UTC时区,SQL语句等效于
|
||||||
|
```
|
||||||
|
SELECT count(*) FROM table_name WHERE TS<1554984068000;
|
||||||
|
```
|
||||||
|
为了避免使用字符串时间格式带来的不确定性,也可以直接使用Unix时间戳。此外,还可以在SQL语句中使用带有时区的时间戳字符串,例如:RFC3339格式的时间戳字符串,2013-04-12T15:52:01.123+08:00或者ISO-8601格式时间戳字符串2013-04-12T15:52:01.123+0800。上述两个字符串转化为Unix时间戳不受系统所在时区的影响。
|
||||||
|
|
||||||
启动taos时,也可以从命令行指定一个taosd实例的end point,否则就从taos.cfg读取。
|
启动taos时,也可以从命令行指定一个taosd实例的end point,否则就从taos.cfg读取。
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
多个taosd的运行实例可以组成一个集群,以保证TDengine的高可靠运行,并提供水平扩展能力。要了解TDengine 2.0的集群管理,需要对集群的基本概念有所了解,请看TDengine 2.0整体架构一章。而且在安装集群之前,请按照[《立即开始》](https://www.taosdata.com/cn/getting-started20/)一章安装并体验过单节点功能。
|
多个taosd的运行实例可以组成一个集群,以保证TDengine的高可靠运行,并提供水平扩展能力。要了解TDengine 2.0的集群管理,需要对集群的基本概念有所了解,请看TDengine 2.0整体架构一章。而且在安装集群之前,请按照[《立即开始》](https://www.taosdata.com/cn/getting-started20/)一章安装并体验过单节点功能。
|
||||||
|
|
||||||
集群的每个节点是由End Point来唯一标识的,End Point是由FQDN(Fully Qualified Domain Name)外加Port组成,比如 h1.taosdata.com:6030。一般FQDN就是服务器的hostname,可通过Linux命令`hostname -f`获取。端口是这个节点对外服务的端口号,缺省是6030,但可以通过taos.cfg里配置参数serverPort进行修改。一个节点可能配置了多个hostname, TDengine会自动获取第一个,但也可以通过taos.cfg里配置参数fqdn进行指定。如果习惯IP地址直接访问,可以将参数fqdn设置为本节点的IP地址。
|
集群的每个节点是由End Point来唯一标识的,End Point是由FQDN(Fully Qualified Domain Name)外加Port组成,比如 h1.taosdata.com:6030。一般FQDN就是服务器的hostname,可通过Linux命令`hostname -f`获取,FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。端口是这个节点对外服务的端口号,缺省是6030,但可以通过taos.cfg里配置参数serverPort进行修改。一个节点可能配置了多个hostname, TDengine会自动获取第一个,但也可以通过taos.cfg里配置参数fqdn进行指定。如果习惯IP地址直接访问,可以将参数fqdn设置为本节点的IP地址。
|
||||||
|
|
||||||
TDengine的集群管理极其简单,除添加和删除节点需要人工干预之外,其他全部是自动完成,最大程度的降低了运维的工作量。本章对集群管理的操作做详细的描述。
|
TDengine的集群管理极其简单,除添加和删除节点需要人工干预之外,其他全部是自动完成,最大程度的降低了运维的工作量。本章对集群管理的操作做详细的描述。
|
||||||
|
|
||||||
## 准备工作
|
## 准备工作
|
||||||
|
|
||||||
**第一步**:如果搭建集群的节点中,存有之前的测试数据、装过1.X的版本,或者装过其他版本的TDengine,请先将其删除,并清空所有数据,具体步骤请参考博客[《TDengine多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html )
|
**第一步**:如果搭建集群的节点中,存有之前的测试数据、装过1.X的版本,或者装过其他版本的TDengine,请先将其删除,并清空所有数据,具体步骤请参考博客[《TDengine多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html )
|
||||||
|
**注意1:**因为FQDN的信息会写进文件,如果之前没有配置或者更改FQDN,且启动了TDengine。请一定在确保数据无用或者备份的前提下,清理一下之前的数据(rm -rf /var/lib/taos/);
|
||||||
|
**注意2:**客户端也需要配置,确保它可以正确解析每个节点的FQDN配置,不管是通过DNS服务,还是 Host 文件。
|
||||||
|
|
||||||
**第二步**:建议关闭防火墙,至少保证端口:6030 - 6042的TCP和UDP端口都是开放的。**强烈建议**先关闭防火墙,集群搭建完毕之后,再来配置端口;
|
**第二步**:建议关闭防火墙,至少保证端口:6030 - 6042的TCP和UDP端口都是开放的。**强烈建议**先关闭防火墙,集群搭建完毕之后,再来配置端口;
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ TDengine的集群管理极其简单,除添加和删除节点需要人工干预
|
||||||
**第五步**:修改TDengine的配置文件(所有节点的文件/etc/taos/taos.cfg都需要修改)。假设准备启动的第一个节点End Point为 h1.taosdata.com:6030, 那么以下几个参数与集群相关:
|
**第五步**:修改TDengine的配置文件(所有节点的文件/etc/taos/taos.cfg都需要修改)。假设准备启动的第一个节点End Point为 h1.taosdata.com:6030, 那么以下几个参数与集群相关:
|
||||||
|
|
||||||
```
|
```
|
||||||
// firstEp 是每个节点启动后连接的第一个节点
|
// firstEp 集群中所有节点的配置都是一致的,对其第一次访问后,就获得了整个集群的信息
|
||||||
firstEp h1.taosdata.com:6030
|
firstEp h1.taosdata.com:6030
|
||||||
|
|
||||||
// 配置本节点的FQDN,如果本机只有一个hostname, 无需配置
|
// 配置本节点的FQDN,如果本机只有一个hostname, 无需配置
|
||||||
|
@ -32,7 +34,7 @@ fqdn h1.taosdata.com
|
||||||
// 配置本节点的端口号,缺省是6030
|
// 配置本节点的端口号,缺省是6030
|
||||||
serverPort 6030
|
serverPort 6030
|
||||||
|
|
||||||
// 副本数为偶数的时候,需要配置,请参考《Arbitrator的使用》的部分
|
// 服务端节点数为偶数的时候,需要配置,请参考《Arbitrator的使用》的部分
|
||||||
arbitrator ha.taosdata.com:6042
|
arbitrator ha.taosdata.com:6042
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
3. 在服务器,执行 `systemctl status taosd` 检查*taosd*运行状态。如果没有运行,启动*taosd*
|
3. 在服务器,执行 `systemctl status taosd` 检查*taosd*运行状态。如果没有运行,启动*taosd*
|
||||||
|
|
||||||
4. 确认客户端连接时指定了正确的服务器FQDN (Fully Qualified Domain Name(可在服务器上执行Linux命令hostname -f获得)
|
4. 确认客户端连接时指定了正确的服务器FQDN (Fully Qualified Domain Name(可在服务器上执行Linux命令hostname -f获得)),FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。
|
||||||
|
|
||||||
5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件
|
5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
## 6. 遇到错误“Unexpected generic error in RPC”或者"TDengine Error: Unable to resolve FQDN", 我怎么办?
|
## 6. 遇到错误“Unexpected generic error in RPC”或者"TDengine Error: Unable to resolve FQDN", 我怎么办?
|
||||||
产生这个错误,是由于客户端或数据节点无法解析FQDN(Fully Qualified Domain Name)导致。对于TAOS Shell或客户端应用,请做如下检查:
|
产生这个错误,是由于客户端或数据节点无法解析FQDN(Fully Qualified Domain Name)导致。对于TAOS Shell或客户端应用,请做如下检查:
|
||||||
|
|
||||||
1. 请检查连接的服务器的FQDN是否正确
|
1. 请检查连接的服务器的FQDN是否正确,FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。
|
||||||
2. 如果网络配置有DNS server, 请检查是否正常工作
|
2. 如果网络配置有DNS server, 请检查是否正常工作
|
||||||
3. 如果网络没有配置DNS server, 请检查客户端所在机器的hosts文件,查看该FQDN是否配置,并是否有正确的IP地址。
|
3. 如果网络没有配置DNS server, 请检查客户端所在机器的hosts文件,查看该FQDN是否配置,并是否有正确的IP地址。
|
||||||
4. 如果网络配置OK,从客户端所在机器,你需要能Ping该连接的FQDN,否则客户端是无法链接服务器的
|
4. 如果网络配置OK,从客户端所在机器,你需要能Ping该连接的FQDN,否则客户端是无法链接服务器的
|
||||||
|
|
|
@ -2090,6 +2090,10 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp;
|
SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp;
|
||||||
|
if (pRetrieve == NULL) {
|
||||||
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
return pRes->code;
|
||||||
|
}
|
||||||
|
|
||||||
pRes->numOfRows = htonl(pRetrieve->numOfRows);
|
pRes->numOfRows = htonl(pRetrieve->numOfRows);
|
||||||
pRes->precision = htons(pRetrieve->precision);
|
pRes->precision = htons(pRetrieve->precision);
|
||||||
|
|
|
@ -93,14 +93,13 @@
|
||||||
<version>3.6.1</version>
|
<version>3.6.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<encoding>UTF-8</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
<source>11</source>
|
<source>8</source>
|
||||||
<target>11</target>
|
<target>8</target>
|
||||||
<debug>true</debug>
|
<debug>true</debug>
|
||||||
<showDeprecation>true</showDeprecation>
|
<showDeprecation>true</showDeprecation>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
|
|
@ -57,9 +57,9 @@ public class TSDBConnection implements Connection {
|
||||||
File cfgDir = loadConfigDir(info.getProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR));
|
File cfgDir = loadConfigDir(info.getProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR));
|
||||||
File cfgFile = cfgDir.listFiles((dir, name) -> "taos.cfg".equalsIgnoreCase(name))[0];
|
File cfgFile = cfgDir.listFiles((dir, name) -> "taos.cfg".equalsIgnoreCase(name))[0];
|
||||||
List<String> endpoints = loadConfigEndpoints(cfgFile);
|
List<String> endpoints = loadConfigEndpoints(cfgFile);
|
||||||
if (!endpoints.isEmpty()){
|
if (!endpoints.isEmpty()) {
|
||||||
info.setProperty(TSDBDriver.PROPERTY_KEY_HOST,endpoints.get(0).split(":")[0]);
|
info.setProperty(TSDBDriver.PROPERTY_KEY_HOST, endpoints.get(0).split(":")[0]);
|
||||||
info.setProperty(TSDBDriver.PROPERTY_KEY_PORT,endpoints.get(0).split(":")[1]);
|
info.setProperty(TSDBDriver.PROPERTY_KEY_PORT, endpoints.get(0).split(":")[1]);
|
||||||
}
|
}
|
||||||
//load taos.cfg end
|
//load taos.cfg end
|
||||||
|
|
||||||
|
@ -69,15 +69,15 @@ public class TSDBConnection implements Connection {
|
||||||
info.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD));
|
info.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> loadConfigEndpoints(File cfgFile){
|
private List<String> loadConfigEndpoints(File cfgFile) {
|
||||||
List<String> endpoints = new ArrayList<>();
|
List<String> endpoints = new ArrayList<>();
|
||||||
try(BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) {
|
try (BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) {
|
||||||
String line = null;
|
String line = null;
|
||||||
while ((line = reader.readLine())!=null){
|
while ((line = reader.readLine()) != null) {
|
||||||
if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")){
|
if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")) {
|
||||||
endpoints.add(line.substring(line.indexOf('p')+1).trim());
|
endpoints.add(line.substring(line.indexOf('p') + 1).trim());
|
||||||
}
|
}
|
||||||
if (endpoints.size()>1)
|
if (endpoints.size() > 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
|
@ -91,7 +91,7 @@ public class TSDBConnection implements Connection {
|
||||||
/**
|
/**
|
||||||
* @param cfgDirPath
|
* @param cfgDirPath
|
||||||
* @return return the config dir
|
* @return return the config dir
|
||||||
* **/
|
**/
|
||||||
private File loadConfigDir(String cfgDirPath) {
|
private File loadConfigDir(String cfgDirPath) {
|
||||||
if (cfgDirPath == null)
|
if (cfgDirPath == null)
|
||||||
return loadDefaultConfigDir();
|
return loadDefaultConfigDir();
|
||||||
|
@ -103,8 +103,8 @@ public class TSDBConnection implements Connection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return search the default config dir, if the config dir is not exist will return null
|
* @return search the default config dir, if the config dir is not exist will return null
|
||||||
* */
|
*/
|
||||||
private File loadDefaultConfigDir(){
|
private File loadDefaultConfigDir() {
|
||||||
File cfgDir;
|
File cfgDir;
|
||||||
File cfgDir_linux = new File("/etc/taos");
|
File cfgDir_linux = new File("/etc/taos");
|
||||||
cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null;
|
cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null;
|
||||||
|
@ -132,7 +132,9 @@ public class TSDBConnection implements Connection {
|
||||||
|
|
||||||
public Statement createStatement() throws SQLException {
|
public Statement createStatement() throws SQLException {
|
||||||
if (!this.connector.isClosed()) {
|
if (!this.connector.isClosed()) {
|
||||||
return new TSDBStatement(this.connector);
|
TSDBStatement statement = new TSDBStatement(this, this.connector);
|
||||||
|
statement.setConnection(this);
|
||||||
|
return statement;
|
||||||
} else {
|
} else {
|
||||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
}
|
}
|
||||||
|
@ -153,7 +155,7 @@ public class TSDBConnection implements Connection {
|
||||||
|
|
||||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||||
if (!this.connector.isClosed()) {
|
if (!this.connector.isClosed()) {
|
||||||
return new TSDBPreparedStatement(this.connector, sql);
|
return new TSDBPreparedStatement(this, this.connector, sql);
|
||||||
} else {
|
} else {
|
||||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
private SavedPreparedStatement savedPreparedStatement;
|
private SavedPreparedStatement savedPreparedStatement;
|
||||||
|
|
||||||
TSDBPreparedStatement(TSDBJNIConnector connecter, String sql) {
|
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
|
||||||
super(connecter);
|
super(connection, connecter);
|
||||||
init(sql);
|
init(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,14 @@ import java.util.List;
|
||||||
public class TSDBStatement implements Statement {
|
public class TSDBStatement implements Statement {
|
||||||
private TSDBJNIConnector connecter = null;
|
private TSDBJNIConnector connecter = null;
|
||||||
|
|
||||||
/** To store batched commands */
|
/**
|
||||||
|
* To store batched commands
|
||||||
|
*/
|
||||||
protected List<String> batchedArgs;
|
protected List<String> batchedArgs;
|
||||||
|
|
||||||
/** Timeout for a query */
|
/**
|
||||||
|
* Timeout for a query
|
||||||
|
*/
|
||||||
protected int queryTimeout = 0;
|
protected int queryTimeout = 0;
|
||||||
|
|
||||||
private Long pSql = 0l;
|
private Long pSql = 0l;
|
||||||
|
@ -35,7 +39,14 @@ public class TSDBStatement implements Statement {
|
||||||
private boolean isClosed = true;
|
private boolean isClosed = true;
|
||||||
private int affectedRows = 0;
|
private int affectedRows = 0;
|
||||||
|
|
||||||
TSDBStatement(TSDBJNIConnector connecter) {
|
private TSDBConnection connection;
|
||||||
|
|
||||||
|
public void setConnection(TSDBConnection connection) {
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSDBStatement(TSDBConnection connection, TSDBJNIConnector connecter) {
|
||||||
|
this.connection = connection;
|
||||||
this.connecter = connecter;
|
this.connecter = connecter;
|
||||||
this.isClosed = false;
|
this.isClosed = false;
|
||||||
}
|
}
|
||||||
|
@ -256,6 +267,8 @@ public class TSDBStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
|
if (this.connecter != null)
|
||||||
|
return this.connection;
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.sql.SQLException;
|
||||||
public class SqlSyntaxValidator {
|
public class SqlSyntaxValidator {
|
||||||
|
|
||||||
private TSDBConnection tsdbConnection;
|
private TSDBConnection tsdbConnection;
|
||||||
|
|
||||||
public SqlSyntaxValidator(Connection connection) {
|
public SqlSyntaxValidator(Connection connection) {
|
||||||
this.tsdbConnection = (TSDBConnection) connection;
|
this.tsdbConnection = (TSDBConnection) connection;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ public class BaseTest {
|
||||||
private static boolean testCluster = false;
|
private static boolean testCluster = false;
|
||||||
private static TDNodes nodes = new TDNodes();
|
private static TDNodes nodes = new TDNodes();
|
||||||
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setupEnv() {
|
public static void setupEnv() {
|
||||||
try{
|
try{
|
||||||
|
@ -19,11 +18,9 @@ public class BaseTest {
|
||||||
nodes.getTDNode(1).setRunning(1);
|
nodes.getTDNode(1).setRunning(1);
|
||||||
nodes.stop(1);
|
nodes.stop(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.setTestCluster(testCluster);
|
nodes.setTestCluster(testCluster);
|
||||||
nodes.deploy(1);
|
nodes.deploy(1);
|
||||||
nodes.start(1);
|
nodes.start(1);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,11 @@ import org.junit.Test;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.*;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class BatchInsertTest extends BaseTest {
|
public class BatchInsertTest extends BaseTest {
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ public class SelectTest extends BaseTest {
|
||||||
statement.executeUpdate("drop database if exists " + dbName);
|
statement.executeUpdate("drop database if exists " + dbName);
|
||||||
statement.executeUpdate("create database if not exists " + dbName);
|
statement.executeUpdate("create database if not exists " + dbName);
|
||||||
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
|
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -66,6 +65,5 @@ public class SelectTest extends BaseTest {
|
||||||
statement.close();
|
statement.close();
|
||||||
connection.close();
|
connection.close();
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@ import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class SubscribeTest extends BaseTest {
|
public class SubscribeTest extends BaseTest {
|
||||||
Connection connection = null;
|
Connection connection = null;
|
||||||
Statement statement = null;
|
Statement statement = null;
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.lib.TSDBCommon;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class BatchInsertTest {
|
||||||
|
|
||||||
|
static String host = "localhost";
|
||||||
|
static String dbName = "test";
|
||||||
|
static String stbName = "meters";
|
||||||
|
static int numOfTables = 30;
|
||||||
|
final static int numOfRecordsPerTable = 1000;
|
||||||
|
static long ts = 1496732686000l;
|
||||||
|
final static String tablePrefix = "t";
|
||||||
|
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
try {
|
||||||
|
connection = TSDBCommon.getConn(host);
|
||||||
|
TSDBCommon.createDatabase(connection, dbName);
|
||||||
|
TSDBCommon.createStable(connection, stbName);
|
||||||
|
TSDBCommon.createTables(connection, numOfTables, stbName, tablePrefix);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBatchInsert(){
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(numOfTables);
|
||||||
|
for (int i = 0; i < numOfTables; i++) {
|
||||||
|
final int index = i;
|
||||||
|
executorService.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
Statement statement = connection.createStatement(); // get statement
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("INSERT INTO " + tablePrefix + index + " VALUES");
|
||||||
|
Random rand = new Random();
|
||||||
|
for (int j = 1; j <= numOfRecordsPerTable; j++) {
|
||||||
|
sb.append("(" + (ts + j) + ", ");
|
||||||
|
sb.append(rand.nextInt(100) + ", ");
|
||||||
|
sb.append(rand.nextInt(100) + ", ");
|
||||||
|
sb.append(rand.nextInt(100) + ")");
|
||||||
|
}
|
||||||
|
statement.addBatch(sb.toString());
|
||||||
|
statement.executeBatch();
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("Thread " + index + " takes " + (endTime - startTime) + " microseconds");
|
||||||
|
connection.commit();
|
||||||
|
statement.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
executorService.shutdown();
|
||||||
|
try {
|
||||||
|
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
ResultSet rs = statement.executeQuery("select * from meters");
|
||||||
|
int num = 0;
|
||||||
|
while (rs.next()) {
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
assertEquals(num, numOfTables * numOfRecordsPerTable);
|
||||||
|
rs.close();
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() {
|
||||||
|
try {
|
||||||
|
if (connection != null)
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.taosdata.jdbc.lib;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class TSDBCommon {
|
||||||
|
|
||||||
|
public static Connection getConn(String host) throws SQLException, ClassNotFoundException {
|
||||||
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
return DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createDatabase(Connection connection, String dbName) throws SQLException {
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeUpdate("drop database if exists " + dbName);
|
||||||
|
statement.executeUpdate("create database if not exists " + dbName);
|
||||||
|
statement.executeUpdate("use " + dbName);
|
||||||
|
statement.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createStable(Connection connection, String stbName) throws SQLException {
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
String createTableSql = "create table " + stbName + "(ts timestamp, f1 int, f2 int, f3 int) tags(areaid int, loc binary(20))";
|
||||||
|
statement.executeUpdate(createTableSql);
|
||||||
|
statement.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createTables(Connection connection, int numOfTables, String stbName,String tablePrefix) throws SQLException {
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
for(int i = 0; i < numOfTables; i++) {
|
||||||
|
String loc = i % 2 == 0 ? "beijing" : "shanghai";
|
||||||
|
String createSubTalbesSql = "create table " + tablePrefix + i + " using " + stbName + " tags(" + i + ", '" + loc + "')";
|
||||||
|
statement.executeUpdate(createSubTalbesSql);
|
||||||
|
}
|
||||||
|
statement.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,11 +16,13 @@
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
|
#include "taosmsg.h"
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "mnode.h"
|
#include "mnode.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "tmqtt.h"
|
#include "tmqtt.h"
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
|
#include "dnode.h"
|
||||||
#include "dnodeInt.h"
|
#include "dnodeInt.h"
|
||||||
#include "dnodeModule.h"
|
#include "dnodeModule.h"
|
||||||
|
|
||||||
|
@ -129,17 +131,34 @@ void dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
||||||
for (int32_t module = TSDB_MOD_MNODE; module < TSDB_MOD_HTTP; ++module) {
|
for (int32_t module = TSDB_MOD_MNODE; module < TSDB_MOD_HTTP; ++module) {
|
||||||
bool enableModule = moduleStatus & (1 << module);
|
bool enableModule = moduleStatus & (1 << module);
|
||||||
if (!tsModule[module].enable && enableModule) {
|
if (!tsModule[module].enable && enableModule) {
|
||||||
dInfo("module status:%u is received, start %s module", tsModuleStatus, tsModule[module].name);
|
dInfo("module status:%u is set, start %s module", moduleStatus, tsModule[module].name);
|
||||||
tsModule[module].enable = true;
|
tsModule[module].enable = true;
|
||||||
dnodeSetModuleStatus(module);
|
dnodeSetModuleStatus(module);
|
||||||
(*tsModule[module].startFp)();
|
(*tsModule[module].startFp)();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsModule[module].enable && !enableModule) {
|
if (tsModule[module].enable && !enableModule) {
|
||||||
dInfo("module status:%u is received, stop %s module", tsModuleStatus, tsModule[module].name);
|
dInfo("module status:%u is set, stop %s module", moduleStatus, tsModule[module].name);
|
||||||
tsModule[module].enable = false;
|
tsModule[module].enable = false;
|
||||||
dnodeUnSetModuleStatus(module);
|
dnodeUnSetModuleStatus(module);
|
||||||
(*tsModule[module].stopFp)();
|
(*tsModule[module].stopFp)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dnodeCheckMnodeStarting() {
|
||||||
|
if (tsModuleStatus & TSDB_MOD_MNODE) return false;
|
||||||
|
|
||||||
|
SDMMnodeInfos *mnodes = dnodeGetMnodeInfos();
|
||||||
|
for (int32_t i = 0; i < mnodes->nodeNum; ++i) {
|
||||||
|
SDMMnodeInfo *node = &mnodes->nodeInfos[i];
|
||||||
|
if (node->nodeId == dnodeGetDnodeId()) {
|
||||||
|
uint32_t moduleStatus = tsModuleStatus | (1 << TSDB_MOD_MNODE);;
|
||||||
|
dInfo("start mnode module, module status:%d, new status:%d", tsModuleStatus, moduleStatus);
|
||||||
|
dnodeProcessModuleStatus(moduleStatus);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ void dnodeGetMnodeEpSetForPeer(void *epSet);
|
||||||
void dnodeGetMnodeEpSetForShell(void *epSet);
|
void dnodeGetMnodeEpSetForShell(void *epSet);
|
||||||
void * dnodeGetMnodeInfos();
|
void * dnodeGetMnodeInfos();
|
||||||
int32_t dnodeGetDnodeId();
|
int32_t dnodeGetDnodeId();
|
||||||
|
bool dnodeCheckMnodeStarting();
|
||||||
|
|
||||||
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
|
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
|
||||||
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
|
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
|
||||||
|
|
|
@ -103,6 +103,9 @@ typedef struct {
|
||||||
|
|
||||||
typedef void* tsync_h;
|
typedef void* tsync_h;
|
||||||
|
|
||||||
|
int32_t syncInit();
|
||||||
|
void syncCleanUp();
|
||||||
|
|
||||||
tsync_h syncStart(const SSyncInfo *);
|
tsync_h syncStart(const SSyncInfo *);
|
||||||
void syncStop(tsync_h shandle);
|
void syncStop(tsync_h shandle);
|
||||||
int32_t syncReconfig(tsync_h shandle, const SSyncCfg *);
|
int32_t syncReconfig(tsync_h shandle, const SSyncCfg *);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "tqueue.h"
|
#include "tqueue.h"
|
||||||
#include "twal.h"
|
#include "twal.h"
|
||||||
#include "tsync.h"
|
#include "tsync.h"
|
||||||
|
#include "ttimer.h"
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "dnode.h"
|
#include "dnode.h"
|
||||||
#include "mnode.h"
|
#include "mnode.h"
|
||||||
|
@ -64,6 +65,7 @@ typedef struct _SSdbTable {
|
||||||
int32_t (*encodeFp)(SSdbOper *pOper);
|
int32_t (*encodeFp)(SSdbOper *pOper);
|
||||||
int32_t (*destroyFp)(SSdbOper *pOper);
|
int32_t (*destroyFp)(SSdbOper *pOper);
|
||||||
int32_t (*restoredFp)();
|
int32_t (*restoredFp)();
|
||||||
|
pthread_mutex_t mutex;
|
||||||
} SSdbTable;
|
} SSdbTable;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -88,6 +90,8 @@ typedef struct {
|
||||||
SSdbWriteWorker *writeWorker;
|
SSdbWriteWorker *writeWorker;
|
||||||
} SSdbWriteWorkerPool;
|
} SSdbWriteWorkerPool;
|
||||||
|
|
||||||
|
extern void * tsMnodeTmr;
|
||||||
|
static void * tsUpdateSyncTmr;
|
||||||
static SSdbObject tsSdbObj = {0};
|
static SSdbObject tsSdbObj = {0};
|
||||||
static taos_qset tsSdbWriteQset;
|
static taos_qset tsSdbWriteQset;
|
||||||
static taos_qall tsSdbWriteQall;
|
static taos_qall tsSdbWriteQall;
|
||||||
|
@ -290,11 +294,17 @@ static void sdbConfirmForward(void *ahandle, void *param, int32_t code) {
|
||||||
taosFreeQitem(pOper);
|
taosFreeQitem(pOper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sdbUpdateSyncTmrFp(void *param, void *tmrId) { sdbUpdateSync(); }
|
||||||
|
|
||||||
void sdbUpdateSync() {
|
void sdbUpdateSync() {
|
||||||
if (!mnodeIsRunning()) {
|
if (!mnodeIsRunning()) {
|
||||||
mDebug("mnode not start yet, update sync info later");
|
mDebug("mnode not start yet, update sync info later");
|
||||||
|
if (dnodeCheckMnodeStarting()) {
|
||||||
|
taosTmrReset(sdbUpdateSyncTmrFp, 1000, NULL, tsMnodeTmr, &tsUpdateSyncTmr);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mDebug("update sync info in sdb");
|
||||||
|
|
||||||
SSyncCfg syncCfg = {0};
|
SSyncCfg syncCfg = {0};
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
|
@ -387,8 +397,6 @@ int32_t sdbInit() {
|
||||||
tsSdbObj.role = TAOS_SYNC_ROLE_MASTER;
|
tsSdbObj.role = TAOS_SYNC_ROLE_MASTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdbUpdateSync();
|
|
||||||
|
|
||||||
tsSdbObj.status = SDB_STATUS_SERVING;
|
tsSdbObj.status = SDB_STATUS_SERVING;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -448,8 +456,9 @@ static void *sdbGetRowMeta(SSdbTable *pTable, void *key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void **ppRow = (void **)taosHashGet(pTable->iHandle, key, keySize);
|
void **ppRow = (void **)taosHashGet(pTable->iHandle, key, keySize);
|
||||||
if (ppRow == NULL) return NULL;
|
if (ppRow != NULL) return *ppRow;
|
||||||
return *ppRow;
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *sdbGetRowMetaFromObj(SSdbTable *pTable, void *key) {
|
static void *sdbGetRowMetaFromObj(SSdbTable *pTable, void *key) {
|
||||||
|
@ -457,13 +466,14 @@ static void *sdbGetRowMetaFromObj(SSdbTable *pTable, void *key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *sdbGetRow(void *handle, void *key) {
|
void *sdbGetRow(void *handle, void *key) {
|
||||||
|
SSdbTable *pTable = handle;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pTable->mutex);
|
||||||
void *pRow = sdbGetRowMeta(handle, key);
|
void *pRow = sdbGetRowMeta(handle, key);
|
||||||
if (pRow) {
|
if (pRow) sdbIncRef(handle, pRow);
|
||||||
sdbIncRef(handle, pRow);
|
pthread_mutex_unlock(&pTable->mutex);
|
||||||
|
|
||||||
return pRow;
|
return pRow;
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *sdbGetRowFromObj(SSdbTable *pTable, void *key) {
|
static void *sdbGetRowFromObj(SSdbTable *pTable, void *key) {
|
||||||
|
@ -478,7 +488,9 @@ static int32_t sdbInsertHash(SSdbTable *pTable, SSdbOper *pOper) {
|
||||||
keySize = strlen((char *)key);
|
keySize = strlen((char *)key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pTable->mutex);
|
||||||
taosHashPut(pTable->iHandle, key, keySize, &pOper->pObj, sizeof(int64_t));
|
taosHashPut(pTable->iHandle, key, keySize, &pOper->pObj, sizeof(int64_t));
|
||||||
|
pthread_mutex_unlock(&pTable->mutex);
|
||||||
|
|
||||||
sdbIncRef(pTable, pOper->pObj);
|
sdbIncRef(pTable, pOper->pObj);
|
||||||
atomic_add_fetch_32(&pTable->numOfRows, 1);
|
atomic_add_fetch_32(&pTable->numOfRows, 1);
|
||||||
|
@ -519,7 +531,10 @@ static int32_t sdbDeleteHash(SSdbTable *pTable, SSdbOper *pOper) {
|
||||||
keySize = strlen((char *)key);
|
keySize = strlen((char *)key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pTable->mutex);
|
||||||
taosHashRemove(pTable->iHandle, key, keySize);
|
taosHashRemove(pTable->iHandle, key, keySize);
|
||||||
|
pthread_mutex_unlock(&pTable->mutex);
|
||||||
|
|
||||||
atomic_sub_fetch_32(&pTable->numOfRows, 1);
|
atomic_sub_fetch_32(&pTable->numOfRows, 1);
|
||||||
|
|
||||||
sdbDebug("table:%s, delete record:%s from hash, numOfRows:%" PRId64 ", msg:%p", pTable->tableName,
|
sdbDebug("table:%s, delete record:%s from hash, numOfRows:%" PRId64 ", msg:%p", pTable->tableName,
|
||||||
|
@ -861,6 +876,7 @@ void *sdbOpenTable(SSdbTableDesc *pDesc) {
|
||||||
|
|
||||||
if (pTable == NULL) return NULL;
|
if (pTable == NULL) return NULL;
|
||||||
|
|
||||||
|
pthread_mutex_init(&pTable->mutex, NULL);
|
||||||
tstrncpy(pTable->tableName, pDesc->tableName, SDB_TABLE_LEN);
|
tstrncpy(pTable->tableName, pDesc->tableName, SDB_TABLE_LEN);
|
||||||
pTable->keyType = pDesc->keyType;
|
pTable->keyType = pDesc->keyType;
|
||||||
pTable->tableId = pDesc->tableId;
|
pTable->tableId = pDesc->tableId;
|
||||||
|
@ -908,6 +924,7 @@ void sdbCloseTable(void *handle) {
|
||||||
|
|
||||||
taosHashDestroyIter(pIter);
|
taosHashDestroyIter(pIter);
|
||||||
taosHashCleanup(pTable->iHandle);
|
taosHashCleanup(pTable->iHandle);
|
||||||
|
pthread_mutex_destroy(&pTable->mutex);
|
||||||
|
|
||||||
sdbDebug("table:%s, is closed, numOfTables:%d", pTable->tableName, tsSdbObj.numOfTables);
|
sdbDebug("table:%s, is closed, numOfTables:%d", pTable->tableName, tsSdbObj.numOfTables);
|
||||||
free(pTable);
|
free(pTable);
|
||||||
|
|
|
@ -35,18 +35,14 @@ int tsSyncTcpThreads = 2;
|
||||||
int tsMaxWatchFiles = 500;
|
int tsMaxWatchFiles = 500;
|
||||||
int tsMaxFwdInfo = 200;
|
int tsMaxFwdInfo = 200;
|
||||||
int tsSyncTimer = 1;
|
int tsSyncTimer = 1;
|
||||||
//int sDebugFlag = 135;
|
|
||||||
//char tsArbitrator[TSDB_FQDN_LEN] = {0};
|
|
||||||
|
|
||||||
// module global, not configurable
|
// module global, not configurable
|
||||||
int tsSyncNum; // number of sync in process in whole system
|
int tsSyncNum; // number of sync in process in whole system
|
||||||
char tsNodeFqdn[TSDB_FQDN_LEN];
|
char tsNodeFqdn[TSDB_FQDN_LEN];
|
||||||
|
|
||||||
static int tsNodeNum; // number of nodes in system
|
|
||||||
static ttpool_h tsTcpPool;
|
static ttpool_h tsTcpPool;
|
||||||
static void *syncTmrCtrl = NULL;
|
static void * syncTmrCtrl = NULL;
|
||||||
static void *vgIdHash;
|
static void * vgIdHash;
|
||||||
static pthread_once_t syncModuleInit = PTHREAD_ONCE_INIT;
|
|
||||||
|
|
||||||
// local functions
|
// local functions
|
||||||
static void syncProcessSyncRequest(char *pMsg, SSyncPeer *pPeer);
|
static void syncProcessSyncRequest(char *pMsg, SSyncPeer *pPeer);
|
||||||
|
@ -75,7 +71,7 @@ char* syncRole[] = {
|
||||||
"master"
|
"master"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void syncModuleInitFunc() {
|
int32_t syncInit() {
|
||||||
SPoolInfo info;
|
SPoolInfo info;
|
||||||
|
|
||||||
info.numOfThreads = tsSyncTcpThreads;
|
info.numOfThreads = tsSyncTcpThreads;
|
||||||
|
@ -87,25 +83,52 @@ static void syncModuleInitFunc() {
|
||||||
info.processIncomingConn = syncProcessIncommingConnection;
|
info.processIncomingConn = syncProcessIncommingConnection;
|
||||||
|
|
||||||
tsTcpPool = taosOpenTcpThreadPool(&info);
|
tsTcpPool = taosOpenTcpThreadPool(&info);
|
||||||
if (tsTcpPool == NULL) return;
|
if (tsTcpPool == NULL) {
|
||||||
|
sError("failed to init tcpPool");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
syncTmrCtrl = taosTmrInit(1000, 50, 10000, "SYNC");
|
syncTmrCtrl = taosTmrInit(1000, 50, 10000, "SYNC");
|
||||||
if (syncTmrCtrl == NULL) {
|
if (syncTmrCtrl == NULL) {
|
||||||
|
sError("failed to init tmrCtrl");
|
||||||
taosCloseTcpThreadPool(tsTcpPool);
|
taosCloseTcpThreadPool(tsTcpPool);
|
||||||
tsTcpPool = NULL;
|
tsTcpPool = NULL;
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgIdHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true);
|
vgIdHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true);
|
||||||
if (vgIdHash == NULL) {
|
if (vgIdHash == NULL) {
|
||||||
|
sError("failed to init vgIdHash");
|
||||||
taosTmrCleanUp(syncTmrCtrl);
|
taosTmrCleanUp(syncTmrCtrl);
|
||||||
taosCloseTcpThreadPool(tsTcpPool);
|
taosCloseTcpThreadPool(tsTcpPool);
|
||||||
tsTcpPool = NULL;
|
tsTcpPool = NULL;
|
||||||
syncTmrCtrl = NULL;
|
syncTmrCtrl = NULL;
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tstrncpy(tsNodeFqdn, tsLocalFqdn, sizeof(tsNodeFqdn));
|
tstrncpy(tsNodeFqdn, tsLocalFqdn, sizeof(tsNodeFqdn));
|
||||||
|
sInfo("sync module initialized successfully");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncCleanUp() {
|
||||||
|
if (tsTcpPool) {
|
||||||
|
taosCloseTcpThreadPool(tsTcpPool);
|
||||||
|
tsTcpPool = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syncTmrCtrl) {
|
||||||
|
taosTmrCleanUp(syncTmrCtrl);
|
||||||
|
syncTmrCtrl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vgIdHash) {
|
||||||
|
taosHashCleanup(vgIdHash);
|
||||||
|
vgIdHash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sInfo("sync module is cleaned up");
|
||||||
}
|
}
|
||||||
|
|
||||||
void *syncStart(const SSyncInfo *pInfo) {
|
void *syncStart(const SSyncInfo *pInfo) {
|
||||||
|
@ -118,15 +141,6 @@ void *syncStart(const SSyncInfo *pInfo) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_once(&syncModuleInit, syncModuleInitFunc);
|
|
||||||
if (tsTcpPool == NULL) {
|
|
||||||
free(pNode);
|
|
||||||
syncModuleInit = PTHREAD_ONCE_INIT;
|
|
||||||
sError("failed to init sync module(%s)", tstrerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
atomic_add_fetch_32(&tsNodeNum, 1);
|
|
||||||
tstrncpy(pNode->path, pInfo->path, sizeof(pNode->path));
|
tstrncpy(pNode->path, pInfo->path, sizeof(pNode->path));
|
||||||
pthread_mutex_init(&pNode->mutex, NULL);
|
pthread_mutex_init(&pNode->mutex, NULL);
|
||||||
|
|
||||||
|
@ -148,9 +162,10 @@ void *syncStart(const SSyncInfo *pInfo) {
|
||||||
for (int i = 0; i < pCfg->replica; ++i) {
|
for (int i = 0; i < pCfg->replica; ++i) {
|
||||||
const SNodeInfo *pNodeInfo = pCfg->nodeInfo + i;
|
const SNodeInfo *pNodeInfo = pCfg->nodeInfo + i;
|
||||||
pNode->peerInfo[i] = syncAddPeer(pNode, pNodeInfo);
|
pNode->peerInfo[i] = syncAddPeer(pNode, pNodeInfo);
|
||||||
if ((strcmp(pNodeInfo->nodeFqdn, tsNodeFqdn) == 0) && (pNodeInfo->nodePort == tsSyncPort))
|
if ((strcmp(pNodeInfo->nodeFqdn, tsNodeFqdn) == 0) && (pNodeInfo->nodePort == tsSyncPort)) {
|
||||||
pNode->selfIndex = i;
|
pNode->selfIndex = i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pNode->selfIndex < 0) {
|
if (pNode->selfIndex < 0) {
|
||||||
sInfo("vgId:%d, this node is not configured", pNode->vgId);
|
sInfo("vgId:%d, this node is not configured", pNode->vgId);
|
||||||
|
@ -182,14 +197,15 @@ void *syncStart(const SSyncInfo *pInfo) {
|
||||||
syncAddNodeRef(pNode);
|
syncAddNodeRef(pNode);
|
||||||
taosHashPut(vgIdHash, (const char *)&pNode->vgId, sizeof(int32_t), (char *)(&pNode), sizeof(SSyncNode *));
|
taosHashPut(vgIdHash, (const char *)&pNode->vgId, sizeof(int32_t), (char *)(&pNode), sizeof(SSyncNode *));
|
||||||
|
|
||||||
if (pNode->notifyRole)
|
if (pNode->notifyRole) {
|
||||||
(*pNode->notifyRole)(pNode->ahandle, nodeRole);
|
(*pNode->notifyRole)(pNode->ahandle, nodeRole);
|
||||||
|
}
|
||||||
|
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncStop(void *param) {
|
void syncStop(void *param) {
|
||||||
SSyncNode * pNode = param;
|
SSyncNode *pNode = param;
|
||||||
SSyncPeer *pPeer;
|
SSyncPeer *pPeer;
|
||||||
|
|
||||||
if (pNode == NULL) return;
|
if (pNode == NULL) return;
|
||||||
|
@ -214,12 +230,12 @@ void syncStop(void *param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncReconfig(void *param, const SSyncCfg *pNewCfg) {
|
int32_t syncReconfig(void *param, const SSyncCfg *pNewCfg) {
|
||||||
SSyncNode * pNode = param;
|
SSyncNode *pNode = param;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
if (pNode == NULL) return TSDB_CODE_SYN_INVALID_CONFIG;
|
if (pNode == NULL) return TSDB_CODE_SYN_INVALID_CONFIG;
|
||||||
sInfo("vgId:%d, reconfig, role:%s replica:%d old:%d", pNode->vgId, syncRole[nodeRole],
|
sInfo("vgId:%d, reconfig, role:%s replica:%d old:%d", pNode->vgId, syncRole[nodeRole], pNewCfg->replica,
|
||||||
pNewCfg->replica, pNode->replica);
|
pNode->replica);
|
||||||
|
|
||||||
pthread_mutex_lock(&(pNode->mutex));
|
pthread_mutex_lock(&(pNode->mutex));
|
||||||
|
|
||||||
|
@ -252,17 +268,19 @@ int32_t syncReconfig(void *param, const SSyncCfg *pNewCfg) {
|
||||||
newPeers[i] = pNode->peerInfo[j];
|
newPeers[i] = pNode->peerInfo[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(pNewNode->nodeFqdn, tsNodeFqdn) == 0) && (pNewNode->nodePort == tsSyncPort))
|
if ((strcmp(pNewNode->nodeFqdn, tsNodeFqdn) == 0) && (pNewNode->nodePort == tsSyncPort)) {
|
||||||
pNode->selfIndex = i;
|
pNode->selfIndex = i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pNode->replica = pNewCfg->replica;
|
pNode->replica = pNewCfg->replica;
|
||||||
pNode->quorum = pNewCfg->quorum;
|
pNode->quorum = pNewCfg->quorum;
|
||||||
if (pNode->quorum > pNode->replica) pNode->quorum = pNode->replica;
|
if (pNode->quorum > pNode->replica) pNode->quorum = pNode->replica;
|
||||||
memcpy(pNode->peerInfo, newPeers, sizeof(SSyncPeer *) * pNewCfg->replica);
|
memcpy(pNode->peerInfo, newPeers, sizeof(SSyncPeer *) * pNewCfg->replica);
|
||||||
|
|
||||||
for (i = pNewCfg->replica; i < TAOS_SYNC_MAX_REPLICA; ++i)
|
for (i = pNewCfg->replica; i < TAOS_SYNC_MAX_REPLICA; ++i) {
|
||||||
pNode->peerInfo[i] = NULL;
|
pNode->peerInfo[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
syncAddArbitrator(pNode);
|
syncAddArbitrator(pNode);
|
||||||
|
|
||||||
|
@ -274,17 +292,18 @@ int32_t syncReconfig(void *param, const SSyncCfg *pNewCfg) {
|
||||||
|
|
||||||
pthread_mutex_unlock(&(pNode->mutex));
|
pthread_mutex_unlock(&(pNode->mutex));
|
||||||
|
|
||||||
sInfo("vgId:%d, %d replicas are configured, quorum:%d role:%s", pNode->vgId, pNode->replica, pNode->quorum, syncRole[nodeRole]);
|
sInfo("vgId:%d, %d replicas are configured, quorum:%d role:%s", pNode->vgId, pNode->replica, pNode->quorum,
|
||||||
|
syncRole[nodeRole]);
|
||||||
syncBroadcastStatus(pNode);
|
syncBroadcastStatus(pNode);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncForwardToPeer(void *param, void *data, void *mhandle, int qtype) {
|
int32_t syncForwardToPeer(void *param, void *data, void *mhandle, int qtype) {
|
||||||
SSyncNode * pNode = param;
|
SSyncNode *pNode = param;
|
||||||
SSyncPeer * pPeer;
|
SSyncPeer *pPeer;
|
||||||
SSyncHead *pSyncHead;
|
SSyncHead *pSyncHead;
|
||||||
SWalHead *pWalHead = data;
|
SWalHead * pWalHead = data;
|
||||||
int fwdLen;
|
int fwdLen;
|
||||||
int code = 0;
|
int code = 0;
|
||||||
|
|
||||||
|
@ -292,23 +311,23 @@ int32_t syncForwardToPeer(void *param, void *data, void *mhandle, int qtype) {
|
||||||
|
|
||||||
// always update version
|
// always update version
|
||||||
nodeVersion = pWalHead->version;
|
nodeVersion = pWalHead->version;
|
||||||
if (pNode->replica == 1 || nodeRole != TAOS_SYNC_ROLE_MASTER ) return 0;
|
if (pNode->replica == 1 || nodeRole != TAOS_SYNC_ROLE_MASTER) return 0;
|
||||||
|
|
||||||
// only pkt from RPC or CQ can be forwarded
|
// only pkt from RPC or CQ can be forwarded
|
||||||
if (qtype != TAOS_QTYPE_RPC && qtype != TAOS_QTYPE_CQ) return 0;
|
if (qtype != TAOS_QTYPE_RPC && qtype != TAOS_QTYPE_CQ) return 0;
|
||||||
|
|
||||||
// a hacker way to improve the performance
|
// a hacker way to improve the performance
|
||||||
pSyncHead = (SSyncHead *) ( ((char *)pWalHead) - sizeof(SSyncHead));
|
pSyncHead = (SSyncHead *)(((char *)pWalHead) - sizeof(SSyncHead));
|
||||||
pSyncHead->type = TAOS_SMSG_FORWARD;
|
pSyncHead->type = TAOS_SMSG_FORWARD;
|
||||||
pSyncHead->pversion = 0;
|
pSyncHead->pversion = 0;
|
||||||
pSyncHead->len = sizeof(SWalHead) + pWalHead->len;
|
pSyncHead->len = sizeof(SWalHead) + pWalHead->len;
|
||||||
fwdLen = pSyncHead->len + sizeof(SSyncHead); //include the WAL and SYNC head
|
fwdLen = pSyncHead->len + sizeof(SSyncHead); // include the WAL and SYNC head
|
||||||
|
|
||||||
pthread_mutex_lock(&(pNode->mutex));
|
pthread_mutex_lock(&(pNode->mutex));
|
||||||
|
|
||||||
for (int i = 0; i < pNode->replica; ++i) {
|
for (int i = 0; i < pNode->replica; ++i) {
|
||||||
pPeer = pNode->peerInfo[i];
|
pPeer = pNode->peerInfo[i];
|
||||||
if (pPeer == NULL || pPeer->peerFd <0) continue;
|
if (pPeer == NULL || pPeer->peerFd < 0) continue;
|
||||||
if (pPeer->role != TAOS_SYNC_ROLE_SLAVE && pPeer->sstatus != TAOS_SYNC_STATUS_CACHE) continue;
|
if (pPeer->role != TAOS_SYNC_ROLE_SLAVE && pPeer->sstatus != TAOS_SYNC_STATUS_CACHE) continue;
|
||||||
|
|
||||||
if (pNode->quorum > 1 && code == 0) {
|
if (pNode->quorum > 1 && code == 0) {
|
||||||
|
@ -340,7 +359,7 @@ void syncConfirmForward(void *param, uint64_t version, int32_t code) {
|
||||||
|
|
||||||
char msg[sizeof(SSyncHead) + sizeof(SFwdRsp)] = {0};
|
char msg[sizeof(SSyncHead) + sizeof(SFwdRsp)] = {0};
|
||||||
|
|
||||||
SSyncHead *pHead = (SSyncHead *) msg;
|
SSyncHead *pHead = (SSyncHead *)msg;
|
||||||
pHead->type = TAOS_SMSG_FORWARD_RSP;
|
pHead->type = TAOS_SMSG_FORWARD_RSP;
|
||||||
pHead->len = sizeof(SFwdRsp);
|
pHead->len = sizeof(SFwdRsp);
|
||||||
|
|
||||||
|
@ -373,7 +392,7 @@ void syncRecover(void *param) {
|
||||||
pthread_mutex_lock(&(pNode->mutex));
|
pthread_mutex_lock(&(pNode->mutex));
|
||||||
|
|
||||||
for (int i = 0; i < pNode->replica; ++i) {
|
for (int i = 0; i < pNode->replica; ++i) {
|
||||||
pPeer = (SSyncPeer *) pNode->peerInfo[i];
|
pPeer = (SSyncPeer *)pNode->peerInfo[i];
|
||||||
if (pPeer->peerFd >= 0) {
|
if (pPeer->peerFd >= 0) {
|
||||||
syncRestartConnection(pPeer);
|
syncRestartConnection(pPeer);
|
||||||
}
|
}
|
||||||
|
@ -386,7 +405,7 @@ int syncGetNodesRole(void *param, SNodesRole *pNodesRole) {
|
||||||
SSyncNode *pNode = param;
|
SSyncNode *pNode = param;
|
||||||
|
|
||||||
pNodesRole->selfIndex = pNode->selfIndex;
|
pNodesRole->selfIndex = pNode->selfIndex;
|
||||||
for (int i=0; i<pNode->replica; ++i) {
|
for (int i = 0; i < pNode->replica; ++i) {
|
||||||
pNodesRole->nodeId[i] = pNode->peerInfo[i]->nodeId;
|
pNodesRole->nodeId[i] = pNode->peerInfo[i]->nodeId;
|
||||||
pNodesRole->role[i] = pNode->peerInfo[i]->role;
|
pNodesRole->role[i] = pNode->peerInfo[i]->role;
|
||||||
}
|
}
|
||||||
|
@ -423,29 +442,16 @@ static void syncAddArbitrator(SSyncNode *pNode) {
|
||||||
pNode->peerInfo[TAOS_SYNC_MAX_REPLICA] = syncAddPeer(pNode, &nodeInfo);
|
pNode->peerInfo[TAOS_SYNC_MAX_REPLICA] = syncAddPeer(pNode, &nodeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncAddNodeRef(SSyncNode *pNode)
|
static void syncAddNodeRef(SSyncNode *pNode) {
|
||||||
{
|
|
||||||
atomic_add_fetch_8(&pNode->refCount, 1);
|
atomic_add_fetch_8(&pNode->refCount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncDecNodeRef(SSyncNode *pNode)
|
static void syncDecNodeRef(SSyncNode *pNode) {
|
||||||
{
|
|
||||||
if (atomic_sub_fetch_8(&pNode->refCount, 1) == 0) {
|
if (atomic_sub_fetch_8(&pNode->refCount, 1) == 0) {
|
||||||
pthread_mutex_destroy(&pNode->mutex);
|
pthread_mutex_destroy(&pNode->mutex);
|
||||||
taosTFree(pNode->pRecv);
|
taosTFree(pNode->pRecv);
|
||||||
taosTFree(pNode->pSyncFwds);
|
taosTFree(pNode->pSyncFwds);
|
||||||
taosTFree(pNode);
|
taosTFree(pNode);
|
||||||
|
|
||||||
if (atomic_sub_fetch_32(&tsNodeNum, 1) == 0) {
|
|
||||||
if (tsTcpPool) taosCloseTcpThreadPool(tsTcpPool);
|
|
||||||
if (syncTmrCtrl) taosTmrCleanUp(syncTmrCtrl);
|
|
||||||
if (vgIdHash) taosHashCleanup(vgIdHash);
|
|
||||||
syncTmrCtrl = NULL;
|
|
||||||
tsTcpPool = NULL;
|
|
||||||
vgIdHash = NULL;
|
|
||||||
syncModuleInit = PTHREAD_ONCE_INIT;
|
|
||||||
sDebug("sync module is cleaned up");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +493,7 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) {
|
||||||
uint32_t ip = taosGetIpFromFqdn(pInfo->nodeFqdn);
|
uint32_t ip = taosGetIpFromFqdn(pInfo->nodeFqdn);
|
||||||
if (ip == -1) return NULL;
|
if (ip == -1) return NULL;
|
||||||
|
|
||||||
SSyncPeer *pPeer = (SSyncPeer *) calloc(1, sizeof(SSyncPeer));
|
SSyncPeer *pPeer = (SSyncPeer *)calloc(1, sizeof(SSyncPeer));
|
||||||
if (pPeer == NULL) return NULL;
|
if (pPeer == NULL) return NULL;
|
||||||
|
|
||||||
pPeer->nodeId = pInfo->nodeId;
|
pPeer->nodeId = pInfo->nodeId;
|
||||||
|
@ -506,7 +512,9 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) {
|
||||||
int ret = strcmp(pPeer->fqdn, tsNodeFqdn);
|
int ret = strcmp(pPeer->fqdn, tsNodeFqdn);
|
||||||
if (pPeer->nodeId == 0 || (ret > 0) || (ret == 0 && pPeer->port > tsSyncPort)) {
|
if (pPeer->nodeId == 0 || (ret > 0) || (ret == 0 && pPeer->port > tsSyncPort)) {
|
||||||
sDebug("%s, start to check peer connection", pPeer->id);
|
sDebug("%s, start to check peer connection", pPeer->id);
|
||||||
taosTmrReset(syncCheckPeerConnection, 100 + (pNode->vgId*10)%100, pPeer, syncTmrCtrl, &pPeer->timer);
|
int32_t checkMs = 100 + (pNode->vgId * 10) % 100;
|
||||||
|
if (pNode->vgId) checkMs = tsStatusInterval * 2000 + 100;
|
||||||
|
taosTmrReset(syncCheckPeerConnection, checkMs, pPeer, syncTmrCtrl, &pPeer->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
syncAddNodeRef(pNode);
|
syncAddNodeRef(pNode);
|
||||||
|
@ -542,18 +550,20 @@ static void syncChooseMaster(SSyncNode *pNode) {
|
||||||
sDebug("vgId:%d, choose master", pNode->vgId);
|
sDebug("vgId:%d, choose master", pNode->vgId);
|
||||||
|
|
||||||
for (int i = 0; i < pNode->replica; ++i) {
|
for (int i = 0; i < pNode->replica; ++i) {
|
||||||
if (pNode->peerInfo[i]->role != TAOS_SYNC_ROLE_OFFLINE)
|
if (pNode->peerInfo[i]->role != TAOS_SYNC_ROLE_OFFLINE) {
|
||||||
onlineNum++;
|
onlineNum++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (onlineNum == pNode->replica) {
|
if (onlineNum == pNode->replica) {
|
||||||
// if all peers are online, peer with highest version shall be master
|
// if all peers are online, peer with highest version shall be master
|
||||||
index = 0;
|
index = 0;
|
||||||
for (int i = 1; i < pNode->replica; ++i) {
|
for (int i = 1; i < pNode->replica; ++i) {
|
||||||
if (pNode->peerInfo[i]->version > pNode->peerInfo[index]->version)
|
if (pNode->peerInfo[i]->version > pNode->peerInfo[index]->version) {
|
||||||
index = i;
|
index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add arbitrator connection
|
// add arbitrator connection
|
||||||
SSyncPeer *pArb = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA];
|
SSyncPeer *pArb = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA];
|
||||||
|
@ -568,11 +578,12 @@ static void syncChooseMaster(SSyncNode *pNode) {
|
||||||
//slave with highest version shall be master
|
//slave with highest version shall be master
|
||||||
pPeer = pNode->peerInfo[i];
|
pPeer = pNode->peerInfo[i];
|
||||||
if (pPeer->role == TAOS_SYNC_ROLE_SLAVE || pPeer->role == TAOS_SYNC_ROLE_MASTER) {
|
if (pPeer->role == TAOS_SYNC_ROLE_SLAVE || pPeer->role == TAOS_SYNC_ROLE_MASTER) {
|
||||||
if (index < 0 || pPeer->version > pNode->peerInfo[index]->version)
|
if (index < 0 || pPeer->version > pNode->peerInfo[index]->version) {
|
||||||
index = i;
|
index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
if (index == pNode->selfIndex) {
|
if (index == pNode->selfIndex) {
|
||||||
|
@ -595,9 +606,10 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) {
|
||||||
int replica = pNode->replica;
|
int replica = pNode->replica;
|
||||||
|
|
||||||
for (int i = 0; i < pNode->replica; ++i) {
|
for (int i = 0; i < pNode->replica; ++i) {
|
||||||
if (pNode->peerInfo[i]->role != TAOS_SYNC_ROLE_OFFLINE)
|
if (pNode->peerInfo[i]->role != TAOS_SYNC_ROLE_OFFLINE) {
|
||||||
onlineNum++;
|
onlineNum++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add arbitrator connection
|
// add arbitrator connection
|
||||||
SSyncPeer *pArb = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA];
|
SSyncPeer *pArb = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA];
|
||||||
|
@ -644,7 +656,7 @@ static int syncValidateMaster(SSyncPeer *pPeer) {
|
||||||
code = -1;
|
code = -1;
|
||||||
|
|
||||||
for (int i = 0; i < pNode->replica; ++i) {
|
for (int i = 0; i < pNode->replica; ++i) {
|
||||||
if ( i == pNode->selfIndex ) continue;
|
if (i == pNode->selfIndex) continue;
|
||||||
syncRestartPeer(pNode->peerInfo[i]);
|
syncRestartPeer(pNode->peerInfo[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -661,12 +673,11 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus peersStatus[], int8_t ne
|
||||||
pNode->peerInfo[pNode->selfIndex]->version = nodeVersion;
|
pNode->peerInfo[pNode->selfIndex]->version = nodeVersion;
|
||||||
pPeer->role = newRole;
|
pPeer->role = newRole;
|
||||||
|
|
||||||
sDebug("%s, own role:%s, new peer role:%s", pPeer->id,
|
sDebug("%s, own role:%s, new peer role:%s", pPeer->id, syncRole[nodeRole], syncRole[pPeer->role]);
|
||||||
syncRole[nodeRole], syncRole[pPeer->role]);
|
|
||||||
|
|
||||||
SSyncPeer *pMaster = syncCheckMaster(pNode);
|
SSyncPeer *pMaster = syncCheckMaster(pNode);
|
||||||
|
|
||||||
if ( pMaster ) {
|
if (pMaster) {
|
||||||
// master is there
|
// master is there
|
||||||
pNode->pMaster = pMaster;
|
pNode->pMaster = pMaster;
|
||||||
sDebug("%s, it is the master, ver:%" PRIu64, pMaster->id, pMaster->version);
|
sDebug("%s, it is the master, ver:%" PRIu64, pMaster->id, pMaster->version);
|
||||||
|
@ -699,19 +710,22 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus peersStatus[], int8_t ne
|
||||||
if (pNode->replica == 2) consistent = 1;
|
if (pNode->replica == 2) consistent = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consistent)
|
if (consistent) {
|
||||||
syncChooseMaster(pNode);
|
syncChooseMaster(pNode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (syncRequired) {
|
if (syncRequired) {
|
||||||
syncRecoverFromMaster(pMaster);
|
syncRecoverFromMaster(pMaster);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peerOldRole != newRole || nodeRole != selfOldRole)
|
if (peerOldRole != newRole || nodeRole != selfOldRole) {
|
||||||
syncBroadcastStatus(pNode);
|
syncBroadcastStatus(pNode);
|
||||||
|
}
|
||||||
|
|
||||||
if (nodeRole != TAOS_SYNC_ROLE_MASTER)
|
if (nodeRole != TAOS_SYNC_ROLE_MASTER) {
|
||||||
syncResetFlowCtrl(pNode);
|
syncResetFlowCtrl(pNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncRestartPeer(SSyncPeer *pPeer) {
|
static void syncRestartPeer(SSyncPeer *pPeer) {
|
||||||
|
@ -722,8 +736,9 @@ static void syncRestartPeer(SSyncPeer *pPeer) {
|
||||||
pPeer->sstatus = TAOS_SYNC_STATUS_INIT;
|
pPeer->sstatus = TAOS_SYNC_STATUS_INIT;
|
||||||
|
|
||||||
int ret = strcmp(pPeer->fqdn, tsNodeFqdn);
|
int ret = strcmp(pPeer->fqdn, tsNodeFqdn);
|
||||||
if (ret > 0 || (ret == 0 && pPeer->port > tsSyncPort))
|
if (ret > 0 || (ret == 0 && pPeer->port > tsSyncPort)) {
|
||||||
taosTmrReset(syncCheckPeerConnection, tsSyncTimer * 1000, pPeer, syncTmrCtrl, &pPeer->timer);
|
taosTmrReset(syncCheckPeerConnection, tsSyncTimer * 1000, pPeer, syncTmrCtrl, &pPeer->timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncRestartConnection(SSyncPeer *pPeer) {
|
void syncRestartConnection(SSyncPeer *pPeer) {
|
||||||
|
@ -805,7 +820,7 @@ static void syncRecoverFromMaster(SSyncPeer *pPeer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sDebug("%s, try to sync", pPeer->id)
|
sDebug("%s, try to sync", pPeer->id);
|
||||||
|
|
||||||
SFirstPkt firstPkt;
|
SFirstPkt firstPkt;
|
||||||
memset(&firstPkt, 0, sizeof(firstPkt));
|
memset(&firstPkt, 0, sizeof(firstPkt));
|
||||||
|
@ -814,31 +829,29 @@ static void syncRecoverFromMaster(SSyncPeer *pPeer) {
|
||||||
firstPkt.syncHead.len = sizeof(firstPkt) - sizeof(SSyncHead);
|
firstPkt.syncHead.len = sizeof(firstPkt) - sizeof(SSyncHead);
|
||||||
tstrncpy(firstPkt.fqdn, tsNodeFqdn, sizeof(firstPkt.fqdn));
|
tstrncpy(firstPkt.fqdn, tsNodeFqdn, sizeof(firstPkt.fqdn));
|
||||||
firstPkt.port = tsSyncPort;
|
firstPkt.port = tsSyncPort;
|
||||||
taosTmrReset(syncNotStarted, tsSyncTimer*1000, pPeer, syncTmrCtrl, &pPeer->timer);
|
taosTmrReset(syncNotStarted, tsSyncTimer * 1000, pPeer, syncTmrCtrl, &pPeer->timer);
|
||||||
|
|
||||||
if (write(pPeer->peerFd, &firstPkt, sizeof(firstPkt)) != sizeof(firstPkt) ) {
|
if (write(pPeer->peerFd, &firstPkt, sizeof(firstPkt)) != sizeof(firstPkt)) {
|
||||||
sError("%s, failed to send sync-req to peer", pPeer->id);
|
sError("%s, failed to send sync-req to peer", pPeer->id);
|
||||||
} else {
|
} else {
|
||||||
nodeSStatus = TAOS_SYNC_STATUS_START;
|
nodeSStatus = TAOS_SYNC_STATUS_START;
|
||||||
sInfo("%s, sync-req is sent", pPeer->id);
|
sInfo("%s, sync-req is sent", pPeer->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncProcessFwdResponse(char *cont, SSyncPeer *pPeer) {
|
static void syncProcessFwdResponse(char *cont, SSyncPeer *pPeer) {
|
||||||
SSyncNode * pNode = pPeer->pSyncNode;
|
SSyncNode *pNode = pPeer->pSyncNode;
|
||||||
SFwdRsp *pFwdRsp = (SFwdRsp *) cont;
|
SFwdRsp * pFwdRsp = (SFwdRsp *)cont;
|
||||||
SSyncFwds *pSyncFwds = pNode->pSyncFwds;
|
SSyncFwds *pSyncFwds = pNode->pSyncFwds;
|
||||||
SFwdInfo *pFwdInfo;
|
SFwdInfo * pFwdInfo;
|
||||||
|
|
||||||
sDebug("%s, forward-rsp is received, ver:%" PRIu64, pPeer->id, pFwdRsp->version);
|
sDebug("%s, forward-rsp is received, ver:%" PRIu64, pPeer->id, pFwdRsp->version);
|
||||||
SFwdInfo *pFirst = pSyncFwds->fwdInfo + pSyncFwds->first;
|
SFwdInfo *pFirst = pSyncFwds->fwdInfo + pSyncFwds->first;
|
||||||
|
|
||||||
if (pFirst->version <= pFwdRsp->version && pSyncFwds->fwds > 0) {
|
if (pFirst->version <= pFwdRsp->version && pSyncFwds->fwds > 0) {
|
||||||
// find the forwardInfo from first
|
// find the forwardInfo from first
|
||||||
for (int i=0; i<pSyncFwds->fwds; ++i) {
|
for (int i = 0; i < pSyncFwds->fwds; ++i) {
|
||||||
pFwdInfo = pSyncFwds->fwdInfo + (i+pSyncFwds->first)%tsMaxFwdInfo;
|
pFwdInfo = pSyncFwds->fwdInfo + (i + pSyncFwds->first) % tsMaxFwdInfo;
|
||||||
if (pFwdRsp->version == pFwdInfo->version) break;
|
if (pFwdRsp->version == pFwdInfo->version) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,13 +861,13 @@ static void syncProcessFwdResponse(char *cont, SSyncPeer *pPeer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncProcessForwardFromPeer(char *cont, SSyncPeer *pPeer) {
|
static void syncProcessForwardFromPeer(char *cont, SSyncPeer *pPeer) {
|
||||||
SSyncNode * pNode = pPeer->pSyncNode;
|
SSyncNode *pNode = pPeer->pSyncNode;
|
||||||
SWalHead *pHead = (SWalHead *)cont;
|
SWalHead * pHead = (SWalHead *)cont;
|
||||||
|
|
||||||
sDebug("%s, forward is received, ver:%" PRIu64, pPeer->id, pHead->version);
|
sDebug("%s, forward is received, ver:%" PRIu64, pPeer->id, pHead->version);
|
||||||
|
|
||||||
if (nodeRole == TAOS_SYNC_ROLE_SLAVE) {
|
if (nodeRole == TAOS_SYNC_ROLE_SLAVE) {
|
||||||
//nodeVersion = pHead->version;
|
// nodeVersion = pHead->version;
|
||||||
(*pNode->writeToCache)(pNode->ahandle, pHead, TAOS_QTYPE_FWD);
|
(*pNode->writeToCache)(pNode->ahandle, pHead, TAOS_QTYPE_FWD);
|
||||||
} else {
|
} else {
|
||||||
if (nodeSStatus != TAOS_SYNC_STATUS_INIT) {
|
if (nodeSStatus != TAOS_SYNC_STATUS_INIT) {
|
||||||
|
@ -877,12 +890,13 @@ static void syncProcessPeersStatusMsg(char *cont, SSyncPeer *pPeer) {
|
||||||
pPeer->version = pPeersStatus->version;
|
pPeer->version = pPeersStatus->version;
|
||||||
syncCheckRole(pPeer, pPeersStatus->peersStatus, pPeersStatus->role);
|
syncCheckRole(pPeer, pPeersStatus->peersStatus, pPeersStatus->role);
|
||||||
|
|
||||||
if (pPeersStatus->ack)
|
if (pPeersStatus->ack) {
|
||||||
syncSendPeersStatusMsgToPeer(pPeer, 0);
|
syncSendPeersStatusMsgToPeer(pPeer, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int syncReadPeerMsg(SSyncPeer *pPeer, SSyncHead *pHead, char *cont) {
|
static int syncReadPeerMsg(SSyncPeer *pPeer, SSyncHead *pHead, char *cont) {
|
||||||
if (pPeer->peerFd <0) return -1;
|
if (pPeer->peerFd < 0) return -1;
|
||||||
|
|
||||||
int hlen = taosReadMsg(pPeer->peerFd, pHead, sizeof(SSyncHead));
|
int hlen = taosReadMsg(pPeer->peerFd, pHead, sizeof(SSyncHead));
|
||||||
if (hlen != sizeof(SSyncHead)) {
|
if (hlen != sizeof(SSyncHead)) {
|
||||||
|
@ -906,9 +920,9 @@ static int syncReadPeerMsg(SSyncPeer *pPeer, SSyncHead *pHead, char *cont) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int syncProcessPeerMsg(void *param, void *buffer) {
|
static int syncProcessPeerMsg(void *param, void *buffer) {
|
||||||
SSyncPeer * pPeer = param;
|
SSyncPeer *pPeer = param;
|
||||||
SSyncHead head;
|
SSyncHead head;
|
||||||
char *cont = (char *)buffer;
|
char * cont = (char *)buffer;
|
||||||
|
|
||||||
SSyncNode *pNode = pPeer->pSyncNode;
|
SSyncNode *pNode = pPeer->pSyncNode;
|
||||||
pthread_mutex_lock(&(pNode->mutex));
|
pthread_mutex_lock(&(pNode->mutex));
|
||||||
|
@ -932,16 +946,16 @@ static int syncProcessPeerMsg(void *param, void *buffer) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define statusMsgLen sizeof(SSyncHead)+sizeof(SPeersStatus)+sizeof(SPeerStatus)*TAOS_SYNC_MAX_REPLICA
|
#define statusMsgLen sizeof(SSyncHead) + sizeof(SPeersStatus) + sizeof(SPeerStatus) * TAOS_SYNC_MAX_REPLICA
|
||||||
|
|
||||||
static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack) {
|
static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack) {
|
||||||
SSyncNode *pNode = pPeer->pSyncNode;
|
SSyncNode *pNode = pPeer->pSyncNode;
|
||||||
char msg[statusMsgLen] = {0};
|
char msg[statusMsgLen] = {0};
|
||||||
|
|
||||||
if (pPeer->peerFd <0 || pPeer->ip ==0) return;
|
if (pPeer->peerFd < 0 || pPeer->ip == 0) return;
|
||||||
|
|
||||||
SSyncHead *pHead = (SSyncHead *) msg;
|
SSyncHead * pHead = (SSyncHead *)msg;
|
||||||
SPeersStatus *pPeersStatus = (SPeersStatus *) (msg + sizeof(SSyncHead));
|
SPeersStatus *pPeersStatus = (SPeersStatus *)(msg + sizeof(SSyncHead));
|
||||||
|
|
||||||
pHead->type = TAOS_SMSG_STATUS;
|
pHead->type = TAOS_SMSG_STATUS;
|
||||||
pHead->len = statusMsgLen - sizeof(SSyncHead);
|
pHead->len = statusMsgLen - sizeof(SSyncHead);
|
||||||
|
@ -979,13 +993,13 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) {
|
||||||
int connFd = taosOpenTcpClientSocket(pPeer->ip, pPeer->port, 0);
|
int connFd = taosOpenTcpClientSocket(pPeer->ip, pPeer->port, 0);
|
||||||
if (connFd < 0) {
|
if (connFd < 0) {
|
||||||
sDebug("%s, failed to open tcp socket(%s)", pPeer->id, strerror(errno));
|
sDebug("%s, failed to open tcp socket(%s)", pPeer->id, strerror(errno));
|
||||||
taosTmrReset(syncCheckPeerConnection, tsSyncTimer *1000, pPeer, syncTmrCtrl, &pPeer->timer);
|
taosTmrReset(syncCheckPeerConnection, tsSyncTimer * 1000, pPeer, syncTmrCtrl, &pPeer->timer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SFirstPkt firstPkt;
|
SFirstPkt firstPkt;
|
||||||
memset(&firstPkt, 0, sizeof(firstPkt));
|
memset(&firstPkt, 0, sizeof(firstPkt));
|
||||||
firstPkt.syncHead.vgId = pPeer->nodeId ? pNode->vgId:0;
|
firstPkt.syncHead.vgId = pPeer->nodeId ? pNode->vgId : 0;
|
||||||
firstPkt.syncHead.type = TAOS_SMSG_STATUS;
|
firstPkt.syncHead.type = TAOS_SMSG_STATUS;
|
||||||
tstrncpy(firstPkt.fqdn, tsNodeFqdn, sizeof(firstPkt.fqdn));
|
tstrncpy(firstPkt.fqdn, tsNodeFqdn, sizeof(firstPkt.fqdn));
|
||||||
firstPkt.port = tsSyncPort;
|
firstPkt.port = tsSyncPort;
|
||||||
|
@ -1000,7 +1014,7 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) {
|
||||||
} else {
|
} else {
|
||||||
sDebug("try later");
|
sDebug("try later");
|
||||||
close(connFd);
|
close(connFd);
|
||||||
taosTmrReset(syncCheckPeerConnection, tsSyncTimer *1000, pPeer, syncTmrCtrl, &pPeer->timer);
|
taosTmrReset(syncCheckPeerConnection, tsSyncTimer * 1000, pPeer, syncTmrCtrl, &pPeer->timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,8 +1079,7 @@ static void syncProcessIncommingConnection(int connFd, uint32_t sourceIp) {
|
||||||
SSyncPeer *pPeer;
|
SSyncPeer *pPeer;
|
||||||
for (i = 0; i < pNode->replica; ++i) {
|
for (i = 0; i < pNode->replica; ++i) {
|
||||||
pPeer = pNode->peerInfo[i];
|
pPeer = pNode->peerInfo[i];
|
||||||
if (pPeer && (strcmp(pPeer->fqdn, firstPkt.fqdn) == 0) && (pPeer->port == firstPkt.port))
|
if (pPeer && (strcmp(pPeer->fqdn, firstPkt.fqdn) == 0) && (pPeer->port == firstPkt.port)) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pPeer = (i < pNode->replica) ? pNode->peerInfo[i] : NULL;
|
pPeer = (i < pNode->replica) ? pNode->peerInfo[i] : NULL;
|
||||||
|
@ -1091,8 +1104,6 @@ static void syncProcessIncommingConnection(int connFd, uint32_t sourceIp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&(pNode->mutex));
|
pthread_mutex_unlock(&(pNode->mutex));
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncProcessBrokenLink(void *param) {
|
static void syncProcessBrokenLink(void *param) {
|
||||||
|
@ -1123,8 +1134,10 @@ static void syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle) {
|
||||||
pSyncFwds->fwds--;
|
pSyncFwds->fwds--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSyncFwds->fwds > 0)
|
if (pSyncFwds->fwds > 0) {
|
||||||
pSyncFwds->last = (pSyncFwds->last+1) % tsMaxFwdInfo;
|
pSyncFwds->last = (pSyncFwds->last + 1) % tsMaxFwdInfo;
|
||||||
|
}
|
||||||
|
|
||||||
SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + pSyncFwds->last;
|
SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + pSyncFwds->last;
|
||||||
pFwdInfo->version = version;
|
pFwdInfo->version = version;
|
||||||
pFwdInfo->mhandle = mhandle;
|
pFwdInfo->mhandle = mhandle;
|
||||||
|
@ -1140,14 +1153,14 @@ static void syncRemoveConfirmedFwdInfo(SSyncNode *pNode) {
|
||||||
SSyncFwds *pSyncFwds = pNode->pSyncFwds;
|
SSyncFwds *pSyncFwds = pNode->pSyncFwds;
|
||||||
|
|
||||||
int fwds = pSyncFwds->fwds;
|
int fwds = pSyncFwds->fwds;
|
||||||
for (int i=0; i<fwds; ++i) {
|
for (int i = 0; i < fwds; ++i) {
|
||||||
SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + pSyncFwds->first;
|
SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + pSyncFwds->first;
|
||||||
if (pFwdInfo->confirmed == 0) break;
|
if (pFwdInfo->confirmed == 0) break;
|
||||||
|
|
||||||
pSyncFwds->first = (pSyncFwds->first+1) % tsMaxFwdInfo;
|
pSyncFwds->first = (pSyncFwds->first + 1) % tsMaxFwdInfo;
|
||||||
pSyncFwds->fwds--;
|
pSyncFwds->fwds--;
|
||||||
if (pSyncFwds->fwds == 0) pSyncFwds->first = pSyncFwds->last;
|
if (pSyncFwds->fwds == 0) pSyncFwds->first = pSyncFwds->last;
|
||||||
//sDebug("vgId:%d, fwd info is removed, ver:%d, fwds:%d",
|
// sDebug("vgId:%d, fwd info is removed, ver:%d, fwds:%d",
|
||||||
// pNode->vgId, pFwdInfo->version, pSyncFwds->fwds);
|
// pNode->vgId, pFwdInfo->version, pSyncFwds->fwds);
|
||||||
memset(pFwdInfo, 0, sizeof(SFwdInfo));
|
memset(pFwdInfo, 0, sizeof(SFwdInfo));
|
||||||
}
|
}
|
||||||
|
@ -1159,13 +1172,15 @@ static void syncProcessFwdAck(SSyncNode *pNode, SFwdInfo *pFwdInfo, int32_t code
|
||||||
|
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
pFwdInfo->acks++;
|
pFwdInfo->acks++;
|
||||||
if (pFwdInfo->acks >= pNode->quorum-1)
|
if (pFwdInfo->acks >= pNode->quorum - 1) {
|
||||||
confirm = 1;
|
confirm = 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pFwdInfo->nacks++;
|
pFwdInfo->nacks++;
|
||||||
if (pFwdInfo->nacks > pNode->replica-pNode->quorum)
|
if (pFwdInfo->nacks > pNode->replica - pNode->quorum) {
|
||||||
confirm = 1;
|
confirm = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (confirm && pFwdInfo->confirmed == 0) {
|
if (confirm && pFwdInfo->confirmed == 0) {
|
||||||
sDebug("vgId:%d, forward is confirmed, ver:%" PRIu64 " code:%x", pNode->vgId, pFwdInfo->version, pFwdInfo->code);
|
sDebug("vgId:%d, forward is confirmed, ver:%" PRIu64 " code:%x", pNode->vgId, pFwdInfo->version, pFwdInfo->code);
|
||||||
|
@ -1181,8 +1196,8 @@ static void syncMonitorFwdInfos(void *param, void *tmrId) {
|
||||||
|
|
||||||
if (pSyncFwds->fwds > 0) {
|
if (pSyncFwds->fwds > 0) {
|
||||||
pthread_mutex_lock(&(pNode->mutex));
|
pthread_mutex_lock(&(pNode->mutex));
|
||||||
for (int i=0; i<pSyncFwds->fwds; ++i) {
|
for (int i = 0; i < pSyncFwds->fwds; ++i) {
|
||||||
SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + (pSyncFwds->first+i) % tsMaxFwdInfo;
|
SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + (pSyncFwds->first + i) % tsMaxFwdInfo;
|
||||||
if (time - pFwdInfo->time < 2000) break;
|
if (time - pFwdInfo->time < 2000) break;
|
||||||
syncProcessFwdAck(pNode, pFwdInfo, TSDB_CODE_RPC_NETWORK_UNAVAIL);
|
syncProcessFwdAck(pNode, pFwdInfo, TSDB_CODE_RPC_NETWORK_UNAVAIL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,9 @@ void syncConfirmForward(tsync_h shandle, uint64_t version, int32_t code) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int32_t vnodeInitResources() {
|
int32_t vnodeInitResources() {
|
||||||
|
int code = syncInit();
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
vnodeInitWriteFp();
|
vnodeInitWriteFp();
|
||||||
vnodeInitReadFp();
|
vnodeInitReadFp();
|
||||||
|
|
||||||
|
@ -70,11 +73,12 @@ int32_t vnodeInitResources() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vnodeCleanupResources() {
|
void vnodeCleanupResources() {
|
||||||
|
|
||||||
if (tsDnodeVnodesHash != NULL) {
|
if (tsDnodeVnodesHash != NULL) {
|
||||||
taosHashCleanup(tsDnodeVnodesHash);
|
taosHashCleanup(tsDnodeVnodesHash);
|
||||||
tsDnodeVnodesHash = NULL;
|
tsDnodeVnodesHash = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syncCleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t vnodeCreate(SMDCreateVnodeMsg *pVnodeCfg) {
|
int32_t vnodeCreate(SMDCreateVnodeMsg *pVnodeCfg) {
|
||||||
|
|
|
@ -93,11 +93,12 @@ static int32_t vnodeDumpQueryResult(SRspRet *pRet, void* pVnode, void** handle,
|
||||||
vDebug("QInfo:%p exec completed, free handle:%d", *handle, *freeHandle);
|
vDebug("QInfo:%p exec completed, free handle:%d", *handle, *freeHandle);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SRetrieveTableRsp* pRsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
||||||
memset(pRsp, 0, sizeof(SRetrieveTableRsp));
|
memset(pRsp, 0, sizeof(SRetrieveTableRsp));
|
||||||
pRsp->completed = true;
|
pRsp->completed = true;
|
||||||
|
|
||||||
pRet->rsp = pRsp;
|
pRet->rsp = pRsp;
|
||||||
|
pRet->len = sizeof(SRetrieveTableRsp);
|
||||||
*freeHandle = true;
|
*freeHandle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +271,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
//TODO handle malloc failure
|
//TODO handle malloc failure
|
||||||
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
||||||
|
pRet->len = sizeof(SRetrieveTableRsp);
|
||||||
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
||||||
freeHandle = true;
|
freeHandle = true;
|
||||||
} else { // result is not ready, return immediately
|
} else { // result is not ready, return immediately
|
||||||
|
|
|
@ -9,21 +9,20 @@
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<build>
|
<build>
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-plugins</artifactId>
|
<artifactId>maven-plugins</artifactId>
|
||||||
<version>30</version>
|
<version>30</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>3.0.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
@ -48,6 +47,7 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
package com.taosdata.example;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class JDBCConnectorChecker {
|
||||||
|
private static String host;
|
||||||
|
private static String dbName = "test";
|
||||||
|
private static String tbName = "weather";
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get connection
|
||||||
|
**/
|
||||||
|
private void init() {
|
||||||
|
try {
|
||||||
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
System.out.println("get connection starting...");
|
||||||
|
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
||||||
|
if (connection != null)
|
||||||
|
System.out.println("[ OK ] Connection established.");
|
||||||
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
|
throw new RuntimeException("connection failed: " + host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create database
|
||||||
|
*/
|
||||||
|
private void createDatabase() {
|
||||||
|
String sql = "create database if not exists " + dbName;
|
||||||
|
exuete(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use database
|
||||||
|
*/
|
||||||
|
private void useDatabase() {
|
||||||
|
String sql = "use " + dbName;
|
||||||
|
exuete(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* select
|
||||||
|
*/
|
||||||
|
private void checkSelect() {
|
||||||
|
final String sql = "select * from test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeQuery(String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
ResultSet resultSet = statement.executeQuery(sql);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
printSql(sql, true, (end - start));
|
||||||
|
printResult(resultSet);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printResult(ResultSet resultSet) throws SQLException {
|
||||||
|
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||||
|
String columnLabel = metaData.getColumnLabel(i);
|
||||||
|
String value = resultSet.getString(i);
|
||||||
|
System.out.printf("%s: %s\t", columnLabel, value);
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatString(String str) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int blankCnt = (26 - str.length()) / 2;
|
||||||
|
for (int j = 0; j < blankCnt; j++)
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append(str);
|
||||||
|
for (int j = 0; j < blankCnt; j++)
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append("|");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert
|
||||||
|
*/
|
||||||
|
private void checkInsert() {
|
||||||
|
final String sql = "insert into test.weather (ts, temperature, humidity) values(now, 20.5, 34)";
|
||||||
|
exuete(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create table
|
||||||
|
*/
|
||||||
|
private void createTable() {
|
||||||
|
final String sql = "create table if not exists " + dbName + "." + tbName + " (ts timestamp, temperature float, humidity int)";
|
||||||
|
exuete(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void printSql(String sql, boolean succeed, long cost) {
|
||||||
|
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void exuete(String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean execute = statement.execute(sql);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
printSql(sql, execute, (end - start));
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() {
|
||||||
|
try {
|
||||||
|
if (connection != null) {
|
||||||
|
this.connection.close();
|
||||||
|
System.out.println("connection closed.");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkDropTable() {
|
||||||
|
final String sql = "drop table if exists " + dbName + "." + tbName + "";
|
||||||
|
exuete(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
if ("-host".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||||
|
host = args[++i];
|
||||||
|
}
|
||||||
|
if ("-db".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||||
|
dbName = args[++i];
|
||||||
|
}
|
||||||
|
if ("-t".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||||
|
tbName = args[++i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host == null) {
|
||||||
|
System.out.println("Usage: java -jar JDBCConnectorChecker.jar -host <hostname>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JDBCConnectorChecker checker = new JDBCConnectorChecker();
|
||||||
|
checker.init();
|
||||||
|
checker.createDatabase();
|
||||||
|
checker.useDatabase();
|
||||||
|
checker.checkDropTable();
|
||||||
|
checker.createTable();
|
||||||
|
checker.checkInsert();
|
||||||
|
checker.checkSelect();
|
||||||
|
checker.checkDropTable();
|
||||||
|
checker.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -22,26 +22,32 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context</artifactId>
|
<artifactId>spring-context</artifactId>
|
||||||
<version>4.3.2.RELEASE</version>
|
<version>5.2.8.RELEASE</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-jdbc</artifactId>
|
<artifactId>spring-jdbc</artifactId>
|
||||||
<version>4.3.2.RELEASE</version>
|
<version>5.1.9.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>5.1.9.RELEASE</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.11</version>
|
<version>4.13</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.2</version>
|
<version>2.0.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -63,7 +69,7 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
<mainClass>com.taosdata.jdbc.App</mainClass>
|
<mainClass>com.taosdata.jdbc.example.jdbcTemplate.App</mainClass>
|
||||||
</manifest>
|
</manifest>
|
||||||
</archive>
|
</archive>
|
||||||
<descriptorRefs>
|
<descriptorRefs>
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
package com.taosdata.jdbc;
|
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class App {
|
|
||||||
|
|
||||||
public static void main( String[] args ) {
|
|
||||||
|
|
||||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
|
|
||||||
|
|
||||||
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
|
|
||||||
|
|
||||||
// create database
|
|
||||||
jdbcTemplate.execute("create database if not exists db ");
|
|
||||||
|
|
||||||
// create table
|
|
||||||
jdbcTemplate.execute("create table if not exists db.tb (ts timestamp, temperature int, humidity float)");
|
|
||||||
|
|
||||||
String insertSql = "insert into db.tb values(now, 23, 10.3) (now + 1s, 20, 9.3)";
|
|
||||||
|
|
||||||
// insert rows
|
|
||||||
int affectedRows = jdbcTemplate.update(insertSql);
|
|
||||||
|
|
||||||
System.out.println("insert success " + affectedRows + " rows.");
|
|
||||||
|
|
||||||
// query for list
|
|
||||||
List<Map<String, Object>> resultList = jdbcTemplate.queryForList("select * from db.tb");
|
|
||||||
|
|
||||||
if(!CollectionUtils.isEmpty(resultList)){
|
|
||||||
for (Map<String, Object> row : resultList){
|
|
||||||
System.out.printf("%s, %d, %s\n", row.get("ts"), row.get("temperature"), row.get("humidity"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.taosdata.jdbc.example.jdbcTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.dao.ExecuteAsStatement;
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.dao.WeatherDao;
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.domain.Weather;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
private static Random random = new Random(System.currentTimeMillis());
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
|
||||||
|
|
||||||
|
ExecuteAsStatement executor = ctx.getBean(ExecuteAsStatement.class);
|
||||||
|
// drop database
|
||||||
|
executor.doExecute("drop database if exists test");
|
||||||
|
// create database
|
||||||
|
executor.doExecute("create database if not exists test");
|
||||||
|
//use database
|
||||||
|
executor.doExecute("use test");
|
||||||
|
// create table
|
||||||
|
executor.doExecute("create table if not exists test.weather (ts timestamp, temperature int, humidity float)");
|
||||||
|
|
||||||
|
WeatherDao weatherDao = ctx.getBean(WeatherDao.class);
|
||||||
|
Weather weather = new Weather(new Timestamp(new Date().getTime()), random.nextFloat() * 50.0f, random.nextInt(100));
|
||||||
|
// insert rows
|
||||||
|
int affectedRows = weatherDao.add(weather);
|
||||||
|
System.out.println("insert success " + affectedRows + " rows.");
|
||||||
|
|
||||||
|
// query for list
|
||||||
|
int limit = 10, offset = 0;
|
||||||
|
List<Weather> weatherList = weatherDao.queryForList(limit, offset);
|
||||||
|
for (Weather w : weatherList) {
|
||||||
|
System.out.println(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.taosdata.jdbc.example.jdbcTemplate.dao;
|
||||||
|
|
||||||
|
public interface ExecuteAsStatement{
|
||||||
|
|
||||||
|
void doExecute(String sql);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.taosdata.jdbc.example.jdbcTemplate.dao;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.domain.Weather;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface WeatherDao {
|
||||||
|
|
||||||
|
|
||||||
|
int add(Weather weather);
|
||||||
|
|
||||||
|
int[] batchInsert(List<Weather> weatherList);
|
||||||
|
|
||||||
|
List<Weather> queryForList(int limit, int offset);
|
||||||
|
|
||||||
|
int count();
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.taosdata.jdbc.example.jdbcTemplate.dao.impl;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.dao.ExecuteAsStatement;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public class ExecuteAsStatementImpl implements ExecuteAsStatement {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doExecute(String sql) {
|
||||||
|
jdbcTemplate.execute(sql);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.taosdata.jdbc.example.jdbcTemplate.dao.impl;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.dao.WeatherDao;
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.domain.Weather;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
|
||||||
|
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public class WeatherDaoImpl implements WeatherDao {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int add(Weather weather) {
|
||||||
|
return jdbcTemplate.update(
|
||||||
|
"insert into test.weather(ts, temperature, humidity) VALUES(?,?,?)",
|
||||||
|
weather.getTs(), weather.getTemperature(), weather.getHumidity()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] batchInsert(List<Weather> weatherList) {
|
||||||
|
return jdbcTemplate.batchUpdate("insert into test.weather(ts, temperature, humidity) values( ?, ?, ?)", new BatchPreparedStatementSetter() {
|
||||||
|
@Override
|
||||||
|
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||||
|
ps.setTimestamp(1, weatherList.get(i).getTs());
|
||||||
|
ps.setFloat(2, weatherList.get(i).getTemperature());
|
||||||
|
ps.setInt(3, weatherList.get(i).getHumidity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBatchSize() {
|
||||||
|
return weatherList.size();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Weather> queryForList(int limit, int offset) {
|
||||||
|
return jdbcTemplate.query("select * from test.weather limit ? offset ?", (rs, rowNum) -> {
|
||||||
|
Timestamp ts = rs.getTimestamp("ts");
|
||||||
|
float temperature = rs.getFloat("temperature");
|
||||||
|
int humidity = rs.getInt("humidity");
|
||||||
|
return new Weather(ts, temperature, humidity);
|
||||||
|
}, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int count() {
|
||||||
|
return jdbcTemplate.queryForObject("select count(*) from test.weather", Integer.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.taosdata.jdbc.example.jdbcTemplate.domain;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
public class Weather {
|
||||||
|
|
||||||
|
private Timestamp ts;
|
||||||
|
private float temperature;
|
||||||
|
private int humidity;
|
||||||
|
|
||||||
|
public Weather() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Weather(Timestamp ts, float temperature, int humidity) {
|
||||||
|
this.ts = ts;
|
||||||
|
this.temperature = temperature;
|
||||||
|
this.humidity = humidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Weather{" +
|
||||||
|
"ts=" + ts +
|
||||||
|
", temperature=" + temperature +
|
||||||
|
", humidity=" + humidity +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timestamp getTs() {
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTs(Timestamp ts) {
|
||||||
|
this.ts = ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTemperature() {
|
||||||
|
return temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemperature(float temperature) {
|
||||||
|
this.temperature = temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHumidity() {
|
||||||
|
return humidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHumidity(int humidity) {
|
||||||
|
this.humidity = humidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -5,20 +5,21 @@
|
||||||
xsi:schemaLocation="
|
xsi:schemaLocation="
|
||||||
http://www.springframework.org/schema/beans
|
http://www.springframework.org/schema/beans
|
||||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
|
||||||
"
|
|
||||||
default-autowire="byName">
|
default-autowire="byName">
|
||||||
|
|
||||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||||
<property name="driverClassName" value="com.taosdata.jdbc.TSDBDriver"></property>
|
<property name="driverClassName" value="com.taosdata.jdbc.TSDBDriver"></property>
|
||||||
<property name="url" value="jdbc:TAOS://127.0.0.1:6030/log"></property>
|
<property name="url" value="jdbc:TAOS://192.168.236.137:6030/"></property>
|
||||||
<property name="username" value="root"></property>
|
<property name="username" value="root"></property>
|
||||||
<property name="password" value="taosdata"></property>
|
<property name="password" value="taosdata"></property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<bean id = "jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
|
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
|
||||||
<property name="dataSource" ref = "dataSource" ></property>
|
<property name="dataSource" ref="dataSource"></property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<context:component-scan base-package="com.taosdata.jdbc.example.jdbcTemplate"/>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
@ -7,14 +7,12 @@ import org.junit.Test;
|
||||||
/**
|
/**
|
||||||
* Unit test for simple App.
|
* Unit test for simple App.
|
||||||
*/
|
*/
|
||||||
public class AppTest
|
public class AppTest {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Rigorous Test :-)
|
* Rigorous Test :-)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void shouldAnswerWithTrue()
|
public void shouldAnswerWithTrue() {
|
||||||
{
|
assertTrue(true);
|
||||||
assertTrue( true );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.taosdata.jdbc.example.jdbcTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.dao.ExecuteAsStatement;
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.dao.WeatherDao;
|
||||||
|
import com.taosdata.jdbc.example.jdbcTemplate.domain.Weather;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration({"classpath:applicationContext.xml"})
|
||||||
|
public class BatcherInsertTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WeatherDao weatherDao;
|
||||||
|
@Autowired
|
||||||
|
private ExecuteAsStatement executor;
|
||||||
|
|
||||||
|
private static final int numOfRecordsPerTable = 1000;
|
||||||
|
private static long ts = 1496732686000l;
|
||||||
|
private static Random random = new Random(System.currentTimeMillis());
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
// drop database
|
||||||
|
executor.doExecute("drop database if exists test");
|
||||||
|
// create database
|
||||||
|
executor.doExecute("create database if not exists test");
|
||||||
|
//use database
|
||||||
|
executor.doExecute("use test");
|
||||||
|
// create table
|
||||||
|
executor.doExecute("create table if not exists test.weather (ts timestamp, temperature int, humidity float)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void batchInsert() {
|
||||||
|
List<Weather> weatherList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < numOfRecordsPerTable; i++) {
|
||||||
|
ts += 1000;
|
||||||
|
Weather weather = new Weather(new Timestamp(ts), random.nextFloat() * 50.0f, random.nextInt(100));
|
||||||
|
weatherList.add(weather);
|
||||||
|
}
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
weatherDao.batchInsert(weatherList);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
System.out.println("batch insert(" + numOfRecordsPerTable + " rows) time cost ==========> " + (end - start) + " ms");
|
||||||
|
|
||||||
|
int count = weatherDao.count();
|
||||||
|
assertEquals(count, numOfRecordsPerTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ class TDTestCase:
|
||||||
tdLog.debug("start to execute %s" % __file__)
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
tdSql.init(conn.cursor(), logSql)
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
self.numOfRecords = 10
|
self.types = ["tinyint", "smallint", "int", "bigint", "float", "double", "bool", "binary(10)", "nchar(10)"]
|
||||||
self.ts = 1537146000000
|
self.ts = 1537146000000
|
||||||
|
|
||||||
def checkNullValue(self, result):
|
def checkNullValue(self, result):
|
||||||
|
@ -38,139 +38,41 @@ class TDTestCase:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def restartTaosd(self):
|
|
||||||
tdDnodes.stop(1)
|
|
||||||
tdDnodes.start(1)
|
|
||||||
tdSql.execute("use db")
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
print("==============step1")
|
for i in range(len(self.types)):
|
||||||
|
print("======== checking type %s ==========" % self.types[i])
|
||||||
|
tdSql.execute("create table t0 (ts timestamp, col %s)" % self.types[i])
|
||||||
|
tdSql.execute("insert into t0 values (%d, NULL)" % (self.ts))
|
||||||
|
|
||||||
tdSql.execute(
|
tdDnodes.stop(1)
|
||||||
"create table meters (ts timestamp, col1 int) tags(tgcol1 int)")
|
tdLog.sleep(10)
|
||||||
tdSql.execute("create table t0 using meters tags(NULL)")
|
tdDnodes.start(1)
|
||||||
|
tdSql.execute("use db")
|
||||||
for i in range (self.numOfRecords):
|
tdSql.query("select * from t0")
|
||||||
tdSql.execute("insert into t0 values (%d, %d)" % (self.ts + i, i));
|
|
||||||
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col2 tinyint")
|
|
||||||
tdSql.execute("alter table meters drop column col1")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col2 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col1 int")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col1 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col3 smallint")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col3 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col4 bigint")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col4 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col5 float")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col5 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col6 double")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col6 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col7 bool")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col7 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col8 binary(20)")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col8 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add column col9 nchar(20)")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select col9 from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add tag tgcol2 tinyint")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select tgcol2 from meters")
|
|
||||||
tdSql.checkRows(1)
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add tag tgcol3 smallint")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select tgcol3 from meters")
|
|
||||||
tdSql.checkRows(1)
|
|
||||||
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add tag tgcol4 bigint")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select tgcol4 from meters")
|
|
||||||
tdSql.checkRows(1)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add tag tgcol5 float")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select tgcol5 from meters")
|
|
||||||
tdSql.checkRows(1)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add tag tgcol6 double")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select tgcol6 from meters")
|
|
||||||
tdSql.checkRows(1)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add tag tgcol7 bool")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select tgcol7 from meters")
|
|
||||||
tdSql.checkRows(1)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add tag tgcol8 binary(20)")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select tgcol8 from meters")
|
|
||||||
tdSql.checkRows(1)
|
|
||||||
|
|
||||||
tdSql.execute("alter table meters add tag tgcol9 nchar(20)")
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
tdSql.query("select tgcol9 from meters")
|
|
||||||
tdSql.checkRows(1)
|
|
||||||
|
|
||||||
self.restartTaosd()
|
|
||||||
tdSql.query("select * from meters")
|
|
||||||
tdSql.checkRows(10)
|
|
||||||
if self.checkNullValue(tdSql.queryResult) is False:
|
if self.checkNullValue(tdSql.queryResult) is False:
|
||||||
tdLog.exit("non None value is detected")
|
tdLog.exit("no None value is detected")
|
||||||
|
|
||||||
|
tdSql.execute("create table t1 (ts timestamp, col %s)" % self.types[i])
|
||||||
|
tdSql.execute("insert into t1 values (%d, NULL)" % (self.ts))
|
||||||
|
tdDnodes.stop(1)
|
||||||
|
tdLog.sleep(10)
|
||||||
|
tdDnodes.start(1)
|
||||||
|
tdSql.execute("use db")
|
||||||
|
|
||||||
|
for j in range(150):
|
||||||
|
tdSql.execute("insert into t1 values (%d, NULL)" % (self.ts + j + 1));
|
||||||
|
|
||||||
|
tdSql.query("select * from t1")
|
||||||
|
tdSql.checkRows(151)
|
||||||
|
|
||||||
|
if self.checkNullValue(tdSql.queryResult) is False:
|
||||||
|
tdLog.exit("no None value is detected")
|
||||||
|
|
||||||
|
print("======== None value check for type %s is OK ==========" % self.types[i])
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
tdSql.close()
|
tdSql.close()
|
||||||
|
|
|
@ -53,7 +53,7 @@ system sh/exec.sh -n dnode2 -s start
|
||||||
system sh/exec.sh -n dnode3 -s start
|
system sh/exec.sh -n dnode3 -s start
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
sleep 3000
|
sleep 5000
|
||||||
|
|
||||||
$sleepTimer = 3000
|
$sleepTimer = 3000
|
||||||
|
|
||||||
|
@ -225,6 +225,7 @@ if $data00 != $totalRows then
|
||||||
endi
|
endi
|
||||||
|
|
||||||
print ============== step5: stop dnode2, and remove its vnode
|
print ============== step5: stop dnode2, and remove its vnode
|
||||||
|
sleep 5000
|
||||||
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
||||||
sleep $sleepTimer
|
sleep $sleepTimer
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,7 @@ if $data00 != $totalRows then
|
||||||
endi
|
endi
|
||||||
|
|
||||||
print ============== step5: stop dnode1
|
print ============== step5: stop dnode1
|
||||||
|
sleep 5000
|
||||||
system sh/exec.sh -n dnode1 -s stop
|
system sh/exec.sh -n dnode1 -s stop
|
||||||
sleep 3000
|
sleep 3000
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,15 @@ if $dnode4Vnodes != null then
|
||||||
goto show1
|
goto show1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
print ============================== step2
|
print ============================== step2
|
||||||
print ========= start dnode4
|
print ========= start dnode4
|
||||||
sql create dnode $hostname4
|
sql create dnode $hostname4
|
||||||
|
@ -132,6 +141,15 @@ if $dnode4Vnodes != 2 then
|
||||||
goto show2
|
goto show2
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
print ============================== step3
|
print ============================== step3
|
||||||
print ========= drop dnode2
|
print ========= drop dnode2
|
||||||
sql drop dnode $hostname2
|
sql drop dnode $hostname2
|
||||||
|
@ -167,6 +185,15 @@ if $dnode4Vnodes != 3 then
|
||||||
goto show3
|
goto show3
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
||||||
|
|
||||||
print ============================== step4
|
print ============================== step4
|
||||||
|
@ -195,6 +222,15 @@ if $dnode5Vnodes != 2 then
|
||||||
goto show4
|
goto show4
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
print ============================== step5
|
print ============================== step5
|
||||||
print ========= drop dnode3
|
print ========= drop dnode3
|
||||||
sql drop dnode $hostname3
|
sql drop dnode $hostname3
|
||||||
|
@ -232,6 +268,15 @@ endi
|
||||||
|
|
||||||
system sh/exec.sh -n dnode3 -s stop -x SIGINT
|
system sh/exec.sh -n dnode3 -s stop -x SIGINT
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
print ============================== step6
|
print ============================== step6
|
||||||
sql create dnode $hostname6
|
sql create dnode $hostname6
|
||||||
system sh/exec.sh -n dnode6 -s start
|
system sh/exec.sh -n dnode6 -s start
|
||||||
|
@ -258,6 +303,15 @@ if $dnode6Vnodes != 2 then
|
||||||
goto show6
|
goto show6
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
print ============================== step7
|
print ============================== step7
|
||||||
print ========= drop dnode4
|
print ========= drop dnode4
|
||||||
sql drop dnode $hostname4
|
sql drop dnode $hostname4
|
||||||
|
@ -294,6 +348,14 @@ if $dnode4Vnodes != null then
|
||||||
endi
|
endi
|
||||||
|
|
||||||
system sh/exec.sh -n dnode4 -s stop -x SIGINT
|
system sh/exec.sh -n dnode4 -s stop -x SIGINT
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
print ============================== step8
|
print ============================== step8
|
||||||
sql create dnode $hostname7
|
sql create dnode $hostname7
|
||||||
|
@ -321,6 +383,15 @@ if $dnode7Vnodes != 2 then
|
||||||
goto show8
|
goto show8
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
print ============================== step9
|
print ============================== step9
|
||||||
print ========= drop dnode1
|
print ========= drop dnode1
|
||||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||||
|
@ -335,15 +406,20 @@ sql show mnodes
|
||||||
$dnode1Role = $data2_1
|
$dnode1Role = $data2_1
|
||||||
$dnode4Role = $data2_4
|
$dnode4Role = $data2_4
|
||||||
$dnode5Role = $data2_5
|
$dnode5Role = $data2_5
|
||||||
print dnode1 ==> $dnode1Role
|
print dnode1 ==> $data2_1
|
||||||
print dnode4 ==> $dnode4Role
|
print dnode2 ==> $data2_2
|
||||||
print dnode5 ==> $dnode5Role
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
if $dnode1Role != offline then
|
if $dnode1Role != offline then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
print ============================== step9.1
|
print ============================== step9.1
|
||||||
|
sleep 2000
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
$x = 0
|
$x = 0
|
||||||
|
@ -353,6 +429,19 @@ show9:
|
||||||
if $x == 20 then
|
if $x == 20 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
$dnode1Role = $data2_1
|
||||||
|
$dnode4Role = $data2_4
|
||||||
|
$dnode5Role = $data2_5
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
sql show dnodes -x show9
|
sql show dnodes -x show9
|
||||||
$dnode5Vnodes = $data2_5
|
$dnode5Vnodes = $data2_5
|
||||||
print dnode5 $dnode5Vnodes
|
print dnode5 $dnode5Vnodes
|
||||||
|
@ -374,6 +463,15 @@ endi
|
||||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||||
sleep 5000
|
sleep 5000
|
||||||
|
|
||||||
|
sql show mnodes
|
||||||
|
print dnode1 ==> $data2_1
|
||||||
|
print dnode2 ==> $data2_2
|
||||||
|
print dnode3 ==> $data2_3
|
||||||
|
print dnode4 ==> $data2_4
|
||||||
|
print dnode5 ==> $data2_5
|
||||||
|
print dnode6 ==> $data2_6
|
||||||
|
print dnode7 ==> $data2_7
|
||||||
|
|
||||||
print ============================== step11
|
print ============================== step11
|
||||||
print ========= add db4
|
print ========= add db4
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,10 @@ system sh/exec.sh -n dnode1 -s start
|
||||||
sleep 3000
|
sleep 3000
|
||||||
sql connect
|
sql connect
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
|
system sh/exec.sh -n dnode2 -s start
|
||||||
system sh/exec.sh -n dnode3 -s start
|
system sh/exec.sh -n dnode3 -s start
|
||||||
|
sleep 3000
|
||||||
|
|
||||||
print ======== step1
|
print ======== step1
|
||||||
sql create database db replica 3 blocks 3
|
sql create database db replica 3 blocks 3
|
||||||
|
|
|
@ -18,13 +18,14 @@ system sh/cfg.sh -n dnode3 -c numOfMnodes -v 3
|
||||||
|
|
||||||
print ========== step1
|
print ========== step1
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
sleep 3000
|
||||||
sql connect
|
sql connect
|
||||||
|
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
system sh/exec.sh -n dnode2 -s start
|
||||||
sleep 3000
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
system sh/exec.sh -n dnode3 -s start
|
system sh/exec.sh -n dnode3 -s start
|
||||||
sleep 3000
|
sleep 5000
|
||||||
|
|
||||||
sql show dnodes
|
sql show dnodes
|
||||||
print dnode1 $data5_1
|
print dnode1 $data5_1
|
||||||
|
|
|
@ -31,8 +31,8 @@ sleep 3000
|
||||||
sql connect
|
sql connect
|
||||||
|
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
|
system sh/exec.sh -n dnode2 -s start
|
||||||
system sh/exec.sh -n dnode3 -s start
|
system sh/exec.sh -n dnode3 -s start
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@ system sh/exec.sh -n dnode1 -s start
|
||||||
sql connect
|
sql connect
|
||||||
|
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
|
system sh/exec.sh -n dnode2 -s start
|
||||||
system sh/exec.sh -n dnode3 -s start
|
system sh/exec.sh -n dnode3 -s start
|
||||||
|
|
||||||
$x = 0
|
$x = 0
|
||||||
|
|
|
@ -17,8 +17,8 @@ system sh/exec.sh -n dnode1 -s start
|
||||||
sql connect
|
sql connect
|
||||||
|
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
|
system sh/exec.sh -n dnode2 -s start
|
||||||
system sh/exec.sh -n dnode3 -s start
|
system sh/exec.sh -n dnode3 -s start
|
||||||
$x = 0
|
$x = 0
|
||||||
createDnode:
|
createDnode:
|
||||||
|
|
|
@ -21,10 +21,10 @@ system sh/exec.sh -n dnode1 -s start
|
||||||
sql connect
|
sql connect
|
||||||
|
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
system sh/exec.sh -n dnode3 -s start
|
|
||||||
sql create dnode $hostname4
|
sql create dnode $hostname4
|
||||||
|
system sh/exec.sh -n dnode2 -s start
|
||||||
|
system sh/exec.sh -n dnode3 -s start
|
||||||
system sh/exec.sh -n dnode4 -s start
|
system sh/exec.sh -n dnode4 -s start
|
||||||
|
|
||||||
$x = 0
|
$x = 0
|
||||||
|
|
|
@ -18,8 +18,8 @@ system sh/exec.sh -n dnode1 -s start
|
||||||
sql connect
|
sql connect
|
||||||
|
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
|
system sh/exec.sh -n dnode2 -s start
|
||||||
system sh/exec.sh -n dnode3 -s start
|
system sh/exec.sh -n dnode3 -s start
|
||||||
$x = 0
|
$x = 0
|
||||||
createDnode:
|
createDnode:
|
||||||
|
|
|
@ -21,10 +21,10 @@ system sh/exec.sh -n dnode1 -s start
|
||||||
sql connect
|
sql connect
|
||||||
|
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
system sh/exec.sh -n dnode3 -s start
|
|
||||||
sql create dnode $hostname4
|
sql create dnode $hostname4
|
||||||
|
system sh/exec.sh -n dnode2 -s start
|
||||||
|
system sh/exec.sh -n dnode3 -s start
|
||||||
system sh/exec.sh -n dnode4 -s start
|
system sh/exec.sh -n dnode4 -s start
|
||||||
$x = 0
|
$x = 0
|
||||||
createDnode:
|
createDnode:
|
||||||
|
|
|
@ -25,8 +25,8 @@ system sh/exec.sh -n dnode1 -s start
|
||||||
sleep 3000
|
sleep 3000
|
||||||
sql connect
|
sql connect
|
||||||
sql create dnode $hostname2
|
sql create dnode $hostname2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
|
||||||
sql create dnode $hostname3
|
sql create dnode $hostname3
|
||||||
|
system sh/exec.sh -n dnode2 -s start
|
||||||
system sh/exec.sh -n dnode3 -s start
|
system sh/exec.sh -n dnode3 -s start
|
||||||
sleep 3000
|
sleep 3000
|
||||||
|
|
||||||
|
|
|
@ -667,7 +667,7 @@ bool simExecuteNativeSqlCommand(SScript *script, char *rest, bool isSlow) {
|
||||||
|
|
||||||
TAOS_RES* pSql = NULL;
|
TAOS_RES* pSql = NULL;
|
||||||
|
|
||||||
for (int attempt = 0; attempt < 3; ++attempt) {
|
for (int attempt = 0; attempt < 10; ++attempt) {
|
||||||
simLogSql(rest, false);
|
simLogSql(rest, false);
|
||||||
pSql = taos_query(script->taos, rest);
|
pSql = taos_query(script->taos, rest);
|
||||||
ret = taos_errno(pSql);
|
ret = taos_errno(pSql);
|
||||||
|
|
Loading…
Reference in New Issue