Merge pull request #29563 from taosdata/main

Merge latest codes from main branch
This commit is contained in:
WANG Xu 2025-01-14 10:48:27 +08:00 committed by GitHub
commit 673887ee82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
160 changed files with 6388 additions and 1207 deletions

View File

@ -42,7 +42,7 @@ jobs:
cmake .. -DBUILD_TOOLS=true \
-DBUILD_KEEPER=true \
-DBUILD_HTTP=false \
-DBUILD_TEST=false \
-DBUILD_TEST=true \
-DBUILD_DEPENDENCY_TESTS=false
make -j 4
sudo make install

View File

@ -368,8 +368,8 @@ def pre_test_build_win() {
'''
bat '''
cd %WIN_COMMUNITY_ROOT%/tests/ci
pip3 install taospy==2.7.16
pip3 install taos-ws-py==0.3.5
pip3 install taospy==2.7.21
pip3 install taos-ws-py==0.3.8
xcopy /e/y/i/f %WIN_INTERNAL_ROOT%\\debug\\build\\lib\\taos.dll C:\\Windows\\System32
'''
return 1

View File

@ -1,6 +1,5 @@
<p>
<p align="center">
<a href="https://tdengine.com" target="_blank">
<a href="https://www.taosdata.com" target="_blank">
<img
src="docs/assets/tdengine.svg"
alt="TDengine"
@ -8,14 +7,8 @@
/>
</a>
</p>
<p>
[![Build Status](https://travis-ci.org/taosdata/TDengine.svg?branch=master)](https://travis-ci.org/taosdata/TDengine)
[![Build status](https://ci.appveyor.com/api/projects/status/kf3pwh2or5afsgl9/branch/master?svg=true)](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master)
[![Coverage Status](https://coveralls.io/repos/github/taosdata/TDengine/badge.svg?branch=3.0)](https://coveralls.io/github/taosdata/TDengine?branch=3.0)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4201/badge)](https://bestpractices.coreinfrastructure.org/projects/4201)
简体中文 | [English](README.md) | [TDengine 云服务](https://cloud.taosdata.com/?utm_medium=cn&utm_source=github) | 很多职位正在热招中,请看[这里](https://www.taosdata.com/cn/careers/)
简体中文 | [English](README.md) | [TDengine 云服务](https://cloud.taosdata.com/?utm_medium=cn&utm_source=github) | 很多职位正在热招中,请看[这里](https://www.taosdata.com/careers/)
# TDengine 简介

View File

@ -15,6 +15,19 @@ When inserting data using parameter binding, it can avoid the resource consumpti
**Tips: It is recommended to use parameter binding for data insertion**
:::note
We only recommend using the following two forms of SQL for parameter binding data insertion:
```sql
a. Subtables already exists:
1. INSERT INTO meters (tbname, ts, current, voltage, phase) VALUES(?, ?, ?, ?, ?)
b. Automatic table creation on insert:
1. INSERT INTO meters (tbname, ts, current, voltage, phase, location, group_id) VALUES(?, ?, ?, ?, ?, ?, ?)
2. INSERT INTO ? USING meters TAGS (?, ?) VALUES (?, ?, ?, ?)
```
:::
Next, we continue to use smart meters as an example to demonstrate the efficient writing functionality of parameter binding with various language connectors:
1. Prepare a parameterized SQL insert statement for inserting data into the supertable `meters`. This statement allows dynamically specifying subtable names, tags, and column values.

View File

@ -26,8 +26,8 @@ Flink Connector supports all platforms that can run Flink 1.19 and above version
| Flink Connector Version | Major Changes | TDengine Version|
|-------------------------| ------------------------------------ | ---------------- |
| 2.0.0 | 1.Support SQL queries on data in TDengine database <br/> 2. Support CDC subscription to data in TDengine database<br/> 3. Supports reading and writing to TDengine database using Table SQL | 3.3.5.0 and above versions|
| 1.0.0 | Support Sink function to write data from other sources to TDengine in the future| 3.3.2.0 and above versions|
| 2.0.0 | 1.Support SQL queries on data in TDengine database. <br/> 2. Support CDC subscription to data in TDengine database.<br/> 3. Supports reading and writing to TDengine database using Table SQL. | 3.3.5.0 and higher|
| 1.0.0 | Support Sink function to write data from other sources to TDengine in the future.| 3.3.2.0 and higher|
## Exception and error codes

View File

@ -13,9 +13,9 @@ Through the Python connector of TDengine, Superset can support TDengine data sou
Prepare the following environment:
- TDengine is installed and running normally (both Enterprise and Community versions are available)
- taosAdapter is running normally, refer to [taosAdapter](../../../reference/components/taosAdapter)
- taosAdapter is running normally, refer to [taosAdapter](../../../tdengine-reference/components/taosadapter/)
- Apache Superset version 2.1.0 or above is already installed, refre to [Apache Superset](https://superset.apache.org/)
## Install TDengine Python Connector
The Python connector of TDengine comes with a connection driver that supports Superset in versions 2.1.18 and later, which will be automatically installed in the Superset directory and provide data source services.

View File

@ -43,7 +43,7 @@ After modifying configuration file parameters, you need to restart the *taosd* s
|resolveFQDNRetryTime | Cancelled after 3.x |Not supported |Number of retries when FQDN resolution fails|
|timeToGetAvailableConn | Cancelled after 3.3.4.x |Maximum waiting time to get an available connection, range 10-50000000, in milliseconds, default value 500000|
|maxShellConns | Cancelled after 3.x |Supported, effective after restart|Maximum number of connections allowed|
|maxRetryWaitTime | |Supported, effective after restart|Maximum timeout for reconnection, default value is 10s|
|maxRetryWaitTime | |Supported, effective after restart|Maximum timeout for reconnection,calculated from the time of retry,range is 0-86400000,in milliseconds, default value 10000|
|shareConnLimit |Added in 3.3.4.0 |Supported, effective after restart|Number of requests a connection can share, range 1-512, default value 10|
|readTimeout |Added in 3.3.4.0 |Supported, effective after restart|Minimum timeout for a single request, range 64-604800, in seconds, default value 900|

View File

@ -268,7 +268,22 @@ An exporter used by Prometheus that exposes hardware and operating system metric
### Getting the VGroup ID of a table
You can access the HTTP interface `http://<fqdn>:6041/rest/vgid?db=<db>&table=<table>` to get the VGroup ID of a table.
You can send a POST request to the HTTP interface `http://<fqdn>:<port>/rest/sql/<db>/vgid` to get the VGroup ID of a table.
The body should be a JSON array of multiple table names.
Example: Get the VGroup ID for the database power and tables d_bind_1 and d_bind_2.
```shell
curl --location 'http://127.0.0.1:6041/rest/sql/power/vgid' \
--user 'root:taosdata' \
--data '["d_bind_1","d_bind_2"]'
```
response:
```json
{"code":0,"vgIDs":[153,152]}
```
## Memory Usage Optimization Methods

View File

@ -491,15 +491,15 @@ SELECT ... FROM (SELECT ... FROM ...) ...;
:::
## UNION ALL Clause
## UNION Clause
```text title=Syntax
SELECT ...
UNION ALL SELECT ...
[UNION ALL SELECT ...]
UNION [ALL] SELECT ...
[UNION [ALL] SELECT ...]
```
TDengine supports the UNION ALL operator. This means that if multiple SELECT clauses return result sets with the exact same structure (column names, column types, number of columns, order), these result sets can be combined together using UNION ALL. Currently, only the UNION ALL mode is supported, which means that duplicates are not removed during the merging process. In the same SQL statement, a maximum of 100 UNION ALLs are supported.
TDengine supports the UNION [ALL] operator. This means that if multiple SELECT clauses return result sets with the exact same structure (column names, column types, number of columns, order), these result sets can be combined together using UNION [ALL].
## SQL Examples

View File

@ -45,7 +45,7 @@ ALTER ALL DNODES dnode_option
For configuration parameters that support dynamic modification, you can use the ALTER DNODE or ALTER ALL DNODES syntax to modify the values of configuration parameters in a dnode. Starting from version 3.3.4.0, the modified configuration parameters will be automatically persisted and will remain effective even after the database service is restarted.
To check whether a configuration parameter supports dynamic modification, please refer to the following page: [taosd Reference](../01-components/01-taosd.md)
To check whether a configuration parameter supports dynamic modification, please refer to the following page: [taosd Reference](/tdengine-reference/components/taosd/)
The value is the parameter's value and needs to be in character format. For example, to change the log output level of dnode 1 to debug:
@ -130,7 +130,7 @@ ALTER LOCAL local_option
You can use the above syntax to modify the client's configuration parameters, and there is no need to restart the client. The changes take effect immediately.
To check whether a configuration parameter supports dynamic modification, please refer to the following page:[taosc Reference](../01-components/02-taosc.md)
To check whether a configuration parameter supports dynamic modification, please refer to the following page:[taosc Reference](/tdengine-reference/components/taosc/)
## View Client Configuration

View File

@ -60,7 +60,7 @@ CREATE [OR REPLACE] AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE
CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 64;
```
About how to develop custom functions, please refer to [UDF Usage Instructions](../../../developer-guide/user-defined-functions/).
About how to develop custom functions, please refer to [UDF Usage Instructions](/developer-guide/user-defined-functions/).
## Manage UDF

View File

@ -4,7 +4,11 @@ title: Time-Range Small Materialized Aggregates (TSMAs)
slug: /tdengine-reference/sql-manual/manage-tsmas
---
To improve the performance of aggregate function queries with large data volumes, window pre-aggregation (TSMA Time-Range Small Materialized Aggregates) objects are created. By using fixed time windows to pre-calculate specified aggregate functions and storing the results, query performance is enhanced by querying these pre-calculated results.
In scenarios with large amounts of data, it is often necessary to query summary results for a certain period. As historical data increases or the time range expands, query time will also increase accordingly. By using materialized aggregation, the calculation results can be stored in advance, allowing subsequent queries to directly read the aggregated results without scanning the original data, such as the SMA (Small Materialized Aggregates) information within the current block.
The SMA information within a block has a small granularity. If the query time range is in days, months, or even years, the number of blocks will be large. Therefore, TSMA (Time-Range Small Materialized Aggregates) supports users to specify a time window for materialized aggregation. By pre-calculating the data within a fixed time window and storing the calculation results, queries can be performed on the pre-calculated results to improve query performance.
![TSMA Introduction](./assets/TSMA_intro.png)
## Creating TSMA

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -509,8 +509,8 @@ For the OpenTSDB text protocol, the parsing of timestamps follows its official p
- **Interface Description**: Used for polling to consume data. Each consumer can only call this interface in a single thread.
- tmq: [Input] Points to a valid ws_tmq_t structure pointer, which represents a TMQ consumer object.
- timeout: [Input] Polling timeout in milliseconds, a negative number indicates a default timeout of 1 second.
- **Return Value**: Non-`NULL`: Success, returns a pointer to a WS_RES structure, which contains the received message. `NULL`: Failure, indicates no data. WS_RES results are consistent with taos_query results, and information in WS_RES can be obtained through various query interfaces, such as schema, etc.
- **Return Value**: Non-`NULL`: Success, returns a pointer to a WS_RES structure, which contains the received message. `NULL`: indicates no data, the error code can be obtained through ws_errno (NULL), please refer to the reference manual for specific error message. WS_RES results are consistent with taos_query results, and information in WS_RES can be obtained through various query interfaces, such as schema, etc.
- `int32_t ws_tmq_consumer_close(ws_tmq_t *tmq)`
- **Interface Description**: Used to close the ws_tmq_t structure. Must be used in conjunction with ws_tmq_consumer_new.
- tmq: [Input] Points to a valid ws_tmq_t structure pointer, which represents a TMQ consumer object.
@ -1195,8 +1195,8 @@ In addition to using SQL or parameter binding APIs to insert data, you can also
- **Interface Description**: Used to poll for consuming data, each consumer can only call this interface in a single thread.
- tmq: [Input] Points to a valid tmq_t structure pointer, representing a TMQ consumer object.
- timeout: [Input] Polling timeout in milliseconds, a negative number indicates a default timeout of 1 second.
- **Return Value**: Non-`NULL`: Success, returns a pointer to a TAOS_RES structure containing the received messages. `NULL`: Failure, indicates no data. TAOS_RES results are consistent with taos_query results, and information in TAOS_RES can be obtained through various query interfaces, such as schema, etc.
- **Return Value**: Non-`NULL`: Success, returns a pointer to a TAOS_RES structure containing the received messages. `NULL`: indicates no data, the error code can be obtained through taos_errno (NULL), please refer to the reference manual for specific error message. TAOS_RES results are consistent with taos_query results, and information in TAOS_RES can be obtained through various query interfaces, such as schema, etc.
- `int32_t tmq_consumer_close(tmq_t *tmq)`
- **Interface Description**: Used to close a tmq_t structure. Must be used in conjunction with tmq_consumer_new.
- tmq: [Input] Points to a valid tmq_t structure pointer, which represents a TMQ consumer object.

View File

@ -50,7 +50,7 @@ Supports Python 3.0 and above.
-The platforms supported by native connections are consistent with those supported by the TDengine client driver.
-WebSocket/REST connections support all platforms that can run Python.
## Versions History
## Version History
Python Connector historical versions (it is recommended to use the latest version of 'taopsy'):

View File

@ -23,13 +23,14 @@ import RequestId from "../../assets/resources/_request_id.mdx";
## Version History
| Connector Version | Major Changes | TDengine Version |
|------------------|-------------------------------------------------|-------------------|
| 3.1.4 | Improved WebSocket query and insert performance. | 3.3.2.0 and higher |
| 3.1.3 | Supported WebSocket auto-reconnect. | - |
| 3.1.2 | Fixed schemaless resource release. | - |
| 3.1.1 | Supported varbinary and geometry types. | - |
| 3.1.0 | WebSocket uses a native C# implementation. | 3.2.1.0 and higher |
| Connector Version | Major Changes | TDengine Version |
|-------------------|------------------------------------------------------------|--------------------|
| 3.1.5 | Fix WebSocket encoding error for Chinese character length. | - |
| 3.1.4 | Improved WebSocket query and insert performance. | 3.3.2.0 and higher |
| 3.1.3 | Supported WebSocket auto-reconnect. | - |
| 3.1.2 | Fixed schemaless resource release. | - |
| 3.1.1 | Supported varbinary and geometry types. | - |
| 3.1.0 | WebSocket uses a native C# implementation. | 3.2.1.0 and higher |
## Exceptions and Error Codes

View File

@ -124,7 +124,7 @@ In addition to this, the WebSocket connection method also supports 32-bit applic
| v1.1.0 | 1. Supports view functionality. <br/>2. Supports VARBINARY/GEOMETRY data types. <br/>3. Supports ODBC 32-bit WebSocket connection method (Enterprise edition only). <br/>4. Supports ODBC data source configuration dialog settings for compatibility adaptation options for industrial software like KingSCADA, Kepware, etc. (Enterprise edition only). | 3.3.3.0 and higher |
| v1.0.2 | Supports CP1252 character encoding. | 3.2.3.0 and higher |
| v1.0.1 | 1. Supports DSN settings for BI mode, in BI mode TDengine database does not return system database and supertable subtable information. <br/>2. Refactored character set conversion module, improving read and write performance. <br/> 3. Default connection method in ODBC data source configuration dialog changed to "WebSocket". <br/>4. Added "Test Connection" control in ODBC data source configuration dialog. <br/>5. ODBC data source configuration supports Chinese/English interface. | - |
| v1.0.0.0 | Initial release, supports interacting with Tdengine database to read and write data, refer to the "API Reference" section for details. | 3.2.2.0 and higher |
| v1.0.0.0 | Initial release, supports interacting with TDengine database to read and write data, refer to the "API Reference" section for details. | 3.2.2.0 and higher |
## Data Type Mapping

View File

@ -252,7 +252,7 @@ Description:
- code: (`int`) 0 represents success.
- column_meta: (`[][3]any`) Column information, each column is described by three values: column name (string), column type (string), and type length (int).
- rows: (`int`) Number of data return rows.
- data: (`[][]any`) Specific data content (time format only supports RFC3339, result set for timezone 0).
- data: (`[][]any`) Specific data content (time format only supports RFC3339, result set for timezone 0, when specifying tz, the corresponding time zone is returned).
Column types use the following strings:
@ -434,7 +434,6 @@ curl http://<fqnd>:<port>/rest/login/<username>/<password>
Here, `fqdn` is the FQDN or IP address of the TDengine database, `port` is the port number of the TDengine service, `username` is the database username, and `password` is the database password. The return is in JSON format, with the fields meaning as follows:
- status: Flag of the request result.
- code: Return code.
- desc: Authorization code.

View File

@ -534,4 +534,5 @@ This document details the server error codes that may be encountered when using
| 0x80004000 | Invalid message | The subscribed data is illegal, generally does not occur | Check the client-side error logs for details |
| 0x80004001 | Consumer mismatch | The vnode requested for subscription and the reassigned vnode are inconsistent, usually occurs when new consumers join the same consumer group | Internal error, not exposed to users |
| 0x80004002 | Consumer closed | The consumer no longer exists | Check if it has already been closed |
| 0x80004017 | Invalid status, please subscribe topic first | tmq status invalidate | Without calling subscribe, directly poll data |
| 0x80004100 | Stream task not exist | The stream computing task does not exist | Check the server-side error logs |

View File

@ -25,6 +25,10 @@ Download links for TDengine 3.x version installation packages are as follows:
import Release from "/components/ReleaseV3";
## 3.3.5.0
<Release type="tdengine" version="3.3.5.0" />
## 3.3.4.8
<Release type="tdengine" version="3.3.4.8" />

View File

@ -2,7 +2,7 @@
title: TDengine 3.3.4.8 Release Notes
sidebar_label: 3.3.4.8
description: Version 3.3.4.8 Notes
slug: /release-history/release-notes/3.3.4.8
slug: /release-history/release-notes/3-3-4-8
---
## New Features

View File

@ -0,0 +1,85 @@
---
title: TDengine 3.3.5.0 Release Notes
sidebar_label: 3.3.5.0
description: Version 3.3.5.0 Notes
slug: /release-history/release-notes/3-3-5-0
---
## Features
1. feat: refactor MQTT to improve stability and performance
2. feat: refactor taosX incremental backup-restore
3. feat: add stmt2 apis in JDBC via websocket connection
4. feat: add stmt2 api in Rust connector
5. feat: add error codes in error prompts in taos-CLI
6. feat: superSet can connect TDengine with python connector
7. feat: configurable grafana dashboards in explorer management
8. feat: add taosX-agent in-memory cache queu capacity option
## Enhancements
1. enh: adjust the reporting mechanism of telemetry.
2. enh: support for SQL-based statistics of disk space for a specified DB.
3. enh: add memory management for SQL queries on the server side
4. enh: interval clause allows the use of the AUTO keyword to specify the window offset.
5. enh: reduce the impact on data write performance during data migration across multi-level storage
6. enh: migrate from angular to react for grafana 11.3+
7. enh: refactor taosAdapter websocket api for a slightly better perf
8. enh: add health state in taosX task status
9. enh: taosX add configurations to handle exceptions
10. enh: support setting options for client connections, including time zone, character set, user IP, and user name.
11. enh: taosdump support retry after connection timeout or broken
12. enh: allow creating index for tags that already subscribed
13. enh: taosX now support literal special chars in password
14. enh: improve data write performance when Last Cache is activated.
15. enh: compact command supports automatic execution, concurrency setting, and progress observation.
16. enh: support update global configuration parameters through SQL statements and persisting them.
17. enh: update the default compression method for all data types to improve the compression ratio in most scenarios.
18. enh: taosBenchmark --nodrop fix for mac/window
19. enh: prohibit the simultaneous execution of DB compaction and replica change operations (Enterpris).
20. enh: taosdump support primary key tables
21. enh: display user IP and name in the results of the SHOW QUERIES and SHOW CONNECTIONS statements.
22. enh: (JDBC)support batch insertion into multiple tables
23. enh: support for dynamically modifying the dataDir parameter for multi-level storage.
24. enh: prefer db file under data_dir
25. enh: enforce users to set strong passwords, which must be 8 to 16 characters in length and include at least three types of characters from the following: uppercase letters, lowercase letters, numbers, and special characters.
26. enh: improve the speed at which clients acquire the new Leader.
27. enh: support negative regex pattern in opc point selector
## Fixes
1. fix: the potential for deadlocks when updating checkpoints in stream computing under high-load scenarios.
2. fix: write tmq data into target error when terrno already set
3. fix: taosd cannot start when there is data corruption in a block within the WAL
4. fix: taosBenchmark fails when taosd disconnected in replica 2/3
5. fix: log files being lost when they are switched frequently.
6. fix: the stream computing stops due to the data update within the window.
7. fix: libtaosws.so sets an incorrect error code when the connection is terminated while fetch data.
8. fix: taosX opc error in case of @-prefixed name
9. fix: fix permission denied with show vgroups sql in cloud
10. fix: fix sql syntax error when migrating from large stables with compress options
11. fix: incorrect memory estimation for vnode usage
12. fix: failed to perform UNION ALL query on constant strings of the varchar type.
13. fix: leader transfer during the execution of transaction may cause deadlock.
14. fix: rust connector invliad pointer addr in ws_stmt_get_tag_fields
15. fix: union statement fails when executing with subqueries containing multiple NULLs.
16. fix: the pause operation of stream computing might fail.
17. fix: when writing data into a sub-table with a table name length of 192 characters using an SQL statement, errors may occur if the table name is enclosed in backticks (`).
18. fix: when performing a join query on super tables across different databases, if each database contains only one vnode, the query will return an error.
19. fix: no enough disk space cause taosX panic
20. fix: when write data to a super table, using both bound and unbound simultaneously will trigger an exception.
21. fix: metrics non-exist cause panic when connect with agent
22. fix: when creating indexes for tag with a large character length, taosd may crash.
23. fix: when the input parameters for the functions first, last, last_row, and char exceed 127, the taosd may crash. https://github.com/taosdata/TDengine/issues/29241
24. fix: when the number of rows in the result set of the LIMIT statement exceeds the size of a single data block, the returned count does not match the expectation.
25. fix: when synchronizing data between clusters, if the target task is deleted, the source cluster may run out of memory
26. fix: metadata read-write lock misconfiguration leads to a very small chance of blocking writes.
27. fix: when importing CSV files using the INSERT INTO statement on the Windows platform, the absence of a newline character at the end of the file may lead to an issue of infinite loop reading.
28. fix: after the tags of the table are updated, the stream computing fails to recognize and apply the ne values.
29. fix: fix kafka timeout issue and improve performance and stability
30. fix: in sql queries, when both 'is null' and invalid 'in' filter conditions are included simultaneously, the query results are incorrect. https://github.com/taosdata/TDengine/issues/29067
31. fix: sql queries containing both 'IN' and 'BETWEEN' filter conditions result in incorrect query results. https://github.com/taosdata/TDengine/issues/28989
32. fix: when performing multiplication or division operations between timestamp and numeric types, the results are incorrect. https://github.com/taosdata/TDengine/issues/28339
33. fix: data type conversion error in the IN statement leads to incorrect query results. https://github.com/taosdata/TDengine/issues/29047 https://github.com/taosdata/TDengine/issues/28902
34. fix: the error in filtering results when constant conditions are combined with OR operators. https://github.com/taosdata/TDengine/issues/28904
35. fix: when performing subtraction operation on timestamp type, the negative value is not considered. https://github.com/taosdata/TDengine/issues/28906
36. fix: tag values may display incorrectly when using GROUP BY tag synatix
37. fix: gcc < 10 bug cause taosX compile error

View File

@ -3,6 +3,8 @@ title: Release Notes
slug: /release-history/release-notes
---
[3.3.5.0](./3-3-5-0/)
[3.3.4.8](./3-3-4-8/)
[3.3.4.3](./3-3-4-3/)

View File

@ -1,6 +1,4 @@
package com.taosdata.example;
import com.alibaba.fastjson.JSON;
import com.taosdata.jdbc.AbstractStatement;
import java.sql.*;

View File

@ -104,8 +104,9 @@ public class JdbcDemo {
private void executeQuery(String sql) {
long start = System.currentTimeMillis();
try (Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery(sql);
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql)) {
long end = System.currentTimeMillis();
printSql(sql, true, (end - start));
Util.printResult(resultSet);

View File

@ -63,7 +63,7 @@ toc_max_heading_level: 4
1. 数据库Database数据库提供时序数据的高效存储和读取能力。在工业、物联网场景由设备所产生的时序数据量是十分惊人的。从存储数据的角度来说数据库需要把这些数据持久化到硬盘上并最大程度地压缩从而降低存储成本。从读取数据的角度来说数据库需要保证实时查询以及历史数据的查询效率。比较传统的存储方案是使用 MySql、Oracle 等关系型数据库,也有 Hadoop 体系的 HBase专用的时序数据库则有 InfluxDB、OpenTSDB、Prometheus 等。
2. 数据订阅Data Subscription很多时序数据应用都需要在第一时间订阅到业务所需的实时数据从而及时了解被监测对象的最新状态,用 AI 或其他工具做实时的数据分析。同时,由于数据的隐私以及安全,你只能允许应用订阅他有权限访问的数据。因此,一个时序数据处理平台一定需要具备数据订阅的能力,帮助应用实时获取最新数据。
2. 数据订阅Data Subscription很多时序数据应用都需要在第一时间订阅到业务所需的实时数据从而及时了解被监测对象的最新状态用 AI 或其他工具做实时的数据分析。同时,由于数据的隐私以及安全,你只能允许应用订阅他有权限访问的数据。因此,一个时序数据处理平台一定需要具备数据订阅的能力,帮助应用实时获取最新数据。
3. ETLExtract Transform Load在实际的物联网、工业场景中时序数据的采集需要特定的 ETL 工具进行数据的提取、清洗和转换操作,才能把数据写入数据库中,以保证数据的质量。因为不同数据采集系统往往使用不同的标准,比如采集的温度的物理单位不一致,有的用摄氏度,有的用华氏度;系统之间所在的时区不一致,要进行转换;时间分辨率也可能不统一,因此这些从不同系统汇聚来的数据需要进行转换才能写入数据库。
@ -135,4 +135,4 @@ toc_max_heading_level: 4
18. 需要支持私有化部署。因为很多企业出于安全以及各种因素的考虑,希望采用私有化部署。而传统的企业往往没有很强的 IT 运维团队,因此在安装、部署、运维等方面需要做到简单、快捷,可维护性强。
总之,时序大数据平台应具备高效、可扩展、实时、可靠、灵活、开放、简单、易维护等特点。近年来,众多企业纷纷将时序数据从传统大数据平台或关系型数据库迁移到专用时序大数据平台,以保障海量时序数据得到快速和有效处理,支撑相关业务的持续增长。
总之,时序大数据平台应具备高效、可扩展、实时、可靠、灵活、开放、简单、易维护等特点。近年来,众多企业纷纷将时序数据从传统大数据平台或关系型数据库迁移到专用时序大数据平台,以保障海量时序数据得到快速和有效处理,支撑相关业务的持续增长。

View File

@ -94,6 +94,8 @@ JSON 解析支持 JSONObject 或者 JSONArray。 如下 JSON 示例数据,可
![JSON 解析](./pic/transform-02.png)
> 注意JSON 属性名称中不能含有`.`;如果含有,则必须使用名称 alias 将名称转义。
##### Regex 正则表达式<a name="regex"></a>
可以使用正则表达式的**命名捕获组**从任何字符串(文本)字段中提取多个字段。如图所示,从 nginx 日志中提取访问ip、时间戳、访问的url等字段。
@ -158,6 +160,14 @@ let v3 = data["voltage"].split(",");
过滤功能可以设置过滤条件,满足条件的数据行 才会被写入目标表。过滤条件表达式的结果必须是 boolean 类型。在编写过滤条件前,必须确定 解析字段的类型,根据解析字段的类型,可以使用判断函数、比较操作符(`>`、`>=`、`<=`、`<`、`==`、`!=`)来判断。
对时间戳过滤,可以采用以下函数。其中 ts 为符合 rfc3339 日期时间格式化字符串的字段t1 和 t2 为相对当前时间的秒数,时间范围为 now + t1 ~ now + t2.
```
between_time_range(ts, t1, t2)
// 例如:如果时间范围为最近 7 天内的才能入库,则过滤条件为:
between_time_range(ts, -604800, 0)
```
#### 字段类型及转换
只有明确解析出的每个字段的类型,才能使用正确的语法做数据过滤。

View File

@ -15,6 +15,19 @@ import TabItem from "@theme/TabItem";
**Tips: 数据写入推荐使用参数绑定方式**
:::note
我们只推荐使用下面两种形式的 SQL 进行参数绑定写入:
```sql
一、确定子表存在:
1. INSERT INTO meters (tbname, ts, current, voltage, phase) VALUES(?, ?, ?, ?, ?)
二、自动建表:
1. INSERT INTO meters (tbname, ts, current, voltage, phase, location, group_id) VALUES(?, ?, ?, ?, ?, ?, ?)
2. INSERT INTO ? USING meters TAGS (?, ?) VALUES (?, ?, ?, ?)
```
:::
下面我们继续以智能电表为例,展示各语言连接器使用参数绑定高效写入的功能:
1. 准备一个参数化的 SQL 插入语句,用于向超级表 `meters` 中插入数据。这个语句允许动态地指定子表名、标签和列值。
2. 循环生成多个子表及其对应的数据行。对于每个子表:

View File

@ -13,7 +13,7 @@ Apache Flink 是一款由 Apache 软件基金会支持的开源分布式流批
## 前置条件
准备以下环境:
- TDengine 集群已部署并正常运行(企业及社区版均可)
- TDengine 服务已部署并正常运行(企业及社区版均可)
- taosAdapter 能够正常运行。详细参考 [taosAdapter 使用手册](../../../reference/components/taosadapter)
- Apache Flink v1.19.0 或以上版本已安装。安装 Apache Flink 请参考 [官方文档](https://flink.apache.org/)

View File

@ -19,7 +19,7 @@ DBeaver 是一款流行的跨平台数据库管理工具,方便开发者、数
![DBeaver 连接 TDengine](./dbeaver/dbeaver-connect-tdengine-zh.webp)
2. 配置 TDengine 连接,填入主机地址、端口号、用户名和密码。如果 TDengine 部署在本机,可以只填用户名和密码,默认用户名为 root默认密码为 taosdata。点击“测试连接”可以对连接是否可用进行测试。如果本机没有安装 TDengine Java
2. 配置 TDengine 连接,填入主机地址、端口号6041、用户名和密码。如果 TDengine 部署在本机,可以只填用户名和密码,默认用户名为 root默认密码为 taosdata。点击“测试连接”可以对连接是否可用进行测试。如果本机没有安装 TDengine Java
连接器DBeaver 会提示下载安装。
![配置 TDengine 连接](./dbeaver/dbeaver-config-tdengine-zh.webp)

View File

@ -41,7 +41,7 @@ taosd 命令行参数如下
|resolveFQDNRetryTime | 3.x 之后取消 |不支持动态修改 |FQDN 解析失败时的重试次数|
|timeToGetAvailableConn | 3.3.4.x之后取消 |支持动态修改 重启生效 |获得可用连接的最长等待时间,取值范围 10-50000000单位为毫秒默认值 500000|
|maxShellConns | 3.x 后取消 |支持动态修改 重启生效 |允许创建的最大链接数|
|maxRetryWaitTime | |支持动态修改 重启生效 |重连最大超时时间, 默认值是 10s|
|maxRetryWaitTime | |支持动态修改 重启生效 |重连最大超时时间, 从重试时候开始计算, 取值范围0-86400000, 单位为毫秒, 默认值10000|
|shareConnLimit |3.3.4.0 新增 |支持动态修改 重启生效 |一个链接可以共享的请求的数目,取值范围 1-512默认值 10|
|readTimeout |3.3.4.0 新增 |支持动态修改 重启生效 |单个请求最小超时时间,取值范围 64-604800单位为秒默认值 900|

View File

@ -262,7 +262,21 @@ Prometheus 使用的由 \*NIX 内核暴露的硬件和操作系统指标的输
### 获取 table 的 VGroup ID
可以访问 http 接口 `http://<fqdn>:6041/rest/vgid?db=<db>&table=<table>` 获取 table 的 VGroup ID。
可以 POST 请求 http 接口 `http://<fqdn>:<port>/rest/sql/<db>/vgid` 获取 table 的 VGroup IDbody 是多个表名 JSON 数组。
样例:获取数据库为 power表名为 d_bind_1 和 d_bind_2 的 VGroup ID
```shell
curl --location 'http://127.0.0.1:6041/rest/sql/power/vgid' \
--user 'root:taosdata' \
--data '["d_bind_1","d_bind_2"]'
```
响应:
```json
{"code":0,"vgIDs":[153,152]}
```
## 内存使用优化方法

View File

@ -29,7 +29,7 @@ taosKeeper 需要在操作系统终端执行,该工具支持三种配置方式
Usage of taoskeeper v3.3.3.0:
-R, --RotationInterval string interval for refresh metrics, such as "300ms", Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Env "TAOS_KEEPER_ROTATION_INTERVAL" (default "15s")
-c, --config string config path default /etc/taos/taoskeeper.toml
--drop string run taoskeeper in command mode, only support old_taosd_metric_stables.
--drop string run taoskeeper in command mode, only support old_taosd_metric_stables.
--environment.incgroup whether running in cgroup. Env "TAOS_KEEPER_ENVIRONMENT_INCGROUP"
--fromTime string parameter of transfer, example: 2020-01-01T00:00:00+08:00 (default "2020-01-01T00:00:00+08:00")
--gopoolsize int coroutine size. Env "TAOS_KEEPER_POOL_SIZE" (default 50000)
@ -65,7 +65,7 @@ Usage of taoskeeper v3.3.3.0:
taosKeeper 支持用 `taoskeeper -c <keeper config file>` 命令来指定配置文件。
若不指定配置文件taosKeeper 会使用默认配置文件,其路径为: `/etc/taos/taoskeeper.toml`
若既不指定 taosKeeper 配置文件,且 `/etc/taos/taoskeeper.toml` 也不存在,将使用默认配置。
若既不指定 taosKeeper 配置文件,且 `/etc/taos/taoskeeper.toml` 也不存在,将使用默认配置。
**下面是配置文件的示例:**
@ -261,7 +261,7 @@ Query OK, 14 row(s) in set (0.006542s)
可以查看一个超级表的最近一条上报记录,如:
``` shell
```shell
taos> select last_row(*) from taosd_dnodes_info;
last_row(_ts) | last_row(disk_engine) | last_row(system_net_in) | last_row(vnodes_num) | last_row(system_net_out) | last_row(uptime) | last_row(has_mnode) | last_row(io_read_disk) | last_row(error_log_count) | last_row(io_read) | last_row(cpu_cores) | last_row(has_qnode) | last_row(has_snode) | last_row(disk_total) | last_row(mem_engine) | last_row(info_log_count) | last_row(cpu_engine) | last_row(io_write_disk) | last_row(debug_log_count) | last_row(disk_used) | last_row(mem_total) | last_row(io_write) | last_row(masters) | last_row(cpu_system) | last_row(trace_log_count) | last_row(mem_free) |
======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
@ -288,22 +288,22 @@ $ curl http://127.0.0.1:6043/metrics
部分结果集:
```shell
# HELP taos_cluster_info_connections_total
# HELP taos_cluster_info_connections_total
# TYPE taos_cluster_info_connections_total counter
taos_cluster_info_connections_total{cluster_id="554014120921134497"} 8
# HELP taos_cluster_info_dbs_total
# HELP taos_cluster_info_dbs_total
# TYPE taos_cluster_info_dbs_total counter
taos_cluster_info_dbs_total{cluster_id="554014120921134497"} 2
# HELP taos_cluster_info_dnodes_alive
# HELP taos_cluster_info_dnodes_alive
# TYPE taos_cluster_info_dnodes_alive counter
taos_cluster_info_dnodes_alive{cluster_id="554014120921134497"} 1
# HELP taos_cluster_info_dnodes_total
# HELP taos_cluster_info_dnodes_total
# TYPE taos_cluster_info_dnodes_total counter
taos_cluster_info_dnodes_total{cluster_id="554014120921134497"} 1
# HELP taos_cluster_info_first_ep
# HELP taos_cluster_info_first_ep
# TYPE taos_cluster_info_first_ep gauge
taos_cluster_info_first_ep{cluster_id="554014120921134497",value="tdengine:6030"} 1
# HELP taos_cluster_info_first_ep_dnode_id
# HELP taos_cluster_info_first_ep_dnode_id
# TYPE taos_cluster_info_first_ep_dnode_id counter
taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
```
@ -365,12 +365,12 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
| taos_dnodes_info_has_qnode | counter | 是否有 qnode |
| taos_dnodes_info_has_snode | counter | 是否有 snode |
| taos_dnodes_info_io_read | gauge | 该 dnode 所在节点的 io 读取速率(单位 Byte/s) |
| taos_dnodes_info_io_read_disk | gauge | 该 dnode 所在节点的磁盘 io 写入速率(单位 Byte/s) |
| taos_dnodes_info_io_write | gauge | 该 dnode 所在节点的 io 写入速率(单位 Byte/s) |
| taos_dnodes_info_io_write_disk | gauge | 该 dnode 所在节点的磁盘 io 写入速率(单位 Byte/s) |
| taos_dnodes_info_io_read_disk | gauge | 该 dnode 所在节点的磁盘 io 写入速率(单位 Byte/s) |
| taos_dnodes_info_io_write | gauge | 该 dnode 所在节点的 io 写入速率(单位 Byte/s) |
| taos_dnodes_info_io_write_disk | gauge | 该 dnode 所在节点的磁盘 io 写入速率(单位 Byte/s) |
| taos_dnodes_info_masters | counter | 主节点数量 |
| taos_dnodes_info_mem_engine | counter | 该 dnode 的进程所使用的内存(单位 KB) |
| taos_dnodes_info_mem_system | counter | 该 dnode 所在节的系统所使用的内存(单位 KB) |
| taos_dnodes_info_mem_system | counter | 该 dnode 所在节的系统所使用的内存(单位 KB) |
| taos_dnodes_info_mem_total | counter | 该 dnode 所在节点的总内存(单位 KB) |
| taos_dnodes_info_net_in | gauge | 该 dnode 所在节点的网络传入速率(单位 Byte/s) |
| taos_dnodes_info_net_out | gauge | 该 dnode 所在节点的网络传出速率(单位 Byte/s) |
@ -511,7 +511,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
- `database_name`: 数据库名称
- `vgroup_id`: 虚拟组 id
- **类型**: gauge
- **含义**: 虚拟组状态。 0 为 unsynced表示没有leader选出1 为 ready。
- **含义**: 虚拟组状态。 0 为 unsynced表示没有 leader 选出1 为 ready。
##### taos_taosd_vgroups_info_tables_num
@ -532,7 +532,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
- `vgroup_id`: 虚拟组 id
- **类型**: gauge
- **含义**: 虚拟节点角色
### 抽取配置
Prometheus 提供了 `scrape_configs` 配置如何从 endpoint 抽取监控数据,通常只需要修改 `static_configs` 中的 targets 配置为 taoskeeper 的 endpoint 地址,更多配置信息请参考 [Prometheus 配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)。
@ -558,13 +558,13 @@ scrape_configs:
taosKeeper 也会将自己采集的监控数据写入监控数据库,默认是 `log` 库,可以在 taoskeeper 配置文件中修改。
### keeper\_monitor 表
### keeper_monitor 表
`keeper_monitor` 记录 taoskeeper 监控数据。
| field | type | is\_tag | comment |
| :------- | :-------- | :------ | :----------- |
| ts | TIMESTAMP | | timestamp |
| cpu | DOUBLE | | cpu 使用率 |
| mem | DOUBLE | | 内存使用率 |
| identify | NCHAR | TAG | 身份标识信息 |
| field | type | is_tag | comment |
| :------- | :-------- | :----- | :----------- |
| ts | TIMESTAMP | | timestamp |
| cpu | DOUBLE | | cpu 使用率 |
| mem | DOUBLE | | 内存使用率 |
| identify | NCHAR | TAG | 身份标识信息 |

View File

@ -225,3 +225,5 @@ sc.exe stop taos-explorer # Windows
登录时,请使用数据库用户名和密码登录。首次使用,默认的用户名为 `root`,密码为 `taosdata`。登录成功后即可进入`数据浏览器`页面,您可以使用查看数据库、 创建数据库、创建超级表/子表等管理功能。
其他功能页面,如`数据写入-数据源`等页面,为企业版特有功能,您可以点击查看和简单体验,并不能实际使用。
如果由于网络原因无法完成注册环节,则需要在有外网的环境注册完毕,然后把注册好的 /etc/taos/explorer-register.cfg 替换到内网环境。

View File

@ -218,7 +218,7 @@ ALTER TABLE tb_name COMMENT 'string_value'
DROP TABLE [IF EXISTS] [db_name.]tb_name [, [IF EXISTS] [db_name.]tb_name] ...
```
**注意**:删除表并不会立即释放该表所占用的磁盘空间,而是把该表的数据标记为已删除,在查询时这些数据将不会再出现,但释放磁盘空间会延迟到系统自动或用户手动进行数据重整时。
**注意**:删除表并不会立即释放该表所占用的磁盘空间,而是把该表的数据标记为已删除,在查询时这些数据将不会再出现,但释放磁盘空间会延迟到系统自动(建库参数 keep 生效)或用户手动进行数据重整时(企业版功能 compact
## 查看表的信息

View File

@ -491,15 +491,15 @@ SELECT ... FROM (SELECT ... FROM ...) ...;
:::
## UNION ALL 子句
## UNION 子句
```txt title=语法
SELECT ...
UNION ALL SELECT ...
[UNION ALL SELECT ...]
UNION [ALL] SELECT ...
[UNION [ALL] SELECT ...]
```
TDengine 支持 UNION ALL 操作符。也就是说,如果多个 SELECT 子句返回结果集的结构完全相同(列名、列类型、列数、顺序),那么可以通过 UNION ALL 把这些结果集合并到一起。目前只支持 UNION ALL 模式,也即在结果集的合并过程中是不去重的。在同一个 sql 语句中UNION ALL 最多支持 100 个。
TDengine 支持 UNION [ALL] 操作符。也就是说,如果多个 SELECT 子句返回结果集的结构完全相同(列名、列类型、列数、顺序),那么可以通过 UNION [ALL] 把这些结果集合并到一起。
## SQL 示例

View File

@ -231,6 +231,7 @@ description: TDengine 保留关键字的详细列表
| LEADER | |
| LEADING | |
| LEFT | |
| LEVEL | 3.3.0.0 到 3.3.2.11 的所有版本 |
| LICENCES | |
| LIKE | |
| LIMIT | |

View File

@ -4,7 +4,10 @@ title: 窗口预聚集
description: 窗口预聚集使用说明
---
为了提高大数据量的聚合函数查询性能,通过创建窗口预聚集 (TSMA Time-Range Small Materialized Aggregates) 对象, 使用固定时间窗口对指定的聚集函数进行预计算,并将计算结果存储下来,查询时通过查询预计算结果以提高查询性能。
在大数据量场景下, 经常需要查询某段时间内的汇总结果, 当历史数据变多或者时间范围变大时, 查询时间也会相应增加. 通过预聚集的方式可以将计算结果提前存储下来, 后续查询可以直接读取聚集结果, 而不需要扫描原始数据, 如当前Block内的SMA (Small Materialized Aggregates)信息.
Block内的SMA信息粒度较小, 若查询时间范围是日,月甚至年时, Block的数量将会很多, 因此TSMA (Time-Range Small Materialized Aggregates)支持用户指定时间窗口进行预聚集. 通过对固定时间窗口内的数据进行预计算, 并将计算结果存储下来, 查询时通过查询预计算结果以提高查询性能。
![TSMA Introduction](./pic/TSMA_intro.png)
## 创建TSMA

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -509,7 +509,7 @@ TDengine 推荐数据库应用的每个线程都建立一个独立的连接,
- **接口说明**:用于轮询消费数据,每一个消费者,只能单线程调用该接口。
- tmq[入参] 指向一个有效的 ws_tmq_t 结构体指针,该结构体代表一个 TMQ 消费者对象。
- timeout[入参] 轮询的超时时间单位为毫秒负数表示默认超时1秒。
- **返回值**:非 `NULL`:成功,返回一个指向 WS_RES 结构体的指针,该结构体包含了接收到的消息。`NULL`失败,表示没有数据。WS_RES 结果和 taos_query 返回结果一致,可通过查询的各种接口获取 WS_RES 里的信息,比如 schema 等。
- **返回值**:非 `NULL`:成功,返回一个指向 WS_RES 结构体的指针,该结构体包含了接收到的消息。`NULL`:表示没有数据, 可通过 ws_errno(NULL) 获取错误码,具体错误码参见参考手册。WS_RES 结果和 taos_query 返回结果一致,可通过查询的各种接口获取 WS_RES 里的信息,比如 schema 等。
- `int32_t ws_tmq_consumer_close(ws_tmq_t *tmq)`
- **接口说明**:用于关闭 ws_tmq_t 结构体。需与 ws_tmq_consumer_new 配合使用。
@ -1125,11 +1125,8 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
- conf[入参] 指向一个有效的 tmq_conf_t 结构体指针,该结构体代表一个 TMQ 配置对象。
- cb[入参] 指向一个有效的 tmq_commit_cb 回调函数指针,该函数将在消息被消费后调用以确认消息处理状态。
- param[入参] 传递给回调函数的用户自定义参数。
设置自动提交回调函数的定义如下:
```
typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param))
```
- 设置自动提交回调函数的定义如下:
`typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param))`
- `void tmq_conf_destroy(tmq_conf_t *conf)`
- **接口说明**:销毁一个 TMQ 配置对象并释放相关资源。
@ -1192,7 +1189,7 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
- `int32_t tmq_consumer_close(tmq_t *tmq)`
- **接口说明**:用于关闭 tmq_t 结构体。需与 tmq_consumer_new 配合使用。
- tmq[入参] 指向一个有效的 tmq_t 结构体指针,该结构体代表一个 TMQ 消费者对象。
- **返回值**`0`:成功。非 `0`:失败,可调用函数 `char *tmq_err2str(int32_t code)` 获取更详细的错误信息
- **返回值**非 `NULL`:成功,返回一个指向 TAOS_RES 结构体的指针,该结构体包含了接收到的消息。。`NULL`表示没有数据可通过taos_errno(NULL) 获取错误码具体错误码参见参考手册。TAOS_RES 结果和 taos_query 返回结果一致,可通过查询的各种接口获取 TAOS_RES 里的信息,比如 schema 等
- `int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, int32_t *numOfAssignment)`
- **接口说明**:返回当前 consumer 分配的 vgroup 的信息,每个 vgroup 的信息包括 vgIdwal 的最大最小 offset以及当前消费到的 offset。
@ -1243,11 +1240,6 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
- cb[入参] 一个回调函数指针,当提交完成时会被调用。
- param[入参] 一个用户自定义的参数,将在回调函数中传递给 cb。
**说明**
- commit接口分为两种类型每种类型有同步和异步接口
- 第一种类型:根据消息提交,提交消息里的进度,如果消息传 NULL提交当前 consumer 所有消费的 vgroup 的当前进度 : tmq_commit_sync/tmq_commit_async
- 第二种类型:根据某个 topic 的某个 vgroup 的 offset 提交 : tmq_commit_offset_sync/tmq_commit_offset_async
- `int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId)`
- **接口说明**:获取当前消费位置,即已消费到的数据位置的下一个位置.
- tmq[入参] 指向一个有效的 tmq_t 结构体指针,该结构体代表一个 TMQ 消费者对象。
@ -1255,7 +1247,7 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
- vgId[入参] 虚拟组 vgroup 的 ID。
- **返回值**`>=0`:成功,返回一个 int64_t 类型的值,表示当前位置的偏移量。`<0`:失败,返回值就是错误码,可调用函数 `char *tmq_err2str(int32_t code)` 获取更详细的错误信息。
- `int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)`
- `int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)`
- **接口说明**:将 TMQ 消费者对象在某个特定 topic 和 vgroup 的偏移量设置到指定的位置。
- tmq[入参] 指向一个有效的 tmq_t 结构体指针,该结构体代表一个 TMQ 消费者对象。
- pTopicName[入参] 要查询当前位置的主题名称。
@ -1288,14 +1280,14 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
- res[入参] 指向一个有效的 TAOS_RES 结构体指针,该结构体包含了从 TMQ 消费者轮询得到的消息。
- **返回值**:返回一个 tmq_res_t 类型的枚举值,表示消息类型。
- tmq_res_t 表示消费到的数据类型,定义如下:
```
typedef enum tmq_res_t {
TMQ_RES_INVALID = -1, // 无效
TMQ_RES_DATA = 1, // 数据类型
TMQ_RES_TABLE_META = 2, // 元数据类型
TMQ_RES_METADATA = 3 // 既有元数据类型又有数据类型,即自动建表
} tmq_res_t;
```
```
typedef enum tmq_res_t {
TMQ_RES_INVALID = -1, // 无效
TMQ_RES_DATA = 1, // 数据类型
TMQ_RES_TABLE_META = 2, // 元数据类型
TMQ_RES_METADATA = 3 // 既有元数据类型又有数据类型,即自动建表
} tmq_res_t;
```
- `const char *tmq_get_topic_name(TAOS_RES *res)`
- **接口说明**:从 TMQ 消费者获取的消息结果中获取所属的 topic 名称。

View File

@ -24,6 +24,7 @@ import RequestId from "./_request_id.mdx";
| Connector 版本 | 主要变化 | TDengine 版本 |
|:-------------|:---------------------------|:--------------|
| 3.1.5 | 修复 websocket 协议编码中文时长度错误 | - |
| 3.1.4 | 提升 websocket 查询和写入性能 | 3.3.2.0 及更高版本 |
| 3.1.3 | 支持 WebSocket 自动重连 | - |
| 3.1.2 | 修复 schemaless 资源释放 | - |

View File

@ -118,7 +118,7 @@ TDengine ODBC 支持两种连接 TDengine 数据库方式WebSocket 连接与
| v1.1.0 | 1. 支持视图功能;<br/>2. 支持 VARBINARY/GEOMETRY 数据类型;<br/>3. 支持 ODBC 32 位 WebSocket 连接方式(仅企业版支持);<br/>4. 支持 ODBC 数据源配置对话框设置对工业软件 KingSCADA、Kepware 等的兼容性适配选项(仅企业版支持); | 3.3.3.0 及更高版本 |
| v1.0.2 | 支持 CP1252 字符编码; | 3.2.3.0 及更高版本 |
| v1.0.1 | 1. 支持 DSN 设置 BI 模式,在 BI 模式下 TDengine 数据库不返回系统数据库和超级表子表信息;<br/>2. 重构字符集转换模块,提升读写性能;<br/>3. ODBC 数据源配置对话框中默认修改默认连接方式为“WebSocket”<br/>4. ODBC 数据源配置对话框增加“测试连接”控件;<br/>5. ODBC 数据源配置支持中文/英文界面; | - |
| v1.0.0.0 | 发布初始版本,支持与Tdengine数据库交互以读写数据具体请参考“API 参考”一节 | 3.2.2.0 及更高版本 |
| v1.0.0.0 | 发布初始版本,支持与 TDengine 数据库交互以读写数据具体请参考“API 参考”一节 | 3.2.2.0 及更高版本 |
## 数据类型映射

View File

@ -253,7 +253,7 @@ C 接口网络不可用相关错误码:
- code`int`0 代表成功。
- column_meta`[][3]any` 列信息每个列会用三个值来说明分别为列名string、列类型string、类型长度int
- rows`int`)数据返回行数。
- data`[][]any`)具体数据内容(时间格式仅支持 RFC3339结果集为 0 时区)。
- data`[][]any`)具体数据内容(时间格式仅支持 RFC3339结果集为 0 时区,指定 tz 时返回对应时区)。
列类型使用如下字符串:
@ -435,7 +435,6 @@ curl http://<fqnd>:<port>/rest/login/<username>/<password>
其中,`fqdn` 是 TDengine 数据库的 FQDN 或 IP 地址,`port` 是 TDengine 服务的端口号,`username` 为数据库用户名,`password` 为数据库密码,返回值为 JSON 格式,各字段含义如下:
- status请求结果的标志位。
- code返回值代码。
- desc授权码。

View File

@ -554,5 +554,6 @@ description: TDengine 服务端的错误码列表和详细说明
| 0x80004000 | Invalid message | 订阅到的数据非法,一般不会出现 | 具体查看client端的错误日志提示 |
| 0x80004001 | Consumer mismatch | 订阅请求的vnode和重新分配的vnode不一致一般存在于有新消费者加入相同消费者组里时 | 内部错误,不暴露给用户 |
| 0x80004002 | Consumer closed | 消费者已经不存在了 | 查看是否已经close掉了 |
| 0x80004017 | Invalid status, please subscribe topic first | 数据订阅状态不对 | 没有调用 subscribe直接poll数据 |
| 0x80004100 | Stream task not exist | 流计算任务不存在 | 具体查看server端的错误日志 |

View File

@ -18,9 +18,9 @@ taosc 的执行过程可以简要总结为:解析 SQL 为 AST生成逻辑
### mnode
在 TDengine 集群中超级表的信息和元数据库的基础信息都得到妥善管理。mnode 为元数据服务器,负责响应 taosc 的元数据查询请求。当 taosc 需要获取 vgroup 等元数据信息时,它会向 mnode 发送请求。mnode 在收到请求后,会迅速返回所需的信息,确保 taosc 能够顺利执行其操作。
在 TDengine 集群中超级表的信息和元数据库的基础信息都得到妥善管理。mnode 为元数据服务器,负责响应 taosc 的元数据查询请求。当 taosc 需要获取 vgroup 等元数据信息时,它会向 mnode 发送请求。mnode 在收到请求后,会迅速返回所需的信息,确保 taosc 能够顺利执行其操作。
此外mnode 还负责接收 taosc 发送的心跳信息。这些心跳信息有助于维持 aosc 与 mnode 之间的连接状态,确保两者之间的通信畅通无阻。
此外mnode 还负责接收 taosc 发送的心跳信息。这些心跳信息有助于维持 taosc 与 mnode 之间的连接状态,确保两者之间的通信畅通无阻。
### vnode

View File

@ -24,6 +24,10 @@ TDengine 3.x 各版本安装包下载链接如下:
import Release from "/components/ReleaseV3";
## 3.3.5.0
<Release type="tdengine" version="3.3.5.0" />
## 3.3.4.8
<Release type="tdengine" version="3.3.4.8" />

View File

@ -0,0 +1,84 @@
---
title: 3.3.5.0 版本说明
sidebar_label: 3.3.5.0
description: 3.3.5.0 版本说明
---
## 特性
1. 特性MQTT 稳定性和性能提升
2. 特性taosX 增量备份与恢复
3. 特性JDBC WebSocket 连接支持 STMT2 接口
4. 特性Rust 连接器支持 STMT2 接口
5. 特性taos-CLI 中在错误提示中增加错误码
6. 特性Python 连接器对接 SuperSet
7. 特性Explorer 可配置 Grafana Dashboard
8. 特性taosX-agent 支持配置内存缓存队列长度
## 优化
1. 优化:调整 telemerty 的上报机制
2. 优化:支持通过 SQL 统计指定 DB 的磁盘空间
3. 优化:在服务端增加查询内存管控
4. 优化INTERVAL 子句允许使用 AUTO 关键字来指定自动计算窗口偏移量
5. 优化:减少在多级存储迁移数据时对数据写入性能的影响
6. 优化Grafana 插件 UI 转为 React 以完整适配 11.3.0 版本
7. 优化taosAdapter websocket 接口优化
8. 优化taosX 添加健康状态
9. 优化taosX 支持可配置的异常数据处理
10. 优化:支持为客户端连接设置选项,包括时区、字符集、用户 IP、用户名称
11. 优化taosdump 支持查询超时或连接端开时自动重连
12. 优化:允许为已经订阅的 tag 列创建索引
13. 优化taosX 支持密码中包含特殊字符
14. 优化:提升开启 Last 缓存时的数据写入性能
15. 优化COMPACT 命令支持自动执行、并发度设置及执行进度观测
16. 优化:支持通过 SQL 语句修改全局配置参数并持久化
17. 优化:更新各数据类型的压缩算法默认值,提高大部分场景的压缩比
18. 优化taosBenchmark 在 Mac/Windows 上 --nodrop 参数行为修复
19. 优化:禁止 DB 内 Compact 和副本变更相关操作同时进行(企业版)
20. 优化taosdump 支持复合主键表导出
21. 优化:支持在 show queries 和 show connections 语句的返回结果中显示用户 IP 和用户名称
22. 优化JDBC 支持多表批量写入
23. 优化:支持对多级存储中的 dataDir 参数进行动态调整。
24. 优化taosX 数据库文件默认使用 data_dir
25. 优化:强制要求用户设置强密码,密码长度必须为 8 到 16 位,并且至少包含大写字母、小写字母、数字、特殊字符中的三类
26. 优化:提高客户端获取新 Leader 的速度
27. 优化OPC 点位正则匹配支持 “非”
## 修复
1. 修复:流计算在高负载场景下更新 checkpoint 时可能出现死锁
2. 修复TMQ 同步目标端报错无法恢复的问题
3. 修复WAL 中的某个数据块校验失败时 taosd 无法启动的问题
4. 修复taosBenchmark 多副本下节点宕机写入失败
5. 修复:日志文件切换频繁时日志文件可能丢失的问题
6. 修复:窗口内数据更新导致流计算停止的问题
7. 修复libtaosws.so 读取数据时如果连接中端,错误码设置有误
8. 修复OPC 数据点位以 @ 开头时解析错误
9. 修复taosBenchmark 解决云服务下show vgroups 权限问题
10. 修复taosX 迁移支持列压缩的超宽超级表时报语法错误
11. 修复Vnode 占用内存估算错误的问题
12. 修复:对 varchar 类型的常量字符串进行 union all 查询时失败的问题
13. 修复:执行事务期间切换 leader 会导致 mnode 死锁
14. 修复ws_stmt_get_tag_fields 返回地址非法
15. 修复UNION 语句中存在包含多个 NULL 的子查询时执行报错
16. 修复:流计算的暂停操作可能失败的问题
17. 修复:通过 SQL 语句将数据写入一个表名长度为192个字符的子表时如果表名被反引号`)包围,可能会导致错误
18. 修复:在对不同数据库的超级表进行联合查询时,如果两个数据库各自仅包含一个虚拟节点,查询将返回错误。
19. 修复:磁盘空间不足时 taosX panic 导致任务无法恢复
20. 修复:在向超级表中写入数据的过程中,如果同时使用了绑定和非绑定的方式,将会引发异常
21. 修复:特殊情况下 taosX agent 连接时 metrics 不存在导致panic
22. 修复为字符长度较大的标签数据创建索引时taosd 可能 crash
23. 修复:当函数 first、last、last_row 和 char 的输入参数超过 127 时taosd 可能会崩溃的问题 https://github.com/taosdata/TDengine/issues/29241
24. 修复Limit 语句的结果集条数超过一个数据块时,返回条数和预期不符合
25. 修复:集群间数据同步时,如果删除掉目标集群任务,源集群可能 OOM
26. 修复:元数据读写锁设置错误导致有极小几率阻塞写入的问题
27. 修复:在 Windows 平台上使用 INSERT INTO 语句导入 CSV 文件时,如果文件末尾没有换行符,可能会导致无限循环读取的问题
28. 修复:在源表的标签更新后,流计算未能识别并应用新的标签值
29. 修复:调整 Kafka 订阅参数提升 Kakfa 数据写入性能和稳定性
30. 修复SQL 查询中同时包含 is null 和无效的 in 筛选条件时,查询结果有误 https://github.com/taosdata/TDengine/issues/29067
31. 修复SQL 查询中同时包含 in 和 between 筛选条件时,查询结果有误 https://github.com/taosdata/TDengine/issues/28989
32. 修复timestamp 类型和数值类型进行乘除运算时结果有误 https://github.com/taosdata/TDengine/issues/28339
33. 修复IN 条件中的数据类型转换错误导致查询结果不正确 https://github.com/taosdata/TDengine/issues/29047 https://github.com/taosdata/TDengine/issues/28902
34. 修复:常量条件和 OR 运算符结合时筛选结果错误 https://github.com/taosdata/TDengine/issues/28904
35. 修复:对时间戳类型进行减法运算时未考虑负值的情况 https://github.com/taosdata/TDengine/issues/28906
36. 修复GROUP BY tag 时某些标签值显示错误的问题
37. 修复:旧版本 GCC Bug 导致编译失败

View File

@ -4,6 +4,7 @@ sidebar_label: 版本说明
description: 各版本版本说明
---
[3.3.5.0](./3.3.5.0)
[3.3.4.8](./3.3.4.8)
[3.3.4.3](./3.3.4.3)
[3.3.3.0](./3.3.3.0)

View File

@ -123,6 +123,10 @@ enum {
TMQ_MSG_TYPE__POLL_BATCH_META_RSP,
};
static char* tmqMsgTypeStr[] = {
"data", "meta", "ask ep", "meta data", "wal info", "batch meta"
};
enum {
STREAM_INPUT__DATA_SUBMIT = 1,
STREAM_INPUT__DATA_BLOCK,

View File

@ -57,9 +57,9 @@ const static uint8_t BIT2_MAP[4] = {0b11111100, 0b11110011, 0b11001111, 0b001111
#define ONE ((uint8_t)1)
#define THREE ((uint8_t)3)
#define DIV_8(i) ((i) >> 3)
#define MOD_8(i) ((i) & 7)
#define MOD_8(i) ((i)&7)
#define DIV_4(i) ((i) >> 2)
#define MOD_4(i) ((i) & 3)
#define MOD_4(i) ((i)&3)
#define MOD_4_TIME_2(i) (MOD_4(i) << 1)
#define BIT1_SIZE(n) (DIV_8((n)-1) + 1)
#define BIT2_SIZE(n) (DIV_4((n)-1) + 1)
@ -201,8 +201,10 @@ int32_t tColDataSortMerge(SArray **arr);
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap,
char *data);
// for encode/decode
int32_t tPutColData(uint8_t version, uint8_t *pBuf, SColData *pColData);
int32_t tGetColData(uint8_t version, uint8_t *pBuf, SColData *pColData);
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData);
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData);
int32_t tEncodeRow(SEncoder *pEncoder, SRow *pRow);
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow);
// STRUCT ================================
struct STColumn {

View File

@ -261,6 +261,7 @@
TD_DEF_MSG_TYPE(TDMT_MND_UPDATE_DNODE_INFO, "update-dnode-info", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_AUDIT, "audit", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_CONFIG, "init-config", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_CONFIG_SDB, "config-sdb", NULL, NULL)
TD_CLOSE_MSG_SEG(TDMT_END_MND_MSG)
TD_NEW_MSG_SEG(TDMT_VND_MSG) // 2<<8

View File

@ -374,7 +374,7 @@ void* getTaskPoolWorkerCb();
((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR || \
(_code) == TSDB_CODE_VND_STOPPED || (_code) == TSDB_CODE_APP_IS_STARTING || (_code) == TSDB_CODE_APP_IS_STOPPING)
#define SYNC_SELF_LEADER_REDIRECT_ERROR(_code) \
((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_RESTORING || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR)
((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_RESTORING || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR || (_code) == TSDB_CODE_SYN_TIMEOUT)
#define SYNC_OTHER_LEADER_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_MNODE_NOT_FOUND)
#define NO_RET_REDIRECT_ERROR(_code) \

View File

@ -176,7 +176,9 @@ typedef struct SSyncFSM {
void (*FpRollBackCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SFsmCbMeta* pMeta);
void (*FpRestoreFinishCb)(const struct SSyncFSM* pFsm, const SyncIndex commitIdx);
void (*FpAfterRestoredCb)(const struct SSyncFSM* pFsm, const SyncIndex commitIdx);
void (*FpReConfigCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SReConfigCbMeta* pMeta);
void (*FpLeaderTransferCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SFsmCbMeta* pMeta);
bool (*FpApplyQueueEmptyCb)(const struct SSyncFSM* pFsm);
int32_t (*FpApplyQueueItems)(const struct SSyncFSM* pFsm);

View File

@ -47,6 +47,7 @@ const char* terrstr();
char* taosGetErrMsgReturn();
char* taosGetErrMsg();
void taosClearErrMsg();
int32_t* taosGetErrno();
int32_t* taosGetErrln();
int32_t taosGetErrSize();
@ -1013,6 +1014,7 @@ int32_t taosGetErrSize();
#define TSDB_CODE_TMQ_REPLAY_NOT_SUPPORT TAOS_DEF_ERROR_CODE(0, 0x4014)
#define TSDB_CODE_TMQ_NO_TABLE_QUALIFIED TAOS_DEF_ERROR_CODE(0, 0x4015)
#define TSDB_CODE_TMQ_NO_NEED_REBALANCE TAOS_DEF_ERROR_CODE(0, 0x4016)
#define TSDB_CODE_TMQ_INVALID_STATUS TAOS_DEF_ERROR_CODE(0, 0x4017)
// stream
#define TSDB_CODE_STREAM_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x4100)

View File

@ -558,6 +558,7 @@ typedef enum ELogicConditionType {
#define TSDB_QUERY_CLEAR_TYPE(x, _type) ((x) &= (~_type))
#define TSDB_QUERY_RESET_TYPE(x) ((x) = TSDB_QUERY_TYPE_NON_TYPE)
#define TSDB_ORDER_NONE 0
#define TSDB_ORDER_ASC 1
#define TSDB_ORDER_DESC 2
@ -664,6 +665,14 @@ typedef enum {
ANAL_ALGO_TYPE_END,
} EAnalAlgoType;
typedef enum {
TSDB_VERSION_UNKNOWN = 0,
TSDB_VERSION_OSS,
TSDB_VERSION_ENTERPRISE,
TSDB_VERSION_CLOUD,
TSDB_VERSION_END,
} EVersionType;
#define MIN_RESERVE_MEM_SIZE 1024 // MB
#ifdef __cplusplus

View File

@ -118,6 +118,7 @@ static int32_t tDecodeI64v(SDecoder* pCoder, int64_t* val);
static int32_t tDecodeFloat(SDecoder* pCoder, float* val);
static int32_t tDecodeDouble(SDecoder* pCoder, double* val);
static int32_t tDecodeBool(SDecoder* pCoder, bool* val);
static int32_t tDecodeBinaryWithSize(SDecoder* pCoder, uint32_t size, uint8_t** val);
static int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint32_t* len);
static int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len);
static int32_t tDecodeCStr(SDecoder* pCoder, char** val);
@ -404,6 +405,19 @@ static int32_t tDecodeBool(SDecoder* pCoder, bool* val) {
return 0;
}
static FORCE_INLINE int32_t tDecodeBinaryWithSize(SDecoder* pCoder, uint32_t size, uint8_t** val) {
if (pCoder->pos + size > pCoder->size) {
TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
}
if (val) {
*val = pCoder->data + pCoder->pos;
}
pCoder->pos += size;
return 0;
}
static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint32_t* len) {
uint32_t length = 0;
@ -412,21 +426,12 @@ static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint3
*len = length;
}
if (pCoder->pos + length > pCoder->size) {
TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
}
if (val) {
*val = pCoder->data + pCoder->pos;
}
pCoder->pos += length;
return 0;
TAOS_RETURN(tDecodeBinaryWithSize(pCoder, length, val));
}
static FORCE_INLINE int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len) {
TAOS_CHECK_RETURN(tDecodeBinary(pCoder, (uint8_t**)val, len));
if (*len > 0) { // notice!!! *len maybe 0
if (*len > 0) { // notice!!! *len maybe 0
(*len) -= 1;
}
return 0;
@ -497,7 +502,7 @@ static FORCE_INLINE int32_t tDecodeBinaryAlloc32(SDecoder* pCoder, void** val, u
static FORCE_INLINE int32_t tDecodeCStrAndLenAlloc(SDecoder* pCoder, char** val, uint64_t* len) {
TAOS_CHECK_RETURN(tDecodeBinaryAlloc(pCoder, (void**)val, len));
if (*len > 0){
if (*len > 0) {
(*len) -= 1;
}
return 0;

View File

@ -119,6 +119,11 @@ void taosLogCrashInfo(char *nodeType, char *pMsg, int64_t msgLen, int signum, vo
void taosReadCrashInfo(char *filepath, char **pMsg, int64_t *pMsgLen, TdFilePtr *pFd);
void taosReleaseCrashLogFile(TdFilePtr pFile, bool truncateFile);
int32_t initCrashLogWriter();
void checkAndPrepareCrashInfo();
bool reportThreadSetQuit();
void writeCrashLogToFile(int signum, void *sigInfo, char *nodeType, int64_t clusterId, int64_t startTime);
// clang-format off
#define uFatal(...) { if (uDebugFlag & DEBUG_FATAL) { taosPrintLog("UTL FATAL", DEBUG_FATAL, tsLogEmbedded ? 255 : uDebugFlag, __VA_ARGS__); }}
#define uError(...) { if (uDebugFlag & DEBUG_ERROR) { taosPrintLog("UTL ERROR ", DEBUG_ERROR, tsLogEmbedded ? 255 : uDebugFlag, __VA_ARGS__); }}

View File

@ -15,7 +15,7 @@ TimeoutStartSec=0
StandardOutput=null
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
StartLimitInterval=900s
[Install]
WantedBy=multi-user.target

View File

@ -16,6 +16,7 @@ verType=$7
script_dir="$(dirname $(readlink -f $0))"
top_dir="$(readlink -f ${script_dir}/../..)"
pkg_dir="${top_dir}/debworkroom"
taosx_dir="$(readlink -f ${script_dir}/../../../../taosx)"
#echo "curr_dir: ${curr_dir}"
#echo "top_dir: ${top_dir}"
@ -81,11 +82,11 @@ fi
if [ -f "${compile_dir}/test/cfg/taoskeeper.service" ]; then
cp ${compile_dir}/test/cfg/taoskeeper.service ${pkg_dir}${install_home_path}/cfg || :
fi
if [ -f "${compile_dir}/../../../explorer/target/taos-explorer.service" ]; then
cp ${compile_dir}/../../../explorer/target/taos-explorer.service ${pkg_dir}${install_home_path}/cfg || :
if [ -f "${taosx_dir}/explorer/server/examples/explorer.service" ]; then
cp ${taosx_dir}/explorer/server/examples/explorer.service ${pkg_dir}${install_home_path}/cfg/taos-explorer.service || :
fi
if [ -f "${compile_dir}/../../../explorer/server/example/explorer.toml" ]; then
cp ${compile_dir}/../../../explorer/server/example/explorer.toml ${pkg_dir}${install_home_path}/cfg || :
if [ -f "${taosx_dir}/explorer/server/examples/explorer.toml" ]; then
cp ${taosx_dir}/explorer/server/examples/explorer.toml ${pkg_dir}${install_home_path}/cfg || :
fi
# cp ${taoskeeper_binary} ${pkg_dir}${install_home_path}/bin
@ -113,8 +114,8 @@ if [ -f "${compile_dir}/build/bin/taoskeeper" ]; then
cp ${compile_dir}/build/bin/taoskeeper ${pkg_dir}${install_home_path}/bin ||:
fi
if [ -f "${compile_dir}/../../../explorer/target/release/taos-explorer" ]; then
cp ${compile_dir}/../../../explorer/target/release/taos-explorer ${pkg_dir}${install_home_path}/bin ||:
if [ -f "${taosx_dir}/target/release/taos-explorer" ]; then
cp ${taosx_dir}/target/release/taos-explorer ${pkg_dir}${install_home_path}/bin ||:
fi
cp ${compile_dir}/build/bin/taos ${pkg_dir}${install_home_path}/bin

View File

@ -17,6 +17,7 @@ verType=$7
script_dir="$(dirname $(readlink -f $0))"
top_dir="$(readlink -f ${script_dir}/../..)"
pkg_dir="${top_dir}/rpmworkroom"
taosx_dir="$(readlink -f ${script_dir}/../../../../taosx)"
spec_file="${script_dir}/tdengine.spec"
#echo "curr_dir: ${curr_dir}"
@ -76,7 +77,7 @@ cd ${pkg_dir}
${csudo}mkdir -p BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
${csudo}rpmbuild --define="_version ${tdengine_ver}" --define="_topdir ${pkg_dir}" --define="_compiledir ${compile_dir}" -bb ${spec_file}
${csudo}rpmbuild --define="_version ${tdengine_ver}" --define="_topdir ${pkg_dir}" --define="_compiledir ${compile_dir}" --define="_taosxdir ${taosx_dir}" -bb ${spec_file}
# copy rpm package to output_dir, and modify package name, then clean temp dir
#${csudo}cp -rf RPMS/* ${output_dir}

View File

@ -76,12 +76,12 @@ if [ -f %{_compiledir}/test/cfg/taoskeeper.service ]; then
cp %{_compiledir}/test/cfg/taoskeeper.service %{buildroot}%{homepath}/cfg ||:
fi
if [ -f %{_compiledir}/../../../explorer/target/taos-explorer.service ]; then
cp %{_compiledir}/../../../explorer/target/taos-explorer.service %{buildroot}%{homepath}/cfg ||:
if [ -f %{_taosxdir}/explorer/server/examples/explorer.service ]; then
cp %{_taosxdir}/explorer/server/examples/explorer.service %{buildroot}%{homepath}/cfg/taos-explorer.service ||:
fi
if [ -f %{_compiledir}/../../../explorer/server/examples/explorer.toml ]; then
cp %{_compiledir}/../../../explorer/server/examples/explorer.toml %{buildroot}%{homepath}/cfg ||:
if [ -f %{_taosxdir}/explorer/server/examples/explorer.toml ]; then
cp %{_taosxdir}/explorer/server/examples/explorer.toml %{buildroot}%{homepath}/cfg ||:
fi
#cp %{_compiledir}/../packaging/rpm/taosd %{buildroot}%{homepath}/init.d
@ -100,8 +100,8 @@ cp %{_compiledir}/../../enterprise/packaging/stop-all.sh %{buildroot}%{homepath
sed -i "s/versionType=\"enterprise\"/versionType=\"community\"/g" %{buildroot}%{homepath}/bin/start-all.sh
sed -i "s/versionType=\"enterprise\"/versionType=\"community\"/g" %{buildroot}%{homepath}/bin/stop-all.sh
if [ -f %{_compiledir}/../../../explorer/target/release/taos-explorer ]; then
cp %{_compiledir}/../../../explorer/target/release/taos-explorer %{buildroot}%{homepath}/bin
if [ -f %{_taosxdir}/target/release/taos-explorer ]; then
cp %{_taosxdir}/target/release/taos-explorer %{buildroot}%{homepath}/bin
fi
if [ -f %{_compiledir}/build/bin//taoskeeper ]; then

View File

@ -1912,6 +1912,7 @@ TDinternal() {
install_maven_via_sdkman 3.9.9
install_node_via_nvm 16.20.2
install_python_via_pyenv 3.10.12
install_via_pip pandas psutil fabric2 requests faker simplejson toml pexpect tzlocal distro decorator loguru hyperloglog toml taospy taos-ws-py
}
# deploy TDgpt

View File

@ -553,7 +553,7 @@ function install_service_on_systemd() {
${csudo}bash -c "echo 'StandardOutput=null' >> ${taosd_service_config}"
${csudo}bash -c "echo 'Restart=always' >> ${taosd_service_config}"
${csudo}bash -c "echo 'StartLimitBurst=3' >> ${taosd_service_config}"
${csudo}bash -c "echo 'StartLimitInterval=60s' >> ${taosd_service_config}"
${csudo}bash -c "echo 'StartLimitInterval=900s' >> ${taosd_service_config}"
${csudo}bash -c "echo >> ${taosd_service_config}"
${csudo}bash -c "echo '[Install]' >> ${taosd_service_config}"
${csudo}bash -c "echo 'WantedBy=multi-user.target' >> ${taosd_service_config}"

View File

@ -90,7 +90,7 @@ fi
kill_service_of() {
_service=$1
pid=$(ps -ef | grep $_service | grep -v grep | grep -v $uninstallScript | awk '{print $2}')
pid=$(ps -C $_service | grep -v $uninstallScript | awk '{print $2}')
if [ -n "$pid" ]; then
${csudo}kill -9 $pid || :
fi

View File

@ -40,7 +40,7 @@ if command -v sudo > /dev/null; then
fi
function kill_client() {
pid=$(ps -ef | grep ${clientName2} | grep -v grep | grep -v $uninstallScript2 | awk '{print $2}')
pid=$(ps -C ${clientName2} | grep -v $uninstallScript2 | awk '{print $2}')
if [ -n "$pid" ]; then
${csudo}kill -9 $pid || :
fi

View File

@ -221,11 +221,8 @@ int stmtPrepare2(TAOS_STMT2 *stmt, const char *sql, unsigned long length
int stmtSetTbName2(TAOS_STMT2 *stmt, const char *tbName);
int stmtSetTbTags2(TAOS_STMT2 *stmt, TAOS_STMT2_BIND *tags);
int stmtBindBatch2(TAOS_STMT2 *stmt, TAOS_STMT2_BIND *bind, int32_t colIdx);
int stmtGetTagFields2(TAOS_STMT2 *stmt, int *nums, TAOS_FIELD_E **fields);
int stmtGetColFields2(TAOS_STMT2 *stmt, int *nums, TAOS_FIELD_E **fields);
int stmtGetStbColFields2(TAOS_STMT2 *stmt, int *nums, TAOS_FIELD_ALL **fields);
int stmtGetParamNum2(TAOS_STMT2 *stmt, int *nums);
int stmtGetParamTbName(TAOS_STMT2 *stmt, int *nums);
int stmtIsInsert2(TAOS_STMT2 *stmt, int *insert);
TAOS_RES *stmtUseResult2(TAOS_STMT2 *stmt);
const char *stmtErrstr2(TAOS_STMT2 *stmt);

View File

@ -43,7 +43,7 @@
#endif
#ifndef CUS_PROMPT
#define CUS_PROMPT "tao"
#define CUS_PROMPT "taos"
#endif
#define TSC_VAR_NOT_RELEASE 1
@ -831,9 +831,17 @@ static void *tscCrashReportThreadFp(void *param) {
return NULL;
}
code = initCrashLogWriter();
if (code) {
tscError("failed to init crash log writer, code:%s", tstrerror(code));
return NULL;
}
while (1) {
if (clientStop > 0) break;
checkAndPrepareCrashInfo();
if (clientStop > 0 && reportThreadSetQuit()) break;
if (loopTimes++ < reportPeriodNum) {
if (loopTimes < 0) loopTimes = reportPeriodNum;
taosMsleep(sleepTime);
continue;
}
@ -921,21 +929,7 @@ void tscStopCrashReport() {
}
void tscWriteCrashInfo(int signum, void *sigInfo, void *context) {
char *pMsg = NULL;
const char *flags = "UTL FATAL ";
ELogLevel level = DEBUG_FATAL;
int32_t dflag = 255;
int64_t msgLen = -1;
if (tsEnableCrashReport) {
if (taosGenCrashJsonMsg(signum, &pMsg, lastClusterId, appInfo.startTime)) {
taosPrintLog(flags, level, dflag, "failed to generate crash json msg");
} else {
msgLen = strlen(pMsg);
}
}
taosLogCrashInfo("taos", pMsg, msgLen, signum, sigInfo);
writeCrashLogToFile(signum, sigInfo, CUS_PROMPT, lastClusterId, appInfo.startTime);
}
void taos_init_imp(void) {
@ -969,7 +963,7 @@ void taos_init_imp(void) {
}
taosHashSetFreeFp(appInfo.pInstMap, destroyAppInst);
const char *logName = CUS_PROMPT "slog";
const char *logName = CUS_PROMPT "log";
ENV_ERR_RET(taosInitLogOutput(&logName), "failed to init log output");
if (taosCreateLog(logName, 10, configDir, NULL, NULL, NULL, NULL, 1) != 0) {
(void)printf(" WARING: Create %s failed:%s. configDir=%s\n", logName, strerror(errno), configDir);

View File

@ -24,13 +24,13 @@
#include "query.h"
#include "scheduler.h"
#include "tcompare.h"
#include "tconv.h"
#include "tdatablock.h"
#include "tglobal.h"
#include "tmsg.h"
#include "tref.h"
#include "trpc.h"
#include "version.h"
#include "tconv.h"
#define TSC_VAR_NOT_RELEASE 1
#define TSC_VAR_RELEASED 0
@ -56,12 +56,12 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
}
#ifndef WINDOWS
static void freeTz(void *p){
static void freeTz(void *p) {
timezone_t tz = *(timezone_t *)p;
tzfree(tz);
}
int32_t tzInit(){
int32_t tzInit() {
pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK);
if (pTimezoneMap == NULL) {
return terrno;
@ -75,15 +75,15 @@ int32_t tzInit(){
return 0;
}
void tzCleanup(){
void tzCleanup() {
taosHashCleanup(pTimezoneMap);
taosHashCleanup(pTimezoneNameMap);
}
static timezone_t setConnnectionTz(const char* val){
timezone_t tz = NULL;
static timezone_t setConnnectionTz(const char *val) {
timezone_t tz = NULL;
timezone_t *tmp = taosHashGet(pTimezoneMap, val, strlen(val));
if (tmp != NULL && *tmp != NULL){
if (tmp != NULL && *tmp != NULL) {
tz = *tmp;
goto END;
}
@ -100,20 +100,20 @@ static timezone_t setConnnectionTz(const char* val){
}
}
int32_t code = taosHashPut(pTimezoneMap, val, strlen(val), &tz, sizeof(timezone_t));
if (code != 0){
if (code != 0) {
tscError("%s put timezone to tz map error:%d", __func__, code);
tzfree(tz);
tz = NULL;
goto END;
}
time_t tx1 = taosGetTimestampSec();
char output[TD_TIMEZONE_LEN] = {0};
time_t tx1 = taosGetTimestampSec();
char output[TD_TIMEZONE_LEN] = {0};
code = taosFormatTimezoneStr(tx1, val, tz, output);
if (code == 0){
if (code == 0) {
code = taosHashPut(pTimezoneNameMap, &tz, sizeof(timezone_t), output, strlen(output) + 1);
}
if (code != 0){
if (code != 0) {
tscError("failed to put timezone %s to map", val);
}
@ -122,18 +122,18 @@ END:
}
#endif
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char* val){
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char *val) {
if (taos == NULL) {
return terrno = TSDB_CODE_INVALID_PARA;
}
#ifdef WINDOWS
if (option == TSDB_OPTION_CONNECTION_TIMEZONE){
if (option == TSDB_OPTION_CONNECTION_TIMEZONE) {
return terrno = TSDB_CODE_NOT_SUPPORTTED_IN_WINDOWS;
}
#endif
if (option < TSDB_OPTION_CONNECTION_CLEAR || option >= TSDB_MAX_OPTIONS_CONNECTION){
if (option < TSDB_OPTION_CONNECTION_CLEAR || option >= TSDB_MAX_OPTIONS_CONNECTION) {
return terrno = TSDB_CODE_INVALID_PARA;
}
@ -149,7 +149,7 @@ static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, co
return terrno;
}
if (option == TSDB_OPTION_CONNECTION_CLEAR){
if (option == TSDB_OPTION_CONNECTION_CLEAR) {
val = NULL;
}
@ -165,19 +165,19 @@ static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, co
goto END;
}
pObj->optionInfo.charsetCxt = tmp;
}else{
} else {
pObj->optionInfo.charsetCxt = NULL;
}
}
if (option == TSDB_OPTION_CONNECTION_TIMEZONE || option == TSDB_OPTION_CONNECTION_CLEAR) {
#ifndef WINDOWS
if (val != NULL){
if (val[0] == 0){
if (val != NULL) {
if (val[0] == 0) {
val = "UTC";
}
timezone_t tz = setConnnectionTz(val);
if (tz == NULL){
if (tz == NULL) {
code = terrno;
goto END;
}
@ -199,7 +199,7 @@ static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, co
if (option == TSDB_OPTION_CONNECTION_USER_IP || option == TSDB_OPTION_CONNECTION_CLEAR) {
if (val != NULL) {
pObj->optionInfo.userIp = taosInetAddr(val);
if (pObj->optionInfo.userIp == INADDR_NONE){
if (pObj->optionInfo.userIp == INADDR_NONE) {
code = TSDB_CODE_INVALID_PARA;
goto END;
}
@ -213,7 +213,7 @@ END:
return terrno = code;
}
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...){
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...) {
return setConnectionOption(taos, option, (const char *)arg);
}
@ -2129,6 +2129,11 @@ int taos_stmt_close(TAOS_STMT *stmt) {
}
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
if (NULL == taos) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
return NULL;
}
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
if (NULL == pObj) {
tscError("invalid parameter for %s", __FUNCTION__);
@ -2257,16 +2262,7 @@ int taos_stmt2_close(TAOS_STMT2 *stmt) {
return stmtClose2(stmt);
}
/*
int taos_stmt2_param_count(TAOS_STMT2 *stmt, int *nums) {
if (stmt == NULL || nums == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
return stmtGetParamNum2(stmt, nums);
}
*/
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
if (stmt == NULL || insert == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
@ -2277,28 +2273,6 @@ int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
return stmtIsInsert2(stmt, insert);
}
// int taos_stmt2_get_fields(TAOS_STMT2 *stmt, TAOS_FIELD_T field_type, int *count, TAOS_FIELD_E **fields) {
// if (stmt == NULL || count == NULL) {
// tscError("NULL parameter for %s", __FUNCTION__);
// terrno = TSDB_CODE_INVALID_PARA;
// return terrno;
// }
// if (field_type == TAOS_FIELD_COL) {
// return stmtGetColFields2(stmt, count, fields);
// } else if (field_type == TAOS_FIELD_TAG) {
// return stmtGetTagFields2(stmt, count, fields);
// } else if (field_type == TAOS_FIELD_QUERY) {
// return stmtGetParamNum2(stmt, count);
// } else if (field_type == TAOS_FIELD_TBNAME) {
// return stmtGetParamTbName(stmt, count);
// } else {
// tscError("invalid parameter for %s", __FUNCTION__);
// terrno = TSDB_CODE_INVALID_PARA;
// return terrno;
// }
// }
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields) {
if (stmt == NULL || count == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);

View File

@ -2572,6 +2572,7 @@ int32_t tmq_write_raw(TAOS* taos, tmq_raw_data raw) {
SET_ERROR_MSG("taos:%p or data:%p is NULL or raw_len <= 0", taos, raw.raw);
return TSDB_CODE_INVALID_PARA;
}
taosClearErrMsg(); // clear global error message
return writeRawImpl(taos, raw.raw, raw.raw_len, raw.raw_type);
}

View File

@ -176,7 +176,7 @@ int32_t stmtGetTbName(TAOS_STMT* stmt, char** tbName) {
return TSDB_CODE_SUCCESS;
}
/*
int32_t stmtBackupQueryFields(STscStmt* pStmt) {
SStmtQueryResInfo* pRes = &pStmt->sql.queryRes;
pRes->numOfCols = pStmt->exec.pRequest->body.resInfo.numOfCols;
@ -225,7 +225,7 @@ int32_t stmtRestoreQueryFields(STscStmt* pStmt) {
return TSDB_CODE_SUCCESS;
}
*/
int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, const char* sTableName,
bool autoCreateTbl) {
STscStmt* pStmt = (STscStmt*)stmt;
@ -1320,11 +1320,12 @@ int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) {
if (colIdx < 0) {
if (pStmt->sql.stbInterlaceMode) {
(*pDataBlock)->pData->flags = 0;
code = qBindStmtStbColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf,
pStmt->exec.pRequest->msgBufLen, &pStmt->sql.siInfo.pTSchema, pStmt->sql.pBindInfo, pStmt->taos->optionInfo.charsetCxt);
} else {
code =
qBindStmtColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, pStmt->taos->optionInfo.charsetCxt);
qBindStmtStbColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen,
&pStmt->sql.siInfo.pTSchema, pStmt->sql.pBindInfo, pStmt->taos->optionInfo.charsetCxt);
} else {
code = qBindStmtColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen,
pStmt->taos->optionInfo.charsetCxt);
}
if (code) {
@ -1348,8 +1349,9 @@ int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) {
pStmt->bInfo.sBindRowNum = bind->num;
}
code = qBindStmtSingleColValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf,
pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum, pStmt->taos->optionInfo.charsetCxt);
code =
qBindStmtSingleColValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen,
colIdx, pStmt->bInfo.sBindRowNum, pStmt->taos->optionInfo.charsetCxt);
if (code) {
tscError("qBindStmtSingleColValue failed, error:%s", tstrerror(code));
STMT_ERR_RET(code);
@ -1401,7 +1403,7 @@ int stmtAddBatch(TAOS_STMT* stmt) {
return TSDB_CODE_SUCCESS;
}
/*
int stmtUpdateTableUid(STscStmt* pStmt, SSubmitRsp* pRsp) {
tscDebug("stmt start to update tbUid, blockNum: %d", pRsp->nBlocks);
@ -1487,6 +1489,7 @@ int stmtUpdateTableUid(STscStmt* pStmt, SSubmitRsp* pRsp) {
return finalCode;
}
*/
/*
int stmtStaticModeExec(TAOS_STMT* stmt) {

View File

@ -853,7 +853,7 @@ static int stmtSetDbName2(TAOS_STMT2* stmt, const char* dbName) {
// The SQL statement specifies a database name, overriding the previously specified database
taosMemoryFreeClear(pStmt->exec.pRequest->pDb);
pStmt->exec.pRequest->pDb = taosStrdup(dbName);
pStmt->exec.pRequest->pDb = taosStrdup(pStmt->db);
if (pStmt->exec.pRequest->pDb == NULL) {
return terrno;
}
@ -1037,28 +1037,6 @@ int stmtSetTbTags2(TAOS_STMT2* stmt, TAOS_STMT2_BIND* tags) {
return TSDB_CODE_SUCCESS;
}
static int stmtFetchTagFields2(STscStmt2* pStmt, int32_t* fieldNum, TAOS_FIELD_E** fields) {
if (pStmt->errCode != TSDB_CODE_SUCCESS) {
return pStmt->errCode;
}
if (STMT_TYPE_QUERY == pStmt->sql.type) {
tscError("invalid operation to get query tag fileds");
STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
}
STableDataCxt** pDataBlock =
(STableDataCxt**)taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName));
if (NULL == pDataBlock) {
tscError("table %s not found in exec blockHash", pStmt->bInfo.tbFName);
STMT_ERR_RET(TSDB_CODE_APP_ERROR);
}
STMT_ERR_RET(qBuildStmtTagFields(*pDataBlock, pStmt->bInfo.boundTags, fieldNum, fields));
return TSDB_CODE_SUCCESS;
}
static int stmtFetchColFields2(STscStmt2* pStmt, int32_t* fieldNum, TAOS_FIELD_E** fields) {
if (pStmt->errCode != TSDB_CODE_SUCCESS) {
return pStmt->errCode;
@ -1820,47 +1798,6 @@ int stmtAffectedRows(TAOS_STMT* stmt) { return ((STscStmt2*)stmt)->affectedRows;
int stmtAffectedRowsOnce(TAOS_STMT* stmt) { return ((STscStmt2*)stmt)->exec.affectedRows; }
*/
int stmtGetTagFields2(TAOS_STMT2* stmt, int* nums, TAOS_FIELD_E** fields) {
int32_t code = 0;
STscStmt2* pStmt = (STscStmt2*)stmt;
int32_t preCode = pStmt->errCode;
STMT_DLOG_E("start to get tag fields");
if (pStmt->errCode != TSDB_CODE_SUCCESS) {
return pStmt->errCode;
}
if (STMT_TYPE_QUERY == pStmt->sql.type) {
STMT_ERRI_JRET(TSDB_CODE_TSC_STMT_API_ERROR);
}
STMT_ERRI_JRET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS));
if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 &&
STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
pStmt->bInfo.needParse = false;
}
if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
taos_free_result(pStmt->exec.pRequest);
pStmt->exec.pRequest = NULL;
}
STMT_ERRI_JRET(stmtCreateRequest(pStmt));
if (pStmt->bInfo.needParse) {
STMT_ERRI_JRET(stmtParseSql(pStmt));
}
STMT_ERRI_JRET(stmtFetchTagFields2(stmt, nums, fields));
_return:
pStmt->errCode = preCode;
return code;
}
int stmtParseColFields2(TAOS_STMT2* stmt) {
int32_t code = 0;
@ -1903,15 +1840,6 @@ _return:
return code;
}
int stmtGetColFields2(TAOS_STMT2* stmt, int* nums, TAOS_FIELD_E** fields) {
int32_t code = stmtParseColFields2(stmt);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
return stmtFetchColFields2(stmt, nums, fields);
}
int stmtGetStbColFields2(TAOS_STMT2* stmt, int* nums, TAOS_FIELD_ALL** fields) {
int32_t code = stmtParseColFields2(stmt);
if (code != TSDB_CODE_SUCCESS) {
@ -1957,95 +1885,6 @@ int stmtGetParamNum2(TAOS_STMT2* stmt, int* nums) {
return TSDB_CODE_SUCCESS;
}
int stmtGetParamTbName(TAOS_STMT2* stmt, int* nums) {
STscStmt2* pStmt = (STscStmt2*)stmt;
int32_t code = 0;
int32_t preCode = pStmt->errCode;
STMT_DLOG_E("start to get param num");
if (pStmt->errCode != TSDB_CODE_SUCCESS) {
return pStmt->errCode;
}
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS));
if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 &&
STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
pStmt->bInfo.needParse = false;
}
if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
taos_free_result(pStmt->exec.pRequest);
pStmt->exec.pRequest = NULL;
}
STMT_ERR_RET(stmtCreateRequest(pStmt));
if (pStmt->bInfo.needParse) {
STMT_ERRI_JRET(stmtParseSql(pStmt));
}
*nums = STMT_TYPE_MULTI_INSERT == pStmt->sql.type ? 1 : 0;
_return:
if (TSDB_CODE_TSC_STMT_TBNAME_ERROR == code) {
*nums = 1;
code = TSDB_CODE_SUCCESS;
}
pStmt->errCode = preCode;
return code;
}
/*
int stmtGetParam(TAOS_STMT* stmt, int idx, int* type, int* bytes) {
STscStmt2* pStmt = (STscStmt2*)stmt;
STMT_DLOG_E("start to get param");
if (pStmt->errCode != TSDB_CODE_SUCCESS) {
return pStmt->errCode;
}
if (STMT_TYPE_QUERY == pStmt->sql.type) {
STMT_RET(TSDB_CODE_TSC_STMT_API_ERROR);
}
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS));
if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 &&
STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
pStmt->bInfo.needParse = false;
}
if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
taos_free_result(pStmt->exec.pRequest);
pStmt->exec.pRequest = NULL;
}
STMT_ERR_RET(stmtCreateRequest(pStmt));
if (pStmt->bInfo.needParse) {
STMT_ERR_RET(stmtParseSql(pStmt));
}
int32_t nums = 0;
TAOS_FIELD_E* pField = NULL;
STMT_ERR_RET(stmtFetchColFields(stmt, &nums, &pField));
if (idx >= nums) {
tscError("idx %d is too big", idx);
taosMemoryFree(pField);
STMT_ERR_RET(TSDB_CODE_INVALID_PARA);
}
*type = pField[idx].type;
*bytes = pField[idx].bytes;
taosMemoryFree(pField);
return TSDB_CODE_SUCCESS;
}
*/
TAOS_RES* stmtUseResult2(TAOS_STMT2* stmt) {
STscStmt2* pStmt = (STscStmt2*)stmt;

View File

@ -64,6 +64,7 @@ enum {
enum {
TMQ_CONSUMER_STATUS__INIT = 0,
TMQ_CONSUMER_STATUS__READY,
TMQ_CONSUMER_STATUS__LOST,
TMQ_CONSUMER_STATUS__CLOSED,
};
@ -768,7 +769,7 @@ static int32_t innerCommit(tmq_t* tmq, char* pTopicName, STqOffsetVal* offsetVal
}
tqDebugC("consumer:0x%" PRIx64 " topic:%s on vgId:%d send commit msg success, send offset:%s committed:%s",
tmq->consumerId, pTopicName, pVg->vgId, offsetBuf, commitBuf);
tmq->consumerId, pTopicName, pVg->vgId, offsetBuf, commitBuf);
tOffsetCopy(&pVg->offsetInfo.committedOffset, offsetVal);
return code;
}
@ -823,7 +824,7 @@ static void asyncCommitFromResult(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_c
code = asyncCommitOffset(tmq, pTopicName, vgId, &offsetVal, pCommitFp, userParam);
end:
end:
if (code != TSDB_CODE_SUCCESS && pCommitFp != NULL) {
if (code == TSDB_CODE_TMQ_SAME_COMMITTED_VALUE) code = TSDB_CODE_SUCCESS;
pCommitFp(tmq, code, userParam);
@ -863,7 +864,7 @@ static int32_t innerCommitAll(tmq_t* tmq, SMqCommitCbParamSet* pParamSet){
}
tqDebugC("consumer:0x%" PRIx64 " total commit:%d for %d topics", tmq->consumerId, pParamSet->waitingRspNum - DEFAULT_COMMIT_CNT,
numOfTopics);
END:
END:
taosRUnLockLatch(&tmq->lock);
return code;
}
@ -988,7 +989,7 @@ int32_t tmqHbCb(void* param, SDataBuf* pMsg, int32_t code) {
tDestroySMqHbRsp(&rsp);
END:
END:
taosMemoryFree(pMsg->pData);
taosMemoryFree(pMsg->pEpSet);
return code;
@ -1088,7 +1089,7 @@ void tmqSendHbReq(void* param, void* tmrId) {
}
(void)atomic_val_compare_exchange_8(&tmq->pollFlag, 1, 0);
END:
END:
tDestroySMqHbReq(&req);
if (tmrId != NULL) {
bool ret = taosTmrReset(tmqSendHbReq, tmq->heartBeatIntervalMs, param, tmqMgmt.timer, &tmq->hbLiveTimer);
@ -1209,9 +1210,9 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
}
static void buildNewTopicList(tmq_t* tmq, SArray* newTopics, const SMqAskEpRsp* pRsp){
if (tmq == NULL || newTopics == NULL || pRsp == NULL) {
return;
}
if (tmq == NULL || newTopics == NULL || pRsp == NULL) {
return;
}
SHashObj* pVgOffsetHashMap = taosHashInit(64, MurmurHash3_32, false, HASH_NO_LOCK);
if (pVgOffsetHashMap == NULL) {
tqErrorC("consumer:0x%" PRIx64 " taos hash init null, code:%d", tmq->consumerId, terrno);
@ -1266,9 +1267,9 @@ static void buildNewTopicList(tmq_t* tmq, SArray* newTopics, const SMqAskEpRsp*
}
static void doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp) {
if (tmq == NULL || pRsp == NULL) {
return;
}
if (tmq == NULL || pRsp == NULL) {
return;
}
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
// vnode transform (epoch == tmq->epoch && topicNumGet != 0)
// ask ep rsp (epoch == tmq->epoch && topicNumGet == 0)
@ -1318,6 +1319,9 @@ static int32_t askEpCb(void* param, SDataBuf* pMsg, int32_t code) {
if (code != TSDB_CODE_SUCCESS) {
if (code != TSDB_CODE_MND_CONSUMER_NOT_READY){
tqErrorC("consumer:0x%" PRIx64 ", get topic endpoint error, code:%s", tmq->consumerId, tstrerror(code));
if (code == TSDB_CODE_MND_CONSUMER_NOT_EXIST){
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__LOST);
}
}
goto END;
}
@ -1388,49 +1392,32 @@ static int32_t askEp(tmq_t* pTmq, void* param, bool sync, bool updateEpSet) {
if (pTmq == NULL) {
return TSDB_CODE_INVALID_PARA;
}
int32_t code = 0;
int32_t lino = 0;
SMqAskEpReq req = {0};
req.consumerId = pTmq->consumerId;
req.epoch = updateEpSet ? -1 : pTmq->epoch;
tstrncpy(req.cgroup, pTmq->groupId, TSDB_CGROUP_LEN);
int code = 0;
SMqAskEpCbParam* pParam = NULL;
void* pReq = NULL;
int32_t tlen = tSerializeSMqAskEpReq(NULL, 0, &req);
if (tlen < 0) {
tqErrorC("consumer:0x%" PRIx64 ", tSerializeSMqAskEpReq failed", pTmq->consumerId);
return TSDB_CODE_INVALID_PARA;
}
TSDB_CHECK_CONDITION(tlen >= 0, code, lino, END, TSDB_CODE_INVALID_PARA);
pReq = taosMemoryCalloc(1, tlen);
if (pReq == NULL) {
tqErrorC("consumer:0x%" PRIx64 ", failed to malloc askEpReq msg, size:%d", pTmq->consumerId, tlen);
return terrno;
}
TSDB_CHECK_NULL(pReq, code, lino, END, terrno);
if (tSerializeSMqAskEpReq(pReq, tlen, &req) < 0) {
tqErrorC("consumer:0x%" PRIx64 ", tSerializeSMqAskEpReq %d failed", pTmq->consumerId, tlen);
taosMemoryFree(pReq);
return TSDB_CODE_INVALID_PARA;
}
code = tSerializeSMqAskEpReq(pReq, tlen, &req);
TSDB_CHECK_CONDITION(code >= 0, code, lino, END, TSDB_CODE_INVALID_PARA);
pParam = taosMemoryCalloc(1, sizeof(SMqAskEpCbParam));
if (pParam == NULL) {
tqErrorC("consumer:0x%" PRIx64 ", failed to malloc subscribe param", pTmq->consumerId);
taosMemoryFree(pReq);
return terrno;
}
TSDB_CHECK_NULL(pParam, code, lino, END, terrno);
pParam->refId = pTmq->refId;
pParam->sync = sync;
pParam->pParam = param;
SMsgSendInfo* sendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
if (sendInfo == NULL) {
taosMemoryFree(pReq);
taosMemoryFree(pParam);
return terrno;
}
TSDB_CHECK_NULL(sendInfo, code, lino, END, terrno);
sendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = tlen, .handle = NULL};
sendInfo->requestId = generateRequestId();
@ -1440,28 +1427,36 @@ static int32_t askEp(tmq_t* pTmq, void* param, bool sync, bool updateEpSet) {
sendInfo->fp = askEpCb;
sendInfo->msgType = TDMT_MND_TMQ_ASK_EP;
pReq = NULL;
pParam = NULL;
SEpSet epSet = getEpSet_s(&pTmq->pTscObj->pAppInfo->mgmtEp);
tqDebugC("consumer:0x%" PRIx64 " ask ep from mnode,QID:0x%" PRIx64, pTmq->consumerId, sendInfo->requestId);
return asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &epSet, NULL, sendInfo);
code = asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &epSet, NULL, sendInfo);
END:
if (code != 0) {
tqErrorC("%s failed at %d, msg:%s", __func__, lino, tstrerror(code));
}
taosMemoryFree(pReq);
taosMemoryFree(pParam);
return code;
}
void tmqHandleAllDelayedTask(tmq_t* pTmq) {
if (pTmq == NULL) {
return;
}
static int32_t tmqHandleAllDelayedTask(tmq_t* pTmq) {
STaosQall* qall = NULL;
int32_t code = 0;
code = taosAllocateQall(&qall);
if (code) {
tqErrorC("consumer:0x%" PRIx64 ", failed to allocate qall, code:%s", pTmq->consumerId, tstrerror(code));
return;
return code;
}
int32_t numOfItems = taosReadAllQitems(pTmq->delayedTask, qall);
if (numOfItems == 0) {
taosFreeQall(qall);
return;
return 0;
}
tqDebugC("consumer:0x%" PRIx64 " handle delayed %d tasks before poll data", pTmq->consumerId, numOfItems);
@ -1472,7 +1467,6 @@ void tmqHandleAllDelayedTask(tmq_t* pTmq) {
code = askEp(pTmq, NULL, false, false);
if (code != 0) {
tqErrorC("consumer:0x%" PRIx64 " failed to ask ep, code:%s", pTmq->consumerId, tstrerror(code));
continue;
}
tqDebugC("consumer:0x%" PRIx64 " retrieve ep from mnode in 1s", pTmq->consumerId);
bool ret = taosTmrReset(tmqAssignAskEpTask, DEFAULT_ASKEP_INTERVAL, (void*)(pTmq->refId), tmqMgmt.timer,
@ -1494,6 +1488,7 @@ void tmqHandleAllDelayedTask(tmq_t* pTmq) {
}
taosFreeQall(qall);
return 0;
}
void tmqClearUnhandleMsg(tmq_t* tmq) {
@ -1562,7 +1557,7 @@ int32_t tmq_subscription(tmq_t* tmq, tmq_list_t** topics) {
}
void tmqFreeImpl(void* handle) {
if (handle == NULL) return;
if (handle == NULL) return;
tmq_t* tmq = (tmq_t*)handle;
int64_t id = tmq->consumerId;
@ -1759,13 +1754,13 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
STqOffsetVal offset = {.type = pTmq->resetOffsetCfg};
tFormatOffset(buf, tListLen(buf), &offset);
tqInfoC("consumer:0x%" PRIx64 " is setup, refId:%" PRId64
", groupId:%s, snapshot:%d, autoCommit:%d, commitInterval:%dms, offset:%s",
", groupId:%s, snapshot:%d, autoCommit:%d, commitInterval:%dms, offset:%s",
pTmq->consumerId, pTmq->refId, pTmq->groupId, pTmq->useSnapshot, pTmq->autoCommit, pTmq->autoCommitInterval,
buf);
return pTmq;
_failed:
_failed:
tmqFreeImpl(pTmq);
return NULL;
}
@ -1942,7 +1937,7 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
}
}
END:
END:
taosArrayDestroyP(req.topicNames, NULL);
return code;
}
@ -2032,7 +2027,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
if (msgEpoch != clientEpoch) {
tqErrorC("consumer:0x%" PRIx64
" msg discard from vgId:%d since epoch not equal, rsp epoch %d, current epoch %d, reqId:0x%" PRIx64,
" msg discard from vgId:%d since epoch not equal, rsp epoch %d, current epoch %d, reqId:0x%" PRIx64,
tmq->consumerId, vgId, msgEpoch, clientEpoch, requestId);
code = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
goto END;
@ -2057,7 +2052,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
pRspWrapper->pollRsp.pEpset = pMsg->pEpSet;
pMsg->pEpSet = NULL;
END:
END:
if (pRspWrapper) {
pRspWrapper->code = code;
pRspWrapper->pollRsp.vgId = vgId;
@ -2082,7 +2077,7 @@ END:
tqErrorC("failed to release ref:%"PRId64 ", code:%d", refId, ret);
}
EXIT:
EXIT:
taosMemoryFreeClear(pMsg->pData);
taosMemoryFreeClear(pMsg->pEpSet);
return code;
@ -2095,7 +2090,7 @@ void tmqBuildConsumeReqImpl(SMqPollReq* pReq, tmq_t* tmq, int64_t timeout, SMqCl
(void)snprintf(pReq->subKey, TSDB_SUBSCRIBE_KEY_LEN, "%s%s%s", tmq->groupId, TMQ_SEPARATOR, pTopic->topicName);
pReq->withTbName = tmq->withTbName;
pReq->consumerId = tmq->consumerId;
pReq->timeout = timeout;
pReq->timeout = timeout < 0 ? INT32_MAX : timeout;
pReq->epoch = tmq->epoch;
pReq->reqOffset = pVg->offsetInfo.endOffset;
pReq->head.vgId = pVg->vgId;
@ -2199,39 +2194,24 @@ static void tmqBuildRspFromWrapperInner(SMqPollRspWrapper* pWrapper, SMqClientVg
}
static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* pVg, int64_t timeout) {
if (pTmq == NULL || pTopic == NULL || pVg == NULL) {
return TSDB_CODE_INVALID_MSG;
}
SMqPollReq req = {0};
char* msg = NULL;
SMqPollCbParam* pParam = NULL;
SMsgSendInfo* sendInfo = NULL;
int code = 0;
int lino = 0;
tmqBuildConsumeReqImpl(&req, pTmq, timeout, pTopic, pVg);
int32_t msgSize = tSerializeSMqPollReq(NULL, 0, &req);
if (msgSize < 0) {
code = TSDB_CODE_INVALID_MSG;
return code;
}
TSDB_CHECK_CONDITION(msgSize >= 0, code, lino, END, TSDB_CODE_INVALID_MSG);
msg = taosMemoryCalloc(1, msgSize);
if (NULL == msg) {
return terrno;
}
TSDB_CHECK_NULL(msg, code, lino, END, terrno);
if (tSerializeSMqPollReq(msg, msgSize, &req) < 0) {
code = TSDB_CODE_INVALID_MSG;
taosMemoryFreeClear(msg);
return code;
}
TSDB_CHECK_CONDITION(tSerializeSMqPollReq(msg, msgSize, &req) >= 0, code, lino, END, TSDB_CODE_INVALID_MSG);
pParam = taosMemoryMalloc(sizeof(SMqPollCbParam));
if (pParam == NULL) {
code = terrno;
taosMemoryFreeClear(msg);
return code;
}
TSDB_CHECK_NULL(pParam, code, lino, END, terrno);
pParam->refId = pTmq->refId;
tstrncpy(pParam->topicName, pTopic->topicName, TSDB_TOPIC_FNAME_LEN);
@ -2239,11 +2219,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
pParam->requestId = req.reqId;
sendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
if (sendInfo == NULL) {
taosMemoryFreeClear(pParam);
taosMemoryFreeClear(msg);
return terrno;
}
TSDB_CHECK_NULL(sendInfo, code, lino, END, terrno);
sendInfo->msgInfo = (SDataBuf){.pData = msg, .len = msgSize, .handle = NULL};
sendInfo->requestId = req.reqId;
@ -2253,30 +2229,41 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
sendInfo->fp = tmqPollCb;
sendInfo->msgType = TDMT_VND_TMQ_CONSUME;
msg = NULL;
pParam = NULL;
char offsetFormatBuf[TSDB_OFFSET_LEN] = {0};
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->offsetInfo.endOffset);
code = asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &pVg->epSet, NULL, sendInfo);
tqDebugC("consumer:0x%" PRIx64 " send poll to %s vgId:%d, code:%d, epoch %d, req:%s,QID:0x%" PRIx64, pTmq->consumerId,
pTopic->topicName, pVg->vgId, code, pTmq->epoch, offsetFormatBuf, req.reqId);
if (code != 0) {
return code;
}
TSDB_CHECK_CODE(code, lino, END);
pVg->pollCnt++;
pVg->seekUpdated = false; // reset this flag.
pTmq->pollCnt++;
return 0;
END:
if (code != 0){
tqErrorC("%s failed at %d msg:%s", __func__, lino, tstrerror(code));
}
taosMemoryFreeClear(pParam);
taosMemoryFreeClear(msg);
return code;
}
// broadcast the poll request to all related vnodes
static int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
if (tmq == NULL) {
return TSDB_CODE_INVALID_MSG;
}
int32_t code = 0;
taosWLockLatch(&tmq->lock);
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__LOST){
code = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
goto end;
}
int32_t numOfTopics = taosArrayGetSize(tmq->clientTopics);
tqDebugC("consumer:0x%" PRIx64 " start to poll data, numOfTopics:%d", tmq->consumerId, numOfTopics);
@ -2325,7 +2312,7 @@ static int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
}
}
end:
end:
taosWUnLockLatch(&tmq->lock);
tqDebugC("consumer:0x%" PRIx64 " end to poll data, code:%d", tmq->consumerId, code);
return code;
@ -2361,9 +2348,6 @@ static SMqRspObj* buildRsp(SMqPollRspWrapper* pollRspWrapper){
SMqBatchMetaRsp batchMetaRsp;
} MEMSIZE;
if (pollRspWrapper == NULL) {
return NULL;
}
SMqRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqRspObj));
if (pRspObj == NULL) {
tqErrorC("buildRsp:failed to allocate memory");
@ -2377,22 +2361,22 @@ static SMqRspObj* buildRsp(SMqPollRspWrapper* pollRspWrapper){
return pRspObj;
}
static void processMqRspError(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
if (tmq == NULL || pRspWrapper == NULL) {
return;
}
static int32_t processMqRspError(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
int32_t code = 0;
SMqPollRspWrapper* pollRspWrapper = &pRspWrapper->pollRsp;
if (pRspWrapper->code == TSDB_CODE_VND_INVALID_VGROUP_ID) { // for vnode transform
int32_t code = askEp(tmq, NULL, false, true);
code = askEp(tmq, NULL, false, true);
if (code != 0) {
tqErrorC("consumer:0x%" PRIx64 " failed to ask ep, code:%s", tmq->consumerId, tstrerror(code));
}
} else if (pRspWrapper->code == TSDB_CODE_TMQ_CONSUMER_MISMATCH) {
int32_t code = askEp(tmq, NULL, false, false);
code = askEp(tmq, NULL, false, false);
if (code != 0) {
tqErrorC("consumer:0x%" PRIx64 " failed to ask ep, code:%s", tmq->consumerId, tstrerror(code));
}
} else if (pRspWrapper->code == TSDB_CODE_TMQ_NO_TABLE_QUALIFIED){
code = 0;
}
tqInfoC("consumer:0x%" PRIx64 " msg from vgId:%d discarded, since %s", tmq->consumerId, pollRspWrapper->vgId,
tstrerror(pRspWrapper->code));
@ -2404,17 +2388,18 @@ static void processMqRspError(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
}
taosWUnLockLatch(&tmq->lock);
return code;
}
static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
if (tmq == NULL || pRspWrapper == NULL) {
return NULL;
}
int32_t code = 0;
SMqRspObj* pRspObj = NULL;
if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__EP_RSP) {
tqDebugC("consumer:0x%" PRIx64 " ep msg received", tmq->consumerId);
SMqAskEpRsp* rspMsg = &pRspWrapper->epRsp;
doUpdateLocalEp(tmq, pRspWrapper->epoch, rspMsg);
terrno = code;
return pRspObj;
}
@ -2425,6 +2410,7 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
if(pVg == NULL) {
tqErrorC("consumer:0x%" PRIx64 " get vg or topic error, topic:%s vgId:%d", tmq->consumerId,
pollRspWrapper->topicName, pollRspWrapper->vgId);
code = TSDB_CODE_TMQ_INVALID_VGID;
goto END;
}
pollRspWrapper->topicHandle = getTopicInfo(tmq, pollRspWrapper->topicName);
@ -2483,88 +2469,92 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
}
END:
terrno = code;
taosWUnLockLatch(&tmq->lock);
return pRspObj;
}
static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
if (tmq == NULL) {
return NULL;
}
static void* tmqHandleAllRsp(tmq_t* tmq) {
tqDebugC("consumer:0x%" PRIx64 " start to handle the rsp, total:%d", tmq->consumerId, taosQallItemSize(tmq->qall));
int32_t code = 0;
void* returnVal = NULL;
while (1) {
SMqRspWrapper* pRspWrapper = NULL;
if (taosGetQitem(tmq->qall, (void**)&pRspWrapper) == 0) {
if (taosReadAllQitems(tmq->mqueue, tmq->qall) == 0){
return NULL;
code = taosReadAllQitems(tmq->mqueue, tmq->qall);
if (code == 0){
goto END;
}
if (taosGetQitem(tmq->qall, (void**)&pRspWrapper) == 0) {
return NULL;
code = taosGetQitem(tmq->qall, (void**)&pRspWrapper);
if (code == 0) {
goto END;
}
}
tqDebugC("consumer:0x%" PRIx64 " handle rsp, type:%d", tmq->consumerId, pRspWrapper->tmqRspType);
tqDebugC("consumer:0x%" PRIx64 " handle rsp, type:%s", tmq->consumerId, tmqMsgTypeStr[pRspWrapper->tmqRspType]);
if (pRspWrapper->code != 0) {
processMqRspError(tmq, pRspWrapper);
code = processMqRspError(tmq, pRspWrapper);
}else{
returnVal = processMqRsp(tmq, pRspWrapper);
code = terrno;
}
tmqFreeRspWrapper(pRspWrapper);
taosFreeQitem(pRspWrapper);
if(returnVal != NULL){
if(returnVal != NULL || code != 0){
break;
}
}
END:
terrno = code;
return returnVal;
}
TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
if (tmq == NULL) return NULL;
int32_t lino = 0;
int32_t code = 0;
TSDB_CHECK_NULL(tmq, code, lino, END, TSDB_CODE_INVALID_PARA);
void* rspObj = NULL;
int64_t startTime = taosGetTimestampMs();
tqDebugC("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime,
timeout);
// in no topic status, delayed task also need to be processed
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__INIT) {
tqInfoC("consumer:0x%" PRIx64 " poll return since consumer is init", tmq->consumerId);
taosMsleep(500); // sleep for a while
return NULL;
}
tqDebugC("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime, timeout);
TSDB_CHECK_CONDITION(atomic_load_8(&tmq->status) != TMQ_CONSUMER_STATUS__INIT, code, lino, END, TSDB_CODE_TMQ_INVALID_STATUS);
(void)atomic_val_compare_exchange_8(&tmq->pollFlag, 0, 1);
while (1) {
tmqHandleAllDelayedTask(tmq);
code = tmqHandleAllDelayedTask(tmq);
TSDB_CHECK_CODE(code, lino, END);
if (tmqPollImpl(tmq, timeout) < 0) {
tqErrorC("consumer:0x%" PRIx64 " return due to poll error", tmq->consumerId);
}
code = tmqPollImpl(tmq, timeout);
TSDB_CHECK_CODE(code, lino, END);
rspObj = tmqHandleAllRsp(tmq, timeout);
rspObj = tmqHandleAllRsp(tmq);
if (rspObj) {
tqDebugC("consumer:0x%" PRIx64 " return rsp %p", tmq->consumerId, rspObj);
return (TAOS_RES*)rspObj;
}
code = terrno;
TSDB_CHECK_CODE(code, lino, END);
if (timeout >= 0) {
int64_t currentTime = taosGetTimestampMs();
int64_t elapsedTime = currentTime - startTime;
if (elapsedTime > timeout || elapsedTime < 0) {
tqDebugC("consumer:0x%" PRIx64 " (epoch %d) timeout, no rsp, start time %" PRId64 ", current time %" PRId64,
tmq->consumerId, tmq->epoch, startTime, currentTime);
return NULL;
}
TSDB_CHECK_CONDITION(elapsedTime <= timeout && elapsedTime >= 0, code, lino, END, 0);
(void)tsem2_timewait(&tmq->rspSem, (timeout - elapsedTime));
} else {
(void)tsem2_timewait(&tmq->rspSem, 1000);
}
}
END:
terrno = code;
if (tmq != NULL) {
tqErrorC("consumer:0x%" PRIx64 " poll error at line:%d, msg:%s", tmq->consumerId, lino, tstrerror(terrno));
}
return NULL;
}
static void displayConsumeStatistics(tmq_t* pTmq) {
@ -2572,7 +2562,7 @@ static void displayConsumeStatistics(tmq_t* pTmq) {
taosRLockLatch(&pTmq->lock);
int32_t numOfTopics = taosArrayGetSize(pTmq->clientTopics);
tqInfoC("consumer:0x%" PRIx64 " closing poll:%" PRId64 " rows:%" PRId64 " topics:%d, final epoch:%d",
pTmq->consumerId, pTmq->pollCnt, pTmq->totalRows, numOfTopics, pTmq->epoch);
pTmq->consumerId, pTmq->pollCnt, pTmq->totalRows, numOfTopics, pTmq->epoch);
tqInfoC("consumer:0x%" PRIx64 " rows dist begin: ", pTmq->consumerId);
for (int32_t i = 0; i < numOfTopics; ++i) {
@ -2597,14 +2587,14 @@ int32_t tmq_unsubscribe(tmq_t* tmq) {
tqInfoC("consumer:0x%" PRIx64 " start to unsubscribe consumer, status:%d", tmq->consumerId, status);
displayConsumeStatistics(tmq);
if (status != TMQ_CONSUMER_STATUS__READY) {
if (status != TMQ_CONSUMER_STATUS__READY && status != TMQ_CONSUMER_STATUS__LOST) {
tqInfoC("consumer:0x%" PRIx64 " status:%d, already closed or not in ready state, no need unsubscribe", tmq->consumerId, status);
goto END;
}
if (tmq->autoCommit) {
code = tmq_commit_sync(tmq, NULL);
if (code != 0) {
goto END;
goto END;
}
}
tmqSendHbReq((void*)(tmq->refId), NULL);
@ -2616,11 +2606,12 @@ int32_t tmq_unsubscribe(tmq_t* tmq) {
}
code = tmq_subscribe(tmq, lst);
tmq_list_destroy(lst);
tmqClearUnhandleMsg(tmq);
if(code != 0){
goto END;
}
END:
END:
return code;
}
@ -2942,7 +2933,7 @@ void tmq_commit_offset_async(tmq_t* tmq, const char* pTopicName, int32_t vgId, i
tqInfoC("consumer:0x%" PRIx64 " async send commit to vgId:%d, offset:%" PRId64 " code:%s", tmq->consumerId, vgId,
offset, tstrerror(code));
end:
end:
if (code != 0 && cb != NULL) {
if (code == TSDB_CODE_TMQ_SAME_COMMITTED_VALUE) code = TSDB_CODE_SUCCESS;
cb(tmq, code, param);
@ -2951,9 +2942,9 @@ end:
int32_t tmqGetNextResInfo(TAOS_RES* res, bool convertUcs4, SReqResultInfo** pResInfo) {
if (res == NULL || pResInfo == NULL) {
return TSDB_CODE_INVALID_PARA;
}
if (res == NULL || pResInfo == NULL) {
return TSDB_CODE_INVALID_PARA;
}
SMqRspObj* pRspObj = (SMqRspObj*)res;
SMqDataRsp* data = &pRspObj->dataRsp;
@ -3014,9 +3005,9 @@ static int32_t tmqGetWalInfoCb(void* param, SDataBuf* pMsg, int32_t code) {
SMqRspHead* pHead = pMsg->pData;
tmq_topic_assignment assignment = {.begin = pHead->walsver,
.end = pHead->walever + 1,
.currentOffset = rsp.rspOffset.version,
.vgId = pParam->vgId};
.end = pHead->walever + 1,
.currentOffset = rsp.rspOffset.version,
.vgId = pParam->vgId};
(void)taosThreadMutexLock(&pCommon->mutex);
if (taosArrayPush(pCommon->pList, &assignment) == NULL) {
@ -3027,7 +3018,7 @@ static int32_t tmqGetWalInfoCb(void* param, SDataBuf* pMsg, int32_t code) {
(void)taosThreadMutexUnlock(&pCommon->mutex);
}
END:
END:
pCommon->code = code;
if (total == pParam->totalReq) {
if (tsem2_post(&pCommon->rsp) != 0) {
@ -3084,7 +3075,7 @@ static int32_t tmCommittedCb(void* param, SDataBuf* pMsg, int32_t code) {
tDecoderClear(&decoder);
}
end:
end:
if (pMsg) {
taosMemoryFree(pMsg->pData);
taosMemoryFree(pMsg->pEpSet);
@ -3290,7 +3281,7 @@ int64_t tmq_committed(tmq_t* tmq, const char* pTopicName, int32_t vgId) {
committed = getCommittedFromServer(tmq, tname, vgId, &epSet);
end:
end:
tqInfoC("consumer:0x%" PRIx64 " tmq_committed vgId:%d committed:%" PRId64, tmq->consumerId, vgId, committed);
return committed;
}
@ -3493,7 +3484,7 @@ int32_t tmq_get_topic_assignment(tmq_t* tmq, const char* pTopicName, tmq_topic_a
}
}
end:
end:
if (code != TSDB_CODE_SUCCESS) {
taosMemoryFree(*assignment);
*assignment = NULL;
@ -3647,4 +3638,4 @@ TAOS* tmq_get_connect(tmq_t* tmq) {
return (TAOS*)(&(tmq->pTscObj->id));
}
return NULL;
}
}

View File

@ -41,6 +41,18 @@ TARGET_LINK_LIBRARIES(
PUBLIC ${TAOS_LIB}
)
ADD_EXECUTABLE(stmt2Test stmt2Test.cpp)
TARGET_LINK_LIBRARIES(
stmt2Test
os util common transport parser catalog scheduler gtest ${TAOS_LIB_STATIC} qcom executor function
)
ADD_EXECUTABLE(stmtTest stmtTest.cpp)
TARGET_LINK_LIBRARIES(
stmtTest
os util common transport parser catalog scheduler gtest ${TAOS_LIB_STATIC} qcom executor function
)
TARGET_INCLUDE_DIRECTORIES(
clientTest
PUBLIC "${TD_SOURCE_DIR}/include/client/"
@ -62,6 +74,14 @@ IF(${TD_LINUX})
NAME connectOptionsTest
COMMAND connectOptionsTest
)
add_test(
NAME stmt2Test
COMMAND stmt2Test
)
add_test(
NAME stmtTest
COMMAND stmtTest
)
ENDIF ()
TARGET_INCLUDE_DIRECTORIES(
@ -82,6 +102,20 @@ TARGET_INCLUDE_DIRECTORIES(
# PRIVATE "${TD_SOURCE_DIR}/source/client/inc"
#)
TARGET_INCLUDE_DIRECTORIES(
stmt2Test
PUBLIC "${TD_SOURCE_DIR}/include/client/"
PUBLIC "${TD_SOURCE_DIR}/include/libs/geometry"
PRIVATE "${TD_SOURCE_DIR}/source/client/inc"
)
TARGET_INCLUDE_DIRECTORIES(
stmtTest
PUBLIC "${TD_SOURCE_DIR}/include/client/"
PUBLIC "${TD_SOURCE_DIR}/include/libs/geometry"
PRIVATE "${TD_SOURCE_DIR}/source/client/inc"
)
add_test(
NAME smlTest
COMMAND smlTest
@ -95,5 +129,4 @@ add_test(
add_test(
NAME userOperTest
COMMAND userOperTest
)
)

View File

@ -532,6 +532,10 @@ TEST(clientCase, create_stable_Test) {
taos_free_result(pRes);
pRes = taos_query(pConn, "use abc1");
while (taos_errno(pRes) == TSDB_CODE_MND_DB_IN_CREATING || taos_errno(pRes) == TSDB_CODE_MND_DB_IN_DROPPING) {
taosMsleep(2000);
pRes = taos_query(pConn, "use abc1");
}
taos_free_result(pRes);
pRes = taos_query(pConn, "create table if not exists abc1.st1(ts timestamp, k int) tags(a int)");
@ -664,6 +668,10 @@ TEST(clientCase, create_multiple_tables) {
taos_free_result(pRes);
pRes = taos_query(pConn, "use abc1");
while (taos_errno(pRes) == TSDB_CODE_MND_DB_IN_CREATING || taos_errno(pRes) == TSDB_CODE_MND_DB_IN_DROPPING) {
taosMsleep(2000);
pRes = taos_query(pConn, "use abc1");
}
if (taos_errno(pRes) != 0) {
(void)printf("failed to use db, reason:%s\n", taos_errstr(pRes));
taos_free_result(pRes);
@ -1524,6 +1532,10 @@ TEST(clientCase, timezone_Test) {
taos_free_result(pRes);
pRes = taos_query(pConn, "create table db1.t1 (ts timestamp, v int)");
while (taos_errno(pRes) == TSDB_CODE_MND_DB_IN_CREATING || taos_errno(pRes) == TSDB_CODE_MND_DB_IN_DROPPING) {
taosMsleep(2000);
pRes = taos_query(pConn, "create table db1.t1 (ts timestamp, v int)");
}
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
taos_free_result(pRes);

View File

@ -55,7 +55,13 @@ TAOS* getConnWithOption(const char *tz){
void execQuery(TAOS* pConn, const char *sql){
TAOS_RES* pRes = taos_query(pConn, sql);
ASSERT(taos_errno(pRes) == TSDB_CODE_SUCCESS);
int code = taos_errno(pRes);
while (code == TSDB_CODE_MND_DB_IN_CREATING || code == TSDB_CODE_MND_DB_IN_DROPPING) {
taosMsleep(2000);
TAOS_RES* pRes = taos_query(pConn, sql);
code = taos_errno(pRes);
}
ASSERT(code == TSDB_CODE_SUCCESS);
taos_free_result(pRes);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,542 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include <string.h>
#include "clientInt.h"
#include "geosWrapper.h"
#include "osSemaphore.h"
#include "taoserror.h"
#include "tglobal.h"
#include "thash.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#include "../inc/clientStmt.h"
#include "../inc/clientStmt2.h"
#include "executor.h"
#include "taos.h"
namespace {
void checkError(TAOS_STMT *stmt, int code) {
if (code != TSDB_CODE_SUCCESS) {
STscStmt *pStmt = (STscStmt *)stmt;
if (pStmt == nullptr || pStmt->sql.sqlStr == nullptr) {
printf("stmt api error\n stats : %d\n errstr : %s\n", pStmt->sql.status, taos_stmt_errstr(stmt));
} else {
printf("stmt api error\n sql : %s\n stats : %d\n errstr : %s\n", pStmt->sql.sqlStr, pStmt->sql.status,
taos_stmt_errstr(stmt));
}
ASSERT_EQ(code, TSDB_CODE_SUCCESS);
}
}
void do_query(TAOS *taos, const char *sql) {
TAOS_RES *result = taos_query(taos, sql);
// printf("sql: %s\n", sql);
int code = taos_errno(result);
while (code == TSDB_CODE_MND_DB_IN_CREATING || code == TSDB_CODE_MND_DB_IN_DROPPING) {
taosMsleep(2000);
result = taos_query(taos, sql);
code = taos_errno(result);
}
if (code != TSDB_CODE_SUCCESS) {
printf("query failen sql : %s\n errstr : %s\n", sql, taos_errstr(result));
ASSERT_EQ(taos_errno(result), TSDB_CODE_SUCCESS);
}
taos_free_result(result);
}
typedef struct {
int64_t ts;
float current;
int voltage;
float phase;
} Row;
void insertData(TAOS *taos, TAOS_STMT_OPTIONS *option, const char *sql, int CTB_NUMS, int ROW_NUMS, int CYC_NUMS,
bool isCreateTable) {
// create database and table
do_query(taos, "DROP DATABASE IF EXISTS stmt_testdb_2");
do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt_testdb_2");
do_query(
taos,
"CREATE STABLE IF NOT EXISTS stmt_testdb_2.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS "
"(groupId INT, location BINARY(24))");
do_query(taos, "USE stmt_testdb_2");
// init
TAOS_STMT *stmt;
if (option == nullptr) {
stmt = taos_stmt_init(taos);
} else {
stmt = taos_stmt_init_with_options(taos, option);
}
ASSERT_NE(stmt, nullptr);
int code = taos_stmt_prepare(stmt, sql, 0);
checkError(stmt, code);
int total_affected = 0;
for (int k = 0; k < CYC_NUMS; k++) {
for (int i = 1; i <= CTB_NUMS; i++) {
char *table_name = (char *)taosMemoryMalloc(20);
char *location = (char *)taosMemoryMalloc(20);
TAOS_MULTI_BIND tags[2];
sprintf(table_name, "d_bind_%d", i);
if (isCreateTable && k == 0) {
char *tmp = (char *)taosMemoryMalloc(100);
sprintf(tmp, "CREATE TABLE %s using meters TAGS (1, 'abc')", table_name);
do_query(taos, tmp);
taosMemoryFree(tmp);
} else {
sprintf(location, "location_%d", i);
// set table name and tags
// groupId
tags[0].buffer_type = TSDB_DATA_TYPE_INT;
tags[0].buffer_length = sizeof(int);
tags[0].length = (int32_t *)&tags[0].buffer_length;
tags[0].buffer = &i;
tags[0].is_null = NULL;
tags[0].num = 1;
// location
tags[1].buffer_type = TSDB_DATA_TYPE_BINARY;
tags[1].buffer_length = strlen(location);
tags[1].length = (int32_t *)&tags[1].buffer_length;
tags[1].buffer = location;
tags[1].is_null = NULL;
tags[1].num = 1;
}
if (!isCreateTable) {
if (k % 2 == 0) {
code = taos_stmt_set_tbname_tags(stmt, table_name, tags);
checkError(stmt, code);
} else {
if (i % 2 == 0) {
code = taos_stmt_set_tbname(stmt, table_name);
checkError(stmt, code);
} else {
code = taos_stmt_set_sub_tbname(stmt, table_name);
checkError(stmt, code);
}
code = taos_stmt_set_tags(stmt, tags);
checkError(stmt, code);
}
} else {
code = taos_stmt_set_tbname(stmt, table_name);
checkError(stmt, code);
}
// insert rows
TAOS_MULTI_BIND params[4];
// ts
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[0].buffer_length = sizeof(int64_t);
params[0].length = (int32_t *)&params[0].buffer_length;
params[0].is_null = NULL;
params[0].num = 1;
// current
params[1].buffer_type = TSDB_DATA_TYPE_FLOAT;
params[1].buffer_length = sizeof(float);
params[1].length = (int32_t *)&params[1].buffer_length;
params[1].is_null = NULL;
params[1].num = 1;
// voltage
params[2].buffer_type = TSDB_DATA_TYPE_INT;
params[2].buffer_length = sizeof(int);
params[2].length = (int32_t *)&params[2].buffer_length;
params[2].is_null = NULL;
params[2].num = 1;
// phase
params[3].buffer_type = TSDB_DATA_TYPE_FLOAT;
params[3].buffer_length = sizeof(float);
params[3].length = (int32_t *)&params[3].buffer_length;
params[3].is_null = NULL;
params[3].num = 1;
for (int j = 0; j < ROW_NUMS; j++) {
struct timeval tv;
(&tv, NULL);
int64_t ts = 1591060628000 + j + k * 100000;
float current = (float)0.0001f * j;
int voltage = j;
float phase = (float)0.0001f * j;
params[0].buffer = &ts;
params[1].buffer = &current;
params[2].buffer = &voltage;
params[3].buffer = &phase;
// bind param
code = taos_stmt_bind_param(stmt, params);
checkError(stmt, code);
}
// add batch
code = taos_stmt_add_batch(stmt);
checkError(stmt, code);
// execute batch
code = taos_stmt_execute(stmt);
checkError(stmt, code);
// get affected rows
int affected = taos_stmt_affected_rows_once(stmt);
total_affected += affected;
taosMemoryFree(table_name);
taosMemoryFree(location);
}
}
ASSERT_EQ(total_affected, CTB_NUMS * ROW_NUMS * CYC_NUMS);
taos_stmt_close(stmt);
}
void getFields(TAOS *taos, const char *sql, int expectedALLFieldNum, TAOS_FIELD_E *expectedTagFields,
int expectedTagFieldNum, TAOS_FIELD_E *expectedColFields, int expectedColFieldNum) {
// create database and table
do_query(taos, "DROP DATABASE IF EXISTS stmt_testdb_3");
do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt_testdb_3");
do_query(taos, "USE stmt_testdb_3");
do_query(
taos,
"CREATE STABLE IF NOT EXISTS stmt_testdb_3.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS "
"(groupId INT, location BINARY(24))");
TAOS_STMT *stmt = taos_stmt_init(taos);
ASSERT_NE(stmt, nullptr);
int code = taos_stmt_prepare(stmt, sql, 0);
checkError(stmt, code);
code = taos_stmt_set_tbname(stmt, "ctb_1");
checkError(stmt, code);
int fieldNum = 0;
TAOS_FIELD_E *pFields = NULL;
code = stmtGetParamNum(stmt, &fieldNum);
checkError(stmt, code);
ASSERT_EQ(fieldNum, expectedColFieldNum);
code = taos_stmt_get_tag_fields(stmt, &fieldNum, &pFields);
checkError(stmt, code);
ASSERT_EQ(fieldNum, expectedTagFieldNum);
for (int i = 0; i < fieldNum; i++) {
ASSERT_STREQ(pFields[i].name, expectedTagFields[i].name);
ASSERT_EQ(pFields[i].type, expectedTagFields[i].type);
ASSERT_EQ(pFields[i].precision, expectedTagFields[i].precision);
// ASSERT_EQ(pFields[i].bytes, expectedTagFields[i].bytes);
ASSERT_EQ(pFields[i].scale, expectedTagFields[i].scale);
}
taosMemoryFree(pFields);
int type;
int bytes;
code = taos_stmt_get_col_fields(stmt, &fieldNum, &pFields);
checkError(stmt, code);
ASSERT_EQ(fieldNum, expectedColFieldNum);
for (int i = 0; i < fieldNum; i++) {
taos_stmt_get_param(stmt, i, &type, &bytes);
ASSERT_EQ(type, pFields[i].type);
ASSERT_EQ(bytes, pFields[i].bytes);
ASSERT_STREQ(pFields[i].name, expectedColFields[i].name);
ASSERT_EQ(pFields[i].type, expectedColFields[i].type);
ASSERT_EQ(pFields[i].precision, expectedColFields[i].precision);
// ASSERT_EQ(pFields[i].bytes, expectedColFields[i].bytes);
ASSERT_EQ(pFields[i].scale, expectedColFields[i].scale);
}
taosMemoryFree(pFields);
taos_stmt_close(stmt);
}
} // namespace
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
TEST(stmtCase, stb_insert) {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
// interlace = 0
{ insertData(taos, nullptr, "INSERT INTO stmt_testdb_2.? USING meters TAGS(?,?) VALUES (?,?,?,?)", 1, 1, 1, false); }
{ insertData(taos, nullptr, "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)", 3, 3, 3, false); }
{ insertData(taos, nullptr, "INSERT INTO ? VALUES (?,?,?,?)", 3, 3, 3, true); }
// interlace = 1
{
TAOS_STMT_OPTIONS options = {0, true, true};
insertData(taos, &options, "INSERT INTO ? VALUES (?,?,?,?)", 3, 3, 3, true);
}
do_query(taos, "DROP DATABASE IF EXISTS stmt_testdb_2");
taos_close(taos);
}
TEST(stmtCase, get_fields) {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
{
TAOS_FIELD_E tagFields[2] = {{"groupid", TSDB_DATA_TYPE_INT, 0, 0, sizeof(int)},
{"location", TSDB_DATA_TYPE_BINARY, 0, 0, 24}};
TAOS_FIELD_E colFields[4] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, sizeof(int64_t)},
{"current", TSDB_DATA_TYPE_FLOAT, 0, 0, sizeof(float)},
{"voltage", TSDB_DATA_TYPE_INT, 0, 0, sizeof(int)},
{"phase", TSDB_DATA_TYPE_FLOAT, 0, 0, sizeof(float)}};
getFields(taos, "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)", 7, &tagFields[0], 2, &colFields[0], 4);
}
do_query(taos, "DROP DATABASE IF EXISTS stmt_testdb_3");
taos_close(taos);
}
TEST(stmtCase, all_type) {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
do_query(taos, "DROP DATABASE IF EXISTS stmt_testdb_1");
do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt_testdb_1");
do_query(
taos,
"CREATE STABLE stmt_testdb_1.stb1(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(8), c6 "
"smallint, c7 "
"tinyint, c8 bool, c9 nchar(8), c10 geometry(100))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 double, t5 "
"binary(8), t6 smallint, t7 tinyint, t8 bool, t9 nchar(8), t10 geometry(100))");
TAOS_STMT *stmt = taos_stmt_init(taos);
ASSERT_NE(stmt, nullptr);
uintptr_t c10len = 0;
struct {
int64_t c1;
int32_t c2;
int64_t c3;
float c4;
double c5;
unsigned char c6[8];
int16_t c7;
int8_t c8;
int8_t c9;
char c10[32];
} v = {1591060628000, 1, 2, 3.0, 4.0, "abcdef", 5, 6, 7, "ijnop"};
struct {
int32_t c1;
int32_t c2;
int32_t c3;
int32_t c4;
int32_t c5;
int32_t c6;
int32_t c7;
int32_t c8;
int32_t c9;
int32_t c10;
} v_len = {sizeof(int64_t), sizeof(int32_t),
sizeof(int64_t), sizeof(float),
sizeof(double), 8,
sizeof(int16_t), sizeof(int8_t),
sizeof(int8_t), 8};
TAOS_MULTI_BIND params[11];
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[0].buffer_length = sizeof(v.c1);
params[0].buffer = &v.c1;
params[0].length = (int32_t *)&params[0].buffer_length;
params[0].is_null = NULL;
params[0].num = 1;
params[1].buffer_type = TSDB_DATA_TYPE_INT;
params[1].buffer_length = sizeof(v.c2);
params[1].buffer = &v.c2;
params[1].length = (int32_t *)&params[1].buffer_length;
params[1].is_null = NULL;
params[1].num = 1;
params[2].buffer_type = TSDB_DATA_TYPE_BIGINT;
params[2].buffer_length = sizeof(v.c3);
params[2].buffer = &v.c3;
params[2].length = (int32_t *)&params[2].buffer_length;
params[2].is_null = NULL;
params[2].num = 1;
params[3].buffer_type = TSDB_DATA_TYPE_FLOAT;
params[3].buffer_length = sizeof(v.c4);
params[3].buffer = &v.c4;
params[3].length = (int32_t *)&params[3].buffer_length;
params[3].is_null = NULL;
params[3].num = 1;
params[4].buffer_type = TSDB_DATA_TYPE_DOUBLE;
params[4].buffer_length = sizeof(v.c5);
params[4].buffer = &v.c5;
params[4].length = (int32_t *)&params[4].buffer_length;
params[4].is_null = NULL;
params[4].num = 1;
params[5].buffer_type = TSDB_DATA_TYPE_BINARY;
params[5].buffer_length = sizeof(v.c6);
params[5].buffer = &v.c6;
params[5].length = (int32_t *)&params[5].buffer_length;
params[5].is_null = NULL;
params[5].num = 1;
params[6].buffer_type = TSDB_DATA_TYPE_SMALLINT;
params[6].buffer_length = sizeof(v.c7);
params[6].buffer = &v.c7;
params[6].length = (int32_t *)&params[6].buffer_length;
params[6].is_null = NULL;
params[6].num = 1;
params[7].buffer_type = TSDB_DATA_TYPE_TINYINT;
params[7].buffer_length = sizeof(v.c8);
params[7].buffer = &v.c8;
params[7].length = (int32_t *)&params[7].buffer_length;
params[7].is_null = NULL;
params[7].num = 1;
params[8].buffer_type = TSDB_DATA_TYPE_BOOL;
params[8].buffer_length = sizeof(v.c9);
params[8].buffer = &v.c9;
params[8].length = (int32_t *)&params[8].buffer_length;
params[8].is_null = NULL;
params[8].num = 1;
params[9].buffer_type = TSDB_DATA_TYPE_NCHAR;
params[9].buffer_length = sizeof(v.c10);
params[9].buffer = &v.c10;
params[9].length = (int32_t *)&c10len;
params[9].is_null = NULL;
params[9].num = 1;
size_t size;
int code = initCtxGeomFromText();
checkError(stmt, code);
unsigned char *outputGeom1;
const char *wkt = "LINESTRING(1.0 1.0, 2.0 2.0)";
code = doGeomFromText(wkt, &outputGeom1, &size);
checkError(stmt, code);
params[10].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
params[10].buffer = outputGeom1;
params[9].buffer_length = size;
params[10].length = (int32_t *)&size;
params[10].is_null = NULL;
params[10].num = 1;
char *stmt_sql = "insert into stmt_testdb_1.? using stb1 tags(?,?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?,?)";
code = taos_stmt_prepare(stmt, stmt_sql, 0);
checkError(stmt, code);
code = taos_stmt_set_tbname(stmt, "ntb");
checkError(stmt, code);
code = taos_stmt_set_tags(stmt, params);
checkError(stmt, code);
code = taos_stmt_bind_param(stmt, params);
checkError(stmt, code);
code = taos_stmt_add_batch(stmt);
checkError(stmt, code);
code = taos_stmt_execute(stmt);
checkError(stmt, code);
taos_stmt_close(stmt);
do_query(taos, "DROP DATABASE IF EXISTS stmt_testdb_1");
taos_close(taos);
}
TEST(stmtCase, geometry) {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
do_query(taos, "DROP DATABASE IF EXISTS stmt_testdb_5");
do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt_testdb_5");
do_query(taos, "CREATE TABLE stmt_testdb_5.tb1(ts timestamp,c1 geometry(256))");
TAOS_STMT *stmt = taos_stmt_init(taos);
ASSERT_NE(stmt, nullptr);
unsigned char wkb1[3][61] = {
{
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
},
{0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f},
{0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40}};
int64_t ts[3] = {1591060628000, 1591060628001, 1591060628002};
int32_t *t64_len = (int32_t *)taosMemoryMalloc(sizeof(int32_t) * 3);
int32_t *wkb_len = (int32_t *)taosMemoryMalloc(sizeof(int32_t) * 3);
for (int i = 0; i < 3; i++) {
t64_len[i] = sizeof(int64_t);
}
wkb_len[0] = 21;
wkb_len[1] = 61;
wkb_len[2] = 41;
TAOS_MULTI_BIND params[2];
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[0].buffer_length = sizeof(int64_t);
params[0].buffer = &ts[0];
params[0].length = t64_len;
params[0].is_null = NULL;
params[0].num = 3;
params[1].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
params[1].buffer_length = 61;
params[1].buffer = wkb1;
params[1].length = wkb_len;
params[1].is_null = NULL;
params[1].num = 3;
char *stmt_sql = "insert into stmt_testdb_5.tb1 (ts,c1)values(?,?)";
int code = taos_stmt_prepare(stmt, stmt_sql, 0);
checkError(stmt, code);
// code = taos_stmt_set_tbname(stmt, "tb1");
// checkError(stmt, code);
code = taos_stmt_bind_param_batch(stmt, params);
checkError(stmt, code);
code = taos_stmt_add_batch(stmt);
checkError(stmt, code);
code = taos_stmt_execute(stmt);
checkError(stmt, code);
taosMemoryFree(t64_len);
taosMemoryFree(wkb_len);
taos_stmt_close(stmt);
do_query(taos, "DROP DATABASE IF EXISTS stmt_testdb_5");
taos_close(taos);
}
#pragma GCC diagnostic pop

View File

@ -14,8 +14,8 @@
*/
#define _DEFAULT_SOURCE
#include "tglobal.h"
#include "tmsg.h"
#include "tglobal.h"
#undef TD_MSG_NUMBER_
#undef TD_MSG_DICT_
@ -11639,16 +11639,14 @@ static int32_t tEncodeSSubmitTbData(SEncoder *pCoder, const SSubmitTbData *pSubm
TAOS_CHECK_EXIT(tEncodeU64v(pCoder, nColData));
for (uint64_t i = 0; i < nColData; i++) {
pCoder->pos +=
tPutColData(SUBMIT_REQUEST_VERSION, pCoder->data ? pCoder->data + pCoder->pos : NULL, &aColData[i]);
TAOS_CHECK_EXIT(tEncodeColData(SUBMIT_REQUEST_VERSION, pCoder, &aColData[i]));
}
} else {
TAOS_CHECK_EXIT(tEncodeU64v(pCoder, TARRAY_SIZE(pSubmitTbData->aRowP)));
SRow **rows = (SRow **)TARRAY_DATA(pSubmitTbData->aRowP);
for (int32_t iRow = 0; iRow < TARRAY_SIZE(pSubmitTbData->aRowP); ++iRow) {
if (pCoder->data) memcpy(pCoder->data + pCoder->pos, rows[iRow], rows[iRow]->len);
pCoder->pos += rows[iRow]->len;
TAOS_CHECK_EXIT(tEncodeRow(pCoder, rows[iRow]));
}
}
TAOS_CHECK_EXIT(tEncodeI64(pCoder, pSubmitTbData->ctimeMs));
@ -11695,7 +11693,7 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa
}
for (int32_t i = 0; i < nColData; ++i) {
pCoder->pos += tGetColData(version, pCoder->data + pCoder->pos, taosArrayReserve(pSubmitTbData->aCol, 1));
TAOS_CHECK_EXIT(tDecodeColData(version, pCoder, taosArrayReserve(pSubmitTbData->aCol, 1)));
}
} else {
uint64_t nRow;
@ -11712,8 +11710,7 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa
TAOS_CHECK_EXIT(terrno);
}
*ppRow = (SRow *)(pCoder->data + pCoder->pos);
pCoder->pos += (*ppRow)->len;
TAOS_CHECK_EXIT(tDecodeRow(pCoder, ppRow));
}
}

View File

@ -2673,7 +2673,7 @@ static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal
};
int32_t tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
if (iVal < 0 || iVal >= pColData->nVal ||
(pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl)/POINTER_BYTES)){
(pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl) / POINTER_BYTES)) {
return TSDB_CODE_INVALID_PARA;
}
tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
@ -3689,25 +3689,25 @@ _exit:
return 0;
}
static int32_t tPutColDataVersion0(uint8_t *pBuf, SColData *pColData) {
int32_t n = 0;
static int32_t tEncodeColDataVersion0(SEncoder *pEncoder, SColData *pColData) {
int32_t code = 0;
n += tPutI16v(pBuf ? pBuf + n : NULL, pColData->cid);
n += tPutI8(pBuf ? pBuf + n : NULL, pColData->type);
n += tPutI32v(pBuf ? pBuf + n : NULL, pColData->nVal);
n += tPutI8(pBuf ? pBuf + n : NULL, pColData->flag);
if ((code = tEncodeI16v(pEncoder, pColData->cid))) return code;
if ((code = tEncodeI8(pEncoder, pColData->type))) return code;
if ((code = tEncodeI32v(pEncoder, pColData->nVal))) return code;
if ((code = tEncodeI8(pEncoder, pColData->flag))) return code;
// bitmap
switch (pColData->flag) {
case (HAS_NULL | HAS_NONE):
case (HAS_VALUE | HAS_NONE):
case (HAS_VALUE | HAS_NULL):
if (pBuf) (void)memcpy(pBuf + n, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
n += BIT1_SIZE(pColData->nVal);
code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
if (code) return code;
break;
case (HAS_VALUE | HAS_NULL | HAS_NONE):
if (pBuf) (void)memcpy(pBuf + n, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
n += BIT2_SIZE(pColData->nVal);
code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
if (code) return code;
break;
default:
break;
@ -3716,40 +3716,46 @@ static int32_t tPutColDataVersion0(uint8_t *pBuf, SColData *pColData) {
// value
if (pColData->flag & HAS_VALUE) {
if (IS_VAR_DATA_TYPE(pColData->type)) {
if (pBuf) (void)memcpy(pBuf + n, pColData->aOffset, pColData->nVal << 2);
n += (pColData->nVal << 2);
code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
if (code) return code;
n += tPutI32v(pBuf ? pBuf + n : NULL, pColData->nData);
if (pBuf) (void)memcpy(pBuf + n, pColData->pData, pColData->nData);
n += pColData->nData;
code = tEncodeI32v(pEncoder, pColData->nData);
if (code) return code;
code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
if (code) return code;
} else {
if (pBuf) (void)memcpy(pBuf + n, pColData->pData, pColData->nData);
n += pColData->nData;
code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
if (code) return code;
}
}
return n;
return code;
}
static int32_t tGetColDataVersion0(uint8_t *pBuf, SColData *pColData) {
int32_t n = 0;
static int32_t tDecodeColDataVersion0(SDecoder *pDecoder, SColData *pColData) {
int32_t code = 0;
n += tGetI16v(pBuf + n, &pColData->cid);
n += tGetI8(pBuf + n, &pColData->type);
n += tGetI32v(pBuf + n, &pColData->nVal);
n += tGetI8(pBuf + n, &pColData->flag);
if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
if (pColData->type <= 0 || pColData->type >= TSDB_DATA_TYPE_MAX || pColData->flag <= 0 || pColData->flag >= 8) {
return TSDB_CODE_INVALID_PARA;
}
// bitmap
switch (pColData->flag) {
case (HAS_NULL | HAS_NONE):
case (HAS_VALUE | HAS_NONE):
case (HAS_VALUE | HAS_NULL):
pColData->pBitMap = pBuf + n;
n += BIT1_SIZE(pColData->nVal);
code = tDecodeBinaryWithSize(pDecoder, BIT1_SIZE(pColData->nVal), &pColData->pBitMap);
if (code) return code;
break;
case (HAS_VALUE | HAS_NULL | HAS_NONE):
pColData->pBitMap = pBuf + n;
n += BIT2_SIZE(pColData->nVal);
code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
if (code) return code;
break;
default:
break;
@ -3758,55 +3764,74 @@ static int32_t tGetColDataVersion0(uint8_t *pBuf, SColData *pColData) {
// value
if (pColData->flag & HAS_VALUE) {
if (IS_VAR_DATA_TYPE(pColData->type)) {
pColData->aOffset = (int32_t *)(pBuf + n);
n += (pColData->nVal << 2);
code = tDecodeBinaryWithSize(pDecoder, pColData->nVal << 2, (uint8_t **)&pColData->aOffset);
if (code) return code;
n += tGetI32v(pBuf + n, &pColData->nData);
pColData->pData = pBuf + n;
n += pColData->nData;
code = tDecodeI32v(pDecoder, &pColData->nData);
if (code) return code;
code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
if (code) return code;
} else {
pColData->pData = pBuf + n;
pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
n += pColData->nData;
code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
if (code) return code;
}
}
pColData->cflag = 0;
return n;
return code;
}
static int32_t tPutColDataVersion1(uint8_t *pBuf, SColData *pColData) {
int32_t n = tPutColDataVersion0(pBuf, pColData);
n += tPutI8(pBuf ? pBuf + n : NULL, pColData->cflag);
return n;
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
if (code) return code;
return tEncodeI8(pEncoder, pColData->cflag);
}
static int32_t tGetColDataVersion1(uint8_t *pBuf, SColData *pColData) {
int32_t n = tGetColDataVersion0(pBuf, pColData);
n += tGetI8(pBuf ? pBuf + n : NULL, &pColData->cflag);
return n;
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
if (code) return code;
code = tDecodeI8(pDecoder, &pColData->cflag);
return code;
}
int32_t tPutColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData) {
if (version == 0) {
return tPutColDataVersion0(pBuf, pColData);
return tEncodeColDataVersion0(pEncoder, pColData);
} else if (version == 1) {
return tPutColDataVersion1(pBuf, pColData);
return tEncodeColDataVersion1(pEncoder, pColData);
} else {
return TSDB_CODE_INVALID_PARA;
}
}
int32_t tGetColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
if (version == 0) {
return tGetColDataVersion0(pBuf, pColData);
return tDecodeColDataVersion0(pDecoder, pColData);
} else if (version == 1) {
return tGetColDataVersion1(pBuf, pColData);
return tDecodeColDataVersion1(pDecoder, pColData);
} else {
return TSDB_CODE_INVALID_PARA;
}
}
int32_t tEncodeRow(SEncoder *pEncoder, SRow *pRow) { return tEncodeFixed(pEncoder, pRow, pRow->len); }
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
if (ppRow == NULL) {
return TSDB_CODE_INVALID_PARA;
}
if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
return TSDB_CODE_OUT_OF_RANGE;
}
SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
}
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
do { \
(SUM) += (VAL); \

View File

@ -2760,6 +2760,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
{"tsmaDataDeleteMark", &tsmaDataDeleteMark},
{"numOfRpcSessions", &tsNumOfRpcSessions},
{"bypassFlag", &tsBypassFlag},
{"safetyCheckLevel", &tsSafetyCheckLevel},
{"streamCoverage", &tsStreamCoverage}};
if ((code = taosCfgSetOption(debugOptions, tListLen(debugOptions), pItem, true)) != TSDB_CODE_SUCCESS) {

View File

@ -231,6 +231,7 @@ int32_t taosGenCrashJsonMsg(int signum, char** pMsg, int64_t clusterId, int64_t
TAOS_CHECK_GOTO(tjsonAddIntegerToObject(pJson, "crashSig", signum), NULL, _exit);
TAOS_CHECK_GOTO(tjsonAddIntegerToObject(pJson, "crashTs", taosGetTimestampUs()), NULL, _exit);
#if 0
#ifdef _TD_DARWIN_64
taosLogTraceToBuf(tmp, sizeof(tmp), 4);
#elif !defined(WINDOWS)
@ -240,7 +241,7 @@ int32_t taosGenCrashJsonMsg(int signum, char** pMsg, int64_t clusterId, int64_t
#endif
TAOS_CHECK_GOTO(tjsonAddStringToObject(pJson, "stackInfo", tmp), NULL, _exit);
#endif
char* pCont = tjsonToString(pJson);
if (pCont == NULL) {
code = terrno;

View File

@ -131,25 +131,7 @@ void dmLogCrash(int signum, void *sigInfo, void *context) {
if (taosIgnSignal(SIGSEGV) != 0) {
dWarn("failed to ignore signal SIGABRT");
}
char *pMsg = NULL;
const char *flags = "UTL FATAL ";
ELogLevel level = DEBUG_FATAL;
int32_t dflag = 255;
int64_t msgLen = -1;
if (tsEnableCrashReport) {
if (taosGenCrashJsonMsg(signum, &pMsg, dmGetClusterId(), global.startTime)) {
taosPrintLog(flags, level, dflag, "failed to generate crash json msg");
goto _return;
} else {
msgLen = strlen(pMsg);
}
}
_return:
taosLogCrashInfo(CUS_PROMPT "d", pMsg, msgLen, signum, sigInfo);
writeCrashLogToFile(signum, sigInfo, CUS_PROMPT "d", dmGetClusterId(), global.startTime);
#ifdef _TD_DARWIN_64
exit(signum);
@ -177,6 +159,15 @@ static void dmSetSignalHandle() {
if (taosSetSignal(SIGBREAK, dmStopDnode) != 0) {
dWarn("failed to set signal SIGUSR1");
}
if (taosSetSignal(SIGABRT, dmLogCrash) != 0) {
dWarn("failed to set signal SIGUSR1");
}
if (taosSetSignal(SIGFPE, dmLogCrash) != 0) {
dWarn("failed to set signal SIGUSR1");
}
if (taosSetSignal(SIGSEGV, dmLogCrash) != 0) {
dWarn("failed to set signal SIGUSR1");
}
#ifndef WINDOWS
if (taosSetSignal(SIGTSTP, dmStopDnode) != 0) {
dWarn("failed to set signal SIGUSR1");
@ -184,6 +175,9 @@ static void dmSetSignalHandle() {
if (taosSetSignal(SIGQUIT, dmStopDnode) != 0) {
dWarn("failed to set signal SIGUSR1");
}
if (taosSetSignal(SIGBUS, dmLogCrash) != 0) {
dWarn("failed to set signal SIGUSR1");
}
#endif
}

View File

@ -274,14 +274,22 @@ static void *dmCrashReportThreadFp(void *param) {
dError("failed to init telemetry since %s", tstrerror(code));
return NULL;
}
code = initCrashLogWriter();
if (code != 0) {
dError("failed to init crash log writer since %s", tstrerror(code));
return NULL;
}
while (1) {
if (pMgmt->pData->dropped || pMgmt->pData->stopped) break;
checkAndPrepareCrashInfo();
if ((pMgmt->pData->dropped || pMgmt->pData->stopped) && reportThreadSetQuit()) {
break;
}
if (loopTimes++ < reportPeriodNum) {
taosMsleep(sleepTime);
if(loopTimes < 0) loopTimes = reportPeriodNum;
continue;
}
taosReadCrashInfo(filepath, &pMsg, &msgLen, &pFile);
if (pMsg && msgLen > 0) {
if (taosSendTelemReport(&mgt, tsSvrCrashReportUri, tsTelemPort, pMsg, msgLen, HTTP_FLAT) != 0) {

View File

@ -114,6 +114,8 @@ SArray *mmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_CONFIG_DNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_SDB_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE_TYPE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
@ -130,6 +132,7 @@ SArray *mmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_MND_GET_USER_AUTH, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_DNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_DNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_SDB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_DNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_MNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_MNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;

View File

@ -254,7 +254,15 @@ static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) {
pRpc->info.wrapper = pWrapper;
EQItype itype = IsReq(pRpc) ? RPC_QITEM : DEF_QITEM; // rsp msg is not restricted by tsQueueMemoryUsed
EQItype itype = RPC_QITEM; // rsp msg is not restricted by tsQueueMemoryUsed
if (IsReq(pRpc)) {
if (pRpc->msgType == TDMT_SYNC_HEARTBEAT || pRpc->msgType == TDMT_SYNC_HEARTBEAT_REPLY)
itype = DEF_QITEM;
else
itype = RPC_QITEM;
} else {
itype = DEF_QITEM;
}
code = taosAllocateQitem(sizeof(SRpcMsg), itype, pRpc->contLen, (void **)&pMsg);
if (code) goto _OVER;

View File

@ -328,12 +328,12 @@ typedef struct {
};
} SConfigObj;
int32_t tEncodeSConfigObj(SEncoder* pEncoder, const SConfigObj* pObj);
int32_t tDecodeSConfigObj(SDecoder* pDecoder, SConfigObj* pObj);
SConfigObj* mndInitConfigObj(SConfigItem* pItem);
SConfigObj* mndInitConfigVersion();
int32_t mndUpdateObj(SConfigObj* pObj, const char* name, char* value);
void tFreeSConfigObj(SConfigObj* obj);
int32_t tEncodeSConfigObj(SEncoder* pEncoder, const SConfigObj* pObj);
int32_t tDecodeSConfigObj(SDecoder* pDecoder, SConfigObj* pObj);
int32_t mndInitConfigObj(SConfigItem* pItem, SConfigObj* pObj);
SConfigObj mndInitConfigVersion();
int32_t mndUpdateObj(SConfigObj* pObj, const char* name, char* value);
void tFreeSConfigObj(SConfigObj* obj);
typedef struct {
int32_t maxUsers;

View File

@ -17,6 +17,7 @@
#include "audit.h"
#include "mndConfig.h"
#include "mndDnode.h"
#include "mndMnode.h"
#include "mndPrivilege.h"
#include "mndSync.h"
#include "mndTrans.h"
@ -33,8 +34,10 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq);
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp);
static int32_t mndProcessConfigReq(SRpcMsg *pReq);
static int32_t mndInitWriteCfg(SMnode *pMnode);
static int32_t mndTryRebuildCfg(SMnode *pMnode);
static int32_t mndSendRebuildReq(SMnode *pMnode);
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp);
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array);
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq);
static void cfgArrayCleanUp(SArray *array);
static void cfgObjArrayCleanUp(SArray *array);
@ -59,6 +62,8 @@ int32_t mndInitConfig(SMnode *pMnode) {
mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp);
mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB, mndTryRebuildConfigSdb);
mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB_RSP, mndTryRebuildConfigSdbRsp);
return sdbSetTable(pMnode->pSdb, table);
}
@ -214,7 +219,7 @@ static int32_t mndCfgActionUpdate(SSdb *pSdb, SConfigObj *pOld, SConfigObj *pNew
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndTryRebuildCfg(pMnode); }
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndSendRebuildReq(pMnode); }
static int32_t mndProcessConfigReq(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
@ -303,32 +308,27 @@ int32_t mndInitWriteCfg(SMnode *pMnode) {
}
// encode mnd config version
SConfigObj *versionObj = mndInitConfigVersion();
if ((code = mndSetCreateConfigCommitLogs(pTrans, versionObj)) != 0) {
SConfigObj versionObj = mndInitConfigVersion();
if ((code = mndSetCreateConfigCommitLogs(pTrans, &versionObj)) != 0) {
mError("failed to init mnd config version, since %s", tstrerror(code));
tFreeSConfigObj(versionObj);
taosMemoryFree(versionObj);
tFreeSConfigObj(&versionObj);
goto _OVER;
}
tFreeSConfigObj(versionObj);
taosMemoryFree(versionObj);
tFreeSConfigObj(&versionObj);
sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
for (int i = 0; i < sz; ++i) {
SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
SConfigObj *obj = mndInitConfigObj(item);
if (obj == NULL) {
code = terrno;
SConfigObj obj;
if ((code = mndInitConfigObj(item, &obj)) != 0) {
goto _OVER;
}
if ((code = mndSetCreateConfigCommitLogs(pTrans, obj)) != 0) {
if ((code = mndSetCreateConfigCommitLogs(pTrans, &obj)) != 0) {
mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
tFreeSConfigObj(obj);
taosMemoryFree(obj);
tFreeSConfigObj(&obj);
goto _OVER;
}
tFreeSConfigObj(obj);
taosMemoryFree(obj);
tFreeSConfigObj(&obj);
}
if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
@ -340,15 +340,38 @@ _OVER:
return code;
}
int32_t mndTryRebuildCfg(SMnode *pMnode) {
int32_t mndSendRebuildReq(SMnode *pMnode) {
int32_t code = 0;
SRpcMsg rpcMsg = {.pCont = NULL,
.contLen = 0,
.msgType = TDMT_MND_CONFIG_SDB,
.info.ahandle = 0,
.info.notFreeAhandle = 1,
.info.refId = 0,
.info.noResp = 0,
.info.handle = 0};
SEpSet epSet = {0};
mndGetMnodeEpSet(pMnode, &epSet);
code = tmsgSendReq(&epSet, &rpcMsg);
if (code != 0) {
mError("failed to send rebuild config req, since %s", tstrerror(code));
}
return code;
}
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
if (!mndIsLeader(pMnode)) {
return TSDB_CODE_SUCCESS;
}
int32_t code = 0;
int32_t sz = -1;
STrans *pTrans = NULL;
SAcctObj *vObj = NULL, *obj = NULL;
SArray *addArray = NULL;
int32_t code = 0;
int32_t sz = -1;
STrans *pTrans = NULL;
SConfigObj *vObj = NULL;
SArray *addArray = NULL;
vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
if (vObj == NULL) {
@ -359,14 +382,12 @@ int32_t mndTryRebuildCfg(SMnode *pMnode) {
addArray = taosArrayInit(4, sizeof(SConfigObj));
for (int i = 0; i < sz; ++i) {
SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
obj = sdbAcquire(pMnode->pSdb, SDB_CFG, item->name);
SConfigObj *obj = sdbAcquire(pMnode->pSdb, SDB_CFG, item->name);
if (obj == NULL) {
SConfigObj *newObj = mndInitConfigObj(item);
if (newObj == NULL) {
code = terrno;
goto _exit;
}
if (NULL == taosArrayPush(addArray, newObj)) {
mInfo("config:%s, not exist in sdb, try to add it", item->name);
SConfigObj newObj;
if ((code = mndInitConfigObj(item, &newObj)) != 0) goto _exit;
if (NULL == taosArrayPush(addArray, &newObj)) {
code = terrno;
goto _exit;
}
@ -394,7 +415,6 @@ _exit:
mError("failed to try rebuild config in sdb, since %s", tstrerror(code));
}
sdbRelease(pMnode->pSdb, vObj);
sdbRelease(pMnode->pSdb, obj);
cfgObjArrayCleanUp(addArray);
mndTransDrop(pTrans);
TAOS_RETURN(code);
@ -518,6 +538,8 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
SMCfgDnodeReq cfgReq = {0};
SConfigObj *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
if (vObj == NULL) {
code = TSDB_CODE_SDB_OBJ_NOT_THERE;
mInfo("failed to acquire mnd config version, since %s", tstrerror(code));
goto _err_out;
}
@ -609,6 +631,11 @@ static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
return 0;
}
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp) {
mInfo("rebuild config sdb rsp");
return 0;
}
// get int32_t value from 'SMCfgDnodeReq'
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
int32_t code = 0;
@ -770,7 +797,6 @@ static void cfgObjArrayCleanUp(SArray *array) {
for (int32_t i = 0; i < sz; ++i) {
SConfigObj *obj = taosArrayGet(array, i);
tFreeSConfigObj(obj);
taosMemoryFree(obj);
}
taosArrayDestroy(array);
}

View File

@ -263,7 +263,7 @@ static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
MND_TMQ_RETURN_CHECK(mndAcquireConsumer(pMnode, consumerId, &pConsumer));
MND_TMQ_RETURN_CHECK(checkPrivilege(pMnode, pConsumer, &rsp, pMsg->info.conn.user));
atomic_store_32(&pConsumer->hbStatus, 0);
mDebug("consumer:0x%" PRIx64 " receive hb pollFlag:%d %d", consumerId, req.pollFlag, pConsumer->pollStatus);
mDebug("consumer:0x%" PRIx64 " receive hb pollFlag:%d pollStatus:%d", consumerId, req.pollFlag, pConsumer->pollStatus);
if (req.pollFlag == 1){
atomic_store_32(&pConsumer->pollStatus, 0);
}

View File

@ -730,11 +730,7 @@ void *tDecodeSubscribeObj(const void *buf, SMqSubscribeObj *pSub, int8_t sver) {
return (void *)buf;
}
SConfigObj *mndInitConfigObj(SConfigItem *pItem) {
SConfigObj *pObj = taosMemoryCalloc(1, sizeof(SConfigObj));
if (pObj == NULL) {
return NULL;
}
int32_t mndInitConfigObj(SConfigItem *pItem, SConfigObj *pObj) {
tstrncpy(pObj->name, pItem->name, CFG_NAME_MAX_LEN);
pObj->dtype = pItem->dtype;
switch (pItem->dtype) {
@ -761,11 +757,11 @@ SConfigObj *mndInitConfigObj(SConfigItem *pItem) {
pObj->str = taosStrdup(pItem->str);
if (pObj->str == NULL) {
taosMemoryFree(pObj);
return NULL;
return TSDB_CODE_OUT_OF_MEMORY;
}
break;
}
return pObj;
return TSDB_CODE_SUCCESS;
}
int32_t mndUpdateObj(SConfigObj *pObjNew, const char *name, char *value) {
@ -822,15 +818,14 @@ int32_t mndUpdateObj(SConfigObj *pObjNew, const char *name, char *value) {
return code;
}
SConfigObj *mndInitConfigVersion() {
SConfigObj *pObj = taosMemoryCalloc(1, sizeof(SConfigObj));
if (pObj == NULL) {
return NULL;
}
tstrncpy(pObj->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
pObj->dtype = CFG_DTYPE_INT32;
pObj->i32 = 0;
return pObj;
SConfigObj mndInitConfigVersion() {
SConfigObj obj;
memset(&obj, 0, sizeof(SConfigObj));
tstrncpy(obj.name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
obj.dtype = CFG_DTYPE_INT32;
obj.i32 = 0;
return obj;
}
int32_t tEncodeSConfigObj(SEncoder *pEncoder, const SConfigObj *pObj) {

View File

@ -1168,8 +1168,6 @@ static int32_t mndCheckTaskAndNodeStatus(SMnode *pMnode) {
}
}
SArray *pInvalidList = taosArrayInit(4, sizeof(STaskId));
for (int32_t i = 0; i < taosArrayGetSize(execInfo.pTaskList); ++i) {
STaskId *p = taosArrayGet(execInfo.pTaskList, i);
if (p == NULL) {
@ -1181,23 +1179,6 @@ static int32_t mndCheckTaskAndNodeStatus(SMnode *pMnode) {
continue;
}
if (pEntry->status == TASK_STATUS__STOP) {
for (int32_t j = 0; j < taosArrayGetSize(pInvalidList); ++j) {
STaskId *pId = taosArrayGet(pInvalidList, j);
if (pId == NULL) {
continue;
}
if (pEntry->id.streamId == pId->streamId) {
void *px = taosArrayPush(pInvalidList, &pEntry->id);
if (px == NULL) {
mError("failed to put stream into invalid list, code:%s", tstrerror(TSDB_CODE_OUT_OF_MEMORY));
}
break;
}
}
}
if (pEntry->status != TASK_STATUS__READY) {
mDebug("s-task:0x%" PRIx64 "-0x%x (nodeId:%d) status:%s, checkpoint not issued", pEntry->id.streamId,
(int32_t)pEntry->id.taskId, pEntry->nodeId, streamTaskGetStatusStr(pEntry->status));
@ -1215,9 +1196,6 @@ static int32_t mndCheckTaskAndNodeStatus(SMnode *pMnode) {
}
}
removeTasksInBuf(pInvalidList, &execInfo);
taosArrayDestroy(pInvalidList);
streamMutexUnlock(&execInfo.lock);
return ready ? 0 : -1;
}
@ -1258,6 +1236,30 @@ static int32_t streamWaitComparFn(const void *p1, const void *p2) {
return pInt1->duration > pInt2->duration ? -1 : 1;
}
// all tasks of this stream should be ready, otherwise do nothing
static bool isStreamReadyHelp(int64_t now, SStreamObj* pStream) {
bool ready = false;
streamMutexLock(&execInfo.lock);
int64_t lastReadyTs = getStreamTaskLastReadyState(execInfo.pTaskList, pStream->uid);
if ((lastReadyTs == -1) || ((lastReadyTs != -1) && ((now - lastReadyTs) < tsStreamCheckpointInterval * 1000))) {
if (lastReadyTs != -1) {
mInfo("not start checkpoint, stream:0x%"PRIx64" last ready ts:%"PRId64" ready duration:%"PRId64" less than threshold",
pStream->uid, lastReadyTs, now - lastReadyTs);
} else {
mInfo("not start checkpoint, stream:0x%"PRIx64" not ready now", pStream->uid);
}
ready = false;
} else {
ready = true;
}
streamMutexUnlock(&execInfo.lock);
return ready;
}
static int32_t mndProcessStreamCheckpoint(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
SSdb *pSdb = pMnode->pSdb;
@ -1284,20 +1286,17 @@ static int32_t mndProcessStreamCheckpoint(SRpcMsg *pReq) {
continue;
}
streamMutexLock(&execInfo.lock);
int64_t startTs = getStreamTaskLastReadyState(execInfo.pTaskList, pStream->uid);
if (startTs != -1 && (now - startTs) < tsStreamCheckpointInterval * 1000) {
streamMutexUnlock(&execInfo.lock);
bool ready = isStreamReadyHelp(now, pStream);
if (!ready) {
sdbRelease(pSdb, pStream);
continue;
}
streamMutexUnlock(&execInfo.lock);
SCheckpointInterval in = {.streamId = pStream->uid, .duration = duration};
void *p = taosArrayPush(pList, &in);
if (p) {
int32_t currentSize = taosArrayGetSize(pList);
mDebug("stream:%s (uid:0x%" PRIx64 ") total %d stream(s) beyond chpt interval threshold: %ds(%" PRId64
mDebug("stream:%s (uid:0x%" PRIx64 ") total %d stream(s) beyond chkpt interval threshold: %ds(%" PRId64
"s), concurrently launch threshold:%d",
pStream->name, pStream->uid, currentSize, tsStreamCheckpointInterval, duration / 1000,
tsMaxConcurrentCheckpoint);

View File

@ -309,9 +309,6 @@ void mndRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
} else {
mInfo("vgId:1, sync restore finished, repeat call");
}
if (sdbAfterRestored(pMnode->pSdb) != 0) {
mError("failed to prepare sdb while start mnode");
}
} else {
mInfo("vgId:1, sync restore finished");
}
@ -329,6 +326,17 @@ void mndRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
}
}
void mndAfterRestored(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
SMnode *pMnode = pFsm->data;
if (!pMnode->deploy) {
if (sdbAfterRestored(pMnode->pSdb) != 0) {
mError("failed to prepare sdb while start mnode");
}
mInfo("vgId:1, sync restore finished and restore sdb success");
}
}
int32_t mndSnapshotStartRead(const SSyncFSM *pFsm, void *pParam, void **ppReader) {
mInfo("start to read snapshot from sdb");
SMnode *pMnode = pFsm->data;
@ -443,6 +451,7 @@ SSyncFSM *mndSyncMakeFsm(SMnode *pMnode) {
pFsm->FpPreCommitCb = NULL;
pFsm->FpRollBackCb = NULL;
pFsm->FpRestoreFinishCb = mndRestoreFinish;
pFsm->FpAfterRestoredCb = mndAfterRestored;
pFsm->FpLeaderTransferCb = NULL;
pFsm->FpApplyQueueEmptyCb = mndApplyQueueEmpty;
pFsm->FpApplyQueueItems = mndApplyQueueItems;

View File

@ -61,6 +61,7 @@ static FORCE_INLINE tb_uid_t metaGenerateUid(SMeta* pMeta) { return tGenIdPI64()
// metaTable ==================
int32_t metaHandleEntry2(SMeta* pMeta, const SMetaEntry* pEntry);
void metaHandleSyncEntry(SMeta* pMeta, const SMetaEntry* pEntry);
// metaCache ==================
int32_t metaCacheOpen(SMeta* pMeta);

View File

@ -112,13 +112,12 @@ int32_t tDecodeSTqHandle(SDecoder* pDecoder, STqHandle* pHandle);
void tqDestroyTqHandle(void* data);
// tqRead
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBatchMetaRsp* pBatchMetaRsp, STqOffsetVal* offset);
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBatchMetaRsp* pBatchMetaRsp, STqOffsetVal* offset, int64_t timeout);
int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* pOffset, const SMqPollReq* pRequest);
int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t reqId);
// tqExec
int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, int8_t sourceExcluded);
int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision);
int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp,
int32_t type, int32_t vgId);
void tqPushEmptyDataRsp(STqHandle* pHandle, int32_t vgId);
@ -178,6 +177,7 @@ int32_t tqExtractDropCtbDataBlock(const void* data, int32_t len, int64_t ver, vo
#define TQ_SUBSCRIBE_NAME "subscribe"
#define TQ_OFFSET_NAME "offset-ver0"
#define TQ_POLL_MAX_TIME 1000
#ifdef __cplusplus
}

View File

@ -78,6 +78,7 @@ int32_t vnodeAsyncC(SVAChannelID* channelID, EVAPriority priority, int32_t (*exe
void vnodeAWait(SVATaskID* taskID);
int32_t vnodeACancel(SVATaskID* taskID);
int32_t vnodeAsyncSetWorkers(int64_t async, int32_t numWorkers);
bool vnodeATaskValid(SVATaskID* taskID);
const char* vnodeGetATaskName(EVATaskT task);

View File

@ -1915,3 +1915,12 @@ int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry) {
}
TAOS_RETURN(code);
}
void metaHandleSyncEntry(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
code = metaHandleEntry2(pMeta, pEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
}
return;
}

View File

@ -197,8 +197,7 @@ int32_t metaSnapWrite(SMetaSnapWriter* pWriter, uint8_t* pData, uint32_t nData)
code = metaDecodeEntry(pDecoder, &metaEntry);
TSDB_CHECK_CODE(code, lino, _exit);
code = metaHandleEntry2(pMeta, &metaEntry);
TSDB_CHECK_CODE(code, lino, _exit);
metaHandleSyncEntry(pMeta, &metaEntry);
_exit:
if (code) {

View File

@ -15,16 +15,13 @@
#include "tq.h"
int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision) {
int32_t code = TDB_CODE_SUCCESS;
int32_t lino = 0;
void* buf = NULL;
TSDB_CHECK_NULL(pBlock, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pRsp, code, lino, END, TSDB_CODE_INVALID_PARA);
static int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision) {
int32_t code = 0;
int32_t lino = 0;
size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
int32_t dataStrLen = sizeof(SRetrieveTableRspForTmq) + dataEncodeBufSize;
buf = taosMemoryCalloc(1, dataStrLen);
void* buf = taosMemoryCalloc(1, dataStrLen);
TSDB_CHECK_NULL(buf, code, lino, END, terrno);
SRetrieveTableRspForTmq* pRetrieve = (SRetrieveTableRspForTmq*)buf;
@ -35,16 +32,17 @@ int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t
int32_t actualLen = blockEncode(pBlock, pRetrieve->data, dataEncodeBufSize, numOfCols);
TSDB_CHECK_CONDITION(actualLen >= 0, code, lino, END, terrno);
actualLen += sizeof(SRetrieveTableRspForTmq);
TSDB_CHECK_NULL(taosArrayPush(pRsp->blockDataLen, &actualLen), code, lino, END, terrno);
TSDB_CHECK_NULL(taosArrayPush(pRsp->blockData, &buf), code, lino, END, terrno);
tqDebug("add block data to block array, blockDataLen:%d, blockData:%p", actualLen, buf);
buf = NULL;
END:
if (code != TSDB_CODE_SUCCESS) {
taosMemoryFree(buf);
tqError("%s failed at %d, failed to add block data to response:%s", __FUNCTION__, lino, tstrerror(code));
if (code != 0){
tqError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code));
}
taosMemoryFree(buf);
return code;
}
@ -173,7 +171,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
TSDB_CHECK_CODE(code, lino, END);
qStreamSetSourceExcluded(task, pRequest->sourceExcluded);
uint64_t st = taosGetTimestampMs();
int64_t st = taosGetTimestampMs();
while (1) {
SSDataBlock* pDataBlock = NULL;
code = getDataBlock(task, pHandle, vgId, &pDataBlock);
@ -192,7 +190,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
pRsp->blockNum++;
totalRows += pDataBlock->info.rows;
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > 1000)) {
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout))) {
break;
}
}
@ -207,22 +205,18 @@ END:
return code;
}
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBatchMetaRsp* pBatchMetaRsp, STqOffsetVal* pOffset) {
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBatchMetaRsp* pBatchMetaRsp, STqOffsetVal* pOffset, int64_t timeout) {
int32_t code = 0;
int32_t lino = 0;
char* tbName = NULL;
SSchemaWrapper* pSW = NULL;
TSDB_CHECK_NULL(pRsp, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pTq, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pHandle, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pOffset, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pBatchMetaRsp, code, lino, END, TSDB_CODE_INVALID_PARA);
const STqExecHandle* pExec = &pHandle->execHandle;
qTaskInfo_t task = pExec->task;
code = qStreamPrepareScan(task, pOffset, pHandle->execHandle.subType);
TSDB_CHECK_CODE(code, lino, END);
int32_t rowCnt = 0;
int64_t st = taosGetTimestampMs();
while (1) {
SSDataBlock* pDataBlock = NULL;
uint64_t ts = 0;
@ -236,20 +230,23 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBat
tbName = taosStrdup(qExtractTbnameFromTask(task));
TSDB_CHECK_NULL(tbName, code, lino, END, terrno);
TSDB_CHECK_NULL(taosArrayPush(pRsp->blockTbName, &tbName), code, lino, END, terrno);
tqDebug("vgId:%d, add tbname:%s to rsp msg", pTq->pVnode->config.vgId, tbName);
tbName = NULL;
}
if (pRsp->withSchema) {
pSW = tCloneSSchemaWrapper(qExtractSchemaFromTask(task));
SSchemaWrapper* pSW = tCloneSSchemaWrapper(qExtractSchemaFromTask(task));
TSDB_CHECK_NULL(pSW, code, lino, END, terrno);
TSDB_CHECK_NULL(taosArrayPush(pRsp->blockSchema, &pSW), code, lino, END, terrno);
pSW = NULL;
}
code = tqAddBlockDataToRsp(pDataBlock, pRsp, taosArrayGetSize(pDataBlock->pDataBlock), pTq->pVnode->config.tsdbCfg.precision);
code = tqAddBlockDataToRsp(pDataBlock, pRsp, taosArrayGetSize(pDataBlock->pDataBlock),
pTq->pVnode->config.tsdbCfg.precision);
TSDB_CHECK_CODE(code, lino, END);
pRsp->blockNum++;
rowCnt += pDataBlock->info.rows;
if (rowCnt <= tmqRowSize) {
if (rowCnt <= tmqRowSize && (taosGetTimestampMs() - st <= TMIN(TQ_POLL_MAX_TIME, timeout))) {
continue;
}
}
@ -283,11 +280,10 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBat
break;
}
}
tqDebug("%s:%d success", __FUNCTION__, lino);
END:
if (code != 0){
tqDebug("%s:%d failed, code:%s", __FUNCTION__, lino, tstrerror(code) );
tqError("%s failed at %d, vgId:%d, task exec error since %s", __FUNCTION__ , lino, pTq->pVnode->config.vgId, tstrerror(code));
}
taosMemoryFree(pSW);
taosMemoryFree(tbName);
@ -422,4 +418,4 @@ END:
tqError("%s failed at %d, failed to scan log:%s", __FUNCTION__, lino, tstrerror(code));
}
return code;
}
}

View File

@ -1047,8 +1047,6 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
pTableSinkInfo->uid = 0;
code = doPutSinkTableInfoIntoCache(pTask->outputInfo.tbSink.pTbInfo, pTableSinkInfo, groupId, id);
} else {
metaReaderClear(&mr);
tqError("s-task:%s vgId:%d dst-table:%s not auto-created, and not create in tsdb, discard data", id, vgId,
dstTableName);
return TSDB_CODE_TDB_TABLE_NOT_EXIST;

View File

@ -101,7 +101,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
char formatBuf[TSDB_OFFSET_LEN] = {0};
tFormatOffset(formatBuf, TSDB_OFFSET_LEN, pOffsetVal);
tqDebug("tmq poll: consumer:0x%" PRIx64
", subkey %s, vgId:%d, existed offset found, offset reset to %s and continue.QID:0x%" PRIx64,
", subkey %s, vgId:%d, existed offset found, offset reset to %s and continue.QID:0x%" PRIx64,
consumerId, pHandle->subKey, vgId, formatBuf, pRequest->reqId);
return 0;
} else {
@ -138,7 +138,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
return code;
} else if (pRequest->reqOffset.type == TMQ_OFFSET__RESET_NONE) {
tqError("tmq poll: subkey:%s, no offset committed for consumer:0x%" PRIx64
" in vg %d, subkey %s, reset none failed",
" in vg %d, subkey %s, reset none failed",
pHandle->subKey, consumerId, vgId, pRequest->subKey);
return TSDB_CODE_TQ_NO_COMMITTED_OFFSET;
}
@ -231,7 +231,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
TQ_ERR_GO_TO_END(tqInitTaosxRsp(&taosxRsp, *offset));
if (offset->type != TMQ_OFFSET__LOG) {
TQ_ERR_GO_TO_END(tqScanTaosx(pTq, pHandle, &taosxRsp, &btMetaRsp, offset));
TQ_ERR_GO_TO_END(tqScanTaosx(pTq, pHandle, &taosxRsp, &btMetaRsp, offset, pRequest->timeout));
if (taosArrayGetSize(btMetaRsp.batchMetaReq) > 0) {
code = tqSendBatchMetaPollRsp(pHandle, pMsg, pRequest, &btMetaRsp, vgId);
@ -274,7 +274,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
}
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer);
code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp,
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
goto END;
}
@ -287,7 +287,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
if (totalRows > 0) {
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer);
code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp,
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
goto END;
}
@ -349,7 +349,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
TQ_NULL_GO_TO_END (taosArrayPush(btMetaRsp.batchMetaReq, &tBuf));
TQ_NULL_GO_TO_END (taosArrayPush(btMetaRsp.batchMetaLen, &tLen));
totalMetaRows++;
if ((taosArrayGetSize(btMetaRsp.batchMetaReq) >= tmqRowSize) || (taosGetTimestampMs() - st > 1000)) {
if ((taosArrayGetSize(btMetaRsp.batchMetaReq) >= tmqRowSize) || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout))) {
tqOffsetResetToLog(&btMetaRsp.rspOffset, fetchVer);
code = tqSendBatchMetaPollRsp(pHandle, pMsg, pRequest, &btMetaRsp, vgId);
goto END;
@ -372,10 +372,10 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
TQ_ERR_GO_TO_END(tqTaosxScanLog(pTq, pHandle, submit, &taosxRsp, &totalRows, pRequest->sourceExcluded));
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > 1000)) {
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout))) {
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer + 1);
code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp,
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
goto END;
} else {
fetchVer++;
@ -386,7 +386,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
END:
if (code != 0){
tqError("tmq poll: tqTaosxScanLog error. consumerId:0x%" PRIx64 ", in vgId:%d, subkey %s", pRequest->consumerId, vgId,
pRequest->subKey);
pRequest->subKey);
}
tDeleteMqBatchMetaRsp(&btMetaRsp);
tDeleteSTaosxRsp(&taosxRsp);
@ -794,4 +794,4 @@ _exit:
taosMemoryFree(pBlock);
}
return code;
}
}

View File

@ -801,7 +801,6 @@ int32_t tsdbDisableAndCancelAllBgTask(STsdb *pTsdb) {
(void)taosThreadMutexUnlock(&pTsdb->mutex);
return terrno;
}
fset->mergeScheduled = false;
tsdbFSSetBlockCommit(fset, false);
}
@ -945,7 +944,7 @@ int32_t tsdbFSEditCommit(STFileSystem *fs) {
// bool skipMerge = false;
int32_t numFile = TARRAY2_SIZE(lvl->fobjArr);
if (numFile >= sttTrigger && (!fset->mergeScheduled)) {
if (numFile >= sttTrigger && (!vnodeATaskValid(&fset->mergeTask))) {
SMergeArg *arg = taosMemoryMalloc(sizeof(*arg));
if (arg == NULL) {
code = terrno;
@ -957,7 +956,6 @@ int32_t tsdbFSEditCommit(STFileSystem *fs) {
code = vnodeAsync(MERGE_TASK_ASYNC, EVA_PRIORITY_HIGH, tsdbMerge, taosAutoMemoryFree, arg, &fset->mergeTask);
TSDB_CHECK_CODE(code, lino, _exit);
fset->mergeScheduled = true;
}
if (numFile >= sttTrigger * BLOCK_COMMIT_FACTOR) {

Some files were not shown because too many files have changed in this diff Show More