Merge branch '3.0' into feature/TD-14761
This commit is contained in:
commit
b5388b09fc
|
@ -34,7 +34,7 @@ endif(${BUILD_TEST})
|
|||
|
||||
add_subdirectory(source)
|
||||
add_subdirectory(tools)
|
||||
add_subdirectory(tests)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(examples/c)
|
||||
|
||||
# docs
|
||||
|
|
|
@ -87,7 +87,7 @@ IF ("${CPUTYPE}" STREQUAL "")
|
|||
SET(TD_ARM_32 TRUE)
|
||||
ADD_DEFINITIONS("-D_TD_ARM_")
|
||||
ADD_DEFINITIONS("-D_TD_ARM_32")
|
||||
ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
|
||||
ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(arm64)")
|
||||
MESSAGE(STATUS "The current platform is aarch64")
|
||||
SET(PLATFORM_ARCH_STR "arm64")
|
||||
SET(TD_ARM_64 TRUE)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
IF (DEFINED VERNUMBER)
|
||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||
ELSE ()
|
||||
SET(TD_VER_NUMBER "3.0.0.1")
|
||||
SET(TD_VER_NUMBER "3.0.1.0")
|
||||
ENDIF ()
|
||||
|
||||
IF (DEFINED VERCOMPATIBLE)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taosadapter
|
||||
ExternalProject_Add(taosadapter
|
||||
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
|
||||
GIT_TAG abed566
|
||||
GIT_TAG 71e7ccf
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taos-tools
|
||||
ExternalProject_Add(taos-tools
|
||||
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
|
||||
GIT_TAG f169c0f
|
||||
GIT_TAG 2dba49c
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taosws-rs
|
||||
ExternalProject_Add(taosws-rs
|
||||
GIT_REPOSITORY https://github.com/taosdata/taos-connector-rust.git
|
||||
GIT_TAG 6fc47d7
|
||||
GIT_TAG e771403
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosws-rs"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -6,101 +6,100 @@ In order to explain the basic concepts and provide some sample code, the TDengin
|
|||
|
||||
<div className="center-table">
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>Device ID</th>
|
||||
<th>Time Stamp</th>
|
||||
<th colSpan="3">Collected Metrics</th>
|
||||
<th colSpan="2">Tags</th>
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowSpan="2">Device ID</th>
|
||||
<th rowSpan="2">Timestamp</th>
|
||||
<th colSpan="3">Collected Metrics</th>
|
||||
<th colSpan="2">Tags</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Device ID</th>
|
||||
<th>Time Stamp</th>
|
||||
<th>current</th>
|
||||
<th>voltage</th>
|
||||
<th>phase</th>
|
||||
<th>location</th>
|
||||
<th>groupId</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548685000</td>
|
||||
<td>10.3</td>
|
||||
<td>219</td>
|
||||
<td>0.31</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1002</td>
|
||||
<td>1538548684000</td>
|
||||
<td>10.2</td>
|
||||
<td>220</td>
|
||||
<td>0.23</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1003</td>
|
||||
<td>1538548686500</td>
|
||||
<td>11.5</td>
|
||||
<td>221</td>
|
||||
<td>0.35</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1004</td>
|
||||
<td>1538548685500</td>
|
||||
<td>13.4</td>
|
||||
<td>223</td>
|
||||
<td>0.29</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548695000</td>
|
||||
<td>12.6</td>
|
||||
<td>218</td>
|
||||
<td>0.33</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1004</td>
|
||||
<td>1538548696600</td>
|
||||
<td>11.8</td>
|
||||
<td>221</td>
|
||||
<td>0.28</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1002</td>
|
||||
<td>1538548696650</td>
|
||||
<td>10.3</td>
|
||||
<td>218</td>
|
||||
<td>0.25</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548696800</td>
|
||||
<td>12.3</td>
|
||||
<td>221</td>
|
||||
<td>0.31</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tr>
|
||||
<th>current</th>
|
||||
<th>voltage</th>
|
||||
<th>phase</th>
|
||||
<th>location</th>
|
||||
<th>groupid</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548685000</td>
|
||||
<td>10.3</td>
|
||||
<td>219</td>
|
||||
<td>0.31</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1002</td>
|
||||
<td>1538548684000</td>
|
||||
<td>10.2</td>
|
||||
<td>220</td>
|
||||
<td>0.23</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1003</td>
|
||||
<td>1538548686500</td>
|
||||
<td>11.5</td>
|
||||
<td>221</td>
|
||||
<td>0.35</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1004</td>
|
||||
<td>1538548685500</td>
|
||||
<td>13.4</td>
|
||||
<td>223</td>
|
||||
<td>0.29</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548695000</td>
|
||||
<td>12.6</td>
|
||||
<td>218</td>
|
||||
<td>0.33</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1004</td>
|
||||
<td>1538548696600</td>
|
||||
<td>11.8</td>
|
||||
<td>221</td>
|
||||
<td>0.28</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1002</td>
|
||||
<td>1538548696650</td>
|
||||
<td>10.3</td>
|
||||
<td>218</td>
|
||||
<td>0.25</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548696800</td>
|
||||
<td>12.3</td>
|
||||
<td>221</td>
|
||||
<td>0.31</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="#model_table1">Table 1: Smart meter example data</a>
|
||||
</div>
|
||||
|
||||
Each row contains the device ID, time stamp, collected metrics (current, voltage, phase as above), and static tags (location and groupId in Table 1) associated with the devices. Each smart meter generates a row (measurement) in a pre-defined time interval or triggered by an external event. The device produces a sequence of measurements with associated time stamps.
|
||||
Each row contains the device ID, timestamp, collected metrics (`current`, `voltage`, `phase` as above), and static tags (`location` and `groupid` in Table 1) associated with the devices. Each smart meter generates a row (measurement) in a pre-defined time interval or triggered by an external event. The device produces a sequence of measurements with associated timestamps.
|
||||
|
||||
## Metric
|
||||
|
||||
|
@ -112,22 +111,22 @@ Label/Tag refers to the static properties of sensors, equipment or other types o
|
|||
|
||||
## Data Collection Point
|
||||
|
||||
Data Collection Point (DCP) refers to hardware or software that collects metrics based on preset time periods or triggered by events. A data collection point can collect one or multiple metrics, but these metrics are collected at the same time and have the same time stamp. For some complex equipment, there are often multiple data collection points, and the sampling rate of each collection point may be different, and fully independent. For example, for a car, there could be a data collection point to collect GPS position metrics, a data collection point to collect engine status metrics, and a data collection point to collect the environment metrics inside the car. So in this example the car would have three data collection points. In the smart meters example, d1001, d1002, d1003, and d1004 are the data collection points.
|
||||
Data Collection Point (DCP) refers to hardware or software that collects metrics based on preset time periods or triggered by events. A data collection point can collect one or multiple metrics, but these metrics are collected at the same time and have the same timestamp. For some complex equipment, there are often multiple data collection points, and the sampling rate of each collection point may be different, and fully independent. For example, for a car, there could be a data collection point to collect GPS position metrics, a data collection point to collect engine status metrics, and a data collection point to collect the environment metrics inside the car. So in this example the car would have three data collection points. In the smart meters example, d1001, d1002, d1003, and d1004 are the data collection points.
|
||||
|
||||
## Table
|
||||
|
||||
Since time-series data is most likely to be structured data, TDengine adopts the traditional relational database model to process them with a short learning curve. You need to create a database, create tables, then insert data points and execute queries to explore the data.
|
||||
|
||||
To make full use of time-series data characteristics, TDengine adopts a strategy of "**One Table for One Data Collection Point**". TDengine requires the user to create a table for each data collection point (DCP) to store collected time-series data. For example, if there are over 10 million smart meters, it means 10 million tables should be created. For the table above, 4 tables should be created for devices D1001, D1002, D1003, and D1004 to store the data collected. This design has several benefits:
|
||||
To make full use of time-series data characteristics, TDengine adopts a strategy of "**One Table for One Data Collection Point**". TDengine requires the user to create a table for each data collection point (DCP) to store collected time-series data. For example, if there are over 10 million smart meters, it means 10 million tables should be created. For the table above, 4 tables should be created for devices d1001, d1002, d1003, and d1004 to store the data collected. This design has several benefits:
|
||||
|
||||
1. Since the metric data from different DCP are fully independent, the data source of each DCP is unique, and a table has only one writer. In this way, data points can be written in a lock-free manner, and the writing speed can be greatly improved.
|
||||
2. For a DCP, the metric data generated by DCP is ordered by timestamp, so the write operation can be implemented by simple appending, which further greatly improves the data writing speed.
|
||||
3. The metric data from a DCP is continuously stored, block by block. If you read data for a period of time, it can greatly reduce random read operations and improve read and query performance by orders of magnitude.
|
||||
4. Inside a data block for a DCP, columnar storage is used, and different compression algorithms are used for different data types. Metrics generally don't vary as significantly between themselves over a time range as compared to other metrics, which allows for a higher compression rate.
|
||||
|
||||
If the metric data of multiple DCPs are traditionally written into a single table, due to uncontrollable network delays, the timing of the data from different DCPs arriving at the server cannot be guaranteed, write operations must be protected by locks, and metric data from one DCP cannot be guaranteed to be continuously stored together. ** One table for one data collection point can ensure the best performance of insert and query of a single data collection point to the greatest possible extent.**
|
||||
If the metric data of multiple DCPs are traditionally written into a single table, due to uncontrollable network delays, the timing of the data from different DCPs arriving at the server cannot be guaranteed, write operations must be protected by locks, and metric data from one DCP cannot be guaranteed to be continuously stored together. **One table for one data collection point can ensure the best performance of insert and query of a single data collection point to the greatest possible extent.**
|
||||
|
||||
TDengine suggests using DCP ID as the table name (like D1001 in the above table). Each DCP may collect one or multiple metrics (like the current, voltage, phase as above). Each metric has a corresponding column in the table. The data type for a column can be int, float, string and others. In addition, the first column in the table must be a timestamp. TDengine uses the time stamp as the index, and won’t build the index on any metrics stored. Column wise storage is used.
|
||||
TDengine suggests using DCP ID as the table name (like d1001 in the above table). Each DCP may collect one or multiple metrics (like the `current`, `voltage`, `phase` as above). Each metric has a corresponding column in the table. The data type for a column can be int, float, string and others. In addition, the first column in the table must be a timestamp. TDengine uses the timestamp as the index, and won’t build the index on any metrics stored. Column wise storage is used.
|
||||
|
||||
Complex devices, such as connected cars, may have multiple DCPs. In this case, multiple tables are created for a single device, one table per DCP.
|
||||
|
||||
|
@ -156,9 +155,16 @@ The relationship between a STable and the subtables created based on this STable
|
|||
|
||||
Queries can be executed on both a table (subtable) and a STable. For a query on a STable, TDengine will treat the data in all its subtables as a whole data set for processing. TDengine will first find the subtables that meet the tag filter conditions, then scan the time-series data of these subtables to perform aggregation operation, which reduces the number of data sets to be scanned which in turn greatly improves the performance of data aggregation across multiple DCPs. In essence, querying a supertable is a very efficient aggregate query on multiple DCPs of the same type.
|
||||
|
||||
In TDengine, it is recommended to use a subtable instead of a regular table for a DCP. In the smart meters example, we can create subtables like d1001, d1002, d1003, and d1004 under super table meters.
|
||||
In TDengine, it is recommended to use a subtable instead of a regular table for a DCP. In the smart meters example, we can create subtables like d1001, d1002, d1003, and d1004 under super table `meters`.
|
||||
|
||||
To better understand the data model using metri, tags, super table and subtable, please refer to the diagram below which demonstrates the data model of the smart meters example. 
|
||||
To better understand the data model using metrics, tags, super table and subtable, please refer to the diagram below which demonstrates the data model of the smart meters example.
|
||||
|
||||
<figure>
|
||||
|
||||

|
||||
|
||||
<center><figcaption>Figure 1. Meters Data Model Diagram</figcaption></center>
|
||||
</figure>
|
||||
|
||||
## Database
|
||||
|
||||
|
@ -172,4 +178,4 @@ FQDN (Fully Qualified Domain Name) is the full domain name of a specific compute
|
|||
|
||||
Each node of a TDengine cluster is uniquely identified by an End Point, which consists of an FQDN and a Port, such as h1.tdengine.com:6030. In this way, when the IP changes, we can still use the FQDN to dynamically find the node without changing any configuration of the cluster. In addition, FQDN is used to facilitate unified access to the same cluster from the Intranet and the Internet.
|
||||
|
||||
TDengine does not recommend using an IP address to access the cluster. FQDN is recommended for cluster management.
|
||||
TDengine does not recommend using an IP address to access the cluster. FQDN is recommended for cluster management.
|
||||
|
|
|
@ -13,7 +13,7 @@ If Docker is already installed on your computer, run the following command:
|
|||
docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043-6049/udp tdengine/tdengine
|
||||
```
|
||||
|
||||
Note that TDengine Server uses TCP port 6030. Port 6041 is used by taosAdapter for the REST API service. Ports 6043 through 6049 are used by taosAdapter for other connectors. You can open these ports as needed.
|
||||
Note that TDengine Server 3.0 uses TCP port 6030. Port 6041 is used by taosAdapter for the REST API service. Ports 6043 through 6049 are used by taosAdapter for other connectors. You can open these ports as needed.
|
||||
|
||||
Run the following command to ensure that your container is running:
|
||||
|
||||
|
@ -21,7 +21,7 @@ Run the following command to ensure that your container is running:
|
|||
docker ps
|
||||
```
|
||||
|
||||
Enter the container and open the bash shell:
|
||||
Enter the container and open the `bash` shell:
|
||||
|
||||
```shell
|
||||
docker exec -it <container name> bash
|
||||
|
@ -31,68 +31,68 @@ You can now access TDengine or run other Linux commands.
|
|||
|
||||
Note: For information about installing docker, see the [official documentation](https://docs.docker.com/get-docker/).
|
||||
|
||||
## Insert Data into TDengine
|
||||
|
||||
You can use the `taosBenchmark` tool included with TDengine to write test data into your deployment.
|
||||
|
||||
To do so, run the following command:
|
||||
|
||||
```bash
|
||||
$ taosBenchmark
|
||||
|
||||
```
|
||||
|
||||
This command creates the `meters` supertable in the `test` database. In the `meters` supertable, it then creates 10,000 subtables named `d0` to `d9999`. Each table has 10,000 rows and each row has four columns: `ts`, `current`, `voltage`, and `phase`. The timestamps of the data in these columns range from 2017-07-14 10:40:00 000 to 2017-07-14 10:40:09 999. Each table is randomly assigned a `groupId` tag from 1 to 10 and a `location` tag of either `Campbell`, `Cupertino`, `Los Angeles`, `Mountain View`, `Palo Alto`, `San Diego`, `San Francisco`, `San Jose`, `Santa Clara` or `Sunnyvale`.
|
||||
|
||||
The `taosBenchmark` command creates a deployment with 100 million data points that you can use for testing purposes. The time required depends on the hardware specifications of the local system.
|
||||
|
||||
You can customize the test deployment that taosBenchmark creates by specifying command-line parameters. For information about command-line parameters, run the `taosBenchmark --help` command. For more information about taosBenchmark, see [taosBenchmark](/reference/taosbenchmark).
|
||||
|
||||
## Open the TDengine CLI
|
||||
|
||||
On the container, run the following command to open the TDengine CLI:
|
||||
On the container, run the following command to open the TDengine CLI:
|
||||
|
||||
```
|
||||
$ taos
|
||||
|
||||
taos>
|
||||
taos>
|
||||
|
||||
```
|
||||
|
||||
## Query Data in TDengine
|
||||
## Test data insert performance
|
||||
|
||||
After using taosBenchmark to create your test deployment, you can run queries in the TDengine CLI to test its performance. For example:
|
||||
After your TDengine Server is running normally, you can run the taosBenchmark utility to test its performance:
|
||||
|
||||
From the TDengine CLI query the number of rows in the `meters` supertable:
|
||||
Start TDengine service and execute `taosBenchmark` (formerly named `taosdemo`) in a Linux or Windows terminal.
|
||||
|
||||
```bash
|
||||
taosBenchmark
|
||||
```
|
||||
|
||||
This command creates the `meters` supertable in the `test` database. In the `meters` supertable, it then creates 10,000 subtables named `d0` to `d9999`. Each table has 10,000 rows and each row has four columns: `ts`, `current`, `voltage`, and `phase`. The timestamps of the data in these columns range from 2017-07-14 10:40:00 000 to 2017-07-14 10:40:09 999. Each table is randomly assigned a `groupId` tag from 1 to 10 and a `location` tag of either `Campbell`, `Cupertino`, `Los Angeles`, `Mountain View`, `Palo Alto`, `San Diego`, `San Francisco`, `San Jose`, `Santa Clara` or `Sunnyvale`.
|
||||
|
||||
The `taosBenchmark` command creates a deployment with 100 million data points that you can use for testing purposes. The time required to create the deployment depends on your hardware. On most modern servers, the deployment is created in ten to twenty seconds.
|
||||
|
||||
You can customize the test deployment that taosBenchmark creates by specifying command-line parameters. For information about command-line parameters, run the `taosBenchmark --help` command. For more information about taosBenchmark, see [taosBenchmark](../../reference/taosbenchmark).
|
||||
|
||||
## Test data query performance
|
||||
|
||||
After using `taosBenchmark` to create your test deployment, you can run queries in the TDengine CLI to test its performance:
|
||||
|
||||
From the TDengine CLI (taos) query the number of rows in the `meters` supertable:
|
||||
|
||||
```sql
|
||||
select count(*) from test.meters;
|
||||
SELECT COUNT(*) FROM test.meters;
|
||||
```
|
||||
|
||||
Query the average, maximum, and minimum values of all 100 million rows of data:
|
||||
|
||||
```sql
|
||||
select avg(current), max(voltage), min(phase) from test.meters;
|
||||
SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters;
|
||||
```
|
||||
|
||||
Query the number of rows whose `location` tag is `San Francisco`:
|
||||
|
||||
```sql
|
||||
select count(*) from test.meters where location="San Francisco";
|
||||
SELECT COUNT(*) FROM test.meters WHERE location = "San Francisco";
|
||||
```
|
||||
|
||||
Query the average, maximum, and minimum values of all rows whose `groupId` tag is `10`:
|
||||
|
||||
```sql
|
||||
select avg(current), max(voltage), min(phase) from test.meters where groupId=10;
|
||||
SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters WHERE groupId = 10;
|
||||
```
|
||||
|
||||
Query the average, maximum, and minimum values for table `d10` in 1 second intervals:
|
||||
Query the average, maximum, and minimum values for table `d10` in 10 second intervals:
|
||||
|
||||
```sql
|
||||
select first(ts), avg(current), max(voltage), min(phase) from test.d10 interval(1s);
|
||||
SELECT FIRST(ts), AVG(current), MAX(voltage), MIN(phase) FROM test.d10 INTERVAL(10s);
|
||||
```
|
||||
In the query above you are selecting the first timestamp (ts) in the interval, another way of selecting this would be _wstart which will give the start of the time window. For more information about windowed queries, see [Time-Series Extensions](../../taos-sql/distinguished/).
|
||||
|
||||
In the query above you are selecting the first timestamp (ts) in the interval, another way of selecting this would be `\_wstart` which will give the start of the time window. For more information about windowed queries, see [Time-Series Extensions](../../taos-sql/distinguished/).
|
||||
|
||||
## Additional Information
|
||||
|
||||
|
|
|
@ -9,23 +9,24 @@ import PkgListV3 from "/components/PkgListV3";
|
|||
|
||||
For information about installing TDengine on Docker, see [Quick Install on Docker](../../get-started/docker). If you want to view the source code, build TDengine yourself, or contribute to the project, see the [TDengine GitHub repository](https://github.com/taosdata/TDengine).
|
||||
|
||||
The full package of TDengine includes the TDengine Server (`taosd`), TDengine Client (`taosc`), taosAdapter for connecting with third-party systems and providing a RESTful interface, a command-line interface, and some tools. Note that taosAdapter supports Linux only. In addition to connectors for multiple languages, TDengine also provides a [REST API](../../reference/rest-api) through [taosAdapter](../../reference/taosadapter).
|
||||
The full package of TDengine includes the TDengine Server (`taosd`), TDengine Client (`taosc`), taosAdapter for connecting with third-party systems and providing a RESTful interface, a command-line interface (CLI, taos), and some tools. Note that taosAdapter supports Linux only. In addition to connectors for multiple languages, TDengine also provides a [REST API](../../reference/rest-api) through [taosAdapter](../../reference/taosadapter).
|
||||
|
||||
The standard server installation package includes `taos`, `taosd`, `taosAdapter`, `taosBenchmark`, and sample code. You can also download a lite package that includes only `taosd` and the C/C++ connector.
|
||||
The standard server installation package includes `taos`, `taosd`, `taosAdapter`, `taosBenchmark`, and sample code. You can also download the Lite package that includes only `taosd` and the C/C++ connector.
|
||||
|
||||
The TDengine Community Edition is released as .deb and .rpm packages. The .deb package can be installed on Debian, Ubuntu, and derivative systems. The .rpm package can be installed on CentOS, RHEL, SUSE, and derivative systems. A .tar.gz package is also provided for enterprise customers, and you can install TDengine over `apt-get` as well. The .tar.tz package includes `taosdump` and the TDinsight installation script. If you want to use these utilities with the .deb or .rpm package, download and install taosTools separately. TDengine can also be installed on 64-bit Windows servers.
|
||||
The TDengine Community Edition is released as Deb and RPM packages. The Deb package can be installed on Debian, Ubuntu, and derivative systems. The RPM package can be installed on CentOS, RHEL, SUSE, and derivative systems. A .tar.gz package is also provided for enterprise customers, and you can install TDengine over `apt-get` as well. The .tar.tz package includes `taosdump` and the TDinsight installation script. If you want to use these utilities with the Deb or RPM package, download and install taosTools separately. TDengine can also be installed on 64-bit Windows.
|
||||
|
||||
## Installation
|
||||
|
||||
<Tabs>
|
||||
<TabItem label=".deb" value="debinst">
|
||||
|
||||
1. Download the .deb installation package.
|
||||
<PkgListV3 type={6}/>
|
||||
1. Download the Deb installation package.
|
||||
<PkgListV3 type={6}/>
|
||||
2. In the directory where the package is located, use `dpkg` to install the package:
|
||||
|
||||
> Please replace `<version>` with the corresponding version of the package downloaded
|
||||
|
||||
```bash
|
||||
# Enter the name of the package that you downloaded.
|
||||
sudo dpkg -i TDengine-server-<version>-Linux-x64.deb
|
||||
```
|
||||
|
||||
|
@ -34,11 +35,12 @@ sudo dpkg -i TDengine-server-<version>-Linux-x64.deb
|
|||
<TabItem label=".rpm" value="rpminst">
|
||||
|
||||
1. Download the .rpm installation package.
|
||||
<PkgListV3 type={5}/>
|
||||
<PkgListV3 type={5}/>
|
||||
2. In the directory where the package is located, use rpm to install the package:
|
||||
|
||||
> Please replace `<version>` with the corresponding version of the package downloaded
|
||||
|
||||
```bash
|
||||
# Enter the name of the package that you downloaded.
|
||||
sudo rpm -ivh TDengine-server-<version>-Linux-x64.rpm
|
||||
```
|
||||
|
||||
|
@ -47,11 +49,12 @@ sudo rpm -ivh TDengine-server-<version>-Linux-x64.rpm
|
|||
<TabItem label=".tar.gz" value="tarinst">
|
||||
|
||||
1. Download the .tar.gz installation package.
|
||||
<PkgListV3 type={0}/>
|
||||
<PkgListV3 type={0}/>
|
||||
2. In the directory where the package is located, use `tar` to decompress the package:
|
||||
|
||||
> Please replace `<version>` with the corresponding version of the package downloaded
|
||||
|
||||
```bash
|
||||
# Enter the name of the package that you downloaded.
|
||||
tar -zxvf TDengine-server-<version>-Linux-x64.tar.gz
|
||||
```
|
||||
|
||||
|
@ -96,23 +99,23 @@ sudo apt-get install tdengine
|
|||
This installation method is supported only for Debian and Ubuntu.
|
||||
::::
|
||||
</TabItem>
|
||||
<TabItem label="Windows" value="windows">
|
||||
<TabItem label="Windows" value="windows">
|
||||
|
||||
Note: TDengine only supports Windows Server 2016/2019 and windows 10/11 system versions on the windows platform.
|
||||
Note: TDengine only supports Windows Server 2016/2019 and Windows 10/11 on the Windows platform.
|
||||
|
||||
1. Download the Windows installation package.
|
||||
<PkgListV3 type={3}/>
|
||||
<PkgListV3 type={3}/>
|
||||
2. Run the downloaded package to install TDengine.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::info
|
||||
For information about TDengine releases, see [Release History](../../releases).
|
||||
For information about TDengine releases, see [Release History](../../releases).
|
||||
:::
|
||||
|
||||
:::note
|
||||
On the first node in your TDengine cluster, leave the `Enter FQDN:` prompt blank and press **Enter**. On subsequent nodes, you can enter the end point of the first dnode in the cluster. You can also configure this setting after you have finished installing TDengine.
|
||||
On the first node in your TDengine cluster, leave the `Enter FQDN:` prompt blank and press **Enter**. On subsequent nodes, you can enter the endpoint of the first dnode in the cluster. You can also configure this setting after you have finished installing TDengine.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -147,7 +150,7 @@ Active: inactive (dead)
|
|||
|
||||
After confirming that TDengine is running, run the `taos` command to access the TDengine CLI.
|
||||
|
||||
The following `systemctl` commands can help you manage TDengine:
|
||||
The following `systemctl` commands can help you manage TDengine service:
|
||||
|
||||
- Start TDengine Server: `systemctl start taosd`
|
||||
|
||||
|
@ -159,7 +162,7 @@ The following `systemctl` commands can help you manage TDengine:
|
|||
|
||||
:::info
|
||||
|
||||
- The `systemctl` command requires _root_ privileges. If you are not logged in as the `root` user, use the `sudo` command.
|
||||
- The `systemctl` command requires _root_ privileges. If you are not logged in as the _root_ user, use the `sudo` command.
|
||||
- The `systemctl stop taosd` command does not instantly stop TDengine Server. The server is stopped only after all data in memory is flushed to disk. The time required depends on the cache size.
|
||||
- If your system does not include `systemd`, you can run `/usr/local/taos/bin/taosd` to start TDengine manually.
|
||||
|
||||
|
@ -174,23 +177,9 @@ After the installation is complete, run `C:\TDengine\taosd.exe` to start TDengin
|
|||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Test data insert performance
|
||||
## Command Line Interface (CLI)
|
||||
|
||||
After your TDengine Server is running normally, you can run the taosBenchmark utility to test its performance:
|
||||
|
||||
```bash
|
||||
taosBenchmark
|
||||
```
|
||||
|
||||
This command creates the `meters` supertable in the `test` database. In the `meters` supertable, it then creates 10,000 subtables named `d0` to `d9999`. Each table has 10,000 rows and each row has four columns: `ts`, `current`, `voltage`, and `phase`. The timestamps of the data in these columns range from 2017-07-14 10:40:00 000 to 2017-07-14 10:40:09 999. Each table is randomly assigned a `groupId` tag from 1 to 10 and a `location` tag of either `Campbell`, `Cupertino`, `Los Angeles`, `Mountain View`, `Palo Alto`, `San Diego`, `San Francisco`, `San Jose`, `Santa Clara` or `Sunnyvale`.
|
||||
|
||||
The `taosBenchmark` command creates a deployment with 100 million data points that you can use for testing purposes. The time required to create the deployment depends on your hardware. On most modern servers, the deployment is created in less than a minute.
|
||||
|
||||
You can customize the test deployment that taosBenchmark creates by specifying command-line parameters. For information about command-line parameters, run the `taosBenchmark --help` command. For more information about taosBenchmark, see [taosBenchmark](../../reference/taosbenchmark).
|
||||
|
||||
## Command Line Interface
|
||||
|
||||
You can use the TDengine CLI to monitor your TDengine deployment and execute ad hoc queries. To open the CLI, run the following command:
|
||||
You can use the TDengine CLI to monitor your TDengine deployment and execute ad hoc queries. To open the CLI, you can execute `taos` in the Linux terminal where TDengine is installed, or you can run `taos.exe` in the `C:\TDengine` directory of the Windows terminal where TDengine is installed to start the TDengine command line.
|
||||
|
||||
```bash
|
||||
taos
|
||||
|
@ -205,52 +194,71 @@ taos>
|
|||
For example, you can create and delete databases and tables and run all types of queries. Each SQL command must be end with a semicolon (;). For example:
|
||||
|
||||
```sql
|
||||
create database demo;
|
||||
use demo;
|
||||
create table t (ts timestamp, speed int);
|
||||
insert into t values ('2019-07-15 00:00:00', 10);
|
||||
insert into t values ('2019-07-15 01:00:00', 20);
|
||||
select * from t;
|
||||
CREATE DATABASE demo;
|
||||
USE demo;
|
||||
CREATE TABLE t (ts TIMESTAMP, speed INT);
|
||||
INSERT INTO t VALUES ('2019-07-15 00:00:00', 10);
|
||||
INSERT INTO t VALUES ('2019-07-15 01:00:00', 20);
|
||||
SELECT * FROM t;
|
||||
|
||||
ts | speed |
|
||||
========================================
|
||||
2019-07-15 00:00:00.000 | 10 |
|
||||
2019-07-15 01:00:00.000 | 20 |
|
||||
|
||||
Query OK, 2 row(s) in set (0.003128s)
|
||||
```
|
||||
|
||||
You can also can monitor the deployment status, add and remove user accounts, and manage running instances. You can run the TDengine CLI on either Linux or Windows machines. For more information, see [TDengine CLI](../../reference/taos-shell/).
|
||||
|
||||
|
||||
## Test data insert performance
|
||||
|
||||
After your TDengine Server is running normally, you can run the taosBenchmark utility to test its performance:
|
||||
|
||||
Start TDengine service and execute `taosBenchmark` (formerly named `taosdemo`) in a Linux or Windows terminal.
|
||||
|
||||
```bash
|
||||
taosBenchmark
|
||||
```
|
||||
|
||||
This command creates the `meters` supertable in the `test` database. In the `meters` supertable, it then creates 10,000 subtables named `d0` to `d9999`. Each table has 10,000 rows and each row has four columns: `ts`, `current`, `voltage`, and `phase`. The timestamps of the data in these columns range from 2017-07-14 10:40:00 000 to 2017-07-14 10:40:09 999. Each table is randomly assigned a `groupId` tag from 1 to 10 and a `location` tag of either `Campbell`, `Cupertino`, `Los Angeles`, `Mountain View`, `Palo Alto`, `San Diego`, `San Francisco`, `San Jose`, `Santa Clara` or `Sunnyvale`.
|
||||
|
||||
The `taosBenchmark` command creates a deployment with 100 million data points that you can use for testing purposes. The time required to create the deployment depends on your hardware. On most modern servers, the deployment is created in ten to twenty seconds.
|
||||
|
||||
You can customize the test deployment that taosBenchmark creates by specifying command-line parameters. For information about command-line parameters, run the `taosBenchmark --help` command. For more information about taosBenchmark, see [taosBenchmark](../../reference/taosbenchmark).
|
||||
|
||||
## Test data query performance
|
||||
|
||||
After using taosBenchmark to create your test deployment, you can run queries in the TDengine CLI to test its performance:
|
||||
After using `taosBenchmark` to create your test deployment, you can run queries in the TDengine CLI to test its performance:
|
||||
|
||||
From the TDengine CLI query the number of rows in the `meters` supertable:
|
||||
From the TDengine CLI (taos) query the number of rows in the `meters` supertable:
|
||||
|
||||
```sql
|
||||
select count(*) from test.meters;
|
||||
SELECT COUNT(*) FROM test.meters;
|
||||
```
|
||||
|
||||
Query the average, maximum, and minimum values of all 100 million rows of data:
|
||||
|
||||
```sql
|
||||
select avg(current), max(voltage), min(phase) from test.meters;
|
||||
SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters;
|
||||
```
|
||||
|
||||
Query the number of rows whose `location` tag is `San Francisco`:
|
||||
|
||||
```sql
|
||||
select count(*) from test.meters where location="San Francisco";
|
||||
SELECT COUNT(*) FROM test.meters WHERE location = "San Francisco";
|
||||
```
|
||||
|
||||
Query the average, maximum, and minimum values of all rows whose `groupId` tag is `10`:
|
||||
|
||||
```sql
|
||||
select avg(current), max(voltage), min(phase) from test.meters where groupId=10;
|
||||
SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters WHERE groupId = 10;
|
||||
```
|
||||
|
||||
Query the average, maximum, and minimum values for table `d10` in 1 second intervals:
|
||||
Query the average, maximum, and minimum values for table `d10` in 10 second intervals:
|
||||
|
||||
```sql
|
||||
select first(ts), avg(current), max(voltage), min(phase) from test.d10 interval(1s);
|
||||
SELECT FIRST(ts), AVG(current), MAX(voltage), MIN(phase) FROM test.d10 INTERVAL(10s);
|
||||
```
|
||||
In the query above you are selecting the first timestamp (ts) in the interval, another way of selecting this would be _wstart which will give the start of the time window. For more information about windowed queries, see [Time-Series Extensions](../../taos-sql/distinguished/).
|
||||
|
||||
In the query above you are selecting the first timestamp (ts) in the interval, another way of selecting this would be `\_wstart` which will give the start of the time window. For more information about windowed queries, see [Time-Series Extensions](../../taos-sql/distinguished/).
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace TDengineExample
|
|||
CheckRes(conn, res, "failed to insert data");
|
||||
int affectedRows = TDengine.AffectRows(res);
|
||||
Console.WriteLine("affectedRows " + affectedRows);
|
||||
TDengine.FreeResult(res);
|
||||
ExitProgram(conn, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ TDengine 的主要功能如下:
|
|||
- 多种[数据导出](../operation/export)方式
|
||||
9. 工具
|
||||
- 提供[交互式命令行程序(CLI)](../reference/taos-shell),便于管理集群,检查系统状态,做即席查询
|
||||
- 提供压力测试工具[taosBenchmark](../reference/taosbenchmark),用于测试 TDengine 的性能
|
||||
- 提供压力测试工具 [taosBenchmark](../reference/taosbenchmark),用于测试 TDengine 的性能
|
||||
10. 编程
|
||||
- 提供各种语言的[连接器(Connector)](../connector): 如 [C/C++](../connector/cpp)、[Java](../connector/java)、[Go](../connector/go)、[Node.js](../connector/node)、[Rust](../connector/rust)、[Python](../connector/python)、[C#](../connector/csharp) 等
|
||||
- 支持 [REST 接口](../connector/rest-api/)
|
||||
|
|
|
@ -4,119 +4,118 @@ title: 数据模型和基本概念
|
|||
description: TDengine 的数据模型和基本概念
|
||||
---
|
||||
|
||||
为了便于解释基本概念,便于撰写示例程序,整个 TDengine 文档以智能电表作为典型时序数据场景。假设每个智能电表采集电流、电压、相位三个量,有多个智能电表,每个电表有位置 location 和分组 group ID 的静态属性. 其采集的数据类似如下的表格:
|
||||
为了便于解释基本概念,便于撰写示例程序,整个 TDengine 文档以智能电表作为典型时序数据场景。假设每个智能电表采集电流、电压、相位三个量,有多个智能电表,每个电表有位置 Location 和分组 Group ID 的静态属性. 其采集的数据类似如下的表格:
|
||||
|
||||
<div className="center-table">
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>Device ID</th>
|
||||
<th>Time Stamp</th>
|
||||
<th colSpan="3">Collected Metrics</th>
|
||||
<th colSpan="2">Tags</th>
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowSpan="2">Device ID</th>
|
||||
<th rowSpan="2">Timestamp</th>
|
||||
<th colSpan="3">Collected Metrics</th>
|
||||
<th colSpan="2">Tags</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Device ID</th>
|
||||
<th>Time Stamp</th>
|
||||
<th>current</th>
|
||||
<th>voltage</th>
|
||||
<th>phase</th>
|
||||
<th>location</th>
|
||||
<th>groupId</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548685000</td>
|
||||
<td>10.3</td>
|
||||
<td>219</td>
|
||||
<td>0.31</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1002</td>
|
||||
<td>1538548684000</td>
|
||||
<td>10.2</td>
|
||||
<td>220</td>
|
||||
<td>0.23</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1003</td>
|
||||
<td>1538548686500</td>
|
||||
<td>11.5</td>
|
||||
<td>221</td>
|
||||
<td>0.35</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1004</td>
|
||||
<td>1538548685500</td>
|
||||
<td>13.4</td>
|
||||
<td>223</td>
|
||||
<td>0.29</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548695000</td>
|
||||
<td>12.6</td>
|
||||
<td>218</td>
|
||||
<td>0.33</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1004</td>
|
||||
<td>1538548696600</td>
|
||||
<td>11.8</td>
|
||||
<td>221</td>
|
||||
<td>0.28</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1002</td>
|
||||
<td>1538548696650</td>
|
||||
<td>10.3</td>
|
||||
<td>218</td>
|
||||
<td>0.25</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548696800</td>
|
||||
<td>12.3</td>
|
||||
<td>221</td>
|
||||
<td>0.31</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tr>
|
||||
<th>current</th>
|
||||
<th>voltage</th>
|
||||
<th>phase</th>
|
||||
<th>location</th>
|
||||
<th>groupid</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548685000</td>
|
||||
<td>10.3</td>
|
||||
<td>219</td>
|
||||
<td>0.31</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1002</td>
|
||||
<td>1538548684000</td>
|
||||
<td>10.2</td>
|
||||
<td>220</td>
|
||||
<td>0.23</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1003</td>
|
||||
<td>1538548686500</td>
|
||||
<td>11.5</td>
|
||||
<td>221</td>
|
||||
<td>0.35</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1004</td>
|
||||
<td>1538548685500</td>
|
||||
<td>13.4</td>
|
||||
<td>223</td>
|
||||
<td>0.29</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548695000</td>
|
||||
<td>12.6</td>
|
||||
<td>218</td>
|
||||
<td>0.33</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1004</td>
|
||||
<td>1538548696600</td>
|
||||
<td>11.8</td>
|
||||
<td>221</td>
|
||||
<td>0.28</td>
|
||||
<td>California.LosAngeles</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1002</td>
|
||||
<td>1538548696650</td>
|
||||
<td>10.3</td>
|
||||
<td>218</td>
|
||||
<td>0.25</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d1001</td>
|
||||
<td>1538548696800</td>
|
||||
<td>12.3</td>
|
||||
<td>221</td>
|
||||
<td>0.31</td>
|
||||
<td>California.SanFrancisco</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="#model_table1">表 1:智能电表数据示例</a>
|
||||
<a name="#model_table1">表 1. 智能电表数据示例</a>
|
||||
</div>
|
||||
|
||||
每一条记录都有设备 ID,时间戳,采集的物理量以及每个设备相关的静态标签。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。
|
||||
每一条记录都有设备 ID、时间戳、采集的物理量(如上表中的 `current`、`voltage` 和 `phase`)以及每个设备相关的静态标签(`location` 和 `groupid`)。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。
|
||||
|
||||
## 采集量 (Metric)
|
||||
## 采集量(Metric)
|
||||
|
||||
采集量是指传感器、设备或其他类型采集点采集的物理量,比如电流、电压、温度、压力、GPS 位置等,是随时间变化的,数据类型可以是整型、浮点型、布尔型,也可是字符串。随着时间的推移,存储的采集量的数据量越来越大。智能电表示例中的电流、电压、相位就是采集量。
|
||||
|
||||
## 标签 (Label/Tag)
|
||||
## 标签(Label/Tag)
|
||||
|
||||
标签是指传感器、设备或其他类型采集点的静态属性,不是随时间变化的,比如设备型号、颜色、设备的所在地等,数据类型可以是任何类型。虽然是静态的,但 TDengine 容许用户修改、删除或增加标签值。与采集量不一样的是,随时间的推移,存储的标签的数据量不会有什么变化。智能电表示例中的location与groupId就是标签。
|
||||
标签是指传感器、设备或其他类型采集点的静态属性,不是随时间变化的,比如设备型号、颜色、设备的所在地等,数据类型可以是任何类型。虽然是静态的,但 TDengine 容许用户修改、删除或增加标签值。与采集量不一样的是,随时间的推移,存储的标签的数据量不会有什么变化。智能电表示例中的 `location` 与 `groupid` 就是标签。
|
||||
|
||||
## 数据采集点 (Data Collection Point)
|
||||
## 数据采集点(Data Collection Point)
|
||||
|
||||
数据采集点是指按照预设时间周期或受事件触发采集物理量的硬件或软件。一个数据采集点可以采集一个或多个采集量,**但这些采集量都是同一时刻采集的,具有相同的时间戳**。对于复杂的设备,往往有多个数据采集点,每个数据采集点采集的周期都可能不一样,而且完全独立,不同步。比如对于一台汽车,有数据采集点专门采集 GPS 位置,有数据采集点专门采集发动机状态,有数据采集点专门采集车内的环境,这样一台汽车就有三个数据采集点。智能电表示例中的d1001, d1002, d1003, d1004等就是数据采集点。
|
||||
数据采集点是指按照预设时间周期或受事件触发采集物理量的硬件或软件。一个数据采集点可以采集一个或多个采集量,**但这些采集量都是同一时刻采集的,具有相同的时间戳**。对于复杂的设备,往往有多个数据采集点,每个数据采集点采集的周期都可能不一样,而且完全独立,不同步。比如对于一台汽车,有数据采集点专门采集 GPS 位置,有数据采集点专门采集发动机状态,有数据采集点专门采集车内的环境,这样一台汽车就有三个数据采集点。智能电表示例中的 d1001、d1002、d1003、d1004 等就是数据采集点。
|
||||
|
||||
## 表 (Table)
|
||||
## 表(Table)
|
||||
|
||||
因为采集量一般是结构化数据,同时为降低学习门槛,TDengine 采用传统的关系型数据库模型管理数据。用户需要先创建库,然后创建表,之后才能插入或查询数据。
|
||||
|
||||
|
@ -129,50 +128,56 @@ description: TDengine 的数据模型和基本概念
|
|||
|
||||
如果采用传统的方式,将多个数据采集点的数据写入一张表,由于网络延时不可控,不同数据采集点的数据到达服务器的时序是无法保证的,写入操作是要有锁保护的,而且一个数据采集点的数据是难以保证连续存储在一起的。**采用一个数据采集点一张表的方式,能最大程度的保证单个数据采集点的插入和查询的性能是最优的。**
|
||||
|
||||
TDengine 建议用数据采集点的名字(如上表中的 D1001)来做表名。每个数据采集点可能同时采集多个采集量(如上表中的 current,voltage,phase),每个采集量对应一张表中的一列,数据类型可以是整型、浮点型、字符串等。除此之外,表的第一列必须是时间戳,即数据类型为 timestamp。对采集量,TDengine 将自动按照时间戳建立索引,但对采集量本身不建任何索引。数据用列式存储方式保存。
|
||||
TDengine 建议用数据采集点的名字(如上表中的 d1001)来做表名。每个数据采集点可能同时采集多个采集量(如上表中的 `current`、`voltage` 和 `phase`),每个采集量对应一张表中的一列,数据类型可以是整型、浮点型、字符串等。除此之外,表的第一列必须是时间戳,即数据类型为 Timestamp。对采集量,TDengine 将自动按照时间戳建立索引,但对采集量本身不建任何索引。数据用列式存储方式保存。
|
||||
|
||||
对于复杂的设备,比如汽车,它有多个数据采集点,那么就需要为一台汽车建立多张表。
|
||||
对于复杂的设备,比如汽车,它有多个数据采集点,那么就需要为一辆汽车建立多张表。
|
||||
|
||||
|
||||
## 超级表 (STable)
|
||||
## 超级表(STable)
|
||||
|
||||
由于一个数据采集点一张表,导致表的数量巨增,难以管理,而且应用经常需要做采集点之间的聚合操作,聚合的操作也变得复杂起来。为解决这个问题,TDengine 引入超级表(Super Table,简称为 STable)的概念。
|
||||
|
||||
超级表是指某一特定类型的数据采集点的集合。同一类型的数据采集点,其表的结构是完全一样的,但每个表(数据采集点)的静态属性(标签)是不一样的。描述一个超级表(某一特定类型的数据采集点的集合),除需要定义采集量的表结构之外,还需要定义其标签的 schema,标签的数据类型可以是整数、浮点数、字符串,标签可以有多个,可以事后增加、删除或修改。如果整个系统有 N 个不同类型的数据采集点,就需要建立 N 个超级表。
|
||||
超级表是指某一特定类型的数据采集点的集合。同一类型的数据采集点,其表的结构是完全一样的,但每个表(数据采集点)的静态属性(标签)是不一样的。描述一个超级表(某一特定类型的数据采集点的集合),除需要定义采集量的表结构之外,还需要定义其标签的 Schema,标签的数据类型可以是整数、浮点数、字符串、JSON,标签可以有多个,可以事后增加、删除或修改。如果整个系统有 N 个不同类型的数据采集点,就需要建立 N 个超级表。
|
||||
|
||||
在 TDengine 的设计里,**表用来代表一个具体的数据采集点,超级表用来代表一组相同类型的数据采集点集合**。智能电表示例中,我们可以创建一个超级表meters.
|
||||
在 TDengine 的设计里,**表用来代表一个具体的数据采集点,超级表用来代表一组相同类型的数据采集点集合**。智能电表示例中,我们可以创建一个超级表 `meters`.
|
||||
|
||||
## 子表 (Subtable)
|
||||
## 子表(Subtable)
|
||||
|
||||
当为某个具体数据采集点创建表时,用户可以使用超级表的定义做模板,同时指定该具体采集点(表)的具体标签值来创建该表。**通过超级表创建的表称之为子表**。正常的表与子表的差异在于:
|
||||
|
||||
1. 子表就是表,因此所有正常表的SQL操作都可以在子表上执行。
|
||||
1. 子表就是表,因此所有正常表的 SQL 操作都可以在子表上执行。
|
||||
2. 子表在正常表的基础上有扩展,它是带有静态标签的,而且这些标签可以事后增加、删除、修改,而正常的表没有。
|
||||
3. 子表一定属于一张超级表,但普通表不属于任何超级表
|
||||
4. 普通表无法转为子表,子表也无法转为普通表。
|
||||
|
||||
超级表与与基于超级表建立的子表之间的关系表现在:
|
||||
|
||||
1. 一张超级表包含有多张子表,这些子表具有相同的采集量 schema,但带有不同的标签值。
|
||||
1. 一张超级表包含有多张子表,这些子表具有相同的采集量 Schema,但带有不同的标签值。
|
||||
2. 不能通过子表调整数据或标签的模式,对于超级表的数据模式修改立即对所有的子表生效。
|
||||
3. 超级表只定义一个模板,自身不存储任何数据或标签信息。因此,不能向一个超级表写入数据,只能将数据写入子表中。
|
||||
|
||||
查询既可以在表上进行,也可以在超级表上进行。针对超级表的查询,TDengine 将把所有子表中的数据视为一个整体数据集进行处理,会先把满足标签过滤条件的表从超级表中找出来,然后再扫描这些表的时序数据,进行聚合操作,这样需要扫描的数据集会大幅减少,从而显著提高查询的性能。本质上,TDengine 通过对超级表查询的支持,实现了多个同类数据采集点的高效聚合。
|
||||
|
||||
TDengine系统建议给一个数据采集点建表,需要通过超级表建表,而不是建普通表。在智能电表的示例中,我们可以通过超级表meters创建子表d1001, d1002, d1003, d1004等。
|
||||
TDengine 系统建议给一个数据采集点建表,需要通过超级表建表,而不是建普通表。在智能电表的示例中,我们可以通过超级表 meters 创建子表 d1001、d1002、d1003、d1004 等。
|
||||
|
||||
为了更好地理解超级与子表的关系,可以参考下面关于智能电表数据模型的示意图。 
|
||||
为了更好地理解采集量、标签、超级与子表的关系,可以参考下面关于智能电表数据模型的示意图。
|
||||
|
||||
## 库 (database)
|
||||
<figure>
|
||||
|
||||

|
||||
|
||||
<center><figcaption>图 1. 智能电表数据模型示意图</figcaption></center>
|
||||
</figure>
|
||||
|
||||
## 库(Database)
|
||||
|
||||
库是指一组表的集合。TDengine 容许一个运行实例有多个库,而且每个库可以配置不同的存储策略。不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为了在各种场景下 TDengine 都能最大效率的工作,TDengine 建议将不同数据特征的超级表创建在不同的库里。
|
||||
|
||||
一个库里,可以有一到多个超级表,但一个超级表只属于一个库。一个超级表所拥有的子表全部存在一个库里。
|
||||
|
||||
## FQDN & End Point
|
||||
## FQDN & Endpoint
|
||||
|
||||
FQDN (fully qualified domain name, 完全限定域名)是 Internet 上特定计算机或主机的完整域名。FQDN 由两部分组成:主机名和域名。例如,假设邮件服务器的 FQDN 可能是 mail.tdengine.com。主机名是 mail,主机位于域名 tdengine.com 中。DNS(Domain Name System),负责将 FQDN 翻译成 IP,是互联网应用的寻址方式。对于没有 DNS 的系统,可以通过配置 hosts 文件来解决。
|
||||
FQDN(Fully Qualified Domain Name,完全限定域名)是 Internet 上特定计算机或主机的完整域名。FQDN 由两部分组成:主机名和域名。例如,假设邮件服务器的 FQDN 可能是 mail.tdengine.com。主机名是 mail,主机位于域名 tdengine.com 中。DNS(Domain Name System),负责将 FQDN 翻译成 IP,是互联网应用的寻址方式。对于没有 DNS 的系统,可以通过配置 hosts 文件来解决。
|
||||
|
||||
TDengine 集群的每个节点是由 End Point 来唯一标识的,End Point 是由 FQDN 外加 Port 组成,比如 h1.tdengine.com:6030。这样当 IP 发生变化的时候,我们依然可以使用 FQDN 来动态找到节点,不需要更改集群的任何配置。而且采用 FQDN,便于内网和外网对同一个集群的统一访问。
|
||||
TDengine 集群的每个节点是由 Endpoint 来唯一标识的,Endpoint 是由 FQDN 外加 Port 组成,比如 h1.tdengine.com:6030。这样当 IP 发生变化的时候,我们依然可以使用 FQDN 来动态找到节点,不需要更改集群的任何配置。而且采用 FQDN,便于内网和外网对同一个集群的统一访问。
|
||||
|
||||
TDengine 不建议采用直接的 IP 地址访问集群,不利于管理。不了解 FQDN 概念,请看博文[《一篇文章说清楚 TDengine 的 FQDN》](https://www.taosdata.com/blog/2020/09/11/1824.html)。
|
||||
|
|
|
@ -4,11 +4,11 @@ title: 通过 Docker 快速体验 TDengine
|
|||
description: 使用 Docker 快速体验 TDengine 的高效写入和查询
|
||||
---
|
||||
|
||||
本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用[安装包的方式快速体验](../../get-started/package/)。如果您希望为 TDengine 贡献代码或对内部技术实现感兴趣,请参考 [TDengine GitHub 主页](https://github.com/taosdata/TDengine) 下载源码构建和安装.
|
||||
本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用[安装包的方式快速体验](../../get-started/package/)。如果您希望为 TDengine 贡献代码或对内部技术实现感兴趣,请参考 [TDengine GitHub 主页](https://github.com/taosdata/TDengine)下载源码构建和安装。
|
||||
|
||||
## 启动 TDengine
|
||||
|
||||
如果已经安装了 docker, 只需执行下面的命令。
|
||||
如果已经安装了 Docker,只需执行下面的命令:
|
||||
|
||||
```shell
|
||||
docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043-6049/udp tdengine/tdengine
|
||||
|
@ -16,84 +16,84 @@ docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043
|
|||
|
||||
注意:TDengine 3.0 服务端仅使用 6030 TCP 端口。6041 为 taosAdapter 所使用提供 REST 服务端口。6043-6049 为 taosAdapter 提供第三方应用接入所使用端口,可根据需要选择是否打开。
|
||||
|
||||
确定该容器已经启动并且在正常运行
|
||||
确定该容器已经启动并且在正常运行。
|
||||
|
||||
```shell
|
||||
docker ps
|
||||
```
|
||||
|
||||
进入该容器并执行 bash
|
||||
进入该容器并执行 `bash`
|
||||
|
||||
```shell
|
||||
docker exec -it <container name> bash
|
||||
```
|
||||
|
||||
然后就可以执行相关的 Linux 命令操作和访问 TDengine
|
||||
然后就可以执行相关的 Linux 命令操作和访问 TDengine。
|
||||
|
||||
注: Docker 工具自身的下载和使用请参考 [Docker 官网文档](https://docs.docker.com/get-docker/)。
|
||||
注:Docker 工具自身的下载和使用请参考 [Docker 官网文档](https://docs.docker.com/get-docker/)。
|
||||
|
||||
## 运行 TDengine CLI
|
||||
|
||||
进入容器,执行 taos
|
||||
进入容器,执行 `taos`:
|
||||
|
||||
```
|
||||
$ taos
|
||||
|
||||
taos>
|
||||
|
||||
taos>
|
||||
```
|
||||
|
||||
## 写入数据
|
||||
## 使用 taosBenchmark 体验写入速度
|
||||
|
||||
可以使用 TDengine 的自带工具 taosBenchmark 快速体验 TDengine 的写入。
|
||||
可以使用 TDengine 的自带工具 taosBenchmark 快速体验 TDengine 的写入速度。
|
||||
|
||||
进入容器,启动 taosBenchmark:
|
||||
启动 TDengine 的服务,在 Linux 或 Windows 终端执行 `taosBenchmark`(曾命名为 `taosdemo`):
|
||||
|
||||
```bash
|
||||
$ taosBenchmark
|
||||
|
||||
```
|
||||
```bash
|
||||
$ taosBenchmark
|
||||
```
|
||||
|
||||
该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "San Francisco" 或者 "Los Angeles"等城市名称。
|
||||
该命令将在数据库 `test` 下面自动创建一张超级表 `meters`,该超级表下有 1 万张表,表名为 `d0` 到 `d9999`,每张表有 1 万条记录,每条记录有 `ts`、`current`、`voltage`、`phase` 四个字段,时间戳从 2017-07-14 10:40:00 000 到 2017-07-14 10:40:09 999,每张表带有标签 `location` 和 `groupId`,groupId 被设置为 1 到 10,location 被设置为 `Campbell`、`Cupertino`、`Los Angeles`、`Mountain View`、`Palo Alto`、`San Diego`、`San Francisco`、`San Jose`、`Santa Clara` 或者 `Sunnyvale`。
|
||||
|
||||
这条命令很快完成 1 亿条记录的插入。具体时间取决于硬件性能。
|
||||
这条命令很快完成 1 亿条记录的插入。具体时间取决于硬件性能,即使在一台普通的 PC 服务器往往也仅需十几秒。
|
||||
|
||||
taosBenchmark 命令本身带有很多选项,配置表的数目、记录条数等等,您可以设置不同参数进行体验,请执行 `taosBenchmark --help` 详细列出。taosBenchmark 详细使用方法请参照 [taosBenchmark 参考手册](../../reference/taosbenchmark)。
|
||||
taosBenchmark 命令本身带有很多选项,配置表的数目、记录条数等等,您可以设置不同参数进行体验,请执行 `taosBenchmark --help` 详细列出。taosBenchmark 详细使用方法请参照[如何使用 taosBenchmark 对 TDengine 进行性能测试](https://www.taosdata.com/2021/10/09/3111.html)和 [taosBenchmark 参考手册](../../reference/taosbenchmark)。
|
||||
|
||||
## 体验查询
|
||||
## 使用 TDengine CLI 体验查询速度
|
||||
|
||||
使用上述 taosBenchmark 插入数据后,可以在 TDengine CLI 输入查询命令,体验查询速度。。
|
||||
使用上述 `taosBenchmark` 插入数据后,可以在 TDengine CLI(taos)输入查询命令,体验查询速度。
|
||||
|
||||
查询超级表下记录总条数:
|
||||
查询超级表 `meters` 下的记录总条数:
|
||||
|
||||
```sql
|
||||
taos> select count(*) from test.meters;
|
||||
SELECT COUNT(*) FROM test.meters;
|
||||
```
|
||||
|
||||
查询 1 亿条记录的平均值、最大值、最小值等:
|
||||
|
||||
```sql
|
||||
taos> select avg(current), max(voltage), min(phase) from test.meters;
|
||||
SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters;
|
||||
```
|
||||
|
||||
查询 location="San Francisco" 的记录总条数:
|
||||
查询 location = "San Francisco" 的记录总条数:
|
||||
|
||||
```sql
|
||||
taos> select count(*) from test.meters where location="San Francisco";
|
||||
SELECT COUNT(*) FROM test.meters WHERE location = "San Francisco";
|
||||
```
|
||||
|
||||
查询 groupId=10 的所有记录的平均值、最大值、最小值等:
|
||||
查询 groupId = 10 的所有记录的平均值、最大值、最小值等:
|
||||
|
||||
```sql
|
||||
taos> select avg(current), max(voltage), min(phase) from test.meters where groupId=10;
|
||||
SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters WHERE groupId = 10;
|
||||
```
|
||||
|
||||
对表 d10 按 10s 进行平均值、最大值和最小值聚合统计:
|
||||
对表 `d10` 按 10 每秒进行平均值、最大值和最小值聚合统计:
|
||||
|
||||
```sql
|
||||
taos> select avg(current), max(voltage), min(phase) from test.d10 interval(10s);
|
||||
SELECT FIRST(ts), AVG(current), MAX(voltage), MIN(phase) FROM test.d10 INTERVAL(10s);
|
||||
```
|
||||
|
||||
在上面的查询中,你选择的是区间内的第一个时间戳(ts),另一种选择方式是 `\_wstart`,它将给出时间窗口的开始。关于窗口查询的更多信息,参见[特色查询](../../taos-sql/distinguished/)。
|
||||
|
||||
## 其它
|
||||
|
||||
更多关于在 Docker 环境下使用 TDengine 的细节,请参考 [在 Docker 下使用 TDengine](../../reference/docker)
|
||||
更多关于在 Docker 环境下使用 TDengine 的细节,请参考 [在 Docker 下使用 TDengine](../../reference/docker)。
|
||||
|
|
|
@ -10,23 +10,24 @@ import PkgListV3 from "/components/PkgListV3";
|
|||
|
||||
您可以[用 Docker 立即体验](../../get-started/docker/) TDengine。如果您希望对 TDengine 贡献代码或对内部实现感兴趣,请参考我们的 [TDengine GitHub 主页](https://github.com/taosdata/TDengine) 下载源码构建和安装.
|
||||
|
||||
TDengine 完整的软件包包括服务端(taosd)、用于与第三方系统对接并提供 RESTful 接口的 taosAdapter、应用驱动(taosc)、命令行程序 (CLI,taos) 和一些工具软件。目前 taosAdapter 仅在 Linux 系统上安装和运行,后续将支持 Windows、macOS 等系统。TDengine 除了提供多种语言的连接器之外,还通过 [taosAdapter](../../reference/taosadapter/) 提供 [RESTful 接口](../../connector/rest-api/)。
|
||||
TDengine 完整的软件包包括服务端(taosd)、应用驱动(taosc)、用于与第三方系统对接并提供 RESTful 接口的 taosAdapter、命令行程序(CLI,taos)和一些工具软件。目前 taosAdapter 仅在 Linux 系统上安装和运行,后续将支持 Windows、macOS 等系统。TDengine 除了提供多种语言的连接器之外,还通过 [taosAdapter](../../reference/taosadapter/) 提供 [RESTful 接口](../../connector/rest-api/)。
|
||||
|
||||
为方便使用,标准的服务端安装包包含了 taosd、taosAdapter、taosc、taos、taosdump、taosBenchmark、TDinsight 安装脚本和示例代码;如果您只需要用到服务端程序和客户端连接的 C/C++ 语言支持,也可以仅下载 lite 版本的安装包。
|
||||
为方便使用,标准的服务端安装包包含了 taosd、taosAdapter、taosc、taos、taosdump、taosBenchmark、TDinsight 安装脚本和示例代码;如果您只需要用到服务端程序和客户端连接的 C/C++ 语言支持,也可以仅下载 Lite 版本的安装包。
|
||||
|
||||
在 Linux 系统上,TDengine 开源版本提供 deb 和 rpm 格式安装包,用户可以根据自己的运行环境选择合适的安装包。其中 deb 支持 Debian/Ubuntu 及衍生系统,rpm 支持 CentOS/RHEL/SUSE 及衍生系统。同时我们也为企业用户提供 tar.gz 格式安装包,也支持通过 `apt-get` 工具从线上进行安装。需要注意的是,rpm 和 deb 包不含 taosdump 和 TDinsight 安装脚本,这些工具需要通过安装 taosTool 包获得。TDengine 也提供 Windows x64 平台的安装包。
|
||||
在 Linux 系统上,TDengine 社区版提供 Deb 和 RPM 格式安装包,用户可以根据自己的运行环境选择合适的安装包。其中 Deb 支持 Debian/Ubuntu 及其衍生系统,RPM 支持 CentOS/RHEL/SUSE 及其衍生系统。同时我们也为企业用户提供 tar.gz 格式安装包,也支持通过 `apt-get` 工具从线上进行安装。需要注意的是,RPM 和 Deb 包不含 `taosdump` 和 TDinsight 安装脚本,这些工具需要通过安装 taosTool 包获得。TDengine 也提供 Windows x64 平台的安装包。
|
||||
|
||||
## 安装
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Deb 安装" value="debinst">
|
||||
|
||||
1. 从列表中下载获得 deb 安装包;
|
||||
<PkgListV3 type={6}/>
|
||||
1. 从列表中下载获得 Deb 安装包;
|
||||
<PkgListV3 type={6}/>
|
||||
2. 进入到安装包所在目录,执行如下的安装命令:
|
||||
|
||||
> 请将 `<version>` 替换为下载的安装包版本
|
||||
|
||||
```bash
|
||||
# 替换为下载的安装包版本
|
||||
sudo dpkg -i TDengine-server-<version>-Linux-x64.deb
|
||||
```
|
||||
|
||||
|
@ -34,12 +35,13 @@ sudo dpkg -i TDengine-server-<version>-Linux-x64.deb
|
|||
|
||||
<TabItem label="RPM 安装" value="rpminst">
|
||||
|
||||
1. 从列表中下载获得 rpm 安装包;
|
||||
<PkgListV3 type={5}/>
|
||||
1. 从列表中下载获得 RPM 安装包;
|
||||
<PkgListV3 type={5}/>
|
||||
2. 进入到安装包所在目录,执行如下的安装命令:
|
||||
|
||||
> 请将 `<version>` 替换为下载的安装包版本
|
||||
|
||||
```bash
|
||||
# 替换为下载的安装包版本
|
||||
sudo rpm -ivh TDengine-server-<version>-Linux-x64.rpm
|
||||
```
|
||||
|
||||
|
@ -48,44 +50,46 @@ sudo rpm -ivh TDengine-server-<version>-Linux-x64.rpm
|
|||
<TabItem label="tar.gz 安装" value="tarinst">
|
||||
|
||||
1. 从列表中下载获得 tar.gz 安装包;
|
||||
<PkgListV3 type={0}/>
|
||||
2. 进入到安装包所在目录,先解压文件后,进入子目录,执行其中的 install.sh 安装脚本:
|
||||
<PkgListV3 type={0}/>
|
||||
2. 进入到安装包所在目录,使用 `tar` 解压安装包;
|
||||
3. 进入到安装包所在目录,先解压文件后,进入子目录,执行其中的 install.sh 安装脚本。
|
||||
|
||||
> 请将 `<version>` 替换为下载的安装包版本
|
||||
|
||||
```bash
|
||||
# 替换为下载的安装包版本
|
||||
tar -zxvf TDengine-server-<version>-Linux-x64.tar.gz
|
||||
```
|
||||
|
||||
解压后进入相应路径,执行
|
||||
解压文件后,进入相应子目录,执行其中的 `install.sh` 安装脚本:
|
||||
|
||||
```bash
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
:::info
|
||||
install.sh 安装脚本在执行过程中,会通过命令行交互界面询问一些配置信息。如果希望采取无交互安装方式,那么可以用 -e no 参数来执行 install.sh 脚本。运行 `./install.sh -h` 指令可以查看所有参数的详细说明信息。
|
||||
install.sh 安装脚本在执行过程中,会通过命令行交互界面询问一些配置信息。如果希望采取无交互安装方式,那么可以运行 `./install.sh -e no`。运行 `./install.sh -h` 指令可以查看所有参数的详细说明信息。
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="apt-get" label="apt-get">
|
||||
可以使用 apt-get 工具从官方仓库安装。
|
||||
可以使用 `apt-get` 工具从官方仓库安装。
|
||||
|
||||
**安装包仓库**
|
||||
**配置包仓库**
|
||||
|
||||
```bash
|
||||
wget -qO - http://repos.taosdata.com/tdengine.key | sudo apt-key add -
|
||||
echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-stable stable main" | sudo tee /etc/apt/sources.list.d/tdengine-stable.list
|
||||
```
|
||||
|
||||
如果安装 Beta 版需要安装包仓库
|
||||
如果安装 Beta 版需要安装包仓库:
|
||||
|
||||
```bash
|
||||
wget -qO - http://repos.taosdata.com/tdengine.key | sudo apt-key add -
|
||||
echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-beta beta main" | sudo tee /etc/apt/sources.list.d/tdengine-beta.list
|
||||
```
|
||||
|
||||
**使用 apt-get 命令安装**
|
||||
**使用 `apt-get` 命令安装**
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
|
@ -94,26 +98,26 @@ sudo apt-get install tdengine
|
|||
```
|
||||
|
||||
:::tip
|
||||
apt-get 方式只适用于 Debian 或 Ubuntu 系统
|
||||
apt-get 方式只适用于 Debian 或 Ubuntu 系统。
|
||||
::::
|
||||
</TabItem>
|
||||
<TabItem label="Windows 安装" value="windows">
|
||||
<TabItem label="Windows 安装" value="windows">
|
||||
|
||||
注意:目前 TDengine 在 Windows 平台上只支持 Windows server 2016/2019 和 Windows 10/11 系统版本。
|
||||
注意:目前 TDengine 在 Windows 平台上只支持 Windows Server 2016/2019 和 Windows 10/11。
|
||||
|
||||
1. 从列表中下载获得 exe 安装程序;
|
||||
<PkgListV3 type={3}/>
|
||||
<PkgListV3 type={3}/>
|
||||
2. 运行可执行程序来安装 TDengine。
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::info
|
||||
下载其他组件、最新 Beta 版及之前版本的安装包,请点击[发布历史页面](../../releases/tdengine)
|
||||
下载其他组件、最新 Beta 版及之前版本的安装包,请点击[发布历史页面](../../releases/tdengine)。
|
||||
:::
|
||||
|
||||
:::note
|
||||
当安装第一个节点时,出现 Enter FQDN:提示的时候,不需要输入任何内容。只有当安装第二个或以后更多的节点时,才需要输入已有集群中任何一个可用节点的 FQDN,支持该新节点加入集群。当然也可以不输入,而是在新节点启动前,配置到新节点的配置文件中。
|
||||
当安装第一个节点时,出现 `Enter FQDN:` 提示的时候,不需要输入任何内容。只有当安装第二个或以后更多的节点时,才需要输入已有集群中任何一个可用节点的 FQDN,支持该新节点加入集群。当然也可以不输入,而是在新节点启动前,配置到新节点的配置文件中。
|
||||
|
||||
:::
|
||||
|
||||
|
@ -148,7 +152,7 @@ Active: inactive (dead)
|
|||
|
||||
如果 TDengine 服务正常工作,那么您可以通过 TDengine 的命令行程序 `taos` 来访问并体验 TDengine。
|
||||
|
||||
systemctl 命令汇总:
|
||||
如下 `systemctl` 命令可以帮助你管理 TDengine 服务:
|
||||
|
||||
- 启动服务进程:`systemctl start taosd`
|
||||
|
||||
|
@ -160,7 +164,7 @@ systemctl 命令汇总:
|
|||
|
||||
:::info
|
||||
|
||||
- systemctl 命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo 。
|
||||
- `systemctl` 命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 `sudo`。
|
||||
- `systemctl stop taosd` 指令在执行后并不会马上停止 TDengine 服务,而是会等待系统中必要的落盘工作正常完成。在数据量很大的情况下,这可能会消耗较长时间。
|
||||
- 如果系统中不支持 `systemd`,也可以用手动运行 `/usr/local/taos/bin/taosd` 方式启动 TDengine 服务。
|
||||
|
||||
|
@ -170,87 +174,93 @@ systemctl 命令汇总:
|
|||
|
||||
<TabItem label="Windows 系统" value="windows">
|
||||
|
||||
安装后,在 C:\TDengine 目录下,运行 taosd.exe 来启动 TDengine 服务进程。
|
||||
安装后,在 `C:\TDengine` 目录下,运行 `taosd.exe` 来启动 TDengine 服务进程。
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## TDengine 命令行 (CLI)
|
||||
## TDengine 命令行(CLI)
|
||||
|
||||
为便于检查 TDengine 的状态,执行数据库 (Database) 的各种即席(Ad Hoc)查询,TDengine 提供一命令行应用程序(以下简称为 TDengine CLI) taos。要进入 TDengine 命令行,您只要在安装有 TDengine 的 Linux 终端执行 `taos` 即可,也可以在安装有 TDengine 的 Windows 终端的 C:\TDengine 目录下,运行 taos.exe 来启动 TDengine 命令行。
|
||||
为便于检查 TDengine 的状态,执行数据库(Database)的各种即席(Ad Hoc)查询,TDengine 提供一命令行应用程序(以下简称为 TDengine CLI)taos。要进入 TDengine 命令行,您只要在安装有 TDengine 的 Linux 终端执行 `taos` 即可,也可以在安装有 TDengine 的 Windows 终端的 C:\TDengine 目录下,运行 taos.exe 来启动 TDengine 命令行。
|
||||
|
||||
```bash
|
||||
taos
|
||||
```
|
||||
|
||||
如果连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息出来(请参考 [FAQ](/train-faq/faq) 来解决终端连接服务端失败的问题)。 TDengine CLI 的提示符号如下:
|
||||
如果连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息出来(请参考 [FAQ](/train-faq/faq) 来解决终端连接服务端失败的问题)。TDengine CLI 的提示符号如下:
|
||||
|
||||
```cmd
|
||||
taos>
|
||||
```
|
||||
|
||||
在 TDengine CLI 中,用户可以通过 SQL 命令来创建/删除数据库、表等,并进行数据库(database)插入查询操作。在终端中运行的 SQL 语句需要以分号结束来运行。示例:
|
||||
在 TDengine CLI 中,用户可以通过 SQL 命令来创建/删除数据库、表等,并进行数据库(Database)插入查询操作。在终端中运行的 SQL 语句需要以分号(;)结束来运行。示例:
|
||||
|
||||
```sql
|
||||
create database demo;
|
||||
use demo;
|
||||
create table t (ts timestamp, speed int);
|
||||
insert into t values ('2019-07-15 00:00:00', 10);
|
||||
insert into t values ('2019-07-15 01:00:00', 20);
|
||||
select * from t;
|
||||
CREATE DATABASE demo;
|
||||
USE demo;
|
||||
CREATE TABLE t (ts TIMESTAMP, speed INT);
|
||||
INSERT INTO t VALUES ('2019-07-15 00:00:00', 10);
|
||||
INSERT INTO t VALUES ('2019-07-15 01:00:00', 20);
|
||||
SELECT * FROM t;
|
||||
|
||||
ts | speed |
|
||||
========================================
|
||||
2019-07-15 00:00:00.000 | 10 |
|
||||
2019-07-15 01:00:00.000 | 20 |
|
||||
|
||||
Query OK, 2 row(s) in set (0.003128s)
|
||||
```
|
||||
|
||||
除执行 SQL 语句外,系统管理员还可以从 TDengine CLI 进行检查系统运行状态、添加删除用户账号等操作。TDengine CLI 连同应用驱动也可以独立安装在 Linux 或 Windows 机器上运行,更多细节请参考 [这里](../../reference/taos-shell/)
|
||||
除执行 SQL 语句外,系统管理员还可以从 TDengine CLI 进行检查系统运行状态、添加删除用户账号等操作。TDengine CLI 连同应用驱动也可以独立安装在 Linux 或 Windows 机器上运行,更多细节请参考 [TDengine 命令行](../../reference/taos-shell/)。
|
||||
|
||||
## 使用 taosBenchmark 体验写入速度
|
||||
|
||||
启动 TDengine 的服务,在 Linux 或 windows 终端执行 `taosBenchmark` (曾命名为 `taosdemo`):
|
||||
可以使用 TDengine 的自带工具 taosBenchmark 快速体验 TDengine 的写入速度。
|
||||
|
||||
启动 TDengine 的服务,在 Linux 或 Windows 终端执行 `taosBenchmark`(曾命名为 `taosdemo`):
|
||||
|
||||
```bash
|
||||
taosBenchmark
|
||||
$ taosBenchmark
|
||||
```
|
||||
|
||||
该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "California.SanFrancisco" 或者 "California.LosAngeles"。
|
||||
该命令将在数据库 `test` 下面自动创建一张超级表 `meters`,该超级表下有 1 万张表,表名为 `d0` 到 `d9999`,每张表有 1 万条记录,每条记录有 `ts`、`current`、`voltage`、`phase` 四个字段,时间戳从 2017-07-14 10:40:00 000 到 2017-07-14 10:40:09 999,每张表带有标签 `location` 和 `groupId`,groupId 被设置为 1 到 10,location 被设置为 `Campbell`、`Cupertino`、`Los Angeles`、`Mountain View`、`Palo Alto`、`San Diego`、`San Francisco`、`San Jose`、`Santa Clara` 或者 `Sunnyvale`。
|
||||
|
||||
这条命令很快完成 1 亿条记录的插入。具体时间取决于硬件性能,即使在一台普通的 PC 服务器往往也仅需十几秒。
|
||||
|
||||
taosBenchmark 命令本身带有很多选项,配置表的数目、记录条数等等,您可以设置不同参数进行体验,请执行 `taosBenchmark --help` 详细列出。taosBenchmark 详细使用方法请参照 [如何使用 taosBenchmark 对 TDengine 进行性能测试](https://www.taosdata.com/2021/10/09/3111.html)。
|
||||
taosBenchmark 命令本身带有很多选项,配置表的数目、记录条数等等,您可以设置不同参数进行体验,请执行 `taosBenchmark --help` 详细列出。taosBenchmark 详细使用方法请参照[如何使用 taosBenchmark 对 TDengine 进行性能测试](https://www.taosdata.com/2021/10/09/3111.html)和 [taosBenchmark 参考手册](../../reference/taosbenchmark)。
|
||||
|
||||
## 使用 TDengine CLI 体验查询速度
|
||||
|
||||
使用上述 taosBenchmark 插入数据后,可以在 TDengine CLI 输入查询命令,体验查询速度。
|
||||
使用上述 `taosBenchmark` 插入数据后,可以在 TDengine CLI(taos)输入查询命令,体验查询速度。
|
||||
|
||||
查询超级表下记录总条数:
|
||||
查询超级表 `meters` 下的记录总条数:
|
||||
|
||||
```sql
|
||||
taos> select count(*) from test.meters;
|
||||
SELECT COUNT(*) FROM test.meters;
|
||||
```
|
||||
|
||||
查询 1 亿条记录的平均值、最大值、最小值等:
|
||||
|
||||
```sql
|
||||
taos> select avg(current), max(voltage), min(phase) from test.meters;
|
||||
SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters;
|
||||
```
|
||||
|
||||
查询 location="California.SanFrancisco" 的记录总条数:
|
||||
查询 location = "San Francisco" 的记录总条数:
|
||||
|
||||
```sql
|
||||
taos> select count(*) from test.meters where location="California.SanFrancisco";
|
||||
SELECT COUNT(*) FROM test.meters WHERE location = "San Francisco";
|
||||
```
|
||||
|
||||
查询 groupId=10 的所有记录的平均值、最大值、最小值等:
|
||||
查询 groupId = 10 的所有记录的平均值、最大值、最小值等:
|
||||
|
||||
```sql
|
||||
taos> select avg(current), max(voltage), min(phase) from test.meters where groupId=10;
|
||||
SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters WHERE groupId = 10;
|
||||
```
|
||||
|
||||
对表 d10 按 10s 进行平均值、最大值和最小值聚合统计:
|
||||
对表 `d10` 按 10 每秒进行平均值、最大值和最小值聚合统计:
|
||||
|
||||
```sql
|
||||
taos> select avg(current), max(voltage), min(phase) from test.d10 interval(10s);
|
||||
SELECT FIRST(ts), AVG(current), MAX(voltage), MIN(phase) FROM test.d10 INTERVAL(10s);
|
||||
```
|
||||
|
||||
在上面的查询中,你选择的是区间内的第一个时间戳(ts),另一种选择方式是 `\_wstart`,它将给出时间窗口的开始。关于窗口查询的更多信息,参见[特色查询](../../taos-sql/distinguished/)。
|
||||
|
|
|
@ -116,7 +116,7 @@ aggfn为函数名的占位符,需要修改为自己的函数名,如l2norm。
|
|||
|
||||
参数的具体含义是:
|
||||
- inputDataBlock: 输入的数据块
|
||||
- resultColumn: 输出列。输出列
|
||||
- resultColumn: 输出列
|
||||
|
||||
### 聚合接口函数
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
```java
|
||||
{{#include docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java}}
|
||||
{{#include docs/examples/java/src/main/java/com/taos/example/MetersDeserializer.java}}
|
||||
{{#include docs/examples/java/src/main/java/com/taos/example/Meters.java}}
|
||||
```
|
||||
```java
|
||||
{{#include docs/examples/java/src/main/java/com/taos/example/MetersDeserializer.java}}
|
||||
|
|
|
@ -23,10 +23,7 @@ create_subtable_clause: {
|
|||
}
|
||||
|
||||
create_definition:
|
||||
col_name column_definition
|
||||
|
||||
column_definition:
|
||||
type_name [comment 'string_value']
|
||||
col_name column_type
|
||||
|
||||
table_options:
|
||||
table_option ...
|
||||
|
|
|
@ -6,7 +6,8 @@ description: TDengine 保留关键字的详细列表
|
|||
|
||||
## 保留关键字
|
||||
|
||||
目前 TDengine 有将近 200 个内部保留关键字,这些关键字无论大小写均不可以用作库名、表名、STable 名、数据列名及标签列名等。这些关键字列表如下:
|
||||
目前 TDengine 有将近 200 个内部保留关键字,这些关键字无论大小写如果需要用作库名、表名、STable 名、数据列名及标签列名等,需要使用符合``将关键字括起来使用,例如`ADD`。
|
||||
关键字列表如下:
|
||||
|
||||
### A
|
||||
|
||||
|
@ -239,6 +240,7 @@ description: TDengine 保留关键字的详细列表
|
|||
- TOPICS
|
||||
- TRIGGER
|
||||
- TSERIES
|
||||
- TTL
|
||||
|
||||
### U
|
||||
|
||||
|
|
|
@ -6,11 +6,7 @@ description: TDengine 发布历史、Release Notes 及下载链接
|
|||
|
||||
import Release from "/components/ReleaseV3";
|
||||
|
||||
## 3.0.0.1
|
||||
## 3.0.1.0
|
||||
|
||||
<Release type="tdengine" version="3.0.0.1" />
|
||||
|
||||
<!-- ## 3.0.0.0
|
||||
|
||||
<Release type="tdengine" version="3.0.0.0" /> -->
|
||||
<Release type="tdengine" version="3.0.1.0" />
|
||||
|
||||
|
|
|
@ -6,6 +6,6 @@ description: taosTools 的发布历史、Release Notes 和下载链接
|
|||
|
||||
import Release from "/components/ReleaseV3";
|
||||
|
||||
## 2.1.2
|
||||
## 2.1.3
|
||||
|
||||
<Release type="tools" version="2.1.2" />
|
||||
<Release type="tools" version="2.1.3" />
|
||||
|
|
|
@ -65,13 +65,6 @@ typedef enum {
|
|||
TSDB_STATIS_NONE = 1, // statis part not exist
|
||||
} ETsdbStatisStatus;
|
||||
|
||||
typedef enum {
|
||||
TSDB_SMA_STAT_UNKNOWN = -1, // unknown
|
||||
TSDB_SMA_STAT_OK = 0, // ready to provide service
|
||||
TSDB_SMA_STAT_EXPIRED = 1, // not ready or expired
|
||||
TSDB_SMA_STAT_DROPPED = 2, // sma dropped
|
||||
} ETsdbSmaStat; // bit operation
|
||||
|
||||
typedef enum {
|
||||
TSDB_SMA_TYPE_BLOCK = 0, // Block-wise SMA
|
||||
TSDB_SMA_TYPE_TIME_RANGE = 1, // Time-range-wise SMA
|
||||
|
|
|
@ -184,7 +184,8 @@ static FORCE_INLINE void colDataAppendDouble(SColumnInfoData* pColumnInfoData, u
|
|||
int32_t getJsonValueLen(const char* data);
|
||||
|
||||
int32_t colDataAppend(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, bool isNull);
|
||||
int32_t colDataAppendNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, uint32_t numOfRows);
|
||||
int32_t colDataAppendNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData,
|
||||
uint32_t numOfRows);
|
||||
int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, int32_t* capacity,
|
||||
const SColumnInfoData* pSource, int32_t numOfRow2);
|
||||
int32_t colDataAssign(SColumnInfoData* pColumnInfoData, const SColumnInfoData* pSource, int32_t numOfRows,
|
||||
|
@ -225,15 +226,16 @@ size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize);
|
|||
int32_t blockDataTrimFirstNRows(SSDataBlock* pBlock, size_t n);
|
||||
int32_t blockDataKeepFirstNRows(SSDataBlock* pBlock, size_t n);
|
||||
|
||||
int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
||||
int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
||||
int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
||||
int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
||||
|
||||
SSDataBlock* createDataBlock();
|
||||
void* blockDataDestroy(SSDataBlock* pBlock);
|
||||
void blockDataFreeRes(SSDataBlock* pBlock);
|
||||
SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData);
|
||||
SSDataBlock* createSpecialDataBlock(EStreamType type);
|
||||
|
||||
int32_t blockDataAppendColInfo(SSDataBlock* pBlock, SColumnInfoData* pColInfoData);
|
||||
int32_t blockDataAppendColInfo(SSDataBlock* pBlock, SColumnInfoData* pColInfoData);
|
||||
|
||||
SColumnInfoData createColumnInfoData(int16_t type, int32_t bytes, int16_t colId);
|
||||
SColumnInfoData* bdGetColumnInfoData(const SSDataBlock* pBlock, int32_t index);
|
||||
|
@ -249,7 +251,6 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf);
|
|||
int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SSDataBlock* pDataBlocks, STSchema* pTSchema, int32_t vgId,
|
||||
tb_uid_t suid);
|
||||
|
||||
|
||||
char* buildCtbNameByGroupId(const char* stbName, uint64_t groupId);
|
||||
|
||||
static FORCE_INLINE int32_t blockGetEncodeSize(const SSDataBlock* pBlock) {
|
||||
|
|
|
@ -785,6 +785,8 @@ typedef struct {
|
|||
int32_t walRollPeriod;
|
||||
int64_t walSegmentSize;
|
||||
int32_t sstTrigger;
|
||||
int16_t hashPrefix;
|
||||
int16_t hashSuffix;
|
||||
} SCreateDbReq;
|
||||
|
||||
int32_t tSerializeSCreateDbReq(void* buf, int32_t bufLen, SCreateDbReq* pReq);
|
||||
|
@ -843,6 +845,8 @@ typedef struct {
|
|||
int64_t uid;
|
||||
int32_t vgVersion;
|
||||
int32_t vgNum;
|
||||
int16_t hashPrefix;
|
||||
int16_t hashSuffix;
|
||||
int8_t hashMethod;
|
||||
SArray* pVgroupInfos; // Array of SVgroupInfo
|
||||
} SUseDbRsp;
|
||||
|
@ -1068,6 +1072,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
int32_t vgId;
|
||||
int32_t syncState;
|
||||
int64_t cacheUsage;
|
||||
int64_t numOfTables;
|
||||
int64_t numOfTimeSeries;
|
||||
int64_t totalStorage;
|
||||
|
@ -1193,6 +1198,8 @@ typedef struct {
|
|||
int32_t walRollPeriod;
|
||||
int64_t walSegmentSize;
|
||||
int16_t sstTrigger;
|
||||
int16_t hashPrefix;
|
||||
int16_t hashSuffix;
|
||||
} SCreateVnodeReq;
|
||||
|
||||
int32_t tSerializeSCreateVnodeReq(void* buf, int32_t bufLen, SCreateVnodeReq* pReq);
|
||||
|
|
|
@ -272,6 +272,8 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_SYNC_LEADER_TRANSFER, "sync-leader-transfer", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_SYNC_SET_MNODE_STANDBY, "set-mnode-standby", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_SYNC_SET_VNODE_STANDBY, "set-vnode-standby", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_SYNC_HEARTBEAT, "sync-heartbeat", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_SYNC_HEARTBEAT_REPLY, "sync-heartbeat-reply", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_SYNC_MAX_MSG, "sync-max", NULL, NULL)
|
||||
|
||||
#if defined(TD_MSG_NUMBER_)
|
||||
|
|
|
@ -103,224 +103,226 @@
|
|||
#define TK_WAL_ROLL_PERIOD 85
|
||||
#define TK_WAL_SEGMENT_SIZE 86
|
||||
#define TK_SST_TRIGGER 87
|
||||
#define TK_NK_COLON 88
|
||||
#define TK_TABLE 89
|
||||
#define TK_NK_LP 90
|
||||
#define TK_NK_RP 91
|
||||
#define TK_STABLE 92
|
||||
#define TK_ADD 93
|
||||
#define TK_COLUMN 94
|
||||
#define TK_MODIFY 95
|
||||
#define TK_RENAME 96
|
||||
#define TK_TAG 97
|
||||
#define TK_SET 98
|
||||
#define TK_NK_EQ 99
|
||||
#define TK_USING 100
|
||||
#define TK_TAGS 101
|
||||
#define TK_COMMENT 102
|
||||
#define TK_BOOL 103
|
||||
#define TK_TINYINT 104
|
||||
#define TK_SMALLINT 105
|
||||
#define TK_INT 106
|
||||
#define TK_INTEGER 107
|
||||
#define TK_BIGINT 108
|
||||
#define TK_FLOAT 109
|
||||
#define TK_DOUBLE 110
|
||||
#define TK_BINARY 111
|
||||
#define TK_TIMESTAMP 112
|
||||
#define TK_NCHAR 113
|
||||
#define TK_UNSIGNED 114
|
||||
#define TK_JSON 115
|
||||
#define TK_VARCHAR 116
|
||||
#define TK_MEDIUMBLOB 117
|
||||
#define TK_BLOB 118
|
||||
#define TK_VARBINARY 119
|
||||
#define TK_DECIMAL 120
|
||||
#define TK_MAX_DELAY 121
|
||||
#define TK_WATERMARK 122
|
||||
#define TK_ROLLUP 123
|
||||
#define TK_TTL 124
|
||||
#define TK_SMA 125
|
||||
#define TK_FIRST 126
|
||||
#define TK_LAST 127
|
||||
#define TK_SHOW 128
|
||||
#define TK_DATABASES 129
|
||||
#define TK_TABLES 130
|
||||
#define TK_STABLES 131
|
||||
#define TK_MNODES 132
|
||||
#define TK_MODULES 133
|
||||
#define TK_QNODES 134
|
||||
#define TK_FUNCTIONS 135
|
||||
#define TK_INDEXES 136
|
||||
#define TK_ACCOUNTS 137
|
||||
#define TK_APPS 138
|
||||
#define TK_CONNECTIONS 139
|
||||
#define TK_LICENCES 140
|
||||
#define TK_GRANTS 141
|
||||
#define TK_QUERIES 142
|
||||
#define TK_SCORES 143
|
||||
#define TK_TOPICS 144
|
||||
#define TK_VARIABLES 145
|
||||
#define TK_BNODES 146
|
||||
#define TK_SNODES 147
|
||||
#define TK_CLUSTER 148
|
||||
#define TK_TRANSACTIONS 149
|
||||
#define TK_DISTRIBUTED 150
|
||||
#define TK_CONSUMERS 151
|
||||
#define TK_SUBSCRIPTIONS 152
|
||||
#define TK_VNODES 153
|
||||
#define TK_LIKE 154
|
||||
#define TK_INDEX 155
|
||||
#define TK_FUNCTION 156
|
||||
#define TK_INTERVAL 157
|
||||
#define TK_TOPIC 158
|
||||
#define TK_AS 159
|
||||
#define TK_WITH 160
|
||||
#define TK_META 161
|
||||
#define TK_CONSUMER 162
|
||||
#define TK_GROUP 163
|
||||
#define TK_DESC 164
|
||||
#define TK_DESCRIBE 165
|
||||
#define TK_RESET 166
|
||||
#define TK_QUERY 167
|
||||
#define TK_CACHE 168
|
||||
#define TK_EXPLAIN 169
|
||||
#define TK_ANALYZE 170
|
||||
#define TK_VERBOSE 171
|
||||
#define TK_NK_BOOL 172
|
||||
#define TK_RATIO 173
|
||||
#define TK_NK_FLOAT 174
|
||||
#define TK_OUTPUTTYPE 175
|
||||
#define TK_AGGREGATE 176
|
||||
#define TK_BUFSIZE 177
|
||||
#define TK_STREAM 178
|
||||
#define TK_INTO 179
|
||||
#define TK_TRIGGER 180
|
||||
#define TK_AT_ONCE 181
|
||||
#define TK_WINDOW_CLOSE 182
|
||||
#define TK_IGNORE 183
|
||||
#define TK_EXPIRED 184
|
||||
#define TK_KILL 185
|
||||
#define TK_CONNECTION 186
|
||||
#define TK_TRANSACTION 187
|
||||
#define TK_BALANCE 188
|
||||
#define TK_VGROUP 189
|
||||
#define TK_MERGE 190
|
||||
#define TK_REDISTRIBUTE 191
|
||||
#define TK_SPLIT 192
|
||||
#define TK_DELETE 193
|
||||
#define TK_INSERT 194
|
||||
#define TK_NULL 195
|
||||
#define TK_NK_QUESTION 196
|
||||
#define TK_NK_ARROW 197
|
||||
#define TK_ROWTS 198
|
||||
#define TK_TBNAME 199
|
||||
#define TK_QSTART 200
|
||||
#define TK_QEND 201
|
||||
#define TK_QDURATION 202
|
||||
#define TK_WSTART 203
|
||||
#define TK_WEND 204
|
||||
#define TK_WDURATION 205
|
||||
#define TK_CAST 206
|
||||
#define TK_NOW 207
|
||||
#define TK_TODAY 208
|
||||
#define TK_TIMEZONE 209
|
||||
#define TK_CLIENT_VERSION 210
|
||||
#define TK_SERVER_VERSION 211
|
||||
#define TK_SERVER_STATUS 212
|
||||
#define TK_CURRENT_USER 213
|
||||
#define TK_COUNT 214
|
||||
#define TK_LAST_ROW 215
|
||||
#define TK_BETWEEN 216
|
||||
#define TK_IS 217
|
||||
#define TK_NK_LT 218
|
||||
#define TK_NK_GT 219
|
||||
#define TK_NK_LE 220
|
||||
#define TK_NK_GE 221
|
||||
#define TK_NK_NE 222
|
||||
#define TK_MATCH 223
|
||||
#define TK_NMATCH 224
|
||||
#define TK_CONTAINS 225
|
||||
#define TK_IN 226
|
||||
#define TK_JOIN 227
|
||||
#define TK_INNER 228
|
||||
#define TK_SELECT 229
|
||||
#define TK_DISTINCT 230
|
||||
#define TK_WHERE 231
|
||||
#define TK_PARTITION 232
|
||||
#define TK_BY 233
|
||||
#define TK_SESSION 234
|
||||
#define TK_STATE_WINDOW 235
|
||||
#define TK_SLIDING 236
|
||||
#define TK_FILL 237
|
||||
#define TK_VALUE 238
|
||||
#define TK_NONE 239
|
||||
#define TK_PREV 240
|
||||
#define TK_LINEAR 241
|
||||
#define TK_NEXT 242
|
||||
#define TK_HAVING 243
|
||||
#define TK_RANGE 244
|
||||
#define TK_EVERY 245
|
||||
#define TK_ORDER 246
|
||||
#define TK_SLIMIT 247
|
||||
#define TK_SOFFSET 248
|
||||
#define TK_LIMIT 249
|
||||
#define TK_OFFSET 250
|
||||
#define TK_ASC 251
|
||||
#define TK_NULLS 252
|
||||
#define TK_ABORT 253
|
||||
#define TK_AFTER 254
|
||||
#define TK_ATTACH 255
|
||||
#define TK_BEFORE 256
|
||||
#define TK_BEGIN 257
|
||||
#define TK_BITAND 258
|
||||
#define TK_BITNOT 259
|
||||
#define TK_BITOR 260
|
||||
#define TK_BLOCKS 261
|
||||
#define TK_CHANGE 262
|
||||
#define TK_COMMA 263
|
||||
#define TK_COMPACT 264
|
||||
#define TK_CONCAT 265
|
||||
#define TK_CONFLICT 266
|
||||
#define TK_COPY 267
|
||||
#define TK_DEFERRED 268
|
||||
#define TK_DELIMITERS 269
|
||||
#define TK_DETACH 270
|
||||
#define TK_DIVIDE 271
|
||||
#define TK_DOT 272
|
||||
#define TK_EACH 273
|
||||
#define TK_END 274
|
||||
#define TK_FAIL 275
|
||||
#define TK_FILE 276
|
||||
#define TK_FOR 277
|
||||
#define TK_GLOB 278
|
||||
#define TK_ID 279
|
||||
#define TK_IMMEDIATE 280
|
||||
#define TK_IMPORT 281
|
||||
#define TK_INITIALLY 282
|
||||
#define TK_INSTEAD 283
|
||||
#define TK_ISNULL 284
|
||||
#define TK_KEY 285
|
||||
#define TK_NK_BITNOT 286
|
||||
#define TK_NK_SEMI 287
|
||||
#define TK_NOTNULL 288
|
||||
#define TK_OF 289
|
||||
#define TK_PLUS 290
|
||||
#define TK_PRIVILEGE 291
|
||||
#define TK_RAISE 292
|
||||
#define TK_REPLACE 293
|
||||
#define TK_RESTRICT 294
|
||||
#define TK_ROW 295
|
||||
#define TK_SEMI 296
|
||||
#define TK_STAR 297
|
||||
#define TK_STATEMENT 298
|
||||
#define TK_STRING 299
|
||||
#define TK_TIMES 300
|
||||
#define TK_UPDATE 301
|
||||
#define TK_VALUES 302
|
||||
#define TK_VARIABLE 303
|
||||
#define TK_VIEW 304
|
||||
#define TK_WAL 305
|
||||
#define TK_TABLE_PREFIX 88
|
||||
#define TK_TABLE_SUFFIX 89
|
||||
#define TK_NK_COLON 90
|
||||
#define TK_TABLE 91
|
||||
#define TK_NK_LP 92
|
||||
#define TK_NK_RP 93
|
||||
#define TK_STABLE 94
|
||||
#define TK_ADD 95
|
||||
#define TK_COLUMN 96
|
||||
#define TK_MODIFY 97
|
||||
#define TK_RENAME 98
|
||||
#define TK_TAG 99
|
||||
#define TK_SET 100
|
||||
#define TK_NK_EQ 101
|
||||
#define TK_USING 102
|
||||
#define TK_TAGS 103
|
||||
#define TK_COMMENT 104
|
||||
#define TK_BOOL 105
|
||||
#define TK_TINYINT 106
|
||||
#define TK_SMALLINT 107
|
||||
#define TK_INT 108
|
||||
#define TK_INTEGER 109
|
||||
#define TK_BIGINT 110
|
||||
#define TK_FLOAT 111
|
||||
#define TK_DOUBLE 112
|
||||
#define TK_BINARY 113
|
||||
#define TK_TIMESTAMP 114
|
||||
#define TK_NCHAR 115
|
||||
#define TK_UNSIGNED 116
|
||||
#define TK_JSON 117
|
||||
#define TK_VARCHAR 118
|
||||
#define TK_MEDIUMBLOB 119
|
||||
#define TK_BLOB 120
|
||||
#define TK_VARBINARY 121
|
||||
#define TK_DECIMAL 122
|
||||
#define TK_MAX_DELAY 123
|
||||
#define TK_WATERMARK 124
|
||||
#define TK_ROLLUP 125
|
||||
#define TK_TTL 126
|
||||
#define TK_SMA 127
|
||||
#define TK_FIRST 128
|
||||
#define TK_LAST 129
|
||||
#define TK_SHOW 130
|
||||
#define TK_DATABASES 131
|
||||
#define TK_TABLES 132
|
||||
#define TK_STABLES 133
|
||||
#define TK_MNODES 134
|
||||
#define TK_MODULES 135
|
||||
#define TK_QNODES 136
|
||||
#define TK_FUNCTIONS 137
|
||||
#define TK_INDEXES 138
|
||||
#define TK_ACCOUNTS 139
|
||||
#define TK_APPS 140
|
||||
#define TK_CONNECTIONS 141
|
||||
#define TK_LICENCES 142
|
||||
#define TK_GRANTS 143
|
||||
#define TK_QUERIES 144
|
||||
#define TK_SCORES 145
|
||||
#define TK_TOPICS 146
|
||||
#define TK_VARIABLES 147
|
||||
#define TK_BNODES 148
|
||||
#define TK_SNODES 149
|
||||
#define TK_CLUSTER 150
|
||||
#define TK_TRANSACTIONS 151
|
||||
#define TK_DISTRIBUTED 152
|
||||
#define TK_CONSUMERS 153
|
||||
#define TK_SUBSCRIPTIONS 154
|
||||
#define TK_VNODES 155
|
||||
#define TK_LIKE 156
|
||||
#define TK_INDEX 157
|
||||
#define TK_FUNCTION 158
|
||||
#define TK_INTERVAL 159
|
||||
#define TK_TOPIC 160
|
||||
#define TK_AS 161
|
||||
#define TK_WITH 162
|
||||
#define TK_META 163
|
||||
#define TK_CONSUMER 164
|
||||
#define TK_GROUP 165
|
||||
#define TK_DESC 166
|
||||
#define TK_DESCRIBE 167
|
||||
#define TK_RESET 168
|
||||
#define TK_QUERY 169
|
||||
#define TK_CACHE 170
|
||||
#define TK_EXPLAIN 171
|
||||
#define TK_ANALYZE 172
|
||||
#define TK_VERBOSE 173
|
||||
#define TK_NK_BOOL 174
|
||||
#define TK_RATIO 175
|
||||
#define TK_NK_FLOAT 176
|
||||
#define TK_OUTPUTTYPE 177
|
||||
#define TK_AGGREGATE 178
|
||||
#define TK_BUFSIZE 179
|
||||
#define TK_STREAM 180
|
||||
#define TK_INTO 181
|
||||
#define TK_TRIGGER 182
|
||||
#define TK_AT_ONCE 183
|
||||
#define TK_WINDOW_CLOSE 184
|
||||
#define TK_IGNORE 185
|
||||
#define TK_EXPIRED 186
|
||||
#define TK_KILL 187
|
||||
#define TK_CONNECTION 188
|
||||
#define TK_TRANSACTION 189
|
||||
#define TK_BALANCE 190
|
||||
#define TK_VGROUP 191
|
||||
#define TK_MERGE 192
|
||||
#define TK_REDISTRIBUTE 193
|
||||
#define TK_SPLIT 194
|
||||
#define TK_DELETE 195
|
||||
#define TK_INSERT 196
|
||||
#define TK_NULL 197
|
||||
#define TK_NK_QUESTION 198
|
||||
#define TK_NK_ARROW 199
|
||||
#define TK_ROWTS 200
|
||||
#define TK_TBNAME 201
|
||||
#define TK_QSTART 202
|
||||
#define TK_QEND 203
|
||||
#define TK_QDURATION 204
|
||||
#define TK_WSTART 205
|
||||
#define TK_WEND 206
|
||||
#define TK_WDURATION 207
|
||||
#define TK_CAST 208
|
||||
#define TK_NOW 209
|
||||
#define TK_TODAY 210
|
||||
#define TK_TIMEZONE 211
|
||||
#define TK_CLIENT_VERSION 212
|
||||
#define TK_SERVER_VERSION 213
|
||||
#define TK_SERVER_STATUS 214
|
||||
#define TK_CURRENT_USER 215
|
||||
#define TK_COUNT 216
|
||||
#define TK_LAST_ROW 217
|
||||
#define TK_BETWEEN 218
|
||||
#define TK_IS 219
|
||||
#define TK_NK_LT 220
|
||||
#define TK_NK_GT 221
|
||||
#define TK_NK_LE 222
|
||||
#define TK_NK_GE 223
|
||||
#define TK_NK_NE 224
|
||||
#define TK_MATCH 225
|
||||
#define TK_NMATCH 226
|
||||
#define TK_CONTAINS 227
|
||||
#define TK_IN 228
|
||||
#define TK_JOIN 229
|
||||
#define TK_INNER 230
|
||||
#define TK_SELECT 231
|
||||
#define TK_DISTINCT 232
|
||||
#define TK_WHERE 233
|
||||
#define TK_PARTITION 234
|
||||
#define TK_BY 235
|
||||
#define TK_SESSION 236
|
||||
#define TK_STATE_WINDOW 237
|
||||
#define TK_SLIDING 238
|
||||
#define TK_FILL 239
|
||||
#define TK_VALUE 240
|
||||
#define TK_NONE 241
|
||||
#define TK_PREV 242
|
||||
#define TK_LINEAR 243
|
||||
#define TK_NEXT 244
|
||||
#define TK_HAVING 245
|
||||
#define TK_RANGE 246
|
||||
#define TK_EVERY 247
|
||||
#define TK_ORDER 248
|
||||
#define TK_SLIMIT 249
|
||||
#define TK_SOFFSET 250
|
||||
#define TK_LIMIT 251
|
||||
#define TK_OFFSET 252
|
||||
#define TK_ASC 253
|
||||
#define TK_NULLS 254
|
||||
#define TK_ABORT 255
|
||||
#define TK_AFTER 256
|
||||
#define TK_ATTACH 257
|
||||
#define TK_BEFORE 258
|
||||
#define TK_BEGIN 259
|
||||
#define TK_BITAND 260
|
||||
#define TK_BITNOT 261
|
||||
#define TK_BITOR 262
|
||||
#define TK_BLOCKS 263
|
||||
#define TK_CHANGE 264
|
||||
#define TK_COMMA 265
|
||||
#define TK_COMPACT 266
|
||||
#define TK_CONCAT 267
|
||||
#define TK_CONFLICT 268
|
||||
#define TK_COPY 269
|
||||
#define TK_DEFERRED 270
|
||||
#define TK_DELIMITERS 271
|
||||
#define TK_DETACH 272
|
||||
#define TK_DIVIDE 273
|
||||
#define TK_DOT 274
|
||||
#define TK_EACH 275
|
||||
#define TK_END 276
|
||||
#define TK_FAIL 277
|
||||
#define TK_FILE 278
|
||||
#define TK_FOR 279
|
||||
#define TK_GLOB 280
|
||||
#define TK_ID 281
|
||||
#define TK_IMMEDIATE 282
|
||||
#define TK_IMPORT 283
|
||||
#define TK_INITIALLY 284
|
||||
#define TK_INSTEAD 285
|
||||
#define TK_ISNULL 286
|
||||
#define TK_KEY 287
|
||||
#define TK_NK_BITNOT 288
|
||||
#define TK_NK_SEMI 289
|
||||
#define TK_NOTNULL 290
|
||||
#define TK_OF 291
|
||||
#define TK_PLUS 292
|
||||
#define TK_PRIVILEGE 293
|
||||
#define TK_RAISE 294
|
||||
#define TK_REPLACE 295
|
||||
#define TK_RESTRICT 296
|
||||
#define TK_ROW 297
|
||||
#define TK_SEMI 298
|
||||
#define TK_STAR 299
|
||||
#define TK_STATEMENT 300
|
||||
#define TK_STRING 301
|
||||
#define TK_TIMES 302
|
||||
#define TK_UPDATE 303
|
||||
#define TK_VALUES 304
|
||||
#define TK_VARIABLE 305
|
||||
#define TK_VIEW 306
|
||||
#define TK_WAL 307
|
||||
|
||||
#define TK_NK_SPACE 300
|
||||
#define TK_NK_COMMENT 301
|
||||
|
|
|
@ -82,6 +82,8 @@ typedef struct SDatabaseOptions {
|
|||
bool walRetentionSizeIsSet;
|
||||
bool walRollPeriodIsSet;
|
||||
int32_t sstTrigger;
|
||||
int32_t tablePrefix;
|
||||
int32_t tableSuffix;
|
||||
} SDatabaseOptions;
|
||||
|
||||
typedef struct SCreateDatabaseStmt {
|
||||
|
|
|
@ -320,6 +320,9 @@ int32_t nodesStringToNode(const char* pStr, SNode** pNode);
|
|||
int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int32_t* pLen);
|
||||
int32_t nodesStringToList(const char* pStr, SNodeList** pList);
|
||||
|
||||
int32_t nodesNodeToMsg(const SNode* pNode, char** pMsg, int32_t* pLen);
|
||||
int32_t nodesMsgToNode(const char* pStr, int32_t len, SNode** pNode);
|
||||
|
||||
int32_t nodesNodeToSQL(SNode* pNode, char* buf, int32_t bufSize, int32_t* len);
|
||||
char* nodesGetNameFromColumnNode(SNode* pNode);
|
||||
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots);
|
||||
|
|
|
@ -116,6 +116,8 @@ typedef struct STableMeta {
|
|||
|
||||
typedef struct SDBVgInfo {
|
||||
int32_t vgVersion;
|
||||
int16_t hashPrefix;
|
||||
int16_t hashSuffix;
|
||||
int8_t hashMethod;
|
||||
int32_t numOfTable; // DB's table num, unit is TSDB_TABLE_NUM_UNIT
|
||||
SHashObj* vgHash; // key:vgId, value:SVgroupInfo
|
||||
|
|
|
@ -554,6 +554,8 @@ typedef struct {
|
|||
int32_t streamStatePut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen);
|
||||
int32_t streamStateGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateDel(SStreamState* pState, const SWinKey* key);
|
||||
int32_t streamStateAddIfNotExist(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateReleaseBuf(SStreamState* pState, const SWinKey* key, void* pVal);
|
||||
void streamFreeVal(void* val);
|
||||
|
||||
SStreamStateCur* streamStateGetCur(SStreamState* pState, const SWinKey* key);
|
||||
|
|
|
@ -444,6 +444,70 @@ void syncAppendEntriesReplyPrint2(char* s, const SyncAppendEntriesReply* pMsg);
|
|||
void syncAppendEntriesReplyLog(const SyncAppendEntriesReply* pMsg);
|
||||
void syncAppendEntriesReplyLog2(char* s, const SyncAppendEntriesReply* pMsg);
|
||||
|
||||
// ---------------------------------------------
|
||||
typedef struct SyncHeartbeat {
|
||||
uint32_t bytes;
|
||||
int32_t vgId;
|
||||
uint32_t msgType;
|
||||
SRaftId srcId;
|
||||
SRaftId destId;
|
||||
|
||||
// private data
|
||||
SyncTerm term;
|
||||
SyncIndex commitIndex;
|
||||
SyncTerm privateTerm;
|
||||
} SyncHeartbeat;
|
||||
|
||||
SyncHeartbeat* syncHeartbeatBuild(int32_t vgId);
|
||||
void syncHeartbeatDestroy(SyncHeartbeat* pMsg);
|
||||
void syncHeartbeatSerialize(const SyncHeartbeat* pMsg, char* buf, uint32_t bufLen);
|
||||
void syncHeartbeatDeserialize(const char* buf, uint32_t len, SyncHeartbeat* pMsg);
|
||||
char* syncHeartbeatSerialize2(const SyncHeartbeat* pMsg, uint32_t* len);
|
||||
SyncHeartbeat* syncHeartbeatDeserialize2(const char* buf, uint32_t len);
|
||||
void syncHeartbeat2RpcMsg(const SyncHeartbeat* pMsg, SRpcMsg* pRpcMsg);
|
||||
void syncHeartbeatFromRpcMsg(const SRpcMsg* pRpcMsg, SyncHeartbeat* pMsg);
|
||||
SyncHeartbeat* syncHeartbeatFromRpcMsg2(const SRpcMsg* pRpcMsg);
|
||||
cJSON* syncHeartbeat2Json(const SyncHeartbeat* pMsg);
|
||||
char* syncHeartbeat2Str(const SyncHeartbeat* pMsg);
|
||||
|
||||
// for debug ----------------------
|
||||
void syncHeartbeatPrint(const SyncHeartbeat* pMsg);
|
||||
void syncHeartbeatPrint2(char* s, const SyncHeartbeat* pMsg);
|
||||
void syncHeartbeatLog(const SyncHeartbeat* pMsg);
|
||||
void syncHeartbeatLog2(char* s, const SyncHeartbeat* pMsg);
|
||||
|
||||
// ---------------------------------------------
|
||||
typedef struct SyncHeartbeatReply {
|
||||
uint32_t bytes;
|
||||
int32_t vgId;
|
||||
uint32_t msgType;
|
||||
SRaftId srcId;
|
||||
SRaftId destId;
|
||||
|
||||
// private data
|
||||
SyncTerm term;
|
||||
SyncTerm privateTerm;
|
||||
int64_t startTime;
|
||||
} SyncHeartbeatReply;
|
||||
|
||||
SyncHeartbeatReply* syncHeartbeatReplyBuild(int32_t vgId);
|
||||
void syncHeartbeatReplyDestroy(SyncHeartbeatReply* pMsg);
|
||||
void syncHeartbeatReplySerialize(const SyncHeartbeatReply* pMsg, char* buf, uint32_t bufLen);
|
||||
void syncHeartbeatReplyDeserialize(const char* buf, uint32_t len, SyncHeartbeatReply* pMsg);
|
||||
char* syncHeartbeatReplySerialize2(const SyncHeartbeatReply* pMsg, uint32_t* len);
|
||||
SyncHeartbeatReply* syncHeartbeatReplyDeserialize2(const char* buf, uint32_t len);
|
||||
void syncHeartbeatReply2RpcMsg(const SyncHeartbeatReply* pMsg, SRpcMsg* pRpcMsg);
|
||||
void syncHeartbeatReplyFromRpcMsg(const SRpcMsg* pRpcMsg, SyncHeartbeatReply* pMsg);
|
||||
SyncHeartbeatReply* syncHeartbeatReplyFromRpcMsg2(const SRpcMsg* pRpcMsg);
|
||||
cJSON* syncHeartbeatReply2Json(const SyncHeartbeatReply* pMsg);
|
||||
char* syncHeartbeatReply2Str(const SyncHeartbeatReply* pMsg);
|
||||
|
||||
// for debug ----------------------
|
||||
void syncHeartbeatReplyPrint(const SyncHeartbeatReply* pMsg);
|
||||
void syncHeartbeatReplyPrint2(char* s, const SyncHeartbeatReply* pMsg);
|
||||
void syncHeartbeatReplyLog(const SyncHeartbeatReply* pMsg);
|
||||
void syncHeartbeatReplyLog2(char* s, const SyncHeartbeatReply* pMsg);
|
||||
|
||||
// ---------------------------------------------
|
||||
typedef struct SyncApplyMsg {
|
||||
uint32_t bytes;
|
||||
|
|
|
@ -616,6 +616,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_RSMA_FETCH_MSG_MSSED_UP TAOS_DEF_ERROR_CODE(0, 0x3155)
|
||||
#define TSDB_CODE_RSMA_EMPTY_INFO TAOS_DEF_ERROR_CODE(0, 0x3156)
|
||||
#define TSDB_CODE_RSMA_INVALID_SCHEMA TAOS_DEF_ERROR_CODE(0, 0x3157)
|
||||
#define TSDB_CODE_RSMA_REGEX_MATCH TAOS_DEF_ERROR_CODE(0, 0x3158)
|
||||
|
||||
//index
|
||||
#define TSDB_CODE_INDEX_REBUILDING TAOS_DEF_ERROR_CODE(0, 0x3200)
|
||||
|
|
|
@ -359,9 +359,15 @@ typedef enum ELogicConditionType {
|
|||
#define TSDB_DB_SCHEMALESS_ON 1
|
||||
#define TSDB_DB_SCHEMALESS_OFF 0
|
||||
#define TSDB_DEFAULT_DB_SCHEMALESS TSDB_DB_SCHEMALESS_OFF
|
||||
#define TSDB_MIN_SST_TRIGGER 1
|
||||
#define TSDB_MAX_SST_TRIGGER 128
|
||||
#define TSDB_MIN_STT_TRIGGER 1
|
||||
#define TSDB_MAX_STT_TRIGGER 16
|
||||
#define TSDB_DEFAULT_SST_TRIGGER 8
|
||||
#define TSDB_MIN_HASH_PREFIX 0
|
||||
#define TSDB_MAX_HASH_PREFIX 128
|
||||
#define TSDB_DEFAULT_HASH_PREFIX 0
|
||||
#define TSDB_MIN_HASH_SUFFIX 0
|
||||
#define TSDB_MAX_HASH_SUFFIX 128
|
||||
#define TSDB_DEFAULT_HASH_SUFFIX 0
|
||||
|
||||
#define TSDB_DB_MIN_WAL_RETENTION_PERIOD -1
|
||||
#define TSDB_REP_DEF_DB_WAL_RET_PERIOD 0
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_UTIL_RBTREE_H_
|
||||
#define _TD_UTIL_RBTREE_H_
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SRBTree SRBTree;
|
||||
typedef struct SRBTreeNode SRBTreeNode;
|
||||
typedef struct SRBTreeIter SRBTreeIter;
|
||||
|
||||
typedef int32_t (*tRBTreeCmprFn)(const void *, const void *);
|
||||
|
||||
// SRBTree =============================================
|
||||
#define tRBTreeMin(T) ((T)->min == ((T)->NIL) ? NULL : (T)->min)
|
||||
#define tRBTreeMax(T) ((T)->max == ((T)->NIL) ? NULL : (T)->max)
|
||||
|
||||
void tRBTreeCreate(SRBTree *pTree, tRBTreeCmprFn cmprFn);
|
||||
SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *z);
|
||||
void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *z);
|
||||
SRBTreeNode *tRBTreeDropByKey(SRBTree *pTree, void *pKey);
|
||||
SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey);
|
||||
|
||||
// SRBTreeIter =============================================
|
||||
#define tRBTreeIterCreate(tree, ascend) \
|
||||
(SRBTreeIter) { .asc = (ascend), .pTree = (tree), .pNode = (ascend) ? (tree)->min : (tree)->max }
|
||||
|
||||
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter);
|
||||
|
||||
// STRUCT =============================================
|
||||
typedef enum { RED, BLACK } ECOLOR;
|
||||
struct SRBTreeNode {
|
||||
ECOLOR color;
|
||||
SRBTreeNode *parent;
|
||||
SRBTreeNode *left;
|
||||
SRBTreeNode *right;
|
||||
};
|
||||
|
||||
#define RBTREE_NODE_PAYLOAD(N) ((const void *)&(N)[1])
|
||||
|
||||
struct SRBTree {
|
||||
tRBTreeCmprFn cmprFn;
|
||||
int64_t n;
|
||||
SRBTreeNode *root;
|
||||
SRBTreeNode *min;
|
||||
SRBTreeNode *max;
|
||||
SRBTreeNode *NIL;
|
||||
SRBTreeNode NILNODE;
|
||||
};
|
||||
|
||||
struct SRBTreeIter {
|
||||
int8_t asc;
|
||||
SRBTree *pTree;
|
||||
SRBTreeNode *pNode;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_UTIL_RBTREE_H_*/
|
|
@ -20,6 +20,7 @@
|
|||
#include "tcrc32c.h"
|
||||
#include "tdef.h"
|
||||
#include "tmd5.h"
|
||||
#include "thash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -68,6 +69,19 @@ static FORCE_INLINE void taosEncryptPass_c(uint8_t *inBuf, size_t len, char *tar
|
|||
memcpy(target, buf, TSDB_PASSWORD_LEN);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t taosGetTbHashVal(const char *tbname, int32_t tblen, int32_t method, int32_t prefix,
|
||||
int32_t suffix) {
|
||||
if (prefix == 0 && suffix == 0) {
|
||||
return MurmurHash3_32(tbname, tblen);
|
||||
} else {
|
||||
if (tblen <= (prefix + suffix)) {
|
||||
return MurmurHash3_32(tbname, tblen);
|
||||
} else {
|
||||
return MurmurHash3_32(tbname + prefix, tblen - prefix - suffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -5,13 +5,6 @@ def sync_source(branch_name) {
|
|||
echo ''' + branch_name + '''
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDINTERNAL_ROOT_DIR}
|
||||
git reset --hard
|
||||
git fetch || git fetch
|
||||
git checkout ''' + branch_name + ''' -f
|
||||
git branch
|
||||
git pull || git pull
|
||||
git log | head -n 20
|
||||
cd ${TDENGINE_ROOT_DIR}
|
||||
git reset --hard
|
||||
git fetch || git fetch
|
||||
|
@ -64,17 +57,12 @@ pipeline {
|
|||
defaultValue:'2.1.2',
|
||||
description: 'This number of baseVerison is generally not modified.Now it is 3.0.0.1'
|
||||
)
|
||||
string (
|
||||
name:'nasPassword',
|
||||
defaultValue:'password',
|
||||
description: 'the pasword of the NAS server which has installPackage-192.168.1.131'
|
||||
)
|
||||
}
|
||||
environment{
|
||||
WORK_DIR = '/var/lib/jenkins/workspace'
|
||||
TDINTERNAL_ROOT_DIR = '/var/lib/jenkins/workspace/TDinternal'
|
||||
TDENGINE_ROOT_DIR = '/var/lib/jenkins/workspace/TDinternal/community'
|
||||
BRANCH_NAME = '3.0'
|
||||
BRANCH_NAME = 'test/chr/TD-14699'
|
||||
|
||||
TD_SERVER_TAR = "TDengine-server-${version}-Linux-x64.tar.gz"
|
||||
BASE_TD_SERVER_TAR = "TDengine-server-${baseVersion}-Linux-x64.tar.gz"
|
||||
|
@ -107,7 +95,7 @@ pipeline {
|
|||
|
||||
}
|
||||
stages {
|
||||
stage ('RUN') {
|
||||
stage ('Test Server') {
|
||||
parallel {
|
||||
stage('ubuntu16') {
|
||||
agent{label " ubuntu16 "}
|
||||
|
@ -116,17 +104,17 @@ pipeline {
|
|||
sync_source("${BRANCH_NAME}")
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_TAR} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_TAR} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_LITE_TAR} ${version} ${BASE_TD_SERVER_LITE_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_LITE_TAR} ${version} ${BASE_TD_SERVER_LITE_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_DEB} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_DEB} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
}
|
||||
|
@ -139,24 +127,21 @@ pipeline {
|
|||
sync_source("${BRANCH_NAME}")
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_TAR} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_TAR} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_LITE_TAR} ${version} ${BASE_TD_SERVER_LITE_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_LITE_TAR} ${version} ${BASE_TD_SERVER_LITE_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_DEB} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server ${nasPassword}
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_CLIENT_TAR} ${version} ${BASE_TD_CLIENT_TAR} ${baseVersion} client ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_DEB} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
dpkg -r tdengine
|
||||
'''
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,17 +152,17 @@ pipeline {
|
|||
sync_source("${BRANCH_NAME}")
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_TAR} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_TAR} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_LITE_TAR} ${version} ${BASE_TD_SERVER_LITE_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_LITE_TAR} ${version} ${BASE_TD_SERVER_LITE_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_RPM} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_RPM} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
}
|
||||
|
@ -190,28 +175,23 @@ pipeline {
|
|||
sync_source("${BRANCH_NAME}")
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_TAR} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_TAR} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_LITE_TAR} ${version} ${BASE_TD_SERVER_LITE_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_LITE_TAR} ${version} ${BASE_TD_SERVER_LITE_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_RPM} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_RPM} ${version} ${BASE_TD_SERVER_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_CLIENT_LITE_TAR} ${version} ${BASE_TD_CLIENT_LITE_TAR} ${baseVersion} client ${nasPassword}
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sudo rpm -e tdengine
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
stage('arm64') {
|
||||
agent{label 'linux_arm64'}
|
||||
steps {
|
||||
|
@ -219,18 +199,53 @@ pipeline {
|
|||
sync_source("${BRANCH_NAME}")
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_SERVER_ARM_TAR} ${version} ${BASE_TD_SERVER_ARM_TAR} ${baseVersion} server ${nasPassword}
|
||||
bash testpackage.sh ${TD_SERVER_ARM_TAR} ${version} ${BASE_TD_SERVER_ARM_TAR} ${baseVersion} server
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_CLIENT_ARM_TAR} ${version} ${BASE_TD_CLIENT_ARM_TAR} ${baseVersion} client ${nasPassword}
|
||||
python3 checkPackageRuning.py
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ('Test Client') {
|
||||
parallel {
|
||||
stage('ubuntu18') {
|
||||
agent{label " ubuntu18 "}
|
||||
steps {
|
||||
timeout(time: 30, unit: 'MINUTES'){
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_CLIENT_TAR} ${version} ${BASE_TD_CLIENT_TAR} ${baseVersion} client
|
||||
python3 checkPackageRuning.py 192.168.0.21
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('centos8') {
|
||||
agent{label " centos8_3 "}
|
||||
steps {
|
||||
timeout(time: 30, unit: 'MINUTES'){
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_CLIENT_LITE_TAR} ${version} ${BASE_TD_CLIENT_LITE_TAR} ${baseVersion} client
|
||||
python3 checkPackageRuning.py 192.168.0.24
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('arm64-client') {
|
||||
agent{label " linux_arm64 "}
|
||||
steps {
|
||||
timeout(time: 30, unit: 'MINUTES'){
|
||||
sh '''
|
||||
cd ${TDENGINE_ROOT_DIR}/packaging
|
||||
bash testpackage.sh ${TD_CLIENT_ARM_TAR} ${version} ${BASE_TD_CLIENT_ARM_TAR} ${baseVersion} client
|
||||
python3 checkPackageRuning.py 192.168.0.21
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,12 +19,19 @@ import subprocess
|
|||
# from this import d
|
||||
import time
|
||||
|
||||
|
||||
if( len(sys.argv)>1 ):
|
||||
serverHost=sys.argv[1]
|
||||
else:
|
||||
serverHost="localhost"
|
||||
|
||||
|
||||
# install taospy
|
||||
|
||||
out = subprocess.getoutput("pip3 show taospy|grep Version| awk -F ':' '{print $2}' ")
|
||||
print("taospy version %s "%out)
|
||||
if (out == "" ):
|
||||
os.system("pip install git+https://github.com/taosdata/taos-connector-python.git")
|
||||
os.system("pip3 install git+https://github.com/taosdata/taos-connector-python.git")
|
||||
print("install taos python connector")
|
||||
else:
|
||||
os.system("pip3 install --upgrade taospy ")
|
||||
|
@ -32,19 +39,19 @@ else:
|
|||
|
||||
|
||||
# start taosd prepare
|
||||
os.system("rm -rf /var/lib/taos/*")
|
||||
os.system("systemctl restart taosd ")
|
||||
# os.system("rm -rf /var/lib/taos/*")
|
||||
# os.system("systemctl restart taosd ")
|
||||
|
||||
# wait a moment ,at least 5 seconds
|
||||
time.sleep(5)
|
||||
|
||||
# prepare data by taosBenchmark
|
||||
|
||||
os.system("taosBenchmark -y -n 100 -t 100")
|
||||
os.system("taosBenchmark -y -n 100 -t 100 -h %s "%serverHost )
|
||||
|
||||
import taos
|
||||
|
||||
conn = taos.connect(host="localhost",
|
||||
conn = taos.connect(host="%s"%serverHost,
|
||||
user="root",
|
||||
password="taosdata",
|
||||
database="test",
|
||||
|
@ -80,15 +87,15 @@ os.system("rm -rf /tmp/dumpdata/*")
|
|||
# dump data out
|
||||
print("taosdump dump out data")
|
||||
|
||||
os.system("taosdump -o /tmp/dumpdata -D test -y ")
|
||||
os.system("taosdump -o /tmp/dumpdata -D test -y -h %s "%serverHost)
|
||||
|
||||
# drop database of test
|
||||
print("drop database test")
|
||||
os.system(" taos -s ' drop database test ;' ")
|
||||
os.system(" taos -s ' drop database test ;' -h %s "%serverHost)
|
||||
|
||||
# dump data in
|
||||
print("taosdump dump data in")
|
||||
os.system("taosdump -i /tmp/dumpdata -y ")
|
||||
os.system("taosdump -i /tmp/dumpdata -y -h %s "%serverHost)
|
||||
|
||||
result = conn.query("SELECT count(*) from test.meters")
|
||||
|
||||
|
|
|
@ -11,3 +11,5 @@ expect "*one:"
|
|||
send "\r"
|
||||
expect "*skip:"
|
||||
send "\r"
|
||||
|
||||
expect eof
|
|
@ -7,7 +7,6 @@ originPackageName=$3
|
|||
originversion=$4
|
||||
testFile=$5
|
||||
subFile="taos.tar.gz"
|
||||
password=$6
|
||||
|
||||
# Color setting
|
||||
RED='\033[41;30m'
|
||||
|
@ -68,11 +67,37 @@ fi
|
|||
}
|
||||
|
||||
|
||||
function wgetFile {
|
||||
|
||||
file=$1
|
||||
|
||||
if [ ! -f ${file} ];then
|
||||
echoColor BD "wget https://www.taosdata.com/assets-download/3.0/${file}"
|
||||
wget https://www.taosdata.com/assets-download/3.0/${file}
|
||||
else
|
||||
echoColor YD "${file} already exists "
|
||||
fi
|
||||
}
|
||||
|
||||
function newPath {
|
||||
|
||||
buildPath=$1
|
||||
|
||||
if [ ! -d ${buildPath} ] ;then
|
||||
echoColor BD "mkdir -p ${buildPath}"
|
||||
mkdir -p ${buildPath}
|
||||
else
|
||||
echoColor YD "${buildPath} already exists"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
echoColor G "===== install basesoft ====="
|
||||
|
||||
cmdInstall tree
|
||||
cmdInstall wget
|
||||
cmdInstall sshpass
|
||||
cmdInstall expect
|
||||
|
||||
echoColor G "===== Uninstall all components of TDeingne ====="
|
||||
|
||||
|
@ -97,11 +122,14 @@ echoColor G "===== new workroom path ====="
|
|||
installPath="/usr/local/src/packageTest"
|
||||
oriInstallPath="/usr/local/src/packageTest/3.1"
|
||||
|
||||
if [ ! -d ${installPath} ] ;then
|
||||
echoColor BD "mkdir -p ${installPath}"
|
||||
mkdir -p ${installPath}
|
||||
else
|
||||
echoColor YD "${installPath} already exists"
|
||||
newPath ${installPath}
|
||||
|
||||
newPath ${oriInstallPath}
|
||||
|
||||
|
||||
if [ -d ${oriInstallPath}/${originTdpPath} ] ;then
|
||||
echoColor BD "rm -rf ${oriInstallPath}/${originTdpPath}/*"
|
||||
rm -rf ${oriInstallPath}/${originTdpPath}/*
|
||||
fi
|
||||
|
||||
if [ -d ${installPath}/${tdPath} ] ;then
|
||||
|
@ -109,33 +137,13 @@ if [ -d ${installPath}/${tdPath} ] ;then
|
|||
rm -rf ${installPath}/${tdPath}/*
|
||||
fi
|
||||
|
||||
if [ ! -d ${oriInstallPath} ] ;then
|
||||
echoColor BD "mkdir -p ${oriInstallPath}"
|
||||
mkdir -p ${oriInstallPath}
|
||||
else
|
||||
echoColor YD "${oriInstallPath} already exists"
|
||||
fi
|
||||
|
||||
if [ -d ${oriInstallPath}/${originTdpPath} ] ;then
|
||||
echoColor BD "rm -rf ${oriInstallPath}/${originTdpPath}/*"
|
||||
rm -rf ${oriInstallPath}/${originTdpPath}/*
|
||||
fi
|
||||
|
||||
|
||||
echoColor G "===== download installPackage ====="
|
||||
# cd ${installPath}
|
||||
# wget https://www.taosdata.com/assets-download/3.0/${packgeName}
|
||||
# cd ${oriInstallPath}
|
||||
# wget https://www.taosdata.com/assets-download/3.0/${originPackageName}
|
||||
cd ${installPath} && wgetFile ${packgeName}
|
||||
cd ${oriInstallPath} && wgetFile ${originPackageName}
|
||||
|
||||
cd ${installPath}
|
||||
cp -r ${scriptDir}/debRpmAutoInstall.sh .
|
||||
|
||||
if [ ! -f {packgeName} ];then
|
||||
echoColor BD "sshpass -p ${password} scp -oStrictHostKeyChecking=no 192.168.1.131:/nas/TDengine3/v${version}/community/${packgeName} ."
|
||||
sshpass -p ${password} scp -oStrictHostKeyChecking=no -oStrictHostKeyChecking=no 192.168.1.131:/nas/TDengine3/v${version}/community/${packgeName} .
|
||||
fi
|
||||
|
||||
packageSuffix=$(echo ${packgeName} | awk -F '.' '{print $NF}')
|
||||
|
||||
|
||||
|
@ -181,8 +189,7 @@ elif [[ ${packgeName} =~ "tar" ]];then
|
|||
cd ${oriInstallPath}
|
||||
if [ ! -f {originPackageName} ];then
|
||||
echoColor YD "download base installPackage"
|
||||
echoColor BD "sshpass -p ${password} scp -oStrictHostKeyChecking=no 192.168.1.131:/nas/TDengine3/v${originversion}/community/${originPackageName} ."
|
||||
sshpass -p ${password} scp -oStrictHostKeyChecking=no 192.168.1.131:/nas/TDengine3/v${originversion}/community/${originPackageName} .
|
||||
wgetFile ${originPackageName}
|
||||
fi
|
||||
echoColor YD "unzip the base installation package"
|
||||
echoColor BD "tar -xf ${originPackageName}" && tar -xf ${originPackageName}
|
||||
|
@ -222,24 +229,45 @@ fi
|
|||
|
||||
cd ${installPath}
|
||||
|
||||
if ([[ ${packgeName} =~ "Lite" ]] && [[ ${packgeName} =~ "tar" ]]) || [[ ${packgeName} =~ "client" ]] ;then
|
||||
if [[ ${packgeName} =~ "Lite" ]] || ([[ ${packgeName} =~ "x64" ]] && [[ ${packgeName} =~ "client" ]]) || ([[ ${packgeName} =~ "deb" ]] && [[ ${packgeName} =~ "server" ]]) || ([[ ${packgeName} =~ "rpm" ]] && [[ ${packgeName} =~ "server" ]]) ;then
|
||||
echoColor G "===== install taos-tools when package is lite or client ====="
|
||||
cd ${installPath}
|
||||
sshpass -p ${password} scp -oStrictHostKeyChecking=no 192.168.1.131:/nas/TDengine3/v${version}/community/taosTools-2.1.2-Linux-x64.tar.gz .
|
||||
# wget https://www.taosdata.com/assets-download/3.0/taosTools-2.1.2-Linux-x64.tar.gz
|
||||
tar xf taosTools-2.1.2-Linux-x64.tar.gz
|
||||
cd taosTools-2.1.2 && bash install-taostools.sh
|
||||
elif [[ ${packgeName} =~ "Lite" ]] && [[ ${packgeName} =~ "deb" ]] ;then
|
||||
echoColor G "===== install taos-tools when package is lite or client ====="
|
||||
wgetFile taosTools-2.1.3-Linux-x64.tar.gz .
|
||||
tar xf taosTools-2.1.3-Linux-x64.tar.gz
|
||||
cd taosTools-2.1.3 && bash install-taostools.sh
|
||||
elif ([[ ${packgeName} =~ "arm64" ]] && [[ ${packgeName} =~ "client" ]]);then
|
||||
echoColor G "===== install taos-tools arm when package is arm64-client ====="
|
||||
cd ${installPath}
|
||||
sshpass -p ${password} scp -oStrictHostKeyChecking=no 192.168.1.131:/nas/TDengine3/v${version}/community/taosTools-2.1.2-Linux-x64.tar.gz .
|
||||
tar xf taosTools-2.1.2-Linux-x64.tar.gz
|
||||
cd taosTools-2.1.2 && bash install-taostools.sh
|
||||
elif [[ ${packgeName} =~ "Lite" ]] && [[ ${packgeName} =~ "rpm" ]] ;then
|
||||
echoColor G "===== install taos-tools when package is lite or client ====="
|
||||
cd ${installPath}
|
||||
sshpass -p ${password} scp -oStrictHostKeyChecking=no -oStrictHostKeyChecking=no 192.168.1.131:/nas/TDengine3/v${version}/community/taosTools-2.1.2-Linux-x64.tar.gz .
|
||||
tar xf taosTools-2.1.2-Linux-x64.tar.gz
|
||||
cd taosTools-2.1.2 && bash install-taostools.sh
|
||||
wgetFile taosTools-2.1.3-Linux-arm64.tar.gz .
|
||||
tar xf taosTools-2.1.3-Linux-arm64.tar.gz
|
||||
cd taosTools-2.1.3 && bash install-taostools.sh
|
||||
fi
|
||||
|
||||
echoColor G "===== start TDengine ====="
|
||||
|
||||
if [[ ${packgeName} =~ "server" ]] ;then
|
||||
echoColor BD " rm -rf /var/lib/taos/* && systemctl restart taosd "
|
||||
rm -rf /var/lib/taos/*
|
||||
systemctl restart taosd
|
||||
fi
|
||||
|
||||
# if ([[ ${packgeName} =~ "Lite" ]] && [[ ${packgeName} =~ "tar" ]]) || [[ ${packgeName} =~ "client" ]] ;then
|
||||
# echoColor G "===== install taos-tools when package is lite or client ====="
|
||||
# cd ${installPath}
|
||||
# wgetFile taosTools-2.1.2-Linux-x64.tar.gz .
|
||||
# tar xf taosTools-2.1.2-Linux-x64.tar.gz
|
||||
# cd taosTools-2.1.2 && bash install-taostools.sh
|
||||
# elif [[ ${packgeName} =~ "Lite" ]] && [[ ${packgeName} =~ "deb" ]] ;then
|
||||
# echoColor G "===== install taos-tools when package is lite or client ====="
|
||||
# cd ${installPath}
|
||||
# wgetFile taosTools-2.1.2-Linux-x64.tar.gz .
|
||||
# tar xf taosTools-2.1.2-Linux-x64.tar.gz
|
||||
# cd taosTools-2.1.2 && bash install-taostools.sh
|
||||
# elif [[ ${packgeName} =~ "Lite" ]] && [[ ${packgeName} =~ "rpm" ]] ;then
|
||||
# echoColor G "===== install taos-tools when package is lite or client ====="
|
||||
# cd ${installPath}
|
||||
# wgetFile taosTools-2.1.2-Linux-x64.tar.gz .
|
||||
# tar xf taosTools-2.1.2-Linux-x64.tar.gz
|
||||
# cd taosTools-2.1.2 && bash install-taostools.sh
|
||||
# fi
|
||||
|
||||
|
|
|
@ -488,7 +488,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) {
|
|||
*/
|
||||
uint64_t generateRequestId() {
|
||||
static uint64_t hashId = 0;
|
||||
static int32_t requestSerialId = 0;
|
||||
static uint32_t requestSerialId = 0;
|
||||
|
||||
if (hashId == 0) {
|
||||
char uid[64] = {0};
|
||||
|
@ -507,7 +507,8 @@ uint64_t generateRequestId() {
|
|||
while (true) {
|
||||
int64_t ts = taosGetTimestampMs();
|
||||
uint64_t pid = taosGetPId();
|
||||
int32_t val = atomic_add_fetch_32(&requestSerialId, 1);
|
||||
uint32_t val = atomic_add_fetch_32(&requestSerialId, 1);
|
||||
if (val >= 0xFFFF) atomic_store_32(&requestSerialId, 0);
|
||||
|
||||
id = ((hashId & 0x0FFF) << 52) | ((pid & 0x0FFF) << 40) | ((ts & 0xFFFFFF) << 16) | (val & 0xFFFF);
|
||||
if (id) {
|
||||
|
|
|
@ -73,6 +73,8 @@ static int32_t hbProcessDBInfoRsp(void *value, int32_t valueLen, struct SCatalog
|
|||
|
||||
vgInfo->vgVersion = rsp->vgVersion;
|
||||
vgInfo->hashMethod = rsp->hashMethod;
|
||||
vgInfo->hashPrefix = rsp->hashPrefix;
|
||||
vgInfo->hashSuffix = rsp->hashSuffix;
|
||||
vgInfo->vgHash = taosHashInit(rsp->vgNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
if (NULL == vgInfo->vgHash) {
|
||||
taosMemoryFree(vgInfo);
|
||||
|
|
|
@ -1672,7 +1672,12 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo, int32_t numOfCols, int
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!needConvert) return TSDB_CODE_SUCCESS;
|
||||
|
||||
if (!needConvert) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tscDebug("start to convert form json format string");
|
||||
|
||||
char* p = (char*)pResultInfo->pData;
|
||||
int32_t dataLen = estimateJsonLen(pResultInfo, numOfCols, numOfRows);
|
||||
|
|
|
@ -767,22 +767,23 @@ static int32_t taosCreateTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
|
||||
pCreateReq->flags |= TD_CREATE_IF_NOT_EXISTS;
|
||||
// change tag cid to new cid
|
||||
if(pCreateReq->type == TSDB_CHILD_TABLE){
|
||||
if (pCreateReq->type == TSDB_CHILD_TABLE) {
|
||||
STableMeta* pTableMeta = NULL;
|
||||
SName sName = {0};
|
||||
toName(pTscObj->acctId, pRequest->pDb, pCreateReq->ctb.name, &sName);
|
||||
code = catalogGetTableMeta(pCatalog, &conn, &sName, &pTableMeta);
|
||||
if(code != TSDB_CODE_SUCCESS){
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
uError("taosCreateTable:catalogGetTableMeta failed. table name: %s", pCreateReq->ctb.name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < taosArrayGetSize(pCreateReq->ctb.tagName); i++){
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pCreateReq->ctb.tagName); i++) {
|
||||
char* tName = taosArrayGet(pCreateReq->ctb.tagName, i);
|
||||
for(int32_t j = pTableMeta->tableInfo.numOfColumns; j < pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags; j++){
|
||||
SSchema *tag = &pTableMeta->schema[j];
|
||||
if(strcmp(tag->name, tName) == 0 && tag->type != TSDB_DATA_TYPE_JSON){
|
||||
tTagSetCid((STag *)pCreateReq->ctb.pTag, i, tag->colId);
|
||||
for (int32_t j = pTableMeta->tableInfo.numOfColumns;
|
||||
j < pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags; j++) {
|
||||
SSchema* tag = &pTableMeta->schema[j];
|
||||
if (strcmp(tag->name, tName) == 0 && tag->type != TSDB_DATA_TYPE_JSON) {
|
||||
tTagSetCid((STag*)pCreateReq->ctb.pTag, i, tag->colId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1323,12 +1324,12 @@ end:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t tmqWriteRaw(TAOS* taos, void* data, int32_t dataLen) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SHashObj* pVgHash = NULL;
|
||||
SQuery* pQuery = NULL;
|
||||
SMqRspObj rspObj = {0};
|
||||
SDecoder decoder = {0};
|
||||
static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SHashObj* pVgHash = NULL;
|
||||
SQuery* pQuery = NULL;
|
||||
SMqRspObj rspObj = {0};
|
||||
SDecoder decoder = {0};
|
||||
STableMeta* pTableMeta = NULL;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
@ -1406,7 +1407,7 @@ static int32_t tmqWriteRaw(TAOS* taos, void* data, int32_t dataLen) {
|
|||
}
|
||||
|
||||
code = catalogGetTableMeta(pCatalog, &conn, &pName, &pTableMeta);
|
||||
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST){
|
||||
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
|
||||
uError("WriteRaw:catalogGetTableMeta table not exist. table name: %s", tbName);
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
continue;
|
||||
|
@ -1467,7 +1468,7 @@ static int32_t tmqWriteRaw(TAOS* taos, void* data, int32_t dataLen) {
|
|||
}
|
||||
|
||||
// pSW->pSchema should be same as pTableMeta->schema
|
||||
// ASSERT(pSW->nCols == pTableMeta->tableInfo.numOfColumns);
|
||||
// ASSERT(pSW->nCols == pTableMeta->tableInfo.numOfColumns);
|
||||
uint64_t suid = (TSDB_NORMAL_TABLE == pTableMeta->tableType ? 0 : pTableMeta->suid);
|
||||
uint64_t uid = pTableMeta->uid;
|
||||
int16_t sver = pTableMeta->sversion;
|
||||
|
@ -1495,10 +1496,10 @@ static int32_t tmqWriteRaw(TAOS* taos, void* data, int32_t dataLen) {
|
|||
int32_t offset = 0;
|
||||
for (int32_t k = 0; k < pTableMeta->tableInfo.numOfColumns; k++) {
|
||||
const SSchema* pColumn = &pTableMeta->schema[k];
|
||||
int32_t* index = taosHashGet(schemaHash, pColumn->name, strlen(pColumn->name));
|
||||
if(!index){
|
||||
int32_t* index = taosHashGet(schemaHash, pColumn->name, strlen(pColumn->name));
|
||||
if (!index) {
|
||||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NULL, NULL, false, offset, k);
|
||||
}else{
|
||||
} else {
|
||||
char* colData = rspObj.resInfo.row[*index];
|
||||
if (!colData) {
|
||||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NULL, NULL, false, offset, k);
|
||||
|
@ -1669,7 +1670,7 @@ int32_t tmq_write_raw(TAOS* taos, tmq_raw_data raw) {
|
|||
} else if (raw.raw_type == TDMT_VND_DELETE) {
|
||||
return taosDeleteData(taos, raw.raw, raw.raw_len);
|
||||
} else if (raw.raw_type == RES_TYPE__TMQ) {
|
||||
return tmqWriteRaw(taos, raw.raw, raw.raw_len);
|
||||
return tmqWriteRawDataImpl(taos, raw.raw, raw.raw_len);
|
||||
}
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
|
@ -547,6 +547,8 @@ static int32_t smlModifyDBSchemas(SSmlHandle *info) {
|
|||
goto end;
|
||||
}
|
||||
needCheckMeta = true;
|
||||
taosHashCleanup(hashTmp);
|
||||
hashTmp = NULL;
|
||||
} else {
|
||||
uError("SML:0x%" PRIx64 " load table meta error: %s", info->id, tstrerror(code));
|
||||
goto end;
|
||||
|
@ -576,7 +578,6 @@ static int32_t smlModifyDBSchemas(SSmlHandle *info) {
|
|||
sTableData->tableMeta = pTableMeta;
|
||||
|
||||
tableMetaSml = (SSmlSTableMeta **)taosHashIterate(info->superTables, tableMetaSml);
|
||||
taosHashCleanup(hashTmp);
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ static const SSysDbTableSchema userDBSchema[] = {
|
|||
{.name = "minrows", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true},
|
||||
{.name = "maxrows", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true},
|
||||
{.name = "comp", .bytes = 1, .type = TSDB_DATA_TYPE_TINYINT, .sysInfo = true},
|
||||
{.name = "precision", .bytes = 2 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||
{.name = "precision", .bytes = 2 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "status", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "retentions", .bytes = 60 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||
{.name = "single_stable", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = true},
|
||||
|
@ -103,6 +103,8 @@ static const SSysDbTableSchema userDBSchema[] = {
|
|||
{.name = "wal_roll_period", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true},
|
||||
{.name = "wal_segment_size", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = true},
|
||||
{.name = "sst_trigger", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true},
|
||||
{.name = "table_prefix", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true},
|
||||
{.name = "table_suffix", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true},
|
||||
};
|
||||
|
||||
static const SSysDbTableSchema userFuncSchema[] = {
|
||||
|
@ -207,6 +209,7 @@ static const SSysDbTableSchema vgroupsSchema[] = {
|
|||
{.name = "v3_dnode", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true},
|
||||
{.name = "v3_status", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||
{.name = "status", .bytes = 12 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||
{.name = "cacheload", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true},
|
||||
{.name = "nfiles", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true},
|
||||
{.name = "file_size", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true},
|
||||
{.name = "tsma", .bytes = 1, .type = TSDB_DATA_TYPE_TINYINT, .sysInfo = true},
|
||||
|
|
|
@ -140,7 +140,8 @@ int32_t colDataReserve(SColumnInfoData* pColumnInfoData, size_t newSize) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t currentRow, const char* pData, int32_t itemLen, int32_t numOfRows) {
|
||||
static void doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t currentRow, const char* pData,
|
||||
int32_t itemLen, int32_t numOfRows) {
|
||||
ASSERT(pColumnInfoData->info.bytes >= itemLen);
|
||||
size_t start = 1;
|
||||
|
||||
|
@ -148,21 +149,23 @@ static void doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t curren
|
|||
memcpy(pColumnInfoData->pData, pData, itemLen);
|
||||
|
||||
int32_t t = 0;
|
||||
int32_t count = log(numOfRows)/log(2);
|
||||
while(t < count) {
|
||||
int32_t count = log(numOfRows) / log(2);
|
||||
while (t < count) {
|
||||
int32_t xlen = 1 << t;
|
||||
memcpy(pColumnInfoData->pData + start * itemLen + pColumnInfoData->varmeta.length, pColumnInfoData->pData, xlen * itemLen);
|
||||
memcpy(pColumnInfoData->pData + start * itemLen + pColumnInfoData->varmeta.length, pColumnInfoData->pData,
|
||||
xlen * itemLen);
|
||||
t += 1;
|
||||
start += xlen;
|
||||
}
|
||||
|
||||
// the tail part
|
||||
if (numOfRows > start) {
|
||||
memcpy(pColumnInfoData->pData + start * itemLen + currentRow * itemLen, pColumnInfoData->pData, (numOfRows - start) * itemLen);
|
||||
memcpy(pColumnInfoData->pData + start * itemLen + currentRow * itemLen, pColumnInfoData->pData,
|
||||
(numOfRows - start) * itemLen);
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
pColumnInfoData->varmeta.offset[i + currentRow] = pColumnInfoData->varmeta.length + i * itemLen;
|
||||
}
|
||||
|
||||
|
@ -170,7 +173,8 @@ static void doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t curren
|
|||
}
|
||||
}
|
||||
|
||||
int32_t colDataAppendNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, uint32_t numOfRows) {
|
||||
int32_t colDataAppendNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData,
|
||||
uint32_t numOfRows) {
|
||||
ASSERT(pData != NULL && pColumnInfoData != NULL);
|
||||
|
||||
int32_t len = pColumnInfoData->info.bytes;
|
||||
|
@ -278,7 +282,7 @@ int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, int
|
|||
} else {
|
||||
if (finalNumOfRows > *capacity || (numOfRow1 == 0 && pColumnInfoData->info.bytes != 0)) {
|
||||
// all data may be null, when the pColumnInfoData->info.type == 0, bytes == 0;
|
||||
// ASSERT(finalNumOfRows * pColumnInfoData->info.bytes);
|
||||
// ASSERT(finalNumOfRows * pColumnInfoData->info.bytes);
|
||||
char* tmp = taosMemoryRealloc(pColumnInfoData->pData, finalNumOfRows * pColumnInfoData->info.bytes);
|
||||
if (tmp == NULL) {
|
||||
return TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||
|
@ -557,7 +561,7 @@ int32_t blockDataToBuf(char* buf, const SSDataBlock* pBlock) {
|
|||
}
|
||||
|
||||
int32_t blockDataFromBuf(SSDataBlock* pBlock, const char* buf) {
|
||||
int32_t numOfRows = *(int32_t*) buf;
|
||||
int32_t numOfRows = *(int32_t*)buf;
|
||||
blockDataEnsureCapacity(pBlock, numOfRows);
|
||||
|
||||
pBlock->info.rows = numOfRows;
|
||||
|
@ -676,7 +680,8 @@ size_t blockDataGetRowSize(SSDataBlock* pBlock) {
|
|||
* @return
|
||||
*/
|
||||
size_t blockDataGetSerialMetaSize(uint32_t numOfCols) {
|
||||
// | version | total length | total rows | total columns | flag seg| block group id | column schema | each column length |
|
||||
// | version | total length | total rows | total columns | flag seg| block group id | column schema | each column
|
||||
// length |
|
||||
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(uint64_t) +
|
||||
numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t);
|
||||
}
|
||||
|
@ -1302,6 +1307,40 @@ int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSDataBlock* createSpecialDataBlock(EStreamType type) {
|
||||
SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
pBlock->info.hasVarCol = false;
|
||||
pBlock->info.groupId = 0;
|
||||
pBlock->info.rows = 0;
|
||||
pBlock->info.type = type;
|
||||
pBlock->info.rowSize =
|
||||
sizeof(TSKEY) + sizeof(TSKEY) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(TSKEY) + sizeof(TSKEY);
|
||||
pBlock->info.watermark = INT64_MIN;
|
||||
|
||||
pBlock->pDataBlock = taosArrayInit(6, sizeof(SColumnInfoData));
|
||||
SColumnInfoData infoData = {0};
|
||||
infoData.info.type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
infoData.info.bytes = sizeof(TSKEY);
|
||||
// window start ts
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
// window end ts
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
infoData.info.type = TSDB_DATA_TYPE_UBIGINT;
|
||||
infoData.info.bytes = sizeof(uint64_t);
|
||||
// uid
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
// group id
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
// calculate start ts
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
// calculate end ts
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
||||
if (pDataBlock == NULL) {
|
||||
return NULL;
|
||||
|
@ -1426,7 +1465,7 @@ size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize) {
|
|||
}
|
||||
|
||||
void colDataDestroy(SColumnInfoData* pColData) {
|
||||
if(!pColData) return;
|
||||
if (!pColData) return;
|
||||
if (IS_VAR_DATA_TYPE(pColData->info.type)) {
|
||||
taosMemoryFreeClear(pColData->varmeta.offset);
|
||||
} else {
|
||||
|
@ -1693,7 +1732,7 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) {
|
|||
}
|
||||
struct tm ptm = {0};
|
||||
taosLocalTime(&tt, &ptm);
|
||||
size_t pos = strftime(buf, 35, "%Y-%m-%d %H:%M:%S", &ptm);
|
||||
size_t pos = strftime(buf, 35, "%Y-%m-%d %H:%M:%S", &ptm);
|
||||
|
||||
if (precision == TSDB_TIME_PRECISION_NANO) {
|
||||
sprintf(buf + pos, ".%09d", ms);
|
||||
|
@ -1847,20 +1886,20 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf)
|
|||
break;
|
||||
case TSDB_DATA_TYPE_VARCHAR: {
|
||||
memset(pBuf, 0, sizeof(pBuf));
|
||||
char* pData = colDataGetVarData(pColInfoData, j);
|
||||
char* pData = colDataGetVarData(pColInfoData, j);
|
||||
int32_t dataSize = TMIN(sizeof(pBuf), varDataLen(pData));
|
||||
memcpy(pBuf, varDataVal(pData), dataSize);
|
||||
len += snprintf(dumpBuf + len, size - len, " %15s |", pBuf);
|
||||
if (len >= size - 1) return dumpBuf;
|
||||
} break;
|
||||
} break;
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
char* pData = colDataGetVarData(pColInfoData, j);
|
||||
char* pData = colDataGetVarData(pColInfoData, j);
|
||||
int32_t dataSize = TMIN(sizeof(pBuf), varDataLen(pData));
|
||||
memset(pBuf, 0, sizeof(pBuf));
|
||||
taosUcs4ToMbs((TdUcs4 *)varDataVal(pData), dataSize, pBuf);
|
||||
taosUcs4ToMbs((TdUcs4*)varDataVal(pData), dataSize, pBuf);
|
||||
len += snprintf(dumpBuf + len, size - len, " %15s |", pBuf);
|
||||
if (len >= size - 1) return dumpBuf;
|
||||
} break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
len += snprintf(dumpBuf + len, size - len, "\n");
|
||||
|
@ -1877,7 +1916,7 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf)
|
|||
* @param pDataBlocks
|
||||
* @param vgId
|
||||
* @param suid
|
||||
*
|
||||
*
|
||||
*/
|
||||
int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SSDataBlock* pDataBlock, STSchema* pTSchema, int32_t vgId,
|
||||
tb_uid_t suid) {
|
||||
|
@ -1904,8 +1943,8 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SSDataBlock* pDataB
|
|||
tdSRowInit(&rb, pTSchema->version);
|
||||
|
||||
for (int32_t i = 0; i < sz; ++i) {
|
||||
int32_t colNum = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||
int32_t rows = pDataBlock->info.rows;
|
||||
int32_t colNum = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||
int32_t rows = pDataBlock->info.rows;
|
||||
// int32_t rowSize = pDataBlock->info.rowSize;
|
||||
// int64_t groupId = pDataBlock->info.groupId;
|
||||
|
||||
|
@ -1926,7 +1965,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SSDataBlock* pDataB
|
|||
|
||||
msgLen += sizeof(SSubmitBlk);
|
||||
int32_t dataLen = 0;
|
||||
for (int32_t j = 0; j < rows; ++j) { // iterate by row
|
||||
for (int32_t j = 0; j < rows; ++j) { // iterate by row
|
||||
tdSRowResetBuf(&rb, POINTER_SHIFT(pDataBuf, msgLen + dataLen)); // set row buf
|
||||
bool isStartKey = false;
|
||||
int32_t offset = 0;
|
||||
|
@ -2081,6 +2120,7 @@ void blockEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_
|
|||
int32_t* rows = (int32_t*)data;
|
||||
*rows = pBlock->info.rows;
|
||||
data += sizeof(int32_t);
|
||||
ASSERT(*rows > 0);
|
||||
|
||||
int32_t* cols = (int32_t*)data;
|
||||
*cols = numOfCols;
|
||||
|
@ -2089,7 +2129,7 @@ void blockEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_
|
|||
// flag segment.
|
||||
// the inital bit is for column info
|
||||
int32_t* flagSegment = (int32_t*)data;
|
||||
*flagSegment = (1<<31);
|
||||
*flagSegment = (1 << 31);
|
||||
|
||||
data += sizeof(int32_t);
|
||||
|
||||
|
@ -2144,12 +2184,14 @@ void blockEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_
|
|||
|
||||
*actualLen = *dataLen;
|
||||
*groupId = pBlock->info.groupId;
|
||||
ASSERT(*dataLen > 0);
|
||||
uDebug("build data block, actualLen:%d, rows:%d, cols:%d", *dataLen, *rows, *cols);
|
||||
}
|
||||
|
||||
const char* blockDecode(SSDataBlock* pBlock, const char* pData) {
|
||||
const char* pStart = pData;
|
||||
|
||||
int32_t version = *(int32_t*) pStart;
|
||||
int32_t version = *(int32_t*)pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
ASSERT(version == 1);
|
||||
|
||||
|
@ -2158,7 +2200,7 @@ const char* blockDecode(SSDataBlock* pBlock, const char* pData) {
|
|||
pStart += sizeof(int32_t);
|
||||
|
||||
// total rows sizeof(int32_t)
|
||||
int32_t numOfRows = *(int32_t*)pStart;
|
||||
int32_t numOfRows = *(int32_t*)pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
|
||||
// total columns sizeof(int32_t)
|
||||
|
|
|
@ -129,10 +129,6 @@ int32_t tsMinIntervalTime = 1;
|
|||
int32_t tsQueryBufferSize = -1;
|
||||
int64_t tsQueryBufferSizeBytes = -1;
|
||||
|
||||
// tsdb config
|
||||
// For backward compatibility
|
||||
bool tsdbForceKeepFile = false;
|
||||
|
||||
int32_t tsDiskCfgNum = 0;
|
||||
SDiskCfg tsDiskCfg[TFS_MAX_DISKS] = {0};
|
||||
|
||||
|
|
|
@ -994,6 +994,7 @@ int32_t tSerializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) {
|
|||
SVnodeLoad *pload = taosArrayGet(pReq->pVloads, i);
|
||||
if (tEncodeI32(&encoder, pload->vgId) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pload->syncState) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pload->cacheUsage) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pload->numOfTables) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pload->numOfTimeSeries) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pload->totalStorage) < 0) return -1;
|
||||
|
@ -1063,6 +1064,7 @@ int32_t tDeserializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) {
|
|||
SVnodeLoad vload = {0};
|
||||
if (tDecodeI32(&decoder, &vload.vgId) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &vload.syncState) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &vload.cacheUsage) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &vload.numOfTables) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &vload.numOfTimeSeries) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &vload.totalStorage) < 0) return -1;
|
||||
|
@ -2025,6 +2027,8 @@ int32_t tSerializeSCreateDbReq(void *buf, int32_t bufLen, SCreateDbReq *pReq) {
|
|||
if (tEncodeI32(&encoder, pReq->walRollPeriod) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pReq->walSegmentSize) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pReq->sstTrigger) < 0) return -1;
|
||||
if (tEncodeI16(&encoder, pReq->hashPrefix) < 0) return -1;
|
||||
if (tEncodeI16(&encoder, pReq->hashSuffix) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pReq->ignoreExist) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pReq->numOfRetensions) < 0) return -1;
|
||||
for (int32_t i = 0; i < pReq->numOfRetensions; ++i) {
|
||||
|
@ -2072,6 +2076,8 @@ int32_t tDeserializeSCreateDbReq(void *buf, int32_t bufLen, SCreateDbReq *pReq)
|
|||
if (tDecodeI32(&decoder, &pReq->walRollPeriod) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &pReq->walSegmentSize) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pReq->sstTrigger) < 0) return -1;
|
||||
if (tDecodeI16(&decoder, &pReq->hashPrefix) < 0) return -1;
|
||||
if (tDecodeI16(&decoder, &pReq->hashSuffix) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &pReq->ignoreExist) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pReq->numOfRetensions) < 0) return -1;
|
||||
pReq->pRetensions = taosArrayInit(pReq->numOfRetensions, sizeof(SRetention));
|
||||
|
@ -2457,6 +2463,8 @@ int32_t tSerializeSUseDbRspImp(SEncoder *pEncoder, const SUseDbRsp *pRsp) {
|
|||
if (tEncodeI64(pEncoder, pRsp->uid) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->vgVersion) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->vgNum) < 0) return -1;
|
||||
if (tEncodeI16(pEncoder, pRsp->hashPrefix) < 0) return -1;
|
||||
if (tEncodeI16(pEncoder, pRsp->hashSuffix) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pRsp->hashMethod) < 0) return -1;
|
||||
|
||||
for (int32_t i = 0; i < pRsp->vgNum; ++i) {
|
||||
|
@ -2508,6 +2516,8 @@ int32_t tDeserializeSUseDbRspImp(SDecoder *pDecoder, SUseDbRsp *pRsp) {
|
|||
if (tDecodeI64(pDecoder, &pRsp->uid) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->vgVersion) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->vgNum) < 0) return -1;
|
||||
if (tDecodeI16(pDecoder, &pRsp->hashPrefix) < 0) return -1;
|
||||
if (tDecodeI16(pDecoder, &pRsp->hashSuffix) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pRsp->hashMethod) < 0) return -1;
|
||||
|
||||
if (pRsp->vgNum <= 0) {
|
||||
|
@ -3767,6 +3777,8 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR
|
|||
if (tEncodeI32(&encoder, pReq->walRollPeriod) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pReq->walSegmentSize) < 0) return -1;
|
||||
if (tEncodeI16(&encoder, pReq->sstTrigger) < 0) return -1;
|
||||
if (tEncodeI16(&encoder, pReq->hashPrefix) < 0) return -1;
|
||||
if (tEncodeI16(&encoder, pReq->hashSuffix) < 0) return -1;
|
||||
|
||||
tEndEncode(&encoder);
|
||||
|
||||
|
@ -3840,6 +3852,8 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *
|
|||
if (tDecodeI32(&decoder, &pReq->walRollPeriod) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &pReq->walSegmentSize) < 0) return -1;
|
||||
if (tDecodeI16(&decoder, &pReq->sstTrigger) < 0) return -1;
|
||||
if (tDecodeI16(&decoder, &pReq->hashPrefix) < 0) return -1;
|
||||
if (tDecodeI16(&decoder, &pReq->hashSuffix) < 0) return -1;
|
||||
|
||||
tEndDecode(&decoder);
|
||||
tDecoderClear(&decoder);
|
||||
|
|
|
@ -538,12 +538,12 @@ bool tdSTSRowIterGetTpVal(STSRowIter *pIter, col_type_t colType, int32_t offset,
|
|||
} else {
|
||||
pVal->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tdGetBitmapValType(pIter->pBitmap, pIter->colIdx - 1, &pVal->valType, 0) != TSDB_CODE_SUCCESS) {
|
||||
pVal->valType = TD_VTYPE_NONE;
|
||||
return terrno;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pVal->valType == TD_VTYPE_NORM) {
|
||||
|
|
|
@ -167,10 +167,12 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) {
|
|||
pCfg->walCfg.segSize = pCreate->walSegmentSize;
|
||||
pCfg->walCfg.level = pCreate->walLevel;
|
||||
|
||||
pCfg->sstTrigger = pCreate->sstTrigger;
|
||||
pCfg->sttTrigger = pCreate->sstTrigger;
|
||||
pCfg->hashBegin = pCreate->hashBegin;
|
||||
pCfg->hashEnd = pCreate->hashEnd;
|
||||
pCfg->hashMethod = pCreate->hashMethod;
|
||||
pCfg->hashPrefix = pCreate->hashPrefix;
|
||||
pCfg->hashSuffix = pCreate->hashSuffix;
|
||||
|
||||
pCfg->standby = pCfg->standby;
|
||||
pCfg->syncCfg.myIndex = pCreate->selfIndex;
|
||||
|
@ -220,9 +222,11 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
dDebug("vgId:%d, start to create vnode, tsma:%d standby:%d cacheLast:%d cacheLastSize:%d sstTrigger:%d",
|
||||
createReq.vgId, createReq.isTsma, createReq.standby, createReq.cacheLast, createReq.cacheLastSize,
|
||||
createReq.sstTrigger);
|
||||
dInfo("vgId:%d, start to create vnode, tsma:%d standby:%d cacheLast:%d cacheLastSize:%d sstTrigger:%d",
|
||||
createReq.vgId, createReq.isTsma, createReq.standby, createReq.cacheLast, createReq.cacheLastSize,
|
||||
createReq.sstTrigger);
|
||||
dInfo("vgId:%d, hashMethod:%d begin:%u end:%u prefix:%d surfix:%d", createReq.vgId, createReq.hashMethod,
|
||||
createReq.hashBegin, createReq.hashEnd, createReq.hashPrefix, createReq.hashSuffix);
|
||||
vmGenerateVnodeCfg(&createReq, &vnodeCfg);
|
||||
|
||||
if (vmTsmaAdjustDays(&vnodeCfg, &createReq) < 0) {
|
||||
|
|
|
@ -305,13 +305,15 @@ typedef struct {
|
|||
int8_t hashMethod; // default is 1
|
||||
int8_t cacheLast;
|
||||
int8_t schemaless;
|
||||
int16_t hashPrefix;
|
||||
int16_t hashSuffix;
|
||||
int16_t sstTrigger;
|
||||
int32_t numOfRetensions;
|
||||
SArray* pRetensions;
|
||||
int32_t walRetentionPeriod;
|
||||
int64_t walRetentionSize;
|
||||
int32_t walRollPeriod;
|
||||
int64_t walRetentionSize;
|
||||
int64_t walSegmentSize;
|
||||
int16_t sstTrigger;
|
||||
} SDbCfg;
|
||||
|
||||
typedef struct {
|
||||
|
@ -341,6 +343,7 @@ typedef struct {
|
|||
uint32_t hashEnd;
|
||||
char dbName[TSDB_DB_FNAME_LEN];
|
||||
int64_t dbUid;
|
||||
int64_t cacheUsage;
|
||||
int64_t numOfTables;
|
||||
int64_t numOfTimeSeries;
|
||||
int64_t totalStorage;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndDb.h"
|
||||
#include "mndCluster.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndOffset.h"
|
||||
#include "mndPrivilege.h"
|
||||
|
@ -30,7 +31,7 @@
|
|||
#include "systable.h"
|
||||
|
||||
#define DB_VER_NUMBER 1
|
||||
#define DB_RESERVE_SIZE 62
|
||||
#define DB_RESERVE_SIZE 58
|
||||
|
||||
static SSdbRaw *mndDbActionEncode(SDbObj *pDb);
|
||||
static SSdbRow *mndDbActionDecode(SSdbRaw *pRaw);
|
||||
|
@ -125,6 +126,8 @@ static SSdbRaw *mndDbActionEncode(SDbObj *pDb) {
|
|||
SDB_SET_INT32(pRaw, dataPos, pDb->cfg.walRollPeriod, _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pDb->cfg.walSegmentSize, _OVER)
|
||||
SDB_SET_INT16(pRaw, dataPos, pDb->cfg.sstTrigger, _OVER)
|
||||
SDB_SET_INT16(pRaw, dataPos, pDb->cfg.hashPrefix, _OVER)
|
||||
SDB_SET_INT16(pRaw, dataPos, pDb->cfg.hashSuffix, _OVER)
|
||||
|
||||
SDB_SET_RESERVE(pRaw, dataPos, DB_RESERVE_SIZE, _OVER)
|
||||
SDB_SET_DATALEN(pRaw, dataPos, _OVER)
|
||||
|
@ -209,6 +212,8 @@ static SSdbRow *mndDbActionDecode(SSdbRaw *pRaw) {
|
|||
SDB_GET_INT32(pRaw, dataPos, &pDb->cfg.walRollPeriod, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pDb->cfg.walSegmentSize, _OVER)
|
||||
SDB_GET_INT16(pRaw, dataPos, &pDb->cfg.sstTrigger, _OVER)
|
||||
SDB_GET_INT16(pRaw, dataPos, &pDb->cfg.hashPrefix, _OVER)
|
||||
SDB_GET_INT16(pRaw, dataPos, &pDb->cfg.hashSuffix, _OVER)
|
||||
|
||||
SDB_GET_RESERVE(pRaw, dataPos, DB_RESERVE_SIZE, _OVER)
|
||||
taosInitRWLatch(&pDb->lock);
|
||||
|
@ -333,7 +338,9 @@ static int32_t mndCheckDbCfg(SMnode *pMnode, SDbCfg *pCfg) {
|
|||
if (pCfg->walRetentionSize < TSDB_DB_MIN_WAL_RETENTION_SIZE) return -1;
|
||||
if (pCfg->walRollPeriod < TSDB_DB_MIN_WAL_ROLL_PERIOD) return -1;
|
||||
if (pCfg->walSegmentSize < TSDB_DB_MIN_WAL_SEGMENT_SIZE) return -1;
|
||||
if (pCfg->sstTrigger < TSDB_MIN_SST_TRIGGER || pCfg->sstTrigger > TSDB_MAX_SST_TRIGGER) return -1;
|
||||
if (pCfg->sstTrigger < TSDB_MIN_STT_TRIGGER || pCfg->sstTrigger > TSDB_MAX_STT_TRIGGER) return -1;
|
||||
if (pCfg->hashPrefix < TSDB_MIN_HASH_PREFIX || pCfg->hashPrefix > TSDB_MAX_HASH_PREFIX) return -1;
|
||||
if (pCfg->hashSuffix < TSDB_MIN_HASH_SUFFIX || pCfg->hashSuffix > TSDB_MAX_HASH_SUFFIX) return -1;
|
||||
|
||||
terrno = 0;
|
||||
return terrno;
|
||||
|
@ -368,6 +375,8 @@ static void mndSetDefaultDbCfg(SDbCfg *pCfg) {
|
|||
if (pCfg->walRollPeriod < 0) pCfg->walRollPeriod = TSDB_REPS_DEF_DB_WAL_ROLL_PERIOD;
|
||||
if (pCfg->walSegmentSize < 0) pCfg->walSegmentSize = TSDB_DEFAULT_DB_WAL_SEGMENT_SIZE;
|
||||
if (pCfg->sstTrigger <= 0) pCfg->sstTrigger = TSDB_DEFAULT_SST_TRIGGER;
|
||||
if (pCfg->hashPrefix < 0) pCfg->hashPrefix = TSDB_DEFAULT_HASH_PREFIX;
|
||||
if (pCfg->hashSuffix < 0) pCfg->hashSuffix = TSDB_DEFAULT_HASH_SUFFIX;
|
||||
}
|
||||
|
||||
static int32_t mndSetCreateDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroups) {
|
||||
|
@ -485,6 +494,8 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate,
|
|||
.walRollPeriod = pCreate->walRollPeriod,
|
||||
.walSegmentSize = pCreate->walSegmentSize,
|
||||
.sstTrigger = pCreate->sstTrigger,
|
||||
.hashPrefix = pCreate->hashPrefix,
|
||||
.hashSuffix = pCreate->hashSuffix,
|
||||
};
|
||||
|
||||
dbObj.cfg.numOfRetensions = pCreate->numOfRetensions;
|
||||
|
@ -502,6 +513,12 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (dbObj.cfg.hashPrefix > 0) {
|
||||
int32_t dbLen = strlen(dbObj.name) + 1;
|
||||
mInfo("db:%s, hashPrefix adjust from %d to %d", dbObj.name, dbObj.cfg.hashPrefix, dbObj.cfg.hashPrefix + dbLen);
|
||||
dbObj.cfg.hashPrefix += dbLen;
|
||||
}
|
||||
|
||||
SVgObj *pVgroups = NULL;
|
||||
if (mndAllocVgroup(pMnode, &dbObj, &pVgroups) != 0) {
|
||||
mError("db:%s, failed to create since %s", pCreate->db, terrstr());
|
||||
|
@ -1161,6 +1178,8 @@ int32_t mndExtractDbInfo(SMnode *pMnode, SDbObj *pDb, SUseDbRsp *pRsp, const SUs
|
|||
pRsp->vgVersion = pDb->vgVersion;
|
||||
pRsp->vgNum = taosArrayGetSize(pRsp->pVgroupInfos);
|
||||
pRsp->hashMethod = pDb->cfg.hashMethod;
|
||||
pRsp->hashPrefix = pDb->cfg.hashPrefix;
|
||||
pRsp->hashSuffix = pDb->cfg.hashSuffix;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1293,6 +1312,8 @@ int32_t mndValidateDbInfo(SMnode *pMnode, SDbVgVersion *pDbs, int32_t numOfDbs,
|
|||
usedbRsp.vgVersion = pDb->vgVersion;
|
||||
usedbRsp.vgNum = (int32_t)taosArrayGetSize(usedbRsp.pVgroupInfos);
|
||||
usedbRsp.hashMethod = pDb->cfg.hashMethod;
|
||||
usedbRsp.hashPrefix = pDb->cfg.hashPrefix;
|
||||
usedbRsp.hashSuffix = pDb->cfg.hashSuffix;
|
||||
|
||||
taosArrayPush(batchUseRsp.pArray, &usedbRsp);
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
|
@ -1542,6 +1563,24 @@ static void mndDumpDbInfoData(SMnode *pMnode, SSDataBlock *pBlock, SDbObj *pDb,
|
|||
STR_WITH_MAXSIZE_TO_VARSTR(buf, "NULL", bytes);
|
||||
}
|
||||
|
||||
const char *precStr = NULL;
|
||||
switch (pDb->cfg.precision) {
|
||||
case TSDB_TIME_PRECISION_MILLI:
|
||||
precStr = TSDB_TIME_PRECISION_MILLI_STR;
|
||||
break;
|
||||
case TSDB_TIME_PRECISION_MICRO:
|
||||
precStr = TSDB_TIME_PRECISION_MICRO_STR;
|
||||
break;
|
||||
case TSDB_TIME_PRECISION_NANO:
|
||||
precStr = TSDB_TIME_PRECISION_NANO_STR;
|
||||
break;
|
||||
default:
|
||||
precStr = "none";
|
||||
break;
|
||||
}
|
||||
char precVstr[10] = {0};
|
||||
STR_WITH_SIZE_TO_VARSTR(precVstr, precStr, 2);
|
||||
|
||||
char *statusStr = "ready";
|
||||
if (objStatus == SDB_STATUS_CREATING) {
|
||||
statusStr = "creating";
|
||||
|
@ -1552,7 +1591,6 @@ static void mndDumpDbInfoData(SMnode *pMnode, SSDataBlock *pBlock, SDbObj *pDb,
|
|||
statusStr = "unsynced";
|
||||
}
|
||||
}
|
||||
|
||||
char statusVstr[24] = {0};
|
||||
STR_WITH_SIZE_TO_VARSTR(statusVstr, statusStr, strlen(statusStr));
|
||||
|
||||
|
@ -1561,8 +1599,12 @@ static void mndDumpDbInfoData(SMnode *pMnode, SSDataBlock *pBlock, SDbObj *pDb,
|
|||
SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, i);
|
||||
if (i == 0) {
|
||||
colDataAppend(pColInfo, rows, buf, false);
|
||||
} else if (i == 1) {
|
||||
colDataAppend(pColInfo, rows, (const char *)&pDb->createdTime, false);
|
||||
} else if (i == 3) {
|
||||
colDataAppend(pColInfo, rows, (const char *)&numOfTables, false);
|
||||
} else if (i == 14) {
|
||||
colDataAppend(pColInfo, rows, precVstr, false);
|
||||
} else if (i == 15) {
|
||||
colDataAppend(pColInfo, rows, statusVstr, false);
|
||||
} else {
|
||||
|
@ -1627,23 +1669,6 @@ static void mndDumpDbInfoData(SMnode *pMnode, SSDataBlock *pBlock, SDbObj *pDb,
|
|||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, rows, (const char *)&pDb->cfg.compression, false);
|
||||
|
||||
const char *precStr = NULL;
|
||||
switch (pDb->cfg.precision) {
|
||||
case TSDB_TIME_PRECISION_MILLI:
|
||||
precStr = TSDB_TIME_PRECISION_MILLI_STR;
|
||||
break;
|
||||
case TSDB_TIME_PRECISION_MICRO:
|
||||
precStr = TSDB_TIME_PRECISION_MICRO_STR;
|
||||
break;
|
||||
case TSDB_TIME_PRECISION_NANO:
|
||||
precStr = TSDB_TIME_PRECISION_NANO_STR;
|
||||
break;
|
||||
default:
|
||||
precStr = "none";
|
||||
break;
|
||||
}
|
||||
char precVstr[10] = {0};
|
||||
STR_WITH_SIZE_TO_VARSTR(precVstr, precStr, 2);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, rows, (const char *)precVstr, false);
|
||||
|
||||
|
@ -1691,23 +1716,33 @@ static void mndDumpDbInfoData(SMnode *pMnode, SSDataBlock *pBlock, SDbObj *pDb,
|
|||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, rows, (const char *)&pDb->cfg.sstTrigger, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
int16_t hashPrefix = pDb->cfg.hashPrefix;
|
||||
if (hashPrefix > 0) {
|
||||
hashPrefix = pDb->cfg.hashPrefix - strlen(pDb->name) - 1;
|
||||
}
|
||||
colDataAppend(pColInfo, rows, (const char *)&hashPrefix, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, rows, (const char *)&pDb->cfg.hashSuffix, false);
|
||||
}
|
||||
|
||||
taosMemoryFree(buf);
|
||||
}
|
||||
|
||||
static void setInformationSchemaDbCfg(SDbObj *pDbObj) {
|
||||
static void setInformationSchemaDbCfg(SMnode *pMnode, SDbObj *pDbObj) {
|
||||
tstrncpy(pDbObj->name, TSDB_INFORMATION_SCHEMA_DB, tListLen(pDbObj->name));
|
||||
pDbObj->createdTime = 0;
|
||||
pDbObj->createdTime = mndGetClusterCreateTime(pMnode);
|
||||
pDbObj->cfg.numOfVgroups = 0;
|
||||
pDbObj->cfg.strict = 1;
|
||||
pDbObj->cfg.replications = 1;
|
||||
pDbObj->cfg.precision = TSDB_TIME_PRECISION_MILLI;
|
||||
}
|
||||
|
||||
static void setPerfSchemaDbCfg(SDbObj *pDbObj) {
|
||||
static void setPerfSchemaDbCfg(SMnode *pMnode, SDbObj *pDbObj) {
|
||||
tstrncpy(pDbObj->name, TSDB_PERFORMANCE_SCHEMA_DB, tListLen(pDbObj->name));
|
||||
pDbObj->createdTime = 0;
|
||||
pDbObj->createdTime = mndGetClusterCreateTime(pMnode);
|
||||
pDbObj->cfg.numOfVgroups = 0;
|
||||
pDbObj->cfg.strict = 1;
|
||||
pDbObj->cfg.replications = 1;
|
||||
|
@ -1738,7 +1773,7 @@ static int32_t mndRetrieveDbs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc
|
|||
// Append the information_schema database into the result.
|
||||
if (!pShow->sysDbRsp) {
|
||||
SDbObj infoschemaDb = {0};
|
||||
setInformationSchemaDbCfg(&infoschemaDb);
|
||||
setInformationSchemaDbCfg(pMnode, &infoschemaDb);
|
||||
size_t numOfTables = 0;
|
||||
getVisibleInfosTablesNum(sysinfo, &numOfTables);
|
||||
mndDumpDbInfoData(pMnode, pBlock, &infoschemaDb, pShow, numOfRows, numOfTables, true, 0, 1);
|
||||
|
@ -1746,7 +1781,7 @@ static int32_t mndRetrieveDbs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc
|
|||
numOfRows += 1;
|
||||
|
||||
SDbObj perfschemaDb = {0};
|
||||
setPerfSchemaDbCfg(&perfschemaDb);
|
||||
setPerfSchemaDbCfg(pMnode, &perfschemaDb);
|
||||
numOfTables = 0;
|
||||
getPerfDbMeta(NULL, &numOfTables);
|
||||
mndDumpDbInfoData(pMnode, pBlock, &perfschemaDb, pShow, numOfRows, numOfTables, true, 0, 1);
|
||||
|
|
|
@ -347,6 +347,7 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
|
|||
SVgObj *pVgroup = mndAcquireVgroup(pMnode, pVload->vgId);
|
||||
if (pVgroup != NULL) {
|
||||
if (pVload->syncState == TAOS_SYNC_STATE_LEADER) {
|
||||
pVgroup->cacheUsage = pVload->cacheUsage;
|
||||
pVgroup->numOfTables = pVload->numOfTables;
|
||||
pVgroup->numOfTimeSeries = pVload->numOfTimeSeries;
|
||||
pVgroup->totalStorage = pVload->totalStorage;
|
||||
|
@ -853,8 +854,8 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
int32_t code = -1;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SDnodeObj *pDnode = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
|
||||
|
@ -877,7 +878,7 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
|
||||
sdbRelease(pSdb, pDnode);
|
||||
}
|
||||
|
||||
|
||||
if (code == -1) {
|
||||
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
}
|
||||
|
|
|
@ -235,6 +235,8 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg
|
|||
createReq.walRollPeriod = pDb->cfg.walRollPeriod;
|
||||
createReq.walSegmentSize = pDb->cfg.walSegmentSize;
|
||||
createReq.sstTrigger = pDb->cfg.sstTrigger;
|
||||
createReq.hashPrefix = pDb->cfg.hashPrefix;
|
||||
createReq.hashSuffix = pDb->cfg.hashSuffix;
|
||||
|
||||
for (int32_t v = 0; v < pVgroup->replica; ++v) {
|
||||
SReplica *pReplica = &createReq.replicas[v];
|
||||
|
@ -694,6 +696,9 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p
|
|||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppendNULL(pColInfo, numOfRows);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pVgroup->cacheUsage, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppendNULL(pColInfo, numOfRows);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ target_sources(
|
|||
# sma
|
||||
"src/sma/smaEnv.c"
|
||||
"src/sma/smaUtil.c"
|
||||
"src/sma/smaFS.c"
|
||||
"src/sma/smaOpen.c"
|
||||
"src/sma/smaCommit.c"
|
||||
"src/sma/smaRollup.c"
|
||||
|
@ -49,6 +50,10 @@ target_sources(
|
|||
"src/tsdb/tsdbSnapshot.c"
|
||||
"src/tsdb/tsdbCacheRead.c"
|
||||
"src/tsdb/tsdbRetention.c"
|
||||
"src/tsdb/tsdbDiskData.c"
|
||||
"src/tsdb/tsdbCompress.c"
|
||||
"src/tsdb/tsdbCompact.c"
|
||||
"src/tsdb/tsdbMergeTree.c"
|
||||
|
||||
# tq
|
||||
"src/tq/tq.c"
|
||||
|
|
|
@ -125,6 +125,9 @@ int32_t metaTbCursorNext(SMTbCursor *pTbCur);
|
|||
// typedef struct STsdb STsdb;
|
||||
typedef struct STsdbReader STsdbReader;
|
||||
|
||||
#define TSDB_DEFAULT_STT_FILE 8
|
||||
#define TSDB_DEFAULT_PAGE_SIZE 4096
|
||||
|
||||
#define TIMEWINDOW_RANGE_CONTAINED 1
|
||||
#define TIMEWINDOW_RANGE_EXTERNAL 2
|
||||
|
||||
|
@ -155,6 +158,7 @@ int32_t tsdbGetTableSchema(SVnode *pVnode, int64_t uid, STSchema **pSchema, int6
|
|||
|
||||
void tsdbCacheSetCapacity(SVnode *pVnode, size_t capacity);
|
||||
size_t tsdbCacheGetCapacity(SVnode *pVnode);
|
||||
size_t tsdbCacheGetUsage(SVnode *pVnode);
|
||||
|
||||
// tq
|
||||
typedef struct SMetaTableInfo {
|
||||
|
@ -287,7 +291,10 @@ struct SVnodeCfg {
|
|||
SVnodeStats vndStats;
|
||||
uint32_t hashBegin;
|
||||
uint32_t hashEnd;
|
||||
int16_t sstTrigger;
|
||||
int16_t sttTrigger;
|
||||
int16_t hashPrefix;
|
||||
int16_t hashSuffix;
|
||||
int32_t tsdbPageSize;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -38,9 +38,10 @@ typedef struct SSmaEnv SSmaEnv;
|
|||
typedef struct SSmaStat SSmaStat;
|
||||
typedef struct STSmaStat STSmaStat;
|
||||
typedef struct SRSmaStat SRSmaStat;
|
||||
typedef struct SSmaKey SSmaKey;
|
||||
typedef struct SRSmaRef SRSmaRef;
|
||||
typedef struct SRSmaInfo SRSmaInfo;
|
||||
typedef struct SRSmaInfoItem SRSmaInfoItem;
|
||||
typedef struct SRSmaFS SRSmaFS;
|
||||
typedef struct SQTaskFile SQTaskFile;
|
||||
typedef struct SQTaskFReader SQTaskFReader;
|
||||
typedef struct SQTaskFWriter SQTaskFWriter;
|
||||
|
@ -54,10 +55,21 @@ struct SSmaEnv {
|
|||
|
||||
#define SMA_ENV_FLG_CLOSE ((int8_t)0x1)
|
||||
|
||||
struct SRSmaRef {
|
||||
int64_t refId; // for SRSmaStat
|
||||
int64_t suid;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int8_t inited;
|
||||
int32_t rsetId;
|
||||
void *tmrHandle; // shared by all fetch tasks
|
||||
/**
|
||||
* @brief key: void* of SRSmaInfoItem, value: SRSmaRef
|
||||
* N.B. Although there is a very small possibility that "void*" point to different objects while with the same
|
||||
* address after release/renew, the functionality is not affected as it just used to fetch the rsma results.
|
||||
*/
|
||||
SHashObj *refHash; // shared by all vgroups
|
||||
} SSmaMgmt;
|
||||
|
||||
#define SMA_ENV_LOCK(env) (&(env)->lock)
|
||||
|
@ -73,20 +85,25 @@ struct STSmaStat {
|
|||
|
||||
struct SQTaskFile {
|
||||
volatile int32_t nRef;
|
||||
int64_t commitID;
|
||||
int32_t padding;
|
||||
int64_t version;
|
||||
int64_t size;
|
||||
};
|
||||
|
||||
struct SQTaskFReader {
|
||||
SSma *pSma;
|
||||
SQTaskFile fTask;
|
||||
TdFilePtr pReadH;
|
||||
SSma *pSma;
|
||||
int64_t version;
|
||||
TdFilePtr pReadH;
|
||||
};
|
||||
struct SQTaskFWriter {
|
||||
SSma *pSma;
|
||||
SQTaskFile fTask;
|
||||
TdFilePtr pWriteH;
|
||||
char *fname;
|
||||
SSma *pSma;
|
||||
int64_t version;
|
||||
TdFilePtr pWriteH;
|
||||
char *fname;
|
||||
};
|
||||
|
||||
struct SRSmaFS {
|
||||
SArray *aQTaskInf; // array of SQTaskFile
|
||||
};
|
||||
|
||||
struct SRSmaStat {
|
||||
|
@ -96,9 +113,10 @@ struct SRSmaStat {
|
|||
volatile int64_t nBufItems; // number of items in queue buffer
|
||||
SRWLatch lock; // r/w lock for rsma fs(e.g. qtaskinfo)
|
||||
volatile int32_t nFetchAll; // active number of fetch all
|
||||
int8_t triggerStat; // shared by fetch tasks
|
||||
int8_t commitStat; // 0 not in committing, 1 in committing
|
||||
SArray *aTaskFile; // qTaskFiles committed recently(for recovery/snapshot r/w)
|
||||
volatile int8_t triggerStat; // shared by fetch tasks
|
||||
volatile int8_t commitStat; // 0 not in committing, 1 in committing
|
||||
volatile int8_t delFlag; // 0 no deleted SRSmaInfo, 1 has deleted SRSmaInfo
|
||||
SRSmaFS fs; // for recovery/snapshot r/w
|
||||
SHashObj *infoHash; // key: suid, value: SRSmaInfo
|
||||
tsem_t notEmpty; // has items in queue buffer
|
||||
};
|
||||
|
@ -118,21 +136,22 @@ struct SSmaStat {
|
|||
#define RSMA_TRIGGER_STAT(r) (&(r)->triggerStat)
|
||||
#define RSMA_COMMIT_STAT(r) (&(r)->commitStat)
|
||||
#define RSMA_REF_ID(r) ((r)->refId)
|
||||
#define RSMA_FS(r) (&(r)->fs)
|
||||
#define RSMA_FS_LOCK(r) (&(r)->lock)
|
||||
|
||||
struct SRSmaInfoItem {
|
||||
int8_t level : 4;
|
||||
int8_t fetchLevel : 4;
|
||||
int8_t triggerStat;
|
||||
uint16_t nSkipped;
|
||||
uint16_t nScanned;
|
||||
int32_t maxDelay; // ms
|
||||
tmr_h tmrId;
|
||||
};
|
||||
|
||||
struct SRSmaInfo {
|
||||
SSma *pSma;
|
||||
STSchema *pTSchema;
|
||||
int64_t suid;
|
||||
int64_t refId; // refId of SRSmaStat
|
||||
int64_t lastRecv; // ms
|
||||
int8_t assigned; // 0 idle, 1 assgined for exec
|
||||
int8_t delFlag;
|
||||
|
@ -163,14 +182,6 @@ enum {
|
|||
TASK_TRIGGER_STAT_DROPPED = 5,
|
||||
};
|
||||
|
||||
enum {
|
||||
RSMA_ROLE_CREATE = 0,
|
||||
RSMA_ROLE_DROP = 1,
|
||||
RSMA_ROLE_SUBMIT = 2,
|
||||
RSMA_ROLE_FETCH = 3,
|
||||
RSMA_ROLE_ITERATE = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
RSMA_RESTORE_REBOOT = 1,
|
||||
RSMA_RESTORE_SYNC = 2,
|
||||
|
@ -182,89 +193,49 @@ typedef enum {
|
|||
RSMA_EXEC_COMMIT = 3, // triggered by commit
|
||||
} ERsmaExecType;
|
||||
|
||||
void tdDestroySmaEnv(SSmaEnv *pSmaEnv);
|
||||
void *tdFreeSmaEnv(SSmaEnv *pSmaEnv);
|
||||
|
||||
int32_t tdDropTSma(SSma *pSma, char *pMsg);
|
||||
int32_t tdDropTSmaData(SSma *pSma, int64_t indexUid);
|
||||
int32_t tdInsertRSmaData(SSma *pSma, char *msg);
|
||||
|
||||
int32_t tdRefSmaStat(SSma *pSma, SSmaStat *pStat);
|
||||
int32_t tdUnRefSmaStat(SSma *pSma, SSmaStat *pStat);
|
||||
int32_t tdRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo);
|
||||
int32_t tdUnRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo);
|
||||
|
||||
// sma
|
||||
int32_t tdCheckAndInitSmaEnv(SSma *pSma, int8_t smaType);
|
||||
void tdDestroySmaEnv(SSmaEnv *pSmaEnv);
|
||||
void *tdFreeSmaEnv(SSmaEnv *pSmaEnv);
|
||||
int32_t tdLockSma(SSma *pSma);
|
||||
int32_t tdUnLockSma(SSma *pSma);
|
||||
void *tdAcquireSmaRef(int32_t rsetId, int64_t refId);
|
||||
int32_t tdReleaseSmaRef(int32_t rsetId, int64_t refId);
|
||||
|
||||
int32_t tdCheckAndInitSmaEnv(SSma *pSma, int8_t smaType);
|
||||
|
||||
int32_t tdLockSma(SSma *pSma);
|
||||
int32_t tdUnLockSma(SSma *pSma);
|
||||
|
||||
static FORCE_INLINE int8_t tdSmaStat(STSmaStat *pTStat) {
|
||||
if (pTStat) {
|
||||
return atomic_load_8(&pTStat->state);
|
||||
}
|
||||
return TSDB_SMA_STAT_UNKNOWN;
|
||||
static FORCE_INLINE void tdRefSmaStat(SSma *pSma, SSmaStat *pStat) {
|
||||
int32_t ref = T_REF_INC(pStat);
|
||||
smaDebug("vgId:%d, ref sma stat:%p, val:%d", SMA_VID(pSma), pStat, ref);
|
||||
}
|
||||
static FORCE_INLINE void tdUnRefSmaStat(SSma *pSma, SSmaStat *pStat) {
|
||||
int32_t ref = T_REF_DEC(pStat);
|
||||
smaDebug("vgId:%d, unref sma stat:%p, val:%d", SMA_VID(pSma), pStat, ref);
|
||||
}
|
||||
|
||||
static FORCE_INLINE bool tdSmaStatIsOK(STSmaStat *pTStat, int8_t *state) {
|
||||
if (!pTStat) {
|
||||
return false;
|
||||
}
|
||||
// rsma
|
||||
void *tdFreeRSmaInfo(SSma *pSma, SRSmaInfo *pInfo, bool isDeepFree);
|
||||
int32_t tdRSmaFSOpen(SSma *pSma, int64_t version);
|
||||
void tdRSmaFSClose(SRSmaFS *fs);
|
||||
int32_t tdRSmaFSRef(SSma *pSma, SRSmaStat *pStat, int64_t version);
|
||||
void tdRSmaFSUnRef(SSma *pSma, SRSmaStat *pStat, int64_t version);
|
||||
int64_t tdRSmaFSMaxVer(SSma *pSma, SRSmaStat *pStat);
|
||||
int32_t tdRSmaFSUpsertQTaskFile(SRSmaFS *pFS, SQTaskFile *qTaskFile);
|
||||
int32_t tdRSmaRestore(SSma *pSma, int8_t type, int64_t committedVer);
|
||||
int32_t tdRSmaProcessCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, const char *tbName);
|
||||
int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type);
|
||||
int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash);
|
||||
int32_t tdRSmaProcessRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer);
|
||||
void tdRSmaQTaskInfoGetFileName(int32_t vid, int64_t version, char *outputName);
|
||||
void tdRSmaQTaskInfoGetFullName(int32_t vid, int64_t version, const char *path, char *outputName);
|
||||
|
||||
if (state) {
|
||||
*state = atomic_load_8(&pTStat->state);
|
||||
return *state == TSDB_SMA_STAT_OK;
|
||||
}
|
||||
return atomic_load_8(&pTStat->state) == TSDB_SMA_STAT_OK;
|
||||
static FORCE_INLINE void tdRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo) {
|
||||
int32_t ref = T_REF_INC(pRSmaInfo);
|
||||
smaDebug("vgId:%d, ref rsma info:%p, val:%d", SMA_VID(pSma), pRSmaInfo, ref);
|
||||
}
|
||||
|
||||
static FORCE_INLINE bool tdSmaStatIsExpired(STSmaStat *pTStat) {
|
||||
return pTStat ? (atomic_load_8(&pTStat->state) & TSDB_SMA_STAT_EXPIRED) : true;
|
||||
static FORCE_INLINE void tdUnRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo) {
|
||||
int32_t ref = T_REF_DEC(pRSmaInfo);
|
||||
smaDebug("vgId:%d, unref rsma info:%p, val:%d", SMA_VID(pSma), pRSmaInfo, ref);
|
||||
}
|
||||
|
||||
static FORCE_INLINE bool tdSmaStatIsDropped(STSmaStat *pTStat) {
|
||||
return pTStat ? (atomic_load_8(&pTStat->state) & TSDB_SMA_STAT_DROPPED) : true;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tdSmaStatSetOK(STSmaStat *pTStat) {
|
||||
if (pTStat) {
|
||||
atomic_store_8(&pTStat->state, TSDB_SMA_STAT_OK);
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tdSmaStatSetExpired(STSmaStat *pTStat) {
|
||||
if (pTStat) {
|
||||
atomic_or_fetch_8(&pTStat->state, TSDB_SMA_STAT_EXPIRED);
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tdSmaStatSetDropped(STSmaStat *pTStat) {
|
||||
if (pTStat) {
|
||||
atomic_or_fetch_8(&pTStat->state, TSDB_SMA_STAT_DROPPED);
|
||||
}
|
||||
}
|
||||
|
||||
void tdRSmaQTaskInfoGetFileName(int32_t vid, int64_t version, char *outputName);
|
||||
void tdRSmaQTaskInfoGetFullName(int32_t vid, int64_t version, const char *path, char *outputName);
|
||||
int32_t tdCloneRSmaInfo(SSma *pSma, SRSmaInfo *pInfo);
|
||||
void tdFreeQTaskInfo(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level);
|
||||
static int32_t tdDestroySmaState(SSmaStat *pSmaStat, int8_t smaType);
|
||||
void *tdFreeSmaState(SSmaStat *pSmaStat, int8_t smaType);
|
||||
void *tdFreeRSmaInfo(SSma *pSma, SRSmaInfo *pInfo, bool isDeepFree);
|
||||
int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash);
|
||||
int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type);
|
||||
|
||||
int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, const char *tbName);
|
||||
int32_t tdProcessRSmaRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer);
|
||||
int32_t tdRsmaRestore(SSma *pSma, int8_t type, int64_t committedVer);
|
||||
|
||||
int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *pMsg);
|
||||
int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg);
|
||||
int32_t tdProcessTSmaGetDaysImpl(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days);
|
||||
|
||||
// smaFileUtil ================
|
||||
|
||||
#define TD_FILE_HEAD_SIZE 512
|
||||
|
|
|
@ -42,15 +42,15 @@ typedef struct SMemTable SMemTable;
|
|||
typedef struct STbDataIter STbDataIter;
|
||||
typedef struct SMapData SMapData;
|
||||
typedef struct SBlockIdx SBlockIdx;
|
||||
typedef struct SBlock SBlock;
|
||||
typedef struct SBlockL SBlockL;
|
||||
typedef struct SDataBlk SDataBlk;
|
||||
typedef struct SSttBlk SSttBlk;
|
||||
typedef struct SColData SColData;
|
||||
typedef struct SDiskDataHdr SDiskDataHdr;
|
||||
typedef struct SBlockData SBlockData;
|
||||
typedef struct SDelFile SDelFile;
|
||||
typedef struct SHeadFile SHeadFile;
|
||||
typedef struct SDataFile SDataFile;
|
||||
typedef struct SLastFile SLastFile;
|
||||
typedef struct SSttFile SSttFile;
|
||||
typedef struct SSmaFile SSmaFile;
|
||||
typedef struct SDFileSet SDFileSet;
|
||||
typedef struct SDataFWriter SDataFWriter;
|
||||
|
@ -64,6 +64,8 @@ typedef struct STsdbReadSnap STsdbReadSnap;
|
|||
typedef struct SBlockInfo SBlockInfo;
|
||||
typedef struct SSmaInfo SSmaInfo;
|
||||
typedef struct SBlockCol SBlockCol;
|
||||
typedef struct SVersionRange SVersionRange;
|
||||
typedef struct SLDataIter SLDataIter;
|
||||
|
||||
#define TSDB_FILE_DLMT ((uint32_t)0xF00AFA0F)
|
||||
#define TSDB_MAX_SUBBLOCKS 8
|
||||
|
@ -79,6 +81,27 @@ typedef struct SBlockCol SBlockCol;
|
|||
#define TSDBKEY_MIN ((TSDBKEY){.ts = TSKEY_MIN, .version = VERSION_MIN})
|
||||
#define TSDBKEY_MAX ((TSDBKEY){.ts = TSKEY_MAX, .version = VERSION_MAX})
|
||||
|
||||
#define TABLE_SAME_SCHEMA(SUID1, UID1, SUID2, UID2) ((SUID1) ? (SUID1) == (SUID2) : (UID1) == (UID2))
|
||||
|
||||
#define PAGE_CONTENT_SIZE(PAGE) ((PAGE) - sizeof(TSCKSUM))
|
||||
#define LOGIC_TO_FILE_OFFSET(LOFFSET, PAGE) \
|
||||
((LOFFSET) / PAGE_CONTENT_SIZE(PAGE) * (PAGE) + (LOFFSET) % PAGE_CONTENT_SIZE(PAGE))
|
||||
#define FILE_TO_LOGIC_OFFSET(OFFSET, PAGE) ((OFFSET) / (PAGE)*PAGE_CONTENT_SIZE(PAGE) + (OFFSET) % (PAGE))
|
||||
#define PAGE_OFFSET(PGNO, PAGE) (((PGNO)-1) * (PAGE))
|
||||
#define OFFSET_PGNO(OFFSET, PAGE) ((OFFSET) / (PAGE) + 1)
|
||||
|
||||
static FORCE_INLINE int64_t tsdbLogicToFileSize(int64_t lSize, int32_t szPage) {
|
||||
int64_t fOffSet = LOGIC_TO_FILE_OFFSET(lSize, szPage);
|
||||
int64_t pgno = OFFSET_PGNO(fOffSet, szPage);
|
||||
int32_t szPageCont = PAGE_CONTENT_SIZE(szPage);
|
||||
|
||||
if (fOffSet % szPageCont == 0) {
|
||||
pgno--;
|
||||
}
|
||||
|
||||
return pgno * szPage;
|
||||
}
|
||||
|
||||
// tsdbUtil.c ==============================================================================================
|
||||
// TSDBROW
|
||||
#define TSDBROW_TS(ROW) (((ROW)->type == 0) ? (ROW)->pTSRow->ts : (ROW)->pBlockData->aTSKEY[(ROW)->iRow])
|
||||
|
@ -111,15 +134,15 @@ int32_t tTABLEIDCmprFn(const void *p1, const void *p2);
|
|||
int32_t tPutBlockCol(uint8_t *p, void *ph);
|
||||
int32_t tGetBlockCol(uint8_t *p, void *ph);
|
||||
int32_t tBlockColCmprFn(const void *p1, const void *p2);
|
||||
// SBlock
|
||||
void tBlockReset(SBlock *pBlock);
|
||||
int32_t tPutBlock(uint8_t *p, void *ph);
|
||||
int32_t tGetBlock(uint8_t *p, void *ph);
|
||||
int32_t tBlockCmprFn(const void *p1, const void *p2);
|
||||
bool tBlockHasSma(SBlock *pBlock);
|
||||
// SBlockL
|
||||
int32_t tPutBlockL(uint8_t *p, void *ph);
|
||||
int32_t tGetBlockL(uint8_t *p, void *ph);
|
||||
// SDataBlk
|
||||
void tDataBlkReset(SDataBlk *pBlock);
|
||||
int32_t tPutDataBlk(uint8_t *p, void *ph);
|
||||
int32_t tGetDataBlk(uint8_t *p, void *ph);
|
||||
int32_t tDataBlkCmprFn(const void *p1, const void *p2);
|
||||
bool tDataBlkHasSma(SDataBlk *pDataBlk);
|
||||
// SSttBlk
|
||||
int32_t tPutSttBlk(uint8_t *p, void *ph);
|
||||
int32_t tGetSttBlk(uint8_t *p, void *ph);
|
||||
// SBlockIdx
|
||||
int32_t tPutBlockIdx(uint8_t *p, void *ph);
|
||||
int32_t tGetBlockIdx(uint8_t *p, void *ph);
|
||||
|
@ -170,6 +193,7 @@ int32_t tGetDelData(uint8_t *p, void *ph);
|
|||
void tMapDataReset(SMapData *pMapData);
|
||||
void tMapDataClear(SMapData *pMapData);
|
||||
int32_t tMapDataPutItem(SMapData *pMapData, void *pItem, int32_t (*tPutItemFn)(uint8_t *, void *));
|
||||
int32_t tMapDataCopy(SMapData *pFrom, SMapData *pTo);
|
||||
void tMapDataGetItemByIdx(SMapData *pMapData, int32_t idx, void *pItem, int32_t (*tGetItemFn)(uint8_t *, void *));
|
||||
int32_t tMapDataSearch(SMapData *pMapData, void *pSearchItem, int32_t (*tGetItemFn)(uint8_t *, void *),
|
||||
int32_t (*tItemCmprFn)(const void *, const void *), void *pItem);
|
||||
|
@ -191,7 +215,6 @@ int32_t tsdbCmprColData(SColData *pColData, int8_t cmprAlg, SBlockCol *pBlockCol
|
|||
uint8_t **ppBuf);
|
||||
int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, int32_t nVal, SColData *pColData,
|
||||
uint8_t **ppBuf);
|
||||
int32_t tsdbReadAndCheck(TdFilePtr pFD, int64_t offset, uint8_t **ppOut, int32_t size, int8_t toCheck);
|
||||
// tsdbMemTable ==============================================================================================
|
||||
// SMemTable
|
||||
int32_t tsdbMemTableCreate(STsdb *pTsdb, SMemTable **ppMemTable);
|
||||
|
@ -215,7 +238,7 @@ bool tsdbDelFileIsSame(SDelFile *pDelFile1, SDelFile *pDelFile2);
|
|||
int32_t tsdbDFileRollback(STsdb *pTsdb, SDFileSet *pSet, EDataFileT ftype);
|
||||
int32_t tPutHeadFile(uint8_t *p, SHeadFile *pHeadFile);
|
||||
int32_t tPutDataFile(uint8_t *p, SDataFile *pDataFile);
|
||||
int32_t tPutLastFile(uint8_t *p, SLastFile *pLastFile);
|
||||
int32_t tPutSttFile(uint8_t *p, SSttFile *pSttFile);
|
||||
int32_t tPutSmaFile(uint8_t *p, SSmaFile *pSmaFile);
|
||||
int32_t tPutDelFile(uint8_t *p, SDelFile *pDelFile);
|
||||
int32_t tGetDelFile(uint8_t *p, SDelFile *pDelFile);
|
||||
|
@ -224,7 +247,7 @@ int32_t tGetDFileSet(uint8_t *p, SDFileSet *pSet);
|
|||
|
||||
void tsdbHeadFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SHeadFile *pHeadF, char fname[]);
|
||||
void tsdbDataFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SDataFile *pDataF, char fname[]);
|
||||
void tsdbLastFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SLastFile *pLastF, char fname[]);
|
||||
void tsdbSttFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SSttFile *pSttF, char fname[]);
|
||||
void tsdbSmaFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SSmaFile *pSmaF, char fname[]);
|
||||
// SDelFile
|
||||
void tsdbDelFileName(STsdb *pTsdb, SDelFile *pFile, char fname[]);
|
||||
|
@ -249,8 +272,8 @@ int32_t tsdbDataFWriterOpen(SDataFWriter **ppWriter, STsdb *pTsdb, SDFileSet *pS
|
|||
int32_t tsdbDataFWriterClose(SDataFWriter **ppWriter, int8_t sync);
|
||||
int32_t tsdbUpdateDFileSetHeader(SDataFWriter *pWriter);
|
||||
int32_t tsdbWriteBlockIdx(SDataFWriter *pWriter, SArray *aBlockIdx);
|
||||
int32_t tsdbWriteBlock(SDataFWriter *pWriter, SMapData *pMapData, SBlockIdx *pBlockIdx);
|
||||
int32_t tsdbWriteBlockL(SDataFWriter *pWriter, SArray *aBlockL);
|
||||
int32_t tsdbWriteDataBlk(SDataFWriter *pWriter, SMapData *mDataBlk, SBlockIdx *pBlockIdx);
|
||||
int32_t tsdbWriteSttBlk(SDataFWriter *pWriter, SArray *aSttBlk);
|
||||
int32_t tsdbWriteBlockData(SDataFWriter *pWriter, SBlockData *pBlockData, SBlockInfo *pBlkInfo, SSmaInfo *pSmaInfo,
|
||||
int8_t cmprAlg, int8_t toLast);
|
||||
|
||||
|
@ -259,11 +282,11 @@ int32_t tsdbDFileSetCopy(STsdb *pTsdb, SDFileSet *pSetFrom, SDFileSet *pSetTo);
|
|||
int32_t tsdbDataFReaderOpen(SDataFReader **ppReader, STsdb *pTsdb, SDFileSet *pSet);
|
||||
int32_t tsdbDataFReaderClose(SDataFReader **ppReader);
|
||||
int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx);
|
||||
int32_t tsdbReadBlock(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *pMapData);
|
||||
int32_t tsdbReadBlockL(SDataFReader *pReader, SArray *aBlockL);
|
||||
int32_t tsdbReadBlockSma(SDataFReader *pReader, SBlock *pBlock, SArray *aColumnDataAgg);
|
||||
int32_t tsdbReadDataBlock(SDataFReader *pReader, SBlock *pBlock, SBlockData *pBlockData);
|
||||
int32_t tsdbReadLastBlock(SDataFReader *pReader, SBlockL *pBlockL, SBlockData *pBlockData);
|
||||
int32_t tsdbReadDataBlk(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *mDataBlk);
|
||||
int32_t tsdbReadSttBlk(SDataFReader *pReader, int32_t iStt, SArray *aSttBlk);
|
||||
int32_t tsdbReadBlockSma(SDataFReader *pReader, SDataBlk *pBlock, SArray *aColumnDataAgg);
|
||||
int32_t tsdbReadDataBlock(SDataFReader *pReader, SDataBlk *pBlock, SBlockData *pBlockData);
|
||||
int32_t tsdbReadSttBlock(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData);
|
||||
// SDelFWriter
|
||||
int32_t tsdbDelFWriterOpen(SDelFWriter **ppWriter, SDelFile *pFile, STsdb *pTsdb);
|
||||
int32_t tsdbDelFWriterClose(SDelFWriter **ppWriter, int8_t sync);
|
||||
|
@ -278,6 +301,8 @@ int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx);
|
|||
// tsdbRead.c ==============================================================================================
|
||||
int32_t tsdbTakeReadSnap(STsdb *pTsdb, STsdbReadSnap **ppSnap);
|
||||
void tsdbUntakeReadSnap(STsdb *pTsdb, STsdbReadSnap *pSnap);
|
||||
// tsdbMerge.c ==============================================================================================
|
||||
int32_t tsdbMerge(STsdb *pTsdb);
|
||||
|
||||
#define TSDB_CACHE_NO(c) ((c).cacheLast == 0)
|
||||
#define TSDB_CACHE_LAST_ROW(c) (((c).cacheLast & 1) > 0)
|
||||
|
@ -324,6 +349,11 @@ struct TSDBKEY {
|
|||
TSKEY ts;
|
||||
};
|
||||
|
||||
struct SVersionRange {
|
||||
uint64_t minVer;
|
||||
uint64_t maxVer;
|
||||
};
|
||||
|
||||
typedef struct SMemSkipListNode SMemSkipListNode;
|
||||
struct SMemSkipListNode {
|
||||
int8_t level;
|
||||
|
@ -416,7 +446,7 @@ struct SSmaInfo {
|
|||
int32_t size;
|
||||
};
|
||||
|
||||
struct SBlock {
|
||||
struct SDataBlk {
|
||||
TSDBKEY minKey;
|
||||
TSDBKEY maxKey;
|
||||
int64_t minVer;
|
||||
|
@ -428,7 +458,7 @@ struct SBlock {
|
|||
SSmaInfo smaInfo;
|
||||
};
|
||||
|
||||
struct SBlockL {
|
||||
struct SSttBlk {
|
||||
int64_t suid;
|
||||
int64_t minUid;
|
||||
int64_t maxUid;
|
||||
|
@ -467,12 +497,6 @@ struct SBlockData {
|
|||
SArray *aColData; // SArray<SColData>
|
||||
};
|
||||
|
||||
// ================== TSDB global config
|
||||
extern bool tsdbForceKeepFile;
|
||||
|
||||
#define TSDB_FS_ITER_FORWARD TSDB_ORDER_ASC
|
||||
#define TSDB_FS_ITER_BACKWARD TSDB_ORDER_DESC
|
||||
|
||||
struct TABLEID {
|
||||
tb_uid_t suid;
|
||||
tb_uid_t uid;
|
||||
|
@ -536,7 +560,7 @@ struct SDataFile {
|
|||
int64_t size;
|
||||
};
|
||||
|
||||
struct SLastFile {
|
||||
struct SSttFile {
|
||||
volatile int32_t nRef;
|
||||
|
||||
int64_t commitID;
|
||||
|
@ -556,8 +580,9 @@ struct SDFileSet {
|
|||
int32_t fid;
|
||||
SHeadFile *pHeadF;
|
||||
SDataFile *pDataF;
|
||||
SLastFile *pLastF;
|
||||
SSmaFile *pSmaF;
|
||||
uint8_t nSttF;
|
||||
SSttFile *aSttF[TSDB_MAX_STT_TRIGGER];
|
||||
};
|
||||
|
||||
struct SRowIter {
|
||||
|
@ -572,37 +597,99 @@ struct SRowMerger {
|
|||
SArray *pArray; // SArray<SColVal>
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *path;
|
||||
int32_t szPage;
|
||||
int32_t flag;
|
||||
TdFilePtr pFD;
|
||||
int64_t pgno;
|
||||
uint8_t *pBuf;
|
||||
int64_t szFile;
|
||||
} STsdbFD;
|
||||
|
||||
struct SDelFWriter {
|
||||
STsdb *pTsdb;
|
||||
SDelFile fDel;
|
||||
TdFilePtr pWriteH;
|
||||
|
||||
STsdb *pTsdb;
|
||||
SDelFile fDel;
|
||||
STsdbFD *pWriteH;
|
||||
uint8_t *aBuf[1];
|
||||
};
|
||||
|
||||
struct SDataFWriter {
|
||||
STsdb *pTsdb;
|
||||
SDFileSet wSet;
|
||||
|
||||
TdFilePtr pHeadFD;
|
||||
TdFilePtr pDataFD;
|
||||
TdFilePtr pLastFD;
|
||||
TdFilePtr pSmaFD;
|
||||
|
||||
SHeadFile fHead;
|
||||
SDataFile fData;
|
||||
SLastFile fLast;
|
||||
SSmaFile fSma;
|
||||
|
||||
uint8_t *aBuf[4];
|
||||
};
|
||||
|
||||
struct STsdbReadSnap {
|
||||
SMemTable *pMem;
|
||||
SMemTable *pIMem;
|
||||
STsdbFS fs;
|
||||
};
|
||||
|
||||
struct SDataFWriter {
|
||||
STsdb *pTsdb;
|
||||
SDFileSet wSet;
|
||||
|
||||
STsdbFD *pHeadFD;
|
||||
STsdbFD *pDataFD;
|
||||
STsdbFD *pSmaFD;
|
||||
STsdbFD *pSttFD;
|
||||
|
||||
SHeadFile fHead;
|
||||
SDataFile fData;
|
||||
SSmaFile fSma;
|
||||
SSttFile fStt[TSDB_MAX_STT_TRIGGER];
|
||||
|
||||
uint8_t *aBuf[4];
|
||||
};
|
||||
|
||||
struct SDataFReader {
|
||||
STsdb *pTsdb;
|
||||
SDFileSet *pSet;
|
||||
STsdbFD *pHeadFD;
|
||||
STsdbFD *pDataFD;
|
||||
STsdbFD *pSmaFD;
|
||||
STsdbFD *aSttFD[TSDB_MAX_STT_TRIGGER];
|
||||
uint8_t *aBuf[3];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
TSDBROW row;
|
||||
} SRowInfo;
|
||||
|
||||
typedef struct SSttBlockLoadInfo {
|
||||
SBlockData blockData[2];
|
||||
SArray *aSttBlk;
|
||||
int32_t blockIndex[2]; // to denote the loaded block in the corresponding position.
|
||||
int32_t currentLoadBlockIndex;
|
||||
int32_t loadBlocks;
|
||||
double elapsedTime;
|
||||
} SSttBlockLoadInfo;
|
||||
|
||||
typedef struct SMergeTree {
|
||||
int8_t backward;
|
||||
SRBTree rbt;
|
||||
SArray *pIterList;
|
||||
SLDataIter *pIter;
|
||||
bool destroyLoadInfo;
|
||||
SSttBlockLoadInfo *pLoadInfo;
|
||||
const char *idStr;
|
||||
} SMergeTree;
|
||||
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
STSchema *pTSchema;
|
||||
} SSkmInfo;
|
||||
|
||||
int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFReader, uint64_t suid, uint64_t uid,
|
||||
STimeWindow *pTimeWindow, SVersionRange *pVerRange, void *pLoadInfo, const char *idStr);
|
||||
void tMergeTreeAddIter(SMergeTree *pMTree, SLDataIter *pIter);
|
||||
bool tMergeTreeNext(SMergeTree *pMTree);
|
||||
TSDBROW tMergeTreeGetRow(SMergeTree *pMTree);
|
||||
void tMergeTreeClose(SMergeTree *pMTree);
|
||||
|
||||
SSttBlockLoadInfo *tCreateLastBlockLoadInfo();
|
||||
void resetLastBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo);
|
||||
void getLastBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo, int64_t *blocks, double *el);
|
||||
void *destroyLastBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo);
|
||||
|
||||
// ========== inline functions ==========
|
||||
static FORCE_INLINE int32_t tsdbKeyCmprFn(const void *p1, const void *p2) {
|
||||
TSDBKEY *pKey1 = (TSDBKEY *)p1;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "tlosertree.h"
|
||||
#include "tlrucache.h"
|
||||
#include "tmsgcb.h"
|
||||
#include "trbtree.h"
|
||||
#include "tref.h"
|
||||
#include "tskiplist.h"
|
||||
#include "tstream.h"
|
||||
|
@ -70,8 +71,8 @@ typedef struct SStreamTaskReader SStreamTaskReader;
|
|||
typedef struct SStreamTaskWriter SStreamTaskWriter;
|
||||
typedef struct SStreamStateReader SStreamStateReader;
|
||||
typedef struct SStreamStateWriter SStreamStateWriter;
|
||||
typedef struct SRsmaSnapReader SRsmaSnapReader;
|
||||
typedef struct SRsmaSnapWriter SRsmaSnapWriter;
|
||||
typedef struct SRSmaSnapReader SRSmaSnapReader;
|
||||
typedef struct SRSmaSnapWriter SRSmaSnapWriter;
|
||||
typedef struct SSnapDataHdr SSnapDataHdr;
|
||||
|
||||
#define VNODE_META_DIR "meta"
|
||||
|
@ -102,8 +103,8 @@ int metaCommit(SMeta* pMeta);
|
|||
int metaCreateSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq);
|
||||
int metaAlterSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq);
|
||||
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq, SArray* tbUidList);
|
||||
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq, STableMetaRsp **pMetaRsp);
|
||||
int metaDropTable(SMeta* pMeta, int64_t version, SVDropTbReq* pReq, SArray* tbUids);
|
||||
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq, STableMetaRsp** pMetaRsp);
|
||||
int metaDropTable(SMeta* pMeta, int64_t version, SVDropTbReq* pReq, SArray* tbUids, int64_t* tbUid);
|
||||
int metaTtlDropTable(SMeta* pMeta, int64_t ttl, SArray* tbUids);
|
||||
int metaAlterTable(SMeta* pMeta, int64_t version, SVAlterTbReq* pReq, STableMetaRsp* pMetaRsp);
|
||||
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, bool isinline);
|
||||
|
@ -173,7 +174,8 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg);
|
|||
// tq-stream
|
||||
int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessTaskDropReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* data, int64_t ver);
|
||||
int32_t tqProcessSubmitReq(STQ* pTq, SSubmitReq* data, int64_t ver);
|
||||
int32_t tqProcessDelReq(STQ* pTq, void* pReq, int32_t len, int64_t ver);
|
||||
int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg, bool exec);
|
||||
int32_t tqProcessTaskRecoverReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
|
@ -206,7 +208,7 @@ int32_t tdProcessRSmaCreate(SSma* pSma, SVCreateStbReq* pReq);
|
|||
int32_t tdProcessRSmaSubmit(SSma* pSma, void* pMsg, int32_t inputType);
|
||||
int32_t tdProcessRSmaDrop(SSma* pSma, SVDropStbReq* pReq);
|
||||
int32_t tdFetchTbUidList(SSma* pSma, STbUidStore** ppStore, tb_uid_t suid, tb_uid_t uid);
|
||||
int32_t tdUpdateTbUidList(SSma* pSma, STbUidStore* pUidStore);
|
||||
int32_t tdUpdateTbUidList(SSma* pSma, STbUidStore* pUidStore, bool isAdd);
|
||||
void tdUidStoreDestory(STbUidStore* pStore);
|
||||
void* tdUidStoreFree(STbUidStore* pStore);
|
||||
|
||||
|
@ -246,14 +248,14 @@ int32_t tqOffsetSnapWrite(STqOffsetWriter* pWriter, uint8_t* pData, uint32_t nDa
|
|||
// SStreamTaskReader ======================================
|
||||
// SStreamStateWriter =====================================
|
||||
// SStreamStateReader =====================================
|
||||
// SRsmaSnapReader ========================================
|
||||
int32_t rsmaSnapReaderOpen(SSma* pSma, int64_t sver, int64_t ever, SRsmaSnapReader** ppReader);
|
||||
int32_t rsmaSnapReaderClose(SRsmaSnapReader** ppReader);
|
||||
int32_t rsmaSnapRead(SRsmaSnapReader* pReader, uint8_t** ppData);
|
||||
// SRsmaSnapWriter ========================================
|
||||
int32_t rsmaSnapWriterOpen(SSma* pSma, int64_t sver, int64_t ever, SRsmaSnapWriter** ppWriter);
|
||||
int32_t rsmaSnapWrite(SRsmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData);
|
||||
int32_t rsmaSnapWriterClose(SRsmaSnapWriter** ppWriter, int8_t rollback);
|
||||
// SRSmaSnapReader ========================================
|
||||
int32_t rsmaSnapReaderOpen(SSma* pSma, int64_t sver, int64_t ever, SRSmaSnapReader** ppReader);
|
||||
int32_t rsmaSnapReaderClose(SRSmaSnapReader** ppReader);
|
||||
int32_t rsmaSnapRead(SRSmaSnapReader* pReader, uint8_t** ppData);
|
||||
// SRSmaSnapWriter ========================================
|
||||
int32_t rsmaSnapWriterOpen(SSma* pSma, int64_t sver, int64_t ever, SRSmaSnapWriter** ppWriter);
|
||||
int32_t rsmaSnapWrite(SRSmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData);
|
||||
int32_t rsmaSnapWriterClose(SRSmaSnapWriter** ppWriter, int8_t rollback);
|
||||
|
||||
typedef struct {
|
||||
int8_t streamType; // sma or other
|
||||
|
|
|
@ -129,10 +129,16 @@ _err:
|
|||
|
||||
bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid) {
|
||||
// query uid.idx
|
||||
metaRLock(pMeta);
|
||||
|
||||
if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), NULL, NULL) < 0) {
|
||||
metaULock(pMeta);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
metaULock(pMeta);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -182,9 +188,14 @@ tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name) {
|
|||
}
|
||||
|
||||
int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName) {
|
||||
int code = 0;
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, (SMeta *)meta, 0);
|
||||
metaGetTableEntryByUid(&mr, uid);
|
||||
code = metaGetTableEntryByUid(&mr, uid);
|
||||
if (code < 0) {
|
||||
metaReaderClear(&mr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STR_TO_VARSTR(tbName, mr.me.name);
|
||||
metaReaderClear(&mr);
|
||||
|
|
|
@ -416,20 +416,22 @@ int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMe
|
|||
me.ctbEntry.pTags = pReq->ctb.pTag;
|
||||
|
||||
#ifdef TAG_FILTER_DEBUG
|
||||
SArray* pTagVals = NULL;
|
||||
int32_t code = tTagToValArray((STag*)pReq->ctb.pTag, &pTagVals);
|
||||
SArray *pTagVals = NULL;
|
||||
int32_t code = tTagToValArray((STag *)pReq->ctb.pTag, &pTagVals);
|
||||
for (int i = 0; i < taosArrayGetSize(pTagVals); i++) {
|
||||
STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, i);
|
||||
STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pTagVal->type)) {
|
||||
char* buf = taosMemoryCalloc(pTagVal->nData + 1, 1);
|
||||
char *buf = taosMemoryCalloc(pTagVal->nData + 1, 1);
|
||||
memcpy(buf, pTagVal->pData, pTagVal->nData);
|
||||
metaDebug("metaTag table:%s varchar index:%d cid:%d type:%d value:%s", pReq->name, i, pTagVal->cid, pTagVal->type, buf);
|
||||
metaDebug("metaTag table:%s varchar index:%d cid:%d type:%d value:%s", pReq->name, i, pTagVal->cid,
|
||||
pTagVal->type, buf);
|
||||
taosMemoryFree(buf);
|
||||
} else {
|
||||
double val = 0;
|
||||
GET_TYPED_DATA(val, double, pTagVal->type, &pTagVal->i64);
|
||||
metaDebug("metaTag table:%s number index:%d cid:%d type:%d value:%f", pReq->name, i, pTagVal->cid, pTagVal->type, val);
|
||||
metaDebug("metaTag table:%s number index:%d cid:%d type:%d value:%f", pReq->name, i, pTagVal->cid,
|
||||
pTagVal->type, val);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -474,7 +476,7 @@ _err:
|
|||
return -1;
|
||||
}
|
||||
|
||||
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUids) {
|
||||
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUids, tb_uid_t *tbUid) {
|
||||
void *pData = NULL;
|
||||
int nData = 0;
|
||||
int rc = 0;
|
||||
|
@ -496,6 +498,10 @@ int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUi
|
|||
taosArrayPush(tbUids, &uid);
|
||||
}
|
||||
|
||||
if ((type == TSDB_CHILD_TABLE) && tbUid) {
|
||||
*tbUid = uid;
|
||||
}
|
||||
|
||||
tdbFree(pData);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
|
||||
#include "sma.h"
|
||||
|
||||
extern SSmaMgmt smaMgmt;
|
||||
|
||||
static int32_t tdProcessRSmaSyncPreCommitImpl(SSma *pSma);
|
||||
static int32_t tdProcessRSmaSyncCommitImpl(SSma *pSma);
|
||||
static int32_t tdProcessRSmaSyncPostCommitImpl(SSma *pSma);
|
||||
static int32_t tdProcessRSmaAsyncPreCommitImpl(SSma *pSma);
|
||||
static int32_t tdProcessRSmaAsyncCommitImpl(SSma *pSma);
|
||||
static int32_t tdProcessRSmaAsyncPostCommitImpl(SSma *pSma);
|
||||
static int32_t tdCleanupQTaskInfoFiles(SSma *pSma, SRSmaStat *pRSmaStat);
|
||||
static int32_t tdUpdateQTaskInfoFiles(SSma *pSma, SRSmaStat *pRSmaStat);
|
||||
|
||||
/**
|
||||
* @brief Only applicable to Rollup SMA
|
||||
|
@ -166,114 +168,65 @@ static int32_t tdProcessRSmaSyncCommitImpl(SSma *pSma) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tdCleanupQTaskInfoFiles(SSma *pSma, SRSmaStat *pRSmaStat) {
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
int64_t committed = pRSmaStat->commitAppliedVer;
|
||||
TdDirPtr pDir = NULL;
|
||||
TdDirEntryPtr pDirEntry = NULL;
|
||||
char dir[TSDB_FILENAME_LEN];
|
||||
const char *pattern = "v[0-9]+qinf\\.v([0-9]+)?$";
|
||||
regex_t regex;
|
||||
int code = 0;
|
||||
|
||||
tdGetVndDirName(TD_VID(pVnode), tfsGetPrimaryPath(pVnode->pTfs), VNODE_RSMA_DIR, true, dir);
|
||||
|
||||
// Resource allocation and init
|
||||
if ((code = regcomp(®ex, pattern, REG_EXTENDED)) != 0) {
|
||||
char errbuf[128];
|
||||
regerror(code, ®ex, errbuf, sizeof(errbuf));
|
||||
smaWarn("vgId:%d, rsma post commit, regcomp for %s failed since %s", TD_VID(pVnode), dir, errbuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if ((pDir = taosOpenDir(dir)) == NULL) {
|
||||
regfree(®ex);
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
smaDebug("vgId:%d, rsma post commit, open dir %s failed since %s", TD_VID(pVnode), dir, terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
int32_t dirLen = strlen(dir);
|
||||
char *dirEnd = POINTER_SHIFT(dir, dirLen);
|
||||
regmatch_t regMatch[2];
|
||||
while ((pDirEntry = taosReadDir(pDir)) != NULL) {
|
||||
char *entryName = taosGetDirEntryName(pDirEntry);
|
||||
if (!entryName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
code = regexec(®ex, entryName, 2, regMatch, 0);
|
||||
|
||||
if (code == 0) {
|
||||
// match
|
||||
int64_t version = -1;
|
||||
sscanf((const char *)POINTER_SHIFT(entryName, regMatch[1].rm_so), "%" PRIi64, &version);
|
||||
if ((version < committed) && (version > -1)) {
|
||||
strncpy(dirEnd, entryName, TSDB_FILENAME_LEN - dirLen);
|
||||
if (taosRemoveFile(dir) != 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
smaWarn("vgId:%d, committed version:%" PRIi64 ", failed to remove %s since %s", TD_VID(pVnode), committed,
|
||||
dir, terrstr());
|
||||
} else {
|
||||
smaDebug("vgId:%d, committed version:%" PRIi64 ", success to remove %s", TD_VID(pVnode), committed, dir);
|
||||
}
|
||||
}
|
||||
} else if (code == REG_NOMATCH) {
|
||||
// not match
|
||||
smaTrace("vgId:%d, rsma post commit, not match %s", TD_VID(pVnode), entryName);
|
||||
continue;
|
||||
} else {
|
||||
// has other error
|
||||
char errbuf[128];
|
||||
regerror(code, ®ex, errbuf, sizeof(errbuf));
|
||||
smaWarn("vgId:%d, rsma post commit, regexec failed since %s", TD_VID(pVnode), errbuf);
|
||||
|
||||
taosCloseDir(&pDir);
|
||||
regfree(®ex);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
taosCloseDir(&pDir);
|
||||
regfree(®ex);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// SQTaskFile ======================================================
|
||||
// int32_t tCmprQTaskFile(void const *lhs, void const *rhs) {
|
||||
// int64_t *lCommitted = *(int64_t *)lhs;
|
||||
// SQTaskFile *rQTaskF = (SQTaskFile *)rhs;
|
||||
|
||||
// if (lCommitted < rQTaskF->commitID) {
|
||||
// return -1;
|
||||
// } else if (lCommitted > rQTaskF->commitID) {
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* @brief At most time, there is only one qtaskinfo file committed latest in aTaskFile. Sometimes, there would be
|
||||
* multiple qtaskinfo files supporting snapshot replication.
|
||||
*
|
||||
* @param pSma
|
||||
* @param pRSmaStat
|
||||
* @param pStat
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tdCleanupQTaskInfoFiles(SSma *pSma, SRSmaStat *pRSmaStat) {
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
int64_t committed = pRSmaStat->commitAppliedVer;
|
||||
SArray *aTaskFile = pRSmaStat->aTaskFile;
|
||||
static int32_t tdUpdateQTaskInfoFiles(SSma *pSma, SRSmaStat *pStat) {
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
SRSmaFS *pFS = RSMA_FS(pStat);
|
||||
int64_t committed = pStat->commitAppliedVer;
|
||||
int64_t fsMaxVer = -1;
|
||||
char qTaskInfoFullName[TSDB_FILENAME_LEN];
|
||||
|
||||
void *qTaskFile = taosArraySearch(aTaskFile, committed, tCmprQTaskFile, TD_LE);
|
||||
|
||||
taosWLockLatch(RSMA_FS_LOCK(pStat));
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pFS->aQTaskInf);) {
|
||||
SQTaskFile *pTaskF = taosArrayGet(pFS->aQTaskInf, i);
|
||||
int32_t oldVal = atomic_fetch_sub_32(&pTaskF->nRef, 1);
|
||||
if ((oldVal <= 1) && (pTaskF->version < committed)) {
|
||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pTaskF->version, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFullName);
|
||||
if (taosRemoveFile(qTaskInfoFullName) < 0) {
|
||||
smaWarn("vgId:%d, cleanup qinf, committed %" PRIi64 ", failed to remove %s since %s", TD_VID(pVnode), committed,
|
||||
qTaskInfoFullName, tstrerror(TAOS_SYSTEM_ERROR(errno)));
|
||||
} else {
|
||||
smaDebug("vgId:%d, cleanup qinf, committed %" PRIi64 ", success to remove %s", TD_VID(pVnode), committed,
|
||||
qTaskInfoFullName);
|
||||
}
|
||||
taosArrayRemove(pFS->aQTaskInf, i);
|
||||
continue;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pFS->aQTaskInf) > 0) {
|
||||
fsMaxVer = ((SQTaskFile *)taosArrayGetLast(pFS->aQTaskInf))->version;
|
||||
}
|
||||
|
||||
if (fsMaxVer < committed) {
|
||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), committed, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFullName);
|
||||
if (taosCheckExistFile(qTaskInfoFullName)) {
|
||||
SQTaskFile qFile = {.nRef = 1, .padding = 0, .version = committed, .size = 0};
|
||||
if (taosArrayPush(pFS->aQTaskInf, &qFile) < 0) {
|
||||
taosWUnLockLatch(RSMA_FS_LOCK(pStat));
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
smaDebug("vgId:%d, update qinf, no need as committed %" PRIi64 " not larger than fsMaxVer %" PRIi64, TD_VID(pVnode),
|
||||
committed, fsMaxVer);
|
||||
}
|
||||
|
||||
taosWUnLockLatch(RSMA_FS_LOCK(pStat));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief post-commit for rollup sma
|
||||
|
@ -290,8 +243,7 @@ static int32_t tdProcessRSmaSyncPostCommitImpl(SSma *pSma) {
|
|||
|
||||
SRSmaStat *pRSmaStat = SMA_RSMA_STAT(pSma);
|
||||
|
||||
// cleanup outdated qtaskinfo files
|
||||
tdCleanupQTaskInfoFiles(pSma, pRSmaStat);
|
||||
tdUpdateQTaskInfoFiles(pSma, pRSmaStat);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -365,12 +317,12 @@ static int32_t tdProcessRSmaAsyncPreCommitImpl(SSma *pSma) {
|
|||
if (tdRSmaPersistExecImpl(pRSmaStat, RSMA_INFO_HASH(pRSmaStat)) < 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
smaInfo("vgId:%d, rsma commit, operator state commited, TID:%p", SMA_VID(pSma), (void *)taosGetSelfPthreadId());
|
||||
smaInfo("vgId:%d, rsma commit, operator state committed, TID:%p", SMA_VID(pSma), (void *)taosGetSelfPthreadId());
|
||||
|
||||
#if 0 // consuming task of qTaskInfo clone
|
||||
// step 4: swap queue/qall and iQueue/iQall
|
||||
// lock
|
||||
// taosWLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
taosWLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
|
||||
ASSERT(RSMA_INFO_HASH(pRSmaStat));
|
||||
|
||||
|
@ -386,7 +338,7 @@ static int32_t tdProcessRSmaAsyncPreCommitImpl(SSma *pSma) {
|
|||
}
|
||||
|
||||
// unlock
|
||||
// taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
#endif
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -428,33 +380,29 @@ static int32_t tdProcessRSmaAsyncPostCommitImpl(SSma *pSma) {
|
|||
}
|
||||
|
||||
SRSmaStat *pRSmaStat = (SRSmaStat *)SMA_ENV_STAT(pEnv);
|
||||
SArray *rsmaDeleted = NULL;
|
||||
|
||||
// step 1: merge qTaskInfo and iQTaskInfo
|
||||
// lock
|
||||
// taosWLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
if (1 == atomic_val_compare_exchange_8(&pRSmaStat->delFlag, 1, 0)) {
|
||||
taosWLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
|
||||
void *pIter = NULL;
|
||||
while ((pIter = taosHashIterate(RSMA_INFO_HASH(pRSmaStat), pIter))) {
|
||||
tb_uid_t *pSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
|
||||
SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)pIter;
|
||||
if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
|
||||
int32_t refVal = T_REF_VAL_GET(pRSmaInfo);
|
||||
if (refVal == 0) {
|
||||
if (!rsmaDeleted) {
|
||||
if ((rsmaDeleted = taosArrayInit(1, sizeof(tb_uid_t)))) {
|
||||
taosArrayPush(rsmaDeleted, pSuid);
|
||||
}
|
||||
void *pIter = NULL;
|
||||
while ((pIter = taosHashIterate(RSMA_INFO_HASH(pRSmaStat), pIter))) {
|
||||
tb_uid_t *pSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
|
||||
SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)pIter;
|
||||
if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
|
||||
int32_t refVal = T_REF_VAL_GET(pRSmaInfo);
|
||||
if (refVal == 0) {
|
||||
taosHashRemove(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(*pSuid));
|
||||
} else {
|
||||
smaDebug(
|
||||
"vgId:%d, rsma async post commit, not free rsma info since ref is %d although already deleted for "
|
||||
"table:%" PRIi64,
|
||||
SMA_VID(pSma), refVal, *pSuid);
|
||||
}
|
||||
} else {
|
||||
smaDebug(
|
||||
"vgId:%d, rsma async post commit, not free rsma info since ref is %d although already deleted for "
|
||||
"table:%" PRIi64,
|
||||
SMA_VID(pSma), refVal, *pSuid);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
if (pRSmaInfo->taskInfo[0]) {
|
||||
if (pRSmaInfo->iTaskInfo[0]) {
|
||||
|
@ -469,27 +417,13 @@ static int32_t tdProcessRSmaAsyncPostCommitImpl(SSma *pSma) {
|
|||
taosHashPut(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(tb_uid_t), pIter, sizeof(pIter));
|
||||
smaDebug("vgId:%d, rsma async post commit, migrated from iRsmaInfoHash for table:%" PRIi64, SMA_VID(pSma), *pSuid);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(rsmaDeleted); ++i) {
|
||||
tb_uid_t *pSuid = taosArrayGet(rsmaDeleted, i);
|
||||
void *pRSmaInfo = taosHashGet(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(tb_uid_t));
|
||||
if ((pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
|
||||
tdFreeRSmaInfo(pSma, pRSmaInfo, true);
|
||||
smaDebug(
|
||||
"vgId:%d, rsma async post commit, free rsma info since already deleted and ref is 0 for "
|
||||
"table:%" PRIi64,
|
||||
SMA_VID(pSma), *pSuid);
|
||||
}
|
||||
taosHashRemove(RSMA_INFO_HASH(pRSmaStat), pSuid, sizeof(tb_uid_t));
|
||||
|
||||
// unlock
|
||||
taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
}
|
||||
taosArrayDestroy(rsmaDeleted);
|
||||
|
||||
// unlock
|
||||
// taosWUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
|
||||
// step 2: cleanup outdated qtaskinfo files
|
||||
tdCleanupQTaskInfoFiles(pSma, pRSmaStat);
|
||||
tdUpdateQTaskInfoFiles(pSma, pRSmaStat);
|
||||
|
||||
atomic_store_8(RSMA_COMMIT_STAT(pRSmaStat), 0);
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ static int32_t tdInitSmaEnv(SSma *pSma, int8_t smaType, SSmaEnv **ppEnv);
|
|||
static int32_t tdInitSmaStat(SSmaStat **pSmaStat, int8_t smaType, const SSma *pSma);
|
||||
static int32_t tdRsmaStartExecutor(const SSma *pSma);
|
||||
static int32_t tdRsmaStopExecutor(const SSma *pSma);
|
||||
static int32_t tdDestroySmaState(SSmaStat *pSmaStat, int8_t smaType);
|
||||
static void *tdFreeSmaState(SSmaStat *pSmaStat, int8_t smaType);
|
||||
static void *tdFreeTSmaStat(STSmaStat *pStat);
|
||||
static void tdDestroyRSmaStat(void *pRSmaStat);
|
||||
|
||||
|
@ -59,12 +61,23 @@ int32_t smaInit() {
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
int32_t type = (8 == POINTER_BYTES) ? TSDB_DATA_TYPE_UBIGINT : TSDB_DATA_TYPE_UINT;
|
||||
smaMgmt.refHash = taosHashInit(64, taosGetDefaultHashFunction(type), true, HASH_ENTRY_LOCK);
|
||||
if (!smaMgmt.refHash) {
|
||||
taosCloseRef(smaMgmt.rsetId);
|
||||
atomic_store_8(&smaMgmt.inited, 0);
|
||||
smaError("failed to init sma tmr hanle since %s", terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
// init fetch timer handle
|
||||
smaMgmt.tmrHandle = taosTmrInit(10000, 100, 10000, "RSMA");
|
||||
if (!smaMgmt.tmrHandle) {
|
||||
taosCloseRef(smaMgmt.rsetId);
|
||||
taosHashCleanup(smaMgmt.refHash);
|
||||
smaMgmt.refHash = NULL;
|
||||
atomic_store_8(&smaMgmt.inited, 0);
|
||||
smaError("failed to init sma tmr hanle since %s", terrstr());
|
||||
smaError("failed to init sma tmr handle since %s", terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -93,6 +106,8 @@ void smaCleanUp() {
|
|||
|
||||
if (old == 1) {
|
||||
taosCloseRef(smaMgmt.rsetId);
|
||||
taosHashCleanup(smaMgmt.refHash);
|
||||
smaMgmt.refHash = NULL;
|
||||
taosTmrCleanUp(smaMgmt.tmrHandle);
|
||||
smaInfo("sma mgmt env is cleaned up, rsetId:%d, tmrHandle:%p", smaMgmt.rsetId, smaMgmt.tmrHandle);
|
||||
atomic_store_8(&smaMgmt.inited, 0);
|
||||
|
@ -162,37 +177,19 @@ void *tdFreeSmaEnv(SSmaEnv *pSmaEnv) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int32_t tdRefSmaStat(SSma *pSma, SSmaStat *pStat) {
|
||||
if (!pStat) return 0;
|
||||
static void tRSmaInfoHashFreeNode(void *data) {
|
||||
SRSmaInfo *pRSmaInfo = NULL;
|
||||
SRSmaInfoItem *pItem = NULL;
|
||||
|
||||
int ref = T_REF_INC(pStat);
|
||||
smaDebug("vgId:%d, ref sma stat:%p, val:%d", SMA_VID(pSma), pStat, ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tdUnRefSmaStat(SSma *pSma, SSmaStat *pStat) {
|
||||
if (!pStat) return 0;
|
||||
|
||||
int ref = T_REF_DEC(pStat);
|
||||
smaDebug("vgId:%d, unref sma stat:%p, val:%d", SMA_VID(pSma), pStat, ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tdRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo) {
|
||||
if (!pRSmaInfo) return 0;
|
||||
|
||||
int ref = T_REF_INC(pRSmaInfo);
|
||||
smaDebug("vgId:%d, ref rsma info:%p, val:%d", SMA_VID(pSma), pRSmaInfo, ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tdUnRefRSmaInfo(SSma *pSma, SRSmaInfo *pRSmaInfo) {
|
||||
if (!pRSmaInfo) return 0;
|
||||
|
||||
int ref = T_REF_DEC(pRSmaInfo);
|
||||
smaDebug("vgId:%d, unref rsma info:%p, val:%d", SMA_VID(pSma), pRSmaInfo, ref);
|
||||
|
||||
return 0;
|
||||
if ((pRSmaInfo = *(SRSmaInfo **)data)) {
|
||||
if ((pItem = RSMA_INFO_ITEM((SRSmaInfo *)pRSmaInfo, 0)) && pItem->level) {
|
||||
taosHashRemove(smaMgmt.refHash, &pItem, POINTER_BYTES);
|
||||
}
|
||||
if ((pItem = RSMA_INFO_ITEM((SRSmaInfo *)pRSmaInfo, 1)) && pItem->level) {
|
||||
taosHashRemove(smaMgmt.refHash, &pItem, POINTER_BYTES);
|
||||
}
|
||||
tdFreeRSmaInfo(pRSmaInfo->pSma, pRSmaInfo, true);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t tdInitSmaStat(SSmaStat **pSmaStat, int8_t smaType, const SSma *pSma) {
|
||||
|
@ -240,10 +237,16 @@ static int32_t tdInitSmaStat(SSmaStat **pSmaStat, int8_t smaType, const SSma *pS
|
|||
if (!RSMA_INFO_HASH(pRSmaStat)) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
taosHashSetFreeFp(RSMA_INFO_HASH(pRSmaStat), tRSmaInfoHashFreeNode);
|
||||
|
||||
if (tdRsmaStartExecutor(pSma) < 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (!(RSMA_FS(pRSmaStat)->aQTaskInf = taosArrayInit(1, sizeof(SQTaskFile)))) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
} else if (smaType == TSDB_SMA_TYPE_TIME_RANGE) {
|
||||
// TODO
|
||||
} else {
|
||||
|
@ -278,14 +281,6 @@ static void tdDestroyRSmaStat(void *pRSmaStat) {
|
|||
tsem_destroy(&(pStat->notEmpty));
|
||||
|
||||
// step 2: destroy the rsma info and associated fetch tasks
|
||||
if (taosHashGetSize(RSMA_INFO_HASH(pStat)) > 0) {
|
||||
void *infoHash = taosHashIterate(RSMA_INFO_HASH(pStat), NULL);
|
||||
while (infoHash) {
|
||||
SRSmaInfo *pSmaInfo = *(SRSmaInfo **)infoHash;
|
||||
tdFreeRSmaInfo(pSma, pSmaInfo, true);
|
||||
infoHash = taosHashIterate(RSMA_INFO_HASH(pStat), infoHash);
|
||||
}
|
||||
}
|
||||
taosHashCleanup(RSMA_INFO_HASH(pStat));
|
||||
|
||||
// step 3: wait for all triggered fetch tasks to finish
|
||||
|
@ -307,12 +302,15 @@ static void tdDestroyRSmaStat(void *pRSmaStat) {
|
|||
// step 4:
|
||||
tdRsmaStopExecutor(pSma);
|
||||
|
||||
// step 5: free pStat
|
||||
// step 5:
|
||||
tdRSmaFSClose(RSMA_FS(pStat));
|
||||
|
||||
// step 6: free pStat
|
||||
taosMemoryFreeClear(pStat);
|
||||
}
|
||||
}
|
||||
|
||||
void *tdFreeSmaState(SSmaStat *pSmaStat, int8_t smaType) {
|
||||
static void *tdFreeSmaState(SSmaStat *pSmaStat, int8_t smaType) {
|
||||
tdDestroySmaState(pSmaStat, smaType);
|
||||
if (smaType == TSDB_SMA_TYPE_TIME_RANGE) {
|
||||
taosMemoryFreeClear(pSmaStat);
|
||||
|
@ -329,7 +327,7 @@ void *tdFreeSmaState(SSmaStat *pSmaStat, int8_t smaType) {
|
|||
* @return int32_t
|
||||
*/
|
||||
|
||||
int32_t tdDestroySmaState(SSmaStat *pSmaStat, int8_t smaType) {
|
||||
static int32_t tdDestroySmaState(SSmaStat *pSmaStat, int8_t smaType) {
|
||||
if (pSmaStat) {
|
||||
if (smaType == TSDB_SMA_TYPE_TIME_RANGE) {
|
||||
tdDestroyTSmaStat(SMA_STAT_TSMA(pSmaStat));
|
||||
|
@ -337,7 +335,7 @@ int32_t tdDestroySmaState(SSmaStat *pSmaStat, int8_t smaType) {
|
|||
SRSmaStat *pRSmaStat = &pSmaStat->rsmaStat;
|
||||
int32_t vid = SMA_VID(pRSmaStat->pSma);
|
||||
int64_t refId = RSMA_REF_ID(pRSmaStat);
|
||||
if (taosRemoveRef(smaMgmt.rsetId, RSMA_REF_ID(pRSmaStat)) < 0) {
|
||||
if (taosRemoveRef(smaMgmt.rsetId, refId) < 0) {
|
||||
smaError("vgId:%d, remove refId:%" PRIi64 " from rsmaRef:%" PRIi32 " failed since %s", vid, refId,
|
||||
smaMgmt.rsetId, terrstr());
|
||||
} else {
|
||||
|
@ -461,6 +459,8 @@ static int32_t tdRsmaStopExecutor(const SSma *pSma) {
|
|||
taosThreadJoin(pthread[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
smaInfo("vgId:%d, rsma executor stopped, number:%d", SMA_VID(pSma), tsNumOfVnodeRsmaThreads);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sma.h"
|
||||
|
||||
// =================================================================================================
|
||||
|
||||
static int32_t tdFetchQTaskInfoFiles(SSma *pSma, int64_t version, SArray **output);
|
||||
static int32_t tdQTaskInfCmprFn1(const void *p1, const void *p2);
|
||||
static int32_t tdQTaskInfCmprFn2(const void *p1, const void *p2);
|
||||
/**
|
||||
* @brief Open RSma FS from qTaskInfo files
|
||||
*
|
||||
* @param pSma
|
||||
* @param version
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tdRSmaFSOpen(SSma *pSma, int64_t version) {
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
int64_t commitID = pVnode->state.commitID;
|
||||
SSmaEnv *pEnv = SMA_RSMA_ENV(pSma);
|
||||
SRSmaStat *pStat = NULL;
|
||||
SArray *output = NULL;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (!pEnv) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (tdFetchQTaskInfoFiles(pSma, version, &output) < 0) {
|
||||
goto _end;
|
||||
}
|
||||
|
||||
pStat = (SRSmaStat *)SMA_ENV_STAT(pEnv);
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(output); ++i) {
|
||||
int32_t vid = 0;
|
||||
int64_t version = -1;
|
||||
sscanf((const char *)taosArrayGetP(output, i), "v%dqinf.v%" PRIi64, &vid, &version);
|
||||
SQTaskFile qTaskFile = {.version = version, .nRef = 1};
|
||||
if ((terrno = tdRSmaFSUpsertQTaskFile(RSMA_FS(pStat), &qTaskFile)) < 0) {
|
||||
goto _end;
|
||||
}
|
||||
smaInfo("vgId:%d, open fs, version:%" PRIi64 ", ref:%" PRIi64, TD_VID(pVnode), qTaskFile.version, qTaskFile.nRef);
|
||||
}
|
||||
|
||||
_end:
|
||||
for (int32_t i = 0; i < taosArrayGetSize(output); ++i) {
|
||||
void *ptr = taosArrayGetP(output, i);
|
||||
taosMemoryFreeClear(ptr);
|
||||
}
|
||||
taosArrayDestroy(output);
|
||||
|
||||
if (terrno != TSDB_CODE_SUCCESS) {
|
||||
smaError("vgId:%d, open rsma fs failed since %s", TD_VID(pVnode), terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void tdRSmaFSClose(SRSmaFS *fs) { taosArrayDestroy(fs->aQTaskInf); }
|
||||
|
||||
static int32_t tdQTaskInfCmprFn1(const void *p1, const void *p2) {
|
||||
if (*(int64_t *)p1 < ((SQTaskFile *)p2)->version) {
|
||||
return -1;
|
||||
} else if (*(int64_t *)p1 > ((SQTaskFile *)p2)->version) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tdRSmaFSRef(SSma *pSma, SRSmaStat *pStat, int64_t version) {
|
||||
SArray *aQTaskInf = RSMA_FS(pStat)->aQTaskInf;
|
||||
SQTaskFile *pTaskF = NULL;
|
||||
int32_t oldVal = 0;
|
||||
|
||||
taosRLockLatch(RSMA_FS_LOCK(pStat));
|
||||
if ((pTaskF = taosArraySearch(aQTaskInf, &version, tdQTaskInfCmprFn1, TD_EQ))) {
|
||||
oldVal = atomic_fetch_add_32(&pTaskF->nRef, 1);
|
||||
ASSERT(oldVal > 0);
|
||||
}
|
||||
taosRUnLockLatch(RSMA_FS_LOCK(pStat));
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
int64_t tdRSmaFSMaxVer(SSma *pSma, SRSmaStat *pStat) {
|
||||
SArray *aQTaskInf = RSMA_FS(pStat)->aQTaskInf;
|
||||
int64_t version = -1;
|
||||
|
||||
taosRLockLatch(RSMA_FS_LOCK(pStat));
|
||||
if (taosArrayGetSize(aQTaskInf) > 0) {
|
||||
version = ((SQTaskFile *)taosArrayGetLast(aQTaskInf))->version;
|
||||
}
|
||||
taosRUnLockLatch(RSMA_FS_LOCK(pStat));
|
||||
return version;
|
||||
}
|
||||
|
||||
void tdRSmaFSUnRef(SSma *pSma, SRSmaStat *pStat, int64_t version) {
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
SArray *aQTaskInf = RSMA_FS(pStat)->aQTaskInf;
|
||||
char qTaskFullName[TSDB_FILENAME_LEN];
|
||||
SQTaskFile *pTaskF = NULL;
|
||||
int32_t idx = -1;
|
||||
|
||||
taosWLockLatch(RSMA_FS_LOCK(pStat));
|
||||
if ((idx = taosArraySearchIdx(aQTaskInf, &version, tdQTaskInfCmprFn1, TD_EQ)) >= 0) {
|
||||
ASSERT(idx < taosArrayGetSize(aQTaskInf));
|
||||
pTaskF = taosArrayGet(aQTaskInf, idx);
|
||||
if (atomic_sub_fetch_32(&pTaskF->nRef, 1) <= 0) {
|
||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), pTaskF->version, tfsGetPrimaryPath(pVnode->pTfs), qTaskFullName);
|
||||
if (taosRemoveFile(qTaskFullName) < 0) {
|
||||
smaWarn("vgId:%d, failed to remove %s since %s", TD_VID(pVnode), qTaskFullName,
|
||||
tstrerror(TAOS_SYSTEM_ERROR(errno)));
|
||||
} else {
|
||||
smaDebug("vgId:%d, success to remove %s", TD_VID(pVnode), qTaskFullName);
|
||||
}
|
||||
taosArrayRemove(aQTaskInf, idx);
|
||||
}
|
||||
}
|
||||
taosWUnLockLatch(RSMA_FS_LOCK(pStat));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetch qtaskfiles LE than version
|
||||
*
|
||||
* @param pSma
|
||||
* @param version
|
||||
* @param output
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tdFetchQTaskInfoFiles(SSma *pSma, int64_t version, SArray **output) {
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
TdDirPtr pDir = NULL;
|
||||
TdDirEntryPtr pDirEntry = NULL;
|
||||
char dir[TSDB_FILENAME_LEN];
|
||||
const char *pattern = "v[0-9]+qinf\\.v([0-9]+)?$";
|
||||
regex_t regex;
|
||||
int code = 0;
|
||||
|
||||
tdGetVndDirName(TD_VID(pVnode), tfsGetPrimaryPath(pVnode->pTfs), VNODE_RSMA_DIR, true, dir);
|
||||
|
||||
if (!taosCheckExistFile(dir)) {
|
||||
smaDebug("vgId:%d, fetch qtask files, no need as dir %s not exist", TD_VID(pVnode), dir);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// Resource allocation and init
|
||||
if ((code = regcomp(®ex, pattern, REG_EXTENDED)) != 0) {
|
||||
terrno = TSDB_CODE_RSMA_REGEX_MATCH;
|
||||
char errbuf[128];
|
||||
regerror(code, ®ex, errbuf, sizeof(errbuf));
|
||||
smaWarn("vgId:%d, fetch qtask files, regcomp for %s failed since %s", TD_VID(pVnode), dir, errbuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (!(pDir = taosOpenDir(dir))) {
|
||||
regfree(®ex);
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
smaError("vgId:%d, fetch qtask files, open dir %s failed since %s", TD_VID(pVnode), dir, terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
int32_t dirLen = strlen(dir);
|
||||
char *dirEnd = POINTER_SHIFT(dir, dirLen);
|
||||
regmatch_t regMatch[2];
|
||||
while ((pDirEntry = taosReadDir(pDir))) {
|
||||
char *entryName = taosGetDirEntryName(pDirEntry);
|
||||
if (!entryName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
code = regexec(®ex, entryName, 2, regMatch, 0);
|
||||
|
||||
if (code == 0) {
|
||||
// match
|
||||
smaInfo("vgId:%d, fetch qtask files, max ver:%" PRIi64 ", %s found", TD_VID(pVnode), version, entryName);
|
||||
|
||||
int64_t ver = -1;
|
||||
sscanf((const char *)POINTER_SHIFT(entryName, regMatch[1].rm_so), "%" PRIi64, &ver);
|
||||
if ((ver <= version) && (ver > -1)) {
|
||||
if (!(*output)) {
|
||||
if (!(*output = taosArrayInit(1, POINTER_BYTES))) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
char *entryDup = strdup(entryName);
|
||||
if (!entryDup) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
if (!taosArrayPush(*output, &entryDup)) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else if (code == REG_NOMATCH) {
|
||||
// not match
|
||||
smaTrace("vgId:%d, fetch qtask files, not match %s", TD_VID(pVnode), entryName);
|
||||
continue;
|
||||
} else {
|
||||
// has other error
|
||||
char errbuf[128];
|
||||
regerror(code, ®ex, errbuf, sizeof(errbuf));
|
||||
smaWarn("vgId:%d, fetch qtask files, regexec failed since %s", TD_VID(pVnode), errbuf);
|
||||
terrno = TSDB_CODE_RSMA_REGEX_MATCH;
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
_end:
|
||||
taosCloseDir(&pDir);
|
||||
regfree(®ex);
|
||||
return terrno == 0 ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
static int32_t tdQTaskFileCmprFn2(const void *p1, const void *p2) {
|
||||
if (((SQTaskFile *)p1)->version < ((SQTaskFile *)p2)->version) {
|
||||
return -1;
|
||||
} else if (((SQTaskFile *)p1)->version > ((SQTaskFile *)p2)->version) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tdRSmaFSUpsertQTaskFile(SRSmaFS *pFS, SQTaskFile *qTaskFile) {
|
||||
int32_t code = 0;
|
||||
int32_t idx = taosArraySearchIdx(pFS->aQTaskInf, qTaskFile, tdQTaskFileCmprFn2, TD_GE);
|
||||
|
||||
if (idx < 0) {
|
||||
idx = taosArrayGetSize(pFS->aQTaskInf);
|
||||
} else {
|
||||
SQTaskFile *pTaskF = (SQTaskFile *)taosArrayGet(pFS->aQTaskInf, idx);
|
||||
int32_t c = tdQTaskFileCmprFn2(pTaskF, qTaskFile);
|
||||
if (c == 0) {
|
||||
pTaskF->nRef = qTaskFile->nRef;
|
||||
pTaskF->version = qTaskFile->version;
|
||||
pTaskF->size = qTaskFile->size;
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (taosArrayInsert(pFS->aQTaskInf, idx, qTaskFile) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
|
@ -150,7 +150,7 @@ int32_t smaOpen(SVnode *pVnode) {
|
|||
}
|
||||
|
||||
// restore the rsma
|
||||
if (tdRsmaRestore(pSma, RSMA_RESTORE_REBOOT, pVnode->state.committed) < 0) {
|
||||
if (tdRSmaRestore(pSma, RSMA_RESTORE_REBOOT, pVnode->state.committed) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
@ -181,8 +181,8 @@ int32_t smaClose(SSma *pSma) {
|
|||
* @param committedVer
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tdRsmaRestore(SSma *pSma, int8_t type, int64_t committedVer) {
|
||||
int32_t tdRSmaRestore(SSma *pSma, int8_t type, int64_t committedVer) {
|
||||
ASSERT(VND_IS_RSMA(pSma->pVnode));
|
||||
|
||||
return tdProcessRSmaRestoreImpl(pSma, type, committedVer);
|
||||
return tdRSmaProcessRestoreImpl(pSma, type, committedVer);
|
||||
}
|
|
@ -19,8 +19,8 @@
|
|||
#define RSMA_QTASKINFO_HEAD_LEN (sizeof(int32_t) + sizeof(int8_t) + sizeof(int64_t)) // len + type + suid
|
||||
#define RSMA_QTASKEXEC_SMOOTH_SIZE (100) // cnt
|
||||
#define RSMA_SUBMIT_BATCH_SIZE (1024) // cnt
|
||||
#define RSMA_FETCH_DELAY_MAX (900000) // ms
|
||||
#define RSMA_FETCH_ACTIVE_MAX (1800) // ms
|
||||
#define RSMA_FETCH_DELAY_MAX (120000) // ms
|
||||
#define RSMA_FETCH_ACTIVE_MAX (1000) // ms
|
||||
#define RSMA_FETCH_INTERVAL (5000) // ms
|
||||
|
||||
SSmaMgmt smaMgmt = {
|
||||
|
@ -34,7 +34,7 @@ typedef struct SRSmaQTaskInfoItem SRSmaQTaskInfoItem;
|
|||
typedef struct SRSmaQTaskInfoIter SRSmaQTaskInfoIter;
|
||||
|
||||
static int32_t tdUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid);
|
||||
static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids);
|
||||
static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids, bool isAdd);
|
||||
static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat *pStat, SRSmaInfo *pRSmaInfo,
|
||||
int8_t idx);
|
||||
static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSize, int32_t inputType, SRSmaInfo *pInfo,
|
||||
|
@ -42,10 +42,12 @@ static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSiz
|
|||
static SRSmaInfo *tdAcquireRSmaInfoBySuid(SSma *pSma, int64_t suid);
|
||||
static void tdReleaseRSmaInfo(SSma *pSma, SRSmaInfo *pInfo);
|
||||
static void tdFreeRSmaSubmitItems(SArray *pItems);
|
||||
static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo, SArray *pSubmitArr);
|
||||
static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo);
|
||||
static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSmaInfoItem *pItem, STSchema *pTSchema,
|
||||
int64_t suid);
|
||||
static void tdRSmaFetchTrigger(void *param, void *tmrId);
|
||||
static int32_t tdRSmaInfoClone(SSma *pSma, SRSmaInfo *pInfo);
|
||||
static void tdRSmaQTaskInfoFree(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level);
|
||||
static int32_t tdRSmaQTaskInfoIterInit(SRSmaQTaskInfoIter *pIter, STFile *pTFile);
|
||||
static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskInfoIter *pIter, bool *isFinish);
|
||||
static int32_t tdRSmaQTaskInfoRestore(SSma *pSma, int8_t type, SRSmaQTaskInfoIter *pIter);
|
||||
|
@ -96,7 +98,7 @@ static FORCE_INLINE int32_t tdRSmaQTaskInfoContLen(int32_t lenWithHead) {
|
|||
|
||||
static FORCE_INLINE void tdRSmaQTaskInfoIterDestroy(SRSmaQTaskInfoIter *pIter) { taosMemoryFreeClear(pIter->pBuf); }
|
||||
|
||||
void tdFreeQTaskInfo(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level) {
|
||||
static void tdRSmaQTaskInfoFree(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level) {
|
||||
// Note: free/kill may in RC
|
||||
if (!taskHandle || !(*taskHandle)) return;
|
||||
qTaskInfo_t otaskHandle = atomic_load_ptr(taskHandle);
|
||||
|
@ -123,20 +125,20 @@ void *tdFreeRSmaInfo(SSma *pSma, SRSmaInfo *pInfo, bool isDeepFree) {
|
|||
SRSmaInfoItem *pItem = &pInfo->items[i];
|
||||
|
||||
if (isDeepFree && pItem->tmrId) {
|
||||
smaDebug("vgId:%d, stop fetch timer %p for table %" PRIi64 " level %d", SMA_VID(pSma), pInfo->suid,
|
||||
pItem->tmrId, i + 1);
|
||||
smaDebug("vgId:%d, stop fetch timer %p for table %" PRIi64 " level %d", SMA_VID(pSma), pItem->tmrId,
|
||||
pInfo->suid, i + 1);
|
||||
taosTmrStopA(&pItem->tmrId);
|
||||
}
|
||||
|
||||
if (isDeepFree && pInfo->taskInfo[i]) {
|
||||
tdFreeQTaskInfo(&pInfo->taskInfo[i], SMA_VID(pSma), i + 1);
|
||||
tdRSmaQTaskInfoFree(&pInfo->taskInfo[i], SMA_VID(pSma), i + 1);
|
||||
} else {
|
||||
smaDebug("vgId:%d, table %" PRIi64 " no need to destroy rsma info level %d since empty taskInfo", SMA_VID(pSma),
|
||||
pInfo->suid, i + 1);
|
||||
}
|
||||
|
||||
if (pInfo->iTaskInfo[i]) {
|
||||
tdFreeQTaskInfo(&pInfo->iTaskInfo[i], SMA_VID(pSma), i + 1);
|
||||
tdRSmaQTaskInfoFree(&pInfo->iTaskInfo[i], SMA_VID(pSma), i + 1);
|
||||
} else {
|
||||
smaDebug("vgId:%d, table %" PRIi64 " no need to destroy rsma info level %d since empty iTaskInfo",
|
||||
SMA_VID(pSma), pInfo->suid, i + 1);
|
||||
|
@ -173,7 +175,7 @@ static FORCE_INLINE int32_t tdUidStoreInit(STbUidStore **pStore) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids) {
|
||||
static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids, bool isAdd) {
|
||||
SRSmaInfo *pRSmaInfo = NULL;
|
||||
|
||||
if (!suid || !tbUids) {
|
||||
|
@ -197,7 +199,7 @@ static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids)
|
|||
|
||||
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
||||
if (pRSmaInfo->taskInfo[i]) {
|
||||
if (((terrno = qUpdateQualifiedTableId(pRSmaInfo->taskInfo[i], tbUids, true)) < 0)) {
|
||||
if (((terrno = qUpdateQualifiedTableId(pRSmaInfo->taskInfo[i], tbUids, isAdd)) < 0)) {
|
||||
tdReleaseRSmaInfo(pSma, pRSmaInfo);
|
||||
smaError("vgId:%d, update tbUidList failed for uid:%" PRIi64 " level %d since %s", SMA_VID(pSma), *suid, i,
|
||||
terrstr());
|
||||
|
@ -213,12 +215,12 @@ static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tdUpdateTbUidList(SSma *pSma, STbUidStore *pStore) {
|
||||
int32_t tdUpdateTbUidList(SSma *pSma, STbUidStore *pStore, bool isAdd) {
|
||||
if (!pStore || (taosArrayGetSize(pStore->tbUids) == 0)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (tdUpdateTbUidListImpl(pSma, &pStore->suid, pStore->tbUids) != TSDB_CODE_SUCCESS) {
|
||||
if (tdUpdateTbUidListImpl(pSma, &pStore->suid, pStore->tbUids, isAdd) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -227,7 +229,7 @@ int32_t tdUpdateTbUidList(SSma *pSma, STbUidStore *pStore) {
|
|||
tb_uid_t *pTbSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
|
||||
SArray *pTbUids = *(SArray **)pIter;
|
||||
|
||||
if (tdUpdateTbUidListImpl(pSma, pTbSuid, pTbUids) != TSDB_CODE_SUCCESS) {
|
||||
if (tdUpdateTbUidListImpl(pSma, pTbSuid, pTbUids, isAdd) != TSDB_CODE_SUCCESS) {
|
||||
taosHashCancelIterate(pStore->uidHash, pIter);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
@ -300,7 +302,7 @@ static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
SRSmaInfoItem *pItem = &(pRSmaInfo->items[idx]);
|
||||
pItem->triggerStat = TASK_TRIGGER_STAT_INACTIVE;
|
||||
pItem->triggerStat = TASK_TRIGGER_STAT_ACTIVE; // fetch the data when reboot
|
||||
if (param->maxdelay[idx] < TSDB_MIN_ROLLUP_MAX_DELAY) {
|
||||
int64_t msInterval =
|
||||
convertTimeFromPrecisionToUnit(pRetention[idx + 1].freq, pTsdbCfg->precision, TIME_UNIT_MILLISECOND);
|
||||
|
@ -313,10 +315,19 @@ static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat
|
|||
}
|
||||
|
||||
pItem->level = idx == 0 ? TSDB_RETENTION_L1 : TSDB_RETENTION_L2;
|
||||
taosTmrReset(tdRSmaFetchTrigger, pItem->maxDelay, pItem, smaMgmt.tmrHandle, &pItem->tmrId);
|
||||
smaInfo("vgId:%d, table:%" PRIi64 " level:%" PRIi8 " maxdelay:%" PRIi64 " watermark:%" PRIi64
|
||||
ASSERT(pItem->level > 0);
|
||||
|
||||
SRSmaRef rsmaRef = {.refId = pStat->refId, .suid = pRSmaInfo->suid};
|
||||
taosHashPut(smaMgmt.refHash, &pItem, POINTER_BYTES, &rsmaRef, sizeof(rsmaRef));
|
||||
|
||||
pItem->fetchLevel = pItem->level;
|
||||
taosTmrReset(tdRSmaFetchTrigger, RSMA_FETCH_INTERVAL, pItem, smaMgmt.tmrHandle, &pItem->tmrId);
|
||||
|
||||
|
||||
smaInfo("vgId:%d, item:%p table:%" PRIi64 " level:%" PRIi8 " maxdelay:%" PRIi64 " watermark:%" PRIi64
|
||||
", finally maxdelay:%" PRIi32,
|
||||
TD_VID(pVnode), pRSmaInfo->suid, idx + 1, param->maxdelay[idx], param->watermark[idx], pItem->maxDelay);
|
||||
TD_VID(pVnode), pItem, pRSmaInfo->suid, idx + 1, param->maxdelay[idx], param->watermark[idx],
|
||||
pItem->maxDelay);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -330,7 +341,7 @@ static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat
|
|||
* @param tbName
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, const char *tbName) {
|
||||
int32_t tdRSmaProcessCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, const char *tbName) {
|
||||
if ((param->qmsgLen[0] == 0) && (param->qmsgLen[1] == 0)) {
|
||||
smaDebug("vgId:%d, no qmsg1/qmsg2 for rollup table %s %" PRIi64, SMA_VID(pSma), tbName, suid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -368,7 +379,10 @@ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con
|
|||
terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION;
|
||||
goto _err;
|
||||
}
|
||||
pRSmaInfo->pSma = pSma;
|
||||
pRSmaInfo->pTSchema = pTSchema;
|
||||
pRSmaInfo->suid = suid;
|
||||
T_REF_INIT_VAL(pRSmaInfo, 1);
|
||||
if (!(pRSmaInfo->queue = taosOpenQueue())) {
|
||||
goto _err;
|
||||
}
|
||||
|
@ -382,9 +396,6 @@ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con
|
|||
if (!(pRSmaInfo->iQall = taosAllocateQall())) {
|
||||
goto _err;
|
||||
}
|
||||
pRSmaInfo->suid = suid;
|
||||
pRSmaInfo->refId = RSMA_REF_ID(pStat);
|
||||
T_REF_INIT_VAL(pRSmaInfo, 1);
|
||||
|
||||
if (tdSetRSmaInfoItemParams(pSma, param, pStat, pRSmaInfo, 0) < 0) {
|
||||
goto _err;
|
||||
|
@ -427,7 +438,7 @@ int32_t tdProcessRSmaCreate(SSma *pSma, SVCreateStbReq *pReq) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
return tdProcessRSmaCreateImpl(pSma, &pReq->rsmaParam, pReq->suid, pReq->name);
|
||||
return tdRSmaProcessCreateImpl(pSma, &pReq->rsmaParam, pReq->suid, pReq->name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -461,6 +472,7 @@ int32_t tdProcessRSmaDrop(SSma *pSma, SVDropStbReq *pReq) {
|
|||
}
|
||||
|
||||
// set del flag for data in mem
|
||||
atomic_store_8(&pRSmaStat->delFlag, 1);
|
||||
RSMA_INFO_SET_DEL(pRSmaInfo);
|
||||
tdUnRefRSmaInfo(pSma, pRSmaInfo);
|
||||
|
||||
|
@ -654,15 +666,15 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
|||
|
||||
if (taosArrayGetSize(pResList) == 0) {
|
||||
if (terrno == 0) {
|
||||
// smaDebug("vgId:%d, no rsma %" PRIi8 " data fetched yet", SMA_VID(pSma), pItem->level);
|
||||
// smaDebug("vgId:%d, no rsma level %" PRIi8 " data fetched yet", SMA_VID(pSma), pItem->level);
|
||||
} else {
|
||||
smaDebug("vgId:%d, no rsma %" PRIi8 " data fetched since %s", SMA_VID(pSma), pItem->level, terrstr());
|
||||
smaDebug("vgId:%d, no rsma level %" PRIi8 " data fetched since %s", SMA_VID(pSma), pItem->level, terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
smaDebug("vgId:%d, rsma %" PRIi8 " data fetched", SMA_VID(pSma), pItem->level);
|
||||
smaDebug("vgId:%d, rsma level %" PRIi8 " data fetched", SMA_VID(pSma), pItem->level);
|
||||
}
|
||||
#if 0
|
||||
char flag[10] = {0};
|
||||
|
@ -676,21 +688,22 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
|||
|
||||
// TODO: the schema update should be handled later(TD-17965)
|
||||
if (buildSubmitReqFromDataBlock(&pReq, output, pTSchema, SMA_VID(pSma), suid) < 0) {
|
||||
smaError("vgId:%d, build submit req for rsma stable %" PRIi64 " level %" PRIi8 " failed since %s",
|
||||
SMA_VID(pSma), suid, pItem->level, terrstr());
|
||||
smaError("vgId:%d, build submit req for rsma table %" PRIi64 " level %" PRIi8 " failed since %s", SMA_VID(pSma),
|
||||
suid, pItem->level, terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (pReq && tdProcessSubmitReq(sinkTsdb, output->info.version, pReq) < 0) {
|
||||
taosMemoryFreeClear(pReq);
|
||||
smaError("vgId:%d, process submit req for rsma stable %" PRIi64 " level %" PRIi8 " failed since %s",
|
||||
smaError("vgId:%d, process submit req for rsma table %" PRIi64 " level %" PRIi8 " failed since %s",
|
||||
SMA_VID(pSma), suid, pItem->level, terrstr());
|
||||
goto _err;
|
||||
}
|
||||
taosMemoryFreeClear(pReq);
|
||||
|
||||
smaDebug("vgId:%d, process submit req for rsma table %" PRIi64 " level %" PRIi8 " version:%" PRIi64,
|
||||
SMA_VID(pSma), suid, pItem->level, output->info.version);
|
||||
smaDebug("vgId:%d, process submit req for rsma table %" PRIi64 " level %" PRIi8 " ver %" PRIi64 " len %" PRIu32,
|
||||
SMA_VID(pSma), suid, pItem->level, output->info.version, htonl(pReq->header.contLen));
|
||||
|
||||
taosMemoryFreeClear(pReq);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,6 +830,95 @@ static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSize,
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tdCloneQTaskInfo(SSma *pSma, qTaskInfo_t dstTaskInfo, qTaskInfo_t srcTaskInfo, SRSmaParam *param,
|
||||
tb_uid_t suid, int8_t idx) {
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
char *pOutput = NULL;
|
||||
int32_t len = 0;
|
||||
|
||||
if ((terrno = qSerializeTaskStatus(srcTaskInfo, &pOutput, &len)) < 0) {
|
||||
smaError("vgId:%d, rsma clone, table %" PRIi64 " serialize qTaskInfo failed since %s", TD_VID(pVnode), suid,
|
||||
terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
SReadHandle handle = {
|
||||
.meta = pVnode->pMeta,
|
||||
.vnode = pVnode,
|
||||
.initTqReader = 1,
|
||||
};
|
||||
ASSERT(!dstTaskInfo);
|
||||
dstTaskInfo = qCreateStreamExecTaskInfo(param->qmsg[idx], &handle);
|
||||
if (!dstTaskInfo) {
|
||||
terrno = TSDB_CODE_RSMA_QTASKINFO_CREATE;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (qDeserializeTaskStatus(dstTaskInfo, pOutput, len) < 0) {
|
||||
smaError("vgId:%d, rsma clone, restore rsma task for table:%" PRIi64 " failed since %s", TD_VID(pVnode), suid,
|
||||
terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
smaDebug("vgId:%d, rsma clone, restore rsma task for table:%" PRIi64 " succeed", TD_VID(pVnode), suid);
|
||||
|
||||
taosMemoryFreeClear(pOutput);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
taosMemoryFreeClear(pOutput);
|
||||
tdRSmaQTaskInfoFree(dstTaskInfo, TD_VID(pVnode), idx + 1);
|
||||
smaError("vgId:%d, rsma clone, restore rsma task for table:%" PRIi64 " failed since %s", TD_VID(pVnode), suid,
|
||||
terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clone qTaskInfo of SRSmaInfo
|
||||
*
|
||||
* @param pSma
|
||||
* @param pInfo
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tdRSmaInfoClone(SSma *pSma, SRSmaInfo *pInfo) {
|
||||
SRSmaParam *param = NULL;
|
||||
if (!pInfo) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, SMA_META(pSma), 0);
|
||||
smaDebug("vgId:%d, rsma clone qTaskInfo for suid:%" PRIi64, SMA_VID(pSma), pInfo->suid);
|
||||
if (metaGetTableEntryByUid(&mr, pInfo->suid) < 0) {
|
||||
smaError("vgId:%d, rsma clone, failed to get table meta for %" PRIi64 " since %s", SMA_VID(pSma), pInfo->suid,
|
||||
terrstr());
|
||||
goto _err;
|
||||
}
|
||||
ASSERT(mr.me.type == TSDB_SUPER_TABLE);
|
||||
ASSERT(mr.me.uid == pInfo->suid);
|
||||
if (TABLE_IS_ROLLUP(mr.me.flags)) {
|
||||
param = &mr.me.stbEntry.rsmaParam;
|
||||
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
||||
if (!pInfo->iTaskInfo[i]) {
|
||||
continue;
|
||||
}
|
||||
if (tdCloneQTaskInfo(pSma, pInfo->taskInfo[i], pInfo->iTaskInfo[i], param, pInfo->suid, i) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
smaDebug("vgId:%d, rsma clone env success for %" PRIi64, SMA_VID(pSma), pInfo->suid);
|
||||
} else {
|
||||
terrno = TSDB_CODE_RSMA_INVALID_SCHEMA;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
metaReaderClear(&mr);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
metaReaderClear(&mr);
|
||||
smaError("vgId:%d, rsma clone env failed for %" PRIi64 " since %s", SMA_VID(pSma), pInfo->suid, terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief During async commit, the SRSmaInfo object would be COW from iRSmaInfoHash and write lock should be applied.
|
||||
*
|
||||
|
@ -840,25 +942,25 @@ static SRSmaInfo *tdAcquireRSmaInfoBySuid(SSma *pSma, int64_t suid) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// taosRLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
taosRLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
pRSmaInfo = taosHashGet(RSMA_INFO_HASH(pStat), &suid, sizeof(tb_uid_t));
|
||||
if (pRSmaInfo && (pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
|
||||
if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
|
||||
// taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
return NULL;
|
||||
}
|
||||
if (!pRSmaInfo->taskInfo[0]) {
|
||||
if (tdCloneRSmaInfo(pSma, pRSmaInfo) < 0) {
|
||||
// taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
if (tdRSmaInfoClone(pSma, pRSmaInfo) < 0) {
|
||||
taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
tdRefRSmaInfo(pSma, pRSmaInfo);
|
||||
// taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
ASSERT(pRSmaInfo->suid == suid);
|
||||
return pRSmaInfo;
|
||||
}
|
||||
// taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
taosRUnLockLatch(SMA_ENV_LOCK(pEnv));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1006,7 +1108,7 @@ static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma, int64_t *nTables) {
|
|||
" qmsgLen:%" PRIi32,
|
||||
TD_VID(pVnode), suid, i, param->maxdelay[i], param->watermark[i], param->qmsgLen[i]);
|
||||
}
|
||||
if (tdProcessRSmaCreateImpl(pSma, &mr.me.stbEntry.rsmaParam, suid, mr.me.name) < 0) {
|
||||
if (tdRSmaProcessCreateImpl(pSma, &mr.me.stbEntry.rsmaParam, suid, mr.me.name) < 0) {
|
||||
smaError("vgId:%d, rsma restore env failed for %" PRIi64 " since %s", TD_VID(pVnode), suid, terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
@ -1019,7 +1121,7 @@ static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma, int64_t *nTables) {
|
|||
goto _err;
|
||||
}
|
||||
|
||||
if (tdUpdateTbUidList(pVnode->pSma, &uidStore) < 0) {
|
||||
if (tdUpdateTbUidList(pVnode->pSma, &uidStore, true) < 0) {
|
||||
smaError("vgId:%d, rsma restore, update tb uid list failed for %" PRIi64 " since %s", TD_VID(pVnode), suid,
|
||||
terrstr());
|
||||
goto _err;
|
||||
|
@ -1118,7 +1220,7 @@ static int32_t tdRSmaRestoreTSDataReload(SSma *pSma) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tdProcessRSmaRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer) {
|
||||
int32_t tdRSmaProcessRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer) {
|
||||
// step 1: iterate all stables to restore the rsma env
|
||||
int64_t nTables = 0;
|
||||
if (tdRSmaRestoreQTaskInfoInit(pSma, &nTables) < 0) {
|
||||
|
@ -1139,6 +1241,12 @@ int32_t tdProcessRSmaRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer)
|
|||
if (tdRSmaRestoreTSDataReload(pSma) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// step 4: open SRSmaFS for qTaskFiles
|
||||
if (tdRSmaFSOpen(pSma, qtaskFileVer) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
smaInfo("vgId:%d, restore rsma task %" PRIi8 " from qtaskf %" PRIi64 " succeed", SMA_VID(pSma), type, qtaskFileVer);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
|
@ -1237,29 +1345,31 @@ static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskInfoIter *pIter, bool *isF
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (tdReadTFile(pTFile, pIter->qBuf, nBytes) != nBytes) {
|
||||
if (tdReadTFile(pTFile, pIter->pBuf, nBytes) != nBytes) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
int32_t infoLen = 0;
|
||||
taosDecodeFixedI32(pIter->qBuf, &infoLen);
|
||||
taosDecodeFixedI32(pIter->pBuf, &infoLen);
|
||||
if (infoLen > nBytes) {
|
||||
if (infoLen <= RSMA_QTASKINFO_BUFSIZE) {
|
||||
terrno = TSDB_CODE_RSMA_FILE_CORRUPTED;
|
||||
smaError("iterate rsma qtaskinfo file %s failed since %s", TD_TFILE_FULL_NAME(pIter->pTFile), terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
pIter->nAlloc = infoLen;
|
||||
void *pBuf = taosMemoryRealloc(pIter->pBuf, infoLen);
|
||||
if (!pBuf) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_FAILED;
|
||||
if (pIter->nAlloc < infoLen) {
|
||||
pIter->nAlloc = infoLen;
|
||||
void *pBuf = taosMemoryRealloc(pIter->pBuf, infoLen);
|
||||
if (!pBuf) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
pIter->pBuf = pBuf;
|
||||
}
|
||||
pIter->pBuf = pBuf;
|
||||
pIter->qBuf = pIter->pBuf;
|
||||
|
||||
nBytes = infoLen;
|
||||
|
||||
if (tdSeekTFile(pTFile, pIter->offset, SEEK_SET)) {
|
||||
if (tdSeekTFile(pTFile, pIter->offset, SEEK_SET) < 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1268,6 +1378,7 @@ static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskInfoIter *pIter, bool *isF
|
|||
}
|
||||
}
|
||||
|
||||
pIter->qBuf = pIter->pBuf;
|
||||
pIter->offset += nBytes;
|
||||
pIter->nBytes = nBytes;
|
||||
pIter->nBufPos = 0;
|
||||
|
@ -1345,17 +1456,24 @@ int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t fsMaxVer = tdRSmaFSMaxVer(pSma, pRSmaStat);
|
||||
if (pRSmaStat->commitAppliedVer <= fsMaxVer) {
|
||||
smaDebug("vgId:%d, rsma persist, no need as applied %" PRIi64 " not larger than fsMaxVer %" PRIi64, vid,
|
||||
pRSmaStat->commitAppliedVer, fsMaxVer);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STFile tFile = {0};
|
||||
#if 0
|
||||
if (pRSmaStat->commitAppliedVer > 0) {
|
||||
char qTaskInfoFName[TSDB_FILENAME_LEN];
|
||||
tdRSmaQTaskInfoGetFileName(vid, pRSmaStat->commitAppliedVer, qTaskInfoFName);
|
||||
if (tdInitTFile(&tFile, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFName) < 0) {
|
||||
smaError("vgId:%d, rsma persit, init %s failed since %s", vid, qTaskInfoFName, terrstr());
|
||||
smaError("vgId:%d, rsma persist, init %s failed since %s", vid, qTaskInfoFName, terrstr());
|
||||
goto _err;
|
||||
}
|
||||
if (tdCreateTFile(&tFile, true, TD_FTYPE_RSMA_QTASKINFO) < 0) {
|
||||
smaError("vgId:%d, rsma persit, create %s failed since %s", vid, TD_TFILE_FULL_NAME(&tFile), terrstr());
|
||||
smaError("vgId:%d, rsma persist, create %s failed since %s", vid, TD_TFILE_FULL_NAME(&tFile), terrstr());
|
||||
goto _err;
|
||||
}
|
||||
smaDebug("vgId:%d, rsma, serialize qTaskInfo, file %s created", vid, TD_TFILE_FULL_NAME(&tFile));
|
||||
|
@ -1405,11 +1523,11 @@ int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash) {
|
|||
char qTaskInfoFName[TSDB_FILENAME_LEN];
|
||||
tdRSmaQTaskInfoGetFileName(vid, pRSmaStat->commitAppliedVer, qTaskInfoFName);
|
||||
if (tdInitTFile(&tFile, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFName) < 0) {
|
||||
smaError("vgId:%d, rsma persit, init %s failed since %s", vid, qTaskInfoFName, terrstr());
|
||||
smaError("vgId:%d, rsma persist, init %s failed since %s", vid, qTaskInfoFName, terrstr());
|
||||
goto _err;
|
||||
}
|
||||
if (tdCreateTFile(&tFile, true, TD_FTYPE_RSMA_QTASKINFO) < 0) {
|
||||
smaError("vgId:%d, rsma persit, create %s failed since %s", vid, TD_TFILE_FULL_NAME(&tFile), terrstr());
|
||||
smaError("vgId:%d, rsma persist, create %s failed since %s", vid, TD_TFILE_FULL_NAME(&tFile), terrstr());
|
||||
goto _err;
|
||||
}
|
||||
smaDebug("vgId:%d, rsma, table %" PRIi64 " serialize qTaskInfo, file %s created", vid, pRSmaInfo->suid,
|
||||
|
@ -1453,7 +1571,7 @@ int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash) {
|
|||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
smaError("vgId:%d, rsma persit failed since %s", vid, terrstr());
|
||||
smaError("vgId:%d, rsma persist failed since %s", vid, terrstr());
|
||||
if (isFileCreated) {
|
||||
tdRemoveTFile(&tFile);
|
||||
tdDestroyTFile(&tFile);
|
||||
|
@ -1468,26 +1586,46 @@ _err:
|
|||
* @param tmrId
|
||||
*/
|
||||
static void tdRSmaFetchTrigger(void *param, void *tmrId) {
|
||||
SRSmaInfoItem *pItem = param;
|
||||
SRSmaRef *pRSmaRef = NULL;
|
||||
SSma *pSma = NULL;
|
||||
SRSmaInfo *pRSmaInfo = tdGetRSmaInfoByItem(pItem);
|
||||
SRSmaStat *pStat = NULL;
|
||||
SRSmaInfo *pRSmaInfo = NULL;
|
||||
SRSmaInfoItem *pItem = NULL;
|
||||
|
||||
if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
|
||||
smaDebug("rsma fetch task not start since rsma info already deleted, rsetId:%" PRIi64 " refId:%d)", smaMgmt.rsetId,
|
||||
pRSmaInfo->refId);
|
||||
if (!(pRSmaRef = taosHashGet(smaMgmt.refHash, ¶m, POINTER_BYTES))) {
|
||||
smaDebug("rsma fetch task not start since rsma info item:%p not exist in refHash:%p, rsetId:%" PRIi64, param,
|
||||
*(int64_t *)¶m, smaMgmt.refHash, smaMgmt.rsetId);
|
||||
return;
|
||||
}
|
||||
|
||||
SRSmaStat *pStat = (SRSmaStat *)tdAcquireSmaRef(smaMgmt.rsetId, pRSmaInfo->refId);
|
||||
|
||||
if (!pStat) {
|
||||
if (!(pStat = (SRSmaStat *)tdAcquireSmaRef(smaMgmt.rsetId, pRSmaRef->refId))) {
|
||||
smaDebug("rsma fetch task not start since rsma stat already destroyed, rsetId:%" PRIi64 " refId:%d)",
|
||||
smaMgmt.rsetId, pRSmaInfo->refId);
|
||||
smaMgmt.rsetId, pRSmaRef->refId); // pRSmaRef freed in taosHashRemove
|
||||
taosHashRemove(smaMgmt.refHash, ¶m, POINTER_BYTES);
|
||||
return;
|
||||
}
|
||||
|
||||
pSma = pStat->pSma;
|
||||
|
||||
if (!(pRSmaInfo = tdAcquireRSmaInfoBySuid(pSma, pRSmaRef->suid))) {
|
||||
smaDebug("rsma fetch task not start since rsma info not exist, rsetId:%" PRIi64 " refId:%d)", smaMgmt.rsetId,
|
||||
pRSmaRef->refId); // pRSmaRef freed in taosHashRemove
|
||||
tdReleaseSmaRef(smaMgmt.rsetId, pRSmaRef->refId);
|
||||
taosHashRemove(smaMgmt.refHash, ¶m, POINTER_BYTES);
|
||||
return;
|
||||
}
|
||||
|
||||
if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
|
||||
smaDebug("rsma fetch task not start since rsma info already deleted, rsetId:%" PRIi64 " refId:%d)", smaMgmt.rsetId,
|
||||
pRSmaRef->refId); // pRSmaRef freed in taosHashRemove
|
||||
tdReleaseRSmaInfo(pSma, pRSmaInfo);
|
||||
tdReleaseSmaRef(smaMgmt.rsetId, pRSmaRef->refId);
|
||||
taosHashRemove(smaMgmt.refHash, ¶m, POINTER_BYTES);
|
||||
return;
|
||||
}
|
||||
|
||||
pItem = *(SRSmaInfoItem **)¶m;
|
||||
|
||||
// if rsma trigger stat in paused, cancelled or finished, not start fetch task
|
||||
int8_t rsmaTriggerStat = atomic_load_8(RSMA_TRIGGER_STAT(pStat));
|
||||
switch (rsmaTriggerStat) {
|
||||
|
@ -1495,11 +1633,12 @@ static void tdRSmaFetchTrigger(void *param, void *tmrId) {
|
|||
case TASK_TRIGGER_STAT_CANCELLED: {
|
||||
smaDebug("vgId:%d, rsma fetch task not start for level %" PRIi8 " since stat is %" PRIi8
|
||||
", rsetId rsetId:%" PRIi64 " refId:%d",
|
||||
SMA_VID(pSma), pItem->level, rsmaTriggerStat, smaMgmt.rsetId, pRSmaInfo->refId);
|
||||
SMA_VID(pSma), pItem->level, rsmaTriggerStat, smaMgmt.rsetId, pRSmaRef->refId);
|
||||
if (rsmaTriggerStat == TASK_TRIGGER_STAT_PAUSED) {
|
||||
taosTmrReset(tdRSmaFetchTrigger, RSMA_FETCH_INTERVAL, pItem, smaMgmt.tmrHandle, &pItem->tmrId);
|
||||
}
|
||||
tdReleaseSmaRef(smaMgmt.rsetId, pRSmaInfo->refId);
|
||||
tdReleaseRSmaInfo(pSma, pRSmaInfo);
|
||||
tdReleaseSmaRef(smaMgmt.rsetId, pRSmaRef->refId);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
|
@ -1544,11 +1683,11 @@ static void tdRSmaFetchTrigger(void *param, void *tmrId) {
|
|||
|
||||
_end:
|
||||
taosTmrReset(tdRSmaFetchTrigger, pItem->maxDelay, pItem, smaMgmt.tmrHandle, &pItem->tmrId);
|
||||
tdReleaseSmaRef(smaMgmt.rsetId, pRSmaInfo->refId);
|
||||
tdReleaseRSmaInfo(pSma, pRSmaInfo);
|
||||
tdReleaseSmaRef(smaMgmt.rsetId, pRSmaRef->refId);
|
||||
}
|
||||
|
||||
static void tdFreeRSmaSubmitItems(SArray *pItems) {
|
||||
ASSERT(taosArrayGetSize(pItems) > 0);
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pItems); ++i) {
|
||||
taosFreeQitem(*(void **)taosArrayGet(pItems, i));
|
||||
}
|
||||
|
@ -1560,10 +1699,9 @@ static void tdFreeRSmaSubmitItems(SArray *pItems) {
|
|||
*
|
||||
* @param pSma
|
||||
* @param pInfo
|
||||
* @param pSubmitArr
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo, SArray *pSubmitArr) {
|
||||
static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo) {
|
||||
SSDataBlock dataBlock = {.info.type = STREAM_GET_ALL};
|
||||
for (int8_t i = 1; i <= TSDB_RETENTION_L2; ++i) {
|
||||
SRSmaInfoItem *pItem = RSMA_INFO_ITEM(pInfo, i - 1);
|
||||
|
@ -1574,21 +1712,23 @@ static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo, SArray *pSubmi
|
|||
continue;
|
||||
}
|
||||
|
||||
int64_t curMs = taosGetTimestampMs();
|
||||
if ((pItem->nSkipped * pItem->maxDelay) > RSMA_FETCH_DELAY_MAX) {
|
||||
smaInfo("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nSkipped:%" PRIi8 " maxDelay:%d, fetch executed",
|
||||
SMA_VID(pSma), pInfo->suid, i, pItem->nSkipped, pItem->maxDelay);
|
||||
} else if (((curMs - pInfo->lastRecv) < RSMA_FETCH_ACTIVE_MAX)) {
|
||||
++pItem->nSkipped;
|
||||
smaDebug("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " curMs:%" PRIi64 " lastRecv:%" PRIi64 ", fetch skipped ",
|
||||
SMA_VID(pSma), pInfo->suid, i, curMs, pInfo->lastRecv);
|
||||
continue;
|
||||
if ((++pItem->nScanned * pItem->maxDelay) > RSMA_FETCH_DELAY_MAX) {
|
||||
smaDebug("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nScanned:%" PRIi8 " maxDelay:%d, fetch executed",
|
||||
SMA_VID(pSma), pInfo->suid, i, pItem->nScanned, pItem->maxDelay);
|
||||
} else {
|
||||
smaInfo("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " curMs:%" PRIi64 " lastRecv:%" PRIi64 ", fetch executed ",
|
||||
SMA_VID(pSma), pInfo->suid, i, curMs, pInfo->lastRecv);
|
||||
int64_t curMs = taosGetTimestampMs();
|
||||
if ((curMs - pInfo->lastRecv) < RSMA_FETCH_ACTIVE_MAX) {
|
||||
smaTrace("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " curMs:%" PRIi64 " lastRecv:%" PRIi64 ", fetch skipped ",
|
||||
SMA_VID(pSma), pInfo->suid, i, curMs, pInfo->lastRecv);
|
||||
atomic_store_8(&pItem->triggerStat, TASK_TRIGGER_STAT_ACTIVE); // restore the active stat
|
||||
continue;
|
||||
} else {
|
||||
smaDebug("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " curMs:%" PRIi64 " lastRecv:%" PRIi64 ", fetch executed ",
|
||||
SMA_VID(pSma), pInfo->suid, i, curMs, pInfo->lastRecv);
|
||||
}
|
||||
}
|
||||
|
||||
pItem->nSkipped = 0;
|
||||
pItem->nScanned = 0;
|
||||
|
||||
if ((terrno = qSetMultiStreamInput(taskInfo, &dataBlock, 1, STREAM_INPUT__DATA_BLOCK)) < 0) {
|
||||
goto _err;
|
||||
|
@ -1599,20 +1739,18 @@ static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo, SArray *pSubmi
|
|||
}
|
||||
|
||||
tdCleanupStreamInputDataBlock(taskInfo);
|
||||
smaInfo("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nSkipped:%" PRIi8 " maxDelay:%d, fetch finished",
|
||||
SMA_VID(pSma), pInfo->suid, i, pItem->nSkipped, pItem->maxDelay);
|
||||
smaDebug("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nScanned:%" PRIi8 " maxDelay:%d, fetch finished",
|
||||
SMA_VID(pSma), pInfo->suid, i, pItem->nScanned, pItem->maxDelay);
|
||||
} else {
|
||||
smaDebug("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nSkipped:%" PRIi8
|
||||
smaDebug("vgId:%d, suid:%" PRIi64 " level:%" PRIi8 " nScanned:%" PRIi8
|
||||
" maxDelay:%d, fetch not executed as fetch level is %" PRIi8,
|
||||
SMA_VID(pSma), pInfo->suid, i, pItem->nSkipped, pItem->maxDelay, pItem->fetchLevel);
|
||||
SMA_VID(pSma), pInfo->suid, i, pItem->nScanned, pItem->maxDelay, pItem->fetchLevel);
|
||||
}
|
||||
}
|
||||
|
||||
_end:
|
||||
tdReleaseRSmaInfo(pSma, pInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
tdReleaseRSmaInfo(pSma, pInfo);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1696,6 +1834,7 @@ int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type) {
|
|||
bool occupied = (batchMax <= 1);
|
||||
if (batchMax > 1) {
|
||||
batchMax = 100 / batchMax;
|
||||
batchMax = TMAX(batchMax, 4);
|
||||
}
|
||||
while (occupied || (++batchCnt < batchMax)) { // greedy mode
|
||||
taosReadAllQitems(pInfo->queue, pInfo->qall); // queue has mutex lock
|
||||
|
@ -1705,13 +1844,15 @@ int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type) {
|
|||
smaDebug("vgId:%d, batchSize:%d, execType:%" PRIi8, SMA_VID(pSma), qallItemSize, type);
|
||||
}
|
||||
|
||||
int8_t oldStat = atomic_val_compare_exchange_8(RSMA_COMMIT_STAT(pRSmaStat), 0, 2);
|
||||
if (oldStat == 0 ||
|
||||
((oldStat == 2) && atomic_load_8(RSMA_TRIGGER_STAT(pRSmaStat)) < TASK_TRIGGER_STAT_PAUSED)) {
|
||||
atomic_fetch_add_32(&pRSmaStat->nFetchAll, 1);
|
||||
tdRSmaFetchAllResult(pSma, pInfo, pSubmitArr);
|
||||
if (0 == atomic_sub_fetch_32(&pRSmaStat->nFetchAll, 1)) {
|
||||
atomic_store_8(RSMA_COMMIT_STAT(pRSmaStat), 0);
|
||||
if (RSMA_INFO_ITEM(pInfo, 0)->fetchLevel || RSMA_INFO_ITEM(pInfo, 1)->fetchLevel) {
|
||||
int8_t oldStat = atomic_val_compare_exchange_8(RSMA_COMMIT_STAT(pRSmaStat), 0, 2);
|
||||
if (oldStat == 0 ||
|
||||
((oldStat == 2) && atomic_load_8(RSMA_TRIGGER_STAT(pRSmaStat)) < TASK_TRIGGER_STAT_PAUSED)) {
|
||||
atomic_fetch_add_32(&pRSmaStat->nFetchAll, 1);
|
||||
tdRSmaFetchAllResult(pSma, pInfo);
|
||||
if (0 == atomic_sub_fetch_32(&pRSmaStat->nFetchAll, 1)) {
|
||||
atomic_store_8(RSMA_COMMIT_STAT(pRSmaStat), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1784,7 +1925,7 @@ int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type) {
|
|||
tsem_wait(&pRSmaStat->notEmpty);
|
||||
|
||||
if ((pEnv->flag & SMA_ENV_FLG_CLOSE) && (atomic_load_64(&pRSmaStat->nBufItems) <= 0)) {
|
||||
smaInfo("vgId:%d, exec task end, flag:%" PRIi8 ", nBufItems:%" PRIi64, SMA_VID(pSma), pEnv->flag,
|
||||
smaDebug("vgId:%d, exec task end, flag:%" PRIi8 ", nBufItems:%" PRIi64, SMA_VID(pSma), pEnv->flag,
|
||||
atomic_load_64(&pRSmaStat->nBufItems));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -15,11 +15,13 @@
|
|||
|
||||
#include "sma.h"
|
||||
|
||||
static int32_t rsmaSnapReadQTaskInfo(SRsmaSnapReader* pReader, uint8_t** ppData);
|
||||
static int32_t rsmaSnapWriteQTaskInfo(SRsmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData);
|
||||
static int32_t rsmaSnapReadQTaskInfo(SRSmaSnapReader* pReader, uint8_t** ppData);
|
||||
static int32_t rsmaSnapWriteQTaskInfo(SRSmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData);
|
||||
static int32_t rsmaQTaskInfSnapReaderOpen(SRSmaSnapReader* pReader, int64_t version);
|
||||
static int32_t rsmaQTaskInfSnapReaderClose(SQTaskFReader** ppReader);
|
||||
|
||||
// SRsmaSnapReader ========================================
|
||||
struct SRsmaSnapReader {
|
||||
// SRSmaSnapReader ========================================
|
||||
struct SRSmaSnapReader {
|
||||
SSma* pSma;
|
||||
int64_t sver;
|
||||
int64_t ever;
|
||||
|
@ -33,13 +35,13 @@ struct SRsmaSnapReader {
|
|||
SQTaskFReader* pQTaskFReader;
|
||||
};
|
||||
|
||||
int32_t rsmaSnapReaderOpen(SSma* pSma, int64_t sver, int64_t ever, SRsmaSnapReader** ppReader) {
|
||||
int32_t rsmaSnapReaderOpen(SSma* pSma, int64_t sver, int64_t ever, SRSmaSnapReader** ppReader) {
|
||||
int32_t code = 0;
|
||||
SVnode* pVnode = pSma->pVnode;
|
||||
SRsmaSnapReader* pReader = NULL;
|
||||
SRSmaSnapReader* pReader = NULL;
|
||||
|
||||
// alloc
|
||||
pReader = (SRsmaSnapReader*)taosMemoryCalloc(1, sizeof(*pReader));
|
||||
pReader = (SRSmaSnapReader*)taosMemoryCalloc(1, sizeof(*pReader));
|
||||
if (pReader == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
|
@ -48,7 +50,7 @@ int32_t rsmaSnapReaderOpen(SSma* pSma, int64_t sver, int64_t ever, SRsmaSnapRead
|
|||
pReader->sver = sver;
|
||||
pReader->ever = ever;
|
||||
|
||||
// rsma1/rsma2
|
||||
// open rsma1/rsma2
|
||||
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
||||
if (pSma->pRSmaTsdb[i]) {
|
||||
code = tsdbSnapReaderOpen(pSma->pRSmaTsdb[i], sver, ever, i == 0 ? SNAP_DATA_RSMA1 : SNAP_DATA_RSMA2,
|
||||
|
@ -59,51 +61,112 @@ int32_t rsmaSnapReaderOpen(SSma* pSma, int64_t sver, int64_t ever, SRsmaSnapRead
|
|||
}
|
||||
}
|
||||
|
||||
// qtaskinfo
|
||||
// 1. add ref to qtaskinfo.v${ever} if exists and then start to replicate
|
||||
char qTaskInfoFullName[TSDB_FILENAME_LEN];
|
||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), ever, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFullName);
|
||||
|
||||
if (!taosCheckExistFile(qTaskInfoFullName)) {
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader for qtaskinfo not need as %s not exists", TD_VID(pVnode),
|
||||
qTaskInfoFullName);
|
||||
} else {
|
||||
pReader->pQTaskFReader = taosMemoryCalloc(1, sizeof(SQTaskFReader));
|
||||
if (!pReader->pQTaskFReader) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
TdFilePtr qTaskF = taosOpenFile(qTaskInfoFullName, TD_FILE_READ);
|
||||
if (!qTaskF) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _err;
|
||||
}
|
||||
pReader->pQTaskFReader->pReadH = qTaskF;
|
||||
#if 0
|
||||
SQTaskFile* pQTaskF = &pReader->pQTaskFReader->fTask;
|
||||
pQTaskF->nRef = 1;
|
||||
#endif
|
||||
// open qtaskinfo
|
||||
if ((code = rsmaQTaskInfSnapReaderOpen(pReader, ever)) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
*ppReader = pReader;
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader opened %s succeed", TD_VID(pVnode), qTaskInfoFullName);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
smaError("vgId:%d, vnode snapshot rsma reader opened failed since %s", TD_VID(pVnode), tstrerror(code));
|
||||
smaError("vgId:%d, vnode snapshot rsma reader open failed since %s", TD_VID(pVnode), tstrerror(code));
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
static int32_t rsmaSnapReadQTaskInfo(SRsmaSnapReader* pReader, uint8_t** ppBuf) {
|
||||
static int32_t rsmaQTaskInfSnapReaderOpen(SRSmaSnapReader* pReader, int64_t version) {
|
||||
int32_t code = 0;
|
||||
SSma* pSma = pReader->pSma;
|
||||
SVnode* pVnode = pSma->pVnode;
|
||||
SSmaEnv* pEnv = NULL;
|
||||
SRSmaStat* pStat = NULL;
|
||||
|
||||
if (!(pEnv = SMA_RSMA_ENV(pSma))) {
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader for qtaskinfo version %" PRIi64 " not need as env is NULL",
|
||||
TD_VID(pVnode), version);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pStat = (SRSmaStat*)SMA_ENV_STAT(pEnv);
|
||||
|
||||
int32_t ref = tdRSmaFSRef(pReader->pSma, pStat, version);
|
||||
if (ref < 1) {
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader for qtaskinfo version %" PRIi64 " not need as ref is %d",
|
||||
TD_VID(pVnode), version, ref);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
char qTaskInfoFullName[TSDB_FILENAME_LEN];
|
||||
tdRSmaQTaskInfoGetFullName(TD_VID(pVnode), version, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFullName);
|
||||
|
||||
if (!taosCheckExistFile(qTaskInfoFullName)) {
|
||||
tdRSmaFSUnRef(pSma, pStat, version);
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader for qtaskinfo version %" PRIi64 " not need as %s not exists",
|
||||
TD_VID(pVnode), qTaskInfoFullName);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pReader->pQTaskFReader = taosMemoryCalloc(1, sizeof(SQTaskFReader));
|
||||
if (!pReader->pQTaskFReader) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
TdFilePtr fp = taosOpenFile(qTaskInfoFullName, TD_FILE_READ);
|
||||
if (!fp) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
taosMemoryFreeClear(pReader->pQTaskFReader);
|
||||
goto _end;
|
||||
}
|
||||
|
||||
pReader->pQTaskFReader->pReadH = fp;
|
||||
pReader->pQTaskFReader->pSma = pSma;
|
||||
pReader->pQTaskFReader->version = pReader->ever;
|
||||
|
||||
_end:
|
||||
if (code < 0) {
|
||||
tdRSmaFSUnRef(pSma, pStat, version);
|
||||
smaError("vgId:%d, vnode snapshot rsma reader open %s succeed", TD_VID(pVnode), qTaskInfoFullName);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader open %s succeed", TD_VID(pVnode), qTaskInfoFullName);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t rsmaQTaskInfSnapReaderClose(SQTaskFReader** ppReader) {
|
||||
if (!(*ppReader)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSma* pSma = (*ppReader)->pSma;
|
||||
SRSmaStat* pStat = SMA_RSMA_STAT(pSma);
|
||||
int64_t version = (*ppReader)->version;
|
||||
|
||||
taosCloseFile(&(*ppReader)->pReadH);
|
||||
tdRSmaFSUnRef(pSma, pStat, version);
|
||||
taosMemoryFreeClear(*ppReader);
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader closed for qTaskInfo version %" PRIi64, SMA_VID(pSma), version);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t rsmaSnapReadQTaskInfo(SRSmaSnapReader* pReader, uint8_t** ppBuf) {
|
||||
int32_t code = 0;
|
||||
SSma* pSma = pReader->pSma;
|
||||
int64_t n = 0;
|
||||
uint8_t* pBuf = NULL;
|
||||
SQTaskFReader* qReader = pReader->pQTaskFReader;
|
||||
|
||||
if (!qReader) {
|
||||
*ppBuf = NULL;
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader qtaskinfo, qTaskReader is NULL", SMA_VID(pSma));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!qReader->pReadH) {
|
||||
*ppBuf = NULL;
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader qtaskinfo, readh is empty", SMA_VID(pSma));
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader qtaskinfo, readh is NULL", SMA_VID(pSma));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -153,7 +216,7 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t rsmaSnapRead(SRsmaSnapReader* pReader, uint8_t** ppData) {
|
||||
int32_t rsmaSnapRead(SRSmaSnapReader* pReader, uint8_t** ppData) {
|
||||
int32_t code = 0;
|
||||
|
||||
*ppData = NULL;
|
||||
|
@ -205,9 +268,9 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t rsmaSnapReaderClose(SRsmaSnapReader** ppReader) {
|
||||
int32_t rsmaSnapReaderClose(SRSmaSnapReader** ppReader) {
|
||||
int32_t code = 0;
|
||||
SRsmaSnapReader* pReader = *ppReader;
|
||||
SRSmaSnapReader* pReader = *ppReader;
|
||||
|
||||
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
||||
if (pReader->pDataReader[i]) {
|
||||
|
@ -215,11 +278,7 @@ int32_t rsmaSnapReaderClose(SRsmaSnapReader** ppReader) {
|
|||
}
|
||||
}
|
||||
|
||||
if (pReader->pQTaskFReader) {
|
||||
taosCloseFile(&pReader->pQTaskFReader->pReadH);
|
||||
taosMemoryFreeClear(pReader->pQTaskFReader);
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader closed for qTaskInfo", SMA_VID(pReader->pSma));
|
||||
}
|
||||
rsmaQTaskInfSnapReaderClose(&pReader->pQTaskFReader);
|
||||
|
||||
smaInfo("vgId:%d, vnode snapshot rsma reader closed", SMA_VID(pReader->pSma));
|
||||
|
||||
|
@ -227,8 +286,8 @@ int32_t rsmaSnapReaderClose(SRsmaSnapReader** ppReader) {
|
|||
return code;
|
||||
}
|
||||
|
||||
// SRsmaSnapWriter ========================================
|
||||
struct SRsmaSnapWriter {
|
||||
// SRSmaSnapWriter ========================================
|
||||
struct SRSmaSnapWriter {
|
||||
SSma* pSma;
|
||||
int64_t sver;
|
||||
int64_t ever;
|
||||
|
@ -244,13 +303,13 @@ struct SRsmaSnapWriter {
|
|||
SQTaskFWriter* pQTaskFWriter;
|
||||
};
|
||||
|
||||
int32_t rsmaSnapWriterOpen(SSma* pSma, int64_t sver, int64_t ever, SRsmaSnapWriter** ppWriter) {
|
||||
int32_t rsmaSnapWriterOpen(SSma* pSma, int64_t sver, int64_t ever, SRSmaSnapWriter** ppWriter) {
|
||||
int32_t code = 0;
|
||||
SRsmaSnapWriter* pWriter = NULL;
|
||||
SRSmaSnapWriter* pWriter = NULL;
|
||||
SVnode* pVnode = pSma->pVnode;
|
||||
|
||||
// alloc
|
||||
pWriter = (SRsmaSnapWriter*)taosMemoryCalloc(1, sizeof(*pWriter));
|
||||
pWriter = (SRSmaSnapWriter*)taosMemoryCalloc(1, sizeof(*pWriter));
|
||||
if (pWriter == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
|
@ -301,9 +360,9 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t rsmaSnapWriterClose(SRsmaSnapWriter** ppWriter, int8_t rollback) {
|
||||
int32_t rsmaSnapWriterClose(SRSmaSnapWriter** ppWriter, int8_t rollback) {
|
||||
int32_t code = 0;
|
||||
SRsmaSnapWriter* pWriter = *ppWriter;
|
||||
SRSmaSnapWriter* pWriter = *ppWriter;
|
||||
SVnode* pVnode = pWriter->pSma->pVnode;
|
||||
|
||||
if (rollback) {
|
||||
|
@ -332,7 +391,7 @@ int32_t rsmaSnapWriterClose(SRsmaSnapWriter** ppWriter, int8_t rollback) {
|
|||
pWriter->pQTaskFWriter->fname, qTaskInfoFullName);
|
||||
|
||||
// rsma restore
|
||||
if ((code = tdRsmaRestore(pWriter->pSma, RSMA_RESTORE_SYNC, pWriter->ever)) < 0) {
|
||||
if ((code = tdRSmaRestore(pWriter->pSma, RSMA_RESTORE_SYNC, pWriter->ever)) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
smaInfo("vgId:%d, vnode snapshot rsma writer restore from %s succeed", SMA_VID(pWriter->pSma), qTaskInfoFullName);
|
||||
|
@ -349,7 +408,7 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t rsmaSnapWrite(SRsmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData) {
|
||||
int32_t rsmaSnapWrite(SRSmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData) {
|
||||
int32_t code = 0;
|
||||
SSnapDataHdr* pHdr = (SSnapDataHdr*)pData;
|
||||
|
||||
|
@ -377,7 +436,7 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t rsmaSnapWriteQTaskInfo(SRsmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData) {
|
||||
static int32_t rsmaSnapWriteQTaskInfo(SRSmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData) {
|
||||
int32_t code = 0;
|
||||
SQTaskFWriter* qWriter = pWriter->pQTaskFWriter;
|
||||
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#define SMA_STORAGE_MINUTES_DAY 1440
|
||||
#define SMA_STORAGE_SPLIT_FACTOR 14400 // least records in tsma file
|
||||
|
||||
static int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *pMsg);
|
||||
static int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg);
|
||||
static int32_t tdProcessTSmaGetDaysImpl(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days);
|
||||
|
||||
// TODO: Who is responsible for resource allocate and release?
|
||||
int32_t tdProcessTSmaInsert(SSma *pSma, int64_t indexUid, const char *msg) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
@ -59,7 +63,7 @@ int32_t smaGetTSmaDays(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *
|
|||
* @param days unit is minute
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tdProcessTSmaGetDaysImpl(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days) {
|
||||
static int32_t tdProcessTSmaGetDaysImpl(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days) {
|
||||
SDecoder coder = {0};
|
||||
tDecoderInit(&coder, pCont, contLen);
|
||||
|
||||
|
@ -106,7 +110,7 @@ _err:
|
|||
* @param pMsg
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *pMsg) {
|
||||
static int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *pMsg) {
|
||||
SSmaCfg *pCfg = (SSmaCfg *)pMsg;
|
||||
|
||||
if (TD_VID(pSma->pVnode) == pCfg->dstVgId) {
|
||||
|
@ -145,7 +149,7 @@ int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *pMsg) {
|
|||
* @param msg
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) {
|
||||
static int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) {
|
||||
const SArray *pDataBlocks = (const SArray *)msg;
|
||||
// TODO: destroy SSDataBlocks(msg)
|
||||
if (!pDataBlocks) {
|
||||
|
@ -174,7 +178,6 @@ int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) {
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
tdRefSmaStat(pSma, pStat);
|
||||
pTsmaStat = SMA_STAT_TSMA(pStat);
|
||||
|
||||
if (!pTsmaStat->pTSma) {
|
||||
|
@ -226,9 +229,7 @@ int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) {
|
|||
goto _err;
|
||||
}
|
||||
|
||||
tdUnRefSmaStat(pSma, pStat);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
tdUnRefSmaStat(pSma, pStat);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
|
|
@ -305,93 +305,4 @@ int32_t tdReleaseSmaRef(int32_t rsetId, int64_t refId) {
|
|||
smaDebug("rsma release ref for rsetId:%" PRIi64 " refId:%d success", rsetId, refId);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tdCloneQTaskInfo(SSma *pSma, qTaskInfo_t dstTaskInfo, qTaskInfo_t srcTaskInfo, SRSmaParam *param,
|
||||
tb_uid_t suid, int8_t idx) {
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
char *pOutput = NULL;
|
||||
int32_t len = 0;
|
||||
|
||||
if ((terrno = qSerializeTaskStatus(srcTaskInfo, &pOutput, &len)) < 0) {
|
||||
smaError("vgId:%d, rsma clone, table %" PRIi64 " serialize qTaskInfo failed since %s", TD_VID(pVnode), suid,
|
||||
terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
SReadHandle handle = {
|
||||
.meta = pVnode->pMeta,
|
||||
.vnode = pVnode,
|
||||
.initTqReader = 1,
|
||||
};
|
||||
ASSERT(!dstTaskInfo);
|
||||
dstTaskInfo = qCreateStreamExecTaskInfo(param->qmsg[idx], &handle);
|
||||
if (!dstTaskInfo) {
|
||||
terrno = TSDB_CODE_RSMA_QTASKINFO_CREATE;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (qDeserializeTaskStatus(dstTaskInfo, pOutput, len) < 0) {
|
||||
smaError("vgId:%d, rsma clone, restore rsma task for table:%" PRIi64 " failed since %s", TD_VID(pVnode), suid,
|
||||
terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
smaDebug("vgId:%d, rsma clone, restore rsma task for table:%" PRIi64 " succeed", TD_VID(pVnode), suid);
|
||||
|
||||
taosMemoryFreeClear(pOutput);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
taosMemoryFreeClear(pOutput);
|
||||
tdFreeQTaskInfo(dstTaskInfo, TD_VID(pVnode), idx + 1);
|
||||
smaError("vgId:%d, rsma clone, restore rsma task for table:%" PRIi64 " failed since %s", TD_VID(pVnode), suid,
|
||||
terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clone qTaskInfo of SRSmaInfo
|
||||
*
|
||||
* @param pSma
|
||||
* @param pInfo
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tdCloneRSmaInfo(SSma *pSma, SRSmaInfo *pInfo) {
|
||||
SRSmaParam *param = NULL;
|
||||
if (!pInfo) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, SMA_META(pSma), 0);
|
||||
smaDebug("vgId:%d, rsma clone qTaskInfo for suid:%" PRIi64, SMA_VID(pSma), pInfo->suid);
|
||||
if (metaGetTableEntryByUid(&mr, pInfo->suid) < 0) {
|
||||
smaError("vgId:%d, rsma clone, failed to get table meta for %" PRIi64 " since %s", SMA_VID(pSma), pInfo->suid,
|
||||
terrstr());
|
||||
goto _err;
|
||||
}
|
||||
ASSERT(mr.me.type == TSDB_SUPER_TABLE);
|
||||
ASSERT(mr.me.uid == pInfo->suid);
|
||||
if (TABLE_IS_ROLLUP(mr.me.flags)) {
|
||||
param = &mr.me.stbEntry.rsmaParam;
|
||||
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
||||
if (!pInfo->iTaskInfo[i]) {
|
||||
continue;
|
||||
}
|
||||
if (tdCloneQTaskInfo(pSma, pInfo->taskInfo[i], pInfo->iTaskInfo[i], param, pInfo->suid, i) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
smaDebug("vgId:%d, rsma clone env success for %" PRIi64, SMA_VID(pSma), pInfo->suid);
|
||||
} else {
|
||||
terrno = TSDB_CODE_RSMA_INVALID_SCHEMA;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
metaReaderClear(&mr);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
metaReaderClear(&mr);
|
||||
smaError("vgId:%d, rsma clone env failed for %" PRIi64 " since %s", SMA_VID(pSma), pInfo->suid, terrstr());
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
|
@ -816,7 +816,86 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t version, char* msg, int32_t msg
|
|||
return streamMetaAddSerializedTask(pTq->pStreamMeta, version, msg, msgLen);
|
||||
}
|
||||
|
||||
int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* pReq, int64_t ver) {
|
||||
int32_t tqProcessDelReq(STQ* pTq, void* pReq, int32_t len, int64_t ver) {
|
||||
bool failed = false;
|
||||
SDecoder* pCoder = &(SDecoder){0};
|
||||
SDeleteRes* pRes = &(SDeleteRes){0};
|
||||
|
||||
pRes->uidList = taosArrayInit(0, sizeof(tb_uid_t));
|
||||
if (pRes->uidList == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
failed = true;
|
||||
}
|
||||
|
||||
tDecoderInit(pCoder, pReq, len);
|
||||
tDecodeDeleteRes(pCoder, pRes);
|
||||
tDecoderClear(pCoder);
|
||||
|
||||
int32_t sz = taosArrayGetSize(pRes->uidList);
|
||||
if (sz == 0) {
|
||||
taosArrayDestroy(pRes->uidList);
|
||||
return 0;
|
||||
}
|
||||
SSDataBlock* pDelBlock = createSpecialDataBlock(STREAM_DELETE_DATA);
|
||||
blockDataEnsureCapacity(pDelBlock, sz);
|
||||
pDelBlock->info.rows = sz;
|
||||
pDelBlock->info.version = ver;
|
||||
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
// start key column
|
||||
SColumnInfoData* pStartCol = taosArrayGet(pDelBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
colDataAppend(pStartCol, i, (const char*)&pRes->skey, false); // end key column
|
||||
SColumnInfoData* pEndCol = taosArrayGet(pDelBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
colDataAppend(pEndCol, i, (const char*)&pRes->ekey, false);
|
||||
// uid column
|
||||
SColumnInfoData* pUidCol = taosArrayGet(pDelBlock->pDataBlock, UID_COLUMN_INDEX);
|
||||
int64_t* pUid = taosArrayGet(pRes->uidList, i);
|
||||
colDataAppend(pUidCol, i, (const char*)pUid, false);
|
||||
|
||||
colDataAppendNULL(taosArrayGet(pDelBlock->pDataBlock, GROUPID_COLUMN_INDEX), i);
|
||||
colDataAppendNULL(taosArrayGet(pDelBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX), i);
|
||||
colDataAppendNULL(taosArrayGet(pDelBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX), i);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pRes->uidList);
|
||||
|
||||
void* pIter = NULL;
|
||||
while (1) {
|
||||
pIter = taosHashIterate(pTq->pStreamMeta->pTasks, pIter);
|
||||
if (pIter == NULL) break;
|
||||
SStreamTask* pTask = *(SStreamTask**)pIter;
|
||||
if (pTask->taskLevel != TASK_LEVEL__SOURCE) continue;
|
||||
|
||||
qDebug("delete req enqueue stream task: %d, ver: %" PRId64, pTask->taskId, ver);
|
||||
|
||||
SStreamDataBlock* pStreamBlock = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM);
|
||||
pStreamBlock->type = STREAM_INPUT__DATA_BLOCK;
|
||||
pStreamBlock->blocks = taosArrayInit(0, sizeof(SSDataBlock));
|
||||
SSDataBlock block = {0};
|
||||
assignOneDataBlock(&block, pDelBlock);
|
||||
block.info.type = STREAM_DELETE_DATA;
|
||||
taosArrayPush(pStreamBlock->blocks, &block);
|
||||
|
||||
if (!failed) {
|
||||
if (streamTaskInput(pTask, (SStreamQueueItem*)pStreamBlock) < 0) {
|
||||
qError("stream task input del failed, task id %d", pTask->taskId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (streamSchedExec(pTask) < 0) {
|
||||
qError("stream task launch failed, task id %d", pTask->taskId);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
streamTaskInputFail(pTask);
|
||||
}
|
||||
}
|
||||
blockDataDestroy(pDelBlock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqProcessSubmitReq(STQ* pTq, SSubmitReq* pReq, int64_t ver) {
|
||||
void* pIter = NULL;
|
||||
bool failed = false;
|
||||
SStreamDataSubmit* pSubmit = NULL;
|
||||
|
|
|
@ -213,20 +213,25 @@ int32_t tqPushMsgNew(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_
|
|||
#endif
|
||||
|
||||
int tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver) {
|
||||
if (vnodeIsRoleLeader(pTq->pVnode) && msgType == TDMT_VND_SUBMIT) {
|
||||
if (taosHashGetSize(pTq->pStreamMeta->pTasks) == 0) return 0;
|
||||
if (vnodeIsRoleLeader(pTq->pVnode)) {
|
||||
if (msgType == TDMT_VND_SUBMIT) {
|
||||
if (taosHashGetSize(pTq->pStreamMeta->pTasks) == 0) return 0;
|
||||
|
||||
void* data = taosMemoryMalloc(msgLen);
|
||||
if (data == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tqError("failed to copy data for stream since out of memory");
|
||||
return -1;
|
||||
void* data = taosMemoryMalloc(msgLen);
|
||||
if (data == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tqError("failed to copy data for stream since out of memory");
|
||||
return -1;
|
||||
}
|
||||
memcpy(data, msg, msgLen);
|
||||
SSubmitReq* pReq = (SSubmitReq*)data;
|
||||
pReq->version = ver;
|
||||
|
||||
tqProcessSubmitReq(pTq, data, ver);
|
||||
}
|
||||
if (msgType == TDMT_VND_DELETE) {
|
||||
tqProcessDelReq(pTq, POINTER_SHIFT(msg, sizeof(SMsgHead)), msgLen - sizeof(SMsgHead), ver);
|
||||
}
|
||||
memcpy(data, msg, msgLen);
|
||||
SSubmitReq* pReq = (SSubmitReq*)data;
|
||||
pReq->version = ver;
|
||||
|
||||
tqProcessStreamTrigger(pTq, data, ver);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -418,31 +418,17 @@ typedef enum {
|
|||
} SFSLASTNEXTROWSTATES;
|
||||
|
||||
typedef struct {
|
||||
SFSLASTNEXTROWSTATES state; // [input]
|
||||
STsdb *pTsdb; // [input]
|
||||
SBlockIdx *pBlockIdxExp; // [input]
|
||||
STSchema *pTSchema; // [input]
|
||||
SFSLASTNEXTROWSTATES state; // [input]
|
||||
STsdb *pTsdb; // [input]
|
||||
tb_uid_t suid;
|
||||
tb_uid_t uid;
|
||||
int32_t nFileSet;
|
||||
int32_t iFileSet;
|
||||
SArray *aDFileSet;
|
||||
SDataFReader *pDataFReader;
|
||||
SArray *aBlockL;
|
||||
SBlockL *pBlockL;
|
||||
SBlockData *pBlockDataL;
|
||||
SBlockData blockDataL;
|
||||
int32_t nRow;
|
||||
int32_t iRow;
|
||||
TSDBROW row;
|
||||
/*
|
||||
SArray *aBlockIdx;
|
||||
SBlockIdx *pBlockIdx;
|
||||
SMapData blockMap;
|
||||
int32_t nBlock;
|
||||
int32_t iBlock;
|
||||
SBlock block;
|
||||
*/
|
||||
|
||||
SMergeTree mergeTree;
|
||||
} SFSLastNextRowIter;
|
||||
|
||||
static int32_t getNextRowFromFSLast(void *iter, TSDBROW **ppRow) {
|
||||
|
@ -451,22 +437,16 @@ static int32_t getNextRowFromFSLast(void *iter, TSDBROW **ppRow) {
|
|||
|
||||
switch (state->state) {
|
||||
case SFSLASTNEXTROW_FS:
|
||||
// state->aDFileSet = state->pTsdb->pFS->cState->aDFileSet;
|
||||
state->nFileSet = taosArrayGetSize(state->aDFileSet);
|
||||
state->iFileSet = state->nFileSet;
|
||||
|
||||
state->pBlockDataL = NULL;
|
||||
|
||||
case SFSLASTNEXTROW_FILESET: {
|
||||
SDFileSet *pFileSet = NULL;
|
||||
_next_fileset:
|
||||
if (--state->iFileSet >= 0) {
|
||||
pFileSet = (SDFileSet *)taosArrayGet(state->aDFileSet, state->iFileSet);
|
||||
} else {
|
||||
if (state->pBlockDataL) {
|
||||
tBlockDataDestroy(state->pBlockDataL, 1);
|
||||
state->pBlockDataL = NULL;
|
||||
}
|
||||
// tMergeTreeClose(&state->mergeTree);
|
||||
|
||||
*ppRow = NULL;
|
||||
return code;
|
||||
|
@ -475,68 +455,24 @@ static int32_t getNextRowFromFSLast(void *iter, TSDBROW **ppRow) {
|
|||
code = tsdbDataFReaderOpen(&state->pDataFReader, state->pTsdb, pFileSet);
|
||||
if (code) goto _err;
|
||||
|
||||
if (!state->aBlockL) {
|
||||
state->aBlockL = taosArrayInit(0, sizeof(SBlockL));
|
||||
} else {
|
||||
taosArrayClear(state->aBlockL);
|
||||
}
|
||||
|
||||
code = tsdbReadBlockL(state->pDataFReader, state->aBlockL);
|
||||
if (code) goto _err;
|
||||
|
||||
// SBlockL *pBlockL = (SBlockL *)taosArrayGet(state->aBlockL, state->iBlockL);
|
||||
|
||||
state->pBlockL = taosArraySearch(state->aBlockL, state->pBlockIdxExp, tCmprBlockL, TD_EQ);
|
||||
if (!state->pBlockL) {
|
||||
tMergeTreeOpen(&state->mergeTree, 1, state->pDataFReader, state->suid, state->uid,
|
||||
&(STimeWindow){.skey = TSKEY_MIN, .ekey = TSKEY_MAX},
|
||||
&(SVersionRange){.minVer = 0, .maxVer = UINT64_MAX}, NULL, NULL);
|
||||
bool hasVal = tMergeTreeNext(&state->mergeTree);
|
||||
if (!hasVal) {
|
||||
state->state = SFSLASTNEXTROW_FILESET;
|
||||
// tMergeTreeClose(&state->mergeTree);
|
||||
goto _next_fileset;
|
||||
}
|
||||
|
||||
int64_t suid = state->pBlockL->suid;
|
||||
int64_t uid = state->pBlockL->maxUid;
|
||||
|
||||
if (!state->pBlockDataL) {
|
||||
state->pBlockDataL = &state->blockDataL;
|
||||
|
||||
tBlockDataCreate(state->pBlockDataL);
|
||||
}
|
||||
code = tBlockDataInit(state->pBlockDataL, suid, suid ? 0 : uid, state->pTSchema);
|
||||
if (code) goto _err;
|
||||
}
|
||||
case SFSLASTNEXTROW_BLOCKDATA:
|
||||
code = tsdbReadLastBlock(state->pDataFReader, state->pBlockL, state->pBlockDataL);
|
||||
if (code) goto _err;
|
||||
|
||||
state->nRow = state->blockDataL.nRow;
|
||||
state->iRow = state->nRow - 1;
|
||||
|
||||
if (!state->pBlockDataL->uid) {
|
||||
while (state->pBlockIdxExp->uid != state->pBlockDataL->aUid[state->iRow]) {
|
||||
--state->iRow;
|
||||
}
|
||||
}
|
||||
|
||||
state->state = SFSLASTNEXTROW_BLOCKROW;
|
||||
}
|
||||
case SFSLASTNEXTROW_BLOCKROW:
|
||||
if (state->pBlockDataL->uid) {
|
||||
if (state->iRow >= 0) {
|
||||
state->row = tsdbRowFromBlockData(state->pBlockDataL, state->iRow);
|
||||
*ppRow = &state->row;
|
||||
|
||||
if (--state->iRow < 0) {
|
||||
state->state = SFSLASTNEXTROW_FILESET;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (state->iRow >= 0 && state->pBlockIdxExp->uid == state->pBlockDataL->aUid[state->iRow]) {
|
||||
state->row = tsdbRowFromBlockData(state->pBlockDataL, state->iRow);
|
||||
*ppRow = &state->row;
|
||||
|
||||
if (--state->iRow < 0 || state->pBlockIdxExp->uid != state->pBlockDataL->aUid[state->iRow]) {
|
||||
state->state = SFSLASTNEXTROW_FILESET;
|
||||
}
|
||||
}
|
||||
state->row = tMergeTreeGetRow(&state->mergeTree);
|
||||
*ppRow = &state->row;
|
||||
bool hasVal = tMergeTreeNext(&state->mergeTree);
|
||||
if (!hasVal) {
|
||||
state->state = SFSLASTNEXTROW_FILESET;
|
||||
}
|
||||
|
||||
return code;
|
||||
default:
|
||||
ASSERT(0);
|
||||
|
@ -548,15 +484,6 @@ _err:
|
|||
tsdbDataFReaderClose(&state->pDataFReader);
|
||||
state->pDataFReader = NULL;
|
||||
}
|
||||
if (state->aBlockL) {
|
||||
taosArrayDestroy(state->aBlockL);
|
||||
state->aBlockL = NULL;
|
||||
}
|
||||
if (state->pBlockDataL) {
|
||||
tBlockDataDestroy(state->pBlockDataL, 1);
|
||||
state->pBlockDataL = NULL;
|
||||
}
|
||||
|
||||
*ppRow = NULL;
|
||||
|
||||
return code;
|
||||
|
@ -574,14 +501,6 @@ int32_t clearNextRowFromFSLast(void *iter) {
|
|||
tsdbDataFReaderClose(&state->pDataFReader);
|
||||
state->pDataFReader = NULL;
|
||||
}
|
||||
if (state->aBlockL) {
|
||||
taosArrayDestroy(state->aBlockL);
|
||||
state->aBlockL = NULL;
|
||||
}
|
||||
if (state->pBlockDataL) {
|
||||
tBlockDataDestroy(state->pBlockDataL, 1);
|
||||
state->pBlockDataL = NULL;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -609,7 +528,7 @@ typedef struct SFSNextRowIter {
|
|||
SMapData blockMap;
|
||||
int32_t nBlock;
|
||||
int32_t iBlock;
|
||||
SBlock block;
|
||||
SDataBlk block;
|
||||
SBlockData blockData;
|
||||
SBlockData *pBlockData;
|
||||
int32_t nRow;
|
||||
|
@ -670,7 +589,7 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
|
|||
}
|
||||
|
||||
tMapDataReset(&state->blockMap);
|
||||
code = tsdbReadBlock(state->pDataFReader, state->pBlockIdx, &state->blockMap);
|
||||
code = tsdbReadDataBlk(state->pDataFReader, state->pBlockIdx, &state->blockMap);
|
||||
if (code) goto _err;
|
||||
|
||||
state->nBlock = state->blockMap.nItem;
|
||||
|
@ -684,13 +603,13 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
|
|||
}
|
||||
case SFSNEXTROW_BLOCKDATA:
|
||||
if (state->iBlock >= 0) {
|
||||
SBlock block = {0};
|
||||
SDataBlk block = {0};
|
||||
|
||||
tBlockReset(&block);
|
||||
tDataBlkReset(&block);
|
||||
// tBlockDataReset(&state->blockData);
|
||||
tBlockDataReset(state->pBlockData);
|
||||
|
||||
tMapDataGetItemByIdx(&state->blockMap, state->iBlock, &block, tGetBlock);
|
||||
tMapDataGetItemByIdx(&state->blockMap, state->iBlock, &block, tGetDataBlk);
|
||||
/* code = tsdbReadBlockData(state->pDataFReader, &state->blockIdx, &block, &state->blockData, NULL, NULL); */
|
||||
tBlockDataReset(state->pBlockData);
|
||||
code = tBlockDataInit(state->pBlockData, state->suid, state->uid, state->pTSchema);
|
||||
|
@ -878,7 +797,7 @@ static bool tsdbKeyDeleted(TSDBKEY *key, SArray *pSkyline, int64_t *iSkyline) {
|
|||
if (key->ts > pItemBack->ts) {
|
||||
return false;
|
||||
} else if (key->ts >= pItemFront->ts && key->ts <= pItemBack->ts) {
|
||||
if ((key->version <= pItemFront->version || key->ts == pItemBack->ts && key->version <= pItemBack->version)) {
|
||||
if (key->version <= pItemFront->version || (key->ts == pItemBack->ts && key->version <= pItemBack->version)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -972,8 +891,6 @@ static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTs
|
|||
pIter->fsLastState.state = (SFSLASTNEXTROWSTATES)SFSNEXTROW_FS;
|
||||
pIter->fsLastState.pTsdb = pTsdb;
|
||||
pIter->fsLastState.aDFileSet = pIter->pReadSnap->fs.aDFileSet;
|
||||
pIter->fsLastState.pBlockIdxExp = &pIter->idx;
|
||||
pIter->fsLastState.pTSchema = pTSchema;
|
||||
pIter->fsLastState.suid = suid;
|
||||
pIter->fsLastState.uid = uid;
|
||||
|
||||
|
@ -1372,25 +1289,33 @@ int32_t tsdbCacheGetLastH(SLRUCache *pCache, tb_uid_t uid, STsdb *pTsdb, LRUHand
|
|||
// getTableCacheKeyS(uid, "l", key, &keyLen);
|
||||
getTableCacheKey(uid, 1, key, &keyLen);
|
||||
LRUHandle *h = taosLRUCacheLookup(pCache, key, keyLen);
|
||||
if (h) {
|
||||
} else {
|
||||
SArray *pLastArray = NULL;
|
||||
code = mergeLast(uid, pTsdb, &pLastArray);
|
||||
// if table's empty or error, return code of -1
|
||||
// if (code < 0 || pRow == NULL) {
|
||||
if (code < 0 || pLastArray == NULL) {
|
||||
*handle = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_taos_lru_deleter_t deleter = deleteTableCacheLast;
|
||||
LRUStatus status =
|
||||
taosLRUCacheInsert(pCache, key, keyLen, pLastArray, pLastArray->capacity, deleter, NULL, TAOS_LRU_PRIORITY_LOW);
|
||||
if (status != TAOS_LRU_STATUS_OK) {
|
||||
code = -1;
|
||||
}
|
||||
if (!h) {
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
h = taosLRUCacheLookup(pCache, key, keyLen);
|
||||
if (!h) {
|
||||
SArray *pLastArray = NULL;
|
||||
code = mergeLast(uid, pTsdb, &pLastArray);
|
||||
// if table's empty or error, return code of -1
|
||||
// if (code < 0 || pRow == NULL) {
|
||||
if (code < 0 || pLastArray == NULL) {
|
||||
*handle = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_taos_lru_deleter_t deleter = deleteTableCacheLast;
|
||||
LRUStatus status = taosLRUCacheInsert(pCache, key, keyLen, pLastArray, pLastArray->capacity, deleter, NULL,
|
||||
TAOS_LRU_PRIORITY_LOW);
|
||||
if (status != TAOS_LRU_STATUS_OK) {
|
||||
code = -1;
|
||||
}
|
||||
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
|
||||
h = taosLRUCacheLookup(pCache, key, keyLen);
|
||||
} else {
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
}
|
||||
}
|
||||
|
||||
*handle = h;
|
||||
|
@ -1411,3 +1336,5 @@ void tsdbCacheSetCapacity(SVnode *pVnode, size_t capacity) {
|
|||
}
|
||||
|
||||
size_t tsdbCacheGetCapacity(SVnode *pVnode) { return taosLRUCacheGetCapacity(pVnode->pTsdb->lruCache); }
|
||||
|
||||
size_t tsdbCacheGetUsage(SVnode *pVnode) { return taosLRUCacheGetUsage(pVnode->pTsdb->lruCache); }
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
typedef struct {
|
||||
STsdb *pTsdb;
|
||||
STsdbFS fs;
|
||||
} STsdbCompactor;
|
||||
|
||||
int32_t tsdbCompact(STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
// Integer =====================================================
|
||||
typedef struct {
|
||||
int8_t rawCopy;
|
||||
int64_t prevVal;
|
||||
int32_t nVal;
|
||||
int32_t nBuf;
|
||||
uint8_t *pBuf;
|
||||
} SIntCompressor;
|
||||
|
||||
#define I64_SAFE_ADD(a, b) (((a) >= 0 && (b) <= INT64_MAX - (b)) || ((a) < 0 && (b) >= INT64_MIN - (a)))
|
||||
#define SIMPLE8B_MAX ((uint64_t)1152921504606846974LL)
|
||||
|
||||
static int32_t tsdbCmprI64(SIntCompressor *pCompressor, int64_t val) {
|
||||
int32_t code = 0;
|
||||
|
||||
// raw copy
|
||||
if (pCompressor->rawCopy) {
|
||||
memcpy(pCompressor->pBuf + pCompressor->nBuf, &val, sizeof(val));
|
||||
pCompressor->nBuf += sizeof(val);
|
||||
pCompressor->nVal++;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (!I64_SAFE_ADD(val, pCompressor->prevVal)) {
|
||||
pCompressor->rawCopy = 1;
|
||||
// TODO: decompress and copy
|
||||
pCompressor->nVal++;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
int64_t diff = val - pCompressor->prevVal;
|
||||
uint8_t zigzag = ZIGZAGE(int64_t, diff);
|
||||
|
||||
if (zigzag >= SIMPLE8B_MAX) {
|
||||
pCompressor->rawCopy = 1;
|
||||
// TODO: decompress and copy
|
||||
pCompressor->nVal++;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
// Timestamp =====================================================
|
||||
|
||||
// Float =====================================================
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
typedef struct SDiskColBuilder SDiskColBuilder;
|
||||
struct SDiskColBuilder {
|
||||
uint8_t flags;
|
||||
uint8_t *pBitMap;
|
||||
int32_t *aOffset;
|
||||
int32_t nData;
|
||||
uint8_t *pData;
|
||||
};
|
||||
|
||||
int32_t tDiskColAddVal(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
typedef struct SDiskDataBuilder SDiskDataBuilder;
|
||||
struct SDiskDataBuilder {
|
||||
SDiskDataHdr hdr;
|
||||
SArray *aBlockCol; // SArray<SBlockCol>
|
||||
};
|
||||
|
||||
int32_t tDiskDataBuilderCreate(SDiskDataBuilder **ppBuilder) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
void tDiskDataBuilderDestroy(SDiskDataBuilder *pBuilder) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void tDiskDataBuilderInit(SDiskDataBuilder *pBuilder, int64_t suid, int64_t uid, STSchema *pTSchema, int8_t cmprAlg) {
|
||||
pBuilder->hdr = (SDiskDataHdr){.delimiter = TSDB_FILE_DLMT, //
|
||||
.fmtVer = 0,
|
||||
.suid = suid,
|
||||
.uid = uid,
|
||||
.cmprAlg = cmprAlg};
|
||||
}
|
||||
|
||||
void tDiskDataBuilderReset(SDiskDataBuilder *pBuilder) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t tDiskDataBuilderAddRow(SDiskDataBuilder *pBuilder, TSDBROW *pRow, STSchema *pTSchema, int64_t uid) {
|
||||
int32_t code = 0;
|
||||
|
||||
// uid (todo)
|
||||
|
||||
// version (todo)
|
||||
|
||||
// TSKEY (todo)
|
||||
|
||||
SRowIter iter = {0};
|
||||
tRowIterInit(&iter, pRow, pTSchema);
|
||||
|
||||
for (int32_t iDiskCol = 0; iDiskCol < 0; iDiskCol++) {
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tDiskDataBuilderGet(SDiskDataBuilder *pBuilder, uint8_t **ppData) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
|
@ -21,6 +21,9 @@ static int32_t tsdbEncodeFS(uint8_t *p, STsdbFS *pFS) {
|
|||
int8_t hasDel = pFS->pDelFile ? 1 : 0;
|
||||
uint32_t nSet = taosArrayGetSize(pFS->aDFileSet);
|
||||
|
||||
// version
|
||||
n += tPutI8(p ? p + n : p, 0);
|
||||
|
||||
// SDelFile
|
||||
n += tPutI8(p ? p + n : p, hasDel);
|
||||
if (hasDel) {
|
||||
|
@ -110,7 +113,7 @@ _err:
|
|||
// taosRemoveFile(fname);
|
||||
// }
|
||||
|
||||
// // last
|
||||
// // stt
|
||||
// if (isSameDisk && pFrom->pLastF->commitID == pTo->pLastF->commitID) {
|
||||
// if (pFrom->pLastF->size > pTo->pLastF->size) {
|
||||
// code = tsdbDFileRollback(pFS->pTsdb, pTo, TSDB_LAST_FILE);
|
||||
|
@ -140,7 +143,7 @@ _err:
|
|||
// tsdbDataFileName(pFS->pTsdb, pFrom->diskId, pFrom->fid, pFrom->pDataF, fname);
|
||||
// taosRemoveFile(fname);
|
||||
|
||||
// // last
|
||||
// // stt
|
||||
// tsdbLastFileName(pFS->pTsdb, pFrom->diskId, pFrom->fid, pFrom->pLastF, fname);
|
||||
// taosRemoveFile(fname);
|
||||
|
||||
|
@ -254,8 +257,10 @@ void tsdbFSDestroy(STsdbFS *pFS) {
|
|||
SDFileSet *pSet = (SDFileSet *)taosArrayGet(pFS->aDFileSet, iSet);
|
||||
taosMemoryFree(pSet->pHeadF);
|
||||
taosMemoryFree(pSet->pDataF);
|
||||
taosMemoryFree(pSet->pLastF);
|
||||
taosMemoryFree(pSet->pSmaF);
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
taosMemoryFree(pSet->aSttF[iStt]);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pFS->aDFileSet);
|
||||
|
@ -290,7 +295,7 @@ static int32_t tsdbScanAndTryFixFS(STsdb *pTsdb) {
|
|||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _err;
|
||||
}
|
||||
if (size != pSet->pHeadF->size) {
|
||||
if (size != tsdbLogicToFileSize(pSet->pHeadF->size, pTsdb->pVnode->config.tsdbPageSize)) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _err;
|
||||
}
|
||||
|
@ -301,38 +306,40 @@ static int32_t tsdbScanAndTryFixFS(STsdb *pTsdb) {
|
|||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _err;
|
||||
}
|
||||
if (size < pSet->pDataF->size) {
|
||||
if (size < tsdbLogicToFileSize(pSet->pDataF->size, pTsdb->pVnode->config.tsdbPageSize)) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _err;
|
||||
} else if (size > pSet->pDataF->size) {
|
||||
} else if (size > tsdbLogicToFileSize(pSet->pDataF->size, pTsdb->pVnode->config.tsdbPageSize)) {
|
||||
code = tsdbDFileRollback(pTsdb, pSet, TSDB_DATA_FILE);
|
||||
if (code) goto _err;
|
||||
}
|
||||
|
||||
// last ===========
|
||||
tsdbLastFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pLastF, fname);
|
||||
if (taosStatFile(fname, &size, NULL)) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _err;
|
||||
}
|
||||
if (size != pSet->pLastF->size) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// sma =============
|
||||
tsdbSmaFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pSmaF, fname);
|
||||
if (taosStatFile(fname, &size, NULL)) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _err;
|
||||
}
|
||||
if (size < pSet->pSmaF->size) {
|
||||
if (size < tsdbLogicToFileSize(pSet->pSmaF->size, pTsdb->pVnode->config.tsdbPageSize)) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _err;
|
||||
} else if (size > pSet->pSmaF->size) {
|
||||
} else if (size > tsdbLogicToFileSize(pSet->pSmaF->size, pTsdb->pVnode->config.tsdbPageSize)) {
|
||||
code = tsdbDFileRollback(pTsdb, pSet, TSDB_SMA_FILE);
|
||||
if (code) goto _err;
|
||||
}
|
||||
|
||||
// stt ===========
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
tsdbSttFileName(pTsdb, pSet->diskId, pSet->fid, pSet->aSttF[iStt], fname);
|
||||
if (taosStatFile(fname, &size, NULL)) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _err;
|
||||
}
|
||||
if (size != tsdbLogicToFileSize(pSet->aSttF[iStt]->size, pTsdb->pVnode->config.tsdbPageSize)) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -360,10 +367,12 @@ static int32_t tsdbRecoverFS(STsdb *pTsdb, uint8_t *pData, int64_t nData) {
|
|||
int32_t code = 0;
|
||||
int8_t hasDel;
|
||||
uint32_t nSet;
|
||||
int32_t n;
|
||||
int32_t n = 0;
|
||||
|
||||
// version
|
||||
n += tGetI8(pData + n, NULL);
|
||||
|
||||
// SDelFile
|
||||
n = 0;
|
||||
n += tGetI8(pData + n, &hasDel);
|
||||
if (hasDel) {
|
||||
pTsdb->fs.pDelFile = (SDelFile *)taosMemoryMalloc(sizeof(SDelFile));
|
||||
|
@ -382,41 +391,15 @@ static int32_t tsdbRecoverFS(STsdb *pTsdb, uint8_t *pData, int64_t nData) {
|
|||
taosArrayClear(pTsdb->fs.aDFileSet);
|
||||
n += tGetU32v(pData + n, &nSet);
|
||||
for (uint32_t iSet = 0; iSet < nSet; iSet++) {
|
||||
SDFileSet fSet;
|
||||
SDFileSet fSet = {0};
|
||||
|
||||
// head
|
||||
fSet.pHeadF = (SHeadFile *)taosMemoryCalloc(1, sizeof(SHeadFile));
|
||||
if (fSet.pHeadF == NULL) {
|
||||
int32_t nt = tGetDFileSet(pData + n, &fSet);
|
||||
if (nt < 0) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
fSet.pHeadF->nRef = 1;
|
||||
|
||||
// data
|
||||
fSet.pDataF = (SDataFile *)taosMemoryCalloc(1, sizeof(SDataFile));
|
||||
if (fSet.pDataF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
fSet.pDataF->nRef = 1;
|
||||
|
||||
// last
|
||||
fSet.pLastF = (SLastFile *)taosMemoryCalloc(1, sizeof(SLastFile));
|
||||
if (fSet.pLastF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
fSet.pLastF->nRef = 1;
|
||||
|
||||
// sma
|
||||
fSet.pSmaF = (SSmaFile *)taosMemoryCalloc(1, sizeof(SSmaFile));
|
||||
if (fSet.pSmaF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
fSet.pSmaF->nRef = 1;
|
||||
|
||||
n += tGetDFileSet(pData + n, &fSet);
|
||||
n += nt;
|
||||
|
||||
if (taosArrayPush(pTsdb->fs.aDFileSet, &fSet) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -532,13 +515,15 @@ int32_t tsdbFSClose(STsdb *pTsdb) {
|
|||
ASSERT(pSet->pDataF->nRef == 1);
|
||||
taosMemoryFree(pSet->pDataF);
|
||||
|
||||
// last
|
||||
ASSERT(pSet->pLastF->nRef == 1);
|
||||
taosMemoryFree(pSet->pLastF);
|
||||
|
||||
// sma
|
||||
ASSERT(pSet->pSmaF->nRef == 1);
|
||||
taosMemoryFree(pSet->pSmaF);
|
||||
|
||||
// stt
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
ASSERT(pSet->aSttF[iStt]->nRef == 1);
|
||||
taosMemoryFree(pSet->aSttF[iStt]);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pTsdb->fs.aDFileSet);
|
||||
|
@ -586,15 +571,7 @@ int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS) {
|
|||
}
|
||||
*fSet.pDataF = *pSet->pDataF;
|
||||
|
||||
// data
|
||||
fSet.pLastF = (SLastFile *)taosMemoryMalloc(sizeof(SLastFile));
|
||||
if (fSet.pLastF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*fSet.pLastF = *pSet->pLastF;
|
||||
|
||||
// last
|
||||
// sma
|
||||
fSet.pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
|
||||
if (fSet.pSmaF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -602,6 +579,16 @@ int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS) {
|
|||
}
|
||||
*fSet.pSmaF = *pSet->pSmaF;
|
||||
|
||||
// stt
|
||||
for (fSet.nSttF = 0; fSet.nSttF < pSet->nSttF; fSet.nSttF++) {
|
||||
fSet.aSttF[fSet.nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (fSet.aSttF[fSet.nSttF] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*fSet.aSttF[fSet.nSttF] = *pSet->aSttF[fSet.nSttF];
|
||||
}
|
||||
|
||||
if (taosArrayPush(pFS->aDFileSet, &fSet) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
|
@ -651,14 +638,38 @@ int32_t tsdbFSUpsertFSet(STsdbFS *pFS, SDFileSet *pSet) {
|
|||
if (c == 0) {
|
||||
*pDFileSet->pHeadF = *pSet->pHeadF;
|
||||
*pDFileSet->pDataF = *pSet->pDataF;
|
||||
*pDFileSet->pLastF = *pSet->pLastF;
|
||||
*pDFileSet->pSmaF = *pSet->pSmaF;
|
||||
// stt
|
||||
if (pSet->nSttF > pDFileSet->nSttF) {
|
||||
ASSERT(pSet->nSttF == pDFileSet->nSttF + 1);
|
||||
|
||||
pDFileSet->aSttF[pDFileSet->nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (pDFileSet->aSttF[pDFileSet->nSttF] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*pDFileSet->aSttF[pDFileSet->nSttF] = *pSet->aSttF[pSet->nSttF - 1];
|
||||
pDFileSet->nSttF++;
|
||||
} else if (pSet->nSttF < pDFileSet->nSttF) {
|
||||
ASSERT(pSet->nSttF == 1);
|
||||
for (int32_t iStt = 1; iStt < pDFileSet->nSttF; iStt++) {
|
||||
taosMemoryFree(pDFileSet->aSttF[iStt]);
|
||||
}
|
||||
|
||||
*pDFileSet->aSttF[0] = *pSet->aSttF[0];
|
||||
pDFileSet->nSttF = 1;
|
||||
} else {
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
*pDFileSet->aSttF[iStt] = *pSet->aSttF[iStt];
|
||||
}
|
||||
}
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
|
||||
SDFileSet fSet = {.diskId = pSet->diskId, .fid = pSet->fid};
|
||||
ASSERT(pSet->nSttF == 1);
|
||||
SDFileSet fSet = {.diskId = pSet->diskId, .fid = pSet->fid, .nSttF = 1};
|
||||
|
||||
// head
|
||||
fSet.pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile));
|
||||
|
@ -676,15 +687,7 @@ int32_t tsdbFSUpsertFSet(STsdbFS *pFS, SDFileSet *pSet) {
|
|||
}
|
||||
*fSet.pDataF = *pSet->pDataF;
|
||||
|
||||
// data
|
||||
fSet.pLastF = (SLastFile *)taosMemoryMalloc(sizeof(SLastFile));
|
||||
if (fSet.pLastF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*fSet.pLastF = *pSet->pLastF;
|
||||
|
||||
// last
|
||||
// sma
|
||||
fSet.pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
|
||||
if (fSet.pSmaF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -692,6 +695,14 @@ int32_t tsdbFSUpsertFSet(STsdbFS *pFS, SDFileSet *pSet) {
|
|||
}
|
||||
*fSet.pSmaF = *pSet->pSmaF;
|
||||
|
||||
// stt
|
||||
fSet.aSttF[0] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (fSet.aSttF[0] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*fSet.aSttF[0] = *pSet->aSttF[0];
|
||||
|
||||
if (taosArrayInsert(pFS->aDFileSet, idx, &fSet) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
|
@ -836,27 +847,6 @@ int32_t tsdbFSCommit2(STsdb *pTsdb, STsdbFS *pFSNew) {
|
|||
pSetOld->pDataF->size = pSetNew->pDataF->size;
|
||||
}
|
||||
|
||||
// last
|
||||
fSet.pLastF = pSetOld->pLastF;
|
||||
if ((!sameDisk) || (pSetOld->pLastF->commitID != pSetNew->pLastF->commitID)) {
|
||||
pSetOld->pLastF = (SLastFile *)taosMemoryMalloc(sizeof(SLastFile));
|
||||
if (pSetOld->pLastF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
*pSetOld->pLastF = *pSetNew->pLastF;
|
||||
pSetOld->pLastF->nRef = 1;
|
||||
|
||||
nRef = atomic_sub_fetch_32(&fSet.pLastF->nRef, 1);
|
||||
if (nRef == 0) {
|
||||
tsdbLastFileName(pTsdb, pSetOld->diskId, pSetOld->fid, fSet.pLastF, fname);
|
||||
taosRemoveFile(fname);
|
||||
taosMemoryFree(fSet.pLastF);
|
||||
}
|
||||
} else {
|
||||
ASSERT(pSetOld->pLastF->size == pSetNew->pLastF->size);
|
||||
}
|
||||
|
||||
// sma
|
||||
fSet.pSmaF = pSetOld->pSmaF;
|
||||
if ((!sameDisk) || (pSetOld->pSmaF->commitID != pSetNew->pSmaF->commitID)) {
|
||||
|
@ -879,6 +869,84 @@ int32_t tsdbFSCommit2(STsdb *pTsdb, STsdbFS *pFSNew) {
|
|||
pSetOld->pSmaF->size = pSetNew->pSmaF->size;
|
||||
}
|
||||
|
||||
// stt
|
||||
if (sameDisk) {
|
||||
if (pSetNew->nSttF > pSetOld->nSttF) {
|
||||
ASSERT(pSetNew->nSttF = pSetOld->nSttF + 1);
|
||||
pSetOld->aSttF[pSetOld->nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (pSetOld->aSttF[pSetOld->nSttF] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
*pSetOld->aSttF[pSetOld->nSttF] = *pSetNew->aSttF[pSetOld->nSttF];
|
||||
pSetOld->aSttF[pSetOld->nSttF]->nRef = 1;
|
||||
pSetOld->nSttF++;
|
||||
} else if (pSetNew->nSttF < pSetOld->nSttF) {
|
||||
ASSERT(pSetNew->nSttF == 1);
|
||||
for (int32_t iStt = 0; iStt < pSetOld->nSttF; iStt++) {
|
||||
SSttFile *pSttFile = pSetOld->aSttF[iStt];
|
||||
nRef = atomic_sub_fetch_32(&pSttFile->nRef, 1);
|
||||
if (nRef == 0) {
|
||||
tsdbSttFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSttFile, fname);
|
||||
taosRemoveFile(fname);
|
||||
taosMemoryFree(pSttFile);
|
||||
}
|
||||
pSetOld->aSttF[iStt] = NULL;
|
||||
}
|
||||
|
||||
pSetOld->nSttF = 1;
|
||||
pSetOld->aSttF[0] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (pSetOld->aSttF[0] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
*pSetOld->aSttF[0] = *pSetNew->aSttF[0];
|
||||
pSetOld->aSttF[0]->nRef = 1;
|
||||
} else {
|
||||
for (int32_t iStt = 0; iStt < pSetOld->nSttF; iStt++) {
|
||||
if (pSetOld->aSttF[iStt]->commitID != pSetNew->aSttF[iStt]->commitID) {
|
||||
SSttFile *pSttFile = pSetOld->aSttF[iStt];
|
||||
nRef = atomic_sub_fetch_32(&pSttFile->nRef, 1);
|
||||
if (nRef == 0) {
|
||||
tsdbSttFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSttFile, fname);
|
||||
taosRemoveFile(fname);
|
||||
taosMemoryFree(pSttFile);
|
||||
}
|
||||
|
||||
pSetOld->aSttF[iStt] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (pSetOld->aSttF[iStt] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
*pSetOld->aSttF[iStt] = *pSetNew->aSttF[iStt];
|
||||
pSetOld->aSttF[iStt]->nRef = 1;
|
||||
} else {
|
||||
ASSERT(pSetOld->aSttF[iStt]->size == pSetOld->aSttF[iStt]->size);
|
||||
ASSERT(pSetOld->aSttF[iStt]->offset == pSetOld->aSttF[iStt]->offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ASSERT(pSetOld->nSttF == pSetNew->nSttF);
|
||||
for (int32_t iStt = 0; iStt < pSetOld->nSttF; iStt++) {
|
||||
SSttFile *pSttFile = pSetOld->aSttF[iStt];
|
||||
nRef = atomic_sub_fetch_32(&pSttFile->nRef, 1);
|
||||
if (nRef == 0) {
|
||||
tsdbSttFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSttFile, fname);
|
||||
taosRemoveFile(fname);
|
||||
taosMemoryFree(pSttFile);
|
||||
}
|
||||
|
||||
pSetOld->aSttF[iStt] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (pSetOld->aSttF[iStt] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
*pSetOld->aSttF[iStt] = *pSetNew->aSttF[iStt];
|
||||
pSetOld->aSttF[iStt]->nRef = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sameDisk) {
|
||||
pSetOld->diskId = pSetNew->diskId;
|
||||
}
|
||||
|
@ -902,13 +970,6 @@ int32_t tsdbFSCommit2(STsdb *pTsdb, STsdbFS *pFSNew) {
|
|||
taosMemoryFree(pSetOld->pDataF);
|
||||
}
|
||||
|
||||
nRef = atomic_sub_fetch_32(&pSetOld->pLastF->nRef, 1);
|
||||
if (nRef == 0) {
|
||||
tsdbLastFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSetOld->pLastF, fname);
|
||||
taosRemoveFile(fname);
|
||||
taosMemoryFree(pSetOld->pLastF);
|
||||
}
|
||||
|
||||
nRef = atomic_sub_fetch_32(&pSetOld->pSmaF->nRef, 1);
|
||||
if (nRef == 0) {
|
||||
tsdbSmaFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSetOld->pSmaF, fname);
|
||||
|
@ -916,12 +977,20 @@ int32_t tsdbFSCommit2(STsdb *pTsdb, STsdbFS *pFSNew) {
|
|||
taosMemoryFree(pSetOld->pSmaF);
|
||||
}
|
||||
|
||||
for (int8_t iStt = 0; iStt < pSetOld->nSttF; iStt++) {
|
||||
nRef = atomic_sub_fetch_32(&pSetOld->aSttF[iStt]->nRef, 1);
|
||||
if (nRef == 0) {
|
||||
tsdbSttFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSetOld->aSttF[iStt], fname);
|
||||
taosRemoveFile(fname);
|
||||
taosMemoryFree(pSetOld->aSttF[iStt]);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayRemove(pTsdb->fs.aDFileSet, iOld);
|
||||
continue;
|
||||
|
||||
_add_new:
|
||||
fSet.diskId = pSetNew->diskId;
|
||||
fSet.fid = pSetNew->fid;
|
||||
fSet = (SDFileSet){.diskId = pSetNew->diskId, .fid = pSetNew->fid, .nSttF = 1};
|
||||
|
||||
// head
|
||||
fSet.pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile));
|
||||
|
@ -941,15 +1010,6 @@ int32_t tsdbFSCommit2(STsdb *pTsdb, STsdbFS *pFSNew) {
|
|||
*fSet.pDataF = *pSetNew->pDataF;
|
||||
fSet.pDataF->nRef = 1;
|
||||
|
||||
// last
|
||||
fSet.pLastF = (SLastFile *)taosMemoryMalloc(sizeof(SLastFile));
|
||||
if (fSet.pLastF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
*fSet.pLastF = *pSetNew->pLastF;
|
||||
fSet.pLastF->nRef = 1;
|
||||
|
||||
// sma
|
||||
fSet.pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
|
||||
if (fSet.pSmaF == NULL) {
|
||||
|
@ -959,6 +1019,16 @@ int32_t tsdbFSCommit2(STsdb *pTsdb, STsdbFS *pFSNew) {
|
|||
*fSet.pSmaF = *pSetNew->pSmaF;
|
||||
fSet.pSmaF->nRef = 1;
|
||||
|
||||
// stt
|
||||
ASSERT(pSetNew->nSttF == 1);
|
||||
fSet.aSttF[0] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (fSet.aSttF[0] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
*fSet.aSttF[0] = *pSetNew->aSttF[0];
|
||||
fSet.aSttF[0]->nRef = 1;
|
||||
|
||||
if (taosArrayInsert(pTsdb->fs.aDFileSet, iOld, &fSet) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
|
@ -1002,12 +1072,14 @@ int32_t tsdbFSRef(STsdb *pTsdb, STsdbFS *pFS) {
|
|||
nRef = atomic_fetch_add_32(&pSet->pDataF->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
|
||||
nRef = atomic_fetch_add_32(&pSet->pLastF->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
|
||||
nRef = atomic_fetch_add_32(&pSet->pSmaF->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
nRef = atomic_fetch_add_32(&pSet->aSttF[iStt]->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
}
|
||||
|
||||
if (taosArrayPush(pFS->aDFileSet, &fSet) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
|
@ -1053,15 +1125,6 @@ void tsdbFSUnref(STsdb *pTsdb, STsdbFS *pFS) {
|
|||
taosMemoryFree(pSet->pDataF);
|
||||
}
|
||||
|
||||
// last
|
||||
nRef = atomic_sub_fetch_32(&pSet->pLastF->nRef, 1);
|
||||
ASSERT(nRef >= 0);
|
||||
if (nRef == 0) {
|
||||
tsdbLastFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pLastF, fname);
|
||||
taosRemoveFile(fname);
|
||||
taosMemoryFree(pSet->pLastF);
|
||||
}
|
||||
|
||||
// sma
|
||||
nRef = atomic_sub_fetch_32(&pSet->pSmaF->nRef, 1);
|
||||
ASSERT(nRef >= 0);
|
||||
|
@ -1070,6 +1133,18 @@ void tsdbFSUnref(STsdb *pTsdb, STsdbFS *pFS) {
|
|||
taosRemoveFile(fname);
|
||||
taosMemoryFree(pSet->pSmaF);
|
||||
}
|
||||
|
||||
// stt
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
nRef = atomic_sub_fetch_32(&pSet->aSttF[iStt]->nRef, 1);
|
||||
ASSERT(nRef >= 0);
|
||||
if (nRef == 0) {
|
||||
tsdbSttFileName(pTsdb, pSet->diskId, pSet->fid, pSet->aSttF[iStt], fname);
|
||||
taosRemoveFile(fname);
|
||||
taosMemoryFree(pSet->aSttF[iStt]);
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pFS->aDFileSet);
|
||||
|
|
|
@ -53,22 +53,22 @@ static int32_t tGetDataFile(uint8_t *p, SDataFile *pDataFile) {
|
|||
return n;
|
||||
}
|
||||
|
||||
int32_t tPutLastFile(uint8_t *p, SLastFile *pLastFile) {
|
||||
int32_t tPutSttFile(uint8_t *p, SSttFile *pSttFile) {
|
||||
int32_t n = 0;
|
||||
|
||||
n += tPutI64v(p ? p + n : p, pLastFile->commitID);
|
||||
n += tPutI64v(p ? p + n : p, pLastFile->size);
|
||||
n += tPutI64v(p ? p + n : p, pLastFile->offset);
|
||||
n += tPutI64v(p ? p + n : p, pSttFile->commitID);
|
||||
n += tPutI64v(p ? p + n : p, pSttFile->size);
|
||||
n += tPutI64v(p ? p + n : p, pSttFile->offset);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int32_t tGetLastFile(uint8_t *p, SLastFile *pLastFile) {
|
||||
static int32_t tGetSttFile(uint8_t *p, SSttFile *pSttFile) {
|
||||
int32_t n = 0;
|
||||
|
||||
n += tGetI64v(p + n, &pLastFile->commitID);
|
||||
n += tGetI64v(p + n, &pLastFile->size);
|
||||
n += tGetI64v(p + n, &pLastFile->offset);
|
||||
n += tGetI64v(p + n, &pSttFile->commitID);
|
||||
n += tGetI64v(p + n, &pSttFile->size);
|
||||
n += tGetI64v(p + n, &pSttFile->offset);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -102,9 +102,9 @@ void tsdbDataFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SDataFile *pDataF,
|
|||
TD_DIRSEP, pTsdb->path, TD_DIRSEP, TD_VID(pTsdb->pVnode), fid, pDataF->commitID, ".data");
|
||||
}
|
||||
|
||||
void tsdbLastFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SLastFile *pLastF, char fname[]) {
|
||||
void tsdbSttFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SSttFile *pSttF, char fname[]) {
|
||||
snprintf(fname, TSDB_FILENAME_LEN - 1, "%s%s%s%sv%df%dver%" PRId64 "%s", tfsGetDiskPath(pTsdb->pVnode->pTfs, did),
|
||||
TD_DIRSEP, pTsdb->path, TD_DIRSEP, TD_VID(pTsdb->pVnode), fid, pLastF->commitID, ".last");
|
||||
TD_DIRSEP, pTsdb->path, TD_DIRSEP, TD_VID(pTsdb->pVnode), fid, pSttF->commitID, ".stt");
|
||||
}
|
||||
|
||||
void tsdbSmaFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SSmaFile *pSmaF, char fname[]) {
|
||||
|
@ -148,7 +148,7 @@ int32_t tsdbDFileRollback(STsdb *pTsdb, SDFileSet *pSet, EDataFileT ftype) {
|
|||
}
|
||||
|
||||
// ftruncate
|
||||
if (taosFtruncateFile(pFD, size) < 0) {
|
||||
if (taosFtruncateFile(pFD, tsdbLogicToFileSize(size, pTsdb->pVnode->config.tsdbPageSize)) < 0) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _err;
|
||||
}
|
||||
|
@ -194,9 +194,11 @@ int32_t tPutDFileSet(uint8_t *p, SDFileSet *pSet) {
|
|||
n += tPutDataFile(p ? p + n : p, pSet->pDataF);
|
||||
n += tPutSmaFile(p ? p + n : p, pSet->pSmaF);
|
||||
|
||||
// last
|
||||
n += tPutU8(p ? p + n : p, 1); // for future compatibility
|
||||
n += tPutLastFile(p ? p + n : p, pSet->pLastF);
|
||||
// stt
|
||||
n += tPutU8(p ? p + n : p, pSet->nSttF);
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
n += tPutSttFile(p ? p + n : p, pSet->aSttF[iStt]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -208,15 +210,40 @@ int32_t tGetDFileSet(uint8_t *p, SDFileSet *pSet) {
|
|||
n += tGetI32v(p + n, &pSet->diskId.id);
|
||||
n += tGetI32v(p + n, &pSet->fid);
|
||||
|
||||
// data
|
||||
// head
|
||||
pSet->pHeadF = (SHeadFile *)taosMemoryCalloc(1, sizeof(SHeadFile));
|
||||
if (pSet->pHeadF == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pSet->pHeadF->nRef = 1;
|
||||
n += tGetHeadFile(p + n, pSet->pHeadF);
|
||||
|
||||
// data
|
||||
pSet->pDataF = (SDataFile *)taosMemoryCalloc(1, sizeof(SDataFile));
|
||||
if (pSet->pDataF == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pSet->pDataF->nRef = 1;
|
||||
n += tGetDataFile(p + n, pSet->pDataF);
|
||||
|
||||
// sma
|
||||
pSet->pSmaF = (SSmaFile *)taosMemoryCalloc(1, sizeof(SSmaFile));
|
||||
if (pSet->pSmaF == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pSet->pSmaF->nRef = 1;
|
||||
n += tGetSmaFile(p + n, pSet->pSmaF);
|
||||
|
||||
// last
|
||||
uint8_t nLast;
|
||||
n += tGetU8(p + n, &nLast);
|
||||
n += tGetLastFile(p + n, pSet->pLastF);
|
||||
// stt
|
||||
n += tGetU8(p + n, &pSet->nSttF);
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
pSet->aSttF[iStt] = (SSttFile *)taosMemoryCalloc(1, sizeof(SSttFile));
|
||||
if (pSet->aSttF[iStt] == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pSet->aSttF[iStt]->nRef = 1;
|
||||
n += tGetSttFile(p + n, pSet->aSttF[iStt]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,561 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
// SLDataIter =================================================
|
||||
struct SLDataIter {
|
||||
SRBTreeNode node;
|
||||
SSttBlk *pSttBlk;
|
||||
SDataFReader *pReader;
|
||||
int32_t iStt;
|
||||
int8_t backward;
|
||||
int32_t iSttBlk;
|
||||
int32_t iRow;
|
||||
SRowInfo rInfo;
|
||||
uint64_t uid;
|
||||
STimeWindow timeWindow;
|
||||
SVersionRange verRange;
|
||||
|
||||
SSttBlockLoadInfo* pBlockLoadInfo;
|
||||
};
|
||||
|
||||
SSttBlockLoadInfo* tCreateLastBlockLoadInfo() {
|
||||
SSttBlockLoadInfo* pLoadInfo = taosMemoryCalloc(TSDB_DEFAULT_STT_FILE, sizeof(SSttBlockLoadInfo));
|
||||
if (pLoadInfo == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < TSDB_DEFAULT_STT_FILE; ++i) {
|
||||
pLoadInfo[i].blockIndex[0] = -1;
|
||||
pLoadInfo[i].blockIndex[1] = -1;
|
||||
pLoadInfo[i].currentLoadBlockIndex = 1;
|
||||
|
||||
int32_t code = tBlockDataCreate(&pLoadInfo[i].blockData[0]);
|
||||
if (code) {
|
||||
terrno = code;
|
||||
}
|
||||
|
||||
code = tBlockDataCreate(&pLoadInfo[i].blockData[1]);
|
||||
if (code) {
|
||||
terrno = code;
|
||||
}
|
||||
|
||||
pLoadInfo[i].aSttBlk = taosArrayInit(4, sizeof(SSttBlk));
|
||||
}
|
||||
|
||||
return pLoadInfo;
|
||||
}
|
||||
|
||||
void resetLastBlockLoadInfo(SSttBlockLoadInfo* pLoadInfo) {
|
||||
for(int32_t i = 0; i < TSDB_DEFAULT_STT_FILE; ++i) {
|
||||
pLoadInfo[i].currentLoadBlockIndex = 1;
|
||||
pLoadInfo[i].blockIndex[0] = -1;
|
||||
pLoadInfo[i].blockIndex[1] = -1;
|
||||
|
||||
taosArrayClear(pLoadInfo[i].aSttBlk);
|
||||
|
||||
pLoadInfo[i].elapsedTime = 0;
|
||||
pLoadInfo[i].loadBlocks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void getLastBlockLoadInfo(SSttBlockLoadInfo* pLoadInfo, int64_t* blocks, double* el) {
|
||||
for(int32_t i = 0; i < TSDB_DEFAULT_STT_FILE; ++i) {
|
||||
*el += pLoadInfo[i].elapsedTime;
|
||||
*blocks += pLoadInfo[i].loadBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
void* destroyLastBlockLoadInfo(SSttBlockLoadInfo* pLoadInfo) {
|
||||
for(int32_t i = 0; i < TSDB_DEFAULT_STT_FILE; ++i) {
|
||||
pLoadInfo[i].currentLoadBlockIndex = 1;
|
||||
pLoadInfo[i].blockIndex[0] = -1;
|
||||
pLoadInfo[i].blockIndex[1] = -1;
|
||||
|
||||
tBlockDataDestroy(&pLoadInfo[i].blockData[0], true);
|
||||
tBlockDataDestroy(&pLoadInfo[i].blockData[1], true);
|
||||
|
||||
taosArrayDestroy(pLoadInfo[i].aSttBlk);
|
||||
}
|
||||
|
||||
taosMemoryFree(pLoadInfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SBlockData* loadLastBlock(SLDataIter *pIter, const char* idStr) {
|
||||
int32_t code = 0;
|
||||
|
||||
SSttBlockLoadInfo* pInfo = pIter->pBlockLoadInfo;
|
||||
if (pInfo->blockIndex[0] == pIter->iSttBlk) {
|
||||
return &pInfo->blockData[0];
|
||||
}
|
||||
|
||||
if (pInfo->blockIndex[1] == pIter->iSttBlk) {
|
||||
return &pInfo->blockData[1];
|
||||
}
|
||||
|
||||
pInfo->currentLoadBlockIndex ^= 1;
|
||||
if (pIter->pSttBlk != NULL) { // current block not loaded yet
|
||||
int64_t st = taosGetTimestampUs();
|
||||
code = tsdbReadSttBlock(pIter->pReader, pIter->iStt, pIter->pSttBlk, &pInfo->blockData[pInfo->currentLoadBlockIndex]);
|
||||
double el = (taosGetTimestampUs() - st)/ 1000.0;
|
||||
pInfo->elapsedTime += el;
|
||||
pInfo->loadBlocks += 1;
|
||||
|
||||
tsdbDebug("read last block, index:%d, last file index:%d, elapsed time:%.2f ms, %s", pIter->iSttBlk, pIter->iStt, el, idStr);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
pInfo->blockIndex[pInfo->currentLoadBlockIndex] = pIter->iSttBlk;
|
||||
pIter->iRow = (pIter->backward) ? pInfo->blockData[pInfo->currentLoadBlockIndex].nRow : -1;
|
||||
}
|
||||
|
||||
return &pInfo->blockData[pInfo->currentLoadBlockIndex];
|
||||
|
||||
_exit:
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// find the earliest block that contains the required records
|
||||
static FORCE_INLINE int32_t findEarliestIndex(int32_t index, uint64_t uid, const SSttBlk* pBlockList, int32_t num, int32_t backward) {
|
||||
int32_t i = index;
|
||||
int32_t step = backward? 1:-1;
|
||||
while (i >= 0 && i < num && uid >= pBlockList[i].minUid && uid <= pBlockList[i].maxUid) {
|
||||
i += step;
|
||||
}
|
||||
return i - step;
|
||||
}
|
||||
|
||||
static int32_t binarySearchForStartBlock(SSttBlk*pBlockList, int32_t num, uint64_t uid, int32_t backward) {
|
||||
int32_t midPos = -1;
|
||||
if (num <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t firstPos = 0;
|
||||
int32_t lastPos = num - 1;
|
||||
|
||||
// find the first position which is bigger than the key
|
||||
if ((uid > pBlockList[lastPos].maxUid) || (uid < pBlockList[firstPos].minUid)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (uid >= pBlockList[firstPos].minUid && uid <= pBlockList[firstPos].maxUid) {
|
||||
return findEarliestIndex(firstPos, uid, pBlockList, num, backward);
|
||||
}
|
||||
|
||||
if (uid > pBlockList[lastPos].maxUid || uid < pBlockList[firstPos].minUid) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t numOfRows = lastPos - firstPos + 1;
|
||||
midPos = (numOfRows >> 1u) + firstPos;
|
||||
|
||||
if (uid < pBlockList[midPos].minUid) {
|
||||
lastPos = midPos - 1;
|
||||
} else if (uid > pBlockList[midPos].maxUid) {
|
||||
firstPos = midPos + 1;
|
||||
} else {
|
||||
return findEarliestIndex(midPos, uid, pBlockList, num, backward);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t findEarliestRow(int32_t index, uint64_t uid, const uint64_t* uidList, int32_t num, int32_t backward) {
|
||||
int32_t i = index;
|
||||
int32_t step = backward? 1:-1;
|
||||
while (i >= 0 && i < num && uid == uidList[i]) {
|
||||
i += step;
|
||||
}
|
||||
return i - step;
|
||||
}
|
||||
|
||||
static int32_t binarySearchForStartRowIndex(uint64_t* uidList, int32_t num, uint64_t uid, int32_t backward) {
|
||||
int32_t firstPos = 0;
|
||||
int32_t lastPos = num - 1;
|
||||
|
||||
// find the first position which is bigger than the key
|
||||
if ((uid > uidList[lastPos]) || (uid < uidList[firstPos])) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (uid == uidList[firstPos]) {
|
||||
return findEarliestRow(firstPos, uid, uidList, num, backward);
|
||||
}
|
||||
|
||||
if (uid > uidList[lastPos] || uid < uidList[firstPos]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t numOfRows = lastPos - firstPos + 1;
|
||||
int32_t midPos = (numOfRows >> 1u) + firstPos;
|
||||
|
||||
if (uid < uidList[midPos]) {
|
||||
lastPos = midPos - 1;
|
||||
} else if (uid > uidList[midPos]) {
|
||||
firstPos = midPos + 1;
|
||||
} else {
|
||||
return findEarliestRow(midPos, uid, uidList, num, backward);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t iStt, int8_t backward, uint64_t suid,
|
||||
uint64_t uid, STimeWindow *pTimeWindow, SVersionRange *pRange, SSttBlockLoadInfo* pBlockLoadInfo) {
|
||||
int32_t code = 0;
|
||||
*pIter = taosMemoryCalloc(1, sizeof(SLDataIter));
|
||||
if (*pIter == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
(*pIter)->uid = uid;
|
||||
(*pIter)->pReader = pReader;
|
||||
(*pIter)->iStt = iStt;
|
||||
(*pIter)->backward = backward;
|
||||
(*pIter)->verRange = *pRange;
|
||||
(*pIter)->timeWindow = *pTimeWindow;
|
||||
|
||||
(*pIter)->pBlockLoadInfo = pBlockLoadInfo;
|
||||
if (taosArrayGetSize(pBlockLoadInfo->aSttBlk) == 0) {
|
||||
code = tsdbReadSttBlk(pReader, iStt, pBlockLoadInfo->aSttBlk);
|
||||
if (code) {
|
||||
goto _exit;
|
||||
} else {
|
||||
size_t size = taosArrayGetSize(pBlockLoadInfo->aSttBlk);
|
||||
SArray* pTmp = taosArrayInit(size, sizeof(SSttBlk));
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SSttBlk* p = taosArrayGet(pBlockLoadInfo->aSttBlk, i);
|
||||
if (p->suid == suid) {
|
||||
taosArrayPush(pTmp, p);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pBlockLoadInfo->aSttBlk);
|
||||
pBlockLoadInfo->aSttBlk = pTmp;
|
||||
}
|
||||
}
|
||||
|
||||
size_t size = taosArrayGetSize(pBlockLoadInfo->aSttBlk);
|
||||
|
||||
// find the start block
|
||||
(*pIter)->iSttBlk = binarySearchForStartBlock(pBlockLoadInfo->aSttBlk->pData, size, uid, backward);
|
||||
if ((*pIter)->iSttBlk != -1) {
|
||||
(*pIter)->pSttBlk = taosArrayGet(pBlockLoadInfo->aSttBlk, (*pIter)->iSttBlk);
|
||||
(*pIter)->iRow = ((*pIter)->backward) ? (*pIter)->pSttBlk->nRow : -1;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
void tLDataIterClose(SLDataIter *pIter) {
|
||||
taosMemoryFree(pIter);
|
||||
}
|
||||
|
||||
void tLDataIterNextBlock(SLDataIter *pIter) {
|
||||
int32_t step = pIter->backward ? -1 : 1;
|
||||
pIter->iSttBlk += step;
|
||||
|
||||
int32_t index = -1;
|
||||
size_t size = pIter->pBlockLoadInfo->aSttBlk->size;
|
||||
for (int32_t i = pIter->iSttBlk; i < size && i >= 0; i += step) {
|
||||
SSttBlk *p = taosArrayGet(pIter->pBlockLoadInfo->aSttBlk, i);
|
||||
if ((!pIter->backward) && p->minUid > pIter->uid) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pIter->backward && p->maxUid < pIter->uid) {
|
||||
break;
|
||||
}
|
||||
|
||||
// check uid firstly
|
||||
if (p->minUid <= pIter->uid && p->maxUid >= pIter->uid) {
|
||||
if ((!pIter->backward) && p->minKey > pIter->timeWindow.ekey) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pIter->backward && p->maxKey < pIter->timeWindow.skey) {
|
||||
break;
|
||||
}
|
||||
|
||||
// check time range secondly
|
||||
if (p->minKey <= pIter->timeWindow.ekey && p->maxKey >= pIter->timeWindow.skey) {
|
||||
if ((!pIter->backward) && p->minVer > pIter->verRange.maxVer) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pIter->backward && p->maxVer < pIter->verRange.minVer) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p->minVer <= pIter->verRange.maxVer && p->maxVer >= pIter->verRange.minVer) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pIter->pSttBlk = NULL;
|
||||
if (index != -1) {
|
||||
pIter->pSttBlk = (SSttBlk *)taosArrayGet(pIter->pBlockLoadInfo->aSttBlk, pIter->iSttBlk);
|
||||
}
|
||||
}
|
||||
|
||||
static void findNextValidRow(SLDataIter *pIter, const char* idStr) {
|
||||
int32_t step = pIter->backward ? -1 : 1;
|
||||
|
||||
bool hasVal = false;
|
||||
int32_t i = pIter->iRow;
|
||||
|
||||
SBlockData *pBlockData = loadLastBlock(pIter, idStr);
|
||||
|
||||
// mostly we only need to find the start position for a given table
|
||||
if ((((i == 0) && (!pIter->backward)) || (i == pBlockData->nRow - 1 && pIter->backward)) && pBlockData->aUid != NULL) {
|
||||
i = binarySearchForStartRowIndex((uint64_t*)pBlockData->aUid, pBlockData->nRow, pIter->uid, pIter->backward);
|
||||
if (i == -1) {
|
||||
pIter->iRow = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < pBlockData->nRow && i >= 0; i += step) {
|
||||
if (pBlockData->aUid != NULL) {
|
||||
if (!pIter->backward) {
|
||||
/*if (pBlockData->aUid[i] < pIter->uid) {
|
||||
continue;
|
||||
} else */if (pBlockData->aUid[i] > pIter->uid) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*if (pBlockData->aUid[i] > pIter->uid) {
|
||||
continue;
|
||||
} else */if (pBlockData->aUid[i] < pIter->uid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t ts = pBlockData->aTSKEY[i];
|
||||
if (!pIter->backward) { // asc
|
||||
if (ts > pIter->timeWindow.ekey) { // no more data
|
||||
break;
|
||||
} else if (ts < pIter->timeWindow.skey) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (ts < pIter->timeWindow.skey) {
|
||||
break;
|
||||
} else if (ts > pIter->timeWindow.ekey) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t ver = pBlockData->aVersion[i];
|
||||
if (ver < pIter->verRange.minVer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// todo opt handle desc case
|
||||
if (ver > pIter->verRange.maxVer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hasVal = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pIter->iRow = (hasVal) ? i : -1;
|
||||
}
|
||||
|
||||
bool tLDataIterNextRow(SLDataIter *pIter, const char* idStr) {
|
||||
int32_t code = 0;
|
||||
int32_t step = pIter->backward ? -1 : 1;
|
||||
|
||||
// no qualified last file block in current file, no need to fetch row
|
||||
if (pIter->pSttBlk == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t iBlockL = pIter->iSttBlk;
|
||||
SBlockData *pBlockData = loadLastBlock(pIter, idStr);
|
||||
pIter->iRow += step;
|
||||
|
||||
while (1) {
|
||||
findNextValidRow(pIter, idStr);
|
||||
|
||||
if (pIter->iRow >= pBlockData->nRow || pIter->iRow < 0) {
|
||||
tLDataIterNextBlock(pIter);
|
||||
if (pIter->pSttBlk == NULL) { // no more data
|
||||
goto _exit;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (iBlockL != pIter->iSttBlk) {
|
||||
pBlockData = loadLastBlock(pIter, idStr);
|
||||
pIter->iRow += step;
|
||||
}
|
||||
}
|
||||
|
||||
pIter->rInfo.suid = pBlockData->suid;
|
||||
pIter->rInfo.uid = pBlockData->uid;
|
||||
pIter->rInfo.row = tsdbRowFromBlockData(pBlockData, pIter->iRow);
|
||||
|
||||
_exit:
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
}
|
||||
|
||||
return (code == TSDB_CODE_SUCCESS) && (pIter->pSttBlk != NULL);
|
||||
}
|
||||
|
||||
SRowInfo *tLDataIterGet(SLDataIter *pIter) { return &pIter->rInfo; }
|
||||
|
||||
// SMergeTree =================================================
|
||||
static FORCE_INLINE int32_t tLDataIterCmprFn(const void *p1, const void *p2) {
|
||||
SLDataIter *pIter1 = (SLDataIter *)(((uint8_t *)p1) - sizeof(SRBTreeNode));
|
||||
SLDataIter *pIter2 = (SLDataIter *)(((uint8_t *)p2) - sizeof(SRBTreeNode));
|
||||
|
||||
TSDBKEY key1 = TSDBROW_KEY(&pIter1->rInfo.row);
|
||||
TSDBKEY key2 = TSDBROW_KEY(&pIter2->rInfo.row);
|
||||
|
||||
if (key1.ts < key2.ts) {
|
||||
return -1;
|
||||
} else if (key1.ts > key2.ts) {
|
||||
return 1;
|
||||
} else {
|
||||
if (key1.version < key2.version) {
|
||||
return -1;
|
||||
} else if (key1.version > key2.version) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFReader, uint64_t suid, uint64_t uid,
|
||||
STimeWindow *pTimeWindow, SVersionRange *pVerRange, void* pBlockLoadInfo, const char* idStr) {
|
||||
pMTree->backward = backward;
|
||||
pMTree->pIter = NULL;
|
||||
pMTree->pIterList = taosArrayInit(4, POINTER_BYTES);
|
||||
if (pMTree->pIterList == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMTree->idStr = idStr;
|
||||
|
||||
tRBTreeCreate(&pMTree->rbt, tLDataIterCmprFn);
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
SSttBlockLoadInfo* pLoadInfo = NULL;
|
||||
if (pBlockLoadInfo == NULL) {
|
||||
if (pMTree->pLoadInfo == NULL) {
|
||||
pMTree->destroyLoadInfo = true;
|
||||
pMTree->pLoadInfo = tCreateLastBlockLoadInfo();
|
||||
}
|
||||
|
||||
pLoadInfo = pMTree->pLoadInfo;
|
||||
} else {
|
||||
pLoadInfo = pBlockLoadInfo;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pFReader->pSet->nSttF; ++i) { // open all last file
|
||||
struct SLDataIter* pIter = NULL;
|
||||
code = tLDataIterOpen(&pIter, pFReader, i, pMTree->backward, suid, uid, pTimeWindow, pVerRange, &pLoadInfo[i]);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _end;
|
||||
}
|
||||
|
||||
bool hasVal = tLDataIterNextRow(pIter, pMTree->idStr);
|
||||
if (hasVal) {
|
||||
taosArrayPush(pMTree->pIterList, &pIter);
|
||||
tMergeTreeAddIter(pMTree, pIter);
|
||||
} else {
|
||||
tLDataIterClose(pIter);
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
|
||||
_end:
|
||||
tMergeTreeClose(pMTree);
|
||||
return code;
|
||||
}
|
||||
|
||||
void tMergeTreeAddIter(SMergeTree *pMTree, SLDataIter *pIter) { tRBTreePut(&pMTree->rbt, (SRBTreeNode *)pIter); }
|
||||
|
||||
bool tMergeTreeNext(SMergeTree *pMTree) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pMTree->pIter) {
|
||||
SLDataIter *pIter = pMTree->pIter;
|
||||
|
||||
bool hasVal = tLDataIterNextRow(pIter, pMTree->idStr);
|
||||
if (!hasVal) {
|
||||
pMTree->pIter = NULL;
|
||||
}
|
||||
|
||||
// compare with min in RB Tree
|
||||
pIter = (SLDataIter *)tRBTreeMin(&pMTree->rbt);
|
||||
if (pMTree->pIter && pIter) {
|
||||
int32_t c = pMTree->rbt.cmprFn(RBTREE_NODE_PAYLOAD(&pMTree->pIter->node), RBTREE_NODE_PAYLOAD(&pIter->node));
|
||||
if (c > 0) {
|
||||
tRBTreePut(&pMTree->rbt, (SRBTreeNode *)pMTree->pIter);
|
||||
pMTree->pIter = NULL;
|
||||
} else {
|
||||
ASSERT(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pMTree->pIter == NULL) {
|
||||
pMTree->pIter = (SLDataIter *)tRBTreeMin(&pMTree->rbt);
|
||||
if (pMTree->pIter) {
|
||||
tRBTreeDrop(&pMTree->rbt, (SRBTreeNode *)pMTree->pIter);
|
||||
}
|
||||
}
|
||||
|
||||
return pMTree->pIter != NULL;
|
||||
}
|
||||
|
||||
TSDBROW tMergeTreeGetRow(SMergeTree *pMTree) { return pMTree->pIter->rInfo.row; }
|
||||
|
||||
void tMergeTreeClose(SMergeTree *pMTree) {
|
||||
size_t size = taosArrayGetSize(pMTree->pIterList);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SLDataIter *pIter = taosArrayGetP(pMTree->pIterList, i);
|
||||
tLDataIterClose(pIter);
|
||||
}
|
||||
|
||||
pMTree->pIterList = taosArrayDestroy(pMTree->pIterList);
|
||||
pMTree->pIter = NULL;
|
||||
|
||||
if (pMTree->destroyLoadInfo) {
|
||||
pMTree->pLoadInfo = destroyLastBlockLoadInfo(pMTree->pLoadInfo);
|
||||
pMTree->destroyLoadInfo = false;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -60,7 +60,7 @@ int32_t tsdbDoRetention(STsdb *pTsdb, int64_t now) {
|
|||
if (expLevel < 0) {
|
||||
taosMemoryFree(pSet->pHeadF);
|
||||
taosMemoryFree(pSet->pDataF);
|
||||
taosMemoryFree(pSet->pLastF);
|
||||
taosMemoryFree(pSet->aSttF[0]);
|
||||
taosMemoryFree(pSet->pSmaF);
|
||||
taosArrayRemove(fs.aDFileSet, iSet);
|
||||
iSet--;
|
||||
|
@ -82,8 +82,6 @@ int32_t tsdbDoRetention(STsdb *pTsdb, int64_t now) {
|
|||
code = tsdbFSUpsertFSet(&fs, &fSet);
|
||||
if (code) goto _err;
|
||||
}
|
||||
|
||||
/* code */
|
||||
}
|
||||
|
||||
// do change fs
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -51,6 +51,22 @@ _exit:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tMapDataCopy(SMapData *pFrom, SMapData *pTo) {
|
||||
int32_t code = 0;
|
||||
|
||||
pTo->nItem = pFrom->nItem;
|
||||
pTo->nData = pFrom->nData;
|
||||
code = tRealloc((uint8_t **)&pTo->aOffset, sizeof(int32_t) * pFrom->nItem);
|
||||
if (code) goto _exit;
|
||||
code = tRealloc(&pTo->pData, pFrom->nData);
|
||||
if (code) goto _exit;
|
||||
memcpy(pTo->aOffset, pFrom->aOffset, sizeof(int32_t) * pFrom->nItem);
|
||||
memcpy(pTo->pData, pFrom->pData, pFrom->nData);
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tMapDataSearch(SMapData *pMapData, void *pSearchItem, int32_t (*tGetItemFn)(uint8_t *, void *),
|
||||
int32_t (*tItemCmprFn)(const void *, const void *), void *pItem) {
|
||||
int32_t code = 0;
|
||||
|
@ -198,7 +214,7 @@ int32_t tCmprBlockIdx(void const *lhs, void const *rhs) {
|
|||
|
||||
int32_t tCmprBlockL(void const *lhs, void const *rhs) {
|
||||
SBlockIdx *lBlockIdx = (SBlockIdx *)lhs;
|
||||
SBlockL *rBlockL = (SBlockL *)rhs;
|
||||
SSttBlk *rBlockL = (SSttBlk *)rhs;
|
||||
|
||||
if (lBlockIdx->suid < rBlockL->suid) {
|
||||
return -1;
|
||||
|
@ -215,69 +231,69 @@ int32_t tCmprBlockL(void const *lhs, void const *rhs) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// SBlock ======================================================
|
||||
void tBlockReset(SBlock *pBlock) {
|
||||
*pBlock = (SBlock){.minKey = TSDBKEY_MAX, .maxKey = TSDBKEY_MIN, .minVer = VERSION_MAX, .maxVer = VERSION_MIN};
|
||||
// SDataBlk ======================================================
|
||||
void tDataBlkReset(SDataBlk *pDataBlk) {
|
||||
*pDataBlk = (SDataBlk){.minKey = TSDBKEY_MAX, .maxKey = TSDBKEY_MIN, .minVer = VERSION_MAX, .maxVer = VERSION_MIN};
|
||||
}
|
||||
|
||||
int32_t tPutBlock(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SBlock *pBlock = (SBlock *)ph;
|
||||
int32_t tPutDataBlk(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SDataBlk *pDataBlk = (SDataBlk *)ph;
|
||||
|
||||
n += tPutI64v(p ? p + n : p, pBlock->minKey.version);
|
||||
n += tPutI64v(p ? p + n : p, pBlock->minKey.ts);
|
||||
n += tPutI64v(p ? p + n : p, pBlock->maxKey.version);
|
||||
n += tPutI64v(p ? p + n : p, pBlock->maxKey.ts);
|
||||
n += tPutI64v(p ? p + n : p, pBlock->minVer);
|
||||
n += tPutI64v(p ? p + n : p, pBlock->maxVer);
|
||||
n += tPutI32v(p ? p + n : p, pBlock->nRow);
|
||||
n += tPutI8(p ? p + n : p, pBlock->hasDup);
|
||||
n += tPutI8(p ? p + n : p, pBlock->nSubBlock);
|
||||
for (int8_t iSubBlock = 0; iSubBlock < pBlock->nSubBlock; iSubBlock++) {
|
||||
n += tPutI64v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].offset);
|
||||
n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].szBlock);
|
||||
n += tPutI32v(p ? p + n : p, pBlock->aSubBlock[iSubBlock].szKey);
|
||||
n += tPutI64v(p ? p + n : p, pDataBlk->minKey.version);
|
||||
n += tPutI64v(p ? p + n : p, pDataBlk->minKey.ts);
|
||||
n += tPutI64v(p ? p + n : p, pDataBlk->maxKey.version);
|
||||
n += tPutI64v(p ? p + n : p, pDataBlk->maxKey.ts);
|
||||
n += tPutI64v(p ? p + n : p, pDataBlk->minVer);
|
||||
n += tPutI64v(p ? p + n : p, pDataBlk->maxVer);
|
||||
n += tPutI32v(p ? p + n : p, pDataBlk->nRow);
|
||||
n += tPutI8(p ? p + n : p, pDataBlk->hasDup);
|
||||
n += tPutI8(p ? p + n : p, pDataBlk->nSubBlock);
|
||||
for (int8_t iSubBlock = 0; iSubBlock < pDataBlk->nSubBlock; iSubBlock++) {
|
||||
n += tPutI64v(p ? p + n : p, pDataBlk->aSubBlock[iSubBlock].offset);
|
||||
n += tPutI32v(p ? p + n : p, pDataBlk->aSubBlock[iSubBlock].szBlock);
|
||||
n += tPutI32v(p ? p + n : p, pDataBlk->aSubBlock[iSubBlock].szKey);
|
||||
}
|
||||
if (pBlock->nSubBlock == 1 && !pBlock->hasDup) {
|
||||
n += tPutI64v(p ? p + n : p, pBlock->smaInfo.offset);
|
||||
n += tPutI32v(p ? p + n : p, pBlock->smaInfo.size);
|
||||
if (pDataBlk->nSubBlock == 1 && !pDataBlk->hasDup) {
|
||||
n += tPutI64v(p ? p + n : p, pDataBlk->smaInfo.offset);
|
||||
n += tPutI32v(p ? p + n : p, pDataBlk->smaInfo.size);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int32_t tGetBlock(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SBlock *pBlock = (SBlock *)ph;
|
||||
int32_t tGetDataBlk(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SDataBlk *pDataBlk = (SDataBlk *)ph;
|
||||
|
||||
n += tGetI64v(p + n, &pBlock->minKey.version);
|
||||
n += tGetI64v(p + n, &pBlock->minKey.ts);
|
||||
n += tGetI64v(p + n, &pBlock->maxKey.version);
|
||||
n += tGetI64v(p + n, &pBlock->maxKey.ts);
|
||||
n += tGetI64v(p + n, &pBlock->minVer);
|
||||
n += tGetI64v(p + n, &pBlock->maxVer);
|
||||
n += tGetI32v(p + n, &pBlock->nRow);
|
||||
n += tGetI8(p + n, &pBlock->hasDup);
|
||||
n += tGetI8(p + n, &pBlock->nSubBlock);
|
||||
for (int8_t iSubBlock = 0; iSubBlock < pBlock->nSubBlock; iSubBlock++) {
|
||||
n += tGetI64v(p + n, &pBlock->aSubBlock[iSubBlock].offset);
|
||||
n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].szBlock);
|
||||
n += tGetI32v(p + n, &pBlock->aSubBlock[iSubBlock].szKey);
|
||||
n += tGetI64v(p + n, &pDataBlk->minKey.version);
|
||||
n += tGetI64v(p + n, &pDataBlk->minKey.ts);
|
||||
n += tGetI64v(p + n, &pDataBlk->maxKey.version);
|
||||
n += tGetI64v(p + n, &pDataBlk->maxKey.ts);
|
||||
n += tGetI64v(p + n, &pDataBlk->minVer);
|
||||
n += tGetI64v(p + n, &pDataBlk->maxVer);
|
||||
n += tGetI32v(p + n, &pDataBlk->nRow);
|
||||
n += tGetI8(p + n, &pDataBlk->hasDup);
|
||||
n += tGetI8(p + n, &pDataBlk->nSubBlock);
|
||||
for (int8_t iSubBlock = 0; iSubBlock < pDataBlk->nSubBlock; iSubBlock++) {
|
||||
n += tGetI64v(p + n, &pDataBlk->aSubBlock[iSubBlock].offset);
|
||||
n += tGetI32v(p + n, &pDataBlk->aSubBlock[iSubBlock].szBlock);
|
||||
n += tGetI32v(p + n, &pDataBlk->aSubBlock[iSubBlock].szKey);
|
||||
}
|
||||
if (pBlock->nSubBlock == 1 && !pBlock->hasDup) {
|
||||
n += tGetI64v(p + n, &pBlock->smaInfo.offset);
|
||||
n += tGetI32v(p + n, &pBlock->smaInfo.size);
|
||||
if (pDataBlk->nSubBlock == 1 && !pDataBlk->hasDup) {
|
||||
n += tGetI64v(p + n, &pDataBlk->smaInfo.offset);
|
||||
n += tGetI32v(p + n, &pDataBlk->smaInfo.size);
|
||||
} else {
|
||||
pBlock->smaInfo.offset = 0;
|
||||
pBlock->smaInfo.size = 0;
|
||||
pDataBlk->smaInfo.offset = 0;
|
||||
pDataBlk->smaInfo.size = 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int32_t tBlockCmprFn(const void *p1, const void *p2) {
|
||||
SBlock *pBlock1 = (SBlock *)p1;
|
||||
SBlock *pBlock2 = (SBlock *)p2;
|
||||
int32_t tDataBlkCmprFn(const void *p1, const void *p2) {
|
||||
SDataBlk *pBlock1 = (SDataBlk *)p1;
|
||||
SDataBlk *pBlock2 = (SDataBlk *)p2;
|
||||
|
||||
if (tsdbKeyCmprFn(&pBlock1->maxKey, &pBlock2->minKey) < 0) {
|
||||
return -1;
|
||||
|
@ -288,48 +304,48 @@ int32_t tBlockCmprFn(const void *p1, const void *p2) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool tBlockHasSma(SBlock *pBlock) {
|
||||
if (pBlock->nSubBlock > 1) return false;
|
||||
if (pBlock->hasDup) return false;
|
||||
bool tDataBlkHasSma(SDataBlk *pDataBlk) {
|
||||
if (pDataBlk->nSubBlock > 1) return false;
|
||||
if (pDataBlk->hasDup) return false;
|
||||
|
||||
return pBlock->smaInfo.size > 0;
|
||||
return pDataBlk->smaInfo.size > 0;
|
||||
}
|
||||
|
||||
// SBlockL ======================================================
|
||||
int32_t tPutBlockL(uint8_t *p, void *ph) {
|
||||
// SSttBlk ======================================================
|
||||
int32_t tPutSttBlk(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SBlockL *pBlockL = (SBlockL *)ph;
|
||||
SSttBlk *pSttBlk = (SSttBlk *)ph;
|
||||
|
||||
n += tPutI64(p ? p + n : p, pBlockL->suid);
|
||||
n += tPutI64(p ? p + n : p, pBlockL->minUid);
|
||||
n += tPutI64(p ? p + n : p, pBlockL->maxUid);
|
||||
n += tPutI64v(p ? p + n : p, pBlockL->minKey);
|
||||
n += tPutI64v(p ? p + n : p, pBlockL->maxKey);
|
||||
n += tPutI64v(p ? p + n : p, pBlockL->minVer);
|
||||
n += tPutI64v(p ? p + n : p, pBlockL->maxVer);
|
||||
n += tPutI32v(p ? p + n : p, pBlockL->nRow);
|
||||
n += tPutI64v(p ? p + n : p, pBlockL->bInfo.offset);
|
||||
n += tPutI32v(p ? p + n : p, pBlockL->bInfo.szBlock);
|
||||
n += tPutI32v(p ? p + n : p, pBlockL->bInfo.szKey);
|
||||
n += tPutI64(p ? p + n : p, pSttBlk->suid);
|
||||
n += tPutI64(p ? p + n : p, pSttBlk->minUid);
|
||||
n += tPutI64(p ? p + n : p, pSttBlk->maxUid);
|
||||
n += tPutI64v(p ? p + n : p, pSttBlk->minKey);
|
||||
n += tPutI64v(p ? p + n : p, pSttBlk->maxKey);
|
||||
n += tPutI64v(p ? p + n : p, pSttBlk->minVer);
|
||||
n += tPutI64v(p ? p + n : p, pSttBlk->maxVer);
|
||||
n += tPutI32v(p ? p + n : p, pSttBlk->nRow);
|
||||
n += tPutI64v(p ? p + n : p, pSttBlk->bInfo.offset);
|
||||
n += tPutI32v(p ? p + n : p, pSttBlk->bInfo.szBlock);
|
||||
n += tPutI32v(p ? p + n : p, pSttBlk->bInfo.szKey);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int32_t tGetBlockL(uint8_t *p, void *ph) {
|
||||
int32_t tGetSttBlk(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SBlockL *pBlockL = (SBlockL *)ph;
|
||||
SSttBlk *pSttBlk = (SSttBlk *)ph;
|
||||
|
||||
n += tGetI64(p + n, &pBlockL->suid);
|
||||
n += tGetI64(p + n, &pBlockL->minUid);
|
||||
n += tGetI64(p + n, &pBlockL->maxUid);
|
||||
n += tGetI64v(p + n, &pBlockL->minKey);
|
||||
n += tGetI64v(p + n, &pBlockL->maxKey);
|
||||
n += tGetI64v(p + n, &pBlockL->minVer);
|
||||
n += tGetI64v(p + n, &pBlockL->maxVer);
|
||||
n += tGetI32v(p + n, &pBlockL->nRow);
|
||||
n += tGetI64v(p + n, &pBlockL->bInfo.offset);
|
||||
n += tGetI32v(p + n, &pBlockL->bInfo.szBlock);
|
||||
n += tGetI32v(p + n, &pBlockL->bInfo.szKey);
|
||||
n += tGetI64(p + n, &pSttBlk->suid);
|
||||
n += tGetI64(p + n, &pSttBlk->minUid);
|
||||
n += tGetI64(p + n, &pSttBlk->maxUid);
|
||||
n += tGetI64v(p + n, &pSttBlk->minKey);
|
||||
n += tGetI64v(p + n, &pSttBlk->maxKey);
|
||||
n += tGetI64v(p + n, &pSttBlk->minVer);
|
||||
n += tGetI64v(p + n, &pSttBlk->maxVer);
|
||||
n += tGetI32v(p + n, &pSttBlk->nRow);
|
||||
n += tGetI64v(p + n, &pSttBlk->bInfo.offset);
|
||||
n += tGetI32v(p + n, &pSttBlk->bInfo.szBlock);
|
||||
n += tGetI32v(p + n, &pSttBlk->bInfo.szKey);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -1532,7 +1548,7 @@ int32_t tCmprBlockData(SBlockData *pBlockData, int8_t cmprAlg, uint8_t **ppOut,
|
|||
if (code) goto _exit;
|
||||
|
||||
blockCol.offset = aBufN[0];
|
||||
aBufN[0] = aBufN[0] + blockCol.szBitmap + blockCol.szOffset + blockCol.szValue + sizeof(TSCKSUM);
|
||||
aBufN[0] = aBufN[0] + blockCol.szBitmap + blockCol.szOffset + blockCol.szValue;
|
||||
}
|
||||
|
||||
code = tRealloc(&aBuf[1], hdr.szBlkCol + tPutBlockCol(NULL, &blockCol));
|
||||
|
@ -1540,15 +1556,8 @@ int32_t tCmprBlockData(SBlockData *pBlockData, int8_t cmprAlg, uint8_t **ppOut,
|
|||
hdr.szBlkCol += tPutBlockCol(aBuf[1] + hdr.szBlkCol, &blockCol);
|
||||
}
|
||||
|
||||
aBufN[1] = 0;
|
||||
if (hdr.szBlkCol > 0) {
|
||||
aBufN[1] = hdr.szBlkCol + sizeof(TSCKSUM);
|
||||
|
||||
code = tRealloc(&aBuf[1], aBufN[1]);
|
||||
if (code) goto _exit;
|
||||
|
||||
taosCalcChecksumAppend(0, aBuf[1], aBufN[1]);
|
||||
}
|
||||
// SBlockCol
|
||||
aBufN[1] = hdr.szBlkCol;
|
||||
|
||||
// uid + version + tskey
|
||||
aBufN[2] = 0;
|
||||
|
@ -1569,16 +1578,11 @@ int32_t tCmprBlockData(SBlockData *pBlockData, int8_t cmprAlg, uint8_t **ppOut,
|
|||
if (code) goto _exit;
|
||||
aBufN[2] += hdr.szKey;
|
||||
|
||||
aBufN[2] += sizeof(TSCKSUM);
|
||||
code = tRealloc(&aBuf[2], aBufN[2]);
|
||||
if (code) goto _exit;
|
||||
|
||||
// hdr
|
||||
aBufN[3] = tPutDiskDataHdr(NULL, &hdr);
|
||||
code = tRealloc(&aBuf[3], aBufN[3]);
|
||||
if (code) goto _exit;
|
||||
tPutDiskDataHdr(aBuf[3], &hdr);
|
||||
taosCalcChecksumAppend(taosCalcChecksum(0, aBuf[3], aBufN[3]), aBuf[2], aBufN[2]);
|
||||
|
||||
// aggragate
|
||||
if (ppOut) {
|
||||
|
@ -1603,17 +1607,13 @@ _exit:
|
|||
int32_t tDecmprBlockData(uint8_t *pIn, int32_t szIn, SBlockData *pBlockData, uint8_t *aBuf[]) {
|
||||
int32_t code = 0;
|
||||
|
||||
tBlockDataClear(pBlockData);
|
||||
tBlockDataReset(pBlockData);
|
||||
|
||||
int32_t n = 0;
|
||||
SDiskDataHdr hdr = {0};
|
||||
|
||||
// SDiskDataHdr
|
||||
n += tGetDiskDataHdr(pIn + n, &hdr);
|
||||
if (!taosCheckChecksumWhole(pIn, n + hdr.szUid + hdr.szVer + hdr.szKey + sizeof(TSCKSUM))) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _exit;
|
||||
}
|
||||
ASSERT(hdr.delimiter == TSDB_FILE_DLMT);
|
||||
|
||||
pBlockData->suid = hdr.suid;
|
||||
|
@ -1641,7 +1641,7 @@ int32_t tDecmprBlockData(uint8_t *pIn, int32_t szIn, SBlockData *pBlockData, uin
|
|||
code = tsdbDecmprData(pIn + n, hdr.szKey, TSDB_DATA_TYPE_TIMESTAMP, hdr.cmprAlg, (uint8_t **)&pBlockData->aTSKEY,
|
||||
sizeof(TSKEY) * hdr.nRow, &aBuf[0]);
|
||||
if (code) goto _exit;
|
||||
n = n + hdr.szKey + sizeof(TSCKSUM);
|
||||
n += hdr.szKey;
|
||||
|
||||
// loop to decode each column data
|
||||
if (hdr.szBlkCol == 0) goto _exit;
|
||||
|
@ -1663,8 +1663,8 @@ int32_t tDecmprBlockData(uint8_t *pIn, int32_t szIn, SBlockData *pBlockData, uin
|
|||
if (code) goto _exit;
|
||||
}
|
||||
} else {
|
||||
code = tsdbDecmprColData(pIn + n + hdr.szBlkCol + sizeof(TSCKSUM) + blockCol.offset, &blockCol, hdr.cmprAlg,
|
||||
hdr.nRow, pColData, &aBuf[0]);
|
||||
code = tsdbDecmprColData(pIn + n + hdr.szBlkCol + blockCol.offset, &blockCol, hdr.cmprAlg, hdr.nRow, pColData,
|
||||
&aBuf[0]);
|
||||
if (code) goto _exit;
|
||||
}
|
||||
}
|
||||
|
@ -2046,12 +2046,6 @@ int32_t tsdbCmprColData(SColData *pColData, int8_t cmprAlg, SBlockCol *pBlockCol
|
|||
}
|
||||
size += pBlockCol->szValue;
|
||||
|
||||
// checksum
|
||||
size += sizeof(TSCKSUM);
|
||||
code = tRealloc(ppOut, nOut + size);
|
||||
if (code) goto _exit;
|
||||
taosCalcChecksumAppend(0, *ppOut + nOut, size);
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
@ -2060,12 +2054,6 @@ int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, in
|
|||
uint8_t **ppBuf) {
|
||||
int32_t code = 0;
|
||||
|
||||
int32_t size = pBlockCol->szBitmap + pBlockCol->szOffset + pBlockCol->szValue + sizeof(TSCKSUM);
|
||||
if (!taosCheckChecksumWhole(pIn, size)) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
ASSERT(pColData->cid == pBlockCol->cid);
|
||||
ASSERT(pColData->type == pBlockCol->type);
|
||||
pColData->smaOn = pBlockCol->smaOn;
|
||||
|
@ -2137,37 +2125,3 @@ int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, in
|
|||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbReadAndCheck(TdFilePtr pFD, int64_t offset, uint8_t **ppOut, int32_t size, int8_t toCheck) {
|
||||
int32_t code = 0;
|
||||
|
||||
// alloc
|
||||
code = tRealloc(ppOut, size);
|
||||
if (code) goto _exit;
|
||||
|
||||
// seek
|
||||
int64_t n = taosLSeekFile(pFD, offset, SEEK_SET);
|
||||
if (n < 0) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// read
|
||||
n = taosReadFile(pFD, *ppOut, size);
|
||||
if (n < 0) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _exit;
|
||||
} else if (n < size) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// check
|
||||
if (toCheck && !taosCheckChecksumWhole(*ppOut, size)) {
|
||||
code = TSDB_CODE_FILE_CORRUPTED;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ int tsdbInsertData(STsdb *pTsdb, int64_t version, SSubmitReq *pMsg, SSubmitRsp *
|
|||
SSubmitBlkRsp r = {0};
|
||||
tGetSubmitMsgNext(&msgIter, &pBlock);
|
||||
if (pBlock == NULL) break;
|
||||
if (tsdbInsertTableData(pTsdb, version, &msgIter, pBlock, &r) < 0) {
|
||||
if ((terrno = tsdbInsertTableData(pTsdb, version, &msgIter, pBlock, &r)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tutil.h"
|
||||
#include "vnd.h"
|
||||
|
||||
const SVnodeCfg vnodeCfgDefault = {.vgId = -1,
|
||||
|
@ -47,7 +48,9 @@ const SVnodeCfg vnodeCfgDefault = {.vgId = -1,
|
|||
},
|
||||
.hashBegin = 0,
|
||||
.hashEnd = 0,
|
||||
.hashMethod = 0};
|
||||
.hashMethod = 0,
|
||||
.sttTrigger = TSDB_DEFAULT_STT_FILE,
|
||||
.tsdbPageSize = TSDB_DEFAULT_PAGE_SIZE};
|
||||
|
||||
int vnodeCheckCfg(const SVnodeCfg *pCfg) {
|
||||
// TODO
|
||||
|
@ -106,10 +109,12 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
|
|||
if (tjsonAddIntegerToObject(pJson, "wal.retentionSize", pCfg->walCfg.retentionSize) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "wal.segSize", pCfg->walCfg.segSize) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "wal.level", pCfg->walCfg.level) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "sstTrigger", pCfg->sstTrigger) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "sstTrigger", pCfg->sttTrigger) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "hashBegin", pCfg->hashBegin) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "hashEnd", pCfg->hashEnd) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "hashMethod", pCfg->hashMethod) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "hashPrefix", pCfg->hashPrefix) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "hashSuffix", pCfg->hashSuffix) < 0) return -1;
|
||||
|
||||
if (tjsonAddIntegerToObject(pJson, "syncCfg.replicaNum", pCfg->syncCfg.replicaNum) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "syncCfg.myIndex", pCfg->syncCfg.myIndex) < 0) return -1;
|
||||
|
@ -129,6 +134,9 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
|
|||
tjsonAddItemToArray(pNodeInfoArr, pNodeInfo);
|
||||
}
|
||||
|
||||
// add tsdb page size config
|
||||
if (tjsonAddIntegerToObject(pJson, "tsdbPageSize", pCfg->tsdbPageSize) < 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -206,7 +214,7 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "wal.level", pCfg->walCfg.level, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "sstTrigger", pCfg->sstTrigger, code);
|
||||
tjsonGetNumberValue(pJson, "sstTrigger", pCfg->sttTrigger, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "hashBegin", pCfg->hashBegin, code);
|
||||
if (code < 0) return -1;
|
||||
|
@ -214,6 +222,10 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "hashMethod", pCfg->hashMethod, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "hashPrefix", pCfg->hashPrefix, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "hashSuffix", pCfg->hashSuffix, code);
|
||||
if (code < 0) return -1;
|
||||
|
||||
tjsonGetNumberValue(pJson, "syncCfg.replicaNum", pCfg->syncCfg.replicaNum, code);
|
||||
if (code < 0) return -1;
|
||||
|
@ -242,6 +254,8 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
tjsonGetStringValue(pNodeInfo, "nodeFqdn", (pCfg->syncCfg.nodeInfo)[i].nodeFqdn);
|
||||
}
|
||||
|
||||
tjsonGetNumberValue(pJson, "tsdbPageSize", pCfg->tsdbPageSize, code);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -250,7 +264,8 @@ int vnodeValidateTableHash(SVnode *pVnode, char *tableFName) {
|
|||
|
||||
switch (pVnode->config.hashMethod) {
|
||||
default:
|
||||
hashValue = MurmurHash3_32(tableFName, strlen(tableFName));
|
||||
hashValue = taosGetTbHashVal(tableFName, strlen(tableFName), pVnode->config.hashMethod, pVnode->config.hashPrefix,
|
||||
pVnode->config.hashSuffix);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|||
|
||||
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pTfs), TD_DIRSEP, path);
|
||||
|
||||
info.config = vnodeCfgDefault;
|
||||
|
||||
// load vnode info
|
||||
ret = vnodeLoadInfo(dir, &info);
|
||||
if (ret < 0) {
|
||||
|
|
|
@ -368,6 +368,7 @@ _exit:
|
|||
int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad) {
|
||||
pLoad->vgId = TD_VID(pVnode);
|
||||
pLoad->syncState = syncGetMyRole(pVnode->sync);
|
||||
pLoad->cacheUsage = tsdbCacheGetUsage(pVnode);
|
||||
pLoad->numOfTables = metaGetTbNum(pVnode->pMeta);
|
||||
pLoad->numOfTimeSeries = metaGetTimeSeriesNum(pVnode->pMeta);
|
||||
pLoad->totalStorage = (int64_t)3 * 1073741824;
|
||||
|
@ -424,8 +425,8 @@ int32_t vnodeGetCtbIdList(SVnode *pVnode, int64_t suid, SArray *list) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t vnodeGetStbIdList(SVnode* pVnode, int64_t suid, SArray* list) {
|
||||
SMStbCursor* pCur = metaOpenStbCursor(pVnode->pMeta, suid);
|
||||
int32_t vnodeGetStbIdList(SVnode *pVnode, int64_t suid, SArray *list) {
|
||||
SMStbCursor *pCur = metaOpenStbCursor(pVnode->pMeta, suid);
|
||||
if (!pCur) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
@ -467,9 +468,13 @@ static int32_t vnodeGetStbColumnNum(SVnode *pVnode, tb_uid_t suid, int *num) {
|
|||
STSchema *pTSchema = metaGetTbTSchema(pVnode->pMeta, suid, -1);
|
||||
// metaGetTbTSchemaEx(pVnode->pMeta, suid, suid, -1, &pTSchema);
|
||||
|
||||
*num = pTSchema->numOfCols;
|
||||
if (pTSchema) {
|
||||
*num = pTSchema->numOfCols;
|
||||
|
||||
taosMemoryFree(pTSchema);
|
||||
taosMemoryFree(pTSchema);
|
||||
} else {
|
||||
*num = 2;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ struct SVSnapReader {
|
|||
SStreamStateReader *pStreamStateReader;
|
||||
// rsma
|
||||
int8_t rsmaDone;
|
||||
SRsmaSnapReader *pRsmaReader;
|
||||
SRSmaSnapReader *pRsmaReader;
|
||||
};
|
||||
|
||||
int32_t vnodeSnapReaderOpen(SVnode *pVnode, int64_t sver, int64_t ever, SVSnapReader **ppReader) {
|
||||
|
@ -241,7 +241,7 @@ struct SVSnapWriter {
|
|||
SStreamTaskWriter *pStreamTaskWriter;
|
||||
SStreamStateWriter *pStreamStateWriter;
|
||||
// rsma
|
||||
SRsmaSnapWriter *pRsmaSnapWriter;
|
||||
SRSmaSnapWriter *pRsmaSnapWriter;
|
||||
};
|
||||
|
||||
int32_t vnodeSnapWriterOpen(SVnode *pVnode, int64_t sver, int64_t ever, SVSnapWriter **ppWriter) {
|
||||
|
@ -354,7 +354,8 @@ int32_t vnodeSnapWrite(SVSnapWriter *pWriter, uint8_t *pData, uint32_t nData) {
|
|||
code = metaSnapWrite(pWriter->pMetaSnapWriter, pData, nData);
|
||||
if (code) goto _err;
|
||||
} break;
|
||||
case SNAP_DATA_TSDB: {
|
||||
case SNAP_DATA_TSDB:
|
||||
case SNAP_DATA_DEL: {
|
||||
// tsdb
|
||||
if (pWriter->pTsdbSnapWriter == NULL) {
|
||||
code = tsdbSnapWriterOpen(pVnode->pTsdb, pWriter->sver, pWriter->ever, &pWriter->pTsdbSnapWriter);
|
||||
|
|
|
@ -371,7 +371,7 @@ void vnodeUpdateMetaRsp(SVnode *pVnode, STableMetaRsp *pMetaRsp) {
|
|||
if (NULL == pMetaRsp) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
strcpy(pMetaRsp->dbFName, pVnode->config.dbname);
|
||||
pMetaRsp->dbId = pVnode->config.dbId;
|
||||
pMetaRsp->vgId = TD_VID(pVnode);
|
||||
|
@ -527,14 +527,14 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t version, void *pR
|
|||
cRsp.code = TSDB_CODE_SUCCESS;
|
||||
tdFetchTbUidList(pVnode->pSma, &pStore, pCreateReq->ctb.suid, pCreateReq->uid);
|
||||
taosArrayPush(tbUids, &pCreateReq->uid);
|
||||
vnodeUpdateMetaRsp(pVnode, cRsp.pMeta);
|
||||
vnodeUpdateMetaRsp(pVnode, cRsp.pMeta);
|
||||
}
|
||||
|
||||
taosArrayPush(rsp.pArray, &cRsp);
|
||||
}
|
||||
|
||||
tqUpdateTbUidList(pVnode->pTq, tbUids, true);
|
||||
if (tdUpdateTbUidList(pVnode->pSma, pStore) < 0) {
|
||||
if (tdUpdateTbUidList(pVnode->pSma, pStore, true) < 0) {
|
||||
goto _exit;
|
||||
}
|
||||
tdUidStoreFree(pStore);
|
||||
|
@ -692,6 +692,7 @@ static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq
|
|||
SEncoder encoder = {0};
|
||||
int32_t ret;
|
||||
SArray *tbUids = NULL;
|
||||
STbUidStore *pStore = NULL;
|
||||
|
||||
pRsp->msgType = TDMT_VND_DROP_TABLE_RSP;
|
||||
pRsp->pCont = NULL;
|
||||
|
@ -715,9 +716,10 @@ static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq
|
|||
for (int32_t iReq = 0; iReq < req.nReqs; iReq++) {
|
||||
SVDropTbReq *pDropTbReq = req.pReqs + iReq;
|
||||
SVDropTbRsp dropTbRsp = {0};
|
||||
tb_uid_t tbUid = 0;
|
||||
|
||||
/* code */
|
||||
ret = metaDropTable(pVnode->pMeta, version, pDropTbReq, tbUids);
|
||||
ret = metaDropTable(pVnode->pMeta, version, pDropTbReq, tbUids, &tbUid);
|
||||
if (ret < 0) {
|
||||
if (pDropTbReq->igNotExists && terrno == TSDB_CODE_VND_TABLE_NOT_EXIST) {
|
||||
dropTbRsp.code = TSDB_CODE_SUCCESS;
|
||||
|
@ -726,15 +728,18 @@ static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq
|
|||
}
|
||||
} else {
|
||||
dropTbRsp.code = TSDB_CODE_SUCCESS;
|
||||
if (tbUid > 0) tdFetchTbUidList(pVnode->pSma, &pStore, pDropTbReq->suid, tbUid);
|
||||
}
|
||||
|
||||
taosArrayPush(rsp.pArray, &dropTbRsp);
|
||||
}
|
||||
|
||||
tqUpdateTbUidList(pVnode->pTq, tbUids, false);
|
||||
tdUpdateTbUidList(pVnode->pSma, pStore, false);
|
||||
|
||||
_exit:
|
||||
taosArrayDestroy(tbUids);
|
||||
tdUidStoreFree(pStore);
|
||||
tDecoderClear(&decoder);
|
||||
tEncodeSize(tEncodeSVDropTbBatchRsp, &rsp, pRsp->contLen, ret);
|
||||
pRsp->pCont = rpcMallocCont(pRsp->contLen);
|
||||
|
@ -1107,6 +1112,7 @@ static int32_t vnodeProcessDeleteReq(SVnode *pVnode, int64_t version, void *pReq
|
|||
|
||||
tDecoderInit(pCoder, pReq, len);
|
||||
tDecodeDeleteRes(pCoder, pRes);
|
||||
ASSERT(taosArrayGetSize(pRes->uidList) == 0 || (pRes->skey != 0 && pRes->ekey != 0));
|
||||
|
||||
for (int32_t iUid = 0; iUid < taosArrayGetSize(pRes->uidList); iUid++) {
|
||||
code = tsdbDeleteTableData(pVnode->pTsdb, version, pRes->suid, *(uint64_t *)taosArrayGet(pRes->uidList, iUid),
|
||||
|
|
|
@ -367,18 +367,22 @@ void ctgdShowDBCache(SCatalog* pCtg, SHashObj *dbHash) {
|
|||
int32_t stbNum = dbCache->stbCache ? taosHashGetSize(dbCache->stbCache) : 0;
|
||||
int32_t vgVersion = CTG_DEFAULT_INVALID_VERSION;
|
||||
int32_t hashMethod = -1;
|
||||
int16_t hashPrefix = 0;
|
||||
int16_t hashSuffix = 0;
|
||||
int32_t vgNum = 0;
|
||||
|
||||
if (dbCache->vgCache.vgInfo) {
|
||||
vgVersion = dbCache->vgCache.vgInfo->vgVersion;
|
||||
hashMethod = dbCache->vgCache.vgInfo->hashMethod;
|
||||
hashPrefix = dbCache->vgCache.vgInfo->hashPrefix;
|
||||
hashSuffix = dbCache->vgCache.vgInfo->hashSuffix;
|
||||
if (dbCache->vgCache.vgInfo->vgHash) {
|
||||
vgNum = taosHashGetSize(dbCache->vgCache.vgInfo->vgHash);
|
||||
}
|
||||
}
|
||||
|
||||
ctgDebug("[%d] db [%.*s][0x%"PRIx64"] %s: metaNum:%d, stbNum:%d, vgVersion:%d, hashMethod:%d, vgNum:%d",
|
||||
i, (int32_t)len, dbFName, dbCache->dbId, dbCache->deleted?"deleted":"", metaNum, stbNum, vgVersion, hashMethod, vgNum);
|
||||
ctgDebug("[%d] db [%.*s][0x%"PRIx64"] %s: metaNum:%d, stbNum:%d, vgVersion:%d, hashMethod:%d, prefix:%d, suffix:%d, vgNum:%d",
|
||||
i, (int32_t)len, dbFName, dbCache->dbId, dbCache->deleted?"deleted":"", metaNum, stbNum, vgVersion, hashMethod, hashPrefix, hashSuffix, vgNum);
|
||||
|
||||
pIter = taosHashIterate(dbHash, pIter);
|
||||
}
|
||||
|
|
|
@ -848,15 +848,11 @@ int32_t ctgGetVgInfoFromHashValue(SCatalog *pCtg, SDBVgInfo *dbInfo, const SName
|
|||
CTG_ERR_RET(TSDB_CODE_TSC_DB_NOT_SELECTED);
|
||||
}
|
||||
|
||||
tableNameHashFp fp = NULL;
|
||||
SVgroupInfo *vgInfo = NULL;
|
||||
|
||||
CTG_ERR_RET(ctgGetHashFunction(dbInfo->hashMethod, &fp));
|
||||
|
||||
char tbFullName[TSDB_TABLE_FNAME_LEN];
|
||||
tNameExtractFullName(pTableName, tbFullName);
|
||||
|
||||
uint32_t hashValue = (*fp)(tbFullName, (uint32_t)strlen(tbFullName));
|
||||
uint32_t hashValue = taosGetTbHashVal(tbFullName, (uint32_t)strlen(tbFullName), dbInfo->hashMethod, dbInfo->hashPrefix, dbInfo->hashSuffix);
|
||||
|
||||
void *pIter = taosHashIterate(dbInfo->vgHash, NULL);
|
||||
while (pIter) {
|
||||
|
@ -919,11 +915,7 @@ int32_t ctgGetVgInfosFromHashValue(SCatalog *pCtg, SCtgTaskReq* tReq, SDBVgInfo
|
|||
CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
tableNameHashFp fp = NULL;
|
||||
SVgroupInfo *vgInfo = NULL;
|
||||
|
||||
CTG_ERR_RET(ctgGetHashFunction(dbInfo->hashMethod, &fp));
|
||||
|
||||
int32_t tbNum = taosArrayGetSize(pNames);
|
||||
|
||||
if (1 == vgNum) {
|
||||
|
@ -975,7 +967,7 @@ int32_t ctgGetVgInfosFromHashValue(SCatalog *pCtg, SCtgTaskReq* tReq, SDBVgInfo
|
|||
tbNameLen = offset + strlen(pName->tname);
|
||||
strcpy(tbFullName + offset, pName->tname);
|
||||
|
||||
uint32_t hashValue = (*fp)(tbFullName, (uint32_t)tbNameLen);
|
||||
uint32_t hashValue = taosGetTbHashVal(tbFullName, (uint32_t)strlen(tbFullName), dbInfo->hashMethod, dbInfo->hashPrefix, dbInfo->hashSuffix);
|
||||
|
||||
SVgroupInfo **p = taosArraySearch(pVgList, &hashValue, ctgHashValueComp, TD_EQ);
|
||||
|
||||
|
|
|
@ -218,6 +218,8 @@ void ctgTestBuildDBVgroup(SDBVgInfo **pdbVgroup) {
|
|||
ctgTestCurrentVgVersion = dbVgroup->vgVersion;
|
||||
|
||||
dbVgroup->hashMethod = 0;
|
||||
dbVgroup->hashPrefix = 0;
|
||||
dbVgroup->hashSuffix = 0;
|
||||
dbVgroup->vgHash = taosHashInit(ctgTestVgNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
|
||||
vgNum = ctgTestGetVgNumFromVgVersion(dbVgroup->vgVersion);
|
||||
|
|
|
@ -87,9 +87,7 @@ struct SqlFunctionCtx;
|
|||
|
||||
size_t getResultRowSize(struct SqlFunctionCtx* pCtx, int32_t numOfOutput);
|
||||
void initResultRowInfo(SResultRowInfo* pResultRowInfo);
|
||||
|
||||
void initResultRow(SResultRow* pResultRow);
|
||||
void closeResultRow(SResultRow* pResultRow);
|
||||
void closeResultRow(SResultRow* pResultRow);
|
||||
|
||||
struct SResultRowEntryInfo* getResultEntryInfo(const SResultRow* pRow, int32_t index, const int32_t* offset);
|
||||
|
||||
|
@ -128,6 +126,7 @@ SArray* extractPartitionColInfo(SNodeList* pNodeList);
|
|||
SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols,
|
||||
int32_t type);
|
||||
|
||||
void createExprFromTargetNode(SExprInfo* pExp, STargetNode* pTargetNode);
|
||||
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs);
|
||||
|
||||
SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowEntryInfoOffset);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -168,7 +168,9 @@ static void getDataLength(SDataSinkHandle* pHandle, int64_t* pLen, bool* pQueryE
|
|||
taosReadQitem(pDeleter->pDataBlocks, (void**)&pBuf);
|
||||
memcpy(&pDeleter->nextOutput, pBuf, sizeof(SDataDeleterBuf));
|
||||
taosFreeQitem(pBuf);
|
||||
*pLen = ((SDataCacheEntry*)(pDeleter->nextOutput.pData))->dataLen;
|
||||
|
||||
SDataCacheEntry* pEntry = (SDataCacheEntry*)pDeleter->nextOutput.pData;
|
||||
*pLen = pEntry->dataLen;
|
||||
*pQueryEnd = pDeleter->queryEnd;
|
||||
qDebug("got data len %" PRId64 ", row num %d in sink", *pLen, ((SDataCacheEntry*)(pDeleter->nextOutput.pData))->numOfRows);
|
||||
}
|
||||
|
|
|
@ -93,6 +93,8 @@ static void toDataCacheEntry(SDataDispatchHandle* pHandle, const SInputData* pIn
|
|||
|
||||
pBuf->useSize = sizeof(SDataCacheEntry);
|
||||
blockEncode(pInput->pData, pEntry->data, &pEntry->dataLen, numOfCols, pEntry->compressed);
|
||||
ASSERT(pEntry->numOfRows == *(int32_t*)(pEntry->data+8));
|
||||
ASSERT(pEntry->numOfCols == *(int32_t*)(pEntry->data+8+4));
|
||||
|
||||
pBuf->useSize += pEntry->dataLen;
|
||||
|
||||
|
@ -170,7 +172,13 @@ static void getDataLength(SDataSinkHandle* pHandle, int64_t* pLen, bool* pQueryE
|
|||
taosReadQitem(pDispatcher->pDataBlocks, (void**)&pBuf);
|
||||
memcpy(&pDispatcher->nextOutput, pBuf, sizeof(SDataDispatchBuf));
|
||||
taosFreeQitem(pBuf);
|
||||
*pLen = ((SDataCacheEntry*)(pDispatcher->nextOutput.pData))->dataLen;
|
||||
|
||||
SDataCacheEntry* pEntry = (SDataCacheEntry*)pDispatcher->nextOutput.pData;
|
||||
*pLen = pEntry->dataLen;
|
||||
|
||||
ASSERT(pEntry->numOfRows == *(int32_t*)(pEntry->data+8));
|
||||
ASSERT(pEntry->numOfCols == *(int32_t*)(pEntry->data+8+4));
|
||||
|
||||
*pQueryEnd = pDispatcher->queryEnd;
|
||||
qDebug("got data len %" PRId64 ", row num %d in sink", *pLen, ((SDataCacheEntry*)(pDispatcher->nextOutput.pData))->numOfRows);
|
||||
}
|
||||
|
@ -191,6 +199,9 @@ static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutputData* pOutput) {
|
|||
pOutput->numOfCols = pEntry->numOfCols;
|
||||
pOutput->compressed = pEntry->compressed;
|
||||
|
||||
ASSERT(pEntry->numOfRows == *(int32_t*)(pEntry->data+8));
|
||||
ASSERT(pEntry->numOfCols == *(int32_t*)(pEntry->data+8+4));
|
||||
|
||||
atomic_sub_fetch_64(&pDispatcher->cachedSize, pEntry->dataLen);
|
||||
atomic_sub_fetch_64(&gDataSinkStat.cachedSize, pEntry->dataLen);
|
||||
|
||||
|
|
|
@ -475,7 +475,6 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
qError("failed to create result, reason:%s", tstrerror(code));
|
||||
terrno = code;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -1012,6 +1011,100 @@ static SColumn* createColumn(int32_t blockId, int32_t slotId, int32_t colId, SDa
|
|||
return pCol;
|
||||
}
|
||||
|
||||
void createExprFromTargetNode(SExprInfo* pExp, STargetNode* pTargetNode) {
|
||||
pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
|
||||
pExp->pExpr->_function.num = 1;
|
||||
pExp->pExpr->_function.functionId = -1;
|
||||
|
||||
int32_t type = nodeType(pTargetNode->pExpr);
|
||||
// it is a project query, or group by column
|
||||
if (type == QUERY_NODE_COLUMN) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
|
||||
SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
|
||||
|
||||
pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
|
||||
pExp->base.numOfParams = 1;
|
||||
|
||||
SDataType* pType = &pColNode->node.resType;
|
||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pColNode->colName);
|
||||
pExp->base.pParam[0].pCol =
|
||||
createColumn(pColNode->dataBlockId, pColNode->slotId, pColNode->colId, pType, pColNode->colType);
|
||||
pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
|
||||
} else if (type == QUERY_NODE_VALUE) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_VALUE;
|
||||
SValueNode* pValNode = (SValueNode*)pTargetNode->pExpr;
|
||||
|
||||
pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
|
||||
pExp->base.numOfParams = 1;
|
||||
|
||||
SDataType* pType = &pValNode->node.resType;
|
||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pValNode->node.aliasName);
|
||||
pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
|
||||
nodesValueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
|
||||
} else if (type == QUERY_NODE_FUNCTION) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
|
||||
SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;
|
||||
|
||||
SDataType* pType = &pFuncNode->node.resType;
|
||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pFuncNode->node.aliasName);
|
||||
|
||||
pExp->pExpr->_function.functionId = pFuncNode->funcId;
|
||||
pExp->pExpr->_function.pFunctNode = pFuncNode;
|
||||
|
||||
strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
|
||||
tListLen(pExp->pExpr->_function.functionName));
|
||||
#if 1
|
||||
// todo refactor: add the parameter for tbname function
|
||||
if (!pFuncNode->pParameterList && (strcmp(pExp->pExpr->_function.functionName, "tbname") == 0)) {
|
||||
pFuncNode->pParameterList = nodesMakeList();
|
||||
ASSERT(LIST_LENGTH(pFuncNode->pParameterList) == 0);
|
||||
SValueNode* res = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
if (NULL == res) { // todo handle error
|
||||
} else {
|
||||
res->node.resType = (SDataType){.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT};
|
||||
nodesListAppend(pFuncNode->pParameterList, (SNode*)res);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
|
||||
|
||||
pExp->base.pParam = taosMemoryCalloc(numOfParam, sizeof(SFunctParam));
|
||||
pExp->base.numOfParams = numOfParam;
|
||||
|
||||
for (int32_t j = 0; j < numOfParam; ++j) {
|
||||
SNode* p1 = nodesListGetNode(pFuncNode->pParameterList, j);
|
||||
if (p1->type == QUERY_NODE_COLUMN) {
|
||||
SColumnNode* pcn = (SColumnNode*)p1;
|
||||
|
||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
|
||||
pExp->base.pParam[j].pCol =
|
||||
createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType, pcn->colType);
|
||||
} else if (p1->type == QUERY_NODE_VALUE) {
|
||||
SValueNode* pvn = (SValueNode*)p1;
|
||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
|
||||
nodesValueNodeToVariant(pvn, &pExp->base.pParam[j].param);
|
||||
}
|
||||
}
|
||||
} else if (type == QUERY_NODE_OPERATOR) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
|
||||
SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
|
||||
|
||||
pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
|
||||
pExp->base.numOfParams = 1;
|
||||
|
||||
SDataType* pType = &pNode->node.resType;
|
||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pNode->node.aliasName);
|
||||
pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs) {
|
||||
int32_t numOfFuncs = LIST_LENGTH(pNodeList);
|
||||
int32_t numOfGroupKeys = 0;
|
||||
|
@ -1035,98 +1128,7 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t*
|
|||
}
|
||||
|
||||
SExprInfo* pExp = &pExprs[i];
|
||||
|
||||
pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
|
||||
pExp->pExpr->_function.num = 1;
|
||||
pExp->pExpr->_function.functionId = -1;
|
||||
|
||||
int32_t type = nodeType(pTargetNode->pExpr);
|
||||
// it is a project query, or group by column
|
||||
if (type == QUERY_NODE_COLUMN) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
|
||||
SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
|
||||
|
||||
pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
|
||||
pExp->base.numOfParams = 1;
|
||||
|
||||
SDataType* pType = &pColNode->node.resType;
|
||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pColNode->colName);
|
||||
pExp->base.pParam[0].pCol =
|
||||
createColumn(pColNode->dataBlockId, pColNode->slotId, pColNode->colId, pType, pColNode->colType);
|
||||
pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
|
||||
} else if (type == QUERY_NODE_VALUE) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_VALUE;
|
||||
SValueNode* pValNode = (SValueNode*)pTargetNode->pExpr;
|
||||
|
||||
pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
|
||||
pExp->base.numOfParams = 1;
|
||||
|
||||
SDataType* pType = &pValNode->node.resType;
|
||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pValNode->node.aliasName);
|
||||
pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
|
||||
nodesValueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
|
||||
} else if (type == QUERY_NODE_FUNCTION) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
|
||||
SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;
|
||||
|
||||
SDataType* pType = &pFuncNode->node.resType;
|
||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pFuncNode->node.aliasName);
|
||||
|
||||
pExp->pExpr->_function.functionId = pFuncNode->funcId;
|
||||
pExp->pExpr->_function.pFunctNode = pFuncNode;
|
||||
|
||||
strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
|
||||
tListLen(pExp->pExpr->_function.functionName));
|
||||
#if 1
|
||||
// todo refactor: add the parameter for tbname function
|
||||
if (!pFuncNode->pParameterList && (strcmp(pExp->pExpr->_function.functionName, "tbname") == 0)) {
|
||||
pFuncNode->pParameterList = nodesMakeList();
|
||||
ASSERT(LIST_LENGTH(pFuncNode->pParameterList) == 0);
|
||||
SValueNode* res = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
if (NULL == res) { // todo handle error
|
||||
} else {
|
||||
res->node.resType = (SDataType){.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT};
|
||||
nodesListAppend(pFuncNode->pParameterList, (SNode*)res);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
|
||||
|
||||
pExp->base.pParam = taosMemoryCalloc(numOfParam, sizeof(SFunctParam));
|
||||
pExp->base.numOfParams = numOfParam;
|
||||
|
||||
for (int32_t j = 0; j < numOfParam; ++j) {
|
||||
SNode* p1 = nodesListGetNode(pFuncNode->pParameterList, j);
|
||||
if (p1->type == QUERY_NODE_COLUMN) {
|
||||
SColumnNode* pcn = (SColumnNode*)p1;
|
||||
|
||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
|
||||
pExp->base.pParam[j].pCol =
|
||||
createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType, pcn->colType);
|
||||
} else if (p1->type == QUERY_NODE_VALUE) {
|
||||
SValueNode* pvn = (SValueNode*)p1;
|
||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
|
||||
nodesValueNodeToVariant(pvn, &pExp->base.pParam[j].param);
|
||||
}
|
||||
}
|
||||
} else if (type == QUERY_NODE_OPERATOR) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
|
||||
SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
|
||||
|
||||
pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
|
||||
pExp->base.numOfParams = 1;
|
||||
|
||||
SDataType* pType = &pNode->node.resType;
|
||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pNode->node.aliasName);
|
||||
pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
createExprFromTargetNode(pExp, pTargetNode);
|
||||
}
|
||||
|
||||
return pExprs;
|
||||
|
|
|
@ -52,7 +52,11 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
|
|||
// TODO: if a block was set but not consumed,
|
||||
// prevent setting a different type of block
|
||||
pInfo->validBlockIndex = 0;
|
||||
taosArrayClear(pInfo->pBlockLists);
|
||||
if (pInfo->blockType == STREAM_INPUT__DATA_BLOCK) {
|
||||
taosArrayClearP(pInfo->pBlockLists, taosMemoryFree);
|
||||
} else {
|
||||
taosArrayClear(pInfo->pBlockLists);
|
||||
}
|
||||
|
||||
if (type == STREAM_INPUT__MERGED_SUBMIT) {
|
||||
// ASSERT(numOfBlocks > 1);
|
||||
|
@ -93,6 +97,8 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
|
|||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void streamInputBlockDataDestory(void* pBlock) { blockDataDestroy((SSDataBlock*)pBlock); }
|
||||
|
||||
void tdCleanupStreamInputDataBlock(qTaskInfo_t tinfo) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
if (!pTaskInfo || !pTaskInfo->pRoot || pTaskInfo->pRoot->numOfDownstream <= 0) {
|
||||
|
@ -103,11 +109,7 @@ void tdCleanupStreamInputDataBlock(qTaskInfo_t tinfo) {
|
|||
if (pOptrInfo->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
SStreamScanInfo* pInfo = pOptrInfo->info;
|
||||
if (pInfo->blockType == STREAM_INPUT__DATA_BLOCK) {
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pInfo->pBlockLists); ++i) {
|
||||
SSDataBlock* p = *(SSDataBlock**)taosArrayGet(pInfo->pBlockLists, i);
|
||||
taosArrayDestroy(p->pDataBlock);
|
||||
taosMemoryFreeClear(p);
|
||||
}
|
||||
taosArrayClearP(pInfo->pBlockLists, streamInputBlockDataDestory);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
|
|
@ -1866,13 +1866,11 @@ void updateLoadRemoteInfo(SLoadRemoteDataInfo* pInfo, int32_t numOfRows, int32_t
|
|||
pOperator->resultInfo.totalRows += numOfRows;
|
||||
}
|
||||
|
||||
int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, int32_t numOfOutput, SArray* pColList,
|
||||
char** pNextStart) {
|
||||
int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pColList, char** pNextStart) {
|
||||
if (pColList == NULL) { // data from other sources
|
||||
blockDataCleanup(pRes);
|
||||
*pNextStart = (char*)blockDecode(pRes, pData);
|
||||
} else { // extract data according to pColList
|
||||
ASSERT(numOfOutput == taosArrayGetSize(pColList));
|
||||
char* pStart = pData;
|
||||
|
||||
int32_t numOfCols = htonl(*(int32_t*)pStart);
|
||||
|
@ -1970,7 +1968,7 @@ static void concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeIn
|
|||
char* pStart = pRetrieveRsp->data;
|
||||
while (index++ < pRetrieveRsp->numOfBlocks) {
|
||||
SSDataBlock* pb = createOneDataBlock(pExchangeInfo->pDummyBlock, false);
|
||||
code = extractDataBlockFromFetchRsp(pb, pStart, pRetrieveRsp->numOfCols, NULL, &pStart);
|
||||
code = extractDataBlockFromFetchRsp(pb, pStart, NULL, &pStart);
|
||||
if (code != 0) {
|
||||
taosMemoryFreeClear(pDataInfo->pRsp);
|
||||
goto _error;
|
||||
|
@ -2095,7 +2093,7 @@ static int32_t seqLoadRemoteData(SOperatorInfo* pOperator) {
|
|||
SRetrieveTableRsp* pRetrieveRsp = pDataInfo->pRsp;
|
||||
|
||||
char* pStart = pRetrieveRsp->data;
|
||||
int32_t code = extractDataBlockFromFetchRsp(NULL, pStart, pRetrieveRsp->numOfCols, NULL, &pStart);
|
||||
int32_t code = extractDataBlockFromFetchRsp(NULL, pStart, NULL, &pStart);
|
||||
|
||||
if (pRsp->completed == 1) {
|
||||
qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " execId:%d numOfRows:%d, rowsOfSource:%" PRIu64
|
||||
|
@ -3441,6 +3439,44 @@ static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t
|
|||
}
|
||||
}
|
||||
|
||||
static bool isWstartColumnExist(SFillOperatorInfo* pInfo) {
|
||||
if (pInfo->numOfNotFillExpr == 0) {
|
||||
return false;
|
||||
}
|
||||
for (int32_t i = 0; i < pInfo->numOfNotFillExpr; ++i) {
|
||||
SExprInfo* exprInfo = pInfo->pNotFillExprInfo + i;
|
||||
if (exprInfo->pExpr->nodeType == QUERY_NODE_COLUMN &&
|
||||
exprInfo->base.numOfParams == 1 &&
|
||||
exprInfo->base.pParam[0].pCol->colType == COLUMN_TYPE_WINDOW_START) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t createWStartTsAsNotFillExpr(SFillOperatorInfo* pInfo, SFillPhysiNode* pPhyFillNode) {
|
||||
bool wstartExist = isWstartColumnExist(pInfo);
|
||||
if (wstartExist == false) {
|
||||
if (pPhyFillNode->pWStartTs->type != QUERY_NODE_TARGET) {
|
||||
qError("pWStartTs of fill physical node is not a target node");
|
||||
return TSDB_CODE_QRY_SYS_ERROR;
|
||||
}
|
||||
|
||||
SExprInfo* notFillExprs = taosMemoryRealloc(pInfo->pNotFillExprInfo, (pInfo->numOfNotFillExpr + 1) * sizeof(SExprInfo));
|
||||
if (notFillExprs == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
createExprFromTargetNode(notFillExprs + pInfo->numOfNotFillExpr, (STargetNode*)pPhyFillNode->pWStartTs);
|
||||
|
||||
++pInfo->numOfNotFillExpr;
|
||||
pInfo->pNotFillExprInfo = notFillExprs;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pPhyFillNode,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
|
||||
|
@ -3452,7 +3488,10 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
|
|||
SSDataBlock* pResBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc);
|
||||
SExprInfo* pExprInfo = createExprInfo(pPhyFillNode->pFillExprs, NULL, &pInfo->numOfExpr);
|
||||
pInfo->pNotFillExprInfo = createExprInfo(pPhyFillNode->pNotFillExprs, NULL, &pInfo->numOfNotFillExpr);
|
||||
|
||||
int32_t code = createWStartTsAsNotFillExpr(pInfo, pPhyFillNode);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
SInterval* pInterval =
|
||||
QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL == downstream->operatorType
|
||||
? &((SMergeAlignedIntervalAggOperatorInfo*)downstream->info)->intervalAggOperatorInfo->interval
|
||||
|
@ -3473,7 +3512,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
|
|||
SArray* pColMatchColInfo = extractColMatchInfo(pPhyFillNode->pFillExprs, pPhyFillNode->node.pOutputDataBlockDesc,
|
||||
&numOfOutputCols, COL_MATCH_FROM_SLOT_ID);
|
||||
|
||||
int32_t code = initFillInfo(pInfo, pExprInfo, pInfo->numOfExpr, pInfo->pNotFillExprInfo, pInfo->numOfNotFillExpr,
|
||||
code = initFillInfo(pInfo, pExprInfo, pInfo->numOfExpr, pInfo->pNotFillExprInfo, pInfo->numOfNotFillExpr,
|
||||
(SNodeListNode*)pPhyFillNode->pValues, pPhyFillNode->timeRange, pResultInfo->capacity,
|
||||
pTaskInfo->id.str, pInterval, type, order);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3915,7 +3954,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
pOptr = createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pAggNode->node.pConditions,
|
||||
pScalarExprInfo, numOfScalarExpr, pAggNode->mergeDataBlock, pTaskInfo);
|
||||
}
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL == type || QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL == type) {
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL == type) {
|
||||
SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
|
||||
|
||||
SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &num);
|
||||
|
@ -3940,6 +3979,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId, &as, pIntervalPhyNode,
|
||||
pTaskInfo, isStream);
|
||||
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL == type) {
|
||||
pOptr = createStreamIntervalOperatorInfo(ops[0], pPhyNode, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL == type) {
|
||||
SMergeAlignedIntervalPhysiNode* pIntervalPhyNode = (SMergeAlignedIntervalPhysiNode*)pPhyNode;
|
||||
pOptr = createMergeAlignedIntervalOperatorInfo(ops[0], pIntervalPhyNode, pTaskInfo);
|
||||
|
@ -4410,3 +4451,108 @@ int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, const char* pKey, SqlF
|
|||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t setOutputBuf(STimeWindow* win, SResultRow** pResult, int64_t tableGroupId, SqlFunctionCtx* pCtx,
|
||||
int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
SWinKey key = {
|
||||
.ts = win->skey,
|
||||
.groupId = tableGroupId,
|
||||
};
|
||||
char* value = NULL;
|
||||
int32_t size = pAggSup->resultRowSize;
|
||||
if (streamStateAddIfNotExist(pTaskInfo->streamInfo.pState, &key, (void**)&value, &size) < 0) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
*pResult = (SResultRow*)value;
|
||||
ASSERT(*pResult);
|
||||
// set time window for current result
|
||||
(*pResult)->win = (*win);
|
||||
setResultRowInitCtx(*pResult, pCtx, numOfOutput, rowEntryInfoOffset);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t releaseOutputBuf(SExecTaskInfo* pTaskInfo, SWinKey* pKey, SResultRow* pResult) {
|
||||
streamStateReleaseBuf(pTaskInfo->streamInfo.pState, pKey, pResult);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t saveOutput(SExecTaskInfo* pTaskInfo, SWinKey* pKey, SResultRow* pResult, int32_t resSize) {
|
||||
streamStatePut(pTaskInfo->streamInfo.pState, pKey, pResult, resSize);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t buildDataBlockFromGroupRes(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup,
|
||||
SGroupResInfo* pGroupResInfo) {
|
||||
SExprInfo* pExprInfo = pSup->pExprInfo;
|
||||
int32_t numOfExprs = pSup->numOfExprs;
|
||||
int32_t* rowEntryOffset = pSup->rowEntryInfoOffset;
|
||||
SqlFunctionCtx* pCtx = pSup->pCtx;
|
||||
|
||||
int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
|
||||
|
||||
for (int32_t i = pGroupResInfo->index; i < numOfRows; i += 1) {
|
||||
SResKeyPos* pPos = taosArrayGetP(pGroupResInfo->pRows, i);
|
||||
int32_t size = 0;
|
||||
void* pVal = NULL;
|
||||
SWinKey key = {
|
||||
.ts = *(TSKEY*)pPos->key,
|
||||
.groupId = pPos->groupId,
|
||||
};
|
||||
int32_t code = streamStateGet(pTaskInfo->streamInfo.pState, &key, &pVal, &size);
|
||||
ASSERT(code == 0);
|
||||
SResultRow* pRow = (SResultRow*)pVal;
|
||||
doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowEntryOffset);
|
||||
// no results, continue to check the next one
|
||||
if (pRow->numOfRows == 0) {
|
||||
pGroupResInfo->index += 1;
|
||||
releaseOutputBuf(pTaskInfo, &key, pRow);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pBlock->info.groupId == 0) {
|
||||
pBlock->info.groupId = pPos->groupId;
|
||||
} else {
|
||||
// current value belongs to different group, it can't be packed into one datablock
|
||||
if (pBlock->info.groupId != pPos->groupId) {
|
||||
releaseOutputBuf(pTaskInfo, &key, pRow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) {
|
||||
ASSERT(pBlock->info.rows > 0);
|
||||
releaseOutputBuf(pTaskInfo, &key, pRow);
|
||||
break;
|
||||
}
|
||||
|
||||
pGroupResInfo->index += 1;
|
||||
|
||||
for (int32_t j = 0; j < numOfExprs; ++j) {
|
||||
int32_t slotId = pExprInfo[j].base.resSchema.slotId;
|
||||
|
||||
pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowEntryOffset);
|
||||
if (pCtx[j].fpSet.finalize) {
|
||||
int32_t code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
|
||||
if (TAOS_FAILED(code)) {
|
||||
qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
} else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
|
||||
// do nothing, todo refactor
|
||||
} else {
|
||||
// expand the result into multiple rows. E.g., _wstart, top(k, 20)
|
||||
// the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows.
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo);
|
||||
for (int32_t k = 0; k < pRow->numOfRows; ++k) {
|
||||
colDataAppend(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
releaseOutputBuf(pTaskInfo, &key, pRow);
|
||||
pBlock->info.rows += pRow->numOfRows;
|
||||
}
|
||||
blockDataUpdateTsWindow(pBlock, 0);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue