提交 90e47f72 编写于 作者: K kailixu

Merge branch '2.6' into feat/TS-1883-2.6

build/ build/
.ycm_extra_conf.py .ycm_extra_conf.py
.vscode/ .vscode/
.cache/
compile_commands.json
.idea/ .idea/
cmake-build-debug/ cmake-build-debug/
cmake-build-release/ cmake-build-release/
cmake-build-relwithdebinfo/
cscope.out cscope.out
cscope.files cscope.files
tags tags
......
...@@ -23,31 +23,31 @@ def sync_source() { ...@@ -23,31 +23,31 @@ def sync_source() {
sh ''' sh '''
cd ${WKC} cd ${WKC}
git clean -fxd git clean -fxd
git checkout master git checkout -f master
''' '''
} else if (env.CHANGE_TARGET == '2.0') { } else if (env.CHANGE_TARGET == '2.0') {
sh ''' sh '''
cd ${WKC} cd ${WKC}
git clean -fxd git clean -fxd
git checkout 2.0 git checkout -f 2.0
''' '''
} else if (env.CHANGE_TARGET == '2.4') { } else if (env.CHANGE_TARGET == '2.4') {
sh ''' sh '''
cd ${WKC} cd ${WKC}
git clean -fxd git clean -fxd
git checkout 2.4 git checkout -f 2.4
''' '''
} else if (env.CHANGE_TARGET == '2.6') { } else if (env.CHANGE_TARGET == '2.6') {
sh ''' sh '''
cd ${WKC} cd ${WKC}
git clean -fxd git clean -fxd
git checkout 2.6 git checkout -f 2.6
''' '''
} else { } else {
sh ''' sh '''
cd ${WKC} cd ${WKC}
git clean -fxd git clean -fxd
git checkout develop git checkout -f develop
''' '''
} }
} }
...@@ -79,7 +79,7 @@ def sync_source() { ...@@ -79,7 +79,7 @@ def sync_source() {
} else if (env.CHANGE_TARGET == '2.6') { } else if (env.CHANGE_TARGET == '2.6') {
sh ''' sh '''
cd ${WK} cd ${WK}
git checkout 2.6 git checkout -f 2.6
''' '''
} else { } else {
sh ''' sh '''
...@@ -194,47 +194,47 @@ def pre_test_win(){ ...@@ -194,47 +194,47 @@ def pre_test_win(){
if (env.CHANGE_TARGET == 'master') { if (env.CHANGE_TARGET == 'master') {
bat ''' bat '''
cd %WIN_INTERNAL_ROOT% cd %WIN_INTERNAL_ROOT%
git checkout master git checkout -f master
''' '''
bat ''' bat '''
cd %WIN_COMMUNITY_ROOT% cd %WIN_COMMUNITY_ROOT%
git checkout master git checkout -f master
''' '''
} else if (env.CHANGE_TARGET == '2.0') { } else if (env.CHANGE_TARGET == '2.0') {
bat ''' bat '''
cd %WIN_INTERNAL_ROOT% cd %WIN_INTERNAL_ROOT%
git checkout 2.0 git checkout -f 2.0
''' '''
bat ''' bat '''
cd %WIN_COMMUNITY_ROOT% cd %WIN_COMMUNITY_ROOT%
git checkout 2.0 git checkout -f 2.0
''' '''
} else if (env.CHANGE_TARGET == '2.4') { } else if (env.CHANGE_TARGET == '2.4') {
bat ''' bat '''
cd %WIN_INTERNAL_ROOT% cd %WIN_INTERNAL_ROOT%
git checkout 2.4 git checkout -f 2.4
''' '''
bat ''' bat '''
cd %WIN_COMMUNITY_ROOT% cd %WIN_COMMUNITY_ROOT%
git checkout 2.4 git checkout -f 2.4
''' '''
} else if (env.CHANGE_TARGET == '2.6') { } else if (env.CHANGE_TARGET == '2.6') {
bat ''' bat '''
cd %WIN_INTERNAL_ROOT% cd %WIN_INTERNAL_ROOT%
git checkout 2.6 git checkout -f 2.6
''' '''
bat ''' bat '''
cd %WIN_COMMUNITY_ROOT% cd %WIN_COMMUNITY_ROOT%
git checkout 2.6 git checkout -f 2.6
''' '''
} else { } else {
bat ''' bat '''
cd %WIN_INTERNAL_ROOT% cd %WIN_INTERNAL_ROOT%
git checkout develop git checkout -f develop
''' '''
bat ''' bat '''
cd %WIN_COMMUNITY_ROOT% cd %WIN_COMMUNITY_ROOT%
git checkout develop git checkout -f develop
''' '''
} }
} }
......
...@@ -20,20 +20,20 @@ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1]; ...@@ -20,20 +20,20 @@ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1];
3. The maximum length of database name is 33 bytes. 3. The maximum length of database name is 33 bytes.
4. The maximum length of a SQL statement is 65,480 bytes. 4. The maximum length of a SQL statement is 65,480 bytes.
5. Below are the parameters that can be used when creating a database 5. Below are the parameters that can be used when creating a database
- cache: [Description](/reference/config/#cache) - cache: [Description](../../reference/config/#cache)
- blocks: [Description](/reference/config/#blocks) - blocks: [Description](../../reference/config/#blocks)
- days: [Description](/reference/config/#days) - days: [Description](../../reference/config/#days)
- keep: [Description](/reference/config/#keep) - keep: [Description](../../reference/config/#keep)
- minRows: [Description](/reference/config/#minrows) - minRows: [Description](../../reference/config/#minrows)
- maxRows: [Description](/reference/config/#maxrows) - maxRows: [Description](../../reference/config/#maxrows)
- wal: [Description](/reference/config/#wallevel) - wal: [Description](../../reference/config/#wallevel)
- fsync: [Description](/reference/config/#fsync) - fsync: [Description](../../reference/config/#fsync)
- update: [Description](/reference/config/#update) - update: [Description](../../reference/config/#update)
- cacheLast: [Description](/reference/config/#cachelast) - cacheLast: [Description](../../reference/config/#cachelast)
- replica: [Description](/reference/config/#replica) - replica: [Description](../../reference/config/#replica)
- quorum: [Description](/reference/config/#quorum) - quorum: [Description](../../reference/config/#quorum)
- comp: [Description](/reference/config/#comp) - comp: [Description](../../reference/config/#comp)
- precision: [Description](/reference/config/#precision) - precision: [Description](../../reference/config/#precision)
6. Please note that all of the parameters mentioned in this section are configured in configuration file `taos.cfg` on the TDengine server. If not specified in the `create database` statement, the values from taos.cfg are used by default. To override default parameters, they must be specified in the `create database` statement. 6. Please note that all of the parameters mentioned in this section are configured in configuration file `taos.cfg` on the TDengine server. If not specified in the `create database` statement, the values from taos.cfg are used by default. To override default parameters, they must be specified in the `create database` statement.
::: :::
......
...@@ -191,7 +191,7 @@ Query OK, 1 row(s) in set (0.000921s) ...@@ -191,7 +191,7 @@ Query OK, 1 row(s) in set (0.000921s)
SELECT MODE(field_name) FROM tb_name [WHERE clause]; SELECT MODE(field_name) FROM tb_name [WHERE clause];
``` ```
**Description**:The value which has the highest frequency of occurrence. NULL is returned if there are multiple values which have highest frequency of occurrence. It can't be used on timestamp column or tags. **Description**:The value which has the highest frequency of occurrence. One random value is returned if there are multiple values which have highest frequency of occurrence. It can't be used on timestamp column or tags.
**Return value type**:Same as the data type of the column being operated upon **Return value type**:Same as the data type of the column being operated upon
......
...@@ -214,7 +214,7 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\) ...@@ -214,7 +214,7 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
The parameters listed in this section apply to all function modes. The parameters listed in this section apply to all function modes.
- **filetype** : The function to be tested, with optional values `insert`, `query` and `subscribe`. These correspond to the insert, query, and subscribe functions, respectively. Users can specify only one of these in each configuration file. - **filetype** : The function to be tested, with optional values `insert`, `query` and `subscribe`. These correspond to the insert, query, and subscribe functions, respectively. Users can specify only one of these in each configuration file.
**cfgdir**: specify the TDengine cluster configuration file's directory. The default path is /etc/taos. **cfgdir**: specify the TDengine client configuration file's directory. The default path is /etc/taos.
- **host**: Specify the FQDN of the TDengine server to connect. The default value is `localhost`. - **host**: Specify the FQDN of the TDengine server to connect. The default value is `localhost`.
...@@ -234,7 +234,7 @@ The parameters related to database creation are configured in `dbinfo` in the js ...@@ -234,7 +234,7 @@ The parameters related to database creation are configured in `dbinfo` in the js
- **name**: specify the name of the database. - **name**: specify the name of the database.
- **drop**: indicate whether to delete the database before inserting. The default is true. - **drop**: indicate whether to delete the database before inserting. The value can be 'yes' or 'no'. No means do not drop. The default is to drop.
- **replica**: specify the number of replicas when creating the database. - **replica**: specify the number of replicas when creating the database.
......
...@@ -20,20 +20,20 @@ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1]; ...@@ -20,20 +20,20 @@ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1];
3. 数据库名最大长度为 33; 3. 数据库名最大长度为 33;
4. 一条 SQL 语句的最大长度为 65480 个字符; 4. 一条 SQL 语句的最大长度为 65480 个字符;
5. 创建数据库时可用的参数有: 5. 创建数据库时可用的参数有:
- cache: [详细说明](/reference/config/#cache) - cache: [详细说明](../../reference/config/#cache)
- blocks: [详细说明](/reference/config/#blocks) - blocks: [详细说明](../../reference/config/#blocks)
- days: [详细说明](/reference/config/#days) - days: [详细说明](../../reference/config/#days)
- keep: [详细说明](/reference/config/#keep) - keep: [详细说明](../../reference/config/#keep)
- minRows: [详细说明](/reference/config/#minrows) - minRows: [详细说明](../../reference/config/#minrows)
- maxRows: [详细说明](/reference/config/#maxrows) - maxRows: [详细说明](../../reference/config/#maxrows)
- wal: [详细说明](/reference/config/#wallevel) - wal: [详细说明](../../reference/config/#wallevel)
- fsync: [详细说明](/reference/config/#fsync) - fsync: [详细说明](../../reference/config/#fsync)
- update: [详细说明](/reference/config/#update) - update: [详细说明](../../reference/config/#update)
- cacheLast: [详细说明](/reference/config/#cachelast) - cacheLast: [详细说明](../../reference/config/#cachelast)
- replica: [详细说明](/reference/config/#replica) - replica: [详细说明](../../reference/config/#replica)
- quorum: [详细说明](/reference/config/#quorum) - quorum: [详细说明](../../reference/config/#quorum)
- comp: [详细说明](/reference/config/#comp) - comp: [详细说明](../../reference/config/#comp)
- precision: [详细说明](/reference/config/#precision) - precision: [详细说明](../../reference/config/#precision)
6. 请注意上面列出的所有参数都可以配置在配置文件 `taosd.cfg` 中作为创建数据库时使用的默认配置, `create database` 的参数中明确指定的会覆盖配置文件中的设置。 6. 请注意上面列出的所有参数都可以配置在配置文件 `taosd.cfg` 中作为创建数据库时使用的默认配置, `create database` 的参数中明确指定的会覆盖配置文件中的设置。
::: :::
...@@ -86,7 +86,7 @@ REPLICA 参数是指修改数据库副本数,取值范围 [1, 3]。在集群 ...@@ -86,7 +86,7 @@ REPLICA 参数是指修改数据库副本数,取值范围 [1, 3]。在集群
ALTER DATABASE db_name KEEP 365; ALTER DATABASE db_name KEEP 365;
``` ```
KEEP 参数是指修改数据文件保存的天数,缺省值为 3650,取值范围 [days, 365000],必须大于或等于 days 参数值。 KEEP 参数是指修改数据文件保存的天数,缺省值为 3650,取值范围 [days, 36500],必须大于或等于 days 参数值。
``` ```
ALTER DATABASE db_name QUORUM 2; ALTER DATABASE db_name QUORUM 2;
......
...@@ -193,7 +193,7 @@ Query OK, 1 row(s) in set (0.000921s) ...@@ -193,7 +193,7 @@ Query OK, 1 row(s) in set (0.000921s)
SELECT MODE(field_name) FROM tb_name [WHERE clause]; SELECT MODE(field_name) FROM tb_name [WHERE clause];
``` ```
**功能说明**:返回出现频率最高的值,若存在多个频率相同的最高值,输出空。不能匹配标签、时间戳输出。 **功能说明**:返回出现频率最高的值,若存在多个频率相同的最高值,则随机输出其中某个值。不能匹配标签、时间戳输出。
**返回数据类型**:同应用的字段。 **返回数据类型**:同应用的字段。
......
...@@ -211,7 +211,7 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\) ...@@ -211,7 +211,7 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
本节所列参数适用于所有功能模式。 本节所列参数适用于所有功能模式。
- **filetype** : 要测试的功能,可选值为 `insert`, `query``subscribe`。分别对应插入、查询和订阅功能。每个配置文件中只能指定其中之一。 - **filetype** : 要测试的功能,可选值为 `insert`, `query``subscribe`。分别对应插入、查询和订阅功能。每个配置文件中只能指定其中之一。
- **cfgdir** : TDengine 集群配置文件所在的目录,默认路径是 /etc/taos 。 - **cfgdir** : TDengine 客户端配置文件所在的目录,默认路径是 /etc/taos 。
- **host** : 指定要连接的 TDengine 服务端的 FQDN,默认值为 localhost。 - **host** : 指定要连接的 TDengine 服务端的 FQDN,默认值为 localhost。
...@@ -231,7 +231,7 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\) ...@@ -231,7 +231,7 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
- **name** : 数据库名。 - **name** : 数据库名。
- **drop** : 插入前是否删除数据库,默认为 true - **drop** : 插入前是否删除数据库,可选项为 "yes" 或者 "no", 为 "no" 时不创建。默认删除
- **replica** : 创建数据库时指定的副本数。 - **replica** : 创建数据库时指定的副本数。
......
...@@ -279,7 +279,8 @@ void verify_schema_less(TAOS* taos) { ...@@ -279,7 +279,8 @@ void verify_schema_less(TAOS* taos) {
int code = 0, affected_rows = 0; int code = 0, affected_rows = 0;
char* lines[] = { char* lines[] = {
"st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", // test support \n \t \r
"st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"aaa\tbbb\nccc\\\\tddd\\\\neee\\nfff\\rggg\\thhh\",c2=false,c4=4f64 1626006833639000000",
"st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000", "st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000",
"ste,t2=5f64,t3=L\"ste\" c1=true,c2=4i64,c3=\"iam\" 1626056811823316532", "ste,t2=5f64,t3=L\"ste\" c1=true,c2=4i64,c3=\"iam\" 1626056811823316532",
"st,t1=4i64,t2=5f64,t3=\"t4\" c1=3i64,c3=L\"passitagain\",c2=true,c4=5f64 1626006833642000000", "st,t1=4i64,t2=5f64,t3=\"t4\" c1=3i64,c3=L\"passitagain\",c2=true,c4=5f64 1626006833642000000",
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# local fully qualified domain name (FQDN) # local fully qualified domain name (FQDN)
# fqdn hostname # fqdn hostname
# first port number for the connection (12 continuous UDP/TCP port number are used) # first port number for the connection (12 continuous UDP/TCP port number are used)
# serverPort 6030 # serverPort 6030
# log file's directory # log file's directory
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
# temporary file's directory # temporary file's directory
# tempDir /tmp/ # tempDir /tmp/
# the arbitrator's fully qualified domain name (FQDN) for TDengine system, for cluster only # the arbitrator's fully qualified domain name (FQDN) for TDengine system, for cluster only
# arbitrator arbitrator_hostname:6042 # arbitrator arbitrator_hostname:6042
# number of threads per CPU core # number of threads per CPU core
# numOfThreadsPerCore 1.0 # numOfThreadsPerCore 1.0
...@@ -60,19 +60,19 @@ keepColumnName 1 ...@@ -60,19 +60,19 @@ keepColumnName 1
# max timer control blocks # max timer control blocks
# maxTmrCtrl 512 # maxTmrCtrl 512
# time interval of system monitor, seconds # time interval of system monitor, seconds
# monitorInterval 30 # monitorInterval 30
# number of seconds allowed for a dnode to be offline, for cluster only # number of seconds allowed for a dnode to be offline, for cluster only
# offlineThreshold 864000 # offlineThreshold 864000
# RPC re-try timer, millisecond # RPC re-try timer, millisecond
# rpcTimer 300 # rpcTimer 300
# RPC maximum time for ack, seconds. # RPC maximum time for ack, seconds.
# rpcMaxTime 600 # rpcMaxTime 600
# time interval of dnode status reporting to mnode, seconds, for cluster only # time interval of dnode status reporting to mnode, seconds, for cluster only
# statusInterval 1 # statusInterval 1
# time interval of heart beat from shell to dnode, seconds # time interval of heart beat from shell to dnode, seconds
...@@ -121,7 +121,7 @@ keepColumnName 1 ...@@ -121,7 +121,7 @@ keepColumnName 1
# maxRows 4096 # maxRows 4096
# the number of acknowledgments required for successful data writing # the number of acknowledgments required for successful data writing
# quorum 1 # quorum 1
# enable/disable compression # enable/disable compression
# comp 2 # comp 2
...@@ -132,7 +132,7 @@ keepColumnName 1 ...@@ -132,7 +132,7 @@ keepColumnName 1
# if walLevel is set to 2, the cycle of fsync being executed, if set to 0, fsync is called right away # if walLevel is set to 2, the cycle of fsync being executed, if set to 0, fsync is called right away
# fsync 3000 # fsync 3000
# number of replications, for cluster only # number of replications, for cluster only
# replica 1 # replica 1
# the compressed rpc message, option: # the compressed rpc message, option:
...@@ -188,9 +188,12 @@ keepColumnName 1 ...@@ -188,9 +188,12 @@ keepColumnName 1
# enbale/disable http service # enbale/disable http service
# http 1 # http 1
# enable/disable system monitor # enable/disable system monitor
# monitor 1 # monitor 1
# enable/disable system audit
# audit 0
# enable/disable recording the SQL statements via restful interface # enable/disable recording the SQL statements via restful interface
# httpEnableRecordSql 0 # httpEnableRecordSql 0
...@@ -219,7 +222,7 @@ keepColumnName 1 ...@@ -219,7 +222,7 @@ keepColumnName 1
# The following parameters are used for debug purpose only. # The following parameters are used for debug purpose only.
# debugFlag 8 bits mask: FILE-SCREEN-UNUSED-HeartBeat-DUMP-TRACE_WARN-ERROR # debugFlag 8 bits mask: FILE-SCREEN-UNUSED-HeartBeat-DUMP-TRACE_WARN-ERROR
# 131: output warning and error # 131: output warning and error
# 135: output debug, warning and error # 135: output debug, warning and error
# 143: output trace, debug, warning and error to log # 143: output trace, debug, warning and error to log
# 199: output debug, warning and error to both screen and file # 199: output debug, warning and error to both screen and file
...@@ -243,13 +246,13 @@ keepColumnName 1 ...@@ -243,13 +246,13 @@ keepColumnName 1
# debug flag for SDB # debug flag for SDB
# sdbDebugFlag 135 # sdbDebugFlag 135
# debug flag for RPC # debug flag for RPC
# rpcDebugFlag 131 # rpcDebugFlag 131
# debug flag for TAOS TIMER # debug flag for TAOS TIMER
# tmrDebugFlag 131 # tmrDebugFlag 131
# debug flag for TDengine client # debug flag for TDengine client
# cDebugFlag 131 # cDebugFlag 131
# debug flag for JNI # debug flag for JNI
...@@ -302,7 +305,7 @@ keepColumnName 1 ...@@ -302,7 +305,7 @@ keepColumnName 1
# default string type used for storing JSON String, options can be binary/nchar, default is nchar # default string type used for storing JSON String, options can be binary/nchar, default is nchar
# defaultJSONStrType nchar # defaultJSONStrType nchar
# force TCP transmission # force TCP transmission
# rpcForceTcp 0 # rpcForceTcp 0
# unit MB. Flush vnode wal file if walSize > walFlushSize and walSize > cache*0.5*blocks # unit MB. Flush vnode wal file if walSize > walFlushSize and walSize > cache*0.5*blocks
...@@ -310,3 +313,12 @@ keepColumnName 1 ...@@ -310,3 +313,12 @@ keepColumnName 1
# unit Hour. Latency of data migration # unit Hour. Latency of data migration
# keepTimeOffset 0 # keepTimeOffset 0
# taosc write batch size, maximum 4096, suggested value 64 ~ 512, default 0, 0 means disable write batching.
# writeBatchSize 0
# taosc write batch timeout in milliseconds, maximum 2048, suggested value 2 ~ 100, default 10.
# writeBatchTimeout 10
# using thread local write batching. this option is not available when writeBatchSize = 0.
# writeBatchThreadLocal 0
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# Generate the deb package for ubuntu, or rpm package for centos, or tar.gz package for other linux os # Generate the deb package for ubuntu, or rpm package for centos, or tar.gz package for other linux os
set -e set -e
#set -x # set -x
# release.sh -v [cluster | edge] # release.sh -v [cluster | edge]
# -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] # -c [aarch32 | aarch64 | x64 | x86 | mips64 ...]
...@@ -263,7 +263,7 @@ if [ "$osType" != "Darwin" ]; then ...@@ -263,7 +263,7 @@ if [ "$osType" != "Darwin" ]; then
if [[ "$pagMode" == "full" ]]; then if [[ "$pagMode" == "full" ]]; then
if [ -d ${top_dir}/src/kit/taos-tools/packaging/deb ]; then if [ -d ${top_dir}/src/kit/taos-tools/packaging/deb ]; then
cd ${top_dir}/src/kit/taos-tools/packaging/deb cd ${top_dir}/src/kit/taos-tools/packaging/deb
taos_tools_ver=$(git describe --tags | sed -e 's/ver-//g' | awk -F '-' '{print $1}') taos_tools_ver=$(git tag |grep -v taos | sort | tail -1)
[ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0"
${csudo}./make-taos-tools-deb.sh ${top_dir} \ ${csudo}./make-taos-tools-deb.sh ${top_dir} \
...@@ -288,7 +288,7 @@ if [ "$osType" != "Darwin" ]; then ...@@ -288,7 +288,7 @@ if [ "$osType" != "Darwin" ]; then
if [[ "$pagMode" == "full" ]]; then if [[ "$pagMode" == "full" ]]; then
if [ -d ${top_dir}/src/kit/taos-tools/packaging/rpm ]; then if [ -d ${top_dir}/src/kit/taos-tools/packaging/rpm ]; then
cd ${top_dir}/src/kit/taos-tools/packaging/rpm cd ${top_dir}/src/kit/taos-tools/packaging/rpm
taos_tools_ver=$(git describe --tags | sed -e 's/ver-//g' | awk -F '-' '{print $1}' | sed -e 's/-/_/g') taos_tools_ver=$(git tag |grep -v taos | sort | tail -1)
[ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0"
${csudo}./make-taos-tools-rpm.sh ${top_dir} \ ${csudo}./make-taos-tools-rpm.sh ${top_dir} \
......
...@@ -105,6 +105,10 @@ elif echo $osinfo | grep -qwi "debian"; then ...@@ -105,6 +105,10 @@ elif echo $osinfo | grep -qwi "debian"; then
elif echo $osinfo | grep -qwi "Kylin"; then elif echo $osinfo | grep -qwi "Kylin"; then
# echo "This is Kylin system" # echo "This is Kylin system"
os_type=1 os_type=1
elif echo $osinfo | grep -qwi "KylinSec"; then
# echo "This is KylinSec system"
os_type=2
csudo=""
elif echo $osinfo | grep -qwi "Red"; then elif echo $osinfo | grep -qwi "Red"; then
# echo "This is Red Hat system" # echo "This is Red Hat system"
os_type=1 os_type=1
......
...@@ -47,7 +47,7 @@ if [ -d ${top_dir}/src/kit/taos-tools/packaging/deb ]; then ...@@ -47,7 +47,7 @@ if [ -d ${top_dir}/src/kit/taos-tools/packaging/deb ]; then
cd ${top_dir}/src/kit/taos-tools/packaging/deb cd ${top_dir}/src/kit/taos-tools/packaging/deb
[ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0"
taostools_ver=$(git describe --tags | sed -e 's/ver-//g' | awk -F '-' '{print $1}') taostools_ver=$(git tag |grep -v taos | sort | tail -1)
taostools_install_dir="${release_dir}/${clientName}Tools-${taostools_ver}" taostools_install_dir="${release_dir}/${clientName}Tools-${taostools_ver}"
cd ${curr_dir} cd ${curr_dir}
......
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_TSCBATCHMERGE_H
#define TDENGINE_TSCBATCHMERGE_H
#include "hash.h"
#include "taosmsg.h"
#include "tarray.h"
#include "tscUtil.h"
#include "tsclient.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* A builder of SSubmitBlk.
*/
typedef struct SSubmitBlkBuilder {
// the metadata of the SSubmitBlk.
SSubmitBlk* metadata;
// the array stores all the rows in a table, aka SArray<SMemRow>.
SArray* rows;
} SSubmitBlkBuilder;
/**
* The builder to build SSubmitMsg::blocks.
*/
typedef struct SSubmitMsgBlocksBuilder {
// SHashObj<table_uid, SSubmitBlkBuilder*>.
SHashObj* blockBuilders;
int64_t vgId;
} SSubmitMsgBlocksBuilder;
/**
* STableDataBlocksBuilder is a tool to build data blocks by append the existing data blocks in a vnode.
*/
typedef struct STableDataBlocksBuilder {
SSubmitMsgBlocksBuilder* blocksBuilder;
STableDataBlocks* firstBlock;
int64_t vgId;
} STableDataBlocksBuilder;
/**
* STableDataBlocksListBuilder is a tool to build vnode data blocks list by appending exist data blocks.
*/
typedef struct STableDataBlocksListBuilder {
SHashObj* dataBlocksBuilders;
} STableDataBlocksListBuilder;
/**
* A Builder to build SInsertStatementParam::pTableNameList.
*/
typedef struct STableNameListBuilder {
// store the unsorted table names, SArray<SName*>.
SArray* pTableNameList;
} STableNameListBuilder;
/**
* Create a SSubmitBlkBuilder using exist metadata.
*
* @param metadata the metadata.
* @return the SSubmitBlkBuilder.
*/
SSubmitBlkBuilder* createSSubmitBlkBuilder(SSubmitBlk* metadata);
/**
* Destroy the SSubmitBlkBuilder.
*
* @param builder the SSubmitBlkBuilder.
*/
void destroySSubmitBlkBuilder(SSubmitBlkBuilder* builder);
/**
* Append a SSubmitBlk* to the builder. The table uid in pBlock must be the same with the builder's.
*
* @param builder the SSubmitBlkBuilder.
* @param pBlock the pBlock to append.
* @return whether the append is success.
*/
bool appendSSubmitBlkBuilder(SSubmitBlkBuilder* builder, SSubmitBlk *pBlock);
/**
* Build and write SSubmitBlk to `target`
*
* @param builder the SSubmitBlkBuilder.
* @param target the target to write.
* @param nRows the number of rows in SSubmitBlk*.
* @return the writen bytes.
*/
size_t writeSSubmitBlkBuilder(SSubmitBlkBuilder* builder, SSubmitBlk* target, size_t* nRows);
/**
* Get the expected writen bytes of `writeSSubmitBlkBuilder`.
*
* @param builder the SSubmitBlkBuilder.
* @return the expected writen bytes of `writeSSubmitBlkBuilder`.
*/
size_t nWriteSSubmitBlkBuilder(SSubmitBlkBuilder* builder);
/**
* Create a SSubmitMsgBuilder.
*
* @param vgId the vgId of SSubmitMsg.
* @return the SSubmitMsgBuilder.
*/
SSubmitMsgBlocksBuilder* createSSubmitMsgBuilder(int64_t vgId);
/**
* Get the expected writen bytes of `writeSSubmitMsgBlocksBuilder`.
*
* @param builder the SSubmitMsgBlocksBuilder.
* @return the expected writen bytes of `writeSSubmitMsgBlocksBuilder`.
*/
size_t nWriteSSubmitMsgBuilder(SSubmitMsgBlocksBuilder* builder);
/**
* Build and write SSubmitMsg::blocks to `pBlocks`
*
* @param builder the SSubmitBlkBuilder.
* @param pBlocks the target to write.
* @param nRows the number of row in SSubmitMsg::blocks.
* @return the writen bytes.
*/
size_t writeSSubmitMsgBlocksBuilder(SSubmitMsgBlocksBuilder* builder, SSubmitBlk* pBlocks, size_t* nRows);
/**
* Get the number of block in SSubmitMsgBlocksBuilder.
* @param builder the SSubmitMsgBlocksBuilder.
* @return the number of SSubmitBlk block.
*/
size_t nBlockSSubmitMsgBlocksBuilder(SSubmitMsgBlocksBuilder* builder);
/**
* Destroy the SSubmitMsgBlocksBuilder.
*
* @param builder the SSubmitMsgBlocksBuilder to destroy.
*/
void destroySSubmitMsgBuilder(SSubmitMsgBlocksBuilder* builder);
/**
* Append SSubmitMsg* to the SSubmitMsgBlocksBuilder.
*
* @param builder the SSubmitMsgBlocksBuilder.
* @param pBlocks the SSubmitBlk in SSubmitMsg::blocks.
* @param nBlocks the number of blocks in SSubmitMsg.
* @return whether the append is success.
*/
bool appendSSubmitMsgBlocks(SSubmitMsgBlocksBuilder* builder, SSubmitBlk* pBlocks, size_t nBlocks);
/**
* Create the STableDataBlocksBuilder.
*
* @param vgId the vgId of STableDataBlocksBuilder.
* @return the STableDataBlocksBuilder.
*/
STableDataBlocksBuilder* createSTableDataBlocksBuilder(int64_t vgId);
/**
* Destroy the STableDataBlocksBuilder.
* @param builder the STableDataBlocksBuilder.
*/
void destroySTableDataBlocksBuilder(STableDataBlocksBuilder *builder);
/**
* Append a data blocks to STableDataBlocksBuilder.
* @param builder the STableDataBlocksBuilder.
* @param dataBlocks the dataBlocks to append. the vgId of dataBlocks must be same with the STableDataBlocksBuilder.
* @return whether the append is success.
*/
bool appendSTableDataBlocksBuilder(STableDataBlocksBuilder* builder, STableDataBlocks* dataBlocks);
/**
* Build the data blocks for single vnode.
* @param builder the STableDataBlocksBuilder.
* @param nRows the number of row in STableDataBlocks.
* @return the data blocks for single vnode.
*/
STableDataBlocks* buildSTableDataBlocksBuilder(STableDataBlocksBuilder* builder, size_t* nRows);
/**
* Create the STableDataBlocksListBuilder.
*
* @return the STableDataBlocksListBuilder.
*/
STableDataBlocksListBuilder* createSTableDataBlocksListBuilder();
/**
* Destroy the STableDataBlocksListBuilder.
*
* @param builder the STableDataBlocksListBuilder.
*/
void destroySTableDataBlocksListBuilder(STableDataBlocksListBuilder* builder);
/**
* Append a data blocks to STableDataBlocksListBuilder.
*
* @param builder the STableDataBlocksListBuilder.
* @param dataBlocks the data blocks.
* @return whether the append is success.
*/
bool appendSTableDataBlocksListBuilder(STableDataBlocksListBuilder* builder, STableDataBlocks* dataBlocks);
/**
* Build the vnode data blocks list.
*
* @param builder the STableDataBlocksListBuilder.
* @param nTables the number of table in vnode data blocks list.
* @param nRows the number of row in vnode data blocks list.
* @return the vnode data blocks list.
*/
SArray* buildSTableDataBlocksListBuilder(STableDataBlocksListBuilder* builder, size_t* nTables, size_t* nRows);
/**
* Create STableNameListBuilder.
*/
STableNameListBuilder* createSTableNameListBuilder();
/**
* Destroy the STableNameListBuilder.
* @param builder the STableNameListBuilder.
*/
void destroySTableNameListBuilder(STableNameListBuilder* builder);
/**
* Insert a SName to builder.
*
* @param builder the STableNameListBuilder.
* @param name the table name.
* @return whether it is success.
*/
bool insertSTableNameListBuilder(STableNameListBuilder* builder, SName* name);
/**
* Build the STable name list.
*
* @param builder the STableNameListBuilder.
* @param numOfTables the number of table.
* @return the STable name list.
*/
SName** buildSTableNameListBuilder(STableNameListBuilder* builder, size_t* numOfTables);
/**
* Merge the KV-PayLoad SQL objects into single one.
* The statements here must be an insertion statement and no schema attached.
*
* @param polls the array of SSqlObj*.
* @param nPolls the number of SSqlObj* in the array.
* @param result the returned result. result is not null!
* @return the status code.
*/
int32_t tscMergeSSqlObjs(SSqlObj** polls, size_t nPolls, SSqlObj *result);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_TSCBATCHMERGE_H
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_TSCBATCHWRITE_H
#define TDENGINE_TSCBATCHWRITE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "tthread.h"
// forward declaration.
typedef struct STscObj STscObj;
typedef struct SSqlObj SSqlObj;
typedef struct SDispatcherTimeoutManager SDispatcherTimeoutManager;
/**
* SAsyncBatchWriteDispatcher is an async batching write dispatcher (ABWD). ABWD accepts the recent SQL requests and put
* them in a queue waiting to be scheduled. When the number of requests in the queue reaches batch_size, it merges the
* requests in the queue and sends them to the server, thus reducing the network overhead caused by multiple
* communications to the server and directly improving the throughput of small object asynchronous writes.
*/
typedef struct SAsyncBatchWriteDispatcher {
// the client object.
STscObj* pClient;
// the timeout manager.
SDispatcherTimeoutManager* timeoutManager;
// the mutex to protect the dispatcher.
pthread_mutex_t bufferMutex;
// the cond to signal when buffer not full.
pthread_cond_t notFull;
// the maximum number of insertion rows in a batch.
int32_t batchSize;
// the number of insertion rows in the buffer.
int32_t currentSize;
// the number of items in the buffer.
int32_t bufferSize;
// whether the dispatcher is shutdown.
bool shutdown;
SSqlObj* buffer[];
} SAsyncBatchWriteDispatcher;
/**
* The manager of SAsyncBatchWriteDispatcher. Call dispatcherAcquire(...) to get the SAsyncBatchWriteDispatcher
* instance. SDispatcherManager will manage the life cycle of SAsyncBatchWriteDispatcher.
*/
typedef struct SDispatcherManager {
pthread_key_t key;
// the maximum number of insertion rows in a batch.
int32_t batchSize;
// the batching timeout in milliseconds.
int32_t timeoutMs;
// specifies whether the dispatcher is thread local, if the dispatcher is not
// thread local, we will use the global dispatcher below.
bool isThreadLocal;
// the global dispatcher, if thread local enabled, global will be set to NULL.
SAsyncBatchWriteDispatcher* pGlobal;
// the client object.
STscObj* pClient;
} SDispatcherManager;
/**
* Control the timeout of the dispatcher queue.
*/
typedef struct SDispatcherTimeoutManager {
// the dispatcher that timeout manager belongs to.
SAsyncBatchWriteDispatcher* dispatcher;
// the background thread.
pthread_t background;
// the mutex to sleep the background thread.
pthread_mutex_t sleepMutex;
// the cond to signal to background thread.
pthread_cond_t timeout;
// the batching timeout in milliseconds.
int32_t timeoutMs;
// whether the timeout manager is shutdown.
bool shutdown;
} SDispatcherTimeoutManager;
/**
* A batch that polls from SAsyncBatchWriteDispatcher::buffer.
*/
typedef struct SBatchRequest {
size_t nRequests;
SSqlObj* pRequests[];
} SBatchRequest;
/**
* Create the dispatcher timeout manager.
*/
SDispatcherTimeoutManager* createSDispatcherTimeoutManager(SAsyncBatchWriteDispatcher* dispatcher, int32_t timeoutMs);
/**
* Destroy the dispatcher timeout manager.
*/
void destroySDispatcherTimeoutManager(SDispatcherTimeoutManager* manager);
/**
* Check if the timeout manager is shutdown.
* @param manager the timeout manager.
* @return whether the timeout manager is shutdown.
*/
bool isShutdownSDispatcherTimeoutManager(SDispatcherTimeoutManager* manager);
/**
* Shutdown the SDispatcherTimeoutManager.
* @param manager the SDispatcherTimeoutManager.
*/
void shutdownSDispatcherTimeoutManager(SDispatcherTimeoutManager* manager);
/**
* Merge SSqlObjs into single SSqlObj.
*
* @param pRequest the batch request.
* @param batch the batch SSqlObj*.
* @return the status code.
*/
int32_t dispatcherBatchBuilder(SBatchRequest* pRequest, SSqlObj** batch);
/**
* Merge the sql statements and execute the merged sql statement asynchronously.
*
* @param pRequest the batch request. the request will be promised to free after calling this function.
*/
void dispatcherAsyncExecute(SBatchRequest* pRequest);
/**
* Merge the sql statements and execute the merged sql statement.
*
* @param pRequest the batch request. you must call free(pRequest) after calling this function.
*/
void dispatcherExecute(SBatchRequest* pRequest);
/**
* Create the async batch write dispatcher.
*
* @param pClient the client object.
* @param batchSize When user submit an insert sql to `taos_query_a`, the SSqlObj* will be buffered instead of executing
* it. If the number of the buffered rows reach `batchSize`, all the SSqlObj* will be merged and sent to vnodes.
* @param timeout The SSqlObj* will be sent to vnodes no more than `timeout` milliseconds. But the actual time
* vnodes received the SSqlObj* depends on the network quality.
*/
SAsyncBatchWriteDispatcher* createSAsyncBatchWriteDispatcher(STscObj* pClient, int32_t batchSize, int32_t timeoutMs);
/**
* Destroy the async auto batch dispatcher.
*/
void destroySAsyncBatchWriteDispatcher(SAsyncBatchWriteDispatcher* dispatcher);
/**
* Check if the current sql object can be dispatch by ABWD.
* 1. auto batch feature on the sql object must be enabled.
* 2. must be an `insert into ... value ...` statement.
* 3. the payload type must be kv payload.
* 4. no schema attached.
*
* @param dispatcher the dispatcher.
* @param pSql the sql object to check.
* @return returns true if the sql object can be dispatch by ABWD.
*/
bool dispatcherCanDispatch(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql);
/**
* Try to offer the SSqlObj* to the dispatcher. If the number of row reach `batchSize`, the function
* will merge the SSqlObj* in the buffer and send them to the vnodes.
*
* @param pSql the insert statement to offer.
* @return if offer success, returns true.
*/
bool dispatcherTryDispatch(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql);
/**
* Create the manager of SAsyncBatchWriteDispatcher.
*
* @param pClient the client object.
* @param batchSize the batchSize of SAsyncBatchWriteDispatcher.
* @param timeoutMs the timeoutMs of SAsyncBatchWriteDispatcher.
* @param isThreadLocal specifies whether the dispatcher is thread local.
* @return the SAsyncBatchWriteDispatcher manager.
*/
SDispatcherManager* createDispatcherManager(STscObj* pClient, int32_t batchSize, int32_t timeoutMs, bool isThreadLocal);
/**
* Destroy the SDispatcherManager.
* (will destroy all the instances of SAsyncBatchWriteDispatcher in the thread local variable)
*
* @param manager the SDispatcherManager.
*/
void destroyDispatcherManager(SDispatcherManager* manager);
/**
* Get an instance of SAsyncBatchWriteDispatcher.
*
* @param manager the SDispatcherManager.
* @return the SAsyncBatchWriteDispatcher instance.
*/
SAsyncBatchWriteDispatcher* dispatcherAcquire(SDispatcherManager* manager);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_TSCBATCHWRITE_H
...@@ -144,6 +144,8 @@ void doRetrieveSubqueryData(SSchedMsg *pMsg); ...@@ -144,6 +144,8 @@ void doRetrieveSubqueryData(SSchedMsg *pMsg);
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, uint16_t bytes, SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, uint16_t bytes,
uint32_t offset); uint32_t offset);
void destroySTableDataBlocksList(SArray* pDataBlocks);
void destroySTableDataBlocks(STableDataBlocks* pDataBlocks);
void* tscDestroyBlockArrayList(SSqlObj* pSql, SArray* pDataBlockList); void* tscDestroyBlockArrayList(SSqlObj* pSql, SArray* pDataBlockList);
void* tscDestroyUdfArrayList(SArray* pUdfList); void* tscDestroyUdfArrayList(SArray* pUdfList);
void* tscDestroyBlockHashTable(SSqlObj* pSql, SHashObj* pBlockHashTable, bool removeMeta); void* tscDestroyBlockHashTable(SSqlObj* pSql, SHashObj* pBlockHashTable, bool removeMeta);
......
...@@ -45,6 +45,7 @@ typedef enum { ...@@ -45,6 +45,7 @@ typedef enum {
// forward declaration // forward declaration
struct SSqlInfo; struct SSqlInfo;
typedef struct SDispatcherManager SDispatcherManager;
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows); typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows);
typedef void (*_freeSqlSupporter)(void **); typedef void (*_freeSqlSupporter)(void **);
...@@ -256,7 +257,7 @@ typedef struct SInsertStatementParam { ...@@ -256,7 +257,7 @@ typedef struct SInsertStatementParam {
int32_t batchSize; // for parameter ('?') binding and batch processing int32_t batchSize; // for parameter ('?') binding and batch processing
int32_t numOfParams; int32_t numOfParams;
int32_t numOfRows;
int32_t numOfFiles; int32_t numOfFiles;
char msg[512]; // error message char msg[512]; // error message
...@@ -352,7 +353,8 @@ typedef struct STscObj { ...@@ -352,7 +353,8 @@ typedef struct STscObj {
SRpcCorEpSet *tscCorMgmtEpSet; SRpcCorEpSet *tscCorMgmtEpSet;
pthread_mutex_t mutex; pthread_mutex_t mutex;
int32_t numOfObj; // number of sqlObj from this tscObj int32_t numOfObj; // number of sqlObj from this tscObj
SDispatcherManager*dispatcherManager;
SReqOrigin from; SReqOrigin from;
} STscObj; } STscObj;
...@@ -400,9 +402,10 @@ typedef struct SSqlObj { ...@@ -400,9 +402,10 @@ typedef struct SSqlObj {
struct SSqlObj *prev, *next; struct SSqlObj *prev, *next;
int64_t self; int64_t self;
// connect alive
int64_t lastAlive; int64_t lastAlive;
void * pPrevContext; void * pPrevContext;
bool enableBatch;
} SSqlObj; } SSqlObj;
typedef struct SSqlStream { typedef struct SSqlStream {
...@@ -503,7 +506,7 @@ void tscCloseTscObj(void *pObj); ...@@ -503,7 +506,7 @@ void tscCloseTscObj(void *pObj);
TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int), TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int),
void *param, TAOS **taos); void *param, TAOS **taos);
TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, int64_t* res); TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, int64_t* res);
TAOS_RES * taos_query_ra(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param); TAOS_RES * taos_query_ra(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param, bool enableBatch);
// get taos connection unused session number // get taos connection unused session number
int32_t taos_unused_session(TAOS* taos); int32_t taos_unused_session(TAOS* taos);
......
...@@ -13,16 +13,19 @@ ...@@ -13,16 +13,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "os.h" #include "os.h"
#include "osAtomic.h"
#include "tarray.h"
#include "tutil.h" #include "tutil.h"
#include "qTableMeta.h"
#include "tnote.h" #include "tnote.h"
#include "trpc.h" #include "trpc.h"
#include "tscBatchWrite.h"
#include "tscLog.h" #include "tscLog.h"
#include "tscSubquery.h" #include "tscSubquery.h"
#include "tscUtil.h" #include "tscUtil.h"
#include "tsched.h"
#include "qTableMeta.h"
#include "tsclient.h" #include "tsclient.h"
static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOfRows); static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
...@@ -334,6 +337,26 @@ bool appendTagsFilter(SSqlObj* pSql) { ...@@ -334,6 +337,26 @@ bool appendTagsFilter(SSqlObj* pSql) {
return false; return false;
} }
// check tags is blank or ''
char* p1 = pTscObj->tags;
if (strcmp(p1, "\'\'") == 0) {
tscDebug("TAGS 0x%" PRIx64 " tags is empty. user=%s", pSql->self, pTscObj->user);
return false;
}
bool blank = true;
while(*p1 != 0) {
if(*p1 != ' ') {
blank = false;
break;
}
++p1;
}
// result
if(blank) {
tscDebug("TAGS 0x%" PRIx64 " tags is all blank. user=%s", pSql->self, pTscObj->user);
return false;
}
char * p = insertTags(pSql->sqlstr, pTscObj->tags); char * p = insertTags(pSql->sqlstr, pTscObj->tags);
if(p == NULL) { if(p == NULL) {
return false; return false;
...@@ -378,7 +401,6 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para ...@@ -378,7 +401,6 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
pCmd->resColumnId = TSDB_RES_COL_ID; pCmd->resColumnId = TSDB_RES_COL_ID;
taosAcquireRef(tscObjRef, pSql->self); taosAcquireRef(tscObjRef, pSql->self);
int32_t code = tsParseSql(pSql, true); int32_t code = tsParseSql(pSql, true);
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
...@@ -392,18 +414,27 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para ...@@ -392,18 +414,27 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
taosReleaseRef(tscObjRef, pSql->self); taosReleaseRef(tscObjRef, pSql->self);
return; return;
} }
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); if (pObj->dispatcherManager != NULL) {
SAsyncBatchWriteDispatcher * dispatcher = dispatcherAcquire(pObj->dispatcherManager);
if (dispatcherTryDispatch(dispatcher, pSql)) {
taosReleaseRef(tscObjRef, pSql->self);
tscDebug("sql obj %p has been buffer in insert buffer", pSql);
return;
}
}
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
executeQuery(pSql, pQueryInfo); executeQuery(pSql, pQueryInfo);
taosReleaseRef(tscObjRef, pSql->self); taosReleaseRef(tscObjRef, pSql->self);
} }
// TODO return the correct error code to client in tscQueueAsyncError // TODO return the correct error code to client in tscQueueAsyncError
void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param) { void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param) {
taos_query_ra(taos, sqlstr, fp, param); taos_query_ra(taos, sqlstr, fp, param, tsWriteBatchSize > 0);
} }
TAOS_RES * taos_query_ra(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param) { TAOS_RES * taos_query_ra(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param, bool enableBatch) {
STscObj *pObj = (STscObj *)taos; STscObj *pObj = (STscObj *)taos;
if (pObj == NULL || pObj->signature != pObj) { if (pObj == NULL || pObj->signature != pObj) {
tscError("pObj:%p is NULL or freed", pObj); tscError("pObj:%p is NULL or freed", pObj);
...@@ -429,6 +460,8 @@ TAOS_RES * taos_query_ra(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, v ...@@ -429,6 +460,8 @@ TAOS_RES * taos_query_ra(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, v
return NULL; return NULL;
} }
pSql->enableBatch = enableBatch;
doAsyncQuery(pObj, pSql, fp, param, sqlstr, sqlLen); doAsyncQuery(pObj, pSql, fp, param, sqlstr, sqlLen);
return pSql; return pSql;
......
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tscBatchMerge.h"
/**
* A util function to compare two SName.
*/
static int32_t compareSName(const void *left, const void *right) {
if (left == right) {
return 0;
}
SName* x = *(SName** ) left;
SName* y = *(SName** ) right;
return memcmp(x, y, sizeof(SName));
}
/**
* A util function to sort SArray<SMemRow> by key.
*/
static int32_t compareSMemRow(const void *x, const void *y) {
TSKEY left = memRowKey(*(void **) x);
TSKEY right = memRowKey(*(void **) y);
if (left == right) {
return 0;
} else {
return left > right ? 1 : -1;
}
}
/**
* If the SSubmitBlkBuilder of pBlock->uid is present, returns it. Otherwise, build a new SSubmitBlkBuilder.
*
* @param builder the SSubmitMsgBlocksBuilder.
* @param pBlock the SSubmitBlk.
* @return the SSubmitBlkBuilder (NULL means failure).
*/
inline static SSubmitBlkBuilder* computeIfAbsentSSubmitBlkBuilder(SSubmitMsgBlocksBuilder* builder, SSubmitBlk* pBlock) {
SSubmitBlkBuilder** iter = taosHashGet(builder->blockBuilders, &pBlock->uid, sizeof(pBlock->uid));
SSubmitBlkBuilder* blocksBuilder = NULL;
if (iter) {
return *iter;
}
blocksBuilder = createSSubmitBlkBuilder(pBlock);
if (!blocksBuilder) {
return NULL;
}
if (taosHashPut(builder->blockBuilders, &pBlock->uid, sizeof(pBlock->uid), &blocksBuilder, sizeof(SArray*))) {
destroySSubmitBlkBuilder(blocksBuilder);
return NULL;
}
return blocksBuilder;
}
SName** buildSTableNameListBuilder(STableNameListBuilder* builder, size_t* nTables) {
if (!taosArrayGetSize(builder->pTableNameList)) {
*nTables = 0;
return NULL;
}
// sort and unique.
taosArraySort(builder->pTableNameList, compareSName);
size_t tail = 0;
size_t nNames = taosArrayGetSize(builder->pTableNameList);
for (size_t i = 1; i < nNames; ++i) {
SName* last = taosArrayGetP(builder->pTableNameList, tail);
SName* current = taosArrayGetP(builder->pTableNameList, i);
if (memcmp(last, current, sizeof(SName)) != 0) {
++tail;
taosArraySet(builder->pTableNameList, tail, &current);
}
}
// build table names list.
SName** tableNames = calloc(tail + 1, sizeof(SName*));
if (!tableNames) {
return NULL;
}
// clone data.
for (size_t i = 0; i <= tail; ++i) {
SName* clone = malloc(sizeof(SName));
if (!clone) {
goto error;
}
memcpy(clone, taosArrayGetP(builder->pTableNameList, i), sizeof(SName));
tableNames[i] = clone;
}
*nTables = tail + 1;
return tableNames;
error:
for (size_t i = 0; i <= tail; ++i) {
if (tableNames[i]) {
free(tableNames[i]);
}
}
free(tableNames);
return NULL;
}
SSubmitBlkBuilder* createSSubmitBlkBuilder(SSubmitBlk* metadata) {
SSubmitBlkBuilder* builder = calloc(1, sizeof(SSubmitBlkBuilder));
if (!builder) {
return NULL;
}
builder->rows = taosArrayInit(1, sizeof(SMemRow));
if (!builder->rows) {
free(builder);
return NULL;
}
builder->metadata = calloc(1, sizeof(SSubmitBlk));
if (!builder->metadata) {
taosArrayDestroy(&builder->rows);
free(builder);
return NULL;
}
memcpy(builder->metadata, metadata, sizeof(SSubmitBlk));
return builder;
}
void destroySSubmitBlkBuilder(SSubmitBlkBuilder* builder) {
if (!builder) {
return;
}
taosArrayDestroy(&builder->rows);
free(builder->metadata);
free(builder);
}
bool appendSSubmitBlkBuilder(SSubmitBlkBuilder* builder, SSubmitBlk* pBlock) {
assert(pBlock->uid == builder->metadata->uid);
assert(pBlock->schemaLen == 0);
// shadow copy all the SMemRow to SSubmitBlkBuilder::rows.
char* pRow = pBlock->data;
char* pEnd = pBlock->data + htonl(pBlock->dataLen);
while (pRow < pEnd) {
if (!taosArrayPush(builder->rows, &pRow)) {
return false;
}
pRow += memRowTLen(pRow);
}
return true;
}
size_t writeSSubmitBlkBuilder(SSubmitBlkBuilder* builder, SSubmitBlk* target, size_t* nRows) {
memcpy(target, builder->metadata, sizeof(SSubmitBlk));
// sort SSubmitBlkBuilder::rows by timestamp.
uint32_t dataLen = 0;
taosArraySort(builder->rows, compareSMemRow);
// deep copy all the SMemRow to target.
size_t nMemRows = taosArrayGetSize(builder->rows);
for (int i = 0; i < nMemRows; ++i) {
char* pRow = taosArrayGetP(builder->rows, i);
memcpy(POINTER_SHIFT(target->data, dataLen), pRow, memRowTLen(pRow));
dataLen += memRowTLen(pRow);
}
*nRows = nMemRows;
target->schemaLen = 0;
target->dataLen = (int32_t) htonl(dataLen);
target->numOfRows = (int16_t) htons(*nRows);
return dataLen + sizeof(SSubmitBlk);
}
size_t nWriteSSubmitBlkBuilder(SSubmitBlkBuilder* builder) {
size_t dataLen = 0;
size_t nRows = taosArrayGetSize(builder->rows);
for (int i = 0; i < nRows; ++i) {
char* pRow = taosArrayGetP(builder->rows, i);
dataLen += memRowTLen(pRow);
}
return dataLen + sizeof(SSubmitBlk);
}
SSubmitMsgBlocksBuilder* createSSubmitMsgBuilder(int64_t vgId) {
SSubmitMsgBlocksBuilder* builder = calloc(1, sizeof(SSubmitMsgBlocksBuilder));
if (!builder) {
return NULL;
}
builder->vgId = vgId;
builder->blockBuilders = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
if (!builder->blockBuilders) {
free(builder);
return NULL;
}
return builder;
}
size_t nWriteSSubmitMsgBuilder(SSubmitMsgBlocksBuilder* builder) {
size_t nWrite = 0;
SSubmitBlkBuilder** iter = taosHashIterate(builder->blockBuilders, NULL);
while (iter) {
SSubmitBlkBuilder* blocksBuilder = *iter;
nWrite += nWriteSSubmitBlkBuilder(blocksBuilder);
iter = taosHashIterate(builder->blockBuilders, iter);
}
return nWrite;
}
size_t writeSSubmitMsgBlocksBuilder(SSubmitMsgBlocksBuilder* builder, SSubmitBlk* pBlocks, size_t* nRows) {
size_t nWrite = 0;
SSubmitBlkBuilder** iter = taosHashIterate(builder->blockBuilders, NULL);
// copy all the SSubmitBlk to pBlocks.
while (iter) {
size_t nSubRows = 0;
SSubmitBlkBuilder* blocksBuilder = *iter;
SSubmitBlk* pBlock = POINTER_SHIFT(pBlocks, nWrite);
nWrite += writeSSubmitBlkBuilder(blocksBuilder, pBlock, &nSubRows);
*nRows += nSubRows;
iter = taosHashIterate(builder->blockBuilders, iter);
}
return nWrite;
}
size_t nBlockSSubmitMsgBlocksBuilder(SSubmitMsgBlocksBuilder* builder) {
return taosHashGetSize(builder->blockBuilders);
}
void destroySSubmitMsgBuilder(SSubmitMsgBlocksBuilder* builder) {
if (!builder) {
return;
}
SSubmitBlkBuilder** iter = taosHashIterate(builder->blockBuilders, NULL);
while (iter) {
destroySSubmitBlkBuilder(*iter);
iter = taosHashIterate(builder->blockBuilders, iter);
}
taosHashCleanup(builder->blockBuilders);
free(builder);
}
bool appendSSubmitMsgBlocks(SSubmitMsgBlocksBuilder* builder, SSubmitBlk* pBlocks, size_t nBlocks) {
SSubmitBlk* pBlock = pBlocks;
for (size_t i = 0; i < nBlocks; ++i) {
// not support SSubmitBlk with schema.
assert(pBlock->schemaLen == 0);
// get the builder of specific table (by pBlock->uid).
SSubmitBlkBuilder* blocksBuilder = computeIfAbsentSSubmitBlkBuilder(builder, pBlock);
if (!blocksBuilder) {
return false;
}
if (!appendSSubmitBlkBuilder(blocksBuilder, pBlock)) {
return false;
}
// go to next block.
size_t blockSize = sizeof (SSubmitBlk) + htonl(pBlock->dataLen);
pBlock = POINTER_SHIFT(pBlock, blockSize);
}
return true;
}
STableDataBlocksBuilder* createSTableDataBlocksBuilder(int64_t vgId) {
STableDataBlocksBuilder* builder = calloc(1, sizeof(STableDataBlocksBuilder));
if (!builder) {
return NULL;
}
builder->blocksBuilder = createSSubmitMsgBuilder(vgId);
if (!builder->blocksBuilder) {
free(builder);
return NULL;
}
builder->vgId = vgId;
builder->firstBlock = NULL;
return builder;
}
void destroySTableDataBlocksBuilder(STableDataBlocksBuilder* builder) {
if (!builder) {
return;
}
destroySSubmitMsgBuilder(builder->blocksBuilder);
free(builder);
}
bool appendSTableDataBlocksBuilder(STableDataBlocksBuilder* builder, STableDataBlocks* dataBlocks) {
// the data blocks vgId must be same with builder vgId.
if (!dataBlocks || dataBlocks->vgId != builder->vgId) {
return false;
}
if (!builder->firstBlock) {
builder->firstBlock = dataBlocks;
}
SSubmitBlk* pBlocks = (SSubmitBlk *)(dataBlocks->pData + dataBlocks->headerSize);
return appendSSubmitMsgBlocks(builder->blocksBuilder, pBlocks, dataBlocks->numOfTables);
}
STableDataBlocks* buildSTableDataBlocksBuilder(STableDataBlocksBuilder* builder, size_t* nRows) {
SSubmitMsgBlocksBuilder* blocksBuilder = builder->blocksBuilder;
STableDataBlocks *firstBlock = builder->firstBlock;
if (!firstBlock) {
return NULL;
}
size_t nWriteSize = nWriteSSubmitMsgBuilder(builder->blocksBuilder);
size_t nHeaderSize = firstBlock->headerSize;
size_t nAllocSize = nWriteSize + nHeaderSize;
// allocate data blocks.
STableDataBlocks* dataBlocks = NULL;
int32_t code = tscCreateDataBlock(nAllocSize, 0, (int32_t) nHeaderSize, &firstBlock->tableName, firstBlock->pTableMeta, &dataBlocks);
if (code != TSDB_CODE_SUCCESS) {
return NULL;
}
// build the header (using first block).
dataBlocks->size = nHeaderSize;
memcpy(dataBlocks->pData, firstBlock->pData, nHeaderSize);
// build the SSubmitMsg::blocks.
dataBlocks->size += writeSSubmitMsgBlocksBuilder(blocksBuilder, (SSubmitBlk *) (dataBlocks->pData + nHeaderSize), nRows);
dataBlocks->numOfTables = (int32_t) nBlockSSubmitMsgBlocksBuilder(blocksBuilder);
return dataBlocks;
}
STableDataBlocksListBuilder* createSTableDataBlocksListBuilder() {
STableDataBlocksListBuilder* builder = calloc(1, sizeof(STableDataBlocksListBuilder));
if (!builder) {
return NULL;
}
builder->dataBlocksBuilders = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
if (!builder->dataBlocksBuilders) {
free(builder);
return NULL;
}
return builder;
}
void destroySTableDataBlocksListBuilder(STableDataBlocksListBuilder* builder) {
if (!builder) {
return;
}
STableDataBlocksBuilder** iter = taosHashIterate(builder->dataBlocksBuilders, NULL);
while (iter) {
destroySTableDataBlocksBuilder(*iter);
iter = taosHashIterate(builder->dataBlocksBuilders, iter);
}
taosHashCleanup(builder->dataBlocksBuilders);
free(builder);
}
bool appendSTableDataBlocksListBuilder(STableDataBlocksListBuilder* builder, STableDataBlocks* dataBlocks) {
// get the data blocks builder of specific vgId.
STableDataBlocksBuilder** item = taosHashGet(builder->dataBlocksBuilders, &dataBlocks->vgId, sizeof(dataBlocks->vgId));
STableDataBlocksBuilder* blocksBuilder = NULL;
if (item) {
blocksBuilder = *item;
} else {
blocksBuilder = createSTableDataBlocksBuilder(dataBlocks->vgId);
if (!blocksBuilder) {
return false;
}
if (taosHashPut(builder->dataBlocksBuilders, &dataBlocks->vgId, sizeof(dataBlocks->vgId), &blocksBuilder, sizeof(STableDataBlocksBuilder*))) {
destroySTableDataBlocksBuilder(blocksBuilder);
return false;
}
}
// append to this builder.
return appendSTableDataBlocksBuilder(blocksBuilder, dataBlocks);
}
SArray* buildSTableDataBlocksListBuilder(STableDataBlocksListBuilder* builder, size_t* nTables, size_t* nRows) {
SArray* pVnodeDataBlockList = taosArrayInit(taosHashGetSize(builder->dataBlocksBuilders), sizeof(STableDataBlocks*));
if (!pVnodeDataBlockList) {
return NULL;
}
// build data blocks of each vgId.
STableDataBlocksBuilder** iter = taosHashIterate(builder->dataBlocksBuilders, NULL);
while (iter) {
size_t nSubRows = 0;
STableDataBlocksBuilder* dataBlocksBuilder = *iter;
STableDataBlocks* dataBlocks = buildSTableDataBlocksBuilder(dataBlocksBuilder, &nSubRows);
if (!dataBlocks) {
goto error;
}
*nTables += dataBlocks->numOfTables;
*nRows += nSubRows;
taosArrayPush(pVnodeDataBlockList, &dataBlocks);
iter = taosHashIterate(builder->dataBlocksBuilders, iter);
}
return pVnodeDataBlockList;
error:
for (int i = 0; i < taosArrayGetSize(pVnodeDataBlockList); ++i) {
STableDataBlocks* dataBlocks = taosArrayGetP(pVnodeDataBlockList, i);
tscDestroyDataBlock(NULL, dataBlocks, false);
}
taosArrayDestroy(&pVnodeDataBlockList);
return NULL;
}
STableNameListBuilder* createSTableNameListBuilder() {
STableNameListBuilder* builder = calloc(1, sizeof(STableNameListBuilder));
if (!builder) {
return NULL;
}
builder->pTableNameList = taosArrayInit(1, sizeof(SName*));
if (!builder->pTableNameList) {
free(builder);
return NULL;
}
return builder;
}
void destroySTableNameListBuilder(STableNameListBuilder* builder) {
if (!builder) {
return;
}
taosArrayDestroy(&builder->pTableNameList);
free(builder);
}
bool insertSTableNameListBuilder(STableNameListBuilder* builder, SName* name) {
return taosArrayPush(builder->pTableNameList, &name);
}
int32_t tscMergeSSqlObjs(SSqlObj** polls, size_t nPolls, SSqlObj* result) {
// statement array is empty.
if (!polls || !nPolls) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
STableDataBlocksListBuilder* builder = createSTableDataBlocksListBuilder();
if (!builder) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
STableNameListBuilder* nameListBuilder = createSTableNameListBuilder();
if (!nameListBuilder) {
destroySTableDataBlocksListBuilder(builder);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
// append the existing data blocks to builder.
for (size_t i = 0; i < nPolls; ++i) {
SSqlObj *pSql = polls[i];
SInsertStatementParam* pInsertParam = &pSql->cmd.insertParam;
if (!pInsertParam->pDataBlocks) {
continue;
}
assert(pInsertParam->payloadType == PAYLOAD_TYPE_KV);
assert(!pInsertParam->schemaAttached);
// append each vnode data block to the builder.
size_t nBlocks = taosArrayGetSize(pInsertParam->pDataBlocks);
for (size_t j = 0; j < nBlocks; ++j) {
STableDataBlocks* tableBlock = taosArrayGetP(pInsertParam->pDataBlocks, j);
if (!appendSTableDataBlocksListBuilder(builder, tableBlock)) {
destroySTableDataBlocksListBuilder(builder);
destroySTableNameListBuilder(nameListBuilder);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
for (int k = 0; k < pInsertParam->numOfTables; ++k) {
if (!insertSTableNameListBuilder(nameListBuilder, pInsertParam->pTableNameList[k])) {
destroySTableDataBlocksListBuilder(builder);
destroySTableNameListBuilder(nameListBuilder);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
}
}
}
// build the vnode data blocks.
size_t nBlocks = 0;
size_t nRows = 0;
SInsertStatementParam* pInsertParam = &result->cmd.insertParam;
SArray* pVnodeDataBlocksList = buildSTableDataBlocksListBuilder(builder, &nBlocks, &nRows);
if (!pVnodeDataBlocksList) {
destroySTableDataBlocksListBuilder(builder);
destroySTableNameListBuilder(nameListBuilder);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
// build the table name list.
size_t nTables = 0;
SName** pTableNameList = buildSTableNameListBuilder(nameListBuilder, &nTables);
if (!pTableNameList) {
destroySTableDataBlocksListBuilder(builder);
destroySTableNameListBuilder(nameListBuilder);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
if (nTables != nBlocks) {
destroySTableDataBlocksListBuilder(builder);
destroySTableNameListBuilder(nameListBuilder);
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// replace table name list.
if (pInsertParam->pTableNameList) {
destroyTableNameList(pInsertParam);
}
pInsertParam->pTableNameList = pTableNameList;
pInsertParam->numOfTables = (int32_t) nTables;
// replace vnode data blocks.
if (pInsertParam->pDataBlocks) {
tscDestroyBlockArrayList(result, pInsertParam->pDataBlocks);
}
pInsertParam->pDataBlocks = pVnodeDataBlocksList;
pInsertParam->numOfRows = (int32_t) nRows;
// clean up.
destroySTableDataBlocksListBuilder(builder);
destroySTableNameListBuilder(nameListBuilder);
return TSDB_CODE_SUCCESS;
}
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "osAtomic.h"
#include "tscBatchMerge.h"
#include "tscBatchWrite.h"
#include "tscLog.h"
#include "tscSubquery.h"
#include "tsclient.h"
/**
* Represents the callback function and its context.
*/
typedef struct {
__async_cb_func_t fp;
void* param;
} SCallbackHandler;
/**
* The context of `batchResultCallback`.
*/
typedef struct {
size_t nHandlers;
SCallbackHandler handler[];
} SBatchCallbackContext;
/**
* Get the number of insertion row in the sql statement.
*
* @param pSql the sql statement.
* @return int32_t the number of insertion row.
*/
inline static int32_t statementGetInsertionRows(SSqlObj* pSql) { return pSql->cmd.insertParam.numOfRows; }
/**
* Return the error result to the callback function, and release the sql object.
*
* @param pSql the sql object.
* @param code the error code of the error result.
*/
inline static void tscReturnsError(SSqlObj* pSql, int code) {
if (pSql == NULL) {
return;
}
pSql->res.code = code;
tscAsyncResultOnError(pSql);
}
/**
* Proxy function to perform sequentially insert operation.
*
* @param param the context of `batchResultCallback`.
* @param tres the result object.
* @param code the error code.
*/
static void batchResultCallback(void* param, TAOS_RES* tres, int32_t code) {
SBatchCallbackContext* context = param;
SSqlObj* res = tres;
// handle corner case [context == null].
if (context == NULL) {
tscError("context in `batchResultCallback` is null, which should not happen");
if (tres) {
taosReleaseRef(tscObjRef, res->self);
}
return;
}
// handle corner case [res == null].
if (res == NULL) {
tscError("tres in `batchResultCallback` is null, which should not happen");
free(context);
return;
}
// handle results.
tscDebug("async batch result callback, number of item: %zu", context->nHandlers);
for (int i = 0; i < context->nHandlers; ++i) {
// the result object is shared by many sql objects.
// therefore, we need to increase the ref count.
taosAcquireRef(tscObjRef, res->self);
SCallbackHandler* handler = &context->handler[i];
handler->fp(handler->param, res, code);
}
taosReleaseRef(tscObjRef, res->self);
free(context);
}
int32_t dispatcherBatchBuilder(SBatchRequest* pRequest, SSqlObj** batch) {
assert(pRequest);
assert(pRequest->pRequests);
assert(pRequest->nRequests);
// create the callback context.
SBatchCallbackContext* context =
calloc(1, sizeof(SBatchCallbackContext) + pRequest->nRequests * sizeof(SCallbackHandler));
if (context == NULL) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
tscDebug("create batch call back context: %p", context);
// initialize the callback context.
context->nHandlers = pRequest->nRequests;
for (size_t i = 0; i < pRequest->nRequests; ++i) {
SSqlObj* pSql = pRequest->pRequests[i];
context->handler[i].fp = pSql->fp;
context->handler[i].param = pSql->param;
}
// merge the statements into single one.
tscDebug("start to merge %zu sql objs", pRequest->nRequests);
SSqlObj* pFirst = pRequest->pRequests[0];
int32_t code = tscMergeSSqlObjs(pRequest->pRequests, pRequest->nRequests, pFirst);
if (code != TSDB_CODE_SUCCESS) {
const char* msg = tstrerror(code);
tscDebug("failed to merge sql objects: %s", msg);
free(context);
return code;
}
pFirst->fp = batchResultCallback;
pFirst->param = context;
pFirst->fetchFp = pFirst->fp;
taosAcquireRef(tscObjRef, pFirst->self);
*batch = pFirst;
for (int i = 0; i < pRequest->nRequests; ++i) {
SSqlObj* pSql = pRequest->pRequests[i];
taosReleaseRef(tscObjRef, pSql->self);
}
return code;
}
/**
* Poll all the SSqlObj* in the dispatcher's buffer (No Lock). After call this function,
* you need to notify dispatcher->notFull by yourself.
*
* @param dispatcher the dispatcher.
* @param nPolls the number of polled SSqlObj*.
* @return all the SSqlObj* in the buffer.
*/
inline static SBatchRequest* dispatcherPollAll(SAsyncBatchWriteDispatcher* dispatcher) {
if (!dispatcher->bufferSize) {
return NULL;
}
SBatchRequest* pRequest = malloc(sizeof(SBatchRequest) + sizeof(SSqlObj*) * dispatcher->bufferSize);
if (pRequest == NULL) {
tscError("failed to poll all items: out of memory");
return NULL;
}
memcpy(pRequest->pRequests, dispatcher->buffer, sizeof(SSqlObj*) * dispatcher->bufferSize);
pRequest->nRequests = dispatcher->bufferSize;
dispatcher->currentSize = 0;
dispatcher->bufferSize = 0;
return pRequest;
}
/**
* Poll all the SSqlObj* in the dispatcher's buffer.
*
* @param dispatcher the dispatcher.
* @return all the SSqlObj* in the buffer.
*/
inline static SBatchRequest* dispatcherLockPollAll(SAsyncBatchWriteDispatcher* dispatcher) {
SBatchRequest* pRequest = NULL;
pthread_mutex_lock(&dispatcher->bufferMutex);
pRequest = dispatcherPollAll(dispatcher);
pthread_cond_broadcast(&dispatcher->notFull);
pthread_mutex_unlock(&dispatcher->bufferMutex);
return pRequest;
}
/**
* @brief Try to offer the SSqlObj* to the dispatcher.
*
* @param dispatcher the async bulk write dispatcher.
* @param pSql the sql object to offer.
* @return return whether offer success.
*/
inline static bool dispatcherTryOffer(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql) {
pthread_mutex_lock(&dispatcher->bufferMutex);
// if dispatcher is shutdown, must fail back to normal insertion.
// usually not happen, unless taos_query_a(...) after taos_close(...).
if (atomic_load_8(&dispatcher->shutdown)) {
pthread_mutex_unlock(&dispatcher->bufferMutex);
return false;
}
// the buffer is full.
while (dispatcher->currentSize >= dispatcher->batchSize) {
if (pthread_cond_wait(&dispatcher->notFull, &dispatcher->bufferMutex)) {
pthread_mutex_unlock(&dispatcher->bufferMutex);
return false;
}
}
dispatcher->buffer[dispatcher->bufferSize++] = pSql;
dispatcher->currentSize += statementGetInsertionRows(pSql);
tscDebug("sql obj %p has been write to insert buffer", pSql);
if (dispatcher->currentSize < dispatcher->batchSize) {
pthread_mutex_unlock(&dispatcher->bufferMutex);
return true;
}
// the dispatcher reaches batch size.
SBatchRequest* pRequest = dispatcherPollAll(dispatcher);
pthread_cond_broadcast(&dispatcher->notFull);
pthread_mutex_unlock(&dispatcher->bufferMutex);
if (pRequest) {
dispatcherAsyncExecute(pRequest);
}
return true;
}
void dispatcherExecute(SBatchRequest* pRequest) {
int32_t code = TSDB_CODE_SUCCESS;
// no item in the buffer (items has been taken by other threads).
if (!pRequest) {
return;
}
assert(pRequest->pRequests);
assert(pRequest->nRequests);
// merge the statements into single one.
SSqlObj* pSql = NULL;
code = dispatcherBatchBuilder(pRequest, &pSql);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
tscDebug("merging %zu sql objs into %p", pRequest->nRequests, pSql);
tscHandleMultivnodeInsert(pSql);
return;
_error:
tscError("send async batch sql obj failed, reason: %s", tstrerror(code));
// handling the failures.
for (size_t i = 0; i < pRequest->nRequests; ++i) {
SSqlObj* item = pRequest->pRequests[i];
tscReturnsError(item, code);
}
}
/**
* Get the timespec after `millis` ms
*
* @param t the timespec.
* @param millis the duration in milliseconds.
* @return the timespec after `millis` ms.
*/
static inline void afterMillis(struct timespec* t, int32_t millis) {
t->tv_nsec += millis * 1000000L;
t->tv_sec += t->tv_nsec / 1000000000L;
t->tv_nsec %= 1000000000L;
}
/**
* Sleep until `timeout` timespec. When dispatcherShutdown(...) called, the function will return immediately.
*
* @param dispatcher the dispatcher thread to sleep.
* @param timeout the timeout in CLOCK_REALTIME.
*/
inline static void timeoutManagerSleepUntil(SDispatcherTimeoutManager* manager, struct timespec* timeout) {
pthread_mutex_lock(&manager->sleepMutex);
while (true) {
// notified by dispatcherShutdown(...).
if (isShutdownSDispatcherTimeoutManager(manager)) {
break;
}
if (pthread_cond_timedwait(&manager->timeout, &manager->sleepMutex, timeout)) {
fflush(stdout);
break;
}
}
pthread_mutex_unlock(&manager->sleepMutex);
}
/**
* The thread to manage batching timeout.
*/
static void* timeoutManagerCallback(void* arg) {
SDispatcherTimeoutManager* manager = arg;
setThreadName("tscAsyncBackground");
while (!isShutdownSDispatcherTimeoutManager(manager)) {
struct timespec timeout;
clock_gettime(CLOCK_REALTIME, &timeout);
afterMillis(&timeout, manager->timeoutMs);
SBatchRequest* pRequest = dispatcherLockPollAll(manager->dispatcher);
if (pRequest) {
dispatcherAsyncExecute(pRequest);
}
// Similar to scheduleAtFixedRate in Java, if the execution time exceed
// `timeoutMs` milliseconds, then there will be no sleep.
timeoutManagerSleepUntil(manager, &timeout);
}
return NULL;
}
SAsyncBatchWriteDispatcher* createSAsyncBatchWriteDispatcher(STscObj* pClient, int32_t batchSize, int32_t timeoutMs) {
SAsyncBatchWriteDispatcher* dispatcher = calloc(1, sizeof(SAsyncBatchWriteDispatcher) + batchSize * sizeof(SSqlObj*));
if (!dispatcher) {
return NULL;
}
assert(pClient != NULL);
dispatcher->pClient = pClient;
dispatcher->currentSize = 0;
dispatcher->bufferSize = 0;
dispatcher->batchSize = batchSize;
atomic_store_8(&dispatcher->shutdown, false);
// init the mutex and the cond.
pthread_mutex_init(&dispatcher->bufferMutex, NULL);
pthread_cond_init(&dispatcher->notFull, NULL);
// init timeout manager.
dispatcher->timeoutManager = createSDispatcherTimeoutManager(dispatcher, timeoutMs);
if (!dispatcher->timeoutManager) {
pthread_mutex_destroy(&dispatcher->bufferMutex);
pthread_cond_destroy(&dispatcher->notFull);
free(dispatcher);
return NULL;
}
return dispatcher;
}
/**
* Shutdown the dispatcher and join the timeout thread.
*
* @param dispatcher the dispatcher.
*/
inline static void dispatcherShutdown(SAsyncBatchWriteDispatcher* dispatcher) {
atomic_store_8(&dispatcher->shutdown, true);
if (dispatcher->timeoutManager) {
shutdownSDispatcherTimeoutManager(dispatcher->timeoutManager);
}
}
void destroySAsyncBatchWriteDispatcher(SAsyncBatchWriteDispatcher* dispatcher) {
if (dispatcher == NULL) {
return;
}
dispatcherShutdown(dispatcher);
// poll and send all the statements in the buffer.
while (true) {
SBatchRequest* pRequest = dispatcherLockPollAll(dispatcher);
if (!pRequest) {
break;
}
dispatcherExecute(pRequest);
free(pRequest);
}
// destroy the timeout manager.
destroySDispatcherTimeoutManager(dispatcher->timeoutManager);
// destroy the mutex.
pthread_mutex_destroy(&dispatcher->bufferMutex);
pthread_cond_destroy(&dispatcher->notFull);
free(dispatcher);
}
bool dispatcherCanDispatch(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql) {
if (pSql == NULL || !pSql->enableBatch) {
return false;
}
SSqlCmd* pCmd = &pSql->cmd;
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
// only support insert statement.
if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) {
return false;
}
SInsertStatementParam* pInsertParam = &pCmd->insertParam;
// file insert not support.
if (TSDB_QUERY_HAS_TYPE(pInsertParam->insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
return false;
}
// only support kv payload.
if (pInsertParam->payloadType != PAYLOAD_TYPE_KV) {
return false;
}
// no schema attached.
if (pInsertParam->schemaAttached) {
return false;
}
// too many insertion rows, fail back to normal insertion.
if (statementGetInsertionRows(pSql) >= dispatcher->batchSize) {
return false;
}
return true;
}
bool dispatcherTryDispatch(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql) {
if (atomic_load_8(&dispatcher->shutdown)) {
return false;
}
// the sql object doesn't support bulk insertion.
if (!dispatcherCanDispatch(dispatcher, pSql)) {
return false;
}
// try to offer pSql to the buffer.
return dispatcherTryOffer(dispatcher, pSql);
}
/**
* Destroy the SAsyncBatchWriteDispatcher create by SDispatcherManager.
* @param arg the thread local SAsyncBatchWriteDispatcher.
*/
static void destroyDispatcher(void* arg) {
SAsyncBatchWriteDispatcher* dispatcher = arg;
if (!dispatcher) {
return;
}
destroySAsyncBatchWriteDispatcher(dispatcher);
}
SDispatcherManager* createDispatcherManager(STscObj* pClient, int32_t batchSize, int32_t timeoutMs,
bool isThreadLocal) {
SDispatcherManager* dispatcher = calloc(1, sizeof(SDispatcherManager));
if (!dispatcher) {
return NULL;
}
assert(pClient != NULL);
dispatcher->pClient = pClient;
dispatcher->batchSize = batchSize;
dispatcher->timeoutMs = timeoutMs;
dispatcher->isThreadLocal = isThreadLocal;
if (isThreadLocal) {
if (pthread_key_create(&dispatcher->key, destroyDispatcher)) {
free(dispatcher);
return NULL;
}
} else {
dispatcher->pGlobal = createSAsyncBatchWriteDispatcher(pClient, batchSize, timeoutMs);
if (!dispatcher->pGlobal) {
free(dispatcher);
return NULL;
}
}
return dispatcher;
}
SAsyncBatchWriteDispatcher* dispatcherAcquire(SDispatcherManager* manager) {
if (!manager->isThreadLocal) {
return manager->pGlobal;
}
SAsyncBatchWriteDispatcher* value = pthread_getspecific(manager->key);
if (value) {
return value;
}
value = createSAsyncBatchWriteDispatcher(manager->pClient, manager->batchSize, manager->timeoutMs);
if (value) {
pthread_setspecific(manager->key, value);
return value;
}
return NULL;
}
void destroyDispatcherManager(SDispatcherManager* manager) {
if (manager) {
if (manager->isThreadLocal) {
pthread_key_delete(manager->key);
}
if (manager->pGlobal) {
destroySAsyncBatchWriteDispatcher(manager->pGlobal);
}
free(manager);
}
}
SDispatcherTimeoutManager* createSDispatcherTimeoutManager(SAsyncBatchWriteDispatcher* dispatcher, int32_t timeoutMs) {
SDispatcherTimeoutManager* manager = calloc(1, sizeof(SDispatcherTimeoutManager));
if (!manager) {
return NULL;
}
manager->timeoutMs = timeoutMs;
manager->dispatcher = dispatcher;
atomic_store_8(&manager->shutdown, false);
pthread_mutex_init(&manager->sleepMutex, NULL);
pthread_cond_init(&manager->timeout, NULL);
// init background thread.
if (pthread_create(&manager->background, NULL, timeoutManagerCallback, manager)) {
pthread_mutex_destroy(&manager->sleepMutex);
pthread_cond_destroy(&manager->timeout);
free(manager);
return NULL;
}
return manager;
}
void destroySDispatcherTimeoutManager(SDispatcherTimeoutManager* manager) {
if (!manager) {
return;
}
shutdownSDispatcherTimeoutManager(manager);
manager->dispatcher->timeoutManager = NULL;
pthread_mutex_destroy(&manager->sleepMutex);
pthread_cond_destroy(&manager->timeout);
free(manager);
}
void shutdownSDispatcherTimeoutManager(SDispatcherTimeoutManager* manager) {
// mark shutdown, signal shutdown to timeout thread.
pthread_mutex_lock(&manager->sleepMutex);
atomic_store_8(&manager->shutdown, true);
pthread_cond_broadcast(&manager->timeout);
pthread_mutex_unlock(&manager->sleepMutex);
// make sure the timeout thread exit.
pthread_join(manager->background, NULL);
}
bool isShutdownSDispatcherTimeoutManager(SDispatcherTimeoutManager* manager) {
if (!manager) {
return true;
}
return atomic_load_8(&manager->shutdown);
}
/**
* The proxy function to call `dispatcherExecute`.
*
* @param pMsg the schedule message.
*/
static void dispatcherExecuteProxy(struct SSchedMsg* pMsg) {
SBatchRequest* pRequest = pMsg->ahandle;
if (!pRequest) {
return;
}
pMsg->ahandle = NULL;
dispatcherExecute(pRequest);
free(pRequest);
}
void dispatcherAsyncExecute(SBatchRequest* pRequest) {
if (!pRequest) {
return;
}
assert(pRequest->pRequests);
assert(pRequest->nRequests);
SSchedMsg schedMsg = {0};
schedMsg.fp = dispatcherExecuteProxy;
schedMsg.ahandle = (void*) pRequest;
schedMsg.thandle = (void*) 1;
schedMsg.msg = 0;
taosScheduleTask(tscQhandle, &schedMsg);
}
...@@ -1569,7 +1569,7 @@ int tsParseInsertSql(SSqlObj *pSql) { ...@@ -1569,7 +1569,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
if (pInsertParam->numOfParams > 0) { if (pInsertParam->numOfParams > 0) {
goto _clean; goto _clean;
} }
// merge according to vgId // merge according to vgId
if (!TSDB_QUERY_HAS_TYPE(pInsertParam->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pInsertParam->pTableBlockHashList) > 0) { if (!TSDB_QUERY_HAS_TYPE(pInsertParam->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pInsertParam->pTableBlockHashList) > 0) {
if ((code = tscMergeTableDataBlocks(pSql, pInsertParam, true)) != TSDB_CODE_SUCCESS) { if ((code = tscMergeTableDataBlocks(pSql, pInsertParam, true)) != TSDB_CODE_SUCCESS) {
...@@ -1577,6 +1577,7 @@ int tsParseInsertSql(SSqlObj *pSql) { ...@@ -1577,6 +1577,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
} }
} }
pCmd->insertParam.numOfRows = totalNum;
code = TSDB_CODE_SUCCESS; code = TSDB_CODE_SUCCESS;
goto _clean; goto _clean;
......
...@@ -757,25 +757,25 @@ static int32_t arrangePointsByChildTableName(TAOS_SML_DATA_POINT* points, int nu ...@@ -757,25 +757,25 @@ static int32_t arrangePointsByChildTableName(TAOS_SML_DATA_POINT* points, int nu
SHashObj* cname2points, SArray* stableSchemas, SSmlLinesInfo* info) { SHashObj* cname2points, SArray* stableSchemas, SSmlLinesInfo* info) {
for (int32_t i = 0; i < numPoints; ++i) { for (int32_t i = 0; i < numPoints; ++i) {
TAOS_SML_DATA_POINT * point = points + i; TAOS_SML_DATA_POINT * point = points + i;
SSmlSTableSchema* stableSchema = taosArrayGet(stableSchemas, point->schemaIdx); // SSmlSTableSchema* stableSchema = taosArrayGet(stableSchemas, point->schemaIdx);
for (int j = 0; j < point->tagNum; ++j) { // for (int j = 0; j < point->tagNum; ++j) {
TAOS_SML_KV* kv = point->tags + j; // TAOS_SML_KV* kv = point->tags + j;
if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) { // if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) {
int64_t ts = *(int64_t*)(kv->value); // int64_t ts = *(int64_t*)(kv->value);
ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, stableSchema->precision); // ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, stableSchema->precision);
*(int64_t*)(kv->value) = ts; // *(int64_t*)(kv->value) = ts;
} // }
} // }
//
for (int j = 0; j < point->fieldNum; ++j) { // for (int j = 0; j < point->fieldNum; ++j) {
TAOS_SML_KV* kv = point->fields + j; // TAOS_SML_KV* kv = point->fields + j;
if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) { // if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) {
int64_t ts = *(int64_t*)(kv->value); // int64_t ts = *(int64_t*)(kv->value);
ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, stableSchema->precision); // ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, stableSchema->precision);
*(int64_t*)(kv->value) = ts; // *(int64_t*)(kv->value) = ts;
} // }
} // }
SArray* cTablePoints = NULL; SArray* cTablePoints = NULL;
SArray** pCTablePoints = taosHashGet(cname2points, point->childTableName, strlen(point->childTableName)); SArray** pCTablePoints = taosHashGet(cname2points, point->childTableName, strlen(point->childTableName));
...@@ -860,7 +860,14 @@ static int32_t addChildTableDataPointsToInsertSql(char* cTableName, char* sTable ...@@ -860,7 +860,14 @@ static int32_t addChildTableDataPointsToInsertSql(char* cTableName, char* sTable
TAOS_SML_KV* kv = tagKVs[i]; TAOS_SML_KV* kv = tagKVs[i];
size_t beforeLen = totalLen; size_t beforeLen = totalLen;
int32_t len = 0; int32_t len = 0;
converToStr(sql + beforeLen, kv->type, kv->value, kv->length, &len);
if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) {
int64_t ts = *(int64_t*)(kv->value);
ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, sTableSchema->precision);
converToStr(sql + beforeLen, kv->type, &ts, kv->length, &len);
}else{
converToStr(sql + beforeLen, kv->type, kv->value, kv->length, &len);
}
totalLen += len; totalLen += len;
ret = smlSnprintf(sql, &totalLen, capacity, ","); ret = smlSnprintf(sql, &totalLen, capacity, ",");
...@@ -914,7 +921,13 @@ static int32_t addChildTableDataPointsToInsertSql(char* cTableName, char* sTable ...@@ -914,7 +921,13 @@ static int32_t addChildTableDataPointsToInsertSql(char* cTableName, char* sTable
TAOS_SML_KV* kv = colKVs[i]; TAOS_SML_KV* kv = colKVs[i];
size_t beforeLen = totalLen; size_t beforeLen = totalLen;
int32_t len = 0; int32_t len = 0;
converToStr(sql + beforeLen, kv->type, kv->value, kv->length, &len); if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) {
int64_t ts = *(int64_t*)(kv->value);
ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, sTableSchema->precision);
converToStr(sql + beforeLen, kv->type, &ts, kv->length, &len);
}else{
converToStr(sql + beforeLen, kv->type, kv->value, kv->length, &len);
}
totalLen += len; totalLen += len;
ret = smlSnprintf(sql, &totalLen, capacity, ","); ret = smlSnprintf(sql, &totalLen, capacity, ",");
if (ret != 0) { if (ret != 0) {
...@@ -965,7 +978,7 @@ static void insertCallback(void *param, TAOS_RES *res, int32_t notUsedCode) { ...@@ -965,7 +978,7 @@ static void insertCallback(void *param, TAOS_RES *res, int32_t notUsedCode) {
batch->tryAgain = true; batch->tryAgain = true;
} }
if (code == TSDB_CODE_TDB_INVALID_TABLE_ID || code == TSDB_CODE_VND_INVALID_VGROUP_ID) { if (code == TSDB_CODE_TDB_INVALID_TABLE_ID || code == TSDB_CODE_VND_INVALID_VGROUP_ID || code == TSDB_CODE_MND_INVALID_TABLE_NAME) {
batch->resetQueryCache = true; batch->resetQueryCache = true;
if (batch->tryAgain) { if (batch->tryAgain) {
batch->sleep = true; batch->sleep = true;
...@@ -1105,6 +1118,9 @@ static int32_t applyDataPointsWithSqlInsert(TAOS* taos, TAOS_SML_DATA_POINT* poi ...@@ -1105,6 +1118,9 @@ static int32_t applyDataPointsWithSqlInsert(TAOS* taos, TAOS_SML_DATA_POINT* poi
SSmlSqlInsertBatch* b = info->batches + i; SSmlSqlInsertBatch* b = info->batches + i;
if (b->code != 0) { if (b->code != 0) {
code = b->code; code = b->code;
if(code == TSDB_CODE_MND_INVALID_TABLE_NAME){
break;
}
} }
} }
...@@ -1221,42 +1237,52 @@ int tscSmlInsert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint, SSmlLine ...@@ -1221,42 +1237,52 @@ int tscSmlInsert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint, SSmlLine
info->affectedRows = 0; info->affectedRows = 0;
if (numPoint == 1) { int32_t tableNotExistTryTimes = 3;
TAOS_SML_DATA_POINT* point = points + 0; while(tableNotExistTryTimes){
code = doSmlInsertOneDataPoint(taos, point, info); if (numPoint == 1) {
if (code == TSDB_CODE_SUCCESS) { TAOS_SML_DATA_POINT* point = points + 0;
return code; code = doSmlInsertOneDataPoint(taos, point, info);
if (code == TSDB_CODE_SUCCESS) {
return code;
}
} }
}
tscDebug("SML:0x%"PRIx64" build data point schemas", info->id); tscDebug("SML:0x%"PRIx64" build data point schemas", info->id);
SArray* stableSchemas = taosArrayInit(32, sizeof(SSmlSTableSchema)); // SArray<STableColumnsSchema> SArray* stableSchemas = taosArrayInit(32, sizeof(SSmlSTableSchema)); // SArray<STableColumnsSchema>
code = buildDataPointSchemas(points, numPoint, stableSchemas, info); code = buildDataPointSchemas(points, numPoint, stableSchemas, info);
if (code != 0) { if (code != 0) {
tscError("SML:0x%"PRIx64" error building data point schemas : %s", info->id, tstrerror(code)); tscError("SML:0x%"PRIx64" error building data point schemas : %s", info->id, tstrerror(code));
goto clean_up; goto clean_up;
} }
tscDebug("SML:0x%"PRIx64" modify db schemas", info->id); tscDebug("SML:0x%"PRIx64" modify db schemas", info->id);
code = modifyDBSchemas(taos, stableSchemas, info); code = modifyDBSchemas(taos, stableSchemas, info);
if (code != 0) { if (code != 0) {
tscError("SML:0x%"PRIx64" error change db schema : %s", info->id, tstrerror(code)); tscError("SML:0x%"PRIx64" error change db schema : %s", info->id, tstrerror(code));
goto clean_up; goto clean_up;
} }
tscDebug("SML:0x%"PRIx64" apply data points", info->id); tscDebug("SML:0x%"PRIx64" apply data points", info->id);
code = applyDataPointsWithSqlInsert(taos, points, numPoint, stableSchemas, info); code = applyDataPointsWithSqlInsert(taos, points, numPoint, stableSchemas, info);
if (code != 0) { if (code != 0) {
tscError("SML:0x%"PRIx64" error apply data points : %s", info->id, tstrerror(code)); tscError("SML:0x%"PRIx64" error apply data points : %s", info->id, tstrerror(code));
} }
clean_up: clean_up:
for (int i = 0; i < taosArrayGetSize(stableSchemas); ++i) { for (int i = 0; i < taosArrayGetSize(stableSchemas); ++i) {
SSmlSTableSchema* schema = taosArrayGet(stableSchemas, i); SSmlSTableSchema* schema = taosArrayGet(stableSchemas, i);
taosArrayDestroy(&schema->fields); taosArrayDestroy(&schema->fields);
taosArrayDestroy(&schema->tags); taosArrayDestroy(&schema->tags);
}
taosArrayDestroy(&stableSchemas);
if(code == TSDB_CODE_MND_INVALID_TABLE_NAME){
tableNotExistTryTimes--;
}else{
tableNotExistTryTimes = 0;
}
} }
taosArrayDestroy(&stableSchemas);
return code; return code;
} }
...@@ -2090,7 +2116,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, int32_t sqlLen, ...@@ -2090,7 +2116,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, int32_t sqlLen,
switch (tag_state) { switch (tag_state) {
case tag_common: case tag_common:
if (back_slash == true) { if (back_slash == true) {
if (*cur != ',' && *cur != '=' && *cur != ' ' && *cur != 'n' ) { if (*cur != ',' && *cur != '=' && *cur != ' ' && *cur != 'n' && *cur != 't' && *cur != 'r') {
tscError("SML:0x%"PRIx64" tag value: state(%d), incorrect character(%c) escaped", info->id, tag_state, *cur); tscError("SML:0x%"PRIx64" tag value: state(%d), incorrect character(%c) escaped", info->id, tag_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR; ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error; goto error;
...@@ -2150,7 +2176,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, int32_t sqlLen, ...@@ -2150,7 +2176,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, int32_t sqlLen,
break; break;
case tag_lqoute: case tag_lqoute:
if (back_slash == true) { if (back_slash == true) {
if (*cur != ',' && *cur != '=' && *cur != ' ' && *cur != 'n') { if (*cur != ',' && *cur != '=' && *cur != ' ' && *cur != 'n' && *cur != 't' && *cur != 'r') {
tscError("SML:0x%"PRIx64" tag value: state(%d), incorrect character(%c) escaped", info->id, tag_state, *cur); tscError("SML:0x%"PRIx64" tag value: state(%d), incorrect character(%c) escaped", info->id, tag_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR; ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error; goto error;
...@@ -2205,7 +2231,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, int32_t sqlLen, ...@@ -2205,7 +2231,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, int32_t sqlLen,
switch (val_state) { switch (val_state) {
case val_common: case val_common:
if (back_slash == true) { if (back_slash == true) {
if (*cur != '\\' && *cur != '"' && *cur != 'n') { if (*cur != '\\' && *cur != '"' && *cur != 'n' && *cur != 't' && *cur != 'r') {
tscError("SML:0x%"PRIx64" field value: state(%d), incorrect character(%c) escaped", info->id, val_state, *cur); tscError("SML:0x%"PRIx64" field value: state(%d), incorrect character(%c) escaped", info->id, val_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR; ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error; goto error;
...@@ -2293,7 +2319,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, int32_t sqlLen, ...@@ -2293,7 +2319,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, int32_t sqlLen,
break; break;
case val_lqoute: case val_lqoute:
if (back_slash == true) { if (back_slash == true) {
if (*cur != '\\' && *cur != '"' && *cur != 'n') { if (*cur != '\\' && *cur != '"' && *cur != 'n' && *cur != 't' && *cur != 'r') {
tscError("SML:0x%"PRIx64" field value: state(%d), incorrect character(%c) escaped", info->id, val_state, *cur); tscError("SML:0x%"PRIx64" field value: state(%d), incorrect character(%c) escaped", info->id, val_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR; ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error; goto error;
......
...@@ -862,7 +862,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -862,7 +862,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
const char* msg3 = "name too long"; const char* msg3 = "name too long";
const char* msg5 = "invalid user rights"; const char* msg5 = "invalid user rights";
const char* msg7 = "not support options"; const char* msg7 = "not support options";
const char* msg8 = "tags filter length must over 3 bytes."; const char* msg8 = "tags filter string length must less than 255 bytes.";
pCmd->command = pInfo->type; pCmd->command = pInfo->type;
...@@ -903,15 +903,14 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -903,15 +903,14 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
} }
} else if (pUser->type == TSDB_ALTER_USER_TAGS) { } else if (pUser->type == TSDB_ALTER_USER_TAGS) {
SStrToken* pTags = &pUser->tags; SStrToken* pTags = &pUser->tags;
if(pTags->n < 4) if (pTags->n > TSDB_TAGS_LEN - 1 ) return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); } else {
} else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
} }
} }
break; break;
} }
case TSDB_SQL_CFG_LOCAL: { case TSDB_SQL_CFG_LOCAL: {
SMiscInfo *pMiscInfo = pInfo->pMiscInfo; SMiscInfo *pMiscInfo = pInfo->pMiscInfo;
...@@ -7340,18 +7339,19 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -7340,18 +7339,19 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
bool dbIncluded = false; bool dbIncluded = false;
SStrToken tmpToken = pAlterSQL->name; SStrToken tmpToken = pAlterSQL->name;
tmpToken.z= strndup(pAlterSQL->name.z, pAlterSQL->name.n); char* z0 = strndup(pAlterSQL->name.z, pAlterSQL->name.n);
tmpToken.z = z0;
if (tscValidateName(&tmpToken, true, &dbIncluded) != TSDB_CODE_SUCCESS) { if (tscValidateName(&tmpToken, true, &dbIncluded) != TSDB_CODE_SUCCESS) {
free(tmpToken.z); free(z0);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
code = tscSetTableFullName(&pTableMetaInfo->name, &tmpToken, pSql, dbIncluded); code = tscSetTableFullName(&pTableMetaInfo->name, &tmpToken, pSql, dbIncluded);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
free(tmpToken.z); free(z0);
return code; return code;
} }
free(tmpToken.z); free(z0);
code = tscGetTableMeta(pSql, pTableMetaInfo); code = tscGetTableMeta(pSql, pTableMetaInfo);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
......
...@@ -2953,6 +2953,12 @@ int tscProcessQueryRsp(SSqlObj *pSql) { ...@@ -2953,6 +2953,12 @@ int tscProcessQueryRsp(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res; SSqlRes *pRes = &pSql->res;
SQueryTableRsp *pQueryAttr = (SQueryTableRsp *)pRes->pRsp; SQueryTableRsp *pQueryAttr = (SQueryTableRsp *)pRes->pRsp;
if (pQueryAttr == NULL) {
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
return pRes->code;
}
pQueryAttr->qId = htobe64(pQueryAttr->qId); pQueryAttr->qId = htobe64(pQueryAttr->qId);
pRes->qId = pQueryAttr->qId; pRes->qId = pQueryAttr->qId;
...@@ -3056,7 +3062,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { ...@@ -3056,7 +3062,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput; int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, numOfCols - 1); TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, numOfCols - 1);
int16_t offset = tscFieldInfoGetOffset(pQueryInfo, numOfCols - 1); int32_t offset = tscFieldInfoGetOffset(pQueryInfo, numOfCols - 1);
char* p = pRes->data + (pField->bytes + offset) * pRes->numOfRows; char* p = pRes->data + (pField->bytes + offset) * pRes->numOfRows;
...@@ -3393,7 +3399,7 @@ int tscRenewTableMeta(SSqlObj *pSql) { ...@@ -3393,7 +3399,7 @@ int tscRenewTableMeta(SSqlObj *pSql) {
SSqlCmd* pCmd2 = &pSql->rootObj->cmd; SSqlCmd* pCmd2 = &pSql->rootObj->cmd;
SHashObj *pmap = pCmd2->pTableMetaMap; SHashObj *pmap = pCmd2->pTableMetaMap;
if (pmap == atomic_val_compare_exchange_ptr(&pCmd2->pTableMetaMap, pmap, NULL)) { if (pmap == atomic_val_compare_exchange_ptr(&pCmd2->pTableMetaMap, pmap, NULL)) {
tscCleanupTableMetaMap(pCmd2->pTableMetaMap); tscCleanupTableMetaMap(pmap);
} }
pCmd2->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK); pCmd2->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "tnote.h" #include "tnote.h"
#include "trpc.h" #include "trpc.h"
#include "tscLog.h" #include "tscLog.h"
#include "tscBatchWrite.h"
#include "tscSubquery.h" #include "tscSubquery.h"
#include "tscUtil.h" #include "tscUtil.h"
#include "tsclient.h" #include "tsclient.h"
...@@ -163,15 +164,30 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa ...@@ -163,15 +164,30 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
pSql->fp = fp; pSql->fp = fp;
pSql->param = param; pSql->param = param;
pSql->cmd.command = TSDB_SQL_CONNECT; pSql->cmd.command = TSDB_SQL_CONNECT;
pObj->dispatcherManager = NULL;
if (tsWriteBatchSize > 1 && !tscEmbedded) {
pObj->dispatcherManager = createDispatcherManager(pObj, tsWriteBatchSize, tsWriteBatchTimeout, tsWriteBatchThreadLocal);
if (!pObj->dispatcherManager) {
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
tscReleaseRpc(pRpcObj);
free(pSql);
free(pObj);
return NULL;
}
}
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE)) { if (TSDB_CODE_SUCCESS != tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
if (pObj->dispatcherManager) {
destroyDispatcherManager(pObj->dispatcherManager);
}
tscReleaseRpc(pRpcObj); tscReleaseRpc(pRpcObj);
free(pSql); free(pSql);
free(pObj); free(pObj);
return NULL; return NULL;
} }
if (taos != NULL) { if (taos != NULL) {
*taos = pObj; *taos = pObj;
} }
......
...@@ -264,7 +264,7 @@ static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) { ...@@ -264,7 +264,7 @@ static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) {
pStream->stime += pStream->slidingTime; pStream->stime += pStream->slidingTime;
*(TSKEY*)row[0] = pStream->stime; *(TSKEY*)row[0] = pStream->stime;
for (int32_t i = 1; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { for (int32_t i = 1; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
int16_t offset = tscFieldInfoGetOffset(pQueryInfo, i); int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
assignVal(pSql->res.data + offset, (char *)(&pQueryInfo->fillVal[i]), pField->bytes, pField->type); assignVal(pSql->res.data + offset, (char *)(&pQueryInfo->fillVal[i]), pField->bytes, pField->type);
row[i] = pSql->res.data + offset; row[i] = pSql->res.data + offset;
...@@ -339,7 +339,7 @@ bool sqlBufSend(TAOS *taos, char *sqlBuf) { ...@@ -339,7 +339,7 @@ bool sqlBufSend(TAOS *taos, char *sqlBuf) {
} while(++sleepCnt < 20); } while(++sleepCnt < 20);
strcat(sqlBuf, ";"); strcat(sqlBuf, ";");
taos_query_ra(taos, sqlBuf, cbSendValues, NULL); taos_query_ra(taos, sqlBuf, cbSendValues, NULL, false);
return true; return true;
} }
......
...@@ -14,18 +14,19 @@ ...@@ -14,18 +14,19 @@
*/ */
#include "os.h" #include "os.h"
#include "qScript.h"
#include "taosmsg.h" #include "taosmsg.h"
#include "tconfig.h"
#include "tglobal.h"
#include "tnote.h"
#include "tref.h" #include "tref.h"
#include "trpc.h" #include "trpc.h"
#include "tnote.h" #include "tscBatchWrite.h"
#include "ttimer.h"
#include "tsched.h"
#include "tscLog.h" #include "tscLog.h"
#include "tsched.h"
#include "tsclient.h" #include "tsclient.h"
#include "tglobal.h" #include "ttimer.h"
#include "tconfig.h"
#include "ttimezone.h" #include "ttimezone.h"
#include "qScript.h"
// global, not configurable // global, not configurable
#define TSC_VAR_NOT_RELEASE 1 #define TSC_VAR_NOT_RELEASE 1
...@@ -319,6 +320,49 @@ void taos_cleanup(void) { ...@@ -319,6 +320,49 @@ void taos_cleanup(void) {
taosTmrCleanUp(p); taosTmrCleanUp(p);
} }
/**
* Set the option value (int32, uint16, int16, int8).
* @param cfg the config.
* @param str the value string.
* @return whether is set or not.
*/
static bool taos_set_option_int(SGlobalCfg * cfg, const char* str) {
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
char* p = NULL;
errno = 0;
long value = strtol(str, &p, 10);
if (errno != 0 || p == str) {
tscError("failed to parse option: %s, value: %s", cfg->option, str);
return false;
}
if ((float) value < cfg->minValue || (float) value > cfg->maxValue) {
tscError("failed to set option: %s, setValue: %ld, minValue: %f, maxValue: %f", cfg->option, value, cfg->minValue, cfg->maxValue);
return false;
}
if (cfg->valType == TAOS_CFG_VTYPE_INT32) {
*((int32_t*) cfg->ptr) = (int32_t) value;
} else if (cfg->valType == TAOS_CFG_VTYPE_UINT16) {
*((uint16_t*) cfg->ptr) = (uint16_t) value;
} else if (cfg->valType == TAOS_CFG_VTYPE_INT16) {
*((int16_t*) cfg->ptr) = (int16_t) value;
} else if (cfg->valType == TAOS_CFG_VTYPE_INT8) {
*((int8_t*) cfg->ptr) = (int8_t) value;
} else {
tscError("failed to set option: %s, type expected %d", cfg->option, cfg->valType);
return false;
}
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
tscDebug("config option: %s has set to %s", cfg->option, str);
return true;
}
tscWarn("config option: %s, is configured by %s", cfg->option, tsCfgStatusStr[cfg->cfgStatus]);
return false;
}
static int taos_options_imp(TSDB_OPTION option, const char *pStr) { static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
SGlobalCfg *cfg = NULL; SGlobalCfg *cfg = NULL;
...@@ -473,6 +517,27 @@ static int taos_options_imp(TSDB_OPTION option, const char *pStr) { ...@@ -473,6 +517,27 @@ static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr); tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
} }
break; break;
case TSDB_WRITE_BATCH_SIZE: {
cfg = taosGetConfigOption("writeBatchSize");
assert(cfg != NULL);
taos_set_option_int(cfg, pStr);
break;
}
case TSDB_WRITE_BATCH_TIMEOUT: {
cfg = taosGetConfigOption("writeBatchTimeout");
assert(cfg != NULL);
taos_set_option_int(cfg, pStr);
break;
}
case TSDB_WRITE_BATCH_THREAD_LOCAL: {
cfg = taosGetConfigOption("writeBatchThreadLocal");
assert(cfg != NULL);
taos_set_option_int(cfg, pStr);
break;
}
default: default:
// TODO return the correct error code to client in the format for taos_errstr() // TODO return the correct error code to client in the format for taos_errstr()
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "texpr.h" #include "texpr.h"
#include "tkey.h" #include "tkey.h"
#include "tmd5.h" #include "tmd5.h"
#include "tscBatchWrite.h"
#include "tscGlobalmerge.h" #include "tscGlobalmerge.h"
#include "tscLog.h" #include "tscLog.h"
#include "tscProfile.h" #include "tscProfile.h"
...@@ -1372,6 +1373,10 @@ void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, b ...@@ -1372,6 +1373,10 @@ void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, b
// set the correct result // set the correct result
SSDataBlock* p = pQueryInfo->pQInfo->runtimeEnv.outputBuf; SSDataBlock* p = pQueryInfo->pQInfo->runtimeEnv.outputBuf;
pRes->numOfRows = (p != NULL)? p->info.rows: 0; pRes->numOfRows = (p != NULL)? p->info.rows: 0;
bool completed = pRes->numOfRows == 0;
if (p && pRes->numOfRows == 0 && tsAggAlways) {
pRes->numOfRows = 1;
}
if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) { if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) {
tscCreateResPointerInfo(pRes, pQueryInfo); tscCreateResPointerInfo(pRes, pQueryInfo);
...@@ -1380,7 +1385,7 @@ void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, b ...@@ -1380,7 +1385,7 @@ void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, b
tscDebug("0x%"PRIx64" retrieve result in pRes, numOfRows:%d", objId, pRes->numOfRows); tscDebug("0x%"PRIx64" retrieve result in pRes, numOfRows:%d", objId, pRes->numOfRows);
pRes->row = 0; pRes->row = 0;
pRes->completed = (pRes->numOfRows == 0); pRes->completed = completed;
} }
/* /*
...@@ -1649,7 +1654,7 @@ void tscResetSqlCmd(SSqlCmd* pCmd, bool clearCachedMeta, uint64_t id) { ...@@ -1649,7 +1654,7 @@ void tscResetSqlCmd(SSqlCmd* pCmd, bool clearCachedMeta, uint64_t id) {
tscFreeQueryInfo(pCmd, clearCachedMeta, id); tscFreeQueryInfo(pCmd, clearCachedMeta, id);
SHashObj *pmap = pCmd->pTableMetaMap; SHashObj *pmap = pCmd->pTableMetaMap;
if (pmap == atomic_val_compare_exchange_ptr(&pCmd->pTableMetaMap, pmap, NULL)) { if (pmap == atomic_val_compare_exchange_ptr(&pCmd->pTableMetaMap, pmap, NULL)) {
tscCleanupTableMetaMap(pCmd->pTableMetaMap); tscCleanupTableMetaMap(pmap);
} }
taosReleaseRef(tscObjRef, id); taosReleaseRef(tscObjRef, id);
} }
...@@ -1837,32 +1842,36 @@ void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo) { ...@@ -1837,32 +1842,36 @@ void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo) {
tfree(pColInfo->colIdxInfo); tfree(pColInfo->colIdxInfo);
} }
void tscDestroyDataBlock(SSqlObj *pSql, STableDataBlocks* pDataBlock, bool removeMeta) { void destroySTableDataBlocks(STableDataBlocks* pDataBlocks) {
if (pDataBlock == NULL) { if (!pDataBlocks) {
return; return;
} }
tfree(pDataBlocks->pData);
if (!pDataBlocks->cloned) {
tfree(pDataBlocks->params);
// free the refcount for metermeta
if (pDataBlocks->pTableMeta != NULL) {
tfree(pDataBlocks->pTableMeta);
}
tfree(pDataBlock->pData); tscDestroyBoundColumnInfo(&pDataBlocks->boundColumnInfo);
}
tfree(pDataBlocks);
}
void tscDestroyDataBlock(SSqlObj *pSql, STableDataBlocks* pDataBlock, bool removeMeta) {
if (pDataBlock == NULL) {
return;
}
if (removeMeta) { if (removeMeta) {
char name[TSDB_TABLE_FNAME_LEN] = {0}; char name[TSDB_TABLE_FNAME_LEN] = {0};
tNameExtractFullName(&pDataBlock->tableName, name); tNameExtractFullName(&pDataBlock->tableName, name);
taosHashRemove(UTIL_GET_TABLEMETA(pSql), name, strnlen(name, TSDB_TABLE_FNAME_LEN)); taosHashRemove(UTIL_GET_TABLEMETA(pSql), name, strnlen(name, TSDB_TABLE_FNAME_LEN));
} }
if (!pDataBlock->cloned) { destroySTableDataBlocks(pDataBlock);
tfree(pDataBlock->params);
// free the refcount for metermeta
if (pDataBlock->pTableMeta != NULL) {
tfree(pDataBlock->pTableMeta);
}
tscDestroyBoundColumnInfo(&pDataBlock->boundColumnInfo);
}
tfree(pDataBlock);
} }
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, uint16_t bytes, SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, uint16_t bytes,
...@@ -1889,18 +1898,22 @@ SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint ...@@ -1889,18 +1898,22 @@ SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint
return param; return param;
} }
void* tscDestroyBlockArrayList(SSqlObj *pSql, SArray* pDataBlockList) { void destroySTableDataBlocksList(SArray* pDataBlocks) {
if (pDataBlockList == NULL) { if (!pDataBlocks) {
return NULL; return;
} }
size_t nBlocks = taosArrayGetSize(pDataBlocks);
size_t size = taosArrayGetSize(pDataBlockList); for (size_t i = 0; i < nBlocks; ++i) {
for (int32_t i = 0; i < size; i++) { STableDataBlocks * pDataBlock = taosArrayGetP(pDataBlocks, i);
void* d = taosArrayGetP(pDataBlockList, i); if (pDataBlock) {
tscDestroyDataBlock(pSql, d, false); destroySTableDataBlocks(pDataBlock);
}
} }
taosArrayDestroy(&pDataBlocks);
}
taosArrayDestroy(&pDataBlockList); void* tscDestroyBlockArrayList(SSqlObj *pSql, SArray* pDataBlockList) {
destroySTableDataBlocksList(pDataBlockList);
return NULL; return NULL;
} }
...@@ -2198,42 +2211,35 @@ static int32_t getRowExpandSize(STableMeta* pTableMeta) { ...@@ -2198,42 +2211,35 @@ static int32_t getRowExpandSize(STableMeta* pTableMeta) {
return result; return result;
} }
static void extractTableNameList(SSqlObj *pSql, SInsertStatementParam *pInsertParam, bool freeBlockMap) {
pInsertParam->numOfTables = (int32_t) taosHashGetSize(pInsertParam->pTableBlockHashList);
if (pInsertParam->pTableNameList == NULL) {
pInsertParam->pTableNameList = malloc(pInsertParam->numOfTables * POINTER_BYTES);
}
STableDataBlocks **p1 = taosHashIterate(pInsertParam->pTableBlockHashList, NULL);
int32_t i = 0;
while(p1) {
STableDataBlocks* pBlocks = *p1;
//tfree(pInsertParam->pTableNameList[i]);
pInsertParam->pTableNameList[i++] = tNameDup(&pBlocks->tableName);
p1 = taosHashIterate(pInsertParam->pTableBlockHashList, p1);
}
if (freeBlockMap) {
pInsertParam->pTableBlockHashList = tscDestroyBlockHashTable(pSql, pInsertParam->pTableBlockHashList, false);
}
}
int32_t tscMergeTableDataBlocks(SSqlObj *pSql, SInsertStatementParam *pInsertParam, bool freeBlockMap) { int32_t tscMergeTableDataBlocks(SSqlObj *pSql, SInsertStatementParam *pInsertParam, bool freeBlockMap) {
const int INSERT_HEAD_SIZE = sizeof(SMsgDesc) + sizeof(SSubmitMsg); const int INSERT_HEAD_SIZE = sizeof(SMsgDesc) + sizeof(SSubmitMsg);
int code = 0; int code = 0;
bool isRawPayload = IS_RAW_PAYLOAD(pInsertParam->payloadType); bool isRawPayload = IS_RAW_PAYLOAD(pInsertParam->payloadType);
void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); size_t initialSize = taosHashGetSize(pInsertParam->pTableBlockHashList);
initialSize = initialSize > 128 ? 128 : initialSize;
void* pVnodeDataBlockHashList = taosHashInit(initialSize, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES); SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES);
STableDataBlocks** p = taosHashIterate(pInsertParam->pTableBlockHashList, NULL); // alloc table name list.
size_t numOfTables = taosHashGetSize(pInsertParam->pTableBlockHashList);
STableDataBlocks* pOneTableBlock = *p; if (pInsertParam->pTableNameList) {
destroyTableNameList(pInsertParam);
}
pInsertParam->pTableNameList = calloc(numOfTables, sizeof(SName*));
pInsertParam->numOfTables = (int32_t) numOfTables;
size_t tail = 0;
SBlockKeyInfo blkKeyInfo = {0}; // share by pOneTableBlock SBlockKeyInfo blkKeyInfo = {0}; // share by pOneTableBlock
STableDataBlocks** iter = taosHashIterate(pInsertParam->pTableBlockHashList, NULL);
while(pOneTableBlock) { while (iter) {
STableDataBlocks* pOneTableBlock = *iter;
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData; SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
iter = taosHashIterate(pInsertParam->pTableBlockHashList, iter);
// extract table name list.
pInsertParam->pTableNameList[tail++] = tNameDup(&pOneTableBlock->tableName);
if (pBlocks->numOfRows > 0) { if (pBlocks->numOfRows > 0) {
// the maximum expanded size in byte when a row-wise data is converted to SDataRow format // the maximum expanded size in byte when a row-wise data is converted to SDataRow format
int32_t expandSize = isRawPayload ? getRowExpandSize(pOneTableBlock->pTableMeta) : 0; int32_t expandSize = isRawPayload ? getRowExpandSize(pOneTableBlock->pTableMeta) : 0;
...@@ -2316,19 +2322,19 @@ int32_t tscMergeTableDataBlocks(SSqlObj *pSql, SInsertStatementParam *pInsertPar ...@@ -2316,19 +2322,19 @@ int32_t tscMergeTableDataBlocks(SSqlObj *pSql, SInsertStatementParam *pInsertPar
dataBuf->numOfTables += 1; dataBuf->numOfTables += 1;
pBlocks->numOfRows = 0; pBlocks->numOfRows = 0;
}else { } else {
tscDebug("0x%"PRIx64" table %s data block is empty", pInsertParam->objectId, pOneTableBlock->tableName.tname); tscDebug("0x%"PRIx64" table %s data block is empty", pInsertParam->objectId, pOneTableBlock->tableName.tname);
} }
p = taosHashIterate(pInsertParam->pTableBlockHashList, p); if (freeBlockMap) {
if (p == NULL) { tscDestroyDataBlock(pSql, pOneTableBlock, false);
break;
} }
pOneTableBlock = *p;
} }
extractTableNameList(pSql, pInsertParam, freeBlockMap); if (freeBlockMap) {
taosHashCleanup(pInsertParam->pTableBlockHashList);
pInsertParam->pTableBlockHashList = NULL;
}
// free the table data blocks; // free the table data blocks;
pInsertParam->pDataBlocks = pVnodeDataBlockList; pInsertParam->pDataBlocks = pVnodeDataBlockList;
...@@ -2349,6 +2355,9 @@ void tscCloseTscObj(void *param) { ...@@ -2349,6 +2355,9 @@ void tscCloseTscObj(void *param) {
tscReleaseRpc(pObj->pRpcObj); tscReleaseRpc(pObj->pRpcObj);
pthread_mutex_destroy(&pObj->mutex); pthread_mutex_destroy(&pObj->mutex);
tscReleaseClusterInfo(pObj->clusterId); tscReleaseClusterInfo(pObj->clusterId);
destroyDispatcherManager(pObj->dispatcherManager);
pObj->dispatcherManager = NULL;
tfree(pObj); tfree(pObj);
} }
...@@ -5238,6 +5247,8 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt ...@@ -5238,6 +5247,8 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
pQueryAttr->precision = pTableMetaInfo->pTableMeta->tableInfo.precision;
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
pQueryAttr->pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr)); pQueryAttr->pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr));
*(pQueryAttr->pGroupbyExpr) = pQueryInfo->groupbyExpr; *(pQueryAttr->pGroupbyExpr) = pQueryInfo->groupbyExpr;
......
...@@ -92,6 +92,9 @@ extern int32_t tsRetryStreamCompDelay; ...@@ -92,6 +92,9 @@ extern int32_t tsRetryStreamCompDelay;
extern float tsStreamComputDelayRatio; // the delayed computing ration of the whole time window extern float tsStreamComputDelayRatio; // the delayed computing ration of the whole time window
extern int32_t tsProjectExecInterval; extern int32_t tsProjectExecInterval;
extern int64_t tsMaxRetentWindow; extern int64_t tsMaxRetentWindow;
extern bool tsWriteBatchThreadLocal;
extern int32_t tsWriteBatchSize;
extern int32_t tsWriteBatchTimeout;
// db parameters in client // db parameters in client
extern int32_t tsCacheBlockSize; extern int32_t tsCacheBlockSize;
...@@ -151,6 +154,10 @@ extern char tsMonitorDbName[]; ...@@ -151,6 +154,10 @@ extern char tsMonitorDbName[];
extern char tsInternalPass[]; extern char tsInternalPass[];
extern int32_t tsMonitorInterval; extern int32_t tsMonitorInterval;
// audit
extern int8_t tsEnableAudit;
extern char tsAuditDbName[];
// stream // stream
extern int8_t tsEnableStream; extern int8_t tsEnableStream;
...@@ -219,6 +226,7 @@ extern int32_t cqDebugFlag; ...@@ -219,6 +226,7 @@ extern int32_t cqDebugFlag;
extern int32_t debugFlag; extern int32_t debugFlag;
extern int8_t tsClientMerge; extern int8_t tsClientMerge;
extern int8_t tsAggAlways;
// probe alive connection // probe alive connection
extern int32_t tsProbeSeconds; extern int32_t tsProbeSeconds;
......
...@@ -127,6 +127,11 @@ int8_t tsSortWhenGroupBy = 1; ...@@ -127,6 +127,11 @@ int8_t tsSortWhenGroupBy = 1;
int32_t tsProjectExecInterval = 10000; // every 10sec, the projection will be executed once int32_t tsProjectExecInterval = 10000; // every 10sec, the projection will be executed once
int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance
// The tsc async write batching feature (using ABWD).
bool tsWriteBatchThreadLocal = false; // if thread local enable, each thread will allocate a dispatcher.
int32_t tsWriteBatchSize = 0; // suggest: 64 - 512, default 0, 0 means disable batching.
int32_t tsWriteBatchTimeout = 10; // suggest: 2 - 100 (unit: milliseconds)
// the maximum allowed query buffer size during query processing for each data node. // the maximum allowed query buffer size during query processing for each data node.
// -1 no limit (default) // -1 no limit (default)
// 0 no query allowed, queries are disabled // 0 no query allowed, queries are disabled
...@@ -200,6 +205,10 @@ char tsMonitorDbName[TSDB_DB_NAME_LEN] = "log"; ...@@ -200,6 +205,10 @@ char tsMonitorDbName[TSDB_DB_NAME_LEN] = "log";
char tsInternalPass[] = "secretkey"; char tsInternalPass[] = "secretkey";
int32_t tsMonitorInterval = 30; // seconds int32_t tsMonitorInterval = 30; // seconds
// audit
int8_t tsEnableAudit = 0;
char tsAuditDbName[TSDB_DB_NAME_LEN] = "audit";
// stream // stream
int8_t tsEnableStream = 1; int8_t tsEnableStream = 1;
...@@ -273,6 +282,7 @@ int32_t cqDebugFlag = 131; ...@@ -273,6 +282,7 @@ int32_t cqDebugFlag = 131;
int32_t fsDebugFlag = 135; int32_t fsDebugFlag = 135;
int8_t tsClientMerge = 0; int8_t tsClientMerge = 0;
int8_t tsAggAlways = 0; // Agg function always return value even if zero row
// probe alive connection // probe alive connection
int32_t tsProbeSeconds = 5 * 60; // start probe link alive after tsProbeSeconds from starting query int32_t tsProbeSeconds = 5 * 60; // start probe link alive after tsProbeSeconds from starting query
...@@ -1286,6 +1296,16 @@ static void doInitGlobalConfig(void) { ...@@ -1286,6 +1296,16 @@ static void doInitGlobalConfig(void) {
cfg.unitType = TAOS_CFG_UTYPE_NONE; cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg); taosInitConfigOption(cfg);
cfg.option = "audit";
cfg.ptr = &tsEnableAudit;
cfg.valType = TAOS_CFG_VTYPE_INT8;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
cfg.minValue = 0;
cfg.maxValue = 1;
cfg.ptrLength = 1;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
cfg.option = "stream"; cfg.option = "stream";
cfg.ptr = &tsEnableStream; cfg.ptr = &tsEnableStream;
cfg.valType = TAOS_CFG_VTYPE_INT8; cfg.valType = TAOS_CFG_VTYPE_INT8;
...@@ -1690,6 +1710,16 @@ static void doInitGlobalConfig(void) { ...@@ -1690,6 +1710,16 @@ static void doInitGlobalConfig(void) {
cfg.unitType = TAOS_CFG_UTYPE_NONE; cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg); taosInitConfigOption(cfg);
cfg.option = "aggAlways";
cfg.ptr = &tsAggAlways;
cfg.valType = TAOS_CFG_VTYPE_INT8;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT;
cfg.minValue = 0;
cfg.maxValue = 1;
cfg.ptrLength = 1;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
// default JSON string type option "binary"/"nchar" // default JSON string type option "binary"/"nchar"
cfg.option = "defaultJSONStrType"; cfg.option = "defaultJSONStrType";
cfg.ptr = tsDefaultJSONStrType; cfg.ptr = tsDefaultJSONStrType;
...@@ -1849,6 +1879,37 @@ static void doInitGlobalConfig(void) { ...@@ -1849,6 +1879,37 @@ static void doInitGlobalConfig(void) {
cfg.ptrLength = 0; cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE; cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg); taosInitConfigOption(cfg);
cfg.option = "writeBatchThreadLocal";
cfg.ptr = &tsWriteBatchThreadLocal;
cfg.valType = TAOS_CFG_VTYPE_INT8;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT;
cfg.minValue = 0;
cfg.maxValue = 1;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
cfg.option = "writeBatchSize";
cfg.ptr = &tsWriteBatchSize;
cfg.valType = TAOS_CFG_VTYPE_INT32;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT;
cfg.minValue = 0;
cfg.maxValue = 4096;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
cfg.option = "writeBatchTimeout";
cfg.ptr = &tsWriteBatchTimeout;
cfg.valType = TAOS_CFG_VTYPE_INT32;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT;
cfg.minValue = 1;
cfg.maxValue = 2048;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
assert(tsGlobalConfigNum == TSDB_CFG_MAX_NUM); assert(tsGlobalConfigNum == TSDB_CFG_MAX_NUM);
#else #else
// if TD_TSZ macro define, have 5 count configs, so must add 5 // if TD_TSZ macro define, have 5 count configs, so must add 5
......
...@@ -27,6 +27,27 @@ extern "C" { ...@@ -27,6 +27,27 @@ extern "C" {
monSaveDnodeLog(level, __VA_ARGS__); \ monSaveDnodeLog(level, __VA_ARGS__); \
} }
typedef enum {
// create
MON_DDL_CMD_CREATE_DATABASE,
MON_DDL_CMD_CREATE_TABLE,
MON_DDL_CMD_CREATE_CHILD_TABLE,
MON_DDL_CMD_CREATE_SUPER_TABLE,
// drop
MON_DDL_CMD_DROP_DATABASE,
MON_DDL_CMD_DROP_TABLE,
MON_DDL_CMD_DROP_CHILD_TABLE,
MON_DDL_CMD_DROP_SUPER_TABLE,
// alter
MON_DDL_CMD_ALTER_DATABASE,
MON_DDL_CMD_ADD_COLUMN,
MON_DDL_CMD_DROP_COLUMN,
MON_DDL_CMD_MODIFY_COLUMN,
MON_DDL_CMD_ADD_TAG,
MON_DDL_CMD_DROP_TAG,
MON_DDL_CMD_CHANGE_TAG,
} EMonDDLCmdType;
typedef struct { typedef struct {
const char * name; const char * name;
int32_t code; int32_t code;
...@@ -62,6 +83,7 @@ int32_t monInitSystem(); ...@@ -62,6 +83,7 @@ int32_t monInitSystem();
int32_t monStartSystem(); int32_t monStartSystem();
void monStopSystem(); void monStopSystem();
void monCleanupSystem(); void monCleanupSystem();
void monSaveAuditLog(int8_t type, const char *user, const char *obj, bool result);
void monSaveAcctLog(SAcctMonitorObj *pMonObj); void monSaveAcctLog(SAcctMonitorObj *pMonObj);
void monSaveLog(int32_t level, const char *const format, ...); void monSaveLog(int32_t level, const char *const format, ...);
void monSaveDnodeLog(int32_t level, const char *const format, ...); void monSaveDnodeLog(int32_t level, const char *const format, ...);
......
...@@ -60,7 +60,10 @@ typedef enum { ...@@ -60,7 +60,10 @@ typedef enum {
TSDB_OPTION_TIMEZONE, TSDB_OPTION_TIMEZONE,
TSDB_OPTION_CONFIGDIR, TSDB_OPTION_CONFIGDIR,
TSDB_OPTION_SHELL_ACTIVITY_TIMER, TSDB_OPTION_SHELL_ACTIVITY_TIMER,
TSDB_MAX_OPTIONS TSDB_MAX_OPTIONS,
TSDB_WRITE_BATCH_SIZE,
TSDB_WRITE_BATCH_TIMEOUT,
TSDB_WRITE_BATCH_THREAD_LOCAL
} TSDB_OPTION; } TSDB_OPTION;
typedef struct taosField { typedef struct taosField {
......
...@@ -256,12 +256,12 @@ do { \ ...@@ -256,12 +256,12 @@ do { \
#define TSDB_VERSION_LEN 12 #define TSDB_VERSION_LEN 12
#define TSDB_LOCALE_LEN 64 #define TSDB_LOCALE_LEN 64
#define TSDB_TIMEZONE_LEN 96 #define TSDB_TIMEZONE_LEN 96
#define TSDB_LABEL_LEN 8 #define TSDB_LABEL_LEN 8
#define TSDB_CLUSTER_ID_LEN 40 #define TSDB_CLUSTER_ID_LEN 40
#define TSDB_FQDN_LEN 128 #define TSDB_FQDN_LEN 128
#define TSDB_EP_LEN (TSDB_FQDN_LEN+6) #define TSDB_EP_LEN (TSDB_FQDN_LEN+6)
#define TSDB_IPv4ADDR_LEN 16 #define TSDB_IPv4ADDR_LEN 16
#define TSDB_FILENAME_LEN 128 #define TSDB_FILENAME_LEN 128
#define TSDB_SHOW_SQL_LEN 512 #define TSDB_SHOW_SQL_LEN 512
#define TSDB_SHOW_SUBQUERY_LEN 1000 #define TSDB_SHOW_SUBQUERY_LEN 1000
...@@ -325,7 +325,7 @@ do { \ ...@@ -325,7 +325,7 @@ do { \
#define TSDB_META_COMPACT_RATIO 0 // disable tsdb meta compact by default #define TSDB_META_COMPACT_RATIO 0 // disable tsdb meta compact by default
#define TSDB_MIN_DAYS_PER_FILE 1 #define TSDB_MIN_DAYS_PER_FILE 1
#define TSDB_MAX_DAYS_PER_FILE 3650 #define TSDB_MAX_DAYS_PER_FILE 3650
#define TSDB_DEFAULT_DAYS_PER_FILE 10 #define TSDB_DEFAULT_DAYS_PER_FILE 10
#define TSDB_MIN_KEEP 1 // data in db to be reserved. #define TSDB_MIN_KEEP 1 // data in db to be reserved.
...@@ -429,7 +429,7 @@ do { \ ...@@ -429,7 +429,7 @@ do { \
#define TSDB_ORDER_ASC 1 #define TSDB_ORDER_ASC 1
#define TSDB_ORDER_DESC 2 #define TSDB_ORDER_DESC 2
#define TSDB_DEFAULT_CLUSTER_HASH_SIZE 1 #define TSDB_DEFAULT_CLUSTER_HASH_SIZE 1
#define TSDB_DEFAULT_MNODES_HASH_SIZE 5 #define TSDB_DEFAULT_MNODES_HASH_SIZE 5
#define TSDB_DEFAULT_DNODES_HASH_SIZE 10 #define TSDB_DEFAULT_DNODES_HASH_SIZE 10
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
extern "C" { extern "C" {
#endif #endif
#define WAL_SIGNATURE ((uint32_t)(0xFAFBFDFE))
#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + 16)
typedef enum { typedef enum {
TAOS_WAL_NOLOG = 0, TAOS_WAL_NOLOG = 0,
TAOS_WAL_WRITE = 1, TAOS_WAL_WRITE = 1,
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
// extern function // extern function
void insertChar(Command *cmd, char *c, int size); void insertStr(Command *cmd, char *str, int size);
typedef struct SAutoPtr { typedef struct SAutoPtr {
...@@ -337,24 +337,23 @@ int cntDel = 0; // delete byte count after next press tab ...@@ -337,24 +337,23 @@ int cntDel = 0; // delete byte count after next press tab
// show auto tab introduction // show auto tab introduction
void printfIntroduction() { void printfIntroduction() {
printf(" **************************** How To Use TAB Key ********************************\n"); printf(" ****************************** Tab Completion **********************************\n");
printf(" * TDengine Command Line supports pressing TAB key to complete word, *\n"); printf(" * The TDengine CLI supports tab completion for a variety of items, *\n");
printf(" * including database name, table name, function name and keywords. *\n"); printf(" * including database names, table names, function names and keywords. *\n");
printf(" * Press TAB key anywhere, you'll get surprise. *\n"); printf(" * The full list of shortcut keys is as follows: *\n");
printf(" * KEYBOARD SHORTCUT: *\n"); printf(" * [ TAB ] ...... complete the current word *\n");
printf(" * [ TAB ] ...... Complete the word or show help if no input *\n"); printf(" * ...... if used on a blank line, display all valid commands *\n");
printf(" * [ Ctrl + A ] ...... move cursor to [A]head of line *\n"); printf(" * [ Ctrl + A ] ...... move cursor to the st[A]rt of the line *\n");
printf(" * [ Ctrl + E ] ...... move cursor to [E]nd of line *\n"); printf(" * [ Ctrl + E ] ...... move cursor to the [E]nd of the line *\n");
printf(" * [ Ctrl + W ] ...... move cursor to line of middle *\n"); printf(" * [ Ctrl + W ] ...... move cursor to the middle of the line *\n");
printf(" * [ Ctrl + L ] ...... clean screen *\n"); printf(" * [ Ctrl + L ] ...... clear the entire screen *\n");
printf(" * [ Ctrl + K ] ...... clean after cursor *\n"); printf(" * [ Ctrl + K ] ...... clear the screen after the cursor *\n");
printf(" * [ Ctrl + U ] ...... clean before cursor *\n"); printf(" * [ Ctrl + U ] ...... clear the screen before the cursor *\n");
printf(" * *\n"); printf(" **********************************************************************************\n\n");
printf(" **********************************************************************************\n\n");
} }
void showHelp() { void showHelp() {
printf("\nThe following are supported commands for TDengine Command Line:"); printf("\nFThe TDengine CLI supports the following commands:");
printf("\n\ printf("\n\
----- A ----- \n\ ----- A ----- \n\
alter database <db_name> <db_options> \n\ alter database <db_name> <db_options> \n\
...@@ -534,26 +533,16 @@ void parseCommand(SWords * command, bool pattern) { ...@@ -534,26 +533,16 @@ void parseCommand(SWords * command, bool pattern) {
} }
// free Command // free Command
void freeCommand(SWords * command) { void freeCommand(SWords* command) {
SWord * word = command->head; SWord* item = command->head;
if (word == NULL) { // loop
return ; while (item) {
} SWord* tmp = item;
item = item->next;
// loop
while (word->next) {
SWord * tmp = word;
word = word->next;
// if malloc need free // if malloc need free
if(tmp->free && tmp->word) if (tmp->free && tmp->word) free(tmp->word);
free(tmp->word);
free(tmp); free(tmp);
} }
// if malloc need free
if(word->free && word->word)
free(word->word);
free(word);
} }
void GenerateVarType(int type, char** p, int count) { void GenerateVarType(int type, char** p, int count) {
...@@ -1088,7 +1077,7 @@ void printScreen(TAOS * con, Command * cmd, SWords * match) { ...@@ -1088,7 +1077,7 @@ void printScreen(TAOS * con, Command * cmd, SWords * match) {
} }
// insert new // insert new
insertChar(cmd, (char *)str, strLen); insertStr(cmd, (char *)str, strLen);
} }
...@@ -1179,11 +1168,11 @@ bool nextMatchCommand(TAOS * con, Command * cmd, SWords * firstMatch) { ...@@ -1179,11 +1168,11 @@ bool nextMatchCommand(TAOS * con, Command * cmd, SWords * firstMatch) {
printScreen(con, cmd, match); printScreen(con, cmd, match);
// free // free
freeCommand(input);
if (input->source) { if (input->source) {
free(input->source); free(input->source);
input->source = NULL; input->source = NULL;
} }
freeCommand(input);
free(input); free(input);
return true; return true;
...@@ -1203,7 +1192,7 @@ bool fillWithType(TAOS * con, Command * cmd, char* pre, int type) { ...@@ -1203,7 +1192,7 @@ bool fillWithType(TAOS * con, Command * cmd, char* pre, int type) {
// show // show
int count = strlen(part); int count = strlen(part);
insertChar(cmd, part, count); insertStr(cmd, part, count);
cntDel = count; // next press tab delete current append count cntDel = count; // next press tab delete current append count
free(str); free(str);
...@@ -1231,7 +1220,7 @@ bool fillTableName(TAOS * con, Command * cmd, char* pre) { ...@@ -1231,7 +1220,7 @@ bool fillTableName(TAOS * con, Command * cmd, char* pre) {
// show // show
int count = strlen(part); int count = strlen(part);
insertChar(cmd, part, count); insertStr(cmd, part, count);
cntDel = count; // next press tab delete current append count cntDel = count; // next press tab delete current append count
free(str); free(str);
...@@ -1251,7 +1240,7 @@ char * lastWord(char * p) { ...@@ -1251,7 +1240,7 @@ char * lastWord(char * p) {
char * p2 = strrchr(p, ','); char * p2 = strrchr(p, ',');
if (p1 && p2) { if (p1 && p2) {
return p1 > p2 ? p1 : p2 + 1; return p1 > p2 ? p1 + 1 : p2 + 1;
} else if (p1) { } else if (p1) {
return p1 + 1; return p1 + 1;
} else if(p2) { } else if(p2) {
...@@ -1355,7 +1344,7 @@ bool appendAfterSelect(TAOS * con, Command * cmd, char* sql, int32_t len) { ...@@ -1355,7 +1344,7 @@ bool appendAfterSelect(TAOS * con, Command * cmd, char* sql, int32_t len) {
bool fieldEnd = fieldsInputEnd(p); bool fieldEnd = fieldsInputEnd(p);
// cheeck fields input end then insert from keyword // cheeck fields input end then insert from keyword
if (fieldEnd && p[len-1] == ' ') { if (fieldEnd && p[len-1] == ' ') {
insertChar(cmd, "from", 4); insertStr(cmd, "from", 4);
free(p); free(p);
return true; return true;
} }
...@@ -1538,7 +1527,7 @@ bool matchOther(TAOS * con, Command * cmd) { ...@@ -1538,7 +1527,7 @@ bool matchOther(TAOS * con, Command * cmd) {
if (p[len - 1] == '\\') { if (p[len - 1] == '\\') {
// append '\G' // append '\G'
char a[] = "G;"; char a[] = "G;";
insertChar(cmd, a, 2); insertStr(cmd, a, 2);
return true; return true;
} }
......
...@@ -131,7 +131,7 @@ static void *shellCheckThreadFp(void *arg) { ...@@ -131,7 +131,7 @@ static void *shellCheckThreadFp(void *arg) {
char *tbname = tbNames[t]; char *tbname = tbNames[t];
if (tbname == NULL) break; if (tbname == NULL) break;
snprintf(sql, SHELL_SQL_LEN, "select count(*) from %s;", tbname); snprintf(sql, SHELL_SQL_LEN, "select last_row(_c0) from `%s`;", tbname);
TAOS_RES *pSql = taos_query(pThread->taos, sql); TAOS_RES *pSql = taos_query(pThread->taos, sql);
int32_t code = taos_errno(pSql); int32_t code = taos_errno(pSql);
......
...@@ -79,11 +79,22 @@ void insertChar(Command *cmd, char *c, int size) { ...@@ -79,11 +79,22 @@ void insertChar(Command *cmd, char *c, int size) {
/* update the values */ /* update the values */
cmd->commandSize += size; cmd->commandSize += size;
cmd->cursorOffset += size; cmd->cursorOffset += size;
for (int i = 0; i < size; i++) { cmd->screenOffset += wcwidth(wc);
mbtowc(&wc, c + i, size); cmd->endOffset += wcwidth(wc);
cmd->screenOffset += wcwidth(wc); showOnScreen(cmd);
cmd->endOffset += wcwidth(wc); }
}
void insertStr(Command *cmd, char *str, int size) {
clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size);
/* update the buffer */
memmove(cmd->command + cmd->cursorOffset + size, cmd->command + cmd->cursorOffset,
cmd->commandSize - cmd->cursorOffset);
memcpy(cmd->command + cmd->cursorOffset, str, size);
/* update the values */
cmd->commandSize += size;
cmd->cursorOffset += size;
cmd->screenOffset += size;
cmd->endOffset += size;
showOnScreen(cmd); showOnScreen(cmd);
} }
......
...@@ -192,9 +192,15 @@ static int32_t shellRunSingleCommand(TAOS *con, char *command) { ...@@ -192,9 +192,15 @@ static int32_t shellRunSingleCommand(TAOS *con, char *command) {
if (regex_match(command, "^[ \t]*source[\t ]+[^ ]+[ \t;]*$", REG_EXTENDED | REG_ICASE)) { if (regex_match(command, "^[ \t]*source[\t ]+[^ ]+[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
/* If source file. */ /* If source file. */
char *c_ptr = strtok(command, " ;"); char *c_ptr = strtok(command, " ;");
assert(c_ptr != NULL); if (c_ptr == NULL) {
shellRunCommandOnServer(con, command);
return 0;
}
c_ptr = strtok(NULL, " ;"); c_ptr = strtok(NULL, " ;");
assert(c_ptr != NULL); if (c_ptr == NULL) {
shellRunCommandOnServer(con, command);
return 0;
}
source_file(con, c_ptr); source_file(con, c_ptr);
return 0; return 0;
} }
...@@ -371,7 +377,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { ...@@ -371,7 +377,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
} else { } else {
int num_rows_affacted = taos_affected_rows(pSql); int num_rows_affacted = taos_affected_rows(pSql);
et = taosGetTimestampUs(); et = taosGetTimestampUs();
printf("Query OK, %d of %d row(s) in database (%.6fs)\n", num_rows_affacted, num_rows_affacted, (et - st) / 1E6); printf("Query OK, %d row(s) affected(%.6fs)\n", num_rows_affacted, (et - st) / 1E6);
#ifndef WINDOWS #ifndef WINDOWS
// call auto tab // call auto tab
......
...@@ -325,30 +325,26 @@ void matchPrefixFromTree(STire* tire, char* prefix, SMatch* match) { ...@@ -325,30 +325,26 @@ void matchPrefixFromTree(STire* tire, char* prefix, SMatch* match) {
} }
SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match) { SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match) {
if(match == NULL) { SMatch* rMatch = match; // define return match
match = (SMatch* )tmalloc(sizeof(SMatch)); if (rMatch == NULL) {
memset(match, 0, sizeof(SMatch)); rMatch = (SMatch*)malloc(sizeof(SMatch));
} memset(rMatch, 0, sizeof(SMatch));
}
switch (tire->type) {
case TIRE_TREE: switch (tire->type) {
matchPrefixFromTree(tire, prefix, match); case TIRE_TREE:
case TIRE_LIST: matchPrefixFromTree(tire, prefix, rMatch);
matchPrefixFromList(tire, prefix, match); break;
default: case TIRE_LIST:
break; matchPrefixFromList(tire, prefix, rMatch);
} break;
default:
// return if need break;
if (match->count == 0) { }
freeMatch(match);
match = NULL; return rMatch;
}
return match;
} }
// get all items from tires tree // get all items from tires tree
void enumFromList(STire* tire, SMatch* match) { void enumFromList(STire* tire, SMatch* match) {
StrName * item = tire->head; StrName * item = tire->head;
...@@ -395,8 +391,10 @@ SMatch* enumAll(STire* tire) { ...@@ -395,8 +391,10 @@ SMatch* enumAll(STire* tire) {
switch (tire->type) { switch (tire->type) {
case TIRE_TREE: case TIRE_TREE:
enumFromTree(tire, match); enumFromTree(tire, match);
break;
case TIRE_LIST: case TIRE_LIST:
enumFromList(tire, match); enumFromList(tire, match);
break;
default: default:
break; break;
} }
......
Subproject commit 85179e99785182bb630832216f887ef84ca23474 Subproject commit 64350feba73d584f920474d8abcd913491081897
...@@ -57,7 +57,7 @@ typedef struct SDnodeObj { ...@@ -57,7 +57,7 @@ typedef struct SDnodeObj {
int8_t alternativeRole; // from dnode status msg, 0-any, 1-mgmt, 2-dnode int8_t alternativeRole; // from dnode status msg, 0-any, 1-mgmt, 2-dnode
int8_t status; // set in balance function int8_t status; // set in balance function
int8_t isMgmt; int8_t isMgmt;
int8_t reserve1[11]; int8_t reserve1[11];
int8_t updateEnd[4]; int8_t updateEnd[4];
int32_t refCount; int32_t refCount;
uint32_t moduleStatus; uint32_t moduleStatus;
...@@ -90,7 +90,7 @@ typedef struct STableObj { ...@@ -90,7 +90,7 @@ typedef struct STableObj {
} STableObj; } STableObj;
typedef struct SSTableObj { typedef struct SSTableObj {
STableObj info; STableObj info;
int8_t reserved0[9]; // for fill struct STableObj to 4byte align int8_t reserved0[9]; // for fill struct STableObj to 4byte align
int16_t nextColId; int16_t nextColId;
int32_t sversion; int32_t sversion;
...@@ -107,10 +107,10 @@ typedef struct SSTableObj { ...@@ -107,10 +107,10 @@ typedef struct SSTableObj {
} SSTableObj; } SSTableObj;
typedef struct { typedef struct {
STableObj info; STableObj info;
int8_t reserved0[9]; // for fill struct STableObj to 4byte align int8_t reserved0[9]; // for fill struct STableObj to 4byte align
int16_t nextColId; //used by normal table int16_t nextColId; //used by normal table
int32_t sversion; //used by normal table int32_t sversion; //used by normal table
uint64_t uid; uint64_t uid;
uint64_t suid; uint64_t suid;
int64_t createdTime; int64_t createdTime;
...@@ -195,7 +195,7 @@ typedef struct SDbObj { ...@@ -195,7 +195,7 @@ typedef struct SDbObj {
int32_t numOfVgroups; int32_t numOfVgroups;
int32_t numOfTables; int32_t numOfTables;
int32_t numOfSuperTables; int32_t numOfSuperTables;
int32_t vgListSize; int32_t vgListSize;
int32_t vgListIndex; int32_t vgListIndex;
SVgObj **vgList; SVgObj **vgList;
struct SAcctObj *pAcct; struct SAcctObj *pAcct;
......
...@@ -160,7 +160,7 @@ static int32_t mnodeDbActionEncode(SSdbRow *pRow) { ...@@ -160,7 +160,7 @@ static int32_t mnodeDbActionEncode(SSdbRow *pRow) {
static int32_t mnodeDbActionDecode(SSdbRow *pRow) { static int32_t mnodeDbActionDecode(SSdbRow *pRow) {
SDbObj *pDb = (SDbObj *) calloc(1, sizeof(SDbObj)); SDbObj *pDb = (SDbObj *) calloc(1, sizeof(SDbObj));
if (pDb == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; if (pDb == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
memcpy(pDb, pRow->rowData, tsDbUpdateSize); memcpy(pDb, pRow->rowData, tsDbUpdateSize);
pRow->pObj = pDb; pRow->pObj = pDb;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -205,8 +205,8 @@ int32_t mnodeInitDbs() { ...@@ -205,8 +205,8 @@ int32_t mnodeInitDbs() {
mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_DB, mnodeGetDbMeta); mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_DB, mnodeGetDbMeta);
mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_DB, mnodeRetrieveDbs); mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_DB, mnodeRetrieveDbs);
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_DB, mnodeCancelGetNextDb); mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_DB, mnodeCancelGetNextDb);
mDebug("table:dbs table is created"); mDebug("table:dbs table is created");
return tpInit(); return tpInit();
} }
...@@ -224,11 +224,11 @@ SDbObj *mnodeGetDb(char *db) { ...@@ -224,11 +224,11 @@ SDbObj *mnodeGetDb(char *db) {
} }
void mnodeIncDbRef(SDbObj *pDb) { void mnodeIncDbRef(SDbObj *pDb) {
sdbIncRef(tsDbSdb, pDb); sdbIncRef(tsDbSdb, pDb);
} }
void mnodeDecDbRef(SDbObj *pDb) { void mnodeDecDbRef(SDbObj *pDb) {
sdbDecRef(tsDbSdb, pDb); sdbDecRef(tsDbSdb, pDb);
} }
SDbObj *mnodeGetDbByTableName(char *tableName) { SDbObj *mnodeGetDbByTableName(char *tableName) {
...@@ -409,6 +409,7 @@ static int32_t mnodeCreateDbCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -409,6 +409,7 @@ static int32_t mnodeCreateDbCb(SMnodeMsg *pMsg, int32_t code) {
} else { } else {
mError("db:%s, failed to create by %s, reason:%s", pDb->name, mnodeGetUserFromMsg(pMsg), tstrerror(code)); mError("db:%s, failed to create by %s, reason:%s", pDb->name, mnodeGetUserFromMsg(pMsg), tstrerror(code));
} }
monSaveAuditLog(MON_DDL_CMD_CREATE_DATABASE, mnodeGetUserFromMsg(pMsg), pDb->name, !code);
return code; return code;
} }
...@@ -419,7 +420,7 @@ static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg * ...@@ -419,7 +420,7 @@ static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg *
SDbObj *pDb = mnodeGetDb(pCreate->db); SDbObj *pDb = mnodeGetDb(pCreate->db);
if (pDb != NULL) { if (pDb != NULL) {
mnodeDecDbRef(pDb); mnodeDecDbRef(pDb);
if (pCreate->ignoreExist) { if (pCreate->ignoreExist) {
mDebug("db:%s, already exist, ignore exist is set", pCreate->db); mDebug("db:%s, already exist, ignore exist is set", pCreate->db);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -434,8 +435,8 @@ static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg * ...@@ -434,8 +435,8 @@ static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg *
pDb = calloc(1, sizeof(SDbObj)); pDb = calloc(1, sizeof(SDbObj));
tstrncpy(pDb->name, pCreate->db, sizeof(pDb->name)); tstrncpy(pDb->name, pCreate->db, sizeof(pDb->name));
tstrncpy(pDb->acct, pAcct->user, sizeof(pDb->acct)); tstrncpy(pDb->acct, pAcct->user, sizeof(pDb->acct));
pDb->createdTime = taosGetTimestampMs(); pDb->createdTime = taosGetTimestampMs();
pDb->cfg = (SDbCfg) { pDb->cfg = (SDbCfg) {
.cacheBlockSize = pCreate->cacheBlockSize, .cacheBlockSize = pCreate->cacheBlockSize,
.totalBlocks = pCreate->totalBlocks, .totalBlocks = pCreate->totalBlocks,
...@@ -499,7 +500,7 @@ bool mnodeCheckIsMonitorDB(char *db, char *monitordb) { ...@@ -499,7 +500,7 @@ bool mnodeCheckIsMonitorDB(char *db, char *monitordb) {
#if 0 #if 0
void mnodePrintVgroups(SDbObj *pDb, char *row) { void mnodePrintVgroups(SDbObj *pDb, char *row) {
mInfo("db:%s, vgroup link from head, row:%s", pDb->name, row); mInfo("db:%s, vgroup link from head, row:%s", pDb->name, row);
SVgObj *pVgroup = pDb->pHead; SVgObj *pVgroup = pDb->pHead;
while (pVgroup != NULL) { while (pVgroup != NULL) {
mInfo("vgId:%d", pVgroup->vgId); mInfo("vgId:%d", pVgroup->vgId);
...@@ -621,7 +622,7 @@ static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn ...@@ -621,7 +622,7 @@ static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn
pShow->bytes[cols] = 24 + VARSTR_HEADER_SIZE; pShow->bytes[cols] = 24 + VARSTR_HEADER_SIZE;
pSchema[cols].type = TSDB_DATA_TYPE_BINARY; pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
#ifdef _STORAGE #ifdef _STORAGE
strcpy(pSchema[cols].name, "keep0,keep1,keep2"); strcpy(pSchema[cols].name, "keep0,keep1,keep2");
#else #else
strcpy(pSchema[cols].name, "keep"); strcpy(pSchema[cols].name, "keep");
...@@ -638,13 +639,13 @@ static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn ...@@ -638,13 +639,13 @@ static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn
strcpy(pSchema[cols].name, "cache(MB)"); strcpy(pSchema[cols].name, "cache(MB)");
pSchema[cols].bytes = htons(pShow->bytes[cols]); pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++; cols++;
pShow->bytes[cols] = 4; pShow->bytes[cols] = 4;
pSchema[cols].type = TSDB_DATA_TYPE_INT; pSchema[cols].type = TSDB_DATA_TYPE_INT;
strcpy(pSchema[cols].name, "blocks"); strcpy(pSchema[cols].name, "blocks");
pSchema[cols].bytes = htons(pShow->bytes[cols]); pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++; cols++;
pShow->bytes[cols] = 4; pShow->bytes[cols] = 4;
pSchema[cols].type = TSDB_DATA_TYPE_INT; pSchema[cols].type = TSDB_DATA_TYPE_INT;
strcpy(pSchema[cols].name, "minrows"); strcpy(pSchema[cols].name, "minrows");
...@@ -743,7 +744,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void ...@@ -743,7 +744,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
cols = 0; cols = 0;
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
char* name = mnodeGetDbStr(pDb->name); char* name = mnodeGetDbStr(pDb->name);
if (name != NULL) { if (name != NULL) {
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, name, pShow->bytes[cols]); STR_WITH_MAXSIZE_TO_VARSTR(pWrite, name, pShow->bytes[cols]);
...@@ -789,10 +790,10 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void ...@@ -789,10 +790,10 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
#endif #endif
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
char tmp[128] = {0}; char tmp[128] = {0};
#ifdef _STORAGE #ifdef _STORAGE
if (pDb->cfg.daysToKeep0 > pDb->cfg.daysToKeep1 || pDb->cfg.daysToKeep0 > pDb->cfg.daysToKeep2) { if (pDb->cfg.daysToKeep0 > pDb->cfg.daysToKeep1 || pDb->cfg.daysToKeep0 > pDb->cfg.daysToKeep2) {
sprintf(tmp, "%d,%d,%d", pDb->cfg.daysToKeep1, pDb->cfg.daysToKeep2, pDb->cfg.daysToKeep0); sprintf(tmp, "%d,%d,%d", pDb->cfg.daysToKeep1, pDb->cfg.daysToKeep2, pDb->cfg.daysToKeep0);
} else { } else {
sprintf(tmp, "%d,%d,%d", pDb->cfg.daysToKeep0, pDb->cfg.daysToKeep1, pDb->cfg.daysToKeep2); sprintf(tmp, "%d,%d,%d", pDb->cfg.daysToKeep0, pDb->cfg.daysToKeep1, pDb->cfg.daysToKeep2);
...@@ -821,7 +822,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void ...@@ -821,7 +822,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
*(int32_t *)pWrite = pDb->cfg.maxRowsPerFileBlock; *(int32_t *)pWrite = pDb->cfg.maxRowsPerFileBlock;
cols++; cols++;
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
*(int8_t *)pWrite = pDb->cfg.walLevel; *(int8_t *)pWrite = pDb->cfg.walLevel;
cols++; cols++;
...@@ -912,7 +913,7 @@ static int32_t mnodeSetDbDropping(SDbObj *pDb) { ...@@ -912,7 +913,7 @@ static int32_t mnodeSetDbDropping(SDbObj *pDb) {
} }
static int32_t mnodeProcessCreateDbMsg(SMnodeMsg *pMsg) { static int32_t mnodeProcessCreateDbMsg(SMnodeMsg *pMsg) {
SCreateDbMsg *pCreate = pMsg->rpcMsg.pCont; SCreateDbMsg *pCreate = pMsg->rpcMsg.pCont;
pCreate->maxTables = htonl(pCreate->maxTables); pCreate->maxTables = htonl(pCreate->maxTables);
pCreate->cacheBlockSize = htonl(pCreate->cacheBlockSize); pCreate->cacheBlockSize = htonl(pCreate->cacheBlockSize);
pCreate->totalBlocks = htonl(pCreate->totalBlocks); pCreate->totalBlocks = htonl(pCreate->totalBlocks);
...@@ -925,7 +926,7 @@ static int32_t mnodeProcessCreateDbMsg(SMnodeMsg *pMsg) { ...@@ -925,7 +926,7 @@ static int32_t mnodeProcessCreateDbMsg(SMnodeMsg *pMsg) {
pCreate->partitions = htons(pCreate->partitions); pCreate->partitions = htons(pCreate->partitions);
pCreate->minRowsPerFileBlock = htonl(pCreate->minRowsPerFileBlock); pCreate->minRowsPerFileBlock = htonl(pCreate->minRowsPerFileBlock);
pCreate->maxRowsPerFileBlock = htonl(pCreate->maxRowsPerFileBlock); pCreate->maxRowsPerFileBlock = htonl(pCreate->maxRowsPerFileBlock);
int32_t code; int32_t code;
#ifdef GRANT_CHECK_WRITE #ifdef GRANT_CHECK_WRITE
if (grantCheck(TSDB_GRANT_TIME) != TSDB_CODE_SUCCESS) { if (grantCheck(TSDB_GRANT_TIME) != TSDB_CODE_SUCCESS) {
...@@ -963,7 +964,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) { ...@@ -963,7 +964,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
int8_t cacheLastRow = pAlter->cacheLastRow; int8_t cacheLastRow = pAlter->cacheLastRow;
int8_t dbType = pAlter->dbType; int8_t dbType = pAlter->dbType;
int16_t partitions = htons(pAlter->partitions); int16_t partitions = htons(pAlter->partitions);
terrno = TSDB_CODE_SUCCESS; terrno = TSDB_CODE_SUCCESS;
//UPGRATE FROM LOW VERSION, reorder it //UPGRATE FROM LOW VERSION, reorder it
...@@ -1013,9 +1014,9 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) { ...@@ -1013,9 +1014,9 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
newCfg.daysToKeep2 = daysToKeep2; newCfg.daysToKeep2 = daysToKeep2;
} }
if (minRows > 0 && minRows != pDb->cfg.minRowsPerFileBlock) { if (minRows >= 0 && minRows != pDb->cfg.minRowsPerFileBlock) {
mError("db:%s, can't alter minRows option", pDb->name); mDebug("db:%s, minRows:%d change to %d", pDb->name, pDb->cfg.minRowsPerFileBlock, minRows);
terrno = TSDB_CODE_MND_INVALID_DB_OPTION; newCfg.minRowsPerFileBlock = minRows;
} }
if (maxRows > 0 && maxRows != pDb->cfg.maxRowsPerFileBlock) { if (maxRows > 0 && maxRows != pDb->cfg.maxRowsPerFileBlock) {
...@@ -1127,6 +1128,8 @@ static int32_t mnodeAlterDbFp(SMnodeMsg *pMsg) { ...@@ -1127,6 +1128,8 @@ static int32_t mnodeAlterDbFp(SMnodeMsg *pMsg) {
mDebug("db:%s, all vgroups is altered", pDb->name); mDebug("db:%s, all vgroups is altered", pDb->name);
mLInfo("db:%s, is alterd by %s", pDb->name, mnodeGetUserFromMsg(pMsg)); mLInfo("db:%s, is alterd by %s", pDb->name, mnodeGetUserFromMsg(pMsg));
monSaveAuditLog(MON_DDL_CMD_ALTER_DATABASE, mnodeGetUserFromMsg(pMsg), pDb->name, true);
// in case there is no vnode for this db currently(no table in db,etc.) // in case there is no vnode for this db currently(no table in db,etc.)
if (pMsg->expected == 0) { if (pMsg->expected == 0) {
SSdbRow row = { SSdbRow row = {
...@@ -1183,7 +1186,7 @@ static int32_t mnodeAlterDb(SDbObj *pDb, SAlterDbMsg *pAlter, void *pMsg) { ...@@ -1183,7 +1186,7 @@ static int32_t mnodeAlterDb(SDbObj *pDb, SAlterDbMsg *pAlter, void *pMsg) {
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
mError("db:%s, failed to alter, reason:%s", pDb->name, tstrerror(code)); mError("db:%s, failed to alter, reason:%s", pDb->name, tstrerror(code));
} }
} }
return code; return code;
} }
...@@ -1197,7 +1200,7 @@ int32_t mnodeProcessAlterDbMsg(SMnodeMsg *pMsg) { ...@@ -1197,7 +1200,7 @@ int32_t mnodeProcessAlterDbMsg(SMnodeMsg *pMsg) {
mError("db:%s, failed to alter, invalid db", pAlter->db); mError("db:%s, failed to alter, invalid db", pAlter->db);
return TSDB_CODE_MND_INVALID_DB; return TSDB_CODE_MND_INVALID_DB;
} }
if (pMsg->pDb->status != TSDB_DB_STATUS_READY) { if (pMsg->pDb->status != TSDB_DB_STATUS_READY) {
mError("db:%s, status:%d, in dropping", pAlter->db, pMsg->pDb->status); mError("db:%s, status:%d, in dropping", pAlter->db, pMsg->pDb->status);
return TSDB_CODE_MND_DB_IN_DROPPING; return TSDB_CODE_MND_DB_IN_DROPPING;
...@@ -1213,13 +1216,14 @@ static int32_t mnodeDropDbCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1213,13 +1216,14 @@ static int32_t mnodeDropDbCb(SMnodeMsg *pMsg, int32_t code) {
} else { } else {
mLInfo("db:%s, is dropped by %s", pDb->name, mnodeGetUserFromMsg(pMsg)); mLInfo("db:%s, is dropped by %s", pDb->name, mnodeGetUserFromMsg(pMsg));
} }
monSaveAuditLog(MON_DDL_CMD_DROP_DATABASE, mnodeGetUserFromMsg(pMsg), pDb->name, !code);
return code; return code;
} }
static int32_t mnodeDropDb(SMnodeMsg *pMsg) { static int32_t mnodeDropDb(SMnodeMsg *pMsg) {
if (pMsg == NULL) return TSDB_CODE_MND_APP_ERROR; if (pMsg == NULL) return TSDB_CODE_MND_APP_ERROR;
SDbObj *pDb = pMsg->pDb; SDbObj *pDb = pMsg->pDb;
mInfo("db:%s, drop db from sdb", pDb->name); mInfo("db:%s, drop db from sdb", pDb->name);
...@@ -1259,7 +1263,7 @@ static int32_t mnodeProcessDropDbMsg(SMnodeMsg *pMsg) { ...@@ -1259,7 +1263,7 @@ static int32_t mnodeProcessDropDbMsg(SMnodeMsg *pMsg) {
mError("db:%s, can't drop monitor database", pDrop->db); mError("db:%s, can't drop monitor database", pDrop->db);
return TSDB_CODE_MND_MONITOR_DB_FORBIDDEN; return TSDB_CODE_MND_MONITOR_DB_FORBIDDEN;
} }
#endif #endif
int32_t code = mnodeSetDbDropping(pMsg->pDb); int32_t code = mnodeSetDbDropping(pMsg->pDb);
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
...@@ -1292,15 +1296,15 @@ static int32_t mnodeSyncDb(SDbObj *pDb, SMnodeMsg *pMsg) { ...@@ -1292,15 +1296,15 @@ static int32_t mnodeSyncDb(SDbObj *pDb, SMnodeMsg *pMsg) {
static int32_t mnodeCompact(SDbObj *pDb, SCompactMsg *pCompactMsg) { static int32_t mnodeCompact(SDbObj *pDb, SCompactMsg *pCompactMsg) {
int32_t count = ntohs(pCompactMsg->numOfVgroup); int32_t count = ntohs(pCompactMsg->numOfVgroup);
int32_t *buf = malloc(sizeof(int32_t) * count); int32_t *buf = malloc(sizeof(int32_t) * count);
if (buf == NULL) { if (buf == NULL) {
return TSDB_CODE_MND_OUT_OF_MEMORY; return TSDB_CODE_MND_OUT_OF_MEMORY;
} }
for (int32_t i = 0; i < count; i++) { for (int32_t i = 0; i < count; i++) {
buf[i] = ntohs(pCompactMsg->vgid[i]); buf[i] = ntohs(pCompactMsg->vgid[i]);
} }
// copy from mnodeSyncDb, so ugly // copy from mnodeSyncDb, so ugly
for (int32_t i = 0; i < count; i++) { for (int32_t i = 0; i < count; i++) {
SVgObj *pVgroup = NULL; SVgObj *pVgroup = NULL;
...@@ -1312,7 +1316,7 @@ static int32_t mnodeCompact(SDbObj *pDb, SCompactMsg *pCompactMsg) { ...@@ -1312,7 +1316,7 @@ static int32_t mnodeCompact(SDbObj *pDb, SCompactMsg *pCompactMsg) {
if (pVgroup->pDb == pDb && pVgroup->vgId == buf[i]) { if (pVgroup->pDb == pDb && pVgroup->vgId == buf[i]) {
mnodeSendCompactVgroupMsg(pVgroup); mnodeSendCompactVgroupMsg(pVgroup);
mnodeDecVgroupRef(pVgroup); mnodeDecVgroupRef(pVgroup);
valid = true; valid = true;
break; break;
} }
mnodeDecVgroupRef(pVgroup); mnodeDecVgroupRef(pVgroup);
...@@ -1321,7 +1325,7 @@ static int32_t mnodeCompact(SDbObj *pDb, SCompactMsg *pCompactMsg) { ...@@ -1321,7 +1325,7 @@ static int32_t mnodeCompact(SDbObj *pDb, SCompactMsg *pCompactMsg) {
mLError("db:%s, cannot find valid vgId: %d", pDb->name, buf[i]); mLError("db:%s, cannot find valid vgId: %d", pDb->name, buf[i]);
} }
} }
free(buf); free(buf);
mLInfo("db:%s, trigger compact", pDb->name); mLInfo("db:%s, trigger compact", pDb->name);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -1352,14 +1356,14 @@ static int32_t mnodeProcessSyncDbMsg(SMnodeMsg *pMsg) { ...@@ -1352,14 +1356,14 @@ static int32_t mnodeProcessSyncDbMsg(SMnodeMsg *pMsg) {
static int32_t mnodeProcessCompactMsg(SMnodeMsg *pMsg) { static int32_t mnodeProcessCompactMsg(SMnodeMsg *pMsg) {
SCompactMsg *pCompact = pMsg->rpcMsg.pCont; SCompactMsg *pCompact = pMsg->rpcMsg.pCont;
mDebug("db:%s, compact is received from thandle:%p", pCompact->db, pMsg->rpcMsg.handle); mDebug("db:%s, compact is received from thandle:%p", pCompact->db, pMsg->rpcMsg.handle);
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pCompact->db); if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pCompact->db);
if (pMsg->pDb == NULL) return TSDB_CODE_MND_DB_NOT_SELECTED; if (pMsg->pDb == NULL) return TSDB_CODE_MND_DB_NOT_SELECTED;
if (pMsg->pDb->status != TSDB_DB_STATUS_READY) { if (pMsg->pDb->status != TSDB_DB_STATUS_READY) {
mError("db:%s, status:%d, in dropping, ignore compact request", pCompact->db, pMsg->pDb->status); mError("db:%s, status:%d, in dropping, ignore compact request", pCompact->db, pMsg->pDb->status);
return TSDB_CODE_MND_DB_IN_DROPPING; return TSDB_CODE_MND_DB_IN_DROPPING;
} }
return mnodeCompact(pMsg->pDb, pCompact); return mnodeCompact(pMsg->pDb, pCompact);
} }
...@@ -1382,7 +1386,7 @@ void mnodeDropAllDbs(SAcctObj *pAcct) { ...@@ -1382,7 +1386,7 @@ void mnodeDropAllDbs(SAcctObj *pAcct) {
.pTable = tsDbSdb, .pTable = tsDbSdb,
.pObj = pDb .pObj = pDb
}; };
sdbDeleteRow(&row); sdbDeleteRow(&row);
numOfDbs++; numOfDbs++;
} }
...@@ -1410,11 +1414,11 @@ int32_t mnodeCompactDbs() { ...@@ -1410,11 +1414,11 @@ int32_t mnodeCompactDbs() {
}; };
mInfo("compact dbs %s", pDb->name); mInfo("compact dbs %s", pDb->name);
sdbInsertCompactRow(&row); sdbInsertCompactRow(&row);
} }
mInfo("end to compact dbs table..."); mInfo("end to compact dbs table...");
return 0; return 0;
} }
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "mnodeSdb.h" #include "mnodeSdb.h"
#include "mnodeShow.h" #include "mnodeShow.h"
#include "mnodeTable.h" #include "mnodeTable.h"
#include "mnodeUser.h"
#include "mnodeVgroup.h" #include "mnodeVgroup.h"
#include "mnodeWrite.h" #include "mnodeWrite.h"
#include "mnodeRead.h" #include "mnodeRead.h"
...@@ -1047,7 +1048,7 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1047,7 +1048,7 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) {
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
mLInfo("stable:%s, is created in sdb, uid:%" PRIu64, pTable->info.tableId, pTable->uid); mLInfo("stable:%s, is created in sdb, uid:%" PRIu64, pTable->info.tableId, pTable->uid);
if(pMsg->pBatchMasterMsg) if(pMsg->pBatchMasterMsg)
pMsg->pBatchMasterMsg->successed ++; pMsg->pBatchMasterMsg->successed ++;
} else { } else {
mError("msg:%p, app:%p stable:%s, failed to create in sdb, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, mError("msg:%p, app:%p stable:%s, failed to create in sdb, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId,
tstrerror(code)); tstrerror(code));
...@@ -1056,11 +1057,12 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1056,11 +1057,12 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) {
if(pMsg->pBatchMasterMsg) if(pMsg->pBatchMasterMsg)
pMsg->pBatchMasterMsg->received ++; pMsg->pBatchMasterMsg->received ++;
} }
monSaveAuditLog(MON_DDL_CMD_CREATE_SUPER_TABLE, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, !code);
// if super table create by batch msg, check done and send finished to client // if super table create by batch msg, check done and send finished to client
if(pMsg->pBatchMasterMsg) { if(pMsg->pBatchMasterMsg) {
if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected) if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected)
dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code); dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code);
} }
return code; return code;
...@@ -1171,11 +1173,12 @@ static int32_t mnodeDropSuperTableCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1171,11 +1173,12 @@ static int32_t mnodeDropSuperTableCb(SMnodeMsg *pMsg, int32_t code) {
SSTableObj *pTable = (SSTableObj *)pMsg->pTable; SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
mError("msg:%p, app:%p stable:%s, failed to drop, sdb error", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); mError("msg:%p, app:%p stable:%s, failed to drop, sdb error", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId);
monSaveAuditLog(MON_DDL_CMD_DROP_SUPER_TABLE, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, false);
return code; return code;
} }
mLInfo("msg:%p, app:%p stable:%s, is dropped from sdb", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); mLInfo("msg:%p, app:%p stable:%s, is dropped from sdb", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId);
monSaveAuditLog(MON_DDL_CMD_DROP_SUPER_TABLE, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, true);
SSTableObj *pStable = (SSTableObj *)pMsg->pTable; SSTableObj *pStable = (SSTableObj *)pMsg->pTable;
if (pStable->vgHash != NULL /*pStable->numOfTables != 0*/) { if (pStable->vgHash != NULL /*pStable->numOfTables != 0*/) {
...@@ -1250,6 +1253,8 @@ static int32_t mnodeAddSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1250,6 +1253,8 @@ static int32_t mnodeAddSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) {
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = mnodeGetSuperTableMeta(pMsg); code = mnodeGetSuperTableMeta(pMsg);
} }
monSaveAuditLog(MON_DDL_CMD_ADD_TAG, mnodeGetUserFromMsg(pMsg), pStable->info.tableId, !code);
return code; return code;
} }
...@@ -1308,6 +1313,8 @@ static int32_t mnodeDropSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1308,6 +1313,8 @@ static int32_t mnodeDropSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) {
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = mnodeGetSuperTableMeta(pMsg); code = mnodeGetSuperTableMeta(pMsg);
} }
monSaveAuditLog(MON_DDL_CMD_DROP_TAG, mnodeGetUserFromMsg(pMsg), pStable->info.tableId, !code);
return code; return code;
} }
...@@ -1345,6 +1352,8 @@ static int32_t mnodeModifySuperTableTagNameCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1345,6 +1352,8 @@ static int32_t mnodeModifySuperTableTagNameCb(SMnodeMsg *pMsg, int32_t code) {
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = mnodeGetSuperTableMeta(pMsg); code = mnodeGetSuperTableMeta(pMsg);
} }
monSaveAuditLog(MON_DDL_CMD_CHANGE_TAG, mnodeGetUserFromMsg(pMsg), pStable->info.tableId, !code);
return code; return code;
} }
...@@ -1403,6 +1412,8 @@ static int32_t mnodeAddSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1403,6 +1412,8 @@ static int32_t mnodeAddSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) {
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = mnodeGetSuperTableMeta(pMsg); code = mnodeGetSuperTableMeta(pMsg);
} }
monSaveAuditLog(MON_DDL_CMD_ADD_COLUMN, mnodeGetUserFromMsg(pMsg), pStable->info.tableId, !code);
return code; return code;
} }
...@@ -1474,6 +1485,8 @@ static int32_t mnodeDropSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1474,6 +1485,8 @@ static int32_t mnodeDropSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) {
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = mnodeGetSuperTableMeta(pMsg); code = mnodeGetSuperTableMeta(pMsg);
} }
monSaveAuditLog(MON_DDL_CMD_DROP_COLUMN, mnodeGetUserFromMsg(pMsg), pStable->info.tableId, !code);
return code; return code;
} }
...@@ -1522,6 +1535,8 @@ static int32_t mnodeChangeSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -1522,6 +1535,8 @@ static int32_t mnodeChangeSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) {
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = mnodeGetSuperTableMeta(pMsg); code = mnodeGetSuperTableMeta(pMsg);
} }
monSaveAuditLog(MON_DDL_CMD_MODIFY_COLUMN, mnodeGetUserFromMsg(pMsg), pStable->info.tableId, !code);
return code; return code;
} }
...@@ -2073,6 +2088,9 @@ static int32_t mnodeDoCreateChildTableCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -2073,6 +2088,9 @@ static int32_t mnodeDoCreateChildTableCb(SMnodeMsg *pMsg, int32_t code) {
SCreateTableMsg *pCreate = (SCreateTableMsg*) ((char*)pMsg->rpcMsg.pCont + sizeof(SCMCreateTableMsg)); SCreateTableMsg *pCreate = (SCreateTableMsg*) ((char*)pMsg->rpcMsg.pCont + sizeof(SCMCreateTableMsg));
assert(pTable); assert(pTable);
monSaveAuditLog((pTable->info.type == TSDB_CHILD_TABLE) ? MON_DDL_CMD_CREATE_CHILD_TABLE : MON_DDL_CMD_CREATE_TABLE,
mnodeGetUserFromMsg(pMsg), pTable->info.tableId, !code);
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
if (pCreate->getMeta) { if (pCreate->getMeta) {
mDebug("msg:%p, app:%p table:%s, created in dnode and continue to get meta, thandle:%p", pMsg, mDebug("msg:%p, app:%p table:%s, created in dnode and continue to get meta, thandle:%p", pMsg,
...@@ -2101,6 +2119,7 @@ static int32_t mnodeDoCreateChildTableCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -2101,6 +2119,7 @@ static int32_t mnodeDoCreateChildTableCb(SMnodeMsg *pMsg, int32_t code) {
} else { } else {
mError("msg:%p, app:%p table:%s, failed to create table sid:%d, uid:%" PRIu64 ", reason:%s", pMsg, mError("msg:%p, app:%p table:%s, failed to create table sid:%d, uid:%" PRIu64 ", reason:%s", pMsg,
pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->tid, pTable->uid, tstrerror(code)); pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->tid, pTable->uid, tstrerror(code));
SSdbRow desc = {.type = SDB_OPER_GLOBAL, .pObj = pTable, .pTable = tsChildTableSdb}; SSdbRow desc = {.type = SDB_OPER_GLOBAL, .pObj = pTable, .pTable = tsChildTableSdb};
sdbDeleteRow(&desc); sdbDeleteRow(&desc);
...@@ -2294,6 +2313,8 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) { ...@@ -2294,6 +2313,8 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) {
if (pDrop == NULL) { if (pDrop == NULL) {
mError("msg:%p, app:%p ctable:%s, failed to drop ctable, no enough memory", pMsg, pMsg->rpcMsg.ahandle, mError("msg:%p, app:%p ctable:%s, failed to drop ctable, no enough memory", pMsg, pMsg->rpcMsg.ahandle,
pTable->info.tableId); pTable->info.tableId);
monSaveAuditLog((pTable->info.type == TSDB_CHILD_TABLE) ? MON_DDL_CMD_DROP_CHILD_TABLE : MON_DDL_CMD_DROP_TABLE,
mnodeGetUserFromMsg(pMsg), pTable->info.tableId, false);
return TSDB_CODE_MND_OUT_OF_MEMORY; return TSDB_CODE_MND_OUT_OF_MEMORY;
} }
...@@ -2308,6 +2329,9 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) { ...@@ -2308,6 +2329,9 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) {
mInfo("msg:%p, app:%p ctable:%s, send drop ctable msg, vgId:%d sid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle, mInfo("msg:%p, app:%p ctable:%s, send drop ctable msg, vgId:%d sid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle,
pDrop->tableFname, pTable->vgId, pTable->tid, pTable->uid); pDrop->tableFname, pTable->vgId, pTable->tid, pTable->uid);
monSaveAuditLog((pTable->info.type == TSDB_CHILD_TABLE) ? MON_DDL_CMD_DROP_CHILD_TABLE : MON_DDL_CMD_DROP_TABLE,
mnodeGetUserFromMsg(pMsg), pTable->info.tableId, true);
SRpcMsg rpcMsg = { SRpcMsg rpcMsg = {
.ahandle = pMsg, .ahandle = pMsg,
.pCont = pDrop, .pCont = pDrop,
...@@ -2327,6 +2351,8 @@ static int32_t mnodeDropChildTableCb(SMnodeMsg *pMsg, int32_t code) { ...@@ -2327,6 +2351,8 @@ static int32_t mnodeDropChildTableCb(SMnodeMsg *pMsg, int32_t code) {
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
SCTableObj *pTable = (SCTableObj *)pMsg->pTable; SCTableObj *pTable = (SCTableObj *)pMsg->pTable;
mError("msg:%p, app:%p ctable:%s, failed to drop, sdb error", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); mError("msg:%p, app:%p ctable:%s, failed to drop, sdb error", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId);
monSaveAuditLog((pTable->info.type == TSDB_CHILD_TABLE) ? MON_DDL_CMD_DROP_CHILD_TABLE : MON_DDL_CMD_DROP_TABLE,
mnodeGetUserFromMsg(pMsg), pTable->info.tableId, false);
return code; return code;
} }
...@@ -2414,6 +2440,7 @@ static int32_t mnodeAddNormalTableColumn(SMnodeMsg *pMsg, SSchema schema[], int3 ...@@ -2414,6 +2440,7 @@ static int32_t mnodeAddNormalTableColumn(SMnodeMsg *pMsg, SSchema schema[], int3
SDbObj *pDb = pMsg->pDb; SDbObj *pDb = pMsg->pDb;
if (ncols <= 0) { if (ncols <= 0) {
mError("msg:%p, app:%p ctable:%s, add column, ncols:%d <= 0", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, ncols); mError("msg:%p, app:%p ctable:%s, add column, ncols:%d <= 0", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, ncols);
monSaveAuditLog(MON_DDL_CMD_ADD_COLUMN, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, false);
return TSDB_CODE_MND_APP_ERROR; return TSDB_CODE_MND_APP_ERROR;
} }
...@@ -2421,6 +2448,7 @@ static int32_t mnodeAddNormalTableColumn(SMnodeMsg *pMsg, SSchema schema[], int3 ...@@ -2421,6 +2448,7 @@ static int32_t mnodeAddNormalTableColumn(SMnodeMsg *pMsg, SSchema schema[], int3
if (mnodeFindNormalTableColumnIndex(pTable, schema[i].name) > 0) { if (mnodeFindNormalTableColumnIndex(pTable, schema[i].name) > 0) {
mError("msg:%p, app:%p ctable:%s, add column, column:%s already exist", pMsg, pMsg->rpcMsg.ahandle, mError("msg:%p, app:%p ctable:%s, add column, column:%s already exist", pMsg, pMsg->rpcMsg.ahandle,
pTable->info.tableId, schema[i].name); pTable->info.tableId, schema[i].name);
monSaveAuditLog(MON_DDL_CMD_ADD_COLUMN, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, false);
return TSDB_CODE_MND_FIELD_ALREAY_EXIST; return TSDB_CODE_MND_FIELD_ALREAY_EXIST;
} }
} }
...@@ -2445,6 +2473,7 @@ static int32_t mnodeAddNormalTableColumn(SMnodeMsg *pMsg, SSchema schema[], int3 ...@@ -2445,6 +2473,7 @@ static int32_t mnodeAddNormalTableColumn(SMnodeMsg *pMsg, SSchema schema[], int3
} }
mInfo("msg:%p, app:%p ctable %s, start to add column", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); mInfo("msg:%p, app:%p ctable %s, start to add column", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId);
monSaveAuditLog(MON_DDL_CMD_ADD_COLUMN, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, true);
SSdbRow row = { SSdbRow row = {
.type = SDB_OPER_GLOBAL, .type = SDB_OPER_GLOBAL,
...@@ -2464,6 +2493,7 @@ static int32_t mnodeDropNormalTableColumn(SMnodeMsg *pMsg, char *colName) { ...@@ -2464,6 +2493,7 @@ static int32_t mnodeDropNormalTableColumn(SMnodeMsg *pMsg, char *colName) {
if (col <= 0) { if (col <= 0) {
mError("msg:%p, app:%p ctable:%s, drop column, column:%s not exist", pMsg, pMsg->rpcMsg.ahandle, mError("msg:%p, app:%p ctable:%s, drop column, column:%s not exist", pMsg, pMsg->rpcMsg.ahandle,
pTable->info.tableId, colName); pTable->info.tableId, colName);
monSaveAuditLog(MON_DDL_CMD_DROP_COLUMN, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, false);
return TSDB_CODE_MND_FIELD_NOT_EXIST; return TSDB_CODE_MND_FIELD_NOT_EXIST;
} }
...@@ -2478,6 +2508,7 @@ static int32_t mnodeDropNormalTableColumn(SMnodeMsg *pMsg, char *colName) { ...@@ -2478,6 +2508,7 @@ static int32_t mnodeDropNormalTableColumn(SMnodeMsg *pMsg, char *colName) {
} }
mInfo("msg:%p, app:%p ctable %s, start to drop column %s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, colName); mInfo("msg:%p, app:%p ctable %s, start to drop column %s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, colName);
monSaveAuditLog(MON_DDL_CMD_DROP_COLUMN, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, true);
SSdbRow row = { SSdbRow row = {
.type = SDB_OPER_GLOBAL, .type = SDB_OPER_GLOBAL,
...@@ -2498,15 +2529,18 @@ static int32_t mnodeChangeNormalTableColumn(SMnodeMsg *pMsg) { ...@@ -2498,15 +2529,18 @@ static int32_t mnodeChangeNormalTableColumn(SMnodeMsg *pMsg) {
if (col < 0) { if (col < 0) {
mError("msg:%p, app:%p ctable:%s, change column, name: %s", pMsg, pMsg->rpcMsg.ahandle, mError("msg:%p, app:%p ctable:%s, change column, name: %s", pMsg, pMsg->rpcMsg.ahandle,
pTable->info.tableId, name); pTable->info.tableId, name);
monSaveAuditLog(MON_DDL_CMD_MODIFY_COLUMN, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, false);
return TSDB_CODE_MND_FIELD_NOT_EXIST; return TSDB_CODE_MND_FIELD_NOT_EXIST;
} }
SSchema *schema = (SSchema *) (pTable->schema + col); SSchema *schema = (SSchema *) (pTable->schema + col);
ASSERT(schema->type == TSDB_DATA_TYPE_BINARY || schema->type == TSDB_DATA_TYPE_NCHAR); ASSERT(schema->type == TSDB_DATA_TYPE_BINARY || schema->type == TSDB_DATA_TYPE_NCHAR);
schema->bytes = pAlter->schema[0].bytes; schema->bytes = pAlter->schema[0].bytes;
++pTable->sversion;
mInfo("msg:%p, app:%p ctable %s, start to modify column %s len to %d", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, mInfo("msg:%p, app:%p ctable %s, start to modify column %s len to %d", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId,
name, schema->bytes); name, schema->bytes);
monSaveAuditLog(MON_DDL_CMD_MODIFY_COLUMN, mnodeGetUserFromMsg(pMsg), pTable->info.tableId, true);
SSdbRow row = { SSdbRow row = {
.type = SDB_OPER_GLOBAL, .type = SDB_OPER_GLOBAL,
...@@ -3558,7 +3592,7 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro ...@@ -3558,7 +3592,7 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro
cols++; cols++;
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pTable->sql, pShow->bytes[cols]); STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pTable->sql, pShow->bytes[cols]);
cols++; cols++;
numOfRows++; numOfRows++;
...@@ -3593,13 +3627,13 @@ static int32_t mnodeCompactSuperTables() { ...@@ -3593,13 +3627,13 @@ static int32_t mnodeCompactSuperTables() {
}; };
//mInfo("compact super %" PRIu64, pTable->uid); //mInfo("compact super %" PRIu64, pTable->uid);
sdbInsertCompactRow(&row); sdbInsertCompactRow(&row);
} }
mInfo("end to compact super table..."); mInfo("end to compact super table...");
return 0; return 0;
} }
static int32_t mnodeCompactChildTables() { static int32_t mnodeCompactChildTables() {
...@@ -3619,13 +3653,13 @@ static int32_t mnodeCompactChildTables() { ...@@ -3619,13 +3653,13 @@ static int32_t mnodeCompactChildTables() {
}; };
//mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid); //mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid);
sdbInsertCompactRow(&row); sdbInsertCompactRow(&row);
} }
mInfo("end to compact child table..."); mInfo("end to compact child table...");
return 0; return 0;
} }
int32_t mnodeCompactTables() { int32_t mnodeCompactTables() {
......
...@@ -97,7 +97,7 @@ static int32_t mnodeUserActionDecode(SSdbRow *pRow) { ...@@ -97,7 +97,7 @@ static int32_t mnodeUserActionDecode(SSdbRow *pRow) {
SUserObj *pUser = (SUserObj *)calloc(1, sizeof(SUserObj)); SUserObj *pUser = (SUserObj *)calloc(1, sizeof(SUserObj));
if (pUser == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; if (pUser == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
memcpy(pUser, pRow->rowData, tsUserUpdateSize); memcpy(pUser, pRow->rowData, pRow->rowSize);
pRow->pObj = pUser; pRow->pObj = pUser;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -108,7 +108,7 @@ static void mnodePrintUserAuth() { ...@@ -108,7 +108,7 @@ static void mnodePrintUserAuth() {
mDebug("failed to auth.txt for write"); mDebug("failed to auth.txt for write");
return; return;
} }
void * pIter = NULL; void * pIter = NULL;
SUserObj *pUser = NULL; SUserObj *pUser = NULL;
...@@ -181,7 +181,7 @@ int32_t mnodeInitUsers() { ...@@ -181,7 +181,7 @@ int32_t mnodeInitUsers() {
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_USER, mnodeCancelGetNextUser); mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_USER, mnodeCancelGetNextUser);
mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_AUTH, mnodeProcessAuthMsg); mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_AUTH, mnodeProcessAuthMsg);
mDebug("table:%s, hash is created", desc.name); mDebug("table:%s, hash is created", desc.name);
return 0; return 0;
} }
...@@ -195,20 +195,20 @@ SUserObj *mnodeGetUser(char *name) { ...@@ -195,20 +195,20 @@ SUserObj *mnodeGetUser(char *name) {
return (SUserObj *)sdbGetRow(tsUserSdb, name); return (SUserObj *)sdbGetRow(tsUserSdb, name);
} }
void *mnodeGetNextUser(void *pIter, SUserObj **pUser) { void *mnodeGetNextUser(void *pIter, SUserObj **pUser) {
return sdbFetchRow(tsUserSdb, pIter, (void **)pUser); return sdbFetchRow(tsUserSdb, pIter, (void **)pUser);
} }
void mnodeCancelGetNextUser(void *pIter) { void mnodeCancelGetNextUser(void *pIter) {
sdbFreeIter(tsUserSdb, pIter); sdbFreeIter(tsUserSdb, pIter);
} }
void mnodeIncUserRef(SUserObj *pUser) { void mnodeIncUserRef(SUserObj *pUser) {
sdbIncRef(tsUserSdb, pUser); sdbIncRef(tsUserSdb, pUser);
} }
void mnodeDecUserRef(SUserObj *pUser) { void mnodeDecUserRef(SUserObj *pUser) {
sdbDecRef(tsUserSdb, pUser); sdbDecRef(tsUserSdb, pUser);
} }
static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) { static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) {
...@@ -464,7 +464,7 @@ char *mnodeGetUserFromMsg(void *pMsg) { ...@@ -464,7 +464,7 @@ char *mnodeGetUserFromMsg(void *pMsg) {
static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) { static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) {
SUserObj *pOperUser = pMsg->pUser; SUserObj *pOperUser = pMsg->pUser;
if (pOperUser->superAuth) { if (pOperUser->superAuth) {
SCreateUserMsg *pCreate = pMsg->rpcMsg.pCont; SCreateUserMsg *pCreate = pMsg->rpcMsg.pCont;
return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pCreate->tags, pMsg); return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pCreate->tags, pMsg);
...@@ -477,7 +477,7 @@ static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) { ...@@ -477,7 +477,7 @@ static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) {
static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) { static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
int32_t code; int32_t code;
SUserObj *pOperUser = pMsg->pUser; SUserObj *pOperUser = pMsg->pUser;
SAlterUserMsg *pAlter = pMsg->rpcMsg.pCont; SAlterUserMsg *pAlter = pMsg->rpcMsg.pCont;
SUserObj *pUser = mnodeGetUser(pAlter->user); SUserObj *pUser = mnodeGetUser(pAlter->user);
if (pUser == NULL) { if (pUser == NULL) {
...@@ -686,10 +686,10 @@ int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, cha ...@@ -686,10 +686,10 @@ int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, cha
static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg) { static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg) {
SAuthMsg *pAuthMsg = pMsg->rpcMsg.pCont; SAuthMsg *pAuthMsg = pMsg->rpcMsg.pCont;
SAuthRsp *pAuthRsp = rpcMallocCont(sizeof(SAuthRsp)); SAuthRsp *pAuthRsp = rpcMallocCont(sizeof(SAuthRsp));
pMsg->rpcRsp.rsp = pAuthRsp; pMsg->rpcRsp.rsp = pAuthRsp;
pMsg->rpcRsp.len = sizeof(SAuthRsp); pMsg->rpcRsp.len = sizeof(SAuthRsp);
return mnodeRetriveAuth(pAuthMsg->user, &pAuthRsp->spi, &pAuthRsp->encrypt, pAuthRsp->secret, pAuthRsp->ckey); return mnodeRetriveAuth(pAuthMsg->user, &pAuthRsp->spi, &pAuthRsp->encrypt, pAuthRsp->secret, pAuthRsp->ckey);
} }
...@@ -711,7 +711,7 @@ int32_t mnodeCompactUsers() { ...@@ -711,7 +711,7 @@ int32_t mnodeCompactUsers() {
}; };
mInfo("compact users %s", pUser->user); mInfo("compact users %s", pUser->user);
sdbInsertCompactRow(&row); sdbInsertCompactRow(&row);
} }
......
...@@ -71,9 +71,13 @@ int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *op ...@@ -71,9 +71,13 @@ int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *op
return setsockopt(socketfd, level, optname, optval, (socklen_t)optlen); return setsockopt(socketfd, level, optname, optval, (socklen_t)optlen);
} }
#endif
#if !defined(_TD_DARWIN_32)
int32_t taosGetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t* optlen) { int32_t taosGetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t* optlen) {
return getsockopt(socketfd, level, optname, optval, (socklen_t *)optlen); return getsockopt(socketfd, level, optname, optval, (socklen_t *)optlen);
} }
#endif #endif
......
...@@ -41,6 +41,9 @@ ...@@ -41,6 +41,9 @@
#define DNODE_INFO_LEN 128 #define DNODE_INFO_LEN 128
#define QUERY_ID_LEN 24 #define QUERY_ID_LEN 24
#define CHECK_INTERVAL 1000 #define CHECK_INTERVAL 1000
#define AUDIT_MAX_RETRIES 10
#define MAX_DDL_TYPE_LEN 32
#define MAX_DDL_OBJ_LEN 512
#define SQL_STR_FMT "\"%s\"" #define SQL_STR_FMT "\"%s\""
...@@ -161,6 +164,7 @@ typedef struct { ...@@ -161,6 +164,7 @@ typedef struct {
} SMonStat; } SMonStat;
static void *monHttpStatusHashTable; static void *monHttpStatusHashTable;
static void *auditConn;
static SMonConn tsMonitor = {0}; static SMonConn tsMonitor = {0};
static SMonStat tsMonStat = {{0}}; static SMonStat tsMonStat = {{0}};
...@@ -175,16 +179,24 @@ static void monSaveDisksInfo(); ...@@ -175,16 +179,24 @@ static void monSaveDisksInfo();
static void monSaveGrantsInfo(); static void monSaveGrantsInfo();
static void monSaveHttpReqInfo(); static void monSaveHttpReqInfo();
static void monGetSysStats(); static void monGetSysStats();
static void *monThreadFunc(void *param); static void *monThreadFunc(void *param);
static void *monAuditFunc(void *param);
static void monBuildMonitorSql(char *sql, int32_t cmd); static void monBuildMonitorSql(char *sql, int32_t cmd);
static void monInitHttpStatusHashTable(); static void monInitHttpStatusHashTable();
static void monCleanupHttpStatusHashTable(); static void monCleanupHttpStatusHashTable();
extern int32_t (*monStartSystemFp)(); extern int32_t (*monStartSystemFp)();
extern void (*monStopSystemFp)(); extern void (*monStopSystemFp)();
extern void (*monExecuteSQLFp)(char *sql); extern void (*monExecuteSQLFp)(char *sql);
extern char * strptime(const char *buf, const char *fmt, struct tm *tm); //make the compilation pass extern char * strptime(const char *buf, const char *fmt, struct tm *tm); //make the compilation pass
#ifdef _STORAGE
char *keepValue = "30,30,30";
#else
char *keepValue = "30";
#endif
int32_t monInitSystem() { int32_t monInitSystem() {
if (tsMonitor.ep[0] == 0) { if (tsMonitor.ep[0] == 0) {
strcpy(tsMonitor.ep, tsLocalEp); strcpy(tsMonitor.ep, tsLocalEp);
...@@ -203,12 +215,20 @@ int32_t monInitSystem() { ...@@ -203,12 +215,20 @@ int32_t monInitSystem() {
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE); pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
if (pthread_create(&tsMonitor.thread, &thAttr, monThreadFunc, NULL)) { if (pthread_create(&tsMonitor.thread, &thAttr, monThreadFunc, NULL)) {
monError("failed to create thread to for monitor module, reason:%s", strerror(errno)); monError("failed to create thread for monitor module, reason:%s", strerror(errno));
return -1;
}
monDebug("monitor thread is launched");
pthread_t auditThread;
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_DETACHED);
if (pthread_create(&auditThread, &thAttr, monAuditFunc, NULL)) {
monError("failed to create audit thread, reason:%s", strerror(errno));
return -1; return -1;
} }
monDebug("audit thread is launched");
pthread_attr_destroy(&thAttr); pthread_attr_destroy(&thAttr);
monDebug("monitor thread is launched");
monStartSystemFp = monStartSystem; monStartSystemFp = monStartSystem;
monStopSystemFp = monStopSystem; monStopSystemFp = monStopSystem;
...@@ -250,6 +270,70 @@ SMonHttpStatus *monGetHttpStatusHashTableEntry(int32_t code) { ...@@ -250,6 +270,70 @@ SMonHttpStatus *monGetHttpStatusHashTableEntry(int32_t code) {
return (SMonHttpStatus*)taosHashGet(monHttpStatusHashTable, &code, sizeof(int32_t)); return (SMonHttpStatus*)taosHashGet(monHttpStatusHashTable, &code, sizeof(int32_t));
} }
static void *monAuditFunc(void *param) {
if (!tsEnableAudit) {
return NULL;
}
monDebug("starting to initialize audit database...");
setThreadName("audit");
taosMsleep(1000);
int32_t try = 0;
for (; try < AUDIT_MAX_RETRIES; ++try) {
auditConn = taos_connect(NULL, "monitor", tsInternalPass, "", 0);
if (auditConn == NULL) {
monDebug("audit retry connect, tries: %d", try);
taosMsleep(1000);
} else {
monDebug("audit successfuly connect to database");
break;
}
}
if (try == AUDIT_MAX_RETRIES) {
monError("audit failed to connect to database, reason:%s", tstrerror(terrno));
return NULL;
}
// create database
char sql[512] = {0};
snprintf(sql, sizeof(sql),
"create database if not exists %s replica 1 days 10 keep %s cache %d "
"blocks %d precision 'us'",
tsAuditDbName, keepValue, TSDB_MIN_CACHE_BLOCK_SIZE, TSDB_MIN_TOTAL_BLOCKS);
void *res = taos_query(auditConn, sql);
int32_t code = taos_errno(res);
taos_free_result(res);
if (code != 0) {
monError("failed to create database: %s, sql:%s, reason:%s", tsAuditDbName, sql, tstrerror(code));
return NULL;
}
// create table
memset(sql, 0, sizeof(sql));
snprintf(sql, sizeof(sql),
"create table if not exists %s.ddl(ts timestamp"
", user_name binary(%d), ip_addr binary(%d), type binary(%d)"
", object binary(%d), result binary(10)"
")",
tsAuditDbName, TSDB_USER_LEN, IP_LEN_STR,
MAX_DDL_TYPE_LEN, MAX_DDL_OBJ_LEN);
res = taos_query(auditConn, sql);
code = taos_errno(res);
taos_free_result(res);
if (code != 0) {
monError("failed to create table: ddl, exec sql:%s, reason:%s", sql, tstrerror(code));
return NULL;
}
return NULL;
}
static void *monThreadFunc(void *param) { static void *monThreadFunc(void *param) {
monDebug("starting to initialize monitor module ..."); monDebug("starting to initialize monitor module ...");
setThreadName("monitor"); setThreadName("monitor");
...@@ -335,12 +419,6 @@ static void *monThreadFunc(void *param) { ...@@ -335,12 +419,6 @@ static void *monThreadFunc(void *param) {
static void monBuildMonitorSql(char *sql, int32_t cmd) { static void monBuildMonitorSql(char *sql, int32_t cmd) {
memset(sql, 0, SQL_LENGTH); memset(sql, 0, SQL_LENGTH);
#ifdef _STORAGE
char *keepValue = "30,30,30";
#else
char *keepValue = "30";
#endif
if (cmd == MON_CMD_CREATE_DB) { if (cmd == MON_CMD_CREATE_DB) {
snprintf(sql, SQL_LENGTH, snprintf(sql, SQL_LENGTH,
"create database if not exists %s replica %d days 10 keep %s cache %d " "create database if not exists %s replica %d days 10 keep %s cache %d "
...@@ -494,6 +572,11 @@ void monCleanupSystem() { ...@@ -494,6 +572,11 @@ void monCleanupSystem() {
pthread_join(tsMonitor.thread, NULL); pthread_join(tsMonitor.thread, NULL);
} }
if (auditConn != NULL) {
taos_close(tsMonitor.conn);
auditConn = NULL;
}
if (tsMonitor.conn != NULL) { if (tsMonitor.conn != NULL) {
taos_close(tsMonitor.conn); taos_close(tsMonitor.conn);
tsMonitor.conn = NULL; tsMonitor.conn = NULL;
...@@ -1323,6 +1406,116 @@ static void monExecSqlCb(void *param, TAOS_RES *result, int32_t code) { ...@@ -1323,6 +1406,116 @@ static void monExecSqlCb(void *param, TAOS_RES *result, int32_t code) {
taos_free_result(result); taos_free_result(result);
} }
static bool monConvDDLType2Str(int8_t type, char *buf, int32_t len) {
if (buf == NULL) {
return false;
}
switch (type) {
case MON_DDL_CMD_CREATE_DATABASE: {
strncpy(buf, "CREATE DATABASE", len);
break;
}
case MON_DDL_CMD_CREATE_TABLE: {
strncpy(buf, "CREATE TABLE", len);
break;
}
case MON_DDL_CMD_CREATE_CHILD_TABLE: {
strncpy(buf, "CREATE CHILD TABLE", len);
break;
}
case MON_DDL_CMD_CREATE_SUPER_TABLE: {
strncpy(buf, "CREATE SUPER TABLE", len);
break;
}
case MON_DDL_CMD_DROP_DATABASE: {
strncpy(buf, "DROP DATABASE", len);
break;
}
case MON_DDL_CMD_DROP_TABLE: {
strncpy(buf, "DROP TABLE", len);
break;
}
case MON_DDL_CMD_DROP_CHILD_TABLE: {
strncpy(buf, "DROP CHILD TABLE", len);
break;
}
case MON_DDL_CMD_DROP_SUPER_TABLE: {
strncpy(buf, "DROP SUPER TABLE", len);
break;
}
case MON_DDL_CMD_DROP_COLUMN: {
strncpy(buf, "DROP COLUMN", len);
break;
}
case MON_DDL_CMD_DROP_TAG: {
strncpy(buf, "DROP TAG", len);
break;
}
case MON_DDL_CMD_ALTER_DATABASE: {
strncpy(buf, "ALTER DATABASE", len);
break;
}
case MON_DDL_CMD_ADD_COLUMN: {
strncpy(buf, "ADD COLUMN", len);
break;
}
case MON_DDL_CMD_ADD_TAG: {
strncpy(buf, "ADD TAG", len);
break;
}
case MON_DDL_CMD_MODIFY_COLUMN: {
strncpy(buf, "MODIFY COLUMN/TAG LENGTH", len);
break;
}
case MON_DDL_CMD_CHANGE_TAG: {
strncpy(buf, "CHANGE TAG NAME", len);
break;
}
default: {
return false;
}
}
return true;
}
void monSaveAuditLog(int8_t type, const char *user, const char *obj, bool result) {
if (tsEnableAudit == 0) { //audit not enabled
return;
}
char sql[1024] = {0};
char typeStr[64] = {0};
if (!monConvDDLType2Str(type, typeStr, (int32_t)sizeof(typeStr))) {
monError("unknown DDL type: %d ", type);
return;
}
snprintf(sql, 1023,
"insert into %s.ddl values(now, "
SQL_STR_FMT", "SQL_STR_FMT", "
SQL_STR_FMT", "SQL_STR_FMT", "
SQL_STR_FMT")",
tsAuditDbName,
(user != NULL) ? user : "NULL",
tsLocalEp,
typeStr,
(obj != NULL) ? obj : "NULL",
result ? "success" : "fail");
monDebug("save ddl info, sql:%s", sql);
void *res = taos_query(auditConn, sql);
int32_t code = taos_errno(res);
taos_free_result(res);
if (code != 0) {
monError("failed to save audit ddl info, reason:%s, sql:%s", tstrerror(code), sql);
} else {
monDebug("successfully save audit ddl info, sql:%s", sql);
}
}
void monSaveAcctLog(SAcctMonitorObj *pMon) { void monSaveAcctLog(SAcctMonitorObj *pMon) {
if (tsMonitor.state != MON_STATE_INITED) return; if (tsMonitor.state != MON_STATE_INITED) return;
...@@ -1399,6 +1592,7 @@ void monSaveDnodeLog(int32_t level, const char *const format, ...) { ...@@ -1399,6 +1592,7 @@ void monSaveDnodeLog(int32_t level, const char *const format, ...) {
taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "log"); taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "log");
} }
void monExecuteSQL(char *sql) { void monExecuteSQL(char *sql) {
if (tsMonitor.state != MON_STATE_INITED) return; if (tsMonitor.state != MON_STATE_INITED) return;
......
Subproject commit 07950e62e576dbf96344d757ef0dd3fabd9570d9 Subproject commit 1b1a07e8477a37be6d61a7fc907479ec5ebd05b7
...@@ -311,6 +311,7 @@ alter_db_optr(Y) ::= alter_db_optr(Z) blocks(X). { Y = Z; Y.numOfBlocks = s ...@@ -311,6 +311,7 @@ alter_db_optr(Y) ::= alter_db_optr(Z) blocks(X). { Y = Z; Y.numOfBlocks = s
alter_db_optr(Y) ::= alter_db_optr(Z) comp(X). { Y = Z; Y.compressionLevel = strtol(X.z, NULL, 10); } alter_db_optr(Y) ::= alter_db_optr(Z) comp(X). { Y = Z; Y.compressionLevel = strtol(X.z, NULL, 10); }
alter_db_optr(Y) ::= alter_db_optr(Z) update(X). { Y = Z; Y.update = strtol(X.z, NULL, 10); } alter_db_optr(Y) ::= alter_db_optr(Z) update(X). { Y = Z; Y.update = strtol(X.z, NULL, 10); }
alter_db_optr(Y) ::= alter_db_optr(Z) cachelast(X). { Y = Z; Y.cachelast = strtol(X.z, NULL, 10); } alter_db_optr(Y) ::= alter_db_optr(Z) cachelast(X). { Y = Z; Y.cachelast = strtol(X.z, NULL, 10); }
alter_db_optr(Y) ::= alter_db_optr(Z) minrows(X). { Y = Z; Y.minRowsPerBlock = strtol(X.z, NULL, 10); }
// dynamically update the following two parameters are not allowed. // dynamically update the following two parameters are not allowed.
//alter_db_optr(Y) ::= alter_db_optr(Z) fsync(X). { Y = Z; Y.fsyncPeriod = strtol(X.z, NULL, 10); } //alter_db_optr(Y) ::= alter_db_optr(Z) fsync(X). { Y = Z; Y.fsyncPeriod = strtol(X.z, NULL, 10); }
......
此差异已折叠。
...@@ -318,10 +318,10 @@ static int32_t getColDataFromGroupRes(SGroupResInfo* pGroupResInfo, SQueryRuntim ...@@ -318,10 +318,10 @@ static int32_t getColDataFromGroupRes(SGroupResInfo* pGroupResInfo, SQueryRuntim
for (int32_t i = 0; i < numRows; ++i) { for (int32_t i = 0; i < numRows; ++i) {
SResultRow* row = taosArrayGetP(pGroupResInfo->pRows, i); SResultRow* row = taosArrayGetP(pGroupResInfo->pRows, i);
row->groupIndex = i; row->groupIndex = i;
tFilePage* page = getResBufPage(pRuntimeEnv->pResultBuf, row->pageId); tFilePage* page = getResBufPage(pRuntimeEnv->pResultBuf, row->pageId);
int32_t rowsToCopy = 1; int32_t rowsToCopy = 1;
char* out = colData + numOfResult * colBytes; char* out = colData + numOfResult * colBytes;
char* in = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, row->offset, colDataOffset); char* in = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, row->offset, colDataOffset);
memcpy(out, in, colBytes * rowsToCopy); memcpy(out, in, colBytes * rowsToCopy);
numOfResult += rowsToCopy; numOfResult += rowsToCopy;
} }
...@@ -2837,6 +2837,10 @@ static bool isCachedLastQuery(SQueryAttr* pQueryAttr) { ...@@ -2837,6 +2837,10 @@ static bool isCachedLastQuery(SQueryAttr* pQueryAttr) {
return false; return false;
} }
if (pQueryAttr->pFilters != NULL || pQueryAttr->pFilterInfo != NULL) {
return false;
}
return true; return true;
} }
...@@ -3165,7 +3169,7 @@ static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlock ...@@ -3165,7 +3169,7 @@ static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlock
return true; return true;
} }
while(w.skey < pBlockInfo->window.ekey) { while (w.skey < pBlockInfo->window.ekey) {
// add one slding // add one slding
if (pQueryAttr->interval.slidingUnit == 'n' || pQueryAttr->interval.slidingUnit == 'y') if (pQueryAttr->interval.slidingUnit == 'n' || pQueryAttr->interval.slidingUnit == 'y')
ekey = taosTimeAdd(ekey, pQueryAttr->interval.sliding, pQueryAttr->interval.slidingUnit, pQueryAttr->precision); ekey = taosTimeAdd(ekey, pQueryAttr->interval.sliding, pQueryAttr->interval.slidingUnit, pQueryAttr->precision);
...@@ -3180,7 +3184,7 @@ static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlock ...@@ -3180,7 +3184,7 @@ static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlock
getAlignQueryTimeWindow(pQueryAttr, ekey, sk, ek, &w); getAlignQueryTimeWindow(pQueryAttr, ekey, sk, ek, &w);
} }
while(1) { while (1) {
if (w.ekey < pBlockInfo->window.skey) { if (w.ekey < pBlockInfo->window.skey) {
break; break;
} }
...@@ -6339,7 +6343,7 @@ SOperatorInfo* createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI ...@@ -6339,7 +6343,7 @@ SOperatorInfo* createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI
SColumnInfoData col = {{0}}; SColumnInfoData col = {{0}};
col.info.colId = pExpr[i].base.colInfo.colId; col.info.colId = pExpr[i].base.colInfo.colId;
col.info.bytes = pExpr[i].base.resBytes; col.info.bytes = pExpr[i].base.resBytes;
col.info.type = pExpr[i].base.resType; col.info.type = pExpr[i].base.resType;
taosArrayPush(pDataBlock->pDataBlock, &col); taosArrayPush(pDataBlock->pDataBlock, &col);
if (!found && col.info.colId == pOrderVal->orderColId) { if (!found && col.info.colId == pOrderVal->orderColId) {
...@@ -6625,7 +6629,7 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { ...@@ -6625,7 +6629,7 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) {
} }
copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput); copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
clearNumOfRes(pInfo->pCtx, pOperator->numOfOutput); clearNumOfRes(pInfo->pCtx, pOperator->numOfOutput);
return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL; return pInfo->pRes;
} }
static SSDataBlock* doLimit(void* param, bool* newgroup) { static SSDataBlock* doLimit(void* param, bool* newgroup) {
...@@ -6874,18 +6878,18 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo ...@@ -6874,18 +6878,18 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
break; break;
} }
} }
if (pCtx == NULL) { if (pCtx == NULL) {
goto group_finished_exit; goto group_finished_exit;
} }
TSKEY* tsCols = NULL; TSKEY* tsCols = NULL;
if (pBlock && pBlock->pDataBlock != NULL) { if (pBlock && pBlock->pDataBlock != NULL) {
SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, 0); SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, 0);
tsCols = (int64_t*)pColDataInfo->pData; tsCols = (int64_t*)pColDataInfo->pData;
assert(tsCols[0] == pBlock->info.window.skey && tsCols[pBlock->info.rows - 1] == pBlock->info.window.ekey); assert(tsCols[0] == pBlock->info.window.skey && tsCols[pBlock->info.rows - 1] == pBlock->info.window.ekey);
} }
if (pCtx->startTs == INT64_MIN) { if (pCtx->startTs == INT64_MIN) {
if (pQueryAttr->range.skey == INT64_MIN) { if (pQueryAttr->range.skey == INT64_MIN) {
if (NULL == tsCols) { if (NULL == tsCols) {
...@@ -6984,7 +6988,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo ...@@ -6984,7 +6988,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
return false; return false;
} }
int32_t nRows = pBlock ? pBlock->info.rows : 0; int32_t nRows = pBlock ? pBlock->info.rows : 0;
int32_t startPos = binarySearchForKey((char*) tsCols, nRows, pCtx->startTs, pQueryAttr->order.order); int32_t startPos = binarySearchForKey((char*)tsCols, nRows, pCtx->startTs, pQueryAttr->order.order);
if (ascQuery && pQueryAttr->fillType != TSDB_FILL_NEXT && pCtx->start.key == INT64_MIN) { if (ascQuery && pQueryAttr->fillType != TSDB_FILL_NEXT && pCtx->start.key == INT64_MIN) {
if (startPos < 0) { if (startPos < 0) {
...@@ -8522,18 +8526,18 @@ SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator ...@@ -8522,18 +8526,18 @@ SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator
SColIndex* idx = taosArrayGet(pInfo->orderColumnList, i); SColIndex* idx = taosArrayGet(pInfo->orderColumnList, i);
offset += pExpr[idx->colIndex].base.resBytes; offset += pExpr[idx->colIndex].base.resBytes;
} }
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
if (pOperator == NULL) { if (pOperator == NULL) {
goto _clean; goto _clean;
} }
pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
if (pInfo->pRes == NULL) { if (pInfo->pRes == NULL) {
tfree(pOperator); tfree(pOperator);
goto _clean; goto _clean;
} }
pOperator->name = "SLimitOperator"; pOperator->name = "SLimitOperator";
pOperator->operatorType = OP_SLimit; pOperator->operatorType = OP_SLimit;
pOperator->blockingOptr = false; pOperator->blockingOptr = false;
...@@ -10172,7 +10176,8 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S ...@@ -10172,7 +10176,8 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
pTableqinfo->pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES); pTableqinfo->pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES);
pTableqinfo->numOfTables = pTableGroupInfo->numOfTables; pTableqinfo->numOfTables = pTableGroupInfo->numOfTables;
pTableqinfo->map = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); pTableqinfo->map = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true,
HASH_ENTRY_LOCK);
} }
pQInfo->pBuf = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo)); pQInfo->pBuf = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
...@@ -10374,7 +10379,7 @@ static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) { ...@@ -10374,7 +10379,7 @@ static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) {
taosArrayDestroy(&pTableqinfoGroupInfo->pGroupList); taosArrayDestroy(&pTableqinfoGroupInfo->pGroupList);
SHashObj *pmap = pTableqinfoGroupInfo->map; SHashObj* pmap = pTableqinfoGroupInfo->map;
if (pmap == atomic_val_compare_exchange_ptr(&pTableqinfoGroupInfo->map, pmap, NULL)) { if (pmap == atomic_val_compare_exchange_ptr(&pTableqinfoGroupInfo->map, pmap, NULL)) {
taosHashCleanup(pmap); taosHashCleanup(pmap);
} }
......
...@@ -338,6 +338,45 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex ...@@ -338,6 +338,45 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex
return code; return code;
} }
bool qFitAlwaysValue(SQInfo * pQInfo) {
// must agg query
if (!pQInfo->query.simpleAgg)
return false;
// must not include ts column
SSDataBlock* pBlock = pQInfo->runtimeEnv.outputBuf;
if (pBlock == NULL || pBlock->pDataBlock == NULL)
return false;
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
if (pColInfoData == NULL)
return false;
// must not first column is timestamp
if (pColInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP)
return false;
// fit ok
return true;
}
bool doFillResultWithNull(SQInfo* pQInfo, char * data, size_t numOfRows) {
SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv;
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
SSDataBlock* pRes = pRuntimeEnv->outputBuf;
int32_t numOfCols = pQueryAttr->numOfOutput;
for (int32_t i = 0; i < numOfCols; ++i) {
int16_t functionId = pQueryAttr->pExpr1[i].base.functionId;
// col
SColumnInfoData* pCol = taosArrayGet(pRes->pDataBlock, i);
if (functionId != TSDB_FUNC_COUNT)
setNull(data, pCol->info.type, pCol->info.bytes);
data += pCol->info.bytes * numOfRows;
}
return true;
}
int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *contLen, bool* continueExec) { int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *contLen, bool* continueExec) {
SQInfo *pQInfo = (SQInfo *)qinfo; SQInfo *pQInfo = (SQInfo *)qinfo;
int32_t compLen = 0; int32_t compLen = 0;
...@@ -350,6 +389,14 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co ...@@ -350,6 +389,14 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co
SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv;
int32_t s = GET_NUM_OF_RESULTS(pRuntimeEnv); int32_t s = GET_NUM_OF_RESULTS(pRuntimeEnv);
bool fillNull = false;
if (s == 0 && tsAggAlways) {
if (qFitAlwaysValue(pQInfo)) {
s = 1;
fillNull = true;
}
}
size_t size = pQueryAttr->resultRowSize * s; size_t size = pQueryAttr->resultRowSize * s;
size += sizeof(int32_t); size += sizeof(int32_t);
size += sizeof(STableIdInfo) * taosHashGetSize(pRuntimeEnv->pTableRetrieveTsMap); size += sizeof(STableIdInfo) * taosHashGetSize(pRuntimeEnv->pTableRetrieveTsMap);
...@@ -378,6 +425,9 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co ...@@ -378,6 +425,9 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co
if (GET_NUM_OF_RESULTS(&(pQInfo->runtimeEnv)) > 0 && pQInfo->code == TSDB_CODE_SUCCESS) { if (GET_NUM_OF_RESULTS(&(pQInfo->runtimeEnv)) > 0 && pQInfo->code == TSDB_CODE_SUCCESS) {
doDumpQueryResult(pQInfo, (*pRsp)->data, (*pRsp)->compressed, &compLen); doDumpQueryResult(pQInfo, (*pRsp)->data, (*pRsp)->compressed, &compLen);
} else { } else {
if (fillNull) {
doFillResultWithNull(pQInfo, (*pRsp)->data, 1);
}
setQueryStatus(pRuntimeEnv, QUERY_OVER); setQueryStatus(pRuntimeEnv, QUERY_OVER);
} }
......
此差异已折叠。
...@@ -1080,7 +1080,9 @@ static void rpcProcessBrokenLink(SRpcConn *pConn) { ...@@ -1080,7 +1080,9 @@ static void rpcProcessBrokenLink(SRpcConn *pConn) {
pContext->code = TSDB_CODE_RPC_NETWORK_UNAVAIL; pContext->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
pContext->pConn = NULL; pContext->pConn = NULL;
pConn->pReqMsg = NULL; pConn->pReqMsg = NULL;
taosTmrStart(rpcProcessConnError, 0, pContext, pRpc->tmrCtrl); int64_t *rid = malloc(sizeof(int64_t));
*rid = pContext->rid;
taosTmrStart(rpcProcessConnError, 0, rid, pRpc->tmrCtrl);
} }
if (pConn->inType) rpcReportBrokenLinkToServer(pConn); if (pConn->inType) rpcReportBrokenLinkToServer(pConn);
...@@ -1293,7 +1295,9 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqConte ...@@ -1293,7 +1295,9 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqConte
rpcFreeCont(rpcMsg.pCont); rpcFreeCont(rpcMsg.pCont);
} else if (pHead->code == TSDB_CODE_RPC_NOT_READY || pHead->code == TSDB_CODE_APP_NOT_READY || pHead->code == TSDB_CODE_DND_EXITING) { } else if (pHead->code == TSDB_CODE_RPC_NOT_READY || pHead->code == TSDB_CODE_APP_NOT_READY || pHead->code == TSDB_CODE_DND_EXITING) {
pContext->code = pHead->code; pContext->code = pHead->code;
rpcProcessConnError(pContext, NULL); int64_t *rid = malloc(sizeof(int64_t));
*rid = pContext->rid;
rpcProcessConnError(rid, NULL);
rpcFreeCont(rpcMsg.pCont); rpcFreeCont(rpcMsg.pCont);
} else { } else {
rpcNotifyClient(pContext, &rpcMsg); rpcNotifyClient(pContext, &rpcMsg);
...@@ -1395,7 +1399,9 @@ static TBOOL rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { ...@@ -1395,7 +1399,9 @@ static TBOOL rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) {
if (pConn == NULL) { if (pConn == NULL) {
pContext->code = terrno; pContext->code = terrno;
// in rpcProcessConnError if numOfTry over limit, could call rpcNotifyClient to stop query // in rpcProcessConnError if numOfTry over limit, could call rpcNotifyClient to stop query
taosTmrStart(rpcProcessConnError, 1, pContext, pRpc->tmrCtrl); int64_t *rid = malloc(sizeof(int64_t));
*rid = pContext->rid;
taosTmrStart(rpcProcessConnError, 1, rid, pRpc->tmrCtrl);
return BOOL_ASYNC; return BOOL_ASYNC;
} }
...@@ -1442,7 +1448,9 @@ static TBOOL rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { ...@@ -1442,7 +1448,9 @@ static TBOOL rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) {
// try next ip again // try next ip again
pContext->code = terrno; pContext->code = terrno;
// in rpcProcessConnError if numOfTry over limit, could call rpcNotifyClient to stop query // in rpcProcessConnError if numOfTry over limit, could call rpcNotifyClient to stop query
taosTmrStart(rpcProcessConnError, 1, pContext, pRpc->tmrCtrl); int64_t *rid = malloc(sizeof(int64_t));
*rid = pContext->rid;
taosTmrStart(rpcProcessConnError, 1, rid, pRpc->tmrCtrl);
return BOOL_ASYNC; return BOOL_ASYNC;
} }
...@@ -1480,11 +1488,23 @@ static bool rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { ...@@ -1480,11 +1488,23 @@ static bool rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) {
} }
static void rpcProcessConnError(void *param, void *id) { static void rpcProcessConnError(void *param, void *id) {
SRpcReqContext *pContext = (SRpcReqContext *)param; if (NULL == param) {
return;
}
int64_t *rid = (int64_t*)param;
SRpcReqContext *pContext = (SRpcReqContext *)taosAcquireRef(tsRpcRefId, *rid);
if (NULL == pContext) {
free(param);
return;
}
SRpcInfo *pRpc = pContext->pRpc; SRpcInfo *pRpc = pContext->pRpc;
SRpcMsg rpcMsg; SRpcMsg rpcMsg;
if (pRpc == NULL) { if (pRpc == NULL) {
taosReleaseRef(tsRpcRefId, *rid);
free(param);
return; return;
} }
...@@ -1504,6 +1524,9 @@ static void rpcProcessConnError(void *param, void *id) { ...@@ -1504,6 +1524,9 @@ static void rpcProcessConnError(void *param, void *id) {
pContext->epSet.inUse = pContext->epSet.inUse % pContext->epSet.numOfEps; pContext->epSet.inUse = pContext->epSet.inUse % pContext->epSet.numOfEps;
rpcSendReqToServer(pRpc, pContext); rpcSendReqToServer(pRpc, pContext);
} }
taosReleaseRef(tsRpcRefId, *rid);
free(param);
} }
static void rpcProcessRetryTimer(void *param, void *tmrId) { static void rpcProcessRetryTimer(void *param, void *tmrId) {
...@@ -1528,7 +1551,9 @@ static void rpcProcessRetryTimer(void *param, void *tmrId) { ...@@ -1528,7 +1551,9 @@ static void rpcProcessRetryTimer(void *param, void *tmrId) {
pConn->pContext->code = TSDB_CODE_RPC_NETWORK_UNAVAIL; pConn->pContext->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
pConn->pContext->pConn = NULL; pConn->pContext->pConn = NULL;
pConn->pReqMsg = NULL; pConn->pReqMsg = NULL;
taosTmrStart(rpcProcessConnError, 1, pConn->pContext, pRpc->tmrCtrl); int64_t *rid = malloc(sizeof(int64_t));
*rid = pConn->pContext->rid;
taosTmrStart(rpcProcessConnError, 1, rid, pRpc->tmrCtrl);
rpcReleaseConn(pConn); rpcReleaseConn(pConn);
} }
} }
...@@ -1892,4 +1917,4 @@ bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext) { ...@@ -1892,4 +1917,4 @@ bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext) {
taosReleaseRef(tsRpcRefId, rpcRid); taosReleaseRef(tsRpcRefId, rpcRid);
return true; return true;
} }
\ No newline at end of file
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include "os.h" #include "os.h"
#include "taoserror.h" #include "taoserror.h"
#include "tchecksum.h"
#include "tlog.h" #include "tlog.h"
#include "tutil.h" #include "tutil.h"
#include "tglobal.h" #include "tglobal.h"
...@@ -23,6 +24,7 @@ ...@@ -23,6 +24,7 @@
#include "tsocket.h" #include "tsocket.h"
#include "twal.h" #include "twal.h"
#include "tsync.h" #include "tsync.h"
#include "tfile.h"
#include "syncInt.h" #include "syncInt.h"
static int32_t syncGetWalVersion(SSyncNode *pNode, SSyncPeer *pPeer) { static int32_t syncGetWalVersion(SSyncNode *pNode, SSyncPeer *pPeer) {
...@@ -134,8 +136,69 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) { ...@@ -134,8 +136,69 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
return 0; return 0;
} }
static int syncValidateChecksum(SWalHead *pHead) {
if (pHead->sver == 0) { // for compatible with wal before sver 1
return taosCheckChecksumWhole((uint8_t *)pHead, sizeof(*pHead));
} else {
// new wal format
uint32_t cksum = pHead->cksum;
pHead->cksum = 0;
int ret = taosCheckChecksum((uint8_t *)pHead, sizeof(*pHead) + pHead->len, cksum);
pHead->cksum = cksum; // must restore cksum for next call walValiteCheckSum
return ret;
}
}
static int32_t syncSkipCorruptedRecord(SWalHead *pHead, int32_t fd) {
int64_t pos = taosLSeek(fd, 0, SEEK_CUR);
if (pos < 0) {
sError("fd:%d, skip corrupte taosLSeek return error. pos=%" PRId64, fd, pos);
return TSDB_CODE_WAL_FILE_CORRUPTED;
}
// save start bad bytes positioin
int64_t start = pos;
while (1) {
pos++;
if (taosLSeek(fd, pos, SEEK_SET) < 0) {
sError("fd:%d, failed to seek from corrupted wal file pos=%" PRId64 ".since %s", fd, pos, strerror(errno));
return TSDB_CODE_WAL_FILE_CORRUPTED;
}
if (fdRead(fd, pHead, sizeof(SWalHead)) <= 0) {
sError("fd:%d, failed to read wal head from corrupted wal. pos=%" PRId64 ".since %s", fd, pos, strerror(errno));
return TSDB_CODE_WAL_FILE_CORRUPTED;
}
if (pHead->signature != WAL_SIGNATURE) {
continue;
}
if (pHead->sver == 0) {
// old format wal, only check head crc
if (syncValidateChecksum(pHead)) {
sInfo("fd:%d, old wal read head ok, pHead->len=%d, skip bad bytes=%" PRId64 " right pos:%" PRId64, fd, pHead->len, pos - start, pos);
return TSDB_CODE_SUCCESS;
}
} else {
// new format wal, check head + body crc
if (fdRead(fd, pHead->cont, pHead->len) < pHead->len) {
sError("fd:%d, read to end of corrupted wal file, offset:%" PRId64, fd, pos);
return TSDB_CODE_WAL_FILE_CORRUPTED;
}
if (syncValidateChecksum(pHead)) {
sInfo("fd:%d, wal read head ok, pHead->len=%d, skip bad bytes=%" PRId64 " right pos:%" PRId64, fd, pHead->len, pos - start, pos);
return TSDB_CODE_SUCCESS;
}
}
}
return TSDB_CODE_WAL_FILE_CORRUPTED;
}
// if only a partial record is read out, upper layer will reload the file to get a complete record // if only a partial record is read out, upper layer will reload the file to get a complete record
static int32_t syncReadOneWalRecord(int32_t sfd, SWalHead *pHead) { static int32_t syncReadOneWalRecord(int32_t sfd, SWalHead *pHead) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t ret = read(sfd, pHead, sizeof(SWalHead)); int32_t ret = read(sfd, pHead, sizeof(SWalHead));
if (ret < 0) { if (ret < 0) {
sError("sfd:%d, failed to read wal head since %s, ret:%d", sfd, strerror(errno), ret); sError("sfd:%d, failed to read wal head since %s, ret:%d", sfd, strerror(errno), ret);
...@@ -153,18 +216,48 @@ static int32_t syncReadOneWalRecord(int32_t sfd, SWalHead *pHead) { ...@@ -153,18 +216,48 @@ static int32_t syncReadOneWalRecord(int32_t sfd, SWalHead *pHead) {
return 0; return 0;
} }
assert(pHead->len <= TSDB_MAX_WAL_SIZE); // check wal head valid
if (pHead->sver == 0 && !syncValidateChecksum(pHead)) {
sError("sfd:%d, old wal head cksum is messed up, sver=%d version:%" PRIu64 " len:%d", sfd, pHead->sver, pHead->version, pHead->len);
code = syncSkipCorruptedRecord(pHead, sfd);
if (code != TSDB_CODE_SUCCESS) {
sError("sfd:%d, wal corrupted and skip failed crc check, code:%d", sfd, code);
return -1;
}
// found next valid item
if (pHead->sver != 0) return sizeof(SWalHead) + pHead->len;
}
if (pHead->len < 0 || pHead->len > WAL_MAX_SIZE - sizeof(SWalHead)) {
sError("sfd:%d, wal head len out of range, hver:%" PRIu64 " len:%d", sfd, pHead->version, pHead->len);
code = syncSkipCorruptedRecord(pHead, sfd);
if (code != TSDB_CODE_SUCCESS) {
sError("sfd:%d, wal corrupted and skip failed length check, code:%d", sfd, code);
return -1;
}
// found next valid item
if (pHead->sver != 0) return sizeof(SWalHead) + pHead->len;
}
ret = read(sfd, pHead->cont, pHead->len); // read body
ret = (int32_t)read(sfd, pHead->cont, pHead->len);
if (ret < 0) { if (ret < 0) {
sError("sfd:%d, failed to read wal content since %s, ret:%d", sfd, strerror(errno), ret); sError("sfd:%d, wal read wal cont failed. read len=%d, ret:%d", sfd, pHead->len, ret);
return -1; return -1;
} }
if (ret != pHead->len) { if (ret < pHead->len) {
// file is not at end yet, it shall be reloaded sError("sfd:%d, wal read wal cont length small. need read len=%d, ret len:%d", sfd, pHead->len, ret);
sInfo("sfd:%d, a partial wal conetnt is read out, ret:%d", sfd, ret); return -1;
return 0; }
if (pHead->sver != 0 && !syncValidateChecksum(pHead)) {
sError("sfd:%d, wal check sum failed, sver=%d version:%" PRIu64 " len:%d", sfd, pHead->sver, pHead->version, pHead->len);
code = syncSkipCorruptedRecord(pHead, sfd);
if (code != TSDB_CODE_SUCCESS) {
sError("sfd:%d, wal read body check sum not right and skip corrupted failed, code:%d", sfd, code);
return -1;
}
} }
return sizeof(SWalHead) + pHead->len; return sizeof(SWalHead) + pHead->len;
......
...@@ -1080,7 +1080,7 @@ int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDFile ...@@ -1080,7 +1080,7 @@ int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDFile
int rowsToWrite = pDataCols->numOfRows; int rowsToWrite = pDataCols->numOfRows;
ASSERT(rowsToWrite > 0 && rowsToWrite <= pCfg->maxRowsPerFileBlock); ASSERT(rowsToWrite > 0 && rowsToWrite <= pCfg->maxRowsPerFileBlock);
ASSERT((!isLast) || rowsToWrite < pCfg->minRowsPerFileBlock); // ASSERT((!isLast) || rowsToWrite < pCfg->minRowsPerFileBlock);
// Make buffer space // Make buffer space
if (tsdbMakeRoom(ppBuf, tsdbBlockStatisSize(pDataCols->numOfCols, SBlockVerLatest)) < 0) { if (tsdbMakeRoom(ppBuf, tsdbBlockStatisSize(pDataCols->numOfCols, SBlockVerLatest)) < 0) {
......
...@@ -132,13 +132,16 @@ static void tsdbApplyRepoConfig(STsdbRepo *pRepo) { ...@@ -132,13 +132,16 @@ static void tsdbApplyRepoConfig(STsdbRepo *pRepo) {
pRepo->config.keep2 = pRepo->save_config.keep2; pRepo->config.keep2 = pRepo->save_config.keep2;
pRepo->config.cacheLastRow = pRepo->save_config.cacheLastRow; pRepo->config.cacheLastRow = pRepo->save_config.cacheLastRow;
pRepo->config.totalBlocks = pRepo->save_config.totalBlocks; pRepo->config.totalBlocks = pRepo->save_config.totalBlocks;
pRepo->config.minRowsPerFileBlock = pRepo->save_config.minRowsPerFileBlock;
pthread_mutex_unlock(&pRepo->save_mutex); pthread_mutex_unlock(&pRepo->save_mutex);
tsdbInfo("vgId:%d apply new config: compression(%d), keep(%d,%d,%d), totalBlocks(%d), cacheLastRow(%d->%d),totalBlocks(%d->%d)", tsdbInfo(
REPO_ID(pRepo), "vgId:%d apply new config: "
pSaveCfg->compression, pSaveCfg->keep,pSaveCfg->keep1, pSaveCfg->keep2, "compression(%d),keep(%d,%d,%d),totalBlocks(%d),cacheLastRow(%d->%d),totalBlocks(%d->%d),minRows(%d->%d)",
pSaveCfg->totalBlocks, oldCfg.cacheLastRow, pSaveCfg->cacheLastRow, oldTotalBlocks, pSaveCfg->totalBlocks); REPO_ID(pRepo), pSaveCfg->compression, pSaveCfg->keep, pSaveCfg->keep1, pSaveCfg->keep2, pSaveCfg->totalBlocks,
oldCfg.cacheLastRow, pSaveCfg->cacheLastRow, oldTotalBlocks, pSaveCfg->totalBlocks, oldCfg.minRowsPerFileBlock,
pSaveCfg->minRowsPerFileBlock);
int err = tsdbExpandPool(pRepo, oldTotalBlocks); int err = tsdbExpandPool(pRepo, oldTotalBlocks);
if (!TAOS_SUCCEEDED(err)) { if (!TAOS_SUCCEEDED(err)) {
......
...@@ -233,7 +233,7 @@ int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) { ...@@ -233,7 +233,7 @@ int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) {
ASSERT(pRCfg->tsdbId == pCfg->tsdbId); ASSERT(pRCfg->tsdbId == pCfg->tsdbId);
ASSERT(pRCfg->cacheBlockSize == pCfg->cacheBlockSize); ASSERT(pRCfg->cacheBlockSize == pCfg->cacheBlockSize);
ASSERT(pRCfg->daysPerFile == pCfg->daysPerFile); ASSERT(pRCfg->daysPerFile == pCfg->daysPerFile);
ASSERT(pRCfg->minRowsPerFileBlock == pCfg->minRowsPerFileBlock); // ASSERT(pRCfg->minRowsPerFileBlock == pCfg->minRowsPerFileBlock);
ASSERT(pRCfg->maxRowsPerFileBlock == pCfg->maxRowsPerFileBlock); ASSERT(pRCfg->maxRowsPerFileBlock == pCfg->maxRowsPerFileBlock);
ASSERT(pRCfg->precision == pCfg->precision); ASSERT(pRCfg->precision == pCfg->precision);
...@@ -256,6 +256,9 @@ int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) { ...@@ -256,6 +256,9 @@ int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) {
if (pRCfg->totalBlocks != pCfg->totalBlocks) { if (pRCfg->totalBlocks != pCfg->totalBlocks) {
configChanged = true; configChanged = true;
} }
if (pRCfg->minRowsPerFileBlock != pCfg->minRowsPerFileBlock) {
configChanged = true;
}
if (!configChanged) { if (!configChanged) {
tsdbError("vgId:%d no config changed", REPO_ID(repo)); tsdbError("vgId:%d no config changed", REPO_ID(repo));
...@@ -277,15 +280,16 @@ int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) { ...@@ -277,15 +280,16 @@ int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) {
pSaveCfg->keep2 = pCfg->keep2; pSaveCfg->keep2 = pCfg->keep2;
pSaveCfg->cacheLastRow = pCfg->cacheLastRow; pSaveCfg->cacheLastRow = pCfg->cacheLastRow;
pSaveCfg->totalBlocks = pCfg->totalBlocks; pSaveCfg->totalBlocks = pCfg->totalBlocks;
pSaveCfg->minRowsPerFileBlock = pCfg->minRowsPerFileBlock;
tsdbInfo("vgId:%d old config: compression(%d), keep(%d,%d,%d), cacheLastRow(%d),totalBlocks(%d)", tsdbInfo("vgId:%d old config: compression(%d),keep(%d,%d,%d),cacheLastRow(%d),totalBlocks(%d),minRows(%d)",
REPO_ID(repo), REPO_ID(repo),
pRCfg->compression, pRCfg->keep, pRCfg->keep1,pRCfg->keep2, pRCfg->compression, pRCfg->keep, pRCfg->keep1,pRCfg->keep2,
pRCfg->cacheLastRow, pRCfg->totalBlocks); pRCfg->cacheLastRow, pRCfg->totalBlocks, pRCfg->minRowsPerFileBlock);
tsdbInfo("vgId:%d new config: compression(%d), keep(%d,%d,%d), cacheLastRow(%d),totalBlocks(%d)", tsdbInfo("vgId:%d new config: compression(%d),keep(%d,%d,%d),cacheLastRow(%d),totalBlocks(%d),minRows(%d)",
REPO_ID(repo), REPO_ID(repo),
pSaveCfg->compression, pSaveCfg->keep,pSaveCfg->keep1, pSaveCfg->keep2, pSaveCfg->compression, pSaveCfg->keep,pSaveCfg->keep1, pSaveCfg->keep2,
pSaveCfg->cacheLastRow,pSaveCfg->totalBlocks); pSaveCfg->cacheLastRow,pSaveCfg->totalBlocks,pSaveCfg->minRowsPerFileBlock);
repo->config_changed = true; repo->config_changed = true;
...@@ -641,6 +645,7 @@ static void tsdbFreeRepo(STsdbRepo *pRepo) { ...@@ -641,6 +645,7 @@ static void tsdbFreeRepo(STsdbRepo *pRepo) {
// tsdbFreeMemTable(pRepo->imem); // tsdbFreeMemTable(pRepo->imem);
tsem_destroy(&(pRepo->readyToCommit)); tsem_destroy(&(pRepo->readyToCommit));
pthread_mutex_destroy(&pRepo->mutex); pthread_mutex_destroy(&pRepo->mutex);
pthread_mutex_destroy(&pRepo->save_mutex);
free(pRepo); free(pRepo);
} }
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
extern "C" { extern "C" {
#endif #endif
#define TSDB_CFG_MAX_NUM 136 #define TSDB_CFG_MAX_NUM 141
#define TSDB_CFG_PRINT_LEN 23 #define TSDB_CFG_PRINT_LEN 23
#define TSDB_CFG_OPTION_LEN 24 #define TSDB_CFG_OPTION_LEN 24
#define TSDB_CFG_VALUE_LEN 41 #define TSDB_CFG_VALUE_LEN 41
......
...@@ -33,6 +33,7 @@ int64_t tfOpenM(const char *pathname, int32_t flags, mode_t mode); ...@@ -33,6 +33,7 @@ int64_t tfOpenM(const char *pathname, int32_t flags, mode_t mode);
int64_t tfClose(int64_t tfd); int64_t tfClose(int64_t tfd);
int64_t tfWrite(int64_t tfd, void *buf, int64_t count); int64_t tfWrite(int64_t tfd, void *buf, int64_t count);
int64_t tfRead(int64_t tfd, void *buf, int64_t count); int64_t tfRead(int64_t tfd, void *buf, int64_t count);
int64_t fdRead(int32_t fd, void *buf, int64_t count);
int32_t tfFsync(int64_t tfd); int32_t tfFsync(int64_t tfd);
bool tfValid(int64_t tfd); bool tfValid(int64_t tfd);
int64_t tfLseek(int64_t tfd, int64_t offset, int32_t whence); int64_t tfLseek(int64_t tfd, int64_t offset, int32_t whence);
......
...@@ -32,20 +32,20 @@ int32_t tsGlobalConfigNum = 0; ...@@ -32,20 +32,20 @@ int32_t tsGlobalConfigNum = 0;
} }
static char *tsGlobalUnit[] = { static char *tsGlobalUnit[] = {
" ", " ",
"(%)", "(%)",
"(GB)", "(GB)",
"(Mb)", "(Mb)",
"(byte)", "(byte)",
"(s)", "(s)",
"(ms)" "(ms)"
}; };
char *tsCfgStatusStr[] = { char *tsCfgStatusStr[] = {
"none", "none",
"system default", "system default",
"config file", "config file",
"taos_options", "taos_options",
"program argument list" "program argument list"
}; };
...@@ -335,7 +335,7 @@ bool taosReadConfigOption(const char *option, char *value, char *value2, char *v ...@@ -335,7 +335,7 @@ bool taosReadConfigOption(const char *option, char *value, char *value2, char *v
taosReadDataDirCfg(value, value2, value3); taosReadDataDirCfg(value, value2, value3);
ret = true; ret = true;
} else { } else {
ret = false; ret = false;
} }
break; break;
default: default:
...@@ -365,8 +365,8 @@ void taosReadGlobalLogCfg() { ...@@ -365,8 +365,8 @@ void taosReadGlobalLogCfg() {
wordfree(&full_path); wordfree(&full_path);
return; return;
} }
if (full_path.we_wordv != NULL && full_path.we_wordv[0] != NULL) { if (full_path.we_wordv != NULL && full_path.we_wordv[0] != NULL) {
if (strlen(full_path.we_wordv[0]) >= TSDB_FILENAME_LEN) { if (strlen(full_path.we_wordv[0]) >= TSDB_FILENAME_LEN) {
printf("\nconfig file: %s path overflow max len %d, all variables are set to default\n", full_path.we_wordv[0], TSDB_FILENAME_LEN - 1); printf("\nconfig file: %s path overflow max len %d, all variables are set to default\n", full_path.we_wordv[0], TSDB_FILENAME_LEN - 1);
wordfree(&full_path); wordfree(&full_path);
...@@ -380,7 +380,7 @@ void taosReadGlobalLogCfg() { ...@@ -380,7 +380,7 @@ void taosReadGlobalLogCfg() {
wordfree(&full_path); wordfree(&full_path);
taosReadLogOption("logDir", tsLogDir); taosReadLogOption("logDir", tsLogDir);
sprintf(fileName, "%s/taos.cfg", configDir); sprintf(fileName, "%s/taos.cfg", configDir);
fp = fopen(fileName, "r"); fp = fopen(fileName, "r");
if (fp == NULL) { if (fp == NULL) {
...@@ -391,10 +391,10 @@ void taosReadGlobalLogCfg() { ...@@ -391,10 +391,10 @@ void taosReadGlobalLogCfg() {
ssize_t _bytes = 0; ssize_t _bytes = 0;
size_t len = 1024; size_t len = 1024;
line = calloc(1, len); line = calloc(1, len);
while (!feof(fp)) { while (!feof(fp)) {
memset(line, 0, len); memset(line, 0, len);
option = value = NULL; option = value = NULL;
olen = vlen = 0; olen = vlen = 0;
...@@ -443,7 +443,7 @@ bool taosReadGlobalCfg() { ...@@ -443,7 +443,7 @@ bool taosReadGlobalCfg() {
ssize_t _bytes = 0; ssize_t _bytes = 0;
size_t len = 1024; size_t len = 1024;
line = calloc(1, len); line = calloc(1, len);
while (!feof(fp)) { while (!feof(fp)) {
memset(line, 0, len); memset(line, 0, len);
...@@ -457,7 +457,7 @@ bool taosReadGlobalCfg() { ...@@ -457,7 +457,7 @@ bool taosReadGlobalCfg() {
} }
line[len - 1] = 0; line[len - 1] = 0;
paGetToken(line, &option, &olen); paGetToken(line, &option, &olen);
if (olen == 0) continue; if (olen == 0) continue;
option[olen] = 0; option[olen] = 0;
...@@ -495,7 +495,7 @@ void taosPrintGlobalCfg() { ...@@ -495,7 +495,7 @@ void taosPrintGlobalCfg() {
SGlobalCfg *cfg = tsGlobalConfig + i; SGlobalCfg *cfg = tsGlobalConfig + i;
if (tscEmbedded == 0 && !(cfg->cfgType & TSDB_CFG_CTYPE_B_CLIENT)) continue; if (tscEmbedded == 0 && !(cfg->cfgType & TSDB_CFG_CTYPE_B_CLIENT)) continue;
if (cfg->cfgType & TSDB_CFG_CTYPE_B_NOT_PRINT) continue; if (cfg->cfgType & TSDB_CFG_CTYPE_B_NOT_PRINT) continue;
int optionLen = (int)strlen(cfg->option); int optionLen = (int)strlen(cfg->option);
int blankLen = TSDB_CFG_PRINT_LEN - optionLen; int blankLen = TSDB_CFG_PRINT_LEN - optionLen;
blankLen = blankLen < 0 ? 0 : blankLen; blankLen = blankLen < 0 ? 0 : blankLen;
......
...@@ -93,6 +93,13 @@ int64_t tfRead(int64_t tfd, void *buf, int64_t count) { ...@@ -93,6 +93,13 @@ int64_t tfRead(int64_t tfd, void *buf, int64_t count) {
return ret; return ret;
} }
int64_t fdRead(int32_t fd, void *buf, int64_t count) {
int64_t ret = taosRead(fd, buf, count);
if (ret < 0) terrno = TAOS_SYSTEM_ERROR(errno);
return ret;
}
int32_t tfFsync(int64_t tfd) { int32_t tfFsync(int64_t tfd) {
void *p = taosAcquireRef(tsFileRsetId, tfd); void *p = taosAcquireRef(tsFileRsetId, tfd);
if (p == NULL) return -1; if (p == NULL) return -1;
......
...@@ -352,43 +352,70 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie ...@@ -352,43 +352,70 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie
serverAddr.sin_addr.s_addr = destIp; serverAddr.sin_addr.s_addr = destIp;
serverAddr.sin_port = (uint16_t)htons((uint16_t)destPort); serverAddr.sin_port = (uint16_t)htons((uint16_t)destPort);
#ifdef _TD_LINUX #if defined(_TD_LINUX)
taosSetNonblocking(sockFd, 1); taosSetNonblocking(sockFd, 1);
ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
if (ret == -1) { if (ret == -1) {
if (errno == EHOSTUNREACH) { if (errno == EHOSTUNREACH) {
uError("failed to connect socket, ip:0x%x, port:%hu(%s)", destIp, destPort, strerror(errno)); uError("failed to connect socket, ip:0x%x, port:%hu(%s)", destIp, destPort, strerror(errno));
taosCloseSocket(sockFd); taosCloseSocket(sockFd);
return -1; return -1;
} else if (errno == EINPROGRESS || errno == EAGAIN || errno == EWOULDBLOCK) { } else if (errno == EINPROGRESS || errno == EAGAIN || errno == EWOULDBLOCK) {
struct pollfd wfd[1]; struct pollfd wfd[1];
wfd[0].fd = sockFd; wfd[0].fd = sockFd;
wfd[0].events = POLLOUT; wfd[0].events = POLLOUT;
int res = poll(wfd, 1, tsTcpConnTimeout); int res = poll(wfd, 1, tsTcpConnTimeout);
if (res == -1 || res == 0) { if (res == -1 || res == 0) {
uError("failed to connect socket, ip:0x%x, port:%hu(poll error/conn timeout)", destIp, destPort); uError("failed to connect socket, ip:0x%x, port:%hu(poll error/conn timeout)", destIp, destPort);
taosCloseSocket(sockFd); // taosCloseSocket(sockFd); //
return -1; return -1;
} }
int optVal = -1, optLen = sizeof(int); int optVal = -1, optLen = sizeof(int);
if ((0 != taosGetSockOpt(sockFd, SOL_SOCKET, SO_ERROR, &optVal, &optLen)) || (optVal != 0)) { if ((0 != taosGetSockOpt(sockFd, SOL_SOCKET, SO_ERROR, &optVal, &optLen)) || (optVal != 0)) {
uError("failed to connect socket, ip:0x%x, port:%hu(connect host error)", destIp, destPort); uError("failed to connect socket, ip:0x%x, port:%hu(connect host error)", destIp, destPort);
taosCloseSocket(sockFd); // taosCloseSocket(sockFd); //
return -1; return -1;
} }
ret = 0; ret = 0;
} else { // Other error } else { // Other error
uError("failed to connect socket, ip:0x%x, port:%hu(target host cannot be reached)", destIp, destPort); uError("failed to connect socket, ip:0x%x, port:%hu(target host cannot be reached)", destIp, destPort);
taosCloseSocket(sockFd); // taosCloseSocket(sockFd); //
return -1; return -1;
} }
} }
taosSetNonblocking(sockFd, 0); taosSetNonblocking(sockFd, 0);
#elif defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)
taosSetNonblocking(sockFd, 1);
ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
if (ret == -1) {
struct timeval timeout;
fd_set set;
timeout.tv_sec = 0;
timeout.tv_usec = tsTcpConnTimeout * 1000;
FD_ZERO(&set);
FD_SET(sockFd, &set);
if (select(sockFd + 1, NULL, &set, NULL, &timeout) <= 0) {
uError("failed to connect socket, ip:0x%x, port:%hu(select error/conn timeout)", destIp, destPort);
taosCloseSocket(sockFd); //
return -1;
}
int optVal = -1, optLen = sizeof(int);
if ((0 != taosGetSockOpt(sockFd, SOL_SOCKET, SO_ERROR, &optVal, &optLen)) || (optVal != 0)) {
uError("failed to connect socket, ip:0x%x, port:%hu(connect host error)", destIp, destPort);
taosCloseSocket(sockFd); //
return -1;
}
ret = 0;
}
taosSetNonblocking(sockFd, 0);
#else #else
ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
#endif #endif
if (ret != 0) { if (ret != 0) {
......
...@@ -161,6 +161,8 @@ static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pR ...@@ -161,6 +161,8 @@ static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pR
vTrace("vgId:%d, submit msg is processed", pVnode->vgId); vTrace("vgId:%d, submit msg is processed", pVnode->vgId);
int64_t submitStartUs = taosGetTimestampUs();
if (pVnode->dbType == TSDB_DB_TYPE_TOPIC && pVnode->role == TAOS_SYNC_ROLE_MASTER) { if (pVnode->dbType == TSDB_DB_TYPE_TOPIC && pVnode->role == TAOS_SYNC_ROLE_MASTER) {
tpUpdateTs(pVnode->vgId, &pVnode->sequence, pCont); tpUpdateTs(pVnode->vgId, &pVnode->sequence, pCont);
} }
...@@ -186,6 +188,11 @@ static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pR ...@@ -186,6 +188,11 @@ static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pR
atomic_fetch_add_64(&tsSubmitRowSucNum, ntohl(pRsp->affectedRows)); atomic_fetch_add_64(&tsSubmitRowSucNum, ntohl(pRsp->affectedRows));
} }
int64_t submitEndUs = taosGetTimestampUs();
if (submitEndUs - submitStartUs > 10 * 1000000) {
vWarn("vgId: %d, submit msg process takes more than 10s", pVnode->vgId);
}
return code; return code;
} }
......
...@@ -34,8 +34,6 @@ extern int32_t wDebugFlag; ...@@ -34,8 +34,6 @@ extern int32_t wDebugFlag;
#define WAL_PREFIX "wal" #define WAL_PREFIX "wal"
#define WAL_PREFIX_LEN 3 #define WAL_PREFIX_LEN 3
#define WAL_REFRESH_MS 1000 #define WAL_REFRESH_MS 1000
#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + 16)
#define WAL_SIGNATURE ((uint32_t)(0xFAFBFDFE))
#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12) #define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12)
#define WAL_FILE_LEN (WAL_PATH_LEN + 32) #define WAL_FILE_LEN (WAL_PATH_LEN + 32)
#define WAL_FILE_NUM 1 // 3 #define WAL_FILE_NUM 1 // 3
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册