other: merge 3.0
This commit is contained in:
commit
24b1a050fc
|
@ -7,7 +7,7 @@ description: This document describes how to query data in TDengine.
|
|||
## Syntax
|
||||
|
||||
```sql
|
||||
SELECT {DATABASE() | CLIENT_VERSION() | SERVER_VERSION() | SERVER_STATUS() | NOW() | TODAY() | TIMEZONE()}
|
||||
SELECT {DATABASE() | CLIENT_VERSION() | SERVER_VERSION() | SERVER_STATUS() | NOW() | TODAY() | TIMEZONE() | CURRENT_USER() | USER() }
|
||||
|
||||
SELECT [hints] [DISTINCT] [TAGS] select_list
|
||||
from_clause
|
||||
|
@ -195,7 +195,7 @@ The following SQL statement returns the number of subtables within the meters su
|
|||
SELECT COUNT(*) FROM (SELECT DISTINCT TBNAME FROM meters);
|
||||
```
|
||||
|
||||
In the preceding two statements, only tags can be used as filtering conditions in the WHERE clause. For example:
|
||||
In the preceding two statements, only tags can be used as filtering conditions in the WHERE clause.
|
||||
|
||||
**\_QSTART and \_QEND**
|
||||
|
||||
|
@ -245,8 +245,7 @@ You can perform INNER JOIN statements based on the primary key. The following co
|
|||
3. For supertables, the ON condition must be equivalent to the primary key. In addition, the tag columns of the tables on which the INNER JOIN is performed must have a one-to-one relationship. You cannot specify an OR condition.
|
||||
4. The tables that are included in a JOIN clause must be of the same type (supertable, standard table, or subtable).
|
||||
5. You can include subqueries before and after the JOIN keyword.
|
||||
6. You cannot include more than ten tables in a JOIN clause.
|
||||
7. You cannot include a FILL clause and a JOIN clause in the same statement.
|
||||
6. You cannot include a FILL clause and a JOIN clause in the same statement.
|
||||
|
||||
## GROUP BY
|
||||
|
||||
|
@ -337,6 +336,12 @@ SELECT TODAY();
|
|||
SELECT TIMEZONE();
|
||||
```
|
||||
|
||||
### Obtain Current User
|
||||
|
||||
```sql
|
||||
SELECT CURRENT_USER();
|
||||
```
|
||||
|
||||
## Regular Expression
|
||||
|
||||
### Syntax
|
||||
|
@ -391,7 +396,7 @@ SELECT AVG(CASE WHEN voltage < 200 or voltage > 250 THEN 220 ELSE voltage END) F
|
|||
|
||||
## JOIN
|
||||
|
||||
TDengine supports the `INTER JOIN` based on the timestamp primary key, that is, the `JOIN` condition must contain the timestamp primary key. As long as the requirement of timestamp-based primary key is met, `INTER JOIN` can be made between normal tables, sub-tables, super tables and sub-queries at will, and there is no limit on the number of tables.
|
||||
TDengine supports the `INTER JOIN` based on the timestamp primary key, that is, the `JOIN` condition must contain the timestamp primary key. As long as the requirement of timestamp-based primary key is met, `INTER JOIN` can be made between normal tables, sub-tables, super tables and sub-queries at will, and there is no limit on the number of tables, primary key and other conditions must be combined with `AND` operator.
|
||||
|
||||
For standard tables:
|
||||
|
||||
|
|
|
@ -1275,6 +1275,14 @@ SELECT SERVER_STATUS();
|
|||
|
||||
**Description**: The server status.
|
||||
|
||||
### CURRENT_USER
|
||||
|
||||
```sql
|
||||
SELECT CURRENT_USER();
|
||||
```
|
||||
|
||||
**Description**: get current user.
|
||||
|
||||
|
||||
## Geometry Functions
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ The following list shows all reserved keywords:
|
|||
|
||||
- MATCH
|
||||
- MAX_DELAY
|
||||
- MAX_SPEED
|
||||
- BWLIMIT
|
||||
- MAXROWS
|
||||
- MERGE
|
||||
- META
|
||||
|
|
|
@ -22,6 +22,14 @@ SHOW CLUSTER;
|
|||
|
||||
Shows information about the current cluster.
|
||||
|
||||
## SHOW CLUSTER ALIVE
|
||||
|
||||
```sql
|
||||
SHOW CLUSTER ALIVE;
|
||||
```
|
||||
|
||||
It is used to check whether the cluster is available or not. Return value: 0 means unavailable, 1 means available, 2 means partially available (some dnodes are offline, the other dnodes are available)
|
||||
|
||||
## SHOW CONNECTIONS
|
||||
|
||||
```sql
|
||||
|
|
|
@ -19,6 +19,9 @@ index_option:
|
|||
functions:
|
||||
function [, function] ...
|
||||
```
|
||||
### tag Indexing
|
||||
|
||||
[tag index](../tag-index)
|
||||
|
||||
### SMA Indexing
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ You can use the SHOW CONNECTIONS statement to find the conn_id.
|
|||
## Terminate a Query
|
||||
|
||||
```sql
|
||||
KILL QUERY kill_id;
|
||||
KILL QUERY 'kill_id';
|
||||
```
|
||||
|
||||
You can use the SHOW QUERIES statement to find the kill_id.
|
||||
|
|
|
@ -168,6 +168,12 @@ The base API is used to do things like create database connections and provide a
|
|||
|
||||
:::
|
||||
|
||||
- `TAOS *taos_connect_auth(const char *host, const char *user, const char *auth, const char *db, uint16_t port)`
|
||||
|
||||
The function is the same as taos_connect. Except that the pass parameter is replaced by auth, other parameters are the same as taos_connect.
|
||||
|
||||
- auth: the 32-bit lowercase md5 of the raw password
|
||||
|
||||
- `char *taos_get_server_info(TAOS *taos)`
|
||||
|
||||
Get server-side version information.
|
||||
|
@ -184,6 +190,14 @@ The base API is used to do things like create database connections and provide a
|
|||
- If len is less than the space required to store the db (including the last '\0'), an error is returned. The truncated data assigned in the database ends with '\0'.
|
||||
- If len is greater than or equal to the space required to store the db (including the last '\0'), return normal 0, and assign the db name ending with '\0' in the database.
|
||||
|
||||
- `int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type)`
|
||||
|
||||
Set the event callback function.
|
||||
|
||||
- fp: event callback function pointer. Declaration:typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);Param is a user-defined parameter, ext is an extended parameter (depending on the event type, and returns the user password version for TAOS_NOTIFY_PASSVER), and type is the event type
|
||||
- param: user-defined parameter
|
||||
- type: event type. Value range: 1) TAOS_NOTIFY_PASSVER: User password changed
|
||||
|
||||
- `void taos_close(TAOS *taos)`
|
||||
|
||||
Closes the connection, where `taos` is the handle returned by `taos_connect()`.
|
||||
|
@ -307,21 +321,20 @@ The specific functions related to the interface are as follows (see also the [pr
|
|||
|
||||
Parse a SQL command, and bind the parsed result and parameter information to `stmt`. If the parameter length is greater than 0, use this parameter as the length of the SQL command. If it is equal to 0, the length of the SQL command will be determined automatically.
|
||||
|
||||
- `int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind)`
|
||||
- `int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind)`
|
||||
|
||||
Not as efficient as `taos_stmt_bind_param_batch()`, but can support non-INSERT type SQL statements.
|
||||
To bind parameters, bind points to an array (representing the row of data to be bound), making sure that the number and order of the elements in this array are the same as the parameters in the SQL statement. taos_bind is used similarly to MYSQL_BIND in MySQL, as defined below.
|
||||
|
||||
```c
|
||||
typedef struct TAOS_BIND {
|
||||
typedef struct TAOS_MULTI_BIND {
|
||||
int buffer_type;
|
||||
void * buffer;
|
||||
uintptr_t buffer_length; // not in use
|
||||
uintptr_t * length;
|
||||
int * is_null;
|
||||
int is_unsigned; // not in use
|
||||
int * error; // not in use
|
||||
} TAOS_BIND;
|
||||
void *buffer;
|
||||
uintptr_t buffer_length;
|
||||
uint32_t *length;
|
||||
char *is_null;
|
||||
int num;
|
||||
} TAOS_MULTI_BIND;
|
||||
```
|
||||
|
||||
- `int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name)`
|
||||
|
@ -329,7 +342,7 @@ The specific functions related to the interface are as follows (see also the [pr
|
|||
(Available in 2.1.1.0 and later versions, only supported for replacing parameter values in INSERT statements)
|
||||
When the table name in the SQL command uses `? ` placeholder, you can use this function to bind a specific table name.
|
||||
|
||||
- `int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags)`
|
||||
- `int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_MULTI_BIND* tags)`
|
||||
|
||||
(Available in 2.1.2.0 and later versions, only supported for replacing parameter values in INSERT statements)
|
||||
When the table name and TAGS in the SQL command both use `? `, you can use this function to bind the specific table name and the specific TAGS value. The most typical usage scenario is an INSERT statement that uses the automatic table building function (the current version does not support specifying specific TAGS columns.) The number of columns in the TAGS parameter needs to be the same as the number of TAGS requested in the SQL command.
|
||||
|
@ -358,6 +371,14 @@ The specific functions related to the interface are as follows (see also the [pr
|
|||
|
||||
Execute the prepared statement. Currently, a statement can only be executed once.
|
||||
|
||||
- `int taos_stmt_affected_rows(TAOS_STMT *stmt)`
|
||||
|
||||
Gets the number of rows affected by executing bind statements multiple times.
|
||||
|
||||
- `int taos_stmt_affected_rows_once(TAOS_STMT *stmt)`
|
||||
|
||||
Gets the number of rows affected by executing a bind statement once.
|
||||
|
||||
- `TAOS_RES* taos_stmt_use_result(TAOS_STMT *stmt)`
|
||||
|
||||
Gets the result set of a statement. Use the result set in the same way as in the non-parametric call. When finished, `taos_free_result()` should be called on this result set to free resources.
|
||||
|
|
|
@ -30,6 +30,10 @@ The source code of `TDengine.Connector` is hosted on [GitHub](https://github.com
|
|||
|
||||
The supported platforms are the same as those supported by the TDengine client driver.
|
||||
|
||||
:::note
|
||||
Please note TDengine does not support 32bit Windows any more.
|
||||
:::
|
||||
|
||||
## Version support
|
||||
|
||||
Please refer to [version support list](/reference/connector#version-support)
|
||||
|
|
|
@ -102,6 +102,8 @@ Usage: taosdump [OPTION...] dbname [tbname ...]
|
|||
-L, --loose-mode Use loose mode if the table name and column name
|
||||
use letter and number only. Default is NOT.
|
||||
-n, --no-escape No escape char '`'. Default is using it.
|
||||
-Q, --dot-replace Repalce dot character with underline character in
|
||||
the table name.
|
||||
-T, --thread-num=THREAD_NUM Number of thread for dump in file. Default is
|
||||
8.
|
||||
-C, --cloud=CLOUD_DSN specify a DSN to access TDengine cloud service
|
||||
|
|
|
@ -74,7 +74,7 @@ grafana-cli plugins install tdengine-datasource
|
|||
sudo -u grafana grafana-cli plugins install tdengine-datasource
|
||||
```
|
||||
|
||||
You can also download zip files from [GitHub](https://github.com/taosdata/grafanaplugin/releases/tag/latest) or [Grafana](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation) and install manually. The commands are as follows:
|
||||
You can also download zip files from [GitHub](https://github.com/taosdata/grafanaplugin/releases/latest) or [Grafana](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation) and install manually. The commands are as follows:
|
||||
|
||||
```bash
|
||||
GF_VERSION=3.3.1
|
||||
|
|
|
@ -51,7 +51,7 @@ void insertData(TAOS *taos) {
|
|||
int code = taos_stmt_prepare(stmt, sql, 0);
|
||||
checkErrorCode(stmt, code, "failed to execute taos_stmt_prepare");
|
||||
// bind table name and tags
|
||||
TAOS_BIND tags[2];
|
||||
TAOS_MULTI_BIND tags[2];
|
||||
char *location = "California.SanFrancisco";
|
||||
int groupId = 2;
|
||||
tags[0].buffer_type = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -144,4 +144,4 @@ int main() {
|
|||
}
|
||||
|
||||
// output:
|
||||
// successfully inserted 2 rows
|
||||
// successfully inserted 2 rows
|
||||
|
|
|
@ -58,7 +58,7 @@ void insertData(TAOS *taos) {
|
|||
int code = taos_stmt_prepare(stmt, sql, 0);
|
||||
checkErrorCode(stmt, code, "failed to execute taos_stmt_prepare");
|
||||
// bind table name and tags
|
||||
TAOS_BIND tags[2];
|
||||
TAOS_MULTI_BIND tags[2];
|
||||
char* location = "California.SanFrancisco";
|
||||
int groupId = 2;
|
||||
tags[0].buffer_type = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -82,7 +82,7 @@ void insertData(TAOS *taos) {
|
|||
{1648432611749, 12.6, 218, 0.33},
|
||||
};
|
||||
|
||||
TAOS_BIND values[4];
|
||||
TAOS_MULTI_BIND values[4];
|
||||
values[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
values[0].buffer_length = sizeof(int64_t);
|
||||
values[0].length = &values[0].buffer_length;
|
||||
|
@ -138,4 +138,4 @@ int main() {
|
|||
|
||||
|
||||
// output:
|
||||
// successfully inserted 2 rows
|
||||
// successfully inserted 2 rows
|
||||
|
|
|
@ -6,7 +6,14 @@ toc_max_heading_level: 2
|
|||
|
||||
TDengine 是一款开源、高性能、云原生的[时序数据库](https://tdengine.com/tsdb/),且针对物联网、车联网、工业互联网、金融、IT 运维等场景进行了优化。TDengine 的代码,包括集群功能,都在 GNU AGPL v3.0 下开源。除核心的时序数据库功能外,TDengine 还提供[缓存](../develop/cache/)、[数据订阅](../develop/tmq)、[流式计算](../develop/stream)等其它功能以降低系统复杂度及研发和运维成本。
|
||||
|
||||
本章节介绍 TDengine 的主要功能、竞争优势、适用场景、与其他数据库的对比测试等等,让大家对 TDengine 有个整体的了解。
|
||||
本章节介绍 TDengine 的主要产品和功能、竞争优势、适用场景、与其他数据库的对比测试等等,让大家对 TDengine 有个整体的了解。
|
||||
|
||||
## 主要产品
|
||||
|
||||
TDengine 有三个主要产品:TDengine Pro (即 TDengine 企业版),TDengine Cloud,和 TDengine OSS,关于它们的具体定义请参考
|
||||
- [TDengine 企业版](https://www.taosdata.com/tdengine-pro)
|
||||
- [TDengine 云服务](https://cloud.taosdata.com/?utm_source=menu&utm_medium=webcn)
|
||||
- [TDengine 开源版](https://www.taosdata.com/tdengine-oss)
|
||||
|
||||
## 主要功能
|
||||
|
||||
|
|
|
@ -256,6 +256,12 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
|
||||
:::
|
||||
|
||||
- `TAOS *taos_connect_auth(const char *host, const char *user, const char *auth, const char *db, uint16_t port)`
|
||||
|
||||
功能同 taos_connect。除 pass 参数替换为 auth 外,其他参数同 taos_connect。
|
||||
|
||||
- auth: 原始密码取 32 位小写 md5
|
||||
|
||||
- `char *taos_get_server_info(TAOS *taos)`
|
||||
|
||||
获取服务端版本信息。
|
||||
|
@ -272,6 +278,14 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
- 如果,len 小于 存储db需要的空间(包含最后的'\0'),返回错误,database里赋值截断的数据,以'\0'结尾。
|
||||
- 如果,len 大于等于 存储db需要的空间(包含最后的'\0'),返回正常0,database里赋值以'\0‘结尾的db名。
|
||||
|
||||
- `int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type)`
|
||||
|
||||
设置事件回调函数。
|
||||
|
||||
- fp 事件回调函数指针。函数声明:typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);其中, param 为用户自定义参数,ext 为扩展参数(依赖事件类型,针对 TAOS_NOTIFY_PASSVER 返回用户密码版本),type 为事件类型
|
||||
- param 用户自定义参数
|
||||
- type 事件类型。取值范围:1)TAOS_NOTIFY_PASSVER: 用户密码改变
|
||||
|
||||
- `void taos_close(TAOS *taos)`
|
||||
|
||||
关闭连接,其中`taos`是 `taos_connect()` 返回的句柄。
|
||||
|
@ -396,21 +410,20 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
|
|||
|
||||
解析一条 SQL 语句,将解析结果和参数信息绑定到 stmt 上,如果参数 length 大于 0,将使用此参数作为 SQL 语句的长度,如等于 0,将自动判断 SQL 语句的长度。
|
||||
|
||||
- `int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind)`
|
||||
- `int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind)`
|
||||
|
||||
不如 `taos_stmt_bind_param_batch()` 效率高,但可以支持非 INSERT 类型的 SQL 语句。
|
||||
进行参数绑定,bind 指向一个数组(代表所要绑定的一行数据),需保证此数组中的元素数量和顺序与 SQL 语句中的参数完全一致。TAOS_BIND 的使用方法与 MySQL 中的 MYSQL_BIND 类似,具体定义如下:
|
||||
进行参数绑定,bind 指向一个数组(代表所要绑定的一行数据),需保证此数组中的元素数量和顺序与 SQL 语句中的参数完全一致。TAOS_MULTI_BIND 的使用方法与 MySQL 中的 MYSQL_BIND 类似,具体定义如下:
|
||||
|
||||
```c
|
||||
typedef struct TAOS_BIND {
|
||||
typedef struct TAOS_MULTI_BIND {
|
||||
int buffer_type;
|
||||
void * buffer;
|
||||
uintptr_t buffer_length; // not in use
|
||||
uintptr_t * length;
|
||||
int * is_null;
|
||||
int is_unsigned; // not in use
|
||||
int * error; // not in use
|
||||
} TAOS_BIND;
|
||||
void *buffer;
|
||||
uintptr_t buffer_length;
|
||||
uint32_t *length;
|
||||
char *is_null;
|
||||
int num; // the number of columns
|
||||
} TAOS_MULTI_BIND;
|
||||
```
|
||||
|
||||
- `int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name)`
|
||||
|
@ -418,7 +431,7 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
|
|||
(2.1.1.0 版本新增,仅支持用于替换 INSERT 语句中的参数值)
|
||||
当 SQL 语句中的表名使用了 `?` 占位时,可以使用此函数绑定一个具体的表名。
|
||||
|
||||
- `int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags)`
|
||||
- `int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_MULTI_BIND* tags)`
|
||||
|
||||
(2.1.2.0 版本新增,仅支持用于替换 INSERT 语句中的参数值)
|
||||
当 SQL 语句中的表名和 TAGS 都使用了 `?` 占位时,可以使用此函数绑定具体的表名和具体的 TAGS 取值。最典型的使用场景是使用了自动建表功能的 INSERT 语句(目前版本不支持指定具体的 TAGS 列)。TAGS 参数中的列数量需要与 SQL 语句中要求的 TAGS 数量完全一致。
|
||||
|
@ -428,17 +441,6 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
|
|||
(2.1.1.0 版本新增,仅支持用于替换 INSERT 语句中的参数值)
|
||||
以多列的方式传递待绑定的数据,需要保证这里传递的数据列的顺序、列的数量与 SQL 语句中的 VALUES 参数完全一致。TAOS_MULTI_BIND 的具体定义如下:
|
||||
|
||||
```c
|
||||
typedef struct TAOS_MULTI_BIND {
|
||||
int buffer_type;
|
||||
void * buffer;
|
||||
uintptr_t buffer_length;
|
||||
uintptr_t * length;
|
||||
char * is_null;
|
||||
int num; // the number of columns
|
||||
} TAOS_MULTI_BIND;
|
||||
```
|
||||
|
||||
- `int taos_stmt_add_batch(TAOS_STMT *stmt)`
|
||||
|
||||
将当前绑定的参数加入批处理中,调用此函数后,可以再次调用 `taos_stmt_bind_param()` 或 `taos_stmt_bind_param_batch()` 绑定新的参数。需要注意,此函数仅支持 INSERT/IMPORT 语句,如果是 SELECT 等其他 SQL 语句,将返回错误。
|
||||
|
@ -447,6 +449,14 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
|
|||
|
||||
执行准备好的语句。目前,一条语句只能执行一次。
|
||||
|
||||
- `int taos_stmt_affected_rows(TAOS_STMT *stmt)`
|
||||
|
||||
获取执行多次绑定语句影响的行数。
|
||||
|
||||
- `int taos_stmt_affected_rows_once(TAOS_STMT *stmt)`
|
||||
|
||||
获取执行一次绑定语句影响的行数。
|
||||
|
||||
- `TAOS_RES* taos_stmt_use_result(TAOS_STMT *stmt)`
|
||||
|
||||
获取语句的结果集。结果集的使用方式与非参数化调用时一致,使用完成后,应对此结果集调用 `taos_free_result()` 以释放资源。
|
||||
|
|
|
@ -29,6 +29,10 @@ import CSAsyncQuery from "../07-develop/04-query-data/_cs_async.mdx"
|
|||
|
||||
支持的平台和 TDengine 客户端驱动支持的平台一致。
|
||||
|
||||
:::note
|
||||
注意 TDengine 不再支持 32 位 Windows 平台。
|
||||
:::
|
||||
|
||||
## 版本支持
|
||||
|
||||
请参考[版本支持列表](../#版本支持)
|
||||
|
|
|
@ -7,7 +7,7 @@ description: 查询数据的详细语法
|
|||
## 查询语法
|
||||
|
||||
```sql
|
||||
SELECT {DATABASE() | CLIENT_VERSION() | SERVER_VERSION() | SERVER_STATUS() | NOW() | TODAY() | TIMEZONE()}
|
||||
SELECT {DATABASE() | CLIENT_VERSION() | SERVER_VERSION() | SERVER_STATUS() | NOW() | TODAY() | TIMEZONE() | CURRENT_USER() | USER() }
|
||||
|
||||
SELECT [hints] [DISTINCT] [TAGS] select_list
|
||||
from_clause
|
||||
|
@ -205,7 +205,7 @@ SELECT table_name, tag_name, tag_type, tag_value FROM information_schema.ins_tag
|
|||
SELECT COUNT(*) FROM (SELECT DISTINCT TBNAME FROM meters);
|
||||
```
|
||||
|
||||
以上两个查询均只支持在 WHERE 条件子句中添加针对标签(TAGS)的过滤条件。例如:
|
||||
以上两个查询均只支持在 WHERE 条件子句中添加针对标签(TAGS)的过滤条件。
|
||||
|
||||
**\_QSTART/\_QEND**
|
||||
|
||||
|
@ -247,8 +247,7 @@ TDengine 支持基于时间戳主键的 INNER JOIN,规则如下:
|
|||
3. 对于超级表,ON 条件在时间戳主键的等值条件之外,还要求有可以一一对应的标签列等值条件,不支持 OR 条件。
|
||||
4. 参与 JOIN 计算的表只能是同一种类型,即只能都是超级表,或都是子表,或都是普通表。
|
||||
5. JOIN 两侧均支持子查询。
|
||||
6. 参与 JOIN 的表个数上限为 10 个。
|
||||
7. 不支持与 FILL 子句混合使用。
|
||||
6. 不支持与 FILL 子句混合使用。
|
||||
|
||||
## GROUP BY
|
||||
|
||||
|
@ -339,6 +338,12 @@ SELECT TODAY();
|
|||
SELECT TIMEZONE();
|
||||
```
|
||||
|
||||
### 获取当前用户
|
||||
|
||||
```sql
|
||||
SELECT CURRENT_USER();
|
||||
```
|
||||
|
||||
## 正则表达式过滤
|
||||
|
||||
### 语法
|
||||
|
@ -392,7 +397,7 @@ SELECT AVG(CASE WHEN voltage < 200 or voltage > 250 THEN 220 ELSE voltage END) F
|
|||
|
||||
## JOIN 子句
|
||||
|
||||
TDengine 支持基于时间戳主键的内连接,即 JOIN 条件必须包含时间戳主键。只要满足基于时间戳主键这个要求,普通表、子表、超级表和子查询之间可以随意的进行内连接,且对表个数没有限制。
|
||||
TDengine 支持基于时间戳主键的内连接,即 JOIN 条件必须包含时间戳主键。只要满足基于时间戳主键这个要求,普通表、子表、超级表和子查询之间可以随意的进行内连接,且对表个数没有限制,其它连接条件与主键间必须是 AND 操作。
|
||||
|
||||
普通表与普通表之间的 JOIN 操作:
|
||||
|
||||
|
|
|
@ -1266,6 +1266,14 @@ SELECT SERVER_STATUS();
|
|||
|
||||
**说明**:检测服务端是否所有 dnode 都在线,如果是则返回成功,否则返回无法建立连接的错误。
|
||||
|
||||
### CURRENT_USER
|
||||
|
||||
```sql
|
||||
SELECT CURRENT_USER();
|
||||
```
|
||||
|
||||
**说明**:获取当前用户。
|
||||
|
||||
|
||||
## Geometry 函数
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ select max(current) from meters partition by location interval(10m)
|
|||
|
||||
## 窗口切分查询
|
||||
|
||||
TDengine 支持按时间窗口切分方式进行聚合结果查询,比如温度传感器每秒采集一次数据,但需查询每隔 10 分钟的温度平均值。这种场景下可以使用窗口子句来获得需要的查询结果。窗口子句用于针对查询的数据集合按照窗口切分成为查询子集并进行聚合,窗口包含时间窗口(time window)、状态窗口(status window)、会话窗口(session window)、条件窗口(event window)四种窗口。其中时间窗口又可划分为滑动时间窗口和翻转时间窗口。
|
||||
TDengine 支持按时间窗口切分方式进行聚合结果查询,比如温度传感器每秒采集一次数据,但需查询每隔 10 分钟的温度平均值。这种场景下可以使用窗口子句来获得需要的查询结果。窗口子句用于针对查询的数据集合按照窗口切分成为查询子集并进行聚合,窗口包含时间窗口(time window)、状态窗口(status window)、会话窗口(session window)、事件窗口(event window)四种窗口。其中时间窗口又可划分为滑动时间窗口和翻转时间窗口。
|
||||
|
||||
窗口子句语法如下:
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ description: TDengine 保留关键字的详细列表
|
|||
|
||||
- MATCH
|
||||
- MAX_DELAY
|
||||
- MAX_SPEED
|
||||
- BWLIMIT
|
||||
- MAXROWS
|
||||
- MERGE
|
||||
- META
|
||||
|
|
|
@ -22,6 +22,14 @@ SHOW CLUSTER;
|
|||
|
||||
显示当前集群的信息
|
||||
|
||||
## SHOW CLUSTER ALIVE
|
||||
|
||||
```sql
|
||||
SHOW CLUSTER ALIVE;
|
||||
```
|
||||
|
||||
查询当前集群的状态是否可用,返回值: 0:不可用 1:完全可用 2:部分可用(集群中部分节点下线,但其它节点仍可以正常使用)
|
||||
|
||||
## SHOW CONNECTIONS
|
||||
|
||||
```sql
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
---
|
||||
sidebar_label: 权限管理
|
||||
title: 权限管理
|
||||
description: 企业版中才具有的权限管理功能
|
||||
---
|
||||
|
||||
本节讲述如何在 TDengine 中进行权限管理的相关操作。权限管理是 TDengine 企业版的特有功能,本节只列举了一些基本的权限管理功能作为示例,更丰富的权限管理请联系 TDengine 销售或市场团队。
|
||||
|
||||
## 创建用户
|
||||
|
||||
```sql
|
||||
CREATE USER use_name PASS 'password' [SYSINFO {1|0}];
|
||||
```
|
||||
|
||||
创建用户。
|
||||
|
||||
use_name 最长为 23 字节。
|
||||
|
||||
password 最长为 31 字节,合法字符包括"a-zA-Z0-9!?$%^&*()_–+={[}]:;@~#|<,>.?/",不可以出现单双引号、撇号、反斜杠和空格,且不可以为空。
|
||||
|
||||
SYSINFO 表示用户是否可以查看系统信息。1 表示可以查看,0 表示不可以查看。系统信息包括服务端配置信息、服务端各种节点信息(如 DNODE、QNODE等)、存储相关的信息等。默认为可以查看系统信息。
|
||||
|
||||
例如,创建密码为123456且可以查看系统信息的用户test如下:
|
||||
|
||||
```sql
|
||||
taos> create user test pass '123456' sysinfo 1;
|
||||
Query OK, 0 of 0 rows affected (0.001254s)
|
||||
```
|
||||
|
||||
## 查看用户
|
||||
|
||||
```sql
|
||||
SHOW USERS;
|
||||
```
|
||||
|
||||
查看用户信息。
|
||||
|
||||
```sql
|
||||
taos> show users;
|
||||
name | super | enable | sysinfo | create_time |
|
||||
================================================================================
|
||||
test | 0 | 1 | 1 | 2022-08-29 15:10:27.315 |
|
||||
root | 1 | 1 | 1 | 2022-08-29 15:03:34.710 |
|
||||
Query OK, 2 rows in database (0.001657s)
|
||||
```
|
||||
|
||||
也可以通过查询INFORMATION_SCHEMA.INS_USERS系统表来查看用户信息,例如:
|
||||
|
||||
```sql
|
||||
taos> select * from information_schema.ins_users;
|
||||
name | super | enable | sysinfo | create_time |
|
||||
================================================================================
|
||||
test | 0 | 1 | 1 | 2022-08-29 15:10:27.315 |
|
||||
root | 1 | 1 | 1 | 2022-08-29 15:03:34.710 |
|
||||
Query OK, 2 rows in database (0.001953s)
|
||||
```
|
||||
|
||||
## 删除用户
|
||||
|
||||
```sql
|
||||
DROP USER user_name;
|
||||
```
|
||||
|
||||
## 修改用户信息
|
||||
|
||||
```sql
|
||||
ALTER USER user_name alter_user_clause
|
||||
|
||||
alter_user_clause: {
|
||||
PASS 'literal'
|
||||
| ENABLE value
|
||||
| SYSINFO value
|
||||
}
|
||||
```
|
||||
|
||||
- PASS:修改用户密码。
|
||||
- ENABLE:修改用户是否启用。1 表示启用此用户,0 表示禁用此用户。
|
||||
- SYSINFO:修改用户是否可查看系统信息。1 表示可以查看系统信息,0 表示不可以查看系统信息。
|
||||
|
||||
例如,禁用 test 用户:
|
||||
|
||||
```sql
|
||||
taos> alter user test enable 0;
|
||||
Query OK, 0 of 0 rows affected (0.001160s)
|
||||
```
|
||||
|
||||
## 授权
|
||||
|
||||
```sql
|
||||
GRANT privileges ON priv_level TO user_name
|
||||
|
||||
privileges : {
|
||||
ALL
|
||||
| priv_type [, priv_type] ...
|
||||
}
|
||||
|
||||
priv_type : {
|
||||
READ
|
||||
| WRITE
|
||||
}
|
||||
|
||||
priv_level : {
|
||||
dbname.*
|
||||
| *.*
|
||||
}
|
||||
```
|
||||
|
||||
对用户授权。授权功能只包含在企业版中。
|
||||
|
||||
授权级别支持到DATABASE,权限有READ和WRITE两种。
|
||||
|
||||
TDengine 有超级用户和普通用户两类用户。超级用户缺省创建为root,拥有所有权限。使用超级用户创建出来的用户为普通用户。在未授权的情况下,普通用户可以创建DATABASE,并拥有自己创建的DATABASE的所有权限,包括删除数据库、修改数据库、查询时序数据和写入时序数据。超级用户可以给普通用户授予其他DATABASE的读写权限,使其可以在此DATABASE上读写数据,但不能对其进行删除和修改数据库的操作。
|
||||
|
||||
对于非DATABASE的对象,如USER、DNODE、UDF、QNODE等,普通用户只有读权限(一般为SHOW命令),不能创建和修改。
|
||||
|
||||
## 撤销授权
|
||||
|
||||
```sql
|
||||
REVOKE privileges ON priv_level FROM user_name
|
||||
|
||||
privileges : {
|
||||
ALL
|
||||
| priv_type [, priv_type] ...
|
||||
}
|
||||
|
||||
priv_type : {
|
||||
READ
|
||||
| WRITE
|
||||
}
|
||||
|
||||
priv_level : {
|
||||
dbname.*
|
||||
| *.*
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
收回对用户的授权。授权功能只包含在企业版中。
|
|
@ -20,6 +20,9 @@ index_option:
|
|||
functions:
|
||||
function [, function] ...
|
||||
```
|
||||
### tag 索引
|
||||
|
||||
[tag 索引](../tag-index)
|
||||
|
||||
### SMA 索引
|
||||
|
|
@ -17,7 +17,7 @@ conn_id 可以通过 `SHOW CONNECTIONS` 获取。
|
|||
## 终止查询
|
||||
|
||||
```sql
|
||||
KILL QUERY kill_id;
|
||||
KILL QUERY 'kill_id';
|
||||
```
|
||||
|
||||
kill_id 可以通过 `SHOW QUERIES` 获取。
|
||||
|
|
|
@ -13,7 +13,7 @@ taosBenchmark (曾用名 taosdemo ) 是一个用于测试 TDengine 产品性能
|
|||
|
||||
taosBenchmark 有两种安装方式:
|
||||
|
||||
- 安装 TDengine 官方安装包的同时会自动安装 taosBenchmark, 详情请参考[ TDengine 安装](/operation/pkg-install)。
|
||||
- 安装 TDengine 官方安装包的同时会自动安装 taosBenchmark, 详情请参考[ TDengine 安装](../../operation/pkg-install)。
|
||||
|
||||
- 单独编译 taos-tools 并安装, 详情请参考 [taos-tools](https://github.com/taosdata/taos-tools) 仓库。
|
||||
|
||||
|
|
|
@ -105,6 +105,8 @@ Usage: taosdump [OPTION...] dbname [tbname ...]
|
|||
-L, --loose-mode Using loose mode if the table name and column name
|
||||
use letter and number only. Default is NOT.
|
||||
-n, --no-escape No escape char '`'. Default is using it.
|
||||
-Q, --dot-replace Repalce dot character with underline character in
|
||||
the table name.
|
||||
-T, --thread-num=THREAD_NUM Number of thread for dump in file. Default is
|
||||
8.
|
||||
-C, --cloud=CLOUD_DSN specify a DSN to access TDengine cloud service
|
||||
|
|
|
@ -16,7 +16,7 @@ taosKeeper 是 TDengine 3.0 版本监控指标的导出工具,通过简单的
|
|||
taosKeeper 有两种安装方式:
|
||||
taosKeeper 安装方式:
|
||||
|
||||
- 安装 TDengine 官方安装包的同时会自动安装 taosKeeper, 详情请参考[ TDengine 安装](/operation/pkg-install)。
|
||||
- 安装 TDengine 官方安装包的同时会自动安装 taosKeeper, 详情请参考[ TDengine 安装](../../operation/pkg-install)。
|
||||
|
||||
- 单独编译 taosKeeper 并安装,详情请参考 [taosKeeper](https://github.com/taosdata/taoskeeper) 仓库。
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
title: 集群运维
|
||||
description: TDengine 提供了多种集群运维手段以使集群运行更健康更高效
|
||||
---
|
||||
|
||||
为了使集群运行更健康更高效,TDengine 企业版提供了一些运维手段来帮助系统管理员更好地运维集群。
|
||||
|
||||
## 数据重整
|
||||
|
||||
TDengine 面向多种写入场景,在有些写入场景下,TDengine 的存储会导致数据存储的放大或数据文件的空洞等。这一方面影响数据的存储效率,另一方面也会影响查询效率。为了解决上述问题,TDengine 企业版提供了对数据的重整功能,即 DATA COMPACT 功能,将存储的数据文件重新整理,删除文件空洞和无效数据,提高数据的组织度,从而提高存储和查询的效率。
|
||||
|
||||
**语法**
|
||||
|
||||
```sql
|
||||
COMPACT DATABASE db_name [start with 'XXXX'] [end with 'YYYY'];
|
||||
```
|
||||
|
||||
**效果**
|
||||
|
||||
- 扫描并压缩指定的 DB 中所有 VGROUP 中 VNODE 的所有数据文件
|
||||
- COMPCAT 会删除被删除数据以及被删除的表的数据
|
||||
- COMPACT 会合并多个 STT 文件
|
||||
- 可通过 start with 关键字指定 COMPACT 数据的起始时间
|
||||
- 可通过 end with 关键字指定 COMPACT 数据的终止时间
|
||||
|
||||
**补充说明**
|
||||
|
||||
- COMPACT 为异步,执行 COMPACT 命令后不会等 COMPACT 结束就会返回。如果上一个 COMPACT 没有完成则再发起一个 COMPACT 任务,则会等上一个任务完成后再返回。
|
||||
- COMPACT 可能阻塞写入,但不阻塞查询
|
||||
- COMPACT 的进度不可观测
|
||||
|
||||
## 集群负载再平衡
|
||||
|
||||
当多副本集群中的一个或多个节点因为升级或其它原因而重启后,有可能出现集群中各个 dnode 负载不均衡的现象,极端情况下会出现所有 vgroup 的 leader 都位于同一个 dnode 的情况。为了解决这个问题,可以使用下面的命令
|
||||
|
||||
```sql
|
||||
balance vgroup leader;
|
||||
```
|
||||
|
||||
**功能**
|
||||
|
||||
让所有的 vgroup 的 leade r在各自的replica节点上均匀分布。这个命令会让 vgroup 强制重新选举,通过重新选举,在选举的过程中,变换 vgroup 的leader,通过这个方式,最终让leader均匀分布。
|
||||
|
||||
**注意**
|
||||
|
||||
Raft选举本身带有随机性,所以通过选举的重新分布产生的均匀分布也是带有一定的概率,不会完全的均匀。**该命令的副作用是影响查询和写入**,在vgroup重新选举时,从开始选举到选举出新的 leader 这段时间,这 个vgroup 无法写入和查询。选举过程一般在秒级完成。所有的vgroup会依次逐个重新选举。
|
||||
|
||||
## 恢复数据节点
|
||||
|
||||
在多节点三副本的集群环境中,如果某个 dnode 的磁盘损坏,该 dnode 会自动退出,但集群中其它的 dnode 仍然能够继续提供写入和查询服务。
|
||||
|
||||
在更换了损坏的磁盘后,如果想要让曾经主动退出的 dnode 重新加入集群提供服务,可以通过 `restore dnode` 命令来恢复该数据节点上的部分或全部逻辑节点,该功能依赖多副本中的其它副本进行数据复制,所以只在集群中 dnode 数量大于等于 3 且副本数为 3 的情况下能够工作。
|
||||
|
||||
|
||||
```sql
|
||||
restore dnode <dnode_id>;# 恢复dnode上的mnode,所有vnode和qnode
|
||||
restore mnode on dnode <dnode_id>;# 恢复dnode上的mnode
|
||||
restore vnode on dnode <dnode_id> ;# 恢复dnode上的所有vnode
|
||||
restore qnode on dnode <dnode_id>;# 恢复dnode上的qnode
|
||||
```
|
||||
|
||||
**限制**
|
||||
- 该功能是基于已有的复制功能的恢复,不是灾难恢复或者备份恢复,所以对于要恢复的 mnode 和 vnode来说,使用该命令的前提是还存在该 mnode 或 vnode 的其它两个副本仍然能够正常工作。
|
||||
- 该命令不能修复数据目录中的个别文件的损坏或者丢失。例如,如果某个 mnode 或者 vnode 中的个别文件或数据损坏,无法单独恢复损坏的某个文件或者某块数据。此时,可以选择将该 mnode/vnode 的数据全部清空再进行恢复。
|
||||
|
||||
|
||||
## 虚拟组分裂 (Scale Out)
|
||||
|
||||
当一个 vgroup 因为子表数过多而导致 CPU 或 Disk 资源使用量负载过高时,增加 dnode 节点后,可通过 `split vgroup` 命令把该 vgroup 分裂为两个虚拟组。分裂完成后,新产生的两个 vgroup 承担原来由一个 vgroup 提供的读写服务。这也是 TDengine 为企业版用户提供的 scale out 集群的能力。
|
||||
|
||||
```sql
|
||||
split vgroup <vgroup_id>
|
||||
```
|
||||
|
||||
**注意**
|
||||
- 单副本库虚拟组,在分裂完成后,历史时序数据总磁盘空间使用量,可能会翻倍。所以,在执行该操作之前,通过增加 dnode 节点方式,确保集群中有足够的 CPU 和磁盘资源,避免资源不足现象发生。
|
||||
- 该命令为 DB 级事务;执行过程,当前DB的其它管理事务将会被拒绝。集群中,其它DB不受影响。
|
||||
- 分裂任务执行过程中,可持续提供读写服务;期间,可能存在可感知的短暂的读写业务中断。
|
||||
- 在分裂过程中,不支持流和订阅。分裂结束后,历史 WAL 会清空。
|
||||
- 分裂过程中,可支持节点宕机重启容错;但不支持节点磁盘故障容错。
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
title: 多级存储
|
||||
---
|
||||
|
||||
## 多级存储
|
||||
|
||||
说明:多级存储功能仅企业版支持。
|
||||
|
||||
在默认配置下,TDengine 会将所有数据保存在 /var/lib/taos 目录下,而且每个 vnode 的数据文件保存在该目录下的不同目录。为扩大存储空间,尽量减少文件读取的瓶颈,提高数据吞吐率 TDengine 可通过配置系统参数 dataDir 让多个挂载的硬盘被系统同时使用。
|
||||
|
||||
除此之外,TDengine 也提供了数据分级存储的功能,将不同时间段的数据存储在挂载的不同介质上的目录里,从而实现不同“热度”的数据存储在不同的存储介质上,充分利用存储,节约成本。比如,最新采集的数据需要经常访问,对硬盘的读取性能要求高,那么用户可以配置将这些数据存储在 SSD 盘上。超过一定期限的数据,查询需求量没有那么高,那么可以存储在相对便宜的 HDD 盘上。
|
||||
|
||||
多级存储支持 3 级,每级最多可配置 16 个挂载点。
|
||||
|
||||
TDengine 多级存储配置方式如下(在配置文件/etc/taos/taos.cfg 中):
|
||||
|
||||
```
|
||||
dataDir [path] <level> <primary>
|
||||
```
|
||||
|
||||
- path: 挂载点的文件夹路径
|
||||
- level: 介质存储等级,取值为 0,1,2。
|
||||
0 级存储最新的数据,1 级存储次新的数据,2 级存储最老的数据,省略默认为 0。
|
||||
各级存储之间的数据流向:0 级存储 -> 1 级存储 -> 2 级存储。
|
||||
同一存储等级可挂载多个硬盘,同一存储等级上的数据文件分布在该存储等级的所有硬盘上。
|
||||
需要说明的是,数据在不同级别的存储介质上的移动,是由系统自动完成的,用户无需干预。
|
||||
- primary: 是否为主挂载点,0(否)或 1(是),省略默认为 1。
|
||||
|
||||
在配置中,只允许一个主挂载点的存在(level=0,primary=1),例如采用如下的配置方式:
|
||||
|
||||
```
|
||||
dataDir /mnt/data1 0 1
|
||||
dataDir /mnt/data2 0 0
|
||||
dataDir /mnt/data3 1 0
|
||||
dataDir /mnt/data4 1 0
|
||||
dataDir /mnt/data5 2 0
|
||||
dataDir /mnt/data6 2 0
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
1. 多级存储不允许跨级配置,合法的配置方案有:仅 0 级,仅 0 级+ 1 级,以及 0 级+ 1 级+ 2 级。而不允许只配置 level=0 和 level=2,而不配置 level=1。
|
||||
2. 禁止手动移除使用中的挂载盘,挂载盘目前不支持非本地的网络盘。
|
||||
3. 多级存储目前不支持删除已经挂载的硬盘的功能。
|
||||
|
||||
:::
|
||||
|
||||
## 0 级负载均衡
|
||||
|
||||
在多级存储中,有且只有一个主挂载点,主挂载点承担了系统中最重要的元数据在座,同时各个 vnode 的主目录均存在于当前 dnode 主挂载点上,从而导致该 dnode 的写入性能受限于单个磁盘的 IO 吞吐能力。
|
||||
|
||||
从 TDengine 3.1.0.0 开始,如果一个 dnode 配置了多个 0 级挂载点,我们将该 dnode 上所有 vnode 的主目录均衡分布在所有的 0 级挂载点上,由这些 0 级挂载点共同承担写入负荷。在网络 I/O 及其它处理资源不成为瓶颈的情况下,通过优化集群配置,测试结果证明整个系统的写入能力和 0 级挂载点的数量呈现线性关系,即随着 0 级挂载点数量的增加,整个系统的写入能力也成倍增加。
|
||||
|
||||
## 同级挂载点选择策略
|
||||
|
||||
一般情况下,当 TDengine 要从同级挂载点中选择一个用于生成新的数据文件时,采用 round robin 策略进行选择。但现实中有可能每个磁盘的容量不相同,或者容量相同但写入的数据量不相同,这就导致会出现每个磁盘上的可用空间不均衡,在实际进行选择时有可能会选择到一个剩余空间已经很小的磁盘。为了解决这个问题,从 3.1.1.0 开始引入了一个新的配置 `minDiskFreeSize`,当某块磁盘上的可用空间小于等于这个阈值时,该磁盘将不再被选择用于生成新的数据文件。该配置项的单位为字节,其值应该大于 2GB,即会跳过可用空间小于 2GB 的挂载点。
|
|
@ -23,7 +23,7 @@ TDengine Source Connector 用于把数据实时地从 TDengine 读出来发送
|
|||
1. Linux 操作系统
|
||||
2. 已安装 Java 8 和 Maven
|
||||
3. 已安装 Git、curl、vi
|
||||
4. 已安装并启动 TDengine。如果还没有可参考[安装和卸载](/operation/pkg-install)
|
||||
4. 已安装并启动 TDengine。如果还没有可参考[安装和卸载](../../operation/pkg-install)
|
||||
|
||||
## 安装 Kafka
|
||||
|
||||
|
|
|
@ -0,0 +1,437 @@
|
|||
---
|
||||
sidebar_label: Seeq
|
||||
title: Seeq
|
||||
description: 如何使用 Seeq 和 TDengine 进行时序数据分析
|
||||
---
|
||||
|
||||
# 如何使用 Seeq 和 TDengine 进行时序数据分析
|
||||
|
||||
## 方案介绍
|
||||
|
||||
Seeq 是制造业和工业互联网(IIOT)高级分析软件。Seeq 支持在工艺制造组织中使用机器学习创新的新功能。这些功能使组织能够将自己或第三方机器学习算法部署到前线流程工程师和主题专家使用的高级分析应用程序,从而使单个数据科学家的努力扩展到许多前线员工。
|
||||
|
||||
通过 TDengine Java connector, Seeq 可以轻松支持查询 TDengine 提供的时序数据,并提供数据展现、分析、预测等功能。
|
||||
|
||||
### Seeq 安装方法
|
||||
|
||||
从 (Seeq 官网)[https://www.seeq.com/customer-download]下载相关软件,例如 Seeq Server 和 Seeq Data Lab 等。
|
||||
|
||||
### Seeq Server 安装和启动
|
||||
|
||||
```
|
||||
tar xvzf seeq-server-xxx.tar.gz
|
||||
cd seeq-server-installer
|
||||
sudo ./install
|
||||
|
||||
sudo seeq service enable
|
||||
sudo seeq start
|
||||
```
|
||||
|
||||
### Seeq Data Lab Server 安装和启动
|
||||
|
||||
Seeq Data Lab 需要安装在和 Seeq Server 不同的服务器上,并通过配置和 Seeq Server 互联。详细安装配置指令参见(Seeq 官方文档)[https://support.seeq.com/space/KB/1034059842]。
|
||||
|
||||
```
|
||||
tar xvf seeq-data-lab-<version>-64bit-linux.tar.gz
|
||||
sudo seeq-data-lab-installer/install -f /opt/seeq/seeq-data-lab -g /var/opt/seeq -u seeq
|
||||
sudo seeq config set Network/DataLab/Hostname localhost
|
||||
sudo seeq config set Network/DataLab/Port 34231 # the port of the Data Lab server (usually 34231)
|
||||
sudo seeq config set Network/Hostname <value> # the host IP or URL of the main Seeq Server
|
||||
|
||||
# If the main Seeq server is configured to listen over HTTPS
|
||||
sudo seeq config set Network/Webserver/SecurePort 443 # the secure port of the main Seeq Server (usually 443)
|
||||
|
||||
# If the main Seeq server is NOT configured to listen over HTTPS
|
||||
sudo seeq config set Network/Webserver/Port <value>
|
||||
|
||||
#On the main Seeq server, open a Seeq Command Prompt and set the hostname of the Data Lab server:
|
||||
sudo seeq config set Network/DataLab/Hostname <value> # the host IP (not URL) of the Data Lab server
|
||||
sudo seeq config set Network/DataLab/Port 34231 # the port of the Data Lab server (usually 34231
|
||||
```
|
||||
|
||||
## TDengine 本地实例安装方法
|
||||
|
||||
请参考(官网文档)[https://docs.taosdata.com/get-started/package/]。
|
||||
|
||||
## TDengine Cloud 访问方法
|
||||
如果使用 Seeq 连接 TDengine Cloud,请在 https://cloud.taosdata.com 申请帐号并登录查看如何访问 TDengine Cloud。
|
||||
|
||||
## 如何配置 Seeq 访问 TDengine
|
||||
|
||||
1. 查看 data 存储位置
|
||||
|
||||
```
|
||||
sudo seeq config get Folders/Data
|
||||
```
|
||||
|
||||
2. 从 maven.org 下载 TDengine Java connector 包,目前最新版本为(3.2.4)[https://repo1.maven.org/maven2/com/taosdata/jdbc/taos-jdbcdriver/3.2.4/taos-jdbcdriver-3.2.4-dist.jar],并拷贝至 data 存储位置的 plugins\lib 中。
|
||||
|
||||
3. 重新启动 seeq server
|
||||
|
||||
```
|
||||
sudo seeq restart
|
||||
```
|
||||
|
||||
4. 输入 License
|
||||
|
||||
使用浏览器访问 ip:34216 并按照说明输入 license。
|
||||
|
||||
## 使用 Seeq 分析 TDengine 时序数据
|
||||
|
||||
本章节演示如何使用 Seeq 软件配合 TDengine 进行时序数据分析。
|
||||
|
||||
### 场景介绍
|
||||
|
||||
示例场景为一个电力系统,用户每天从电站仪表收集用电量数据,并将其存储在 TDengine 集群中。现在用户想要预测电力消耗将会如何发展,并购买更多设备来支持它。用户电力消耗随着每月订单变化而不同,另外考虑到季节变化,电力消耗量会有所不同。这个城市位于北半球,所以在夏天会使用更多的电力。我们模拟数据来反映这些假定。
|
||||
|
||||
### 数据 Schema
|
||||
|
||||
```
|
||||
CREATE STABLE meters (ts TIMESTAMP, num INT, temperature FLOAT, goods INT) TAGS (device NCHAR(20));
|
||||
CREATE TABLE goods (ts1 TIMESTAMP, ts2 TIMESTAMP, goods FLOAT);
|
||||
```
|
||||
|
||||
!(Seeq demo schema)[./seeq/seeq-demo-schema.webp]
|
||||
|
||||
### 构造数据方法
|
||||
|
||||
```
|
||||
python mockdata.py
|
||||
taos -s "insert into power.goods select _wstart, _wstart + 10d, avg(goods) from power.meters interval(10d);"
|
||||
```
|
||||
源代码托管在(github 仓库)[https://github.com/sangshuduo/td-forecasting]。
|
||||
|
||||
### 使用 Seeq 进行数据分析
|
||||
|
||||
#### 配置数据源(Data Source)
|
||||
|
||||
使用 Seeq 管理员角色的帐号登录,并新建数据源。
|
||||
|
||||
- Power
|
||||
|
||||
```
|
||||
{
|
||||
"QueryDefinitions": [
|
||||
{
|
||||
"Name": "PowerNum",
|
||||
"Type": "SIGNAL",
|
||||
"Sql": "SELECT ts, num FROM meters",
|
||||
"Enabled": true,
|
||||
"TestMode": false,
|
||||
"TestQueriesDuringSync": true,
|
||||
"InProgressCapsulesEnabled": false,
|
||||
"Variables": null,
|
||||
"Properties": [
|
||||
{
|
||||
"Name": "Name",
|
||||
"Value": "Num",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Interpolation Method",
|
||||
"Value": "linear",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Maximum Interpolation",
|
||||
"Value": "2day",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
}
|
||||
],
|
||||
"CapsuleProperties": null
|
||||
}
|
||||
],
|
||||
"Type": "GENERIC",
|
||||
"Hostname": null,
|
||||
"Port": 0,
|
||||
"DatabaseName": null,
|
||||
"Username": "root",
|
||||
"Password": "taosdata",
|
||||
"InitialSql": null,
|
||||
"TimeZone": null,
|
||||
"PrintRows": false,
|
||||
"UseWindowsAuth": false,
|
||||
"SqlFetchBatchSize": 100000,
|
||||
"UseSSL": false,
|
||||
"JdbcProperties": null,
|
||||
"GenericDatabaseConfig": {
|
||||
"DatabaseJdbcUrl": "jdbc:TAOS-RS://127.0.0.1:6041/power?user=root&password=taosdata",
|
||||
"SqlDriverClassName": "com.taosdata.jdbc.rs.RestfulDriver",
|
||||
"ResolutionInNanoseconds": 1000,
|
||||
"ZonedColumnTypes": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Goods
|
||||
|
||||
```
|
||||
{
|
||||
"QueryDefinitions": [
|
||||
{
|
||||
"Name": "PowerGoods",
|
||||
"Type": "CONDITION",
|
||||
"Sql": "SELECT ts1, ts2, goods FROM power.goods",
|
||||
"Enabled": true,
|
||||
"TestMode": false,
|
||||
"TestQueriesDuringSync": true,
|
||||
"InProgressCapsulesEnabled": false,
|
||||
"Variables": null,
|
||||
"Properties": [
|
||||
{
|
||||
"Name": "Name",
|
||||
"Value": "Goods",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Maximum Duration",
|
||||
"Value": "10days",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
}
|
||||
],
|
||||
"CapsuleProperties": [
|
||||
{
|
||||
"Name": "goods",
|
||||
"Value": "${columnResult}",
|
||||
"Column": "goods",
|
||||
"Uom": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Type": "GENERIC",
|
||||
"Hostname": null,
|
||||
"Port": 0,
|
||||
"DatabaseName": null,
|
||||
"Username": "root",
|
||||
"Password": "taosdata",
|
||||
"InitialSql": null,
|
||||
"TimeZone": null,
|
||||
"PrintRows": false,
|
||||
"UseWindowsAuth": false,
|
||||
"SqlFetchBatchSize": 100000,
|
||||
"UseSSL": false,
|
||||
"JdbcProperties": null,
|
||||
"GenericDatabaseConfig": {
|
||||
"DatabaseJdbcUrl": "jdbc:TAOS-RS://127.0.0.1:6041/power?user=root&password=taosdata",
|
||||
"SqlDriverClassName": "com.taosdata.jdbc.rs.RestfulDriver",
|
||||
"ResolutionInNanoseconds": 1000,
|
||||
"ZonedColumnTypes": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Temperature
|
||||
|
||||
```
|
||||
{
|
||||
"QueryDefinitions": [
|
||||
{
|
||||
"Name": "PowerNum",
|
||||
"Type": "SIGNAL",
|
||||
"Sql": "SELECT ts, temperature FROM meters",
|
||||
"Enabled": true,
|
||||
"TestMode": false,
|
||||
"TestQueriesDuringSync": true,
|
||||
"InProgressCapsulesEnabled": false,
|
||||
"Variables": null,
|
||||
"Properties": [
|
||||
{
|
||||
"Name": "Name",
|
||||
"Value": "Temperature",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Interpolation Method",
|
||||
"Value": "linear",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Maximum Interpolation",
|
||||
"Value": "2day",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
}
|
||||
],
|
||||
"CapsuleProperties": null
|
||||
}
|
||||
],
|
||||
"Type": "GENERIC",
|
||||
"Hostname": null,
|
||||
"Port": 0,
|
||||
"DatabaseName": null,
|
||||
"Username": "root",
|
||||
"Password": "taosdata",
|
||||
"InitialSql": null,
|
||||
"TimeZone": null,
|
||||
"PrintRows": false,
|
||||
"UseWindowsAuth": false,
|
||||
"SqlFetchBatchSize": 100000,
|
||||
"UseSSL": false,
|
||||
"JdbcProperties": null,
|
||||
"GenericDatabaseConfig": {
|
||||
"DatabaseJdbcUrl": "jdbc:TAOS-RS://127.0.0.1:6041/power?user=root&password=taosdata",
|
||||
"SqlDriverClassName": "com.taosdata.jdbc.rs.RestfulDriver",
|
||||
"ResolutionInNanoseconds": 1000,
|
||||
"ZonedColumnTypes": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 使用 Seeq Workbench
|
||||
|
||||
登录 Seeq 服务页面并新建 Seeq Workbench,通过选择数据源搜索结果和根据需要选择不同的工具,可以进行数据展现或预测,详细使用方法参见(官方知识库)[https://support.seeq.com/space/KB/146440193/Seeq+Workbench]。
|
||||
|
||||
!(Seeq Workbench)[./seeq/seeq-demo-workbench.webp]
|
||||
|
||||
#### 用 Seeq Data Lab Server 进行进一步的数据分析
|
||||
|
||||
登录 Seeq 服务页面并新建 Seeq Data Lab,可以进一步使用 Python 编程或其他机器学习工具进行更复杂的数据挖掘功能。
|
||||
|
||||
```Python
|
||||
from seeq import spy
|
||||
spy.options.compatibility = 189
|
||||
import pandas as pd
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
import mlforecast
|
||||
import lightgbm as lgb
|
||||
from mlforecast.target_transforms import Differences
|
||||
from sklearn.linear_model import LinearRegression
|
||||
|
||||
ds = spy.search({'ID': "8C91A9C7-B6C2-4E18-AAAF-XXXXXXXXX"})
|
||||
print(ds)
|
||||
|
||||
sig = ds.loc[ds['Name'].isin(['Num'])]
|
||||
print(sig)
|
||||
|
||||
data = spy.pull(sig, start='2015-01-01', end='2022-12-31', grid=None)
|
||||
print("data.info()")
|
||||
data.info()
|
||||
print(data)
|
||||
#data.plot()
|
||||
|
||||
print("data[Num].info()")
|
||||
data['Num'].info()
|
||||
da = data['Num'].index.tolist()
|
||||
#print(da)
|
||||
|
||||
li = data['Num'].tolist()
|
||||
#print(li)
|
||||
|
||||
data2 = pd.DataFrame()
|
||||
data2['ds'] = da
|
||||
print('1st data2 ds info()')
|
||||
data2['ds'].info()
|
||||
|
||||
#data2['ds'] = pd.to_datetime(data2['ds']).to_timestamp()
|
||||
data2['ds'] = pd.to_datetime(data2['ds']).astype('int64')
|
||||
data2['y'] = li
|
||||
print('2nd data2 ds info()')
|
||||
data2['ds'].info()
|
||||
print(data2)
|
||||
|
||||
data2.insert(0, column = "unique_id", value="unique_id")
|
||||
|
||||
print("Forecasting ...")
|
||||
|
||||
forecast = mlforecast.MLForecast(
|
||||
models = lgb.LGBMRegressor(),
|
||||
freq = 1,
|
||||
lags=[365],
|
||||
target_transforms=[Differences([365])],
|
||||
)
|
||||
|
||||
forecast.fit(data2)
|
||||
predicts = forecast.predict(365)
|
||||
|
||||
pd.concat([data2, predicts]).set_index("ds").plot(title = "current data with forecast")
|
||||
plt.show()
|
||||
```
|
||||
|
||||
运行程序输出结果:
|
||||
|
||||
!(Seeq forecast result)[./seeq/seeq-forecast-result.webp]
|
||||
|
||||
### 配置 Seeq 数据源连接 TDengine Cloud
|
||||
|
||||
配置 Seeq 数据源连接 TDengine Cloud 和连接 TDengine 本地安装实例没有本质的不同,只要登录 TDengine Cloud 后选择“编程 - Java”并拷贝带 token 字符串的 JDBC 填写为 Seeq Data Source 的 DatabaseJdbcUrl 值。
|
||||
注意使用 TDengine Cloud 时 SQL 命令中需要指定数据库名称。
|
||||
|
||||
#### 用 TDengine Cloud 作为数据源的配置内容示例:
|
||||
|
||||
```
|
||||
{
|
||||
"QueryDefinitions": [
|
||||
{
|
||||
"Name": "CloudVoltage",
|
||||
"Type": "SIGNAL",
|
||||
"Sql": "SELECT ts, voltage FROM test.meters",
|
||||
"Enabled": true,
|
||||
"TestMode": false,
|
||||
"TestQueriesDuringSync": true,
|
||||
"InProgressCapsulesEnabled": false,
|
||||
"Variables": null,
|
||||
"Properties": [
|
||||
{
|
||||
"Name": "Name",
|
||||
"Value": "Voltage",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Interpolation Method",
|
||||
"Value": "linear",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
},
|
||||
{
|
||||
"Name": "Maximum Interpolation",
|
||||
"Value": "2day",
|
||||
"Sql": null,
|
||||
"Uom": "string"
|
||||
}
|
||||
],
|
||||
"CapsuleProperties": null
|
||||
}
|
||||
],
|
||||
"Type": "GENERIC",
|
||||
"Hostname": null,
|
||||
"Port": 0,
|
||||
"DatabaseName": null,
|
||||
"Username": "root",
|
||||
"Password": "taosdata",
|
||||
"InitialSql": null,
|
||||
"TimeZone": null,
|
||||
"PrintRows": false,
|
||||
"UseWindowsAuth": false,
|
||||
"SqlFetchBatchSize": 100000,
|
||||
"UseSSL": false,
|
||||
"JdbcProperties": null,
|
||||
"GenericDatabaseConfig": {
|
||||
"DatabaseJdbcUrl": "jdbc:TAOS-RS://gw.cloud.taosdata.com?useSSL=true&token=41ac9d61d641b6b334e8b76f45f5a8XXXXXXXXXX",
|
||||
"SqlDriverClassName": "com.taosdata.jdbc.rs.RestfulDriver",
|
||||
"ResolutionInNanoseconds": 1000,
|
||||
"ZonedColumnTypes": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### TDengine Cloud 作为数据源的 Seeq Workbench 界面示例
|
||||
|
||||
!(Seeq workbench with TDengine cloud)[./seeq/seeq-workbench-with-tdengine-cloud.webp]
|
||||
|
||||
## 方案总结
|
||||
|
||||
通过集成Seeq和TDengine,可以充分利用TDengine高效的存储和查询性能,同时也可以受益于Seeq提供给用户的强大数据可视化和分析功能。
|
||||
|
||||
这种集成使用户能够充分利用TDengine的高性能时序数据存储和检索,确保高效处理大量数据。同时,Seeq提供高级分析功能,如数据可视化、异常检测、相关性分析和预测建模,使用户能够获得有价值的洞察并基于数据进行决策。
|
||||
|
||||
综合来看,Seeq和TDengine共同为制造业、工业物联网和电力系统等各行各业的时序数据分析提供了综合解决方案。高效数据存储和先进的分析相结合,赋予用户充分发挥时序数据潜力的能力,推动运营改进,并支持预测和规划分析应用。
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
|
@ -133,6 +133,7 @@
|
|||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
|
|
@ -8,4 +8,4 @@ java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -data
|
|||
```
|
||||
|
||||
如果发生错误 Exception in thread "main" java.lang.UnsatisfiedLinkError: no taos in java.library.path
|
||||
请检查是否安装 TDengine 客户端安装包或编译 TDengine 安装。如果确定已经安装过还出现这个错误,可以在命令行 java 后加 -Djava.library.path=/usr/local/lib 来指定寻找共享库的路径。
|
||||
请检查是否安装 TDengine 客户端安装包或编译 TDengine 安装。如果确定已经安装过还出现这个错误,可以在命令行 java 后加 -Djava.library.path=/usr/lib 来指定寻找共享库的路径。
|
||||
|
|
|
@ -43,7 +43,7 @@ int main(int argc, char *argv[])
|
|||
taos_free_result(result);
|
||||
|
||||
// create table
|
||||
const char* sql = "create table m1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))";
|
||||
const char* sql = "create table m1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10), varbin varbinary(16))";
|
||||
result = taos_query(taos, sql);
|
||||
code = taos_errno(result);
|
||||
if (code != 0) {
|
||||
|
@ -68,6 +68,7 @@ int main(int argc, char *argv[])
|
|||
double f8;
|
||||
char bin[40];
|
||||
char blob[80];
|
||||
int8_t varbin[16];
|
||||
} v = {0};
|
||||
|
||||
int32_t boolLen = sizeof(int8_t);
|
||||
|
@ -80,7 +81,7 @@ int main(int argc, char *argv[])
|
|||
int32_t ncharLen = 30;
|
||||
|
||||
stmt = taos_stmt_init(taos);
|
||||
TAOS_MULTI_BIND params[10];
|
||||
TAOS_MULTI_BIND params[11];
|
||||
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
params[0].buffer_length = sizeof(v.ts);
|
||||
params[0].buffer = &v.ts;
|
||||
|
@ -152,9 +153,19 @@ int main(int argc, char *argv[])
|
|||
params[9].is_null = NULL;
|
||||
params[9].num = 1;
|
||||
|
||||
int8_t tmp[16] = {'a', 0, 1, 13, '1'};
|
||||
int32_t vbinLen = 5;
|
||||
memcpy(v.varbin, tmp, sizeof(v.varbin));
|
||||
params[10].buffer_type = TSDB_DATA_TYPE_VARBINARY;
|
||||
params[10].buffer_length = sizeof(v.varbin);
|
||||
params[10].buffer = v.varbin;
|
||||
params[10].length = &vbinLen;
|
||||
params[10].is_null = NULL;
|
||||
params[10].num = 1;
|
||||
|
||||
char is_null = 1;
|
||||
|
||||
sql = "insert into m1 values(?,?,?,?,?,?,?,?,?,?)";
|
||||
sql = "insert into m1 values(?,?,?,?,?,?,?,?,?,?,?)";
|
||||
code = taos_stmt_prepare(stmt, sql, 0);
|
||||
if (code != 0){
|
||||
printf("failed to execute taos_stmt_prepare. code:0x%x\n", code);
|
||||
|
@ -162,7 +173,7 @@ int main(int argc, char *argv[])
|
|||
v.ts = 1591060628000;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
v.ts += 1;
|
||||
for (int j = 1; j < 10; ++j) {
|
||||
for (int j = 1; j < 11; ++j) {
|
||||
params[j].is_null = ((i == j) ? &is_null : 0);
|
||||
}
|
||||
v.b = (int8_t)i % 2;
|
||||
|
@ -216,7 +227,7 @@ int main(int argc, char *argv[])
|
|||
printf("expect two rows, but %d rows are fetched\n", rows);
|
||||
}
|
||||
|
||||
taos_free_result(result);
|
||||
// taos_free_result(result);
|
||||
taos_stmt_close(stmt);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -280,7 +280,7 @@ void consume_repeatly(tmq_t* tmq) {
|
|||
|
||||
code = tmq_offset_seek(tmq, topic_name, p->vgId, p->begin);
|
||||
if (code != 0) {
|
||||
fprintf(stderr, "failed to seek to %ld, reason:%s", p->begin, tmq_err2str(code));
|
||||
fprintf(stderr, "failed to seek to %d, reason:%s", (int)p->begin, tmq_err2str(code));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,11 @@ extern uint16_t tsMonitorPort;
|
|||
extern int32_t tsMonitorMaxLogs;
|
||||
extern bool tsMonitorComp;
|
||||
|
||||
// audit
|
||||
extern bool tsEnableAudit;
|
||||
extern char tsAuditFqdn[];
|
||||
extern uint16_t tsAuditPort;
|
||||
|
||||
// telem
|
||||
extern bool tsEnableTelem;
|
||||
extern int32_t tsTelemInterval;
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
#define TK_TABLE_PREFIX 95
|
||||
#define TK_TABLE_SUFFIX 96
|
||||
#define TK_NK_COLON 97
|
||||
#define TK_MAX_SPEED 98
|
||||
#define TK_BWLIMIT 98
|
||||
#define TK_START 99
|
||||
#define TK_TIMESTAMP 100
|
||||
#define TK_END 101
|
||||
|
@ -356,6 +356,7 @@
|
|||
#define TK_WAL 338
|
||||
|
||||
|
||||
|
||||
#define TK_NK_SPACE 600
|
||||
#define TK_NK_COMMENT 601
|
||||
#define TK_NK_ILLEGAL 602
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_AUDIT_H_
|
||||
#define _TD_AUDIT_H_
|
||||
|
||||
#include "tarray.h"
|
||||
#include "tdef.h"
|
||||
#include "tlog.h"
|
||||
#include "tmsg.h"
|
||||
#include "tjson.h"
|
||||
#include "tmsgcb.h"
|
||||
#include "trpc.h"
|
||||
#include "mnode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const char *server;
|
||||
uint16_t port;
|
||||
bool comp;
|
||||
} SAuditCfg;
|
||||
|
||||
int32_t auditInit(const SAuditCfg *pCfg);
|
||||
void auditSend(SJson *pJson);
|
||||
void auditRecord(SRpcMsg *pReq, int64_t clusterId, char *operation, char *target1, char *target2, char *detail);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_MONITOR_H_*/
|
|
@ -59,7 +59,7 @@ typedef struct SDataSinkMgtCfg {
|
|||
uint32_t maxDataBlockNumPerQuery;
|
||||
} SDataSinkMgtCfg;
|
||||
|
||||
int32_t dsDataSinkMgtInit(SDataSinkMgtCfg* cfg, SStorageAPI* pAPI);
|
||||
int32_t dsDataSinkMgtInit(SDataSinkMgtCfg* cfg, SStorageAPI* pAPI, void** ppSinkManager);
|
||||
|
||||
typedef struct SInputData {
|
||||
const struct SSDataBlock* pData;
|
||||
|
@ -83,7 +83,7 @@ typedef struct SOutputData {
|
|||
* @param pHandle output
|
||||
* @return error code
|
||||
*/
|
||||
int32_t dsCreateDataSinker(const SDataSinkNode* pDataSink, DataSinkHandle* pHandle, void* pParam, const char* id);
|
||||
int32_t dsCreateDataSinker(void* pSinkManager, const SDataSinkNode* pDataSink, DataSinkHandle* pHandle, void* pParam, const char* id);
|
||||
|
||||
int32_t dsDataSinkGetCacheSize(SDataSinkStat* pStat);
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ void taosRemoveDir(const char *dirname);
|
|||
bool taosDirExist(const char *dirname);
|
||||
int32_t taosMkDir(const char *dirname);
|
||||
int32_t taosMulMkDir(const char *dirname);
|
||||
int32_t taosMulModeMkDir(const char *dirname, int mode);
|
||||
int32_t taosMulModeMkDir(const char *dirname, int mode, bool checkAccess);
|
||||
void taosRemoveOldFiles(const char *dirname, int32_t keepDays);
|
||||
int32_t taosExpandDir(const char *dirname, char *outname, int32_t maxlen);
|
||||
int32_t taosRealPath(char *dirname, char *realPath, int32_t maxlen);
|
||||
|
|
|
@ -114,7 +114,7 @@ pipeline {
|
|||
sync_source("${BRANCH_NAME}")
|
||||
sh '''
|
||||
if [ "${verMode}" = "all" ];then
|
||||
verMode="community enterprise"
|
||||
verMode="enterprise"
|
||||
fi
|
||||
verModeList=${verMode}
|
||||
for verModeSin in ${verModeList}
|
||||
|
@ -123,18 +123,6 @@ pipeline {
|
|||
bash testpackage.sh -m ${verModeSin} -f server -l false -c x64 -v ${version} -o ${baseVersion} -s ${sourcePath} -t tar
|
||||
python3 checkPackageRuning.py
|
||||
done
|
||||
'''
|
||||
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh -m community -f server -l true -c x64 -v ${version} -o ${baseVersion} -s ${sourcePath} -t tar
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh -m community -f server -l false -c x64 -v ${version} -o ${baseVersion} -s ${sourcePath} -t deb
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ else
|
|||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/tdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||
[ -f ${inc_link_dir}/taosws.h ] && ${csudo}rm -f ${inc_link_dir}/taosws.h || :
|
||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||
|
|
|
@ -98,6 +98,7 @@ cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_pat
|
|||
cp ${compile_dir}/../include/client/taos.h ${pkg_dir}${install_home_path}/include
|
||||
cp ${compile_dir}/../include/common/taosdef.h ${pkg_dir}${install_home_path}/include
|
||||
cp ${compile_dir}/../include/util/taoserror.h ${pkg_dir}${install_home_path}/include
|
||||
cp ${compile_dir}/../include/util/tdef.h ${pkg_dir}${install_home_path}/include
|
||||
cp ${compile_dir}/../include/libs/function/taosudf.h ${pkg_dir}${install_home_path}/include
|
||||
[ -f ${compile_dir}/build/include/taosws.h ] && cp ${compile_dir}/build/include/taosws.h ${pkg_dir}${install_home_path}/include ||:
|
||||
cp -r ${top_dir}/examples/* ${pkg_dir}${install_home_path}/examples
|
||||
|
|
|
@ -95,6 +95,7 @@ cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driv
|
|||
cp %{_compiledir}/../include/client/taos.h %{buildroot}%{homepath}/include
|
||||
cp %{_compiledir}/../include/common/taosdef.h %{buildroot}%{homepath}/include
|
||||
cp %{_compiledir}/../include/util/taoserror.h %{buildroot}%{homepath}/include
|
||||
cp %{_compiledir}/../include/util/tdef.h %{buildroot}%{homepath}/include
|
||||
cp %{_compiledir}/../include/libs/function/taosudf.h %{buildroot}%{homepath}/include
|
||||
[ -f %{_compiledir}/build/include/taosws.h ] && cp %{_compiledir}/build/include/taosws.h %{buildroot}%{homepath}/include ||:
|
||||
#cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
||||
|
@ -217,6 +218,7 @@ if [ $1 -eq 0 ];then
|
|||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/tdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ function install_jemalloc() {
|
|||
}
|
||||
|
||||
function install_header() {
|
||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/tdef.h ${inc_link_dir}/taosudf.h || :
|
||||
|
||||
[ -f ${inc_link_dir}/taosws.h ] && ${csudo}rm -f ${inc_link_dir}/taosws.h || :
|
||||
|
||||
|
@ -353,6 +353,7 @@ function install_header() {
|
|||
${csudo}ln -sf ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||
${csudo}ln -sf ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
||||
${csudo}ln -sf ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||
${csudo}ln -sf ${install_main_dir}/include/tdef.h ${inc_link_dir}/tdef.h
|
||||
${csudo}ln -sf ${install_main_dir}/include/taosudf.h ${inc_link_dir}/taosudf.h
|
||||
|
||||
[ -f ${install_main_dir}/include/taosws.h ] && ${csudo}ln -sf ${install_main_dir}/include/taosws.h ${inc_link_dir}/taosws.h || :
|
||||
|
@ -935,7 +936,7 @@ function updateProduct() {
|
|||
fi
|
||||
echo
|
||||
echo -e "\033[44;32;1m${productName2} is updated successfully!${NC}"
|
||||
echo -e "\033[44;32;1mTo manage ${productName2} instance, view documentation and explorer features, you need to install ${clientName2}Explorer ${NC}"
|
||||
echo -e "\033[44;32;1mTo manage ${productName2} instance, view documentation or explorer features, please install ${clientName2}Explorer ${NC}"
|
||||
else
|
||||
install_bin
|
||||
install_config
|
||||
|
@ -1028,7 +1029,7 @@ function installProduct() {
|
|||
fi
|
||||
|
||||
echo -e "\033[44;32;1m${productName2} is installed successfully!${NC}"
|
||||
echo -e "\033[44;32;1mTo manage ${productName2} instance, view documentation and explorer features, you need to install ${clientName2}Explorer ${NC}"
|
||||
echo -e "\033[44;32;1mTo manage ${productName2} instance, view documentation or explorer features, please install ${clientName2}Explorer ${NC}"
|
||||
echo
|
||||
else # Only install client
|
||||
install_bin
|
||||
|
|
|
@ -180,10 +180,11 @@ function install_lib() {
|
|||
}
|
||||
|
||||
function install_header() {
|
||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/tdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||
${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
||||
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
||||
${csudo}ln -s ${install_main_dir}/include/tdef.h ${inc_link_dir}/tdef.h
|
||||
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||
${csudo}ln -s ${install_main_dir}/include/taosudf.h ${inc_link_dir}/taosudf.h
|
||||
|
||||
|
|
|
@ -158,7 +158,6 @@ function install_bin() {
|
|||
${csudo}rm -f ${bin_link_dir}/udfd || :
|
||||
${csudo}rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo}rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo}rm -f ${bin_link_dir}/taosx || :
|
||||
${csudo}rm -f ${bin_link_dir}/${uninstallScript} || :
|
||||
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
|
@ -348,9 +347,9 @@ function install_lib() {
|
|||
|
||||
function install_header() {
|
||||
${csudo}mkdir -p ${inc_link_dir}
|
||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/tdef.h ${inc_link_dir}/taosudf.h || :
|
||||
[ -f ${inc_link_dir}/taosws.h ] && ${csudo}rm -f ${inc_link_dir}/taosws.h ||:
|
||||
${csudo}cp -f ${source_dir}/include/client/taos.h ${source_dir}/include/common/taosdef.h ${source_dir}/include/util/taoserror.h ${source_dir}/include/libs/function/taosudf.h \
|
||||
${csudo}cp -f ${source_dir}/include/client/taos.h ${source_dir}/include/common/taosdef.h ${source_dir}/include/util/taoserror.h ${source_dir}/include/util/tdef.h ${source_dir}/include/libs/function/taosudf.h \
|
||||
${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
||||
|
||||
if [ -f ${binary_dir}/build/include/taosws.h ]; then
|
||||
|
@ -361,6 +360,7 @@ function install_header() {
|
|||
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h > /dev/null 2>&1
|
||||
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h > /dev/null 2>&1
|
||||
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h > /dev/null 2>&1
|
||||
${csudo}ln -s ${install_main_dir}/include/tdef.h ${inc_link_dir}/tdef.h > /dev/null 2>&1
|
||||
${csudo}ln -s ${install_main_dir}/include/taosudf.h ${inc_link_dir}/taosudf.h > /dev/null 2>&1
|
||||
|
||||
${csudo}chmod 644 ${install_main_dir}/include/*
|
||||
|
|
|
@ -83,7 +83,7 @@ else
|
|||
wslib_files="${build_dir}/lib/libtaosws.dylib"
|
||||
fi
|
||||
|
||||
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h ${code_dir}/include/libs/function/taosudf.h"
|
||||
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h ${code_dir}/include/util/tdef.h ${code_dir}/include/libs/function/taosudf.h"
|
||||
wsheader_files="${build_dir}/include/taosws.h"
|
||||
|
||||
if [ "$dbName" != "taos" ]; then
|
||||
|
|
|
@ -115,7 +115,7 @@ else
|
|||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||
wslib_files="${build_dir}/lib/libtaosws.so"
|
||||
fi
|
||||
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h ${code_dir}/include/libs/function/taosudf.h"
|
||||
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h ${code_dir}/include/util/tdef.h ${code_dir}/include/libs/function/taosudf.h"
|
||||
|
||||
wsheader_files="${build_dir}/include/taosws.h"
|
||||
|
||||
|
|
|
@ -133,12 +133,13 @@ function kill_taosd() {
|
|||
function install_include() {
|
||||
log_print "start install include from ${inc_dir} to ${inc_link_dir}"
|
||||
${csudo}mkdir -p ${inc_link_dir}
|
||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/tdef.h ${inc_link_dir}/taosudf.h || :
|
||||
[ -f ${inc_link_dir}/taosws.h ] && ${csudo}rm -f ${inc_link_dir}/taosws.h ||:
|
||||
|
||||
${csudo}ln -s ${inc_dir}/taos.h ${inc_link_dir}/taos.h
|
||||
${csudo}ln -s ${inc_dir}/taosdef.h ${inc_link_dir}/taosdef.h
|
||||
${csudo}ln -s ${inc_dir}/taoserror.h ${inc_link_dir}/taoserror.h
|
||||
${csudo}ln -s ${inc_dir}/tdef.h ${inc_link_dir}/tdef.h
|
||||
${csudo}ln -s ${inc_dir}/taosudf.h ${inc_link_dir}/taosudf.h
|
||||
|
||||
[ -f ${inc_dir}/taosws.h ] && ${csudo}ln -sf ${inc_dir}/taosws.h ${inc_link_dir}/taosws.h ||:
|
||||
|
|
|
@ -143,6 +143,7 @@ ${csudo}rm -f ${cfg_link_dir}/*.new || :
|
|||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/tdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo}rm -f ${lib64_link_dir}/libtaos.* || :
|
||||
|
|
|
@ -155,6 +155,7 @@ function clean_header() {
|
|||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/tdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||
|
||||
[ -f ${inc_link_dir}/taosws.h ] && ${csudo}rm -f ${inc_link_dir}/taosws.h || :
|
||||
|
|
|
@ -73,6 +73,7 @@ function clean_header() {
|
|||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/tdef.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||
}
|
||||
|
||||
|
|
|
@ -387,8 +387,18 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
len += sprintf(str + len, "%lf", dv);
|
||||
} break;
|
||||
|
||||
case TSDB_DATA_TYPE_VARBINARY:{
|
||||
void* data = NULL;
|
||||
uint32_t size = 0;
|
||||
int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
|
||||
if(taosAscii2Hex(row[i], charLen, &data, &size) < 0){
|
||||
break;
|
||||
}
|
||||
memcpy(str + len, data, size);
|
||||
len += size;
|
||||
taosMemoryFree(data);
|
||||
}break;
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_GEOMETRY: {
|
||||
int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
|
||||
|
|
|
@ -522,9 +522,9 @@ static char* processAlterTable(SMqMetaRsp* metaRsp) {
|
|||
buf = parseTagDatatoJson(vAlterTbReq.pTagVal);
|
||||
} else {
|
||||
if(vAlterTbReq.tagType == TSDB_DATA_TYPE_VARBINARY){
|
||||
buf = taosMemoryCalloc(vAlterTbReq.nTagVal + 1, 1);
|
||||
buf = taosMemoryCalloc(vAlterTbReq.nTagVal*2 + 2 + 3, 1);
|
||||
}else{
|
||||
buf = taosMemoryCalloc(vAlterTbReq.nTagVal + 1, 1);
|
||||
buf = taosMemoryCalloc(vAlterTbReq.nTagVal + 3, 1);
|
||||
}
|
||||
dataConverToStr(buf, vAlterTbReq.tagType, vAlterTbReq.pTagVal, vAlterTbReq.nTagVal, NULL);
|
||||
}
|
||||
|
@ -697,14 +697,14 @@ static int32_t taosCreateStb(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
pReq.pColumns = taosArrayInit(req.schemaRow.nCols, sizeof(SField));
|
||||
for (int32_t i = 0; i < req.schemaRow.nCols; i++) {
|
||||
SSchema* pSchema = req.schemaRow.pSchema + i;
|
||||
SField field = {.type = pSchema->type, .bytes = pSchema->bytes};
|
||||
SField field = {.type = pSchema->type, .flags = pSchema->flags, .bytes = pSchema->bytes};
|
||||
strcpy(field.name, pSchema->name);
|
||||
taosArrayPush(pReq.pColumns, &field);
|
||||
}
|
||||
pReq.pTags = taosArrayInit(req.schemaTag.nCols, sizeof(SField));
|
||||
for (int32_t i = 0; i < req.schemaTag.nCols; i++) {
|
||||
SSchema* pSchema = req.schemaTag.pSchema + i;
|
||||
SField field = {.type = pSchema->type, .bytes = pSchema->bytes};
|
||||
SField field = {.type = pSchema->type, .flags = pSchema->flags, .bytes = pSchema->bytes};
|
||||
strcpy(field.name, pSchema->name);
|
||||
taosArrayPush(pReq.pTags, &field);
|
||||
}
|
||||
|
|
|
@ -218,7 +218,16 @@ int32_t smlSetCTableName(SSmlTableInfo *oneTable) {
|
|||
|
||||
if (strlen(oneTable->childTableName) == 0) {
|
||||
SArray *dst = taosArrayDup(oneTable->tags, NULL);
|
||||
RandTableName rName = {dst, oneTable->sTableName, (uint8_t)oneTable->sTableNameLen, oneTable->childTableName};
|
||||
ASSERT(oneTable->sTableNameLen < TSDB_TABLE_NAME_LEN);
|
||||
char superName[TSDB_TABLE_NAME_LEN] = {0};
|
||||
RandTableName rName = {dst, NULL, (uint8_t)oneTable->sTableNameLen, oneTable->childTableName};
|
||||
if(tsSmlDot2Underline){
|
||||
memcpy(superName, oneTable->sTableName, oneTable->sTableNameLen);
|
||||
smlStrReplace(superName, oneTable->sTableNameLen);
|
||||
rName.stbFullName = superName;
|
||||
}else{
|
||||
rName.stbFullName = oneTable->sTableName;
|
||||
}
|
||||
|
||||
buildChildTableName(&rName);
|
||||
taosArrayDestroy(dst);
|
||||
|
@ -230,6 +239,9 @@ void getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tin
|
|||
char key[TSDB_TABLE_NAME_LEN * 2 + 1] = {0};
|
||||
size_t nLen = strlen(tinfo->childTableName);
|
||||
memcpy(key, currElement->measure, currElement->measureLen);
|
||||
if(tsSmlDot2Underline){
|
||||
smlStrReplace(key, currElement->measureLen);
|
||||
}
|
||||
memcpy(key + currElement->measureLen + 1, tinfo->childTableName, nLen);
|
||||
void *uid =
|
||||
taosHashGet(info->tableUids, key,
|
||||
|
|
|
@ -986,7 +986,7 @@ int32_t tmq_subscription(tmq_t* tmq, tmq_list_t** topics) {
|
|||
int32_t tmq_unsubscribe(tmq_t* tmq) {
|
||||
if(tmq == NULL) return TSDB_CODE_INVALID_PARA;
|
||||
if (tmq->status != TMQ_CONSUMER_STATUS__READY) {
|
||||
tscInfo("consumer:0x%" PRIx64 " not in ready state, close it directly", tmq->consumerId);
|
||||
tscInfo("consumer:0x%" PRIx64 " not in ready state, unsubscribe it directly", tmq->consumerId);
|
||||
return 0;
|
||||
}
|
||||
if (tmq->autoCommit) {
|
||||
|
|
|
@ -95,6 +95,11 @@ uint16_t tsMonitorPort = 6043;
|
|||
int32_t tsMonitorMaxLogs = 100;
|
||||
bool tsMonitorComp = false;
|
||||
|
||||
// audit
|
||||
bool tsEnableAudit = false;
|
||||
char tsAuditFqdn[TSDB_FQDN_LEN] = {0};
|
||||
uint16_t tsAuditPort = 6043;
|
||||
|
||||
// telem
|
||||
bool tsEnableTelem = true;
|
||||
int32_t tsTelemInterval = 43200;
|
||||
|
@ -602,6 +607,10 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddInt32(pCfg, "monitorMaxLogs", tsMonitorMaxLogs, 1, 1000000, CFG_SCOPE_SERVER) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "monitorComp", tsMonitorComp, CFG_SCOPE_SERVER) != 0) return -1;
|
||||
|
||||
if (cfgAddBool(pCfg, "audit", tsEnableAudit, CFG_SCOPE_SERVER) != 0) return -1;
|
||||
if (cfgAddString(pCfg, "auditFqdn", tsAuditFqdn, CFG_SCOPE_SERVER) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "auditPort", tsAuditPort, 1, 65056, CFG_SCOPE_SERVER) != 0) return -1;
|
||||
|
||||
if (cfgAddBool(pCfg, "crashReporting", tsEnableCrashReport, CFG_SCOPE_BOTH) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "telemetryReporting", tsEnableTelem, CFG_SCOPE_BOTH) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "telemetryInterval", tsTelemInterval, 1, 200000, CFG_SCOPE_BOTH) != 0) return -1;
|
||||
|
@ -1003,6 +1012,10 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
|
|||
tsMonitorComp = cfgGetItem(pCfg, "monitorComp")->bval;
|
||||
tsQueryRspPolicy = cfgGetItem(pCfg, "queryRspPolicy")->i32;
|
||||
|
||||
tsEnableAudit = cfgGetItem(pCfg, "audit")->bval;
|
||||
tstrncpy(tsAuditFqdn, cfgGetItem(pCfg, "auditFqdn")->str, TSDB_FQDN_LEN);
|
||||
tsAuditPort = (uint16_t)cfgGetItem(pCfg, "auditPort")->i32;
|
||||
|
||||
tsEnableTelem = cfgGetItem(pCfg, "telemetryReporting")->bval;
|
||||
tsEnableCrashReport = cfgGetItem(pCfg, "crashReporting")->bval;
|
||||
tsTtlChangeOnWrite = cfgGetItem(pCfg, "ttlChangeOnWrite")->bval;
|
||||
|
@ -1511,7 +1524,7 @@ int32_t taosCreateLog(const char *logname, int32_t logFileNum, const char *cfgDi
|
|||
|
||||
taosSetAllDebugFlag(cfgGetItem(pCfg, "debugFlag")->i32, false);
|
||||
|
||||
if (taosMulModeMkDir(tsLogDir, 0777) != 0) {
|
||||
if (taosMulModeMkDir(tsLogDir, 0777, true) != 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
printf("failed to create dir:%s since %s", tsLogDir, terrstr());
|
||||
cfgCleanup(pCfg);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "dmMgmt.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define STR_CASE_CMP(s, d) (0 == strcasecmp((s), (d)))
|
||||
#define STR_STR_CMP(s, d) (strstr((s), (d)))
|
||||
|
@ -34,6 +35,16 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define DM_INIT_AUDIT() \
|
||||
do { \
|
||||
auditCfg.port = tsMonitorPort; \
|
||||
auditCfg.server = tsMonitorFqdn; \
|
||||
auditCfg.comp = tsMonitorComp; \
|
||||
if (auditInit(&auditCfg) != 0) { \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DM_ERR_RTN(c) \
|
||||
do { \
|
||||
code = (c); \
|
||||
|
@ -96,6 +107,14 @@ _exit:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t dmInitAudit() {
|
||||
SAuditCfg auditCfg = {0};
|
||||
|
||||
DM_INIT_AUDIT();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool dmDataSpaceAvailable() {
|
||||
SDnode *pDnode = dmInstance();
|
||||
if (pDnode->pTfs) {
|
||||
|
@ -176,6 +195,7 @@ int32_t dmInit() {
|
|||
if (dmCheckRepeatInit(dmInstance()) != 0) return -1;
|
||||
if (dmInitSystem() != 0) return -1;
|
||||
if (dmInitMonitor() != 0) return -1;
|
||||
if (dmInitAudit() != 0) return -1;
|
||||
if (dmInitDnode(dmInstance()) != 0) return -1;
|
||||
|
||||
dInfo("dnode env is initialized");
|
||||
|
|
|
@ -16,7 +16,7 @@ target_include_directories(
|
|||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||
)
|
||||
target_link_libraries(
|
||||
mnode scheduler sdb wal transport cjson sync monitor executor qworker stream parser
|
||||
mnode scheduler sdb wal transport cjson sync monitor executor qworker stream parser audit
|
||||
)
|
||||
|
||||
IF (TD_GRANT)
|
||||
|
|
|
@ -33,7 +33,7 @@ enum {
|
|||
|
||||
int32_t mndInitConsumer(SMnode *pMnode);
|
||||
void mndCleanupConsumer(SMnode *pMnode);
|
||||
void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId);
|
||||
void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId, SRpcHandleInfo* info);
|
||||
|
||||
SMqConsumerObj *mndAcquireConsumer(SMnode *pMnode, int64_t consumerId);
|
||||
void mndReleaseConsumer(SMnode *pMnode, SMqConsumerObj *pConsumer);
|
||||
|
|
|
@ -99,6 +99,8 @@ typedef enum {
|
|||
TRN_CONFLICT_GLOBAL = 1,
|
||||
TRN_CONFLICT_DB = 2,
|
||||
TRN_CONFLICT_DB_INSIDE = 3,
|
||||
TRN_CONFLICT_TOPIC = 4,
|
||||
TRN_CONFLICT_TOPIC_INSIDE = 5,
|
||||
} ETrnConflct;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -37,7 +37,6 @@ static const char *mndConsumerStatusName(int status);
|
|||
static int32_t mndConsumerActionInsert(SSdb *pSdb, SMqConsumerObj *pConsumer);
|
||||
static int32_t mndConsumerActionDelete(SSdb *pSdb, SMqConsumerObj *pConsumer);
|
||||
static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, SMqConsumerObj *pNewConsumer);
|
||||
static int32_t mndProcessConsumerMetaMsg(SRpcMsg *pMsg);
|
||||
static int32_t mndRetrieveConsumer(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||
static void mndCancelGetNextConsumer(SMnode *pMnode, void *pIter);
|
||||
|
||||
|
@ -45,7 +44,6 @@ static int32_t mndProcessSubscribeReq(SRpcMsg *pMsg);
|
|||
static int32_t mndProcessAskEpReq(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessMqHbReq(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessConsumerLostMsg(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg);
|
||||
|
||||
|
@ -64,7 +62,6 @@ int32_t mndInitConsumer(SMnode *pMnode) {
|
|||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_HB, mndProcessMqHbReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_ASK_EP, mndProcessAskEpReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_TIMER, mndProcessMqTimerMsg);
|
||||
// mndSetMsgHandle(pMnode, TDMT_MND_TMQ_CONSUMER_LOST, mndProcessConsumerLostMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_CONSUMER_RECOVER, mndProcessConsumerRecoverMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, mndProcessConsumerClearMsg);
|
||||
|
||||
|
@ -76,7 +73,7 @@ int32_t mndInitConsumer(SMnode *pMnode) {
|
|||
|
||||
void mndCleanupConsumer(SMnode *pMnode) {}
|
||||
|
||||
void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId){
|
||||
void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId, SRpcHandleInfo* info){
|
||||
SMqConsumerClearMsg *pClearMsg = rpcMallocCont(sizeof(SMqConsumerClearMsg));
|
||||
if (pClearMsg == NULL) {
|
||||
mError("consumer:0x%"PRIx64" failed to clear consumer due to out of memory. alloc size:%d", consumerId, (int32_t)sizeof(SMqConsumerClearMsg));
|
||||
|
@ -85,7 +82,11 @@ void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId){
|
|||
|
||||
pClearMsg->consumerId = consumerId;
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, .pCont = pClearMsg, .contLen = sizeof(SMqConsumerClearMsg)};
|
||||
.msgType = TDMT_MND_TMQ_LOST_CONSUMER_CLEAR,
|
||||
.pCont = pClearMsg,
|
||||
.contLen = sizeof(SMqConsumerClearMsg),
|
||||
.info = *info,
|
||||
};
|
||||
|
||||
mInfo("consumer:0x%" PRIx64 " drop from sdb", consumerId);
|
||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
|
||||
|
@ -122,48 +123,31 @@ void mndRebCntDec() {
|
|||
}
|
||||
}
|
||||
|
||||
//static int32_t mndProcessConsumerLostMsg(SRpcMsg *pMsg) {
|
||||
// SMnode *pMnode = pMsg->info.node;
|
||||
// SMqConsumerLostMsg *pLostMsg = pMsg->pCont;
|
||||
// SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, pLostMsg->consumerId);
|
||||
// if (pConsumer == NULL) {
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// mInfo("process consumer lost msg, consumer:0x%" PRIx64 " status:%d(%s)", pLostMsg->consumerId, pConsumer->status,
|
||||
// mndConsumerStatusName(pConsumer->status));
|
||||
//
|
||||
// if (pConsumer->status != MQ_CONSUMER_STATUS_READY) {
|
||||
// mndReleaseConsumer(pMnode, pConsumer);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup);
|
||||
// pConsumerNew->updateType = CONSUMER_UPDATE_TIMER_LOST;
|
||||
//
|
||||
// mndReleaseConsumer(pMnode, pConsumer);
|
||||
//
|
||||
// STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "lost-csm");
|
||||
// if (pTrans == NULL) {
|
||||
// goto FAIL;
|
||||
// }
|
||||
//
|
||||
// if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
|
||||
// goto FAIL;
|
||||
// }
|
||||
//
|
||||
// if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
// goto FAIL;
|
||||
// }
|
||||
//
|
||||
// tDeleteSMqConsumerObj(pConsumerNew, true);
|
||||
// mndTransDrop(pTrans);
|
||||
// return 0;
|
||||
//FAIL:
|
||||
// tDeleteSMqConsumerObj(pConsumerNew, true);
|
||||
// mndTransDrop(pTrans);
|
||||
// return -1;
|
||||
//}
|
||||
static int32_t validateTopics(STrans *pTrans, const SArray *pTopicList, SMnode *pMnode, const char *pUser) {
|
||||
int32_t numOfTopics = taosArrayGetSize(pTopicList);
|
||||
|
||||
for (int32_t i = 0; i < numOfTopics; i++) {
|
||||
char *pOneTopic = taosArrayGetP(pTopicList, i);
|
||||
SMqTopicObj *pTopic = mndAcquireTopic(pMnode, pOneTopic);
|
||||
if (pTopic == NULL) { // terrno has been set by callee function
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mndCheckTopicPrivilege(pMnode, pUser, MND_OPER_SUBSCRIBE, pTopic) != 0) {
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mndTransSetDbName(pTrans, pOneTopic, NULL);
|
||||
if(mndTransCheckConflict(pMnode, pTrans) != 0){
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
return -1;
|
||||
}
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
|
@ -188,10 +172,13 @@ static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg) {
|
|||
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pMsg, "recover-csm");
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_TOPIC, pMsg, "recover-csm");
|
||||
if (pTrans == NULL) {
|
||||
goto FAIL;
|
||||
}
|
||||
if(validateTopics(pTrans, pConsumer->assignedTopics, pMnode, pMsg->info.conn.user) != 0){
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL;
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL;
|
||||
|
@ -221,19 +208,12 @@ static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) {
|
|||
mInfo("consumer:0x%" PRIx64 " needs to be cleared, status %s", pClearMsg->consumerId,
|
||||
mndConsumerStatusName(pConsumer->status));
|
||||
|
||||
// if (pConsumer->status != MQ_CONSUMER_STATUS_LOST) {
|
||||
// mndReleaseConsumer(pMnode, pConsumer);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup);
|
||||
// pConsumerNew->updateType = CONSUMER_UPDATE_TIMER_LOST;
|
||||
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "clear-csm");
|
||||
if (pTrans == NULL) goto FAIL;
|
||||
|
||||
// this is the drop action, not the update action
|
||||
if (mndSetConsumerDropLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL;
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL;
|
||||
|
@ -318,7 +298,7 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
|
|||
|
||||
if (status == MQ_CONSUMER_STATUS_READY) {
|
||||
if (taosArrayGetSize(pConsumer->assignedTopics) == 0) { // unsubscribe or close
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId);
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pMsg->info);
|
||||
} else if (hbStatus > MND_CONSUMER_LOST_HB_CNT) {
|
||||
taosRLockLatch(&pConsumer->lock);
|
||||
int32_t topicNum = taosArrayGetSize(pConsumer->currentTopics);
|
||||
|
@ -333,7 +313,7 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
|
|||
}
|
||||
} else if (status == MQ_CONSUMER_STATUS_LOST) {
|
||||
if (hbStatus > MND_CONSUMER_LOST_CLEAR_THRESHOLD) { // clear consumer if lost a day
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId);
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pMsg->info);
|
||||
}
|
||||
} else { // MQ_CONSUMER_STATUS_REBALANCE
|
||||
taosRLockLatch(&pConsumer->lock);
|
||||
|
@ -410,6 +390,7 @@ static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
|
|||
.msgType = TDMT_MND_TMQ_CONSUMER_RECOVER,
|
||||
.pCont = pRecoverMsg,
|
||||
.contLen = sizeof(SMqConsumerRecoverMsg),
|
||||
.info = pMsg->info,
|
||||
};
|
||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &pRpcMsg);
|
||||
}
|
||||
|
@ -484,6 +465,7 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
|||
.msgType = TDMT_MND_TMQ_CONSUMER_RECOVER,
|
||||
.pCont = pRecoverMsg,
|
||||
.contLen = sizeof(SMqConsumerRecoverMsg),
|
||||
.info = pMsg->info,
|
||||
};
|
||||
|
||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &pRpcMsg);
|
||||
|
@ -629,27 +611,6 @@ int32_t mndSetConsumerCommitLogs(SMnode *pMnode, STrans *pTrans, SMqConsumerObj
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t validateTopics(const SArray *pTopicList, SMnode *pMnode, const char *pUser) {
|
||||
int32_t numOfTopics = taosArrayGetSize(pTopicList);
|
||||
|
||||
for (int32_t i = 0; i < numOfTopics; i++) {
|
||||
char *pOneTopic = taosArrayGetP(pTopicList, i);
|
||||
SMqTopicObj *pTopic = mndAcquireTopic(pMnode, pOneTopic);
|
||||
if (pTopic == NULL) { // terrno has been set by callee function
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mndCheckTopicPrivilege(pMnode, pUser, MND_OPER_SUBSCRIBE, pTopic) != 0) {
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *topicNameDup(void *p) { return taosStrdup((char *)p); }
|
||||
|
||||
static void freeItem(void *param) {
|
||||
|
@ -688,12 +649,12 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
// check topic existence
|
||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pMsg, "subscribe");
|
||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_TOPIC, pMsg, "subscribe");
|
||||
if (pTrans == NULL) {
|
||||
goto _over;
|
||||
}
|
||||
|
||||
code = validateTopics(pTopicList, pMnode, pMsg->info.conn.user);
|
||||
code = validateTopics(pTrans, pTopicList, pMnode, pMsg->info.conn.user);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _over;
|
||||
}
|
||||
|
@ -722,7 +683,6 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
|||
|
||||
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) goto _over;
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto _over;
|
||||
|
||||
} else {
|
||||
int32_t status = atomic_load_32(&pExistedConsumer->status);
|
||||
|
||||
|
@ -802,7 +762,6 @@ _over:
|
|||
|
||||
tDeleteSMqConsumerObj(pConsumerNew, true);
|
||||
|
||||
// TODO: replace with destroy subscribe msg
|
||||
taosArrayDestroyP(subscribe.topicNames, (FDelete)taosMemoryFree);
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include "mndUser.h"
|
||||
#include "mndVgroup.h"
|
||||
#include "systable.h"
|
||||
#include "tjson.h"
|
||||
#include "thttp.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define DB_VER_NUMBER 1
|
||||
#define DB_RESERVE_SIZE 46
|
||||
|
@ -675,6 +678,22 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
static void mndBuildAuditDetailInt32(char* detail, char* tmp, char* format, int32_t para){
|
||||
if(para > 0){
|
||||
if(strlen(detail) > 0) strcat(detail, ", ");
|
||||
sprintf(tmp, format, para);
|
||||
strcat(detail, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static void mndBuildAuditDetailInt64(char* detail, char* tmp, char* format, int64_t para){
|
||||
if(para > 0){
|
||||
if(strlen(detail) > 0) strcat(detail, ", ");
|
||||
sprintf(tmp, format, para);
|
||||
strcat(detail, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
int32_t code = -1;
|
||||
|
@ -733,6 +752,45 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) {
|
|||
code = mndCreateDb(pMnode, pReq, &createReq, pUser);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char detail[3000] = {0};
|
||||
char tmp[100] = {0};
|
||||
|
||||
mndBuildAuditDetailInt32(detail, tmp, "buffer:%d", createReq.buffer);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "cacheLast:%d", createReq.cacheLast);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "cacheLastSize:%d", createReq.cacheLastSize);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "compression:%d", createReq.compression);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "daysPerFile:%d", createReq.daysPerFile);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "daysToKeep0:%d", createReq.daysToKeep0);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "daysToKeep1:%d", createReq.daysToKeep1);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "daysToKeep2:%d", createReq.daysToKeep2);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "hashPrefix:%d", createReq.hashPrefix);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "hashSuffix:%d", createReq.hashSuffix);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "ignoreExist:%d", createReq.ignoreExist);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "maxRows:%d", createReq.maxRows);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "minRows:%d", createReq.minRows);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "numOfRetensions:%d", createReq.numOfRetensions);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "numOfStables:%d", createReq.numOfStables);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "numOfVgroups:%d", createReq.numOfVgroups);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "pages:%d", createReq.pages);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "pageSize:%d", createReq.pageSize);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "precision:%d", createReq.precision);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "replications:%d", createReq.replications);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "schemaless:%d", createReq.schemaless);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "sstTrigger:%d", createReq.sstTrigger);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "strict:%d", createReq.strict);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "tsdbPageSize:%d", createReq.tsdbPageSize);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "walFsyncPeriod:%d", createReq.walFsyncPeriod);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "walLevel:%d", createReq.walLevel);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "walRetentionPeriod:%d", createReq.walRetentionPeriod);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "walRetentionSize:%" PRId64, createReq.walRetentionSize);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "walRollPeriod:%d", createReq.walRollPeriod);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "walSegmentSize:%" PRId64, createReq.walSegmentSize);
|
||||
|
||||
SName name = {0};
|
||||
tNameFromString(&name, createReq.db, T_NAME_ACCT | T_NAME_DB);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createDB", name.dbname, "", detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("db:%s, failed to create since %s", createReq.db, terrstr());
|
||||
|
@ -975,6 +1033,30 @@ static int32_t mndProcessAlterDbReq(SRpcMsg *pReq) {
|
|||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
char detail[3000] = {0};
|
||||
char tmp[100] = {0};
|
||||
|
||||
mndBuildAuditDetailInt32(detail, tmp, "buffer:%d", alterReq.buffer);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "cacheLast:%d", alterReq.cacheLast);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "cacheLastSize:%d", alterReq.cacheLastSize);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "daysPerFile:%d", alterReq.daysPerFile);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "daysToKeep0:%d", alterReq.daysToKeep0);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "daysToKeep1:%d", alterReq.daysToKeep1);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "daysToKeep2:%d", alterReq.daysToKeep2);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "minRows:%d", alterReq.minRows);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "pages:%d", alterReq.pages);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "pageSize:%d", alterReq.pageSize);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "replications:%d", alterReq.replications);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "sstTrigger:%d", alterReq.sstTrigger);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "strict:%d", alterReq.strict);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "walFsyncPeriod:%d", alterReq.walFsyncPeriod);
|
||||
mndBuildAuditDetailInt32(detail, tmp, "walRetentionSize:%d", alterReq.walRetentionSize);
|
||||
|
||||
SName name = {0};
|
||||
tNameFromString(&name, alterReq.db, T_NAME_ACCT | T_NAME_DB);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "alterDB", name.dbname, "", detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
if (terrno != 0) code = terrno;
|
||||
|
@ -1264,6 +1346,14 @@ static int32_t mndProcessDropDbReq(SRpcMsg *pReq) {
|
|||
code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "ignoreNotExists:%d", dropReq.ignoreNotExists);
|
||||
|
||||
SName name = {0};
|
||||
tNameFromString(&name, dropReq.db, T_NAME_ACCT | T_NAME_DB);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "dropDB", name.dbname, "", detail);
|
||||
|
||||
_OVER:
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("db:%s, failed to drop since %s", dropReq.db, terrstr());
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "mndVgroup.h"
|
||||
#include "tmisce.h"
|
||||
#include "mndCluster.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define TSDB_DNODE_VER_NUMBER 2
|
||||
#define TSDB_DNODE_RESERVE_SIZE 64
|
||||
|
@ -908,6 +909,12 @@ static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) {
|
|||
code = mndCreateDnode(pMnode, pReq, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
tsGrantHBInterval = 5;
|
||||
|
||||
char obj[200] = {0};
|
||||
sprintf(obj, "%s:%d", createReq.fqdn, createReq.port);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createDnode", obj, "", "");
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("dnode:%s:%d, failed to create since %s", createReq.fqdn, createReq.port, terrstr());
|
||||
|
@ -1055,6 +1062,17 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) {
|
|||
code = mndDropDnode(pMnode, pReq, pDnode, pMObj, pQObj, pSObj, numOfVnodes, force, dropReq.unsafe);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char obj1[150] = {0};
|
||||
sprintf(obj1, "%s:%d", dropReq.fqdn, dropReq.port);
|
||||
|
||||
char obj2[30] = {0};
|
||||
sprintf(obj2, "%d", dropReq.dnodeId);
|
||||
|
||||
char detail[100] = {0};
|
||||
sprintf(detail, "force:%d, unsafe:%d", dropReq.force, dropReq.unsafe);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "dropDnode", obj1, obj2, detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("dnode:%d, failed to drop since %s", dropReq.dnodeId, terrstr());
|
||||
|
@ -1236,6 +1254,14 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
}
|
||||
|
||||
char obj[50] = {0};
|
||||
sprintf(obj, "%d", cfgReq.dnodeId);
|
||||
|
||||
char detail[500] = {0};
|
||||
sprintf(detail, "config:%s, value:%s", cfgReq.config, cfgReq.value);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", detail);
|
||||
|
||||
int32_t code = -1;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "mndSync.h"
|
||||
#include "mndTrans.h"
|
||||
#include "tmisce.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define MNODE_VER_NUMBER 2
|
||||
#define MNODE_RESERVE_SIZE 64
|
||||
|
@ -652,6 +653,11 @@ static int32_t mndProcessCreateMnodeReq(SRpcMsg *pReq) {
|
|||
code = mndCreateMnode(pMnode, pReq, pDnode, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char obj[40] = {0};
|
||||
sprintf(obj, "%d", createReq.dnodeId);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createMnode", obj, "", "");
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("mnode:%d, failed to create since %s", createReq.dnodeId, terrstr());
|
||||
|
@ -788,6 +794,11 @@ static int32_t mndProcessDropMnodeReq(SRpcMsg *pReq) {
|
|||
code = mndDropMnode(pMnode, pReq, pObj);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char obj[40] = {0};
|
||||
sprintf(obj, "%d", dropReq.dnodeId);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "dropMnode", obj, "", "");
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("mnode:%d, failed to drop since %s", dropReq.dnodeId, terrstr());
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "mndUser.h"
|
||||
#include "tglobal.h"
|
||||
#include "tversion.h"
|
||||
#include "audit.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
|
@ -308,6 +309,15 @@ _CONNECT:
|
|||
|
||||
code = 0;
|
||||
|
||||
char obj[100] = {0};
|
||||
sprintf(obj, "%s:%d", ip, pConn->port);
|
||||
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "connType:%d, db:%s, pid:%d, startTime:%" PRId64 ", sVer:%s, app:%s",
|
||||
connReq.connType, connReq.db, connReq.pid, connReq.startTime, connReq.sVer, connReq.app);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "login", connReq.user, obj, detail);
|
||||
|
||||
_OVER:
|
||||
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "mndShow.h"
|
||||
#include "mndTrans.h"
|
||||
#include "mndUser.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define QNODE_VER_NUMBER 1
|
||||
#define QNODE_RESERVE_SIZE 64
|
||||
|
@ -306,6 +307,10 @@ static int32_t mndProcessCreateQnodeReq(SRpcMsg *pReq) {
|
|||
code = mndCreateQnode(pMnode, pReq, pDnode, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char obj[33] = {0};
|
||||
sprintf(obj, "%d", createReq.dnodeId);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createQnode", obj, "", "");
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("qnode:%d, failed to create since %s", createReq.dnodeId, terrstr());
|
||||
|
@ -415,6 +420,11 @@ static int32_t mndProcessDropQnodeReq(SRpcMsg *pReq) {
|
|||
code = mndDropQnode(pMnode, pReq, pObj);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char obj[33] = {0};
|
||||
sprintf(obj, "%d", dropReq.dnodeId);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "dropQnode", obj, "", "");
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("qnode:%d, failed to drop since %s", dropReq.dnodeId, terrstr());
|
||||
|
|
|
@ -329,7 +329,7 @@ static int32_t mndProcessRetrieveSysTableReq(SRpcMsg *pReq) {
|
|||
pReq->info.rsp = pRsp;
|
||||
pReq->info.rspLen = size;
|
||||
|
||||
if (rowsRead == 0 || ((rowsRead < rowsToRead) && !pShow->restore)) {
|
||||
if (rowsRead == 0 || mndCheckRetrieveFinished(pShow)) {
|
||||
pRsp->completed = 1;
|
||||
mDebug("show:0x%" PRIx64 ", retrieve completed", pShow->id);
|
||||
mndReleaseShowObj(pShow, true);
|
||||
|
|
|
@ -1324,7 +1324,14 @@ static int32_t mndRetrieveIdx(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc
|
|||
pShow->pIter = taosMemoryCalloc(1, sizeof(SSmaAndTagIter));
|
||||
}
|
||||
int32_t read = mndRetrieveSma(pReq, pShow, pBlock, rows);
|
||||
if (read < rows) read += mndRetrieveTagIdx(pReq, pShow, pBlock, rows - read);
|
||||
if (read < rows) {
|
||||
read += mndRetrieveTagIdx(pReq, pShow, pBlock, rows - read);
|
||||
}
|
||||
// no more to read
|
||||
if (read < rows) {
|
||||
taosMemoryFree(pShow->pIter);
|
||||
pShow->pIter = NULL;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
static void mndCancelRetrieveIdx(SMnode *pMnode, void *pIter) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "mndUser.h"
|
||||
#include "mndVgroup.h"
|
||||
#include "tname.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define STB_VER_NUMBER 1
|
||||
#define STB_RESERVE_SIZE 64
|
||||
|
@ -1173,6 +1174,21 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) {
|
|||
}
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char detail[2000] = {0};
|
||||
sprintf(detail, "colVer:%d, delay1:%" PRId64 ", delay2:%" PRId64 ", deleteMark1:%" PRId64 ", "
|
||||
"deleteMark2:%" PRId64 ", igExists:%d, numOfColumns:%d, numOfFuncs:%d, numOfTags:%d, "
|
||||
"source:%d, suid:%" PRId64 ", tagVer:%d, ttl:%d, "
|
||||
"watermark1:%" PRId64 ", watermark2:%" PRId64,
|
||||
createReq.colVer, createReq.delay1, createReq.delay2, createReq.deleteMark1,
|
||||
createReq.deleteMark2, createReq.igExists, createReq.numOfColumns, createReq.numOfFuncs, createReq.numOfTags,
|
||||
createReq.source, createReq.suid, createReq.tagVer, createReq.ttl,
|
||||
createReq.watermark1, createReq.watermark2);
|
||||
|
||||
SName name = {0};
|
||||
tNameFromString(&name, pDb->name, T_NAME_ACCT | T_NAME_DB);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createStb", name.dbname, createReq.name, detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("stb:%s, failed to create since %s", createReq.name, terrstr());
|
||||
|
@ -2241,6 +2257,15 @@ static int32_t mndProcessAlterStbReq(SRpcMsg *pReq) {
|
|||
code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char detail[2000] = {0};
|
||||
sprintf(detail, "alterType:%d, numOfFields:%d, ttl:%d" ,
|
||||
alterReq.alterType, alterReq.numOfFields, alterReq.ttl);
|
||||
|
||||
SName name = {0};
|
||||
tNameFromString(&name, pDb->name, T_NAME_ACCT | T_NAME_DB);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "alterStb", name.dbname, alterReq.name, detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("stb:%s, failed to alter since %s", alterReq.name, terrstr());
|
||||
|
@ -2502,6 +2527,15 @@ static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
|
|||
code = mndDropStb(pMnode, pReq, pDb, pStb);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char detail[2000] = {0};
|
||||
sprintf(detail, "igNotExists:%d, source:%d" ,
|
||||
dropReq.igNotExists, dropReq.source);
|
||||
|
||||
SName name = {0};
|
||||
tNameFromString(&name, pDb->name, T_NAME_ACCT | T_NAME_DB);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "dropStb", name.dbname, dropReq.name, detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("stb:%s, failed to drop since %s", dropReq.name, terrstr());
|
||||
|
@ -3233,136 +3267,161 @@ static int32_t buildDbColsInfoBlock(const SSDataBlock *p, const SSysTableMeta *p
|
|||
|
||||
return numOfRows;
|
||||
}
|
||||
#define BUILD_COL_FOR_INFO_DB 1
|
||||
#define BUILD_COL_FOR_PERF_DB 1 << 1
|
||||
#define BUILD_COL_FOR_USER_DB 1 << 2
|
||||
#define BUILD_COL_FOR_ALL_DB (BUILD_COL_FOR_INFO_DB | BUILD_COL_FOR_PERF_DB | BUILD_COL_FOR_USER_DB)
|
||||
|
||||
static int32_t buildSysDbColsInfo(SSDataBlock *p, char *db, char *tb) {
|
||||
static int32_t buildSysDbColsInfo(SSDataBlock *p, int8_t buildWhichDBs, char *tb) {
|
||||
size_t size = 0;
|
||||
const SSysTableMeta *pSysDbTableMeta = NULL;
|
||||
|
||||
if (db[0] && strncmp(db, TSDB_INFORMATION_SCHEMA_DB, TSDB_DB_FNAME_LEN) != 0 &&
|
||||
strncmp(db, TSDB_PERFORMANCE_SCHEMA_DB, TSDB_DB_FNAME_LEN) != 0) {
|
||||
return p->info.rows;
|
||||
if (buildWhichDBs & BUILD_COL_FOR_INFO_DB) {
|
||||
getInfosDbMeta(&pSysDbTableMeta, &size);
|
||||
p->info.rows = buildDbColsInfoBlock(p, pSysDbTableMeta, size, TSDB_INFORMATION_SCHEMA_DB, tb);
|
||||
}
|
||||
|
||||
getInfosDbMeta(&pSysDbTableMeta, &size);
|
||||
p->info.rows = buildDbColsInfoBlock(p, pSysDbTableMeta, size, TSDB_INFORMATION_SCHEMA_DB, tb);
|
||||
|
||||
getPerfDbMeta(&pSysDbTableMeta, &size);
|
||||
p->info.rows = buildDbColsInfoBlock(p, pSysDbTableMeta, size, TSDB_PERFORMANCE_SCHEMA_DB, tb);
|
||||
if (buildWhichDBs & BUILD_COL_FOR_PERF_DB) {
|
||||
getPerfDbMeta(&pSysDbTableMeta, &size);
|
||||
p->info.rows = buildDbColsInfoBlock(p, pSysDbTableMeta, size, TSDB_PERFORMANCE_SCHEMA_DB, tb);
|
||||
}
|
||||
|
||||
return p->info.rows;
|
||||
}
|
||||
|
||||
static int8_t determineBuildColForWhichDBs(const char* db) {
|
||||
int8_t buildWhichDBs;
|
||||
if (!db[0])
|
||||
buildWhichDBs = BUILD_COL_FOR_ALL_DB;
|
||||
else {
|
||||
char *p = strchr(db, '.');
|
||||
if (p && strcmp(p + 1, TSDB_INFORMATION_SCHEMA_DB) == 0) {
|
||||
buildWhichDBs = BUILD_COL_FOR_INFO_DB;
|
||||
} else if (p && strcmp(p + 1, TSDB_PERFORMANCE_SCHEMA_DB) == 0) {
|
||||
buildWhichDBs = BUILD_COL_FOR_PERF_DB;
|
||||
} else {
|
||||
buildWhichDBs = BUILD_COL_FOR_USER_DB;
|
||||
}
|
||||
}
|
||||
return buildWhichDBs;
|
||||
}
|
||||
|
||||
static int32_t mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||
uint8_t buildWhichDBs;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStbObj *pStb = NULL;
|
||||
|
||||
int32_t numOfRows = 0;
|
||||
|
||||
buildWhichDBs = determineBuildColForWhichDBs(pShow->db);
|
||||
|
||||
if (!pShow->sysDbRsp) {
|
||||
numOfRows = buildSysDbColsInfo(pBlock, pShow->db, pShow->filterTb);
|
||||
numOfRows = buildSysDbColsInfo(pBlock, buildWhichDBs, pShow->filterTb);
|
||||
mDebug("mndRetrieveStbCol get system table cols, rows:%d, db:%s", numOfRows, pShow->db);
|
||||
pShow->sysDbRsp = true;
|
||||
}
|
||||
|
||||
SDbObj *pDb = NULL;
|
||||
if (strlen(pShow->db) > 0) {
|
||||
pDb = mndAcquireDb(pMnode, pShow->db);
|
||||
if (pDb == NULL) return terrno;
|
||||
}
|
||||
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(typeName, "SUPER_TABLE");
|
||||
bool fetch = pShow->restore ? false : true;
|
||||
pShow->restore = false;
|
||||
while (numOfRows < rows) {
|
||||
if (fetch) {
|
||||
pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
|
||||
if (pShow->pIter == NULL) break;
|
||||
} else {
|
||||
fetch = true;
|
||||
void *pKey = taosHashGetKey(pShow->pIter, NULL);
|
||||
pStb = sdbAcquire(pSdb, SDB_STB, pKey);
|
||||
if (!pStb) continue;
|
||||
if (buildWhichDBs & BUILD_COL_FOR_USER_DB) {
|
||||
SDbObj *pDb = NULL;
|
||||
if (strlen(pShow->db) > 0) {
|
||||
pDb = mndAcquireDb(pMnode, pShow->db);
|
||||
if (pDb == NULL && TSDB_CODE_MND_DB_NOT_EXIST != terrno && pBlock->info.rows == 0) return terrno;
|
||||
}
|
||||
|
||||
if (pDb != NULL && pStb->dbUid != pDb->uid) {
|
||||
sdbRelease(pSdb, pStb);
|
||||
continue;
|
||||
}
|
||||
|
||||
SName name = {0};
|
||||
char stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
|
||||
if (pShow->filterTb[0] && strncmp(pShow->filterTb, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN) != 0) {
|
||||
sdbRelease(pSdb, pStb);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((numOfRows + pStb->numOfColumns) > rows) {
|
||||
pShow->restore = true;
|
||||
if (numOfRows == 0) {
|
||||
mError("mndRetrieveStbCol failed to get stable cols since buf:%d less than result:%d, stable name:%s, db:%s",
|
||||
rows, pStb->numOfColumns, pStb->name, pStb->db);
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(typeName, "SUPER_TABLE");
|
||||
bool fetch = pShow->restore ? false : true;
|
||||
pShow->restore = false;
|
||||
while (numOfRows < rows) {
|
||||
if (fetch) {
|
||||
pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
|
||||
if (pShow->pIter == NULL) break;
|
||||
} else {
|
||||
fetch = true;
|
||||
void *pKey = taosHashGetKey(pShow->pIter, NULL);
|
||||
pStb = sdbAcquire(pSdb, SDB_STB, pKey);
|
||||
if (!pStb) continue;
|
||||
}
|
||||
sdbRelease(pSdb, pStb);
|
||||
break;
|
||||
}
|
||||
|
||||
varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
|
||||
|
||||
mDebug("mndRetrieveStbCol get stable cols, stable name:%s, db:%s", pStb->name, pStb->db);
|
||||
|
||||
char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
|
||||
tNameGetDbName(&name, varDataVal(db));
|
||||
varDataSetLen(db, strlen(varDataVal(db)));
|
||||
|
||||
for (int i = 0; i < pStb->numOfColumns; i++) {
|
||||
int32_t cols = 0;
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, (const char *)stbName, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, (const char *)db, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, typeName, false);
|
||||
|
||||
// col name
|
||||
char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(colName, pStb->pColumns[i].name);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, colName, false);
|
||||
|
||||
// col type
|
||||
int8_t colType = pStb->pColumns[i].type;
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
char colTypeStr[VARSTR_HEADER_SIZE + 32];
|
||||
int colTypeLen = sprintf(varDataVal(colTypeStr), "%s", tDataTypes[colType].name);
|
||||
if (colType == TSDB_DATA_TYPE_VARCHAR) {
|
||||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)(pStb->pColumns[i].bytes - VARSTR_HEADER_SIZE));
|
||||
} else if (colType == TSDB_DATA_TYPE_NCHAR) {
|
||||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)((pStb->pColumns[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||
if (pDb != NULL && pStb->dbUid != pDb->uid) {
|
||||
sdbRelease(pSdb, pStb);
|
||||
continue;
|
||||
}
|
||||
varDataSetLen(colTypeStr, colTypeLen);
|
||||
colDataSetVal(pColInfo, numOfRows, (char *)colTypeStr, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->pColumns[i].bytes, false);
|
||||
while (cols < pShow->numOfColumns) {
|
||||
SName name = {0};
|
||||
char stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
|
||||
if (pShow->filterTb[0] && strncmp(pShow->filterTb, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN) != 0) {
|
||||
sdbRelease(pSdb, pStb);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((numOfRows + pStb->numOfColumns) > rows) {
|
||||
pShow->restore = true;
|
||||
if (numOfRows == 0) {
|
||||
mError("mndRetrieveStbCol failed to get stable cols since buf:%d less than result:%d, stable name:%s, db:%s",
|
||||
rows, pStb->numOfColumns, pStb->name, pStb->db);
|
||||
}
|
||||
sdbRelease(pSdb, pStb);
|
||||
break;
|
||||
}
|
||||
|
||||
varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
|
||||
|
||||
mDebug("mndRetrieveStbCol get stable cols, stable name:%s, db:%s", pStb->name, pStb->db);
|
||||
|
||||
char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
|
||||
tNameGetDbName(&name, varDataVal(db));
|
||||
varDataSetLen(db, strlen(varDataVal(db)));
|
||||
|
||||
for (int i = 0; i < pStb->numOfColumns; i++) {
|
||||
int32_t cols = 0;
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, (const char *)stbName, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetNULL(pColInfo, numOfRows);
|
||||
colDataSetVal(pColInfo, numOfRows, (const char *)db, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, typeName, false);
|
||||
|
||||
// col name
|
||||
char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(colName, pStb->pColumns[i].name);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, colName, false);
|
||||
|
||||
// col type
|
||||
int8_t colType = pStb->pColumns[i].type;
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
char colTypeStr[VARSTR_HEADER_SIZE + 32];
|
||||
int colTypeLen = sprintf(varDataVal(colTypeStr), "%s", tDataTypes[colType].name);
|
||||
if (colType == TSDB_DATA_TYPE_VARCHAR) {
|
||||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)(pStb->pColumns[i].bytes - VARSTR_HEADER_SIZE));
|
||||
} else if (colType == TSDB_DATA_TYPE_NCHAR) {
|
||||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)((pStb->pColumns[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||
}
|
||||
varDataSetLen(colTypeStr, colTypeLen);
|
||||
colDataSetVal(pColInfo, numOfRows, (char *)colTypeStr, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->pColumns[i].bytes, false);
|
||||
while (cols < pShow->numOfColumns) {
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetNULL(pColInfo, numOfRows);
|
||||
}
|
||||
numOfRows++;
|
||||
}
|
||||
numOfRows++;
|
||||
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
if (pDb != NULL) {
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
if (pDb != NULL) {
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
}
|
||||
}
|
||||
|
||||
pShow->numOfRows += numOfRows;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "parser.h"
|
||||
#include "tmisce.h"
|
||||
#include "tname.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define MND_STREAM_VER_NUMBER 3
|
||||
#define MND_STREAM_RESERVE_SIZE 64
|
||||
|
@ -872,6 +873,20 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
|
||||
code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char detail[2000] = {0};
|
||||
sprintf(detail, "checkpointFreq:%" PRId64 ", createStb:%d, deleteMark:%" PRId64 ", "
|
||||
"fillHistory:%d, igExists:%d, "
|
||||
"igExpired:%d, igUpdate:%d, lastTs:%" PRId64 ", "
|
||||
"maxDelay:%" PRId64 ", numOfTags:%d, sourceDB:%s, "
|
||||
"targetStbFullName:%s, triggerType:%d, watermark:%" PRId64,
|
||||
createStreamReq.checkpointFreq, createStreamReq.createStb, createStreamReq.deleteMark,
|
||||
createStreamReq.fillHistory, createStreamReq.igExists,
|
||||
createStreamReq.igExpired, createStreamReq.igUpdate, createStreamReq.lastTs,
|
||||
createStreamReq.maxDelay, createStreamReq.numOfTags, createStreamReq.sourceDB,
|
||||
createStreamReq.targetStbFullName, createStreamReq.triggerType, createStreamReq.watermark);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createStream", createStreamReq.name, "", detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("stream:%s, failed to create since %s", createStreamReq.name, terrstr());
|
||||
|
@ -1301,6 +1316,11 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
char detail[100] = {0};
|
||||
sprintf(detail, "igNotExists:%d", dropReq.igNotExists);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "dropStream", dropReq.name, "", detail);
|
||||
|
||||
sdbRelease(pMnode->pSdb, pStream);
|
||||
mndTransDrop(pTrans);
|
||||
|
||||
|
|
|
@ -553,13 +553,17 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
|||
}
|
||||
}
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pMsg, "tmq-reb");
|
||||
char topic[TSDB_TOPIC_FNAME_LEN] = {0};
|
||||
char cgroup[TSDB_CGROUP_LEN] = {0};
|
||||
mndSplitSubscribeKey(pOutput->pSub->key, topic, cgroup, true);
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_TOPIC_INSIDE, pMsg, "tmq-reb");
|
||||
if (pTrans == NULL) {
|
||||
nodesDestroyNode((SNode*)pPlan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mndTransSetDbName(pTrans, pOutput->pSub->dbName, NULL);
|
||||
mndTransSetDbName(pTrans, topic, cgroup);
|
||||
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||
mndTransDrop(pTrans);
|
||||
nodesDestroyNode((SNode*)pPlan);
|
||||
|
@ -587,10 +591,6 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
|||
return -1;
|
||||
}
|
||||
|
||||
char topic[TSDB_TOPIC_FNAME_LEN] = {0};
|
||||
char cgroup[TSDB_CGROUP_LEN] = {0};
|
||||
mndSplitSubscribeKey(pOutput->pSub->key, topic, cgroup, true);
|
||||
|
||||
// 3. commit log: consumer to update status and epoch
|
||||
// 3.1 set touched consumer
|
||||
int32_t consumerNum = taosArrayGetSize(pOutput->modifyConsumers);
|
||||
|
@ -802,6 +802,19 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg) {
|
|||
goto end;
|
||||
}
|
||||
|
||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_TOPIC_INSIDE, pMsg, "drop-cgroup");
|
||||
if (pTrans == NULL) {
|
||||
mError("cgroup: %s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr());
|
||||
code = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
mndTransSetDbName(pTrans, dropReq.topic, dropReq.cgroup);
|
||||
code = mndTransCheckConflict(pMnode, pTrans);
|
||||
if (code != 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
void *pIter = NULL;
|
||||
SMqConsumerObj *pConsumer;
|
||||
while (1) {
|
||||
|
@ -811,18 +824,11 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
if (strcmp(dropReq.cgroup, pConsumer->cgroup) == 0) {
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId);
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pMsg->info);
|
||||
}
|
||||
sdbRelease(pMnode->pSdb, pConsumer);
|
||||
}
|
||||
|
||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "drop-cgroup");
|
||||
if (pTrans == NULL) {
|
||||
mError("cgroup: %s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr());
|
||||
code = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
mInfo("trans:%d, used to drop cgroup:%s on topic %s", pTrans->id, dropReq.cgroup, dropReq.topic);
|
||||
|
||||
if (mndSetDropSubCommitLogs(pMnode, pTrans, pSub) < 0) {
|
||||
|
@ -1019,8 +1025,8 @@ int32_t mndGetGroupNumByTopic(SMnode *pMnode, const char *topicName) {
|
|||
if (pIter == NULL) break;
|
||||
|
||||
|
||||
char topic[TSDB_TOPIC_FNAME_LEN];
|
||||
char cgroup[TSDB_CGROUP_LEN];
|
||||
char topic[TSDB_TOPIC_FNAME_LEN] = {0};
|
||||
char cgroup[TSDB_CGROUP_LEN] = {0};
|
||||
mndSplitSubscribeKey(pSub->key, topic, cgroup, true);
|
||||
if (strcmp(topic, topicName) != 0) {
|
||||
sdbRelease(pSdb, pSub);
|
||||
|
@ -1084,7 +1090,6 @@ int32_t mndDropSubByDB(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) {
|
|||
}
|
||||
|
||||
int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topicName) {
|
||||
int32_t code = -1;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
void *pIter = NULL;
|
||||
|
@ -1093,8 +1098,8 @@ int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topicName)
|
|||
pIter = sdbFetch(pSdb, SDB_SUBSCRIBE, pIter, (void **)&pSub);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
char topic[TSDB_TOPIC_FNAME_LEN];
|
||||
char cgroup[TSDB_CGROUP_LEN];
|
||||
char topic[TSDB_TOPIC_FNAME_LEN] = {0};
|
||||
char cgroup[TSDB_CGROUP_LEN] = {0};
|
||||
mndSplitSubscribeKey(pSub->key, topic, cgroup, true);
|
||||
if (strcmp(topic, topicName) != 0) {
|
||||
sdbRelease(pSdb, pSub);
|
||||
|
@ -1132,15 +1137,13 @@ int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topicName)
|
|||
if (mndSetDropSubRedoLogs(pMnode, pTrans, pSub) < 0) {
|
||||
sdbRelease(pSdb, pSub);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
goto END;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pSub);
|
||||
}
|
||||
|
||||
code = 0;
|
||||
END:
|
||||
return code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t buildResult(SSDataBlock *pBlock, int32_t* numOfRows, int64_t consumerId, const char* topic, const char* cgroup, SArray* vgs, SArray *offsetRows){
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "mndVgroup.h"
|
||||
#include "parser.h"
|
||||
#include "tname.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define MND_TOPIC_VER_NUMBER 3
|
||||
#define MND_TOPIC_RESERVE_SIZE 64
|
||||
|
@ -381,14 +382,29 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
int32_t code = -1;
|
||||
SNode *pAst = NULL;
|
||||
SQueryPlan *pPlan = NULL;
|
||||
|
||||
SMqTopicObj topicObj = {0};
|
||||
|
||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_TOPIC, pReq, "create-topic");
|
||||
if (pTrans == NULL) {
|
||||
mError("topic:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
code = -1;
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
mndTransSetDbName(pTrans, pCreate->name, NULL);
|
||||
code = mndTransCheckConflict(pMnode, pTrans);
|
||||
if (code != 0) {
|
||||
goto _OUT;
|
||||
}
|
||||
mInfo("trans:%d to create topic:%s", pTrans->id, pCreate->name);
|
||||
|
||||
tstrncpy(topicObj.name, pCreate->name, TSDB_TOPIC_FNAME_LEN);
|
||||
tstrncpy(topicObj.db, pDb->name, TSDB_DB_FNAME_LEN);
|
||||
tstrncpy(topicObj.createUser, userName, TSDB_USER_LEN);
|
||||
|
||||
if (mndCheckTopicPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_TOPIC, &topicObj) != 0) {
|
||||
return -1;
|
||||
code = mndCheckTopicPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_TOPIC, &topicObj);
|
||||
if (code != 0) {
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
topicObj.createTime = taosGetTimestampMs();
|
||||
|
@ -405,6 +421,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
if (pCreate->withMeta) {
|
||||
terrno = TSDB_CODE_MND_INVALID_TOPIC_OPTION;
|
||||
mError("topic:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
code = terrno;
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
|
@ -413,13 +430,15 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
|
||||
qDebugL("topic:%s ast %s", topicObj.name, topicObj.ast);
|
||||
|
||||
if (nodesStringToNode(pCreate->ast, &pAst) != 0) {
|
||||
code = nodesStringToNode(pCreate->ast, &pAst);
|
||||
if (code != 0) {
|
||||
mError("topic:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
SPlanContext cxt = {.pAstRoot = pAst, .topicQuery = true};
|
||||
if (qCreateQueryPlan(&cxt, &pPlan, NULL) != 0) {
|
||||
code = qCreateQueryPlan(&cxt, &pPlan, NULL);
|
||||
if (code != 0) {
|
||||
mError("failed to create topic:%s since %s", pCreate->name, terrstr());
|
||||
goto _OUT;
|
||||
}
|
||||
|
@ -427,6 +446,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
topicObj.ntbColIds = taosArrayInit(0, sizeof(int16_t));
|
||||
if (topicObj.ntbColIds == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
code = terrno;
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
|
@ -437,12 +457,14 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
topicObj.ntbColIds = NULL;
|
||||
}
|
||||
|
||||
if (qExtractResultSchema(pAst, &topicObj.schema.nCols, &topicObj.schema.pSchema) != 0) {
|
||||
code = qExtractResultSchema(pAst, &topicObj.schema.nCols, &topicObj.schema.pSchema);
|
||||
if (code != 0) {
|
||||
mError("topic:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
if (nodesNodeToString((SNode *)pPlan, false, &topicObj.physicalPlan, NULL) != 0) {
|
||||
code = nodesNodeToString((SNode *)pPlan, false, &topicObj.physicalPlan, NULL);
|
||||
if (code != 0) {
|
||||
mError("topic:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
goto _OUT;
|
||||
}
|
||||
|
@ -450,6 +472,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
SStbObj *pStb = mndAcquireStb(pMnode, pCreate->subStbName);
|
||||
if (pStb == NULL) {
|
||||
terrno = TSDB_CODE_MND_STB_NOT_EXIST;
|
||||
code = terrno;
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
|
@ -469,21 +492,10 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
/*topicObj.withTbName = 1;*/
|
||||
/*topicObj.withSchema = 1;*/
|
||||
|
||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq, "create-topic");
|
||||
if (pTrans == NULL) {
|
||||
mError("topic:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
mndTransSetDbName(pTrans, pDb->name, NULL);
|
||||
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||
goto _OUT;
|
||||
}
|
||||
mInfo("trans:%d to create topic:%s", pTrans->id, pCreate->name);
|
||||
|
||||
SSdbRaw *pCommitRaw = mndTopicActionEncode(&topicObj);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
code = -1;
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
|
@ -509,7 +521,6 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
|
||||
// encoder check alter info
|
||||
int32_t len;
|
||||
int32_t code;
|
||||
tEncodeSize(tEncodeSTqCheckInfo, &info, len, code);
|
||||
if (code < 0) {
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
|
@ -524,6 +535,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
taosMemoryFree(buf);
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
code = -1;
|
||||
goto _OUT;
|
||||
}
|
||||
tEncoderClear(&encoder);
|
||||
|
@ -538,6 +550,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
taosMemoryFree(buf);
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
code = -1;
|
||||
goto _OUT;
|
||||
}
|
||||
buf = NULL;
|
||||
|
@ -547,6 +560,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
code = -1;
|
||||
goto _OUT;
|
||||
}
|
||||
|
||||
|
@ -621,6 +635,15 @@ static int32_t mndProcessCreateTopicReq(SRpcMsg *pReq) {
|
|||
code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "igExists:%d, subStbName:%s, subType:%d, withMeta:%d",
|
||||
createTopicReq.igExists, createTopicReq.subStbName, createTopicReq.subType, createTopicReq.withMeta);
|
||||
|
||||
SName name = {0};
|
||||
tNameFromString(&name, createTopicReq.subDbName, T_NAME_ACCT | T_NAME_DB);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "crateTopic", createTopicReq.name, name.dbname, detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("failed to create topic:%s since %s", createTopicReq.name, terrstr());
|
||||
|
@ -654,16 +677,19 @@ _OVER:
|
|||
}
|
||||
|
||||
static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SMDropTopicReq dropReq = {0};
|
||||
int32_t code = 0;
|
||||
SMqTopicObj *pTopic = NULL;
|
||||
STrans *pTrans = NULL;
|
||||
|
||||
if (tDeserializeSMDropTopicReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SMqTopicObj *pTopic = mndAcquireTopic(pMnode, dropReq.name);
|
||||
pTopic = mndAcquireTopic(pMnode, dropReq.name);
|
||||
if (pTopic == NULL) {
|
||||
if (dropReq.igNotExists) {
|
||||
mInfo("topic:%s, not exist, ignore not exist is set", dropReq.name);
|
||||
|
@ -675,9 +701,29 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mndCheckTopicPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_TOPIC, pTopic) != 0) {
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
return -1;
|
||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_TOPIC, pReq, "drop-topic");
|
||||
if (pTrans == NULL) {
|
||||
mError("topic:%s, failed to drop since %s", pTopic->name, terrstr());
|
||||
code = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
mndTransSetDbName(pTrans, pTopic->name, NULL);
|
||||
code = mndTransCheckConflict(pMnode, pTrans);
|
||||
if (code != 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
mInfo("trans:%d, used to drop topic:%s", pTrans->id, pTopic->name);
|
||||
|
||||
code = mndCheckTopicPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_TOPIC, pTopic);
|
||||
if (code != 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
code = mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_READ_DB, pTopic->db);
|
||||
if (code != 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
void *pIter = NULL;
|
||||
|
@ -688,37 +734,42 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (pConsumer->status == MQ_CONSUMER_STATUS_LOST){
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId);
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
int32_t sz = taosArrayGetSize(pConsumer->assignedTopics);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
char *name = taosArrayGetP(pConsumer->assignedTopics, i);
|
||||
if (strcmp(name, pTopic->name) == 0) {
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
terrno = TSDB_CODE_MND_TOPIC_SUBSCRIBED;
|
||||
mError("topic:%s, failed to drop since subscribed by consumer:0x%" PRIx64 ", in consumer group %s",
|
||||
dropReq.name, pConsumer->consumerId, pConsumer->cgroup);
|
||||
return -1;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found){
|
||||
if (pConsumer->status == MQ_CONSUMER_STATUS_LOST) {
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pReq->info);
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
continue;
|
||||
}
|
||||
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
terrno = TSDB_CODE_MND_TOPIC_SUBSCRIBED;
|
||||
mError("topic:%s, failed to drop since subscribed by consumer:0x%" PRIx64 ", in consumer group %s",
|
||||
dropReq.name, pConsumer->consumerId, pConsumer->cgroup);
|
||||
code = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sz = taosArrayGetSize(pConsumer->rebNewTopics);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
char *name = taosArrayGetP(pConsumer->rebNewTopics, i);
|
||||
if (strcmp(name, pTopic->name) == 0) {
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
terrno = TSDB_CODE_MND_TOPIC_SUBSCRIBED;
|
||||
mError("topic:%s, failed to drop since subscribed by consumer:%" PRId64 ", in consumer group %s (reb new)",
|
||||
dropReq.name, pConsumer->consumerId, pConsumer->cgroup);
|
||||
return -1;
|
||||
code = -1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -727,45 +778,22 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
|
|||
char *name = taosArrayGetP(pConsumer->rebRemovedTopics, i);
|
||||
if (strcmp(name, pTopic->name) == 0) {
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
terrno = TSDB_CODE_MND_TOPIC_SUBSCRIBED;
|
||||
mError("topic:%s, failed to drop since subscribed by consumer:%" PRId64 ", in consumer group %s (reb remove)",
|
||||
dropReq.name, pConsumer->consumerId, pConsumer->cgroup);
|
||||
return -1;
|
||||
code = -1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pConsumer);
|
||||
}
|
||||
|
||||
if (mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_READ_DB, pTopic->db) != 0) {
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq, "drop-topic");
|
||||
if (pTrans == NULL) {
|
||||
code = mndDropSubByTopic(pMnode, pTrans, dropReq.name);
|
||||
if (code < 0) {
|
||||
mError("topic:%s, failed to drop since %s", pTopic->name, terrstr());
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mndTransSetDbName(pTrans, pTopic->db, NULL);
|
||||
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mInfo("trans:%d, used to drop topic:%s", pTrans->id, pTopic->name);
|
||||
|
||||
// TODO check if rebalancing
|
||||
if (mndDropSubByTopic(pMnode, pTrans, dropReq.name) < 0) {
|
||||
mError("topic:%s, failed to drop since %s", pTopic->name, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
return -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (pTopic->ntbUid != 0) {
|
||||
|
@ -791,27 +819,32 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
|
|||
action.pCont = buf;
|
||||
action.contLen = sizeof(SMsgHead) + TSDB_TOPIC_FNAME_LEN;
|
||||
action.msgType = TDMT_VND_TMQ_DEL_CHECKINFO;
|
||||
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
|
||||
code = mndTransAppendRedoAction(pTrans, &action);
|
||||
if (code != 0) {
|
||||
taosMemoryFree(buf);
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
goto end;
|
||||
}
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t code = mndDropTopic(pMnode, pTrans, pReq, pTopic);
|
||||
code = mndDropTopic(pMnode, pTrans, pReq, pTopic);
|
||||
|
||||
end:
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
mndTransDrop(pTrans);
|
||||
|
||||
if (code != 0) {
|
||||
mError("topic:%s, failed to drop since %s", dropReq.name, terrstr());
|
||||
return -1;
|
||||
return code;
|
||||
}
|
||||
|
||||
char detail[100] = {0};
|
||||
sprintf(detail, "igNotExists:%d", dropReq.igNotExists);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "dropTopic", dropReq.name, "", detail);
|
||||
|
||||
return TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -790,6 +790,22 @@ static bool mndCheckTransConflict(SMnode *pMnode, STrans *pNew) {
|
|||
}
|
||||
}
|
||||
|
||||
if (pNew->conflict == TRN_CONFLICT_TOPIC) {
|
||||
if (pTrans->conflict == TRN_CONFLICT_GLOBAL) conflict = true;
|
||||
if (pTrans->conflict == TRN_CONFLICT_TOPIC || pTrans->conflict == TRN_CONFLICT_TOPIC_INSIDE) {
|
||||
if (strcasecmp(pNew->dbname, pTrans->dbname) == 0 ) conflict = true;
|
||||
}
|
||||
}
|
||||
if (pNew->conflict == TRN_CONFLICT_TOPIC_INSIDE) {
|
||||
if (pTrans->conflict == TRN_CONFLICT_GLOBAL) conflict = true;
|
||||
if (pTrans->conflict == TRN_CONFLICT_TOPIC ) {
|
||||
if (strcasecmp(pNew->dbname, pTrans->dbname) == 0 ) conflict = true;
|
||||
}
|
||||
if (pTrans->conflict == TRN_CONFLICT_TOPIC_INSIDE) {
|
||||
if (strcasecmp(pNew->dbname, pTrans->dbname) == 0 && strcasecmp(pNew->stbname, pTrans->stbname) == 0) conflict = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (conflict) {
|
||||
mError("trans:%d, db:%s stb:%s type:%d, can't execute since conflict with trans:%d db:%s stb:%s type:%d",
|
||||
pNew->id, pNew->dbname, pNew->stbname, pNew->conflict, pTrans->id, pTrans->dbname, pTrans->stbname,
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "mndTopic.h"
|
||||
#include "mndTrans.h"
|
||||
#include "tbase64.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define USER_VER_NUMBER 4
|
||||
#define USER_RESERVE_SIZE 64
|
||||
|
@ -655,6 +656,12 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
|
|||
code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "createType:%d, enable:%d, superUser:%d, sysInfo:%d",
|
||||
createReq.createType, createReq.enable, createReq.superUser, createReq.sysInfo);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createUser", createReq.user, "", detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to create since %s", createReq.user, terrstr());
|
||||
|
@ -970,6 +977,48 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
|
|||
code = mndAlterUser(pMnode, pUser, &newUser, pReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "alterType:%d, enable:%d, superUser:%d, sysInfo:%d, tabName:%s",
|
||||
alterReq.alterType, alterReq.enable, alterReq.superUser, alterReq.sysInfo, alterReq.tabName);
|
||||
|
||||
if(alterReq.alterType == TSDB_ALTER_USER_PASSWD){
|
||||
auditRecord(pReq, pMnode->clusterId, "changePassword", alterReq.user, "", detail);
|
||||
}
|
||||
else if(alterReq.alterType == TSDB_ALTER_USER_SUPERUSER ||
|
||||
alterReq.alterType == TSDB_ALTER_USER_ENABLE ||
|
||||
alterReq.alterType == TSDB_ALTER_USER_SYSINFO){
|
||||
auditRecord(pReq, pMnode->clusterId, "alterUser", alterReq.user, "", detail);
|
||||
}
|
||||
else if(alterReq.alterType == TSDB_ALTER_USER_ADD_READ_DB||
|
||||
alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_DB||
|
||||
alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_DB||
|
||||
alterReq.alterType == TSDB_ALTER_USER_ADD_READ_TABLE||
|
||||
alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_TABLE||
|
||||
alterReq.alterType == TSDB_ALTER_USER_ADD_ALL_TABLE){
|
||||
if (strcmp(alterReq.objname, "1.*") != 0){
|
||||
SName name = {0};
|
||||
tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB);
|
||||
auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.user, name.dbname, detail);
|
||||
}else{
|
||||
auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.user, "*", detail);
|
||||
}
|
||||
}
|
||||
else if(alterReq.alterType == TSDB_ALTER_USER_ADD_SUBSCRIBE_TOPIC){
|
||||
auditRecord(pReq, pMnode->clusterId, "GrantPrivileges", alterReq.user, alterReq.objname, detail);
|
||||
}
|
||||
else if(alterReq.alterType == TSDB_ALTER_USER_REMOVE_SUBSCRIBE_TOPIC){
|
||||
auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.user, alterReq.objname, detail);
|
||||
}
|
||||
else{
|
||||
if (strcmp(alterReq.objname, "1.*") != 0){
|
||||
SName name = {0};
|
||||
tNameFromString(&name, alterReq.objname, T_NAME_ACCT | T_NAME_DB);
|
||||
auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.user, name.dbname, detail);
|
||||
}else{
|
||||
auditRecord(pReq, pMnode->clusterId, "RevokePrivileges", alterReq.user, "*", detail);
|
||||
}
|
||||
}
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to alter since %s", alterReq.user, terrstr());
|
||||
|
@ -1039,6 +1088,8 @@ static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
|
|||
code = mndDropUser(pMnode, pReq, pUser);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "dropUser", dropReq.user, "", "");
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to drop since %s", dropReq.user, terrstr());
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "mndTrans.h"
|
||||
#include "mndUser.h"
|
||||
#include "tmisce.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define VGROUP_VER_NUMBER 1
|
||||
#define VGROUP_RESERVE_SIZE 64
|
||||
|
@ -1090,7 +1091,7 @@ static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB
|
|||
int32_t cols = 0;
|
||||
int64_t curMs = taosGetTimestampMs();
|
||||
|
||||
while (numOfRows < rows) {
|
||||
while (numOfRows < rows - TSDB_MAX_REPLICA) {
|
||||
pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
|
||||
if (pShow->pIter == NULL) break;
|
||||
|
||||
|
@ -2171,6 +2172,15 @@ static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq) {
|
|||
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
char obj[33] = {0};
|
||||
sprintf(obj, "%d", req.vgId);
|
||||
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "dnodeId1:%d, dnodeId2:%d, dnodeId3:%d",
|
||||
req.dnodeId1, req.dnodeId2, req.dnodeId3);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "RedistributeVgroup", obj, "", detail);
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("vgId:%d, failed to redistribute to dnode %d:%d:%d since %s", req.vgId, req.dnodeId1, req.dnodeId2,
|
||||
|
@ -2981,6 +2991,8 @@ static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq) {
|
|||
code = mndBalanceVgroup(pMnode, pReq, pArray);
|
||||
}
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "balanceVgroup", "", "", "");
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("failed to balance vgroup since %s", terrstr());
|
||||
|
|
|
@ -150,6 +150,7 @@ target_link_libraries(
|
|||
PUBLIC executor
|
||||
PUBLIC scheduler
|
||||
PUBLIC tdb
|
||||
PUBLIC audit
|
||||
|
||||
# PUBLIC bdb
|
||||
# PUBLIC scalar
|
||||
|
|
|
@ -26,7 +26,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef enum DirtyEntryType {
|
||||
ENTRY_TYPE_DEL = 1,
|
||||
ENTRY_TYPE_DELETE = 1,
|
||||
ENTRY_TYPE_UPSERT = 2,
|
||||
} DirtyEntryType;
|
||||
|
||||
|
@ -44,6 +44,8 @@ typedef struct STtlManger {
|
|||
typedef struct {
|
||||
int64_t ttlDays;
|
||||
int64_t changeTimeMs;
|
||||
int64_t ttlDaysDirty;
|
||||
int64_t changeTimeMsDirty;
|
||||
} STtlCacheEntry;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -209,7 +209,8 @@ static int32_t ttlMgrFillCacheOneEntry(const void *pKey, int keyLen, const void
|
|||
int64_t ttlDays = *(int64_t *)pVal;
|
||||
int64_t changeTimeMs = ttlKey->deleteTimeMs - ttlDays * tsTtlUnit * 1000;
|
||||
|
||||
STtlCacheEntry data = {.ttlDays = ttlDays, .changeTimeMs = changeTimeMs};
|
||||
STtlCacheEntry data = {
|
||||
.ttlDays = ttlDays, .changeTimeMs = changeTimeMs, .ttlDaysDirty = ttlDays, .changeTimeMsDirty = changeTimeMs};
|
||||
|
||||
return taosHashPut(pCache, &uid, sizeof(uid), &data, sizeof(data));
|
||||
}
|
||||
|
@ -257,34 +258,37 @@ static int32_t ttlMgrFindExpiredOneEntry(const void *pKey, int keyLen, const voi
|
|||
static int ttlMgrConvert(TTB *pOldTtlIdx, TTB *pNewTtlIdx, void *pMeta) {
|
||||
SMeta *meta = pMeta;
|
||||
|
||||
metaInfo("ttlMgr convert ttl start.");
|
||||
metaInfo("ttlMgr convert start.");
|
||||
|
||||
SConvertData cvData = {.pNewTtlIdx = pNewTtlIdx, .pMeta = meta};
|
||||
|
||||
int ret = tdbTbTraversal(pOldTtlIdx, &cvData, ttlMgrConvertOneEntry);
|
||||
if (ret < 0) {
|
||||
metaError("failed to convert ttl since %s", tstrerror(terrno));
|
||||
metaError("failed to convert since %s", tstrerror(terrno));
|
||||
}
|
||||
|
||||
metaInfo("ttlMgr convert ttl end.");
|
||||
metaInfo("ttlMgr convert end.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ttlMgrInsertTtl(STtlManger *pTtlMgr, const STtlUpdTtlCtx *updCtx) {
|
||||
if (updCtx->ttlDays == 0) return 0;
|
||||
|
||||
STtlCacheEntry cacheEntry = {.ttlDays = updCtx->ttlDays, .changeTimeMs = updCtx->changeTimeMs};
|
||||
STtlCacheEntry cacheEntry = {.ttlDays = updCtx->ttlDays,
|
||||
.changeTimeMs = updCtx->changeTimeMs,
|
||||
.ttlDaysDirty = updCtx->ttlDays,
|
||||
.changeTimeMsDirty = updCtx->changeTimeMs};
|
||||
STtlDirtyEntry dirtryEntry = {.type = ENTRY_TYPE_UPSERT};
|
||||
|
||||
int ret = taosHashPut(pTtlMgr->pTtlCache, &updCtx->uid, sizeof(updCtx->uid), &cacheEntry, sizeof(cacheEntry));
|
||||
if (ret < 0) {
|
||||
metaError("%s, ttlMgr insert failed to update ttl cache since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
metaError("%s, ttlMgr insert failed to update cache since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
ret = taosHashPut(pTtlMgr->pDirtyUids, &updCtx->uid, sizeof(updCtx->uid), &dirtryEntry, sizeof(dirtryEntry));
|
||||
if (ret < 0) {
|
||||
metaError("%s, ttlMgr insert failed to update ttl dirty uids since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
metaError("%s, ttlMgr insert failed to update dirty uids since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
|
@ -304,11 +308,11 @@ _out:
|
|||
int ttlMgrDeleteTtl(STtlManger *pTtlMgr, const STtlDelTtlCtx *delCtx) {
|
||||
if (delCtx->ttlDays == 0) return 0;
|
||||
|
||||
STtlDirtyEntry dirtryEntry = {.type = ENTRY_TYPE_DEL};
|
||||
STtlDirtyEntry dirtryEntry = {.type = ENTRY_TYPE_DELETE};
|
||||
|
||||
int ret = taosHashPut(pTtlMgr->pDirtyUids, &delCtx->uid, sizeof(delCtx->uid), &dirtryEntry, sizeof(dirtryEntry));
|
||||
if (ret < 0) {
|
||||
metaError("%s, ttlMgr del failed to update ttl dirty uids since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
metaError("%s, ttlMgr del failed to update dirty uids since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
|
@ -332,19 +336,22 @@ int ttlMgrUpdateChangeTime(STtlManger *pTtlMgr, const STtlUpdCtimeCtx *pUpdCtime
|
|||
goto _out;
|
||||
}
|
||||
|
||||
STtlCacheEntry cacheEntry = {.ttlDays = oldData->ttlDays, .changeTimeMs = pUpdCtimeCtx->changeTimeMs};
|
||||
STtlCacheEntry cacheEntry = {.ttlDays = oldData->ttlDays,
|
||||
.changeTimeMs = oldData->changeTimeMs,
|
||||
.ttlDaysDirty = oldData->ttlDays,
|
||||
.changeTimeMsDirty = pUpdCtimeCtx->changeTimeMs};
|
||||
STtlDirtyEntry dirtryEntry = {.type = ENTRY_TYPE_UPSERT};
|
||||
|
||||
ret = taosHashPut(pTtlMgr->pTtlCache, &pUpdCtimeCtx->uid, sizeof(pUpdCtimeCtx->uid), &cacheEntry, sizeof(cacheEntry));
|
||||
if (ret < 0) {
|
||||
metaError("%s, ttlMgr update ctime failed to update ttl cache since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
metaError("%s, ttlMgr update ctime failed to update cache since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
ret = taosHashPut(pTtlMgr->pDirtyUids, &pUpdCtimeCtx->uid, sizeof(pUpdCtimeCtx->uid), &dirtryEntry,
|
||||
sizeof(dirtryEntry));
|
||||
if (ret < 0) {
|
||||
metaError("%s, ttlMgr update ctime failed to update ttl dirty uids since %s", pTtlMgr->logPrefix,
|
||||
metaError("%s, ttlMgr update ctime failed to update dirty uids since %s", pTtlMgr->logPrefix,
|
||||
tstrerror(terrno));
|
||||
goto _out;
|
||||
}
|
||||
|
@ -396,27 +403,35 @@ int ttlMgrFlush(STtlManger *pTtlMgr, TXN *pTxn) {
|
|||
STtlIdxKeyV1 ttlKey;
|
||||
ttlMgrBuildKey(&ttlKey, cacheEntry->ttlDays, cacheEntry->changeTimeMs, *pUid);
|
||||
|
||||
STtlIdxKeyV1 ttlKeyDirty;
|
||||
ttlMgrBuildKey(&ttlKeyDirty, cacheEntry->ttlDaysDirty, cacheEntry->changeTimeMsDirty, *pUid);
|
||||
|
||||
if (pEntry->type == ENTRY_TYPE_UPSERT) {
|
||||
ret = tdbTbUpsert(pTtlMgr->pTtlIdx, &ttlKey, sizeof(ttlKey), &cacheEntry->ttlDays, sizeof(cacheEntry->ttlDays),
|
||||
pTxn);
|
||||
// delete old key & upsert new key
|
||||
tdbTbDelete(pTtlMgr->pTtlIdx, &ttlKey, sizeof(ttlKey), pTxn); // maybe first insert, ignore error
|
||||
ret = tdbTbUpsert(pTtlMgr->pTtlIdx, &ttlKeyDirty, sizeof(ttlKeyDirty), &cacheEntry->ttlDaysDirty,
|
||||
sizeof(cacheEntry->ttlDaysDirty), pTxn);
|
||||
if (ret < 0) {
|
||||
metaError("%s, ttlMgr flush failed to flush ttl cache upsert since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
metaError("%s, ttlMgr flush failed to upsert since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
goto _out;
|
||||
}
|
||||
} else if (pEntry->type == ENTRY_TYPE_DEL) {
|
||||
|
||||
cacheEntry->ttlDays = cacheEntry->ttlDaysDirty;
|
||||
cacheEntry->changeTimeMs = cacheEntry->changeTimeMsDirty;
|
||||
} else if (pEntry->type == ENTRY_TYPE_DELETE) {
|
||||
ret = tdbTbDelete(pTtlMgr->pTtlIdx, &ttlKey, sizeof(ttlKey), pTxn);
|
||||
if (ret < 0) {
|
||||
metaError("%s, ttlMgr flush failed to flush ttl cache del since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
metaError("%s, ttlMgr flush failed to delete since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
ret = taosHashRemove(pTtlMgr->pTtlCache, pUid, sizeof(*pUid));
|
||||
if (ret < 0) {
|
||||
metaError("%s, ttlMgr flush failed to delete ttl cache since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
metaError("%s, ttlMgr flush failed to remove cache since %s", pTtlMgr->logPrefix, tstrerror(terrno));
|
||||
goto _out;
|
||||
}
|
||||
} else {
|
||||
metaError("%s, ttlMgr flush failed to flush ttl cache, unknown type: %d", pTtlMgr->logPrefix, pEntry->type);
|
||||
metaError("%s, ttlMgr flush failed, unknown type: %d", pTtlMgr->logPrefix, pEntry->type);
|
||||
goto _out;
|
||||
}
|
||||
|
||||
|
|
|
@ -666,6 +666,8 @@ int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
|||
walCloseRef(pTq->pVnode->pWal, pHandle->pRef->refId);
|
||||
}
|
||||
|
||||
tqUnregisterPushHandle(pTq, pHandle);
|
||||
|
||||
code = taosHashRemove(pTq->pHandle, pReq->subKey, strlen(pReq->subKey));
|
||||
if (code != 0) {
|
||||
tqError("cannot process tq delete req %s, since no such handle", pReq->subKey);
|
||||
|
@ -767,20 +769,7 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
|||
tqInfo("vgId:%d switch consumer from Id:0x%" PRIx64 " to Id:0x%" PRIx64, req.vgId, pHandle->consumerId,
|
||||
req.newConsumerId);
|
||||
atomic_store_64(&pHandle->consumerId, req.newConsumerId);
|
||||
// atomic_add_fetch_32(&pHandle->epoch, 1);
|
||||
|
||||
// kill executing task
|
||||
// if(tqIsHandleExec(pHandle)) {
|
||||
// qTaskInfo_t pTaskInfo = pHandle->execHandle.task;
|
||||
// if (pTaskInfo != NULL) {
|
||||
// qKillTask(pTaskInfo, TSDB_CODE_SUCCESS);
|
||||
// }
|
||||
|
||||
// if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
// qStreamCloseTsdbReader(pTaskInfo);
|
||||
// }
|
||||
// }
|
||||
// remove if it has been register in the push manager, and return one empty block to consumer
|
||||
atomic_store_32(&pHandle->epoch, 0);
|
||||
tqUnregisterPushHandle(pTq, pHandle);
|
||||
ret = tqMetaSaveHandle(pTq, req.subKey, pHandle);
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ int32_t extractMsgFromWal(SWalReader* pReader, void** pItem, int64_t maxVer, con
|
|||
}
|
||||
|
||||
SWalCont* pCont = &pReader->pHead->head;
|
||||
int64_t ver = pCont->version;
|
||||
int64_t ver = pCont->version;
|
||||
if (ver > maxVer) {
|
||||
tqDebug("maxVer in WAL:%" PRId64 " reached current:%" PRId64 ", do not scan wal anymore, %s", maxVer, ver, id);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* pReader, const int32_t* slotIds,
|
||||
const int32_t* dstSlotIds, void** pRes, const char* idStr) {
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
bool allNullRow = true;
|
||||
// bool allNullRow = true;
|
||||
|
||||
if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST)) {
|
||||
for (int32_t i = 0; i < pReader->numOfCols; ++i) {
|
||||
|
@ -36,7 +36,7 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
|
||||
p->ts = pColVal->ts;
|
||||
p->isNull = !COL_VAL_IS_VALUE(&pColVal->colVal);
|
||||
allNullRow = p->isNull & allNullRow;
|
||||
// allNullRow = p->isNull & allNullRow;
|
||||
|
||||
if (!p->isNull) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
|
@ -56,7 +56,8 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
colDataSetVal(pColInfoData, numOfRows, (const char*)pRes[i], false);
|
||||
}
|
||||
|
||||
pBlock->info.rows += allNullRow ? 0 : 1;
|
||||
// pBlock->info.rows += allNullRow ? 0 : 1;
|
||||
++pBlock->info.rows;
|
||||
} else if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST_ROW)) {
|
||||
for (int32_t i = 0; i < pReader->numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]);
|
||||
|
@ -65,7 +66,7 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, i);
|
||||
SColVal* pVal = &pColVal->colVal;
|
||||
|
||||
allNullRow = false;
|
||||
// allNullRow = false;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
if (!COL_VAL_IS_VALUE(&pColVal->colVal)) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
|
@ -80,7 +81,8 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
}
|
||||
}
|
||||
|
||||
pBlock->info.rows += allNullRow ? 0 : 1;
|
||||
// pBlock->info.rows += allNullRow ? 0 : 1;
|
||||
++pBlock->info.rows;
|
||||
} else {
|
||||
tsdbError("invalid retrieve type:%d, %s", pReader->type, idStr);
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
|
|
|
@ -235,36 +235,33 @@ static int32_t tsdbCommitOpenReader(SCommitter2 *committer) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
ASSERT(TARRAY2_SIZE(committer->ctx->fset->lvlArr) == 1);
|
||||
SSttLvl *lvl;
|
||||
TARRAY2_FOREACH(committer->ctx->fset->lvlArr, lvl) {
|
||||
STFileObj *fobj = NULL;
|
||||
TARRAY2_FOREACH(lvl->fobjArr, fobj) {
|
||||
SSttFileReader *sttReader;
|
||||
|
||||
SSttLvl *lvl = TARRAY2_FIRST(committer->ctx->fset->lvlArr);
|
||||
SSttFileReaderConfig config = {
|
||||
.tsdb = committer->tsdb,
|
||||
.szPage = committer->szPage,
|
||||
.file = fobj->f[0],
|
||||
};
|
||||
|
||||
ASSERT(lvl->level == 0);
|
||||
code = tsdbSttFileReaderOpen(fobj->fname, &config, &sttReader);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
STFileObj *fobj = NULL;
|
||||
TARRAY2_FOREACH(lvl->fobjArr, fobj) {
|
||||
SSttFileReader *sttReader;
|
||||
code = TARRAY2_APPEND(committer->sttReaderArray, sttReader);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
SSttFileReaderConfig config = {
|
||||
.tsdb = committer->tsdb,
|
||||
.szPage = committer->szPage,
|
||||
.file = fobj->f[0],
|
||||
};
|
||||
STFileOp op = {
|
||||
.optype = TSDB_FOP_REMOVE,
|
||||
.fid = fobj->f->fid,
|
||||
.of = fobj->f[0],
|
||||
};
|
||||
|
||||
code = tsdbSttFileReaderOpen(fobj->fname, &config, &sttReader);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
code = TARRAY2_APPEND(committer->sttReaderArray, sttReader);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
STFileOp op = {
|
||||
.optype = TSDB_FOP_REMOVE,
|
||||
.fid = fobj->f->fid,
|
||||
.of = fobj->f[0],
|
||||
};
|
||||
|
||||
code = TARRAY2_APPEND(committer->fopArray, op);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = TARRAY2_APPEND(committer->fopArray, op);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "tsdbFS2.h"
|
||||
#include "tsdbUpgrade.h"
|
||||
#include "vnd.h"
|
||||
#include "vndCos.h"
|
||||
|
||||
extern int vnodeScheduleTask(int (*execute)(void *), void *arg);
|
||||
extern int vnodeScheduleTaskEx(int tpid, int (*execute)(void *), void *arg);
|
||||
|
@ -365,6 +366,14 @@ static int32_t tsdbFSDoScanAndFixFile(STFileSystem *fs, const STFileObj *fobj) {
|
|||
|
||||
// check file existence
|
||||
if (!taosCheckExistFile(fobj->fname)) {
|
||||
if (tsS3Enabled) {
|
||||
const char *object_name = taosDirEntryBaseName((char *)fobj->fname);
|
||||
long s3_size = s3Size(object_name);
|
||||
if (s3_size > 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
tsdbError("vgId:%d %s failed since file:%s does not exist", TD_VID(fs->tsdb->pVnode), __func__, fobj->fname);
|
||||
return code;
|
||||
|
@ -628,7 +637,7 @@ _exit:
|
|||
} else {
|
||||
tsdbInfo("vgId:%d %s success", TD_VID(pTsdb->pVnode), __func__);
|
||||
}
|
||||
return 0;
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t close_file_system(STFileSystem *fs) {
|
||||
|
@ -721,7 +730,7 @@ _exit:
|
|||
} else {
|
||||
tsdbInfo("vgId:%d %s success", TD_VID(pTsdb->pVnode), __func__);
|
||||
}
|
||||
return 0;
|
||||
return code;
|
||||
}
|
||||
|
||||
static void tsdbDoWaitBgTask(STFileSystem *fs, STFSBgTask *task) {
|
||||
|
|
|
@ -5608,4 +5608,4 @@ void tsdbReaderSetId(STsdbReader* pReader, const char* idstr) {
|
|||
pReader->idStr = taosStrdup(idstr);
|
||||
}
|
||||
|
||||
void tsdbReaderSetCloseFlag(STsdbReader* pReader) { pReader->code = TSDB_CODE_TSC_QUERY_CANCELLED; }
|
||||
void tsdbReaderSetCloseFlag(STsdbReader* pReader) { /*pReader->code = TSDB_CODE_TSC_QUERY_CANCELLED;*/ }
|
||||
|
|
|
@ -1268,7 +1268,7 @@ static void getBlockToLoadInfo(SDataBlockToLoadInfo* pInfo, SFileDataBlockInfo*
|
|||
}
|
||||
|
||||
// has duplicated ts of different version in this block
|
||||
pInfo->hasDupTs = (pBlockInfo->record.numRow > pBlockInfo->record.count);
|
||||
pInfo->hasDupTs = (pBlockInfo->record.numRow > pBlockInfo->record.count) || (pBlockInfo->record.count <= 0);
|
||||
pInfo->overlapWithDelInfo = overlapWithDelSkyline(pScanInfo, &pBlockInfo->record, pReader->info.order);
|
||||
|
||||
if (hasDataInLastBlock(pLastBlockReader)) {
|
||||
|
|
|
@ -26,8 +26,8 @@ static int32_t tsdbOpenFileImpl(STsdbFD *pFD) {
|
|||
if (pFD->pFD == NULL) {
|
||||
int errsv = errno;
|
||||
const char *object_name = taosDirEntryBaseName((char *)path);
|
||||
long s3_size = s3Size(object_name);
|
||||
if (!strncmp(path + strlen(path) - 5, ".data", 5) && s3_size > 0) {
|
||||
long s3_size = tsS3Enabled ? s3Size(object_name) : 0;
|
||||
if (tsS3Enabled && !strncmp(path + strlen(path) - 5, ".data", 5) && s3_size > 0) {
|
||||
s3EvictCache(path, s3_size);
|
||||
s3Get(object_name, path);
|
||||
|
||||
|
|
|
@ -338,6 +338,17 @@ static int32_t tsdbDoRetention2(void *arg) {
|
|||
code = tsdbMigrateDataFileS3(rtner, fobj, &did);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
} else {
|
||||
if (tsS3Enabled) {
|
||||
int64_t fsize = 0;
|
||||
if (taosStatFile(fobj->fname, &fsize, NULL, NULL) < 0) {
|
||||
code = TAOS_SYSTEM_ERROR(terrno);
|
||||
tsdbError("vgId:%d %s failed since file:%s stat failed, reason:%s", TD_VID(rtner->tsdb->pVnode), __func__,
|
||||
fobj->fname, tstrerror(code));
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
s3EvictCache(fobj->fname, fsize * 2);
|
||||
}
|
||||
|
||||
code = tsdbDoMigrateFileObj(rtner, fobj, &did);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
|
|
@ -120,7 +120,15 @@ static int32_t tsdbUpgradeHead(STsdb *tsdb, SDFileSet *pDFileSet, SDataFReader *
|
|||
};
|
||||
|
||||
if (dataBlk->hasDup) {
|
||||
code = tsdbReadDataBlockEx(reader, dataBlk, ctx->blockData);
|
||||
tBlockDataReset(ctx->blockData);
|
||||
|
||||
int16_t aCid = 0;
|
||||
STSchema tSchema = {0};
|
||||
TABLEID tbid = {.suid = pBlockIdx->suid, .uid = pBlockIdx->uid};
|
||||
code = tBlockDataInit(ctx->blockData, &tbid, &tSchema, &aCid, 0);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
code = tsdbReadDataBlock(reader, dataBlk, ctx->blockData);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
record.count = 1;
|
||||
|
@ -334,6 +342,8 @@ static int32_t tsdbUpgradeFileSet(STsdb *tsdb, SDFileSet *pDFileSet, TFileSetArr
|
|||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
tsdbInfo("vgId:%d upgrade file set start, fid:%d", TD_VID(tsdb->pVnode), pDFileSet->fid);
|
||||
|
||||
SDataFReader *reader;
|
||||
STFileSet *fset;
|
||||
|
||||
|
@ -366,6 +376,8 @@ static int32_t tsdbUpgradeFileSet(STsdb *tsdb, SDFileSet *pDFileSet, TFileSetArr
|
|||
code = TARRAY2_APPEND(fileSetArray, fset);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
tsdbInfo("vgId:%d upgrade file set end, fid:%d", TD_VID(tsdb->pVnode), pDFileSet->fid);
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
TSDB_ERROR_LOG(TD_VID(tsdb->pVnode), lino, code);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "vndCos.h"
|
||||
#include "vnode.h"
|
||||
#include "vnodeInt.h"
|
||||
#include "audit.h"
|
||||
|
||||
static int32_t vnodeProcessCreateStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessAlterStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
|
@ -940,6 +941,14 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq,
|
|||
}
|
||||
|
||||
taosArrayPush(rsp.pArray, &cRsp);
|
||||
|
||||
int32_t clusterId = pVnode->config.syncCfg.nodeInfo[0].clusterId;
|
||||
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "btime:%" PRId64 ", flags:%d, ttl:%d, type:%d",
|
||||
pCreateReq->btime, pCreateReq->flags, pCreateReq->ttl, pCreateReq->type);
|
||||
|
||||
auditRecord(pReq, clusterId, "createTable", pVnode->config.dbname, pCreateReq->name, detail);
|
||||
}
|
||||
|
||||
vDebug("vgId:%d, add %d new created tables into query table list", TD_VID(pVnode), (int32_t)taosArrayGetSize(tbUids));
|
||||
|
|
|
@ -7,6 +7,7 @@ add_subdirectory(sync)
|
|||
add_subdirectory(qcom)
|
||||
add_subdirectory(nodes)
|
||||
add_subdirectory(catalog)
|
||||
add_subdirectory(audit)
|
||||
|
||||
add_subdirectory(scalar)
|
||||
add_subdirectory(function)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
aux_source_directory(src AUDIT_SRC)
|
||||
IF (TD_ENTERPRISE)
|
||||
LIST(APPEND AUDIT_SRC ${TD_ENTERPRISE_DIR}/src/plugins/audit/src/audit.c)
|
||||
ENDIF ()
|
||||
|
||||
add_library(audit STATIC ${AUDIT_SRC})
|
||||
target_include_directories(
|
||||
audit
|
||||
PUBLIC "${TD_SOURCE_DIR}/include/libs/audit"
|
||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||
)
|
||||
|
||||
target_link_libraries(audit os util common transport mnode)
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_AUDIT_INT_H_
|
||||
#define _TD_AUDIT_INT_H_
|
||||
|
||||
#include "audit.h"
|
||||
|
||||
typedef struct {
|
||||
SAuditCfg cfg;
|
||||
} SAudit;
|
||||
|
||||
#endif /*_TD_AUDIT_INT_H_*/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue