Merge branch 'develop' into test/testcase
This commit is contained in:
commit
6a2a12fccb
|
@ -44,6 +44,7 @@ def pre_test(){
|
|||
git pull
|
||||
git fetch
|
||||
git checkout ${CHANGE_BRANCH}
|
||||
git pull
|
||||
git merge develop
|
||||
cd ${WK}
|
||||
git reset --hard
|
||||
|
@ -79,14 +80,25 @@ pipeline {
|
|||
changeRequest()
|
||||
}
|
||||
parallel {
|
||||
stage('python') {
|
||||
agent{label 'pytest'}
|
||||
stage('python_1') {
|
||||
agent{label 'p1'}
|
||||
steps {
|
||||
|
||||
pre_test()
|
||||
sh '''
|
||||
cd ${WKC}/tests
|
||||
./test-all.sh pytestfq
|
||||
./test-all.sh p1
|
||||
date'''
|
||||
}
|
||||
}
|
||||
stage('python_2') {
|
||||
agent{label 'p2'}
|
||||
steps {
|
||||
|
||||
pre_test()
|
||||
sh '''
|
||||
cd ${WKC}/tests
|
||||
./test-all.sh p2
|
||||
date'''
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ PROJECT(TDengine)
|
|||
IF (DEFINED VERNUMBER)
|
||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||
ELSE ()
|
||||
SET(TD_VER_NUMBER "2.0.11.0")
|
||||
SET(TD_VER_NUMBER "2.0.12.0")
|
||||
ENDIF ()
|
||||
|
||||
IF (DEFINED VERCOMPATIBLE)
|
||||
|
|
|
@ -128,5 +128,18 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
|
|||
|
||||
## [培训和FAQ](https://www.taosdata.com/cn/faq)
|
||||
|
||||
- [FAQ](https://www.taosdata.com/cn/documentation20/faq):常见问题与答案
|
||||
- [应用案列](https://www.taosdata.com/cn/blog/?categories=4):一些使用实例来解释如何使用TDengine
|
||||
<ul>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/12/25/2126.html">技术公开课:开源、高效的物联网大数据平台,TDengine内核技术剖析</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1941.html">TDengine视频教程-快速上手</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1945.html">TDengine视频教程-数据建模</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1961.html">TDengine视频教程-集群搭建</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1951.html">TDengine视频教程-Go Connector</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1955.html">TDengine视频教程-JDBC Connector</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1957.html">TDengine视频教程-NodeJS Connector</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1963.html">TDengine视频教程-Python Connector</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1965.html">TDengine视频教程-RESTful Connector</a></li>
|
||||
<li><a l href="https://www.taosdata.com/blog/2020/11/11/1959.html">TDengine视频教程-“零”代码运维监控</a></li>
|
||||
<li><a l href="https://www.taosdata.com/cn/documentation20/faq">FAQ:常见问题与答案</a></li>
|
||||
<li><a l href="https://www.taosdata.com/cn/blog/?categories=4"> 应用案例:一些使用实例来解释如何使用TDengine</a></li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ TDengine的安装非常简单,从下载到安装成功仅仅只要几秒钟。
|
|||
- TDengine-server-2.0.10.0-Linux-x64.deb (2.7M)
|
||||
- TDengine-server-2.0.10.0-Linux-x64.tar.gz (4.5M)
|
||||
|
||||
具体的安装过程,请参见<a href="https://www.taosdata.com/blog/2019/08/09/566.html">TDengine多种安装包的安装和卸载</a>。
|
||||
具体的安装过程,请参见<a href="https://www.taosdata.com/blog/2019/08/09/566.html">TDengine多种安装包的安装和卸载</a>以及<a href="https://www.taosdata.com/blog/2020/11/11/1941.html">视频教程</a>。
|
||||
|
||||
## 轻松启动
|
||||
|
||||
|
|
|
@ -59,3 +59,5 @@ INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 21
|
|||
TDengine支持多列模型,只要物理量是一个数据采集点同时采集的(时间戳一致),这些量就可以作为不同列放在一张超级表里。但还有一种极限的设计,单列模型,每个采集的物理量都单独建表,因此每种类型的物理量都单独建立一超级表。比如电流、电压、相位,就建三张超级表。
|
||||
|
||||
TDengine建议尽可能采用多列模型,因为插入效率以及存储效率更高。但对于有些场景,一个采集点的采集量的种类经常变化,这个时候,如果采用多列模型,就需要频繁修改超级表的结构定义,让应用变的复杂,这个时候,采用单列模型会显得简单。
|
||||
|
||||
关于数据建模请参考<a href="https://www.taosdata.com/blog/2020/11/11/1945.html">视频教程</a>。
|
||||
|
|
|
@ -226,3 +226,5 @@ SHOW MNODES;
|
|||
如果副本数为偶数,当一个vnode group里一半vnode不工作时,是无法从中选出master的。同理,一半mnode不工作时,是无法选出mnode的master的,因为存在“split brain”问题。为解决这个问题,TDengine引入了arbitrator的概念。Arbitrator模拟一个vnode或mnode在工作,但只简单的负责网络连接,不处理任何数据插入或访问。只要包含arbitrator在内,超过半数的vnode或mnode工作,那么该vnode group或mnode组就可以正常的提供数据插入或查询服务。比如对于副本数为2的情形,如果一个节点A离线,但另外一个节点B正常,而且能连接到arbitrator, 那么节点B就能正常工作。
|
||||
|
||||
TDengine提供一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。请点击[安装包下载](https://www.taosdata.com/cn/all-downloads/),在TDengine Arbitrator Linux一节中,选择适合的版本下载并安装。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6042。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的arbitrator。如果副本数为奇数,即使配置了arbitrator, 系统也不会去建立连接。
|
||||
|
||||
关于集群搭建请参考<a href="https://www.taosdata.com/blog/2020/11/11/1961.html">视频教程</a>。
|
||||
|
|
|
@ -187,7 +187,7 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
|
|||
- pass:密码
|
||||
- db:数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库
|
||||
- port:端口号
|
||||
|
||||
|
||||
返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。
|
||||
|
||||
- `char *taos_get_server_info(TAOS *taos)`
|
||||
|
@ -336,7 +336,7 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线
|
|||
- `TAOS_RES* taos_stmt_use_result(TAOS_STMT *stmt)`
|
||||
|
||||
获取语句的结果集。结果集的使用方式与非参数化调用时一致,使用完成后,应对此结果集调用 `taos_free_result`以释放资源。
|
||||
|
||||
|
||||
- `int taos_stmt_close(TAOS_STMT *stmt)`
|
||||
|
||||
执行完毕,释放所有资源。
|
||||
|
@ -354,7 +354,7 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
|
|||
* stime:是流式计算开始的时间,如果是0,表示从现在开始,如果不为零,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)
|
||||
* param:是应用提供的用于回调的一个参数,回调时,提供给应用
|
||||
* callback: 第二个回调函数,会在连续查询自动停止时被调用。
|
||||
|
||||
|
||||
返回值为NULL,表示创建成功,返回值不为空,表示成功。
|
||||
|
||||
- `void taos_close_stream (TAOS_STREAM *tstr)`
|
||||
|
@ -394,6 +394,8 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
|
|||
|
||||
## Python Connector
|
||||
|
||||
Python连接器的使用参见<a href="https://www.taosdata.com/blog/2020/11/11/1963.html">视频教程</a>
|
||||
|
||||
### 安装准备
|
||||
* 应用驱动安装请参考<a href="https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤">安装连接器驱动步骤</a>。
|
||||
* 已安装python 2.7 or >= 3.4
|
||||
|
@ -433,7 +435,7 @@ python -m pip install python3\
|
|||
* 导入TDengine客户端模块
|
||||
|
||||
```python
|
||||
import taos
|
||||
import taos
|
||||
```
|
||||
* 获取连接并获取游标对象
|
||||
```python
|
||||
|
@ -445,7 +447,7 @@ c1 = conn.cursor()
|
|||
* 写入数据
|
||||
```python
|
||||
import datetime
|
||||
|
||||
|
||||
# 创建数据库
|
||||
c1.execute('create database db')
|
||||
c1.execute('use db')
|
||||
|
@ -473,7 +475,7 @@ numOfRows = c1.rowcount
|
|||
numOfCols = len(c1.description)
|
||||
for irow in range(numOfRows):
|
||||
print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2]))
|
||||
|
||||
|
||||
# 直接使用cursor 循环拉取查询结果
|
||||
c1.execute('select * from tb')
|
||||
for data in c1:
|
||||
|
@ -534,7 +536,7 @@ conn.close()
|
|||
|
||||
## RESTful Connector
|
||||
|
||||
为支持各种不同类型平台的开发,TDengine提供符合REST设计标准的API,即RESTful API。为最大程度降低学习成本,不同于其他数据库RESTful API的设计方法,TDengine直接通过HTTP POST 请求BODY中包含的SQL语句来操作数据库,仅需要一个URL。
|
||||
为支持各种不同类型平台的开发,TDengine提供符合REST设计标准的API,即RESTful API。为最大程度降低学习成本,不同于其他数据库RESTful API的设计方法,TDengine直接通过HTTP POST 请求BODY中包含的SQL语句来操作数据库,仅需要一个URL。RESTful连接器的使用参见<a href=https://www.taosdata.com/blog/2020/11/11/1965.html>视频教程</a>。
|
||||
|
||||
### HTTP请求格式
|
||||
|
||||
|
@ -779,7 +781,7 @@ https://www.taosdata.com/blog/2020/11/02/1901.html
|
|||
|
||||
TDengine提供了GO驱动程序`taosSql`。 `taosSql`实现了GO语言的内置接口`database/sql/driver`。用户只需按如下方式引入包就可以在应用程序中访问TDengine, 详见`https://github.com/taosdata/driver-go/blob/develop/taosSql/driver_test.go`。
|
||||
|
||||
使用 Go 连接器的示例代码请参考 https://github.com/taosdata/TDengine/tree/develop/tests/examples/go。
|
||||
使用 Go 连接器的示例代码请参考 https://github.com/taosdata/TDengine/tree/develop/tests/examples/go 以及<a href="https://www.taosdata.com/blog/2020/11/11/1951.html">视频教程</a>。
|
||||
|
||||
```Go
|
||||
import (
|
||||
|
@ -796,7 +798,7 @@ go env -w GOPROXY=https://goproxy.io,direct
|
|||
|
||||
### 常用API
|
||||
|
||||
- sql.Open(DRIVER_NAME string, dataSourceName string) *DB`
|
||||
- `sql.Open(DRIVER_NAME string, dataSourceName string) *DB`
|
||||
|
||||
该API用来打开DB,返回一个类型为*DB的对象,一般情况下,DRIVER_NAME设置为字符串`taosSql`, dataSourceName设置为字符串`user:password@/tcp(host:port)/dbname`,如果客户想要用多个goroutine并发访问TDengine, 那么需要在各个goroutine中分别创建一个sql.Open对象并用之访问TDengine
|
||||
|
||||
|
@ -835,6 +837,8 @@ Node.js连接器支持的系统有:
|
|||
| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
|
||||
| **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** |
|
||||
|
||||
Node.js连接器的使用参见<a href="https://www.taosdata.com/blog/2020/11/11/1957.html">视频教程</a>
|
||||
|
||||
### 安装准备
|
||||
|
||||
* 应用驱动安装请参考<a href="https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤">安装连接器驱动步骤</a>。
|
||||
|
@ -909,7 +913,7 @@ node nodejsChecker.js host=localhost
|
|||
|
||||
#### 建立连接
|
||||
|
||||
使用node.js连接器时,必须先<em>require</em> ```td2.0-connector```,然后使用 ```taos.connect``` 函数。```taos.connect``` 函数必须提供的参数是```host```,其它参数在没有提供的情况下会使用如下的默认值。最后需要初始化```cursor``` 来和TDengine服务端通信
|
||||
使用node.js连接器时,必须先<em>require</em> `td2.0-connector`,然后使用 `taos.connect` 函数。`taos.connect` 函数必须提供的参数是`host`,其它参数在没有提供的情况下会使用如下的默认值。最后需要初始化`cursor` 来和TDengine服务端通信
|
||||
|
||||
```javascript
|
||||
const taos = require('td2.0-connector');
|
||||
|
@ -945,13 +949,13 @@ TDengine目前还不支持update和delete语句。
|
|||
|
||||
#### 查询
|
||||
|
||||
可通过 ```cursor.query``` 函数来查询数据库。
|
||||
可通过 `cursor.query` 函数来查询数据库。
|
||||
|
||||
```javascript
|
||||
var query = cursor.query('show databases;')
|
||||
```
|
||||
|
||||
查询的结果可以通过 ```query.execute()``` 函数获取并打印出来
|
||||
查询的结果可以通过 `query.execute()` 函数获取并打印出来
|
||||
|
||||
```javascript
|
||||
var promise = query.execute();
|
||||
|
@ -959,7 +963,7 @@ promise.then(function(result) {
|
|||
result.pretty();
|
||||
});
|
||||
```
|
||||
格式化查询语句还可以使用```query```的```bind```方法。如下面的示例:```query```会自动将提供的数值填入查询语句的```?```里。
|
||||
格式化查询语句还可以使用`query`的`bind`方法。如下面的示例:`query`会自动将提供的数值填入查询语句的`?`里。
|
||||
|
||||
```javascript
|
||||
var query = cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?;').bind(new Date(), 5);
|
||||
|
@ -967,7 +971,7 @@ query.execute().then(function(result) {
|
|||
result.pretty();
|
||||
})
|
||||
```
|
||||
如果在```query```语句里提供第二个参数并设为```true```也可以立即获取查询结果。如下:
|
||||
如果在`query`语句里提供第二个参数并设为`true`也可以立即获取查询结果。如下:
|
||||
|
||||
```javascript
|
||||
var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true)
|
||||
|
@ -991,4 +995,4 @@ promise2.then(function(result) {
|
|||
### 示例
|
||||
<a href="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js">这里</a>提供了一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例
|
||||
|
||||
<a href="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js">这里</a>同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`cursor`.
|
||||
<a href="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js">这里</a>同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`cursor`.
|
||||
|
|
|
@ -6,6 +6,8 @@ Java连接器支持的系统有:
|
|||
| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
|
||||
| **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** |
|
||||
|
||||
Java连接器的使用请参见<a href=https://www.taosdata.com/blog/2020/11/11/1955.html>视频教程</a>。
|
||||
|
||||
TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现。目前可以通过 [Sonatype Repository][1] 搜索并下载。
|
||||
|
||||
由于 TDengine 是使用 c 语言开发的,使用 taos-jdbcdriver 驱动包时需要依赖系统对应的本地函数库。
|
||||
|
|
|
@ -265,8 +265,14 @@ function install_config() {
|
|||
[ -f ${cfg_dir}/taos.cfg ] && ${csudo} cp ${cfg_dir}/taos.cfg ${cfg_install_dir}
|
||||
${csudo} chmod 644 ${cfg_install_dir}/*
|
||||
fi
|
||||
|
||||
# Save standard input to 6 and open / dev / TTY on standard input
|
||||
exec 6<&0 0</dev/tty
|
||||
|
||||
local_fqdn_check
|
||||
|
||||
# restore the backup standard input, and turn off 6
|
||||
exec 0<&6 6<&-
|
||||
|
||||
${csudo} mv ${cfg_dir}/taos.cfg ${cfg_dir}/taos.cfg.org
|
||||
${csudo} ln -s ${cfg_install_dir}/taos.cfg ${cfg_dir}
|
||||
|
@ -422,7 +428,7 @@ function install_service() {
|
|||
}
|
||||
|
||||
function install_TDengine() {
|
||||
echo -e "${GREEN}Start to install TDEngine...${NC}"
|
||||
echo -e "${GREEN}Start to install TDengine...${NC}"
|
||||
|
||||
#install log and data dir , then ln to /usr/local/taos
|
||||
${csudo} mkdir -p ${log_dir} && ${csudo} chmod 777 ${log_dir}
|
||||
|
|
|
@ -119,4 +119,4 @@ if ((${service_mod}==2)); then
|
|||
kill_taosd
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}TDEngine is removed successfully!${NC}"
|
||||
echo -e "${GREEN}TDengine is removed successfully!${NC}"
|
||||
|
|
|
@ -2,19 +2,39 @@
|
|||
#
|
||||
# This file is used to set config for core when taosd crash
|
||||
|
||||
set -e
|
||||
# Color setting
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[1;32m'
|
||||
GREEN_DARK='\033[0;32m'
|
||||
GREEN_UNDERLINE='\033[4;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
# set -e
|
||||
# set -x
|
||||
corePath=$1
|
||||
|
||||
csudo=""
|
||||
if command -v sudo > /dev/null; then
|
||||
csudo="sudo"
|
||||
fi
|
||||
|
||||
#ulimit -c unlimited
|
||||
if [[ ! -n ${corePath} ]]; then
|
||||
echo -e -n "${GREEN}Please enter a file directory to save the coredump file${NC}:"
|
||||
read corePath
|
||||
while true; do
|
||||
if [[ ! -z "$corePath" ]]; then
|
||||
break
|
||||
else
|
||||
read -p "Please enter a file directory to save the coredump file:" corePath
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
ulimit -c unlimited
|
||||
${csudo} sed -i '/ulimit -c unlimited/d' /etc/profile ||:
|
||||
${csudo} sed -i '$a\ulimit -c unlimited' /etc/profile ||:
|
||||
source /etc/profile
|
||||
|
||||
${csudo} mkdir -p /coredump ||:
|
||||
${csudo} sysctl -w kernel.core_pattern='/coredump/core-%e-%p' ||:
|
||||
${csudo} echo '/coredump/core-%e-%p' | ${csudo} tee /proc/sys/kernel/core_pattern ||:
|
||||
${csudo} mkdir -p ${corePath} ||:
|
||||
${csudo} sysctl -w kernel.core_pattern=${corePath}/core-%e-%p ||:
|
||||
${csudo} echo "${corePath}/core-%e-%p" | ${csudo} tee /proc/sys/kernel/core_pattern ||:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: tdengine
|
||||
base: core18
|
||||
version: '2.0.11.0'
|
||||
version: '2.0.12.0'
|
||||
icon: snap/gui/t-dengine.svg
|
||||
summary: an open-source big data platform designed and optimized for IoT.
|
||||
description: |
|
||||
|
@ -72,7 +72,7 @@ parts:
|
|||
- usr/bin/taosd
|
||||
- usr/bin/taos
|
||||
- usr/bin/taosdemo
|
||||
- usr/lib/libtaos.so.2.0.11.0
|
||||
- usr/lib/libtaos.so.2.0.12.0
|
||||
- usr/lib/libtaos.so.1
|
||||
- usr/lib/libtaos.so
|
||||
|
||||
|
|
|
@ -66,6 +66,77 @@ static bool bnCheckFree(SDnodeObj *pDnode) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void bnSwapVnodeGid(SVnodeGid *pVnodeGid1, SVnodeGid *pVnodeGid2) {
|
||||
SVnodeGid tmp = *pVnodeGid1;
|
||||
*pVnodeGid1 = *pVnodeGid2;
|
||||
*pVnodeGid2 = tmp;
|
||||
}
|
||||
|
||||
static void bnAdjustVnodeIndex(SVgObj *pInVg) {
|
||||
int32_t d0Id = pInVg->vnodeGid[0].dnodeId;
|
||||
int32_t d1Id = pInVg->vnodeGid[1].dnodeId;
|
||||
int32_t d2Id = pInVg->vnodeGid[2].dnodeId;
|
||||
|
||||
int32_t vgId = pInVg->vgId;
|
||||
int32_t d0Num = 0;
|
||||
int32_t d1Num = 0;
|
||||
int32_t d2Num = 0;
|
||||
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SVgObj *pVgroup = NULL;
|
||||
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
||||
if (pVgroup == NULL) break;
|
||||
|
||||
if (pVgroup->vgId != vgId) {
|
||||
if (pVgroup->vnodeGid[0].dnodeId == d0Id) d0Num++;
|
||||
if (pVgroup->vnodeGid[0].dnodeId == d1Id) d1Num++;
|
||||
if (pVgroup->vnodeGid[0].dnodeId == d2Id) d2Num++;
|
||||
}
|
||||
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
}
|
||||
|
||||
if (pInVg->numOfVnodes == 1) {
|
||||
}
|
||||
|
||||
if (pInVg->numOfVnodes == 2) {
|
||||
mDebug("vgId:%d, dnode:%d num:%d dnode:%d num:%d", pInVg->vgId, d0Id, d0Num, d1Id, d1Num);
|
||||
if (d0Num > d1Num) {
|
||||
mDebug("vgId:%d, adjust vnode index 0 to 1", pInVg->vgId);
|
||||
bnSwapVnodeGid(&pInVg->vnodeGid[0], &pInVg->vnodeGid[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (pInVg->numOfVnodes >= 3) {
|
||||
mDebug("vgId:%d, dnode:%d num:%d dnode:%d num:%d dnode:%d num:%d", pInVg->vgId, d0Id, d0Num, d1Id, d1Num, d2Id, d2Num);
|
||||
if (d0Num <= d1Num && d0Num <= d2Num) {
|
||||
if (d1Num > d2Num) {
|
||||
mDebug("vgId:%d, adjust vnode index 1 to 2", pInVg->vgId);
|
||||
bnSwapVnodeGid(&pInVg->vnodeGid[1], &pInVg->vnodeGid[2]);
|
||||
}
|
||||
} else if (d1Num <= d2Num && d1Num <= d0Num) {
|
||||
mDebug("vgId:%d, adjust vnode index 0 to 1", pInVg->vgId);
|
||||
bnSwapVnodeGid(&pInVg->vnodeGid[0], &pInVg->vnodeGid[1]);
|
||||
if (d0Num > d2Num) {
|
||||
mDebug("vgId:%d, adjust vnode index 1 to 2", pInVg->vgId);
|
||||
bnSwapVnodeGid(&pInVg->vnodeGid[1], &pInVg->vnodeGid[2]);
|
||||
}
|
||||
} else {
|
||||
mDebug("vgId:%d, adjust vnode index 0 to 2", pInVg->vgId);
|
||||
bnSwapVnodeGid(&pInVg->vnodeGid[0], &pInVg->vnodeGid[2]);
|
||||
if (d1Num > d0Num) {
|
||||
mDebug("vgId:%d, adjust vnode index 1 to 2", pInVg->vgId);
|
||||
bnSwapVnodeGid(&pInVg->vnodeGid[1], &pInVg->vnodeGid[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < pInVg->numOfVnodes; ++i) {
|
||||
mDebug("vgId:%d index:%d dnodeId:%d", pInVg->vgId, i, pInVg->vnodeGid[i].dnodeId);
|
||||
}
|
||||
}
|
||||
|
||||
static void bnDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
|
||||
mDebug("vgId:%d, dnode:%d is dropping", pVgroup->vgId, pVnodeGid->dnodeId);
|
||||
|
||||
|
@ -88,15 +159,10 @@ static void bnDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
|
|||
memcpy(pVgroup->vnodeGid, vnodeGid, TSDB_MAX_REPLICA * sizeof(SVnodeGid));
|
||||
pVgroup->numOfVnodes = numOfVnodes;
|
||||
|
||||
bnAdjustVnodeIndex(pVgroup);
|
||||
mnodeUpdateVgroup(pVgroup);
|
||||
}
|
||||
|
||||
static void bnSwapVnodeGid(SVnodeGid *pVnodeGid1, SVnodeGid *pVnodeGid2) {
|
||||
SVnodeGid tmp = *pVnodeGid1;
|
||||
*pVnodeGid1 = *pVnodeGid2;
|
||||
*pVnodeGid2 = tmp;
|
||||
}
|
||||
|
||||
int32_t bnAllocVnodes(SVgObj *pVgroup) {
|
||||
int32_t dnode = 0;
|
||||
int32_t vnodes = 0;
|
||||
|
@ -147,6 +213,7 @@ int32_t bnAllocVnodes(SVgObj *pVgroup) {
|
|||
}
|
||||
}
|
||||
|
||||
bnAdjustVnodeIndex(pVgroup);
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -233,6 +300,7 @@ static int32_t bnAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj *pDes
|
|||
vnodeGids[numOfVnodes].pDnode = pDestDnode;
|
||||
numOfVnodes++;
|
||||
|
||||
// move the src vnode to the end
|
||||
for (int32_t v = 0; v < numOfVnodes; ++v) {
|
||||
if (pSrcDnode != NULL && pSrcDnode->dnodeId == vnodeGids[v].dnodeId) {
|
||||
bnSwapVnodeGid(&vnodeGids[v], &vnodeGids[numOfVnodes - 1]);
|
||||
|
@ -241,6 +309,11 @@ static int32_t bnAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj *pDes
|
|||
}
|
||||
}
|
||||
|
||||
// adjust the vgroup postion
|
||||
if (pSrcDnode == NULL) {
|
||||
bnAdjustVnodeIndex(pVgroup);
|
||||
}
|
||||
|
||||
memcpy(&pVgroup->vnodeGid, &vnodeGids, sizeof(SVnodeGid) * TSDB_MAX_REPLICA);
|
||||
pVgroup->numOfVnodes = numOfVnodes;
|
||||
atomic_add_fetch_32(&pDestDnode->openVnodes, 1);
|
||||
|
@ -330,7 +403,7 @@ void bnReset() {
|
|||
tsAccessSquence = 0;
|
||||
}
|
||||
|
||||
static int32_t bnMonitorVgroups() {
|
||||
static bool bnMonitorVgroups() {
|
||||
void * pIter = NULL;
|
||||
SVgObj *pVgroup = NULL;
|
||||
bool hasUpdatingVgroup = false;
|
||||
|
@ -489,6 +562,7 @@ void bnCheckStatus() {
|
|||
mInfo("dnode:%d, set to offline state, access seq:%d last seq:%d laststat:%d", pDnode->dnodeId, tsAccessSquence,
|
||||
pDnode->lastAccess, pDnode->status);
|
||||
bnSetVgroupOffline(pDnode);
|
||||
bnStartTimer(3000);
|
||||
}
|
||||
}
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
|
|
|
@ -31,7 +31,10 @@ static void *bnThreadFunc(void *arg) {
|
|||
}
|
||||
|
||||
pthread_cond_wait(&tsBnThread.cond, &tsBnThread.mutex);
|
||||
mDebug("balance thread wakes up to work");
|
||||
bool updateSoon = bnStart();
|
||||
mDebug("balance thread finished this poll, updateSoon:%d", updateSoon);
|
||||
|
||||
bnStartTimer(updateSoon ? 1000 : -1);
|
||||
pthread_mutex_unlock(&(tsBnThread.mutex));
|
||||
}
|
||||
|
@ -101,8 +104,8 @@ static void bnProcessTimer(void *handle, void *tmrId) {
|
|||
tsBnThread.timer = NULL;
|
||||
tsAccessSquence++;
|
||||
|
||||
bnCheckStatus();
|
||||
bnStartTimer(-1);
|
||||
bnCheckStatus();
|
||||
|
||||
if (handle == NULL) {
|
||||
if (tsAccessSquence % tsBalanceInterval == 0) {
|
||||
|
@ -121,6 +124,7 @@ void bnStartTimer(int64_t mseconds) {
|
|||
|
||||
bool updateSoon = (mseconds != -1);
|
||||
if (updateSoon) {
|
||||
mTrace("balance function will be called after %" PRId64 " ms", mseconds);
|
||||
taosTmrReset(bnProcessTimer, mseconds, (void *)mseconds, tsMnodeTmr, &tsBnThread.timer);
|
||||
} else {
|
||||
taosTmrReset(bnProcessTimer, tsStatusInterval * 1000, NULL, tsMnodeTmr, &tsBnThread.timer);
|
||||
|
|
|
@ -38,12 +38,6 @@ typedef struct SLocalDataSource {
|
|||
tFilePage filePage;
|
||||
} SLocalDataSource;
|
||||
|
||||
enum {
|
||||
TSC_LOCALREDUCE_READY = 0x0,
|
||||
TSC_LOCALREDUCE_IN_PROGRESS = 0x1,
|
||||
TSC_LOCALREDUCE_TOBE_FREED = 0x2,
|
||||
};
|
||||
|
||||
typedef struct SLocalReducer {
|
||||
SLocalDataSource ** pLocalDataSrc;
|
||||
int32_t numOfBuffer;
|
||||
|
@ -56,7 +50,6 @@ typedef struct SLocalReducer {
|
|||
tFilePage * pTempBuffer;
|
||||
struct SQLFunctionCtx *pCtx;
|
||||
int32_t rowSize; // size of each intermediate result.
|
||||
int32_t status; // denote it is in reduce process, in reduce process, it
|
||||
bool hasPrevRow; // cannot be released
|
||||
bool hasUnprocessedRow;
|
||||
tOrderDescriptor * pDesc;
|
||||
|
|
|
@ -22,8 +22,8 @@ extern "C" {
|
|||
|
||||
#include "tlog.h"
|
||||
|
||||
extern uint32_t cDebugFlag;
|
||||
extern uint32_t tscEmbedded;
|
||||
extern int32_t cDebugFlag;
|
||||
extern int8_t tscEmbedded;
|
||||
|
||||
#define tscFatal(...) do { if (cDebugFlag & DEBUG_FATAL) { taosPrintLog("TSC FATAL ", tscEmbedded ? 255 : cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscError(...) do { if (cDebugFlag & DEBUG_ERROR) { taosPrintLog("TSC ERROR ", tscEmbedded ? 255 : cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
|
|
|
@ -69,9 +69,10 @@ typedef struct STableMeta {
|
|||
int16_t sversion;
|
||||
int16_t tversion;
|
||||
char sTableId[TSDB_TABLE_FNAME_LEN];
|
||||
SVgroupInfo vgroupInfo;
|
||||
int32_t vgId;
|
||||
SCorVgroupInfo corVgroupInfo;
|
||||
STableId id;
|
||||
// union {int64_t stableUid; SSchema* schema;};
|
||||
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
||||
} STableMeta;
|
||||
|
||||
|
@ -307,6 +308,7 @@ typedef struct STscObj {
|
|||
SRpcCorEpSet *tscCorMgmtEpSet;
|
||||
void* pDnodeConn;
|
||||
pthread_mutex_t mutex;
|
||||
int32_t numOfObj; // number of sqlObj from this tscObj
|
||||
} STscObj;
|
||||
|
||||
typedef struct SSubqueryState {
|
||||
|
@ -419,7 +421,7 @@ void tscCloseTscObj(void *pObj);
|
|||
// todo move to taos? or create a new file: taos_internal.h
|
||||
TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int),
|
||||
void *param, TAOS **taos);
|
||||
TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, TAOS_RES** res);
|
||||
TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, int64_t* res);
|
||||
void waitForQueryRsp(void *param, TAOS_RES *tres, int code);
|
||||
|
||||
void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, __async_cb_func_t fp, void *param, const char *sqlstr, size_t sqlLen);
|
||||
|
@ -477,14 +479,14 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
|
|||
}
|
||||
}
|
||||
|
||||
extern SCacheObj* tscMetaCache;
|
||||
extern int tscObjRef;
|
||||
extern void * tscTmr;
|
||||
extern void * tscQhandle;
|
||||
extern int tscKeepConn[];
|
||||
extern int tscNumOfThreads;
|
||||
extern int tscRefId;
|
||||
|
||||
extern SCacheObj *tscMetaCache;
|
||||
|
||||
extern int tscObjRef;
|
||||
extern void *tscTmr;
|
||||
extern void *tscQhandle;
|
||||
extern int tscKeepConn[];
|
||||
extern int tscRefId;
|
||||
extern int tscNumOfObj; // number of existed sqlObj in current process.
|
||||
|
||||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||
|
||||
|
|
|
@ -388,10 +388,10 @@ void tscQueueAsyncRes(SSqlObj *pSql) {
|
|||
return;
|
||||
}
|
||||
|
||||
assert(pSql->res.code != TSDB_CODE_SUCCESS);
|
||||
tscError("%p add into queued async res, code:%s", pSql, tstrerror(pSql->res.code));
|
||||
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
if (pSql->fp == NULL || pSql->fetchFp == NULL){
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2597,14 +2597,23 @@ static void percentile_next_step(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
static void buildHistogramInfo(SAPercentileInfo* pInfo) {
|
||||
pInfo->pHisto = (SHistogramInfo*) ((char*) pInfo + sizeof(SAPercentileInfo));
|
||||
pInfo->pHisto->elems = (SHistBin*) ((char*)pInfo->pHisto + sizeof(SHistogramInfo));
|
||||
}
|
||||
|
||||
static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) {
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
SAPercentileInfo* pInfo = NULL;
|
||||
|
||||
if (pCtx->stableQuery && pCtx->currentStage != SECONDARY_STAGE_MERGE) {
|
||||
return (SAPercentileInfo*) pCtx->aOutputBuf;
|
||||
pInfo = (SAPercentileInfo*) pCtx->aOutputBuf;
|
||||
} else {
|
||||
return GET_ROWCELL_INTERBUF(pResInfo);
|
||||
pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
}
|
||||
|
||||
buildHistogramInfo(pInfo);
|
||||
return pInfo;
|
||||
}
|
||||
|
||||
static bool apercentile_function_setup(SQLFunctionCtx *pCtx) {
|
||||
|
@ -2624,6 +2633,8 @@ static void apercentile_function(SQLFunctionCtx *pCtx) {
|
|||
|
||||
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
|
||||
SAPercentileInfo *pInfo = getAPerctInfo(pCtx);
|
||||
|
||||
assert(pInfo->pHisto->elems != NULL);
|
||||
|
||||
for (int32_t i = 0; i < pCtx->size; ++i) {
|
||||
char *data = GET_INPUT_CHAR_INDEX(pCtx, i);
|
||||
|
|
|
@ -93,7 +93,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
|
|||
|
||||
// for top/bottom function, the output of timestamp is the first column
|
||||
int32_t functionId = pExpr->functionId;
|
||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) {
|
||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
|
||||
pCtx->ptsOutputBuf = pReducer->pCtx[0].aOutputBuf;
|
||||
pCtx->param[2].i64Key = pQueryInfo->order.order;
|
||||
pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT;
|
||||
|
@ -493,13 +493,6 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
|
|||
// there is no more result, so we release all allocated resource
|
||||
SLocalReducer *pLocalReducer = (SLocalReducer *)atomic_exchange_ptr(&pRes->pLocalReducer, NULL);
|
||||
if (pLocalReducer != NULL) {
|
||||
int32_t status = 0;
|
||||
while ((status = atomic_val_compare_exchange_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY,
|
||||
TSC_LOCALREDUCE_TOBE_FREED)) == TSC_LOCALREDUCE_IN_PROGRESS) {
|
||||
taosMsleep(100);
|
||||
tscDebug("%p waiting for delete procedure, status: %d", pSql, status);
|
||||
}
|
||||
|
||||
pLocalReducer->pFillInfo = taosDestroyFillInfo(pLocalReducer->pFillInfo);
|
||||
|
||||
if (pLocalReducer->pCtx != NULL) {
|
||||
|
@ -1303,6 +1296,10 @@ void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) {// re
|
|||
for (int32_t i = 0; i < t; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
pLocalReducer->pCtx[i].aOutputBuf = pLocalReducer->pResultBuf->data + pExpr->offset * pLocalReducer->resColModel->capacity;
|
||||
|
||||
if (pExpr->functionId == TSDB_FUNC_TOP || pExpr->functionId == TSDB_FUNC_BOTTOM || pExpr->functionId == TSDB_FUNC_DIFF) {
|
||||
pLocalReducer->pCtx[i].ptsOutputBuf = pLocalReducer->pCtx[0].aOutputBuf;
|
||||
}
|
||||
}
|
||||
|
||||
memset(pLocalReducer->pResultBuf, 0, pLocalReducer->nResultBufSize + sizeof(tFilePage));
|
||||
|
@ -1437,24 +1434,13 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
|
|||
|
||||
SLocalReducer *pLocalReducer = pRes->pLocalReducer;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
// set the data merge in progress
|
||||
int32_t prevStatus =
|
||||
atomic_val_compare_exchange_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY, TSC_LOCALREDUCE_IN_PROGRESS);
|
||||
if (prevStatus != TSC_LOCALREDUCE_READY) {
|
||||
assert(prevStatus == TSC_LOCALREDUCE_TOBE_FREED); // it is in tscDestroyLocalReducer function already
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tFilePage *tmpBuffer = pLocalReducer->pTempBuffer;
|
||||
tFilePage *tmpBuffer = pLocalReducer->pTempBuffer;
|
||||
|
||||
if (doHandleLastRemainData(pSql)) {
|
||||
pLocalReducer->status = TSC_LOCALREDUCE_READY; // set the flag, taos_free_result can release this result.
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (doBuildFilledResultForGroup(pSql)) {
|
||||
pLocalReducer->status = TSC_LOCALREDUCE_READY; // set the flag, taos_free_result can release this result.
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1510,7 +1496,6 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
|
|||
pLocalReducer->discardData->num = 0;
|
||||
|
||||
if (saveGroupResultInfo(pSql)) {
|
||||
pLocalReducer->status = TSC_LOCALREDUCE_READY;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1556,7 +1541,6 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
|
|||
|
||||
// here we do not check the return value
|
||||
adjustLoserTreeFromNewData(pLocalReducer, pOneDataSrc, pTree);
|
||||
assert(pLocalReducer->status == TSC_LOCALREDUCE_IN_PROGRESS);
|
||||
|
||||
if (pRes->numOfRows == 0) {
|
||||
handleUnprocessedRow(pCmd, pLocalReducer, tmpBuffer);
|
||||
|
@ -1567,7 +1551,6 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
|
|||
* If previous group is not skipped, keep it in pRes->numOfGroups
|
||||
*/
|
||||
if (notSkipped && saveGroupResultInfo(pSql)) {
|
||||
pLocalReducer->status = TSC_LOCALREDUCE_READY;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1587,7 +1570,6 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
|
|||
if (pRes->numOfRows == 0) {
|
||||
continue;
|
||||
} else {
|
||||
pLocalReducer->status = TSC_LOCALREDUCE_READY; // set the flag, taos_free_result can release this result.
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
} else { // result buffer is not full
|
||||
|
@ -1612,9 +1594,6 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
|
|||
genFinalResults(pSql, pLocalReducer, true);
|
||||
}
|
||||
|
||||
assert(pLocalReducer->status == TSC_LOCALREDUCE_IN_PROGRESS && pRes->row == 0);
|
||||
pLocalReducer->status = TSC_LOCALREDUCE_READY; // set the flag, taos_free_result can release this result.
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -731,7 +731,7 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, SParsedDataColI
|
|||
return code;
|
||||
}
|
||||
|
||||
dataBuf->vgId = pTableMeta->vgroupInfo.vgId;
|
||||
dataBuf->vgId = pTableMeta->vgId;
|
||||
dataBuf->numOfTables = 1;
|
||||
|
||||
*totalNum += numOfRows;
|
||||
|
@ -1413,13 +1413,25 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int code) {
|
|||
if (taos_errno(pSql) != TSDB_CODE_SUCCESS) { // handle error
|
||||
assert(taos_errno(pSql) == code);
|
||||
|
||||
taos_free_result(pSql);
|
||||
tfree(pSupporter);
|
||||
fclose(fp);
|
||||
do {
|
||||
if (code == TSDB_CODE_TDB_TABLE_RECONFIGURE) {
|
||||
assert(pSql->res.numOfRows == 0);
|
||||
int32_t errc = fseek(fp, 0, SEEK_SET);
|
||||
if (errc < 0) {
|
||||
tscError("%p failed to seek SEEK_SET since:%s", pSql, tstrerror(errno));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pParentSql->res.code = code;
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
return;
|
||||
taos_free_result(pSql);
|
||||
tfree(pSupporter);
|
||||
fclose(fp);
|
||||
|
||||
pParentSql->res.code = code;
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
return;
|
||||
} while (0);
|
||||
}
|
||||
|
||||
// accumulate the total submit records
|
||||
|
|
|
@ -666,6 +666,7 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQ
|
|||
const char* msg1 = "invalid query expression";
|
||||
const char* msg2 = "interval cannot be less than 10 ms";
|
||||
const char* msg3 = "sliding cannot be used without interval";
|
||||
const char* msg4 = "top/bottom query does not support order by value in interval query";
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
|
@ -712,6 +713,11 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQ
|
|||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
int32_t colId = pQueryInfo->order.orderColId;
|
||||
if (pQueryInfo->interval.interval > 0 && colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4646,7 +4652,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
|
|||
|
||||
if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
} else {
|
||||
} else { // order by top/bottom result value column is not supported in case of interval query.
|
||||
assert(!(orderByTags && orderByTS));
|
||||
}
|
||||
|
||||
|
@ -4936,7 +4942,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
}
|
||||
|
||||
SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
|
||||
pUpdateMsg->head.vgId = htonl(pTableMeta->vgroupInfo.vgId);
|
||||
pUpdateMsg->head.vgId = htonl(pTableMeta->vgId);
|
||||
pUpdateMsg->tid = htonl(pTableMeta->id.tid);
|
||||
pUpdateMsg->uid = htobe64(pTableMeta->id.uid);
|
||||
pUpdateMsg->colId = htons(pTagsSchema->colId);
|
||||
|
@ -5442,6 +5448,7 @@ static void setCreateDBOption(SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
|
|||
pMsg->quorum = pCreateDb->quorum;
|
||||
pMsg->ignoreExist = pCreateDb->ignoreExists;
|
||||
pMsg->update = pCreateDb->update;
|
||||
pMsg->cacheLastRow = pCreateDb->cachelast;
|
||||
}
|
||||
|
||||
int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) {
|
||||
|
|
|
@ -130,13 +130,14 @@ SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void tscInitCorVgroupInfo(SCorVgroupInfo *corVgroupInfo, SVgroupInfo *vgroupInfo) {
|
||||
static void tscInitCorVgroupInfo(SCorVgroupInfo *corVgroupInfo, SVgroupMsg *pVgroupMsg) {
|
||||
corVgroupInfo->version = 0;
|
||||
corVgroupInfo->inUse = 0;
|
||||
corVgroupInfo->numOfEps = vgroupInfo->numOfEps;
|
||||
for (int32_t i = 0; i < corVgroupInfo->numOfEps; i++) {
|
||||
corVgroupInfo->epAddr[i].fqdn = strdup(vgroupInfo->epAddr[i].fqdn);
|
||||
corVgroupInfo->epAddr[i].port = vgroupInfo->epAddr[i].port;
|
||||
corVgroupInfo->inUse = 0;
|
||||
corVgroupInfo->numOfEps = pVgroupMsg->numOfEps;
|
||||
|
||||
for (int32_t i = 0; i < pVgroupMsg->numOfEps; i++) {
|
||||
corVgroupInfo->epAddr[i].fqdn = strndup(pVgroupMsg->epAddr[i].fqdn, tListLen(pVgroupMsg->epAddr[0].fqdn));
|
||||
corVgroupInfo->epAddr[i].port = pVgroupMsg->epAddr[i].port;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,8 +146,10 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
|
|||
|
||||
int32_t schemaSize = (pTableMetaMsg->numOfColumns + pTableMetaMsg->numOfTags) * sizeof(SSchema);
|
||||
STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + schemaSize);
|
||||
|
||||
pTableMeta->tableType = pTableMetaMsg->tableType;
|
||||
|
||||
pTableMeta->vgId = pTableMetaMsg->vgroup.vgId;
|
||||
|
||||
pTableMeta->tableInfo = (STableComInfo) {
|
||||
.numOfTags = pTableMetaMsg->numOfTags,
|
||||
.precision = pTableMetaMsg->precision,
|
||||
|
@ -156,18 +159,7 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
|
|||
pTableMeta->id.tid = pTableMetaMsg->tid;
|
||||
pTableMeta->id.uid = pTableMetaMsg->uid;
|
||||
|
||||
SVgroupInfo* pVgroupInfo = &pTableMeta->vgroupInfo;
|
||||
pVgroupInfo->numOfEps = pTableMetaMsg->vgroup.numOfEps;
|
||||
pVgroupInfo->vgId = pTableMetaMsg->vgroup.vgId;
|
||||
|
||||
for(int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
|
||||
SEpAddrMsg* pEpMsg = &pTableMetaMsg->vgroup.epAddr[i];
|
||||
|
||||
pVgroupInfo->epAddr[i].fqdn = strndup(pEpMsg->fqdn, tListLen(pEpMsg->fqdn));
|
||||
pVgroupInfo->epAddr[i].port = pEpMsg->port;
|
||||
}
|
||||
|
||||
tscInitCorVgroupInfo(&pTableMeta->corVgroupInfo, pVgroupInfo);
|
||||
tscInitCorVgroupInfo(&pTableMeta->corVgroupInfo, &pTableMetaMsg->vgroup);
|
||||
|
||||
pTableMeta->sversion = pTableMetaMsg->sversion;
|
||||
pTableMeta->tversion = pTableMetaMsg->tversion;
|
||||
|
|
|
@ -45,32 +45,30 @@ static int32_t getWaitingTimeInterval(int32_t count) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return initial * (2<<(count - 2));
|
||||
return initial * ((2u)<<(count - 2));
|
||||
}
|
||||
|
||||
static void tscSetDnodeEpSet(SSqlObj* pSql, SVgroupInfo* pVgroupInfo) {
|
||||
assert(pSql != NULL && pVgroupInfo != NULL && pVgroupInfo->numOfEps > 0);
|
||||
|
||||
SRpcEpSet* pEpSet = &pSql->epSet;
|
||||
static void tscSetDnodeEpSet(SRpcEpSet* pEpSet, SVgroupInfo* pVgroupInfo) {
|
||||
assert(pEpSet != NULL && pVgroupInfo != NULL && pVgroupInfo->numOfEps > 0);
|
||||
|
||||
// Issue the query to one of the vnode among a vgroup randomly.
|
||||
// change the inUse property would not affect the isUse attribute of STableMeta
|
||||
pEpSet->inUse = rand() % pVgroupInfo->numOfEps;
|
||||
|
||||
// apply the FQDN string length check here
|
||||
bool hasFqdn = false;
|
||||
bool existed = false;
|
||||
|
||||
pEpSet->numOfEps = pVgroupInfo->numOfEps;
|
||||
for(int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
|
||||
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn, tListLen(pEpSet->fqdn[i]));
|
||||
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
||||
|
||||
if (!hasFqdn) {
|
||||
hasFqdn = (strlen(pEpSet->fqdn[i]) > 0);
|
||||
int32_t len = (int32_t) strnlen(pVgroupInfo->epAddr[i].fqdn, TSDB_FQDN_LEN);
|
||||
if (len > 0) {
|
||||
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn, tListLen(pEpSet->fqdn[i]));
|
||||
existed = true;
|
||||
}
|
||||
}
|
||||
|
||||
assert(hasFqdn);
|
||||
assert(existed);
|
||||
}
|
||||
|
||||
static void tscDumpMgmtEpSet(SSqlObj *pSql) {
|
||||
|
@ -102,7 +100,8 @@ void tscUpdateMgmtEpSet(SSqlObj *pSql, SRpcEpSet *pEpSet) {
|
|||
pCorEpSet->epSet = *pEpSet;
|
||||
taosCorEndWrite(&pCorEpSet->version);
|
||||
}
|
||||
static void tscDumpEpSetFromVgroupInfo(SCorVgroupInfo *pVgroupInfo, SRpcEpSet *pEpSet) {
|
||||
|
||||
static void tscDumpEpSetFromVgroupInfo(SRpcEpSet *pEpSet, SCorVgroupInfo *pVgroupInfo) {
|
||||
if (pVgroupInfo == NULL) { return;}
|
||||
taosCorBeginRead(&pVgroupInfo->version);
|
||||
int8_t inUse = pVgroupInfo->inUse;
|
||||
|
@ -515,8 +514,8 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
}
|
||||
} else {
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
pRetrieveMsg->header.vgId = htonl(pTableMeta->vgroupInfo.vgId);
|
||||
tscDebug("%p build fetch msg from only one vgroup, vgId:%d", pSql, pTableMeta->vgroupInfo.vgId);
|
||||
pRetrieveMsg->header.vgId = htonl(pTableMeta->vgId);
|
||||
tscDebug("%p build fetch msg from only one vgroup, vgId:%d", pSql, pTableMeta->vgId);
|
||||
}
|
||||
|
||||
pSql->cmd.payloadLen = sizeof(SRetrieveTableMsg);
|
||||
|
@ -535,7 +534,6 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
// NOTE: shell message size should not include SMsgDesc
|
||||
int32_t size = pSql->cmd.payloadLen - sizeof(SMsgDesc);
|
||||
int32_t vgId = pTableMeta->vgroupInfo.vgId;
|
||||
|
||||
SMsgDesc* pMsgDesc = (SMsgDesc*) pMsg;
|
||||
pMsgDesc->numOfVnodes = htonl(1); // always one vnode
|
||||
|
@ -543,7 +541,7 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pMsg += sizeof(SMsgDesc);
|
||||
SSubmitMsg *pShellMsg = (SSubmitMsg *)pMsg;
|
||||
|
||||
pShellMsg->header.vgId = htonl(vgId);
|
||||
pShellMsg->header.vgId = htonl(pTableMeta->vgId);
|
||||
pShellMsg->header.contLen = htonl(size); // the length not includes the size of SMsgDesc
|
||||
pShellMsg->length = pShellMsg->header.contLen;
|
||||
|
||||
|
@ -551,9 +549,9 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
// pSql->cmd.payloadLen is set during copying data into payload
|
||||
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
||||
tscDumpEpSetFromVgroupInfo(&pTableMeta->corVgroupInfo, &pSql->epSet);
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMeta->corVgroupInfo);
|
||||
|
||||
tscDebug("%p build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql, vgId, pSql->cmd.numOfTablesInSubmit,
|
||||
tscDebug("%p build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql, pTableMeta->vgId, pSql->cmd.numOfTablesInSubmit,
|
||||
pSql->epSet.numOfEps);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -597,24 +595,28 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
|||
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo) || pTableMetaInfo->pVgroupTables == NULL) {
|
||||
|
||||
SVgroupInfo* pVgroupInfo = NULL;
|
||||
int32_t vgId = -1;
|
||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
int32_t index = pTableMetaInfo->vgroupIndex;
|
||||
assert(index >= 0);
|
||||
|
||||
|
||||
SVgroupInfo* pVgroupInfo = NULL;
|
||||
if (pTableMetaInfo->vgroupList->numOfVgroups > 0) {
|
||||
assert(index < pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[index];
|
||||
}
|
||||
|
||||
vgId = pVgroupInfo->vgId;
|
||||
tscSetDnodeEpSet(&pSql->epSet, pVgroupInfo);
|
||||
tscDebug("%p query on stable, vgIndex:%d, numOfVgroups:%d", pSql, index, pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
} else {
|
||||
pVgroupInfo = &pTableMeta->vgroupInfo;
|
||||
vgId = pTableMeta->vgId;
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMeta->corVgroupInfo);
|
||||
}
|
||||
|
||||
assert(pVgroupInfo != NULL);
|
||||
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
|
||||
|
||||
tscSetDnodeEpSet(pSql, pVgroupInfo);
|
||||
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
|
||||
pQueryMsg->head.vgId = htonl(vgId);
|
||||
|
||||
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
|
||||
pTableIdInfo->tid = htonl(pTableMeta->id.tid);
|
||||
|
@ -633,7 +635,7 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
|||
SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, index);
|
||||
|
||||
// set the vgroup info
|
||||
tscSetDnodeEpSet(pSql, &pTableIdList->vgInfo);
|
||||
tscSetDnodeEpSet(&pSql->epSet, &pTableIdList->vgInfo);
|
||||
pQueryMsg->head.vgId = htonl(pTableIdList->vgInfo.vgId);
|
||||
|
||||
int32_t numOfTables = (int32_t)taosArrayGetSize(pTableIdList->itemList);
|
||||
|
@ -888,13 +890,13 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
|
||||
SColIndex* pCol = taosArrayGet(pGroupbyExpr->columnInfo, j);
|
||||
|
||||
*((int16_t *)pMsg) = pCol->colId;
|
||||
*((int16_t *)pMsg) = htons(pCol->colId);
|
||||
pMsg += sizeof(pCol->colId);
|
||||
|
||||
*((int16_t *)pMsg) += pCol->colIndex;
|
||||
*((int16_t *)pMsg) += htons(pCol->colIndex);
|
||||
pMsg += sizeof(pCol->colIndex);
|
||||
|
||||
*((int16_t *)pMsg) += pCol->flag;
|
||||
*((int16_t *)pMsg) += htons(pCol->flag);
|
||||
pMsg += sizeof(pCol->flag);
|
||||
|
||||
memcpy(pMsg, pCol->name, tListLen(pCol->name));
|
||||
|
@ -1247,7 +1249,7 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pShowMsg->payloadLen = htons(pEpAddr->n);
|
||||
}
|
||||
|
||||
pCmd->payloadLen = sizeof(SShowMsg) + pShowMsg->payloadLen;
|
||||
pCmd->payloadLen = sizeof(SShowMsg) + htons(pShowMsg->payloadLen);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1448,48 +1450,11 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
|
|||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
tscDumpEpSetFromVgroupInfo(&pTableMetaInfo->pTableMeta->corVgroupInfo, &pSql->epSet);
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMetaInfo->pTableMeta->corVgroupInfo);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
//int tscBuildCancelQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||
// SCancelQueryMsg *pCancelMsg = (SCancelQueryMsg*) pSql->cmd.payload;
|
||||
// pCancelMsg->qhandle = htobe64(pSql->res.qhandle);
|
||||
//
|
||||
// SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
// STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
//
|
||||
// if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
// int32_t vgIndex = pTableMetaInfo->vgroupIndex;
|
||||
// if (pTableMetaInfo->pVgroupTables == NULL) {
|
||||
// SVgroupsInfo *pVgroupInfo = pTableMetaInfo->vgroupList;
|
||||
// assert(pVgroupInfo->vgroups[vgIndex].vgId > 0 && vgIndex < pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
//
|
||||
// pCancelMsg->header.vgId = htonl(pVgroupInfo->vgroups[vgIndex].vgId);
|
||||
// tscDebug("%p build cancel query msg from vgId:%d, vgIndex:%d", pSql, pVgroupInfo->vgroups[vgIndex].vgId, vgIndex);
|
||||
// } else {
|
||||
// int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
|
||||
// assert(vgIndex >= 0 && vgIndex < numOfVgroups);
|
||||
//
|
||||
// SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, vgIndex);
|
||||
//
|
||||
// pCancelMsg->header.vgId = htonl(pTableIdList->vgInfo.vgId);
|
||||
// tscDebug("%p build cancel query msg from vgId:%d, vgIndex:%d", pSql, pTableIdList->vgInfo.vgId, vgIndex);
|
||||
// }
|
||||
// } else {
|
||||
// STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
// pCancelMsg->header.vgId = htonl(pTableMeta->vgroupInfo.vgId);
|
||||
// tscDebug("%p build cancel query msg from only one vgroup, vgId:%d", pSql, pTableMeta->vgroupInfo.vgId);
|
||||
// }
|
||||
//
|
||||
// pSql->cmd.payloadLen = sizeof(SCancelQueryMsg);
|
||||
// pSql->cmd.msgType = TSDB_MSG_TYPE_CANCEL_QUERY;
|
||||
//
|
||||
// pCancelMsg->header.contLen = htonl(sizeof(SCancelQueryMsg));
|
||||
// return TSDB_CODE_SUCCESS;
|
||||
//}
|
||||
|
||||
int tscAlterDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
pCmd->payloadLen = sizeof(SAlterDbMsg);
|
||||
|
|
|
@ -314,7 +314,7 @@ static void waitForRetrieveRsp(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
tsem_post(&pSql->rspSem);
|
||||
}
|
||||
|
||||
TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, TAOS_RES** res) {
|
||||
TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, int64_t* res) {
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
if (pObj == NULL || pObj->signature != pObj) {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
|
@ -340,7 +340,7 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, TAOS_RES
|
|||
doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen);
|
||||
|
||||
if (res != NULL) {
|
||||
*res = pSql;
|
||||
atomic_store_64(res, pSql->self);
|
||||
}
|
||||
|
||||
tsem_wait(&pSql->rspSem);
|
||||
|
@ -351,7 +351,7 @@ TAOS_RES* taos_query(TAOS *taos, const char *sqlstr) {
|
|||
return taos_query_c(taos, sqlstr, (uint32_t)strlen(sqlstr), NULL);
|
||||
}
|
||||
|
||||
TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, TAOS_RES** res) {
|
||||
TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, int64_t* res) {
|
||||
return taos_query_c(taos, sqlstr, (uint32_t) strlen(sqlstr), res);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,14 +69,17 @@ TSKEY tscGetSubscriptionProgress(void* sub, int64_t uid, TSKEY dflt) {
|
|||
}
|
||||
|
||||
void tscUpdateSubscriptionProgress(void* sub, int64_t uid, TSKEY ts) {
|
||||
if( sub == NULL)
|
||||
if( sub == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSub* pSub = (SSub*)sub;
|
||||
|
||||
SSubscriptionProgress target = {.uid = uid, .key = ts};
|
||||
SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress);
|
||||
if (p != NULL) {
|
||||
p->key = ts;
|
||||
tscDebug("subscribe:%s, uid:%"PRIu64" update sub start ts:%"PRId64, pSub->topic, p->uid, p->key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,6 +505,7 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
|||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single tabel subscription
|
||||
pQueryInfo->window.skey = ((SSubscriptionProgress*)taosArrayGet(pSub->progress, 0))->key;
|
||||
tscDebug("subscribe:%s set subscribe skey:%"PRId64, pSub->topic, pQueryInfo->window.skey);
|
||||
}
|
||||
|
||||
if (pSub->pTimer == NULL) {
|
||||
|
|
|
@ -31,17 +31,16 @@
|
|||
#include "tlocale.h"
|
||||
|
||||
// global, not configurable
|
||||
SCacheObj* tscMetaCache;
|
||||
SCacheObj *tscMetaCache; // table meta cache
|
||||
SHashObj *tscHashMap; // hash map to keep the global vgroup info
|
||||
int tscObjRef = -1;
|
||||
void * tscTmr;
|
||||
void * tscQhandle;
|
||||
void * tscCheckDiskUsageTmr;
|
||||
void *tscTmr;
|
||||
void *tscQhandle;
|
||||
void *tscCheckDiskUsageTmr;
|
||||
int tscRefId = -1;
|
||||
|
||||
int tscNumOfThreads;
|
||||
int tscNumOfObj = 0; // number of sqlObj in current process.
|
||||
|
||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||
//void tscUpdateEpSet(void *ahandle, SRpcEpSet *pEpSet);
|
||||
|
||||
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void* UNUSED_PARAM(param)) {
|
||||
taosGetDisk();
|
||||
|
@ -114,7 +113,7 @@ void taos_init_imp(void) {
|
|||
int queueSize = tsMaxConnections*2;
|
||||
|
||||
double factor = (tscEmbedded == 0)? 2.0:4.0;
|
||||
tscNumOfThreads = (int)(tsNumOfCores * tsNumOfThreadsPerCore / factor);
|
||||
int32_t tscNumOfThreads = (int)(tsNumOfCores * tsNumOfThreadsPerCore / factor);
|
||||
if (tscNumOfThreads < 2) {
|
||||
tscNumOfThreads = 2;
|
||||
}
|
||||
|
@ -133,7 +132,8 @@ void taos_init_imp(void) {
|
|||
int64_t refreshTime = 10; // 10 seconds by default
|
||||
if (tscMetaCache == NULL) {
|
||||
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, tscFreeTableMetaHelper, "tableMeta");
|
||||
tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj);
|
||||
tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj);
|
||||
tscHashMap = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
}
|
||||
|
||||
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
||||
|
|
|
@ -458,21 +458,19 @@ void tscFreeRegisteredSqlObj(void *pSql) {
|
|||
SSqlObj* p = *(SSqlObj**)pSql;
|
||||
STscObj* pTscObj = p->pTscObj;
|
||||
|
||||
assert(p->self != 0);
|
||||
assert(RID_VALID(p->self));
|
||||
|
||||
tscFreeSqlObj(p);
|
||||
taosReleaseRef(tscRefId, pTscObj->rid);
|
||||
|
||||
int32_t num = atomic_sub_fetch_32(&pTscObj->numOfObj, 1);
|
||||
int32_t total = atomic_sub_fetch_32(&tscNumOfObj, 1);
|
||||
tscDebug("%p free SqlObj, total in tscObj:%d, total:%d", pSql, num, total);
|
||||
}
|
||||
|
||||
void tscFreeTableMetaHelper(void *pTableMeta) {
|
||||
STableMeta* p = (STableMeta*) pTableMeta;
|
||||
|
||||
int32_t numOfEps = p->vgroupInfo.numOfEps;
|
||||
assert(numOfEps >= 0 && numOfEps <= TSDB_MAX_REPLICA);
|
||||
|
||||
for(int32_t i = 0; i < numOfEps; ++i) {
|
||||
tfree(p->vgroupInfo.epAddr[i].fqdn);
|
||||
}
|
||||
|
||||
int32_t numOfEps1 = p->corVgroupInfo.numOfEps;
|
||||
assert(numOfEps1 >= 0 && numOfEps1 <= TSDB_MAX_REPLICA);
|
||||
|
||||
|
@ -1912,6 +1910,10 @@ void tscResetForNextRetrieve(SSqlRes* pRes) {
|
|||
void registerSqlObj(SSqlObj* pSql) {
|
||||
taosAcquireRef(tscRefId, pSql->pTscObj->rid);
|
||||
pSql->self = taosAddRef(tscObjRef, pSql);
|
||||
|
||||
int32_t num = atomic_add_fetch_32(&pSql->pTscObj->numOfObj, 1);
|
||||
int32_t total = atomic_add_fetch_32(&tscNumOfObj, 1);
|
||||
tscDebug("%p new SqlObj from %p, total in tscObj:%d, total:%d", pSql, pSql->pTscObj, num, total);
|
||||
}
|
||||
|
||||
SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cmd) {
|
||||
|
@ -1941,30 +1943,24 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cm
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pNew->fp = fp;
|
||||
pNew->fp = fp;
|
||||
pNew->fetchFp = fp;
|
||||
pNew->param = param;
|
||||
pNew->param = param;
|
||||
pNew->sqlstr = NULL;
|
||||
pNew->maxRetry = TSDB_MAX_REPLICA;
|
||||
|
||||
pNew->sqlstr = strdup(pSql->sqlstr);
|
||||
if (pNew->sqlstr == NULL) {
|
||||
tscError("%p new subquery failed", pSql);
|
||||
tscFreeSqlObj(pNew);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, 0);
|
||||
|
||||
assert(pSql->cmd.clauseIndex == 0);
|
||||
STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0);
|
||||
|
||||
tscAddTableMetaInfo(pQueryInfo, pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL);
|
||||
|
||||
registerSqlObj(pNew);
|
||||
|
||||
return pNew;
|
||||
}
|
||||
|
||||
static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pQueryInfo, SQueryInfo* pNewQueryInfo, int64_t uid) {
|
||||
static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pNewQueryInfo, int64_t uid) {
|
||||
int32_t numOfOutput = (int32_t)tscSqlExprNumOfExprs(pNewQueryInfo);
|
||||
if (numOfOutput == 0) {
|
||||
return;
|
||||
|
@ -2017,15 +2013,9 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, tableIndex);
|
||||
|
||||
pNew->pTscObj = pSql->pTscObj;
|
||||
pNew->pTscObj = pSql->pTscObj;
|
||||
pNew->signature = pNew;
|
||||
|
||||
pNew->sqlstr = strdup(pSql->sqlstr);
|
||||
if (pNew->sqlstr == NULL) {
|
||||
tscError("%p new subquery failed, tableIndex:%d, vgroupIndex:%d", pSql, tableIndex, pTableMetaInfo->vgroupIndex);
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
pNew->sqlstr = NULL;
|
||||
|
||||
SSqlCmd* pnCmd = &pNew->cmd;
|
||||
memcpy(pnCmd, pCmd, sizeof(SSqlCmd));
|
||||
|
@ -2113,23 +2103,22 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
goto _error;
|
||||
}
|
||||
|
||||
doSetSqlExprAndResultFieldInfo(pQueryInfo, pNewQueryInfo, uid);
|
||||
doSetSqlExprAndResultFieldInfo(pNewQueryInfo, uid);
|
||||
|
||||
pNew->fp = fp;
|
||||
pNew->fp = fp;
|
||||
pNew->fetchFp = fp;
|
||||
|
||||
pNew->param = param;
|
||||
pNew->param = param;
|
||||
pNew->maxRetry = TSDB_MAX_REPLICA;
|
||||
|
||||
char* name = pTableMetaInfo->name;
|
||||
STableMetaInfo* pFinalInfo = NULL;
|
||||
|
||||
if (pPrevSql == NULL) {
|
||||
STableMeta* pTableMeta = taosCacheAcquireByData(tscMetaCache, pTableMetaInfo->pTableMeta); // get by name may failed due to the cache cleanup
|
||||
if (pPrevSql == NULL) { // get by name may failed due to the cache cleanup
|
||||
STableMeta* pTableMeta = taosCacheAcquireByData(tscMetaCache, pTableMetaInfo->pTableMeta);
|
||||
assert(pTableMeta != NULL);
|
||||
|
||||
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pTableMeta, pTableMetaInfo->vgroupList,
|
||||
pTableMetaInfo->tagColList, pTableMetaInfo->pVgroupTables);
|
||||
pTableMetaInfo->tagColList, pTableMetaInfo->pVgroupTables);
|
||||
} else { // transfer the ownership of pTableMeta to the newly create sql object.
|
||||
STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex, 0);
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ extern uint16_t tsSyncPort;
|
|||
extern uint16_t tsArbitratorPort;
|
||||
extern int32_t tsStatusInterval;
|
||||
extern int32_t tsNumOfMnodes;
|
||||
extern int32_t tsEnableVnodeBak;
|
||||
extern int32_t tsEnableTelemetryReporting;
|
||||
extern int8_t tsEnableVnodeBak;
|
||||
extern int8_t tsEnableTelemetryReporting;
|
||||
extern char tsEmail[];
|
||||
extern char tsArbitrator[];
|
||||
|
||||
|
@ -51,7 +51,7 @@ extern int8_t tsDaylight;
|
|||
extern char tsTimezone[];
|
||||
extern char tsLocale[];
|
||||
extern char tsCharset[]; // default encode string
|
||||
extern int32_t tsEnableCoreFile;
|
||||
extern int8_t tsEnableCoreFile;
|
||||
extern int32_t tsCompressMsgSize;
|
||||
extern char tsTempDir[];
|
||||
|
||||
|
@ -59,12 +59,12 @@ extern char tsTempDir[];
|
|||
extern int32_t tsQueryBufferSize; // maximum allowed usage buffer for each data node during query processing
|
||||
extern int32_t tsRetrieveBlockingModel;// retrieve threads will be blocked
|
||||
|
||||
extern int32_t tsKeepOriginalColumnName;
|
||||
extern int8_t tsKeepOriginalColumnName;
|
||||
|
||||
// client
|
||||
extern int32_t tsTableMetaKeepTimer;
|
||||
extern int32_t tsMaxSQLStringLen;
|
||||
extern int32_t tsTscEnableRecordSql;
|
||||
extern int8_t tsTscEnableRecordSql;
|
||||
extern int32_t tsMaxNumOfOrderedResults;
|
||||
extern int32_t tsMinSlidingTime;
|
||||
extern int32_t tsMinIntervalTime;
|
||||
|
@ -93,48 +93,51 @@ extern int16_t tsWAL;
|
|||
extern int32_t tsFsyncPeriod;
|
||||
extern int32_t tsReplications;
|
||||
extern int32_t tsQuorum;
|
||||
extern int32_t tsUpdate;
|
||||
extern int8_t tsUpdate;
|
||||
extern int8_t tsCacheLastRow;
|
||||
|
||||
// balance
|
||||
extern int32_t tsEnableBalance;
|
||||
extern int32_t tsAlternativeRole;
|
||||
extern int8_t tsEnableBalance;
|
||||
extern int8_t tsAlternativeRole;
|
||||
extern int32_t tsBalanceInterval;
|
||||
extern int32_t tsOfflineThreshold;
|
||||
extern int32_t tsMnodeEqualVnodeNum;
|
||||
extern int32_t tsFlowCtrl;
|
||||
extern int8_t tsEnableFlowCtrl;
|
||||
extern int8_t tsEnableSlaveQuery;
|
||||
extern int8_t tsEnableAdjustMaster;
|
||||
|
||||
// restful
|
||||
extern int32_t tsEnableHttpModule;
|
||||
extern int8_t tsEnableHttpModule;
|
||||
extern int32_t tsRestRowLimit;
|
||||
extern uint16_t tsHttpPort;
|
||||
extern int32_t tsHttpCacheSessions;
|
||||
extern int32_t tsHttpSessionExpire;
|
||||
extern int32_t tsHttpMaxThreads;
|
||||
extern int32_t tsHttpEnableCompress;
|
||||
extern int32_t tsHttpEnableRecordSql;
|
||||
extern int32_t tsTelegrafUseFieldNum;
|
||||
extern int8_t tsHttpEnableCompress;
|
||||
extern int8_t tsHttpEnableRecordSql;
|
||||
extern int8_t tsTelegrafUseFieldNum;
|
||||
|
||||
// mqtt
|
||||
extern int32_t tsEnableMqttModule;
|
||||
extern char tsMqttHostName[];
|
||||
extern char tsMqttPort[];
|
||||
extern char tsMqttUser[];
|
||||
extern char tsMqttPass[];
|
||||
extern char tsMqttClientId[];
|
||||
extern char tsMqttTopic[];
|
||||
extern int8_t tsEnableMqttModule;
|
||||
extern char tsMqttHostName[];
|
||||
extern char tsMqttPort[];
|
||||
extern char tsMqttUser[];
|
||||
extern char tsMqttPass[];
|
||||
extern char tsMqttClientId[];
|
||||
extern char tsMqttTopic[];
|
||||
|
||||
// monitor
|
||||
extern int32_t tsEnableMonitorModule;
|
||||
extern int8_t tsEnableMonitorModule;
|
||||
extern char tsMonitorDbName[];
|
||||
extern char tsInternalPass[];
|
||||
extern int32_t tsMonitorInterval;
|
||||
|
||||
// stream
|
||||
extern int32_t tsEnableStream;
|
||||
extern int8_t tsEnableStream;
|
||||
|
||||
// internal
|
||||
extern int32_t tsPrintAuth;
|
||||
extern uint32_t tscEmbedded;
|
||||
extern int8_t tsPrintAuth;
|
||||
extern int8_t tscEmbedded;
|
||||
extern char configDir[];
|
||||
extern char tsVnodeDir[];
|
||||
extern char tsDnodeDir[];
|
||||
|
@ -161,7 +164,7 @@ extern float tsMinimalLogDirGB;
|
|||
extern float tsReservedTmpDirectorySpace;
|
||||
extern float tsMinimalDataDirGB;
|
||||
extern int32_t tsTotalMemoryMB;
|
||||
extern int32_t tsVersion;
|
||||
extern uint32_t tsVersion;
|
||||
|
||||
// build info
|
||||
extern char version[];
|
||||
|
@ -171,13 +174,13 @@ extern char gitinfoOfInternal[];
|
|||
extern char buildinfo[];
|
||||
|
||||
// log
|
||||
extern int32_t tsAsyncLog;
|
||||
extern int8_t tsAsyncLog;
|
||||
extern int32_t tsNumOfLogLines;
|
||||
extern int32_t tsLogKeepDays;
|
||||
extern int32_t dDebugFlag;
|
||||
extern int32_t vDebugFlag;
|
||||
extern int32_t mDebugFlag;
|
||||
extern uint32_t cDebugFlag;
|
||||
extern int32_t cDebugFlag;
|
||||
extern int32_t jniDebugFlag;
|
||||
extern int32_t tmrDebugFlag;
|
||||
extern int32_t sdbDebugFlag;
|
||||
|
@ -187,7 +190,7 @@ extern int32_t monDebugFlag;
|
|||
extern int32_t uDebugFlag;
|
||||
extern int32_t rpcDebugFlag;
|
||||
extern int32_t odbcDebugFlag;
|
||||
extern uint32_t qDebugFlag;
|
||||
extern int32_t qDebugFlag;
|
||||
extern int32_t wDebugFlag;
|
||||
extern int32_t cqDebugFlag;
|
||||
extern int32_t debugFlag;
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
#include "tlog.h"
|
||||
|
||||
extern int32_t uDebugFlag;
|
||||
extern uint32_t tscEmbedded;
|
||||
extern int8_t tscEmbedded;
|
||||
|
||||
#define uFatal(...) { if (uDebugFlag & DEBUG_FATAL) { taosPrintLog("UTL FATAL", tscEmbedded ? 255 : uDebugFlag, __VA_ARGS__); }}
|
||||
#define uError(...) { if (uDebugFlag & DEBUG_ERROR) { taosPrintLog("UTL ERROR ", tscEmbedded ? 255 : uDebugFlag, __VA_ARGS__); }}
|
||||
|
|
|
@ -39,8 +39,8 @@ uint16_t tsSyncPort = 6040;
|
|||
uint16_t tsArbitratorPort = 6042;
|
||||
int32_t tsStatusInterval = 1; // second
|
||||
int32_t tsNumOfMnodes = 3;
|
||||
int32_t tsEnableVnodeBak = 1;
|
||||
int32_t tsEnableTelemetryReporting = 1;
|
||||
int8_t tsEnableVnodeBak = 1;
|
||||
int8_t tsEnableTelemetryReporting = 1;
|
||||
char tsEmail[TSDB_FQDN_LEN] = {0};
|
||||
|
||||
// common
|
||||
|
@ -56,7 +56,7 @@ int8_t tsDaylight = 0;
|
|||
char tsTimezone[TSDB_TIMEZONE_LEN] = {0};
|
||||
char tsLocale[TSDB_LOCALE_LEN] = {0};
|
||||
char tsCharset[TSDB_LOCALE_LEN] = {0}; // default encode string
|
||||
int32_t tsEnableCoreFile = 0;
|
||||
int8_t tsEnableCoreFile = 0;
|
||||
int32_t tsMaxBinaryDisplayWidth = 30;
|
||||
char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/";
|
||||
|
||||
|
@ -73,7 +73,7 @@ int32_t tsCompressMsgSize = -1;
|
|||
// client
|
||||
int32_t tsTableMetaKeepTimer = 7200; // second
|
||||
int32_t tsMaxSQLStringLen = TSDB_MAX_SQL_LEN;
|
||||
int32_t tsTscEnableRecordSql = 0;
|
||||
int8_t tsTscEnableRecordSql = 0;
|
||||
|
||||
// the maximum number of results for projection query on super table that are returned from
|
||||
// one virtual node, to order according to timestamp
|
||||
|
@ -110,7 +110,7 @@ int32_t tsQueryBufferSize = -1;
|
|||
int32_t tsRetrieveBlockingModel = 0;
|
||||
|
||||
// last_row(*), first(*), last_row(ts, col1, col2) query, the result fields will be the original column name
|
||||
int32_t tsKeepOriginalColumnName = 0;
|
||||
int8_t tsKeepOriginalColumnName = 0;
|
||||
|
||||
// db parameters
|
||||
int32_t tsCacheBlockSize = TSDB_DEFAULT_CACHE_BLOCK_SIZE;
|
||||
|
@ -126,33 +126,36 @@ int16_t tsWAL = TSDB_DEFAULT_WAL_LEVEL;
|
|||
int32_t tsFsyncPeriod = TSDB_DEFAULT_FSYNC_PERIOD;
|
||||
int32_t tsReplications = TSDB_DEFAULT_DB_REPLICA_OPTION;
|
||||
int32_t tsQuorum = TSDB_DEFAULT_DB_QUORUM_OPTION;
|
||||
int32_t tsUpdate = TSDB_DEFAULT_DB_UPDATE_OPTION;
|
||||
int8_t tsUpdate = TSDB_DEFAULT_DB_UPDATE_OPTION;
|
||||
int8_t tsCacheLastRow = TSDB_DEFAULT_CACHE_BLOCK_SIZE;
|
||||
int32_t tsMaxVgroupsPerDb = 0;
|
||||
int32_t tsMinTablePerVnode = TSDB_TABLES_STEP;
|
||||
int32_t tsMaxTablePerVnode = TSDB_DEFAULT_TABLES;
|
||||
int32_t tsTableIncStepPerVnode = TSDB_TABLES_STEP;
|
||||
|
||||
// balance
|
||||
int32_t tsEnableBalance = 1;
|
||||
int32_t tsAlternativeRole = 0;
|
||||
int32_t tsBalanceInterval = 300; // seconds
|
||||
int32_t tsOfflineThreshold = 86400*100; // seconds 10days
|
||||
int8_t tsEnableBalance = 1;
|
||||
int8_t tsAlternativeRole = 0;
|
||||
int32_t tsBalanceInterval = 300; // seconds
|
||||
int32_t tsOfflineThreshold = 86400 * 100; // seconds 10days
|
||||
int32_t tsMnodeEqualVnodeNum = 4;
|
||||
int32_t tsFlowCtrl = 1;
|
||||
int8_t tsEnableFlowCtrl = 1;
|
||||
int8_t tsEnableSlaveQuery = 1;
|
||||
int8_t tsEnableAdjustMaster = 1;
|
||||
|
||||
// restful
|
||||
int32_t tsEnableHttpModule = 1;
|
||||
int8_t tsEnableHttpModule = 1;
|
||||
int32_t tsRestRowLimit = 10240;
|
||||
uint16_t tsHttpPort = 6041; // only tcp, range tcp[6041]
|
||||
int32_t tsHttpCacheSessions = 1000;
|
||||
int32_t tsHttpSessionExpire = 36000;
|
||||
int32_t tsHttpMaxThreads = 2;
|
||||
int32_t tsHttpEnableCompress = 1;
|
||||
int32_t tsHttpEnableRecordSql = 0;
|
||||
int32_t tsTelegrafUseFieldNum = 0;
|
||||
int8_t tsHttpEnableCompress = 1;
|
||||
int8_t tsHttpEnableRecordSql = 0;
|
||||
int8_t tsTelegrafUseFieldNum = 0;
|
||||
|
||||
// mqtt
|
||||
int32_t tsEnableMqttModule = 0; // not finished yet, not started it by default
|
||||
int8_t tsEnableMqttModule = 0; // not finished yet, not started it by default
|
||||
char tsMqttHostName[TSDB_MQTT_HOSTNAME_LEN] = "test.mosquitto.org";
|
||||
char tsMqttPort[TSDB_MQTT_PORT_LEN] = "1883";
|
||||
char tsMqttUser[TSDB_MQTT_USER_LEN] = {0};
|
||||
|
@ -161,24 +164,24 @@ char tsMqttClientId[TSDB_MQTT_CLIENT_ID_LEN] = "TDengineMqttSubscriber";
|
|||
char tsMqttTopic[TSDB_MQTT_TOPIC_LEN] = "/test"; // #
|
||||
|
||||
// monitor
|
||||
int32_t tsEnableMonitorModule = 1;
|
||||
int8_t tsEnableMonitorModule = 1;
|
||||
char tsMonitorDbName[TSDB_DB_NAME_LEN] = "log";
|
||||
char tsInternalPass[] = "secretkey";
|
||||
int32_t tsMonitorInterval = 30; // seconds
|
||||
|
||||
// stream
|
||||
int32_t tsEnableStream = 1;
|
||||
int8_t tsEnableStream = 1;
|
||||
|
||||
// internal
|
||||
int32_t tsPrintAuth = 0;
|
||||
uint32_t tscEmbedded = 0;
|
||||
char configDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsVnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsDnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsMnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsDataDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsScriptDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsVnodeBakDir[TSDB_FILENAME_LEN] = {0};
|
||||
int8_t tsPrintAuth = 0;
|
||||
int8_t tscEmbedded = 0;
|
||||
char configDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsVnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsDnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsMnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsDataDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsScriptDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsVnodeBakDir[TSDB_FILENAME_LEN] = {0};
|
||||
|
||||
/*
|
||||
* minimum scale for whole system, millisecond by default
|
||||
|
@ -198,10 +201,10 @@ float tsTotalTmpDirGB = 0;
|
|||
float tsTotalDataDirGB = 0;
|
||||
float tsAvailTmpDirectorySpace = 0;
|
||||
float tsAvailDataDirGB = 0;
|
||||
float tsReservedTmpDirectorySpace = 0.1f;
|
||||
float tsMinimalDataDirGB = 0.5f;
|
||||
float tsReservedTmpDirectorySpace = 1.0f;
|
||||
float tsMinimalDataDirGB = 1.0f;
|
||||
int32_t tsTotalMemoryMB = 0;
|
||||
int32_t tsVersion = 0;
|
||||
uint32_t tsVersion = 0;
|
||||
|
||||
// log
|
||||
int32_t tsNumOfLogLines = 10000000;
|
||||
|
@ -209,13 +212,13 @@ int32_t mDebugFlag = 131;
|
|||
int32_t sdbDebugFlag = 131;
|
||||
int32_t dDebugFlag = 135;
|
||||
int32_t vDebugFlag = 135;
|
||||
uint32_t cDebugFlag = 131;
|
||||
int32_t cDebugFlag = 131;
|
||||
int32_t jniDebugFlag = 131;
|
||||
int32_t odbcDebugFlag = 131;
|
||||
int32_t httpDebugFlag = 131;
|
||||
int32_t mqttDebugFlag = 131;
|
||||
int32_t monDebugFlag = 131;
|
||||
uint32_t qDebugFlag = 131;
|
||||
int32_t qDebugFlag = 131;
|
||||
int32_t rpcDebugFlag = 131;
|
||||
int32_t uDebugFlag = 131;
|
||||
int32_t debugFlag = 0;
|
||||
|
@ -275,12 +278,16 @@ bool taosCfgDynamicOptions(char *msg) {
|
|||
for (int32_t i = 0; i < tsGlobalConfigNum; ++i) {
|
||||
SGlobalCfg *cfg = tsGlobalConfig + i;
|
||||
//if (!(cfg->cfgType & TSDB_CFG_CTYPE_B_LOG)) continue;
|
||||
if (cfg->valType != TAOS_CFG_VTYPE_INT32) continue;
|
||||
if (cfg->valType != TAOS_CFG_VTYPE_INT32 && cfg->valType != TAOS_CFG_VTYPE_INT8) continue;
|
||||
|
||||
int32_t cfgLen = (int32_t)strlen(cfg->option);
|
||||
if (cfgLen != olen) continue;
|
||||
if (strncasecmp(option, cfg->option, olen) != 0) continue;
|
||||
*((int32_t *)cfg->ptr) = vint;
|
||||
if (cfg->valType != TAOS_CFG_VTYPE_INT32) {
|
||||
*((int32_t *)cfg->ptr) = vint;
|
||||
} else {
|
||||
*((int8_t *)cfg->ptr) = (int8_t)vint;
|
||||
}
|
||||
|
||||
if (strncasecmp(cfg->option, "monitor", olen) == 0) {
|
||||
if (1 == vint) {
|
||||
|
@ -468,7 +475,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "vnodeBak";
|
||||
cfg.ptr = &tsEnableVnodeBak;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -478,7 +485,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "telemetryReporting";
|
||||
cfg.ptr = &tsEnableTelemetryReporting;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -488,7 +495,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "balance";
|
||||
cfg.ptr = &tsEnableBalance;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -509,7 +516,7 @@ static void doInitGlobalConfig(void) {
|
|||
// 0-any; 1-mnode; 2-vnode
|
||||
cfg.option = "role";
|
||||
cfg.ptr = &tsAlternativeRole;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 2;
|
||||
|
@ -542,7 +549,7 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.ptr = &tsOfflineThreshold;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 5;
|
||||
cfg.minValue = 3;
|
||||
cfg.maxValue = 7200000;
|
||||
cfg.ptrLength = 0;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_SECOND;
|
||||
|
@ -811,7 +818,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "update";
|
||||
cfg.ptr = &tsUpdate;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = TSDB_MIN_DB_UPDATE;
|
||||
cfg.maxValue = TSDB_MAX_DB_UPDATE;
|
||||
|
@ -901,7 +908,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "keepColumnName";
|
||||
cfg.ptr = &tsKeepOriginalColumnName;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1004,8 +1011,28 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
// module configs
|
||||
cfg.option = "flowctrl";
|
||||
cfg.ptr = &tsFlowCtrl;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.ptr = &tsEnableFlowCtrl;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
cfg.ptrLength = 0;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "slaveQuery";
|
||||
cfg.ptr = &tsEnableSlaveQuery;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
cfg.ptrLength = 0;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "adjustMaster";
|
||||
cfg.ptr = &tsEnableAdjustMaster;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1015,7 +1042,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "http";
|
||||
cfg.ptr = &tsEnableHttpModule;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1025,7 +1052,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "mqtt";
|
||||
cfg.ptr = &tsEnableMqttModule;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1035,7 +1062,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "monitor";
|
||||
cfg.ptr = &tsEnableMonitorModule;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1045,7 +1072,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "stream";
|
||||
cfg.ptr = &tsEnableStream;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1055,7 +1082,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "httpEnableRecordSql";
|
||||
cfg.ptr = &tsHttpEnableRecordSql;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1065,7 +1092,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "telegrafUseFieldNum";
|
||||
cfg.ptr = &tsTelegrafUseFieldNum;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1116,7 +1143,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "asyncLog";
|
||||
cfg.ptr = &tsAsyncLog;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT16;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG | TSDB_CFG_CTYPE_B_CLIENT;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1317,7 +1344,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "enableRecordSql";
|
||||
cfg.ptr = &tsTscEnableRecordSql;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1327,7 +1354,7 @@ static void doInitGlobalConfig(void) {
|
|||
|
||||
cfg.option = "enableCoreFile";
|
||||
cfg.ptr = &tsEnableCoreFile;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT8;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
|
@ -1451,15 +1478,20 @@ int32_t taosCheckGlobalCfg() {
|
|||
|
||||
// todo refactor
|
||||
tsVersion = 0;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int ver = 0, i = 0; i < TSDB_VERSION_LEN; ++i) {
|
||||
if (version[i] >= '0' && version[i] <= '9') {
|
||||
tsVersion = tsVersion * 10 + (version[i] - '0');
|
||||
ver = ver * 10 + (version[i] - '0');
|
||||
} else if (version[i] == '.') {
|
||||
tsVersion |= ver & 0xFF;
|
||||
tsVersion <<= 8;
|
||||
|
||||
ver = 0;
|
||||
} else if (version[i] == 0) {
|
||||
tsVersion |= ver & 0xFF;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tsVersion = 10 * tsVersion;
|
||||
|
||||
tsDnodeShellPort = tsServerPort + TSDB_PORT_DNODESHELL; // udp[6035-6039] tcp[6035]
|
||||
tsDnodeDnodePort = tsServerPort + TSDB_PORT_DNODEDNODE; // udp/tcp
|
||||
|
|
|
@ -349,11 +349,12 @@ CTaosInterface.prototype.useResult = function useResult(result) {
|
|||
return fields;
|
||||
}
|
||||
CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
||||
let pblock = ref.ref(ref.ref(ref.NULL)); // equal to our raw data
|
||||
let num_of_rows = this.libtaos.taos_fetch_block(result, pblock)
|
||||
if (num_of_rows == 0) {
|
||||
//let pblock = ref.ref(ref.ref(ref.NULL)); // equal to our raw data
|
||||
let pblock = this.libtaos.taos_fetch_row(result);
|
||||
if (pblock == null) {
|
||||
return {block:null, num_of_rows:0};
|
||||
}
|
||||
|
||||
var fieldL = this.libtaos.taos_fetch_lengths(result);
|
||||
|
||||
let isMicro = (this.libtaos.taos_result_precision(result) == FieldTypes.C_TIMESTAMP_MICRO);
|
||||
|
@ -361,7 +362,6 @@ CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
|||
var fieldlens = [];
|
||||
|
||||
if (ref.isNull(fieldL) == false) {
|
||||
|
||||
for (let i = 0; i < fields.length; i ++) {
|
||||
let plen = ref.reinterpret(fieldL, 4, i*4);
|
||||
let len = plen.readInt32LE(0);
|
||||
|
|
|
@ -25,6 +25,7 @@ int32_t dnodeInitCfg();
|
|||
void dnodeCleanupCfg();
|
||||
void dnodeUpdateCfg(SDnodeCfg *cfg);
|
||||
int32_t dnodeGetDnodeId();
|
||||
void dnodeGetClusterId(char *clusterId);
|
||||
void dnodeGetCfg(int32_t *dnodeId, char *clusterId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -51,6 +51,12 @@ int32_t dnodeGetDnodeId() {
|
|||
return dnodeId;
|
||||
}
|
||||
|
||||
void dnodeGetClusterId(char *clusterId) {
|
||||
pthread_mutex_lock(&tsCfgMutex);
|
||||
tstrncpy(clusterId, tsCfg.clusterId, TSDB_CLUSTER_ID_LEN);
|
||||
pthread_mutex_unlock(&tsCfgMutex);
|
||||
}
|
||||
|
||||
void dnodeGetCfg(int32_t *dnodeId, char *clusterId) {
|
||||
pthread_mutex_lock(&tsCfgMutex);
|
||||
*dnodeId = tsCfg.dnodeId;
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "tqueue.h"
|
||||
#include "twal.h"
|
||||
#include "mnode.h"
|
||||
#include "dnodeVMgmt.h"
|
||||
#include "dnodeMInfos.h"
|
||||
#include "dnodeMRead.h"
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "ttimer.h"
|
||||
#include "tqueue.h"
|
||||
#include "mnode.h"
|
||||
#include "dnodeVMgmt.h"
|
||||
#include "dnodeMInfos.h"
|
||||
#include "dnodeMWrite.h"
|
||||
|
||||
|
|
|
@ -113,6 +113,7 @@ static void dnodeCleanupTmr() {
|
|||
int32_t dnodeInitSystem() {
|
||||
dnodeSetRunStatus(TSDB_RUN_STATUS_INITIALIZE);
|
||||
tscEmbedded = 1;
|
||||
taosIgnSIGPIPE();
|
||||
taosBlockSIGPIPE();
|
||||
taosResolveCRC();
|
||||
taosInitGlobalCfg();
|
||||
|
@ -120,7 +121,6 @@ int32_t dnodeInitSystem() {
|
|||
taosSetCoreDump();
|
||||
taosInitNotes();
|
||||
dnodeInitTmr();
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (dnodeCreateDir(tsLogDir) < 0) {
|
||||
printf("failed to create dir: %s, reason: %s\n", tsLogDir, strerror(errno));
|
||||
|
|
|
@ -217,4 +217,4 @@ static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
|
|||
dnodeStartMnode(&pCfg->mnodes);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ void dnodeCleanupVRead() {
|
|||
void dnodeDispatchToVReadQueue(SRpcMsg *pMsg) {
|
||||
int32_t queuedMsgNum = 0;
|
||||
int32_t leftLen = pMsg->contLen;
|
||||
int32_t code = TSDB_CODE_VND_INVALID_VGROUP_ID;
|
||||
char * pCont = pMsg->pCont;
|
||||
|
||||
while (leftLen > 0) {
|
||||
|
@ -64,7 +65,7 @@ void dnodeDispatchToVReadQueue(SRpcMsg *pMsg) {
|
|||
assert(pHead->contLen > 0);
|
||||
void *pVnode = vnodeAcquire(pHead->vgId);
|
||||
if (pVnode != NULL) {
|
||||
int32_t code = vnodeWriteToRQueue(pVnode, pCont, pHead->contLen, TAOS_QTYPE_RPC, pMsg);
|
||||
code = vnodeWriteToRQueue(pVnode, pCont, pHead->contLen, TAOS_QTYPE_RPC, pMsg);
|
||||
if (code == TSDB_CODE_SUCCESS) queuedMsgNum++;
|
||||
vnodeRelease(pVnode);
|
||||
}
|
||||
|
@ -74,7 +75,7 @@ void dnodeDispatchToVReadQueue(SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
if (queuedMsgNum == 0) {
|
||||
SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = TSDB_CODE_VND_INVALID_VGROUP_ID};
|
||||
SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = code};
|
||||
rpcSendResponse(&rpcRsp);
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ static void *dnodeProcessVWriteQueue(void *wparam) {
|
|||
int32_t numOfMsgs;
|
||||
int32_t qtype;
|
||||
|
||||
taosBlockSIGPIPE();
|
||||
dDebug("dnode vwrite worker:%d is running", pWorker->workerId);
|
||||
|
||||
while (1) {
|
||||
|
|
|
@ -245,12 +245,11 @@ static void dnodeSendStatusMsg(void *handle, void *tmrId) {
|
|||
pStatus->lastReboot = htonl(tsRebootTime);
|
||||
pStatus->numOfCores = htons((uint16_t) tsNumOfCores);
|
||||
pStatus->diskAvailable = tsAvailDataDirGB;
|
||||
pStatus->alternativeRole = (uint8_t) tsAlternativeRole;
|
||||
pStatus->alternativeRole = tsAlternativeRole;
|
||||
tstrncpy(pStatus->dnodeEp, tsLocalEp, TSDB_EP_LEN);
|
||||
|
||||
// fill cluster cfg parameters
|
||||
pStatus->clusterCfg.numOfMnodes = htonl(tsNumOfMnodes);
|
||||
pStatus->clusterCfg.enableBalance = htonl(tsEnableBalance);
|
||||
pStatus->clusterCfg.mnodeEqualVnodeNum = htonl(tsMnodeEqualVnodeNum);
|
||||
pStatus->clusterCfg.offlineThreshold = htonl(tsOfflineThreshold);
|
||||
pStatus->clusterCfg.statusInterval = htonl(tsStatusInterval);
|
||||
|
@ -262,7 +261,12 @@ static void dnodeSendStatusMsg(void *handle, void *tmrId) {
|
|||
char timestr[32] = "1970-01-01 00:00:00.00";
|
||||
(void)taosParseTime(timestr, &pStatus->clusterCfg.checkTime, strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
|
||||
tstrncpy(pStatus->clusterCfg.locale, tsLocale, TSDB_LOCALE_LEN);
|
||||
tstrncpy(pStatus->clusterCfg.charset, tsCharset, TSDB_LOCALE_LEN);
|
||||
tstrncpy(pStatus->clusterCfg.charset, tsCharset, TSDB_LOCALE_LEN);
|
||||
|
||||
pStatus->clusterCfg.enableBalance = tsEnableBalance;
|
||||
pStatus->clusterCfg.flowCtrl = tsEnableFlowCtrl;
|
||||
pStatus->clusterCfg.slaveQuery = tsEnableSlaveQuery;
|
||||
pStatus->clusterCfg.adjustMaster = tsEnableAdjustMaster;
|
||||
|
||||
vnodeBuildStatusMsg(pStatus);
|
||||
contLen = sizeof(SStatusMsg) + pStatus->openVnodes * sizeof(SVnodeLoad);
|
||||
|
|
|
@ -36,6 +36,8 @@ bool dnodeIsMasterEp(char *ep);
|
|||
void dnodeGetEpSetForPeer(SRpcEpSet *epSet);
|
||||
void dnodeGetEpSetForShell(SRpcEpSet *epSet);
|
||||
int32_t dnodeGetDnodeId();
|
||||
void dnodeGetClusterId(char *clusterId);
|
||||
|
||||
void dnodeUpdateEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
|
||||
bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr);
|
||||
bool dnodeStartMnode(SMInfos *pMinfos);
|
||||
|
@ -80,4 +82,4 @@ void dnodeReportStep(char *name, char *desc, int8_t finished);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -369,6 +369,10 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_MAX_DB_UPDATE 1
|
||||
#define TSDB_DEFAULT_DB_UPDATE_OPTION 0
|
||||
|
||||
#define TSDB_MIN_DB_CACHE_LAST_ROW 0
|
||||
#define TSDB_MAX_DB_CACHE_LAST_ROW 1
|
||||
#define TSDB_DEFAULT_CACHE_LAST_ROW 0
|
||||
|
||||
#define TSDB_MIN_FSYNC_PERIOD 0
|
||||
#define TSDB_MAX_FSYNC_PERIOD 180000 // millisecond
|
||||
#define TSDB_DEFAULT_FSYNC_PERIOD 3000 // three second
|
||||
|
|
|
@ -67,6 +67,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_RESPONSE_TYPE, 0, 0x0012, "Invalid re
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_TIME_STAMP, 0, 0x0013, "Client and server's time is not synchronized")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_APP_NOT_READY, 0, 0x0014, "Database not ready")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_RPC_FQDN_ERROR, 0, 0x0015, "Unable to resolve FQDN")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_VERSION, 0, 0x0016, "Invalid app version")
|
||||
|
||||
//common & util
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_COM_OPS_NOT_SUPPORT, 0, 0x0100, "Operation not supported")
|
||||
|
|
|
@ -324,6 +324,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
char acctId[TSDB_ACCT_LEN];
|
||||
char serverVersion[TSDB_VERSION_LEN];
|
||||
char clusterId[TSDB_CLUSTER_ID_LEN];
|
||||
int8_t writeAuth;
|
||||
int8_t superAuth;
|
||||
int8_t reserved1;
|
||||
|
@ -549,7 +550,8 @@ typedef struct {
|
|||
int8_t quorum;
|
||||
int8_t ignoreExist;
|
||||
int8_t update;
|
||||
int8_t reserve[9];
|
||||
int8_t cacheLastRow;
|
||||
int8_t reserve[8];
|
||||
} SCreateDbMsg, SAlterDbMsg;
|
||||
|
||||
typedef struct {
|
||||
|
@ -604,7 +606,6 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int32_t numOfMnodes; // tsNumOfMnodes
|
||||
int32_t enableBalance; // tsEnableBalance
|
||||
int32_t mnodeEqualVnodeNum; // tsMnodeEqualVnodeNum
|
||||
int32_t offlineThreshold; // tsOfflineThreshold
|
||||
int32_t statusInterval; // tsStatusInterval
|
||||
|
@ -615,6 +616,11 @@ typedef struct {
|
|||
int64_t checkTime; // 1970-01-01 00:00:00.000
|
||||
char locale[TSDB_LOCALE_LEN]; // tsLocale
|
||||
char charset[TSDB_LOCALE_LEN]; // tsCharset
|
||||
int8_t enableBalance; // tsEnableBalance
|
||||
int8_t flowCtrl;
|
||||
int8_t slaveQuery;
|
||||
int8_t adjustMaster;
|
||||
int8_t reserved[4];
|
||||
} SClusterCfg;
|
||||
|
||||
typedef struct {
|
||||
|
@ -661,8 +667,9 @@ typedef struct {
|
|||
int8_t wals;
|
||||
int8_t quorum;
|
||||
int8_t update;
|
||||
int8_t reserved[11];
|
||||
int8_t cacheLastRow;
|
||||
int32_t vgCfgVersion;
|
||||
int8_t reserved[10];
|
||||
} SVnodeCfg;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -66,6 +66,7 @@ typedef struct {
|
|||
int8_t precision;
|
||||
int8_t compression;
|
||||
int8_t update;
|
||||
int8_t cacheLastRow;
|
||||
} STsdbCfg;
|
||||
|
||||
// --------- TSDB REPOSITORY USAGE STATISTICS
|
||||
|
@ -119,7 +120,7 @@ STableCfg *tsdbCreateTableCfgFromMsg(SMDCreateTableMsg *pMsg);
|
|||
int tsdbCreateTable(TSDB_REPO_T *repo, STableCfg *pCfg);
|
||||
int tsdbDropTable(TSDB_REPO_T *pRepo, STableId tableId);
|
||||
int tsdbUpdateTableTagValue(TSDB_REPO_T *repo, SUpdateTableTagValMsg *pMsg);
|
||||
TSKEY tsdbGetTableLastKey(TSDB_REPO_T *repo, uint64_t uid);
|
||||
// TSKEY tsdbGetTableLastKey(TSDB_REPO_T *repo, uint64_t uid);
|
||||
|
||||
uint32_t tsdbGetFileInfo(TSDB_REPO_T *repo, char *name, uint32_t *index, uint32_t eindex, int64_t *size);
|
||||
|
||||
|
|
|
@ -114,114 +114,115 @@
|
|||
#define TK_COMP 96
|
||||
#define TK_PRECISION 97
|
||||
#define TK_UPDATE 98
|
||||
#define TK_LP 99
|
||||
#define TK_RP 100
|
||||
#define TK_TAGS 101
|
||||
#define TK_USING 102
|
||||
#define TK_AS 103
|
||||
#define TK_COMMA 104
|
||||
#define TK_NULL 105
|
||||
#define TK_SELECT 106
|
||||
#define TK_UNION 107
|
||||
#define TK_ALL 108
|
||||
#define TK_FROM 109
|
||||
#define TK_VARIABLE 110
|
||||
#define TK_INTERVAL 111
|
||||
#define TK_FILL 112
|
||||
#define TK_SLIDING 113
|
||||
#define TK_ORDER 114
|
||||
#define TK_BY 115
|
||||
#define TK_ASC 116
|
||||
#define TK_DESC 117
|
||||
#define TK_GROUP 118
|
||||
#define TK_HAVING 119
|
||||
#define TK_LIMIT 120
|
||||
#define TK_OFFSET 121
|
||||
#define TK_SLIMIT 122
|
||||
#define TK_SOFFSET 123
|
||||
#define TK_WHERE 124
|
||||
#define TK_NOW 125
|
||||
#define TK_RESET 126
|
||||
#define TK_QUERY 127
|
||||
#define TK_ADD 128
|
||||
#define TK_COLUMN 129
|
||||
#define TK_TAG 130
|
||||
#define TK_CHANGE 131
|
||||
#define TK_SET 132
|
||||
#define TK_KILL 133
|
||||
#define TK_CONNECTION 134
|
||||
#define TK_STREAM 135
|
||||
#define TK_COLON 136
|
||||
#define TK_ABORT 137
|
||||
#define TK_AFTER 138
|
||||
#define TK_ATTACH 139
|
||||
#define TK_BEFORE 140
|
||||
#define TK_BEGIN 141
|
||||
#define TK_CASCADE 142
|
||||
#define TK_CLUSTER 143
|
||||
#define TK_CONFLICT 144
|
||||
#define TK_COPY 145
|
||||
#define TK_DEFERRED 146
|
||||
#define TK_DELIMITERS 147
|
||||
#define TK_DETACH 148
|
||||
#define TK_EACH 149
|
||||
#define TK_END 150
|
||||
#define TK_EXPLAIN 151
|
||||
#define TK_FAIL 152
|
||||
#define TK_FOR 153
|
||||
#define TK_IGNORE 154
|
||||
#define TK_IMMEDIATE 155
|
||||
#define TK_INITIALLY 156
|
||||
#define TK_INSTEAD 157
|
||||
#define TK_MATCH 158
|
||||
#define TK_KEY 159
|
||||
#define TK_OF 160
|
||||
#define TK_RAISE 161
|
||||
#define TK_REPLACE 162
|
||||
#define TK_RESTRICT 163
|
||||
#define TK_ROW 164
|
||||
#define TK_STATEMENT 165
|
||||
#define TK_TRIGGER 166
|
||||
#define TK_VIEW 167
|
||||
#define TK_COUNT 168
|
||||
#define TK_SUM 169
|
||||
#define TK_AVG 170
|
||||
#define TK_MIN 171
|
||||
#define TK_MAX 172
|
||||
#define TK_FIRST 173
|
||||
#define TK_LAST 174
|
||||
#define TK_TOP 175
|
||||
#define TK_BOTTOM 176
|
||||
#define TK_STDDEV 177
|
||||
#define TK_PERCENTILE 178
|
||||
#define TK_APERCENTILE 179
|
||||
#define TK_LEASTSQUARES 180
|
||||
#define TK_HISTOGRAM 181
|
||||
#define TK_DIFF 182
|
||||
#define TK_SPREAD 183
|
||||
#define TK_TWA 184
|
||||
#define TK_INTERP 185
|
||||
#define TK_LAST_ROW 186
|
||||
#define TK_RATE 187
|
||||
#define TK_IRATE 188
|
||||
#define TK_SUM_RATE 189
|
||||
#define TK_SUM_IRATE 190
|
||||
#define TK_AVG_RATE 191
|
||||
#define TK_AVG_IRATE 192
|
||||
#define TK_TBID 193
|
||||
#define TK_SEMI 194
|
||||
#define TK_NONE 195
|
||||
#define TK_PREV 196
|
||||
#define TK_LINEAR 197
|
||||
#define TK_IMPORT 198
|
||||
#define TK_METRIC 199
|
||||
#define TK_TBNAME 200
|
||||
#define TK_JOIN 201
|
||||
#define TK_METRICS 202
|
||||
#define TK_STABLE 203
|
||||
#define TK_INSERT 204
|
||||
#define TK_INTO 205
|
||||
#define TK_VALUES 206
|
||||
#define TK_CACHELAST 99
|
||||
#define TK_LP 100
|
||||
#define TK_RP 101
|
||||
#define TK_TAGS 102
|
||||
#define TK_USING 103
|
||||
#define TK_AS 104
|
||||
#define TK_COMMA 105
|
||||
#define TK_NULL 106
|
||||
#define TK_SELECT 107
|
||||
#define TK_UNION 108
|
||||
#define TK_ALL 109
|
||||
#define TK_FROM 110
|
||||
#define TK_VARIABLE 111
|
||||
#define TK_INTERVAL 112
|
||||
#define TK_FILL 113
|
||||
#define TK_SLIDING 114
|
||||
#define TK_ORDER 115
|
||||
#define TK_BY 116
|
||||
#define TK_ASC 117
|
||||
#define TK_DESC 118
|
||||
#define TK_GROUP 119
|
||||
#define TK_HAVING 120
|
||||
#define TK_LIMIT 121
|
||||
#define TK_OFFSET 122
|
||||
#define TK_SLIMIT 123
|
||||
#define TK_SOFFSET 124
|
||||
#define TK_WHERE 125
|
||||
#define TK_NOW 126
|
||||
#define TK_RESET 127
|
||||
#define TK_QUERY 128
|
||||
#define TK_ADD 129
|
||||
#define TK_COLUMN 130
|
||||
#define TK_TAG 131
|
||||
#define TK_CHANGE 132
|
||||
#define TK_SET 133
|
||||
#define TK_KILL 134
|
||||
#define TK_CONNECTION 135
|
||||
#define TK_STREAM 136
|
||||
#define TK_COLON 137
|
||||
#define TK_ABORT 138
|
||||
#define TK_AFTER 139
|
||||
#define TK_ATTACH 140
|
||||
#define TK_BEFORE 141
|
||||
#define TK_BEGIN 142
|
||||
#define TK_CASCADE 143
|
||||
#define TK_CLUSTER 144
|
||||
#define TK_CONFLICT 145
|
||||
#define TK_COPY 146
|
||||
#define TK_DEFERRED 147
|
||||
#define TK_DELIMITERS 148
|
||||
#define TK_DETACH 149
|
||||
#define TK_EACH 150
|
||||
#define TK_END 151
|
||||
#define TK_EXPLAIN 152
|
||||
#define TK_FAIL 153
|
||||
#define TK_FOR 154
|
||||
#define TK_IGNORE 155
|
||||
#define TK_IMMEDIATE 156
|
||||
#define TK_INITIALLY 157
|
||||
#define TK_INSTEAD 158
|
||||
#define TK_MATCH 159
|
||||
#define TK_KEY 160
|
||||
#define TK_OF 161
|
||||
#define TK_RAISE 162
|
||||
#define TK_REPLACE 163
|
||||
#define TK_RESTRICT 164
|
||||
#define TK_ROW 165
|
||||
#define TK_STATEMENT 166
|
||||
#define TK_TRIGGER 167
|
||||
#define TK_VIEW 168
|
||||
#define TK_COUNT 169
|
||||
#define TK_SUM 170
|
||||
#define TK_AVG 171
|
||||
#define TK_MIN 172
|
||||
#define TK_MAX 173
|
||||
#define TK_FIRST 174
|
||||
#define TK_LAST 175
|
||||
#define TK_TOP 176
|
||||
#define TK_BOTTOM 177
|
||||
#define TK_STDDEV 178
|
||||
#define TK_PERCENTILE 179
|
||||
#define TK_APERCENTILE 180
|
||||
#define TK_LEASTSQUARES 181
|
||||
#define TK_HISTOGRAM 182
|
||||
#define TK_DIFF 183
|
||||
#define TK_SPREAD 184
|
||||
#define TK_TWA 185
|
||||
#define TK_INTERP 186
|
||||
#define TK_LAST_ROW 187
|
||||
#define TK_RATE 188
|
||||
#define TK_IRATE 189
|
||||
#define TK_SUM_RATE 190
|
||||
#define TK_SUM_IRATE 191
|
||||
#define TK_AVG_RATE 192
|
||||
#define TK_AVG_IRATE 193
|
||||
#define TK_TBID 194
|
||||
#define TK_SEMI 195
|
||||
#define TK_NONE 196
|
||||
#define TK_PREV 197
|
||||
#define TK_LINEAR 198
|
||||
#define TK_IMPORT 199
|
||||
#define TK_METRIC 200
|
||||
#define TK_TBNAME 201
|
||||
#define TK_JOIN 202
|
||||
#define TK_METRICS 203
|
||||
#define TK_STABLE 204
|
||||
#define TK_INSERT 205
|
||||
#define TK_INTO 206
|
||||
#define TK_VALUES 207
|
||||
|
||||
|
||||
#define TK_SPACE 300
|
||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
|||
default: \
|
||||
(_v) = (_finalType)GET_INT32_VAL(_data); \
|
||||
break; \
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -302,14 +302,12 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
|||
|
||||
st = taosGetTimestampUs();
|
||||
|
||||
TAOS_RES* tmpSql = NULL;
|
||||
TAOS_RES* pSql = taos_query_h(con, command, &tmpSql);
|
||||
TAOS_RES* pSql = taos_query_h(con, command, &result);
|
||||
if (taos_errno(pSql)) {
|
||||
taos_error(pSql, st);
|
||||
return;
|
||||
}
|
||||
|
||||
atomic_store_64(&result, ((SSqlObj*)tmpSql)->self);
|
||||
int64_t oresult = atomic_load_64(&result);
|
||||
|
||||
if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) {
|
||||
|
|
|
@ -95,7 +95,7 @@ typedef struct DemoArguments {
|
|||
{0, 'P', "password", 0, "The password to use when connecting to the server. Default is 'taosdata'.", 3},
|
||||
#endif
|
||||
{0, 'd', "database", 0, "Destination database. Default is 'test'.", 3},
|
||||
{0, 'a', "replica", 0, "Set the replica parameters of the database, Default 1, min: 1, max: 3.", 3},
|
||||
{0, 'a', "replica", 0, "Set the replica parameters of the database, Default 1, min: 1, max: 3.", 3},
|
||||
{0, 'm', "table_prefix", 0, "Table prefix name. Default is 't'.", 3},
|
||||
{0, 's', "sql file", 0, "The select sql file.", 3},
|
||||
{0, 'M', 0, 0, "Use metric flag.", 13},
|
||||
|
@ -205,10 +205,10 @@ typedef struct DemoArguments {
|
|||
arguments->tb_prefix = arg;
|
||||
break;
|
||||
case 'M':
|
||||
arguments->use_metric = false;
|
||||
arguments->use_metric = true;
|
||||
break;
|
||||
case 'x':
|
||||
arguments->insert_only = false;
|
||||
arguments->insert_only = true;
|
||||
break;
|
||||
case 'c':
|
||||
if (wordexp(arg, &full_path, 0) != 0) {
|
||||
|
@ -406,9 +406,9 @@ typedef struct DemoArguments {
|
|||
} else if (strcmp(argv[i], "-m") == 0) {
|
||||
arguments->tb_prefix = argv[++i];
|
||||
} else if (strcmp(argv[i], "-M") == 0) {
|
||||
arguments->use_metric = false;
|
||||
arguments->use_metric = true;
|
||||
} else if (strcmp(argv[i], "-x") == 0) {
|
||||
arguments->insert_only = false;
|
||||
arguments->insert_only = true;
|
||||
} else if (strcmp(argv[i], "-c") == 0) {
|
||||
strcpy(configDir, argv[++i]);
|
||||
} else if (strcmp(argv[i], "-O") == 0) {
|
||||
|
@ -476,6 +476,14 @@ typedef struct {
|
|||
int notFinished;
|
||||
tsem_t lock_sem;
|
||||
int counter;
|
||||
|
||||
// insert delay statitics
|
||||
int64_t cntDelay;
|
||||
int64_t totalDelay;
|
||||
int64_t avgDelay;
|
||||
int64_t maxDelay;
|
||||
int64_t minDelay;
|
||||
|
||||
} info;
|
||||
|
||||
typedef struct {
|
||||
|
@ -575,7 +583,7 @@ int main(int argc, char *argv[]) {
|
|||
arguments.num_of_DPT = 100000;
|
||||
arguments.num_of_RPR = 1000;
|
||||
arguments.use_metric = true;
|
||||
arguments.insert_only = true;
|
||||
arguments.insert_only = false;
|
||||
// end change
|
||||
|
||||
parse_args(argc, argv, &arguments);
|
||||
|
@ -739,6 +747,9 @@ int main(int argc, char *argv[]) {
|
|||
printf("Inserting data......\n");
|
||||
pthread_t *pids = malloc(threads * sizeof(pthread_t));
|
||||
info *infos = malloc(threads * sizeof(info));
|
||||
|
||||
memset(pids, 0, threads * sizeof(pthread_t));
|
||||
memset(infos, 0, threads * sizeof(info));
|
||||
|
||||
int a = ntables / threads;
|
||||
if (a < 1) {
|
||||
|
@ -768,6 +779,7 @@ int main(int argc, char *argv[]) {
|
|||
t_info->end_table_id = i < b ? last + a : last + a - 1;
|
||||
last = t_info->end_table_id + 1;
|
||||
t_info->counter = 0;
|
||||
t_info->minDelay = INT16_MAX;
|
||||
|
||||
tsem_init(&(t_info->mutex_sem), 0, 1);
|
||||
t_info->notFinished = t_info->end_table_id - t_info->start_table_id + 1;
|
||||
|
@ -799,12 +811,29 @@ int main(int argc, char *argv[]) {
|
|||
t, (int64_t)ntables * nrecords_per_table, nrecords_per_request,
|
||||
(int64_t)ntables * nrecords_per_table / t);
|
||||
|
||||
int64_t totalDelay = 0;
|
||||
int64_t maxDelay = 0;
|
||||
int64_t minDelay = INT16_MAX;
|
||||
int64_t cntDelay = 0;
|
||||
double avgDelay = 0;
|
||||
for (int i = 0; i < threads; i++) {
|
||||
info *t_info = infos + i;
|
||||
taos_close(t_info->taos);
|
||||
tsem_destroy(&(t_info->mutex_sem));
|
||||
tsem_destroy(&(t_info->lock_sem));
|
||||
|
||||
totalDelay += t_info->totalDelay;
|
||||
cntDelay += t_info->cntDelay;
|
||||
if (t_info->maxDelay > maxDelay) maxDelay = t_info->maxDelay;
|
||||
if (t_info->minDelay < minDelay) minDelay = t_info->minDelay;
|
||||
}
|
||||
avgDelay = (double)totalDelay / cntDelay;
|
||||
|
||||
fprintf(fp, "insert delay, avg:%10.6fms, max: %10.6fms, min: %10.6fms\n\n",
|
||||
avgDelay/1000.0, (double)maxDelay/1000.0, (double)minDelay/1000.0);
|
||||
|
||||
printf("insert delay, avg: %10.6fms, max: %10.6fms, min: %10.6fms\n\n",
|
||||
avgDelay/1000.0, (double)maxDelay/1000.0, (double)minDelay/1000.0);
|
||||
|
||||
free(pids);
|
||||
free(infos);
|
||||
|
@ -859,7 +888,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
|
||||
if (!insert_only) {
|
||||
if (false == insert_only) {
|
||||
// query data
|
||||
pthread_t read_id;
|
||||
info *rInfo = malloc(sizeof(info));
|
||||
|
@ -998,7 +1027,7 @@ void * createTable(void *sarg)
|
|||
/* Create all the tables; */
|
||||
printf("Creating table from %d to %d\n", winfo->start_table_id, winfo->end_table_id);
|
||||
for (int i = winfo->start_table_id; i <= winfo->end_table_id; i++) {
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s%d (ts timestamp%s;", winfo->db_name, winfo->tb_prefix, i, winfo->cols);
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s%d (ts timestamp%s);", winfo->db_name, winfo->tb_prefix, i, winfo->cols);
|
||||
queryDB(winfo->taos, command);
|
||||
}
|
||||
} else {
|
||||
|
@ -1204,6 +1233,41 @@ void *readMetric(void *sarg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int queryDbExec(TAOS *taos, char *command, int type) {
|
||||
int i;
|
||||
TAOS_RES *res = NULL;
|
||||
int32_t code = -1;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (NULL != res) {
|
||||
taos_free_result(res);
|
||||
res = NULL;
|
||||
}
|
||||
|
||||
res = taos_query(taos, command);
|
||||
code = taos_errno(res);
|
||||
if (0 == code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (code != 0) {
|
||||
fprintf(stderr, "Failed to run %s, reason: %s\n", command, taos_errstr(res));
|
||||
taos_free_result(res);
|
||||
//taos_close(taos);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (1 == type) {
|
||||
int affectedRows = taos_affected_rows(res);
|
||||
taos_free_result(res);
|
||||
return affectedRows;
|
||||
}
|
||||
|
||||
taos_free_result(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void queryDB(TAOS *taos, char *command) {
|
||||
int i;
|
||||
TAOS_RES *pSql = NULL;
|
||||
|
@ -1273,7 +1337,21 @@ void *syncWrite(void *sarg) {
|
|||
}
|
||||
|
||||
/* puts(buffer); */
|
||||
queryDB(winfo->taos, buffer);
|
||||
int64_t startTs;
|
||||
int64_t endTs;
|
||||
startTs = taosGetTimestampUs();
|
||||
//queryDB(winfo->taos, buffer);
|
||||
int affectedRows = queryDbExec(winfo->taos, buffer, 1);
|
||||
|
||||
if (0 <= affectedRows){
|
||||
endTs = taosGetTimestampUs();
|
||||
int64_t delay = endTs - startTs;
|
||||
if (delay > winfo->maxDelay) winfo->maxDelay = delay;
|
||||
if (delay < winfo->minDelay) winfo->minDelay = delay;
|
||||
winfo->cntDelay++;
|
||||
winfo->totalDelay += delay;
|
||||
//winfo->avgDelay = (double)winfo->totalDelay / winfo->cntDelay;
|
||||
}
|
||||
|
||||
if (tID == winfo->end_table_id) {
|
||||
i = inserted;
|
||||
|
|
|
@ -332,6 +332,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||
break;
|
||||
case 'N':
|
||||
arguments->data_batch = atoi(arg);
|
||||
if (arguments->data_batch >= INT16_MAX) {
|
||||
arguments->data_batch = INT16_MAX - 1;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
{
|
||||
|
|
|
@ -174,7 +174,8 @@ typedef struct {
|
|||
int8_t replications;
|
||||
int8_t quorum;
|
||||
int8_t update;
|
||||
int8_t reserved[11];
|
||||
int8_t cacheLastRow;
|
||||
int8_t reserved[10];
|
||||
} SDbCfg;
|
||||
|
||||
typedef struct SDbObj {
|
||||
|
|
|
@ -52,6 +52,9 @@ typedef enum EDnodeOfflineReason {
|
|||
TAOS_DN_OFF_TIME_ZONE_NOT_MATCH,
|
||||
TAOS_DN_OFF_LOCALE_NOT_MATCH,
|
||||
TAOS_DN_OFF_CHARSET_NOT_MATCH,
|
||||
TAOS_DN_OFF_FLOW_CTRL_NOT_MATCH,
|
||||
TAOS_DN_OFF_SLAVE_QUERY_NOT_MATCH,
|
||||
TAOS_DN_OFF_ADJUST_MASTER_NOT_MATCH,
|
||||
TAOS_DN_OFF_OTHERS
|
||||
} EDnodeOfflineReason;
|
||||
|
||||
|
|
|
@ -322,6 +322,11 @@ static int32_t mnodeCheckDbCfg(SDbCfg *pCfg) {
|
|||
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
||||
}
|
||||
|
||||
if (pCfg->cacheLastRow < TSDB_MIN_DB_CACHE_LAST_ROW || pCfg->cacheLastRow > TSDB_MAX_DB_CACHE_LAST_ROW) {
|
||||
mError("invalid db option cacheLastRow:%d valid range: [%d, %d]", pCfg->cacheLastRow, TSDB_MIN_DB_CACHE_LAST_ROW, TSDB_MAX_DB_CACHE_LAST_ROW);
|
||||
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -343,6 +348,7 @@ static void mnodeSetDefaultDbCfg(SDbCfg *pCfg) {
|
|||
if (pCfg->replications < 0) pCfg->replications = tsReplications;
|
||||
if (pCfg->quorum < 0) pCfg->quorum = tsQuorum;
|
||||
if (pCfg->update < 0) pCfg->update = tsUpdate;
|
||||
if (pCfg->cacheLastRow < 0) pCfg->cacheLastRow = tsCacheLastRow;
|
||||
}
|
||||
|
||||
static int32_t mnodeCreateDbCb(SMnodeMsg *pMsg, int32_t code) {
|
||||
|
@ -396,7 +402,8 @@ static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg *
|
|||
.walLevel = pCreate->walLevel,
|
||||
.replications = pCreate->replications,
|
||||
.quorum = pCreate->quorum,
|
||||
.update = pCreate->update
|
||||
.update = pCreate->update,
|
||||
.cacheLastRow = pCreate->cacheLastRow
|
||||
};
|
||||
|
||||
mnodeSetDefaultDbCfg(&pDb->cfg);
|
||||
|
@ -605,6 +612,12 @@ static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn
|
|||
strcpy(pSchema[cols].name, "comp");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 1;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_TINYINT;
|
||||
strcpy(pSchema[cols].name, "cachelast");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
#ifndef __CLOUD_VERSION__
|
||||
}
|
||||
#endif
|
||||
|
@ -750,6 +763,10 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
|
|||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int8_t *)pWrite = pDb->cfg.compression;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int8_t *)pWrite = pDb->cfg.cacheLastRow;
|
||||
cols++;
|
||||
#ifndef __CLOUD_VERSION__
|
||||
}
|
||||
#endif
|
||||
|
@ -864,6 +881,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
|
|||
int8_t quorum = pAlter->quorum;
|
||||
int8_t precision = pAlter->precision;
|
||||
int8_t update = pAlter->update;
|
||||
int8_t cacheLastRow = pAlter->cacheLastRow;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -976,6 +994,11 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
|
|||
#endif
|
||||
}
|
||||
|
||||
if (cacheLastRow >= 0 && cacheLastRow != pDb->cfg.cacheLastRow) {
|
||||
mDebug("db:%s, cacheLastRow:%d change to %d", pDb->name, pDb->cfg.cacheLastRow, cacheLastRow);
|
||||
newCfg.cacheLastRow = cacheLastRow;
|
||||
}
|
||||
|
||||
return newCfg;
|
||||
}
|
||||
|
||||
|
|
|
@ -375,10 +375,6 @@ static int32_t mnodeCheckClusterCfgPara(const SClusterCfg *clusterCfg) {
|
|||
mError("\"numOfMnodes\"[%d - %d] cfg parameters inconsistent", clusterCfg->numOfMnodes, htonl(tsNumOfMnodes));
|
||||
return TAOS_DN_OFF_NUM_OF_MNODES_NOT_MATCH;
|
||||
}
|
||||
if (clusterCfg->enableBalance != htonl(tsEnableBalance)) {
|
||||
mError("\"balance\"[%d - %d] cfg parameters inconsistent", clusterCfg->enableBalance, htonl(tsEnableBalance));
|
||||
return TAOS_DN_OFF_ENABLE_BALANCE_NOT_MATCH;
|
||||
}
|
||||
if (clusterCfg->mnodeEqualVnodeNum != htonl(tsMnodeEqualVnodeNum)) {
|
||||
mError("\"mnodeEqualVnodeNum\"[%d - %d] cfg parameters inconsistent", clusterCfg->mnodeEqualVnodeNum,
|
||||
htonl(tsMnodeEqualVnodeNum));
|
||||
|
@ -428,6 +424,23 @@ static int32_t mnodeCheckClusterCfgPara(const SClusterCfg *clusterCfg) {
|
|||
return TAOS_DN_OFF_CHARSET_NOT_MATCH;
|
||||
}
|
||||
|
||||
if (clusterCfg->enableBalance != tsEnableBalance) {
|
||||
mError("\"balance\"[%d - %d] cfg parameters inconsistent", clusterCfg->enableBalance, tsEnableBalance);
|
||||
return TAOS_DN_OFF_ENABLE_BALANCE_NOT_MATCH;
|
||||
}
|
||||
if (clusterCfg->flowCtrl != tsEnableFlowCtrl) {
|
||||
mError("\"flowCtrl\"[%d - %d] cfg parameters inconsistent", clusterCfg->flowCtrl, tsEnableFlowCtrl);
|
||||
return TAOS_DN_OFF_FLOW_CTRL_NOT_MATCH;
|
||||
}
|
||||
if (clusterCfg->slaveQuery != tsEnableSlaveQuery) {
|
||||
mError("\"slaveQuery\"[%d - %d] cfg parameters inconsistent", clusterCfg->slaveQuery, tsEnableSlaveQuery);
|
||||
return TAOS_DN_OFF_SLAVE_QUERY_NOT_MATCH;
|
||||
}
|
||||
if (clusterCfg->adjustMaster != tsEnableAdjustMaster) {
|
||||
mError("\"adjustMaster\"[%d - %d] cfg parameters inconsistent", clusterCfg->adjustMaster, tsEnableAdjustMaster);
|
||||
return TAOS_DN_OFF_ADJUST_MASTER_NOT_MATCH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1031,6 +1044,11 @@ static int32_t mnodeRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, v
|
|||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
switch (cfg->valType) {
|
||||
case TAOS_CFG_VTYPE_INT8:
|
||||
t = snprintf(varDataVal(pWrite), TSDB_CFG_VALUE_LEN, "%d", *((int8_t *)cfg->ptr));
|
||||
varDataSetLen(pWrite, t);
|
||||
numOfRows++;
|
||||
break;
|
||||
case TAOS_CFG_VTYPE_INT16:
|
||||
t = snprintf(varDataVal(pWrite), TSDB_CFG_VALUE_LEN, "%d", *((int16_t *)cfg->ptr));
|
||||
varDataSetLen(pWrite, t);
|
||||
|
|
|
@ -377,6 +377,24 @@ static int32_t mnodeCreateMnodeCb(SMnodeMsg *pMsg, int32_t code) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static bool mnodeAllOnline() {
|
||||
void *pIter = NULL;
|
||||
bool allOnline = true;
|
||||
|
||||
while (1) {
|
||||
SMnodeObj *pMnode = NULL;
|
||||
pIter = mnodeGetNextMnode(pIter, &pMnode);
|
||||
if (pMnode == NULL) break;
|
||||
if (pMnode->role != TAOS_SYNC_ROLE_MASTER && pMnode->role != TAOS_SYNC_ROLE_SLAVE) {
|
||||
allOnline = false;
|
||||
mnodeDecMnodeRef(pMnode);
|
||||
}
|
||||
}
|
||||
mnodeCancelGetNextMnode(pIter);
|
||||
|
||||
return allOnline;
|
||||
}
|
||||
|
||||
void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) {
|
||||
SMnodeObj *pMnode = calloc(1, sizeof(SMnodeObj));
|
||||
pMnode->mnodeId = dnodeId;
|
||||
|
@ -389,6 +407,11 @@ void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) {
|
|||
.fpRsp = mnodeCreateMnodeCb
|
||||
};
|
||||
|
||||
if (needConfirm && !mnodeAllOnline()) {
|
||||
mDebug("wait all mnode online then create new mnode");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (needConfirm) {
|
||||
code = mnodeSendCreateMnodeMsg(dnodeId, dnodeEp);
|
||||
|
|
|
@ -1081,6 +1081,8 @@ static void *sdbWorkerFp(void *pWorker) {
|
|||
int32_t qtype;
|
||||
void * unUsed;
|
||||
|
||||
taosBlockSIGPIPE();
|
||||
|
||||
while (1) {
|
||||
int32_t numOfMsgs = taosReadAllQitemsFromQset(tsSdbWQset, tsSdbWQall, &unUsed);
|
||||
if (numOfMsgs == 0) {
|
||||
|
|
|
@ -351,6 +351,8 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
mnodeGetMnodeEpSetForShell(&pConnectRsp->epSet, false);
|
||||
|
||||
dnodeGetClusterId(pConnectRsp->clusterId);
|
||||
|
||||
connect_over:
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
if (pConnectRsp) rpcFreeCont(pConnectRsp);
|
||||
|
|
|
@ -659,7 +659,7 @@ static int32_t mnodeGetVgroupMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *p
|
|||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "onlineVnodes");
|
||||
strcpy(pSchema[cols].name, "onlines");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
|
@ -674,13 +674,13 @@ static int32_t mnodeGetVgroupMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *p
|
|||
for (int32_t i = 0; i < pShow->maxReplica; ++i) {
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
snprintf(pSchema[cols].name, TSDB_COL_NAME_LEN, "v%dDnode", i + 1);
|
||||
snprintf(pSchema[cols].name, TSDB_COL_NAME_LEN, "v%d_dnode", i + 1);
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 9 + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
snprintf(pSchema[cols].name, TSDB_COL_NAME_LEN, "v%dStatus", i + 1);
|
||||
snprintf(pSchema[cols].name, TSDB_COL_NAME_LEN, "v%d_status", i + 1);
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
}
|
||||
|
@ -863,6 +863,7 @@ static SCreateVnodeMsg *mnodeBuildVnodeMsg(SVgObj *pVgroup) {
|
|||
pCfg->wals = 3;
|
||||
pCfg->quorum = pDb->cfg.quorum;
|
||||
pCfg->update = pDb->cfg.update;
|
||||
pCfg->cacheLastRow = pDb->cfg.cacheLastRow;
|
||||
|
||||
SVnodeDesc *pNodes = pVnode->nodes;
|
||||
for (int32_t j = 0; j < pVgroup->numOfVnodes; ++j) {
|
||||
|
|
|
@ -59,6 +59,7 @@ extern "C" {
|
|||
|
||||
// TAOS_OS_FUNC_SOCKET
|
||||
int32_t taosSetNonblocking(SOCKET sock, int32_t on);
|
||||
void taosIgnSIGPIPE();
|
||||
void taosBlockSIGPIPE();
|
||||
|
||||
// TAOS_OS_FUNC_SOCKET_SETSOCKETOPT
|
||||
|
|
|
@ -39,6 +39,10 @@ int32_t taosSetNonblocking(SOCKET sock, int32_t on) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void taosIgnSIGPIPE() {
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
|
||||
void taosBlockSIGPIPE() {
|
||||
sigset_t signal_mask;
|
||||
sigemptyset(&signal_mask);
|
||||
|
|
|
@ -46,6 +46,7 @@ int32_t taosSetNonblocking(SOCKET sock, int32_t on) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void taosIgnSIGPIPE() {}
|
||||
void taosBlockSIGPIPE() {}
|
||||
|
||||
int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t optlen) {
|
||||
|
|
|
@ -33,13 +33,6 @@ struct SColumnFilterElem;
|
|||
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, char* val1, char* val2);
|
||||
typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int32_t order);
|
||||
|
||||
typedef struct SGroupResInfo {
|
||||
int32_t groupId;
|
||||
int32_t numOfDataPages;
|
||||
int32_t pageId;
|
||||
int32_t rowId;
|
||||
} SGroupResInfo;
|
||||
|
||||
typedef struct SResultRowPool {
|
||||
int32_t elemSize;
|
||||
int32_t blockSize;
|
||||
|
@ -72,6 +65,12 @@ typedef struct SResultRow {
|
|||
union {STimeWindow win; char* key;}; // start key of current time window
|
||||
} SResultRow;
|
||||
|
||||
typedef struct SGroupResInfo {
|
||||
int32_t rowId;
|
||||
int32_t index;
|
||||
SArray* pRows; // SArray<SResultRow*>
|
||||
} SGroupResInfo;
|
||||
|
||||
/**
|
||||
* If the number of generated results is greater than this value,
|
||||
* query query will be halt and return results to client immediate.
|
||||
|
@ -89,7 +88,6 @@ typedef struct SResultRowInfo {
|
|||
int32_t size:24; // number of result set
|
||||
int32_t capacity; // max capacity
|
||||
int32_t curIndex; // current start active index
|
||||
int64_t startTime; // start time of the first time window for sliding query
|
||||
int64_t prevSKey; // previous (not completed) sliding window start key
|
||||
} SResultRowInfo;
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ void tHistogramDestroy(SHistogramInfo** pHisto);
|
|||
|
||||
void tHistogramPrint(SHistogramInfo* pHisto);
|
||||
|
||||
int32_t vnodeHistobinarySearch(SHistBin* pEntry, int32_t len, double val);
|
||||
int32_t histoBinarySearch(SHistBin* pEntry, int32_t len, double val);
|
||||
|
||||
SHeapEntry* tHeapCreate(int32_t numOfEntries);
|
||||
void tHeapSort(SHeapEntry* pEntry, int32_t len);
|
||||
|
|
|
@ -120,7 +120,8 @@ typedef struct SCreateDBInfo {
|
|||
int32_t compressionLevel;
|
||||
SStrToken precision;
|
||||
bool ignoreExists;
|
||||
int8_t update;
|
||||
int8_t update;
|
||||
int8_t cachelast;
|
||||
|
||||
SArray *keep;
|
||||
} SCreateDBInfo;
|
||||
|
|
|
@ -34,17 +34,13 @@ int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size, int16_t
|
|||
void cleanupResultRowInfo(SResultRowInfo* pResultRowInfo);
|
||||
|
||||
void resetResultRowInfo(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo);
|
||||
void popFrontResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, int32_t num);
|
||||
void clearClosedResultRows(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo *pResultRowInfo);
|
||||
int32_t numOfClosedResultRows(SResultRowInfo* pResultRowInfo);
|
||||
void closeAllResultRows(SResultRowInfo* pResultRowInfo);
|
||||
void removeRedundantResultRows(SResultRowInfo *pResultRowInfo, TSKEY lastKey, int32_t order);
|
||||
|
||||
int32_t initResultRow(SResultRow *pResultRow);
|
||||
void closeResultRow(SResultRowInfo* pResultRowInfo, int32_t slot);
|
||||
bool isResultRowClosed(SResultRowInfo *pResultRowInfo, int32_t slot);
|
||||
void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, int16_t type);
|
||||
void copyResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* dst, const SResultRow* src, int16_t type);
|
||||
|
||||
SResultRowCellInfo* getResultCell(SQueryRuntimeEnv* pRuntimeEnv, const SResultRow* pRow, int32_t index);
|
||||
|
||||
|
@ -77,7 +73,6 @@ void* destroyResultRowPool(SResultRowPool* p);
|
|||
int32_t getNumOfAllocatedResultRows(SResultRowPool* p);
|
||||
int32_t getNumOfUsedResultRows(SResultRowPool* p);
|
||||
|
||||
uint64_t getResultInfoUId(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
bool isPointInterpoQuery(SQuery *pQuery);
|
||||
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ extern "C" {
|
|||
|
||||
#include "tlog.h"
|
||||
|
||||
extern uint32_t qDebugFlag;
|
||||
extern uint32_t tscEmbedded;
|
||||
extern int32_t qDebugFlag;
|
||||
extern int8_t tscEmbedded;
|
||||
|
||||
#define qFatal(...) do { if (qDebugFlag & DEBUG_FATAL) { taosPrintLog("QRY FATAL ", 255, __VA_ARGS__); }} while(0)
|
||||
#define qError(...) do { if (qDebugFlag & DEBUG_ERROR) { taosPrintLog("QRY ERROR ", 255, __VA_ARGS__); }} while(0)
|
||||
|
|
|
@ -112,29 +112,29 @@ cmd ::= SHOW dbPrefix(X) STABLES. {
|
|||
|
||||
cmd ::= SHOW dbPrefix(X) STABLES LIKE ids(Y). {
|
||||
SStrToken token;
|
||||
setDBName(&token, &X);
|
||||
setDbName(&token, &X);
|
||||
setShowOptions(pInfo, TSDB_MGMT_TABLE_METRIC, &token, &Y);
|
||||
}
|
||||
|
||||
cmd ::= SHOW dbPrefix(X) VGROUPS. {
|
||||
SStrToken token;
|
||||
setDBName(&token, &X);
|
||||
setDbName(&token, &X);
|
||||
setShowOptions(pInfo, TSDB_MGMT_TABLE_VGROUP, &token, 0);
|
||||
}
|
||||
|
||||
cmd ::= SHOW dbPrefix(X) VGROUPS ids(Y). {
|
||||
SStrToken token;
|
||||
setDBName(&token, &X);
|
||||
setDbName(&token, &X);
|
||||
setShowOptions(pInfo, TSDB_MGMT_TABLE_VGROUP, &token, &Y);
|
||||
}
|
||||
|
||||
//drop configure for tables
|
||||
cmd ::= DROP TABLE ifexists(Y) ids(X) cpxName(Z). {
|
||||
X.n += Z.n;
|
||||
setDropDBTableInfo(pInfo, TSDB_SQL_DROP_TABLE, &X, &Y);
|
||||
setDropDbTableInfo(pInfo, TSDB_SQL_DROP_TABLE, &X, &Y);
|
||||
}
|
||||
|
||||
cmd ::= DROP DATABASE ifexists(Y) ids(X). { setDropDBTableInfo(pInfo, TSDB_SQL_DROP_DB, &X, &Y); }
|
||||
cmd ::= DROP DATABASE ifexists(Y) ids(X). { setDropDbTableInfo(pInfo, TSDB_SQL_DROP_DB, &X, &Y); }
|
||||
cmd ::= DROP DNODE ids(X). { setDCLSQLElems(pInfo, TSDB_SQL_DROP_DNODE, 1, &X); }
|
||||
cmd ::= DROP USER ids(X). { setDCLSQLElems(pInfo, TSDB_SQL_DROP_USER, 1, &X); }
|
||||
cmd ::= DROP ACCOUNT ids(X). { setDCLSQLElems(pInfo, TSDB_SQL_DROP_ACCT, 1, &X); }
|
||||
|
@ -149,16 +149,16 @@ cmd ::= DESCRIBE ids(X) cpxName(Y). {
|
|||
}
|
||||
|
||||
/////////////////////////////////THE ALTER STATEMENT////////////////////////////////////////
|
||||
cmd ::= ALTER USER ids(X) PASS ids(Y). { setAlterUserSQL(pInfo, TSDB_ALTER_USER_PASSWD, &X, &Y, NULL); }
|
||||
cmd ::= ALTER USER ids(X) PRIVILEGE ids(Y). { setAlterUserSQL(pInfo, TSDB_ALTER_USER_PRIVILEGES, &X, NULL, &Y);}
|
||||
cmd ::= ALTER USER ids(X) PASS ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PASSWD, &X, &Y, NULL); }
|
||||
cmd ::= ALTER USER ids(X) PRIVILEGE ids(Y). { setAlterUserSql(pInfo, TSDB_ALTER_USER_PRIVILEGES, &X, NULL, &Y);}
|
||||
cmd ::= ALTER DNODE ids(X) ids(Y). { setDCLSQLElems(pInfo, TSDB_SQL_CFG_DNODE, 2, &X, &Y); }
|
||||
cmd ::= ALTER DNODE ids(X) ids(Y) ids(Z). { setDCLSQLElems(pInfo, TSDB_SQL_CFG_DNODE, 3, &X, &Y, &Z); }
|
||||
cmd ::= ALTER LOCAL ids(X). { setDCLSQLElems(pInfo, TSDB_SQL_CFG_LOCAL, 1, &X); }
|
||||
cmd ::= ALTER LOCAL ids(X) ids(Y). { setDCLSQLElems(pInfo, TSDB_SQL_CFG_LOCAL, 2, &X, &Y); }
|
||||
cmd ::= ALTER DATABASE ids(X) alter_db_optr(Y). { SStrToken t = {0}; setCreateDBSQL(pInfo, TSDB_SQL_ALTER_DB, &X, &Y, &t);}
|
||||
|
||||
cmd ::= ALTER ACCOUNT ids(X) acct_optr(Z). { setCreateAcctSQL(pInfo, TSDB_SQL_ALTER_ACCT, &X, NULL, &Z);}
|
||||
cmd ::= ALTER ACCOUNT ids(X) PASS ids(Y) acct_optr(Z). { setCreateAcctSQL(pInfo, TSDB_SQL_ALTER_ACCT, &X, &Y, &Z);}
|
||||
cmd ::= ALTER ACCOUNT ids(X) acct_optr(Z). { setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &X, NULL, &Z);}
|
||||
cmd ::= ALTER ACCOUNT ids(X) PASS ids(Y) acct_optr(Z). { setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &X, &Y, &Z);}
|
||||
|
||||
// An IDENTIFIER can be a generic identifier, or one of several keywords.
|
||||
// Any non-standard keyword can also be an identifier.
|
||||
|
@ -179,9 +179,9 @@ ifnotexists(X) ::= . { X.n = 0;}
|
|||
//create option for dnode/db/user/account
|
||||
cmd ::= CREATE DNODE ids(X). { setDCLSQLElems(pInfo, TSDB_SQL_CREATE_DNODE, 1, &X);}
|
||||
cmd ::= CREATE ACCOUNT ids(X) PASS ids(Y) acct_optr(Z).
|
||||
{ setCreateAcctSQL(pInfo, TSDB_SQL_CREATE_ACCT, &X, &Y, &Z);}
|
||||
{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &X, &Y, &Z);}
|
||||
cmd ::= CREATE DATABASE ifnotexists(Z) ids(X) db_optr(Y). { setCreateDBSQL(pInfo, TSDB_SQL_CREATE_DB, &X, &Y, &Z);}
|
||||
cmd ::= CREATE USER ids(X) PASS ids(Y). { setCreateUserSQL(pInfo, &X, &Y);}
|
||||
cmd ::= CREATE USER ids(X) PASS ids(Y). { setCreateUserSql(pInfo, &X, &Y);}
|
||||
|
||||
pps(Y) ::= . { Y.n = 0; }
|
||||
pps(Y) ::= PPS INTEGER(X). { Y = X; }
|
||||
|
@ -240,6 +240,7 @@ fsync(Y) ::= FSYNC INTEGER(X). { Y = X; }
|
|||
comp(Y) ::= COMP INTEGER(X). { Y = X; }
|
||||
prec(Y) ::= PRECISION STRING(X). { Y = X; }
|
||||
update(Y) ::= UPDATE INTEGER(X). { Y = X; }
|
||||
cachelast(Y) ::= CACHELAST INTEGER(X). { Y = X; }
|
||||
|
||||
%type db_optr {SCreateDBInfo}
|
||||
db_optr(Y) ::= . {setDefaultCreateDbOption(&Y);}
|
||||
|
@ -258,6 +259,7 @@ db_optr(Y) ::= db_optr(Z) comp(X). { Y = Z; Y.compressionLevel = strto
|
|||
db_optr(Y) ::= db_optr(Z) prec(X). { Y = Z; Y.precision = X; }
|
||||
db_optr(Y) ::= db_optr(Z) keep(X). { Y = Z; Y.keep = X; }
|
||||
db_optr(Y) ::= db_optr(Z) update(X). { Y = Z; Y.update = strtol(X.z, NULL, 10); }
|
||||
db_optr(Y) ::= db_optr(Z) cachelast(X). { Y = Z; Y.cachelast = strtol(X.z, NULL, 10); }
|
||||
|
||||
%type alter_db_optr {SCreateDBInfo}
|
||||
alter_db_optr(Y) ::= . { setDefaultCreateDbOption(&Y);}
|
||||
|
@ -270,21 +272,22 @@ alter_db_optr(Y) ::= alter_db_optr(Z) comp(X). { Y = Z; Y.compressionLeve
|
|||
alter_db_optr(Y) ::= alter_db_optr(Z) wal(X). { Y = Z; Y.walLevel = strtol(X.z, NULL, 10); }
|
||||
alter_db_optr(Y) ::= alter_db_optr(Z) fsync(X). { Y = Z; Y.fsyncPeriod = strtol(X.z, NULL, 10); }
|
||||
alter_db_optr(Y) ::= alter_db_optr(Z) update(X). { Y = Z; Y.update = strtol(X.z, NULL, 10); }
|
||||
alter_db_optr(Y) ::= alter_db_optr(Z) cachelast(X). { Y = Z; Y.cachelast = strtol(X.z, NULL, 10); }
|
||||
|
||||
%type typename {TAOS_FIELD}
|
||||
typename(A) ::= ids(X). {
|
||||
X.type = 0;
|
||||
tSQLSetColumnType (&A, &X);
|
||||
tSqlSetColumnType (&A, &X);
|
||||
}
|
||||
|
||||
//define binary type, e.g., binary(10), nchar(10)
|
||||
typename(A) ::= ids(X) LP signed(Y) RP. {
|
||||
if (Y <= 0) {
|
||||
X.type = 0;
|
||||
tSQLSetColumnType(&A, &X);
|
||||
tSqlSetColumnType(&A, &X);
|
||||
} else {
|
||||
X.type = -Y; // negative value of name length
|
||||
tSQLSetColumnType(&A, &X);
|
||||
tSqlSetColumnType(&A, &X);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,8 +318,8 @@ create_table_list(A) ::= create_table_list(X) create_from_stable(Z). {
|
|||
|
||||
%type create_table_args{SCreateTableSQL*}
|
||||
create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) LP columnlist(X) RP. {
|
||||
A = tSetCreateSQLElems(X, NULL, NULL, TSQL_CREATE_TABLE);
|
||||
setSQLInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE);
|
||||
A = tSetCreateSqlElems(X, NULL, NULL, TSQL_CREATE_TABLE);
|
||||
setSqlInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE);
|
||||
|
||||
V.n += Z.n;
|
||||
setCreatedTableName(pInfo, &V, &U);
|
||||
|
@ -324,8 +327,8 @@ create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) LP columnlist(X) RP. {
|
|||
|
||||
// create super table
|
||||
create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) LP columnlist(X) RP TAGS LP columnlist(Y) RP. {
|
||||
A = tSetCreateSQLElems(X, Y, NULL, TSQL_CREATE_STABLE);
|
||||
setSQLInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE);
|
||||
A = tSetCreateSqlElems(X, Y, NULL, TSQL_CREATE_STABLE);
|
||||
setSqlInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE);
|
||||
|
||||
V.n += Z.n;
|
||||
setCreatedTableName(pInfo, &V, &U);
|
||||
|
@ -343,8 +346,8 @@ create_from_stable(A) ::= ifnotexists(U) ids(V) cpxName(Z) USING ids(X) cpxName(
|
|||
// create stream
|
||||
// create table table_name as select count(*) from super_table_name interval(time)
|
||||
create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) AS select(S). {
|
||||
A = tSetCreateSQLElems(NULL, NULL, S, TSQL_CREATE_STREAM);
|
||||
setSQLInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE);
|
||||
A = tSetCreateSqlElems(NULL, NULL, S, TSQL_CREATE_STREAM);
|
||||
setSqlInfo(pInfo, A, NULL, TSDB_SQL_CREATE_TABLE);
|
||||
|
||||
V.n += Z.n;
|
||||
setCreatedTableName(pInfo, &V, &U);
|
||||
|
@ -359,7 +362,7 @@ columnlist(A) ::= column(X). {A = taosArrayInit(4, sizeof(T
|
|||
// The information used for a column is the name and type of column:
|
||||
// tinyint smallint int bigint float double bool timestamp binary(x) nchar(x)
|
||||
column(A) ::= ids(X) typename(Y). {
|
||||
tSQLSetColumnInfo(&A, &X, &Y);
|
||||
tSqlSetColumnInfo(&A, &X, &Y);
|
||||
}
|
||||
|
||||
%type tagitemlist {SArray*}
|
||||
|
@ -407,7 +410,7 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). {
|
|||
%type select {SQuerySQL*}
|
||||
%destructor select {doDestroyQuerySql($$);}
|
||||
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
||||
A = tSetQuerySQLElems(&T, W, X, Y, P, Z, &K, &S, F, &L, &G);
|
||||
A = tSetQuerySqlElems(&T, W, X, Y, P, Z, &K, &S, F, &L, &G);
|
||||
}
|
||||
|
||||
%type union {SSubclauseInfo*}
|
||||
|
@ -418,33 +421,33 @@ union(Y) ::= LP union(X) RP. { Y = X; }
|
|||
union(Y) ::= union(Z) UNION ALL select(X). { Y = appendSelectClause(Z, X); }
|
||||
union(Y) ::= union(Z) UNION ALL LP select(X) RP. { Y = appendSelectClause(Z, X); }
|
||||
|
||||
cmd ::= union(X). { setSQLInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
|
||||
cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
|
||||
|
||||
// Support for the SQL exprssion without from & where subclauses, e.g.,
|
||||
// select current_database(),
|
||||
// select server_version(), select client_version(),
|
||||
// select server_state();
|
||||
select(A) ::= SELECT(T) selcollist(W). {
|
||||
A = tSetQuerySQLElems(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
A = tSetQuerySqlElems(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
// selcollist is a list of expressions that are to become the return
|
||||
// values of the SELECT statement. The "*" in statements like
|
||||
// "SELECT * FROM ..." is encoded as a special expression with an opcode of TK_ALL.
|
||||
%type selcollist {tSQLExprList*}
|
||||
%destructor selcollist {tSQLExprListDestroy($$);}
|
||||
%destructor selcollist {tSqlExprListDestroy($$);}
|
||||
|
||||
%type sclp {tSQLExprList*}
|
||||
%destructor sclp {tSQLExprListDestroy($$);}
|
||||
%destructor sclp {tSqlExprListDestroy($$);}
|
||||
sclp(A) ::= selcollist(X) COMMA. {A = X;}
|
||||
sclp(A) ::= . {A = 0;}
|
||||
selcollist(A) ::= sclp(P) expr(X) as(Y). {
|
||||
A = tSQLExprListAppend(P, X, Y.n?&Y:0);
|
||||
A = tSqlExprListAppend(P, X, Y.n?&Y:0);
|
||||
}
|
||||
|
||||
selcollist(A) ::= sclp(P) STAR. {
|
||||
tSQLExpr *pNode = tSQLExprIdValueCreate(NULL, TK_ALL);
|
||||
A = tSQLExprListAppend(P, pNode, 0);
|
||||
tSQLExpr *pNode = tSqlExprIdValueCreate(NULL, TK_ALL);
|
||||
A = tSqlExprListAppend(P, pNode, 0);
|
||||
}
|
||||
|
||||
// An option "AS <id>" phrase that can follow one of the expressions that
|
||||
|
@ -573,7 +576,7 @@ grouplist(A) ::= item(X). {
|
|||
|
||||
//having clause, ignore the input condition in having
|
||||
%type having_opt {tSQLExpr*}
|
||||
%destructor having_opt {tSQLExprDestroy($$);}
|
||||
%destructor having_opt {tSqlExprDestroy($$);}
|
||||
having_opt(A) ::=. {A = 0;}
|
||||
having_opt(A) ::= HAVING expr(X). {A = X;}
|
||||
|
||||
|
@ -595,7 +598,7 @@ slimit_opt(A) ::= SLIMIT signed(X) COMMA signed(Y).
|
|||
{A.limit = Y; A.offset = X;}
|
||||
|
||||
%type where_opt {tSQLExpr*}
|
||||
%destructor where_opt {tSQLExprDestroy($$);}
|
||||
%destructor where_opt {tSqlExprDestroy($$);}
|
||||
|
||||
where_opt(A) ::= . {A = 0;}
|
||||
where_opt(A) ::= WHERE expr(X). {A = X;}
|
||||
|
@ -603,67 +606,67 @@ where_opt(A) ::= WHERE expr(X). {A = X;}
|
|||
/////////////////////////// Expression Processing /////////////////////////////
|
||||
//
|
||||
%type expr {tSQLExpr*}
|
||||
%destructor expr {tSQLExprDestroy($$);}
|
||||
%destructor expr {tSqlExprDestroy($$);}
|
||||
|
||||
expr(A) ::= LP(X) expr(Y) RP(Z). {A = Y; A->token.z = X.z; A->token.n = (Z.z - X.z + 1);}
|
||||
|
||||
expr(A) ::= ID(X). { A = tSQLExprIdValueCreate(&X, TK_ID);}
|
||||
expr(A) ::= ID(X) DOT ID(Y). { X.n += (1+Y.n); A = tSQLExprIdValueCreate(&X, TK_ID);}
|
||||
expr(A) ::= ID(X) DOT STAR(Y). { X.n += (1+Y.n); A = tSQLExprIdValueCreate(&X, TK_ALL);}
|
||||
expr(A) ::= ID(X). { A = tSqlExprIdValueCreate(&X, TK_ID);}
|
||||
expr(A) ::= ID(X) DOT ID(Y). { X.n += (1+Y.n); A = tSqlExprIdValueCreate(&X, TK_ID);}
|
||||
expr(A) ::= ID(X) DOT STAR(Y). { X.n += (1+Y.n); A = tSqlExprIdValueCreate(&X, TK_ALL);}
|
||||
|
||||
expr(A) ::= INTEGER(X). { A = tSQLExprIdValueCreate(&X, TK_INTEGER);}
|
||||
expr(A) ::= MINUS(X) INTEGER(Y). { X.n += Y.n; X.type = TK_INTEGER; A = tSQLExprIdValueCreate(&X, TK_INTEGER);}
|
||||
expr(A) ::= PLUS(X) INTEGER(Y). { X.n += Y.n; X.type = TK_INTEGER; A = tSQLExprIdValueCreate(&X, TK_INTEGER);}
|
||||
expr(A) ::= FLOAT(X). { A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
|
||||
expr(A) ::= MINUS(X) FLOAT(Y). { X.n += Y.n; X.type = TK_FLOAT; A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
|
||||
expr(A) ::= PLUS(X) FLOAT(Y). { X.n += Y.n; X.type = TK_FLOAT; A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
|
||||
expr(A) ::= STRING(X). { A = tSQLExprIdValueCreate(&X, TK_STRING);}
|
||||
expr(A) ::= NOW(X). { A = tSQLExprIdValueCreate(&X, TK_NOW); }
|
||||
expr(A) ::= VARIABLE(X). { A = tSQLExprIdValueCreate(&X, TK_VARIABLE);}
|
||||
expr(A) ::= BOOL(X). { A = tSQLExprIdValueCreate(&X, TK_BOOL);}
|
||||
expr(A) ::= INTEGER(X). { A = tSqlExprIdValueCreate(&X, TK_INTEGER);}
|
||||
expr(A) ::= MINUS(X) INTEGER(Y). { X.n += Y.n; X.type = TK_INTEGER; A = tSqlExprIdValueCreate(&X, TK_INTEGER);}
|
||||
expr(A) ::= PLUS(X) INTEGER(Y). { X.n += Y.n; X.type = TK_INTEGER; A = tSqlExprIdValueCreate(&X, TK_INTEGER);}
|
||||
expr(A) ::= FLOAT(X). { A = tSqlExprIdValueCreate(&X, TK_FLOAT);}
|
||||
expr(A) ::= MINUS(X) FLOAT(Y). { X.n += Y.n; X.type = TK_FLOAT; A = tSqlExprIdValueCreate(&X, TK_FLOAT);}
|
||||
expr(A) ::= PLUS(X) FLOAT(Y). { X.n += Y.n; X.type = TK_FLOAT; A = tSqlExprIdValueCreate(&X, TK_FLOAT);}
|
||||
expr(A) ::= STRING(X). { A = tSqlExprIdValueCreate(&X, TK_STRING);}
|
||||
expr(A) ::= NOW(X). { A = tSqlExprIdValueCreate(&X, TK_NOW); }
|
||||
expr(A) ::= VARIABLE(X). { A = tSqlExprIdValueCreate(&X, TK_VARIABLE);}
|
||||
expr(A) ::= BOOL(X). { A = tSqlExprIdValueCreate(&X, TK_BOOL);}
|
||||
|
||||
// ordinary functions: min(x), max(x), top(k, 20)
|
||||
expr(A) ::= ID(X) LP exprlist(Y) RP(E). { A = tSQLExprCreateFunction(Y, &X, &E, X.type); }
|
||||
expr(A) ::= ID(X) LP exprlist(Y) RP(E). { A = tSqlExprCreateFunction(Y, &X, &E, X.type); }
|
||||
|
||||
// for parsing sql functions with wildcard for parameters. e.g., count(*)/first(*)/last(*) operation
|
||||
expr(A) ::= ID(X) LP STAR RP(Y). { A = tSQLExprCreateFunction(NULL, &X, &Y, X.type); }
|
||||
expr(A) ::= ID(X) LP STAR RP(Y). { A = tSqlExprCreateFunction(NULL, &X, &Y, X.type); }
|
||||
|
||||
// is (not) null expression
|
||||
expr(A) ::= expr(X) IS NULL. {A = tSQLExprCreate(X, NULL, TK_ISNULL);}
|
||||
expr(A) ::= expr(X) IS NOT NULL. {A = tSQLExprCreate(X, NULL, TK_NOTNULL);}
|
||||
expr(A) ::= expr(X) IS NULL. {A = tSqlExprCreate(X, NULL, TK_ISNULL);}
|
||||
expr(A) ::= expr(X) IS NOT NULL. {A = tSqlExprCreate(X, NULL, TK_NOTNULL);}
|
||||
|
||||
// relational expression
|
||||
expr(A) ::= expr(X) LT expr(Y). {A = tSQLExprCreate(X, Y, TK_LT);}
|
||||
expr(A) ::= expr(X) GT expr(Y). {A = tSQLExprCreate(X, Y, TK_GT);}
|
||||
expr(A) ::= expr(X) LE expr(Y). {A = tSQLExprCreate(X, Y, TK_LE);}
|
||||
expr(A) ::= expr(X) GE expr(Y). {A = tSQLExprCreate(X, Y, TK_GE);}
|
||||
expr(A) ::= expr(X) NE expr(Y). {A = tSQLExprCreate(X, Y, TK_NE);}
|
||||
expr(A) ::= expr(X) EQ expr(Y). {A = tSQLExprCreate(X, Y, TK_EQ);}
|
||||
expr(A) ::= expr(X) LT expr(Y). {A = tSqlExprCreate(X, Y, TK_LT);}
|
||||
expr(A) ::= expr(X) GT expr(Y). {A = tSqlExprCreate(X, Y, TK_GT);}
|
||||
expr(A) ::= expr(X) LE expr(Y). {A = tSqlExprCreate(X, Y, TK_LE);}
|
||||
expr(A) ::= expr(X) GE expr(Y). {A = tSqlExprCreate(X, Y, TK_GE);}
|
||||
expr(A) ::= expr(X) NE expr(Y). {A = tSqlExprCreate(X, Y, TK_NE);}
|
||||
expr(A) ::= expr(X) EQ expr(Y). {A = tSqlExprCreate(X, Y, TK_EQ);}
|
||||
|
||||
expr(A) ::= expr(X) AND expr(Y). {A = tSQLExprCreate(X, Y, TK_AND);}
|
||||
expr(A) ::= expr(X) OR expr(Y). {A = tSQLExprCreate(X, Y, TK_OR); }
|
||||
expr(A) ::= expr(X) AND expr(Y). {A = tSqlExprCreate(X, Y, TK_AND);}
|
||||
expr(A) ::= expr(X) OR expr(Y). {A = tSqlExprCreate(X, Y, TK_OR); }
|
||||
|
||||
// binary arithmetic expression
|
||||
expr(A) ::= expr(X) PLUS expr(Y). {A = tSQLExprCreate(X, Y, TK_PLUS); }
|
||||
expr(A) ::= expr(X) MINUS expr(Y). {A = tSQLExprCreate(X, Y, TK_MINUS); }
|
||||
expr(A) ::= expr(X) STAR expr(Y). {A = tSQLExprCreate(X, Y, TK_STAR); }
|
||||
expr(A) ::= expr(X) SLASH expr(Y). {A = tSQLExprCreate(X, Y, TK_DIVIDE);}
|
||||
expr(A) ::= expr(X) REM expr(Y). {A = tSQLExprCreate(X, Y, TK_REM); }
|
||||
expr(A) ::= expr(X) PLUS expr(Y). {A = tSqlExprCreate(X, Y, TK_PLUS); }
|
||||
expr(A) ::= expr(X) MINUS expr(Y). {A = tSqlExprCreate(X, Y, TK_MINUS); }
|
||||
expr(A) ::= expr(X) STAR expr(Y). {A = tSqlExprCreate(X, Y, TK_STAR); }
|
||||
expr(A) ::= expr(X) SLASH expr(Y). {A = tSqlExprCreate(X, Y, TK_DIVIDE);}
|
||||
expr(A) ::= expr(X) REM expr(Y). {A = tSqlExprCreate(X, Y, TK_REM); }
|
||||
|
||||
// like expression
|
||||
expr(A) ::= expr(X) LIKE expr(Y). {A = tSQLExprCreate(X, Y, TK_LIKE); }
|
||||
expr(A) ::= expr(X) LIKE expr(Y). {A = tSqlExprCreate(X, Y, TK_LIKE); }
|
||||
|
||||
//in expression
|
||||
expr(A) ::= expr(X) IN LP exprlist(Y) RP. {A = tSQLExprCreate(X, (tSQLExpr*)Y, TK_IN); }
|
||||
expr(A) ::= expr(X) IN LP exprlist(Y) RP. {A = tSqlExprCreate(X, (tSQLExpr*)Y, TK_IN); }
|
||||
|
||||
%type exprlist {tSQLExprList*}
|
||||
%destructor exprlist {tSQLExprListDestroy($$);}
|
||||
%destructor exprlist {tSqlExprListDestroy($$);}
|
||||
|
||||
%type expritem {tSQLExpr*}
|
||||
%destructor expritem {tSQLExprDestroy($$);}
|
||||
%destructor expritem {tSqlExprDestroy($$);}
|
||||
|
||||
exprlist(A) ::= exprlist(X) COMMA expritem(Y). {A = tSQLExprListAppend(X,Y,0);}
|
||||
exprlist(A) ::= expritem(X). {A = tSQLExprListAppend(0,X,0);}
|
||||
exprlist(A) ::= exprlist(X) COMMA expritem(Y). {A = tSqlExprListAppend(X,Y,0);}
|
||||
exprlist(A) ::= expritem(X). {A = tSqlExprListAppend(0,X,0);}
|
||||
expritem(A) ::= expr(X). {A = X;}
|
||||
expritem(A) ::= . {A = 0;}
|
||||
|
||||
|
@ -673,8 +676,8 @@ cmd ::= RESET QUERY CACHE. { setDCLSQLElems(pInfo, TSDB_SQL_RESET_CACHE, 0);}
|
|||
///////////////////////////////////ALTER TABLE statement//////////////////////////////////
|
||||
cmd ::= ALTER TABLE ids(X) cpxName(F) ADD COLUMN columnlist(A). {
|
||||
X.n += F.n;
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&X, A, NULL, TSDB_ALTER_TABLE_ADD_COLUMN);
|
||||
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSqlElems(&X, A, NULL, TSDB_ALTER_TABLE_ADD_COLUMN);
|
||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
}
|
||||
|
||||
cmd ::= ALTER TABLE ids(X) cpxName(F) DROP COLUMN ids(A). {
|
||||
|
@ -683,15 +686,15 @@ cmd ::= ALTER TABLE ids(X) cpxName(F) DROP COLUMN ids(A). {
|
|||
toTSDBType(A.type);
|
||||
SArray* K = tVariantListAppendToken(NULL, &A, -1);
|
||||
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&X, NULL, K, TSDB_ALTER_TABLE_DROP_COLUMN);
|
||||
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSqlElems(&X, NULL, K, TSDB_ALTER_TABLE_DROP_COLUMN);
|
||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
}
|
||||
|
||||
//////////////////////////////////ALTER TAGS statement/////////////////////////////////////
|
||||
cmd ::= ALTER TABLE ids(X) cpxName(Y) ADD TAG columnlist(A). {
|
||||
X.n += Y.n;
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&X, A, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN);
|
||||
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSqlElems(&X, A, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN);
|
||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
}
|
||||
cmd ::= ALTER TABLE ids(X) cpxName(Z) DROP TAG ids(Y). {
|
||||
X.n += Z.n;
|
||||
|
@ -699,8 +702,8 @@ cmd ::= ALTER TABLE ids(X) cpxName(Z) DROP TAG ids(Y). {
|
|||
toTSDBType(Y.type);
|
||||
SArray* A = tVariantListAppendToken(NULL, &Y, -1);
|
||||
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&X, NULL, A, TSDB_ALTER_TABLE_DROP_TAG_COLUMN);
|
||||
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSqlElems(&X, NULL, A, TSDB_ALTER_TABLE_DROP_TAG_COLUMN);
|
||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
}
|
||||
|
||||
cmd ::= ALTER TABLE ids(X) cpxName(F) CHANGE TAG ids(Y) ids(Z). {
|
||||
|
@ -712,8 +715,8 @@ cmd ::= ALTER TABLE ids(X) cpxName(F) CHANGE TAG ids(Y) ids(Z). {
|
|||
toTSDBType(Z.type);
|
||||
A = tVariantListAppendToken(A, &Z, -1);
|
||||
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&X, NULL, A, TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN);
|
||||
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSqlElems(&X, NULL, A, TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN);
|
||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
}
|
||||
|
||||
cmd ::= ALTER TABLE ids(X) cpxName(F) SET TAG ids(Y) EQ tagitem(Z). {
|
||||
|
@ -723,14 +726,14 @@ cmd ::= ALTER TABLE ids(X) cpxName(F) SET TAG ids(Y) EQ tagitem(Z). {
|
|||
SArray* A = tVariantListAppendToken(NULL, &Y, -1);
|
||||
A = tVariantListAppend(A, &Z, -1);
|
||||
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&X, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL);
|
||||
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
SAlterTableSQL* pAlterTable = tAlterTableSqlElems(&X, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL);
|
||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////kill statement///////////////////////////////////////
|
||||
cmd ::= KILL CONNECTION INTEGER(Y). {setKillSQL(pInfo, TSDB_SQL_KILL_CONNECTION, &Y);}
|
||||
cmd ::= KILL STREAM INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); setKillSQL(pInfo, TSDB_SQL_KILL_STREAM, &X);}
|
||||
cmd ::= KILL QUERY INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); setKillSQL(pInfo, TSDB_SQL_KILL_QUERY, &X);}
|
||||
cmd ::= KILL CONNECTION INTEGER(Y). {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &Y);}
|
||||
cmd ::= KILL STREAM INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); setKillSql(pInfo, TSDB_SQL_KILL_STREAM, &X);}
|
||||
cmd ::= KILL QUERY INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); setKillSql(pInfo, TSDB_SQL_KILL_QUERY, &X);}
|
||||
|
||||
%fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT COPY DATABASE DEFERRED
|
||||
DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -158,8 +158,8 @@ int32_t tHistogramAdd(SHistogramInfo** pHisto, double val) {
|
|||
}
|
||||
|
||||
#if defined(USE_ARRAYLIST)
|
||||
int32_t idx = vnodeHistobinarySearch((*pHisto)->elems, (*pHisto)->numOfEntries, val);
|
||||
assert(idx >= 0 && idx <= (*pHisto)->maxEntries);
|
||||
int32_t idx = histoBinarySearch((*pHisto)->elems, (*pHisto)->numOfEntries, val);
|
||||
assert(idx >= 0 && idx <= (*pHisto)->maxEntries && (*pHisto)->elems != NULL);
|
||||
|
||||
if ((*pHisto)->elems[idx].val == val && idx >= 0) {
|
||||
(*pHisto)->elems[idx].num += 1;
|
||||
|
@ -356,7 +356,7 @@ int32_t tHistogramAdd(SHistogramInfo** pHisto, double val) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t vnodeHistobinarySearch(SHistBin* pEntry, int32_t len, double val) {
|
||||
int32_t histoBinarySearch(SHistBin* pEntry, int32_t len, double val) {
|
||||
int32_t end = len - 1;
|
||||
int32_t start = 0;
|
||||
|
||||
|
@ -466,7 +466,7 @@ void tHistogramPrint(SHistogramInfo* pHisto) {
|
|||
*/
|
||||
int64_t tHistogramSum(SHistogramInfo* pHisto, double v) {
|
||||
#if defined(USE_ARRAYLIST)
|
||||
int32_t slotIdx = vnodeHistobinarySearch(pHisto->elems, pHisto->numOfEntries, v);
|
||||
int32_t slotIdx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, v);
|
||||
if (pHisto->elems[slotIdx].val != v) {
|
||||
slotIdx -= 1;
|
||||
|
||||
|
|
|
@ -846,5 +846,6 @@ void setDefaultCreateDbOption(SCreateDBInfo *pDBInfo) {
|
|||
pDBInfo->keep = NULL;
|
||||
|
||||
pDBInfo->update = -1;
|
||||
pDBInfo->cachelast = 0;
|
||||
memset(&pDBInfo->precision, 0, sizeof(SStrToken));
|
||||
}
|
||||
|
|
|
@ -313,7 +313,7 @@ tFilePage* getNewDataBuf(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32
|
|||
|
||||
// allocate buf
|
||||
if (availablePage == NULL) {
|
||||
pi->pData = calloc(1, pResultBuf->pageSize + POINTER_BYTES);
|
||||
pi->pData = calloc(1, pResultBuf->pageSize + POINTER_BYTES + 2); // add extract bytes in case of zipped buffer increased.
|
||||
} else {
|
||||
pi->pData = availablePage;
|
||||
}
|
||||
|
|
|
@ -238,6 +238,7 @@ static SKeyword keywordTable[] = {
|
|||
{"SUM_IRATE", TK_SUM_IRATE},
|
||||
{"AVG_RATE", TK_AVG_RATE},
|
||||
{"AVG_IRATE", TK_AVG_IRATE},
|
||||
{"CACHELAST", TK_CACHELAST},
|
||||
};
|
||||
|
||||
static const char isIdChar[] = {
|
||||
|
|
|
@ -20,18 +20,6 @@
|
|||
#include "qExecutor.h"
|
||||
#include "qUtil.h"
|
||||
|
||||
static int32_t getResultRowKeyInfo(SResultRow* pResult, int16_t type, char** key, int16_t* bytes) {
|
||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
||||
*key = varDataVal(pResult->key);
|
||||
*bytes = varDataLen(pResult->key);
|
||||
} else {
|
||||
*key = (char*) &pResult->win.skey;
|
||||
*bytes = tDataTypeDesc[type].nSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t getOutputInterResultBufSize(SQuery* pQuery) {
|
||||
int32_t size = 0;
|
||||
|
||||
|
@ -96,78 +84,9 @@ void resetResultRowInfo(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRo
|
|||
|
||||
pResultRowInfo->curIndex = -1;
|
||||
pResultRowInfo->size = 0;
|
||||
|
||||
pResultRowInfo->startTime = TSKEY_INITIAL_VAL;
|
||||
pResultRowInfo->prevSKey = TSKEY_INITIAL_VAL;
|
||||
}
|
||||
|
||||
void popFrontResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, int32_t num) {
|
||||
if (pResultRowInfo == NULL || pResultRowInfo->capacity == 0 || pResultRowInfo->size == 0 || num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t numOfClosed = numOfClosedResultRows(pResultRowInfo);
|
||||
assert(num >= 0 && num <= numOfClosed);
|
||||
|
||||
int16_t type = pResultRowInfo->type;
|
||||
int64_t uid = getResultInfoUId(pRuntimeEnv);
|
||||
|
||||
char *key = NULL;
|
||||
int16_t bytes = -1;
|
||||
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SResultRow *pResult = pResultRowInfo->pResult[i];
|
||||
if (pResult->closed) { // remove the window slot from hash table
|
||||
getResultRowKeyInfo(pResult, type, &key, &bytes);
|
||||
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid);
|
||||
taosHashRemove(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t remain = pResultRowInfo->size - num;
|
||||
|
||||
// clear all the closed windows from the window list
|
||||
for (int32_t k = 0; k < remain; ++k) {
|
||||
copyResultRow(pRuntimeEnv, pResultRowInfo->pResult[k], pResultRowInfo->pResult[num + k], type);
|
||||
}
|
||||
|
||||
// move the unclosed window in the front of the window list
|
||||
for (int32_t k = remain; k < pResultRowInfo->size; ++k) {
|
||||
SResultRow *pWindowRes = pResultRowInfo->pResult[k];
|
||||
clearResultRow(pRuntimeEnv, pWindowRes, pResultRowInfo->type);
|
||||
}
|
||||
|
||||
pResultRowInfo->size = remain;
|
||||
|
||||
for (int32_t k = 0; k < pResultRowInfo->size; ++k) {
|
||||
SResultRow *pResult = pResultRowInfo->pResult[k];
|
||||
getResultRowKeyInfo(pResult, type, &key, &bytes);
|
||||
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid);
|
||||
|
||||
int32_t *p = (int32_t *)taosHashGet(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
|
||||
assert(p != NULL);
|
||||
|
||||
int32_t v = (*p - num);
|
||||
assert(v >= 0 && v <= pResultRowInfo->size);
|
||||
|
||||
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid);
|
||||
taosHashPut(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), (char *)&v, sizeof(int32_t));
|
||||
}
|
||||
|
||||
pResultRowInfo->curIndex = -1;
|
||||
}
|
||||
|
||||
void clearClosedResultRows(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo) {
|
||||
if (pResultRowInfo == NULL || pResultRowInfo->capacity == 0 || pResultRowInfo->size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t numOfClosed = numOfClosedResultRows(pResultRowInfo);
|
||||
popFrontResultRow(pRuntimeEnv, &pRuntimeEnv->windowResInfo, numOfClosed);
|
||||
}
|
||||
|
||||
int32_t numOfClosedResultRows(SResultRowInfo *pResultRowInfo) {
|
||||
int32_t i = 0;
|
||||
while (i < pResultRowInfo->size && pResultRowInfo->pResult[i]->closed) {
|
||||
|
@ -181,45 +100,12 @@ void closeAllResultRows(SResultRowInfo *pResultRowInfo) {
|
|||
assert(pResultRowInfo->size >= 0 && pResultRowInfo->capacity >= pResultRowInfo->size);
|
||||
|
||||
for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
|
||||
if (pResultRowInfo->pResult[i]->closed) {
|
||||
SResultRow* pRow = pResultRowInfo->pResult[i];
|
||||
if (pRow->closed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pResultRowInfo->pResult[i]->closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remove the results that are not the FIRST time window that spreads beyond the
|
||||
* the last qualified time stamp in case of sliding query, which the sliding time is not equalled to the interval time.
|
||||
* NOTE: remove redundant, only when the result set order equals to traverse order
|
||||
*/
|
||||
void removeRedundantResultRows(SResultRowInfo *pResultRowInfo, TSKEY lastKey, int32_t order) {
|
||||
assert(pResultRowInfo->size >= 0 && pResultRowInfo->capacity >= pResultRowInfo->size);
|
||||
if (pResultRowInfo->size <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the result order
|
||||
int32_t resultOrder = (pResultRowInfo->pResult[0]->win.skey < pResultRowInfo->pResult[1]->win.skey)? 1:-1;
|
||||
if (order != resultOrder) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t i = 0;
|
||||
if (order == QUERY_ASC_FORWARD_STEP) {
|
||||
TSKEY ekey = pResultRowInfo->pResult[i]->win.ekey;
|
||||
while (i < pResultRowInfo->size && (ekey < lastKey)) {
|
||||
++i;
|
||||
}
|
||||
} else if (order == QUERY_DESC_FORWARD_STEP) {
|
||||
while (i < pResultRowInfo->size && (pResultRowInfo->pResult[i]->win.skey > lastKey)) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < pResultRowInfo->size) {
|
||||
pResultRowInfo->size = (i + 1);
|
||||
pRow->closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,47 +149,6 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The source window result pos attribution of the source window result does not assign to the destination,
|
||||
* since the attribute of "Pos" is bound to each window result when the window result is created in the
|
||||
* disk-based result buffer.
|
||||
*/
|
||||
void copyResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *dst, const SResultRow *src, int16_t type) {
|
||||
dst->numOfRows = src->numOfRows;
|
||||
|
||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
||||
dst->key = realloc(dst->key, varDataTLen(src->key));
|
||||
varDataCopy(dst->key, src->key);
|
||||
} else {
|
||||
dst->win = src->win;
|
||||
}
|
||||
dst->closed = src->closed;
|
||||
|
||||
int32_t nOutputCols = pRuntimeEnv->pQuery->numOfOutput;
|
||||
|
||||
for (int32_t i = 0; i < nOutputCols; ++i) {
|
||||
SResultRowCellInfo *pDst = getResultCell(pRuntimeEnv, dst, i);
|
||||
SResultRowCellInfo *pSrc = getResultCell(pRuntimeEnv, src, i);
|
||||
|
||||
// char *buf = pDst->interResultBuf;
|
||||
memcpy(pDst, pSrc, sizeof(SResultRowCellInfo) + pRuntimeEnv->pCtx[i].interBufBytes);
|
||||
// pDst->interResultBuf = buf; // restore the allocated buffer
|
||||
|
||||
// copy the result info struct
|
||||
// memcpy(pDst->interResultBuf, pSrc->interResultBuf, pRuntimeEnv->pCtx[i].interBufBytes);
|
||||
|
||||
// copy the output buffer data from src to dst, the position info keep unchanged
|
||||
tFilePage *dstpage = getResBufPage(pRuntimeEnv->pResultBuf, dst->pageId);
|
||||
char * dstBuf = getPosInResultPage(pRuntimeEnv, i, dst, dstpage);
|
||||
|
||||
tFilePage *srcpage = getResBufPage(pRuntimeEnv->pResultBuf, src->pageId);
|
||||
char * srcBuf = getPosInResultPage(pRuntimeEnv, i, (SResultRow *)src, srcpage);
|
||||
size_t s = pRuntimeEnv->pQuery->pExpr1[i].bytes;
|
||||
|
||||
memcpy(dstBuf, srcBuf, s);
|
||||
}
|
||||
}
|
||||
|
||||
SResultRowCellInfo* getResultCell(SQueryRuntimeEnv* pRuntimeEnv, const SResultRow* pRow, int32_t index) {
|
||||
assert(index >= 0 && index < pRuntimeEnv->pQuery->numOfOutput);
|
||||
return (SResultRowCellInfo*)((char*) pRow->pCellInfo + pRuntimeEnv->rowCellInfoOffset[index]);
|
||||
|
@ -383,18 +228,4 @@ void* destroyResultRowPool(SResultRowPool* p) {
|
|||
|
||||
tfree(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t getResultInfoUId(SQueryRuntimeEnv* pRuntimeEnv) {
|
||||
if (!pRuntimeEnv->stableQuery) {
|
||||
return 0; // for simple table query, the uid is always set to be 0;
|
||||
}
|
||||
|
||||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
if (pQuery->interval.interval == 0 || isPointInterpoQuery(pQuery) || pRuntimeEnv->groupbyNormalCol) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
STableId* id = TSDB_TABLEID(pRuntimeEnv->pQuery->current->pTable);
|
||||
return id->uid;
|
||||
}
|
2455
src/query/src/sql.c
2455
src/query/src/sql.c
File diff suppressed because it is too large
Load Diff
|
@ -21,19 +21,19 @@ TEST(testCase, histogram_binary_search) {
|
|||
pHisto->elems[i].val = i;
|
||||
}
|
||||
|
||||
int32_t idx = vnodeHistobinarySearch(pHisto->elems, pHisto->numOfEntries, 1);
|
||||
int32_t idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 1);
|
||||
assert(idx == 1);
|
||||
|
||||
idx = vnodeHistobinarySearch(pHisto->elems, pHisto->numOfEntries, 9);
|
||||
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 9);
|
||||
assert(idx == 9);
|
||||
|
||||
idx = vnodeHistobinarySearch(pHisto->elems, pHisto->numOfEntries, 20);
|
||||
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 20);
|
||||
assert(idx == 10);
|
||||
|
||||
idx = vnodeHistobinarySearch(pHisto->elems, pHisto->numOfEntries, -1);
|
||||
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, -1);
|
||||
assert(idx == 0);
|
||||
|
||||
idx = vnodeHistobinarySearch(pHisto->elems, pHisto->numOfEntries, 3.9);
|
||||
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 3.9);
|
||||
assert(idx == 4);
|
||||
|
||||
free(pHisto);
|
||||
|
|
|
@ -20,10 +20,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RPC_CONN_UDPS 0
|
||||
#define RPC_CONN_UDPC 1
|
||||
#define RPC_CONN_TCPS 2
|
||||
#define RPC_CONN_TCPC 3
|
||||
#define RPC_CONN_TCP 2
|
||||
|
||||
extern int tsRpcOverhead;
|
||||
|
@ -58,6 +54,7 @@ typedef struct {
|
|||
char empty[1]; // reserved
|
||||
uint8_t msgType; // message type
|
||||
int32_t msgLen; // message length including the header iteslf
|
||||
uint32_t msgVer;
|
||||
int32_t code; // code in response message
|
||||
uint8_t content[0]; // message body starts from here
|
||||
} SRpcHead;
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
#include "tlog.h"
|
||||
|
||||
extern int32_t rpcDebugFlag;
|
||||
extern uint32_t tscEmbedded;
|
||||
extern int8_t tscEmbedded;
|
||||
|
||||
#define tFatal(...) { if (rpcDebugFlag & DEBUG_FATAL) { taosPrintLog("RPC FATAL ", tscEmbedded ? 255 : rpcDebugFlag, __VA_ARGS__); }}
|
||||
#define tError(...) { if (rpcDebugFlag & DEBUG_ERROR) { taosPrintLog("RPC ERROR ", tscEmbedded ? 255 : rpcDebugFlag, __VA_ARGS__); }}
|
||||
|
|
|
@ -142,7 +142,6 @@ static int32_t tsRpcNum = 0;
|
|||
#define RPC_CONN_UDPC 1
|
||||
#define RPC_CONN_TCPS 2
|
||||
#define RPC_CONN_TCPC 3
|
||||
#define RPC_CONN_TCP 2
|
||||
|
||||
void *(*taosInitConn[])(uint32_t ip, uint16_t port, char *label, int threads, void *fp, void *shandle) = {
|
||||
taosInitUdpConnection,
|
||||
|
@ -959,6 +958,11 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv, SRpcReqCont
|
|||
terrno = TSDB_CODE_RPC_INVALID_SESSION_ID; return NULL;
|
||||
}
|
||||
|
||||
if (rpcIsReq(pHead->msgType) && htonl(pHead->msgVer) != tsVersion >> 8) {
|
||||
tDebug("%s sid:%d, invalid client version:%x/%x %s", pRpc->label, sid, htonl(pHead->msgVer), tsVersion, taosMsg[pHead->msgType]);
|
||||
terrno = TSDB_CODE_RPC_INVALID_VERSION; return NULL;
|
||||
}
|
||||
|
||||
pConn = rpcGetConnObj(pRpc, sid, pRecv);
|
||||
if (pConn == NULL) {
|
||||
tDebug("%s %p, failed to get connection obj(%s)", pRpc->label, (void *)pHead->ahandle, tstrerror(terrno));
|
||||
|
@ -1212,6 +1216,7 @@ static void rpcSendReqHead(SRpcConn *pConn) {
|
|||
pHead = (SRpcHead *)msg;
|
||||
pHead->version = 1;
|
||||
pHead->msgType = pConn->outType;
|
||||
pHead->msgVer = htonl(tsVersion >> 8);
|
||||
pHead->spi = pConn->spi;
|
||||
pHead->encrypt = 0;
|
||||
pHead->tranId = pConn->outTranId;
|
||||
|
@ -1282,6 +1287,7 @@ static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) {
|
|||
|
||||
// set the message header
|
||||
pHead->version = 1;
|
||||
pHead->msgVer = htonl(tsVersion >> 8);
|
||||
pHead->msgType = msgType;
|
||||
pHead->encrypt = 0;
|
||||
pConn->tranId++;
|
||||
|
|
|
@ -38,7 +38,7 @@ extern "C" {
|
|||
#define SYNC_MAX_FWDS 512
|
||||
#define SYNC_FWD_TIMER 300
|
||||
#define SYNC_ROLE_TIMER 15000 // ms
|
||||
#define SYNC_CHECK_INTERVAL 1 // ms
|
||||
#define SYNC_CHECK_INTERVAL 1000 // ms
|
||||
#define SYNC_WAIT_AFTER_CHOOSE_MASTER 10 // ms
|
||||
|
||||
#define nodeRole pNode->peerInfo[pNode->selfIndex]->role
|
||||
|
@ -86,9 +86,10 @@ typedef struct SsyncPeer {
|
|||
int32_t peerFd; // forward FD
|
||||
int32_t numOfRetrieves; // number of retrieves tried
|
||||
int32_t fileChanged; // a flag to indicate file is changed during retrieving process
|
||||
int32_t refCount;
|
||||
int64_t rid;
|
||||
void * timer;
|
||||
void * pConn;
|
||||
int32_t refCount; // reference count
|
||||
struct SSyncNode *pSyncNode;
|
||||
} SSyncPeer;
|
||||
|
||||
|
@ -98,6 +99,7 @@ typedef struct SSyncNode {
|
|||
int8_t quorum;
|
||||
int8_t selfIndex;
|
||||
uint32_t vgId;
|
||||
int32_t refCount;
|
||||
int64_t rid;
|
||||
SSyncPeer * peerInfo[TAOS_SYNC_MAX_REPLICA + 1]; // extra one for arbitrator
|
||||
SSyncPeer * pMaster;
|
||||
|
@ -121,13 +123,13 @@ extern int32_t tsSyncNum;
|
|||
extern char tsNodeFqdn[TSDB_FQDN_LEN];
|
||||
extern char * syncStatus[];
|
||||
|
||||
void *syncRetrieveData(void *param);
|
||||
void *syncRestoreData(void *param);
|
||||
int32_t syncSaveIntoBuffer(SSyncPeer *pPeer, SWalHead *pHead);
|
||||
void syncRestartConnection(SSyncPeer *pPeer);
|
||||
void syncBroadcastStatus(SSyncNode *pNode);
|
||||
void syncAddPeerRef(SSyncPeer *pPeer);
|
||||
int32_t syncDecPeerRef(SSyncPeer *pPeer);
|
||||
void * syncRetrieveData(void *param);
|
||||
void * syncRestoreData(void *param);
|
||||
int32_t syncSaveIntoBuffer(SSyncPeer *pPeer, SWalHead *pHead);
|
||||
void syncRestartConnection(SSyncPeer *pPeer);
|
||||
void syncBroadcastStatus(SSyncNode *pNode);
|
||||
SSyncPeer *syncAcquirePeer(int64_t rid);
|
||||
void syncReleasePeer(SSyncPeer *pPeer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -25,14 +25,14 @@ typedef struct {
|
|||
uint32_t serverIp;
|
||||
int16_t port;
|
||||
int32_t bufferSize;
|
||||
void (*processBrokenLink)(void *ahandle);
|
||||
int32_t (*processIncomingMsg)(void *ahandle, void *buffer);
|
||||
void (*processBrokenLink)(int64_t handleId);
|
||||
int32_t (*processIncomingMsg)(int64_t handleId, void *buffer);
|
||||
void (*processIncomingConn)(int32_t fd, uint32_t ip);
|
||||
} SPoolInfo;
|
||||
|
||||
void *syncOpenTcpThreadPool(SPoolInfo *pInfo);
|
||||
void syncCloseTcpThreadPool(void *);
|
||||
void *syncAllocateTcpConn(void *, void *ahandle, int32_t connFd);
|
||||
void *syncAllocateTcpConn(void *, int64_t rid, int32_t connFd);
|
||||
void syncFreeTcpConn(void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
static void arbSignalHandler(int32_t signum, siginfo_t *sigInfo, void *context);
|
||||
static void arbProcessIncommingConnection(int32_t connFd, uint32_t sourceIp);
|
||||
static void arbProcessBrokenLink(void *param);
|
||||
static int32_t arbProcessPeerMsg(void *param, void *buffer);
|
||||
static void arbProcessBrokenLink(int64_t rid);
|
||||
static int32_t arbProcessPeerMsg(int64_t rid, void *buffer);
|
||||
static tsem_t tsArbSem;
|
||||
static void * tsArbTcpPool;
|
||||
|
||||
|
@ -138,20 +138,20 @@ static void arbProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) {
|
|||
|
||||
sDebug("%s, arbitrator request is accepted", pNode->id);
|
||||
pNode->nodeFd = connFd;
|
||||
pNode->pConn = syncAllocateTcpConn(tsArbTcpPool, pNode, connFd);
|
||||
pNode->pConn = syncAllocateTcpConn(tsArbTcpPool, (int64_t)pNode, connFd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void arbProcessBrokenLink(void *param) {
|
||||
SNodeConn *pNode = param;
|
||||
static void arbProcessBrokenLink(int64_t rid) {
|
||||
SNodeConn *pNode = (SNodeConn *)rid;
|
||||
|
||||
sDebug("%s, TCP link is broken since %s, close connection", pNode->id, strerror(errno));
|
||||
tfree(pNode);
|
||||
}
|
||||
|
||||
static int32_t arbProcessPeerMsg(void *param, void *buffer) {
|
||||
SNodeConn *pNode = param;
|
||||
static int32_t arbProcessPeerMsg(int64_t rid, void *buffer) {
|
||||
SNodeConn *pNode = (SNodeConn *)rid;
|
||||
SSyncHead head;
|
||||
int32_t bytes = 0;
|
||||
char * cont = (char *)buffer;
|
||||
|
|
|
@ -35,19 +35,21 @@ char tsNodeFqdn[TSDB_FQDN_LEN] = {0};
|
|||
static void * tsTcpPool = NULL;
|
||||
static void * tsSyncTmrCtrl = NULL;
|
||||
static void * tsVgIdHash = NULL;
|
||||
static int32_t tsSyncRefId = -1;
|
||||
static int32_t tsNodeRefId = -1;
|
||||
static int32_t tsPeerRefId = -1;
|
||||
|
||||
// local functions
|
||||
static void syncProcessSyncRequest(char *pMsg, SSyncPeer *pPeer);
|
||||
static void syncRecoverFromMaster(SSyncPeer *pPeer);
|
||||
static void syncCheckPeerConnection(void *param, void *tmrId);
|
||||
static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type, uint16_t tranId);
|
||||
static void syncProcessBrokenLink(void *param);
|
||||
static int32_t syncProcessPeerMsg(void *param, void *buffer);
|
||||
static int32_t syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type, uint16_t tranId);
|
||||
static void syncProcessBrokenLink(int64_t rid);
|
||||
static int32_t syncProcessPeerMsg(int64_t rid, void *buffer);
|
||||
static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp);
|
||||
static void syncRemovePeer(SSyncPeer *pPeer);
|
||||
static void syncAddArbitrator(SSyncNode *pNode);
|
||||
static void syncFreeNode(void *);
|
||||
static void syncFreePeer(void *);
|
||||
static void syncRemoveConfirmedFwdInfo(SSyncNode *pNode);
|
||||
static void syncMonitorFwdInfos(void *param, void *tmrId);
|
||||
static void syncMonitorNodeRole(void *param, void *tmrId);
|
||||
|
@ -55,7 +57,12 @@ static void syncProcessFwdAck(SSyncNode *pNode, SFwdInfo *pFwdInfo, int32_t c
|
|||
static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle);
|
||||
static void syncRestartPeer(SSyncPeer *pPeer);
|
||||
static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle, int32_t qtyp);
|
||||
|
||||
static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo);
|
||||
static void syncStartCheckPeerConn(SSyncPeer *pPeer);
|
||||
static void syncStopCheckPeerConn(SSyncPeer *pPeer);
|
||||
static SSyncNode *syncAcquireNode(int64_t rid);
|
||||
static void syncReleaseNode(SSyncNode *pNode);
|
||||
|
||||
char* syncRole[] = {
|
||||
"offline",
|
||||
|
@ -87,29 +94,34 @@ int32_t syncInit() {
|
|||
tsTcpPool = syncOpenTcpThreadPool(&info);
|
||||
if (tsTcpPool == NULL) {
|
||||
sError("failed to init tcpPool");
|
||||
syncCleanUp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsSyncTmrCtrl = taosTmrInit(1000, 50, 10000, "SYNC");
|
||||
if (tsSyncTmrCtrl == NULL) {
|
||||
sError("failed to init tmrCtrl");
|
||||
syncCloseTcpThreadPool(tsTcpPool);
|
||||
tsTcpPool = NULL;
|
||||
syncCleanUp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsVgIdHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
if (tsVgIdHash == NULL) {
|
||||
sError("failed to init vgIdHash");
|
||||
taosTmrCleanUp(tsSyncTmrCtrl);
|
||||
syncCloseTcpThreadPool(tsTcpPool);
|
||||
tsTcpPool = NULL;
|
||||
tsSyncTmrCtrl = NULL;
|
||||
syncCleanUp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsSyncRefId = taosOpenRef(200, syncFreeNode);
|
||||
if (tsSyncRefId < 0) {
|
||||
tsNodeRefId = taosOpenRef(200, syncFreeNode);
|
||||
if (tsNodeRefId < 0) {
|
||||
sError("failed to init node ref");
|
||||
syncCleanUp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsPeerRefId = taosOpenRef(1000, syncFreePeer);
|
||||
if (tsPeerRefId < 0) {
|
||||
sError("failed to init peer ref");
|
||||
syncCleanUp();
|
||||
return -1;
|
||||
}
|
||||
|
@ -121,12 +133,12 @@ int32_t syncInit() {
|
|||
}
|
||||
|
||||
void syncCleanUp() {
|
||||
if (tsTcpPool) {
|
||||
if (tsTcpPool != NULL) {
|
||||
syncCloseTcpThreadPool(tsTcpPool);
|
||||
tsTcpPool = NULL;
|
||||
}
|
||||
|
||||
if (tsSyncTmrCtrl) {
|
||||
if (tsSyncTmrCtrl != NULL) {
|
||||
taosTmrCleanUp(tsSyncTmrCtrl);
|
||||
tsSyncTmrCtrl = NULL;
|
||||
}
|
||||
|
@ -136,8 +148,15 @@ void syncCleanUp() {
|
|||
tsVgIdHash = NULL;
|
||||
}
|
||||
|
||||
taosCloseRef(tsSyncRefId);
|
||||
tsSyncRefId = -1;
|
||||
if (tsNodeRefId != -1) {
|
||||
taosCloseRef(tsNodeRefId);
|
||||
tsNodeRefId = -1;
|
||||
}
|
||||
|
||||
if (tsPeerRefId != -1) {
|
||||
taosCloseRef(tsPeerRefId);
|
||||
tsPeerRefId = -1;
|
||||
}
|
||||
|
||||
sInfo("sync module is cleaned up");
|
||||
}
|
||||
|
@ -170,7 +189,8 @@ int64_t syncStart(const SSyncInfo *pInfo) {
|
|||
pNode->quorum = pCfg->quorum;
|
||||
if (pNode->quorum > pNode->replica) pNode->quorum = pNode->replica;
|
||||
|
||||
pNode->rid = taosAddRef(tsSyncRefId, pNode);
|
||||
pNode->refCount = 1;
|
||||
pNode->rid = taosAddRef(tsNodeRefId, pNode);
|
||||
if (pNode->rid < 0) {
|
||||
syncFreeNode(pNode);
|
||||
return -1;
|
||||
|
@ -232,13 +252,18 @@ int64_t syncStart(const SSyncInfo *pInfo) {
|
|||
(*pNode->notifyRole)(pNode->vgId, nodeRole);
|
||||
}
|
||||
|
||||
syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb
|
||||
for (int32_t index = 0; index < pNode->replica; ++index) {
|
||||
syncStartCheckPeerConn(pNode->peerInfo[index]);
|
||||
}
|
||||
|
||||
return pNode->rid;
|
||||
}
|
||||
|
||||
void syncStop(int64_t rid) {
|
||||
SSyncPeer *pPeer;
|
||||
|
||||
SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid);
|
||||
SSyncNode *pNode = syncAcquireNode(rid);
|
||||
if (pNode == NULL) return;
|
||||
|
||||
sInfo("vgId:%d, cleanup sync", pNode->vgId);
|
||||
|
@ -259,14 +284,14 @@ void syncStop(int64_t rid) {
|
|||
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
taosRemoveRef(tsSyncRefId, rid);
|
||||
syncReleaseNode(pNode);
|
||||
taosRemoveRef(tsNodeRefId, rid);
|
||||
}
|
||||
|
||||
int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) {
|
||||
int32_t i, j;
|
||||
|
||||
SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid);
|
||||
SSyncNode *pNode = syncAcquireNode(rid);
|
||||
if (pNode == NULL) return TSDB_CODE_SYN_INVALID_CONFIG;
|
||||
|
||||
sInfo("vgId:%d, reconfig, role:%s replica:%d old:%d", pNode->vgId, syncRole[nodeRole], pNewCfg->replica,
|
||||
|
@ -274,6 +299,11 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) {
|
|||
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
|
||||
syncStopCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb
|
||||
for (int32_t index = 0; index < pNode->replica; ++index) {
|
||||
syncStopCheckPeerConn(pNode->peerInfo[index]);
|
||||
}
|
||||
|
||||
for (i = 0; i < pNode->replica; ++i) {
|
||||
for (j = 0; j < pNewCfg->replica; ++j) {
|
||||
if ((strcmp(pNode->peerInfo[i]->fqdn, pNewCfg->nodeInfo[j].nodeFqdn) == 0) &&
|
||||
|
@ -330,28 +360,32 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) {
|
|||
(*pNode->notifyRole)(pNode->vgId, nodeRole);
|
||||
}
|
||||
|
||||
syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb
|
||||
for (int32_t index = 0; index < pNode->replica; ++index) {
|
||||
syncStartCheckPeerConn(pNode->peerInfo[index]);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
sInfo("vgId:%d, %d replicas are configured, quorum:%d", pNode->vgId, pNode->replica, pNode->quorum);
|
||||
syncBroadcastStatus(pNode);
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
syncReleaseNode(pNode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncForwardToPeer(int64_t rid, void *data, void *mhandle, int32_t qtype) {
|
||||
SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid);
|
||||
if (pNode == NULL) return 0;
|
||||
SSyncNode *pNode = syncAcquireNode(rid);
|
||||
if (pNode == NULL) return 0;
|
||||
|
||||
int32_t code = syncForwardToPeerImpl(pNode, data, mhandle, qtype);
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
|
||||
syncReleaseNode(pNode);
|
||||
return code;
|
||||
}
|
||||
|
||||
void syncConfirmForward(int64_t rid, uint64_t version, int32_t code) {
|
||||
SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid);
|
||||
SSyncNode *pNode = syncAcquireNode(rid);
|
||||
if (pNode == NULL) return;
|
||||
|
||||
SSyncPeer *pPeer = pNode->pMaster;
|
||||
|
@ -367,14 +401,14 @@ void syncConfirmForward(int64_t rid, uint64_t version, int32_t code) {
|
|||
}
|
||||
}
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
syncReleaseNode(pNode);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void syncRecover(int64_t rid) {
|
||||
SSyncPeer *pPeer;
|
||||
|
||||
SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid);
|
||||
SSyncNode *pNode = syncAcquireNode(rid);
|
||||
if (pNode == NULL) return;
|
||||
|
||||
// to do: add a few lines to check if recover is OK
|
||||
|
@ -395,12 +429,12 @@ void syncRecover(int64_t rid) {
|
|||
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
syncReleaseNode(pNode);
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t syncGetNodesRole(int64_t rid, SNodesRole *pNodesRole) {
|
||||
SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid);
|
||||
SSyncNode *pNode = syncAcquireNode(rid);
|
||||
if (pNode == NULL) return -1;
|
||||
|
||||
pNodesRole->selfIndex = pNode->selfIndex;
|
||||
|
@ -409,8 +443,7 @@ int32_t syncGetNodesRole(int64_t rid, SNodesRole *pNodesRole) {
|
|||
pNodesRole->role[i] = pNode->peerInfo[i]->role;
|
||||
}
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
|
||||
syncReleaseNode(pNode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -446,24 +479,61 @@ static void syncAddArbitrator(SSyncNode *pNode) {
|
|||
static void syncFreeNode(void *param) {
|
||||
SSyncNode *pNode = param;
|
||||
|
||||
int32_t refCount = atomic_sub_fetch_32(&pNode->refCount, 1);
|
||||
sDebug("vgId:%d, syncnode is freed, refCount:%d", pNode->vgId, refCount);
|
||||
|
||||
pthread_mutex_destroy(&pNode->mutex);
|
||||
tfree(pNode->pRecv);
|
||||
tfree(pNode->pSyncFwds);
|
||||
tfree(pNode);
|
||||
}
|
||||
|
||||
void syncAddPeerRef(SSyncPeer *pPeer) { atomic_add_fetch_32(&pPeer->refCount, 1); }
|
||||
|
||||
int32_t syncDecPeerRef(SSyncPeer *pPeer) {
|
||||
if (atomic_sub_fetch_32(&pPeer->refCount, 1) == 0) {
|
||||
taosReleaseRef(tsSyncRefId, pPeer->pSyncNode->rid);
|
||||
|
||||
sDebug("%s, resource is freed", pPeer->id);
|
||||
tfree(pPeer);
|
||||
return 0;
|
||||
SSyncNode *syncAcquireNode(int64_t rid) {
|
||||
SSyncNode *pNode = taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pNode == NULL) {
|
||||
sDebug("failed to acquire syncnode from refId:%" PRId64, rid);
|
||||
} else {
|
||||
int32_t refCount = atomic_add_fetch_32(&pNode->refCount, 1);
|
||||
sTrace("vgId:%d, acquire syncnode refId:%" PRId64 ", refCount:%d", pNode->vgId, rid, refCount);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void syncReleaseNode(SSyncNode *pNode) {
|
||||
int32_t refCount = atomic_sub_fetch_32(&pNode->refCount, 1);
|
||||
sTrace("vgId:%d, dec syncnode refId:%" PRId64 " refCount:%d", pNode->vgId, pNode->rid, refCount);
|
||||
|
||||
taosReleaseRef(tsNodeRefId, pNode->rid);
|
||||
}
|
||||
|
||||
static void syncFreePeer(void *param) {
|
||||
SSyncPeer *pPeer = param;
|
||||
|
||||
int32_t refCount = atomic_sub_fetch_32(&pPeer->refCount, 1);
|
||||
sDebug("%s, peer is freed, refCount:%d", pPeer->id, refCount);
|
||||
|
||||
syncReleaseNode(pPeer->pSyncNode);
|
||||
tfree(pPeer);
|
||||
}
|
||||
|
||||
SSyncPeer *syncAcquirePeer(int64_t rid) {
|
||||
SSyncPeer *pPeer = taosAcquireRef(tsPeerRefId, rid);
|
||||
if (pPeer == NULL) {
|
||||
sDebug("failed to acquire peer from refId:%" PRId64, rid);
|
||||
} else {
|
||||
int32_t refCount = atomic_add_fetch_32(&pPeer->refCount, 1);
|
||||
sTrace("%s, acquire peer refId:%" PRId64 ", refCount:%d", pPeer->id, rid, refCount);
|
||||
}
|
||||
|
||||
return pPeer;
|
||||
}
|
||||
|
||||
void syncReleasePeer(SSyncPeer *pPeer) {
|
||||
int32_t refCount = atomic_sub_fetch_32(&pPeer->refCount, 1);
|
||||
sTrace("%s, dec peer refId:%" PRId64 ", refCount:%d", pPeer->id, pPeer->rid, refCount);
|
||||
|
||||
taosReleaseRef(tsPeerRefId, pPeer->rid);
|
||||
}
|
||||
|
||||
static void syncClosePeerConn(SSyncPeer *pPeer) {
|
||||
|
@ -473,7 +543,8 @@ static void syncClosePeerConn(SSyncPeer *pPeer) {
|
|||
taosClose(pPeer->syncFd);
|
||||
if (pPeer->peerFd >= 0) {
|
||||
pPeer->peerFd = -1;
|
||||
syncFreeTcpConn(pPeer->pConn);
|
||||
void *pConn = pPeer->pConn;
|
||||
if (pConn != NULL) syncFreeTcpConn(pPeer->pConn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -482,7 +553,28 @@ static void syncRemovePeer(SSyncPeer *pPeer) {
|
|||
|
||||
pPeer->ip = 0;
|
||||
syncClosePeerConn(pPeer);
|
||||
syncDecPeerRef(pPeer);
|
||||
//taosRemoveRef(tsPeerRefId, pPeer->rid);
|
||||
syncReleasePeer(pPeer);
|
||||
}
|
||||
|
||||
static void syncStartCheckPeerConn(SSyncPeer *pPeer) {
|
||||
if (pPeer == NULL) return;
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
|
||||
int32_t ret = strcmp(pPeer->fqdn, tsNodeFqdn);
|
||||
if (pPeer->nodeId == 0 || (ret > 0) || (ret == 0 && pPeer->port > tsSyncPort)) {
|
||||
int32_t checkMs = 100 + (pNode->vgId * 10) % 100;
|
||||
if (pNode->vgId > 1) checkMs = tsStatusInterval * 1000 + checkMs;
|
||||
sDebug("%s, check peer connection after %d ms", pPeer->id, checkMs);
|
||||
taosTmrReset(syncCheckPeerConnection, checkMs, (void *)pPeer->rid, tsSyncTmrCtrl, &pPeer->timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void syncStopCheckPeerConn(SSyncPeer *pPeer) {
|
||||
if (pPeer == NULL) return;
|
||||
|
||||
taosTmrStopA(&pPeer->timer);
|
||||
sDebug("%s, stop check peer connection", pPeer->id);
|
||||
}
|
||||
|
||||
static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) {
|
||||
|
@ -508,17 +600,11 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) {
|
|||
pPeer->role = TAOS_SYNC_ROLE_OFFLINE;
|
||||
pPeer->pSyncNode = pNode;
|
||||
pPeer->refCount = 1;
|
||||
pPeer->rid = taosAddRef(tsPeerRefId, pPeer);
|
||||
|
||||
sInfo("%s, it is configured, ep:%s:%u", pPeer->id, pPeer->fqdn, pPeer->port);
|
||||
int32_t ret = strcmp(pPeer->fqdn, tsNodeFqdn);
|
||||
if (pPeer->nodeId == 0 || (ret > 0) || (ret == 0 && pPeer->port > tsSyncPort)) {
|
||||
int32_t checkMs = 100 + (pNode->vgId * 10) % 100;
|
||||
if (pNode->vgId > 1) checkMs = tsStatusInterval * 1000 + checkMs;
|
||||
sDebug("%s, check peer connection after %d ms", pPeer->id, checkMs);
|
||||
taosTmrReset(syncCheckPeerConnection, checkMs, pPeer, tsSyncTmrCtrl, &pPeer->timer);
|
||||
}
|
||||
sInfo("%s, %p it is configured, ep:%s:%u rid:%" PRId64, pPeer->id, pPeer, pPeer->fqdn, pPeer->port, pPeer->rid);
|
||||
|
||||
taosAcquireRef(tsSyncRefId, pNode->rid);
|
||||
(void)syncAcquireNode(pNode->rid);
|
||||
return pPeer;
|
||||
}
|
||||
|
||||
|
@ -560,6 +646,9 @@ static void syncChooseMaster(SSyncNode *pNode) {
|
|||
index = i;
|
||||
}
|
||||
}
|
||||
sDebug("vgId:%d, master:%s may be choosed, index:%d", pNode->vgId, pNode->peerInfo[index]->id, index);
|
||||
} else {
|
||||
sDebug("vgId:%d, no master election since onlineNum:%d replica:%d", pNode->vgId, onlineNum, pNode->replica);
|
||||
}
|
||||
|
||||
// add arbitrator connection
|
||||
|
@ -580,6 +669,11 @@ static void syncChooseMaster(SSyncNode *pNode) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
sDebug("vgId:%d, master:%s may be choosed, index:%d onlineNum(arb):%d replica:%d", pNode->vgId,
|
||||
pNode->peerInfo[index]->id, index, onlineNum, replica);
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
|
@ -621,9 +715,13 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) {
|
|||
|
||||
if (onlineNum <= replica * 0.5) {
|
||||
if (nodeRole != TAOS_SYNC_ROLE_UNSYNCED) {
|
||||
nodeRole = TAOS_SYNC_ROLE_UNSYNCED;
|
||||
if (nodeRole == TAOS_SYNC_ROLE_MASTER && onlineNum == replica * 0.5 && onlineNum >= 1) {
|
||||
sInfo("vgId:%d, self keep work as master, online:%d replica:%d", pNode->vgId, onlineNum, replica);
|
||||
} else {
|
||||
nodeRole = TAOS_SYNC_ROLE_UNSYNCED;
|
||||
sInfo("vgId:%d, self change to unsynced state, online:%d replica:%d", pNode->vgId, onlineNum, replica);
|
||||
}
|
||||
(*pNode->notifyRole)(pNode->vgId, nodeRole);
|
||||
sInfo("vgId:%d, self change to unsynced state, online:%d replica:%d", pNode->vgId, onlineNum, replica);
|
||||
}
|
||||
} else {
|
||||
for (int32_t index = 0; index < pNode->replica; ++index) {
|
||||
|
@ -678,7 +776,7 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t new
|
|||
if (pMaster) {
|
||||
// master is there
|
||||
pNode->pMaster = pMaster;
|
||||
sDebug("%s, it is the master, sver:%" PRIu64, pMaster->id, pMaster->version);
|
||||
sDebug("%s, it is the master, replica:%d sver:%" PRIu64, pMaster->id, pNode->replica, pMaster->version);
|
||||
|
||||
if (syncValidateMaster(pPeer) < 0) return;
|
||||
|
||||
|
@ -711,10 +809,10 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t new
|
|||
}
|
||||
|
||||
if (consistent) {
|
||||
sDebug("vgId:%d, choose master", pNode->vgId);
|
||||
sDebug("vgId:%d, choose master, replica:%d", pNode->vgId, pNode->replica);
|
||||
syncChooseMaster(pNode);
|
||||
} else {
|
||||
sDebug("vgId:%d, cannot choose master since roles inequality", pNode->vgId);
|
||||
sDebug("vgId:%d, cannot choose master since roles inequality, replica:%d", pNode->vgId, pNode->replica);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -743,7 +841,7 @@ static void syncRestartPeer(SSyncPeer *pPeer) {
|
|||
int32_t ret = strcmp(pPeer->fqdn, tsNodeFqdn);
|
||||
if (ret > 0 || (ret == 0 && pPeer->port > tsSyncPort)) {
|
||||
sDebug("%s, check peer connection in 1000 ms", pPeer->id);
|
||||
taosTmrReset(syncCheckPeerConnection, SYNC_CHECK_INTERVAL, pPeer, tsSyncTmrCtrl, &pPeer->timer);
|
||||
taosTmrReset(syncCheckPeerConnection, SYNC_CHECK_INTERVAL, (void *)pPeer->rid, tsSyncTmrCtrl, &pPeer->timer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -772,25 +870,30 @@ static void syncProcessSyncRequest(char *msg, SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
// start a new thread to retrieve the data
|
||||
syncAddPeerRef(pPeer);
|
||||
(void)syncAcquirePeer(pPeer->rid);
|
||||
|
||||
pthread_attr_t thattr;
|
||||
pthread_t thread;
|
||||
pthread_attr_init(&thattr);
|
||||
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED);
|
||||
int32_t ret = pthread_create(&thread, &thattr, syncRetrieveData, pPeer);
|
||||
int32_t ret = pthread_create(&thread, &thattr, syncRetrieveData, (void *)pPeer->rid);
|
||||
pthread_attr_destroy(&thattr);
|
||||
|
||||
if (ret != 0) {
|
||||
sError("%s, failed to create sync thread since %s", pPeer->id, strerror(errno));
|
||||
syncDecPeerRef(pPeer);
|
||||
} else {
|
||||
pPeer->sstatus = TAOS_SYNC_STATUS_START;
|
||||
sDebug("%s, thread is created to retrieve data, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
}
|
||||
|
||||
syncReleasePeer(pPeer);
|
||||
}
|
||||
|
||||
static void syncNotStarted(void *param, void *tmrId) {
|
||||
SSyncPeer *pPeer = param;
|
||||
int64_t rid = (int64_t)param;
|
||||
SSyncPeer *pPeer = syncAcquirePeer(rid);
|
||||
if (pPeer == NULL) return;
|
||||
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
|
@ -799,15 +902,22 @@ static void syncNotStarted(void *param, void *tmrId) {
|
|||
sInfo("%s, sync conn is still not up, restart and set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
syncRestartConnection(pPeer);
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
syncReleasePeer(pPeer);
|
||||
}
|
||||
|
||||
static void syncTryRecoverFromMaster(void *param, void *tmrId) {
|
||||
SSyncPeer *pPeer = param;
|
||||
int64_t rid = (int64_t)param;
|
||||
SSyncPeer *pPeer = syncAcquirePeer(rid);
|
||||
if (pPeer == NULL) return;
|
||||
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
syncRecoverFromMaster(pPeer);
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
syncReleasePeer(pPeer);
|
||||
}
|
||||
|
||||
static void syncRecoverFromMaster(SSyncPeer *pPeer) {
|
||||
|
@ -823,7 +933,7 @@ static void syncRecoverFromMaster(SSyncPeer *pPeer) {
|
|||
// Ensure the sync of mnode not interrupted
|
||||
if (pNode->vgId != 1 && tsSyncNum >= SYNC_MAX_NUM) {
|
||||
sInfo("%s, %d syncs are in process, try later", pPeer->id, tsSyncNum);
|
||||
taosTmrReset(syncTryRecoverFromMaster, 500 + (pNode->vgId * 10) % 200, pPeer, tsSyncTmrCtrl, &pPeer->timer);
|
||||
taosTmrReset(syncTryRecoverFromMaster, 500 + (pNode->vgId * 10) % 200, (void *)pPeer->rid, tsSyncTmrCtrl, &pPeer->timer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -832,7 +942,7 @@ static void syncRecoverFromMaster(SSyncPeer *pPeer) {
|
|||
SSyncMsg msg;
|
||||
syncBuildSyncReqMsg(&msg, pNode->vgId);
|
||||
|
||||
taosTmrReset(syncNotStarted, SYNC_CHECK_INTERVAL, pPeer, tsSyncTmrCtrl, &pPeer->timer);
|
||||
taosTmrReset(syncNotStarted, SYNC_CHECK_INTERVAL, (void *)pPeer->rid, tsSyncTmrCtrl, &pPeer->timer);
|
||||
|
||||
if (taosWriteMsg(pPeer->peerFd, &msg, sizeof(SSyncMsg)) != sizeof(SSyncMsg)) {
|
||||
sError("%s, failed to send sync-req to peer", pPeer->id);
|
||||
|
@ -920,8 +1030,10 @@ static int32_t syncReadPeerMsg(SSyncPeer *pPeer, SSyncHead *pHead) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t syncProcessPeerMsg(void *param, void *buffer) {
|
||||
SSyncPeer *pPeer = param;
|
||||
static int32_t syncProcessPeerMsg(int64_t rid, void *buffer) {
|
||||
SSyncPeer *pPeer = syncAcquirePeer(rid);
|
||||
if (pPeer == NULL) return -1;
|
||||
|
||||
SSyncHead *pHead = buffer;
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
|
||||
|
@ -942,12 +1054,17 @@ static int32_t syncProcessPeerMsg(void *param, void *buffer) {
|
|||
}
|
||||
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
syncReleasePeer(pPeer);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type, uint16_t tranId) {
|
||||
if (pPeer->peerFd < 0 || pPeer->ip == 0) return;
|
||||
static int32_t syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type, uint16_t tranId) {
|
||||
if (pPeer->peerFd < 0 || pPeer->ip == 0) {
|
||||
sDebug("%s, failed to send status msg, restart fd:%d", pPeer->id, pPeer->peerFd);
|
||||
syncRestartConnection(pPeer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSyncNode * pNode = pPeer->pSyncNode;
|
||||
SPeersStatus msg;
|
||||
|
@ -970,9 +1087,11 @@ static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type
|
|||
sDebug("%s, status is sent, self:%s:%s:%" PRIu64 ", peer:%s:%s:%" PRIu64 ", ack:%d tranId:%u type:%s pfd:%d",
|
||||
pPeer->id, syncRole[nodeRole], syncStatus[nodeSStatus], nodeVersion, syncRole[pPeer->role],
|
||||
syncStatus[pPeer->sstatus], pPeer->version, ack, tranId, statusType[type], pPeer->peerFd);
|
||||
return 0;
|
||||
} else {
|
||||
sDebug("%s, failed to send status msg, restart", pPeer->id);
|
||||
syncRestartConnection(pPeer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -989,7 +1108,7 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) {
|
|||
int32_t connFd = taosOpenTcpClientSocket(pPeer->ip, pPeer->port, 0);
|
||||
if (connFd < 0) {
|
||||
sDebug("%s, failed to open tcp socket since %s", pPeer->id, strerror(errno));
|
||||
taosTmrReset(syncCheckPeerConnection, SYNC_CHECK_INTERVAL, pPeer, tsSyncTmrCtrl, &pPeer->timer);
|
||||
taosTmrReset(syncCheckPeerConnection, SYNC_CHECK_INTERVAL, (void *)pPeer->rid, tsSyncTmrCtrl, &pPeer->timer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1000,17 +1119,19 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) {
|
|||
sDebug("%s, connection to peer server is setup, pfd:%d sfd:%d tranId:%u", pPeer->id, connFd, pPeer->syncFd, msg.tranId);
|
||||
pPeer->peerFd = connFd;
|
||||
pPeer->role = TAOS_SYNC_ROLE_UNSYNCED;
|
||||
pPeer->pConn = syncAllocateTcpConn(tsTcpPool, pPeer, connFd);
|
||||
syncAddPeerRef(pPeer);
|
||||
pPeer->pConn = syncAllocateTcpConn(tsTcpPool, pPeer->rid, connFd);
|
||||
} else {
|
||||
sDebug("%s, failed to setup peer connection to server since %s, try later", pPeer->id, strerror(errno));
|
||||
taosClose(connFd);
|
||||
taosTmrReset(syncCheckPeerConnection, SYNC_CHECK_INTERVAL, pPeer, tsSyncTmrCtrl, &pPeer->timer);
|
||||
taosTmrReset(syncCheckPeerConnection, SYNC_CHECK_INTERVAL, (void *)pPeer->rid, tsSyncTmrCtrl, &pPeer->timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void syncCheckPeerConnection(void *param, void *tmrId) {
|
||||
SSyncPeer *pPeer = param;
|
||||
int64_t rid = (int64_t)param;
|
||||
SSyncPeer *pPeer = syncAcquirePeer(rid);
|
||||
if (pPeer == NULL) return;
|
||||
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
|
@ -1019,6 +1140,8 @@ static void syncCheckPeerConnection(void *param, void *tmrId) {
|
|||
syncSetupPeerConnection(pPeer);
|
||||
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
syncReleasePeer(pPeer);
|
||||
}
|
||||
|
||||
static void syncCreateRestoreDataThread(SSyncPeer *pPeer) {
|
||||
|
@ -1029,8 +1152,9 @@ static void syncCreateRestoreDataThread(SSyncPeer *pPeer) {
|
|||
pthread_attr_init(&thattr);
|
||||
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
syncAddPeerRef(pPeer);
|
||||
int32_t ret = pthread_create(&(thread), &thattr, (void *)syncRestoreData, pPeer);
|
||||
(void)syncAcquirePeer(pPeer->rid);
|
||||
|
||||
int32_t ret = pthread_create(&(thread), &thattr, (void *)syncRestoreData, (void *)pPeer->rid);
|
||||
pthread_attr_destroy(&thattr);
|
||||
|
||||
if (ret < 0) {
|
||||
|
@ -1038,10 +1162,11 @@ static void syncCreateRestoreDataThread(SSyncPeer *pPeer) {
|
|||
nodeSStatus = TAOS_SYNC_STATUS_INIT;
|
||||
sError("%s, failed to create sync thread, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
|
||||
taosClose(pPeer->syncFd);
|
||||
syncDecPeerRef(pPeer);
|
||||
} else {
|
||||
sInfo("%s, sync connection is up", pPeer->id);
|
||||
}
|
||||
|
||||
syncReleasePeer(pPeer);
|
||||
}
|
||||
|
||||
static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) {
|
||||
|
@ -1073,7 +1198,7 @@ static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) {
|
|||
return;
|
||||
}
|
||||
|
||||
sDebug("vgId:%d, sync msg is received, tranId:%u", vgId, msg.tranId);
|
||||
sDebug("vgId:%d, sync connection is incomming, tranId:%u", vgId, msg.tranId);
|
||||
|
||||
SSyncNode *pNode = *ppNode;
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
|
@ -1101,8 +1226,7 @@ static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) {
|
|||
sDebug("%s, TCP connection is up, pfd:%d sfd:%d, old pfd:%d", pPeer->id, connFd, pPeer->syncFd, pPeer->peerFd);
|
||||
syncClosePeerConn(pPeer);
|
||||
pPeer->peerFd = connFd;
|
||||
pPeer->pConn = syncAllocateTcpConn(tsTcpPool, pPeer, connFd);
|
||||
syncAddPeerRef(pPeer);
|
||||
pPeer->pConn = syncAllocateTcpConn(tsTcpPool, pPeer->rid, connFd);
|
||||
sDebug("%s, ready to exchange data", pPeer->id);
|
||||
syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_EXCHANGE_DATA, syncGenTranId());
|
||||
}
|
||||
|
@ -1111,23 +1235,21 @@ static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) {
|
|||
pthread_mutex_unlock(&pNode->mutex);
|
||||
}
|
||||
|
||||
static void syncProcessBrokenLink(void *param) {
|
||||
if (param == NULL) return; // the connection for arbitrator
|
||||
SSyncPeer *pPeer = param;
|
||||
static void syncProcessBrokenLink(int64_t rid) {
|
||||
SSyncPeer *pPeer = syncAcquirePeer(rid);
|
||||
if (pPeer == NULL) return;
|
||||
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
|
||||
if (taosAcquireRef(tsSyncRefId, pNode->rid) == NULL) return;
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
|
||||
sDebug("%s, TCP link is broken since %s, pfd:%d sfd:%d", pPeer->id, strerror(errno), pPeer->peerFd, pPeer->syncFd);
|
||||
pPeer->peerFd = -1;
|
||||
|
||||
if (syncDecPeerRef(pPeer) != 0) {
|
||||
syncRestartConnection(pPeer);
|
||||
}
|
||||
|
||||
syncRestartConnection(pPeer);
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
taosReleaseRef(tsSyncRefId, pNode->rid);
|
||||
|
||||
syncReleasePeer(pPeer);
|
||||
}
|
||||
|
||||
static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle) {
|
||||
|
@ -1198,7 +1320,7 @@ static void syncProcessFwdAck(SSyncNode *pNode, SFwdInfo *pFwdInfo, int32_t code
|
|||
|
||||
static void syncMonitorNodeRole(void *param, void *tmrId) {
|
||||
int64_t rid = (int64_t)param;
|
||||
SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid);
|
||||
SSyncNode *pNode = syncAcquireNode(rid);
|
||||
if (pNode == NULL) return;
|
||||
|
||||
for (int32_t index = 0; index < pNode->replica; index++) {
|
||||
|
@ -1215,12 +1337,12 @@ static void syncMonitorNodeRole(void *param, void *tmrId) {
|
|||
}
|
||||
|
||||
pNode->pRoleTimer = taosTmrStart(syncMonitorNodeRole, SYNC_ROLE_TIMER, (void *)pNode->rid, tsSyncTmrCtrl);
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
syncReleaseNode(pNode);
|
||||
}
|
||||
|
||||
static void syncMonitorFwdInfos(void *param, void *tmrId) {
|
||||
int64_t rid = (int64_t)param;
|
||||
SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid);
|
||||
SSyncNode *pNode = syncAcquireNode(rid);
|
||||
if (pNode == NULL) return;
|
||||
|
||||
SSyncFwds *pSyncFwds = pNode->pSyncFwds;
|
||||
|
@ -1246,7 +1368,7 @@ static void syncMonitorFwdInfos(void *param, void *tmrId) {
|
|||
pNode->pFwdTimer = taosTmrStart(syncMonitorFwdInfos, SYNC_FWD_TIMER, (void *)pNode->rid, tsSyncTmrCtrl);
|
||||
}
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
syncReleaseNode(pNode);
|
||||
}
|
||||
|
||||
static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle, int32_t qtype) {
|
||||
|
|
|
@ -90,15 +90,18 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
|||
break;
|
||||
}
|
||||
|
||||
sDebug("%s, file:%s info is received from master, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%d", pPeer->id,
|
||||
minfo.name, minfo.index, minfo.size, minfo.fversion, minfo.magic);
|
||||
|
||||
// remove extra files on slave between the current and last index
|
||||
syncRemoveExtraFile(pPeer, pindex + 1, minfo.index - 1);
|
||||
pindex = minfo.index;
|
||||
|
||||
// check the file info
|
||||
sinfo = minfo;
|
||||
sDebug("%s, get file:%s info size:%" PRId64, pPeer->id, minfo.name, minfo.size);
|
||||
sinfo.magic = (*pNode->getFileInfo)(pNode->vgId, sinfo.name, &sinfo.index, TAOS_SYNC_MAX_INDEX, &sinfo.size,
|
||||
&sinfo.fversion);
|
||||
sinfo.magic = (*pNode->getFileInfo)(pNode->vgId, sinfo.name, &sinfo.index, TAOS_SYNC_MAX_INDEX, &sinfo.size, &sinfo.fversion);
|
||||
sDebug("%s, local file:%s info, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%d", pPeer->id, sinfo.name,
|
||||
sinfo.index, sinfo.size, sinfo.fversion, sinfo.magic);
|
||||
|
||||
// if file not there or magic is not the same, file shall be synced
|
||||
memset(&fileAck, 0, sizeof(SFileAck));
|
||||
|
@ -116,6 +119,8 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
|||
if (fileAck.sync == 0) {
|
||||
sDebug("%s, %s is the same", pPeer->id, minfo.name);
|
||||
continue;
|
||||
} else {
|
||||
sDebug("%s, %s will be received, size:%" PRId64, pPeer->id, minfo.name, minfo.size);
|
||||
}
|
||||
|
||||
// if sync is required, open file, receive from master, and write to file
|
||||
|
@ -155,7 +160,7 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t syncRestoreWal(SSyncPeer *pPeer) {
|
||||
static int32_t syncRestoreWal(SSyncPeer *pPeer, uint64_t *wver) {
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
int32_t ret, code = -1;
|
||||
uint64_t lastVer = 0;
|
||||
|
@ -198,6 +203,7 @@ static int32_t syncRestoreWal(SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
free(pHead);
|
||||
*wver = lastVer;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -321,12 +327,19 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) {
|
|||
|
||||
nodeVersion = fversion;
|
||||
|
||||
sInfo("%s, start to restore wal", pPeer->id);
|
||||
if (syncRestoreWal(pPeer) < 0) {
|
||||
sError("%s, failed to restore wal", pPeer->id);
|
||||
sInfo("%s, start to restore wal, fver:%" PRIu64, pPeer->id, nodeVersion);
|
||||
uint64_t wver = 0;
|
||||
code = syncRestoreWal(pPeer, &wver); // lastwar
|
||||
if (code < 0) {
|
||||
sError("%s, failed to restore wal, code:%d", pPeer->id, code);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wver != 0) {
|
||||
nodeVersion = wver;
|
||||
sDebug("%s, restore wal finished, set sver:%" PRIu64, pPeer->id, nodeVersion);
|
||||
}
|
||||
|
||||
nodeSStatus = TAOS_SYNC_STATUS_CACHE;
|
||||
sInfo("%s, start to insert buffered points, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
|
||||
if (syncProcessBufferedFwd(pPeer) < 0) {
|
||||
|
@ -338,7 +351,10 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
void *syncRestoreData(void *param) {
|
||||
SSyncPeer *pPeer = param;
|
||||
int64_t rid = (int64_t)param;
|
||||
SSyncPeer *pPeer = syncAcquirePeer(rid);
|
||||
if (pPeer == NULL) return NULL;
|
||||
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
|
||||
taosBlockSIGPIPE();
|
||||
|
@ -369,7 +385,7 @@ void *syncRestoreData(void *param) {
|
|||
taosClose(pPeer->syncFd);
|
||||
syncCloseRecvBuffer(pNode);
|
||||
__sync_fetch_and_sub(&tsSyncNum, 1);
|
||||
syncDecPeerRef(pPeer);
|
||||
syncReleasePeer(pPeer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,8 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
|||
fileInfo.magic = (*pNode->getFileInfo)(pNode->vgId, fileInfo.name, &fileInfo.index, TAOS_SYNC_MAX_INDEX,
|
||||
&fileInfo.size, &fileInfo.fversion);
|
||||
syncBuildFileInfo(&fileInfo, pNode->vgId);
|
||||
sDebug("%s, file:%s info is sent, size:%" PRId64, pPeer->id, fileInfo.name, fileInfo.size);
|
||||
sDebug("%s, file:%s info is sent, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%d", pPeer->id, fileInfo.name,
|
||||
fileInfo.index, fileInfo.size, fileInfo.fversion, fileInfo.magic);
|
||||
|
||||
// send the file info
|
||||
int32_t ret = taosWriteMsg(pPeer->syncFd, &(fileInfo), sizeof(SFileInfo));
|
||||
|
@ -144,6 +145,8 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
|||
fileInfo.index++;
|
||||
sDebug("%s, %s is the same", pPeer->id, fileInfo.name);
|
||||
continue;
|
||||
} else {
|
||||
sDebug("%s, %s will be sent", pPeer->id, fileInfo.name);
|
||||
}
|
||||
|
||||
// get the full path to file
|
||||
|
@ -461,7 +464,10 @@ static int32_t syncRetrieveDataStepByStep(SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
void *syncRetrieveData(void *param) {
|
||||
SSyncPeer *pPeer = (SSyncPeer *)param;
|
||||
int64_t rid = (int64_t)param;
|
||||
SSyncPeer *pPeer = syncAcquirePeer(rid);
|
||||
if (pPeer == NULL) return NULL;
|
||||
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
taosBlockSIGPIPE();
|
||||
|
||||
|
@ -490,7 +496,7 @@ void *syncRetrieveData(void *param) {
|
|||
|
||||
pPeer->fileChanged = 0;
|
||||
taosClose(pPeer->syncFd);
|
||||
syncDecPeerRef(pPeer);
|
||||
syncReleasePeer(pPeer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ typedef struct SPoolObj {
|
|||
|
||||
typedef struct {
|
||||
SThreadObj *pThread;
|
||||
void * ahandle;
|
||||
int64_t handleId;
|
||||
int32_t fd;
|
||||
int32_t closedByApp;
|
||||
} SConnObj;
|
||||
|
@ -112,7 +112,7 @@ void syncCloseTcpThreadPool(void *param) {
|
|||
tfree(pPool);
|
||||
}
|
||||
|
||||
void *syncAllocateTcpConn(void *param, void *pPeer, int32_t connFd) {
|
||||
void *syncAllocateTcpConn(void *param, int64_t rid, int32_t connFd) {
|
||||
struct epoll_event event;
|
||||
SPoolObj *pPool = param;
|
||||
|
||||
|
@ -130,7 +130,7 @@ void *syncAllocateTcpConn(void *param, void *pPeer, int32_t connFd) {
|
|||
|
||||
pConn->fd = connFd;
|
||||
pConn->pThread = pThread;
|
||||
pConn->ahandle = pPeer;
|
||||
pConn->handleId = rid;
|
||||
pConn->closedByApp = 0;
|
||||
|
||||
event.events = EPOLLIN | EPOLLRDHUP;
|
||||
|
@ -164,7 +164,7 @@ static void taosProcessBrokenLink(SConnObj *pConn) {
|
|||
SPoolInfo * pInfo = &pPool->info;
|
||||
|
||||
if (pConn->closedByApp == 0) shutdown(pConn->fd, SHUT_WR);
|
||||
(*pInfo->processBrokenLink)(pConn->ahandle);
|
||||
(*pInfo->processBrokenLink)(pConn->handleId);
|
||||
|
||||
pThread->numOfFds--;
|
||||
epoll_ctl(pThread->pollFd, EPOLL_CTL_DEL, pConn->fd, NULL);
|
||||
|
@ -221,7 +221,7 @@ static void *syncProcessTcpData(void *param) {
|
|||
}
|
||||
|
||||
if (pConn->closedByApp == 0) {
|
||||
if ((*pInfo->processIncomingMsg)(pConn->ahandle, buffer) < 0) {
|
||||
if ((*pInfo->processIncomingMsg)(pConn->handleId, buffer) < 0) {
|
||||
syncFreeTcpConn(pConn);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -31,19 +31,19 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int tsdbDebugFlag;
|
||||
extern int32_t tsdbDebugFlag;
|
||||
|
||||
#define tsdbFatal(...) { if (tsdbDebugFlag & DEBUG_FATAL) { taosPrintLog("TDB FATAL ", 255, __VA_ARGS__); }}
|
||||
#define tsdbError(...) { if (tsdbDebugFlag & DEBUG_ERROR) { taosPrintLog("TDB ERROR ", 255, __VA_ARGS__); }}
|
||||
#define tsdbWarn(...) { if (tsdbDebugFlag & DEBUG_WARN) { taosPrintLog("TDB WARN ", 255, __VA_ARGS__); }}
|
||||
#define tsdbInfo(...) { if (tsdbDebugFlag & DEBUG_INFO) { taosPrintLog("TDB ", 255, __VA_ARGS__); }}
|
||||
#define tsdbDebug(...) { if (tsdbDebugFlag & DEBUG_DEBUG) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }}
|
||||
#define tsdbTrace(...) { if (tsdbDebugFlag & DEBUG_TRACE) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }}
|
||||
#define tsdbFatal(...) do { if (tsdbDebugFlag & DEBUG_FATAL) { taosPrintLog("TDB FATAL ", 255, __VA_ARGS__); }} while(0)
|
||||
#define tsdbError(...) do { if (tsdbDebugFlag & DEBUG_ERROR) { taosPrintLog("TDB ERROR ", 255, __VA_ARGS__); }} while(0)
|
||||
#define tsdbWarn(...) do { if (tsdbDebugFlag & DEBUG_WARN) { taosPrintLog("TDB WARN ", 255, __VA_ARGS__); }} while(0)
|
||||
#define tsdbInfo(...) do { if (tsdbDebugFlag & DEBUG_INFO) { taosPrintLog("TDB ", 255, __VA_ARGS__); }} while(0)
|
||||
#define tsdbDebug(...) do { if (tsdbDebugFlag & DEBUG_DEBUG) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tsdbTrace(...) do { if (tsdbDebugFlag & DEBUG_TRACE) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }} while(0)
|
||||
|
||||
#define TSDB_MAX_TABLE_SCHEMAS 16
|
||||
#define TSDB_FILE_HEAD_SIZE 512
|
||||
#define TSDB_FILE_DELIMITER 0xF00AFA0F
|
||||
#define TSDB_FILE_INIT_MAGIC 0xFFFFFFFF
|
||||
#define TSDB_FILE_HEAD_SIZE 512
|
||||
#define TSDB_FILE_DELIMITER 0xF00AFA0F
|
||||
#define TSDB_FILE_INIT_MAGIC 0xFFFFFFFF
|
||||
|
||||
#define TAOS_IN_RANGE(key, keyMin, keyLast) (((key) >= (keyMin)) && ((key) <= (keyMax)))
|
||||
|
||||
|
@ -66,7 +66,8 @@ typedef struct STable {
|
|||
SSkipList* pIndex; // For TSDB_SUPER_TABLE, it is the skiplist index
|
||||
void* eventHandler; // TODO
|
||||
void* streamHandler; // TODO
|
||||
TSKEY lastKey; // lastkey inserted in this table, initialized as 0, TODO: make a structure
|
||||
TSKEY lastKey;
|
||||
SDataRow lastRow;
|
||||
char* sql;
|
||||
void* cqhandle;
|
||||
SRWLatch latch; // TODO: implementa latch functions
|
||||
|
@ -360,8 +361,11 @@ typedef struct {
|
|||
#define TABLE_UID(t) (t)->tableId.uid
|
||||
#define TABLE_TID(t) (t)->tableId.tid
|
||||
#define TABLE_SUID(t) (t)->suid
|
||||
#define TABLE_LASTKEY(t) (t)->lastKey
|
||||
#define TSDB_META_FILE_MAGIC(m) KVSTORE_MAGIC((m)->pStore)
|
||||
#define TSDB_RLOCK_TABLE(t) taosRLockLatch(&((t)->latch))
|
||||
#define TSDB_RUNLOCK_TABLE(t) taosRUnLockLatch(&((t)->latch))
|
||||
#define TSDB_WLOCK_TABLE(t) taosWLockLatch(&((t)->latch))
|
||||
#define TSDB_WUNLOCK_TABLE(t) taosWUnLockLatch(&((t)->latch))
|
||||
|
||||
STsdbMeta* tsdbNewMeta(STsdbCfg* pCfg);
|
||||
void tsdbFreeMeta(STsdbMeta* pMeta);
|
||||
|
@ -391,7 +395,7 @@ static FORCE_INLINE STSchema* tsdbGetTableSchemaImpl(STable* pTable, bool lock,
|
|||
STSchema* pSchema = NULL;
|
||||
STSchema* pTSchema = NULL;
|
||||
|
||||
if (lock) taosRLockLatch(&(pDTable->latch));
|
||||
if (lock) TSDB_RLOCK_TABLE(pDTable);
|
||||
if (version < 0) { // get the latest version of schema
|
||||
pTSchema = pDTable->schema[pDTable->numOfSchemas - 1];
|
||||
} else { // get the schema with version
|
||||
|
@ -413,7 +417,7 @@ static FORCE_INLINE STSchema* tsdbGetTableSchemaImpl(STable* pTable, bool lock,
|
|||
}
|
||||
|
||||
_exit:
|
||||
if (lock) taosRUnLockLatch(&(pDTable->latch));
|
||||
if (lock) TSDB_RUNLOCK_TABLE(pDTable);
|
||||
return pSchema;
|
||||
}
|
||||
|
||||
|
@ -433,6 +437,11 @@ static FORCE_INLINE STSchema *tsdbGetTableTagSchema(STable *pTable) {
|
|||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE TSKEY tsdbGetTableLastKeyImpl(STable* pTable) {
|
||||
ASSERT(pTable->lastRow == NULL || pTable->lastKey == dataRowKey(pTable->lastRow));
|
||||
return pTable->lastKey;
|
||||
}
|
||||
|
||||
// ------------------ tsdbBuffer.c
|
||||
#define TSDB_BUFFER_RESERVE 1024 // Reseve 1K as commit threshold
|
||||
|
||||
|
|
|
@ -161,6 +161,11 @@ _err:
|
|||
|
||||
static void tsdbEndCommit(STsdbRepo *pRepo, int eno) {
|
||||
if (pRepo->appH.notifyStatus) pRepo->appH.notifyStatus(pRepo->appH.appH, TSDB_STATUS_COMMIT_OVER, eno);
|
||||
SMemTable *pIMem = pRepo->imem;
|
||||
tsdbLockRepo(pRepo);
|
||||
pRepo->imem = NULL;
|
||||
tsdbUnlockRepo(pRepo);
|
||||
tsdbUnRefMemTable(pRepo, pIMem);
|
||||
sem_post(&(pRepo->readyToCommit));
|
||||
}
|
||||
|
||||
|
@ -220,7 +225,7 @@ static int tsdbCommitToFile(STsdbRepo *pRepo, int fid, SCommitIter *iters, SRWHe
|
|||
SCommitIter *pIter = iters + tid;
|
||||
if (pIter->pTable == NULL) continue;
|
||||
|
||||
taosRLockLatch(&(pIter->pTable->latch));
|
||||
TSDB_RLOCK_TABLE(pIter->pTable);
|
||||
|
||||
if (tsdbSetHelperTable(pHelper, pIter->pTable, pRepo) < 0) goto _err;
|
||||
|
||||
|
@ -231,7 +236,7 @@ static int tsdbCommitToFile(STsdbRepo *pRepo, int fid, SCommitIter *iters, SRWHe
|
|||
}
|
||||
|
||||
if (tsdbCommitTableData(pHelper, pIter, pDataCols, maxKey) < 0) {
|
||||
taosRUnLockLatch(&(pIter->pTable->latch));
|
||||
TSDB_RUNLOCK_TABLE(pIter->pTable);
|
||||
tsdbError("vgId:%d failed to write data of table %s tid %d uid %" PRIu64 " since %s", REPO_ID(pRepo),
|
||||
TABLE_CHAR_NAME(pIter->pTable), TABLE_TID(pIter->pTable), TABLE_UID(pIter->pTable),
|
||||
tstrerror(terrno));
|
||||
|
@ -239,7 +244,7 @@ static int tsdbCommitToFile(STsdbRepo *pRepo, int fid, SCommitIter *iters, SRWHe
|
|||
}
|
||||
}
|
||||
|
||||
taosRUnLockLatch(&(pIter->pTable->latch));
|
||||
TSDB_RUNLOCK_TABLE(pIter->pTable);
|
||||
|
||||
// Move the last block to the new .l file if neccessary
|
||||
if (tsdbMoveLastBlockIfNeccessary(pHelper) < 0) {
|
||||
|
|
|
@ -77,9 +77,9 @@ int32_t tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg) {
|
|||
|
||||
tsdbDebug(
|
||||
"vgId:%d tsdb env create succeed! cacheBlockSize %d totalBlocks %d daysPerFile %d keep "
|
||||
"%d minRowsPerFileBlock %d maxRowsPerFileBlock %d precision %d compression %d",
|
||||
"%d minRowsPerFileBlock %d maxRowsPerFileBlock %d precision %d compression %d update %d cacheLastRow %d",
|
||||
pCfg->tsdbId, pCfg->cacheBlockSize, pCfg->totalBlocks, pCfg->daysPerFile, pCfg->keep, pCfg->minRowsPerFileBlock,
|
||||
pCfg->maxRowsPerFileBlock, pCfg->precision, pCfg->compression);
|
||||
pCfg->maxRowsPerFileBlock, pCfg->precision, pCfg->compression, pCfg->update, pCfg->cacheLastRow);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -281,6 +281,10 @@ int32_t tsdbConfigRepo(TSDB_REPO_T *repo, STsdbCfg *pCfg) {
|
|||
config.totalBlocks = pCfg->totalBlocks;
|
||||
configChanged = true;
|
||||
}
|
||||
if (pRCfg->cacheLastRow != pCfg->cacheLastRow) {
|
||||
config.cacheLastRow = pCfg->cacheLastRow;
|
||||
configChanged = true;
|
||||
}
|
||||
|
||||
if (configChanged) {
|
||||
if (tsdbSaveConfig(pRepo->rootDir, &config) < 0) {
|
||||
|
@ -475,6 +479,9 @@ static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg) {
|
|||
// update check
|
||||
if (pCfg->update != 0) pCfg->update = 1;
|
||||
|
||||
// update cacheLastRow
|
||||
if (pCfg->cacheLastRow != 0) pCfg->cacheLastRow = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
|
@ -692,10 +699,12 @@ static void tsdbFreeRepo(STsdbRepo *pRepo) {
|
|||
}
|
||||
}
|
||||
|
||||
static int tsdbRestoreInfo(STsdbRepo *pRepo) {
|
||||
static int tsdbRestoreInfo(STsdbRepo *pRepo) { // TODO
|
||||
STsdbMeta * pMeta = pRepo->tsdbMeta;
|
||||
STsdbFileH *pFileH = pRepo->tsdbFileH;
|
||||
SFileGroup *pFGroup = NULL;
|
||||
STsdbCfg * pCfg = &(pRepo->config);
|
||||
SCompBlock *pBlock = NULL;
|
||||
|
||||
SFileGroupIter iter;
|
||||
SRWHelper rhelper = {0};
|
||||
|
@ -713,7 +722,32 @@ static int tsdbRestoreInfo(STsdbRepo *pRepo) {
|
|||
if (tsdbSetHelperTable(&rhelper, pTable, pRepo) < 0) goto _err;
|
||||
SCompIdx *pIdx = &(rhelper.curCompIdx);
|
||||
|
||||
if (pIdx->offset > 0 && pTable->lastKey < pIdx->maxKey) pTable->lastKey = pIdx->maxKey;
|
||||
TSKEY lastKey = tsdbGetTableLastKeyImpl(pTable);
|
||||
if (pIdx->offset > 0 && lastKey < pIdx->maxKey) {
|
||||
pTable->lastKey = pIdx->maxKey;
|
||||
if (pCfg->cacheLastRow) { // load the block of data
|
||||
if (tsdbLoadCompInfo(&rhelper, NULL) < 0) goto _err;
|
||||
|
||||
pBlock = rhelper.pCompInfo->blocks + pIdx->numOfBlocks - 1;
|
||||
if (tsdbLoadBlockData(&rhelper, pBlock, NULL) < 0) goto _err;
|
||||
|
||||
// construct the data row
|
||||
ASSERT(pTable->lastRow == NULL);
|
||||
STSchema *pSchema = tsdbGetTableSchema(pTable);
|
||||
pTable->lastRow = taosTMalloc(schemaTLen(pSchema));
|
||||
if (pTable->lastRow == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
tdInitDataRow(pTable->lastRow, pSchema);
|
||||
for (int icol = 0; icol < schemaNCols(pSchema); icol++) {
|
||||
STColumn *pCol = schemaColAt(pSchema, icol);
|
||||
SDataCol *pDataCol = rhelper.pDataCols[0]->cols + icol;
|
||||
tdAppendColVal(pTable->lastRow, tdGetColDataOfRow(pDataCol, pBlock->numOfRows - 1), pCol->type, pCol->bytes,
|
||||
pCol->offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -800,6 +834,7 @@ static int tsdbEncodeCfg(void **buf, STsdbCfg *pCfg) {
|
|||
tlen += taosEncodeFixedI8(buf, pCfg->precision);
|
||||
tlen += taosEncodeFixedI8(buf, pCfg->compression);
|
||||
tlen += taosEncodeFixedI8(buf, pCfg->update);
|
||||
tlen += taosEncodeFixedI8(buf, pCfg->cacheLastRow);
|
||||
|
||||
return tlen;
|
||||
}
|
||||
|
@ -817,6 +852,7 @@ static void *tsdbDecodeCfg(void *buf, STsdbCfg *pCfg) {
|
|||
buf = taosDecodeFixedI8(buf, &(pCfg->precision));
|
||||
buf = taosDecodeFixedI8(buf, &(pCfg->compression));
|
||||
buf = taosDecodeFixedI8(buf, &(pCfg->update));
|
||||
buf = taosDecodeFixedI8(buf, &(pCfg->cacheLastRow));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "tsdbMain.h"
|
||||
|
||||
#define TSDB_DATA_SKIPLIST_LEVEL 5
|
||||
#define TSDB_MAX_INSERT_BATCH 512
|
||||
|
||||
static SMemTable * tsdbNewMemTable(STsdbRepo *pRepo);
|
||||
static void tsdbFreeMemTable(SMemTable *pMemTable);
|
||||
|
@ -35,6 +36,7 @@ static int tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPB
|
|||
static int tsdbCheckTableSchema(STsdbRepo *pRepo, SSubmitBlk *pBlock, STable *pTable);
|
||||
static int tsdbInsertDataToTableImpl(STsdbRepo *pRepo, STable *pTable, void **rows, int rowCounter);
|
||||
static void tsdbFreeRows(STsdbRepo *pRepo, void **rows, int rowCounter);
|
||||
static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SDataRow row);
|
||||
|
||||
static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SDataRow row, TSKEY minKey, TSKEY maxKey,
|
||||
TSKEY now);
|
||||
|
@ -205,7 +207,7 @@ void *tsdbAllocBytes(STsdbRepo *pRepo, int bytes) {
|
|||
int tsdbAsyncCommit(STsdbRepo *pRepo) {
|
||||
if (pRepo->mem == NULL) return 0;
|
||||
|
||||
SMemTable *pIMem = pRepo->imem;
|
||||
ASSERT(pRepo->imem == NULL);
|
||||
|
||||
sem_wait(&(pRepo->readyToCommit));
|
||||
|
||||
|
@ -220,8 +222,6 @@ int tsdbAsyncCommit(STsdbRepo *pRepo) {
|
|||
tsdbScheduleCommit(pRepo);
|
||||
if (tsdbUnlockRepo(pRepo) < 0) return -1;
|
||||
|
||||
if (tsdbUnRefMemTable(pRepo, pIMem) < 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -606,19 +606,13 @@ static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *
|
|||
STable * pTable = NULL;
|
||||
SSubmitBlkIter blkIter = {0};
|
||||
SDataRow row = NULL;
|
||||
void ** rows = NULL;
|
||||
void * rows[TSDB_MAX_INSERT_BATCH] = {0};
|
||||
int rowCounter = 0;
|
||||
|
||||
ASSERT(pBlock->tid < pMeta->maxTables);
|
||||
pTable = pMeta->tables[pBlock->tid];
|
||||
ASSERT(pTable != NULL && TABLE_UID(pTable) == pBlock->uid);
|
||||
|
||||
rows = (void **)calloc(pBlock->numOfRows, sizeof(void *));
|
||||
if (rows == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsdbInitSubmitBlkIter(pBlock, &blkIter);
|
||||
while ((row = tsdbGetSubmitBlkNext(&blkIter)) != NULL) {
|
||||
if (tsdbCopyRowToMem(pRepo, row, pTable, &(rows[rowCounter])) < 0) {
|
||||
|
@ -632,9 +626,18 @@ static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *
|
|||
if (rows[rowCounter] != NULL) {
|
||||
rowCounter++;
|
||||
}
|
||||
|
||||
if (rowCounter == TSDB_MAX_INSERT_BATCH) {
|
||||
if (tsdbInsertDataToTableImpl(pRepo, pTable, rows, rowCounter) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
rowCounter = 0;
|
||||
memset(rows, 0, sizeof(rows));
|
||||
}
|
||||
}
|
||||
|
||||
if (tsdbInsertDataToTableImpl(pRepo, pTable, rows, rowCounter) < 0) {
|
||||
if (rowCounter > 0 && tsdbInsertDataToTableImpl(pRepo, pTable, rows, rowCounter) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
|
@ -642,11 +645,9 @@ static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *
|
|||
pRepo->stat.pointsWritten += points * schemaNCols(pSchema);
|
||||
pRepo->stat.totalStorage += points * schemaVLen(pSchema);
|
||||
|
||||
free(rows);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
free(rows);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -663,9 +664,10 @@ static int tsdbCopyRowToMem(STsdbRepo *pRepo, SDataRow row, STable *pTable, void
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (key > TABLE_LASTKEY(pTable)) {
|
||||
TSKEY lastKey = tsdbGetTableLastKeyImpl(pTable);
|
||||
if (key > lastKey) {
|
||||
tsdbTrace("vgId:%d skip to delete row key %" PRId64 " which is larger than table lastKey %" PRId64,
|
||||
REPO_ID(pRepo), key, TABLE_LASTKEY(pTable));
|
||||
REPO_ID(pRepo), key, lastKey);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -846,8 +848,10 @@ static int tsdbInsertDataToTableImpl(STsdbRepo *pRepo, STable *pTable, void **ro
|
|||
if (pTableData->keyLast < dataRowKey(rows[rowCounter - 1])) pTableData->keyLast = dataRowKey(rows[rowCounter - 1]);
|
||||
pTableData->numOfRows += dsize;
|
||||
|
||||
// TODO: impl delete row thing
|
||||
if (TABLE_LASTKEY(pTable) < dataRowKey(rows[rowCounter-1])) TABLE_LASTKEY(pTable) = dataRowKey(rows[rowCounter-1]);
|
||||
// update table latest info
|
||||
if (tsdbUpdateTableLatestInfo(pRepo, pTable, rows[rowCounter - 1]) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -889,4 +893,38 @@ static void tsdbFreeRows(STsdbRepo *pRepo, void **rows, int rowCounter) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SDataRow row) {
|
||||
STsdbCfg *pCfg = &pRepo->config;
|
||||
|
||||
if (tsdbGetTableLastKeyImpl(pTable) < dataRowKey(row)) {
|
||||
if (pCfg->cacheLastRow || pTable->lastRow != NULL) {
|
||||
SDataRow nrow = pTable->lastRow;
|
||||
if (taosTSizeof(nrow) < dataRowLen(row)) {
|
||||
SDataRow orow = nrow;
|
||||
nrow = taosTMalloc(dataRowLen(row));
|
||||
if (nrow == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dataRowCpy(nrow, row);
|
||||
TSDB_WLOCK_TABLE(pTable);
|
||||
pTable->lastKey = dataRowKey(row);
|
||||
pTable->lastRow = nrow;
|
||||
TSDB_WUNLOCK_TABLE(pTable);
|
||||
taosTZfree(orow);
|
||||
} else {
|
||||
TSDB_WLOCK_TABLE(pTable);
|
||||
pTable->lastKey = dataRowKey(row);
|
||||
dataRowCpy(nrow, row);
|
||||
TSDB_WUNLOCK_TABLE(pTable);
|
||||
}
|
||||
} else {
|
||||
pTable->lastKey = dataRowKey(row);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -377,11 +377,11 @@ int tsdbUpdateTableTagValue(TSDB_REPO_T *repo, SUpdateTableTagValMsg *pMsg) {
|
|||
|
||||
// Chage in memory
|
||||
if (pNewSchema != NULL) { // change super table tag schema
|
||||
taosWLockLatch(&(pTable->pSuper->latch));
|
||||
TSDB_WLOCK_TABLE(pTable->pSuper);
|
||||
STSchema *pOldSchema = pTable->pSuper->tagSchema;
|
||||
pTable->pSuper->tagSchema = pNewSchema;
|
||||
tdFreeSchema(pOldSchema);
|
||||
taosWUnLockLatch(&(pTable->pSuper->latch));
|
||||
TSDB_WUNLOCK_TABLE(pTable->pSuper);
|
||||
}
|
||||
|
||||
bool isChangeIndexCol = (pMsg->colId == colColId(schemaColAt(pTable->pSuper->tagSchema, 0)));
|
||||
|
@ -392,9 +392,9 @@ int tsdbUpdateTableTagValue(TSDB_REPO_T *repo, SUpdateTableTagValMsg *pMsg) {
|
|||
tsdbWLockRepoMeta(pRepo);
|
||||
tsdbRemoveTableFromIndex(pMeta, pTable);
|
||||
}
|
||||
taosWLockLatch(&(pTable->latch));
|
||||
TSDB_WLOCK_TABLE(pTable);
|
||||
tdSetKVRowDataOfCol(&(pTable->tagVal), pMsg->colId, pMsg->type, POINTER_SHIFT(pMsg->data, pMsg->schemaLen));
|
||||
taosWUnLockLatch(&(pTable->latch));
|
||||
TSDB_WUNLOCK_TABLE(pTable);
|
||||
if (isChangeIndexCol) {
|
||||
tsdbAddTableIntoIndex(pMeta, pTable, false);
|
||||
tsdbUnlockRepoMeta(pRepo);
|
||||
|
@ -587,7 +587,7 @@ void tsdbUpdateTableSchema(STsdbRepo *pRepo, STable *pTable, STSchema *pSchema,
|
|||
STable *pCTable = (TABLE_TYPE(pTable) == TSDB_CHILD_TABLE) ? pTable->pSuper : pTable;
|
||||
ASSERT(schemaVersion(pSchema) > schemaVersion(pCTable->schema[pCTable->numOfSchemas - 1]));
|
||||
|
||||
taosWLockLatch(&(pCTable->latch));
|
||||
TSDB_WLOCK_TABLE(pCTable);
|
||||
if (pCTable->numOfSchemas < TSDB_MAX_TABLE_SCHEMAS) {
|
||||
pCTable->schema[pCTable->numOfSchemas++] = pSchema;
|
||||
} else {
|
||||
|
@ -599,7 +599,7 @@ void tsdbUpdateTableSchema(STsdbRepo *pRepo, STable *pTable, STSchema *pSchema,
|
|||
|
||||
if (schemaNCols(pSchema) > pMeta->maxCols) pMeta->maxCols = schemaNCols(pSchema);
|
||||
if (schemaTLen(pSchema) > pMeta->maxRowBytes) pMeta->maxRowBytes = schemaTLen(pSchema);
|
||||
taosWUnLockLatch(&(pCTable->latch));
|
||||
TSDB_WUNLOCK_TABLE(pCTable);
|
||||
|
||||
if (insertAct) {
|
||||
int tlen = tsdbGetTableEncodeSize(TSDB_UPDATE_META, pCTable);
|
||||
|
@ -775,6 +775,7 @@ static void tsdbFreeTable(STable *pTable) {
|
|||
kvRowFree(pTable->tagVal);
|
||||
|
||||
tSkipListDestroy(pTable->pIndex);
|
||||
taosTZfree(pTable->lastRow);
|
||||
tfree(pTable->sql);
|
||||
free(pTable);
|
||||
}
|
||||
|
|
|
@ -110,6 +110,7 @@ typedef struct STsdbQueryHandle {
|
|||
SArray* pTableCheckInfo; // SArray<STableCheckInfo>
|
||||
int32_t activeIndex;
|
||||
bool checkFiles; // check file stage
|
||||
bool cachelastrow; // check if last row cached
|
||||
void* qinfo; // query info handle, for debug purpose
|
||||
int32_t type; // query type: retrieve all data blocks, 2. retrieve only last row, 3. retrieve direct prev|next rows
|
||||
SFileGroup* pFileGroup;
|
||||
|
@ -133,7 +134,9 @@ typedef struct STableGroupSupporter {
|
|||
STSchema* pTagSchema;
|
||||
} STableGroupSupporter;
|
||||
|
||||
static STimeWindow changeTableGroupByLastrow(STableGroupInfo *groupList);
|
||||
static STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList);
|
||||
static int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *groupList);
|
||||
static int32_t tsdbGetCachedLastRow(STable* pTable, SDataRow* pRes, TSKEY* lastKey);
|
||||
|
||||
static void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle);
|
||||
static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* pCheckInfo, SCompBlock* pBlock);
|
||||
|
@ -370,7 +373,7 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab
|
|||
}
|
||||
|
||||
TsdbQueryHandleT tsdbQueryLastRow(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, void* qinfo, SMemRef* pMemRef) {
|
||||
pCond->twindow = changeTableGroupByLastrow(groupList);
|
||||
pCond->twindow = updateLastrowForEachGroup(groupList);
|
||||
|
||||
// no qualified table
|
||||
if (groupList->numOfTables == 0) {
|
||||
|
@ -378,8 +381,14 @@ TsdbQueryHandleT tsdbQueryLastRow(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STab
|
|||
}
|
||||
|
||||
STsdbQueryHandle *pQueryHandle = (STsdbQueryHandle*) tsdbQueryTables(tsdb, pCond, groupList, qinfo, pMemRef);
|
||||
int32_t code = checkForCachedLastRow(pQueryHandle, groupList);
|
||||
if (code != TSDB_CODE_SUCCESS) { // set the numOfTables to be 0
|
||||
terrno = code;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(pCond->order == TSDB_ORDER_ASC && pCond->twindow.skey <= pCond->twindow.ekey);
|
||||
pQueryHandle->type = TSDB_QUERY_TYPE_LAST;
|
||||
return pQueryHandle;
|
||||
}
|
||||
|
||||
|
@ -956,9 +965,9 @@ static int32_t loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBl
|
|||
return code;
|
||||
}
|
||||
|
||||
SDataCols* pTSCol = pQueryHandle->rhelper.pDataCols[0];
|
||||
SDataCols* pTsCol = pQueryHandle->rhelper.pDataCols[0];
|
||||
if (pCheckInfo->lastKey < pBlock->keyLast) {
|
||||
cur->pos = binarySearchForKey(pTSCol->cols[0].pData, pBlock->numOfRows, pCheckInfo->lastKey, pQueryHandle->order);
|
||||
cur->pos = binarySearchForKey(pTsCol->cols[0].pData, pBlock->numOfRows, pCheckInfo->lastKey, pQueryHandle->order);
|
||||
} else {
|
||||
cur->pos = pBlock->numOfRows - 1;
|
||||
}
|
||||
|
@ -1704,7 +1713,32 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t getDataBlocksInFilesImpl(STsdbQueryHandle* pQueryHandle, bool* exists) {
|
||||
static int32_t getFirstFileDataBlock(STsdbQueryHandle* pQueryHandle, bool* exists);
|
||||
|
||||
static int32_t getDataBlockRv(STsdbQueryHandle* pQueryHandle, STableBlockInfo* pNext, bool *exists) {
|
||||
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1 : -1;
|
||||
SQueryFilePos* cur = &pQueryHandle->cur;
|
||||
|
||||
while(1) {
|
||||
int32_t code = loadFileDataBlock(pQueryHandle, pNext->compBlock, pNext->pTableCheckInfo, exists);
|
||||
if (code != TSDB_CODE_SUCCESS || *exists) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((cur->slot == pQueryHandle->numOfBlocks - 1 && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
||||
(cur->slot == 0 && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||
// all data blocks in current file has been checked already, try next file if exists
|
||||
return getFirstFileDataBlock(pQueryHandle, exists);
|
||||
} else { // next block of the same file
|
||||
cur->slot += step;
|
||||
cur->mixBlock = false;
|
||||
cur->blockCompleted = false;
|
||||
pNext = &pQueryHandle->pDataBlockInfo[cur->slot];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t getFirstFileDataBlock(STsdbQueryHandle* pQueryHandle, bool* exists) {
|
||||
pQueryHandle->numOfBlocks = 0;
|
||||
SQueryFilePos* cur = &pQueryHandle->cur;
|
||||
|
||||
|
@ -1789,7 +1823,23 @@ static int32_t getDataBlocksInFilesImpl(STsdbQueryHandle* pQueryHandle, bool* ex
|
|||
cur->fid = pQueryHandle->pFileGroup->fileId;
|
||||
|
||||
STableBlockInfo* pBlockInfo = &pQueryHandle->pDataBlockInfo[cur->slot];
|
||||
return loadFileDataBlock(pQueryHandle, pBlockInfo->compBlock, pBlockInfo->pTableCheckInfo, exists);
|
||||
return getDataBlockRv(pQueryHandle, pBlockInfo, exists);
|
||||
}
|
||||
|
||||
static bool isEndFileDataBlock(SQueryFilePos* cur, int32_t numOfBlocks, bool ascTrav) {
|
||||
assert(cur != NULL && numOfBlocks > 0);
|
||||
return (cur->slot == numOfBlocks - 1 && ascTrav) || (cur->slot == 0 && !ascTrav);
|
||||
}
|
||||
|
||||
static void moveToNextDataBlockInCurrentFile(STsdbQueryHandle* pQueryHandle) {
|
||||
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1 : -1;
|
||||
|
||||
SQueryFilePos* cur = &pQueryHandle->cur;
|
||||
assert(cur->slot < pQueryHandle->numOfBlocks && cur->slot >= 0);
|
||||
|
||||
cur->slot += step;
|
||||
cur->mixBlock = false;
|
||||
cur->blockCompleted = false;
|
||||
}
|
||||
|
||||
static int32_t getDataBlocksInFiles(STsdbQueryHandle* pQueryHandle, bool* exists) {
|
||||
|
@ -1800,14 +1850,14 @@ static int32_t getDataBlocksInFiles(STsdbQueryHandle* pQueryHandle, bool* exists
|
|||
if (!pQueryHandle->locateStart) {
|
||||
pQueryHandle->locateStart = true;
|
||||
STsdbCfg* pCfg = &pQueryHandle->pTsdb->config;
|
||||
int32_t fid = getFileIdFromKey(pQueryHandle->window.skey, pCfg->daysPerFile, pCfg->precision);
|
||||
int32_t fid = getFileIdFromKey(pQueryHandle->window.skey, pCfg->daysPerFile, pCfg->precision);
|
||||
|
||||
pthread_rwlock_rdlock(&pQueryHandle->pTsdb->tsdbFileH->fhlock);
|
||||
tsdbInitFileGroupIter(pFileHandle, &pQueryHandle->fileIter, pQueryHandle->order);
|
||||
tsdbSeekFileGroupIter(&pQueryHandle->fileIter, fid);
|
||||
pthread_rwlock_unlock(&pQueryHandle->pTsdb->tsdbFileH->fhlock);
|
||||
|
||||
return getDataBlocksInFilesImpl(pQueryHandle, exists);
|
||||
return getFirstFileDataBlock(pQueryHandle, exists);
|
||||
} else {
|
||||
// check if current file block is all consumed
|
||||
STableBlockInfo* pBlockInfo = &pQueryHandle->pDataBlockInfo[cur->slot];
|
||||
|
@ -1815,27 +1865,26 @@ static int32_t getDataBlocksInFiles(STsdbQueryHandle* pQueryHandle, bool* exists
|
|||
|
||||
// current block is done, try next
|
||||
if ((!cur->mixBlock) || cur->blockCompleted) {
|
||||
if ((cur->slot == pQueryHandle->numOfBlocks - 1 && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
||||
(cur->slot == 0 && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||
// all data blocks in current file has been checked already, try next file if exists
|
||||
return getDataBlocksInFilesImpl(pQueryHandle, exists);
|
||||
} else {
|
||||
// next block of the same file
|
||||
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order) ? 1 : -1;
|
||||
cur->slot += step;
|
||||
|
||||
cur->mixBlock = false;
|
||||
cur->blockCompleted = false;
|
||||
|
||||
STableBlockInfo* pNext = &pQueryHandle->pDataBlockInfo[cur->slot];
|
||||
return loadFileDataBlock(pQueryHandle, pNext->compBlock, pNext->pTableCheckInfo, exists);
|
||||
}
|
||||
// all data blocks in current file has been checked already, try next file if exists
|
||||
} else {
|
||||
tsdbDebug("%p continue in current data block, index:%d, pos:%d, %p", pQueryHandle, cur->slot, cur->pos, pQueryHandle->qinfo);
|
||||
tsdbDebug("%p continue in current data block, index:%d, pos:%d, %p", pQueryHandle, cur->slot, cur->pos,
|
||||
pQueryHandle->qinfo);
|
||||
int32_t code = handleDataMergeIfNeeded(pQueryHandle, pBlockInfo->compBlock, pCheckInfo);
|
||||
*exists = pQueryHandle->realNumOfRows > 0;
|
||||
*exists = (pQueryHandle->realNumOfRows > 0);
|
||||
|
||||
return code;
|
||||
if (code != TSDB_CODE_SUCCESS || *exists) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
// current block is empty, try next block in file
|
||||
// all data blocks in current file has been checked already, try next file if exists
|
||||
if (isEndFileDataBlock(cur, pQueryHandle->numOfBlocks, ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||
return getFirstFileDataBlock(pQueryHandle, exists);
|
||||
} else {
|
||||
moveToNextDataBlockInCurrentFile(pQueryHandle);
|
||||
STableBlockInfo* pNext = &pQueryHandle->pDataBlockInfo[cur->slot];
|
||||
return getDataBlockRv(pQueryHandle, pNext, exists);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2104,6 +2153,39 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pHandle) {
|
|||
// restore the pMemRef
|
||||
pQueryHandle->pMemRef = pMemRef;
|
||||
return ret;
|
||||
} else if (pQueryHandle->type == TSDB_QUERY_TYPE_LAST && pQueryHandle->cachelastrow) {
|
||||
// the last row is cached in buffer, return it directly.
|
||||
// here note that the pQueryHandle->window must be the TS_INITIALIZER
|
||||
int32_t numOfCols = (int32_t)(QH_GET_NUM_OF_COLS(pQueryHandle));
|
||||
SQueryFilePos* cur = &pQueryHandle->cur;
|
||||
|
||||
SDataRow pRow = NULL;
|
||||
TSKEY key = TSKEY_INITIAL_VAL;
|
||||
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1:-1;
|
||||
|
||||
if (++pQueryHandle->activeIndex < numOfTables) {
|
||||
STableCheckInfo* pCheckInfo = taosArrayGet(pQueryHandle->pTableCheckInfo, pQueryHandle->activeIndex);
|
||||
int32_t ret = tsdbGetCachedLastRow(pCheckInfo->pTableObj, &pRow, &key);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
copyOneRowFromMem(pQueryHandle, pQueryHandle->outputCapacity, 0, pRow, numOfCols, pCheckInfo->pTableObj);
|
||||
tfree(pRow);
|
||||
|
||||
// update the last key value
|
||||
pCheckInfo->lastKey = key + step;
|
||||
|
||||
cur->rows = 1; // only one row
|
||||
cur->lastKey = key + step;
|
||||
cur->mixBlock = true;
|
||||
cur->win.skey = key;
|
||||
cur->win.ekey = key;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pQueryHandle->checkFiles) {
|
||||
|
@ -2136,7 +2218,57 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pHandle) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
STimeWindow changeTableGroupByLastrow(STableGroupInfo *groupList) {
|
||||
/*
|
||||
* 1. no data at all (pTable->lastKey = TSKEY_INITIAL_VAL), just return TSKEY_INITIAL_VAL
|
||||
* 2. has data but not loaded, just return lastKey but not set pRes
|
||||
* 3. has data and loaded, return lastKey and set pRes
|
||||
*/
|
||||
int32_t tsdbGetCachedLastRow(STable* pTable, SDataRow* pRes, TSKEY* lastKey) {
|
||||
TSDB_RLOCK_TABLE(pTable);
|
||||
*lastKey = pTable->lastKey;
|
||||
|
||||
if ((*lastKey) != TSKEY_INITIAL_VAL && pTable->lastRow) {
|
||||
*pRes = tdDataRowDup(pTable->lastRow);
|
||||
if (*pRes == NULL) {
|
||||
TSDB_RUNLOCK_TABLE(pTable);
|
||||
return TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
TSDB_RUNLOCK_TABLE(pTable);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *groupList) {
|
||||
assert(pQueryHandle != NULL && groupList != NULL);
|
||||
|
||||
SDataRow pRow = NULL;
|
||||
TSKEY key = TSKEY_INITIAL_VAL;
|
||||
|
||||
SArray* group = taosArrayGetP(groupList->pGroupList, 0);
|
||||
assert(group != NULL);
|
||||
|
||||
STableKeyInfo* pInfo = (STableKeyInfo*)taosArrayGet(group, 0);
|
||||
|
||||
int32_t code = tsdbGetCachedLastRow(pInfo->pTable, &pRow, &key);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pQueryHandle->cachelastrow = false;
|
||||
} else {
|
||||
pQueryHandle->cachelastrow = (pRow != NULL);
|
||||
}
|
||||
|
||||
// update the tsdb query time range
|
||||
if (pQueryHandle->cachelastrow) {
|
||||
pQueryHandle->window = TSWINDOW_INITIALIZER;
|
||||
pQueryHandle->checkFiles = false;
|
||||
pQueryHandle->activeIndex = -1; // start from -1
|
||||
}
|
||||
|
||||
tfree(pRow);
|
||||
return code;
|
||||
}
|
||||
|
||||
STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList) {
|
||||
STimeWindow window = {INT64_MAX, INT64_MIN};
|
||||
|
||||
int32_t totalNumOfTable = 0;
|
||||
|
@ -2151,16 +2283,16 @@ STimeWindow changeTableGroupByLastrow(STableGroupInfo *groupList) {
|
|||
|
||||
size_t numOfTables = taosArrayGetSize(pGroup);
|
||||
for(int32_t i = 0; i < numOfTables; ++i) {
|
||||
STableKeyInfo* pKeyInfo = (STableKeyInfo*) taosArrayGet(pGroup, i);
|
||||
STableKeyInfo* pInfo = (STableKeyInfo*) taosArrayGet(pGroup, i);
|
||||
|
||||
// if the lastKey equals to INT64_MIN, there is no data in this table
|
||||
TSKEY lastKey = ((STable*)(pKeyInfo->pTable))->lastKey;
|
||||
TSKEY lastKey = ((STable*)(pInfo->pTable))->lastKey;
|
||||
if (key < lastKey) {
|
||||
key = lastKey;
|
||||
|
||||
keyInfo.pTable = pKeyInfo->pTable;
|
||||
keyInfo.pTable = pInfo->pTable;
|
||||
keyInfo.lastKey = key;
|
||||
pKeyInfo->lastKey = key;
|
||||
pInfo->lastKey = key;
|
||||
|
||||
if (key < window.skey) {
|
||||
window.skey = key;
|
||||
|
@ -2174,11 +2306,11 @@ STimeWindow changeTableGroupByLastrow(STableGroupInfo *groupList) {
|
|||
|
||||
// clear current group, unref unused table
|
||||
for (int32_t i = 0; i < numOfTables; ++i) {
|
||||
STableKeyInfo* pKeyInfo = (STableKeyInfo*)taosArrayGet(pGroup, i);
|
||||
STableKeyInfo* pInfo = (STableKeyInfo*)taosArrayGet(pGroup, i);
|
||||
|
||||
// keyInfo.pTable may be NULL here.
|
||||
if (pKeyInfo->pTable != keyInfo.pTable) {
|
||||
tsdbUnRefTable(pKeyInfo->pTable);
|
||||
if (pInfo->pTable != keyInfo.pTable) {
|
||||
tsdbUnRefTable(pInfo->pTable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef _TS_BUILD_H_
|
||||
#define _TS_BUILD_H_
|
||||
|
||||
extern const char tsVersion[];
|
||||
extern const char tsBuildInfo[];
|
||||
|
||||
#endif
|
|
@ -32,17 +32,18 @@ typedef void (*_hash_free_fn_t)(void *param);
|
|||
|
||||
typedef struct SHashNode {
|
||||
struct SHashNode *next;
|
||||
uint32_t hashVal; // the hash value of key
|
||||
uint32_t keyLen; // length of the key
|
||||
size_t dataLen; // length of data
|
||||
int8_t count; // reference count
|
||||
int8_t removed; // flag to indicate removed
|
||||
uint32_t hashVal; // the hash value of key
|
||||
uint32_t dataLen; // length of data
|
||||
uint32_t keyLen; // length of the key
|
||||
int8_t removed; // flag to indicate removed
|
||||
int8_t count; // reference count
|
||||
char data[];
|
||||
} SHashNode;
|
||||
|
||||
#define GET_HASH_NODE_KEY(_n) ((char*)(_n) + sizeof(SHashNode) + (_n)->dataLen)
|
||||
#define GET_HASH_NODE_DATA(_n) ((char*)(_n) + sizeof(SHashNode))
|
||||
#define GET_HASH_PNODE(_n) ((char*)(_n) - sizeof(SHashNode));
|
||||
|
||||
typedef enum SHashLockTypeE {
|
||||
HASH_NO_LOCK = 0,
|
||||
HASH_ENTRY_LOCK = 1,
|
||||
|
@ -115,7 +116,7 @@ void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen);
|
|||
* @param dsize
|
||||
* @return
|
||||
*/
|
||||
void* taosHashGetCB(SHashObj *pHashObj, const void *key, size_t keyLen, void (*fp)(void *), void* d, size_t dsize);
|
||||
void* taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void (*fp)(void *), void* d, size_t dsize);
|
||||
|
||||
/**
|
||||
* remove item with the specified key
|
||||
|
|
|
@ -41,6 +41,7 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
TAOS_CFG_VTYPE_INT8,
|
||||
TAOS_CFG_VTYPE_INT16,
|
||||
TAOS_CFG_VTYPE_INT32,
|
||||
TAOS_CFG_VTYPE_FLOAT,
|
||||
|
|
|
@ -271,10 +271,10 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
|
|||
}
|
||||
|
||||
void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen) {
|
||||
return taosHashGetCB(pHashObj, key, keyLen, NULL, NULL, 0);
|
||||
return taosHashGetClone(pHashObj, key, keyLen, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
void* taosHashGetCB(SHashObj *pHashObj, const void *key, size_t keyLen, void (*fp)(void *), void* d, size_t dsize) {
|
||||
void* taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void (*fp)(void *), void* d, size_t dsize) {
|
||||
if (pHashObj->size <= 0 || keyLen == 0 || key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -654,7 +654,7 @@ SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, s
|
|||
|
||||
pNewNode->keyLen = (uint32_t)keyLen;
|
||||
pNewNode->hashVal = hashVal;
|
||||
pNewNode->dataLen = dsize;
|
||||
pNewNode->dataLen = (uint32_t) dsize;
|
||||
pNewNode->count = 1;
|
||||
|
||||
memcpy(GET_HASH_NODE_DATA(pNewNode), pData, dsize);
|
||||
|
|
|
@ -278,7 +278,7 @@ void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen
|
|||
}
|
||||
|
||||
SCacheDataNode* ptNode = NULL;
|
||||
taosHashGetCB(pCacheObj->pHashTable, key, keyLen, incRefFn, &ptNode, sizeof(void*));
|
||||
taosHashGetClone(pCacheObj->pHashTable, key, keyLen, incRefFn, &ptNode, sizeof(void*));
|
||||
|
||||
void* pData = (ptNode != NULL)? ptNode->data:NULL;
|
||||
|
||||
|
@ -547,13 +547,14 @@ void taosAddToTrashcan(SCacheObj *pCacheObj, SCacheDataNode *pNode) {
|
|||
return;
|
||||
}
|
||||
|
||||
__cache_wr_lock(pCacheObj);
|
||||
STrashElem *pElem = calloc(1, sizeof(STrashElem));
|
||||
pElem->pData = pNode;
|
||||
pElem->prev = NULL;
|
||||
pElem->prev = NULL;
|
||||
pElem->next = NULL;
|
||||
pNode->inTrashcan = true;
|
||||
pNode->pTNodeHeader = pElem;
|
||||
|
||||
__cache_wr_lock(pCacheObj);
|
||||
pElem->next = pCacheObj->pTrash;
|
||||
if (pCacheObj->pTrash) {
|
||||
pCacheObj->pTrash->prev = pElem;
|
||||
|
@ -563,8 +564,8 @@ void taosAddToTrashcan(SCacheObj *pCacheObj, SCacheDataNode *pNode) {
|
|||
pCacheObj->numOfElemsInTrash++;
|
||||
__cache_unlock(pCacheObj);
|
||||
|
||||
uDebug("cache:%s key:%p, %p move to trashcan, pTrashElem:%p, numOfElem in trashcan:%d", pCacheObj->name,
|
||||
pNode->key, pNode->data, pElem, pCacheObj->numOfElemsInTrash);
|
||||
uDebug("cache:%s key:%p, %p move to trashcan, pTrashElem:%p, numOfElem in trashcan:%d", pCacheObj->name, pNode->key,
|
||||
pNode->data, pElem, pCacheObj->numOfElemsInTrash);
|
||||
}
|
||||
|
||||
void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) {
|
||||
|
|
|
@ -95,6 +95,23 @@ static void taosReadInt16Config(SGlobalCfg *cfg, char *input_value) {
|
|||
}
|
||||
}
|
||||
|
||||
static void taosReadInt8Config(SGlobalCfg *cfg, char *input_value) {
|
||||
int32_t value = atoi(input_value);
|
||||
int8_t *option = (int8_t *)cfg->ptr;
|
||||
if (value < cfg->minValue || value > cfg->maxValue) {
|
||||
uError("config option:%s, input value:%s, out of range[%f, %f], use default value:%d",
|
||||
cfg->option, input_value, cfg->minValue, cfg->maxValue, *option);
|
||||
} else {
|
||||
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_FILE) {
|
||||
*option = (int8_t)value;
|
||||
cfg->cfgStatus = TAOS_CFG_CSTATUS_FILE;
|
||||
} else {
|
||||
uWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg->option, input_value,
|
||||
tsCfgStatusStr[cfg->cfgStatus], *option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void taosReadDirectoryConfig(SGlobalCfg *cfg, char *input_value) {
|
||||
int length = (int)strlen(input_value);
|
||||
char *option = (char *)cfg->ptr;
|
||||
|
@ -204,6 +221,9 @@ static void taosReadConfigOption(const char *option, char *value) {
|
|||
if (strcasecmp(cfg->option, option) != 0) continue;
|
||||
|
||||
switch (cfg->valType) {
|
||||
case TAOS_CFG_VTYPE_INT8:
|
||||
taosReadInt8Config(cfg, value);
|
||||
break;
|
||||
case TAOS_CFG_VTYPE_INT16:
|
||||
taosReadInt16Config(cfg, value);
|
||||
break;
|
||||
|
@ -376,6 +396,9 @@ void taosPrintGlobalCfg() {
|
|||
blank[blankLen] = 0;
|
||||
|
||||
switch (cfg->valType) {
|
||||
case TAOS_CFG_VTYPE_INT8:
|
||||
uInfo(" %s:%s%d%s", cfg->option, blank, *((int8_t *)cfg->ptr), tsGlobalUnit[cfg->unitType]);
|
||||
break;
|
||||
case TAOS_CFG_VTYPE_INT16:
|
||||
uInfo(" %s:%s%d%s", cfg->option, blank, *((int16_t *)cfg->ptr), tsGlobalUnit[cfg->unitType]);
|
||||
break;
|
||||
|
@ -408,6 +431,9 @@ static void taosDumpCfg(SGlobalCfg *cfg) {
|
|||
blank[blankLen] = 0;
|
||||
|
||||
switch (cfg->valType) {
|
||||
case TAOS_CFG_VTYPE_INT8:
|
||||
printf(" %s:%s%d%s\n", cfg->option, blank, *((int8_t *)cfg->ptr), tsGlobalUnit[cfg->unitType]);
|
||||
break;
|
||||
case TAOS_CFG_VTYPE_INT16:
|
||||
printf(" %s:%s%d%s\n", cfg->option, blank, *((int16_t *)cfg->ptr), tsGlobalUnit[cfg->unitType]);
|
||||
break;
|
||||
|
|
|
@ -64,10 +64,10 @@ typedef struct {
|
|||
} SLogObj;
|
||||
|
||||
int32_t tsLogKeepDays = 0;
|
||||
int32_t tsAsyncLog = 1;
|
||||
int8_t tsAsyncLog = 1;
|
||||
float tsTotalLogDirGB = 0;
|
||||
float tsAvailLogDirGB = 0;
|
||||
float tsMinimalLogDirGB = 0.1f;
|
||||
float tsMinimalLogDirGB = 1.0f;
|
||||
#ifdef _TD_POWER_
|
||||
char tsLogDir[TSDB_FILENAME_LEN] = "/var/log/power";
|
||||
#else
|
||||
|
|
|
@ -280,10 +280,13 @@ bool tSkipListIterNext(SSkipListIterator *iter) {
|
|||
tSkipListRLock(pSkipList);
|
||||
|
||||
if (iter->order == TSDB_ORDER_ASC) {
|
||||
if (iter->cur == pSkipList->pTail) {
|
||||
// no data in the skip list
|
||||
if (iter->cur == pSkipList->pTail || iter->next == NULL) {
|
||||
iter->cur = pSkipList->pTail;
|
||||
tSkipListUnlock(pSkipList);
|
||||
return false;
|
||||
}
|
||||
|
||||
iter->cur = SL_NODE_GET_FORWARD_POINTER(iter->cur, 0);
|
||||
|
||||
// a new node is inserted into between iter->cur and iter->next, ignore it
|
||||
|
@ -295,9 +298,11 @@ bool tSkipListIterNext(SSkipListIterator *iter) {
|
|||
iter->step++;
|
||||
} else {
|
||||
if (iter->cur == pSkipList->pHead) {
|
||||
iter->cur = pSkipList->pHead;
|
||||
tSkipListUnlock(pSkipList);
|
||||
return false;
|
||||
}
|
||||
|
||||
iter->cur = SL_NODE_GET_BACKWARD_POINTER(iter->cur, 0);
|
||||
|
||||
// a new node is inserted into between iter->cur and iter->next, ignore it
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue