Merge branches 'test/cover1' and '3.0' of github.com:taosdata/TDengine into test/cover1

This commit is contained in:
happyguoxy 2025-03-20 09:59:44 +08:00
commit 8de611ea42
301 changed files with 9890 additions and 7671 deletions

View File

@ -81,6 +81,8 @@ jobs:
-DBUILD_KEEPER=true \
-DBUILD_HTTP=false \
-DBUILD_TEST=true \
-DWEBSOCKET=true \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_DEPENDENCY_TESTS=false
make -j 4
sudo make install

View File

@ -33,7 +33,9 @@ on:
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}-${{ github.event.inputs.specified_target_branch }}-${{ github.event.inputs.specified_pr_number }}-TDengine
group: ${{ github.workflow }}-${{ github.event_name }}-
${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || inputs.specified_target_branch }}-
${{ github.event_name == 'pull_request' && github.event.pull_request.number || inputs.specified_pr_number }}-TDengine
cancel-in-progress: true
env:
@ -42,27 +44,24 @@ env:
jobs:
run-tests-on-linux:
uses: taosdata/.github/.github/workflows/run-tests-on-linux.yml@main
if: ${{ github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'}}
with:
tdinternal: false
specified_source_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_source_branch }}
specified_target_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_target_branch }}
specified_pr_number: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_pr_number }}
specified_source_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_source_branch }}
specified_target_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_target_branch }}
specified_pr_number: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_pr_number }}
run-tests-on-mac:
uses: taosdata/.github/.github/workflows/run-tests-on-macos.yml@main
if: ${{ github.event_name == 'pull_request' }}
with:
tdinternal: false
specified_source_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_source_branch }}
specified_target_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_target_branch }}
specified_pr_number: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_pr_number }}
specified_source_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_source_branch }}
specified_target_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_target_branch }}
specified_pr_number: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_pr_number }}
run-tests-on-windows:
uses: taosdata/.github/.github/workflows/run-tests-on-windows.yml@main
if: ${{ github.event_name == 'pull_request' }}
with:
tdinternal: false
specified_source_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_source_branch }}
specified_target_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_target_branch }}
specified_pr_number: ${{ github.event_name == 'pull_request' && 'unavailable' || github.event.inputs.specified_pr_number }}
specified_source_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_source_branch }}
specified_target_branch: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_target_branch }}
specified_pr_number: ${{ github.event_name == 'pull_request' && 'unavailable' || inputs.specified_pr_number }}

View File

@ -1,3 +1,5 @@
# Run unit-test and system-test cases for TDgpt when TDgpt code is changed.
name: TDgpt Test
on:

View File

@ -1,3 +1,5 @@
# Scheduled updates for the TDgpt service.
name: TDgpt Update Service
on:

1
.gitignore vendored
View File

@ -132,7 +132,6 @@ tools/THANKS
tools/NEWS
tools/COPYING
tools/BUGS
tools/taos-tools
tools/taosws-rs
tags
.clangd

View File

@ -80,7 +80,7 @@ TDengine 目前可以在 Linux、 Windows、macOS 等平台上安装和运行。
### Ubuntu 18.04、20.04、22.04
```bash
sudo apt-get udpate
sudo apt-get update
sudo apt-get install -y gcc cmake build-essential git libjansson-dev \
libsnappy-dev liblzma-dev zlib1g-dev pkg-config
```
@ -188,7 +188,7 @@ cmake .. && cmake --build .
如果你想要编译 taosAdapter需要添加 `-DBUILD_HTTP=false` 选项。
如果你想要编译 taosKeeper需要添加 `--DBUILD_KEEPER=true` 选项。
如果你想要编译 taosKeeper需要添加 `-DBUILD_KEEPER=true` 选项。
</details>

View File

@ -8,7 +8,7 @@
</a>
</p>
[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/taosdata/tdengine/taosd-ci-build.yml)](https://github.com/taosdata/TDengine/actions/workflows/taosd-ci-build.yml)
[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/taosdata/tdengine/tdengine-test.yml)](https://github.com/taosdata/TDengine/actions/workflows/tdengine-test.yml)
[![Coverage Status](https://coveralls.io/repos/github/taosdata/TDengine/badge.svg?branch=3.0)](https://coveralls.io/github/taosdata/TDengine?branch=3.0)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/taosdata/tdengine)](https://github.com/feici02/TDengine/commits/main/)
<br />
@ -174,7 +174,7 @@ make
If you want to compile taosAdapter, you need to add the `-DBUILD_HTTP=false` option.
If you want to compile taosKeeper, you need to add the `--DBUILD_KEEPER=true` option.
If you want to compile taosKeeper, you need to add the `-DBUILD_KEEPER=true` option.
You can use Jemalloc as memory allocator instead of glibc:
@ -206,7 +206,7 @@ cmake .. && cmake --build .
If you want to compile taosAdapter, you need to add the `-DBUILD_HTTP=false` option.
If you want to compile taosKeeper, you need to add the `--DBUILD_KEEPER=true` option.
If you want to compile taosKeeper, you need to add the `-DBUILD_KEEPER=true` option.
</details>

View File

@ -69,10 +69,10 @@ This statement creates a subscription that includes all table data in the databa
## Delete Topic
If you no longer need to subscribe to the data, you can delete the topic. Note that only topics that are not currently subscribed can be deleted.
If you no longer need to subscribe to the data, you can delete the topic. If the current topic is subscribed to by a consumer, it can be forcibly deleted using the FORCE syntax. After the forced deletion, the subscribed consumer will consume data with errors (FORCE syntax supported from version 3.3.6.0).
```sql
DROP TOPIC [IF EXISTS] topic_name;
DROP TOPIC [IF EXISTS] [FORCE] topic_name;
```
## View Topics
@ -99,10 +99,10 @@ Displays information about all consumers in the current database, including the
### Delete Consumer Group
When creating a consumer, a consumer group is assigned to the consumer. Consumers cannot be explicitly deleted, but the consumer group can be deleted with the following statement when there are no consumers in the group:
When creating a consumer, a consumer group is assigned to the consumer. Consumers cannot be explicitly deleted, but the consumer group can be deleted. If there are consumers in the current consumer group who are consuming, the FORCE syntax can be used to force deletion. After forced deletion, subscribed consumers will consume data with errors (FORCE syntax supported from version 3.3.6.0).
```sql
DROP CONSUMER GROUP [IF EXISTS] cgroup_name ON topic_name;
DROP CONSUMER GROUP [IF EXISTS] [FORCE] cgroup_name ON topic_name;
```
## Data Subscription
@ -137,6 +137,7 @@ If the following 3 data entries were written, then during replay, the first entr
When using the data subscription's replay feature, note the following:
- Enable replay function by configuring the consumption parameter enable.replay to true
- The replay function of data subscription only supports data playback for query subscriptions; supertable and database subscriptions do not support playback.
- Replay does not support progress saving.
- Because data playback itself requires processing time, there is a precision error of several tens of milliseconds in playback.

View File

@ -26,11 +26,11 @@ CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name
SUBTABLE(expression) AS subquery
stream_options: {
TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time | FORCE_WINDOW_CLOSE]
TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time | FORCE_WINDOW_CLOSE | CONTINUOUS_WINDOW_CLOSE [recalculate rec_time_val] ]
WATERMARK time
IGNORE EXPIRED [0|1]
DELETE_MARK time
FILL_HISTORY [0|1]
FILL_HISTORY [0|1] [ASYNC]
IGNORE UPDATE [0|1]
}
@ -109,7 +109,7 @@ Under normal circumstances, stream computation tasks will not process data that
By enabling the fill_history option, the created stream computation task will be capable of processing data written before, during, and after the creation of the stream. This means that data written either before or after the creation of the stream will be included in the scope of stream computation, thus ensuring data integrity and consistency. This setting provides users with greater flexibility, allowing them to flexibly handle historical and new data according to actual needs.
Tips:
- When enabling fill_ristory, creating a stream requires finding the boundary point of historical data. If there is a lot of historical data, it may cause the task of creating a stream to take a long time. In this case, the parameter streamRunHistorySync (supported since version 3.3.6.0) can be configured to 1 (default is 0), and the task of creating a stream can be processed in the background. The statement of creating a stream can be returned immediately without blocking subsequent operations.
- When enabling fill_history, creating a stream requires finding the boundary point of historical data. If there is a lot of historical data, it may cause the task of creating a stream to take a long time. In this case, you can use fill_history 1 async (supported since version 3.3.6.0) , then the task of creating a stream can be processed in the background. The statement of creating a stream can be returned immediately without blocking subsequent operations. async only takes effect when fill_history 1 is used, and creating a stream with fill_history 0 is very fast and does not require asynchronous processing.
- Show streams can be used to view the progress of background stream creation (ready status indicates success, init status indicates stream creation in progress, failed status indicates that the stream creation has failed, and the message column can be used to view the reason for the failure. In the case of failed stream creation, the stream can be deleted and rebuilt).
@ -142,8 +142,12 @@ When creating a stream, you can specify the trigger mode of stream computing thr
1. AT_ONCE: Triggered immediately upon writing.
2. WINDOW_CLOSE: Triggered when the window closes (the closing of the window is determined by the event time, can be used in conjunction with watermark).
3. MAX_DELAY time: If the window closes, computation is triggered. If the window has not closed, and the duration since it has not closed exceeds the time specified by max delay, computation is triggered.
4. FORCE_WINDOW_CLOSE: Based on the current time of the operating system, only the results of the currently closed window are calculated and pushed out. The window is only calculated once at the moment of closure, and will not be recalculated subsequently. This mode currently only supports INTERVAL windows (does not support sliding); FILL_HISTORY must be 0, IGNORE EXPIRED must be 1, IGNORE UPDATE must be 1; FILL only supports PREV, NULL, NONE, VALUE.
4. FORCE_WINDOW_CLOSE: Based on the current time of the operating system, only the results of the currently closed window are calculated and pushed out. The window is only calculated once at the moment of closure, and will not be recalculated subsequently. This mode currently only supports INTERVAL windows (does support sliding); In this mode, FILL_HISTORY is automatically set to 0, IGNORE EXPIRED is automatically set to 1 and IGNORE UPDATE is automatically set to 1; FILL only supports PREV, NULL, NONE, VALUE.
- This mode can be used to implement continuous queries, such as creating a stream that queries the number of data entries in the past 10 seconds window every 1 second。SQL as follows:
```sql
create stream if not exists continuous_query_s trigger force_window_close into continuous_query as select count(*) from power.meters interval(10s) sliding(1s)
```
5. CONTINUOUS_WINDOW_CLOSE: Results are output when the window is closed. Modifying or deleting data does not immediately trigger a recalculation. Instead, periodic recalculations are performed every rec_time_val duration. If rec_time_val is not specified, the recalculation period is 60 minutes. If the recalculation time exceeds rec_time_val, the next recalculation will be automatically initiated after the current one is completed. Currently, this mode only supports INTERVAL windows. If the FILL clause is used, relevant information of the adapter needs to be configured, including adapterFqdn, adapterPort, and adapterToken. The adapterToken is a string obtained by Base64-encoding `{username}:{password}`. For example, after encoding `root:taosdata`, the result is `cm9vdDp0YW9zZGF0YQ==`.
The closing of the window is determined by the event time, such as when the event stream is interrupted or continuously delayed, at which point the event time cannot be updated, possibly leading to outdated computation results.
Therefore, stream computing provides the MAX_DELAY trigger mode that combines event time with processing time: MAX_DELAY mode triggers computation immediately when the window closes, and its unit can be specified, specific units: a (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks). Additionally, when data is written, if the time that triggers computation exceeds the time specified by MAX_DELAY, computation is triggered immediately.

View File

@ -298,13 +298,53 @@ select max_vol(vol1, vol2, vol3, deviceid) from battery;
</details>
#### Aggregate Function Example 3 Split string and calculate average value [extract_avg](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/extract_avg.c)
The `extract_avg` function converts a comma-separated string sequence into a set of numerical values, counts the results of all rows, and calculates the final average. Note when implementing:
- `interBuf->numOfResult` needs to return 1 or 0 and cannot be used for count.
- Count can use additional caches, such as the `SumCount` structure.
- Use `varDataVal` to obtain the string.
Create table:
```shell
create table scores(ts timestamp, varStr varchar(128));
```
Create custom function:
```shell
create aggregate function extract_avg as '/root/udf/libextract_avg.so' outputtype double bufsize 16 language 'C';
```
Use custom function:
```shell
select extract_avg(valStr) from scores;
```
Generate `.so` file
```bash
gcc -g -O0 -fPIC -shared extract_vag.c -o libextract_avg.so
```
<details>
<summary>max_vol.c</summary>
```c
{{#include tests/script/sh/max_vol.c}}
```
</details>
## Developing UDFs in Python Language
### Environment Setup
The specific steps to prepare the environment are as follows:
- Step 1, prepare the Python runtime environment.
- Step 1, prepare the Python runtime environment. If you compile and install Python locally, be sure to enable the `--enable-shared` option, otherwise the subsequent installation of taospyudf will fail due to failure to generate a shared library.
- Step 2, install the Python package taospyudf. The command is as follows.
```shell

View File

@ -72,8 +72,16 @@ TDengine Enterprise implements incremental backup and recovery of data by using
7. **Directory:** Enter the full path of the directory in which you want to store backup files.
8. **Backup file max size:** Enter the maximum size of a single backup file. If the total size of your backup exceeds this number, the backup is split into multiple files.
9. **Compression level:** Select **fastest** for the fastest performance but lowest compression ratio, **best** for the highest compression ratio but slowest performance, or **balanced** for a combination of performance and compression.
4. Click **Confirm** to create the backup plan.
4. Users can enable S3 dumping to upload backup files to the S3 storage service. To enable S3 dumping, the following information needs to be provided:
1. **Endpoint**: The address of the S3 endpoint.
2. **Access Key ID**: The access key ID for authentication.
3. **Secret Access Key**: The secret access key for authentication.
4. **Bucket**: The name of the target bucket.
5. **Region**: The region where the bucket is located.
6. **Object Prefix**: A prefix for backup file objects, similar to a directory path on S3.
7. **Backup Retention Period**: The retention duration for local backups. All files older than `current time - backup_retention_period` must be uploaded to S3.
8. **Backup Retention Count**: The number of local backups to retain. Only the latest `backup_retention_size` backup files are kept locally.
5. Click **Confirm** to create the backup plan.
You can view your backup plans and modify, clone, or delete them using the buttons in the **Operation** columns. Click **Refresh** to update the status of your plans. Note that you must stop a backup plan before you can delete it. You can also click **View** in the **Backup File** column to view the backup record points and files created by each plan.

View File

@ -246,6 +246,9 @@ The effective value of charset is UTF-8.
| streamSinkDataRate | |Supported, effective after restart| Internal parameter, used to control the write speed of stream computing results |
| streamNotifyMessageSize | After 3.3.6.0 | Not supported | Internal parameter, controls the message size for event notifications, default value is 8192 |
| streamNotifyFrameSize | After 3.3.6.0 | Not supported | Internal parameter, controls the underlying frame size when sending event notification messages, default value is 256 |
| adapterFqdn | After 3.3.6.0 | Not supported | Internal parameter, The address of the taosadapter services, default value is localhost |
| adapterPort | After 3.3.6.0 | Not supported | Internal parameter, The port of the taosadapter services, default value is 6041 |
| adapterToken | After 3.3.6.0 | Not supported | Internal parameter, The string obtained by Base64-encoding `{username}:{password}`, default value is `cm9vdDp0YW9zZGF0YQ==` |
### Log Related

View File

@ -72,12 +72,6 @@ The TDengine client driver provides all the APIs needed for application programm
| tempDir | |Supported, effective immediately | Specifies the directory for generating temporary files during operation, default on Linux platform is /tmp |
| minimalTmpDirGB | |Supported, effective immediately | Minimum space required to be reserved in the directory specified by tempDir, in GB, default value: 1 |
### Stream Related
| Parameter Name |Supported Version|Dynamic Modification| Description |
|-----------------------|----------|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| streamRunHistoryAsync | 3.3.6.0 |Supported, effective immediately | When creating a stream with the fill_history parameter, should the stream statement be executed asynchronously. Boolean value, async if true, sync if false. default is false |
### Log Related
|Parameter Name|Supported Version|Dynamic Modification|Description|

View File

@ -58,11 +58,11 @@ Note: Subscriptions to supertables and databases are advanced subscription modes
## Delete topic
If you no longer need to subscribe to data, you can delete the topic, but note: only TOPICS that are not currently being subscribed to can be deleted.
If you no longer need to subscribe to the data, you can delete the topic. If the current topic is subscribed to by a consumer, it can be forcibly deleted using the FORCE syntax. After the forced deletion, the subscribed consumer will consume data with errors (FORCE syntax supported from version 3.3.6.0)
```sql
/* Delete topic */
DROP TOPIC [IF EXISTS] topic_name;
DROP TOPIC [IF EXISTS] [FORCE] topic_name;
```
At this point, if there are consumers on this subscription topic, they will receive an error.
@ -81,8 +81,10 @@ Consumer groups can only be created through the TDengine client driver or APIs p
## Delete consumer group
When creating a consumer, a consumer group is assigned to the consumer. Consumers cannot be explicitly deleted, but the consumer group can be deleted. If there are consumers in the current consumer group who are consuming, the FORCE syntax can be used to force deletion. After forced deletion, subscribed consumers will consume data with errors (FORCE syntax supported from version 3.3.6.0).
```sql
DROP CONSUMER GROUP [IF EXISTS] cgroup_name ON topic_name;
DROP CONSUMER GROUP [IF EXISTS] [FORCE] cgroup_name ON topic_name;
```
Deletes the consumer group `cgroup_name` on the topic `topic_name`.

View File

@ -11,11 +11,11 @@ import imgStream from './assets/stream-processing-01.png';
```sql
CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name[(field1_name, field2_name [PRIMARY KEY], ...)] [TAGS (create_definition [, create_definition] ...)] SUBTABLE(expression) AS subquery [notification_definition]
stream_options: {
TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time | FORCE_WINDOW_CLOSE]
TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time | FORCE_WINDOW_CLOSE | CONTINUOUS_WINDOW_CLOSE [recalculate rec_time_val] ]
WATERMARK time
IGNORE EXPIRED [0|1]
DELETE_MARK time
FILL_HISTORY [0|1]
FILL_HISTORY [0|1] [ASYNC]
IGNORE UPDATE [0|1]
}
@ -127,6 +127,13 @@ create stream if not exists s1 fill_history 1 into st1 as select count(*) from
If the stream task is completely outdated and you no longer want it to monitor or process data, you can manually delete it. The computed data will still be retained.
Tips:
- When enabling fill_history, creating a stream requires finding the boundary point of historical data. If there is a lot of historical data, it may cause the task of creating a stream to take a long time. In this case, you can use fill_history 1 async (supported since version 3.3.6.0) , then the task of creating a stream can be processed in the background. The statement of creating a stream can be returned immediately without blocking subsequent operations. async only takes effect when fill_history 1 is used, and creating a stream with fill_history 0 is very fast and does not require asynchronous processing.
- Show streams can be used to view the progress of background stream creation (ready status indicates success, init status indicates stream creation in progress, failed status indicates that the stream creation has failed, and the message column can be used to view the reason for the failure. In the case of failed stream creation, the stream can be deleted and rebuilt).
- Besides, do not create multiple streams asynchronously at the same time, as transaction conflicts may cause subsequent streams to fail.
## Deleting Stream Computing
```sql
@ -157,6 +164,7 @@ For non-window computations, the trigger of stream computing is real-time; for w
2. WINDOW_CLOSE: Triggered when the window closes (window closure is determined by event time, can be used in conjunction with watermark)
3. MAX_DELAY time: Trigger computation if the window closes. If the window does not close, and the time since it has not closed exceeds the time specified by max delay, then trigger computation.
4. FORCE_WINDOW_CLOSE: Based on the current time of the operating system, only compute and push the results of the currently closed window. The window is only computed once at the moment of closure and will not be recalculated subsequently. This mode currently only supports INTERVAL windows (does not support sliding); FILL_HISTORY must be 0, IGNORE EXPIRED must be 1, IGNORE UPDATE must be 1; FILL only supports PREV, NULL, NONE, VALUE.
5. CONTINUOUS_WINDOW_CLOSE: Results are output when the window is closed. Modifying or deleting data does not immediately trigger a recalculation. Instead, periodic recalculations are performed every rec_time_val duration. If rec_time_val is not specified, the recalculation period is 60 minutes. If the recalculation time exceeds rec_time_val, the next recalculation will be automatically initiated after the current one is completed. Currently, this mode only supports INTERVAL windows. If the FILL clause is used, relevant information of the adapter needs to be configured, including adapterFqdn, adapterPort, and adapterToken. The adapterToken is a string obtained by Base64-encoding `{username}:{password}`. For example, after encoding `root:taosdata`, the result is `cm9vdDp0YW9zZGF0YQ==`.
Since the closure of the window is determined by event time, if the event stream is interrupted or continuously delayed, the event time cannot be updated, which may result in not obtaining the latest computation results.

View File

@ -35,6 +35,7 @@ The list of keywords is as follows:
| AS | |
| ASC | |
| ASOF | |
| ASYNC | 3.3.6.0+ |
| AT_ONCE | |
| ATTACH | |
| AUTO | 3.3.5.0+ |

View File

@ -29,6 +29,17 @@ SELECT a.* FROM meters a LEFT ASOF JOIN meters b ON timetruncate(a.ts, 1s) < tim
### Main Join Condition
As a time-series database, all join queries in TDengine revolve around the primary key timestamp column. Therefore, all join queries (except ASOF/Window Join) must include an equality condition on the primary key column, and the first primary key column equality condition that appears in the join conditions will be considered the main join condition. ASOF Join's main join condition can include non-equality conditions, while Window Join's main join condition is specified through `WINDOW_OFFSET`.
Starting from version 3.3.6.0, TDengine supports constant timestamps in subqueries (including constant functions with return timestamps such as today (), now (), etc., constant timestamps and their addition and subtraction operations) as equivalent primary key columns that can appear in the main join condition. For example:
```sql
SELECT * from d1001 a JOIN (SELECT today() as ts1, * from d1002 WHERE ts = '2025-03-19 10:00:00.000') b ON timetruncate(a.ts, 1d) = b.ts1;
```
The above example SQL will perform join operation between all records in table d1001 today and a certain time record in table d1002. It should be noticed that the constant time string appears in SQL will not be treated as a timestamp by default. For example, "2025-03-19 10:00:00.000" will only be treated as a string instead of a timestamp. Therefore, when it needs to be treated as a constant timestamp, you can specify the constant string as a timestamp type by using the type prefix timestamp. For example:
```sql
SELECT * from d1001 a JOIN (SELECT timestamp '2025-03-19 10:00:00.000' as ts1, * from d1002 WHERE ts = '2025-03-19 10:00:00.000') b ON timetruncate(a.ts, 1d) = b.ts1;
```
Apart from Window Join, TDengine supports the `timetruncate` function operation in the main join condition, such as `ON timetruncate(a.ts, 1s) = timetruncate(b.ts, 1s)`, but does not support other functions and scalar operations.
@ -38,7 +49,7 @@ The characteristic ASOF/Window Join of time-series databases supports grouping t
### Primary Key Timeline
As a time-series database, TDengine requires each table (subtable) to have a primary key timestamp column, which will serve as the primary key timeline for many time-related operations. The result of a subquery or the result of a Join operation also needs to clearly identify which column will be considered the primary key timeline for subsequent time-related operations. In subqueries, the first appearing ordered primary key column (or its operation) or a pseudocolumn equivalent to the primary key column (`_wstart`/`_wend`) will be considered the primary key timeline of the output table. The selection of the primary key timeline in Join output results follows these rules:
As a time-series database, TDengine requires each table (subtable) to have a primary key timestamp column, which will serve as the primary key timeline for many time-related operations. The result of a subquery or the result of a Join operation also needs to clearly identify which column will be considered the primary key timeline for subsequent time-related operations. In subqueries, the first appearing ordered primary key column (or its operation) or a pseudocolumn equivalent to the primary key column (`_wstart`/`_wend`) will be considered the primary key timeline of the output table. In addition, starting with version 3.3.6.0, TDengine also supports constant timestamp columns in subquery results as the primary key timeline for the output table. The selection of the primary key timeline in Join output results follows these rules:
- In the Left/Right Join series, the primary key column of the driving table (subquery) will be used as the primary key timeline for subsequent queries; additionally, within the Window Join window, since both tables are ordered, any table's primary key column can be used as the primary key timeline, with a preference for the primary key column of the same table.
- Inner Join can use the primary key column of any table as the primary key timeline, but when there are grouping conditions similar to tag column equality conditions related by `AND` with the main join condition, it will not produce a primary key timeline.

View File

@ -1121,10 +1121,14 @@ In addition to using SQL or parameter binding APIs to insert data, you can also
- conf: [Input] Pointer to a valid tmq_conf_t structure, representing a TMQ configuration object.
- key: [Input] Configuration item key name.
- value: [Input] Configuration item value.
- **Return Value**: Returns a tmq_conf_res_t enum value, indicating the result of the configuration setting.
- TMQ_CONF_OK: Successfully set the configuration item.
- TMQ_CONF_INVALID_KEY: Invalid key value.
- TMQ_CONF_UNKNOWN: Invalid key name.
- **Return Value**: Returns a tmq_conf_res_t enum value, indicating the result of the configuration setting. tmq_conf_res_t defined as follows:
```
typedef enum tmq_conf_res_t {
TMQ_CONF_UNKNOWN = -2, // invalid key
TMQ_CONF_INVALID = -1, // invalid value
TMQ_CONF_OK = 0, // success
} tmq_conf_res_t;
```
- `void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param)`
- **Interface Description**: Sets the auto-commit callback function in the TMQ configuration object.

View File

@ -148,6 +148,7 @@ TDengine currently supports timestamp, numeric, character, boolean types, and th
| JSON | java.lang.String | only supported in tags |
| VARBINARY | byte[] | |
| GEOMETRY | byte[] | |
| DECIMAL | java.math.BigDecimal | |
**Note**: Due to historical reasons, the BINARY type in TDengine is not truly binary data and is no longer recommended. Please use VARBINARY type instead.
GEOMETRY type is binary data in little endian byte order, complying with the WKB standard. For more details, please refer to [Data Types](../../sql-manual/data-types/)

View File

@ -168,6 +168,7 @@ This document details the server error codes that may be encountered when using
| 0x8000038B | Index not exist | Does not exist | Confirm if the operation is correct |
| 0x80000396 | Database in creating status | Database is being created | Retry |
| 0x8000039A | Invalid system table name | Internal error | Report issue |
| 0x8000039F | No VGroup's leader need to be balanced | Perform balance leader operation on VGroup | There is no VGroup's leader needs to be balanced |
| 0x800003A0 | Mnode already exists | Already exists | Confirm if the operation is correct |
| 0x800003A1 | Mnode not there | Already exists | Confirm if the operation is correct |
| 0x800003A2 | Qnode already exists | Already exists | Confirm if the operation is correct |
@ -558,9 +559,10 @@ This document details the server error codes that may be encountered when using
## virtual table
| Error Code | Description | Possible Error Scenarios or Reasons | Recommended Actions for Users |
|-------------|---------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|
| 0x80006200 | Virtual table scan internal error | virtual table scan operator internal error, generally does not occur | Check error logs, contact development for handling |
| 0x80006201 | Virtual table scan invalid downstream operator type | The incorrect execution plan generated causes the downstream operator type of the virtual table scan operator to be incorrect. | Check error logs, contact development for handling |
| 0x80006202 | Virtual table prim timestamp column should not has ref | The timestamp primary key column of a virtual table should not have a data source. If it does, this error will occur during subsequent queries on the virtual table. | Check error logs, contact development for handling |
| 0x80006203 | Create virtual child table must use virtual super table | Create virtual child table using non-virtual super table | create virtual child table using virtual super table |
| Error Code | Description | Possible Error Scenarios or Reasons | Recommended Actions for Users |
|------------|---------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|
| 0x80006200 | Virtual table scan internal error | virtual table scan operator internal error, generally does not occur | Check error logs, contact development for handling |
| 0x80006201 | Virtual table scan invalid downstream operator type | The incorrect execution plan generated causes the downstream operator type of the virtual table scan operator to be incorrect. | Check error logs, contact development for handling |
| 0x80006202 | Virtual table prim timestamp column should not has ref | The timestamp primary key column of a virtual table should not have a data source. If it does, this error will occur during subsequent queries on the virtual table. | Check error logs, contact development for handling |
| 0x80006203 | Create virtual child table must use virtual super table | Create virtual child table using non-virtual super table | create virtual child table using virtual super table |
| 0x80006204 | Virtual table not support decimal type | Create virtual table using decimal type | create virtual table without using decimal type |

View File

@ -0,0 +1,297 @@
---
title: Usage of Special Characters in Passwords
description: Usage of special characters in user passwords in TDengine
---
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
TDengine user passwords must meet the following rules:
1. The username must not exceed 23 bytes.
2. The password length must be between 8 and 255 characters.
3. The range of password characters:
1. Uppercase letters: `A-Z`
2. Lowercase letters: `a-z`
3. Numbers: `0-9`
4. Special characters: `! @ # $ % ^ & * ( ) - _ + = [ ] { } : ; > < ? | ~ , .`
4. When strong password is enabled (EnableStrongPassword 1, enabled by default), the password must contain at least three of the following categories: uppercase letters, lowercase letters, numbers, and special characters. When not enabled, there are no restrictions on character types.
## Usage Guide for Special Characters in Different Components
Take the username `user1` and password `Ab1!@#$%^&*()-_+=[]{}` as an example.
```sql
CREATE USER user1 PASS 'Ab1!@#$%^&*()-_+=[]{}';
```
<Tabs defaultValue="shell" groupId="component">
<TabItem label="CLI" value="shell">
In the [TDengine Command Line Interface (CLI)](../../tdengine-reference/tools/tdengine-cli/), note the following:
- If the `-p` parameter is used without a password, you will be prompted to enter a password, and any acceptable characters can be entered.
- If the `-p` parameter is used with a password, and the password contains special characters, single quotes must be used.
Login with user `user1`:
```shell
taos -u user1 -p'Ab1!@#$%^&*()-_+=[]{}'
taos -u user1 -pAb1\!\@\#\$\%\^\&\*\(\)\-\_\+\=\[\]\{\}
```
</TabItem>
<TabItem label="taosdump" value="taosdump">
In [taosdump](../../tdengine-reference/tools/taosdump/), note the following:
- If the `-p` parameter is used without a password, you will be prompted to enter a password, and any acceptable characters can be entered.
- If the `-p` parameter is used with a password, and the password contains special characters, single quotes or escaping must be used.
Backup database `test` with user `user1`:
```shell
taosdump -u user1 -p'Ab1!@#$%^&*()-_+=[]{}' -D test
taosdump -u user1 -pAb1\!\@\#\$\%\^\&\*\(\)\-\_\+\=\[\]\{\} -D test
```
</TabItem>
<TabItem label="Benchmark" value="benchmark">
In [taosBenchmark](../../tdengine-reference/tools/taosbenchmark/), note the following:
- If the `-p` parameter is used without a password, you will be prompted to enter a password, and any acceptable characters can be entered.
- If the `-p` parameter is used with a password, and the password contains special characters, single quotes or escaping must be used.
Example of data write test with user `user1`:
```shell
taosBenchmark -u user1 -p'Ab1!@#$%^&*()-_+=[]{}' -d test -y
```
When using `taosBenchmark -f <JSON>`, there are no restrictions on the password in the JSON file.
</TabItem>
<TabItem label="taosX" value="taosx">
[taosX](../../tdengine-reference/components/taosx/) uses DSN to represent TDengine connections, in the format: `(taos|tmq)[+ws]://<user>:<pass>@<ip>:<port>`, where `<pass>` can contain special characters, such as: `taos+ws://user1:Ab1!@#$%^&*()-_+=[]{}@192.168.10.10:6041`.
Example of exporting data with user `user1`:
```shell
taosx -f 'taos://user1:Ab1!@#$%^&*()-_+=[]{}@localhost:6030?query=select * from test.t1' \
-t 'csv:./test.csv'
```
Note that if the password can be URL decoded, the URL decoded result will be used as the password. For example: `taos+ws://user1:Ab1%21%40%23%24%25%5E%26%2A%28%29-_%2B%3D%5B%5D%7B%7D@localhost:6041` is equivalent to `taos+ws://user1:Ab1!@#$%^&*()-_+=[]{}@localhost:6041`.
No special handling is required in [Explorer](../../tdengine-reference/components/taosexplorer/), just use it directly.
</TabItem>
<TabItem label="Java" value="java">
When using special character passwords in JDBC, the password needs to be URL encoded, as shown below:
```java
package com.taosdata.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import com.taosdata.jdbc.TSDBDriver;
public class JdbcPassDemo {
public static void main(String[] args) throws Exception {
String password = "Ab1!@#$%^&*()-_+=[]{}";
String encodedPassword = URLEncoder.encode(password, StandardCharsets.UTF_8.toString());
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "user1");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, encodedPassword);
connProps.setProperty(TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT, "true");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
try (Connection conn = DriverManager.getConnection(jdbcUrl, connProps)) {
System.out.println("Connected to " + jdbcUrl + " successfully.");
// you can use the connection for execute SQL here
} catch (Exception ex) {
// please refer to the JDBC specifications for detailed exceptions info
System.out.printf("Failed to connect to %s, %sErrMessage: %s%n",
jdbcUrl,
ex instanceof SQLException ? "ErrCode: " + ((SQLException) ex).getErrorCode() + ", " : "",
ex.getMessage());
// Print stack trace for context in examples. Use logging in production.
ex.printStackTrace();
throw ex;
}
}
}
```
</TabItem>
<TabItem label="Python" value="python">
No special handling is required for special character passwords in Python, as shown below:
```python
import taos
import taosws
def create_connection():
host = "localhost"
port = 6030
return taos.connect(
user="user1",
password="Ab1!@#$%^&*()-_+=[]{}",
host=host,
port=port,
)
def create_ws_connection():
host = "localhost"
port = 6041
return taosws.connect(
user="user1",
password="Ab1!@#$%^&*()-_+=[]{}",
host=host,
port=port,
)
def show_databases(conn):
cursor = conn.cursor()
cursor.execute("show databases")
print(cursor.fetchall())
cursor.close()
if __name__ == "__main__":
print("Connect with native protocol")
conn = create_connection()
show_databases(conn)
print("Connect with websocket protocol")
conn = create_ws_connection()
show_databases(conn)
```
</TabItem>
<TabItem label="Go" value="go">
Starting from version 3.6.0, Go supports passwords containing special characters, which need to be encoded using encodeURIComponent.
```go
package main
import (
"database/sql"
"fmt"
"log"
"net/url"
_ "github.com/taosdata/driver-go/v3/taosWS"
)
func main() {
var user = "user1"
var password = "Ab1!@#$%^&*()-_+=[]{}"
var encodedPassword = url.QueryEscape(password)
var taosDSN = user + ":" + encodedPassword + "@ws(localhost:6041)/"
taos, err := sql.Open("taosWS", taosDSN)
if err != nil {
log.Fatalln("Failed to connect to " + taosDSN + "; ErrMessage: " + err.Error())
}
fmt.Println("Connected to " + taosDSN + " successfully.")
defer taos.Close()
}
```
</TabItem>
<TabItem label="Rust" value="rust">
In Rust, DSN is used to represent TDengine connections, in the format: `(taos|tmq)[+ws]://<user>:<pass>@<ip>:<port>`, where `<pass>` can contain special characters, such as: `taos+ws://user1:Ab1!@#$%^&*()-_+=[]{}@192.168.10.10:6041`.
```rust
let dsn = "taos+ws://user1:Ab1!@#$%^&*()-_+=[]{}@localhost:6041";
let connection = TaosBuilder::from_dsn(&dsn)?.build().await?;
```
</TabItem>
<TabItem label="Node.js" value="node">
Starting from version 3.1.5, the Node.js connector supports passwords containing all valid characters.
```js
const taos = require("@tdengine/websocket");
let dsn = 'ws://localhost:6041';
async function createConnect() {
try {
let conf = new taos.WSConfig(dsn);
conf.setUser('user1');
conf.setPwd('Ab1!@#$%^&*()-_+=[]{}');
conf.setDb('test');
conn = await taos.sqlConnect(conf);
console.log("Connected to " + dsn + " successfully.");
return conn;
} catch (err) {
console.log("Connection failed with code: " + err.code + ", message: " + err.message);
throw err;
}
}
createConnect()
```
</TabItem>
<TabItem label="C#" value="csharp">
When using passwords in C#, note that connection strings do not support semicolons (as semicolons are delimiters). In this case, you can construct the `ConnectionStringBuilder` without a password, and then set the username and password.
As shown below:
```csharp
var builder = new ConnectionStringBuilder("host=localhost;port=6030");
builder.Username = "user1";
builder.Password = "Ab1!@#$%^&*()-_+=[]{}";
using (var client = DbDriver.Open(builder)){}
```
</TabItem>
<TabItem label="C" value="c">
There are no restrictions on passwords in C.
```c
TAOS *taos = taos_connect("localhost", "user1", "Ab1!@#$%^&*()-_+=[]{}", NULL, 6030);
```
</TabItem>
<TabItem label="REST" value="rest">
When using passwords in REST API, note the following:
- Passwords use Basic Auth, in the format `Authorization: Basic base64(<user>:<pass>)`.
- Passwords containing colons `:` are not supported.
The following two methods are equivalent:
```shell
curl -u'user1:Ab1!@#$%^&*()-_+=[]{}' \
-d 'show databases' http://localhost:6041/rest/sql
curl -H 'Authorization: Basic dXNlcjE6QWIxIUAjJCVeJiooKS1fKz1bXXt9' \
-d 'show databases' http://localhost:6041/rest/sql
```
</TabItem>
</Tabs>

View File

@ -64,10 +64,10 @@ CREATE TOPIC [IF NOT EXISTS] topic_name [with meta] AS DATABASE db_name;
## 删除主题
如果不再需要订阅数据,可以删除 topic需要注意只有当前未在订阅中的 topic 才能被删除
如果不再需要订阅数据,可以删除 topic如果当前 topic 被消费者订阅,通过 FORCE 语法可强制删除强制删除后订阅的消费者会消费数据会出错FORCE 语法从 v3.3.6.0 开始支持)
```sql
DROP TOPIC [IF EXISTS] topic_name;
DROP TOPIC [IF EXISTS] [FORCE] topic_name;
```
## 查看主题
@ -94,9 +94,9 @@ SHOW CONSUMERS;
### 删除消费组
消费者创建的时候,会给消费者指定一个消费者组,消费者不能显式的删除,但是消费者组在组内没有消费者时可以通过下面语句删除:
消费者创建的时候,会给消费者指定一个消费者组,消费者不能显式的删除,但是可以删除消费者组。如果当前消费者组里有消费者在消费,通过 FORCE 语法可强制删除强制删除后订阅的消费者会消费数据会出错FORCE 语法从 v3.3.6.0 开始支持)。
```sql
DROP CONSUMER GROUP [IF EXISTS] cgroup_name ON topic_name;
DROP CONSUMER GROUP [IF EXISTS] [FORCE] cgroup_name ON topic_name;
```
## 数据订阅
@ -129,6 +129,7 @@ TDengine 的数据订阅功能支持回放replay功能允许用户按
```
使用数据订阅的回放功能时需要注意如下几项:
- 通过配置消费参数 enable.replay 为 true 开启回放功能。
- 数据订阅的回放功能仅查询订阅支持数据回放,超级表和库订阅不支持回放。
- 回放不支持进度保存。
- 因为数据回放本身需要处理时间,所以回放的精度存在几十毫秒的误差。

View File

@ -23,11 +23,11 @@ CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name
SUBTABLE(expression) AS subquery
stream_options: {
TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time | FORCE_WINDOW_CLOSE]
TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time | FORCE_WINDOW_CLOSE | CONTINUOUS_WINDOW_CLOSE [recalculate rec_time_val] ]
WATERMARK time
IGNORE EXPIRED [0|1]
DELETE_MARK time
FILL_HISTORY [0|1]
FILL_HISTORY [0|1] [ASYNC]
IGNORE UPDATE [0|1]
}
@ -102,7 +102,7 @@ PARTITION 子句中,为 tbname 定义了一个别名 tname 在 PARTITION
通过启用 fill_history 选项,创建的流计算任务将具备处理创建前、创建过程中以及创建后写入的数据的能力。这意味着,无论数据是在流创建之前还是之后写入的,都将纳入流计算的范围,从而确保数据的完整性和一致性。这一设置为用户提供了更大的灵活性,使其能够根据实际需求灵活处理历史数据和新数据。
注意:
- 开启 fill_history 时,创建流需要找到历史数据的分界点,如果历史数据很多,可能会导致创建流任务耗时较长,此时可以配置参数 streamRunHistoryAsync3.3.6.0版本开始支持) 为 1 默认为0将创建流的任务放在后台处理,创建流的语句可立即返回,不阻塞后面的操作。
- 开启 fill_history 时,创建流需要找到历史数据的分界点,如果历史数据很多,可能会导致创建流任务耗时较长,此时可以通过 fill_history 1 asyncv3.3.6.0 开始支持) 语法将创建流的任务放在后台处理,创建流的语句可立即返回,不阻塞后面的操作。async 只对 fill_history 1 起效fill_history 0 时建流很快,不需要异步处理。
- 通过 show streams 可查看后台建流的进度ready 状态表示成功init 状态表示正在建流failed 状态表示建流失败,失败时 message 列可以查看原因。对于建流失败的情况可以删除流重新建立)。
@ -131,7 +131,12 @@ create stream if not exists count_history_s fill_history 1 into count_history as
1. AT_ONCE写入立即触发。
2. WINDOW_CLOSE窗口关闭时触发窗口关闭由事件时间决定可配合 watermark 使用)。
3. MAX_DELAY time若窗口关闭则触发计算。若窗口未关闭且未关闭时长超过 max delay 指定的时间,则触发计算。
4. FORCE_WINDOW_CLOSE以操作系统当前时间为准只计算当前关闭窗口的结果并推送出去。窗口只会在被关闭的时刻计算一次后续不会再重复计算。该模式当前只支持 INTERVAL 窗口不支持滑动FILL_HISTORY必须为 0IGNORE EXPIRED 必须为 1IGNORE UPDATE 必须为 1FILL 只支持 PREV 、NULL、 NONE、VALUE。
4. FORCE_WINDOW_CLOSE以操作系统当前时间为准只计算当前关闭窗口的结果并推送出去。窗口只会在被关闭的时刻计算一次后续不会再重复计算。该模式当前只支持 INTERVAL 窗口支持滑动该模式时FILL_HISTORY 自动设置为 0IGNORE EXPIRED 自动设置为 1IGNORE UPDATE 自动设置为 1FILL 只支持 PREV 、NULL、 NONE、VALUE。
- 该模式可用于实现连续查询,比如,创建一个流,每隔 1s 查询一次过去 10s 窗口内的数据条数。SQL 如下:
```sql
create stream if not exists continuous_query_s trigger force_window_close into continuous_query as select count(*) from power.meters interval(10s) sliding(1s)
```
5. CONTINUOUS_WINDOW_CLOSE窗口关闭时输出结果。修改、删除数据并不会立即触发重算每等待 rec_time_val 时长,会进行周期性重算。如果不指定 rec_time_val那么重算周期是60分钟。如果重算的时间长度超过 rec_time_val在本次重算后自动开启下一次重算。该模式当前只支持 INTERVAL 窗口。如果使用 FILL需要配置 adapter的相关信息adapterFqdn、adapterPort、adapterToken。adapterToken 为 `{username}:{password}` 经过 Base64 编码之后的字符串,例如 `root:taosdata` 编码后为 `cm9vdDp0YW9zZGF0YQ==`
窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,此时事件时间无法更新,可能导致无法得到最新的计算结果。

View File

@ -97,7 +97,6 @@ CSV 文件中的每个 Row 配置一个 OPC 数据点位。Row 的规则如下
(1) 与 Header 中的列有如下对应关系
| 序号 | Header 中的列 | 值的类型 | 值的范围 | 是否必填 | 默认值 |
|----|-------------------------| -------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------|--------------|
| 1 | tag_name | String | 类似`root.parent.temperature`这样的字符串,要满足 OPC DA 的 ID 规范 | 是 | |

View File

@ -9,9 +9,15 @@
> 丢弃:将异常数据忽略,不写入目标库
> 报错:任务报错
- **目标库连接超时** 目标库连接失败,可选处理策略:归档、丢弃、报错、缓存
> 缓存:当目标库状态异常(连接错误或资源不足等情况)时写入缓存文件(默认路径为 `${data_dir}/tasks/_id/.datetime`),目标库恢复正常后重新入库
- **目标库不存在** 写入报错目标库不存在,可选处理策略:归档、丢弃、报错
- **表不存在** 写入报错表不存在,可选处理策略:归档、丢弃、报错、自动建表
> 自动建表:自动建表,建表成功后重试
- **主键时间戳溢出** 检查数据中第一列时间戳是否在正确的时间范围内now - keep1, now + 100y可选处理策略归档、丢弃、报错
- **主键时间戳空** 检查数据中第一列时间戳是否为空,可选处理策略:归档、丢弃、报错、使用当前时间
> 使用当前时间:使用当前时间填充到空的时间戳字段中
- **复合主键空** 写入报错复合主键空,可选处理策略:归档、丢弃、报错
- **表名长度溢出** 检查子表表名的长度是否超出限制(最大 192 字符),可选处理策略:归档、丢弃、报错、截断、截断且归档
> 截断:截取原始表名的前 192 个字符作为新的表名
> 截断且归档:截取原始表名的前 192 个字符作为新的表名,并且将此行记录写入归档文件
@ -20,4 +26,20 @@
- **表名模板变量空值** 检查子表表名模板中的变量是否为空,可选处理策略:丢弃、留空、变量替换为指定字符串
> 留空:变量位置不做任何特殊处理,例如 `a_{x}` 转换为 `a_`
> 变量替换为指定字符串:变量位置使用后方输入框中的指定字符串,例如 `a_{x}` 转换为 `a_b`
- **列名长度溢出** 检查列名的长度是否超出限制(最大 64 字符),可选处理策略:归档、丢弃、报错
- **列名不存在** 写入报错列名不存在,可选处理策略:归档、丢弃、报错、自动增加缺失列
> 自动增加缺失列:根据数据信息,自动修改表结构增加列,修改成功后重试
- **列名长度溢出** 检查列名的长度是否超出限制(最大 64 字符),可选处理策略:归档、丢弃、报错
- **列自动扩容** 开关选项,打开时,列数据长度超长时将自动修改表结构并重试
- **列长度溢出** 写入报错列长度溢出,可选处理策略:归档、丢弃、报错、截断、截断且归档
> 截断:截取数据中符合长度限制的前 n 个字符
> 截断且归档:截取数据中符合长度限制的前 n 个字符,并且将此行记录写入归档文件
- **数据异常** 其他数据异常(未在上方列出的其他异常)的处理策略,可选处理策略:归档、丢弃、报错
- **连接超时** 配置目标库连接超时时间,单位“秒”取值范围 1~600
- **临时存储文件位置** 配置缓存文件的位置,实际生效位置 `$DATA_DIR/tasks/:id/{location}`
- **归档数据保留天数** 非负整数0 表示无限制
- **归档数据可用空间** 0~65535其中 0 表示无限制
- **归档数据文件位置** 配置归档文件的位置,实际生效位置 `$DATA_DIR/tasks/:id/{location}`
- **归档数据失败处理策略** 当写入归档文件报错时的处理策略,可选处理策略:删除旧文件、丢弃、报错并停止任务
> 删除旧文件:删除旧文件,如果删除旧文件后仍然无法写入,则报错并停止任务
> 丢弃:丢弃即将归档的数据
> 报错并停止任务:报错并停止当前任务

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 98 KiB

View File

@ -0,0 +1,31 @@
---
title: "LSTM"
sidebar_label: "LSTM"
---
本节说明 LSTM 模型的使用方法。
## 功能概述
LSTM 模型即长短期记忆网络(Long Short Term Memory),是一种特殊的循环神经网络,适用于处理时间序列数据、自然语言处理等任务,通过其独特的门控机制,能够有效捕捉长期依赖关系,
解决传统 RNN 的梯度消失问题,从而对序列数据进行准确预测,不过它不直接提供计算的置信区间范围结果。
完整的调用 SQL 语句如下:
```SQL
SELECT _frowts, FORECAST(i32, "algo=lstm,alpha=95,period=10,start_p=1,max_p=5,start_q=1,max_q=5") from foo
```
```json5
{
"rows": fc_rows, // 返回结果的行数
"period": period, // 返回结果的周期性,同输入
"alpha": alpha, // 返回结果的置信区间,同输入
"algo": "lstm", // 返回结果使用的算法
"mse": mse, // 拟合输入时间序列时候生成模型的最小均方误差(MSE)
"res": res // 列模式的结果
}
```
### 参考文献
- [1] Hochreiter S. Long Short-term Memory[J]. Neural Computation MIT-Press, 1997.

View File

@ -0,0 +1,35 @@
---
title: "MLP"
sidebar_label: "MLP"
---
本节说明 MLP 模型的使用方法。
## 功能概述
MLPMutiLayers Perceptron多层感知机是一种典的神经网络模型能够通过学习历史数据的非线性关系
捕捉时间序列中的模式并进行未来值预测。它通过多层全连接网络进行特征提取和映射,
对输入的历史数据生成预测结果。由于不直接考虑趋势或季节性变化,通常需要结合数据预处理来提升效果,
适合解决非线性和复杂的时间序列问题。
完整的调用SQL语句如下
```SQL
SELECT _frowts, FORECAST(i32, "algo=mlp") from foo
```
```json5
{
"rows": fc_rows, // 返回结果的行数
"period": period, // 返回结果的周期性,同输入
"alpha": alpha, // 返回结果的置信区间,同输入
"algo": "mlp", // 返回结果使用的算法
"mse": mse, // 拟合输入时间序列时候生成模型的最小均方误差(MSE)
"res": res // 列模式的结果
}
```
### 参考文献
- [1]Rumelhart D E, Hinton G E, Williams R J. Learning representations by back-propagating errors[J]. nature, 1986, 323(6088): 533-536.
- [2]Rosenblatt F. The perceptron: a probabilistic model for information storage and organization in the brain[J]. Psychological review, 1958, 65(6): 386.
- [3]LeCun Y, Bottou L, Bengio Y, et al. Gradient-based learning applied to document recognition[J]. Proceedings of the IEEE, 1998, 86(11): 2278-2324.

View File

@ -3,7 +3,9 @@ title: "机器学习算法"
sidebar_label: "机器学习算法"
---
Autoencoder<sup>[1]</sup>: TDgpt 内置使用自编码器Autoencoder的异常检测算法对周期性的时间序列数据具有较好的检测结果。使用该模型需要针对输入时序数据进行预训练同时将训练完成的模型保存在到服务目录 `ad_autoencoder` 中,然后在 SQL 语句中指定调用该算法模型即可使用。
Autoencoder<sup>[1]</sup>: TDgpt 内置使用自编码器Autoencoder的异常检测算法
对周期性的时间序列数据具有较好的检测结果。使用该模型需要针对输入时序数据进行预训练,
同时将训练完成的模型保存在到服务目录 `ad_autoencoder` 中,然后在 SQL 语句中指定调用该算法模型即可使用。
```SQL
--- 在 options 中增加 model 的名称ad_autoencoder_foo 针对 foo 数据集(表)训练的采用自编码器的异常检测模型进行异常检测

View File

@ -237,7 +237,7 @@ typedef struct SUdfInterBuf {
#### 标量函数示例 [bit_and](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/bit_and.c)
bit_add 实现多列的按位与功能。如果只有一列返回这一列。bit_add 忽略空值。
bit_and 实现多列的按位与功能。如果只有一列返回这一列。bit_and 忽略空值。
<details>
<summary>bit_and.c</summary>
@ -287,12 +287,46 @@ select max_vol(vol1, vol2, vol3, deviceid) from battery;
</details>
#### 聚合函数示例3 切分字符串求平均值 [extract_avg](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/extract_avg.c)
`extract_avg` 函数是将一个逗号分隔的字符串数列转为一组数值,统计所有行的结果,计算最终平均值。实现时需注意:
- `interBuf->numOfResult` 需要返回 1 或者 0不能用于 count 计数。
- count 计数可使用额外的缓存,例如 `SumCount` 结构体。
- 字符串的获取需使用`varDataVal`。
创建表:
```bash
create table scores(ts timestamp, varStr varchar(128));
```
创建自定义函数:
```bash
create aggregate function extract_avg as '/root/udf/libextract_avg.so' outputtype double bufsize 16 language 'C';
```
使用自定义函数:
```bash
select extract_avg(valStr) from scores;
```
生成 `.so` 文件
```bash
gcc -g -O0 -fPIC -shared extract_vag.c -o libextract_avg.so
```
<details>
<summary>extract_avg.c</summary>
```c
{{#include tests/script/sh/extract_avg.c}}
```
</details>
## 用 Python 语言开发 UDF
### 准备环境
准备环境的具体步骤如下:
- 第 1 步,准备好 Python 运行环境。
- 第 1 步,准备好 Python 运行环境。本地编译安装 python 注意打开 `--enable-shared` 选项,不然后续安装 taospyudf 会因无法生成共享库而导致失败。
- 第 2 步,安装 Python 包 taospyudf。命令如下。
```shell
pip3 install taospyudf

File diff suppressed because it is too large Load Diff

View File

@ -305,15 +305,6 @@ TDengine 客户端驱动提供了应用编程所需要的全部 API并且在
- 动态修改:不支持
- 支持版本:从 v3.1.0.0 版本开始引入
### 流相关
#### streamRunHistoryAsync
- 说明:创建流有 fill_history 参数时,是否异步执行建流语句
- 类型布尔false同步true异步
- 默认值false
- 动态修改:支持通过 SQL 修改,立即生效
- 支持版本:从 v3.3.6.0 版本开始引入
### 日志相关
#### logDir

View File

@ -7,7 +7,7 @@ description: "创建、删除数据库,查看、修改数据库参数"
## 创建数据库
```sql
CREATE DATABASE [IF NOT EXISTS] db_name [database_options]
CREATE DATABASE [IF NOT EXISTS] db_name [database_options];
database_options:
database_option ...
@ -46,53 +46,80 @@ database_option: {
### 参数说明
- VGROUPS数据库中初始 vgroup 的数目。
- PRECISION数据库的时间戳精度。ms 表示毫秒、us 表示微秒、ns 表示纳秒、默认 ms 毫秒。
- REPLICA表示数据库副本数取值为 1、2 或 3默认为 1; 2 仅在企业版 3.3.0.0 及以后版本中可用。在集群中使用,副本数必须小于或等于 DNODE 的数目。且使用时存在以下限制:
- PRECISION数据库的时间戳精度。
- ms 表示毫秒(默认值)。
- us 表示微秒。
- ns 表示纳秒。
- REPLICA表示数据库副本数取值为 1、2 或 3默认为 1; 2 仅在企业版 3.3.0.0 及以后版本中可用。在集群中使用时,副本数必须小于或等于 DNODE 的数目。且使用时存在以下限制:
- 暂不支持对双副本数据库相关 Vgroup 进行 SPLITE VGROUP 或 REDISTRIBUTE VGROUP 操作
- 单副本数据库可变更为双副本数据库,但不支持从双副本变更为其它副本数,也不支持从三副本变更为双副本
- 单副本数据库可变更为双副本数据库,但不支持从双副本变更为其它副本数,也不支持从三副本变更为双副本
- BUFFER一个 vnode 写入内存池大小,单位为 MB默认为 256最小为 3最大为 16384。
- PAGES一个 vnode 中元数据存储引擎的缓存页个数,默认为 256最小 64。一个 vnode 元数据存储占用 PAGESIZE \* PAGES默认情况下为 1MB 内存。
- PAGESIZE一个 vnode 中元数据存储引擎的页大小,单位为 KB默认为 4 KB。范围为 1 到 16384即 1 KB 到 16 MB。
- CACHEMODEL表示是否在内存中缓存子表的最近数据。默认为 none。
- none表示不缓存。
- CACHEMODEL表示是否在内存中缓存子表的最近数据。
- none表示不缓存(默认值)
- last_row表示缓存子表最近一行数据。这将显著改善 LAST_ROW 函数的性能表现。
- last_value表示缓存子表每一列的最近的非 NULL 值。这将显著改善无特殊影响WHERE、ORDER BY、GROUP BY、INTERVAL下的 LAST 函数的性能表现。
- both表示同时打开缓存最近行和列功能。
NoteCacheModel 值来回切换有可能导致 last/last_row 的查询结果不准确,请谨慎操作。推荐保持打开
NoteCacheModel 值来回切换有可能导致 last/last_row 的查询结果不准确,请谨慎操作(推荐保持打开)
- CACHESIZE表示每个 vnode 中用于缓存子表最近数据的内存大小。默认为 1 ,范围是[1, 65536],单位是 MB。
- COMP表示数据库文件压缩标志位缺省值为 2取值范围为 [0, 2]。
- 0表示不压缩。
- 1表示一阶段压缩。
- 2表示两阶段压缩。
- DURATION数据文件存储数据的时间跨度。可以使用加单位的表示形式如 DURATION 100h、DURATION 10d 等,支持 m分钟、h小时和 d三个单位。不加时间单位时默认单位为天如 DURATION 50 表示 50 天。
- DURATION数据文件存储数据的时间跨度。
- 可以使用加单位的表示形式,如 DURATION 100h、DURATION 10d 等,支持 m分钟、h小时和 d三个单位。
- 不加时间单位时默认单位为天,如 DURATION 50 表示 50 天。
- MAXROWS文件块中记录的最大条数默认为 4096 条。
- MINROWS文件块中记录的最小条数默认为 100 条。
- KEEP表示数据文件保存的天数缺省值为 3650取值范围 [1, 365000],且必须大于或等于 3 倍的 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据从而释放存储空间。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m分钟、h小时和 d三个单位。也可以不写单位如 KEEP 50此时默认单位为天。企业版支持[多级存储](https://docs.taosdata.com/operation/planning/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 \<= keep 1 \<= keep 2如 KEEP 100h,100d,3650d; 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。了解更多,请点击 [关于主键时间戳](https://docs.taosdata.com/reference/taos-sql/insert/)
- KEEP_TIME_OFFSET自 3.2.0.0 版本生效。删除或迁移保存时间超过 KEEP 值的数据的延迟执行时间,默认值为 0 (小时)。在数据文件保存时间超过 KEEP 后,删除或迁移操作不会立即执行,而会额外等待本参数指定的时间间隔,以实现与业务高峰期错开的目的。
- STT_TRIGGER表示落盘文件触发文件合并的个数。对于少表高频写入场景此参数建议使用默认配置而对于多表低频写入场景此参数建议配置较大的值。
- KEEP表示数据文件保存的天数缺省值为 3650取值范围 [1, 365000],且必须大于或等于 3 倍的 DURATION 参数值。
- 数据库会自动删除保存时间超过 KEEP 值的数据从而释放存储空间;
- KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m分钟、h小时和 d三个单位
- 也可以不写单位,如 KEEP 50此时默认单位为天
- 仅企业版支持[多级存储](https://docs.taosdata.com/operation/planning/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 \<= keep 1 \<= keep 2如 KEEP 100h,100d,3650d
- 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间);
- 了解更多,请点击 [关于主键时间戳](https://docs.taosdata.com/reference/taos-sql/insert/)。
- KEEP_TIME_OFFSET删除或迁移保存时间超过 KEEP 值的数据的延迟执行时间(自 3.2.0.0 版本生效),默认值为 0 (小时)。
- 在数据文件保存时间超过 KEEP 后,删除或迁移操作不会立即执行,而会额外等待本参数指定的时间间隔,以实现与业务高峰期错开的目的。
- STT_TRIGGER表示落盘文件触发文件合并的个数。
- 对于少表高频写入场景,此参数建议使用默认配置;
- 而对于多表低频写入场景,此参数建议配置较大的值。
- SINGLE_STABLE表示此数据库中是否只可以创建一个超级表用于超级表列非常多的情况。
- 0表示可以创建多张超级表。
- 1表示只可以创建一张超级表。
- TABLE_PREFIX当其为正值时在决定把一个表分配到哪个 vgroup 时要忽略表名中指定长度的前缀;当其为负值时,在决定把一个表分配到哪个 vgroup 时只使用表名中指定长度的前缀;例如,假定表名为 "v30001",当 TSDB_PREFIX = 2 时 使用 "0001" 来决定分配到哪个 vgroup ,当 TSDB_PREFIX = -2 时使用 "v3" 来决定分配到哪个 vgroup
- TABLE_SUFFIX当其为正值时在决定把一个表分配到哪个 vgroup 时要忽略表名中指定长度的后缀;当其为负值时,在决定把一个表分配到哪个 vgroup 时只使用表名中指定长度的后缀;例如,假定表名为 "v30001",当 TSDB_SUFFIX = 2 时 使用 "v300" 来决定分配到哪个 vgroup ,当 TSDB_SUFFIX = -2 时使用 "01" 来决定分配到哪个 vgroup。
- TABLE_PREFIX分配数据表到某个 vgroup 时,用于忽略或仅使用表名前缀的长度值。
- 当其为正值时,在决定把一个表分配到哪个 vgroup 时要忽略表名中指定长度的前缀;
- 当其为负值时,在决定把一个表分配到哪个 vgroup 时只使用表名中指定长度的前缀;
- 例如:假定表名为 "v30001",当 TSDB_PREFIX = 2 时,使用 "0001" 来决定分配到哪个 vgroup ,当 TSDB_PREFIX = -2 时使用 "v3" 来决定分配到哪个 vgroup。
- TABLE_SUFFIX分配数据表到某个 vgroup 时,用于忽略或仅使用表名后缀的长度值。
- 当其为正值时,在决定把一个表分配到哪个 vgroup 时要忽略表名中指定长度的后缀;
- 当其为负值时,在决定把一个表分配到哪个 vgroup 时只使用表名中指定长度的后缀;
- 例如:假定表名为 "v30001",当 TSDB_SUFFIX = 2 时,使用 "v300" 来决定分配到哪个 vgroup ,当 TSDB_SUFFIX = -2 时使用 "01" 来决定分配到哪个 vgroup。
- TSDB_PAGESIZE一个 vnode 中时序数据存储引擎的页大小,单位为 KB默认为 4 KB。范围为 1 到 16384即 1 KB到 16 MB。
- DNODES指定 vnode 所在的 DNODE 列表,如 '1,2,3',以逗号区分且字符间不能有空格,仅企业版支持。
- DNODES指定 vnode 所在的 DNODE 列表,如 '1,2,3',以逗号区分且字符间不能有空格 **仅企业版支持**
- WAL_LEVELWAL 级别,默认为 1。
- 1写 WAL但不执行 fsync。
- 2写 WAL而且执行 fsync。
- WAL_FSYNC_PERIOD当 WAL_LEVEL 参数设置为 2 时,用于设置落盘的周期。默认为 3000单位毫秒。最小为 0表示每次写入立即落盘最大为 180000即三分钟。
- WAL_RETENTION_PERIOD为了数据订阅消费需要 WAL 日志文件额外保留的最大时长策略。WAL 日志清理,不受订阅客户端消费状态影响。单位为 s。默认为 3600表示在 WAL 保留最近 3600 秒的数据,请根据数据订阅的需要修改这个参数为适当值。
- WAL_RETENTION_SIZE为了数据订阅消费需要 WAL 日志文件额外保留的最大累计大小策略。单位为 KB。默认为 0表示累计大小无上限。
- COMPACT_INTERVAL自动 compact 触发周期(从 1970-01-01T00:00:00Z 开始切分的时间周期)。取值范围0 或 [10m, keep2]单位m分钟h小时d。不加时间单位默认单位为天默认值为 0即不触发自动 compact 功能。如果 db 中有未完成的 compact 任务,不重复下发 compact 任务。仅企业版 3.3.5.0 版本开始支持。
- COMPACT_TIME_RANGE自动 compact 任务触发的 compact 时间范围,取值范围:[-keep2, -duration]单位m分钟h小时d。不加时间单位时默认单位为天默认值为 [0, 0]。取默认值 [0, 0] 时,如果 COMPACT_INTERVAL 大于 0会按照 [-keep2, -duration] 下发自动 compact。因此要关闭自动 compact 功能,需要将 COMPACT_INTERVAL 设置为 0。仅企业版 3.3.5.0 版本开始支持。
- COMPACT_TIME_OFFSET自动 compact 任务触发的 compact 时间相对本地时间的偏移量。取值范围:[0, 23]单位h小时默认值为 0。以 UTC 0 时区为例,如果 COMPACT_INTERVAL 为 1d当 COMPACT_TIME_OFFSET 为 0 时,在每天 0 点下发自动 compact如果 COMPACT_TIME_OFFSET 为 2在每天 2 点下发自动 compact。仅企业版 3.3.5.0 版本开始支持。
-
- COMPACT_INTERVAL自动 compact 触发周期(从 1970-01-01T00:00:00Z 开始切分的时间周期)**仅企业版 3.3.5.0 版本开始支持**)。
- 取值范围0 或 [10m, keep2]单位m分钟h小时d
- 不加时间单位默认单位为天,默认值为 0即不触发自动 compact 功能;
- 如果 db 中有未完成的 compact 任务,不重复下发 compact 任务。
- COMPACT_TIME_RANGE自动 compact 任务触发的 compact 时间范围(**仅企业版 3.3.5.0 版本开始支持**)。
- 取值范围:[-keep2, -duration]单位m分钟h小时d
- 不加时间单位时默认单位为天,默认值为 [0, 0]
- 取默认值 [0, 0] 时,如果 COMPACT_INTERVAL 大于 0会按照 [-keep2, -duration] 下发自动 compact
- 因此,要关闭自动 compact 功能,需要将 COMPACT_INTERVAL 设置为 0。
- COMPACT_TIME_OFFSET自动 compact 任务触发的 compact 时间相对本地时间的偏移量(**仅企业版 3.3.5.0 版本开始支持**)。取值范围:[0, 23]单位h小时默认值为 0。以 UTC 0 时区为例:
- 如果 COMPACT_INTERVAL 为 1d当 COMPACT_TIME_OFFSET 为 0 时,在每天 0 点下发自动 compact
- 如果 COMPACT_TIME_OFFSET 为 2在每天 2 点下发自动 compact。
### 创建数据库示例
```sql
create database if not exists db vgroups 10 buffer 10
create database if not exists db vgroups 10 buffer 10;
```
以上示例创建了一个有 10 个 vgroup 名为 db 的数据库, 其中每个 vnode 分配 10MB 的写入缓存
@ -108,7 +135,7 @@ USE db_name;
## 删除数据库
```sql
DROP DATABASE [IF EXISTS] db_name
DROP DATABASE [IF EXISTS] db_name;
```
删除数据库。指定 Database 所包含的全部数据表将被删除,该数据库的所有 vgroups 也会被全部销毁,请谨慎使用!
@ -146,15 +173,18 @@ alter_database_option: {
1. 如何查看 cachesize?
通过 select * from information_schema.ins_databases; 可以查看这些 cachesize 的具体值(单位为 MB
通过 select * from information_schema.ins_databases; 可以查看这些 cachesize 的具体值(单位MB
2. 如何查看 cacheload?
通过 show \<db_name>.vgroups; 可以查看 cacheload单位字节)。
通过 show \<db_name>.vgroups; 可以查看 cacheload单位Byte字节)。
3. 判断 cachesize 是否够用
如果 cacheload 非常接近 cachesize则 cachesize 可能过小。 如果 cacheload 明显小于 cachesize 则 cachesize 是够用的。可以根据这个原则判断是否需要修改 cachesize 。具体修改值可以根据系统可用内存情况来决定是加倍或者是提高几倍。
- 如果 cacheload 非常接近 cachesize则 cachesize 可能过小。
- 如果 cacheload 明显小于 cachesize 则 cachesize 是够用的。
- 可以根据这个原则判断是否需要修改 cachesize 。
- 具体修改值可以根据系统可用内存情况来决定是加倍或者是提高几倍。
:::note
其它参数在 3.0.0.0 中暂不支持修改
@ -204,7 +234,7 @@ FLUSH DATABASE db_name;
## 调整 VGROUP 中 VNODE 的分布
```sql
REDISTRIBUTE VGROUP vgroup_no DNODE dnode_id1 [DNODE dnode_id2] [DNODE dnode_id3]
REDISTRIBUTE VGROUP vgroup_no DNODE dnode_id1 [DNODE dnode_id2] [DNODE dnode_id3];
```
按照给定的 dnode 列表,调整 vgroup 中的 vnode 分布。因为副本数目最大为 3所以最多输入 3 个 dnode。
@ -212,10 +242,10 @@ REDISTRIBUTE VGROUP vgroup_no DNODE dnode_id1 [DNODE dnode_id2] [DNODE dnode_id3
## 自动调整 VGROUP 中 LEADER 的分布
```sql
BALANCE VGROUP LEADER
BALANCE VGROUP LEADER;
```
触发集群所有 vgroup 中的 leader 重新选主,对集群各节点进行负载均衡操作。(企业版功能)
触发集群所有 vgroup 中的 leader 重新选主,对集群各节点进行负载均衡操作。(**企业版功能**
## 查看数据库工作状态
@ -223,19 +253,22 @@ BALANCE VGROUP LEADER
SHOW db_name.ALIVE;
```
查询数据库 db_name 的可用状态,返回值 0不可用 1完全可用 2部分可用即数据库包含的 VNODE 部分节点可用,部分节点不可用)
查询数据库 db_name 的可用状态(返回值):
- 0不可用
- 1完全可用
- 2部分可用即数据库包含的 VNODE 部分节点可用,部分节点不可用)。
## 查看 DB 的磁盘空间占用
```sql
select * from INFORMATION_SCHEMA.INS_DISK_USAGE where db_name = 'db_name'
select * from INFORMATION_SCHEMA.INS_DISK_USAGE where db_name = 'db_name';
```
查看DB各个模块所占用磁盘的大小
查看DB各个模块所占用磁盘的大小
```sql
SHOW db_name.disk_info;
```
查看数据库 db_name 的数据压缩压缩率和数据在磁盘上所占用的大小
查看数据库 db_name 的数据压缩压缩率和数据在磁盘上所占用的大小
该命令本质上等同于 `select sum(data1 + data2 + data3)/sum(raw_data), sum(data1 + data2 + data3) from information_schema.ins_disk_usage where db_name="dbname"`
该命令本质上等同于 `select sum(data1 + data2 + data3)/sum(raw_data), sum(data1 + data2 + data3) from information_schema.ins_disk_usage where db_name="dbname";`

View File

@ -59,11 +59,11 @@ CREATE TOPIC [IF NOT EXISTS] topic_name [with meta] AS DATABASE db_name;
## 删除 topic
如果不再需要订阅数据,可以删除 topic需要注意:只有当前未在订阅中的 TOPIC 才能被删除
如果不再需要订阅数据,可以删除 topic如果当前 topic 被消费者订阅,通过 FORCE 语法可强制删除强制删除后订阅的消费者会消费数据会出错FORCE 语法3.3.6.0版本开始支持)
```sql
/* 删除 topic */
DROP TOPIC [IF EXISTS] topic_name;
DROP TOPIC [IF EXISTS] [FORCE] topic_name;
```
此时如果该订阅主题上存在 consumer则此 consumer 会收到一个错误。
@ -82,8 +82,10 @@ SHOW TOPICS;
## 删除消费组
消费者创建的时候,会给消费者指定一个消费者组,消费者不能显式的删除,但是可以删除消费者组。如果当前消费者组里有消费者在消费,通过 FORCE 语法可强制删除强制删除后订阅的消费者会消费数据会出错FORCE 语法3.3.6.0版本开始支持)。
```sql
DROP CONSUMER GROUP [IF EXISTS] cgroup_name ON topic_name;
DROP CONSUMER GROUP [IF EXISTS] [FORCE] cgroup_name ON topic_name;
```
删除主题 topic_name 上的消费组 cgroup_name。

View File

@ -10,11 +10,11 @@ description: 流式计算的相关 SQL 的详细语法
```sql
CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name[(field1_name, field2_name [PRIMARY KEY], ...)] [TAGS (create_definition [, create_definition] ...)] SUBTABLE(expression) AS subquery [notification_definition]
stream_options: {
TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time | FORCE_WINDOW_CLOSE]
TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time | FORCE_WINDOW_CLOSE| CONTINUOUS_WINDOW_CLOSE [recalculate rec_time_val] ]
WATERMARK time
IGNORE EXPIRED [0|1]
DELETE_MARK time
FILL_HISTORY [0|1]
FILL_HISTORY [0|1] [ASYNC]
IGNORE UPDATE [0|1]
}
@ -34,7 +34,7 @@ subquery: SELECT select_list
stb_name 是保存计算结果的超级表的表名,如果该超级表不存在,会自动创建;如果已存在,则检查列的 schema 信息。详见 [写入已存在的超级表](#写入已存在的超级表)。
TAGS 子句定义了流计算中创建TAG的规则可以为每个 partition 对应的子表生成自定义的TAG值详见 [自定义 TAG](#自定义 TAG)
TAGS 子句定义了流计算中创建TAG的规则可以为每个 partition 对应的子表生成自定义的TAG值详见 [自定义 TAG](#自定义-TAG)
```sql
create_definition:
col_name column_definition
@ -42,7 +42,7 @@ column_definition:
type_name [COMMENT 'string_value']
```
subtable 子句定义了流式计算中创建的子表的命名规则,详见 [流式计算的 partition](#流式计算的 partition)。
subtable 子句定义了流式计算中创建的子表的命名规则,详见 [流式计算的 partition](#流式计算的-partition)。
```sql
window_clause: {
@ -127,6 +127,13 @@ create stream if not exists s1 fill_history 1 into st1 as select count(*) from
如果该流任务已经彻底过期,并且您不再想让它检测或处理数据,您可以手动删除它,被计算出的数据仍会被保留。
注意:
- 开启 fill_history 时,创建流需要找到历史数据的分界点,如果历史数据很多,可能会导致创建流任务耗时较长,此时可以通过 fill_history 1 asyncv3.3.6.0 开始支持) 语法将创建流的任务放在后台处理创建流的语句可立即返回不阻塞后面的操作。async 只对 fill_history 1 起效fill_history 0 时建流很快,不需要异步处理。
- 通过 show streams 可查看后台建流的进度ready 状态表示成功init 状态表示正在建流failed 状态表示建流失败,失败时 message 列可以查看原因。对于建流失败的情况可以删除流重新建立)。
- 另外,不要同时异步创建多个流,可能由于事务冲突导致后面创建的流失败。
## 删除流式计算
```sql
@ -158,8 +165,11 @@ SELECT * from information_schema.`ins_streams`;
2. WINDOW_CLOSE窗口关闭时触发窗口关闭由事件时间决定可配合 watermark 使用)
3. MAX_DELAY time若窗口关闭则触发计算。若窗口未关闭且未关闭时长超过 max delay 指定的时间,则触发计算。
4. FORCE_WINDOW_CLOSE以操作系统当前时间为准只计算当前关闭窗口的结果并推送出去。窗口只会在被关闭的时刻计算一次后续不会再重复计算。该模式当前只支持 INTERVAL 窗口不支持滑动FILL_HISTORY 必须为 0IGNORE EXPIRED 必须为 1IGNORE UPDATE 必须为 1FILL 只支持 PREV、NULL、NONE、VALUE。
5. CONTINUOUS_WINDOW_CLOSE窗口关闭时输出结果。修改、删除数据并不会立即触发重算每等待 rec_time_val 时长,会进行周期性重算。如果不指定 rec_time_val那么重算周期是60分钟。如果重算的时间长度超过 rec_time_val在本次重算后自动开启下一次重算。该模式当前只支持 INTERVAL 窗口。如果使用 FILL需要配置 adapter的相关信息adapterFqdn、adapterPort、adapterToken。adapterToken 为 `{username}:{password}` 经过 Base64 编码之后的字符串,例如 `root:taosdata` 编码后为 `cm9vdDp0YW9zZGF0YQ==`
由于窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,则事件时间无法更新,可能导致无法得到最新的计算结果。
因此,流式计算提供了以事件时间结合处理时间计算的 MAX_DELAY 触发模式。MAX_DELAY 最小时间是 5s如果低于 5s创建流计算时会报错。

View File

@ -30,6 +30,17 @@ SELECT a.* FROM meters a LEFT ASOF JOIN meters b ON timetruncate(a.ts, 1s) < tim
### 主连接条件
作为一款时序数据库TDengine 所有的关联查询都围绕主键时戳列进行,因此要求除 ASOF/Window Join 外的所有关联查询都必须含有主键列的等值连接条件而按照顺序首次出现在连接条件中的主键列等值连接条件将会被作为主连接条件。ASOF Join 的主连接条件可以包含非等值的连接条件,而 Window Join 的主连接条件则是通过 `WINDOW_OFFSET` 来指定。
从 3.3.6.0 版本开始TDengine 支持子查询中的常量包含返回时戳的常量函数如today()、now()等,常量时戳及其加减运算)作为等价主键列可以出现在主连接条件中。例如:
```sql
SELECT * from d1001 a JOIN (SELECT today() as ts1, * from d1002 WHERE ts = '2025-03-19 10:00:00.000') b ON timetruncate(a.ts, 1d) = b.ts1;
```
上面的示例语句可以实现表 d1001 今天的所有记录与表 d1002 中某一时刻的某条记录进行关联运算。需要注意的是SQL 中出现的时间字符串常量默认不会被当作时戳,例如 `'2025-03-19 10:00:00.000'` 只会被当作字符串而不是时戳,因此当需要作为常量时戳处理时,可以通过类型前缀 timestamp 来指定字符串常量为时间戳类型,例如:
```sql
SELECT * from d1001 a JOIN (SELECT timestamp '2025-03-19 10:00:00.000' as ts1, * from d1002 WHERE ts = '2025-03-19 10:00:00.000') b ON timetruncate(a.ts, 1d) = b.ts1;
```
除 Window Join 外TDengine 支持在主连接条件中进行 `timetruncate` 函数操作,例如 `ON timetruncate(a.ts, 1s) = timetruncate(b.ts, 1s)`,除此之外,暂不支持其他函数及标量运算。
@ -39,7 +50,7 @@ SELECT a.* FROM meters a LEFT ASOF JOIN meters b ON timetruncate(a.ts, 1s) < tim
### 主键时间线
TDengine 作为时序数据库要求每个表(子表)中必须有主键时间戳列,它将作为该表的主键时间线进行很多跟时间相关的运算,而子查询的结果或者 Join 运算的结果中也需要明确哪一列将被视作主键时间线参与后续的时间相关的运算。在子查询中,查询结果中存在的有序的第一个出现的主键列(或其运算)或等同主键列的伪列(`_wstart`/`_wend`将被视作该输出表的主键时间线。Join 输出结果中主键时间线的选择遵从以下规则:
TDengine 作为时序数据库要求每个表(子表)中必须有主键时间戳列,它将作为该表的主键时间线进行很多跟时间相关的运算,而子查询的结果或者 Join 运算的结果中也需要明确哪一列将被视作主键时间线参与后续的时间相关的运算。在子查询中,查询结果中存在的有序的第一个出现的主键列(或其运算)或等同主键列的伪列(`_wstart`/`_wend`)将被视作该输出表的主键时间线。此外,从 3.3.6.0 版本开始TDengine 也开始支持子查询结果中的常量时戳列作为输出表的主键时间线。Join 输出结果中主键时间线的选择遵从以下规则:
- Left/Right Join 系列中驱动表(子查询)的主键列将被作为后续查询的主键时间线;此外,在 Window Join 窗口内,因为左右表同时有序所以在窗口内可以把任意一个表的主键列做作主键时间线,优先选择本表的主键列作为主键时间线。
- Inner Join 可以把任意一个表的主键列做作主键时间线当存在类似分组条件Tag 列的等值条件且与主连接条件 `AND` 关系)时将无法产生主键时间线。
- Full Join 因为无法产生任何一个有效的主键时间序列,因此没有主键时间线,这也就意味着 Full Join 中无法进行时间线相关的运算。

View File

@ -1115,10 +1115,14 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
- conf[入参] 指向一个有效的 tmq_conf_t 结构体指针,该结构体代表一个 TMQ 配置对象。
- key[入参] 数配置项的键名。
- value[入参] 配置项的值。
- **返回值**:返回一个 tmq_conf_res_t 枚举值,表示配置设置的结果。
- TMQ_CONF_OK成功设置配置项。
- TMQ_CONF_INVALID_KEY键值无效。
- TMQ_CONF_UNKNOWN键名无效。
- **返回值**:返回一个 tmq_conf_res_t 枚举值表示配置设置的结果。tmq_conf_res_t 定义如下:
```
typedef enum tmq_conf_res_t {
TMQ_CONF_UNKNOWN = -2, // 键名无效
TMQ_CONF_INVALID = -1, // 键值无效
TMQ_CONF_OK = 0, // 成功设置配置项
} tmq_conf_res_t;
```
- `void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param)`
- **接口说明**:设置 TMQ 配置对象中的自动提交回调函数。

View File

@ -148,6 +148,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对
| JSON | java.lang.String |仅在 tag 中支持|
| VARBINARY | byte[] ||
| GEOMETRY | byte[] ||
| DECIMAL | java.math.BigDecimal ||
**注意**由于历史原因TDengine中的BINARY底层不是真正的二进制数据已不建议使用。请用VARBINARY类型代替。
GEOMETRY类型是little endian字节序的二进制数据符合WKB规范。详细信息请参考 [数据类型](../../taos-sql/data-type/#数据类型)

View File

@ -31,7 +31,7 @@ description: "TDengine 服务端、客户端和连接器支持的平台列表"
## TDengine 客户端和连接器支持的平台列表
目前 TDengine 的连接器可支持的平台广泛目前包括X64/X86/ARM64/ARM32/MIPS/LoongArch64 等硬件平台,以及 Linux/Win64/Win32/macOS 等开发环境。
目前 TDengine 的连接器可支持的平台广泛目前包括X64/X86/ARM64/ARM32/MIPS/LoongArch64(或Loong64) 等硬件平台,以及 Linux/Win64/Win32/macOS 等开发环境。
对照矩阵如下:

View File

@ -174,6 +174,7 @@ description: TDengine 服务端的错误码列表和详细说明
| 0x8000038B | Index not exist | 不存在 | 确认操作是否正确 |
| 0x80000396 | Database in creating status | 数据库正在被创建 | 重试 |
| 0x8000039A | Invalid system table name | 内部错误 | 上报 issue |
| 0x8000039F | No VGroup's leader need to be balanced | 执行 balance vgroup leader 操作 | 没有需要进行 balance leader 操作的 VGroup |
| 0x800003A0 | Mnode already exists | 已存在 | 确认操作是否正确 |
| 0x800003A1 | Mnode not there | 已存在 | 确认操作是否正确 |
| 0x800003A2 | Qnode already exists | 已存在 | 确认操作是否正确 |
@ -577,10 +578,11 @@ description: TDengine 服务端的错误码列表和详细说明
## virtual table
| 错误码 | 错误描述 | 可能的出错场景或者可能的原因 | 建议用户采取的措施 |
|------------|---------------------------------------------------------|------------------------------------------------|------------------------|
| 0x80006200 | Virtual table scan 算子内部错误 | virtual table scan 算子内部逻辑错误,一般不会出现 | 具体查看client端的错误日志提示 |
| 0x80006201 | Virtual table scan invalid downstream operator type | 由于生成的执行计划不对,导致 virtual table scan 算子的下游算子类型不正确 | 保留 explain 执行计划,联系开发处理 |
| 0x80006202 | Virtual table prim timestamp column should not has ref | 虚拟表的时间戳主键列不应该有数据源,如果有,后续查询虚拟表的时候就会出现该错误 | 检查错误日志,联系开发处理 |
| 0x80006203 | Create virtual child table must use virtual super table | 虚拟子表必须建在虚拟超级表下,否则就会出现该错误 | 创建虚拟子表的时候USING 虚拟超级表 |
| 错误码 | 错误描述 | 可能的出错场景或者可能的原因 | 建议用户采取的措施 |
|------------|---------------------------------------------------------|------------------------------------------------|----------------------------|
| 0x80006200 | Virtual table scan 算子内部错误 | virtual table scan 算子内部逻辑错误,一般不会出现 | 具体查看client端的错误日志提示 |
| 0x80006201 | Virtual table scan invalid downstream operator type | 由于生成的执行计划不对,导致 virtual table scan 算子的下游算子类型不正确 | 保留 explain 执行计划,联系开发处理 |
| 0x80006202 | Virtual table prim timestamp column should not has ref | 虚拟表的时间戳主键列不应该有数据源,如果有,后续查询虚拟表的时候就会出现该错误 | 检查错误日志,联系开发处理 |
| 0x80006203 | Create virtual child table must use virtual super table | 虚拟子表必须建在虚拟超级表下,否则就会出现该错误 | 创建虚拟子表的时候USING 虚拟超级表 |
| 0x80006204 | Virtual table not support decimal type | 虚拟表不支持 decimal 类型 | 创建虚拟表时不使用 decimal 类型的列/tag |

View File

@ -0,0 +1,297 @@
---
title: 密码中特殊字符的使用
description: TDengine 用户密码中特殊字符的使用
---
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
TDengine 用户密码需满足以下规则:
1. 用户名最长不超过 23 个字节。
2. 密码长度必须为 8 到 255 位。
3. 密码字符的取值范围
1. 大写字母:`A-Z`
2. 小写字母:`a-z`
3. 数字:`0-9`
4. 特殊字符: `! @ # $ % ^ & * ( ) - _ + = [ ] { } : ; > < ? | ~ , .`
4. 强密码启用EnableStrongPassword 1默认开启至少包含大写字母、小写字母、数字、特殊字符中的三类不启用时字符种类不做约束。
## 各组件特殊字符使用指南
以用户名 `user1`,密码 `Ab1!@#$%^&*()-_+=[]{}` 为例。
```sql
CREATE USER user1 PASS 'Ab1!@#$%^&*()-_+=[]{}';
```
<Tabs defaultValue="shell" groupId="component">
<TabItem label="CLI" value="shell">
在 [TDengine 命令行客户端CLI](../../reference/tools/taos-cli/) 中使用需要注意以下几点:
- 使用参数 `-p` 后不带密码,会提示输入密码,可输入任意可接收字符。
- 使用参数 `-p` 后带密码,如果密码中包含特殊字符,需使用单引号。
使用用户 `user1` 登录:
```shell
taos -u user1 -p'Ab1!@#$%^&*()-_+=[]{}'
taos -u user1 -pAb1\!\@\#\$\%\^\&\*\(\)\-\_\+\=\[\]\{\}
```
</TabItem>
<TabItem label="taosdump" value="taosdump">
在 [taosdump](../../reference/tools/taosdump/) 中使用需要注意以下几点:
- 使用参数 `-p` 后不带密码,会提示输入密码,可输入任意可接收字符。
- 使用参数 `-p` 后带密码,如果密码中包含特殊字符,需使用单引号或进行转义。
使用用户 `user1` 备份数据库 `test`
```shell
taosdump -u user1 -p'Ab1!@#$%^&*()-_+=[]{}' -D test
taosdump -u user1 -pAb1\!\@\#\$\%\^\&\*\(\)\-\_\+\=\[\]\{\} -D test
```
</TabItem>
<TabItem label="Benchmark" value="benchmark">
在 [taosBenchmark](../../reference/tools/taosbenchmark/) 中使用需要注意以下几点:
- 使用参数 `-p` 后不带密码,会提示输入密码,可输入任意可接收字符。
- 使用参数 `-p` 后带密码,如果密码中包含特殊字符,需使用单引号或进行转义。
使用用户 `user1` 进行数据写入测试示例如下:
```shell
taosBenchmark -u user1 -p'Ab1!@#$%^&*()-_+=[]{}' -d test -y
```
使用 `taosBenchmark -f <JSON>` 方式时JSON 文件中密码使用无限制。
</TabItem>
<TabItem label="taosX" value="taosx">
[taosX](../../reference/components/taosx/) 使用 DSN 表示 TDengine 连接,使用如下格式:`(taos|tmq)[+ws]://<user>:<pass>@<ip>:<port>`,其中 `<pass>` 可以包含特殊字符,如:`taos+ws://user1:Ab1!@#$%^&*()-_+=[]{}@192.168.10.10:6041`。
使用用户 `user1` 导出数据示例如下:
```shell
taosx -f 'taos://user1:Ab1!@#$%^&*()-_+=[]{}@localhost:6030?query=select * from test.t1' \
-t 'csv:./test.csv'
```
需要注意的是,如果密码可被 URL decode则会使用 URL decoded 结果作为密码。如:`taos+ws://user1:Ab1%21%40%23%24%25%5E%26%2A%28%29-_%2B%3D%5B%5D%7B%7D@localhost:6041` 与 `taos+ws://user1:Ab1!@#$%^&*()-_+=[]{}@localhost:6041` 是等价的。
在 [Explorer](../../reference/components/explorer/) 中无需特殊处理,直接使用即可。
</TabItem>
<TabItem label="Java" value="java">
在 JDBC 中使用特殊字符密码时,密码需要通过 URL 编码,示例如下:
```java
package com.taosdata.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import com.taosdata.jdbc.TSDBDriver;
public class JdbcPassDemo {
public static void main(String[] args) throws Exception {
String password = "Ab1!@#$%^&*()-_+=[]{}";
String encodedPassword = URLEncoder.encode(password, StandardCharsets.UTF_8.toString());
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "user1");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, encodedPassword);
connProps.setProperty(TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT, "true");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
try (Connection conn = DriverManager.getConnection(jdbcUrl, connProps)) {
System.out.println("Connected to " + jdbcUrl + " successfully.");
// you can use the connection for execute SQL here
} catch (Exception ex) {
// please refer to the JDBC specifications for detailed exceptions info
System.out.printf("Failed to connect to %s, %sErrMessage: %s%n",
jdbcUrl,
ex instanceof SQLException ? "ErrCode: " + ((SQLException) ex).getErrorCode() + ", " : "",
ex.getMessage());
// Print stack trace for context in examples. Use logging in production.
ex.printStackTrace();
throw ex;
}
}
}
```
</TabItem>
<TabItem label="Python" value="python">
在 Python 中使用特殊字符密码无需特殊处理,示例如下:
```python
import taos
import taosws
def create_connection():
host = "localhost"
port = 6030
return taos.connect(
user="user1",
password="Ab1!@#$%^&*()-_+=[]{}",
host=host,
port=port,
)
def create_ws_connection():
host = "localhost"
port = 6041
return taosws.connect(
user="user1",
password="Ab1!@#$%^&*()-_+=[]{}",
host=host,
port=port,
)
def show_databases(conn):
cursor = conn.cursor()
cursor.execute("show databases")
print(cursor.fetchall())
cursor.close()
if __name__ == "__main__":
print("Connect with native protocol")
conn = create_connection()
show_databases(conn)
print("Connect with websocket protocol")
conn = create_ws_connection()
show_databases(conn)
```
</TabItem>
<TabItem label="Go" value="go">
从 3.6.0 版本开始Go 语言中支持密码中包含特殊字符,使用时需要 encodeURIComponent 编码。
```go
package main
import (
"database/sql"
"fmt"
"log"
"net/url"
_ "github.com/taosdata/driver-go/v3/taosWS"
)
func main() {
var user = "user1"
var password = "Ab1!@#$%^&*()-_+=[]{}"
var encodedPassword = url.QueryEscape(password)
var taosDSN = user + ":" + encodedPassword + "@ws(localhost:6041)/"
taos, err := sql.Open("taosWS", taosDSN)
if err != nil {
log.Fatalln("Failed to connect to " + taosDSN + "; ErrMessage: " + err.Error())
}
fmt.Println("Connected to " + taosDSN + " successfully.")
defer taos.Close()
}
```
</TabItem>
<TabItem label="Rust" value="rust">
Rust 中使用 DSN 表示 TDengine 连接,使用如下格式:`(taos|tmq)[+ws]://<user>:<pass>@<ip>:<port>`,其中 `<pass>` 可以包含特殊字符,如:`taos+ws://user1:Ab1!@#$%^&*()-_+=[]{}@192.168.10.10:6041`。
```rust
let dsn = "taos+ws://user1:Ab1!@#$%^&*()-_+=[]{}@localhost:6041";
let connection = TaosBuilder::from_dsn(&dsn)?.build().await?;
```
</TabItem>
<TabItem label="Node.js" value="node">
从 3.1.5 版本开始Node.js 连接器支持密码中包含特殊字符无需特殊处理。
```js
const taos = require("@tdengine/websocket");
let dsn = 'ws://localhost:6041';
async function createConnect() {
try {
let conf = new taos.WSConfig(dsn);
conf.setUser('user1');
conf.setPwd('Ab1!@#$%^&*()-_+=[]{}');
conf.setDb('test');
conn = await taos.sqlConnect(conf);
console.log("Connected to " + dsn + " successfully.");
return conn;
} catch (err) {
console.log("Connection failed with code: " + err.code + ", message: " + err.message);
throw err;
}
}
createConnect()
```
</TabItem>
<TabItem label="C#" value="csharp">
在 C# 中使用密码时,需要注意:使用连接字符串时,不支持分号(因分号为分隔符);此时可使用不带密码的字符串构建 `ConnectionStringBuilder`,之后再设置用户名和密码。
示例如下:
```csharp
var builder = new ConnectionStringBuilder("host=localhost;port=6030");
builder.Username = "user1";
builder.Password = "Ab1!@#$%^&*()-_+=[]{}";
using (var client = DbDriver.Open(builder)){}
```
</TabItem>
<TabItem label="C" value="c">
C 语言中使用密码无限制。
```c
TAOS *taos = taos_connect("localhost", "user1", "Ab1!@#$%^&*()-_+=[]{}", NULL, 6030);
```
</TabItem>
<TabItem label="REST" value="rest">
REST API 中使用密码时,需要注意以下几点:
- 密码使用 Basic Auth格式为 `Authorization: Basic base64(<user>:<pass>)`
- 不支持密码中包含冒号 `:`
以下两种方式等价:
```shell
curl -u'user1:Ab1!@#$%^&*()-_+=[]{}' \
-d 'show databases' http://localhost:6041/rest/sql
curl -H 'Authorization: Basic dXNlcjE6QWIxIUAjJCVeJiooKS1fKz1bXXt9' \
-d 'show databases' http://localhost:6041/rest/sql
```
</TabItem>
</Tabs>

View File

@ -241,6 +241,7 @@ typedef struct SRestoreCheckpointInfo {
int32_t transId; // transaction id of the update the consensus-checkpointId transaction
int32_t taskId;
int32_t nodeId;
int32_t term;
} SRestoreCheckpointInfo;
int32_t tEncodeRestoreCheckpointInfo(SEncoder* pEncoder, const SRestoreCheckpointInfo* pReq);

View File

@ -297,7 +297,6 @@ extern bool tsFilterScalarMode;
extern int32_t tsMaxStreamBackendCache;
extern int32_t tsPQSortMemThreshold;
extern bool tsStreamCoverage;
extern bool tsStreamRunHistoryAsync;
extern int8_t tsS3EpNum;
extern int32_t tsStreamNotifyMessageSize;
extern int32_t tsStreamNotifyFrameSize;

View File

@ -3358,6 +3358,7 @@ typedef struct {
int8_t igNotExists;
int32_t sqlLen;
char* sql;
int8_t force;
} SMDropTopicReq;
int32_t tSerializeSMDropTopicReq(void* buf, int32_t bufLen, SMDropTopicReq* pReq);
@ -3368,6 +3369,7 @@ typedef struct {
char topic[TSDB_TOPIC_FNAME_LEN];
char cgroup[TSDB_CGROUP_LEN];
int8_t igNotExists;
int8_t force;
} SMDropCgroupReq;
int32_t tSerializeSMDropCgroupReq(void* buf, int32_t bufLen, SMDropCgroupReq* pReq);

View File

@ -54,6 +54,8 @@ const char* tNameGetDbNameP(const SName* name);
int32_t tNameGetFullDbName(const SName* name, char* dst);
int32_t tNameGetFullTableName(const SName* name, char* dst);
bool tNameIsEmpty(const SName* name);
void tNameAssign(SName* dst, const SName* src);

View File

@ -134,6 +134,8 @@ int32_t qUpdateTableListForStreamScanner(qTaskInfo_t tinfo, const SArray* tableI
bool qIsDynamicExecTask(qTaskInfo_t tinfo);
void qDestroyOperatorParam(SOperatorParam* pParam);
void qUpdateOperatorParam(qTaskInfo_t tinfo, void* pParam);
/**

View File

@ -553,6 +553,7 @@ typedef struct SDropTopicStmt {
ENodeType type;
char topicName[TSDB_TOPIC_NAME_LEN];
bool ignoreNotExists;
bool force;
} SDropTopicStmt;
typedef struct SDropCGroupStmt {
@ -560,6 +561,7 @@ typedef struct SDropCGroupStmt {
char topicName[TSDB_TOPIC_NAME_LEN];
char cgroup[TSDB_CGROUP_LEN];
bool ignoreNotExists;
bool force;
} SDropCGroupStmt;
typedef struct SAlterClusterStmt {
@ -608,6 +610,7 @@ typedef struct SStreamOptions {
SNode* pDeleteMark;
SNode* pRecInterval;
int8_t fillHistory;
bool runHistoryAsync;
int8_t ignoreExpired;
int8_t ignoreUpdate;
int64_t setFlag;

View File

@ -495,6 +495,17 @@ struct SStreamTask {
typedef int32_t (*startComplete_fn_t)(struct SStreamMeta*);
typedef enum {
START_MARK_REQ_CHKPID = 0x1,
START_WAIT_FOR_CHKPTID = 0x2,
START_CHECK_DOWNSTREAM = 0x3,
} EStartStage;
typedef struct {
EStartStage stage;
int64_t ts;
} SStartTaskStageInfo;
typedef struct STaskStartInfo {
int64_t startTs;
int64_t readyTs;
@ -504,6 +515,8 @@ typedef struct STaskStartInfo {
SHashObj* pFailedTaskSet; // tasks that are done the check downstream process, may be successful or failed
int64_t elapsedTime;
int32_t restartCount; // restart task counter
EStartStage curStage; // task start stage
SArray* pStagesList; // history stage list with timestamp, SArrya<SStartTaskStageInfo>
startComplete_fn_t completeFn; // complete callback function
} STaskStartInfo;
@ -738,7 +751,7 @@ void streamTaskStopMonitorCheckRsp(STaskCheckInfo* pInfo, const char* id);
void streamTaskCleanupCheckInfo(STaskCheckInfo* pInfo);
// fill-history task
int32_t streamLaunchFillHistoryTask(SStreamTask* pTask);
int32_t streamLaunchFillHistoryTask(SStreamTask* pTask, bool lock);
int32_t streamStartScanHistoryAsync(SStreamTask* pTask, int8_t igUntreated);
void streamExecScanHistoryInFuture(SStreamTask* pTask, int32_t idleDuration);
bool streamHistoryTaskSetVerRangeStep2(SStreamTask* pTask, int64_t latestVer);
@ -810,12 +823,14 @@ void streamMetaNotifyClose(SStreamMeta* pMeta);
void streamMetaStartHb(SStreamMeta* pMeta);
int32_t streamMetaAddTaskLaunchResult(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
int64_t endTs, bool ready);
int32_t streamMetaAddTaskLaunchResultNoLock(SStreamMeta* pMeta, int64_t streamId, int32_t taskId,
int64_t startTs, int64_t endTs, bool ready);
int32_t streamMetaInitStartInfo(STaskStartInfo* pStartInfo);
void streamMetaClearStartInfo(STaskStartInfo* pStartInfo);
int32_t streamMetaResetTaskStatus(SStreamMeta* pMeta);
int32_t streamMetaAddFailedTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId);
void streamMetaAddFailedTaskSelf(SStreamTask* pTask, int64_t failedTs);
int32_t streamMetaAddFailedTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, bool lock);
void streamMetaAddFailedTaskSelf(SStreamTask* pTask, int64_t failedTs, bool lock);
void streamMetaAddIntoUpdateTaskList(SStreamMeta* pMeta, SStreamTask* pTask, SStreamTask* pHTask, int32_t transId,
int64_t startTs);
void streamMetaClearSetUpdateTaskListComplete(SStreamMeta* pMeta);

View File

@ -21,6 +21,7 @@
#include "tdef.h"
#include "tlog.h"
#include "tmsg.h"
#include "ttrace.h"
#ifdef __cplusplus
extern "C" {
@ -170,7 +171,8 @@ void walClose(SWal *);
// write interfaces
// By assigning index by the caller, wal gurantees linearizability
int32_t walAppendLog(SWal *, int64_t index, tmsg_t msgType, SWalSyncInfo syncMeta, const void *body, int32_t bodyLen);
int32_t walAppendLog(SWal *, int64_t index, tmsg_t msgType, SWalSyncInfo syncMeta, const void *body, int32_t bodyLen,
const STraceId *trace);
int32_t walFsync(SWal *, bool force);
// apis for lifecycle management

View File

@ -367,6 +367,7 @@ int32_t taosGetErrSize();
#define TSDB_CODE_MND_INVALID_WAL_LEVEL TAOS_DEF_ERROR_CODE(0, 0x039C)
#define TSDB_CODE_MND_INVALID_DNODE_LIST_FMT TAOS_DEF_ERROR_CODE(0, 0x039D)
#define TSDB_CODE_MND_DNODE_LIST_REPEAT TAOS_DEF_ERROR_CODE(0, 0x039E)
#define TSDB_CODE_MND_NO_VGROUP_ON_DB TAOS_DEF_ERROR_CODE(0, 0x039F)
// mnode-node
#define TSDB_CODE_MND_MNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x03A0)
@ -1069,6 +1070,7 @@ int32_t taosGetErrSize();
#define TSDB_CODE_VTABLE_SCAN_INVALID_DOWNSTREAM TAOS_DEF_ERROR_CODE(0, 0x6201)
#define TSDB_CODE_VTABLE_PRIMTS_HAS_REF TAOS_DEF_ERROR_CODE(0, 0x6202)
#define TSDB_CODE_VTABLE_NOT_VIRTUAL_SUPER_TABLE TAOS_DEF_ERROR_CODE(0, 0x6203)
#define TSDB_CODE_VTABLE_NOT_SUPPORT_DATA_TYPE TAOS_DEF_ERROR_CODE(0, 0x6204)
#ifdef __cplusplus
}
#endif

View File

@ -36,6 +36,12 @@ extern "C" {
#define FLT_GREATEREQUAL(_x, _y) (FLT_EQUAL((_x), (_y)) || ((_x) > (_y)))
#define FLT_LESSEQUAL(_x, _y) (FLT_EQUAL((_x), (_y)) || ((_x) < (_y)))
#define DBL_EQUAL(_x, _y) fabs((_x) - (_y)) <= (FLT_COMPAR_TOL_FACTOR * DBL_EPSILON)
#define DBL_GREATER(_x, _y) (!DBL_EQUAL((_x), (_y)) && ((_x) > (_y)))
#define DBL_LESS(_x, _y) (!DBL_EQUAL((_x), (_y)) && ((_x) < (_y)))
#define DBL_GREATEREQUAL(_x, _y) (DBL_EQUAL((_x), (_y)) || ((_x) > (_y)))
#define DBL_LESSEQUAL(_x, _y) (DBL_EQUAL((_x), (_y)) || ((_x) < (_y)))
#define PATTERN_COMPARE_INFO_INITIALIZER { '%', '_', L'%', L'_' }
typedef struct SPatternCompareInfo {

View File

@ -37,6 +37,7 @@ demoName="${PREFIX}demo"
xname="${PREFIX}x"
explorerName="${PREFIX}-explorer"
keeperName="${PREFIX}keeper"
inspect_name="${PREFIX}inspect"
bin_link_dir="/usr/bin"
lib_link_dir="/usr/lib"
@ -156,12 +157,13 @@ done
#echo "verType=${verType} interactiveFqdn=${interactiveFqdn}"
tools=(${clientName} ${benchmarkName} ${dumpName} ${demoName} remove.sh taosudf set_core.sh TDinsight.sh start_pre.sh start-all.sh stop-all.sh)
tools=(${clientName} ${benchmarkName} ${dumpName} ${demoName} ${inspect_name} remove.sh taosudf set_core.sh TDinsight.sh start_pre.sh start-all.sh stop-all.sh)
if [ "${verMode}" == "cluster" ]; then
services=(${serverName} ${adapterName} ${xname} ${explorerName} ${keeperName})
elif [ "${verMode}" == "edge" ]; then
if [ "${pagMode}" == "full" ]; then
services=(${serverName} ${adapterName} ${keeperName} ${explorerName})
tools=(${clientName} ${benchmarkName} ${dumpName} ${demoName} remove.sh taosudf set_core.sh TDinsight.sh start_pre.sh start-all.sh stop-all.sh)
else
services=(${serverName})
tools=(${clientName} ${benchmarkName} remove.sh start_pre.sh)
@ -225,6 +227,7 @@ function install_bin() {
${csudo}cp -r ${script_dir}/bin/${clientName} ${install_main_dir}/bin
${csudo}cp -r ${script_dir}/bin/${benchmarkName} ${install_main_dir}/bin
${csudo}cp -r ${script_dir}/bin/${dumpName} ${install_main_dir}/bin
${csudo}cp -r ${script_dir}/bin/${inspect_name} ${install_main_dir}/bin
${csudo}cp -r ${script_dir}/bin/remove.sh ${install_main_dir}/bin
else
${csudo}cp -r ${script_dir}/bin/* ${install_main_dir}/bin
@ -521,14 +524,14 @@ function local_fqdn_check() {
function install_taosx_config() {
[ ! -z $1 ] && return 0 || : # only install client
fileName="${script_dir}/${xname}/etc/${PREFIX}/${xname}.toml"
if [ -f ${fileName} ]; then
${csudo}sed -i -r "s/#*\s*(fqdn\s*=\s*).*/\1\"${serverFqdn}\"/" ${fileName}
file_name="${script_dir}/${xname}/etc/${PREFIX}/${xname}.toml"
if [ -f ${file_name} ]; then
${csudo}sed -i -r "s/#*\s*(fqdn\s*=\s*).*/\1\"${serverFqdn}\"/" ${file_name}
if [ -f "${configDir}/${xname}.toml" ]; then
${csudo}cp ${fileName} ${configDir}/${xname}.toml.new
${csudo}cp ${file_name} ${configDir}/${xname}.toml.new
else
${csudo}cp ${fileName} ${configDir}/${xname}.toml
${csudo}cp ${file_name} ${configDir}/${xname}.toml
fi
fi
}
@ -538,18 +541,18 @@ function install_explorer_config() {
[ ! -z $1 ] && return 0 || : # only install client
if [ "$verMode" == "cluster" ]; then
fileName="${script_dir}/${xname}/etc/${PREFIX}/explorer.toml"
file_name="${script_dir}/${xname}/etc/${PREFIX}/explorer.toml"
else
fileName="${script_dir}/cfg/explorer.toml"
file_name="${script_dir}/cfg/explorer.toml"
fi
if [ -f ${fileName} ]; then
${csudo}sed -i "s/localhost/${serverFqdn}/g" ${fileName}
if [ -f ${file_name} ]; then
${csudo}sed -i "s/localhost/${serverFqdn}/g" ${file_name}
if [ -f "${configDir}/explorer.toml" ]; then
${csudo}cp ${fileName} ${configDir}/explorer.toml.new
${csudo}cp ${file_name} ${configDir}/explorer.toml.new
else
${csudo}cp ${fileName} ${configDir}/explorer.toml
${csudo}cp ${file_name} ${configDir}/explorer.toml
fi
fi
}
@ -557,14 +560,14 @@ function install_explorer_config() {
function install_adapter_config() {
[ ! -z $1 ] && return 0 || : # only install client
fileName="${script_dir}/cfg/${adapterName}.toml"
if [ -f ${fileName} ]; then
${csudo}sed -i -r "s/localhost/${serverFqdn}/g" ${fileName}
file_name="${script_dir}/cfg/${adapterName}.toml"
if [ -f ${file_name} ]; then
${csudo}sed -i -r "s/localhost/${serverFqdn}/g" ${file_name}
if [ -f "${configDir}/${adapterName}.toml" ]; then
${csudo}cp ${fileName} ${configDir}/${adapterName}.toml.new
${csudo}cp ${file_name} ${configDir}/${adapterName}.toml.new
else
${csudo}cp ${fileName} ${configDir}/${adapterName}.toml
${csudo}cp ${file_name} ${configDir}/${adapterName}.toml
fi
fi
}
@ -572,21 +575,21 @@ function install_adapter_config() {
function install_keeper_config() {
[ ! -z $1 ] && return 0 || : # only install client
fileName="${script_dir}/cfg/${keeperName}.toml"
if [ -f ${fileName} ]; then
${csudo}sed -i -r "s/127.0.0.1/${serverFqdn}/g" ${fileName}
file_name="${script_dir}/cfg/${keeperName}.toml"
if [ -f ${file_name} ]; then
${csudo}sed -i -r "s/127.0.0.1/${serverFqdn}/g" ${file_name}
if [ -f "${configDir}/${keeperName}.toml" ]; then
${csudo}cp ${fileName} ${configDir}/${keeperName}.toml.new
${csudo}cp ${file_name} ${configDir}/${keeperName}.toml.new
else
${csudo}cp ${fileName} ${configDir}/${keeperName}.toml
${csudo}cp ${file_name} ${configDir}/${keeperName}.toml
fi
fi
}
function install_taosd_config() {
fileName="${script_dir}/cfg/${configFile}"
if [ -f ${fileName} ]; then
file_name="${script_dir}/cfg/${configFile}"
if [ -f ${file_name} ]; then
${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$serverFqdn/" ${script_dir}/cfg/${configFile}
${csudo}echo "monitor 1" >>${script_dir}/cfg/${configFile}
${csudo}echo "monitorFQDN ${serverFqdn}" >>${script_dir}/cfg/${configFile}
@ -595,15 +598,27 @@ function install_taosd_config() {
fi
if [ -f "${configDir}/${configFile}" ]; then
${csudo}cp ${fileName} ${configDir}/${configFile}.new
${csudo}cp ${file_name} ${configDir}/${configFile}.new
else
${csudo}cp ${fileName} ${configDir}/${configFile}
${csudo}cp ${file_name} ${configDir}/${configFile}
fi
fi
${csudo}ln -sf ${configDir}/${configFile} ${install_main_dir}/cfg
}
function install_taosinspect_config() {
file_name="${script_dir}/cfg/inspect.cfg"
if [ -f ${file_name} ]; then
if [ -f "${configDir}/inspect.cfg" ]; then
${csudo}cp ${file_name} ${configDir}/inspect.cfg.new
else
${csudo}cp ${file_name} ${configDir}/inspect.cfg
fi
fi
${csudo}ln -sf ${configDir}/inspect.cfg ${install_main_dir}/cfg
}
function install_config() {
@ -915,6 +930,10 @@ function updateProduct() {
install_adapter_config
install_taosx_config
install_explorer_config
if [ "${verMode}" == "cluster" ]; then
install_taosinspect_config
fi
if [ "${verMode}" != "cloud" ]; then
install_keeper_config
fi
@ -1007,6 +1026,11 @@ function installProduct() {
install_adapter_config
install_taosx_config
install_explorer_config
if [ "${verMode}" == "cluster" ]; then
install_taosinspect_config
fi
if [ "${verMode}" != "cloud" ]; then
install_keeper_config
fi

View File

@ -32,6 +32,8 @@ benchmarkName2="${clientName2}Benchmark"
dumpName2="${clientName2}dump"
demoName2="${clientName2}demo"
uninstallScript2="rm${clientName2}"
inspect_name="${clientName2}inspect"
if [ "$osType" != "Darwin" ]; then
script_dir=$(dirname $(readlink -f "$0"))
@ -106,12 +108,15 @@ function install_main_path() {
function install_bin() {
# Remove links
${csudo}rm -f ${bin_link_dir}/${clientName} || :
${csudo}rm -f ${bin_link_dir}/${clientName} || :
if [ "$osType" != "Darwin" ]; then
${csudo}rm -f ${bin_link_dir}/taosdemo || :
${csudo}rm -f ${bin_link_dir}/${inspect_name} || :
fi
${csudo}rm -f ${bin_link_dir}/${uninstallScript} || :
${csudo}rm -f ${bin_link_dir}/set_core || :
${csudo}rm -f ${bin_link_dir}/${uninstallScript} || :
${csudo}rm -f ${bin_link_dir}/set_core || :
${csudo}rm -f ${bin_link_dir}/${benchmarkName2} || :
${csudo}rm -f ${bin_link_dir}/${dumpName2} || :
${csudo}cp -r ${script_dir}/bin/* ${install_main_dir}/bin && ${csudo}chmod 0555 ${install_main_dir}/bin/*
@ -119,6 +124,7 @@ function install_bin() {
[ -x ${install_main_dir}/bin/${clientName2} ] && ${csudo}ln -s ${install_main_dir}/bin/${clientName2} ${bin_link_dir}/${clientName2} || :
if [ "$osType" != "Darwin" ]; then
[ -x ${install_main_dir}/bin/${demoName2} ] && ${csudo}ln -s ${install_main_dir}/bin/${demoName2} ${bin_link_dir}/${demoName2} || :
[ -x ${install_main_dir}/bin/${inspect_name} ] && ${csudo}ln -s ${install_main_dir}/bin/${inspect_name} ${bin_link_dir}/${inspect_name} || :
fi
[ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/${uninstallScript} || :
[ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
@ -237,16 +243,34 @@ function install_jemalloc() {
}
function install_config() {
if [ ! -f ${cfg_install_dir}/${configFile} ]; then
file_name=${cfg_install_dir}/${configFile}
if [ -f ${file_name} ]; then
echo "The configuration file ${file_name} already exists"
${csudo}cp ${file_name} ${cfg_install_dir}/${configFile}.new
else
${csudo}mkdir -p ${cfg_install_dir}
[ -f ${script_dir}/cfg/${configFile} ] && ${csudo}cp ${script_dir}/cfg/${configFile} ${cfg_install_dir}
${csudo}chmod 644 ${cfg_install_dir}/*
${csudo}ln -s ${cfg_install_dir}/${configFile} ${install_main_dir}/cfg
fi
${csudo}cp -f ${script_dir}/cfg/${configFile} ${install_main_dir}/cfg/${configFile}.org
${csudo}ln -s ${cfg_install_dir}/${configFile} ${install_main_dir}/cfg
}
function install_taosinspect_config() {
file_name="${script_dir}/cfg/inspect.cfg"
if [ -f ${file_name} ]; then
if [ -f "${cfg_install_dir}/inspect.cfg" ]; then
${csudo}cp ${file_name} ${cfg_install_dir}/inspect.cfg.new
else
${csudo}mkdir -p ${cfg_install_dir}
${csudo}cp ${file_name} ${cfg_install_dir}/inspect.cfg
fi
${csudo}ln -sf ${cfg_install_dir}/inspect.cfg ${install_main_dir}/cfg
fi
}
function install_log() {
${csudo}rm -rf ${log_dir} || :
@ -293,6 +317,7 @@ function update_TDengine() {
install_jemalloc
if [ "$verMode" == "cluster" ]; then
install_connector
install_taosinspect_config
fi
install_examples
install_bin
@ -320,6 +345,7 @@ function install_TDengine() {
install_jemalloc
if [ "$verMode" == "cluster" ]; then
install_connector
install_taosinspect_config
fi
install_examples
install_bin

View File

@ -44,6 +44,7 @@ dumpName="${PREFIX}dump"
keeperName="${PREFIX}keeper"
xName="${PREFIX}x"
explorerName="${PREFIX}-explorer"
inspect_name="${PREFIX}inspect"
tarbitratorName="tarbitratord"
productName="TDengine"
@ -58,10 +59,13 @@ config_dir="/etc/${PREFIX}"
if [ "${verMode}" == "cluster" ]; then
services=(${PREFIX}"d" ${PREFIX}"adapter" ${PREFIX}"keeper")
tools=(${PREFIX} ${PREFIX}"Benchmark" ${PREFIX}"dump" ${PREFIX}"demo" ${PREFIX}"inspect" taosudf set_core.sh TDinsight.sh $uninstallScript start-all.sh stop-all.sh)
else
tools=(${PREFIX} ${PREFIX}"Benchmark" ${PREFIX}"dump" ${PREFIX}"demo" taosudf set_core.sh TDinsight.sh $uninstallScript start-all.sh stop-all.sh)
services=(${PREFIX}"d" ${PREFIX}"adapter" ${PREFIX}"keeper" ${PREFIX}"-explorer")
fi
tools=(${PREFIX} ${PREFIX}"Benchmark" ${PREFIX}"dump" ${PREFIX}"demo" taosudf set_core.sh TDinsight.sh $uninstallScript start-all.sh stop-all.sh)
csudo=""
if command -v sudo >/dev/null; then
@ -158,9 +162,9 @@ remove_service_of() {
remove_tools_of() {
_tool=$1
kill_service_of ${_tool}
[ -e "${bin_link_dir}/${_tool}" ] && ${csudo}rm -rf ${bin_link_dir}/${_tool} || :
[ -L "${bin_link_dir}/${_tool}" ] && ${csudo}rm -rf ${bin_link_dir}/${_tool} || :
[ -e "${installDir}/bin/${_tool}" ] && ${csudo}rm -rf ${installDir}/bin/${_tool} || :
[ -e "${local_bin_link_dir}/${_tool}" ] && ${csudo}rm -rf ${local_bin_link_dir}/${_tool} || :
[ -L "${local_bin_link_dir}/${_tool}" ] && ${csudo}rm -rf ${local_bin_link_dir}/${_tool} || :
}
remove_bin() {
@ -232,21 +236,56 @@ function remove_data_and_config() {
[ -d "${log_dir}" ] && ${csudo}rm -rf ${log_dir}
}
echo
echo "Do you want to remove all the data, log and configuration files? [y/n]"
read answer
remove_flag=false
if [ X$answer == X"y" ] || [ X$answer == X"Y" ]; then
confirmMsg="I confirm that I would like to delete all data, log and configuration files"
echo "Please enter '${confirmMsg}' to continue"
function usage() {
echo -e "\nUsage: $(basename $0) [-e <yes|no>]"
echo "-e: silent mode, specify whether to remove all the data, log and configuration files."
echo " yes: remove the data, log, and configuration files."
echo " no: don't remove the data, log, and configuration files."
}
# main
interactive_remove="yes"
remove_flag="false"
while getopts "e:h" opt; do
case $opt in
e)
interactive_remove="no"
if [ "$OPTARG" == "yes" ]; then
remove_flag="true"
echo "Remove all the data, log, and configuration files."
elif [ "$OPTARG" == "no" ]; then
remove_flag="false"
echo "Do not remove the data, log, and configuration files."
else
echo "Invalid option for -e: $OPTARG"
usage
exit 1
fi
;;
h | *)
usage
exit 1
;;
esac
done
if [ "$interactive_remove" == "yes" ]; then
echo -e "\nDo you want to remove all the data, log and configuration files? [y/n]"
read answer
if [ X"$answer" == X"${confirmMsg}" ]; then
remove_flag=true
else
echo "answer doesn't match, skip this step"
if [ X$answer == X"y" ] || [ X$answer == X"Y" ]; then
confirmMsg="I confirm that I would like to delete all data, log and configuration files"
echo "Please enter '${confirmMsg}' to continue"
read answer
if [ X"$answer" == X"${confirmMsg}" ]; then
remove_flag="true"
else
echo "answer doesn't match, skip this step"
fi
fi
echo
fi
echo
if [ -e ${install_main_dir}/uninstall_${PREFIX}x.sh ]; then
if [ X$remove_flag == X"true" ]; then
@ -256,7 +295,6 @@ if [ -e ${install_main_dir}/uninstall_${PREFIX}x.sh ]; then
fi
fi
if [ "$osType" = "Darwin" ]; then
clean_service_on_launchctl
${csudo}rm -rf /Applications/TDengine.app
@ -295,8 +333,7 @@ elif echo $osinfo | grep -qwi "centos"; then
${csudo}rpm -e --noscripts tdengine >/dev/null 2>&1 || :
fi
command -v systemctl >/dev/null 2>&1 && ${csudo}systemctl daemon-reload >/dev/null 2>&1 || true
echo
echo "${productName} is removed successfully!"
echo
echo

View File

@ -7,6 +7,7 @@ set -e
RED='\033[0;31m'
GREEN='\033[1;32m'
NC='\033[0m'
verMode=edge
installDir="/usr/local/taos"
clientName="taos"
@ -18,8 +19,10 @@ productName2="TDengine"
benchmarkName2="${clientName2}Benchmark"
demoName2="${clientName2}demo"
dumpName2="${clientName2}dump"
inspect_name="${clientName2}inspect"
uninstallScript2="rm${clientName2}"
installDir="/usr/local/${clientName2}"
#install main path
@ -52,8 +55,9 @@ function clean_bin() {
${csudo}rm -f ${bin_link_dir}/${demoName2} || :
${csudo}rm -f ${bin_link_dir}/${benchmarkName2} || :
${csudo}rm -f ${bin_link_dir}/${dumpName2} || :
${csudo}rm -f ${bin_link_dir}/${uninstallScript} || :
${csudo}rm -f ${bin_link_dir}/${uninstallScript2} || :
${csudo}rm -f ${bin_link_dir}/set_core || :
[ -L ${bin_link_dir}/${inspect_name} ] && ${csudo}rm -f ${bin_link_dir}/${inspect_name} || :
if [ "$verMode" == "cluster" ] && [ "$clientName" != "$clientName2" ]; then
${csudo}rm -f ${bin_link_dir}/${clientName2} || :
@ -61,6 +65,7 @@ function clean_bin() {
${csudo}rm -f ${bin_link_dir}/${benchmarkName2} || :
${csudo}rm -f ${bin_link_dir}/${dumpName2} || :
${csudo}rm -f ${bin_link_dir}/${uninstallScript2} || :
[ -L ${bin_link_dir}/${inspect_name} ] && ${csudo}rm -f ${bin_link_dir}/${inspect_name} || :
fi
}

View File

@ -313,7 +313,7 @@ typedef struct SSyncQueryParam {
void* doAsyncFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4);
void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4);
void doSetOneRowPtr(SReqResultInfo* pResultInfo, bool isStmt);
void doSetOneRowPtr(SReqResultInfo* pResultInfo);
void setResPrecision(SReqResultInfo* pResInfo, int32_t precision);
int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* pRsp, bool convertUcs4, bool isStmt);
int32_t setResultDataPtr(SReqResultInfo* pResultInfo, bool convertUcs4, bool isStmt);

View File

@ -93,7 +93,7 @@ static int32_t registerRequest(SRequestObj *pRequest, STscObj *pTscObj) {
int32_t total = atomic_add_fetch_64((int64_t *)&pSummary->totalRequests, 1);
int32_t currentInst = atomic_add_fetch_64((int64_t *)&pSummary->currentRequests, 1);
tscDebug("req:0x%" PRIx64 ", new from connObj:0x%" PRIx64 ", current:%d, app current:%d, total:%d, QID:0x%" PRIx64,
tscDebug("req:0x%" PRIx64 ", create request from conn:0x%" PRIx64 ", current:%d, app current:%d, total:%d, QID:0x%" PRIx64,
pRequest->self, pRequest->pTscObj->id, num, currentInst, total, pRequest->requestId);
}
@ -254,7 +254,7 @@ static void deregisterRequest(SRequestObj *pRequest) {
int32_t reqType = SLOW_LOG_TYPE_OTHERS;
int64_t duration = taosGetTimestampUs() - pRequest->metric.start;
tscDebug("req:0x%" PRIx64 ", free from connObj:0x%" PRIx64 ", QID:0x%" PRIx64
tscDebug("req:0x%" PRIx64 ", free from conn:0x%" PRIx64 ", QID:0x%" PRIx64
", elapsed:%.2f ms, current:%d, app current:%d",
pRequest->self, pTscObj->id, pRequest->requestId, duration / 1000.0, num, currentInst);
@ -263,16 +263,18 @@ static void deregisterRequest(SRequestObj *pRequest) {
(0 == ((SVnodeModifyOpStmt *)pRequest->pQuery->pRoot)->sqlNodeType)) ||
QUERY_NODE_VNODE_MODIFY_STMT == pRequest->stmtType) {
tscDebug("req:0x%" PRIx64 ", insert duration:%" PRId64 "us, parseCost:%" PRId64 "us, ctgCost:%" PRId64
"us, analyseCost:%" PRId64 "us, planCost:%" PRId64 "us, exec:%" PRId64 "us",
"us, analyseCost:%" PRId64 "us, planCost:%" PRId64 "us, exec:%" PRId64 "us, QID:0x%" PRIx64,
pRequest->self, duration, pRequest->metric.parseCostUs, pRequest->metric.ctgCostUs,
pRequest->metric.analyseCostUs, pRequest->metric.planCostUs, pRequest->metric.execCostUs);
pRequest->metric.analyseCostUs, pRequest->metric.planCostUs, pRequest->metric.execCostUs,
pRequest->requestId);
(void)atomic_add_fetch_64((int64_t *)&pActivity->insertElapsedTime, duration);
reqType = SLOW_LOG_TYPE_INSERT;
} else if (QUERY_NODE_SELECT_STMT == pRequest->stmtType) {
tscDebug("req:0x%" PRIx64 ", query duration:%" PRId64 "us, parseCost:%" PRId64 "us, ctgCost:%" PRId64
"us, analyseCost:%" PRId64 "us, planCost:%" PRId64 "us, exec:%" PRId64 "us",
"us, analyseCost:%" PRId64 "us, planCost:%" PRId64 "us, exec:%" PRId64 "us, QID:0x%" PRIx64,
pRequest->self, duration, pRequest->metric.parseCostUs, pRequest->metric.ctgCostUs,
pRequest->metric.analyseCostUs, pRequest->metric.planCostUs, pRequest->metric.execCostUs);
pRequest->metric.analyseCostUs, pRequest->metric.planCostUs, pRequest->metric.execCostUs,
pRequest->requestId);
(void)atomic_add_fetch_64((int64_t *)&pActivity->queryElapsedTime, duration);
reqType = SLOW_LOG_TYPE_QUERY;
@ -460,7 +462,7 @@ void destroyTscObj(void *pObj) {
STscObj *pTscObj = pObj;
int64_t tscId = pTscObj->id;
tscTrace("connObj:%" PRIx64 ", begin destroy, p:%p", tscId, pTscObj);
tscTrace("conn:%" PRIx64 ", begin destroy, p:%p", tscId, pTscObj);
SClientHbKey connKey = {.tscRid = pTscObj->id, .connType = pTscObj->connType};
hbDeregisterConn(pTscObj, connKey);
@ -469,7 +471,7 @@ void destroyTscObj(void *pObj) {
taosHashCleanup(pTscObj->pRequests);
schedulerStopQueryHb(pTscObj->pAppInfo->pTransporter);
tscDebug("connObj:0x%" PRIx64 ", p:%p destroyed, remain inst totalConn:%" PRId64, pTscObj->id, pTscObj,
tscDebug("conn:0x%" PRIx64 ", p:%p destroyed, remain inst totalConn:%" PRId64, pTscObj->id, pTscObj,
pTscObj->pAppInfo->numOfConns);
// In any cases, we should not free app inst here. Or an race condition rises.
@ -478,7 +480,7 @@ void destroyTscObj(void *pObj) {
(void)taosThreadMutexDestroy(&pTscObj->mutex);
taosMemoryFree(pTscObj);
tscTrace("connObj:0x%" PRIx64 ", end destroy, p:%p", tscId, pTscObj);
tscTrace("conn:0x%" PRIx64 ", end destroy, p:%p", tscId, pTscObj);
}
int32_t createTscObj(const char *user, const char *auth, const char *db, int32_t connType, SAppInstInfo *pAppInfo,
@ -518,7 +520,7 @@ int32_t createTscObj(const char *user, const char *auth, const char *db, int32_t
(void)atomic_add_fetch_64(&(*pObj)->pAppInfo->numOfConns, 1);
tscInfo("connObj:0x%" PRIx64 ", created, p:%p", (*pObj)->id, *pObj);
tscInfo("conn:0x%" PRIx64 ", created, p:%p", (*pObj)->id, *pObj);
return code;
}
@ -684,7 +686,7 @@ void doDestroyRequest(void *p) {
SRequestObj *pRequest = (SRequestObj *)p;
uint64_t reqId = pRequest->requestId;
tscDebug("QID:0x%" PRIx64 ", begin destroy request, res:%p", reqId, pRequest);
tscTrace("QID:0x%" PRIx64 ", begin destroy request, res:%p", reqId, pRequest);
int64_t nextReqRefId = pRequest->relation.nextRefId;
@ -726,7 +728,7 @@ void doDestroyRequest(void *p) {
taosMemoryFreeClear(pRequest->effectiveUser);
taosMemoryFreeClear(pRequest->sqlstr);
taosMemoryFree(pRequest);
tscDebug("QID:0x%" PRIx64 ", end destroy request, res:%p", reqId, pRequest);
tscTrace("QID:0x%" PRIx64 ", end destroy request, res:%p", reqId, pRequest);
destroyNextReq(nextReqRefId);
}

View File

@ -121,7 +121,7 @@ static int32_t hbUpdateUserAuthInfo(SAppHbMgr *pAppHbMgr, SUserAuthBatchRsp *bat
pTscObj->authVer = pRsp->version;
if (pTscObj->sysInfo != pRsp->sysInfo) {
tscDebug("update sysInfo of user %s from %" PRIi8 " to %" PRIi8 ", connObj:%" PRIi64, pRsp->user,
tscDebug("update sysInfo of user %s from %" PRIi8 " to %" PRIi8 ", conn:%" PRIi64, pRsp->user,
pTscObj->sysInfo, pRsp->sysInfo, pTscObj->id);
pTscObj->sysInfo = pRsp->sysInfo;
}
@ -134,7 +134,7 @@ static int32_t hbUpdateUserAuthInfo(SAppHbMgr *pAppHbMgr, SUserAuthBatchRsp *bat
if (passInfo->fp) {
(*passInfo->fp)(passInfo->param, &pRsp->passVer, TAOS_NOTIFY_PASSVER);
}
tscDebug("update passVer of user %s from %d to %d, connObj:%" PRIi64, pRsp->user, oldVer,
tscDebug("update passVer of user %s from %d to %d, conn:%" PRIi64, pRsp->user, oldVer,
atomic_load_32(&passInfo->ver), pTscObj->id);
}
}
@ -147,7 +147,7 @@ static int32_t hbUpdateUserAuthInfo(SAppHbMgr *pAppHbMgr, SUserAuthBatchRsp *bat
if (whiteListInfo->fp) {
(*whiteListInfo->fp)(whiteListInfo->param, &pRsp->whiteListVer, TAOS_NOTIFY_WHITELIST_VER);
}
tscDebug("update whitelist version of user %s from %" PRId64 " to %" PRId64 ", connObj:%" PRIi64, pRsp->user,
tscDebug("update whitelist version of user %s from %" PRId64 " to %" PRId64 ", conn:%" PRIi64, pRsp->user,
oldVer, atomic_load_64(&whiteListInfo->ver), pTscObj->id);
}
} else {
@ -156,7 +156,7 @@ static int32_t hbUpdateUserAuthInfo(SAppHbMgr *pAppHbMgr, SUserAuthBatchRsp *bat
SWhiteListInfo *whiteListInfo = &pTscObj->whiteListInfo;
int64_t oldVer = atomic_load_64(&whiteListInfo->ver);
atomic_store_64(&whiteListInfo->ver, pRsp->whiteListVer);
tscDebug("update whitelist version of user %s from %" PRId64 " to %" PRId64 ", connObj:%" PRIi64, pRsp->user,
tscDebug("update whitelist version of user %s from %" PRId64 " to %" PRId64 ", conn:%" PRIi64, pRsp->user,
oldVer, atomic_load_64(&whiteListInfo->ver), pTscObj->id);
}
releaseTscObj(pReq->connKey.tscRid);
@ -516,7 +516,7 @@ static int32_t hbQueryHbRspHandle(SAppHbMgr *pAppHbMgr, SClientHbRsp *pRsp) {
pTscObj->pAppInfo->totalDnodes);
if (pRsp->query->killRid) {
tscDebug("QID:%" PRIx64 ", need to be killed now", pRsp->query->killRid);
tscDebug("QID:0x%" PRIx64 ", need to be killed now", pRsp->query->killRid);
SRequestObj *pRequest = acquireRequest(pRsp->query->killRid);
if (NULL == pRequest) {
tscDebug("QID:0x%" PRIx64 ", not exist to kill", pRsp->query->killRid);
@ -885,7 +885,7 @@ int32_t hbGetExpiredDBInfo(SClientHbKey *connKey, struct SCatalog *pCatalog, SCl
for (int32_t i = 0; i < dbNum; ++i) {
SDbCacheInfo *db = &dbs[i];
tscDebug("the %dth expired dbFName:%s, dbId:%" PRId64
tscDebug("the %dth expired db:%s, dbId:%" PRId64
", vgVersion:%d, cfgVersion:%d, numOfTable:%d, startTs:%" PRId64,
i, db->dbFName, db->dbId, db->vgVersion, db->cfgVersion, db->numOfTable, db->stateTs);

View File

@ -247,7 +247,7 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param,
int32_t err = taosHashPut(pTscObj->pRequests, &(*pRequest)->self, sizeof((*pRequest)->self), &(*pRequest)->self,
sizeof((*pRequest)->self));
if (err) {
tscError("req:0x%" PRId64 ", failed to add to request container, QID:0x%" PRIx64 ", connObj:%" PRId64 ", %s",
tscError("req:0x%" PRId64 ", failed to add to request container, QID:0x%" PRIx64 ", conn:%" PRId64 ", %s",
(*pRequest)->self, (*pRequest)->requestId, pTscObj->id, sql);
destroyRequest(*pRequest);
*pRequest = NULL;
@ -258,7 +258,7 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param,
if (tsQueryUseNodeAllocator && !qIsInsertValuesSql((*pRequest)->sqlstr, (*pRequest)->sqlLen)) {
if (TSDB_CODE_SUCCESS !=
nodesCreateAllocator((*pRequest)->requestId, tsQueryNodeChunkSize, &((*pRequest)->allocatorRefId))) {
tscError("req:0x%" PRId64 ", failed to create node allocator, QID:0x%" PRIx64 ", connObj:%" PRId64 ", %s", (*pRequest)->self,
tscError("req:0x%" PRId64 ", failed to create node allocator, QID:0x%" PRIx64 ", conn:%" PRId64 ", %s", (*pRequest)->self,
(*pRequest)->requestId, pTscObj->id, sql);
destroyRequest(*pRequest);
*pRequest = NULL;
@ -266,7 +266,7 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param,
}
}
tscDebugL("req:0x%" PRIx64 ", QID:0x%" PRIx64 ", build request", (*pRequest)->self, (*pRequest)->requestId);
tscDebugL("req:0x%" PRIx64 ", build request, QID:0x%" PRIx64, (*pRequest)->self, (*pRequest)->requestId);
return TSDB_CODE_SUCCESS;
}
@ -1658,7 +1658,7 @@ int32_t taosConnectImpl(const char* user, const char* auth, const char* db, __ta
*pTscObj = NULL;
return terrno;
} else {
tscInfo("connObj:0x%" PRIx64 ", connection is opening, connId:%u, dnodeConn:%p, QID:0x%" PRIx64, (*pTscObj)->id,
tscInfo("conn:0x%" PRIx64 ", connection is opening, connId:%u, dnodeConn:%p, QID:0x%" PRIx64, (*pTscObj)->id,
(*pTscObj)->connId, (*pTscObj)->pAppInfo->pTransporter, pRequest->requestId);
destroyRequest(pRequest);
}
@ -1941,12 +1941,12 @@ TAOS* taos_connect_auth(const char* ip, const char* user, const char* auth, cons
// return taos_connect(ipStr, userStr, passStr, dbStr, port);
// }
void doSetOneRowPtr(SReqResultInfo* pResultInfo, bool isStmt) {
void doSetOneRowPtr(SReqResultInfo* pResultInfo) {
for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
SResultColumn* pCol = &pResultInfo->pCol[i];
int32_t type = pResultInfo->fields[i].type;
int32_t schemaBytes = calcSchemaBytesFromTypeBytes(type, pResultInfo->fields[i].bytes, isStmt);
int32_t schemaBytes = calcSchemaBytesFromTypeBytes(type, pResultInfo->userFields[i].bytes, false);
if (IS_VAR_DATA_TYPE(type)) {
if (!IS_VAR_NULL_TYPE(type, schemaBytes) && pCol->offset[pResultInfo->current] != -1) {
@ -2012,7 +2012,7 @@ void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4)
}
if (setupOneRowPtr) {
doSetOneRowPtr(pResultInfo, pRequest->isStmtBind);
doSetOneRowPtr(pResultInfo);
pResultInfo->current += 1;
}
@ -2059,7 +2059,7 @@ void* doAsyncFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertU
return NULL;
} else {
if (setupOneRowPtr) {
doSetOneRowPtr(pResultInfo, pRequest->isStmtBind);
doSetOneRowPtr(pResultInfo);
pResultInfo->current += 1;
}
@ -2135,8 +2135,9 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t* colLength, bo
static int32_t convertDecimalType(SReqResultInfo* pResultInfo) {
for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
TAOS_FIELD_E* pField = pResultInfo->fields + i;
int32_t type = pField->type;
TAOS_FIELD_E* pFieldE = pResultInfo->fields + i;
TAOS_FIELD* pField = pResultInfo->userFields + i;
int32_t type = pFieldE->type;
int32_t bufLen = 0;
char* p = NULL;
if (!IS_DECIMAL_TYPE(type) || !pResultInfo->pCol[i].pData) {
@ -2144,6 +2145,7 @@ static int32_t convertDecimalType(SReqResultInfo* pResultInfo) {
} else {
bufLen = 64;
p = taosMemoryRealloc(pResultInfo->convertBuf[i], bufLen * pResultInfo->numOfRows);
pFieldE->bytes = bufLen;
pField->bytes = bufLen;
}
if (!p) return terrno;
@ -2151,7 +2153,7 @@ static int32_t convertDecimalType(SReqResultInfo* pResultInfo) {
for (int32_t j = 0; j < pResultInfo->numOfRows; ++j) {
int32_t code = decimalToStr((DecimalWord*)(pResultInfo->pCol[i].pData + j * tDataTypes[type].bytes), type,
pField->precision, pField->scale, p, bufLen);
pFieldE->precision, pFieldE->scale, p, bufLen);
p += bufLen;
if (TSDB_CODE_SUCCESS != code) {
return code;
@ -2395,6 +2397,7 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo) {
}
int32_t setResultDataPtr(SReqResultInfo* pResultInfo, bool convertUcs4, bool isStmt) {
bool convertForDecimal = convertUcs4;
if (pResultInfo == NULL || pResultInfo->numOfCols <= 0 || pResultInfo->fields == NULL) {
tscError("setResultDataPtr paras error");
return TSDB_CODE_TSC_INTERNAL_ERROR;
@ -2507,7 +2510,7 @@ int32_t setResultDataPtr(SReqResultInfo* pResultInfo, bool convertUcs4, bool isS
code = doConvertUCS4(pResultInfo, colLength, isStmt);
}
#endif
if (TSDB_CODE_SUCCESS == code && convertUcs4) {
if (TSDB_CODE_SUCCESS == code && convertForDecimal) {
code = convertDecimalType(pResultInfo);
}
return code;
@ -2990,7 +2993,7 @@ TAOS_RES* taosQueryImpl(TAOS* taos, const char* sql, bool validateOnly, int8_t s
return NULL;
}
tscDebug("connObj:0x%" PRIx64 ", taos_query start with sql:%s", *(int64_t*)taos, sql);
tscDebug("conn:0x%" PRIx64 ", taos_query execute sql:%s", *(int64_t*)taos, sql);
SSyncQueryParam* param = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
if (NULL == param) {
@ -3021,7 +3024,8 @@ TAOS_RES* taosQueryImpl(TAOS* taos, const char* sql, bool validateOnly, int8_t s
}
taosMemoryFree(param);
tscDebug("connObj:0x%" PRIx64 ", res:%p created, taos_query end", *(int64_t*)taos, pRequest);
tscDebug("QID:0x%" PRIx64 ", taos_query end, conn:0x%" PRIx64 " res:%p", pRequest ? pRequest->requestId : 0,
*(int64_t*)taos, pRequest);
return pRequest;
}

View File

@ -487,10 +487,10 @@ void taos_close_internal(void *taos) {
}
STscObj *pTscObj = (STscObj *)taos;
tscDebug("connObj:0x%" PRIx64 ", try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
tscDebug("conn:0x%" PRIx64 ", try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
if (TSDB_CODE_SUCCESS != taosRemoveRef(clientConnRefPool, pTscObj->id)) {
tscError("connObj:0x%" PRIx64 ", failed to remove ref from conn pool", pTscObj->id);
tscError("conn:0x%" PRIx64 ", failed to remove ref from conn pool", pTscObj->id);
}
}
@ -548,7 +548,7 @@ void taos_free_result(TAOS_RES *res) {
if (TD_RES_QUERY(res)) {
SRequestObj *pRequest = (SRequestObj *)res;
tscDebug("QID:0x%" PRIx64 ", call taos_free_result to free query", pRequest->requestId);
tscDebug("QID:0x%" PRIx64 ", call taos_free_result to free query, res:%p", pRequest->requestId, res);
destroyRequest(pRequest);
return;
}
@ -647,7 +647,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
}
if (pResultInfo->current < pResultInfo->numOfRows) {
doSetOneRowPtr(pResultInfo, false);
doSetOneRowPtr(pResultInfo);
pResultInfo->current += 1;
return pResultInfo->row;
} else {
@ -655,7 +655,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
return NULL;
}
doSetOneRowPtr(pResultInfo, false);
doSetOneRowPtr(pResultInfo);
pResultInfo->current += 1;
return pResultInfo->row;
}
@ -1360,7 +1360,7 @@ static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t c
SQuery *pQuery = pRequest->pQuery;
pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
qDebug("req:0x%" PRIx64 ", start to continue parse, QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
qDebug("req:0x%" PRIx64 ", continue parse query, QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
tstrerror(code));
if (code == TSDB_CODE_SUCCESS) {

View File

@ -361,7 +361,7 @@ void monitorCounterInc(int64_t clusterId, const char* counterName, const char**
tscError("clusterId:0x%" PRIx64 ", monitor:%p counter:%s inc failed", clusterId, pMonitor, counterName);
goto end;
}
tscDebug("clusterId:0x%" PRIx64 ", monitor:%p, counter:%s inc", pMonitor->clusterId, pMonitor, counterName);
tscTrace("clusterId:0x%" PRIx64 ", monitor:%p, counter:%s inc", pMonitor->clusterId, pMonitor, counterName);
end:
taosWUnLockLatch(&monitorLock);

View File

@ -123,7 +123,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
}
for (int32_t i = 0; i < connectRsp.epSet.numOfEps; ++i) {
tscDebug("QID:0x%" PRIx64 ", epSet.fqdn[%d]:%s port:%d, connObj:0x%" PRIx64, pRequest->requestId, i,
tscDebug("QID:0x%" PRIx64 ", epSet.fqdn[%d]:%s port:%d, conn:0x%" PRIx64, pRequest->requestId, i,
connectRsp.epSet.eps[i].fqdn, connectRsp.epSet.eps[i].port, pTscObj->id);
}
@ -956,7 +956,9 @@ int32_t processCreateStreamFirstPhaseRsp(void* param, SDataBuf* pMsg, int32_t co
taosMemoryFree(pMsg->pData);
taosMemoryFree(pMsg->pEpSet);
if (code == 0 && !pRequest->streamRunHistory && tsStreamRunHistoryAsync){
if (code == 0 && !pRequest->streamRunHistory &&
((SCreateStreamStmt*)(pRequest->pQuery->pRoot))->pOptions->fillHistory &&
((SCreateStreamStmt*)(pRequest->pQuery->pRoot))->pOptions->runHistoryAsync){
processCreateStreamSecondPhase(pRequest);
}

View File

@ -1631,20 +1631,20 @@ int stmtClose(TAOS_STMT* stmt) {
STMT_DLOG_E("start to free stmt");
pStmt->queue.stopQueue = true;
(void)taosThreadMutexLock(&pStmt->queue.mutex);
(void)atomic_add_fetch_64(&pStmt->queue.qRemainNum, 1);
(void)taosThreadCondSignal(&(pStmt->queue.waitCond));
(void)taosThreadMutexUnlock(&pStmt->queue.mutex);
if (pStmt->bindThreadInUse) {
pStmt->queue.stopQueue = true;
(void)taosThreadMutexLock(&pStmt->queue.mutex);
(void)atomic_add_fetch_64(&pStmt->queue.qRemainNum, 1);
(void)taosThreadCondSignal(&(pStmt->queue.waitCond));
(void)taosThreadMutexUnlock(&pStmt->queue.mutex);
(void)taosThreadJoin(pStmt->bindThread, NULL);
pStmt->bindThreadInUse = false;
}
(void)taosThreadCondDestroy(&pStmt->queue.waitCond);
(void)taosThreadMutexDestroy(&pStmt->queue.mutex);
(void)taosThreadCondDestroy(&pStmt->queue.waitCond);
(void)taosThreadMutexDestroy(&pStmt->queue.mutex);
}
STMT_DLOG("stmt %p closed, stbInterlaceMode:%d, statInfo: ctgGetTbMetaNum=>%" PRId64 ", getCacheTbInfo=>%" PRId64
", parseSqlNum=>%" PRId64 ", pStmt->stat.bindDataNum=>%" PRId64

View File

@ -889,6 +889,9 @@ static int stmtSetDbName2(TAOS_STMT2* stmt, const char* dbName) {
if (pStmt->exec.pRequest->pDb == NULL) {
return terrno;
}
if (pStmt->sql.stbInterlaceMode) {
pStmt->sql.siInfo.dbname = pStmt->db;
}
return TSDB_CODE_SUCCESS;
}
@ -1928,16 +1931,19 @@ int stmtClose2(TAOS_STMT2* stmt) {
STMT_DLOG_E("start to free stmt");
pStmt->queue.stopQueue = true;
(void)taosThreadMutexLock(&pStmt->queue.mutex);
(void)atomic_add_fetch_64(&pStmt->queue.qRemainNum, 1);
(void)taosThreadCondSignal(&(pStmt->queue.waitCond));
(void)taosThreadMutexUnlock(&pStmt->queue.mutex);
if (pStmt->bindThreadInUse) {
pStmt->queue.stopQueue = true;
(void)taosThreadMutexLock(&pStmt->queue.mutex);
(void)atomic_add_fetch_64(&pStmt->queue.qRemainNum, 1);
(void)taosThreadCondSignal(&(pStmt->queue.waitCond));
(void)taosThreadMutexUnlock(&pStmt->queue.mutex);
(void)taosThreadJoin(pStmt->bindThread, NULL);
pStmt->bindThreadInUse = false;
(void)taosThreadCondDestroy(&pStmt->queue.waitCond);
(void)taosThreadMutexDestroy(&pStmt->queue.mutex);
}
TSC_ERR_RET(taosThreadMutexLock(&pStmt->asyncBindParam.mutex));
@ -1946,9 +1952,6 @@ int stmtClose2(TAOS_STMT2* stmt) {
}
TSC_ERR_RET(taosThreadMutexUnlock(&pStmt->asyncBindParam.mutex));
(void)taosThreadCondDestroy(&pStmt->queue.waitCond);
(void)taosThreadMutexDestroy(&pStmt->queue.mutex);
(void)taosThreadCondDestroy(&pStmt->asyncBindParam.waitCond);
(void)taosThreadMutexDestroy(&pStmt->asyncBindParam.mutex);

View File

@ -1167,6 +1167,7 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
}
// TD-33419
// TD-34075
TEST(stmt2Case, stmt2_insert_db) {
TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
ASSERT_NE(taos, nullptr);
@ -1177,7 +1178,7 @@ TEST(stmt2Case, stmt2_insert_db) {
"INSERT INTO `stmt2_testdb_12`.`stb1` (ts,int_tag,tbname) VALUES "
"(1591060627000,1,'tb1')(1591060627000,2,'tb2')");
TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
ASSERT_NE(stmt, nullptr);

View File

@ -822,6 +822,7 @@ _exit:
return code;
}
// todo: serialized term attributes.
int32_t tDecodeRestoreCheckpointInfo(SDecoder* pDecoder, SRestoreCheckpointInfo* pReq) {
int32_t code = 0;
int32_t lino;

View File

@ -6676,6 +6676,8 @@ int32_t tSerializeSMDropTopicReq(void *buf, int32_t bufLen, SMDropTopicReq *pReq
TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pReq->name));
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->igNotExists));
ENCODESQL();
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->force));
tEndEncode(&encoder);
_exit:
@ -6699,6 +6701,9 @@ int32_t tDeserializeSMDropTopicReq(void *buf, int32_t bufLen, SMDropTopicReq *pR
TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, pReq->name));
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->igNotExists));
DECODESQL();
if (!tDecodeIsEnd(&decoder)) {
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->force));
}
tEndDecode(&decoder);
_exit:
@ -6719,6 +6724,7 @@ int32_t tSerializeSMDropCgroupReq(void *buf, int32_t bufLen, SMDropCgroupReq *pR
TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pReq->topic));
TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pReq->cgroup));
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->igNotExists));
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->force));
tEndEncode(&encoder);
_exit:
@ -6741,6 +6747,9 @@ int32_t tDeserializeSMDropCgroupReq(void *buf, int32_t bufLen, SMDropCgroupReq *
TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, pReq->topic));
TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, pReq->cgroup));
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->igNotExists));
if (!tDecodeIsEnd(&decoder)) {
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->force));
}
tEndDecode(&decoder);
_exit:
@ -9477,10 +9486,11 @@ int32_t tDeserializeSOperatorParam(SDecoder *pDecoder, SOperatorParam *pOpParam)
TAOS_CHECK_RETURN(tDecodeI32(pDecoder, &pOpParam->downstreamIdx));
switch (pOpParam->opType) {
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {
STableScanOperatorParam *pScan = taosMemoryMalloc(sizeof(STableScanOperatorParam));
if (NULL == pScan) {
pOpParam->value = taosMemoryMalloc(sizeof(STableScanOperatorParam));
if (NULL == pOpParam->value) {
TAOS_CHECK_RETURN(terrno);
}
STableScanOperatorParam *pScan = pOpParam->value;
TAOS_CHECK_RETURN(tDecodeI8(pDecoder, (int8_t *)&pScan->tableSeq));
int32_t uidNum = 0;
int64_t uid = 0;
@ -9526,8 +9536,6 @@ int32_t tDeserializeSOperatorParam(SDecoder *pDecoder, SOperatorParam *pOpParam)
}
TAOS_CHECK_RETURN(tDecodeI64(pDecoder, &pScan->window.skey));
TAOS_CHECK_RETURN(tDecodeI64(pDecoder, &pScan->window.ekey));
pOpParam->value = pScan;
break;
}
default:

View File

@ -559,10 +559,10 @@ static int32_t taosAnalyJsonBufWriteColData(SAnalyticBuf *pBuf, int32_t colIndex
break;
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP:
bufLen += tsnprintf(buf + bufLen, sizeof(buf) - bufLen, "%" PRId64 "", *(int64_t *)colValue);
bufLen += tsnprintf(buf + bufLen, sizeof(buf) - bufLen, "%" PRId64, *(int64_t *)colValue);
break;
case TSDB_DATA_TYPE_UBIGINT:
bufLen += tsnprintf(buf + bufLen, sizeof(buf) - bufLen, "%" PRIu64 "", *(uint64_t *)colValue);
bufLen += tsnprintf(buf + bufLen, sizeof(buf) - bufLen, "%" PRIu64, *(uint64_t *)colValue);
break;
case TSDB_DATA_TYPE_FLOAT:
bufLen += tsnprintf(buf + bufLen, sizeof(buf) - bufLen, "%f", GET_FLOAT_VAL(colValue));

View File

@ -3045,31 +3045,18 @@ _end:
}
// Construct the child table name in the form of <ctbName>_<stbName>_<groupId> and store it in `ctbName`.
// If the name length exceeds TSDB_TABLE_NAME_LEN, first convert <stbName>_<groupId> to an MD5 value and then
// concatenate. If the length is still too long, convert <ctbName> to an MD5 value as well.
int32_t buildCtbNameAddGroupId(const char* stbName, char* ctbName, uint64_t groupId, size_t cap) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
char tmp[TSDB_TABLE_NAME_LEN] = {0};
char* suffix = tmp;
size_t suffixCap = sizeof(tmp);
size_t suffixLen = 0;
size_t prefixLen = 0;
T_MD5_CTX context;
if (ctbName == NULL || cap < TSDB_TABLE_NAME_LEN) {
code = TSDB_CODE_INTERNAL_ERROR;
TSDB_CHECK_CODE(code, lino, _end);
}
prefixLen = strlen(ctbName);
if (stbName == NULL) {
suffixLen = snprintf(suffix, suffixCap, "%" PRIu64, groupId);
if (suffixLen >= suffixCap) {
code = TSDB_CODE_INTERNAL_ERROR;
TSDB_CHECK_CODE(code, lino, _end);
}
snprintf(tmp, TSDB_TABLE_NAME_LEN, "_%"PRIu64, groupId);
} else {
int32_t i = strlen(stbName) - 1;
for (; i >= 0; i--) {
@ -3077,52 +3064,12 @@ int32_t buildCtbNameAddGroupId(const char* stbName, char* ctbName, uint64_t grou
break;
}
}
suffixLen = snprintf(suffix, suffixCap, "%s_%" PRIu64, stbName + i + 1, groupId);
if (suffixLen >= suffixCap) {
suffixCap = suffixLen + 1;
suffix = taosMemoryMalloc(suffixCap);
TSDB_CHECK_NULL(suffix, code, lino, _end, TSDB_CODE_OUT_OF_MEMORY);
suffixLen = snprintf(suffix, suffixCap, "%s_%" PRIu64, stbName + i + 1, groupId);
if (suffixLen >= suffixCap) {
code = TSDB_CODE_INTERNAL_ERROR;
TSDB_CHECK_CODE(code, lino, _end);
}
}
snprintf(tmp, TSDB_TABLE_NAME_LEN, "_%s_%" PRIu64, stbName + i + 1, groupId);
}
if (prefixLen + suffixLen + 1 >= TSDB_TABLE_NAME_LEN) {
// If the name length exceeeds the limit, convert the suffix to MD5 value.
tMD5Init(&context);
tMD5Update(&context, (uint8_t*)suffix, suffixLen);
tMD5Final(&context);
suffixLen = snprintf(suffix, suffixCap, "%016" PRIx64 "%016" PRIx64, *(uint64_t*)context.digest,
*(uint64_t*)(context.digest + 8));
if (suffixLen >= suffixCap) {
code = TSDB_CODE_INTERNAL_ERROR;
TSDB_CHECK_CODE(code, lino, _end);
}
}
if (prefixLen + suffixLen + 1 >= TSDB_TABLE_NAME_LEN) {
// If the name is still too long, convert the ctbName to MD5 value.
tMD5Init(&context);
tMD5Update(&context, (uint8_t*)ctbName, prefixLen);
tMD5Final(&context);
prefixLen = snprintf(ctbName, cap, "t_%016" PRIx64 "%016" PRIx64, *(uint64_t*)context.digest,
*(uint64_t*)(context.digest + 8));
if (prefixLen >= cap) {
code = TSDB_CODE_INTERNAL_ERROR;
TSDB_CHECK_CODE(code, lino, _end);
}
}
if (prefixLen + suffixLen + 1 >= TSDB_TABLE_NAME_LEN) {
code = TSDB_CODE_INTERNAL_ERROR;
TSDB_CHECK_CODE(code, lino, _end);
}
ctbName[prefixLen] = '_';
tstrncpy(&ctbName[prefixLen + 1], suffix, cap - prefixLen - 1);
ctbName[cap - strlen(tmp) - 1] = 0; // put stbname + groupId to the end
size_t prefixLen = strlen(ctbName);
ctbName = strncat(ctbName, tmp, cap - prefixLen - 1);
for (char* p = ctbName; *p; ++p) {
if (*p == '.') *p = '_';
@ -3132,9 +3079,6 @@ _end:
if (code != TSDB_CODE_SUCCESS) {
uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
if (suffix != tmp) {
taosMemoryFree(suffix);
}
return code;
}

View File

@ -3295,6 +3295,10 @@ int32_t tRowBuildFromBind2(SBindInfo2 *infos, int32_t numOfInfos, bool infoSorte
for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
if (infos[iInfo].bind->is_null[iRow] == 1) {
if(iInfo == 0) {
code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
goto _exit;
}
colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
} else {
colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);

View File

@ -351,7 +351,6 @@ int64_t tsStreamFailedTimeout = 30 * 60 * 1000;
bool tsFilterScalarMode = false;
int tsStreamAggCnt = 100000;
bool tsStreamCoverage = false;
bool tsStreamRunHistoryAsync = false;
char tsAdapterFqdn[TSDB_FQDN_LEN] = "localhost";
uint16_t tsAdapterPort = 6041;
@ -784,9 +783,6 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
TAOS_CHECK_RETURN(cfgAddBool(pCfg, "compareAsStrInGreatest", tsCompareAsStrInGreatest, CFG_SCOPE_CLIENT, CFG_DYN_CLIENT,CFG_CATEGORY_LOCAL));
TAOS_CHECK_RETURN(
cfgAddBool(pCfg, "streamRunHistoryAsync", tsStreamRunHistoryAsync, CFG_DYN_CLIENT, CFG_DYN_CLIENT, CFG_CATEGORY_LOCAL));
TAOS_RETURN(TSDB_CODE_SUCCESS);
}
@ -1529,9 +1525,6 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "streamCoverage");
tsStreamCoverage = pItem->bval;
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "streamRunHistoryAsync");
tsStreamRunHistoryAsync = pItem->bval;
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "compareAsStrInGreatest");
tsCompareAsStrInGreatest = pItem->bval;
@ -2873,7 +2866,6 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
{"numOfRpcSessions", &tsNumOfRpcSessions},
{"bypassFlag", &tsBypassFlag},
{"safetyCheckLevel", &tsSafetyCheckLevel},
{"streamRunHistoryAsync", &tsStreamRunHistoryAsync},
{"streamCoverage", &tsStreamCoverage},
{"compareAsStrInGreatest", &tsCompareAsStrInGreatest}};

View File

@ -16,7 +16,6 @@
#define _DEFAULT_SOURCE
#include "tname.h"
#include "tcommon.h"
#include "tstrbuild.h"
#define VALID_NAME_TYPE(x) ((x) == TSDB_DB_NAME_T || (x) == TSDB_TABLE_NAME_T)
@ -105,6 +104,14 @@ const char* tNameGetTableName(const SName* name) {
return &name->tname[0];
}
int32_t tNameGetFullTableName(const SName* name, char* dst) {
if (name == NULL || dst == NULL) {
return TSDB_CODE_INVALID_PARA;
}
(void)snprintf(dst, TSDB_TABLE_FNAME_LEN, "%s.%s", name->dbname, name->tname);
return 0;
}
void tNameAssign(SName* dst, const SName* src) { memcpy(dst, src, sizeof(SName)); }
int32_t tNameSetDbName(SName* dst, int32_t acct, const char* dbName, size_t nameLen) {
@ -231,46 +238,41 @@ static int compareKv(const void* p1, const void* p2) {
}
/*
* use stable name and tags to grearate child table name
* use stable name and tags to generate child table name
*/
int32_t buildChildTableName(RandTableName* rName) {
SStringBuilder sb = {0};
taosStringBuilderAppendStringLen(&sb, rName->stbFullName, rName->stbFullNameLen);
if (sb.buf == NULL) {
return TSDB_CODE_OUT_OF_MEMORY;
}
taosArraySort(rName->tags, compareKv);
T_MD5_CTX context;
tMD5Init(&context);
// add stable name
tMD5Update(&context, (uint8_t*)rName->stbFullName, rName->stbFullNameLen);
// add tags
for (int j = 0; j < taosArrayGetSize(rName->tags); ++j) {
taosStringBuilderAppendChar(&sb, ',');
SSmlKv* tagKv = taosArrayGet(rName->tags, j);
if (tagKv == NULL) {
return TSDB_CODE_SML_INVALID_DATA;
}
taosStringBuilderAppendStringLen(&sb, tagKv->key, tagKv->keyLen);
taosStringBuilderAppendChar(&sb, '=');
tMD5Update(&context, (uint8_t*)",", 1);
tMD5Update(&context, (uint8_t*)tagKv->key, tagKv->keyLen);
tMD5Update(&context, (uint8_t*)"=", 1);
if (IS_VAR_DATA_TYPE(tagKv->type)) {
taosStringBuilderAppendStringLen(&sb, tagKv->value, tagKv->length);
tMD5Update(&context, (uint8_t*)tagKv->value, tagKv->length);
} else {
taosStringBuilderAppendStringLen(&sb, (char*)(&(tagKv->value)), tagKv->length);
tMD5Update(&context, (uint8_t*)(&(tagKv->value)), tagKv->length);
}
}
size_t len = 0;
char* keyJoined = taosStringBuilderGetResult(&sb, &len);
T_MD5_CTX context;
tMD5Init(&context);
tMD5Update(&context, (uint8_t*)keyJoined, (uint32_t)len);
tMD5Final(&context);
char temp[8] = {0};
rName->ctbShortName[0] = 't';
rName->ctbShortName[1] = '_';
for (int i = 0; i < 16; i++) {
(void)sprintf(temp, "%02x", context.digest[i]);
(void)strcat(rName->ctbShortName, temp);
}
taosStringBuilderDestroy(&sb);
taosByteArrayToHexStr(context.digest, 16, rName->ctbShortName + 2);
rName->ctbShortName[34] = 0;
return TSDB_CODE_SUCCESS;
}

View File

@ -531,7 +531,6 @@ TEST(testCase, StreamWithoutDotInStbName2) {
TEST(testCase, StreamWithLongStbName) {
char ctbName[TSDB_TABLE_NAME_LEN];
char expectName[TSDB_TABLE_NAME_LEN];
char *stbName = "a_simle_stb_name";
uint64_t groupId = UINT64_MAX;
@ -550,29 +549,13 @@ TEST(testCase, StreamWithLongStbName) {
EXPECT_EQ(buildCtbNameAddGroupId(stbName, NULL, groupId, sizeof(ctbName)), TSDB_CODE_INTERNAL_ERROR);
EXPECT_EQ(buildCtbNameAddGroupId(stbName, ctbName, groupId, sizeof(ctbName) - 1), TSDB_CODE_INTERNAL_ERROR);
// test md5 conversion of stbName with groupid
// test truncation of long ctbName
for (int32_t i = 0; i < 159; ++i) ctbName[i] = 'A';
ctbName[159] = '\0';
stbName = taosStrdup(ctbName);
snprintf(expectName, TSDB_TABLE_NAME_LEN, "%s_d85f0d87946d76eeedd7b7b78b7492a2", ctbName);
std::string expectName = std::string(ctbName) + "_" + std::string(stbName) + "_" + std::to_string(groupId);
EXPECT_EQ(buildCtbNameAddGroupId(stbName, ctbName, groupId, sizeof(ctbName)), TSDB_CODE_SUCCESS);
EXPECT_STREQ(ctbName, expectName);
// test md5 conversion of all parts
for (int32_t i = 0; i < 190; ++i) ctbName[i] = 'A';
ctbName[190] = '\0';
tstrncpy(expectName, "t_d38a8b2df999bef0082ffc80a59a9cd7_d85f0d87946d76eeedd7b7b78b7492a2", TSDB_TABLE_NAME_LEN);
EXPECT_EQ(buildCtbNameAddGroupId(stbName, ctbName, groupId, sizeof(ctbName)), TSDB_CODE_SUCCESS);
EXPECT_STREQ(ctbName, expectName);
// test larger stbName
taosMemoryFree(stbName);
for (int32_t i = 0; i < 190; ++i) ctbName[i] = 'A';
ctbName[190] = '\0';
stbName = taosStrdup(ctbName);
tstrncpy(expectName, "t_d38a8b2df999bef0082ffc80a59a9cd7_9c99cc7c52073b63fb750af402d9b84b", TSDB_TABLE_NAME_LEN);
EXPECT_EQ(buildCtbNameAddGroupId(stbName, ctbName, groupId, sizeof(ctbName)), TSDB_CODE_SUCCESS);
EXPECT_STREQ(ctbName, expectName);
EXPECT_STREQ(ctbName, expectName.c_str() + expectName.size() - TSDB_TABLE_NAME_LEN + 1);
taosMemoryFree(stbName);
}

View File

@ -48,10 +48,10 @@ static void dmUpdateDnodeCfg(SDnodeMgmt *pMgmt, SDnodeCfg *pCfg) {
static void dmMayShouldUpdateIpWhiteList(SDnodeMgmt *pMgmt, int64_t ver) {
int32_t code = 0;
dDebug("ip-white-list on dnode ver: %" PRId64 ", status ver: %" PRId64 "", pMgmt->pData->ipWhiteVer, ver);
dDebug("ip-white-list on dnode ver: %" PRId64 ", status ver: %" PRId64, pMgmt->pData->ipWhiteVer, ver);
if (pMgmt->pData->ipWhiteVer == ver) {
if (ver == 0) {
dDebug("disable ip-white-list on dnode ver: %" PRId64 ", status ver: %" PRId64 "", pMgmt->pData->ipWhiteVer, ver);
dDebug("disable ip-white-list on dnode ver: %" PRId64 ", status ver: %" PRId64, pMgmt->pData->ipWhiteVer, ver);
if (rpcSetIpWhite(pMgmt->msgCb.serverRpc, NULL) != 0) {
dError("failed to disable ip white list on dnode");
}

View File

@ -106,15 +106,15 @@ static void vmProcessQueryQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
SVnodeObj *pVnode = pInfo->ahandle;
const STraceId *trace = &pMsg->info.traceId;
dGTrace("vgId:%d, msg:%p get from vnode-query queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, get from vnode-query queue", pVnode->vgId, pMsg);
int32_t code = vnodeProcessQueryMsg(pVnode->pImpl, pMsg, pInfo);
if (code != 0) {
if (terrno != 0) code = terrno;
dGError("vgId:%d, msg:%p failed to query since %s", pVnode->vgId, pMsg, tstrerror(code));
dGError("vgId:%d, msg:%p, failed to query since %s", pVnode->vgId, pMsg, tstrerror(code));
vmSendRsp(pMsg, code);
}
dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code);
dGTrace("vgId:%d, msg:%p, is freed, code:0x%x", pVnode->vgId, pMsg, code);
rpcFreeCont(pMsg->pCont);
taosFreeQitem(pMsg);
}
@ -124,16 +124,16 @@ static void vmProcessStreamQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
SVnodeObj *pVnode = pInfo->ahandle;
const STraceId *trace = &pMsg->info.traceId;
dGTrace("vgId:%d, msg:%p get from vnode-stream queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, get from vnode-stream queue", pVnode->vgId, pMsg);
int32_t code = vnodeProcessStreamMsg(pVnode->pImpl, pMsg, pInfo);
if (code != 0) {
terrno = code;
dGError("vgId:%d, msg:%p failed to process stream msg %s since %s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType),
dGError("vgId:%d, msg:%p, failed to process stream msg %s since %s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType),
tstrerror(code));
vmSendRsp(pMsg, code);
}
dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code);
dGTrace("vgId:%d, msg:%p, is freed, code:0x%x", pVnode->vgId, pMsg, code);
rpcFreeCont(pMsg->pCont);
taosFreeQitem(pMsg);
#endif
@ -153,16 +153,16 @@ static void vmProcessStreamCtrlQueue(SQueueInfo *pInfo, STaosQall* pQall, int32_
SRpcMsg *pMsg = pItem;
const STraceId *trace = &pMsg->info.traceId;
dGTrace("vgId:%d, msg:%p get from vnode-stream-ctrl queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, get from vnode-stream-ctrl queue", pVnode->vgId, pMsg);
code = vnodeProcessStreamCtrlMsg(pVnode->pImpl, pMsg, pInfo);
if (code != 0) {
terrno = code;
dGError("vgId:%d, msg:%p failed to process stream ctrl msg %s since %s", pVnode->vgId, pMsg,
dGError("vgId:%d, msg:%p, failed to process stream ctrl msg %s since %s", pVnode->vgId, pMsg,
TMSG_INFO(pMsg->msgType), tstrerror(code));
vmSendRsp(pMsg, code);
}
dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code);
dGTrace("vgId:%d, msg:%p, is freed, code:0x%x", pVnode->vgId, pMsg, code);
rpcFreeCont(pMsg->pCont);
taosFreeQitem(pMsg);
}
@ -182,16 +182,16 @@ static void vmProcessStreamChkptQueue(SQueueInfo *pInfo, STaosQall* pQall, int32
SRpcMsg *pMsg = pItem;
const STraceId *trace = &pMsg->info.traceId;
dGTrace("vgId:%d, msg:%p get from vnode-stream-chkpt queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, get from vnode-stream-chkpt queue", pVnode->vgId, pMsg);
code = vnodeProcessStreamChkptMsg(pVnode->pImpl, pMsg, pInfo);
if (code != 0) {
terrno = code;
dGError("vgId:%d, msg:%p failed to process stream chkpt msg %s since %s", pVnode->vgId, pMsg,
dGError("vgId:%d, msg:%p, failed to process stream chkpt msg %s since %s", pVnode->vgId, pMsg,
TMSG_INFO(pMsg->msgType), tstrerror(code));
vmSendRsp(pMsg, code);
}
dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code);
dGTrace("vgId:%d, msg:%p, is freed, code:0x%x", pVnode->vgId, pMsg, code);
rpcFreeCont(pMsg->pCont);
taosFreeQitem(pMsg);
}
@ -202,17 +202,17 @@ static void vmProcessStreamLongExecQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
const STraceId *trace = &pMsg->info.traceId;
int32_t code = 0;
dGTrace("vgId:%d, msg:%p get from vnode-stream long-exec queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, get from vnode-stream long-exec queue", pVnode->vgId, pMsg);
code = vnodeProcessStreamLongExecMsg(pVnode->pImpl, pMsg, pInfo);
if (code != 0) {
terrno = code;
dGError("vgId:%d, msg:%p failed to process stream msg %s since %s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType),
dGError("vgId:%d, msg:%p, failed to process stream msg %s since %s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType),
tstrerror(code));
vmSendRsp(pMsg, code);
}
dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code);
dGTrace("vgId:%d, msg:%p, is freed, code:0x%x", pVnode->vgId, pMsg, code);
rpcFreeCont(pMsg->pCont);
taosFreeQitem(pMsg);
}
@ -224,7 +224,7 @@ static void vmProcessFetchQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO
for (int32_t i = 0; i < numOfMsgs; ++i) {
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
const STraceId *trace = &pMsg->info.traceId;
dGTrace("vgId:%d, msg:%p get from vnode-fetch queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, get from vnode-fetch queue", pVnode->vgId, pMsg);
terrno = 0;
int32_t code = vnodeProcessFetchMsg(pVnode->pImpl, pMsg, pInfo);
@ -234,15 +234,15 @@ static void vmProcessFetchQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO
}
if (code == TSDB_CODE_WAL_LOG_NOT_EXIST) {
dGDebug("vnodeProcessFetchMsg vgId:%d, msg:%p failed to fetch since %s", pVnode->vgId, pMsg, terrstr());
dGDebug("vgId:%d, msg:%p, failed to fetch since %s [vnodeProcessFetchMsg]", pVnode->vgId, pMsg, terrstr());
} else {
dGError("vnodeProcessFetchMsg vgId:%d, msg:%p failed to fetch since %s", pVnode->vgId, pMsg, terrstr());
dGError("vgId:%d, msg:%p, failed to fetch since %s [vnodeProcessFetchMsg]", pVnode->vgId, pMsg, terrstr());
}
vmSendRsp(pMsg, code);
}
dGTrace("vnodeProcessFetchMsg vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code);
dGTrace("vgId:%d, msg:%p, is freed, code:0x%x [vnodeProcessFetchMsg]", pVnode->vgId, pMsg, code);
rpcFreeCont(pMsg->pCont);
taosFreeQitem(pMsg);
}
@ -255,10 +255,10 @@ static void vmProcessSyncQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numOf
for (int32_t i = 0; i < numOfMsgs; ++i) {
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
const STraceId *trace = &pMsg->info.traceId;
dGTrace("vgId:%d, msg:%p get from vnode-sync queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, get from vnode-sync queue", pVnode->vgId, pMsg);
int32_t code = vnodeProcessSyncMsg(pVnode->pImpl, pMsg, NULL); // no response here
dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code);
dGTrace("vgId:%d, msg:%p, is freed, code:0x%x", pVnode->vgId, pMsg, code);
rpcFreeCont(pMsg->pCont);
taosFreeQitem(pMsg);
}
@ -306,7 +306,7 @@ static int32_t vmPutMsgToQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg, EQueueType qtyp
SVnodeObj *pVnode = NULL;
code = vmAcquireVnodeWrapper(pMgmt, pHead->vgId, &pVnode);
if (code != 0) {
dGDebug("vgId:%d, msg:%p failed to put into vnode queue since %s, type:%s qtype:%d contLen:%d", pHead->vgId, pMsg,
dGDebug("vgId:%d, msg:%p, failed to put into vnode queue since %s, type:%s qtype:%d contLen:%d", pHead->vgId, pMsg,
tstrerror(code), TMSG_INFO(pMsg->msgType), qtype, pHead->contLen);
return code;
}
@ -315,61 +315,64 @@ static int32_t vmPutMsgToQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg, EQueueType qtyp
case QUERY_QUEUE:
code = vnodePreprocessQueryMsg(pVnode->pImpl, pMsg);
if (code) {
dError("vgId:%d, msg:%p preprocess query msg failed since %s", pVnode->vgId, pMsg, tstrerror(code));
dError("vgId:%d, msg:%p, preprocess query msg failed since %s", pVnode->vgId, pMsg, tstrerror(code));
} else {
dGTrace("vgId:%d, msg:%p put into vnode-query queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, put into vnode-query queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pQueryQ, pMsg);
}
break;
case STREAM_QUEUE:
dGTrace("vgId:%d, msg:%p put into vnode-stream queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, put into vnode-stream queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pStreamQ, pMsg);
break;
case STREAM_CTRL_QUEUE:
dGTrace("vgId:%d, msg:%p put into vnode-stream-ctrl queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, put into vnode-stream-ctrl queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pStreamCtrlQ, pMsg);
break;
case STREAM_LONG_EXEC_QUEUE:
dGTrace("vgId:%d, msg:%p put into vnode-stream-long-exec queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, put into vnode-stream-long-exec queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pStreamLongExecQ, pMsg);
break;
case STREAM_CHKPT_QUEUE:
dGTrace("vgId:%d, msg:%p put into vnode-stream-chkpt queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, put into vnode-stream-chkpt queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pStreamChkQ, pMsg);
break;
case FETCH_QUEUE:
dGTrace("vgId:%d, msg:%p put into vnode-fetch queue", pVnode->vgId, pMsg);
dGTrace("vgId:%d, msg:%p, put into vnode-fetch queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pFetchQ, pMsg);
break;
case WRITE_QUEUE:
if (!vmDataSpaceSufficient(pVnode)) {
code = TSDB_CODE_NO_ENOUGH_DISKSPACE;
dError("vgId:%d, msg:%p put into vnode-write queue failed since %s", pVnode->vgId, pMsg, tstrerror(code));
dError("vgId:%d, msg:%p, failed to put into vnode-write queue since %s, type:%s", pVnode->vgId, pMsg,
tstrerror(code), TMSG_INFO(pMsg->msgType));
break;
}
if (pMsg->msgType == TDMT_VND_SUBMIT && (grantCheck(TSDB_GRANT_STORAGE) != TSDB_CODE_SUCCESS)) {
code = TSDB_CODE_VND_NO_WRITE_AUTH;
dDebug("vgId:%d, msg:%p put into vnode-write queue failed since %s", pVnode->vgId, pMsg, tstrerror(code));
dDebug("vgId:%d, msg:%p, failed to put into vnode-write queue since %s, type:%s", pVnode->vgId, pMsg,
tstrerror(code), TMSG_INFO(pMsg->msgType));
break;
}
if (pMsg->msgType != TDMT_VND_ALTER_CONFIRM && pVnode->disable) {
dDebug("vgId:%d, msg:%p put into vnode-write queue failed since its disable", pVnode->vgId, pMsg);
dDebug("vgId:%d, msg:%p, failed to put into vnode-write queue since its disable, type:%s", pVnode->vgId, pMsg,
TMSG_INFO(pMsg->msgType));
code = TSDB_CODE_VND_STOPPED;
break;
}
dGTrace("vgId:%d, msg:%p put into vnode-write queue", pVnode->vgId, pMsg);
dGDebug("vgId:%d, msg:%p, put into vnode-write queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pWriteW.queue, pMsg);
break;
case SYNC_QUEUE:
dGTrace("vgId:%d, msg:%p put into vnode-sync queue", pVnode->vgId, pMsg);
dGDebug("vgId:%d, msg:%p, put into vnode-sync queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pSyncW.queue, pMsg);
break;
case SYNC_RD_QUEUE:
dGTrace("vgId:%d, msg:%p put into vnode-sync-rd queue", pVnode->vgId, pMsg);
dGDebug("vgId:%d, msg:%p, put into vnode-sync-rd queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pSyncRdW.queue, pMsg);
break;
case APPLY_QUEUE:
dGTrace("vgId:%d, msg:%p put into vnode-apply queue", pVnode->vgId, pMsg);
dGDebug("vgId:%d, msg:%p, put into vnode-apply queue, type:%s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType));
code = taosWriteQitem(pVnode->pApplyW.queue, pMsg);
break;
default:
@ -431,7 +434,7 @@ int32_t vmPutRpcMsgToQueue(SVnodeMgmt *pMgmt, EQueueType qtype, SRpcMsg *pRpc) {
}
SMsgHead *pHead = pRpc->pCont;
dTrace("vgId:%d, msg:%p is created, type:%s len:%d", pHead->vgId, pMsg, TMSG_INFO(pRpc->msgType), pRpc->contLen);
dTrace("vgId:%d, msg:%p, is created, type:%s len:%d", pHead->vgId, pMsg, TMSG_INFO(pRpc->msgType), pRpc->contLen);
pHead->contLen = htonl(pHead->contLen);
pHead->vgId = htonl(pHead->vgId);

View File

@ -122,7 +122,7 @@ int32_t mndStreamGetRelTrans(SMnode *pMnode, int64_t streamId);
int32_t mndGetNumOfStreams(SMnode *pMnode, char *dbName, int32_t *pNumOfStreams);
int32_t mndGetNumOfStreamTasks(const SStreamObj *pStream);
int32_t mndTakeVgroupSnapshot(SMnode *pMnode, bool *allReady, SArray **pList);
int32_t mndTakeVgroupSnapshot(SMnode *pMnode, bool *allReady, SArray **pList, SHashObj* pTermMap);
void mndDestroyVgroupChangeInfo(SVgroupChangeInfo *pInfo);
void mndKillTransImpl(SMnode *pMnode, int32_t transId, const char *pDbName);
int32_t setTransAction(STrans *pTrans, void *pCont, int32_t contLen, int32_t msgType, const SEpSet *pEpset,
@ -147,7 +147,7 @@ int32_t mndStreamSetDropActionFromList(SMnode *pMnode, STrans *pTrans, SArray *p
int32_t mndStreamSetResetTaskAction(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream, int64_t chkptId);
int32_t mndStreamSetUpdateChkptAction(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream);
int32_t mndCreateStreamResetStatusTrans(SMnode *pMnode, SStreamObj *pStream, int64_t chkptId);
int32_t mndStreamSetChkptIdAction(SMnode *pMnode, STrans *pTrans, SStreamTask *pTask, int64_t checkpointId, int64_t ts);
int32_t mndStreamSetChkptIdAction(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream, int64_t checkpointId, SArray *pList);
int32_t mndStreamSetRestartAction(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream);
int32_t mndStreamSetCheckpointAction(SMnode *pMnode, STrans *pTrans, SStreamTask *pTask, int64_t checkpointId,
int8_t mndTrigger);
@ -155,8 +155,7 @@ int32_t mndStreamSetStopStreamTasksActions(SMnode* pMnode, STrans *pTrans, uint6
int32_t mndCreateStreamChkptInfoUpdateTrans(SMnode *pMnode, SStreamObj *pStream, SArray *pChkptInfoList);
int32_t mndScanCheckpointReportInfo(SRpcMsg *pReq);
int32_t mndCreateSetConsensusChkptIdTrans(SMnode *pMnode, SStreamObj *pStream, int32_t taskId, int64_t checkpointId,
int64_t ts);
int32_t mndCreateSetConsensusChkptIdTrans(SMnode *pMnode, SStreamObj *pStream, int64_t checkpointId, SArray* pList);
void removeTasksInBuf(SArray *pTaskIds, SStreamExecInfo *pExecInfo);
int32_t mndFindChangedNodeInfo(SMnode *pMnode, const SArray *pPrevNodeList, const SArray *pNodeList,
SVgroupChangeInfo *pInfo);

View File

@ -29,7 +29,7 @@ int32_t mndGetGroupNumByTopic(SMnode *pMnode, const char *topicName);
int32_t mndAcquireSubscribeByKey(SMnode *pMnode, const char *key, SMqSubscribeObj** pSub);
void mndReleaseSubscribe(SMnode *pMnode, SMqSubscribeObj *pSub);
int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topic);
int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topic, bool force);
int32_t mndSetDropSubCommitLogs(SMnode *pMnode, STrans *pTrans, SMqSubscribeObj *pSub);
bool mndRebTryStart();

View File

@ -429,9 +429,8 @@ void mndDoTimerPullupTask(SMnode *pMnode, int64_t sec) {
if (sec % 5 == 0) {
mndStreamConsensusChkpt(pMnode);
}
#endif
#ifdef USE_REPORT
if (sec % tsTelemInterval == (TMIN(86400, (tsTelemInterval - 1)))) {
if (tsTelemInterval > 0 && sec % tsTelemInterval == 0) {
mndPullupTelem(pMnode);
}
#endif
@ -474,19 +473,18 @@ static void *mndThreadFp(void *param) {
while (1) {
lastTime++;
taosMsleep(100);
if (mndGetStop(pMnode)) break;
if (lastTime % 10 != 0) continue;
if (mnodeIsNotLeader(pMnode)) {
mTrace("timer not process since mnode is not leader");
continue;
}
int64_t sec = lastTime / 10;
mndDoTimerCheckTask(pMnode, sec);
int64_t minCron = minCronTime();
if (sec % minCron == 0 && mnodeIsNotLeader(pMnode)) {
// not leader, do nothing
mTrace("timer not process since mnode is not leader, reason: %s", tstrerror(terrno));
terrno = 0;
continue;
}
mndDoTimerPullupTask(pMnode, sec);
}
@ -856,11 +854,11 @@ int32_t mndProcessSyncMsg(SRpcMsg *pMsg) {
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
const STraceId *trace = &pMsg->info.traceId;
mGTrace("vgId:1, sync msg:%p will be processed, type:%s", pMsg, TMSG_INFO(pMsg->msgType));
mGTrace("vgId:1, process sync msg:%p, type:%s", pMsg, TMSG_INFO(pMsg->msgType));
int32_t code = syncProcessMsg(pMgmt->sync, pMsg);
if (code != 0) {
mGError("vgId:1, failed to process sync msg:%p type:%s, reason: %s, code:0x%x", pMsg, TMSG_INFO(pMsg->msgType),
mGError("vgId:1, failed to process sync msg:%p type:%s since %s, code:0x%x", pMsg, TMSG_INFO(pMsg->msgType),
tstrerror(code), code);
}

View File

@ -13,13 +13,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mndStream.h"
#include "audit.h"
#include "mndDb.h"
#include "mndPrivilege.h"
#include "mndScheduler.h"
#include "mndShow.h"
#include "mndStb.h"
#include "mndStream.h"
#include "mndTrans.h"
#include "osMemory.h"
#include "parser.h"
@ -1183,7 +1183,7 @@ int64_t mndStreamGenChkptId(SMnode *pMnode, bool lock) {
if (pIter == NULL) break;
maxChkptId = TMAX(maxChkptId, pStream->checkpointId);
mDebug("stream:%p, %s id:0x%" PRIx64 " checkpoint %" PRId64 "", pStream, pStream->name, pStream->uid,
mDebug("stream:%p, %s id:0x%" PRIx64 " checkpoint %" PRId64, pStream, pStream->name, pStream->uid,
pStream->checkpointId);
sdbRelease(pSdb, pStream);
}
@ -1257,7 +1257,7 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre
goto _ERR;
}
mDebug("start to trigger checkpoint for stream:%s, checkpoint: %" PRId64 "", pStream->name, checkpointId);
mDebug("start to trigger checkpoint for stream:%s, checkpoint: %" PRId64, pStream->name, checkpointId);
taosWLockLatch(&pStream->lock);
pStream->currentTick = 1;
@ -1390,18 +1390,16 @@ static int32_t streamWaitComparFn(const void *p1, const void *p2) {
}
// all tasks of this stream should be ready, otherwise do nothing
static bool isStreamReadyHelp(int64_t now, SStreamObj* pStream) {
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
"ms less than threshold",
pStream->uid, lastReadyTs, (now - lastReadyTs));
mInfo("not start checkpoint, stream:0x%" PRIx64 " readyTs:%" PRId64 " ready duration:%.2fs less than threshold",
pStream->uid, lastReadyTs, (now - lastReadyTs) / 1000.0);
}
ready = false;
@ -2094,11 +2092,12 @@ static int32_t mndProcessResetStreamReq(SRpcMsg *pReq) {
return TSDB_CODE_ACTION_IN_PROGRESS;
}
static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChangeInfo, bool includeAllNodes, STrans** pUpdateTrans) {
SSdb *pSdb = pMnode->pSdb;
void *pIter = NULL;
STrans *pTrans = NULL;
int32_t code = 0;
static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChangeInfo, bool includeAllNodes,
STrans **pUpdateTrans, SArray* pStreamList) {
SSdb *pSdb = pMnode->pSdb;
void *pIter = NULL;
STrans *pTrans = NULL;
int32_t code = 0;
*pUpdateTrans = NULL;
// conflict check for nodeUpdate trans, here we randomly chose one stream to add into the trans pool
@ -2167,6 +2166,10 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
}
code = mndPersistTransLog(pStream, pTrans, SDB_STATUS_READY);
if (code == 0) {
taosArrayPush(pStreamList, &pStream->uid);
}
sdbRelease(pSdb, pStream);
if (code != TSDB_CODE_SUCCESS) {
@ -2345,7 +2348,7 @@ static int32_t mndProcessNodeCheckReq(SRpcMsg *pMsg) {
return 0;
}
code = mndTakeVgroupSnapshot(pMnode, &allReady, &pNodeSnapshot);
code = mndTakeVgroupSnapshot(pMnode, &allReady, &pNodeSnapshot, NULL);
if (code) {
mError("failed to take the vgroup snapshot, ignore it and continue");
}
@ -2369,10 +2372,27 @@ static int32_t mndProcessNodeCheckReq(SRpcMsg *pMsg) {
mDebug("vnode(s) change detected, build trans to update stream task epsets");
STrans *pTrans = NULL;
SArray* pStreamIdList = taosArrayInit(4, sizeof(int64_t));
streamMutexLock(&execInfo.lock);
code = mndProcessVgroupChange(pMnode, &changeInfo, updateAllVgroups, &pTrans);
code = mndProcessVgroupChange(pMnode, &changeInfo, updateAllVgroups, &pTrans, pStreamIdList);
// remove the consensus-checkpoint-id req of all related stream(s)
int32_t num = taosArrayGetSize(pStreamIdList);
if (num > 0) {
mDebug("start to clear %d related stream in consensus-checkpoint-id list due to nodeUpdate", num);
for (int32_t x = 0; x < num; ++x) {
int64_t uid = *(int64_t *)taosArrayGet(pStreamIdList, x);
int32_t ret = mndClearConsensusCheckpointId(execInfo.pStreamConsensus, uid);
if (ret != 0) {
mError("failed to remove stream:0x%" PRIx64 " from consensus-checkpoint-id list, code:%s", uid,
tstrerror(ret));
}
}
}
streamMutexUnlock(&execInfo.lock);
taosArrayDestroy(pStreamIdList);
// NOTE: sync trans out of lock
if (code == 0 && pTrans != NULL) {
@ -2595,8 +2615,9 @@ int32_t mndProcessStreamReqCheckpoint(SRpcMsg *pReq) {
if (pStream != NULL) { // TODO:handle error
code = mndProcessStreamCheckpointTrans(pMnode, pStream, checkpointId, 0, false);
if (code) {
mError("failed to create checkpoint trans, code:%s", tstrerror(code));
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
mError("stream:0x%" PRIx64 " failed to create checkpoint trans, checkpointId:%" PRId64 ", code:%s",
req.streamId, checkpointId, tstrerror(code));
}
} else {
// todo: wait for the create stream trans completed, and launch the checkpoint trans
@ -2604,11 +2625,15 @@ int32_t mndProcessStreamReqCheckpoint(SRpcMsg *pReq) {
// sleep(500ms)
}
// remove this entry
(void) taosHashRemove(execInfo.pTransferStateStreams, &req.streamId, sizeof(int64_t));
// remove this entry, not overwriting the global error code
int32_t ret = taosHashRemove(execInfo.pTransferStateStreams, &req.streamId, sizeof(int64_t));
if (ret) {
mError("failed to remove transfer state stream, code:%s", tstrerror(ret));
}
int32_t numOfStreams = taosHashGetSize(execInfo.pTransferStateStreams);
mDebug("stream:0x%" PRIx64 " removed, remain streams:%d fill-history not completed", req.streamId, numOfStreams);
mDebug("stream:0x%" PRIx64 " removed in transfer-state list, %d stream(s) not finish fill-history process",
req.streamId, numOfStreams);
}
if (pStream != NULL) {
@ -2685,7 +2710,7 @@ static void doAddReportStreamTask(SArray *pList, int64_t reportedChkptId, const
pReport->taskId, p->checkpointId, pReport->checkpointId);
} else if (p->checkpointId < pReport->checkpointId) { // expired checkpoint-report msg, update it
mInfo("s-task:0x%x expired checkpoint-report info in checkpoint-report list update from %" PRId64 "->%" PRId64,
pReport->taskId, p->checkpointId, pReport->checkpointId);
pReport->taskId, p->checkpointId, pReport->checkpointId);
// update the checkpoint report info
p->checkpointId = pReport->checkpointId;
@ -2822,6 +2847,8 @@ static int64_t getConsensusId(int64_t streamId, int32_t numOfTasks, int32_t *pEx
if (chkId > pe->checkpointInfo.latestId) {
if (chkId != INT64_MAX) {
*pAllSame = false;
mDebug("checkpointIds not identical, prev:%" PRId64 " smaller:%" PRId64 " from task:0x%" PRIx64, chkId,
pe->checkpointInfo.latestId, pe->id.taskId);
}
chkId = pe->checkpointInfo.latestId;
}
@ -2847,7 +2874,7 @@ static void doSendQuickRsp(SRpcHandleInfo *pInfo, int32_t msgSize, int32_t vgId,
}
}
static int32_t doCleanReqList(SArray* pList, SCheckpointConsensusInfo* pInfo) {
static int32_t doCleanReqList(SArray *pList, SCheckpointConsensusInfo *pInfo) {
int32_t alreadySend = taosArrayGetSize(pList);
for (int32_t i = 0; i < alreadySend; ++i) {
@ -2873,7 +2900,6 @@ int32_t mndProcessConsensusInTmr(SRpcMsg *pMsg) {
int64_t now = taosGetTimestampMs();
bool allReady = true;
SArray *pNodeSnapshot = NULL;
int32_t maxAllowedTrans = 20;
int32_t numOfTrans = 0;
int32_t code = 0;
void *pIter = NULL;
@ -2889,9 +2915,16 @@ int32_t mndProcessConsensusInTmr(SRpcMsg *pMsg) {
return terrno;
}
SHashObj* pTermMap = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
if (pTermMap == NULL) {
taosArrayDestroy(pList);
taosArrayDestroy(pStreamList);
return terrno;
}
mDebug("start to process consensus-checkpointId in tmr");
code = mndTakeVgroupSnapshot(pMnode, &allReady, &pNodeSnapshot);
code = mndTakeVgroupSnapshot(pMnode, &allReady, &pNodeSnapshot, pTermMap);
taosArrayDestroy(pNodeSnapshot);
if (code) {
mError("failed to get the vgroup snapshot, ignore it and continue");
@ -2901,6 +2934,7 @@ int32_t mndProcessConsensusInTmr(SRpcMsg *pMsg) {
mWarn("not all vnodes are ready, end to process the consensus-checkpointId in tmr process");
taosArrayDestroy(pStreamList);
taosArrayDestroy(pList);
taosHashCleanup(pTermMap);
return 0;
}
@ -2927,31 +2961,62 @@ int32_t mndProcessConsensusInTmr(SRpcMsg *pMsg) {
continue;
}
if (pStream->uid != pInfo->streamId) {
// todo remove it
}
if ((num < pInfo->numOfTasks) || (pInfo->numOfTasks == 0)) {
mDebug("stream:0x%" PRIx64 " %s %d/%d tasks send checkpoint-consensus req(not all), ignore", pStream->uid,
pStream->name, num, pInfo->numOfTasks);
mndReleaseStream(pMnode, pStream);
continue;
}
streamId = pStream->uid;
int32_t existed = 0;
bool allSame = true;
int64_t chkId = getConsensusId(pInfo->streamId, pInfo->numOfTasks, &existed, &allSame);
if (chkId == -1) {
mDebug("not all(%d/%d) task(s) send hbMsg yet, wait for a while and check again", existed, pInfo->numOfTasks);
mndReleaseStream(pMnode, pStream);
continue;
}
bool allQualified = true;
for (int32_t j = 0; j < num; ++j) {
SCheckpointConsensusEntry *pe = taosArrayGet(pInfo->pTaskList, j);
if (pe == NULL) {
continue;
}
if (streamId == -1) {
streamId = pe->req.streamId;
}
int32_t existed = 0;
bool allSame = true;
int64_t chkId = getConsensusId(pe->req.streamId, pInfo->numOfTasks, &existed, &allSame);
if (chkId == -1) {
mDebug("not all(%d/%d) task(s) send hbMsg yet, wait for a while and check again, s-task:0x%x", existed,
pInfo->numOfTasks, pe->req.taskId);
break;
if (pe->req.nodeId != -2) {
int32_t *pTerm = taosHashGet(pTermMap, &(pe->req.nodeId), sizeof(pe->req.nodeId));
if (pTerm == NULL) {
mError("stream:0x%" PRIx64 " s-task:0x%x req from vgId:%d not found in termMap", pe->req.streamId,
pe->req.taskId, pe->req.nodeId);
allQualified = false;
continue;
} else {
if (*pTerm != pe->req.term) {
mWarn("stream:0x%" PRIx64 " s-task:0x%x req from vgId:%d is expired, term:%d, current term:%d",
pe->req.streamId, pe->req.taskId, pe->req.nodeId, pe->req.term, *pTerm);
allQualified = false;
continue;
}
}
}
if (((now - pe->ts) >= 10 * 1000) || allSame) {
mDebug("s-task:0x%x sendTs:%" PRId64 " wait %.2fs and all tasks have same checkpointId", pe->req.taskId,
pe->req.startTs, (now - pe->ts) / 1000.0);
mDebug("s-task:0x%x vgId:%d term:%d sendTs:%" PRId64 " wait %.2fs or all tasks have same checkpointId:%" PRId64, pe->req.taskId,
pe->req.nodeId, pe->req.term, pe->req.startTs, (now - pe->ts) / 1000.0, chkId);
if (chkId > pe->req.checkpointId) {
streamMutexUnlock(&execInfo.lock);
taosArrayDestroy(pStreamList);
taosArrayDestroy(pList);
taosHashCleanup(pTermMap);
mError("s-task:0x%x checkpointId:%" PRId64 " is updated to %" PRId64 ", update it", pe->req.taskId,
pe->req.checkpointId, chkId);
@ -2960,42 +3025,38 @@ int32_t mndProcessConsensusInTmr(SRpcMsg *pMsg) {
return TSDB_CODE_FAILED;
}
// todo: check for redundant consensus-checkpoint trans, if this kinds of trans repeatly failed.
code = mndCreateSetConsensusChkptIdTrans(pMnode, pStream, pe->req.taskId, chkId, pe->req.startTs);
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS) {
mError("failed to create consensus-checkpoint trans, stream:0x%" PRIx64, pStream->uid);
}
void *p = taosArrayPush(pList, &pe->req.taskId);
if (p == NULL) {
mError("failed to put into task list, taskId:0x%x", pe->req.taskId);
}
} else {
mDebug("s-task:0x%x sendTs:%" PRId64 " wait %.2fs already, wait for next round to check", pe->req.taskId,
pe->req.startTs, (now - pe->ts) / 1000.0);
allQualified = false;
}
}
if (allQualified) {
code = mndStreamTransConflictCheck(pMnode, pStream->uid, MND_STREAM_CHKPT_CONSEN_NAME, false);
if (code == 0) {
code = mndCreateSetConsensusChkptIdTrans(pMnode, pStream, chkId, pInfo->pTaskList);
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS) {
mError("failed to create consensus-checkpoint trans, stream:0x%" PRIx64, pStream->uid);
} else {
numOfTrans += 1;
mndClearConsensusRspEntry(pInfo);
void *p = taosArrayPush(pStreamList, &streamId);
if (p == NULL) {
mError("failed to put into stream list, stream:0x%" PRIx64 " not remove it in consensus-chkpt list",
streamId);
}
}
} else {
mDebug("stream:0x%" PRIx64 "not create chktp-consensus, due to trans conflict", pStream->uid);
}
}
mndReleaseStream(pMnode, pStream);
int32_t alreadySend = doCleanReqList(pList, pInfo);
// clear request stream item with empty task list
if (taosArrayGetSize(pInfo->pTaskList) == 0) {
mndClearConsensusRspEntry(pInfo);
if (streamId == -1) {
mError("streamId is -1, streamId:%" PRIx64 " in consensus-checkpointId hashMap, cont", pInfo->streamId);
}
void *p = taosArrayPush(pStreamList, &streamId);
if (p == NULL) {
mError("failed to put into stream list, stream:0x%" PRIx64 " not remove it in consensus-chkpt list", streamId);
}
}
numOfTrans += alreadySend;
if (numOfTrans > maxAllowedTrans) {
mInfo("already send consensus-checkpointId trans:%d, try next time", alreadySend);
// create one transaction each time
if (numOfTrans > 0) {
taosHashCancelIterate(execInfo.pStreamConsensus, pIter);
break;
}
@ -3014,6 +3075,7 @@ int32_t mndProcessConsensusInTmr(SRpcMsg *pMsg) {
taosArrayDestroy(pStreamList);
taosArrayDestroy(pList);
taosHashCleanup(pTermMap);
mDebug("end to process consensus-checkpointId in tmr, send consensus-checkpoint trans:%d", numOfTrans);
return code;

View File

@ -427,6 +427,8 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
.taskId = p->id.taskId,
.checkpointId = p->checkpointInfo.latestId,
.startTs = pChkInfo->consensusTs,
.nodeId = p->nodeId,
.term = p->stage,
};
SStreamObj *pStream = NULL;
@ -486,7 +488,7 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
if (pMnode != NULL) {
SArray *p = NULL;
code = mndTakeVgroupSnapshot(pMnode, &allReady, &p);
code = mndTakeVgroupSnapshot(pMnode, &allReady, &p, NULL);
taosArrayDestroy(p);
if (code) {
mError("failed to get the vgroup snapshot, ignore it and continue");

View File

@ -16,7 +16,7 @@
#include "mndStream.h"
#include "mndTrans.h"
#define MAX_CHKPT_EXEC_ELAPSED (600*1000) // 600s
#define MAX_CHKPT_EXEC_ELAPSED (600*1000*3) // 600s
typedef struct SKeyInfo {
void *pKey;
@ -137,6 +137,7 @@ static int32_t doStreamTransConflictCheck(SMnode *pMnode, int64_t streamId, cons
} else if ((strcmp(tInfo.name, MND_STREAM_CREATE_NAME) == 0) || (strcmp(tInfo.name, MND_STREAM_DROP_NAME) == 0) ||
(strcmp(tInfo.name, MND_STREAM_TASK_RESET_NAME) == 0) ||
(strcmp(tInfo.name, MND_STREAM_TASK_UPDATE_NAME) == 0) ||
(strcmp(tInfo.name, MND_STREAM_CHKPT_CONSEN_NAME) == 0) ||
strcmp(tInfo.name, MND_STREAM_RESTART_NAME) == 0) {
mWarn("conflict with other transId:%d streamUid:0x%" PRIx64 ", trans:%s", tInfo.transId, tInfo.streamId,
tInfo.name);
@ -152,7 +153,7 @@ static int32_t doStreamTransConflictCheck(SMnode *pMnode, int64_t streamId, cons
// * Transactions of different streams are not related. Here only check the conflict of transaction for a given stream.
// For a given stream:
// 1. checkpoint trans is conflict with any other trans except for the drop and reset trans.
// 2. create/drop/reset/update trans are conflict with any other trans.
// 2. create/drop/reset/update/chkpt-consensus trans are conflict with any other trans.
int32_t mndStreamTransConflictCheck(SMnode *pMnode, int64_t streamId, const char *pTransName, bool lock) {
if (lock) {
streamMutexLock(&execInfo.lock);
@ -266,7 +267,7 @@ _over:
}
terrno = 0;
mTrace("stream:%s, encode to raw:%p, row:%p, checkpoint:%" PRId64 "", pStream->name, pRaw, pStream,
mTrace("stream:%s, encode to raw:%p, row:%p, checkpoint:%" PRId64, pStream->name, pRaw, pStream,
pStream->checkpointId);
return pRaw;
}

View File

@ -113,8 +113,6 @@ static int32_t doSetResumeAction(STrans *pTrans, SMnode *pMnode, SStreamTask *pT
taosMemoryFree(pReq);
return code;
}
mDebug("set the resume action for trans:%d", pTrans->id);
return code;
}
@ -438,6 +436,8 @@ int32_t mndStreamSetResumeAction(STrans *pTrans, SMnode *pMnode, SStreamObj *pSt
return code;
}
mDebug("transId:%d start to create resume actions", pTrans->id);
while (streamTaskIterNextTask(pIter)) {
SStreamTask *pTask = NULL;
code = streamTaskIterGetCurrent(pIter, &pTask);
@ -578,7 +578,7 @@ int32_t mndStreamSetResetTaskAction(SMnode *pMnode, STrans *pTrans, SStreamObj *
return 0;
}
int32_t mndStreamSetChkptIdAction(SMnode *pMnode, STrans *pTrans, SStreamTask* pTask, int64_t checkpointId, int64_t ts) {
int32_t doSetCheckpointIdAction(SMnode *pMnode, STrans *pTrans, SStreamTask* pTask, int64_t checkpointId, int64_t ts) {
SRestoreCheckpointInfo req = {
.taskId = pTask->id.taskId,
.streamId = pTask->id.streamId,
@ -624,7 +624,7 @@ int32_t mndStreamSetChkptIdAction(SMnode *pMnode, STrans *pTrans, SStreamTask* p
return code;
}
code = setTransAction(pTrans, pBuf, tlen, TDMT_STREAM_CONSEN_CHKPT, &epset, 0, TSDB_CODE_VND_INVALID_VGROUP_ID);
code = setTransAction(pTrans, pBuf, tlen, TDMT_STREAM_CONSEN_CHKPT, &epset, TSDB_CODE_STREAM_TASK_IVLD_STATUS, TSDB_CODE_VND_INVALID_VGROUP_ID);
if (code != TSDB_CODE_SUCCESS) {
taosMemoryFree(pBuf);
}
@ -632,6 +632,50 @@ int32_t mndStreamSetChkptIdAction(SMnode *pMnode, STrans *pTrans, SStreamTask* p
return code;
}
int32_t mndStreamSetChkptIdAction(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream, int64_t checkpointId,
SArray *pList) {
SStreamTaskIter *pIter = NULL;
int32_t num = taosArrayGetSize(pList);
taosWLockLatch(&pStream->lock);
int32_t code = createStreamTaskIter(pStream, &pIter);
if (code) {
taosWUnLockLatch(&pStream->lock);
mError("failed to create stream task iter:%s", pStream->name);
return code;
}
while (streamTaskIterNextTask(pIter)) {
SStreamTask *pTask = NULL;
code = streamTaskIterGetCurrent(pIter, &pTask);
if (code) {
destroyStreamTaskIter(pIter);
taosWUnLockLatch(&pStream->lock);
return code;
}
// find the required entry
int64_t startTs = 0;
for(int32_t i = 0; i < num; ++i) {
SCheckpointConsensusEntry* pEntry = taosArrayGet(pList, i);
if (pEntry->req.taskId == pTask->id.taskId) {
startTs = pEntry->req.startTs;
break;
}
}
code = doSetCheckpointIdAction(pMnode, pTrans, pTask, checkpointId, startTs);
if (code != TSDB_CODE_SUCCESS) {
destroyStreamTaskIter(pIter);
taosWUnLockLatch(&pStream->lock);
return code;
}
}
destroyStreamTaskIter(pIter);
taosWUnLockLatch(&pStream->lock);
return 0;
}
int32_t mndStreamSetCheckpointAction(SMnode *pMnode, STrans *pTrans, SStreamTask *pTask, int64_t checkpointId,
int8_t mndTrigger) {

View File

@ -181,7 +181,7 @@ static int32_t mndCheckMnodeStatus(SMnode* pMnode) {
return TSDB_CODE_SUCCESS;
}
static int32_t mndCheckAndAddVgroupsInfo(SMnode *pMnode, SArray *pVgroupList, bool* allReady) {
static int32_t mndCheckAndAddVgroupsInfo(SMnode *pMnode, SArray *pVgroupList, bool* allReady, SHashObj* pTermMap) {
SSdb *pSdb = pMnode->pSdb;
void *pIter = NULL;
SVgObj *pVgroup = NULL;
@ -243,6 +243,14 @@ static int32_t mndCheckAndAddVgroupsInfo(SMnode *pMnode, SArray *pVgroupList, bo
mDebug("take node snapshot, nodeId:%d %s", entry.nodeId, buf);
}
if (pTermMap != NULL) {
int64_t term = pVgroup->vnodeGid[0].syncTerm;
code = taosHashPut(pTermMap, &pVgroup->vgId, sizeof(pVgroup->vgId), &term, sizeof(term));
if (code) {
mError("failed to put vnode:%d term into hashMap, code:%s", pVgroup->vgId, tstrerror(code));
}
}
sdbRelease(pSdb, pVgroup);
}
@ -251,7 +259,7 @@ _end:
return code;
}
int32_t mndTakeVgroupSnapshot(SMnode *pMnode, bool *allReady, SArray **pList) {
int32_t mndTakeVgroupSnapshot(SMnode *pMnode, bool *allReady, SArray **pList, SHashObj* pTermMap) {
int32_t code = 0;
SArray *pVgroupList = NULL;
@ -266,7 +274,7 @@ int32_t mndTakeVgroupSnapshot(SMnode *pMnode, bool *allReady, SArray **pList) {
}
// 1. check for all vnodes status
code = mndCheckAndAddVgroupsInfo(pMnode, pVgroupList, allReady);
code = mndCheckAndAddVgroupsInfo(pMnode, pVgroupList, allReady, pTermMap);
if (code) {
goto _err;
}
@ -728,15 +736,21 @@ int32_t mndScanCheckpointReportInfo(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
void *pIter = NULL;
int32_t code = 0;
SArray *pDropped = taosArrayInit(4, sizeof(int64_t));
if (pDropped == NULL) {
return terrno;
}
int32_t lino = 0;
SArray *pDropped = NULL;
mDebug("start to scan checkpoint report info");
streamMutexLock(&execInfo.lock);
int32_t num = taosHashGetSize(execInfo.pChkptStreams);
if (num == 0) {
goto _end;
}
pDropped = taosArrayInit(4, sizeof(int64_t));
TSDB_CHECK_NULL(pDropped, code, lino, _end, terrno);
while ((pIter = taosHashIterate(execInfo.pChkptStreams, pIter)) != NULL) {
SChkptReportInfo *px = (SChkptReportInfo *)pIter;
if (taosArrayGetSize(px->pTaskList) == 0) {
@ -804,42 +818,35 @@ int32_t mndScanCheckpointReportInfo(SRpcMsg *pReq) {
mDebug("drop %d stream(s) in checkpoint-report list, remain:%d", size, numOfStreams);
}
_end:
streamMutexUnlock(&execInfo.lock);
taosArrayDestroy(pDropped);
if (pDropped != NULL) {
taosArrayDestroy(pDropped);
}
mDebug("end to scan checkpoint report info")
return TSDB_CODE_SUCCESS;
return code;
}
int32_t mndCreateSetConsensusChkptIdTrans(SMnode *pMnode, SStreamObj *pStream, int32_t taskId, int64_t checkpointId,
int64_t ts) {
char msg[128] = {0};
STrans *pTrans = NULL;
SStreamTask *pTask = NULL;
int32_t mndCreateSetConsensusChkptIdTrans(SMnode *pMnode, SStreamObj *pStream, int64_t checkpointId, SArray* pList) {
char msg[128] = {0};
STrans *pTrans = NULL;
snprintf(msg, tListLen(msg), "set consen-chkpt-id for task:0x%x", taskId);
snprintf(msg, tListLen(msg), "set consen-chkpt-id for stream:0x%" PRIx64, pStream->uid);
int32_t code = doCreateTrans(pMnode, pStream, NULL, TRN_CONFLICT_NOTHING, MND_STREAM_CHKPT_CONSEN_NAME, msg, &pTrans);
if (pTrans == NULL || code != 0) {
return terrno;
}
STaskId id = {.streamId = pStream->uid, .taskId = taskId};
code = mndGetStreamTask(&id, pStream, &pTask);
if (code) {
mError("failed to get task:0x%x in stream:%s, failed to create consensus-checkpointId", taskId, pStream->name);
sdbRelease(pMnode->pSdb, pStream);
return code;
}
code = mndStreamRegisterTrans(pTrans, MND_STREAM_CHKPT_CONSEN_NAME, pStream->uid);
if (code) {
sdbRelease(pMnode->pSdb, pStream);
return code;
}
code = mndStreamSetChkptIdAction(pMnode, pTrans, pTask, checkpointId, ts);
code = mndStreamSetChkptIdAction(pMnode, pTrans, pStream, checkpointId, pList);
if (code != 0) {
sdbRelease(pMnode->pSdb, pStream);
mndTransDrop(pTrans);
@ -854,8 +861,10 @@ int32_t mndCreateSetConsensusChkptIdTrans(SMnode *pMnode, SStreamObj *pStream, i
}
code = mndTransPrepare(pMnode, pTrans);
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS) {
mError("trans:%d, failed to prepare set consensus-chkptId trans since %s", pTrans->id, terrstr());
mError("trans:%d, failed to prepare set consensus-chkptId trans for stream:0x%" PRId64 " since %s", pTrans->id,
pStream->uid, tstrerror(code));
sdbRelease(pMnode->pSdb, pStream);
mndTransDrop(pTrans);
return code;
@ -911,13 +920,15 @@ void mndAddConsensusTasks(SCheckpointConsensusInfo *pInfo, const SRestoreCheckpo
}
if (p->req.taskId == info.req.taskId) {
mDebug("s-task:0x%x already in consensus-checkpointId list for stream:0x%" PRIx64 ", update ts %" PRId64
"->%" PRId64 " checkpointId:%" PRId64 " -> %" PRId64 " total existed:%d",
mDebug("s-task:0x%x already in consensus-checkpointId list for stream:0x%" PRIx64 ", update send reqTs %" PRId64
"->%" PRId64 " checkpointId:%" PRId64 " -> %" PRId64 " term:%d->%d total existed:%d",
pRestoreInfo->taskId, pRestoreInfo->streamId, p->req.startTs, info.req.startTs, p->req.checkpointId,
info.req.checkpointId, num);
info.req.checkpointId, p->req.term, info.req.term, num);
p->req.startTs = info.req.startTs;
p->req.checkpointId = info.req.checkpointId;
p->req.transId = info.req.transId;
p->req.nodeId = info.req.nodeId;
p->req.term = info.req.term;
return;
}
}
@ -927,9 +938,10 @@ void mndAddConsensusTasks(SCheckpointConsensusInfo *pInfo, const SRestoreCheckpo
mError("s-task:0x%x failed to put task into consensus-checkpointId list, code: out of memory", info.req.taskId);
} else {
num = taosArrayGetSize(pInfo->pTaskList);
mDebug("s-task:0x%x checkpointId:%" PRId64 " added into consensus-checkpointId list, stream:0x%" PRIx64
" waiting tasks:%d",
pRestoreInfo->taskId, pRestoreInfo->checkpointId, pRestoreInfo->streamId, num);
mDebug("s-task:0x%x (vgId:%d) checkpointId:%" PRId64 " term:%d, reqTs:%" PRId64
" added into consensus-checkpointId list, stream:0x%" PRIx64 " waiting tasks:%d",
pRestoreInfo->taskId, pRestoreInfo->nodeId, pRestoreInfo->checkpointId, info.req.term,
info.req.startTs, pRestoreInfo->streamId, num);
}
}
@ -947,6 +959,7 @@ int32_t mndClearConsensusCheckpointId(SHashObj *pHash, int64_t streamId) {
code = taosHashRemove(pHash, &streamId, sizeof(streamId));
if (code == 0) {
numOfStreams = taosHashGetSize(pHash);
mDebug("drop stream:0x%" PRIx64 " in consensus-checkpointId list, remain:%d", streamId, numOfStreams);
} else {
mError("failed to remove stream:0x%" PRIx64 " in consensus-checkpointId list, remain:%d", streamId, numOfStreams);
@ -1686,7 +1699,7 @@ static int32_t doCheckForUpdated(SMnode *pMnode, SArray **ppNodeSnapshot) {
}
}
int32_t code = mndTakeVgroupSnapshot(pMnode, &allReady, ppNodeSnapshot);
int32_t code = mndTakeVgroupSnapshot(pMnode, &allReady, ppNodeSnapshot, NULL);
if (code) {
mError("failed to get the vgroup snapshot, ignore it and continue");
}

View File

@ -1112,12 +1112,13 @@ END:
return code;
}
static int32_t mndCheckConsumerByGroup(SMnode *pMnode, STrans *pTrans, char *cgroup, char *topic) {
static int32_t mndCheckConsumerByGroup(SMnode *pMnode, STrans *pTrans, char *cgroup, char *topic, bool deleteConsumer) {
if (pMnode == NULL || pTrans == NULL || cgroup == NULL || topic == NULL) {
return TSDB_CODE_INVALID_PARA;
}
void *pIter = NULL;
SMqConsumerObj *pConsumer = NULL;
SMqConsumerObj *pConsumerNew = NULL;
int code = 0;
while (1) {
pIter = sdbFetch(pMnode->pSdb, SDB_CONSUMER, pIter, (void **)&pConsumer);
@ -1130,18 +1131,27 @@ static int32_t mndCheckConsumerByGroup(SMnode *pMnode, STrans *pTrans, char *cgr
continue;
}
bool found = checkTopic(pConsumer->assignedTopics, topic);
if (found){
mError("topic:%s, failed to drop since subscribed by consumer:0x%" PRIx64 ", in consumer group %s",
topic, pConsumer->consumerId, pConsumer->cgroup);
code = TSDB_CODE_MND_CGROUP_USED;
goto END;
if (deleteConsumer) {
MND_TMQ_RETURN_CHECK(tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup, -1, NULL, NULL, &pConsumerNew));
MND_TMQ_RETURN_CHECK(mndSetConsumerDropLogs(pTrans, pConsumerNew));
tDeleteSMqConsumerObj(pConsumerNew);
pConsumerNew = NULL;
} else {
bool found = checkTopic(pConsumer->assignedTopics, topic);
if (found){
mError("topic:%s, failed to drop since subscribed by consumer:0x%" PRIx64 ", in consumer group %s",
topic, pConsumer->consumerId, pConsumer->cgroup);
code = TSDB_CODE_MND_CGROUP_USED;
goto END;
}
}
sdbRelease(pMnode->pSdb, pConsumer);
}
END:
tDeleteSMqConsumerObj(pConsumerNew);
sdbRelease(pMnode->pSdb, pConsumer);
sdbCancelFetch(pMnode->pSdb, pIter);
return code;
@ -1173,7 +1183,7 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg) {
}
taosWLockLatch(&pSub->lock);
if (taosHashGetSize(pSub->consumerHash) != 0) {
if (!dropReq.force && taosHashGetSize(pSub->consumerHash) != 0) {
code = TSDB_CODE_MND_CGROUP_USED;
mError("cgroup:%s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, tstrerror(code));
goto END;
@ -1185,7 +1195,7 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg) {
mndTransSetDbName(pTrans, pSub->dbName, NULL);
MND_TMQ_RETURN_CHECK(mndTransCheckConflict(pMnode, pTrans));
MND_TMQ_RETURN_CHECK(sendDeleteSubToVnode(pMnode, pSub, pTrans));
MND_TMQ_RETURN_CHECK(mndCheckConsumerByGroup(pMnode, pTrans, dropReq.cgroup, dropReq.topic));
MND_TMQ_RETURN_CHECK(mndCheckConsumerByGroup(pMnode, pTrans, dropReq.cgroup, dropReq.topic, dropReq.force));
MND_TMQ_RETURN_CHECK(mndSetDropSubCommitLogs(pMnode, pTrans, pSub));
MND_TMQ_RETURN_CHECK(mndTransPrepare(pMnode, pTrans));
@ -1409,7 +1419,7 @@ END:
return code;
}
int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topicName) {
int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topicName, bool force) {
if (pMnode == NULL || pTrans == NULL || topicName == NULL) return TSDB_CODE_INVALID_PARA;
SSdb *pSdb = pMnode->pSdb;
int32_t code = 0;
@ -1428,7 +1438,7 @@ int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topicName)
}
// iter all vnode to delete handle
if (taosHashGetSize(pSub->consumerHash) != 0) {
if (!force && taosHashGetSize(pSub->consumerHash) != 0) {
code = TSDB_CODE_MND_IN_REBALANCE;
goto END;
}

View File

@ -650,7 +650,7 @@ bool checkTopic(SArray *topics, char *topicName){
return false;
}
static int32_t mndCheckConsumerByTopic(SMnode *pMnode, STrans *pTrans, char *topicName){
static int32_t mndCheckConsumerByTopic(SMnode *pMnode, STrans *pTrans, char *topicName, bool deleteConsumer){
if (pMnode == NULL || pTrans == NULL || topicName == NULL) {
return TSDB_CODE_INVALID_MSG;
}
@ -658,24 +658,34 @@ static int32_t mndCheckConsumerByTopic(SMnode *pMnode, STrans *pTrans, char *top
SSdb *pSdb = pMnode->pSdb;
void *pIter = NULL;
SMqConsumerObj *pConsumer = NULL;
SMqConsumerObj *pConsumerNew = NULL;
while (1) {
pIter = sdbFetch(pSdb, SDB_CONSUMER, pIter, (void **)&pConsumer);
if (pIter == NULL) {
break;
}
bool found = checkTopic(pConsumer->assignedTopics, topicName);
if (found){
mError("topic:%s, failed to drop since subscribed by consumer:0x%" PRIx64 ", in consumer group %s",
topicName, pConsumer->consumerId, pConsumer->cgroup);
code = TSDB_CODE_MND_TOPIC_SUBSCRIBED;
goto END;
if (deleteConsumer) {
MND_TMQ_RETURN_CHECK(tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup, -1, NULL, NULL, &pConsumerNew));
MND_TMQ_RETURN_CHECK(mndSetConsumerDropLogs(pTrans, pConsumerNew));
tDeleteSMqConsumerObj(pConsumerNew);
pConsumerNew = NULL;
} else {
bool found = checkTopic(pConsumer->assignedTopics, topicName);
if (found){
mError("topic:%s, failed to drop since subscribed by consumer:0x%" PRIx64 ", in consumer group %s",
topicName, pConsumer->consumerId, pConsumer->cgroup);
code = TSDB_CODE_MND_TOPIC_SUBSCRIBED;
goto END;
}
}
sdbRelease(pSdb, pConsumer);
}
END:
tDeleteSMqConsumerObj(pConsumerNew);
sdbRelease(pSdb, pConsumer);
sdbCancelFetch(pSdb, pIter);
return code;
@ -760,8 +770,8 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
MND_TMQ_RETURN_CHECK(mndCheckTopicPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_TOPIC, pTopic));
MND_TMQ_RETURN_CHECK(mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_READ_DB, pTopic->db));
MND_TMQ_RETURN_CHECK(mndCheckConsumerByTopic(pMnode, pTrans, dropReq.name));
MND_TMQ_RETURN_CHECK(mndDropSubByTopic(pMnode, pTrans, dropReq.name));
MND_TMQ_RETURN_CHECK(mndCheckConsumerByTopic(pMnode, pTrans, dropReq.name, dropReq.force));
MND_TMQ_RETURN_CHECK(mndDropSubByTopic(pMnode, pTrans, dropReq.name, dropReq.force));
if (pTopic->ntbUid != 0) {
MND_TMQ_RETURN_CHECK(mndDropCheckInfoByTopic(pMnode, pTrans, pTopic));

View File

@ -1945,7 +1945,7 @@ void mndTransExecuteImp(SMnode *pMnode, STrans *pTrans, bool topHalf) {
bool continueExec = true;
while (continueExec) {
mInfo("trans:%d, continue to execute stage:%s in %s, createTime:%" PRId64 "", pTrans->id,
mInfo("trans:%d, continue to execute stage:%s in %s, createTime:%" PRId64, pTrans->id,
mndTransStr(pTrans->stage), mndStrExecutionContext(topHalf), pTrans->createdTime);
pTrans->lastExecTime = taosGetTimestampMs();
switch (pTrans->stage) {

View File

@ -338,7 +338,7 @@ int64_t mndGetIpWhiteVer(SMnode *pMnode) {
if (mndEnableIpWhiteList(pMnode) == 0 || tsEnableWhiteList == false) {
ver = 0;
}
mDebug("ip-white-list on mnode ver: %" PRId64 "", ver);
mDebug("ip-white-list on mnode ver: %" PRId64, ver);
return ver;
}

View File

@ -157,7 +157,7 @@ int32_t tqSetDstTableDataPayload(uint64_t suid, const STSchema* pTSchema, int32_
int32_t doMergeExistedRows(SSubmitTbData* pExisted, const SSubmitTbData* pNew, const char* id);
int32_t buildAutoCreateTableReq(const char* stbFullName, int64_t suid, int32_t numOfCols, SSDataBlock* pDataBlock,
SArray* pTagArray, bool newSubTableRule, SVCreateTbReq** pReq);
SArray* pTagArray, bool newSubTableRule, SVCreateTbReq** pReq, const char* id);
int32_t tqExtractDropCtbDataBlock(const void* data, int32_t len, int64_t ver, void** pRefBlock, int32_t type);
// tq send notifications

View File

@ -962,7 +962,7 @@ int32_t tsdbCacheDeleteLastrow(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
int32_t tsdbCacheDeleteLast(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
int32_t tsdbCacheDelete(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
int32_t tsdbGetS3Size(STsdb *tsdb, int64_t *size);
int32_t tsdbGetFsSize(STsdb *tsdb, SDbSizeStatisInfo *pInfo);
// ========== inline functions ==========
static FORCE_INLINE int32_t tsdbKeyCmprFn(const void *p1, const void *p2) {

View File

@ -32,12 +32,12 @@ extern "C" {
#define vDebug(...) do { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND DEBUG ", DEBUG_DEBUG, vDebugFlag, __VA_ARGS__); }} while(0)
#define vTrace(...) do { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND TRACE ", DEBUG_TRACE, vDebugFlag, __VA_ARGS__); }} while(0)
#define vGTrace(param, ...) do { if (vDebugFlag & DEBUG_TRACE) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vTrace(param ", QID:%s", __VA_ARGS__, buf);}} while(0)
#define vGFatal(param, ...) do { if (vDebugFlag & DEBUG_FATAL) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vFatal(param ", QID:%s", __VA_ARGS__, buf);}} while(0)
#define vGError(param, ...) do { if (vDebugFlag & DEBUG_ERROR) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vError(param ", QID:%s", __VA_ARGS__, buf);}} while(0)
#define vGWarn(param, ...) do { if (vDebugFlag & DEBUG_WARN) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vWarn(param ", QID:%s", __VA_ARGS__, buf);}} while(0)
#define vGInfo(param, ...) do { if (vDebugFlag & DEBUG_INFO) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vInfo(param ", QID:%s", __VA_ARGS__, buf);}} while(0)
#define vGDebug(param, ...) do { if (vDebugFlag & DEBUG_DEBUG) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vDebug(param ", QID:%s", __VA_ARGS__, buf);}} while(0)
#define vGTrace(trace, param, ...) do { if (vDebugFlag & DEBUG_TRACE) { vTrace(param ", QID:0x%" PRIx64 ":0x%" PRIx64, __VA_ARGS__, (trace) ? (trace)->rootId : 0, (trace) ? (trace)->msgId : 0);}} while(0)
#define vGFatal(trace, param, ...) do { if (vDebugFlag & DEBUG_FATAL) { vFatal(param ", QID:0x%" PRIx64 ":0x%" PRIx64, __VA_ARGS__, (trace) ? (trace)->rootId : 0, (trace) ? (trace)->msgId : 0);}} while(0)
#define vGError(trace, param, ...) do { if (vDebugFlag & DEBUG_ERROR) { vError(param ", QID:0x%" PRIx64 ":0x%" PRIx64, __VA_ARGS__, (trace) ? (trace)->rootId : 0, (trace) ? (trace)->msgId : 0);}} while(0)
#define vGWarn(trace, param, ...) do { if (vDebugFlag & DEBUG_WARN) { vWarn(param ", QID:0x%" PRIx64 ":0x%" PRIx64, __VA_ARGS__, (trace) ? (trace)->rootId : 0, (trace) ? (trace)->msgId : 0);}} while(0)
#define vGInfo(trace, param, ...) do { if (vDebugFlag & DEBUG_INFO) { vInfo(param ", QID:0x%" PRIx64 ":0x%" PRIx64, __VA_ARGS__, (trace) ? (trace)->rootId : 0, (trace) ? (trace)->msgId : 0);}} while(0)
#define vGDebug(trace, param, ...) do { if (vDebugFlag & DEBUG_DEBUG) { vDebug(param ", QID:0x%" PRIx64 ":0x%" PRIx64, __VA_ARGS__, (trace) ? (trace)->rootId : 0, (trace) ? (trace)->msgId : 0);}} while(0)
// clang-format on

View File

@ -48,7 +48,7 @@ int meteEncodeColRefEntry(SEncoder *pCoder, const SMetaEntry *pME) {
const SColRefWrapper *pw = &pME->colRef;
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->nCols));
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->version));
uDebug("encode cols:%d", pw->nCols);
uTrace("encode cols:%d", pw->nCols);
for (int32_t i = 0; i < pw->nCols; i++) {
SColRef *p = &pw->pColRef[i];
@ -171,7 +171,7 @@ int meteEncodeColCmprEntry(SEncoder *pCoder, const SMetaEntry *pME) {
const SColCmprWrapper *pw = &pME->colCmpr;
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->nCols));
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->version));
uDebug("encode cols:%d", pw->nCols);
uTrace("encode cols:%d", pw->nCols);
for (int32_t i = 0; i < pw->nCols; i++) {
SColCmpr *p = &pw->pColCmpr[i];

View File

@ -2515,8 +2515,8 @@ int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry) {
if (TSDB_CODE_SUCCESS == code) {
pMeta->changed = true;
metaDebug("vgId:%d, %s success, version:%" PRId64 " type:%d uid:%" PRId64 " name:%s", vgId, __func__,
pEntry->version, pEntry->type, pEntry->uid, pEntry->type > 0 ? pEntry->name : "");
metaDebug("vgId:%d, index:%" PRId64 ", handle meta entry success, type:%d tb:%s uid:%" PRId64, vgId, pEntry->version,
pEntry->type, pEntry->type > 0 ? pEntry->name : "", pEntry->uid);
} else {
metaErr(vgId, code);
}

View File

@ -1524,7 +1524,7 @@ int32_t metaGetTableTagsByUids(void *pVnode, int64_t suid, SArray *uidList) {
memcpy(p->pTagVal, val, len);
tdbFree(val);
} else {
metaError("vgId:%d, failed to table tags, suid: %" PRId64 ", uid: %" PRId64 "", TD_VID(pMeta->pVnode), suid,
metaError("vgId:%d, failed to table tags, suid: %" PRId64 ", uid: %" PRId64, TD_VID(pMeta->pVnode), suid,
p->uid);
}
}

View File

@ -381,8 +381,8 @@ static int32_t metaCreateChildTable(SMeta *pMeta, int64_t version, SVCreateTbReq
// handle entry
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, child table:%s uid %" PRId64 " suid:%" PRId64 " is created, version:%" PRId64,
TD_VID(pMeta->pVnode), pReq->name, pReq->uid, pReq->ctb.suid, version);
metaInfo("vgId:%d, index:%" PRId64 ", child table is created, tb:%s uid:%" PRId64 " suid:%" PRId64,
TD_VID(pMeta->pVnode), version, pReq->name, pReq->uid, pReq->ctb.suid);
} else {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s suid:%" PRId64 " version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name,
@ -493,8 +493,8 @@ static int32_t metaCreateNormalTable(SMeta *pMeta, int64_t version, SVCreateTbRe
// handle entry
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, normal table:%s uid %" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
pReq->uid, version);
metaInfo("vgId:%d, index:%" PRId64 ", normal table is created, tb:%s uid:%" PRId64, TD_VID(pMeta->pVnode), version,
pReq->name, pReq->uid);
} else {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
@ -557,8 +557,8 @@ static int32_t metaCreateVirtualNormalTable(SMeta *pMeta, int64_t version, SVCre
// handle entry
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, normal table:%s uid %" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
pReq->uid, version);
metaInfo("vgId:%d, index:%" PRId64 ", virtual normal table is created, tb:%s uid:%" PRId64, TD_VID(pMeta->pVnode),
version, pReq->name, pReq->uid);
} else {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
@ -625,8 +625,8 @@ static int32_t metaCreateVirtualChildTable(SMeta *pMeta, int64_t version, SVCrea
// handle entry
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, normal table:%s uid %" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
pReq->uid, version);
metaInfo("vgId:%d, index:%" PRId64 ", virtual child table is created, tb:%s uid:%" PRId64, TD_VID(pMeta->pVnode),
version, pReq->name, pReq->uid);
} else {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);

View File

@ -457,7 +457,7 @@ static int32_t tdRsmaStopExecutor(const SSma *pSma) {
for (int32_t i = 0; i < tsNumOfVnodeRsmaThreads; ++i) {
if (taosCheckPthreadValid(pthread[i])) {
smaDebug("vgId:%d, start to join pthread for rsma:%" PRId64 "", SMA_VID(pSma), taosGetPthreadId(pthread[i]));
smaDebug("vgId:%d, start to join pthread for rsma:%" PRId64, SMA_VID(pSma), taosGetPthreadId(pthread[i]));
(void)taosThreadJoin(pthread[i], NULL);
}
}

View File

@ -196,7 +196,8 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
int32_t cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1;
TAOS_CHECK_EXIT(buildAutoCreateTableReq(stbFullName, suid, cid, pDataBlock, tagArray, true, &tbData.pCreateTbReq));
TAOS_CHECK_EXIT(buildAutoCreateTableReq(stbFullName, suid, cid, pDataBlock, tagArray, true, &tbData.pCreateTbReq,
""));
{
uint64_t groupId = pDataBlock->info.id.groupId;

View File

@ -736,7 +736,7 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
req.vgId, req.subKey, req.newConsumerId, req.oldConsumerId);
}
if (req.newConsumerId == -1) {
tqError("vgId:%d, tq invalid rebalance request, new consumerId %" PRId64 "", req.vgId, req.newConsumerId);
tqError("vgId:%d, tq invalid rebalance request, new consumerId %" PRId64, req.vgId, req.newConsumerId);
ret = TSDB_CODE_INVALID_PARA;
goto end;
}
@ -1078,11 +1078,19 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
// 1. get the related stream task
code = streamMetaAcquireTask(pMeta, pTask->streamTaskId.streamId, pTask->streamTaskId.taskId, &pStreamTask);
if (pStreamTask == NULL) {
tqError("failed to find s-task:0x%" PRIx64 ", it may have been destroyed, drop related fill-history task:%s",
pTask->streamTaskId.taskId, pTask->id.idStr);
tqDebug("s-task:%s fill-history task set status to be dropping", id);
code = streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id, 0);
int32_t ret = streamMetaAcquireTaskUnsafe(pMeta, &pTask->streamTaskId, &pStreamTask);
if (ret == 0 && pStreamTask != NULL) {
tqWarn("s-task:0x%" PRIx64 " stopped, not ready for related task:%s scan-history work, do nothing",
pTask->streamTaskId.taskId, pTask->id.idStr);
streamMetaReleaseTask(pMeta, pStreamTask);
} else {
tqError("failed to find s-task:0x%" PRIx64 ", it may have been destroyed, drop related fill-history task:%s",
pTask->streamTaskId.taskId, pTask->id.idStr);
tqDebug("s-task:%s fill-history task set status to be dropping", id);
code = streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id, 0);
}
atomic_store_32(&pTask->status.inScanHistorySentinel, 0);
streamMetaReleaseTask(pMeta, pTask);
@ -1371,10 +1379,24 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
int32_t tqProcessTaskCheckpointReadyMsg(STQ* pTq, SRpcMsg* pMsg) {
int32_t vgId = TD_VID(pTq->pVnode);
SStreamCheckpointReadyMsg* pReq = (SStreamCheckpointReadyMsg*)pMsg->pCont;
if (!vnodeIsRoleLeader(pTq->pVnode)) {
tqError("vgId:%d not leader, ignore the retrieve checkpoint-trigger msg from 0x%x", vgId,
(int32_t)pReq->downstreamTaskId);
char* msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
int32_t len = pMsg->contLen - sizeof(SMsgHead);
int32_t code = 0;
SDecoder decoder;
SStreamCheckpointReadyMsg req = {0};
tDecoderInit(&decoder, (uint8_t*)msg, len);
if (tDecodeStreamCheckpointReadyMsg(&decoder, &req) < 0) {
code = TSDB_CODE_MSG_DECODE_ERROR;
tDecoderClear(&decoder);
return code;
}
tDecoderClear(&decoder);
tqError("vgId:%d not leader, s-task:0x%x ignore the retrieve checkpoint-trigger msg from s-task:0x%x vgId:%d", vgId,
req.upstreamTaskId, req.downstreamTaskId, req.downstreamNodeId);
return TSDB_CODE_STREAM_NOT_LEADER;
}

View File

@ -565,7 +565,7 @@ bool tqNextBlockImpl(STqReader* pReader, const char* idstr) {
void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t));
TSDB_CHECK_CONDITION(ret == NULL, code, lino, END, true);
tqTrace("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid);
tqTrace("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64, pReader->nextBlk, blockSz, uid);
pReader->nextBlk++;
}
@ -593,7 +593,7 @@ bool tqNextDataBlockFilterOut(STqReader* pReader, SHashObj* filterOutUids) {
uid = pSubmitTbData->uid;
void* ret = taosHashGet(filterOutUids, &pSubmitTbData->uid, sizeof(int64_t));
TSDB_CHECK_NULL(ret, code, lino, END, true);
tqTrace("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid);
tqTrace("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64, pReader->nextBlk, blockSz, uid);
pReader->nextBlk++;
}
tqReaderClearSubmitMsg(pReader);
@ -1848,7 +1848,7 @@ bool tqNextVTableSourceBlockImpl(STqReader* pReader, const char* idstr) {
return true;
}
}
tqTrace("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz,
tqTrace("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64, pReader->nextBlk, blockSz,
pTbUid);
pReader->nextBlk++;
}

View File

@ -39,7 +39,7 @@ static int32_t initCreateTableMsg(SVCreateTbReq* pCreateTableReq, uint64_t suid,
int32_t numOfTags);
static int32_t createDefaultTagColName(SArray** pColNameList);
static int32_t setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDataBlock,
const char* stbFullName, int64_t gid, bool newSubTableRule);
const char* stbFullName, int64_t gid, bool newSubTableRule, const char* id);
static int32_t doCreateSinkTableInfo(const char* pDstTableName, STableSinkInfo** pInfo);
static int32_t doPutSinkTableInfoIntoCache(SSHashObj* pSinkTableMap, STableSinkInfo* pTableSinkInfo, uint64_t groupId,
const char* id);
@ -260,7 +260,7 @@ int32_t createDefaultTagColName(SArray** pColNameList) {
}
int32_t setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDataBlock, const char* stbFullName,
int64_t gid, bool newSubTableRule) {
int64_t gid, bool newSubTableRule, const char* id) {
if (pDataBlock->info.parTbName[0]) {
if (newSubTableRule && !isAutoTableName(pDataBlock->info.parTbName) &&
!alreadyAddGroupId(pDataBlock->info.parTbName, gid) && gid != 0 && stbFullName) {
@ -274,16 +274,17 @@ int32_t setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock*
if (code != TSDB_CODE_SUCCESS) {
return code;
}
// tqDebug("gen name from:%s", pDataBlock->info.parTbName);
tqDebug("s-task:%s gen name from:%s blockdata", id, pDataBlock->info.parTbName);
} else {
pCreateTableReq->name = taosStrdup(pDataBlock->info.parTbName);
if (pCreateTableReq->name == NULL) {
return terrno;
}
// tqDebug("copy name:%s", pDataBlock->info.parTbName);
tqDebug("s-task:%s copy name:%s from blockdata", id, pDataBlock->info.parTbName);
}
} else {
int32_t code = buildCtbNameByGroupId(stbFullName, gid, &pCreateTableReq->name);
tqDebug("s-task:%s no name in blockdata, auto-created table name:%s", id, pCreateTableReq->name);
return code;
}
@ -389,7 +390,8 @@ static int32_t doBuildAndSendCreateTableMsg(SVnode* pVnode, char* stbFullName, S
}
}
code = setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, gid, IS_NEW_SUBTB_RULE(pTask));
code = setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, gid, IS_NEW_SUBTB_RULE(pTask),
pTask->id.idStr);
if (code) {
goto _end;
}
@ -641,7 +643,7 @@ bool isValidDstChildTable(SMetaReader* pReader, int32_t vgId, const char* ctbNam
}
int32_t buildAutoCreateTableReq(const char* stbFullName, int64_t suid, int32_t numOfCols, SSDataBlock* pDataBlock,
SArray* pTagArray, bool newSubTableRule, SVCreateTbReq** pReq) {
SArray* pTagArray, bool newSubTableRule, SVCreateTbReq** pReq, const char* id) {
*pReq = NULL;
SVCreateTbReq* pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
@ -674,7 +676,8 @@ int32_t buildAutoCreateTableReq(const char* stbFullName, int64_t suid, int32_t n
}
// set table name
code = setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, pDataBlock->info.id.groupId, newSubTableRule);
code = setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, pDataBlock->info.id.groupId, newSubTableRule,
id);
if (code) {
return code;
}
@ -1041,7 +1044,7 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
pTableData->flags = SUBMIT_REQ_AUTO_CREATE_TABLE;
code = buildAutoCreateTableReq(stbFullName, suid, pTSchema->numOfCols + 1, pDataBlock, pTagArray,
IS_NEW_SUBTB_RULE(pTask), &pTableData->pCreateTbReq);
IS_NEW_SUBTB_RULE(pTask), &pTableData->pCreateTbReq, id);
taosArrayDestroy(pTagArray);
if (code) {
@ -1164,8 +1167,8 @@ void tqSinkDataIntoDstTable(SStreamTask* pTask, void* vnode, void* data) {
bool onlySubmitData = hasOnlySubmitData(pBlocks, numOfBlocks);
if (!onlySubmitData || pTask->subtableWithoutMd5 == 1) {
tqDebug("vgId:%d, s-task:%s write %d stream resBlock(s) into table, has delete block, submit one-by-one", vgId, id,
numOfBlocks);
tqDebug("vgId:%d, s-task:%s write %d stream resBlock(s) into table, has other type block, submit one-by-one", vgId,
id, numOfBlocks);
for (int32_t i = 0; i < numOfBlocks; ++i) {
if (streamTaskShouldStop(pTask)) {

View File

@ -87,7 +87,7 @@ static void doStartScanWal(void* param, void* tmrId) {
tmr_h pTimer = NULL;
SBuildScanWalMsgParam* pParam = (SBuildScanWalMsgParam*)param;
tqDebug("start to do scan wal in tmr, metaRid:%" PRId64, pParam->metaId);
tqTrace("start to do scan wal in tmr, metaRid:%" PRId64, pParam->metaId);
SStreamMeta* pMeta = taosAcquireRef(streamMetaRefPool, pParam->metaId);
if (pMeta == NULL) {
@ -173,7 +173,7 @@ static void doStartScanWal(void* param, void* tmrId) {
_end:
streamTmrStart(doStartScanWal, SCAN_WAL_IDLE_DURATION, pParam, pTimer, &pMeta->scanInfo.scanTimer, vgId, "scan-wal");
tqDebug("vgId:%d try scan-wal will start in %dms", vgId, SCAN_WAL_IDLE_DURATION*SCAN_WAL_WAIT_COUNT);
tqTrace("vgId:%d try scan-wal will start in %dms", vgId, SCAN_WAL_IDLE_DURATION*SCAN_WAL_WAIT_COUNT);
code = taosReleaseRef(streamMetaRefPool, pParam->metaId);
if (code) {

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