Merge branch '3.0' of https://github.com/taosdata/TDengine into fix/TD-30837

This commit is contained in:
54liuyao 2024-08-08 19:30:46 +08:00
commit 3491396d92
72 changed files with 2092 additions and 1122 deletions

Binary file not shown.

View File

@ -1,276 +1,276 @@
--- ---
sidebar_label: 数据 sidebar_label: 数据
title: 零代码数据接入 title: 零代码第三方数据接入
toc_max_heading_level: 4 toc_max_heading_level: 4
--- ---
## 概述 ## 概述
TDengine Enterprise 配备了一个强大的可视化数据管理工具—taosExplorer。借助 taosExplorer用户只须在浏览器中简单配置就能轻松地向 TDengine 提交任务,实现以零代码方式将来自不同数据源的数据无缝导入 TDengine。在导入过程中TDengine 会对数据进行自动提取、过滤和转换以保证导入的数据质量。通过这种零代码数据源接入方式TDengine 成功转型为一个卓越的时序大数据汇聚平台。用户无须部署额外的 ETL 工具,从而大大简化整体架构的设计,提高了数据处理效率。 TDengine Enterprise 配备了一个强大的可视化数据管理工具—taosExplorer。借助 taosExplorer用户只须在浏览器中简单配置就能轻松地向 TDengine 提交任务,实现以零代码方式将来自不同数据源的数据无缝导入 TDengine。在导入过程中TDengine 会对数据进行自动提取、过滤和转换以保证导入的数据质量。通过这种零代码数据源接入方式TDengine 成功转型为一个卓越的时序大数据汇聚平台。用户无须部署额外的 ETL 工具,从而大大简化整体架构的设计,提高了数据处理效率。
下图展示了零代码接入平台的系统架构。 下图展示了零代码接入平台的系统架构。
![零代码数据接入架构图](./data-in.png) ![零代码数据接入架构图](./data-in.png)
## 支持的数据源 ## 支持的数据源
目前 TDengine 支持的数据源如下: 目前 TDengine 支持的数据源如下:
1. Aveva PI System一个工业数据管理和分析平台前身为 OSIsoft PI System它能够实时采集、整合、分析和可视化工业数据助力企业实现智能化决策和精细化管理 1. Aveva PI System一个工业数据管理和分析平台前身为 OSIsoft PI System它能够实时采集、整合、分析和可视化工业数据助力企业实现智能化决策和精细化管理
2. Aveva Historian一个工业大数据分析软件前身为 Wonderware Historian专为工业环境设计用于存储、管理和分析来自各种工业设备、传感器的实时和历史数据。 2. Aveva Historian一个工业大数据分析软件前身为 Wonderware Historian专为工业环境设计用于存储、管理和分析来自各种工业设备、传感器的实时和历史数据。
3. OPC DA/UAOPC 是 Open Platform Communications 的缩写是一种开放式、标准化的通信协议用于不同厂商的自动化设备之间进行数据交换。它最初由微软公司开发旨在解决工业控制领域中不同设备之间互操作性差的问题。OPC 协议最初于 1996 年发布,当时称为 OPC DA Data Access主要用于实时数据采集和控制2006 年OPC 基金会发布了 OPC UA Unified Architecture 标准,它是一种基于服务的面向对象的协议,具有更高的灵活性和可扩展性,已成为 OPC 协议的主流版本。 3. OPC DA/UAOPC 是 Open Platform Communications 的缩写是一种开放式、标准化的通信协议用于不同厂商的自动化设备之间进行数据交换。它最初由微软公司开发旨在解决工业控制领域中不同设备之间互操作性差的问题。OPC 协议最初于 1996 年发布,当时称为 OPC DA Data Access主要用于实时数据采集和控制2006 年OPC 基金会发布了 OPC UA Unified Architecture 标准,它是一种基于服务的面向对象的协议,具有更高的灵活性和可扩展性,已成为 OPC 协议的主流版本。
4. MQTTMessage Queuing Telemetry Transport 的缩写,一种基于发布/订阅模式的轻量级通讯协议,专为低开销、低带宽占用的即时通讯设计,广泛适用于物联网、小型设备、移动应用等领域。 4. MQTTMessage Queuing Telemetry Transport 的缩写,一种基于发布/订阅模式的轻量级通讯协议,专为低开销、低带宽占用的即时通讯设计,广泛适用于物联网、小型设备、移动应用等领域。
5. Kafka由 Apache 软件基金会开发的一个开源流处理平台,主要用于处理实时数据,并提供一个统一、高通量、低延迟的消息系统。它具备高速度、可伸缩性、持久性和分布式设计等特点,使得它能够在每秒处理数十万次的读写操作,支持上千个客户端,同时保持数据的可靠性和可用性。 5. Kafka由 Apache 软件基金会开发的一个开源流处理平台,主要用于处理实时数据,并提供一个统一、高通量、低延迟的消息系统。它具备高速度、可伸缩性、持久性和分布式设计等特点,使得它能够在每秒处理数十万次的读写操作,支持上千个客户端,同时保持数据的可靠性和可用性。
6. OpenTSDB基于 HBase 的分布式、可伸缩的时序数据库。它主要用于存储、索引和提供从大规模集群(包括网络设备、操作系统、应用程序等)中收集的指标数据,使这些数据更易于访问和图形化展示。 6. OpenTSDB基于 HBase 的分布式、可伸缩的时序数据库。它主要用于存储、索引和提供从大规模集群(包括网络设备、操作系统、应用程序等)中收集的指标数据,使这些数据更易于访问和图形化展示。
7. CSVComma Separated Values 的缩写,是一种以逗号分隔的纯文本文件格式,通常用于电子表格或数据库软件。 7. CSVComma Separated Values 的缩写,是一种以逗号分隔的纯文本文件格式,通常用于电子表格或数据库软件。
8. TDengine 2泛指运行 TDengine 2.x 版本的 TDengine 实例。 8. TDengine 2泛指运行 TDengine 2.x 版本的 TDengine 实例。
9. TDengine 3泛指运行 TDengine 3.x 版本的 TDengine 实例。 9. TDengine 3泛指运行 TDengine 3.x 版本的 TDengine 实例。
10. MySQL PostgreSQL Oracle 等关系型数据库。 10. MySQL PostgreSQL Oracle 等关系型数据库。
## 数据提取、过滤和转换 ## 数据提取、过滤和转换
因为数据源可以有多个每个数据源的物理单位可能不一样命名规则也不一样时区也可能不同。为解决这个问题TDengine 内置 ETL 功能,可以从数据源的数据包中解析、提取需要的数据,并进行过滤和转换,以保证写入数据的质量,提供统一的命名空间。具体的功能如下: 因为数据源可以有多个每个数据源的物理单位可能不一样命名规则也不一样时区也可能不同。为解决这个问题TDengine 内置 ETL 功能,可以从数据源的数据包中解析、提取需要的数据,并进行过滤和转换,以保证写入数据的质量,提供统一的命名空间。具体的功能如下:
1. 解析:使用 JSON Path 或正则表达式,从原始消息中解析字段 1. 解析:使用 JSON Path 或正则表达式,从原始消息中解析字段
2. 从列中提取或拆分:使用 split 或正则表达式,从一个原始字段中提取多个字段 2. 从列中提取或拆分:使用 split 或正则表达式,从一个原始字段中提取多个字段
3. 过滤:只有表达式的值为 true 时,消息才会被写入 TDengine 3. 过滤:只有表达式的值为 true 时,消息才会被写入 TDengine
4. 转换:建立解析后的字段和 TDengine 超级表字段之间的转换与映射关系。 4. 转换:建立解析后的字段和 TDengine 超级表字段之间的转换与映射关系。
下面详细讲解数据转换规则 下面详细讲解数据转换规则
### 解析 ### 解析
仅非结构化的数据源需要这个步骤,目前 MQTT 和 Kafka 数据源会使用这个步骤提供的规则来解析非结构化数据,以初步获取结构化数据,即可以以字段描述的行列数据。在 explorer 中您需要提供示例数据和解析规则,来预览解析出以表格呈现的结构化数据。 仅非结构化的数据源需要这个步骤,目前 MQTT 和 Kafka 数据源会使用这个步骤提供的规则来解析非结构化数据,以初步获取结构化数据,即可以以字段描述的行列数据。在 explorer 中您需要提供示例数据和解析规则,来预览解析出以表格呈现的结构化数据。
#### 示例数据 #### 示例数据
![示例数据](./pic/transform-01.png) ![示例数据](./pic/transform-01.png)
如图textarea 输入框中就是示例数据,可以通过三种方式来获取示例数据: 如图textarea 输入框中就是示例数据,可以通过三种方式来获取示例数据:
1. 直接在 textarea 中输入示例数据; 1. 直接在 textarea 中输入示例数据;
2. 点击右侧按钮 “从服务器检索” 则从配置的服务器获取示例数据,并追加到示例数据 textarea 中; 2. 点击右侧按钮 “从服务器检索” 则从配置的服务器获取示例数据,并追加到示例数据 textarea 中;
3. 上传文件,将文件内容追加到示例数据 textarea 中。 3. 上传文件,将文件内容追加到示例数据 textarea 中。
#### 解析<a name="parse"></a> #### 解析<a name="parse"></a>
解析就是通过解析规则,将非结构化字符串解析为结构化数据。消息体的解析规则目前支持 JSON、Regex 和 UDT。 解析就是通过解析规则,将非结构化字符串解析为结构化数据。消息体的解析规则目前支持 JSON、Regex 和 UDT。
##### JSON 解析 ##### JSON 解析
如下 JSON 示例数据,可自动解析出字段:`groupid`、`voltage`、`current`、`ts`、`inuse`、`location`。 如下 JSON 示例数据,可自动解析出字段:`groupid`、`voltage`、`current`、`ts`、`inuse`、`location`。
``` json ``` json
{"groupid": 170001, "voltage": "221V", "current": 12.3, "ts": "2023-12-18T22:12:00", "inuse": true, "location": "beijing.chaoyang.datun"} {"groupid": 170001, "voltage": "221V", "current": 12.3, "ts": "2023-12-18T22:12:00", "inuse": true, "location": "beijing.chaoyang.datun"}
{"groupid": 170001, "voltage": "220V", "current": 12.2, "ts": "2023-12-18T22:12:02", "inuse": true, "location": "beijing.chaoyang.datun"} {"groupid": 170001, "voltage": "220V", "current": 12.2, "ts": "2023-12-18T22:12:02", "inuse": true, "location": "beijing.chaoyang.datun"}
{"groupid": 170001, "voltage": "216V", "current": 12.5, "ts": "2023-12-18T22:12:04", "inuse": false, "location": "beijing.chaoyang.datun"} {"groupid": 170001, "voltage": "216V", "current": 12.5, "ts": "2023-12-18T22:12:04", "inuse": false, "location": "beijing.chaoyang.datun"}
``` ```
如下嵌套结构的 JSON 数据,可自动解析出字段`groupid`、`data_voltage`、`data_current`、`ts`、`inuse`、`location_0_province`、`location_0_city`、`location_0_datun`,也可以选择要解析的字段,并设置解析的别名。 如下嵌套结构的 JSON 数据,可自动解析出字段`groupid`、`data_voltage`、`data_current`、`ts`、`inuse`、`location_0_province`、`location_0_city`、`location_0_datun`,也可以选择要解析的字段,并设置解析的别名。
``` json ``` json
{"groupid": 170001, "data": { "voltage": "221V", "current": 12.3 }, "ts": "2023-12-18T22:12:00", "inuse": true, "location": [{"province": "beijing", "city":"chaoyang", "street": "datun"}]} {"groupid": 170001, "data": { "voltage": "221V", "current": 12.3 }, "ts": "2023-12-18T22:12:00", "inuse": true, "location": [{"province": "beijing", "city":"chaoyang", "street": "datun"}]}
``` ```
![JSON 解析](./pic/transform-02.png) ![JSON 解析](./pic/transform-02.png)
##### Regex 正则表达式<a name="regex"></a> ##### Regex 正则表达式<a name="regex"></a>
可以使用正则表达式的**命名捕获组**从任何字符串(文本)字段中提取多个字段。如图所示,从 nginx 日志中提取访问ip、时间戳、访问的url等字段。 可以使用正则表达式的**命名捕获组**从任何字符串(文本)字段中提取多个字段。如图所示,从 nginx 日志中提取访问ip、时间戳、访问的url等字段。
``` re ``` re
(?<ip>\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b)\s-\s-\s\[(?<ts>\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2}\s\+\d{4})\]\s"(?<method>[A-Z]+)\s(?<url>[^\s"]+).*(?<status>\d{3})\s(?<length>\d+) (?<ip>\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b)\s-\s-\s\[(?<ts>\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2}\s\+\d{4})\]\s"(?<method>[A-Z]+)\s(?<url>[^\s"]+).*(?<status>\d{3})\s(?<length>\d+)
``` ```
![Regex 解析](./pic/transform-03.png) ![Regex 解析](./pic/transform-03.png)
##### UDT 自定义解析脚本 ##### UDT 自定义解析脚本
自定义 rhai 语法脚本解析输入数据(参考 `https://rhai.rs/book/` ),脚本目前仅支持 json 格式原始数据。 自定义 rhai 语法脚本解析输入数据(参考 `https://rhai.rs/book/` ),脚本目前仅支持 json 格式原始数据。
**输入**:脚本中可以使用参数 data, data 是原始数据 json 解析后的 Object Map **输入**:脚本中可以使用参数 data, data 是原始数据 json 解析后的 Object Map
**输出**:输出的数据必须是数组。 **输出**:输出的数据必须是数组。
例如对于数据,一次上报三相电压值,分别入到三个子表中。则需要对这类数据做解析 例如对于数据,一次上报三相电压值,分别入到三个子表中。则需要对这类数据做解析
``` json ``` json
{ {
"ts": "2024-06-27 18:00:00", "ts": "2024-06-27 18:00:00",
"voltage": "220.1,220.3,221.1", "voltage": "220.1,220.3,221.1",
"dev_id": "8208891" "dev_id": "8208891"
} }
``` ```
那么可以使用如下脚本来提取三个电压数据。 那么可以使用如下脚本来提取三个电压数据。
``` ```
let v3 = data["voltage"].split(","); let v3 = data["voltage"].split(",");
[ [
#{"ts": data["ts"], "val": v3[0], "dev_id": data["dev_id"]}, #{"ts": data["ts"], "val": v3[0], "dev_id": data["dev_id"]},
#{"ts": data["ts"], "val": v3[1], "dev_id": data["dev_id"]}, #{"ts": data["ts"], "val": v3[1], "dev_id": data["dev_id"]},
#{"ts": data["ts"], "val": v3[2], "dev_id": data["dev_id"]} #{"ts": data["ts"], "val": v3[2], "dev_id": data["dev_id"]}
] ]
``` ```
最终解析结果如下所示: 最终解析结果如下所示:
![UDT](./pic/transform-udf.png) ![UDT](./pic/transform-udf.png)
### 提取或拆分 ### 提取或拆分
解析后的数据,可能还无法满足目标表的数据要求。比如智能表原始采集数据如下( json 格式): 解析后的数据,可能还无法满足目标表的数据要求。比如智能表原始采集数据如下( json 格式):
``` json ``` json
{"groupid": 170001, "voltage": "221V", "current": 12.3, "ts": "2023-12-18T22:12:00", "inuse": true, "location": "beijing.chaoyang.datun"} {"groupid": 170001, "voltage": "221V", "current": 12.3, "ts": "2023-12-18T22:12:00", "inuse": true, "location": "beijing.chaoyang.datun"}
{"groupid": 170001, "voltage": "220V", "current": 12.2, "ts": "2023-12-18T22:12:02", "inuse": true, "location": "beijing.chaoyang.datun"} {"groupid": 170001, "voltage": "220V", "current": 12.2, "ts": "2023-12-18T22:12:02", "inuse": true, "location": "beijing.chaoyang.datun"}
{"groupid": 170001, "voltage": "216V", "current": 12.5, "ts": "2023-12-18T22:12:04", "inuse": false, "location": "beijing.chaoyang.datun"} {"groupid": 170001, "voltage": "216V", "current": 12.5, "ts": "2023-12-18T22:12:04", "inuse": false, "location": "beijing.chaoyang.datun"}
``` ```
使用 json 规则解析出的电压是字符串表达的带单位形式,最终入库希望能使用 int 类型记录电压值和电流值,便于统计分析,此时就需要对电压进一步拆分;另外日期期望拆分为日期和时间入库。 使用 json 规则解析出的电压是字符串表达的带单位形式,最终入库希望能使用 int 类型记录电压值和电流值,便于统计分析,此时就需要对电压进一步拆分;另外日期期望拆分为日期和时间入库。
如下图所示可以对源字段`ts`使用 split 规则拆分成日期和时间,对字段`voltage`使用 regex 提取出电压值和电压单位。split 规则需要设置**分隔符**和**拆分数量**,拆分后的字段命名规则为`{原字段名}_{顺序号}`Regex 规则同解析过程中的一样,使用**命名捕获组**命名提取字段。 如下图所示可以对源字段`ts`使用 split 规则拆分成日期和时间,对字段`voltage`使用 regex 提取出电压值和电压单位。split 规则需要设置**分隔符**和**拆分数量**,拆分后的字段命名规则为`{原字段名}_{顺序号}`Regex 规则同解析过程中的一样,使用**命名捕获组**命名提取字段。
![拆分和提取](./pic/transform-04.png) ![拆分和提取](./pic/transform-04.png)
### 过滤<a name="filter"></a> ### 过滤<a name="filter"></a>
过滤功能可以设置过滤条件,满足条件的数据行 才会被写入目标表。过滤条件表达式的结果必须是 boolean 类型。在编写过滤条件前,必须确定 解析字段的类型,根据解析字段的类型,可以使用判断函数、比较操作符(`>`、`>=`、`<=`、`<`、`==`、`!=`)来判断。 过滤功能可以设置过滤条件,满足条件的数据行 才会被写入目标表。过滤条件表达式的结果必须是 boolean 类型。在编写过滤条件前,必须确定 解析字段的类型,根据解析字段的类型,可以使用判断函数、比较操作符(`>`、`>=`、`<=`、`<`、`==`、`!=`)来判断。
#### 字段类型及转换 #### 字段类型及转换
只有明确解析出的每个字段的类型,才能使用正确的语法做数据过滤。 只有明确解析出的每个字段的类型,才能使用正确的语法做数据过滤。
使用 json 规则解析出的字段,按照属性值来自动设置类型: 使用 json 规则解析出的字段,按照属性值来自动设置类型:
1. bool 类型:"inuse": true 1. bool 类型:"inuse": true
2. int 类型:"voltage": 220 2. int 类型:"voltage": 220
3. float 类型:"current" : 12.2 3. float 类型:"current" : 12.2
4. String 类型:"location": "MX001" 4. String 类型:"location": "MX001"
使用 regex 规则解析的数据都是 string 类型。 使用 regex 规则解析的数据都是 string 类型。
使用 split 和 regex 提取或拆分的数据是 string 类型。 使用 split 和 regex 提取或拆分的数据是 string 类型。
如果提取出的数据类型不是预期中的类型,可以做数据类型转换。常用的数据类型转换就是把字符串转换成为数值类型。支持的转换函数如下: 如果提取出的数据类型不是预期中的类型,可以做数据类型转换。常用的数据类型转换就是把字符串转换成为数值类型。支持的转换函数如下:
|Function|From type|To type|e.g.| |Function|From type|To type|e.g.|
|:----|:----|:----|:----| |:----|:----|:----|:----|
| parse_int | string | int | parse_int("56") // 结果为整数 56 | | parse_int | string | int | parse_int("56") // 结果为整数 56 |
| parse_float | string | float | parse_float("12.3") // 结果为浮点数 12.3 | | parse_float | string | float | parse_float("12.3") // 结果为浮点数 12.3 |
#### 判断表达式 #### 判断表达式
不同的数据类型有各自判断表达式的写法。 不同的数据类型有各自判断表达式的写法。
##### BOOL 类型 ##### BOOL 类型
可以使用变量或者使用操作符`!`,比如对于字段 "inuse": true可以编写以下表达式 可以使用变量或者使用操作符`!`,比如对于字段 "inuse": true可以编写以下表达式
> 1. inuse > 1. inuse
> 2. !inuse > 2. !inuse
##### 数值类型int/float ##### 数值类型int/float
数值类型支持使用比较操作符`==`、`!=`、`>`、`>=`、`<`、`<=`。 数值类型支持使用比较操作符`==`、`!=`、`>`、`>=`、`<`、`<=`。
##### 字符串类型 ##### 字符串类型
使用比较操作符,比较字符串。 使用比较操作符,比较字符串。
字符串函数 字符串函数
|Function|Description|e.g.| |Function|Description|e.g.|
|:----|:----|:----| |:----|:----|:----|
| is_empty | returns true if the string is empty | s.is_empty() | | is_empty | returns true if the string is empty | s.is_empty() |
| contains | checks if a certain character or sub-string occurs in the string | s.contains("substring") | | contains | checks if a certain character or sub-string occurs in the string | s.contains("substring") |
| starts_with | returns true if the string starts with a certain string | s.starts_with("prefix") | | starts_with | returns true if the string starts with a certain string | s.starts_with("prefix") |
| ends_with | returns true if the string ends with a certain string | s.ends_with("suffix") | | ends_with | returns true if the string ends with a certain string | s.ends_with("suffix") |
| len | returns the number of characters (not number of bytes) in the stringmust be used with comparison operator | s.len == 5 判断字符串长度是否为5len作为属性返回 int ,和前四个函数有区别,前四个直接返回 bool。 | | len | returns the number of characters (not number of bytes) in the stringmust be used with comparison operator | s.len == 5 判断字符串长度是否为5len作为属性返回 int ,和前四个函数有区别,前四个直接返回 bool。 |
##### 复合表达式 ##### 复合表达式
多个判断表达式,可以使用逻辑操作符(&&、||、!)来组合。 多个判断表达式,可以使用逻辑操作符(&&、||、!)来组合。
比如下面的表达式表示获取北京市安装的并且电压值大于 200 的智能表数据。 比如下面的表达式表示获取北京市安装的并且电压值大于 200 的智能表数据。
> location.starts_with("beijing") && voltage > 200 > location.starts_with("beijing") && voltage > 200
### 映射 ### 映射
映射是将解析、提取、拆分的**源字段**对应到**目标表字段**,可以直接对应,也可以通过一些规则计算后再映射到目标表。 映射是将解析、提取、拆分的**源字段**对应到**目标表字段**,可以直接对应,也可以通过一些规则计算后再映射到目标表。
#### 选择目标超级表 #### 选择目标超级表
选择目标超级表后,会加载出超级表所有的 tags 和 columns。 选择目标超级表后,会加载出超级表所有的 tags 和 columns。
源字段根据名称自动使用 mapping 规则映射到目标超级表的 tag 和 column。 源字段根据名称自动使用 mapping 规则映射到目标超级表的 tag 和 column。
例如有如下解析、提取、拆分后的预览数据: 例如有如下解析、提取、拆分后的预览数据:
#### 映射规则 <a name="expression"></a> #### 映射规则 <a name="expression"></a>
支持的映射规则如下表所示: 支持的映射规则如下表所示:
|rule|description| |rule|description|
|:----|:----| |:----|:----|
| mapping | 直接映射,需要选择映射源字段。| | mapping | 直接映射,需要选择映射源字段。|
| value | 常量,可以输入字符串常量,也可以是数值常量,输入的常量值直接入库。| | value | 常量,可以输入字符串常量,也可以是数值常量,输入的常量值直接入库。|
| generator | 生成器,目前仅支持时间戳生成器 now入库时会将当前时间入库。| | generator | 生成器,目前仅支持时间戳生成器 now入库时会将当前时间入库。|
| join | 字符串连接器,可指定连接字符拼接选择的多个源字段。| | join | 字符串连接器,可指定连接字符拼接选择的多个源字段。|
| format | **字符串格式化工具**,填写格式化字符串,比如有三个源字段 year, month, day 分别表示年月日入库希望以yyyy-MM-dd的日期格式入库则可以提供格式化字符串为 `${year}-${month}-${day}`。其中`${}`作为占位符,占位符中可以是一个源字段,也可以是 string 类型字段的函数处理| | format | **字符串格式化工具**,填写格式化字符串,比如有三个源字段 year, month, day 分别表示年月日入库希望以yyyy-MM-dd的日期格式入库则可以提供格式化字符串为 `${year}-${month}-${day}`。其中`${}`作为占位符,占位符中可以是一个源字段,也可以是 string 类型字段的函数处理|
| sum | 选择多个数值型字段做加法计算。| | sum | 选择多个数值型字段做加法计算。|
| expr | **数值运算表达式**,可以对数值型字段做更加复杂的函数处理和数学运算。| | expr | **数值运算表达式**,可以对数值型字段做更加复杂的函数处理和数学运算。|
##### format 中支持的字符串处理函数 ##### format 中支持的字符串处理函数
|Function|description|e.g.| |Function|description|e.g.|
|:----|:----|:----| |:----|:----|:----|
| pad(len, pad_chars) | pads the string with a character or a string to at least a specified length | "1.2".pad(5, '0') // 结果为"1.200" | | pad(len, pad_chars) | pads the string with a character or a string to at least a specified length | "1.2".pad(5, '0') // 结果为"1.200" |
|trim|trims the string of whitespace at the beginning and end|" abc ee ".trim() // 结果为"abc ee"| |trim|trims the string of whitespace at the beginning and end|" abc ee ".trim() // 结果为"abc ee"|
|sub_string(start_pos, len)|extracts a sub-string两个参数<br />1. start position, counting from end if < 0<br />2. (optional) number of characters to extract, none if ≤ 0, to end if omitted|"012345678".sub_string(5) // "5678"<br />"012345678".sub_string(5, 2) // "56"<br />"012345678".sub_string(-2) // "78"| |sub_string(start_pos, len)|extracts a sub-string两个参数<br />1. start position, counting from end if < 0<br />2. (optional) number of characters to extract, none if ≤ 0, to end if omitted|"012345678".sub_string(5) // "5678"<br />"012345678".sub_string(5, 2) // "56"<br />"012345678".sub_string(-2) // "78"|
|replace(substring, replacement)|replaces a sub-string with another|"012345678".replace("012", "abc") // "abc345678"| |replace(substring, replacement)|replaces a sub-string with another|"012345678".replace("012", "abc") // "abc345678"|
##### expr 数学计算表达式 ##### expr 数学计算表达式
基本数学运算支持加`+`、减`-`、乘`*`、除`/`。 基本数学运算支持加`+`、减`-`、乘`*`、除`/`。
比如数据源采集数值以设置度为单位,目标库存储华氏度温度值。那么就需要对采集的温度数据做转换。 比如数据源采集数值以设置度为单位,目标库存储华氏度温度值。那么就需要对采集的温度数据做转换。
解析的源字段为`temperature`,则需要使用表达式 `temperature * 1.8 + 32` 解析的源字段为`temperature`,则需要使用表达式 `temperature * 1.8 + 32`
数值表达式中也支持使用数学函数,可用的数学函数如下表所示: 数值表达式中也支持使用数学函数,可用的数学函数如下表所示:
|Function|description|e.g.| |Function|description|e.g.|
|:----|:----|:----| |:----|:----|:----|
|sin、cos、tan、sinh、cosh|Trigonometry|a.sin() | |sin、cos、tan、sinh、cosh|Trigonometry|a.sin() |
|asin、acos、atan、 asinh、acosh|arc-trigonometry|a.asin()| |asin、acos、atan、 asinh、acosh|arc-trigonometry|a.asin()|
|sqrt|Square root|a.sqrt() // 4.sqrt() == 2| |sqrt|Square root|a.sqrt() // 4.sqrt() == 2|
|exp|Exponential|a.exp()| |exp|Exponential|a.exp()|
|ln、log|Logarithmic|a.ln() // e.ln() == 1<br />a.log() // 10.log() == 1| |ln、log|Logarithmic|a.ln() // e.ln() == 1<br />a.log() // 10.log() == 1|
|floor、ceiling、round、int、fraction|rounding|a.floor() // (4.2).floor() == 4<br />a.ceiling() // (4.2).ceiling() == 5<br />a.round() // (4.2).round() == 4<br />a.int() // (4.2).int() == 4<br />a.fraction() // (4.2).fraction() == 0.2| |floor、ceiling、round、int、fraction|rounding|a.floor() // (4.2).floor() == 4<br />a.ceiling() // (4.2).ceiling() == 5<br />a.round() // (4.2).round() == 4<br />a.int() // (4.2).int() == 4<br />a.fraction() // (4.2).fraction() == 0.2|
#### 子表名映射 #### 子表名映射
子表名类型为字符串,可以使用映射规则中的字符串格式化 format 表达式定义子表名。 子表名类型为字符串,可以使用映射规则中的字符串格式化 format 表达式定义子表名。
## 任务的创建 ## 任务的创建
下面以 MQTT 数据源为例,介绍如何创建一个 MQTT 类型的任务,从 MQTT Broker 消费数据,并写入 TDengine。 下面以 MQTT 数据源为例,介绍如何创建一个 MQTT 类型的任务,从 MQTT Broker 消费数据,并写入 TDengine。
1. 登录至 taosExplorer 以后,点击左侧导航栏上的“数据写入”,即可进入任务列表页面 1. 登录至 taosExplorer 以后,点击左侧导航栏上的“数据写入”,即可进入任务列表页面
2. 在任务列表页面,点击“+ 新增数据源”,即可进入任务创建页面 2. 在任务列表页面,点击“+ 新增数据源”,即可进入任务创建页面
3. 输入任务名称后,选择类型为 MQTT 然后可以创建一个新的代理,或者选择已创建的代理 3. 输入任务名称后,选择类型为 MQTT 然后可以创建一个新的代理,或者选择已创建的代理
4. 输入 MQTT broker 的 IP 地址和端口号例如192.168.1.1001883 4. 输入 MQTT broker 的 IP 地址和端口号例如192.168.1.1001883
5. 配置认证和 SSL 加密: 5. 配置认证和 SSL 加密:
- 如果 MQTT broker 开启了用户认证,则在认证部分,输入 MQTT broker 的用户名和密码; - 如果 MQTT broker 开启了用户认证,则在认证部分,输入 MQTT broker 的用户名和密码;
- 如果 MQTT broker 开启了 SSL 加密,则可以打开页面上的 SSL 证书开关,并上传 CA 的证书,以及客户端的证书和私钥文件; - 如果 MQTT broker 开启了 SSL 加密,则可以打开页面上的 SSL 证书开关,并上传 CA 的证书,以及客户端的证书和私钥文件;
6. 在“采集配置“部分,可选择 MQTT 协议的版本,目前支持 3.1 3.1.1 5.0 三个版本;配置 Client ID 时要注意,如果对同一个 MQTT broker 创建了多个任务Client ID 应不同,否则会造成 Client ID 冲突,导致任务无法正常运行;在对主题和 QoS 进行配置时,需要使用 `<topic name>::<QoS>` 的形式,即订阅的主题与 QoS 之间要使用两个冒号分隔,其中 QoS 的取值范围为 0 1 2 分别代表 at most once at lease once exactly once配置完成以上信息后可以点击“检查连通性”按钮对以上配置进行检查如果连通性检查失败请按照页面上返回的具体错误提示进行修改 6. 在“采集配置“部分,可选择 MQTT 协议的版本,目前支持 3.1 3.1.1 5.0 三个版本;配置 Client ID 时要注意,如果对同一个 MQTT broker 创建了多个任务Client ID 应不同,否则会造成 Client ID 冲突,导致任务无法正常运行;在对主题和 QoS 进行配置时,需要使用 `<topic name>::<QoS>` 的形式,即订阅的主题与 QoS 之间要使用两个冒号分隔,其中 QoS 的取值范围为 0 1 2 分别代表 at most once at lease once exactly once配置完成以上信息后可以点击“检查连通性”按钮对以上配置进行检查如果连通性检查失败请按照页面上返回的具体错误提示进行修改
7. 在从 MQTT broker 同步数据的过程中taosX 还支持对消息体中的字段进行提取,过滤、映射等操作。在位于 “Payload 转换”下方的文本框中,可以直接输入输入消息体样例,或是以上传文件的方式导入,以后还会支持直接从所配置的服务器中检索样例消息; 7. 在从 MQTT broker 同步数据的过程中taosX 还支持对消息体中的字段进行提取,过滤、映射等操作。在位于 “Payload 转换”下方的文本框中,可以直接输入输入消息体样例,或是以上传文件的方式导入,以后还会支持直接从所配置的服务器中检索样例消息;
8. 对消息体字段的提取,目前支持 2 种方式JSON 和正则表达式。对于简单的 key/value 格式的 JSON 数据,可以直接点击提取按钮,即可展示解析出的字段名;对于复杂的 JSON 数据,可以使用 JSON Path 提取感兴趣的字段;当使用正则表达式提取字段时,要保证正则表达式的正确性; 8. 对消息体字段的提取,目前支持 2 种方式JSON 和正则表达式。对于简单的 key/value 格式的 JSON 数据,可以直接点击提取按钮,即可展示解析出的字段名;对于复杂的 JSON 数据,可以使用 JSON Path 提取感兴趣的字段;当使用正则表达式提取字段时,要保证正则表达式的正确性;
9. 消息体中的字段被解析后,可以基于解析出的字段名设置过滤规则,只有满足过滤规则的数据,才会写入 TDengine否则会忽略该消息例如可以配置过滤规则为 voltage > 200即只有当电压大于 200V 的数据才会被同步至 TDengine 9. 消息体中的字段被解析后,可以基于解析出的字段名设置过滤规则,只有满足过滤规则的数据,才会写入 TDengine否则会忽略该消息例如可以配置过滤规则为 voltage > 200即只有当电压大于 200V 的数据才会被同步至 TDengine
10. 最后,在配置完消息体中的字段和超级表中的字段的映射规则后,就可以提交任务了;除了基本的映射以外,在这里还可以对消息中字段的值进行转换,例如:可以通过表达式 expr 将原消息体中的电压和电流,计算为功率后再写入 TDengine 10. 最后,在配置完消息体中的字段和超级表中的字段的映射规则后,就可以提交任务了;除了基本的映射以外,在这里还可以对消息中字段的值进行转换,例如:可以通过表达式 expr 将原消息体中的电压和电流,计算为功率后再写入 TDengine
11. 任务提交后,会自动返回任务列表页面,如果提交成功,任务的状态会切换至“运行中”,如果提交失败,可通过查看该任务的活动日志,查找错误原因; 11. 任务提交后,会自动返回任务列表页面,如果提交成功,任务的状态会切换至“运行中”,如果提交失败,可通过查看该任务的活动日志,查找错误原因;
12. 对于运行中的任务,点击指标的查看按钮,可以查看该任务的详细运行指标,弹出窗口划分为 2 个标签页,分别展示该任务多次运行的累计指标和本次运行的指标,这些指标每 2 秒钟会自动刷新一次。 12. 对于运行中的任务,点击指标的查看按钮,可以查看该任务的详细运行指标,弹出窗口划分为 2 个标签页,分别展示该任务多次运行的累计指标和本次运行的指标,这些指标每 2 秒钟会自动刷新一次。
## 任务管理 ## 任务管理
在任务列表页面,还可以对任务进行启动、停止、查看、删除、复制等操作,也可以查看各个任务的运行情况,包括写入的记录条数、流量等。 在任务列表页面,还可以对任务进行启动、停止、查看、删除、复制等操作,也可以查看各个任务的运行情况,包括写入的记录条数、流量等。

View File

@ -8,57 +8,13 @@ toc_max_heading_level: 4
至于如何获取和使用这些监控数据,用户可以使用第三方的监测工具比如 Zabbix 来获取这些保存的系统监测数据,进而将 TDengine 的运行状况无缝集成到现有的 IT 监控系统中。也可以使用 TDengine 提供的 TDinsight 插件,使用该插件用户可以通过 Grafana 平台直观地展示和管理这些监控信息,如下图所示。这为用户提供了灵活的监控选项,以满足不同场景下的运维需求。 至于如何获取和使用这些监控数据,用户可以使用第三方的监测工具比如 Zabbix 来获取这些保存的系统监测数据,进而将 TDengine 的运行状况无缝集成到现有的 IT 监控系统中。也可以使用 TDengine 提供的 TDinsight 插件,使用该插件用户可以通过 Grafana 平台直观地展示和管理这些监控信息,如下图所示。这为用户提供了灵活的监控选项,以满足不同场景下的运维需求。
~[通过监控组件管理监控信息](./grafana.png) ![通过监控组件管理监控信息](./grafana.png)
## 配置 taosKeeper ## 配置 taosKeeper
因为 TDengine 的监控数据都通过 taosKeeper 上报并存储,所以本节先介绍 taosKeeper 的配置。 因为 TDengine 的监控数据都通过 taosKeeper 上报并存储,所以本节先介绍 taosKeeper 的配置。
taosKeeper 的配置文件默认位于 `/etc/taos/taoskeeper.toml`。 下面为一个示例配置文件,更多详细信息见参考手册。其中最为关键的一个配置项是 `database`,它决定了收集到的监控数据存储在目标系统的哪个数据库中。 taosKeeper 的配置文件默认位于 `/etc/taos/taoskeeper.toml`。 详细配置见 [参考手册](../../reference/components/taoskeeper/#配置文件)。其中最为关键的一个配置项是 `database`,它决定了收集到的监控数据存储在目标系统的哪个数据库中。
```toml
# gin 框架是否启用 debug
debug = false
# 服务监听端口, 默认为 6043
port = 6043
# 日志级别,包含 panic、error、info、debug、trace等
loglevel = "info"
# 程序中使用协程池的大小
gopoolsize = 50000
# 查询 TDengine 监控数据轮询间隔
RotationInterval = "15s"
[tdengine]
host = "127.0.0.1"
port = 6041
username = "root"
password = "taosdata"
# 需要被监控的 taosAdapter
[taosAdapter]
address = ["127.0.0.1:6041"]
[metrics]
# 监控指标前缀
prefix = "taos"
# 集群数据的标识符
cluster = "production"
# 存放监控数据的数据库
database = "log"
# 指定需要监控的普通表
tables = []
# database options for db storing metrics data
[metrics.databaseoptions]
cachemodel = "none"
```
## 监控 taosd ## 监控 taosd
@ -66,9 +22,9 @@ cachemodel = "none"
为了简化用户在 TDengine 监控方面的配置工作TDengine 提供了一个名为 TDinsight 的 Grafana 插件。该插件与 taosKeeper 协同工作,能够实时监控 TDengine 的各项性能指标。 为了简化用户在 TDengine 监控方面的配置工作TDengine 提供了一个名为 TDinsight 的 Grafana 插件。该插件与 taosKeeper 协同工作,能够实时监控 TDengine 的各项性能指标。
通过集成 Grafana 和 TDengine 数据源插件TDinsight 能够读取 taosKeeper 收集并存储的监控数据。这使得用户可以在 Grafana 平台上直观地查看 TDengine 集群的状态、节点信息、读写请求以及资源使用情况等关键指标,实现数据的可视化展示。 通过集成 Grafana 和 TDengine 数据源插件TDinsight 能够读取 taosKeeper 收集的监控数据。这使得用户可以在 Grafana 平台上直观地查看 TDengine 集群的状态、节点信息、读写请求以及资源使用情况等关键指标,实现数据的可视化展示。
此外TDinsight 还具备针对 vnode、dnode 和 mnode 节点的异常状态告警功能,为开发者提供实时的集群运行状态监控,确保 TDengine 集群的稳定性和可靠性。以下是TDinsight 的详细使用说明,以帮助你充分利用这一强大工具。 以下是TDinsight 的详细使用说明,以帮助你充分利用这一强大工具。
#### 前置条件 #### 前置条件
@ -76,314 +32,31 @@ cachemodel = "none"
- TDengine 已安装并正常运行。 - TDengine 已安装并正常运行。
- taosAdapter 已经安装并正常运行。 - taosAdapter 已经安装并正常运行。
- taosKeeper 已经安装并正常运行。 - taosKeeper 已经安装并正常运行。
- Grafana 已安装并正常运行,以下介绍以 Grafna 10.4.0 为例。 - Grafana 已安装并正常运行,以下介绍以 Grafna 11.0.0 为例。
同时记录以下信息。 同时记录以下信息。
- taosAdapter 的 RESTful 接口地址,如 http://www.example.com:6041。 - taosAdapter 的 RESTful 接口地址,如 `http://www.example.com:6041`
- TDengine 集群的认证信息,包括用户名及密码。 - TDengine 集群的认证信息,包括用户名及密码。
#### 导入仪表盘 #### 导入仪表盘
TDengine 数据源插件已被提交至 Grafana 官网,完成插件的安装和数据源的创建后,可以进行 TDinsight 仪表盘的导入。 TDengine 数据源插件已被提交至 Grafana 官网,完成插件的安装和数据源的创建后,可以进行 TDinsight 仪表盘的导入。
在 Grafana 的 Home-Dashboards 页面,点击位于右上角的 New → mport 按钮,即可进入 Dashboard 的导入页面,它支持以下两种导入方式。 在 Grafana 的 ”Home“ -> ”Dashboards“ 页面,点击位于右上角的 ”New“ -> ”import“ 按钮,即可进入 Dashboard 的导入页面,它支持以下两种导入方式。
- Dashboard ID18180。 - Dashboard ID18180。
- Dashboard URLhttps://grafana.com/grafana/dashboards/18180-tdinsight-for-3-x/ - Dashboard URLhttps://grafana.com/grafana/dashboards/18180-tdinsight-for-3-x/
填写以上 Dashboard ID 或 Dashboard URL 以后,点击 Load 按钮按照向导操作即可完成导入。导入成功后Dashboards 列表页面会出现 TDinsight for 3.x 仪盘,点击进入后,就可以看到 TDinsight 中已创建的各个指标的面板,如下图所示: 填写以上 Dashboard ID 或 Dashboard URL 以后,点击 Load 按钮按照向导操作即可完成导入。导入成功后Dashboards 列表页面会出现 TDinsight for 3.x盘,点击进入后,就可以看到 TDinsight 中已创建的各个指标的面板,如下图所示:
![TDinsight 界面示例](./tdinsight.png) ![TDinsight 界面示例](./TDinsight-1-cluster-status.webp)
**注意** 在 TDinsight 界面左上角的 Log from 下拉列表中可以选择 log 数据库。 **注意** 在 TDinsight 界面左上角的 Log from 下拉列表中可以选择 `log` 数据库。
### taosd 监控数据 ### TDengine V3 监控数据
TDinsight dashboard 数据来源于 log 库(存放监控数据的默认 db可以在 taoskeeper 配置文件中修改。以下是由 taosd 上报由 taosKeeper 存储在 log 库中的数据。 TDinsight dashboard 数据来源于 `log` 库(存放监控数据的默认数据库,可以在 taoskeeper 配置文件中修改。”TDinsight for 3.x“ 仪表盘查询了 taosd 和 TaosAdapter 的监控指标。
- taosd 的监控指标请参考 [taosd 监控指标](../../reference/components/taosd/#taosd-监控指标)
1. taosd\_cluster\_basic 表 - taosAdapter 的监控指标请参考 [taosAdapter 监控指标](../../reference/components/taosadapter/#taosadapter-监控指标)
`taosd_cluster_basic` 表记录集群基础信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|first\_ep|VARCHAR||集群 first ep|
|first\_ep\_dnode\_id|INT||集群 first ep 的 dnode id|
|cluster_version|VARCHAR||tdengine version。例如3.0.4.0|
|cluster\_id|VARCHAR|TAG|cluster id|
2. taosd\_cluster\_info 表
`taosd_cluster_info` 表记录集群信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|cluster_uptime|DOUBLE||当前 master 节点的uptime。单位秒|
|dbs\_total|DOUBLE||database 总数|
|tbs\_total|DOUBLE||当前集群 table 总数|
|stbs\_total|DOUBLE||当前集群 stable 总数|
|dnodes\_total|DOUBLE||当前集群 dnode 总数|
|dnodes\_alive|DOUBLE||当前集群 dnode 存活总数|
|mnodes\_total|DOUBLE||当前集群 mnode 总数|
|mnodes\_alive|DOUBLE||当前集群 mnode 存活总数|
|vgroups\_total|DOUBLE||当前集群 vgroup 总数|
|vgroups\_alive|DOUBLE||当前集群 vgroup 存活总数|
|vnodes\_total|DOUBLE||当前集群 vnode 总数|
|vnodes\_alive|DOUBLE||当前集群 vnode 存活总数|
|connections\_total|DOUBLE||当前集群连接总数|
|topics\_total|DOUBLE||当前集群 topic 总数|
|streams\_total|DOUBLE||当前集群 stream 总数|
|grants_expire\_time|DOUBLE||认证过期时间,企业版有效,社区版为 DOUBLE 最大值|
|grants_timeseries\_used|DOUBLE||已用测点数|
|grants_timeseries\_total|DOUBLE||总测点数,开源版本为 DOUBLE 最大值|
|cluster\_id|VARCHAR|TAG|cluster id|
3. taosd\_vgroups\_info 表
`taosd_vgroups_info` 表记录虚拟节点组信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|tables\_num|DOUBLE||vgroup 中 table 数量|
|status|DOUBLE||vgroup 状态, 取值范围unsynced = 0, ready = 1|
|vgroup\_id|VARCHAR|TAG|vgroup id|
|database\_name|VARCHAR|TAG|vgroup 所属的 database 名字|
|cluster\_id|VARCHAR|TAG|cluster id|
4. taosd\_dnodes\_info 表
`taosd_dnodes_info` 记录 dnode 信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|uptime|DOUBLE||dnode uptime单位秒|
|cpu\_engine|DOUBLE||taosd cpu 使用率,从 `/proc/<taosd_pid>/stat` 读取|
|cpu\_system|DOUBLE||服务器 cpu 使用率,从 `/proc/stat` 读取|
|cpu\_cores|DOUBLE||服务器 cpu 核数|
|mem\_engine|DOUBLE||taosd 内存使用率,从 `/proc/<taosd_pid>/status` 读取|
|mem\_free|DOUBLE||服务器可用内存,单位 KB|
|mem\_total|DOUBLE||服务器内存总量,单位 KB|
|disk\_used|DOUBLE||data dir 挂载的磁盘使用量,单位 bytes|
|disk\_total|DOUBLE||data dir 挂载的磁盘总容量,单位 bytes|
|system\_net\_in|DOUBLE||网络吞吐率,从 `/proc/net/dev` 中读取的 received bytes。单位 byte/s|
|system\_net\_out|DOUBLE||网络吞吐率,从 `/proc/net/dev` 中读取的 transmit bytes。单位 byte/s|
|io\_read|DOUBLE||io 吞吐率,从 `/proc/<taosd_pid>/io` 中读取的 rchar 与上次数值计算之后,计算得到速度。单位 byte/s|
|io\_write|DOUBLE||io 吞吐率,从 `/proc/<taosd_pid>/io` 中读取的 wchar 与上次数值计算之后,计算得到速度。单位 byte/s|
|io\_read\_disk|DOUBLE||磁盘 io 吞吐率,从 `/proc/<taosd_pid>/io` 中读取的 read_bytes。单位 byte/s|
|io\_write\_disk|DOUBLE||磁盘 io 吞吐率,从 `/proc/<taosd_pid>/io` 中读取的 write_bytes。单位 byte/s|
|vnodes\_num|DOUBLE||dnode 上 vnodes 数量|
|masters|DOUBLE||dnode 上 master node 数量|
|has\_mnode|DOUBLE||dnode 是否包含 mnode取值范围包含=1,不包含=0|
|has\_qnode|DOUBLE||dnode 是否包含 qnode取值范围包含=1,不包含=0|
|has\_snode|DOUBLE||dnode 是否包含 snode取值范围包含=1,不包含=0|
|has\_bnode|DOUBLE||dnode 是否包含 bnode取值范围包含=1,不包含=0|
|error\_log\_count|DOUBLE||error 总数|
|info\_log\_count|DOUBLE||info 总数|
|debug\_log\_count|DOUBLE||debug 总数|
|trace\_log\_count|DOUBLE||trace 总数|
|dnode\_id|VARCHAR|TAG|dnode id|
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|cluster\_id|VARCHAR|TAG|cluster id|
5. taosd\_dnodes\_status 表
`taosd_dnodes_status` 表记录 dnode 状态信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|status|DOUBLE||dnode 状态,取值范围ready=1offline =0|
|dnode\_id|VARCHAR|TAG|dnode id|
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|cluster\_id|VARCHAR|TAG|cluster id|
6. taosd\_dnodes\_log\_dir 表
`taosd_dnodes_log_dir` 表记录 log 目录信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|avail|DOUBLE||log 目录可用空间。单位 byte|
|used|DOUBLE||log 目录已使用空间。单位 byte|
|total|DOUBLE||log 目录空间。单位 byte|
|name|VARCHAR|TAG|log 目录名,一般为 `/var/log/taos/`|
|dnode\_id|VARCHAR|TAG|dnode id|
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|cluster\_id|VARCHAR|TAG|cluster id|
7. taosd\_dnodes\_data\_dir 表
`taosd_dnodes_data_dir` 表记录 data 目录信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|avail|DOUBLE||data 目录可用空间。单位 byte|
|used|DOUBLE||data 目录已使用空间。单位 byte|
|total|DOUBLE||data 目录空间。单位 byte|
|level|VARCHAR|TAG|0、1、2 多级存储级别|
|name|VARCHAR|TAG|data 目录,一般为 `/var/lib/taos`|
|dnode\_id|VARCHAR|TAG|dnode id|
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|cluster\_id|VARCHAR|TAG|cluster id|
8. taosd\_mnodes\_info 表
`taosd_mnodes_info` 表记录 mnode 角色信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|role|DOUBLE||mnode 角色, 取值范围offline = 0,follower = 100,candidate = 101,leader = 102,error = 103,learner = 104|
|mnode\_id|VARCHAR|TAG|master node id|
|mnode\_ep|VARCHAR|TAG|master node endpoint|
|cluster\_id|VARCHAR|TAG|cluster id|
9. taosd\_vnodes\_role 表
`taosd_vnodes_role` 表记录虚拟节点角色信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|vnode\_role|DOUBLE||vnode 角色取值范围offline = 0,follower = 100,candidate = 101,leader = 102,error = 103,learner = 104|
|vgroup\_id|VARCHAR|TAG|dnode id|
|dnode\_id|VARCHAR|TAG|dnode id|
|database\_name|VARCHAR|TAG|vgroup 所属的 database 名字|
|cluster\_id|VARCHAR|TAG|cluster id|
10. taosd\_sql\_req 表
`taosd_sql_req` 记录授权信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|count|DOUBLE||sql 数量|
|result|VARCHAR|TAG|sql的执行结果取值范围Success, Failed|
|username|VARCHAR|TAG|执行sql的user name|
|sql\_type|VARCHAR|TAG|sql类型取值范围inserted_rows|
|dnode\_id|VARCHAR|TAG|dnode id|
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|vgroup\_id|VARCHAR|TAG|dnode id|
|cluster\_id|VARCHAR|TAG|cluster id|
11. taos\_sql\_req 表
`taos_sql_req` 记录授权信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|count|DOUBLE||sql 数量|
|result|VARCHAR|TAG|sql的执行结果取值范围Success, Failed|
|username|VARCHAR|TAG|执行sql的user name|
|sql\_type|VARCHAR|TAG|sql类型取值范围select, insertdelete|
|cluster\_id|VARCHAR|TAG|cluster id|
12. taos\_slow\_sql 表
`taos_slow_sql` 记录授权信息。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|count|DOUBLE||sql 数量|
|result|VARCHAR|TAG|sql的执行结果取值范围Success, Failed|
|username|VARCHAR|TAG|执行sql的user name|
|duration|VARCHAR|TAG|sql执行耗时取值范围3-10s,10-100s,100-1000s,1000s-|
|cluster\_id|VARCHAR|TAG|cluster id|
13. keeper\_monitor 表
`keeper_monitor` 记录 taoskeeper 监控数据。
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|ts|TIMESTAMP||timestamp|
|cpu|DOUBLE||cpu 使用率|
|mem|DOUBLE||内存使用率|
|identify|NCHAR|TAG||
14. taosadapter\_restful\_http\_request\_total 表
`taosadapter_restful_http_request_total` 记录 taosadapter rest 请求信息,该表为 schemaless 方式创建的表,时间戳字段名为 `_ts`
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|\_ts|TIMESTAMP||timestamp|
|gauge|DOUBLE||监控指标值|
|client\_ip|NCHAR|TAG|client ip|
|endpoint|NCHAR|TAG|taosadpater endpoint|
|request\_method|NCHAR|TAG|request method|
|request\_uri|NCHAR|TAG|request uri|
|status\_code|NCHAR|TAG|status code|
15. taosadapter\_restful\_http\_request\_fail 表
`taosadapter_restful_http_request_fail` 记录 taosadapter rest 请求失败信息,该表为 schemaless 方式创建的表,时间戳字段名为 `_ts`
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|\_ts|TIMESTAMP||timestamp|
|gauge|DOUBLE||监控指标值|
|client\_ip|NCHAR|TAG|client ip|
|endpoint|NCHAR|TAG|taosadpater endpoint|
|request\_method|NCHAR|TAG|request method|
|request\_uri|NCHAR|TAG|request uri|
|status\_code|NCHAR|TAG|status code|
16. taosadapter\_restful\_http\_request\_in\_flight 表
`taosadapter_restful_http_request_in_flight` 记录 taosadapter rest 实时请求信息,该表为 schemaless 方式创建的表,时间戳字段名为 `_ts`
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|\_ts|TIMESTAMP||timestamp|
|gauge|DOUBLE||监控指标值|
|endpoint|NCHAR|TAG|taosadpater endpoint|
17. taosadapter\_restful\_http\_request\_summary\_milliseconds 表
`taosadapter_restful_http_request_summary_milliseconds` 记录 taosadapter rest 请求汇总信息,该表为 schemaless 方式创建的表,时间戳字段名为 `_ts`
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|\_ts|TIMESTAMP||timestamp|
|count|DOUBLE|||
|sum|DOUBLE|||
|0.5|DOUBLE|||
|0.9|DOUBLE|||
|0.99|DOUBLE|||
|0.1|DOUBLE|||
|0.2|DOUBLE|||
|endpoint|NCHAR|TAG|taosadpater endpoint|
|request\_method|NCHAR|TAG|request method|
|request\_uri|NCHAR|TAG|request uri|
18. taosadapter\_system\_mem\_percent 表
`taosadapter_system_mem_percent` 表记录 taosadapter 内存使用情况,该表为 schemaless 方式创建的表,时间戳字段名为 `_ts`
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|\_ts|TIMESTAMP||timestamp|
|gauge|DOUBLE||监控指标值|
|endpoint|NCHAR|TAG|taosadpater endpoint|
19. taosadapter\_system\_cpu\_percent 表
`taosadapter_system_cpu_percent` 表记录 taosadapter cpu 使用情况,该表为 schemaless 方式创建的表,时间戳字段名为 `_ts`
|field|type|is\_tag|comment|
|:----|:---|:-----|:------|
|\_ts|TIMESTAMP||timestamp|
|gauge|DOUBLE||监控指标值|
|endpoint|NCHAR|TAG|taosadpater endpoint|
## 监控 taosX ## 监控 taosX
@ -396,13 +69,13 @@ taosX 是 TDengine 中提供零代码数据接入能力的核心组件,对它
### 版本支持 ### 版本支持
1. TDengine 企业版本 3.2.3.0 或以上版本包含的 taosX 才包含此功能。如果单独安装 taosX需要 taosX 1.5.0 或以上版本。 1. TDengine 企业版本 3.2.3.0 或以上版本包含的 taosX 才包含此功能。如果单独安装 taosX需要 taosX 1.5.0 或以上版本。
1. 需要安装 Grafana 插件 [TDengie Datasource v3.5.0](https://grafana.com/grafana/plugins/tdengine-datasource/) 或以上版本。 2. 需要安装 Grafana 插件 [TDengie Datasource v3.5.0](https://grafana.com/grafana/plugins/tdengine-datasource/) 或以上版本。
### 准备工作 ### 准备工作
假设你已经部署好了 taosdtaosAdapter 和 taosAdapter。 那么还需要: 假设你已经部署好了 taosdtaosAdapter 和 taosAdapter。 那么还需要:
2. 启动 taosX 服务。 1. 启动 taosX 服务。
3. 部署 Grafana ,安装 TDengine Datasource 插件,配置好数据源。 2. 部署 Grafana ,安装 TDengine Datasource 插件,配置好数据源。
### 配置 taosX ### 配置 taosX
@ -426,52 +99,50 @@ toasX 的配置文件(默认 /etc/taos/taosx.toml) 中与 monitor 相关的配
| port | --monitor-port | MONITOR_PORT | taosKeeper 服务的端口 | | 6043 | | port | --monitor-port | MONITOR_PORT | taosKeeper 服务的端口 | | 6043 |
| interval | --monitor-interval | MONITTOR_INTERVAL | taosX 发送 metrics 数据到 taosKeeper 的时间间隔,单位秒 | 1-10 | 10 | | interval | --monitor-interval | MONITTOR_INTERVAL | taosX 发送 metrics 数据到 taosKeeper 的时间间隔,单位秒 | 1-10 | 10 |
TDinsight for taosX
"TDinsight for taosX" 专门为 taosX 监控创建的 Grafana 面板。使用前需要先导入这个面板。
### 基于 TDinsight 监控 tasoX ### 基于 TDinsight 监控 tasoX
"TDinsight for taosX" 是专门为 taosX 监控创建的 Grafana 面板。使用前需要先导入这个面板。
#### 进入面板 #### 进入面板
1. 选择 TDengine Datasource 1. 在 Grafana 界面菜单中点击 ”Data sources“ 然后选择已经配置好的 TDengine 数据源。
![TDengine Datasource](./pic/monitor-01.jpg) 2. 在数据源配置界面选择 “Dashboard” Tab, 然后导入 ”TDinsight for taosX“ 面板(第一次使用需要先导入)。 下面是一个示例图:
2. 点击 “Dashboard”, 选择 TDinsight for taosX 面板。(第一次使用需要先导入)。
![Dashboard](./pic/monitor-02.jpg)
![monitor rows](./pic/monitor-04.jpg) ![monitor rows](./pic/monitor-04.jpg)
该面板每一行代表一个或一类监控对象。最上面是 taosX 监控行,然后是 Agent 监控行, 最后是各类数据写入任务的监控。
:::note 该面板每一行代表一个或一类监控对象。最上面是 taosX 监控行,然后是 Agent 监控行, 最后是各类数据写入任务的监控。
1. 如果打开这个面板后看不到任何数据,你很可能需要点击左上角的数据库列表(即 “Log from” 下拉菜单),切换到监控数据所在的数据库。 :::note
2. 数据库包含多少个 Agent 的数据就会自动创建多少个 Agent 行。(如上图) - 如果打开这个面板后看不到任何数据,你很可能需要点击左上角的数据库列表(即 “Log from” 下拉菜单),切换到监控数据所在的数据库。
- 数据库包含多少个 Agent 的数据就会自动创建多少个 Agent 行。(如上图)
::: :::
#### 监控示例 #### 监控示例
1. taosX 监控示例 1. taosX 监控示例
![monitor taosx](./pic/monitor-03.png) ![monitor taosx](./pic/monitor-03.png)
2. Agent 监控示例 2. Agent 监控示例
![monitor agent](./pic/monitor-09.jpg) ![monitor agent](./pic/monitor-09.jpg)
3. TDengine2 数据源监控示例 3. TDengine2 数据源监控示例
![monitor tdengine2](./pic/monitor-05.png) ![monitor tdengine2](./pic/monitor-05.png)
:::info :::info
监控面板只展示了数据写入任务的部分监控指标,在 Explorer 页面上有更全面的监控指标,且有每个指标的具体说明。 监控面板只展示了数据写入任务的部分监控指标,在 Explorer 页面上有更全面的监控指标,且有每个指标的具体说明。
::: :::
3. TDengine3 数据源监控示例 4. TDengine3 数据源监控示例图
![monitor tdengine3](./pic/monitor-06.jpg)
![monitor tdengine3](./pic/monitor-06.jpg)
4. 其它数据源监控示例 5. 其它数据源监控示例图
![monitor task](./pic/monitor-10.jpg) ![monitor task](./pic/monitor-10.jpg)
#### 限制 #### 限制

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

View File

@ -6,29 +6,28 @@ toc_max_heading_level: 4
## UDF 简介 ## UDF 简介
在某些应用场景中,应用逻辑需要的查询功能无法直接使用TDengine内置的函数来实现。TDengine允许编写用户自定义函数UDF以便解决特殊应用场景中的使用需求。UDF在集群中注册成功后可以像系统内置函数一样在SQL中调用就使用角度而言没有任何区别。UDF分为标量函数和聚合函数。标量函数对每行数据输出一个值如求绝对值abs、正弦函数sin、字符串拼接函数concat等。聚合函数对多行数据输出一个值如求平均数avg、取最大值max等。 在某些应用场景中,应用逻辑需要的查询功能无法直接使用内置函数来实现TDengine 允许编写用户自定义函数UDF以便解决特殊应用场景中的使用需求。UDF 在集群中注册成功后,可以像系统内置函数一样在 SQL 中调用就使用角度而言没有任何区别。UDF 分为标量函数和聚合函数。标量函数对每行数据输出一个值,如求绝对值abs、正弦函数sin、字符串拼接函数concat等。聚合函数对多行数据输出一个值,如求平均数avg、取最大值max等。
TDengine支持用C和Python两种编程语言编写UDF。C语言编写的UDF与内置函数的性能几乎相同Python语言编写的UDF可以利用丰富的Python运算库。为了避免UDF执行中发生异常影响数据库服务TDengine使用了进程分离技术把UDF的执行放到另一个进程中完成即使用户编写的UDF崩溃也不会影响TDengine的正常运行。 TDengine 支持用 C Python 两种编程语言编写 UDF。C 语言编写的 UDF 与内置函数的性能几乎相同Python 语言编写的 UDF 可以利用丰富的 Python 运算库。为了避免 UDF 执行中发生异常影响数据库服务TDengine 使用了进程分离技术,把 UDF 的执行放到另一个进程中完成,即使用户编写的 UDF 崩溃,也不会影响 TDengine 的正常运行。
## 用 C 语言开发 UDF ## 用 C 语言开发 UDF
使用 C 语言实现 UDF 时,需要实现规定的接口函数 使用 C 语言实现 UDF 时,需要实现规定的接口函数
- 标量函数需要实现标量接口函数 scalarfn 。 - 标量函数需要实现标量接口函数 scalarfn 。
- 聚合函数需要实现聚合接口函数 aggfn_start aggfn aggfn_finish。 - 聚合函数需要实现聚合接口函数 aggfn_start、aggfn、aggfn_finish。
- 如果需要初始化,实现 udf_init如果需要清理工作实现udf_destroy。 - 如果需要初始化,实现 udf_init。
- 如果需要清理工作,实现 udf_destroy。
接口函数的名称是 UDF 名称,或者是 UDF 名称和特定后缀(`_start`, `_finish`, `_init`, `_destroy`)的连接。列表中的scalarfnaggfn, udf需要替换成udf函数名。
### 接口定义 ### 接口定义
在TDengine中UDF的接口函数名称可以是UDF名称也可以是UDF名称和特定后缀_start、_finish、_init、_destroy的连接。后面内容中描述的函数名称例如scalarfn、aggfn需要替换成UDF名称。 接口函数的名称是 UDF 名称,或者是 UDF 名称和特定后缀(_start、_finish、_init、_destroy的连接。后面内容中描述的函数名称例如 scalarfn、aggfn需要替换成 UDF 名称。
#### 标量函数接口 #### 标量函数接口
标量函数是一种将输入数据转换为输出数据的函数,通常用于对单个数据值进行计算和转换。标量函数的接口函数原型如下。 标量函数是一种将输入数据转换为输出数据的函数,通常用于对单个数据值进行计算和转换。标量函数的接口函数原型如下。
```c ```c
int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn) int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn);
``` ```
主要参数说明如下。 主要参数说明如下。
- inputDataBlock输入的数据块。 - inputDataBlock输入的数据块。
@ -37,23 +36,22 @@ int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn)
#### 聚合函数接口 #### 聚合函数接口
聚合函数是一种特殊的函数,用于对数据进行分组和计算,从而生成汇总信息。聚合函数的工作原理如下。 聚合函数是一种特殊的函数,用于对数据进行分组和计算,从而生成汇总信息。聚合函数的工作原理如下。
- 初始化结果缓冲区首先调用aggfn_start函数生成一个结果缓冲区result buffer用于存储中间结果。 - 初始化结果缓冲区:首先调用 aggfn_start 函数生成一个结果缓冲区result buffer用于存储中间结果。
- 分组数据相关数据会被分为多个行数据块row data block每个行数据块包含一组具有相同分组键grouping key的数据。 - 分组数据相关数据会被分为多个行数据块row data block每个行数据块包含一组具有相同分组键grouping key的数据。
- 更新中间结果对于每个数据块调用aggfn函数更新中间结果。aggfn函数会根据聚合函数的类型如sum、avg、count等对数据进行相应的计算并将计算结 - 更新中间结果:对于每个数据块,调用 aggfn 函数更新中间结果。aggfn 函数会根据聚合函数的类型(如 sum、avg、count 等)对数据进行相应的计算,并将计算结
果存储在结果缓冲区中。 果存储在结果缓冲区中。
- 生成最终结果在所有数据块的中间结果更新完成后调用aggfn_finish函数从结果缓冲区中提取最终结果。最终结果通常只包含0条或1条数据具体取决于聚 - 生成最终结果:在所有数据块的中间结果更新完成后,调用 aggfn_finish 函数从结果缓冲区中提取最终结果。最终结果只包含 0 条或 1 条数据,具体取决于聚
合函数的类型和输入数据。 合函数的类型和输入数据。
聚合函数的接口函数原型如下。 聚合函数的接口函数原型如下。
```c ```c
int32_t aggfn_start(SUdfInterBuf *interBuf) int32_t aggfn_start(SUdfInterBuf *interBuf);
int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf);
int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result) int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result);
``` ```
其中 aggfn 是函数名的占位符。首先调用 aggfn_start 生成结果 buffer然后相关的数据会被分为多个行数据块对每个数据块调用 aggfn 用数据块更新中间结果,最后再调用 aggfn_finish 从中间结果产生最终结果,最终结果只能含 0 或 1 条结果数据。
其中 aggfn 是函数名的占位符。首先调用aggfn_start生成结果buffer然后相关的数据会被分为多个行数据块对每个数据块调用 aggfn 用数据块更新中间结果,最后再调用 aggfn_finish 从中间结果产生最终结果,最终结果只能含 0 或 1 条结果数据。
主要参数说明如下。 主要参数说明如下。
- interBuf中间结果缓存区。 - interBuf中间结果缓存区。
@ -61,29 +59,49 @@ int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result)
- newInterBuf新的中间结果缓冲区。 - newInterBuf新的中间结果缓冲区。
- result最终结果。 - result最终结果。
#### 初始化和销毁接口 #### 初始化和销毁接口
初始化和销毁接口是标量函数和聚合函数共同使用的接口相关API如下。 初始化和销毁接口是标量函数和聚合函数共同使用的接口,相关 API 如下。
```c ```c
int32_t udf_init() int32_t udf_init()
int32_t udf_destroy() int32_t udf_destroy()
``` ```
其中udf_init函数完成初始化工作udf_destroy函数完成清理工作。如果没有初始化工作无须定义udf_init函数如果没有清理工作无须定义udf_destroy函数。 其中udf_init 函数完成初始化工作udf_destroy 函数完成清理工作。如果没有初始化工作,无须定义 udf_init 函数;如果没有清理工作,无须定义 udf_destroy 函数。
### 标量函数模板 ### 标量函数模板
用C语言开发标量函数的模板如下。 C 语言开发标量函数的模板如下。
```c ```c
#include "taos.h"
#include "taoserror.h"
#include "taosudf.h"
// Initialization function.
// If no initialization, we can skip definition of it.
// The initialization function shall be concatenation of the udf name and _init suffix.
// @return error number defined in taoserror.h
int32_t scalarfn_init() { int32_t scalarfn_init() {
// initialization.
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Scalar function main computation function.
// @param inputDataBlock, input data block composed of multiple columns with each column defined by SUdfColumn
// @param resultColumn, output column
// @return error number defined in taoserror.h
int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn* resultColumn) { int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn* resultColumn) {
// read data from inputDataBlock and process, then output to resultColumn.
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Cleanup function.
// If no cleanup related processing, we can skip definition of it.
// The destroy function shall be concatenation of the udf name and _destroy suffix.
// @return error number defined in taoserror.h
int32_t scalarfn_destroy() { int32_t scalarfn_destroy() {
// clean up
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
``` ```
@ -91,53 +109,211 @@ int32_t scalarfn_destroy() {
用C语言开发聚合函数的模板如下。 用C语言开发聚合函数的模板如下。
```c ```c
#include "taos.h"
#include "taoserror.h"
#include "taosudf.h"
// Initialization function.
// If no initialization, we can skip definition of it.
// The initialization function shall be concatenation of the udf name and _init suffix.
// @return error number defined in taoserror.h
int32_t aggfn_init() { int32_t aggfn_init() {
// initialization.
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Aggregate start function.
// The intermediate value or the state(@interBuf) is initialized in this function.
// The function name shall be concatenation of udf name and _start suffix.
// @param interbuf intermediate value to initialize
// @return error number defined in taoserror.h
int32_t aggfn_start(SUdfInterBuf* interBuf) { int32_t aggfn_start(SUdfInterBuf* interBuf) {
// initialize intermediate value in interBuf
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Aggregate reduce function.
// This function aggregate old state(@interbuf) and one data bock(inputBlock) and output a new state(@newInterBuf).
// @param inputBlock input data block
// @param interBuf old state
// @param newInterBuf new state
// @return error number defined in taoserror.h
int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) { int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) {
// read from inputBlock and interBuf and output to newInterBuf
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Aggregate function finish function.
// This function transforms the intermediate value(@interBuf) into the final output(@result).
// The function name must be concatenation of aggfn and _finish suffix.
// @interBuf : intermediate value
// @result: final result
// @return error number defined in taoserror.h
int32_t int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result) { int32_t int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result) {
// read data from inputDataBlock and process, then output to result
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Cleanup function.
// If no cleanup related processing, we can skip definition of it.
// The destroy function shall be concatenation of the udf name and _destroy suffix.
// @return error number defined in taoserror.h
int32_t aggfn_destroy() { int32_t aggfn_destroy() {
// clean up
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
``` ```
### 编译 ### 编译
在TDengine中为了实现UDF需要编写C语言源代码并按照TDengine的规范编译为动态链接库文件。 TDengine 中,为了实现 UDF需要编写 C 语言源代码,并按照 TDengine 的规范编译为动态链接库文件。
按照前面描述的规则准备UDF的源代码bit_and.c。以Linux操作系统为例执行如下指令编译得到动态链接库文件。 按照前面描述的规则,准备 UDF 的源代码 bit_and.c。以 Linux 操作系统为例,执行如下指令,编译得到动态链接库文件。
```shell ```shell
gcc-g-O0-fPIC-sharedbit_and.c-olibbitand.so gcc -g -O0 -fPIC -shared bit_and.c -o libbitand.so
``` ```
为了保证可靠运行推荐使用7.5及以上版本的GCC。 为了保证可靠运行,推荐使用 7.5 及以上版本的 GCC。
### C UDF 数据结构
```c
typedef struct SUdfColumnMeta {
int16_t type;
int32_t bytes;
uint8_t precision;
uint8_t scale;
} SUdfColumnMeta;
typedef struct SUdfColumnData {
int32_t numOfRows;
int32_t rowsAlloc;
union {
struct {
int32_t nullBitmapLen;
char *nullBitmap;
int32_t dataLen;
char *data;
} fixLenCol;
struct {
int32_t varOffsetsLen;
int32_t *varOffsets;
int32_t payloadLen;
char *payload;
int32_t payloadAllocLen;
} varLenCol;
};
} SUdfColumnData;
typedef struct SUdfColumn {
SUdfColumnMeta colMeta;
bool hasNull;
SUdfColumnData colData;
} SUdfColumn;
typedef struct SUdfDataBlock {
int32_t numOfRows;
int32_t numOfCols;
SUdfColumn **udfCols;
} SUdfDataBlock;
typedef struct SUdfInterBuf {
int32_t bufLen;
char *buf;
int8_t numOfResult; //zero or one
} SUdfInterBuf;
```
数据结构说明如下:
- SUdfDataBlock 数据块包含行数 numOfRows 和列数 numCols。udfCols[i] (0 \<= i \<= numCols-1)表示每一列数据类型为SUdfColumn*。
- SUdfColumn 包含列的数据类型定义 colMeta 和列的数据 colData。
- SUdfColumnMeta 成员定义同 taos.h 数据类型定义。
- SUdfColumnData 数据可以变长varLenCol 定义变长数据fixLenCol 定义定长数据。
- SUdfInterBuf 定义中间结构 buffer以及 buffer 中结果个数 numOfResult
为了更好的操作以上数据结构,提供了一些便利函数,定义在 taosudf.h。
### C UDF 示例代码
#### 标量函数示例 [bit_and](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/bit_and.c)
bit_add 实现多列的按位与功能。如果只有一列返回这一列。bit_add 忽略空值。
<details>
<summary>bit_and.c</summary>
```c
{{#include tests/script/sh/bit_and.c}}
```
</details>
#### 聚合函数示例1 返回值为数值类型 [l2norm](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/l2norm.c)
l2norm 实现了输入列的所有数据的二阶范数,即对每个数据先平方,再累加求和,最后开方。
<details>
<summary>l2norm.c</summary>
```c
{{#include tests/script/sh/l2norm.c}}
```
</details>
#### 聚合函数示例2 返回值为字符串类型 [max_vol](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/max_vol.c)
max_vol 实现了从多个输入的电压列中找到最大电压,返回由设备 ID + 最大电压所在(行,列)+ 最大电压值 组成的组合字符串值
创建表:
```bash
create table battery(ts timestamp, vol1 float, vol2 float, vol3 float, deviceId varchar(16));
```
创建自定义函数:
```bash
create aggregate function max_vol as '/root/udf/libmaxvol.so' outputtype binary(64) bufsize 10240 language 'C';
```
使用自定义函数:
```bash
select max_vol(vol1, vol2, vol3, deviceid) from battery;
```
<details>
<summary>max_vol.c</summary>
```c
{{#include tests/script/sh/max_vol.c}}
```
</details>
## 用 Python 语言开发 UDF ## 用 Python 语言开发 UDF
### 准备环境 ### 准备环境
准备环境的具体步骤如下: 准备环境的具体步骤如下:
- 第1步准备好Python运行环境。 - 第1步准备好 Python 运行环境。
- 第2步安装Python包taospyudf。命令如下。 - 第2步安装 Python taospyudf。命令如下。
```shell ```shell
pip3 install taospyudf pip3 install taospyudf
``` ```
- 第3步执行命令ldconfig。 - 第3步执行命令 ldconfig。
- 第4步启动taosd服务。 - 第4步启动 taosd 服务。
安装过程中会编译 C++ 源码,因此系统上要有 cmake 和 gcc。编译生成的 libtaospyudf.so 文件自动会被复制到 /usr/local/lib/ 目录,因此如果是非 root 用户,安装时需加 sudo。安装完可以检查这个目录是否有了这个文件:
```shell
root@slave11 ~/udf $ ls -l /usr/local/lib/libtaos*
-rw-r--r-- 1 root root 671344 May 24 22:54 /usr/local/lib/libtaospyudf.so
```
### 接口定义 ### 接口定义
当使用Python语言开发UDF时需要实现规定的接口函数。具体要求如下。 当使用 Python 语言开发 UDF 时,需要实现规定的接口函数。具体要求如下。
- 标量函数需要实现标量接口函数process。 - 标量函数需要实现标量接口函数 process。
- 聚合函数需要实现聚合接口函数start、reduce、finish。 - 聚合函数需要实现聚合接口函数 start、reduce、finish。
- 如果需要初始化则应实现函数init。 - 如果需要初始化,则应实现函数 init。
- 如果需要清理工作则实现函数destroy。 - 如果需要清理工作,则实现函数 destroy。
#### 标量函数接口 #### 标量函数接口
@ -147,7 +323,7 @@ def process(input: datablock) -> tuple[output_type]:
``` ```
主要参数说明如下: 主要参数说明如下:
- input:datablock 类似二维矩阵,通过成员方法 data(row,col)返回位于 row 行,col 列的 python 对象 - input:datablock 类似二维矩阵,通过成员方法 data(row, col) 读取位于 row 行、col 列的 python 对象
- 返回值是一个 Python 对象元组,每个元素类型为输出类型。 - 返回值是一个 Python 对象元组,每个元素类型为输出类型。
#### 聚合函数接口 #### 聚合函数接口
@ -159,13 +335,13 @@ def reduce(inputs: datablock, buf: bytes) -> bytes
def finish(buf: bytes) -> output_type: def finish(buf: bytes) -> output_type:
``` ```
上述代码定义了3个函数分别用于实现一个自定义的聚合函数。具体过程如下。 上述代码定义了 3 个函数,分别用于实现一个自定义的聚合函数。具体过程如下。
首先调用start函数生成最初的结果缓冲区。这个结果缓冲区用于存储聚合函数的内部状态随着输入数据的处理而不断更新。 首先,调用 start 函数生成最初的结果缓冲区。这个结果缓冲区用于存储聚合函数的内部状态,随着输入数据的处理而不断更新。
然后输入数据会被分为多个行数据块。对于每个行数据块调用reduce函数并将当前行数据块inputs和当前的中间结果buf作为参数传递。reduce函数会根据输入数据和当前状态来更新聚合函数的内部状态并返回新的中间结果 然后,输入数据会被分为多个行数据块。对于每个行数据块,调用 reduce 函数并将当前行数据块inputs和当前的中间结果buf作为参数传递。reduce 函数会根据输入数据和当前状态来更新聚合函数的内部状态,并返回新的中间结果
最后当所有行数据块都处理完毕后调用finish函数。这个函数接收最终的中间结果buf作为参数并从中生成最终的输出。由于聚合函数的特性最终输出只能包含0条或1条数据。这个输出结果将作为聚合函数的计算结果返回给调用者。 最后,当所有行数据块都处理完毕后,调用 finish 函数。这个函数接收最终的中间结果buf作为参数并从中生成最终的输出。由于聚合函数的特性最终输出只能包含 0 条或 1 条数据。这个输出结果将作为聚合函数的计算结果返回给调用者。
#### 初始化和销毁接口 #### 初始化和销毁接口
@ -179,7 +355,7 @@ def destroy()
- init 完成初始化工作 - init 完成初始化工作
- destroy 完成清理工作 - destroy 完成清理工作
**注意** 用Python开发UDF时必须定义init函数和destroy函数 **注意** 用 Python 开发 UDF 时必须定义 init 函数和 destroy 函数
### 标量函数模板 ### 标量函数模板
@ -204,7 +380,7 @@ def start() -> bytes:
def reduce(inputs: datablock, buf: bytes) -> bytes def reduce(inputs: datablock, buf: bytes) -> bytes
# deserialize buf to state # deserialize buf to state
# reduce the inputs and state into new_state. # reduce the inputs and state into new_state.
# use inputs.data(i,j) to access python object of location(i,j) # use inputs.data(i, j) to access python object of location(i, j)
# serialize new_state into new_state_bytes # serialize new_state into new_state_bytes
return new_state_bytes return new_state_bytes
def finish(buf: bytes) -> output_type: def finish(buf: bytes) -> output_type:
@ -217,13 +393,13 @@ def finish(buf: bytes) -> output_type:
| **TDengine SQL数据类型** | **Python数据类型** | | **TDengine SQL数据类型** | **Python数据类型** |
| :-----------------------: | ------------ | | :-----------------------: | ------------ |
|TINYINT / SMALLINT / INT / BIGINT | int | | TINYINT / SMALLINT / INT / BIGINT | int |
|TINYINT UNSIGNED / SMALLINT UNSIGNED / INT UNSIGNED / BIGINT UNSIGNED | int | | TINYINT UNSIGNED / SMALLINT UNSIGNED / INT UNSIGNED / BIGINT UNSIGNED | int |
|FLOAT / DOUBLE | float | | FLOAT / DOUBLE | float |
|BOOL | bool | | BOOL | bool |
|BINARY / VARCHAR / NCHAR | bytes| | BINARY / VARCHAR / NCHAR | bytes|
|TIMESTAMP | int | | TIMESTAMP | int |
|JSON and other types | 不支持 | | JSON and other types | 不支持 |
### 开发示例 ### 开发示例
@ -262,7 +438,7 @@ create function myfun as '/root/udf/myfun.py' outputtype double language 'Python
其输出如下 其输出如下
```shell ```shell
taos> create function myfun as '/root/udf/myfun.py' outputtype double language 'Python'; taos> create function myfun as '/root/udf/myfun.py' outputtype double language 'Python';
Create OK, 0 row(s) affected (0.005202s) Create OK, 0 row(s) affected (0.005202s)
``` ```
@ -460,7 +636,7 @@ def process(block):
for i in range(rows)] for i in range(rows)]
``` ```
UDF 框架会将 TDengine 的 timestamp 类型映射为 Python 的 int 类型所以这个函数只接受一个表示毫秒数的整数。process 方法先做参数检查,然后用 moment 包替换时间的星期为星期日最后格式化输出。输出的字符串长度是固定的10个字符长因此可以这样创建 UDF 函数: UDF 框架会将 TDengine 的 timestamp 类型映射为 Python 的 int 类型所以这个函数只接受一个表示毫秒数的整数。process 方法先做参数检查,然后用 moment 包替换时间的星期为星期日,最后格式化输出。输出的字符串长度是固定的 10 个字符长,因此可以这样创建 UDF 函数:
```sql ```sql
create function nextsunday as '/root/udf/nextsunday.py' outputtype binary(10) language 'Python'; create function nextsunday as '/root/udf/nextsunday.py' outputtype binary(10) language 'Python';
@ -627,39 +803,77 @@ close log file: spread.log
通过这个示例,我们学会了如何定义聚合函数,并打印自定义的日志信息。 通过这个示例,我们学会了如何定义聚合函数,并打印自定义的日志信息。
### 更多 Python UDF 示例代码
#### 标量函数示例 [pybitand](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/pybitand.py)
pybitand 实现多列的按位与功能。如果只有一列返回这一列。pybitand 忽略空值。
<details>
<summary>pybitand.py</summary>
```Python
{{#include tests/script/sh/pybitand.py}}
```
</details>
#### 聚合函数示例 [pyl2norm](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/pyl2norm.py)
pyl2norm 实现了输入列的所有数据的二阶范数,即对每个数据先平方,再累加求和,最后开方。
<details>
<summary>pyl2norm.py</summary>
```c
{{#include tests/script/sh/pyl2norm.py}}
```
</details>
#### 聚合函数示例 [pycumsum](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/pycumsum.py)
pycumsum 使用 numpy 计算输入列所有数据的累积和。
<details>
<summary>pycumsum.py</summary>
```c
{{#include tests/script/sh/pycumsum.py}}
```
</details>
## 管理 UDF ## 管理 UDF
在集群中管理UDF的过程涉及创建、使用和维护这些函数。用户可以通过SQL在集群中创建和管理UDF一旦创建成功集群的所有用户都可以在SQL中使用这些函数。由于UDF存储在集群的mnode上因此即使重启集群已经创建的UDF也仍然可用。 在集群中管理 UDF 的过程涉及创建、使用和维护这些函数。用户可以通过 SQL 在集群中创建和管理 UDF一旦创建成功集群的所有用户都可以在 SQL 中使用这些函数。由于 UDF 存储在集群的 mnode 上,因此即使重启集群,已经创建的 UDF 也仍然可用。
在创建UDF时需要区分标量函数和聚合函数。标量函数接受零个或多个输入参数并返回一个单一的值。聚合函数接受一组输入值并通过对这些值进行某种计算如求和、计数等来返回一个单一的值。如果创建时声明了错误的函数类别则通过SQL调用函数时会报错。 在创建 UDF 时,需要区分标量函数和聚合函数。标量函数接受零个或多个输入参数,并返回一个单一的值。聚合函数接受一组输入值,并通过对这些值进行某种计算(如求和、计数等)来返回一个单一的值。如果创建时声明了错误的函数类别,则通过 SQL 调用函数时会报错。
此外用户需要确保输入数据类型与UDF程序匹配UDF输出的数据类型与outputtype匹配。这意味着在创建UDF时需要为输入参数和输出值指定正确的数据类型。这有助于确保在调用UDF时输入数据能够正确地传递给UDF并且UDF的输出值与预期的数据类型相匹配。 此外,用户需要确保输入数据类型与 UDF 程序匹配UDF 输出的数据类型与 outputtype 匹配。这意味着在创建 UDF 时,需要为输入参数和输出值指定正确的数据类型。这有助于确保在调用 UDF 时,输入数据能够正确地传递给 UDF并且 UDF 的输出值与预期的数据类型相匹配。
### 创建标量函数 ### 创建标量函数
创建标量函数的SQL语法如下。 创建标量函数的 SQL 语法如下。
```sql ```sql
CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type LANGUAGE 'Python'; CREATE OR REPLACE FUNCTION function_name AS library_path OUTPUTTYPE output_type LANGUAGE 'Python';
``` ```
各参数说明如下。 各参数说明如下。
- or replace如果函数已经存在则会修改已有的函数属性。 - or replace如果函数已经存在则会修改已有的函数属性。
- function_name标量函数在SQL中被调用时的函数名。 - function_name标量函数在SQL中被调用时的函数名。
- language支持C语言和Python语言3.7及以上版本默认为C。 - language支持 C 语言和 Python 语言3.7 及以上版本),默认为 C。
- library_path如果编程语言是C则路径是包含UDF实现的动态链接库的库文件绝对路径通常指向一个so文件。如果编程语言是Python则路径是包含UDF - library_path如果编程语言是 C则路径是包含 UDF 实现的动态链接库的库文件绝对路径,通常指向一个 so 文件。如果编程语言是 Python则路径是包含 UDF
实现的Python文件路径。路径需要用英文单引号或英文双引号括起来。 实现的 Python 文件路径。路径需要用英文单引号或英文双引号括起来。
- output_type函数计算结果的数据类型名称。 - output_type函数计算结果的数据类型名称。
### 创建聚合函数 ### 创建聚合函数
创建聚合函数的SQL语法如下。 创建聚合函数的 SQL 语法如下。
```sql ```sql
CREATE AGGREGATE FUNCTION function_name library_path OUTPUTTYPE output_type LANGUAGE 'Python'; CREATE OR REPLACE AGGREGATE FUNCTION function_name library_path OUTPUTTYPE output_type LANGUAGE 'Python';
``` ```
其中buffer_size 表示中间计算结果的缓冲区大小,单位是字节。其他参数的含义与标量函数相同。 其中buffer_size 表示中间计算结果的缓冲区大小,单位是字节。其他参数的含义与标量函数相同。
如下SQL创建一个名为 l2norm 的UDF。 如下 SQL 创建一个名为 l2norm 的 UDF。
```sql ```sql
CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 8; CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 8;
``` ```
@ -673,8 +887,15 @@ DROP FUNCTION function_name;
### 查看 UDF ### 查看 UDF
显示集群中当前可用的所有UDF的SQL如下。 显示集群中当前可用的所有 UDF SQL 如下。
```sql ```sql
show functions; show functions;
``` ```
### 查看函数信息
同名的 UDF 每更新一次,版本号会增加 1。
```sql
select * from ins_functions \G;
```

View File

@ -27,42 +27,42 @@ taosd 命令行参数如下
### 连接相关 ### 连接相关
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :--------------------: | :-------------------------------------------------------------------------------------: |
|firstEp | taosd 启动时,主动连接的集群中首个 dnode 的 end point缺省值localhost:6030 | | firstEp | taosd 启动时,主动连接的集群中首个 dnode 的 end point缺省值localhost:6030 |
|secondEp | taosd 启动时,如果 firstEp 连接不上,尝试连接集群中第二个 dnode 的 endpoint缺省值无| | secondEp | taosd 启动时,如果 firstEp 连接不上,尝试连接集群中第二个 dnode 的 endpoint缺省值 |
|fqdn | 启动 taosd 后所监听的服务地址,缺省值:所在服务器上配置的第一个 hostname | | fqdn | 启动 taosd 后所监听的服务地址,缺省值:所在服务器上配置的第一个 hostname |
|serverPort | 启动 taosd 后所监听的端口缺省值6030 | | serverPort | 启动 taosd 后所监听的端口缺省值6030 |
|maxShellConns | 一个 dnode 容许的连接数,取值范围为 10-5000000缺省值5000 | | maxShellConns | 一个 dnode 容许的连接数,取值范围为 10-5000000缺省值5000 |
|numOfRpcSessions | 允许一个客户端能创建的最大连接数,取值范围 100-100000缺省值30000 | | numOfRpcSessions | 允许一个客户端能创建的最大连接数,取值范围 100-100000缺省值30000 |
|timeToGetAvailableConn | 获得可用连接的最长等待时间,取值范围 10-50000000单位为毫秒缺省值500000 | | timeToGetAvailableConn | 获得可用连接的最长等待时间,取值范围 10-50000000单位为毫秒缺省值500000 |
### 监控相关 ### 监控相关
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :----------------: | :------------------------------------------------------------------------------------: |
|monitor | 是否收集监控数据并上报0: 关闭1:打开缺省值0 | | monitor | 是否收集监控数据并上报0: 关闭1:打开缺省值0 |
|monitorFqdn | taosKeeper 服务所在服务器的 FQDN缺省值无 | | monitorFqdn | taosKeeper 服务所在服务器的 FQDN缺省值 |
|monitorPort | taosKeeper 服务所监听的端口号缺省值6043 | | monitorPort | taosKeeper 服务所监听的端口号缺省值6043 |
|monitorInternal | 监控数据库记录系统参数CPU/内存)的时间间隔,单位是秒,取值范围 1-200000 缺省值30| | monitorInternal | 监控数据库记录系统参数CPU/内存)的时间间隔,单位是秒,取值范围 1-200000 缺省值30 |
|telemetryReporting | 是否上传 telemetry0: 不上传1上传缺省值1 | | telemetryReporting | 是否上传 telemetry0: 不上传1上传缺省值1 |
|crashReporting | 是否上传 crash 信息0: 不上传1: 上传;缺省值: 1| | crashReporting | 是否上传 crash 信息0: 不上传1: 上传;缺省值: 1 |
### 查询相关 ### 查询相关
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :--------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|queryPolicy | 查询策略1: 只使用 vnode不使用 qnode; 2: 没有扫描算子的子任务在 qnode 执行,带扫描算子的子任务在 vnode 执行; 3: vnode 只运行扫描算子,其余算子均在 qnode 执行 缺省值1 | | queryPolicy | 查询策略1: 只使用 vnode不使用 qnode; 2: 没有扫描算子的子任务在 qnode 执行,带扫描算子的子任务在 vnode 执行; 3: vnode 只运行扫描算子,其余算子均在 qnode 执行 缺省值1 |
|maxNumOfDistinctRes | 允许返回的 distinct 结果最大行数,默认值 10 万,最大允许值 1 亿 | | maxNumOfDistinctRes | 允许返回的 distinct 结果最大行数,默认值 10 万,最大允许值 1 亿 |
|countAlwaysReturnValue | ount/hyperloglog函数在输入数据为空或者NULL的情况下是否返回值0: 返回空行1: 返回;该参数设置为 1 时,如果查询中含有 INTERVAL 子句或者该查询使用了TSMA时, 且相应的组或窗口内数据为空或者NULL 对应的组或窗口将不返回查询结果. 注意此参数客户端和服务端值应保持一致.| | countAlwaysReturnValue | ount/hyperloglog函数在输入数据为空或者NULL的情况下是否返回值0: 返回空行1: 返回;该参数设置为 1 时,如果查询中含有 INTERVAL 子句或者该查询使用了TSMA时, 且相应的组或窗口内数据为空或者NULL 对应的组或窗口将不返回查询结果. 注意此参数客户端和服务端值应保持一致. |
### 区域相关 ### 区域相关
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :------: | :------------------------------------------------------------------------------------------------------: |
|timezone | 时区,缺省值:当前服务器所配置的时区 | | timezone | 时区,缺省值:当前服务器所配置的时区 |
|locale | 系统区位信息及编码格式 ,缺省值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过 API 设置 | | locale | 系统区位信息及编码格式 ,缺省值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过 API 设置 |
|charset | 字符集编码,缺省值:系统自动获取 | | charset | 字符集编码,缺省值:系统自动获取 |
:::info :::info
1. 为应对多时区的数据写入和查询问题TDengine 采用 Unix 时间戳(Unix Timestamp)来记录和存储时间戳。Unix 时间戳的特点决定了任一时刻不论在任何时区产生的时间戳均一致。需要注意的是Unix 时间戳是在客户端完成转换和记录。为了确保客户端其他形式的时间转换为正确的 Unix 时间戳,需要设置正确的时区。 1. 为应对多时区的数据写入和查询问题TDengine 采用 Unix 时间戳(Unix Timestamp)来记录和存储时间戳。Unix 时间戳的特点决定了任一时刻不论在任何时区产生的时间戳均一致。需要注意的是Unix 时间戳是在客户端完成转换和记录。为了确保客户端其他形式的时间转换为正确的 Unix 时间戳,需要设置正确的时区。
@ -141,64 +141,64 @@ charset 的有效值是 UTF-8。
### 存储相关 ### 存储相关
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :--------------: | :--------------------------------------------------------------------: |
|dataDir | 数据文件目录,所有的数据文件都将写入该目录,缺省值:/var/lib | | dataDir | 数据文件目录,所有的数据文件都将写入该目录,缺省值:/var/lib |
|tempDir | 指定所有系统运行过程中的临时文件生成的目录,缺省值:/tmp | | tempDir | 指定所有系统运行过程中的临时文件生成的目录,缺省值:/tmp |
|minimalTmpDirGB | tempDir 所指定的临时文件目录所需要保留的最小空间,单位 GB缺省值: 1| | minimalTmpDirGB | tempDir 所指定的临时文件目录所需要保留的最小空间,单位 GB缺省值: 1 |
|minimalDataDirGB | dataDir 指定的时序数据存储目录所需要保留的最小空间,单位 GB缺省值: 2 | | minimalDataDirGB | dataDir 指定的时序数据存储目录所需要保留的最小空间,单位 GB缺省值: 2 |
### 集群相关 ### 集群相关
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :-----------: | :-------------------------------------------------------------------------: |
|supportVnodes | dnode 支持的最大 vnode 数目取值范围0-4096缺省值 CPU 核数的 2 倍 + 5 | | supportVnodes | dnode 支持的最大 vnode 数目取值范围0-4096缺省值 CPU 核数的 2 倍 + 5 |
### 性能调优 ### 性能调优
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :----------------: | :---------------------------------------------: |
|numOfCommitThreads | 写入线程的最大数量,取值范围 0-1024缺省值为 4 | | numOfCommitThreads | 写入线程的最大数量,取值范围 0-1024缺省值为 4 |
### 日志相关 ### 日志相关
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :--------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------: |
|logDir | 日志文件目录,运行日志将写入该目录,缺省值:/var/log/taos | | logDir | 日志文件目录,运行日志将写入该目录,缺省值:/var/log/taos |
|minimalLogDirGB | 当日志文件夹所在磁盘可用空间大小小于该值时停止写日志单位GB缺省值1| | minimalLogDirGB | 当日志文件夹所在磁盘可用空间大小小于该值时停止写日志单位GB缺省值1 |
|numOfLogLines | 单个日志文件允许的最大行数缺省值10,000,000 | | numOfLogLines | 单个日志文件允许的最大行数缺省值10,000,000 |
|asyncLog | 日志写入模式0: 同步1: 异步,缺省值: 1 | | asyncLog | 日志写入模式0: 同步1: 异步,缺省值: 1 |
|logKeepDays | 日志文件的最长保存时间 单位缺省值0意味着无限保存当设置为大于0 的值时,日志文件会被重命名为 taosdlog.xxx其中 xxx 为日志文件最后修改的时间戳。 | | logKeepDays | 日志文件的最长保存时间 单位缺省值0意味着无限保存当设置为大于0 的值时,日志文件会被重命名为 taosdlog.xxx其中 xxx 为日志文件最后修改的时间戳。 |
|slowLogThreshold | 慢查询门限值,大于等于门限值认为是慢查询,单位秒,默认值: 3 | | slowLogThreshold | 慢查询门限值,大于等于门限值认为是慢查询,单位秒,默认值: 3 |
|slowLogScope | 定启动记录哪些类型的慢查询可选值ALL, QUERY, INSERT, OHTERS, NONE; 默认值ALL | | slowLogScope | 定启动记录哪些类型的慢查询可选值ALL, QUERY, INSERT, OHTERS, NONE; 默认值ALL |
|debugFlag | 运行日志开关131输出错误和警告日志135输出错误、警告和调试日志143输出错误、警告、调试和跟踪日志; 默认值131 或 135 (取决于不同模块)| | debugFlag | 运行日志开关131输出错误和警告日志135输出错误、警告和调试日志143输出错误、警告、调试和跟踪日志; 默认值131 或 135 (取决于不同模块) |
|tmrDebugFlag | 定时器模块的日志开关,取值范围同上 | | tmrDebugFlag | 定时器模块的日志开关,取值范围同上 |
|uDebugFlag | 共用功能模块的日志开关,取值范围同上 | | uDebugFlag | 共用功能模块的日志开关,取值范围同上 |
|rpcDebugFlag | rpc 模块的日志开关,取值范围同上 | | rpcDebugFlag | rpc 模块的日志开关,取值范围同上 |
|jniDebugFlag | jni 模块的日志开关,取值范围同上 | | jniDebugFlag | jni 模块的日志开关,取值范围同上 |
|qDebugFlag | query 模块的日志开关,取值范围同上 | | qDebugFlag | query 模块的日志开关,取值范围同上 |
|dDebugFlag | dnode 模块的日志开关,取值范围同上,缺省值 135 | | dDebugFlag | dnode 模块的日志开关,取值范围同上,缺省值 135 |
|vDebugFlag | vnode 模块的日志开关,取值范围同上 | | vDebugFlag | vnode 模块的日志开关,取值范围同上 |
|mDebugFlag | mnode 模块的日志开关,取值范围同上 | | mDebugFlag | mnode 模块的日志开关,取值范围同上 |
|wDebugFlag | wal 模块的日志开关,取值范围同上 | | wDebugFlag | wal 模块的日志开关,取值范围同上 |
|sDebugFlag | sync 模块的日志开关,取值范围同上 | | sDebugFlag | sync 模块的日志开关,取值范围同上 |
|tsdbDebugFlag | tsdb 模块的日志开关,取值范围同上 | | tsdbDebugFlag | tsdb 模块的日志开关,取值范围同上 |
|tqDebugFlag | tq 模块的日志开关,取值范围同上 | | tqDebugFlag | tq 模块的日志开关,取值范围同上 |
|fsDebugFlag | fs 模块的日志开关,取值范围同上 | | fsDebugFlag | fs 模块的日志开关,取值范围同上 |
|udfDebugFlag | udf 模块的日志开关,取值范围同上 | | udfDebugFlag | udf 模块的日志开关,取值范围同上 |
|smaDebugFlag | sma 模块的日志开关,取值范围同上 | | smaDebugFlag | sma 模块的日志开关,取值范围同上 |
|idxDebugFlag | index 模块的日志开关,取值范围同上 | | idxDebugFlag | index 模块的日志开关,取值范围同上 |
|tdbDebugFlag | tdb 模块的日志开关,取值范围同上 | | tdbDebugFlag | tdb 模块的日志开关,取值范围同上 |
### 压缩参数 ### 压缩参数
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :-------------: | :----------------------------------------------------------------------------------------------------------------------------------------------: |
| compressMsgSize | 是否对 RPC 消息进行压缩;-1: 所有消息都不压缩; 0: 所有消息都压缩; N (N>0): 只有大于 N 个字节的消息才压缩;缺省值 -1 | | compressMsgSize | 是否对 RPC 消息进行压缩;-1: 所有消息都不压缩; 0: 所有消息都压缩; N (N>0): 只有大于 N 个字节的消息才压缩;缺省值 -1 |
| fPrecision | 设置 float 类型浮点数压缩精度 取值范围0.1 ~ 0.00000001 ,默认值 0.00000001 , 小于此值的浮点数尾数部分将被截断 | | fPrecision | 设置 float 类型浮点数压缩精度 取值范围0.1 ~ 0.00000001 ,默认值 0.00000001 , 小于此值的浮点数尾数部分将被截断 |
|dPrecision | 设置 double 类型浮点数压缩精度 , 取值范围0.1 ~ 0.0000000000000001 缺省值 0.0000000000000001 小于此值的浮点数尾数部分将被截取 | | dPrecision | 设置 double 类型浮点数压缩精度 , 取值范围0.1 ~ 0.0000000000000001 缺省值 0.0000000000000001 小于此值的浮点数尾数部分将被截取 |
|lossyColumn | 对 float 和/或 double 类型启用 TSZ 有损压缩;取值范围: float, double, none缺省值: none表示关闭无损压缩 | | lossyColumn | 对 float 和/或 double 类型启用 TSZ 有损压缩;取值范围: float, double, none缺省值: none表示关闭无损压缩 |
|ifAdtFse | 在启用 TSZ 有损压缩时,使用 FSE 算法替换 HUFFMAN 算法, FSE 算法压缩速度更快,但解压稍慢,追求压缩速度可选用此算法; 0: 关闭1打开默认值为 0 | | ifAdtFse | 在启用 TSZ 有损压缩时,使用 FSE 算法替换 HUFFMAN 算法, FSE 算法压缩速度更快,但解压稍慢,追求压缩速度可选用此算法; 0: 关闭1打开默认值为 0 |
**补充说明** **补充说明**
@ -216,10 +216,214 @@ lossyColumns float|double
### 其他参数 ### 其他参数
| 参数名称 | 参数说明 | | 参数名称 | 参数说明 |
|:-------------:|:----------------------------------------------------------------:| | :--------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|enableCoreFile | crash 时是否生成 core 文件0: 不生成1生成默认值 为 1; 不同的启动方式,生成 core 文件的目录如下1、systemctl start taosd 启动:生成的 core 在根目录下 <br/> 2、手动启动就在 taosd 执行目录下。| | enableCoreFile | crash 时是否生成 core 文件0: 不生成1生成默认值 为 1; 不同的启动方式,生成 core 文件的目录如下1、systemctl start taosd 启动:生成的 core 在根目录下 <br/> 2、手动启动就在 taosd 执行目录下。 |
|udf | 是否启动 UDF 服务0: 不启动1启动默认值 为 0 | | udf | 是否启动 UDF 服务0: 不启动1启动默认值 为 0 |
|ttlChangeOnWrite | ttl 到期时间是否伴随表的修改操作改变; 0: 不改变1改变 ;默认值 为 | | ttlChangeOnWrite | ttl 到期时间是否伴随表的修改操作改变; 0: 不改变1改变 ;默认值 为 |
| tmqMaxTopicNum| 订阅最多可建立的 topic 数量; 取值范围 1-10000缺省值 为20 | | tmqMaxTopicNum | 订阅最多可建立的 topic 数量; 取值范围 1-10000缺省值 为20 |
|maxTsmaNum | 集群内可创建的TSMA个数取值范围0-3缺省值: 3| | maxTsmaNum | 集群内可创建的TSMA个数取值范围0-3缺省值: 3 |
## taosd 监控指标
taosd 会将监控指标上报给 taosKeeper这些监控指标会被 taosKeeper 写入监控数据库,默认是 `log` 库,可以在 taoskeeper 配置文件中修改。以下是这些监控指标的详细介绍。
### taosd\_cluster\_basic 表
`taosd_cluster_basic` 表记录集群基础信息。
| field | type | is\_tag | comment |
| :------------------- | :-------- | :------ | :------------------------------ |
| ts | TIMESTAMP | | timestamp |
| first\_ep | VARCHAR | | 集群 first ep |
| first\_ep\_dnode\_id | INT | | 集群 first ep 的 dnode id |
| cluster_version | VARCHAR | | tdengine version。例如3.0.4.0 |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_cluster\_info 表
`taosd_cluster_info` 表记录集群信息。
| field | type | is\_tag | comment |
| :----------------------- | :-------- | :------ | :----------------------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| cluster_uptime | DOUBLE | | 当前 master 节点的uptime。单位秒 |
| dbs\_total | DOUBLE | | database 总数 |
| tbs\_total | DOUBLE | | 当前集群 table 总数 |
| stbs\_total | DOUBLE | | 当前集群 stable 总数 |
| dnodes\_total | DOUBLE | | 当前集群 dnode 总数 |
| dnodes\_alive | DOUBLE | | 当前集群 dnode 存活总数 |
| mnodes\_total | DOUBLE | | 当前集群 mnode 总数 |
| mnodes\_alive | DOUBLE | | 当前集群 mnode 存活总数 |
| vgroups\_total | DOUBLE | | 当前集群 vgroup 总数 |
| vgroups\_alive | DOUBLE | | 当前集群 vgroup 存活总数 |
| vnodes\_total | DOUBLE | | 当前集群 vnode 总数 |
| vnodes\_alive | DOUBLE | | 当前集群 vnode 存活总数 |
| connections\_total | DOUBLE | | 当前集群连接总数 |
| topics\_total | DOUBLE | | 当前集群 topic 总数 |
| streams\_total | DOUBLE | | 当前集群 stream 总数 |
| grants_expire\_time | DOUBLE | | 认证过期时间,企业版有效,社区版为 DOUBLE 最大值 |
| grants_timeseries\_used | DOUBLE | | 已用测点数 |
| grants_timeseries\_total | DOUBLE | | 总测点数,开源版本为 DOUBLE 最大值 |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_vgroups\_info 表
`taosd_vgroups_info` 表记录虚拟节点组信息。
| field | type | is\_tag | comment |
| :------------- | :-------- | :------ | :--------------------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| tables\_num | DOUBLE | | vgroup 中 table 数量 |
| status | DOUBLE | | vgroup 状态, 取值范围unsynced = 0, ready = 1 |
| vgroup\_id | VARCHAR | TAG | vgroup id |
| database\_name | VARCHAR | TAG | vgroup 所属的 database 名字 |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_dnodes\_info 表
`taosd_dnodes_info` 记录 dnode 信息。
| field | type | is\_tag | comment |
| :---------------- | :-------- | :------ | :------------------------------------------------------------------------------------------------ |
| \_ts | TIMESTAMP | | timestamp |
| uptime | DOUBLE | | dnode uptime单位秒 |
| cpu\_engine | DOUBLE | | taosd cpu 使用率,从 `/proc/<taosd_pid>/stat` 读取 |
| cpu\_system | DOUBLE | | 服务器 cpu 使用率,从 `/proc/stat` 读取 |
| cpu\_cores | DOUBLE | | 服务器 cpu 核数 |
| mem\_engine | DOUBLE | | taosd 内存使用率,从 `/proc/<taosd_pid>/status` 读取 |
| mem\_free | DOUBLE | | 服务器可用内存,单位 KB |
| mem\_total | DOUBLE | | 服务器内存总量,单位 KB |
| disk\_used | DOUBLE | | data dir 挂载的磁盘使用量,单位 bytes |
| disk\_total | DOUBLE | | data dir 挂载的磁盘总容量,单位 bytes |
| system\_net\_in | DOUBLE | | 网络吞吐率,从 `/proc/net/dev` 中读取的 received bytes。单位 byte/s |
| system\_net\_out | DOUBLE | | 网络吞吐率,从 `/proc/net/dev` 中读取的 transmit bytes。单位 byte/s |
| io\_read | DOUBLE | | io 吞吐率,从 `/proc/<taosd_pid>/io` 中读取的 rchar 与上次数值计算之后,计算得到速度。单位 byte/s |
| io\_write | DOUBLE | | io 吞吐率,从 `/proc/<taosd_pid>/io` 中读取的 wchar 与上次数值计算之后,计算得到速度。单位 byte/s |
| io\_read\_disk | DOUBLE | | 磁盘 io 吞吐率,从 `/proc/<taosd_pid>/io` 中读取的 read_bytes。单位 byte/s |
| io\_write\_disk | DOUBLE | | 磁盘 io 吞吐率,从 `/proc/<taosd_pid>/io` 中读取的 write_bytes。单位 byte/s |
| vnodes\_num | DOUBLE | | dnode 上 vnodes 数量 |
| masters | DOUBLE | | dnode 上 master node 数量 |
| has\_mnode | DOUBLE | | dnode 是否包含 mnode取值范围包含=1,不包含=0 |
| has\_qnode | DOUBLE | | dnode 是否包含 qnode取值范围包含=1,不包含=0 |
| has\_snode | DOUBLE | | dnode 是否包含 snode取值范围包含=1,不包含=0 |
| has\_bnode | DOUBLE | | dnode 是否包含 bnode取值范围包含=1,不包含=0 |
| error\_log\_count | DOUBLE | | error 总数 |
| info\_log\_count | DOUBLE | | info 总数 |
| debug\_log\_count | DOUBLE | | debug 总数 |
| trace\_log\_count | DOUBLE | | trace 总数 |
| dnode\_id | VARCHAR | TAG | dnode id |
| dnode\_ep | VARCHAR | TAG | dnode endpoint |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_dnodes\_status 表
`taosd_dnodes_status` 表记录 dnode 状态信息。
| field | type | is\_tag | comment |
| :---------- | :-------- | :------ | :--------------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| status | DOUBLE | | dnode 状态,取值范围ready=1offline =0 |
| dnode\_id | VARCHAR | TAG | dnode id |
| dnode\_ep | VARCHAR | TAG | dnode endpoint |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_dnodes\_log\_dir 表
`taosd_dnodes_log_dir` 表记录 log 目录信息。
| field | type | is\_tag | comment |
| :---------- | :-------- | :------ | :---------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| avail | DOUBLE | | log 目录可用空间。单位 byte |
| used | DOUBLE | | log 目录已使用空间。单位 byte |
| total | DOUBLE | | log 目录空间。单位 byte |
| name | VARCHAR | TAG | log 目录名,一般为 `/var/log/taos/` |
| dnode\_id | VARCHAR | TAG | dnode id |
| dnode\_ep | VARCHAR | TAG | dnode endpoint |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_dnodes\_data\_dir 表
`taosd_dnodes_data_dir` 表记录 data 目录信息。
| field | type | is\_tag | comment |
| :---------- | :-------- | :------ | :-------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| avail | DOUBLE | | data 目录可用空间。单位 byte |
| used | DOUBLE | | data 目录已使用空间。单位 byte |
| total | DOUBLE | | data 目录空间。单位 byte |
| level | VARCHAR | TAG | 0、1、2 多级存储级别 |
| name | VARCHAR | TAG | data 目录,一般为 `/var/lib/taos` |
| dnode\_id | VARCHAR | TAG | dnode id |
| dnode\_ep | VARCHAR | TAG | dnode endpoint |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_mnodes\_info 表
`taosd_mnodes_info` 表记录 mnode 角色信息。
| field | type | is\_tag | comment |
| :---------- | :-------- | :------ | :------------------------------------------------------------------------------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| role | DOUBLE | | mnode 角色, 取值范围offline = 0,follower = 100,candidate = 101,leader = 102,error = 103,learner = 104 |
| mnode\_id | VARCHAR | TAG | master node id |
| mnode\_ep | VARCHAR | TAG | master node endpoint |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_vnodes\_role 表
`taosd_vnodes_role` 表记录虚拟节点角色信息。
| field | type | is\_tag | comment |
| :------------- | :-------- | :------ | :------------------------------------------------------------------------------------------------------ |
| \_ts | TIMESTAMP | | timestamp |
| vnode\_role | DOUBLE | | vnode 角色取值范围offline = 0,follower = 100,candidate = 101,leader = 102,error = 103,learner = 104 |
| vgroup\_id | VARCHAR | TAG | dnode id |
| dnode\_id | VARCHAR | TAG | dnode id |
| database\_name | VARCHAR | TAG | vgroup 所属的 database 名字 |
| cluster\_id | VARCHAR | TAG | cluster id |
### taosd\_sql\_req 表
`taosd_sql_req` 记录服务端 sql 请求信息。
| field | type | is\_tag | comment |
| :---------- | :-------- | :------ | :--------------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| count | DOUBLE | | sql 数量 |
| result | VARCHAR | TAG | sql的执行结果取值范围Success, Failed |
| username | VARCHAR | TAG | 执行sql的user name |
| sql\_type | VARCHAR | TAG | sql类型取值范围inserted_rows |
| dnode\_id | VARCHAR | TAG | dnode id |
| dnode\_ep | VARCHAR | TAG | dnode endpoint |
| vgroup\_id | VARCHAR | TAG | dnode id |
| cluster\_id | VARCHAR | TAG | cluster id |
### taos\_sql\_req 表
`taos_sql_req` 记录客户端 sql 请求信息。
| field | type | is\_tag | comment |
| :---------- | :-------- | :------ | :---------------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| count | DOUBLE | | sql 数量 |
| result | VARCHAR | TAG | sql的执行结果取值范围Success, Failed |
| username | VARCHAR | TAG | 执行sql的user name |
| sql\_type | VARCHAR | TAG | sql类型取值范围select, insertdelete |
| cluster\_id | VARCHAR | TAG | cluster id |
### taos\_slow\_sql 表
`taos_slow_sql` 记录客户端慢查询信息。
| field | type | is\_tag | comment |
| :---------- | :-------- | :------ | :---------------------------------------------------- |
| \_ts | TIMESTAMP | | timestamp |
| count | DOUBLE | | sql 数量 |
| result | VARCHAR | TAG | sql的执行结果取值范围Success, Failed |
| username | VARCHAR | TAG | 执行sql的user name |
| duration | VARCHAR | TAG | sql执行耗时取值范围3-10s,10-100s,100-1000s,1000s- |
| cluster\_id | VARCHAR | TAG | cluster id |

View File

@ -289,31 +289,32 @@ http 返回内容:
## taosAdapter 监控指标 ## taosAdapter 监控指标
taosAdapter 采集 http 相关指标、CPU 百分比和内存百分比。 taosAdapter 采集 REST/Websocket 相关请求的监控指标。将监控指标上报给 taosKeeper这些监控指标会被 taosKeeper 写入监控数据库,默认是 `log` 库,可以在 taoskeeper 配置文件中修改。以下是这些监控指标的详细介绍。
### http 接口 #### adapter\_requests 表
提供符合 [OpenMetrics](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md) 接口: `adapter_requests` 记录 taosadapter 监控数据。
```text | field | type | is\_tag | comment |
http://<fqdn>:6041/metrics | :----------------- | :----------- | :------ | :---------------------------------- |
``` | ts | TIMESTAMP | | timestamp |
| total | INT UNSIGNED | | 总请求数 |
### 写入 TDengine | query | INT UNSIGNED | | 查询请求数 |
| write | INT UNSIGNED | | 写入请求数 |
taosAdapter 支持将 http 监控、CPU 百分比和内存百分比写入 TDengine。 | other | INT UNSIGNED | | 其他请求数 |
| in\_process | INT UNSIGNED | | 正在处理请求数 |
有关配置参数 | success | INT UNSIGNED | | 成功请求数 |
| fail | INT UNSIGNED | | 失败请求数 |
| **配置项** | **描述** | **默认值** | | query\_success | INT UNSIGNED | | 查询成功请求数 |
|-------------------------|--------------------------------------------|----------| | query\_fail | INT UNSIGNED | | 查询失败请求数 |
| monitor.collectDuration | CPU 和内存采集间隔 | 3s | | write\_success | INT UNSIGNED | | 写入成功请求数 |
| monitor.identity | 当前taosadapter 的标识符如果不设置将使用 'hostname:port' | | | write\_fail | INT UNSIGNED | | 写入失败请求数 |
| monitor.incgroup | 是否是 cgroup 中运行(容器中运行设置为 true) | false | | other\_success | INT UNSIGNED | | 其他成功请求数 |
| monitor.writeToTD | 是否写入到 TDengine | false | | other\_fail | INT UNSIGNED | | 其他失败请求数 |
| monitor.user | TDengine 连接用户名 | root | | query\_in\_process | INT UNSIGNED | | 正在处理查询请求数 |
| monitor.password | TDengine 连接密码 | taosdata | | write\_in\_process | INT UNSIGNED | | 正在处理写入请求数 |
| monitor.writeInterval | 写入TDengine 间隔 | 30s | | endpoint | VARCHAR | | 请求端点 |
| req\_type | NCHAR | TAG | 请求类型0 为 REST1 为 Websocket |
## 结果返回条数限制 ## 结果返回条数限制
@ -342,11 +343,11 @@ taosAdapter 从 3.0.4.0 版本开始,提供参数 `smlAutoCreateDB` 来控制
在 TDengine server 2.2.x.x 或更早期版本中taosd 进程包含一个内嵌的 http 服务。如前面所述taosAdapter 是一个使用 systemd 管理的独立软件,拥有自己的进程。并且两者有一些配置参数和行为是不同的,请见下表: 在 TDengine server 2.2.x.x 或更早期版本中taosd 进程包含一个内嵌的 http 服务。如前面所述taosAdapter 是一个使用 systemd 管理的独立软件,拥有自己的进程。并且两者有一些配置参数和行为是不同的,请见下表:
| **#** | **embedded httpd** | **taosAdapter** | **comment** | | **#** | **embedded httpd** | **taosAdapter** | **comment** |
|-------|---------------------|-------------------------------|------------------------------------------------------------------------------------------------| | ----- | ------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | httpEnableRecordSql | --logLevel=debug | | | 1 | httpEnableRecordSql | --logLevel=debug | |
| 2 | httpMaxThreads | n/a | taosAdapter 自动管理线程池,无需此参数 | | 2 | httpMaxThreads | n/a | taosAdapter 自动管理线程池,无需此参数 |
| 3 | telegrafUseFieldNum | 请参考 taosAdapter telegraf 配置方法 | | 3 | telegrafUseFieldNum | 请参考 taosAdapter telegraf 配置方法 |
| 4 | restfulRowLimit | restfulRowLimit | 内嵌 httpd 默认输出 10240 行数据,最大允许值为 102400。taosAdapter 也提供 restfulRowLimit 但是默认不做限制。您可以根据实际场景需求进行配置 | | 4 | restfulRowLimit | restfulRowLimit | 内嵌 httpd 默认输出 10240 行数据,最大允许值为 102400。taosAdapter 也提供 restfulRowLimit 但是默认不做限制。您可以根据实际场景需求进行配置 |
| 5 | httpDebugFlag | 不适用 | httpdDebugFlag 对 taosAdapter 不起作用 | | 5 | httpDebugFlag | 不适用 | httpdDebugFlag 对 taosAdapter 不起作用 |
| 6 | httpDBNameMandatory | 不适用 | taosAdapter 要求 URL 中必须指定数据库名 | | 6 | httpDBNameMandatory | 不适用 | taosAdapter 要求 URL 中必须指定数据库名 |

View File

@ -90,11 +90,11 @@ taosx privileges -i ./user-pass-privileges-backup.json -t "taos:///"
可用参数列表: 可用参数列表:
| 参数 | 说明 | | 参数 | 说明 |
| ---- | ---- | | ---- | ------------------------------------ |
| -u | 包含用户基本信息(密码、是否启用等) | | -u | 包含用户基本信息(密码、是否启用等) |
| -p | 包含权限信息 | | -p | 包含权限信息 |
| -w | 包含白名单信息 | | -w | 包含白名单信息 |
`-u`/`-p` 参数应用时,将仅包含指定的信息,不带参数时,表示所有信息(用户名、密码、权限和白名单)。 `-u`/`-p` 参数应用时,将仅包含指定的信息,不带参数时,表示所有信息(用户名、密码、权限和白名单)。
@ -324,4 +324,131 @@ Linux 下 `journalctl` 查看日志的命令如下:
```bash ```bash
journalctl -u taosx [-f] journalctl -u taosx [-f]
``` ```
## taosX 监控指标
taosX 会将监控指标上报给 taosKeeper这些监控指标会被 taosKeeper 写入监控数据库,默认是 `log` 库,可以在 taoskeeper 配置文件中修改。以下是这些监控指标的详细介绍。
### taosX 服务
| 字段 | 描述 |
| -------------------------- | ----------------------------------------------------------------------------- |
| sys_cpu_cores | 系统 CPU 核数 |
| sys_total_memory | 系统总内存,单位:字节 |
| sys_used_memory | 系统已用内存, 单位:字节 |
| sys_available_memory | 系统可用内存, 单位:字节 |
| process_uptime | taosX 运行时长,单位:秒 |
| process_id | taosX 进程 ID |
| running_tasks | taosX 当前执行任务数 |
| completed_tasks | taosX 进程在一个监控周期比如10s内完成的任务数 |
| failed_tasks | taosX 进程在一个监控周期比如10s内失败的任务数 |
| process_cpu_percent | taosX 进程占用 CPU 百分比, 单位 % |
| process_memory_percent | taosX 进程占用内存百分比, 单位 % |
| process_disk_read_bytes | taosX 进程在一个监控周期比如10s内从硬盘读取的字节数的平均值单位 bytes/s |
| process_disk_written_bytes | taosX 进程在一个监控周期比如10s内写到硬盘的字节数的平均值单位 bytres/s |
### Agent
| 字段 | 描述 |
| -------------------------- | ----------------------------------------------------------------------------- |
| sys_cpu_cores | 系统 CPU 核数 |
| sys_total_memory | 系统总内存,单位:字节 |
| sys_used_memory | 系统已用内存, 单位:字节 |
| sys_available_memory | 系统可用内存, 单位:字节 |
| process_uptime | agent 运行时长,单位:秒 |
| process_id | agent 进程 id |
| process_cpu_percent | agent 进程占用 CPU 百分比 |
| process_memory_percent | agent 进程占用内存百分比 |
| process_uptime | 进程启动时间,单位秒 |
| process_disk_read_bytes | agent 进程在一个监控周期比如10s内从硬盘读取的字节数的平均值单位 bytes/s |
| process_disk_written_bytes | agent 进程在一个监控周期比如10s内写到硬盘的字节数的平均值单位 bytes/s |
### Connector
| 字段 | 描述 |
| -------------------------- | --------------------------------------------------------------------------------- |
| process_id | connector 进程 id |
| process_uptime | 进程启动时间,单位秒 |
| process_cpu_percent | 进程占用 CPU 百分比, 单位 % |
| process_memory_percent | 进程占用内存百分比, 单位 % |
| process_disk_read_bytes | connector 进程在一个监控周期比如10s内从硬盘读取的字节数的平均值单位 bytes/s |
| process_disk_written_bytes | connector 进程在一个监控周期比如10s内写到硬盘的字节数的平均值单位 bytes/s |
### taosX 通用数据源任务
| 字段 | 描述 |
| -------------------- | --------------------------------------------------------------- |
| total_execute_time | 任务累计运行时间,单位毫秒 |
| total_written_rowsls | 成功写入 TDengine 的总行数(包括重复记录) |
| total_written_points | 累计写入成功点数 (等于数据块包含的行数乘以数据块包含的列数) |
| start_time | 任务启动时间 (每次重启任务会被重置) |
| written_rows | 本次运行此任务成功写入 TDengine 的总行数(包括重复记录) |
| written_points | 本次运行写入成功点数 (等于数据块包含的行数乘以数据块包含的列数) |
| execute_time | 任务本次运行时间,单位秒 |
### taosX TDengine V2 任务
| 字段 | 描述 |
| --------------------- | -------------------------------------------------------------------- |
| read_concurrency | 并发读取数据源的数据 worker 数, 也等于并发写入 TDengine 的 worker 数 |
| total_stables | 需要迁移的超级表数据数量 |
| total_updated_tags | 累计更新 tag 数 |
| total_created_tables | 累计创建子表数 |
| total_tables | 需要迁移的子表数量 |
| total_finished_tables | 完成数据迁移的子表数 (任务中断重启可能大于实际值) |
| total_success_blocks | 累计写入成功的数据块数 |
| finished_tables | 本次运行完成迁移子表数 |
| success_blocks | 本次写入成功的数据块数 |
| created_tables | 本次运行创建子表数 |
| updated_tags | 本次运行更新 tag 数 |
### taosX TDengine V3 任务
| 字段 | 描述 |
| ---------------------- | ------------------------------------------------------- |
| total_messages | 通过 TMQ 累计收到的消息总数 |
| total_messages_of_meta | 通过 TMQ 累计收到的 Meta 类型的消息总数 |
| total_messages_of_data | 通过 TMQ 累计收到的 Data 和 MetaData 类型的消息总数 |
| total_write_raw_fails | 累计写入 raw meta 失败的次数 |
| total_success_blocks | 累计写入成功的数据块数 |
| topics | 通过 TMQ 订阅的主题数 |
| consumers | TMQ 消费者数 |
| messages | 本次运行通过 TMQ 收到的消息总数 |
| messages_of_meta | 本次运行通过 TMQ 收到的 Meta 类型的消息总数 |
| messages_of_data | 本次运行通过 TMQ 收到的 Data 和 MetaData 类型的消息总数 |
| write_raw_fails | 本次运行写入 raw meta 失败的次数 |
| success_blocks | 本次写入成功的数据块数 |
### taosX 其他数据源 任务
这些数据源包括: InfluxDBOpenTSDBOPC UAOPC DAPICSVMQTTAVEVA Historian 和 Kafka。
| 字段 | 描述 |
| ----------------------- | ----------------------------------------------------------- |
| total_received_batches | 通过 IPC Stream 收到的数据总批数 |
| total_processed_batches | 已经处理的批数 |
| total_processed_rows | 已经处理的总行数(等于每批包含数据行数之和) |
| total_inserted_sqls | 执行的 INSERT SQL 总条数 |
| total_failed_sqls | 执行失败的 INSERT SQL 总条数 |
| total_created_stables | 创建的超级表总数(可能大于实际值) |
| total_created_tables | 尝试创建子表总数(可能大于实际值) |
| total_failed_rows | 写入失败的总行数 |
| total_failed_point | 写入失败的总点数 |
| total_written_blocks | 写入成功的 raw block 总数 |
| total_failed_blocks | 写入失败的 raw block 总数 |
| received_batches | 本次运行此任务通过 IPC Stream 收到的数据总批数 |
| processed_batches | 本次运行已处理批数 |
| processed_rows | 本次处理的总行数(等于包含数据的 batch 包含的数据行数之和) |
| received_records | 本次运行此任务通过 IPC Stream 收到的数据总行数 |
| inserted_sqls | 本次运行此任务执行的 INSERT SQL 总条数 |
| failed_sqls | 本次运行此任务执行失败的 INSERT SQL 总条数 |
| created_stables | 本次运行此任务尝试创建超级表数(可能大于实际值) |
| created_tables | 本次运行此任务尝试创建子表数(可能大于实际值) |
| failed_rows | 本次运行此任务写入失败的行数 |
| failed_points | 本次运行此任务写入失败的点数 |
| written_blocks | 本次运行此任务写人成功的 raw block 数 |
| failed_blocks | 本次运行此任务写入失败的 raw block 数 |

View File

@ -317,3 +317,19 @@ scrape_configs:
在 Grafana Dashboard 菜单点击 `import`dashboard ID 填写 `18587`,点击 `Load` 按钮即可导入 `TaosKeeper Prometheus Dashboard for 3.x` dashboard。 在 Grafana Dashboard 菜单点击 `import`dashboard ID 填写 `18587`,点击 `Load` 按钮即可导入 `TaosKeeper Prometheus Dashboard for 3.x` dashboard。
## taosKeeper 监控指标
taosKeeper 也会将自己采集的监控数据写入监控数据库,默认是 `log` 库,可以在 taoskeeper 配置文件中修改。
### keeper\_monitor 表
`keeper_monitor` 记录 taoskeeper 监控数据。
| field | type | is\_tag | comment |
| :------- | :-------- | :------ | :----------- |
| ts | TIMESTAMP | | timestamp |
| cpu | DOUBLE | | cpu 使用率 |
| mem | DOUBLE | | 内存使用率 |
| identify | NCHAR | TAG | 身份标识信息 |

View File

@ -15,8 +15,8 @@ TDengine 通过 taosKeeper 将服务器的 CPU、内存、硬盘空间、带宽
首先检查下面服务: 首先检查下面服务:
- TDengine 已经安装并正常运行,此仪表盘需要 TDengine 3.0.0.0 及以上,并开启监控上报配置,具体配置请参考:[TDengine 监控配置](../taosd/#监控相关)。 - TDengine 已经安装并正常运行,此仪表盘需要 TDengine 3.0.0.0 及以上,并开启监控上报配置,具体配置请参考:[TDengine 监控配置](../taosd/#监控相关)。
- taosAdapter 已经安装并正常运行。具体细节请参考:[taosAdapter 使用手册](../taosadapter) - taosAdapter 已经安装并正常运行。具体细节请参考:[taosAdapter 参考手册](../taosadapter)
- taosKeeper 已安装并正常运行。具体细节请参考:[taosKeeper 使用手册](../taoskeeper) - taosKeeper 已安装并正常运行。具体细节请参考:[taosKeeper 参考手册](../taoskeeper)
然后记录以下信息: 然后记录以下信息:

View File

@ -1,6 +1,13 @@
--- ---
sidebar_label: 产品组件 title: 产品组件
title: 产品组件 description: TDengine 产品组件参考手册
toc_max_heading_level: 4 ---
description: TDengine 产品组件参考手册
--- 本节详细说明 TDengine 中的主要产品组件的功能、命令行参数、配置参数等。
```mdx-code-block
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
<DocCardList items={useCurrentSidebarCategory().items}/>
```

View File

@ -118,3 +118,9 @@ import VerifyMacOS from "./_verify_macos.mdx";
</TabItem> </TabItem>
</Tabs> </Tabs>
```mdx-code-block
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
<DocCardList items={useCurrentSidebarCategory().items}/>
```

View File

@ -301,7 +301,7 @@ TDengine 采用了一种数据驱动的策略来实现缓存数据的持久化
对于采集的数据,通常会有一定的保留期限,该期限由数据库参数 keep 指定。超出设定天数的数据文件将被集群自动移除,并释放相应的存储空间。 对于采集的数据,通常会有一定的保留期限,该期限由数据库参数 keep 指定。超出设定天数的数据文件将被集群自动移除,并释放相应的存储空间。
当设置 duration 和 keep 两个参数后,一个处于典型工作状态的 vnode 中,总的数据文件数量应为向上取整 (keep/duration)+1 个。数据文件的总个数应保持在一个合理的范围内,不宜过多也不宜过少,通常介于 10 到 100 之间较为适宜。基于这一原则,可以合理设置 duration 参数。在本书编写时的版本中,可以调整参数 keep但参数 duration 一旦设定,则无法更改。 当设置 duration 和 keep 两个参数后,一个处于典型工作状态的 vnode 中,总的数据文件数量应为向上取整 (keep/duration)+1 个。数据文件的总个数应保持在一个合理的范围内,不宜过多也不宜过少,通常介于 10 到 100 之间较为适宜。基于这一原则,可以合理设置 duration 参数。可以调整参数 keep但参数 duration 一旦设定,则无法更改。
在每个数据文件中,表的数据是以块的形式存储的。一张表可能包含一到多个数据文件块。在一个文件块内,数据采用列式存储,占据连续的存储空间,这有助于显著提高读取度。文件块的大小由数据库参数 maxRows每块最大记录条数控制默认值为 4096。这个值应适中过大可能导致定位特定时间段数据的搜索时间变长影响读取速度过小则可能导致数据文件块的索引过大压缩效率降低同样影响读取速度。 在每个数据文件中,表的数据是以块的形式存储的。一张表可能包含一到多个数据文件块。在一个文件块内,数据采用列式存储,占据连续的存储空间,这有助于显著提高读取度。文件块的大小由数据库参数 maxRows每块最大记录条数控制默认值为 4096。这个值应适中过大可能导致定位特定时间段数据的搜索时间变长影响读取速度过小则可能导致数据文件块的索引过大压缩效率降低同样影响读取速度。

View File

@ -270,7 +270,10 @@ DLL_EXPORT TAOS_RES *taos_schemaless_insert_raw_ttl(TAOS *taos, char *lines, int
int precision, int32_t ttl); int precision, int32_t ttl);
DLL_EXPORT TAOS_RES *taos_schemaless_insert_raw_ttl_with_reqid(TAOS *taos, char *lines, int len, int32_t *totalRows, DLL_EXPORT TAOS_RES *taos_schemaless_insert_raw_ttl_with_reqid(TAOS *taos, char *lines, int len, int32_t *totalRows,
int protocol, int precision, int32_t ttl, int64_t reqid); int protocol, int precision, int32_t ttl, int64_t reqid);
DLL_EXPORT TAOS_RES *taos_schemaless_insert_raw_ttl_with_reqid_tbname_key(TAOS *taos, char *lines, int len, int32_t *totalRows,
int protocol, int precision, int32_t ttl, int64_t reqid, char *tbnameKey);
DLL_EXPORT TAOS_RES *taos_schemaless_insert_ttl_with_reqid_tbname_key(TAOS *taos, char *lines[], int numLines, int protocol,
int precision, int32_t ttl, int64_t reqid, char *tbnameKey);
/* --------------------------TMQ INTERFACE------------------------------- */ /* --------------------------TMQ INTERFACE------------------------------- */
typedef struct tmq_t tmq_t; typedef struct tmq_t tmq_t;

View File

@ -246,12 +246,12 @@ typedef struct SStoreSnapshotFn {
} SStoreSnapshotFn; } SStoreSnapshotFn;
typedef struct SStoreMeta { typedef struct SStoreMeta {
SMTbCursor* (*openTableMetaCursor)(void* pVnode); // metaOpenTbCursor SMTbCursor* (*openTableMetaCursor)(void* pVnode); // metaOpenTbCursor
void (*closeTableMetaCursor)(SMTbCursor* pTbCur); // metaCloseTbCursor void (*closeTableMetaCursor)(SMTbCursor* pTbCur); // metaCloseTbCursor
void (*pauseTableMetaCursor)(SMTbCursor* pTbCur); // metaPauseTbCursor void (*pauseTableMetaCursor)(SMTbCursor* pTbCur); // metaPauseTbCursor
void (*resumeTableMetaCursor)(SMTbCursor* pTbCur, int8_t first, int8_t move); // metaResumeTbCursor int32_t (*resumeTableMetaCursor)(SMTbCursor* pTbCur, int8_t first, int8_t move); // metaResumeTbCursor
int32_t (*cursorNext)(SMTbCursor* pTbCur, ETableType jumpTableType); // metaTbCursorNext int32_t (*cursorNext)(SMTbCursor* pTbCur, ETableType jumpTableType); // metaTbCursorNext
int32_t (*cursorPrev)(SMTbCursor* pTbCur, ETableType jumpTableType); // metaTbCursorPrev int32_t (*cursorPrev)(SMTbCursor* pTbCur, ETableType jumpTableType); // metaTbCursorPrev
int32_t (*getTableTags)(void* pVnode, uint64_t suid, SArray* uidList); int32_t (*getTableTags)(void* pVnode, uint64_t suid, SArray* uidList);
int32_t (*getTableTagsByUid)(void* pVnode, int64_t suid, SArray* uidList); int32_t (*getTableTagsByUid)(void* pVnode, int64_t suid, SArray* uidList);

View File

@ -320,6 +320,30 @@ typedef int32_t (*TScriptUdfDestoryFunc)(void *udfCtx);
typedef int32_t (*TScriptOpenFunc)(SScriptUdfEnvItem *items, int numItems); typedef int32_t (*TScriptOpenFunc)(SScriptUdfEnvItem *items, int numItems);
typedef int32_t (*TScriptCloseFunc)(); typedef int32_t (*TScriptCloseFunc)();
// clang-format off
#ifdef WINDOWS
#define fnFatal(...) {}
#define fnError(...) {}
#define fnWarn(...) {}
#define fnInfo(...) {}
#define fnDebug(...) {}
#define fnTrace(...) {}
#else
DLL_EXPORT void taosPrintLog(const char *flags, int32_t level, int32_t dflag, const char *format, ...)
#ifdef __GNUC__
__attribute__((format(printf, 4, 5)))
#endif
;
extern int32_t udfDebugFlag;
#define udfFatal(...) { if (udfDebugFlag & 1) { taosPrintLog("UDF FATAL ", 1, 255, __VA_ARGS__); }}
#define udfError(...) { if (udfDebugFlag & 1) { taosPrintLog("UDF ERROR ", 1, 255, __VA_ARGS__); }}
#define udfWarn(...) { if (udfDebugFlag & 2) { taosPrintLog("UDF WARN ", 2, 255, __VA_ARGS__); }}
#define udfInfo(...) { if (udfDebugFlag & 2) { taosPrintLog("UDF ", 2, 255, __VA_ARGS__); }}
#define udfDebug(...) { if (udfDebugFlag & 4) { taosPrintLog("UDF ", 4, udfDebugFlag, __VA_ARGS__); }}
#define udfTrace(...) { if (udfDebugFlag & 8) { taosPrintLog("UDF ", 8, udfDebugFlag, __VA_ARGS__); }}
#endif
// clang-format on
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -49,6 +49,7 @@ int32_t InitRegexCache();
void DestroyRegexCache(); void DestroyRegexCache();
int32_t patternMatch(const char *pattern, size_t psize, const char *str, size_t ssize, const SPatternCompareInfo *pInfo); int32_t patternMatch(const char *pattern, size_t psize, const char *str, size_t ssize, const SPatternCompareInfo *pInfo);
int32_t checkRegexPattern(const char *pPattern); int32_t checkRegexPattern(const char *pPattern);
void DestoryThreadLocalRegComp();
int32_t wcsPatternMatch(const TdUcs4 *pattern, size_t psize, const TdUcs4 *str, size_t ssize, const SPatternCompareInfo *pInfo); int32_t wcsPatternMatch(const TdUcs4 *pattern, size_t psize, const TdUcs4 *str, size_t ssize, const SPatternCompareInfo *pInfo);

View File

@ -74,13 +74,13 @@ void taosCloseLog();
void taosResetLog(); void taosResetLog();
void taosDumpData(uint8_t *msg, int32_t len); void taosDumpData(uint8_t *msg, int32_t len);
void taosPrintLog(const char *flags, ELogLevel level, int32_t dflag, const char *format, ...) void taosPrintLog(const char *flags, int32_t level, int32_t dflag, const char *format, ...)
#ifdef __GNUC__ #ifdef __GNUC__
__attribute__((format(printf, 4, 5))) __attribute__((format(printf, 4, 5)))
#endif #endif
; ;
void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, const char *format, ...) void taosPrintLongString(const char *flags, int32_t level, int32_t dflag, const char *format, ...)
#ifdef __GNUC__ #ifdef __GNUC__
__attribute__((format(printf, 4, 5))) __attribute__((format(printf, 4, 5)))
#endif #endif

View File

@ -204,6 +204,7 @@ typedef struct {
STableMeta *currSTableMeta; STableMeta *currSTableMeta;
STableDataCxt *currTableDataCtx; STableDataCxt *currTableDataCtx;
bool needModifySchema; bool needModifySchema;
char *tbnameKey;
} SSmlHandle; } SSmlHandle;
extern int64_t smlFactorNS[]; extern int64_t smlFactorNS[];
@ -219,9 +220,10 @@ bool smlParseNumberOld(SSmlKv *kvVal, SSmlMsgBuf *msg);
void smlBuildInvalidDataMsg(SSmlMsgBuf *pBuf, const char *msg1, const char *msg2); void smlBuildInvalidDataMsg(SSmlMsgBuf *pBuf, const char *msg1, const char *msg2);
int32_t smlParseNumber(SSmlKv *kvVal, SSmlMsgBuf *msg); int32_t smlParseNumber(SSmlKv *kvVal, SSmlMsgBuf *msg);
int64_t smlGetTimeValue(const char *value, int32_t len, uint8_t fromPrecision, uint8_t toPrecision); int64_t smlGetTimeValue(const char *value, int32_t len, uint8_t fromPrecision, uint8_t toPrecision);
int32_t smlBuildTableInfo(int numRows, const char* measure, int32_t measureLen, SSmlTableInfo** tInfo);
int32_t smlBuildTableInfo(int numRows, const char* measure, int32_t measureLen, SSmlTableInfo** tInfo);
int32_t smlBuildSTableMeta(bool isDataFormat, SSmlSTableMeta** sMeta); int32_t smlBuildSTableMeta(bool isDataFormat, SSmlSTableMeta** sMeta);
int32_t smlSetCTableName(SSmlTableInfo *oneTable); int32_t smlSetCTableName(SSmlTableInfo *oneTable, char *tbnameKey);
int32_t getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tinfo); int32_t getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tinfo);
int32_t smlGetMeta(SSmlHandle *info, const void* measure, int32_t measureLen, STableMeta **pTableMeta); int32_t smlGetMeta(SSmlHandle *info, const void* measure, int32_t measureLen, STableMeta **pTableMeta);
int32_t is_same_child_table_telnet(const void *a, const void *b); int32_t is_same_child_table_telnet(const void *a, const void *b);

View File

@ -374,8 +374,8 @@ int32_t openTransporter(const char *user, const char *auth, int32_t numOfThread,
*pDnodeConn = rpcOpen(&rpcInit); *pDnodeConn = rpcOpen(&rpcInit);
if (*pDnodeConn == NULL) { if (*pDnodeConn == NULL) {
tscError("failed to init connection to server."); tscError("failed to init connection to server since %s", tstrerror(terrno));
code = TSDB_CODE_FAILED; code = terrno;
} }
return code; return code;
@ -526,19 +526,17 @@ int32_t createRequest(uint64_t connId, int32_t type, int64_t reqid, SRequestObj
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
*pRequest = (SRequestObj *)taosMemoryCalloc(1, sizeof(SRequestObj)); *pRequest = (SRequestObj *)taosMemoryCalloc(1, sizeof(SRequestObj));
if (NULL == *pRequest) { if (NULL == *pRequest) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
STscObj *pTscObj = acquireTscObj(connId); STscObj *pTscObj = acquireTscObj(connId);
if (pTscObj == NULL) { if (pTscObj == NULL) {
code = TSDB_CODE_TSC_DISCONNECTED; TSC_ERR_JRET(TSDB_CODE_TSC_DISCONNECTED);
goto _return;
} }
SSyncQueryParam *interParam = taosMemoryCalloc(1, sizeof(SSyncQueryParam)); SSyncQueryParam *interParam = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
if (interParam == NULL) { if (interParam == NULL) {
releaseTscObj(connId); releaseTscObj(connId);
code = TSDB_CODE_OUT_OF_MEMORY; TSC_ERR_JRET(terrno);
goto _return;
} }
TSC_ERR_JRET(tsem_init(&interParam->sem, 0, 0)); TSC_ERR_JRET(tsem_init(&interParam->sem, 0, 0));
interParam->pRequest = *pRequest; interParam->pRequest = *pRequest;
@ -566,7 +564,11 @@ int32_t createRequest(uint64_t connId, int32_t type, int64_t reqid, SRequestObj
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
_return: _return:
doDestroyRequest(*pRequest); if ((*pRequest)->pTscObj) {
doDestroyRequest(*pRequest);
} else {
taosMemoryFree(*pRequest);
}
return code; return code;
} }
@ -869,7 +871,7 @@ _return:
TSC_ERR_RET(terrno); TSC_ERR_RET(terrno);
} }
return TSDB_CODE_SUCCESS; return code;
} }
void tscStopCrashReport() { void tscStopCrashReport() {

View File

@ -1405,7 +1405,7 @@ _return:
TSC_ERR_RET(terrno); TSC_ERR_RET(terrno);
} }
return TSDB_CODE_SUCCESS; return code;
} }
static void hbStopThread() { static void hbStopThread() {

View File

@ -2467,7 +2467,8 @@ TSDB_SERVER_STATUS taos_check_server_status(const char* fqdn, int port, char* de
clientRpc = rpcOpen(&rpcInit); clientRpc = rpcOpen(&rpcInit);
if (clientRpc == NULL) { if (clientRpc == NULL) {
tscError("failed to init server status client"); code = terrno;
tscError("failed to init server status client since %s", tstrerror(code));
goto _OVER; goto _OVER;
} }

View File

@ -402,7 +402,7 @@ int32_t smlProcessChildTable(SSmlHandle *info, SSmlLineInfo *elements) {
if (kv->valueEscaped) kv->value = NULL; if (kv->valueEscaped) kv->value = NULL;
} }
code = smlSetCTableName(tinfo); code = smlSetCTableName(tinfo, info->tbnameKey);
if (code != TSDB_CODE_SUCCESS){ if (code != TSDB_CODE_SUCCESS){
smlDestroyTableInfo(&tinfo); smlDestroyTableInfo(&tinfo);
return code; return code;
@ -486,10 +486,10 @@ int32_t smlParseEndLine(SSmlHandle *info, SSmlLineInfo *elements, SSmlKv *kvTs)
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t smlParseTableName(SArray *tags, char *childTableName) { static int32_t smlParseTableName(SArray *tags, char *childTableName, char *tbnameKey) {
bool autoChildName = false; bool autoChildName = false;
size_t delimiter = strlen(tsSmlAutoChildTableNameDelimiter); size_t delimiter = strlen(tsSmlAutoChildTableNameDelimiter);
if (delimiter > 0) { if(delimiter > 0 && tbnameKey == NULL){
size_t totalNameLen = delimiter * (taosArrayGetSize(tags) - 1); size_t totalNameLen = delimiter * (taosArrayGetSize(tags) - 1);
for (int i = 0; i < taosArrayGetSize(tags); i++) { for (int i = 0; i < taosArrayGetSize(tags); i++) {
SSmlKv *tag = (SSmlKv *)taosArrayGet(tags, i); SSmlKv *tag = (SSmlKv *)taosArrayGet(tags, i);
@ -517,8 +517,11 @@ static int32_t smlParseTableName(SArray *tags, char *childTableName) {
if (tsSmlDot2Underline) { if (tsSmlDot2Underline) {
smlStrReplace(childTableName, strlen(childTableName)); smlStrReplace(childTableName, strlen(childTableName));
} }
} else { }else{
size_t childTableNameLen = strlen(tsSmlChildTableName); if (tbnameKey == NULL){
tbnameKey = tsSmlChildTableName;
}
size_t childTableNameLen = strlen(tbnameKey);
if (childTableNameLen <= 0) return TSDB_CODE_SUCCESS; if (childTableNameLen <= 0) return TSDB_CODE_SUCCESS;
for (int i = 0; i < taosArrayGetSize(tags); i++) { for (int i = 0; i < taosArrayGetSize(tags); i++) {
@ -527,7 +530,7 @@ static int32_t smlParseTableName(SArray *tags, char *childTableName) {
return TSDB_CODE_SML_INVALID_DATA; return TSDB_CODE_SML_INVALID_DATA;
} }
// handle child table name // handle child table name
if (childTableNameLen == tag->keyLen && strncmp(tag->key, tsSmlChildTableName, tag->keyLen) == 0) { if (childTableNameLen == tag->keyLen && strncmp(tag->key, tbnameKey, tag->keyLen) == 0) {
(void)memset(childTableName, 0, TSDB_TABLE_NAME_LEN); (void)memset(childTableName, 0, TSDB_TABLE_NAME_LEN);
(void)strncpy(childTableName, tag->value, (tag->length < TSDB_TABLE_NAME_LEN ? tag->length : TSDB_TABLE_NAME_LEN)); (void)strncpy(childTableName, tag->value, (tag->length < TSDB_TABLE_NAME_LEN ? tag->length : TSDB_TABLE_NAME_LEN));
if (tsSmlDot2Underline) { if (tsSmlDot2Underline) {
@ -542,8 +545,8 @@ static int32_t smlParseTableName(SArray *tags, char *childTableName) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t smlSetCTableName(SSmlTableInfo *oneTable) { int32_t smlSetCTableName(SSmlTableInfo *oneTable, char *tbnameKey) {
int32_t code = smlParseTableName(oneTable->tags, oneTable->childTableName); int32_t code = smlParseTableName(oneTable->tags, oneTable->childTableName, tbnameKey);
if(code != TSDB_CODE_SUCCESS){ if(code != TSDB_CODE_SUCCESS){
return code; return code;
} }
@ -2127,7 +2130,7 @@ void smlSetReqSQL(SRequestObj *request, char *lines[], char *rawLine, char *rawL
} }
TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine, char *rawLineEnd, int numLines, TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine, char *rawLineEnd, int numLines,
int protocol, int precision, int32_t ttl, int64_t reqid) { int protocol, int precision, int32_t ttl, int64_t reqid, char *tbnameKey) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
if (NULL == taos) { if (NULL == taos) {
uError("SML:taos_schemaless_insert error taos is null"); uError("SML:taos_schemaless_insert error taos is null");
@ -2159,6 +2162,7 @@ TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine,
info->msgBuf.buf = info->pRequest->msgBuf; info->msgBuf.buf = info->pRequest->msgBuf;
info->msgBuf.len = ERROR_MSG_BUF_DEFAULT_SIZE; info->msgBuf.len = ERROR_MSG_BUF_DEFAULT_SIZE;
info->lineNum = numLines; info->lineNum = numLines;
info->tbnameKey = tbnameKey;
smlSetReqSQL(request, lines, rawLine, rawLineEnd); smlSetReqSQL(request, lines, rawLine, rawLineEnd);
@ -2237,9 +2241,14 @@ end:
* @return TAOS_RES * @return TAOS_RES
*/ */
TAOS_RES *taos_schemaless_insert_ttl_with_reqid_tbname_key(TAOS *taos, char *lines[], int numLines, int protocol,
int precision, int32_t ttl, int64_t reqid, char *tbnameKey){
return taos_schemaless_insert_inner(taos, lines, NULL, NULL, numLines, protocol, precision, ttl, reqid, tbnameKey);
}
TAOS_RES *taos_schemaless_insert_ttl_with_reqid(TAOS *taos, char *lines[], int numLines, int protocol, int precision, TAOS_RES *taos_schemaless_insert_ttl_with_reqid(TAOS *taos, char *lines[], int numLines, int protocol, int precision,
int32_t ttl, int64_t reqid) { int32_t ttl, int64_t reqid) {
return taos_schemaless_insert_inner(taos, lines, NULL, NULL, numLines, protocol, precision, ttl, reqid); return taos_schemaless_insert_ttl_with_reqid_tbname_key(taos, lines, numLines, protocol, precision, ttl, reqid, NULL);
} }
TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision) { TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision) {
@ -2272,10 +2281,15 @@ static void getRawLineLen(char *lines, int len, int32_t *totalRows, int protocol
} }
} }
TAOS_RES *taos_schemaless_insert_raw_ttl_with_reqid_tbname_key(TAOS *taos, char *lines, int len, int32_t *totalRows,
int protocol, int precision, int32_t ttl, int64_t reqid, char *tbnameKey){
getRawLineLen(lines, len, totalRows, protocol);
return taos_schemaless_insert_inner(taos, NULL, lines, lines + len, *totalRows, protocol, precision, ttl, reqid, tbnameKey);
}
TAOS_RES *taos_schemaless_insert_raw_ttl_with_reqid(TAOS *taos, char *lines, int len, int32_t *totalRows, int protocol, TAOS_RES *taos_schemaless_insert_raw_ttl_with_reqid(TAOS *taos, char *lines, int len, int32_t *totalRows, int protocol,
int precision, int32_t ttl, int64_t reqid) { int precision, int32_t ttl, int64_t reqid) {
getRawLineLen(lines, len, totalRows, protocol); return taos_schemaless_insert_raw_ttl_with_reqid_tbname_key(taos, lines, len, totalRows, protocol, precision, ttl, reqid, NULL);
return taos_schemaless_insert_inner(taos, NULL, lines, lines + len, *totalRows, protocol, precision, ttl, reqid);
} }
TAOS_RES *taos_schemaless_insert_raw_with_reqid(TAOS *taos, char *lines, int len, int32_t *totalRows, int protocol, TAOS_RES *taos_schemaless_insert_raw_with_reqid(TAOS *taos, char *lines, int len, int32_t *totalRows, int protocol,

View File

@ -1275,7 +1275,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
// init semaphore // init semaphore
if (tsem2_init(&pTmq->rspSem, 0, 0) != 0) { if (tsem2_init(&pTmq->rspSem, 0, 0) != 0) {
tscError("consumer:0x %" PRIx64 " setup failed since %s, consumer group %s", pTmq->consumerId, terrstr(), tscError("consumer:0x %" PRIx64 " setup failed since %s, consumer group %s", pTmq->consumerId, tstrerror(TAOS_SYSTEM_ERROR(errno)),
pTmq->groupId); pTmq->groupId);
SET_ERROR_MSG_TMQ("init t_sem failed") SET_ERROR_MSG_TMQ("init t_sem failed")
goto _failed; goto _failed;

View File

@ -393,8 +393,8 @@ int32_t dmInitClient(SDnode *pDnode) {
pTrans->clientRpc = rpcOpen(&rpcInit); pTrans->clientRpc = rpcOpen(&rpcInit);
if (pTrans->clientRpc == NULL) { if (pTrans->clientRpc == NULL) {
dError("failed to init dnode rpc client"); dError("failed to init dnode rpc client since:%s", tstrerror(terrno));
return -1; return terrno;
} }
dDebug("dnode rpc client is initialized"); dDebug("dnode rpc client is initialized");
@ -437,8 +437,8 @@ int32_t dmInitStatusClient(SDnode *pDnode) {
pTrans->statusRpc = rpcOpen(&rpcInit); pTrans->statusRpc = rpcOpen(&rpcInit);
if (pTrans->statusRpc == NULL) { if (pTrans->statusRpc == NULL) {
dError("failed to init dnode rpc status client"); dError("failed to init dnode rpc status client since %s", tstrerror(terrno));
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
dDebug("dnode rpc status client is initialized"); dDebug("dnode rpc status client is initialized");
@ -482,8 +482,8 @@ int32_t dmInitSyncClient(SDnode *pDnode) {
pTrans->syncRpc = rpcOpen(&rpcInit); pTrans->syncRpc = rpcOpen(&rpcInit);
if (pTrans->syncRpc == NULL) { if (pTrans->syncRpc == NULL) {
dError("failed to init dnode rpc sync client"); dError("failed to init dnode rpc sync client since %s", tstrerror(terrno));
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
dDebug("dnode rpc sync client is initialized"); dDebug("dnode rpc sync client is initialized");
@ -532,7 +532,7 @@ int32_t dmInitServer(SDnode *pDnode) {
(void)taosVersionStrToInt(version, &(rpcInit.compatibilityVer)); (void)taosVersionStrToInt(version, &(rpcInit.compatibilityVer));
pTrans->serverRpc = rpcOpen(&rpcInit); pTrans->serverRpc = rpcOpen(&rpcInit);
if (pTrans->serverRpc == NULL) { if (pTrans->serverRpc == NULL) {
dError("failed to init dnode rpc server"); dError("failed to init dnode rpc server since:%s", tstrerror(terrno));
return terrno; return terrno;
} }

View File

@ -46,7 +46,7 @@ const char *mndConsumerStatusName(int status);
#define MND_TMQ_NULL_CHECK(c) \ #define MND_TMQ_NULL_CHECK(c) \
do { \ do { \
if (c == NULL) { \ if (c == NULL) { \
code = TSDB_CODE_OUT_OF_MEMORY; \ code = TAOS_GET_TERRNO(TSDB_CODE_OUT_OF_MEMORY); \
goto END; \ goto END; \
} \ } \
} while (0) } while (0)

View File

@ -882,7 +882,7 @@ static int32_t buildRebOutput(SMnode *pMnode, SMqRebInputObj *rebInput, SMqRebOu
rebInput->oldConsumerNum = 0; rebInput->oldConsumerNum = 0;
code = mndCreateSubscription(pMnode, pTopic, key, &rebOutput->pSub); code = mndCreateSubscription(pMnode, pTopic, key, &rebOutput->pSub);
if (code != 0) { if (code != 0) {
mError("[rebalance] mq rebalance %s failed create sub since %s, ignore", key, terrstr()); mError("[rebalance] mq rebalance %s failed create sub since %s, ignore", key, tstrerror(code));
taosRUnLockLatch(&pTopic->lock); taosRUnLockLatch(&pTopic->lock);
mndReleaseTopic(pMnode, pTopic); mndReleaseTopic(pMnode, pTopic);
return code; return code;
@ -1067,7 +1067,7 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg) {
return 0; return 0;
} else { } else {
code = TSDB_CODE_MND_SUBSCRIBE_NOT_EXIST; code = TSDB_CODE_MND_SUBSCRIBE_NOT_EXIST;
mError("topic:%s, cgroup:%s, failed to drop since %s", dropReq.topic, dropReq.cgroup, terrstr()); mError("topic:%s, cgroup:%s, failed to drop since %s", dropReq.topic, dropReq.cgroup, tstrerror(code));
return code; return code;
} }
} }
@ -1075,7 +1075,7 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg) {
taosWLockLatch(&pSub->lock); taosWLockLatch(&pSub->lock);
if (taosHashGetSize(pSub->consumerHash) != 0) { if (taosHashGetSize(pSub->consumerHash) != 0) {
code = TSDB_CODE_MND_CGROUP_USED; code = TSDB_CODE_MND_CGROUP_USED;
mError("cgroup:%s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr()); mError("cgroup:%s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, tstrerror(code));
goto END; goto END;
} }

View File

@ -574,7 +574,7 @@ static int32_t mndProcessCreateTopicReq(SRpcMsg *pReq) {
END: END:
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
mError("failed to create topic:%s since %s", createTopicReq.name, terrstr()); mError("failed to create topic:%s since %s", createTopicReq.name, tstrerror(code));
} }
mndReleaseTopic(pMnode, pTopic); mndReleaseTopic(pMnode, pTopic);
@ -699,7 +699,7 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
tFreeSMDropTopicReq(&dropReq); tFreeSMDropTopicReq(&dropReq);
return 0; return 0;
} else { } else {
mError("topic:%s, failed to drop since %s", dropReq.name, terrstr()); mError("topic:%s, failed to drop since %s", dropReq.name, tstrerror(code));
tFreeSMDropTopicReq(&dropReq); tFreeSMDropTopicReq(&dropReq);
return code; return code;
} }
@ -727,7 +727,7 @@ END:
mndReleaseTopic(pMnode, pTopic); mndReleaseTopic(pMnode, pTopic);
mndTransDrop(pTrans); mndTransDrop(pTrans);
if (code != 0) { if (code != 0) {
mError("topic:%s, failed to drop since %s", dropReq.name, terrstr()); mError("topic:%s, failed to drop since %s", dropReq.name, tstrerror(code));
tFreeSMDropTopicReq(&dropReq); tFreeSMDropTopicReq(&dropReq);
return code; return code;
} }

View File

@ -131,7 +131,7 @@ typedef SVCreateTSmaReq SSmaCfg;
SMTbCursor* metaOpenTbCursor(void* pVnode); SMTbCursor* metaOpenTbCursor(void* pVnode);
void metaCloseTbCursor(SMTbCursor* pTbCur); void metaCloseTbCursor(SMTbCursor* pTbCur);
void metaPauseTbCursor(SMTbCursor* pTbCur); void metaPauseTbCursor(SMTbCursor* pTbCur);
void metaResumeTbCursor(SMTbCursor* pTbCur, int8_t first, int8_t move); int32_t metaResumeTbCursor(SMTbCursor* pTbCur, int8_t first, int8_t move);
int32_t metaTbCursorNext(SMTbCursor* pTbCur, ETableType jumpTableType); int32_t metaTbCursorNext(SMTbCursor* pTbCur, ETableType jumpTableType);
int32_t metaTbCursorPrev(SMTbCursor* pTbCur, ETableType jumpTableType); int32_t metaTbCursorPrev(SMTbCursor* pTbCur, ETableType jumpTableType);

View File

@ -231,6 +231,7 @@ _exit:
#if 1 // =================================================== #if 1 // ===================================================
SMTbCursor *metaOpenTbCursor(void *pVnode) { SMTbCursor *metaOpenTbCursor(void *pVnode) {
SMTbCursor *pTbCur = NULL; SMTbCursor *pTbCur = NULL;
int32_t code;
pTbCur = (SMTbCursor *)taosMemoryCalloc(1, sizeof(*pTbCur)); pTbCur = (SMTbCursor *)taosMemoryCalloc(1, sizeof(*pTbCur));
if (pTbCur == NULL) { if (pTbCur == NULL) {
@ -241,7 +242,12 @@ SMTbCursor *metaOpenTbCursor(void *pVnode) {
// tdbTbcMoveToFirst((TBC *)pTbCur->pDbc); // tdbTbcMoveToFirst((TBC *)pTbCur->pDbc);
pTbCur->pMeta = pVnodeObj->pMeta; pTbCur->pMeta = pVnodeObj->pMeta;
pTbCur->paused = 1; pTbCur->paused = 1;
metaResumeTbCursor(pTbCur, 1, 0); code = metaResumeTbCursor(pTbCur, 1, 0);
if (code) {
terrno = code;
taosMemoryFree(pTbCur);
return NULL;
}
return pTbCur; return pTbCur;
} }
@ -266,28 +272,39 @@ void metaPauseTbCursor(SMTbCursor *pTbCur) {
pTbCur->paused = 1; pTbCur->paused = 1;
} }
} }
void metaResumeTbCursor(SMTbCursor *pTbCur, int8_t first, int8_t move) { int32_t metaResumeTbCursor(SMTbCursor *pTbCur, int8_t first, int8_t move) {
int32_t code = 0;
int32_t lino;
if (pTbCur->paused) { if (pTbCur->paused) {
metaReaderDoInit(&pTbCur->mr, pTbCur->pMeta, META_READER_LOCK); metaReaderDoInit(&pTbCur->mr, pTbCur->pMeta, META_READER_LOCK);
(void)tdbTbcOpen(((SMeta *)pTbCur->pMeta)->pUidIdx, (TBC **)&pTbCur->pDbc, NULL); code = tdbTbcOpen(((SMeta *)pTbCur->pMeta)->pUidIdx, (TBC **)&pTbCur->pDbc, NULL);
TSDB_CHECK_CODE(code, lino, _exit);
if (first) { if (first) {
(void)tdbTbcMoveToFirst((TBC *)pTbCur->pDbc); code = tdbTbcMoveToFirst((TBC *)pTbCur->pDbc);
TSDB_CHECK_CODE(code, lino, _exit);
} else { } else {
int c = 1; int c = 1;
(void)tdbTbcMoveTo(pTbCur->pDbc, pTbCur->pKey, pTbCur->kLen, &c); code = tdbTbcMoveTo(pTbCur->pDbc, pTbCur->pKey, pTbCur->kLen, &c);
TSDB_CHECK_CODE(code, lino, _exit);
if (c == 0) { if (c == 0) {
if (move) tdbTbcMoveToNext(pTbCur->pDbc); if (move) tdbTbcMoveToNext(pTbCur->pDbc);
} else if (c < 0) { } else if (c < 0) {
(void)tdbTbcMoveToPrev(pTbCur->pDbc); code = tdbTbcMoveToPrev(pTbCur->pDbc);
TSDB_CHECK_CODE(code, lino, _exit);
} else { } else {
(void)tdbTbcMoveToNext(pTbCur->pDbc); code = tdbTbcMoveToNext(pTbCur->pDbc);
TSDB_CHECK_CODE(code, lino, _exit);
} }
} }
pTbCur->paused = 0; pTbCur->paused = 0;
} }
_exit:
return code;
} }
int32_t metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType) { int32_t metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType) {
@ -355,7 +372,9 @@ _query:
version = ((SUidIdxVal *)pData)[0].version; version = ((SUidIdxVal *)pData)[0].version;
(void)tdbTbGet(pMeta->pTbDb, &(STbDbKey){.uid = uid, .version = version}, sizeof(STbDbKey), &pData, &nData); if (tdbTbGet(pMeta->pTbDb, &(STbDbKey){.uid = uid, .version = version}, sizeof(STbDbKey), &pData, &nData) != 0) {
goto _err;
}
SMetaEntry me = {0}; SMetaEntry me = {0};
tDecoderInit(&dc, pData, nData); tDecoderInit(&dc, pData, nData);
@ -385,7 +404,9 @@ _query:
} }
tDecoderInit(&dc, pData, nData); tDecoderInit(&dc, pData, nData);
(void)tDecodeSSchemaWrapperEx(&dc, &schema); if (tDecodeSSchemaWrapperEx(&dc, &schema) != 0) {
goto _err;
}
pSchema = tCloneSSchemaWrapper(&schema); pSchema = tCloneSSchemaWrapper(&schema);
tDecoderClear(&dc); tDecoderClear(&dc);
@ -588,6 +609,7 @@ STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) {
int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sver, STSchema **ppTSchema) { int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sver, STSchema **ppTSchema) {
int32_t code = 0; int32_t code = 0;
int32_t lino;
void *pData = NULL; void *pData = NULL;
int nData = 0; int nData = 0;
@ -603,7 +625,8 @@ int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sv
skmDbKey.uid = suid ? suid : uid; skmDbKey.uid = suid ? suid : uid;
skmDbKey.sver = INT32_MAX; skmDbKey.sver = INT32_MAX;
(void)tdbTbcOpen(pMeta->pSkmDb, &pSkmDbC, NULL); code = tdbTbcOpen(pMeta->pSkmDb, &pSkmDbC, NULL);
TSDB_CHECK_CODE(code, lino, _exit);
metaRLock(pMeta); metaRLock(pMeta);
if (tdbTbcMoveTo(pSkmDbC, &skmDbKey, sizeof(skmDbKey), &c) < 0) { if (tdbTbcMoveTo(pSkmDbC, &skmDbKey, sizeof(skmDbKey), &c) < 0) {

View File

@ -306,12 +306,13 @@ _err:
} }
int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq, SArray *tbUidList) { int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq, SArray *tbUidList) {
void *pKey = NULL; void *pKey = NULL;
int nKey = 0; int nKey = 0;
void *pData = NULL; void *pData = NULL;
int nData = 0; int nData = 0;
int c = 0; int c = 0;
int rc = 0; int rc = 0;
int32_t lino;
// check if super table exists // check if super table exists
rc = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData); rc = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData);
@ -323,7 +324,11 @@ int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq, SArray *tb
// drop all child tables // drop all child tables
TBC *pCtbIdxc = NULL; TBC *pCtbIdxc = NULL;
(void)(void)tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL); rc = tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL);
if (rc) {
return (terrno = rc);
}
rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = pReq->suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c); rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = pReq->suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
if (rc < 0) { if (rc < 0) {
(void)tdbTbcClose(pCtbIdxc); (void)tdbTbcClose(pCtbIdxc);
@ -379,20 +384,20 @@ _exit:
return 0; return 0;
} }
static void metaGetSubtables(SMeta *pMeta, int64_t suid, SArray *uids) { static int32_t metaGetSubtables(SMeta *pMeta, int64_t suid, SArray *uids) {
if (!uids) return; if (!uids) return TSDB_CODE_INVALID_PARA;
int c = 0; int c = 0;
void *pKey = NULL; void *pKey = NULL;
int nKey = 0; int nKey = 0;
TBC *pCtbIdxc = NULL; TBC *pCtbIdxc = NULL;
(void)tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL));
int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c); int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
if (rc < 0) { if (rc < 0) {
(void)tdbTbcClose(pCtbIdxc); (void)tdbTbcClose(pCtbIdxc);
metaWLock(pMeta); metaWLock(pMeta);
return; return 0;
} }
for (;;) { for (;;) {
@ -405,12 +410,17 @@ static void metaGetSubtables(SMeta *pMeta, int64_t suid, SArray *uids) {
break; break;
} }
(void)taosArrayPush(uids, &(((SCtbIdxKey *)pKey)->uid)); if (taosArrayPush(uids, &(((SCtbIdxKey *)pKey)->uid)) == NULL) {
tdbFree(pKey);
(void)tdbTbcClose(pCtbIdxc);
return terrno;
}
} }
tdbFree(pKey); tdbFree(pKey);
(void)tdbTbcClose(pCtbIdxc); (void)tdbTbcClose(pCtbIdxc);
return 0;
} }
int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) { int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
@ -425,7 +435,7 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
int32_t ret; int32_t ret;
int32_t c = -2; int32_t c = -2;
(void)tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
ret = tdbTbcMoveTo(pUidIdxc, &pReq->suid, sizeof(tb_uid_t), &c); ret = tdbTbcMoveTo(pUidIdxc, &pReq->suid, sizeof(tb_uid_t), &c);
if (ret < 0 || c) { if (ret < 0 || c) {
(void)tdbTbcClose(pUidIdxc); (void)tdbTbcClose(pUidIdxc);
@ -442,7 +452,7 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
oversion = ((SUidIdxVal *)pData)[0].version; oversion = ((SUidIdxVal *)pData)[0].version;
(void)tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
ret = tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = pReq->suid, .version = oversion}), sizeof(STbDbKey), &c); ret = tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = pReq->suid, .version = oversion}), sizeof(STbDbKey), &c);
if (!(ret == 0 && c == 0)) { if (!(ret == 0 && c == 0)) {
(void)tdbTbcClose(pUidIdxc); (void)tdbTbcClose(pUidIdxc);
@ -486,7 +496,7 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
int16_t cid = pReq->schemaRow.pSchema[nCols - 1].colId; int16_t cid = pReq->schemaRow.pSchema[nCols - 1].colId;
int8_t col_type = pReq->schemaRow.pSchema[nCols - 1].type; int8_t col_type = pReq->schemaRow.pSchema[nCols - 1].type;
metaGetSubtables(pMeta, pReq->suid, uids); TAOS_CHECK_RETURN(metaGetSubtables(pMeta, pReq->suid, uids));
(void)tsdbCacheNewSTableColumn(pTsdb, uids, cid, col_type); (void)tsdbCacheNewSTableColumn(pTsdb, uids, cid, col_type);
} else if (deltaCol == -1) { } else if (deltaCol == -1) {
int16_t cid = -1; int16_t cid = -1;
@ -502,7 +512,7 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
} }
if (cid != -1) { if (cid != -1) {
metaGetSubtables(pMeta, pReq->suid, uids); TAOS_CHECK_RETURN(metaGetSubtables(pMeta, pReq->suid, uids));
(void)tsdbCacheDropSTableColumn(pTsdb, uids, cid, hasPrimaryKey); (void)tsdbCacheDropSTableColumn(pTsdb, uids, cid, hasPrimaryKey);
} }
} }
@ -619,7 +629,7 @@ int metaAddIndexToSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
* iterator all pTdDbc by uid and version * iterator all pTdDbc by uid and version
*/ */
TBC *pCtbIdxc = NULL; TBC *pCtbIdxc = NULL;
(void)tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL));
int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c); int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
if (rc < 0) { if (rc < 0) {
(void)tdbTbcClose(pCtbIdxc); (void)tdbTbcClose(pCtbIdxc);
@ -756,7 +766,7 @@ int metaDropIndexFromSTable(SMeta *pMeta, int64_t version, SDropIndexReq *pReq)
* iterator all pTdDbc by uid and version * iterator all pTdDbc by uid and version
*/ */
TBC *pCtbIdxc = NULL; TBC *pCtbIdxc = NULL;
(void)tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL));
int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c); int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
if (rc < 0) { if (rc < 0) {
(void)tdbTbcClose(pCtbIdxc); (void)tdbTbcClose(pCtbIdxc);
@ -1424,7 +1434,7 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
// search uid index // search uid index
TBC *pUidIdxc = NULL; TBC *pUidIdxc = NULL;
(void)tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
(void)tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c); (void)tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
if (c != 0) { if (c != 0) {
(void)tdbTbcClose(pUidIdxc); (void)tdbTbcClose(pUidIdxc);
@ -1438,7 +1448,7 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
// search table.db // search table.db
TBC *pTbDbc = NULL; TBC *pTbDbc = NULL;
(void)tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
(void)tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c); (void)tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
if (c != 0) { if (c != 0) {
(void)tdbTbcClose(pUidIdxc); (void)tdbTbcClose(pUidIdxc);
@ -1689,7 +1699,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
// search uid index // search uid index
TBC *pUidIdxc = NULL; TBC *pUidIdxc = NULL;
(void)tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
(void)tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c); (void)tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
if (c != 0) { if (c != 0) {
(void)tdbTbcClose(pUidIdxc); (void)tdbTbcClose(pUidIdxc);
@ -1706,7 +1716,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
SDecoder dc2 = {0}; SDecoder dc2 = {0};
/* get ctbEntry */ /* get ctbEntry */
(void)tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
(void)tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c); (void)tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
if (c != 0) { if (c != 0) {
(void)tdbTbcClose(pUidIdxc); (void)tdbTbcClose(pUidIdxc);
@ -1869,7 +1879,7 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p
// search uid index // search uid index
TBC *pUidIdxc = NULL; TBC *pUidIdxc = NULL;
(void)tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
(void)tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c); (void)tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
if (c != 0) { if (c != 0) {
(void)tdbTbcClose(pUidIdxc); (void)tdbTbcClose(pUidIdxc);
@ -1883,7 +1893,7 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p
// search table.db // search table.db
TBC *pTbDbc = NULL; TBC *pTbDbc = NULL;
(void)tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
(void)tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c); (void)tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
if (c != 0) { if (c != 0) {
(void)tdbTbcClose(pUidIdxc); (void)tdbTbcClose(pUidIdxc);
@ -2018,7 +2028,7 @@ static int metaAddTagIndex(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTb
* iterator all pTdDbc by uid and version * iterator all pTdDbc by uid and version
*/ */
TBC *pCtbIdxc = NULL; TBC *pCtbIdxc = NULL;
(void)tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL));
int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c); int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
if (rc < 0) { if (rc < 0) {
(void)tdbTbcClose(pCtbIdxc); (void)tdbTbcClose(pCtbIdxc);
@ -2157,7 +2167,7 @@ static int metaDropTagIndex(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterT
SArray *tagIdxList = taosArrayInit(512, sizeof(SMetaPair)); SArray *tagIdxList = taosArrayInit(512, sizeof(SMetaPair));
TBC *pTagIdxc = NULL; TBC *pTagIdxc = NULL;
(void)tdbTbcOpen(pMeta->pTagIdx, &pTagIdxc, NULL); TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTagIdx, &pTagIdxc, NULL));
int rc = int rc =
tdbTbcMoveTo(pTagIdxc, &(STagIdxKey){.suid = suid, .cid = INT32_MIN, .type = pCol->type}, sizeof(STagIdxKey), &c); tdbTbcMoveTo(pTagIdxc, &(STagIdxKey){.suid = suid, .cid = INT32_MIN, .type = pCol->type}, sizeof(STagIdxKey), &c);
for (;;) { for (;;) {

View File

@ -101,6 +101,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
TSDB_CHECK_CODE(code, line, END); TSDB_CHECK_CODE(code, line, END);
qStreamSetSourceExcluded(task, pRequest->sourceExcluded); qStreamSetSourceExcluded(task, pRequest->sourceExcluded);
uint64_t st = taosGetTimestampMs();
while (1) { while (1) {
SSDataBlock* pDataBlock = NULL; SSDataBlock* pDataBlock = NULL;
code = getDataBlock(task, pHandle, vgId, &pDataBlock); code = getDataBlock(task, pHandle, vgId, &pDataBlock);
@ -160,7 +161,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
pRsp->common.blockNum++; pRsp->common.blockNum++;
totalRows += pDataBlock->info.rows; totalRows += pDataBlock->info.rows;
if (totalRows >= tmqRowSize) { if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > 1000)) {
break; break;
} }
} }

View File

@ -38,7 +38,7 @@ static int32_t buildRetrieveTableRsp(SSDataBlock* pBlock, int32_t numOfCols, SRe
size_t rspSize = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock) + PAYLOAD_PREFIX_LEN; size_t rspSize = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock) + PAYLOAD_PREFIX_LEN;
*pRsp = taosMemoryCalloc(1, rspSize); *pRsp = taosMemoryCalloc(1, rspSize);
if (NULL == *pRsp) { if (NULL == *pRsp) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
(*pRsp)->useconds = 0; (*pRsp)->useconds = 0;
@ -289,7 +289,7 @@ static int32_t buildRetension(SArray* pRetension, char **ppRetentions ) {
char* p1 = taosMemoryCalloc(1, 100); char* p1 = taosMemoryCalloc(1, 100);
if(NULL == p1) { if(NULL == p1) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
int32_t len = 0; int32_t len = 0;
@ -849,7 +849,7 @@ _return:
static int32_t buildLocalVariablesResultDataBlock(SSDataBlock** pOutput) { static int32_t buildLocalVariablesResultDataBlock(SSDataBlock** pOutput) {
SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock)); SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
if (NULL == pBlock) { if (NULL == pBlock) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
pBlock->info.hasVarCol = true; pBlock->info.hasVarCol = true;

View File

@ -227,7 +227,7 @@ int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplai
SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode)); SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
if (NULL == resNode) { if (NULL == resNode) {
qError("calloc SPhysiNodeExplainRes failed"); qError("calloc SPhysiNodeExplainRes failed");
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
int32_t code = 0; int32_t code = 0;

View File

@ -147,7 +147,10 @@ _error:
if (pInfo != NULL) { if (pInfo != NULL) {
destroyAggOperatorInfo(pInfo); destroyAggOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -340,6 +343,7 @@ int32_t doAggregateImpl(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx) {
static int32_t createDataBlockForEmptyInput(SOperatorInfo* pOperator, SSDataBlock** ppBlock) { static int32_t createDataBlockForEmptyInput(SOperatorInfo* pOperator, SSDataBlock** ppBlock) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
SSDataBlock* pBlock = NULL;
if (!tsCountAlwaysReturnValue) { if (!tsCountAlwaysReturnValue) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -363,7 +367,6 @@ static int32_t createDataBlockForEmptyInput(SOperatorInfo* pOperator, SSDataBloc
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
SSDataBlock* pBlock = NULL;
code = createDataBlock(&pBlock); code = createDataBlock(&pBlock);
if (code) { if (code) {
return code; return code;
@ -411,6 +414,7 @@ static int32_t createDataBlockForEmptyInput(SOperatorInfo* pOperator, SSDataBloc
_end: _end:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
blockDataDestroy(pBlock);
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code)); qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
} }
return code; return code;

View File

@ -247,7 +247,10 @@ _error:
} }
pInfo->pTableList = NULL; pInfo->pTableList = NULL;
destroyCacheScanOperator(pInfo); destroyCacheScanOperator(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
return code; return code;
} }
@ -448,7 +451,7 @@ void destroyCacheScanOperator(void* param) {
taosArrayDestroy(pInfo->matchInfo.pList); taosArrayDestroy(pInfo->matchInfo.pList);
tableListDestroy(pInfo->pTableList); tableListDestroy(pInfo->pTableList);
if (pInfo->pLastrowReader != NULL) { if (pInfo->pLastrowReader != NULL && pInfo->readHandle.api.cacheFn.closeReader != NULL) {
pInfo->readHandle.api.cacheFn.closeReader(pInfo->pLastrowReader); pInfo->readHandle.api.cacheFn.closeReader(pInfo->pLastrowReader);
pInfo->pLastrowReader = NULL; pInfo->pLastrowReader = NULL;
} }

View File

@ -294,10 +294,11 @@ int32_t createCountwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* phy
SSDataBlock* pResBlock = createDataBlockFromDescNode(pCountWindowNode->window.node.pOutputDataBlockDesc); SSDataBlock* pResBlock = createDataBlockFromDescNode(pCountWindowNode->window.node.pOutputDataBlockDesc);
QUERY_CHECK_NULL(pResBlock, code, lino, _error, terrno); QUERY_CHECK_NULL(pResBlock, code, lino, _error, terrno);
initBasicInfo(&pInfo->binfo, pResBlock);
code = blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity); code = blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
QUERY_CHECK_CODE(code, lino, _error); QUERY_CHECK_CODE(code, lino, _error);
initBasicInfo(&pInfo->binfo, pResBlock);
initResultRowInfo(&pInfo->binfo.resultRowInfo); initResultRowInfo(&pInfo->binfo.resultRowInfo);
pInfo->binfo.inputTsOrder = physiNode->inputTsOrder; pInfo->binfo.inputTsOrder = physiNode->inputTsOrder;
pInfo->binfo.outputTsOrder = physiNode->outputTsOrder; pInfo->binfo.outputTsOrder = physiNode->outputTsOrder;
@ -341,7 +342,10 @@ _error:
destroyCountWindowOperatorInfo(pInfo); destroyCountWindowOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -110,11 +110,11 @@ int32_t createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* phy
SSDataBlock* pResBlock = createDataBlockFromDescNode(pEventWindowNode->window.node.pOutputDataBlockDesc); SSDataBlock* pResBlock = createDataBlockFromDescNode(pEventWindowNode->window.node.pOutputDataBlockDesc);
QUERY_CHECK_NULL(pResBlock, code, lino, _error, terrno); QUERY_CHECK_NULL(pResBlock, code, lino, _error, terrno);
initBasicInfo(&pInfo->binfo, pResBlock);
code = blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity); code = blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
QUERY_CHECK_CODE(code, lino, _error); QUERY_CHECK_CODE(code, lino, _error);
initBasicInfo(&pInfo->binfo, pResBlock);
initResultRowInfo(&pInfo->binfo.resultRowInfo); initResultRowInfo(&pInfo->binfo.resultRowInfo);
pInfo->binfo.inputTsOrder = physiNode->inputTsOrder; pInfo->binfo.inputTsOrder = physiNode->inputTsOrder;
pInfo->binfo.outputTsOrder = physiNode->outputTsOrder; pInfo->binfo.outputTsOrder = physiNode->outputTsOrder;
@ -145,7 +145,10 @@ _error:
destroyEWindowOperatorInfo(pInfo); destroyEWindowOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -452,7 +452,10 @@ _error:
doDestroyExchangeOperatorInfo(pInfo); doDestroyExchangeOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -707,8 +710,9 @@ void updateLoadRemoteInfo(SLoadRemoteDataInfo* pInfo, int64_t numOfRows, int32_t
} }
int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pColList, char** pNextStart) { int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pColList, char** pNextStart) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
SSDataBlock* pBlock = NULL;
if (pColList == NULL) { // data from other sources if (pColList == NULL) { // data from other sources
blockDataCleanup(pRes); blockDataCleanup(pRes);
code = blockDecode(pRes, pData, (const char**)pNextStart); code = blockDecode(pRes, pData, (const char**)pNextStart);
@ -731,7 +735,7 @@ int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pCo
pStart += sizeof(SSysTableSchema); pStart += sizeof(SSysTableSchema);
} }
SSDataBlock* pBlock = NULL; pBlock = NULL;
code = createDataBlock(&pBlock); code = createDataBlock(&pBlock);
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
@ -756,10 +760,12 @@ int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pCo
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
blockDataDestroy(pBlock); blockDataDestroy(pBlock);
pBlock = NULL;
} }
_end: _end:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
blockDataDestroy(pBlock);
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
} }
return code; return code;

View File

@ -278,7 +278,7 @@ SSDataBlock* createDataBlockFromDescNode(SDataBlockDescNode* pNode) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code)); qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
blockDataDestroy(pBlock); blockDataDestroy(pBlock);
pBlock = NULL; pBlock = NULL;
terrno = code; terrno = TSDB_CODE_INVALID_PARA;
break; break;
} }
SColumnInfoData idata = SColumnInfoData idata =
@ -1094,7 +1094,7 @@ SSDataBlock* createTagValBlockForFilter(SArray* pColList, int32_t numOfTables, S
code = blockDataEnsureCapacity(pResBlock, numOfTables); code = blockDataEnsureCapacity(pResBlock, numOfTables);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
terrno = code; terrno = code;
taosMemoryFree(pResBlock); blockDataDestroy(pResBlock);
return NULL; return NULL;
} }
@ -1166,7 +1166,7 @@ SSDataBlock* createTagValBlockForFilter(SArray* pColList, int32_t numOfTables, S
_end: _end:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
taosMemoryFree(pResBlock); blockDataDestroy(pResBlock);
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
terrno = code; terrno = code;
return NULL; return NULL;

View File

@ -567,7 +567,10 @@ _error:
} }
pTaskInfo->code = code; pTaskInfo->code = code;
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
return code; return code;
} }

View File

@ -1504,7 +1504,10 @@ _error:
destroyGroupCacheOperator(pInfo); destroyGroupCacheOperator(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -1246,7 +1246,10 @@ _error:
destroyPartitionOperatorInfo(pInfo); destroyPartitionOperatorInfo(pInfo);
} }
pTaskInfo->code = code; pTaskInfo->code = code;
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
TAOS_RETURN(code); TAOS_RETURN(code);
} }
@ -1792,7 +1795,10 @@ int32_t createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStreamPart
_error: _error:
pTaskInfo->code = code; pTaskInfo->code = code;
if (pInfo != NULL) destroyStreamPartitionOperatorInfo(pInfo); if (pInfo != NULL) destroyStreamPartitionOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
return code; return code;
} }

View File

@ -652,7 +652,7 @@ void destroyOperator(SOperatorInfo* pOperator) {
freeResetOperatorParams(pOperator, OP_GET_PARAM, true); freeResetOperatorParams(pOperator, OP_GET_PARAM, true);
freeResetOperatorParams(pOperator, OP_NOTIFY_PARAM, true); freeResetOperatorParams(pOperator, OP_NOTIFY_PARAM, true);
if (pOperator->fpSet.closeFn != NULL) { if (pOperator->fpSet.closeFn != NULL && pOperator->info != NULL) {
pOperator->fpSet.closeFn(pOperator->info); pOperator->fpSet.closeFn(pOperator->info);
} }

View File

@ -180,7 +180,10 @@ int32_t createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhysiNode*
_error: _error:
destroyProjectOperatorInfo(pInfo); destroyProjectOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -529,7 +532,10 @@ int32_t createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhysiNode*
_error: _error:
destroyIndefinitOperatorInfo(pInfo); destroyIndefinitOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -1466,7 +1466,10 @@ _error:
destroyTableScanOperatorInfo(pInfo); destroyTableScanOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -3935,7 +3938,7 @@ static void destroyStreamScanOperatorInfo(void* param) {
destroyOperator(pStreamScan->pTableScanOp); destroyOperator(pStreamScan->pTableScanOp);
} }
if (pStreamScan->tqReader) { if (pStreamScan->tqReader != NULL && pStreamScan->readerFn.tqReaderClose != NULL) {
pStreamScan->readerFn.tqReaderClose(pStreamScan->tqReader); pStreamScan->readerFn.tqReaderClose(pStreamScan->tqReader);
} }
if (pStreamScan->matchInfo.pList) { if (pStreamScan->matchInfo.pList) {
@ -4306,7 +4309,10 @@ _error:
destroyStreamScanOperatorInfo(pInfo); destroyStreamScanOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -4472,11 +4478,12 @@ static int32_t tagScanFilterByTagCond(SArray* aUidTags, SNode* pTagCond, SArray*
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
int32_t numOfTables = taosArrayGetSize(aUidTags); int32_t numOfTables = taosArrayGetSize(aUidTags);
SArray* pBlockList = NULL;
SSDataBlock* pResBlock = createTagValBlockForFilter(pInfo->filterCtx.cInfoList, numOfTables, aUidTags, pVnode, pAPI); SSDataBlock* pResBlock = createTagValBlockForFilter(pInfo->filterCtx.cInfoList, numOfTables, aUidTags, pVnode, pAPI);
QUERY_CHECK_NULL(pResBlock, code, lino, _end, terrno); QUERY_CHECK_NULL(pResBlock, code, lino, _end, terrno);
SArray* pBlockList = taosArrayInit(1, POINTER_BYTES); pBlockList = taosArrayInit(1, POINTER_BYTES);
QUERY_CHECK_NULL(pBlockList, code, lino, _end, terrno); QUERY_CHECK_NULL(pBlockList, code, lino, _end, terrno);
void* tmp = taosArrayPush(pBlockList, &pResBlock); void* tmp = taosArrayPush(pBlockList, &pResBlock);
@ -4766,7 +4773,7 @@ static SSDataBlock* doTagScanFromMetaEntry(SOperatorInfo* pOperator) {
static void destroyTagScanOperatorInfo(void* param) { static void destroyTagScanOperatorInfo(void* param) {
STagScanInfo* pInfo = (STagScanInfo*)param; STagScanInfo* pInfo = (STagScanInfo*)param;
if (pInfo->pCtbCursor != NULL) { if (pInfo->pCtbCursor != NULL && pInfo->pStorageAPI != NULL) {
pInfo->pStorageAPI->metaFn.closeCtbCursor(pInfo->pCtbCursor); pInfo->pStorageAPI->metaFn.closeCtbCursor(pInfo->pCtbCursor);
} }
taosHashCleanup(pInfo->filterCtx.colHash); taosHashCleanup(pInfo->filterCtx.colHash);
@ -4863,7 +4870,10 @@ _error:
} }
if (pInfo != NULL) destroyTagScanOperatorInfo(pInfo); if (pInfo != NULL) destroyTagScanOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
return code; return code;
} }
@ -5928,8 +5938,10 @@ void destroyTableMergeScanOperatorInfo(void* param) {
STableMergeScanInfo* pTableScanInfo = (STableMergeScanInfo*)param; STableMergeScanInfo* pTableScanInfo = (STableMergeScanInfo*)param;
// start one reader variable // start one reader variable
pTableScanInfo->base.readerAPI.tsdReaderClose(pTableScanInfo->base.dataReader); if (pTableScanInfo->base.readerAPI.tsdReaderClose != NULL) {
pTableScanInfo->base.dataReader = NULL; pTableScanInfo->base.readerAPI.tsdReaderClose(pTableScanInfo->base.dataReader);
pTableScanInfo->base.dataReader = NULL;
}
for (int32_t i = 0; i < pTableScanInfo->numNextDurationBlocks; ++i) { for (int32_t i = 0; i < pTableScanInfo->numNextDurationBlocks; ++i) {
if (pTableScanInfo->nextDurationBlocks[i] != NULL) { if (pTableScanInfo->nextDurationBlocks[i] != NULL) {
@ -5984,7 +5996,8 @@ int32_t createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SR
SOperatorInfo** pOptrInfo) { SOperatorInfo** pOptrInfo) {
QRY_OPTR_CHECK(pOptrInfo); QRY_OPTR_CHECK(pOptrInfo);
int32_t code = 0; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
STableMergeScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableMergeScanInfo)); STableMergeScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableMergeScanInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
if (pInfo == NULL || pOperator == NULL) { if (pInfo == NULL || pOperator == NULL) {
@ -5997,16 +6010,10 @@ int32_t createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SR
int32_t numOfCols = 0; int32_t numOfCols = 0;
code = extractColMatchInfo(pTableScanNode->scan.pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID, code = extractColMatchInfo(pTableScanNode->scan.pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID,
&pInfo->base.matchInfo); &pInfo->base.matchInfo);
int32_t lino = 0; QUERY_CHECK_CODE(code, lino, _error);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
code = initQueryTableDataCond(&pInfo->base.cond, pTableScanNode, readHandle); code = initQueryTableDataCond(&pInfo->base.cond, pTableScanNode, readHandle);
if (code != TSDB_CODE_SUCCESS) { QUERY_CHECK_CODE(code, lino, _error);
taosArrayDestroy(pInfo->base.matchInfo.pList);
goto _error;
}
if (pTableScanNode->scan.pScanPseudoCols != NULL) { if (pTableScanNode->scan.pScanPseudoCols != NULL) {
SExprSupp* pSup = &pInfo->base.pseudoSup; SExprSupp* pSup = &pInfo->base.pseudoSup;
@ -6021,10 +6028,7 @@ int32_t createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SR
pInfo->scanInfo = (SScanInfo){.numOfAsc = pTableScanNode->scanSeq[0], .numOfDesc = pTableScanNode->scanSeq[1]}; pInfo->scanInfo = (SScanInfo){.numOfAsc = pTableScanNode->scanSeq[0], .numOfDesc = pTableScanNode->scanSeq[1]};
pInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5); pInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5);
if (pInfo->base.metaCache.pTableMetaEntryCache == NULL) { QUERY_CHECK_NULL(pInfo->base.metaCache.pTableMetaEntryCache, code, lino, _error, terrno);
code = terrno;
goto _error;
}
pInfo->base.readerAPI = pTaskInfo->storageAPI.tsdReader; pInfo->base.readerAPI = pTaskInfo->storageAPI.tsdReader;
pInfo->base.dataBlockLoadFlag = FUNC_DATA_REQUIRED_DATA_LOAD; pInfo->base.dataBlockLoadFlag = FUNC_DATA_REQUIRED_DATA_LOAD;
@ -6041,9 +6045,7 @@ int32_t createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SR
pInfo->sample.seed = taosGetTimestampSec(); pInfo->sample.seed = taosGetTimestampSec();
code = filterInitFromNode((SNode*)pTableScanNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0); code = filterInitFromNode((SNode*)pTableScanNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
if (code != TSDB_CODE_SUCCESS) { QUERY_CHECK_CODE(code, lino, _error);
goto _error;
}
initLimitInfo(pTableScanNode->scan.node.pLimit, pTableScanNode->scan.node.pSlimit, &pInfo->limitInfo); initLimitInfo(pTableScanNode->scan.node.pLimit, pTableScanNode->scan.node.pSlimit, &pInfo->limitInfo);
@ -6105,10 +6107,16 @@ int32_t createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SR
return code; return code;
_error: _error:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
pTaskInfo->code = code; pTaskInfo->code = code;
pInfo->base.pTableListInfo = NULL; pInfo->base.pTableListInfo = NULL;
if (pInfo != NULL) destroyTableMergeScanOperatorInfo(pInfo); if (pInfo != NULL) destroyTableMergeScanOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
return code; return code;
} }
@ -6265,7 +6273,10 @@ _error:
if (pInfo != NULL) { if (pInfo != NULL) {
destoryTableCountScanOperator(pInfo); destoryTableCountScanOperator(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -164,7 +164,10 @@ _error:
destroySortOperatorInfo(pInfo); destroySortOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -836,6 +839,9 @@ _error:
if (pInfo != NULL) { if (pInfo != NULL) {
destroyGroupSortOperatorInfo(pInfo); destroyGroupSortOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
return code; return code;
} }

View File

@ -927,7 +927,10 @@ _error:
destroyStreamCountAggOperatorInfo(pInfo); destroyStreamCountAggOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
return code; return code;

View File

@ -982,7 +982,10 @@ int32_t createStreamEventAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode*
_error: _error:
if (pInfo != NULL) destroyStreamEventOperatorInfo(pInfo); if (pInfo != NULL) destroyStreamEventOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
return code; return code;

View File

@ -1458,7 +1458,10 @@ _error:
qError("%s failed at line %d since %s. task:%s", __func__, lino, tstrerror(code), GET_TASKID(pTaskInfo)); qError("%s failed at line %d since %s. task:%s", __func__, lino, tstrerror(code), GET_TASKID(pTaskInfo));
} }
if (pInfo != NULL) destroyStreamFillOperatorInfo(pInfo); if (pInfo != NULL) destroyStreamFillOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -2025,7 +2025,10 @@ int32_t createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiN
_error: _error:
if (pInfo != NULL) destroyStreamFinalIntervalOperatorInfo(pInfo); if (pInfo != NULL) destroyStreamFinalIntervalOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -3851,7 +3854,10 @@ _error:
destroyStreamSessionAggOperatorInfo(pInfo); destroyStreamSessionAggOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
return code; return code;
@ -4107,7 +4113,10 @@ _error:
if (pInfo != NULL) { if (pInfo != NULL) {
destroyStreamSessionAggOperatorInfo(pInfo); destroyStreamSessionAggOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s. task:%s", __func__, lino, tstrerror(code), GET_TASKID(pTaskInfo)); qError("%s failed at line %d since %s. task:%s", __func__, lino, tstrerror(code), GET_TASKID(pTaskInfo));
@ -4998,7 +5007,10 @@ int32_t createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode*
_error: _error:
if (pInfo != NULL) destroyStreamStateOperatorInfo(pInfo); if (pInfo != NULL) destroyStreamStateOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
return code; return code;
@ -5211,6 +5223,8 @@ int32_t createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode*
SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc);
QUERY_CHECK_NULL(pResBlock, code, lino, _error, terrno); QUERY_CHECK_NULL(pResBlock, code, lino, _error, terrno);
initBasicInfo(&pInfo->binfo, pResBlock);
pInfo->interval = (SInterval){ pInfo->interval = (SInterval){
.interval = pIntervalPhyNode->interval, .interval = pIntervalPhyNode->interval,
.sliding = pIntervalPhyNode->sliding, .sliding = pIntervalPhyNode->sliding,
@ -5238,7 +5252,6 @@ int32_t createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode*
SExprSupp* pSup = &pOperator->exprSupp; SExprSupp* pSup = &pOperator->exprSupp;
pSup->hasWindowOrGroup = true; pSup->hasWindowOrGroup = true;
initBasicInfo(&pInfo->binfo, pResBlock);
code = initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); code = initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
QUERY_CHECK_CODE(code, lino, _error); QUERY_CHECK_CODE(code, lino, _error);
@ -5333,7 +5346,10 @@ int32_t createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode*
_error: _error:
if (pInfo != NULL) destroyStreamFinalIntervalOperatorInfo(pInfo); if (pInfo != NULL) destroyStreamFinalIntervalOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -568,7 +568,7 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
if (pInfo->pCur == NULL) { if (pInfo->pCur == NULL) {
pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode); pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
} else { } else {
pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 0); (void)pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 0);
} }
if (pInfo->pSchema == NULL) { if (pInfo->pSchema == NULL) {
@ -672,6 +672,7 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
} }
blockDataDestroy(pDataBlock); blockDataDestroy(pDataBlock);
pDataBlock = NULL;
if (ret != 0) { if (ret != 0) {
pAPI->metaFn.closeTableMetaCursor(pInfo->pCur); pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
pInfo->pCur = NULL; pInfo->pCur = NULL;
@ -683,6 +684,7 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
_end: _end:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
blockDataDestroy(pDataBlock);
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
pTaskInfo->code = code; pTaskInfo->code = code;
T_LONG_JMP(pTaskInfo->env, code); T_LONG_JMP(pTaskInfo->env, code);
@ -695,6 +697,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
int32_t lino = 0; int32_t lino = 0;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SStorageAPI* pAPI = &pTaskInfo->storageAPI; SStorageAPI* pAPI = &pTaskInfo->storageAPI;
SSDataBlock* dataBlock = NULL;
SSysTableScanInfo* pInfo = pOperator->info; SSysTableScanInfo* pInfo = pOperator->info;
if (pOperator->status == OP_EXEC_DONE) { if (pOperator->status == OP_EXEC_DONE) {
@ -704,7 +707,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
blockDataCleanup(pInfo->pRes); blockDataCleanup(pInfo->pRes);
int32_t numOfRows = 0; int32_t numOfRows = 0;
SSDataBlock* dataBlock = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TAGS); dataBlock = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TAGS);
code = blockDataEnsureCapacity(dataBlock, pOperator->resultInfo.capacity); code = blockDataEnsureCapacity(dataBlock, pOperator->resultInfo.capacity);
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
@ -777,8 +780,9 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
int32_t ret = 0; int32_t ret = 0;
if (pInfo->pCur == NULL) { if (pInfo->pCur == NULL) {
pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode); pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
QUERY_CHECK_NULL(pInfo->pCur, code, lino, _end, terrno);
} else { } else {
pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 0); (void)pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 0);
} }
while ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) { while ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) {
@ -826,6 +830,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
} }
blockDataDestroy(dataBlock); blockDataDestroy(dataBlock);
dataBlock = NULL;
if (ret != 0) { if (ret != 0) {
pAPI->metaFn.closeTableMetaCursor(pInfo->pCur); pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
pInfo->pCur = NULL; pInfo->pCur = NULL;
@ -837,6 +842,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
_end: _end:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
blockDataDestroy(dataBlock);
pAPI->metaFn.closeTableMetaCursor(pInfo->pCur); pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
pInfo->pCur = NULL; pInfo->pCur = NULL;
pTaskInfo->code = code; pTaskInfo->code = code;
@ -1196,7 +1202,7 @@ static SSDataBlock* buildInfoSchemaTableMetaBlock(char* tableName) {
} }
SSDataBlock* pBlock = NULL; SSDataBlock* pBlock = NULL;
int32_t code = createDataBlock(&pBlock); int32_t code = createDataBlock(&pBlock);
if (code) { if (code) {
terrno = code; terrno = code;
return NULL; return NULL;
@ -1310,9 +1316,11 @@ int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity) {
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
blockDataDestroy(p); blockDataDestroy(p);
p = NULL;
_end: _end:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
blockDataDestroy(p);
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
} }
return code; return code;
@ -1325,6 +1333,7 @@ static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
SStorageAPI* pAPI = &pTaskInfo->storageAPI; SStorageAPI* pAPI = &pTaskInfo->storageAPI;
SSysTableScanInfo* pInfo = pOperator->info; SSysTableScanInfo* pInfo = pOperator->info;
SSysTableIndex* pIdx = pInfo->pIdx; SSysTableIndex* pIdx = pInfo->pIdx;
SSDataBlock* p = NULL;
blockDataCleanup(pInfo->pRes); blockDataCleanup(pInfo->pRes);
int32_t numOfRows = 0; int32_t numOfRows = 0;
@ -1344,7 +1353,7 @@ static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
varDataSetLen(dbname, strlen(varDataVal(dbname))); varDataSetLen(dbname, strlen(varDataVal(dbname)));
SSDataBlock* p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES); p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES);
code = blockDataEnsureCapacity(p, pOperator->resultInfo.capacity); code = blockDataEnsureCapacity(p, pOperator->resultInfo.capacity);
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
@ -1366,7 +1375,7 @@ static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
// table name // table name
SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0); SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno); QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, n, false); code = colDataSetVal(pColInfoData, numOfRows, n, false);
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
@ -1545,12 +1554,14 @@ static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
} }
blockDataDestroy(p); blockDataDestroy(p);
p = NULL;
pInfo->loadInfo.totalRows += pInfo->pRes->info.rows; pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
_end: _end:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
blockDataDestroy(p);
pTaskInfo->code = code; pTaskInfo->code = code;
T_LONG_JMP(pTaskInfo->env, code); T_LONG_JMP(pTaskInfo->env, code);
} }
@ -1563,14 +1574,16 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SStorageAPI* pAPI = &pTaskInfo->storageAPI; SStorageAPI* pAPI = &pTaskInfo->storageAPI;
int8_t firstMetaCursor = 0; int8_t firstMetaCursor = 0;
SSDataBlock* p = NULL;
SSysTableScanInfo* pInfo = pOperator->info; SSysTableScanInfo* pInfo = pOperator->info;
if (pInfo->pCur == NULL) { if (pInfo->pCur == NULL) {
pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode); pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
QUERY_CHECK_NULL(pInfo->pCur, code, lino, _end, terrno);
firstMetaCursor = 1; firstMetaCursor = 1;
} }
if (!firstMetaCursor) { if (!firstMetaCursor) {
pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 1); (void)pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 1);
} }
blockDataCleanup(pInfo->pRes); blockDataCleanup(pInfo->pRes);
@ -1590,7 +1603,7 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
varDataSetLen(dbname, strlen(varDataVal(dbname))); varDataSetLen(dbname, strlen(varDataVal(dbname)));
SSDataBlock* p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES); p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES);
QUERY_CHECK_NULL(p, code, lino, _end, terrno); QUERY_CHECK_NULL(p, code, lino, _end, terrno);
code = blockDataEnsureCapacity(p, pOperator->resultInfo.capacity); code = blockDataEnsureCapacity(p, pOperator->resultInfo.capacity);
@ -1783,6 +1796,7 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
} }
blockDataDestroy(p); blockDataDestroy(p);
p = NULL;
// todo temporarily free the cursor here, the true reason why the free is not valid needs to be found // todo temporarily free the cursor here, the true reason why the free is not valid needs to be found
if (ret != 0) { if (ret != 0) {
@ -1796,6 +1810,7 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
_end: _end:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
blockDataDestroy(p);
pTaskInfo->code = code; pTaskInfo->code = code;
T_LONG_JMP(pTaskInfo->env, code); T_LONG_JMP(pTaskInfo->env, code);
} }
@ -2021,7 +2036,7 @@ static void sysTableScanFillTbName(SOperatorInfo* pOperator, const SSysTableScan
if (pInfo->tbnameSlotId != -1) { if (pInfo->tbnameSlotId != -1) {
SColumnInfoData* pColumnInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, pInfo->tbnameSlotId); SColumnInfoData* pColumnInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, pInfo->tbnameSlotId);
QUERY_CHECK_NULL(pColumnInfoData, code, lino, _end, terrno); QUERY_CHECK_NULL(pColumnInfoData, code, lino, _end, terrno);
char varTbName[TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE] = {0}; char varTbName[TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE] = {0};
STR_TO_VARSTR(varTbName, name); STR_TO_VARSTR(varTbName, name);
code = colDataSetNItems(pColumnInfoData, 0, varTbName, pBlock->info.rows, true); code = colDataSetNItems(pColumnInfoData, 0, varTbName, pBlock->info.rows, true);
@ -2138,8 +2153,8 @@ static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableSca
} }
} }
int32_t createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode, int32_t createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode, const char* pUser,
const char* pUser, SExecTaskInfo* pTaskInfo, SOperatorInfo** pOptrInfo) { SExecTaskInfo* pTaskInfo, SOperatorInfo** pOptrInfo) {
QRY_OPTR_CHECK(pOptrInfo); QRY_OPTR_CHECK(pOptrInfo);
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -2148,7 +2163,7 @@ int32_t createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNo
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
if (pInfo == NULL || pOperator == NULL) { if (pInfo == NULL || pOperator == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY; code = TSDB_CODE_OUT_OF_MEMORY;
lino = __LINE__; lino = __LINE__;
goto _error; goto _error;
} }
@ -2209,7 +2224,10 @@ _error:
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -2244,7 +2262,7 @@ void destroySysScanOperator(void* param) {
if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 || if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 ||
strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 || strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 ||
strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0 || pInfo->pCur != NULL) { strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0 || pInfo->pCur != NULL) {
if (pInfo->pAPI->metaFn.closeTableMetaCursor != NULL) { if (pInfo->pAPI != NULL && pInfo->pAPI->metaFn.closeTableMetaCursor != NULL) {
pInfo->pAPI->metaFn.closeTableMetaCursor(pInfo->pCur); pInfo->pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
} }
@ -2437,10 +2455,10 @@ static FORCE_INLINE int optSysBinarySearch(SArray* arr, int s, int e, uint64_t k
} }
int32_t optSysIntersection(SArray* in, SArray* out) { int32_t optSysIntersection(SArray* in, SArray* out) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
MergeIndex* mi = NULL; MergeIndex* mi = NULL;
int32_t sz = (int32_t)taosArrayGetSize(in); int32_t sz = (int32_t)taosArrayGetSize(in);
if (sz <= 0) { if (sz <= 0) {
goto _end; goto _end;
} }
@ -2678,7 +2696,6 @@ static int32_t doBlockInfoScanNext(SOperatorInfo* pOperator, SSDataBlock** ppRes
int32_t slotId = pOperator->exprSupp.pExprInfo->base.resSchema.slotId; int32_t slotId = pOperator->exprSupp.pExprInfo->base.resSchema.slotId;
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, slotId); SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, slotId);
QUERY_CHECK_NULL(pColInfo, code, lino, _end, terrno); QUERY_CHECK_NULL(pColInfo, code, lino, _end, terrno);
int32_t len = tSerializeBlockDistInfo(NULL, 0, &blockDistInfo); int32_t len = tSerializeBlockDistInfo(NULL, 0, &blockDistInfo);
char* p = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE); char* p = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE);
@ -2700,7 +2717,7 @@ static int32_t doBlockInfoScanNext(SOperatorInfo* pOperator, SSDataBlock** ppRes
if (slotId != 0) { if (slotId != 0) {
SColumnInfoData* p1 = taosArrayGet(pBlock->pDataBlock, 0); SColumnInfoData* p1 = taosArrayGet(pBlock->pDataBlock, 0);
QUERY_CHECK_NULL(p1, code, lino, _end, terrno); QUERY_CHECK_NULL(p1, code, lino, _end, terrno);
int64_t v = 0; int64_t v = 0;
colDataSetInt64(p1, 0, &v); colDataSetInt64(p1, 0, &v);
} }
@ -2726,7 +2743,9 @@ static SSDataBlock* doBlockInfoScan(SOperatorInfo* pOperator) {
static void destroyBlockDistScanOperatorInfo(void* param) { static void destroyBlockDistScanOperatorInfo(void* param) {
SBlockDistInfo* pDistInfo = (SBlockDistInfo*)param; SBlockDistInfo* pDistInfo = (SBlockDistInfo*)param;
blockDataDestroy(pDistInfo->pResBlock); blockDataDestroy(pDistInfo->pResBlock);
pDistInfo->readHandle.api.tsdReader.tsdReaderClose(pDistInfo->pHandle); if (pDistInfo->readHandle.api.tsdReader.tsdReaderClose != NULL) {
pDistInfo->readHandle.api.tsdReader.tsdReaderClose(pDistInfo->pHandle);
}
tableListDestroy(pDistInfo->pTableListInfo); tableListDestroy(pDistInfo->pTableListInfo);
taosMemoryFreeClear(param); taosMemoryFreeClear(param);
} }
@ -2760,11 +2779,12 @@ static int32_t initTableblockDistQueryCond(uint64_t uid, SQueryTableDataCond* pC
} }
int32_t createDataBlockInfoScanOperator(SReadHandle* readHandle, SBlockDistScanPhysiNode* pBlockScanNode, int32_t createDataBlockInfoScanOperator(SReadHandle* readHandle, SBlockDistScanPhysiNode* pBlockScanNode,
STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo, SOperatorInfo** pOptrInfo) { STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo,
SOperatorInfo** pOptrInfo) {
QRY_OPTR_CHECK(pOptrInfo); QRY_OPTR_CHECK(pOptrInfo);
int32_t code = 0; int32_t code = 0;
int32_t lino = 0; int32_t lino = 0;
SBlockDistInfo* pInfo = taosMemoryCalloc(1, sizeof(SBlockDistInfo)); SBlockDistInfo* pInfo = taosMemoryCalloc(1, sizeof(SBlockDistInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
if (pInfo == NULL || pOperator == NULL) { if (pInfo == NULL || pOperator == NULL) {
@ -2815,6 +2835,9 @@ _error:
pInfo->pTableListInfo = NULL; pInfo->pTableListInfo = NULL;
destroyBlockDistScanOperatorInfo(pInfo); destroyBlockDistScanOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
return code; return code;
} }

View File

@ -1208,7 +1208,10 @@ _error:
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
} }
if (pInfo != NULL) destroyTimeSliceOperatorInfo(pInfo); if (pInfo != NULL) destroyTimeSliceOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -1414,7 +1414,10 @@ _error:
if (pInfo != NULL) { if (pInfo != NULL) {
destroyIntervalOperatorInfo(pInfo); destroyIntervalOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -1690,7 +1693,10 @@ _error:
destroyStateWindowOperatorInfo(pInfo); destroyStateWindowOperatorInfo(pInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -1783,7 +1789,10 @@ int32_t createSessionAggOperatorInfo(SOperatorInfo* downstream, SSessionWinodwPh
_error: _error:
if (pInfo != NULL) destroySWindowOperatorInfo(pInfo); if (pInfo != NULL) destroySWindowOperatorInfo(pInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -2094,8 +2103,11 @@ int32_t createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream, SMerge
return code; return code;
_error: _error:
destroyMAIOperatorInfo(miaInfo); if (miaInfo != NULL) destroyMAIOperatorInfo(miaInfo);
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }
@ -2427,7 +2439,10 @@ _error:
destroyMergeIntervalOperatorInfo(pMergeIntervalInfo); destroyMergeIntervalOperatorInfo(pMergeIntervalInfo);
} }
destroyOperator(pOperator); if (pOperator != NULL) {
pOperator->info = NULL;
destroyOperator(pOperator);
}
pTaskInfo->code = code; pTaskInfo->code = code;
return code; return code;
} }

View File

@ -152,8 +152,10 @@ static void destoryAllocatedTuple(void* t) { taosMemoryFree(t); }
* @param colIndex the columnIndex, for setting null bitmap * @param colIndex the columnIndex, for setting null bitmap
* @return the next offset to add field * @return the next offset to add field
* */ * */
static inline size_t tupleAddField(char** t, uint32_t colNum, uint32_t offset, uint32_t colIdx, void* data, static inline int32_t tupleAddField(char** t, uint32_t colNum, uint32_t offset, uint32_t colIdx, void* data,
size_t length, bool isNull, uint32_t tupleLen) { size_t length, bool isNull, uint32_t tupleLen, uint32_t* pOffset) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
tupleSetOffset(*t, colIdx, offset); tupleSetOffset(*t, colIdx, offset);
if (isNull) { if (isNull) {
@ -161,16 +163,20 @@ static inline size_t tupleAddField(char** t, uint32_t colNum, uint32_t offset, u
} else { } else {
if (offset + length > tupleLen + tupleGetDataStartOffset(colNum)) { if (offset + length > tupleLen + tupleGetDataStartOffset(colNum)) {
void* px = taosMemoryRealloc(*t, offset + length); void* px = taosMemoryRealloc(*t, offset + length);
if (px == NULL) { QUERY_CHECK_NULL(px, code, lino, _end, terrno);
return terrno;
}
*t = px; *t = px;
} }
tupleSetData(*t, offset, data, length); tupleSetData(*t, offset, data, length);
} }
return offset + length; (*pOffset) = offset + length;
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
} }
static void* tupleGetField(char* t, uint32_t colIdx, uint32_t colNum) { static void* tupleGetField(char* t, uint32_t colIdx, uint32_t colNum) {
@ -200,6 +206,7 @@ typedef struct ReferencedTuple {
} ReferencedTuple; } ReferencedTuple;
static int32_t createAllocatedTuple(SSDataBlock* pBlock, size_t colNum, uint32_t tupleLen, size_t rowIdx, TupleDesc** pDesc) { static int32_t createAllocatedTuple(SSDataBlock* pBlock, size_t colNum, uint32_t tupleLen, size_t rowIdx, TupleDesc** pDesc) {
int32_t code = TSDB_CODE_SUCCESS;
TupleDesc* t = taosMemoryCalloc(1, sizeof(TupleDesc)); TupleDesc* t = taosMemoryCalloc(1, sizeof(TupleDesc));
if (t == NULL) { if (t == NULL) {
return terrno; return terrno;
@ -216,15 +223,20 @@ static int32_t createAllocatedTuple(SSDataBlock* pBlock, size_t colNum, uint32_t
for (size_t colIdx = 0; colIdx < colNum; ++colIdx) { for (size_t colIdx = 0; colIdx < colNum; ++colIdx) {
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, colIdx); SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, colIdx);
if (pCol == NULL) { if (pCol == NULL) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return terrno; return terrno;
} }
if (colDataIsNull_s(pCol, rowIdx)) { if (colDataIsNull_s(pCol, rowIdx)) {
offset = tupleAddField((char**)&pTuple, colNum, offset, colIdx, 0, 0, true, tupleLen); code = tupleAddField((char**)&pTuple, colNum, offset, colIdx, 0, 0, true, tupleLen, &offset);
} else { } else {
colLen = colDataGetRowLength(pCol, rowIdx); colLen = colDataGetRowLength(pCol, rowIdx);
offset = code =
tupleAddField((char**)&pTuple, colNum, offset, colIdx, colDataGetData(pCol, rowIdx), colLen, false, tupleLen); tupleAddField((char**)&pTuple, colNum, offset, colIdx, colDataGetData(pCol, rowIdx), colLen, false, tupleLen, &offset);
}
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
return code;
} }
} }
@ -232,7 +244,7 @@ static int32_t createAllocatedTuple(SSDataBlock* pBlock, size_t colNum, uint32_t
t->data = pTuple; t->data = pTuple;
*pDesc = t; *pDesc = t;
return 0; return code;
} }
int32_t tupleDescGetField(const TupleDesc* pDesc, int32_t colIdx, uint32_t colNum, void** pResult) { int32_t tupleDescGetField(const TupleDesc* pDesc, int32_t colIdx, uint32_t colNum, void** pResult) {
@ -259,7 +271,7 @@ int32_t tupleDescGetField(const TupleDesc* pDesc, int32_t colIdx, uint32_t colNu
void destroyTuple(void* t) { void destroyTuple(void* t) {
TupleDesc* pDesc = t; TupleDesc* pDesc = t;
if (pDesc->type == AllocatedTupleType) { if (pDesc != NULL && pDesc->type == AllocatedTupleType) {
destoryAllocatedTuple(pDesc->data); destoryAllocatedTuple(pDesc->data);
taosMemoryFree(pDesc); taosMemoryFree(pDesc);
} }
@ -1686,6 +1698,7 @@ static int32_t initRowIdSort(SSortHandle* pHandle) {
biTs.compFn = getKeyComparFunc(TSDB_DATA_TYPE_TIMESTAMP, biTs.order); biTs.compFn = getKeyComparFunc(TSDB_DATA_TYPE_TIMESTAMP, biTs.order);
void* p = taosArrayPush(pOrderInfoList, &biTs); void* p = taosArrayPush(pOrderInfoList, &biTs);
if (p == NULL) { if (p == NULL) {
taosArrayDestroy(pOrderInfoList);
return terrno; return terrno;
} }
@ -1698,6 +1711,7 @@ static int32_t initRowIdSort(SSortHandle* pHandle) {
void* px = taosArrayPush(pOrderInfoList, &biPk); void* px = taosArrayPush(pOrderInfoList, &biPk);
if (px == NULL) { if (px == NULL) {
taosArrayDestroy(pOrderInfoList);
return terrno; return terrno;
} }
} }

View File

@ -162,7 +162,7 @@ static int32_t udfSpawnUdfd(SUdfdData *pData) {
fnInfo("[UDFD]Succsess to set TAOS_FQDN:%s", taosFqdn); fnInfo("[UDFD]Succsess to set TAOS_FQDN:%s", taosFqdn);
} else { } else {
fnError("[UDFD]Failed to allocate memory for TAOS_FQDN"); fnError("[UDFD]Failed to allocate memory for TAOS_FQDN");
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
} }
@ -837,10 +837,13 @@ int32_t convertDataBlockToUdfDataBlock(SSDataBlock *block, SUdfDataBlock *udfBlo
udfBlock->numOfRows = block->info.rows; udfBlock->numOfRows = block->info.rows;
udfBlock->numOfCols = taosArrayGetSize(block->pDataBlock); udfBlock->numOfCols = taosArrayGetSize(block->pDataBlock);
udfBlock->udfCols = taosMemoryCalloc(taosArrayGetSize(block->pDataBlock), sizeof(SUdfColumn *)); udfBlock->udfCols = taosMemoryCalloc(taosArrayGetSize(block->pDataBlock), sizeof(SUdfColumn *));
if((udfBlock->udfCols) == NULL) {
return terrno;
}
for (int32_t i = 0; i < udfBlock->numOfCols; ++i) { for (int32_t i = 0; i < udfBlock->numOfCols; ++i) {
udfBlock->udfCols[i] = taosMemoryCalloc(1, sizeof(SUdfColumn)); udfBlock->udfCols[i] = taosMemoryCalloc(1, sizeof(SUdfColumn));
if(udfBlock->udfCols[i] == NULL) { if(udfBlock->udfCols[i] == NULL) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
SColumnInfoData *col = (SColumnInfoData *)taosArrayGet(block->pDataBlock, i); SColumnInfoData *col = (SColumnInfoData *)taosArrayGet(block->pDataBlock, i);
SUdfColumn *udfCol = udfBlock->udfCols[i]; SUdfColumn *udfCol = udfBlock->udfCols[i];
@ -854,13 +857,13 @@ int32_t convertDataBlockToUdfDataBlock(SSDataBlock *block, SUdfDataBlock *udfBlo
udfCol->colData.varLenCol.varOffsetsLen = sizeof(int32_t) * udfBlock->numOfRows; udfCol->colData.varLenCol.varOffsetsLen = sizeof(int32_t) * udfBlock->numOfRows;
udfCol->colData.varLenCol.varOffsets = taosMemoryMalloc(udfCol->colData.varLenCol.varOffsetsLen); udfCol->colData.varLenCol.varOffsets = taosMemoryMalloc(udfCol->colData.varLenCol.varOffsetsLen);
if(udfCol->colData.varLenCol.varOffsets == NULL) { if(udfCol->colData.varLenCol.varOffsets == NULL) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
memcpy(udfCol->colData.varLenCol.varOffsets, col->varmeta.offset, udfCol->colData.varLenCol.varOffsetsLen); memcpy(udfCol->colData.varLenCol.varOffsets, col->varmeta.offset, udfCol->colData.varLenCol.varOffsetsLen);
udfCol->colData.varLenCol.payloadLen = colDataGetLength(col, udfBlock->numOfRows); udfCol->colData.varLenCol.payloadLen = colDataGetLength(col, udfBlock->numOfRows);
udfCol->colData.varLenCol.payload = taosMemoryMalloc(udfCol->colData.varLenCol.payloadLen); udfCol->colData.varLenCol.payload = taosMemoryMalloc(udfCol->colData.varLenCol.payloadLen);
if(udfCol->colData.varLenCol.payload == NULL) { if(udfCol->colData.varLenCol.payload == NULL) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
if (col->reassigned) { if (col->reassigned) {
for (int32_t row = 0; row < udfCol->colData.numOfRows; ++row) { for (int32_t row = 0; row < udfCol->colData.numOfRows; ++row) {
@ -882,7 +885,7 @@ int32_t convertDataBlockToUdfDataBlock(SSDataBlock *block, SUdfDataBlock *udfBlo
int32_t bitmapLen = udfCol->colData.fixLenCol.nullBitmapLen; int32_t bitmapLen = udfCol->colData.fixLenCol.nullBitmapLen;
udfCol->colData.fixLenCol.nullBitmap = taosMemoryMalloc(udfCol->colData.fixLenCol.nullBitmapLen); udfCol->colData.fixLenCol.nullBitmap = taosMemoryMalloc(udfCol->colData.fixLenCol.nullBitmapLen);
if(udfCol->colData.fixLenCol.nullBitmap == NULL) { if(udfCol->colData.fixLenCol.nullBitmap == NULL) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
char *bitmap = udfCol->colData.fixLenCol.nullBitmap; char *bitmap = udfCol->colData.fixLenCol.nullBitmap;
memcpy(bitmap, col->nullbitmap, bitmapLen); memcpy(bitmap, col->nullbitmap, bitmapLen);
@ -985,7 +988,7 @@ int32_t convertDataBlockToScalarParm(SSDataBlock *input, SScalarParam *output) {
output->columnData = taosMemoryMalloc(sizeof(SColumnInfoData)); output->columnData = taosMemoryMalloc(sizeof(SColumnInfoData));
if(output->columnData == NULL) { if(output->columnData == NULL) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
memcpy(output->columnData, taosArrayGet(input->pDataBlock, 0), sizeof(SColumnInfoData)); memcpy(output->columnData, taosArrayGet(input->pDataBlock, 0), sizeof(SColumnInfoData));
output->colAlloced = true; output->colAlloced = true;
@ -1724,7 +1727,7 @@ int32_t udfcStartUvTask(SClientUvTaskNode *uvTask) {
if(conn == NULL) { if(conn == NULL) {
fnError("udfc event loop start connect task malloc conn failed."); fnError("udfc event loop start connect task malloc conn failed.");
taosMemoryFree(pipe); taosMemoryFree(pipe);
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
conn->pipe = pipe; conn->pipe = pipe;
conn->readBuf.len = 0; conn->readBuf.len = 0;
@ -1954,7 +1957,7 @@ int32_t udfcRunUdfUvTask(SClientUdfTask *task, int8_t uvTaskType) {
SClientUvTaskNode *uvTask = taosMemoryCalloc(1, sizeof(SClientUvTaskNode)); SClientUvTaskNode *uvTask = taosMemoryCalloc(1, sizeof(SClientUvTaskNode));
if(uvTask == NULL) { if(uvTask == NULL) {
fnError("udfc client task: %p failed to allocate memory for uvTask", task); fnError("udfc client task: %p failed to allocate memory for uvTask", task);
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
fnDebug("udfc client task: %p created uvTask: %p. pipe: %p", task, uvTask, task->session->udfUvPipe); fnDebug("udfc client task: %p created uvTask: %p. pipe: %p", task, uvTask, task->session->udfUvPipe);
@ -1986,13 +1989,13 @@ int32_t doSetupUdf(char udfName[], UdfcFuncHandle *funcHandle) {
SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask)); SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask));
if(task == NULL) { if(task == NULL) {
fnError("doSetupUdf, failed to allocate memory for task"); fnError("doSetupUdf, failed to allocate memory for task");
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
task->session = taosMemoryCalloc(1, sizeof(SUdfcUvSession)); task->session = taosMemoryCalloc(1, sizeof(SUdfcUvSession));
if(task->session == NULL) { if(task->session == NULL) {
fnError("doSetupUdf, failed to allocate memory for session"); fnError("doSetupUdf, failed to allocate memory for session");
taosMemoryFree(task); taosMemoryFree(task);
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
task->session->udfc = &gUdfcProxy; task->session->udfc = &gUdfcProxy;
task->type = UDF_TASK_SETUP; task->type = UDF_TASK_SETUP;
@ -2037,7 +2040,7 @@ int32_t callUdf(UdfcFuncHandle handle, int8_t callType, SSDataBlock *input, SUdf
SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask)); SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask));
if(task == NULL) { if(task == NULL) {
fnError("udfc call udf. failed to allocate memory for task"); fnError("udfc call udf. failed to allocate memory for task");
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
task->session = (SUdfcUvSession *)handle; task->session = (SUdfcUvSession *)handle;
task->type = UDF_TASK_CALL; task->type = UDF_TASK_CALL;
@ -2169,7 +2172,7 @@ int32_t doTeardownUdf(UdfcFuncHandle handle) {
if(task == NULL) { if(task == NULL) {
fnError("doTeardownUdf, failed to allocate memory for task"); fnError("doTeardownUdf, failed to allocate memory for task");
taosMemoryFree(session); taosMemoryFree(session);
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
task->session = session; task->session = session;
task->type = UDF_TASK_TEARDOWN; task->type = UDF_TASK_TEARDOWN;

View File

@ -409,6 +409,10 @@ int32_t udfdInitializePythonPlugin(SUdfScriptPlugin *plugin) {
int16_t lenPythonPath = int16_t lenPythonPath =
strlen(tsUdfdLdLibPath) + strlen(global.udfDataDir) + 1 + 1; // global.udfDataDir:tsUdfdLdLibPath strlen(tsUdfdLdLibPath) + strlen(global.udfDataDir) + 1 + 1; // global.udfDataDir:tsUdfdLdLibPath
char *pythonPath = taosMemoryMalloc(lenPythonPath); char *pythonPath = taosMemoryMalloc(lenPythonPath);
if(pythonPath == NULL) {
uv_dlclose(&plugin->lib);
return terrno;
}
#ifdef WINDOWS #ifdef WINDOWS
snprintf(pythonPath, lenPythonPath, "%s;%s", global.udfDataDir, tsUdfdLdLibPath); snprintf(pythonPath, lenPythonPath, "%s;%s", global.udfDataDir, tsUdfdLdLibPath);
#else #else
@ -705,6 +709,10 @@ void udfdProcessSetupRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
uv_mutex_unlock(&udf->lock); uv_mutex_unlock(&udf->lock);
} }
SUdfcFuncHandle *handle = taosMemoryMalloc(sizeof(SUdfcFuncHandle)); SUdfcFuncHandle *handle = taosMemoryMalloc(sizeof(SUdfcFuncHandle));
if(handle == NULL) {
fnError("udfdProcessSetupRequest: malloc failed.");
code = terrno;
}
handle->udf = udf; handle->udf = udf;
_send: _send:
@ -775,7 +783,7 @@ void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
if (outBuf.buf != NULL) { if (outBuf.buf != NULL) {
code = udf->scriptPlugin->udfAggStartFunc(&outBuf, udf->scriptUdfCtx); code = udf->scriptPlugin->udfAggStartFunc(&outBuf, udf->scriptUdfCtx);
} else { } else {
code = TSDB_CODE_OUT_OF_MEMORY; code = terrno;
} }
subRsp->resultBuf = outBuf; subRsp->resultBuf = outBuf;
break; break;
@ -784,9 +792,13 @@ void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
SUdfDataBlock input = {0}; SUdfDataBlock input = {0};
if (convertDataBlockToUdfDataBlock(&call->block, &input) == TSDB_CODE_SUCCESS) { if (convertDataBlockToUdfDataBlock(&call->block, &input) == TSDB_CODE_SUCCESS) {
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0}; SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0};
code = udf->scriptPlugin->udfAggProcFunc(&input, &call->interBuf, &outBuf, udf->scriptUdfCtx); if (outBuf.buf != NULL) {
freeUdfInterBuf(&call->interBuf); code = udf->scriptPlugin->udfAggProcFunc(&input, &call->interBuf, &outBuf, udf->scriptUdfCtx);
subRsp->resultBuf = outBuf; freeUdfInterBuf(&call->interBuf);
subRsp->resultBuf = outBuf;
} else {
code = terrno;
}
} }
freeUdfDataDataBlock(&input); freeUdfDataDataBlock(&input);
@ -794,18 +806,27 @@ void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
} }
case TSDB_UDF_CALL_AGG_MERGE: { case TSDB_UDF_CALL_AGG_MERGE: {
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0}; SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0};
code = udf->scriptPlugin->udfAggMergeFunc(&call->interBuf, &call->interBuf2, &outBuf, udf->scriptUdfCtx); if (outBuf.buf != NULL) {
freeUdfInterBuf(&call->interBuf); code = udf->scriptPlugin->udfAggMergeFunc(&call->interBuf, &call->interBuf2, &outBuf, udf->scriptUdfCtx);
freeUdfInterBuf(&call->interBuf2); freeUdfInterBuf(&call->interBuf);
subRsp->resultBuf = outBuf; freeUdfInterBuf(&call->interBuf2);
subRsp->resultBuf = outBuf;
} else {
code = terrno;
}
break; break;
} }
case TSDB_UDF_CALL_AGG_FIN: { case TSDB_UDF_CALL_AGG_FIN: {
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0}; SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0};
code = udf->scriptPlugin->udfAggFinishFunc(&call->interBuf, &outBuf, udf->scriptUdfCtx); if (outBuf.buf != NULL) {
freeUdfInterBuf(&call->interBuf); code = udf->scriptPlugin->udfAggFinishFunc(&call->interBuf, &outBuf, udf->scriptUdfCtx);
subRsp->resultBuf = outBuf; freeUdfInterBuf(&call->interBuf);
subRsp->resultBuf = outBuf;
} else {
code = terrno;
}
break; break;
} }
default: default:
@ -820,19 +841,24 @@ void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
int32_t len = encodeUdfResponse(NULL, rsp); int32_t len = encodeUdfResponse(NULL, rsp);
if(len < 0) { if(len < 0) {
fnError("udfdProcessCallRequest: encode udf response failed. len %d", len); fnError("udfdProcessCallRequest: encode udf response failed. len %d", len);
return; goto _exit;
} }
rsp->msgLen = len; rsp->msgLen = len;
void *bufBegin = taosMemoryMalloc(len); void *bufBegin = taosMemoryMalloc(len);
if (bufBegin == NULL) {
fnError("udfdProcessCallRequest: malloc failed. len %d", len);
goto _exit;
}
void *buf = bufBegin; void *buf = bufBegin;
if(encodeUdfResponse(&buf, rsp) < 0) { if(encodeUdfResponse(&buf, rsp) < 0) {
fnError("udfdProcessCallRequest: encode udf response failed. len %d", len); fnError("udfdProcessCallRequest: encode udf response failed. len %d", len);
taosMemoryFree(bufBegin); taosMemoryFree(bufBegin);
return; goto _exit;
} }
uvUdf->output = uv_buf_init(bufBegin, len); uvUdf->output = uv_buf_init(bufBegin, len);
_exit:
switch (call->callType) { switch (call->callType) {
case TSDB_UDF_CALL_SCALA_PROC: { case TSDB_UDF_CALL_SCALA_PROC: {
blockDataFreeRes(&call->block); blockDataFreeRes(&call->block);
@ -906,6 +932,10 @@ _send:
} }
rsp->msgLen = len; rsp->msgLen = len;
void *bufBegin = taosMemoryMalloc(len); void *bufBegin = taosMemoryMalloc(len);
if(bufBegin == NULL) {
fnError("udfdProcessTeardownRequest: malloc failed. len %d", len);
return;
}
void *buf = bufBegin; void *buf = bufBegin;
if (encodeUdfResponse(&buf, rsp) < 0) { if (encodeUdfResponse(&buf, rsp) < 0) {
fnError("udfdProcessTeardownRequest: encode udf response failed. len %d", len); fnError("udfdProcessTeardownRequest: encode udf response failed. len %d", len);
@ -1173,7 +1203,7 @@ int32_t udfdOpenClientRpc() {
global.clientRpc = rpcOpen(&rpcInit); global.clientRpc = rpcOpen(&rpcInit);
if (global.clientRpc == NULL) { if (global.clientRpc == NULL) {
fnError("failed to init dnode rpc client"); fnError("failed to init dnode rpc client");
return -1; return terrno;
} }
return 0; return 0;
} }
@ -1210,6 +1240,11 @@ void udfdSendResponse(uv_work_t *work, int status) {
if (udfWork->conn != NULL) { if (udfWork->conn != NULL) {
uv_write_t *write_req = taosMemoryMalloc(sizeof(uv_write_t)); uv_write_t *write_req = taosMemoryMalloc(sizeof(uv_write_t));
if(write_req == NULL) {
fnError("udfd send response error, malloc failed");
taosMemoryFree(work);
return;
}
write_req->data = udfWork; write_req->data = udfWork;
int32_t code = uv_write(write_req, udfWork->conn->client, &udfWork->output, 1, udfdOnWrite); int32_t code = uv_write(write_req, udfWork->conn->client, &udfWork->output, 1, udfdOnWrite);
if (code != 0) { if (code != 0) {
@ -1269,7 +1304,16 @@ void udfdHandleRequest(SUdfdUvConn *conn) {
int32_t inputLen = conn->inputLen; int32_t inputLen = conn->inputLen;
uv_work_t *work = taosMemoryMalloc(sizeof(uv_work_t)); uv_work_t *work = taosMemoryMalloc(sizeof(uv_work_t));
if(work == NULL) {
fnError("udfd malloc work failed");
return;
}
SUvUdfWork *udfWork = taosMemoryMalloc(sizeof(SUvUdfWork)); SUvUdfWork *udfWork = taosMemoryMalloc(sizeof(SUvUdfWork));
if(udfWork == NULL) {
fnError("udfd malloc udf work failed");
taosMemoryFree(work);
return;
}
udfWork->conn = conn; udfWork->conn = conn;
udfWork->pWorkNext = conn->pWorkList; udfWork->pWorkNext = conn->pWorkList;
conn->pWorkList = udfWork; conn->pWorkList = udfWork;
@ -1334,6 +1378,10 @@ void udfdOnNewConnection(uv_stream_t *server, int status) {
int32_t code = 0; int32_t code = 0;
uv_pipe_t *client = (uv_pipe_t *)taosMemoryMalloc(sizeof(uv_pipe_t)); uv_pipe_t *client = (uv_pipe_t *)taosMemoryMalloc(sizeof(uv_pipe_t));
if(client == NULL) {
fnError("udfd pipe malloc failed");
return;
}
code = uv_pipe_init(global.loop, client, 0); code = uv_pipe_init(global.loop, client, 0);
if (code) { if (code) {
fnError("udfd pipe init error %s", uv_strerror(code)); fnError("udfd pipe init error %s", uv_strerror(code));
@ -1342,6 +1390,10 @@ void udfdOnNewConnection(uv_stream_t *server, int status) {
} }
if (uv_accept(server, (uv_stream_t *)client) == 0) { if (uv_accept(server, (uv_stream_t *)client) == 0) {
SUdfdUvConn *ctx = taosMemoryMalloc(sizeof(SUdfdUvConn)); SUdfdUvConn *ctx = taosMemoryMalloc(sizeof(SUdfdUvConn));
if(ctx == NULL) {
fnError("udfd conn malloc failed");
goto _exit;
}
ctx->pWorkList = NULL; ctx->pWorkList = NULL;
ctx->client = (uv_stream_t *)client; ctx->client = (uv_stream_t *)client;
ctx->inputBuf = 0; ctx->inputBuf = 0;
@ -1356,9 +1408,11 @@ void udfdOnNewConnection(uv_stream_t *server, int status) {
taosMemoryFree(ctx); taosMemoryFree(ctx);
taosMemoryFree(client); taosMemoryFree(client);
} }
} else { return;
uv_close((uv_handle_t *)client, NULL);
} }
_exit:
uv_close((uv_handle_t *)client, NULL);
taosMemoryFree(client);
} }
void udfdIntrSignalHandler(uv_signal_t *handle, int signum) { void udfdIntrSignalHandler(uv_signal_t *handle, int signum) {
@ -1411,6 +1465,10 @@ static int32_t udfdInitLog() {
void udfdCtrlAllocBufCb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { void udfdCtrlAllocBufCb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = taosMemoryMalloc(suggested_size); buf->base = taosMemoryMalloc(suggested_size);
if (buf->base == NULL) {
fnError("udfd ctrl pipe alloc buffer failed");
return;
}
buf->len = suggested_size; buf->len = suggested_size;
} }
@ -1477,13 +1535,13 @@ static int32_t udfdGlobalDataInit() {
uv_loop_t *loop = taosMemoryMalloc(sizeof(uv_loop_t)); uv_loop_t *loop = taosMemoryMalloc(sizeof(uv_loop_t));
if (loop == NULL) { if (loop == NULL) {
fnError("udfd init uv loop failed, mem overflow"); fnError("udfd init uv loop failed, mem overflow");
return -1; return terrno;
} }
global.loop = loop; global.loop = loop;
if (uv_mutex_init(&global.scriptPluginsMutex) != 0) { if (uv_mutex_init(&global.scriptPluginsMutex) != 0) {
fnError("udfd init script plugins mutex failed"); fnError("udfd init script plugins mutex failed");
return -1; return TSDB_CODE_UDF_UV_EXEC_FAILURE;
} }
global.udfsHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); global.udfsHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
@ -1494,7 +1552,7 @@ static int32_t udfdGlobalDataInit() {
if (uv_mutex_init(&global.udfsMutex) != 0) { if (uv_mutex_init(&global.udfsMutex) != 0) {
fnError("udfd init udfs mutex failed"); fnError("udfd init udfs mutex failed");
return -2; return TSDB_CODE_UDF_UV_EXEC_FAILURE;
} }
return 0; return 0;

View File

@ -34,7 +34,7 @@ int32_t queryBuildUseDbOutput(SUseDbOutput *pOut, SUseDbRsp *usedbRsp) {
pOut->dbVgroup = taosMemoryCalloc(1, sizeof(SDBVgInfo)); pOut->dbVgroup = taosMemoryCalloc(1, sizeof(SDBVgInfo));
if (NULL == pOut->dbVgroup) { if (NULL == pOut->dbVgroup) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
pOut->dbVgroup->vgVersion = usedbRsp->vgVersion; pOut->dbVgroup->vgVersion = usedbRsp->vgVersion;
@ -509,7 +509,7 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp *msg, bool isStb, STableMeta *
STableMeta *pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize); STableMeta *pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize);
if (NULL == pTableMeta) { if (NULL == pTableMeta) {
qError("calloc size[%d] failed", metaSize); qError("calloc size[%d] failed", metaSize);
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
SSchemaExt *pSchemaExt = (SSchemaExt *)((char *)pTableMeta + metaSize); SSchemaExt *pSchemaExt = (SSchemaExt *)((char *)pTableMeta + metaSize);
@ -764,7 +764,7 @@ int32_t queryProcessGetTbCfgRsp(void *output, char *msg, int32_t msgSize) {
STableCfgRsp *out = taosMemoryCalloc(1, sizeof(STableCfgRsp)); STableCfgRsp *out = taosMemoryCalloc(1, sizeof(STableCfgRsp));
if(out == NULL) { if(out == NULL) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
if (tDeserializeSTableCfgRsp(msg, msgSize, out) != 0) { if (tDeserializeSTableCfgRsp(msg, msgSize, out) != 0) {
qError("tDeserializeSTableCfgRsp failed, msgSize:%d", msgSize); qError("tDeserializeSTableCfgRsp failed, msgSize:%d", msgSize);
@ -785,7 +785,7 @@ int32_t queryProcessGetViewMetaRsp(void *output, char *msg, int32_t msgSize) {
SViewMetaRsp *out = taosMemoryCalloc(1, sizeof(SViewMetaRsp)); SViewMetaRsp *out = taosMemoryCalloc(1, sizeof(SViewMetaRsp));
if (out == NULL) { if (out == NULL) {
return TSDB_CODE_OUT_OF_MEMORY; return terrno;
} }
if (tDeserializeSViewMetaRsp(msg, msgSize, out) != 0) { if (tDeserializeSViewMetaRsp(msg, msgSize, out) != 0) {
qError("tDeserializeSViewMetaRsp failed, msgSize:%d", msgSize); qError("tDeserializeSViewMetaRsp failed, msgSize:%d", msgSize);

View File

@ -2343,7 +2343,7 @@ _return:
(void)filterFreeRangeCtx(ctx); // No need to handle the return value. (void)filterFreeRangeCtx(ctx); // No need to handle the return value.
return TSDB_CODE_SUCCESS; return code;
} }
int32_t filterMergeGroupUnits(SFilterInfo *info, SFilterGroupCtx **gRes, int32_t *gResNum) { int32_t filterMergeGroupUnits(SFilterInfo *info, SFilterGroupCtx **gRes, int32_t *gResNum) {
@ -2671,7 +2671,7 @@ _return:
(void)filterFreeRangeCtx(ctx); // No need to handle the return value. (void)filterFreeRangeCtx(ctx); // No need to handle the return value.
return TSDB_CODE_SUCCESS; return code;
} }
int32_t filterMergeGroups(SFilterInfo *info, SFilterGroupCtx **gRes, int32_t *gResNum) { int32_t filterMergeGroups(SFilterInfo *info, SFilterGroupCtx **gRes, int32_t *gResNum) {
@ -2758,7 +2758,7 @@ _return:
FILTER_SET_FLAG(info->status, FI_STATUS_ALL); FILTER_SET_FLAG(info->status, FI_STATUS_ALL);
return TSDB_CODE_SUCCESS; return code;
} }
int32_t filterConvertGroupFromArray(SFilterInfo *info, SArray *group) { int32_t filterConvertGroupFromArray(SFilterInfo *info, SArray *group) {
@ -2958,7 +2958,7 @@ _return:
taosMemoryFreeClear(idxNum); taosMemoryFreeClear(idxNum);
taosMemoryFreeClear(idxs); taosMemoryFreeClear(idxs);
return TSDB_CODE_SUCCESS; return code;
} }
int32_t filterPostProcessRange(SFilterInfo *info) { int32_t filterPostProcessRange(SFilterInfo *info) {
@ -3601,12 +3601,12 @@ int32_t filterPreprocess(SFilterInfo *info) {
if (FILTER_GET_FLAG(info->status, FI_STATUS_ALL)) { if (FILTER_GET_FLAG(info->status, FI_STATUS_ALL)) {
fltInfo("Final - FilterInfo: [ALL]"); fltInfo("Final - FilterInfo: [ALL]");
goto _return; goto _return1;
} }
if (FILTER_GET_FLAG(info->status, FI_STATUS_EMPTY)) { if (FILTER_GET_FLAG(info->status, FI_STATUS_EMPTY)) {
fltInfo("Final - FilterInfo: [EMPTY]"); fltInfo("Final - FilterInfo: [EMPTY]");
goto _return; goto _return1;
} }
FLT_ERR_JRET(filterGenerateColRange(info, gRes, gResNum)); FLT_ERR_JRET(filterGenerateColRange(info, gRes, gResNum));
@ -3619,10 +3619,10 @@ int32_t filterPreprocess(SFilterInfo *info) {
FLT_ERR_JRET(filterGenerateComInfo(info)); FLT_ERR_JRET(filterGenerateComInfo(info));
_return1:
FLT_ERR_JRET(filterSetExecFunc(info));
_return: _return:
FLT_ERR_RET(filterSetExecFunc(info));
for (int32_t i = 0; i < gResNum; ++i) { for (int32_t i = 0; i < gResNum; ++i) {
filterFreeGroupCtx(gRes[i]); filterFreeGroupCtx(gRes[i]);
} }
@ -3660,15 +3660,25 @@ int32_t fltInitFromNode(SNode *tree, SFilterInfo *info, uint32_t options) {
FLT_ERR_JRET(terrno); FLT_ERR_JRET(terrno);
} }
FLT_ERR_JRET(filterInitUnitsFields(info)); code = filterInitUnitsFields(info);
if(TSDB_CODE_SUCCESS != code) {
taosArrayDestroy(group);
goto _return;
}
SFltBuildGroupCtx tctx = {.info = info, .group = group}; SFltBuildGroupCtx tctx = {.info = info, .group = group};
nodesWalkExpr(tree, fltTreeToGroup, (void *)&tctx); nodesWalkExpr(tree, fltTreeToGroup, (void *)&tctx);
FLT_ERR_JRET(tctx.code); if (TSDB_CODE_SUCCESS != tctx.code) {
taosArrayDestroy(group);
FLT_ERR_JRET(filterConvertGroupFromArray(info, group)); code = tctx.code;
goto _return;
}
code = filterConvertGroupFromArray(info, group);
if (TSDB_CODE_SUCCESS != code) {
taosArrayDestroy(group);
goto _return;
}
taosArrayDestroy(group); taosArrayDestroy(group);
FLT_ERR_JRET(fltInitValFieldData(info)); FLT_ERR_JRET(fltInitValFieldData(info));
if (!FILTER_GET_FLAG(info->options, FLT_OPTION_NO_REWRITE)) { if (!FILTER_GET_FLAG(info->options, FLT_OPTION_NO_REWRITE)) {
@ -4993,7 +5003,7 @@ int32_t fltOptimizeNodes(SFilterInfo *pInfo, SNode **pNode, SFltTreeStat *pStat)
} }
_return: _return:
taosArrayDestroy(sclOpList); taosArrayDestroy(sclOpList);
return TSDB_CODE_SUCCESS; return code;
} }
int32_t fltGetDataFromColId(void *param, int32_t id, void **data) { int32_t fltGetDataFromColId(void *param, int32_t id, void **data) {

View File

@ -904,9 +904,8 @@ int32_t sclExecOperator(SOperatorNode *node, SScalarCtx *ctx, SScalarParam *outp
terrno = TSDB_CODE_SUCCESS; terrno = TSDB_CODE_SUCCESS;
SCL_ERR_JRET(OperatorFn(pLeft, pRight, output, TSDB_ORDER_ASC)); SCL_ERR_JRET(OperatorFn(pLeft, pRight, output, TSDB_ORDER_ASC));
SCL_ERR_JRET(terrno);
_return:
_return:
sclFreeParamList(params, paramNum); sclFreeParamList(params, paramNum);
SCL_RET(code); SCL_RET(code);
} }

View File

@ -2913,7 +2913,7 @@ int32_t histogramScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarP
_return: _return:
taosMemoryFree(bins); taosMemoryFree(bins);
return TSDB_CODE_SUCCESS; return code;
} }
int32_t selectScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { int32_t selectScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {

View File

@ -193,7 +193,7 @@ static int32_t syncIOStartInternal(SSyncIO *io) {
io->clientRpc = rpcOpen(&rpcInit); io->clientRpc = rpcOpen(&rpcInit);
if (io->clientRpc == NULL) { if (io->clientRpc == NULL) {
sError("failed to initialize RPC"); sError("failed to initialize RPC");
return -1; return terrno;
} }
} }
@ -214,7 +214,7 @@ static int32_t syncIOStartInternal(SSyncIO *io) {
void *pRpc = rpcOpen(&rpcInit); void *pRpc = rpcOpen(&rpcInit);
if (pRpc == NULL) { if (pRpc == NULL) {
sError("failed to start RPC server"); sError("failed to start RPC server");
return -1; return terrno;
} }
} }

View File

@ -194,7 +194,11 @@ int tdbBtreeInsert(SBTree *pBt, const void *pKey, int kLen, const void *pVal, in
int idx; int idx;
int c; int c;
(void)tdbBtcOpen(&btc, pBt, pTxn); ret = tdbBtcOpen(&btc, pBt, pTxn);
if (ret) {
tdbError("tdb/btree-insert: btc open failed with ret: %d.", ret);
return ret;
}
tdbTrace("tdb insert, btc: %p, pTxn: %p", &btc, pTxn); tdbTrace("tdb insert, btc: %p, pTxn: %p", &btc, pTxn);
@ -235,7 +239,11 @@ int tdbBtreeDelete(SBTree *pBt, const void *pKey, int kLen, TXN *pTxn) {
int c; int c;
int ret; int ret;
(void)tdbBtcOpen(&btc, pBt, pTxn); ret = tdbBtcOpen(&btc, pBt, pTxn);
if (ret) {
tdbError("tdb/btree-delete: btc open failed with ret: %d.", ret);
return ret;
}
/* /*
btc.coder.ofps = taosArrayInit(8, sizeof(SPage *)); btc.coder.ofps = taosArrayInit(8, sizeof(SPage *));
// btc.coder.ofps = taosArrayInit(8, sizeof(SPgno)); // btc.coder.ofps = taosArrayInit(8, sizeof(SPgno));
@ -337,7 +345,11 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
void *pTVal = NULL; void *pTVal = NULL;
SCellDecoder cd = {0}; SCellDecoder cd = {0};
(void)tdbBtcOpen(&btc, pBt, NULL); ret = tdbBtcOpen(&btc, pBt, NULL);
if (ret) {
tdbError("tdb/btree-pget: btc open failed with ret: %d.", ret);
return ret;
}
tdbTrace("tdb pget, btc: %p", &btc); tdbTrace("tdb pget, btc: %p", &btc);

View File

@ -160,7 +160,7 @@ int main(int argc, char *argv[]) {
void *pRpc = rpcOpen(&rpcInit); void *pRpc = rpcOpen(&rpcInit);
if (pRpc == NULL) { if (pRpc == NULL) {
tError("failed to initialize RPC"); tError("failed to initialize RPC");
return -1; return terrno;
} }
tInfo("client is initialized"); tInfo("client is initialized");

View File

@ -1208,20 +1208,28 @@ typedef struct UsingRegex {
regex_t pRegex; regex_t pRegex;
int32_t lastUsedTime; int32_t lastUsedTime;
} UsingRegex; } UsingRegex;
typedef UsingRegex* HashRegexPtr;
typedef struct RegexCache { typedef struct RegexCache {
SHashObj *regexHash; SHashObj *regexHash;
void *regexCacheTmr; void *regexCacheTmr;
void *timer; void *timer;
SRWLatch mutex;
bool exit;
} RegexCache; } RegexCache;
static RegexCache sRegexCache; static RegexCache sRegexCache;
#define MAX_REGEX_CACHE_SIZE 20 #define MAX_REGEX_CACHE_SIZE 20
#define REGEX_CACHE_CLEAR_TIME 30 #define REGEX_CACHE_CLEAR_TIME 30
static void checkRegexCache(void* param, void* tmrId) { static void checkRegexCache(void* param, void* tmrId) {
int32_t code = 0;
taosRLockLatch(&sRegexCache.mutex);
if(sRegexCache.exit) {
goto _exit;
}
(void)taosTmrReset(checkRegexCache, REGEX_CACHE_CLEAR_TIME * 1000, param, sRegexCache.regexCacheTmr, &tmrId); (void)taosTmrReset(checkRegexCache, REGEX_CACHE_CLEAR_TIME * 1000, param, sRegexCache.regexCacheTmr, &tmrId);
if (taosHashGetSize(sRegexCache.regexHash) < MAX_REGEX_CACHE_SIZE) { if (taosHashGetSize(sRegexCache.regexHash) < MAX_REGEX_CACHE_SIZE) {
return; goto _exit;
} }
if (taosHashGetSize(sRegexCache.regexHash) >= MAX_REGEX_CACHE_SIZE) { if (taosHashGetSize(sRegexCache.regexHash) >= MAX_REGEX_CACHE_SIZE) {
@ -1235,6 +1243,8 @@ static void checkRegexCache(void* param, void* tmrId) {
ppUsingRegex = taosHashIterate(sRegexCache.regexHash, ppUsingRegex); ppUsingRegex = taosHashIterate(sRegexCache.regexHash, ppUsingRegex);
} }
} }
_exit:
taosRUnLockLatch(&sRegexCache.mutex);
} }
void regexCacheFree(void *ppUsingRegex) { void regexCacheFree(void *ppUsingRegex) {
@ -1246,30 +1256,35 @@ int32_t InitRegexCache() {
sRegexCache.regexHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK); sRegexCache.regexHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
if (sRegexCache.regexHash == NULL) { if (sRegexCache.regexHash == NULL) {
uError("failed to create RegexCache"); uError("failed to create RegexCache");
return -1; return terrno;
} }
taosHashSetFreeFp(sRegexCache.regexHash, regexCacheFree); taosHashSetFreeFp(sRegexCache.regexHash, regexCacheFree);
sRegexCache.regexCacheTmr = taosTmrInit(0, 0, 0, "REGEXCACHE"); sRegexCache.regexCacheTmr = taosTmrInit(0, 0, 0, "REGEXCACHE");
if (sRegexCache.regexCacheTmr == NULL) { if (sRegexCache.regexCacheTmr == NULL) {
uError("failed to create regex cache check timer"); uError("failed to create regex cache check timer");
terrno = TSDB_CODE_OUT_OF_MEMORY; return terrno;
return -1;
} }
sRegexCache.exit = false;
taosInitRWLatch(&sRegexCache.mutex);
sRegexCache.timer = taosTmrStart(checkRegexCache, REGEX_CACHE_CLEAR_TIME * 1000, NULL, sRegexCache.regexCacheTmr); sRegexCache.timer = taosTmrStart(checkRegexCache, REGEX_CACHE_CLEAR_TIME * 1000, NULL, sRegexCache.regexCacheTmr);
if (sRegexCache.timer == NULL) { if (sRegexCache.timer == NULL) {
uError("failed to start regex cache timer"); uError("failed to start regex cache timer");
return -1; return terrno;
} }
return 0; return TSDB_CODE_SUCCESS;
} }
void DestroyRegexCache(){ void DestroyRegexCache(){
int32_t code = 0;
uInfo("[regex cache] destory regex cache"); uInfo("[regex cache] destory regex cache");
(void)taosTmrStopA(&sRegexCache.timer); (void)taosTmrStopA(&sRegexCache.timer);
taosWLockLatch(&sRegexCache.mutex);
sRegexCache.exit = true;
taosHashCleanup(sRegexCache.regexHash); taosHashCleanup(sRegexCache.regexHash);
taosTmrCleanUp(sRegexCache.regexCacheTmr); taosTmrCleanUp(sRegexCache.regexCacheTmr);
taosWUnLockLatch(&sRegexCache.mutex);
} }
int32_t checkRegexPattern(const char *pPattern) { int32_t checkRegexPattern(const char *pPattern) {
@ -1290,18 +1305,17 @@ int32_t checkRegexPattern(const char *pPattern) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static UsingRegex **getRegComp(const char *pPattern) { int32_t getRegComp(const char *pPattern, HashRegexPtr **regexRet) {
UsingRegex **ppUsingRegex = (UsingRegex **)taosHashAcquire(sRegexCache.regexHash, pPattern, strlen(pPattern)); HashRegexPtr* ppUsingRegex = (HashRegexPtr*)taosHashAcquire(sRegexCache.regexHash, pPattern, strlen(pPattern));
if (ppUsingRegex != NULL) { if (ppUsingRegex != NULL) {
(*ppUsingRegex)->lastUsedTime = taosGetTimestampSec(); (*ppUsingRegex)->lastUsedTime = taosGetTimestampSec();
return ppUsingRegex; *regexRet = ppUsingRegex;
return TSDB_CODE_SUCCESS;
} }
UsingRegex *pUsingRegex = taosMemoryMalloc(sizeof(UsingRegex)); UsingRegex *pUsingRegex = taosMemoryMalloc(sizeof(UsingRegex));
if (pUsingRegex == NULL) { if (pUsingRegex == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
uError("Failed to Malloc when compile regex pattern %s.", pPattern); uError("Failed to Malloc when compile regex pattern %s.", pPattern);
return NULL; return terrno;
} }
int32_t cflags = REG_EXTENDED; int32_t cflags = REG_EXTENDED;
int32_t ret = regcomp(&pUsingRegex->pRegex, pPattern, cflags); int32_t ret = regcomp(&pUsingRegex->pRegex, pPattern, cflags);
@ -1310,8 +1324,7 @@ static UsingRegex **getRegComp(const char *pPattern) {
(void)regerror(ret, &pUsingRegex->pRegex, msgbuf, tListLen(msgbuf)); (void)regerror(ret, &pUsingRegex->pRegex, msgbuf, tListLen(msgbuf));
uError("Failed to compile regex pattern %s. reason %s", pPattern, msgbuf); uError("Failed to compile regex pattern %s. reason %s", pPattern, msgbuf);
taosMemoryFree(pUsingRegex); taosMemoryFree(pUsingRegex);
terrno = TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR; return TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR;
return NULL;
} }
while (true) { while (true) {
@ -1319,8 +1332,9 @@ static UsingRegex **getRegComp(const char *pPattern) {
if (code != 0 && code != TSDB_CODE_DUP_KEY) { if (code != 0 && code != TSDB_CODE_DUP_KEY) {
regexCacheFree(&pUsingRegex); regexCacheFree(&pUsingRegex);
uError("Failed to put regex pattern %s into cache, exception internal error.", pPattern); uError("Failed to put regex pattern %s into cache, exception internal error.", pPattern);
terrno = code; return code;
return NULL; } else if (code == TSDB_CODE_DUP_KEY) {
terrno = 0;
} }
ppUsingRegex = (UsingRegex **)taosHashAcquire(sRegexCache.regexHash, pPattern, strlen(pPattern)); ppUsingRegex = (UsingRegex **)taosHashAcquire(sRegexCache.regexHash, pPattern, strlen(pPattern));
if (ppUsingRegex) { if (ppUsingRegex) {
@ -1334,27 +1348,68 @@ static UsingRegex **getRegComp(const char *pPattern) {
} }
} }
pUsingRegex->lastUsedTime = taosGetTimestampSec(); pUsingRegex->lastUsedTime = taosGetTimestampSec();
return ppUsingRegex; *regexRet = ppUsingRegex;
return TSDB_CODE_SUCCESS;
} }
void releaseRegComp(UsingRegex **regex){ void releaseRegComp(UsingRegex **regex){
taosHashRelease(sRegexCache.regexHash, regex); taosHashRelease(sRegexCache.regexHash, regex);
} }
static threadlocal UsingRegex ** ppUsingRegex;
static threadlocal regex_t * pRegex;
static threadlocal char *pOldPattern = NULL;
void DestoryThreadLocalRegComp() {
if (NULL != pOldPattern) {
releaseRegComp(ppUsingRegex);
taosMemoryFree(pOldPattern);
ppUsingRegex = NULL;
pRegex = NULL;
pOldPattern = NULL;
}
}
int32_t threadGetRegComp(regex_t **regex, const char *pPattern) {
if (NULL != pOldPattern) {
if (strcmp(pOldPattern, pPattern) == 0) {
*regex = pRegex;
return 0;
} else {
DestoryThreadLocalRegComp();
}
}
HashRegexPtr *ppRegex = NULL;
int32_t code = getRegComp(pPattern, &ppRegex);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
pOldPattern = taosStrdup(pPattern);
if (NULL == pOldPattern) {
uError("Failed to Malloc when compile regex pattern %s.", pPattern);
return terrno;
}
ppUsingRegex = ppRegex;
pRegex = &((*ppUsingRegex)->pRegex);
*regex = &(*ppRegex)->pRegex;
return 0;
}
static int32_t doExecRegexMatch(const char *pString, const char *pPattern) { static int32_t doExecRegexMatch(const char *pString, const char *pPattern) {
int32_t ret = 0; int32_t ret = 0;
char msgbuf[256] = {0}; char msgbuf[256] = {0};
UsingRegex **pUsingRegex = getRegComp(pPattern);
if (pUsingRegex == NULL) { regex_t *regex = NULL;
return 1; ret = threadGetRegComp(&regex, pPattern);
if (ret != 0) {
return ret;
} }
regmatch_t pmatch[1]; regmatch_t pmatch[1];
ret = regexec(&(*pUsingRegex)->pRegex, pString, 1, pmatch, 0); ret = regexec(regex, pString, 1, pmatch, 0);
releaseRegComp(pUsingRegex);
if (ret != 0 && ret != REG_NOMATCH) { if (ret != 0 && ret != REG_NOMATCH) {
terrno = TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR; terrno = TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR;
(void)regerror(ret, &(*pUsingRegex)->pRegex, msgbuf, sizeof(msgbuf)); (void)regerror(ret, regex, msgbuf, sizeof(msgbuf));
uDebug("Failed to match %s with pattern %s, reason %s", pString, pPattern, msgbuf) uDebug("Failed to match %s with pattern %s, reason %s", pString, pPattern, msgbuf)
} }
@ -1365,8 +1420,7 @@ int32_t comparestrRegexMatch(const void *pLeft, const void *pRight) {
size_t sz = varDataLen(pRight); size_t sz = varDataLen(pRight);
char *pattern = taosMemoryMalloc(sz + 1); char *pattern = taosMemoryMalloc(sz + 1);
if (NULL == pattern) { if (NULL == pattern) {
terrno = TSDB_CODE_OUT_OF_MEMORY; return 1; // terrno has been set
return 1;
} }
(void)memcpy(pattern, varDataVal(pRight), varDataLen(pRight)); (void)memcpy(pattern, varDataVal(pRight), varDataLen(pRight));
@ -1376,8 +1430,7 @@ int32_t comparestrRegexMatch(const void *pLeft, const void *pRight) {
char *str = taosMemoryMalloc(sz + 1); char *str = taosMemoryMalloc(sz + 1);
if (NULL == str) { if (NULL == str) {
taosMemoryFree(pattern); taosMemoryFree(pattern);
terrno = TSDB_CODE_OUT_OF_MEMORY; return 1; // terrno has been set
return 1;
} }
(void)memcpy(str, varDataVal(pLeft), sz); (void)memcpy(str, varDataVal(pLeft), sz);
@ -1395,14 +1448,13 @@ int32_t comparewcsRegexMatch(const void *pString, const void *pPattern) {
size_t len = varDataLen(pPattern); size_t len = varDataLen(pPattern);
char *pattern = taosMemoryMalloc(len + 1); char *pattern = taosMemoryMalloc(len + 1);
if (NULL == pattern) { if (NULL == pattern) {
terrno = TSDB_CODE_OUT_OF_MEMORY; return 1; // terrno has been set
return 1;
} }
int convertLen = taosUcs4ToMbs((TdUcs4 *)varDataVal(pPattern), len, pattern); int convertLen = taosUcs4ToMbs((TdUcs4 *)varDataVal(pPattern), len, pattern);
if (convertLen < 0) { if (convertLen < 0) {
taosMemoryFree(pattern); taosMemoryFree(pattern);
return (terrno = TSDB_CODE_APP_ERROR); return 1; // terrno has been set
} }
pattern[convertLen] = 0; pattern[convertLen] = 0;
@ -1411,15 +1463,14 @@ int32_t comparewcsRegexMatch(const void *pString, const void *pPattern) {
char *str = taosMemoryMalloc(len + 1); char *str = taosMemoryMalloc(len + 1);
if (NULL == str) { if (NULL == str) {
taosMemoryFree(pattern); taosMemoryFree(pattern);
terrno = TSDB_CODE_OUT_OF_MEMORY; return 1; // terrno has been set
return 1;
} }
convertLen = taosUcs4ToMbs((TdUcs4 *)varDataVal(pString), len, str); convertLen = taosUcs4ToMbs((TdUcs4 *)varDataVal(pString), len, str);
if (convertLen < 0) { if (convertLen < 0) {
taosMemoryFree(str); taosMemoryFree(str);
taosMemoryFree(pattern); taosMemoryFree(pattern);
return (terrno = TSDB_CODE_APP_ERROR); return 1; // terrno has been set
} }
str[convertLen] = 0; str[convertLen] = 0;

View File

@ -567,7 +567,7 @@ static inline void taosPrintLogImp(ELogLevel level, int32_t dflag, const char *b
} }
} }
void taosPrintLog(const char *flags, ELogLevel level, int32_t dflag, const char *format, ...) { void taosPrintLog(const char *flags, int32_t level, int32_t dflag, const char *format, ...) {
if (!(dflag & DEBUG_FILE) && !(dflag & DEBUG_SCREEN)) return; if (!(dflag & DEBUG_FILE) && !(dflag & DEBUG_SCREEN)) return;
char buffer[LOG_MAX_LINE_BUFFER_SIZE]; char buffer[LOG_MAX_LINE_BUFFER_SIZE];
@ -590,7 +590,7 @@ void taosPrintLog(const char *flags, ELogLevel level, int32_t dflag, const char
} }
} }
void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, const char *format, ...) { void taosPrintLongString(const char *flags, int32_t level, int32_t dflag, const char *format, ...) {
if (!osLogSpaceAvailable()) return; if (!osLogSpaceAvailable()) return;
if (!(dflag & DEBUG_FILE) && !(dflag & DEBUG_SCREEN)) return; if (!(dflag & DEBUG_FILE) && !(dflag & DEBUG_SCREEN)) return;

View File

@ -106,6 +106,7 @@ static void *tQWorkerThreadFp(SQueueWorker *worker) {
} }
destroyThreadLocalGeosCtx(); destroyThreadLocalGeosCtx();
DestoryThreadLocalRegComp();
return NULL; return NULL;
} }
@ -237,6 +238,7 @@ static void *tAutoQWorkerThreadFp(SQueueWorker *worker) {
taosUpdateItemSize(qinfo.queue, 1); taosUpdateItemSize(qinfo.queue, 1);
} }
DestoryThreadLocalRegComp();
return NULL; return NULL;
} }
@ -664,6 +666,7 @@ static void *tQueryAutoQWorkerThreadFp(SQueryAutoQWorker *worker) {
} }
destroyThreadLocalGeosCtx(); destroyThreadLocalGeosCtx();
DestoryThreadLocalRegComp();
return NULL; return NULL;
} }

View File

@ -119,6 +119,13 @@ add_test(
COMMAND bufferTest COMMAND bufferTest
) )
add_executable(regexTest "regexTest.cpp")
target_link_libraries(regexTest os util gtest_main )
add_test(
NAME regexTest
COMMAND regexTest
)
#add_executable(decompressTest "decompressTest.cpp") #add_executable(decompressTest "decompressTest.cpp")
#target_link_libraries(decompressTest os util common gtest_main) #target_link_libraries(decompressTest os util common gtest_main)
#add_test( #add_test(

View File

@ -0,0 +1,344 @@
#include <chrono>
#include <cstdio>
#include <gtest/gtest.h>
#include <limits.h>
#include <taosdef.h>
#include "os.h"
#include "tutil.h"
#include "regex.h"
#include "osDef.h"
#include "tcompare.h"
extern "C" {
typedef struct UsingRegex UsingRegex;
typedef struct HashRegexPtr HashRegexPtr;
int32_t getRegComp(const char *pPattern, HashRegexPtr **regexRet);
int32_t threadGetRegComp(regex_t **regex, const char *pPattern);
}
class regexTest {
public:
regexTest() { (void)InitRegexCache(); }
~regexTest() { (void)DestroyRegexCache(); }
};
static regexTest test;
static threadlocal regex_t pRegex;
static threadlocal char *pOldPattern = NULL;
void DestoryThreadLocalRegComp1() {
if (NULL != pOldPattern) {
regfree(&pRegex);
taosMemoryFree(pOldPattern);
pOldPattern = NULL;
}
}
static regex_t *threadGetRegComp1(const char *pPattern) {
if (NULL != pOldPattern) {
if( strcmp(pOldPattern, pPattern) == 0) {
return &pRegex;
} else {
DestoryThreadLocalRegComp1();
}
}
pOldPattern = (char*)taosMemoryMalloc(strlen(pPattern) + 1);
if (NULL == pOldPattern) {
uError("Failed to Malloc when compile regex pattern %s.", pPattern);
return NULL;
}
strcpy(pOldPattern, pPattern);
int32_t cflags = REG_EXTENDED;
int32_t ret = regcomp(&pRegex, pPattern, cflags);
if (ret != 0) {
char msgbuf[256] = {0};
regerror(ret, &pRegex, msgbuf, tListLen(msgbuf));
uError("Failed to compile regex pattern %s. reason %s", pPattern, msgbuf);
DestoryThreadLocalRegComp1();
return NULL;
}
return &pRegex;
}
TEST(testCase, regexCacheTest1) {
int times = 100000;
char s1[] = "abc";
auto start = std::chrono::high_resolution_clock::now();
uint64_t t0 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s1, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s1;
}
}
uint64_t t1 = taosGetTimestampUs();
printf("%s regex(current) %d times:%" PRIu64 " us.\n", s1, times, t1 - t0);
uint64_t t2 = taosGetTimestampUs();
for(int i = 0; i < times; i++) {
regex_t* rex = threadGetRegComp1(s1);
}
uint64_t t3 = taosGetTimestampUs();
printf("%s regex(before) %d times:%" PRIu64 " us.\n", s1, times, t3 - t2);
t2 = taosGetTimestampUs();
for(int i = 0; i < times; i++) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s1);
}
t3 = taosGetTimestampUs();
printf("%s regex(new) %d times:%" PRIu64 " us.\n", s1, times, t3 - t2);
}
TEST(testCase, regexCacheTest2) {
int times = 100000;
char s1[] = "abc%*";
auto start = std::chrono::high_resolution_clock::now();
uint64_t t0 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s1, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s1;
}
}
uint64_t t1 = taosGetTimestampUs();
printf("%s regex(current) %d times:%" PRIu64 " us.\n", s1, times, t1 - t0);
uint64_t t2 = taosGetTimestampUs();
for(int i = 0; i < times; i++) {
regex_t* rex = threadGetRegComp1(s1);
}
uint64_t t3 = taosGetTimestampUs();
printf("%s regex(before) %d times:%" PRIu64 " us.\n", s1, times, t3 - t2);
t2 = taosGetTimestampUs();
for(int i = 0; i < times; i++) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s1);
}
t3 = taosGetTimestampUs();
printf("%s regex(new) %d times:%" PRIu64 " us.\n", s1, times, t3 - t2);
}
TEST(testCase, regexCacheTest3) {
int times = 100000;
char s1[] = "abc%*";
char s2[] = "abc";
auto start = std::chrono::high_resolution_clock::now();
uint64_t t0 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s1, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s1;
}
}
uint64_t t1 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn regex(current) %d times:%" PRIu64 " us.\n", s1, s2, times, t1 - t0);
uint64_t t2 = taosGetTimestampUs();
for(int i = 0; i < times; i++) {
regex_t* rex = threadGetRegComp1(s1);
rex = threadGetRegComp1(s2);
}
uint64_t t3 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn regex(before) %d times:%" PRIu64 " us.\n", s1, s2, times, t3 - t2);
t2 = taosGetTimestampUs();
for(int i = 0; i < times; i++) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s1);
(void)threadGetRegComp(&rex, s2);
}
t3 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn regex(new) %d times:%" PRIu64 " us.\n", s1, s2, times, t3 - t2);
}
TEST(testCase, regexCacheTest4) {
int times = 100;
int count = 1000;
char s1[] = "abc%*";
char s2[] = "abc";
auto start = std::chrono::high_resolution_clock::now();
uint64_t t0 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s1, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s1;
}
}
for (int j = 0; j < count; ++j) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s2, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s2;
}
}
}
uint64_t t1 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(current) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t1 - t0);
uint64_t t2 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
regex_t* rex = threadGetRegComp1(s1);
}
for (int j = 0; j < count; ++j) {
regex_t* rex = threadGetRegComp1(s2);
}
}
uint64_t t3 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(before) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t3 - t2);
t2 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s1);
}
for (int j = 0; j < count; ++j) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s2);
}
}
t3 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(new) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t3 - t2);
}
// It is not a good idea to test this case, because it will take a long time.
/*
TEST(testCase, regexCacheTest5) {
int times = 10000;
int count = 10000;
char s1[] = "abc%*";
char s2[] = "abc";
auto start = std::chrono::high_resolution_clock::now();
uint64_t t0 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s1, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s1;
}
}
for (int j = 0; j < count; ++j) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s2, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s2;
}
}
}
uint64_t t1 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(current) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t1 - t0);
uint64_t t2 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
regex_t* rex = threadGetRegComp1(s1);
}
for (int j = 0; j < count; ++j) {
regex_t* rex = threadGetRegComp1(s2);
}
}
uint64_t t3 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(before) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t3 - t2);
t2 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s1);
}
for (int j = 0; j < count; ++j) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s2);
}
}
t3 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(new) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t3 - t2);
}
TEST(testCase, regexCacheTest6) {
int times = 10000;
int count = 1000;
char s1[] = "abc%*";
char s2[] = "abc";
auto start = std::chrono::high_resolution_clock::now();
uint64_t t0 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s1, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s1;
}
}
for (int j = 0; j < count; ++j) {
HashRegexPtr* ret = NULL;
int32_t code = getRegComp(s2, &ret);
if (code != 0) {
FAIL() << "Failed to compile regex pattern " << s2;
}
}
}
uint64_t t1 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(current) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t1 - t0);
uint64_t t2 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
regex_t* rex = threadGetRegComp1(s1);
}
for (int j = 0; j < count; ++j) {
regex_t* rex = threadGetRegComp1(s2);
}
}
uint64_t t3 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(before) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t3 - t2);
t2 = taosGetTimestampUs();
for (int i = 0; i < times; i++) {
for (int j = 0; j < count; ++j) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s1);
}
for (int j = 0; j < count; ++j) {
regex_t* rex = NULL;
(void)threadGetRegComp(&rex, s2);
}
}
t3 = taosGetTimestampUs();
printf("'%s' and '%s' take place by turn(per %d count) regex(new) %d times:%" PRIu64 " us.\n", s1, s2, count, times, t3 - t2);
}
*/

View File

@ -8,13 +8,17 @@ DLL_EXPORT int32_t bit_and_init() { return 0; }
DLL_EXPORT int32_t bit_and_destroy() { return 0; } DLL_EXPORT int32_t bit_and_destroy() { return 0; }
DLL_EXPORT int32_t bit_and(SUdfDataBlock* block, SUdfColumn* resultCol) { DLL_EXPORT int32_t bit_and(SUdfDataBlock* block, SUdfColumn* resultCol) {
udfTrace("block:%p, processing begins, rows:%d cols:%d", block, block->numOfRows, block->numOfCols);
if (block->numOfCols < 2) { if (block->numOfCols < 2) {
udfError("block:%p, cols:%d needs to be greater than 2", block, block->numOfCols);
return TSDB_CODE_UDF_INVALID_INPUT; return TSDB_CODE_UDF_INVALID_INPUT;
} }
for (int32_t i = 0; i < block->numOfCols; ++i) { for (int32_t i = 0; i < block->numOfCols; ++i) {
SUdfColumn* col = block->udfCols[i]; SUdfColumn* col = block->udfCols[i];
if (!(col->colMeta.type == TSDB_DATA_TYPE_INT)) { if (col->colMeta.type != TSDB_DATA_TYPE_INT) {
udfError("block:%p, col:%d type:%d should be int(%d)", block, i, col->colMeta.type, TSDB_DATA_TYPE_INT);
return TSDB_CODE_UDF_INVALID_INPUT; return TSDB_CODE_UDF_INVALID_INPUT;
} }
} }
@ -23,25 +27,35 @@ DLL_EXPORT int32_t bit_and(SUdfDataBlock* block, SUdfColumn* resultCol) {
for (int32_t i = 0; i < block->numOfRows; ++i) { for (int32_t i = 0; i < block->numOfRows; ++i) {
if (udfColDataIsNull(block->udfCols[0], i)) { if (udfColDataIsNull(block->udfCols[0], i)) {
udfTrace("block:%p, row:%d result is null since col:0 is null", block, i);
udfColDataSetNull(resultCol, i); udfColDataSetNull(resultCol, i);
continue; continue;
} }
int32_t result = *(int32_t*)udfColDataGetData(block->udfCols[0], i); int32_t result = *(int32_t*)udfColDataGetData(block->udfCols[0], i);
int j = 1; udfTrace("block:%p, row:%d col:0 data:%d", block, i, result);
int32_t j = 1;
for (; j < block->numOfCols; ++j) { for (; j < block->numOfCols; ++j) {
if (udfColDataIsNull(block->udfCols[j], i)) { if (udfColDataIsNull(block->udfCols[j], i)) {
udfTrace("block:%p, row:%d result is null since col:%d is null", block, i, j);
udfColDataSetNull(resultCol, i); udfColDataSetNull(resultCol, i);
break; break;
} }
char* colData = udfColDataGetData(block->udfCols[j], i); char* colData = udfColDataGetData(block->udfCols[j], i);
result &= *(int32_t*)colData; result &= *(int32_t*)colData;
udfTrace("block:%p, row:%d col:%d data:%d", block, i, j, *(int32_t*)colData);
} }
if (j == block->numOfCols) { if (j == block->numOfCols) {
udfColDataSet(resultCol, i, (char*)&result, false); udfColDataSet(resultCol, i, (char*)&result, false);
udfTrace("block:%p, row:%d result is %d", block, i, result);
} }
} }
resultData->numOfRows = block->numOfRows; resultData->numOfRows = block->numOfRows;
udfTrace("block:%p, processing completed, rows:%d, cols:%d,", block, block->numOfRows, block->numOfCols);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }

View File

@ -104,7 +104,7 @@ class TDTestCase:
stop_flag = 0 stop_flag = 0
try: try:
while True: while True:
res = consumer.poll(1) res = consumer.poll(3)
tdSql.query('show consumers;') tdSql.query('show consumers;')
consumer_info = tdSql.queryResult[0][-1] consumer_info = tdSql.queryResult[0][-1]
if offset_value == "latest": if offset_value == "latest":