diff --git a/cmake/cmake.define b/cmake/cmake.define index 56b6b7e1de..44b36d0efa 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -170,7 +170,7 @@ ELSE () SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx2") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2") ENDIF() - MESSAGE(STATUS "SIMD instructions (FMA/AVX/AVX2/AVX512) is ACTIVATED") + MESSAGE(STATUS "SIMD instructions (FMA/AVX/AVX2) is ACTIVATED") IF (COMPILER_SUPPORT_AVX512F AND COMPILER_SUPPORT_AVX512BMI) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx512f -mavx512vbmi") diff --git a/docs/en/13-operation/07-import.md b/docs/en/13-operation/07-import.md index e95824e927..be0b988fc0 100644 --- a/docs/en/13-operation/07-import.md +++ b/docs/en/13-operation/07-import.md @@ -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. diff --git a/docs/en/13-operation/08-export.md b/docs/en/13-operation/08-export.md index bffda36e23..580844cf08 100644 --- a/docs/en/13-operation/08-export.md +++ b/docs/en/13-operation/08-export.md @@ -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. diff --git a/docs/en/13-operation/10-monitor.md b/docs/en/13-operation/10-monitor.md index b08216a9c4..f1be4c5fd3 100644 --- a/docs/en/13-operation/10-monitor.md +++ b/docs/en/13-operation/10-monitor.md @@ -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: diff --git a/docs/en/14-reference/03-connector/04-java.mdx b/docs/en/14-reference/03-connector/04-java.mdx index fd43dd67fa..f770ce0d5d 100644 --- a/docs/en/14-reference/03-connector/04-java.mdx +++ b/docs/en/14-reference/03-connector/04-java.mdx @@ -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: com.taosdata.jdbc taos-jdbcdriver - 3.2.2 + 3.2.7 ``` diff --git a/docs/en/14-reference/05-taosbenchmark.md b/docs/en/14-reference/05-taosbenchmark.md index 8e5ee178a4..4744e143fc 100644 --- a/docs/en/14-reference/05-taosbenchmark.md +++ b/docs/en/14-reference/05-taosbenchmark.md @@ -13,7 +13,7 @@ taosBenchmark (formerly taosdemo ) is a tool for testing the performance of TDen There are two ways to install taosBenchmark: -- Installing the official TDengine installer will automatically install taosBenchmark. +- Installing the official TDengine installer will automatically install taosBenchmark. - Compile taos-tools separately and install them. Please refer to the [taos-tools](https://github.com/taosdata/taos-tools) repository for details. diff --git a/docs/en/20-third-party/01-grafana.mdx b/docs/en/20-third-party/01-grafana.mdx index 8475888df5..f7d1a2db7e 100644 --- a/docs/en/20-third-party/01-grafana.mdx +++ b/docs/en/20-third-party/01-grafana.mdx @@ -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. ![TDengine Database Grafana plugine import dashboard](./import_dashboard.webp) diff --git a/docs/en/20-third-party/11-kafka.md b/docs/en/20-third-party/11-kafka.md index 64c0f0bd48..b865c00bc3 100644 --- a/docs/en/20-third-party/11-kafka.md +++ b/docs/en/20-third-party/11-kafka.md @@ -21,7 +21,7 @@ TDengine Source Connector is used to read data from TDengine in real-time and se 1. Linux operating system 2. Java 8 and Maven installed 3. Git/curl/vi is installed -4. TDengine is installed and started. +4. TDengine is installed and started. ## Install Kafka diff --git a/docs/zh/08-connector/14-java.mdx b/docs/zh/08-connector/14-java.mdx index 237e3ef8f9..e2a0a85b9a 100644 --- a/docs/zh/08-connector/14-java.mdx +++ b/docs/zh/08-connector/14-java.mdx @@ -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 中添加以下依赖: com.taosdata.jdbc taos-jdbcdriver - 3.2.2 + 3.2.7 ``` @@ -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 diff --git a/docs/zh/08-connector/05-schemaless-api.mdx b/docs/zh/08-connector/_05-schemaless.mdx similarity index 100% rename from docs/zh/08-connector/05-schemaless-api.mdx rename to docs/zh/08-connector/_05-schemaless.mdx diff --git a/docs/zh/10-deployment/03-k8s.md b/docs/zh/10-deployment/03-k8s.md index 16e2be0dfd..31e909f02d 100644 --- a/docs/zh/10-deployment/03-k8s.md +++ b/docs/zh/10-deployment/03-k8s.md @@ -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. diff --git a/docs/zh/12-taos-sql/02-database.md b/docs/zh/12-taos-sql/02-database.md index e9ca5405f4..bd33281bc0 100644 --- a/docs/zh/12-taos-sql/02-database.md +++ b/docs/zh/12-taos-sql/02-database.md @@ -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 会取最大的保存时间)。 diff --git a/docs/zh/17-operation/04-import.md b/docs/zh/17-operation/04-import.md index 17945be595..e2c35b36c6 100644 --- a/docs/zh/17-operation/04-import.md +++ b/docs/zh/17-operation/04-import.md @@ -59,4 +59,4 @@ Query OK, 9 row(s) affected (0.004763s) ## taosdump 工具导入 -TDengine 提供了方便的数据库导入导出工具 taosdump。用户可以将 taosdump 从一个系统导出的数据,导入到其他系统中。具体使用方法,请参见:[TDengine 数据备份工具: taosdump](/reference/taosdump)。 +TDengine 提供了方便的数据库导入导出工具 taosdump。用户可以将 taosdump 从一个系统导出的数据,导入到其他系统中。具体使用方法,请参考 taosdump 的相关文档。 diff --git a/docs/zh/17-operation/05-export.md b/docs/zh/17-operation/05-export.md index 44247e28bd..3d4425a792 100644 --- a/docs/zh/17-operation/05-export.md +++ b/docs/zh/17-operation/05-export.md @@ -17,5 +17,4 @@ select * from >> data.csv; ## 用 taosdump 导出数据 -利用 taosdump,用户可以根据需要选择导出所有数据库、一个数据库或者数据库中的一张表,所有数据或一时间段的数据,甚至仅仅表的定义。具体使用方法,请参见: -[TDengine 数据备份工具: taosdump](/reference/taosdump)。 +利用 taosdump,用户可以根据需要选择导出所有数据库、一个数据库或者数据库中的一张表,所有数据或一时间段的数据,甚至仅仅表的定义。具体使用方法,请参考 taosdump 的相关文档。 \ No newline at end of file diff --git a/docs/zh/20-third-party/01-grafana.mdx b/docs/zh/20-third-party/01-grafana.mdx index 9a1223ab9c..8e17ce4768 100644 --- a/docs/zh/20-third-party/01-grafana.mdx +++ b/docs/zh/20-third-party/01-grafana.mdx @@ -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。 ![TDengine Database Grafana plugine import dashboard](./import_dashboard.webp) diff --git a/docs/zh/21-tdinternal/07-tsz.md b/docs/zh/21-tdinternal/07-tsz.md new file mode 100644 index 0000000000..db1a340ab8 --- /dev/null +++ b/docs/zh/21-tdinternal/07-tsz.md @@ -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 之前的版本,数据将不能被识别 diff --git a/examples/JDBC/taosdemo/pom.xml b/examples/JDBC/taosdemo/pom.xml index ff64d3e1df..031d83b084 100644 --- a/examples/JDBC/taosdemo/pom.xml +++ b/examples/JDBC/taosdemo/pom.xml @@ -67,7 +67,7 @@ com.taosdata.jdbc taos-jdbcdriver - 3.0.0 + 3.2.7 diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 8688e07932..58517a5db0 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -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(); diff --git a/include/common/ttime.h b/include/common/ttime.h index 306b5105d0..1dfa609064 100644 --- a/include/common/ttime.h +++ b/include/common/ttime.h @@ -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 diff --git a/include/libs/executor/storageapi.h b/include/libs/executor/storageapi.h index f5392f02b1..d5f1da957d 100644 --- a/include/libs/executor/storageapi.h +++ b/include/libs/executor/storageapi.h @@ -119,6 +119,7 @@ typedef struct SRowBuffPos { bool beFlushed; bool beUsed; bool needFree; + bool beUpdated; } SRowBuffPos; // tq @@ -387,11 +388,13 @@ 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); - bool (*updateInfoIsUpdated)(SUpdateInfo* pInfo, uint64_t tableId, TSKEY ts); - bool (*updateInfoIsTableInserted)(SUpdateInfo* pInfo, int64_t tbUid); + TSKEY (*updateInfoFillBlockData)(SUpdateInfo* pInfo, SSDataBlock* pBlock, int32_t primaryTsCol); + bool (*updateInfoIsUpdated)(SUpdateInfo* pInfo, uint64_t tableId, TSKEY ts); + bool (*updateInfoIsTableInserted)(SUpdateInfo* pInfo, int64_t tbUid); void (*updateInfoDestroy)(SUpdateInfo* pInfo); void (*windowSBfDelete)(SUpdateInfo *pInfo, uint64_t count); void (*windowSBfAdd)(SUpdateInfo *pInfo, uint64_t count); diff --git a/include/libs/stream/streamState.h b/include/libs/stream/streamState.h index b7f100733b..d0a2b311ee 100644 --- a/include/libs/stream/streamState.h +++ b/include/libs/stream/streamState.h @@ -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); diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index 1505b42524..3ce2de476e 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -825,6 +825,7 @@ int32_t streamMetaGetNumOfTasks(SStreamMeta* pMeta); SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId); void streamMetaReleaseTask(SStreamMeta* pMeta, SStreamTask* pTask); int32_t streamMetaReopen(SStreamMeta* pMeta); +void streamMetaInitBackend(SStreamMeta* pMeta); int32_t streamMetaCommit(SStreamMeta* pMeta); int32_t streamMetaLoadAllTasks(SStreamMeta* pMeta); int64_t streamMetaGetLatestCheckpointId(SStreamMeta* pMeta); diff --git a/include/libs/stream/tstreamFileState.h b/include/libs/stream/tstreamFileState.h index c1974df7de..2a129c1830 100644 --- a/include/libs/stream/tstreamFileState.h +++ b/include/libs/stream/tstreamFileState.h @@ -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); diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 7665550153..a3ee294338 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -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) diff --git a/include/util/tcompression.h b/include/util/tcompression.h index 3a3d13117e..ab0c22fc9b 100644 --- a/include/util/tcompression.h +++ b/include/util/tcompression.h @@ -30,6 +30,10 @@ extern "C" { #define INT64MASK(_x) ((((uint64_t)1) << _x) - 1) #define INT32MASK(_x) (((uint32_t)1 << _x) - 1) #define INT8MASK(_x) (((uint8_t)1 << _x) - 1) + +#define ZIGZAG_ENCODE(T, v) (((u##T)((v) >> (sizeof(T) * 8 - 1))) ^ (((u##T)(v)) << 1)) // zigzag encode +#define ZIGZAG_DECODE(T, v) (((v) >> 1) ^ -((T)((v)&1))) // zigzag decode + // Compression algorithm #define NO_COMPRESSION 0 #define ONE_STAGE_COMP 1 @@ -129,6 +133,12 @@ int32_t tsCompressBigint(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32 int32_t nBuf); int32_t tsDecompressBigint(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint8_t cmprAlg, void *pBuf, int32_t nBuf); +// for internal usage +int32_t getWordLength(char type); + +int32_t tsDecompressIntImpl_Hw(const char *const input, const int32_t nelements, char *const output, const char type); +int32_t tsDecompressFloatImplAvx512(const char *const input, const int32_t nelements, char *const output); +int32_t tsDecompressFloatImplAvx2(const char *const input, const int32_t nelements, char *const output); /************************************************************************* * STREAM COMPRESSION diff --git a/include/util/tdef.h b/include/util/tdef.h index 1b56b5b623..69d0c1126d 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -34,7 +34,6 @@ extern "C" { // Bytes for each type. extern const int32_t TYPE_BYTES[21]; -// TODO: replace and remove code below #define CHAR_BYTES sizeof(char) #define SHORT_BYTES sizeof(int16_t) #define INT_BYTES sizeof(int32_t) diff --git a/include/util/tunit.h b/include/util/tunit.h new file mode 100644 index 0000000000..de37c85929 --- /dev/null +++ b/include/util/tunit.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#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_*/ diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index 0a11ef3a53..02ebb182fa 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -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 - ${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$newHostname/" ${cfg_install_dir}/${configFile2} + 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 - ${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${cfg_install_dir}/${configFile2} + + 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 @@ -460,8 +479,12 @@ function set_ipAsFqdn() { if [[ $retval != 0 ]]; then read -p "Please choose an IP from local IP list:" localFqdn else - # Write the local FQDN to configuration file - ${csudo}sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${cfg_install_dir}/${configFile2} + # 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 + set_hostname } 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_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 - ${csudo}sed -i -r "s/#*\s*(firstEp\s*).*/\1$firstEp/" ${cfg_install_dir}/${configFile2} + 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 @@ -606,7 +636,10 @@ 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 -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 || : @@ -701,30 +742,7 @@ function clean_service_on_systemd() { ${csudo}systemctl stop tarbitratord &>/dev/null || echo &>/dev/null 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 + ${csudo}rm -f ${tarbitratord_service_config} } 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 @@ -900,54 +932,71 @@ function updateProduct() { if [ -z $1 ]; then install_bin install_service - install_adapter_service - install_config + install_adapter_service 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 + install_bin echo echo -e "\033[44;32;1m${productName2} client is updated successfully!${NC}" fi - rm -rf $(tar -tf ${tarName} | grep -Ev "^\./$|^\/") + cd $script_dir + rm -rf $(tar -tf ${tarName} | grep -Ev "^\./$|^\/") } function installProduct() { @@ -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}" - - 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: ${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}" - 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 + 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 - 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}" + # 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 + 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 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 + + diff --git a/packaging/tools/install_client.sh b/packaging/tools/install_client.sh index c8baab8269..6643363339 100755 --- a/packaging/tools/install_client.sh +++ b/packaging/tools/install_client.sh @@ -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 diff --git a/packaging/tools/makeclient.sh b/packaging/tools/makeclient.sh index 243efd693e..f46a9adeff 100755 --- a/packaging/tools/makeclient.sh +++ b/packaging/tools/makeclient.sh @@ -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" diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh index 42465b8783..4b0faaa958 100755 --- a/packaging/tools/makepkg.sh +++ b/packaging/tools/makepkg.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 \ @@ -284,8 +280,13 @@ if [ "$pagMode" == "lite" ]; then fi chmod a+x ${install_dir}/install.sh -if [[ $dbName == "taos" ]]; then - # Copy example code +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" cp -r ${examples_dir}/c ${install_dir}/examples @@ -330,8 +331,8 @@ 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 -if [ "$verMode" == "cluster" ]; then +# Copy connector && taosx +if [ "$verMode" == "cluster" ]; then connector_dir="${code_dir}/connector" mkdir -p ${install_dir}/connector if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then @@ -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 diff --git a/packaging/tools/remove.sh b/packaging/tools/remove.sh index 97bffb0535..1ec83b7b0d 100755 --- a/packaging/tools/remove.sh +++ b/packaging/tools/remove.sh @@ -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 diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index b36ef20b53..da24bc0a3b 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -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); } } diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index 03cd19fa40..1f9d3c6d8c 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -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; } diff --git a/source/common/src/cos.c b/source/common/src/cos.c index ea41afd8fb..f36ab42ada 100644 --- a/source/common/src/cos.c +++ b/source/common/src/cos.c @@ -497,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); @@ -519,9 +513,14 @@ int32_t s3PutObjectFromFile2(const char *file, const char *object) { manager.gb = 0; // div round up - int seq; - uint64_t chunk_size = MULTIPART_CHUNK_SIZE >> 8; - int totalSeq = ((contentLength + chunk_size - 1) / chunk_size); + int seq; + 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)); @@ -622,6 +621,12 @@ int32_t s3PutObjectFromFile2(const char *file, const char *object) { for (i = 0; i < manager.next_etags_pos; i++) { taosMemoryFree(manager.etags[i]); } + if (data.infileFD) { + taosCloseFile(&data.infileFD); + } else if (data.gb) { + growbuffer_destroy(data.gb); + } + growbuffer_destroy(manager.gb); taosMemoryFree(manager.etags); } @@ -719,6 +724,8 @@ static SArray *getListByPrefix(const char *prefix) { } else { s3PrintError(__func__, data.status, data.err_msg); } + + taosArrayDestroyEx(data.objectArray, s3FreeObjectKey); return NULL; } diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 47988b0de9..40d1f92d5d 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -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" @@ -94,8 +95,8 @@ int32_t tsMonitorMaxLogs = 100; bool tsMonitorComp = false; // audit -bool tsEnableAudit = true; -bool tsEnableAuditCreateTable = true; +bool tsEnableAudit = true; +bool tsEnableAuditCreateTable = true; // telem #ifdef TD_ENTERPRISE @@ -507,8 +508,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; @@ -722,7 +723,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; @@ -753,6 +754,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; @@ -1196,302 +1201,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(); @@ -1629,49 +1338,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; + } + + break; } - if (strcasecmp(option, "resetlog") == 0) { + 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}, - {"sndDebugFlag", &sndDebugFlag}, + { // '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}, {"sndDebugFlag", &sndDebugFlag}, + }; + static OptionNameAndVar options[] = { {"audit", &tsEnableAudit}, {"asynclog", &tsAsyncLog}, {"disableStream", &tsDisableStream}, @@ -1704,54 +1462,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; - - SConfig *pCfg = taosGetCfg(); - SConfigItem *pItem = NULL; - - pItem = cfgGetItem(pCfg, optName); - if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) { - uError("failed to config:%s, not support", optName); - 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); - } - } 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: - break; - } - - return; + 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); + return terrno == TSDB_CODE_SUCCESS ? 0 : -1; +} + +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; + } + 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; + } + default: + terrno = TSDB_CODE_CFG_NOT_FOUND; + break; + } + + 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); + } + } + +_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) { diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index a701c88a24..227de7f5fc 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -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 diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c index 991f17f326..ac94390619 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c @@ -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; } diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index f4108b52c6..e224aceec2 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -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; diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 1b21d4a017..82d0074fbd 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -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; } diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index 1c9c3887a2..66e3982cba 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -678,7 +678,7 @@ _OVER: return -1; } -static int32_t mndPersistTaskDropReq(STrans *pTrans, SStreamTask *pTask) { +static int32_t mndPersistTaskDropReq(SMnode* pMnode, STrans *pTrans, SStreamTask *pTask) { SVDropStreamTaskReq *pReq = taosMemoryCalloc(1, sizeof(SVDropStreamTaskReq)); if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -690,7 +690,12 @@ static int32_t mndPersistTaskDropReq(STrans *pTrans, SStreamTask *pTask) { pReq->streamId = pTask->id.streamId; STransAction action = {0}; - initTransAction(&action, pReq, sizeof(SVDropStreamTaskReq), TDMT_STREAM_TASK_DROP, &pTask->info.epSet, 0); + SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId); + SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj); + mndReleaseVgroup(pMnode, pVgObj); + + // The epset of nodeId of this task may have been expired now, let's use the newest epset from mnode. + initTransAction(&action, pReq, sizeof(SVDropStreamTaskReq), TDMT_STREAM_TASK_DROP, &epset, 0); if (mndTransAppendRedoAction(pTrans, &action) != 0) { taosMemoryFree(pReq); return -1; @@ -706,7 +711,7 @@ int32_t mndDropStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream) int32_t sz = taosArrayGetSize(pTasks); for (int32_t j = 0; j < sz; j++) { SStreamTask *pTask = taosArrayGetP(pTasks, j); - if (mndPersistTaskDropReq(pTrans, pTask) < 0) { + if (mndPersistTaskDropReq(pMnode, pTrans, pTask) < 0) { return -1; } } @@ -1085,9 +1090,10 @@ static int32_t mndAddStreamCheckpointToTrans(STrans *pTrans, SStreamObj *pStream STransAction action = {0}; SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj); + mndReleaseVgroup(pMnode, pVgObj); + initTransAction(&action, buf, tlen, TDMT_VND_STREAM_CHECK_POINT_SOURCE, &epset, TSDB_CODE_SYN_PROPOSE_NOT_READY); - mndReleaseVgroup(pMnode, pVgObj); if (mndTransAppendRedoAction(pTrans, &action) != 0) { taosMemoryFree(buf); @@ -1283,12 +1289,13 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) { if (pStream == NULL) { if (dropReq.igNotExists) { - mInfo("stream:%s, not exist, ignore not exist is set", dropReq.name); + mInfo("stream:%s not exist, ignore not exist is set", dropReq.name); sdbRelease(pMnode->pSdb, pStream); tFreeSMDropStreamReq(&dropReq); return 0; } else { terrno = TSDB_CODE_MND_STREAM_NOT_EXIST; + mError("stream:%s not exist failed to drop", dropReq.name); tFreeSMDropStreamReq(&dropReq); return -1; } @@ -1660,7 +1667,7 @@ static void mndCancelGetNextStreamTask(SMnode *pMnode, void *pIter) { sdbCancelFetch(pSdb, pIter); } -static int32_t mndPauseStreamTask(STrans *pTrans, SStreamTask *pTask) { +static int32_t mndPauseStreamTask(SMnode* pMnode, STrans *pTrans, SStreamTask *pTask) { SVPauseStreamTaskReq *pReq = taosMemoryCalloc(1, sizeof(SVPauseStreamTaskReq)); if (pReq == NULL) { mError("failed to malloc in pause stream, size:%" PRIzu ", code:%s", sizeof(SVPauseStreamTaskReq), @@ -1673,8 +1680,12 @@ static int32_t mndPauseStreamTask(STrans *pTrans, SStreamTask *pTask) { pReq->taskId = pTask->id.taskId; pReq->streamId = pTask->id.streamId; + SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId); + SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj); + mndReleaseVgroup(pMnode, pVgObj); + STransAction action = {0}; - initTransAction(&action, pReq, sizeof(SVPauseStreamTaskReq), TDMT_STREAM_TASK_PAUSE, &pTask->info.epSet, 0); + initTransAction(&action, pReq, sizeof(SVPauseStreamTaskReq), TDMT_STREAM_TASK_PAUSE, &epset, 0); if (mndTransAppendRedoAction(pTrans, &action) != 0) { taosMemoryFree(pReq); return -1; @@ -1682,7 +1693,7 @@ static int32_t mndPauseStreamTask(STrans *pTrans, SStreamTask *pTask) { return 0; } -int32_t mndPauseAllStreamTasks(STrans *pTrans, SStreamObj *pStream) { +int32_t mndPauseAllStreamTasks(SMnode* pMnode, STrans *pTrans, SStreamObj *pStream) { SArray *tasks = pStream->tasks; int32_t size = taosArrayGetSize(tasks); @@ -1691,7 +1702,7 @@ int32_t mndPauseAllStreamTasks(STrans *pTrans, SStreamObj *pStream) { int32_t sz = taosArrayGetSize(pTasks); for (int32_t j = 0; j < sz; j++) { SStreamTask *pTask = taosArrayGetP(pTasks, j); - if (mndPauseStreamTask(pTrans, pTask) < 0) { + if (mndPauseStreamTask(pMnode, pTrans, pTask) < 0) { return -1; } @@ -1768,7 +1779,7 @@ static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq) { } // pause all tasks - if (mndPauseAllStreamTasks(pTrans, pStream) < 0) { + if (mndPauseAllStreamTasks(pMnode, pTrans, pStream) < 0) { mError("stream:%s, failed to pause task since %s", pauseReq.name, terrstr()); sdbRelease(pMnode->pSdb, pStream); mndTransDrop(pTrans); @@ -1795,7 +1806,7 @@ static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq) { return TSDB_CODE_ACTION_IN_PROGRESS; } -static int32_t mndResumeStreamTask(STrans *pTrans, SStreamTask *pTask, int8_t igUntreated) { +static int32_t mndResumeStreamTask(STrans *pTrans, SMnode* pMnode, SStreamTask *pTask, int8_t igUntreated) { SVResumeStreamTaskReq *pReq = taosMemoryCalloc(1, sizeof(SVResumeStreamTaskReq)); if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -1806,8 +1817,12 @@ static int32_t mndResumeStreamTask(STrans *pTrans, SStreamTask *pTask, int8_t ig pReq->streamId = pTask->id.streamId; pReq->igUntreated = igUntreated; + SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId); + SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj); + mndReleaseVgroup(pMnode, pVgObj); + STransAction action = {0}; - initTransAction(&action, pReq, sizeof(SVResumeStreamTaskReq), TDMT_STREAM_TASK_RESUME, &pTask->info.epSet, 0); + initTransAction(&action, pReq, sizeof(SVResumeStreamTaskReq), TDMT_STREAM_TASK_RESUME, &epset, 0); if (mndTransAppendRedoAction(pTrans, &action) != 0) { taosMemoryFree(pReq); return -1; @@ -1815,14 +1830,14 @@ static int32_t mndResumeStreamTask(STrans *pTrans, SStreamTask *pTask, int8_t ig return 0; } -int32_t mndResumeAllStreamTasks(STrans *pTrans, SStreamObj *pStream, int8_t igUntreated) { +int32_t mndResumeAllStreamTasks(STrans *pTrans, SMnode* pMnode, SStreamObj *pStream, int8_t igUntreated) { int32_t size = taosArrayGetSize(pStream->tasks); for (int32_t i = 0; i < size; i++) { SArray *pTasks = taosArrayGetP(pStream->tasks, i); int32_t sz = taosArrayGetSize(pTasks); for (int32_t j = 0; j < sz; j++) { SStreamTask *pTask = taosArrayGetP(pTasks, j); - if (mndResumeStreamTask(pTrans, pTask, igUntreated) < 0) { + if (mndResumeStreamTask(pTrans, pMnode, pTask, igUntreated) < 0) { return -1; } @@ -1831,7 +1846,6 @@ int32_t mndResumeAllStreamTasks(STrans *pTrans, SStreamObj *pStream, int8_t igUn } } } - // pStream->pHTasksList is null return 0; } @@ -1884,7 +1898,7 @@ static int32_t mndProcessResumeStreamReq(SRpcMsg *pReq) { } // resume all tasks - if (mndResumeAllStreamTasks(pTrans, pStream, pauseReq.igUntreated) < 0) { + if (mndResumeAllStreamTasks(pTrans, pMnode, pStream, pauseReq.igUntreated) < 0) { mError("stream:%s, failed to drop task since %s", pauseReq.name, terrstr()); sdbRelease(pMnode->pSdb, pStream); mndTransDrop(pTrans); @@ -2557,8 +2571,12 @@ int32_t createStreamResetStatusTrans(SMnode *pMnode, SStreamObj *pStream) { pReq->taskId = pTask->id.taskId; pReq->streamId = pTask->id.streamId; + SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId); + SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj); + mndReleaseVgroup(pMnode, pVgObj); + STransAction action = {0}; - initTransAction(&action, pReq, sizeof(SVResetStreamTaskReq), TDMT_VND_STREAM_TASK_RESET, &pTask->info.epSet, 0); + initTransAction(&action, pReq, sizeof(SVResetStreamTaskReq), TDMT_VND_STREAM_TASK_RESET, &epset, 0); if (mndTransAppendRedoAction(pTrans, &action) != 0) { taosMemoryFree(pReq); taosWUnLockLatch(&pStream->lock); diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index af4ccd4ad0..01ffa92513 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -2176,7 +2176,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; } diff --git a/source/dnode/snode/src/snodeInitApi.c b/source/dnode/snode/src/snodeInitApi.c index 389137f630..570feffc14 100644 --- a/source/dnode/snode/src/snodeInitApi.c +++ b/source/dnode/snode/src/snodeInitApi.c @@ -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; diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h index ec69ae5ca7..ca9d22a987 100644 --- a/source/dnode/vnode/src/inc/tsdb.h +++ b/source/dnode/vnode/src/inc/tsdb.h @@ -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)) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 521686d023..8ee0edcb31 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1100,10 +1100,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; @@ -1150,7 +1146,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; @@ -1969,6 +1967,8 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { return -1; } + streamMetaInitBackend(pMeta); + if (streamMetaLoadAllTasks(pTq->pStreamMeta) < 0) { tqError("vgId:%d failed to load stream tasks", vgId); streamMetaWUnLock(pMeta); diff --git a/source/dnode/vnode/src/tq/tqStreamStateSnap.c b/source/dnode/vnode/src/tq/tqStreamStateSnap.c index 41392ba27b..7a8147f83b 100644 --- a/source/dnode/vnode/src/tq/tqStreamStateSnap.c +++ b/source/dnode/vnode/src/tq/tqStreamStateSnap.c @@ -169,10 +169,15 @@ int32_t streamStateSnapWriterClose(SStreamStateWriter* pWriter, int8_t rollback) } int32_t streamStateRebuildFromSnap(SStreamStateWriter* pWriter, int64_t chkpId) { tqDebug("vgId:%d, vnode %s start to rebuild stream-state", TD_VID(pWriter->pTq->pVnode), STREAM_STATE_TRANSFER); + + streamMetaWLock(pWriter->pTq->pStreamMeta); int32_t code = streamMetaReopen(pWriter->pTq->pStreamMeta); if (code == 0) { + streamMetaInitBackend(pWriter->pTq->pStreamMeta); code = streamStateLoadTasks(pWriter); } + + streamMetaWUnLock(pWriter->pTq->pStreamMeta); tqDebug("vgId:%d, vnode %s succ to rebuild stream-state", TD_VID(pWriter->pTq->pVnode), STREAM_STATE_TRANSFER); taosMemoryFree(pWriter); return code; diff --git a/source/dnode/vnode/src/tq/tqStreamTask.c b/source/dnode/vnode/src/tq/tqStreamTask.c index 9f00f9cc10..e069d6c4b7 100644 --- a/source/dnode/vnode/src/tq/tqStreamTask.c +++ b/source/dnode/vnode/src/tq/tqStreamTask.c @@ -145,7 +145,6 @@ int32_t tqRestartStreamTasks(STQ* pTq) { } streamMetaWLock(pMeta); - code = streamMetaReopen(pMeta); if (code != TSDB_CODE_SUCCESS) { tqError("vgId:%d failed to reopen stream meta", vgId); @@ -154,9 +153,10 @@ int32_t tqRestartStreamTasks(STQ* pTq) { return code; } + 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) { @@ -169,12 +169,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; } diff --git a/source/dnode/vnode/src/tq/tqStreamTaskSnap.c b/source/dnode/vnode/src/tq/tqStreamTaskSnap.c index e122cf19d3..f22ecc3daf 100644 --- a/source/dnode/vnode/src/tq/tqStreamTaskSnap.c +++ b/source/dnode/vnode/src/tq/tqStreamTaskSnap.c @@ -212,9 +212,7 @@ int32_t streamTaskSnapWriterClose(SStreamTaskWriter* pWriter, int8_t rollback) { taosMemoryFree(pWriter); goto _err; } - taosWUnLockLatch(&pTq->pStreamMeta->lock); - taosMemoryFree(pWriter); return code; diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit2.c b/source/dnode/vnode/src/tsdb/tsdbCommit2.c index 22fb3b84ec..48b622e324 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit2.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit2.c @@ -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) { @@ -670,4 +669,4 @@ _exit: tsdbInfo("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); } return code; -} \ No newline at end of file +} diff --git a/source/dnode/vnode/src/tsdb/tsdbFS2.c b/source/dnode/vnode/src/tsdb/tsdbFS2.c index 02ef75ae86..a3b3ffc1c8 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFS2.c +++ b/source/dnode/vnode/src/tsdb/tsdbFS2.c @@ -882,8 +882,38 @@ int32_t tsdbFSEditCommit(STFileSystem *fs) { int32_t numFile = TARRAY2_SIZE(lvl->fobjArr); if (numFile >= sttTrigger) { // launch merge - code = tsdbSchedMerge(fs->tsdb, fset->fid); - TSDB_CHECK_CODE(code, lino, _exit); + bool skipMerge = false; + { + int32_t now = taosGetTimestampSec(); + + 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 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) { diff --git a/source/dnode/vnode/src/tsdb/tsdbFile2.c b/source/dnode/vnode/src/tsdb/tsdbFile2.c index cc05b8ee18..8cd9304188 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFile2.c +++ b/source/dnode/vnode/src/tsdb/tsdbFile2.c @@ -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); } diff --git a/source/dnode/vnode/src/tsdb/tsdbRead2.c b/source/dnode/vnode/src/tsdb/tsdbRead2.c index 4682c47bd1..6169014d9f 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead2.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead2.c @@ -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) { diff --git a/source/dnode/vnode/src/tsdb/tsdbReadUtil.c b/source/dnode/vnode/src/tsdb/tsdbReadUtil.c index af7cae33fc..305399e0af 100644 --- a/source/dnode/vnode/src/tsdb/tsdbReadUtil.c +++ b/source/dnode/vnode/src/tsdb/tsdbReadUtil.c @@ -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; diff --git a/source/dnode/vnode/src/tsdb/tsdbReadUtil.h b/source/dnode/vnode/src/tsdb/tsdbReadUtil.h index 47585ea6e3..60e6e6960a 100644 --- a/source/dnode/vnode/src/tsdb/tsdbReadUtil.h +++ b/source/dnode/vnode/src/tsdb/tsdbReadUtil.h @@ -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); diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index 194c2784f4..f6888ba9cb 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -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; diff --git a/source/dnode/vnode/src/vnd/vnodeInitApi.c b/source/dnode/vnode/src/vnd/vnodeInitApi.c index a6dae429c3..a6673917bf 100644 --- a/source/dnode/vnode/src/vnd/vnodeInitApi.c +++ b/source/dnode/vnode/src/vnd/vnodeInitApi.c @@ -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; diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index 899efc8e70..33b4114009 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -21,6 +21,8 @@ #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); @@ -1002,10 +1004,12 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, taosMemoryFreeClear(*key); } - size_t len = 0; - char *keyJoined = taosStringBuilderGetResult(&sb, &len); + size_t len = 0; + char* keyJoined = taosStringBuilderGetResult(&sb, &len); - auditRecord(pOriginRpc, 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); } @@ -1015,7 +1019,7 @@ _exit: pCreateReq = req.pReqs + iReq; taosMemoryFree(pCreateReq->sql); taosMemoryFree(pCreateReq->comment); - taosArrayDestroy(pCreateReq->ctb.tagName); + taosArrayDestroy(pCreateReq->ctb.tagName); } taosArrayDestroyEx(rsp.pArray, tFreeSVCreateTbRsp); taosArrayDestroy(tbUids); @@ -1227,11 +1231,13 @@ static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, in size_t len = 0; char *keyJoined = taosStringBuilderGetResult(&sb, &len); - auditRecord(pOriginRpc, 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); } - + _exit: taosArrayDestroy(tbUids); tdUidStoreFree(pStore); diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index 12063d4883..6bae0e1022 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -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; } diff --git a/source/libs/executor/inc/executorInt.h b/source/libs/executor/inc/executorInt.h index 331ce44366..cf717472b1 100644 --- a/source/libs/executor/inc/executorInt.h +++ b/source/libs/executor/inc/executorInt.h @@ -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); -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); diff --git a/source/libs/executor/inc/operator.h b/source/libs/executor/inc/operator.h index 13da9f7238..0858a7e595 100644 --- a/source/libs/executor/inc/operator.h +++ b/source/libs/executor/inc/operator.h @@ -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); diff --git a/source/libs/executor/src/operator.c b/source/libs/executor/src/operator.c index 6f9aac7595..69a8acb3d7 100644 --- a/source/libs/executor/src/operator.c +++ b/source/libs/executor/src/operator.c @@ -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) { diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index c47e14ad0d..1c3db48972 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -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; } diff --git a/source/libs/executor/src/streameventwindowoperator.c b/source/libs/executor/src/streameventwindowoperator.c new file mode 100644 index 0000000000..9b987ff1a4 --- /dev/null +++ b/source/libs/executor/src/streameventwindowoperator.c @@ -0,0 +1,751 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ +#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; +} diff --git a/source/libs/executor/src/streamtimewindowoperator.c b/source/libs/executor/src/streamtimewindowoperator.c index 0d82fcc9c3..86d83e05ad 100644 --- a/source/libs/executor/src/streamtimewindowoperator.c +++ b/source/libs/executor/src/streamtimewindowoperator.c @@ -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; @@ -1880,7 +1887,7 @@ static int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* } void getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* pStUpdated, SResultWindowInfo* pCurWin, - SResultWindowInfo* pNextWin) { + SResultWindowInfo* pNextWin) { SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pCurWin->sessionWin); pNextWin->isOutput = true; setSessionWinOutputInfo(pStUpdated, pNextWin); @@ -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) { diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index a55bd5663f..1a65a29259 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -7363,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) { diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 4eda11a6a4..e71e18d37d 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2784,11 +2784,44 @@ static int32_t splitCacheLastFuncOptCreateAggLogicNode(SAggLogicNode** pNewAgg, pNew->hasGroup = pAgg->hasGroup; pNew->node.pChildren = nodesCloneList(pAgg->node.pChildren); - SNode* pNode = NULL; - FOREACH(pNode, pNew->node.pChildren) { - if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) { - OPTIMIZE_FLAG_CLEAR_MASK(((SScanLogicNode*)pNode)->node.optimizedFlag, OPTIMIZE_FLAG_SCAN_PATH); + 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; diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index e7c6297f44..6144ebd340 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -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; diff --git a/source/libs/scheduler/src/schStatus.c b/source/libs/scheduler/src/schStatus.c index 9d0ad30e2a..d37393137f 100644 --- a/source/libs/scheduler/src/schStatus.c +++ b/source/libs/scheduler/src/schStatus.c @@ -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; diff --git a/source/libs/stream/inc/streamBackendRocksdb.h b/source/libs/stream/inc/streamBackendRocksdb.h index 441c71662e..3eadea3cdd 100644 --- a/source/libs/stream/inc/streamBackendRocksdb.h +++ b/source/libs/stream/inc/streamBackendRocksdb.h @@ -122,7 +122,7 @@ int32_t streamDefaultGet_rocksdb(SStreamState* pState, const void* key, void** p int32_t streamDefaultDel_rocksdb(SStreamState* pState, const void* key); int32_t streamDefaultIterGet_rocksdb(SStreamState* pState, const void* start, const void* end, SArray* result); void* streamDefaultIterCreate_rocksdb(SStreamState* pState); -int32_t streamDefaultIterValid_rocksdb(void* iter); +bool streamDefaultIterValid_rocksdb(void* iter); void streamDefaultIterSeek_rocksdb(void* iter, const char* key); void streamDefaultIterNext_rocksdb(void* iter); char* streamDefaultIterKey_rocksdb(void* iter, int32_t* len); diff --git a/source/libs/stream/src/streamBackendRocksdb.c b/source/libs/stream/src/streamBackendRocksdb.c index 63dc497c6f..c23483fffb 100644 --- a/source/libs/stream/src/streamBackendRocksdb.c +++ b/source/libs/stream/src/streamBackendRocksdb.c @@ -2859,9 +2859,12 @@ void* streamDefaultIterCreate_rocksdb(SStreamState* pState) { pCur->number = pState->number; return pCur; } -int32_t streamDefaultIterValid_rocksdb(void* iter) { +bool streamDefaultIterValid_rocksdb(void* iter) { + if (iter) { + return false; + } SStreamStateCur* pCur = iter; - return rocksdb_iter_valid(pCur->iter) ? 1 : 0; + return (rocksdb_iter_valid(pCur->iter) && !iterValueIsStale(pCur->iter)) ? true : false; } void streamDefaultIterSeek_rocksdb(void* iter, const char* key) { SStreamStateCur* pCur = iter; diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 15b4bd634a..edb61be2d5 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -1106,8 +1106,8 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i taosArrayPush(pTask->msgInfo.pRetryList, &pRsp->downstreamNodeId); taosThreadMutexUnlock(&pTask->lock); - stError("s-task:%s inputQ of downstream task:0x%x(vgId:%d) is full, wait for %dms and retry dispatch data", id, - pRsp->downstreamTaskId, pRsp->downstreamNodeId, DISPATCH_RETRY_INTERVAL_MS); + stWarn("s-task:%s inputQ of downstream task:0x%x(vgId:%d) is full, wait for %dms and retry dispatch", id, + pRsp->downstreamTaskId, pRsp->downstreamNodeId, DISPATCH_RETRY_INTERVAL_MS); } else if (pRsp->inputStatus == TASK_INPUT_STATUS__REFUSED) { stError("s-task:%s downstream task:0x%x(vgId:%d) refused the dispatch msg, treat it as success", id, pRsp->downstreamTaskId, pRsp->downstreamNodeId); @@ -1147,8 +1147,8 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i } int32_t ref = atomic_add_fetch_32(&pTask->status.timerActive, 1); - stDebug("s-task:%s failed to dispatch msg to downstream code:%s, add timer to retry in %dms, ref:%d", - pTask->id.idStr, tstrerror(terrno), DISPATCH_RETRY_INTERVAL_MS, ref); + stDebug("s-task:%s failed to dispatch msg to downstream, add into timer to retry in %dms, ref:%d", + pTask->id.idStr, DISPATCH_RETRY_INTERVAL_MS, ref); streamRetryDispatchData(pTask, DISPATCH_RETRY_INTERVAL_MS); } else { // this message has been sent successfully, let's try next one. diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index ac04c6c214..039a1d0737 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -262,18 +262,33 @@ int32_t streamMetaReopen(SStreamMeta* pMeta) { } } - // todo: not wait in a critical region - while ((pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId, pMeta->vgId)) == NULL) { - stInfo("vgId:%d failed to init stream backend, retry in 100ms", pMeta->vgId); - taosMsleep(100); + taosMemoryFree(defaultPath); + taosMemoryFree(newPath); + + return 0; +} + +// todo refactor: the lock shoud be restricted in one function +void streamMetaInitBackend(SStreamMeta* pMeta) { + pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId, pMeta->vgId); + if (pMeta->streamBackend == NULL) { + streamMetaWUnLock(pMeta); + + while (1) { + streamMetaWLock(pMeta); + pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId, pMeta->vgId); + if (pMeta->streamBackend != NULL) { + break; + } + + streamMetaWUnLock(pMeta); + stInfo("vgId:%d failed to init stream backend, retry in 100ms", pMeta->vgId); + taosMsleep(100); + } } pMeta->streamBackendRid = taosAddRef(streamBackendId, pMeta->streamBackend); streamBackendLoadCheckpointInfo(pMeta); - - taosMemoryFree(defaultPath); - taosMemoryFree(newPath); - return 0; } void streamMetaClear(SStreamMeta* pMeta) { diff --git a/source/libs/stream/src/streamSessionState.c b/source/libs/stream/src/streamSessionState.c index cc96778762..45d656c456 100644 --- a/source/libs/stream/src/streamSessionState.c +++ b/source/libs/stream/src/streamSessionState.c @@ -72,7 +72,7 @@ bool inSessionWindow(SSessionKey* pKey, TSKEY ts, int64_t gap) { return false; } -static SRowBuffPos* addNewSessionWindow(SStreamFileState* pFileState, SArray* pWinInfos, SSessionKey* pKey) { +static SRowBuffPos* addNewSessionWindow(SStreamFileState* pFileState, SArray* pWinInfos, const SSessionKey* pKey) { SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState); ASSERT(pNewPos->pRowBuff); memcpy(pNewPos->pKey, pKey, sizeof(SSessionKey)); @@ -80,7 +80,7 @@ static SRowBuffPos* addNewSessionWindow(SStreamFileState* pFileState, SArray* pW return pNewPos; } -static SRowBuffPos* insertNewSessionWindow(SStreamFileState* pFileState, SArray* pWinInfos, SSessionKey* pKey, int32_t index) { +static SRowBuffPos* insertNewSessionWindow(SStreamFileState* pFileState, SArray* pWinInfos, const SSessionKey* pKey, int32_t index) { SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState); ASSERT(pNewPos->pRowBuff); memcpy(pNewPos->pKey, pKey, sizeof(SSessionKey)); @@ -270,6 +270,51 @@ int32_t deleteSessionWinStateBuffByPosFn(SStreamFileState* pFileState, SRowBuffP return TSDB_CODE_SUCCESS; } +int32_t allocSessioncWinBuffByNextPosition(SStreamFileState* pFileState, SStreamStateCur* pCur, const SSessionKey* pWinKey, void** ppVal, int32_t* pVLen) { + SRowBuffPos* pNewPos = NULL; + SSHashObj* pSessionBuff = getRowStateBuff(pFileState); + void** ppBuff = tSimpleHashGet(pSessionBuff, &pWinKey->groupId, sizeof(uint64_t)); + SArray* pWinStates = NULL; + if (!ppBuff) { + pWinStates = taosArrayInit(16, POINTER_BYTES); + tSimpleHashPut(pSessionBuff, &pWinKey->groupId, sizeof(uint64_t), &pWinStates, POINTER_BYTES); + } else { + pWinStates = (SArray*)(*ppBuff); + } + if (!pCur) { + pNewPos = addNewSessionWindow(pFileState, pWinStates, pWinKey); + goto _end; + } + + int32_t size = taosArrayGetSize(pWinStates); + if (pCur->buffIndex >= 0) { + if (pCur->buffIndex >= size) { + pNewPos = insertNewSessionWindow(pFileState, pWinStates, pWinKey, size); + goto _end; + } + pNewPos = insertNewSessionWindow(pFileState, pWinStates, pWinKey, pCur->buffIndex); + goto _end; + } else { + if (size > 0) { + SRowBuffPos* pPos = taosArrayGetP(pWinStates, 0); + if (sessionWinKeyCmpr(pWinKey, pPos->pKey) >=0) { + // pCur is invalid + SSessionKey pTmpKey = *pWinKey; + int32_t code = getSessionWinResultBuff(pFileState, &pTmpKey, 0, (void**)&pNewPos, pVLen); + ASSERT(code == TSDB_CODE_FAILED); + goto _end; + } + } + pNewPos = getNewRowPosForWrite(pFileState); + pNewPos->needFree = true; + } + +_end: + memcpy(pNewPos->pKey, pWinKey, sizeof(SSessionKey)); + (*ppVal) = pNewPos; + return TSDB_CODE_SUCCESS; +} + void sessionWinStateClear(SStreamFileState* pFileState) { int32_t buffSize = getRowStateRowSize(pFileState); void* pIte = NULL; diff --git a/source/libs/stream/src/streamSnapshot.c b/source/libs/stream/src/streamSnapshot.c index 103fd9e087..5893bc14f1 100644 --- a/source/libs/stream/src/streamSnapshot.c +++ b/source/libs/stream/src/streamSnapshot.c @@ -195,7 +195,7 @@ int32_t streamSnapHandleInit(SStreamSnapHandle* pHandle, char* path, int64_t chk } } if (qDebugFlag & DEBUG_TRACE) { - char* buf = taosMemoryCalloc(1, 128 + taosArrayGetSize(pFile->pSst) * 16); + char* buf = taosMemoryCalloc(1, 128 + taosArrayGetSize(pFile->pSst) * 64); sprintf(buf, "[current: %s,", pFile->pCurrent); sprintf(buf + strlen(buf), "MANIFEST: %s,", pFile->pMainfest); sprintf(buf + strlen(buf), "options: %s,", pFile->pOptions); @@ -483,7 +483,7 @@ int32_t streamSnapWrite(SStreamSnapWriter* pWriter, uint8_t* pData, uint32_t nDa int32_t streamSnapWriterClose(SStreamSnapWriter* pWriter, int8_t rollback) { SStreamSnapHandle* handle = &pWriter->handle; if (qDebugFlag & DEBUG_TRACE) { - char* buf = (char*)taosMemoryMalloc(128 + taosArrayGetSize(handle->pFileList) * 16); + char* buf = (char*)taosMemoryMalloc(128 + taosArrayGetSize(handle->pFileList) * 64); int n = sprintf(buf, "["); for (int i = 0; i < taosArrayGetSize(handle->pFileList); i++) { SBackendFileItem* item = taosArrayGet(handle->pFileList, i); diff --git a/source/libs/stream/src/streamStart.c b/source/libs/stream/src/streamStart.c index 0b2bf6b4ba..97eb7b79a2 100644 --- a/source/libs/stream/src/streamStart.c +++ b/source/libs/stream/src/streamStart.c @@ -134,7 +134,7 @@ int32_t streamReExecScanHistoryFuture(SStreamTask* pTask, int32_t idleDuration) pTask->schedHistoryInfo.numOfTicks = numOfTicks; int32_t ref = atomic_add_fetch_32(&pTask->status.timerActive, 1); - stDebug("s-task:%s scan-history start in %.2fs, ref:%d", pTask->id.idStr, numOfTicks*0.1, ref); + stDebug("s-task:%s scan-history resumed in %.2fs, ref:%d", pTask->id.idStr, numOfTicks*0.1, ref); if (pTask->schedHistoryInfo.pTimer == NULL) { pTask->schedHistoryInfo.pTimer = taosTmrStart(doReExecScanhistory, SCANHISTORY_IDLE_TIME_SLICE, pTask, streamEnv.timer); diff --git a/source/libs/stream/src/streamState.c b/source/libs/stream/src/streamState.c index 6ca7bc5e7b..2e51200fe4 100644 --- a/source/libs/stream/src/streamState.c +++ b/source/libs/stream/src/streamState.c @@ -735,6 +735,14 @@ int32_t streamStateSessionPut(SStreamState* pState, const SSessionKey* key, void #endif } +int32_t streamStateSessionAllocWinBuffByNextPosition(SStreamState* pState, SStreamStateCur* pCur, const SSessionKey* pKey, void** pVal, int32_t* pVLen) { +#ifdef USE_ROCKSDB + return allocSessioncWinBuffByNextPosition(pState->pFileState, pCur, pKey, pVal, pVLen); +#else + return TSDB_CODE_FAILED; +#endif +} + int32_t streamStateSessionGet(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen) { #ifdef USE_ROCKSDB return getSessionFlushedBuff(pState->pFileState, key, pVal, pVLen); diff --git a/source/libs/stream/src/tstreamFileState.c b/source/libs/stream/src/tstreamFileState.c index fc47498a3c..d31e4cbfcd 100644 --- a/source/libs/stream/src/tstreamFileState.c +++ b/source/libs/stream/src/tstreamFileState.c @@ -321,6 +321,10 @@ void popUsedBuffs(SStreamFileState* pFileState, SStreamSnapshot* pFlushList, uin while ((pNode = tdListNext(&iter)) != NULL && i < max) { SRowBuffPos* pPos = *(SRowBuffPos**)pNode->data; if (pPos->beUsed == used) { + if (used && !pPos->pRowBuff) { + ASSERT(pPos->needFree == true); + continue; + } tdListAppend(pFlushList, &pPos); pFileState->flushMark = TMAX(pFileState->flushMark, pFileState->getTs(pPos->pKey)); pFileState->stateBuffRemoveByPosFn(pFileState, pPos); @@ -428,6 +432,7 @@ SRowBuffPos* getNewRowPosForWrite(SStreamFileState* pFileState) { newPos->beUsed = true; newPos->beFlushed = false; newPos->needFree = false; + newPos->beUpdated = true; return newPos; } diff --git a/source/libs/transport/src/thttp.c b/source/libs/transport/src/thttp.c index c483d82027..65b0058cfe 100644 --- a/source/libs/transport/src/thttp.c +++ b/source/libs/transport/src/thttp.c @@ -293,6 +293,15 @@ int32_t httpSendQuit() { static int32_t taosSendHttpReportImpl(const char* server, const char* uri, uint16_t port, char* pCont, int32_t contLen, EHttpCompFlag flag) { + if (server == NULL || uri == NULL) { + tError("http-report failed to report to invalid addr"); + return -1; + } + + if (pCont == NULL || contLen == 0) { + tError("http-report failed to report empty packet"); + return -1; + } SHttpModule* load = taosAcquireRef(httpRefMgt, httpRef); if (load == NULL) { tError("http-report already released"); diff --git a/source/util/src/tcompression.c b/source/util/src/tcompression.c index dc89a24180..06b82f3ba1 100644 --- a/source/util/src/tcompression.c +++ b/source/util/src/tcompression.c @@ -52,6 +52,7 @@ #include "lz4.h" #include "tRealloc.h" #include "tlog.h" +#include "ttypes.h" #ifdef TD_TSZ #include "td_sz.h" @@ -62,8 +63,6 @@ static const int32_t TEST_NUMBER = 1; #define SIMPLE8B_MAX_INT64 ((uint64_t)1152921504606846974LL) #define safeInt64Add(a, b) (((a >= 0) && (b <= INT64_MAX - a)) || ((a < 0) && (b >= INT64_MIN - a))) -#define ZIGZAG_ENCODE(T, v) (((u##T)((v) >> (sizeof(T) * 8 - 1))) ^ (((u##T)(v)) << 1)) // zigzag encode -#define ZIGZAG_DECODE(T, v) (((v) >> 1) ^ -((T)((v)&1))) // zigzag decode #ifdef TD_TSZ bool lossyFloat = false; @@ -99,24 +98,7 @@ int32_t tsCompressINTImp(const char *const input, const int32_t nelements, char 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}; // get the byte limit. - int32_t word_length = 0; - switch (type) { - case TSDB_DATA_TYPE_BIGINT: - word_length = LONG_BYTES; - break; - case TSDB_DATA_TYPE_INT: - word_length = INT_BYTES; - break; - case TSDB_DATA_TYPE_SMALLINT: - word_length = SHORT_BYTES; - break; - case TSDB_DATA_TYPE_TINYINT: - word_length = CHAR_BYTES; - break; - default: - uError("Invalid compress integer type:%d", type); - return -1; - } + int32_t word_length = getWordLength(type); int32_t byte_limit = nelements * word_length + 1; int32_t opos = 1; @@ -221,24 +203,9 @@ int32_t tsCompressINTImp(const char *const input, const int32_t nelements, char } int32_t tsDecompressINTImp(const char *const input, const int32_t nelements, char *const output, const char type) { - - int32_t word_length = 0; - switch (type) { - case TSDB_DATA_TYPE_BIGINT: - word_length = LONG_BYTES; - break; - case TSDB_DATA_TYPE_INT: - word_length = INT_BYTES; - break; - case TSDB_DATA_TYPE_SMALLINT: - word_length = SHORT_BYTES; - break; - case TSDB_DATA_TYPE_TINYINT: - word_length = CHAR_BYTES; - break; - default: - uError("Invalid decompress integer type:%d", type); - return -1; + int32_t word_length = getWordLength(type); + if (word_length == -1) { + return word_length; } // If not compressed. @@ -247,8 +214,11 @@ int32_t tsDecompressINTImp(const char *const input, const int32_t nelements, cha return nelements * word_length; } - // Selector value: 0 1 2 3 4 5 6 7 8 9 10 11 - // 12 13 14 15 +#if __AVX2__ + tsDecompressIntImpl_Hw(input, nelements, output, type); + return nelements * word_length; +#else + // Selector value: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 char bit_per_integer[] = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 15, 20, 30, 60}; int32_t selector_to_elems[] = {240, 120, 60, 30, 20, 15, 12, 10, 8, 7, 6, 5, 4, 3, 2, 1}; @@ -257,185 +227,6 @@ int32_t tsDecompressINTImp(const char *const input, const int32_t nelements, cha int32_t _pos = 0; int64_t prev_value = 0; -#if __AVX2__ - while (1) { - if (_pos == nelements) break; - - uint64_t w = 0; - memcpy(&w, ip, LONG_BYTES); - - char selector = (char)(w & INT64MASK(4)); // selector = 4 - char bit = bit_per_integer[(int32_t)selector]; // bit = 3 - int32_t elems = selector_to_elems[(int32_t)selector]; - - // Optimize the performance, by remove the constantly switch operation. - int32_t v = 4; - uint64_t zigzag_value = 0; - uint64_t mask = INT64MASK(bit); - - switch (type) { - case TSDB_DATA_TYPE_BIGINT: { - int64_t* p = (int64_t*) output; - - int32_t gRemainder = (nelements - _pos); - int32_t num = (gRemainder > elems)? elems:gRemainder; - - int32_t batch = num >> 2; - int32_t remain = num & 0x03; - if (selector == 0 || selector == 1) { - if (tsAVX2Enable && tsSIMDEnable) { - for (int32_t i = 0; i < batch; ++i) { - __m256i prev = _mm256_set1_epi64x(prev_value); - _mm256_storeu_si256((__m256i *)&p[_pos], prev); - _pos += 4; - } - - for (int32_t i = 0; i < remain; ++i) { - p[_pos++] = prev_value; - } - } else { - for (int32_t i = 0; i < elems && count < nelements; i++, count++) { - p[_pos++] = prev_value; - v += bit; - } - } - } else { - if (tsAVX2Enable && tsSIMDEnable) { - __m256i base = _mm256_set1_epi64x(w); - __m256i maskVal = _mm256_set1_epi64x(mask); - - __m256i shiftBits = _mm256_set_epi64x(bit * 3 + 4, bit * 2 + 4, bit + 4, 4); - __m256i inc = _mm256_set1_epi64x(bit << 2); - - for (int32_t i = 0; i < batch; ++i) { - __m256i after = _mm256_srlv_epi64(base, shiftBits); - __m256i zigzagVal = _mm256_and_si256(after, maskVal); - - // ZIGZAG_DECODE(T, v) (((v) >> 1) ^ -((T)((v)&1))) - __m256i signmask = _mm256_and_si256(_mm256_set1_epi64x(1), zigzagVal); - signmask = _mm256_sub_epi64(_mm256_setzero_si256(), signmask); - // get the four zigzag values here - __m256i delta = _mm256_xor_si256(_mm256_srli_epi64(zigzagVal, 1), signmask); - - // calculate the cumulative sum (prefix sum) for each number - // decode[0] = prev_value + final[0] - // decode[1] = decode[0] + final[1] -----> prev_value + final[0] + final[1] - // decode[2] = decode[1] + final[2] -----> prev_value + final[0] + final[1] + final[2] - // decode[3] = decode[2] + final[3] -----> prev_value + final[0] + final[1] + final[2] + final[3] - - // 1, 2, 3, 4 - //+ 0, 1, 0, 3 - // 1, 3, 3, 7 - // shift and add for the first round - __m128i prev = _mm_set1_epi64x(prev_value); - __m256i x = _mm256_slli_si256(delta, 8); - - delta = _mm256_add_epi64(delta, x); - _mm256_storeu_si256((__m256i *)&p[_pos], delta); - - // 1, 3, 3, 7 - //+ 0, 0, 3, 3 - // 1, 3, 6, 10 - // shift and add operation for the second round - __m128i firstPart = _mm_loadu_si128((__m128i *)&p[_pos]); - __m128i secondItem = _mm_set1_epi64x(p[_pos + 1]); - __m128i secPart = _mm_add_epi64(_mm_loadu_si128((__m128i *)&p[_pos + 2]), secondItem); - firstPart = _mm_add_epi64(firstPart, prev); - secPart = _mm_add_epi64(secPart, prev); - - // save it in the memory - _mm_storeu_si128((__m128i *)&p[_pos], firstPart); - _mm_storeu_si128((__m128i *)&p[_pos + 2], secPart); - - shiftBits = _mm256_add_epi64(shiftBits, inc); - prev_value = p[_pos + 3]; -// uDebug("_pos:%d %"PRId64", %"PRId64", %"PRId64", %"PRId64, _pos, p[_pos], p[_pos+1], p[_pos+2], p[_pos+3]); - _pos += 4; - } - - // handle the remain value - for (int32_t i = 0; i < remain; i++) { - zigzag_value = ((w >> (v + (batch * bit * 4))) & mask); - prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); - - p[_pos++] = prev_value; -// uDebug("_pos:%d %"PRId64, _pos-1, p[_pos-1]); - - v += bit; - } - } else { - for (int32_t i = 0; i < elems && count < nelements; i++, count++) { - zigzag_value = ((w >> v) & mask); - prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); - - p[_pos++] = prev_value; -// uDebug("_pos:%d %"PRId64, _pos-1, p[_pos-1]); - - v += bit; - } - } - } - } break; - case TSDB_DATA_TYPE_INT: { - int32_t* p = (int32_t*) output; - - if (selector == 0 || selector == 1) { - for (int32_t i = 0; i < elems && count < nelements; i++, count++) { - p[_pos++] = (int32_t)prev_value; - } - } else { - for (int32_t i = 0; i < elems && count < nelements; i++, count++) { - zigzag_value = ((w >> v) & mask); - prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); - - p[_pos++] = (int32_t)prev_value; - v += bit; - } - } - } break; - case TSDB_DATA_TYPE_SMALLINT: { - int16_t* p = (int16_t*) output; - - if (selector == 0 || selector == 1) { - for (int32_t i = 0; i < elems && count < nelements; i++, count++) { - p[_pos++] = (int16_t)prev_value; - } - } else { - for (int32_t i = 0; i < elems && count < nelements; i++, count++) { - zigzag_value = ((w >> v) & mask); - prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); - - p[_pos++] = (int16_t)prev_value; - v += bit; - } - } - } break; - - case TSDB_DATA_TYPE_TINYINT: { - int8_t *p = (int8_t *)output; - - if (selector == 0 || selector == 1) { - for (int32_t i = 0; i < elems && count < nelements; i++, count++) { - p[_pos++] = (int8_t)prev_value; - } - } else { - for (int32_t i = 0; i < elems && count < nelements; i++, count++) { - zigzag_value = ((w >> v) & mask); - prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); - - p[_pos++] = (int8_t)prev_value; - v += bit; - } - } - } break; - } - - ip += LONG_BYTES; - } - - return nelements * word_length; -#else - while (1) { if (count == nelements) break; @@ -644,6 +435,8 @@ int32_t tsDecompressStringImp(const char *const input, int32_t compressedSize, c // TODO: Take care here, we assumes little endian encoding. int32_t tsCompressTimestampImp(const char *const input, const int32_t nelements, char *const output) { int32_t _pos = 1; + int32_t longBytes = LONG_BYTES; + ASSERTS(nelements >= 0, "nelements is negative"); if (nelements == 0) return 0; @@ -684,25 +477,25 @@ int32_t tsCompressTimestampImp(const char *const input, const int32_t nelements, } flags = flag1 | (flag2 << 4); // Encode the flag. - if ((_pos + CHAR_BYTES - 1) >= nelements * LONG_BYTES) goto _exit_over; + if ((_pos + CHAR_BYTES - 1) >= nelements * longBytes) goto _exit_over; memcpy(output + _pos, &flags, CHAR_BYTES); _pos += CHAR_BYTES; /* Here, we assume it is little endian encoding method. */ // Encode dd1 if (is_bigendian()) { - if ((_pos + flag1 - 1) >= nelements * LONG_BYTES) goto _exit_over; - memcpy(output + _pos, (char *)(&dd1) + LONG_BYTES - flag1, flag1); + if ((_pos + flag1 - 1) >= nelements * longBytes) goto _exit_over; + memcpy(output + _pos, (char *)(&dd1) + longBytes - flag1, flag1); } else { - if ((_pos + flag1 - 1) >= nelements * LONG_BYTES) goto _exit_over; + if ((_pos + flag1 - 1) >= nelements * longBytes) goto _exit_over; memcpy(output + _pos, (char *)(&dd1), flag1); } _pos += flag1; // Encode dd2; if (is_bigendian()) { - if ((_pos + flag2 - 1) >= nelements * LONG_BYTES) goto _exit_over; - memcpy(output + _pos, (char *)(&dd2) + LONG_BYTES - flag2, flag2); + if ((_pos + flag2 - 1) >= nelements * longBytes) goto _exit_over; + memcpy(output + _pos, (char *)(&dd2) + longBytes - flag2, flag2); } else { - if ((_pos + flag2 - 1) >= nelements * LONG_BYTES) goto _exit_over; + if ((_pos + flag2 - 1) >= nelements * longBytes) goto _exit_over; memcpy(output + _pos, (char *)(&dd2), flag2); } _pos += flag2; @@ -715,15 +508,15 @@ int32_t tsCompressTimestampImp(const char *const input, const int32_t nelements, flag2 = 0; flags = flag1 | (flag2 << 4); // Encode the flag. - if ((_pos + CHAR_BYTES - 1) >= nelements * LONG_BYTES) goto _exit_over; + if ((_pos + CHAR_BYTES - 1) >= nelements * longBytes) goto _exit_over; memcpy(output + _pos, &flags, CHAR_BYTES); _pos += CHAR_BYTES; // Encode dd1; if (is_bigendian()) { - if ((_pos + flag1 - 1) >= nelements * LONG_BYTES) goto _exit_over; - memcpy(output + _pos, (char *)(&dd1) + LONG_BYTES - flag1, flag1); + if ((_pos + flag1 - 1) >= nelements * longBytes) goto _exit_over; + memcpy(output + _pos, (char *)(&dd1) + longBytes - flag1, flag1); } else { - if ((_pos + flag1 - 1) >= nelements * LONG_BYTES) goto _exit_over; + if ((_pos + flag1 - 1) >= nelements * longBytes) goto _exit_over; memcpy(output + _pos, (char *)(&dd1), flag1); } _pos += flag1; @@ -734,17 +527,19 @@ int32_t tsCompressTimestampImp(const char *const input, const int32_t nelements, _exit_over: output[0] = 0; // Means the string is not compressed - memcpy(output + 1, input, nelements * LONG_BYTES); - return nelements * LONG_BYTES + 1; + memcpy(output + 1, input, nelements * longBytes); + return nelements * longBytes + 1; } int32_t tsDecompressTimestampImp(const char *const input, const int32_t nelements, char *const output) { + int64_t longBytes = LONG_BYTES; + ASSERTS(nelements >= 0, "nelements is negative"); if (nelements == 0) return 0; if (input[0] == 0) { - memcpy(output, input + 1, nelements * LONG_BYTES); - return nelements * LONG_BYTES; + memcpy(output, input + 1, nelements * longBytes); + return nelements * longBytes; } else if (input[0] == 1) { // Decompress int64_t *ostream = (int64_t *)output; @@ -763,7 +558,7 @@ int32_t tsDecompressTimestampImp(const char *const input, const int32_t nelement delta_of_delta = 0; } else { if (is_bigendian()) { - memcpy(((char *)(&dd1)) + LONG_BYTES - nbytes, input + ipos, nbytes); + memcpy(((char *)(&dd1)) + longBytes - nbytes, input + ipos, nbytes); } else { memcpy(&dd1, input + ipos, nbytes); } @@ -779,7 +574,7 @@ int32_t tsDecompressTimestampImp(const char *const input, const int32_t nelement prev_value = prev_value + prev_delta; ostream[opos++] = prev_value; } - if (opos == nelements) return nelements * LONG_BYTES; + if (opos == nelements) return nelements * longBytes; // Decode dd2 uint64_t dd2 = 0; @@ -788,7 +583,7 @@ int32_t tsDecompressTimestampImp(const char *const input, const int32_t nelement delta_of_delta = 0; } else { if (is_bigendian()) { - memcpy(((char *)(&dd2)) + LONG_BYTES - nbytes, input + ipos, nbytes); + memcpy(((char *)(&dd2)) + longBytes - nbytes, input + ipos, nbytes); } else { memcpy(&dd2, input + ipos, nbytes); } @@ -799,7 +594,7 @@ int32_t tsDecompressTimestampImp(const char *const input, const int32_t nelement prev_delta = delta_of_delta + prev_delta; prev_value = prev_value + prev_delta; ostream[opos++] = prev_value; - if (opos == nelements) return nelements * LONG_BYTES; + if (opos == nelements) return nelements * longBytes; } } else { @@ -807,11 +602,13 @@ int32_t tsDecompressTimestampImp(const char *const input, const int32_t nelement return -1; } } -/* --------------------------------------------Double Compression - * ---------------------------------------------- */ + +/* --------------------------------------------Double Compression ---------------------------------------------- */ void encodeDoubleValue(uint64_t diff, uint8_t flag, char *const output, int32_t *const pos) { + int32_t longBytes = LONG_BYTES; + uint8_t nbytes = (flag & INT8MASK(3)) + 1; - int32_t nshift = (LONG_BYTES * BITS_PER_BYTE - nbytes * BITS_PER_BYTE) * (flag >> 3); + int32_t nshift = (longBytes * BITS_PER_BYTE - nbytes * BITS_PER_BYTE) * (flag >> 3); diff >>= nshift; while (nbytes) { @@ -906,12 +703,14 @@ int32_t tsCompressDoubleImp(const char *const input, const int32_t nelements, ch } FORCE_INLINE uint64_t decodeDoubleValue(const char *const input, int32_t *const ipos, uint8_t flag) { + int32_t longBytes = LONG_BYTES; + uint64_t diff = 0ul; int32_t nbytes = (flag & 0x7) + 1; for (int32_t i = 0; i < nbytes; i++) { diff |= (((uint64_t)0xff & input[(*ipos)++]) << BITS_PER_BYTE * i); } - int32_t shift_width = (LONG_BYTES * BITS_PER_BYTE - nbytes * BITS_PER_BYTE) * (flag >> 3); + int32_t shift_width = (longBytes * BITS_PER_BYTE - nbytes * BITS_PER_BYTE) * (flag >> 3); diff <<= shift_width; return diff; @@ -1061,14 +860,7 @@ uint32_t decodeFloatValue(const char *const input, int32_t *const ipos, uint8_t return diff; } -int32_t tsDecompressFloatImp(const char *const input, const int32_t nelements, char *const output) { - float *ostream = (float *)output; - - if (input[0] == 1) { - memcpy(output, input + 1, nelements * FLOAT_BYTES); - return nelements * FLOAT_BYTES; - } - +static void tsDecompressFloatHelper(const char *const input, const int32_t nelements, float* ostream) { uint8_t flags = 0; int32_t ipos = 1; int32_t opos = 0; @@ -1094,6 +886,21 @@ int32_t tsDecompressFloatImp(const char *const input, const int32_t nelements, c ostream[opos++] = curr.real; } +} + +int32_t tsDecompressFloatImp(const char *const input, const int32_t nelements, char *const output) { + if (input[0] == 1) { + memcpy(output, input + 1, nelements * FLOAT_BYTES); + return nelements * FLOAT_BYTES; + } + + if (tsSIMDEnable && tsAVX2Enable) { + tsDecompressFloatImplAvx2(input, nelements, output); + } else if (tsSIMDEnable && tsAVX512Enable) { + tsDecompressFloatImplAvx512(input, nelements, output); + } else { // alternative implementation without SIMD instructions. + tsDecompressFloatHelper(input, nelements, (float*)output); + } return nelements * FLOAT_BYTES; } diff --git a/source/util/src/tconfig.c b/source/util/src/tconfig.c index bb282b4ee3..a78d930326 100644 --- a/source/util/src/tconfig.c +++ b/source/util/src/tconfig.c @@ -22,6 +22,7 @@ #include "tjson.h" #include "tlog.h" #include "tutil.h" +#include "tunit.h" #define CFG_NAME_PRINT_LEN 24 #define CFG_SRC_PRINT_LEN 12 @@ -173,7 +174,7 @@ static int32_t cfgSetBool(SConfigItem *pItem, const char *value, ECfgSrcType sty } static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType stype) { - int32_t ival = (int32_t)atoi(value); + int32_t ival = taosStrHumanToInt32(value); if (ival < pItem->imin || ival > pItem->imax) { uError("cfg:%s, type:%s src:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name, cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax); @@ -187,7 +188,7 @@ static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType st } static int32_t cfgSetInt64(SConfigItem *pItem, const char *value, ECfgSrcType stype) { - int64_t ival = (int64_t)atoll(value); + int64_t ival = taosStrHumanToInt64(value); if (ival < pItem->imin || ival > pItem->imax) { uError("cfg:%s, type:%s src:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name, cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax); @@ -379,7 +380,7 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p } } break; case CFG_DTYPE_INT32: { - int32_t ival = (int32_t)atoi(pVal); + int32_t ival = (int32_t)taosStrHumanToInt32(pVal); if (ival < pItem->imin || ival > pItem->imax) { uError("cfg:%s, type:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name, cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax); @@ -388,7 +389,7 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p } } break; case CFG_DTYPE_INT64: { - int64_t ival = (int64_t)atoll(pVal); + int64_t ival = (int64_t)taosStrHumanToInt64(pVal); if (ival < pItem->imin || ival > pItem->imax) { uError("cfg:%s, type:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name, cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax); diff --git a/source/util/src/tdecompress.c b/source/util/src/tdecompress.c new file mode 100644 index 0000000000..f32a4014d6 --- /dev/null +++ b/source/util/src/tdecompress.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "os.h" +#include "ttypes.h" +#include "tcompression.h" + +int32_t getWordLength(char type) { + int32_t wordLength = 0; + switch (type) { + case TSDB_DATA_TYPE_BIGINT: + wordLength = LONG_BYTES; + break; + case TSDB_DATA_TYPE_INT: + wordLength = INT_BYTES; + break; + case TSDB_DATA_TYPE_SMALLINT: + wordLength = SHORT_BYTES; + break; + case TSDB_DATA_TYPE_TINYINT: + wordLength = CHAR_BYTES; + break; + default: + uError("Invalid decompress integer type:%d", type); + return -1; + } + + return wordLength; +} + +int32_t tsDecompressIntImpl_Hw(const char *const input, const int32_t nelements, char *const output, const char type) { + int32_t word_length = getWordLength(type); + + // Selector value: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + char bit_per_integer[] = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 15, 20, 30, 60}; + int32_t selector_to_elems[] = {240, 120, 60, 30, 20, 15, 12, 10, 8, 7, 6, 5, 4, 3, 2, 1}; + + const char *ip = input + 1; + int32_t count = 0; + int32_t _pos = 0; + int64_t prev_value = 0; + +#if __AVX2__ + while (1) { + if (_pos == nelements) break; + + uint64_t w = 0; + memcpy(&w, ip, LONG_BYTES); + + char selector = (char)(w & INT64MASK(4)); // selector = 4 + char bit = bit_per_integer[(int32_t)selector]; // bit = 3 + int32_t elems = selector_to_elems[(int32_t)selector]; + + // Optimize the performance, by remove the constantly switch operation. + int32_t v = 4; + uint64_t zigzag_value = 0; + uint64_t mask = INT64MASK(bit); + + switch (type) { + case TSDB_DATA_TYPE_BIGINT: { + int64_t* p = (int64_t*) output; + + int32_t gRemainder = (nelements - _pos); + int32_t num = (gRemainder > elems)? elems:gRemainder; + + int32_t batch = num >> 2; + int32_t remain = num & 0x03; + if (selector == 0 || selector == 1) { + if (tsSIMDEnable && tsAVX2Enable) { + for (int32_t i = 0; i < batch; ++i) { + __m256i prev = _mm256_set1_epi64x(prev_value); + _mm256_storeu_si256((__m256i *)&p[_pos], prev); + _pos += 4; + } + + for (int32_t i = 0; i < remain; ++i) { + p[_pos++] = prev_value; + } + } else if (tsSIMDEnable && tsAVX512Enable) { +#if __AVX512F__ + // todo add avx512 impl +#endif + } else { // alternative implementation without SIMD instructions. + for (int32_t i = 0; i < elems && count < nelements; i++, count++) { + p[_pos++] = prev_value; + v += bit; + } + } + } else { + if (tsSIMDEnable && tsAVX2Enable) { + __m256i base = _mm256_set1_epi64x(w); + __m256i maskVal = _mm256_set1_epi64x(mask); + + __m256i shiftBits = _mm256_set_epi64x(bit * 3 + 4, bit * 2 + 4, bit + 4, 4); + __m256i inc = _mm256_set1_epi64x(bit << 2); + + for (int32_t i = 0; i < batch; ++i) { + __m256i after = _mm256_srlv_epi64(base, shiftBits); + __m256i zigzagVal = _mm256_and_si256(after, maskVal); + + // ZIGZAG_DECODE(T, v) (((v) >> 1) ^ -((T)((v)&1))) + __m256i signmask = _mm256_and_si256(_mm256_set1_epi64x(1), zigzagVal); + signmask = _mm256_sub_epi64(_mm256_setzero_si256(), signmask); + + // get the four zigzag values here + __m256i delta = _mm256_xor_si256(_mm256_srli_epi64(zigzagVal, 1), signmask); + + // calculate the cumulative sum (prefix sum) for each number + // decode[0] = prev_value + final[0] + // decode[1] = decode[0] + final[1] -----> prev_value + final[0] + final[1] + // decode[2] = decode[1] + final[2] -----> prev_value + final[0] + final[1] + final[2] + // decode[3] = decode[2] + final[3] -----> prev_value + final[0] + final[1] + final[2] + final[3] + + // 1, 2, 3, 4 + //+ 0, 1, 0, 3 + // 1, 3, 3, 7 + // shift and add for the first round + __m128i prev = _mm_set1_epi64x(prev_value); + __m256i x = _mm256_slli_si256(delta, 8); + + delta = _mm256_add_epi64(delta, x); + _mm256_storeu_si256((__m256i *)&p[_pos], delta); + + // 1, 3, 3, 7 + //+ 0, 0, 3, 3 + // 1, 3, 6, 10 + // shift and add operation for the second round + __m128i firstPart = _mm_loadu_si128((__m128i *)&p[_pos]); + __m128i secondItem = _mm_set1_epi64x(p[_pos + 1]); + __m128i secPart = _mm_add_epi64(_mm_loadu_si128((__m128i *)&p[_pos + 2]), secondItem); + firstPart = _mm_add_epi64(firstPart, prev); + secPart = _mm_add_epi64(secPart, prev); + + // save it in the memory + _mm_storeu_si128((__m128i *)&p[_pos], firstPart); + _mm_storeu_si128((__m128i *)&p[_pos + 2], secPart); + + shiftBits = _mm256_add_epi64(shiftBits, inc); + prev_value = p[_pos + 3]; + _pos += 4; + } + + // handle the remain value + for (int32_t i = 0; i < remain; i++) { + zigzag_value = ((w >> (v + (batch * bit * 4))) & mask); + prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); + + p[_pos++] = prev_value; + v += bit; + } + } else if (tsSIMDEnable && tsAVX512Enable) { +#if __AVX512F__ + // todo add avx512 impl +#endif + } else { // alternative implementation without SIMD instructions. + for (int32_t i = 0; i < elems && count < nelements; i++, count++) { + zigzag_value = ((w >> v) & mask); + prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); + + p[_pos++] = prev_value; + v += bit; + } + } + } + } break; + case TSDB_DATA_TYPE_INT: { + int32_t* p = (int32_t*) output; + + if (selector == 0 || selector == 1) { + for (int32_t i = 0; i < elems && count < nelements; i++, count++) { + p[_pos++] = (int32_t)prev_value; + } + } else { + for (int32_t i = 0; i < elems && count < nelements; i++, count++) { + zigzag_value = ((w >> v) & mask); + prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); + + p[_pos++] = (int32_t)prev_value; + v += bit; + } + } + } break; + case TSDB_DATA_TYPE_SMALLINT: { + int16_t* p = (int16_t*) output; + + if (selector == 0 || selector == 1) { + for (int32_t i = 0; i < elems && count < nelements; i++, count++) { + p[_pos++] = (int16_t)prev_value; + } + } else { + for (int32_t i = 0; i < elems && count < nelements; i++, count++) { + zigzag_value = ((w >> v) & mask); + prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); + + p[_pos++] = (int16_t)prev_value; + v += bit; + } + } + } break; + + case TSDB_DATA_TYPE_TINYINT: { + int8_t *p = (int8_t *)output; + + if (selector == 0 || selector == 1) { + for (int32_t i = 0; i < elems && count < nelements; i++, count++) { + p[_pos++] = (int8_t)prev_value; + } + } else { + for (int32_t i = 0; i < elems && count < nelements; i++, count++) { + zigzag_value = ((w >> v) & mask); + prev_value += ZIGZAG_DECODE(int64_t, zigzag_value); + + p[_pos++] = (int8_t)prev_value; + v += bit; + } + } + } break; + } + + ip += LONG_BYTES; + } + +#endif + return nelements * word_length; +} + +int32_t tsDecompressFloatImplAvx512(const char *const input, const int32_t nelements, char *const output) { +#if __AVX512F__ + // todo add it +#endif + return 0; +} + +// todo add later +int32_t tsDecompressFloatImplAvx2(const char *const input, const int32_t nelements, char *const output) { +#if __AVX2__ +#endif + return 0; +} \ No newline at end of file diff --git a/source/util/src/terror.c b/source/util/src/terror.c index bcdbb3e3ac..21022f2016 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -147,6 +147,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_STMT_CACHE_ERROR, "Stmt cache error") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INTERNAL_ERROR, "Internal error") // mnode-common +TAOS_DEFINE_ERROR(TSDB_CODE_MND_REQ_REJECTED, "Request rejected") TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_RIGHTS, "Insufficient privilege for operation") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SHOWOBJ, "Data expired") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, "Invalid query id") @@ -503,6 +504,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_SCH_STATUS_ERROR, "scheduler status erro TAOS_DEFINE_ERROR(TSDB_CODE_SCH_INTERNAL_ERROR, "scheduler internal error") TAOS_DEFINE_ERROR(TSDB_CODE_SCH_TIMEOUT_ERROR, "Task timeout") TAOS_DEFINE_ERROR(TSDB_CODE_SCH_JOB_IS_DROPPING, "Job is dropping") +TAOS_DEFINE_ERROR(TSDB_CODE_SCH_JOB_NOT_EXISTS, "Job no longer exist") // parser TAOS_DEFINE_ERROR(TSDB_CODE_PAR_SYNTAX_ERROR, "syntax error near") diff --git a/source/util/src/tunit.c b/source/util/src/tunit.c new file mode 100644 index 0000000000..d3447294ea --- /dev/null +++ b/source/util/src/tunit.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "tunit.h" + +#define UNIT_SIZE_CONVERT_FACTOR 1024LL +#define UNIT_ONE_KIBIBYTE UNIT_SIZE_CONVERT_FACTOR +#define UNIT_ONE_MEBIBYTE (UNIT_ONE_KIBIBYTE * UNIT_SIZE_CONVERT_FACTOR) +#define UNIT_ONE_GIBIBYTE (UNIT_ONE_MEBIBYTE * UNIT_SIZE_CONVERT_FACTOR) +#define UNIT_ONE_TEBIBYTE (UNIT_ONE_GIBIBYTE * UNIT_SIZE_CONVERT_FACTOR) +#define UNIT_ONE_PEBIBYTE (UNIT_ONE_TEBIBYTE * UNIT_SIZE_CONVERT_FACTOR) +#define UNIT_ONE_EXBIBYTE (UNIT_ONE_PEBIBYTE * UNIT_SIZE_CONVERT_FACTOR) + +int64_t taosStrHumanToInt64(const char* str) { + size_t sLen = strlen(str); + if (sLen < 2) return atoll(str); + + int64_t val = 0; + + char* strNoUnit = NULL; + char unit = str[sLen - 1]; + if ((unit == 'P') || (unit == 'p')) { + strNoUnit = taosMemoryCalloc(sLen, 1); + memcpy(strNoUnit, str, sLen - 1); + + val = atof(strNoUnit) * UNIT_ONE_PEBIBYTE; + } else if ((unit == 'T') || (unit == 't')) { + strNoUnit = taosMemoryCalloc(sLen, 1); + memcpy(strNoUnit, str, sLen - 1); + + val = atof(strNoUnit) * UNIT_ONE_TEBIBYTE; + } else if ((unit == 'G') || (unit == 'g')) { + strNoUnit = taosMemoryCalloc(sLen, 1); + memcpy(strNoUnit, str, sLen - 1); + + val = atof(strNoUnit) * UNIT_ONE_GIBIBYTE; + } else if ((unit == 'M') || (unit == 'm')) { + strNoUnit = taosMemoryCalloc(sLen, 1); + memcpy(strNoUnit, str, sLen - 1); + + val = atof(strNoUnit) * UNIT_ONE_MEBIBYTE; + } else if ((unit == 'K') || (unit == 'k')) { + strNoUnit = taosMemoryCalloc(sLen, 1); + memcpy(strNoUnit, str, sLen - 1); + + val = atof(strNoUnit) * UNIT_ONE_KIBIBYTE; + } else { + val = atoll(str); + } + + taosMemoryFree(strNoUnit); + return val; +} + +void taosInt64ToHumanStr(int64_t val, char* outStr) { + if (((val >= UNIT_ONE_EXBIBYTE) || (-val >= UNIT_ONE_EXBIBYTE)) && ((val % UNIT_ONE_EXBIBYTE) == 0)) { + sprintf(outStr, "%qdE", (long long)val / UNIT_ONE_EXBIBYTE); + } else if (((val >= UNIT_ONE_PEBIBYTE) || (-val >= UNIT_ONE_PEBIBYTE)) && ((val % UNIT_ONE_PEBIBYTE) == 0)) { + sprintf(outStr, "%qdP", (long long)val / UNIT_ONE_PEBIBYTE); + } else if (((val >= UNIT_ONE_TEBIBYTE) || (-val >= UNIT_ONE_TEBIBYTE)) && ((val % UNIT_ONE_TEBIBYTE) == 0)) { + sprintf(outStr, "%qdT", (long long)val / UNIT_ONE_TEBIBYTE); + } else if (((val >= UNIT_ONE_GIBIBYTE) || (-val >= UNIT_ONE_GIBIBYTE)) && ((val % UNIT_ONE_GIBIBYTE) == 0)) { + sprintf(outStr, "%qdG", (long long)val / UNIT_ONE_GIBIBYTE); + } else if (((val >= UNIT_ONE_MEBIBYTE) || (-val >= UNIT_ONE_MEBIBYTE)) && ((val % UNIT_ONE_MEBIBYTE) == 0)) { + sprintf(outStr, "%qdM", (long long)val / UNIT_ONE_MEBIBYTE); + } else if (((val >= UNIT_ONE_KIBIBYTE) || (-val >= UNIT_ONE_KIBIBYTE)) && ((val % UNIT_ONE_KIBIBYTE) == 0)) { + sprintf(outStr, "%qdK", (long long)val / UNIT_ONE_KIBIBYTE); + } else + sprintf(outStr, "%qd", (long long)val); +} + +int32_t taosStrHumanToInt32(const char* str) { + size_t sLen = strlen(str); + if (sLen < 2) return atoll(str); + + int32_t val = 0; + + char* strNoUnit = NULL; + char unit = str[sLen - 1]; + if ((unit == 'G') || (unit == 'g')) { + strNoUnit = taosMemoryCalloc(sLen, 1); + memcpy(strNoUnit, str, sLen - 1); + + val = atof(strNoUnit) * UNIT_ONE_GIBIBYTE; + } else if ((unit == 'M') || (unit == 'm')) { + strNoUnit = taosMemoryCalloc(sLen, 1); + memcpy(strNoUnit, str, sLen - 1); + + val = atof(strNoUnit) * UNIT_ONE_MEBIBYTE; + } else if ((unit == 'K') || (unit == 'k')) { + strNoUnit = taosMemoryCalloc(sLen, 1); + memcpy(strNoUnit, str, sLen - 1); + + val = atof(strNoUnit) * UNIT_ONE_KIBIBYTE; + } else { + val = atoll(str); + } + + taosMemoryFree(strNoUnit); + return val; +} + +void taosInt32ToHumanStr(int32_t val, char* outStr) { + if (((val >= UNIT_ONE_GIBIBYTE) || (-val >= UNIT_ONE_GIBIBYTE)) && ((val % UNIT_ONE_GIBIBYTE) == 0)) { + sprintf(outStr, "%qdG", (long long)val / UNIT_ONE_GIBIBYTE); + } else if (((val >= UNIT_ONE_MEBIBYTE) || (-val >= UNIT_ONE_MEBIBYTE)) && ((val % UNIT_ONE_MEBIBYTE) == 0)) { + sprintf(outStr, "%qdM", (long long)val / UNIT_ONE_MEBIBYTE); + } else if (((val >= UNIT_ONE_KIBIBYTE) || (-val >= UNIT_ONE_KIBIBYTE)) && ((val % UNIT_ONE_KIBIBYTE) == 0)) { + sprintf(outStr, "%qdK", (long long)val / UNIT_ONE_KIBIBYTE); + } else + sprintf(outStr, "%qd", (long long)val); +} diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 6a7c0b47ec..92eaec52b5 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -120,6 +120,10 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 2 ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 3 ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 4 +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 2 +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 3 +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 4 ,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreDnode.py -N 5 -M 3 -i False ,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreVnode.py -N 5 -M 3 -i False @@ -239,6 +243,7 @@ e ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/splitVGroupRep3.py -N 3 ,,n,system-test,python3 ./test.py -f 0-others/timeRangeWise.py -N 3 ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/delete_check.py +,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/test_hot_refresh_configurations.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/alter_database.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/alter_replica.py -N 3 diff --git a/tests/script/tsim/stream/checkpointInterval1.sim b/tests/script/tsim/stream/checkpointInterval1.sim index 21825e7f48..36f361ad64 100644 --- a/tests/script/tsim/stream/checkpointInterval1.sim +++ b/tests/script/tsim/stream/checkpointInterval1.sim @@ -15,6 +15,8 @@ sql create table t1 using st tags(1,1,1); sql create table t2 using st tags(2,2,2); sql create stream streams0 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt as select _wstart, count(*) c1, sum(a) from st interval(10s); +sleep 1000 + sql insert into t1 values(1648791213000,1,2,3,1.0); sql insert into t2 values(1648791213001,2,2,3,1.1); diff --git a/tests/script/tsim/stream/event0.sim b/tests/script/tsim/stream/event0.sim new file mode 100644 index 0000000000..57116bbc79 --- /dev/null +++ b/tests/script/tsim/stream/event0.sim @@ -0,0 +1,322 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print step1 +print =============== create database +sql create database test vgroups 1; +sql use test; + +sql create table t1(ts timestamp, a int, b int , c int, d double); +sql create stream streams1 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt as select _wstart as s, count(*) c1, sum(b), max(c) from t1 event_window start with a = 0 end with a = 9; +sleep 1000 +sql insert into t1 values(1648791213000,0,1,1,1.0); +sql insert into t1 values(1648791223001,9,2,2,1.1); +sql insert into t1 values(1648791213009,0,3,3,1.0); + +$loop_count = 0 +loop0: + +sleep 300 +print 1 sql select * from streamt; +sql select * from streamt; + +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +# row 0 +if $data01 != 3 then + print ======data01=$data01 + goto loop0 +endi + +if $data02 != 6 then + print ======data02=$data02 + goto loop0 +endi + +if $data03 != 3 then + print ======data03=$data03 + goto loop0 +endi + +sql insert into t1 values(1648791243006,1,1,1,1.1); +sql insert into t1 values(1648791253000,2,2,2,1.1); + + +$loop_count = 0 +loop1: + +sleep 300 +print 2 sql select * from streamt; +sql select * from streamt; + +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +# row 0 +if $rows != 1 then + print ======rows=$rows + goto loop1 +endi + +sql insert into t1 values(1648791243000,0,3,3,1.1); + +$loop_count = 0 +loop2: + +sleep 300 +print 3 sql select * from streamt; +sql select * from streamt; + +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +# row 0 +if $rows != 1 then + print ======rows=$rows + goto loop2 +endi + +sql insert into t1 values(1648791253009,9,4,4,1.1); + +$loop_count = 0 +loop3: + +sleep 300 +print 4 sql select * from streamt; +sql select * from streamt; + +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +# row 0 +if $rows != 2 then + print ======rows=$rows + goto loop3 +endi + +# row 0 +if $data01 != 3 then + print ======data01=$data01 + goto loop3 +endi + +if $data02 != 6 then + print ======data02=$data02 + goto loop3 +endi + +if $data03 != 3 then + print ======data03=$data03 + goto loop3 +endi + +# row 1 +if $data11 != 4 then + print ======data11=$data11 + goto loop3 +endi + +if $data12 != 10 then + print ======data12=$data12 + goto loop3 +endi + +if $data13 != 4 then + print ======data13=$data13 + goto loop3 +endi + +print step2 +print =============== create database test2 +sql create database test2 vgroups 1; +sql use test2; + +sql create table t1(ts timestamp, a int, b int , c int, d double); +sql create stream streams2 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt2 as select _wstart as s, count(*) c1, sum(b), max(c) from t1 event_window start with a = 0 end with b = 9; +sleep 1000 +sql insert into t1 values(1648791213000,0,1,1,1.0); +sql insert into t1 values(1648791213009,1,2,2,2.1); +sql insert into t1 values(1648791223000,0,9,9,9.0); + + +sql insert into t1 values(1648791233000,0,9,9,9.0); + + +$loop_count = 0 +loop4: + +sleep 300 +print sql select * from streamt2; +sql select * from streamt2; + +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +# row 0 +if $rows != 2 then + print ======rows=$rows + goto loop4 +endi + +# row 0 +if $data01 != 3 then + print ======data01=$data01 + goto loop4 +endi + +if $data11 != 1 then + print ======data11=$data11 + goto loop4 +endi + +print step3 +print =============== create database test3 +sql create database test3 vgroups 1; +sql use test3; + +sql create table t1(ts timestamp, a int, b int , c int, d double); +sql create stream streams3 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt3 as select _wstart as s, count(*) c1, sum(b), max(c) from t1 event_window start with a = 0 end with b = 9; +sleep 1000 + +sql insert into t1 values(1648791233009,1,2,2,2.1); + +sql insert into t1 values(1648791233000,0,1,1,1.0); +sql insert into t1 values(1648791243000,0,9,9,9.0); + +$loop_count = 0 +loop5: + +sleep 300 +print 1 sql select * from streamt3; +sql select * from streamt3; + +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +# row 0 +if $rows != 1 then + print ======rows=$rows + goto loop5 +endi + +# row 0 +if $data01 != 3 then + print ======data01=$data01 + goto loop5 +endi + +sql insert into t1 values(1648791223000,0,9,9,9.0); + +$loop_count = 0 +loop6: + +sleep 300 +print 2 sql select * from streamt3; +sql select * from streamt3; + +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 2 then + print ======rows=$rows + goto loop6 +endi + +# row 0 +if $data01 != 1 then + print ======data01=$data01 + goto loop6 +endi + +# row 1 +if $data11 != 3 then + print ======data11=$data11 + goto loop6 +endi + +sql insert into t1 values(1648791213000,0,1,1,1.0); + +sleep 300 + +sql insert into t1 values(1648791213001,1,9,9,9.0); + +$loop_count = 0 +loop7: + +sleep 300 +print 3 sql select * from streamt3; +sql select * from streamt3; + +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print $data20 $data21 $data22 $data23 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 3 then + print ======rows=$rows + goto loop7 +endi + +# row 0 +if $data01 != 2 then + print ======data01=$data01 + goto loop7 +endi + +# row 1 +if $data11 != 1 then + print ======data11=$data11 + goto loop7 +endi + +# row 2 +if $data21 != 3 then + print ======data21=$data21 + goto loop7 +endi + +print event0 end +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/stream/event1.sim b/tests/script/tsim/stream/event1.sim new file mode 100644 index 0000000000..f3b0e4eb01 --- /dev/null +++ b/tests/script/tsim/stream/event1.sim @@ -0,0 +1,332 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print step1 +print =============== create database test1 +sql create database test1 vgroups 1; +sql use test1; + +sql create table t1(ts timestamp, a int, b int , c int, d double); +sql create stream streams1 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt1 as select _wstart as s, count(*) c1, sum(b), max(c) from t1 event_window start with a = 0 end with b = 9; +sleep 1000 + +sql insert into t1 values(1648791233000,0,1,1,1.0); +sql insert into t1 values(1648791243000,1,9,9,9.0); + + +sql insert into t1 values(1648791223000,3,3,3,3.0); + +$loop_count = 0 +loop0: + +sleep 300 +print 1 sql select * from streamt1; +sql select * from streamt1; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 1 then + print ======rows=$rows + goto loop0 +endi + +# row 0 +if $data01 != 2 then + print ======data01=$data01 + goto loop0 +endi + +print step2 +print =============== create database test2 +sql create database test2 vgroups 1; +sql use test2; + +sql create table t1(ts timestamp, a int, b int , c int, d double); +sql create stream streams2 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt2 as select _wstart as s, count(*) c1, sum(b), max(c) from t1 event_window start with a = 0 end with b = 9; +sleep 1000 + +sql insert into t1 values(1648791223000,0,3,3,3.0); + +sql insert into t1 values(1648791233000,0,1,1,1.0); +sql insert into t1 values(1648791243000,1,9,2,2.0); + + +$loop_count = 0 +loop1: + +sleep 300 +print 1 sql select * from streamt2; +sql select * from streamt2; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 1 then + print ======rows=$rows + goto loop1 +endi + +# row 0 +if $data01 != 3 then + print ======data01=$data01 + goto loop1 +endi + + +sql insert into t1 values(1648791223000,1,1,4,4.0); + +$loop_count = 0 +loop2: + +sleep 300 +print 1 sql select * from streamt2; +sql select * from streamt2; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 1 then + print ======rows=$rows + goto loop2 +endi + +# row 0 +if $data01 != 2 then + print ======data01=$data01 + goto loop2 +endi + +sql insert into t1 values(1648791243000,1,1,5,5.0); + +$loop_count = 0 +loop3: + +sleep 300 +print 1 sql select * from streamt2; +sql select * from streamt2; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 0 then + print ======rows=$rows + goto loop3 +endi + +sql insert into t1 values(1648791253000,1,9,6,6.0); + +$loop_count = 0 +loop4: + +sleep 300 +print 1 sql select * from streamt2; +sql select * from streamt2; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 1 then + print ======rows=$rows + goto loop4 +endi + +# row 0 +if $data01 != 3 then + print ======data01=$data01 + goto loop4 +endi + +sql delete from t1 where ts = 1648791253000; + +$loop_count = 0 +loop5: + +sleep 300 +print 1 sql select * from streamt2; +sql select * from streamt2; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 0 then + print ======rows=$rows + goto loop5 +endi + +sql insert into t1 values(1648791263000,1,9,7,7.0); +sql delete from t1 where ts = 1648791243000; + +$loop_count = 0 +loop6: + +sleep 300 +print 1 sql select * from streamt2; +sql select * from streamt2; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 1 then + print ======rows=$rows + goto loop6 +endi + +# row 0 +if $data01 != 2 then + print ======data01=$data01 + goto loop6 +endi + +print step3 +print =============== create database test3 +sql create database test3 vgroups 1; +sql use test3; + +sql create stable st(ts timestamp, a int, b int , c int, d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); + +sql create stream streams3 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt3 as select _wstart as s, count(*) c1, sum(b), max(c) from st partition by tbname event_window start with a = 0 end with b = 9; +sleep 1000 + +sql insert into t1 values(1648791223000,0,3,3,3.0); + +sql insert into t1 values(1648791233000,0,1,1,1.0); +sql insert into t1 values(1648791243000,1,9,2,2.0); + +sql insert into t2 values(1648791223000,0,3,3,3.0); + +sql insert into t2 values(1648791233000,0,1,1,1.0); +sql insert into t2 values(1648791243000,1,9,2,2.0); + + +$loop_count = 0 +loop7: + +sleep 300 +print 1 sql select * from streamt3; +sql select * from streamt3; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print $data20 $data21 $data22 $data23 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 2 then + print ======rows=$rows + goto loop7 +endi + +if $data01 != 3 then + print ======data01=$data01 + goto loop7 +endi + +if $data11 != 3 then + print ======data11=$data11 + goto loop7 +endi + +print update data +sql insert into t1 values(1648791243000,1,3,3,3.0); +sql insert into t2 values(1648791243000,1,3,3,3.0); + +sleep 1000 + +sql insert into t1 values(1648791253000,1,9,3,3.0); +sql insert into t2 values(1648791253000,1,9,3,3.0); + +$loop_count = 0 +loop8: + +sleep 300 +print 1 sql select * from streamt3; +sql select * from streamt3; + +print +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print $data20 $data21 $data22 $data23 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 2 then + print ======rows=$rows + goto loop8 +endi + +if $data01 != 4 then + print ======data01=$data01 + goto loop8 +endi + +if $data11 != 4 then + print ======data11=$data11 + goto loop8 +endi + +print event1 end +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/stream/event2.sim b/tests/script/tsim/stream/event2.sim new file mode 100644 index 0000000000..eb9fca46e6 --- /dev/null +++ b/tests/script/tsim/stream/event2.sim @@ -0,0 +1,84 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print step1 +print =============== create database test +sql create database test vgroups 1; +sql use test; + +sql create stable st(ts timestamp, a int, b int , c int, d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create table t3 using st tags(3,3,3); +sql create table t4 using st tags(3,3,3); + +sql insert into t1 values(1648791223000,0,1,1,1.0); +sql insert into t1 values(1648791233000,0,2,2,2.0); +sql insert into t1 values(1648791243000,1,3,3,3.0); + +sql insert into t2 values(1648791223000,0,1,4,3.0); +sql insert into t2 values(1648791233000,0,2,5,1.0); +sql insert into t2 values(1648791243000,1,3,6,2.0); + +sql insert into t3 values(1648791223000,1,1,7,3.0); +sql insert into t3 values(1648791233000,1,2,8,1.0); +sql insert into t3 values(1648791243000,1,3,9,2.0); + +sql insert into t4 values(1648791223000,1,1,10,3.0); +sql insert into t4 values(1648791233000,0,2,11,1.0); +sql insert into t4 values(1648791243000,1,9,12,2.0); + +sql create stream streams0 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 fill_history 1 into streamt0 as select _wstart as s, count(*) c1, sum(b), max(c), _wend as e from st partition by tbname event_window start with a = 0 end with b = 9; + +sleep 1000 + +sql insert into t1 values(1648791253000,1,9,13,2.0); +sql insert into t2 values(1648791253000,1,9,14,2.0); +sql insert into t3 values(1648791253000,1,9,15,2.0); +sql insert into t4 values(1648791253000,1,9,16,2.0); + +$loop_count = 0 +loop0: + +sleep 300 +print 1 sql select * from streamt0 order by 1, 2, 3, 4; +sql select * from streamt0 order by 1, 2, 3, 4; + +print +print $data00 $data01 $data02 $data03 $data04 +print $data10 $data11 $data12 $data13 $data14 +print $data20 $data21 $data22 $data23 $data24 +print $data30 $data31 $data32 $data33 $data34 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 3 then + print ======rows=$rows + goto loop0 +endi + +if $data01 != 4 then + print ======data01=$data01 + goto loop0 +endi + +if $data11 != 4 then + print ======data11=$data11 + goto loop0 +endi + +if $data21 != 2 then + print ======data21=$data21 + goto loop0 +endi + + +print event1 end +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/stream/eventtmp.sim b/tests/script/tsim/stream/eventtmp.sim new file mode 100644 index 0000000000..52ca4fd9ef --- /dev/null +++ b/tests/script/tsim/stream/eventtmp.sim @@ -0,0 +1,61 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print step1 +print =============== create database test +sql create database test vgroups 1; +sql use test; + +sql create stable st(ts timestamp, a int, b int , c int, d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create table t3 using st tags(3,3,3); +sql create table t4 using st tags(3,3,3); + + +sql insert into t4 values(1648791223000,1,1,10,3.0); +sql insert into t4 values(1648791233000,0,2,11,1.0); +sql insert into t4 values(1648791243000,1,9,12,2.0); + +sql create stream streams0 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 fill_history 1 into streamt0 as select _wstart as s, count(*) c1, sum(b), max(c), _wend as e from st partition by tbname event_window start with a = 0 end with b = 9; + +sleep 1000 + +sql insert into t4 values(1648791253000,1,9,16,2.0); + +$loop_count = 0 +loop0: + +sleep 300 +print 1 sql select * from streamt0 order by 1, 2, 3, 4; +sql select * from streamt0 order by 1, 2, 3, 4; + +print +print $data00 $data01 $data02 $data03 $data04 +print $data10 $data11 $data12 $data13 $data14 +print $data20 $data21 $data22 $data23 $data24 +print $data30 $data31 $data32 $data33 $data34 +print + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 1 then + print ======rows=$rows + goto loop0 +endi + +if $data01 != 2 then + print ======data01=$data01 + goto loop0 +endi + + + +print event1 end +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/stream/fillIntervalRange.sim b/tests/script/tsim/stream/fillIntervalRange.sim index 99c1fe8ad4..e5316e6a1e 100644 --- a/tests/script/tsim/stream/fillIntervalRange.sim +++ b/tests/script/tsim/stream/fillIntervalRange.sim @@ -64,7 +64,7 @@ endi sql select count(*) from streamt; if $data00 != 9098 then - print =====rows=$rows + print =====data00=$data00 goto loop1 endi diff --git a/tests/script/tsim/stream/sliding.sim b/tests/script/tsim/stream/sliding.sim index a92da7f472..cc4d14b6fb 100644 --- a/tests/script/tsim/stream/sliding.sim +++ b/tests/script/tsim/stream/sliding.sim @@ -23,6 +23,8 @@ sql create stream stream_t1 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 i sql create stream stream_t2 trigger at_once watermark 1d IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamtST2 as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s) sliding (5s); sleep 1000 +sleep 1000 + sql insert into t1 values(1648791210000,1,2,3,1.0); sql insert into t1 values(1648791216000,2,2,3,1.1); sql insert into t1 values(1648791220000,3,2,3,2.1); @@ -314,6 +316,8 @@ sql create stream streams11 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 i sql create stream streams12 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt2 as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s, 5s); sleep 1000 +sleep 1000 + sql insert into t1 values(1648791213000,1,2,3,1.0); sql insert into t1 values(1648791223001,2,2,3,1.1); sql insert into t1 values(1648791233002,3,2,3,2.1); @@ -448,6 +452,8 @@ sql create stream streams21 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 i sql create stream streams22 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt22 as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s, 5s); sleep 1000 +sleep 1000 + sql insert into t1 values(1648791213000,1,1,1,1.0); sql insert into t1 values(1648791223001,2,2,2,1.1); sql insert into t1 values(1648791233002,3,3,3,2.1); @@ -712,6 +718,8 @@ sql create table t2 using st tags(2,2,2); sql create stream streams4 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt4 as select _wstart as ts, count(*),min(a) c1 from st interval(10s) sliding(5s); sleep 1000 +sleep 1000 + sql insert into t1 values(1648791213000,1,1,1,1.0); sql insert into t1 values(1648791243000,2,1,1,1.0); diff --git a/tests/script/tsim/stream/windowClose.sim b/tests/script/tsim/stream/windowClose.sim index 5bd17e076e..67678963ea 100644 --- a/tests/script/tsim/stream/windowClose.sim +++ b/tests/script/tsim/stream/windowClose.sim @@ -134,6 +134,162 @@ if $rows != 2 then goto loop1 endi +print step 1 max delay 2s +sql create database test3 vgroups 4; +sql use test3; +sql create table t1(ts timestamp, a int, b int , c int, d double); + +sql create stream stream13 trigger max_delay 2s into streamt13 as select _wstart, sum(a), now from t1 interval(10s); + +sleep 1000 + +sql insert into t1 values(1648791213000,1,2,3,1.0); +sql insert into t1 values(1648791223001,2,2,3,1.1); + +$loop_count = 0 + +loop2: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt13; + +if $rows != 2 then + print ======rows=$rows + goto loop2 +endi + +$now02 = $data02 +$now12 = $data12 + + +print step1 max delay 2s......... sleep 3s +sleep 3000 + +sql select * from streamt13; + + +if $data02 != $now02 then + print ======data02=$data02 + return -1 +endi + +if $data12 != $now12 then + print ======data12=$data12 + return -1 +endi + +print step 2 max delay 2s + +sql create database test4 vgroups 4; +sql use test4; + +sql create stable st(ts timestamp, a int, b int , c int, d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); + +sql create stream stream14 trigger max_delay 2s into streamt14 as select _wstart, sum(a), now from st partition by tbname interval(10s); + +sleep 1000 + +sql insert into t1 values(1648791213000,1,2,3,1.0); +sql insert into t1 values(1648791223000,2,2,3,1.1); + +sql insert into t2 values(1648791213000,3,2,3,1.0); +sql insert into t2 values(1648791223000,4,2,3,1.1); + +$loop_count = 0 + +loop3: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt14 order by 2; +print $data00 $data01 $data02 +print $data10 $data11 $data12 +print $data20 $data21 $data22 +print $data30 $data31 $data32 + +if $rows != 4 then + print ======rows=$rows + goto loop3 +endi + +$now02 = $data02 +$now12 = $data12 +$now22 = $data22 +$now32 = $data32 + +print step2 max delay 2s......... sleep 3s +sleep 3000 + +sql select * from streamt14 order by 2; +print $data00 $data01 $data02 +print $data10 $data11 $data12 +print $data20 $data21 $data22 +print $data30 $data31 $data32 + + +if $data02 != $now02 then + print ======data02=$data02 + return -1 +endi + +if $data12 != $now12 then + print ======data12=$data12 + return -1 +endi + +if $data22 != $now22 then + print ======data22=$data22 + return -1 +endi + +if $data32 != $now32 then + print ======data32=$data32 + return -1 +endi + +print step2 max delay 2s......... sleep 3s +sleep 3000 + +sql select * from streamt14 order by 2; +print $data00 $data01 $data02 +print $data10 $data11 $data12 +print $data20 $data21 $data22 +print $data30 $data31 $data32 + + +if $data02 != $now02 then + print ======data02=$data02 + return -1 +endi + +if $data12 != $now12 then + print ======data12=$data12 + return -1 +endi + +if $data22 != $now22 then + print ======data22=$data22 + return -1 +endi + +if $data32 != $now32 then + print ======data32=$data32 + return -1 +endi + print ======over system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/system-test/0-others/test_hot_refresh_configurations.py b/tests/system-test/0-others/test_hot_refresh_configurations.py new file mode 100644 index 0000000000..7aed7274a4 --- /dev/null +++ b/tests/system-test/0-others/test_hot_refresh_configurations.py @@ -0,0 +1,222 @@ +import subprocess +import random +import time +import os + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * + + +class TDTestCase: + """This test case is used to veirfy hot refresh configurations + """ + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor()) + + self.configration_dic = { + "cli": [ + { + "name": "keepAliveIdle", + "values": [1, 100, 7200000], + "except_values": [0, 7200001] + }, + { + "name": "queryPolicy", + "values": [1, 2, 4], + "except_values": [0, 5] + }, + { + "name": "numOfLogLines", + "values": [1000, 2000, 2000000000], + "except_values": [999, 2000000001] + }, + { + "name": "logKeepDays", + "values": [-365000, 2000, 365000], + "except_values": [-365001, 365001] + } + ], + "svr": [ + { + "name": "keepAliveIdle", + "alias": "tsKeepAliveIdle", + "values": [1, 100, 7200000], + "except_values": [0, 7200001] + }, + { + "name": "mndSdbWriteDelta", + "alias": "tsMndSdbWriteDelta", + "values": [20, 1000, 10000], + "except_values": [19, 10001] + }, + { + "name": "enableWhiteList", + "alias": "tsEnableWhiteList", + "values": [0, 1], + "except_values": [-1, 2] + }, + { + "name": "audit", + "alias": "tsEnableAudit", + "values": [0, 1], + "except_values": [-1, 2] + }, + { + "name": "telemetryReporting", + "alias": "tsEnableTelem", + "values": [0, 1], + "except_values": [-1, 2] + }, + { + "name": "cacheLazyLoadThreshold", + "alias": "tsCacheLazyLoadThreshold", + "values": [0, 200, 100000], + "except_values": [-1, 100001] + }, + { + "name": "queryRspPolicy", + "alias": "tsQueryRspPolicy", + "values": [0, 1], + "except_values": [-1, 2] + }, + { + "name": "ttlFlushThreshold", + "alias": "tsTtlFlushThreshold", + "values": [-1, 200, 1000000], + "except_values": [-2, 1000001] + }, + { + "name": "timeseriesThreshold", + "alias": "tsTimeSeriesThreshold", + "values": [0, 200, 2000], + "except_values": [-2, 2001] + }, + { + "name": "minDiskFreeSize", + "alias": "tsMinDiskFreeSize", + "values": ["51200K", "100M", "1G"], + "except_values": ["1024K", "1.1G", "1T"] + }, + { + "name": "tmqMaxTopicNum", + "alias": "tmqMaxTopicNum", + "values": [1, 1000, 10000], + "except_values": [0, 10001] + }, + { + "name": "transPullupInterval", + "alias": "tsTransPullupInterval", + "values": [1, 1000, 10000], + "except_values": [0, 10001] + }, + { + "name": "mqRebalanceInterval", + "alias": "tsMqRebalanceInterval", + "values": [1, 1000, 10000], + "except_values": [0, 10001] + }, + { + "name": "checkpointInterval", + "alias": "tsStreamCheckpointInterval", + "values": [60, 1000, 1200], + "except_values": [59, 1201] + }, + { + "name": "trimVDbIntervalSec", + "alias": "tsTrimVDbIntervalSec", + "values": [1, 1000, 100000], + "except_values": [0, 100001] + }, + { + "name": "disableStream", + "alias": "tsDisableStream", + "values": [0, 1], + "except_values": [-1] + }, + { + "name": "maxStreamBackendCache", + "alias": "tsMaxStreamBackendCache", + "values": [16, 512, 1024], + "except_values": [15, 1025] + }, + { + "name": "numOfLogLines", + "alias": "tsNumOfLogLines", + "values": [1000, 50000, 2000000000], + "except_values": [999, 2000000001] + }, + { + "name": "logKeepDays", + "alias": "tsLogKeepDays", + "values": [-365000, 10, 365000], + "except_values": [-365001, 365001] + } + ] + } + + def get_param_value_with_gdb(self, config_name, process_name): + res = subprocess.Popen("gdb -q -nx -p `pidof {}` --batch -ex 'set height 0' -ex 'p {}'".format(process_name, config_name), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + r_lines = res.stdout.read() + if r_lines: + for line in r_lines.decode().split("\n"): + if "$1 = " in line: + tdLog.debug("gdb result: {}".format(line)) + return line.split(" = ")[1] + + def cli_check(self, name, values, except_values=False): + if not except_values: + for v in values: + tdLog.debug("Set {} to {}".format(name, v)) + tdSql.execute(f'alter local "{name} {v}";') + else: + for v in values: + tdLog.debug("Set {} to {}".format(name, v)) + tdSql.error(f'alter local "{name} {v}";') + + def svr_check(self, name, alias, values, except_values=False): + p_list = ["dnode 1", "all dnodes"] + # check bool param value + if len(values) == 2 and [0, 1] == values and name != "queryRspPolicy": + is_bool = True + else: + is_bool = False + tdLog.debug(f"{name} is_bool: {is_bool}") + if not except_values: + for v in values: + dnode = random.choice(p_list) + tdSql.execute(f'alter {dnode} "{name} {v}";') + value = self.get_param_value_with_gdb(alias, "taosd") + if value: + tdLog.debug(f"value: {value}") + assert(value == str(bool(v)).lower() if is_bool else str(v)) + else: + for v in values: + dnode = random.choice(p_list) + tdSql.error(f'alter {dnode} "{name} {v}";') + + def run(self): + for key in self.configration_dic: + if "cli" == key: + for item in self.configration_dic[key]: + self.cli_check(item["name"], item["values"]) + if "except_values" in item: + self.cli_check(item["name"], item["except_values"], True) + elif "svr" == key: + for item in self.configration_dic[key]: + self.svr_check(item["name"], item["alias"], item["values"]) + if "except_values" in item: + self.svr_check(item["name"], item["alias"], item["except_values"], True) + else: + raise Exception(f"unknown key: {key}") + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/2-query/To_iso8601.py b/tests/system-test/2-query/To_iso8601.py index 92aacbb350..160473ffce 100644 --- a/tests/system-test/2-query/To_iso8601.py +++ b/tests/system-test/2-query/To_iso8601.py @@ -30,17 +30,16 @@ class TDTestCase: tdSql.query(f'select to_iso8601(ts) from {self.ntbname}') for i in range(self.rowNum): tdSql.checkEqual(tdSql.queryResult[i][0],f'2022-01-01T00:00:00.00{i}{time_zone}') - timezone_list = ['+0000','+0100','+0200','+0300','+0330','+0400','+0500','+0530','+0600','+0700','+0800','+0900','+1000','+1100','+1200',\ - '+00','+01','+02','+03','+04','+05','+06','+07','+08','+09','+10','+11','+12',\ - '+00:00','+01:00','+02:00','+03:00','+03:30','+04:00','+05:00','+05:30','+06:00','+07:00','+08:00','+09:00','+10:00','+11:00','+12:00',\ - '-0000','-0100','-0200','-0300','-0400','-0500','-0600','-0700','-0800','-0900','-1000','-1100','-1200',\ - '-00','-01','-02','-03','-04','-05','-06','-07','-08','-09','-10','-11','-12',\ - '-00:00','-01:00','-02:00','-03:00','-04:00','-05:00','-06:00','-07:00','-08:00','-09:00','-10:00','-11:00','-12:00',\ - 'z','Z'] - for j in timezone_list: - tdSql.query(f'select to_iso8601(ts,"{j}") from {self.ntbname}') - for i in range(self.rowNum): - tdSql.checkEqual(tdSql.queryResult[i][0],f'2022-01-01T00:00:00.00{i}{j}') + + tz_list = ['+0000','+0530', '+00', '+06', '+00:00', '+12:00', '-0000', '-0900', '-00', '-05', '-00:00', '-03:00','z', 'Z'] + res_list = ['2021-12-31T16:00:00.000+0000', '2021-12-31T21:30:00.000+0530', '2021-12-31T16:00:00.000+00', '2021-12-31T22:00:00.000+06',\ + '2021-12-31T16:00:00.000+00:00', '2022-01-01T04:00:00.000+12:00','2021-12-31T16:00:00.000-0000','2021-12-31T07:00:00.000-0900',\ + '2021-12-31T16:00:00.000-00', '2021-12-31T11:00:00.000-05','2021-12-31T16:00:00.000-00:00','2021-12-31T13:00:00.000-03:00',\ + '2021-12-31T16:00:00.000z', '2021-12-31T16:00:00.000Z'] + for i in range(len(tz_list)): + tdSql.query(f'select to_iso8601(ts,"{tz_list[i]}") from {self.ntbname} where c1==1') + tdSql.checkEqual(tdSql.queryResult[0][0],res_list[i]) + error_param_list = [0,100.5,'a','!'] for i in error_param_list: tdSql.error(f'select to_iso8601(ts,"{i}") from {self.ntbname}') diff --git a/tests/system-test/2-query/limit.py b/tests/system-test/2-query/limit.py index fb5595a8be..961cff5087 100644 --- a/tests/system-test/2-query/limit.py +++ b/tests/system-test/2-query/limit.py @@ -338,11 +338,38 @@ class TDTestCase: tdLog.printNoPrefix("======== test case 1 end ...... ") + # + def checkVGroups(self): + + # db2 + tdSql.execute("create database db2 vgroups 2;") + tdSql.execute("use db2;") + tdSql.execute("create table st(ts timestamp, age int) tags(area int);") + tdSql.execute("create table t1 using st tags(1);") + tdSql.query("select distinct(tbname) from st limit 1 offset 100;") + tdSql.checkRows(0) + tdLog.info("check db2 vgroups 2 limit 1 offset 100 successfully!") + + + # db1 + tdSql.execute("create database db1 vgroups 1;") + tdSql.execute("use db1;") + tdSql.execute("create table st(ts timestamp, age int) tags(area int);") + tdSql.execute("create table t1 using st tags(1);") + tdSql.query("select distinct(tbname) from st limit 1 offset 100;") + tdSql.checkRows(0) + tdLog.info("check db1 vgroups 1 limit 1 offset 100 successfully!") + + def run(self): # tdSql.prepare() self.prepareTestEnv() self.tmqCase1() + # one vgroup diff more than one vgroup check + self.checkVGroups() + + def stop(self): tdSql.close() tdLog.success(f"{__file__} successfully executed") diff --git a/tests/system-test/2-query/ts-4233.py b/tests/system-test/2-query/ts-4233.py new file mode 100644 index 0000000000..9b0a2f175c --- /dev/null +++ b/tests/system-test/2-query/ts-4233.py @@ -0,0 +1,46 @@ + +import taos + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * + +class TDTestCase: + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), True) + + def checksql(self, sql): + result = os.popen("taos -s '%s'" %sql) + res = result.read() + print(res) + if ("Query OK" in res): + tdLog.info(f"checkEqual success") + else : + tdLog.exit(f"checkEqual error") + + def check(self): + conn = taos.connect() + sql = "select 'a;b' as x" + tdSql.query(f"%s" %sql) + tdSql.checkRows(1) + + self.checksql('select "a;b" as x\G') + self.checksql('select "a;b" as x >> /tmp/res.txt') + return + + def run(self): + tdSql.prepare() + self.check() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tools/shell/inc/shellInt.h b/tools/shell/inc/shellInt.h index 57415f8335..1c885b151c 100644 --- a/tools/shell/inc/shellInt.h +++ b/tools/shell/inc/shellInt.h @@ -80,6 +80,7 @@ typedef struct { #ifdef WEBSOCKET bool restful; bool cloud; + bool local; char* dsn; int32_t timeout; #endif diff --git a/tools/shell/src/shellArguments.c b/tools/shell/src/shellArguments.c index 52cb524e3b..4817b23029 100644 --- a/tools/shell/src/shellArguments.c +++ b/tools/shell/src/shellArguments.c @@ -410,7 +410,7 @@ int32_t shellParseArgs(int32_t argc, char *argv[]) { shellInitArgs(argc, argv); shell.info.clientVersion = "Welcome to the %s Command Line Interface, Client Version:%s\r\n" - "Copyright (c) 2022 by %s, all rights reserved.\r\n\r\n"; + "Copyright (c) 2023 by %s, all rights reserved.\r\n\r\n"; #ifdef CUS_NAME strcpy(shell.info.cusName, CUS_NAME); #else diff --git a/tools/shell/src/shellAuto.c b/tools/shell/src/shellAuto.c index 60d6388faa..bd5329d810 100644 --- a/tools/shell/src/shellAuto.c +++ b/tools/shell/src/shellAuto.c @@ -83,6 +83,11 @@ SWords shellCommands[] = { {"alter local \"asynclog\" \"1\";", 0, 0, NULL}, {"alter topic", 0, 0, NULL}, {"alter user ;", 0, 0, NULL}, +#ifdef TD_ENTERPRISE + {"balance vgroup;", 0, 0, NULL}, + {"balance vgroup leader ", 0, 0, NULL}, +#endif + // 20 {"create table using tags(", 0, 0, NULL}, {"create database " @@ -127,9 +132,12 @@ SWords shellCommands[] = { {"kill query ", 0, 0, NULL}, {"kill transaction ", 0, 0, NULL}, #ifdef TD_ENTERPRISE - {"merge vgroup ", 0, 0, NULL}, + {"merge vgroup ", 0, 0, NULL}, #endif {"pause stream ;", 0, 0, NULL}, +#ifdef TD_ENTERPRISE + {"redistribute vgroup dnode ;", 0, 0, NULL}, +#endif {"resume stream ;", 0, 0, NULL}, {"reset query cache;", 0, 0, NULL}, {"restore dnode ;", 0, 0, NULL}, @@ -187,7 +195,7 @@ SWords shellCommands[] = { {"show consumers;", 0, 0, NULL}, {"show grants;", 0, 0, NULL}, #ifdef TD_ENTERPRISE - {"split vgroup ", 0, 0, NULL}, + {"split vgroup ", 0, 0, NULL}, #endif {"insert into values(", 0, 0, NULL}, {"insert into using tags(", 0, 0, NULL}, @@ -268,7 +276,9 @@ char* db_options[] = {"keep ", "wal_retention_size ", "wal_segment_size "}; -char* alter_db_options[] = {"cachemodel ", "replica ", "keep ", "cachesize ", "wal_fsync_period ", "wal_level "}; +char* alter_db_options[] = {"cachemodel ", "replica ", "keep ", "stt_trigger ", + "wal_retention_period ", "wal_retention_size ", "cachesize ", + "wal_fsync_period ", "buffer ", "pages " ,"wal_level "}; char* data_types[] = {"timestamp", "int", "int unsigned", "varchar(16)", @@ -312,26 +322,27 @@ bool waitAutoFill = false; #define WT_VAR_TOPIC 5 #define WT_VAR_STREAM 6 #define WT_VAR_UDFNAME 7 +#define WT_VAR_VGROUPID 8 -#define WT_FROM_DB_MAX 7 // max get content from db +#define WT_FROM_DB_MAX 8 // max get content from db #define WT_FROM_DB_CNT (WT_FROM_DB_MAX + 1) -#define WT_VAR_ALLTABLE 8 -#define WT_VAR_FUNC 9 -#define WT_VAR_KEYWORD 10 -#define WT_VAR_TBACTION 11 -#define WT_VAR_DBOPTION 12 -#define WT_VAR_ALTER_DBOPTION 13 -#define WT_VAR_DATATYPE 14 -#define WT_VAR_KEYTAGS 15 -#define WT_VAR_ANYWORD 16 -#define WT_VAR_TBOPTION 17 -#define WT_VAR_USERACTION 18 -#define WT_VAR_KEYSELECT 19 -#define WT_VAR_SYSTABLE 20 -#define WT_VAR_LANGUAGE 21 +#define WT_VAR_ALLTABLE 9 +#define WT_VAR_FUNC 10 +#define WT_VAR_KEYWORD 11 +#define WT_VAR_TBACTION 12 +#define WT_VAR_DBOPTION 13 +#define WT_VAR_ALTER_DBOPTION 14 +#define WT_VAR_DATATYPE 15 +#define WT_VAR_KEYTAGS 16 +#define WT_VAR_ANYWORD 17 +#define WT_VAR_TBOPTION 18 +#define WT_VAR_USERACTION 19 +#define WT_VAR_KEYSELECT 20 +#define WT_VAR_SYSTABLE 21 +#define WT_VAR_LANGUAGE 22 -#define WT_VAR_CNT 22 +#define WT_VAR_CNT 23 #define WT_TEXT 0xFF @@ -345,11 +356,11 @@ TdThread* threads[WT_FROM_DB_CNT]; // obtain var name with sql from server char varTypes[WT_VAR_CNT][64] = { "", "", "", "", "", "", "", - "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}; char varSqls[WT_FROM_DB_CNT][64] = {"show databases;", "show stables;", "show tables;", "show dnodes;", - "show users;", "show topics;", "show streams;", "show functions;"}; + "show users;", "show topics;", "show streams;", "show functions;", "show vgroups;"}; // var words current cursor, if user press any one key except tab, cursorVar can be reset to -1 int cursorVar = -1; @@ -520,7 +531,10 @@ void showHelp() { printf( "\n\n\ ----- special commands on enterpise version ----- \n\ + balance vgroup; \n\ + balance vgroup leader \n\ compact database ; \n\ + redistribute vgroup dnode ;\n\ split vgroup ;"); #endif @@ -675,9 +689,9 @@ bool shellAutoInit() { // generate varType GenerateVarType(WT_VAR_FUNC, functions, sizeof(functions) / sizeof(char*)); GenerateVarType(WT_VAR_KEYWORD, keywords, sizeof(keywords) / sizeof(char*)); + GenerateVarType(WT_VAR_TBACTION, tb_actions, sizeof(tb_actions) / sizeof(char*)); GenerateVarType(WT_VAR_DBOPTION, db_options, sizeof(db_options) / sizeof(char*)); GenerateVarType(WT_VAR_ALTER_DBOPTION, alter_db_options, sizeof(alter_db_options) / sizeof(char*)); - GenerateVarType(WT_VAR_TBACTION, tb_actions, sizeof(tb_actions) / sizeof(char*)); GenerateVarType(WT_VAR_DATATYPE, data_types, sizeof(data_types) / sizeof(char*)); GenerateVarType(WT_VAR_KEYTAGS, key_tags, sizeof(key_tags) / sizeof(char*)); GenerateVarType(WT_VAR_TBOPTION, tb_options, sizeof(tb_options) / sizeof(char*)); diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index 3b150230e7..115abdcd36 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -62,6 +62,8 @@ static void shellCleanup(void *arg); static void *shellCancelHandler(void *arg); static void *shellThreadLoop(void *arg); +static bool shellCmdkilled = false; + bool shellIsEmptyCommand(const char *cmd) { for (char c = *cmd++; c != 0; c = *cmd++) { if (c != ' ' && c != '\t' && c != ';') { @@ -72,6 +74,8 @@ bool shellIsEmptyCommand(const char *cmd) { } int32_t shellRunSingleCommand(char *command) { + shellCmdkilled = false; + if (shellIsEmptyCommand(command)) { return 0; } @@ -199,22 +203,17 @@ void shellRunSingleCommandImp(char *command) { bool printMode = false; if ((sptr = strstr(command, ">>")) != NULL) { - cptr = strstr(command, ";"); - if (cptr != NULL) { - *cptr = '\0'; - } - fname = sptr + 2; while (*fname == ' ') fname++; *sptr = '\0'; - } - if ((sptr = strstr(command, "\\G")) != NULL) { - cptr = strstr(command, ";"); + cptr = strstr(fname, ";"); if (cptr != NULL) { *cptr = '\0'; } + } + if ((sptr = strstr(command, "\\G")) != NULL) { *sptr = '\0'; printMode = true; // When output to a file, the switch does not work. } @@ -262,7 +261,8 @@ void shellRunSingleCommandImp(char *command) { if (error_no == 0) { printf("Query OK, %"PRId64 " row(s) in set (%.6fs)\r\n", numOfRows, (et - st) / 1E6); } else { - printf("Query interrupted (%s), %"PRId64 " row(s) in set (%.6fs)\r\n", taos_errstr(pSql), numOfRows, (et - st) / 1E6); + terrno = error_no; + printf("Query interrupted (%s), %"PRId64 " row(s) in set (%.6fs)\r\n", taos_errstr(NULL), numOfRows, (et - st) / 1E6); } taos_free_result(pSql); } else { @@ -957,7 +957,11 @@ void shellDumpResultCallback(void *param, TAOS_RES *tres, int num_of_rows) { } } dump_info->numOfAllRows += num_of_rows; - taos_fetch_rows_a(tres, shellDumpResultCallback, param); + if (!shellCmdkilled) { + taos_fetch_rows_a(tres, shellDumpResultCallback, param); + } else { + tsem_post(&dump_info->sem); + } } else { if (num_of_rows < 0) { printf("\033[31masync retrieve failed, code: %d\033[0m\n", num_of_rows); @@ -972,13 +976,15 @@ int64_t shellDumpResult(TAOS_RES *tres, char *fname, int32_t *error_no, bool ver num_of_rows = shellDumpResultToFile(fname, tres); } else { tsDumpInfo dump_info; - init_dump_info(&dump_info, tres, sql, vertical); - taos_fetch_rows_a(tres, shellDumpResultCallback, &dump_info); - tsem_wait(&dump_info.sem); - num_of_rows = dump_info.numOfAllRows; + if (!shellCmdkilled) { + init_dump_info(&dump_info, tres, sql, vertical); + taos_fetch_rows_a(tres, shellDumpResultCallback, &dump_info); + tsem_wait(&dump_info.sem); + num_of_rows = dump_info.numOfAllRows; + } } - *error_no = taos_errno(tres); + *error_no = shellCmdkilled ? TSDB_CODE_TSC_QUERY_KILLED : taos_errno(tres); return num_of_rows; } @@ -1202,6 +1208,7 @@ void *shellCancelHandler(void *arg) { } else { #endif if (shell.conn) { + shellCmdkilled = true; taos_kill_query(shell.conn); } #ifdef WEBSOCKET diff --git a/tools/shell/src/shellMain.c b/tools/shell/src/shellMain.c index 795621dfdd..18f4ca21d1 100644 --- a/tools/shell/src/shellMain.c +++ b/tools/shell/src/shellMain.c @@ -47,6 +47,7 @@ int main(int argc, char *argv[]) { #ifdef WEBSOCKET shell.args.timeout = SHELL_WS_TIMEOUT; shell.args.cloud = true; + shell.args.local = false; #endif #if !defined(WINDOWS) diff --git a/tools/shell/src/shellUtil.c b/tools/shell/src/shellUtil.c index 93451c85a9..0350d934a7 100644 --- a/tools/shell/src/shellUtil.c +++ b/tools/shell/src/shellUtil.c @@ -130,11 +130,21 @@ void shellCheckConnectMode() { } if (shell.args.cloud) { shell.args.dsn = getenv("TDENGINE_CLOUD_DSN"); - if (shell.args.dsn) { + if (shell.args.dsn && strlen(shell.args.dsn) > 4) { shell.args.cloud = true; + shell.args.local = false; shell.args.restful = false; return; } + + shell.args.dsn = getenv("TDENGINE_DSN"); + if (shell.args.dsn && strlen(shell.args.dsn) > 4) { + shell.args.cloud = true; + shell.args.local = true; + shell.args.restful = false; + return; + } + if (shell.args.restful) { if (!shell.args.host) { shell.args.host = "localhost"; diff --git a/tools/shell/src/shellWebsocket.c b/tools/shell/src/shellWebsocket.c index e83ceff099..bff2ef7592 100644 --- a/tools/shell/src/shellWebsocket.c +++ b/tools/shell/src/shellWebsocket.c @@ -59,7 +59,17 @@ int shell_conn_ws_server(bool first) { fprintf(stdout, "successfully connected to %s\n\n", shell.args.dsn); } else if (first && shell.args.cloud) { - fprintf(stdout, "successfully connected to cloud service\n"); + if(shell.args.local) { + const char* host = strstr(shell.args.dsn, "@"); + if(host) { + host += 1; + } else { + host = shell.args.dsn; + } + fprintf(stdout, "successfully connected to %s\n", host); + } else { + fprintf(stdout, "successfully connected to cloud service\n"); + } } fflush(stdout); @@ -236,22 +246,17 @@ void shellRunSingleCommandWebsocketImp(char *command) { bool printMode = false; if ((sptr = strstr(command, ">>")) != NULL) { - cptr = strstr(command, ";"); - if (cptr != NULL) { - *cptr = '\0'; - } - fname = sptr + 2; while (*fname == ' ') fname++; *sptr = '\0'; - } - if ((sptr = strstr(command, "\\G")) != NULL) { - cptr = strstr(command, ";"); + cptr = strstr(fname, ";"); if (cptr != NULL) { *cptr = '\0'; } + } + if ((sptr = strstr(command, "\\G")) != NULL) { *sptr = '\0'; printMode = true; // When output to a file, the switch does not work. }