Merge branch '3.0' into fix/3_liaohj

This commit is contained in:
Haojun Liao 2024-08-09 10:31:55 +08:00
commit bc38eadf53
82 changed files with 2836 additions and 2012 deletions

View File

@ -6,7 +6,7 @@ toc_max_heading_level: 4
TDengine 是一个高性能、分布式的时序数据库。通过集成的缓存、数据订阅、流计算和数据清洗与转换等功能TDengine 已经发展成为一个专为物联网、工业互联网、金融和 IT 运维等关键行业量身定制的时序大数据平台。该平台能够高效地汇聚、存储、分析、计算和分发来自海量数据采集点的大规模数据流,每日处理能力可达 TB 乃至 PB 级别。借助 TDengine企业可以实现实时的业务监控和预警进而发掘出有价值的商业洞察。 TDengine 是一个高性能、分布式的时序数据库。通过集成的缓存、数据订阅、流计算和数据清洗与转换等功能TDengine 已经发展成为一个专为物联网、工业互联网、金融和 IT 运维等关键行业量身定制的时序大数据平台。该平台能够高效地汇聚、存储、分析、计算和分发来自海量数据采集点的大规模数据流,每日处理能力可达 TB 乃至 PB 级别。借助 TDengine企业可以实现实时的业务监控和预警进而发掘出有价值的商业洞察。
自 2019 年 7 月 以 来, 涛 将 TDengine 的 源, 机版2019 年 7 月、集群版2020 年 8 月以及云原生版2022 年 8 月。开源之后TDengine 迅速获得了全球开发者的关注,多次在 GitHub 网站全球趋势排行榜上位居榜首,最新的关注热度见[涛思数据首页](https://www.taosdata.com/)。 自 2019 年 7 月 以来, 涛思数据陆续将 TDengine 的不同版本开源包括单机版2019 年 7 月、集群版2020 年 8 月以及云原生版2022 年 8 月。开源之后TDengine 迅速获得了全球开发者的关注,多次在 GitHub 网站全球趋势排行榜上位居榜首,最新的关注热度见[涛思数据首页](https://www.taosdata.com/)。
## TDengine 产品 ## TDengine 产品
@ -20,7 +20,7 @@ TDengine OSS 是一个开源的高性能时序数据库,与其他时序数据
## TDengine 主要功能与特性 ## TDengine 主要功能与特性
TDengine 经过特别优化,以适应时间序列数据的独特需求,引入了“一个数据采集点一张表”和“超级表”的创新数据组织策略。这些策略背后的支撑是一个革命性的存储引擎,它极大地提升了数据处理的速度和效率,无论是在数据的写入、查询还是存储方面。接下来,逐一探索 TDengine 的众多功能,帮助您全面了解这个为高效处理时间序列数据而生的大数据平台。 TDengine 经过特别优化,以适应时间序列数据的独特需求,引入了 “一个数据采集点一张表” “超级表” 的创新数据组织策略。这些策略背后的支撑是一个革命性的存储引擎,它极大地提升了数据处理的速度和效率,无论是在数据的写入、查询还是存储方面。接下来,逐一探索 TDengine 的众多功能,帮助您全面了解这个为高效处理时间序列数据而生的大数据平台。
1. 写入数据TDengine 支持多种数据写入方式。首先,它完全兼容 SQL允许用户使用标准的 SQL 语法进行数据写入。而且 TDengine 还支持无模式Schemaless写入包括流行的 InfluxDB Line 协议、OpenTSDB 的 Telnet 和 JSON 协议这些协议的加入使得数据的导入变得更加灵活和高效。更进一步TDengine 与众多第三方工具实现了无缝集成,例如 Telegraf、Prometheus、EMQX、StatsD、collectd 和 HiveMQ 等。在 TDengine Enterprise 中, 还提供了 MQTT、OPC-UA、OPC-DA、PI、Wonderware、Kafka、InfluxDB、OpenTSDB、MySQL、Oracle 和 SQL Server 等连接器。这些工具通过简单的配置,无需一行代码,就可以将来自各种数据源的数据源源不断的写入数据库,极大地简化了数据收集和存储的过程。 1. 写入数据TDengine 支持多种数据写入方式。首先,它完全兼容 SQL允许用户使用标准的 SQL 语法进行数据写入。而且 TDengine 还支持无模式Schemaless写入包括流行的 InfluxDB Line 协议、OpenTSDB 的 Telnet 和 JSON 协议这些协议的加入使得数据的导入变得更加灵活和高效。更进一步TDengine 与众多第三方工具实现了无缝集成,例如 Telegraf、Prometheus、EMQX、StatsD、collectd 和 HiveMQ 等。在 TDengine Enterprise 中, 还提供了 MQTT、OPC-UA、OPC-DA、PI、Wonderware、Kafka、InfluxDB、OpenTSDB、MySQL、Oracle 和 SQL Server 等连接器。这些工具通过简单的配置,无需一行代码,就可以将来自各种数据源的数据源源不断的写入数据库,极大地简化了数据收集和存储的过程。

View File

@ -81,7 +81,7 @@ taosBenchmark 是一个专为测试 TDengine 性能而设计的工具,它能
taosBenchmark -y taosBenchmark -y
``` ```
系统将自动在数据库 test 下创建一张名为 meters的超级表。这张超级表将包含 10 000 张子表,表名从 d0 到 d9999每张表包含 10,000条记录。每条记录包含 ts时间戳、current电流、voltage电压和 phase相位4个字段。时间戳范围从“2017-07-14 10:40:00 000”到“2017-07-14 10:40:09 999”。每张表还带有 location 和 groupId 两个标签其中groupId 设置为 1 到 10而 location 则设置为 California.Campbell、California.Cupertino 等城市信息。 系统将自动在数据库 test 下创建一张名为 meters的超级表。这张超级表将包含 10,000 张子表,表名从 d0 到 d9999每张表包含 10,000条记录。每条记录包含 ts时间戳、current电流、voltage电压和 phase相位4个字段。时间戳范围从“2017-07-14 10:40:00 000” “2017-07-14 10:40:09 999”。每张表还带有 location 和 groupId 两个标签其中groupId 设置为 1 到 10而 location 则设置为 California.Campbell、California.Cupertino 等城市信息。
执行该命令后,系统将迅速完成 1 亿条记录的写入过程。实际所需时间取决于硬件性能,但即便在普通 PC 服务器上,这个过程通常也只需要十几秒。 执行该命令后,系统将迅速完成 1 亿条记录的写入过程。实际所需时间取决于硬件性能,但即便在普通 PC 服务器上,这个过程通常也只需要十几秒。

View File

@ -277,7 +277,7 @@ taosBenchmark 是一个专为测试 TDengine 性能而设计的工具,它能
taosBenchmark -y taosBenchmark -y
``` ```
系统将自动在数据库 test 下创建一张名为 meters的超级表。这张超级表将包含 10 000 张子表,表名从 d0 到 d9999每张表包含 10,000条记录。每条记录包含 ts时间戳、current电流、voltage电压和 phase相位4个字段。时间戳范围从“2017-07-14 10:40:00 000”到“2017-07-14 10:40:09 999”。每张表还带有 location 和 groupId 两个标签其中groupId 设置为 1 到 10而 location 则设置为 California.Campbell、California.Cupertino 等城市信息。 系统将自动在数据库 test 下创建一张名为 meters的超级表。这张超级表将包含 10,000 张子表,表名从 d0 到 d9999每张表包含 10,000条记录。每条记录包含 ts时间戳、current电流、voltage电压和 phase相位4个字段。时间戳范围从 “2017-07-14 10:40:00 000” “2017-07-14 10:40:09 999”。每张表还带有 location 和 groupId 两个标签其中groupId 设置为 1 到 10而 location 则设置为 California.Campbell、California.Cupertino 等城市信息。
执行该命令后,系统将迅速完成 1 亿条记录的写入过程。实际所需时间取决于硬件性能,但即便在普通 PC 服务器上,这个过程通常也只需要十几秒。 执行该命令后,系统将迅速完成 1 亿条记录的写入过程。实际所需时间取决于硬件性能,但即便在普通 PC 服务器上,这个过程通常也只需要十几秒。

View File

@ -41,7 +41,7 @@ LIMIT 5
TDengine 支持通过 GROUP BY 子句对数据进行聚合查询。SQL 语句包含 GROUP BY 子句时SELECT 列表只能包含如下表达式: TDengine 支持通过 GROUP BY 子句对数据进行聚合查询。SQL 语句包含 GROUP BY 子句时SELECT 列表只能包含如下表达式:
1. 常量 1. 常量
2. 聚函数 2. 聚函数
3. 与 GROUP BY 后表达式相同的表达式 3. 与 GROUP BY 后表达式相同的表达式
4. 包含前面表达式的表达式 4. 包含前面表达式的表达式
@ -158,7 +158,7 @@ window_clause: {
**注意** 在使用窗口子句时应注意以下规则: **注意** 在使用窗口子句时应注意以下规则:
1. 窗口子句位于数据切分子句之后,不可以和 GROUP BY 子句一起使用。 1. 窗口子句位于数据切分子句之后,不可以和 GROUP BY 子句一起使用。
2. 窗口子句将数据按窗口进行切分,对每个窗口进行 SELECT 列表中的表达式的计算SELECT 列表中的表达式只能包含常量伪列_wstart 伪列、_wend 伪列和 _wduration 伪列;聚函数(包括选择函数和可以由参数确定输出行数的时序特有函数) 2. 窗口子句将数据按窗口进行切分,对每个窗口进行 SELECT 列表中的表达式的计算SELECT 列表中的表达式只能包含常量伪列_wstart 伪列、_wend 伪列和 _wduration 伪列;聚函数(包括选择函数和可以由参数确定输出行数的时序特有函数)
3. WHERE 语句可以指定查询的起止时间和其他过滤条件。 3. WHERE 语句可以指定查询的起止时间和其他过滤条件。
### 时间戳伪列 ### 时间戳伪列

View File

@ -16,12 +16,12 @@ TDengine 采用了一种创新的时间驱动缓存管理策略,亦称为写
为了实现数据的分布式存储和高可用性TDengine 引入了虚拟节点vnode的概念。每个 vnode 可以拥有多达 3 个副本,这些副本共同组成一个 vnode group简称 vgroup。在创建数据库时用户需要确定每个 vnode 的写入缓存大小,以确保数据的合理分配和高效存储。 为了实现数据的分布式存储和高可用性TDengine 引入了虚拟节点vnode的概念。每个 vnode 可以拥有多达 3 个副本,这些副本共同组成一个 vnode group简称 vgroup。在创建数据库时用户需要确定每个 vnode 的写入缓存大小,以确保数据的合理分配和高效存储。
创建数据库时的两个关键参数—vgroups 和 buffer—分别决定了数据库中的数据由多少个 vgroup 进行处理,以及为每个 vnode 分配多少写入缓存。通过合理配置这两个 创建数据库时的两个关键参数 `vgroups``buffer` 分别决定了数据库中的数据由多少个 vgroup 进行处理,以及为每个 vnode 分配多少写入缓存。通过合理配置这两个
参数,用户可以根据实际需求调整数据库的性能和存储容量,从而实现最佳的性能和成本效益。 参数,用户可以根据实际需求调整数据库的性能和存储容量,从而实现最佳的性能和成本效益。
例 如, 下面的 SQL 创建了包含 10 个 vgroup每个 vnode 占 用 256MB 内存的数据库。 例 如, 下面的 SQL 创建了包含 10 个 vgroup每个 vnode 占 用 256MB 内存的数据库。
```ssql ```sql
create database power vgroups 10 buffer 256 cachemodel 'none' pages 128 pagesize 16 CREATE DATABASE POWER VGROUPS 10 BUFFER 256 CACHEMODEL 'NONE' PAGES 128 PAGESIZE 16;
``` ```
缓存越大越好,但超过一定阈值后再增加缓存对写入性能提升并无帮助。 缓存越大越好,但超过一定阈值后再增加缓存对写入性能提升并无帮助。
@ -43,7 +43,7 @@ create database power vgroups 10 buffer 256 cachemodel 'none' pages 128 pagesize
为了提升查询和写入操作的效率,每个 vnode 都配备了缓存机制,用于存储其曾经获取过的元数据。这一元数据缓存的大小由创建数据库时的两个参数 pages 和 pagesize 共同决定。其中pagesize 参数的单位是 KB用于指定每个缓存页的大小。如下 SQL 会为数据库 power 的每个 vnode 创建 128 个 page、每个 page 16KB 的元数据缓存 为了提升查询和写入操作的效率,每个 vnode 都配备了缓存机制,用于存储其曾经获取过的元数据。这一元数据缓存的大小由创建数据库时的两个参数 pages 和 pagesize 共同决定。其中pagesize 参数的单位是 KB用于指定每个缓存页的大小。如下 SQL 会为数据库 power 的每个 vnode 创建 128 个 page、每个 page 16KB 的元数据缓存
```sql ```sql
create database power pages 128 pagesize 16 CREATE DATABASE POWER PAGES 128 PAGESIZE 16;
``` ```
## 文件系统缓存 ## 文件系统缓存
@ -57,7 +57,7 @@ TDengine 利用这些日志文件实现故障前的状态恢复。在写入 WAL
- wal_fsync_period当 wal_level 设置为 2 时,这个参数控制执行 fsync 的频率。设置为 0 表示每次写入后立即执行 fsync这可以确保数据的安全性但可能会牺牲一些性能。当设置为大于 0 的数值时,表示 fsync 周期,默认为 3000范围是[1 180000],单位毫秒。 - wal_fsync_period当 wal_level 设置为 2 时,这个参数控制执行 fsync 的频率。设置为 0 表示每次写入后立即执行 fsync这可以确保数据的安全性但可能会牺牲一些性能。当设置为大于 0 的数值时,表示 fsync 周期,默认为 3000范围是[1 180000],单位毫秒。
```sql ```sql
create database power wal_level 1 wal_fsync_period 3000 CREATE DATABASE POWER WAL_LEVEL 1 WAL_FSYNC_PERIOD 3000;
``` ```
在创建数据库时可以选择不同的参数类型,来选择性能优先或者可靠性优先。 在创建数据库时可以选择不同的参数类型,来选择性能优先或者可靠性优先。

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

@ -63,7 +63,7 @@ M = (T × S × 3 + (N / 4096) + 100)
TDengine 用户对 CPU 的需求主要受以下 3 个因素影响: TDengine 用户对 CPU 的需求主要受以下 3 个因素影响:
- 数据分片:在 TDengine 中,每个 CPU 核心可以服务 1 至 2 个 vnode。假设一个集群配置了 100 个 vgroup并且采用三副本策略那么建议该集群的 CPU 核心数量为 150~300 个,以实现最佳性能。 - 数据分片:在 TDengine 中,每个 CPU 核心可以服务 1 至 2 个 vnode。假设一个集群配置了 100 个 vgroup并且采用三副本策略那么建议该集群的 CPU 核心数量为 150~300 个,以实现最佳性能。
- 数据写入TDengine 的单核每秒至少能处理 10 000 个写入请求。值得注意的是,每个写入请求可以包含多条记录,而且一次写入一条记录与同时写入 10 条记录相比,消耗的计算资源相差无几。因此,每次写入的记录数越多,写入效率越高。例如,如果一个写入请求包含 200 条以上记录,单核就能实现每秒写入 100 万条记录的速度。然而,这要求前端数据采集系统具备更高的能力,因为它需要缓存记录,然后批量写入。 - 数据写入TDengine 的单核每秒至少能处理 10,000 个写入请求。值得注意的是,每个写入请求可以包含多条记录,而且一次写入一条记录与同时写入 10 条记录相比,消耗的计算资源相差无几。因此,每次写入的记录数越多,写入效率越高。例如,如果一个写入请求包含 200 条以上记录,单核就能实现每秒写入 100 万条记录的速度。然而,这要求前端数据采集系统具备更高的能力,因为它需要缓存记录,然后批量写入。
- 查询需求:虽然 TDengine 提供了高效的查询功能,但由于每个应用场景的查询差异较大,且查询频次也会发生变化,因此很难给出一个具体的数字来衡量查询所需的计算资源。用户需要根据自己的实际场景编写一些查询语句,以便更准确地确定所需的计算资源。 - 查询需求:虽然 TDengine 提供了高效的查询功能,但由于每个应用场景的查询差异较大,且查询频次也会发生变化,因此很难给出一个具体的数字来衡量查询所需的计算资源。用户需要根据自己的实际场景编写一些查询语句,以便更准确地确定所需的计算资源。
综上所述对于数据分片和数据写入CPU 的需求是可以预估的。然而,查询需求所消耗的计算资源则难以预测。在实际运行过程中,建议保持 CPU 使用率不超过 50%,以确保系统的稳定性和性能。一旦 CPU 使用率超过这一阈值,就需要考虑增加新的节点或增加 CPU 核心数量,以提供更多的计算资源。 综上所述对于数据分片和数据写入CPU 的需求是可以预估的。然而,查询需求所消耗的计算资源则难以预测。在实际运行过程中,建议保持 CPU 使用率不超过 50%,以确保系统的稳定性和性能。一旦 CPU 使用率超过这一阈值,就需要考虑增加新的节点或增加 CPU 核心数量,以提供更多的计算资源。
@ -152,5 +152,5 @@ TDengine 的多级存储功能在使用上还具备以下优点。
|RESTful 接口 | 6041 | |RESTful 接口 | 6041 |
|WebSocket 接口 |6041 | |WebSocket 接口 |6041 |
|taosKeeper | 6043 | |taosKeeper | 6043 |
|taosX | 6055 | |taosX | 6050, 6055 |
|taosExplorer | 6060 | |taosExplorer | 6060 |

File diff suppressed because it is too large Load Diff

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)
#### 限制 #### 限制

View File

@ -11,7 +11,7 @@ toc_max_heading_level: 4
TDengine 支持 WAL 机制实现数据的容错能力保证数据的高可靠。TDengine 接收到应用程序的请求数据包时,会先将请求的原始数据包写入数据库日志文件,等数据成功写入数据库数据文件后,再删除相应的 WAL。这样保证了 TDengine 能够在断电等因素导致的服务重启时,从数据库日志文件中恢复数据,避免数据丢失。涉及的配置参数有如下两个: TDengine 支持 WAL 机制实现数据的容错能力保证数据的高可靠。TDengine 接收到应用程序的请求数据包时,会先将请求的原始数据包写入数据库日志文件,等数据成功写入数据库数据文件后,再删除相应的 WAL。这样保证了 TDengine 能够在断电等因素导致的服务重启时,从数据库日志文件中恢复数据,避免数据丢失。涉及的配置参数有如下两个:
- wal_level WAL 级别1 表示写 WAL但不执行 fsync 2 表示写 WAL而且执行 fsync。默认值为 1。 - wal_level WAL 级别1 表示写 WAL但不执行 fsync 2 表示写 WAL而且执行 fsync。默认值为 1。
- wal_fsync_period当 wal_level 设置为 2 时,执行 fsync 的周期;当 wal-level 设置为 0 时,表示每次写入,立即执行 fsync。 - wal_fsync_period当 wal_level 设置为 2 时,执行 fsync 的周期;当 wal_fsync_period 设置为 0 时,表示每次写入,立即执行 fsync。
如果要 100% 保证数据不丢失,则需要将 wal_level 设置为 2wal_fsync_period 设置为 0。这时写入速度将会下降。但如果应用程序侧启动的写数据的线程数达到一定的数量超过 50那么写入数据的性能也会很不错只会比 wal_fsync_period 设置为 3000ms 下降 30% 左右。 如果要 100% 保证数据不丢失,则需要将 wal_level 设置为 2wal_fsync_period 设置为 0。这时写入速度将会下降。但如果应用程序侧启动的写数据的线程数达到一定的数量超过 50那么写入数据的性能也会很不错只会比 wal_fsync_period 设置为 3000ms 下降 30% 左右。

View File

@ -76,7 +76,7 @@ drop user user_name
在 TDengine 中,库和表的权限分为 read (读)和 write (写)两种。这些权限可以单独授予,也可以同时授予用户。 在 TDengine 中,库和表的权限分为 read (读)和 write (写)两种。这些权限可以单独授予,也可以同时授予用户。
- read 权限:拥有 read 权限的用户仅能查询库或表中的数据,而无法对数据进行修改或删除。这种权限适用于需要访问数据但不需要对数据进行写入操作的场景,如数据分析师、报表生成器等。 - read 权限:拥有 read 权限的用户仅能查询库或表中的数据,而无法对数据进行修改或删除。这种权限适用于需要访问数据但不需要对数据进行写入操作的场景,如数据分析师、报表生成器等。
- write 权限:拥有 write 权限的用户既可以查询库或表中的数据,也可以向库或表中写入数据。这种权限适用于需要对数据进行写入操作的场景,如数据采集器、数据处理器等。 - write 权限:拥有 write 权限的用户可以向库或表中写入数据。这种权限适用于需要对数据进行写入操作的场景,如数据采集器、数据处理器等。如果只拥有 write 权限而没有 read 权限,则只能写入数据但不能查询数据。
对某个用户进行库和表访问授权的语法如下。 对某个用户进行库和表访问授权的语法如下。

View File

@ -18,13 +18,13 @@ alter user test add host host_name1
查询 IP 白名单的 SQL 如下。 查询 IP 白名单的 SQL 如下。
```sql ```sql
select test, allowed_host from ins_user_privileges; SELECT TEST, ALLOWED_HOST FROM INS_USERS;
show users; SHOW USERS;
``` ```
删除 IP 白名单的命令如下。 删除 IP 白名单的命令如下。
```sql ```sql
alter user test drop host host_name1 ALTER USER TEST DROP HOST HOST_NAME1
``` ```
## 审计日志 ## 审计日志

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

View File

@ -6,7 +6,7 @@ toc_max_heading_level: 4
## UDF 简介 ## UDF 简介
在某些应用场景中,应用逻辑需要的查询功能无法直接使用 TDengine 内置的函数来实现。TDengine 允许编写用户自定义函数UDF以便解决特殊应用场景中的使用需求。UDF 在集群中注册成功后,可以像系统内置函数一样在 SQ L中调用就使用角度而言没有任何区别。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 的正常运行。
@ -15,20 +15,19 @@ TDengine 支持用 C 和 Python 两种编程语言编写 UDF。C 语言编写的
使用 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`)的连接。
### 接口定义 ### 接口定义
在 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输入的数据块。
@ -47,9 +46,9 @@ int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn)
聚合函数的接口函数原型如下。 聚合函数的接口函数原型如下。
```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 条结果数据。
@ -79,15 +78,16 @@ int32_t udf_destroy()
#include "taoserror.h" #include "taoserror.h"
#include "taosudf.h" #include "taosudf.h"
// Initialization function. If no initialization, we can skip definition of it. // Initialization function.
// The initialization function shall be concatenation of the udf name and _init suffix // 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 // @return error number defined in taoserror.h
int32_t scalarfn_init() { int32_t scalarfn_init() {
// initialization. // initialization.
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Scalar function main computation function // Scalar function main computation function.
// @param inputDataBlock, input data block composed of multiple columns with each column defined by SUdfColumn // @param inputDataBlock, input data block composed of multiple columns with each column defined by SUdfColumn
// @param resultColumn, output column // @param resultColumn, output column
// @return error number defined in taoserror.h // @return error number defined in taoserror.h
@ -96,7 +96,8 @@ int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn* resultColumn) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Cleanup function. If no cleanup related processing, we can skip definition of it. // 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. // The destroy function shall be concatenation of the udf name and _destroy suffix.
// @return error number defined in taoserror.h // @return error number defined in taoserror.h
int32_t scalarfn_destroy() { int32_t scalarfn_destroy() {
@ -112,16 +113,18 @@ int32_t scalarfn_destroy() {
#include "taoserror.h" #include "taoserror.h"
#include "taosudf.h" #include "taosudf.h"
// Initialization function. If no initialization, we can skip definition of it. // Initialization function.
// The initialization function shall be concatenation of the udf name and _init suffix // 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 // @return error number defined in taoserror.h
int32_t aggfn_init() { int32_t aggfn_init() {
// initialization. // initialization.
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Aggregate start function. The intermediate value or the state(@interBuf) is initialized in this function. // Aggregate start function.
// The function name shall be concatenation of udf name and _start suffix // 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 // @param interbuf intermediate value to initialize
// @return error number defined in taoserror.h // @return error number defined in taoserror.h
int32_t aggfn_start(SUdfInterBuf* interBuf) { int32_t aggfn_start(SUdfInterBuf* interBuf) {
@ -129,7 +132,8 @@ int32_t aggfn_start(SUdfInterBuf* 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). // 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 inputBlock input data block
// @param interBuf old state // @param interBuf old state
// @param newInterBuf new state // @param newInterBuf new state
@ -139,7 +143,8 @@ int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *n
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Aggregate function finish function. This function transforms the intermediate value(@interBuf) into the final output(@result). // 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. // The function name must be concatenation of aggfn and _finish suffix.
// @interBuf : intermediate value // @interBuf : intermediate value
// @result: final result // @result: final result
@ -149,7 +154,8 @@ int32_t int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// Cleanup function. If no cleanup related processing, we can skip definition of it. // 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. // The destroy function shall be concatenation of the udf name and _destroy suffix.
// @return error number defined in taoserror.h // @return error number defined in taoserror.h
int32_t aggfn_destroy() { int32_t aggfn_destroy() {
@ -432,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)
``` ```

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,54 +141,54 @@ 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 模块的日志开关,取值范围同上 |
### 压缩参数 ### 压缩参数
@ -197,7 +197,7 @@ charset 的有效值是 UTF-8。
| 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表示关闭无损压缩。**注意:此参数在 3.3.0.0 及更高版本中不再使用** |
|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

@ -245,12 +245,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

@ -131,6 +131,14 @@ static FORCE_INLINE char *udfColDataGetData(const SUdfColumn *pColumn, int32_t r
} }
} }
static FORCE_INLINE int32_t udfColDataGetDataLen(const SUdfColumn *pColumn, int32_t row) {
if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) {
return *(uint16_t*)(pColumn->colData.varLenCol.payload + pColumn->colData.varLenCol.varOffsets[row]);
} else {
return pColumn->colMeta.bytes;
}
}
static FORCE_INLINE bool udfColDataIsNull(const SUdfColumn *pColumn, int32_t row) { static FORCE_INLINE bool udfColDataIsNull(const SUdfColumn *pColumn, int32_t row) {
if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) { if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) {
if (pColumn->colMeta.type == TSDB_DATA_TYPE_JSON) { if (pColumn->colMeta.type == TSDB_DATA_TYPE_JSON) {
@ -320,6 +328,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;
@ -531,7 +531,7 @@ int32_t createRequest(uint64_t connId, int32_t type, int64_t reqid, SRequestObj
STscObj *pTscObj = acquireTscObj(connId); STscObj *pTscObj = acquireTscObj(connId);
if (pTscObj == NULL) { if (pTscObj == NULL) {
TSC_ERR_JRET(terrno); TSC_ERR_JRET(TSDB_CODE_TSC_DISCONNECTED);
} }
SSyncQueryParam *interParam = taosMemoryCalloc(1, sizeof(SSyncQueryParam)); SSyncQueryParam *interParam = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
if (interParam == NULL) { if (interParam == NULL) {
@ -871,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

@ -142,7 +142,7 @@ static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) {
mndConsumerStatusName(pConsumer->status)); mndConsumerStatusName(pConsumer->status));
MND_TMQ_RETURN_CHECK(tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup, -1, NULL, NULL, &pConsumerNew)); MND_TMQ_RETURN_CHECK(tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup, -1, NULL, NULL, &pConsumerNew));
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "clear-csm"); pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pMsg, "clear-csm");
MND_TMQ_NULL_CHECK(pTrans); MND_TMQ_NULL_CHECK(pTrans);
MND_TMQ_RETURN_CHECK(mndSetConsumerDropLogs(pTrans, pConsumerNew)); MND_TMQ_RETURN_CHECK(mndSetConsumerDropLogs(pTrans, pConsumerNew));
code = mndTransPrepare(pMnode, pTrans); code = mndTransPrepare(pMnode, pTrans);

View File

@ -643,7 +643,7 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
char cgroup[TSDB_CGROUP_LEN] = {0}; char cgroup[TSDB_CGROUP_LEN] = {0};
mndSplitSubscribeKey(pOutput->pSub->key, topic, cgroup, true); mndSplitSubscribeKey(pOutput->pSub->key, topic, cgroup, true);
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pMsg, "tmq-reb"); pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pMsg, "tmq-reb");
if (pTrans == NULL) { if (pTrans == NULL) {
code = TSDB_CODE_MND_RETURN_VALUE_NULL; code = TSDB_CODE_MND_RETURN_VALUE_NULL;
if (terrno != 0) code = terrno; if (terrno != 0) code = terrno;
@ -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,11 +1075,11 @@ 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;
} }
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB, pMsg, "drop-cgroup"); pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pMsg, "drop-cgroup");
MND_TMQ_NULL_CHECK(pTrans); MND_TMQ_NULL_CHECK(pTrans);
mInfo("trans:%d, used to drop cgroup:%s on topic %s", pTrans->id, dropReq.cgroup, dropReq.topic); mInfo("trans:%d, used to drop cgroup:%s on topic %s", pTrans->id, dropReq.cgroup, dropReq.topic);
mndTransSetDbName(pTrans, pSub->dbName, NULL); mndTransSetDbName(pTrans, pSub->dbName, NULL);

View File

@ -431,7 +431,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
SQueryPlan *pPlan = NULL; SQueryPlan *pPlan = NULL;
SMqTopicObj topicObj = {0}; SMqTopicObj topicObj = {0};
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB, pReq, "create-topic"); pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "create-topic");
MND_TMQ_NULL_CHECK(pTrans); MND_TMQ_NULL_CHECK(pTrans);
mndTransSetDbName(pTrans, pDb->name, NULL); mndTransSetDbName(pTrans, pDb->name, NULL);
MND_TMQ_RETURN_CHECK(mndTransCheckConflict(pMnode, pTrans)); MND_TMQ_RETURN_CHECK(mndTransCheckConflict(pMnode, pTrans));
@ -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

@ -3519,8 +3519,10 @@ static int32_t initForFirstBlockInFile(STsdbReader* pReader, SDataBlockIter* pBl
resetTableListIndex(&pReader->status); resetTableListIndex(&pReader->status);
} }
// set the correct start position according to the query time window if (code == TSDB_CODE_SUCCESS) {
initBlockDumpInfo(pReader, pBlockIter); // set the correct start position according to the query time window
initBlockDumpInfo(pReader, pBlockIter);
}
taosArrayDestroy(pTableList); taosArrayDestroy(pTableList);
return code; return code;
} }

View File

@ -1074,8 +1074,12 @@ int32_t doAdjustValidDataIters(SArray* pLDIterList, int32_t numOfFileObj) {
int32_t inc = numOfFileObj - size; int32_t inc = numOfFileObj - size;
for (int32_t k = 0; k < inc; ++k) { for (int32_t k = 0; k < inc; ++k) {
SLDataIter* pIter = taosMemoryCalloc(1, sizeof(SLDataIter)); SLDataIter* pIter = taosMemoryCalloc(1, sizeof(SLDataIter));
void* px = taosArrayPush(pLDIterList, &pIter); if (!pIter) {
return terrno;
}
void* px = taosArrayPush(pLDIterList, &pIter);
if (px == NULL) { if (px == NULL) {
taosMemoryFree(pIter);
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
} }

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

@ -343,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;
} }
@ -366,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;
@ -414,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

@ -245,8 +245,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));
} }
pInfo->pTableList = NULL; if (pInfo != NULL) {
destroyCacheScanOperator(pInfo); pInfo->pTableList = NULL;
destroyCacheScanOperator(pInfo);
}
if (pOperator != NULL) { if (pOperator != NULL) {
pOperator->info = NULL; pOperator->info = NULL;
destroyOperator(pOperator); destroyOperator(pOperator);

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;

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;

View File

@ -735,6 +735,7 @@ int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pCo
pStart += sizeof(SSysTableSchema); pStart += sizeof(SSysTableSchema);
} }
pBlock = NULL;
code = createDataBlock(&pBlock); code = createDataBlock(&pBlock);
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);

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

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

View File

@ -1568,6 +1568,8 @@ void resetTableScanInfo(STableScanInfo* pTableScanInfo, STimeWindow* pWin, uint6
static SSDataBlock* readPreVersionData(SOperatorInfo* pTableScanOp, uint64_t tbUid, TSKEY startTs, TSKEY endTs, static SSDataBlock* readPreVersionData(SOperatorInfo* pTableScanOp, uint64_t tbUid, TSKEY startTs, TSKEY endTs,
int64_t maxVersion) { int64_t maxVersion) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
STableKeyInfo tblInfo = {.uid = tbUid, .groupId = 0}; STableKeyInfo tblInfo = {.uid = tbUid, .groupId = 0};
STableScanInfo* pTableScanInfo = pTableScanOp->info; STableScanInfo* pTableScanInfo = pTableScanOp->info;
@ -1582,37 +1584,33 @@ static SSDataBlock* readPreVersionData(SOperatorInfo* pTableScanOp, uint64_t tbU
SSDataBlock* pBlock = pTableScanInfo->pResBlock; SSDataBlock* pBlock = pTableScanInfo->pResBlock;
STsdbReader* pReader = NULL; STsdbReader* pReader = NULL;
int32_t code = pAPI->tsdReader.tsdReaderOpen(pTableScanInfo->base.readHandle.vnode, &cond, &tblInfo, 1, pBlock, code = pAPI->tsdReader.tsdReaderOpen(pTableScanInfo->base.readHandle.vnode, &cond, &tblInfo, 1, pBlock,
(void**)&pReader, GET_TASKID(pTaskInfo), NULL); (void**)&pReader, GET_TASKID(pTaskInfo), NULL);
if (code != TSDB_CODE_SUCCESS) { QUERY_CHECK_CODE(code, lino, _end);
terrno = code;
T_LONG_JMP(pTaskInfo->env, code);
return NULL;
}
bool hasNext = false; bool hasNext = false;
code = pAPI->tsdReader.tsdNextDataBlock(pReader, &hasNext); code = pAPI->tsdReader.tsdNextDataBlock(pReader, &hasNext);
if (code != TSDB_CODE_SUCCESS) { QUERY_CHECK_CODE(code, lino, _end);
terrno = code;
T_LONG_JMP(pTaskInfo->env, code);
return NULL;
}
if (hasNext) { if (hasNext) {
SSDataBlock* p = NULL; SSDataBlock* p = NULL;
code = pAPI->tsdReader.tsdReaderRetrieveDataBlock(pReader, &p, NULL); code = pAPI->tsdReader.tsdReaderRetrieveDataBlock(pReader, &p, NULL);
if (code != TSDB_CODE_SUCCESS) { QUERY_CHECK_CODE(code, lino, _end);
return NULL;
}
doSetTagColumnData(&pTableScanInfo->base, pBlock, pTaskInfo, pBlock->info.rows); doSetTagColumnData(&pTableScanInfo->base, pBlock, pTaskInfo, pBlock->info.rows);
pBlock->info.id.groupId = tableListGetTableGroupId(pTableScanInfo->base.pTableListInfo, pBlock->info.id.uid); pBlock->info.id.groupId = tableListGetTableGroupId(pTableScanInfo->base.pTableListInfo, pBlock->info.id.uid);
} }
_end:
pAPI->tsdReader.tsdReaderClose(pReader); pAPI->tsdReader.tsdReaderClose(pReader);
qDebug("retrieve prev rows:%" PRId64 ", skey:%" PRId64 ", ekey:%" PRId64 " uid:%" PRIu64 ", max ver:%" PRId64 qDebug("retrieve prev rows:%" PRId64 ", skey:%" PRId64 ", ekey:%" PRId64 " uid:%" PRIu64 ", max ver:%" PRId64
", suid:%" PRIu64, ", suid:%" PRIu64,
pBlock->info.rows, startTs, endTs, tbUid, maxVersion, cond.suid); pBlock->info.rows, startTs, endTs, tbUid, maxVersion, cond.suid);
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
terrno = code;
return NULL;
}
return pBlock->info.rows > 0 ? pBlock : NULL; return pBlock->info.rows > 0 ? pBlock : NULL;
} }
@ -2259,6 +2257,10 @@ static int32_t generatePartitionDelResBlock(SStreamScanInfo* pInfo, SSDataBlock*
uint64_t srcUid = srcUidData[delI]; uint64_t srcUid = srcUidData[delI];
char tbname[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN] = {0}; char tbname[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN] = {0};
SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, srcUid, srcStartTsCol[delI], srcEndTsCol[delI], ver); SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, srcUid, srcStartTsCol[delI], srcEndTsCol[delI], ver);
if (!pPreRes) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
continue;
}
code = blockDataEnsureCapacity(pDestBlock, pDestBlock->info.rows + pPreRes->info.rows); code = blockDataEnsureCapacity(pDestBlock, pDestBlock->info.rows + pPreRes->info.rows);
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
for (int32_t preJ = 0; preJ < pPreRes->info.rows; preJ++) { for (int32_t preJ = 0; preJ < pPreRes->info.rows; preJ++) {
@ -2331,6 +2333,10 @@ static int32_t generateDeleteResultBlockImpl(SStreamScanInfo* pInfo, SSDataBlock
if (winCode != TSDB_CODE_SUCCESS) { if (winCode != TSDB_CODE_SUCCESS) {
SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, srcUid, srcStartTsCol[i], srcStartTsCol[i], ver); SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, srcUid, srcStartTsCol[i], srcStartTsCol[i], ver);
if (!pPreRes) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
continue;
}
printDataBlock(pPreRes, "pre res", GET_TASKID(pInfo->pStreamScanOp->pTaskInfo)); printDataBlock(pPreRes, "pre res", GET_TASKID(pInfo->pStreamScanOp->pTaskInfo));
code = calBlockTbName(pInfo, pPreRes, 0); code = calBlockTbName(pInfo, pPreRes, 0);
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
@ -4319,11 +4325,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);
@ -5836,7 +5843,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) {
@ -5849,16 +5857,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;
@ -5873,10 +5875,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;
@ -5893,9 +5892,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);
@ -5957,9 +5954,14 @@ 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; if (pInfo != NULL) {
if (pInfo != NULL) destroyTableMergeScanOperatorInfo(pInfo); pInfo->base.pTableListInfo = NULL;
destroyTableMergeScanOperatorInfo(pInfo);
}
if (pOperator != NULL) { if (pOperator != NULL) {
pOperator->info = NULL; pOperator->info = NULL;
destroyOperator(pOperator); destroyOperator(pOperator);

View File

@ -5203,6 +5203,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,
@ -5230,7 +5232,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);

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) {
@ -780,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) {
@ -1201,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;
@ -1374,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);
@ -1578,10 +1579,11 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
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);
@ -2034,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);
@ -2151,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;
@ -2161,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;
} }
@ -2453,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;
} }
@ -2694,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);
@ -2716,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);
} }
@ -2778,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) {

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]);
} }
@ -5003,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

@ -1152,6 +1152,20 @@ void streamMetaNotifyClose(SStreamMeta* pMeta) {
taosMsleep(100); taosMsleep(100);
} }
streamMetaRLock(pMeta);
SArray* pTaskList = NULL;
int32_t code = streamMetaSendMsgBeforeCloseTasks(pMeta, &pTaskList);
if (code != TSDB_CODE_SUCCESS) {
// return code;
}
streamMetaRUnLock(pMeta);
if (pTaskList != NULL) {
taosArrayDestroy(pTaskList);
}
int64_t el = taosGetTimestampMs() - st; int64_t el = taosGetTimestampMs() - st;
stDebug("vgId:%d all stream tasks are not in timer, continue close, elapsed time:%" PRId64 " ms", pMeta->vgId, el); stDebug("vgId:%d all stream tasks are not in timer, continue close, elapsed time:%" PRId64 " ms", pMeta->vgId, el);
} }

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

@ -1620,15 +1620,18 @@ static void cliHandleFreeById(SCliMsg* pMsg, SCliThrd* pThrd) {
if (size == 0) { if (size == 0) {
// already recv, and notify upper layer // already recv, and notify upper layer
TAOS_CHECK_GOTO(TSDB_CODE_REF_INVALID_ID, NULL, _exception); TAOS_CHECK_GOTO(TSDB_CODE_REF_INVALID_ID, NULL, _exception);
return;
} else { } else {
while (T_REF_VAL_GET(conn) >= 1) transUnrefCliHandle(conn); while (T_REF_VAL_GET(conn) >= 1) {
transUnrefCliHandle(conn);
}
return;
} }
return;
_exception: _exception:
tDebug("already free conn %p by id %" PRId64"", conn, refId); tDebug("already free conn %p by id %" PRId64"", conn, refId);
(void)transReleaseExHandle(transGetRefMgt(), refId); (void)transReleaseExHandle(transGetRefMgt(), refId);
(void)transReleaseExHandle(transGetRefMgt(), refId);
(void)transRemoveExHandle(transGetRefMgt(), refId);
destroyCmsg(pMsg); destroyCmsg(pMsg);
} }
@ -2225,6 +2228,11 @@ static FORCE_INLINE void destroyCmsgAndAhandle(void* param) {
pThrd->destroyAhandleFp(pMsg->ctx->ahandle); pThrd->destroyAhandleFp(pMsg->ctx->ahandle);
} }
if (pMsg->msg.info.handle !=0) {
(void)transReleaseExHandle(transGetRefMgt(), (int64_t)pMsg->msg.info.handle);
(void)transRemoveExHandle(transGetRefMgt(), (int64_t)pMsg->msg.info.handle);
}
transDestroyConnCtx(pMsg->ctx); transDestroyConnCtx(pMsg->ctx);
transFreeMsg(pMsg->msg.pCont); transFreeMsg(pMsg->msg.pCont);
taosMemoryFree(pMsg); taosMemoryFree(pMsg);

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

@ -871,14 +871,14 @@ void taosGetSystemTimezone(char *outTimezoneStr, enum TdTimezone *tsTimezone) {
{ {
int n = readlink("/etc/localtime", buf, sizeof(buf)); int n = readlink("/etc/localtime", buf, sizeof(buf));
if (n < 0) { if (n < 0) {
printf("read /etc/localtime error, reason:%s", strerror(errno)); printf("read /etc/localtime error, reason:%s\n", strerror(errno));
return; return;
} }
buf[n] = '\0'; buf[n] = '\0';
char *zi = strstr(buf, "zoneinfo"); char *zi = strstr(buf, "zoneinfo");
if (!zi) { if (!zi) {
printf("parsing /etc/localtime failed"); printf("parsing /etc/localtime failed\n");
return; return;
} }
tz = zi + strlen("zoneinfo") + 1; tz = zi + strlen("zoneinfo") + 1;
@ -893,7 +893,7 @@ void taosGetSystemTimezone(char *outTimezoneStr, enum TdTimezone *tsTimezone) {
// } // }
// } // }
// if (!tz || 0 == strchr(tz, '/')) { // if (!tz || 0 == strchr(tz, '/')) {
// printf("parsing /etc/localtime failed"); // printf("parsing /etc/localtime failed\n");
// return; // return;
// } // }
@ -927,7 +927,7 @@ void taosGetSystemTimezone(char *outTimezoneStr, enum TdTimezone *tsTimezone) {
{ {
int n = readlink("/etc/localtime", buf, sizeof(buf)-1); int n = readlink("/etc/localtime", buf, sizeof(buf)-1);
if (n < 0) { if (n < 0) {
(void)printf("read /etc/localtime error, reason:%s", strerror(errno)); (void)printf("read /etc/localtime error, reason:%s\n", strerror(errno));
if (taosCheckExistFile("/etc/timezone")) { if (taosCheckExistFile("/etc/timezone")) {
/* /*
@ -947,7 +947,7 @@ void taosGetSystemTimezone(char *outTimezoneStr, enum TdTimezone *tsTimezone) {
int len = taosReadFile(pFile, buf, 64); int len = taosReadFile(pFile, buf, 64);
if (len < 0) { if (len < 0) {
(void)taosCloseFile(&pFile); (void)taosCloseFile(&pFile);
(void)printf("read /etc/timezone error, reason:%s", strerror(errno)); (void)printf("read /etc/timezone error, reason:%s\n", strerror(errno));
return; return;
} }
@ -994,7 +994,7 @@ void taosGetSystemTimezone(char *outTimezoneStr, enum TdTimezone *tsTimezone) {
char *zi = strstr(buf, "zoneinfo"); char *zi = strstr(buf, "zoneinfo");
if (!zi) { if (!zi) {
(void)printf("parsing /etc/localtime failed"); (void)printf("parsing /etc/localtime failed\n");
return; return;
} }
tz = zi + strlen("zoneinfo") + 1; tz = zi + strlen("zoneinfo") + 1;

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

@ -113,6 +113,34 @@ class TDTestCase(TBase):
tdSql.checkData(0, 0, f"nihao{num + 2}") tdSql.checkData(0, 0, f"nihao{num + 2}")
tdSql.checkData(0, 1, f"{11*i}") tdSql.checkData(0, 1, f"{11*i}")
def FIX_TS_5239(self):
tdLog.info("check bug TS_5239 ...\n")
sqls = [
"drop database if exists ts_5239",
"create database ts_5239 cachemodel 'both' stt_trigger 1;",
"use ts_5239;",
"CREATE STABLE st (ts timestamp, c1 int) TAGS (groupId int);",
"CREATE TABLE ct1 USING st TAGS (1);"
]
tdSql.executes(sqls)
# 2024-07-03 06:00:00.000
start_ts = 1719957600000
# insert 100 rows
sql = "insert into ct1 values "
for i in range(100):
sql += f"('{start_ts+i * 100}', {i+1})"
sql += ";"
tdSql.execute(sql)
tdSql.execute("flush database ts_5239;")
tdSql.execute("alter database ts_5239 stt_trigger 3;")
tdSql.execute(f"insert into ct1(ts) values({start_ts - 100 * 100})")
tdSql.execute("flush database ts_5239;")
tdSql.execute(f"insert into ct1(ts) values({start_ts + 100 * 200})")
tdSql.execute("flush database ts_5239;")
tdSql.query("select count(*) from ct1;")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 102)
# run # run
def run(self): def run(self):
tdLog.debug(f"start to excute {__file__}") tdLog.debug(f"start to excute {__file__}")
@ -123,6 +151,7 @@ class TDTestCase(TBase):
# TS BUGS # TS BUGS
self.FIX_TS_5105() self.FIX_TS_5105()
self.FIX_TS_5143() self.FIX_TS_5143()
self.FIX_TS_5239()
tdLog.success(f"{__file__} successfully executed") tdLog.success(f"{__file__} successfully executed")

98
tests/army/tmq/tmqBugs.py Normal file
View File

@ -0,0 +1,98 @@
import taos
import sys
import time
import socket
import os
import threading
from frame.log import *
from frame.cases import *
from frame.sql import *
from frame.caseBase import *
from frame import *
from taos.tmq import *
import frame.etool
class TDTestCase:
updatecfgDict = {'debugFlag': 135, 'asynclog': 0}
def init(self, conn, logSql, replicaVar=1):
self.replicaVar = int(replicaVar)
tdLog.debug(f"start to excute {__file__}")
tdSql.init(conn.cursor())
#tdSql.init(conn.cursor(), logSql) # output sql.txt file
def td_31283_test(self):
tdSql.execute(f'create database if not exists d1 vgroups 1')
tdSql.execute(f'use d1')
tdSql.execute(f'create table st(ts timestamp, i int) tags(t int)')
tdSql.execute(f'insert into t1 using st tags(1) values(now, 1) (now+1s, 2)')
tdSql.execute(f'insert into t2 using st tags(2) values(now, 1) (now+1s, 2)')
tdSql.execute(f'insert into t3 using st tags(3) values(now, 1) (now+1s, 2)')
tdSql.execute(f'insert into t1 using st tags(1) values(now+5s, 11) (now+10s, 12)')
tdSql.query("select * from st")
tdSql.checkRows(8)
tdSql.error(f'create topic t1 with meta as database d2', expectErrInfo="Database not exist")
tdSql.error(f'create topic t1 as database d2', expectErrInfo="Database not exist")
tdSql.error(f'create topic t2 as select * from st2', expectErrInfo="Fail to get table info, error: Table does not exist")
tdSql.error(f'create topic t3 as stable st2', expectErrInfo="STable not exist")
tdSql.error(f'create topic t3 with meta as stable st2', expectErrInfo="STable not exist")
tdSql.execute(f'create topic t1 with meta as database d1')
consumer_dict = {
"group.id": "g1",
"td.connect.user": "root",
"td.connect.pass": "taosdata",
"auto.offset.reset": "earliest",
# "msg.enable.batchmeta": "true",
"experimental.snapshot.enable": "true",
}
consumer1 = Consumer(consumer_dict)
try:
consumer1.subscribe(["t1"])
except TmqError:
tdLog.exit(f"subscribe error")
index = 0
try:
while True:
res = consumer1.poll(1)
if not res:
if index != 1:
tdLog.exit("consume error")
break
val = res.value()
if val is None:
continue
cnt = 0;
for block in val:
cnt += len(block.fetchall())
if cnt != 8:
tdLog.exit("consume error")
index += 1
finally:
consumer1.close()
tdSql.query(f'show consumers')
tdSql.checkRows(0)
tdSql.execute(f'drop topic t1')
tdSql.execute(f'drop database d1')
def run(self):
self.td_31283_test()
def stop(self):
tdSql.close()
tdLog.success(f"{__file__} successfully executed")
tdCases.addLinux(__file__, TDTestCase())
tdCases.addWindows(__file__, TDTestCase())

View File

@ -35,6 +35,7 @@
,,y,army,./pytest.sh python3 ./test.py -f storage/compressBasic.py -N 3 ,,y,army,./pytest.sh python3 ./test.py -f storage/compressBasic.py -N 3
,,y,army,./pytest.sh python3 ./test.py -f grant/grantBugs.py -N 3 ,,y,army,./pytest.sh python3 ./test.py -f grant/grantBugs.py -N 3
,,y,army,./pytest.sh python3 ./test.py -f query/queryBugs.py -N 3 ,,y,army,./pytest.sh python3 ./test.py -f query/queryBugs.py -N 3
,,y,army,./pytest.sh python3 ./test.py -f tmq/tmqBugs.py -N 3
# #
# system test # system test

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;
} }
} }
@ -24,24 +28,34 @@ 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)) {
udfColDataSetNull(resultCol, i); udfColDataSetNull(resultCol, i);
udfTrace("block:%p, row:%d result is null since col:0 is null", block, 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)) {
udfColDataSetNull(resultCol, i); udfColDataSetNull(resultCol, i);
udfTrace("block:%p, row:%d result is null since col:%d is null", block, i, j);
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", block);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }

View File

@ -1,71 +1,87 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h> #include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "taosudf.h" #include "taosudf.h"
DLL_EXPORT int32_t l2norm_init() { DLL_EXPORT int32_t l2norm_init() { return 0; }
return 0;
}
DLL_EXPORT int32_t l2norm_destroy() { DLL_EXPORT int32_t l2norm_destroy() { return 0; }
return 0;
}
DLL_EXPORT int32_t l2norm_start(SUdfInterBuf *buf) { DLL_EXPORT int32_t l2norm_start(SUdfInterBuf* buf) {
int32_t bufLen = sizeof(double);
if (buf->bufLen < bufLen) {
udfError("failed to execute udf since input buflen:%d < %d", buf->bufLen, bufLen);
return TSDB_CODE_UDF_INVALID_BUFSIZE;
}
udfTrace("start aggregation, buflen:%d used:%d", buf->bufLen, bufLen);
*(int64_t*)(buf->buf) = 0; *(int64_t*)(buf->buf) = 0;
buf->bufLen = sizeof(double); buf->bufLen = bufLen;
buf->numOfResult = 1; buf->numOfResult = 0;
return 0; return 0;
} }
DLL_EXPORT int32_t l2norm(SUdfDataBlock* block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) { DLL_EXPORT int32_t l2norm(SUdfDataBlock* block, SUdfInterBuf* interBuf, SUdfInterBuf* newInterBuf) {
double sumSquares = *(double*)interBuf->buf; udfTrace("block:%p, processing begins, cols:%d rows:%d", block, block->numOfCols, block->numOfRows);
int8_t numNotNull = 0;
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 && col->colMeta.type != TSDB_DATA_TYPE_DOUBLE) {
col->colMeta.type == TSDB_DATA_TYPE_DOUBLE)) { udfError("block:%p, col:%d type:%d should be int(%d) or double(%d)", block, i, col->colMeta.type,
TSDB_DATA_TYPE_INT, TSDB_DATA_TYPE_DOUBLE);
return TSDB_CODE_UDF_INVALID_INPUT; return TSDB_CODE_UDF_INVALID_INPUT;
} }
} }
double sumSquares = *(double*)interBuf->buf;
int8_t numNotNull = 0;
for (int32_t i = 0; i < block->numOfCols; ++i) { for (int32_t i = 0; i < block->numOfCols; ++i) {
for (int32_t j = 0; j < block->numOfRows; ++j) { for (int32_t j = 0; j < block->numOfRows; ++j) {
SUdfColumn* col = block->udfCols[i]; SUdfColumn* col = block->udfCols[i];
if (udfColDataIsNull(col, j)) { if (udfColDataIsNull(col, j)) {
udfTrace("block:%p, col:%d row:%d is null", block, i, j);
continue; continue;
} }
switch (col->colMeta.type) { switch (col->colMeta.type) {
case TSDB_DATA_TYPE_INT: { case TSDB_DATA_TYPE_INT: {
char* cell = udfColDataGetData(col, j); char* cell = udfColDataGetData(col, j);
int32_t num = *(int32_t*)cell; int32_t num = *(int32_t*)cell;
sumSquares += (double)num * num; sumSquares += (double)num * num;
udfTrace("block:%p, col:%d row:%d data:%d", block, i, j, num);
break; break;
} }
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE: {
char* cell = udfColDataGetData(col, j); char* cell = udfColDataGetData(col, j);
double num = *(double*)cell; double num = *(double*)cell;
sumSquares += num * num; sumSquares += num * num;
udfTrace("block:%p, col:%d row:%d data:%f", block, i, j, num);
break; break;
} }
default: default:
break; break;
} }
++numNotNull; ++numNotNull;
} }
udfTrace("block:%p, col:%d result is %f", block, i, sumSquares);
} }
*(double*)(newInterBuf->buf) = sumSquares; *(double*)(newInterBuf->buf) = sumSquares;
newInterBuf->bufLen = sizeof(double); newInterBuf->bufLen = sizeof(double);
newInterBuf->numOfResult = 1; newInterBuf->numOfResult = 1;
udfTrace("block:%p, result is %f", block, sumSquares);
return 0; return 0;
} }
DLL_EXPORT int32_t l2norm_finish(SUdfInterBuf* buf, SUdfInterBuf *resultData) { DLL_EXPORT int32_t l2norm_finish(SUdfInterBuf* buf, SUdfInterBuf* resultData) {
double sumSquares = *(double*)(buf->buf); double sumSquares = *(double*)(buf->buf);
*(double*)(resultData->buf) = sqrt(sumSquares); *(double*)(resultData->buf) = sqrt(sumSquares);
resultData->bufLen = sizeof(double); resultData->bufLen = sizeof(double);
resultData->numOfResult = 1; resultData->numOfResult = 1;
udfTrace("end aggregation, result is %f", *(double*)(resultData->buf));
return 0; return 0;
} }

View File

@ -1,101 +1,113 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h> #include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "taosudf.h" #include "taosudf.h"
#define STR_MAX_LEN 256 // inter buffer length #define STR_MAX_LEN 256 // inter buffer length
// init DLL_EXPORT int32_t max_vol_init() { return 0; }
DLL_EXPORT int32_t max_vol_init()
{
return 0;
}
// destory DLL_EXPORT int32_t max_vol_destroy() { return 0; }
DLL_EXPORT int32_t max_vol_destroy()
{
return 0;
}
// start DLL_EXPORT int32_t max_vol_start(SUdfInterBuf *buf) {
DLL_EXPORT int32_t max_vol_start(SUdfInterBuf *buf) int32_t bufLen = sizeof(float) + STR_MAX_LEN;
{ if (buf->bufLen < bufLen) {
memset(buf->buf, 0, sizeof(float) + STR_MAX_LEN); udfError("failed to execute udf since input buflen:%d < %d", buf->bufLen, bufLen);
// set init value return TSDB_CODE_UDF_INVALID_BUFSIZE;
*((float*)buf->buf) = -10000000; }
buf->bufLen = sizeof(float) + STR_MAX_LEN;
buf->numOfResult = 0; udfTrace("start aggregation, buflen:%d used:%d", buf->bufLen, bufLen);
return 0; memset(buf->buf, 0, sizeof(float) + STR_MAX_LEN);
*((float *)buf->buf) = INT32_MIN;
buf->bufLen = bufLen;
buf->numOfResult = 0;
return 0;
} }
DLL_EXPORT int32_t max_vol(SUdfDataBlock *block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) { DLL_EXPORT int32_t max_vol(SUdfDataBlock *block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) {
float maxValue = *(float *)interBuf->buf; udfTrace("block:%p, processing begins, cols:%d rows:%d", block, block->numOfCols, block->numOfRows);
char strBuff[STR_MAX_LEN] = "inter1buf";
float maxValue = *(float *)interBuf->buf;
if (block->numOfCols < 2) char strBuff[STR_MAX_LEN] = "inter1buf";
{
if (block->numOfCols < 2) {
udfError("block:%p, cols:%d needs to be greater than 2", block, block->numOfCols);
return TSDB_CODE_UDF_INVALID_INPUT;
}
// check data type
for (int32_t i = 0; i < block->numOfCols; ++i) {
SUdfColumn *col = block->udfCols[i];
if (i == block->numOfCols - 1) {
// last column is device id , must varchar
if (col->colMeta.type != TSDB_DATA_TYPE_VARCHAR) {
udfError("block:%p, col:%d type:%d should be varchar(%d)", block, i, col->colMeta.type, TSDB_DATA_TYPE_VARCHAR);
return TSDB_CODE_UDF_INVALID_INPUT; return TSDB_CODE_UDF_INVALID_INPUT;
}
} else {
if (col->colMeta.type != TSDB_DATA_TYPE_FLOAT) {
udfError("block:%p, col:%d type:%d should be float(%d)", block, i, col->colMeta.type, TSDB_DATA_TYPE_FLOAT);
return TSDB_CODE_UDF_INVALID_INPUT;
}
} }
}
// check data type // calc max voltage
for (int32_t i = 0; i < block->numOfCols; ++i) SUdfColumn *lastCol = block->udfCols[block->numOfCols - 1];
{ for (int32_t i = 0; i < block->numOfCols - 1; ++i) {
SUdfColumn *col = block->udfCols[i]; for (int32_t j = 0; j < block->numOfRows; ++j) {
if( i == block->numOfCols - 1) { SUdfColumn *col = block->udfCols[i];
// last column is device id , must varchar if (udfColDataIsNull(col, j)) {
if (col->colMeta.type != TSDB_DATA_TYPE_VARCHAR ) { udfTrace("block:%p, col:%d row:%d is null", block, i, j);
return TSDB_CODE_UDF_INVALID_INPUT; continue;
} }
} else {
if (col->colMeta.type != TSDB_DATA_TYPE_FLOAT) { char *data = udfColDataGetData(col, j);
return TSDB_CODE_UDF_INVALID_INPUT; float voltage = *(float *)data;
}
} if (voltage <= maxValue) {
udfTrace("block:%p, col:%d row:%d data:%f", block, i, j, voltage);
} else {
maxValue = voltage;
char *valData = udfColDataGetData(lastCol, j);
int32_t valDataLen = udfColDataGetDataLen(lastCol, j);
// get device id
char *deviceId = valData + sizeof(uint16_t);
int32_t deviceIdLen = valDataLen < (STR_MAX_LEN - 1) ? valDataLen : (STR_MAX_LEN - 1);
strncpy(strBuff, deviceId, deviceIdLen);
snprintf(strBuff + deviceIdLen, STR_MAX_LEN - deviceIdLen, "_(%d,%d)_%f", j, i, maxValue);
udfTrace("block:%p, col:%d row:%d data:%f, as max_val:%s", block, i, j, voltage, strBuff);
}
} }
}
// calc max voltage *(float *)newInterBuf->buf = maxValue;
SUdfColumn *lastCol = block->udfCols[block->numOfCols - 1]; strncpy(newInterBuf->buf + sizeof(float), strBuff, STR_MAX_LEN);
for (int32_t i = 0; i < (block->numOfCols - 1); ++i) { newInterBuf->bufLen = sizeof(float) + strlen(strBuff) + 1;
for (int32_t j = 0; j < block->numOfRows; ++j) { newInterBuf->numOfResult = 1;
SUdfColumn *col = block->udfCols[i];
if (udfColDataIsNull(col, j)) {
continue;
}
char *data = udfColDataGetData(col, j);
float voltage = *(float *)data;
if (voltage > maxValue) {
maxValue = voltage;
char *valData = udfColDataGetData(lastCol, j);
// get device id
char *deviceId = valData + sizeof(uint16_t);
sprintf(strBuff, "%s_(%d,%d)_%f", deviceId, j, i, maxValue);
}
}
}
*(float*)newInterBuf->buf = maxValue; udfTrace("block:%p, result is %s", block, strBuff);
strcpy(newInterBuf->buf + sizeof(float), strBuff); return 0;
newInterBuf->bufLen = sizeof(float) + strlen(strBuff)+1;
newInterBuf->numOfResult = 1;
return 0;
} }
DLL_EXPORT int32_t max_vol_finish(SUdfInterBuf *buf, SUdfInterBuf *resultData) DLL_EXPORT int32_t max_vol_finish(SUdfInterBuf *buf, SUdfInterBuf *resultData) {
{ char *str = buf->buf + sizeof(float);
char * str = buf->buf + sizeof(float); // copy to des
// copy to des char *des = resultData->buf + sizeof(uint16_t);
char * des = resultData->buf + sizeof(uint16_t); strcpy(des, str);
strcpy(des, str);
// set binary type len // set binary type len
uint16_t len = strlen(str); uint16_t len = strlen(str);
*((uint16_t*)resultData->buf) = len; *((uint16_t *)resultData->buf) = len;
// set buf len // set buf len
resultData->bufLen = len + sizeof(uint16_t); resultData->bufLen = len + sizeof(uint16_t);
// set row count // set row count
resultData->numOfResult = 1; resultData->numOfResult = 1;
return 0;
udfTrace("end aggregation, result is %s", str);
return 0;
} }

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":