Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
f44eea86
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
f44eea86
编写于
9月 17, 2020
作者:
S
Shengliang Guan
提交者:
GitHub
9月 17, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3558 from taosdata/develop
Merge from develop into feature/query
上级
9466a68e
455f9f87
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
198 addition
and
160 deletion
+198
-160
alert/cmd/alert/install_driver.sh
alert/cmd/alert/install_driver.sh
+16
-19
alert/cmd/alert/main.go
alert/cmd/alert/main.go
+2
-2
alert/release.sh
alert/release.sh
+20
-7
documentation20/webdocs/markdowndocs/Connections with other Tools-ch.md
...0/webdocs/markdowndocs/Connections with other Tools-ch.md
+1
-1
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
+3
-3
documentation20/webdocs/markdowndocs/cluster-ch.md
documentation20/webdocs/markdowndocs/cluster-ch.md
+97
-57
src/client/inc/tsclient.h
src/client/inc/tsclient.h
+2
-2
src/client/src/tscFunctionImpl.c
src/client/src/tscFunctionImpl.c
+2
-2
src/client/src/tscSubquery.c
src/client/src/tscSubquery.c
+1
-1
src/common/src/tglobal.c
src/common/src/tglobal.c
+0
-11
src/kit/shell/src/shellEngine.c
src/kit/shell/src/shellEngine.c
+4
-2
src/plugins/http/src/httpContext.c
src/plugins/http/src/httpContext.c
+0
-2
src/plugins/http/src/httpRestJson.c
src/plugins/http/src/httpRestJson.c
+12
-16
src/plugins/http/src/httpServer.c
src/plugins/http/src/httpServer.c
+37
-34
src/util/src/tlog.c
src/util/src/tlog.c
+1
-1
未找到文件。
alert/cmd/alert/install_driver.sh
100644 → 100755
浏览文件 @
f44eea86
...
...
@@ -9,9 +9,7 @@ set -e
script_dir
=
$(
dirname
$(
readlink
-f
"
$0
"
))
# Dynamic directory
lib_link_dir
=
"/usr/lib"
#install main path
install_main_dir
=
"/usr/local/taos"
lib64_link_dir
=
"/usr/lib64"
# Color setting
RED
=
'\033[0;31m'
...
...
@@ -25,24 +23,23 @@ if command -v sudo > /dev/null; then
csudo
=
"sudo"
fi
function
clean_driver
()
{
${
csudo
}
rm
-f
/usr/lib/libtaos.so
||
:
}
function
install_driver
()
{
echo
-e
"
${
GREEN
}
Start to install TDengine client driver ...
${
NC
}
"
#create install main dir and all sub dir
${
csudo
}
mkdir
-p
${
install_main_dir
}
${
csudo
}
mkdir
-p
${
install_main_dir
}
/driver
${
csudo
}
rm
-f
${
lib_link_dir
}
/libtaos.
*
||
:
${
csudo
}
cp
-rf
${
script_dir
}
/driver/
*
${
install_main_dir
}
/driver
&&
${
csudo
}
chmod
777
${
install_main_dir
}
/driver/
*
${
csudo
}
ln
-s
${
install_main_dir
}
/driver/libtaos.
*
${
lib_link_dir
}
/libtaos.so.1
${
csudo
}
ln
-s
${
lib_link_dir
}
/libtaos.so.1
${
lib_link_dir
}
/libtaos.so
echo
echo
-e
"
\0
33[44;32;1mTDengine client driver is successfully installed!
${
NC
}
"
if
[[
-d
${
lib_link_dir
}
&&
!
-e
${
lib_link_dir
}
/libtaos.so
]]
;
then
echo
-e
"
${
GREEN
}
Start to install TDengine client driver ...
${
NC
}
"
${
csudo
}
ln
-s
${
script_dir
}
/driver/libtaos.
*
${
lib_link_dir
}
/libtaos.so.1
||
:
${
csudo
}
ln
-s
${
lib_link_dir
}
/libtaos.so.1
${
lib_link_dir
}
/libtaos.so
||
:
if
[[
-d
${
lib64_link_dir
}
&&
!
-e
${
lib64_link_dir
}
/libtaos.so
]]
;
then
${
csudo
}
ln
-s
${
script_dir
}
/driver/libtaos.
*
${
lib64_link_dir
}
/libtaos.so.1
||
:
${
csudo
}
ln
-s
${
lib64_link_dir
}
/libtaos.so.1
${
lib64_link_dir
}
/libtaos.so
||
:
fi
echo
echo
-e
"
${
GREEN
}
TDengine client driver is successfully installed!
${
NC
}
"
else
echo
-e
"
${
GREEN
}
TDengine client driver already exists, Please confirm whether the alert version matches the client driver version!
${
NC
}
"
fi
}
install_driver
alert/cmd/alert/main.go
浏览文件 @
f44eea86
...
...
@@ -119,7 +119,7 @@ WantedBy=multi-user.target
return
nil
}
const
version
=
"TDengine alert v2.0.0.1
"
var
version
=
"2.0.0.1s
"
func
main
()
{
var
(
...
...
@@ -133,7 +133,7 @@ func main() {
flag
.
Parse
()
if
showVersion
{
fmt
.
Println
(
version
)
fmt
.
Println
(
"TDengine alert v"
+
version
)
return
}
...
...
alert/release.sh
浏览文件 @
f44eea86
...
...
@@ -6,9 +6,9 @@ set -e
# set parameters by default value
cpuType
=
amd64
# [armv6l | arm64 | amd64 | 386]
osType
=
linux
# [linux | darwin | windows]
version
=
""
declare
-A
archMap
=([
"armv6l"
]=
"arm"
[
"arm64"
]=
"arm64"
[
"amd64"
]=
"x64"
[
"386"
]=
"x86"
)
while
getopts
"h:c:o:"
arg
while
getopts
"h:c:o:
n:
"
arg
do
case
$arg
in
c
)
...
...
@@ -19,6 +19,10 @@ do
#echo "osType=$OPTARG"
osType
=
$(
echo
$OPTARG
)
;;
n
)
#echo "version=$OPTARG"
version
=
$(
echo
$OPTARG
)
;;
h
)
echo
"Usage:
`
basename
$0
`
-c [armv6l | arm64 | amd64 | 386] -o [linux | darwin | windows]"
exit
0
...
...
@@ -30,18 +34,27 @@ do
esac
done
if
[
"
$version
"
==
""
]
;
then
echo
"Please input the correct version!"
exit
1
fi
startdir
=
$(
pwd
)
scriptdir
=
$(
dirname
$(
readlink
-f
$0
))
cd
${
scriptdir
}
/cmd/alert
version
=
$(
grep
'const version ='
main.go |
awk
'{print $NF}'
)
version
=
${
version
%\
"}
version=
${
version
:1
}
echo
"cpuType=
${
cpuType
}
"
echo
"osType=
${
osType
}
"
echo
"version=
${
version
}
"
GOOS=
${
osType
}
GOARCH=
${
cpuType
}
go build
GOOS
=
${
osType
}
GOARCH
=
${
cpuType
}
go build
-ldflags
'-X main.version='
${
version
}
mkdir
-p
TDengine-alert/driver
cp
alert alert.cfg install_driver.sh ./TDengine-alert/.
cp
../../../debug/build/lib/libtaos.so.
${
version
}
./TDengine-alert/driver/.
chmod
777 ./TDengine-alert/install_driver.sh
tar
-I
'gzip -9'
-cf
${
startdir
}
/TDengine-alert-
${
version
}
-
${
osType
^
}
-
${
archMap
[
${
cpuType
}
]
}
.tar.gz TDengine-alert/
rm
-rf
./TDengine-alert
tar -I 'gzip -9' -cf
${
startdir
}
/TDengine-alert-
${
version
}
-
${
osType
^
}
-
${
archMap
[
${
cpuType
}
]
}
.tar.gz alert alert.cfg install_driver.sh driver/
documentation20/webdocs/markdowndocs/Connections with other Tools-ch.md
浏览文件 @
f44eea86
...
...
@@ -11,7 +11,7 @@ TDengine能够与开源数据可视化系统[Grafana](https://www.grafana.com/)
### 配置Grafana
TDengine的Grafana插件在安装包的/usr/local/taos/connector/grafana目录下。
TDengine的Grafana插件在安装包的/usr/local/taos/connector/grafana
plugin
目录下。
以CentOS 7.2操作系统为例,将tdengine目录拷贝到/var/lib/grafana/plugins目录下,重新启动grafana即可。
...
...
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
浏览文件 @
f44eea86
# TDengine 2.0 错误码以及对应的十进制码
|
Code | bit | error code | 错误描述 | 十进制错误码
|
|
状态码 | 模 | 错误码(十六进制) | 错误描述 | 错误码(十进制)
|
|-----------------------| :---: | :---------: | :------------------------ | ---------------- |
|TSDB_CODE_RPC_ACTION_IN_PROGRESS| 0 | 0x0001| "Action in progress"| -2147483647|
|TSDB_CODE_RPC_AUTH_REQUIRED| 0 | 0x0002 | "Authentication required"| -2147483646|
...
...
@@ -87,7 +87,7 @@
|TSDB_CODE_MND_INVALID_ACCT_OPTION| 0 | 0x0342 | "Invalid account options"| -2147482814|
|TSDB_CODE_MND_USER_ALREADY_EXIST| 0 | 0x0350 | "User already exists"| -2147482800|
|TSDB_CODE_MND_INVALID_USER |0 | 0x0351 | "Invalid user" |-2147482799|
|TSDB_CODE_MND_INVALID_USER_FORMAT|
|
0 |0x0352 |"Invalid user format" |-2147482798|
|TSDB_CODE_MND_INVALID_USER_FORMAT|
0 |0x0352 |"Invalid user format" |-2147482798|
|TSDB_CODE_MND_INVALID_PASS_FORMAT| 0| 0x0353 | "Invalid password format"| -2147482797|
|TSDB_CODE_MND_NO_USER_FROM_CONN| 0 | 0x0354 | "Can not get user from conn"| -2147482796|
|TSDB_CODE_MND_TOO_MANY_USERS| 0 | 0x0355| "Too many users"| -2147482795|
...
...
@@ -107,7 +107,7 @@
|TSDB_CODE_MND_DB_NOT_SELECTED| 0 | 0x0380 | "Database not specified or available"| -2147482752|
|TSDB_CODE_MND_DB_ALREADY_EXIST| 0 | 0x0381 | "Database already exists"| -2147482751|
|TSDB_CODE_MND_INVALID_DB_OPTION| 0 | 0x0382 | "Invalid database options"| -2147482750|
|TSDB_CODE_MND_INVALID_DB|
|
0 | 0x0383 | "Invalid database name"| -2147482749|
|TSDB_CODE_MND_INVALID_DB| 0 | 0x0383 | "Invalid database name"| -2147482749|
|TSDB_CODE_MND_MONITOR_DB_FORBIDDEN| 0 | 0x0384 | "Cannot delete monitor database"| -2147482748|
|TSDB_CODE_MND_TOO_MANY_DATABASES| 0| 0x0385 | "Too many databases for account"| -2147482747|
|TSDB_CODE_MND_DB_IN_DROPPING| 0 | 0x0386| "Database not available" |-2147482746|
...
...
documentation20/webdocs/markdowndocs/cluster-ch.md
浏览文件 @
f44eea86
# TDengine 集群安装、管理
多个
taosd的运行实例可以组成一个集群,以保证TDengine的高可靠运行,并提供水平扩展能力。要了解TDengine 2.0的集群管理,需要对集群的基本概念有所了解,请看TDengine 2.0整体架构一章。而且在安装集群之前,请按照
[
《立即开始》
](
https://www.taosdata.com/cn/getting-started20/
)
一章安装并体验过
单节点功能。
多个
TDengine服务器,也就是多个taosd的运行实例可以组成一个集群,以保证TDengine的高可靠运行,并提供水平扩展能力。要了解TDengine 2.0的集群管理,需要对集群的基本概念有所了解,请看TDengine 2.0整体架构一章。而且在安装集群之前,先请按照
[
《立即开始》
](
https://www.taosdata.com/cn/getting-started20/
)
一章安装并体验
单节点功能。
集群的每个
节点是由End Point来唯一标识的,End Point是由FQDN(Fully Qualified Domain Name)外加Port组成,比如 h1.taosdata.com:6030。一般FQDN就是服务器的hostname,可通过Linux命令
`hostname -f`
获取,FQDN配置参考:
[
一篇文章说清楚TDengine的FQDN
](
https://www.taosdata.com/blog/2020/09/11/1824.html
)
。端口是这个节点对外服务的端口号,缺省是6030,但可以通过taos.cfg里配置参数serverPort进行修改。一个
节点可能配置了多个hostname, TDengine会自动获取第一个,但也可以通过taos.cfg里配置参数fqdn进行指定。如果习惯IP地址直接访问,可以将参数fqdn设置为本节点的IP地址。
集群的每个
数据节点是由End Point来唯一标识的,End Point是由FQDN(Fully Qualified Domain Name)外加Port组成,比如 h1.taosdata.com:6030。一般FQDN就是服务器的hostname,可通过Linux命令
`hostname -f`
获取,FQDN配置参考:
[
一篇文章说清楚TDengine的FQDN
](
https://www.taosdata.com/blog/2020/09/11/1824.html
)
。端口是这个数据节点对外服务的端口号,缺省是6030,但可以通过taos.cfg里配置参数serverPort进行修改。一个物理
节点可能配置了多个hostname, TDengine会自动获取第一个,但也可以通过taos.cfg里配置参数fqdn进行指定。如果习惯IP地址直接访问,可以将参数fqdn设置为本节点的IP地址。
TDengine的集群管理极其简单,除添加和删除节点需要人工干预之外,其他全部是自动完成,最大程度的降低了运维的工作量。本章对集群管理的操作做详细的描述。
## 准备工作
**第一步**
:如果搭建集群的节点中,存有之前的测试数据、装过1.X的版本,或者装过其他版本的TDengine,请先将其删除,并清空所有数据,具体步骤请参考博客
[
《TDengine多种安装包的安装和卸载》
](
https://www.taosdata.com/blog/2019/08/09/566.html
)
**第零步**
:规划集群所有物理节点的FQDN,将规划好的FQDN分别添加到每个物理节点的/etc/hostname;修改每个物理节点的/etc/hosts,将所有集群物理节点的IP与FQDN的对应添加好【如部署了DNS,请联系网络管理员在DNS上做好相关配置】;
**第一步**
:如果搭建集群的物理节点中,存有之前的测试数据、装过1.X的版本,或者装过其他版本的TDengine,请先将其删除,并清空所有数据,具体步骤请参考博客
[
《TDengine多种安装包的安装和卸载》
](
https://www.taosdata.com/blog/2019/08/09/566.html
)
**注意1:**
因为FQDN的信息会写进文件,如果之前没有配置或者更改FQDN,且启动了TDengine。请一定在确保数据无用或者备份的前提下,清理一下之前的数据(rm -rf /var/lib/taos/);
**注意2:**
客户端也需要配置,确保它可以正确解析每个节点的FQDN配置,不管是通过DNS服务,还是 Host 文件。
**第二步**
:建议关闭防火墙,至少保证端口:6030 - 6042的TCP和UDP端口都是开放的。
**强烈建议**
先关闭防火墙,集群搭建完毕之后,再来配置端口;
**第二步**
:建议关闭
所有物理节点的
防火墙,至少保证端口:6030 - 6042的TCP和UDP端口都是开放的。
**强烈建议**
先关闭防火墙,集群搭建完毕之后,再来配置端口;
**第三步**
:在所有节点安装TDengine,且版本必须是一致的,
**但不要启动taosd**
;
**第三步**
:在所有节点安装TDengine,且版本必须是一致的,
**但不要启动taosd**
。安装时,提示输入是否要加入一个已经存在的TDengine集群时,第一个物理节点直接回车创建新集群,后续物理节点则输入该集群任何一个在线的物理节点的FQDN:端口号(默认6030)
;
**第四步**
:检查
、配置所有节点的FQDN
:
**第四步**
:检查
所有数据节点,以及应用所在物理节点的网络设置
:
1.
每个
节点上执行命令
`hostname -f`
,查看和确认所有节点的hostname是不相同的
;
2.
每个
节点上执行
`ping host`
, 其中host是其他节点的hostname, 看能否ping通其它节点; 如果不能ping通,需要检查网络设置, 或/etc/hosts文件,或DNS的配置。如果无法ping通,是无法组成集群的。
3.
每个
节点的FQDN
就是输出的hostname外加端口号,比如h1.taosdata.com:6030
1.
每个
物理节点上执行命令
`hostname -f`
,查看和确认所有节点的hostname是不相同的(应用驱动所在节点无需做此项检查)
;
2.
每个
物理节点上执行
`ping host`
, 其中host是其他物理节点的hostname, 看能否ping通其它物理节点; 如果不能ping通,需要检查网络设置, 或/etc/hosts文件(Windows系统默认路径为C:
\W
indows
\s
ystem32
\d
rivers
\e
tc
\h
osts),或DNS的配置。如果无法ping通,是无法组成集群的;
3.
每个
数据节点的End Point
就是输出的hostname外加端口号,比如h1.taosdata.com:6030
**第五步**
:修改TDengine的配置文件(所有节点的文件/etc/taos/taos.cfg都需要修改)。假设准备启动的第一个
节点End Point为 h1.taosdata.com:6030, 那么以下几个参数与集群相关
:
**第五步**
:修改TDengine的配置文件(所有节点的文件/etc/taos/taos.cfg都需要修改)。假设准备启动的第一个
数据节点End Point为 h1.taosdata.com:6030, 其与集群配置相关参数如下
:
```
// firstEp
集群中所有节点的配置都是一致的,对其第一次访问后,就获得了整个集群的信息
// firstEp
是每个数据节点首次启动后连接的第一个数据节点
firstEp h1.taosdata.com:6030
// 配置本节点的FQDN,如果本机只有一个hostname, 无需配置
// 配置本
数据
节点的FQDN,如果本机只有一个hostname, 无需配置
fqdn h1.taosdata.com
// 配置本节点的端口号,缺省是6030
// 配置本
数据
节点的端口号,缺省是6030
serverPort 6030
// 服务端节点数为偶数的时候,需要配置,请参考《Arbitrator的使用》的部分
arbitrator ha.taosdata.com:6042
```
一定要修改的参数是firstEp, 其他参数可不做任何修改,除非你很清楚为什么要修改。
一定要修改的参数是firstEp和fqdn, 其他参数可不做任何修改,除非你很清楚为什么要修改。
**加入到集群中的数据节点dnode,涉及集群相关的下表11项参数必须完全相同,否则不能成功加入到集群中。**
|
**#**
|
**配置参数名称**
|
**含义**
|
| ----- | ------------------ | ---------------------------------------- |
| 1 | numOfMnodes | 系统中管理节点个数 |
| 2 | mnodeEqualVnodeNum | 一个mnode等同于vnode消耗的个数 |
| 3 | offlineThreshold | dnode离线阈值,超过该时间将导致Dnode离线 |
| 4 | statusInterval | dnode向mnode报告状态时长 |
| 5 | arbitrator | 系统中裁决器的end point |
| 6 | timezone | 时区 |
| 7 | locale | 系统区位信息及编码格式 |
| 8 | charset | 字符集编码 |
| 9 | balance | 是否启动负载均衡 |
| 10 | maxTablesPerVnode | 每个vnode中能够创建的最大表个数 |
| 11 | maxVgroupsPerDb | 每个DB中 能够使用的最大vnode个数 |
## 启动第一个节点
## 启动第一个数据节点
按照
[
《立即开始》
](
https://www.taosdata.com/cn/getting-started20/
)
里的指示,启动第一个数据节点,例如h1.taosdata.com,然后执行taos, 启动taos shell,从shell里执行命令"show dnodes;",如下所示:
按照
[
《立即开始》
](
https://www.taosdata.com/cn/getting-started20/
)
里的指示,启动第一个节点h1.taosdata.com,然后执行taos, 启动taos shell,从shell里执行命令"show dnodes;",如下所示:
```
Welcome to the TDengine shell from Linux, Client Version:2.0.0.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
...
...
@@ -55,74 +76,86 @@ Query OK, 1 row(s) in set (0.006385s)
taos>
```
上述命令里,可以看到这个刚启动的这个节点的End Point是:h1.taos.com:6030
## 启动后续节点
上述命令里,可以看到这个刚启动的这个数据节点的End Point是:h1.taos.com:6030,就是这个新集群的firstEP。
## 启动后续数据节点
将后续的节点添加到现有集群,具体有以下几步:
将后续的
数据
节点添加到现有集群,具体有以下几步:
1.
按照
[
"立即开始“
](
https://www.taosdata.com/cn/getting-started/
)
一章的方法在每个
节点启动taosd。
1.
按照
[
"立即开始“
](
https://www.taosdata.com/cn/getting-started/
)
一章的方法在每个
物理节点启动taosd;
2.
在第一个节点,使用CLI程序taos, 登录进TDengine系统, 执行命令:
2.
在第一个
数据
节点,使用CLI程序taos, 登录进TDengine系统, 执行命令:
```
CREATE DNODE "h2.taos.com:6030";
```
```
CREATE DNODE "h2.taos.com:6030";
```
将新节点的End Point (准备工作中第四步获知的) 添加进集群的EP列表。**"fqdn:port"需要用双引号引起来**,否则出错。请注意将示例的“h2.taos.com:6030" 替换为这个新
节点的End Point。
将新数据节点的End Point (准备工作中第四步获知的) 添加进集群的EP列表。
**"fqdn:port"需要用双引号引起来**
,否则出错。请注意将示例的“h2.taos.com:6030" 替换为这个新数据
节点的End Point。
3.
然后执行命令
```
SHOW DNODES;
```
```
SHOW DNODES;
```
查看新节点是否被成功加入。如果该被加入的节点处于离线状态,请做两个检查
- 查看该节点的taosd是否正常工作,如果没有正常运行,需要先检查为什么
- 查看该节点taosd日志文件taosdlog.0里前面几行日志(一般在/var/log/taos目录),看日志里输出的该节点fqdn以及端口号是否为刚添加的End Point。如果不一致,需要将正确的End Point添加进去。
查看新节点是否被成功加入。如果该被加入的数据节点处于离线状态,请做两个检查
按照上述步骤可以源源不断的将新的节点加入到集群。
-
查看该数据节点的taosd是否正常工作,如果没有正常运行,需要先检查为什么
-
查看该数据节点taosd日志文件taosdlog.0里前面几行日志(一般在/var/log/taos目录),看日志里输出的该数据节点fqdn以及端口号是否为刚添加的End Point。如果不一致,需要将正确的End Point添加进去。
按照上述步骤可以源源不断的将新的数据节点加入到集群。
**提示:**
-
firstEp这个参数仅仅在该节点第一次加入集群时有作用,加入集群后,该节点会保存最新的mnode的End Point列表,不再依赖这两个参数。
-
两个没有配置firstEp参数的dnode启动后,会独立运行起来。这个时候,无法将其中一个节点加入到另外一个节点,形成集群。
**无法将两个独立的集群合并成为新的集群**
。
-
任何已经加入集群在线的数据节点,都可以作为后续待加入节点的firstEP。
-
firstEp这个参数仅仅在该数据节点首次加入集群时有作用,加入集群后,该数据节点会保存最新的mnode的End Point列表,不再依赖这个参数。
-
两个没有配置firstEp参数的数据节点dnode启动后,会独立运行起来。这个时候,无法将其中一个数据节点加入到另外一个数据节点,形成集群。
**无法将两个独立的集群合并成为新的集群**
。
## 数据节点管理
##
节点管理
##
# 添加数据节点
### 添加节点
执行CLI程序taos, 使用root账号登录进系统, 执行:
```
CREATE DNODE "fqdn:port";
```
将新节点的End Point添加进集群的EP列表。
**"fqdn:port"需要用双引号引起来**
,否则出错。一个节点对外服务的fqdn和port可以通过配置文件taos.cfg进行配置,缺省是自动获取。
### 删除节点
将新数据节点的End Point添加进集群的EP列表。
**"fqdn:port"需要用双引号引起来**
,否则出错。一个数据节点对外服务的fqdn和port可以通过配置文件taos.cfg进行配置,缺省是自动获取。【强烈不建议用自动获取方式来配置FQDN,可能导致生成的数据节点的End Point不是所期望的】
### 删除数据节点
执行CLI程序taos, 使用root账号登录进TDengine系统,执行:
```
DROP DNODE "fqdn:port";
```
其中fqdn是被删除的节点的FQDN,port是其对外服务器的端口号
### 查看节点
### 查看数据节点
执行CLI程序taos,使用root账号登录进TDengine系统,执行:
```
SHOW DNODES;
```
它将列出集群中所有的dnode,每个dnode的fqdn:port, 状态(ready, offline等),vnode数目,还未使用的vnode数目等信息。在添加或删除一个节点后,可以使用该命令查看。
它将列出集群中所有的dnode,每个dnode的fqdn:port, 状态(ready, offline等),vnode数目,还未使用的vnode数目等信息。在添加或删除一个数据节点后,可以使用该命令查看。
### 查看虚拟节点组
为充分利用多核技术,并提供scalability,数据需要分片处理。因此TDengine会将一个DB的数据切分成多份,存放在多个vnode里。这些vnode可能分布在多个dnode里,这样就实现了水平扩展。一个vnode仅仅属于一个DB,但一个DB可以有多个vnode。vnode的是mnode根据当前系统资源的情况,自动进行分配的,无需任何人工干预。
为充分利用多核技术,并提供scalability,数据需要分片处理。因此TDengine会将一个DB的数据切分成多份,存放在多个vnode里。这些vnode可能分布在多个
数据节点
dnode里,这样就实现了水平扩展。一个vnode仅仅属于一个DB,但一个DB可以有多个vnode。vnode的是mnode根据当前系统资源的情况,自动进行分配的,无需任何人工干预。
执行CLI程序taos,使用root账号登录进TDengine系统,执行:
```
SHOW VGROUPS;
```
## vnode的高可用性
TDengine通过多副本的机制来提供系统的高可用性,包括vnode和mnode的高可用性。
vnode的副本数是与DB关联的,一个集群里可以有多个DB,根据运营的需求,每个DB可以配置不同的副本数。创建数据库时,通过参数replica 指定副本数(缺省为1)。如果副本数为1,系统的可靠性无法保证,只要数据所在的节点宕机,就将无法提供服务。集群的节点数必须大于等于副本数,否则创建表时将返回错误“more dnodes are needed"。比如下面的命令将创建副本数为3的数据库demo:
...
...
@@ -130,21 +163,25 @@ vnode的副本数是与DB关联的,一个集群里可以有多个DB,根据
```
CREATE DATABASE demo replica 3;
```
一个DB里的数据会被切片分到多个vnode group,vnode group里的vnode数目就是DB的副本数,同一个vnode group里各vnode的数据是完全一致的。为保证高可用性,vnode group里的vnode一定要分布在不同的dnode里(实际部署时,需要在不同的物理机上),只要一个vgroup里超过半数的vnode处于工作状态,这个vgroup就能正常的对外服务。
一个dnode里可能有多个DB的数据,因此一个dnode离线时,可能会影响到多个DB。如果一个vnode group里的一半或一半以上的vnode不工作,那么该vnode group就无法对外服务,无法插入或读取数据,这样会影响到它所属的DB的一部分表的读写操作。
一个DB里的数据会被切片分到多个vnode group,vnode group里的vnode数目就是DB的副本数,同一个vnode group里各vnode的数据是完全一致的。为保证高可用性,vnode group里的vnode一定要分布在不同的数据节点dnode里(实际部署时,需要在不同的物理机上),只要一个vgroup里超过半数的vnode处于工作状态,这个vgroup就能正常的对外服务。
一个数据节点dnode里可能有多个DB的数据,因此一个dnode离线时,可能会影响到多个DB。如果一个vnode group里的一半或一半以上的vnode不工作,那么该vnode group就无法对外服务,无法插入或读取数据,这样会影响到它所属的DB的一部分表的读写操作。
因为vnode的引入,无法简单的给出结论:“集群中过半
dnode工作,集群就应该工作”。但是对于简单的情形,很好下结论。比如副本数为3,只有三个dnode,那如果仅有一个节点不工作,整个集群还是可以正常工作的,但如果有两个
节点不工作,那整个集群就无法正常工作了。
因为vnode的引入,无法简单的给出结论:“集群中过半
数据节点dnode工作,集群就应该工作”。但是对于简单的情形,很好下结论。比如副本数为3,只有三个dnode,那如果仅有一个节点不工作,整个集群还是可以正常工作的,但如果有两个数据
节点不工作,那整个集群就无法正常工作了。
## Mnode的高可用性
TDengine集群是由mnode (taosd的一个模块,逻辑节点) 负责管理的,为保证mnode的高可用,可以配置多个mnode副本,副本数由系统配置参数numOfMnodes决定,有效范围为1-3。为保证元数据的强一致性,mnode副本之间是通过同步的方式进行数据复制的。
一个集群有多个dnode, 但一个dnode至多运行一个mnode实例。多个dnode情况下,哪个dnode可以作为mnode呢?这是完全由系统根据整个系统资源情况,自动指定的。用户可通过CLI程序taos,在TDengine的console里,执行如下命令:
TDengine集群是由mnode (taosd的一个模块,管理节点) 负责管理的,为保证mnode的高可用,可以配置多个mnode副本,副本数由系统配置参数numOfMnodes决定,有效范围为1-3。为保证元数据的强一致性,mnode副本之间是通过同步的方式进行数据复制的。
一个集群有多个数据节点dnode, 但一个dnode至多运行一个mnode实例。多个dnode情况下,哪个dnode可以作为mnode呢?这是完全由系统根据整个系统资源情况,自动指定的。用户可通过CLI程序taos,在TDengine的console里,执行如下命令:
```
SHOW MNODES;
```
来查看mnode列表,该列表将列出mnode所处的dnode的End Point和角色(master, slave, unsynced 或offline)。
当集群中第一个
节点启动时,该节点一定会运行一个mnode实例,否则该
dnode无法正常工作,因为一个系统是必须有至少一个mnode的。如果numOfMnodes配置为2,启动第二个dnode时,该dnode也将运行一个mnode实例。
当集群中第一个
数据节点启动时,该数据节点一定会运行一个mnode实例,否则该数据节点
dnode无法正常工作,因为一个系统是必须有至少一个mnode的。如果numOfMnodes配置为2,启动第二个dnode时,该dnode也将运行一个mnode实例。
为保证mnode服务的高可用性,numOfMnodes必须设置为2或更大。因为mnode保存的元数据必须是强一致的,如果numOfMnodes大于2,复制参数quorum自动设为2,也就是说,至少要保证有两个副本写入数据成功,才通知客户端应用写入成功。
...
...
@@ -154,22 +191,25 @@ SHOW MNODES;
有三种情况,将触发负载均衡,而且都无需人工干预。
-
当一个新节点添加进集群时,系统将自动触发负载均衡,一些节点上的数据将被自动转移到新节点上,无需任何人工干预。
-
当一个节点从集群中移除时,系统将自动把该节点上的数据转移到其他节点,无需任何人工干预。
-
如果一个节点过热(数据量过大),系统将自动进行负载均衡,将该节点的一些vnode自动挪到其他节点。
-
当一个新数据节点添加进集群时,系统将自动触发负载均衡,一些节点上的数据将被自动转移到新数据节点上,无需任何人工干预。
-
当一个数据节点从集群中移除时,系统将自动把该数据节点上的数据转移到其他数据节点,无需任何人工干预。
-
如果一个数据节点过热(数据量过大),系统将自动进行负载均衡,将该数据节点的一些vnode自动挪到其他节点。
当上述三种情况发生时,系统将启动一各个数据节点的负载计算,从而决定如何挪动。
当上述三种情况发生时,系统将启动一各个节点的负载计算,从而决定如何挪动。
**【提示】负载均衡由参数balance控制,它决定是否启动自动负载均衡。**
##节点离线处理
如果一个节点离线,TDengine集群将自动检测到。有如下两种情况:
-
改节点离线超过一定时间(taos.cfg里配置参数offlineThreshold控制时长),系统将自动把该节点删除,产生系统报警信息,触发负载均衡流程。如果该被删除的节点重现上线时,它将无法加入集群,需要系统管理员重新将其添加进集群才会开始工作。
## 数据节点离线处理
如果一个数据节点离线,TDengine集群将自动检测到。有如下两种情况:
-
该数据节点离线超过一定时间(taos.cfg里配置参数offlineThreshold控制时长),系统将自动把该数据节点删除,产生系统报警信息,触发负载均衡流程。如果该被删除的数据节点重现上线时,它将无法加入集群,需要系统管理员重新将其添加进集群才会开始工作。
-
离线后,在offlineThreshold的时长内重新上线,系统将自动启动数据恢复流程,等数据完全恢复后,该节点将开始正常工作。
**注意:**
如果一个虚拟节点组(包括mnode组)里
每个节点都处于离线或unsynced状态,必须等该虚拟节点组里的所有节点都上线、都能交换状态信息后,才能选出Master,该虚拟节点组才能对外提供服务。比如整个集群有3个节点,副本数为3,如果3个节点都宕机,然后2个节点重启,是无法工作的,只有等3个
节点都重启成功,才能对外服务。
**注意:**
如果一个虚拟节点组(包括mnode组)里
所归属的每个数据节点都处于离线或unsynced状态,必须等该虚拟节点组里的所有数据节点都上线、都能交换状态信息后,才能选出Master,该虚拟节点组才能对外提供服务。比如整个集群有3个数据节点,副本数为3,如果3个数据节点都宕机,然后2个数据节点重启,是无法工作的,只有等3个数据
节点都重启成功,才能对外服务。
## Arbitrator的使用
如果副本数为偶数,当一个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服务器运行它即可。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数
`-p`
可以指定其对外服务的端口号,缺省是6042。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的arbitrator。
src/client/inc/tsclient.h
浏览文件 @
f44eea86
...
...
@@ -334,7 +334,7 @@ typedef struct STscObj {
struct
SSqlStream
*
streamList
;
void
*
pDnodeConn
;
pthread_mutex_t
mutex
;
T_REF_DECLARE
()
;
T_REF_DECLARE
()
}
STscObj
;
typedef
struct
SSqlObj
{
...
...
@@ -470,7 +470,7 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
int32_t
type
=
pInfo
->
pSqlExpr
->
resType
;
int32_t
bytes
=
pInfo
->
pSqlExpr
->
resBytes
;
char
*
pData
=
pRes
->
data
+
pInfo
->
pSqlExpr
->
offset
*
pRes
->
numOfRows
+
bytes
*
pRes
->
row
;
char
*
pData
=
pRes
->
data
+
(
int32_t
)(
pInfo
->
pSqlExpr
->
offset
*
pRes
->
numOfRows
+
bytes
*
pRes
->
row
)
;
// user defined constant value output columns
if
(
TSDB_COL_IS_UD_COL
(
pInfo
->
pSqlExpr
->
colInfo
.
flag
))
{
...
...
src/client/src/tscFunctionImpl.c
浏览文件 @
f44eea86
...
...
@@ -2460,11 +2460,11 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
if
(
pInfo
->
stage
==
0
)
{
if
(
pCtx
->
preAggVals
.
isSet
)
{
if
(
pInfo
->
minval
>
pCtx
->
preAggVals
.
statis
.
min
)
{
pInfo
->
minval
=
pCtx
->
preAggVals
.
statis
.
min
;
pInfo
->
minval
=
(
double
)
pCtx
->
preAggVals
.
statis
.
min
;
}
if
(
pInfo
->
maxval
<
pCtx
->
preAggVals
.
statis
.
max
)
{
pInfo
->
maxval
=
pCtx
->
preAggVals
.
statis
.
max
;
pInfo
->
maxval
=
(
double
)
pCtx
->
preAggVals
.
statis
.
max
;
}
pInfo
->
numOfElems
+=
(
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
);
...
...
src/client/src/tscSubquery.c
浏览文件 @
f44eea86
...
...
@@ -1950,7 +1950,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) {
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
pSql
->
numOfSubs
=
taosArrayGetSize
(
pCmd
->
pDataBlocks
);
pSql
->
numOfSubs
=
(
uint16_t
)
taosArrayGetSize
(
pCmd
->
pDataBlocks
);
assert
(
pSql
->
numOfSubs
>
0
);
pRes
->
code
=
TSDB_CODE_SUCCESS
;
...
...
src/common/src/tglobal.c
浏览文件 @
f44eea86
...
...
@@ -957,17 +957,6 @@ static void doInitGlobalConfig(void) {
cfg
.
unitType
=
TAOS_CFG_UTYPE_NONE
;
taosInitConfigOption
(
cfg
);
// http configs
cfg
.
option
=
"httpCacheSessions"
;
cfg
.
ptr
=
&
tsHttpCacheSessions
;
cfg
.
valType
=
TAOS_CFG_VTYPE_INT32
;
cfg
.
cfgType
=
TSDB_CFG_CTYPE_B_CONFIG
;
cfg
.
minValue
=
1
;
cfg
.
maxValue
=
100000
;
cfg
.
ptrLength
=
0
;
cfg
.
unitType
=
TAOS_CFG_UTYPE_NONE
;
taosInitConfigOption
(
cfg
);
cfg
.
option
=
"httpEnableRecordSql"
;
cfg
.
ptr
=
&
tsHttpEnableRecordSql
;
cfg
.
valType
=
TAOS_CFG_VTYPE_INT32
;
...
...
src/kit/shell/src/shellEngine.c
浏览文件 @
f44eea86
...
...
@@ -765,7 +765,9 @@ void read_history() {
FILE
*
f
=
fopen
(
f_history
,
"r"
);
if
(
f
==
NULL
)
{
#ifndef WINDOWS
fprintf
(
stderr
,
"Failed to open file %s
\n
"
,
f_history
);
if
(
errno
!=
ENOENT
)
{
fprintf
(
stderr
,
"Failed to open file %s, reason:%s
\n
"
,
f_history
,
strerror
(
errno
));
}
#endif
return
;
}
...
...
@@ -792,7 +794,7 @@ void write_history() {
FILE
*
f
=
fopen
(
f_history
,
"w"
);
if
(
f
==
NULL
)
{
#ifndef WINDOWS
fprintf
(
stderr
,
"Failed to open file %s for write
\n
"
,
f_history
);
fprintf
(
stderr
,
"Failed to open file %s for write
, reason:%s
\n
"
,
f_history
,
strerror
(
errno
)
);
#endif
return
;
}
...
...
src/plugins/http/src/httpContext.c
浏览文件 @
f44eea86
...
...
@@ -131,8 +131,6 @@ HttpContext *httpCreateContext(int32_t fd) {
HttpContext
*
httpGetContext
(
void
*
ptr
)
{
uint64_t
handleVal
=
(
uint64_t
)
ptr
;
HttpContext
**
ppContext
=
taosCacheAcquireByKey
(
tsHttpServer
.
contextCache
,
&
handleVal
,
sizeof
(
HttpContext
*
));
ASSERT
(
ppContext
);
ASSERT
(
*
ppContext
);
if
(
ppContext
)
{
HttpContext
*
pContext
=
*
ppContext
;
...
...
src/plugins/http/src/httpRestJson.c
浏览文件 @
f44eea86
...
...
@@ -87,15 +87,12 @@ bool restBuildSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result,
JsonBuf
*
jsonBuf
=
httpMallocJsonBuf
(
pContext
);
if
(
jsonBuf
==
NULL
)
return
false
;
cmd
->
numOfRows
+=
numOfRows
;
int32_t
num_fields
=
taos_num_fields
(
result
);
TAOS_FIELD
*
fields
=
taos_fetch_fields
(
result
);
for
(
int32_t
k
=
0
;
k
<
numOfRows
;
++
k
)
{
TAOS_ROW
row
=
taos_fetch_row
(
result
);
if
(
row
==
NULL
)
{
cmd
->
numOfRows
--
;
continue
;
}
int32_t
*
length
=
taos_fetch_lengths
(
result
);
...
...
@@ -151,24 +148,23 @@ bool restBuildSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result,
}
// data row array end
httpJsonToken
(
jsonBuf
,
JsonArrEnd
);
}
httpJsonToken
(
jsonBuf
,
JsonArrEnd
);
cmd
->
numOfRows
++
;
if
(
cmd
->
numOfRows
>=
tsRestRowLimit
)
{
httpDebug
(
"context:%p, fd:%d, user:%s, retrieve rows:%d larger than limit:%d, abort retrieve"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
cmd
->
numOfRows
,
tsRestRowLimit
);
return
false
;
}
else
{
if
(
pContext
->
fd
<=
0
)
{
httpError
(
"context:%p, fd:%d, user:%s, connection is closed, abort retrieve"
,
pContext
,
pContext
->
fd
,
pContext
->
user
);
httpError
(
"context:%p, fd:%d, user:%s, conn closed, abort retrieve"
,
pContext
,
pContext
->
fd
,
pContext
->
user
);
return
false
;
}
if
(
cmd
->
numOfRows
>=
tsRestRowLimit
)
{
httpDebug
(
"context:%p, fd:%d, user:%s, retrieve rows:%d larger than limit:%d, abort retrieve"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
cmd
->
numOfRows
,
tsRestRowLimit
);
return
false
;
}
else
{
httpDebug
(
"context:%p, fd:%d, user:%s, total rows:%d retrieved"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
cmd
->
numOfRows
);
return
true
;
}
}
httpDebug
(
"context:%p, fd:%d, user:%s, retrieved row:%d"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
cmd
->
numOfRows
);
return
true
;
}
bool
restBuildSqlTimestampJson
(
HttpContext
*
pContext
,
HttpSqlCmd
*
cmd
,
TAOS_RES
*
result
,
int32_t
numOfRows
)
{
...
...
src/plugins/http/src/httpServer.c
浏览文件 @
f44eea86
...
...
@@ -315,45 +315,48 @@ static bool httpReadData(HttpContext *pContext) {
pContext
->
accessTimes
++
;
pContext
->
lastAccessTime
=
taosGetTimestampSec
();
char
buf
[
HTTP_STEP_SIZE
+
1
]
=
{
0
};
char
buf
[
HTTP_STEP_SIZE
+
1
]
=
{
0
};
int32_t
nread
=
(
int32_t
)
taosReadSocket
(
pContext
->
fd
,
buf
,
HTTP_STEP_SIZE
);
if
(
nread
>
0
)
{
buf
[
nread
]
=
'\0'
;
httpTraceL
(
"context:%p, fd:%d, nread:%d content:%s"
,
pContext
,
pContext
->
fd
,
nread
,
buf
);
int32_t
ok
=
httpParseBuf
(
pParser
,
buf
,
nread
);
if
(
ok
)
{
httpError
(
"context:%p, fd:%d, parse failed, ret:%d code:%d close connect"
,
pContext
,
pContext
->
fd
,
ok
,
pParser
->
parseCode
);
httpSendErrorResp
(
pContext
,
pParser
->
parseCode
);
httpNotifyContextClose
(
pContext
);
return
false
;
}
while
(
1
)
{
int32_t
nread
=
(
int32_t
)
taosReadSocket
(
pContext
->
fd
,
buf
,
HTTP_STEP_SIZE
);
if
(
nread
>
0
)
{
buf
[
nread
]
=
'\0'
;
httpTraceL
(
"context:%p, fd:%d, nread:%d content:%s"
,
pContext
,
pContext
->
fd
,
nread
,
buf
);
int32_t
ok
=
httpParseBuf
(
pParser
,
buf
,
nread
);
if
(
ok
)
{
httpError
(
"context:%p, fd:%d, parse failed, ret:%d code:%d close connect"
,
pContext
,
pContext
->
fd
,
ok
,
pParser
->
parseCode
);
httpSendErrorResp
(
pContext
,
pParser
->
parseCode
);
httpNotifyContextClose
(
pContext
);
return
false
;
}
if
(
pParser
->
parseCode
)
{
httpError
(
"context:%p, fd:%d, parse failed, code:%d close connect"
,
pContext
,
pContext
->
fd
,
pParser
->
parseCode
);
httpSendErrorResp
(
pContext
,
pParser
->
parseCode
);
httpNotifyContextClose
(
pContext
);
return
false
;
}
if
(
pParser
->
parseCode
)
{
httpError
(
"context:%p, fd:%d, parse failed, code:%d close connect"
,
pContext
,
pContext
->
fd
,
pParser
->
parseCode
);
httpSendErrorResp
(
pContext
,
pParser
->
parseCode
);
httpNotifyContextClose
(
pContext
);
return
false
;
}
if
(
!
pParser
->
parsed
)
{
httpTrace
(
"context:%p, fd:%d, read not over yet, len:%d"
,
pContext
,
pContext
->
fd
,
pParser
->
body
.
pos
);
return
false
;
}
else
{
httpDebug
(
"context:%p, fd:%d, totalLen:%d"
,
pContext
,
pContext
->
fd
,
pParser
->
body
.
pos
);
return
true
;
}
}
else
if
(
nread
<
0
)
{
if
(
errno
==
EINTR
||
errno
==
EAGAIN
||
errno
==
EWOULDBLOCK
)
{
httpDebug
(
"context:%p, fd:%d, read from socket error:%d, wait another event"
,
pContext
,
pContext
->
fd
,
errno
);
return
false
;
// later again
if
(
!
pParser
->
parsed
)
{
httpTrace
(
"context:%p, fd:%d, read not finished"
,
pContext
,
pContext
->
fd
);
continue
;
}
else
{
httpDebug
(
"context:%p, fd:%d, bodyLen:%d"
,
pContext
,
pContext
->
fd
,
pParser
->
body
.
pos
);
return
true
;
}
}
else
if
(
nread
<
0
)
{
if
(
errno
==
EINTR
||
errno
==
EAGAIN
||
errno
==
EWOULDBLOCK
)
{
httpDebug
(
"context:%p, fd:%d, read from socket error:%d, wait another event"
,
pContext
,
pContext
->
fd
,
errno
);
return
false
;
// later again
}
else
{
httpError
(
"context:%p, fd:%d, read from socket error:%d, close connect"
,
pContext
,
pContext
->
fd
,
errno
);
return
false
;
}
}
else
{
httpError
(
"context:%p, fd:%d,
read from socket error:%d, close connect"
,
pContext
,
pContext
->
fd
,
errno
);
httpError
(
"context:%p, fd:%d,
nread:%d, wait another event"
,
pContext
,
pContext
->
fd
,
nread
);
return
false
;
}
}
else
{
httpError
(
"context:%p, fd:%d, nread:%d, wait another event"
,
pContext
,
pContext
->
fd
,
nread
);
return
false
;
}
}
src/util/src/tlog.c
浏览文件 @
f44eea86
...
...
@@ -433,7 +433,7 @@ void taosPrintLongString(const char *flags, int32_t dflag, const char *format, .
va_list
argpointer
;
char
buffer
[
MAX_LOGLINE_DUMP_BUFFER_SIZE
];
int32_t
len
;
int32_t
len
;
struct
tm
Tm
,
*
ptm
;
struct
timeval
timeSecs
;
time_t
curTime
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录