Merge branch '3.0' of https://github.com/taosdata/TDengine into enh/tsdb_optimize
This commit is contained in:
commit
d81d2790ea
|
@ -51,6 +51,11 @@ DESCRIBE [db_name.]stb_name;
|
||||||
|
|
||||||
### View tag information for all child tables in the supertable
|
### View tag information for all child tables in the supertable
|
||||||
|
|
||||||
|
```
|
||||||
|
SHOW TABLE TAGS FROM table_name [FROM db_name];
|
||||||
|
SHOW TABLE TAGS FROM [db_name.]table_name;
|
||||||
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
taos> SHOW TABLE TAGS FROM st1;
|
taos> SHOW TABLE TAGS FROM st1;
|
||||||
tbname | id | loc |
|
tbname | id | loc |
|
||||||
|
|
|
@ -101,6 +101,7 @@ Note: TDengine Enterprise Edition only.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SHOW INDEXES FROM tbl_name [FROM db_name];
|
SHOW INDEXES FROM tbl_name [FROM db_name];
|
||||||
|
SHOW INDEXES FROM [db_name.]tbl_name;
|
||||||
```
|
```
|
||||||
|
|
||||||
Shows indices that have been created.
|
Shows indices that have been created.
|
||||||
|
@ -326,6 +327,7 @@ Note that only the information about the data blocks in the data file will be di
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SHOW TAGS FROM child_table_name [FROM db_name];
|
SHOW TAGS FROM child_table_name [FROM db_name];
|
||||||
|
SHOW TAGS FROM [db_name.]child_table_name;
|
||||||
```
|
```
|
||||||
|
|
||||||
Shows all tag information in a subtable.
|
Shows all tag information in a subtable.
|
||||||
|
|
|
@ -43,6 +43,7 @@ DROP INDEX index_name;
|
||||||
````sql
|
````sql
|
||||||
```sql
|
```sql
|
||||||
SHOW INDEXES FROM tbl_name [FROM db_name];
|
SHOW INDEXES FROM tbl_name [FROM db_name];
|
||||||
|
SHOW INDEXES FROM [db_name.]tbl_name ;
|
||||||
````
|
````
|
||||||
|
|
||||||
Shows indices that have been created for the specified database or table.
|
Shows indices that have been created for the specified database or table.
|
||||||
|
|
|
@ -36,8 +36,8 @@ REST connection supports all platforms that can run Java.
|
||||||
|
|
||||||
| taos-jdbcdriver version | major changes | TDengine version |
|
| taos-jdbcdriver version | major changes | TDengine version |
|
||||||
| :---------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------: |
|
| :---------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------: |
|
||||||
| 3.2.4 | Subscription add the enable.auto.commit parameter and the unsubscribe() method in the WebSocket connection | 3.0.5.0 or later |
|
| 3.2.4 | Subscription add the enable.auto.commit parameter and the unsubscribe() method in the WebSocket connection | - |
|
||||||
| 3.2.3 | Fixed resultSet data parsing failure in some cases | 3.0.5.0 or later |
|
| 3.2.3 | Fixed resultSet data parsing failure in some cases | - |
|
||||||
| 3.2.2 | Subscription add seek function | 3.0.5.0 or later |
|
| 3.2.2 | Subscription add seek function | 3.0.5.0 or later |
|
||||||
| 3.2.1 | JDBC REST connection supports schemaless/prepareStatement over WebSocket | 3.0.3.0 or later |
|
| 3.2.1 | JDBC REST connection supports schemaless/prepareStatement over WebSocket | 3.0.3.0 or later |
|
||||||
| 3.2.0 | This version has been deprecated | - |
|
| 3.2.0 | This version has been deprecated | - |
|
||||||
|
@ -1019,11 +1019,13 @@ while(true) {
|
||||||
#### Assignment subscription Offset
|
#### Assignment subscription Offset
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
// get offset
|
||||||
long position(TopicPartition partition) throws SQLException;
|
long position(TopicPartition partition) throws SQLException;
|
||||||
Map<TopicPartition, Long> position(String topic) throws SQLException;
|
Map<TopicPartition, Long> position(String topic) throws SQLException;
|
||||||
Map<TopicPartition, Long> beginningOffsets(String topic) throws SQLException;
|
Map<TopicPartition, Long> beginningOffsets(String topic) throws SQLException;
|
||||||
Map<TopicPartition, Long> endOffsets(String topic) throws SQLException;
|
Map<TopicPartition, Long> endOffsets(String topic) throws SQLException;
|
||||||
|
|
||||||
|
// Overrides the fetch offsets that the consumer will use on the next poll(timeout).
|
||||||
void seek(TopicPartition partition, long offset) throws SQLException;
|
void seek(TopicPartition partition, long offset) throws SQLException;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -87,9 +87,9 @@ TDengine currently supports timestamp, number, character, Boolean type, and the
|
||||||
|NCHAR|str|
|
|NCHAR|str|
|
||||||
|JSON|str|
|
|JSON|str|
|
||||||
|
|
||||||
## Installation
|
## Installation Steps
|
||||||
|
|
||||||
### Preparation
|
### Pre-installation preparation
|
||||||
|
|
||||||
1. Install Python. The recent taospy package requires Python 3.6.2+. The earlier versions of taospy require Python 3.7+. The taos-ws-py package requires Python 3.7+. If Python is not available on your system, refer to the [Python BeginnersGuide](https://wiki.python.org/moin/BeginnersGuide/Download) to install it.
|
1. Install Python. The recent taospy package requires Python 3.6.2+. The earlier versions of taospy require Python 3.7+. The taos-ws-py package requires Python 3.7+. If Python is not available on your system, refer to the [Python BeginnersGuide](https://wiki.python.org/moin/BeginnersGuide/Download) to install it.
|
||||||
2. Install [pip](https://pypi.org/project/pip/). In most cases, the Python installer comes with the pip utility. If not, please refer to [pip documentation](https://pip.pypa.io/en/stable/installation/) to install it.
|
2. Install [pip](https://pypi.org/project/pip/). In most cases, the Python installer comes with the pip utility. If not, please refer to [pip documentation](https://pip.pypa.io/en/stable/installation/) to install it.
|
||||||
|
@ -275,7 +275,7 @@ Transfer-Encoding: chunked
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### Using connectors to establish connections
|
### Specify the Host and Properties to get the connection
|
||||||
|
|
||||||
The following example code assumes that TDengine is installed locally and that the default configuration is used for both FQDN and serverPort.
|
The following example code assumes that TDengine is installed locally and that the default configuration is used for both FQDN and serverPort.
|
||||||
|
|
||||||
|
@ -331,7 +331,69 @@ The parameter of `connect()` is the url of TDengine, and the protocol is `taosws
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
## Example program
|
### Priority of configuration parameters
|
||||||
|
|
||||||
|
If the configuration parameters are duplicated in the parameters or client configuration file, the priority of the parameters, from highest to lowest, are as follows:
|
||||||
|
|
||||||
|
1. Parameters in `connect` function.
|
||||||
|
2. the configuration file taos.cfg of the TDengine client driver when using a native connection.
|
||||||
|
|
||||||
|
## Usage examples
|
||||||
|
|
||||||
|
### Create database and tables
|
||||||
|
|
||||||
|
<Tabs defaultValue="rest">
|
||||||
|
<TabItem value="native" label="native connection">
|
||||||
|
|
||||||
|
```python
|
||||||
|
conn = taos.connect()
|
||||||
|
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||||
|
conn.execute("DROP DATABASE IF EXISTS test")
|
||||||
|
conn.execute("CREATE DATABASE test")
|
||||||
|
# change database. same as execute "USE db"
|
||||||
|
conn.select_db("test")
|
||||||
|
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="rest" label="REST connection">
|
||||||
|
|
||||||
|
```python
|
||||||
|
conn = taosrest.connect(url="http://localhost:6041")
|
||||||
|
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||||
|
conn.execute("DROP DATABASE IF EXISTS test")
|
||||||
|
conn.execute("CREATE DATABASE test")
|
||||||
|
conn.execute("USE test")
|
||||||
|
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="websocket" label="WebSocket connection">
|
||||||
|
|
||||||
|
```python
|
||||||
|
conn = taosws.connect(url="ws://localhost:6041")
|
||||||
|
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||||
|
conn.execute("DROP DATABASE IF EXISTS test")
|
||||||
|
conn.execute("CREATE DATABASE test")
|
||||||
|
conn.execute("USE test")
|
||||||
|
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
### Insert data
|
||||||
|
|
||||||
|
```python
|
||||||
|
conn.execute("INSERT INTO t1 USING weather TAGS(1) VALUES (now, 23.5) (now+1m, 23.5) (now+2m, 24.4)")
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
now is an internal function. The default is the current time of the client's computer. now + 1s represents the current time of the client plus 1 second, followed by the number representing the unit of time: a (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks), n (months), y (years).
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
### Basic Usage
|
### Basic Usage
|
||||||
|
|
||||||
|
@ -453,7 +515,7 @@ The `query` method of the `TaosConnection` class can be used to query data and r
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### Usage with req_id
|
### Execute SQL with reqId
|
||||||
|
|
||||||
By using the optional req_id parameter, you can specify a request ID that can be used for tracing.
|
By using the optional req_id parameter, you can specify a request ID that can be used for tracing.
|
||||||
|
|
||||||
|
@ -553,221 +615,7 @@ As the way to connect introduced above but add `req_id` argument.
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### Subscription
|
### Writing data via parameter binding
|
||||||
|
|
||||||
Connector support data subscription. For more information about subscroption, please refer to [Data Subscription](../../../develop/tmq/).
|
|
||||||
|
|
||||||
<Tabs defaultValue="native">
|
|
||||||
<TabItem value="native" label="native connection">
|
|
||||||
|
|
||||||
The `consumer` in the connector contains the subscription api.
|
|
||||||
|
|
||||||
##### Create Consumer
|
|
||||||
|
|
||||||
The syntax for creating a consumer is `consumer = Consumer(configs)`. For more subscription api parameters, please refer to [Data Subscription](../../../develop/tmq/).
|
|
||||||
|
|
||||||
```python
|
|
||||||
from taos.tmq import Consumer
|
|
||||||
|
|
||||||
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Subscribe topics
|
|
||||||
|
|
||||||
The `subscribe` function is used to subscribe to a list of topics.
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.subscribe(['topic1', 'topic2'])
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Consume
|
|
||||||
|
|
||||||
The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data.
|
|
||||||
|
|
||||||
```python
|
|
||||||
while True:
|
|
||||||
res = consumer.poll(1)
|
|
||||||
if not res:
|
|
||||||
continue
|
|
||||||
err = res.error()
|
|
||||||
if err is not None:
|
|
||||||
raise err
|
|
||||||
val = res.value()
|
|
||||||
|
|
||||||
for block in val:
|
|
||||||
print(block.fetchall())
|
|
||||||
```
|
|
||||||
|
|
||||||
##### assignment
|
|
||||||
|
|
||||||
The `assignment` function is used to get the assignment of the topic.
|
|
||||||
|
|
||||||
```python
|
|
||||||
assignments = consumer.assignment()
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Seek
|
|
||||||
|
|
||||||
The `seek` function is used to reset the assignment of the topic.
|
|
||||||
|
|
||||||
```python
|
|
||||||
tp = TopicPartition(topic='topic1', partition=0, offset=0)
|
|
||||||
consumer.seek(tp)
|
|
||||||
```
|
|
||||||
|
|
||||||
##### After consuming data
|
|
||||||
|
|
||||||
You should unsubscribe to the topics and close the consumer after consuming.
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.unsubscribe()
|
|
||||||
consumer.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Tmq subscription example
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/tmq_example.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### assignment and seek example
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
|
|
||||||
<TabItem value="websocket" label="WebSocket connection">
|
|
||||||
|
|
||||||
In addition to native connections, the connector also supports subscriptions via websockets.
|
|
||||||
|
|
||||||
##### Create Consumer
|
|
||||||
|
|
||||||
The syntax for creating a consumer is "consumer = consumer = Consumer(conf=configs)". You need to specify that the `td.connect.websocket.scheme` parameter is set to "ws" in the configuration. For more subscription api parameters, please refer to [Data Subscription](../../../develop/tmq/#create-a-consumer).
|
|
||||||
|
|
||||||
```python
|
|
||||||
import taosws
|
|
||||||
|
|
||||||
consumer = taosws.(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
|
|
||||||
```
|
|
||||||
|
|
||||||
##### subscribe topics
|
|
||||||
|
|
||||||
The `subscribe` function is used to subscribe to a list of topics.
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.subscribe(['topic1', 'topic2'])
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Consume
|
|
||||||
|
|
||||||
The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data.
|
|
||||||
|
|
||||||
```python
|
|
||||||
while True:
|
|
||||||
res = consumer.poll(timeout=1.0)
|
|
||||||
if not res:
|
|
||||||
continue
|
|
||||||
err = res.error()
|
|
||||||
if err is not None:
|
|
||||||
raise err
|
|
||||||
for block in message:
|
|
||||||
for row in block:
|
|
||||||
print(row)
|
|
||||||
```
|
|
||||||
|
|
||||||
##### assignment
|
|
||||||
|
|
||||||
The `assignment` function is used to get the assignment of the topic.
|
|
||||||
|
|
||||||
```python
|
|
||||||
assignments = consumer.assignment()
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Seek
|
|
||||||
|
|
||||||
The `seek` function is used to reset the assignment of the topic.
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.seek(topic='topic1', partition=0, offset=0)
|
|
||||||
```
|
|
||||||
|
|
||||||
##### After consuming data
|
|
||||||
|
|
||||||
You should unsubscribe to the topics and close the consumer after consuming.
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.unsubscribe()
|
|
||||||
consumer.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Subscription example
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/tmq_websocket_example.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Assignment and seek example
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
### Schemaless Insert
|
|
||||||
|
|
||||||
Connector support schemaless insert.
|
|
||||||
|
|
||||||
<Tabs defaultValue="list">
|
|
||||||
<TabItem value="list" label="List Insert">
|
|
||||||
|
|
||||||
##### Simple insert
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Insert with ttl argument
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_ttl.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Insert with req_id argument
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
|
|
||||||
<TabItem value="raw" label="Raw Insert">
|
|
||||||
|
|
||||||
##### Simple insert
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_raw.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Insert with ttl argument
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_raw_ttl.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Insert with req_id argument
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
### Parameter Binding
|
|
||||||
|
|
||||||
The Python connector provides a parameter binding api for inserting data. Similar to most databases, TDengine currently only supports the question mark `?` to indicate the parameters to be bound.
|
The Python connector provides a parameter binding api for inserting data. Similar to most databases, TDengine currently only supports the question mark `?` to indicate the parameters to be bound.
|
||||||
|
|
||||||
|
@ -898,6 +746,264 @@ stmt.close()
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
### Schemaless Writing
|
||||||
|
|
||||||
|
Connector support schemaless insert.
|
||||||
|
|
||||||
|
<Tabs defaultValue="list">
|
||||||
|
<TabItem value="list" label="List Insert">
|
||||||
|
|
||||||
|
##### Simple insert
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Insert with ttl argument
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_ttl.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Insert with req_id argument
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="raw" label="Raw Insert">
|
||||||
|
|
||||||
|
##### Simple insert
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_raw.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Insert with ttl argument
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_raw_ttl.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Insert with req_id argument
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
### Schemaless with reqId
|
||||||
|
|
||||||
|
There is a optional parameter called `req_id` in `schemaless_insert` and `schemaless_insert_raw` method. This reqId can be used to request link tracing.
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Subscription
|
||||||
|
|
||||||
|
Connector support data subscription. For more information about subscroption, please refer to [Data Subscription](../../../develop/tmq/).
|
||||||
|
|
||||||
|
#### Create a Topic
|
||||||
|
|
||||||
|
To create topic, please refer to [Data Subscription](../../../develop/tmq/#create-a-topic).
|
||||||
|
|
||||||
|
#### Create a Consumer
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="native connection">
|
||||||
|
|
||||||
|
The consumer in the connector contains the subscription api. The syntax for creating a consumer is consumer = Consumer(configs). For more subscription api parameters, please refer to [Data Subscription](../../../develop/tmq/#create-a-consumer).
|
||||||
|
|
||||||
|
```python
|
||||||
|
from taos.tmq import Consumer
|
||||||
|
|
||||||
|
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="websocket" label="WebSocket connection">
|
||||||
|
|
||||||
|
In addition to native connections, the connector also supports subscriptions via websockets.
|
||||||
|
|
||||||
|
The syntax for creating a consumer is "consumer = consumer = Consumer(conf=configs)". You need to specify that the `td.connect.websocket.scheme` parameter is set to "ws" in the configuration. For more subscription api parameters, please refer to [Data Subscription](../../../develop/tmq/#create-a-consumer).
|
||||||
|
|
||||||
|
```python
|
||||||
|
import taosws
|
||||||
|
|
||||||
|
consumer = taosws.(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### Subscribe to a Topic
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="native connection">
|
||||||
|
|
||||||
|
The `subscribe` function is used to subscribe to a list of topics.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.subscribe(['topic1', 'topic2'])
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket connection">
|
||||||
|
|
||||||
|
The `subscribe` function is used to subscribe to a list of topics.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.subscribe(['topic1', 'topic2'])
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### Consume messages
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="native connection">
|
||||||
|
|
||||||
|
The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data.
|
||||||
|
|
||||||
|
```python
|
||||||
|
while True:
|
||||||
|
res = consumer.poll(1)
|
||||||
|
if not res:
|
||||||
|
continue
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
val = res.value()
|
||||||
|
|
||||||
|
for block in val:
|
||||||
|
print(block.fetchall())
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket connection">
|
||||||
|
|
||||||
|
The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data.
|
||||||
|
|
||||||
|
```python
|
||||||
|
while True:
|
||||||
|
res = consumer.poll(timeout=1.0)
|
||||||
|
if not res:
|
||||||
|
continue
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
for block in message:
|
||||||
|
for row in block:
|
||||||
|
print(row)
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### Assignment subscription Offset
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="native connection">
|
||||||
|
|
||||||
|
The `assignment` function is used to get the assignment of the topic.
|
||||||
|
|
||||||
|
```python
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
```
|
||||||
|
|
||||||
|
The `seek` function is used to reset the assignment of the topic.
|
||||||
|
|
||||||
|
```python
|
||||||
|
tp = TopicPartition(topic='topic1', partition=0, offset=0)
|
||||||
|
consumer.seek(tp)
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket connection">
|
||||||
|
|
||||||
|
The `assignment` function is used to get the assignment of the topic.
|
||||||
|
|
||||||
|
```python
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
```
|
||||||
|
|
||||||
|
The `seek` function is used to reset the assignment of the topic.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.seek(topic='topic1', partition=0, offset=0)
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### Close subscriptions
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="native connection">
|
||||||
|
|
||||||
|
You should unsubscribe to the topics and close the consumer after consuming.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.unsubscribe()
|
||||||
|
consumer.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket connection">
|
||||||
|
|
||||||
|
You should unsubscribe to the topics and close the consumer after consuming.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.unsubscribe()
|
||||||
|
consumer.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### Full Sample Code
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="native connection">
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_example.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket connection">
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_websocket_example.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
### Other sample programs
|
### Other sample programs
|
||||||
|
|
||||||
| Example program links | Example program content |
|
| Example program links | Example program content |
|
||||||
|
|
|
@ -1022,11 +1022,13 @@ while(true) {
|
||||||
#### 指定订阅 Offset
|
#### 指定订阅 Offset
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
// 获取 offset
|
||||||
long position(TopicPartition partition) throws SQLException;
|
long position(TopicPartition partition) throws SQLException;
|
||||||
Map<TopicPartition, Long> position(String topic) throws SQLException;
|
Map<TopicPartition, Long> position(String topic) throws SQLException;
|
||||||
Map<TopicPartition, Long> beginningOffsets(String topic) throws SQLException;
|
Map<TopicPartition, Long> beginningOffsets(String topic) throws SQLException;
|
||||||
Map<TopicPartition, Long> endOffsets(String topic) throws SQLException;
|
Map<TopicPartition, Long> endOffsets(String topic) throws SQLException;
|
||||||
|
|
||||||
|
// 指定下一次 poll 中使用的 offset
|
||||||
void seek(TopicPartition partition, long offset) throws SQLException;
|
void seek(TopicPartition partition, long offset) throws SQLException;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ Python Connector 的所有数据库操作如果出现异常,都会直接抛出
|
||||||
{{#include docs/examples/python/handle_exception.py}}
|
{{#include docs/examples/python/handle_exception.py}}
|
||||||
```
|
```
|
||||||
|
|
||||||
TDengine DataType 和 Python DataType
|
## TDengine DataType 和 Python DataType
|
||||||
|
|
||||||
TDengine 目前支持时间戳、数字、字符、布尔类型,与 Python 对应类型转换如下:
|
TDengine 目前支持时间戳、数字、字符、布尔类型,与 Python 对应类型转换如下:
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ Transfer-Encoding: chunked
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### 使用连接器建立连接
|
### 指定 Host 和 Properties 获取连接
|
||||||
|
|
||||||
以下示例代码假设 TDengine 安装在本机, 且 FQDN 和 serverPort 都使用了默认配置。
|
以下示例代码假设 TDengine 安装在本机, 且 FQDN 和 serverPort 都使用了默认配置。
|
||||||
|
|
||||||
|
@ -332,8 +332,69 @@ Transfer-Encoding: chunked
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
### 配置参数的优先级
|
||||||
|
|
||||||
|
如果配置参数在参数和客户端配置文件中有重复,则参数的优先级由高到低分别如下:
|
||||||
|
|
||||||
|
1. 连接参数
|
||||||
|
2. 使用原生连接时,TDengine 客户端驱动的配置文件 taos.cfg
|
||||||
|
|
||||||
## 使用示例
|
## 使用示例
|
||||||
|
|
||||||
|
### 创建数据库和表
|
||||||
|
|
||||||
|
<Tabs defaultValue="rest">
|
||||||
|
<TabItem value="native" label="原生连接">
|
||||||
|
|
||||||
|
```python
|
||||||
|
conn = taos.connect()
|
||||||
|
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||||
|
conn.execute("DROP DATABASE IF EXISTS test")
|
||||||
|
conn.execute("CREATE DATABASE test")
|
||||||
|
# change database. same as execute "USE db"
|
||||||
|
conn.select_db("test")
|
||||||
|
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="rest" label="REST 连接">
|
||||||
|
|
||||||
|
```python
|
||||||
|
conn = taosrest.connect(url="http://localhost:6041")
|
||||||
|
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||||
|
conn.execute("DROP DATABASE IF EXISTS test")
|
||||||
|
conn.execute("CREATE DATABASE test")
|
||||||
|
conn.execute("USE test")
|
||||||
|
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="websocket" label="WebSocket 连接">
|
||||||
|
|
||||||
|
```python
|
||||||
|
conn = taosws.connect(url="ws://localhost:6041")
|
||||||
|
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||||
|
conn.execute("DROP DATABASE IF EXISTS test")
|
||||||
|
conn.execute("CREATE DATABASE test")
|
||||||
|
conn.execute("USE test")
|
||||||
|
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
### 插入数据
|
||||||
|
|
||||||
|
```python
|
||||||
|
conn.execute("INSERT INTO t1 USING weather TAGS(1) VALUES (now, 23.5) (now+1m, 23.5) (now+2m, 24.4)")
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
now 为系统内部函数,默认为客户端所在计算机当前时间。 now + 1s 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。
|
||||||
|
:::
|
||||||
|
|
||||||
### 基本使用
|
### 基本使用
|
||||||
|
|
||||||
<Tabs defaultValue="rest">
|
<Tabs defaultValue="rest">
|
||||||
|
@ -372,7 +433,6 @@ Transfer-Encoding: chunked
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能跨线程共享使用,否则会导致返回结果出现错误。
|
TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能跨线程共享使用,否则会导致返回结果出现错误。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
@ -455,7 +515,7 @@ RestClient 类是对于 REST API 的直接封装。它只包含一个 sql() 方
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### 与 req_id 一起使用
|
### 执行带有 reqId 的 SQL
|
||||||
|
|
||||||
使用可选的 req_id 参数,指定请求 id,可以用于 tracing
|
使用可选的 req_id 参数,指定请求 id,可以用于 tracing
|
||||||
|
|
||||||
|
@ -556,224 +616,6 @@ RestClient 类是对于 REST API 的直接封装。它只包含一个 sql() 方
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### 数据订阅
|
|
||||||
|
|
||||||
连接器支持数据订阅功能,数据订阅功能请参考 [数据订阅文档](../../develop/tmq/)。
|
|
||||||
|
|
||||||
<Tabs defaultValue="native">
|
|
||||||
<TabItem value="native" label="原生连接">
|
|
||||||
|
|
||||||
`Consumer` 提供了 Python 连接器订阅 TMQ 数据的 API。
|
|
||||||
|
|
||||||
##### 创建 Consumer
|
|
||||||
|
|
||||||
创建 Consumer 语法为 `consumer = Consumer(configs)`,参数定义请参考 [数据订阅文档](../../develop/tmq/#%E5%88%9B%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85-consumer)。
|
|
||||||
|
|
||||||
```python
|
|
||||||
from taos.tmq import Consumer
|
|
||||||
|
|
||||||
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 订阅 topics
|
|
||||||
|
|
||||||
Consumer API 的 `subscribe` 方法用于订阅 topics,consumer 支持同时订阅多个 topic。
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.subscribe(['topic1', 'topic2'])
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 消费数据
|
|
||||||
|
|
||||||
Consumer API 的 `poll` 方法用于消费数据,`poll` 方法接收一个 float 类型的超时时间,超时时间单位为秒(s),`poll` 方法在超时之前返回一条 Message 类型的数据或超时返回 `None`。消费者必须通过 Message 的 `error()` 方法校验返回数据的 error 信息。
|
|
||||||
|
|
||||||
```python
|
|
||||||
while True:
|
|
||||||
res = consumer.poll(1)
|
|
||||||
if not res:
|
|
||||||
continue
|
|
||||||
err = res.error()
|
|
||||||
if err is not None:
|
|
||||||
raise err
|
|
||||||
val = res.value()
|
|
||||||
|
|
||||||
for block in val:
|
|
||||||
print(block.fetchall())
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 获取消费进度
|
|
||||||
|
|
||||||
Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。
|
|
||||||
|
|
||||||
```python
|
|
||||||
assignments = consumer.assignment()
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 指定订阅 Offset
|
|
||||||
|
|
||||||
Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置,方法参数类型为 TopicPartition。
|
|
||||||
|
|
||||||
```python
|
|
||||||
tp = TopicPartition(topic='topic1', partition=0, offset=0)
|
|
||||||
consumer.seek(tp)
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 关闭订阅
|
|
||||||
|
|
||||||
消费结束后,应当取消订阅,并关闭 Consumer。
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.unsubscribe()
|
|
||||||
consumer.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 完整示例
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/tmq_example.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 获取和重置消费进度示例代码
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
|
|
||||||
<TabItem value="websocket" label="WebSocket 连接">
|
|
||||||
|
|
||||||
除了原生的连接方式,Python 连接器还支持通过 websocket 订阅 TMQ 数据,使用 websocket 方式订阅 TMQ 数据需要安装 `taos-ws-py`。
|
|
||||||
|
|
||||||
taosws `Consumer` API 提供了基于 Websocket 订阅 TMQ 数据的 API。
|
|
||||||
|
|
||||||
##### 创建 Consumer
|
|
||||||
|
|
||||||
创建 Consumer 语法为 `consumer = Consumer(conf=configs)`,使用时需要指定 `td.connect.websocket.scheme` 参数值为 "ws",参数定义请参考 [数据订阅文档](../../develop/tmq/#%E5%88%9B%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85-consumer)。
|
|
||||||
|
|
||||||
```python
|
|
||||||
import taosws
|
|
||||||
|
|
||||||
consumer = taosws.(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 订阅 topics
|
|
||||||
|
|
||||||
Consumer API 的 `subscribe` 方法用于订阅 topics,consumer 支持同时订阅多个 topic。
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.subscribe(['topic1', 'topic2'])
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 消费数据
|
|
||||||
|
|
||||||
Consumer API 的 `poll` 方法用于消费数据,`poll` 方法接收一个 float 类型的超时时间,超时时间单位为秒(s),`poll` 方法在超时之前返回一条 Message 类型的数据或超时返回 `None`。消费者必须通过 Message 的 `error()` 方法校验返回数据的 error 信息。
|
|
||||||
|
|
||||||
```python
|
|
||||||
while True:
|
|
||||||
res = consumer.poll(timeout=1.0)
|
|
||||||
if not res:
|
|
||||||
continue
|
|
||||||
err = res.error()
|
|
||||||
if err is not None:
|
|
||||||
raise err
|
|
||||||
for block in message:
|
|
||||||
for row in block:
|
|
||||||
print(row)
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 获取消费进度
|
|
||||||
|
|
||||||
Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。
|
|
||||||
|
|
||||||
```python
|
|
||||||
assignments = consumer.assignment()
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 重置消费进度
|
|
||||||
|
|
||||||
Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置。
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.seek(topic='topic1', partition=0, offset=0)
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 结束消费
|
|
||||||
|
|
||||||
消费结束后,应当取消订阅,并关闭 Consumer。
|
|
||||||
|
|
||||||
```python
|
|
||||||
consumer.unsubscribe()
|
|
||||||
consumer.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
##### tmq 订阅示例代码
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/tmq_websocket_example.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
连接器提供了 `assignment` 接口,用于获取 topic assignment 的功能,可以查询订阅的 topic 的消费进度,并提供 `seek` 接口,用于重置 topic 的消费进度。
|
|
||||||
|
|
||||||
##### 获取和重置消费进度示例代码
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
### 无模式写入
|
|
||||||
|
|
||||||
连接器支持无模式写入功能。
|
|
||||||
|
|
||||||
<Tabs defaultValue="list">
|
|
||||||
<TabItem value="list" label="List 写入">
|
|
||||||
|
|
||||||
##### 简单写入
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 带有 ttl 参数的写入
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_ttl.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 带有 req_id 参数的写入
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
|
|
||||||
<TabItem value="raw" label="Raw 写入">
|
|
||||||
|
|
||||||
##### 简单写入
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_raw.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 带有 ttl 参数的写入
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_raw_ttl.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 带有 req_id 参数的写入
|
|
||||||
|
|
||||||
```python
|
|
||||||
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
### 通过参数绑定写入数据
|
### 通过参数绑定写入数据
|
||||||
|
|
||||||
TDengine 的 Python 连接器支持参数绑定风格的 Prepare API 方式写入数据,和大多数数据库类似,目前仅支持用 `?` 来代表待绑定的参数。
|
TDengine 的 Python 连接器支持参数绑定风格的 Prepare API 方式写入数据,和大多数数据库类似,目前仅支持用 `?` 来代表待绑定的参数。
|
||||||
|
@ -909,6 +751,264 @@ stmt.close()
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
### 无模式写入
|
||||||
|
|
||||||
|
连接器支持无模式写入功能。
|
||||||
|
|
||||||
|
<Tabs defaultValue="list">
|
||||||
|
<TabItem value="list" label="List 写入">
|
||||||
|
|
||||||
|
##### 简单写入
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 带有 ttl 参数的写入
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_ttl.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 带有 req_id 参数的写入
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="raw" label="Raw 写入">
|
||||||
|
|
||||||
|
##### 简单写入
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_raw.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 带有 ttl 参数的写入
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_raw_ttl.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 带有 req_id 参数的写入
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
### 执行带有 reqId 的无模式写入
|
||||||
|
|
||||||
|
连接器的 `schemaless_insert` 和 `schemaless_insert_raw` 方法支持 `req_id` 可选参数,此 `req_Id` 可用于请求链路追踪。
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数据订阅
|
||||||
|
|
||||||
|
连接器支持数据订阅功能,数据订阅功能请参考 [数据订阅文档](../../develop/tmq/)。
|
||||||
|
|
||||||
|
#### 创建 Topic
|
||||||
|
|
||||||
|
创建 Topic 相关请参考 [数据订阅文档](../../develop/tmq/#创建-topic)。
|
||||||
|
|
||||||
|
#### 创建 Consumer
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="原生连接">
|
||||||
|
|
||||||
|
`Consumer` 提供了 Python 连接器订阅 TMQ 数据的 API。创建 Consumer 语法为 `consumer = Consumer(configs)`,参数定义请参考 [数据订阅文档](../../develop/tmq/#创建消费者-consumer)。
|
||||||
|
|
||||||
|
```python
|
||||||
|
from taos.tmq import Consumer
|
||||||
|
|
||||||
|
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="websocket" label="WebSocket 连接">
|
||||||
|
|
||||||
|
除了原生的连接方式,Python 连接器还支持通过 websocket 订阅 TMQ 数据,使用 websocket 方式订阅 TMQ 数据需要安装 `taos-ws-py`。
|
||||||
|
|
||||||
|
taosws `Consumer` API 提供了基于 Websocket 订阅 TMQ 数据的 API。创建 Consumer 语法为 `consumer = Consumer(conf=configs)`,使用时需要指定 `td.connect.websocket.scheme` 参数值为 "ws",参数定义请参考 [数据订阅文档](../../develop/tmq/#%E5%88%9B%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85-consumer)。
|
||||||
|
|
||||||
|
```python
|
||||||
|
import taosws
|
||||||
|
|
||||||
|
consumer = taosws.(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### 订阅 topics
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="原生连接">
|
||||||
|
|
||||||
|
Consumer API 的 `subscribe` 方法用于订阅 topics,consumer 支持同时订阅多个 topic。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.subscribe(['topic1', 'topic2'])
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket 连接">
|
||||||
|
|
||||||
|
Consumer API 的 `subscribe` 方法用于订阅 topics,consumer 支持同时订阅多个 topic。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.subscribe(['topic1', 'topic2'])
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### 消费数据
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="原生连接">
|
||||||
|
|
||||||
|
Consumer API 的 `poll` 方法用于消费数据,`poll` 方法接收一个 float 类型的超时时间,超时时间单位为秒(s),`poll` 方法在超时之前返回一条 Message 类型的数据或超时返回 `None`。消费者必须通过 Message 的 `error()` 方法校验返回数据的 error 信息。
|
||||||
|
|
||||||
|
```python
|
||||||
|
while True:
|
||||||
|
res = consumer.poll(1)
|
||||||
|
if not res:
|
||||||
|
continue
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
val = res.value()
|
||||||
|
|
||||||
|
for block in val:
|
||||||
|
print(block.fetchall())
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket 连接">
|
||||||
|
|
||||||
|
Consumer API 的 `poll` 方法用于消费数据,`poll` 方法接收一个 float 类型的超时时间,超时时间单位为秒(s),`poll` 方法在超时之前返回一条 Message 类型的数据或超时返回 `None`。消费者必须通过 Message 的 `error()` 方法校验返回数据的 error 信息。
|
||||||
|
|
||||||
|
```python
|
||||||
|
while True:
|
||||||
|
res = consumer.poll(timeout=1.0)
|
||||||
|
if not res:
|
||||||
|
continue
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
for block in message:
|
||||||
|
for row in block:
|
||||||
|
print(row)
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### 获取消费进度
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="原生连接">
|
||||||
|
|
||||||
|
Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。
|
||||||
|
|
||||||
|
```python
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
```
|
||||||
|
|
||||||
|
Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置,方法参数类型为 TopicPartition。
|
||||||
|
|
||||||
|
```python
|
||||||
|
tp = TopicPartition(topic='topic1', partition=0, offset=0)
|
||||||
|
consumer.seek(tp)
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket 连接">
|
||||||
|
|
||||||
|
Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。
|
||||||
|
|
||||||
|
```python
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
```
|
||||||
|
|
||||||
|
Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.seek(topic='topic1', partition=0, offset=0)
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### 关闭订阅
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="原生连接">
|
||||||
|
|
||||||
|
消费结束后,应当取消订阅,并关闭 Consumer。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.unsubscribe()
|
||||||
|
consumer.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket 连接">
|
||||||
|
|
||||||
|
消费结束后,应当取消订阅,并关闭 Consumer。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.unsubscribe()
|
||||||
|
consumer.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
#### 完整示例
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
|
||||||
|
<TabItem value="native" label="原生连接">
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_example.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="websocket" label="WebSocket 连接">
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_websocket_example.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
### 更多示例程序
|
### 更多示例程序
|
||||||
|
|
||||||
| 示例程序链接 | 示例程序内容 |
|
| 示例程序链接 | 示例程序内容 |
|
||||||
|
|
|
@ -51,6 +51,11 @@ DESCRIBE [db_name.]stb_name;
|
||||||
|
|
||||||
### 获取超级表中所有子表的标签信息
|
### 获取超级表中所有子表的标签信息
|
||||||
|
|
||||||
|
```
|
||||||
|
SHOW TABLE TAGS FROM table_name [FROM db_name];
|
||||||
|
SHOW TABLE TAGS FROM [db_name.]table_name;
|
||||||
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
taos> SHOW TABLE TAGS FROM st1;
|
taos> SHOW TABLE TAGS FROM st1;
|
||||||
tbname | id | loc |
|
tbname | id | loc |
|
||||||
|
|
|
@ -101,6 +101,7 @@ SHOW GRANTS;
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SHOW INDEXES FROM tbl_name [FROM db_name];
|
SHOW INDEXES FROM tbl_name [FROM db_name];
|
||||||
|
SHOW INDEXES FROM [db_name.]tbl_name;
|
||||||
```
|
```
|
||||||
|
|
||||||
显示已创建的索引。
|
显示已创建的索引。
|
||||||
|
@ -269,6 +270,7 @@ Query OK, 24 row(s) in set (0.002444s)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SHOW TAGS FROM child_table_name [FROM db_name];
|
SHOW TAGS FROM child_table_name [FROM db_name];
|
||||||
|
SHOW TAGS FROM [db_name.]child_table_name;
|
||||||
```
|
```
|
||||||
|
|
||||||
显示子表的标签信息。
|
显示子表的标签信息。
|
||||||
|
|
|
@ -43,6 +43,7 @@ DROP INDEX index_name;
|
||||||
````sql
|
````sql
|
||||||
```sql
|
```sql
|
||||||
SHOW INDEXES FROM tbl_name [FROM db_name];
|
SHOW INDEXES FROM tbl_name [FROM db_name];
|
||||||
|
SHOW INDEXES FROM [db_name.]tbl_name;
|
||||||
````
|
````
|
||||||
|
|
||||||
显示在所指定的数据库或表上已创建的索引。
|
显示在所指定的数据库或表上已创建的索引。
|
||||||
|
|
|
@ -16,105 +16,105 @@
|
||||||
#ifndef _TD_COMMON_TOKEN_H_
|
#ifndef _TD_COMMON_TOKEN_H_
|
||||||
#define _TD_COMMON_TOKEN_H_
|
#define _TD_COMMON_TOKEN_H_
|
||||||
|
|
||||||
#define TK_OR 1
|
#define TK_OR 1
|
||||||
#define TK_AND 2
|
#define TK_AND 2
|
||||||
#define TK_UNION 3
|
#define TK_UNION 3
|
||||||
#define TK_ALL 4
|
#define TK_ALL 4
|
||||||
#define TK_MINUS 5
|
#define TK_MINUS 5
|
||||||
#define TK_EXCEPT 6
|
#define TK_EXCEPT 6
|
||||||
#define TK_INTERSECT 7
|
#define TK_INTERSECT 7
|
||||||
#define TK_NK_BITAND 8
|
#define TK_NK_BITAND 8
|
||||||
#define TK_NK_BITOR 9
|
#define TK_NK_BITOR 9
|
||||||
#define TK_NK_LSHIFT 10
|
#define TK_NK_LSHIFT 10
|
||||||
#define TK_NK_RSHIFT 11
|
#define TK_NK_RSHIFT 11
|
||||||
#define TK_NK_PLUS 12
|
#define TK_NK_PLUS 12
|
||||||
#define TK_NK_MINUS 13
|
#define TK_NK_MINUS 13
|
||||||
#define TK_NK_STAR 14
|
#define TK_NK_STAR 14
|
||||||
#define TK_NK_SLASH 15
|
#define TK_NK_SLASH 15
|
||||||
#define TK_NK_REM 16
|
#define TK_NK_REM 16
|
||||||
#define TK_NK_CONCAT 17
|
#define TK_NK_CONCAT 17
|
||||||
#define TK_CREATE 18
|
#define TK_CREATE 18
|
||||||
#define TK_ACCOUNT 19
|
#define TK_ACCOUNT 19
|
||||||
#define TK_NK_ID 20
|
#define TK_NK_ID 20
|
||||||
#define TK_PASS 21
|
#define TK_PASS 21
|
||||||
#define TK_NK_STRING 22
|
#define TK_NK_STRING 22
|
||||||
#define TK_ALTER 23
|
#define TK_ALTER 23
|
||||||
#define TK_PPS 24
|
#define TK_PPS 24
|
||||||
#define TK_TSERIES 25
|
#define TK_TSERIES 25
|
||||||
#define TK_STORAGE 26
|
#define TK_STORAGE 26
|
||||||
#define TK_STREAMS 27
|
#define TK_STREAMS 27
|
||||||
#define TK_QTIME 28
|
#define TK_QTIME 28
|
||||||
#define TK_DBS 29
|
#define TK_DBS 29
|
||||||
#define TK_USERS 30
|
#define TK_USERS 30
|
||||||
#define TK_CONNS 31
|
#define TK_CONNS 31
|
||||||
#define TK_STATE 32
|
#define TK_STATE 32
|
||||||
#define TK_USER 33
|
#define TK_USER 33
|
||||||
#define TK_ENABLE 34
|
#define TK_ENABLE 34
|
||||||
#define TK_NK_INTEGER 35
|
#define TK_NK_INTEGER 35
|
||||||
#define TK_SYSINFO 36
|
#define TK_SYSINFO 36
|
||||||
#define TK_DROP 37
|
#define TK_DROP 37
|
||||||
#define TK_GRANT 38
|
#define TK_GRANT 38
|
||||||
#define TK_ON 39
|
#define TK_ON 39
|
||||||
#define TK_TO 40
|
#define TK_TO 40
|
||||||
#define TK_REVOKE 41
|
#define TK_REVOKE 41
|
||||||
#define TK_FROM 42
|
#define TK_FROM 42
|
||||||
#define TK_SUBSCRIBE 43
|
#define TK_SUBSCRIBE 43
|
||||||
#define TK_NK_COMMA 44
|
#define TK_NK_COMMA 44
|
||||||
#define TK_READ 45
|
#define TK_READ 45
|
||||||
#define TK_WRITE 46
|
#define TK_WRITE 46
|
||||||
#define TK_NK_DOT 47
|
#define TK_NK_DOT 47
|
||||||
#define TK_WITH 48
|
#define TK_WITH 48
|
||||||
#define TK_DNODE 49
|
#define TK_DNODE 49
|
||||||
#define TK_PORT 50
|
#define TK_PORT 50
|
||||||
#define TK_DNODES 51
|
#define TK_DNODES 51
|
||||||
#define TK_RESTORE 52
|
#define TK_RESTORE 52
|
||||||
#define TK_NK_IPTOKEN 53
|
#define TK_NK_IPTOKEN 53
|
||||||
#define TK_FORCE 54
|
#define TK_FORCE 54
|
||||||
#define TK_UNSAFE 55
|
#define TK_UNSAFE 55
|
||||||
#define TK_LOCAL 56
|
#define TK_LOCAL 56
|
||||||
#define TK_QNODE 57
|
#define TK_QNODE 57
|
||||||
#define TK_BNODE 58
|
#define TK_BNODE 58
|
||||||
#define TK_SNODE 59
|
#define TK_SNODE 59
|
||||||
#define TK_MNODE 60
|
#define TK_MNODE 60
|
||||||
#define TK_VNODE 61
|
#define TK_VNODE 61
|
||||||
#define TK_DATABASE 62
|
#define TK_DATABASE 62
|
||||||
#define TK_USE 63
|
#define TK_USE 63
|
||||||
#define TK_FLUSH 64
|
#define TK_FLUSH 64
|
||||||
#define TK_TRIM 65
|
#define TK_TRIM 65
|
||||||
#define TK_COMPACT 66
|
#define TK_COMPACT 66
|
||||||
#define TK_IF 67
|
#define TK_IF 67
|
||||||
#define TK_NOT 68
|
#define TK_NOT 68
|
||||||
#define TK_EXISTS 69
|
#define TK_EXISTS 69
|
||||||
#define TK_BUFFER 70
|
#define TK_BUFFER 70
|
||||||
#define TK_CACHEMODEL 71
|
#define TK_CACHEMODEL 71
|
||||||
#define TK_CACHESIZE 72
|
#define TK_CACHESIZE 72
|
||||||
#define TK_COMP 73
|
#define TK_COMP 73
|
||||||
#define TK_DURATION 74
|
#define TK_DURATION 74
|
||||||
#define TK_NK_VARIABLE 75
|
#define TK_NK_VARIABLE 75
|
||||||
#define TK_MAXROWS 76
|
#define TK_MAXROWS 76
|
||||||
#define TK_MINROWS 77
|
#define TK_MINROWS 77
|
||||||
#define TK_KEEP 78
|
#define TK_KEEP 78
|
||||||
#define TK_PAGES 79
|
#define TK_PAGES 79
|
||||||
#define TK_PAGESIZE 80
|
#define TK_PAGESIZE 80
|
||||||
#define TK_TSDB_PAGESIZE 81
|
#define TK_TSDB_PAGESIZE 81
|
||||||
#define TK_PRECISION 82
|
#define TK_PRECISION 82
|
||||||
#define TK_REPLICA 83
|
#define TK_REPLICA 83
|
||||||
#define TK_VGROUPS 84
|
#define TK_VGROUPS 84
|
||||||
#define TK_SINGLE_STABLE 85
|
#define TK_SINGLE_STABLE 85
|
||||||
#define TK_RETENTIONS 86
|
#define TK_RETENTIONS 86
|
||||||
#define TK_SCHEMALESS 87
|
#define TK_SCHEMALESS 87
|
||||||
#define TK_WAL_LEVEL 88
|
#define TK_WAL_LEVEL 88
|
||||||
#define TK_WAL_FSYNC_PERIOD 89
|
#define TK_WAL_FSYNC_PERIOD 89
|
||||||
#define TK_WAL_RETENTION_PERIOD 90
|
#define TK_WAL_RETENTION_PERIOD 90
|
||||||
#define TK_WAL_RETENTION_SIZE 91
|
#define TK_WAL_RETENTION_SIZE 91
|
||||||
#define TK_WAL_ROLL_PERIOD 92
|
#define TK_WAL_ROLL_PERIOD 92
|
||||||
#define TK_WAL_SEGMENT_SIZE 93
|
#define TK_WAL_SEGMENT_SIZE 93
|
||||||
#define TK_STT_TRIGGER 94
|
#define TK_STT_TRIGGER 94
|
||||||
#define TK_TABLE_PREFIX 95
|
#define TK_TABLE_PREFIX 95
|
||||||
#define TK_TABLE_SUFFIX 96
|
#define TK_TABLE_SUFFIX 96
|
||||||
#define TK_NK_COLON 97
|
#define TK_NK_COLON 97
|
||||||
#define TK_MAX_SPEED 98
|
#define TK_MAX_SPEED 98
|
||||||
#define TK_START 99
|
#define TK_START 99
|
||||||
#define TK_TIMESTAMP 100
|
#define TK_TIMESTAMP 100
|
||||||
#define TK_END 101
|
#define TK_END 101
|
||||||
#define TK_TABLE 102
|
#define TK_TABLE 102
|
||||||
|
@ -355,8 +355,6 @@
|
||||||
#define TK_WAL 337
|
#define TK_WAL 337
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TK_NK_SPACE 600
|
#define TK_NK_SPACE 600
|
||||||
#define TK_NK_COMMENT 601
|
#define TK_NK_COMMENT 601
|
||||||
#define TK_NK_ILLEGAL 602
|
#define TK_NK_ILLEGAL 602
|
||||||
|
|
|
@ -346,6 +346,7 @@ struct SStreamTask {
|
||||||
int32_t refCnt;
|
int32_t refCnt;
|
||||||
int64_t checkpointingId;
|
int64_t checkpointingId;
|
||||||
int32_t checkpointAlignCnt;
|
int32_t checkpointAlignCnt;
|
||||||
|
int32_t transferStateAlignCnt;
|
||||||
struct SStreamMeta* pMeta;
|
struct SStreamMeta* pMeta;
|
||||||
SSHashObj* pNameMap;
|
SSHashObj* pNameMap;
|
||||||
};
|
};
|
||||||
|
@ -630,6 +631,8 @@ int32_t streamProcessCheckpointRsp(SStreamMeta* pMeta, SStreamTask* pTask, SStre
|
||||||
|
|
||||||
int32_t streamTaskReleaseState(SStreamTask* pTask);
|
int32_t streamTaskReleaseState(SStreamTask* pTask);
|
||||||
int32_t streamTaskReloadState(SStreamTask* pTask);
|
int32_t streamTaskReloadState(SStreamTask* pTask);
|
||||||
|
int32_t streamAlignTransferState(SStreamTask* pTask);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,22 +265,6 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||||
|
|
||||||
snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vnodeCfg.vgId);
|
snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vnodeCfg.vgId);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (pMgmt->pTfs) {
|
|
||||||
if (tfsDirExistAt(pMgmt->pTfs, path, (SDiskID){0})) {
|
|
||||||
terrno = TSDB_CODE_VND_DIR_ALREADY_EXIST;
|
|
||||||
dError("vgId:%d, failed to restore vnode since %s", req.vgId, terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (taosDirExist(path)) {
|
|
||||||
terrno = TSDB_CODE_VND_DIR_ALREADY_EXIST;
|
|
||||||
dError("vgId:%d, failed to restore vnode since %s", req.vgId, terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (vnodeCreate(path, &vnodeCfg, pMgmt->pTfs) < 0) {
|
if (vnodeCreate(path, &vnodeCfg, pMgmt->pTfs) < 0) {
|
||||||
tFreeSCreateVnodeReq(&req);
|
tFreeSCreateVnodeReq(&req);
|
||||||
dError("vgId:%d, failed to create vnode since %s", req.vgId, terrstr());
|
dError("vgId:%d, failed to create vnode since %s", req.vgId, terrstr());
|
||||||
|
|
|
@ -889,11 +889,11 @@ _OVER:
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mndDropSmasByStb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
int32_t mndDropSmasByStb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
||||||
SSdb *pSdb = pMnode->pSdb;
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
SSmaObj *pSma = NULL;
|
SSmaObj *pSma = NULL;
|
||||||
void *pIter = NULL;
|
void *pIter = NULL;
|
||||||
SVgObj *pVgroup = NULL;
|
SVgObj *pVgroup = NULL;
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
pIter = sdbFetch(pSdb, SDB_SMA, pIter, (void **)&pSma);
|
pIter = sdbFetch(pSdb, SDB_SMA, pIter, (void **)&pSma);
|
||||||
|
@ -911,12 +911,18 @@ int32_t mndDropSmasByStb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *p
|
||||||
if (pStream != NULL && pStream->smaId == pSma->uid) {
|
if (pStream != NULL && pStream->smaId == pSma->uid) {
|
||||||
if (mndDropStreamTasks(pMnode, pTrans, pStream) < 0) {
|
if (mndDropStreamTasks(pMnode, pTrans, pStream) < 0) {
|
||||||
mError("stream:%s, failed to drop task since %s", pStream->name, terrstr());
|
mError("stream:%s, failed to drop task since %s", pStream->name, terrstr());
|
||||||
|
mndReleaseStream(pMnode, pStream);
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mndPersistDropStreamLog(pMnode, pTrans, pStream) < 0) {
|
if (mndPersistDropStreamLog(pMnode, pTrans, pStream) < 0) {
|
||||||
|
mndReleaseStream(pMnode, pStream);
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mndReleaseStream(pMnode, pStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mndSetDropSmaVgroupCommitLogs(pMnode, pTrans, pVgroup) != 0) goto _OVER;
|
if (mndSetDropSmaVgroupCommitLogs(pMnode, pTrans, pVgroup) != 0) goto _OVER;
|
||||||
if (mndSetDropSmaVgroupRedoActions(pMnode, pTrans, pDb, pVgroup) != 0) goto _OVER;
|
if (mndSetDropSmaVgroupRedoActions(pMnode, pTrans, pDb, pVgroup) != 0) goto _OVER;
|
||||||
if (mndSetDropSmaCommitLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
|
if (mndSetDropSmaCommitLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
|
||||||
|
|
|
@ -229,11 +229,11 @@ int32_t tdRSmaProcessCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con
|
||||||
int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type);
|
int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type);
|
||||||
int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash);
|
int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash);
|
||||||
int32_t tdRSmaProcessRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer, int8_t rollback);
|
int32_t tdRSmaProcessRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer, int8_t rollback);
|
||||||
void tdRSmaQTaskInfoGetFileName(int32_t vgId, int64_t suid, int8_t level, int64_t version, char *outputName);
|
void tdRSmaQTaskInfoGetFileName(SVnode *pVnode, int64_t suid, int8_t level, int64_t version, char *outputName);
|
||||||
void tdRSmaQTaskInfoGetFullName(int32_t vgId, int64_t suid, int8_t level, int64_t version, const char *path,
|
void tdRSmaQTaskInfoGetFullName(SVnode *pVnode, int64_t suid, int8_t level, int64_t version, STfs *pTfs,
|
||||||
char *outputName);
|
char *outputName);
|
||||||
void tdRSmaQTaskInfoGetFullPath(int32_t vgId, int8_t level, const char *path, char *outputName);
|
void tdRSmaQTaskInfoGetFullPath(SVnode *pVnode, int8_t level, STfs *pTfs, char *outputName);
|
||||||
void tdRSmaQTaskInfoGetFullPathEx(int32_t vgId, tb_uid_t suid, int8_t level, const char *path, char *outputName);
|
void tdRSmaQTaskInfoGetFullPathEx(SVnode *pVnode, tb_uid_t suid, int8_t level, STfs *pTfs, char *outputName);
|
||||||
|
|
||||||
static FORCE_INLINE void tdRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo) {
|
static FORCE_INLINE void tdRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo) {
|
||||||
int32_t ref = T_REF_INC(pRSmaInfo);
|
int32_t ref = T_REF_INC(pRSmaInfo);
|
||||||
|
@ -244,9 +244,9 @@ static FORCE_INLINE void tdUnRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo) {
|
||||||
smaTrace("vgId:%d, unref rsma info:%p, val:%d", SMA_VID(pSma), pRSmaInfo, ref);
|
smaTrace("vgId:%d, unref rsma info:%p, val:%d", SMA_VID(pSma), pRSmaInfo, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdRSmaGetFileName(int32_t vgId, const char *pdname, const char *dname, const char *fname, int64_t suid,
|
void tdRSmaGetFileName(SVnode *pVnode, STfs *pTfs, const char *fname, int64_t suid, int8_t level, int64_t version,
|
||||||
int8_t level, int64_t version, char *outputName);
|
char *outputName);
|
||||||
void tdRSmaGetDirName(int32_t vgId, const char *pdname, const char *dname, bool endWithSep, char *outputName);
|
void tdRSmaGetDirName(SVnode *pVnode, STfs *pTfs, bool endWithSep, char *outputName);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,9 @@ void vnodeBufPoolReset(SVBufPool* pPool);
|
||||||
void vnodeBufPoolAddToFreeList(SVBufPool* pPool);
|
void vnodeBufPoolAddToFreeList(SVBufPool* pPool);
|
||||||
int32_t vnodeBufPoolRecycle(SVBufPool* pPool);
|
int32_t vnodeBufPoolRecycle(SVBufPool* pPool);
|
||||||
|
|
||||||
|
// vnodeOpen.c
|
||||||
|
int32_t vnodeGetPrimaryDir(const char* relPath, STfs* pTfs, char* buf, size_t bufLen);
|
||||||
|
|
||||||
// vnodeQuery.c
|
// vnodeQuery.c
|
||||||
int32_t vnodeQueryOpen(SVnode* pVnode);
|
int32_t vnodeQueryOpen(SVnode* pVnode);
|
||||||
void vnodeQueryPreClose(SVnode* pVnode);
|
void vnodeQueryPreClose(SVnode* pVnode);
|
||||||
|
|
|
@ -248,7 +248,7 @@ int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqProcessTaskRetrieveReq(STQ* pTq, SRpcMsg* pMsg);
|
int32_t tqProcessTaskRetrieveReq(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqProcessTaskRetrieveRsp(STQ* pTq, SRpcMsg* pMsg);
|
int32_t tqProcessTaskRetrieveRsp(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg);
|
int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqProcessTaskTransferStateReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
int32_t tqProcessTaskTransferStateReq(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqProcessStreamTaskScanHistoryFinishReq(STQ* pTq, SRpcMsg* pMsg);
|
int32_t tqProcessStreamTaskScanHistoryFinishReq(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqProcessTaskRecoverFinishRsp(STQ* pTq, SRpcMsg* pMsg);
|
int32_t tqProcessTaskRecoverFinishRsp(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqCheckLogInWal(STQ* pTq, int64_t version);
|
int32_t tqCheckLogInWal(STQ* pTq, int64_t version);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
|
#include "vnd.h"
|
||||||
|
|
||||||
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
|
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
|
||||||
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
|
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
|
||||||
|
@ -34,30 +35,27 @@ static void metaCleanup(SMeta **ppMeta);
|
||||||
int metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
|
int metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
|
||||||
SMeta *pMeta = NULL;
|
SMeta *pMeta = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
int slen;
|
int offset;
|
||||||
|
char path[TSDB_FILENAME_LEN] = {0};
|
||||||
|
|
||||||
*ppMeta = NULL;
|
*ppMeta = NULL;
|
||||||
|
|
||||||
// create handle
|
// create handle
|
||||||
if (pVnode->pTfs) {
|
vnodeGetPrimaryDir(pVnode->path, pVnode->pTfs, path, TSDB_FILENAME_LEN);
|
||||||
slen = strlen(tfsGetPrimaryPath(pVnode->pTfs)) + strlen(pVnode->path) + strlen(VNODE_META_DIR) + 3;
|
offset = strlen(path);
|
||||||
} else {
|
snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, VNODE_META_DIR);
|
||||||
slen = strlen(pVnode->path) + strlen(VNODE_META_DIR) + 2;
|
|
||||||
}
|
if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + strlen(path) + 1)) == NULL) {
|
||||||
if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + slen)) == NULL) {
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
metaInitLock(pMeta);
|
metaInitLock(pMeta);
|
||||||
|
|
||||||
pMeta->path = (char *)&pMeta[1];
|
pMeta->path = (char *)&pMeta[1];
|
||||||
if (pVnode->pTfs) {
|
strcpy(pMeta->path, path);
|
||||||
sprintf(pMeta->path, "%s%s%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path, TD_DIRSEP,
|
taosRealPath(pMeta->path, NULL, strlen(path) + 1);
|
||||||
VNODE_META_DIR);
|
|
||||||
} else {
|
|
||||||
sprintf(pMeta->path, "%s%s%s", pVnode->path, TD_DIRSEP, VNODE_META_DIR);
|
|
||||||
}
|
|
||||||
taosRealPath(pMeta->path, NULL, slen);
|
|
||||||
pMeta->pVnode = pVnode;
|
pMeta->pVnode = pVnode;
|
||||||
|
|
||||||
// create path if not created yet
|
// create path if not created yet
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sma.h"
|
#include "sma.h"
|
||||||
|
#include "vnd.h"
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
|
||||||
|
@ -157,25 +158,15 @@ _exit:
|
||||||
|
|
||||||
static void tdRSmaGetCurrentFName(SSma *pSma, char *current, char *current_t) {
|
static void tdRSmaGetCurrentFName(SSma *pSma, char *current, char *current_t) {
|
||||||
SVnode *pVnode = pSma->pVnode;
|
SVnode *pVnode = pSma->pVnode;
|
||||||
if (pVnode->pTfs) {
|
int32_t offset = 0;
|
||||||
if (current) {
|
|
||||||
snprintf(current, TSDB_FILENAME_LEN - 1, "%s%svnode%svnode%d%srsma%sPRESENT", tfsGetPrimaryPath(pVnode->pTfs),
|
vnodeGetPrimaryDir(pVnode->path, pVnode->pTfs, current, TSDB_FILENAME_LEN);
|
||||||
TD_DIRSEP, TD_DIRSEP, TD_VID(pVnode), TD_DIRSEP, TD_DIRSEP);
|
offset = strlen(current);
|
||||||
}
|
snprintf(current + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s%sPRESENT", TD_DIRSEP, VNODE_RSMA_DIR, TD_DIRSEP);
|
||||||
if (current_t) {
|
|
||||||
snprintf(current_t, TSDB_FILENAME_LEN - 1, "%s%svnode%svnode%d%srsma%sPRESENT.t", tfsGetPrimaryPath(pVnode->pTfs),
|
vnodeGetPrimaryDir(pVnode->path, pVnode->pTfs, current_t, TSDB_FILENAME_LEN);
|
||||||
TD_DIRSEP, TD_DIRSEP, TD_VID(pVnode), TD_DIRSEP, TD_DIRSEP);
|
offset = strlen(current_t);
|
||||||
}
|
snprintf(current_t + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s%sPRESENT.t", TD_DIRSEP, VNODE_RSMA_DIR, TD_DIRSEP);
|
||||||
} else {
|
|
||||||
#if 0
|
|
||||||
if (current) {
|
|
||||||
snprintf(current, TSDB_FILENAME_LEN - 1, "%s%sPRESENT", pTsdb->path, TD_DIRSEP);
|
|
||||||
}
|
|
||||||
if (current_t) {
|
|
||||||
snprintf(current_t, TSDB_FILENAME_LEN - 1, "%s%sPRESENT.t", pTsdb->path, TD_DIRSEP);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tdRSmaLoadFSFromFile(const char *fname, SRSmaFS *pFS) {
|
static int32_t tdRSmaLoadFSFromFile(const char *fname, SRSmaFS *pFS) {
|
||||||
|
@ -309,8 +300,7 @@ static int32_t tdRSmaFSApplyChange(SSma *pSma, SRSmaFS *pFSNew) {
|
||||||
|
|
||||||
nRef = atomic_sub_fetch_32(&preTaskF->nRef, 1);
|
nRef = atomic_sub_fetch_32(&preTaskF->nRef, 1);
|
||||||
if (nRef <= 0) {
|
if (nRef <= 0) {
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), preTaskF->suid, preTaskF->level, preTaskF->version,
|
tdRSmaQTaskInfoGetFullName(pVnode, preTaskF->suid, preTaskF->level, preTaskF->version, pVnode->pTfs, fname);
|
||||||
tfsGetPrimaryPath(pVnode->pTfs), fname);
|
|
||||||
(void)taosRemoveFile(fname);
|
(void)taosRemoveFile(fname);
|
||||||
taosArrayRemove(pFSOld->aQTaskInf, idx);
|
taosArrayRemove(pFSOld->aQTaskInf, idx);
|
||||||
}
|
}
|
||||||
|
@ -341,9 +331,9 @@ static int32_t tdRSmaFSScanAndTryFix(SSma *pSma) {
|
||||||
SQTaskFile *pTaskF = (SQTaskFile *)taosArrayGet(pFS->aQTaskInf, i);
|
SQTaskFile *pTaskF = (SQTaskFile *)taosArrayGet(pFS->aQTaskInf, i);
|
||||||
|
|
||||||
// main.tdb =========
|
// main.tdb =========
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pTaskF->suid, pTaskF->level, pTaskF->version,
|
tdRSmaQTaskInfoGetFullName(pVnode, pTaskF->suid, pTaskF->level, pTaskF->version,
|
||||||
tfsGetPrimaryPath(pVnode->pTfs), fnameVer);
|
pVnode->pTfs, fnameVer);
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pTaskF->suid, pTaskF->level, -1, tfsGetPrimaryPath(pVnode->pTfs), fname);
|
tdRSmaQTaskInfoGetFullName(pVnode, pTaskF->suid, pTaskF->level, -1, pVnode->pTfs, fname);
|
||||||
|
|
||||||
if (taosCheckExistFile(fnameVer)) {
|
if (taosCheckExistFile(fnameVer)) {
|
||||||
if (taosRenameFile(fnameVer, fname) < 0) {
|
if (taosRenameFile(fnameVer, fname) < 0) {
|
||||||
|
@ -597,8 +587,7 @@ void tdRSmaFSUnRef(SSma *pSma, SRSmaFS *pFS) {
|
||||||
|
|
||||||
nRef = atomic_sub_fetch_32(&pTaskF->nRef, 1);
|
nRef = atomic_sub_fetch_32(&pTaskF->nRef, 1);
|
||||||
if (nRef == 0) {
|
if (nRef == 0) {
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pTaskF->suid, pTaskF->level, pTaskF->version,
|
tdRSmaQTaskInfoGetFullName(pVnode, pTaskF->suid, pTaskF->level, pTaskF->version, pVnode->pTfs, fname);
|
||||||
tfsGetPrimaryPath(pVnode->pTfs), fname);
|
|
||||||
if (taosRemoveFile(fname) < 0) {
|
if (taosRemoveFile(fname) < 0) {
|
||||||
smaWarn("vgId:%d, failed to remove %s since %s", TD_VID(pVnode), fname, tstrerror(TAOS_SYSTEM_ERROR(errno)));
|
smaWarn("vgId:%d, failed to remove %s since %s", TD_VID(pVnode), fname, tstrerror(TAOS_SYSTEM_ERROR(errno)));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -260,7 +260,7 @@ static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat
|
||||||
void *pStreamState = NULL;
|
void *pStreamState = NULL;
|
||||||
|
|
||||||
// set the backend of stream state
|
// set the backend of stream state
|
||||||
tdRSmaQTaskInfoGetFullPathEx(TD_VID(pVnode), pRSmaInfo->suid, idx + 1, tfsGetPrimaryPath(pVnode->pTfs), taskInfDir);
|
tdRSmaQTaskInfoGetFullPathEx(pVnode, pRSmaInfo->suid, idx + 1, pVnode->pTfs, taskInfDir);
|
||||||
if (!taosCheckExistFile(taskInfDir)) {
|
if (!taosCheckExistFile(taskInfDir)) {
|
||||||
char *s = taosStrdup(taskInfDir);
|
char *s = taosStrdup(taskInfDir);
|
||||||
if (taosMulMkDir(taosDirName(s)) != 0) {
|
if (taosMulMkDir(taosDirName(s)) != 0) {
|
||||||
|
@ -1258,9 +1258,8 @@ int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash) {
|
||||||
pRSmaInfo->suid, i + 1);
|
pRSmaInfo->suid, i + 1);
|
||||||
|
|
||||||
// qTaskInfo file
|
// qTaskInfo file
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pRSmaInfo->suid, i + 1, -1, tfsGetPrimaryPath(pVnode->pTfs), fname);
|
tdRSmaQTaskInfoGetFullName(pVnode, pRSmaInfo->suid, i + 1, -1, pVnode->pTfs, fname);
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pRSmaInfo->suid, i + 1, version, tfsGetPrimaryPath(pVnode->pTfs),
|
tdRSmaQTaskInfoGetFullName(pVnode, pRSmaInfo->suid, i + 1, version, pVnode->pTfs, fnameVer);
|
||||||
fnameVer);
|
|
||||||
if (taosCheckExistFile(fnameVer)) {
|
if (taosCheckExistFile(fnameVer)) {
|
||||||
smaWarn("vgId:%d, rsma persist, duplicate file %s exist", TD_VID(pVnode), fnameVer);
|
smaWarn("vgId:%d, rsma persist, duplicate file %s exist", TD_VID(pVnode), fnameVer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,8 +117,7 @@ static int32_t rsmaSnapReadQTaskInfo(SRSmaSnapReader* pReader, uint8_t** ppBuf)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), qTaskF->suid, qTaskF->level, version, tfsGetPrimaryPath(pVnode->pTfs),
|
tdRSmaQTaskInfoGetFullName(pVnode, qTaskF->suid, qTaskF->level, version, pVnode->pTfs, fname);
|
||||||
fname);
|
|
||||||
if (!taosCheckExistFile(fname)) {
|
if (!taosCheckExistFile(fname)) {
|
||||||
smaError("vgId:%d, vnode snapshot rsma reader for qtaskinfo, table %" PRIi64 ", level %" PRIi8
|
smaError("vgId:%d, vnode snapshot rsma reader for qtaskinfo, table %" PRIi64 ", level %" PRIi8
|
||||||
", version %" PRIi64 " failed since %s not exist",
|
", version %" PRIi64 " failed since %s not exist",
|
||||||
|
@ -340,7 +339,6 @@ int32_t rsmaSnapWriterClose(SRSmaSnapWriter** ppWriter, int8_t rollback) {
|
||||||
SSmaEnv* pEnv = NULL;
|
SSmaEnv* pEnv = NULL;
|
||||||
SRSmaStat* pStat = NULL;
|
SRSmaStat* pStat = NULL;
|
||||||
SRSmaSnapWriter* pWriter = *ppWriter;
|
SRSmaSnapWriter* pWriter = *ppWriter;
|
||||||
const char* primaryPath = NULL;
|
|
||||||
char fname[TSDB_FILENAME_LEN] = {0};
|
char fname[TSDB_FILENAME_LEN] = {0};
|
||||||
char fnameVer[TSDB_FILENAME_LEN] = {0};
|
char fnameVer[TSDB_FILENAME_LEN] = {0};
|
||||||
TdFilePtr pOutFD = NULL;
|
TdFilePtr pOutFD = NULL;
|
||||||
|
@ -354,7 +352,6 @@ int32_t rsmaSnapWriterClose(SRSmaSnapWriter** ppWriter, int8_t rollback) {
|
||||||
pVnode = pSma->pVnode;
|
pVnode = pSma->pVnode;
|
||||||
pEnv = SMA_RSMA_ENV(pSma);
|
pEnv = SMA_RSMA_ENV(pSma);
|
||||||
pStat = (SRSmaStat*)SMA_ENV_STAT(pEnv);
|
pStat = (SRSmaStat*)SMA_ENV_STAT(pEnv);
|
||||||
primaryPath = tfsGetPrimaryPath(pVnode->pTfs);
|
|
||||||
|
|
||||||
// rsma1/rsma2
|
// rsma1/rsma2
|
||||||
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
||||||
|
@ -375,8 +372,8 @@ int32_t rsmaSnapWriterClose(SRSmaSnapWriter** ppWriter, int8_t rollback) {
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
SQTaskFile* pTaskF = TARRAY_GET_ELEM(pFS->aQTaskInf, i);
|
SQTaskFile* pTaskF = TARRAY_GET_ELEM(pFS->aQTaskInf, i);
|
||||||
if (pTaskF->version == pWriter->ever) {
|
if (pTaskF->version == pWriter->ever) {
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pTaskF->suid, pTaskF->level, pTaskF->version, primaryPath, fnameVer);
|
tdRSmaQTaskInfoGetFullName(pVnode, pTaskF->suid, pTaskF->level, pTaskF->version, pVnode->pTfs, fnameVer);
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pTaskF->suid, pTaskF->level, -1, primaryPath, fname);
|
tdRSmaQTaskInfoGetFullName(pVnode, pTaskF->suid, pTaskF->level, -1, pVnode->pTfs, fname);
|
||||||
|
|
||||||
pInFD = taosOpenFile(fnameVer, TD_FILE_READ);
|
pInFD = taosOpenFile(fnameVer, TD_FILE_READ);
|
||||||
if (pInFD == NULL) {
|
if (pInFD == NULL) {
|
||||||
|
@ -486,8 +483,7 @@ static int32_t rsmaSnapWriteQTaskInfo(SRSmaSnapWriter* pWriter, uint8_t* pData,
|
||||||
SQTaskFile qTaskFile = {
|
SQTaskFile qTaskFile = {
|
||||||
.nRef = 1, .level = pHdr->flag, .suid = pHdr->index, .version = pWriter->ever, .size = pHdr->size};
|
.nRef = 1, .level = pHdr->flag, .suid = pHdr->index, .version = pWriter->ever, .size = pHdr->size};
|
||||||
|
|
||||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pHdr->index, pHdr->flag, qTaskFile.version,
|
tdRSmaQTaskInfoGetFullName(pVnode, pHdr->index, pHdr->flag, qTaskFile.version, pVnode->pTfs, fname);
|
||||||
tfsGetPrimaryPath(pVnode->pTfs), fname);
|
|
||||||
|
|
||||||
fp = taosCreateFile(fname, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
fp = taosCreateFile(fname, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
|
|
|
@ -14,88 +14,72 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sma.h"
|
#include "sma.h"
|
||||||
|
#include "vnd.h"
|
||||||
|
|
||||||
#define TD_QTASKINFO_FNAME_PREFIX "main.tdb"
|
#define TD_QTASKINFO_FNAME_PREFIX "main.tdb"
|
||||||
|
|
||||||
void tdRSmaQTaskInfoGetFileName(int32_t vgId, int64_t suid, int8_t level, int64_t version, char *outputName) {
|
void tdRSmaQTaskInfoGetFileName(SVnode *pVnode, int64_t suid, int8_t level, int64_t version, char *outputName) {
|
||||||
tdRSmaGetFileName(vgId, NULL, VNODE_RSMA_DIR, TD_QTASKINFO_FNAME_PREFIX, suid, level, version, outputName);
|
tdRSmaGetFileName(pVnode, NULL, TD_QTASKINFO_FNAME_PREFIX, suid, level, version, outputName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdRSmaQTaskInfoGetFullName(int32_t vgId, int64_t suid, int8_t level, int64_t version, const char *path,
|
void tdRSmaQTaskInfoGetFullName(SVnode *pVnode, int64_t suid, int8_t level, int64_t version, STfs *pTfs,
|
||||||
char *outputName) {
|
char *outputName) {
|
||||||
tdRSmaGetFileName(vgId, path, VNODE_RSMA_DIR, TD_QTASKINFO_FNAME_PREFIX, suid, level, version, outputName);
|
tdRSmaGetFileName(pVnode, pTfs, TD_QTASKINFO_FNAME_PREFIX, suid, level, version, outputName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdRSmaQTaskInfoGetFullPath(int32_t vgId, int8_t level, const char *path, char *outputName) {
|
void tdRSmaQTaskInfoGetFullPath(SVnode *pVnode, int8_t level, STfs *pTfs, char *outputName) {
|
||||||
tdRSmaGetDirName(vgId, path, VNODE_RSMA_DIR, true, outputName);
|
tdRSmaGetDirName(pVnode, pTfs, true, outputName);
|
||||||
int32_t rsmaLen = strlen(outputName);
|
int32_t rsmaLen = strlen(outputName);
|
||||||
snprintf(outputName + rsmaLen, TSDB_FILENAME_LEN - rsmaLen, "%" PRIi8, level);
|
snprintf(outputName + rsmaLen, TSDB_FILENAME_LEN - rsmaLen, "%" PRIi8, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdRSmaQTaskInfoGetFullPathEx(int32_t vgId, tb_uid_t suid, int8_t level, const char *path, char *outputName) {
|
void tdRSmaQTaskInfoGetFullPathEx(SVnode *pVnode, tb_uid_t suid, int8_t level, STfs *pTfs, char *outputName) {
|
||||||
tdRSmaGetDirName(vgId, path, VNODE_RSMA_DIR, true, outputName);
|
tdRSmaGetDirName(pVnode, pTfs, true, outputName);
|
||||||
int32_t rsmaLen = strlen(outputName);
|
int32_t rsmaLen = strlen(outputName);
|
||||||
snprintf(outputName + rsmaLen, TSDB_FILENAME_LEN - rsmaLen, "%" PRIi8 "%s%" PRIi64, level, TD_DIRSEP, suid);
|
snprintf(outputName + rsmaLen, TSDB_FILENAME_LEN - rsmaLen, "%" PRIi8 "%s%" PRIi64, level, TD_DIRSEP, suid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdRSmaGetFileName(int32_t vgId, const char *pdname, const char *dname, const char *fname, int64_t suid,
|
void tdRSmaGetFileName(SVnode *pVnode, STfs *pTfs, const char *fname, int64_t suid, int8_t level, int64_t version,
|
||||||
int8_t level, int64_t version, char *outputName) {
|
char *outputName) {
|
||||||
|
int32_t offset = 0;
|
||||||
|
|
||||||
|
// vnode
|
||||||
|
vnodeGetPrimaryDir(pVnode->path, pTfs, outputName, TSDB_FILENAME_LEN);
|
||||||
|
offset = strlen(outputName);
|
||||||
|
|
||||||
|
// rsma
|
||||||
|
snprintf(outputName + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, VNODE_RSMA_DIR);
|
||||||
|
offset = strlen(outputName);
|
||||||
|
|
||||||
|
// level & suid || vgid
|
||||||
if (level >= 0 && suid > 0) {
|
if (level >= 0 && suid > 0) {
|
||||||
if (version >= 0) {
|
snprintf(outputName + offset, TSDB_FILENAME_LEN - offset - 1, "%s%" PRIi8 "%s%" PRIi64 "%s", TD_DIRSEP, level,
|
||||||
if (pdname) {
|
TD_DIRSEP, suid, TD_DIRSEP);
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "%s%svnode%svnode%d%s%s%s%" PRIi8 "%s%" PRIi64 "%s%s.%" PRIi64, pdname,
|
|
||||||
TD_DIRSEP, TD_DIRSEP, vgId, TD_DIRSEP, dname, TD_DIRSEP, level, TD_DIRSEP, suid, TD_DIRSEP, fname,
|
|
||||||
version);
|
|
||||||
} else {
|
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "vnode%svnode%d%s%s%s%" PRIi8 "%s%" PRIi64 "%s%s.%" PRIi64, TD_DIRSEP,
|
|
||||||
vgId, TD_DIRSEP, dname, TD_DIRSEP, level, TD_DIRSEP, suid, TD_DIRSEP, fname, version);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (pdname) {
|
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "%s%svnode%svnode%d%s%s%s%" PRIi8 "%s%" PRIi64 "%s%s", pdname,
|
|
||||||
TD_DIRSEP, TD_DIRSEP, vgId, TD_DIRSEP, dname, TD_DIRSEP, level, TD_DIRSEP, suid, TD_DIRSEP, fname);
|
|
||||||
} else {
|
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "vnode%svnode%d%s%s%s%" PRIi8 "%s%" PRIi64 "%s%s", TD_DIRSEP, vgId,
|
|
||||||
TD_DIRSEP, dname, TD_DIRSEP, level, TD_DIRSEP, suid, TD_DIRSEP, fname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (version >= 0) {
|
snprintf(outputName + offset, TSDB_FILENAME_LEN - offset - 1, "%sv%d", TD_DIRSEP, TD_VID(pVnode));
|
||||||
if (pdname) {
|
}
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "%s%svnode%svnode%d%s%s%sv%d%s%" PRIi64, pdname, TD_DIRSEP, TD_DIRSEP,
|
offset = strlen(outputName);
|
||||||
vgId, TD_DIRSEP, dname, TD_DIRSEP, vgId, fname, version);
|
|
||||||
} else {
|
// fname
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "vnode%svnode%d%s%s%sv%d%s%" PRIi64, TD_DIRSEP, vgId, TD_DIRSEP, dname,
|
snprintf(outputName + offset, TSDB_FILENAME_LEN - offset - 1, "%s", fname);
|
||||||
TD_DIRSEP, vgId, fname, version);
|
offset = strlen(outputName);
|
||||||
}
|
|
||||||
} else {
|
// version
|
||||||
if (pdname) {
|
if (version >= 0) {
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "%s%svnode%svnode%d%s%s%sv%d%s", pdname, TD_DIRSEP, TD_DIRSEP, vgId,
|
snprintf(outputName + offset, TSDB_FILENAME_LEN - offset - 1, ".%" PRIi64, version);
|
||||||
TD_DIRSEP, dname, TD_DIRSEP, vgId, fname);
|
|
||||||
} else {
|
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "vnode%svnode%d%s%s%sv%d%s", TD_DIRSEP, vgId, TD_DIRSEP, dname,
|
|
||||||
TD_DIRSEP, vgId, fname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdRSmaGetDirName(int32_t vgId, const char *pdname, const char *dname, bool endWithSep, char *outputName) {
|
void tdRSmaGetDirName(SVnode *pVnode, STfs *pTfs, bool endWithSep, char *outputName) {
|
||||||
if (pdname) {
|
int32_t offset = 0;
|
||||||
if (endWithSep) {
|
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "%s%svnode%svnode%d%s%s%s", pdname, TD_DIRSEP, TD_DIRSEP, vgId, TD_DIRSEP,
|
// vnode
|
||||||
dname, TD_DIRSEP);
|
vnodeGetPrimaryDir(pVnode->path, pTfs, outputName, TSDB_FILENAME_LEN);
|
||||||
} else {
|
offset = strlen(outputName);
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "%s%svnode%svnode%d%s%s", pdname, TD_DIRSEP, TD_DIRSEP, vgId, TD_DIRSEP,
|
|
||||||
dname);
|
// rsma
|
||||||
}
|
snprintf(outputName + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s%s", TD_DIRSEP, VNODE_RSMA_DIR,
|
||||||
} else {
|
(endWithSep ? TD_DIRSEP : ""));
|
||||||
if (endWithSep) {
|
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "vnode%svnode%d%s%s%s", TD_DIRSEP, vgId, TD_DIRSEP, dname, TD_DIRSEP);
|
|
||||||
} else {
|
|
||||||
snprintf(outputName, TSDB_FILENAME_LEN, "vnode%svnode%d%s%s", TD_DIRSEP, vgId, TD_DIRSEP, dname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// smaXXXUtil ================
|
// smaXXXUtil ================
|
||||||
|
@ -117,4 +101,4 @@ int32_t tdReleaseSmaRef(int32_t rsetId, int64_t refId) {
|
||||||
smaTrace("rsma release ref for rsetId:%d refId:%" PRIi64 " success", rsetId, refId);
|
smaTrace("rsma release ref for rsetId:%d refId:%" PRIi64 " success", rsetId, refId);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -934,7 +934,6 @@ int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
};
|
};
|
||||||
|
|
||||||
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
|
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
|
||||||
|
|
||||||
if (pTask != NULL) {
|
if (pTask != NULL) {
|
||||||
rsp.status = streamTaskCheckStatus(pTask);
|
rsp.status = streamTaskCheckStatus(pTask);
|
||||||
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
||||||
|
@ -1106,7 +1105,15 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
// 1. stop the related stream task, get the current scan wal version of stream task, ver.
|
// 1. stop the related stream task, get the current scan wal version of stream task, ver.
|
||||||
pStreamTask = streamMetaAcquireTask(pMeta, pTask->streamTaskId.taskId);
|
pStreamTask = streamMetaAcquireTask(pMeta, pTask->streamTaskId.taskId);
|
||||||
if (pStreamTask == NULL) {
|
if (pStreamTask == NULL) {
|
||||||
// todo handle error
|
qError("failed to find s-task:0x%x, it may have been destroyed, drop fill history task:%s",
|
||||||
|
pTask->streamTaskId.taskId, pTask->id.idStr);
|
||||||
|
|
||||||
|
pTask->status.taskStatus = TASK_STATUS__DROPPING;
|
||||||
|
tqDebug("s-task:%s scan-history-task set status to be dropping", pId);
|
||||||
|
|
||||||
|
streamMetaSaveTask(pMeta, pTask);
|
||||||
|
streamMetaReleaseTask(pMeta, pTask);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE);
|
ASSERT(pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE);
|
||||||
|
@ -1213,11 +1220,14 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify the downstream tasks to transfer executor state after handle all history blocks.
|
// notify the downstream tasks to transfer executor state after handle all history blocks.
|
||||||
int32_t tqProcessTaskTransferStateReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
int32_t tqProcessTaskTransferStateReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
SStreamTransferReq req;
|
char* pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||||
|
int32_t len = pMsg->contLen - sizeof(SMsgHead);
|
||||||
|
|
||||||
|
SStreamTransferReq req = {0};
|
||||||
|
|
||||||
SDecoder decoder;
|
SDecoder decoder;
|
||||||
tDecoderInit(&decoder, (uint8_t*)msg, msgLen);
|
tDecoderInit(&decoder, (uint8_t*)pReq, len);
|
||||||
int32_t code = tDecodeStreamScanHistoryFinishReq(&decoder, &req);
|
int32_t code = tDecodeStreamScanHistoryFinishReq(&decoder, &req);
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
|
|
||||||
|
@ -1227,25 +1237,33 @@ int32_t tqProcessTaskTransferStateReq(STQ* pTq, int64_t sversion, char* msg, int
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t remain = streamAlignTransferState(pTask);
|
||||||
|
if (remain > 0) {
|
||||||
|
tqDebug("s-task:%s receive transfer state msg, remain:%d", pTask->id.idStr, remain);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// transfer the ownership of executor state
|
// transfer the ownership of executor state
|
||||||
streamTaskReleaseState(pTask);
|
tqDebug("s-task:%s all upstream tasks end transfer msg", pTask->id.idStr);
|
||||||
tqDebug("s-task:%s receive state transfer req", pTask->id.idStr);
|
|
||||||
|
|
||||||
// related stream task load the state from the state storage backend
|
// related stream task load the state from the state storage backend
|
||||||
SStreamTask* pStreamTask = streamMetaAcquireTask(pTq->pStreamMeta, pTask->streamTaskId.taskId);
|
SStreamTask* pStreamTask = streamMetaAcquireTask(pTq->pStreamMeta, pTask->streamTaskId.taskId);
|
||||||
if (pStreamTask == NULL) {
|
if (pStreamTask == NULL) {
|
||||||
|
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
||||||
tqError("failed to find related stream task:0x%x, it may have been dropped already", req.taskId);
|
tqError("failed to find related stream task:0x%x, it may have been dropped already", req.taskId);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// when all upstream tasks have notified the this task to start transfer state, then we start the transfer procedure.
|
||||||
|
streamTaskReleaseState(pTask);
|
||||||
streamTaskReloadState(pStreamTask);
|
streamTaskReloadState(pStreamTask);
|
||||||
|
streamMetaReleaseTask(pTq->pStreamMeta, pStreamTask);
|
||||||
|
|
||||||
ASSERT(pTask->streamTaskId.taskId != 0);
|
ASSERT(pTask->streamTaskId.taskId != 0);
|
||||||
pTask->status.transferState = true;
|
pTask->status.transferState = true;
|
||||||
|
|
||||||
streamSchedExec(pTask);
|
streamSchedExec(pTask);
|
||||||
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
#include "vnd.h"
|
||||||
|
|
||||||
#define ROCKS_BATCH_SIZE (4096)
|
#define ROCKS_BATCH_SIZE (4096)
|
||||||
|
|
||||||
|
@ -58,16 +59,10 @@ typedef struct {
|
||||||
|
|
||||||
static void tsdbGetRocksPath(STsdb *pTsdb, char *path) {
|
static void tsdbGetRocksPath(STsdb *pTsdb, char *path) {
|
||||||
SVnode *pVnode = pTsdb->pVnode;
|
SVnode *pVnode = pTsdb->pVnode;
|
||||||
if (pVnode->pTfs) {
|
vnodeGetPrimaryDir(pTsdb->path, pVnode->pTfs, path, TSDB_FILENAME_LEN);
|
||||||
if (path) {
|
|
||||||
snprintf(path, TSDB_FILENAME_LEN, "%s%s%s%scache.rdb", tfsGetPrimaryPath(pTsdb->pVnode->pTfs), TD_DIRSEP,
|
int32_t offset = strlen(path);
|
||||||
pTsdb->path, TD_DIRSEP);
|
snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%scache.rdb", TD_DIRSEP);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (path) {
|
|
||||||
snprintf(path, TSDB_FILENAME_LEN, "%s%scache.rdb", pTsdb->path, TD_DIRSEP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *myCmpName(void *state) {
|
static const char *myCmpName(void *state) {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
#include "vnd.h"
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
static int32_t tsdbFSToBinary(uint8_t *p, STsdbFS *pFS) {
|
static int32_t tsdbFSToBinary(uint8_t *p, STsdbFS *pFS) {
|
||||||
|
@ -271,22 +272,20 @@ int32_t tDFileSetCmprFn(const void *p1, const void *p2) {
|
||||||
|
|
||||||
void tsdbGetCurrentFName(STsdb *pTsdb, char *current, char *current_t) {
|
void tsdbGetCurrentFName(STsdb *pTsdb, char *current, char *current_t) {
|
||||||
SVnode *pVnode = pTsdb->pVnode;
|
SVnode *pVnode = pTsdb->pVnode;
|
||||||
if (pVnode->pTfs) {
|
int32_t offset = 0;
|
||||||
if (current) {
|
|
||||||
snprintf(current, TSDB_FILENAME_LEN - 1, "%s%s%s%sCURRENT", tfsGetPrimaryPath(pTsdb->pVnode->pTfs), TD_DIRSEP,
|
// CURRENT
|
||||||
pTsdb->path, TD_DIRSEP);
|
if (current) {
|
||||||
}
|
vnodeGetPrimaryDir(pTsdb->path, pVnode->pTfs, current, TSDB_FILENAME_LEN);
|
||||||
if (current_t) {
|
offset = strlen(current);
|
||||||
snprintf(current_t, TSDB_FILENAME_LEN - 1, "%s%s%s%sCURRENT.t", tfsGetPrimaryPath(pTsdb->pVnode->pTfs), TD_DIRSEP,
|
snprintf(current + offset, TSDB_FILENAME_LEN - offset - 1, "%sCURRENT", TD_DIRSEP);
|
||||||
pTsdb->path, TD_DIRSEP);
|
}
|
||||||
}
|
|
||||||
} else {
|
// CURRENT.t
|
||||||
if (current) {
|
if (current_t) {
|
||||||
snprintf(current, TSDB_FILENAME_LEN - 1, "%s%sCURRENT", pTsdb->path, TD_DIRSEP);
|
vnodeGetPrimaryDir(pTsdb->path, pVnode->pTfs, current_t, TSDB_FILENAME_LEN);
|
||||||
}
|
offset = strlen(current_t);
|
||||||
if (current_t) {
|
snprintf(current_t + offset, TSDB_FILENAME_LEN - offset - 1, "%sCURRENT.t", TD_DIRSEP);
|
||||||
snprintf(current_t, TSDB_FILENAME_LEN - 1, "%s%sCURRENT.t", pTsdb->path, TD_DIRSEP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,4 +1141,4 @@ void tsdbFSUnref(STsdb *pTsdb, STsdbFS *pFS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayDestroy(pFS->aDFileSet);
|
taosArrayDestroy(pFS->aDFileSet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
#include "vnd.h"
|
||||||
|
|
||||||
int32_t tPutHeadFile(uint8_t *p, SHeadFile *pHeadFile) {
|
int32_t tPutHeadFile(uint8_t *p, SHeadFile *pHeadFile) {
|
||||||
int32_t n = 0;
|
int32_t n = 0;
|
||||||
|
@ -282,8 +283,12 @@ int32_t tGetDFileSet(uint8_t *p, SDFileSet *pSet) {
|
||||||
|
|
||||||
// SDelFile ===============================================
|
// SDelFile ===============================================
|
||||||
void tsdbDelFileName(STsdb *pTsdb, SDelFile *pFile, char fname[]) {
|
void tsdbDelFileName(STsdb *pTsdb, SDelFile *pFile, char fname[]) {
|
||||||
snprintf(fname, TSDB_FILENAME_LEN - 1, "%s%s%s%sv%dver%" PRId64 "%s", tfsGetPrimaryPath(pTsdb->pVnode->pTfs),
|
int32_t offset = 0;
|
||||||
TD_DIRSEP, pTsdb->path, TD_DIRSEP, TD_VID(pTsdb->pVnode), pFile->commitID, ".del");
|
|
||||||
|
vnodeGetPrimaryDir(pTsdb->path, pTsdb->pVnode->pTfs, fname, TSDB_FILENAME_LEN);
|
||||||
|
offset = strlen(fname);
|
||||||
|
snprintf((char *)fname + offset, TSDB_FILENAME_LEN - offset - 1, "%sv%dver%" PRId64 ".del", TD_DIRSEP,
|
||||||
|
TD_VID(pTsdb->pVnode), pFile->commitID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tPutDelFile(uint8_t *p, SDelFile *pDelFile) {
|
int32_t tPutDelFile(uint8_t *p, SDelFile *pDelFile) {
|
||||||
|
|
|
@ -295,11 +295,7 @@ static int32_t vnodePrepareCommit(SVnode *pVnode, SCommitInfo *pInfo) {
|
||||||
pInfo->txn = metaGetTxn(pVnode->pMeta);
|
pInfo->txn = metaGetTxn(pVnode->pMeta);
|
||||||
|
|
||||||
// save info
|
// save info
|
||||||
if (pVnode->pTfs) {
|
vnodeGetPrimaryDir(pVnode->path, pVnode->pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path);
|
|
||||||
} else {
|
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s", pVnode->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
vDebug("vgId:%d, save config while prepare commit", TD_VID(pVnode));
|
vDebug("vgId:%d, save config while prepare commit", TD_VID(pVnode));
|
||||||
if (vnodeSaveInfo(dir, &pInfo->info) < 0) {
|
if (vnodeSaveInfo(dir, &pInfo->info) < 0) {
|
||||||
|
@ -432,11 +428,7 @@ static int vnodeCommitImpl(SCommitInfo *pInfo) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pVnode->pTfs) {
|
vnodeGetPrimaryDir(pVnode->path, pVnode->pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path);
|
|
||||||
} else {
|
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s", pVnode->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
syncBeginSnapshot(pVnode->sync, pInfo->info.state.committed);
|
syncBeginSnapshot(pVnode->sync, pInfo->info.state.committed);
|
||||||
|
|
||||||
|
@ -497,16 +489,22 @@ _exit:
|
||||||
|
|
||||||
bool vnodeShouldRollback(SVnode *pVnode) {
|
bool vnodeShouldRollback(SVnode *pVnode) {
|
||||||
char tFName[TSDB_FILENAME_LEN] = {0};
|
char tFName[TSDB_FILENAME_LEN] = {0};
|
||||||
snprintf(tFName, TSDB_FILENAME_LEN, "%s%s%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path, TD_DIRSEP,
|
int32_t offset = 0;
|
||||||
VND_INFO_FNAME_TMP);
|
|
||||||
|
vnodeGetPrimaryDir(pVnode->path, pVnode->pTfs, tFName, TSDB_FILENAME_LEN);
|
||||||
|
offset = strlen(tFName);
|
||||||
|
snprintf(tFName + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, VND_INFO_FNAME_TMP);
|
||||||
|
|
||||||
return taosCheckExistFile(tFName);
|
return taosCheckExistFile(tFName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vnodeRollback(SVnode *pVnode) {
|
void vnodeRollback(SVnode *pVnode) {
|
||||||
char tFName[TSDB_FILENAME_LEN] = {0};
|
char tFName[TSDB_FILENAME_LEN] = {0};
|
||||||
snprintf(tFName, TSDB_FILENAME_LEN, "%s%s%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path, TD_DIRSEP,
|
int32_t offset = 0;
|
||||||
VND_INFO_FNAME_TMP);
|
|
||||||
|
vnodeGetPrimaryDir(pVnode->path, pVnode->pTfs, tFName, TSDB_FILENAME_LEN);
|
||||||
|
offset = strlen(tFName);
|
||||||
|
snprintf(tFName + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, VND_INFO_FNAME_TMP);
|
||||||
|
|
||||||
(void)taosRemoveFile(tFName);
|
(void)taosRemoveFile(tFName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,16 @@
|
||||||
|
|
||||||
#include "vnd.h"
|
#include "vnd.h"
|
||||||
|
|
||||||
|
int32_t vnodeGetPrimaryDir(const char *relPath, STfs *pTfs, char *buf, size_t bufLen) {
|
||||||
|
if (pTfs) {
|
||||||
|
snprintf(buf, bufLen - 1, "%s%s%s", tfsGetPrimaryPath(pTfs), TD_DIRSEP, relPath);
|
||||||
|
} else {
|
||||||
|
snprintf(buf, bufLen - 1, "%s", relPath);
|
||||||
|
}
|
||||||
|
buf[bufLen - 1] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
|
int32_t vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
|
||||||
SVnodeInfo info = {0};
|
SVnodeInfo info = {0};
|
||||||
char dir[TSDB_FILENAME_LEN] = {0};
|
char dir[TSDB_FILENAME_LEN] = {0};
|
||||||
|
@ -26,17 +36,9 @@ int32_t vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create vnode env
|
// create vnode env
|
||||||
if (pTfs) {
|
vnodeGetPrimaryDir(path, pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
if (tfsMkdirAt(pTfs, path, (SDiskID){0}) < 0) {
|
if (taosMkDir(dir)) {
|
||||||
vError("vgId:%d, failed to create vnode since:%s", pCfg->vgId, tstrerror(terrno));
|
return TAOS_SYSTEM_ERROR(errno);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pTfs), TD_DIRSEP, path);
|
|
||||||
} else {
|
|
||||||
if (taosMkDir(path)) {
|
|
||||||
return TAOS_SYSTEM_ERROR(errno);
|
|
||||||
}
|
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s", path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCfg) {
|
if (pCfg) {
|
||||||
|
@ -63,11 +65,7 @@ int32_t vnodeAlterReplica(const char *path, SAlterVnodeReplicaReq *pReq, STfs *p
|
||||||
char dir[TSDB_FILENAME_LEN] = {0};
|
char dir[TSDB_FILENAME_LEN] = {0};
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
if (pTfs) {
|
vnodeGetPrimaryDir(path, pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pTfs), TD_DIRSEP, path);
|
|
||||||
} else {
|
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = vnodeLoadInfo(dir, &info);
|
ret = vnodeLoadInfo(dir, &info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -185,21 +183,12 @@ int32_t vnodeRenameVgroupId(const char *srcPath, const char *dstPath, int32_t sr
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t vnodeGetAbsDir(const char *relPath, STfs *pTfs, char *buf, size_t bufLen) {
|
|
||||||
if (pTfs) {
|
|
||||||
snprintf(buf, bufLen, "%s%s%s", tfsGetPrimaryPath(pTfs), TD_DIRSEP, relPath);
|
|
||||||
} else {
|
|
||||||
snprintf(buf, bufLen, "%s", relPath);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t vnodeAlterHashRange(const char *srcPath, const char *dstPath, SAlterVnodeHashRangeReq *pReq, STfs *pTfs) {
|
int32_t vnodeAlterHashRange(const char *srcPath, const char *dstPath, SAlterVnodeHashRangeReq *pReq, STfs *pTfs) {
|
||||||
SVnodeInfo info = {0};
|
SVnodeInfo info = {0};
|
||||||
char dir[TSDB_FILENAME_LEN] = {0};
|
char dir[TSDB_FILENAME_LEN] = {0};
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
vnodeGetAbsDir(srcPath, pTfs, dir, TSDB_FILENAME_LEN);
|
vnodeGetPrimaryDir(srcPath, pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
|
|
||||||
ret = vnodeLoadInfo(dir, &info);
|
ret = vnodeLoadInfo(dir, &info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -258,7 +247,7 @@ int32_t vnodeRestoreVgroupId(const char *srcPath, const char *dstPath, int32_t s
|
||||||
SVnodeInfo info = {0};
|
SVnodeInfo info = {0};
|
||||||
char dir[TSDB_FILENAME_LEN] = {0};
|
char dir[TSDB_FILENAME_LEN] = {0};
|
||||||
|
|
||||||
vnodeGetAbsDir(dstPath, pTfs, dir, TSDB_FILENAME_LEN);
|
vnodeGetPrimaryDir(dstPath, pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
if (vnodeLoadInfo(dir, &info) == 0) {
|
if (vnodeLoadInfo(dir, &info) == 0) {
|
||||||
if (info.config.vgId != dstVgId) {
|
if (info.config.vgId != dstVgId) {
|
||||||
vError("vgId:%d, unexpected vnode config.vgId:%d", dstVgId, info.config.vgId);
|
vError("vgId:%d, unexpected vnode config.vgId:%d", dstVgId, info.config.vgId);
|
||||||
|
@ -267,7 +256,7 @@ int32_t vnodeRestoreVgroupId(const char *srcPath, const char *dstPath, int32_t s
|
||||||
return dstVgId;
|
return dstVgId;
|
||||||
}
|
}
|
||||||
|
|
||||||
vnodeGetAbsDir(srcPath, pTfs, dir, TSDB_FILENAME_LEN);
|
vnodeGetPrimaryDir(srcPath, pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
if (vnodeLoadInfo(dir, &info) < 0) {
|
if (vnodeLoadInfo(dir, &info) < 0) {
|
||||||
vError("vgId:%d, failed to read vnode config from %s since %s", srcVgId, srcPath, tstrerror(terrno));
|
vError("vgId:%d, failed to read vnode config from %s since %s", srcVgId, srcPath, tstrerror(terrno));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -302,11 +291,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
||||||
char tdir[TSDB_FILENAME_LEN * 2] = {0};
|
char tdir[TSDB_FILENAME_LEN * 2] = {0};
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
if (pTfs) {
|
vnodeGetPrimaryDir(path, pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pTfs), TD_DIRSEP, path);
|
|
||||||
} else {
|
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
info.config = vnodeCfgDefault;
|
info.config = vnodeCfgDefault;
|
||||||
|
|
||||||
|
|
|
@ -27,4 +27,4 @@ int32_t vnodeSyncRetention(SVnode *pVnode, int64_t now) {
|
||||||
code = tsdbSyncRetention(pVnode->pTsdb, now);
|
code = tsdbSyncRetention(pVnode->pTsdb, now);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
|
@ -91,12 +91,11 @@ int32_t vnodeSnapRead(SVSnapReader *pReader, uint8_t **ppData, uint32_t *nData)
|
||||||
// FIXME: if commit multiple times and the config changed?
|
// FIXME: if commit multiple times and the config changed?
|
||||||
if (!pReader->cfgDone) {
|
if (!pReader->cfgDone) {
|
||||||
char fName[TSDB_FILENAME_LEN];
|
char fName[TSDB_FILENAME_LEN];
|
||||||
if (pReader->pVnode->pTfs) {
|
int32_t offset = 0;
|
||||||
snprintf(fName, TSDB_FILENAME_LEN, "%s%s%s%s%s", tfsGetPrimaryPath(pReader->pVnode->pTfs), TD_DIRSEP,
|
|
||||||
pReader->pVnode->path, TD_DIRSEP, VND_INFO_FNAME);
|
vnodeGetPrimaryDir(pReader->pVnode->path, pReader->pVnode->pTfs, fName, TSDB_FILENAME_LEN);
|
||||||
} else {
|
offset = strlen(fName);
|
||||||
snprintf(fName, TSDB_FILENAME_LEN, "%s%s%s", pReader->pVnode->path, TD_DIRSEP, VND_INFO_FNAME);
|
snprintf(fName + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, VND_INFO_FNAME);
|
||||||
}
|
|
||||||
|
|
||||||
TdFilePtr pFile = taosOpenFile(fName, TD_FILE_READ);
|
TdFilePtr pFile = taosOpenFile(fName, TD_FILE_READ);
|
||||||
if (NULL == pFile) {
|
if (NULL == pFile) {
|
||||||
|
@ -344,11 +343,7 @@ int32_t vnodeSnapWriterClose(SVSnapWriter *pWriter, int8_t rollback, SSnapshot *
|
||||||
.applyTerm = pWriter->info.state.commitTerm};
|
.applyTerm = pWriter->info.state.commitTerm};
|
||||||
pVnode->statis = pWriter->info.statis;
|
pVnode->statis = pWriter->info.statis;
|
||||||
char dir[TSDB_FILENAME_LEN] = {0};
|
char dir[TSDB_FILENAME_LEN] = {0};
|
||||||
if (pWriter->pVnode->pTfs) {
|
vnodeGetPrimaryDir(pVnode->path, pVnode->pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path);
|
|
||||||
} else {
|
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s", pWriter->pVnode->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
vnodeCommitInfo(dir);
|
vnodeCommitInfo(dir);
|
||||||
} else {
|
} else {
|
||||||
|
@ -400,12 +395,7 @@ static int32_t vnodeSnapWriteInfo(SVSnapWriter *pWriter, uint8_t *pData, uint32_
|
||||||
|
|
||||||
// modify info as needed
|
// modify info as needed
|
||||||
char dir[TSDB_FILENAME_LEN] = {0};
|
char dir[TSDB_FILENAME_LEN] = {0};
|
||||||
if (pWriter->pVnode->pTfs) {
|
vnodeGetPrimaryDir(pWriter->pVnode->path, pWriter->pVnode->pTfs, dir, TSDB_FILENAME_LEN);
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pWriter->pVnode->pTfs), TD_DIRSEP,
|
|
||||||
pWriter->pVnode->path);
|
|
||||||
} else {
|
|
||||||
snprintf(dir, TSDB_FILENAME_LEN, "%s", pWriter->pVnode->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
SVnodeStats vndStats = pWriter->info.config.vndStats;
|
SVnodeStats vndStats = pWriter->info.config.vndStats;
|
||||||
SVnode *pVnode = pWriter->pVnode;
|
SVnode *pVnode = pWriter->pVnode;
|
||||||
|
|
|
@ -661,11 +661,8 @@ int32_t vnodeProcessStreamMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo)
|
||||||
return tqProcessTaskRetrieveRsp(pVnode->pTq, pMsg);
|
return tqProcessTaskRetrieveRsp(pVnode->pTq, pMsg);
|
||||||
case TDMT_VND_STREAM_SCAN_HISTORY:
|
case TDMT_VND_STREAM_SCAN_HISTORY:
|
||||||
return tqProcessTaskScanHistory(pVnode->pTq, pMsg);
|
return tqProcessTaskScanHistory(pVnode->pTq, pMsg);
|
||||||
case TDMT_STREAM_TRANSFER_STATE: {
|
case TDMT_STREAM_TRANSFER_STATE:
|
||||||
char* pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
return tqProcessTaskTransferStateReq(pVnode->pTq, pMsg);
|
||||||
int32_t len = pMsg->contLen - sizeof(SMsgHead);
|
|
||||||
return tqProcessTaskTransferStateReq(pVnode->pTq, 0, pReq, len);
|
|
||||||
}
|
|
||||||
case TDMT_STREAM_SCAN_HISTORY_FINISH:
|
case TDMT_STREAM_SCAN_HISTORY_FINISH:
|
||||||
return tqProcessStreamTaskScanHistoryFinishReq(pVnode->pTq, pMsg);
|
return tqProcessStreamTaskScanHistoryFinishReq(pVnode->pTq, pMsg);
|
||||||
case TDMT_STREAM_SCAN_HISTORY_FINISH_RSP:
|
case TDMT_STREAM_SCAN_HISTORY_FINISH_RSP:
|
||||||
|
|
|
@ -286,20 +286,24 @@ static void setCreateDBResultIntoDataBlock(SSDataBlock* pBlock, char* dbName, ch
|
||||||
hashPrefix = pCfg->hashPrefix + dbFNameLen + 1;
|
hashPrefix = pCfg->hashPrefix + dbFNameLen + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len += sprintf(
|
if (IS_SYS_DBNAME(dbName)) {
|
||||||
buf2 + VARSTR_HEADER_SIZE,
|
len += sprintf(buf2 + VARSTR_HEADER_SIZE, "CREATE DATABASE `%s`", dbName);
|
||||||
"CREATE DATABASE `%s` BUFFER %d CACHESIZE %d CACHEMODEL '%s' COMP %d DURATION %dm "
|
} else {
|
||||||
"WAL_FSYNC_PERIOD %d MAXROWS %d MINROWS %d STT_TRIGGER %d KEEP %dm,%dm,%dm PAGES %d PAGESIZE %d PRECISION '%s' REPLICA %d "
|
len += sprintf(
|
||||||
"WAL_LEVEL %d VGROUPS %d SINGLE_STABLE %d TABLE_PREFIX %d TABLE_SUFFIX %d TSDB_PAGESIZE %d "
|
buf2 + VARSTR_HEADER_SIZE,
|
||||||
"WAL_RETENTION_PERIOD %d WAL_RETENTION_SIZE %" PRId64,
|
"CREATE DATABASE `%s` BUFFER %d CACHESIZE %d CACHEMODEL '%s' COMP %d DURATION %dm "
|
||||||
dbName, pCfg->buffer, pCfg->cacheSize, cacheModelStr(pCfg->cacheLast), pCfg->compression, pCfg->daysPerFile,
|
"WAL_FSYNC_PERIOD %d MAXROWS %d MINROWS %d STT_TRIGGER %d KEEP %dm,%dm,%dm PAGES %d PAGESIZE %d PRECISION '%s' REPLICA %d "
|
||||||
pCfg->walFsyncPeriod, pCfg->maxRows, pCfg->minRows, pCfg->sstTrigger, pCfg->daysToKeep0, pCfg->daysToKeep1, pCfg->daysToKeep2,
|
"WAL_LEVEL %d VGROUPS %d SINGLE_STABLE %d TABLE_PREFIX %d TABLE_SUFFIX %d TSDB_PAGESIZE %d "
|
||||||
pCfg->pages, pCfg->pageSize, prec, pCfg->replications, pCfg->walLevel, pCfg->numOfVgroups,
|
"WAL_RETENTION_PERIOD %d WAL_RETENTION_SIZE %" PRId64,
|
||||||
1 == pCfg->numOfStables, hashPrefix, pCfg->hashSuffix, pCfg->tsdbPageSize, pCfg->walRetentionPeriod, pCfg->walRetentionSize);
|
dbName, pCfg->buffer, pCfg->cacheSize, cacheModelStr(pCfg->cacheLast), pCfg->compression, pCfg->daysPerFile,
|
||||||
|
pCfg->walFsyncPeriod, pCfg->maxRows, pCfg->minRows, pCfg->sstTrigger, pCfg->daysToKeep0, pCfg->daysToKeep1, pCfg->daysToKeep2,
|
||||||
|
pCfg->pages, pCfg->pageSize, prec, pCfg->replications, pCfg->walLevel, pCfg->numOfVgroups,
|
||||||
|
1 == pCfg->numOfStables, hashPrefix, pCfg->hashSuffix, pCfg->tsdbPageSize, pCfg->walRetentionPeriod, pCfg->walRetentionSize);
|
||||||
|
|
||||||
if (retentions) {
|
if (retentions) {
|
||||||
len += sprintf(buf2 + VARSTR_HEADER_SIZE + len, " RETENTIONS %s", retentions);
|
len += sprintf(buf2 + VARSTR_HEADER_SIZE + len, " RETENTIONS %s", retentions);
|
||||||
taosMemoryFree(retentions);
|
taosMemoryFree(retentions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(varDataLen(buf2)) = len;
|
(varDataLen(buf2)) = len;
|
||||||
|
|
|
@ -288,9 +288,8 @@ qTaskInfo_t qCreateQueueExecTaskInfo(void* msg, SReadHandle* pReaderHandle, int3
|
||||||
return pTaskInfo;
|
return pTaskInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SSubplan* pPlan = NULL;
|
SSubplan* pPlan = NULL;
|
||||||
|
int32_t code = qStringToSubplan(msg, &pPlan);
|
||||||
int32_t code = qStringToSubplan(msg, &pPlan);
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
terrno = code;
|
terrno = code;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -335,6 +334,7 @@ qTaskInfo_t qCreateStreamExecTaskInfo(void* msg, SReadHandle* readers, int32_t v
|
||||||
qTaskInfo_t pTaskInfo = NULL;
|
qTaskInfo_t pTaskInfo = NULL;
|
||||||
code = qCreateExecTask(readers, vgId, 0, pPlan, &pTaskInfo, NULL, NULL, OPTR_EXEC_MODEL_STREAM);
|
code = qCreateExecTask(readers, vgId, 0, pPlan, &pTaskInfo, NULL, NULL, OPTR_EXEC_MODEL_STREAM);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
nodesDestroyNode((SNode*)pPlan);
|
||||||
qDestroyTask(pTaskInfo);
|
qDestroyTask(pTaskInfo);
|
||||||
terrno = code;
|
terrno = code;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -447,6 +447,7 @@ cmd ::= SHOW MNODES.
|
||||||
cmd ::= SHOW QNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT); }
|
cmd ::= SHOW QNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT); }
|
||||||
cmd ::= SHOW FUNCTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); }
|
cmd ::= SHOW FUNCTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); }
|
||||||
cmd ::= SHOW INDEXES FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, B, A, OP_TYPE_EQUAL); }
|
cmd ::= SHOW INDEXES FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, B, A, OP_TYPE_EQUAL); }
|
||||||
|
cmd ::= SHOW INDEXES FROM db_name(B) NK_DOT table_name(A). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, createIdentifierValueNode(pCxt, &B), createIdentifierValueNode(pCxt, &A), OP_TYPE_EQUAL); }
|
||||||
cmd ::= SHOW STREAMS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT); }
|
cmd ::= SHOW STREAMS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT); }
|
||||||
cmd ::= SHOW ACCOUNTS. { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
|
cmd ::= SHOW ACCOUNTS. { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
|
||||||
cmd ::= SHOW APPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT); }
|
cmd ::= SHOW APPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT); }
|
||||||
|
@ -471,7 +472,9 @@ cmd ::= SHOW TABLE DISTRIBUTED full_table_name(A).
|
||||||
cmd ::= SHOW CONSUMERS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONSUMERS_STMT); }
|
cmd ::= SHOW CONSUMERS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONSUMERS_STMT); }
|
||||||
cmd ::= SHOW SUBSCRIPTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SUBSCRIPTIONS_STMT); }
|
cmd ::= SHOW SUBSCRIPTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SUBSCRIPTIONS_STMT); }
|
||||||
cmd ::= SHOW TAGS FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, B, A, OP_TYPE_EQUAL); }
|
cmd ::= SHOW TAGS FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, B, A, OP_TYPE_EQUAL); }
|
||||||
|
cmd ::= SHOW TAGS FROM db_name(B) NK_DOT table_name(A). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, createIdentifierValueNode(pCxt, &B), createIdentifierValueNode(pCxt, &A), OP_TYPE_EQUAL); }
|
||||||
cmd ::= SHOW TABLE TAGS tag_list_opt(C) FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowTableTagsStmt(pCxt, A, B, C); }
|
cmd ::= SHOW TABLE TAGS tag_list_opt(C) FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowTableTagsStmt(pCxt, A, B, C); }
|
||||||
|
cmd ::= SHOW TABLE TAGS tag_list_opt(C) FROM db_name(B) NK_DOT table_name(A). { pCxt->pRootNode = createShowTableTagsStmt(pCxt, createIdentifierValueNode(pCxt, &A), createIdentifierValueNode(pCxt, &B), C); }
|
||||||
cmd ::= SHOW VNODES NK_INTEGER(A). { pCxt->pRootNode = createShowVnodesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &A), NULL); }
|
cmd ::= SHOW VNODES NK_INTEGER(A). { pCxt->pRootNode = createShowVnodesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &A), NULL); }
|
||||||
cmd ::= SHOW VNODES NK_STRING(A). { pCxt->pRootNode = createShowVnodesStmt(pCxt, NULL, createValueNode(pCxt, TSDB_DATA_TYPE_VARCHAR, &A)); }
|
cmd ::= SHOW VNODES NK_STRING(A). { pCxt->pRootNode = createShowVnodesStmt(pCxt, NULL, createValueNode(pCxt, TSDB_DATA_TYPE_VARCHAR, &A)); }
|
||||||
// show alive
|
// show alive
|
||||||
|
|
|
@ -509,6 +509,10 @@ static int32_t getDBVgVersion(STranslateContext* pCxt, const char* pDbFName, int
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t getDBCfg(STranslateContext* pCxt, const char* pDbName, SDbCfgInfo* pInfo) {
|
static int32_t getDBCfg(STranslateContext* pCxt, const char* pDbName, SDbCfgInfo* pInfo) {
|
||||||
|
if (IS_SYS_DBNAME(pDbName)) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
SParseContext* pParCxt = pCxt->pParseCxt;
|
SParseContext* pParCxt = pCxt->pParseCxt;
|
||||||
SName name;
|
SName name;
|
||||||
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pDbName, strlen(pDbName));
|
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pDbName, strlen(pDbName));
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -61,7 +61,7 @@ char* createStreamTaskIdStr(int64_t streamId, int32_t taskId) {
|
||||||
return taosStrdup(buf);
|
return taosStrdup(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamSchedByTimer(void* param, void* tmrId) {
|
static void streamSchedByTimer(void* param, void* tmrId) {
|
||||||
SStreamTask* pTask = (void*)param;
|
SStreamTask* pTask = (void*)param;
|
||||||
|
|
||||||
int8_t status = atomic_load_8(&pTask->triggerStatus);
|
int8_t status = atomic_load_8(&pTask->triggerStatus);
|
||||||
|
|
|
@ -352,11 +352,12 @@ static void waitForTaskIdle(SStreamTask* pTask, SStreamTask* pStreamTask) {
|
||||||
static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) {
|
static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) {
|
||||||
SStreamTask* pStreamTask = streamMetaAcquireTask(pTask->pMeta, pTask->streamTaskId.taskId);
|
SStreamTask* pStreamTask = streamMetaAcquireTask(pTask->pMeta, pTask->streamTaskId.taskId);
|
||||||
if (pStreamTask == NULL) {
|
if (pStreamTask == NULL) {
|
||||||
qError("s-task:%s failed to find related stream task:0x%x, it may have been destoryed or closed",
|
qError("s-task:%s failed to find related stream task:0x%x, it may have been destroyed or closed",
|
||||||
pTask->id.idStr, pTask->streamTaskId.taskId);
|
pTask->id.idStr, pTask->streamTaskId.taskId);
|
||||||
return TSDB_CODE_STREAM_TASK_NOT_EXIST;
|
return TSDB_CODE_STREAM_TASK_NOT_EXIST;
|
||||||
} else {
|
} else {
|
||||||
qDebug("s-task:%s scan history task end, update stream task:%s info, transfer exec state", pTask->id.idStr, pStreamTask->id.idStr);
|
qDebug("s-task:%s fill-history task end, update related stream task:%s info, transfer exec state", pTask->id.idStr,
|
||||||
|
pStreamTask->id.idStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(pStreamTask != NULL && pStreamTask->historyTaskId.taskId == pTask->id.taskId);
|
ASSERT(pStreamTask != NULL && pStreamTask->historyTaskId.taskId == pTask->id.taskId);
|
||||||
|
@ -369,6 +370,7 @@ static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) {
|
||||||
} else {
|
} else {
|
||||||
ASSERT(pStreamTask->status.taskStatus == TASK_STATUS__NORMAL);
|
ASSERT(pStreamTask->status.taskStatus == TASK_STATUS__NORMAL);
|
||||||
pStreamTask->status.taskStatus = TASK_STATUS__HALT;
|
pStreamTask->status.taskStatus = TASK_STATUS__HALT;
|
||||||
|
qDebug("s-task:%s status: halt by related fill history task:%s", pStreamTask->id.idStr, pTask->id.idStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for the stream task to be idle
|
// wait for the stream task to be idle
|
||||||
|
@ -477,6 +479,7 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
||||||
ASSERT(batchSize == 0);
|
ASSERT(batchSize == 0);
|
||||||
if (pTask->info.fillHistory && pTask->status.transferState) {
|
if (pTask->info.fillHistory && pTask->status.transferState) {
|
||||||
int32_t code = streamTransferStateToStreamTask(pTask);
|
int32_t code = streamTransferStateToStreamTask(pTask);
|
||||||
|
pTask->status.transferState = false; // reset this value, to avoid transfer state again
|
||||||
if (code != TSDB_CODE_SUCCESS) { // todo handle this
|
if (code != TSDB_CODE_SUCCESS) { // todo handle this
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -611,3 +614,13 @@ int32_t streamTaskReloadState(SStreamTask* pTask) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t streamAlignTransferState(SStreamTask* pTask) {
|
||||||
|
int32_t numOfUpstream = taosArrayGetSize(pTask->pUpstreamEpInfoList);
|
||||||
|
int32_t old = atomic_val_compare_exchange_32(&pTask->transferStateAlignCnt, 0, numOfUpstream);
|
||||||
|
if (old == 0) {
|
||||||
|
qDebug("s-task:%s set the transfer state aligncnt %d", pTask->id.idStr, numOfUpstream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return atomic_sub_fetch_32(&pTask->transferStateAlignCnt, 1);
|
||||||
|
}
|
||||||
|
|
|
@ -264,8 +264,9 @@ SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int32_t taskId) {
|
||||||
SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &taskId, sizeof(int32_t));
|
SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &taskId, sizeof(int32_t));
|
||||||
if (ppTask != NULL) {
|
if (ppTask != NULL) {
|
||||||
if (!streamTaskShouldStop(&(*ppTask)->status)) {
|
if (!streamTaskShouldStop(&(*ppTask)->status)) {
|
||||||
atomic_add_fetch_32(&(*ppTask)->refCnt, 1);
|
int32_t ref = atomic_add_fetch_32(&(*ppTask)->refCnt, 1);
|
||||||
taosRUnLockLatch(&pMeta->lock);
|
taosRUnLockLatch(&pMeta->lock);
|
||||||
|
qDebug("s-task:%s acquire task, ref:%d", (*ppTask)->id.idStr, ref);
|
||||||
return *ppTask;
|
return *ppTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,12 +276,24 @@ SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int32_t taskId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamMetaReleaseTask(SStreamMeta* pMeta, SStreamTask* pTask) {
|
void streamMetaReleaseTask(SStreamMeta* pMeta, SStreamTask* pTask) {
|
||||||
int32_t left = atomic_sub_fetch_32(&pTask->refCnt, 1);
|
int32_t ref = atomic_sub_fetch_32(&pTask->refCnt, 1);
|
||||||
if (left < 0) {
|
if (ref > 0) {
|
||||||
qError("task ref is invalid, ref:%d, %s", left, pTask->id.idStr);
|
qDebug("s-task:%s release task, ref:%d", pTask->id.idStr, ref);
|
||||||
} else if (left == 0) {
|
} else if (ref == 0) {
|
||||||
ASSERT(streamTaskShouldStop(&pTask->status));
|
ASSERT(streamTaskShouldStop(&pTask->status));
|
||||||
tFreeStreamTask(pTask);
|
tFreeStreamTask(pTask);
|
||||||
|
} else if (ref < 0) {
|
||||||
|
qError("task ref is invalid, ref:%d, %s", ref, pTask->id.idStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doRemoveIdFromList(SStreamMeta* pMeta, int32_t num, int32_t taskId) {
|
||||||
|
for (int32_t i = 0; i < num; ++i) {
|
||||||
|
int32_t* pTaskId = taosArrayGet(pMeta->pTaskList, i);
|
||||||
|
if (*pTaskId == taskId) {
|
||||||
|
taosArrayRemove(pMeta->pTaskList, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,17 +346,17 @@ void streamMetaRemoveTask(SStreamMeta* pMeta, int32_t taskId) {
|
||||||
|
|
||||||
int32_t num = taosArrayGetSize(pMeta->pTaskList);
|
int32_t num = taosArrayGetSize(pMeta->pTaskList);
|
||||||
qDebug("s-task:%s set the drop task flag, remain running s-task:%d", pTask->id.idStr, num - 1);
|
qDebug("s-task:%s set the drop task flag, remain running s-task:%d", pTask->id.idStr, num - 1);
|
||||||
for (int32_t i = 0; i < num; ++i) {
|
doRemoveIdFromList(pMeta, num, pTask->id.taskId);
|
||||||
int32_t* pTaskId = taosArrayGet(pMeta->pTaskList, i);
|
|
||||||
if (*pTaskId == taskId) {
|
// remove the ref by timer
|
||||||
taosArrayRemove(pMeta->pTaskList, i);
|
if (pTask->triggerParam != 0) {
|
||||||
break;
|
taosTmrStop(pTask->schedTimer);
|
||||||
}
|
streamMetaReleaseTask(pMeta, pTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
streamMetaReleaseTask(pMeta, pTask);
|
streamMetaReleaseTask(pMeta, pTask);
|
||||||
} else {
|
} else {
|
||||||
qDebug("vgId:%d failed to find the task:0x%x, it may be dropped already", pMeta->vgId, taskId);
|
qDebug("vgId:%d failed to find the task:0x%x, it may have been dropped already", pMeta->vgId, taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosWUnLockLatch(&pMeta->lock);
|
taosWUnLockLatch(&pMeta->lock);
|
||||||
|
|
|
@ -43,6 +43,7 @@ const char* streamGetTaskStatusStr(int32_t status) {
|
||||||
case TASK_STATUS__SCAN_HISTORY: return "scan-history";
|
case TASK_STATUS__SCAN_HISTORY: return "scan-history";
|
||||||
case TASK_STATUS__HALT: return "halt";
|
case TASK_STATUS__HALT: return "halt";
|
||||||
case TASK_STATUS__PAUSE: return "paused";
|
case TASK_STATUS__PAUSE: return "paused";
|
||||||
|
case TASK_STATUS__DROPPING: return "dropping";
|
||||||
default:return "";
|
default:return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +206,7 @@ int32_t streamProcessCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRs
|
||||||
qDebug("s-task:%s all %d downstream tasks are ready, now enter into scan-history-data stage, status:%s", id,
|
qDebug("s-task:%s all %d downstream tasks are ready, now enter into scan-history-data stage, status:%s", id,
|
||||||
numOfReqs, streamGetTaskStatusStr(pTask->status.taskStatus));
|
numOfReqs, streamGetTaskStatusStr(pTask->status.taskStatus));
|
||||||
streamTaskLaunchScanHistory(pTask);
|
streamTaskLaunchScanHistory(pTask);
|
||||||
} else { // todo add assert, agg tasks?
|
} else {
|
||||||
ASSERT(pTask->status.taskStatus == TASK_STATUS__NORMAL);
|
ASSERT(pTask->status.taskStatus == TASK_STATUS__NORMAL);
|
||||||
qDebug("s-task:%s fixed downstream task is ready, now ready for data from wal, status:%s", id,
|
qDebug("s-task:%s fixed downstream task is ready, now ready for data from wal, status:%s", id,
|
||||||
streamGetTaskStatusStr(pTask->status.taskStatus));
|
streamGetTaskStatusStr(pTask->status.taskStatus));
|
||||||
|
@ -258,9 +259,15 @@ int32_t streamRestoreParam(SStreamTask* pTask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t streamSetStatusNormal(SStreamTask* pTask) {
|
int32_t streamSetStatusNormal(SStreamTask* pTask) {
|
||||||
qDebug("s-task:%s set task status to be normal, prev:%s", pTask->id.idStr, streamGetTaskStatusStr(pTask->status.taskStatus));
|
int32_t status = atomic_load_8(&pTask->status.taskStatus);
|
||||||
atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__NORMAL);
|
if (status == TASK_STATUS__DROPPING) {
|
||||||
return 0;
|
qError("s-task:%s cannot be set normal, since in dropping state", pTask->id.idStr);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
qDebug("s-task:%s set task status to be normal, prev:%s", pTask->id.idStr, streamGetTaskStatusStr(status));
|
||||||
|
atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__NORMAL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// source
|
// source
|
||||||
|
@ -344,7 +351,8 @@ static int32_t doDispatchTransferMsg(SStreamTask* pTask, const SStreamTransferRe
|
||||||
msg.info.noResp = 1;
|
msg.info.noResp = 1;
|
||||||
|
|
||||||
tmsgSendReq(pEpSet, &msg);
|
tmsgSendReq(pEpSet, &msg);
|
||||||
qDebug("s-task:%s dispatch transfer state msg to taskId:0x%x (vgId:%d)", pTask->id.idStr, pReq->taskId, vgId);
|
qDebug("s-task:%s level:%d, status:%s dispatch transfer state msg to taskId:0x%x (vgId:%d)", pTask->id.idStr,
|
||||||
|
pTask->info.taskLevel, streamGetTaskStatusStr(pTask->status.taskStatus), pReq->taskId, vgId);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -354,9 +362,6 @@ int32_t streamDispatchTransferStateMsg(SStreamTask* pTask) {
|
||||||
|
|
||||||
// serialize
|
// serialize
|
||||||
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
||||||
qDebug("s-task:%s send transfer state msg to downstream (fix-dispatch) to taskId:0x%x, status:%s", pTask->id.idStr,
|
|
||||||
pTask->fixedEpDispatcher.taskId, streamGetTaskStatusStr(pTask->status.taskStatus));
|
|
||||||
|
|
||||||
req.taskId = pTask->fixedEpDispatcher.taskId;
|
req.taskId = pTask->fixedEpDispatcher.taskId;
|
||||||
doDispatchTransferMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet);
|
doDispatchTransferMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet);
|
||||||
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||||
|
@ -451,6 +456,7 @@ static void tryLaunchHistoryTask(void* param, void* tmrId) {
|
||||||
const char* pStatus = streamGetTaskStatusStr((*ppTask)->status.taskStatus);
|
const char* pStatus = streamGetTaskStatusStr((*ppTask)->status.taskStatus);
|
||||||
qDebug("s-task:%s status:%s quit timer task", (*ppTask)->id.idStr, pStatus);
|
qDebug("s-task:%s status:%s quit timer task", (*ppTask)->id.idStr, pStatus);
|
||||||
|
|
||||||
|
taosMemoryFree(pInfo);
|
||||||
(*ppTask)->status.timerActive = 0;
|
(*ppTask)->status.timerActive = 0;
|
||||||
taosWUnLockLatch(&pMeta->lock);
|
taosWUnLockLatch(&pMeta->lock);
|
||||||
return;
|
return;
|
||||||
|
@ -511,6 +517,7 @@ int32_t streamCheckHistoryTaskDownstream(SStreamTask* pTask) {
|
||||||
pTask->launchTaskTimer = taosTmrStart(tryLaunchHistoryTask, 100, pInfo, streamEnv.timer);
|
pTask->launchTaskTimer = taosTmrStart(tryLaunchHistoryTask, 100, pInfo, streamEnv.timer);
|
||||||
if (pTask->launchTaskTimer == NULL) {
|
if (pTask->launchTaskTimer == NULL) {
|
||||||
// todo failed to create timer
|
// todo failed to create timer
|
||||||
|
taosMemoryFree(pInfo);
|
||||||
} else {
|
} else {
|
||||||
pTask->status.timerActive = 1; // timer is active
|
pTask->status.timerActive = 1; // timer is active
|
||||||
qDebug("s-task:%s set timer active flag", pTask->id.idStr);
|
qDebug("s-task:%s set timer active flag", pTask->id.idStr);
|
||||||
|
@ -553,8 +560,10 @@ int32_t streamTaskScanHistoryDataComplete(SStreamTask* pTask) {
|
||||||
streamSetStatusNormal(pTask);
|
streamSetStatusNormal(pTask);
|
||||||
atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE);
|
atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE);
|
||||||
|
|
||||||
// todo check rsp, commit data
|
taosWLockLatch(&pMeta->lock);
|
||||||
streamMetaSaveTask(pMeta, pTask);
|
streamMetaSaveTask(pMeta, pTask);
|
||||||
|
taosWUnLockLatch(&pMeta->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,13 +205,16 @@ int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask) {
|
||||||
|
|
||||||
void tFreeStreamTask(SStreamTask* pTask) {
|
void tFreeStreamTask(SStreamTask* pTask) {
|
||||||
qDebug("free s-task:%s", pTask->id.idStr);
|
qDebug("free s-task:%s", pTask->id.idStr);
|
||||||
|
|
||||||
int32_t status = atomic_load_8((int8_t*)&(pTask->status.taskStatus));
|
int32_t status = atomic_load_8((int8_t*)&(pTask->status.taskStatus));
|
||||||
if (pTask->inputQueue) {
|
if (pTask->inputQueue) {
|
||||||
streamQueueClose(pTask->inputQueue);
|
streamQueueClose(pTask->inputQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTask->outputQueue) {
|
if (pTask->outputQueue) {
|
||||||
streamQueueClose(pTask->outputQueue);
|
streamQueueClose(pTask->outputQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTask->exec.qmsg) {
|
if (pTask->exec.qmsg) {
|
||||||
taosMemoryFree(pTask->exec.qmsg);
|
taosMemoryFree(pTask->exec.qmsg);
|
||||||
}
|
}
|
||||||
|
@ -230,9 +233,7 @@ void tFreeStreamTask(SStreamTask* pTask) {
|
||||||
tDeleteSchemaWrapper(pTask->tbSink.pSchemaWrapper);
|
tDeleteSchemaWrapper(pTask->tbSink.pSchemaWrapper);
|
||||||
taosMemoryFree(pTask->tbSink.pTSchema);
|
taosMemoryFree(pTask->tbSink.pTSchema);
|
||||||
tSimpleHashCleanup(pTask->tbSink.pTblInfo);
|
tSimpleHashCleanup(pTask->tbSink.pTblInfo);
|
||||||
}
|
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||||
|
|
||||||
if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
|
||||||
taosArrayDestroy(pTask->shuffleDispatcher.dbInfo.pVgroupInfos);
|
taosArrayDestroy(pTask->shuffleDispatcher.dbInfo.pVgroupInfos);
|
||||||
taosArrayDestroy(pTask->checkReqIds);
|
taosArrayDestroy(pTask->checkReqIds);
|
||||||
pTask->checkReqIds = NULL;
|
pTask->checkReqIds = NULL;
|
||||||
|
|
|
@ -207,6 +207,7 @@
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/precisionUS.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/precisionUS.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/precisionNS.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/precisionNS.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/show.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/show.py
|
||||||
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/show_tag_index.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/information_schema.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/information_schema.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/abs.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/abs.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/abs.py -R
|
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/abs.py -R
|
||||||
|
|
|
@ -81,12 +81,20 @@ class TDTestCase:
|
||||||
tag_sql += f"{k} {v}, "
|
tag_sql += f"{k} {v}, "
|
||||||
create_stb_sql = f'create stable {stbname} ({column_sql[:-2]}) tags ({tag_sql[:-2]})'
|
create_stb_sql = f'create stable {stbname} ({column_sql[:-2]}) tags ({tag_sql[:-2]})'
|
||||||
return create_stb_sql
|
return create_stb_sql
|
||||||
|
|
||||||
def set_create_database_sql(self,sql_dict):
|
def set_create_database_sql(self,sql_dict):
|
||||||
create_sql = 'create'
|
create_sql = 'create'
|
||||||
for key,value in sql_dict.items():
|
for key,value in sql_dict.items():
|
||||||
create_sql += f' {key} {value}'
|
create_sql += f' {key} {value}'
|
||||||
return create_sql
|
return create_sql
|
||||||
|
|
||||||
|
def show_create_sysdb_sql(self):
|
||||||
|
sysdb_list = {'information_schema', 'performance_schema'}
|
||||||
|
for db in sysdb_list:
|
||||||
|
tdSql.query(f'show create database {db}')
|
||||||
|
tdSql.checkEqual(f'{db}',tdSql.queryResult[0][0])
|
||||||
|
tdSql.checkEqual(f'CREATE DATABASE `{db}`',tdSql.queryResult[0][1])
|
||||||
|
|
||||||
def show_create_sql(self):
|
def show_create_sql(self):
|
||||||
create_db_sql = self.set_create_database_sql(self.db_param)
|
create_db_sql = self.set_create_database_sql(self.db_param)
|
||||||
print(create_db_sql)
|
print(create_db_sql)
|
||||||
|
@ -106,7 +114,7 @@ class TDTestCase:
|
||||||
tdSql.query('show vnodes 1')
|
tdSql.query('show vnodes 1')
|
||||||
tdSql.checkRows(self.vgroups)
|
tdSql.checkRows(self.vgroups)
|
||||||
tdSql.execute(f'use {self.dbname}')
|
tdSql.execute(f'use {self.dbname}')
|
||||||
|
|
||||||
column_dict = {
|
column_dict = {
|
||||||
'`ts`': 'timestamp',
|
'`ts`': 'timestamp',
|
||||||
'`col1`': 'tinyint',
|
'`col1`': 'tinyint',
|
||||||
|
@ -122,7 +130,7 @@ class TDTestCase:
|
||||||
'`col11`': 'bool',
|
'`col11`': 'bool',
|
||||||
'`col12`': 'varchar(20)',
|
'`col12`': 'varchar(20)',
|
||||||
'`col13`': 'nchar(20)'
|
'`col13`': 'nchar(20)'
|
||||||
|
|
||||||
}
|
}
|
||||||
tag_dict = {
|
tag_dict = {
|
||||||
'`t1`': 'tinyint',
|
'`t1`': 'tinyint',
|
||||||
|
@ -139,7 +147,7 @@ class TDTestCase:
|
||||||
'`t12`': 'varchar(20)',
|
'`t12`': 'varchar(20)',
|
||||||
'`t13`': 'nchar(20)',
|
'`t13`': 'nchar(20)',
|
||||||
'`t14`': 'timestamp'
|
'`t14`': 'timestamp'
|
||||||
|
|
||||||
}
|
}
|
||||||
create_table_sql = self.set_stb_sql(self.stbname,column_dict,tag_dict)
|
create_table_sql = self.set_stb_sql(self.stbname,column_dict,tag_dict)
|
||||||
tdSql.execute(create_table_sql)
|
tdSql.execute(create_table_sql)
|
||||||
|
@ -150,7 +158,7 @@ class TDTestCase:
|
||||||
tag_sql = '('
|
tag_sql = '('
|
||||||
for tag_keys in tag_dict.keys():
|
for tag_keys in tag_dict.keys():
|
||||||
tag_sql += f'{tag_keys}, '
|
tag_sql += f'{tag_keys}, '
|
||||||
tags = f'{tag_sql[:-2]})'
|
tags = f'{tag_sql[:-2]})'
|
||||||
sql = f'create table {self.tbname} using {self.stbname} {tags} tags (1, 1, 1, 1, 1, 1, 1, 1, 1.000000e+00, 1.000000e+00, true, "abc", "abc123", 0)'
|
sql = f'create table {self.tbname} using {self.stbname} {tags} tags (1, 1, 1, 1, 1, 1, 1, 1, 1.000000e+00, 1.000000e+00, true, "abc", "abc123", 0)'
|
||||||
tdSql.query(f'show create table {self.tbname}')
|
tdSql.query(f'show create table {self.tbname}')
|
||||||
query_result = tdSql.queryResult
|
query_result = tdSql.queryResult
|
||||||
|
@ -173,7 +181,7 @@ class TDTestCase:
|
||||||
taosd_info = os.popen('taosd -V').read()
|
taosd_info = os.popen('taosd -V').read()
|
||||||
taosd_gitinfo = re.findall("^gitinfo.*",taosd_info,re.M)
|
taosd_gitinfo = re.findall("^gitinfo.*",taosd_info,re.M)
|
||||||
tdSql.checkEqual(taosd_gitinfo_sql,taosd_gitinfo[0])
|
tdSql.checkEqual(taosd_gitinfo_sql,taosd_gitinfo[0])
|
||||||
|
|
||||||
def show_base(self):
|
def show_base(self):
|
||||||
for sql in ['dnodes','mnodes','cluster']:
|
for sql in ['dnodes','mnodes','cluster']:
|
||||||
tdSql.query(f'show {sql}')
|
tdSql.query(f'show {sql}')
|
||||||
|
@ -191,6 +199,7 @@ class TDTestCase:
|
||||||
self.ins_check()
|
self.ins_check()
|
||||||
self.perf_check()
|
self.perf_check()
|
||||||
self.show_create_sql()
|
self.show_create_sql()
|
||||||
|
self.show_create_sysdb_sql()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
tdSql.close()
|
tdSql.close()
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import re
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.common import *
|
||||||
|
from util.sqlset import *
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
|
self.replicaVar = int(replicaVar)
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
|
||||||
|
def check_tags(self):
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
tdSql.checkCols(6)
|
||||||
|
tdSql.checkData(0, 0, 'ctb1')
|
||||||
|
tdSql.checkData(0, 1, 'db')
|
||||||
|
tdSql.checkData(0, 2, 'stb')
|
||||||
|
tdSql.checkData(0, 3, 't0')
|
||||||
|
tdSql.checkData(0, 4, 'INT')
|
||||||
|
tdSql.checkData(0, 5, 1)
|
||||||
|
tdSql.checkData(1, 0, 'ctb1')
|
||||||
|
tdSql.checkData(1, 1, 'db')
|
||||||
|
tdSql.checkData(1, 2, 'stb')
|
||||||
|
tdSql.checkData(1, 3, 't1')
|
||||||
|
tdSql.checkData(1, 4, 'INT')
|
||||||
|
tdSql.checkData(1, 5, 1)
|
||||||
|
|
||||||
|
def check_table_tags(self, is_super_table):
|
||||||
|
|
||||||
|
if is_super_table == False:
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.checkCols(3)
|
||||||
|
tdSql.checkData(0, 0, 'ctb1')
|
||||||
|
tdSql.checkData(0, 1, 1)
|
||||||
|
tdSql.checkData(0, 2, 1)
|
||||||
|
else:
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
tdSql.checkCols(3)
|
||||||
|
tdSql.checkData(0, 0, 'ctb1')
|
||||||
|
tdSql.checkData(1, 0, 'ctb2')
|
||||||
|
tdSql.checkData(0, 1, 1)
|
||||||
|
tdSql.checkData(1, 1, 2)
|
||||||
|
tdSql.checkData(0, 2, 1)
|
||||||
|
tdSql.checkData(1, 2, 2)
|
||||||
|
|
||||||
|
def check_indexes(self):
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.checkCols(7)
|
||||||
|
tdSql.checkData(0, 0, 'idx1')
|
||||||
|
tdSql.checkData(0, 1, 'db')
|
||||||
|
tdSql.checkData(0, 2, 'stb')
|
||||||
|
tdSql.checkData(0, 3, -1)
|
||||||
|
tdSql.checkData(0, 5, 't1')
|
||||||
|
tdSql.checkData(0, 6, 'tag_index')
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.execute(f'create database db')
|
||||||
|
tdSql.execute(f'use db')
|
||||||
|
tdSql.execute(f'create table stb (ts timestamp, c0 int) tags (t0 int, t1 int)')
|
||||||
|
tdSql.execute(f'create table ctb1 using stb tags (1, 1)')
|
||||||
|
tdSql.execute(f'create table ctb2 using stb tags (2, 2)')
|
||||||
|
tdSql.execute(f'insert into ctb1 values (now, 1)')
|
||||||
|
tdSql.execute(f'insert into ctb2 values (now, 2)')
|
||||||
|
|
||||||
|
# show tags
|
||||||
|
tdSql.query(f'show tags from stb')
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
tdSql.query(f'show tags from stb')
|
||||||
|
tdSql.checkRows(0);
|
||||||
|
tdSql.query(f'show tags from `stb`')
|
||||||
|
tdSql.checkRows(0);
|
||||||
|
tdSql.query(f'show tags from stb from db')
|
||||||
|
tdSql.checkRows(0);
|
||||||
|
tdSql.query(f'show tags from `stb` from `db`')
|
||||||
|
tdSql.checkRows(0);
|
||||||
|
tdSql.query(f'show tags from db.stb')
|
||||||
|
tdSql.checkRows(0);
|
||||||
|
tdSql.query(f'show tags from `db`.`stb`')
|
||||||
|
tdSql.checkRows(0);
|
||||||
|
tdSql.query(f'show tags from ctb1')
|
||||||
|
self.check_tags();
|
||||||
|
tdSql.query(f'show tags from `ctb1`')
|
||||||
|
self.check_tags();
|
||||||
|
tdSql.query(f'show tags from ctb1 from db')
|
||||||
|
self.check_tags();
|
||||||
|
tdSql.query(f'show tags from `ctb1` from `db`')
|
||||||
|
self.check_tags();
|
||||||
|
tdSql.query(f'show tags from db.ctb1')
|
||||||
|
self.check_tags();
|
||||||
|
tdSql.query(f'show tags from `db`.`ctb1`')
|
||||||
|
self.check_tags();
|
||||||
|
|
||||||
|
tdSql.error(f'show tags from db.stb from db')
|
||||||
|
tdSql.error(f'show tags from `db`.`stb` from db')
|
||||||
|
tdSql.error(f'show tags from db.ctb1 from db')
|
||||||
|
tdSql.error(f'show tags from `db`.`ctb1` from db')
|
||||||
|
|
||||||
|
# show table tags
|
||||||
|
tdSql.query(f'show table tags from stb')
|
||||||
|
self.check_table_tags(True);
|
||||||
|
tdSql.query(f'show table tags from `stb`')
|
||||||
|
self.check_table_tags(True);
|
||||||
|
tdSql.query(f'show table tags from stb from db')
|
||||||
|
self.check_table_tags(True);
|
||||||
|
tdSql.query(f'show table tags from `stb` from `db`')
|
||||||
|
self.check_table_tags(True);
|
||||||
|
tdSql.query(f'show table tags from db.stb')
|
||||||
|
self.check_table_tags(True);
|
||||||
|
tdSql.query(f'show table tags from `db`.`stb`')
|
||||||
|
self.check_table_tags(True);
|
||||||
|
|
||||||
|
tdSql.query(f'show table tags from ctb1')
|
||||||
|
self.check_table_tags(False);
|
||||||
|
tdSql.query(f'show table tags from `ctb1`')
|
||||||
|
self.check_table_tags(False);
|
||||||
|
tdSql.query(f'show table tags from ctb1 from db')
|
||||||
|
self.check_table_tags(False);
|
||||||
|
tdSql.query(f'show table tags from `ctb1` from `db`')
|
||||||
|
self.check_table_tags(False);
|
||||||
|
tdSql.query(f'show table tags from db.ctb1')
|
||||||
|
self.check_table_tags(False);
|
||||||
|
tdSql.query(f'show table tags from `db`.`ctb1`')
|
||||||
|
self.check_table_tags(False);
|
||||||
|
|
||||||
|
tdSql.error(f'show table tags from db.stb from db')
|
||||||
|
tdSql.error(f'show table tags from `db`.`stb` from db')
|
||||||
|
tdSql.error(f'show table tags from db.ctb1 from db')
|
||||||
|
tdSql.error(f'show table tags from `db`.`ctb1` from db')
|
||||||
|
|
||||||
|
# show indexes
|
||||||
|
tdSql.execute(f'create index idx1 on stb (t1)')
|
||||||
|
|
||||||
|
tdSql.query(f'show indexes from stb')
|
||||||
|
self.check_indexes();
|
||||||
|
tdSql.query(f'show indexes from `stb`')
|
||||||
|
self.check_indexes();
|
||||||
|
tdSql.query(f'show indexes from stb from db')
|
||||||
|
self.check_indexes();
|
||||||
|
tdSql.query(f'show indexes from `stb` from `db`')
|
||||||
|
self.check_indexes();
|
||||||
|
tdSql.query(f'show indexes from db.stb')
|
||||||
|
self.check_indexes();
|
||||||
|
tdSql.query(f'show indexes from `db`.`stb`')
|
||||||
|
self.check_indexes();
|
||||||
|
|
||||||
|
tdSql.query(f'show indexes from ctb1')
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
tdSql.query(f'show indexes from `ctb1`')
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
tdSql.query(f'show indexes from ctb1 from db')
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
tdSql.query(f'show indexes from `ctb1` from `db`')
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
tdSql.query(f'show indexes from db.ctb1')
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
tdSql.query(f'show indexes from `db`.`ctb1`')
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
tdSql.error(f'show indexes from db.stb from db')
|
||||||
|
tdSql.error(f'show indexes from `db`.`stb` from db')
|
||||||
|
tdSql.error(f'show indexes from db.ctb1 from db')
|
||||||
|
tdSql.error(f'show indexes from `db`.`ctb1` from db')
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
Loading…
Reference in New Issue