Merge remote-tracking branch 'origin/3.0' into feat/TD-30268
This commit is contained in:
commit
371094cc13
|
@ -0,0 +1,58 @@
|
|||
name: TaosKeeper CI
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- tools/keeper/**
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Run unit tests
|
||||
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.18
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
sudo apt update -y
|
||||
sudo apt install -y build-essential cmake libgeos-dev
|
||||
|
||||
- name: Install TDengine
|
||||
run: |
|
||||
mkdir debug
|
||||
cd debug
|
||||
cmake .. -DBUILD_HTTP=false -DBUILD_JDBC=false -DBUILD_TOOLS=false -DBUILD_TEST=off -DBUILD_KEEPER=true -DBUILD_DEPENDENCY_TESTS=false
|
||||
make -j 4
|
||||
sudo make install
|
||||
which taosd
|
||||
which taosadapter
|
||||
which taoskeeper
|
||||
|
||||
- name: Start taosd
|
||||
run: |
|
||||
cp /etc/taos/taos.cfg ./
|
||||
sudo echo "supportVnodes 256" >> taos.cfg
|
||||
nohup sudo taosd -c taos.cfg &
|
||||
|
||||
- name: Start taosadapter
|
||||
run: nohup sudo taosadapter &
|
||||
|
||||
- name: Run tests with coverage
|
||||
working-directory: tools/keeper
|
||||
run: |
|
||||
go mod tidy
|
||||
sudo go test -v -ldflags="-X 'github.com/taosdata/taoskeeper/version.IsEnterprise=true'" -coverpkg=./... -coverprofile=coverage.out ./...
|
||||
go tool cover -func=coverage.out
|
||||
|
||||
- name: Clean up
|
||||
if: always()
|
||||
run: |
|
||||
if pgrep taosd; then sudo pkill taosd; fi
|
||||
if pgrep taosadapter; then sudo pkill taosadapter; fi
|
|
@ -159,4 +159,6 @@ pcre2.h
|
|||
zconf.h
|
||||
version.h
|
||||
geos_c.h
|
||||
|
||||
source/libs/parser/src/sql.c
|
||||
include/common/ttokenauto.h
|
||||
!packaging/smokeTest/pytest_require.txt
|
||||
|
|
|
@ -348,7 +348,7 @@ TDengine 提供了丰富的应用程序开发接口,其中包括 C/C++、Java
|
|||
|
||||
# 成为社区贡献者
|
||||
|
||||
点击 [这里](https://www.taosdata.com/cn/contributor/),了解如何成为 TDengine 的贡献者。
|
||||
点击 [这里](https://www.taosdata.com/contributor),了解如何成为 TDengine 的贡献者。
|
||||
|
||||
# 加入技术交流群
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
set(CMAKE_VERBOSE_MAKEFILE FALSE)
|
||||
set(TD_BUILD_TAOSA_INTERNAL FALSE)
|
||||
set(TD_BUILD_KEEPER_INTERNAL FALSE)
|
||||
|
||||
# set output directory
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/build/lib)
|
||||
|
@ -57,6 +58,19 @@ IF(TD_BUILD_HTTP)
|
|||
ADD_DEFINITIONS(-DHTTP_EMBEDDED)
|
||||
ENDIF()
|
||||
|
||||
IF("${BUILD_KEEPER}" STREQUAL "")
|
||||
SET(TD_BUILD_KEEPER FALSE)
|
||||
ELSEIF(${BUILD_KEEPER} MATCHES "false")
|
||||
SET(TD_BUILD_KEEPER FALSE)
|
||||
ELSEIF(${BUILD_KEEPER} MATCHES "true")
|
||||
SET(TD_BUILD_KEEPER TRUE)
|
||||
ELSEIF(${BUILD_KEEPER} MATCHES "internal")
|
||||
SET(TD_BUILD_KEEPER FALSE)
|
||||
SET(TD_BUILD_KEEPER_INTERNAL TRUE)
|
||||
ELSE()
|
||||
SET(TD_BUILD_KEEPER FALSE)
|
||||
ENDIF()
|
||||
|
||||
IF("${BUILD_TOOLS}" STREQUAL "")
|
||||
IF(TD_LINUX)
|
||||
IF(TD_ARM_32)
|
||||
|
@ -177,48 +191,11 @@ ELSE()
|
|||
SET(COMPILER_SUPPORT_AVX512VL false)
|
||||
ELSE()
|
||||
CHECK_C_COMPILER_FLAG("-mfma" COMPILER_SUPPORT_FMA)
|
||||
CHECK_C_COMPILER_FLAG("-mavx" COMPILER_SUPPORT_AVX)
|
||||
CHECK_C_COMPILER_FLAG("-mavx2" COMPILER_SUPPORT_AVX2)
|
||||
CHECK_C_COMPILER_FLAG("-mavx512f" COMPILER_SUPPORT_AVX512F)
|
||||
CHECK_C_COMPILER_FLAG("-mavx512vbmi" COMPILER_SUPPORT_AVX512BMI)
|
||||
CHECK_C_COMPILER_FLAG("-mavx512vl" COMPILER_SUPPORT_AVX512VL)
|
||||
|
||||
INCLUDE(CheckCSourceRuns)
|
||||
SET(CMAKE_REQUIRED_FLAGS "-mavx")
|
||||
check_c_source_runs("
|
||||
#include <immintrin.h>
|
||||
int main() {
|
||||
__m256d a, b, c;
|
||||
double buf[4] = {0};
|
||||
a = _mm256_loadu_pd(buf);
|
||||
b = _mm256_loadu_pd(buf);
|
||||
c = _mm256_add_pd(a, b);
|
||||
_mm256_storeu_pd(buf, c);
|
||||
for (int i = 0; i < sizeof(buf) / sizeof(buf[0]); ++i) {
|
||||
IF (buf[i] != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
" COMPILER_SUPPORT_AVX)
|
||||
|
||||
SET(CMAKE_REQUIRED_FLAGS "-mavx2")
|
||||
check_c_source_runs("
|
||||
#include <immintrin.h>
|
||||
int main() {
|
||||
__m256i a, b, c;
|
||||
int buf[8] = {0};
|
||||
a = _mm256_loadu_si256((__m256i *)buf);
|
||||
b = _mm256_loadu_si256((__m256i *)buf);
|
||||
c = _mm256_and_si256(a, b);
|
||||
_mm256_storeu_si256((__m256i *)buf, c);
|
||||
for (int i = 0; i < sizeof(buf) / sizeof(buf[0]); ++i) {
|
||||
IF (buf[i] != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
" COMPILER_SUPPORT_AVX2)
|
||||
ENDIF()
|
||||
|
||||
IF(COMPILER_SUPPORT_SSE42)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# lemon
|
||||
|
||||
ExternalProject_Add(
|
||||
lemon
|
||||
SOURCE_DIR ${TD_CONTRIB_DIR}/lemon
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND "${C_COMPILER_LEMON}" -o ${TD_CONTRIB_DIR}/lemon/lemon ${TD_CONTRIB_DIR}/lemon/lemon.c
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_IN_SOURCE 1
|
||||
BUILD_ALWAYS 1
|
||||
)
|
|
@ -184,6 +184,17 @@ if(${BUILD_PCRE2})
|
|||
cat("${TD_SUPPORT_DIR}/pcre2_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
endif()
|
||||
|
||||
find_program(C_COMPILER_LEMON NAMES gcc)
|
||||
if(C_COMPILER_LEMON)
|
||||
message(STATUS "LEMON C compiler: ${C_COMPILER_LEMON}")
|
||||
else()
|
||||
set(C_COMPILER_LEMON ${CMAKE_C_COMPILER})
|
||||
message(STATUS "LEMON C compiler: ${C_COMPILER_LEMON}")
|
||||
endif()
|
||||
|
||||
# lemon
|
||||
cat("${TD_SUPPORT_DIR}/lemon_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
|
||||
# download dependencies
|
||||
configure_file(${CONTRIB_TMP_FILE} "${TD_CONTRIB_DIR}/deps-download/CMakeLists.txt")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
|
||||
|
@ -261,11 +272,19 @@ if(${TD_DARWIN})
|
|||
endif(${TD_DARWIN})
|
||||
|
||||
add_subdirectory(zlib EXCLUDE_FROM_ALL)
|
||||
|
||||
if(${TD_DARWIN})
|
||||
target_compile_options(zlibstatic PRIVATE -Wno-error=deprecated-non-prototype)
|
||||
endif()
|
||||
target_include_directories(
|
||||
zlibstatic
|
||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/zlib
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/zlib
|
||||
)
|
||||
|
||||
if(${TD_DARWIN})
|
||||
target_compile_options(zlib PRIVATE -Wno-error=deprecated-non-prototype)
|
||||
endif()
|
||||
target_include_directories(
|
||||
zlib
|
||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/zlib
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -46,7 +46,7 @@ For more details on features, please read through the entire documentation.
|
|||
|
||||
By making full use of [characteristics of time series data](https://tdengine.com/characteristics-of-time-series-data/), TDengine differentiates itself from other time series databases with the following advantages.
|
||||
|
||||
- **[High-Performance](https://tdengine.com/high-performance/)**: TDengine is the only time-series database to solve the high cardinality issue to support billions of data collection points while out performing other time-series databases for data ingestion, querying and data compression.
|
||||
- **[High-Performance](https://tdengine.com/high-performance/)**: TDengine is the only time-series database to solve the high cardinality issue to support billions of data collection points while outperforming other time-series databases for data ingestion, querying and data compression.
|
||||
|
||||
- **[Simplified Solution](https://tdengine.com/comprehensive-industrial-data-solution/)**: Through built-in caching, stream processing and data subscription features, TDengine provides a simplified solution for time-series data processing. It reduces system design complexity and operation costs significantly.
|
||||
|
||||
|
|
|
@ -75,9 +75,9 @@ taos>
|
|||
|
||||
## TDegnine Graphic User Interface
|
||||
|
||||
From TDengine 3.3.0.0, there is a new componenet called `taos-explorer` added in the TDengine docker image. You can use it to manage the databases, super tables, child tables, and data in your TDengine system. There are also some features only available in TDengine Enterprise Edition, please contact TDengine sales team in case you need these features.
|
||||
From TDengine 3.3.0.0, there is a new component called `taos-explorer` added in the TDengine docker image. You can use it to manage the databases, super tables, child tables, and data in your TDengine system. There are also some features only available in TDengine Enterprise Edition, please contact TDengine sales team in case you need these features.
|
||||
|
||||
To use taos-explorer in the container, you need to access the host port mapped from container port 6060. Assuming the host name is abc.com, and the port used on host is 6060, you need to access `http://abc.com:6060`. taos-explorer uses port 6060 by default in the container. When you use it the first time, you need to register with your enterprise email, then can logon using your user name and password in the TDengine database management system.
|
||||
To use taos-explorer in the container, you need to access the host port mapped from container port 6060. Assuming the host name is abc.com, and the port used on host is 6060, you need to access `http://abc.com:6060`. taos-explorer uses port 6060 by default in the container. The default username and password to log in to the TDengine Database Management System is "root/taosdata".
|
||||
|
||||
## Test data insert performance
|
||||
|
||||
|
|
|
@ -364,6 +364,9 @@ The configuration parameters for specifying super table tag columns and data col
|
|||
- **min**: The minimum value of the column/label of the data type. The generated value will equal or large than the minimum value.
|
||||
|
||||
- **max**: The maximum value of the column/label of the data type. The generated value will less than the maximum value.
|
||||
|
||||
- **scalingFactor**: Floating-point precision enhancement factor, which takes effect only when the data type is float/double. It has a valid range of positive integers from 1 to 1,000,000. It is used to enhance the precision of generated floating-point numbers, particularly when the min or max values are small. This property enhances the precision after the decimal point by powers of 10: scalingFactor of 10 indicates an enhancement of 1 decimal precision, 100 indicates an enhancement of 2 decimal precision, and so on.
|
||||
|
||||
- **fun**: This column of data is filled with functions. Currently, only the sin and cos functions are supported. The input parameter is the timestamp and converted to an angle value. The conversion formula is: angle x=input time column ts value % 360. At the same time, it supports coefficient adjustment and random fluctuation factor adjustment, presented in a fixed format expression, such as fun="10\*sin(x)+100\*random(5)", where x represents the angle, ranging from 0 to 360 degrees, and the growth step size is consistent with the time column step size. 10 represents the coefficient of multiplication, 100 represents the coefficient of addition or subtraction, and 5 represents the fluctuation range within a random range of 5%. The currently supported data types are int, bigint, float, and double. Note: The expression is fixed and cannot be reversed.
|
||||
|
||||
- **values**: The value field of the nchar/binary column/label, which will be chosen randomly from the values.
|
||||
|
|
|
@ -1187,7 +1187,7 @@ CSUM(expr)
|
|||
### DERIVATIVE
|
||||
|
||||
```sql
|
||||
DERIVATIVE(expr, time_inerval, ignore_negative)
|
||||
DERIVATIVE(expr, time_interval, ignore_negative)
|
||||
|
||||
ignore_negative: {
|
||||
0
|
||||
|
|
|
@ -80,7 +80,7 @@ These pseudocolumns occur after the aggregation clause.
|
|||
`FILL` clause is used to specify how to fill when there is data missing in any window, including:
|
||||
|
||||
1. NONE: No fill (the default fill mode)
|
||||
2. VALUE: Fill with a fixed value, which should be specified together, for example `FILL(VALUE, 1.23)` Note: The value filled depends on the data type. For example, if you run FILL(VALUE 1.23) on an integer column, the value 1 is filled. If multiple columns in select list need to be filled, then in the fill clause there must be a fill value for each of these columns, for example, `SELECT _wstart, min(c1), max(c1) FROM ... FILL(VALUE, 0, 0)`.
|
||||
2. VALUE: Fill with a fixed value, which should be specified together, for example `FILL(VALUE, 1.23)` Note: The value filled depends on the data type. For example, if you run FILL(VALUE 1.23) on an integer column, the value 1 is filled. If multiple columns in select list need to be filled, then in the fill clause there must be a fill value for each of these columns, for example, `SELECT _wstart, min(c1), max(c1) FROM ... FILL(VALUE, 0, 0)`. Note that only exprs in select list that contains normal cols need to specify fill value, exprs like `_wstart`, `_wend`, `_wduration`, `_wstart + 1a`, `now`, `1+1`, partition keys like tbname(when using partition by) don't need to specify fill value. But exprs like `timediff(last(ts), _wstart)` need to specify fill value.
|
||||
3. PREV: Fill with the previous non-NULL value, `FILL(PREV)`
|
||||
4. NULL: Fill with NULL, `FILL(NULL)`
|
||||
5. LINEAR: Fill with the closest non-NULL value, `FILL(LINEAR)`
|
||||
|
|
|
@ -27,11 +27,15 @@ The preceding SQL command shows all dnodes in the cluster with the ID, endpoint,
|
|||
## Delete a DNODE
|
||||
|
||||
```sql
|
||||
DROP DNODE dnode_id
|
||||
DROP DNODE dnode_id [force] [unsafe]
|
||||
```
|
||||
|
||||
Note that deleting a dnode does not stop its process. You must stop the process after the dnode is deleted.
|
||||
|
||||
Only online node is allowed to be deleted. Drop is executed with force option if the offline node need to be deleted.
|
||||
|
||||
Drop is executed with unsafe option if the node with single replica is offline, and the data on it is not able to be restored.
|
||||
|
||||
## Modify Dnode Configuration
|
||||
|
||||
```sql
|
||||
|
|
|
@ -41,7 +41,7 @@ In this article, it specifically refers to the level within the secondary compre
|
|||
### Create Table with Compression
|
||||
|
||||
```sql
|
||||
CREATE [dbname.]tabname (colName colType [ENCODE 'encode_type'] [COMPRESS 'compress_type' [LEVEL 'level'], [, other cerate_definition]...])
|
||||
CREATE [dbname.]tabname (colName colType [ENCODE 'encode_type'] [COMPRESS 'compress_type' [LEVEL 'level'], [, other create_definition]...])
|
||||
```
|
||||
|
||||
**Parameter Description**
|
||||
|
@ -58,7 +58,7 @@ CREATE [dbname.]tabname (colName colType [ENCODE 'encode_type'] [COMPRESS 'compr
|
|||
### Change Compression Method
|
||||
|
||||
```sql
|
||||
ALTER TABLE [db_name.]tabName MODIFY COLUMN colName [ENCODE 'ecode_type'] [COMPRESS 'compress_type'] [LEVEL "high"]
|
||||
ALTER TABLE [db_name.]tabName MODIFY COLUMN colName [ENCODE 'encode_type'] [COMPRESS 'compress_type'] [LEVEL "high"]
|
||||
```
|
||||
|
||||
**Parameter Description**
|
||||
|
|
|
@ -125,7 +125,7 @@ where `TOKEN` is the string after Base64 encoding of `{username}:{password}`, e.
|
|||
Starting from `TDengine 3.0.3.0`, `taosAdapter` provides a configuration parameter `httpCodeServerError` to set whether to return a non-200 http status code when the C interface returns an error
|
||||
|
||||
| **Description** | **httpCodeServerError false** | **httpCodeServerError true** |
|
||||
|--------------------|---------------------------- ------|---------------------------------------|
|
||||
|--------------------|----------------------------------|---------------------------------------|
|
||||
| taos_errno() returns 0 | 200 | 200 |
|
||||
| taos_errno() returns non-0 | 200 (except authentication error) | 500 (except authentication error and 400/502 error) |
|
||||
| Parameter error | 400 (only handle HTTP request URL parameter error) | 400 (handle HTTP request URL parameter error and taosd return error) |
|
||||
|
|
|
@ -701,15 +701,6 @@ The charset that takes effect is UTF-8.
|
|||
| Type | String |
|
||||
| Default Value | _tag_null |
|
||||
|
||||
### smlDataFormat
|
||||
|
||||
| Attribute | Description |
|
||||
| ----------- | ----------------------------------------------------------------------------------- |
|
||||
| Applicable | Client only |
|
||||
| Meaning | Whether schemaless columns are consistently ordered, depat, discarded since 3.0.3.0 |
|
||||
| Value Range | 0: not consistent; 1: consistent. |
|
||||
| Default | 0 |
|
||||
|
||||
### smlTsDefaultName
|
||||
|
||||
| Attribute | Description |
|
||||
|
@ -719,6 +710,16 @@ The charset that takes effect is UTF-8.
|
|||
| Type | String |
|
||||
| Default Value | _ts |
|
||||
|
||||
### smlDot2Underline
|
||||
|
||||
| Attribute | Description |
|
||||
| -------- | -------------------------------------------------------- |
|
||||
| Applicable | Client only |
|
||||
| Meaning | Convert the dot in the supertable name to an underscore |
|
||||
| Type | Bool |
|
||||
| Default Value | true |
|
||||
|
||||
|
||||
## Compress Parameters
|
||||
|
||||
### compressMsgSize
|
||||
|
|
|
@ -4,7 +4,7 @@ sidebar_label: Load Balance
|
|||
description: This document describes how TDengine implements load balancing.
|
||||
---
|
||||
|
||||
The load balance in TDengine is mainly about processing data series data. TDengine employes builtin hash algorithm to distribute all the tables, sub-tables and their data of a database across all the vgroups that belongs to the database. Each table or sub-table can only be handled by a single vgroup, while each vgroup can process multiple table or sub-table.
|
||||
The load balance in TDengine is mainly about processing data series data. TDengine employs builtin hash algorithm to distribute all the tables, sub-tables and their data of a database across all the vgroups that belongs to the database. Each table or sub-table can only be handled by a single vgroup, while each vgroup can process multiple table or sub-table.
|
||||
|
||||
The number of vgroup can be specified when creating a database, using the parameter `vgroups`.
|
||||
|
||||
|
@ -12,10 +12,10 @@ The number of vgroup can be specified when creating a database, using the parame
|
|||
create database db0 vgroups 100;
|
||||
```
|
||||
|
||||
The proper value of `vgroups` depends on available system resources. Assuming there is only one database to be created in the system, then the number of `vgroups` is determined by the available resources from all dnodes. In principle more vgroups can be created if you have more CPU and memory. Disk I/O is another important factor to consider. Once the bottleneck shows on disk I/O, more vgroups may downgrad the system performance significantly. If multiple databases are to be created in the system, then the total number of `vroups` of all the databases are dependent on the available system resources. It needs to be careful to distribute vgroups among these databases, you need to consider the number of tables, data writing frequency, size of each data row for all these databases. A recommended practice is to firstly choose a starting number for `vgroups`, for example double of the number of CPU cores, then try to adjust and optimize system configurations to find the best setting for `vgroups`, then distribute these vgroups among databases.
|
||||
The proper value of `vgroups` depends on available system resources. Assuming there is only one database to be created in the system, then the number of `vgroups` is determined by the available resources from all dnodes. In principle more vgroups can be created if you have more CPU and memory. Disk I/O is another important factor to consider. Once the bottleneck shows on disk I/O, more vgroups may degrade the system performance significantly. If multiple databases are to be created in the system, then the total number of `vgroups` of all the databases are dependent on the available system resources. It needs to be careful to distribute vgroups among these databases, you need to consider the number of tables, data writing frequency, size of each data row for all these databases. A recommended practice is to firstly choose a starting number for `vgroups`, for example double of the number of CPU cores, then try to adjust and optimize system configurations to find the best setting for `vgroups`, then distribute these vgroups among databases.
|
||||
|
||||
Furthermode, TDengine distributes the vgroups of each database equally among all dnodes. In case of replica 3, the distribution is even more complex, TDengine tries its best to prevent any dnode from becoming a bottleneck.
|
||||
Furthermore, TDengine distributes the vgroups of each database equally among all dnodes. In case of replica 3, the distribution is even more complex, TDengine tries its best to prevent any dnode from becoming a bottleneck.
|
||||
|
||||
TDegnine utilizes the above ways to achieve load balance in a cluster, and finally achieve higher throughput.
|
||||
TDengine utilizes the above ways to achieve load balance in a cluster, and finally achieve higher throughput.
|
||||
|
||||
Once the load balance is achieved, after some operations like deleting tables or dropping databases, the load across all dnodes may become imbalanced, the method of rebalance will be provided in later versions. However, even without explicit rebalancing, TDengine will try its best to achieve new balance without manual interfering when a new database is created.
|
||||
|
|
|
@ -7,8 +7,4 @@ java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -data
|
|||
java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable false -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
|
||||
```
|
||||
|
||||
如果发生错误 Exception in thread "main" java.lang.UnsatisfiedLinkError: no taos in java.library.path
|
||||
请检查是否安装 TDengine 客户端安装包或编译 TDengine 安装。如果确定已经安装过还出现这个错误,可以在命令行 java 后加 -Djava.library.path=/usr/lib 来指定寻找共享库的路径。
|
||||
|
||||
|
||||
If you encounter the error Exception in thread "main" `java.lang.UnsatisfiedLinkError: no taos in java.library.path`, please check whether the TDengine client package is installed or TDengine is compiled and installed. If you are sure it is installed and still encounter this error, you can add `-Djava.library.path=/usr/lib` after the `java` command to specify the path to the shared library.
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package com.taos.example;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import com.taosdata.jdbc.tmq.*;
|
||||
import com.taosdata.jdbc.utils.JsonUtil;
|
||||
|
||||
import java.sql.*;
|
||||
import java.time.Duration;
|
||||
|
@ -60,7 +61,7 @@ public class ConsumerLoopFull {
|
|||
// ANCHOR_END: create_consumer
|
||||
}
|
||||
|
||||
public static void pollExample(TaosConsumer<ResultBean> consumer) throws SQLException {
|
||||
public static void pollExample(TaosConsumer<ResultBean> consumer) throws SQLException, JsonProcessingException {
|
||||
// ANCHOR: poll_data_code_piece
|
||||
List<String> topics = Collections.singletonList("topic_meters");
|
||||
try {
|
||||
|
@ -73,7 +74,7 @@ public class ConsumerLoopFull {
|
|||
for (ConsumerRecord<ResultBean> record : records) {
|
||||
ResultBean bean = record.value();
|
||||
// Add your data processing logic here
|
||||
System.out.println("data: " + JSON.toJSONString(bean));
|
||||
System.out.println("data: " + JsonUtil.getObjectMapper().writeValueAsString(bean));
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
|
@ -91,7 +92,7 @@ public class ConsumerLoopFull {
|
|||
// ANCHOR_END: poll_data_code_piece
|
||||
}
|
||||
|
||||
public static void seekExample(TaosConsumer<ResultBean> consumer) throws SQLException {
|
||||
public static void seekExample(TaosConsumer<ResultBean> consumer) throws SQLException, JsonProcessingException {
|
||||
// ANCHOR: consumer_seek
|
||||
List<String> topics = Collections.singletonList("topic_meters");
|
||||
try {
|
||||
|
@ -99,7 +100,7 @@ public class ConsumerLoopFull {
|
|||
consumer.subscribe(topics);
|
||||
System.out.println("Subscribe topics successfully.");
|
||||
Set<TopicPartition> assignment = consumer.assignment();
|
||||
System.out.println("Now assignment: " + JSON.toJSONString(assignment));
|
||||
System.out.println("Now assignment: " + JsonUtil.getObjectMapper().writeValueAsString(assignment));
|
||||
|
||||
ConsumerRecords<ResultBean> records = ConsumerRecords.emptyRecord();
|
||||
// make sure we have got some data
|
||||
|
@ -125,7 +126,7 @@ public class ConsumerLoopFull {
|
|||
}
|
||||
|
||||
|
||||
public static void commitExample(TaosConsumer<ResultBean> consumer) throws SQLException {
|
||||
public static void commitExample(TaosConsumer<ResultBean> consumer) throws SQLException, JsonProcessingException {
|
||||
// ANCHOR: commit_code_piece
|
||||
List<String> topics = Collections.singletonList("topic_meters");
|
||||
try {
|
||||
|
@ -135,7 +136,7 @@ public class ConsumerLoopFull {
|
|||
for (ConsumerRecord<ResultBean> record : records) {
|
||||
ResultBean bean = record.value();
|
||||
// Add your data processing logic here
|
||||
System.out.println("data: " + JSON.toJSONString(bean));
|
||||
System.out.println("data: " + JsonUtil.getObjectMapper().writeValueAsString(bean));
|
||||
}
|
||||
if (!records.isEmpty()) {
|
||||
// after processing the data, commit the offset manually
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.taos.example;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import com.taosdata.jdbc.utils.JsonUtil;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
|
@ -31,7 +31,11 @@ public class ConsumerLoopImp {
|
|||
final AbsConsumerLoop consumerLoop = new AbsConsumerLoop() {
|
||||
@Override
|
||||
public void process(ResultBean result) {
|
||||
System.out.println("data: " + JSON.toJSONString(result));
|
||||
try{
|
||||
System.out.println("data: " + JsonUtil.getObjectMapper().writeValueAsString(result));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package com.taos.example;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import com.taosdata.jdbc.tmq.*;
|
||||
import com.taosdata.jdbc.utils.JsonUtil;
|
||||
|
||||
import java.sql.*;
|
||||
import java.time.Duration;
|
||||
|
@ -60,7 +61,7 @@ public class WsConsumerLoopFull {
|
|||
// ANCHOR_END: create_consumer
|
||||
}
|
||||
|
||||
public static void pollExample(TaosConsumer<ResultBean> consumer) throws SQLException {
|
||||
public static void pollExample(TaosConsumer<ResultBean> consumer) throws SQLException, JsonProcessingException {
|
||||
// ANCHOR: poll_data_code_piece
|
||||
List<String> topics = Collections.singletonList("topic_meters");
|
||||
try {
|
||||
|
@ -73,7 +74,7 @@ public class WsConsumerLoopFull {
|
|||
for (ConsumerRecord<ResultBean> record : records) {
|
||||
ResultBean bean = record.value();
|
||||
// Add your data processing logic here
|
||||
System.out.println("data: " + JSON.toJSONString(bean));
|
||||
System.out.println("data: " + JsonUtil.getObjectMapper().writeValueAsString(bean));
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
|
@ -91,7 +92,7 @@ public class WsConsumerLoopFull {
|
|||
// ANCHOR_END: poll_data_code_piece
|
||||
}
|
||||
|
||||
public static void seekExample(TaosConsumer<ResultBean> consumer) throws SQLException {
|
||||
public static void seekExample(TaosConsumer<ResultBean> consumer) throws SQLException, JsonProcessingException {
|
||||
// ANCHOR: consumer_seek
|
||||
List<String> topics = Collections.singletonList("topic_meters");
|
||||
try {
|
||||
|
@ -99,7 +100,7 @@ public class WsConsumerLoopFull {
|
|||
consumer.subscribe(topics);
|
||||
System.out.println("Subscribe topics successfully.");
|
||||
Set<TopicPartition> assignment = consumer.assignment();
|
||||
System.out.println("Now assignment: " + JSON.toJSONString(assignment));
|
||||
System.out.println("Now assignment: " + JsonUtil.getObjectMapper().writeValueAsString(assignment));
|
||||
|
||||
ConsumerRecords<ResultBean> records = ConsumerRecords.emptyRecord();
|
||||
// make sure we have got some data
|
||||
|
@ -125,7 +126,7 @@ public class WsConsumerLoopFull {
|
|||
}
|
||||
|
||||
|
||||
public static void commitExample(TaosConsumer<ResultBean> consumer) throws SQLException {
|
||||
public static void commitExample(TaosConsumer<ResultBean> consumer) throws SQLException, JsonProcessingException {
|
||||
// ANCHOR: commit_code_piece
|
||||
List<String> topics = Collections.singletonList("topic_meters");
|
||||
try {
|
||||
|
@ -135,7 +136,7 @@ public class WsConsumerLoopFull {
|
|||
for (ConsumerRecord<ResultBean> record : records) {
|
||||
ResultBean bean = record.value();
|
||||
// Add your data processing logic here
|
||||
System.out.println("data: " + JSON.toJSONString(bean));
|
||||
System.out.println("data: " + JsonUtil.getObjectMapper().writeValueAsString(bean));
|
||||
}
|
||||
if (!records.isEmpty()) {
|
||||
// after processing the data, commit the offset manually
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.taos.example;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import com.taosdata.jdbc.utils.JsonUtil;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
|
@ -28,7 +28,11 @@ public abstract class WsConsumerLoopImp {
|
|||
final AbsConsumerLoop consumerLoop = new AbsConsumerLoop() {
|
||||
@Override
|
||||
public void process(ResultBean result) {
|
||||
System.out.println("data: " + JSON.toJSONString(result));
|
||||
try{
|
||||
System.out.println("data: " + JsonUtil.getObjectMapper().writeValueAsString(result));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ public class DataBaseMonitor {
|
|||
public DataBaseMonitor init() throws SQLException {
|
||||
if (conn == null) {
|
||||
String jdbcURL = System.getenv("TDENGINE_JDBC_URL");
|
||||
if (jdbcURL == null || jdbcURL == ""){
|
||||
jdbcURL = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
|
||||
}
|
||||
conn = DriverManager.getConnection(jdbcURL);
|
||||
stmt = conn.createStatement();
|
||||
}
|
||||
|
|
|
@ -69,6 +69,9 @@ public class SQLWriter {
|
|||
*/
|
||||
private static Connection getConnection() throws SQLException {
|
||||
String jdbcURL = System.getenv("TDENGINE_JDBC_URL");
|
||||
if (jdbcURL == null || jdbcURL == ""){
|
||||
jdbcURL = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
|
||||
}
|
||||
return DriverManager.getConnection(jdbcURL);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,37 @@ public class TestAll {
|
|||
stmt.execute("drop database if exists " + dbName);
|
||||
}
|
||||
}
|
||||
waitTransaction();
|
||||
}
|
||||
|
||||
public void dropTopic(String topicName) throws SQLException {
|
||||
String jdbcUrl = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
|
||||
try (Connection conn = DriverManager.getConnection(jdbcUrl)) {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
stmt.execute("drop topic if exists " + topicName);
|
||||
}
|
||||
}
|
||||
waitTransaction();
|
||||
}
|
||||
|
||||
public void waitTransaction() throws SQLException {
|
||||
|
||||
String jdbcUrl = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
|
||||
try (Connection conn = DriverManager.getConnection(jdbcUrl)) {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
stmt.execute("show transactions");
|
||||
try (ResultSet resultSet = stmt.getResultSet()) {
|
||||
if (resultSet.next()) {
|
||||
int count = resultSet.getInt(1);
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void insertData() throws SQLException {
|
||||
|
@ -104,14 +135,20 @@ public class TestAll {
|
|||
SubscribeDemo.main(args);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testSubscribeJni() throws SQLException, InterruptedException {
|
||||
// dropDB("power");
|
||||
// ConsumerLoopFull.main(args);
|
||||
// }
|
||||
// @Test
|
||||
// public void testSubscribeWs() throws SQLException, InterruptedException {
|
||||
// dropDB("power");
|
||||
// WsConsumerLoopFull.main(args);
|
||||
// }
|
||||
@Test
|
||||
public void testSubscribeJni() throws SQLException, InterruptedException {
|
||||
dropTopic("topic_meters");
|
||||
dropDB("power");
|
||||
ConsumerLoopFull.main(args);
|
||||
dropTopic("topic_meters");
|
||||
dropDB("power");
|
||||
}
|
||||
@Test
|
||||
public void testSubscribeWs() throws SQLException, InterruptedException {
|
||||
dropTopic("topic_meters");
|
||||
dropDB("power");
|
||||
WsConsumerLoopFull.main(args);
|
||||
dropTopic("topic_meters");
|
||||
dropDB("power");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tdengine/websocket": "^3.1.0"
|
||||
"@tdengine/websocket": "^3.1.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ const taos = require("@tdengine/websocket");
|
|||
|
||||
let dsn = 'ws://localhost:6041';
|
||||
async function createConnect() {
|
||||
|
||||
try {
|
||||
let conf = new taos.WSConfig(dsn);
|
||||
conf.setUser('root');
|
||||
|
|
|
@ -10,7 +10,6 @@ const groupId = "group1";
|
|||
const clientId = "client1";
|
||||
|
||||
async function createConsumer() {
|
||||
|
||||
let groupId = "group1";
|
||||
let clientId = "client1";
|
||||
let configMap = new Map([
|
||||
|
|
|
@ -4,9 +4,9 @@ sidebar_label: 文档首页
|
|||
slug: /
|
||||
---
|
||||
|
||||
TDengine 是一款[开源](https://www.taosdata.com/tdengine/open_source_time-series_database)、[高性能](https://www.taosdata.com/fast)、[云原生](https://www.taosdata.com/tdengine/cloud_native_time-series_database)的<a href="https://www.taosdata.com/" data-internallinksmanager029f6b8e52c="2" title="时序数据库" target="_blank" rel="noopener">时序数据库</a>(<a href="https://www.taosdata.com/time-series-database" data-internallinksmanager029f6b8e52c="9" title="Time Series DataBase" target="_blank" rel="noopener">Time Series Database</a>, <a href="https://www.taosdata.com/tsdb" data-internallinksmanager029f6b8e52c="8" title="TSDB" target="_blank" rel="noopener">TSDB</a>), 它专为物联网、车联网、工业互联网、金融、IT 运维等场景优化设计。同时它还带有内建的缓存、流式计算、数据订阅等系统功能,能大幅减少系统设计的复杂度,降低研发和运营成本,是一款极简的时序数据处理平台。本文档是 TDengine 的用户手册,主要是介绍 TDengine 的基本概念、安装、使用、功能、开发接口、运营维护、TDengine 内核设计等等,它主要是面向架构师、开发工程师与系统管理员的。如果你对时序数据的基本概念、价值以及其所能带来的业务价值尚不了解,请参考[时序数据基础](./concept)
|
||||
TDengine 是一款[开源](https://www.taosdata.com/tdengine/open_source_time-series_database)、[高性能](https://www.taosdata.com/fast)、[云原生](https://www.taosdata.com/tdengine/cloud_native_time-series_database)的<a href="https://www.taosdata.com/" data-internallinksmanager029f6b8e52c="2" title="时序数据库" target="_blank" rel="noopener">时序数据库</a>(<a href="https://www.taosdata.com/time-series-database" data-internallinksmanager029f6b8e52c="9" title="Time Series DataBase" target="_blank" rel="noopener">Time Series Database</a>, <a href="https://www.taosdata.com/tsdb" data-internallinksmanager029f6b8e52c="8" title="TSDB" target="_blank" rel="noopener">TSDB</a>), 它专为物联网、车联网、工业互联网、金融、IT 运维等场景优化设计。同时它还带有内建的缓存、流式计算、数据订阅等系统功能,能大幅减少系统设计的复杂度,降低研发和运营成本,是一款极简的时序数据处理平台。本文档是 TDengine 的用户手册,主要是介绍 TDengine 的基本概念、安装、使用、功能、开发接口、运营维护、TDengine 内核设计等等,它主要是面向架构师、开发工程师与系统管理员的。如果你对时序数据的基本概念、价值以及其所能带来的业务价值尚不了解,请参考[时序数据基础](./concept)。
|
||||
|
||||
TDengine 充分利用了时序数据的特点,提出了“一个数据采集点一张表”与“超级表”的概念,设计了创新的存储引擎,让数据的写入、查询和存储效率都得到极大的提升。为正确理解并使用 TDengine,无论如何,请您仔细阅读[数据模型](./basic/model)一章。
|
||||
TDengine 充分利用了时序数据的特点,提出了“一个数据采集点一张表”与“超级表”的概念,设计了创新的存储引擎,让数据的写入、查询和存储效率都得到极大的提升。为正确理解并使用 TDengine,无论你在工作中是什么角色,请您仔细阅读[数据模型](./basic/model)一章。
|
||||
|
||||
如果你是开发工程师,请一定仔细阅读[开发指南](./develop)一章,该部分对数据库连接、建模、插入数据、查询、流式计算、缓存、数据订阅、用户自定义函数等功能都做了详细介绍,并配有各种编程语言的示例代码。大部分情况下,你只要复制粘贴示例代码,针对自己的应用稍作改动,就能跑起来。对 REST API、各种编程语言的连接器(Connector)想做更多详细了解的话,请看[连接器](./reference/connector)一章。
|
||||
|
||||
|
@ -16,6 +16,8 @@ TDengine 采用 SQL 作为查询语言,大大降低学习成本、降低迁移
|
|||
|
||||
如果你是系统管理员,关心安装、升级、容错灾备、关心数据导入、导出、配置参数,如何监测 TDengine 是否健康运行,如何提升系统运行的性能,请仔细参考[运维指南](./operation)一章。
|
||||
|
||||
如果你对数据库内核设计感兴趣,或是开源爱好者,建议仔细阅读[技术内幕](./tdinterna)一章。该章从分布式架构到存储引擎、查询引擎、数据订阅,再到流计算引擎都做了详细阐述。建议对照文档,查看TDengine在GitHub的源代码,对TDengine的设计和编码做深入了解,更欢迎加入开源社区,贡献代码。
|
||||
|
||||
最后,作为一个开源软件,欢迎大家的参与。如果发现文档有任何错误、描述不清晰的地方,请在每个页面的最下方,点击“编辑本文档”直接进行修改。
|
||||
|
||||
Together, we make a difference!
|
||||
|
|
|
@ -17,23 +17,24 @@ docker pull tdengine/tdengine:latest
|
|||
或者指定版本的容器镜像:
|
||||
|
||||
```shell
|
||||
docker pull tdengine/tdengine:3.0.1.4
|
||||
docker pull tdengine/tdengine:3.3.3.0
|
||||
```
|
||||
|
||||
然后只需执行下面的命令:
|
||||
|
||||
```shell
|
||||
docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6060:6043-6060 -p 6043-6060:6043-6060/udp tdengine/tdengine
|
||||
docker run -d -p 6030:6030 -p 6041:6041 -p 6043:6043 -p 6044-6049:6044-6049 -p 6044-6045:6044-6045/udp -p 6060:6060 tdengine/tdengine
|
||||
```
|
||||
|
||||
注意:TDengine 3.0 服务端仅使用 6030 TCP 端口。6041 为 taosAdapter 所使用提供 REST 服务端口。6043-6049 为 taosAdapter 提供第三方应用接入所使用端口,可根据需要选择是否打开。
|
||||
注意:TDengine 3.0 服务端仅使用 6030 TCP 端口。6041 为 taosAdapter 所使用提供 REST 服务端口。6043 为 taosKeeper 使用端口。6044-6049 TCP 端口为 taosAdapter 提供第三方应用接入所使用端口,可根据需要选择是否打开。
|
||||
6044 和 6045 UDP 端口为 statsd 和 collectd 格式写入接口,可根据需要选择是否打开。6060 为 taosExplorer 使用端口。具体端口使用情况请参考[网络端口要求](../../operation/planning#网络端口要求)。
|
||||
|
||||
如果需要将数据持久化到本机的某一个文件夹,则执行下边的命令:
|
||||
|
||||
```shell
|
||||
docker run -d -v ~/data/taos/dnode/data:/var/lib/taos \
|
||||
-v ~/data/taos/dnode/log:/var/log/taos \
|
||||
-p 6030:6030 -p 6041:6041 -p 6043-6060:6043-6060 -p 6043-6060:6043-6060/udp tdengine/tdengine
|
||||
-p 6030:6030 -p 6041:6041 -p 6043:6043 -p 6044-6049:6044-6049 -p 6044-6045:6044-6045/udp -p 6060:6060 tdengine/tdengine
|
||||
```
|
||||
|
||||
:::note
|
||||
|
@ -121,4 +122,4 @@ SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters WHERE groupId = 1
|
|||
SELECT _wstart, AVG(current), MAX(voltage), MIN(phase) FROM test.d1001 INTERVAL(10s);
|
||||
```
|
||||
|
||||
在上面的查询中,使用系统提供的伪列_wstart 来给出每个窗口的开始时间。
|
||||
在上面的查询中,使用系统提供的伪列 _wstart 来给出每个窗口的开始时间。
|
||||
|
|
|
@ -14,7 +14,9 @@ TDengine 完整的软件包包括服务端(taosd)、应用驱动(taosc)
|
|||
|
||||
为方便使用,标准的服务端安装包包含了 taosd、taosAdapter、taosc、taos、taosdump、taosBenchmark、TDinsight 安装脚本和示例代码;如果您只需要用到服务端程序和客户端连接的 C/C++ 语言支持,也可以仅下载 Lite 版本的安装包。
|
||||
|
||||
在 Linux 系统上,TDengine 社区版提供 Deb 和 RPM 格式安装包,用户可以根据自己的运行环境选择合适的安装包。其中 Deb 支持 Debian/Ubuntu 及其衍生系统,RPM 支持 CentOS/RHEL/SUSE 及其衍生系统。同时我们也为企业用户提供 tar.gz 格式安装包,也支持通过 `apt-get` 工具从线上进行安装。需要注意的是,RPM 和 Deb 包不含 `taosdump` 和 TDinsight 安装脚本,这些工具需要通过安装 taosTools 包获得。TDengine 也提供 Windows x64 平台和 macOS x64/m1 平台的安装包。
|
||||
在 Linux 系统上,TDengine 社区版提供 Deb 和 RPM 格式安装包,其中 Deb 支持 Debian/Ubuntu 及其衍生系统,RPM 支持 CentOS/RHEL/SUSE 及其衍生系统,用户可以根据自己的运行环境自行选择。同时我们也提供了 tar.gz 格式安装包,以及 `apt-get` 工具从线上进行安装。
|
||||
|
||||
此外,TDengine 也提供 macOS x64/m1 平台的 pkg 安装包。
|
||||
|
||||
## 运行环境要求
|
||||
在linux系统中,运行环境最低要求如下:
|
||||
|
@ -317,4 +319,4 @@ SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters WHERE groupId = 1
|
|||
SELECT _wstart, AVG(current), MAX(voltage), MIN(phase) FROM test.d1001 INTERVAL(10s);
|
||||
```
|
||||
|
||||
在上面的查询中,使用系统提供的伪列_wstart 来给出每个窗口的开始时间。
|
||||
在上面的查询中,使用系统提供的伪列 _wstart 来给出每个窗口的开始时间。
|
|
@ -54,4 +54,4 @@ SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters WHERE groupId = 1
|
|||
SELECT _wstart, AVG(current), MAX(voltage), MIN(phase) FROM test.d1001 INTERVAL(10s);
|
||||
```
|
||||
|
||||
在上面的查询中,使用系统提供的伪列_wstart 来给出每个窗口的开始时间。
|
||||
在上面的查询中,使用系统提供的伪列 _wstart 来给出每个窗口的开始时间。
|
|
@ -106,7 +106,7 @@ CREATE DATABASE power PRECISION 'ms' KEEP 3650 DURATION 10 BUFFER 16;
|
|||
```
|
||||
该 SQL 将创建一个名为 `power` 的数据库,各参数说明如下:
|
||||
- `PRECISION 'ms'` :这个数据库的时序数据使用毫秒(ms)精度的时间戳
|
||||
- `KEEP 365`:这个库的数据将保留 3650 天,超过 3650 天的数据将被自动删除
|
||||
- `KEEP 3650`:这个库的数据将保留 3650 天,超过 3650 天的数据将被自动删除
|
||||
- `DURATION 10` :每 10 天的数据放在一个数据文件中
|
||||
- `BUFFER 16` :写入使用大小为 16MB 的内存池。
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ toc_max_heading_level: 4
|
|||
|
||||
## 基本查询
|
||||
|
||||
为了更好的介绍 TDengine 数据查询,使用 如下 taosBenchmark 命令,生成本章内容需要的时序数据。
|
||||
为了更好的介绍 TDengine 数据查询,使用如下 taosBenchmark 命令,生成本章内容需要的时序数据。
|
||||
|
||||
```shell
|
||||
taosBenchmark --start-timestamp=1600000000000 --tables=100 --records=10000000 --time-step=10000
|
||||
|
@ -20,21 +20,22 @@ taosBenchmark --start-timestamp=1600000000000 --tables=100 --records=10000000 --
|
|||
|
||||
```sql
|
||||
SELECT * FROM meters
|
||||
WHERE voltage > 10
|
||||
WHERE voltage > 230
|
||||
ORDER BY ts DESC
|
||||
LIMIT 5
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
上面的 SQL,从超级表 `meters` 中查询出电压 `voltage` 大于 10 的记录,按时间降序排列,且仅输出前 5 行。查询结果如下:
|
||||
上面的 SQL,从超级表 `meters` 中查询出电压 `voltage` 大于 230V 的记录,按时间降序排列,且仅输出前 5 行。查询结果如下:
|
||||
|
||||
```text
|
||||
ts | current | voltage | phase | groupid | location |
|
||||
==========================================================================================================
|
||||
2023-11-14 22:13:10.000 | 1.1294620 | 18 | 0.3531540 | 8 | California.MountainView |
|
||||
2023-11-14 22:13:10.000 | 1.0294620 | 12 | 0.3631540 | 2 | California.Campbell |
|
||||
2023-11-14 22:13:10.000 | 1.0294620 | 16 | 0.3531540 | 1 | California.Campbell |
|
||||
2023-11-14 22:13:10.000 | 1.1294620 | 18 | 0.3531540 | 2 | California.Campbell |
|
||||
2023-11-14 22:13:10.000 | 1.1294620 | 16 | 0.3431540 | 7 | California.PaloAlto |
|
||||
===================================================================================================
|
||||
2023-11-15 06:13:10.000 | 14.0601978 | 232 | 146.5000000 | 10 | California.Sunnyvale |
|
||||
2023-11-15 06:13:10.000 | 14.0601978 | 232 | 146.5000000 | 1 | California.LosAngles |
|
||||
2023-11-15 06:13:10.000 | 14.0601978 | 232 | 146.5000000 | 10 | California.Sunnyvale |
|
||||
2023-11-15 06:13:10.000 | 14.0601978 | 232 | 146.5000000 | 5 | California.Cupertino |
|
||||
2023-11-15 06:13:10.000 | 14.0601978 | 232 | 146.5000000 | 4 | California.SanFrancisco |
|
||||
Query OK, 5 row(s) in set (0.145403s)
|
||||
```
|
||||
|
||||
## 聚合查询
|
||||
|
@ -48,28 +49,28 @@ TDengine 支持通过 GROUP BY 子句,对数据进行聚合查询。SQL 语句
|
|||
group by 子句用于对数据进行分组,并为每个分组返回一行汇总信息。在 group by 子句中,可以使用表或视图中的任何列作为分组依据,这些列不需要出现在 select 列表中。此外,用户可以直接在超级表上执行聚合查询,无须预先创建子表。以智能电表的数据模型为例,使用 group by 子句的 SQL 如下:
|
||||
|
||||
```sql
|
||||
SELECT groupid,avg(voltage)
|
||||
SELECT groupid, avg(voltage)
|
||||
FROM meters
|
||||
WHERE ts >= "2022-01-01T00:00:00+08:00"
|
||||
AND ts < "2023-01-01T00:00:00+08:00"
|
||||
GROUP BY groupid
|
||||
GROUP BY groupid;
|
||||
```
|
||||
|
||||
上面的 SQL,查询超级表 `meters` 中,时间戳大于等于 `2022-01-01T00:00:00+08:00`,且时间戳小于 `2023-01-01T00:00:00+08:00` 的数据,按照 `groupid` 进行分组,求每组的平均电压。查询结果如下:
|
||||
|
||||
```text
|
||||
groupid | avg(voltage) |
|
||||
==========================================
|
||||
8 | 9.104040404040404 |
|
||||
5 | 9.078333333333333 |
|
||||
1 | 9.087037037037037 |
|
||||
7 | 8.991414141414142 |
|
||||
9 | 8.789814814814815 |
|
||||
6 | 9.051010101010101 |
|
||||
4 | 9.135353535353536 |
|
||||
10 | 9.213131313131314 |
|
||||
2 | 9.008888888888889 |
|
||||
3 | 8.783888888888889 |
|
||||
======================================
|
||||
8 | 243.961981544901079 |
|
||||
5 | 243.961981544901079 |
|
||||
1 | 243.961981544901079 |
|
||||
7 | 243.961981544901079 |
|
||||
9 | 243.961981544901079 |
|
||||
6 | 243.961981544901079 |
|
||||
4 | 243.961981544901079 |
|
||||
10 | 243.961981544901079 |
|
||||
2 | 243.961981544901079 |
|
||||
3 | 243.961981544901079 |
|
||||
Query OK, 10 row(s) in set (0.042446s)
|
||||
```
|
||||
|
||||
|
@ -110,24 +111,24 @@ TDengine 按如下方式处理数据切分子句。
|
|||
```sql
|
||||
SELECT location, avg(voltage)
|
||||
FROM meters
|
||||
PARTITION BY location
|
||||
PARTITION BY location;
|
||||
```
|
||||
|
||||
上面的示例 SQL 查询超级表 `meters`,将数据按标签 `location` 进行分组,每个分组计算电压的平均值。查询结果如下:
|
||||
|
||||
```text
|
||||
location | avg(voltage) |
|
||||
=========================================================
|
||||
California.SantaClara | 8.793334320000000 |
|
||||
California.SanFrancisco | 9.017645882352941 |
|
||||
California.SanJose | 9.156112940000000 |
|
||||
California.LosAngles | 9.036753507692307 |
|
||||
California.SanDiego | 8.967037053333334 |
|
||||
California.Sunnyvale | 8.978572085714285 |
|
||||
California.PaloAlto | 8.936665800000000 |
|
||||
California.Cupertino | 8.987654066666666 |
|
||||
California.MountainView | 9.046297266666667 |
|
||||
California.Campbell | 9.149999028571429 |
|
||||
======================================================
|
||||
California.SantaClara | 243.962050000000005 |
|
||||
California.SanFrancisco | 243.962050000000005 |
|
||||
California.SanJose | 243.962050000000005 |
|
||||
California.LosAngles | 243.962050000000005 |
|
||||
California.SanDiego | 243.962050000000005 |
|
||||
California.Sunnyvale | 243.962050000000005 |
|
||||
California.PaloAlto | 243.962050000000005 |
|
||||
California.Cupertino | 243.962050000000005 |
|
||||
California.MountainView | 243.962050000000005 |
|
||||
California.Campbell | 243.962050000000005 |
|
||||
Query OK, 10 row(s) in set (2.415961s)
|
||||
```
|
||||
|
||||
|
@ -201,19 +202,19 @@ SLIMIT 2;
|
|||
|
||||
```text
|
||||
tbname | _wstart | _wend | avg(voltage) |
|
||||
==========================================================================================
|
||||
d40 | 2021-12-31 15:59:05.000 | 2021-12-31 16:00:05.000 | 4.000000000000000 |
|
||||
d40 | 2021-12-31 16:00:05.000 | 2021-12-31 16:01:05.000 | 5.000000000000000 |
|
||||
d40 | 2021-12-31 16:01:05.000 | 2021-12-31 16:02:05.000 | 8.000000000000000 |
|
||||
d40 | 2021-12-31 16:02:05.000 | 2021-12-31 16:03:05.000 | 7.666666666666667 |
|
||||
d40 | 2021-12-31 16:03:05.000 | 2021-12-31 16:04:05.000 | 9.666666666666666 |
|
||||
d40 | 2021-12-31 16:04:05.000 | 2021-12-31 16:05:05.000 | 15.199999999999999 |
|
||||
d41 | 2021-12-31 15:59:05.000 | 2021-12-31 16:00:05.000 | 4.000000000000000 |
|
||||
d41 | 2021-12-31 16:00:05.000 | 2021-12-31 16:01:05.000 | 7.000000000000000 |
|
||||
d41 | 2021-12-31 16:01:05.000 | 2021-12-31 16:02:05.000 | 9.000000000000000 |
|
||||
d41 | 2021-12-31 16:02:05.000 | 2021-12-31 16:03:05.000 | 10.666666666666666 |
|
||||
d41 | 2021-12-31 16:03:05.000 | 2021-12-31 16:04:05.000 | 8.333333333333334 |
|
||||
d41 | 2021-12-31 16:04:05.000 | 2021-12-31 16:05:05.000 | 9.600000000000000 |
|
||||
======================================================================================
|
||||
d2 | 2021-12-31 23:59:05.000 | 2022-01-01 00:00:05.000 | 253.000000000000000 |
|
||||
d2 | 2022-01-01 00:00:05.000 | 2022-01-01 00:01:05.000 | 244.166666666666657 |
|
||||
d2 | 2022-01-01 00:01:05.000 | 2022-01-01 00:02:05.000 | 241.833333333333343 |
|
||||
d2 | 2022-01-01 00:02:05.000 | 2022-01-01 00:03:05.000 | 243.166666666666657 |
|
||||
d2 | 2022-01-01 00:03:05.000 | 2022-01-01 00:04:05.000 | 240.833333333333343 |
|
||||
d2 | 2022-01-01 00:04:05.000 | 2022-01-01 00:05:05.000 | 244.800000000000011 |
|
||||
d26 | 2021-12-31 23:59:05.000 | 2022-01-01 00:00:05.000 | 253.000000000000000 |
|
||||
d26 | 2022-01-01 00:00:05.000 | 2022-01-01 00:01:05.000 | 244.166666666666657 |
|
||||
d26 | 2022-01-01 00:01:05.000 | 2022-01-01 00:02:05.000 | 241.833333333333343 |
|
||||
d26 | 2022-01-01 00:02:05.000 | 2022-01-01 00:03:05.000 | 243.166666666666657 |
|
||||
d26 | 2022-01-01 00:03:05.000 | 2022-01-01 00:04:05.000 | 240.833333333333343 |
|
||||
d26 | 2022-01-01 00:04:05.000 | 2022-01-01 00:05:05.000 | 244.800000000000011 |
|
||||
Query OK, 12 row(s) in set (0.021265s)
|
||||
```
|
||||
|
||||
|
@ -256,18 +257,18 @@ SLIMIT 1;
|
|||
|
||||
```text
|
||||
tbname | _wstart | avg(voltage) |
|
||||
================================================================
|
||||
d40 | 2021-12-31 15:59:30.000 | 4.000000000000000 |
|
||||
d40 | 2021-12-31 16:00:00.000 | 5.666666666666667 |
|
||||
d40 | 2021-12-31 16:00:30.000 | 4.333333333333333 |
|
||||
d40 | 2021-12-31 16:01:00.000 | 5.000000000000000 |
|
||||
d40 | 2021-12-31 16:01:30.000 | 9.333333333333334 |
|
||||
d40 | 2021-12-31 16:02:00.000 | 9.666666666666666 |
|
||||
d40 | 2021-12-31 16:02:30.000 | 10.000000000000000 |
|
||||
d40 | 2021-12-31 16:03:00.000 | 10.333333333333334 |
|
||||
d40 | 2021-12-31 16:03:30.000 | 10.333333333333334 |
|
||||
d40 | 2021-12-31 16:04:00.000 | 13.000000000000000 |
|
||||
d40 | 2021-12-31 16:04:30.000 | 15.333333333333334 |
|
||||
=============================================================
|
||||
d2 | 2021-12-31 23:59:30.000 | 248.333333333333343 |
|
||||
d2 | 2022-01-01 00:00:00.000 | 246.000000000000000 |
|
||||
d2 | 2022-01-01 00:00:30.000 | 244.666666666666657 |
|
||||
d2 | 2022-01-01 00:01:00.000 | 240.833333333333343 |
|
||||
d2 | 2022-01-01 00:01:30.000 | 239.500000000000000 |
|
||||
d2 | 2022-01-01 00:02:00.000 | 243.833333333333343 |
|
||||
d2 | 2022-01-01 00:02:30.000 | 243.833333333333343 |
|
||||
d2 | 2022-01-01 00:03:00.000 | 241.333333333333343 |
|
||||
d2 | 2022-01-01 00:03:30.000 | 241.666666666666657 |
|
||||
d2 | 2022-01-01 00:04:00.000 | 244.166666666666657 |
|
||||
d2 | 2022-01-01 00:04:30.000 | 244.666666666666657 |
|
||||
Query OK, 11 row(s) in set (0.013153s)
|
||||
```
|
||||
|
||||
|
@ -291,12 +292,12 @@ SLIMIT 1;
|
|||
|
||||
```text
|
||||
tbname | _wstart | _wend | avg(voltage) |
|
||||
=================================================================================================================
|
||||
d28 | 2021-12-31 16:00:00.000 | 2021-12-31 16:01:00.000 | 7.333333333333333 |
|
||||
d28 | 2021-12-31 16:01:00.000 | 2021-12-31 16:02:00.000 | 8.000000000000000 |
|
||||
d28 | 2021-12-31 16:02:00.000 | 2021-12-31 16:03:00.000 | 11.000000000000000 |
|
||||
d28 | 2021-12-31 16:03:00.000 | 2021-12-31 16:04:00.000 | 6.666666666666667 |
|
||||
d28 | 2021-12-31 16:04:00.000 | 2021-12-31 16:05:00.000 | 10.000000000000000 |
|
||||
======================================================================================
|
||||
d2 | 2022-01-01 00:00:00.000 | 2022-01-01 00:01:00.000 | 246.000000000000000 |
|
||||
d2 | 2022-01-01 00:01:00.000 | 2022-01-01 00:02:00.000 | 240.833333333333343 |
|
||||
d2 | 2022-01-01 00:02:00.000 | 2022-01-01 00:03:00.000 | 243.833333333333343 |
|
||||
d2 | 2022-01-01 00:03:00.000 | 2022-01-01 00:04:00.000 | 241.333333333333343 |
|
||||
d2 | 2022-01-01 00:04:00.000 | 2022-01-01 00:05:00.000 | 244.166666666666657 |
|
||||
Query OK, 5 row(s) in set (0.016812s)
|
||||
```
|
||||
|
||||
|
@ -343,52 +344,64 @@ SLIMIT 2;
|
|||
|
||||
```text
|
||||
tbname | _wstart | _wend | avg(voltage) |
|
||||
=================================================================================================================
|
||||
d40 | 2021-12-31 16:00:00.000 | 2021-12-31 16:01:00.000 | 5.666666666666667 |
|
||||
d40 | 2021-12-31 16:01:00.000 | 2021-12-31 16:02:00.000 | 5.000000000000000 |
|
||||
d40 | 2021-12-31 16:02:00.000 | 2021-12-31 16:03:00.000 | 9.666666666666666 |
|
||||
d40 | 2021-12-31 16:03:00.000 | 2021-12-31 16:04:00.000 | 10.333333333333334 |
|
||||
d40 | 2021-12-31 16:04:00.000 | 2021-12-31 16:05:00.000 | 13.000000000000000 |
|
||||
d41 | 2021-12-31 16:00:00.000 | 2021-12-31 16:01:00.000 | 5.666666666666667 |
|
||||
d41 | 2021-12-31 16:01:00.000 | 2021-12-31 16:02:00.000 | 9.333333333333334 |
|
||||
d41 | 2021-12-31 16:02:00.000 | 2021-12-31 16:03:00.000 | 11.000000000000000 |
|
||||
d41 | 2021-12-31 16:03:00.000 | 2021-12-31 16:04:00.000 | 7.666666666666667 |
|
||||
d41 | 2021-12-31 16:04:00.000 | 2021-12-31 16:05:00.000 | 10.000000000000000 |
|
||||
=======================================================================================
|
||||
d2 | 2022-01-01 00:00:00.000 | 2022-01-01 00:01:00.000 | 246.000000000000000 |
|
||||
d2 | 2022-01-01 00:01:00.000 | 2022-01-01 00:02:00.000 | 240.833333333333343 |
|
||||
d2 | 2022-01-01 00:02:00.000 | 2022-01-01 00:03:00.000 | 243.833333333333343 |
|
||||
d2 | 2022-01-01 00:03:00.000 | 2022-01-01 00:04:00.000 | 241.333333333333343 |
|
||||
d2 | 2022-01-01 00:04:00.000 | 2022-01-01 00:05:00.000 | 244.166666666666657 |
|
||||
d26 | 2022-01-01 00:00:00.000 | 2022-01-01 00:01:00.000 | 246.000000000000000 |
|
||||
d26 | 2022-01-01 00:01:00.000 | 2022-01-01 00:02:00.000 | 240.833333333333343 |
|
||||
d26 | 2022-01-01 00:02:00.000 | 2022-01-01 00:03:00.000 | 243.833333333333343 |
|
||||
d26 | 2022-01-01 00:03:00.000 | 2022-01-01 00:04:00.000 | 241.333333333333343 |
|
||||
d26 | 2022-01-01 00:04:00.000 | 2022-01-01 00:05:00.000 | 244.166666666666657 |
|
||||
Query OK, 10 row(s) in set (0.022866s)
|
||||
```
|
||||
|
||||
### 状态窗口
|
||||
|
||||
使用整数(布尔值)或字符串来标识产生记录时候设备的状态量。产生的记录如果具有相同的状态量数值则归属于同一个状态窗口,数值改变后该窗口关闭。TDengine 还支持将 CASE 表达式用在状态量,可以表达某个状态的开始是由满足某个条件而触发,这个状态的结束是由另外一个条件满足而触发的语义。以智能电表为例,电压正常范围是 205V 到 235V,那么可以通过监控电压来判断电路是否正常。
|
||||
使用整数(布尔值)或字符串来标识产生记录时候设备的状态量。产生的记录如果具有相同的状态量数值则归属于同一个状态窗口,数值改变后该窗口关闭。TDengine 还支持将 CASE 表达式用在状态量,可以表达某个状态的开始是由满足某个条件而触发,这个状态的结束是由另外一个条件满足而触发的语义。以智能电表为例,电压正常范围是 225V 到 235V,那么可以通过监控电压来判断电路是否正常。
|
||||
|
||||
```sql
|
||||
SELECT tbname, _wstart, _wend,_wduration, CASE WHEN voltage >= 205 and voltage <= 235 THEN 1 ELSE 0 END status
|
||||
SELECT tbname, _wstart, _wend,_wduration, CASE WHEN voltage >= 225 and voltage <= 235 THEN 1 ELSE 0 END status
|
||||
FROM meters
|
||||
WHERE ts >= "2022-01-01T00:00:00+08:00"
|
||||
AND ts < "2022-01-01T00:05:00+08:00"
|
||||
PARTITION BY tbname
|
||||
STATE_WINDOW(
|
||||
CASE WHEN voltage >= 205 and voltage <= 235 THEN 1 ELSE 0 END
|
||||
CASE WHEN voltage >= 225 and voltage <= 235 THEN 1 ELSE 0 END
|
||||
)
|
||||
SLIMIT 10;
|
||||
SLIMIT 2;
|
||||
```
|
||||
|
||||
以上 SQL,查询超级表 meters 中,时间戳大于等于 2022-01-01T00:00:00+08:00,且时间戳小于 2022-01-01T00:05:00+08:00的数据;数据首先按照子表名 tbname 进行数据切分;根据电压是否在正常范围内进行状态窗口的划分;最后,取前 10 个分片的数据作为结果。查询结果如下:
|
||||
以上 SQL,查询超级表 meters 中,时间戳大于等于 2022-01-01T00:00:00+08:00,且时间戳小于 2022-01-01T00:05:00+08:00的数据;数据首先按照子表名 tbname 进行数据切分;根据电压是否在正常范围内进行状态窗口的划分;最后,取前 2 个分片的数据作为结果。查询结果如下:(由于数据是随机生成,结果集包含的数据条数会有不同)
|
||||
|
||||
```text
|
||||
tbname | _wstart | _wend | _wduration | status |
|
||||
=====================================================================================================================================
|
||||
d76 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d47 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d37 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d87 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d64 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d35 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d83 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d51 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d63 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
d0 | 2021-12-31 16:00:00.000 | 2021-12-31 16:04:50.000 | 290000 | 0 |
|
||||
Query OK, 10 row(s) in set (0.040495s)
|
||||
===============================================================================================
|
||||
d2 | 2022-01-01 00:00:00.000 | 2022-01-01 00:01:20.000 | 80000 | 0 |
|
||||
d2 | 2022-01-01 00:01:30.000 | 2022-01-01 00:01:30.000 | 0 | 1 |
|
||||
d2 | 2022-01-01 00:01:40.000 | 2022-01-01 00:01:40.000 | 0 | 0 |
|
||||
d2 | 2022-01-01 00:01:50.000 | 2022-01-01 00:01:50.000 | 0 | 1 |
|
||||
d2 | 2022-01-01 00:02:00.000 | 2022-01-01 00:02:20.000 | 20000 | 0 |
|
||||
d2 | 2022-01-01 00:02:30.000 | 2022-01-01 00:02:30.000 | 0 | 1 |
|
||||
d2 | 2022-01-01 00:02:40.000 | 2022-01-01 00:03:00.000 | 20000 | 0 |
|
||||
d2 | 2022-01-01 00:03:10.000 | 2022-01-01 00:03:10.000 | 0 | 1 |
|
||||
d2 | 2022-01-01 00:03:20.000 | 2022-01-01 00:03:40.000 | 20000 | 0 |
|
||||
d2 | 2022-01-01 00:03:50.000 | 2022-01-01 00:03:50.000 | 0 | 1 |
|
||||
d2 | 2022-01-01 00:04:00.000 | 2022-01-01 00:04:50.000 | 50000 | 0 |
|
||||
d26 | 2022-01-01 00:00:00.000 | 2022-01-01 00:01:20.000 | 80000 | 0 |
|
||||
d26 | 2022-01-01 00:01:30.000 | 2022-01-01 00:01:30.000 | 0 | 1 |
|
||||
d26 | 2022-01-01 00:01:40.000 | 2022-01-01 00:01:40.000 | 0 | 0 |
|
||||
d26 | 2022-01-01 00:01:50.000 | 2022-01-01 00:01:50.000 | 0 | 1 |
|
||||
d26 | 2022-01-01 00:02:00.000 | 2022-01-01 00:02:20.000 | 20000 | 0 |
|
||||
d26 | 2022-01-01 00:02:30.000 | 2022-01-01 00:02:30.000 | 0 | 1 |
|
||||
d26 | 2022-01-01 00:02:40.000 | 2022-01-01 00:03:00.000 | 20000 | 0 |
|
||||
d26 | 2022-01-01 00:03:10.000 | 2022-01-01 00:03:10.000 | 0 | 1 |
|
||||
d26 | 2022-01-01 00:03:20.000 | 2022-01-01 00:03:40.000 | 20000 | 0 |
|
||||
d26 | 2022-01-01 00:03:50.000 | 2022-01-01 00:03:50.000 | 0 | 1 |
|
||||
d26 | 2022-01-01 00:04:00.000 | 2022-01-01 00:04:50.000 | 50000 | 0 |
|
||||
Query OK, 22 row(s) in set (0.153403s)
|
||||
```
|
||||
|
||||
### 会话窗口
|
||||
|
@ -418,17 +431,17 @@ SLIMIT 10;
|
|||
上面的 SQL,查询超级表 meters 中,时间戳大于等于 2022-01-01T00:00:00+08:00,且时间戳小于 2022-01-01T00:10:00+08:00的数据;数据先按照子表名 tbname 进行数据切分,再根据 10 分钟的会话窗口进行切分;最后,取前 10 个分片的数据作为结果,返回子表名、窗口开始时间、窗口结束时间、窗口宽度、窗口内数据条数。查询结果如下:
|
||||
```text
|
||||
tbname | _wstart | _wend | _wduration | count(*) |
|
||||
=====================================================================================================================================
|
||||
d76 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d47 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d37 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d87 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d64 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d35 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d83 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d51 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d63 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
d0 | 2021-12-31 16:00:00.000 | 2021-12-31 16:09:50.000 | 590000 | 60 |
|
||||
===============================================================================================
|
||||
d2 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d26 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d52 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d64 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d76 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d28 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d4 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d88 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d77 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
d54 | 2022-01-01 00:00:00.000 | 2022-01-01 00:09:50.000 | 590000 | 60 |
|
||||
Query OK, 10 row(s) in set (0.043489s)
|
||||
```
|
||||
|
||||
|
@ -458,26 +471,26 @@ FROM meters
|
|||
WHERE ts >= "2022-01-01T00:00:00+08:00"
|
||||
AND ts < "2022-01-01T00:10:00+08:00"
|
||||
PARTITION BY tbname
|
||||
EVENT_WINDOW START WITH voltage >= 10 END WITH voltage < 20
|
||||
LIMIT 10;
|
||||
EVENT_WINDOW START WITH voltage >= 225 END WITH voltage < 235
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
上面的 SQL,查询超级表meters中,时间戳大于等于2022-01-01T00:00:00+08:00,且时间戳小于2022-01-01T00:10:00+08:00的数据;数据先按照子表名tbname进行数据切分,再根据事件窗口条件:电压大于等于 10V,且小于 20V 进行切分;最后,取前 10 行的数据作为结果,返回子表名、窗口开始时间、窗口结束时间、窗口宽度、窗口内数据条数。查询结果如下:
|
||||
上面的 SQL,查询超级表meters中,时间戳大于等于2022-01-01T00:00:00+08:00,且时间戳小于2022-01-01T00:10:00+08:00的数据;数据先按照子表名tbname进行数据切分,再根据事件窗口条件:电压大于等于 225V,且小于 235V 进行切分;最后,取每个分片的前 5 行的数据作为结果,返回子表名、窗口开始时间、窗口结束时间、窗口宽度、窗口内数据条数。查询结果如下:
|
||||
|
||||
```text
|
||||
tbname | _wstart | _wend | _wduration | count(*) |
|
||||
=====================================================================================================================================
|
||||
d0 | 2021-12-31 16:00:00.000 | 2021-12-31 16:00:00.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:00:30.000 | 2021-12-31 16:00:30.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:00:40.000 | 2021-12-31 16:00:40.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:01:20.000 | 2021-12-31 16:01:20.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:02:20.000 | 2021-12-31 16:02:20.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:02:30.000 | 2021-12-31 16:02:30.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:03:10.000 | 2021-12-31 16:03:10.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:03:30.000 | 2021-12-31 16:03:30.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:03:40.000 | 2021-12-31 16:03:40.000 | 0 | 1 |
|
||||
d0 | 2021-12-31 16:03:50.000 | 2021-12-31 16:03:50.000 | 0 | 1 |
|
||||
Query OK, 10 row(s) in set (0.034127s)
|
||||
==============================================================================================
|
||||
d0 | 2022-01-01 00:00:00.000 | 2022-01-01 00:01:30.000 | 90000 | 10 |
|
||||
d0 | 2022-01-01 00:01:40.000 | 2022-01-01 00:02:30.000 | 50000 | 6 |
|
||||
d0 | 2022-01-01 00:02:40.000 | 2022-01-01 00:03:10.000 | 30000 | 4 |
|
||||
d0 | 2022-01-01 00:03:20.000 | 2022-01-01 00:07:10.000 | 230000 | 24 |
|
||||
d0 | 2022-01-01 00:07:20.000 | 2022-01-01 00:07:50.000 | 30000 | 4 |
|
||||
d1 | 2022-01-01 00:00:00.000 | 2022-01-01 00:01:30.000 | 90000 | 10 |
|
||||
d1 | 2022-01-01 00:01:40.000 | 2022-01-01 00:02:30.000 | 50000 | 6 |
|
||||
d1 | 2022-01-01 00:02:40.000 | 2022-01-01 00:03:10.000 | 30000 | 4 |
|
||||
d1 | 2022-01-01 00:03:20.000 | 2022-01-01 00:07:10.000 | 230000 | 24 |
|
||||
……
|
||||
Query OK, 500 row(s) in set (0.328557s)
|
||||
```
|
||||
|
||||
### 计数窗口
|
||||
|
@ -492,17 +505,25 @@ sliding_val 是一个常量,表示窗口滑动的数量,类似于 interval
|
|||
select _wstart, _wend, count(*)
|
||||
from meters
|
||||
where ts >= "2022-01-01T00:00:00+08:00" and ts < "2022-01-01T00:30:00+08:00"
|
||||
count_window(10);
|
||||
count_window(1000);
|
||||
```
|
||||
|
||||
上面的 SQL 查询超级表 meters 中时间戳大于等于 2022-01-01T00:00:00+08:00 且时间戳小于 2022-01-01T00:10:00+08:00 的数据。以每 10 条数据为一组,返回每组的开始时间、结束时间和分组条数。查询结果如下。
|
||||
上面的 SQL 查询超级表 meters 中时间戳大于等于 2022-01-01T00:00:00+08:00 且时间戳小于 2022-01-01T00:10:00+08:00 的数据。以每 1000 条数据为一组,返回每组的开始时间、结束时间和分组条数。查询结果如下:
|
||||
|
||||
```text
|
||||
_wstart | _wend |count(*)|
|
||||
===========================================================
|
||||
2021-12-31 16:00:00.000 | 2021-12-31 16:10:00.000 | 10 |
|
||||
2021-12-31 16:10:00.000 | 2021-12-31 16:20:00.000 | 10 |
|
||||
2021-12-31 16:20:00.000 | 2021-12-31 16:30:00.000 | 10 |
|
||||
_wstart | _wend | count(*) |
|
||||
=====================================================================
|
||||
2022-01-01 00:00:00.000 | 2022-01-01 00:01:30.000 | 1000 |
|
||||
2022-01-01 00:01:40.000 | 2022-01-01 00:03:10.000 | 1000 |
|
||||
2022-01-01 00:03:20.000 | 2022-01-01 00:04:50.000 | 1000 |
|
||||
2022-01-01 00:05:00.000 | 2022-01-01 00:06:30.000 | 1000 |
|
||||
2022-01-01 00:06:40.000 | 2022-01-01 00:08:10.000 | 1000 |
|
||||
2022-01-01 00:08:20.000 | 2022-01-01 00:09:50.000 | 1000 |
|
||||
2022-01-01 00:10:00.000 | 2022-01-01 00:11:30.000 | 1000 |
|
||||
2022-01-01 00:11:40.000 | 2022-01-01 00:13:10.000 | 1000 |
|
||||
2022-01-01 00:13:20.000 | 2022-01-01 00:14:50.000 | 1000 |
|
||||
2022-01-01 00:15:00.000 | 2022-01-01 00:16:30.000 | 1000 |
|
||||
Query OK, 10 row(s) in set (0.062794s)
|
||||
```
|
||||
|
||||
## 时序数据特有函数
|
||||
|
@ -564,13 +585,13 @@ UNION ALL
|
|||
|
||||
```text
|
||||
tbname | ts | current | voltage | phase |
|
||||
=================================================================================================
|
||||
d11 | 2020-09-13 12:26:40.000 | 1.0260611 | 6 | 0.3620200 |
|
||||
d11 | 2020-09-13 12:26:50.000 | 2.9544230 | 8 | 1.0048079 |
|
||||
d21 | 2020-09-13 12:26:40.000 | 1.0260611 | 2 | 0.3520200 |
|
||||
d21 | 2020-09-13 12:26:50.000 | 2.9544230 | 2 | 0.9948080 |
|
||||
d21 | 2020-09-13 12:27:00.000 | -0.0000430 | 12 | 0.0099860 |
|
||||
d1 | 2020-09-13 12:26:40.000 | 1.0260611 | 10 | 0.3520200 |
|
||||
====================================================================================
|
||||
d11 | 2020-09-13 20:26:40.000 | 11.5680809 | 247 | 146.5000000 |
|
||||
d11 | 2020-09-13 20:26:50.000 | 14.2392311 | 234 | 148.0000000 |
|
||||
d1 | 2020-09-13 20:26:40.000 | 11.5680809 | 247 | 146.5000000 |
|
||||
d21 | 2020-09-13 20:26:40.000 | 11.5680809 | 247 | 146.5000000 |
|
||||
d21 | 2020-09-13 20:26:50.000 | 14.2392311 | 234 | 148.0000000 |
|
||||
d21 | 2020-09-13 20:27:00.000 | 10.0999422 | 251 | 146.0000000 |
|
||||
Query OK, 6 row(s) in set (0.006438s)
|
||||
```
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ TDengine 利用这些日志文件实现故障前的状态恢复。在写入 WAL
|
|||
- wal_fsync_period:当 wal_level 设置为 2 时,这个参数控制执行 fsync 的频率。设置为 0 表示每次写入后立即执行 fsync,这可以确保数据的安全性,但可能会牺牲一些性能。当设置为大于 0 的数值时,表示 fsync 周期,默认为 3000,范围是[1, 180000],单位毫秒。
|
||||
|
||||
```sql
|
||||
CREATE DATABASE POWER WAL_LEVEL 1 WAL_FSYNC_PERIOD 3000;
|
||||
CREATE DATABASE POWER WAL_LEVEL 2 WAL_FSYNC_PERIOD 3000;
|
||||
```
|
||||
|
||||
在创建数据库时可以选择不同的参数类型,来选择性能优先或者可靠性优先。
|
||||
|
|
|
@ -116,10 +116,11 @@ create stream if not exists count_history_s fill_history 1 into count_history as
|
|||
|
||||
### 流计算的触发模式
|
||||
|
||||
在创建流时,可以通过 TRIGGER 指令指定流计算的触发模式。对于非窗口计算,流计算的触发是实时的,对于窗口计算,目前提供 3 种触发模式,默认为 WINDOW_CLOSE。
|
||||
在创建流时,可以通过 TRIGGER 指令指定流计算的触发模式。对于非窗口计算,流计算的触发是实时的,对于窗口计算,目前提供 4 种触发模式,默认为 WINDOW_CLOSE。
|
||||
1. AT_ONCE:写入立即触发。
|
||||
2. WINDOW_CLOSE:窗口关闭时触发(窗口关闭由事件时间决定,可配合 watermark 使用)。
|
||||
3. MAX_DELAY time:若窗口关闭,则触发计算。若窗口未关闭,且未关闭时长超过 max delay 指定的时间,则触发计算。
|
||||
4. FORCE_WINDOW_CLOSE:以操作系统当前时间为准,只计算当前关闭窗口的结果,并推送出去。窗口只会在被关闭的时刻计算一次,后续不会再重复计算。该模式当前只支持 INTERVAL 窗口(不支持滑动);FILL_HISTORY必须为 0,IGNORE EXPIRED 必须为 1,IGNORE UPDATE 必须为 1;FILL 只支持 PREV 、NULL、 NONE、VALUE。
|
||||
|
||||
窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,此时事件时间无法更新,可能导致无法得到最新的计算结果。
|
||||
|
||||
|
@ -228,3 +229,34 @@ RESUME STREAM [IF EXISTS] [IGNORE UNTREATED] stream_name;
|
|||
```
|
||||
|
||||
没有指定 IF EXISTS,如果该 stream 不存在,则报错。如果存在,则恢复流计算。指定了 IF EXISTS,如果 stream 不存在,则返回成功。如果存在,则恢复流计算。如果指定 IGNORE UNTREATED,则恢复流计算时,忽略流计算暂停期间写入的数据。
|
||||
|
||||
### 流计算升级故障恢复
|
||||
|
||||
升级 TDengine 后,如果流计算不兼容,需要删除流计算,然后重新创建流计算。步骤如下:
|
||||
|
||||
1.修改 taos.cfg,添加 disableStream 1
|
||||
|
||||
2.重启 taosd。如果启动失败,修改 stream 目录的名称,避免 taosd 启动的时候尝试加载 stream 目录下的流计算数据信息。不使用删除操作避免误操作导致的风险。需要修改的文件夹:$dataDir/vnode/vnode*/tq/stream,$dataDir 指 TDengine 存储数据的目录,在 $dataDir/vnode/ 目录下会有多个类似 vnode1 、vnode2...vnode* 的目录,全部需要修改里面的 tq/stream 目录的名字,改为 tq/stream.bk
|
||||
|
||||
3.启动 taos
|
||||
|
||||
```sql
|
||||
drop stream xxxx; ---- xxx 指stream name
|
||||
flush database stream_source_db; ---- 流计算读取数据的超级表所在的 database
|
||||
flush database stream_dest_db; ---- 流计算写入数据的超级表所在的 database
|
||||
```
|
||||
|
||||
举例:
|
||||
|
||||
```sql
|
||||
create stream streams1 into test1.streamst as select _wstart, count(a) c1 from test.st interval(1s) ;
|
||||
drop database streams1;
|
||||
flush database test;
|
||||
flush database test1;
|
||||
```
|
||||
|
||||
4.关闭 taosd
|
||||
|
||||
5.修改 taos.cfg,去掉 disableStream 1,或将 disableStream 改为 0
|
||||
|
||||
6.启动 taosd
|
|
@ -14,18 +14,26 @@ TDengine Enterprise 配备了一个强大的可视化数据管理工具—taosEx
|
|||
|
||||
## 支持的数据源
|
||||
|
||||
目前 TDengine 支持的数据源如下:
|
||||
目前 TDengine 支持的数据源如下表:
|
||||
|
||||
1. Aveva PI System:一个工业数据管理和分析平台,前身为 OSIsoft PI System,它能够实时采集、整合、分析和可视化工业数据,助力企业实现智能化决策和精细化管理
|
||||
2. Aveva Historian:一个工业大数据分析软件,前身为 Wonderware Historian,专为工业环境设计,用于存储、管理和分析来自各种工业设备、传感器的实时和历史数据。
|
||||
3. OPC DA/UA:OPC 是 Open Platform Communications 的缩写,是一种开放式、标准化的通信协议,用于不同厂商的自动化设备之间进行数据交换。它最初由微软公司开发,旨在解决工业控制领域中不同设备之间互操作性差的问题。OPC 协议最初于 1996 年发布,当时称为 OPC DA (Data Access),主要用于实时数据采集和控制;2006 年,OPC 基金会发布了 OPC UA (Unified Architecture) 标准,它是一种基于服务的面向对象的协议,具有更高的灵活性和可扩展性,已成为 OPC 协议的主流版本。
|
||||
4. MQTT:Message Queuing Telemetry Transport 的缩写,一种基于发布/订阅模式的轻量级通讯协议,专为低开销、低带宽占用的即时通讯设计,广泛适用于物联网、小型设备、移动应用等领域。
|
||||
5. Kafka:由 Apache 软件基金会开发的一个开源流处理平台,主要用于处理实时数据,并提供一个统一、高通量、低延迟的消息系统。它具备高速度、可伸缩性、持久性和分布式设计等特点,使得它能够在每秒处理数十万次的读写操作,支持上千个客户端,同时保持数据的可靠性和可用性。
|
||||
6. OpenTSDB:基于 HBase 的分布式、可伸缩的时序数据库。它主要用于存储、索引和提供从大规模集群(包括网络设备、操作系统、应用程序等)中收集的指标数据,使这些数据更易于访问和图形化展示。
|
||||
7. CSV:Comma Separated Values 的缩写,是一种以逗号分隔的纯文本文件格式,通常用于电子表格或数据库软件。
|
||||
8. TDengine 2:泛指运行 TDengine 2.x 版本的 TDengine 实例。
|
||||
9. TDengine 3:泛指运行 TDengine 3.x 版本的 TDengine 实例。
|
||||
10. MySQL, PostgreSQL, Oracle 等关系型数据库。
|
||||
| 数据源 | 支持版本 | 描述 |
|
||||
| --- | --- | --- |
|
||||
| Aveva PI System | PI AF Server Version 2.10.9.593 或以上 | 工业数据管理和分析平台,前身为 OSIsoft PI System,它能够实时采集、整合、分析和可视化工业数据,助力企业实现智能化决策和精细化管理 |
|
||||
| Aveva Historian | AVEVA Historian 2020 RS SP1 | 工业大数据分析软件,前身为 Wonderware Historian,专为工业环境设计,用于存储、管理和分析来自各种工业设备、传感器的实时和历史数据 |
|
||||
| OPC DA | Matrikon OPC version: 1.7.2.7433 | OPC 是 Open Platform Communications 的缩写,是一种开放式、标准化的通信协议,用于不同厂商的自动化设备之间进行数据交换。它最初由微软公司开发,旨在解决工业控制领域中不同设备之间互操作性差的问题;OPC 协议最初于 1996 年发布,当时称为 OPC DA (Data Access),主要用于实时数据采集和控制。 |
|
||||
| OPC UA | KeepWare KEPServerEx 6.5 | 2006 年,OPC 基金会发布了 OPC UA (Unified Architecture) 标准,它是一种基于服务的面向对象的协议,具有更高的灵活性和可扩展性,已成为 OPC 协议的主流版本 |
|
||||
| MQTT | emqx: 3.0.0 到 5.7.1<br/> hivemq: 4.0.0 到 4.31.0<br/> mosquitto: 1.4.4 到 2.0.18 | Message Queuing Telemetry Transport 的缩写,一种基于发布/订阅模式的轻量级通讯协议,专为低开销、低带宽占用的即时通讯设计,广泛适用于物联网、小型设备、移动应用等领域。 |
|
||||
| Kafka | 2.11 ~ 3.8.0 | 由 Apache 软件基金会开发的一个开源流处理平台,主要用于处理实时数据,并提供一个统一、高通量、低延迟的消息系统。它具备高速度、可伸缩性、持久性和分布式设计等特点,使得它能够在每秒处理数十万次的读写操作,支持上千个客户端,同时保持数据的可靠性和可用性。 |
|
||||
| InfluxDB | 1.7、1.8、2.0-2.7 | InfluxDB 是一种流行的开源时间序列数据库,它针对处理大量时间序列数据进行了优化。|
|
||||
| OpenTSDB | 2.4.1 | 基于 HBase 的分布式、可伸缩的时序数据库。它主要用于存储、索引和提供从大规模集群(包括网络设备、操作系统、应用程序等)中收集的指标数据,使这些数据更易于访问和图形化展示。 |
|
||||
| MySQL | 5.6,5.7,8.0+ | MySQL是最流行的关系型数据库管理系统之一,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择 MySQL 作为网站数据库。 |
|
||||
| Oracle | 11G/12c/19c | Oracle 数据库系统是世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小微机环境。它是一种高效率的、可靠性好的、适应高吞吐量的数据库方案。 |
|
||||
| PostgreSQL | v15.0+ | PostgreSQL 是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统, 有很多在大型商业RDBMS中所具有的特性,包括事务、子选择、触发器、视图、外键引用完整性和复杂锁定功能。|
|
||||
| SQL Server | 2012/2022 | Microsoft SQL Server 是一种关系型数据库管理系统,由 Microsoft 公司开发,具有使用方便可伸缩性好与相关软件集成程度高等优点。 |
|
||||
| MongoDB | 3.6+ | MongoDB 是一个介于关系型数据库与非关系型数据库之间的产品,被广泛应用于内容管理系统、移动应用与物联网等众多领域。 |
|
||||
| CSV | - | Comma Separated Values 的缩写,是一种以逗号分隔的纯文本文件格式,通常用于电子表格或数据库软件。 |
|
||||
| TDengine 2.x | 2.4 或 2.6+ | TDengine 旧版本,已不再维护,推荐升级到 3.0 最新版本。 |
|
||||
| TDengine 3.x | 源端版本+ | 使用 TMQ 进行 TDengine 指定从数据库或超级表的订阅。 |
|
||||
|
||||
## 数据提取、过滤和转换
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
title: "ARIMA"
|
||||
sidebar_label: "ARIMA"
|
||||
---
|
||||
|
||||
本节讲述 ARIMA 算法模型的使用方法。
|
||||
|
||||
## 功能概述
|
||||
|
||||
ARIMA 即自回归移动平均模型(Autoregressive Integrated Moving Average, ARIMA),也记作 ARIMA(p,d,q),是统计模型中最常见的一种用来进行时间序列预测的模型。
|
||||
ARIMA 模型是一种自回归模型,只需要自变量即可预测后续的值。ARIMA 模型要求时间序列**平稳**,或经过差分处理后平稳,如果是不平稳的数据,**无法**获得正确的结果。
|
||||
|
||||
>平稳的时间序列:其性质不随观测时间的变化而变化。具有趋势或季节性的时间序列不是平稳时间序列——趋势和季节性使得时间序列在不同时段呈现不同性质。
|
||||
|
||||
以下参数可以动态输入,控制预测过程中生成合适的 ARIMA 模型。
|
||||
|
||||
- p= 自回归模型阶数
|
||||
- d= 差分阶数
|
||||
- q= 移动平均模型阶数
|
||||
|
||||
|
||||
### 参数
|
||||
分析平台中使用自动化的 ARIMA 模型进行计算,因此每次计算的时候会根据输入的数据自动拟合最合适的模型,然后根据该模型进行预测输出结果。
|
||||
|参数|说明|必填项|
|
||||
|---|---|-----|
|
||||
|period|输入时间序列每个周期包含的数据点个数,如果不设置该参数或该参数设置为 0,将使用非季节性/周期性的 ARIMA 模型预测|选填|
|
||||
|start_p|自回归模型阶数的起始值,0 开始的整数,不推荐大于 10|选填|
|
||||
|max_p|自回归模型阶数的结束值,0 开始的整数,不推荐大于 10|选填|
|
||||
|start_q|移动平均模型阶数的起始值,0 开始的整数,不推荐大于 10|选填|
|
||||
|max_q|移动平均模型阶数的结束值,0 开始的整数,不推荐大于 10|选填|
|
||||
|d|差分阶数|选填|
|
||||
|
||||
`start_p`、`max_p` `start_q` `max_q` 四个参数约束了模型在多大的范围内去搜寻合适的最优解。相同输入数据的条件下,参数范围越大,消耗的资源越多,系统响应的时间越长。
|
||||
|
||||
### 示例及结果
|
||||
针对 i32 列进行数据预测,输入列 i32 每 10 个点是一个周期,start_p 起始是 1, 最大拟合是 5,start_q 是 1,最大值是 5,预测结果中返回 95% 置信区间范围边界。
|
||||
```
|
||||
FORECAST(i32, "algo=arima,alpha=95,period=10,start_p=1,max_p=5,start_q=1,max_q=5")
|
||||
```
|
||||
|
||||
```json5
|
||||
{
|
||||
"rows": fc_rows, // 返回结果的行数
|
||||
"period": period, // 返回结果的周期性,同输入
|
||||
"alpha": alpha, // 返回结果的置信区间,同输入
|
||||
"algo": "arima", // 返回结果使用的算法
|
||||
"mse": mse, // 拟合输入时间序列时候生成模型的最小均方误差(MSE)
|
||||
"res": res // 列模式的结果
|
||||
}
|
||||
```
|
||||
|
||||
### 参考文献
|
||||
- https://en.wikipedia.org/wiki/Autoregressive_moving-average_model
|
||||
- https://baike.baidu.com/item/%E8%87%AA%E5%9B%9E%E5%BD%92%E6%BB%91%E5%8A%A8%E5%B9%B3%E5%9D%87%E6%A8%A1%E5%9E%8B/5023931?fromtitle=ARMA%E6%A8%A1%E5%9E%8B&fromid=8048415
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
title: "HoltWinters"
|
||||
sidebar_label: "HoltWinters"
|
||||
---
|
||||
|
||||
本节讲述 HoltWinters 算法模型的使用方法。
|
||||
|
||||
## 功能概述
|
||||
HoltWinters 模型又称为多次指数平滑模型(EMA)。适用于含有线性趋势和周期波动的非平稳序列,利用指数平滑法让模型参数不断适应非平稳序列的变化,并对未来趋势进行**短期**预测。
|
||||
HoltWinters 有两种不同的季节性组成部分,当季节变化在该时间序列中大致保持不变时,通常选择**加法模型**;而当季节变化与时间序列的水平成比例变化时,通常选择**乘法模型**。
|
||||
该模型对于返回数据不提供计算的置信区间范围结果,在 95% 置信区间的上下界结果与预测结果相同。
|
||||
|
||||
|
||||
### 参数
|
||||
|
||||
分析平台中使用自动化的 HoltWinters 模型进行计算,因此每次计算的时候会根据输入的数据自动拟合最合适的模型,然后根据该模型进行预测输出结果。
|
||||
|参数|说明|必填项|
|
||||
|---|---|---|
|
||||
|period|输入时间序列每个周期包含的数据点个数。如果不设置该参数或该参数设置为 0,将使用一次(简单)指数平滑方式进行数据拟合,并据此进行未来数据的预测|选填|
|
||||
|trend|趋势模型使用加法模型还是乘法模型|选填|
|
||||
|seasonal|季节性采用加法模型还是乘法模型|选填|
|
||||
|
||||
参数 `trend` 和 `seasonal`的均可以选择 `add` (加法模型)或 `mul`(乘法模型)。
|
||||
|
||||
### 示例及结果
|
||||
针对 i32 列进行数据预测,输入列 i32 每 10 个点是一个周期,趋势采用乘法模型,季节采用乘法模型
|
||||
```
|
||||
FORECAST(i32, "algo=holtwinters,period=10,trend=mul,seasonal=mul")
|
||||
```
|
||||
|
||||
```json5
|
||||
{
|
||||
"rows": rows, // 返回结果的行数
|
||||
"period": period, // 返回结果的周期性,该结果与输入的周期性相同,如果没有周期性,该值为 0
|
||||
"algo": 'holtwinters' // 返回结果使用的计算模型
|
||||
"mse": mse, // 最小均方误差(minmum square error)
|
||||
"res": res // 具体的结果,按照列形式返回的结果。一般意义上包含了两列 [timestamp][fc_results]。
|
||||
}
|
||||
```
|
||||
|
||||
### 参考文献
|
||||
- https://en.wikipedia.org/wiki/Exponential_smoothing
|
||||
- https://orangematter.solarwinds.com/2019/12/15/holt-winters-forecasting-simplified/
|
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
title: "Anomaly-detection"
|
||||
sidebar_label: "Anomaly-detection"
|
||||
---
|
||||
|
||||
本节讲述异常检测算法模型的使用方法。
|
||||
|
||||
## 概述
|
||||
分析平台提供了 6 种异常检查模型,6 种异常检查模型分为 3 个类别,分别属于基于统计的异常检测模型、基于数据密度的检测模型、基于深度学习的异常检测模型。在不指定异常检测使用的方法的情况下,默认调用 iqr 的方法进行计算。
|
||||
|
||||
|
||||
### 统计学异常检测方法
|
||||
|
||||
- k-sigma<sup>[1]</sup>: 即 ***68–95–99.7 rule*** 。***k***值默认为 3,即序列均值的 3 倍标准差范围为边界,超过边界的是异常值。KSigma 要求数据整体上服从正态分布,如果一个点偏离均值 K 倍标准差,则该点被视为异常点.
|
||||
|
||||
|参数|说明|是否必选|默认值|
|
||||
|---|---|---|---|
|
||||
|k|标准差倍数|选填|3|
|
||||
|
||||
|
||||
- IQR<sup>[2]</sup>:四分位距 (Interquartile range, IQR) 是一种衡量变异性的方法. 四分位数将一个按等级排序的数据集划分为四个相等的部分。即 Q1(第 1 个四分位数)、Q2(第 2 个四分位数)和 Q3(第 3 个四分位数)。IQR 定义为 Q3–Q1,位于 Q3+1.5。无输入参数。
|
||||
|
||||
- Grubbs<sup>[3]</sup>: 又称为 Grubbs' test,即最大标准残差测试。Grubbs 通常用作检验最大值、最小值偏离均值的程度是否为异常,该单变量数据集遵循近似标准正态分布。非正态分布数据集不能使用该方法。无输入参数。
|
||||
|
||||
- SHESD<sup>[4]</sup>: 带有季节性的 ESD 检测算法。ESD 可以检测时间序列数据的多异常点。需要指定异常点比例的上界***k***,最差的情况是至多 49.9%。数据集的异常比例一般不超过 5%
|
||||
|
||||
|参数|说明|是否必选|默认值|
|
||||
|---|---|---|---|
|
||||
|k|异常点在输入数据集中占比,范围是$`1\le K \le 49.9`$ |选填|5|
|
||||
|
||||
|
||||
### 基于数据密度的检测方法
|
||||
LOF<sup>[5]</sup>: 局部离群因子(LOF,又叫局部异常因子)算法是 Breunig 于 2000 年提出的一种基于密度的局部离群点检测算法,该方法适用于不同类簇密度分散情况迥异的数据。根据数据点周围的数据密集情况,首先计算每个数据点的一个局部可达密度,然后通过局部可达密度进一步计算得到每个数据点的一个离群因子,该离群因子即标识了一个数据点的离群程度,因子值越大,表示离群程度越高,因子值越小,表示离群程度越低。最后,输出离群程度最大的 top(n) 个点。
|
||||
|
||||
|
||||
### 基于深度学习的检测方法
|
||||
使用自动编码器的异常检测模型。可以对具有周期性的数据具有较好的检测结果。但是使用该模型需要针对输入的时序数据进行训练,同时将训练完成的模型部署到服务目录中,才能够运行与使用。
|
||||
|
||||
|
||||
### 参考文献
|
||||
1. https://en.wikipedia.org/wiki/68%E2%80%9395%E2%80%9399.7_rule
|
||||
2. https://en.wikipedia.org/wiki/Interquartile_range
|
||||
3. Adikaram, K. K. L. B.; Hussein, M. A.; Effenberger, M.; Becker, T. (2015-01-14). "Data Transformation Technique to Improve the Outlier Detection Power of Grubbs's Test for Data Expected to Follow Linear Relation". Journal of Applied Mathematics. 2015: 1–9. doi:10.1155/2015/708948.
|
||||
4. Hochenbaum, O. S. Vallis, and A. Kejariwal. 2017. Automatic Anomaly Detection in the Cloud Via Statistical Learning. arXiv preprint arXiv:1704.07706 (2017).
|
||||
5. Breunig, M. M.; Kriegel, H.-P.; Ng, R. T.; Sander, J. (2000). LOF: Identifying Density-based Local Outliers (PDF). Proceedings of the 2000 ACM SIGMOD International Conference on Management of Data. SIGMOD. pp. 93–104. doi:10.1145/335191.335388. ISBN 1-58113-217-4.
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
---
|
||||
title: "addins"
|
||||
sidebar_label: "addins"
|
||||
---
|
||||
|
||||
本节说明如何将自己开发的预测算法和异常检测算法整合到 TDengine 分析平台,并能够通过 SQL 语句进行调用。
|
||||
|
||||
## 目录结构
|
||||
|
||||

|
||||
|
||||
|目录|说明|
|
||||
|---|---|
|
||||
|taos|Python 源代码目录,其下包含了算法具体保存目录 algo,放置杂项目录 misc,单元测试和集成测试目录 test。 algo 目录下 ad 放置异常检测算法代码,fc 放置预测算法代码|
|
||||
|script|是安装脚本和发布脚本放置目录|
|
||||
|model|放置针对数据集完成的训练模型|
|
||||
|cfg|配置文件目录|
|
||||
|
||||
## 约定与限制
|
||||
|
||||
定义异常检测算法的 Python 代码文件需放在 /taos/algo/ad 目录中,预测算法 Python 代码文件需要放在 /taos/algo/fc 目录中,以确保系统启动的时候能够正常加载对应目录下的 Python 文件。
|
||||
|
||||
|
||||
### 类命名规范
|
||||
|
||||
算法类的名称需要以下划线开始,以 Service 结尾。例如:_KsigmaService 是 KSigma 异常检测算法的实现类。
|
||||
|
||||
### 类继承约定
|
||||
|
||||
- 异常检测算法需要从 `AbstractAnomalyDetectionService` 继承,并实现其核心抽象方法 `execute`
|
||||
- 预测算法需要从 `AbstractForecastService` 继承,同样需要实现其核心抽象方法 `execute`
|
||||
|
||||
### 类属性初始化
|
||||
每个算法实现的类需要静态初始化两个类属性,分别是:
|
||||
|
||||
- `name`:触发调用的关键词,全小写英文字母
|
||||
- `desc`:算法的描述信息
|
||||
|
||||
### 核心方法输入与输出约定
|
||||
|
||||
`execute` 是算法处理的核心方法。调用该方法的时候,`self.list` 已经设置好输入数组。
|
||||
|
||||
异常检测输出结果
|
||||
|
||||
`execute` 的返回值是长度与 `self.list` 相同的数组,数组位置为 -1 的即为异常值点。例如:输入数组是 [2, 2, 2, 2, 100], 如果 100 是异常点,那么返回值是 [1, 1, 1, 1, -1]。
|
||||
|
||||
预测输出结果
|
||||
|
||||
对于预测算法,`AbstractForecastService` 的对象属性说明如下:
|
||||
|
||||
|属性名称|说明|默认值|
|
||||
|---|---|---|
|
||||
|period|输入时间序列的周期性,多少个数据点表示一个完整的周期。如果没有周期性,那么设置为 0 即可| 0|
|
||||
|start_ts|预测结果的开始时间| 0|
|
||||
|time_step|预测结果的两个数据点之间时间间隔|0 |
|
||||
|fc_rows|预测结果的数量| 0 |
|
||||
|return_conf|预测结果中是否包含置信区间范围,如果不包含置信区间,那么上界和下界与自身相同| 1|
|
||||
|conf|置信区间分位数 0.05|
|
||||
|
||||
|
||||
预测返回结果如下:
|
||||
```python
|
||||
return {
|
||||
"rows": self.fc_rows, # 预测数据行数
|
||||
"period": self.period, # 数据周期性,同输入
|
||||
"algo": "holtwinters", # 预测使用的算法
|
||||
"mse": mse, # 预测算法的 mse
|
||||
"res": res # 结果数组 [时间戳数组, 预测结果数组, 预测结果执行区间下界数组,预测结果执行区间上界数组]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 示例代码
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
from service import AbstractAnomalyDetectionService
|
||||
|
||||
# 算法实现类名称 需要以下划线 "_" 开始,并以 Service 结束,如下 _IqrService 是 IQR 异常检测算法的实现类。
|
||||
class _IqrService(AbstractAnomalyDetectionService):
|
||||
""" IQR algorithm 定义类,从 AbstractAnomalyDetectionService 继承,并实现 AbstractAnomalyDetectionService 类的抽象函数 """
|
||||
|
||||
# 定义算法调用关键词,全小写ASCII码(必须添加)
|
||||
name = 'iqr'
|
||||
|
||||
# 该算法的描述信息(建议添加)
|
||||
desc = """found the anomaly data according to the inter-quartile range"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def execute(self):
|
||||
""" execute 是算法实现逻辑的核心实现,直接修改该实现即可 """
|
||||
|
||||
# self.list 是输入数值列,list 类型,例如:[1,2,3,4,5]。设置 self.list 的方法在父类中已经进行了定义。实现自己的算法,修改该文件即可,以下代码使用自己的实现替换即可。
|
||||
#lower = np.quantile(self.list, 0.25)
|
||||
#upper = np.quantile(self.list, 0.75)
|
||||
|
||||
#min_val = lower - 1.5 * (upper - lower)
|
||||
#max_val = upper + 1.5 * (upper - lower)
|
||||
#threshold = [min_val, max_val]
|
||||
|
||||
# 返回值是与输入数值列长度相同的数据列,异常值对应位置是 -1。例如上述输入数据列,返回数值列是 [1, 1, 1, 1, -1],表示 [5] 是异常值。
|
||||
return [-1 if k < threshold[0] or k > threshold[1] else 1 for k in self.list]
|
||||
|
||||
|
||||
def set_params(self, params):
|
||||
"""该算法无需任何输入参数,直接重载父类该函数,不处理算法参数设置逻辑"""
|
||||
pass
|
||||
```
|
||||
|
||||
|
||||
## 单元测试
|
||||
|
||||
在测试文件目录中的 anomaly_test.py 中增加单元测试用例。
|
||||
|
||||
```python
|
||||
def test_iqr(self):
|
||||
""" 测试 _IqrService 类 """
|
||||
s = loader.get_service("iqr")
|
||||
|
||||
# 设置需要进行检测的输入数据
|
||||
s.set_input_list(AnomalyDetectionTest.input_list)
|
||||
|
||||
# 测试 set_params 的处理逻辑
|
||||
try:
|
||||
s.set_params({"k": 2})
|
||||
except ValueError as e:
|
||||
self.assertEqual(1, 0)
|
||||
|
||||
r = s.execute()
|
||||
|
||||
# 绘制异常检测结果
|
||||
draw_ad_results(AnomalyDetectionTest.input_list, r, "iqr")
|
||||
|
||||
# 检查结果
|
||||
self.assertEqual(r[-1], -1)
|
||||
self.assertEqual(len(r), len(AnomalyDetectionTest.input_list))
|
||||
```
|
||||
|
||||
## 需要模型的算法
|
||||
|
||||
针对特定数据集,进行模型训练的算法,在训练完成后。需要将训练得到的模型保存在 model 目录中。需要注意的是,针对每个算法,需要建立独立的文件夹。例如 auto_encoder 的训练算法在 model 目录下建立 autoencoder 的目录,使用该算法针对不同数据集训练得到的模型,均需要放置在该目录下。
|
||||
|
||||
训练完成后的模型,使用 joblib 进行保存。
|
||||
|
||||
并在 model 目录下建立对应的文件夹存放该模型。
|
||||
|
||||
保存模型的调用,可参考 encoder.py 的方式,用户通过调用 set_params 方法,并指定参数 `{"model": "ad_encoder_keras"}` 的方式,可以调用该模型进行计算。
|
||||
|
||||
具体的调用方式如下:
|
||||
|
||||
```python
|
||||
def test_autoencoder_ad(self):
|
||||
# 获取特定的算法服务
|
||||
s = loader.get_service("ac")
|
||||
data = self.__load_remote_data_for_ad()
|
||||
|
||||
# 设置异常检查的输入数据
|
||||
s.set_input_list(data)
|
||||
|
||||
# 指定调用的模型,该模型是之前针对该数据集进行训练获得
|
||||
s.set_params({"model": "ad_encoder_keras"})
|
||||
# 执行检查动作,并返回结果
|
||||
r = s.execute()
|
||||
|
||||
num_of_error = -(sum(filter(lambda x: x == -1, r)))
|
||||
self.assertEqual(num_of_error, 109)
|
||||
```
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
---
|
||||
sidebar_label: 数据分析
|
||||
title: 数据分析功能
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
ANode(Analysis Node)是 TDengine 提供数据分析功能的扩展组件,通过 Restful 接口提供分析服务,拓展 TDengine 的功能,支持时间序列高级分析。
|
||||
ANode 是无状态的数据分析节点,集群中可以存在多个 ANode 节点,相互之间没有关联。将 ANode 注册到 TDengine 集群以后,通过 SQL 语句即可调用并完成时序分析任务。
|
||||
下图是数据分析的技术架构示意图。
|
||||
|
||||

|
||||
|
||||
## 安装部署
|
||||
### 环境准备
|
||||
ANode 要求节点上准备有 Python 3.10 及以上版本,以及相应的 Python 包自动安装组件 Pip,同时请确保能够正常连接互联网。
|
||||
|
||||
### 安装及卸载
|
||||
使用专门的 ANode 安装包 TDengine-enterprise-anode-1.x.x.tar.gz 进行 ANode 的安装部署工作,安装过程与 TDengine 的安装流程一致。
|
||||
|
||||
```bash
|
||||
tar -xzvf TDengine-enterprise-anode-1.0.0.tar.gz
|
||||
cd TDengine-enterprise-anode-1.0.0
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
卸载 ANode,执行命令 `rmtaosanode` 即可。
|
||||
|
||||
### 其他
|
||||
为了避免 ANode 安装后影响目标节点现有的 Python 库。 ANode 使用 Python 虚拟环境运行,安装后的默认 Python 目录处于 `/var/lib/taos/taosanode/venv/`。为了避免反复安装虚拟环境带来的开销,卸载 ANode 并不会自动删除该虚拟环境,如果您确认不需要 Python 的虚拟环境,可以手动删除。
|
||||
|
||||
## 启动及停止服务
|
||||
安装 ANode 以后,可以使用 `systemctl` 来管理 ANode 的服务。使用如下命令可以启动/停止/检查状态。
|
||||
|
||||
```bash
|
||||
systemctl start taosanoded
|
||||
systemctl stop taosanoded
|
||||
systemctl status taosanoded
|
||||
```
|
||||
|
||||
## 目录及配置说明
|
||||
|目录/文件|说明|
|
||||
|---------------|------|
|
||||
|/usr/local/taos/taosanode/bin|可执行文件目录|
|
||||
|/usr/local/taos/taosanode/resource|资源文件目录,链接到文件夹 /var/lib/taos/taosanode/resource/|
|
||||
|/usr/local/taos/taosanode/lib|库文件目录|
|
||||
|/var/lib/taos/taosanode/model/|模型文件目录,链接到文件夹 /var/lib/taos/taosanode/model|
|
||||
|/var/log/taos/taosanode/|日志文件目录|
|
||||
|/etc/taos/taosanode.ini|配置文件|
|
||||
|
||||
### 配置说明
|
||||
|
||||
Anode 提供的 RestFul 服务使用 uWSGI 驱动,因此 ANode 和 uWSGI 的配置信息存放在同一个配置文件中,具体如下:
|
||||
|
||||
```ini
|
||||
[uwsgi]
|
||||
# charset
|
||||
env = LC_ALL = en_US.UTF-8
|
||||
|
||||
# ip:port
|
||||
http = 127.0.0.1:6050
|
||||
|
||||
# the local unix socket file than communicate to Nginx
|
||||
#socket = 127.0.0.1:8001
|
||||
#socket-timeout = 10
|
||||
|
||||
# base directory
|
||||
chdir = /usr/local/taos/taosanode/lib
|
||||
|
||||
# initialize python file
|
||||
wsgi-file = /usr/local/taos/taosanode/lib/taos/app.py
|
||||
|
||||
# call module of uWSGI
|
||||
callable = app
|
||||
|
||||
# auto remove unix Socket and pid file when stopping
|
||||
vacuum = true
|
||||
|
||||
# socket exec model
|
||||
#chmod-socket = 664
|
||||
|
||||
# uWSGI pid
|
||||
uid = root
|
||||
|
||||
# uWSGI gid
|
||||
gid = root
|
||||
|
||||
# main process
|
||||
master = true
|
||||
|
||||
# the number of worker processes
|
||||
processes = 2
|
||||
|
||||
# pid file
|
||||
pidfile = /usr/local/taos/taosanode/taosanode.pid
|
||||
|
||||
# enable threads
|
||||
enable-threads = true
|
||||
|
||||
# the number of threads for each process
|
||||
threads = 4
|
||||
|
||||
# memory useage report
|
||||
memory-report = true
|
||||
|
||||
# smooth restart
|
||||
reload-mercy = 10
|
||||
|
||||
# conflict with systemctl, so do NOT uncomment this
|
||||
# daemonize = /var/log/taos/taosanode/taosanode.log
|
||||
|
||||
# log directory
|
||||
logto = /var/log/taos/taosanode/taosanode.log
|
||||
|
||||
# wWSGI monitor port
|
||||
stats = 127.0.0.1:8387
|
||||
|
||||
# python virtual environment directory
|
||||
virtualenv = /usr/local/taos/taosanode/venv/
|
||||
|
||||
[taosanode]
|
||||
# default app log file
|
||||
app-log = /var/log/taos/taosanode/taosanode.app.log
|
||||
|
||||
# model storage directory
|
||||
model-dir = /usr/local/taos/taosanode/model/
|
||||
|
||||
# default log level
|
||||
log-level = DEBUG
|
||||
|
||||
# draw the query results
|
||||
draw-result = 0
|
||||
```
|
||||
|
||||
**提示**
|
||||
请勿设置 `daemonize` 参数,该参数会导致 uWSGI 与 systemctl 冲突,从而无法正常启动。
|
||||
|
||||
|
||||
## ANode 基本操作
|
||||
### 管理 ANode
|
||||
#### 创建 ANode
|
||||
```sql
|
||||
CREATE ANODE {node_url}
|
||||
```
|
||||
node_url 是提供服务的 ANode 的 IP 和 PORT, 例如:`create anode 'http://localhost:6050'`。启动 ANode 以后如果不注册到 TDengine 集群中,则无法提供正常的服务。不建议 ANode 注册到两个或多个集群中。
|
||||
|
||||
#### 查看 ANode
|
||||
列出集群中所有的数据分析节点,包括其 `FQDN`, `PORT`, `STATUS`。
|
||||
```sql
|
||||
SHOW ANODES;
|
||||
```
|
||||
|
||||
#### 查看提供的时序数据分析服务
|
||||
|
||||
```SQL
|
||||
SHOW ANODES FULL;
|
||||
```
|
||||
|
||||
#### 强制刷新集群中的分析算法缓存
|
||||
```SQL
|
||||
UPDATE ANODE {node_id}
|
||||
UPDATE ALL ANODES
|
||||
```
|
||||
|
||||
#### 删除 ANode
|
||||
```sql
|
||||
DROP ANODE {anode_id}
|
||||
```
|
||||
删除 ANode 只是将 ANode 从 TDengine 集群中删除,管理 ANode 的启停仍然需要使用`systemctl`命令。
|
||||
|
||||
### 时序数据分析功能
|
||||
|
||||
#### 白噪声检查
|
||||
|
||||
分析平台提供的 Restful 服务要求输入的时间序列不能是白噪声时间序列(White Noise Data, WND)和随机数序列 , 因此针对所有数据均默认进行白噪声检查。当前白噪声检查采用通行的 `Ljung-Box` 检验,`Ljung-Box` 统计量检查过程需要遍历整个输入序列并进行计算。
|
||||
如果用户能够明确输入序列一定不是白噪声序列,那么可以通过输入参数,指定预测之前忽略该检查,从而节省分析过程的 CPU 计算资源。
|
||||
同时支持独立地针对输入序列进行白噪声检测(该检测功能暂不独立对外开放)。
|
||||
|
||||
|
||||
#### 数据重采样和时间戳对齐
|
||||
|
||||
分析平台支持将输入数据进行重采样预处理,从而确保输出结果按照用户指定的等间隔进行处理。处理过程分为两种类别:
|
||||
|
||||
- 数据时间戳对齐。由于真实数据可能并非严格按照查询指定的时间戳输入。此时分析平台会自动将数据的时间间隔按照指定的时间间隔进行对齐。例如输入时间序列 [11, 22, 29, 41],用户指定时间间隔为 10,该序列将被对齐重整为以下序列 [10, 20, 30, 40]。
|
||||
- 数据时间重采样。用户输入时间序列的采样频率超过了输出结果的频率,例如输入时间序列的采样频率是 5,输出结果的频率是 10,输入时间序列 [0, 5, 10, 15, 20, 25, 30] 将被重采用为间隔 为 10 的序列 [0, 10, 20,30],[5, 15, 25] 处的数据将被丢弃。
|
||||
|
||||
需要注意的是,数据输入平台不支持缺失数据补齐后进行的预测分析,如果输入时间序列数据 [11, 22, 29, 49],并且用户要求的时间间隔为 10,重整对齐后的序列是 [10, 20, 30, 50] 那么该序列进行预测分析将返回错误。
|
||||
|
||||
|
||||
#### 时序数据异常检测
|
||||
异常检测是针对输入的时序数据,使用预设或用户指定的算法确定时间序列中**可能**出现异常的时间序列点,对于时间序列中若干个连续的异常点,将自动合并成为一个连续的(闭区间)异常窗口。对于只有单个点的场景,异常窗口窗口退化成为一个起始时间和结束时间相同的点。
|
||||
异常检测生成的异常窗口受检测算法和算法参数的共同影响,对于异常窗口范围内的数据,可以应用 TDengine 提供的聚合和标量函数进行查询或变换处理。
|
||||
对于输入时间序列 (1, 20), (2, 22), (3, 91), (4, 120), (5, 18), (6, 19)。系统检测到 (3, 91), (4, 120) 为异常点,那么返回的异常窗口是闭区间 [3, 4]。
|
||||
|
||||
|
||||
##### 语法
|
||||
|
||||
```SQL
|
||||
ANOMALY_WINDOW(column_name, option_expr)
|
||||
|
||||
option_expr: {"
|
||||
algo=expr1
|
||||
[,wncheck=1|0]
|
||||
[,expr2]
|
||||
"}
|
||||
```
|
||||
|
||||
1. `column`:进行时序数据异常检测的输入数据列,当前只支持单列,且只能是数值类型,不能是字符类型(例如:`NCHAR` `VARCHAR` `VARBINARY`等类型),**不支持函数表达式**。
|
||||
2. `options`:字符串。其中使用 K=V 调用异常检测算法及与算法相关的参数。采用逗号分隔的 K=V 字符串表示,其中的字符串不需要使用单引号、双引号、或转义号等符号,不能使用中文及其他宽字符。例如:`algo=ksigma,k=2` 表示进行异常检测的算法是 ksigma,该算法接受的输入参数是 2。
|
||||
3. 异常检测的结果可以作为外层查询的子查询输入,在 `SELECT` 子句中使用的聚合函数或标量函数与其他类型的窗口查询相同。
|
||||
4. 输入数据默认进行白噪声检查,如果输入数据是白噪声,将不会有任何(异常)窗口信息返回。
|
||||
|
||||
**参数说明**
|
||||
|参数|含义|默认值|
|
||||
|---|---|---|
|
||||
|algo|异常检测调用的算法|iqr|
|
||||
|wncheck|对输入数据列是否进行白噪声检查|取值为 0 或者 1,默认值为 1,表示进行白噪声检查|
|
||||
|
||||
异常检测的返回结果以窗口形式呈现,因此窗口查询相关的伪列在这种场景下仍然可用。可以使用的伪列如下:
|
||||
1. `_WSTART`: 异常窗口开始时间戳
|
||||
2. `_WEND`:异常窗口结束时间戳
|
||||
3. `_WDURATION`:异常窗口持续时间
|
||||
|
||||
**示例**
|
||||
```SQL
|
||||
--- 使用 iqr 算法进行异常检测,检测列 i32 列。
|
||||
SELECT _wstart, _wend, SUM(i32)
|
||||
FROM ai.atb
|
||||
ANOMALY_WINDOW(i32, "algo=iqr");
|
||||
|
||||
--- 使用 ksigma 算法进行异常检测,输入参数 k 值为 2,检测列 i32 列
|
||||
SELECT _wstart, _wend, SUM(i32)
|
||||
FROM ai.atb
|
||||
ANOMALY_WINDOW(i32, "algo=ksigma,k=2");
|
||||
```
|
||||
|
||||
```
|
||||
taos> SELECT _wstart, _wend, count(*) FROM ai.atb ANOMAYL_WINDOW(i32);
|
||||
_wstart | _wend | count(*) |
|
||||
====================================================================
|
||||
2020-01-01 00:00:16.000 | 2020-01-01 00:00:16.001 | 1 |
|
||||
Query OK, 1 row(s) in set (0.028946s)
|
||||
```
|
||||
|
||||
|
||||
**可用异常检测算法**
|
||||
- iqr
|
||||
- ksigma
|
||||
- grubbs
|
||||
- lof
|
||||
- shesd
|
||||
- tac
|
||||
|
||||
|
||||
#### 时序数据预测
|
||||
数据预测以一段训练数据作为输入,预测接下来一个连续时间区间内,时序数据的趋势。
|
||||
|
||||
##### 语法
|
||||
```SQL
|
||||
FORECAST(column_expr, option_expr)
|
||||
|
||||
option_expr: {"
|
||||
algo=expr1
|
||||
[,wncheck=1|0]
|
||||
[,conf=conf_val]
|
||||
[,every=every_val]
|
||||
[,rows=rows_val]
|
||||
[,start=start_ts_val]
|
||||
[,expr2]
|
||||
"}
|
||||
|
||||
```
|
||||
1. `column_expr`:预测的时序数据列。与异常检测相同,只支持数值类型输入。
|
||||
2. `options`:异常检测函数的参数,使用规则与 anomaly_window 相同。预测还支持 `conf`, `every`, `rows`, `start`, `rows` 几个参数,其含义如下:
|
||||
|
||||
**参数说明**
|
||||
|
||||
|参数|含义|默认值|
|
||||
|---|---|---|
|
||||
|algo|预测分析使用的算法|holtwinters|
|
||||
|wncheck|白噪声(white noise data)检查|默认值为 1,0 表示不进行检查|
|
||||
|conf|预测数据的置信区间范围 ,取值范围 [0, 100]|95|
|
||||
|every|预测数据的采样间隔|输入数据的采样间隔|
|
||||
|start|预测结果的开始时间戳|输入数据最后一个时间戳加上一个采样时间段|
|
||||
|rows|预测结果的记录数|10|
|
||||
|
||||
1. 预测查询结果新增了三个伪列,具体如下:`_FROWTS`:预测结果的时间戳、`_FLOW`:置信区间下界、`_FHIGH`:置信区间上界, 对于没有置信区间的预测算法,其置信区间同预测结果
|
||||
2. 更改参数 `START`:返回预测结果的起始时间,改变起始时间不会影响返回的预测数值,只影响起始时间。
|
||||
3. `EVERY`:可以与输入数据的采样频率不同。采样频率只能低于或等于输入数据采样频率,不能**高于**输入数据的采样频率。
|
||||
4. 对于某些不需要计算置信区间的算法,即使指定了置信区间,返回的结果中其上下界退化成为一个点。
|
||||
|
||||
**示例**
|
||||
|
||||
```SQL
|
||||
--- 使用 arima 算法进行预测,预测结果是 10 条记录(默认值),数据进行白噪声检查,默认置信区间 95%.
|
||||
SELECT _flow, _fhigh, _frowts, FORECAST(i32, "algo=arima")
|
||||
FROM ai.ftb;
|
||||
|
||||
--- 使用 arima 算法进行预测,输入数据的是周期数据,每 10 个采样点是一个周期。返回置信区间是 95%.
|
||||
SELECT _flow, _fhigh, _frowts, FORECAST(i32, "algo=arima,alpha=95,period=10")
|
||||
FROM ai.ftb;
|
||||
```
|
||||
```
|
||||
taos> select _flow, _fhigh, _frowts, forecast(i32) from ai.ftb;
|
||||
_flow | _fhigh | _frowts | forecast(i32) |
|
||||
========================================================================================
|
||||
10.5286684 | 41.8038254 | 2020-01-01 00:01:35.001 | 26 |
|
||||
-21.9861946 | 83.3938904 | 2020-01-01 00:01:36.001 | 30 |
|
||||
-78.5686035 | 144.6729126 | 2020-01-01 00:01:37.001 | 33 |
|
||||
-154.9797363 | 230.3057709 | 2020-01-01 00:01:38.001 | 37 |
|
||||
-253.9852905 | 337.6083984 | 2020-01-01 00:01:39.001 | 41 |
|
||||
-375.7857971 | 466.4594727 | 2020-01-01 00:01:40.001 | 45 |
|
||||
-514.8043823 | 622.4426270 | 2020-01-01 00:01:41.001 | 53 |
|
||||
-680.6343994 | 796.2861328 | 2020-01-01 00:01:42.001 | 57 |
|
||||
-868.4956665 | 992.8603516 | 2020-01-01 00:01:43.001 | 62 |
|
||||
-1076.1566162 | 1214.4498291 | 2020-01-01 00:01:44.001 | 69 |
|
||||
```
|
||||
|
||||
|
||||
**可用预测算法**
|
||||
- arima
|
||||
- holtwinters
|
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
|
@ -53,7 +53,7 @@ M = (T × S × 3 + (N / 4096) + 100)
|
|||
|
||||
与 WebSocket 连接方式相比,RESTful 连接方式在内存占用上更大,除了缓冲区所需的内存以外,还需要考虑每个连接响应结果的内存开销。这种内存开销与响应结果的JSON 数据大小密切相关,特别是在查询数据量很大时,会占用大量内存。
|
||||
|
||||
由于 RESTful 连接方式不支持分批获取查询数据,这就导致在查询获取超大结果集时,可能会占用特别大的内存,从而导致内存溢出,因此,在大型项目中,建议打开batchfetch=true 选项,以启用 WebSocket 连接方式,实现流式结果集返回,从而避免内存溢出的风险
|
||||
由于 RESTful 连接方式不支持分批获取查询数据,这就导致在查询获取超大结果集时,可能会占用特别大的内存,从而导致内存溢出,因此,在大型项目中,建议使用 WebSocket 连接方式,实现流式结果集返回,从而避免内存溢出的风险
|
||||
|
||||
**注意**
|
||||
- 建议采用 RESTful/WebSocket 连接方式来访问 TDengine 集群,而不采用taosc 原生连接方式。
|
||||
|
@ -146,11 +146,17 @@ TDengine 的多级存储功能在使用上还具备以下优点。
|
|||
|
||||
下表列出了 TDengine 的一些接口或组件的常用端口,这些端口均可以通过配置文件中的参数进行修改。
|
||||
|
||||
|接口或组件 | 端口 |
|
||||
|:---------------------------:|:---------:|
|
||||
|原生接口(taosc) | 6030 |
|
||||
|RESTful 接口 | 6041 |
|
||||
|WebSocket 接口 |6041 |
|
||||
|taosKeeper | 6043 |
|
||||
|taosX | 6050, 6055 |
|
||||
|taosExplorer | 6060 |
|
||||
| 接口或组件名称 | 端口 | 协议 |
|
||||
|:-----------------------------------------:|:----------:|:--------:|
|
||||
| 原生接口(taosc) | 6030 | TCP |
|
||||
| RESTful 接口 | 6041 | TCP |
|
||||
| WebSocket 接口 | 6041 | TCP |
|
||||
| taosKeeper | 6043 | TCP |
|
||||
| statsd 格式写入接口 | 6044 | TCP/UDP |
|
||||
| collectd 格式写入接口 | 6045 | TCP/UDP |
|
||||
| openTSDB Telnet 格式写入接口 | 6046 | TCP |
|
||||
| collectd 使用 openTSDB Telnet 格式写入接口 | 6047 | TCP |
|
||||
| icinga2 使用 openTSDB Telnet 格式写入接口 | 6048 | TCP |
|
||||
| tcollector 使用 openTSDB Telnet 格式写入接口 | 6049 | TCP |
|
||||
| taosX | 6050, 6055 | TCP |
|
||||
| taosExplorer | 6060 | TCP |
|
||||
|
|
|
@ -368,6 +368,18 @@ spec:
|
|||
labels:
|
||||
app: "tdengine"
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- tdengine
|
||||
topologyKey: kubernetes.io/hostname
|
||||
containers:
|
||||
- name: "tdengine"
|
||||
image: "tdengine/tdengine:3.2.3.0"
|
||||
|
|
|
@ -76,7 +76,7 @@ dataDir /mnt/data6 2 0
|
|||
|s3UploadDelaySec | data 文件持续多长时间不再变动后上传至 s3,单位:秒。最小值:1;最大值:2592000 (30天),默认值 60 秒 |
|
||||
|s3PageCacheSize |s3 page cache 缓存页数目,单位:页。最小值:4;最大值:1024*1024\*1024。 ,默认值 4096|
|
||||
|s3MigrateIntervalSec | 本地数据文件自动上传 S3 的触发周期,单位为秒。最小值:600;最大值:100000。默认值 3600 |
|
||||
|s3MigrateEnabled | 是否自动进行 S3 迁移,默认值为 1,表示开启自动 S3 迁移,可配置为 0。 |
|
||||
|s3MigrateEnabled | 是否自动进行 S3 迁移,默认值为 0,表示关闭自动 S3 迁移,可配置为 1。 |
|
||||
|
||||
### 检查配置参数可用性
|
||||
|
||||
|
@ -108,9 +108,37 @@ s3migrate database <db_name>;
|
|||
|
||||
| # | 参数 | 默认值 | 最小值 | 最大值 | 描述 |
|
||||
| :--- | :----------- | :----- | :----- | :------ | :----------------------------------------------------------- |
|
||||
| 1 | s3_keeplocal | 3650 | 1 | 365000 | 数据在本地保留的天数,即 data 文件在本地磁盘保留多长时间后可以上传到 S3。默认单位:天,支持 m(分钟)、h(小时)和 d(天)三个单位 |
|
||||
| 2 | s3_chunksize | 262144 | 131072 | 1048576 | 上传对象的大小阈值,与 TSDB_PAGESIZE 参数一样,不可修改,单位为 TSDB 页 |
|
||||
| 3 | s3_compact | 0 | 0 | 1 | TSDB 文件组首次上传 S3 时,是否自动进行 compact 操作。 |
|
||||
| 1 | s3_keeplocal | 365 | 1 | 365000 | 数据在本地保留的天数,即 data 文件在本地磁盘保留多长时间后可以上传到 S3。默认单位:天,支持 m(分钟)、h(小时)和 d(天)三个单位 |
|
||||
| 2 | s3_chunkpages | 131072 | 131072 | 1048576 | 上传对象的大小阈值,与 tsdb_pagesize 参数一样,不可修改,单位为 TSDB 页 |
|
||||
| 3 | s3_compact | 1 | 0 | 1 | TSDB 文件组首次上传 S3 时,是否自动进行 compact 操作。 |
|
||||
|
||||
### 对象存储读写次数估算
|
||||
|
||||
对象存储服务的使用成本与存储的数据量及请求次数相关,下面分别介绍数据的上传及下载过程。
|
||||
|
||||
#### 数据上传
|
||||
|
||||
当 TSDB 时序数据超过 `s3_keeplocal` 参数指定的时间,相关的数据文件会被切分成多个文件块,每个文件块的默认大小是 512M 字节 (`s3_chunkpages * tsdb_pagesize`)。除了最后一个文件块保留在本地文件系统外,其余的文件块会被上传到对象存储服务。
|
||||
|
||||
```math
|
||||
上传次数 = 数据文件大小 / (s3_chunkpages * tsdb_pagesize) - 1
|
||||
```
|
||||
|
||||
在创建数据库时,可以通过 `s3_chunkpages` 参数调整每个文件块的大小,从而控制每个数据文件的上传次数。
|
||||
|
||||
其它类型的文件如 head, stt, sma 等,保留在本地文件系统,以加速预计算相关查询。
|
||||
|
||||
#### 数据下载
|
||||
|
||||
在查询操作中,如果需要访问对象存储中的数据,TSDB 不会下载整个数据文件,而是计算所需数据在文件中的位置,只下载相应的数据到 TSDB 页缓存中,然后将数据返回给查询执行引擎。后续查询首先检查页缓存,查看数据是否已被缓存。如果数据已缓存,则直接使用缓存中的数据,而无需重复从对象存储下载,从而有效降低从对象存储下载数据的次数。
|
||||
|
||||
相邻的多个数据页会作为一个数据块从对象存储下载一次,以减少从对象存储下载的次数。每个数据页的大小,在创建数据库时,通过 `tsdb_pagesize` 参数指定,默认 4K 字节。
|
||||
|
||||
```math
|
||||
下载次数 = 查询需要的数据块数量 - 已缓存的数据块数量
|
||||
```
|
||||
|
||||
页缓存是内存缓存,节点重启后,再次查询需要重新下载数据。缓存采用 LRU (Least Recently Used) 策略,当缓存空间不足时,最近最少使用的数据将被淘汰。缓存的大小可以通过 `s3PageCacheSize` 参数进行调整,通常来说,缓存越大,下载次数越少。
|
||||
|
||||
## Azure Blob 存储
|
||||
本节介绍在 TDengine Enterprise 如何使用微软 Azure Blob 对象存储。本功能是上一小节‘对象存储’功能的扩展,需额外依赖 Flexify 服务提供的 S3 网关。通过适当的参数配置,可以把大部分较冷的时序数据存储到 Azure Blob 服务中。
|
||||
|
@ -135,3 +163,15 @@ s3BucketName td-test
|
|||
- 认为全部 S3 服务均指向同一数据源,对各个 S3 服务操作完全等价
|
||||
- 在某一 S3 服务上操作失败后会切换至其他服务,全部服务都失败后将返回最后产生的错误码
|
||||
- 最大支持的 S3 服务配置数为 10
|
||||
|
||||
### 不依赖 Flexify 服务
|
||||
|
||||
用户界面同 S3,不同的地方在于下面三个参数的配置:
|
||||
|
||||
| # | 参数 | 示例值 | 描述 |
|
||||
| :--- | :----------- | :--------------------------------------- | :----------------------------------------------------------- |
|
||||
| 1 | s3EndPoint | https://fd2d01c73.blob.core.windows.net | Blob URL |
|
||||
| 2 | s3AccessKey | fd2d01c73:veUy/iRBeWaI2YAerl+AStw6PPqg== | 冒号分隔的用户 accountId:accountKey |
|
||||
| 3 | s3BucketName | test-container | Container name |
|
||||
|
||||
其中 fd2d01c73 是账户 ID;微软 Blob 存储服务只支持 Https 协议,不支持 Http。
|
||||
|
|
|
@ -33,7 +33,7 @@ taosd 命令行参数如下
|
|||
| secondEp | taosd 启动时,如果 firstEp 连接不上,尝试连接集群中第二个 dnode 的 endpoint,缺省值:无 |
|
||||
| fqdn | 启动 taosd 后所监听的服务地址,缺省值:所在服务器上配置的第一个 hostname |
|
||||
| serverPort | 启动 taosd 后所监听的端口,缺省值:6030 |
|
||||
| numOfRpcSessions | 允许一个客户端能创建的最大连接数,取值范围 100-100000,缺省值:30000 |
|
||||
| numOfRpcSessions | 允许一个 dnode 能发起的最大连接数,取值范围 100-100000,缺省值:30000 |
|
||||
| timeToGetAvailableConn | 获得可用连接的最长等待时间,取值范围 10-50000000,单位为毫秒,缺省值:500000 |
|
||||
|
||||
### 监控相关
|
||||
|
@ -156,14 +156,14 @@ charset 的有效值是 UTF-8。
|
|||
### 内存相关
|
||||
| 参数名称 | 参数说明 |
|
||||
| :----------------: | :---------------------------------------------: |
|
||||
| rpcQueueMemoryAllowed | 一个 dnode 允许的 rpc 消息占用的内存最大值,单位 bytes,取值范围:10485760-INT64_MAX,缺省值:服务器内存的 1/10 |
|
||||
| syncLogBufferMemoryAllowed | 一个 dnode 允许的 sync 日志缓存消息占用的内存最大值,单位 bytes,取值范围:10485760-INT64_MAX,缺省值:服务器内存的 1/10,3.1.3.2/3.3.2.13 版本开始生效 |
|
||||
| rpcQueueMemoryAllowed | 一个 dnode 允许的 rpc 消息占用的内存最大值,单位 bytes,取值范围:104857600-INT64_MAX,缺省值:服务器内存的 1/10 |
|
||||
| syncLogBufferMemoryAllowed | 一个 dnode 允许的 sync 日志缓存消息占用的内存最大值,单位 bytes,取值范围:104857600-INT64_MAX,缺省值:服务器内存的 1/10,3.1.3.2/3.3.2.13 版本开始生效 |
|
||||
|
||||
### 性能调优
|
||||
|
||||
| 参数名称 | 参数说明 |
|
||||
| :----------------: | :---------------------------------------------: |
|
||||
| numOfCommitThreads | 写入线程的最大数量,取值范围 0-1024,缺省值为 4 |
|
||||
| numOfCommitThreads | 落盘线程的最大数量,取值范围 0-1024,缺省值为 4 |
|
||||
|
||||
### 日志相关
|
||||
|
||||
|
@ -180,6 +180,7 @@ charset 的有效值是 UTF-8。
|
|||
| tmrDebugFlag | 定时器模块的日志开关,取值范围同上 |
|
||||
| uDebugFlag | 共用功能模块的日志开关,取值范围同上 |
|
||||
| rpcDebugFlag | rpc 模块的日志开关,取值范围同上 |
|
||||
| cDebugFlag | 客户端模块的日志开关,取值范围同上 |
|
||||
| jniDebugFlag | jni 模块的日志开关,取值范围同上 |
|
||||
| qDebugFlag | query 模块的日志开关,取值范围同上 |
|
||||
| dDebugFlag | dnode 模块的日志开关,取值范围同上,缺省值 135 |
|
||||
|
@ -223,11 +224,11 @@ lossyColumns float|double
|
|||
|
||||
| 参数名称 | 参数说明 |
|
||||
| :--------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||
| enableCoreFile | crash 时是否生成 core 文件;0: 不生成,1:生成;默认值 为 1; 不同的启动方式,生成 core 文件的目录如下:1、systemctl start taosd 启动:生成的 core 在根目录下 <br/> 2、手动启动,就在 taosd 执行目录下。 |
|
||||
| udf | 是否启动 UDF 服务;0: 不启动,1:启动;默认值 为 0 |
|
||||
| ttlChangeOnWrite | ttl 到期时间是否伴随表的修改操作改变; 0: 不改变,1:改变 ;默认值 为 |
|
||||
| tmqMaxTopicNum | 订阅最多可建立的 topic 数量; 取值范围 1-10000;缺省值 为20 |
|
||||
| maxTsmaNum | 集群内可创建的TSMA个数;取值范围:0-3;缺省值: 3 |
|
||||
| enableCoreFile | crash 时是否生成 core 文件;0: 不生成,1:生成;默认值为 1; 不同的启动方式,生成 core 文件的目录如下:1、systemctl start taosd 启动:生成的 core 在根目录下 <br/> 2、手动启动,就在 taosd 执行目录下。 |
|
||||
| udf | 是否启动 UDF 服务;0: 不启动,1:启动;默认值为 0 |
|
||||
| ttlChangeOnWrite | ttl 到期时间是否伴随表的修改操作改变; 0: 不改变,1:改变;默认值为 0 |
|
||||
| tmqMaxTopicNum | 订阅最多可建立的 topic 数量; 取值范围 1-10000;缺省值为20 |
|
||||
| maxTsmaNum | 集群内可创建的TSMA个数;取值范围:0-3;缺省值为 3 |
|
||||
|
||||
|
||||
## taosd 监控指标
|
||||
|
|
|
@ -10,7 +10,7 @@ TDengine 客户端驱动提供了应用编程所需要的全部 API,并且在
|
|||
|
||||
| 参数名称 | 参数含义 |
|
||||
|:-----------:|:----------------------------------------------------------:|
|
||||
|firstEp | taos 启动时,主动连接的集群中首个 dnode 的 endpoint,缺省值:${hostname}:6030,若无法获取 ${hostname},则赋值为 localhost |
|
||||
|firstEp | taos 启动时,主动连接的集群中首个 dnode 的 endpoint,缺省值:hostname:6030,若无法获取该服务器的 hostname,则赋值为 localhost |
|
||||
|secondEp | 启动时,如果 firstEp 连接不上,尝试连接集群中第二个 dnode 的 endpoint,没有缺省值 |
|
||||
|numOfRpcSessions | 一个客户端能创建的最大连接数,取值范围:10-50000000(单位为毫秒);缺省值:500000 |
|
||||
|telemetryReporting | 是否上传 telemetry,0: 不上传,1: 上传;缺省值:1 |
|
||||
|
@ -35,6 +35,7 @@ TDengine 客户端驱动提供了应用编程所需要的全部 API,并且在
|
|||
|smlAutoChildTableNameDelimiter | schemaless tag之间的连接符,连起来作为子表名,无缺省值 |
|
||||
|smlTagName | schemaless tag 为空时默认的 tag 名字, 缺省值 "_tag_null" |
|
||||
|smlTsDefaultName | schemaless自动建表的时间列名字通过该配置设置, 缺省值 "_ts" |
|
||||
|smlDot2Underline | schemaless 把超级表名中的 dot 转成下划线 |
|
||||
|enableCoreFile | crash 时是否生成 core 文件,0: 不生成, 1: 生成;缺省值:1 |
|
||||
|enableScience | 是否开启科学计数法显示浮点数; 0: 不开始, 1: 开启;缺省值:1 |
|
||||
|compressMsgSize | 是否对 RPC 消息进行压缩; -1: 所有消息都不压缩; 0: 所有消息都压缩; N (N>0): 只有大于 N 个字节的消息才压缩; 缺省值 -1|
|
||||
|
|
|
@ -13,7 +13,7 @@ taosKeeper 是 TDengine 3.0 版本监控指标的导出工具,通过简单的
|
|||
|
||||
taosKeeper 有两种安装方式:
|
||||
|
||||
- 安装 TDengine 官方安装包的同时会自动安装 taosKeeper, 详情请参考[ TDengine 安装](../../../get-started/)。
|
||||
- 安装 TDengine 官方安装包的同时会自动安装 taosKeeper, 详情请参考[TDengine 安装](../../../get-started/)。
|
||||
|
||||
- 单独编译 taosKeeper 并安装,详情请参考 [taosKeeper](https://github.com/taosdata/taoskeeper) 仓库。
|
||||
|
||||
|
@ -22,34 +22,45 @@ taosKeeper 有两种安装方式:
|
|||
taosKeeper 需要在操作系统终端执行,该工具支持三种配置方式:命令行参数、环境变量 和 配置文件。优先级为:命令行参数、环境变量、配置文件参数。 一般我们推荐使用配置文件。
|
||||
|
||||
### 命令行参数和环境变量
|
||||
|
||||
命令行参数 和 环境变量说明可以参考命令 `taoskeeper --help` 的输出。下面是一个例子:
|
||||
|
||||
```shell
|
||||
Usage of taosKeeper v3.3.2.0:
|
||||
--debug enable debug mode. Env "TAOS_KEEPER_DEBUG"
|
||||
-P, --port int http port. Env "TAOS_KEEPER_PORT" (default 6043)
|
||||
--logLevel string log level (panic fatal error warn warning info debug trace). Env "TAOS_KEEPER_LOG_LEVEL" (default "info")
|
||||
--gopoolsize int coroutine size. Env "TAOS_KEEPER_POOL_SIZE" (default 50000)
|
||||
Usage of taoskeeper v3.3.3.0:
|
||||
-R, --RotationInterval string interval for refresh metrics, such as "300ms", Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Env "TAOS_KEEPER_ROTATION_INTERVAL" (default "15s")
|
||||
-c, --config string config path default /etc/taos/taoskeeper.toml
|
||||
--drop string run taoskeeper in command mode, only support old_taosd_metric_stables.
|
||||
--environment.incgroup whether running in cgroup. Env "TAOS_KEEPER_ENVIRONMENT_INCGROUP"
|
||||
--fromTime string parameter of transfer, example: 2020-01-01T00:00:00+08:00 (default "2020-01-01T00:00:00+08:00")
|
||||
--gopoolsize int coroutine size. Env "TAOS_KEEPER_POOL_SIZE" (default 50000)
|
||||
-h, --help Print this help message and exit
|
||||
--instanceId int instance ID. Env "TAOS_KEEPER_INSTANCE_ID" (default 64)
|
||||
--log.compress whether to compress old log. Env "TAOS_KEEPER_LOG_COMPRESS"
|
||||
--log.keepDays uint log retention days, must be a positive integer. Env "TAOS_KEEPER_LOG_KEEP_DAYS" (default 30)
|
||||
--log.level string log level (trace debug info warning error). Env "TAOS_KEEPER_LOG_LEVEL" (default "info")
|
||||
--log.path string log path. Env "TAOS_KEEPER_LOG_PATH" (default "/var/log/taos")
|
||||
--log.reservedDiskSize string reserved disk size for log dir (KB MB GB), must be a positive integer. Env "TAOS_KEEPER_LOG_RESERVED_DISK_SIZE" (default "1GB")
|
||||
--log.rotationCount uint log rotation count. Env "TAOS_KEEPER_LOG_ROTATION_COUNT" (default 5)
|
||||
--log.rotationSize string log rotation size(KB MB GB), must be a positive integer. Env "TAOS_KEEPER_LOG_ROTATION_SIZE" (default "1GB")
|
||||
--log.rotationTime duration deprecated: log rotation time always 24 hours. Env "TAOS_KEEPER_LOG_ROTATION_TIME" (default 24h0m0s)
|
||||
--logLevel string log level (trace debug info warning error). Env "TAOS_KEEPER_LOG_LEVEL" (default "info")
|
||||
--metrics.database.name string database for storing metrics data. Env "TAOS_KEEPER_METRICS_DATABASE" (default "log")
|
||||
--metrics.database.options.buffer int database option buffer for audit database. Env "TAOS_KEEPER_METRICS_BUFFER" (default 64)
|
||||
--metrics.database.options.cachemodel string database option cachemodel for audit database. Env "TAOS_KEEPER_METRICS_CACHEMODEL" (default "both")
|
||||
--metrics.database.options.keep int database option buffer for audit database. Env "TAOS_KEEPER_METRICS_KEEP" (default 90)
|
||||
--metrics.database.options.vgroups int database option vgroups for audit database. Env "TAOS_KEEPER_METRICS_VGROUPS" (default 1)
|
||||
--metrics.prefix string prefix in metrics names. Env "TAOS_KEEPER_METRICS_PREFIX"
|
||||
--metrics.tables stringArray export some tables that are not super table, multiple values split with white space. Env "TAOS_KEEPER_METRICS_TABLES"
|
||||
-P, --port int http port. Env "TAOS_KEEPER_PORT" (default 6043)
|
||||
--tdengine.host string TDengine server's ip. Env "TAOS_KEEPER_TDENGINE_HOST" (default "127.0.0.1")
|
||||
--tdengine.password string TDengine server's password. Env "TAOS_KEEPER_TDENGINE_PASSWORD" (default "taosdata")
|
||||
--tdengine.port int TDengine REST server(taosAdapter)'s port. Env "TAOS_KEEPER_TDENGINE_PORT" (default 6041)
|
||||
--tdengine.username string TDengine server's username. Env "TAOS_KEEPER_TDENGINE_USERNAME" (default "root")
|
||||
--tdengine.password string TDengine server's password. Env "TAOS_KEEPER_TDENGINE_PASSWORD" (default "taosdata")
|
||||
--tdengine.usessl TDengine server use ssl or not. Env "TAOS_KEEPER_TDENGINE_USESSL"
|
||||
--metrics.prefix string prefix in metrics names. Env "TAOS_KEEPER_METRICS_PREFIX"
|
||||
--metrics.database.name string database for storing metrics data. Env "TAOS_KEEPER_METRICS_DATABASE" (default "log")
|
||||
--metrics.tables stringArray export some tables that are not super table, multiple values split with white space. Env "TAOS_KEEPER_METRICS_TABLES"
|
||||
--environment.incgroup whether running in cgroup. Env "TAOS_KEEPER_ENVIRONMENT_INCGROUP"
|
||||
--log.path string log path. Env "TAOS_KEEPER_LOG_PATH" (default "/var/log/taos")
|
||||
--log.rotationCount uint log rotation count. Env "TAOS_KEEPER_LOG_ROTATION_COUNT" (default 5)
|
||||
--log.rotationTime duration log rotation time. Env "TAOS_KEEPER_LOG_ROTATION_TIME" (default 24h0m0s)
|
||||
--log.rotationSize string log rotation size(KB MB GB), must be a positive integer. Env "TAOS_KEEPER_LOG_ROTATION_SIZE" (default "100000000")
|
||||
-c, --config string config path default /etc/taos/taoskeeper.toml
|
||||
--transfer string run taoskeeper in command mode, only support old_taosd_metric. transfer old metrics data to new tables and exit
|
||||
-V, --version Print the version and exit
|
||||
-h, --help Print this help message and exit
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 配置文件
|
||||
|
||||
taosKeeper 支持用 `taoskeeper -c <keeper config file>` 命令来指定配置文件。
|
||||
|
@ -57,20 +68,18 @@ taosKeeper 支持用 `taoskeeper -c <keeper config file>` 命令来指定配置
|
|||
若既不指定 taosKeeper 配置文件,且 `/etc/taos/taoskeeper.toml` 也不存在,将使用默认配置。
|
||||
|
||||
**下面是配置文件的示例:**
|
||||
```toml
|
||||
# Start with debug middleware for gin
|
||||
debug = false
|
||||
|
||||
# Listen port, default is 6043
|
||||
```toml
|
||||
# The ID of the currently running taoskeeper instance, default is 64.
|
||||
instanceId = 64
|
||||
|
||||
# Listening port, default is 6043.
|
||||
port = 6043
|
||||
|
||||
# log level
|
||||
loglevel = "info"
|
||||
|
||||
# go pool size
|
||||
# Go pool size
|
||||
gopoolsize = 50000
|
||||
|
||||
# interval for metrics
|
||||
# Interval for metrics
|
||||
RotationInterval = "15s"
|
||||
|
||||
[tdengine]
|
||||
|
@ -81,20 +90,21 @@ password = "taosdata"
|
|||
usessl = false
|
||||
|
||||
[metrics]
|
||||
# metrics prefix in metrics names.
|
||||
# Metrics prefix in metrics names.
|
||||
prefix = "taos"
|
||||
|
||||
# export some tables that are not super table
|
||||
# Export some tables that are not super table.
|
||||
tables = []
|
||||
|
||||
# database for storing metrics data
|
||||
# Database for storing metrics data.
|
||||
[metrics.database]
|
||||
name = "log"
|
||||
# database options for db storing metrics data
|
||||
|
||||
# Database options for db storing metrics data.
|
||||
[metrics.database.options]
|
||||
vgroups = 1
|
||||
buffer = 64
|
||||
KEEP = 90
|
||||
keep = 90
|
||||
cachemodel = "both"
|
||||
|
||||
[environment]
|
||||
|
@ -102,9 +112,19 @@ cachemodel = "both"
|
|||
incgroup = false
|
||||
|
||||
[log]
|
||||
rotationCount = 5
|
||||
rotationTime = "24h"
|
||||
rotationSize = 100000000
|
||||
# The directory where log files are stored.
|
||||
# path = "/var/log/taos"
|
||||
level = "info"
|
||||
# Number of log file rotations before deletion.
|
||||
rotationCount = 30
|
||||
# The number of days to retain log files.
|
||||
keepDays = 30
|
||||
# The maximum size of a log file before rotation.
|
||||
rotationSize = "1GB"
|
||||
# If set to true, log files will be compressed.
|
||||
compress = false
|
||||
# Minimum disk space to reserve. Log files will not be written if disk space falls below this limit.
|
||||
reservedDiskSize = "1GB"
|
||||
```
|
||||
|
||||
## 启动
|
||||
|
@ -118,7 +138,6 @@ monitorFqdn localhost # taoskeeper 服务的 FQDN
|
|||
|
||||
TDengine 监控配置相关,具体请参考:[TDengine 监控配置](../../../operation/monitor)。
|
||||
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Linux" value="linux">
|
||||
|
||||
|
@ -188,7 +207,6 @@ Active: inactive (dead)
|
|||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## 健康检查
|
||||
|
||||
可以访问 taosKeeper 的 `check_health` 接口来判断服务是否存活,如果服务正常则会返回 HTTP 200 状态码:
|
||||
|
@ -208,7 +226,6 @@ Content-Length: 21
|
|||
{"version":"3.3.2.3"}
|
||||
```
|
||||
|
||||
|
||||
## 数据收集与监控
|
||||
|
||||
taosKeeper 作为 TDengine 监控指标的导出工具,可以将 TDengine 产生的监控数据记录在指定数据库中(默认的监控数据是 `log`),这些监控数据可以用来配置 TDengine 监控。
|
||||
|
@ -216,6 +233,7 @@ taosKeeper 作为 TDengine 监控指标的导出工具,可以将 TDengine 产
|
|||
### 查看监控数据
|
||||
|
||||
可以查看 `log` 库下的超级表,每个超级表都对应一组监控指标,具体指标不再赘述。
|
||||
|
||||
```shell
|
||||
taos> use log;
|
||||
Database changed.
|
||||
|
@ -251,17 +269,14 @@ taos> select last_row(*) from taosd_dnodes_info;
|
|||
Query OK, 1 row(s) in set (0.003168s)
|
||||
```
|
||||
|
||||
|
||||
### 使用 TDInsight 配置监控
|
||||
|
||||
收集到监控数据以后,就可以使用 TDInsight 来配置 TDengine 的监控,具体请参考 [TDinsight 参考手册](../tdinsight/)
|
||||
|
||||
收集到监控数据以后,就可以使用 TDInsight 来配置 TDengine 的监控,具体请参考 [TDinsight 参考手册](../tdinsight/)。
|
||||
|
||||
## 集成 Prometheus
|
||||
|
||||
taoskeeper 提供了 `/metrics` 接口,返回了 Prometheus 格式的监控数据,Prometheus 可以从 taoskeeper 抽取监控数据,实现通过 Prometheus 监控 TDengine 的目的。
|
||||
|
||||
|
||||
### 导出监控指标
|
||||
|
||||
下面通过 `curl` 命令展示 `/metrics` 接口返回的数据格式:
|
||||
|
@ -298,9 +313,11 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
#### taosd 集群
|
||||
|
||||
##### 监控信息支持的标签
|
||||
|
||||
- `cluster_id`: 集群 id
|
||||
|
||||
##### 相关指标及其含义
|
||||
|
||||
| 指标名称 | 类型 | 含义 |
|
||||
| ----------------------------------- | ------- | ------------------------------------- |
|
||||
| taos_cluster_info_connections_total | counter | 总连接数 |
|
||||
|
@ -328,11 +345,13 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
#### dnode
|
||||
|
||||
##### 监控信息支持的标签
|
||||
|
||||
- `cluster_id`: 集群 id
|
||||
- `dnode_ep`: dnode 端点
|
||||
- `dnode_id`:dnode id
|
||||
|
||||
##### 相关指标及其含义
|
||||
|
||||
| 指标名称 | 类型 | 含义 |
|
||||
| ------------------------------ | ------- | ---------------------------------------------------------------------------------------- |
|
||||
| taos_d_info_status | gauge | dnode 状态,标签 value 表示状态, ready 表示正常, offline 表示下线, unknown 表示未知。 |
|
||||
|
@ -361,6 +380,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
#### 数据目录
|
||||
|
||||
##### 监控信息支持的标签
|
||||
|
||||
- `cluster_id`: 集群 id
|
||||
- `dnode_ep`: dnode 端点
|
||||
- `dnode_id`:dnode id
|
||||
|
@ -368,6 +388,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
- `data_dir_level`:数据目录级别
|
||||
|
||||
##### 相关指标及其含义
|
||||
|
||||
| 指标名称 | 类型 | 含义 |
|
||||
| --------------------------------- | ----- | -------------------- |
|
||||
| taos_taosd_dnodes_data_dirs_avail | gauge | 可用空间(单位 Byte) |
|
||||
|
@ -377,12 +398,14 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
#### 日志目录
|
||||
|
||||
##### 监控信息支持的标签
|
||||
|
||||
- `cluster_id`: 集群 id
|
||||
- `dnode_ep`: dnode 端点
|
||||
- `dnode_id`:dnode id
|
||||
- `log_dir_name`:日志目录名
|
||||
|
||||
##### 相关指标及其含义
|
||||
|
||||
| 指标名称 | 类型 | 含义 |
|
||||
| -------------------------------- | ----- | -------------------- |
|
||||
| taos_taosd_dnodes_log_dirs_avail | gauge | 可用空间(单位 Byte) |
|
||||
|
@ -392,11 +415,13 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
#### 日志数量
|
||||
|
||||
##### 监控信息支持的标签
|
||||
|
||||
- `cluster_id`: 集群 id
|
||||
- `dnode_ep`: dnode 端点
|
||||
- `dnode_id`:dnode id
|
||||
|
||||
##### 相关指标及其含义
|
||||
|
||||
| 指标名称 | 类型 | 含义 |
|
||||
| ---------------------- | ------- | ------------ |
|
||||
| taos_log_summary_debug | counter | 调试日志数量 |
|
||||
|
@ -404,14 +429,15 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
| taos_log_summary_info | counter | 信息日志数量 |
|
||||
| taos_log_summary_trace | counter | 跟踪日志数量 |
|
||||
|
||||
|
||||
#### taosadapter
|
||||
|
||||
##### 监控信息支持的标签
|
||||
|
||||
- `endpoint`:端点
|
||||
- `req_type`:请求类型,0 表示 rest,1 表示 websocket
|
||||
|
||||
##### 相关指标及其含义
|
||||
|
||||
| 指标名称 | 类型 | 含义 |
|
||||
| -------------------------------------- | ------- | -------------------- |
|
||||
| taos_adapter_requests_fail | counter | 失败的请求数 |
|
||||
|
@ -433,9 +459,11 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
#### taoskeeper
|
||||
|
||||
##### 监控信息支持的标签
|
||||
|
||||
- `identify`: 节点 endpoint
|
||||
|
||||
##### 相关指标及其含义
|
||||
|
||||
| 指标名称 | 类型 | 含义 |
|
||||
| ----------------------- | ----- | ------------------------------------- |
|
||||
| taos_keeper_monitor_cpu | gauge | taoskeeper CPU 使用率(取值范围 0~1) |
|
||||
|
@ -444,6 +472,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
#### 其他 taosd 集群监控项
|
||||
|
||||
##### taos_m_info_role
|
||||
|
||||
- **标签**:
|
||||
- `cluster_id`: 集群 id
|
||||
- `mnode_ep`: mnode 端点
|
||||
|
@ -453,6 +482,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
- **含义**: mnode 角色
|
||||
|
||||
##### taos_taos_sql_req_count
|
||||
|
||||
- **标签**:
|
||||
- `cluster_id`: 集群 id
|
||||
- `result`: 请求结果(取值范围: Success, Failed)
|
||||
|
@ -462,6 +492,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
- **含义**: SQL 请求数量
|
||||
|
||||
##### taos_taosd_sql_req_count
|
||||
|
||||
- **标签**:
|
||||
- `cluster_id`: 集群 id
|
||||
- `dnode_ep`: dnode 端点
|
||||
|
@ -474,6 +505,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
- **含义**: SQL 请求数量
|
||||
|
||||
##### taos_taosd_vgroups_info_status
|
||||
|
||||
- **标签**:
|
||||
- `cluster_id`: 集群 id
|
||||
- `database_name`: 数据库名称
|
||||
|
@ -482,6 +514,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
- **含义**: 虚拟组状态。 0 为 unsynced,表示没有leader选出;1 为 ready。
|
||||
|
||||
##### taos_taosd_vgroups_info_tables_num
|
||||
|
||||
- **标签**:
|
||||
- `cluster_id`: 集群 id
|
||||
- `database_name`: 数据库名称
|
||||
|
@ -490,6 +523,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
- **含义**: 虚拟组表数量
|
||||
|
||||
##### taos_taosd_vnodes_info_role
|
||||
|
||||
- **标签**:
|
||||
- `cluster_id`: 集群 id
|
||||
- `database_name`: 数据库名称
|
||||
|
@ -499,7 +533,6 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
|||
- **类型**: gauge
|
||||
- **含义**: 虚拟节点角色
|
||||
|
||||
|
||||
### 抽取配置
|
||||
|
||||
Prometheus 提供了 `scrape_configs` 配置如何从 endpoint 抽取监控数据,通常只需要修改 `static_configs` 中的 targets 配置为 taoskeeper 的 endpoint 地址,更多配置信息请参考 [Prometheus 配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)。
|
||||
|
@ -521,8 +554,6 @@ scrape_configs:
|
|||
|
||||
在 Grafana Dashboard 菜单点击 `import`,dashboard ID 填写 `18587`,点击 `Load` 按钮即可导入 `TaosKeeper Prometheus Dashboard for 3.x` dashboard。
|
||||
|
||||
|
||||
|
||||
## taosKeeper 监控指标
|
||||
|
||||
taosKeeper 也会将自己采集的监控数据写入监控数据库,默认是 `log` 库,可以在 taoskeeper 配置文件中修改。
|
||||
|
|
|
@ -8,7 +8,7 @@ taosExplorer 是一个为用户提供 TDengine 实例的可视化管理交互工
|
|||
|
||||
## 安装
|
||||
|
||||
taosEexplorer 无需单独安装,从 TDengine 3.3.0.0 版本开始,它随着 TDengine 安装包一起发布,安装完成后,就可以看到 `taos-explorer` 服务。如果按照 GitHub 里步骤自己编译 TDengine 源代码生成的安装包不包含 taosExplorer。
|
||||
taosExplorer 无需单独安装,从 TDengine 3.3.0.0 版本开始,它随着 TDengine 安装包一起发布,安装完成后,就可以看到 `taos-explorer` 服务。如果按照 GitHub 里步骤自己编译 TDengine 源代码生成的安装包不包含 taosExplorer。
|
||||
|
||||
## 配置
|
||||
|
||||
|
|
|
@ -364,6 +364,8 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
|
|||
|
||||
- **max** : 数据类型的 列/标签 的最大值。生成的值将小于最小值。
|
||||
|
||||
- **scalingFactor** : 浮点数精度增强因子,仅当数据类型是 float/double 时生效,有效值范围为 1 至 1000000 的正整数。用于增强生成浮点数的精度,特别是在 min 或 max 值较小的情况下。此属性按 10 的幂次增强小数点后的精度:scalingFactor 为 10 表示增强 1 位小数精度,100 表示增强 2 位,依此类推。
|
||||
|
||||
- **fun** : 此列数据以函数填充,目前只支持 sin 和 cos 两函数,输入参数为时间戳换算成角度值,换算公式: 角度 x = 输入的时间列ts值 % 360。同时支持系数调节,随机波动因子调节,以固定格式的表达式展现,如 fun=“10\*sin(x)+100\*random(5)” , x 表示角度,取值 0 ~ 360度,增长步长与时间列步长一致。10 表示乘的系数,100 表示加或减的系数,5 表示波动幅度在 5% 的随机范围内。目前支持的数据类型为 int, bigint, float, double 四种数据类型。注意:表达式为固定模式,不可前后颠倒。
|
||||
|
||||
- **values** : nchar/binary 列/标签的值域,将从值中随机选择。
|
||||
|
|
|
@ -30,6 +30,7 @@ database_option: {
|
|||
| SINGLE_STABLE {0 | 1}
|
||||
| TABLE_PREFIX value
|
||||
| TABLE_SUFFIX value
|
||||
| DNODES value
|
||||
| TSDB_PAGESIZE value
|
||||
| WAL_LEVEL {1 | 2}
|
||||
| WAL_FSYNC_PERIOD value
|
||||
|
@ -63,19 +64,20 @@ database_option: {
|
|||
- 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/tdinternal/arch/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 \<= keep 1 \<= keep 2,如 KEEP 100h,100d,3650d); 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。
|
||||
- STT_TRIGGER:表示落盘文件触发文件合并的个数。默认为 1,范围 1 到 16。对于少表高频场景,此参数建议使用默认配置,或较小的值;而对于多表低频场景,此参数建议配置较大的值。
|
||||
- STT_TRIGGER:表示落盘文件触发文件合并的个数。开源版本固定为 1,企业版本可设置范围为 1 到 16。对于少表高频写入场景,此参数建议使用默认配置;而对于多表低频写入场景,此参数建议配置较大的值。
|
||||
- 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。
|
||||
- TSDB_PAGESIZE:一个 VNODE 中时序数据存储引擎的页大小,单位为 KB,默认为 4 KB。范围为 1 到 16384,即 1 KB到 16 MB。
|
||||
- DNODES:指定 VNODE 所在的 DNODE 列表,如 '1,2,3',以逗号区分且字符间不能有空格,仅企业版支持。
|
||||
- WAL_LEVEL:WAL 级别,默认为 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,表示累计大小无上限。
|
||||
- WAL_RETENTION_PERIOD: 为了数据订阅消费,需要 WAL 日志文件额外保留的最大时长策略。WAL 日志清理,不受订阅客户端消费状态影响。单位为 s。默认为 3600,表示在 WAL 保留最近 3600 秒的数据,请根据数据订阅的需要修改这个参数为适当值。
|
||||
- WAL_RETENTION_SIZE:为了数据订阅消费,需要 WAL 日志文件额外保留的最大累计大小策略。单位为 KB。默认为 0,表示累计大小无上限。
|
||||
### 创建数据库示例
|
||||
|
||||
```sql
|
||||
|
@ -120,6 +122,7 @@ alter_database_option: {
|
|||
| KEEP value
|
||||
| WAL_RETENTION_PERIOD value
|
||||
| WAL_RETENTION_SIZE value
|
||||
| MINROWS value
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -42,12 +42,12 @@ table_option: {
|
|||
**使用说明**
|
||||
|
||||
1. 表(列)名命名规则参见[名称命名规则](./19-limit.md#名称命名规则)。
|
||||
1. 表名最大长度为 192。
|
||||
1. 表的第一个字段必须是 TIMESTAMP,并且系统自动将其设为主键。
|
||||
1. 除时间戳主键列之外,还可以通过 PRIMARY KEY 关键字指定第二列为额外的主键列。被指定为主键列的第二列必须为整型或字符串类型(varchar)。
|
||||
1. 表的每行长度不能超过 48KB(从 3.0.5.0 版本开始为 64KB);(注意:每个 BINARY/NCHAR/GEOMETRY 类型的列还会额外占用 2 个字节的存储位置)。
|
||||
1. 使用数据类型 BINARY/NCHAR/GEOMETRY,需指定其最长的字节数,如 BINARY(20),表示 20 字节。
|
||||
1. 关于 `ENCODE` 和 `COMPRESS` 的使用,请参考[按列压缩](../compress)
|
||||
2. 表名最大长度为 192。
|
||||
3. 表的第一个字段必须是 TIMESTAMP,并且系统自动将其设为主键。
|
||||
4. 除时间戳主键列之外,还可以通过 PRIMARY KEY 关键字指定第二列为额外的主键列。被指定为主键列的第二列必须为整型或字符串类型(VARCHAR)。
|
||||
5. 表的每行长度不能超过 48KB(从 3.0.5.0 版本开始为 64KB);(注意:每个 VARCHAR/NCHAR/GEOMETRY 类型的列还会额外占用 2 个字节的存储位置)。
|
||||
6. 使用数据类型 VARCHAR/NCHAR/GEOMETRY,需指定其最长的字节数,如 VARCHAR(20),表示 20 字节。
|
||||
7. 关于 `ENCODE` 和 `COMPRESS` 的使用,请参考[按列压缩](../compress)
|
||||
|
||||
**参数说明**
|
||||
|
||||
|
@ -87,7 +87,7 @@ CREATE TABLE [IF NOT EXISTS] USING [db_name.]stb_name (field1_name [, field2_nam
|
|||
|
||||
**参数说明**
|
||||
|
||||
1. FILE 语法表示数据来自于 CSV 文件(英文逗号分隔、英文单引号括住每个值),CSV 文件无需表头。CSV 文件中应仅包含 table name 与 tag 值。如需插入数据,请参考数据写入章节。
|
||||
1. FILE 语法表示数据来自于 CSV 文件(英文逗号分隔、英文单引号括住每个值),CSV 文件无需表头。CSV 文件中应仅包含 table name 与 tag 值。如需插入数据,请参考'数据写入'章节。
|
||||
2. 为指定的 stb_name 创建子表,该超级表必须已经存在。
|
||||
3. field_name 列表顺序与 CSV 文件各列内容顺序一致。列表中不允许出现重复项,且必须包含 `tbname`,可包含零个或多个超级表中已定义的标签列。未包含在列表中的标签值将被设置为 NULL。
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ INSERT INTO
|
|||
|
||||
2. VALUES 语法表示了要插入的一行或多行数据。
|
||||
|
||||
3. FILE 语法表示数据来自于 CSV 文件(英文逗号分隔、英文单引号括住每个值),CSV 文件无需表头。
|
||||
3. FILE 语法表示数据来自于 CSV 文件(英文逗号分隔、英文单引号括住每个值),CSV 文件无需表头。如仅需创建子表,请参考'表'章节。
|
||||
|
||||
4. `INSERT ... VALUES` 语句和 `INSERT ... FILE` 语句均可以在一条 INSERT 语句中同时向多个表插入数据。
|
||||
|
||||
|
@ -154,12 +154,20 @@ INSERT INTO d21001 USING meters TAGS ('California.SanFrancisco', 2) FILE '/tmp/c
|
|||
INSERT INTO d21001 USING meters TAGS ('California.SanFrancisco', 2) FILE '/tmp/csvfile_21001.csv'
|
||||
d21002 USING meters (groupId) TAGS (2) FILE '/tmp/csvfile_21002.csv';
|
||||
```
|
||||
## 超级表语法
|
||||
## 向超级表插入数据并自动创建子表
|
||||
|
||||
自动建表, 表名通过tbname列指定
|
||||
自动建表, 表名通过 tbname 列指定
|
||||
```sql
|
||||
INSERT INTO meters(tbname, location, groupId, ts, current, voltage, phase)
|
||||
values('d31001', 'California.SanFrancisco', 2, '2021-07-13 14:06:34.630', 10.2, 219, 0.32)
|
||||
VALUES ('d31001', 'California.SanFrancisco', 2, '2021-07-13 14:06:34.630', 10.2, 219, 0.32)
|
||||
('d31001', 'California.SanFrancisco', 2, '2021-07-13 14:06:35.779', 10.15, 217, 0.33)
|
||||
('d31002', NULL, 2, '2021-07-13 14:06:34.255', 10.15, 217, 0.33)
|
||||
```
|
||||
## 通过 CSV 文件向超级表插入数据并自动创建子表
|
||||
|
||||
根据 csv 文件内容,为 超级表创建子表,并填充相应 column 与 tag
|
||||
|
||||
```sql
|
||||
INSERT INTO meters(tbname, location, groupId, ts, current, voltage, phase)
|
||||
FILE '/tmp/csvfile_21002.csv'
|
||||
```
|
||||
|
|
|
@ -11,7 +11,7 @@ description: 使用标签索引提升查询性能
|
|||
创建索引的语法如下
|
||||
|
||||
```sql
|
||||
CREATE INDEX index_name ON tbl_name (tagColName)
|
||||
CREATE INDEX index_name ON tbl_name (tagColName)
|
||||
```
|
||||
|
||||
其中 `index_name` 为索引名称, `tbl_name` 为超级表名称,`tagColName` 为要在其上建立索引的 tag 列的名称。`tagColName` 的类型不受限制,即任何类型的 tag 列都可以建立索引。
|
||||
|
|
|
@ -1569,7 +1569,7 @@ COUNT({* | expr})
|
|||
ELAPSED(ts_primary_key [, time_unit])
|
||||
```
|
||||
|
||||
**功能说明**:elapsed函数表达了统计周期内连续的时间长度,和twa函数配合使用可以计算统计曲线下的面积。在通过INTERVAL子句指定窗口的情况下,统计在给定时间范围内的每个窗口内有数据覆盖的时间范围;如果没有INTERVAL子句,则返回整个给定时间范围内的有数据覆盖的时间范围。注意,ELAPSED返回的并不是时间范围的绝对值,而是绝对值除以time_unit所得到的单位个数。
|
||||
**功能说明**:elapsed 函数表达了统计周期内连续的时间长度,和 twa 函数配合使用可以计算统计曲线下的面积。在通过 INTERVAL 子句指定窗口的情况下,统计在给定时间范围内的每个窗口内有数据覆盖的时间范围;如果没有 INTERVAL 子句,则返回整个给定时间范围内的有数据覆盖的时间范围。注意,ELAPSED 返回的并不是时间范围的绝对值,而是绝对值除以 time_unit 所得到的单位个数。流计算仅在 FORCE_WINDOW_CLOSE 模式下支持该函数。
|
||||
|
||||
**返回结果类型**:DOUBLE。
|
||||
|
||||
|
@ -1578,15 +1578,15 @@ ELAPSED(ts_primary_key [, time_unit])
|
|||
**适用于**: 表,超级表,嵌套查询的外层查询
|
||||
|
||||
**说明**:
|
||||
- ts_primary_key参数只能是表的第一列,即 TIMESTAMP 类型的主键列。
|
||||
- 按time_unit参数指定的时间单位返回,最小是数据库的时间分辨率。time_unit 参数未指定时,以数据库的时间分辨率为时间单位。支持的时间单位 time_unit 如下:
|
||||
- ts_primary_key 参数只能是表的第一列,即 TIMESTAMP 类型的主键列。
|
||||
- 按 time_unit 参数指定的时间单位返回,最小是数据库的时间分辨率。time_unit 参数未指定时,以数据库的时间分辨率为时间单位。支持的时间单位 time_unit 如下:
|
||||
1b(纳秒), 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天), 1w(周)。
|
||||
- 可以和interval组合使用,返回每个时间窗口的时间戳差值。需要特别注意的是,除第一个时间窗口和最后一个时间窗口外,中间窗口的时间戳差值均为窗口长度。
|
||||
- order by asc/desc不影响差值的计算结果。
|
||||
- 对于超级表,需要和group by tbname子句组合使用,不可以直接使用。
|
||||
- 对于普通表,不支持和group by子句组合使用。
|
||||
- 对于嵌套查询,仅当内层查询会输出隐式时间戳列时有效。例如select elapsed(ts) from (select diff(value) from sub1)语句,diff函数会让内层查询输出隐式时间戳列,此为主键列,可以用于elapsed函数的第一个参数。相反,例如select elapsed(ts) from (select * from sub1) 语句,ts列输出到外层时已经没有了主键列的含义,无法使用elapsed函数。此外,elapsed函数作为一个与时间线强依赖的函数,形如select elapsed(ts) from (select diff(value) from st group by tbname)尽管会返回一条计算结果,但并无实际意义,这种用法后续也将被限制。
|
||||
- 不支持与leastsquares、diff、derivative、top、bottom、last_row、interp等函数混合使用。
|
||||
- 可以和 interval 组合使用,返回每个时间窗口的时间戳差值。需要特别注意的是,除第一个时间窗口和最后一个时间窗口外,中间窗口的时间戳差值均为窗口长度。
|
||||
- order by asc/desc 不影响差值的计算结果。
|
||||
- 对于超级表,需要和 group by tbname 子句组合使用,不可以直接使用。
|
||||
- 对于普通表,不支持和 group by 子句组合使用。
|
||||
- 对于嵌套查询,仅当内层查询会输出隐式时间戳列时有效。例如 select elapsed(ts) from (select diff(value) from sub1) 语句,diff 函数会让内层查询输出隐式时间戳列,此为主键列,可以用于 elapsed 函数的第一个参数。相反,例如 select elapsed(ts) from (select * from sub1) 语句,ts 列输出到外层时已经没有了主键列的含义,无法使用 elapsed 函数。此外,elapsed 函数作为一个与时间线强依赖的函数,形如 select elapsed(ts) from (select diff(value) from st group by tbname)尽 管会返回一条计算结果,但并无实际意义,这种用法后续也将被限制。
|
||||
- 不支持与 leastsquares、diff、derivative、top、bottom、last_row、interp 等函数混合使用。
|
||||
|
||||
|
||||
### LEASTSQUARES
|
||||
|
@ -1829,14 +1829,14 @@ ignore_null_values: {
|
|||
|
||||
- INTERP 用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
|
||||
- INTERP 的输入数据为指定列的数据,可以通过条件语句(where 子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
|
||||
- INTERP 需要同时与 RANGE,EVERY 和 FILL 关键字一起使用。
|
||||
- INTERP 的输出时间范围根据 RANGE(timestamp1, timestamp2)字段来指定,需满足 timestamp1 \<= timestamp2。其中 timestamp1 为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2 为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。
|
||||
- INTERP SQL 查询需要同时与 RANGE,EVERY 和 FILL 关键字一起使用;流计算不能使用 RANGE,需要 EVERY 和 FILL 关键字一起使用。
|
||||
- INTERP 的输出时间范围根据 RANGE(timestamp1, timestamp2) 字段来指定,需满足 timestamp1 \<= timestamp2。其中 timestamp1 为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2 为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。
|
||||
- INTERP 根据 EVERY(time_unit) 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(time_unit 值)进行插值,time_unit 可取值时间单位:1a(毫秒),1s(秒),1m(分),1h(小时),1d(天),1w(周)。例如 EVERY(500a) 将对于指定数据每500毫秒间隔进行一次插值.
|
||||
- INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值。关于 FILL 子句如何使用请参考 [FILL 子句](../distinguished/#fill-子句)
|
||||
- INTERP 可以在 RANGE 字段中只指定唯一的时间戳对单个时间点进行插值,在这种情况下,EVERY 字段可以省略。例如:SELECT INTERP(col) FROM tb RANGE('2023-01-01 00:00:00') FILL(linear).
|
||||
- INTERP 作用于超级表时, 会将该超级表下的所有子表数据按照主键列排序后进行插值计算,也可以搭配 PARTITION BY tbname 使用,将结果强制规约到单个时间线。
|
||||
- INTERP 可以与伪列 _irowts 一起使用,返回插值点所对应的时间戳(3.0.2.0版本以后支持)。
|
||||
- INTERP 可以与伪列 _isfilled 一起使用,显示返回结果是否为原始记录或插值算法产生的数据(3.0.3.0版本以后支持)。
|
||||
- INTERP 可以与伪列 _irowts 一起使用,返回插值点所对应的时间戳(3.0.2.0 版本以后支持)。
|
||||
- INTERP 可以与伪列 _isfilled 一起使用,显示返回结果是否为原始记录或插值算法产生的数据(3.0.3.0 版本以后支持)。
|
||||
- INTERP 对于带复合主键的表的查询,若存在相同时间戳的数据,则只有对应的复合主键最小的数据参与运算。
|
||||
|
||||
### LAST
|
||||
|
@ -2180,7 +2180,7 @@ STATEDURATION(expr, oper, val, unit)
|
|||
TWA(expr)
|
||||
```
|
||||
|
||||
**功能说明**:时间加权平均函数。统计表中某列在一段时间内的时间加权平均。对于存在复合主键的表的查询,若时间戳相同的数据存在多条,则只有对应的复合主键最小的数据参与运算。
|
||||
**功能说明**:时间加权平均函数。统计表中某列在一段时间内的时间加权平均。对于存在复合主键的表的查询,若时间戳相同的数据存在多条,则只有对应的复合主键最小的数据参与运算。流计算仅在 FORCE_WINDOW_CLOSE 模式下支持该函数。
|
||||
|
||||
**返回数据类型**:DOUBLE。
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ window_clause: {
|
|||
FILL 语句指定某一窗口区间数据缺失的情况下的填充模式。填充模式包括以下几种:
|
||||
|
||||
1. 不进行填充:NONE(默认填充模式)。
|
||||
2. VALUE 填充:固定值填充,此时需要指定填充的数值。例如:FILL(VALUE, 1.23)。这里需要注意,最终填充的值受由相应列的类型决定,如 FILL(VALUE, 1.23),相应列为 INT 类型,则填充值为 1, 若查询列表中有多列需要FILL, 则需要给每一个FILL列指定VALUE, 如`SELECT _wstart, min(c1), max(c1) FROM ... FILL(VALUE, 0, 0)`。
|
||||
2. VALUE 填充:固定值填充,此时需要指定填充的数值。例如:FILL(VALUE, 1.23)。这里需要注意,最终填充的值受由相应列的类型决定,如 FILL(VALUE, 1.23),相应列为 INT 类型,则填充值为 1, 若查询列表中有多列需要 FILL, 则需要给每一个 FILL 列指定 VALUE, 如 `SELECT _wstart, min(c1), max(c1) FROM ... FILL(VALUE, 0, 0)`, 注意, SELECT 表达式中只有包含普通列时才需要指定 FILL VALUE, 如 `_wstart`, `_wstart+1a`, `now`, `1+1` 以及使用 partition by 时的 partition key (如 tbname)都不需要指定 VALUE, 如 `timediff(last(ts), _wstart)` 则需要指定VALUE。
|
||||
3. PREV 填充:使用前一个非 NULL 值填充数据。例如:FILL(PREV)。
|
||||
4. NULL 填充:使用 NULL 填充数据。例如:FILL(NULL)。
|
||||
5. LINEAR 填充:根据前后距离最近的非 NULL 值做线性插值填充。例如:FILL(LINEAR)。
|
||||
|
|
|
@ -143,13 +143,14 @@ SELECT * from information_schema.`ins_streams`;
|
|||
|
||||
在创建流时,可以通过 TRIGGER 指令指定流式计算的触发模式。
|
||||
|
||||
对于非窗口计算,流式计算的触发是实时的;对于窗口计算,目前提供 3 种触发模式,默认为 WINDOW_CLOSE:
|
||||
对于非窗口计算,流式计算的触发是实时的;对于窗口计算,目前提供 4 种触发模式,默认为 WINDOW_CLOSE:
|
||||
|
||||
1. AT_ONCE:写入立即触发
|
||||
|
||||
2. WINDOW_CLOSE:窗口关闭时触发(窗口关闭由事件时间决定,可配合 watermark 使用)
|
||||
|
||||
3. MAX_DELAY time:若窗口关闭,则触发计算。若窗口未关闭,且未关闭时长超过 max delay 指定的时间,则触发计算。
|
||||
4. FORCE_WINDOW_CLOSE:以操作系统当前时间为准,只计算当前关闭窗口的结果,并推送出去。窗口只会在被关闭的时刻计算一次,后续不会再重复计算。该模式当前只支持 INTERVAL 窗口(不支持滑动);FILL_HISTORY 必须为 0,IGNORE EXPIRED 必须为 1,IGNORE UPDATE 必须为 1;FILL 只支持 PREV 、NULL、NONE、VALUE。
|
||||
|
||||
由于窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,则事件时间无法更新,可能导致无法得到最新的计算结果。
|
||||
|
||||
|
@ -212,11 +213,11 @@ TDengine 对于修改数据提供两种处理方式,由 IGNORE UPDATE 选项
|
|||
```sql
|
||||
[field1_name,...]
|
||||
```
|
||||
用来指定stb_name的列与subquery输出结果的对应关系。如果stb_name的列与subquery输出结果的位置、数量全部匹配,则不需要显示指定对应关系。如果stb_name的列与subquery输出结果的数据类型不匹配,会把subquery输出结果的类型转换成对应的stb_name的列的类型。
|
||||
在本页文档顶部的 [field1_name,...] 是用来指定 stb_name 的列与 subquery 输出结果的对应关系的。如果 stb_name 的列与 subquery 输出结果的位置、数量全部匹配,则不需要显示指定对应关系。如果 stb_name 的列与 subquery 输出结果的数据类型不匹配,会把 subquery 输出结果的类型转换成对应的 stb_name 的列的类型。
|
||||
|
||||
对于已经存在的超级表,检查列的schema信息
|
||||
1. 检查列的schema信息是否匹配,对于不匹配的,则自动进行类型转换,当前只有数据长度大于4096byte时才报错,其余场景都能进行类型转换。
|
||||
2. 检查列的个数是否相同,如果不同,需要显示的指定超级表与subquery的列的对应关系,否则报错;如果相同,可以指定对应关系,也可以不指定,不指定则按位置顺序对应。
|
||||
1. 检查列的 schema 信息是否匹配,对于不匹配的,则自动进行类型转换,当前只有数据长度大于 4096byte 时才报错,其余场景都能进行类型转换。
|
||||
2. 检查列的个数是否相同,如果不同,需要显示的指定超级表与 subquery 的列的对应关系,否则报错;如果相同,可以指定对应关系,也可以不指定,不指定则按位置顺序对应。
|
||||
|
||||
## 自定义TAG
|
||||
|
||||
|
@ -291,3 +292,4 @@ RESUME STREAM [IF EXISTS] [IGNORE UNTREATED] stream_name;
|
|||
CREATE SNODE ON DNODE [id]
|
||||
```
|
||||
其中的 id 是集群中的 dnode 的序号。请注意选择的dnode,流计算的中间状态将自动在其上进行备份。
|
||||
从 3.3.4.0 版本开始,在多副本环境中创建流会进行 snode 的**存在性检查**,要求首先创建 snode。如果 snode 不存在,无法创建流。
|
||||
|
|
|
@ -33,7 +33,7 @@ description: 对 JSON 类型如何使用的详细说明
|
|||
|
||||
## 支持的操作
|
||||
|
||||
1. 在 where 条件中时,支持函数 match/nmatch/between and/like/and/or/is null/is no null,不支持 in
|
||||
1. 在 where 条件中时,支持函数 match/nmatch/between and/like/and/or/is null/is not null,不支持 in
|
||||
|
||||
```
|
||||
select * from s1 where info->'k1' match 'v*';
|
||||
|
|
|
@ -27,11 +27,15 @@ SHOW DNODES;
|
|||
## 删除数据节点
|
||||
|
||||
```sql
|
||||
DROP DNODE dnode_id
|
||||
DROP DNODE dnode_id [force] [unsafe]
|
||||
```
|
||||
|
||||
注意删除 dnode 不等于停止相应的进程。实际中推荐先将一个 dnode 删除之后再停止其所对应的进程。
|
||||
|
||||
只有在线节点可以被删除。如果要强制删除离线节点,需要执行强制删除操作, 即指定force选项。
|
||||
|
||||
当节点上存在单副本,并且节点处于离线,如果要强制删除该节点,需要执行非安全删除,即制定unsafe,并且数据不可再恢复。
|
||||
|
||||
## 修改数据节点配置
|
||||
|
||||
```sql
|
||||
|
|
|
@ -26,6 +26,7 @@ Node.js 连接器目前仅支持 WebSocket 连接器, 其通过 taosAdapter
|
|||
|
||||
| Node.js 连接器 版本 | 主要变化 | TDengine 版本 |
|
||||
| :------------------: | :----------------------: | :----------------: |
|
||||
| 3.1.1 | 优化了数据传输性能 | 3.3.2.0 及更高版本 |
|
||||
| 3.1.0 | 新版本发布,支持 WebSocket 连接 | 3.2.0.0 及更高版本 |
|
||||
|
||||
## 处理异常
|
||||
|
|
|
@ -3,11 +3,14 @@ sidebar_label: ODBC
|
|||
title: TDengine ODBC
|
||||
---
|
||||
|
||||
TDengine ODBC 是为 TDengine 实现的 ODBC 驱动程序,支持 Windows 系统的应用(如 [PowerBI](https://powerbi.microsoft.com/zh-cn/) 等)通过 ODBC 标准接口访问本地、远程和云服务的 TDengine 数据库的数据表/视图。
|
||||
TDengine ODBC 是为 TDengine 实现的 ODBC 驱动程序,支持 Windows 系统的应用(如 [PowerBI](https://powerbi.microsoft.com/zh-cn/) 等)以及用户自定义开发的应用程序,通过 ODBC 标准接口访问本地、远程和云服务的 TDengine 数据库。
|
||||
|
||||
TDengine ODBC 提供基于 WebSocket(推荐)和 原生连接两种方式连接 TDengine 数据库,使用时可以为 TDengine 数据源设置不同的连接方式。访问云服务时必须使用 WebSocket 连接方式。
|
||||
|
||||
注意:TDengine ODBC 支持 32/64 位 Windows 系统,调用 TDengine ODBC 需要通过相应位数的 ODBC 驱动管理器进行。在 32 位 Windows 系统或者 64 位 Windows 系统的 32 位应用程序中,仅支持使用 WebSocket 连接方式访问 TDengine 数据库。
|
||||
TDengine ODBC 提供 64 位 和 32 位 两种驱动程序。但 32 位仅企业版支持,且仅支持 WebSocket 连接方式。
|
||||
**注意:**
|
||||
- 驱动管理器:确保使用与应用程序架构匹配的 ODBC 驱动管理器。32 位应用程序需要使用 32 位 ODBC 驱动管理器,64 位应用程序需要使用 64 位 ODBC 驱动管理器。
|
||||
- 数据源名称(DSN):32 位和 64 位 ODBC 驱动管理器都可以看到所有 DSN,用户 DSN 标签页下的 DSN 如果名字相同会共用,因此需要在 DSN 名称上去区分。
|
||||
|
||||
想更多了解 TDengine 时序时序数据库的使用,可访问 [TDengine官方文档](https://docs.taosdata.com/intro/)。
|
||||
|
||||
|
@ -24,17 +27,17 @@ TDengine ODBC 提供基于 WebSocket(推荐)和 原生连接两种方式连
|
|||
|
||||
### 数据源连接类型与区别
|
||||
|
||||
TDengine ODBC 支持两种连接 TDengine 数据库方式:Websocket 连接与 Native 连接,其区别如下:
|
||||
TDengine ODBC 支持两种连接 TDengine 数据库方式:WebSocket 连接与 Native 连接,其区别如下:
|
||||
|
||||
1. 访问云服务仅支持使用 Websocket 连接方式。
|
||||
1. 访问云服务仅支持使用 WebSocket 连接方式。
|
||||
|
||||
2. 32 位应用程序仅支持使用 WebSocket 连接方式。
|
||||
|
||||
3. Websocket 连接的兼容性更好,一般不需要随着 TDengine 数据库服务端升级而升级客户端的库。
|
||||
3. WebSocket 连接的兼容性更好,一般不需要随着 TDengine 数据库服务端升级而升级客户端的库。
|
||||
|
||||
4. Native 连接通常性能更好一点,但是必须与 TDengine 数据库服务端的版本保持一致。
|
||||
|
||||
5. 对于一般用户,建议使用 **Websocket** 连接方式,性能与 Native 差别不大,兼容性更好。
|
||||
5. 对于一般用户,建议使用 **WebSocket** 连接方式,性能与 Native 差别不大,兼容性更好。
|
||||
|
||||
### WebSocket 连接
|
||||
|
||||
|
@ -46,11 +49,11 @@ TDengine ODBC 支持两种连接 TDengine 数据库方式:Websocket 连接与
|
|||
|
||||
4. 点击完成,进入 TDengine ODBC 数据源配置页面,填写如下必要信息
|
||||
|
||||

|
||||

|
||||
|
||||
4.1 【DSN】:Data Source Name 必填,为新添加的 ODBC 数据源命名
|
||||
|
||||
4.2【连接类型】 : 必选,选择连接类型,这里选择 【Websocket】
|
||||
4.2【连接类型】 : 必选,选择连接类型,这里选择 【WebSocket】
|
||||
|
||||
4.3【URL】必填,ODBC 数据源 URL,示例: `http://localhost:6041`, 云服务的 url 示例: `https://gw.cloud.taosdata.com?token=your_token`
|
||||
|
||||
|
@ -111,7 +114,7 @@ WebSocket 连接方式除此之外还支持 Windows X64系统上运行的 32 位
|
|||
|
||||
| taos_odbc 版本 | 主要变化 | TDengine 版本 |
|
||||
| :----------- | :-------------------------------------------------------------------------------------------------- | :---------------- |
|
||||
| v1.1.0 | 1. 支持视图功能;<br/>2. 支持 VARBINARY/GEOMETRY 数据类型; | 3.3.3.0及更高版本 |
|
||||
| v1.1.0 | 1. 支持视图功能;<br/>2. 支持 VARBINARY/GEOMETRY 数据类型;<br/>3. 支持 ODBC 32 位 WebSocket 连接方式(仅企业版支持);<br/>4. 支持 ODBC 数据源配置对话框设置对工业软件 KingSCADA、Kepware 等的兼容性适配选项(仅企业版支持); | 3.3.3.0及更高版本 |
|
||||
| v1.0.2 | 支持 CP1252 字符编码; | 3.2.3.0及更高版本 |
|
||||
| v1.0.1 | 1. 支持 DSN 设置 BI 模式,在 BI 模式下 TDengine 数据库不返回系统数据库和超级表子表信息;<br/>2. 重构字符集转换模块,提升读写性能;<br/>3. ODBC 数据源配置对话框中默认修改默认连接方式为“WebSocket”;<br/>4. ODBC 数据源配置对话框增加“测试连接”控件;<br/>5. ODBC 数据源配置支持中文/英文界面; | - |
|
||||
| v1.0.0.0 | 发布初始版本,支持与Tdengine数据库交互以读写数据,具体请参考“API 参考”一节 | 3.2.2.0及更高版本 |
|
||||
|
|
|
@ -34,8 +34,8 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器
|
|||
| **3.0.0.0 及以上** | 3.0.2以上 | 当前版本 | 3.0 分支 | 3.0.0 | 3.1.0 | 当前版本 | 与 TDengine 相同版本 |
|
||||
| **2.4.0.14 及以上** | 2.0.38 | 当前版本 | develop 分支 | 1.0.2 - 1.0.6 | 2.0.10 - 2.0.12 | 当前版本 | 与 TDengine 相同版本 |
|
||||
| **2.4.0.4 - 2.4.0.13** | 2.0.37 | 当前版本 | develop 分支 | 1.0.2 - 1.0.6 | 2.0.10 - 2.0.12 | 当前版本 | 与 TDengine 相同版本 |
|
||||
| **2.2.x.x ** | 2.0.36 | 当前版本 | master 分支 | n/a | 2.0.7 - 2.0.9 | 当前版本 | 与 TDengine 相同版本 |
|
||||
| **2.0.x.x ** | 2.0.34 | 当前版本 | master 分支 | n/a | 2.0.1 - 2.0.6 | 当前版本 | 与 TDengine 相同版本 |
|
||||
| **2.2.x.x** | 2.0.36 | 当前版本 | master 分支 | n/a | 2.0.7 - 2.0.9 | 当前版本 | 与 TDengine 相同版本 |
|
||||
| **2.0.x.x** | 2.0.34 | 当前版本 | master 分支 | n/a | 2.0.1 - 2.0.6 | 当前版本 | 与 TDengine 相同版本 |
|
||||
|
||||
## 功能特性
|
||||
|
||||
|
|
|
@ -6,15 +6,28 @@ description: "TDengine 服务端、客户端和连接器支持的平台列表"
|
|||
|
||||
## TDengine 服务端支持的平台列表
|
||||
|
||||
| | **Windows server 2016/2019** | **Windows 10/11** | **CentOS 7.9/8** | **Ubuntu 18 以上** | **统信 UOS** | **银河/中标麒麟** | **凝思 V60/V80** | **macOS** |
|
||||
| ------------ | ---------------------------- | ----------------- | ---------------- | ------------------ | ------------ | ----------------- | ---------------- | --------- |
|
||||
| X64 | ●/E | ●/E | ● | ● | ●/E | ●/E | ●/E | ● |
|
||||
| 树莓派 ARM64 | | | ● | | | | | |
|
||||
| 华为云 ARM64 | | | | ● | | | | |
|
||||
| M1 | | | | | | | | ● |
|
||||
| | **版本** | **X64 64bit** | **ARM64** |
|
||||
| ----------------------|----------------| ------------- | --------- |
|
||||
| **CentOS** | **7.9 以上** | ● | ● |
|
||||
| **Ubuntu** | **18 以上** | ● | ● |
|
||||
| **RedHat** | **RHEL 7 以上** | ● | ● |
|
||||
| **Debian** | **6.0 以上** | ● | ● |
|
||||
| **FreeBSD** | **12 以上** | ● | ● |
|
||||
| **OpenSUSE** | **全部版本** | ● | ● |
|
||||
| **SUSE Linux** | **11 以上** | ● | ● |
|
||||
| **Fedora** | **21 以上** | ● | ● |
|
||||
| **Windows Server** | **2016 以上** | ●/E | |
|
||||
| **Windows** | **10/11** | ●/E | |
|
||||
| **银河麒麟** | **V10 以上** | ●/E | ●/E |
|
||||
| **中标麒麟** | **V7.0 以上** | ●/E | ●/E |
|
||||
| **统信 UOS** | **V20 以上** | ●/E | |
|
||||
| **凝思磐石** | **V8.0 以上** | ●/E | |
|
||||
| **华为欧拉 openEuler** | **V20.03 以上** | ●/E | |
|
||||
| **龙蜥 Anolis OS** | **V8.6 以上** | ●/E | |
|
||||
| **macOS** | **11.0 以上** | | ● |
|
||||
|
||||
注:1) ● 表示经过官方测试验证, ○ 表示非官方测试验证,E 表示仅企业版支持。
|
||||
2) 社区版仅支持主流操作系统的较新版本,包括 Ubuntu 18+/CentOS 7+/RedHat/Debian/CoreOS/FreeBSD/OpenSUSE/SUSE Linux/Fedora/macOS 等。如果有其他操作系统及版本的需求,请联系企业版支持。
|
||||
2) 社区版仅支持主流操作系统的较新版本,包括 Ubuntu 18+/CentOS 7+/CentOS Stream/RedHat/Debian/CoreOS/FreeBSD/OpenSUSE/SUSE Linux/Fedora/macOS 等。如果有其他操作系统及版本的需求,请联系企业版支持。
|
||||
|
||||
## TDengine 客户端和连接器支持的平台列表
|
||||
|
||||
|
@ -22,16 +35,16 @@ description: "TDengine 服务端、客户端和连接器支持的平台列表"
|
|||
|
||||
对照矩阵如下:
|
||||
|
||||
| **CPU** | **X64 64bit** | **X64 64bit** | **ARM64** | **X64 64bit** | **ARM64** |
|
||||
| ----------- | ------------- | ------------- | --------- | ------------- | --------- |
|
||||
| **OS** | **Linux** | **Win64** | **Linux** | **macOS** | **macOS** |
|
||||
| **CPU** | **X64 64bit** | **X64 64bit** | **X64 64bit** | **ARM64** | **ARM64** |
|
||||
| ----------- | ------------- | ------------- | ------------- | --------- | --------- |
|
||||
| **OS** | **Linux** | **Win64** | **macOS** | **Linux** | **macOS** |
|
||||
| **C/C++** | ● | ● | ● | ● | ● |
|
||||
| **JDBC** | ● | ● | ● | ○ | ○ |
|
||||
| **JDBC** | ● | ● | ● | ● | ● |
|
||||
| **Python** | ● | ● | ● | ● | ● |
|
||||
| **Go** | ● | ● | ● | ● | ● |
|
||||
| **NodeJs** | ● | ● | ● | ○ | ○ |
|
||||
| **C#** | ● | ● | ○ | ○ | ○ |
|
||||
| **Rust** | ● | ● | ○ | ● | ● |
|
||||
| **NodeJs** | ● | ● | ● | ● | ● |
|
||||
| **C#** | ● | ● | ○ | ● | ○ |
|
||||
| **Rust** | ● | ● | ● | ○ | ● |
|
||||
| **RESTful** | ● | ● | ● | ● | ● |
|
||||
|
||||
注:● 表示官方测试验证通过,○ 表示非官方测试验证通过,-- 表示未经验证。
|
||||
|
|
|
@ -178,7 +178,7 @@ TDengine 集群可以容纳单个、多个甚至几千个数据节点。应用
|
|||
|
||||
TDengine 存储的数据包括采集的时序数据以及库、表相关的元数据、标签数据等,这些数据具体分为三部分:
|
||||
|
||||
- 时序数据:TDengine 的核心存储对象,存放于 vnode 里,由 data、head 和 last 三个文件组成,数据量大,查询量取决于应用场景。允许乱序写入,但暂时不支持删除操作,并且仅在 update 参数设置为 1 时允许更新操作。通过采用一个采集点一张表的模型,一个时间段的数据是连续存储,对单张表的写入是简单的追加操作,一次读,可以读到多条记录,这样保证对单个采集点的插入和查询操作,性能达到最优。
|
||||
- 时序数据:时序数据是 TDengine 的核心存储对象,它们被存储在 vnode 中。时序数据由 data、head、sma 和 stt 4 类文件组成,这些文件共同构成了时序数据的完整存储结构。由于时序数据的特点是数据量大且查询需求取决于具体应用场景,因此 TDengine 采用了“一个数据采集点一张表”的模型来优化存储和查询性能。在这种模型下,一个时间段内的数据是连续存储的,对单张表的写入是简单的追加操作,一次读取可以获取多条记录。这种设计确保了单个数据采集点的写入和查询操作都能达到最优性能。
|
||||
- 数据表元数据:包含标签信息和 Table Schema 信息,存放于 vnode 里的 meta 文件,支持增删改查四个标准操作。数据量很大,有 N 张表,就有 N 条记录,因此采用 LRU 存储,支持标签数据的索引。TDengine 支持多核多线程并发查询。只要计算内存足够,元数据全内存存储,千万级别规模的标签数据过滤结果能毫秒级返回。在内存资源不足的情况下,仍然可以支持数千万张表的快速查询。
|
||||
- 数据库元数据:存放于 mnode 里,包含系统节点、用户、DB、STable Schema 等信息,支持增删改查四个标准操作。这部分数据的量不大,可以全内存保存,而且由于客户端有缓存,查询量也不大。因此目前的设计虽是集中式存储管理,但不会构成性能瓶颈。
|
||||
|
||||
|
|
|
@ -81,6 +81,13 @@ typedef enum {
|
|||
TSDB_SML_TIMESTAMP_NANO_SECONDS,
|
||||
} TSDB_SML_TIMESTAMP_TYPE;
|
||||
|
||||
typedef enum TAOS_FIELD_T {
|
||||
TAOS_FIELD_COL = 1,
|
||||
TAOS_FIELD_TAG,
|
||||
TAOS_FIELD_QUERY,
|
||||
TAOS_FIELD_TBNAME,
|
||||
} TAOS_FIELD_T;
|
||||
|
||||
typedef struct taosField {
|
||||
char name[65];
|
||||
int8_t type;
|
||||
|
@ -95,6 +102,15 @@ typedef struct TAOS_FIELD_E {
|
|||
int32_t bytes;
|
||||
} TAOS_FIELD_E;
|
||||
|
||||
typedef struct TAOS_FIELD_STB {
|
||||
char name[65];
|
||||
int8_t type;
|
||||
uint8_t precision;
|
||||
uint8_t scale;
|
||||
int32_t bytes;
|
||||
TAOS_FIELD_T field_type;
|
||||
} TAOS_FIELD_STB;
|
||||
|
||||
#ifdef WINDOWS
|
||||
#define DLL_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
|
@ -195,13 +211,6 @@ DLL_EXPORT int taos_stmt_affected_rows_once(TAOS_STMT *stmt);
|
|||
|
||||
typedef void TAOS_STMT2;
|
||||
|
||||
typedef enum TAOS_FIELD_T {
|
||||
TAOS_FIELD_COL = 1,
|
||||
TAOS_FIELD_TAG,
|
||||
TAOS_FIELD_QUERY,
|
||||
TAOS_FIELD_TBNAME,
|
||||
} TAOS_FIELD_T;
|
||||
|
||||
typedef struct TAOS_STMT2_OPTION {
|
||||
int64_t reqid;
|
||||
bool singleStbInsert;
|
||||
|
@ -232,7 +241,9 @@ DLL_EXPORT int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows);
|
|||
DLL_EXPORT int taos_stmt2_close(TAOS_STMT2 *stmt);
|
||||
DLL_EXPORT int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert);
|
||||
DLL_EXPORT int taos_stmt2_get_fields(TAOS_STMT2 *stmt, TAOS_FIELD_T field_type, int *count, TAOS_FIELD_E **fields);
|
||||
DLL_EXPORT int taos_stmt2_get_stb_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_STB **fields);
|
||||
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_E *fields);
|
||||
DLL_EXPORT void taos_stmt2_free_stb_fields(TAOS_STMT2 *stmt, TAOS_FIELD_STB *fields);
|
||||
DLL_EXPORT TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt);
|
||||
DLL_EXPORT char *taos_stmt2_error(TAOS_STMT2 *stmt);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct {
|
|||
int32_t anode;
|
||||
int32_t urlLen;
|
||||
char *url;
|
||||
} SAnalUrl;
|
||||
} SAnalyticsUrl;
|
||||
|
||||
typedef enum {
|
||||
ANAL_BUF_TYPE_JSON = 0,
|
||||
|
@ -53,18 +53,18 @@ typedef struct {
|
|||
TdFilePtr filePtr;
|
||||
char fileName[TSDB_FILENAME_LEN + 10];
|
||||
int64_t numOfRows;
|
||||
} SAnalColBuf;
|
||||
} SAnalyticsColBuf;
|
||||
|
||||
typedef struct {
|
||||
EAnalBufType bufType;
|
||||
TdFilePtr filePtr;
|
||||
char fileName[TSDB_FILENAME_LEN];
|
||||
int32_t numOfCols;
|
||||
SAnalColBuf *pCols;
|
||||
SAnalyticsColBuf *pCols;
|
||||
} SAnalBuf;
|
||||
|
||||
int32_t taosAnalInit();
|
||||
void taosAnalCleanup();
|
||||
int32_t taosAnalyticsInit();
|
||||
void taosAnalyticsCleanup();
|
||||
SJson *taosAnalSendReqRetJson(const char *url, EAnalHttpType type, SAnalBuf *pBuf);
|
||||
|
||||
int32_t taosAnalGetAlgoUrl(const char *algoName, EAnalAlgoType type, char *url, int32_t urlLen);
|
|
@ -154,6 +154,7 @@ typedef enum EStreamType {
|
|||
STREAM_TRANS_STATE,
|
||||
STREAM_MID_RETRIEVE,
|
||||
STREAM_PARTITION_DELETE_DATA,
|
||||
STREAM_GET_RESULT,
|
||||
} EStreamType;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
@ -383,6 +384,10 @@ typedef struct STUidTagInfo {
|
|||
#define TABLE_NAME_COLUMN_INDEX 6
|
||||
#define PRIMARY_KEY_COLUMN_INDEX 7
|
||||
|
||||
//steam get result block column
|
||||
#define DATA_TS_COLUMN_INDEX 0
|
||||
#define DATA_VERSION_COLUMN_INDEX 1
|
||||
|
||||
// stream create table block column
|
||||
#define UD_TABLE_NAME_COLUMN_INDEX 0
|
||||
#define UD_GROUPID_COLUMN_INDEX 1
|
||||
|
|
|
@ -189,7 +189,12 @@ static FORCE_INLINE void colDataSetDouble(SColumnInfoData* pColumnInfoData, uint
|
|||
|
||||
int32_t getJsonValueLen(const char* data);
|
||||
|
||||
// For the VAR_DATA_TYPE type, new data is inserted strictly according to the position of SVarColAttr.length.
|
||||
// If the same row is inserted repeatedly, data holes will result.
|
||||
int32_t colDataSetVal(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull);
|
||||
// For the VAR_DATA_TYPE type, if a row already has data before inserting it (judged by offset != -1),
|
||||
// it will be inserted at the original position and the old data will be overwritten.
|
||||
int32_t colDataSetValOrCover(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull);
|
||||
int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, uint32_t srcRowIdx, const char* pData);
|
||||
int32_t colDataSetNItems(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, uint32_t numOfRows,
|
||||
bool trimValue);
|
||||
|
@ -233,7 +238,7 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo);
|
|||
* @brief find how many rows already in order start from first row
|
||||
*/
|
||||
int32_t blockDataGetSortedRows(SSDataBlock* pDataBlock, SArray* pOrderInfo);
|
||||
void blockDataCheck(const SSDataBlock* pDataBlock, bool forceChk);
|
||||
int32_t blockDataCheck(const SSDataBlock* pDataBlock);
|
||||
|
||||
int32_t colInfoDataEnsureCapacity(SColumnInfoData* pColumn, uint32_t numOfRows, bool clearPayload);
|
||||
int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows);
|
||||
|
@ -266,7 +271,7 @@ SColumnInfoData createColumnInfoData(int16_t type, int32_t bytes, int16_t colId)
|
|||
int32_t bdGetColumnInfoData(const SSDataBlock* pBlock, int32_t index, SColumnInfoData** pColInfoData);
|
||||
|
||||
int32_t blockGetEncodeSize(const SSDataBlock* pBlock);
|
||||
int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols);
|
||||
int32_t blockEncode(const SSDataBlock* pBlock, char* data, size_t dataLen, int32_t numOfCols);
|
||||
int32_t blockDecode(SSDataBlock* pBlock, const char* pData, const char** pEndPos);
|
||||
|
||||
// for debug
|
||||
|
|
|
@ -151,6 +151,7 @@ extern bool tsMonitorForceV2;
|
|||
// audit
|
||||
extern bool tsEnableAudit;
|
||||
extern bool tsEnableAuditCreateTable;
|
||||
extern bool tsEnableAuditDelete;
|
||||
extern int32_t tsAuditInterval;
|
||||
|
||||
// telem
|
||||
|
@ -162,6 +163,12 @@ extern bool tsEnableCrashReport;
|
|||
extern char *tsTelemUri;
|
||||
extern char *tsClientCrashReportUri;
|
||||
extern char *tsSvrCrashReportUri;
|
||||
extern int8_t tsSafetyCheckLevel;
|
||||
enum {
|
||||
TSDB_SAFETY_CHECK_LEVELL_NEVER = 0,
|
||||
TSDB_SAFETY_CHECK_LEVELL_NORMAL = 1,
|
||||
TSDB_SAFETY_CHECK_LEVELL_BYROW = 2,
|
||||
};
|
||||
|
||||
// query buffer management
|
||||
extern int32_t tsQueryBufferSize; // maximum allowed usage buffer size in MB for each data node during query processing
|
||||
|
@ -203,10 +210,10 @@ extern int32_t tsMinIntervalTime;
|
|||
extern int32_t tsMaxInsertBatchRows;
|
||||
|
||||
// build info
|
||||
extern char version[];
|
||||
extern char compatible_version[];
|
||||
extern char gitinfo[];
|
||||
extern char buildinfo[];
|
||||
extern char td_version[];
|
||||
extern char td_compatible_version[];
|
||||
extern char td_gitinfo[];
|
||||
extern char td_buildinfo[];
|
||||
|
||||
// lossy
|
||||
extern char tsLossyColumns[];
|
||||
|
|
|
@ -421,7 +421,7 @@ typedef enum ENodeType {
|
|||
// physical plan node
|
||||
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN = 1100,
|
||||
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN,
|
||||
QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN,
|
||||
QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN, // INACTIVE
|
||||
QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN,
|
||||
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN,
|
||||
|
@ -435,7 +435,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_PHYSICAL_PLAN_SORT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL, // INACTIVE
|
||||
QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL,
|
||||
|
@ -467,9 +467,11 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_MID_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_ANOMALY,
|
||||
QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC,
|
||||
} ENodeType;
|
||||
|
||||
typedef struct {
|
||||
|
@ -1022,6 +1024,7 @@ typedef struct {
|
|||
char sDetailVer[128];
|
||||
int64_t whiteListVer;
|
||||
SMonitorParas monitorParas;
|
||||
int8_t enableAuditDelete;
|
||||
} SConnectRsp;
|
||||
|
||||
int32_t tSerializeSConnectRsp(void* buf, int32_t bufLen, SConnectRsp* pRsp);
|
||||
|
@ -1215,6 +1218,7 @@ typedef struct {
|
|||
int32_t bytes;
|
||||
int8_t type;
|
||||
uint8_t pk;
|
||||
bool noData;
|
||||
} SColumnInfo;
|
||||
|
||||
typedef struct STimeWindow {
|
||||
|
@ -1337,6 +1341,7 @@ typedef struct {
|
|||
char* sql;
|
||||
int8_t withArbitrator;
|
||||
int8_t encryptAlgorithm;
|
||||
char dnodeListStr[TSDB_DNODE_LIST_LEN];
|
||||
} SCreateDbReq;
|
||||
|
||||
int32_t tSerializeSCreateDbReq(void* buf, int32_t bufLen, SCreateDbReq* pReq);
|
||||
|
@ -1825,6 +1830,17 @@ int32_t tSerializeSStatisReq(void* buf, int32_t bufLen, SStatisReq* pReq);
|
|||
int32_t tDeserializeSStatisReq(void* buf, int32_t bufLen, SStatisReq* pReq);
|
||||
void tFreeSStatisReq(SStatisReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
char table[TSDB_TABLE_NAME_LEN];
|
||||
char operation[AUDIT_OPERATION_LEN];
|
||||
int32_t sqlLen;
|
||||
char* pSql;
|
||||
} SAuditReq;
|
||||
int32_t tSerializeSAuditReq(void* buf, int32_t bufLen, SAuditReq* pReq);
|
||||
int32_t tDeserializeSAuditReq(void* buf, int32_t bufLen, SAuditReq* pReq);
|
||||
void tFreeSAuditReq(SAuditReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
int32_t dnodeId;
|
||||
int64_t clusterId;
|
||||
|
@ -2816,6 +2832,8 @@ typedef struct {
|
|||
#define STREAM_TRIGGER_AT_ONCE 1
|
||||
#define STREAM_TRIGGER_WINDOW_CLOSE 2
|
||||
#define STREAM_TRIGGER_MAX_DELAY 3
|
||||
#define STREAM_TRIGGER_FORCE_WINDOW_CLOSE 4
|
||||
|
||||
#define STREAM_DEFAULT_IGNORE_EXPIRED 1
|
||||
#define STREAM_FILL_HISTORY_ON 1
|
||||
#define STREAM_FILL_HISTORY_OFF 0
|
||||
|
@ -3413,6 +3431,7 @@ typedef struct {
|
|||
int32_t svrTimestamp;
|
||||
SArray* rsps; // SArray<SClientHbRsp>
|
||||
SMonitorParas monitorParas;
|
||||
int8_t enableAuditDelete;
|
||||
} SClientHbBatchRsp;
|
||||
|
||||
static FORCE_INLINE uint32_t hbKeyHashFunc(const char* key, uint32_t keyLen) { return taosIntHash_64(key, keyLen); }
|
||||
|
@ -4104,7 +4123,6 @@ void tDeleteMqMetaRsp(SMqMetaRsp* pRsp);
|
|||
#define MQ_DATA_RSP_VERSION 100
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
SMqRspHead head;
|
||||
STqOffsetVal rspOffset;
|
||||
STqOffsetVal reqOffset;
|
||||
|
@ -4115,7 +4133,6 @@ typedef struct {
|
|||
SArray* blockData;
|
||||
SArray* blockTbName;
|
||||
SArray* blockSchema;
|
||||
};
|
||||
|
||||
union{
|
||||
struct{
|
||||
|
|
|
@ -259,6 +259,7 @@
|
|||
TD_DEF_MSG_TYPE(TDMT_MND_STREAM_DROP_ORPHANTASKS, "stream-drop-orphan-tasks", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_STREAM_TASK_RESET, "stream-reset-tasks", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_UPDATE_DNODE_INFO, "update-dnode-info", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_AUDIT, "audit", NULL, NULL)
|
||||
TD_CLOSE_MSG_SEG(TDMT_END_MND_MSG)
|
||||
|
||||
TD_NEW_MSG_SEG(TDMT_VND_MSG) // 2<<8
|
||||
|
|
|
@ -16,394 +16,7 @@
|
|||
#ifndef _TD_COMMON_TOKEN_H_
|
||||
#define _TD_COMMON_TOKEN_H_
|
||||
|
||||
#define TK_OR 1
|
||||
#define TK_AND 2
|
||||
#define TK_UNION 3
|
||||
#define TK_ALL 4
|
||||
#define TK_MINUS 5
|
||||
#define TK_EXCEPT 6
|
||||
#define TK_INTERSECT 7
|
||||
#define TK_NK_BITAND 8
|
||||
#define TK_NK_BITOR 9
|
||||
#define TK_NK_LSHIFT 10
|
||||
#define TK_NK_RSHIFT 11
|
||||
#define TK_NK_PLUS 12
|
||||
#define TK_NK_MINUS 13
|
||||
#define TK_NK_STAR 14
|
||||
#define TK_NK_SLASH 15
|
||||
#define TK_NK_REM 16
|
||||
#define TK_NK_CONCAT 17
|
||||
#define TK_CREATE 18
|
||||
#define TK_ACCOUNT 19
|
||||
#define TK_NK_ID 20
|
||||
#define TK_PASS 21
|
||||
#define TK_NK_STRING 22
|
||||
#define TK_ALTER 23
|
||||
#define TK_PPS 24
|
||||
#define TK_TSERIES 25
|
||||
#define TK_STORAGE 26
|
||||
#define TK_STREAMS 27
|
||||
#define TK_QTIME 28
|
||||
#define TK_DBS 29
|
||||
#define TK_USERS 30
|
||||
#define TK_CONNS 31
|
||||
#define TK_STATE 32
|
||||
#define TK_NK_COMMA 33
|
||||
#define TK_HOST 34
|
||||
#define TK_IS_IMPORT 35
|
||||
#define TK_NK_INTEGER 36
|
||||
#define TK_CREATEDB 37
|
||||
#define TK_USER 38
|
||||
#define TK_ENABLE 39
|
||||
#define TK_SYSINFO 40
|
||||
#define TK_ADD 41
|
||||
#define TK_DROP 42
|
||||
#define TK_GRANT 43
|
||||
#define TK_ON 44
|
||||
#define TK_TO 45
|
||||
#define TK_REVOKE 46
|
||||
#define TK_FROM 47
|
||||
#define TK_SUBSCRIBE 48
|
||||
#define TK_READ 49
|
||||
#define TK_WRITE 50
|
||||
#define TK_NK_DOT 51
|
||||
#define TK_WITH 52
|
||||
#define TK_ENCRYPT_KEY 53
|
||||
#define TK_ANODE 54
|
||||
#define TK_UPDATE 55
|
||||
#define TK_ANODES 56
|
||||
#define TK_DNODE 57
|
||||
#define TK_PORT 58
|
||||
#define TK_DNODES 59
|
||||
#define TK_RESTORE 60
|
||||
#define TK_NK_IPTOKEN 61
|
||||
#define TK_FORCE 62
|
||||
#define TK_UNSAFE 63
|
||||
#define TK_CLUSTER 64
|
||||
#define TK_LOCAL 65
|
||||
#define TK_QNODE 66
|
||||
#define TK_BNODE 67
|
||||
#define TK_SNODE 68
|
||||
#define TK_MNODE 69
|
||||
#define TK_VNODE 70
|
||||
#define TK_DATABASE 71
|
||||
#define TK_USE 72
|
||||
#define TK_FLUSH 73
|
||||
#define TK_TRIM 74
|
||||
#define TK_S3MIGRATE 75
|
||||
#define TK_COMPACT 76
|
||||
#define TK_IF 77
|
||||
#define TK_NOT 78
|
||||
#define TK_EXISTS 79
|
||||
#define TK_BUFFER 80
|
||||
#define TK_CACHEMODEL 81
|
||||
#define TK_CACHESIZE 82
|
||||
#define TK_COMP 83
|
||||
#define TK_DURATION 84
|
||||
#define TK_NK_VARIABLE 85
|
||||
#define TK_MAXROWS 86
|
||||
#define TK_MINROWS 87
|
||||
#define TK_KEEP 88
|
||||
#define TK_PAGES 89
|
||||
#define TK_PAGESIZE 90
|
||||
#define TK_TSDB_PAGESIZE 91
|
||||
#define TK_PRECISION 92
|
||||
#define TK_REPLICA 93
|
||||
#define TK_VGROUPS 94
|
||||
#define TK_SINGLE_STABLE 95
|
||||
#define TK_RETENTIONS 96
|
||||
#define TK_SCHEMALESS 97
|
||||
#define TK_WAL_LEVEL 98
|
||||
#define TK_WAL_FSYNC_PERIOD 99
|
||||
#define TK_WAL_RETENTION_PERIOD 100
|
||||
#define TK_WAL_RETENTION_SIZE 101
|
||||
#define TK_WAL_ROLL_PERIOD 102
|
||||
#define TK_WAL_SEGMENT_SIZE 103
|
||||
#define TK_STT_TRIGGER 104
|
||||
#define TK_TABLE_PREFIX 105
|
||||
#define TK_TABLE_SUFFIX 106
|
||||
#define TK_S3_CHUNKSIZE 107
|
||||
#define TK_S3_KEEPLOCAL 108
|
||||
#define TK_S3_COMPACT 109
|
||||
#define TK_KEEP_TIME_OFFSET 110
|
||||
#define TK_ENCRYPT_ALGORITHM 111
|
||||
#define TK_NK_COLON 112
|
||||
#define TK_BWLIMIT 113
|
||||
#define TK_START 114
|
||||
#define TK_TIMESTAMP 115
|
||||
#define TK_END 116
|
||||
#define TK_TABLE 117
|
||||
#define TK_NK_LP 118
|
||||
#define TK_NK_RP 119
|
||||
#define TK_USING 120
|
||||
#define TK_FILE 121
|
||||
#define TK_STABLE 122
|
||||
#define TK_COLUMN 123
|
||||
#define TK_MODIFY 124
|
||||
#define TK_RENAME 125
|
||||
#define TK_TAG 126
|
||||
#define TK_SET 127
|
||||
#define TK_NK_EQ 128
|
||||
#define TK_TAGS 129
|
||||
#define TK_BOOL 130
|
||||
#define TK_TINYINT 131
|
||||
#define TK_SMALLINT 132
|
||||
#define TK_INT 133
|
||||
#define TK_INTEGER 134
|
||||
#define TK_BIGINT 135
|
||||
#define TK_FLOAT 136
|
||||
#define TK_DOUBLE 137
|
||||
#define TK_BINARY 138
|
||||
#define TK_NCHAR 139
|
||||
#define TK_UNSIGNED 140
|
||||
#define TK_JSON 141
|
||||
#define TK_VARCHAR 142
|
||||
#define TK_MEDIUMBLOB 143
|
||||
#define TK_BLOB 144
|
||||
#define TK_VARBINARY 145
|
||||
#define TK_GEOMETRY 146
|
||||
#define TK_DECIMAL 147
|
||||
#define TK_COMMENT 148
|
||||
#define TK_MAX_DELAY 149
|
||||
#define TK_WATERMARK 150
|
||||
#define TK_ROLLUP 151
|
||||
#define TK_TTL 152
|
||||
#define TK_SMA 153
|
||||
#define TK_DELETE_MARK 154
|
||||
#define TK_FIRST 155
|
||||
#define TK_LAST 156
|
||||
#define TK_SHOW 157
|
||||
#define TK_FULL 158
|
||||
#define TK_PRIVILEGES 159
|
||||
#define TK_DATABASES 160
|
||||
#define TK_TABLES 161
|
||||
#define TK_STABLES 162
|
||||
#define TK_MNODES 163
|
||||
#define TK_QNODES 164
|
||||
#define TK_ARBGROUPS 165
|
||||
#define TK_FUNCTIONS 166
|
||||
#define TK_INDEXES 167
|
||||
#define TK_ACCOUNTS 168
|
||||
#define TK_APPS 169
|
||||
#define TK_CONNECTIONS 170
|
||||
#define TK_LICENCES 171
|
||||
#define TK_GRANTS 172
|
||||
#define TK_LOGS 173
|
||||
#define TK_MACHINES 174
|
||||
#define TK_ENCRYPTIONS 175
|
||||
#define TK_QUERIES 176
|
||||
#define TK_SCORES 177
|
||||
#define TK_TOPICS 178
|
||||
#define TK_VARIABLES 179
|
||||
#define TK_BNODES 180
|
||||
#define TK_SNODES 181
|
||||
#define TK_TRANSACTIONS 182
|
||||
#define TK_DISTRIBUTED 183
|
||||
#define TK_CONSUMERS 184
|
||||
#define TK_SUBSCRIPTIONS 185
|
||||
#define TK_VNODES 186
|
||||
#define TK_ALIVE 187
|
||||
#define TK_VIEWS 188
|
||||
#define TK_VIEW 189
|
||||
#define TK_COMPACTS 190
|
||||
#define TK_NORMAL 191
|
||||
#define TK_CHILD 192
|
||||
#define TK_LIKE 193
|
||||
#define TK_TBNAME 194
|
||||
#define TK_QTAGS 195
|
||||
#define TK_AS 196
|
||||
#define TK_SYSTEM 197
|
||||
#define TK_TSMA 198
|
||||
#define TK_INTERVAL 199
|
||||
#define TK_RECURSIVE 200
|
||||
#define TK_TSMAS 201
|
||||
#define TK_FUNCTION 202
|
||||
#define TK_INDEX 203
|
||||
#define TK_COUNT 204
|
||||
#define TK_LAST_ROW 205
|
||||
#define TK_META 206
|
||||
#define TK_ONLY 207
|
||||
#define TK_TOPIC 208
|
||||
#define TK_CONSUMER 209
|
||||
#define TK_GROUP 210
|
||||
#define TK_DESC 211
|
||||
#define TK_DESCRIBE 212
|
||||
#define TK_RESET 213
|
||||
#define TK_QUERY 214
|
||||
#define TK_CACHE 215
|
||||
#define TK_EXPLAIN 216
|
||||
#define TK_ANALYZE 217
|
||||
#define TK_VERBOSE 218
|
||||
#define TK_NK_BOOL 219
|
||||
#define TK_RATIO 220
|
||||
#define TK_NK_FLOAT 221
|
||||
#define TK_OUTPUTTYPE 222
|
||||
#define TK_AGGREGATE 223
|
||||
#define TK_BUFSIZE 224
|
||||
#define TK_LANGUAGE 225
|
||||
#define TK_REPLACE 226
|
||||
#define TK_STREAM 227
|
||||
#define TK_INTO 228
|
||||
#define TK_PAUSE 229
|
||||
#define TK_RESUME 230
|
||||
#define TK_PRIMARY 231
|
||||
#define TK_KEY 232
|
||||
#define TK_TRIGGER 233
|
||||
#define TK_AT_ONCE 234
|
||||
#define TK_WINDOW_CLOSE 235
|
||||
#define TK_IGNORE 236
|
||||
#define TK_EXPIRED 237
|
||||
#define TK_FILL_HISTORY 238
|
||||
#define TK_SUBTABLE 239
|
||||
#define TK_UNTREATED 240
|
||||
#define TK_KILL 241
|
||||
#define TK_CONNECTION 242
|
||||
#define TK_TRANSACTION 243
|
||||
#define TK_BALANCE 244
|
||||
#define TK_VGROUP 245
|
||||
#define TK_LEADER 246
|
||||
#define TK_MERGE 247
|
||||
#define TK_REDISTRIBUTE 248
|
||||
#define TK_SPLIT 249
|
||||
#define TK_DELETE 250
|
||||
#define TK_INSERT 251
|
||||
#define TK_NK_BIN 252
|
||||
#define TK_NK_HEX 253
|
||||
#define TK_NULL 254
|
||||
#define TK_NK_QUESTION 255
|
||||
#define TK_NK_ALIAS 256
|
||||
#define TK_NK_ARROW 257
|
||||
#define TK_ROWTS 258
|
||||
#define TK_QSTART 259
|
||||
#define TK_QEND 260
|
||||
#define TK_QDURATION 261
|
||||
#define TK_WSTART 262
|
||||
#define TK_WEND 263
|
||||
#define TK_WDURATION 264
|
||||
#define TK_IROWTS 265
|
||||
#define TK_ISFILLED 266
|
||||
#define TK_FLOW 267
|
||||
#define TK_FHIGH 268
|
||||
#define TK_FROWTS 269
|
||||
#define TK_CAST 270
|
||||
#define TK_POSITION 271
|
||||
#define TK_IN 272
|
||||
#define TK_FOR 273
|
||||
#define TK_NOW 274
|
||||
#define TK_TODAY 275
|
||||
#define TK_RAND 276
|
||||
#define TK_SUBSTR 277
|
||||
#define TK_SUBSTRING 278
|
||||
#define TK_BOTH 279
|
||||
#define TK_TRAILING 280
|
||||
#define TK_LEADING 281
|
||||
#define TK_TIMEZONE 282
|
||||
#define TK_CLIENT_VERSION 283
|
||||
#define TK_SERVER_VERSION 284
|
||||
#define TK_SERVER_STATUS 285
|
||||
#define TK_CURRENT_USER 286
|
||||
#define TK_PI 287
|
||||
#define TK_CASE 288
|
||||
#define TK_WHEN 289
|
||||
#define TK_THEN 290
|
||||
#define TK_ELSE 291
|
||||
#define TK_BETWEEN 292
|
||||
#define TK_IS 293
|
||||
#define TK_NK_LT 294
|
||||
#define TK_NK_GT 295
|
||||
#define TK_NK_LE 296
|
||||
#define TK_NK_GE 297
|
||||
#define TK_NK_NE 298
|
||||
#define TK_MATCH 299
|
||||
#define TK_NMATCH 300
|
||||
#define TK_CONTAINS 301
|
||||
#define TK_JOIN 302
|
||||
#define TK_INNER 303
|
||||
#define TK_LEFT 304
|
||||
#define TK_RIGHT 305
|
||||
#define TK_OUTER 306
|
||||
#define TK_SEMI 307
|
||||
#define TK_ANTI 308
|
||||
#define TK_ASOF 309
|
||||
#define TK_WINDOW 310
|
||||
#define TK_WINDOW_OFFSET 311
|
||||
#define TK_JLIMIT 312
|
||||
#define TK_SELECT 313
|
||||
#define TK_NK_HINT 314
|
||||
#define TK_DISTINCT 315
|
||||
#define TK_WHERE 316
|
||||
#define TK_PARTITION 317
|
||||
#define TK_BY 318
|
||||
#define TK_SESSION 319
|
||||
#define TK_STATE_WINDOW 320
|
||||
#define TK_EVENT_WINDOW 321
|
||||
#define TK_COUNT_WINDOW 322
|
||||
#define TK_ANOMALY_WINDOW 323
|
||||
#define TK_SLIDING 324
|
||||
#define TK_FILL 325
|
||||
#define TK_VALUE 326
|
||||
#define TK_VALUE_F 327
|
||||
#define TK_NONE 328
|
||||
#define TK_PREV 329
|
||||
#define TK_NULL_F 330
|
||||
#define TK_LINEAR 331
|
||||
#define TK_NEXT 332
|
||||
#define TK_HAVING 333
|
||||
#define TK_RANGE 334
|
||||
#define TK_EVERY 335
|
||||
#define TK_ORDER 336
|
||||
#define TK_SLIMIT 337
|
||||
#define TK_SOFFSET 338
|
||||
#define TK_LIMIT 339
|
||||
#define TK_OFFSET 340
|
||||
#define TK_ASC 341
|
||||
#define TK_NULLS 342
|
||||
#define TK_ABORT 343
|
||||
#define TK_AFTER 344
|
||||
#define TK_ATTACH 345
|
||||
#define TK_BEFORE 346
|
||||
#define TK_BEGIN 347
|
||||
#define TK_BITAND 348
|
||||
#define TK_BITNOT 349
|
||||
#define TK_BITOR 350
|
||||
#define TK_BLOCKS 351
|
||||
#define TK_CHANGE 352
|
||||
#define TK_COMMA 353
|
||||
#define TK_CONCAT 354
|
||||
#define TK_CONFLICT 355
|
||||
#define TK_COPY 356
|
||||
#define TK_DEFERRED 357
|
||||
#define TK_DELIMITERS 358
|
||||
#define TK_DETACH 359
|
||||
#define TK_DIVIDE 360
|
||||
#define TK_DOT 361
|
||||
#define TK_EACH 362
|
||||
#define TK_FAIL 363
|
||||
#define TK_GLOB 364
|
||||
#define TK_ID 365
|
||||
#define TK_IMMEDIATE 366
|
||||
#define TK_IMPORT 367
|
||||
#define TK_INITIALLY 368
|
||||
#define TK_INSTEAD 369
|
||||
#define TK_ISNULL 370
|
||||
#define TK_MODULES 371
|
||||
#define TK_NK_BITNOT 372
|
||||
#define TK_NK_SEMI 373
|
||||
#define TK_NOTNULL 374
|
||||
#define TK_OF 375
|
||||
#define TK_PLUS 376
|
||||
#define TK_PRIVILEGE 377
|
||||
#define TK_RAISE 378
|
||||
#define TK_RESTRICT 379
|
||||
#define TK_ROW 380
|
||||
#define TK_STAR 381
|
||||
#define TK_STATEMENT 382
|
||||
#define TK_STRICT 383
|
||||
#define TK_STRING 384
|
||||
#define TK_TIMES 385
|
||||
#define TK_VALUES 386
|
||||
#define TK_VARIABLE 387
|
||||
#define TK_WAL 388
|
||||
#include "ttokenauto.h"
|
||||
|
||||
#define TK_NK_SPACE 600
|
||||
#define TK_NK_COMMENT 601
|
||||
|
|
|
@ -238,12 +238,26 @@ typedef struct {
|
|||
case TSDB_DATA_TYPE_UBIGINT: \
|
||||
snprintf(_output, (int32_t)(_outputBytes), "%" PRIu64, *(uint64_t *)(_input)); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_FLOAT: \
|
||||
case TSDB_DATA_TYPE_FLOAT: { \
|
||||
int32_t n = snprintf(_output, (int32_t)(_outputBytes), "%f", *(float *)(_input)); \
|
||||
if (n >= (_outputBytes)) { \
|
||||
n = snprintf(_output, (int32_t)(_outputBytes), "%.7e", *(float *)(_input)); \
|
||||
if (n >= (_outputBytes)) { \
|
||||
snprintf(_output, (int32_t)(_outputBytes), "%f", *(float *)(_input)); \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_DOUBLE: \
|
||||
} \
|
||||
case TSDB_DATA_TYPE_DOUBLE: { \
|
||||
int32_t n = snprintf(_output, (int32_t)(_outputBytes), "%f", *(double *)(_input)); \
|
||||
if (n >= (_outputBytes)) { \
|
||||
snprintf(_output, (int32_t)(_outputBytes), "%.15e", *(double *)(_input)); \
|
||||
if (n >= (_outputBytes)) { \
|
||||
snprintf(_output, (int32_t)(_outputBytes), "%f", *(double *)(_input)); \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
case TSDB_DATA_TYPE_UINT: \
|
||||
snprintf(_output, (int32_t)(_outputBytes), "%u", *(uint32_t *)(_input)); \
|
||||
break; \
|
||||
|
@ -284,6 +298,7 @@ typedef struct {
|
|||
#define IS_VALID_UINT64(_t) ((_t) >= 0 && (_t) <= UINT64_MAX)
|
||||
#define IS_VALID_FLOAT(_t) ((_t) >= -FLT_MAX && (_t) <= FLT_MAX)
|
||||
#define IS_VALID_DOUBLE(_t) ((_t) >= -DBL_MAX && (_t) <= DBL_MAX)
|
||||
#define IS_INVALID_TYPE(_t) ((_t) < TSDB_DATA_TYPE_NULL || (_t) >= TSDB_DATA_TYPE_MAX)
|
||||
|
||||
#define IS_CONVERT_AS_SIGNED(_t) \
|
||||
(IS_SIGNED_NUMERIC_TYPE(_t) || (_t) == (TSDB_DATA_TYPE_BOOL) || (_t) == (TSDB_DATA_TYPE_TIMESTAMP))
|
||||
|
|
|
@ -29,7 +29,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define AUDIT_DETAIL_MAX 65472
|
||||
#define AUDIT_OPERATION_LEN 20
|
||||
|
||||
typedef struct {
|
||||
const char *server;
|
||||
|
|
|
@ -151,8 +151,9 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
|
|||
* @param tversion
|
||||
* @return
|
||||
*/
|
||||
int32_t qGetQueryTableSchemaVersion(qTaskInfo_t tinfo, char* dbName, char* tableName, int32_t* sversion,
|
||||
int32_t* tversion, int32_t idx, bool* tbGet);
|
||||
int32_t qGetQueryTableSchemaVersion(qTaskInfo_t tinfo, char* dbName, int32_t dbNameBuffLen, char* tableName,
|
||||
int32_t tbaleNameBuffLen, int32_t* sversion, int32_t* tversion, int32_t idx,
|
||||
bool* tbGet);
|
||||
|
||||
/**
|
||||
* The main task execution function, including query on both table and multiple tables,
|
||||
|
@ -222,8 +223,8 @@ int32_t qStreamSourceScanParamForHistoryScanStep2(qTaskInfo_t tinfo, SVersionRan
|
|||
int32_t qStreamRecoverFinish(qTaskInfo_t tinfo);
|
||||
bool qStreamScanhistoryFinished(qTaskInfo_t tinfo);
|
||||
int32_t qStreamInfoResetTimewindowFilter(qTaskInfo_t tinfo);
|
||||
void resetTaskInfo(qTaskInfo_t tinfo);
|
||||
|
||||
void qResetTaskInfoCode(qTaskInfo_t tinfo);
|
||||
int32_t qGetStreamIntervalExecInfo(qTaskInfo_t tinfo, int64_t* pWaterMark, SInterval* pInterval, STimeWindow* pLastWindow);
|
||||
int32_t qStreamOperatorReleaseState(qTaskInfo_t tInfo);
|
||||
int32_t qStreamOperatorReloadState(qTaskInfo_t tInfo);
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ extern "C" {
|
|||
|
||||
#define STREAM_STATE_BUFF_HASH 1
|
||||
#define STREAM_STATE_BUFF_SORT 2
|
||||
#define STREAM_STATE_BUFF_HASH_SORT 3
|
||||
#define STREAM_STATE_BUFF_HASH_SEARCH 4
|
||||
|
||||
typedef struct SMeta SMeta;
|
||||
typedef TSKEY (*GetTsFun)(void*);
|
||||
|
@ -325,6 +327,9 @@ typedef struct {
|
|||
int64_t number;
|
||||
void* pStreamFileState;
|
||||
int32_t buffIndex;
|
||||
int32_t hashIter;
|
||||
void* pHashData;
|
||||
int64_t minGpId;
|
||||
} SStreamStateCur;
|
||||
|
||||
typedef struct SStateStore {
|
||||
|
@ -337,6 +342,8 @@ typedef struct SStateStore {
|
|||
void (*streamStateReleaseBuf)(SStreamState* pState, void* pVal, bool used);
|
||||
void (*streamStateClearBuff)(SStreamState* pState, void* pVal);
|
||||
void (*streamStateFreeVal)(void* val);
|
||||
int32_t (*streamStateGetPrev)(SStreamState* pState, const SWinKey* pKey, SWinKey* pResKey, void** pVal,
|
||||
int32_t* pVLen, int32_t* pWinCode);
|
||||
|
||||
int32_t (*streamStatePut)(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen);
|
||||
int32_t (*streamStateGet)(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen, int32_t* pWinCode);
|
||||
|
@ -349,8 +356,15 @@ typedef struct SStateStore {
|
|||
int32_t (*streamStateGetInfo)(SStreamState* pState, void* pKey, int32_t keyLen, void** pVal, int32_t* pLen);
|
||||
|
||||
int32_t (*streamStateFillPut)(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen);
|
||||
int32_t (*streamStateFillGet)(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
||||
int32_t (*streamStateFillGet)(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
int32_t (*streamStateFillAddIfNotExist)(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
void (*streamStateFillDel)(SStreamState* pState, const SWinKey* key);
|
||||
int32_t (*streamStateFillGetNext)(SStreamState* pState, const SWinKey* pKey, SWinKey* pResKey, void** pVal,
|
||||
int32_t* pVLen, int32_t* pWinCode);
|
||||
int32_t (*streamStateFillGetPrev)(SStreamState* pState, const SWinKey* pKey, SWinKey* pResKey, void** pVal,
|
||||
int32_t* pVLen, int32_t* pWinCode);
|
||||
|
||||
void (*streamStateCurNext)(SStreamState* pState, SStreamStateCur* pCur);
|
||||
void (*streamStateCurPrev)(SStreamState* pState, SStreamStateCur* pCur);
|
||||
|
@ -361,9 +375,12 @@ typedef struct SStateStore {
|
|||
SStreamStateCur* (*streamStateFillSeekKeyPrev)(SStreamState* pState, const SWinKey* key);
|
||||
void (*streamStateFreeCur)(SStreamStateCur* pCur);
|
||||
|
||||
int32_t (*streamStateGetGroupKVByCur)(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
||||
int32_t (*streamStateFillGetGroupKVByCur)(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
||||
int32_t (*streamStateGetKVByCur)(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
||||
|
||||
void (*streamStateSetFillInfo)(SStreamState* pState);
|
||||
void (*streamStateClearExpiredState)(SStreamState* pState);
|
||||
|
||||
int32_t (*streamStateSessionAddIfNotExist)(SStreamState* pState, SSessionKey* key, TSKEY gap, void** pVal,
|
||||
int32_t* pVLen, int32_t* pWinCode);
|
||||
int32_t (*streamStateSessionPut)(SStreamState* pState, const SSessionKey* key, void* value, int32_t vLen);
|
||||
|
@ -400,8 +417,8 @@ typedef struct SStateStore {
|
|||
SUpdateInfo** ppInfo);
|
||||
void (*updateInfoAddCloseWindowSBF)(SUpdateInfo* pInfo);
|
||||
void (*updateInfoDestoryColseWinSBF)(SUpdateInfo* pInfo);
|
||||
int32_t (*updateInfoSerialize)(void* buf, int32_t bufLen, const SUpdateInfo* pInfo, int32_t* pLen);
|
||||
int32_t (*updateInfoDeserialize)(void* buf, int32_t bufLen, SUpdateInfo* pInfo);
|
||||
int32_t (*updateInfoSerialize)(SEncoder* pEncoder, const SUpdateInfo* pInfo);
|
||||
int32_t (*updateInfoDeserialize)(SDecoder* pDeCoder, SUpdateInfo* pInfo);
|
||||
|
||||
SStreamStateCur* (*streamStateSessionSeekKeyNext)(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* (*streamStateCountSeekKeyPrev)(SStreamState* pState, const SSessionKey* pKey, COUNT_TYPE count);
|
||||
|
@ -412,6 +429,11 @@ typedef struct SStateStore {
|
|||
GetTsFun fp, void* pFile, TSKEY delMark, const char* id, int64_t ckId, int8_t type,
|
||||
struct SStreamFileState** ppFileState);
|
||||
|
||||
int32_t (*streamStateGroupPut)(SStreamState* pState, int64_t groupId, void* value, int32_t vLen);
|
||||
SStreamStateCur* (*streamStateGroupGetCur)(SStreamState* pState);
|
||||
void (*streamStateGroupCurNext)(SStreamStateCur* pCur);
|
||||
int32_t (*streamStateGroupGetKVByCur)(SStreamStateCur* pCur, int64_t* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
void (*streamFileStateDestroy)(struct SStreamFileState* pFileState);
|
||||
void (*streamFileStateClear)(struct SStreamFileState* pFileState);
|
||||
bool (*needClearDiskBuff)(struct SStreamFileState* pFileState);
|
||||
|
|
|
@ -26,6 +26,8 @@ extern "C" {
|
|||
#define FUNC_AGGREGATE_UDF_ID 5001
|
||||
#define FUNC_SCALAR_UDF_ID 5002
|
||||
|
||||
extern const int32_t funcMgtBuiltinsNum;
|
||||
|
||||
typedef enum EFunctionType {
|
||||
// aggregate function
|
||||
FUNCTION_TYPE_APERCENTILE = 1,
|
||||
|
@ -290,6 +292,7 @@ bool fmIsElapsedFunc(int32_t funcId);
|
|||
|
||||
void getLastCacheDataType(SDataType* pType, int32_t pkBytes);
|
||||
int32_t createFunction(const char* pName, SNodeList* pParameterList, SFunctionNode** pFunc);
|
||||
int32_t createFunctionWithSrcFunc(const char* pName, const SFunctionNode* pSrcFunc, SNodeList* pParameterList, SFunctionNode** pFunc);
|
||||
|
||||
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMidFunc, SFunctionNode** pMergeFunc);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ extern "C" {
|
|||
#include "thash.h"
|
||||
#include "query.h"
|
||||
#include "tqueue.h"
|
||||
#include "clientInt.h"
|
||||
|
||||
typedef enum {
|
||||
SQL_RESULT_SUCCESS = 0,
|
||||
|
@ -81,6 +82,8 @@ void monitorCreateClientCounter(int64_t clusterId, const char* name,
|
|||
void monitorCounterInc(int64_t clusterId, const char* counterName, const char** label_values);
|
||||
const char* monitorResultStr(SQL_RESULT_CODE code);
|
||||
int32_t monitorPutData2MonitorQueue(MonitorSlowLogData data);
|
||||
|
||||
void clientOperateReport(SRequestObj* pRequest);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -72,6 +72,7 @@ typedef struct SDatabaseOptions {
|
|||
int8_t compressionLevel;
|
||||
int8_t encryptAlgorithm;
|
||||
int32_t daysPerFile;
|
||||
char dnodeListStr[TSDB_DNODE_LIST_LEN];
|
||||
char encryptAlgorithmStr[TSDB_ENCRYPT_ALGO_STR_LEN];
|
||||
SValueNode* pDaysPerFile;
|
||||
int32_t fsyncPeriod;
|
||||
|
|
|
@ -194,14 +194,26 @@ typedef struct SIndefRowsFuncLogicNode {
|
|||
bool isTimeLineFunc;
|
||||
} SIndefRowsFuncLogicNode;
|
||||
|
||||
typedef struct SStreamNodeOption {
|
||||
int8_t triggerType;
|
||||
int64_t watermark;
|
||||
int64_t deleteMark;
|
||||
int8_t igExpired;
|
||||
int8_t igCheckUpdate;
|
||||
int8_t destHasPrimaryKey;
|
||||
} SStreamNodeOption;
|
||||
|
||||
typedef struct SInterpFuncLogicNode {
|
||||
SLogicNode node;
|
||||
SNodeList* pFuncs;
|
||||
STimeWindow timeRange;
|
||||
int64_t interval;
|
||||
int8_t intervalUnit;
|
||||
int8_t precision;
|
||||
EFillMode fillMode;
|
||||
SNode* pFillValues; // SNodeListNode
|
||||
SNode* pTimeSeries; // SColumnNode
|
||||
SStreamNodeOption streamNodeOption;
|
||||
} SInterpFuncLogicNode;
|
||||
|
||||
typedef struct SForecastFuncLogicNode {
|
||||
|
@ -333,6 +345,7 @@ typedef struct SFillLogicNode {
|
|||
SNode* pWStartTs;
|
||||
SNode* pValues; // SNodeListNode
|
||||
STimeWindow timeRange;
|
||||
SNodeList* pFillNullExprs;
|
||||
} SFillLogicNode;
|
||||
|
||||
typedef struct SSortLogicNode {
|
||||
|
@ -510,11 +523,15 @@ typedef struct SInterpFuncPhysiNode {
|
|||
STimeWindow timeRange;
|
||||
int64_t interval;
|
||||
int8_t intervalUnit;
|
||||
int8_t precision;
|
||||
EFillMode fillMode;
|
||||
SNode* pFillValues; // SNodeListNode
|
||||
SNode* pTimeSeries; // SColumnNode
|
||||
SStreamNodeOption streamNodeOption;
|
||||
} SInterpFuncPhysiNode;
|
||||
|
||||
typedef SInterpFuncPhysiNode SStreamInterpFuncPhysiNode;
|
||||
|
||||
typedef struct SForecastFuncPhysiNode {
|
||||
SPhysiNode node;
|
||||
SNodeList* pExprs;
|
||||
|
@ -649,7 +666,7 @@ typedef struct SWindowPhysiNode {
|
|||
int64_t watermark;
|
||||
int64_t deleteMark;
|
||||
int8_t igExpired;
|
||||
int8_t destHasPrimayKey;
|
||||
int8_t destHasPrimaryKey;
|
||||
bool mergeDataBlock;
|
||||
} SWindowPhysiNode;
|
||||
|
||||
|
@ -677,6 +694,7 @@ typedef struct SFillPhysiNode {
|
|||
SNode* pWStartTs; // SColumnNode
|
||||
SNode* pValues; // SNodeListNode
|
||||
STimeWindow timeRange;
|
||||
SNodeList* pFillNullExprs;
|
||||
} SFillPhysiNode;
|
||||
|
||||
typedef SFillPhysiNode SStreamFillPhysiNode;
|
||||
|
@ -786,9 +804,9 @@ typedef struct SDataDeleterNode {
|
|||
char tableFName[TSDB_TABLE_NAME_LEN];
|
||||
char tsColName[TSDB_COL_NAME_LEN];
|
||||
STimeWindow deleteTimeRange;
|
||||
SNode* pAffectedRows;
|
||||
SNode* pStartTs;
|
||||
SNode* pEndTs;
|
||||
SNode* pAffectedRows; // usless
|
||||
SNode* pStartTs; // usless
|
||||
SNode* pEndTs; // usless
|
||||
} SDataDeleterNode;
|
||||
|
||||
typedef struct SSubplan {
|
||||
|
|
|
@ -457,6 +457,7 @@ typedef struct SSelectStmt {
|
|||
bool hasCountFunc;
|
||||
bool hasUdaf;
|
||||
bool hasStateKey;
|
||||
bool hasTwaOrElapsedFunc;
|
||||
bool onlyHasKeepOrderFunc;
|
||||
bool groupSort;
|
||||
bool tagScan;
|
||||
|
|
|
@ -65,7 +65,7 @@ typedef struct SParseCsvCxt {
|
|||
const char* pLastSqlPos; // the location of the last parsed sql
|
||||
} SParseCsvCxt;
|
||||
|
||||
typedef void(*setQueryFn)(int64_t);
|
||||
typedef void (*setQueryFn)(int64_t);
|
||||
|
||||
typedef struct SParseContext {
|
||||
uint64_t requestId;
|
||||
|
@ -147,6 +147,7 @@ int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, c
|
|||
int32_t qBindStmtSingleColValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen,
|
||||
int32_t colIdx, int32_t rowNum);
|
||||
int32_t qBuildStmtColFields(void* pDataBlock, int32_t* fieldNum, TAOS_FIELD_E** fields);
|
||||
int32_t qBuildStmtStbColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD_STB** fields);
|
||||
int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD_E** fields);
|
||||
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName,
|
||||
TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen);
|
||||
|
@ -176,8 +177,8 @@ int32_t smlBindData(SQuery* handle, bool dataFormat, SArray* tags, SArray* colsS
|
|||
STableMeta* pTableMeta, char* tableName, const char* sTableName, int32_t sTableNameLen, int32_t ttl,
|
||||
char* msgBuf, int32_t msgBufLen);
|
||||
int32_t smlBuildOutput(SQuery* handle, SHashObj* pVgHash);
|
||||
int rawBlockBindData(SQuery* query, STableMeta* pTableMeta, void* data, SVCreateTbReq** pCreateTb, TAOS_FIELD* fields,
|
||||
int numFields, bool needChangeLength, char* errstr, int32_t errstrLen);
|
||||
int rawBlockBindData(SQuery* query, STableMeta* pTableMeta, void* data, SVCreateTbReq* pCreateTb, void* fields,
|
||||
int numFields, bool needChangeLength, char* errstr, int32_t errstrLen, bool raw);
|
||||
|
||||
int32_t rewriteToVnodeModifyOpStmt(SQuery* pQuery, SArray* pBufArray);
|
||||
int32_t serializeVgroupsCreateTableBatch(SHashObj* pVgroupHashmap, SArray** pOut);
|
||||
|
|
|
@ -364,7 +364,7 @@ void* getTaskPoolWorkerCb();
|
|||
#define NEED_CLIENT_REFRESH_VG_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_VND_HASH_MISMATCH || (_code) == TSDB_CODE_VND_INVALID_VGROUP_ID)
|
||||
#define NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER || (_code) == TSDB_CODE_MND_INVALID_SCHEMA_VER)
|
||||
((_code) == TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER || (_code) == TSDB_CODE_MND_INVALID_SCHEMA_VER || (_code) == TSDB_CODE_SCH_DATA_SRC_EP_MISS)
|
||||
#define NEED_CLIENT_HANDLE_ERROR(_code) \
|
||||
(NEED_CLIENT_RM_TBLMETA_ERROR(_code) || NEED_CLIENT_REFRESH_VG_ERROR(_code) || \
|
||||
NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code))
|
||||
|
|
|
@ -105,6 +105,7 @@ int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara
|
|||
int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t todayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t timeZoneStrLen();
|
||||
int32_t timezoneFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t weekdayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t dayofweekFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
|
|
|
@ -76,8 +76,6 @@ int32_t schedulerExecJob(SSchedulerReq* pReq, int64_t* pJob);
|
|||
|
||||
int32_t schedulerFetchRows(int64_t jobId, SSchedulerReq* pReq);
|
||||
|
||||
void schedulerFetchRowsA(int64_t job, schedulerFetchFp fp, void* param);
|
||||
|
||||
int32_t schedulerGetTasksStatus(int64_t job, SArray* pSub);
|
||||
|
||||
void schedulerStopQueryHb(void* pTrans);
|
||||
|
@ -100,6 +98,8 @@ void schedulerFreeJob(int64_t* job, int32_t errCode);
|
|||
|
||||
void schedulerDestroy(void);
|
||||
|
||||
int32_t schedulerValidatePlan(SQueryPlan* pPlan);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -49,6 +49,8 @@ void streamStateClear(SStreamState* pState);
|
|||
void streamStateSetNumber(SStreamState* pState, int32_t number, int32_t tsIdex);
|
||||
void streamStateSaveInfo(SStreamState* pState, void* pKey, int32_t keyLen, void* pVal, int32_t vLen);
|
||||
int32_t streamStateGetInfo(SStreamState* pState, void* pKey, int32_t keyLen, void** pVal, int32_t* pLen);
|
||||
int32_t streamStateGetPrev(SStreamState* pState, const SWinKey* pKey, SWinKey* pResKey, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
|
||||
// session window
|
||||
int32_t streamStateSessionAddIfNotExist(SStreamState* pState, SSessionKey* key, TSKEY gap, void** pVal, int32_t* pVLen,
|
||||
|
@ -75,8 +77,14 @@ int32_t streamStateStateAddIfNotExist(SStreamState* pState, SSessionKey* key, ch
|
|||
|
||||
// fill
|
||||
int32_t streamStateFillPut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen);
|
||||
int32_t streamStateFillGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateFillGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen, int32_t* pWinCode);
|
||||
int32_t streamStateFillAddIfNotExist(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
void streamStateFillDel(SStreamState* pState, const SWinKey* key);
|
||||
int32_t streamStateFillGetNext(SStreamState* pState, const SWinKey* pKey, SWinKey* pResKey, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
int32_t streamStateFillGetPrev(SStreamState* pState, const SWinKey* pKey, SWinKey* pResKey, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
|
||||
int32_t streamStateAddIfNotExist(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
|
@ -96,15 +104,25 @@ SStreamStateCur* streamStateFillSeekKeyPrev(SStreamState* pState, const SWinKey*
|
|||
void streamStateFreeCur(SStreamStateCur* pCur);
|
||||
void streamStateResetCur(SStreamStateCur* pCur);
|
||||
|
||||
int32_t streamStateGetGroupKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateFillGetGroupKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
||||
|
||||
// twa
|
||||
void streamStateSetFillInfo(SStreamState* pState);
|
||||
void streamStateClearExpiredState(SStreamState* pState);
|
||||
|
||||
void streamStateCurNext(SStreamState* pState, SStreamStateCur* pCur);
|
||||
void streamStateCurPrev(SStreamState* pState, SStreamStateCur* pCur);
|
||||
|
||||
int32_t streamStatePutParName(SStreamState* pState, int64_t groupId, const char* tbname);
|
||||
int32_t streamStateGetParName(SStreamState* pState, int64_t groupId, void** pVal, bool onlyCache, int32_t* pWinCode);
|
||||
|
||||
// group id
|
||||
int32_t streamStateGroupPut(SStreamState* pState, int64_t groupId, void* value, int32_t vLen);
|
||||
SStreamStateCur* streamStateGroupGetCur(SStreamState* pState);
|
||||
void streamStateGroupCurNext(SStreamStateCur* pCur);
|
||||
int32_t streamStateGroupGetKVByCur(SStreamStateCur* pCur, int64_t* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
void streamStateReloadInfo(SStreamState* pState, TSKEY ts);
|
||||
|
||||
void streamStateCopyBackend(SStreamState* src, SStreamState* dst);
|
||||
|
|
|
@ -70,7 +70,8 @@ typedef struct SActiveCheckpointInfo SActiveCheckpointInfo;
|
|||
#define SSTREAM_TASK_NEED_CONVERT_VER 2
|
||||
#define SSTREAM_TASK_SUBTABLE_CHANGED_VER 3
|
||||
|
||||
extern int32_t streamMetaId;
|
||||
extern int32_t streamMetaRefPool;
|
||||
extern int32_t streamTaskRefPool;
|
||||
|
||||
enum {
|
||||
STREAM_STATUS__NORMAL = 0,
|
||||
|
@ -113,7 +114,7 @@ enum {
|
|||
|
||||
enum {
|
||||
TASK_TRIGGER_STATUS__INACTIVE = 1,
|
||||
TASK_TRIGGER_STATUS__ACTIVE,
|
||||
TASK_TRIGGER_STATUS__MAY_ACTIVE,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
@ -258,6 +259,7 @@ typedef struct STaskId {
|
|||
typedef struct SStreamTaskId {
|
||||
int64_t streamId;
|
||||
int32_t taskId;
|
||||
int64_t refId;
|
||||
const char* idStr;
|
||||
} SStreamTaskId;
|
||||
|
||||
|
@ -291,12 +293,12 @@ typedef struct SStreamStatus {
|
|||
int8_t schedStatus;
|
||||
int8_t statusBackup;
|
||||
int32_t schedIdleTime; // idle time before invoke again
|
||||
int32_t timerActive; // timer is active
|
||||
int64_t lastExecTs; // last exec time stamp
|
||||
int32_t inScanHistorySentinel;
|
||||
bool appendTranstateBlock; // has append the transfer state data block already
|
||||
bool appendTranstateBlock; // has appended the transfer state data block already
|
||||
bool removeBackendFiles; // remove backend files on disk when free stream tasks
|
||||
SConsenChkptInfo consenChkptInfo;
|
||||
STimeWindow latestForceWindow; // latest generated time window, only valid in
|
||||
} SStreamStatus;
|
||||
|
||||
typedef struct SDataRange {
|
||||
|
@ -309,10 +311,12 @@ typedef struct SSTaskBasicInfo {
|
|||
SEpSet epSet;
|
||||
SEpSet mnodeEpset; // mnode epset for send heartbeat
|
||||
int32_t selfChildId;
|
||||
int32_t totalLevel;
|
||||
int32_t trigger;
|
||||
int8_t taskLevel;
|
||||
int8_t fillHistory; // is fill history task or not
|
||||
int64_t delaySchedParam; // in msec
|
||||
int64_t watermark; // extracted from operators
|
||||
SInterval interval;
|
||||
} SSTaskBasicInfo;
|
||||
|
||||
typedef struct SStreamRetrieveReq SStreamRetrieveReq;
|
||||
|
@ -454,7 +458,6 @@ struct SStreamTask {
|
|||
|
||||
// the followings attributes don't be serialized
|
||||
SScanhistorySchedInfo schedHistoryInfo;
|
||||
int32_t refCnt;
|
||||
int32_t transferStateAlignCnt;
|
||||
struct SStreamMeta* pMeta;
|
||||
SSHashObj* pNameMap;
|
||||
|
@ -544,9 +547,10 @@ typedef struct STaskUpdateEntry {
|
|||
|
||||
typedef int32_t (*__state_trans_user_fn)(SStreamTask*, void* param);
|
||||
|
||||
int32_t tNewStreamTask(int64_t streamId, int8_t taskLevel, SEpSet* pEpset, bool fillHistory, int64_t triggerParam,
|
||||
SArray* pTaskList, bool hasFillhistory, int8_t subtableWithoutMd5, SStreamTask** pTask);
|
||||
void tFreeStreamTask(SStreamTask* pTask);
|
||||
int32_t tNewStreamTask(int64_t streamId, int8_t taskLevel, SEpSet* pEpset, bool fillHistory, int32_t trigger,
|
||||
int64_t triggerParam, SArray* pTaskList, bool hasFillhistory, int8_t subtableWithoutMd5,
|
||||
SStreamTask** pTask);
|
||||
void tFreeStreamTask(void* pTask);
|
||||
int32_t tEncodeStreamTask(SEncoder* pEncoder, const SStreamTask* pTask);
|
||||
int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask);
|
||||
int32_t streamTaskInit(SStreamTask* pTask, SStreamMeta* pMeta, SMsgCb* pMsgCb, int64_t ver);
|
||||
|
@ -664,6 +668,8 @@ void streamTaskResetStatus(SStreamTask* pTask);
|
|||
void streamTaskSetStatusReady(SStreamTask* pTask);
|
||||
ETaskStatus streamTaskGetPrevStatus(const SStreamTask* pTask);
|
||||
const char* streamTaskGetExecType(int32_t type);
|
||||
int32_t streamTaskAllocRefId(SStreamTask* pTask, int64_t** pRefId);
|
||||
void streamTaskFreeRefId(int64_t* pRefId);
|
||||
|
||||
bool streamTaskUpdateEpsetInfo(SStreamTask* pTask, SArray* pNodeList);
|
||||
void streamTaskResetUpstreamStageInfo(SStreamTask* pTask);
|
||||
|
@ -752,16 +758,15 @@ int32_t streamMetaRegisterTask(SStreamMeta* pMeta, int64_t ver, SStreamTask* pTa
|
|||
int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId);
|
||||
int32_t streamMetaGetNumOfTasks(SStreamMeta* pMeta);
|
||||
int32_t streamMetaAcquireTaskNoLock(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, SStreamTask** pTask);
|
||||
int32_t streamMetaAcquireTaskUnsafe(SStreamMeta* pMeta, STaskId* pId, SStreamTask** pTask);
|
||||
int32_t streamMetaAcquireTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, SStreamTask** pTask);
|
||||
void streamMetaReleaseTask(SStreamMeta* pMeta, SStreamTask* pTask);
|
||||
int32_t streamMetaAcquireOneTask(SStreamTask* pTask);
|
||||
void streamMetaClear(SStreamMeta* pMeta);
|
||||
void streamMetaInitBackend(SStreamMeta* pMeta);
|
||||
int32_t streamMetaCommit(SStreamMeta* pMeta);
|
||||
int64_t streamMetaGetLatestCheckpointId(SStreamMeta* pMeta);
|
||||
void streamMetaNotifyClose(SStreamMeta* pMeta);
|
||||
void streamMetaStartHb(SStreamMeta* pMeta);
|
||||
bool streamMetaTaskInTimer(SStreamMeta* pMeta);
|
||||
int32_t streamMetaAddTaskLaunchResult(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
|
||||
int64_t endTs, bool ready);
|
||||
int32_t streamMetaInitStartInfo(STaskStartInfo* pStartInfo);
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
#ifndef _STREAM_FILE_STATE_H_
|
||||
#define _STREAM_FILE_STATE_H_
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "storageapi.h"
|
||||
#include "tarray.h"
|
||||
#include "tdef.h"
|
||||
|
@ -37,7 +35,7 @@ typedef void (*_state_buff_cleanup_fn)(void* pRowBuff);
|
|||
typedef void* (*_state_buff_create_statekey_fn)(SRowBuffPos* pPos, int64_t num);
|
||||
|
||||
typedef int32_t (*_state_file_remove_fn)(SStreamFileState* pFileState, const void* pKey);
|
||||
typedef int32_t (*_state_file_get_fn)(SStreamFileState* pFileState, void* pKey, void* data, int32_t* pDataLen);
|
||||
typedef int32_t (*_state_file_get_fn)(SStreamFileState* pFileState, void* pKey, void** data, int32_t* pDataLen);
|
||||
typedef int32_t (*_state_file_clear_fn)(SStreamState* pState);
|
||||
|
||||
typedef int32_t (*_state_fun_get_fn)(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal,
|
||||
|
@ -45,6 +43,8 @@ typedef int32_t (*_state_fun_get_fn)(SStreamFileState* pFileState, void* pKey, i
|
|||
|
||||
typedef int32_t (*range_cmpr_fn)(const SSessionKey* pWin1, const SSessionKey* pWin2);
|
||||
|
||||
typedef int (*__session_compare_fn_t)(const void* pWin, const void* pDatas, int pos);
|
||||
|
||||
int32_t streamFileStateInit(int64_t memSize, uint32_t keySize, uint32_t rowSize, uint32_t selectRowSize, GetTsFun fp,
|
||||
void* pFile, TSKEY delMark, const char* taskId, int64_t checkpointId, int8_t type,
|
||||
struct SStreamFileState** ppFileState);
|
||||
|
@ -54,6 +54,8 @@ bool needClearDiskBuff(SStreamFileState* pFileState);
|
|||
void streamFileStateReleaseBuff(SStreamFileState* pFileState, SRowBuffPos* pPos, bool used);
|
||||
void streamFileStateClearBuff(SStreamFileState* pFileState, SRowBuffPos* pPos);
|
||||
|
||||
int32_t addRowBuffIfNotExist(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
int32_t getRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
void deleteRowBuff(SStreamFileState* pFileState, const void* pKey, int32_t keyLen);
|
||||
|
@ -71,9 +73,11 @@ int32_t streamFileStateGetSelectRowSize(SStreamFileState* pFileState);
|
|||
void streamFileStateReloadInfo(SStreamFileState* pFileState, TSKEY ts);
|
||||
|
||||
void* getRowStateBuff(SStreamFileState* pFileState);
|
||||
void* getSearchBuff(SStreamFileState* pFileState);
|
||||
void* getStateFileStore(SStreamFileState* pFileState);
|
||||
bool isDeteled(SStreamFileState* pFileState, TSKEY ts);
|
||||
bool isFlushedState(SStreamFileState* pFileState, TSKEY ts, TSKEY gap);
|
||||
TSKEY getFlushMark(SStreamFileState* pFileState);
|
||||
SRowBuffPos* getNewRowPosForWrite(SStreamFileState* pFileState);
|
||||
int32_t getRowStateRowSize(SStreamFileState* pFileState);
|
||||
|
||||
|
@ -94,6 +98,7 @@ int32_t recoverSesssion(SStreamFileState* pFileState, int64_t ckId);
|
|||
void sessionWinStateClear(SStreamFileState* pFileState);
|
||||
void sessionWinStateCleanup(void* pBuff);
|
||||
|
||||
SStreamStateCur* createStateCursor(SStreamFileState* pFileState);
|
||||
SStreamStateCur* sessionWinStateSeekKeyCurrentPrev(SStreamFileState* pFileState, const SSessionKey* pWinKey);
|
||||
SStreamStateCur* sessionWinStateSeekKeyCurrentNext(SStreamFileState* pFileState, const SSessionKey* pWinKey);
|
||||
SStreamStateCur* sessionWinStateSeekKeyNext(SStreamFileState* pFileState, const SSessionKey* pWinKey);
|
||||
|
@ -103,6 +108,8 @@ void sessionWinStateMoveToNext(SStreamStateCur* pCur);
|
|||
int32_t sessionWinStateGetKeyByRange(SStreamFileState* pFileState, const SSessionKey* key, SSessionKey* curKey,
|
||||
range_cmpr_fn cmpFn);
|
||||
|
||||
int32_t binarySearch(void* keyList, int num, const void* key, __session_compare_fn_t cmpFn);
|
||||
|
||||
// state window
|
||||
int32_t getStateWinResultBuff(SStreamFileState* pFileState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
|
||||
state_key_cmpr_fn fn, void** pVal, int32_t* pVLen, int32_t* pWinCode);
|
||||
|
@ -117,6 +124,34 @@ int32_t getSessionRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyL
|
|||
int32_t* pWinCode);
|
||||
int32_t getFunctionRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen);
|
||||
|
||||
// time slice
|
||||
int32_t getHashSortRowBuff(SStreamFileState* pFileState, const SWinKey* pKey, void** pVal, int32_t* pVLen,
|
||||
int32_t* pWinCode);
|
||||
int32_t hashSortFileGetFn(SStreamFileState* pFileState, void* pKey, void** data, int32_t* pDataLen);
|
||||
int32_t hashSortFileRemoveFn(SStreamFileState* pFileState, const void* pKey);
|
||||
void clearSearchBuff(SStreamFileState* pFileState);
|
||||
int32_t getHashSortNextRow(SStreamFileState* pFileState, const SWinKey* pKey, SWinKey* pResKey, void** pVal,
|
||||
int32_t* pVLen, int32_t* pWinCode);
|
||||
int32_t getHashSortPrevRow(SStreamFileState* pFileState, const SWinKey* pKey, SWinKey* pResKey, void** ppVal,
|
||||
int32_t* pVLen, int32_t* pWinCode);
|
||||
int32_t recoverFillSnapshot(SStreamFileState* pFileState, int64_t ckId);
|
||||
void deleteHashSortRowBuff(SStreamFileState* pFileState, const SWinKey* pKey);
|
||||
|
||||
//group
|
||||
int32_t streamFileStateGroupPut(SStreamFileState* pFileState, int64_t groupId, void* value, int32_t vLen);
|
||||
void streamFileStateGroupCurNext(SStreamStateCur* pCur);
|
||||
int32_t streamFileStateGroupGetKVByCur(SStreamStateCur* pCur, int64_t* pKey, void** pVal, int32_t* pVLen);
|
||||
SSHashObj* getGroupIdCache(SStreamFileState* pFileState);
|
||||
int fillStateKeyCompare(const void* pWin1, const void* pDatas, int pos);
|
||||
int32_t getRowStatePrevRow(SStreamFileState* pFileState, const SWinKey* pKey, SWinKey* pResKey, void** ppVal,
|
||||
int32_t* pVLen, int32_t* pWinCode);
|
||||
int32_t addSearchItem(SStreamFileState* pFileState, SArray* pWinStates, const SWinKey* pKey);
|
||||
|
||||
//twa
|
||||
void setFillInfo(SStreamFileState* pFileState);
|
||||
void clearExpiredState(SStreamFileState* pFileState);
|
||||
int32_t addArrayBuffIfNotExist(SSHashObj* pSearchBuff, uint64_t groupId, SArray** ppResStates);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,8 +36,8 @@ bool updateInfoIsTableInserted(SUpdateInfo* pInfo, int64_t tbUid);
|
|||
void updateInfoDestroy(SUpdateInfo* pInfo);
|
||||
void updateInfoAddCloseWindowSBF(SUpdateInfo* pInfo);
|
||||
void updateInfoDestoryColseWinSBF(SUpdateInfo* pInfo);
|
||||
int32_t updateInfoSerialize(void* buf, int32_t bufLen, const SUpdateInfo* pInfo, int32_t* pLen);
|
||||
int32_t updateInfoDeserialize(void* buf, int32_t bufLen, SUpdateInfo* pInfo);
|
||||
int32_t updateInfoSerialize(SEncoder* pEncoder, const SUpdateInfo* pInfo);
|
||||
int32_t updateInfoDeserialize(SDecoder* pDeCoder, SUpdateInfo* pInfo);
|
||||
void windowSBfDelete(SUpdateInfo* pInfo, uint64_t count);
|
||||
int32_t windowSBfAdd(SUpdateInfo* pInfo, uint64_t count);
|
||||
bool isIncrementalTimeStamp(SUpdateInfo* pInfo, uint64_t tableId, TSKEY ts, void* pPkVal, int32_t len);
|
||||
|
|
|
@ -210,6 +210,7 @@ int32_t taosGetErrSize();
|
|||
#define TSDB_CODE_TSC_COMPRESS_PARAM_ERROR TAOS_DEF_ERROR_CODE(0, 0X0233)
|
||||
#define TSDB_CODE_TSC_COMPRESS_LEVEL_ERROR TAOS_DEF_ERROR_CODE(0, 0X0234)
|
||||
#define TSDB_CODE_TSC_FAIL_GENERATE_JSON TAOS_DEF_ERROR_CODE(0, 0X0235)
|
||||
#define TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR TAOS_DEF_ERROR_CODE(0, 0X0236)
|
||||
#define TSDB_CODE_TSC_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0X02FF)
|
||||
|
||||
// mnode-common
|
||||
|
@ -354,6 +355,8 @@ int32_t taosGetErrSize();
|
|||
#define TSDB_CODE_MND_INVALID_SYS_TABLENAME TAOS_DEF_ERROR_CODE(0, 0x039A)
|
||||
#define TSDB_CODE_MND_ENCRYPT_NOT_ALLOW_CHANGE TAOS_DEF_ERROR_CODE(0, 0x039B)
|
||||
#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)
|
||||
|
||||
// mnode-node
|
||||
#define TSDB_CODE_MND_MNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x03A0)
|
||||
|
@ -776,6 +779,7 @@ int32_t taosGetErrSize();
|
|||
#define TSDB_CODE_SCH_TIMEOUT_ERROR TAOS_DEF_ERROR_CODE(0, 0x2504)
|
||||
#define TSDB_CODE_SCH_JOB_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x2505)
|
||||
#define TSDB_CODE_SCH_JOB_NOT_EXISTS TAOS_DEF_ERROR_CODE(0, 0x2506)
|
||||
#define TSDB_CODE_SCH_DATA_SRC_EP_MISS TAOS_DEF_ERROR_CODE(0, 0x2507)
|
||||
|
||||
//parser
|
||||
#define TSDB_CODE_PAR_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x2600)
|
||||
|
@ -922,6 +926,11 @@ int32_t taosGetErrSize();
|
|||
#define TSDB_CODE_FUNC_INVALID_RES_LENGTH TAOS_DEF_ERROR_CODE(0, 0x280E)
|
||||
#define TSDB_CODE_FUNC_HISTOGRAM_ERROR TAOS_DEF_ERROR_CODE(0, 0x280F)
|
||||
#define TSDB_CODE_FUNC_PERCENTILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x2810)
|
||||
#define TSDB_CODE_FUNC_FUNTION_PARA_RANGE TAOS_DEF_ERROR_CODE(0, 0x2811)
|
||||
#define TSDB_CODE_FUNC_FUNTION_PARA_PRIMTS TAOS_DEF_ERROR_CODE(0, 0x2812)
|
||||
#define TSDB_CODE_FUNC_FUNTION_PARA_PK TAOS_DEF_ERROR_CODE(0, 0x2813)
|
||||
#define TSDB_CODE_FUNC_FUNTION_PARA_HAS_COL TAOS_DEF_ERROR_CODE(0, 0x2814)
|
||||
#define TSDB_CODE_FUNC_FUNCTION_HISTO_TYPE TAOS_DEF_ERROR_CODE(0, 0x2815)
|
||||
|
||||
|
||||
//udf
|
||||
|
|
|
@ -152,15 +152,12 @@ int32_t tsDecompressBigint(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int
|
|||
// for internal usage
|
||||
int32_t getWordLength(char type);
|
||||
|
||||
#ifdef __AVX2__
|
||||
int32_t tsDecompressIntImpl_Hw(const char *const input, const int32_t nelements, char *const output, const char type);
|
||||
int32_t tsDecompressFloatImpAvx2(const char *input, int32_t nelements, char *output);
|
||||
int32_t tsDecompressDoubleImpAvx2(const char *input, int32_t nelements, char *output);
|
||||
#endif
|
||||
#ifdef __AVX512VL__
|
||||
void tsDecompressTimestampAvx2(const char *input, int32_t nelements, char *output, bool bigEndian);
|
||||
void tsDecompressTimestampAvx512(const char *const input, const int32_t nelements, char *const output, bool bigEndian);
|
||||
#endif
|
||||
int32_t tsDecompressTimestampAvx2(const char *input, int32_t nelements, char *output, bool bigEndian);
|
||||
int32_t tsDecompressTimestampAvx512(const char *const input, const int32_t nelements, char *const output,
|
||||
bool bigEndian);
|
||||
|
||||
/*************************************************************************
|
||||
* REGULAR COMPRESSION 2
|
||||
|
|
|
@ -41,6 +41,7 @@ extern const int32_t TYPE_BYTES[21];
|
|||
#define FLOAT_BYTES sizeof(float)
|
||||
#define DOUBLE_BYTES sizeof(double)
|
||||
#define POINTER_BYTES sizeof(void *)
|
||||
#define M256_BYTES 32
|
||||
#define TSDB_KEYSIZE sizeof(TSKEY)
|
||||
#define TSDB_NCHAR_SIZE sizeof(TdUcs4)
|
||||
|
||||
|
@ -188,6 +189,47 @@ typedef enum EOperatorType {
|
|||
OP_TYPE_ASSIGN = 200
|
||||
} EOperatorType;
|
||||
|
||||
static const EOperatorType OPERATOR_ARRAY[] = {
|
||||
OP_TYPE_ADD,
|
||||
OP_TYPE_SUB,
|
||||
OP_TYPE_MULTI,
|
||||
OP_TYPE_DIV,
|
||||
OP_TYPE_REM,
|
||||
|
||||
OP_TYPE_MINUS,
|
||||
|
||||
OP_TYPE_BIT_AND,
|
||||
OP_TYPE_BIT_OR,
|
||||
|
||||
OP_TYPE_GREATER_THAN,
|
||||
OP_TYPE_GREATER_EQUAL,
|
||||
OP_TYPE_LOWER_THAN,
|
||||
OP_TYPE_LOWER_EQUAL,
|
||||
OP_TYPE_EQUAL,
|
||||
OP_TYPE_NOT_EQUAL,
|
||||
OP_TYPE_IN,
|
||||
OP_TYPE_NOT_IN,
|
||||
OP_TYPE_LIKE,
|
||||
OP_TYPE_NOT_LIKE,
|
||||
OP_TYPE_MATCH,
|
||||
OP_TYPE_NMATCH,
|
||||
|
||||
OP_TYPE_IS_NULL,
|
||||
OP_TYPE_IS_NOT_NULL,
|
||||
OP_TYPE_IS_TRUE,
|
||||
OP_TYPE_IS_FALSE,
|
||||
OP_TYPE_IS_UNKNOWN,
|
||||
OP_TYPE_IS_NOT_TRUE,
|
||||
OP_TYPE_IS_NOT_FALSE,
|
||||
OP_TYPE_IS_NOT_UNKNOWN,
|
||||
//OP_TYPE_COMPARE_MAX_VALUE,
|
||||
|
||||
OP_TYPE_JSON_GET_VALUE,
|
||||
OP_TYPE_JSON_CONTAINS,
|
||||
|
||||
OP_TYPE_ASSIGN
|
||||
};
|
||||
|
||||
#define OP_TYPE_CALC_MAX OP_TYPE_BIT_OR
|
||||
|
||||
typedef enum ELogicConditionType {
|
||||
|
@ -411,6 +453,7 @@ typedef enum ELogicConditionType {
|
|||
#define TSDB_CACHE_MODEL_LAST_ROW 1
|
||||
#define TSDB_CACHE_MODEL_LAST_VALUE 2
|
||||
#define TSDB_CACHE_MODEL_BOTH 3
|
||||
#define TSDB_DNODE_LIST_LEN 256
|
||||
#define TSDB_ENCRYPT_ALGO_STR_LEN 16
|
||||
#define TSDB_ENCRYPT_ALGO_NONE_STR "none"
|
||||
#define TSDB_ENCRYPT_ALGO_SM4_STR "sm4"
|
||||
|
@ -450,13 +493,13 @@ typedef enum ELogicConditionType {
|
|||
|
||||
#define TSDB_MIN_S3_CHUNK_SIZE (128 * 1024)
|
||||
#define TSDB_MAX_S3_CHUNK_SIZE (1024 * 1024)
|
||||
#define TSDB_DEFAULT_S3_CHUNK_SIZE (256 * 1024)
|
||||
#define TSDB_DEFAULT_S3_CHUNK_SIZE (128 * 1024)
|
||||
#define TSDB_MIN_S3_KEEP_LOCAL (1 * 1440) // unit minute
|
||||
#define TSDB_MAX_S3_KEEP_LOCAL (365000 * 1440)
|
||||
#define TSDB_DEFAULT_S3_KEEP_LOCAL (3650 * 1440)
|
||||
#define TSDB_DEFAULT_S3_KEEP_LOCAL (365 * 1440)
|
||||
#define TSDB_MIN_S3_COMPACT 0
|
||||
#define TSDB_MAX_S3_COMPACT 1
|
||||
#define TSDB_DEFAULT_S3_COMPACT 0
|
||||
#define TSDB_DEFAULT_S3_COMPACT 1
|
||||
|
||||
#define TSDB_DB_MIN_WAL_RETENTION_PERIOD -1
|
||||
#define TSDB_REP_DEF_DB_WAL_RET_PERIOD 3600
|
||||
|
@ -610,6 +653,8 @@ enum { RAND_ERR_MEMORY = 1, RAND_ERR_FILE = 2, RAND_ERR_NETWORK = 4 };
|
|||
#define MONITOR_TAG_VALUE_LEN 300
|
||||
#define MONITOR_METRIC_NAME_LEN 100
|
||||
|
||||
#define AUDIT_OPERATION_LEN 20
|
||||
|
||||
typedef enum {
|
||||
ANAL_ALGO_TYPE_ANOMALY_DETECT = 0,
|
||||
ANAL_ALGO_TYPE_FORECAST = 1,
|
||||
|
|
|
@ -70,7 +70,7 @@ extern int32_t tdbDebugFlag;
|
|||
extern int32_t sndDebugFlag;
|
||||
extern int32_t simDebugFlag;
|
||||
|
||||
extern int32_t tqClientDebug;
|
||||
extern int32_t tqClientDebugFlag;
|
||||
|
||||
int32_t taosInitLog(const char *logName, int32_t maxFiles, bool tsc);
|
||||
void taosCloseLog();
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char version[];
|
||||
extern char compatible_version[];
|
||||
extern char gitinfo[];
|
||||
extern char gitinfoOfInternal[];
|
||||
extern char buildinfo[];
|
||||
extern char td_version[];
|
||||
extern char td_compatible_version[];
|
||||
extern char td_gitinfo[];
|
||||
extern char td_gitinfoOfInternal[];
|
||||
extern char td_buildinfo[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import subprocess
|
||||
import re
|
||||
|
||||
# 执行 git fetch 命令并捕获输出
|
||||
def git_fetch():
|
||||
result = subprocess.run(['git', 'fetch'], capture_output=True, text=True)
|
||||
return result
|
||||
|
||||
# 解析分支名称
|
||||
def parse_branch_name_type1(error_output):
|
||||
# 使用正则表达式匹配 'is at' 前的分支名称
|
||||
match = re.search(r"error: cannot lock ref '(refs/remotes/origin/[^']+)': is at", error_output)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
# 解析第二种错误中的分支名称
|
||||
def parse_branch_name_type2(error_output):
|
||||
# 使用正则表达式匹配 'exists' 前的第一个引号内的分支名称
|
||||
match = re.search(r"'(refs/remotes/origin/[^']+)' exists;", error_output)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
# 执行 git update-ref -d 命令
|
||||
def git_update_ref(branch_name):
|
||||
if branch_name:
|
||||
subprocess.run(['git', 'update-ref', '-d', f'{branch_name}'], check=True)
|
||||
|
||||
# 解析错误类型并执行相应的修复操作
|
||||
def handle_error(error_output):
|
||||
# 错误类型1:本地引用的提交ID与远程不一致
|
||||
if "is at" in error_output and "but expected" in error_output:
|
||||
branch_name = parse_branch_name_type1(error_output)
|
||||
if branch_name:
|
||||
print(f"Detected error type 1, attempting to delete ref for branch: {branch_name}")
|
||||
git_update_ref(branch_name)
|
||||
else:
|
||||
print("Error parsing branch name for type 1.")
|
||||
# 错误类型2:尝试创建新的远程引用时,本地已经存在同名的引用
|
||||
elif "exists; cannot create" in error_output:
|
||||
branch_name = parse_branch_name_type2(error_output)
|
||||
if branch_name:
|
||||
print(f"Detected error type 2, attempting to delete ref for branch: {branch_name}")
|
||||
git_update_ref(branch_name)
|
||||
else:
|
||||
print("Error parsing branch name for type 2.")
|
||||
|
||||
# 主函数
|
||||
def main():
|
||||
fetch_result = git_fetch()
|
||||
if fetch_result.returncode != 0: # 如果 git fetch 命令失败
|
||||
error_output = fetch_result.stderr
|
||||
handle_error(error_output)
|
||||
else:
|
||||
print("Git fetch successful.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,319 @@
|
|||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
/* do not increase min-width as some may use split screens */
|
||||
min-width: 800px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
p {
|
||||
color: black;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* SUMMARY INFORMATION
|
||||
******************************/
|
||||
#environment td {
|
||||
padding: 5px;
|
||||
border: 1px solid #e6e6e6;
|
||||
vertical-align: top;
|
||||
}
|
||||
#environment tr:nth-child(odd) {
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
#environment ul {
|
||||
margin: 0;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* TEST RESULT COLORS
|
||||
******************************/
|
||||
span.passed,
|
||||
.passed .col-result {
|
||||
color: green;
|
||||
}
|
||||
|
||||
span.skipped,
|
||||
span.xfailed,
|
||||
span.rerun,
|
||||
.skipped .col-result,
|
||||
.xfailed .col-result,
|
||||
.rerun .col-result {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
span.error,
|
||||
span.failed,
|
||||
span.xpassed,
|
||||
.error .col-result,
|
||||
.failed .col-result,
|
||||
.xpassed .col-result {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.col-links__extra {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* RESULTS TABLE
|
||||
*
|
||||
* 1. Table Layout
|
||||
* 2. Extra
|
||||
* 3. Sorting items
|
||||
*
|
||||
******************************/
|
||||
/*------------------
|
||||
* 1. Table Layout
|
||||
*------------------*/
|
||||
#results-table {
|
||||
border: 1px solid #e6e6e6;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
#results-table th,
|
||||
#results-table td {
|
||||
padding: 5px;
|
||||
border: 1px solid #e6e6e6;
|
||||
text-align: left;
|
||||
}
|
||||
#results-table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*------------------
|
||||
* 2. Extra
|
||||
*------------------*/
|
||||
.logwrapper {
|
||||
max-height: 230px;
|
||||
overflow-y: scroll;
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
.logwrapper.expanded {
|
||||
max-height: none;
|
||||
}
|
||||
.logwrapper.expanded .logexpander:after {
|
||||
content: "collapse [-]";
|
||||
}
|
||||
.logwrapper .logexpander {
|
||||
z-index: 1;
|
||||
position: sticky;
|
||||
top: 10px;
|
||||
width: max-content;
|
||||
border: 1px solid;
|
||||
border-radius: 3px;
|
||||
padding: 5px 7px;
|
||||
margin: 10px 0 10px calc(100% - 80px);
|
||||
cursor: pointer;
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
.logwrapper .logexpander:after {
|
||||
content: "expand [+]";
|
||||
}
|
||||
.logwrapper .logexpander:hover {
|
||||
color: #000;
|
||||
border-color: #000;
|
||||
}
|
||||
.logwrapper .log {
|
||||
min-height: 40px;
|
||||
position: relative;
|
||||
top: -50px;
|
||||
height: calc(100% + 50px);
|
||||
border: 1px solid #e6e6e6;
|
||||
color: black;
|
||||
display: block;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
padding: 5px;
|
||||
padding-right: 80px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
div.media {
|
||||
border: 1px solid #e6e6e6;
|
||||
float: right;
|
||||
height: 240px;
|
||||
margin: 0 5px;
|
||||
overflow: hidden;
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.media-container {
|
||||
display: grid;
|
||||
grid-template-columns: 25px auto 25px;
|
||||
align-items: center;
|
||||
flex: 1 1;
|
||||
overflow: hidden;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.media-container--fullscreen {
|
||||
grid-template-columns: 0px auto 0px;
|
||||
}
|
||||
|
||||
.media-container__nav--right,
|
||||
.media-container__nav--left {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.media-container__viewport {
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
height: inherit;
|
||||
}
|
||||
.media-container__viewport img,
|
||||
.media-container__viewport video {
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.media__name,
|
||||
.media__counter {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
flex: 0 0 25px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.collapsible td:not(.col-links) {
|
||||
cursor: pointer;
|
||||
}
|
||||
.collapsible td:not(.col-links):hover::after {
|
||||
color: #bbb;
|
||||
font-style: italic;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.col-result {
|
||||
width: 130px;
|
||||
}
|
||||
.col-result:hover::after {
|
||||
content: " (hide details)";
|
||||
}
|
||||
|
||||
.col-result.collapsed:hover::after {
|
||||
content: " (show details)";
|
||||
}
|
||||
|
||||
#environment-header h2:hover::after {
|
||||
content: " (hide details)";
|
||||
color: #bbb;
|
||||
font-style: italic;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#environment-header.collapsed h2:hover::after {
|
||||
content: " (show details)";
|
||||
color: #bbb;
|
||||
font-style: italic;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/*------------------
|
||||
* 3. Sorting items
|
||||
*------------------*/
|
||||
.sortable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.sortable.desc:after {
|
||||
content: " ";
|
||||
position: relative;
|
||||
left: 5px;
|
||||
bottom: -12.5px;
|
||||
border: 10px solid #4caf50;
|
||||
border-bottom: 0;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.sortable.asc:after {
|
||||
content: " ";
|
||||
position: relative;
|
||||
left: 5px;
|
||||
bottom: 12.5px;
|
||||
border: 10px solid #4caf50;
|
||||
border-top: 0;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
|
||||
.hidden, .summary__reload__button.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.summary__data {
|
||||
flex: 0 0 550px;
|
||||
}
|
||||
.summary__reload {
|
||||
flex: 1 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.summary__reload__button {
|
||||
flex: 0 0 300px;
|
||||
display: flex;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
background-color: #4caf50;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.summary__reload__button:hover {
|
||||
background-color: #46a049;
|
||||
}
|
||||
.summary__spacer {
|
||||
flex: 0 0 550px;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.filters,
|
||||
.collapse {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.filters button,
|
||||
.collapse button {
|
||||
color: #999;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.filters button:hover,
|
||||
.collapse button:hover {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.filter__label {
|
||||
margin-right: 10px;
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
# conftest.py
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption(
|
||||
"--verMode", default="enterprise", help="community or enterprise"
|
||||
)
|
||||
parser.addoption(
|
||||
"--tVersion", default="3.3.2.6", help="the version of taos"
|
||||
)
|
||||
parser.addoption(
|
||||
"--baseVersion", default="smoking", help="the path of nas"
|
||||
)
|
||||
parser.addoption(
|
||||
"--sourcePath", default="nas", help="only support nas currently"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
# Collect the setup and teardown of each test case and their std information
|
||||
setup_stdout_info = {}
|
||||
teardown_stdout_info = {}
|
||||
|
||||
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
def pytest_runtest_makereport(item, call):
|
||||
outcome = yield
|
||||
rep = outcome.get_result()
|
||||
|
||||
# Record the std of setup and teardown
|
||||
if call.when == 'setup':
|
||||
for i in rep.sections:
|
||||
if i[0] == "Captured stdout setup":
|
||||
if not setup_stdout_info:
|
||||
setup_stdout_info[item.nodeid] = i[1]
|
||||
elif call.when == 'teardown':
|
||||
for i in rep.sections:
|
||||
if i[0] == "Captured stdout teardown":
|
||||
teardown_stdout_info[item.nodeid] = i[1]
|
||||
|
||||
|
||||
# Insert setup and teardown's std in the summary section
|
||||
def pytest_html_results_summary(prefix, summary, postfix):
|
||||
if setup_stdout_info or teardown_stdout_info:
|
||||
rows = []
|
||||
|
||||
# Insert setup stdout
|
||||
if setup_stdout_info:
|
||||
for nodeid, stdout in setup_stdout_info.items():
|
||||
html_content = '''
|
||||
<tr>
|
||||
<td><b><span style="font-size: larger; color: black;">Setup:</span></b></td>
|
||||
<td colspan="4">
|
||||
<a href="#" id="toggleSetup">Show Setup</a>
|
||||
<div id="setupContent" class="collapsible-content" style="display: none; white-space: pre-wrap; margin-top: 5px;">
|
||||
<pre>{}</pre>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
'''.format(stdout.strip())
|
||||
|
||||
# 如果需要在 Python 脚本中生成 HTML,并使用 JavaScript 控制折叠内容的显示,可以这样做:
|
||||
|
||||
html_script = '''
|
||||
<script>
|
||||
document.getElementById('toggleSetup').addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
var setupContentDiv = document.getElementById('setupContent');
|
||||
setupContentDiv.style.display = setupContentDiv.style.display === 'none' ? 'block' : 'none';
|
||||
var buttonText = setupContentDiv.style.display === 'none' ? 'Show Setup' : 'Hide Setup';
|
||||
this.textContent = buttonText;
|
||||
});
|
||||
</script>
|
||||
'''
|
||||
|
||||
# 输出完整的 HTML 代码
|
||||
final_html = html_content + html_script
|
||||
rows.append(final_html)
|
||||
rows.append("<br>")
|
||||
# Insert teardown stdout
|
||||
if teardown_stdout_info:
|
||||
for nodeid, stdout in teardown_stdout_info.items():
|
||||
html_content = '''
|
||||
<tr>
|
||||
<td><b><span style="font-size: larger; color: black;">Teardown:</span></b></td>
|
||||
<td colspan="4">
|
||||
<a href="#" id="toggleTeardown">Show Teardown</a>
|
||||
<div id="teardownContent" class="collapsible-content" style="display: none; white-space: pre-wrap; margin-top: 5px;">
|
||||
<pre>{}</pre>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
'''.format(stdout.strip())
|
||||
|
||||
# 如果需要在 Python 脚本中生成 HTML,并使用 JavaScript 控制折叠内容的显示,可以这样做:
|
||||
|
||||
html_script = '''
|
||||
<script>
|
||||
document.getElementById('toggleTeardown').addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
var teardownContentDiv = document.getElementById('teardownContent');
|
||||
teardownContentDiv.style.display = teardownContentDiv.style.display === 'none' ? 'block' : 'none';
|
||||
var buttonText = teardownContentDiv.style.display === 'none' ? 'Show Teardown' : 'Hide Teardown';
|
||||
this.textContent = buttonText;
|
||||
});
|
||||
</script>
|
||||
'''
|
||||
|
||||
# 输出完整的 HTML 代码
|
||||
final_html = html_content + html_script
|
||||
rows.append(final_html)
|
||||
|
||||
prefix.extend(rows)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue