Merge branch '3.0' into fix/3_liaohj
This commit is contained in:
commit
2a1a7c82e2
10
Jenkinsfile2
10
Jenkinsfile2
|
@ -151,14 +151,6 @@ def pre_test(){
|
|||
cd ${WKC}
|
||||
git submodule update --init --recursive
|
||||
'''
|
||||
sh '''
|
||||
cd ${WKPY}
|
||||
git reset --hard
|
||||
git pull
|
||||
git log -5
|
||||
echo "python connector log: `git log -5`" >>${WKDIR}/jenkins.log
|
||||
echo >>${WKDIR}/jenkins.log
|
||||
'''
|
||||
return 1
|
||||
}
|
||||
def pre_test_build_mac() {
|
||||
|
@ -409,7 +401,7 @@ pipeline {
|
|||
}
|
||||
}
|
||||
stage('linux test') {
|
||||
agent{label " slave1_47 || slave1_48 || slave1_49 || slave1_52 || worker03 || slave215 || slave217 || slave219 "}
|
||||
agent{label " slave1_50 || slave1_47 || slave1_48 || slave1_49 || slave1_52 || worker03 || slave215 || slave217 || slave219 "}
|
||||
options { skipDefaultCheckout() }
|
||||
when {
|
||||
changeRequest()
|
||||
|
|
|
@ -13,6 +13,6 @@ ExternalProject_Add(xml2
|
|||
BUILD_IN_SOURCE TRUE
|
||||
CONFIGURE_COMMAND ./configure --prefix=$ENV{HOME}/.cos-local.2 --enable-shared=no --enable-static=yes --without-python --without-lzma
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install && ln -s $ENV{HOME}/.cos-local.2/include/libxml2/libxml $ENV{HOME}/.cos-local.2/include/libxml
|
||||
INSTALL_COMMAND make install && ln -sf $ENV{HOME}/.cos-local.2/include/libxml2/libxml $ENV{HOME}/.cos-local.2/include/libxml
|
||||
TEST_COMMAND ""
|
||||
)
|
||||
|
|
|
@ -59,4 +59,4 @@ Query OK, 9 row(s) affected (0.004763s)
|
|||
|
||||
## Import using taosdump
|
||||
|
||||
A convenient tool for importing and exporting data is provided by TDengine, `taosdump`, which can be used to export data from one TDengine cluster and import into another one. For the details of using `taosdump` please refer to [Tool for exporting and importing data: taosdump](/reference/taosdump).
|
||||
A convenient tool for importing and exporting data is provided by TDengine, `taosdump`, which can be used to export data from one TDengine cluster and import into another one. For the details of using `taosdump` please refer to the taosdump documentation.
|
||||
|
|
|
@ -19,4 +19,4 @@ The data of table or STable specified by `tb_name` will be exported into a file
|
|||
|
||||
## Export Using taosdump
|
||||
|
||||
With `taosdump`, you can choose to export the data of all databases, a database, a table or a STable, you can also choose to export the data within a time range, or even only export the schema definition of a table. For the details of using `taosdump` please refer to [Tool for exporting and importing data: taosdump](/reference/taosdump).
|
||||
With `taosdump`, you can choose to export the data of all databases, a database, a table or a STable, you can also choose to export the data within a time range, or even only export the schema definition of a table. For the details of using `taosdump` please refer to the taosdump documentation.
|
||||
|
|
|
@ -11,8 +11,6 @@ The collection of the monitoring information is enabled by default, but can be d
|
|||
|
||||
TDinsight is a complete solution which uses the monitoring database `log` mentioned previously, and Grafana, to monitor a TDengine cluster.
|
||||
|
||||
Please refer to [TDinsight Grafana Dashboard](../../reference/tdinsight) to learn more details about using TDinsight to monitor TDengine.
|
||||
|
||||
A script `TDinsight.sh` is provided to deploy TDinsight automatically.
|
||||
|
||||
Download `TDinsight.sh` with the below command:
|
||||
|
|
|
@ -36,6 +36,7 @@ REST connection supports all platforms that can run Java.
|
|||
|
||||
| taos-jdbcdriver version | major changes | TDengine version |
|
||||
| :---------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------: |
|
||||
| 3.2.7 | Support VARBINARY and GEOMETRY types, and add time zone support for native connections. Support websocket auto reconnection | 3.2.0.0 or later |
|
||||
| 3.2.5 | Subscription add committed() and assignment() method | 3.1.0.3 or later |
|
||||
| 3.2.4 | Subscription add the enable.auto.commit parameter and the unsubscribe() method in the WebSocket connection | - |
|
||||
| 3.2.3 | Fixed resultSet data parsing failure in some cases | - |
|
||||
|
@ -178,7 +179,7 @@ Add following dependency in the `pom.xml` file of your Maven project:
|
|||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<version>3.2.7</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ The example to query the average system memory usage for the specified interval
|
|||
|
||||
### Importing the Dashboard
|
||||
|
||||
You can install TDinsight dashboard in data source configuration page (like `http://localhost:3000/datasources/edit/1/dashboards`) as a monitoring visualization tool for TDengine cluster. Ensure that you use TDinsight for 3.x. Please note TDinsight for 3.x needs to configure and run taoskeeper correctly. Check the [TDinsight User Manual](/reference/tdinsight/) for the details.
|
||||
You can install TDinsight dashboard in data source configuration page (like `http://localhost:3000/datasources/edit/1/dashboards`) as a monitoring visualization tool for TDengine cluster. Ensure that you use TDinsight for 3.x. Please note TDinsight for 3.x needs to configure and run taoskeeper correctly.
|
||||
|
||||

|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ REST 连接支持所有能运行 Java 的平台。
|
|||
|
||||
| taos-jdbcdriver 版本 | 主要变化 | TDengine 版本 |
|
||||
| :------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------: |
|
||||
| 3.2.7 | 支持VARBINARY和GEOMETRY类型,增加native连接的时区设置支持。增加websocket自动重连功能。 | 3.2.0.0 及更高版本 |
|
||||
| 3.2.5 | 数据订阅增加 committed()、assignment() 方法 | 3.1.0.3 及更高版本 |
|
||||
| 3.2.4 | 数据订阅在 WebSocket 连接下增加 enable.auto.commit 参数,以及 unsubscribe() 方法。 | - |
|
||||
| 3.2.3 | 修复 ResultSet 在一些情况数据解析失败 | - |
|
||||
|
@ -177,7 +178,7 @@ Maven 项目中,在 pom.xml 中添加以下依赖:
|
|||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<version>3.2.7</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
@ -1097,7 +1098,6 @@ TaosConsumer consumer = new TaosConsumer<>(config);
|
|||
- httpPoolSize: 同一个连接下最大并行请求数。仅在 WebSocket 连接下有效。
|
||||
其他参数请参考:[Consumer 参数列表](../../develop/tmq#创建-consumer-以及consumer-group), 注意TDengine服务端自3.2.0.0版本开始消息订阅中的auto.offset.reset默认值发生变化。
|
||||
|
||||
|
||||
#### 订阅消费数据
|
||||
|
||||
```java
|
||||
|
|
|
@ -105,7 +105,7 @@ spec:
|
|||
# TZ for timezone settings, we recommend to always set it.
|
||||
- name: TZ
|
||||
value: "Asia/Shanghai"
|
||||
# TAOS_ prefix will configured in taos.cfg, strip prefix and camelCase.
|
||||
# Environment variables with prefix TAOS_ will be parsed and converted into corresponding parameter in taos.cfg. For example, serverPort in taos.cfg should be configured by TAOS_SERVER_PORT when using K8S to deploy
|
||||
- name: TAOS_SERVER_PORT
|
||||
value: "6030"
|
||||
# Must set if you want a cluster.
|
||||
|
|
|
@ -53,7 +53,7 @@ database_option: {
|
|||
- 1:表示一阶段压缩。
|
||||
- 2:表示两阶段压缩。
|
||||
- DURATION:数据文件存储数据的时间跨度。可以使用加单位的表示形式,如 DURATION 100h、DURATION 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。不加时间单位时默认单位为天,如 DURATION 50 表示 50 天。
|
||||
- WAL_FSYNC_PERIOD:当 WAL 参数设置为 2 时,落盘的周期。默认为 3000,单位毫秒。最小为 0,表示每次写入立即落盘;最大为 180000,即三分钟。
|
||||
- WAL_FSYNC_PERIOD:当 WAL_LEVEL 参数设置为 2 时,用于设置落盘的周期。默认为 3000,单位毫秒。最小为 0,表示每次写入立即落盘;最大为 180000,即三分钟。
|
||||
- MAXROWS:文件块中记录的最大条数,默认为 4096 条。
|
||||
- MINROWS:文件块中记录的最小条数,默认为 100 条。
|
||||
- KEEP:表示数据文件保存的天数,缺省值为 3650,取值范围 [1, 365000],且必须大于或等于3倍的 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。也可以不写单位,如 KEEP 50,此时默认单位为天。企业版支持[多级存储](https://docs.taosdata.com/tdinternal/arch/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 <= keep 1 <= keep 2,如 KEEP 100h,100d,3650d); 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。
|
||||
|
|
|
@ -59,4 +59,4 @@ Query OK, 9 row(s) affected (0.004763s)
|
|||
|
||||
## taosdump 工具导入
|
||||
|
||||
TDengine 提供了方便的数据库导入导出工具 taosdump。用户可以将 taosdump 从一个系统导出的数据,导入到其他系统中。具体使用方法,请参见:[TDengine 数据备份工具: taosdump](/reference/taosdump)。
|
||||
TDengine 提供了方便的数据库导入导出工具 taosdump。用户可以将 taosdump 从一个系统导出的数据,导入到其他系统中。具体使用方法,请参考 taosdump 的相关文档。
|
||||
|
|
|
@ -17,5 +17,4 @@ select * from <tb_name> >> data.csv;
|
|||
|
||||
## 用 taosdump 导出数据
|
||||
|
||||
利用 taosdump,用户可以根据需要选择导出所有数据库、一个数据库或者数据库中的一张表,所有数据或一时间段的数据,甚至仅仅表的定义。具体使用方法,请参见:
|
||||
[TDengine 数据备份工具: taosdump](/reference/taosdump)。
|
||||
利用 taosdump,用户可以根据需要选择导出所有数据库、一个数据库或者数据库中的一张表,所有数据或一时间段的数据,甚至仅仅表的定义。具体使用方法,请参考 taosdump 的相关文档。
|
|
@ -218,7 +218,7 @@ docker run -d \
|
|||
|
||||
### 导入 Dashboard
|
||||
|
||||
在数据源配置页面,您可以为该数据源导入 TDinsight 面板,作为 TDengine 集群的监控可视化工具。如果 TDengine 服务端为 3.0 版本请选择 `TDinsight for 3.x` 导入。注意 TDinsight for 3.x 需要运行和配置 taoskeeper,相关使用说明请见 [TDinsight 用户手册](/reference/tdinsight/)。
|
||||
在数据源配置页面,您可以为该数据源导入 TDinsight 面板,作为 TDengine 集群的监控可视化工具。如果 TDengine 服务端为 3.0 版本请选择 `TDinsight for 3.x` 导入。注意 TDinsight for 3.x 需要运行和配置 taoskeeper。
|
||||
|
||||

|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
title: TSZ 压缩算法
|
||||
description: TDengine 对浮点数进行高效压缩的算法
|
||||
---
|
||||
|
||||
TSZ 压缩算法是 TDengine 为浮点数据类型提供的可选压缩算法,可以实现浮点数有损至无损全状态压缩,相比默认压缩算法, TSZ 压缩算法压缩率更高,即使切至无损状态,压缩率也会比默认压缩高一倍。
|
||||
|
||||
## 适合场景
|
||||
|
||||
- TSZ 压缩算法是通过数据预测技术完成的压缩,所以更适合有规律变化的数据
|
||||
- TSZ 压缩时间会更长一些,如果您的服务器 CPU 空闲多,存储空间小的情况下适合选用
|
||||
|
||||
## 使用步骤
|
||||
- TDengine 支持版本为 3.2.0.0 或以上
|
||||
- 开启选项
|
||||
在 taos.cfg 配置中增加以下内容,即可开启 TSZ 压缩算法,功能打开后,会替换默认算法。
|
||||
以下表示字段类型是 float 及 double 类型都使用此压缩算法,也可以单独只配置一个
|
||||
|
||||
```sql
|
||||
lossyColumns float|double
|
||||
```
|
||||
|
||||
- 配置需重启服务生效
|
||||
- Taosd 日志输出以下内容,表明功能已生效:
|
||||
|
||||
```sql
|
||||
02/22 10:49:27.607990 00002933 UTL lossyColumns float|double
|
||||
```
|
||||
|
||||
## 配置参数
|
||||
|
||||
### fPrecision
|
||||
FLOAT 类型精度控制:
|
||||
|
||||
| 属性 | 说明 |
|
||||
| -------- | -------------------------------- |
|
||||
| 适用范围 | 服务器端 |
|
||||
| 含义 | 设置 float 类型浮点数压缩精度 |
|
||||
| 取值范围 | 0.1 ~ 0.00000001 |
|
||||
| 缺省值 | 0.00000001 |
|
||||
| 补充说明 | 小于此值的浮点数尾数部分将被截取 |
|
||||
|
||||
|
||||
|
||||
### dPrecision
|
||||
DOUBLE 类型精度控制:
|
||||
|
||||
| 属性 | 说明 |
|
||||
| -------- | -------------------------------- |
|
||||
| 适用范围 | 服务器端 |
|
||||
| 含义 | 设置 double 类型浮点数压缩精度 |
|
||||
| 取值范围 | 0.1 ~ 0.0000000000000001 |
|
||||
| 缺省值 | 0.0000000000000001 |
|
||||
| 补充说明 | 小于此值的浮点数尾数部分将被截取 |
|
||||
|
||||
|
||||
### ifAdtFse
|
||||
TSZ 压缩中可选择的算法 FSE,默认为 HUFFMAN:
|
||||
|
||||
| 属性 | 说明 |
|
||||
| -------- | -------------------------------- |
|
||||
| 适用范围 | 服务器端 |
|
||||
| 含义 | 使用 FSE 算法替换 HUFFMAN 算法, FSE 算法压缩速度更快,但解压稍慢,追求压缩速度可选用此算法 |
|
||||
| 取值范围 | 0:关闭 1:打开 |
|
||||
| 缺省值 | 0:关闭 |
|
||||
|
||||
|
||||
## 注意事项
|
||||
- 打开 TSZ 后生成的存储数据格式,回退至 3.2.0.0 之前的版本,数据将不能被识别
|
|
@ -67,7 +67,7 @@
|
|||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.2.7</version>
|
||||
<!-- <scope>system</scope>-->
|
||||
<!-- <systemPath>${project.basedir}/src/main/resources/lib/taos-jdbcdriver-2.0.15-dist.jar</systemPath>-->
|
||||
</dependency>
|
||||
|
|
|
@ -365,6 +365,11 @@ typedef struct SSortExecInfo {
|
|||
int32_t readBytes; // read io bytes
|
||||
} SSortExecInfo;
|
||||
|
||||
typedef struct SNonSortExecInfo {
|
||||
int32_t blkNums;
|
||||
} SNonSortExecInfo;
|
||||
|
||||
|
||||
typedef struct STUidTagInfo {
|
||||
char* name;
|
||||
uint64_t uid;
|
||||
|
|
|
@ -217,13 +217,13 @@ int32_t taosCreateLog(const char *logname, int32_t logFileNum, const char *cfgDi
|
|||
int32_t taosInitCfg(const char *cfgDir, const char **envCmd, const char *envFile, char *apolloUrl, SArray *pArgs,
|
||||
bool tsc);
|
||||
void taosCleanupCfg();
|
||||
void taosCfgDynamicOptions(const char *option, const char *value);
|
||||
|
||||
int32_t taosCfgDynamicOptions(SConfig *pCfg, char *name, bool forServer);
|
||||
|
||||
struct SConfig *taosGetCfg();
|
||||
|
||||
void taosSetAllDebugFlag(int32_t flag, bool rewrite);
|
||||
void taosSetDebugFlag(int32_t *pFlagPtr, const char *flagName, int32_t flagVal, bool rewrite);
|
||||
int32_t taosApplyLocalCfg(SConfig *pCfg, char *name);
|
||||
void taosLocalCfgForbiddenToChange(char *name, bool *forbidden);
|
||||
int8_t taosGranted();
|
||||
|
||||
|
|
|
@ -3774,6 +3774,7 @@ typedef struct {
|
|||
int64_t suid;
|
||||
SArray* deleteReqs; // SArray<SSingleDeleteReq>
|
||||
int64_t ctimeMs; // fill by vnode
|
||||
int8_t level; // 0 tsdb(default), 1 rsma1 , 2 rsma2
|
||||
} SBatchDeleteReq;
|
||||
|
||||
int32_t tEncodeSBatchDeleteReq(SEncoder* pCoder, const SBatchDeleteReq* pReq);
|
||||
|
|
|
@ -118,6 +118,13 @@ int32_t taosChar2Ts(const char* format, SArray** formats, const char* tsStr, int
|
|||
void TEST_ts2char(const char* format, int64_t ts, int32_t precision, char* out, int32_t outLen);
|
||||
int32_t TEST_char2ts(const char* format, int64_t* ts, int32_t precision, const char* tsStr);
|
||||
|
||||
/// @brief get offset seconds from zero timezone to input timezone
|
||||
/// for +XX timezone, the offset to zero is negative value
|
||||
/// @param tzStr timezonestr, eg: +0800, -0830, -08
|
||||
/// @param offset seconds, eg: +08 offset -28800, -01 offset 3600
|
||||
/// @return 0 success, other fail
|
||||
int32_t offsetOfTimezone(char* tzStr, int64_t* offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -119,6 +119,7 @@ typedef struct SRowBuffPos {
|
|||
bool beFlushed;
|
||||
bool beUsed;
|
||||
bool needFree;
|
||||
bool beUpdated;
|
||||
} SRowBuffPos;
|
||||
|
||||
// tq
|
||||
|
@ -387,6 +388,8 @@ typedef struct SStateStore {
|
|||
int32_t (*streamStateStateAddIfNotExist)(SStreamState* pState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
|
||||
state_key_cmpr_fn fn, void** pVal, int32_t* pVLen);
|
||||
int32_t (*streamStateSessionGetKeyByRange)(SStreamState* pState, const SSessionKey* range, SSessionKey* curKey);
|
||||
int32_t (*streamStateSessionAllocWinBuffByNextPosition)(SStreamState* pState, SStreamStateCur* pCur,
|
||||
const SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
SUpdateInfo* (*updateInfoInit)(int64_t interval, int32_t precision, int64_t watermark, bool igUp);
|
||||
TSKEY (*updateInfoFillBlockData)(SUpdateInfo* pInfo, SSDataBlock* pBlock, int32_t primaryTsCol);
|
||||
|
|
|
@ -121,6 +121,7 @@ int32_t nodesListMakeAppend(SNodeList** pList, SNode* pNode);
|
|||
int32_t nodesListMakeStrictAppend(SNodeList** pList, SNode* pNode);
|
||||
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc);
|
||||
int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc);
|
||||
int32_t nodesListMakeStrictAppendList(SNodeList** pTarget, SNodeList* pSrc);
|
||||
int32_t nodesListPushFront(SNodeList* pList, SNode* pNode);
|
||||
SListCell* nodesListErase(SNodeList* pList, SListCell* pCell);
|
||||
void nodesListInsertList(SNodeList* pTarget, SListCell* pPos, SNodeList* pSrc);
|
||||
|
|
|
@ -40,6 +40,13 @@ typedef enum EGroupAction {
|
|||
GROUP_ACTION_CLEAR
|
||||
} EGroupAction;
|
||||
|
||||
typedef enum EMergeType {
|
||||
MERGE_TYPE_SORT = 1,
|
||||
MERGE_TYPE_NON_SORT,
|
||||
MERGE_TYPE_COLUMNS,
|
||||
MERGE_TYPE_MAX_VALUE
|
||||
} EMergeType;
|
||||
|
||||
typedef struct SLogicNode {
|
||||
ENodeType type;
|
||||
bool dynamicOp;
|
||||
|
@ -138,6 +145,7 @@ typedef struct SAggLogicNode {
|
|||
bool hasGroupKeyOptimized;
|
||||
bool isGroupTb;
|
||||
bool isPartTb; // true if partition keys has tbname
|
||||
bool hasGroup;
|
||||
} SAggLogicNode;
|
||||
|
||||
typedef struct SProjectLogicNode {
|
||||
|
@ -221,6 +229,8 @@ typedef struct SMergeLogicNode {
|
|||
SNodeList* pInputs;
|
||||
int32_t numOfChannels;
|
||||
int32_t srcGroupId;
|
||||
bool colsMerge;
|
||||
bool needSort;
|
||||
bool groupSort;
|
||||
bool ignoreGroupId;
|
||||
bool inputWithGroupId;
|
||||
|
@ -532,6 +542,7 @@ typedef struct SExchangePhysiNode {
|
|||
|
||||
typedef struct SMergePhysiNode {
|
||||
SPhysiNode node;
|
||||
EMergeType type;
|
||||
SNodeList* pMergeKeys;
|
||||
SNodeList* pTargets;
|
||||
int32_t numOfChannels;
|
||||
|
|
|
@ -57,6 +57,8 @@ int32_t streamStateSessionDel(SStreamState* pState, const SSessionKey* key);
|
|||
int32_t streamStateSessionClear(SStreamState* pState);
|
||||
int32_t streamStateSessionGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateSessionGetKeyByRange(SStreamState* pState, const SSessionKey* range, SSessionKey* curKey);
|
||||
int32_t streamStateSessionAllocWinBuffByNextPosition(SStreamState* pState, SStreamStateCur* pCur,
|
||||
const SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
SStreamStateCur* streamStateSessionSeekKeyNext(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* streamStateSessionSeekKeyCurrentPrev(SStreamState* pState, const SSessionKey* key);
|
||||
|
@ -66,6 +68,7 @@ SStreamStateCur* streamStateSessionSeekKeyCurrentNext(SStreamState* pState, cons
|
|||
int32_t streamStateStateAddIfNotExist(SStreamState* pState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
|
||||
state_key_cmpr_fn fn, void** pVal, int32_t* pVLen);
|
||||
|
||||
// fill
|
||||
int32_t streamStateFillPut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen);
|
||||
int32_t streamStateFillGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateFillDel(SStreamState* pState, const SWinKey* key);
|
||||
|
|
|
@ -76,8 +76,10 @@ int32_t getRowStateRowSize(SStreamFileState* pFileState);
|
|||
int32_t getSessionWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, TSKEY gap, void** pVal, int32_t* pVLen);
|
||||
int32_t putSessionWinResultBuff(SStreamFileState* pFileState, SRowBuffPos* pPos);
|
||||
int32_t getSessionFlushedBuff(SStreamFileState* pFileState, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
int32_t deleteSessionWinStateBuffFn(void* pBuff, const void *key, size_t keyLen);
|
||||
int32_t deleteSessionWinStateBuffFn(void* pBuff, const void* key, size_t keyLen);
|
||||
int32_t deleteSessionWinStateBuffByPosFn(SStreamFileState* pFileState, SRowBuffPos* pPos);
|
||||
int32_t allocSessioncWinBuffByNextPosition(SStreamFileState* pFileState, SStreamStateCur* pCur,
|
||||
const SSessionKey* pWinKey, void** ppVal, int32_t* pVLen);
|
||||
|
||||
SRowBuffPos* createSessionWinBuff(SStreamFileState* pFileState, SSessionKey* pKey, void* p, int32_t* pVLen);
|
||||
int32_t recoverSesssion(SStreamFileState* pFileState, int64_t ckId);
|
||||
|
|
|
@ -172,7 +172,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_TSC_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0X0231)
|
||||
|
||||
// mnode-common
|
||||
// #define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) // 2.x
|
||||
#define TSDB_CODE_MND_REQ_REJECTED TAOS_DEF_ERROR_CODE(0, 0x0300)
|
||||
// #define TSDB_CODE_MND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0301) // 2.x
|
||||
// #define TSDB_CODE_MND_ACTION_NEED_REPROCESSEDTAOS_DEF_ERROR_CODE(0, 0x0302) // 2.x
|
||||
#define TSDB_CODE_MND_NO_RIGHTS TAOS_DEF_ERROR_CODE(0, 0x0303)
|
||||
|
@ -640,6 +640,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_SCH_IGNORE_ERROR TAOS_DEF_ERROR_CODE(0, 0x2503)
|
||||
#define TSDB_CODE_SCH_TIMEOUT_ERROR TAOS_DEF_ERROR_CODE(0, 0x2504)
|
||||
#define TSDB_CODE_SCH_JOB_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x2505)
|
||||
#define TSDB_CODE_SCH_JOB_NOT_EXISTS TAOS_DEF_ERROR_CODE(0, 0x2506)
|
||||
|
||||
//parser
|
||||
#define TSDB_CODE_PAR_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x2600)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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_UNIT_H_
|
||||
#define _TD_UNIT_H_
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int64_t taosStrHumanToInt64(const char* str);
|
||||
void taosInt64ToHumanStr(int64_t val, char* outStr);
|
||||
|
||||
int32_t taosStrHumanToInt32(const char* str);
|
||||
void taosInt32ToHumanStr(int32_t val, char* outStr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_UNIT_H_*/
|
|
@ -34,6 +34,7 @@ benchmarkName="taosBenchmark"
|
|||
dumpName="taosdump"
|
||||
demoName="taosdemo"
|
||||
xname="taosx"
|
||||
keeperName="taoskeeper"
|
||||
|
||||
clientName2="taos"
|
||||
serverName2="${clientName2}d"
|
||||
|
@ -42,6 +43,7 @@ productName2="TDengine"
|
|||
emailName2="taosdata.com"
|
||||
xname2="${clientName2}x"
|
||||
adapterName2="${clientName2}adapter"
|
||||
keeperName2="${clientName2}keeper"
|
||||
|
||||
explorerName="${clientName2}-explorer"
|
||||
benchmarkName2="${clientName2}Benchmark"
|
||||
|
@ -154,7 +156,7 @@ interactiveFqdn=yes # [yes | no]
|
|||
verType=server # [server | client]
|
||||
initType=systemd # [systemd | service | ...]
|
||||
|
||||
while getopts "hv:e:i:" arg; do
|
||||
while getopts "hv:e:" arg; do
|
||||
case $arg in
|
||||
e)
|
||||
#echo "interactiveFqdn=$OPTARG"
|
||||
|
@ -164,10 +166,6 @@ while getopts "hv:e:i:" arg; do
|
|||
#echo "verType=$OPTARG"
|
||||
verType=$(echo $OPTARG)
|
||||
;;
|
||||
i)
|
||||
#echo "initType=$OPTARG"
|
||||
initType=$(echo $OPTARG)
|
||||
;;
|
||||
h)
|
||||
echo "Usage: $(basename $0) -v [server | client] -e [yes | no]"
|
||||
exit 0
|
||||
|
@ -218,6 +216,7 @@ function install_bin() {
|
|||
${csudo}rm -f ${bin_link_dir}/${demoName2} || :
|
||||
${csudo}rm -f ${bin_link_dir}/${benchmarkName2} || :
|
||||
${csudo}rm -f ${bin_link_dir}/${dumpName2} || :
|
||||
${csudo}rm -f ${bin_link_dir}/${keeperName2} || :
|
||||
${csudo}rm -f ${bin_link_dir}/set_core || :
|
||||
${csudo}rm -f ${bin_link_dir}/TDinsight.sh || :
|
||||
|
||||
|
@ -231,6 +230,7 @@ function install_bin() {
|
|||
[ -x ${install_main_dir}/bin/${benchmarkName2} ] && ${csudo}ln -sf ${install_main_dir}/bin/${benchmarkName2} ${bin_link_dir}/${demoName2} || :
|
||||
[ -x ${install_main_dir}/bin/${benchmarkName2} ] && ${csudo}ln -sf ${install_main_dir}/bin/${benchmarkName2} ${bin_link_dir}/${benchmarkName2} || :
|
||||
[ -x ${install_main_dir}/bin/${dumpName2} ] && ${csudo}ln -sf ${install_main_dir}/bin/${dumpName2} ${bin_link_dir}/${dumpName2} || :
|
||||
[ -x ${install_main_dir}/bin/${keeperName2} ] && ${csudo}ln -sf ${install_main_dir}/bin/${keeperName2} ${bin_link_dir}/${keeperName2} || :
|
||||
[ -x ${install_main_dir}/bin/TDinsight.sh ] && ${csudo}ln -sf ${install_main_dir}/bin/TDinsight.sh ${bin_link_dir}/TDinsight.sh || :
|
||||
if [ "$clientName2" == "${clientName}" ]; then
|
||||
[ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/${uninstallScript} || :
|
||||
|
@ -373,42 +373,56 @@ function add_newHostname_to_hosts() {
|
|||
return
|
||||
fi
|
||||
done
|
||||
${csudo}echo "127.0.0.1 $1" >>/etc/hosts || :
|
||||
|
||||
if grep -q "127.0.0.1 $1" /etc/hosts; then
|
||||
return
|
||||
else
|
||||
${csudo}chmod 666 /etc/hosts
|
||||
${csudo}echo "127.0.0.1 $1" >>/etc/hosts
|
||||
fi
|
||||
}
|
||||
|
||||
function set_hostname() {
|
||||
echo -e -n "${GREEN}Please enter one hostname(must not be 'localhost')${NC}:"
|
||||
read newHostname
|
||||
echo -e -n "${GREEN}Host name or IP (assigned to this machine) which can be accessed by your tools or apps (must not be 'localhost')${NC}"
|
||||
read -e -p " : " -i "$(hostname)" newHostname
|
||||
while true; do
|
||||
if [[ ! -z "$newHostname" && "$newHostname" != "localhost" ]]; then
|
||||
if [ -z "$newHostname" ]; then
|
||||
newHostname=$(hostname)
|
||||
break
|
||||
elif [ "$newHostname" != "localhost" ]; then
|
||||
break
|
||||
else
|
||||
read -p "Please enter one hostname(must not be 'localhost'):" newHostname
|
||||
echo -e -n "${GREEN}Host name or IP (assigned to this machine) which can be accessed by your tools or apps (must not be 'localhost')${NC}"
|
||||
read -e -p " : " -i "$(hostname)" newHostname
|
||||
fi
|
||||
done
|
||||
|
||||
${csudo}hostname $newHostname || :
|
||||
retval=$(echo $?)
|
||||
if [[ $retval != 0 ]]; then
|
||||
echo
|
||||
echo "set hostname fail!"
|
||||
return
|
||||
fi
|
||||
# ${csudo}hostname $newHostname || :
|
||||
# retval=$(echo $?)
|
||||
# if [[ $retval != 0 ]]; then
|
||||
# echo
|
||||
# echo "set hostname fail!"
|
||||
# return
|
||||
# fi
|
||||
|
||||
#ubuntu/centos /etc/hostname
|
||||
if [[ -e /etc/hostname ]]; then
|
||||
${csudo}echo $newHostname >/etc/hostname || :
|
||||
fi
|
||||
# #ubuntu/centos /etc/hostname
|
||||
# if [[ -e /etc/hostname ]]; then
|
||||
# ${csudo}echo $newHostname >/etc/hostname || :
|
||||
# fi
|
||||
|
||||
#debian: #HOSTNAME=yourname
|
||||
if [[ -e /etc/sysconfig/network ]]; then
|
||||
${csudo}sed -i -r "s/#*\s*(HOSTNAME=\s*).*/\1$newHostname/" /etc/sysconfig/network || :
|
||||
fi
|
||||
# #debian: #HOSTNAME=yourname
|
||||
# if [[ -e /etc/sysconfig/network ]]; then
|
||||
# ${csudo}sed -i -r "s/#*\s*(HOSTNAME=\s*).*/\1$newHostname/" /etc/sysconfig/network || :
|
||||
# fi
|
||||
|
||||
if [ -f ${cfg_install_dir}/${configFile2} ]; then
|
||||
${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$newHostname/" ${cfg_install_dir}/${configFile2}
|
||||
else
|
||||
${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$newHostname/" ${script_dir}/cfg/${configFile2}
|
||||
fi
|
||||
serverFqdn=$newHostname
|
||||
|
||||
if [[ -e /etc/hosts ]]; then
|
||||
if [[ -e /etc/hosts ]] && [[ ! $newHostname =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
add_newHostname_to_hosts $newHostname
|
||||
fi
|
||||
}
|
||||
|
@ -439,7 +453,12 @@ function set_ipAsFqdn() {
|
|||
echo -e -n "${GREEN}Unable to get local ip, use 127.0.0.1${NC}"
|
||||
localFqdn="127.0.0.1"
|
||||
# Write the local FQDN to configuration file
|
||||
|
||||
if [ -f ${cfg_install_dir}/${configFile2} ]; then
|
||||
${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${cfg_install_dir}/${configFile2}
|
||||
else
|
||||
${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${script_dir}/cfg/${configFile2}
|
||||
fi
|
||||
serverFqdn=$localFqdn
|
||||
echo
|
||||
return
|
||||
|
@ -461,7 +480,11 @@ function set_ipAsFqdn() {
|
|||
read -p "Please choose an IP from local IP list:" localFqdn
|
||||
else
|
||||
# Write the local FQDN to configuration file
|
||||
if [ -f ${cfg_install_dir}/${configFile2} ]; then
|
||||
${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${cfg_install_dir}/${configFile2}
|
||||
else
|
||||
${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${script_dir}/cfg/${configFile2}
|
||||
fi
|
||||
serverFqdn=$localFqdn
|
||||
break
|
||||
fi
|
||||
|
@ -476,37 +499,13 @@ function local_fqdn_check() {
|
|||
echo
|
||||
echo -e -n "System hostname is: ${GREEN}$serverFqdn${NC}"
|
||||
echo
|
||||
if [[ "$serverFqdn" == "" ]] || [[ "$serverFqdn" == "localhost" ]]; then
|
||||
echo -e -n "${GREEN}It is strongly recommended to configure a hostname for this machine ${NC}"
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -r -p "Set hostname now? [Y/n] " input
|
||||
if [ ! -n "$input" ]; then
|
||||
set_hostname
|
||||
break
|
||||
else
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
set_hostname
|
||||
break
|
||||
;;
|
||||
|
||||
[nN][oO] | [nN])
|
||||
set_ipAsFqdn
|
||||
break
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Invalid input..."
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
function install_adapter_config() {
|
||||
if [ -f ${script_dir}/cfg/${adapterName}.toml ]; then
|
||||
${csudo}sed -i -r "s/localhost/${serverFqdn}/g" ${script_dir}/cfg/${adapterName}.toml
|
||||
fi
|
||||
if [ ! -f "${cfg_install_dir}/${adapterName}.toml" ]; then
|
||||
${csudo}mkdir -p ${cfg_install_dir}
|
||||
[ -f ${script_dir}/cfg/${adapterName}.toml ] && ${csudo}cp ${script_dir}/cfg/${adapterName}.toml ${cfg_install_dir}
|
||||
|
@ -523,13 +522,38 @@ function install_adapter_config() {
|
|||
|
||||
}
|
||||
|
||||
function install_keeper_config() {
|
||||
if [ -f ${script_dir}/cfg/${keeperName2}.toml ]; then
|
||||
${csudo}sed -i -r "s/127.0.0.1/${serverFqdn}/g" ${script_dir}/cfg/${keeperName2}.toml
|
||||
fi
|
||||
if [ -f "${configDir}/keeper.toml" ]; then
|
||||
echo "The file keeper.toml will be renamed to ${keeperName2}.toml"
|
||||
${csudo}cp ${script_dir}/cfg/${keeperName2}.toml ${configDir}/${keeperName2}.toml.new
|
||||
${csudo}mv ${configDir}/keeper.toml ${configDir}/${keeperName2}.toml
|
||||
elif [ -f "${configDir}/${keeperName2}.toml" ]; then
|
||||
# "taoskeeper.toml exists,new config is taoskeeper.toml.new"
|
||||
${csudo}cp ${script_dir}/cfg/${keeperName2}.toml ${configDir}/${keeperName2}.toml.new
|
||||
else
|
||||
${csudo}cp ${script_dir}/cfg/${keeperName2}.toml ${configDir}/${keeperName2}.toml
|
||||
fi
|
||||
command -v systemctl >/dev/null 2>&1 && ${csudo}systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
function install_config() {
|
||||
|
||||
if [ ! -f "${cfg_install_dir}/${configFile2}" ]; then
|
||||
${csudo}mkdir -p ${cfg_install_dir}
|
||||
[ -f ${script_dir}/cfg/${configFile2} ] && ${csudo}cp ${script_dir}/cfg/${configFile2} ${cfg_install_dir}
|
||||
if [ -f ${script_dir}/cfg/${configFile2} ]; then
|
||||
${csudo} echo "monitor 1" >> ${script_dir}/cfg/${configFile2}
|
||||
${csudo} echo "monitorFQDN ${serverFqdn}" >> ${script_dir}/cfg/${configFile2}
|
||||
${csudo} echo "audit 1" >> ${script_dir}/cfg/${configFile2}
|
||||
${csudo}cp ${script_dir}/cfg/${configFile2} ${cfg_install_dir}
|
||||
fi
|
||||
${csudo}chmod 644 ${cfg_install_dir}/*
|
||||
else
|
||||
${csudo} echo "monitor 1" >> ${script_dir}/cfg/${configFile2}
|
||||
${csudo} echo "monitorFQDN ${serverFqdn}" >> ${script_dir}/cfg/${configFile2}
|
||||
${csudo} echo "audit 1" >> ${script_dir}/cfg/${configFile2}
|
||||
${csudo}cp -f ${script_dir}/cfg/${configFile2} ${cfg_install_dir}/${configFile2}.new
|
||||
fi
|
||||
|
||||
|
@ -537,6 +561,8 @@ function install_config() {
|
|||
|
||||
[ ! -z $1 ] && return 0 || : # only install client
|
||||
|
||||
|
||||
|
||||
if ((${update_flag} == 1)); then
|
||||
return 0
|
||||
fi
|
||||
|
@ -554,7 +580,11 @@ function install_config() {
|
|||
read firstEp
|
||||
while true; do
|
||||
if [ ! -z "$firstEp" ]; then
|
||||
if [ -f ${cfg_install_dir}/${configFile2} ]; then
|
||||
${csudo}sed -i -r "s/#*\s*(firstEp\s*).*/\1$firstEp/" ${cfg_install_dir}/${configFile2}
|
||||
else
|
||||
${csudo}sed -i -r "s/#*\s*(firstEp\s*).*/\1$firstEp/" ${script_dir}/cfg/${configFile2}
|
||||
fi
|
||||
break
|
||||
else
|
||||
break
|
||||
|
@ -607,6 +637,9 @@ function install_data() {
|
|||
function install_connector() {
|
||||
if [ -d "${script_dir}/connector/" ]; then
|
||||
${csudo}cp -rf ${script_dir}/connector/ ${install_main_dir}/ || echo "failed to copy connector"
|
||||
${csudo}cp ${script_dir}/start-all.sh ${install_main_dir}/ || echo "failed to copy start-all.sh"
|
||||
${csudo}cp ${script_dir}/stop-all.sh ${install_main_dir}/ || echo "failed to copy stop-all.sh"
|
||||
${csudo}cp ${script_dir}/README.md ${install_main_dir}/ || echo "failed to copy README.md"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -622,6 +655,14 @@ function install_web() {
|
|||
fi
|
||||
}
|
||||
|
||||
function install_taosx() {
|
||||
if [ -f "${script_dir}/taosx/install_taosx.sh" ]; then
|
||||
cd ${script_dir}/taosx
|
||||
chmod a+x install_taosx.sh
|
||||
bash install_taosx.sh -e $serverFqdn
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_service_on_sysvinit() {
|
||||
if ps aux | grep -v grep | grep ${serverName2} &>/dev/null; then
|
||||
${csudo}service ${serverName2} stop || :
|
||||
|
@ -702,29 +743,6 @@ function clean_service_on_systemd() {
|
|||
fi
|
||||
${csudo}systemctl disable tarbitratord &>/dev/null || echo &>/dev/null
|
||||
${csudo}rm -f ${tarbitratord_service_config}
|
||||
|
||||
if [ "$verMode" == "cluster" ] && [ "$clientName" != "$clientName2" ]; then
|
||||
x_service_config="${service_config_dir}/${xName2}.service"
|
||||
if [ -e "$x_service_config" ]; then
|
||||
if systemctl is-active --quiet ${xName2}; then
|
||||
echo "${productName2} ${xName2} is running, stopping it..."
|
||||
${csudo}systemctl stop ${xName2} &>/dev/null || echo &>/dev/null
|
||||
fi
|
||||
${csudo}systemctl disable ${xName2} &>/dev/null || echo &>/dev/null
|
||||
${csudo}rm -f ${x_service_config}
|
||||
fi
|
||||
|
||||
explorer_service_config="${service_config_dir}/${explorerName2}.service"
|
||||
if [ -e "$explorer_service_config" ]; then
|
||||
if systemctl is-active --quiet ${explorerName2}; then
|
||||
echo "${productName2} ${explorerName2} is running, stopping it..."
|
||||
${csudo}systemctl stop ${explorerName2} &>/dev/null || echo &>/dev/null
|
||||
fi
|
||||
${csudo}systemctl disable ${explorerName2} &>/dev/null || echo &>/dev/null
|
||||
${csudo}rm -f ${explorer_service_config}
|
||||
${csudo}rm -f /etc/${clientName2}/explorer.toml
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function install_service_on_systemd() {
|
||||
|
@ -745,15 +763,27 @@ function install_service_on_systemd() {
|
|||
${csudo}systemctl daemon-reload
|
||||
|
||||
${csudo}systemctl enable ${serverName2}
|
||||
|
||||
${csudo}systemctl daemon-reload
|
||||
}
|
||||
|
||||
function install_adapter_service() {
|
||||
if ((${service_mod} == 0)); then
|
||||
[ -f ${script_dir}/cfg/${adapterName}.service ] &&
|
||||
${csudo}cp ${script_dir}/cfg/${adapterName}.service \
|
||||
[ -f ${script_dir}/cfg/${adapterName2}.service ] &&
|
||||
${csudo}cp ${script_dir}/cfg/${adapterName2}.service \
|
||||
${service_config_dir}/ || :
|
||||
|
||||
${csudo}systemctl enable ${adapterName2}
|
||||
${csudo}systemctl daemon-reload
|
||||
fi
|
||||
}
|
||||
|
||||
function install_keeper_service() {
|
||||
if ((${service_mod} == 0)); then
|
||||
[ -f ${script_dir}/cfg/${clientName2}keeper.service ] &&
|
||||
${csudo}cp ${script_dir}/cfg/${clientName2}keeper.service \
|
||||
${service_config_dir}/ || :
|
||||
|
||||
${csudo}systemctl enable ${clientName2}keeper
|
||||
${csudo}systemctl daemon-reload
|
||||
fi
|
||||
}
|
||||
|
@ -872,7 +902,7 @@ function updateProduct() {
|
|||
tar -zxf ${tarName}
|
||||
install_jemalloc
|
||||
|
||||
echo -e "${GREEN}Start to update ${productName2}...${NC}"
|
||||
echo "Start to update ${productName2}..."
|
||||
# Stop the service if running
|
||||
if ps aux | grep -v grep | grep ${serverName2} &>/dev/null; then
|
||||
if ((${service_mod} == 0)); then
|
||||
|
@ -890,9 +920,11 @@ function updateProduct() {
|
|||
install_log
|
||||
install_header
|
||||
install_lib
|
||||
install_config
|
||||
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
install_connector
|
||||
install_taosx
|
||||
fi
|
||||
|
||||
install_examples
|
||||
|
@ -901,52 +933,69 @@ function updateProduct() {
|
|||
install_bin
|
||||
install_service
|
||||
install_adapter_service
|
||||
install_config
|
||||
install_adapter_config
|
||||
install_keeper_service
|
||||
install_keeper_config
|
||||
|
||||
openresty_work=false
|
||||
|
||||
echo
|
||||
echo -e "${GREEN_DARK}To configure ${productName2} ${NC}\t: edit ${cfg_install_dir}/${configFile2}"
|
||||
echo -e "${GREEN_DARK}To configure ${productName2} ${NC}\t\t: edit ${cfg_install_dir}/${configFile2}"
|
||||
[ -f ${configDir}/${clientName2}adapter.toml ] && [ -f ${installDir}/bin/${clientName2}adapter ] && \
|
||||
echo -e "${GREEN_DARK}To configure ${clientName2}Adapter ${NC}\t: edit ${configDir}/${clientName2}adapter.toml"
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
echo -e "${GREEN_DARK}To configure ${clientName2}-explorer ${NC}\t: edit ${configDir}/explorer.toml"
|
||||
fi
|
||||
if ((${service_mod} == 0)); then
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t: ${csudo}systemctl start ${serverName2}${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t\t: ${csudo}systemctl start ${serverName2}${NC}"
|
||||
[ -f ${service_config_dir}/${clientName2}adapter.service ] && [ -f ${installDir}/bin/${clientName2}adapter ] && \
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t: ${csudo}systemctl start ${clientName2}adapter ${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t\t: ${csudo}systemctl start ${clientName2}adapter ${NC}"
|
||||
elif ((${service_mod} == 1)); then
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t: ${csudo}service ${serverName2} start${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t\t: ${csudo}service ${serverName2} start${NC}"
|
||||
[ -f ${service_config_dir}/${clientName2}adapter.service ] && [ -f ${installDir}/bin/${clientName2}adapter ] && \
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t: ${csudo}service ${clientName2}adapter start${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t\t: ${csudo}service ${clientName2}adapter start${NC}"
|
||||
else
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t: ./${serverName2}${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t\t: ./${serverName2}${NC}"
|
||||
[ -f ${installDir}/bin/${clientName2}adapter ] && \
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t: ${clientName2}adapter ${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t\t: ${clientName2}adapter ${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN_DARK}To enable ${clientName2}keeper ${NC}\t: sudo systemctl enable ${clientName2}keeper ${NC}"
|
||||
|
||||
if [ ${openresty_work} = 'true' ]; then
|
||||
echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t: use ${GREEN_UNDERLINE}${clientName2} -h $serverFqdn${NC} in shell OR from ${GREEN_UNDERLINE}http://127.0.0.1:${web_port}${NC}"
|
||||
else
|
||||
echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t: use ${GREEN_UNDERLINE}${clientName2} -h $serverFqdn${NC} in shell${NC}"
|
||||
echo -e "${GREEN_DARK}To enable ${clientName2}keeper ${NC}\t\t: sudo systemctl enable ${clientName2}keeper ${NC}"
|
||||
if [ "$verMode" == "cluster" ];then
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}x ${NC}\t\t\t: sudo systemctl start ${clientName2}x ${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}-explorer ${NC}\t\t: sudo systemctl start ${clientName2}-explorer ${NC}"
|
||||
fi
|
||||
|
||||
if ((${prompt_force} == 1)); then
|
||||
echo ""
|
||||
echo -e "${RED}Please run '${serverName2} --force-keep-file' at first time for the exist ${productName2} $exist_version!${NC}"
|
||||
fi
|
||||
# if [ ${openresty_work} = 'true' ]; then
|
||||
# echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t\t: use ${GREEN_UNDERLINE}${clientName2} -h $serverFqdn${NC} in shell OR from ${GREEN_UNDERLINE}http://127.0.0.1:${web_port}${NC}"
|
||||
# else
|
||||
# echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t\t: use ${GREEN_UNDERLINE}${clientName2} -h $serverFqdn${NC} in shell${NC}"
|
||||
# fi
|
||||
|
||||
# if ((${prompt_force} == 1)); then
|
||||
# echo ""
|
||||
# echo -e "${RED}Please run '${serverName2} --force-keep-file' at first time for the exist ${productName2} $exist_version!${NC}"
|
||||
# fi
|
||||
|
||||
echo
|
||||
echo -e "\033[44;32;1m${productName2} is updated successfully!${NC}"
|
||||
echo -e "\033[44;32;1mTo manage ${productName2} instance, view documentation or explorer features, please install ${clientName2}Explorer ${NC}"
|
||||
echo "${productName2} is updated successfully!"
|
||||
echo
|
||||
if [ "$verMode" == "cluster" ];then
|
||||
echo -e "\033[44;32;1mTo start all the components : ./start-all.sh${NC}"
|
||||
fi
|
||||
echo -e "\033[44;32;1mTo access ${productName2} : ${clientName2} -h $serverFqdn${NC}"
|
||||
if [ "$verMode" == "cluster" ];then
|
||||
echo -e "\033[44;32;1mTo access the management system : http://$serverFqdn:6060${NC}"
|
||||
echo -e "\033[44;32;1mTo read the user manual : http://$serverFqdn:6060/docs${NC}"
|
||||
fi
|
||||
else
|
||||
install_bin
|
||||
install_config
|
||||
|
||||
echo
|
||||
echo -e "\033[44;32;1m${productName2} client is updated successfully!${NC}"
|
||||
fi
|
||||
|
||||
cd $script_dir
|
||||
rm -rf $(tar -tf ${tarName} | grep -Ev "^\./$|^\/")
|
||||
}
|
||||
|
||||
|
@ -958,7 +1007,7 @@ function installProduct() {
|
|||
fi
|
||||
tar -zxf ${tarName}
|
||||
|
||||
echo -e "${GREEN}Start to install ${productName2}...${NC}"
|
||||
echo "Start to install ${productName2}..."
|
||||
|
||||
install_main_path
|
||||
|
||||
|
@ -972,9 +1021,11 @@ function installProduct() {
|
|||
install_jemalloc
|
||||
#install_avro lib
|
||||
#install_avro lib64
|
||||
install_config
|
||||
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
install_connector
|
||||
install_taosx
|
||||
fi
|
||||
install_examples
|
||||
install_web
|
||||
|
@ -984,62 +1035,80 @@ function installProduct() {
|
|||
install_service
|
||||
install_adapter_service
|
||||
install_adapter_config
|
||||
install_keeper_service
|
||||
install_keeper_config
|
||||
|
||||
openresty_work=false
|
||||
|
||||
install_config
|
||||
|
||||
# Ask if to start the service
|
||||
echo
|
||||
echo -e "${GREEN_DARK}To configure ${productName2} ${NC}\t: edit ${cfg_install_dir}/${configFile2}"
|
||||
echo -e "${GREEN_DARK}To configure ${productName2} ${NC}\t\t: edit ${cfg_install_dir}/${configFile2}"
|
||||
[ -f ${configDir}/${clientName2}adapter.toml ] && [ -f ${installDir}/bin/${clientName2}adapter ] && \
|
||||
echo -e "${GREEN_DARK}To configure ${clientName2}Adapter ${NC}\t: edit ${configDir}/${clientName2}adapter.toml"
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
echo -e "${GREEN_DARK}To configure ${clientName2}-explorer ${NC}\t: edit ${configDir}/explorer.toml"
|
||||
fi
|
||||
if ((${service_mod} == 0)); then
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t: ${csudo}systemctl start ${serverName2}${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t\t: ${csudo}systemctl start ${serverName2}${NC}"
|
||||
[ -f ${service_config_dir}/${clientName2}adapter.service ] && [ -f ${installDir}/bin/${clientName2}adapter ] && \
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t: ${csudo}systemctl start ${clientName2}adapter ${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t\t: ${csudo}systemctl start ${clientName2}adapter ${NC}"
|
||||
elif ((${service_mod} == 1)); then
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t: ${csudo}service ${serverName2} start${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t\t: ${csudo}service ${serverName2} start${NC}"
|
||||
[ -f ${service_config_dir}/${clientName2}adapter.service ] && [ -f ${installDir}/bin/${clientName2}adapter ] && \
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t: ${csudo}service ${clientName2}adapter start${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t\t: ${csudo}service ${clientName2}adapter start${NC}"
|
||||
else
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t: ${serverName2}${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${productName2} ${NC}\t\t: ${serverName2}${NC}"
|
||||
[ -f ${installDir}/bin/${clientName2}adapter ] && \
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t: ${clientName2}adapter ${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}Adapter ${NC}\t\t: ${clientName2}adapter ${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN_DARK}To enable ${clientName2}keeper ${NC}\t: sudo systemctl enable ${clientName2}keeper ${NC}"
|
||||
echo -e "${GREEN_DARK}To enable ${clientName2}keeper ${NC}\t\t: sudo systemctl enable ${clientName2}keeper ${NC}"
|
||||
|
||||
if [ ! -z "$firstEp" ]; then
|
||||
tmpFqdn=${firstEp%%:*}
|
||||
substr=":"
|
||||
if [[ $firstEp =~ $substr ]]; then
|
||||
tmpPort=${firstEp#*:}
|
||||
else
|
||||
tmpPort=""
|
||||
if [ "$verMode" == "cluster" ];then
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}x ${NC}\t\t\t: sudo systemctl start ${clientName2}x ${NC}"
|
||||
echo -e "${GREEN_DARK}To start ${clientName2}-explorer ${NC}\t\t: sudo systemctl start ${clientName2}-explorer ${NC}"
|
||||
fi
|
||||
if [[ "$tmpPort" != "" ]]; then
|
||||
echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t: ${clientName2} -h $tmpFqdn -P $tmpPort${GREEN_DARK} to login into cluster, then${NC}"
|
||||
else
|
||||
echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t: ${clientName2} -h $tmpFqdn${GREEN_DARK} to login into cluster, then${NC}"
|
||||
fi
|
||||
echo -e "${GREEN_DARK}execute ${NC}: create dnode 'newDnodeFQDN:port'; ${GREEN_DARK}to add this new node${NC}"
|
||||
|
||||
# if [ ! -z "$firstEp" ]; then
|
||||
# tmpFqdn=${firstEp%%:*}
|
||||
# substr=":"
|
||||
# if [[ $firstEp =~ $substr ]]; then
|
||||
# tmpPort=${firstEp#*:}
|
||||
# else
|
||||
# tmpPort=""
|
||||
# fi
|
||||
# if [[ "$tmpPort" != "" ]]; then
|
||||
# echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t\t: ${clientName2} -h $tmpFqdn -P $tmpPort${GREEN_DARK} to login into cluster, then${NC}"
|
||||
# else
|
||||
# echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t\t: ${clientName2} -h $tmpFqdn${GREEN_DARK} to login into cluster, then${NC}"
|
||||
# fi
|
||||
# echo -e "${GREEN_DARK}execute ${NC}: create dnode 'newDnodeFQDN:port'; ${GREEN_DARK}to add this new node${NC}"
|
||||
# echo
|
||||
# elif [ ! -z "$serverFqdn" ]; then
|
||||
# echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t\t: ${clientName2} -h $serverFqdn${GREEN_DARK} to login into ${productName2} server${NC}"
|
||||
# echo
|
||||
# fi
|
||||
echo
|
||||
elif [ ! -z "$serverFqdn" ]; then
|
||||
echo -e "${GREEN_DARK}To access ${productName2} ${NC}\t: ${clientName2} -h $serverFqdn${GREEN_DARK} to login into ${productName2} server${NC}"
|
||||
echo "${productName2} is installed successfully!"
|
||||
echo
|
||||
if [ "$verMode" == "cluster" ];then
|
||||
echo -e "\033[44;32;1mTo start all the components : sudo ./start-all.sh${NC}"
|
||||
fi
|
||||
echo -e "\033[44;32;1mTo access ${productName2} : ${clientName2} -h $serverFqdn${NC}"
|
||||
if [ "$verMode" == "cluster" ];then
|
||||
echo -e "\033[44;32;1mTo access the management system : http://$serverFqdn:6060${NC}"
|
||||
echo -e "\033[44;32;1mTo read the user manual : http://$serverFqdn:6060/docs-en${NC}"
|
||||
fi
|
||||
|
||||
echo -e "\033[44;32;1m${productName2} is installed successfully!${NC}"
|
||||
echo -e "\033[44;32;1mTo manage ${productName2} instance, view documentation or explorer features, please install ${clientName2}Explorer ${NC}"
|
||||
echo
|
||||
else # Only install client
|
||||
install_bin
|
||||
install_config
|
||||
|
||||
echo
|
||||
echo -e "\033[44;32;1m${productName2} client is installed successfully!${NC}"
|
||||
fi
|
||||
|
||||
cd $script_dir
|
||||
touch ~/.${historyFile}
|
||||
rm -rf $(tar -tf ${tarName} | grep -Ev "^\./$|^\/")
|
||||
}
|
||||
|
@ -1071,3 +1140,5 @@ elif [ "$verType" == "client" ]; then
|
|||
else
|
||||
echo "please input correct verType"
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ function install_bin() {
|
|||
if [ "$osType" != "Darwin" ]; then
|
||||
[ -x ${install_main_dir}/bin/${demoName2} ] && ${csudo}ln -s ${install_main_dir}/bin/${demoName2} ${bin_link_dir}/${demoName2} || :
|
||||
[ -x ${install_main_dir}/bin/${benchmarkName2} ] && ${csudo}ln -s ${install_main_dir}/bin/${benchmarkName2} ${bin_link_dir}/${benchmarkName2} || :
|
||||
[ -x ${install_main_dir}/bin/${dumpName2} ] && ${csudo}ln -s ${install_main_dir}/bin/${dumpName2} ${bin_link_dir}/${dumpName2} || :
|
||||
fi
|
||||
[ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo}ln -sf ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/${uninstallScript2} || :
|
||||
fi
|
||||
|
|
|
@ -24,10 +24,12 @@ clientName2="${12}"
|
|||
productName="TDengine"
|
||||
clientName="taos"
|
||||
benchmarkName="taosBenchmark"
|
||||
dumpName="taosdump"
|
||||
configFile="taos.cfg"
|
||||
tarName="package.tar.gz"
|
||||
|
||||
benchmarkName2="${clientName2}Benchmark"
|
||||
dumpName2="${clientName2}dump"
|
||||
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
script_dir="$(dirname $(readlink -f $0))"
|
||||
|
@ -71,6 +73,7 @@ if [ "$osType" != "Darwin" ]; then
|
|||
else
|
||||
bin_files="${build_dir}/bin/${clientName} \
|
||||
${build_dir}/bin/${benchmarkName} \
|
||||
${build_dir}/bin/${dumpName} \
|
||||
${script_dir}/remove_client.sh \
|
||||
${script_dir}/set_core.sh \
|
||||
${script_dir}/get_client.sh"
|
||||
|
|
|
@ -42,7 +42,7 @@ release_dir="${top_dir}/release"
|
|||
|
||||
#package_name='linux'
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
install_dir="${release_dir}/${productName2}-enterprise-server-${version}"
|
||||
install_dir="${release_dir}/${productName2}-enterprise-${version}"
|
||||
elif [ "$verMode" == "cloud" ]; then
|
||||
install_dir="${release_dir}/${productName2}-cloud-server-${version}"
|
||||
else
|
||||
|
@ -92,14 +92,10 @@ else
|
|||
${build_dir}/bin/tdengine-datasource.zip.md5"
|
||||
fi
|
||||
|
||||
[ -f ${build_dir}/bin/taosx ] && taosx_bin="${build_dir}/bin/taosx"
|
||||
explorer_bin_files=$(find ${build_dir}/bin/ -name '*-explorer')
|
||||
|
||||
bin_files="${build_dir}/bin/${serverName} \
|
||||
${build_dir}/bin/${clientName} \
|
||||
${taostools_bin_files} \
|
||||
${taosx_bin} \
|
||||
${explorer_bin_files} \
|
||||
${build_dir}/bin/${clientName}adapter \
|
||||
${build_dir}/bin/udfd \
|
||||
${script_dir}/remove.sh \
|
||||
|
@ -285,6 +281,11 @@ fi
|
|||
chmod a+x ${install_dir}/install.sh
|
||||
|
||||
if [[ $dbName == "taos" ]]; then
|
||||
cp ${top_dir}/../enterprise/packaging/start-all.sh ${install_dir}
|
||||
cp ${top_dir}/../enterprise/packaging/stop-all.sh ${install_dir}
|
||||
cp ${top_dir}/../enterprise/packaging/README.md ${install_dir}
|
||||
chmod a+x ${install_dir}/start-all.sh
|
||||
chmod a+x ${install_dir}/stop-all.sh
|
||||
# Copy example code
|
||||
mkdir -p ${install_dir}/examples
|
||||
examples_dir="${top_dir}/examples"
|
||||
|
@ -330,7 +331,7 @@ fi
|
|||
mkdir -p ${install_dir}/driver && cp ${lib_files} ${install_dir}/driver && echo "${versionComp}" >${install_dir}/driver/vercomp.txt
|
||||
[ -f ${wslib_files} ] && cp ${wslib_files} ${install_dir}/driver || :
|
||||
|
||||
# Copy connector
|
||||
# Copy connector && taosx
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
connector_dir="${code_dir}/connector"
|
||||
mkdir -p ${install_dir}/connector
|
||||
|
@ -364,8 +365,13 @@ if [ "$verMode" == "cluster" ]; then
|
|||
git clone --depth 1 https://github.com/taosdata/taos-connector-rust ${install_dir}/connector/rust
|
||||
rm -rf ${install_dir}/connector/rust/.git ||:
|
||||
|
||||
# cp -r ${connector_dir}/python ${install_dir}/connector
|
||||
# cp -r ${connector_dir}/nodejs ${install_dir}/connector
|
||||
# copy taosx
|
||||
if [ -d ${top_dir}/../enterprise/src/plugins/taosx/release/taosx ]; then
|
||||
cp -r ${top_dir}/../enterprise/src/plugins/taosx/release/taosx ${install_dir}
|
||||
cp ${top_dir}/../enterprise/packaging/install_taosx.sh ${install_dir}/taosx
|
||||
cp ${top_dir}/../enterprise/src/plugins/taosx/packaging/uninstall.sh ${install_dir}/taosx
|
||||
sed -i 's/target=\"\"/target=\"taosx\"/g' ${install_dir}/taosx/uninstall.sh
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
@ -63,6 +63,10 @@ service_config_dir="/etc/systemd/system"
|
|||
taos_service_name=${serverName2}
|
||||
taosadapter_service_name="${clientName2}adapter"
|
||||
tarbitrator_service_name="tarbitratord"
|
||||
|
||||
config_dir="/etc/${clientName2}"
|
||||
|
||||
|
||||
csudo=""
|
||||
if command -v sudo >/dev/null; then
|
||||
csudo="sudo "
|
||||
|
@ -113,8 +117,10 @@ function clean_bin() {
|
|||
# Remove link
|
||||
${csudo}rm -f ${bin_link_dir}/${clientName} || :
|
||||
${csudo}rm -f ${bin_link_dir}/${serverName} || :
|
||||
echo "${serverName} is removed successfully"
|
||||
${csudo}rm -f ${bin_link_dir}/udfd || :
|
||||
${csudo}rm -f ${bin_link_dir}/${adapterName2} || :
|
||||
echo "${adapterName2} is removed successfully"
|
||||
${csudo}rm -f ${bin_link_dir}/${benchmarkName2} || :
|
||||
${csudo}rm -f ${bin_link_dir}/${demoName2} || :
|
||||
${csudo}rm -f ${bin_link_dir}/${dumpName2} || :
|
||||
|
@ -175,7 +181,7 @@ function clean_log() {
|
|||
function clean_service_on_systemd() {
|
||||
taosd_service_config="${service_config_dir}/${taos_service_name}.service"
|
||||
if systemctl is-active --quiet ${taos_service_name}; then
|
||||
echo "${productName2} ${serverName2} is running, stopping it..."
|
||||
echo "${taos_service_name} is running, stopping it..."
|
||||
${csudo}systemctl stop ${taos_service_name} &>/dev/null || echo &>/dev/null
|
||||
fi
|
||||
${csudo}systemctl disable ${taos_service_name} &>/dev/null || echo &>/dev/null
|
||||
|
@ -183,7 +189,7 @@ function clean_service_on_systemd() {
|
|||
|
||||
taosadapter_service_config="${service_config_dir}/${clientName2}adapter.service"
|
||||
if systemctl is-active --quiet ${taosadapter_service_name}; then
|
||||
echo "${productName2} ${clientName2}Adapter is running, stopping it..."
|
||||
echo "${clientName2}Adapter is running, stopping it..."
|
||||
${csudo}systemctl stop ${taosadapter_service_name} &>/dev/null || echo &>/dev/null
|
||||
fi
|
||||
${csudo}systemctl disable ${taosadapter_service_name} &>/dev/null || echo &>/dev/null
|
||||
|
@ -196,33 +202,11 @@ function clean_service_on_systemd() {
|
|||
fi
|
||||
${csudo}systemctl disable ${tarbitrator_service_name} &>/dev/null || echo &>/dev/null
|
||||
|
||||
if [ "$verMode" == "cluster" ] && [ "$clientName" != "$clientName2" ]; then
|
||||
x_service_config="${service_config_dir}/${xName2}.service"
|
||||
if [ -e "$x_service_config" ]; then
|
||||
if systemctl is-active --quiet ${xName2}; then
|
||||
echo "${productName2} ${xName2} is running, stopping it..."
|
||||
${csudo}systemctl stop ${xName2} &>/dev/null || echo &>/dev/null
|
||||
fi
|
||||
${csudo}systemctl disable ${xName2} &>/dev/null || echo &>/dev/null
|
||||
${csudo}rm -f ${x_service_config}
|
||||
fi
|
||||
|
||||
explorer_service_config="${service_config_dir}/${explorerName2}.service"
|
||||
if [ -e "$explorer_service_config" ]; then
|
||||
if systemctl is-active --quiet ${explorerName2}; then
|
||||
echo "${productName2} ${explorerName2} is running, stopping it..."
|
||||
${csudo}systemctl stop ${explorerName2} &>/dev/null || echo &>/dev/null
|
||||
fi
|
||||
${csudo}systemctl disable ${explorerName2} &>/dev/null || echo &>/dev/null
|
||||
${csudo}rm -f ${explorer_service_config}
|
||||
${csudo}rm -f /etc/${clientName2}/explorer.toml
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_service_on_sysvinit() {
|
||||
if ps aux | grep -v grep | grep ${serverName} &>/dev/null; then
|
||||
echo "${productName2} ${serverName2} is running, stopping it..."
|
||||
echo "${serverName2} is running, stopping it..."
|
||||
${csudo}service ${serverName} stop || :
|
||||
fi
|
||||
|
||||
|
@ -284,6 +268,97 @@ function clean_service() {
|
|||
fi
|
||||
}
|
||||
|
||||
function remove_data_and_config() {
|
||||
data_dir=`grep dataDir /etc/taos/taos.cfg | grep -v '#' | tail -n 1 | awk {'print $2'}`
|
||||
if [ X"$data_dir" == X"" ]; then
|
||||
data_dir="/var/lib/taos"
|
||||
fi
|
||||
log_dir=`grep logDir /etc/taos/taos.cfg | grep -v '#' | tail -n 1 | awk {'print $2'}`
|
||||
if [ X"$log_dir" == X"" ]; then
|
||||
log_dir="/var/log/taos"
|
||||
fi
|
||||
[ -d "${config_dir}" ] && ${csudo}rm -rf ${config_dir}/*
|
||||
[ -d "${data_dir}" ] && ${csudo}rm -rf ${data_dir}/*
|
||||
[ -d "${log_dir}" ] && ${csudo}rm -rf ${log_dir}/*
|
||||
}
|
||||
|
||||
_kill_service_of() {
|
||||
_service=$1
|
||||
pid=$(ps -ef | grep "$_service" | grep -v "grep" | awk '{print $2}')
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo}kill -9 $pid || :
|
||||
fi
|
||||
}
|
||||
|
||||
_clean_service_on_systemd_of() {
|
||||
_service=$1
|
||||
_service_config="${service_config_dir}/${_service}.service"
|
||||
if systemctl is-active --quiet ${_service}; then
|
||||
echo "taoskeeper is running, stopping it..."
|
||||
${csudo}systemctl stop ${_service} &>/dev/null || echo &>/dev/null
|
||||
fi
|
||||
${csudo}systemctl disable ${_service} &>/dev/null || echo &>/dev/null
|
||||
${csudo}rm -f ${_service_config}
|
||||
}
|
||||
_clean_service_on_sysvinit_of() {
|
||||
_service=$1
|
||||
if pidof ${_service} &>/dev/null; then
|
||||
echo "${_service} is running, stopping it..."
|
||||
${csudo}service ${_service} stop || :
|
||||
fi
|
||||
if ((${initd_mod} == 1)); then
|
||||
if [ -e ${service_config_dir}/${_service} ]; then
|
||||
${csudo}chkconfig --del ${_service} || :
|
||||
fi
|
||||
elif ((${initd_mod} == 2)); then
|
||||
if [ -e ${service_config_dir}/${_service} ]; then
|
||||
${csudo}insserv -r ${_service} || :
|
||||
fi
|
||||
elif ((${initd_mod} == 3)); then
|
||||
if [ -e ${service_config_dir}/${_service} ]; then
|
||||
${csudo}update-rc.d -f ${_service} remove || :
|
||||
fi
|
||||
fi
|
||||
|
||||
${csudo}rm -f ${service_config_dir}/${_service} || :
|
||||
|
||||
if $(which init &>/dev/null); then
|
||||
${csudo}init q || :
|
||||
fi
|
||||
}
|
||||
|
||||
_clean_service_of() {
|
||||
_service=$1
|
||||
if ((${service_mod} == 0)); then
|
||||
_clean_service_on_systemd_of $_service
|
||||
elif ((${service_mod} == 1)); then
|
||||
_clean_service_on_sysvinit_of $_service
|
||||
else
|
||||
_kill_service_of $_service
|
||||
fi
|
||||
}
|
||||
|
||||
remove_taoskeeper() {
|
||||
# remove taoskeeper bin
|
||||
_clean_service_of taoskeeper
|
||||
[ -e "${bin_link_dir}/taoskeeper" ] && ${csudo}rm -rf ${bin_link_dir}/taoskeeper
|
||||
[ -e "${installDir}/taoskeeper" ] && ${csudo}rm -rf ${installDir}/taoskeeper
|
||||
[ -e "${cfg_link_dir}/metrics.toml" ] || ${csudo}rm -rf ${cfg_link_dir}/metrics.toml
|
||||
echo "taosKeeper is removed successfully!"
|
||||
}
|
||||
|
||||
function uninstall_taosx() {
|
||||
if [ -f ${installDir}/uninstall.sh ]; then
|
||||
cd ${installDir}
|
||||
bash uninstall.sh
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
uninstall_taosx
|
||||
fi
|
||||
|
||||
remove_taoskeeper
|
||||
# Stop service and disable booting start.
|
||||
clean_service
|
||||
# Remove binary file and links
|
||||
|
@ -322,5 +397,13 @@ if [ "$osType" = "Darwin" ]; then
|
|||
${csudo}rm -rf /Applications/TDengine.app
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}${productName2} is removed successfully!${NC}"
|
||||
echo
|
||||
echo "Do you want to remove all the data, log and configuration files? [y/n]"
|
||||
read answer
|
||||
if [ X$answer == X"y" ] || [ X$answer == X"Y" ]; then
|
||||
remove_data_and_config
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "${productName2} is removed successfully!"
|
||||
echo
|
||||
|
|
|
@ -776,7 +776,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) {
|
|||
} else {
|
||||
tscInfo("set cfg:%s to %s", pItem->name, str);
|
||||
if (TSDB_OPTION_SHELL_ACTIVITY_TIMER == option || TSDB_OPTION_USE_ADAPTER == option) {
|
||||
code = taosApplyLocalCfg(pCfg, pItem->name);
|
||||
code = taosCfgDynamicOptions(pCfg, pItem->name, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ static char* processCreateStb(SMqMetaRsp* metaRsp) {
|
|||
goto _err;
|
||||
}
|
||||
string = buildCreateTableJson(&req.schemaRow, &req.schemaTag, req.name, req.suid, TSDB_SUPER_TABLE);
|
||||
_err:
|
||||
_err:
|
||||
uDebug("create stable return, sql json:%s", string);
|
||||
tDecoderClear(&coder);
|
||||
return string;
|
||||
|
@ -224,7 +224,7 @@ static char* processAlterStb(SMqMetaRsp* metaRsp) {
|
|||
goto _err;
|
||||
}
|
||||
string = buildAlterSTableJson(req.alterOriData, req.alterOriDataLen);
|
||||
_err:
|
||||
_err:
|
||||
uDebug("alter stable return, sql json:%s", string);
|
||||
tDecoderClear(&coder);
|
||||
return string;
|
||||
|
@ -375,7 +375,7 @@ static char* processCreateTable(SMqMetaRsp* metaRsp) {
|
|||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
uDebug("create table return, sql json:%s", string);
|
||||
for (int32_t iReq = 0; iReq < req.nReqs; iReq++) {
|
||||
pCreateReq = req.pReqs + iReq;
|
||||
|
@ -416,7 +416,7 @@ static char* processAutoCreateTable(STaosxRsp* rsp) {
|
|||
}
|
||||
}
|
||||
string = buildCreateCTableJson(pCreateReq, rsp->createTableNum);
|
||||
_exit:
|
||||
_exit:
|
||||
uDebug("auto created table return, sql json:%s", string);
|
||||
for (int i = 0; i < rsp->createTableNum; i++) {
|
||||
tDecoderClear(&decoder[i]);
|
||||
|
@ -549,7 +549,7 @@ static char* processAlterTable(SMqMetaRsp* metaRsp) {
|
|||
}
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
uDebug("alter table return, sql json:%s", string);
|
||||
cJSON_Delete(json);
|
||||
tDecoderClear(&decoder);
|
||||
|
@ -585,7 +585,7 @@ static char* processDropSTable(SMqMetaRsp* metaRsp) {
|
|||
cJSON_AddItemToObject(json, "tableName", tableName);
|
||||
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
_exit:
|
||||
_exit:
|
||||
uDebug("processDropSTable return, sql json:%s", string);
|
||||
cJSON_Delete(json);
|
||||
tDecoderClear(&decoder);
|
||||
|
@ -624,7 +624,7 @@ static char* processDeleteTable(SMqMetaRsp* metaRsp) {
|
|||
cJSON_AddItemToObject(json, "sql", sqlJson);
|
||||
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
_exit:
|
||||
_exit:
|
||||
uDebug("processDeleteTable return, sql json:%s", string);
|
||||
cJSON_Delete(json);
|
||||
tDecoderClear(&coder);
|
||||
|
@ -669,7 +669,7 @@ static char* processDropTable(SMqMetaRsp* metaRsp) {
|
|||
cJSON_AddItemToObject(json, "tableNameList", tableNameList);
|
||||
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
_exit:
|
||||
_exit:
|
||||
uDebug("processDropTable return, json sql:%s", string);
|
||||
cJSON_Delete(json);
|
||||
tDecoderClear(&decoder);
|
||||
|
@ -765,7 +765,7 @@ static int32_t taosCreateStb(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
code = pRequest->code;
|
||||
taosMemoryFree(pCmdMsg.pMsg);
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG" create stable return, msg:%s", LOG_ID_VALUE, tstrerror(code));
|
||||
destroyRequest(pRequest);
|
||||
tFreeSMCreateStbReq(&pReq);
|
||||
|
@ -869,7 +869,7 @@ static int32_t taosDropStb(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
code = pRequest->code;
|
||||
taosMemoryFree(pCmdMsg.pMsg);
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG" drop stable return, msg:%s", LOG_ID_VALUE, tstrerror(code));
|
||||
destroyRequest(pRequest);
|
||||
tDecoderClear(&coder);
|
||||
|
@ -1023,7 +1023,7 @@ static int32_t taosCreateTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG" create table return, msg:%s", LOG_ID_VALUE, tstrerror(code));
|
||||
for (int32_t iReq = 0; iReq < req.nReqs; iReq++) {
|
||||
pCreateReq = req.pReqs + iReq;
|
||||
|
@ -1175,7 +1175,7 @@ static int32_t taosDropTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
}
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG" drop table return, msg:%s", LOG_ID_VALUE, tstrerror(code));
|
||||
taosHashCleanup(pVgroupHashmap);
|
||||
destroyRequest(pRequest);
|
||||
|
@ -1250,7 +1250,7 @@ static int32_t taosDeleteData(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
}
|
||||
taos_free_result(res);
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug("connId:0x%"PRIx64" delete data sql:%s, code:%s", *(int64_t*)taos, sql, tstrerror(code));
|
||||
tDecoderClear(&coder);
|
||||
terrno = code;
|
||||
|
@ -1368,7 +1368,7 @@ static int32_t taosAlterTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
code = handleAlterTbExecRes(pRes->res, pCatalog);
|
||||
}
|
||||
}
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG " alter table return, meta:%p, len:%d, msg:%s", LOG_ID_VALUE, meta, metaLen, tstrerror(code));
|
||||
taosArrayDestroy(pArray);
|
||||
if (pVgData) taosMemoryFreeClear(pVgData->pData);
|
||||
|
@ -1459,7 +1459,7 @@ int taos_write_raw_block_with_fields_with_reqid(TAOS *taos, int rows, char *pDat
|
|||
launchQueryImpl(pRequest, pQuery, true, NULL);
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG " write raw block with field return, msg:%s", LOG_ID_VALUE, tstrerror(code));
|
||||
taosMemoryFreeClear(pTableMeta);
|
||||
qDestroyQuery(pQuery);
|
||||
|
@ -1543,7 +1543,7 @@ int taos_write_raw_block_with_reqid(TAOS* taos, int rows, char* pData, const cha
|
|||
launchQueryImpl(pRequest, pQuery, true, NULL);
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG " write raw block return, msg:%s", LOG_ID_VALUE, tstrerror(code));
|
||||
taosMemoryFreeClear(pTableMeta);
|
||||
qDestroyQuery(pQuery);
|
||||
|
@ -1669,7 +1669,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) {
|
|||
launchQueryImpl(pRequest, pQuery, true, NULL);
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG " write raw data return, msg:%s", LOG_ID_VALUE, tstrerror(code));
|
||||
tDeleteMqDataRsp(&rspObj.rsp);
|
||||
tDecoderClear(&decoder);
|
||||
|
@ -1841,7 +1841,7 @@ static int32_t tmqWriteRawMetaDataImpl(TAOS* taos, void* data, int32_t dataLen)
|
|||
launchQueryImpl(pRequest, pQuery, true, NULL);
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
uDebug(LOG_ID_TAG " write raw metadata return, msg:%s", LOG_ID_VALUE, tstrerror(code));
|
||||
tDeleteSTaosxRsp(&rspObj.rsp);
|
||||
tDecoderClear(&decoder);
|
||||
|
@ -1984,7 +1984,7 @@ int32_t tmq_write_raw(TAOS* taos, tmq_raw_data raw) {
|
|||
return tmqWriteRawMetaDataImpl(taos, raw.raw, raw.raw_len);
|
||||
}
|
||||
|
||||
end:
|
||||
end:
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return terrno;
|
||||
}
|
||||
|
|
|
@ -267,8 +267,6 @@ typedef struct list_parts_callback_data {
|
|||
} list_parts_callback_data;
|
||||
|
||||
typedef struct MultipartPartData {
|
||||
char err_msg[512];
|
||||
S3Status status;
|
||||
put_object_callback_data put_object_data;
|
||||
int seq;
|
||||
UploadManager *manager;
|
||||
|
@ -276,11 +274,12 @@ typedef struct MultipartPartData {
|
|||
|
||||
static int putObjectDataCallback(int bufferSize, char *buffer, void *callbackData) {
|
||||
put_object_callback_data *data = (put_object_callback_data *)callbackData;
|
||||
/*
|
||||
if (data->infileFD == 0) {
|
||||
MultipartPartData *mpd = (MultipartPartData *)callbackData;
|
||||
data = &mpd->put_object_data;
|
||||
}
|
||||
|
||||
*/
|
||||
int ret = 0;
|
||||
|
||||
if (data->contentLength) {
|
||||
|
@ -458,13 +457,13 @@ int32_t s3PutObjectFromFile2(const char *file, const char *object) {
|
|||
int metaPropertiesCount = 0;
|
||||
S3NameValue metaProperties[S3_MAX_METADATA_COUNT];
|
||||
char useServerSideEncryption = 0;
|
||||
int noStatus = 0;
|
||||
put_object_callback_data data;
|
||||
put_object_callback_data data = {0};
|
||||
// int noStatus = 0;
|
||||
|
||||
// data.infile = 0;
|
||||
data.infileFD = NULL;
|
||||
data.gb = 0;
|
||||
data.noStatus = noStatus;
|
||||
// data.gb = 0;
|
||||
// data.infileFD = NULL;
|
||||
// data.noStatus = noStatus;
|
||||
|
||||
if (taosStatFile(file, &contentLength, NULL, NULL) < 0) {
|
||||
uError("ERROR: %s Failed to stat file %s: ", __func__, file);
|
||||
|
@ -498,12 +497,6 @@ int32_t s3PutObjectFromFile2(const char *file, const char *object) {
|
|||
S3_put_object(&bucketContext, key, contentLength, &putProperties, 0, 0, &putObjectHandler, &data);
|
||||
} while (S3_status_is_retryable(data.status) && should_retry());
|
||||
|
||||
if (data.infileFD) {
|
||||
taosCloseFile(&data.infileFD);
|
||||
} else if (data.gb) {
|
||||
growbuffer_destroy(data.gb);
|
||||
}
|
||||
|
||||
if (data.status != S3StatusOK) {
|
||||
s3PrintError(__func__, data.status, data.err_msg);
|
||||
code = TAOS_SYSTEM_ERROR(EIO);
|
||||
|
@ -521,8 +514,13 @@ int32_t s3PutObjectFromFile2(const char *file, const char *object) {
|
|||
|
||||
// div round up
|
||||
int seq;
|
||||
uint64_t chunk_size = MULTIPART_CHUNK_SIZE >> 8;
|
||||
int totalSeq = ((contentLength + chunk_size - 1) / chunk_size);
|
||||
uint64_t chunk_size = MULTIPART_CHUNK_SIZE >> 7;
|
||||
int totalSeq = (contentLength + chunk_size - 1) / chunk_size;
|
||||
const int max_part_num = 1000;
|
||||
if (totalSeq > max_part_num) {
|
||||
chunk_size = (contentLength + max_part_num - contentLength % max_part_num) / max_part_num;
|
||||
totalSeq = (contentLength + chunk_size - 1) / chunk_size;
|
||||
}
|
||||
|
||||
MultipartPartData partData;
|
||||
memset(&partData, 0, sizeof(MultipartPartData));
|
||||
|
@ -581,9 +579,9 @@ int32_t s3PutObjectFromFile2(const char *file, const char *object) {
|
|||
do {
|
||||
S3_upload_part(&bucketContext, key, &putProperties, &putObjectHandler, seq, manager.upload_id,
|
||||
partContentLength, 0, timeoutMsG, &partData);
|
||||
} while (S3_status_is_retryable(partData.status) && should_retry());
|
||||
if (partData.status != S3StatusOK) {
|
||||
s3PrintError(__func__, partData.status, partData.err_msg);
|
||||
} while (S3_status_is_retryable(partData.put_object_data.status) && should_retry());
|
||||
if (partData.put_object_data.status != S3StatusOK) {
|
||||
s3PrintError(__func__, partData.put_object_data.status, partData.put_object_data.err_msg);
|
||||
code = TAOS_SYSTEM_ERROR(EIO);
|
||||
goto clean;
|
||||
}
|
||||
|
@ -627,6 +625,12 @@ int32_t s3PutObjectFromFile2(const char *file, const char *object) {
|
|||
taosMemoryFree(manager.etags);
|
||||
}
|
||||
|
||||
if (data.infileFD) {
|
||||
taosCloseFile(&data.infileFD);
|
||||
} else if (data.gb) {
|
||||
growbuffer_destroy(data.gb);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -720,6 +724,8 @@ static SArray *getListByPrefix(const char *prefix) {
|
|||
} else {
|
||||
s3PrintError(__func__, data.status, data.err_msg);
|
||||
}
|
||||
|
||||
taosArrayDestroyEx(data.objectArray, s3FreeObjectKey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -2121,6 +2121,7 @@ _end:
|
|||
char* buildCtbNameByGroupId(const char* stbFullName, uint64_t groupId) {
|
||||
char* pBuf = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN + 1);
|
||||
if (!pBuf) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
int32_t code = buildCtbNameByGroupIdImpl(stbFullName, groupId, pBuf);
|
||||
|
@ -2133,6 +2134,7 @@ char* buildCtbNameByGroupId(const char* stbFullName, uint64_t groupId) {
|
|||
|
||||
int32_t buildCtbNameByGroupIdImpl(const char* stbFullName, uint64_t groupId, char* cname) {
|
||||
if (stbFullName[0] == 0) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -2142,6 +2144,7 @@ int32_t buildCtbNameByGroupIdImpl(const char* stbFullName, uint64_t groupId, cha
|
|||
}
|
||||
|
||||
if (cname == NULL) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
taosArrayDestroy(tags);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "tgrant.h"
|
||||
#include "tlog.h"
|
||||
#include "tmisce.h"
|
||||
#include "tunit.h"
|
||||
|
||||
#if defined(CUS_NAME) || defined(CUS_PROMPT) || defined(CUS_EMAIL)
|
||||
#include "cus_name.h"
|
||||
|
@ -277,7 +278,7 @@ char tsS3Hostname[TSDB_FQDN_LEN] = "<hostname>";
|
|||
int32_t tsS3BlockSize = -1; // number of tsdb pages (4096)
|
||||
int32_t tsS3BlockCacheSize = 16; // number of blocks
|
||||
int32_t tsS3PageCacheSize = 4096; // number of pages
|
||||
int32_t tsS3UploadDelaySec = 60 * 60;
|
||||
int32_t tsS3UploadDelaySec = 60 * 60 * 24;
|
||||
|
||||
#ifndef _STORAGE
|
||||
int32_t taosSetTfsCfg(SConfig *pCfg) {
|
||||
|
@ -506,8 +507,8 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
|
|||
|
||||
tsNumOfTaskQueueThreads = tsNumOfCores / 2;
|
||||
tsNumOfTaskQueueThreads = TMAX(tsNumOfTaskQueueThreads, 4);
|
||||
if (tsNumOfTaskQueueThreads >= 10) {
|
||||
tsNumOfTaskQueueThreads = 10;
|
||||
if (tsNumOfTaskQueueThreads >= 50) {
|
||||
tsNumOfTaskQueueThreads = 50;
|
||||
}
|
||||
if (cfgAddInt32(pCfg, "numOfTaskQueueThreads", tsNumOfTaskQueueThreads, 4, 1024, CFG_SCOPE_CLIENT, CFG_DYN_NONE) != 0)
|
||||
return -1;
|
||||
|
@ -610,7 +611,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
0)
|
||||
return -1;
|
||||
|
||||
tsNumOfVnodeRsmaThreads = tsNumOfCores / 2;
|
||||
tsNumOfVnodeRsmaThreads = tsNumOfCores / 4;
|
||||
tsNumOfVnodeRsmaThreads = TMAX(tsNumOfVnodeRsmaThreads, 4);
|
||||
if (cfgAddInt32(pCfg, "numOfVnodeRsmaThreads", tsNumOfVnodeRsmaThreads, 1, 1024, CFG_SCOPE_SERVER, CFG_DYN_NONE) != 0)
|
||||
return -1;
|
||||
|
@ -721,7 +722,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddBool(pCfg, "disableStream", tsDisableStream, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) != 0) return -1;
|
||||
if (cfgAddInt64(pCfg, "streamBufferSize", tsStreamBufferSize, 0, INT64_MAX, CFG_SCOPE_SERVER, CFG_DYN_NONE) != 0)
|
||||
return -1;
|
||||
if (cfgAddInt64(pCfg, "checkpointInterval", tsStreamCheckpointInterval, 60, 1200, CFG_SCOPE_SERVER,
|
||||
if (cfgAddInt32(pCfg, "checkpointInterval", tsStreamCheckpointInterval, 60, 1200, CFG_SCOPE_SERVER,
|
||||
CFG_DYN_ENT_SERVER) != 0)
|
||||
return -1;
|
||||
if (cfgAddFloat(pCfg, "streamSinkDataRate", tsSinkDataRate, 0.1, 5, CFG_SCOPE_SERVER, CFG_DYN_NONE) != 0) return -1;
|
||||
|
@ -752,6 +753,10 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddString(pCfg, "s3BucketName", tsS3BucketName, CFG_SCOPE_SERVER, CFG_DYN_NONE) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "s3BlockSize", tsS3BlockSize, -1, 1024 * 1024, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) != 0)
|
||||
return -1;
|
||||
if (tsS3BlockSize > -1 && tsS3BlockSize < 1024) {
|
||||
uError("failed to config s3blocksize since value:%d. Valid range: -1 or [1024, 1024 * 1024]", tsS3BlockSize);
|
||||
return -1;
|
||||
}
|
||||
if (cfgAddInt32(pCfg, "s3BlockCacheSize", tsS3BlockCacheSize, 4, 1024 * 1024, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) !=
|
||||
0)
|
||||
return -1;
|
||||
|
@ -1194,302 +1199,6 @@ static int32_t taosSetReleaseCfg(SConfig *pCfg) { return 0; }
|
|||
int32_t taosSetReleaseCfg(SConfig *pCfg);
|
||||
#endif
|
||||
|
||||
int32_t taosApplyLocalCfg(SConfig *pCfg, char *name) {
|
||||
int32_t len = strlen(name);
|
||||
char lowcaseName[CFG_NAME_MAX_LEN + 1] = {0};
|
||||
strntolower(lowcaseName, name, TMIN(CFG_NAME_MAX_LEN, len));
|
||||
bool matchItem = true;
|
||||
|
||||
switch (lowcaseName[0]) {
|
||||
case 'a': {
|
||||
if (strcasecmp("asyncLog", name) == 0) {
|
||||
tsAsyncLog = cfgGetItem(pCfg, "asyncLog")->bval;
|
||||
} else if (strcasecmp("assert", name) == 0) {
|
||||
tsAssert = cfgGetItem(pCfg, "assert")->bval;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
if (strcasecmp("compressMsgSize", name) == 0) {
|
||||
tsCompressMsgSize = cfgGetItem(pCfg, "compressMsgSize")->i32;
|
||||
} else if (strcasecmp("countAlwaysReturnValue", name) == 0) {
|
||||
tsCountAlwaysReturnValue = cfgGetItem(pCfg, "countAlwaysReturnValue")->i32;
|
||||
} else if (strcasecmp("cDebugFlag", name) == 0) {
|
||||
cDebugFlag = cfgGetItem(pCfg, "cDebugFlag")->i32;
|
||||
} else if (strcasecmp("crashReporting", name) == 0) {
|
||||
tsEnableCrashReport = cfgGetItem(pCfg, "crashReporting")->bval;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
if (strcasecmp("dDebugFlag", name) == 0) {
|
||||
dDebugFlag = cfgGetItem(pCfg, "dDebugFlag")->i32;
|
||||
} else if (strcasecmp("debugFlag", name) == 0) {
|
||||
int32_t flag = cfgGetItem(pCfg, "debugFlag")->i32;
|
||||
taosSetAllDebugFlag(flag, true);
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'e': {
|
||||
if (strcasecmp("enableCoreFile", name) == 0) {
|
||||
bool enableCore = cfgGetItem(pCfg, "enableCoreFile")->bval;
|
||||
taosSetCoreDump(enableCore);
|
||||
} else if (strcasecmp("enableQueryHb", name) == 0) {
|
||||
tsEnableQueryHb = cfgGetItem(pCfg, "enableQueryHb")->bval;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'f': {
|
||||
if (strcasecmp("fqdn", name) == 0) {
|
||||
tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN);
|
||||
tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32;
|
||||
snprintf(tsLocalEp, sizeof(tsLocalEp), "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
char defaultFirstEp[TSDB_EP_LEN] = {0};
|
||||
snprintf(defaultFirstEp, TSDB_EP_LEN, "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
SConfigItem *pFirstEpItem = cfgGetItem(pCfg, "firstEp");
|
||||
SEp firstEp = {0};
|
||||
taosGetFqdnPortFromEp(strlen(pFirstEpItem->str) == 0 ? defaultFirstEp : pFirstEpItem->str, &firstEp);
|
||||
snprintf(tsFirst, sizeof(tsFirst), "%s:%u", firstEp.fqdn, firstEp.port);
|
||||
cfgSetItem(pCfg, "firstEp", tsFirst, pFirstEpItem->stype);
|
||||
} else if (strcasecmp("firstEp", name) == 0) {
|
||||
tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN);
|
||||
tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32;
|
||||
snprintf(tsLocalEp, sizeof(tsLocalEp), "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
char defaultFirstEp[TSDB_EP_LEN] = {0};
|
||||
snprintf(defaultFirstEp, TSDB_EP_LEN, "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
SConfigItem *pFirstEpItem = cfgGetItem(pCfg, "firstEp");
|
||||
SEp firstEp = {0};
|
||||
taosGetFqdnPortFromEp(strlen(pFirstEpItem->str) == 0 ? defaultFirstEp : pFirstEpItem->str, &firstEp);
|
||||
snprintf(tsFirst, sizeof(tsFirst), "%s:%u", firstEp.fqdn, firstEp.port);
|
||||
cfgSetItem(pCfg, "firstEp", tsFirst, pFirstEpItem->stype);
|
||||
} else if (strcasecmp("fsDebugFlag", name) == 0) {
|
||||
fsDebugFlag = cfgGetItem(pCfg, "fsDebugFlag")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
if (strcasecmp("idxDebugFlag", name) == 0) {
|
||||
idxDebugFlag = cfgGetItem(pCfg, "idxDebugFlag")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'j': {
|
||||
if (strcasecmp("jniDebugFlag", name) == 0) {
|
||||
jniDebugFlag = cfgGetItem(pCfg, "jniDebugFlag")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'k': {
|
||||
if (strcasecmp("keepColumnName", name) == 0) {
|
||||
tsKeepColumnName = cfgGetItem(pCfg, "keepColumnName")->bval;
|
||||
} else if (strcasecmp("keepAliveIdle", name) == 0) {
|
||||
tsKeepAliveIdle = cfgGetItem(pCfg, "keepAliveIdle")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
if (strcasecmp("locale", name) == 0) {
|
||||
const char *locale = cfgGetItem(pCfg, "locale")->str;
|
||||
const char *charset = cfgGetItem(pCfg, "charset")->str;
|
||||
taosSetSystemLocale(locale, charset);
|
||||
osSetSystemLocale(locale, charset);
|
||||
} else if (strcasecmp("logDir", name) == 0) {
|
||||
tstrncpy(tsLogDir, cfgGetItem(pCfg, "logDir")->str, PATH_MAX);
|
||||
taosExpandDir(tsLogDir, tsLogDir, PATH_MAX);
|
||||
} else if (strcasecmp("logKeepDays", name) == 0) {
|
||||
tsLogKeepDays = cfgGetItem(pCfg, "logKeepDays")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'm': {
|
||||
switch (lowcaseName[1]) {
|
||||
case 'a': {
|
||||
if (strcasecmp("maxInsertBatchRows", name) == 0) {
|
||||
tsMaxInsertBatchRows = cfgGetItem(pCfg, "maxInsertBatchRows")->i32;
|
||||
} else if (strcasecmp("maxRetryWaitTime", name) == 0) {
|
||||
tsMaxRetryWaitTime = cfgGetItem(pCfg, "maxRetryWaitTime")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'e': {
|
||||
if (strcasecmp("metaCacheMaxSize", name) == 0) {
|
||||
atomic_store_32(&tsMetaCacheMaxSize, cfgGetItem(pCfg, "metaCacheMaxSize")->i32);
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
if (strcasecmp("minimalTmpDirGB", name) == 0) {
|
||||
tsTempSpace.reserved = (int64_t)(((double)cfgGetItem(pCfg, "minimalTmpDirGB")->fval) * 1024 * 1024 * 1024);
|
||||
} else if (strcasecmp("minimalDataDirGB", name) == 0) {
|
||||
tsDataSpace.reserved = (int64_t)(((double)cfgGetItem(pCfg, "minimalDataDirGB")->fval) * 1024 * 1024 * 1024);
|
||||
} else if (strcasecmp("minSlidingTime", name) == 0) {
|
||||
tsMinSlidingTime = cfgGetItem(pCfg, "minSlidingTime")->i32;
|
||||
} else if (strcasecmp("minIntervalTime", name) == 0) {
|
||||
tsMinIntervalTime = cfgGetItem(pCfg, "minIntervalTime")->i32;
|
||||
} else if (strcasecmp("minimalLogDirGB", name) == 0) {
|
||||
tsLogSpace.reserved = (int64_t)(((double)cfgGetItem(pCfg, "minimalLogDirGB")->fval) * 1024 * 1024 * 1024);
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
terrno = TSDB_CODE_CFG_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
if (strcasecmp("numOfLogLines", name) == 0) {
|
||||
tsNumOfLogLines = cfgGetItem(pCfg, "numOfLogLines")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'q': {
|
||||
if (strcasecmp("querySmaOptimize", name) == 0) {
|
||||
tsQuerySmaOptimize = cfgGetItem(pCfg, "querySmaOptimize")->i32;
|
||||
} else if (strcasecmp("queryPolicy", name) == 0) {
|
||||
tsQueryPolicy = cfgGetItem(pCfg, "queryPolicy")->i32;
|
||||
} else if (strcasecmp("qDebugFlag", name) == 0) {
|
||||
qDebugFlag = cfgGetItem(pCfg, "qDebugFlag")->i32;
|
||||
} else if (strcasecmp("queryPlannerTrace", name) == 0) {
|
||||
tsQueryPlannerTrace = cfgGetItem(pCfg, "queryPlannerTrace")->bval;
|
||||
} else if (strcasecmp("queryNodeChunkSize", name) == 0) {
|
||||
tsQueryNodeChunkSize = cfgGetItem(pCfg, "queryNodeChunkSize")->i32;
|
||||
} else if (strcasecmp("queryUseNodeAllocator", name) == 0) {
|
||||
tsQueryUseNodeAllocator = cfgGetItem(pCfg, "queryUseNodeAllocator")->bval;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'r': {
|
||||
if (strcasecmp("rpcDebugFlag", name) == 0) {
|
||||
rpcDebugFlag = cfgGetItem(pCfg, "rpcDebugFlag")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
if (strcasecmp("secondEp", name) == 0) {
|
||||
SConfigItem *pSecondpItem = cfgGetItem(pCfg, "secondEp");
|
||||
SEp secondEp = {0};
|
||||
taosGetFqdnPortFromEp(strlen(pSecondpItem->str) == 0 ? tsFirst : pSecondpItem->str, &secondEp);
|
||||
snprintf(tsSecond, sizeof(tsSecond), "%s:%u", secondEp.fqdn, secondEp.port);
|
||||
cfgSetItem(pCfg, "secondEp", tsSecond, pSecondpItem->stype);
|
||||
} else if (strcasecmp("smlChildTableName", name) == 0) {
|
||||
tstrncpy(tsSmlChildTableName, cfgGetItem(pCfg, "smlChildTableName")->str, TSDB_TABLE_NAME_LEN);
|
||||
} else if (strcasecmp("smlAutoChildTableNameDelimiter", name) == 0) {
|
||||
tstrncpy(tsSmlAutoChildTableNameDelimiter, cfgGetItem(pCfg, "smlAutoChildTableNameDelimiter")->str,
|
||||
TSDB_TABLE_NAME_LEN);
|
||||
} else if (strcasecmp("smlTagName", name) == 0) {
|
||||
tstrncpy(tsSmlTagName, cfgGetItem(pCfg, "smlTagName")->str, TSDB_COL_NAME_LEN);
|
||||
// } else if (strcasecmp("smlDataFormat", name) == 0) {
|
||||
// tsSmlDataFormat = cfgGetItem(pCfg, "smlDataFormat")->bval;
|
||||
// } else if (strcasecmp("smlBatchSize", name) == 0) {
|
||||
// tsSmlBatchSize = cfgGetItem(pCfg, "smlBatchSize")->i32;
|
||||
} else if (strcasecmp("smlTsDefaultName", name) == 0) {
|
||||
tstrncpy(tsSmlTsDefaultName, cfgGetItem(pCfg, "smlTsDefaultName")->str, TSDB_COL_NAME_LEN);
|
||||
} else if (strcasecmp("smlDot2Underline", name) == 0) {
|
||||
tsSmlDot2Underline = cfgGetItem(pCfg, "smlDot2Underline")->bval;
|
||||
} else if (strcasecmp("shellActivityTimer", name) == 0) {
|
||||
tsShellActivityTimer = cfgGetItem(pCfg, "shellActivityTimer")->i32;
|
||||
} else if (strcasecmp("serverPort", name) == 0) {
|
||||
tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN);
|
||||
tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32;
|
||||
snprintf(tsLocalEp, sizeof(tsLocalEp), "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
char defaultFirstEp[TSDB_EP_LEN] = {0};
|
||||
snprintf(defaultFirstEp, TSDB_EP_LEN, "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
SConfigItem *pFirstEpItem = cfgGetItem(pCfg, "firstEp");
|
||||
SEp firstEp = {0};
|
||||
taosGetFqdnPortFromEp(strlen(pFirstEpItem->str) == 0 ? defaultFirstEp : pFirstEpItem->str, &firstEp);
|
||||
snprintf(tsFirst, sizeof(tsFirst), "%s:%u", firstEp.fqdn, firstEp.port);
|
||||
cfgSetItem(pCfg, "firstEp", tsFirst, pFirstEpItem->stype);
|
||||
} else if (strcasecmp("smaDebugFlag", name) == 0) {
|
||||
smaDebugFlag = cfgGetItem(pCfg, "smaDebugFlag")->i32;
|
||||
} else if (strcasecmp("slowLogThreshold", name) == 0) {
|
||||
tsSlowLogThreshold = cfgGetItem(pCfg, "slowLogThreshold")->i32;
|
||||
} else if (strcasecmp("slowLogScope", name) == 0) {
|
||||
if (taosSetSlowLogScope(cfgGetItem(pCfg, "slowLogScope")->str)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
if (strcasecmp("timezone", name) == 0) {
|
||||
SConfigItem *pItem = cfgGetItem(pCfg, "timezone");
|
||||
osSetTimezone(pItem->str);
|
||||
uDebug("timezone format changed from %s to %s", pItem->str, tsTimezoneStr);
|
||||
cfgSetItem(pCfg, "timezone", tsTimezoneStr, pItem->stype);
|
||||
} else if (strcasecmp("tempDir", name) == 0) {
|
||||
tstrncpy(tsTempDir, cfgGetItem(pCfg, "tempDir")->str, PATH_MAX);
|
||||
taosExpandDir(tsTempDir, tsTempDir, PATH_MAX);
|
||||
if (taosMulMkDir(tsTempDir) != 0) {
|
||||
uError("failed to create tempDir:%s since %s", tsTempDir, terrstr());
|
||||
return -1;
|
||||
}
|
||||
} else if (strcasecmp("telemetryServer", name) == 0) {
|
||||
tstrncpy(tsTelemServer, cfgGetItem(pCfg, "telemetryServer")->str, TSDB_FQDN_LEN);
|
||||
} else if (strcasecmp("tmrDebugFlag", name) == 0) {
|
||||
tmrDebugFlag = cfgGetItem(pCfg, "tmrDebugFlag")->i32;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
if (strcasecmp("uDebugFlag", name) == 0) {
|
||||
uDebugFlag = cfgGetItem(pCfg, "uDebugFlag")->i32;
|
||||
} else if (strcasecmp("useAdapter", name) == 0) {
|
||||
tsUseAdapter = cfgGetItem(pCfg, "useAdapter")->bval;
|
||||
} else {
|
||||
matchItem = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
terrno = TSDB_CODE_CFG_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!matchItem) terrno = TSDB_CODE_CFG_NOT_FOUND;
|
||||
return matchItem ? 0 : -1;
|
||||
}
|
||||
|
||||
int32_t taosCreateLog(const char *logname, int32_t logFileNum, const char *cfgDir, const char **envCmd,
|
||||
const char *envFile, char *apolloUrl, SArray *pArgs, bool tsc) {
|
||||
if (tsCfg == NULL) osDefaultInit();
|
||||
|
@ -1627,48 +1336,98 @@ void taosCleanupCfg() {
|
|||
tsCfg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *optionName;
|
||||
void *optionVar;
|
||||
} OptionNameAndVar;
|
||||
|
||||
void taosCfgDynamicOptions(const char *option, const char *value) {
|
||||
if (strncasecmp(option, "debugFlag", 9) == 0) {
|
||||
int32_t flag = atoi(value);
|
||||
taosSetAllDebugFlag(flag, true);
|
||||
return;
|
||||
static int32_t taosCfgSetOption(OptionNameAndVar *pOptions, int32_t optionSize, SConfigItem *pItem, bool isDebugflag) {
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
char *name = pItem->name;
|
||||
for (int32_t d = 0; d < optionSize; ++d) {
|
||||
const char *optName = pOptions[d].optionName;
|
||||
int32_t optLen = strlen(optName);
|
||||
if (strncasecmp(name, optName, optLen) != 0) continue;
|
||||
switch (pItem->dtype) {
|
||||
case CFG_DTYPE_BOOL: {
|
||||
int32_t flag = pItem->i32;
|
||||
bool *pVar = pOptions[d].optionVar;
|
||||
uInfo("%s set from %d to %d", optName, *pVar, flag);
|
||||
*pVar = flag;
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
case CFG_DTYPE_INT32: {
|
||||
int32_t flag = pItem->i32;
|
||||
int32_t *pVar = pOptions[d].optionVar;
|
||||
uInfo("%s set from %d to %d", optName, *pVar, flag);
|
||||
*pVar = flag;
|
||||
|
||||
if (isDebugflag) {
|
||||
taosSetDebugFlag(pOptions[d].optionVar, optName, flag, true);
|
||||
}
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
case CFG_DTYPE_INT64: {
|
||||
int64_t flag = pItem->i64;
|
||||
int64_t *pVar = pOptions[d].optionVar;
|
||||
uInfo("%s set from %" PRId64 " to %" PRId64, optName, *pVar, flag);
|
||||
*pVar = flag;
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
case CFG_DTYPE_FLOAT:
|
||||
case CFG_DTYPE_DOUBLE: {
|
||||
float flag = pItem->fval;
|
||||
float *pVar = pOptions[d].optionVar;
|
||||
uInfo("%s set from %f to %f", optName, *pVar, flag);
|
||||
*pVar = flag;
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
default:
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcasecmp(option, "resetlog") == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
|
||||
}
|
||||
|
||||
static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) {
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||
if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) {
|
||||
uError("failed to config:%s, not support", name);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncasecmp(name, "debugFlag", 9) == 0) {
|
||||
int32_t flag = pItem->i32;
|
||||
taosSetAllDebugFlag(flag, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcasecmp(name, "resetlog") == 0) {
|
||||
taosResetLog();
|
||||
cfgDumpCfg(tsCfg, 0, false);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
{ // 'bool/int32_t/int64_t' variables with general modification function
|
||||
const int32_t nDebugFlag = 20;
|
||||
static OptionNameAndVar options[] = {
|
||||
{"dDebugFlag", &dDebugFlag},
|
||||
{"vDebugFlag", &vDebugFlag},
|
||||
{"mDebugFlag", &mDebugFlag},
|
||||
{"wDebugFlag", &wDebugFlag},
|
||||
{"sDebugFlag", &sDebugFlag},
|
||||
{"tsdbDebugFlag", &tsdbDebugFlag},
|
||||
{"tqDebugFlag", &tqDebugFlag},
|
||||
{"fsDebugFlag", &fsDebugFlag},
|
||||
{"udfDebugFlag", &udfDebugFlag},
|
||||
{"smaDebugFlag", &smaDebugFlag},
|
||||
{"idxDebugFlag", &idxDebugFlag},
|
||||
{"tdbDebugFlag", &tdbDebugFlag},
|
||||
{"tmrDebugFlag", &tmrDebugFlag},
|
||||
{"uDebugFlag", &uDebugFlag},
|
||||
{"smaDebugFlag", &smaDebugFlag},
|
||||
{"rpcDebugFlag", &rpcDebugFlag},
|
||||
{"qDebugFlag", &qDebugFlag},
|
||||
{"metaDebugFlag", &metaDebugFlag},
|
||||
{"jniDebugFlag", &jniDebugFlag},
|
||||
{"stDebugFlag", &stDebugFlag},
|
||||
{ // 'bool/int32_t/int64_t/float/double' variables with general modification function
|
||||
static OptionNameAndVar debugOptions[] = {
|
||||
{"dDebugFlag", &dDebugFlag}, {"vDebugFlag", &vDebugFlag}, {"mDebugFlag", &mDebugFlag},
|
||||
{"wDebugFlag", &wDebugFlag}, {"sDebugFlag", &sDebugFlag}, {"tsdbDebugFlag", &tsdbDebugFlag},
|
||||
{"tqDebugFlag", &tqDebugFlag}, {"fsDebugFlag", &fsDebugFlag}, {"udfDebugFlag", &udfDebugFlag},
|
||||
{"smaDebugFlag", &smaDebugFlag}, {"idxDebugFlag", &idxDebugFlag}, {"tdbDebugFlag", &tdbDebugFlag},
|
||||
{"tmrDebugFlag", &tmrDebugFlag}, {"uDebugFlag", &uDebugFlag}, {"smaDebugFlag", &smaDebugFlag},
|
||||
{"rpcDebugFlag", &rpcDebugFlag}, {"qDebugFlag", &qDebugFlag}, {"metaDebugFlag", &metaDebugFlag},
|
||||
{"jniDebugFlag", &jniDebugFlag}, {"stDebugFlag", &stDebugFlag},
|
||||
};
|
||||
|
||||
static OptionNameAndVar options[] = {
|
||||
{"audit", &tsEnableAudit},
|
||||
{"asynclog", &tsAsyncLog},
|
||||
{"disableStream", &tsDisableStream},
|
||||
|
@ -1701,54 +1460,241 @@ void taosCfgDynamicOptions(const char *option, const char *value) {
|
|||
{"supportVnodes", &tsNumOfSupportVnodes},
|
||||
};
|
||||
|
||||
int32_t optionSize = tListLen(options);
|
||||
for (int32_t d = 0; d < optionSize; ++d) {
|
||||
const char *optName = options[d].optionName;
|
||||
int32_t optLen = strlen(optName);
|
||||
if (strncasecmp(option, optName, optLen) != 0) continue;
|
||||
if (taosCfgSetOption(debugOptions, tListLen(debugOptions), pItem, true) != 0) {
|
||||
taosCfgSetOption(options, tListLen(options), pItem, false);
|
||||
}
|
||||
}
|
||||
|
||||
SConfig *pCfg = taosGetCfg();
|
||||
SConfigItem *pItem = NULL;
|
||||
return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
|
||||
}
|
||||
|
||||
pItem = cfgGetItem(pCfg, optName);
|
||||
if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) {
|
||||
uError("failed to config:%s, not support", optName);
|
||||
static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) {
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||
if (!pItem || (pItem->dynScope & CFG_DYN_CLIENT) == 0) {
|
||||
uError("failed to config:%s, not support", name);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool matched = false;
|
||||
|
||||
int32_t len = strlen(name);
|
||||
char lowcaseName[CFG_NAME_MAX_LEN + 1] = {0};
|
||||
strntolower(lowcaseName, name, TMIN(CFG_NAME_MAX_LEN, len));
|
||||
switch (lowcaseName[0]) {
|
||||
case 'd': {
|
||||
if (strcasecmp("debugFlag", name) == 0) {
|
||||
int32_t flag = pItem->i32;
|
||||
taosSetAllDebugFlag(flag, true);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pItem->dtype) {
|
||||
case CFG_DTYPE_BOOL: {
|
||||
int32_t flag = atoi(value);
|
||||
bool *pVar = options[d].optionVar;
|
||||
uInfo("%s set from %d to %d", optName, *pVar, flag);
|
||||
*pVar = flag;
|
||||
} break;
|
||||
case CFG_DTYPE_INT32: {
|
||||
int32_t flag = atoi(value);
|
||||
int32_t *pVar = options[d].optionVar;
|
||||
uInfo("%s set from %d to %d", optName, *pVar, flag);
|
||||
*pVar = flag;
|
||||
|
||||
if (d < nDebugFlag) {
|
||||
// debug flags
|
||||
taosSetDebugFlag(options[d].optionVar, optName, flag, true);
|
||||
case 'e': {
|
||||
if (strcasecmp("enableCoreFile", name) == 0) {
|
||||
bool enableCore = pItem->bval;
|
||||
taosSetCoreDump(enableCore);
|
||||
uInfo("%s set to %d", name, enableCore);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'f': {
|
||||
if (strcasecmp("fqdn", name) == 0) {
|
||||
tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN);
|
||||
tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32;
|
||||
snprintf(tsLocalEp, sizeof(tsLocalEp), "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
char defaultFirstEp[TSDB_EP_LEN] = {0};
|
||||
snprintf(defaultFirstEp, TSDB_EP_LEN, "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
SConfigItem *pFirstEpItem = cfgGetItem(pCfg, "firstEp");
|
||||
SEp firstEp = {0};
|
||||
taosGetFqdnPortFromEp(strlen(pFirstEpItem->str) == 0 ? defaultFirstEp : pFirstEpItem->str, &firstEp);
|
||||
snprintf(tsFirst, sizeof(tsFirst), "%s:%u", firstEp.fqdn, firstEp.port);
|
||||
cfgSetItem(pCfg, "firstEp", tsFirst, pFirstEpItem->stype);
|
||||
uInfo("localEp set to '%s', tsFirst set to '%s'", tsLocalEp, tsFirst);
|
||||
matched = true;
|
||||
} else if (strcasecmp("firstEp", name) == 0) {
|
||||
tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN);
|
||||
tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32;
|
||||
snprintf(tsLocalEp, sizeof(tsLocalEp), "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
char defaultFirstEp[TSDB_EP_LEN] = {0};
|
||||
snprintf(defaultFirstEp, TSDB_EP_LEN, "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
SConfigItem *pFirstEpItem = cfgGetItem(pCfg, "firstEp");
|
||||
SEp firstEp = {0};
|
||||
taosGetFqdnPortFromEp(strlen(pFirstEpItem->str) == 0 ? defaultFirstEp : pFirstEpItem->str, &firstEp);
|
||||
snprintf(tsFirst, sizeof(tsFirst), "%s:%u", firstEp.fqdn, firstEp.port);
|
||||
cfgSetItem(pCfg, "firstEp", tsFirst, pFirstEpItem->stype);
|
||||
uInfo("localEp set to '%s', tsFirst set to '%s'", tsLocalEp, tsFirst);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
if (strcasecmp("locale", name) == 0) {
|
||||
const char *locale = cfgGetItem(pCfg, "locale")->str;
|
||||
const char *charset = cfgGetItem(pCfg, "charset")->str;
|
||||
taosSetSystemLocale(locale, charset);
|
||||
osSetSystemLocale(locale, charset);
|
||||
uInfo("locale set to '%s', charset set to '%s'", locale, charset);
|
||||
matched = true;
|
||||
} else if (strcasecmp("logDir", name) == 0) {
|
||||
uInfo("%s set from '%s' to '%s'", name, tsLogDir, pItem->str);
|
||||
tstrncpy(tsLogDir, pItem->str, PATH_MAX);
|
||||
taosExpandDir(tsLogDir, tsLogDir, PATH_MAX);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'm': {
|
||||
if (strcasecmp("metaCacheMaxSize", name) == 0) {
|
||||
atomic_store_32(&tsMetaCacheMaxSize, pItem->i32);
|
||||
uInfo("%s set to %d", name, atomic_load_32(&tsMetaCacheMaxSize));
|
||||
matched = true;
|
||||
} else if (strcasecmp("minimalTmpDirGB", name) == 0) {
|
||||
tsTempSpace.reserved = (int64_t)(((double)pItem->fval) * 1024 * 1024 * 1024);
|
||||
uInfo("%s set to %" PRId64, name, tsTempSpace.reserved);
|
||||
matched = true;
|
||||
} else if (strcasecmp("minimalDataDirGB", name) == 0) {
|
||||
tsDataSpace.reserved = (int64_t)(((double)pItem->fval) * 1024 * 1024 * 1024);
|
||||
uInfo("%s set to %" PRId64, name, tsDataSpace.reserved);
|
||||
matched = true;
|
||||
} else if (strcasecmp("minimalLogDirGB", name) == 0) {
|
||||
tsLogSpace.reserved = (int64_t)(((double)pItem->fval) * 1024 * 1024 * 1024);
|
||||
uInfo("%s set to %" PRId64, name, tsLogSpace.reserved);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
if (strcasecmp("secondEp", name) == 0) {
|
||||
SEp secondEp = {0};
|
||||
taosGetFqdnPortFromEp(strlen(pItem->str) == 0 ? tsFirst : pItem->str, &secondEp);
|
||||
snprintf(tsSecond, sizeof(tsSecond), "%s:%u", secondEp.fqdn, secondEp.port);
|
||||
cfgSetItem(pCfg, "secondEp", tsSecond, pItem->stype);
|
||||
uInfo("%s set to %s", name, tsSecond);
|
||||
matched = true;
|
||||
} else if (strcasecmp("smlChildTableName", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, tsSmlChildTableName, pItem->str);
|
||||
tstrncpy(tsSmlChildTableName, pItem->str, TSDB_TABLE_NAME_LEN);
|
||||
matched = true;
|
||||
} else if (strcasecmp("smlAutoChildTableNameDelimiter", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, tsSmlAutoChildTableNameDelimiter, pItem->str);
|
||||
tstrncpy(tsSmlAutoChildTableNameDelimiter, pItem->str, TSDB_TABLE_NAME_LEN);
|
||||
matched = true;
|
||||
} else if (strcasecmp("smlTagName", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, tsSmlTagName, pItem->str);
|
||||
tstrncpy(tsSmlTagName, pItem->str, TSDB_COL_NAME_LEN);
|
||||
matched = true;
|
||||
} else if (strcasecmp("smlTsDefaultName", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, tsSmlTsDefaultName, pItem->str);
|
||||
tstrncpy(tsSmlTsDefaultName, pItem->str, TSDB_COL_NAME_LEN);
|
||||
matched = true;
|
||||
} else if (strcasecmp("serverPort", name) == 0) {
|
||||
tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN);
|
||||
tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32;
|
||||
snprintf(tsLocalEp, sizeof(tsLocalEp), "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
char defaultFirstEp[TSDB_EP_LEN] = {0};
|
||||
snprintf(defaultFirstEp, TSDB_EP_LEN, "%s:%u", tsLocalFqdn, tsServerPort);
|
||||
|
||||
SConfigItem *pFirstEpItem = cfgGetItem(pCfg, "firstEp");
|
||||
SEp firstEp = {0};
|
||||
taosGetFqdnPortFromEp(strlen(pFirstEpItem->str) == 0 ? defaultFirstEp : pFirstEpItem->str, &firstEp);
|
||||
snprintf(tsFirst, sizeof(tsFirst), "%s:%u", firstEp.fqdn, firstEp.port);
|
||||
cfgSetItem(pCfg, "firstEp", tsFirst, pFirstEpItem->stype);
|
||||
uInfo("localEp set to '%s', tsFirst set to '%s'", tsLocalEp, tsFirst);
|
||||
matched = true;
|
||||
} else if (strcasecmp("slowLogScope", name) == 0) {
|
||||
if (taosSetSlowLogScope(pItem->str)) {
|
||||
return -1;
|
||||
}
|
||||
uInfo("%s set to %s", name, pItem->str);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
if (strcasecmp("timezone", name) == 0) {
|
||||
osSetTimezone(pItem->str);
|
||||
uInfo("%s set from %s to %s", name, tsTimezoneStr, pItem->str);
|
||||
cfgSetItem(pCfg, "timezone", tsTimezoneStr, pItem->stype);
|
||||
matched = true;
|
||||
} else if (strcasecmp("tempDir", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, tsTempDir, pItem->str);
|
||||
tstrncpy(tsTempDir, pItem->str, PATH_MAX);
|
||||
taosExpandDir(tsTempDir, tsTempDir, PATH_MAX);
|
||||
if (taosMulMkDir(tsTempDir) != 0) {
|
||||
uError("failed to create tempDir:%s since %s", tsTempDir, terrstr());
|
||||
return -1;
|
||||
}
|
||||
matched = true;
|
||||
} else if (strcasecmp("telemetryServer", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, pItem->str, tsTelemServer);
|
||||
tstrncpy(tsTelemServer, pItem->str, TSDB_FQDN_LEN);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case CFG_DTYPE_INT64: {
|
||||
int64_t flag = atoll(value);
|
||||
int64_t *pVar = options[d].optionVar;
|
||||
uInfo("%s set from %" PRId64 " to %" PRId64, optName, *pVar, flag);
|
||||
*pVar = flag;
|
||||
} break;
|
||||
default:
|
||||
terrno = TSDB_CODE_CFG_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
if (matched) goto _out;
|
||||
|
||||
{ // 'bool/int32_t/int64_t/float/double' variables with general modification function
|
||||
static OptionNameAndVar debugOptions[] = {
|
||||
{"cDebugFlag", &cDebugFlag}, {"dDebugFlag", &dDebugFlag}, {"fsDebugFlag", &fsDebugFlag},
|
||||
{"idxDebugFlag", &idxDebugFlag}, {"jniDebugFlag", &jniDebugFlag}, {"qDebugFlag", &qDebugFlag},
|
||||
{"rpcDebugFlag", &rpcDebugFlag}, {"smaDebugFlag", &smaDebugFlag}, {"tmrDebugFlag", &tmrDebugFlag},
|
||||
{"uDebugFlag", &uDebugFlag},
|
||||
};
|
||||
|
||||
static OptionNameAndVar options[] = {
|
||||
{"asyncLog", &tsAsyncLog},
|
||||
{"assert", &tsAssert},
|
||||
{"compressMsgSize", &tsCompressMsgSize},
|
||||
{"countAlwaysReturnValue", &tsCountAlwaysReturnValue},
|
||||
{"crashReporting", &tsEnableCrashReport},
|
||||
{"enableCoreFile", &tsAsyncLog},
|
||||
{"enableQueryHb", &tsEnableQueryHb},
|
||||
{"keepColumnName", &tsKeepColumnName},
|
||||
{"keepAliveIdle", &tsKeepAliveIdle},
|
||||
{"logKeepDays", &tsLogKeepDays},
|
||||
{"maxInsertBatchRows", &tsMaxInsertBatchRows},
|
||||
{"maxRetryWaitTime", &tsMaxRetryWaitTime},
|
||||
{"minSlidingTime", &tsMinSlidingTime},
|
||||
{"minIntervalTime", &tsMinIntervalTime},
|
||||
{"numOfLogLines", &tsNumOfLogLines},
|
||||
{"querySmaOptimize", &tsQuerySmaOptimize},
|
||||
{"queryPolicy", &tsQueryPolicy},
|
||||
{"queryPlannerTrace", &tsQueryPlannerTrace},
|
||||
{"queryNodeChunkSize", &tsQueryNodeChunkSize},
|
||||
{"queryUseNodeAllocator", &tsQueryUseNodeAllocator},
|
||||
{"smlDot2Underline", &tsSmlDot2Underline},
|
||||
{"shellActivityTimer", &tsShellActivityTimer},
|
||||
{"slowLogThreshold", &tsSlowLogThreshold},
|
||||
{"useAdapter", &tsUseAdapter},
|
||||
};
|
||||
|
||||
if (taosCfgSetOption(debugOptions, tListLen(debugOptions), pItem, true) != 0) {
|
||||
taosCfgSetOption(options, tListLen(options), pItem, false);
|
||||
}
|
||||
}
|
||||
|
||||
uError("failed to cfg dynamic option:%s value:%s", option, value);
|
||||
_out:
|
||||
return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
|
||||
}
|
||||
|
||||
int32_t taosCfgDynamicOptions(SConfig *pCfg, char *name, bool forServer) {
|
||||
if (forServer) return taosCfgDynamicOptionsForServer(pCfg, name);
|
||||
return taosCfgDynamicOptionsForClient(pCfg, name);
|
||||
}
|
||||
|
||||
void taosSetDebugFlag(int32_t *pFlagPtr, const char *flagName, int32_t flagVal, bool rewrite) {
|
||||
|
|
|
@ -8337,6 +8337,7 @@ int32_t tEncodeSBatchDeleteReq(SEncoder *pEncoder, const SBatchDeleteReq *pReq)
|
|||
if (tEncodeSSingleDeleteReq(pEncoder, pOneReq) < 0) return -1;
|
||||
}
|
||||
if (tEncodeI64(pEncoder, pReq->ctimeMs) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pReq->level) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -8361,6 +8362,9 @@ int32_t tDecodeSBatchDeleteReq(SDecoder *pDecoder, SBatchDeleteReq *pReq) {
|
|||
if (!tDecodeIsEnd(pDecoder)) {
|
||||
if (tDecodeI64(pDecoder, &pReq->ctimeMs) < 0) return -1;
|
||||
}
|
||||
if (!tDecodeIsEnd(pDecoder)) {
|
||||
if (tDecodeI8(pDecoder, &pReq->level) < 0) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -296,7 +296,10 @@ static int compareKv(const void* p1, const void* p2) {
|
|||
void buildChildTableName(RandTableName* rName) {
|
||||
SStringBuilder sb = {0};
|
||||
taosStringBuilderAppendStringLen(&sb, rName->stbFullName, rName->stbFullNameLen);
|
||||
if (sb.buf == NULL) return;
|
||||
if (sb.buf == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
taosArraySort(rName->tags, compareKv);
|
||||
for (int j = 0; j < taosArrayGetSize(rName->tags); ++j) {
|
||||
taosStringBuilderAppendChar(&sb, ',');
|
||||
|
|
|
@ -194,6 +194,14 @@ int32_t parseTimezone(char* str, int64_t* tzOffset) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t offsetOfTimezone(char* tzStr, int64_t* offset) {
|
||||
if (tzStr && (tzStr[0] == 'z' || tzStr[0] == 'Z')) {
|
||||
*offset = 0;
|
||||
return 0;
|
||||
}
|
||||
return parseTimezone(tzStr, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* rfc3339 format:
|
||||
* 2013-04-12T15:52:01+08:00
|
||||
|
|
|
@ -218,7 +218,10 @@ int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
dInfo("start to config, option:%s, value:%s", cfgReq.config, cfgReq.value);
|
||||
taosCfgDynamicOptions(cfgReq.config, cfgReq.value);
|
||||
|
||||
SConfig *pCfg = taosGetCfg();
|
||||
cfgSetItem(pCfg, cfgReq.config, cfgReq.value, CFG_STYPE_ALTER_CMD);
|
||||
taosCfgDynamicOptions(pCfg, cfgReq.config, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -299,10 +299,11 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vnodeCfg.vgId);
|
||||
|
||||
if (vnodeCreate(path, &vnodeCfg, diskPrimary, pMgmt->pTfs) < 0) {
|
||||
tFreeSCreateVnodeReq(&req);
|
||||
dError("vgId:%d, failed to create vnode since %s", req.vgId, terrstr());
|
||||
vmReleaseVnode(pMgmt, pVnode);
|
||||
tFreeSCreateVnodeReq(&req);
|
||||
code = terrno;
|
||||
goto _OVER;
|
||||
return code;
|
||||
}
|
||||
|
||||
SVnode *pImpl = vnodeOpen(path, diskPrimary, pMgmt->pTfs, pMgmt->msgCb, true);
|
||||
|
|
|
@ -8,6 +8,12 @@ IF (TD_ENTERPRISE)
|
|||
LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/mnode/src/mndVgroup.c)
|
||||
LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/mnode/src/mndDnode.c)
|
||||
LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/view/src/mndView.c)
|
||||
|
||||
IF(${BUILD_WITH_S3})
|
||||
add_definitions(-DUSE_S3)
|
||||
ELSEIF(${BUILD_WITH_COS})
|
||||
add_definitions(-DUSE_COS)
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
add_library(mnode STATIC ${MNODE_SRC})
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "mndUser.h"
|
||||
#include "mndVgroup.h"
|
||||
#include "tmisce.h"
|
||||
#include "tunit.h"
|
||||
|
||||
#define TSDB_DNODE_VER_NUMBER 2
|
||||
#define TSDB_DNODE_RESERVE_SIZE 64
|
||||
|
@ -1316,8 +1317,8 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
|
||||
if (code < 0) return code;
|
||||
|
||||
if (flag > 1024 * 1024 || (flag > -1 && flag < 4) || flag < -1) {
|
||||
mError("dnode:%d, failed to config s3blocksize since value:%d. Valid range: -1 or [4, 1024 * 1024]",
|
||||
if (flag > 1024 * 1024 || (flag > -1 && flag < 1024) || flag < -1) {
|
||||
mError("dnode:%d, failed to config s3blocksize since value:%d. Valid range: -1 or [1024, 1024 * 1024]",
|
||||
cfgReq.dnodeId, flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
|
@ -1328,7 +1329,7 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
#endif
|
||||
} else {
|
||||
mndMCfg2DCfg(&cfgReq, &dcfgReq);
|
||||
if (mndMCfg2DCfg(&cfgReq, &dcfgReq)) goto _err_out;
|
||||
if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
|
||||
mError("dnode:%d, failed to config since config is too long", cfgReq.dnodeId);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
|
|
|
@ -313,7 +313,7 @@ _CONNECT:
|
|||
code = 0;
|
||||
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "%s:%d, app:%s", ip, pConn->port, connReq.app);
|
||||
sprintf(detail, "app:%s", connReq.app);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "login", "", "", detail, strlen(detail));
|
||||
|
||||
|
|
|
@ -882,7 +882,6 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea
|
|||
if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0 && idx.pIdx != NULL) {
|
||||
terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST;
|
||||
mndReleaseIdx(pMnode, idx.pIdx);
|
||||
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -1179,8 +1178,16 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) {
|
|||
SName name = {0};
|
||||
tNameFromString(&name, createReq.name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createStb", name.dbname, name.tname, createReq.sql, createReq.sqlLen);
|
||||
if(createReq.sql == NULL && createReq.sqlLen == 0){
|
||||
char detail[1000] = {0};
|
||||
|
||||
sprintf(detail, "dbname:%s, stable name:%s", name.dbname, name.tname);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createStb", name.dbname, name.tname, detail, strlen(detail));
|
||||
}
|
||||
else{
|
||||
auditRecord(pReq, pMnode->clusterId, "createStb", name.dbname, name.tname, createReq.sql, createReq.sqlLen);
|
||||
}
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("stb:%s, failed to create since %s", createReq.name, terrstr());
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "mndTrans.h"
|
||||
#include "mndUser.h"
|
||||
#include "mndVgroup.h"
|
||||
#include "osMemory.h"
|
||||
#include "parser.h"
|
||||
#include "tmisce.h"
|
||||
#include "tname.h"
|
||||
|
@ -756,6 +757,15 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
char* sql = NULL;
|
||||
int32_t sqlLen = 0;
|
||||
if(createStreamReq.sql != NULL){
|
||||
sqlLen = strlen(createStreamReq.sql);
|
||||
sql = taosMemoryMalloc(sqlLen + 1);
|
||||
memset(sql, 0, sqlLen + 1);
|
||||
memcpy(sql, createStreamReq.sql, sqlLen);
|
||||
}
|
||||
|
||||
// build stream obj from request
|
||||
if (mndBuildStreamObjFromCreateReq(pMnode, &streamObj, &createStreamReq) < 0) {
|
||||
mError("stream:%s, failed to create since %s", createStreamReq.name, terrstr());
|
||||
|
@ -861,14 +871,21 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
|
||||
code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
SName dbname = {0};
|
||||
tNameFromString(&dbname, createStreamReq.sourceDB, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
||||
SName name = {0};
|
||||
tNameFromString(&name, createStreamReq.name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
// reuse this function for stream
|
||||
|
||||
// TODO
|
||||
if (createStreamReq.sql != NULL) {
|
||||
auditRecord(pReq, pMnode->clusterId, "createStream", name.dbname, name.tname, createStreamReq.sql,
|
||||
strlen(createStreamReq.sql));
|
||||
if (sql != NULL && sqlLen > 0) {
|
||||
auditRecord(pReq, pMnode->clusterId, "createStream", dbname.dbname, name.dbname, sql,
|
||||
sqlLen);
|
||||
}
|
||||
else{
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "dbname:%s, stream name:%s", dbname.dbname, name.dbname);
|
||||
auditRecord(pReq, pMnode->clusterId, "createStream", dbname.dbname, name.dbname, detail, strlen(detail));
|
||||
}
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
|
@ -879,6 +896,9 @@ _OVER:
|
|||
|
||||
tFreeSCMCreateStreamReq(&createStreamReq);
|
||||
tFreeStreamObj(&streamObj);
|
||||
if(sql != NULL){
|
||||
taosMemoryFreeClear(sql);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -1229,6 +1229,21 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA
|
|||
}
|
||||
} else {
|
||||
mInfo("trans:%d, %d of %d actions executed", pTrans->id, numOfExecuted, numOfActions);
|
||||
|
||||
for (int32_t action = 0; action < numOfActions; ++action) {
|
||||
STransAction *pAction = taosArrayGet(pArray, action);
|
||||
mDebug("trans:%d, %s:%d Sent:%d, Received:%d, errCode:0x%x, acceptableCode:0x%x, retryCode:0x%x",
|
||||
pTrans->id, mndTransStr(pAction->stage), pAction->id, pAction->msgSent, pAction->msgReceived,
|
||||
pAction->errCode, pAction->acceptableCode, pAction->retryCode);
|
||||
if (pAction->msgSent) {
|
||||
if (pAction->msgReceived) {
|
||||
if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {
|
||||
mndTransResetAction(pMnode, pTrans, pAction);
|
||||
mInfo("trans:%d, %s:%d reset", pTrans->id, mndTransStr(pAction->stage), pAction->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1561,7 +1561,11 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
|
|||
code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createUser", "", createReq.user, createReq.sql, createReq.sqlLen);
|
||||
char detail[1000] = {0};
|
||||
sprintf(detail, "enable:%d, superUser:%d, sysInfo:%d, password:xxx",
|
||||
createReq.enable, createReq.superUser, createReq.sysInfo);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "createUser", "", createReq.user, detail, strlen(detail));
|
||||
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndVgroup.h"
|
||||
#include "audit.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
|
@ -26,7 +27,6 @@
|
|||
#include "mndTrans.h"
|
||||
#include "mndUser.h"
|
||||
#include "tmisce.h"
|
||||
#include "audit.h"
|
||||
|
||||
#define VGROUP_VER_NUMBER 1
|
||||
#define VGROUP_RESERVE_SIZE 64
|
||||
|
@ -73,7 +73,7 @@ int32_t mndInitVgroup(SMnode *pMnode) {
|
|||
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_REDISTRIBUTE_VGROUP, mndProcessRedistributeVgroupMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_SPLIT_VGROUP, mndProcessSplitVgroupMsg);
|
||||
//mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP, mndProcessVgroupBalanceLeaderMsg);
|
||||
// mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP, mndProcessVgroupBalanceLeaderMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP, mndProcessBalanceVgroupMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP_LEADER, mndProcessVgroupBalanceLeaderMsg);
|
||||
|
||||
|
@ -162,7 +162,7 @@ SSdbRow *mndVgroupActionDecode(SSdbRaw *pRaw) {
|
|||
pVgid->syncState = TAOS_SYNC_STATE_LEADER;
|
||||
}
|
||||
}
|
||||
if(dataPos + sizeof(int32_t) + VGROUP_RESERVE_SIZE <= pRaw->dataLen){
|
||||
if (dataPos + sizeof(int32_t) + VGROUP_RESERVE_SIZE <= pRaw->dataLen) {
|
||||
SDB_GET_INT32(pRaw, dataPos, &pVgroup->syncConfChangeVer, _OVER)
|
||||
}
|
||||
|
||||
|
@ -289,15 +289,14 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg
|
|||
createReq.hashPrefix = pDb->cfg.hashPrefix;
|
||||
createReq.hashSuffix = pDb->cfg.hashSuffix;
|
||||
createReq.tsdbPageSize = pDb->cfg.tsdbPageSize;
|
||||
createReq.changeVersion= ++(pVgroup->syncConfChangeVer);
|
||||
createReq.changeVersion = ++(pVgroup->syncConfChangeVer);
|
||||
|
||||
for (int32_t v = 0; v < pVgroup->replica; ++v) {
|
||||
SReplica *pReplica = NULL;
|
||||
|
||||
if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
pReplica = &createReq.replicas[createReq.replica];
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
pReplica = &createReq.learnerReplicas[createReq.learnerReplica];
|
||||
}
|
||||
|
||||
|
@ -312,21 +311,19 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg
|
|||
memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
|
||||
mndReleaseDnode(pMnode, pVgidDnode);
|
||||
|
||||
if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
if (pDnode->id == pVgid->dnodeId) {
|
||||
createReq.selfIndex = createReq.replica;
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
if (pDnode->id == pVgid->dnodeId) {
|
||||
createReq.learnerSelfIndex = createReq.learnerReplica;
|
||||
}
|
||||
}
|
||||
|
||||
if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
createReq.replica++;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
createReq.learnerReplica++;
|
||||
}
|
||||
}
|
||||
|
@ -338,10 +335,11 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg
|
|||
|
||||
createReq.changeVersion = pVgroup->syncConfChangeVer;
|
||||
|
||||
mInfo("vgId:%d, build create vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
|
||||
mInfo(
|
||||
"vgId:%d, build create vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
|
||||
"changeVersion:%d",
|
||||
createReq.vgId, createReq.replica, createReq.selfIndex, createReq.learnerReplica,
|
||||
createReq.learnerReplica, createReq.strict, createReq.changeVersion);
|
||||
createReq.vgId, createReq.replica, createReq.selfIndex, createReq.learnerReplica, createReq.learnerReplica,
|
||||
createReq.strict, createReq.changeVersion);
|
||||
for (int32_t i = 0; i < createReq.replica; ++i) {
|
||||
mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.replicas[i].fqdn, createReq.replicas[i].port);
|
||||
}
|
||||
|
@ -426,11 +424,10 @@ static void *mndBuildAlterVnodeReplicaReq(SMnode *pMnode, SDbObj *pDb, SVgObj *p
|
|||
for (int32_t v = 0; v < pVgroup->replica; ++v) {
|
||||
SReplica *pReplica = NULL;
|
||||
|
||||
if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
pReplica = &alterReq.replicas[alterReq.replica];
|
||||
alterReq.replica++;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
pReplica = &alterReq.learnerReplicas[alterReq.learnerReplica];
|
||||
alterReq.learnerReplica++;
|
||||
}
|
||||
|
@ -444,28 +441,28 @@ static void *mndBuildAlterVnodeReplicaReq(SMnode *pMnode, SDbObj *pDb, SVgObj *p
|
|||
memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
|
||||
mndReleaseDnode(pMnode, pVgidDnode);
|
||||
|
||||
if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
if (dnodeId == pVgid->dnodeId) {
|
||||
alterReq.selfIndex = v;
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
if (dnodeId == pVgid->dnodeId) {
|
||||
alterReq.learnerSelfIndex = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mInfo("vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
|
||||
mInfo(
|
||||
"vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
|
||||
"changeVersion:%d",
|
||||
alterReq.vgId, alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica,
|
||||
alterReq.learnerSelfIndex, alterReq.strict, alterReq.changeVersion);
|
||||
alterReq.vgId, alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica, alterReq.learnerSelfIndex,
|
||||
alterReq.strict, alterReq.changeVersion);
|
||||
for (int32_t i = 0; i < alterReq.replica; ++i) {
|
||||
mInfo("vgId:%d, replica:%d ep:%s:%u", alterReq.vgId, i, alterReq.replicas[i].fqdn, alterReq.replicas[i].port);
|
||||
}
|
||||
for (int32_t i = 0; i < alterReq.learnerReplica; ++i) {
|
||||
mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", alterReq.vgId, i,
|
||||
alterReq.learnerReplicas[i].fqdn, alterReq.learnerReplicas[i].port);
|
||||
mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", alterReq.vgId, i, alterReq.learnerReplicas[i].fqdn,
|
||||
alterReq.learnerReplicas[i].port);
|
||||
}
|
||||
|
||||
if (alterReq.selfIndex == -1 && alterReq.learnerSelfIndex == -1) {
|
||||
|
@ -504,11 +501,10 @@ static void *mndBuildCheckLearnCatchupReq(SMnode *pMnode, SDbObj *pDb, SVgObj *p
|
|||
for (int32_t v = 0; v < pVgroup->replica; ++v) {
|
||||
SReplica *pReplica = NULL;
|
||||
|
||||
if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
pReplica = &req.replicas[req.replica];
|
||||
req.replica++;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
pReplica = &req.learnerReplicas[req.learnerReplica];
|
||||
req.learnerReplica++;
|
||||
}
|
||||
|
@ -522,12 +518,11 @@ static void *mndBuildCheckLearnCatchupReq(SMnode *pMnode, SDbObj *pDb, SVgObj *p
|
|||
memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
|
||||
mndReleaseDnode(pMnode, pVgidDnode);
|
||||
|
||||
if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
|
||||
if (dnodeId == pVgid->dnodeId) {
|
||||
req.selfIndex = v;
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
if (dnodeId == pVgid->dnodeId) {
|
||||
req.learnerSelfIndex = v;
|
||||
}
|
||||
|
@ -535,14 +530,12 @@ static void *mndBuildCheckLearnCatchupReq(SMnode *pMnode, SDbObj *pDb, SVgObj *p
|
|||
}
|
||||
|
||||
mInfo("vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d",
|
||||
req.vgId, req.replica, req.selfIndex, req.learnerReplica,
|
||||
req.learnerSelfIndex, req.strict);
|
||||
req.vgId, req.replica, req.selfIndex, req.learnerReplica, req.learnerSelfIndex, req.strict);
|
||||
for (int32_t i = 0; i < req.replica; ++i) {
|
||||
mInfo("vgId:%d, replica:%d ep:%s:%u", req.vgId, i, req.replicas[i].fqdn, req.replicas[i].port);
|
||||
}
|
||||
for (int32_t i = 0; i < req.learnerReplica; ++i) {
|
||||
mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", req.vgId, i,
|
||||
req.learnerReplicas[i].fqdn, req.learnerReplicas[i].port);
|
||||
mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", req.vgId, i, req.learnerReplicas[i].fqdn, req.learnerReplicas[i].port);
|
||||
}
|
||||
|
||||
if (req.selfIndex == -1 && req.learnerSelfIndex == -1) {
|
||||
|
@ -1350,7 +1343,8 @@ int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVg
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t mndRestoreAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SDnodeObj *pDnode) {
|
||||
int32_t mndRestoreAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
|
||||
SDnodeObj *pDnode) {
|
||||
STransAction action = {0};
|
||||
|
||||
action.epSet = mndGetDnodeEpset(pDnode);
|
||||
|
@ -1401,8 +1395,8 @@ int32_t mndAddAlterVnodeConfirmAction(SMnode *pMnode, STrans *pTrans, SDbObj *pD
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t mndAddChangeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb,
|
||||
SVgObj *pOldVgroup, SVgObj *pNewVgroup, int32_t dnodeId) {
|
||||
int32_t mndAddChangeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pOldVgroup, SVgObj *pNewVgroup,
|
||||
int32_t dnodeId) {
|
||||
STransAction action = {0};
|
||||
action.epSet = mndGetVgroupEpset(pMnode, pNewVgroup);
|
||||
|
||||
|
@ -1422,7 +1416,7 @@ int32_t mndAddChangeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb,
|
|||
pHead->contLen = htonl(totallen);
|
||||
pHead->vgId = htonl(pNewVgroup->vgId);
|
||||
|
||||
memcpy((void*)(pHead + 1), pReq, contLen);
|
||||
memcpy((void *)(pHead + 1), pReq, contLen);
|
||||
taosMemoryFree(pReq);
|
||||
|
||||
action.pCont = pHead;
|
||||
|
@ -1727,7 +1721,7 @@ int32_t mndSetMoveVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb,
|
|||
mInfo("vgId:%d, will add 1 vnode and force remove 1 vnode", pVgroup->vgId);
|
||||
if (mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray) != 0) return -1;
|
||||
newVg.replica--;
|
||||
//SVnodeGid del = newVg.vnodeGid[vnIndex];
|
||||
// SVnodeGid del = newVg.vnodeGid[vnIndex];
|
||||
newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
|
||||
memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
|
||||
{
|
||||
|
@ -1748,8 +1742,8 @@ int32_t mndSetMoveVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb,
|
|||
if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[vnIndex]) != 0) return -1;
|
||||
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg) != 0) return -1;
|
||||
|
||||
if(newVg.replica == 1){
|
||||
if(force && !unsafe){
|
||||
if (newVg.replica == 1) {
|
||||
if (force && !unsafe) {
|
||||
terrno = TSDB_CODE_VND_META_DATA_UNSAFE_DELETE;
|
||||
return -1;
|
||||
}
|
||||
|
@ -2176,7 +2170,7 @@ static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq) {
|
|||
code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, pNew3, pOld3);
|
||||
|
||||
} else {
|
||||
terrno = TSDB_CODE_MND_INVALID_REPLICA;
|
||||
terrno = TSDB_CODE_MND_REQ_REJECTED;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -2206,8 +2200,7 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
static void *mndBuildSForceBecomeFollowerReq(SMnode *pMnode, SVgObj *pVgroup, int32_t dnodeId,
|
||||
int32_t *pContLen) {
|
||||
static void *mndBuildSForceBecomeFollowerReq(SMnode *pMnode, SVgObj *pVgroup, int32_t dnodeId, int32_t *pContLen) {
|
||||
SForceBecomeFollowerReq balanceReq = {
|
||||
.vgId = pVgroup->vgId,
|
||||
};
|
||||
|
@ -2258,22 +2251,21 @@ int32_t mndAddBalanceVgroupLeaderAction(SMnode *pMnode, STrans *pTrans, SVgObj *
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans){
|
||||
int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
int32_t vgid = pVgroup->vgId;
|
||||
int8_t replica = pVgroup->replica;
|
||||
|
||||
if(pVgroup->replica <= 1) {
|
||||
if (pVgroup->replica <= 1) {
|
||||
mInfo("trans:%d, vgid:%d no need to balance, replica:%d", pTrans->id, vgid, replica);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t dnodeId = pVgroup->vnodeGid[0].dnodeId;
|
||||
|
||||
for(int i = 0; i < replica; i++)
|
||||
{
|
||||
if(pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER){
|
||||
for (int i = 0; i < replica; i++) {
|
||||
if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER) {
|
||||
dnodeId = pVgroup->vnodeGid[i].dnodeId;
|
||||
break;
|
||||
}
|
||||
|
@ -2289,8 +2281,7 @@ int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTra
|
|||
mndReleaseDnode(pMnode, pDnode);
|
||||
}
|
||||
|
||||
if(exist && online)
|
||||
{
|
||||
if (exist && online) {
|
||||
mInfo("trans:%d, vgid:%d leader to dnode:%d", pTrans->id, vgid, dnodeId);
|
||||
|
||||
if (mndAddBalanceVgroupLeaderAction(pMnode, pTrans, pVgroup, dnodeId) != 0) {
|
||||
|
@ -2322,11 +2313,9 @@ int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTra
|
|||
return -1;
|
||||
}
|
||||
(void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
|
||||
}
|
||||
else
|
||||
{
|
||||
mInfo("trans:%d, vgid:%d cant be balanced to dnode:%d, exist:%d, online:%d",
|
||||
pTrans->id, vgid, dnodeId, exist, online);
|
||||
} else {
|
||||
mInfo("trans:%d, vgid:%d cant be balanced to dnode:%d, exist:%d, online:%d", pTrans->id, vgid, dnodeId, exist,
|
||||
online);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2334,14 +2323,10 @@ int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTra
|
|||
|
||||
extern int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq);
|
||||
|
||||
int32_t mndProcessVgroupBalanceLeaderMsg(SRpcMsg *pReq) {
|
||||
return mndProcessVgroupBalanceLeaderMsgImp(pReq);
|
||||
}
|
||||
int32_t mndProcessVgroupBalanceLeaderMsg(SRpcMsg *pReq) { return mndProcessVgroupBalanceLeaderMsgImp(pReq); }
|
||||
|
||||
#ifndef TD_ENTERPRISE
|
||||
int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq) {
|
||||
return 0;
|
||||
}
|
||||
int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq) { return 0; }
|
||||
#endif
|
||||
|
||||
static int32_t mndCheckDnodeMemory(SMnode *pMnode, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pOldVgroup,
|
||||
|
@ -2394,10 +2379,10 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb
|
|||
mInfo("db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId,
|
||||
pVgroup->vnodeGid[0].dnodeId);
|
||||
|
||||
//add second
|
||||
// add second
|
||||
if (mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray) != 0) return -1;
|
||||
|
||||
//learner stage
|
||||
// learner stage
|
||||
newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0)
|
||||
|
@ -2405,16 +2390,15 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb
|
|||
|
||||
if (mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[1]) != 0) return -1;
|
||||
|
||||
//follower stage
|
||||
// follower stage
|
||||
newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
if (mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId) != 0)
|
||||
return -1;
|
||||
if (mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId) != 0) return -1;
|
||||
if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0)
|
||||
return -1;
|
||||
|
||||
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup) != 0) return -1;
|
||||
|
||||
//add third
|
||||
// add third
|
||||
if (mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray) != 0) return -1;
|
||||
|
||||
newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
|
@ -2478,41 +2462,43 @@ int32_t mndBuildRaftAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pO
|
|||
|
||||
mndTransSetSerial(pTrans);
|
||||
|
||||
mInfo("trans:%d, vgId:%d, alter vgroup, syncConfChangeVer:%d, version:%d, replica:%d",
|
||||
pTrans->id, pVgroup->vgId, pVgroup->syncConfChangeVer, pVgroup->version, pVgroup->replica);
|
||||
mInfo("trans:%d, vgId:%d, alter vgroup, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
|
||||
pVgroup->syncConfChangeVer, pVgroup->version, pVgroup->replica);
|
||||
|
||||
if (newVgroup.replica == 1 && pNewDb->cfg.replications == 3) {
|
||||
mInfo("db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId,
|
||||
pVgroup->vnodeGid[0].dnodeId);
|
||||
|
||||
//add second
|
||||
// add second
|
||||
if (mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray) != 0) return -1;
|
||||
//add third
|
||||
// add third
|
||||
if (mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray) != 0) return -1;
|
||||
|
||||
//add learner stage
|
||||
// add learner stage
|
||||
newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
if (mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0) return -1;
|
||||
mInfo("trans:%d, vgId:%d, add change config, syncConfChangeVer:%d, version:%d, replica:%d",
|
||||
pTrans->id, pVgroup->vgId, newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
|
||||
if (mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0)
|
||||
return -1;
|
||||
mInfo("trans:%d, vgId:%d, add change config, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id,
|
||||
pVgroup->vgId, newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
|
||||
if (mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[1]) != 0) return -1;
|
||||
mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d",
|
||||
pTrans->id, pVgroup->vgId, newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
|
||||
mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
|
||||
newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
|
||||
if (mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[2]) != 0) return -1;
|
||||
mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d",
|
||||
pTrans->id, pVgroup->vgId, newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
|
||||
mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
|
||||
newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
|
||||
|
||||
|
||||
//check learner
|
||||
// check learner
|
||||
newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
if (mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId) != 0) return -1;
|
||||
if (mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[2].dnodeId) != 0) return -1;
|
||||
if (mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId) != 0)
|
||||
return -1;
|
||||
if (mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[2].dnodeId) != 0)
|
||||
return -1;
|
||||
|
||||
//change raft type
|
||||
// change raft type
|
||||
newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
|
@ -2543,7 +2529,8 @@ int32_t mndBuildRaftAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pO
|
|||
SVnodeGid del1 = {0};
|
||||
if (mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del1) != 0) return -1;
|
||||
|
||||
if (mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0) return -1;
|
||||
if (mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0)
|
||||
return -1;
|
||||
|
||||
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup) != 0) return -1;
|
||||
|
||||
|
@ -2560,7 +2547,8 @@ int32_t mndBuildRaftAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pO
|
|||
SVnodeGid del2 = {0};
|
||||
if (mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del2) != 0) return -1;
|
||||
|
||||
if (mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0) return -1;
|
||||
if (mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0)
|
||||
return -1;
|
||||
|
||||
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup) != 0) return -1;
|
||||
|
||||
|
@ -2597,37 +2585,33 @@ int32_t mndBuildRestoreAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj
|
|||
SVgObj newVgroup = {0};
|
||||
memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
|
||||
|
||||
mInfo("db:%s, vgId:%d, restore vnodes, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId,
|
||||
pVgroup->vnodeGid[0].dnodeId);
|
||||
mInfo("db:%s, vgId:%d, restore vnodes, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId);
|
||||
|
||||
if(newVgroup.replica == 1){
|
||||
if (newVgroup.replica == 1) {
|
||||
int selected = 0;
|
||||
for(int i = 0; i < newVgroup.replica; i++){
|
||||
for (int i = 0; i < newVgroup.replica; i++) {
|
||||
newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
if(newVgroup.vnodeGid[i].dnodeId == pDnode->id){
|
||||
if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
|
||||
selected = i;
|
||||
}
|
||||
}
|
||||
if (mndAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, &newVgroup.vnodeGid[selected]) != 0) return -1;
|
||||
}
|
||||
else if(newVgroup.replica == 3){
|
||||
for(int i = 0; i < newVgroup.replica; i++){
|
||||
if(newVgroup.vnodeGid[i].dnodeId == pDnode->id){
|
||||
} else if (newVgroup.replica == 3) {
|
||||
for (int i = 0; i < newVgroup.replica; i++) {
|
||||
if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
|
||||
newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
}
|
||||
}
|
||||
if (mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode) != 0) return -1;
|
||||
|
||||
for(int i = 0; i < newVgroup.replica; i++){
|
||||
for (int i = 0; i < newVgroup.replica; i++) {
|
||||
newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
if(newVgroup.vnodeGid[i].dnodeId == pDnode->id){
|
||||
if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
|
||||
}
|
||||
}
|
||||
if (mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode) != 0)
|
||||
return -1;
|
||||
if (mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode) != 0) return -1;
|
||||
}
|
||||
|
||||
SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
|
||||
|
@ -2679,14 +2663,14 @@ int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgro
|
|||
SDbObj dbObj = {0};
|
||||
SArray *pArray = mndBuildDnodesArray(pMnode, 0);
|
||||
|
||||
// int32_t numOfTopics = 0;
|
||||
// if (mndGetNumOfTopics(pMnode, pDb->name, &numOfTopics) != 0) {
|
||||
// goto _OVER;
|
||||
// }
|
||||
// if (numOfTopics > 0) {
|
||||
// terrno = TSDB_CODE_MND_TOPIC_MUST_BE_DELETED;
|
||||
// goto _OVER;
|
||||
// }
|
||||
// int32_t numOfTopics = 0;
|
||||
// if (mndGetNumOfTopics(pMnode, pDb->name, &numOfTopics) != 0) {
|
||||
// goto _OVER;
|
||||
// }
|
||||
// if (numOfTopics > 0) {
|
||||
// terrno = TSDB_CODE_MND_TOPIC_MUST_BE_DELETED;
|
||||
// goto _OVER;
|
||||
// }
|
||||
|
||||
int32_t numOfStreams = 0;
|
||||
if (mndGetNumOfStreams(pMnode, pDb->name, &numOfStreams) != 0) {
|
||||
|
@ -2697,6 +2681,15 @@ int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgro
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
#if defined(USE_S3)
|
||||
extern int8_t tsS3Enabled;
|
||||
if (tsS3Enabled) {
|
||||
code = TSDB_CODE_OPS_NOT_SUPPORT;
|
||||
mError("vgId:%d, db:%s, s3 exists, split vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
|
||||
goto _OVER;
|
||||
}
|
||||
#endif
|
||||
|
||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "split-vgroup");
|
||||
if (pTrans == NULL) goto _OVER;
|
||||
mndTransSetSerial(pTrans);
|
||||
|
@ -3013,8 +3006,8 @@ _OVER:
|
|||
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; }
|
||||
|
||||
bool mndVgroupInDnode(SVgObj *pVgroup, int32_t dnodeId) {
|
||||
for(int i = 0; i < pVgroup->replica; i++){
|
||||
if(pVgroup->vnodeGid[i].dnodeId == dnodeId) return true;
|
||||
for (int i = 0; i < pVgroup->replica; i++) {
|
||||
if (pVgroup->vnodeGid[i].dnodeId == dnodeId) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ void initStateStoreAPI(SStateStore* pStore) {
|
|||
pStore->streamStateSessionGetKVByCur = streamStateSessionGetKVByCur;
|
||||
pStore->streamStateStateAddIfNotExist = streamStateStateAddIfNotExist;
|
||||
pStore->streamStateSessionGetKeyByRange = streamStateSessionGetKeyByRange;
|
||||
pStore->streamStateSessionAllocWinBuffByNextPosition = streamStateSessionAllocWinBuffByNextPosition;
|
||||
|
||||
pStore->updateInfoInit = updateInfoInit;
|
||||
pStore->updateInfoFillBlockData = updateInfoFillBlockData;
|
||||
|
|
|
@ -147,7 +147,7 @@ int32_t tqOffsetDelete(STqOffsetStore* pStore, const char* subscribeKey)
|
|||
int32_t tqOffsetCommitFile(STqOffsetStore* pStore);
|
||||
|
||||
// tqSink
|
||||
int32_t tqBuildDeleteReq(const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq,
|
||||
int32_t tqBuildDeleteReq(STQ* pTq, const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq,
|
||||
const char* pIdStr);
|
||||
void tqSinkDataIntoDstTable(SStreamTask* pTask, void* vnode, void* data);
|
||||
|
||||
|
@ -160,7 +160,7 @@ int32_t tqResetStreamTaskStatus(STQ* pTq);
|
|||
int32_t tqStopStreamTasks(STQ* pTq);
|
||||
|
||||
// tq util
|
||||
int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, SStreamRefDataBlock** pRefBlock);
|
||||
int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, void** pRefBlock, int32_t type);
|
||||
int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg);
|
||||
int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId,
|
||||
int32_t type, int64_t sver, int64_t ever);
|
||||
|
|
|
@ -831,7 +831,7 @@ struct SDiskDataBuilder {
|
|||
SBlkInfo bi;
|
||||
};
|
||||
|
||||
typedef struct SLDataIter {
|
||||
struct SLDataIter {
|
||||
SRBTreeNode node;
|
||||
SSttBlk *pSttBlk;
|
||||
int64_t cid; // for debug purpose
|
||||
|
@ -845,7 +845,7 @@ typedef struct SLDataIter {
|
|||
SSttBlockLoadInfo *pBlockLoadInfo;
|
||||
bool ignoreEarlierTs;
|
||||
struct SSttFileReader *pReader;
|
||||
} SLDataIter;
|
||||
};
|
||||
|
||||
#define tMergeTreeGetRow(_t) (&((_t)->pIter->rInfo.row))
|
||||
|
||||
|
|
|
@ -286,7 +286,8 @@ int32_t tdProcessTSmaCreate(SSma* pSma, int64_t version, const char* msg);
|
|||
int32_t tdProcessTSmaInsert(SSma* pSma, int64_t indexUid, const char* msg);
|
||||
|
||||
int32_t tdProcessRSmaCreate(SSma* pSma, SVCreateStbReq* pReq);
|
||||
int32_t tdProcessRSmaSubmit(SSma* pSma, int64_t version, void* pReq, void* pMsg, int32_t len, int32_t inputType);
|
||||
int32_t tdProcessRSmaSubmit(SSma* pSma, int64_t version, void* pReq, void* pMsg, int32_t len);
|
||||
int32_t tdProcessRSmaDelete(SSma* pSma, int64_t version, void* pReq, void* pMsg, int32_t len);
|
||||
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, bool isAdd);
|
||||
|
|
|
@ -217,10 +217,7 @@ static int32_t tdProcessRSmaAsyncCommitImpl(SSma *pSma, SCommitInfo *pInfo) {
|
|||
int32_t lino = 0;
|
||||
SVnode *pVnode = pSma->pVnode;
|
||||
|
||||
SSmaEnv *pSmaEnv = SMA_RSMA_ENV(pSma);
|
||||
if (!pSmaEnv) {
|
||||
goto _exit;
|
||||
}
|
||||
if (!SMA_RSMA_ENV(pSma)) goto _exit;
|
||||
|
||||
code = tsdbCommitBegin(VND_RSMA1(pVnode), pInfo);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
|
|
@ -17,12 +17,17 @@
|
|||
#include "tq.h"
|
||||
#include "tstream.h"
|
||||
|
||||
#define RSMA_QTASKEXEC_SMOOTH_SIZE (100) // cnt
|
||||
#define RSMA_SUBMIT_BATCH_SIZE (1024) // cnt
|
||||
#define RSMA_EXEC_SMOOTH_SIZE (100) // cnt
|
||||
#define RSMA_EXEC_BATCH_SIZE (1024) // cnt
|
||||
#define RSMA_FETCH_DELAY_MAX (120000) // ms
|
||||
#define RSMA_FETCH_ACTIVE_MAX (1000) // ms
|
||||
#define RSMA_FETCH_INTERVAL (5000) // ms
|
||||
#define RSMA_TASK_FLAG "rsma"
|
||||
#define RSMA_EXEC_TASK_FLAG "rsma"
|
||||
#define RSMA_EXEC_MSG_HLEN (13) // type(int8_t) + len(int32_t) + version(int64_t)
|
||||
#define RSMA_EXEC_MSG_TYPE(msg) (*(int8_t *)(msg))
|
||||
#define RSMA_EXEC_MSG_LEN(msg) (*(int32_t *)POINTER_SHIFT((msg), sizeof(int8_t)))
|
||||
#define RSMA_EXEC_MSG_VER(msg) (*(int64_t *)POINTER_SHIFT((msg), sizeof(int8_t) + sizeof(int32_t)))
|
||||
#define RSMA_EXEC_MSG_BODY(msg) (POINTER_SHIFT((msg), RSMA_EXEC_MSG_HLEN))
|
||||
|
||||
#define RSMA_NEED_FETCH(r) (RSMA_INFO_ITEM((r), 0)->fetchLevel || RSMA_INFO_ITEM((r), 1)->fetchLevel)
|
||||
|
||||
|
@ -38,11 +43,11 @@ static void tdUidStoreDestory(STbUidStore *pStore);
|
|||
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,
|
||||
ERsmaExecType type, int8_t level);
|
||||
static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSize, int64_t version, int32_t inputType,
|
||||
SRSmaInfo *pInfo, ERsmaExecType type, int8_t level);
|
||||
static SRSmaInfo *tdAcquireRSmaInfoBySuid(SSma *pSma, int64_t suid);
|
||||
static void tdReleaseRSmaInfo(SSma *pSma, SRSmaInfo *pInfo);
|
||||
static void tdFreeRSmaSubmitItems(SArray *pItems);
|
||||
static void tdFreeRSmaSubmitItems(SArray *pItems, int32_t type);
|
||||
static int32_t tdRSmaFetchAllResult(SSma *pSma, SRSmaInfo *pInfo);
|
||||
static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSmaInfoItem *pItem, SRSmaInfo *pInfo,
|
||||
int32_t execType, int8_t *streamFlushed);
|
||||
|
@ -288,8 +293,8 @@ static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat
|
|||
pStreamTask->id.streamId = pRSmaInfo->suid + idx;
|
||||
pStreamTask->chkInfo.startTs = taosGetTimestampMs();
|
||||
pStreamTask->pMeta = pVnode->pTq->pStreamMeta;
|
||||
pStreamTask->exec.qmsg = taosMemoryMalloc(strlen(RSMA_TASK_FLAG) + 1);
|
||||
sprintf(pStreamTask->exec.qmsg, "%s", RSMA_TASK_FLAG);
|
||||
pStreamTask->exec.qmsg = taosMemoryMalloc(strlen(RSMA_EXEC_TASK_FLAG) + 1);
|
||||
sprintf(pStreamTask->exec.qmsg, "%s", RSMA_EXEC_TASK_FLAG);
|
||||
pStreamTask->chkInfo.checkpointId = streamMetaGetLatestCheckpointId(pStreamTask->pMeta);
|
||||
tdRSmaTaskInit(pStreamTask->pMeta, pItem, &pStreamTask->id);
|
||||
pStreamState = streamStateOpen(taskInfDir, pStreamTask, true, -1, -1);
|
||||
|
@ -624,6 +629,45 @@ _end:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t tdRSmaProcessDelReq(SSma *pSma, int64_t suid, int8_t level, SBatchDeleteReq *pDelReq) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
if (taosArrayGetSize(pDelReq->deleteReqs) > 0) {
|
||||
int32_t len = 0;
|
||||
tEncodeSize(tEncodeSBatchDeleteReq, pDelReq, len, code);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
void *pBuf = rpcMallocCont(len + sizeof(SMsgHead));
|
||||
if (!pBuf) {
|
||||
code = terrno;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
SEncoder encoder;
|
||||
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SMsgHead)), len);
|
||||
tEncodeSBatchDeleteReq(&encoder, pDelReq);
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
((SMsgHead *)pBuf)->vgId = TD_VID(pSma->pVnode);
|
||||
|
||||
SRpcMsg delMsg = {.msgType = TDMT_VND_BATCH_DEL,
|
||||
.pCont = pBuf,
|
||||
.contLen = len + sizeof(SMsgHead)};
|
||||
code = tmsgPutToQueue(&pSma->pVnode->msgCb, WRITE_QUEUE, &delMsg);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
_exit:
|
||||
taosArrayDestroy(pDelReq->deleteReqs);
|
||||
if (code) {
|
||||
smaError("vgId:%d, failed at line %d to process delete req for table:%" PRIi64 ", level:%" PRIi8 " since %s",
|
||||
SMA_VID(pSma), lino, suid, level, tstrerror(code));
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSmaInfoItem *pItem, SRSmaInfo *pInfo,
|
||||
int32_t execType, int8_t *streamFlushed) {
|
||||
int32_t code = 0;
|
||||
|
@ -652,9 +696,42 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
|||
if (output->info.type == STREAM_CHECKPOINT) {
|
||||
if (streamFlushed) *streamFlushed = 1;
|
||||
continue;
|
||||
} else if (output->info.type == STREAM_DELETE_RESULT) {
|
||||
SBatchDeleteReq deleteReq = {.suid = suid, .level = pItem->level};
|
||||
deleteReq.deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq));
|
||||
if (!deleteReq.deleteReqs) {
|
||||
code = terrno;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
code = tqBuildDeleteReq(pSma->pVnode->pTq, NULL, output, &deleteReq, "");
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tdRSmaProcessDelReq(pSma, suid, pItem->level, &deleteReq);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
continue;
|
||||
}
|
||||
|
||||
smaDebug("vgId:%d, result block, execType:%d, ver:%" PRIi64 ", submitReqVer:%" PRIi64 ", fetchResultVer:%" PRIi64
|
||||
", suid:%" PRIi64 ", level:%" PRIi8 ", uid:%" PRIu64 ", groupid:%" PRIu64 ", rows:%" PRIi64,
|
||||
SMA_VID(pSma), execType, output->info.version, pItem->submitReqVer, pItem->fetchResultVer, suid,
|
||||
pItem->level, output->info.id.uid, output->info.id.groupId, output->info.rows);
|
||||
|
||||
if (STREAM_GET_ALL == execType) {
|
||||
/**
|
||||
* 1. reset the output version when reboot
|
||||
* 2. delete msg version not updated from the result
|
||||
*/
|
||||
if (output->info.version < pItem->submitReqVer) {
|
||||
// submitReqVer keeps unchanged since tdExecuteRSmaImpl and tdRSmaFetchAllResult are executed synchronously
|
||||
output->info.version = pItem->submitReqVer;
|
||||
} else if (output->info.version == pItem->fetchResultVer) {
|
||||
smaWarn("vgId:%d, result block, skip dup version, execType:%d, ver:%" PRIi64 ", submitReqVer:%" PRIi64
|
||||
", fetchResultVer:%" PRIi64 ", suid:%" PRIi64 ", level:%" PRIi8 ", uid:%" PRIu64 ", groupid:%" PRIu64
|
||||
", rows:%" PRIi64,
|
||||
SMA_VID(pSma), execType, output->info.version, pItem->submitReqVer, pItem->fetchResultVer, suid,
|
||||
pItem->level, output->info.id.uid, output->info.id.groupId, output->info.rows);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
smaDebug("vgId:%d, result block, uid:%" PRIu64 ", groupid:%" PRIu64 ", rows:%" PRIi64, SMA_VID(pSma),
|
||||
output->info.id.uid, output->info.id.groupId, output->info.rows);
|
||||
|
||||
STsdb *sinkTsdb = (pItem->level == TSDB_RETENTION_L1 ? pSma->pRSmaTsdb[0] : pSma->pRSmaTsdb[1]);
|
||||
SSubmitReq2 *pReq = NULL;
|
||||
|
@ -664,12 +741,6 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
|||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
// reset the output version to handle reboot
|
||||
if (STREAM_GET_ALL == execType && output->info.version == 0) {
|
||||
// the submitReqVer keeps unchanged since tdExecuteRSmaImpl and tdRSmaFetchAllResult are executed synchronously
|
||||
output->info.version = pItem->submitReqVer;
|
||||
}
|
||||
|
||||
if (pReq && tdProcessSubmitReq(sinkTsdb, output->info.version, pReq) < 0) {
|
||||
if (terrno == TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE) {
|
||||
// TODO: reconfigure SSubmitReq2
|
||||
|
@ -686,8 +757,9 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
|||
atomic_store_64(&pItem->fetchResultVer, output->info.version);
|
||||
}
|
||||
|
||||
smaDebug("vgId:%d, process submit req for rsma suid:%" PRIu64 ",uid:%" PRIu64 ", level %" PRIi8 " ver %" PRIi64,
|
||||
SMA_VID(pSma), suid, output->info.id.groupId, pItem->level, output->info.version);
|
||||
smaDebug("vgId:%d, process submit req for rsma suid:%" PRIu64 ",uid:%" PRIu64 ", level:%" PRIi8
|
||||
", execType:%d, ver:%" PRIi64,
|
||||
SMA_VID(pSma), suid, output->info.id.groupId, pItem->level, execType, output->info.version);
|
||||
|
||||
if (pReq) {
|
||||
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
||||
|
@ -722,7 +794,7 @@ _exit:
|
|||
*/
|
||||
static int32_t tdExecuteRSmaImplAsync(SSma *pSma, int64_t version, const void *pMsg, int32_t len, int32_t inputType,
|
||||
SRSmaInfo *pInfo, tb_uid_t suid) {
|
||||
int32_t size = sizeof(int32_t) + sizeof(int64_t) + len;
|
||||
int32_t size = RSMA_EXEC_MSG_HLEN + len; // header + payload
|
||||
void *qItem = taosAllocateQitem(size, DEF_QITEM, 0);
|
||||
|
||||
if (!qItem) {
|
||||
|
@ -731,6 +803,8 @@ static int32_t tdExecuteRSmaImplAsync(SSma *pSma, int64_t version, const void *p
|
|||
|
||||
void *pItem = qItem;
|
||||
|
||||
*(int8_t *)pItem = (int8_t)inputType;
|
||||
pItem = POINTER_SHIFT(pItem, sizeof(int8_t));
|
||||
*(int32_t *)pItem = len;
|
||||
pItem = POINTER_SHIFT(pItem, sizeof(int32_t));
|
||||
*(int64_t *)pItem = version;
|
||||
|
@ -749,7 +823,7 @@ static int32_t tdExecuteRSmaImplAsync(SSma *pSma, int64_t version, const void *p
|
|||
}
|
||||
|
||||
// smoothing consume
|
||||
int32_t n = nItems / RSMA_QTASKEXEC_SMOOTH_SIZE;
|
||||
int32_t n = nItems / RSMA_EXEC_SMOOTH_SIZE;
|
||||
if (n > 1) {
|
||||
if (n > 10) {
|
||||
n = 10;
|
||||
|
@ -796,7 +870,7 @@ static int32_t tdRsmaPrintSubmitReq(SSma *pSma, SSubmitReq *pReq) {
|
|||
* @param level
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSize, int32_t inputType, SRSmaInfo *pInfo,
|
||||
static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSize, int64_t version, int32_t inputType, SRSmaInfo *pInfo,
|
||||
ERsmaExecType type, int8_t level) {
|
||||
int32_t idx = level - 1;
|
||||
void *qTaskInfo = RSMA_INFO_QTASK(pInfo, idx);
|
||||
|
@ -813,25 +887,15 @@ static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t msgSize,
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
smaDebug("vgId:%d, execute rsma %" PRIi8 " task for qTaskInfo:%p suid:%" PRIu64 " nMsg:%d", SMA_VID(pSma), level,
|
||||
RSMA_INFO_QTASK(pInfo, idx), pInfo->suid, msgSize);
|
||||
smaDebug("vgId:%d, execute rsma %" PRIi8 " task for qTaskInfo:%p, suid:%" PRIu64 ", nMsg:%d, submitReqVer:%" PRIi64 ", inputType:%d", SMA_VID(pSma), level,
|
||||
RSMA_INFO_QTASK(pInfo, idx), pInfo->suid, msgSize, version, inputType);
|
||||
|
||||
#if 0
|
||||
for (int32_t i = 0; i < msgSize; ++i) {
|
||||
SSubmitReq *pReq = *(SSubmitReq **)((char *)pMsg + i * sizeof(void *));
|
||||
smaDebug("vgId:%d, [%d][%d] version %" PRIi64, SMA_VID(pSma), msgSize, i, pReq->version);
|
||||
tdRsmaPrintSubmitReq(pSma, pReq);
|
||||
}
|
||||
#endif
|
||||
if ((terrno = qSetSMAInput(qTaskInfo, pMsg, msgSize, inputType)) < 0) {
|
||||
smaError("vgId:%d, rsma %" PRIi8 " qSetStreamInput failed since %s", SMA_VID(pSma), level, tstrerror(terrno));
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (STREAM_INPUT__MERGED_SUBMIT == inputType) {
|
||||
SPackedData *packData = POINTER_SHIFT(pMsg, sizeof(SPackedData) * (msgSize - 1));
|
||||
atomic_store_64(&pItem->submitReqVer, packData->ver);
|
||||
}
|
||||
atomic_store_64(&pItem->submitReqVer, version);
|
||||
|
||||
terrno = tdRSmaExecAndSubmitResult(pSma, qTaskInfo, pItem, pInfo, STREAM_NORMAL, NULL);
|
||||
|
||||
|
@ -910,7 +974,7 @@ static int32_t tdExecuteRSmaAsync(SSma *pSma, int64_t version, const void *pMsg,
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (inputType == STREAM_INPUT__DATA_SUBMIT) {
|
||||
if (inputType == STREAM_INPUT__DATA_SUBMIT || inputType == STREAM_INPUT__REF_DATA_BLOCK) {
|
||||
if (tdExecuteRSmaImplAsync(pSma, version, pMsg, len, inputType, pRSmaInfo, suid) < 0) {
|
||||
tdReleaseRSmaInfo(pSma, pRSmaInfo);
|
||||
return TSDB_CODE_FAILED;
|
||||
|
@ -937,12 +1001,8 @@ static int32_t tdExecuteRSmaAsync(SSma *pSma, int64_t version, const void *pMsg,
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tdProcessRSmaSubmit(SSma *pSma, int64_t version, void *pReq, void *pMsg, int32_t len, int32_t inputType) {
|
||||
SSmaEnv *pEnv = SMA_RSMA_ENV(pSma);
|
||||
if (!pEnv) {
|
||||
// only applicable when rsma env exists
|
||||
return TDB_CODE_SUCCESS;
|
||||
}
|
||||
int32_t tdProcessRSmaSubmit(SSma *pSma, int64_t version, void *pReq, void *pMsg, int32_t len) {
|
||||
if (!SMA_RSMA_ENV(pSma)) return TSDB_CODE_SUCCESS;
|
||||
|
||||
if ((terrno = atomic_load_32(&SMA_RSMA_STAT(pSma)->execStat))) {
|
||||
smaError("vgId:%d, failed to process rsma submit since invalid exec code: %s", SMA_VID(pSma), terrstr());
|
||||
|
@ -951,14 +1011,13 @@ int32_t tdProcessRSmaSubmit(SSma *pSma, int64_t version, void *pReq, void *pMsg,
|
|||
|
||||
STbUidStore uidStore = {0};
|
||||
|
||||
if (inputType == STREAM_INPUT__DATA_SUBMIT) {
|
||||
if (tdFetchSubmitReqSuids(pReq, &uidStore) < 0) {
|
||||
smaError("vgId:%d, failed to process rsma submit fetch suid since: %s", SMA_VID(pSma), terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (uidStore.suid != 0) {
|
||||
if (tdExecuteRSmaAsync(pSma, version, pMsg, len, inputType, uidStore.suid) < 0) {
|
||||
if (tdExecuteRSmaAsync(pSma, version, pMsg, len, STREAM_INPUT__DATA_SUBMIT, uidStore.suid) < 0) {
|
||||
smaError("vgId:%d, failed to process rsma submit exec 1 since: %s", SMA_VID(pSma), terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
@ -966,14 +1025,13 @@ int32_t tdProcessRSmaSubmit(SSma *pSma, int64_t version, void *pReq, void *pMsg,
|
|||
void *pIter = NULL;
|
||||
while ((pIter = taosHashIterate(uidStore.uidHash, pIter))) {
|
||||
tb_uid_t *pTbSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
|
||||
if (tdExecuteRSmaAsync(pSma, version, pMsg, len, inputType, *pTbSuid) < 0) {
|
||||
if (tdExecuteRSmaAsync(pSma, version, pMsg, len, STREAM_INPUT__DATA_SUBMIT, *pTbSuid) < 0) {
|
||||
smaError("vgId:%d, failed to process rsma submit exec 2 since: %s", SMA_VID(pSma), terrstr());
|
||||
taosHashCancelIterate(uidStore.uidHash, pIter);
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tdUidStoreDestory(&uidStore);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
|
@ -981,6 +1039,24 @@ _err:
|
|||
return terrno;
|
||||
}
|
||||
|
||||
int32_t tdProcessRSmaDelete(SSma *pSma, int64_t version, void *pReq, void *pMsg, int32_t len) {
|
||||
if (!SMA_RSMA_ENV(pSma)) return TSDB_CODE_SUCCESS;
|
||||
|
||||
if ((terrno = atomic_load_32(&SMA_RSMA_STAT(pSma)->execStat))) {
|
||||
smaError("vgId:%d, failed to process rsma delete since invalid exec code: %s", SMA_VID(pSma), terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
SDeleteRes *pDelRes = pReq;
|
||||
if (tdExecuteRSmaAsync(pSma, version, pMsg, len, STREAM_INPUT__REF_DATA_BLOCK, pDelRes->suid) < 0) {
|
||||
smaError("vgId:%d, failed to process rsma submit exec 1 since: %s", SMA_VID(pSma), terrstr());
|
||||
goto _err;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
return terrno;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief retrieve rsma meta and init
|
||||
*
|
||||
|
@ -1359,10 +1435,20 @@ _end:
|
|||
tdReleaseSmaRef(smaMgmt.rsetId, pRSmaRef->refId);
|
||||
}
|
||||
|
||||
static void tdFreeRSmaSubmitItems(SArray *pItems) {
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pItems); ++i) {
|
||||
SPackedData *packData = taosArrayGet(pItems, i);
|
||||
taosFreeQitem(POINTER_SHIFT(packData->msgStr, -sizeof(int32_t) - sizeof(int64_t)));
|
||||
static void tdFreeRSmaSubmitItems(SArray *pItems, int32_t type) {
|
||||
int32_t arrSize = taosArrayGetSize(pItems);
|
||||
if (type == STREAM_INPUT__MERGED_SUBMIT) {
|
||||
for (int32_t i = 0; i < arrSize; ++i) {
|
||||
SPackedData *packData = TARRAY_GET_ELEM(pItems, i);
|
||||
taosFreeQitem(POINTER_SHIFT(packData->msgStr, -RSMA_EXEC_MSG_HLEN));
|
||||
}
|
||||
} else if (type == STREAM_INPUT__REF_DATA_BLOCK) {
|
||||
for (int32_t i = 0; i < arrSize; ++i) {
|
||||
SPackedData *packData = TARRAY_GET_ELEM(pItems, i);
|
||||
blockDataDestroy(packData->pDataBlock);
|
||||
}
|
||||
} else {
|
||||
ASSERTS(0, "unknown type:%d", type);
|
||||
}
|
||||
taosArrayClear(pItems);
|
||||
}
|
||||
|
@ -1427,40 +1513,98 @@ _err:
|
|||
}
|
||||
|
||||
static int32_t tdRSmaBatchExec(SSma *pSma, SRSmaInfo *pInfo, STaosQall *qall, SArray *pSubmitArr, ERsmaExecType type) {
|
||||
taosArrayClear(pSubmitArr);
|
||||
while (1) {
|
||||
void *msg = NULL;
|
||||
int8_t resume = 0;
|
||||
int32_t nSubmit = 0;
|
||||
int32_t nDelete = 0;
|
||||
int64_t version = 0;
|
||||
|
||||
SPackedData packData;
|
||||
|
||||
taosArrayClear(pSubmitArr);
|
||||
|
||||
// the submitReq/deleteReq msg may exsit alternately in the msg queue, consume them sequentially in batch mode
|
||||
while (1) {
|
||||
taosGetQitem(qall, (void **)&msg);
|
||||
if (msg) {
|
||||
SPackedData packData = {.msgLen = *(int32_t *)msg,
|
||||
.ver = *(int64_t *)POINTER_SHIFT(msg, sizeof(int32_t)),
|
||||
.msgStr = POINTER_SHIFT(msg, sizeof(int32_t) + sizeof(int64_t))};
|
||||
|
||||
int8_t inputType = RSMA_EXEC_MSG_TYPE(msg);
|
||||
if (inputType == STREAM_INPUT__DATA_SUBMIT) {
|
||||
if (nDelete > 0) {
|
||||
resume = 1;
|
||||
break;
|
||||
}
|
||||
_resume_submit:
|
||||
packData.msgLen = RSMA_EXEC_MSG_LEN(msg);
|
||||
packData.ver = RSMA_EXEC_MSG_VER(msg);
|
||||
packData.msgStr = RSMA_EXEC_MSG_BODY(msg);
|
||||
version = packData.ver;
|
||||
if (!taosArrayPush(pSubmitArr, &packData)) {
|
||||
taosFreeQitem(msg);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tdFreeRSmaSubmitItems(pSubmitArr);
|
||||
goto _err;
|
||||
}
|
||||
++nSubmit;
|
||||
} else if (inputType == STREAM_INPUT__REF_DATA_BLOCK) {
|
||||
if (nSubmit > 0) {
|
||||
resume = 2;
|
||||
break;
|
||||
}
|
||||
_resume_delete:
|
||||
version = RSMA_EXEC_MSG_VER(msg);
|
||||
if ((terrno = extractDelDataBlock(RSMA_EXEC_MSG_BODY(msg), RSMA_EXEC_MSG_LEN(msg), version,
|
||||
&packData.pDataBlock, 1))) {
|
||||
taosFreeQitem(msg);
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (packData.pDataBlock && !taosArrayPush(pSubmitArr, &packData)) {
|
||||
taosFreeQitem(msg);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
taosFreeQitem(msg);
|
||||
if (packData.pDataBlock) {
|
||||
// packData.pDataBlock is NULL if delete affects 0 row
|
||||
++nDelete;
|
||||
}
|
||||
} else {
|
||||
ASSERTS(0, "unknown msg type:%d", inputType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t size = taosArrayGetSize(pSubmitArr);
|
||||
if (size > 0) {
|
||||
if (nSubmit > 0 || nDelete > 0) {
|
||||
int32_t size = TARRAY_SIZE(pSubmitArr);
|
||||
ASSERTS(size > 0, "size is %d", size);
|
||||
int32_t inputType = nSubmit > 0 ? STREAM_INPUT__MERGED_SUBMIT : STREAM_INPUT__REF_DATA_BLOCK;
|
||||
for (int32_t i = 1; i <= TSDB_RETENTION_L2; ++i) {
|
||||
if (tdExecuteRSmaImpl(pSma, pSubmitArr->pData, size, STREAM_INPUT__MERGED_SUBMIT, pInfo, type, i) < 0) {
|
||||
if (tdExecuteRSmaImpl(pSma, pSubmitArr->pData, size, version, inputType, pInfo, type, i) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
tdFreeRSmaSubmitItems(pSubmitArr);
|
||||
tdFreeRSmaSubmitItems(pSubmitArr, inputType);
|
||||
nSubmit = 0;
|
||||
nDelete = 0;
|
||||
} else {
|
||||
goto _rtn;
|
||||
}
|
||||
|
||||
if (resume == 1) {
|
||||
resume = 0;
|
||||
goto _resume_submit;
|
||||
} else if (resume == 2) {
|
||||
resume = 0;
|
||||
goto _resume_delete;
|
||||
}
|
||||
}
|
||||
|
||||
_rtn:
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
atomic_store_32(&SMA_RSMA_STAT(pSma)->execStat, terrno);
|
||||
smaError("vgId:%d, batch exec for suid:%" PRIi64 " execType:%d size:%d failed since %s", SMA_VID(pSma), pInfo->suid,
|
||||
type, (int32_t)taosArrayGetSize(pSubmitArr), terrstr());
|
||||
tdFreeRSmaSubmitItems(pSubmitArr);
|
||||
tdFreeRSmaSubmitItems(pSubmitArr, nSubmit ? STREAM_INPUT__MERGED_SUBMIT : STREAM_INPUT__REF_DATA_BLOCK);
|
||||
while (1) {
|
||||
void *msg = NULL;
|
||||
taosGetQitem(qall, (void **)&msg);
|
||||
|
@ -1497,7 +1641,7 @@ int32_t tdRSmaProcessExecImpl(SSma *pSma, ERsmaExecType type) {
|
|||
}
|
||||
|
||||
if (!(pSubmitArr =
|
||||
taosArrayInit(TMIN(RSMA_SUBMIT_BATCH_SIZE, atomic_load_64(&pRSmaStat->nBufItems)), sizeof(SPackedData)))) {
|
||||
taosArrayInit(TMIN(RSMA_EXEC_BATCH_SIZE, atomic_load_64(&pRSmaStat->nBufItems)), sizeof(SPackedData)))) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
|
|
@ -188,7 +188,8 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
|||
if (pDataBlock->info.type == STREAM_DELETE_RESULT) {
|
||||
pDeleteReq->suid = suid;
|
||||
pDeleteReq->deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq));
|
||||
tqBuildDeleteReq(stbFullName, pDataBlock, pDeleteReq, "");
|
||||
code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, pDeleteReq, "");
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1105,10 +1105,6 @@ static void doStartFillhistoryStep2(SStreamTask* pTask, SStreamTask* pStreamTask
|
|||
}
|
||||
}
|
||||
|
||||
static void ddxx() {
|
||||
|
||||
}
|
||||
|
||||
// this function should be executed by only one thread, so we set an sentinel to protect this function
|
||||
int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
||||
SStreamScanHistoryReq* pReq = (SStreamScanHistoryReq*)pMsg->pCont;
|
||||
|
@ -1155,7 +1151,9 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
|||
tqDebug("s-task:%s continue exec scan-history(step1), original step1 startTs:%" PRId64 ", already elapsed:%.2fs",
|
||||
id, pTask->execInfo.step1Start, pTask->execInfo.step1El);
|
||||
} else {
|
||||
tqDebug("s-task:%s already in step2, no need to scan-history data, step2 starTs:%"PRId64, id, pTask->execInfo.step2Start);
|
||||
tqDebug("s-task:%s already in step2, no need to scan-history data, step2 startTs:%" PRId64, id,
|
||||
pTask->execInfo.step2Start);
|
||||
|
||||
atomic_store_32(&pTask->status.inScanHistorySentinel, 0);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return 0;
|
||||
|
|
|
@ -343,7 +343,7 @@ int32_t extractMsgFromWal(SWalReader* pReader, void** pItem, int64_t maxVer, con
|
|||
void* pBody = POINTER_SHIFT(pCont->body, sizeof(SMsgHead));
|
||||
int32_t len = pCont->bodyLen - sizeof(SMsgHead);
|
||||
|
||||
code = extractDelDataBlock(pBody, len, ver, (SStreamRefDataBlock**)pItem);
|
||||
code = extractDelDataBlock(pBody, len, ver, (void**)pItem, 0);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
if (*pItem == NULL) {
|
||||
tqDebug("s-task:%s empty delete msg, discard it, len:%d, ver:%" PRId64, id, len, ver);
|
||||
|
|
|
@ -43,7 +43,7 @@ static SArray* createDefaultTagColName();
|
|||
static void setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDataBlock, const char* stbFullName,
|
||||
int64_t gid);
|
||||
|
||||
int32_t tqBuildDeleteReq(const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq,
|
||||
int32_t tqBuildDeleteReq(STQ* pTq, const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq,
|
||||
const char* pIdStr) {
|
||||
int32_t totalRows = pDataBlock->info.rows;
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pDataBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
|
@ -58,7 +58,8 @@ int32_t tqBuildDeleteReq(const char* stbFullName, const SSDataBlock* pDataBlock,
|
|||
int64_t ekey = *(int64_t*)colDataGetData(pEndTsCol, row);
|
||||
int64_t groupId = *(int64_t*)colDataGetData(pGidCol, row);
|
||||
|
||||
char* name;
|
||||
char* name = NULL;
|
||||
char* originName = NULL;
|
||||
void* varTbName = NULL;
|
||||
if (!colDataIsNull(pTbNameCol, totalRows, row, NULL)) {
|
||||
varTbName = colDataGetVarData(pTbNameCol, row);
|
||||
|
@ -67,19 +68,30 @@ int32_t tqBuildDeleteReq(const char* stbFullName, const SSDataBlock* pDataBlock,
|
|||
if (varTbName != NULL && varTbName != (void*)-1) {
|
||||
name = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN);
|
||||
memcpy(name, varDataVal(varTbName), varDataLen(varTbName));
|
||||
} else {
|
||||
} else if (stbFullName) {
|
||||
name = buildCtbNameByGroupId(stbFullName, groupId);
|
||||
} else {
|
||||
originName = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE);
|
||||
if (metaGetTableNameByUid(pTq->pVnode, groupId, originName) == 0) {
|
||||
name = varDataVal(originName);
|
||||
}
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s build delete msg groupId:%" PRId64 ", name:%s, skey:%" PRId64 " ekey:%" PRId64,
|
||||
pIdStr, groupId, name, skey, ekey);
|
||||
if (!name || *name == '\0') {
|
||||
tqWarn("s-task:%s failed to build delete msg groupId:%" PRId64 ", skey:%" PRId64 " ekey:%" PRId64
|
||||
" since invalid tbname:%s",
|
||||
pIdStr, groupId, skey, ekey, name ? name : "NULL");
|
||||
} else {
|
||||
tqDebug("s-task:%s build delete msg groupId:%" PRId64 ", name:%s, skey:%" PRId64 " ekey:%" PRId64, pIdStr,
|
||||
groupId, name, skey, ekey);
|
||||
|
||||
SSingleDeleteReq req = { .startTs = skey, .endTs = ekey};
|
||||
SSingleDeleteReq req = {.startTs = skey, .endTs = ekey};
|
||||
strncpy(req.tbname, name, TSDB_TABLE_NAME_LEN - 1);
|
||||
taosMemoryFree(name);
|
||||
|
||||
taosArrayPush(deleteReq->deleteReqs, &req);
|
||||
}
|
||||
if (originName) name = originName;
|
||||
taosMemoryFreeClear(name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -345,7 +357,7 @@ int32_t doBuildAndSendDeleteMsg(SVnode* pVnode, char* stbFullName, SSDataBlock*
|
|||
int64_t suid) {
|
||||
SBatchDeleteReq deleteReq = {.suid = suid, .deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq))};
|
||||
|
||||
int32_t code = tqBuildDeleteReq(stbFullName, pDataBlock, &deleteReq, pTask->id.idStr);
|
||||
int32_t code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, &deleteReq, pTask->id.idStr);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ int32_t tqRestartStreamTasks(STQ* pTq) {
|
|||
streamMetaInitBackend(pMeta);
|
||||
int64_t el = taosGetTimestampMs() - st;
|
||||
|
||||
tqInfo("vgId:%d close&reload state elapsed time:%.3fms", vgId, el/1000.);
|
||||
tqInfo("vgId:%d close&reload state elapsed time:%.3fs", vgId, el/1000.);
|
||||
|
||||
code = streamMetaLoadAllTasks(pTq->pStreamMeta);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -168,12 +168,15 @@ int32_t tqRestartStreamTasks(STQ* pTq) {
|
|||
if (vnodeIsRoleLeader(pTq->pVnode) && !tsDisableStream) {
|
||||
tqInfo("vgId:%d restart all stream tasks after all tasks being updated", vgId);
|
||||
tqResetStreamTaskStatus(pTq);
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
tqStartStreamTasks(pTq);
|
||||
} else {
|
||||
streamMetaResetStartInfo(&pMeta->startInfo);
|
||||
streamMetaWUnLock(pMeta);
|
||||
tqInfo("vgId:%d, follower node not start stream tasks", vgId);
|
||||
}
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
code = terrno;
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -212,9 +212,7 @@ int32_t streamTaskSnapWriterClose(SStreamTaskWriter* pWriter, int8_t rollback) {
|
|||
taosMemoryFree(pWriter);
|
||||
goto _err;
|
||||
}
|
||||
|
||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||
|
||||
taosMemoryFree(pWriter);
|
||||
return code;
|
||||
|
||||
|
|
|
@ -399,7 +399,7 @@ int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp*
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, SStreamRefDataBlock** pRefBlock) {
|
||||
int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, void** pRefBlock, int32_t type) {
|
||||
SDecoder* pCoder = &(SDecoder){0};
|
||||
SDeleteRes* pRes = &(SDeleteRes){0};
|
||||
|
||||
|
@ -442,6 +442,7 @@ int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, SStream
|
|||
}
|
||||
|
||||
taosArrayDestroy(pRes->uidList);
|
||||
if (type == 0) {
|
||||
*pRefBlock = taosAllocateQitem(sizeof(SStreamRefDataBlock), DEF_QITEM, 0);
|
||||
if (*pRefBlock == NULL) {
|
||||
blockDataCleanup(pDelBlock);
|
||||
|
@ -449,7 +450,13 @@ int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, SStream
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
(*pRefBlock)->type = STREAM_INPUT__REF_DATA_BLOCK;
|
||||
(*pRefBlock)->pBlock = pDelBlock;
|
||||
((SStreamRefDataBlock*)(*pRefBlock))->type = STREAM_INPUT__REF_DATA_BLOCK;
|
||||
((SStreamRefDataBlock*)(*pRefBlock))->pBlock = pDelBlock;
|
||||
} else if (type == 1) {
|
||||
*pRefBlock = pDelBlock;
|
||||
} else {
|
||||
ASSERTS(0, "unknown type:%d", type);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -409,7 +409,6 @@ static int32_t tsdbCommitFileSetBegin(SCommitter2 *committer) {
|
|||
extern int32_t tsS3UploadDelaySec;
|
||||
long s3Size(const char *object_name);
|
||||
int32_t nlevel = tfsGetLevel(committer->tsdb->pVnode->pTfs);
|
||||
committer->ctx->skipTsRow = false;
|
||||
if (tsS3Enabled && nlevel > 1 && committer->ctx->fset) {
|
||||
STFileObj *fobj = committer->ctx->fset->farr[TSDB_FTYPE_DATA];
|
||||
if (fobj && fobj->f->did.level == nlevel - 1) {
|
||||
|
|
|
@ -879,14 +879,43 @@ int32_t tsdbFSEditCommit(STFileSystem *fs) {
|
|||
continue;
|
||||
}
|
||||
|
||||
bool skipMerge = false;
|
||||
int32_t numFile = TARRAY2_SIZE(lvl->fobjArr);
|
||||
if (numFile >= sttTrigger) {
|
||||
// launch merge
|
||||
{
|
||||
extern int8_t tsS3Enabled;
|
||||
extern int32_t tsS3UploadDelaySec;
|
||||
long s3Size(const char *object_name);
|
||||
int32_t nlevel = tfsGetLevel(fs->tsdb->pVnode->pTfs);
|
||||
if (tsS3Enabled && nlevel > 1) {
|
||||
STFileObj *fobj = fset->farr[TSDB_FTYPE_DATA];
|
||||
if (fobj && fobj->f->did.level == nlevel - 1) {
|
||||
// if exists on s3 or local mtime < committer->ctx->now - tsS3UploadDelay
|
||||
const char *object_name = taosDirEntryBaseName((char *)fobj->fname);
|
||||
|
||||
if (taosCheckExistFile(fobj->fname)) {
|
||||
int32_t now = taosGetTimestampSec();
|
||||
int32_t mtime = 0;
|
||||
taosStatFile(fobj->fname, NULL, &mtime, NULL);
|
||||
if (mtime < now - tsS3UploadDelaySec) {
|
||||
skipMerge = true;
|
||||
}
|
||||
} else if (s3Size(object_name) > 0) {
|
||||
skipMerge = true;
|
||||
}
|
||||
}
|
||||
// new fset can be written with ts data
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipMerge) {
|
||||
code = tsdbSchedMerge(fs->tsdb, fset->fid);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
}
|
||||
|
||||
if (numFile >= sttTrigger * BLOCK_COMMIT_FACTOR) {
|
||||
if (numFile >= sttTrigger * BLOCK_COMMIT_FACTOR && !skipMerge) {
|
||||
tsdbFSSetBlockCommit(fset, true);
|
||||
} else {
|
||||
tsdbFSSetBlockCommit(fset, false);
|
||||
|
|
|
@ -50,6 +50,7 @@ void remove_file(const char *fname, bool last_level) {
|
|||
long s3_size = tsS3Enabled ? s3Size(object_name) : 0;
|
||||
if (!strncmp(fname + strlen(fname) - 5, ".data", 5) && s3_size > 0) {
|
||||
s3DeleteObjects(&object_name, 1);
|
||||
tsdbInfo("file:%s is removed from s3", fname);
|
||||
} else {
|
||||
tsdbError("file:%s remove failed", fname);
|
||||
}
|
||||
|
|
|
@ -548,6 +548,36 @@ static int32_t tsdbMerge(void *arg) {
|
|||
|
||||
if (merger->fset == NULL) return 0;
|
||||
|
||||
bool skipMerge = false;
|
||||
{
|
||||
extern int8_t tsS3Enabled;
|
||||
extern int32_t tsS3UploadDelaySec;
|
||||
long s3Size(const char *object_name);
|
||||
int32_t nlevel = tfsGetLevel(merger->tsdb->pVnode->pTfs);
|
||||
if (tsS3Enabled && nlevel > 1) {
|
||||
STFileObj *fobj = merger->fset->farr[TSDB_FTYPE_DATA];
|
||||
if (fobj && fobj->f->did.level == nlevel - 1) {
|
||||
// if exists on s3 or local mtime < committer->ctx->now - tsS3UploadDelay
|
||||
const char *object_name = taosDirEntryBaseName((char *)fobj->fname);
|
||||
|
||||
if (taosCheckExistFile(fobj->fname)) {
|
||||
int32_t now = taosGetTimestampSec();
|
||||
int32_t mtime = 0;
|
||||
|
||||
taosStatFile(fobj->fname, NULL, &mtime, NULL);
|
||||
if (mtime < now - tsS3UploadDelaySec) {
|
||||
skipMerge = true;
|
||||
}
|
||||
} else if (s3Size(object_name) > 0) {
|
||||
skipMerge = true;
|
||||
}
|
||||
}
|
||||
// new fset can be written with ts data
|
||||
}
|
||||
}
|
||||
|
||||
if (skipMerge) return 0;
|
||||
|
||||
// do merge
|
||||
tsdbDebug("vgId:%d merge begin, fid:%d", TD_VID(tsdb->pVnode), merger->fid);
|
||||
code = tsdbDoMerge(merger);
|
||||
|
|
|
@ -524,7 +524,7 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN
|
|||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
// clear info for the new file
|
||||
cleanupInfoFoxNextFileset(pReader->status.pTableMap);
|
||||
cleanupInfoForNextFileset(pReader->status.pTableMap);
|
||||
|
||||
int32_t k = 0;
|
||||
int32_t numOfTables = tSimpleHashGetSize(pReader->status.pTableMap);
|
||||
|
@ -1444,7 +1444,9 @@ static bool nextRowFromSttBlocks(SLastBlockReader* pLastBlockReader, STableBlock
|
|||
}
|
||||
}
|
||||
|
||||
static void doPinSttBlock(SLastBlockReader* pLastBlockReader) { tMergeTreePinSttBlock(&pLastBlockReader->mergeTree); }
|
||||
static void doPinSttBlock(SLastBlockReader* pLastBlockReader) {
|
||||
tMergeTreePinSttBlock(&pLastBlockReader->mergeTree);
|
||||
}
|
||||
|
||||
static void doUnpinSttBlock(SLastBlockReader* pLastBlockReader) {
|
||||
tMergeTreeUnpinSttBlock(&pLastBlockReader->mergeTree);
|
||||
|
@ -1454,7 +1456,6 @@ static bool tryCopyDistinctRowFromSttBlock(TSDBROW* fRow, SLastBlockReader* pLas
|
|||
STableBlockScanInfo* pScanInfo, int64_t ts, STsdbReader* pReader,
|
||||
bool* copied) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
*copied = false;
|
||||
|
||||
// avoid the fetch next row replace the referenced stt block in buffer
|
||||
|
@ -1540,12 +1541,6 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
if (ps == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
int32_t code = tsdbRowMergerInit(pMerger, ps);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tsdbError("failed to init row merger, code:%s", tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t minKey = 0;
|
||||
|
@ -1688,7 +1683,7 @@ static int32_t doMergeFileBlockAndLastBlock(SLastBlockReader* pLastBlockReader,
|
|||
tsdbTrace("fRow ptr:%p, %d, uid:%" PRIu64 ", ts:%" PRId64 " %s", pRow->pBlockData, pRow->iRow, pLastBlockReader->uid,
|
||||
fRow.pBlockData->aTSKEY[fRow.iRow], pReader->idStr);
|
||||
|
||||
// only last block exists
|
||||
// only stt block exists
|
||||
if ((!mergeBlockData) || (tsLastBlock != pBlockData->aTSKEY[pDumpInfo->rowIndex])) {
|
||||
code = tryCopyDistinctRowFromSttBlock(&fRow, pLastBlockReader, pBlockScanInfo, tsLastBlock, pReader, &copied);
|
||||
if (code) {
|
||||
|
@ -1767,12 +1762,6 @@ static int32_t mergeFileBlockAndLastBlock(STsdbReader* pReader, SLastBlockReader
|
|||
if (ps == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
int32_t code = tsdbRowMergerInit(pMerger, ps);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tsdbError("failed to init row merger, code:%s", tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDataInFileBlock(pBlockData, pDumpInfo)) {
|
||||
|
@ -1874,12 +1863,6 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
if (ps == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
code = tsdbRowMergerInit(pMerger, ps);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tsdbError("failed to init row merger, code:%s", tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t minKey = 0;
|
||||
|
@ -2202,12 +2185,6 @@ int32_t mergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pBloc
|
|||
if (ps == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
code = tsdbRowMergerInit(pMerger, ps);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tsdbError("failed to init row merger, code:%s", tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
if (copied) {
|
||||
|
|
|
@ -245,7 +245,7 @@ static void doCleanupInfoForNextFileset(STableBlockScanInfo* pScanInfo) {
|
|||
pScanInfo->sttKeyInfo.status = STT_FILE_READER_UNINIT;
|
||||
}
|
||||
|
||||
void cleanupInfoFoxNextFileset(SSHashObj* pTableMap) {
|
||||
void cleanupInfoForNextFileset(SSHashObj* pTableMap) {
|
||||
STableBlockScanInfo** p = NULL;
|
||||
|
||||
int32_t iter = 0;
|
||||
|
|
|
@ -248,7 +248,7 @@ SSHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf* pBuf
|
|||
void clearBlockScanInfo(STableBlockScanInfo* p);
|
||||
void destroyAllBlockScanInfo(SSHashObj* pTableMap);
|
||||
void resetAllDataBlockScanInfo(SSHashObj* pTableMap, int64_t ts, int32_t step);
|
||||
void cleanupInfoFoxNextFileset(SSHashObj* pTableMap);
|
||||
void cleanupInfoForNextFileset(SSHashObj* pTableMap);
|
||||
int32_t ensureBlockScanInfoBuf(SBlockInfoBuf* pBuf, int32_t numOfTables);
|
||||
void clearBlockScanInfoBuf(SBlockInfoBuf* pBuf);
|
||||
void* getPosInBlockInfoBuf(SBlockInfoBuf* pBuf, int32_t index);
|
||||
|
|
|
@ -74,6 +74,8 @@ static int32_t tsdbDoCopyFile(SRTNer *rtner, const STFileObj *from, const STFile
|
|||
if (fdFrom == NULL) code = terrno;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
tsdbInfo("vgId: %d, open tofile: %s size: %" PRId64, TD_VID(rtner->tsdb->pVnode), fname, from->f->size);
|
||||
|
||||
fdTo = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
|
||||
if (fdTo == NULL) code = terrno;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
@ -101,7 +103,7 @@ static int32_t tsdbCopyFileS3(SRTNer *rtner, const STFileObj *from, const STFile
|
|||
|
||||
char fname[TSDB_FILENAME_LEN];
|
||||
TdFilePtr fdFrom = NULL;
|
||||
TdFilePtr fdTo = NULL;
|
||||
// TdFilePtr fdTo = NULL;
|
||||
|
||||
tsdbTFileName(rtner->tsdb, to, fname);
|
||||
|
||||
|
@ -333,6 +335,7 @@ static int32_t tsdbDoRetentionOnFileSet(SRTNer *rtner, STFileSet *fset) {
|
|||
int32_t mtime = 0;
|
||||
taosStatFile(fobj->fname, NULL, &mtime, NULL);
|
||||
if (mtime < rtner->now - tsS3UploadDelaySec) {
|
||||
tsdbInfo("file:%s size: %" PRId64 " do migrate s3", fobj->fname, fobj->f->size);
|
||||
code = tsdbMigrateDataFileS3(rtner, fobj, &did);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
@ -356,6 +359,12 @@ static int32_t tsdbDoRetentionOnFileSet(SRTNer *rtner, STFileSet *fset) {
|
|||
s3EvictCache(fobj->fname, fsize * 2);
|
||||
}
|
||||
*/
|
||||
if (fobj->f->did.level > did.level) {
|
||||
continue;
|
||||
}
|
||||
tsdbInfo("file:%s size: %" PRId64 " do migrate from %d to %d", fobj->fname, fobj->f->size, fobj->f->did.level,
|
||||
did.level);
|
||||
|
||||
code = tsdbDoMigrateFileObj(rtner, fobj, &did);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
//}
|
||||
|
@ -375,14 +384,6 @@ static int32_t tsdbDoRetentionOnFileSet(SRTNer *rtner, STFileSet *fset) {
|
|||
|
||||
_exit:
|
||||
if (code) {
|
||||
if (TARRAY2_DATA(rtner->fopArr)) {
|
||||
TARRAY2_DESTROY(rtner->fopArr, NULL);
|
||||
}
|
||||
TFileSetArray **fsetArr = &rtner->fsetArr;
|
||||
if (fsetArr[0]) {
|
||||
tsdbFSDestroyCopySnapshot(&rtner->fsetArr);
|
||||
}
|
||||
|
||||
TSDB_ERROR_LOG(TD_VID(rtner->tsdb->pVnode), lino, code);
|
||||
}
|
||||
return code;
|
||||
|
@ -437,13 +438,19 @@ static int32_t tsdbDoRetentionAsync(void *arg) {
|
|||
|
||||
_exit:
|
||||
if (code) {
|
||||
if (TARRAY2_DATA(rtner->fopArr)) {
|
||||
TARRAY2_DESTROY(rtner->fopArr, NULL);
|
||||
}
|
||||
TFileSetArray **fsetArr = &rtner->fsetArr;
|
||||
if (fsetArr[0]) {
|
||||
tsdbFSDestroyCopySnapshot(&rtner->fsetArr);
|
||||
}
|
||||
|
||||
TSDB_ERROR_LOG(TD_VID(rtner->tsdb->pVnode), lino, code);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t tsdbRetention(STsdb *tsdb, int64_t now, int32_t sync) {
|
||||
int32_t code = 0;
|
||||
|
||||
|
|
|
@ -180,6 +180,7 @@ void initStateStoreAPI(SStateStore* pStore) {
|
|||
pStore->streamStateSessionGetKVByCur = streamStateSessionGetKVByCur;
|
||||
pStore->streamStateStateAddIfNotExist = streamStateStateAddIfNotExist;
|
||||
pStore->streamStateSessionGetKeyByRange = streamStateSessionGetKeyByRange;
|
||||
pStore->streamStateSessionAllocWinBuffByNextPosition = streamStateSessionAllocWinBuffByNextPosition;
|
||||
|
||||
pStore->updateInfoInit = updateInfoInit;
|
||||
pStore->updateInfoFillBlockData = updateInfoFillBlockData;
|
||||
|
|
|
@ -21,13 +21,17 @@
|
|||
#include "cos.h"
|
||||
#include "vnode.h"
|
||||
#include "vnodeInt.h"
|
||||
#include "audit.h"
|
||||
#include "tstrbuild.h"
|
||||
|
||||
static int32_t vnodeProcessCreateStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessAlterStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessDropStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginRpc);
|
||||
static int32_t vnodeProcessAlterTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginRpc);
|
||||
static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessCreateTSmaReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessAlterConfirmReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
|
@ -380,7 +384,7 @@ static int32_t vnodePreProcessDeleteMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
SEncoder *pCoder = &(SEncoder){0};
|
||||
SDeleteRes res = {0};
|
||||
|
||||
SReadHandle handle = {.vnode = pVnode, .pMsgCb = &pVnode->msgCb};
|
||||
SReadHandle handle = {.vnode = pVnode, .pMsgCb = &pVnode->msgCb, .skipRollup = 1};
|
||||
initStorageAPI(&handle.api);
|
||||
|
||||
code = qWorkerProcessDeleteMsg(&handle, pVnode->pQuery, pMsg, &res);
|
||||
|
@ -509,13 +513,13 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t ver, SRpcMsg
|
|||
if (vnodeProcessDropStbReq(pVnode, ver, pReq, len, pRsp) < 0) goto _err;
|
||||
break;
|
||||
case TDMT_VND_CREATE_TABLE:
|
||||
if (vnodeProcessCreateTbReq(pVnode, ver, pReq, len, pRsp) < 0) goto _err;
|
||||
if (vnodeProcessCreateTbReq(pVnode, ver, pReq, len, pRsp, pMsg) < 0) goto _err;
|
||||
break;
|
||||
case TDMT_VND_ALTER_TABLE:
|
||||
if (vnodeProcessAlterTbReq(pVnode, ver, pReq, len, pRsp) < 0) goto _err;
|
||||
break;
|
||||
case TDMT_VND_DROP_TABLE:
|
||||
if (vnodeProcessDropTbReq(pVnode, ver, pReq, len, pRsp) < 0) goto _err;
|
||||
if (vnodeProcessDropTbReq(pVnode, ver, pReq, len, pRsp, pMsg) < 0) goto _err;
|
||||
break;
|
||||
case TDMT_VND_DROP_TTL_TABLE:
|
||||
if (vnodeProcessDropTtlTbReq(pVnode, ver, pReq, len, pRsp) < 0) goto _err;
|
||||
|
@ -878,7 +882,8 @@ _err:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginRpc) {
|
||||
SDecoder decoder = {0};
|
||||
SEncoder encoder = {0};
|
||||
int32_t rcode = 0;
|
||||
|
@ -928,7 +933,7 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq,
|
|||
goto _exit;
|
||||
}
|
||||
|
||||
if(tsEnableAuditCreateTable){
|
||||
if(tsEnableAudit && tsEnableAuditCreateTable){
|
||||
char* str = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN);
|
||||
if (str == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -983,7 +988,7 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq,
|
|||
tEncoderInit(&encoder, pRsp->pCont, pRsp->contLen);
|
||||
tEncodeSVCreateTbBatchRsp(&encoder, &rsp);
|
||||
|
||||
if (tsEnableAuditCreateTable) {
|
||||
if(tsEnableAudit && tsEnableAuditCreateTable){
|
||||
int64_t clusterId = pVnode->config.syncCfg.nodeInfo[0].clusterId;
|
||||
|
||||
SName name = {0};
|
||||
|
@ -1000,9 +1005,11 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq,
|
|||
}
|
||||
|
||||
size_t len = 0;
|
||||
char *keyJoined = taosStringBuilderGetResult(&sb, &len);
|
||||
char* keyJoined = taosStringBuilderGetResult(&sb, &len);
|
||||
|
||||
auditRecord(NULL, clusterId, "createTable", name.dbname, "", keyJoined, len);
|
||||
if(pOriginRpc->info.conn.user != NULL && strlen(pOriginRpc->info.conn.user) > 0){
|
||||
auditRecord(pOriginRpc, clusterId, "createTable", name.dbname, "", keyJoined, len);
|
||||
}
|
||||
|
||||
taosStringBuilderDestroy(&sb);
|
||||
}
|
||||
|
@ -1144,7 +1151,8 @@ _exit:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginRpc) {
|
||||
SVDropTbBatchReq req = {0};
|
||||
SVDropTbBatchRsp rsp = {0};
|
||||
SDecoder decoder = {0};
|
||||
|
@ -1223,7 +1231,9 @@ static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, in
|
|||
size_t len = 0;
|
||||
char *keyJoined = taosStringBuilderGetResult(&sb, &len);
|
||||
|
||||
auditRecord(NULL, clusterId, "dropTable", name.dbname, "", keyJoined, len);
|
||||
if(pOriginRpc->info.conn.user != NULL && strlen(pOriginRpc->info.conn.user) > 0){
|
||||
auditRecord(pOriginRpc, clusterId, "dropTable", name.dbname, "", keyJoined, len);
|
||||
}
|
||||
|
||||
taosStringBuilderDestroy(&sb);
|
||||
}
|
||||
|
@ -1674,7 +1684,7 @@ _exit:
|
|||
atomic_add_fetch_64(&pVnode->statis.nBatchInsert, 1);
|
||||
if (code == 0) {
|
||||
atomic_add_fetch_64(&pVnode->statis.nBatchInsertSuccess, 1);
|
||||
code = tdProcessRSmaSubmit(pVnode->pSma, ver, pSubmitReq, pReq, len, STREAM_INPUT__DATA_SUBMIT);
|
||||
code = tdProcessRSmaSubmit(pVnode->pSma, ver, pSubmitReq, pReq, len);
|
||||
}
|
||||
|
||||
// clear
|
||||
|
@ -1891,6 +1901,11 @@ static int32_t vnodeProcessBatchDeleteReq(SVnode *pVnode, int64_t ver, void *pRe
|
|||
|
||||
SMetaReader mr = {0};
|
||||
metaReaderDoInit(&mr, pVnode->pMeta, META_READER_NOLOCK);
|
||||
STsdb *pTsdb = pVnode->pTsdb;
|
||||
|
||||
if (deleteReq.level) {
|
||||
pTsdb = deleteReq.level == 1 ? VND_RSMA1(pVnode) : VND_RSMA2(pVnode);
|
||||
}
|
||||
|
||||
int32_t sz = taosArrayGetSize(deleteReq.deleteReqs);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
|
@ -1903,13 +1918,14 @@ static int32_t vnodeProcessBatchDeleteReq(SVnode *pVnode, int64_t ver, void *pRe
|
|||
|
||||
int64_t uid = mr.me.uid;
|
||||
|
||||
int32_t code = tsdbDeleteTableData(pVnode->pTsdb, ver, deleteReq.suid, uid, pOneReq->startTs, pOneReq->endTs);
|
||||
int32_t code = tsdbDeleteTableData(pTsdb, ver, deleteReq.suid, uid, pOneReq->startTs, pOneReq->endTs);
|
||||
if (code < 0) {
|
||||
terrno = code;
|
||||
vError("vgId:%d, delete error since %s, suid:%" PRId64 ", uid:%" PRId64 ", start ts:%" PRId64 ", end ts:%" PRId64,
|
||||
TD_VID(pVnode), terrstr(), deleteReq.suid, uid, pOneReq->startTs, pOneReq->endTs);
|
||||
}
|
||||
|
||||
if (deleteReq.level == 0) {
|
||||
code = metaUpdateChangeTimeWithLock(pVnode->pMeta, uid, deleteReq.ctimeMs);
|
||||
if (code < 0) {
|
||||
terrno = code;
|
||||
|
@ -1917,7 +1933,7 @@ static int32_t vnodeProcessBatchDeleteReq(SVnode *pVnode, int64_t ver, void *pRe
|
|||
", end ts:%" PRId64,
|
||||
TD_VID(pVnode), terrstr(), deleteReq.suid, uid, pOneReq->startTs, pOneReq->endTs);
|
||||
}
|
||||
|
||||
}
|
||||
tDecoderClear(&mr.coder);
|
||||
}
|
||||
metaReaderClear(&mr);
|
||||
|
@ -1952,6 +1968,8 @@ static int32_t vnodeProcessDeleteReq(SVnode *pVnode, int64_t ver, void *pReq, in
|
|||
if (code) goto _err;
|
||||
}
|
||||
|
||||
code = tdProcessRSmaDelete(pVnode->pSma, ver, pRes, pReq, len);
|
||||
|
||||
tDecoderClear(pCoder);
|
||||
taosArrayDestroy(pRes->uidList);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ extern "C" {
|
|||
#define EXPLAIN_TABLE_COUNT_SCAN_FORMAT "Table Count Row Scan on %s"
|
||||
#define EXPLAIN_PROJECTION_FORMAT "Projection"
|
||||
#define EXPLAIN_JOIN_FORMAT "%s"
|
||||
#define EXPLAIN_AGG_FORMAT "Aggragate"
|
||||
#define EXPLAIN_AGG_FORMAT "%s"
|
||||
#define EXPLAIN_INDEF_ROWS_FORMAT "Indefinite Rows Function"
|
||||
#define EXPLAIN_EXCHANGE_FORMAT "Data Exchange %d:1"
|
||||
#define EXPLAIN_SORT_FORMAT "Sort"
|
||||
|
@ -59,7 +59,7 @@ extern "C" {
|
|||
#define EXPLAIN_TIME_WINDOWS_FORMAT "Time Window: interval=%" PRId64 "%c offset=%" PRId64 "%c sliding=%" PRId64 "%c"
|
||||
#define EXPLAIN_WINDOW_FORMAT "Window: gap=%" PRId64
|
||||
#define EXPLAIN_RATIO_TIME_FORMAT "Ratio: %f"
|
||||
#define EXPLAIN_MERGE_FORMAT "SortMerge"
|
||||
#define EXPLAIN_MERGE_FORMAT "Merge"
|
||||
#define EXPLAIN_MERGE_KEYS_FORMAT "Merge Key: "
|
||||
#define EXPLAIN_IGNORE_GROUPID_FORMAT "Ignore Group Id: %s"
|
||||
#define EXPLAIN_PARTITION_KETS_FORMAT "Partition Key: "
|
||||
|
@ -85,7 +85,9 @@ extern "C" {
|
|||
#define EXPLAIN_COLUMNS_FORMAT "columns=%d"
|
||||
#define EXPLAIN_PSEUDO_COLUMNS_FORMAT "pseudo_columns=%d"
|
||||
#define EXPLAIN_WIDTH_FORMAT "width=%d"
|
||||
#define EXPLAIN_TABLE_SCAN_FORMAT "order=[asc|%d desc|%d]"
|
||||
#define EXPLAIN_SCAN_ORDER_FORMAT "order=[asc|%d desc|%d]"
|
||||
#define EXPLAIN_SCAN_MODE_FORMAT "mode=%s"
|
||||
#define EXPLAIN_SCAN_DATA_LOAD_FORMAT "data_load=%s"
|
||||
#define EXPLAIN_GROUPS_FORMAT "groups=%d"
|
||||
#define EXPLAIN_WIDTH_FORMAT "width=%d"
|
||||
#define EXPLAIN_INTERVAL_VALUE_FORMAT "interval=%" PRId64 "%c"
|
||||
|
@ -105,6 +107,7 @@ extern "C" {
|
|||
#define EXPLAIN_UID_SLOT_FORMAT "uid_slot=%d,%d"
|
||||
#define EXPLAIN_SRC_SCAN_FORMAT "src_scan=%d,%d"
|
||||
#define EXPLAIN_PLAN_BLOCKING "blocking=%d"
|
||||
#define EXPLAIN_MERGE_MODE_FORMAT "mode=%s"
|
||||
|
||||
#define COMMAND_RESET_LOG "resetLog"
|
||||
#define COMMAND_SCHEDULE_POLICY "schedulePolicy"
|
||||
|
@ -156,6 +159,7 @@ typedef struct SExplainCtx {
|
|||
|
||||
#define EXPLAIN_ORDER_STRING(_order) ((ORDER_ASC == _order) ? "asc" : ORDER_DESC == _order ? "desc" : "unknown")
|
||||
#define EXPLAIN_JOIN_STRING(_type) ((JOIN_TYPE_INNER == _type) ? "Inner join" : "Join")
|
||||
#define EXPLAIN_MERGE_MODE_STRING(_mode) ((_mode) == MERGE_TYPE_SORT ? "sort" : ((_mode) == MERGE_TYPE_NON_SORT ? "merge" : "column"))
|
||||
|
||||
#define INVERAL_TIME_FROM_PRECISION_TO_UNIT(_t, _u, _p) (((_u) == 'n' || (_u) == 'y') ? (_t) : (convertTimeFromPrecisionToUnit(_t, _p, _u)))
|
||||
|
||||
|
|
|
@ -842,7 +842,7 @@ static int32_t execAlterLocal(SAlterLocalStmt* pStmt) {
|
|||
return terrno;
|
||||
}
|
||||
|
||||
if (taosApplyLocalCfg(tsCfg, pStmt->config)) {
|
||||
if (taosCfgDynamicOptions(tsCfg, pStmt->config, false)) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "tcommon.h"
|
||||
#include "tdatablock.h"
|
||||
#include "systable.h"
|
||||
#include "functionMgt.h"
|
||||
|
||||
int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pRes);
|
||||
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level, bool singleChannel);
|
||||
|
@ -284,10 +285,49 @@ int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static uint8_t getIntervalPrecision(SIntervalPhysiNode *pIntNode) {
|
||||
static uint8_t qExplainGetIntervalPrecision(SIntervalPhysiNode *pIntNode) {
|
||||
return ((SColumnNode *)pIntNode->window.pTspk)->node.resType.precision;
|
||||
}
|
||||
|
||||
static char* qExplainGetScanMode(STableScanPhysiNode* pScan) {
|
||||
bool isGroupByTbname = false;
|
||||
bool isGroupByTag = false;
|
||||
bool seq = false;
|
||||
bool groupOrder = false;
|
||||
if (pScan->pGroupTags && LIST_LENGTH(pScan->pGroupTags) == 1) {
|
||||
SNode* p = nodesListGetNode(pScan->pGroupTags, 0);
|
||||
if (QUERY_NODE_FUNCTION == nodeType(p) && (strcmp(((struct SFunctionNode*)p)->functionName, "tbname") == 0)) {
|
||||
isGroupByTbname = true;
|
||||
}
|
||||
}
|
||||
|
||||
isGroupByTag = (NULL != pScan->pGroupTags) && !isGroupByTbname;
|
||||
if ((((!isGroupByTag) || isGroupByTbname) && pScan->groupSort) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
|
||||
return "seq_grp_order";
|
||||
}
|
||||
|
||||
if ((isGroupByTbname && (pScan->groupSort || pScan->scan.groupOrderScan)) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
|
||||
return "grp_order";
|
||||
}
|
||||
|
||||
return "ts_order";
|
||||
}
|
||||
|
||||
static char* qExplainGetScanDataLoad(STableScanPhysiNode* pScan) {
|
||||
switch (pScan->dataRequired) {
|
||||
case FUNC_DATA_REQUIRED_DATA_LOAD:
|
||||
return "data";
|
||||
case FUNC_DATA_REQUIRED_SMA_LOAD:
|
||||
return "sma";
|
||||
case FUNC_DATA_REQUIRED_NOT_LOAD:
|
||||
return "no";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
|
||||
int32_t tlen = 0;
|
||||
bool isVerboseLine = false;
|
||||
|
@ -360,7 +400,11 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_TABLE_SCAN_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_ORDER_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_MODE_FORMAT, qExplainGetScanMode(pTblScanNode));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_DATA_LOAD_FORMAT, qExplainGetScanDataLoad(pTblScanNode));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
@ -599,7 +643,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
|
||||
SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT);
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT, (pAggNode->pGroupKeys ? "GroupAggragate" : "Aggragate"));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
|
@ -841,7 +885,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
uint8_t precision = getIntervalPrecision(pIntNode);
|
||||
uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
|
||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision),
|
||||
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
|
||||
|
@ -893,7 +937,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
uint8_t precision = getIntervalPrecision(pIntNode);
|
||||
uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
|
||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision),
|
||||
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
|
||||
|
@ -1119,23 +1163,14 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.inputTsOrder));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.outputTsOrder));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_MERGE_MODE_FORMAT, EXPLAIN_MERGE_MODE_STRING(pMergeNode->type));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
|
||||
// sort key
|
||||
EXPLAIN_ROW_NEW(level + 1, "Merge Key: ");
|
||||
if (pResNode->pExecInfo) {
|
||||
for (int32_t i = 0; i < LIST_LENGTH(pMergeNode->pMergeKeys); ++i) {
|
||||
SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pMergeNode->pMergeKeys, i);
|
||||
EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
|
||||
}
|
||||
}
|
||||
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (MERGE_TYPE_SORT == pMergeNode->type) {
|
||||
// sort method
|
||||
EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
|
||||
|
||||
|
@ -1155,6 +1190,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
|
@ -1167,6 +1203,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (MERGE_TYPE_SORT == pMergeNode->type) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pMergeNode->ignoreGroupId ? "true" : "false");
|
||||
EXPLAIN_ROW_END();
|
||||
|
@ -1190,6 +1227,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
||||
if (pMergeNode->node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
|
@ -1419,7 +1457,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
uint8_t precision = getIntervalPrecision(pIntNode);
|
||||
uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
|
||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision),
|
||||
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
|
||||
|
|
|
@ -607,6 +607,31 @@ typedef struct SStreamStateAggOperatorInfo {
|
|||
bool recvGetAll;
|
||||
} SStreamStateAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamEventAggOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SStreamAggSupporter streamAggSup;
|
||||
SExprSupp scalarSupp; // supporter for perform scalar function
|
||||
SGroupResInfo groupResInfo;
|
||||
int32_t primaryTsIndex; // primary timestamp slot id
|
||||
STimeWindowAggSupp twAggSup;
|
||||
SSDataBlock* pDelRes;
|
||||
SSHashObj* pSeDeleted;
|
||||
void* pDelIterator;
|
||||
SArray* pChildren; // cache for children's result;
|
||||
bool ignoreExpiredData;
|
||||
bool ignoreExpiredDataSaved;
|
||||
SArray* pUpdated;
|
||||
SSHashObj* pSeUpdated;
|
||||
SSHashObj* pAllUpdated;
|
||||
int64_t dataVersion;
|
||||
bool isHistoryOp;
|
||||
SArray* historyWins;
|
||||
bool reCkBlock;
|
||||
SSDataBlock* pCheckpointRes;
|
||||
SFilterInfo* pStartCondInfo;
|
||||
SFilterInfo* pEndCondInfo;
|
||||
} SStreamEventAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamPartitionOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SPartitionBySupporter partitionSup;
|
||||
|
@ -765,9 +790,51 @@ void doClearBufferedBlocks(SStreamScanInfo* pInfo);
|
|||
uint64_t calcGroupId(char* pData, int32_t len);
|
||||
void streamOpReleaseState(struct SOperatorInfo* pOperator);
|
||||
void streamOpReloadState(struct SOperatorInfo* pOperator);
|
||||
void destroyStreamAggSupporter(SStreamAggSupporter* pSup);
|
||||
void clearGroupResInfo(SGroupResInfo* pGroupResInfo);
|
||||
int32_t initBasicInfoEx(SOptrBasicInfo* pBasicInfo, SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResultBlock, SFunctionStateStore* pStore);
|
||||
int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SExprSupp* pExpSup, int32_t numOfOutput, int64_t gap,
|
||||
SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore,
|
||||
SReadHandle* pHandle, STimeWindowAggSupp* pTwAggSup, const char* taskIdStr,
|
||||
SStorageAPI* pApi);
|
||||
void initDownStream(struct SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uint16_t type, int32_t tsColIndex,
|
||||
STimeWindowAggSupp* pTwSup);
|
||||
void getMaxTsWins(const SArray* pAllWins, SArray* pMaxWins);
|
||||
void initGroupResInfoFromArrayList(SGroupResInfo* pGroupResInfo, SArray* pArrayList);
|
||||
void getSessionHashKey(const SSessionKey* pKey, SSessionKey* pHashKey);
|
||||
void deleteSessionWinState(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SSHashObj* pMapUpdate, SSHashObj* pMapDelete);
|
||||
int32_t getAllSessionWindow(SSHashObj* pHashMap, SSHashObj* pStUpdated);
|
||||
int32_t closeSessionWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SSHashObj* pClosed);
|
||||
int32_t copyUpdateResult(SSHashObj** ppWinUpdated, SArray* pUpdated, __compar_fn_t compar);
|
||||
int32_t sessionKeyCompareAsc(const void* pKey1, const void* pKey2);
|
||||
void removeSessionDeleteResults(SSHashObj* pHashMap, SArray* pWins);
|
||||
int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo* pCurWin, SResultRow** pResult,
|
||||
int32_t startIndex, int32_t winRows, int32_t rows, int32_t numOutput,
|
||||
struct SOperatorInfo* pOperator, int64_t winDelta);
|
||||
int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* pWinInfo);
|
||||
int32_t saveSessionOutputBuf(SStreamAggSupporter* pAggSup, SResultWindowInfo* pWinInfo);
|
||||
int32_t saveResult(SResultWindowInfo winInfo, SSHashObj* pStUpdated);
|
||||
void saveDeleteRes(SSHashObj* pStDelete, SSessionKey key);
|
||||
void removeSessionResult(SStreamAggSupporter* pAggSup, SSHashObj* pHashMap, SSHashObj* pResMap, SSessionKey* pKey);
|
||||
void doBuildDeleteDataBlock(struct SOperatorInfo* pOp, SSHashObj* pStDeleted, SSDataBlock* pBlock, void** Ite);
|
||||
void doBuildSessionResult(struct SOperatorInfo* pOperator, void* pState, SGroupResInfo* pGroupResInfo, SSDataBlock* pBlock);
|
||||
void getSessionWindowInfoByKey(SStreamAggSupporter* pAggSup, SSessionKey* pKey, SResultWindowInfo* pWinInfo);
|
||||
void getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* pStUpdated, SResultWindowInfo* pCurWin,
|
||||
SResultWindowInfo* pNextWin);
|
||||
void compactTimeWindow(SExprSupp* pSup, SStreamAggSupporter* pAggSup, STimeWindowAggSupp* pTwAggSup,
|
||||
SExecTaskInfo* pTaskInfo, SResultWindowInfo* pCurWin, SResultWindowInfo* pNextWin,
|
||||
SSHashObj* pStUpdated, SSHashObj* pStDeleted, bool addGap);
|
||||
int32_t releaseOutputBuf(void* pState, SRowBuffPos* pPos, SStateStore* pAPI);
|
||||
void resetWinRange(STimeWindow* winRange);
|
||||
|
||||
int32_t encodeSSessionKey(void** buf, SSessionKey* key);
|
||||
void* decodeSSessionKey(void* buf, SSessionKey* key);
|
||||
int32_t encodeSResultWindowInfo(void** buf, SResultWindowInfo* key, int32_t outLen);
|
||||
void* decodeSResultWindowInfo(void* buf, SResultWindowInfo* key, int32_t outLen);
|
||||
int32_t encodeSTimeWindowAggSupp(void** buf, STimeWindowAggSupp* pTwAggSup);
|
||||
void* decodeSTimeWindowAggSupp(void* buf, STimeWindowAggSupp* pTwAggSup);
|
||||
|
||||
void destroyOperatorParamValue(void* pValues);
|
||||
int32_t mergeOperatorParams(SOperatorParam* pDst, SOperatorParam* pSrc);
|
||||
int32_t buildTableScanOperatorParam(SOperatorParam** ppRes, SArray* pUidList, int32_t srcOpType, bool tableSeq);
|
||||
|
|
|
@ -152,6 +152,8 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
|
||||
SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createStreamEventAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle);
|
||||
|
||||
SOperatorInfo* createGroupSortOperatorInfo(SOperatorInfo* downstream, SGroupSortPhysiNode* pSortPhyNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo);
|
||||
|
|
|
@ -77,6 +77,12 @@ static int32_t doSetSMABlock(SOperatorInfo* pOperator, void* input, size_t numOf
|
|||
SPackedData tmp = {.pDataBlock = input};
|
||||
taosArrayPush(pInfo->pBlockLists, &tmp);
|
||||
pInfo->blockType = STREAM_INPUT__CHECKPOINT;
|
||||
} else if (type == STREAM_INPUT__REF_DATA_BLOCK) {
|
||||
for (int32_t i = 0; i < numOfBlocks; ++i) {
|
||||
SPackedData* pReq = POINTER_SHIFT(input, i * sizeof(SPackedData));
|
||||
taosArrayPush(pInfo->pBlockLists, pReq);
|
||||
}
|
||||
pInfo->blockType = STREAM_INPUT__DATA_BLOCK;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -239,7 +239,7 @@ SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
|||
numOfDownstream = 2;
|
||||
} else {
|
||||
pInfo->downstreamResBlkId[0] = getOperatorResultBlockId(pDownstream[0], 0);
|
||||
pInfo->downstreamResBlkId[1] = getOperatorResultBlockId(pDownstream[1], 1);
|
||||
pInfo->downstreamResBlkId[1] = getOperatorResultBlockId(pDownstream[1], 0);
|
||||
}
|
||||
|
||||
int32_t numOfCols = 0;
|
||||
|
|
|
@ -0,0 +1,531 @@
|
|||
/*
|
||||
* 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 "executorInt.h"
|
||||
#include "filter.h"
|
||||
#include "operator.h"
|
||||
#include "querytask.h"
|
||||
#include "tdatablock.h"
|
||||
|
||||
typedef struct SSortMergeInfo {
|
||||
SArray* pSortInfo;
|
||||
SSortHandle* pSortHandle;
|
||||
STupleHandle* prefetchedTuple;
|
||||
int32_t bufPageSize;
|
||||
uint32_t sortBufSize; // max buffer size for in-memory sort
|
||||
SSDataBlock* pIntermediateBlock; // to hold the intermediate result
|
||||
SSDataBlock* pInputBlock;
|
||||
SColMatchInfo matchInfo;
|
||||
} SSortMergeInfo;
|
||||
|
||||
typedef struct SNonSortMergeInfo {
|
||||
int32_t lastSourceIdx;
|
||||
int32_t sourceWorkIdx;
|
||||
int32_t sourceNum;
|
||||
int32_t* pSourceStatus;
|
||||
} SNonSortMergeInfo;
|
||||
|
||||
typedef struct SColsMergeInfo {
|
||||
SNodeList* pTargets;
|
||||
uint64_t srcBlkIds[2];
|
||||
} SColsMergeInfo;
|
||||
|
||||
typedef struct SMultiwayMergeOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
EMergeType type;
|
||||
union {
|
||||
SSortMergeInfo sortMergeInfo;
|
||||
SNonSortMergeInfo nsortMergeInfo;
|
||||
SColsMergeInfo colsMergeInfo;
|
||||
};
|
||||
SLimitInfo limitInfo;
|
||||
bool groupMerge;
|
||||
bool ignoreGroupId;
|
||||
uint64_t groupId;
|
||||
bool inputWithGroupId;
|
||||
} SMultiwayMergeOperatorInfo;
|
||||
|
||||
SSDataBlock* sortMergeloadNextDataBlock(void* param) {
|
||||
SOperatorInfo* pOperator = (SOperatorInfo*)param;
|
||||
SSDataBlock* pBlock = pOperator->fpSet.getNextFn(pOperator);
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
int32_t openSortMergeOperator(SOperatorInfo* pOperator) {
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SSortMergeInfo* pSortMergeInfo = &pInfo->sortMergeInfo;
|
||||
|
||||
int32_t numOfBufPage = pSortMergeInfo->sortBufSize / pSortMergeInfo->bufPageSize;
|
||||
|
||||
pSortMergeInfo->pSortHandle = tsortCreateSortHandle(pSortMergeInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pSortMergeInfo->bufPageSize, numOfBufPage,
|
||||
pSortMergeInfo->pInputBlock, pTaskInfo->id.str, 0, 0, 0);
|
||||
|
||||
tsortSetFetchRawDataFp(pSortMergeInfo->pSortHandle, sortMergeloadNextDataBlock, NULL, NULL);
|
||||
tsortSetCompareGroupId(pSortMergeInfo->pSortHandle, pInfo->groupMerge);
|
||||
|
||||
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
|
||||
SOperatorInfo* pDownstream = pOperator->pDownstream[i];
|
||||
if (pDownstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE) {
|
||||
pDownstream->fpSet._openFn(pDownstream);
|
||||
}
|
||||
|
||||
SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
|
||||
ps->param = pDownstream;
|
||||
ps->onlyRef = true;
|
||||
|
||||
tsortAddSource(pSortMergeInfo->pSortHandle, ps);
|
||||
}
|
||||
|
||||
return tsortOpen(pSortMergeInfo->pSortHandle);
|
||||
}
|
||||
|
||||
static void doGetSortedBlockData(SMultiwayMergeOperatorInfo* pInfo, SSortHandle* pHandle, int32_t capacity,
|
||||
SSDataBlock* p, bool* newgroup) {
|
||||
SSortMergeInfo* pSortMergeInfo = &pInfo->sortMergeInfo;
|
||||
*newgroup = false;
|
||||
|
||||
while (1) {
|
||||
STupleHandle* pTupleHandle = NULL;
|
||||
if (pInfo->groupMerge || pInfo->inputWithGroupId) {
|
||||
if (pSortMergeInfo->prefetchedTuple == NULL) {
|
||||
pTupleHandle = tsortNextTuple(pHandle);
|
||||
} else {
|
||||
pTupleHandle = pSortMergeInfo->prefetchedTuple;
|
||||
pSortMergeInfo->prefetchedTuple = NULL;
|
||||
uint64_t gid = tsortGetGroupId(pTupleHandle);
|
||||
if (gid != pInfo->groupId) {
|
||||
*newgroup = true;
|
||||
pInfo->groupId = gid;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pTupleHandle = tsortNextTuple(pHandle);
|
||||
pInfo->groupId = 0;
|
||||
}
|
||||
|
||||
if (pTupleHandle == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pInfo->groupMerge || pInfo->inputWithGroupId) {
|
||||
uint64_t tupleGroupId = tsortGetGroupId(pTupleHandle);
|
||||
if (pInfo->groupId == 0 || pInfo->groupId == tupleGroupId) {
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
p->info.id.groupId = tupleGroupId;
|
||||
pInfo->groupId = tupleGroupId;
|
||||
} else {
|
||||
if (p->info.rows == 0) {
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
p->info.id.groupId = pInfo->groupId = tupleGroupId;
|
||||
} else {
|
||||
pSortMergeInfo->prefetchedTuple = pTupleHandle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
}
|
||||
|
||||
if (p->info.rows >= capacity) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSDataBlock* doSortMerge(SOperatorInfo* pOperator) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
SSortMergeInfo* pSortMergeInfo = &pInfo->sortMergeInfo;
|
||||
SSortHandle* pHandle = pSortMergeInfo->pSortHandle;
|
||||
SSDataBlock* pDataBlock = pInfo->binfo.pRes;
|
||||
SArray* pColMatchInfo = pSortMergeInfo->matchInfo.pList;
|
||||
int32_t capacity = pOperator->resultInfo.capacity;
|
||||
|
||||
qDebug("start to merge final sorted rows, %s", GET_TASKID(pTaskInfo));
|
||||
|
||||
blockDataCleanup(pDataBlock);
|
||||
|
||||
if (pSortMergeInfo->pIntermediateBlock == NULL) {
|
||||
pSortMergeInfo->pIntermediateBlock = tsortGetSortedDataBlock(pHandle);
|
||||
if (pSortMergeInfo->pIntermediateBlock == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
blockDataEnsureCapacity(pSortMergeInfo->pIntermediateBlock, capacity);
|
||||
} else {
|
||||
blockDataCleanup(pSortMergeInfo->pIntermediateBlock);
|
||||
}
|
||||
|
||||
SSDataBlock* p = pSortMergeInfo->pIntermediateBlock;
|
||||
bool newgroup = false;
|
||||
|
||||
while (1) {
|
||||
doGetSortedBlockData(pInfo, pHandle, capacity, p, &newgroup);
|
||||
if (p->info.rows == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (newgroup) {
|
||||
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
||||
}
|
||||
|
||||
applyLimitOffset(&pInfo->limitInfo, p, pTaskInfo);
|
||||
|
||||
if (p->info.rows > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->info.rows > 0) {
|
||||
int32_t numOfCols = taosArrayGetSize(pColMatchInfo);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColMatchItem* pmInfo = taosArrayGet(pColMatchInfo, i);
|
||||
|
||||
SColumnInfoData* pSrc = taosArrayGet(p->pDataBlock, pmInfo->srcSlotId);
|
||||
SColumnInfoData* pDst = taosArrayGet(pDataBlock->pDataBlock, pmInfo->dstSlotId);
|
||||
colDataAssign(pDst, pSrc, p->info.rows, &pDataBlock->info);
|
||||
}
|
||||
|
||||
pDataBlock->info.rows = p->info.rows;
|
||||
pDataBlock->info.scanFlag = p->info.scanFlag;
|
||||
if (pInfo->ignoreGroupId) {
|
||||
pDataBlock->info.id.groupId = 0;
|
||||
} else {
|
||||
pDataBlock->info.id.groupId = pInfo->groupId;
|
||||
}
|
||||
pDataBlock->info.dataLoad = 1;
|
||||
}
|
||||
|
||||
qDebug("%s get sorted block, groupId:0x%" PRIx64 " rows:%" PRId64 , GET_TASKID(pTaskInfo), pDataBlock->info.id.groupId,
|
||||
pDataBlock->info.rows);
|
||||
|
||||
return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
|
||||
}
|
||||
|
||||
|
||||
int32_t getSortMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
|
||||
SSortExecInfo* pSortExecInfo = taosMemoryCalloc(1, sizeof(SSortExecInfo));
|
||||
|
||||
SMultiwayMergeOperatorInfo* pInfo = (SMultiwayMergeOperatorInfo*)pOptr->info;
|
||||
SSortMergeInfo* pSortMergeInfo = &pInfo->sortMergeInfo;
|
||||
|
||||
*pSortExecInfo = tsortGetSortExecInfo(pSortMergeInfo->pSortHandle);
|
||||
*pOptrExplain = pSortExecInfo;
|
||||
|
||||
*len = sizeof(SSortExecInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void destroySortMergeOperatorInfo(void* param) {
|
||||
SSortMergeInfo* pSortMergeInfo = param;
|
||||
pSortMergeInfo->pInputBlock = blockDataDestroy(pSortMergeInfo->pInputBlock);
|
||||
pSortMergeInfo->pIntermediateBlock = blockDataDestroy(pSortMergeInfo->pIntermediateBlock);
|
||||
|
||||
taosArrayDestroy(pSortMergeInfo->matchInfo.pList);
|
||||
|
||||
tsortDestroySortHandle(pSortMergeInfo->pSortHandle);
|
||||
taosArrayDestroy(pSortMergeInfo->pSortInfo);
|
||||
}
|
||||
|
||||
#define NON_SORT_NEXT_SRC(_info, _idx) ((++(_idx) >= (_info)->sourceNum) ? ((_info)->sourceWorkIdx) : (_idx))
|
||||
|
||||
int32_t openNonSortMergeOperator(SOperatorInfo* pOperator) {
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SNonSortMergeInfo* pNonSortMergeInfo = &pInfo->nsortMergeInfo;
|
||||
|
||||
pNonSortMergeInfo->sourceWorkIdx = 0;
|
||||
pNonSortMergeInfo->sourceNum = pOperator->numOfDownstream;
|
||||
pNonSortMergeInfo->lastSourceIdx = -1;
|
||||
pNonSortMergeInfo->pSourceStatus = taosMemoryCalloc(pOperator->numOfDownstream, sizeof(*pNonSortMergeInfo->pSourceStatus));
|
||||
if (NULL == pNonSortMergeInfo->pSourceStatus) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
|
||||
pNonSortMergeInfo->pSourceStatus[i] = i;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSDataBlock* doNonSortMerge(SOperatorInfo* pOperator) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
SNonSortMergeInfo* pNonSortMerge = &pInfo->nsortMergeInfo;
|
||||
SSDataBlock* pBlock = NULL;
|
||||
|
||||
qDebug("start to merge no sorted rows, %s", GET_TASKID(pTaskInfo));
|
||||
|
||||
int32_t idx = NON_SORT_NEXT_SRC(pNonSortMerge, pNonSortMerge->lastSourceIdx);
|
||||
while (idx < pNonSortMerge->sourceNum) {
|
||||
pBlock = getNextBlockFromDownstream(pOperator, pNonSortMerge->pSourceStatus[idx]);
|
||||
if (NULL == pBlock) {
|
||||
TSWAP(pNonSortMerge->pSourceStatus[pNonSortMerge->sourceWorkIdx], pNonSortMerge->pSourceStatus[idx]);
|
||||
pNonSortMerge->sourceWorkIdx++;
|
||||
idx = NON_SORT_NEXT_SRC(pNonSortMerge, idx);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
void destroyNonSortMergeOperatorInfo(void* param) {
|
||||
SNonSortMergeInfo* pNonSortMerge = param;
|
||||
taosMemoryFree(pNonSortMerge->pSourceStatus);
|
||||
}
|
||||
|
||||
int32_t getNonSortMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t openColsMergeOperator(SOperatorInfo* pOperator) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t copyColumnsValue(SNodeList* pNodeList, uint64_t targetBlkId, SSDataBlock* pDst, SSDataBlock* pSrc) {
|
||||
bool isNull = (NULL == pSrc || pSrc->info.rows <= 0);
|
||||
size_t numOfCols = LIST_LENGTH(pNodeList);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
|
||||
if (nodeType(pNode->pExpr) == QUERY_NODE_COLUMN && ((SColumnNode*)pNode->pExpr)->dataBlockId == targetBlkId) {
|
||||
SColumnInfoData* pDstCol = taosArrayGet(pDst->pDataBlock, pNode->slotId);
|
||||
if (isNull) {
|
||||
colDataSetVal(pDstCol, 0, NULL, true);
|
||||
} else {
|
||||
SColumnInfoData* pSrcCol = taosArrayGet(pSrc->pDataBlock, ((SColumnNode*)pNode->pExpr)->slotId);
|
||||
colDataAssign(pDstCol, pSrcCol, 1, &pDst->info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSDataBlock* doColsMerge(SOperatorInfo* pOperator) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
SSDataBlock* pBlock = NULL;
|
||||
SColsMergeInfo* pColsMerge = &pInfo->colsMergeInfo;
|
||||
int32_t nullBlkNum = 0;
|
||||
|
||||
qDebug("start to merge columns, %s", GET_TASKID(pTaskInfo));
|
||||
|
||||
for (int32_t i = 0; i < 2; ++i) {
|
||||
pBlock = getNextBlockFromDownstream(pOperator, i);
|
||||
if (pBlock && pBlock->info.rows > 1) {
|
||||
qError("more than 1 row returned from downstream, rows:%" PRId64, pBlock->info.rows);
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR);
|
||||
} else if (NULL == pBlock) {
|
||||
nullBlkNum++;
|
||||
}
|
||||
|
||||
copyColumnsValue(pColsMerge->pTargets, pColsMerge->srcBlkIds[i], pInfo->binfo.pRes, pBlock);
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
|
||||
if (2 == nullBlkNum) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pInfo->binfo.pRes->info.rows = 1;
|
||||
|
||||
return pInfo->binfo.pRes;
|
||||
}
|
||||
|
||||
void destroyColsMergeOperatorInfo(void* param) {
|
||||
}
|
||||
|
||||
int32_t getColsMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SOperatorFpSet gMultiwayMergeFps[MERGE_TYPE_MAX_VALUE] = {
|
||||
{0},
|
||||
{._openFn = openSortMergeOperator, .getNextFn = doSortMerge, .closeFn = destroySortMergeOperatorInfo, .getExplainFn = getSortMergeExplainExecInfo},
|
||||
{._openFn = openNonSortMergeOperator, .getNextFn = doNonSortMerge, .closeFn = destroyNonSortMergeOperatorInfo, .getExplainFn = getNonSortMergeExplainExecInfo},
|
||||
{._openFn = openColsMergeOperator, .getNextFn = doColsMerge, .closeFn = destroyColsMergeOperatorInfo, .getExplainFn = getColsMergeExplainExecInfo},
|
||||
};
|
||||
|
||||
|
||||
int32_t openMultiwayMergeOperator(SOperatorInfo* pOperator) {
|
||||
int32_t code = 0;
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
if (OPTR_IS_OPENED(pOperator)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t startTs = taosGetTimestampUs();
|
||||
|
||||
if (NULL != gMultiwayMergeFps[pInfo->type]._openFn) {
|
||||
code = (*gMultiwayMergeFps[pInfo->type]._openFn)(pOperator);
|
||||
}
|
||||
|
||||
pOperator->cost.openCost = (taosGetTimestampUs() - startTs) / 1000.0;
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, terrno);
|
||||
}
|
||||
|
||||
OPTR_SET_OPENED(pOperator);
|
||||
return code;
|
||||
}
|
||||
|
||||
SSDataBlock* doMultiwayMerge(SOperatorInfo* pOperator) {
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSDataBlock* pBlock = NULL;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
|
||||
int32_t code = pOperator->fpSet._openFn(pOperator);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
if (NULL != gMultiwayMergeFps[pInfo->type].getNextFn) {
|
||||
pBlock = (*gMultiwayMergeFps[pInfo->type].getNextFn)(pOperator);
|
||||
}
|
||||
if (pBlock != NULL) {
|
||||
pOperator->resultInfo.totalRows += pBlock->info.rows;
|
||||
} else {
|
||||
setOperatorCompleted(pOperator);
|
||||
}
|
||||
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
void destroyMultiwayMergeOperatorInfo(void* param) {
|
||||
SMultiwayMergeOperatorInfo* pInfo = (SMultiwayMergeOperatorInfo*)param;
|
||||
pInfo->binfo.pRes = blockDataDestroy(pInfo->binfo.pRes);
|
||||
|
||||
if (NULL != gMultiwayMergeFps[pInfo->type].closeFn) {
|
||||
(*gMultiwayMergeFps[pInfo->type].closeFn)(&pInfo->sortMergeInfo);
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
int32_t getMultiwayMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
|
||||
int32_t code = 0;
|
||||
SMultiwayMergeOperatorInfo* pInfo = (SMultiwayMergeOperatorInfo*)pOptr->info;
|
||||
|
||||
if (NULL != gMultiwayMergeFps[pInfo->type].getExplainFn) {
|
||||
code = (*gMultiwayMergeFps[pInfo->type].getExplainFn)(pOptr, pOptrExplain, len);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
SOperatorInfo* createMultiwayMergeOperatorInfo(SOperatorInfo** downStreams, size_t numStreams,
|
||||
SMergePhysiNode* pMergePhyNode, SExecTaskInfo* pTaskInfo) {
|
||||
SPhysiNode* pPhyNode = (SPhysiNode*)pMergePhyNode;
|
||||
|
||||
SMultiwayMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SMultiwayMergeOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
SDataBlockDescNode* pDescNode = pPhyNode->pOutputDataBlockDesc;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->groupMerge = pMergePhyNode->groupSort;
|
||||
pInfo->ignoreGroupId = pMergePhyNode->ignoreGroupId;
|
||||
pInfo->binfo.inputTsOrder = pMergePhyNode->node.inputTsOrder;
|
||||
pInfo->binfo.outputTsOrder = pMergePhyNode->node.outputTsOrder;
|
||||
pInfo->inputWithGroupId = pMergePhyNode->inputWithGroupId;
|
||||
|
||||
pInfo->type = pMergePhyNode->type;
|
||||
switch (pInfo->type) {
|
||||
case MERGE_TYPE_SORT: {
|
||||
SSortMergeInfo* pSortMergeInfo = &pInfo->sortMergeInfo;
|
||||
initLimitInfo(pMergePhyNode->node.pLimit, pMergePhyNode->node.pSlimit, &pInfo->limitInfo);
|
||||
pInfo->binfo.pRes = createDataBlockFromDescNode(pDescNode);
|
||||
|
||||
SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, 0);
|
||||
SSDataBlock* pInputBlock = createDataBlockFromDescNode(pChildNode->pOutputDataBlockDesc);
|
||||
|
||||
initResultSizeInfo(&pOperator->resultInfo, 1024);
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pInfo->binfo.pRes->pDataBlock);
|
||||
int32_t rowSize = pInfo->binfo.pRes->info.rowSize;
|
||||
int32_t numOfOutputCols = 0;
|
||||
pSortMergeInfo->pSortInfo = createSortInfo(pMergePhyNode->pMergeKeys);
|
||||
pSortMergeInfo->bufPageSize = getProperSortPageSize(rowSize, numOfCols);
|
||||
pSortMergeInfo->sortBufSize = pSortMergeInfo->bufPageSize * (numStreams + 1); // one additional is reserved for merged result.
|
||||
pSortMergeInfo->pInputBlock = pInputBlock;
|
||||
code = extractColMatchInfo(pMergePhyNode->pTargets, pDescNode, &numOfOutputCols, COL_MATCH_FROM_SLOT_ID,
|
||||
&pSortMergeInfo->matchInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MERGE_TYPE_NON_SORT: {
|
||||
SNonSortMergeInfo* pNonSortMerge = &pInfo->nsortMergeInfo;
|
||||
break;
|
||||
}
|
||||
case MERGE_TYPE_COLUMNS: {
|
||||
SColsMergeInfo* pColsMerge = &pInfo->colsMergeInfo;
|
||||
pInfo->binfo.pRes = createDataBlockFromDescNode(pDescNode);
|
||||
initResultSizeInfo(&pOperator->resultInfo, 1);
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
||||
pColsMerge->pTargets = pMergePhyNode->pTargets;
|
||||
pColsMerge->srcBlkIds[0] = getOperatorResultBlockId(downStreams[0], 0);
|
||||
pColsMerge->srcBlkIds[1] = getOperatorResultBlockId(downStreams[1], 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qError("Invalid merge type: %d", pInfo->type);
|
||||
code = TSDB_CODE_INVALID_PARA;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
setOperatorInfo(pOperator, "MultiwayMergeOperator", QUERY_NODE_PHYSICAL_PLAN_MERGE, false, OP_NOT_OPENED, pInfo, pTaskInfo);
|
||||
pOperator->fpSet = createOperatorFpSet(openMultiwayMergeOperator, doMultiwayMerge, NULL,
|
||||
destroyMultiwayMergeOperatorInfo, optrDefaultBufFn, getMultiwayMergeExplainExecInfo, optrDefaultGetNextExtFn, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, downStreams, numStreams);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
if (pInfo != NULL) {
|
||||
destroyMultiwayMergeOperatorInfo(pInfo);
|
||||
}
|
||||
|
||||
pTaskInfo->code = code;
|
||||
taosMemoryFree(pOperator);
|
||||
return NULL;
|
||||
}
|
|
@ -519,6 +519,8 @@ SOperatorInfo* createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SR
|
|||
pOptr = createStatewindowOperatorInfo(ops[0], pStateNode, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE == type) {
|
||||
pOptr = createStreamStateAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT == type) {
|
||||
pOptr = createStreamEventAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN == type) {
|
||||
pOptr = createMergeJoinOperatorInfo(ops, size, (SSortMergeJoinPhysiNode*)pPhyNode, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_HASH_JOIN == type) {
|
||||
|
|
|
@ -1127,7 +1127,8 @@ static bool isSessionWindow(SStreamScanInfo* pInfo) {
|
|||
}
|
||||
|
||||
static bool isStateWindow(SStreamScanInfo* pInfo) {
|
||||
return pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE;
|
||||
return pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE ||
|
||||
pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT;
|
||||
}
|
||||
|
||||
static bool isIntervalWindow(SStreamScanInfo* pInfo) {
|
||||
|
@ -2243,6 +2244,7 @@ FETCH_NEXT_BLOCK:
|
|||
blockDataCleanup(pSup->pScanBlock);
|
||||
prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
|
||||
pInfo->pUpdateRes->info.type = STREAM_DELETE_DATA;
|
||||
printSpecDataBlock(pInfo->pUpdateRes, getStreamOpName(pOperator->operatorType), "rebuild", GET_TASKID(pTaskInfo));
|
||||
return pInfo->pUpdateRes;
|
||||
}
|
||||
|
||||
|
|
|
@ -675,293 +675,5 @@ _error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// Multiway Sort Merge operator
|
||||
typedef struct SMultiwayMergeOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
int32_t bufPageSize;
|
||||
uint32_t sortBufSize; // max buffer size for in-memory sort
|
||||
SLimitInfo limitInfo;
|
||||
SArray* pSortInfo;
|
||||
SSortHandle* pSortHandle;
|
||||
SColMatchInfo matchInfo;
|
||||
SSDataBlock* pInputBlock;
|
||||
SSDataBlock* pIntermediateBlock; // to hold the intermediate result
|
||||
int64_t startTs; // sort start time
|
||||
bool groupSort;
|
||||
bool ignoreGroupId;
|
||||
uint64_t groupId;
|
||||
STupleHandle* prefetchedTuple;
|
||||
bool inputWithGroupId;
|
||||
} SMultiwayMergeOperatorInfo;
|
||||
|
||||
int32_t openMultiwayMergeOperator(SOperatorInfo* pOperator) {
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
if (OPTR_IS_OPENED(pOperator)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pInfo->startTs = taosGetTimestampUs();
|
||||
int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
|
||||
|
||||
pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize, numOfBufPage,
|
||||
pInfo->pInputBlock, pTaskInfo->id.str, 0, 0, 0);
|
||||
|
||||
tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, NULL, NULL);
|
||||
tsortSetCompareGroupId(pInfo->pSortHandle, pInfo->groupSort);
|
||||
|
||||
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
|
||||
SOperatorInfo* pDownstream = pOperator->pDownstream[i];
|
||||
if (pDownstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE) {
|
||||
pDownstream->fpSet._openFn(pDownstream);
|
||||
}
|
||||
|
||||
SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
|
||||
ps->param = pDownstream;
|
||||
ps->onlyRef = true;
|
||||
|
||||
tsortAddSource(pInfo->pSortHandle, ps);
|
||||
}
|
||||
|
||||
int32_t code = tsortOpen(pInfo->pSortHandle);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, terrno);
|
||||
}
|
||||
|
||||
pOperator->cost.openCost = (taosGetTimestampUs() - pInfo->startTs) / 1000.0;
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
|
||||
OPTR_SET_OPENED(pOperator);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void doGetSortedBlockData(SMultiwayMergeOperatorInfo* pInfo, SSortHandle* pHandle, int32_t capacity,
|
||||
SSDataBlock* p, bool* newgroup) {
|
||||
*newgroup = false;
|
||||
|
||||
while (1) {
|
||||
STupleHandle* pTupleHandle = NULL;
|
||||
if (pInfo->groupSort || pInfo->inputWithGroupId) {
|
||||
if (pInfo->prefetchedTuple == NULL) {
|
||||
pTupleHandle = tsortNextTuple(pHandle);
|
||||
} else {
|
||||
pTupleHandle = pInfo->prefetchedTuple;
|
||||
pInfo->prefetchedTuple = NULL;
|
||||
uint64_t gid = tsortGetGroupId(pTupleHandle);
|
||||
if (gid != pInfo->groupId) {
|
||||
*newgroup = true;
|
||||
pInfo->groupId = gid;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pTupleHandle = tsortNextTuple(pHandle);
|
||||
pInfo->groupId = 0;
|
||||
}
|
||||
|
||||
if (pTupleHandle == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pInfo->groupSort || pInfo->inputWithGroupId) {
|
||||
uint64_t tupleGroupId = tsortGetGroupId(pTupleHandle);
|
||||
if (pInfo->groupId == 0 || pInfo->groupId == tupleGroupId) {
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
p->info.id.groupId = tupleGroupId;
|
||||
pInfo->groupId = tupleGroupId;
|
||||
} else {
|
||||
if (p->info.rows == 0) {
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
p->info.id.groupId = pInfo->groupId = tupleGroupId;
|
||||
} else {
|
||||
pInfo->prefetchedTuple = pTupleHandle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
}
|
||||
|
||||
if (p->info.rows >= capacity) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, SArray* pColMatchInfo,
|
||||
SOperatorInfo* pOperator) {
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
|
||||
int32_t capacity = pOperator->resultInfo.capacity;
|
||||
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
blockDataCleanup(pDataBlock);
|
||||
|
||||
if (pInfo->pIntermediateBlock == NULL) {
|
||||
pInfo->pIntermediateBlock = tsortGetSortedDataBlock(pHandle);
|
||||
if (pInfo->pIntermediateBlock == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
blockDataEnsureCapacity(pInfo->pIntermediateBlock, capacity);
|
||||
} else {
|
||||
blockDataCleanup(pInfo->pIntermediateBlock);
|
||||
}
|
||||
|
||||
SSDataBlock* p = pInfo->pIntermediateBlock;
|
||||
bool newgroup = false;
|
||||
|
||||
while (1) {
|
||||
doGetSortedBlockData(pInfo, pHandle, capacity, p, &newgroup);
|
||||
if (p->info.rows == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (newgroup) {
|
||||
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
||||
}
|
||||
|
||||
applyLimitOffset(&pInfo->limitInfo, p, pTaskInfo);
|
||||
|
||||
if (p->info.rows > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->info.rows > 0) {
|
||||
int32_t numOfCols = taosArrayGetSize(pColMatchInfo);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColMatchItem* pmInfo = taosArrayGet(pColMatchInfo, i);
|
||||
|
||||
SColumnInfoData* pSrc = taosArrayGet(p->pDataBlock, pmInfo->srcSlotId);
|
||||
SColumnInfoData* pDst = taosArrayGet(pDataBlock->pDataBlock, pmInfo->dstSlotId);
|
||||
colDataAssign(pDst, pSrc, p->info.rows, &pDataBlock->info);
|
||||
}
|
||||
|
||||
pDataBlock->info.rows = p->info.rows;
|
||||
pDataBlock->info.scanFlag = p->info.scanFlag;
|
||||
if (pInfo->ignoreGroupId) {
|
||||
pDataBlock->info.id.groupId = 0;
|
||||
} else {
|
||||
pDataBlock->info.id.groupId = pInfo->groupId;
|
||||
}
|
||||
pDataBlock->info.dataLoad = 1;
|
||||
}
|
||||
|
||||
qDebug("%s get sorted block, groupId:0x%" PRIx64 " rows:%" PRId64 , GET_TASKID(pTaskInfo), pDataBlock->info.id.groupId,
|
||||
pDataBlock->info.rows);
|
||||
|
||||
return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
|
||||
}
|
||||
|
||||
SSDataBlock* doMultiwayMerge(SOperatorInfo* pOperator) {
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SMultiwayMergeOperatorInfo* pInfo = pOperator->info;
|
||||
|
||||
int32_t code = pOperator->fpSet._openFn(pOperator);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
qDebug("start to merge final sorted rows, %s", GET_TASKID(pTaskInfo));
|
||||
SSDataBlock* pBlock = getMultiwaySortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pInfo->matchInfo.pList, pOperator);
|
||||
if (pBlock != NULL) {
|
||||
pOperator->resultInfo.totalRows += pBlock->info.rows;
|
||||
} else {
|
||||
setOperatorCompleted(pOperator);
|
||||
}
|
||||
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
void destroyMultiwayMergeOperatorInfo(void* param) {
|
||||
SMultiwayMergeOperatorInfo* pInfo = (SMultiwayMergeOperatorInfo*)param;
|
||||
pInfo->binfo.pRes = blockDataDestroy(pInfo->binfo.pRes);
|
||||
pInfo->pInputBlock = blockDataDestroy(pInfo->pInputBlock);
|
||||
pInfo->pIntermediateBlock = blockDataDestroy(pInfo->pIntermediateBlock);
|
||||
|
||||
tsortDestroySortHandle(pInfo->pSortHandle);
|
||||
taosArrayDestroy(pInfo->pSortInfo);
|
||||
taosArrayDestroy(pInfo->matchInfo.pList);
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
int32_t getMultiwayMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
|
||||
SSortExecInfo* pSortExecInfo = taosMemoryCalloc(1, sizeof(SSortExecInfo));
|
||||
|
||||
SMultiwayMergeOperatorInfo* pInfo = (SMultiwayMergeOperatorInfo*)pOptr->info;
|
||||
|
||||
*pSortExecInfo = tsortGetSortExecInfo(pInfo->pSortHandle);
|
||||
*pOptrExplain = pSortExecInfo;
|
||||
|
||||
*len = sizeof(SSortExecInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SOperatorInfo* createMultiwayMergeOperatorInfo(SOperatorInfo** downStreams, size_t numStreams,
|
||||
SMergePhysiNode* pMergePhyNode, SExecTaskInfo* pTaskInfo) {
|
||||
SPhysiNode* pPhyNode = (SPhysiNode*)pMergePhyNode;
|
||||
|
||||
SMultiwayMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SMultiwayMergeOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
SDataBlockDescNode* pDescNode = pPhyNode->pOutputDataBlockDesc;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
initLimitInfo(pMergePhyNode->node.pLimit, pMergePhyNode->node.pSlimit, &pInfo->limitInfo);
|
||||
pInfo->binfo.pRes = createDataBlockFromDescNode(pDescNode);
|
||||
|
||||
int32_t rowSize = pInfo->binfo.pRes->info.rowSize;
|
||||
int32_t numOfOutputCols = 0;
|
||||
code = extractColMatchInfo(pMergePhyNode->pTargets, pDescNode, &numOfOutputCols, COL_MATCH_FROM_SLOT_ID,
|
||||
&pInfo->matchInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, 0);
|
||||
SSDataBlock* pInputBlock = createDataBlockFromDescNode(pChildNode->pOutputDataBlockDesc);
|
||||
|
||||
initResultSizeInfo(&pOperator->resultInfo, 1024);
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
||||
pInfo->groupSort = pMergePhyNode->groupSort;
|
||||
pInfo->ignoreGroupId = pMergePhyNode->ignoreGroupId;
|
||||
pInfo->pSortInfo = createSortInfo(pMergePhyNode->pMergeKeys);
|
||||
pInfo->pInputBlock = pInputBlock;
|
||||
size_t numOfCols = taosArrayGetSize(pInfo->binfo.pRes->pDataBlock);
|
||||
pInfo->bufPageSize = getProperSortPageSize(rowSize, numOfCols);
|
||||
pInfo->sortBufSize = pInfo->bufPageSize * (numStreams + 1); // one additional is reserved for merged result.
|
||||
pInfo->binfo.inputTsOrder = pMergePhyNode->node.inputTsOrder;
|
||||
pInfo->binfo.outputTsOrder = pMergePhyNode->node.outputTsOrder;
|
||||
pInfo->inputWithGroupId = pMergePhyNode->inputWithGroupId;
|
||||
|
||||
setOperatorInfo(pOperator, "MultiwayMergeOperator", QUERY_NODE_PHYSICAL_PLAN_MERGE, false, OP_NOT_OPENED, pInfo, pTaskInfo);
|
||||
pOperator->fpSet = createOperatorFpSet(openMultiwayMergeOperator, doMultiwayMerge, NULL,
|
||||
destroyMultiwayMergeOperatorInfo, optrDefaultBufFn, getMultiwayMergeExplainExecInfo, optrDefaultGetNextExtFn, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, downStreams, numStreams);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
if (pInfo != NULL) {
|
||||
destroyMultiwayMergeOperatorInfo(pInfo);
|
||||
}
|
||||
|
||||
pTaskInfo->code = code;
|
||||
taosMemoryFree(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,751 @@
|
|||
/*
|
||||
* 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 "executorInt.h"
|
||||
#include "filter.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
#include "operator.h"
|
||||
#include "querytask.h"
|
||||
#include "tchecksum.h"
|
||||
#include "tcommon.h"
|
||||
#include "tcompare.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tfill.h"
|
||||
#include "tglobal.h"
|
||||
#include "tlog.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#define IS_FINAL_EVENT_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_EVENT)
|
||||
#define STREAM_EVENT_OP_STATE_NAME "StreamEventHistoryState"
|
||||
#define STREAM_EVENT_OP_CHECKPOINT_NAME "StreamEventOperator_Checkpoint"
|
||||
|
||||
typedef struct SEventWinfowFlag {
|
||||
bool startFlag;
|
||||
bool endFlag;
|
||||
} SEventWinfowFlag;
|
||||
|
||||
typedef struct SEventWindowInfo {
|
||||
SResultWindowInfo winInfo;
|
||||
SEventWinfowFlag* pWinFlag;
|
||||
} SEventWindowInfo;
|
||||
|
||||
void destroyStreamEventOperatorInfo(void* param) {
|
||||
SStreamEventAggOperatorInfo* pInfo = (SStreamEventAggOperatorInfo*)param;
|
||||
cleanupBasicInfo(&pInfo->binfo);
|
||||
destroyStreamAggSupporter(&pInfo->streamAggSup);
|
||||
clearGroupResInfo(&pInfo->groupResInfo);
|
||||
cleanupExprSupp(&pInfo->scalarSupp);
|
||||
if (pInfo->pChildren != NULL) {
|
||||
int32_t size = taosArrayGetSize(pInfo->pChildren);
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i);
|
||||
destroyOperator(pChild);
|
||||
}
|
||||
taosArrayDestroy(pInfo->pChildren);
|
||||
}
|
||||
colDataDestroy(&pInfo->twAggSup.timeWindowData);
|
||||
blockDataDestroy(pInfo->pDelRes);
|
||||
tSimpleHashCleanup(pInfo->pSeUpdated);
|
||||
tSimpleHashCleanup(pInfo->pAllUpdated);
|
||||
tSimpleHashCleanup(pInfo->pSeDeleted);
|
||||
pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated);
|
||||
cleanupGroupResInfo(&pInfo->groupResInfo);
|
||||
|
||||
taosArrayDestroy(pInfo->historyWins);
|
||||
blockDataDestroy(pInfo->pCheckpointRes);
|
||||
|
||||
if (pInfo->pStartCondInfo != NULL) {
|
||||
filterFreeInfo(pInfo->pStartCondInfo);
|
||||
pInfo->pStartCondInfo = NULL;
|
||||
}
|
||||
|
||||
if (pInfo->pEndCondInfo != NULL) {
|
||||
filterFreeInfo(pInfo->pEndCondInfo);
|
||||
pInfo->pEndCondInfo = NULL;
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
void setEventWindowFlag(SStreamAggSupporter* pAggSup, SEventWindowInfo* pWinInfo) {
|
||||
char* pFlagInfo = (char*)pWinInfo->winInfo.pStatePos->pRowBuff + (pAggSup->resultRowSize - pAggSup->stateKeySize);
|
||||
pWinInfo->pWinFlag = (SEventWinfowFlag*) pFlagInfo;
|
||||
}
|
||||
|
||||
void setEventWindowInfo(SStreamAggSupporter* pAggSup, SSessionKey* pKey, SRowBuffPos* pPos, SEventWindowInfo* pWinInfo) {
|
||||
pWinInfo->winInfo.sessionWin = *pKey;
|
||||
pWinInfo->winInfo.pStatePos = pPos;
|
||||
setEventWindowFlag(pAggSup, pWinInfo);
|
||||
}
|
||||
|
||||
int32_t getEndCondIndex(bool* pEnd, int32_t start, int32_t rows) {
|
||||
for (int32_t i = start; i < rows; i++) {
|
||||
if (pEnd[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void setEventOutputBuf(SStreamAggSupporter* pAggSup, TSKEY* pTs, uint64_t groupId, bool* pStart, bool* pEnd, int32_t index, int32_t rows, SEventWindowInfo* pCurWin, SSessionKey* pNextWinKey) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t size = pAggSup->resultRowSize;
|
||||
TSKEY ts = pTs [index];
|
||||
bool start = pStart[index];
|
||||
bool end = pEnd[index];
|
||||
pCurWin->winInfo.sessionWin.groupId = groupId;
|
||||
pCurWin->winInfo.sessionWin.win.skey = ts;
|
||||
pCurWin->winInfo.sessionWin.win.ekey = ts;
|
||||
SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyCurrentPrev(pAggSup->pState, &pCurWin->winInfo.sessionWin);
|
||||
SSessionKey leftWinKey = {.groupId = groupId};
|
||||
void* pVal = NULL;
|
||||
int32_t len = 0;
|
||||
code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &leftWinKey, &pVal, &len);
|
||||
if (code == TSDB_CODE_SUCCESS && inWinRange(&pAggSup->winRange, &leftWinKey.win) ) {
|
||||
bool inWin = isInTimeWindow(&leftWinKey.win, ts, 0);
|
||||
setEventWindowInfo(pAggSup, &leftWinKey, pVal, pCurWin);
|
||||
if(inWin || (pCurWin->pWinFlag->startFlag && !pCurWin->pWinFlag->endFlag) ) {
|
||||
pCurWin->winInfo.isOutput = true;
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
pAggSup->stateStore.streamStateFreeCur(pCur);
|
||||
pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pCurWin->winInfo.sessionWin);
|
||||
SSessionKey rightWinKey = {.groupId = groupId};
|
||||
code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &rightWinKey, &pVal, &len);
|
||||
bool inWin = isInTimeWindow(&rightWinKey.win, ts, 0);
|
||||
if (code == TSDB_CODE_SUCCESS && inWinRange(&pAggSup->winRange, &rightWinKey.win) && (inWin || (start && !end))) {
|
||||
int32_t endi = getEndCondIndex(pEnd, index, rows);
|
||||
if (endi < 0 || pTs[endi] >= rightWinKey.win.skey) {
|
||||
setEventWindowInfo(pAggSup, &rightWinKey, pVal, pCurWin);
|
||||
pCurWin->winInfo.isOutput = true;
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
|
||||
SSessionKey winKey = {.win.skey = ts, .win.ekey = ts, .groupId = groupId};
|
||||
pAggSup->stateStore.streamStateSessionAllocWinBuffByNextPosition(pAggSup->pState, pCur, &winKey, &pVal, &len);
|
||||
setEventWindowInfo(pAggSup, &winKey, pVal, pCurWin);
|
||||
pCurWin->pWinFlag->startFlag = start;
|
||||
pCurWin->pWinFlag->endFlag = end;
|
||||
pCurWin->winInfo.isOutput = false;
|
||||
|
||||
_end:
|
||||
pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pCur);
|
||||
pNextWinKey->groupId = groupId;
|
||||
code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, pNextWinKey, NULL, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
SET_SESSION_WIN_KEY_INVALID(pNextWinKey);
|
||||
}
|
||||
if(pCurWin->winInfo.pStatePos->needFree) {
|
||||
pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->winInfo.sessionWin);
|
||||
}
|
||||
pAggSup->stateStore.streamStateFreeCur(pCur);
|
||||
qDebug("===stream===set event next win buff. skey:%" PRId64 ", endkey:%" PRId64, pCurWin->winInfo.sessionWin.win.skey,
|
||||
pCurWin->winInfo.sessionWin.win.ekey);
|
||||
}
|
||||
|
||||
int32_t updateEventWindowInfo(SStreamAggSupporter* pAggSup, SEventWindowInfo* pWinInfo, SSessionKey* pNextWinKey,
|
||||
TSKEY* pTsData, bool* starts, bool* ends, int32_t rows, int32_t start, SSHashObj* pResultRows,
|
||||
SSHashObj* pStUpdated, SSHashObj* pStDeleted, bool* pRebuild) {
|
||||
*pRebuild = false;
|
||||
if (!pWinInfo->pWinFlag->startFlag && !(starts[start]) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
TSKEY maxTs = INT64_MAX;
|
||||
STimeWindow* pWin = &pWinInfo->winInfo.sessionWin.win;
|
||||
if (pWinInfo->pWinFlag->endFlag) {
|
||||
maxTs = pWin->ekey + 1;
|
||||
}
|
||||
if (!IS_INVALID_SESSION_WIN_KEY(*pNextWinKey)) {
|
||||
maxTs = TMIN(maxTs, pNextWinKey->win.skey);
|
||||
}
|
||||
|
||||
for (int32_t i = start; i < rows; ++i) {
|
||||
if (pTsData[i] >= maxTs) {
|
||||
return i - 1 - start;
|
||||
}
|
||||
|
||||
if (pWin->skey > pTsData[i]) {
|
||||
if (pStDeleted && pWinInfo->winInfo.isOutput) {
|
||||
saveDeleteRes(pStDeleted, pWinInfo->winInfo.sessionWin);
|
||||
}
|
||||
removeSessionResult(pAggSup, pStUpdated, pResultRows, &pWinInfo->winInfo.sessionWin);
|
||||
pWin->skey = pTsData[i];
|
||||
pWinInfo->pWinFlag->startFlag = starts[i];
|
||||
} else if (pWin->skey == pTsData[i]) {
|
||||
pWinInfo->pWinFlag->startFlag |= starts[i];
|
||||
}
|
||||
|
||||
if (pWin->ekey < pTsData[i]) {
|
||||
pWin->ekey = pTsData[i];
|
||||
pWinInfo->pWinFlag->endFlag = ends[i];
|
||||
} else if (pWin->ekey == pTsData[i]) {
|
||||
pWinInfo->pWinFlag->endFlag |= ends[i];
|
||||
}
|
||||
|
||||
memcpy(pWinInfo->winInfo.pStatePos->pKey, &pWinInfo->winInfo.sessionWin, sizeof(SSessionKey));
|
||||
|
||||
if (ends[i]) {
|
||||
if (pWinInfo->pWinFlag->endFlag && pWin->skey <= pTsData[i] && pTsData[i] < pWin->ekey ) {
|
||||
*pRebuild = true;
|
||||
}
|
||||
return i + 1 - start;
|
||||
}
|
||||
}
|
||||
return rows - start;
|
||||
}
|
||||
|
||||
static int32_t compactEventWindow(SOperatorInfo* pOperator, SEventWindowInfo* pCurWin, SSHashObj* pStUpdated,
|
||||
SSHashObj* pStDeleted, bool addGap) {
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI;
|
||||
int32_t winNum = 0;
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
SResultRow* pCurResult = NULL;
|
||||
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
while (1) {
|
||||
if (!pCurWin->pWinFlag->startFlag || pCurWin->pWinFlag->endFlag) {
|
||||
break;
|
||||
}
|
||||
SEventWindowInfo nextWinInfo = {0};
|
||||
getNextSessionWinInfo(pAggSup, pStUpdated, &pCurWin->winInfo, &nextWinInfo.winInfo);
|
||||
if (!IS_VALID_SESSION_WIN(nextWinInfo.winInfo) || !inWinRange(&pAggSup->winRange, &nextWinInfo.winInfo.sessionWin.win)) {
|
||||
releaseOutputBuf(pAggSup->pState, nextWinInfo.winInfo.pStatePos, &pAggSup->pSessionAPI->stateStore);
|
||||
break;
|
||||
}
|
||||
setEventWindowFlag(pAggSup, &nextWinInfo);
|
||||
compactTimeWindow(pSup, pAggSup, &pInfo->twAggSup, pTaskInfo, &pCurWin->winInfo, &nextWinInfo.winInfo, pStUpdated, pStDeleted, false);
|
||||
pCurWin->pWinFlag->endFlag = nextWinInfo.pWinFlag->endFlag;
|
||||
winNum++;
|
||||
}
|
||||
return winNum;
|
||||
}
|
||||
|
||||
static bool isWindowIncomplete(SEventWindowInfo* pWinInfo) {
|
||||
return !(pWinInfo->pWinFlag->startFlag && pWinInfo->pWinFlag->endFlag);
|
||||
}
|
||||
|
||||
bool doDeleteEventWindow(SStreamAggSupporter* pAggSup, SSHashObj* pSeUpdated, SSessionKey* pKey) {
|
||||
pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, pKey);
|
||||
removeSessionResult(pAggSup, pSeUpdated, pAggSup->pResultRows, pKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void doStreamEventAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pSeUpdated,
|
||||
SSHashObj* pStDeleted) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI;
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
|
||||
uint64_t groupId = pSDataBlock->info.id.groupId;
|
||||
int64_t code = TSDB_CODE_SUCCESS;
|
||||
TSKEY* tsCols = NULL;
|
||||
SResultRow* pResult = NULL;
|
||||
int32_t winRows = 0;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
SColumnInfoData* pColStart = NULL;
|
||||
SColumnInfoData* pColEnd = NULL;
|
||||
|
||||
pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version);
|
||||
pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow;
|
||||
if (pAggSup->winRange.ekey <= 0) {
|
||||
pAggSup->winRange.ekey = INT64_MAX;
|
||||
}
|
||||
|
||||
if (pSDataBlock->pDataBlock != NULL) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
tsCols = (int64_t*)pColDataInfo->pData;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
SFilterColumnParam paramStart = {.numOfCols = taosArrayGetSize(pSDataBlock->pDataBlock), .pDataBlock = pSDataBlock->pDataBlock};
|
||||
code = filterSetDataFromSlotId(pInfo->pStartCondInfo, ¶mStart);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("set data from start slotId error.");
|
||||
goto _end;
|
||||
}
|
||||
int32_t statusStart = 0;
|
||||
filterExecute(pInfo->pStartCondInfo, pSDataBlock, &pColStart, NULL, paramStart.numOfCols, &statusStart);
|
||||
|
||||
SFilterColumnParam paramEnd = {.numOfCols = taosArrayGetSize(pSDataBlock->pDataBlock), .pDataBlock = pSDataBlock->pDataBlock};
|
||||
code = filterSetDataFromSlotId(pInfo->pEndCondInfo, ¶mEnd);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("set data from end slotId error.");
|
||||
goto _end;
|
||||
}
|
||||
|
||||
int32_t statusEnd = 0;
|
||||
filterExecute(pInfo->pEndCondInfo, pSDataBlock, &pColEnd, NULL, paramEnd.numOfCols, &statusEnd);
|
||||
|
||||
int32_t rows = pSDataBlock->info.rows;
|
||||
blockDataEnsureCapacity(pAggSup->pScanBlock, rows);
|
||||
for (int32_t i = 0; i < rows; i += winRows) {
|
||||
if (pInfo->ignoreExpiredData && isOverdue(tsCols[i], &pInfo->twAggSup)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
int32_t winIndex = 0;
|
||||
bool allEqual = true;
|
||||
SEventWindowInfo curWin = {0};
|
||||
SSessionKey nextWinKey = {0};
|
||||
setEventOutputBuf(pAggSup, tsCols, groupId, (bool*)pColStart->pData, (bool*)pColEnd->pData, i, rows, &curWin, &nextWinKey);
|
||||
setSessionWinOutputInfo(pSeUpdated, &curWin.winInfo);
|
||||
bool rebuild = false;
|
||||
winRows = updateEventWindowInfo(pAggSup, &curWin, &nextWinKey, tsCols, (bool*)pColStart->pData, (bool*)pColEnd->pData, rows, i,
|
||||
pAggSup->pResultRows, pSeUpdated, pStDeleted, &rebuild);
|
||||
ASSERT(winRows >= 1);
|
||||
if (rebuild) {
|
||||
uint64_t uid = 0;
|
||||
appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey,
|
||||
&curWin.winInfo.sessionWin.win.ekey, &uid, &groupId, NULL);
|
||||
tSimpleHashRemove(pSeUpdated, &curWin.winInfo.sessionWin, sizeof(SSessionKey));
|
||||
doDeleteEventWindow(pAggSup, pSeUpdated, &curWin.winInfo.sessionWin);
|
||||
releaseOutputBuf(pAggSup->pState, curWin.winInfo.pStatePos, &pAPI->stateStore);
|
||||
continue;
|
||||
}
|
||||
code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput,
|
||||
pOperator, 0);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
compactEventWindow(pOperator, &curWin, pInfo->pSeUpdated, pInfo->pSeDeleted, false);
|
||||
saveSessionOutputBuf(pAggSup, &curWin.winInfo);
|
||||
|
||||
if (pInfo->isHistoryOp) {
|
||||
saveResult(curWin.winInfo, pInfo->pAllUpdated);
|
||||
}
|
||||
|
||||
if (isWindowIncomplete(&curWin)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
|
||||
code = saveResult(curWin.winInfo, pSeUpdated);
|
||||
}
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
SSessionKey key = {0};
|
||||
getSessionHashKey(&curWin.winInfo.sessionWin, &key);
|
||||
tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curWin.winInfo, sizeof(SResultWindowInfo));
|
||||
}
|
||||
}
|
||||
|
||||
_end:
|
||||
colDataDestroy(pColStart);
|
||||
taosMemoryFree(pColStart);
|
||||
colDataDestroy(pColEnd);
|
||||
taosMemoryFree(pColEnd);
|
||||
}
|
||||
|
||||
int32_t doStreamEventEncodeOpState(void** buf, int32_t len, SOperatorInfo* pOperator) {
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
if (!pInfo) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* pData = (buf == NULL) ? NULL : *buf;
|
||||
|
||||
// 1.streamAggSup.pResultRows
|
||||
int32_t tlen = 0;
|
||||
int32_t mapSize = tSimpleHashGetSize(pInfo->streamAggSup.pResultRows);
|
||||
tlen += taosEncodeFixedI32(buf, mapSize);
|
||||
void* pIte = NULL;
|
||||
size_t keyLen = 0;
|
||||
int32_t iter = 0;
|
||||
while ((pIte = tSimpleHashIterate(pInfo->streamAggSup.pResultRows, pIte, &iter)) != NULL) {
|
||||
void* key = tSimpleHashGetKey(pIte, &keyLen);
|
||||
tlen += encodeSSessionKey(buf, key);
|
||||
tlen += encodeSResultWindowInfo(buf, pIte, pInfo->streamAggSup.resultRowSize);
|
||||
}
|
||||
|
||||
// 2.twAggSup
|
||||
tlen += encodeSTimeWindowAggSupp(buf, &pInfo->twAggSup);
|
||||
|
||||
// 3.dataVersion
|
||||
tlen += taosEncodeFixedI32(buf, pInfo->dataVersion);
|
||||
|
||||
// 4.checksum
|
||||
if (buf) {
|
||||
uint32_t cksum = taosCalcChecksum(0, pData, len - sizeof(uint32_t));
|
||||
tlen += taosEncodeFixedU32(buf, cksum);
|
||||
} else {
|
||||
tlen += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
return tlen;
|
||||
}
|
||||
|
||||
void* doStreamEventDecodeOpState(void* buf, int32_t len, SOperatorInfo* pOperator) {
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
if (!pInfo) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
// 4.checksum
|
||||
int32_t dataLen = len - sizeof(uint32_t);
|
||||
void* pCksum = POINTER_SHIFT(buf, dataLen);
|
||||
if (taosCheckChecksum(buf, dataLen, *(uint32_t*)pCksum) != TSDB_CODE_SUCCESS) {
|
||||
ASSERT(0); // debug
|
||||
qError("stream event state is invalid");
|
||||
return buf;
|
||||
}
|
||||
|
||||
// 1.streamAggSup.pResultRows
|
||||
int32_t mapSize = 0;
|
||||
buf = taosDecodeFixedI32(buf, &mapSize);
|
||||
for (int32_t i = 0; i < mapSize; i++) {
|
||||
SSessionKey key = {0};
|
||||
SResultWindowInfo winfo = {0};
|
||||
buf = decodeSSessionKey(buf, &key);
|
||||
buf = decodeSResultWindowInfo(buf, &winfo, pInfo->streamAggSup.resultRowSize);
|
||||
tSimpleHashPut(pInfo->streamAggSup.pResultRows, &key, sizeof(SSessionKey), &winfo, sizeof(SResultWindowInfo));
|
||||
}
|
||||
|
||||
// 2.twAggSup
|
||||
buf = decodeSTimeWindowAggSupp(buf, &pInfo->twAggSup);
|
||||
|
||||
// 3.dataVersion
|
||||
buf = taosDecodeFixedI64(buf, &pInfo->dataVersion);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void doStreamEventSaveCheckpoint(SOperatorInfo* pOperator) {
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
int32_t len = doStreamEventEncodeOpState(NULL, 0, pOperator);
|
||||
void* buf = taosMemoryCalloc(1, len);
|
||||
void* pBuf = buf;
|
||||
len = doStreamEventEncodeOpState(&pBuf, len, pOperator);
|
||||
pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_EVENT_OP_CHECKPOINT_NAME,
|
||||
strlen(STREAM_EVENT_OP_CHECKPOINT_NAME), buf, len);
|
||||
taosMemoryFree(buf);
|
||||
}
|
||||
|
||||
static SSDataBlock* buildEventResult(SOperatorInfo* pOperator) {
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
|
||||
if (pInfo->pDelRes->info.rows > 0) {
|
||||
printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pDelRes;
|
||||
}
|
||||
|
||||
doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes);
|
||||
if (pBInfo->pRes->info.rows > 0) {
|
||||
printDataBlock(pBInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pBInfo->pRes;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SSDataBlock* doStreamEventAgg(SOperatorInfo* pOperator) {
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
qDebug("===stream=== stream event agg");
|
||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
SSDataBlock* resBlock = buildEventResult(pOperator);
|
||||
if (resBlock != NULL) {
|
||||
return resBlock;
|
||||
}
|
||||
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
if (!pInfo->pUpdated) {
|
||||
pInfo->pUpdated = taosArrayInit(16, sizeof(SEventWindowInfo));
|
||||
}
|
||||
if (!pInfo->pSeUpdated) {
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pSeUpdated = tSimpleHashInit(64, hashFn);
|
||||
}
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
}
|
||||
printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo));
|
||||
|
||||
if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
|
||||
pBlock->info.type == STREAM_CLEAR) {
|
||||
deleteSessionWinState(&pInfo->streamAggSup, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pSeUpdated);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) {
|
||||
return pBlock;
|
||||
} else if (pBlock->info.type == STREAM_CHECKPOINT) {
|
||||
pInfo->streamAggSup.stateStore.streamStateCommit(pInfo->streamAggSup.pState);
|
||||
doStreamEventSaveCheckpoint(pOperator);
|
||||
pInfo->reCkBlock = true;
|
||||
copyDataBlock(pInfo->pCheckpointRes, pBlock);
|
||||
continue;
|
||||
} else {
|
||||
ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type");
|
||||
}
|
||||
|
||||
if (pInfo->scalarSupp.pExprInfo != NULL) {
|
||||
SExprSupp* pExprSup = &pInfo->scalarSupp;
|
||||
projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL);
|
||||
}
|
||||
// the pDataBlock are always the same one, no need to call this again
|
||||
setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true);
|
||||
doStreamEventAggImpl(pOperator, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
}
|
||||
// restore the value
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
|
||||
closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pInfo->pSeUpdated);
|
||||
copyUpdateResult(&pInfo->pSeUpdated, pInfo->pUpdated, sessionKeyCompareAsc);
|
||||
removeSessionDeleteResults(pInfo->pSeDeleted, pInfo->pUpdated);
|
||||
|
||||
if (pInfo->isHistoryOp) {
|
||||
SArray* pHisWins = taosArrayInit(16, sizeof(SEventWindowInfo));
|
||||
copyUpdateResult(&pInfo->pAllUpdated, pHisWins, sessionKeyCompareAsc);
|
||||
getMaxTsWins(pHisWins, pInfo->historyWins);
|
||||
taosArrayDestroy(pHisWins);
|
||||
}
|
||||
|
||||
initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated);
|
||||
pInfo->pUpdated = NULL;
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
||||
SSDataBlock* resBlock = buildEventResult(pOperator);
|
||||
if (resBlock != NULL) {
|
||||
return resBlock;
|
||||
}
|
||||
setOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void streamEventReleaseState(SOperatorInfo* pOperator) {
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
int32_t winSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey);
|
||||
int32_t resSize = winSize + sizeof(TSKEY);
|
||||
char* pBuff = taosMemoryCalloc(1, resSize);
|
||||
memcpy(pBuff, pInfo->historyWins->pData, winSize);
|
||||
memcpy(pBuff + winSize, &pInfo->twAggSup.maxTs, sizeof(TSKEY));
|
||||
qDebug("===stream=== event window operator relase state. save result count:%d", (int32_t)taosArrayGetSize(pInfo->historyWins));
|
||||
pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_EVENT_OP_STATE_NAME,
|
||||
strlen(STREAM_EVENT_OP_STATE_NAME), pBuff, resSize);
|
||||
pInfo->streamAggSup.stateStore.streamStateCommit(pInfo->streamAggSup.pState);
|
||||
taosMemoryFreeClear(pBuff);
|
||||
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
if (downstream->fpSet.releaseStreamStateFn) {
|
||||
downstream->fpSet.releaseStreamStateFn(downstream);
|
||||
}
|
||||
}
|
||||
|
||||
void streamEventReloadState(SOperatorInfo* pOperator) {
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
resetWinRange(&pAggSup->winRange);
|
||||
|
||||
SSessionKey seKey = {.win.skey = INT64_MIN, .win.ekey = INT64_MIN, .groupId = 0};
|
||||
int32_t size = 0;
|
||||
void* pBuf = NULL;
|
||||
int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_EVENT_OP_STATE_NAME,
|
||||
strlen(STREAM_EVENT_OP_STATE_NAME), &pBuf, &size);
|
||||
int32_t num = (size - sizeof(TSKEY)) / sizeof(SSessionKey);
|
||||
qDebug("===stream=== event window operator reload state. get result count:%d", num);
|
||||
SSessionKey* pSeKeyBuf = (SSessionKey*)pBuf;
|
||||
ASSERT(size == num * sizeof(SSessionKey) + sizeof(TSKEY));
|
||||
|
||||
TSKEY ts = *(TSKEY*)((char*)pBuf + size - sizeof(TSKEY));
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, ts);
|
||||
pAggSup->stateStore.streamStateReloadInfo(pAggSup->pState, ts);
|
||||
|
||||
if (!pInfo->pSeUpdated && num > 0) {
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pSeUpdated = tSimpleHashInit(64, hashFn);
|
||||
}
|
||||
if (!pInfo->pSeDeleted && num > 0) {
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pSeDeleted = tSimpleHashInit(64, hashFn);
|
||||
}
|
||||
for (int32_t i = 0; i < num; i++) {
|
||||
SEventWindowInfo curInfo = {0};
|
||||
qDebug("===stream=== reload state. try process result %" PRId64 ", %" PRIu64 ", index:%d", pSeKeyBuf[i].win.skey,
|
||||
pSeKeyBuf[i].groupId, i);
|
||||
getSessionWindowInfoByKey(pAggSup, pSeKeyBuf + i, &curInfo.winInfo);
|
||||
setEventWindowFlag(pAggSup, &curInfo);
|
||||
if (!curInfo.pWinFlag->startFlag || curInfo.pWinFlag->endFlag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
compactEventWindow(pOperator, &curInfo, pInfo->pSeUpdated, pInfo->pSeDeleted, false);
|
||||
qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, curInfo.winInfo.sessionWin.win.skey,
|
||||
curInfo.winInfo.sessionWin.groupId);
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
|
||||
saveResult(curInfo.winInfo, pInfo->pSeUpdated);
|
||||
} else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
if (!isCloseWindow(&curInfo.winInfo.sessionWin.win, &pInfo->twAggSup)) {
|
||||
saveDeleteRes(pInfo->pSeDeleted, curInfo.winInfo.sessionWin);
|
||||
}
|
||||
SSessionKey key = {0};
|
||||
getSessionHashKey(&curInfo.winInfo.sessionWin, &key);
|
||||
tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curInfo.winInfo, sizeof(SResultWindowInfo));
|
||||
}
|
||||
|
||||
if (IS_VALID_SESSION_WIN(curInfo.winInfo)) {
|
||||
saveSessionOutputBuf(pAggSup, &curInfo.winInfo);
|
||||
}
|
||||
}
|
||||
taosMemoryFree(pBuf);
|
||||
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
if (downstream->fpSet.reloadStreamStateFn) {
|
||||
downstream->fpSet.reloadStreamStateFn(downstream);
|
||||
}
|
||||
}
|
||||
|
||||
SOperatorInfo* createStreamEventAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
|
||||
SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) {
|
||||
SStreamEventWinodwPhysiNode* pEventNode = (SStreamEventWinodwPhysiNode*)pPhyNode;
|
||||
int32_t tsSlotId = ((SColumnNode*)pEventNode->window.pTspk)->slotId;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SStreamEventAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamEventAggOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||
if (pEventNode->window.pExprs != NULL) {
|
||||
int32_t numOfScalar = 0;
|
||||
SExprInfo* pScalarExprInfo = createExprInfo(pEventNode->window.pExprs, NULL, &numOfScalar);
|
||||
code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
}
|
||||
|
||||
pInfo->twAggSup = (STimeWindowAggSupp){
|
||||
.waterMark = pEventNode->window.watermark,
|
||||
.calTrigger = pEventNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.minTs = INT64_MAX,
|
||||
};
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
||||
SExprSupp* pExpSup = &pOperator->exprSupp;
|
||||
int32_t numOfCols = 0;
|
||||
SExprInfo* pExprInfo = createExprInfo(pEventNode->window.pFuncs, NULL, &numOfCols);
|
||||
SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc);
|
||||
code = initBasicInfoEx(&pInfo->binfo, pExpSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
code = initStreamAggSupporter(&pInfo->streamAggSup, pExpSup, numOfCols, 0, pTaskInfo->streamInfo.pState,
|
||||
sizeof(bool) + sizeof(bool), 0, &pTaskInfo->storageAPI.stateStore, pHandle,
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->primaryTsIndex = tsSlotId;
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pSeDeleted = tSimpleHashInit(64, hashFn);
|
||||
pInfo->pDelIterator = NULL;
|
||||
pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT);
|
||||
pInfo->pChildren = NULL;
|
||||
pInfo->ignoreExpiredData = pEventNode->window.igExpired;
|
||||
pInfo->ignoreExpiredDataSaved = false;
|
||||
pInfo->pUpdated = NULL;
|
||||
pInfo->pSeUpdated = NULL;
|
||||
pInfo->dataVersion = 0;
|
||||
pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey));
|
||||
if (!pInfo->historyWins) {
|
||||
goto _error;
|
||||
}
|
||||
if (pHandle) {
|
||||
pInfo->isHistoryOp = pHandle->fillHistory;
|
||||
}
|
||||
|
||||
if (pInfo->isHistoryOp) {
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pAllUpdated = tSimpleHashInit(64, hashFn);
|
||||
} else {
|
||||
pInfo->pAllUpdated = NULL;
|
||||
}
|
||||
|
||||
pInfo->pCheckpointRes = createSpecialDataBlock(STREAM_CHECKPOINT);
|
||||
pInfo->reCkBlock = false;
|
||||
|
||||
// for stream
|
||||
void* buff = NULL;
|
||||
int32_t len = 0;
|
||||
int32_t res =
|
||||
pInfo->streamAggSup.stateStore.streamStateGetInfo(pInfo->streamAggSup.pState, STREAM_EVENT_OP_CHECKPOINT_NAME,
|
||||
strlen(STREAM_EVENT_OP_CHECKPOINT_NAME), &buff, &len);
|
||||
if (res == TSDB_CODE_SUCCESS) {
|
||||
doStreamEventDecodeOpState(buff, len, pOperator);
|
||||
taosMemoryFree(buff);
|
||||
}
|
||||
|
||||
setOperatorInfo(pOperator, "StreamEventAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT, true, OP_NOT_OPENED,
|
||||
pInfo, pTaskInfo);
|
||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamEventAgg, NULL, destroyStreamEventOperatorInfo,
|
||||
optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
|
||||
setOperatorStreamStateFn(pOperator, streamEventReleaseState, streamEventReloadState);
|
||||
initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup);
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
code = filterInitFromNode((SNode*)pEventNode->pStartCond, &pInfo->pStartCondInfo, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
code = filterInitFromNode((SNode*)pEventNode->pEndCond, &pInfo->pEndCondInfo, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
destroyStreamEventOperatorInfo(pInfo);
|
||||
taosMemoryFreeClear(pOperator);
|
||||
pTaskInfo->code = code;
|
||||
return NULL;
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define IS_FINAL_INTERVAL_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL)
|
||||
#define IS_FINAL_SESSION_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION)
|
||||
#define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL);
|
||||
#define DEAULT_DELETE_MARK INT64_MAX
|
||||
#define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState"
|
||||
#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState"
|
||||
#define STREAM_STATE_OP_STATE_NAME "StreamStateHistoryState"
|
||||
|
@ -146,7 +146,7 @@ static int32_t savePullWindow(SPullWindowInfo* pPullInfo, SArray* pPullWins) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t saveResult(SResultWindowInfo winInfo, SSHashObj* pStUpdated) {
|
||||
int32_t saveResult(SResultWindowInfo winInfo, SSHashObj* pStUpdated) {
|
||||
winInfo.sessionWin.win.ekey = winInfo.sessionWin.win.skey;
|
||||
return tSimpleHashPut(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo));
|
||||
}
|
||||
|
@ -279,7 +279,12 @@ static int32_t getAllIntervalWindow(SSHashObj* pHashMap, SSHashObj* resWins) {
|
|||
SWinKey* pKey = tSimpleHashGetKey(pIte, NULL);
|
||||
uint64_t groupId = pKey->groupId;
|
||||
TSKEY ts = pKey->ts;
|
||||
int32_t code = saveWinResultInfo(ts, groupId, *(SRowBuffPos**)pIte, resWins);
|
||||
SRowBuffPos* pPos = *(SRowBuffPos**)pIte;
|
||||
if (!pPos->beUpdated) {
|
||||
continue;
|
||||
}
|
||||
pPos->beUpdated = false;
|
||||
int32_t code = saveWinResultInfo(ts, groupId, pPos, resWins);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -848,6 +853,7 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat
|
|||
pSup->rowEntryInfoOffset, &pInfo->aggSup, &pInfo->stateStore);
|
||||
pResult = (SResultRow*)pResPos->pRowBuff;
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
qError("%s set interval output buff error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
if (IS_FINAL_INTERVAL_OP(pOperator)) {
|
||||
|
@ -866,6 +872,7 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat
|
|||
}
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
pResPos->beUpdated = true;
|
||||
tSimpleHashPut(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey), &pResPos, POINTER_BYTES);
|
||||
}
|
||||
|
||||
|
@ -1076,7 +1083,6 @@ void doStreamIntervalDecodeOpState(void* buf, int32_t len, SOperatorInfo* pOpera
|
|||
int32_t dataLen = len - sizeof(uint32_t);
|
||||
void* pCksum = POINTER_SHIFT(buf, dataLen);
|
||||
if (taosCheckChecksum(buf, dataLen, *(uint32_t*)pCksum) != TSDB_CODE_SUCCESS) {
|
||||
ASSERT(0); // debug
|
||||
qError("stream interval state is invalid");
|
||||
return;
|
||||
}
|
||||
|
@ -1159,7 +1165,7 @@ static SSDataBlock* buildIntervalResult(SOperatorInfo* pOperator) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t copyUpdateResult(SSHashObj** ppWinUpdated, SArray* pUpdated, __compar_fn_t compar) {
|
||||
int32_t copyUpdateResult(SSHashObj** ppWinUpdated, SArray* pUpdated, __compar_fn_t compar) {
|
||||
void* pIte = NULL;
|
||||
int32_t iter = 0;
|
||||
while ((pIte = tSimpleHashIterate(*ppWinUpdated, pIte, &iter)) != NULL) {
|
||||
|
@ -1237,7 +1243,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
tSimpleHashCleanup(pInfo->pUpdatedMap);
|
||||
pInfo->pUpdatedMap = NULL;
|
||||
}
|
||||
|
||||
qInfo("%s task is killed, code %s", GET_TASKID(pTaskInfo), tstrerror(pTaskInfo->code));
|
||||
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
||||
}
|
||||
|
||||
|
@ -1768,8 +1774,9 @@ int32_t reuseOutputBuf(void* pState, SRowBuffPos* pPos, SStateStore* pAPI) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void removeSessionResult(SStreamAggSupporter* pAggSup, SSHashObj* pHashMap, SSHashObj* pResMap, SSessionKey key) {
|
||||
key.win.ekey = key.win.skey;
|
||||
void removeSessionResult(SStreamAggSupporter* pAggSup, SSHashObj* pHashMap, SSHashObj* pResMap, SSessionKey* pKey) {
|
||||
SSessionKey key = {0};
|
||||
getSessionHashKey(pKey, &key);
|
||||
void* pVal = tSimpleHashGet(pHashMap, &key, sizeof(SSessionKey));
|
||||
if (pVal) {
|
||||
releaseOutputBuf(pAggSup->pState, *(void**)pVal, &pAggSup->pSessionAPI->stateStore);
|
||||
|
@ -1778,12 +1785,12 @@ static void removeSessionResult(SStreamAggSupporter* pAggSup, SSHashObj* pHashMa
|
|||
tSimpleHashRemove(pResMap, &key, sizeof(SSessionKey));
|
||||
}
|
||||
|
||||
static void getSessionHashKey(const SSessionKey* pKey, SSessionKey* pHashKey) {
|
||||
void getSessionHashKey(const SSessionKey* pKey, SSessionKey* pHashKey) {
|
||||
*pHashKey = *pKey;
|
||||
pHashKey->win.ekey = pKey->win.skey;
|
||||
}
|
||||
|
||||
static void removeSessionDeleteResults(SSHashObj* pHashMap, SArray* pWins) {
|
||||
void removeSessionDeleteResults(SSHashObj* pHashMap, SArray* pWins) {
|
||||
if (tSimpleHashGetSize(pHashMap) == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -1797,7 +1804,7 @@ static void removeSessionDeleteResults(SSHashObj* pHashMap, SArray* pWins) {
|
|||
}
|
||||
}
|
||||
|
||||
static void removeSessionResults(SStreamAggSupporter* pAggSup, SSHashObj* pHashMap, SArray* pWins) {
|
||||
void removeSessionResults(SStreamAggSupporter* pAggSup, SSHashObj* pHashMap, SArray* pWins) {
|
||||
if (tSimpleHashGetSize(pHashMap) == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -1826,7 +1833,7 @@ int32_t updateSessionWindowInfo(SStreamAggSupporter* pAggSup, SResultWindowInfo*
|
|||
if (pStDeleted && pWinInfo->isOutput) {
|
||||
saveDeleteRes(pStDeleted, pWinInfo->sessionWin);
|
||||
}
|
||||
removeSessionResult(pAggSup, pStUpdated, pResultRows, pWinInfo->sessionWin);
|
||||
removeSessionResult(pAggSup, pStUpdated, pResultRows, &pWinInfo->sessionWin);
|
||||
pWinInfo->sessionWin.win.skey = pStartTs[i];
|
||||
}
|
||||
pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pStartTs[i]);
|
||||
|
@ -1848,7 +1855,7 @@ static int32_t initSessionOutputBuf(SResultWindowInfo* pWinInfo, SResultRow** pR
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo* pCurWin, SResultRow** pResult,
|
||||
int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo* pCurWin, SResultRow** pResult,
|
||||
int32_t startIndex, int32_t winRows, int32_t rows, int32_t numOutput,
|
||||
SOperatorInfo* pOperator, int64_t winDelta) {
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
|
@ -1870,7 +1877,7 @@ static bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKe
|
|||
return true;
|
||||
}
|
||||
|
||||
static int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* pWinInfo) {
|
||||
int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* pWinInfo) {
|
||||
void* pVal = tSimpleHashGet(pStUpdated, &pWinInfo->sessionWin, sizeof(SSessionKey));
|
||||
if (pVal) {
|
||||
SResultWindowInfo* pWin = pVal;
|
||||
|
@ -1894,6 +1901,34 @@ void getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* pStUpdated,
|
|||
pAggSup->stateStore.streamStateFreeCur(pCur);
|
||||
}
|
||||
|
||||
void compactTimeWindow(SExprSupp* pSup, SStreamAggSupporter* pAggSup, STimeWindowAggSupp* pTwAggSup,
|
||||
SExecTaskInfo* pTaskInfo, SResultWindowInfo* pCurWin, SResultWindowInfo* pNextWin,
|
||||
SSHashObj* pStUpdated, SSHashObj* pStDeleted, bool addGap) {
|
||||
SResultRow* pCurResult = NULL;
|
||||
int32_t numOfOutput = pSup->numOfExprs;
|
||||
initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
SResultRow* pWinResult = NULL;
|
||||
initSessionOutputBuf(pNextWin, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, pNextWin->sessionWin.win.ekey);
|
||||
memcpy(pCurWin->pStatePos->pKey, &pCurWin->sessionWin, sizeof(SSessionKey));
|
||||
|
||||
int64_t winDelta = 0;
|
||||
if (addGap) {
|
||||
winDelta = pAggSup->gap;
|
||||
}
|
||||
updateTimeWindowInfo(&pTwAggSup->timeWindowData, &pCurWin->sessionWin.win, winDelta);
|
||||
compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pTwAggSup->timeWindowData);
|
||||
tSimpleHashRemove(pStUpdated, &pNextWin->sessionWin, sizeof(SSessionKey));
|
||||
if (pNextWin->isOutput && pStDeleted) {
|
||||
qDebug("===stream=== save delete window info %" PRId64 ", %" PRIu64, pNextWin->sessionWin.win.skey,
|
||||
pNextWin->sessionWin.groupId);
|
||||
saveDeleteRes(pStDeleted, pNextWin->sessionWin);
|
||||
}
|
||||
removeSessionResult(pAggSup, pStUpdated, pAggSup->pResultRows, &pNextWin->sessionWin);
|
||||
doDeleteSessionWindow(pAggSup, &pNextWin->sessionWin);
|
||||
releaseOutputBuf(pAggSup->pState, pNextWin->pStatePos, &pAggSup->pSessionAPI->stateStore);
|
||||
}
|
||||
|
||||
static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SSHashObj* pStUpdated,
|
||||
SSHashObj* pStDeleted, bool addGap) {
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
|
@ -1905,7 +1940,7 @@ static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo*
|
|||
SResultRow* pCurResult = NULL;
|
||||
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
// initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
// Just look for the window behind StartIndex
|
||||
while (1) {
|
||||
SResultWindowInfo winInfo = {0};
|
||||
|
@ -1915,23 +1950,7 @@ static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo*
|
|||
releaseOutputBuf(pAggSup->pState, winInfo.pStatePos, &pAggSup->pSessionAPI->stateStore);
|
||||
break;
|
||||
}
|
||||
SResultRow* pWinResult = NULL;
|
||||
initSessionOutputBuf(&winInfo, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, winInfo.sessionWin.win.ekey);
|
||||
memcpy(pCurWin->pStatePos->pKey, &pCurWin->sessionWin, sizeof(SSessionKey));
|
||||
int64_t winDelta = 0;
|
||||
if (addGap) {
|
||||
winDelta = pAggSup->gap;
|
||||
}
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, winDelta);
|
||||
compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData);
|
||||
tSimpleHashRemove(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey));
|
||||
if (winInfo.isOutput && pStDeleted) {
|
||||
saveDeleteRes(pStDeleted, winInfo.sessionWin);
|
||||
}
|
||||
removeSessionResult(pAggSup, pStUpdated, pAggSup->pResultRows, winInfo.sessionWin);
|
||||
doDeleteSessionWindow(pAggSup, &winInfo.sessionWin);
|
||||
releaseOutputBuf(pAggSup->pState, winInfo.pStatePos, &pAggSup->pSessionAPI->stateStore);
|
||||
compactTimeWindow(pSup, pAggSup, &pInfo->twAggSup, pTaskInfo, pCurWin, &winInfo, pStUpdated, pStDeleted, true);
|
||||
winNum++;
|
||||
}
|
||||
return winNum;
|
||||
|
@ -2017,6 +2036,7 @@ static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSData
|
|||
code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &winInfo, &pResult, i, winRows, rows, numOfOutput,
|
||||
pOperator, winDelta);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
qError("%s do stream session aggregate impl error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
compactSessionWindow(pOperator, &winInfo, pStUpdated, pStDeleted, addGap);
|
||||
|
@ -2025,6 +2045,7 @@ static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSData
|
|||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) {
|
||||
code = saveResult(winInfo, pStUpdated);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s do stream session aggregate impl, set result error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
@ -2038,7 +2059,7 @@ static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSData
|
|||
}
|
||||
}
|
||||
|
||||
static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result) {
|
||||
void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result) {
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
TSKEY* startDatas = (TSKEY*)pStartTsCol->pData;
|
||||
SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
|
@ -2060,7 +2081,7 @@ static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBloc
|
|||
}
|
||||
}
|
||||
|
||||
static inline int32_t sessionKeyCompareAsc(const void* pKey1, const void* pKey2) {
|
||||
inline int32_t sessionKeyCompareAsc(const void* pKey1, const void* pKey2) {
|
||||
SResultWindowInfo* pWinInfo1 = (SResultWindowInfo*)pKey1;
|
||||
SResultWindowInfo* pWinInfo2 = (SResultWindowInfo*)pKey2;
|
||||
SSessionKey* pWin1 = &pWinInfo1->sessionWin;
|
||||
|
@ -2490,8 +2511,7 @@ void* doStreamSessionDecodeOpState(void* buf, int32_t len, SOperatorInfo* pOpera
|
|||
int32_t dataLen = len - sizeof(uint32_t);
|
||||
void* pCksum = POINTER_SHIFT(buf, dataLen);
|
||||
if (taosCheckChecksum(buf, dataLen, *(uint32_t*)pCksum) != TSDB_CODE_SUCCESS) {
|
||||
ASSERT(0); // debug
|
||||
qError("stream interval state is invalid");
|
||||
qError("stream session state is invalid");
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
@ -2559,6 +2579,12 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
return opRes;
|
||||
}
|
||||
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
|
@ -2631,6 +2657,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
SOperatorInfo* pChildOp =
|
||||
createStreamFinalSessionAggOperatorInfo(NULL, pInfo->pPhyNode, pOperator->pTaskInfo, 0, NULL);
|
||||
if (!pChildOp) {
|
||||
qError("%s create stream child of final session error", GET_TASKID(pTaskInfo));
|
||||
T_LONG_JMP(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
taosArrayPush(pInfo->pChildren, &pChildOp);
|
||||
|
@ -2897,6 +2924,14 @@ static void clearStreamSessionOperator(SStreamSessionAggOperatorInfo* pInfo) {
|
|||
pInfo->streamAggSup.stateStore.streamStateSessionClear(pInfo->streamAggSup.pState);
|
||||
}
|
||||
|
||||
void deleteSessionWinState(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SSHashObj* pMapUpdate, SSHashObj* pMapDelete) {
|
||||
SArray* pWins = taosArrayInit(16, sizeof(SSessionKey));
|
||||
doDeleteTimeWindows(pAggSup, pBlock, pWins);
|
||||
removeSessionResults(pAggSup, pMapUpdate, pWins);
|
||||
copyDeleteWindowInfo(pWins, pMapDelete);
|
||||
taosArrayDestroy(pWins);
|
||||
}
|
||||
|
||||
static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
|
||||
SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
|
||||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
|
@ -2923,6 +2958,11 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
clearFunctionContext(&pOperator->exprSupp);
|
||||
// semi session operator clear disk buffer
|
||||
clearStreamSessionOperator(pInfo);
|
||||
|
@ -2951,11 +2991,7 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
|
|||
if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
|
||||
pBlock->info.type == STREAM_CLEAR) {
|
||||
// gap must be 0
|
||||
SArray* pWins = taosArrayInit(16, sizeof(SSessionKey));
|
||||
doDeleteTimeWindows(pAggSup, pBlock, pWins);
|
||||
removeSessionResults(pAggSup, pInfo->pStUpdated, pWins);
|
||||
copyDeleteWindowInfo(pWins, pInfo->pStDeleted);
|
||||
taosArrayDestroy(pWins);
|
||||
deleteSessionWinState(pAggSup, pBlock, pInfo->pStUpdated, pInfo->pStDeleted);
|
||||
pInfo->clearState = true;
|
||||
break;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
|
@ -3248,7 +3284,7 @@ int32_t updateStateWindowInfo(SStreamAggSupporter* pAggSup, SStateWindowInfo* pW
|
|||
if (pSeDeleted && pWinInfo->winInfo.isOutput) {
|
||||
saveDeleteRes(pSeDeleted, pWinInfo->winInfo.sessionWin);
|
||||
}
|
||||
removeSessionResult(pAggSup, pSeUpdated, pResultRows, pWinInfo->winInfo.sessionWin);
|
||||
removeSessionResult(pAggSup, pSeUpdated, pResultRows, &pWinInfo->winInfo.sessionWin);
|
||||
pWinInfo->winInfo.sessionWin.win.skey = pTs[i];
|
||||
}
|
||||
pWinInfo->winInfo.sessionWin.win.ekey = TMAX(pWinInfo->winInfo.sessionWin.win.ekey, pTs[i]);
|
||||
|
@ -3318,6 +3354,7 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
|
|||
code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput,
|
||||
pOperator, 0);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
qError("%s do one window aggregate impl error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
saveSessionOutputBuf(pAggSup, &curWin.winInfo);
|
||||
|
@ -3325,6 +3362,7 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
|
|||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
|
||||
code = saveResult(curWin.winInfo, pSeUpdated);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s do stream state aggregate impl, set result error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
@ -3396,8 +3434,7 @@ void* doStreamStateDecodeOpState(void* buf, int32_t len, SOperatorInfo* pOperato
|
|||
int32_t dataLen = len - sizeof(uint32_t);
|
||||
void* pCksum = POINTER_SHIFT(buf, dataLen);
|
||||
if (taosCheckChecksum(buf, dataLen, *(uint32_t*)pCksum) != TSDB_CODE_SUCCESS) {
|
||||
ASSERT(0); // debug
|
||||
qError("stream interval state is invalid");
|
||||
qError("stream state_window state is invalid");
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
@ -3475,6 +3512,12 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
|
|||
return resBlock;
|
||||
}
|
||||
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
|
@ -3501,11 +3544,7 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
|
||||
pBlock->info.type == STREAM_CLEAR) {
|
||||
SArray* pWins = taosArrayInit(16, sizeof(SSessionKey));
|
||||
doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins);
|
||||
removeSessionResults(&pInfo->streamAggSup, pInfo->pSeUpdated, pWins);
|
||||
copyDeleteWindowInfo(pWins, pInfo->pSeDeleted);
|
||||
taosArrayDestroy(pWins);
|
||||
deleteSessionWinState(&pInfo->streamAggSup, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
pInfo->recvGetAll = true;
|
||||
|
@ -3515,7 +3554,7 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
|
|||
return pBlock;
|
||||
} else if (pBlock->info.type == STREAM_CHECKPOINT) {
|
||||
pInfo->streamAggSup.stateStore.streamStateCommit(pInfo->streamAggSup.pState);
|
||||
doStreamSessionSaveCheckpoint(pOperator);
|
||||
doStreamStateSaveCheckpoint(pOperator);
|
||||
copyDataBlock(pInfo->pCheckpointRes, pBlock);
|
||||
continue;
|
||||
} else {
|
||||
|
@ -3577,29 +3616,8 @@ static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCur
|
|||
SSHashObj* pStUpdated, SSHashObj* pStDeleted) {
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI;
|
||||
|
||||
SStreamStateAggOperatorInfo* pInfo = pOperator->info;
|
||||
SResultRow* pCurResult = NULL;
|
||||
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
SResultRow* pWinResult = NULL;
|
||||
initSessionOutputBuf(pNextWin, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, pNextWin->sessionWin.win.ekey);
|
||||
memcpy(pCurWin->pStatePos->pKey, &pCurWin->sessionWin, sizeof(SSessionKey));
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, 1);
|
||||
compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData);
|
||||
tSimpleHashRemove(pStUpdated, &pNextWin->sessionWin, sizeof(SSessionKey));
|
||||
if (pNextWin->isOutput && pStDeleted) {
|
||||
qDebug("===stream=== save delete window info %" PRId64 ", %" PRIu64, pNextWin->sessionWin.win.skey,
|
||||
pNextWin->sessionWin.groupId);
|
||||
saveDeleteRes(pStDeleted, pNextWin->sessionWin);
|
||||
}
|
||||
removeSessionResult(pAggSup, pStUpdated, pAggSup->pResultRows, pNextWin->sessionWin);
|
||||
doDeleteSessionWindow(pAggSup, &pNextWin->sessionWin);
|
||||
releaseOutputBuf(pAggSup->pState, pNextWin->pStatePos, &pAggSup->pSessionAPI->stateStore);
|
||||
compactTimeWindow(pSup, &pInfo->streamAggSup, &pInfo->twAggSup, pTaskInfo, pCurWin, pNextWin, pStUpdated, pStDeleted, false);
|
||||
}
|
||||
|
||||
void streamStateReloadState(SOperatorInfo* pOperator) {
|
||||
|
@ -3771,12 +3789,6 @@ _error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void cleanupAfterGroupResultGen(SMergeAlignedIntervalAggOperatorInfo* pMiaInfo, SSDataBlock* pRes) {
|
||||
pRes->info.id.groupId = pMiaInfo->groupId;
|
||||
pMiaInfo->curTs = INT64_MIN;
|
||||
pMiaInfo->groupId = 0;
|
||||
}
|
||||
|
||||
static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (type == STREAM_INVERT) {
|
||||
|
|
|
@ -419,6 +419,7 @@ static int32_t logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
|
|||
COPY_SCALAR_FIELD(groupSort);
|
||||
CLONE_NODE_LIST_FIELD(pTags);
|
||||
CLONE_NODE_FIELD(pSubtable);
|
||||
COPY_SCALAR_FIELD(cacheLastMode);
|
||||
COPY_SCALAR_FIELD(igLastNull);
|
||||
COPY_SCALAR_FIELD(groupOrderScan);
|
||||
COPY_SCALAR_FIELD(onlyMetaCtbIdx);
|
||||
|
@ -443,8 +444,14 @@ static int32_t logicAggCopy(const SAggLogicNode* pSrc, SAggLogicNode* pDst) {
|
|||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
CLONE_NODE_LIST_FIELD(pGroupKeys);
|
||||
CLONE_NODE_LIST_FIELD(pAggFuncs);
|
||||
COPY_SCALAR_FIELD(hasLastRow);
|
||||
COPY_SCALAR_FIELD(hasLast);
|
||||
COPY_SCALAR_FIELD(hasTimeLineFunc);
|
||||
COPY_SCALAR_FIELD(onlyHasKeepOrderFunc);
|
||||
COPY_SCALAR_FIELD(hasGroupKeyOptimized);
|
||||
COPY_SCALAR_FIELD(isGroupTb);
|
||||
COPY_SCALAR_FIELD(isPartTb);
|
||||
COPY_SCALAR_FIELD(hasGroup);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -488,6 +495,8 @@ static int32_t logicMergeCopy(const SMergeLogicNode* pSrc, SMergeLogicNode* pDst
|
|||
CLONE_NODE_LIST_FIELD(pInputs);
|
||||
COPY_SCALAR_FIELD(numOfChannels);
|
||||
COPY_SCALAR_FIELD(srcGroupId);
|
||||
COPY_SCALAR_FIELD(colsMerge);
|
||||
COPY_SCALAR_FIELD(needSort);
|
||||
COPY_SCALAR_FIELD(groupSort);
|
||||
COPY_SCALAR_FIELD(ignoreGroupId);
|
||||
COPY_SCALAR_FIELD(inputWithGroupId);
|
||||
|
|
|
@ -2285,6 +2285,7 @@ static const char* jkMergePhysiPlanSrcGroupId = "SrcGroupId";
|
|||
static const char* jkMergePhysiPlanGroupSort = "GroupSort";
|
||||
static const char* jkMergePhysiPlanIgnoreGroupID = "IgnoreGroupID";
|
||||
static const char* jkMergePhysiPlanInputWithGroupId = "InputWithGroupId";
|
||||
static const char* jkMergePhysiPlanType = "Type";
|
||||
|
||||
static int32_t physiMergeNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SMergePhysiNode* pNode = (const SMergePhysiNode*)pObj;
|
||||
|
@ -2311,6 +2312,9 @@ static int32_t physiMergeNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkMergePhysiPlanInputWithGroupId, pNode->inputWithGroupId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkMergePhysiPlanType, pNode->type);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2337,6 +2341,9 @@ static int32_t jsonToPhysiMergeNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkMergePhysiPlanIgnoreGroupID, &pNode->ignoreGroupId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetIntValue(pJson, jkMergePhysiPlanType, (int32_t*)&pNode->type);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -2690,6 +2690,7 @@ enum {
|
|||
PHY_MERGE_CODE_GROUP_SORT,
|
||||
PHY_MERGE_CODE_IGNORE_GROUP_ID,
|
||||
PHY_MERGE_CODE_INPUT_WITH_GROUP_ID,
|
||||
PHY_MERGE_CODE_TYPE,
|
||||
};
|
||||
|
||||
static int32_t physiMergeNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
|
@ -2717,6 +2718,9 @@ static int32_t physiMergeNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeBool(pEncoder, PHY_MERGE_CODE_INPUT_WITH_GROUP_ID, pNode->inputWithGroupId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, PHY_MERGE_CODE_TYPE, pNode->type);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2752,6 +2756,9 @@ static int32_t msgToPhysiMergeNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case PHY_MERGE_CODE_INPUT_WITH_GROUP_ID:
|
||||
code = tlvDecodeBool(pTlv, &pNode->inputWithGroupId);
|
||||
break;
|
||||
case PHY_MERGE_CODE_TYPE:
|
||||
code = tlvDecodeI32(pTlv, (int32_t*)&pNode->type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1572,6 +1572,19 @@ int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc) {
|
|||
return code;
|
||||
}
|
||||
|
||||
|
||||
int32_t nodesListMakeStrictAppendList(SNodeList** pTarget, SNodeList* pSrc) {
|
||||
if (NULL == *pTarget) {
|
||||
*pTarget = nodesMakeList();
|
||||
if (NULL == *pTarget) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return nodesListStrictAppendList(*pTarget, pSrc);
|
||||
}
|
||||
|
||||
|
||||
int32_t nodesListPushFront(SNodeList* pList, SNode* pNode) {
|
||||
if (NULL == pList || NULL == pNode) {
|
||||
return TSDB_CODE_FAILED;
|
||||
|
|
|
@ -3925,6 +3925,267 @@ static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelec
|
|||
return code;
|
||||
}
|
||||
|
||||
typedef struct SEqCondTbNameTableInfo {
|
||||
SRealTableNode* pRealTable;
|
||||
SArray* aTbnames;
|
||||
} SEqCondTbNameTableInfo;
|
||||
|
||||
//[tableAlias.]tbname = tbNamVal
|
||||
static bool isOperatorEqTbnameCond(STranslateContext* pCxt, SOperatorNode* pOperator, char** ppTableAlias, SArray** ppTabNames) {
|
||||
if (pOperator->opType != OP_TYPE_EQUAL) return false;
|
||||
SFunctionNode* pTbnameFunc = NULL;
|
||||
SValueNode* pValueNode = NULL;
|
||||
if (nodeType(pOperator->pLeft) == QUERY_NODE_FUNCTION &&
|
||||
((SFunctionNode*)(pOperator->pLeft))->funcType == FUNCTION_TYPE_TBNAME &&
|
||||
nodeType(pOperator->pRight) == QUERY_NODE_VALUE) {
|
||||
pTbnameFunc = (SFunctionNode*)pOperator->pLeft;
|
||||
pValueNode = (SValueNode*)pOperator->pRight;
|
||||
} else if (nodeType(pOperator->pRight) == QUERY_NODE_FUNCTION &&
|
||||
((SFunctionNode*)(pOperator->pRight))->funcType == FUNCTION_TYPE_TBNAME &&
|
||||
nodeType(pOperator->pLeft) == QUERY_NODE_VALUE) {
|
||||
pTbnameFunc = (SFunctionNode*)pOperator->pRight;
|
||||
pValueNode = (SValueNode*)pOperator->pLeft;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LIST_LENGTH(pTbnameFunc->pParameterList) == 0) {
|
||||
*ppTableAlias = NULL;
|
||||
} else if (LIST_LENGTH(pTbnameFunc->pParameterList) == 1) {
|
||||
SNode* pQualNode = nodesListGetNode(pTbnameFunc->pParameterList, 0);
|
||||
if (nodeType(pQualNode) != QUERY_NODE_VALUE) return false;
|
||||
SValueNode* pQualValNode = (SValueNode*)pQualNode;
|
||||
*ppTableAlias = pQualValNode->literal;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
*ppTabNames = taosArrayInit(1, sizeof(void*));
|
||||
taosArrayPush(*ppTabNames, &(pValueNode->literal));
|
||||
return true;
|
||||
}
|
||||
|
||||
//[tableAlias.]tbname in (value1, value2, ...)
|
||||
static bool isOperatorTbnameInCond(STranslateContext* pCxt, SOperatorNode* pOperator, char** ppTableAlias, SArray** ppTbNames) {
|
||||
if (pOperator->opType != OP_TYPE_IN) return false;
|
||||
if (nodeType(pOperator->pLeft) != QUERY_NODE_FUNCTION ||
|
||||
((SFunctionNode*)(pOperator->pLeft))->funcType != FUNCTION_TYPE_TBNAME ||
|
||||
nodeType(pOperator->pRight) != QUERY_NODE_NODE_LIST) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SFunctionNode* pTbnameFunc = (SFunctionNode*)pOperator->pLeft;
|
||||
if (LIST_LENGTH(pTbnameFunc->pParameterList) == 0) {
|
||||
*ppTableAlias = NULL;
|
||||
} else if (LIST_LENGTH(pTbnameFunc->pParameterList) == 1) {
|
||||
SNode* pQualNode = nodesListGetNode(pTbnameFunc->pParameterList, 0);
|
||||
if (nodeType(pQualNode) != QUERY_NODE_VALUE) return false;
|
||||
SValueNode* pQualValNode = (SValueNode*)pQualNode;
|
||||
*ppTableAlias = pQualValNode->literal;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
*ppTbNames = taosArrayInit(1, sizeof(void*));
|
||||
SNodeListNode* pValueListNode = (SNodeListNode*)pOperator->pRight;
|
||||
SNodeList* pValueNodeList = pValueListNode->pNodeList;
|
||||
SNode* pValNode = NULL;
|
||||
FOREACH(pValNode, pValueNodeList) {
|
||||
if (nodeType(pValNode) != QUERY_NODE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
taosArrayPush(*ppTbNames, &((SValueNode*)pValNode)->literal);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static bool findEqCondTbNameInOperatorNode(STranslateContext* pCxt, SNode* pWhere, SEqCondTbNameTableInfo* pInfo) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
char* pTableAlias = NULL;
|
||||
char* pTbNameVal = NULL;
|
||||
if (isOperatorEqTbnameCond(pCxt, (SOperatorNode*)pWhere, &pTableAlias, &pInfo->aTbnames) ||
|
||||
isOperatorTbnameInCond(pCxt, (SOperatorNode*)pWhere, &pTableAlias, &pInfo->aTbnames)) {
|
||||
STableNode* pTable;
|
||||
if (pTableAlias == NULL) {
|
||||
pTable = (STableNode*)((SSelectStmt*)(pCxt->pCurrStmt))->pFromTable;
|
||||
} else {
|
||||
code = findTable(pCxt, pTableAlias, &pTable);
|
||||
}
|
||||
if (code == TSDB_CODE_SUCCESS && nodeType(pTable) == QUERY_NODE_REAL_TABLE &&
|
||||
((SRealTableNode*)pTable)->pMeta && ((SRealTableNode*)pTable)->pMeta->tableType == TSDB_SUPER_TABLE) {
|
||||
pInfo->pRealTable = (SRealTableNode*)pTable;
|
||||
return true;
|
||||
}
|
||||
taosArrayDestroy(pInfo->aTbnames);
|
||||
pInfo->aTbnames = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isTableExistInTableTbnames(SArray* aTableTbNames, SRealTableNode* pTable) {
|
||||
for (int i = 0; i < taosArrayGetSize(aTableTbNames); ++i) {
|
||||
SEqCondTbNameTableInfo* info = taosArrayGet(aTableTbNames, i);
|
||||
if (info->pRealTable == pTable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void findEqualCondTbnameInLogicCondAnd(STranslateContext* pCxt, SNode* pWhere, SArray* aTableTbnames) {
|
||||
SNode* pTmpNode = NULL;
|
||||
FOREACH(pTmpNode, ((SLogicConditionNode*)pWhere)->pParameterList) {
|
||||
if (nodeType(pTmpNode) == QUERY_NODE_OPERATOR) {
|
||||
SEqCondTbNameTableInfo info = {0};
|
||||
bool bIsEqTbnameCond = findEqCondTbNameInOperatorNode(pCxt, pTmpNode, &info);
|
||||
if (bIsEqTbnameCond) {
|
||||
if (!isTableExistInTableTbnames(aTableTbnames, info.pRealTable)) {
|
||||
//TODO: intersect tbNames of same table? speed
|
||||
taosArrayPush(aTableTbnames, &info);
|
||||
} else {
|
||||
taosArrayDestroy(info.aTbnames);
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: logic cond
|
||||
}
|
||||
}
|
||||
|
||||
static void unionEqualCondTbnamesOfSameTable(SArray* aTableTbnames, SEqCondTbNameTableInfo* pInfo) {
|
||||
bool bFoundTable = false;
|
||||
for (int i = 0; i < taosArrayGetSize(aTableTbnames); ++i) {
|
||||
SEqCondTbNameTableInfo* info = taosArrayGet(aTableTbnames, i);
|
||||
if (info->pRealTable == pInfo->pRealTable) {
|
||||
taosArrayAddAll(info->aTbnames, pInfo->aTbnames);
|
||||
taosArrayDestroy(pInfo->aTbnames);
|
||||
pInfo->aTbnames = NULL;
|
||||
bFoundTable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFoundTable) {
|
||||
taosArrayPush(aTableTbnames, pInfo);
|
||||
}
|
||||
}
|
||||
|
||||
static void findEqualCondTbnameInLogicCondOr(STranslateContext* pCxt, SNode* pWhere, SArray* aTableTbnames) {
|
||||
bool bAllTbName = true;
|
||||
SNode* pTmpNode = NULL;
|
||||
FOREACH(pTmpNode, ((SLogicConditionNode*)pWhere)->pParameterList) {
|
||||
//TODO: logic cond
|
||||
if (nodeType(pTmpNode) == QUERY_NODE_OPERATOR) {
|
||||
SEqCondTbNameTableInfo info = {0};
|
||||
bool bIsEqTbnameCond = findEqCondTbNameInOperatorNode(pCxt, pTmpNode, &info);
|
||||
if (!bIsEqTbnameCond) {
|
||||
bAllTbName = false;
|
||||
break;
|
||||
} else {
|
||||
unionEqualCondTbnamesOfSameTable(aTableTbnames, &info);
|
||||
}
|
||||
} else {
|
||||
bAllTbName = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bAllTbName) {
|
||||
for (int i = 0; i < taosArrayGetSize(aTableTbnames); ++i) {
|
||||
SEqCondTbNameTableInfo* pInfo = taosArrayGet(aTableTbnames, i);
|
||||
taosArrayDestroy(pInfo->aTbnames);
|
||||
pInfo->aTbnames = NULL;
|
||||
}
|
||||
taosArrayClear(aTableTbnames);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t findEqualCondTbname(STranslateContext* pCxt, SNode* pWhere, SArray* aTableTbnames) {
|
||||
//TODO: optimize nested and/or condition. now only the fist level is processed.
|
||||
if (nodeType(pWhere) == QUERY_NODE_OPERATOR) {
|
||||
SEqCondTbNameTableInfo info = {0};
|
||||
bool bIsEqTbnameCond = findEqCondTbNameInOperatorNode(pCxt, pWhere, &info);
|
||||
if (bIsEqTbnameCond) {
|
||||
taosArrayPush(aTableTbnames, &info);
|
||||
}
|
||||
} else if (nodeType(pWhere) == QUERY_NODE_LOGIC_CONDITION) {
|
||||
if (((SLogicConditionNode*)pWhere)->condType == LOGIC_COND_TYPE_AND) {
|
||||
findEqualCondTbnameInLogicCondAnd(pCxt, pWhere, aTableTbnames);
|
||||
} else if (((SLogicConditionNode*)pWhere)->condType == LOGIC_COND_TYPE_OR) {
|
||||
findEqualCondTbnameInLogicCondOr(pCxt, pWhere, aTableTbnames);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t findVgroupsFromEqualTbname(STranslateContext* pCxt, SEqCondTbNameTableInfo* pInfo, SVgroupsInfo* vgsInfo) {
|
||||
int32_t nVgroups = 0;
|
||||
int32_t nTbls = taosArrayGetSize(pInfo->aTbnames);
|
||||
|
||||
if (nTbls >= pInfo->pRealTable->pVgroupList->numOfVgroups) {
|
||||
vgsInfo->numOfVgroups = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
for (int j = 0; j < nTbls; ++j) {
|
||||
char* dbName = pInfo->pRealTable->table.dbName;
|
||||
SName snameTb;
|
||||
char* tbName = taosArrayGetP(pInfo->aTbnames, j);
|
||||
toName(pCxt->pParseCxt->acctId, dbName, tbName, &snameTb);
|
||||
SVgroupInfo vgInfo;
|
||||
bool bExists;
|
||||
int32_t code = catalogGetCachedTableHashVgroup(pCxt->pParseCxt->pCatalog, &snameTb, &vgInfo, &bExists);
|
||||
if (code == TSDB_CODE_SUCCESS && bExists) {
|
||||
bool bFoundVg = false;
|
||||
for (int32_t k = 0; k < nVgroups; ++k) {
|
||||
if (vgsInfo->vgroups[k].vgId == vgInfo.vgId) {
|
||||
bFoundVg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFoundVg) {
|
||||
vgsInfo->vgroups[nVgroups] = vgInfo;
|
||||
++nVgroups;
|
||||
vgsInfo->numOfVgroups = nVgroups;
|
||||
}
|
||||
} else {
|
||||
vgsInfo->numOfVgroups = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t setEqualTbnameTableVgroups(STranslateContext* pCxt, SSelectStmt* pSelect, SArray* aTables) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
for (int i = 0; i < taosArrayGetSize(aTables); ++i) {
|
||||
SEqCondTbNameTableInfo* pInfo = taosArrayGet(aTables, i);
|
||||
int32_t nTbls = taosArrayGetSize(pInfo->aTbnames);
|
||||
|
||||
SVgroupsInfo* vgsInfo = taosMemoryMalloc(sizeof(SVgroupsInfo) + nTbls * sizeof(SVgroupInfo));
|
||||
int32_t nVgroups = 0;
|
||||
findVgroupsFromEqualTbname(pCxt, pInfo, vgsInfo);
|
||||
if (vgsInfo->numOfVgroups != 0) {
|
||||
taosMemoryFree(pInfo->pRealTable->pVgroupList);
|
||||
pInfo->pRealTable->pVgroupList = vgsInfo;
|
||||
} else {
|
||||
taosMemoryFree(vgsInfo);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t setTableVgroupsFromEqualTbnameCond(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SArray* aTables = taosArrayInit(1, sizeof(SEqCondTbNameTableInfo));
|
||||
code = findEqualCondTbname(pCxt, pSelect->pWhere, aTables);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
code = setEqualTbnameTableVgroups(pCxt, pSelect, aTables);
|
||||
}
|
||||
for (int i = 0; i < taosArrayGetSize(aTables); ++i) {
|
||||
SEqCondTbNameTableInfo* pInfo = taosArrayGet(aTables, i);
|
||||
taosArrayDestroy(pInfo->aTbnames);
|
||||
}
|
||||
taosArrayDestroy(aTables);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
pCxt->currClause = SQL_CLAUSE_WHERE;
|
||||
int32_t code = translateExpr(pCxt, &pSelect->pWhere);
|
||||
|
@ -3934,6 +4195,9 @@ static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
if (TSDB_CODE_SUCCESS == code && pSelect->timeRange.skey > pSelect->timeRange.ekey) {
|
||||
pSelect->isEmptyResult = true;
|
||||
}
|
||||
if (pSelect->pWhere != NULL) {
|
||||
setTableVgroupsFromEqualTbnameCond(pCxt, pSelect);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -7099,7 +7363,7 @@ static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStm
|
|||
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
|
||||
if (TSDB_DATA_TYPE_TIMESTAMP != ((SExprNode*)nodesListGetNode(pSelect->pProjectionList, 0))->resType.type ||
|
||||
!isTimeLineQuery(pStmt->pQuery) || crossTableWithoutAggOper(pSelect) || NULL != pSelect->pOrderByList ||
|
||||
crossTableWithUdaf(pSelect) || isEventWindowQuery(pSelect) || hasJsonTypeProjection(pSelect)) {
|
||||
crossTableWithUdaf(pSelect) || hasJsonTypeProjection(pSelect)) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
|
||||
}
|
||||
if (NULL != pSelect->pSubtable && TSDB_DATA_TYPE_VARCHAR != ((SExprNode*)pSelect->pSubtable)->resType.type) {
|
||||
|
|
|
@ -43,6 +43,7 @@ int32_t optimizeLogicPlan(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan);
|
|||
int32_t splitLogicPlan(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan);
|
||||
int32_t scaleOutLogicPlan(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan, SQueryLogicPlan** pLogicPlan);
|
||||
int32_t createPhysiPlan(SPlanContext* pCxt, SQueryLogicPlan* pLogicPlan, SQueryPlan** pPlan, SArray* pExecNodeList);
|
||||
int32_t validateQueryPlan(SPlanContext* pCxt, SQueryPlan* pPlan);
|
||||
|
||||
bool getBatchScanOptionFromHint(SNodeList* pList);
|
||||
bool getSortForGroupOptHint(SNodeList* pList);
|
||||
|
|
|
@ -747,6 +747,7 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
|
||||
pAgg->isGroupTb = pAgg->pGroupKeys ? keysHasTbname(pAgg->pGroupKeys) : 0;
|
||||
pAgg->isPartTb = pSelect->pPartitionByList ? keysHasTbname(pSelect->pPartitionByList) : 0;
|
||||
pAgg->hasGroup = pAgg->pGroupKeys || pSelect->pPartitionByList;
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pLogicNode = (SLogicNode*)pAgg;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define OPTIMIZE_FLAG_PUSH_DOWN_CONDE OPTIMIZE_FLAG_MASK(1)
|
||||
|
||||
#define OPTIMIZE_FLAG_SET_MASK(val, mask) (val) |= (mask)
|
||||
#define OPTIMIZE_FLAG_CLEAR_MASK(val, mask) (val) &= (~(mask))
|
||||
#define OPTIMIZE_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
||||
|
||||
typedef struct SOptimizeContext {
|
||||
|
@ -2499,21 +2500,7 @@ static bool lastRowScanOptCheckColNum(int32_t lastColNum, col_id_t lastColId,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptMayBeOptimized(SLogicNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_AGG != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) ||
|
||||
QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SAggLogicNode* pAgg = (SAggLogicNode*)pNode;
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pNode->pChildren, 0);
|
||||
// Only one of LAST and LASTROW can appear
|
||||
if (pAgg->hasLastRow == pAgg->hasLast || NULL != pAgg->pGroupKeys || NULL != pScan->node.pConditions ||
|
||||
!hasSuitableCache(pScan->cacheLastMode, pAgg->hasLastRow, pAgg->hasLast) ||
|
||||
IS_TSWINDOW_SPECIFIED(pScan->scanRange)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, bool* hasOtherFunc) {
|
||||
bool hasNonPKSelectFunc = false;
|
||||
SNode* pFunc = NULL;
|
||||
int32_t lastColNum = 0, selectNonPKColNum = 0;
|
||||
|
@ -2559,8 +2546,43 @@ static bool lastRowScanOptMayBeOptimized(SLogicNode* pNode) {
|
|||
return false;
|
||||
}
|
||||
} else if (FUNCTION_TYPE_LAST_ROW != pAggFunc->funcType) {
|
||||
*hasOtherFunc = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptCheckLastCache(SAggLogicNode* pAgg, SScanLogicNode* pScan) {
|
||||
// Only one of LAST and LASTROW can appear
|
||||
if (pAgg->hasLastRow == pAgg->hasLast || (!pAgg->hasLast && !pAgg->hasLastRow) || NULL != pAgg->pGroupKeys || NULL != pScan->node.pConditions ||
|
||||
!hasSuitableCache(pScan->cacheLastMode, pAgg->hasLastRow, pAgg->hasLast) ||
|
||||
IS_TSWINDOW_SPECIFIED(pScan->scanRange)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptMayBeOptimized(SLogicNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_AGG != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) ||
|
||||
QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SAggLogicNode* pAgg = (SAggLogicNode*)pNode;
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pNode->pChildren, 0);
|
||||
if (!lastRowScanOptCheckLastCache(pAgg, pScan)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasOtherFunc = false;
|
||||
if (!lastRowScanOptCheckFuncList(pNode, &hasOtherFunc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasOtherFunc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2569,6 +2591,7 @@ static bool lastRowScanOptMayBeOptimized(SLogicNode* pNode) {
|
|||
typedef struct SLastRowScanOptSetColDataTypeCxt {
|
||||
bool doAgg;
|
||||
SNodeList* pLastCols;
|
||||
SNodeList* pOtherCols;
|
||||
} SLastRowScanOptSetColDataTypeCxt;
|
||||
|
||||
static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) {
|
||||
|
@ -2611,6 +2634,33 @@ static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCo
|
|||
}
|
||||
}
|
||||
|
||||
static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pList1, SNodeList* pList2) {
|
||||
SNode* pTarget = NULL;
|
||||
WHERE_EACH(pTarget, pTargets) {
|
||||
bool found = false;
|
||||
SNode* pCol = NULL;
|
||||
FOREACH(pCol, pList1) {
|
||||
if (nodesEqualNode(pCol, pTarget)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
FOREACH(pCol, pList2) {
|
||||
if (nodesEqualNode(pCol, pTarget)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
ERASE_NODE(pTargets);
|
||||
continue;
|
||||
}
|
||||
WHERE_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||
SAggLogicNode* pAgg = (SAggLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, lastRowScanOptMayBeOptimized);
|
||||
|
||||
|
@ -2618,7 +2668,7 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SLastRowScanOptSetColDataTypeCxt cxt = {.doAgg = true, .pLastCols = NULL};
|
||||
SLastRowScanOptSetColDataTypeCxt cxt = {.doAgg = true, .pLastCols = NULL, .pOtherCols = NULL};
|
||||
SNode* pNode = NULL;
|
||||
SColumnNode* pPKTsCol = NULL;
|
||||
SColumnNode* pNonPKCol = NULL;
|
||||
|
@ -2639,8 +2689,11 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
nodesWalkExpr(nodesListGetNode(pFunc->pParameterList, 0), lastRowScanOptSetColDataType, &cxt);
|
||||
nodesListErase(pFunc->pParameterList, nodesListGetCell(pFunc->pParameterList, 1));
|
||||
}
|
||||
} else if (FUNCTION_TYPE_SELECT_VALUE == funcType) {
|
||||
} else {
|
||||
pNode = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
nodesListMakeAppend(&cxt.pOtherCols, pNode);
|
||||
|
||||
if (FUNCTION_TYPE_SELECT_VALUE == funcType) {
|
||||
if (nodeType(pNode) == QUERY_NODE_COLUMN) {
|
||||
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||
if (pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||
|
@ -2651,6 +2704,7 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
||||
pScan->scanType = SCAN_TYPE_LAST_ROW;
|
||||
|
@ -2660,6 +2714,7 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
lastRowScanOptSetLastTargets(pScan->pScanCols, cxt.pLastCols, true);
|
||||
nodesWalkExprs(pScan->pScanPseudoCols, lastRowScanOptSetColDataType, &cxt);
|
||||
lastRowScanOptSetLastTargets(pScan->node.pTargets, cxt.pLastCols, false);
|
||||
lastRowScanOptRemoveUslessTargets(pScan->node.pTargets, cxt.pLastCols, cxt.pOtherCols);
|
||||
if (pPKTsCol && pScan->node.pTargets->length == 1) {
|
||||
// when select last(ts),ts from ..., we add another ts to targets
|
||||
sprintf(pPKTsCol->colName, "#sel_val.%p", pPKTsCol);
|
||||
|
@ -2679,6 +2734,241 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static bool splitCacheLastFuncOptMayBeOptimized(SLogicNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_AGG != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) ||
|
||||
QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SAggLogicNode* pAgg = (SAggLogicNode*)pNode;
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pNode->pChildren, 0);
|
||||
if (!lastRowScanOptCheckLastCache(pAgg, pScan)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasOtherFunc = false;
|
||||
if (!lastRowScanOptCheckFuncList(pNode, &hasOtherFunc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pAgg->hasGroup || !hasOtherFunc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t splitCacheLastFuncOptCreateAggLogicNode(SAggLogicNode** pNewAgg, SAggLogicNode* pAgg, SNodeList* pFunc, SNodeList* pTargets) {
|
||||
SAggLogicNode* pNew = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
|
||||
if (NULL == pNew) {
|
||||
nodesDestroyList(pFunc);
|
||||
nodesDestroyList(pTargets);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pNew->hasLastRow = false;
|
||||
pNew->hasLast = false;
|
||||
pNew->hasTimeLineFunc = pAgg->hasTimeLineFunc;
|
||||
pNew->hasGroupKeyOptimized = false;
|
||||
pNew->onlyHasKeepOrderFunc = pAgg->onlyHasKeepOrderFunc;
|
||||
pNew->node.groupAction = pAgg->node.groupAction;
|
||||
pNew->node.requireDataOrder = pAgg->node.requireDataOrder;
|
||||
pNew->node.resultDataOrder = pAgg->node.resultDataOrder;
|
||||
pNew->node.pTargets = pTargets;
|
||||
pNew->pAggFuncs = pFunc;
|
||||
pNew->pGroupKeys = nodesCloneList(pAgg->pGroupKeys);
|
||||
pNew->node.pConditions = nodesCloneNode(pAgg->node.pConditions);
|
||||
pNew->isGroupTb = pAgg->isGroupTb;
|
||||
pNew->isPartTb = pAgg->isPartTb;
|
||||
pNew->hasGroup = pAgg->hasGroup;
|
||||
pNew->node.pChildren = nodesCloneList(pAgg->node.pChildren);
|
||||
|
||||
int32_t code = 0;
|
||||
SNode* pNode = nodesListGetNode(pNew->node.pChildren, 0);
|
||||
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)pNode;
|
||||
SNodeList* pOldScanCols = NULL;
|
||||
TSWAP(pScan->pScanCols, pOldScanCols);
|
||||
nodesDestroyList(pScan->pScanPseudoCols);
|
||||
pScan->pScanPseudoCols = NULL;
|
||||
nodesDestroyList(pScan->node.pTargets);
|
||||
pScan->node.pTargets = NULL;
|
||||
SNodeListNode* list = (SNodeListNode*)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||
list->pNodeList = pFunc;
|
||||
code = nodesCollectColumnsFromNode((SNode*)list, NULL, COLLECT_COL_TYPE_COL, &pScan->pScanCols);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
nodesFree(list);
|
||||
bool found = false;
|
||||
FOREACH(pNode, pScan->pScanCols) {
|
||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pNode)->colId) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
FOREACH(pNode, pOldScanCols) {
|
||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pNode)->colId) {
|
||||
nodesListMakeStrictAppend(&pScan->pScanCols, nodesCloneNode(pNode));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nodesDestroyList(pOldScanCols);
|
||||
code = createColumnByRewriteExprs(pScan->pScanCols, &pScan->node.pTargets);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
OPTIMIZE_FLAG_CLEAR_MASK(pScan->node.optimizedFlag, OPTIMIZE_FLAG_SCAN_PATH);
|
||||
}
|
||||
|
||||
*pNewAgg = pNew;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t splitCacheLastFuncOptModifyAggLogicNode(SAggLogicNode* pAgg) {
|
||||
pAgg->hasTimeLineFunc = false;
|
||||
pAgg->onlyHasKeepOrderFunc = true;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t splitCacheLastFuncOptCreateMergeLogicNode(SMergeLogicNode** pNew, SAggLogicNode* pAgg1, SAggLogicNode* pAgg2) {
|
||||
SMergeLogicNode* pMerge = (SMergeLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_MERGE);
|
||||
if (NULL == pMerge) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pMerge->colsMerge = true;
|
||||
pMerge->numOfChannels = 2;
|
||||
pMerge->srcGroupId = -1;
|
||||
pMerge->node.precision = pAgg1->node.precision;
|
||||
|
||||
SNode* pNewAgg1 = nodesCloneNode((SNode*)pAgg1);
|
||||
SNode* pNewAgg2 = nodesCloneNode((SNode*)pAgg2);
|
||||
if (NULL == pNewAgg1 || NULL == pNewAgg2) {
|
||||
nodesDestroyNode(pNewAgg1);
|
||||
nodesDestroyNode(pNewAgg2);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
((SAggLogicNode*)pNewAgg1)->node.pParent = (SLogicNode*)pMerge;
|
||||
((SAggLogicNode*)pNewAgg2)->node.pParent = (SLogicNode*)pMerge;
|
||||
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, ((SAggLogicNode*)pNewAgg1)->node.pChildren) {
|
||||
((SLogicNode*)pNode)->pParent = (SLogicNode*)pNewAgg1;
|
||||
}
|
||||
FOREACH(pNode, ((SAggLogicNode*)pNewAgg2)->node.pChildren) {
|
||||
((SLogicNode*)pNode)->pParent = (SLogicNode*)pNewAgg2;
|
||||
}
|
||||
|
||||
int32_t code = nodesListMakeStrictAppendList(&pMerge->node.pTargets, nodesCloneList(pAgg1->node.pTargets));
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListMakeStrictAppendList(&pMerge->node.pTargets, nodesCloneList(pAgg2->node.pTargets));
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListMakeStrictAppend(&pMerge->node.pChildren, pNewAgg1);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListMakeStrictAppend(&pMerge->node.pChildren, pNewAgg2);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyNode(pNewAgg1);
|
||||
nodesDestroyNode(pNewAgg2);
|
||||
nodesDestroyNode((SNode*)pMerge);
|
||||
} else {
|
||||
*pNew = pMerge;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t splitCacheLastFuncOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||
SAggLogicNode* pAgg = (SAggLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, splitCacheLastFuncOptMayBeOptimized);
|
||||
|
||||
if (NULL == pAgg) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SNode* pNode = NULL;
|
||||
SNodeList* pAggFuncList = NULL;
|
||||
{
|
||||
WHERE_EACH(pNode, pAgg->pAggFuncs) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
int32_t funcType = pFunc->funcType;
|
||||
if (FUNCTION_TYPE_LAST_ROW != funcType && FUNCTION_TYPE_LAST != funcType &&
|
||||
FUNCTION_TYPE_SELECT_VALUE != funcType && FUNCTION_TYPE_GROUP_KEY != funcType) {
|
||||
nodesListMakeStrictAppend(&pAggFuncList, nodesCloneNode(pNode));
|
||||
ERASE_NODE(pAgg->pAggFuncs);
|
||||
continue;
|
||||
}
|
||||
WHERE_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == pAggFuncList) {
|
||||
planError("empty agg func list while splite projections, funcNum:%d", pAgg->pAggFuncs->length);
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
SNodeList* pTargets = NULL;
|
||||
{
|
||||
WHERE_EACH(pNode, pAgg->node.pTargets) {
|
||||
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||
SNode* pFuncNode = NULL;
|
||||
bool found = false;
|
||||
FOREACH(pFuncNode, pAggFuncList) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pFuncNode;
|
||||
if (0 == strcmp(pFunc->node.aliasName, pCol->colName)) {
|
||||
nodesListMakeStrictAppend(&pTargets, nodesCloneNode(pNode));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
ERASE_NODE(pAgg->node.pTargets);
|
||||
continue;
|
||||
}
|
||||
WHERE_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == pTargets) {
|
||||
planError("empty target func list while splite projections, targetsNum:%d", pAgg->node.pTargets->length);
|
||||
nodesDestroyList(pAggFuncList);
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
SMergeLogicNode* pMerge = NULL;
|
||||
SAggLogicNode* pNewAgg = NULL;
|
||||
int32_t code = splitCacheLastFuncOptCreateAggLogicNode(&pNewAgg, pAgg, pAggFuncList, pTargets);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = splitCacheLastFuncOptModifyAggLogicNode(pAgg);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = splitCacheLastFuncOptCreateMergeLogicNode(&pMerge, pNewAgg, pAgg);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = replaceLogicNode(pLogicSubplan, (SLogicNode*)pAgg, (SLogicNode*)pMerge);
|
||||
}
|
||||
|
||||
nodesDestroyNode((SNode *)pAgg);
|
||||
nodesDestroyNode((SNode *)pNewAgg);
|
||||
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyNode((SNode *)pMerge);
|
||||
}
|
||||
|
||||
pCxt->optimized = true;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// merge projects
|
||||
static bool mergeProjectsMayBeOptimized(SLogicNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren)) {
|
||||
|
@ -3762,6 +4052,7 @@ static const SOptimizeRule optimizeRuleSet[] = {
|
|||
{.pName = "MergeProjects", .optimizeFunc = mergeProjectsOptimize},
|
||||
{.pName = "RewriteTail", .optimizeFunc = rewriteTailOptimize},
|
||||
{.pName = "RewriteUnique", .optimizeFunc = rewriteUniqueOptimize},
|
||||
{.pName = "splitCacheLastFunc", .optimizeFunc = splitCacheLastFuncOptimize},
|
||||
{.pName = "LastRowScan", .optimizeFunc = lastRowScanOptimize},
|
||||
{.pName = "TagScan", .optimizeFunc = tagScanOptimize},
|
||||
{.pName = "TableCountScan", .optimizeFunc = tableCountScanOptimize},
|
||||
|
|
|
@ -1951,20 +1951,30 @@ static int32_t createExchangePhysiNodeByMerge(SMergePhysiNode* pMerge) {
|
|||
return nodesListMakeStrictAppend(&pMerge->node.pChildren, (SNode*)pExchange);
|
||||
}
|
||||
|
||||
static int32_t createMergePhysiNode(SPhysiPlanContext* pCxt, SMergeLogicNode* pMergeLogicNode, SPhysiNode** pPhyNode) {
|
||||
static int32_t createMergePhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SMergeLogicNode* pMergeLogicNode, SPhysiNode** pPhyNode) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SMergePhysiNode* pMerge =
|
||||
(SMergePhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pMergeLogicNode, QUERY_NODE_PHYSICAL_PLAN_MERGE);
|
||||
if (NULL == pMerge) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (pMergeLogicNode->colsMerge) {
|
||||
pMerge->type = MERGE_TYPE_COLUMNS;
|
||||
} else if (pMergeLogicNode->needSort) {
|
||||
pMerge->type = MERGE_TYPE_SORT;
|
||||
} else {
|
||||
pMerge->type = MERGE_TYPE_NON_SORT;
|
||||
}
|
||||
|
||||
pMerge->numOfChannels = pMergeLogicNode->numOfChannels;
|
||||
pMerge->srcGroupId = pMergeLogicNode->srcGroupId;
|
||||
pMerge->groupSort = pMergeLogicNode->groupSort;
|
||||
pMerge->ignoreGroupId = pMergeLogicNode->ignoreGroupId;
|
||||
pMerge->inputWithGroupId = pMergeLogicNode->inputWithGroupId;
|
||||
|
||||
int32_t code = addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc);
|
||||
if (!pMergeLogicNode->colsMerge) {
|
||||
code = addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc);
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
for (int32_t i = 0; i < pMerge->numOfChannels; ++i) {
|
||||
|
@ -1987,6 +1997,15 @@ static int32_t createMergePhysiNode(SPhysiPlanContext* pCxt, SMergeLogicNode* pM
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc);
|
||||
}
|
||||
} else {
|
||||
SDataBlockDescNode* pLeftDesc = ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc;
|
||||
SDataBlockDescNode* pRightDesc = ((SPhysiNode*)nodesListGetNode(pChildren, 1))->pOutputDataBlockDesc;
|
||||
|
||||
code = setListSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pMergeLogicNode->node.pTargets, &pMerge->pTargets);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc);
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pPhyNode = (SPhysiNode*)pMerge;
|
||||
|
@ -2023,7 +2042,7 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
|
|||
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||
return createInterpFuncPhysiNode(pCxt, pChildren, (SInterpFuncLogicNode*)pLogicNode, pPhyNode);
|
||||
case QUERY_NODE_LOGIC_PLAN_MERGE:
|
||||
return createMergePhysiNode(pCxt, (SMergeLogicNode*)pLogicNode, pPhyNode);
|
||||
return createMergePhysiNode(pCxt, pChildren, (SMergeLogicNode*)pLogicNode, pPhyNode);
|
||||
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
||||
return createGroupCachePhysiNode(pCxt, pChildren, (SGroupCacheLogicNode*)pLogicNode, pPhyNode);
|
||||
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
||||
|
|
|
@ -248,8 +248,6 @@ static bool stbSplHasMultiTbScan(bool streamQuery, SLogicNode* pNode) {
|
|||
}
|
||||
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pChild) && stbSplIsMultiTbScan(streamQuery, (SScanLogicNode*)pChild)) {
|
||||
return true;
|
||||
} else if (QUERY_NODE_LOGIC_PLAN_SORT == nodeType(pChild)) {
|
||||
return stbSplHasMultiTbScan(streamQuery, (SLogicNode*)pChild);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -540,11 +538,12 @@ static int32_t stbSplRewriteFromMergeNode(SMergeLogicNode* pMerge, SLogicNode* p
|
|||
}
|
||||
|
||||
static int32_t stbSplCreateMergeNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pSplitNode,
|
||||
SNodeList* pMergeKeys, SLogicNode* pPartChild, bool groupSort) {
|
||||
SNodeList* pMergeKeys, SLogicNode* pPartChild, bool groupSort, bool needSort) {
|
||||
SMergeLogicNode* pMerge = (SMergeLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_MERGE);
|
||||
if (NULL == pMerge) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pMerge->needSort = needSort;
|
||||
pMerge->numOfChannels = stbSplGetNumOfVgroups(pPartChild);
|
||||
pMerge->srcGroupId = pCxt->groupId;
|
||||
pMerge->node.precision = pPartChild->precision;
|
||||
|
@ -621,7 +620,7 @@ static int32_t stbSplSplitIntervalForBatch(SSplitContext* pCxt, SStableSplitInfo
|
|||
code = stbSplCreateMergeKeysByPrimaryKey(((SWindowLogicNode*)pInfo->pSplitNode)->pTspk,
|
||||
((SWindowLogicNode*)pInfo->pSplitNode)->node.outputTsOrder, &pMergeKeys);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = stbSplCreateMergeNode(pCxt, NULL, pInfo->pSplitNode, pMergeKeys, pPartWindow, true);
|
||||
code = stbSplCreateMergeNode(pCxt, NULL, pInfo->pSplitNode, pMergeKeys, pPartWindow, true, true);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyList(pMergeKeys);
|
||||
|
@ -712,7 +711,7 @@ static int32_t stbSplSplitSessionOrStateForBatch(SSplitContext* pCxt, SStableSpl
|
|||
((SWindowLogicNode*)pWindow)->node.inputTsOrder, &pMergeKeys);
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pChild, pMergeKeys, (SLogicNode*)pChild, true);
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pChild, pMergeKeys, (SLogicNode*)pChild, true, true);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -982,7 +981,7 @@ static int32_t stbSplAggNodeCreateMerge(SSplitContext* pCtx, SStableSplitInfo* p
|
|||
}
|
||||
}
|
||||
}
|
||||
code = stbSplCreateMergeNode(pCtx, NULL, pInfo->pSplitNode, pMergeKeys, pChildAgg, groupSort);
|
||||
code = stbSplCreateMergeNode(pCtx, NULL, pInfo->pSplitNode, pMergeKeys, pChildAgg, groupSort, true);
|
||||
if (TSDB_CODE_SUCCESS == code && sortForGroup) {
|
||||
SMergeLogicNode* pMerge =
|
||||
(SMergeLogicNode*)nodesListGetNode(pInfo->pSplitNode->pChildren, LIST_LENGTH(pInfo->pSplitNode->pChildren) - 1);
|
||||
|
@ -1145,7 +1144,7 @@ static int32_t stbSplSplitSortNode(SSplitContext* pCxt, SStableSplitInfo* pInfo)
|
|||
bool groupSort = ((SSortLogicNode*)pInfo->pSplitNode)->groupSort;
|
||||
int32_t code = stbSplCreatePartSortNode((SSortLogicNode*)pInfo->pSplitNode, &pPartSort, &pMergeKeys);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pInfo->pSplitNode, pMergeKeys, pPartSort, groupSort);
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pInfo->pSplitNode, pMergeKeys, pPartSort, groupSort, true);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
nodesDestroyNode((SNode*)pInfo->pSplitNode);
|
||||
|
@ -1195,7 +1194,7 @@ static int32_t stbSplSplitScanNodeWithPartTags(SSplitContext* pCxt, SStableSplit
|
|||
SLogicNode* pSplitNode = NULL;
|
||||
int32_t code = stbSplGetSplitNodeForScan(pInfo, &pSplitNode);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pSplitNode, NULL, pSplitNode, true);
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pSplitNode, NULL, pSplitNode, true, true);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
|
||||
|
@ -1269,7 +1268,7 @@ static int32_t stbSplSplitMergeScanNode(SSplitContext* pCxt, SLogicSubplan* pSub
|
|||
((SLimitNode*)pMergeScan->pLimit)->limit += ((SLimitNode*)pMergeScan->pLimit)->offset;
|
||||
((SLimitNode*)pMergeScan->pLimit)->offset = 0;
|
||||
}
|
||||
code = stbSplCreateMergeNode(pCxt, pSubplan, (SLogicNode*)pScan, pMergeKeys, pMergeScan, groupSort);
|
||||
code = stbSplCreateMergeNode(pCxt, pSubplan, (SLogicNode*)pScan, pMergeKeys, pMergeScan, groupSort, true);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
nodesDestroyNode((SNode*)pScan);
|
||||
|
@ -1345,7 +1344,7 @@ static int32_t stbSplSplitPartitionNode(SSplitContext* pCxt, SStableSplitInfo* p
|
|||
code = stbSplCreateMergeKeysForPartitionNode(pInfo->pSplitNode, &pMergeKeys);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pInfo->pSplitNode, pMergeKeys, pInfo->pSplitNode, true);
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pInfo->pSplitNode, pMergeKeys, pInfo->pSplitNode, true, true);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
|
||||
|
@ -1587,10 +1586,13 @@ typedef struct SSmaIndexSplitInfo {
|
|||
static bool smaIdxSplFindSplitNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pNode,
|
||||
SSmaIndexSplitInfo* pInfo) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_MERGE == nodeType(pNode) && LIST_LENGTH(pNode->pChildren) > 1) {
|
||||
int32_t nodeType = nodeType(nodesListGetNode(pNode->pChildren, 0));
|
||||
if (nodeType == QUERY_NODE_LOGIC_PLAN_EXCHANGE || nodeType == QUERY_NODE_LOGIC_PLAN_MERGE) {
|
||||
pInfo->pMerge = (SMergeLogicNode*)pNode;
|
||||
pInfo->pSubplan = pSubplan;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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 "planInt.h"
|
||||
|
||||
#include "catalog.h"
|
||||
#include "functionMgt.h"
|
||||
#include "systable.h"
|
||||
#include "tglobal.h"
|
||||
|
||||
typedef struct SValidatePlanContext {
|
||||
SPlanContext* pPlanCxt;
|
||||
int32_t errCode;
|
||||
} SValidatePlanContext;
|
||||
|
||||
int32_t doValidatePhysiNode(SValidatePlanContext* pCxt, SNode* pNode);
|
||||
|
||||
int32_t validateMergePhysiNode(SValidatePlanContext* pCxt, SMergePhysiNode* pMerge) {
|
||||
if ((NULL != pMerge->node.pLimit || NULL != pMerge->node.pSlimit) && pMerge->type == MERGE_TYPE_NON_SORT) {
|
||||
planError("no limit&slimit supported for non sort merge, pLimit:%p", pMerge->node.pLimit);
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t validateSubplanNode(SValidatePlanContext* pCxt, SSubplan* pSubPlan) {
|
||||
if (SUBPLAN_TYPE_MODIFY == pSubPlan->subplanType) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
return doValidatePhysiNode(pCxt, (SNode*)pSubPlan->pNode);
|
||||
}
|
||||
|
||||
int32_t validateQueryPlanNode(SValidatePlanContext* pCxt, SQueryPlan* pPlan) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pPlan->pSubplans) {
|
||||
if (QUERY_NODE_NODE_LIST != nodeType(pNode)) {
|
||||
code = TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
SNode* pSubNode = NULL;
|
||||
SNodeListNode* pSubplans = (SNodeListNode*)pNode;
|
||||
FOREACH(pSubNode, pSubplans->pNodeList) {
|
||||
if (QUERY_NODE_PHYSICAL_SUBPLAN != nodeType(pNode)) {
|
||||
code = TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
code = doValidatePhysiNode(pCxt, pSubNode);
|
||||
if (code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t doValidatePhysiNode(SValidatePlanContext* pCxt, SNode* pNode) {
|
||||
switch (nodeType(pNode)) {
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE:
|
||||
return validateMergePhysiNode(pCxt, (SMergePhysiNode*)pNode);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_DELETE:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_HASH_JOIN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_SUBPLAN:
|
||||
return validateSubplanNode(pCxt, (SSubplan*)pNode);
|
||||
case QUERY_NODE_PHYSICAL_PLAN:
|
||||
return validateQueryPlanNode(pCxt, (SQueryPlan *)pNode);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void destoryValidatePlanContext(SValidatePlanContext* pCxt) {
|
||||
|
||||
}
|
||||
|
||||
int32_t validateQueryPlan(SPlanContext* pCxt, SQueryPlan* pPlan) {
|
||||
SValidatePlanContext cxt = {.pPlanCxt = pCxt,
|
||||
.errCode = TSDB_CODE_SUCCESS
|
||||
};
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pPlan->pSubplans) {
|
||||
if (QUERY_NODE_NODE_LIST != nodeType(pNode)) {
|
||||
code = TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
SNode* pSubNode = NULL;
|
||||
SNodeListNode* pSubplans = (SNodeListNode*)pNode;
|
||||
FOREACH(pSubNode, pSubplans->pNodeList) {
|
||||
code = doValidatePhysiNode(&cxt, pSubNode);
|
||||
if (code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
destoryValidatePlanContext(&cxt);
|
||||
return code;
|
||||
}
|
|
@ -57,6 +57,9 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createPhysiPlan(pCxt, pLogicPlan, pPlan, pExecNodeList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = validateQueryPlan(pCxt, *pPlan);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
dumpQueryPlan(*pPlan);
|
||||
}
|
||||
|
|
|
@ -1083,6 +1083,15 @@ int32_t toISO8601Function(SScalarParam *pInput, int32_t inputNum, SScalarParam *
|
|||
memmove(fraction, fraction + TSDB_TIME_PRECISION_SEC_DIGITS, TSDB_TIME_PRECISION_SEC_DIGITS);
|
||||
}
|
||||
|
||||
// trans current timezone's unix ts to dest timezone
|
||||
// offset = delta from dest timezone to zero
|
||||
// delta from zero to current timezone = 3600 * (cur)tsTimezone
|
||||
int64_t offset = 0;
|
||||
if (0 != offsetOfTimezone(tz, &offset)) {
|
||||
goto _end;
|
||||
}
|
||||
timeVal -= offset + 3600 * ((int64_t)tsTimezone);
|
||||
|
||||
struct tm tmInfo;
|
||||
int32_t len = 0;
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ int32_t schHandleOpBeginEvent(int64_t jobId, SSchJob** job, SCH_OP_TYPE type, SS
|
|||
SSchJob* pJob = schAcquireJob(jobId);
|
||||
if (NULL == pJob) {
|
||||
qDebug("Acquire sch job failed, may be dropped, jobId:0x%" PRIx64, jobId);
|
||||
SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR);
|
||||
SCH_ERR_RET(TSDB_CODE_SCH_JOB_NOT_EXISTS);
|
||||
}
|
||||
|
||||
*job = pJob;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue