Merge branch 'develop' into xiaoping/add_test_case
This commit is contained in:
commit
ee6aaf56dc
|
@ -0,0 +1,402 @@
|
||||||
|
##########################################################################################
|
||||||
|
# Customize file classifications. #
|
||||||
|
# Results from files under any classifier will be excluded from LGTM #
|
||||||
|
# statistics. #
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
# Use the `path_classifiers` block to define changes to the default classification of #
|
||||||
|
# files. #
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
path_classifiers:
|
||||||
|
# docs:
|
||||||
|
# Identify the top-level file called `generate_javadoc.py` as documentation-related.
|
||||||
|
test:
|
||||||
|
# Override LGTM's default classification of test files by excluding all files.
|
||||||
|
- exclude: /
|
||||||
|
# Classify all files in the top-level directories tests/ and testsuites/ as test code.
|
||||||
|
- tests
|
||||||
|
# - testsuites
|
||||||
|
# Classify all files with suffix `.test` as test code.
|
||||||
|
# Note: use only forward slash / as a path separator.
|
||||||
|
# Use ** to indicate an arbitrary parent path.
|
||||||
|
# Use * to indicate any sequence of characters excluding /.
|
||||||
|
# Always enclose the expression in double quotes if it includes *.
|
||||||
|
# - "**/*.test"
|
||||||
|
# Refine the classifications above by excluding files in test/util/.
|
||||||
|
# - exclude: test/util
|
||||||
|
# The default behavior is to tag all files created during the
|
||||||
|
# build as `generated`. Results are hidden for generated code. You can tag
|
||||||
|
# further files as being generated by adding them to the `generated` section.
|
||||||
|
generated:
|
||||||
|
# Exclude all `*.c` files under the `ui/` directory from classification as
|
||||||
|
# generated code.
|
||||||
|
# - exclude: ui/**/*.c
|
||||||
|
# By default, all files not checked into the repository are considered to be
|
||||||
|
# 'generated'.
|
||||||
|
# The default behavior is to tag library code as `library`. Results are hidden
|
||||||
|
# for library code. You can tag further files as being library code by adding them
|
||||||
|
# to the `library` section.
|
||||||
|
library:
|
||||||
|
- exclude: deps/
|
||||||
|
# The default behavior is to tag template files as `template`. Results are hidden
|
||||||
|
# for template files. You can tag further files as being template files by adding
|
||||||
|
# them to the `template` section.
|
||||||
|
template:
|
||||||
|
#- exclude: path/to/template/code/**/*.c
|
||||||
|
# Define your own category, for example: 'some_custom_category'.
|
||||||
|
some_custom_category:
|
||||||
|
# Classify all files in the top-level directory tools/ (or the top-level file
|
||||||
|
# called tools).
|
||||||
|
# - tools
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# Use the `queries` block to change the default display of query results. #
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
# queries:
|
||||||
|
# Start by hiding the results of all queries.
|
||||||
|
# - exclude: "*"
|
||||||
|
# Then include all queries tagged 'security' and 'correctness', and with a severity of
|
||||||
|
# 'error'.
|
||||||
|
# - include:
|
||||||
|
# tags:
|
||||||
|
# - "security"
|
||||||
|
# - "correctness"
|
||||||
|
# severity: "error"
|
||||||
|
# Specifically hide the results of two queries.
|
||||||
|
# - exclude: cpp/use-of-goto
|
||||||
|
# - exclude: java/equals-on-unrelated-types
|
||||||
|
# Refine by including the `java/command-line-injection` query.
|
||||||
|
# - include: java/command-line-injection
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# Define changes to the default code extraction process. #
|
||||||
|
# Each block configures the extraction of a single language, and modifies actions in a #
|
||||||
|
# named step. Every named step includes automatic default actions, #
|
||||||
|
# except for the 'prepare' step. The steps are performed in the following sequence: #
|
||||||
|
# prepare #
|
||||||
|
# after_prepare #
|
||||||
|
# configure (C/C++ only) #
|
||||||
|
# python_setup (Python only) #
|
||||||
|
# before_index #
|
||||||
|
# index #
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# Environment variables available to the steps: #
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
# LGTM_SRC
|
||||||
|
# The root of the source tree.
|
||||||
|
# LGTM_WORKSPACE
|
||||||
|
# An existing (initially empty) folder outside the source tree.
|
||||||
|
# Used for temporary download and setup commands.
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# Use the extraction block to define changes to the default code extraction process #
|
||||||
|
# for one or more languages. The settings for each language are defined in a child #
|
||||||
|
# block, with one or more steps. #
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
extraction:
|
||||||
|
# Define settings for C/C++ analysis
|
||||||
|
#####################################
|
||||||
|
cpp:
|
||||||
|
# The `prepare` step exists for customization on LGTM.com only.
|
||||||
|
prepare:
|
||||||
|
# # The `packages` section is valid for LGTM.com only. It names Ubuntu packages to
|
||||||
|
# # be installed.
|
||||||
|
packages:
|
||||||
|
- cmake
|
||||||
|
# Add an `after-prepare` step if you need to run commands after the prepare step.
|
||||||
|
# Each command should be listed on a separate line.
|
||||||
|
# This step is useful for C/C++ analysis where you want to prepare the environment
|
||||||
|
# for the `configure` step without changing the default behavior for that step.
|
||||||
|
# after_prepare:
|
||||||
|
#- export GNU_MAKE=make
|
||||||
|
#- export GIT=true
|
||||||
|
# The `configure` step generates build configuration files which the `index` step
|
||||||
|
# then uses to build the codebase.
|
||||||
|
configure:
|
||||||
|
command:
|
||||||
|
- mkdir build
|
||||||
|
- cd build
|
||||||
|
- cmake ..
|
||||||
|
# - ./prepare_deps
|
||||||
|
# Optional step. You should add a `before_index` step if you need to run commands
|
||||||
|
# before the `index` step.
|
||||||
|
# before_index:
|
||||||
|
# - export BOOST_DIR=$LGTM_SRC/boost
|
||||||
|
# - export GTEST_DIR=$LGTM_SRC/googletest
|
||||||
|
# - export HUNSPELL_DIR=$LGTM_SRC/hunspell
|
||||||
|
# - export CRYPTOPP_DIR=$LGTM_SRC/cryptopp
|
||||||
|
# The `index` step builds the code and extracts information during the build
|
||||||
|
# process.
|
||||||
|
index:
|
||||||
|
# Override the autobuild process by specifying a list of custom build commands
|
||||||
|
# to use instead.
|
||||||
|
build_command:
|
||||||
|
- cd build
|
||||||
|
- make
|
||||||
|
# - $GNU_MAKE -j2 -s
|
||||||
|
# Specify that all project or solution files should be used for extraction.
|
||||||
|
# Default: false.
|
||||||
|
# all_solutions: true
|
||||||
|
# Specify a list of one or more project or solution files for extraction.
|
||||||
|
# Default: LGTM chooses the file closest to the root of the repository (this may
|
||||||
|
# fail if there are multiple candidates).
|
||||||
|
# solution:
|
||||||
|
# - myProject.sln
|
||||||
|
# Specify MSBuild settings
|
||||||
|
# msbuild:
|
||||||
|
# Specify a list of additional arguments to MSBuild. Default: empty.
|
||||||
|
# arguments: /p:Platform=x64 /p:Configuration=Release
|
||||||
|
# Specify the MSBuild configuration to use, for example, debug or release.
|
||||||
|
# Default: read from the solution file or files.
|
||||||
|
# configuration:
|
||||||
|
# Specify the platform to target, for example: x86, x64, or Any CPU.
|
||||||
|
# Default: read from the solution file or files.
|
||||||
|
# platform:
|
||||||
|
# Specify the MSBuild target. Default: rebuild.
|
||||||
|
# target:
|
||||||
|
# Specify whether or not to perform a NuGet restore for extraction. Default: true.
|
||||||
|
# nuget_restore: false
|
||||||
|
# Specify a version of Microsoft Visual Studio to use for MSBuild or any custom
|
||||||
|
# build commands (build_command). For example:
|
||||||
|
# 10 for Visual Studio 2010
|
||||||
|
# 12 for Visual Studio 2012
|
||||||
|
# 14 for Visual Studio 2015
|
||||||
|
# 15 for Visual Studio 2017
|
||||||
|
# Default: read from project files.
|
||||||
|
# vstools_version: 10
|
||||||
|
|
||||||
|
# Define settings for C# analysis
|
||||||
|
##################################
|
||||||
|
# csharp:
|
||||||
|
# The `prepare` step exists for customization on LGTM.com only.
|
||||||
|
# prepare:
|
||||||
|
# packages:
|
||||||
|
# - example_package
|
||||||
|
# Add an `after-prepare` step if you need to run commands after the `prepare` step.
|
||||||
|
# Each command should be listed on a separate line.
|
||||||
|
# after_prepare:
|
||||||
|
# - export PATH=$LGTM_WORKSPACE/tools:$PATH
|
||||||
|
# The `index` step builds the code and extracts information during the build
|
||||||
|
# process.
|
||||||
|
#index:
|
||||||
|
# Specify that all project or solution files should be used for extraction.
|
||||||
|
# Default: false.
|
||||||
|
# all_solutions: true
|
||||||
|
# Specify a list of one or more project or solution files for extraction.
|
||||||
|
# Default: LGTM chooses the file closest to the root of the repository (this may
|
||||||
|
# fail if there are multiple candidates).
|
||||||
|
# solution:
|
||||||
|
# - myProject.sln
|
||||||
|
# Override the autobuild process by specifying a list of custom build commands
|
||||||
|
# to use instead.
|
||||||
|
# build_command:
|
||||||
|
# - ./example-compile-all.sh
|
||||||
|
# By default, LGTM analyzes the code by building it. You can override this,
|
||||||
|
# and tell LGTM not to build the code. Beware that this can lead
|
||||||
|
# to less accurate results.
|
||||||
|
# buildless: true
|
||||||
|
# Specify .NET Core settings.
|
||||||
|
# dotnet:
|
||||||
|
# Specify additional arguments to `dotnet build`.
|
||||||
|
# Default: empty.
|
||||||
|
# arguments: "example_arg"
|
||||||
|
# Specify the version of .NET Core SDK to use.
|
||||||
|
# Default: The version installed on the build machine.
|
||||||
|
# version: 2.1
|
||||||
|
# Specify MSBuild settings.
|
||||||
|
# msbuild:
|
||||||
|
# Specify a list of additional arguments to MSBuild. Default: empty.
|
||||||
|
# arguments: /P:WarningLevel=2
|
||||||
|
# Specify the MSBuild configuration to use, for example, debug or release.
|
||||||
|
# Default: read from the solution file or files.
|
||||||
|
# configuration: release
|
||||||
|
# Specify the platform to target, for example: x86, x64, or Any CPU.
|
||||||
|
# Default: read from the solution file or files.
|
||||||
|
# platform: x86
|
||||||
|
# Specify the MSBuild target. Default: rebuild.
|
||||||
|
# target: notest
|
||||||
|
# Specify whether or not to perform a NuGet restore for extraction. Default: true.
|
||||||
|
# nuget_restore: false
|
||||||
|
# Specify a version of Microsoft Visual Studio to use for MSBuild or any custom
|
||||||
|
# build commands (build_command). For example:
|
||||||
|
# 10 for Visual Studio 2010
|
||||||
|
# 12 for Visual Studio 2012
|
||||||
|
# 14 for Visual Studio 2015
|
||||||
|
# 15 for Visual Studio 2017
|
||||||
|
# Default: read from project files
|
||||||
|
# vstools_version: 10
|
||||||
|
# Specify additional options for the extractor,
|
||||||
|
# for example --fast to perform a faster extraction that produces a smaller
|
||||||
|
# database.
|
||||||
|
# extractor: "--fast"
|
||||||
|
|
||||||
|
# Define settings for Go analysis
|
||||||
|
##################################
|
||||||
|
# go:
|
||||||
|
# The `prepare` step exists for customization on LGTM.com only.
|
||||||
|
# prepare:
|
||||||
|
# packages:
|
||||||
|
# - example_package
|
||||||
|
# Add an `after-prepare` step if you need to run commands after the `prepare` step.
|
||||||
|
# Each command should be listed on a separate line.
|
||||||
|
# after_prepare:
|
||||||
|
# - export PATH=$LGTM_WORKSPACE/tools:$PATH
|
||||||
|
# The `index` step builds the code and extracts information during the build
|
||||||
|
# process.
|
||||||
|
# index:
|
||||||
|
# Override the autobuild process by specifying a list of custom build commands
|
||||||
|
# to use instead.
|
||||||
|
# build_command:
|
||||||
|
# - ./compile-all.sh
|
||||||
|
|
||||||
|
# Define settings for Java analysis
|
||||||
|
####################################
|
||||||
|
# java:
|
||||||
|
# The `prepare` step exists for customization on LGTM.com only.
|
||||||
|
# prepare:
|
||||||
|
# packages:
|
||||||
|
# - example_package
|
||||||
|
# Add an `after-prepare` step if you need to run commands after the prepare step.
|
||||||
|
# Each command should be listed on a separate line.
|
||||||
|
# after_prepare:
|
||||||
|
# - export PATH=$LGTM_WORKSPACE/tools:$PATH
|
||||||
|
# The `index` step extracts information from the files in the codebase.
|
||||||
|
# index:
|
||||||
|
# Specify Gradle settings.
|
||||||
|
# gradle:
|
||||||
|
# Specify the required Gradle version.
|
||||||
|
# Default: determined automatically.
|
||||||
|
# version: 4.4
|
||||||
|
# Override the autobuild process by specifying a list of custom build commands
|
||||||
|
# to use instead.
|
||||||
|
# build_command: ./compile-all.sh
|
||||||
|
# Specify the Java version required to build the project.
|
||||||
|
# java_version: 11
|
||||||
|
# Specify whether to extract Java .properties files
|
||||||
|
# Default: false
|
||||||
|
# properties_files: true
|
||||||
|
# Specify Maven settings.
|
||||||
|
# maven:
|
||||||
|
# Specify the path (absolute or relative) of a Maven settings file to use.
|
||||||
|
# Default: Maven uses a settings file in the default location, if it exists.
|
||||||
|
# settings_file: /opt/share/settings.xml
|
||||||
|
# Specify the path of a Maven toolchains file.
|
||||||
|
# Default: Maven uses a toolchains file in the default location, if it exists.
|
||||||
|
# toolchains_file: /opt/share/toolchains.xml
|
||||||
|
# Specify the required Maven version.
|
||||||
|
# Default: the Maven version is determined automatically, where feasible.
|
||||||
|
# version: 3.5.2
|
||||||
|
# Specify how XML files should be extracted:
|
||||||
|
# all = extract all XML files.
|
||||||
|
# default = only extract XML files named `AndroidManifest.xml`, `pom.xml`, and `web.xml`.
|
||||||
|
# disabled = do not extract any XML files.
|
||||||
|
# xml_mode: all
|
||||||
|
|
||||||
|
# Define settings for JavaScript analysis
|
||||||
|
##########################################
|
||||||
|
# javascript:
|
||||||
|
# The `prepare` step exists for customization on LGTM.com only.
|
||||||
|
# prepare:
|
||||||
|
# packages:
|
||||||
|
# - example_package
|
||||||
|
# Add an `after-prepare` step if you need to run commands after the prepare step.
|
||||||
|
# Each command should be listed on a separate line.
|
||||||
|
# after_prepare:
|
||||||
|
# - export PATH=$LGTM_WORKSPACE/tools:$PATH
|
||||||
|
# The `index` step extracts information from the files in the codebase.
|
||||||
|
# index:
|
||||||
|
# Specify a list of files and folders to extract.
|
||||||
|
# Default: The project root directory.
|
||||||
|
# include:
|
||||||
|
# - src/js
|
||||||
|
# Specify a list of files and folders to exclude from extraction.
|
||||||
|
# exclude:
|
||||||
|
# - thirdparty/lib
|
||||||
|
# You can add additional file types for LGTM to extract, by mapping file
|
||||||
|
# extensions (including the leading dot) to file types. The usual
|
||||||
|
# include/exclude patterns apply, so, for example, `.jsm` files under
|
||||||
|
# `thirdparty/lib` will not be extracted.
|
||||||
|
# filetypes:
|
||||||
|
# ".jsm": "js"
|
||||||
|
# ".tmpl": "html"
|
||||||
|
# Specify a list of glob patterns to include/exclude files from extraction; this
|
||||||
|
# is applied on top of the include/exclude paths from above; patterns are
|
||||||
|
# processed in the same way as for path classifiers above.
|
||||||
|
# Default: include all files with known extensions (such as .js, .ts and .html),
|
||||||
|
# but exclude files ending in `-min.js` or `.min.js` and folders named `node_modules`
|
||||||
|
# or `bower_components`
|
||||||
|
# filters:
|
||||||
|
# exclude any *.ts files anywhere.
|
||||||
|
# - exclude: "**/*.ts"
|
||||||
|
# but include *.ts files under src/js/typescript.
|
||||||
|
# - include: "src/js/typescript/**/*.ts"
|
||||||
|
# Specify how TypeScript files should be extracted:
|
||||||
|
# none = exclude all TypeScript files.
|
||||||
|
# basic = extract syntactic information from TypeScript files.
|
||||||
|
# full = extract syntactic and type information from TypeScript files.
|
||||||
|
# Default: full.
|
||||||
|
# typescript: basic
|
||||||
|
# By default, LGTM doesn't extract any XML files. You can override this by
|
||||||
|
# using the `xml_mode` property and setting it to `all`.
|
||||||
|
# xml_mode: all
|
||||||
|
|
||||||
|
# Define settings for Python analysis
|
||||||
|
######################################
|
||||||
|
# python:
|
||||||
|
# # The `prepare` step exists for customization on LGTM.com only.
|
||||||
|
# # prepare:
|
||||||
|
# # # The `packages` section is valid for LGTM.com only. It names packages to
|
||||||
|
# # # be installed.
|
||||||
|
# # packages: libpng-dev
|
||||||
|
# # This step is useful for Python analysis where you want to prepare the
|
||||||
|
# # environment for the `python_setup` step without changing the default behavior
|
||||||
|
# # for that step.
|
||||||
|
# after_prepare:
|
||||||
|
# - export PATH=$LGTM_WORKSPACE/tools:$PATH
|
||||||
|
# # This sets up the Python interpreter and virtual environment, ready for the
|
||||||
|
# # `index` step to extract the codebase.
|
||||||
|
# python_setup:
|
||||||
|
# # Specify packages that should NOT be installed despite being mentioned in the
|
||||||
|
# # requirements.txt file.
|
||||||
|
# # Default: no package marked for exclusion.
|
||||||
|
# exclude_requirements:
|
||||||
|
# - pywin32
|
||||||
|
# # Specify a list of pip packages to install.
|
||||||
|
# # If any of these packages cannot be installed, the extraction will fail.
|
||||||
|
# requirements:
|
||||||
|
# - Pillow
|
||||||
|
# # Specify a list of requirements text files to use to set up the environment,
|
||||||
|
# # or false for none. Default: any requirements.txt, test-requirements.txt,
|
||||||
|
# # and similarly named files identified in the codebase are used.
|
||||||
|
# requirements_files:
|
||||||
|
# - required-packages.txt
|
||||||
|
# # Specify a setup.py file to use to set up the environment, or false for none.
|
||||||
|
# # Default: any setup.py files identified in the codebase are used in preference
|
||||||
|
# # to any requirements text files.
|
||||||
|
# setup_py: new-setup.py
|
||||||
|
# # Override the version of the Python interpreter used for setup and extraction
|
||||||
|
# # Default: Python 3.
|
||||||
|
# version: 2
|
||||||
|
# # Optional step. You should add a `before_index` step if you need to run commands
|
||||||
|
# # before the `index` step.
|
||||||
|
# before_index:
|
||||||
|
# - antlr4 -Dlanguage=Python3 Grammar.g4
|
||||||
|
# # The `index` step extracts information from the files in the codebase.
|
||||||
|
# index:
|
||||||
|
# # Specify a list of files and folders to exclude from extraction.
|
||||||
|
# # Default: Git submodules and Subversion externals.
|
||||||
|
# exclude:
|
||||||
|
# - legacy-implementation
|
||||||
|
# - thirdparty/libs
|
||||||
|
# filters:
|
||||||
|
# - exclude: "**/documentation/examples/snippets/*.py"
|
||||||
|
# - include: "**/documentation/examples/test_application/*"
|
||||||
|
# include:
|
||||||
|
# - example/to/include
|
|
@ -54,6 +54,7 @@ matrix:
|
||||||
|
|
||||||
py3ver=`python3 --version|awk '{print $2}'|cut -d "." -f 1,2` && apt install python$py3ver-dev
|
py3ver=`python3 --version|awk '{print $2}'|cut -d "." -f 1,2` && apt install python$py3ver-dev
|
||||||
pip3 install psutil
|
pip3 install psutil
|
||||||
|
pip3 install guppy3
|
||||||
pip3 install --user ${TRAVIS_BUILD_DIR}/src/connector/python/linux/python3/
|
pip3 install --user ${TRAVIS_BUILD_DIR}/src/connector/python/linux/python3/
|
||||||
|
|
||||||
cd ${TRAVIS_BUILD_DIR}/tests
|
cd ${TRAVIS_BUILD_DIR}/tests
|
||||||
|
|
|
@ -1,65 +1,119 @@
|
||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent none
|
||||||
|
environment{
|
||||||
|
WK = '/var/lib/jenkins/workspace/TDinternal'
|
||||||
|
WKC= '/var/lib/jenkins/workspace/TDinternal/community'
|
||||||
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('build TDengine') {
|
stage('Parallel test stage') {
|
||||||
steps {
|
|
||||||
sh '''cd ${WORKSPACE}
|
|
||||||
export TZ=Asia/Harbin
|
|
||||||
date
|
|
||||||
rm -rf ${WORKSPACE}/debug
|
|
||||||
mkdir debug
|
|
||||||
cd debug
|
|
||||||
cmake .. > /dev/null
|
|
||||||
make > /dev/null
|
|
||||||
cd ${WORKSPACE}/debug'''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('test_tsim') {
|
|
||||||
parallel {
|
parallel {
|
||||||
stage('test') {
|
stage('pytest') {
|
||||||
|
agent{label 'master'}
|
||||||
steps {
|
steps {
|
||||||
sh '''cd ${WORKSPACE}/tests
|
sh '''
|
||||||
#./test-all.sh smoke
|
date
|
||||||
sudo ./test-all.sh full'''
|
cd ${WKC}
|
||||||
|
git checkout develop
|
||||||
|
git pull
|
||||||
|
git submodule update
|
||||||
|
cd ${WK}
|
||||||
|
git checkout develop
|
||||||
|
git pull
|
||||||
|
export TZ=Asia/Harbin
|
||||||
|
date
|
||||||
|
rm -rf ${WK}/debug
|
||||||
|
mkdir debug
|
||||||
|
cd debug
|
||||||
|
cmake .. > /dev/null
|
||||||
|
make > /dev/null
|
||||||
|
cd ${WKC}/tests
|
||||||
|
#./test-all.sh smoke
|
||||||
|
./test-all.sh pytest
|
||||||
|
date'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('test_b1') {
|
||||||
|
agent{label '184'}
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
date
|
||||||
|
cd ${WKC}
|
||||||
|
git checkout develop
|
||||||
|
git pull
|
||||||
|
git submodule update
|
||||||
|
cd ${WK}
|
||||||
|
git checkout develop
|
||||||
|
git pull
|
||||||
|
export TZ=Asia/Harbin
|
||||||
|
date
|
||||||
|
rm -rf ${WK}/debug
|
||||||
|
mkdir debug
|
||||||
|
cd debug
|
||||||
|
cmake .. > /dev/null
|
||||||
|
make > /dev/null
|
||||||
|
cd ${WKC}/tests
|
||||||
|
#./test-all.sh smoke
|
||||||
|
./test-all.sh b1
|
||||||
|
date'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('test_crash_gen') {
|
stage('test_crash_gen') {
|
||||||
|
agent{label "185"}
|
||||||
steps {
|
steps {
|
||||||
sh '''cd ${WORKSPACE}/tests/pytest
|
sh '''
|
||||||
sudo ./crash_gen.sh -a -p -t 4 -s 2000'''
|
|
||||||
|
cd ${WKC}
|
||||||
|
git checkout develop
|
||||||
|
git pull
|
||||||
|
git submodule update
|
||||||
|
cd ${WK}
|
||||||
|
git checkout develop
|
||||||
|
git pull
|
||||||
|
export TZ=Asia/Harbin
|
||||||
|
|
||||||
|
rm -rf ${WK}/debug
|
||||||
|
mkdir debug
|
||||||
|
cd debug
|
||||||
|
cmake .. > /dev/null
|
||||||
|
make > /dev/null
|
||||||
|
cd ${WKC}/tests/pytest
|
||||||
|
./crash_gen.sh -a -p -t 4 -s 2000
|
||||||
|
date
|
||||||
|
cd ${WKC}/tests
|
||||||
|
./test-all.sh b2
|
||||||
|
date
|
||||||
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('test_valgrind') {
|
stage('test_valgrind') {
|
||||||
|
agent{label "186"}
|
||||||
steps {
|
steps {
|
||||||
sh '''cd ${WORKSPACE}/tests/pytest
|
sh '''
|
||||||
sudo ./valgrind-test.sh 2>&1 > mem-error-out.log
|
date
|
||||||
grep \'start to execute\\|ERROR SUMMARY\' mem-error-out.log|grep -v \'grep\'|uniq|tee uniq-mem-error-out.log
|
cd ${WKC}
|
||||||
|
git checkout develop
|
||||||
for memError in `grep \'ERROR SUMMARY\' uniq-mem-error-out.log | awk \'{print $4}\'`
|
git pull
|
||||||
do
|
git submodule update
|
||||||
if [ -n "$memError" ]; then
|
cd ${WK}
|
||||||
if [ "$memError" -gt 12 ]; then
|
git checkout develop
|
||||||
echo -e "${RED} ## Memory errors number valgrind reports is $memError.\\
|
git pull
|
||||||
More than our threshold! ## ${NC}"
|
export TZ=Asia/Harbin
|
||||||
travis_terminate $memError
|
date
|
||||||
fi
|
rm -rf ${WK}/debug
|
||||||
fi
|
mkdir debug
|
||||||
done
|
cd debug
|
||||||
|
cmake .. > /dev/null
|
||||||
grep \'start to execute\\|definitely lost:\' mem-error-out.log|grep -v \'grep\'|uniq|tee uniq-definitely-lost-out.log
|
make > /dev/null
|
||||||
for defiMemError in `grep \'definitely lost:\' uniq-definitely-lost-out.log | awk \'{print $7}\'`
|
cd ${WKC}/tests/pytest
|
||||||
do
|
./valgrind-test.sh 2>&1 > mem-error-out.log
|
||||||
if [ -n "$defiMemError" ]; then
|
./handle_val_log.sh
|
||||||
if [ "$defiMemError" -gt 13 ]; then
|
|
||||||
echo -e "${RED} ## Memory errors number valgrind reports \\
|
date
|
||||||
Definitely lost is $defiMemError. More than our threshold! ## ${NC}"
|
cd ${WKC}/tests
|
||||||
travis_terminate $defiMemError
|
./test-all.sh b3
|
||||||
fi
|
date'''
|
||||||
fi
|
|
||||||
done'''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,4 +121,5 @@ done'''
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -45,7 +45,7 @@ IF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||||
ELSEIF (${CMAKE_BUILD_TYPE} MATCHES "Release")
|
ELSEIF (${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||||
MESSAGE(STATUS "Build Release Version")
|
MESSAGE(STATUS "Build Release Version")
|
||||||
ELSE ()
|
ELSE ()
|
||||||
IF (TD_WINDOWS_64)
|
IF (TD_WINDOWS)
|
||||||
SET(CMAKE_BUILD_TYPE "Release")
|
SET(CMAKE_BUILD_TYPE "Release")
|
||||||
MESSAGE(STATUS "Build Release Version in Windows as default")
|
MESSAGE(STATUS "Build Release Version in Windows as default")
|
||||||
ELSE ()
|
ELSE ()
|
||||||
|
|
|
@ -16,6 +16,7 @@ ELSEIF (TD_WINDOWS)
|
||||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/tests/examples DESTINATION .)
|
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/tests/examples DESTINATION .)
|
||||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/packaging/cfg DESTINATION .)
|
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/packaging/cfg DESTINATION .)
|
||||||
INSTALL(FILES ${TD_COMMUNITY_DIR}/src/inc/taos.h DESTINATION include)
|
INSTALL(FILES ${TD_COMMUNITY_DIR}/src/inc/taos.h DESTINATION include)
|
||||||
|
INSTALL(FILES ${TD_COMMUNITY_DIR}/src/inc/taoserror.h DESTINATION include)
|
||||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.lib DESTINATION driver)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.lib DESTINATION driver)
|
||||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.exp DESTINATION driver)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.exp DESTINATION driver)
|
||||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver)
|
||||||
|
|
|
@ -4,7 +4,7 @@ PROJECT(TDengine)
|
||||||
IF (DEFINED VERNUMBER)
|
IF (DEFINED VERNUMBER)
|
||||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
SET(TD_VER_NUMBER "2.0.4.0")
|
SET(TD_VER_NUMBER "2.0.5.1")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (DEFINED VERCOMPATIBLE)
|
IF (DEFINED VERCOMPATIBLE)
|
||||||
|
|
|
@ -472,7 +472,7 @@ typedef uint64_t z_crc_t;
|
||||||
#endif
|
#endif
|
||||||
#ifndef Z_SOLO
|
#ifndef Z_SOLO
|
||||||
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||||
#if (_WIN64)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -472,7 +472,7 @@ typedef uLong FAR uLongf;
|
||||||
#endif
|
#endif
|
||||||
#ifndef Z_SOLO
|
#ifndef Z_SOLO
|
||||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||||
#if (_WIN64)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -11,7 +11,7 @@ TDengine的模块之一是时序数据库。但除此之外,为减少研发的
|
||||||
* __全栈时序数据处理引擎__:将数据库、消息队列、缓存、流式计算等功能融为一体,应用无需再集成Kafka/Redis/HBase/Spark/HDFS等软件,大幅降低应用开发和维护的复杂度成本。
|
* __全栈时序数据处理引擎__:将数据库、消息队列、缓存、流式计算等功能融为一体,应用无需再集成Kafka/Redis/HBase/Spark/HDFS等软件,大幅降低应用开发和维护的复杂度成本。
|
||||||
* __强大的分析功能__:无论是十年前还是一秒钟前的数据,指定时间范围即可查询。数据可在时间轴上或多个设备上进行聚合。即席查询可通过Shell, Python, R, Matlab随时进行。
|
* __强大的分析功能__:无论是十年前还是一秒钟前的数据,指定时间范围即可查询。数据可在时间轴上或多个设备上进行聚合。即席查询可通过Shell, Python, R, Matlab随时进行。
|
||||||
* __与第三方工具无缝连接__:不用一行代码,即可与Telegraf, Grafana, EMQ, Prometheus, Matlab, R等集成。后续将支持OPC, Hadoop, Spark等, BI工具也将无缝连接。
|
* __与第三方工具无缝连接__:不用一行代码,即可与Telegraf, Grafana, EMQ, Prometheus, Matlab, R等集成。后续将支持OPC, Hadoop, Spark等, BI工具也将无缝连接。
|
||||||
* __零运维成本、零学习成本__:安装、集群一秒搞定,无需分库分表,实时备份。标准SQL,支持JDBC, RESTful, 支持Python/Java/C/C++/Go, 与MySQL相似,零学习成本。
|
* __零运维成本、零学习成本__:安装集群简单快捷,无需分库分表,实时备份。类似标准SQL,支持RESTful, 支持Python/Java/C/C++/C#/Go/Node.js, 与MySQL相似,零学习成本。
|
||||||
|
|
||||||
采用TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。但需要指出的是,因充分利用了物联网时序数据的特点,它无法用来处理网络爬虫、微博、微信、电商、ERP、CRM等通用型数据。
|
采用TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。但需要指出的是,因充分利用了物联网时序数据的特点,它无法用来处理网络爬虫、微博、微信、电商、ERP、CRM等通用型数据。
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,13 @@ TDengine软件分为服务器、客户端和报警模块三部分,目前2.0版
|
||||||
|
|
||||||
- TDengine-alert-2.0.0-Linux-x64.tar.gz (8.1M)
|
- TDengine-alert-2.0.0-Linux-x64.tar.gz (8.1M)
|
||||||
|
|
||||||
目前,TDengine只支持在使用[`systemd`](https://en.wikipedia.org/wiki/Systemd)做进程服务管理的linux系统上安装。其他linux系统的支持正在开发中。用`which`命令来检测系统中是否存在`systemd`:
|
目前,TDengine只支持在使用[`systemd`](https://en.wikipedia.org/wiki/Systemd)做进程服务管理的linux系统上安装。其他linux系统的支持正在开发中。用`which systemctl`命令来检测系统中是否存在`systemd`包:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
which systemd
|
which systemctl
|
||||||
```
|
```
|
||||||
|
|
||||||
如果系统中不存在`systemd`命令,请考虑[通过源码安装](#通过源码安装)TDengine。
|
如果系统中不存在`systemd`包,请考虑[通过源码安装](#通过源码安装)TDengine。
|
||||||
|
|
||||||
具体的安装过程,请参见<a href="https://www.taosdata.com/blog/2019/08/09/566.html">TDengine多种安装包的安装和卸载</a>。
|
具体的安装过程,请参见<a href="https://www.taosdata.com/blog/2019/08/09/566.html">TDengine多种安装包的安装和卸载</a>。
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,13 @@ Three different packages are provided, please pick up the one you like.
|
||||||
<li><a id='tdengine-deb' style='color:var(--b2)'>TDengine DEB package (1.7M)</a></li>
|
<li><a id='tdengine-deb' style='color:var(--b2)'>TDengine DEB package (1.7M)</a></li>
|
||||||
<li><a id='tdengine-tar' style='color:var(--b2)'>TDengine Tarball (3.0M)</a></li>
|
<li><a id='tdengine-tar' style='color:var(--b2)'>TDengine Tarball (3.0M)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
For the time being, TDengine only supports installation on Linux systems using [`systemd`](https://en.wikipedia.org/wiki/Systemd) as the service manager. To check if your system has *systemd*, use the _which_ command.
|
For the time being, TDengine only supports installation on Linux systems using [`systemd`](https://en.wikipedia.org/wiki/Systemd) as the service manager. To check if your system has *systemd* package, use the _which systemctl_ command.
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
which systemd
|
which systemctl
|
||||||
```
|
```
|
||||||
|
|
||||||
If the `systemd` command is not found, please [install from source code](#Install-from-Source).
|
If the `systemd` package is not found, please [install from source code](#Install-from-Source).
|
||||||
|
|
||||||
### Running TDengine
|
### Running TDengine
|
||||||
|
|
||||||
|
|
|
@ -29,23 +29,9 @@ Query OK, 2 row(s) in set (0.001100s)
|
||||||
具体的查询语法请看<a href="https://www.taosdata.com/cn/documentation20/taos-sql/">TAOS SQL </a>。
|
具体的查询语法请看<a href="https://www.taosdata.com/cn/documentation20/taos-sql/">TAOS SQL </a>。
|
||||||
|
|
||||||
## 多表聚合查询
|
## 多表聚合查询
|
||||||
|
物联网场景中,往往同一个类型的数据采集点有多个。TDengine采用超级表(STable)的概念来描述某一个类型的数据采集点,一张普通的表来描述一个具体的数据采集点。同时TDengine使用标签来描述数据采集点的静态属性,一个具体的数据采集点有具体的标签值。通过指定标签的过滤条件,TDengine提供了一高效的方法将超级表(某一类型的数据采集点)所属的子表进行聚合查询。对普通表的聚合函数以及绝大部分操作都适用于超级表,语法完全一样。
|
||||||
|
|
||||||
TDengine对每个数据采集点单独建表,但在实际应用中经常需要对不同的采集点数据进行聚合。为高效的进行聚合操作,TDengine引入超级表(STable)的概念。超级表用来代表一特定类型的数据采集点,它是包含多张表的表集合,集合里每张表的模式(schema)完全一致,但每张表都带有自己的静态标签,标签可以多个,可以随时增加、删除和修改。
|
**示例1**:在TAOS Shell,查找北京所有智能电表采集的电压平均值,并按照location分组
|
||||||
|
|
||||||
应用可通过指定标签的过滤条件,对一个STable下的全部或部分表进行聚合或统计操作,这样大大简化应用的开发。其具体流程如下图所示:
|
|
||||||
|
|
||||||
<center> <img src="../assets/stable.png"> </center>
|
|
||||||
|
|
||||||
<center> 多表聚合查询原理图 </center>
|
|
||||||
|
|
||||||
1:应用将一个查询条件发往系统;2: taosc将超级表的名字发往 Meta Node(管理节点);3:管理节点将超级表所拥有的 vnode 列表发回 taosc;4:taosc将计算的请求连同标签过滤条件发往这些vnode对应的多个数据节点;5:每个vnode先在内存里查找出自己节点里符合标签过滤条件的表的集合,然后扫描存储的时序数据,完成相应的聚合计算,将结果返回给taosc;6:taosc将多个数据节点返回的结果做最后的聚合,将其返回给应用。
|
|
||||||
|
|
||||||
由于TDengine在vnode内将标签数据与时序数据分离存储,通过先在内存里过滤标签数据,将需要扫描的数据集大幅减少,大幅提升聚合计算速度。同时,由于数据分布在多个vnode/dnode,聚合计算操作在多个vnode里并发进行,又进一步提升了聚合的速度。
|
|
||||||
|
|
||||||
对普通表的聚合函数以及绝大部分操作都适用于超级表,语法完全一样,细节请看 TAOS SQL。
|
|
||||||
|
|
||||||
比如:在TAOS Shell,查找所有智能电表采集的电压平均值,并按照location分组
|
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
taos> SELECT AVG(voltage) FROM meters GROUP BY location;
|
taos> SELECT AVG(voltage) FROM meters GROUP BY location;
|
||||||
avg(voltage) | location |
|
avg(voltage) | location |
|
||||||
|
@ -55,6 +41,18 @@ taos> SELECT AVG(voltage) FROM meters GROUP BY location;
|
||||||
Query OK, 2 row(s) in set (0.002136s)
|
Query OK, 2 row(s) in set (0.002136s)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**示例2**:在TAOS shell, 查找groupId为2的所有智能电表过去24小时的记录条数,电流的最大值
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now - 24h;
|
||||||
|
cunt(*) | max(current) |
|
||||||
|
==================================
|
||||||
|
5 | 13.4 |
|
||||||
|
Query OK, 1 row(s) in set (0.002136s)
|
||||||
|
```
|
||||||
|
|
||||||
|
TDengine仅容许对属于同一个超级表的表之间进行聚合查询,不同超级表之间的聚合查询不支持。在<a href="https://www.taosdata.com/cn/documentation20/taos-sql/">TAOS SQL </a>一章,查询类操作都会注明是否支持超级表。
|
||||||
|
|
||||||
## 降采样查询、插值
|
## 降采样查询、插值
|
||||||
|
|
||||||
物联网场景里,经常需要通过降采样(down sampling)将采集的数据按时间段进行聚合。TDengine 提供了一个简便的关键词 interval 让按照时间窗口的查询操作变得极为简单。比如,将智能电表 d1001 采集的电流值每10秒钟求和
|
物联网场景里,经常需要通过降采样(down sampling)将采集的数据按时间段进行聚合。TDengine 提供了一个简便的关键词 interval 让按照时间窗口的查询操作变得极为简单。比如,将智能电表 d1001 采集的电流值每10秒钟求和
|
||||||
|
@ -66,9 +64,9 @@ taos> SELECT sum(current) FROM d1001 INTERVAL(10s);
|
||||||
2018-10-03 14:38:10.000 | 24.900000572 |
|
2018-10-03 14:38:10.000 | 24.900000572 |
|
||||||
Query OK, 2 row(s) in set (0.000883s)
|
Query OK, 2 row(s) in set (0.000883s)
|
||||||
```
|
```
|
||||||
降采样操作也适用于超级表,比如:将所有智能电表采集的电流值每秒钟求和
|
降采样操作也适用于超级表,比如:将北京所有智能电表采集的电流值每秒钟求和
|
||||||
```mysql
|
```mysql
|
||||||
taos> SELECT SUM(current) FROM meters INTERVAL(1s);
|
taos> SELECT SUM(current) FROM meters where location like "Beijing%" INTERVAL(1s);
|
||||||
ts | sum(current) |
|
ts | sum(current) |
|
||||||
======================================================
|
======================================================
|
||||||
2018-10-03 14:38:04.000 | 10.199999809 |
|
2018-10-03 14:38:04.000 | 10.199999809 |
|
||||||
|
|
|
@ -124,7 +124,8 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
||||||
说明:
|
说明:
|
||||||
1) 表的第一个字段必须是TIMESTAMP,并且系统自动将其设为主键;
|
1) 表的第一个字段必须是TIMESTAMP,并且系统自动将其设为主键;
|
||||||
2) 表名最大长度为193;
|
2) 表名最大长度为193;
|
||||||
3) 表的每行长度不能超过16k个字符;
|
3) 表的每行长度不能超过16k个字符;
|
||||||
|
4) 子表名只能由字母、数字和下划线组成,且不能以数字开头
|
||||||
5) 使用数据类型binary或nchar,需指定其最长的字节数,如binary(20),表示20字节;
|
5) 使用数据类型binary或nchar,需指定其最长的字节数,如binary(20),表示20字节;
|
||||||
|
|
||||||
- **删除数据表**
|
- **删除数据表**
|
||||||
|
|
|
@ -82,8 +82,7 @@ TDengine系统后台服务由taosd提供,可以在配置文件taos.cfg里修
|
||||||
|
|
||||||
下面仅仅列出一些重要的配置参数,更多的参数请看配置文件里的说明。各个参数的详细介绍及作用请看前述章节,而且这些参数的缺省配置都是工作的,一般无需设置。**注意:配置修改后,需要重启*taosd*服务才能生效。**
|
下面仅仅列出一些重要的配置参数,更多的参数请看配置文件里的说明。各个参数的详细介绍及作用请看前述章节,而且这些参数的缺省配置都是工作的,一般无需设置。**注意:配置修改后,需要重启*taosd*服务才能生效。**
|
||||||
|
|
||||||
- firstEp: taosd启动时,主动连接的集群中第一个dnode的end point, 默认值为localhost:6030。
|
- firstEp: taosd启动时,主动连接的集群中首个dnode的end point, 默认值为localhost:6030。
|
||||||
- secondEp: taosd启动时,如果first连接不上,尝试连接集群中第二个dnode的end point, 默认值为空。
|
|
||||||
- fqdn:数据节点的FQDN,缺省为操作系统配置的第一个hostname。如果习惯IP地址访问,可设置为该节点的IP地址。
|
- fqdn:数据节点的FQDN,缺省为操作系统配置的第一个hostname。如果习惯IP地址访问,可设置为该节点的IP地址。
|
||||||
- serverPort:taosd启动后,对外服务的端口号,默认值为6030。
|
- serverPort:taosd启动后,对外服务的端口号,默认值为6030。
|
||||||
- httpPort: RESTful服务使用的端口号,所有的HTTP请求(TCP)都需要向该接口发起查询/写入请求, 默认值为6041。
|
- httpPort: RESTful服务使用的端口号,所有的HTTP请求(TCP)都需要向该接口发起查询/写入请求, 默认值为6041。
|
||||||
|
@ -156,76 +155,80 @@ TDengine系统的前台交互客户端应用程序为taos,它与taosd共享同
|
||||||
客户端配置参数
|
客户端配置参数
|
||||||
|
|
||||||
- firstEp: taos启动时,主动连接的集群中第一个taosd实例的end point, 缺省值为 localhost:6030。
|
- firstEp: taos启动时,主动连接的集群中第一个taosd实例的end point, 缺省值为 localhost:6030。
|
||||||
- secondEp: taos启动时,如果first连接不上,尝试连接集群中第二个taosd实例的end point, 缺省值为空。
|
|
||||||
- locale
|
- locale
|
||||||
|
|
||||||
> 默认值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置
|
默认值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置
|
||||||
|
|
||||||
TDengine为存储中文、日文、韩文等非ASCII编码的宽字符,提供一种专门的字段类型nchar。写入nchar字段的数据将统一采用UCS4-LE格式进行编码并发送到服务器。需要注意的是,编码正确性是客户端来保证。因此,如果用户想要正常使用nchar字段来存储诸如中文、日文、韩文等非ASCII字符,需要正确设置客户端的编码格式。
|
TDengine为存储中文、日文、韩文等非ASCII编码的宽字符,提供一种专门的字段类型nchar。写入nchar字段的数据将统一采用UCS4-LE格式进行编码并发送到服务器。需要注意的是,编码正确性是客户端来保证。因此,如果用户想要正常使用nchar字段来存储诸如中文、日文、韩文等非ASCII字符,需要正确设置客户端的编码格式。
|
||||||
|
|
||||||
客户端的输入的字符均采用操作系统当前默认的编码格式,在Linux系统上多为UTF-8,部分中文系统编码则可能是GB18030或GBK等。在docker环境中默认的编码是POSIX。在中文版Windows系统中,编码则是CP936。客户端需要确保正确设置自己所使用的字符集,即客户端运行的操作系统当前编码字符集,才能保证nchar中的数据正确转换为UCS4-LE编码格式。
|
客户端的输入的字符均采用操作系统当前默认的编码格式,在Linux系统上多为UTF-8,部分中文系统编码则可能是GB18030或GBK等。在docker环境中默认的编码是POSIX。在中文版Windows系统中,编码则是CP936。客户端需要确保正确设置自己所使用的字符集,即客户端运行的操作系统当前编码字符集,才能保证nchar中的数据正确转换为UCS4-LE编码格式。
|
||||||
|
|
||||||
在 Linux 中 locale 的命名规则为: <语言>_<地区>.<字符集编码> 如:zh_CN.UTF-8,zh代表中文,CN代表大陆地区,UTF-8表示字符集。字符集编码为客户端正确解析本地字符串提供编码转换的说明。Linux系统与 Mac OSX 系统可以通过设置locale来确定系统的字符编码,由于Windows使用的locale中不是POSIX标准的locale格式,因此在Windows下需要采用另一个配置参数charset来指定字符编码。在Linux 系统中也可以使用charset来指定字符编码。
|
在 Linux 中 locale 的命名规则为: <语言>_<地区>.<字符集编码> 如:zh_CN.UTF-8,zh代表中文,CN代表大陆地区,UTF-8表示字符集。字符集编码为客户端正确解析本地字符串提供编码转换的说明。Linux系统与 Mac OSX 系统可以通过设置locale来确定系统的字符编码,由于Windows使用的locale中不是POSIX标准的locale格式,因此在Windows下需要采用另一个配置参数charset来指定字符编码。在Linux 系统中也可以使用charset来指定字符编码。
|
||||||
|
|
||||||
- charset
|
- charset
|
||||||
|
|
||||||
> 默认值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置
|
默认值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置
|
||||||
|
|
||||||
如果配置文件中不设置charset,在Linux系统中,taos在启动时候,自动读取系统当前的locale信息,并从locale信息中解析提取charset编码格式。如果自动读取locale信息失败,则尝试读取charset配置,如果读取charset配置也失败,则中断启动过程。
|
如果配置文件中不设置charset,在Linux系统中,taos在启动时候,自动读取系统当前的locale信息,并从locale信息中解析提取charset编码格式。如果自动读取locale信息失败,则尝试读取charset配置,如果读取charset配置也失败,则中断启动过程。
|
||||||
|
|
||||||
在Linux系统中,locale信息包含了字符编码信息,因此正确设置了Linux系统locale以后可以不用再单独设置charset。例如:
|
在Linux系统中,locale信息包含了字符编码信息,因此正确设置了Linux系统locale以后可以不用再单独设置charset。例如:
|
||||||
```
|
```
|
||||||
locale zh_CN.UTF-8
|
locale zh_CN.UTF-8
|
||||||
```
|
```
|
||||||
在Windows系统中,无法从locale获取系统当前编码。如果无法从配置文件中读取字符串编码信息,taos默认设置为字符编码为CP936。其等效在配置文件中添加如下配置:
|
在Windows系统中,无法从locale获取系统当前编码。如果无法从配置文件中读取字符串编码信息,taos默认设置为字符编码为CP936。其等效在配置文件中添加如下配置:
|
||||||
```
|
```
|
||||||
charset CP936
|
charset CP936
|
||||||
```
|
```
|
||||||
如果需要调整字符编码,请查阅当前操作系统使用的编码,并在配置文件中正确设置。
|
如果需要调整字符编码,请查阅当前操作系统使用的编码,并在配置文件中正确设置。
|
||||||
|
|
||||||
在Linux系统中,如果用户同时设置了locale和字符集编码charset,并且locale和charset的不一致,后设置的值将覆盖前面设置的值。
|
在Linux系统中,如果用户同时设置了locale和字符集编码charset,并且locale和charset的不一致,后设置的值将覆盖前面设置的值。
|
||||||
```
|
```
|
||||||
locale zh_CN.UTF-8
|
locale zh_CN.UTF-8
|
||||||
charset GBK
|
charset GBK
|
||||||
```
|
```
|
||||||
则charset的有效值是GBK。
|
则charset的有效值是GBK。
|
||||||
```
|
```
|
||||||
charset GBK
|
charset GBK
|
||||||
locale zh_CN.UTF-8
|
locale zh_CN.UTF-8
|
||||||
```
|
```
|
||||||
charset的有效值是UTF-8。
|
charset的有效值是UTF-8。
|
||||||
|
|
||||||
日志的配置参数,与server 的配置参数完全一样。
|
日志的配置参数,与server 的配置参数完全一样。
|
||||||
|
|
||||||
- timezone
|
- timezone
|
||||||
|
|
||||||
默认值:从系统中动态获取当前的时区设置
|
默认值:从系统中动态获取当前的时区设置
|
||||||
|
|
||||||
客户端运行系统所在的时区。为应对多时区的数据写入和查询问题,TDengine 采用 Unix 时间戳(Unix Timestamp)来记录和存储时间戳。Unix 时间戳的特点决定了任一时刻不论在任何时区,产生的时间戳均一致。需要注意的是,Unix时间戳是在客户端完成转换和记录。为了确保客户端其他形式的时间转换为正确的 Unix 时间戳,需要设置正确的时区。
|
客户端运行系统所在的时区。为应对多时区的数据写入和查询问题,TDengine 采用 Unix 时间戳(Unix Timestamp)来记录和存储时间戳。Unix 时间戳的特点决定了任一时刻不论在任何时区,产生的时间戳均一致。需要注意的是,Unix时间戳是在客户端完成转换和记录。为了确保客户端其他形式的时间转换为正确的 Unix 时间戳,需要设置正确的时区。
|
||||||
|
|
||||||
在Linux系统中,客户端会自动读取系统设置的时区信息。用户也可以采用多种方式在配置文件设置时区。例如:
|
在Linux系统中,客户端会自动读取系统设置的时区信息。用户也可以采用多种方式在配置文件设置时区。例如:
|
||||||
```
|
```
|
||||||
timezone UTC-8
|
timezone UTC-8
|
||||||
timezone GMT-8
|
timezone GMT-8
|
||||||
timezone Asia/Shanghai
|
timezone Asia/Shanghai
|
||||||
```
|
```
|
||||||
均是合法的设置东八区时区的格式。
|
均是合法的设置东八区时区的格式。
|
||||||
|
|
||||||
时区的设置对于查询和写入SQL语句中非Unix时间戳的内容(时间戳字符串、关键词now的解析)产生影响。例如:
|
时区的设置对于查询和写入SQL语句中非Unix时间戳的内容(时间戳字符串、关键词now的解析)产生影响。例如:
|
||||||
```
|
```
|
||||||
SELECT count(*) FROM table_name WHERE TS<'2019-04-11 12:01:08';
|
SELECT count(*) FROM table_name WHERE TS<'2019-04-11 12:01:08';
|
||||||
```
|
```
|
||||||
在东八区,SQL语句等效于
|
在东八区,SQL语句等效于
|
||||||
```
|
```
|
||||||
SELECT count(*) FROM table_name WHERE TS<1554955268000;
|
SELECT count(*) FROM table_name WHERE TS<1554955268000;
|
||||||
```
|
```
|
||||||
在UTC时区,SQL语句等效于
|
在UTC时区,SQL语句等效于
|
||||||
```
|
```
|
||||||
SELECT count(*) FROM table_name WHERE TS<1554984068000;
|
SELECT count(*) FROM table_name WHERE TS<1554984068000;
|
||||||
```
|
```
|
||||||
为了避免使用字符串时间格式带来的不确定性,也可以直接使用Unix时间戳。此外,还可以在SQL语句中使用带有时区的时间戳字符串,例如:RFC3339格式的时间戳字符串,2013-04-12T15:52:01.123+08:00或者ISO-8601格式时间戳字符串2013-04-12T15:52:01.123+0800。上述两个字符串转化为Unix时间戳不受系统所在时区的影响。
|
为了避免使用字符串时间格式带来的不确定性,也可以直接使用Unix时间戳。此外,还可以在SQL语句中使用带有时区的时间戳字符串,例如:RFC3339格式的时间戳字符串,2013-04-12T15:52:01.123+08:00或者ISO-8601格式时间戳字符串2013-04-12T15:52:01.123+0800。上述两个字符串转化为Unix时间戳不受系统所在时区的影响。
|
||||||
|
|
||||||
启动taos时,也可以从命令行指定一个taosd实例的end point,否则就从taos.cfg读取。
|
启动taos时,也可以从命令行指定一个taosd实例的end point,否则就从taos.cfg读取。
|
||||||
|
|
||||||
|
- maxBinaryDisplayWidth
|
||||||
|
|
||||||
|
Shell中binary 和 nchar字段的显示宽度上限,超过此限制的部分将被隐藏。默认值:30。可在 shell 中通过命令 set max_binary_display_width nn 动态修改此选项。
|
||||||
|
|
||||||
|
|
||||||
## 用户管理
|
## 用户管理
|
||||||
|
|
||||||
|
@ -378,7 +381,7 @@ KILL STREAM <stream-id>;
|
||||||
|
|
||||||
## 系统监控
|
## 系统监控
|
||||||
|
|
||||||
TDengine启动后,会自动创建一个监测数据库SYS,并自动将服务器的CPU、内存、硬盘空间、带宽、请求数、磁盘读写速度、慢查询等信息定时写入该数据库。TDengine还将重要的系统操作(比如登录、创建、删除数据库等)日志以及各种错误报警信息记录下来存放在SYS库里。系统管理员可以从CLI直接查看这个数据库,也可以在WEB通过图形化界面查看这些监测信息。
|
TDengine启动后,会自动创建一个监测数据库log,并自动将服务器的CPU、内存、硬盘空间、带宽、请求数、磁盘读写速度、慢查询等信息定时写入该数据库。TDengine还将重要的系统操作(比如登录、创建、删除数据库等)日志以及各种错误报警信息记录下来存放在log库里。系统管理员可以从CLI直接查看这个数据库,也可以在WEB通过图形化界面查看这些监测信息。
|
||||||
|
|
||||||
这些监测信息的采集缺省是打开的,但可以修改配置文件里的选项enableMonitor将其关闭或打开。
|
这些监测信息的采集缺省是打开的,但可以修改配置文件里的选项enableMonitor将其关闭或打开。
|
||||||
|
|
||||||
|
@ -408,5 +411,4 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
|
||||||
|
|
||||||
您可以通过修改系统配置文件taos.cfg来配置不同的数据目录和日志目录。
|
您可以通过修改系统配置文件taos.cfg来配置不同的数据目录和日志目录。
|
||||||
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
|
@ -65,24 +65,24 @@ TDengine 的设计是基于单个硬件、软件系统不可靠,基于任何
|
||||||
TDengine 分布式架构的逻辑结构图如下:
|
TDengine 分布式架构的逻辑结构图如下:
|
||||||
<center> <img src="../assets/structure.png"> </center>
|
<center> <img src="../assets/structure.png"> </center>
|
||||||
<center> 图 1 TDengine架构示意图 </center>
|
<center> 图 1 TDengine架构示意图 </center>
|
||||||
一个完整的 TDengine 系统是运行在一到多个物理节点上的,逻辑上,它包含数据节点(dnode)、TDengine客户端(taosc)以及应用(app)。系统中存在一到多个数据节点,这些数据节点组成一个集群(cluster)。应用通过taosc的API与TDengine集群进行互动。下面对每个逻辑单元进行简要介绍。
|
一个完整的 TDengine 系统是运行在一到多个物理节点上的,逻辑上,它包含数据节点(dnode)、TDengine应用驱动(taosc)以及应用(app)。系统中存在一到多个数据节点,这些数据节点组成一个集群(cluster)。应用通过taosc的API与TDengine集群进行互动。下面对每个逻辑单元进行简要介绍。
|
||||||
|
|
||||||
**物理节点(pnode):** pnode是一独立运行、拥有自己的计算、存储和网络能力的计算机,可以是安装有OS的物理机、虚拟机或容器。物理节点由其配置的 FQDN(Fully Qualified Domain Name)来标识。TDengine完全依赖FQDN来进行网络通讯,如果不了解FQDN,请看博文《[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)》。
|
**物理节点(pnode):** pnode是一独立运行、拥有自己的计算、存储和网络能力的计算机,可以是安装有OS的物理机、虚拟机或Docker容器。物理节点由其配置的 FQDN(Fully Qualified Domain Name)来标识。TDengine完全依赖FQDN来进行网络通讯,如果不了解FQDN,请看博文《[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)》。
|
||||||
|
|
||||||
**数据节点(dnode):** dnode 是 TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例,一个工作的系统必须有至少一个数据节点。dnode包含零到多个逻辑的虚拟节点(VNODE),零或者至多一个逻辑的管理节点(mnode)。dnode在系统中的唯一标识由实例的End Point (EP )决定。EP是dnode所在物理节点的FQDN (Fully Qualified Domain Name)和系统所配置的网络端口号(Port)的组合。通过配置不同的端口,一个物理节点(一台物理机、虚拟机或容器)可以运行多个实例,或有多个数据节点。
|
**数据节点(dnode):** dnode 是 TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例,一个工作的系统必须有至少一个数据节点。dnode包含零到多个逻辑的虚拟节点(VNODE),零或者至多一个逻辑的管理节点(mnode)。dnode在系统中的唯一标识由实例的End Point (EP )决定。EP是dnode所在物理节点的FQDN (Fully Qualified Domain Name)和系统所配置的网络端口号(Port)的组合。通过配置不同的端口,一个物理节点(一台物理机、虚拟机或容器)可以运行多个实例,或有多个数据节点。
|
||||||
|
|
||||||
**虚拟节点(vnode)**: 为更好的支持数据分片、负载均衡,防止数据过热或倾斜,数据节点被虚拟化成多个虚拟节点(vnode,图中V2, V3, V4等)。每个 vnode 都是一个相对独立的工作单元,是时序数据存储的基本单元,具有独立的运行线程、内存空间与持久化存储的路径。一个 vnode 包含一定数量的表(数据采集点)。当创建一张新表时,系统会检查是否需要创建新的 vnode。一个数据节点上能创建的 vnode 的数量取决于该数据节点所在物理节点的硬件资源。一个 vnode 只属于一个DB,但一个DB可以有多个 vnode。一个 vnode 除存储的时序数据外,也保存有所包含的表的SCHEMA、标签值等。一个虚拟节点由所属的数据节点的EP,以及所属的VGroup ID在系统内唯一标识,由管理节点创建并管理。
|
**虚拟节点(vnode)**: 为更好的支持数据分片、负载均衡,防止数据过热或倾斜,数据节点被虚拟化成多个虚拟节点(vnode,图中V2, V3, V4等)。每个 vnode 都是一个相对独立的工作单元,是时序数据存储的基本单元,具有独立的运行线程、内存空间与持久化存储的路径。一个 vnode 包含一定数量的表(数据采集点)。当创建一张新表时,系统会检查是否需要创建新的 vnode。一个数据节点上能创建的 vnode 的数量取决于该数据节点所在物理节点的硬件资源。一个 vnode 只属于一个DB,但一个DB可以有多个 vnode。一个 vnode 除存储的时序数据外,也保存有所包含的表的schema、标签值等。一个虚拟节点由所属的数据节点的EP,以及所属的VGroup ID在系统内唯一标识,由管理节点创建并管理。
|
||||||
|
|
||||||
**管理节点(mnode):** 一个虚拟的逻辑单元,负责所有数据节点运行状态的监控和维护,以及节点之间的负载均衡(图中M)。同时,管理节点也负责元数据(包括用户、数据库、表、静态标签等)的存储和管理,因此也称为 Meta Node。TDengine 集群中可配置多个(最多不超过5个) mnode,它们自动构建成为一个虚拟管理节点组(图中M0, M1, M2)。mnode 间采用 master/slave 的机制进行管理,而且采取强一致方式进行数据同步, 任何数据更新操作只能在 Master 上进行。mnode 集群的创建由系统自动完成,无需人工干预。每个dnode上至多有一个mnode,由所属的数据节点的EP来唯一标识。每个dnode通过内部消息交互自动获取整个集群中所有 mnode 所在的 dnode 的EP。
|
**管理节点(mnode):** 一个虚拟的逻辑单元,负责所有数据节点运行状态的监控和维护,以及节点之间的负载均衡(图中M)。同时,管理节点也负责元数据(包括用户、数据库、表、静态标签等)的存储和管理,因此也称为 Meta Node。TDengine 集群中可配置多个(最多不超过5个) mnode,它们自动构建成为一个虚拟管理节点组(图中M0, M1, M2)。mnode 间采用 master/slave 的机制进行管理,而且采取强一致方式进行数据同步, 任何数据更新操作只能在 Master 上进行。mnode 集群的创建由系统自动完成,无需人工干预。每个dnode上至多有一个mnode,由所属的数据节点的EP来唯一标识。每个dnode通过内部消息交互自动获取整个集群中所有 mnode 所在的 dnode 的EP。
|
||||||
|
|
||||||
**虚拟节点组(VGroup):** 不同数据节点上的 vnode 可以组成一个虚拟节点组(vnode group)来保证系统的高可靠。虚拟节点组内采取master/slave的方式进行管理。写操作只能在 master vnode 上进行,系统采用异步复制的方式将数据同步到 slave vnode,这样确保了一份数据在多个物理节点上有拷贝。一个 vgroup 里虚拟节点个数就是数据的副本数。如果一个DB的副本数为N,系统必须有至少N个数据节点。副本数在创建DB时通过参数 replica 可以指定,缺省为1。使用 TDengine 的多副本特性,可以不再需要昂贵的磁盘阵列等存储设备,就可以获得同样的数据高可靠性。虚拟节点组由管理节点创建、管理,并且由管理节点分配一个系统唯一的ID,VGroup ID。如果两个虚拟节点的vnode group ID相同,说明他们属于同一个组,数据互为备份。虚拟节点组里虚拟节点的个数是可以动态改变的,容许只有一个,也就是没有数据复制。VGroup ID是永远不变的,即使一个虚拟节点组被删除,它的ID也不会被收回重复利用。
|
**虚拟节点组(VGroup):** 不同数据节点上的 vnode 可以组成一个虚拟节点组(vnode group)来保证系统的高可靠。虚拟节点组内采取master/slave的方式进行管理。写操作只能在 master vnode 上进行,系统采用异步复制的方式将数据同步到 slave vnode,这样确保了一份数据在多个物理节点上有拷贝。一个 vgroup 里虚拟节点个数就是数据的副本数。如果一个DB的副本数为N,系统必须有至少N个数据节点。副本数在创建DB时通过参数 replica 可以指定,缺省为1。使用 TDengine 的多副本特性,可以不再需要昂贵的磁盘阵列等存储设备,就可以获得同样的数据高可靠性。虚拟节点组由管理节点创建、管理,并且由管理节点分配一个系统唯一的ID,VGroup ID。如果两个虚拟节点的vnode group ID相同,说明他们属于同一个组,数据互为备份。虚拟节点组里虚拟节点的个数是可以动态改变的,容许只有一个,也就是没有数据复制。VGroup ID是永远不变的,即使一个虚拟节点组被删除,它的ID也不会被收回重复利用。
|
||||||
|
|
||||||
**TAOSC:** taosc是TDengine给应用提供的驱动程序(driver),负责处理应用与集群的接口交互,内嵌于JDBC、ODBC driver中,或者C、Python、Go语言连接库里。应用都是通过taosc而不是直接连接集群中的数据节点与整个集群进行交互的。这个模块负责获取并缓存元数据;将插入、查询等请求转发到正确的数据节点;在把结果返回给应用时,还需要负责最后一级的聚合、排序、过滤等操作。对于JDBC, ODBC, C/C++接口而言,这个模块是在应用所处的物理节点上运行,但消耗的资源很小。同时,为支持全分布式的RESTful接口,taosc在TDengine集群的每个dnode上都有一运行实例。
|
**TAOSC:** taosc是TDengine给应用提供的驱动程序(driver),负责处理应用与集群的接口交互,提供C/C++语言原生接口,内嵌于JDBC、C#、Python、Go、Node.js语言连接库里。应用都是通过taosc而不是直接连接集群中的数据节点与整个集群进行交互的。这个模块负责获取并缓存元数据;将插入、查询等请求转发到正确的数据节点;在把结果返回给应用时,还需要负责最后一级的聚合、排序、过滤等操作。对于JDBC, C/C++/C#/Python/Go/Node.js接口而言,这个模块是在应用所处的物理节点上运行。同时,为支持全分布式的RESTful接口,taosc在TDengine集群的每个dnode上都有一运行实例。
|
||||||
|
|
||||||
### 节点之间的通讯
|
### 节点之间的通讯
|
||||||
**通讯方式:**TDengine系统的各个节点之间的通讯是通过TCP/UDP进行的。因为考虑到物联网场景,数据写入的包一般不大,因此TDengine 除采用TCP做传输之外,还采用UDP方式,因为UDP 更加高效,而且不受连接数的限制。TDengine实现了自己的超时、重传、确认等机制,以确保UDP的可靠传输。对于数据量不到15K的数据包,采取UDP的方式进行传输,超过15K的,或者是查询类的操作,自动采取TCP的方式进行传输。同时,TDengine根据配置和数据包,会自动对数据进行压缩/解压缩,数字签名/认证等处理。对于数据节点之间的数据复制,只采用TCP方式进行数据传输。
|
**通讯方式:**TDengine系统的各个数据节点之间,以及应用驱动与各数据节点之间的通讯是通过TCP/UDP进行的。因为考虑到物联网场景,数据写入的包一般不大,因此TDengine 除采用TCP做传输之外,还采用UDP方式,因为UDP 更加高效,而且不受连接数的限制。TDengine实现了自己的超时、重传、确认等机制,以确保UDP的可靠传输。对于数据量不到15K的数据包,采取UDP的方式进行传输,超过15K的,或者是查询类的操作,自动采取TCP的方式进行传输。同时,TDengine根据配置和数据包,会自动对数据进行压缩/解压缩,数字签名/认证等处理。对于数据节点之间的数据复制,只采用TCP方式进行数据传输。
|
||||||
|
|
||||||
**FQDN配置**:一个数据节点有一个或多个FQDN,可以在系统配置文件taos.cfg通过参数“fqdn"进行指定,如果没有指定,系统将自动获取FQDN。如果节点没有配置FQDN,可以直接将该节点的配置参数fqdn设置为它的IP地址。但不建议使用IP,因为IP地址可变,一旦变化,将让集群无法正常工作。一个数据节点的EP(End Point)由FQDN + Port组成。采用FQDN,需要保证DNS服务正常工作,或者在节点以及应用所在的节点配置好hosts文件。
|
**FQDN配置**:一个数据节点有一个或多个FQDN,可以在系统配置文件taos.cfg通过参数“fqdn"进行指定,如果没有指定,系统将自动获取计算机的hostname作为其FQDN。如果节点没有配置FQDN,可以直接将该节点的配置参数fqdn设置为它的IP地址。但不建议使用IP,因为IP地址可变,一旦变化,将让集群无法正常工作。一个数据节点的EP(End Point)由FQDN + Port组成。采用FQDN,需要保证DNS服务正常工作,或者在节点以及应用所在的节点配置好hosts文件。
|
||||||
|
|
||||||
**端口配置:**一个数据节点对外的端口由TDengine的系统配置参数serverPort决定,对集群内部通讯的端口是serverPort+5。集群内数据节点之间的数据复制操作还占有一个TCP端口,是serverPort+10. 为支持多线程高效的处理UDP数据,每个对内和对外的UDP连接,都需要占用5个连续的端口。因此一个数据节点总的端口范围为serverPort到serverPort + 10,总共11个TCP/UDP端口。使用时,需要确保防火墙将这些端口打开。每个数据节点可以配置不同的serverPort。
|
**端口配置:**一个数据节点对外的端口由TDengine的系统配置参数serverPort决定,对集群内部通讯的端口是serverPort+5。集群内数据节点之间的数据复制操作还占有一个TCP端口,是serverPort+10. 为支持多线程高效的处理UDP数据,每个对内和对外的UDP连接,都需要占用5个连续的端口。因此一个数据节点总的端口范围为serverPort到serverPort + 10,总共11个TCP/UDP端口。使用时,需要确保防火墙将这些端口打开。每个数据节点可以配置不同的serverPort。
|
||||||
|
|
||||||
|
@ -153,6 +153,7 @@ TDengine除vnode分片之外,还对时序数据按照时间段进行分区。
|
||||||
当新的数据节点被添加进集群,因为新的计算和存储被添加进来,系统也将自动启动负载均衡流程。
|
当新的数据节点被添加进集群,因为新的计算和存储被添加进来,系统也将自动启动负载均衡流程。
|
||||||
|
|
||||||
负载均衡过程无需任何人工干预,应用也无需重启,将自动连接新的节点,完全透明。
|
负载均衡过程无需任何人工干预,应用也无需重启,将自动连接新的节点,完全透明。
|
||||||
|
**提示:负载均衡由参数balance控制,决定开启/关闭自动负载均衡。**
|
||||||
|
|
||||||
## 数据写入与复制流程
|
## 数据写入与复制流程
|
||||||
如果一个数据库有N个副本,那一个虚拟节点组就有N个虚拟节点,但是只有一个是Master,其他都是slave。当应用将新的记录写入系统时,只有Master vnode能接受写的请求。如果slave vnode收到写的请求,系统将通知taosc需要重新定向。
|
如果一个数据库有N个副本,那一个虚拟节点组就有N个虚拟节点,但是只有一个是Master,其他都是slave。当应用将新的记录写入系统时,只有Master vnode能接受写的请求。如果slave vnode收到写的请求,系统将通知taosc需要重新定向。
|
||||||
|
@ -192,7 +193,8 @@ Master Vnode遵循下面的写入流程:
|
||||||
|
|
||||||
理论上,只要是异步复制,就无法保证100%不丢失。但是这个窗口极小,mater与slave要同时发生故障,而且发生在刚给应用确认写入成功之后。
|
理论上,只要是异步复制,就无法保证100%不丢失。但是这个窗口极小,mater与slave要同时发生故障,而且发生在刚给应用确认写入成功之后。
|
||||||
|
|
||||||
注:异地容灾、IDC无中断迁移,仅仅企业版支持
|
注:异地容灾、IDC无中断迁移,仅仅企业版支持。
|
||||||
|
**提示:该功能暂未提供**
|
||||||
|
|
||||||
### 主从选择
|
### 主从选择
|
||||||
Vnode会保持一个数据版本号(Version),对内存数据进行持久化存储时,对该版本号也进行持久化存储。每个数据更新操作,无论是采集的时序数据还是元数据,这个版本号将增一。
|
Vnode会保持一个数据版本号(Version),对内存数据进行持久化存储时,对该版本号也进行持久化存储。每个数据更新操作,无论是采集的时序数据还是元数据,这个版本号将增一。
|
||||||
|
@ -259,6 +261,7 @@ dataDir /mnt/disk6/taos 2
|
||||||
挂载的盘也可以是非本地的网络盘,只要系统能访问即可。
|
挂载的盘也可以是非本地的网络盘,只要系统能访问即可。
|
||||||
|
|
||||||
注:多级存储功能仅企业版支持
|
注:多级存储功能仅企业版支持
|
||||||
|
**提示:该功能暂未提供**
|
||||||
|
|
||||||
## 数据查询
|
## 数据查询
|
||||||
TDengine提供了多种多样针对表和超级表的查询处理功能,除了常规的聚合查询之外,还提供针对时序数据的窗口查询、统计聚合等功能。TDengine的查询处理需要客户端、vnode, mnode节点协同完成。
|
TDengine提供了多种多样针对表和超级表的查询处理功能,除了常规的聚合查询之外,还提供针对时序数据的窗口查询、统计聚合等功能。TDengine的查询处理需要客户端、vnode, mnode节点协同完成。
|
||||||
|
@ -289,11 +292,18 @@ select count(*) from d1001 interval(1h) fill(prev);
|
||||||
针对d1001设备采集数据统计每小时记录数,如果某一个小时不存在数据,这返回之前一个小时的统计数据。TDengine提供前向插值(prev)、线性插值(linear)、NULL值填充(NULL)、特定值填充(value)。
|
针对d1001设备采集数据统计每小时记录数,如果某一个小时不存在数据,这返回之前一个小时的统计数据。TDengine提供前向插值(prev)、线性插值(linear)、NULL值填充(NULL)、特定值填充(value)。
|
||||||
|
|
||||||
### 多表聚合查询
|
### 多表聚合查询
|
||||||
多表聚合查询与单表查询的整体流程相同,但是存在如下的差异:
|
TDengine对每个数据采集点单独建表,但在实际应用中经常需要对不同的采集点数据进行聚合。为高效的进行聚合操作,TDengine引入超级表(STable)的概念。超级表用来代表一特定类型的数据采集点,它是包含多张表的表集合,集合里每张表的模式(schema)完全一致,但每张表都带有自己的静态标签,标签可以多个,可以随时增加、删除和修改。 应用可通过指定标签的过滤条件,对一个STable下的全部或部分表进行聚合或统计操作,这样大大简化应用的开发。其具体流程如下图所示:
|
||||||
|
<center> <img src="../assets/multi_tables.png"> </center>
|
||||||
|
|
||||||
- 由于多表可能分布在不同的节点(dnode),因此多表的聚合查询需要首先获得表所在的全部数据节点的信息,并且同时向相关的dnode发出查询请求。
|
<center> 图 5 多表聚合查询原理图 </center>
|
||||||
- 每个vnode的计算获得的中间结果(partial results)需要进行第二阶段的聚合才能形成最终结果,第二阶段的聚合过程在客户端完成。
|
1:应用将一个查询条件发往系统;
|
||||||
- 由于表标签信息存储在vnode中,因此针对标签信息的查询也需要vnode完成。客户端将标签的过滤表达式封装在查询请求结构体中发送给vnode,由vnode的查询执行线程从中抽取出标签查询条件,然后执行查询。标签查询与过滤是在针对表的查询之前完成。标签查询完成以后,将符合条件的表纳入到接下来的查询处理流程中。
|
2: taosc将超级表的名字发往 Meta Node(管理节点);
|
||||||
|
3:管理节点将超级表所拥有的 vnode 列表发回 taosc;
|
||||||
|
4:taosc将计算的请求连同标签过滤条件发往这些vnode对应的多个数据节点;
|
||||||
|
5:每个vnode先在内存里查找出自己节点里符合标签过滤条件的表的集合,然后扫描存储的时序数据,完成相应的聚合计算,将结果返回给taosc;
|
||||||
|
6:taosc将多个数据节点返回的结果做最后的聚合,将其返回给应用。
|
||||||
|
|
||||||
|
由于TDengine在vnode内将标签数据与时序数据分离存储,通过在内存里过滤标签数据,先找到需要参与聚合操作的表的集合,将需要扫描的数据集大幅减少,大幅提升聚合计算速度。同时,由于数据分布在多个vnode/dnode,聚合计算操作在多个vnode里并发进行,又进一步提升了聚合的速度。 对普通表的聚合函数以及绝大部分操作都适用于超级表,语法完全一样,细节请看 TAOS SQL。
|
||||||
|
|
||||||
### 预计算
|
### 预计算
|
||||||
为有效提升查询处理的性能,针对物联网数据的不可更改的特点,在数据块头部记录该数据块中存储数据的统计信息:包括最大值、最小值、和。我们称之为预计算单元。如果查询处理涉及整个数据块的全部数据,直接使用预计算结果,完全不需要读取数据块的内容。由于预计算数据量远小于磁盘上存储的数据块数据的大小,对于磁盘IO为瓶颈的查询处理,使用预计算结果可以极大地减小读取IO压力,加速查询处理的流程。预计算机制与Postgre SQL的索引BRIN(block range index)有异曲同工之妙。
|
为有效提升查询处理的性能,针对物联网数据的不可更改的特点,在数据块头部记录该数据块中存储数据的统计信息:包括最大值、最小值、和。我们称之为预计算单元。如果查询处理涉及整个数据块的全部数据,直接使用预计算结果,完全不需要读取数据块的内容。由于预计算数据量远小于磁盘上存储的数据块数据的大小,对于磁盘IO为瓶颈的查询处理,使用预计算结果可以极大地减小读取IO压力,加速查询处理的流程。预计算机制与Postgre SQL的索引BRIN(block range index)有异曲同工之妙。
|
||||||
|
|
|
@ -8,7 +8,7 @@ TDengine的集群管理极其简单,除添加和删除节点需要人工干预
|
||||||
|
|
||||||
## 准备工作
|
## 准备工作
|
||||||
|
|
||||||
**第零步**:如果没有部署DNS服务,请规划集群所有物理节点的FQDN,然后按照《[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)》里的步骤,将所有集群物理节点的IP与FQDN的对应关系添加好。
|
**第零步**:规划集群所有物理节点的FQDN,将规划好的FQDN分别添加到每个物理节点的/etc/hostname;修改每个物理节点的/etc/hosts,将所有集群物理节点的IP与FQDN的对应添加好。【如部署了DNS,请联系网络管理员在DNS上做好相关配置】
|
||||||
|
|
||||||
**第一步**:如果搭建集群的物理节点中,存有之前的测试数据、装过1.X的版本,或者装过其他版本的TDengine,请先将其删除,并清空所有数据,具体步骤请参考博客[《TDengine多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html )
|
**第一步**:如果搭建集群的物理节点中,存有之前的测试数据、装过1.X的版本,或者装过其他版本的TDengine,请先将其删除,并清空所有数据,具体步骤请参考博客[《TDengine多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html )
|
||||||
**注意1:**因为FQDN的信息会写进文件,如果之前没有配置或者更改FQDN,且启动了TDengine。请一定在确保数据无用或者备份的前提下,清理一下之前的数据(rm -rf /var/lib/taos/);
|
**注意1:**因为FQDN的信息会写进文件,如果之前没有配置或者更改FQDN,且启动了TDengine。请一定在确保数据无用或者备份的前提下,清理一下之前的数据(rm -rf /var/lib/taos/);
|
||||||
|
@ -16,9 +16,9 @@ TDengine的集群管理极其简单,除添加和删除节点需要人工干预
|
||||||
|
|
||||||
**第二步**:建议关闭所有物理节点的防火墙,至少保证端口:6030 - 6042的TCP和UDP端口都是开放的。**强烈建议**先关闭防火墙,集群搭建完毕之后,再来配置端口;
|
**第二步**:建议关闭所有物理节点的防火墙,至少保证端口:6030 - 6042的TCP和UDP端口都是开放的。**强烈建议**先关闭防火墙,集群搭建完毕之后,再来配置端口;
|
||||||
|
|
||||||
**第三步**:在所有节点安装TDengine,且版本必须是一致的,**但不要启动taosd**。安装时,提示输入是否要加入一个已经存在的TDengine集群时,第一个物理节点直接回车创建新集群,后续物理节点则输入该集群任何一个在线的物理节点的FQDN:端口号(默认6030);
|
**第三步**:在所有物理节点安装TDengine,且版本必须是一致的,**但不要启动taosd**。安装时,提示输入是否要加入一个已经存在的TDengine集群时,第一个物理节点直接回车创建新集群,后续物理节点则输入该集群任何一个在线的物理节点的FQDN:端口号(默认6030);
|
||||||
|
|
||||||
**第四步**:检查所有数据节点,以及应用所在物理节点的网络设置:
|
**第四步**:检查所有数据节点,以及应用程序所在物理节点的网络设置:
|
||||||
|
|
||||||
1. 每个物理节点上执行命令`hostname -f`,查看和确认所有节点的hostname是不相同的(应用驱动所在节点无需做此项检查);
|
1. 每个物理节点上执行命令`hostname -f`,查看和确认所有节点的hostname是不相同的(应用驱动所在节点无需做此项检查);
|
||||||
2. 每个物理节点上执行`ping host`, 其中host是其他物理节点的hostname, 看能否ping通其它物理节点; 如果不能ping通,需要检查网络设置, 或/etc/hosts文件(Windows系统默认路径为C:\Windows\system32\drivers\etc\hosts),或DNS的配置。如果无法ping通,是无法组成集群的;
|
2. 每个物理节点上执行`ping host`, 其中host是其他物理节点的hostname, 看能否ping通其它物理节点; 如果不能ping通,需要检查网络设置, 或/etc/hosts文件(Windows系统默认路径为C:\Windows\system32\drivers\etc\hosts),或DNS的配置。如果无法ping通,是无法组成集群的;
|
||||||
|
|
|
@ -72,38 +72,34 @@ maven 项目中使用如下 pom.xml 配置即可:
|
||||||
|
|
||||||
### 获取连接
|
### 获取连接
|
||||||
|
|
||||||
如下所示配置即可获取 TDengine Connection:
|
#### 通过JdbcUrl获取连接
|
||||||
|
|
||||||
|
通过指定的jdbcUrl获取连接,如下所示:
|
||||||
```java
|
```java
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:6030/log?user=root&password=taosdata";
|
String jdbcUrl = "jdbc:TAOS://taosdemo.com:6030/test?user=root&password=taosdata";
|
||||||
Connection conn = DriverManager.getConnection(jdbcUrl);
|
Connection conn = DriverManager.getConnection(jdbcUrl);
|
||||||
```
|
```
|
||||||
> 端口 6030 为默认连接端口,JDBC URL 中的 log 为系统本身的监控数据库。
|
以上示例,建立了到hostname为taosdemo.com,端口为6030(TDengine的默认端口),数据库名为test的连接。这个url中指定用户名(user)为root,密码(password)为taosdata。
|
||||||
|
|
||||||
TDengine 的 JDBC URL 规范格式为:
|
TDengine 的 JDBC URL 规范格式为:
|
||||||
`jdbc:TAOS://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
`jdbc:TAOS://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||||
|
url中的配置参数如下:
|
||||||
其中,`{}` 中的内容必须,`[]` 中为可选。配置参数说明如下:
|
|
||||||
|
|
||||||
* user:登录 TDengine 用户名,默认值 root。
|
* user:登录 TDengine 用户名,默认值 root。
|
||||||
* password:用户登录密码,默认值 taosdata。
|
* password:用户登录密码,默认值 taosdata。
|
||||||
* charset:客户端使用的字符集,默认值为系统字符集。
|
|
||||||
* cfgdir:客户端配置文件目录路径,Linux OS 上默认值 /etc/taos ,Windows OS 上默认值 C:/TDengine/cfg。
|
* cfgdir:客户端配置文件目录路径,Linux OS 上默认值 /etc/taos ,Windows OS 上默认值 C:/TDengine/cfg。
|
||||||
|
* charset:客户端使用的字符集,默认值为系统字符集。
|
||||||
* locale:客户端语言环境,默认值系统当前 locale。
|
* locale:客户端语言环境,默认值系统当前 locale。
|
||||||
* timezone:客户端使用的时区,默认值为系统当前时区。
|
* timezone:客户端使用的时区,默认值为系统当前时区。
|
||||||
|
|
||||||
以上参数可以在 3 处配置,`优先级由高到低`分别如下:
|
#### 使用JdbcUrl和Properties获取连接
|
||||||
1. JDBC URL 参数
|
|
||||||
如上所述,可以在 JDBC URL 的参数中指定。
|
除了通过指定的jdbcUrl获取连接,还可以使用Properties指定建立连接时的参数,如下所示:
|
||||||
2. java.sql.DriverManager.getConnection(String jdbcUrl, Properties connProps)
|
|
||||||
```java
|
```java
|
||||||
public Connection getConn() throws Exception{
|
public Connection getConn() throws Exception{
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:0/log?user=root&password=taosdata";
|
String jdbcUrl = "jdbc:TAOS://taosdemo.com:6030/test?user=root&password=taosdata";
|
||||||
Properties connProps = new Properties();
|
Properties connProps = new Properties();
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR, "/etc/taos");
|
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
@ -111,16 +107,39 @@ public Connection getConn() throws Exception{
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
以上示例,建立一个到hostname为taosdemo.com,端口为6030,数据库名为test的连接。这个连接在url中指定了用户名(user)为root,密码(password)为taosdata,并在connProps中指定了使用的字符集、语言环境、时区等信息。
|
||||||
|
|
||||||
3. 客户端配置文件 taos.cfg
|
properties中的配置参数如下:
|
||||||
|
* TSDBDriver.PROPERTY_KEY_USER:登录 TDengine 用户名,默认值 root。
|
||||||
|
* TSDBDriver.PROPERTY_KEY_PASSWORD:用户登录密码,默认值 taosdata。
|
||||||
|
* TSDBDriver.PROPERTY_KEY_CONFIG_DIR:客户端配置文件目录路径,Linux OS 上默认值 /etc/taos ,Windows OS 上默认值 C:/TDengine/cfg。
|
||||||
|
* TSDBDriver.PROPERTY_KEY_CHARSET:客户端使用的字符集,默认值为系统字符集。
|
||||||
|
* TSDBDriver.PROPERTY_KEY_LOCALE:客户端语言环境,默认值系统当前 locale。
|
||||||
|
* TSDBDriver.PROPERTY_KEY_TIME_ZONE:客户端使用的时区,默认值为系统当前时区。
|
||||||
|
|
||||||
linux 系统默认配置文件为 /var/lib/taos/taos.cfg,windows 系统默认配置文件路径为 C:\TDengine\cfg\taos.cfg。
|
#### 使用客户端配置文件建立连接
|
||||||
```properties
|
当使用JDBC连接TDengine集群时,可以使用客户端配置文件,在客户端配置文件中指定集群的firstEp、secondEp参数。
|
||||||
# client default username
|
如下所示:
|
||||||
# defaultUser root
|
1. 在java中不指定hostname和port
|
||||||
|
```java
|
||||||
|
public Connection getConn() throws Exception{
|
||||||
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
String jdbcUrl = "jdbc:TAOS://:/test?user=root&password=taosdata";
|
||||||
|
Properties connProps = new Properties();
|
||||||
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
2. 在配置文件中指定firstEp和secondEp
|
||||||
|
```
|
||||||
|
# first fully qualified domain name (FQDN) for TDengine system
|
||||||
|
firstEp cluster_node1:6030
|
||||||
|
|
||||||
# client default password
|
# second fully qualified domain name (FQDN) for TDengine system, for cluster only
|
||||||
# defaultPass taosdata
|
secondEp cluster_node2:6030
|
||||||
|
|
||||||
# default system charset
|
# default system charset
|
||||||
# charset UTF-8
|
# charset UTF-8
|
||||||
|
@ -128,6 +147,19 @@ public Connection getConn() throws Exception{
|
||||||
# system locale
|
# system locale
|
||||||
# locale en_US.UTF-8
|
# locale en_US.UTF-8
|
||||||
```
|
```
|
||||||
|
|
||||||
|
以上示例,jdbc会使用客户端的配置文件,建立到hostname为cluster_node1,端口为6030,数据库名为test的连接。当集群中firstEp节点失效时,JDBC会尝试使用secondEp连接集群。
|
||||||
|
TDengine中,只要保证firstEp和secondEp中一个节点有效,就可以正常建立到集群的连接。
|
||||||
|
|
||||||
|
> 注意:这里的配置文件指的是调用JDBC Connector的应用程序所在机器上的配置文件,Linux OS 上默认值 /etc/taos/taos.cfg ,Windows OS 上默认值 C://TDengine/cfg/taos.cfg。
|
||||||
|
|
||||||
|
#### 配置参数的优先级
|
||||||
|
通过以上3种方式获取连接,如果配置参数在url、Properties、客户端配置文件中有重复,则参数的`优先级由高到低`分别如下:
|
||||||
|
1. JDBC URL 参数,如上所述,可以在 JDBC URL 的参数中指定。
|
||||||
|
2. Properties connProps
|
||||||
|
3. 客户端配置文件 taos.cfg
|
||||||
|
例如:在url中指定了password为taosdata,在Properties中指定了password为taosdemo,那么,JDBC会使用url中的password建立连接。
|
||||||
|
|
||||||
> 更多详细配置请参考[客户端配置][13]
|
> 更多详细配置请参考[客户端配置][13]
|
||||||
|
|
||||||
### 创建数据库和表
|
### 创建数据库和表
|
||||||
|
|
|
@ -22,7 +22,7 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6,
|
||||||
|
|
||||||
**Tips:**
|
**Tips:**
|
||||||
|
|
||||||
- 要提高写入效率,需要批量写入。一批写入的记录条数越多,插入效率就越高。但一条记录不能超过16K,一条SQL语句总长度不能超过64K(可通过参数maxSQLLength配置,最大可配置为8M)。
|
- 要提高写入效率,需要批量写入。一批写入的记录条数越多,插入效率就越高。但一条记录不能超过16K,一条SQL语句总长度不能超过64K(可通过参数maxSQLLength配置,最大可配置为1M)。
|
||||||
- TDengine支持多线程同时写入,要进一步提高写入速度,一个客户端需要打开20个以上的线程同时写。但线程数达到一定数量后,无法再提高,甚至还会下降,因为线程切频繁切换,带来额外开销。
|
- TDengine支持多线程同时写入,要进一步提高写入速度,一个客户端需要打开20个以上的线程同时写。但线程数达到一定数量后,无法再提高,甚至还会下降,因为线程切频繁切换,带来额外开销。
|
||||||
- 对同一张表,如果新插入记录的时间戳已经存在,新记录将被直接抛弃,也就是说,在一张表里,时间戳必须是唯一的。如果应用自动生成记录,很有可能生成的时间戳是一样的,这样,成功插入的记录条数会小于应用插入的记录条数。
|
- 对同一张表,如果新插入记录的时间戳已经存在,新记录将被直接抛弃,也就是说,在一张表里,时间戳必须是唯一的。如果应用自动生成记录,很有可能生成的时间戳是一样的,这样,成功插入的记录条数会小于应用插入的记录条数。
|
||||||
- 写入的数据的时间戳必须大于当前时间减去配置参数keep的时间。如果keep配置为3650天,那么无法写入比3650天还老的数据。写入数据的时间戳也不能大于当前时间加配置参数days。如果days配置为2,那么无法写入比当前时间还晚2天的数据。
|
- 写入的数据的时间戳必须大于当前时间减去配置参数keep的时间。如果keep配置为3650天,那么无法写入比3650天还老的数据。写入数据的时间戳也不能大于当前时间加配置参数days。如果days配置为2,那么无法写入比当前时间还晚2天的数据。
|
||||||
|
|
|
@ -6,73 +6,76 @@
|
||||||
########################################################
|
########################################################
|
||||||
|
|
||||||
# first fully qualified domain name (FQDN) for TDengine system
|
# first fully qualified domain name (FQDN) for TDengine system
|
||||||
# firstEp hostname1:6030
|
# firstEp hostname:6030
|
||||||
|
|
||||||
# second fully qualified domain name (FQDN) for TDengine system, for cluster only
|
|
||||||
# secondEp cluster_hostname2:6030
|
|
||||||
|
|
||||||
# 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
|
||||||
# logDir /var/log/taos
|
# logDir /var/log/taos
|
||||||
|
|
||||||
# data file's directory
|
# data file's directory
|
||||||
# dataDir /var/lib/taos
|
# dataDir /var/lib/taos
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
# the proportion of total threads responsible for query
|
||||||
|
# ratioOfQueryThreads 0.5
|
||||||
|
|
||||||
# number of management nodes in the system
|
# number of management nodes in the system
|
||||||
# numOfMnodes 3
|
# numOfMnodes 3
|
||||||
|
|
||||||
# enable/disable backuping vnode directory when removing dnode
|
# enable/disable backuping vnode directory when removing dnode
|
||||||
# vnodeBak 1
|
# vnodeBak 1
|
||||||
|
|
||||||
|
# if report installation / use information
|
||||||
|
# telemetryReporting 1
|
||||||
|
|
||||||
# enable/disable load balancing
|
# enable/disable load balancing
|
||||||
# balance 1
|
# balance 1
|
||||||
|
|
||||||
# role for dnode. 0 - any, 1 - mnode, 2 - dnode
|
# role for dnode. 0 - any, 1 - mnode, 2 - dnode
|
||||||
# role 0
|
# role 0
|
||||||
|
|
||||||
# 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 8640000
|
# offlineThreshold 8640000
|
||||||
|
|
||||||
# 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
|
||||||
# shellActivityTimer 3
|
# shellActivityTimer 3
|
||||||
|
|
||||||
# time of keeping table meta data in cache, seconds
|
# time of keeping table meta data in cache, seconds
|
||||||
# tableMetaKeepTimer 7200
|
# tableMetaKeepTimer 7200
|
||||||
|
|
||||||
# minimum sliding window time, milli-second
|
# minimum sliding window time, milli-second
|
||||||
# minSlidingTime 10
|
# minSlidingTime 10
|
||||||
|
|
||||||
# minimum time window, milli-second
|
# minimum time window, milli-second
|
||||||
# minIntervalTime 10
|
# minIntervalTime 10
|
||||||
|
|
||||||
# maximum delay before launching a stream compution, milli-second
|
# maximum delay before launching a stream compution, milli-second
|
||||||
# maxStreamCompDelay 20000
|
# maxStreamCompDelay 20000
|
||||||
|
|
||||||
# maximum delay before launching a stream computation for the first time, milli-second
|
# maximum delay before launching a stream computation for the first time, milli-second
|
||||||
# maxFirstStreamCompDelay 10000
|
# maxFirstStreamCompDelay 10000
|
||||||
|
@ -89,9 +92,6 @@
|
||||||
# max number of tables per vnode
|
# max number of tables per vnode
|
||||||
# maxTablesPerVnode 1000000
|
# maxTablesPerVnode 1000000
|
||||||
|
|
||||||
# step size of increasing table number in a vnode
|
|
||||||
# tableIncStepPerVnode 1000
|
|
||||||
|
|
||||||
# cache block size (Mbyte)
|
# cache block size (Mbyte)
|
||||||
# cache 16
|
# cache 16
|
||||||
|
|
||||||
|
@ -110,6 +110,9 @@
|
||||||
# maximum rows of records in file block
|
# maximum rows of records in file block
|
||||||
# maxRows 4096
|
# maxRows 4096
|
||||||
|
|
||||||
|
# the number of acknowledgments required for successful data writing
|
||||||
|
# quorum 1
|
||||||
|
|
||||||
# enable/disable compression
|
# enable/disable compression
|
||||||
# comp 2
|
# comp 2
|
||||||
|
|
||||||
|
@ -122,15 +125,6 @@
|
||||||
# number of replications, for cluster only
|
# number of replications, for cluster only
|
||||||
# replica 1
|
# replica 1
|
||||||
|
|
||||||
# mqtt hostname
|
|
||||||
# mqttHostName test.mosquitto.org
|
|
||||||
|
|
||||||
# mqtt port
|
|
||||||
# mqttPort 1883
|
|
||||||
|
|
||||||
# mqtt topic
|
|
||||||
# mqttTopic /test
|
|
||||||
|
|
||||||
# the compressed rpc message, option:
|
# the compressed rpc message, option:
|
||||||
# -1 (no compression)
|
# -1 (no compression)
|
||||||
# 0 (all message compressed),
|
# 0 (all message compressed),
|
||||||
|
@ -167,12 +161,12 @@
|
||||||
# stop writing data when the disk size of the log folder is less than this value
|
# stop writing data when the disk size of the log folder is less than this value
|
||||||
# minimalDataDirGB 0.1
|
# minimalDataDirGB 0.1
|
||||||
|
|
||||||
|
# One mnode is equal to the number of vnode consumed
|
||||||
|
# mnodeEqualVnodeNum 4
|
||||||
|
|
||||||
# enbale/disable http service
|
# enbale/disable http service
|
||||||
# http 1
|
# http 1
|
||||||
|
|
||||||
# enable/disable muqq service
|
|
||||||
# mqtt 0
|
|
||||||
|
|
||||||
# enable/disable system monitor
|
# enable/disable system monitor
|
||||||
# monitor 1
|
# monitor 1
|
||||||
|
|
||||||
|
@ -189,11 +183,12 @@
|
||||||
# max number of rows per log filters
|
# max number of rows per log filters
|
||||||
# numOfLogLines 10000000
|
# numOfLogLines 10000000
|
||||||
|
|
||||||
|
# enable/disable async log
|
||||||
|
# asyncLog 1
|
||||||
|
|
||||||
# time of keeping log files, days
|
# time of keeping log files, days
|
||||||
# logKeepDays 0
|
# logKeepDays 0
|
||||||
|
|
||||||
# enable/disable async log
|
|
||||||
# asyncLog 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
|
||||||
|
@ -231,18 +226,12 @@
|
||||||
# debug flag for JNI
|
# debug flag for JNI
|
||||||
# jniDebugflag 131
|
# jniDebugflag 131
|
||||||
|
|
||||||
# debug flag for ODBC
|
|
||||||
# odbcDebugflag 131
|
|
||||||
|
|
||||||
# debug flag for storage
|
# debug flag for storage
|
||||||
# uDebugflag 131
|
# uDebugflag 131
|
||||||
|
|
||||||
# debug flag for http server
|
# debug flag for http server
|
||||||
# httpDebugFlag 131
|
# httpDebugFlag 131
|
||||||
|
|
||||||
# debug flag for mqtt
|
|
||||||
# mqttDebugFlag 131
|
|
||||||
|
|
||||||
# debug flag for monitor
|
# debug flag for monitor
|
||||||
# monitorDebugFlag 131
|
# monitorDebugFlag 131
|
||||||
|
|
||||||
|
@ -255,6 +244,9 @@
|
||||||
# debug flag for http server
|
# debug flag for http server
|
||||||
# tsdbDebugFlag 131
|
# tsdbDebugFlag 131
|
||||||
|
|
||||||
|
# debug flag for continue query
|
||||||
|
# cqDebugFlag 131
|
||||||
|
|
||||||
# enable/disable recording the SQL in taos client
|
# enable/disable recording the SQL in taos client
|
||||||
# tscEnableRecordSql 0
|
# tscEnableRecordSql 0
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
FROM centos:7
|
FROM ubuntu:16
|
||||||
|
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
|
ARG version
|
||||||
|
RUN echo $version
|
||||||
COPY tdengine.tar.gz /root/
|
COPY tdengine.tar.gz /root/
|
||||||
RUN tar -zxf tdengine.tar.gz
|
RUN tar -zxf tdengine.tar.gz
|
||||||
WORKDIR /root/TDengine-server/
|
WORKDIR /root/TDengine-server-$version/
|
||||||
RUN sh install.sh -e no
|
RUN sh install.sh -e no
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -x
|
set -x
|
||||||
docker build --rm -f "Dockerfile" -t tdengine/tdengine:$1 "."
|
docker build --rm -f "Dockerfile" -t tdengine/tdengine:$1 "." --build-arg version=$1
|
||||||
docker login -u tdengine -p $2 #replace the docker registry username and password
|
docker login -u tdengine -p $2 #replace the docker registry username and password
|
||||||
docker push tdengine/tdengine:$1
|
docker push tdengine/tdengine:$1
|
||||||
|
|
|
@ -272,6 +272,29 @@ function install_config() {
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# user email
|
||||||
|
#EMAIL_PATTERN='^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$'
|
||||||
|
#EMAIL_PATTERN='^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$'
|
||||||
|
#EMAIL_PATTERN="^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"
|
||||||
|
echo
|
||||||
|
echo -e -n "${GREEN}Enter your email address for priority support or enter empty to skip${NC}: "
|
||||||
|
read emailAddr
|
||||||
|
while true; do
|
||||||
|
if [ ! -z "$emailAddr" ]; then
|
||||||
|
# check the format of the emailAddr
|
||||||
|
#if [[ "$emailAddr" =~ $EMAIL_PATTERN ]]; then
|
||||||
|
# Write the email address to temp file
|
||||||
|
email_file="${install_main_dir}/email"
|
||||||
|
${csudo} bash -c "echo $emailAddr > ${email_file}"
|
||||||
|
break
|
||||||
|
#else
|
||||||
|
# read -p "Please enter the correct email address: " emailAddr
|
||||||
|
#fi
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: tdengine
|
name: tdengine
|
||||||
base: core18
|
base: core18
|
||||||
version: 'RELEASE_VERSION'
|
version: '2.0.5.1'
|
||||||
icon: snap/gui/t-dengine.svg
|
icon: snap/gui/t-dengine.svg
|
||||||
summary: an open-source big data platform designed and optimized for IoT.
|
summary: an open-source big data platform designed and optimized for IoT.
|
||||||
description: |
|
description: |
|
||||||
|
@ -72,7 +72,7 @@ parts:
|
||||||
- usr/bin/taosd
|
- usr/bin/taosd
|
||||||
- usr/bin/taos
|
- usr/bin/taos
|
||||||
- usr/bin/taosdemo
|
- usr/bin/taosdemo
|
||||||
- usr/lib/libtaos.so.RELEASE_VERSION
|
- usr/lib/libtaos.so.2.0.5.1
|
||||||
- usr/lib/libtaos.so.1
|
- usr/lib/libtaos.so.1
|
||||||
- usr/lib/libtaos.so
|
- usr/lib/libtaos.so
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,8 @@ int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
||||||
|
|
||||||
balanceAccquireDnodeList();
|
balanceAccquireDnodeList();
|
||||||
|
|
||||||
|
mDebug("db:%s, try alloc %d vnodes to vgroup, dnodes total:%d, avail:%d", pVgroup->dbName, pVgroup->numOfVnodes,
|
||||||
|
mnodeGetDnodesNum(), tsBalanceDnodeListSize);
|
||||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||||
for (; dnode < tsBalanceDnodeListSize; ++dnode) {
|
for (; dnode < tsBalanceDnodeListSize; ++dnode) {
|
||||||
SDnodeObj *pDnode = tsBalanceDnodeList[dnode];
|
SDnodeObj *pDnode = tsBalanceDnodeList[dnode];
|
||||||
|
@ -135,17 +137,33 @@ int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
||||||
pVnodeGid->pDnode = pDnode;
|
pVnodeGid->pDnode = pDnode;
|
||||||
dnode++;
|
dnode++;
|
||||||
vnodes++;
|
vnodes++;
|
||||||
|
mDebug("dnode:%d, is selected, vnodeIndex:%d", pDnode->dnodeId, i);
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
mDebug("dnode:%d, is not selected, status:%s vnodes:%d disk:%fGB role:%d", pDnode->dnodeId,
|
||||||
|
mnodeGetDnodeStatusStr(pDnode->status), pDnode->openVnodes, pDnode->diskAvailable,
|
||||||
|
pDnode->alternativeRole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vnodes != pVgroup->numOfVnodes) {
|
if (vnodes != pVgroup->numOfVnodes) {
|
||||||
mDebug("vgId:%d, db:%s need vnodes:%d, but alloc:%d, free them", pVgroup->vgId, pVgroup->dbName,
|
|
||||||
pVgroup->numOfVnodes, vnodes);
|
|
||||||
balanceReleaseDnodeList();
|
balanceReleaseDnodeList();
|
||||||
balanceUnLock();
|
balanceUnLock();
|
||||||
|
|
||||||
|
mDebug("db:%s, need vnodes:%d, but alloc:%d", pVgroup->dbName, pVgroup->numOfVnodes, vnodes);
|
||||||
|
|
||||||
|
void * pIter = NULL;
|
||||||
|
SDnodeObj *pDnode = NULL;
|
||||||
|
while (1) {
|
||||||
|
pIter = mnodeGetNextDnode(pIter, &pDnode);
|
||||||
|
if (pDnode == NULL) break;
|
||||||
|
mDebug("dnode:%d, status:%s vnodes:%d disk:%fGB role:%d", pDnode->dnodeId, mnodeGetDnodeStatusStr(pDnode->status),
|
||||||
|
pDnode->openVnodes, pDnode->diskAvailable, pDnode->alternativeRole);
|
||||||
|
mnodeDecDnodeRef(pDnode);
|
||||||
|
}
|
||||||
|
sdbFreeIter(pIter);
|
||||||
|
|
||||||
if (mnodeGetOnlineDnodesNum() == 0) {
|
if (mnodeGetOnlineDnodesNum() == 0) {
|
||||||
return TSDB_CODE_MND_NOT_READY;
|
return TSDB_CODE_MND_NOT_READY;
|
||||||
} else {
|
} else {
|
||||||
|
@ -553,7 +571,8 @@ static void balanceCheckDnodeAccess() {
|
||||||
if (pDnode->status != TAOS_DN_STATUS_DROPPING && pDnode->status != TAOS_DN_STATUS_OFFLINE) {
|
if (pDnode->status != TAOS_DN_STATUS_DROPPING && pDnode->status != TAOS_DN_STATUS_OFFLINE) {
|
||||||
pDnode->status = TAOS_DN_STATUS_OFFLINE;
|
pDnode->status = TAOS_DN_STATUS_OFFLINE;
|
||||||
pDnode->offlineReason = TAOS_DN_OFF_STATUS_MSG_TIMEOUT;
|
pDnode->offlineReason = TAOS_DN_OFF_STATUS_MSG_TIMEOUT;
|
||||||
mInfo("dnode:%d, set to offline state", pDnode->dnodeId);
|
mInfo("dnode:%d, set to offline state, access seq:%d, last seq:%d", pDnode->dnodeId, tsAccessSquence,
|
||||||
|
pDnode->lastAccess);
|
||||||
balanceSetVgroupOffline(pDnode);
|
balanceSetVgroupOffline(pDnode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -937,6 +956,7 @@ static int32_t balanceRetrieveScores(SShowObj *pShow, char *data, int32_t rows,
|
||||||
mnodeDecDnodeRef(pDnode);
|
mnodeDecDnodeRef(pDnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
@ -957,11 +977,16 @@ static void balanceMonitorDnodeModule() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLInfo("dnode:%d, numOfMnodes:%d expect:%d, add mnode in this dnode", pDnode->dnodeId, numOfMnodes, tsNumOfMnodes);
|
mLInfo("dnode:%d, numOfMnodes:%d expect:%d, create mnode in this dnode", pDnode->dnodeId, numOfMnodes, tsNumOfMnodes);
|
||||||
mnodeAddMnode(pDnode->dnodeId);
|
mnodeCreateMnode(pDnode->dnodeId, pDnode->dnodeEp, true);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Only create one mnode each time
|
||||||
|
return;
|
||||||
|
#else
|
||||||
numOfMnodes = mnodeGetMnodesNum();
|
numOfMnodes = mnodeGetMnodesNum();
|
||||||
if (numOfMnodes >= tsNumOfMnodes) return;
|
if (numOfMnodes >= tsNumOfMnodes) return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,17 +72,10 @@ typedef struct SLocalReducer {
|
||||||
bool orderPrjOnSTable; // projection query on stable
|
bool orderPrjOnSTable; // projection query on stable
|
||||||
} SLocalReducer;
|
} SLocalReducer;
|
||||||
|
|
||||||
typedef struct SSubqueryState {
|
|
||||||
int32_t numOfRemain; // the number of remain unfinished subquery
|
|
||||||
int32_t numOfTotal; // the number of total sub-queries
|
|
||||||
uint64_t numOfRetrievedRows; // total number of points in this query
|
|
||||||
} SSubqueryState;
|
|
||||||
|
|
||||||
typedef struct SRetrieveSupport {
|
typedef struct SRetrieveSupport {
|
||||||
tExtMemBuffer ** pExtMemBuffer; // for build loser tree
|
tExtMemBuffer ** pExtMemBuffer; // for build loser tree
|
||||||
tOrderDescriptor *pOrderDescriptor;
|
tOrderDescriptor *pOrderDescriptor;
|
||||||
SColumnModel * pFinalColModel; // colModel for final result
|
SColumnModel * pFinalColModel; // colModel for final result
|
||||||
SSubqueryState * pState;
|
|
||||||
int32_t subqueryIndex; // index of current vnode in vnode list
|
int32_t subqueryIndex; // index of current vnode in vnode list
|
||||||
SSqlObj * pParentSql;
|
SSqlObj * pParentSql;
|
||||||
tFilePage * localBuffer; // temp buffer, there is a buffer for each vnode to
|
tFilePage * localBuffer; // temp buffer, there is a buffer for each vnode to
|
||||||
|
|
|
@ -66,7 +66,6 @@ typedef struct STidTags {
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
typedef struct SJoinSupporter {
|
typedef struct SJoinSupporter {
|
||||||
SSubqueryState* pState;
|
|
||||||
SSqlObj* pObj; // parent SqlObj
|
SSqlObj* pObj; // parent SqlObj
|
||||||
int32_t subqueryIndex; // index of sub query
|
int32_t subqueryIndex; // index of sub query
|
||||||
SInterval interval;
|
SInterval interval;
|
||||||
|
@ -207,8 +206,6 @@ void tscTagCondRelease(STagCond* pCond);
|
||||||
|
|
||||||
void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo);
|
void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
void tscSetFreeHeatBeat(STscObj* pObj);
|
|
||||||
bool tscShouldFreeHeartBeat(SSqlObj* pHb);
|
|
||||||
bool tscShouldBeFreed(SSqlObj* pSql);
|
bool tscShouldBeFreed(SSqlObj* pSql);
|
||||||
|
|
||||||
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex);
|
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex);
|
||||||
|
|
|
@ -80,6 +80,8 @@ enum {
|
||||||
DATA_FROM_DATA_FILE = 2,
|
DATA_FROM_DATA_FILE = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows);
|
||||||
|
|
||||||
typedef struct STableComInfo {
|
typedef struct STableComInfo {
|
||||||
uint8_t numOfTags;
|
uint8_t numOfTags;
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
|
@ -226,7 +228,7 @@ typedef struct STableDataBlocks {
|
||||||
typedef struct SQueryInfo {
|
typedef struct SQueryInfo {
|
||||||
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
||||||
uint32_t type; // query/insert type
|
uint32_t type; // query/insert type
|
||||||
// TODO refactor
|
|
||||||
STimeWindow window; // query time window
|
STimeWindow window; // query time window
|
||||||
SInterval interval;
|
SInterval interval;
|
||||||
|
|
||||||
|
@ -334,6 +336,12 @@ typedef struct STscObj {
|
||||||
T_REF_DECLARE()
|
T_REF_DECLARE()
|
||||||
} STscObj;
|
} STscObj;
|
||||||
|
|
||||||
|
typedef struct SSubqueryState {
|
||||||
|
int32_t numOfRemain; // the number of remain unfinished subquery
|
||||||
|
int32_t numOfSub; // the number of total sub-queries
|
||||||
|
uint64_t numOfRetrievedRows; // total number of points in this query
|
||||||
|
} SSubqueryState;
|
||||||
|
|
||||||
typedef struct SSqlObj {
|
typedef struct SSqlObj {
|
||||||
void *signature;
|
void *signature;
|
||||||
pthread_t owner; // owner of sql object, by which it is executed
|
pthread_t owner; // owner of sql object, by which it is executed
|
||||||
|
@ -355,10 +363,11 @@ typedef struct SSqlObj {
|
||||||
tsem_t rspSem;
|
tsem_t rspSem;
|
||||||
SSqlCmd cmd;
|
SSqlCmd cmd;
|
||||||
SSqlRes res;
|
SSqlRes res;
|
||||||
uint16_t numOfSubs;
|
|
||||||
struct SSqlObj **pSubs;
|
|
||||||
struct SSqlObj * prev, *next;
|
|
||||||
|
|
||||||
|
SSubqueryState subState;
|
||||||
|
struct SSqlObj **pSubs;
|
||||||
|
|
||||||
|
struct SSqlObj *prev, *next;
|
||||||
struct SSqlObj **self;
|
struct SSqlObj **self;
|
||||||
} SSqlObj;
|
} SSqlObj;
|
||||||
|
|
||||||
|
@ -433,19 +442,20 @@ void tscPartiallyFreeSqlObj(SSqlObj *pSql);
|
||||||
* @param pObj
|
* @param pObj
|
||||||
*/
|
*/
|
||||||
void tscFreeSqlObj(SSqlObj *pSql);
|
void tscFreeSqlObj(SSqlObj *pSql);
|
||||||
|
void tscFreeRegisteredSqlObj(void *pSql);
|
||||||
void tscFreeSqlObjInCache(void *pSql);
|
|
||||||
|
|
||||||
void tscCloseTscObj(STscObj *pObj);
|
void tscCloseTscObj(STscObj *pObj);
|
||||||
|
|
||||||
|
// todo move to taos? or create a new file: taos_internal.h
|
||||||
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, void **taos);
|
void *param, void **taos);
|
||||||
void waitForQueryRsp(void *param, TAOS_RES *tres, int code) ;
|
TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, TAOS_RES** res);
|
||||||
|
|
||||||
void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, void (*fp)(), void *param, const char *sqlstr, size_t sqlLen);
|
void waitForQueryRsp(void *param, TAOS_RES *tres, int code);
|
||||||
|
|
||||||
|
void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, __async_cb_func_t fp, void *param, const char *sqlstr, size_t sqlLen);
|
||||||
|
|
||||||
void tscProcessMultiVnodesImportFromFile(SSqlObj *pSql);
|
void tscProcessMultiVnodesImportFromFile(SSqlObj *pSql);
|
||||||
void tscKillSTableQuery(SSqlObj *pSql);
|
|
||||||
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen);
|
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen);
|
||||||
bool tscIsUpdateQuery(SSqlObj* pSql);
|
bool tscIsUpdateQuery(SSqlObj* pSql);
|
||||||
bool tscHasReachLimitation(SQueryInfo *pQueryInfo, SSqlRes *pRes);
|
bool tscHasReachLimitation(SQueryInfo *pQueryInfo, SSqlRes *pRes);
|
||||||
|
@ -510,8 +520,6 @@ extern SRpcCorEpSet tscMgmtEpSet;
|
||||||
|
|
||||||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||||
|
|
||||||
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int numOfRows);
|
|
||||||
|
|
||||||
int32_t tscCompareTidTags(const void* p1, const void* p2);
|
int32_t tscCompareTidTags(const void* p1, const void* p2);
|
||||||
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
|
||||||
static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows);
|
static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows);
|
||||||
static void tscAsyncFetchSingleRowProxy(void *param, TAOS_RES *tres, int numOfRows);
|
static void tscAsyncFetchSingleRowProxy(void *param, TAOS_RES *tres, int numOfRows);
|
||||||
|
|
||||||
void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const char* sqlstr, size_t sqlLen) {
|
void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* param, const char* sqlstr, size_t sqlLen) {
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
pSql->signature = pSql;
|
pSql->signature = pSql;
|
||||||
|
@ -361,15 +361,6 @@ void tscProcessFetchRow(SSchedMsg *pMsg) {
|
||||||
(*pSql->fetchFp)(pSql->param, pSql, pRes->tsrow);
|
(*pSql->fetchFp)(pSql->param, pSql, pRes->tsrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscProcessAsyncRes(SSchedMsg *pMsg) {
|
|
||||||
SSqlObj *pSql = (SSqlObj *)pMsg->ahandle;
|
|
||||||
SSqlRes *pRes = &pSql->res;
|
|
||||||
assert(pSql->fp != NULL && pSql->fetchFp != NULL);
|
|
||||||
|
|
||||||
pSql->fp = pSql->fetchFp;
|
|
||||||
(*pSql->fp)(pSql->param, pSql, pRes->code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this function will be executed by queue task threads, so the terrno is not valid
|
// this function will be executed by queue task threads, so the terrno is not valid
|
||||||
static void tscProcessAsyncError(SSchedMsg *pMsg) {
|
static void tscProcessAsyncError(SSchedMsg *pMsg) {
|
||||||
void (*fp)() = pMsg->ahandle;
|
void (*fp)() = pMsg->ahandle;
|
||||||
|
@ -393,22 +384,15 @@ void tscQueueAsyncRes(SSqlObj *pSql) {
|
||||||
if (pSql == NULL || pSql->signature != pSql) {
|
if (pSql == NULL || pSql->signature != pSql) {
|
||||||
tscDebug("%p SqlObj is freed, not add into queue async res", pSql);
|
tscDebug("%p SqlObj is freed, not add into queue async res", pSql);
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
tscError("%p add into queued async res, code:%s", pSql, tstrerror(pSql->res.code));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchedMsg schedMsg = { 0 };
|
tscError("%p add into queued async res, code:%s", pSql, tstrerror(pSql->res.code));
|
||||||
schedMsg.fp = tscProcessAsyncRes;
|
|
||||||
schedMsg.ahandle = pSql;
|
|
||||||
schedMsg.thandle = (void *)1;
|
|
||||||
schedMsg.msg = NULL;
|
|
||||||
taosScheduleTask(tscQhandle, &schedMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tscProcessAsyncFree(SSchedMsg *pMsg) {
|
SSqlRes *pRes = &pSql->res;
|
||||||
SSqlObj *pSql = (SSqlObj *)pMsg->ahandle;
|
assert(pSql->fp != NULL && pSql->fetchFp != NULL);
|
||||||
tscDebug("%p sql is freed", pSql);
|
|
||||||
taos_free_result(pSql);
|
pSql->fp = pSql->fetchFp;
|
||||||
|
(*pSql->fp)(pSql->param, pSql, pRes->code);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscSendMsgToServer(SSqlObj *pSql);
|
int tscSendMsgToServer(SSqlObj *pSql);
|
||||||
|
|
|
@ -639,7 +639,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
||||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pSql->numOfSubs);
|
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pSql->subState.numOfSub);
|
||||||
if (*pMemBuffer == NULL) {
|
if (*pMemBuffer == NULL) {
|
||||||
tscError("%p failed to allocate memory", pSql);
|
tscError("%p failed to allocate memory", pSql);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
@ -742,6 +742,7 @@ void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDe
|
||||||
int32_t numOfVnodes) {
|
int32_t numOfVnodes) {
|
||||||
destroyColumnModel(pFinalModel);
|
destroyColumnModel(pFinalModel);
|
||||||
tOrderDescDestroy(pDesc);
|
tOrderDescDestroy(pDesc);
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||||
pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]);
|
pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,10 +151,12 @@ void tscKillQuery(STscObj *pObj, uint32_t killId) {
|
||||||
|
|
||||||
pthread_mutex_unlock(&pObj->mutex);
|
pthread_mutex_unlock(&pObj->mutex);
|
||||||
|
|
||||||
if (pSql == NULL) return;
|
if (pSql == NULL) {
|
||||||
|
tscError("failed to kill query, id:%d, it may have completed/terminated", killId);
|
||||||
tscDebug("%p query is killed, queryId:%d", pSql, killId);
|
} else {
|
||||||
taos_stop_query(pSql);
|
tscDebug("%p query is killed, queryId:%d", pSql, killId);
|
||||||
|
taos_stop_query(pSql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscAddIntoStreamList(SSqlStream *pStream) {
|
void tscAddIntoStreamList(SSqlStream *pStream) {
|
||||||
|
@ -242,6 +244,7 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) {
|
||||||
pQdesc->stime = htobe64(pSql->stime);
|
pQdesc->stime = htobe64(pSql->stime);
|
||||||
pQdesc->queryId = htonl(pSql->queryId);
|
pQdesc->queryId = htonl(pSql->queryId);
|
||||||
pQdesc->useconds = htobe64(pSql->res.useconds);
|
pQdesc->useconds = htobe64(pSql->res.useconds);
|
||||||
|
pQdesc->qHandle = htobe64(pSql->res.qhandle);
|
||||||
|
|
||||||
pHeartbeat->numOfQueries++;
|
pHeartbeat->numOfQueries++;
|
||||||
pQdesc++;
|
pQdesc++;
|
||||||
|
|
|
@ -1200,6 +1200,10 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr
|
||||||
return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
|
return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
|
||||||
|
SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
|
tscColumnListInsert(pQueryInfo->colList, &tsCol);
|
||||||
|
}
|
||||||
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
|
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
|
||||||
const char* msg1 = "invalid column name, or illegal column type";
|
const char* msg1 = "invalid column name, or illegal column type";
|
||||||
const char* msg2 = "invalid arithmetic expression in select clause";
|
const char* msg2 = "invalid arithmetic expression in select clause";
|
||||||
|
@ -1275,6 +1279,8 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t
|
||||||
addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len, index.tableIndex);
|
addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len, index.tableIndex);
|
||||||
|
|
||||||
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
|
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
|
||||||
|
// add ts column
|
||||||
|
tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
|
||||||
|
|
||||||
tbufCloseWriter(&bw);
|
tbufCloseWriter(&bw);
|
||||||
taosArrayDestroy(colList);
|
taosArrayDestroy(colList);
|
||||||
|
@ -1317,10 +1323,6 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
|
|
||||||
SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
|
||||||
tscColumnListInsert(pQueryInfo->colList, &tsCol);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSQLExprItem* pItem) {
|
static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSQLExprItem* pItem) {
|
||||||
SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos, pIndex->columnIndex, pIndex->tableIndex);
|
SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, startPos, pIndex->columnIndex, pIndex->tableIndex);
|
||||||
|
@ -1603,8 +1605,8 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, SConvertFunc cvtFunc, char* aliasName,
|
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, SConvertFunc cvtFunc,
|
||||||
int32_t resColIdx, SColumnIndex* pColIndex) {
|
char* aliasName, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult) {
|
||||||
const char* msg1 = "not support column types";
|
const char* msg1 = "not support column types";
|
||||||
|
|
||||||
int16_t type = 0;
|
int16_t type = 0;
|
||||||
|
@ -1650,8 +1652,13 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
|
||||||
SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
tscColumnListInsert(pQueryInfo->colList, &index);
|
tscColumnListInsert(pQueryInfo->colList, &index);
|
||||||
|
|
||||||
|
// if it is not in the final result, do not add it
|
||||||
SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
|
SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
|
||||||
insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, columnName, pExpr);
|
if (finalResult) {
|
||||||
|
insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, columnName, pExpr);
|
||||||
|
} else {
|
||||||
|
tscColumnListInsert(pQueryInfo->colList, &(ids.ids[0]));
|
||||||
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1926,7 +1933,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
|
|
||||||
for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
|
for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
|
||||||
index.columnIndex = j;
|
index.columnIndex = j;
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex++, &index) != 0) {
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex++, &index, finalResult) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1943,7 +1950,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
|
if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
|
||||||
}
|
}
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex + i, &index) != 0) {
|
|
||||||
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex + i, &index, finalResult) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1980,7 +1988,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
|
|
||||||
for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
|
for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
|
||||||
SColumnIndex index = {.tableIndex = j, .columnIndex = i};
|
SColumnIndex index = {.tableIndex = j, .columnIndex = i};
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex, &index) != 0) {
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex, &index, finalResult) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "tschemautil.h"
|
#include "tschemautil.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
#include "ttimer.h"
|
#include "ttimer.h"
|
||||||
#include "tutil.h"
|
|
||||||
#include "tlockfree.h"
|
#include "tlockfree.h"
|
||||||
|
|
||||||
SRpcCorEpSet tscMgmtEpSet;
|
SRpcCorEpSet tscMgmtEpSet;
|
||||||
|
@ -198,15 +197,19 @@ void tscProcessActivityTimer(void *handle, void *tmrId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tscShouldFreeHeartBeat(pHB)) {
|
void** p = taosCacheAcquireByKey(tscObjCache, &pHB, sizeof(TSDB_CACHE_PTR_TYPE));
|
||||||
tscDebug("%p free HB object and release connection", pHB);
|
if (p == NULL) {
|
||||||
pObj->pHb = 0;
|
tscWarn("%p HB object has been released already", pHB);
|
||||||
taos_free_result(pHB);
|
return;
|
||||||
} else {
|
}
|
||||||
int32_t code = tscProcessSql(pHB);
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
assert(*pHB->self == pHB);
|
||||||
tscError("%p failed to sent HB to server, reason:%s", pHB, tstrerror(code));
|
|
||||||
}
|
int32_t code = tscProcessSql(pHB);
|
||||||
|
taosCacheRelease(tscObjCache, (void**) &p, false);
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tscError("%p failed to sent HB to server, reason:%s", pHB, tstrerror(code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,35 +467,6 @@ int tscProcessSql(SSqlObj *pSql) {
|
||||||
return doProcessSql(pSql);
|
return doProcessSql(pSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscKillSTableQuery(SSqlObj *pSql) {
|
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
|
||||||
if (!tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
|
||||||
|
|
||||||
for (int i = 0; i < pSql->numOfSubs; ++i) {
|
|
||||||
// NOTE: pSub may have been released already here
|
|
||||||
SSqlObj *pSub = pSql->pSubs[i];
|
|
||||||
if (pSub == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pSub->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
|
||||||
if (pSub->pRpcCtx != NULL) {
|
|
||||||
rpcCancelRequest(pSub->pRpcCtx);
|
|
||||||
pSub->pRpcCtx = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tscQueueAsyncRes(pSub); // async res? not other functions?
|
|
||||||
}
|
|
||||||
|
|
||||||
tscDebug("%p super table query cancelled", pSql);
|
|
||||||
}
|
|
||||||
|
|
||||||
int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg *) pSql->cmd.payload;
|
SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg *) pSql->cmd.payload;
|
||||||
pRetrieveMsg->qhandle = htobe64(pSql->res.qhandle);
|
pRetrieveMsg->qhandle = htobe64(pSql->res.qhandle);
|
||||||
|
@ -1451,7 +1425,7 @@ int tscProcessLocalRetrieveRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
int32_t code = pRes->code;
|
int32_t code = pRes->code;
|
||||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -1494,6 +1468,7 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
|
|
||||||
SCMConnectMsg *pConnect = (SCMConnectMsg*)pCmd->payload;
|
SCMConnectMsg *pConnect = (SCMConnectMsg*)pCmd->payload;
|
||||||
|
|
||||||
|
// TODO refactor full_name
|
||||||
char *db; // ugly code to move the space
|
char *db; // ugly code to move the space
|
||||||
db = strstr(pObj->db, TS_PATH_DELIMITER);
|
db = strstr(pObj->db, TS_PATH_DELIMITER);
|
||||||
db = (db == NULL) ? pObj->db : db + 1;
|
db = (db == NULL) ? pObj->db : db + 1;
|
||||||
|
@ -1501,6 +1476,9 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
tstrncpy(pConnect->clientVersion, version, sizeof(pConnect->clientVersion));
|
tstrncpy(pConnect->clientVersion, version, sizeof(pConnect->clientVersion));
|
||||||
tstrncpy(pConnect->msgVersion, "", sizeof(pConnect->msgVersion));
|
tstrncpy(pConnect->msgVersion, "", sizeof(pConnect->msgVersion));
|
||||||
|
|
||||||
|
pConnect->pid = htonl(taosGetPId());
|
||||||
|
taosGetCurrentAPPName(pConnect->appName, NULL);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1653,6 +1631,10 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SCMHeartBeatMsg *pHeartbeat = (SCMHeartBeatMsg *)pCmd->payload;
|
SCMHeartBeatMsg *pHeartbeat = (SCMHeartBeatMsg *)pCmd->payload;
|
||||||
pHeartbeat->numOfQueries = numOfQueries;
|
pHeartbeat->numOfQueries = numOfQueries;
|
||||||
pHeartbeat->numOfStreams = numOfStreams;
|
pHeartbeat->numOfStreams = numOfStreams;
|
||||||
|
|
||||||
|
pHeartbeat->pid = htonl(taosGetPId());
|
||||||
|
taosGetCurrentAPPName(pHeartbeat->appName, NULL);
|
||||||
|
|
||||||
int msgLen = tscBuildQueryStreamDesc(pHeartbeat, pObj);
|
int msgLen = tscBuildQueryStreamDesc(pHeartbeat, pObj);
|
||||||
|
|
||||||
pthread_mutex_unlock(&pObj->mutex);
|
pthread_mutex_unlock(&pObj->mutex);
|
||||||
|
|
|
@ -26,7 +26,9 @@
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
#include "ttimer.h"
|
||||||
#include "tscProfile.h"
|
#include "tscProfile.h"
|
||||||
|
#include "ttimer.h"
|
||||||
|
|
||||||
static bool validImpl(const char* str, size_t maxsize) {
|
static bool validImpl(const char* str, size_t maxsize) {
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
|
@ -256,10 +258,21 @@ TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port,
|
||||||
void taos_close(TAOS *taos) {
|
void taos_close(TAOS *taos) {
|
||||||
STscObj *pObj = (STscObj *)taos;
|
STscObj *pObj = (STscObj *)taos;
|
||||||
|
|
||||||
if (pObj == NULL || pObj->signature != pObj) {
|
if (pObj == NULL) {
|
||||||
|
tscDebug("(null) try to free tscObj and close dnodeConn");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tscDebug("%p try to free tscObj and close dnodeConn:%p", pObj, pObj->pDnodeConn);
|
||||||
|
if (pObj->signature != pObj) {
|
||||||
|
tscDebug("%p already closed or invalid tscObj", pObj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure that the close connection can only be executed once.
|
||||||
|
pObj->signature = NULL;
|
||||||
|
taosTmrStopA(&(pObj->pTimer));
|
||||||
|
|
||||||
SSqlObj* pHb = pObj->pHb;
|
SSqlObj* pHb = pObj->pHb;
|
||||||
if (pHb != NULL && atomic_val_compare_exchange_ptr(&pObj->pHb, pHb, 0) == pHb) {
|
if (pHb != NULL && atomic_val_compare_exchange_ptr(&pObj->pHb, pHb, 0) == pHb) {
|
||||||
if (pHb->pRpcCtx != NULL) { // wait for rsp from dnode
|
if (pHb->pRpcCtx != NULL) { // wait for rsp from dnode
|
||||||
|
@ -295,7 +308,7 @@ static void waitForRetrieveRsp(void *param, TAOS_RES *tres, int numOfRows) {
|
||||||
tsem_post(&pSql->rspSem);
|
tsem_post(&pSql->rspSem);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) {
|
TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, TAOS_RES** res) {
|
||||||
STscObj *pObj = (STscObj *)taos;
|
STscObj *pObj = (STscObj *)taos;
|
||||||
if (pObj == NULL || pObj->signature != pObj) {
|
if (pObj == NULL || pObj->signature != pObj) {
|
||||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
@ -320,12 +333,20 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) {
|
||||||
tsem_init(&pSql->rspSem, 0, 0);
|
tsem_init(&pSql->rspSem, 0, 0);
|
||||||
doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen);
|
doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen);
|
||||||
|
|
||||||
|
if (res != NULL) {
|
||||||
|
*res = pSql;
|
||||||
|
}
|
||||||
|
|
||||||
tsem_wait(&pSql->rspSem);
|
tsem_wait(&pSql->rspSem);
|
||||||
return pSql;
|
return pSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_RES* taos_query(TAOS *taos, const char *sqlstr) {
|
TAOS_RES* taos_query(TAOS *taos, const char *sqlstr) {
|
||||||
return taos_query_c(taos, sqlstr, (uint32_t)strlen(sqlstr));
|
return taos_query_c(taos, sqlstr, (uint32_t)strlen(sqlstr), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, TAOS_RES** res) {
|
||||||
|
return taos_query_c(taos, sqlstr, (uint32_t) strlen(sqlstr), res);
|
||||||
}
|
}
|
||||||
|
|
||||||
int taos_result_precision(TAOS_RES *res) {
|
int taos_result_precision(TAOS_RES *res) {
|
||||||
|
@ -459,6 +480,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
|
|
||||||
if (pRes->qhandle == 0 ||
|
if (pRes->qhandle == 0 ||
|
||||||
|
pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED ||
|
||||||
pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
|
pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
|
||||||
pCmd->command == TSDB_SQL_INSERT) {
|
pCmd->command == TSDB_SQL_INSERT) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -522,7 +544,7 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
||||||
pRes->numOfClauseTotal = 0;
|
pRes->numOfClauseTotal = 0;
|
||||||
pRes->rspType = 0;
|
pRes->rspType = 0;
|
||||||
|
|
||||||
pSql->numOfSubs = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
taosTFree(pSql->pSubs);
|
taosTFree(pSql->pSubs);
|
||||||
|
|
||||||
assert(pSql->fp == NULL);
|
assert(pSql->fp == NULL);
|
||||||
|
@ -676,6 +698,45 @@ int* taos_fetch_lengths(TAOS_RES *res) {
|
||||||
|
|
||||||
char *taos_get_client_info() { return version; }
|
char *taos_get_client_info() { return version; }
|
||||||
|
|
||||||
|
static void tscKillSTableQuery(SSqlObj *pSql) {
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
|
if (!tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the master sqlObj flag to cancel query
|
||||||
|
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
|
|
||||||
|
for (int i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
|
// NOTE: pSub may have been released already here
|
||||||
|
SSqlObj *pSub = pSql->pSubs[i];
|
||||||
|
if (pSub == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void** p = taosCacheAcquireByKey(tscObjCache, &pSub, sizeof(TSDB_CACHE_PTR_TYPE));
|
||||||
|
if (p == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSqlObj* pSubObj = (SSqlObj*) (*p);
|
||||||
|
assert(pSubObj->self == (SSqlObj**) p);
|
||||||
|
|
||||||
|
pSubObj->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
|
if (pSubObj->pRpcCtx != NULL) {
|
||||||
|
rpcCancelRequest(pSubObj->pRpcCtx);
|
||||||
|
pSubObj->pRpcCtx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tscQueueAsyncRes(pSubObj);
|
||||||
|
taosCacheRelease(tscObjCache, (void**) &p, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
tscDebug("%p super table query cancelled", pSql);
|
||||||
|
}
|
||||||
|
|
||||||
void taos_stop_query(TAOS_RES *res) {
|
void taos_stop_query(TAOS_RES *res) {
|
||||||
SSqlObj *pSql = (SSqlObj *)res;
|
SSqlObj *pSql = (SSqlObj *)res;
|
||||||
if (pSql == NULL || pSql->signature != pSql) {
|
if (pSql == NULL || pSql->signature != pSql) {
|
||||||
|
@ -685,21 +746,26 @@ void taos_stop_query(TAOS_RES *res) {
|
||||||
tscDebug("%p start to cancel query", res);
|
tscDebug("%p start to cancel query", res);
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
// TODO there are multi-thread problem.
|
|
||||||
// It may have been released by the other thread already.
|
|
||||||
// The ref count may fix this problem.
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
|
||||||
|
|
||||||
// set the error code for master pSqlObj firstly
|
// set the error code for master pSqlObj firstly
|
||||||
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
|
|
||||||
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
||||||
assert(pSql->pRpcCtx == NULL);
|
assert(pSql->pRpcCtx == NULL);
|
||||||
tscKillSTableQuery(pSql);
|
tscKillSTableQuery(pSql);
|
||||||
} else {
|
} else {
|
||||||
if (pSql->cmd.command < TSDB_SQL_LOCAL) {
|
if (pSql->cmd.command < TSDB_SQL_LOCAL) {
|
||||||
assert(pSql->pRpcCtx != NULL);
|
/*
|
||||||
rpcCancelRequest(pSql->pRpcCtx);
|
* There is multi-thread problem here, since pSql->pRpcCtx may have been
|
||||||
|
* reset and freed in the processMsgFromServer function, and causes the invalid
|
||||||
|
* write problem for rpcCancelRequest.
|
||||||
|
*/
|
||||||
|
if (pSql->pRpcCtx != NULL) {
|
||||||
|
rpcCancelRequest(pSql->pRpcCtx);
|
||||||
|
pSql->pRpcCtx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tscQueueAsyncRes(pSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,6 +894,8 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
pSql->fp = asyncCallback;
|
pSql->fp = asyncCallback;
|
||||||
pSql->fetchFp = asyncCallback;
|
pSql->fetchFp = asyncCallback;
|
||||||
pSql->param = pSql;
|
pSql->param = pSql;
|
||||||
|
|
||||||
|
registerSqlObj(pSql);
|
||||||
int code = tsParseSql(pSql, true);
|
int code = tsParseSql(pSql, true);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
tsem_wait(&pSql->rspSem);
|
tsem_wait(&pSql->rspSem);
|
||||||
|
|
|
@ -274,7 +274,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), false);
|
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), false);
|
||||||
tscFreeSqlResult(pSql);
|
tscFreeSqlResult(pSql);
|
||||||
taosTFree(pSql->pSubs);
|
taosTFree(pSql->pSubs);
|
||||||
pSql->numOfSubs = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
taosTFree(pTableMetaInfo->vgroupList);
|
taosTFree(pTableMetaInfo->vgroupList);
|
||||||
tscSetNextLaunchTimer(pStream, pSql);
|
tscSetNextLaunchTimer(pStream, pSql);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
|
|
||||||
typedef struct SInsertSupporter {
|
typedef struct SInsertSupporter {
|
||||||
SSubqueryState* pState;
|
|
||||||
SSqlObj* pSql;
|
SSqlObj* pSql;
|
||||||
int32_t index;
|
int32_t index;
|
||||||
} SInsertSupporter;
|
} SInsertSupporter;
|
||||||
|
@ -174,7 +173,6 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pState, in
|
||||||
}
|
}
|
||||||
|
|
||||||
pSupporter->pObj = pSql;
|
pSupporter->pObj = pSql;
|
||||||
pSupporter->pState = pState;
|
|
||||||
|
|
||||||
pSupporter->subqueryIndex = index;
|
pSupporter->subqueryIndex = index;
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||||
|
@ -250,7 +248,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
|
||||||
SJoinSupporter* pSupporter = NULL;
|
SJoinSupporter* pSupporter = NULL;
|
||||||
|
|
||||||
//If the columns are not involved in the final select clause, the corresponding query will not be issued.
|
//If the columns are not involved in the final select clause, the corresponding query will not be issued.
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
pSupporter = pSql->pSubs[i]->param;
|
pSupporter = pSql->pSubs[i]->param;
|
||||||
if (taosArrayGetSize(pSupporter->exprList) > 0) {
|
if (taosArrayGetSize(pSupporter->exprList) > 0) {
|
||||||
++numOfSub;
|
++numOfSub;
|
||||||
|
@ -260,16 +258,15 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
|
||||||
assert(numOfSub > 0);
|
assert(numOfSub > 0);
|
||||||
|
|
||||||
// scan all subquery, if one sub query has only ts, ignore it
|
// scan all subquery, if one sub query has only ts, ignore it
|
||||||
tscDebug("%p start to launch secondary subqueries, total:%d, only:%d needs to query", pSql, pSql->numOfSubs, numOfSub);
|
tscDebug("%p start to launch secondary subqueries, %d out of %d needs to query", pSql, numOfSub, pSql->subState.numOfSub);
|
||||||
|
|
||||||
//the subqueries that do not actually launch the secondary query to virtual node is set as completed.
|
//the subqueries that do not actually launch the secondary query to virtual node is set as completed.
|
||||||
SSubqueryState* pState = pSupporter->pState;
|
SSubqueryState* pState = &pSql->subState;
|
||||||
pState->numOfTotal = pSql->numOfSubs;
|
|
||||||
pState->numOfRemain = numOfSub;
|
pState->numOfRemain = numOfSub;
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
SSqlObj *pPrevSub = pSql->pSubs[i];
|
SSqlObj *pPrevSub = pSql->pSubs[i];
|
||||||
pSql->pSubs[i] = NULL;
|
pSql->pSubs[i] = NULL;
|
||||||
|
|
||||||
|
@ -322,7 +319,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
|
||||||
memset(&pSupporter->fieldsInfo, 0, sizeof(SFieldInfo));
|
memset(&pSupporter->fieldsInfo, 0, sizeof(SFieldInfo));
|
||||||
|
|
||||||
SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0);
|
SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0);
|
||||||
assert(pNew->numOfSubs == 0 && pNew->cmd.numOfClause == 1 && pNewQueryInfo->numOfTables == 1);
|
assert(pNew->subState.numOfSub == 0 && pNew->cmd.numOfClause == 1 && pNewQueryInfo->numOfTables == 1);
|
||||||
|
|
||||||
tscFieldInfoUpdateOffset(pNewQueryInfo);
|
tscFieldInfoUpdateOffset(pNewQueryInfo);
|
||||||
|
|
||||||
|
@ -373,13 +370,13 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
pSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscError("%p failed to prepare subqueries objs for secondary phase query, numOfSub:%d, code:%d", pSql,
|
tscError("%p failed to prepare subqueries objs for secondary phase query, numOfSub:%d, code:%d", pSql,
|
||||||
pSql->numOfSubs, pSql->res.code);
|
pSql->subState.numOfSub, pSql->res.code);
|
||||||
freeJoinSubqueryObj(pSql);
|
freeJoinSubqueryObj(pSql);
|
||||||
|
|
||||||
return pSql->res.code;
|
return pSql->res.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
if (pSql->pSubs[i] == NULL) {
|
if (pSql->pSubs[i] == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -391,17 +388,13 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeJoinSubqueryObj(SSqlObj* pSql) {
|
void freeJoinSubqueryObj(SSqlObj* pSql) {
|
||||||
SSubqueryState* pState = NULL;
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
|
||||||
SSqlObj* pSub = pSql->pSubs[i];
|
SSqlObj* pSub = pSql->pSubs[i];
|
||||||
if (pSub == NULL) {
|
if (pSub == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SJoinSupporter* p = pSub->param;
|
SJoinSupporter* p = pSub->param;
|
||||||
pState = p->pState;
|
|
||||||
|
|
||||||
tscDestroyJoinSupporter(p);
|
tscDestroyJoinSupporter(p);
|
||||||
|
|
||||||
if (pSub->res.code == TSDB_CODE_SUCCESS) {
|
if (pSub->res.code == TSDB_CODE_SUCCESS) {
|
||||||
|
@ -409,14 +402,13 @@ void freeJoinSubqueryObj(SSqlObj* pSql) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
taosTFree(pState);
|
pSql->subState.numOfSub = 0;
|
||||||
pSql->numOfSubs = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void quitAllSubquery(SSqlObj* pSqlObj, SJoinSupporter* pSupporter) {
|
static void quitAllSubquery(SSqlObj* pSqlObj, SJoinSupporter* pSupporter) {
|
||||||
assert(pSupporter->pState->numOfRemain > 0);
|
assert(pSqlObj->subState.numOfRemain > 0);
|
||||||
|
|
||||||
if (atomic_sub_fetch_32(&pSupporter->pState->numOfRemain, 1) <= 0) {
|
if (atomic_sub_fetch_32(&pSqlObj->subState.numOfRemain, 1) <= 0) {
|
||||||
tscError("%p all subquery return and query failed, global code:%d", pSqlObj, pSqlObj->res.code);
|
tscError("%p all subquery return and query failed, global code:%d", pSqlObj, pSqlObj->res.code);
|
||||||
freeJoinSubqueryObj(pSqlObj);
|
freeJoinSubqueryObj(pSqlObj);
|
||||||
}
|
}
|
||||||
|
@ -680,7 +672,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
|
|
||||||
// no data exists in next vnode, mark the <tid, tags> query completed
|
// no data exists in next vnode, mark the <tid, tags> query completed
|
||||||
// only when there is no subquery exits any more, proceeds to get the intersect of the <tid, tags> tuple sets.
|
// only when there is no subquery exits any more, proceeds to get the intersect of the <tid, tags> tuple sets.
|
||||||
if (atomic_sub_fetch_32(&pSupporter->pState->numOfRemain, 1) > 0) {
|
if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,10 +708,10 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
STableMetaInfo* pTableMetaInfo2 = tscGetMetaInfo(pQueryInfo2, 0);
|
STableMetaInfo* pTableMetaInfo2 = tscGetMetaInfo(pQueryInfo2, 0);
|
||||||
tscBuildVgroupTableInfo(pParentSql, pTableMetaInfo2, s2);
|
tscBuildVgroupTableInfo(pParentSql, pTableMetaInfo2, s2);
|
||||||
|
|
||||||
pSupporter->pState->numOfTotal = 2;
|
pParentSql->subState.numOfSub = 2;
|
||||||
pSupporter->pState->numOfRemain = pSupporter->pState->numOfTotal;
|
pParentSql->subState.numOfRemain = pParentSql->subState.numOfSub;
|
||||||
|
|
||||||
for (int32_t m = 0; m < pParentSql->numOfSubs; ++m) {
|
for (int32_t m = 0; m < pParentSql->subState.numOfSub; ++m) {
|
||||||
SSqlObj* sub = pParentSql->pSubs[m];
|
SSqlObj* sub = pParentSql->pSubs[m];
|
||||||
issueTSCompQuery(sub, sub->param, pParentSql);
|
issueTSCompQuery(sub, sub->param, pParentSql);
|
||||||
}
|
}
|
||||||
|
@ -818,7 +810,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomic_sub_fetch_32(&pSupporter->pState->numOfRemain, 1) > 0) {
|
if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +842,6 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
||||||
SJoinSupporter* pSupporter = (SJoinSupporter*)param;
|
SJoinSupporter* pSupporter = (SJoinSupporter*)param;
|
||||||
|
|
||||||
SSqlObj* pParentSql = pSupporter->pObj;
|
SSqlObj* pParentSql = pSupporter->pObj;
|
||||||
SSubqueryState* pState = pSupporter->pState;
|
|
||||||
|
|
||||||
SSqlObj* pSql = (SSqlObj*)tres;
|
SSqlObj* pSql = (SSqlObj*)tres;
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
@ -871,6 +862,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
||||||
pRes->numOfTotal += pRes->numOfRows;
|
pRes->numOfTotal += pRes->numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSubqueryState* pState = &pParentSql->subState;
|
||||||
if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && numOfRows == 0) {
|
if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && numOfRows == 0) {
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
assert(pQueryInfo->numOfTables == 1);
|
assert(pQueryInfo->numOfTables == 1);
|
||||||
|
@ -878,7 +870,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
||||||
// for projection query, need to try next vnode if current vnode is exhausted
|
// for projection query, need to try next vnode if current vnode is exhausted
|
||||||
if ((++pTableMetaInfo->vgroupIndex) < pTableMetaInfo->vgroupList->numOfVgroups) {
|
if ((++pTableMetaInfo->vgroupIndex) < pTableMetaInfo->vgroupList->numOfVgroups) {
|
||||||
pState->numOfRemain = 1;
|
pState->numOfRemain = 1;
|
||||||
pState->numOfTotal = 1;
|
pState->numOfSub = 1;
|
||||||
|
|
||||||
pSql->cmd.command = TSDB_SQL_SELECT;
|
pSql->cmd.command = TSDB_SQL_SELECT;
|
||||||
pSql->fp = tscJoinQueryCallback;
|
pSql->fp = tscJoinQueryCallback;
|
||||||
|
@ -888,12 +880,12 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomic_sub_fetch_32(&pState->numOfRemain, 1) > 0) {
|
if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) {
|
||||||
tscDebug("%p sub:%p completed, remain:%d, total:%d", pParentSql, tres, pState->numOfRemain, pState->numOfTotal);
|
tscDebug("%p sub:%p completed, remain:%d, total:%d", pParentSql, tres, pParentSql->subState.numOfRemain, pState->numOfSub);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("%p all %d secondary subqueries retrieval completed, code:%d", tres, pState->numOfTotal, pParentSql->res.code);
|
tscDebug("%p all %d secondary subqueries retrieval completed, code:%d", tres, pState->numOfSub, pParentSql->res.code);
|
||||||
|
|
||||||
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
||||||
freeJoinSubqueryObj(pParentSql);
|
freeJoinSubqueryObj(pParentSql);
|
||||||
|
@ -901,7 +893,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the records for each subquery in parent sql object.
|
// update the records for each subquery in parent sql object.
|
||||||
for (int32_t i = 0; i < pParentSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pState->numOfSub; ++i) {
|
||||||
if (pParentSql->pSubs[i] == NULL) {
|
if (pParentSql->pSubs[i] == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -917,32 +909,26 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
||||||
static SJoinSupporter* tscUpdateSubqueryStatus(SSqlObj* pSql, int32_t numOfFetch) {
|
static SJoinSupporter* tscUpdateSubqueryStatus(SSqlObj* pSql, int32_t numOfFetch) {
|
||||||
int32_t notInvolved = 0;
|
int32_t notInvolved = 0;
|
||||||
SJoinSupporter* pSupporter = NULL;
|
SJoinSupporter* pSupporter = NULL;
|
||||||
SSubqueryState* pState = NULL;
|
SSubqueryState* pState = &pSql->subState;
|
||||||
|
|
||||||
for(int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
if (pSql->pSubs[i] == NULL) {
|
if (pSql->pSubs[i] == NULL) {
|
||||||
notInvolved++;
|
notInvolved++;
|
||||||
} else {
|
} else {
|
||||||
pSupporter = (SJoinSupporter*)pSql->pSubs[i]->param;
|
pSupporter = (SJoinSupporter*)pSql->pSubs[i]->param;
|
||||||
pState = pSupporter->pState;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pState != NULL);
|
pState->numOfRemain = numOfFetch;
|
||||||
if (pState != NULL) {
|
|
||||||
pState->numOfTotal = pSql->numOfSubs;
|
|
||||||
pState->numOfRemain = numOfFetch;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pSupporter;
|
return pSupporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
||||||
assert(pSql->numOfSubs >= 1);
|
assert(pSql->subState.numOfSub >= 1);
|
||||||
|
|
||||||
int32_t numOfFetch = 0;
|
int32_t numOfFetch = 0;
|
||||||
bool hasData = true;
|
bool hasData = true;
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
// if the subquery is NULL, it does not involved in the final result generation
|
// if the subquery is NULL, it does not involved in the final result generation
|
||||||
SSqlObj* pSub = pSql->pSubs[i];
|
SSqlObj* pSub = pSql->pSubs[i];
|
||||||
if (pSub == NULL) {
|
if (pSub == NULL) {
|
||||||
|
@ -989,7 +975,7 @@ void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
||||||
tscDebug("%p retrieve data from %d subqueries", pSql, numOfFetch);
|
tscDebug("%p retrieve data from %d subqueries", pSql, numOfFetch);
|
||||||
SJoinSupporter* pSupporter = tscUpdateSubqueryStatus(pSql, numOfFetch);
|
SJoinSupporter* pSupporter = tscUpdateSubqueryStatus(pSql, numOfFetch);
|
||||||
|
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
SSqlObj* pSql1 = pSql->pSubs[i];
|
SSqlObj* pSql1 = pSql->pSubs[i];
|
||||||
if (pSql1 == NULL) {
|
if (pSql1 == NULL) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1124,7 +1110,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for the other subqueries response from vnode
|
// wait for the other subqueries response from vnode
|
||||||
if (atomic_sub_fetch_32(&pSupporter->pState->numOfRemain, 1) > 0) {
|
if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,7 +1122,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
||||||
* data instead of returning to its invoker
|
* data instead of returning to its invoker
|
||||||
*/
|
*/
|
||||||
if (pTableMetaInfo->vgroupIndex > 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
if (pTableMetaInfo->vgroupIndex > 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||||
pSupporter->pState->numOfRemain = pSupporter->pState->numOfTotal; // reset the record value
|
pParentSql->subState.numOfRemain = pParentSql->subState.numOfSub; // reset the record value
|
||||||
|
|
||||||
pSql->fp = joinRetrieveFinalResCallback; // continue retrieve data
|
pSql->fp = joinRetrieveFinalResCallback; // continue retrieve data
|
||||||
pSql->cmd.command = TSDB_SQL_FETCH;
|
pSql->cmd.command = TSDB_SQL_FETCH;
|
||||||
|
@ -1165,7 +1151,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
||||||
assert(pSql->res.numOfRows == 0);
|
assert(pSql->res.numOfRows == 0);
|
||||||
|
|
||||||
if (pSql->pSubs == NULL) {
|
if (pSql->pSubs == NULL) {
|
||||||
pSql->pSubs = calloc(pSupporter->pState->numOfTotal, POINTER_BYTES);
|
pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES);
|
||||||
if (pSql->pSubs == NULL) {
|
if (pSql->pSubs == NULL) {
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -1176,8 +1162,8 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSql->pSubs[pSql->numOfSubs++] = pNew;
|
pSql->pSubs[pSql->subState.numOfRemain++] = pNew;
|
||||||
assert(pSql->numOfSubs <= pSupporter->pState->numOfTotal);
|
assert(pSql->subState.numOfRemain <= pSql->subState.numOfSub);
|
||||||
|
|
||||||
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
|
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
|
||||||
addGroupInfoForSubquery(pSql, pNew, 0, tableIndex);
|
addGroupInfoForSubquery(pSql, pNew, 0, tableIndex);
|
||||||
|
@ -1221,7 +1207,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0);
|
||||||
|
|
||||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // return the tableId & tag
|
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // return the tableId & tag
|
||||||
SColumnIndex index = {0};
|
SColumnIndex colIndex = {0};
|
||||||
|
|
||||||
STagCond* pTagCond = &pSupporter->tagCond;
|
STagCond* pTagCond = &pSupporter->tagCond;
|
||||||
assert(pTagCond->joinInfo.hasJoin);
|
assert(pTagCond->joinInfo.hasJoin);
|
||||||
|
@ -1234,7 +1220,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
||||||
SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||||
for(int32_t i = 0; i < numOfTags; ++i) {
|
for(int32_t i = 0; i < numOfTags; ++i) {
|
||||||
if (pSchema[i].colId == tagColId) {
|
if (pSchema[i].colId == tagColId) {
|
||||||
index.columnIndex = i;
|
colIndex.columnIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1251,18 +1237,18 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
||||||
|
|
||||||
// set get tags query type
|
// set get tags query type
|
||||||
TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
|
TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
|
||||||
tscAddSpecialColumnForSelect(pNewQueryInfo, 0, TSDB_FUNC_TID_TAG, &index, &s1, TSDB_COL_TAG);
|
tscAddSpecialColumnForSelect(pNewQueryInfo, 0, TSDB_FUNC_TID_TAG, &colIndex, &s1, TSDB_COL_TAG);
|
||||||
size_t numOfCols = taosArrayGetSize(pNewQueryInfo->colList);
|
size_t numOfCols = taosArrayGetSize(pNewQueryInfo->colList);
|
||||||
|
|
||||||
tscDebug(
|
tscDebug(
|
||||||
"%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, transfer to tid_tag query to retrieve (tableId, tags), "
|
"%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, transfer to tid_tag query to retrieve (tableId, tags), "
|
||||||
"exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, tagIndex:%d, name:%s",
|
"exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, tagIndex:%d, name:%s",
|
||||||
pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo),
|
pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo),
|
||||||
numOfCols, pNewQueryInfo->fieldsInfo.numOfOutput, index.columnIndex, pNewQueryInfo->pTableMetaInfo[0]->name);
|
numOfCols, pNewQueryInfo->fieldsInfo.numOfOutput, colIndex.columnIndex, pNewQueryInfo->pTableMetaInfo[0]->name);
|
||||||
} else {
|
} else {
|
||||||
SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1};
|
SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1};
|
||||||
SColumnIndex index = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
SColumnIndex colIndex = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
tscAddSpecialColumnForSelect(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL);
|
tscAddSpecialColumnForSelect(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &colIndex, &colSchema, TSDB_COL_NORMAL);
|
||||||
|
|
||||||
// set the tags value for ts_comp function
|
// set the tags value for ts_comp function
|
||||||
SSqlExpr *pExpr = tscSqlExprGet(pNewQueryInfo, 0);
|
SSqlExpr *pExpr = tscSqlExprGet(pNewQueryInfo, 0);
|
||||||
|
@ -1320,8 +1306,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pState->numOfTotal = pQueryInfo->numOfTables;
|
pSql->subState.numOfSub = pQueryInfo->numOfTables;
|
||||||
pState->numOfRemain = pState->numOfTotal;
|
|
||||||
|
|
||||||
bool hasEmptySub = false;
|
bool hasEmptySub = false;
|
||||||
|
|
||||||
|
@ -1354,10 +1339,10 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
|
||||||
pSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
pSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
||||||
(*pSql->fp)(pSql->param, pSql, 0);
|
(*pSql->fp)(pSql->param, pSql, 0);
|
||||||
} else {
|
} else {
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
SSqlObj* pSub = pSql->pSubs[i];
|
SSqlObj* pSub = pSql->pSubs[i];
|
||||||
if ((code = tscProcessSql(pSub)) != TSDB_CODE_SUCCESS) {
|
if ((code = tscProcessSql(pSub)) != TSDB_CODE_SUCCESS) {
|
||||||
pState->numOfRemain = i - 1; // the already sent reques will continue and do not go to the error process routine
|
pSql->subState.numOfRemain = i - 1; // the already sent request will continue and do not go to the error process routine
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1373,7 +1358,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs, SSubqueryState* pState) {
|
static void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs, SSubqueryState* pState) {
|
||||||
assert(numOfSubs <= pSql->numOfSubs && numOfSubs >= 0 && pState != NULL);
|
assert(numOfSubs <= pSql->subState.numOfSub && numOfSubs >= 0 && pState != NULL);
|
||||||
|
|
||||||
for(int32_t i = 0; i < numOfSubs; ++i) {
|
for(int32_t i = 0; i < numOfSubs; ++i) {
|
||||||
SSqlObj* pSub = pSql->pSubs[i];
|
SSqlObj* pSub = pSql->pSubs[i];
|
||||||
|
@ -1411,8 +1396,8 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
pSql->numOfSubs = pTableMetaInfo->vgroupList->numOfVgroups;
|
pSql->subState.numOfSub = pTableMetaInfo->vgroupList->numOfVgroups;
|
||||||
assert(pSql->numOfSubs > 0);
|
assert(pSql->subState.numOfSub > 0);
|
||||||
|
|
||||||
int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, nBufferSize);
|
int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, nBufferSize);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
@ -1422,28 +1407,26 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSql->pSubs = calloc(pSql->numOfSubs, POINTER_BYTES);
|
pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES);
|
||||||
|
|
||||||
tscDebug("%p retrieved query data from %d vnode(s)", pSql, pSql->numOfSubs);
|
tscDebug("%p retrieved query data from %d vnode(s)", pSql, pSql->subState.numOfSub);
|
||||||
SSubqueryState *pState = calloc(1, sizeof(SSubqueryState));
|
SSubqueryState *pState = calloc(1, sizeof(SSubqueryState));
|
||||||
|
|
||||||
if (pSql->pSubs == NULL || pState == NULL) {
|
if (pSql->pSubs == NULL || pState == NULL) {
|
||||||
taosTFree(pState);
|
taosTFree(pState);
|
||||||
taosTFree(pSql->pSubs);
|
taosTFree(pSql->pSubs);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pSql->numOfSubs);
|
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pSql->subState.numOfSub);
|
||||||
|
|
||||||
tscQueueAsyncRes(pSql);
|
tscQueueAsyncRes(pSql);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pState->numOfTotal = pSql->numOfSubs;
|
pSql->subState.numOfRemain = pSql->subState.numOfSub;
|
||||||
pState->numOfRemain = pSql->numOfSubs;
|
|
||||||
|
|
||||||
pRes->code = TSDB_CODE_SUCCESS;
|
pRes->code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
for (; i < pSql->numOfSubs; ++i) {
|
for (; i < pSql->subState.numOfSub; ++i) {
|
||||||
SRetrieveSupport *trs = (SRetrieveSupport *)calloc(1, sizeof(SRetrieveSupport));
|
SRetrieveSupport *trs = (SRetrieveSupport *)calloc(1, sizeof(SRetrieveSupport));
|
||||||
if (trs == NULL) {
|
if (trs == NULL) {
|
||||||
tscError("%p failed to malloc buffer for SRetrieveSupport, orderOfSub:%d, reason:%s", pSql, i, strerror(errno));
|
tscError("%p failed to malloc buffer for SRetrieveSupport, orderOfSub:%d, reason:%s", pSql, i, strerror(errno));
|
||||||
|
@ -1452,8 +1435,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||||
|
|
||||||
trs->pExtMemBuffer = pMemoryBuf;
|
trs->pExtMemBuffer = pMemoryBuf;
|
||||||
trs->pOrderDescriptor = pDesc;
|
trs->pOrderDescriptor = pDesc;
|
||||||
trs->pState = pState;
|
|
||||||
|
|
||||||
trs->localBuffer = (tFilePage *)calloc(1, nBufferSize + sizeof(tFilePage));
|
trs->localBuffer = (tFilePage *)calloc(1, nBufferSize + sizeof(tFilePage));
|
||||||
if (trs->localBuffer == NULL) {
|
if (trs->localBuffer == NULL) {
|
||||||
tscError("%p failed to malloc buffer for local buffer, orderOfSub:%d, reason:%s", pSql, i, strerror(errno));
|
tscError("%p failed to malloc buffer for local buffer, orderOfSub:%d, reason:%s", pSql, i, strerror(errno));
|
||||||
|
@ -1461,8 +1443,8 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
trs->subqueryIndex = i;
|
trs->subqueryIndex = i;
|
||||||
trs->pParentSql = pSql;
|
trs->pParentSql = pSql;
|
||||||
trs->pFinalColModel = pModel;
|
trs->pFinalColModel = pModel;
|
||||||
|
|
||||||
SSqlObj *pNew = tscCreateSTableSubquery(pSql, trs, NULL);
|
SSqlObj *pNew = tscCreateSTableSubquery(pSql, trs, NULL);
|
||||||
|
@ -1483,42 +1465,46 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||||
tscDebug("%p sub:%p create subquery success. orderOfSub:%d", pSql, pNew, trs->subqueryIndex);
|
tscDebug("%p sub:%p create subquery success. orderOfSub:%d", pSql, pNew, trs->subqueryIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < pSql->numOfSubs) {
|
if (i < pSql->subState.numOfSub) {
|
||||||
tscError("%p failed to prepare subquery structure and launch subqueries", pSql);
|
tscError("%p failed to prepare subquery structure and launch subqueries", pSql);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
|
||||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pSql->numOfSubs);
|
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pSql->subState.numOfSub);
|
||||||
doCleanupSubqueries(pSql, i, pState);
|
doCleanupSubqueries(pSql, i, pState);
|
||||||
return pRes->code; // free all allocated resource
|
return pRes->code; // free all allocated resource
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED) {
|
if (pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED) {
|
||||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pSql->numOfSubs);
|
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pSql->subState.numOfSub);
|
||||||
doCleanupSubqueries(pSql, i, pState);
|
doCleanupSubqueries(pSql, i, pState);
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32_t j = 0; j < pSql->numOfSubs; ++j) {
|
for(int32_t j = 0; j < pSql->subState.numOfSub; ++j) {
|
||||||
SSqlObj* pSub = pSql->pSubs[j];
|
SSqlObj* pSub = pSql->pSubs[j];
|
||||||
SRetrieveSupport* pSupport = pSub->param;
|
SRetrieveSupport* pSupport = pSub->param;
|
||||||
|
|
||||||
tscDebug("%p sub:%p launch subquery, orderOfSub:%d.", pSql, pSub, pSupport->subqueryIndex);
|
tscDebug("%p sub:%p launch subquery, orderOfSub:%d.", pSql, pSub, pSupport->subqueryIndex);
|
||||||
tscProcessSql(pSub);
|
tscProcessSql(pSub);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscFreeSubSqlObj(SRetrieveSupport *trsupport, SSqlObj *pSql) {
|
static void tscFreeRetrieveSup(SSqlObj *pSql) {
|
||||||
tscDebug("%p start to free subquery obj", pSql);
|
SRetrieveSupport *trsupport = pSql->param;
|
||||||
|
|
||||||
int32_t index = trsupport->subqueryIndex;
|
void* p = atomic_val_compare_exchange_ptr(&pSql->param, trsupport, 0);
|
||||||
SSqlObj *pParentSql = trsupport->pParentSql;
|
if (p == NULL) {
|
||||||
|
tscDebug("%p retrieve supp already released", pSql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
assert(pSql == pParentSql->pSubs[index]);
|
tscDebug("%p start to free subquery supp obj:%p", pSql, trsupport);
|
||||||
// pParentSql->pSubs[index] = NULL;
|
// int32_t index = trsupport->subqueryIndex;
|
||||||
//
|
// SSqlObj *pParentSql = trsupport->pParentSql;
|
||||||
// taos_free_result(pSql);
|
|
||||||
|
// assert(pSql == pParentSql->pSubs[index]);
|
||||||
taosTFree(trsupport->localBuffer);
|
taosTFree(trsupport->localBuffer);
|
||||||
taosTFree(trsupport);
|
taosTFree(trsupport);
|
||||||
}
|
}
|
||||||
|
@ -1577,13 +1563,19 @@ static int32_t tscReissueSubquery(SRetrieveSupport *trsupport, SSqlObj *pSql, in
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numOfRows) {
|
void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numOfRows) {
|
||||||
|
// it has been freed already
|
||||||
|
if (pSql->param != trsupport || pSql->param == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SSqlObj *pParentSql = trsupport->pParentSql;
|
SSqlObj *pParentSql = trsupport->pParentSql;
|
||||||
int32_t subqueryIndex = trsupport->subqueryIndex;
|
int32_t subqueryIndex = trsupport->subqueryIndex;
|
||||||
|
|
||||||
assert(pSql != NULL);
|
assert(pSql != NULL);
|
||||||
SSubqueryState* pState = trsupport->pState;
|
|
||||||
assert(pState->numOfRemain <= pState->numOfTotal && pState->numOfRemain >= 0 && pParentSql->numOfSubs == pState->numOfTotal);
|
SSubqueryState* pState = &pParentSql->subState;
|
||||||
|
assert(pState->numOfRemain <= pState->numOfSub && pState->numOfRemain >= 0);
|
||||||
|
|
||||||
// retrieved in subquery failed. OR query cancelled in retrieve phase.
|
// retrieved in subquery failed. OR query cancelled in retrieve phase.
|
||||||
if (taos_errno(pSql) == TSDB_CODE_SUCCESS && pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
if (taos_errno(pSql) == TSDB_CODE_SUCCESS && pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
||||||
|
|
||||||
|
@ -1616,22 +1608,21 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
|
||||||
int32_t remain = -1;
|
int32_t remain = -1;
|
||||||
if ((remain = atomic_sub_fetch_32(&pState->numOfRemain, 1)) > 0) {
|
if ((remain = atomic_sub_fetch_32(&pState->numOfRemain, 1)) > 0) {
|
||||||
tscDebug("%p sub:%p orderOfSub:%d freed, finished subqueries:%d", pParentSql, pSql, trsupport->subqueryIndex,
|
tscDebug("%p sub:%p orderOfSub:%d freed, finished subqueries:%d", pParentSql, pSql, trsupport->subqueryIndex,
|
||||||
pState->numOfTotal - remain);
|
pState->numOfSub - remain);
|
||||||
|
|
||||||
tscFreeSubSqlObj(trsupport, pSql);
|
tscFreeRetrieveSup(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all subqueries are failed
|
// all subqueries are failed
|
||||||
tscError("%p retrieve from %d vnode(s) completed,code:%s.FAILED.", pParentSql, pState->numOfTotal,
|
tscError("%p retrieve from %d vnode(s) completed,code:%s.FAILED.", pParentSql, pState->numOfSub,
|
||||||
tstrerror(pParentSql->res.code));
|
tstrerror(pParentSql->res.code));
|
||||||
|
|
||||||
// release allocated resource
|
// release allocated resource
|
||||||
tscLocalReducerEnvDestroy(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, trsupport->pFinalColModel,
|
tscLocalReducerEnvDestroy(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, trsupport->pFinalColModel,
|
||||||
pState->numOfTotal);
|
pState->numOfSub);
|
||||||
|
|
||||||
taosTFree(trsupport->pState);
|
tscFreeRetrieveSup(pSql);
|
||||||
tscFreeSubSqlObj(trsupport, pSql);
|
|
||||||
|
|
||||||
// in case of second stage join subquery, invoke its callback function instead of regular QueueAsyncRes
|
// in case of second stage join subquery, invoke its callback function instead of regular QueueAsyncRes
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pParentSql->cmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pParentSql->cmd, 0);
|
||||||
|
@ -1650,7 +1641,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
|
||||||
SSqlObj * pParentSql = trsupport->pParentSql;
|
SSqlObj * pParentSql = trsupport->pParentSql;
|
||||||
tOrderDescriptor *pDesc = trsupport->pOrderDescriptor;
|
tOrderDescriptor *pDesc = trsupport->pOrderDescriptor;
|
||||||
|
|
||||||
SSubqueryState* pState = trsupport->pState;
|
SSubqueryState* pState = &pParentSql->subState;
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||||
|
@ -1687,11 +1678,11 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t remain = -1;
|
int32_t remain = -1;
|
||||||
if ((remain = atomic_sub_fetch_32(&pState->numOfRemain, 1)) > 0) {
|
if ((remain = atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1)) > 0) {
|
||||||
tscDebug("%p sub:%p orderOfSub:%d freed, finished subqueries:%d", pParentSql, pSql, trsupport->subqueryIndex,
|
tscDebug("%p sub:%p orderOfSub:%d freed, finished subqueries:%d", pParentSql, pSql, trsupport->subqueryIndex,
|
||||||
pState->numOfTotal - remain);
|
pState->numOfSub - remain);
|
||||||
|
|
||||||
tscFreeSubSqlObj(trsupport, pSql);
|
tscFreeRetrieveSup(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1699,21 +1690,19 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
|
||||||
pDesc->pColumnModel->capacity = trsupport->pExtMemBuffer[idx]->numOfElemsPerPage;
|
pDesc->pColumnModel->capacity = trsupport->pExtMemBuffer[idx]->numOfElemsPerPage;
|
||||||
|
|
||||||
tscDebug("%p retrieve from %d vnodes completed.final NumOfRows:%" PRId64 ",start to build loser tree", pParentSql,
|
tscDebug("%p retrieve from %d vnodes completed.final NumOfRows:%" PRId64 ",start to build loser tree", pParentSql,
|
||||||
pState->numOfTotal, pState->numOfRetrievedRows);
|
pState->numOfSub, pState->numOfRetrievedRows);
|
||||||
|
|
||||||
SQueryInfo *pPQueryInfo = tscGetQueryInfoDetail(&pParentSql->cmd, 0);
|
SQueryInfo *pPQueryInfo = tscGetQueryInfoDetail(&pParentSql->cmd, 0);
|
||||||
tscClearInterpInfo(pPQueryInfo);
|
tscClearInterpInfo(pPQueryInfo);
|
||||||
|
|
||||||
tscCreateLocalReducer(trsupport->pExtMemBuffer, pState->numOfTotal, pDesc, trsupport->pFinalColModel, pParentSql);
|
tscCreateLocalReducer(trsupport->pExtMemBuffer, pState->numOfSub, pDesc, trsupport->pFinalColModel, pParentSql);
|
||||||
tscDebug("%p build loser tree completed", pParentSql);
|
tscDebug("%p build loser tree completed", pParentSql);
|
||||||
|
|
||||||
pParentSql->res.precision = pSql->res.precision;
|
pParentSql->res.precision = pSql->res.precision;
|
||||||
pParentSql->res.numOfRows = 0;
|
pParentSql->res.numOfRows = 0;
|
||||||
pParentSql->res.row = 0;
|
pParentSql->res.row = 0;
|
||||||
|
|
||||||
// only free once
|
tscFreeRetrieveSup(pSql);
|
||||||
taosTFree(trsupport->pState);
|
|
||||||
tscFreeSubSqlObj(trsupport, pSql);
|
|
||||||
|
|
||||||
// set the command flag must be after the semaphore been correctly set.
|
// set the command flag must be after the semaphore been correctly set.
|
||||||
pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE;
|
pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE;
|
||||||
|
@ -1725,16 +1714,23 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
||||||
|
SSqlObj *pSql = (SSqlObj *)tres;
|
||||||
|
assert(pSql != NULL);
|
||||||
|
|
||||||
|
// this query has been freed already
|
||||||
SRetrieveSupport *trsupport = (SRetrieveSupport *)param;
|
SRetrieveSupport *trsupport = (SRetrieveSupport *)param;
|
||||||
|
if (pSql->param == NULL || param == NULL) {
|
||||||
|
tscDebug("%p already freed in dnodecallback", pSql);
|
||||||
|
assert(pSql->res.code == TSDB_CODE_TSC_QUERY_CANCELLED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tOrderDescriptor *pDesc = trsupport->pOrderDescriptor;
|
tOrderDescriptor *pDesc = trsupport->pOrderDescriptor;
|
||||||
int32_t idx = trsupport->subqueryIndex;
|
int32_t idx = trsupport->subqueryIndex;
|
||||||
SSqlObj * pParentSql = trsupport->pParentSql;
|
SSqlObj * pParentSql = trsupport->pParentSql;
|
||||||
|
|
||||||
assert(tres != NULL);
|
SSubqueryState* pState = &pParentSql->subState;
|
||||||
SSqlObj *pSql = (SSqlObj *)tres;
|
assert(pState->numOfRemain <= pState->numOfSub && pState->numOfRemain >= 0);
|
||||||
|
|
||||||
SSubqueryState* pState = trsupport->pState;
|
|
||||||
assert(pState->numOfRemain <= pState->numOfTotal && pState->numOfRemain >= 0 && pParentSql->numOfSubs == pState->numOfTotal);
|
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||||
SCMVgroupInfo *pVgroup = &pTableMetaInfo->vgroupList->vgroups[0];
|
SCMVgroupInfo *pVgroup = &pTableMetaInfo->vgroupList->vgroups[0];
|
||||||
|
@ -1751,6 +1747,10 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR
|
||||||
if (taos_errno(pSql) != TSDB_CODE_SUCCESS) {
|
if (taos_errno(pSql) != TSDB_CODE_SUCCESS) {
|
||||||
assert(numOfRows == taos_errno(pSql));
|
assert(numOfRows == taos_errno(pSql));
|
||||||
|
|
||||||
|
if (numOfRows == TSDB_CODE_TSC_QUERY_CANCELLED) {
|
||||||
|
trsupport->numOfRetry = MAX_NUM_OF_SUBQUERY_RETRY;
|
||||||
|
}
|
||||||
|
|
||||||
if (trsupport->numOfRetry++ < MAX_NUM_OF_SUBQUERY_RETRY) {
|
if (trsupport->numOfRetry++ < MAX_NUM_OF_SUBQUERY_RETRY) {
|
||||||
tscError("%p sub:%p failed code:%s, retry:%d", pParentSql, pSql, tstrerror(numOfRows), trsupport->numOfRetry);
|
tscError("%p sub:%p failed code:%s, retry:%d", pParentSql, pSql, tstrerror(numOfRows), trsupport->numOfRetry);
|
||||||
|
|
||||||
|
@ -1822,7 +1822,7 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0);
|
||||||
|
|
||||||
pQueryInfo->type |= TSDB_QUERY_TYPE_STABLE_SUBQUERY;
|
pQueryInfo->type |= TSDB_QUERY_TYPE_STABLE_SUBQUERY;
|
||||||
assert(pQueryInfo->numOfTables == 1 && pNew->cmd.numOfClause == 1 && trsupport->subqueryIndex < pSql->numOfSubs);
|
assert(pQueryInfo->numOfTables == 1 && pNew->cmd.numOfClause == 1 && trsupport->subqueryIndex < pSql->subState.numOfSub);
|
||||||
|
|
||||||
// launch subquery for each vnode, so the subquery index equals to the vgroupIndex.
|
// launch subquery for each vnode, so the subquery index equals to the vgroupIndex.
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, table_index);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, table_index);
|
||||||
|
@ -1893,7 +1893,6 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
||||||
static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) {
|
static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) {
|
||||||
SInsertSupporter *pSupporter = (SInsertSupporter *)param;
|
SInsertSupporter *pSupporter = (SInsertSupporter *)param;
|
||||||
SSqlObj* pParentObj = pSupporter->pSql;
|
SSqlObj* pParentObj = pSupporter->pSql;
|
||||||
SSubqueryState* pState = pSupporter->pState;
|
|
||||||
|
|
||||||
// record the total inserted rows
|
// record the total inserted rows
|
||||||
if (numOfRows > 0) {
|
if (numOfRows > 0) {
|
||||||
|
@ -1908,15 +1907,13 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
||||||
}
|
}
|
||||||
|
|
||||||
taosTFree(pSupporter);
|
taosTFree(pSupporter);
|
||||||
if (atomic_sub_fetch_32(&pState->numOfRemain, 1) > 0) {
|
|
||||||
|
if (atomic_sub_fetch_32(&pParentObj->subState.numOfRemain, 1) > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("%p Async insertion completed, total inserted:%" PRId64, pParentObj, pParentObj->res.numOfRows);
|
tscDebug("%p Async insertion completed, total inserted:%" PRId64, pParentObj, pParentObj->res.numOfRows);
|
||||||
|
|
||||||
// release data block data
|
|
||||||
taosTFree(pState);
|
|
||||||
|
|
||||||
// restore user defined fp
|
// restore user defined fp
|
||||||
pParentObj->fp = pParentObj->fetchFp;
|
pParentObj->fp = pParentObj->fetchFp;
|
||||||
|
|
||||||
|
@ -1937,7 +1934,7 @@ int32_t tscHandleInsertRetry(SSqlObj* pSql) {
|
||||||
SSqlRes* pRes = &pSql->res;
|
SSqlRes* pRes = &pSql->res;
|
||||||
|
|
||||||
SInsertSupporter* pSupporter = (SInsertSupporter*) pSql->param;
|
SInsertSupporter* pSupporter = (SInsertSupporter*) pSql->param;
|
||||||
assert(pSupporter->index < pSupporter->pState->numOfTotal);
|
assert(pSupporter->index < pSupporter->pSql->subState.numOfSub);
|
||||||
|
|
||||||
STableDataBlocks* pTableDataBlock = taosArrayGetP(pCmd->pDataBlocks, pSupporter->index);
|
STableDataBlocks* pTableDataBlock = taosArrayGetP(pCmd->pDataBlocks, pSupporter->index);
|
||||||
int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock);
|
int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock);
|
||||||
|
@ -1954,33 +1951,29 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
|
|
||||||
pSql->numOfSubs = (uint16_t)taosArrayGetSize(pCmd->pDataBlocks);
|
pSql->subState.numOfSub = (uint16_t)taosArrayGetSize(pCmd->pDataBlocks);
|
||||||
assert(pSql->numOfSubs > 0);
|
assert(pSql->subState.numOfSub > 0);
|
||||||
|
|
||||||
pRes->code = TSDB_CODE_SUCCESS;
|
pRes->code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
// the number of already initialized subqueries
|
// the number of already initialized subqueries
|
||||||
int32_t numOfSub = 0;
|
int32_t numOfSub = 0;
|
||||||
|
|
||||||
SSubqueryState *pState = calloc(1, sizeof(SSubqueryState));
|
pSql->subState.numOfRemain = pSql->subState.numOfSub;
|
||||||
pState->numOfTotal = pSql->numOfSubs;
|
pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES);
|
||||||
pState->numOfRemain = pSql->numOfSubs;
|
|
||||||
|
|
||||||
pSql->pSubs = calloc(pSql->numOfSubs, POINTER_BYTES);
|
|
||||||
if (pSql->pSubs == NULL) {
|
if (pSql->pSubs == NULL) {
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("%p submit data to %d vnode(s)", pSql, pSql->numOfSubs);
|
tscDebug("%p submit data to %d vnode(s)", pSql, pSql->subState.numOfSub);
|
||||||
|
|
||||||
while(numOfSub < pSql->numOfSubs) {
|
while(numOfSub < pSql->subState.numOfSub) {
|
||||||
SInsertSupporter* pSupporter = calloc(1, sizeof(SInsertSupporter));
|
SInsertSupporter* pSupporter = calloc(1, sizeof(SInsertSupporter));
|
||||||
if (pSupporter == NULL) {
|
if (pSupporter == NULL) {
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSupporter->pSql = pSql;
|
pSupporter->pSql = pSql;
|
||||||
pSupporter->pState = pState;
|
|
||||||
pSupporter->index = numOfSub;
|
pSupporter->index = numOfSub;
|
||||||
|
|
||||||
SSqlObj *pNew = createSimpleSubObj(pSql, multiVnodeInsertFinalize, pSupporter, TSDB_SQL_INSERT);
|
SSqlObj *pNew = createSimpleSubObj(pSql, multiVnodeInsertFinalize, pSupporter, TSDB_SQL_INSERT);
|
||||||
|
@ -2003,12 +1996,12 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) {
|
||||||
numOfSub++;
|
numOfSub++;
|
||||||
} else {
|
} else {
|
||||||
tscDebug("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%d, code:%s", pSql, numOfSub,
|
tscDebug("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%d, code:%s", pSql, numOfSub,
|
||||||
pSql->numOfSubs, tstrerror(pRes->code));
|
pSql->subState.numOfSub, tstrerror(pRes->code));
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOfSub < pSql->numOfSubs) {
|
if (numOfSub < pSql->subState.numOfSub) {
|
||||||
tscError("%p failed to prepare subObj structure and launch sub-insertion", pSql);
|
tscError("%p failed to prepare subObj structure and launch sub-insertion", pSql);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
goto _error;
|
goto _error;
|
||||||
|
@ -2026,7 +2019,6 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
_error:
|
_error:
|
||||||
taosTFree(pState);
|
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2048,7 +2040,7 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) {
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||||
|
|
||||||
int32_t numOfRes = INT32_MAX;
|
int32_t numOfRes = INT32_MAX;
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
if (pSql->pSubs[i] == NULL) {
|
if (pSql->pSubs[i] == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2238,7 +2230,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) {
|
||||||
if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||||
bool allSubqueryExhausted = true;
|
bool allSubqueryExhausted = true;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
if (pSql->pSubs[i] == NULL) {
|
if (pSql->pSubs[i] == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2264,7 +2256,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) {
|
||||||
|
|
||||||
hasData = !allSubqueryExhausted;
|
hasData = !allSubqueryExhausted;
|
||||||
} else { // otherwise, in case inner join, if any subquery exhausted, query completed.
|
} else { // otherwise, in case inner join, if any subquery exhausted, query completed.
|
||||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
if (pSql->pSubs[i] == 0) {
|
if (pSql->pSubs[i] == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ void taos_init_imp(void) {
|
||||||
int64_t refreshTime = 10; // 10 seconds by default
|
int64_t refreshTime = 10; // 10 seconds by default
|
||||||
if (tscMetaCache == NULL) {
|
if (tscMetaCache == NULL) {
|
||||||
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, NULL, "tableMeta");
|
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, NULL, "tableMeta");
|
||||||
tscObjCache = taosCacheInit(TSDB_CACHE_PTR_KEY, refreshTime / 2, false, tscFreeSqlObjInCache, "sqlObj");
|
tscObjCache = taosCacheInit(TSDB_CACHE_PTR_KEY, refreshTime / 2, false, tscFreeRegisteredSqlObj, "sqlObj");
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("client is initialized successfully");
|
tscDebug("client is initialized successfully");
|
||||||
|
|
|
@ -360,26 +360,26 @@ void tscPartiallyFreeSqlObj(SSqlObj* pSql) {
|
||||||
tscFreeSqlResult(pSql);
|
tscFreeSqlResult(pSql);
|
||||||
|
|
||||||
taosTFree(pSql->pSubs);
|
taosTFree(pSql->pSubs);
|
||||||
pSql->numOfSubs = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
pSql->self = 0;
|
pSql->self = 0;
|
||||||
|
|
||||||
tscResetSqlCmdObj(pCmd, false);
|
tscResetSqlCmdObj(pCmd, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UNUSED_FUNC void tscFreeSubobj(SSqlObj* pSql) {
|
static void tscFreeSubobj(SSqlObj* pSql) {
|
||||||
if (pSql->numOfSubs == 0) {
|
if (pSql->subState.numOfSub == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("%p start to free sub SqlObj, numOfSub:%d", pSql, pSql->numOfSubs);
|
tscDebug("%p start to free sub SqlObj, numOfSub:%d", pSql, pSql->subState.numOfSub);
|
||||||
|
|
||||||
for(int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||||
tscDebug("%p free sub SqlObj:%p, index:%d", pSql, pSql->pSubs[i], i);
|
tscDebug("%p free sub SqlObj:%p, index:%d", pSql, pSql->pSubs[i], i);
|
||||||
taos_free_result(pSql->pSubs[i]);
|
taos_free_result(pSql->pSubs[i]);
|
||||||
pSql->pSubs[i] = NULL;
|
pSql->pSubs[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSql->numOfSubs = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -389,7 +389,7 @@ static UNUSED_FUNC void tscFreeSubobj(SSqlObj* pSql) {
|
||||||
*
|
*
|
||||||
* @param pSql
|
* @param pSql
|
||||||
*/
|
*/
|
||||||
void tscFreeSqlObjInCache(void *pSql) {
|
void tscFreeRegisteredSqlObj(void *pSql) {
|
||||||
assert(pSql != NULL);
|
assert(pSql != NULL);
|
||||||
|
|
||||||
SSqlObj** p = (SSqlObj**)pSql;
|
SSqlObj** p = (SSqlObj**)pSql;
|
||||||
|
@ -415,7 +415,9 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
||||||
|
|
||||||
tscDebug("%p start to free sqlObj", pSql);
|
tscDebug("%p start to free sqlObj", pSql);
|
||||||
|
|
||||||
|
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
tscFreeSubobj(pSql);
|
tscFreeSubobj(pSql);
|
||||||
|
|
||||||
tscPartiallyFreeSqlObj(pSql);
|
tscPartiallyFreeSqlObj(pSql);
|
||||||
|
|
||||||
pSql->signature = NULL;
|
pSql->signature = NULL;
|
||||||
|
@ -1516,13 +1518,6 @@ void tscSetFreeHeatBeat(STscObj* pObj) {
|
||||||
pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE;
|
pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tscShouldFreeHeartBeat(SSqlObj* pHb) {
|
|
||||||
assert(pHb == pHb->signature);
|
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pHb->cmd, 0);
|
|
||||||
return pQueryInfo->type == TSDB_QUERY_TYPE_FREE_RESOURCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the following four kinds of SqlObj should not be freed
|
* the following four kinds of SqlObj should not be freed
|
||||||
* 1. SqlObj for stream computing
|
* 1. SqlObj for stream computing
|
||||||
|
@ -2291,7 +2286,7 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) {
|
||||||
*
|
*
|
||||||
* For super table join with projection query, if anyone of the subquery is exhausted, the query completed.
|
* For super table join with projection query, if anyone of the subquery is exhausted, the query completed.
|
||||||
*/
|
*/
|
||||||
pSql->numOfSubs = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
pCmd->command = TSDB_SQL_SELECT;
|
pCmd->command = TSDB_SQL_SELECT;
|
||||||
|
|
||||||
tscResetForNextRetrieve(pRes);
|
tscResetForNextRetrieve(pRes);
|
||||||
|
@ -2323,7 +2318,7 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) {
|
||||||
pRes->numOfTotal = num;
|
pRes->numOfTotal = num;
|
||||||
|
|
||||||
taosTFree(pSql->pSubs);
|
taosTFree(pSql->pSubs);
|
||||||
pSql->numOfSubs = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
pSql->fp = fp;
|
pSql->fp = fp;
|
||||||
|
|
||||||
tscDebug("%p try data in the next subclause:%d, total subclause:%d", pSql, pCmd->clauseIndex, pCmd->numOfClause);
|
tscDebug("%p try data in the next subclause:%d, total subclause:%d", pSql, pCmd->clauseIndex, pCmd->numOfClause);
|
||||||
|
|
|
@ -34,6 +34,7 @@ extern int32_t tsStatusInterval;
|
||||||
extern int32_t tsNumOfMnodes;
|
extern int32_t tsNumOfMnodes;
|
||||||
extern int32_t tsEnableVnodeBak;
|
extern int32_t tsEnableVnodeBak;
|
||||||
extern int32_t tsEnableTelemetryReporting;
|
extern int32_t tsEnableTelemetryReporting;
|
||||||
|
extern char tsEmail[];
|
||||||
|
|
||||||
// common
|
// common
|
||||||
extern int tsRpcTimer;
|
extern int tsRpcTimer;
|
||||||
|
|
|
@ -42,6 +42,7 @@ int32_t tsStatusInterval = 1; // second
|
||||||
int32_t tsNumOfMnodes = 3;
|
int32_t tsNumOfMnodes = 3;
|
||||||
int32_t tsEnableVnodeBak = 1;
|
int32_t tsEnableVnodeBak = 1;
|
||||||
int32_t tsEnableTelemetryReporting = 1;
|
int32_t tsEnableTelemetryReporting = 1;
|
||||||
|
char tsEmail[TSDB_FQDN_LEN] = {0};
|
||||||
|
|
||||||
// common
|
// common
|
||||||
int32_t tsRpcTimer = 1000;
|
int32_t tsRpcTimer = 1000;
|
||||||
|
@ -307,6 +308,8 @@ bool taosCfgDynamicOptions(char *msg) {
|
||||||
|
|
||||||
static void doInitGlobalConfig(void) {
|
static void doInitGlobalConfig(void) {
|
||||||
osInit();
|
osInit();
|
||||||
|
srand(taosSafeRand());
|
||||||
|
|
||||||
SGlobalCfg cfg = {0};
|
SGlobalCfg cfg = {0};
|
||||||
|
|
||||||
// ip address
|
// ip address
|
||||||
|
|
|
@ -33,7 +33,8 @@ typedef struct {
|
||||||
} SMPeerWorker;
|
} SMPeerWorker;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t num;
|
int32_t curNum;
|
||||||
|
int32_t maxNum;
|
||||||
SMPeerWorker *peerWorker;
|
SMPeerWorker *peerWorker;
|
||||||
} SMPeerWorkerPool;
|
} SMPeerWorkerPool;
|
||||||
|
|
||||||
|
@ -46,37 +47,44 @@ static void *dnodeProcessMnodePeerQueue(void *param);
|
||||||
int32_t dnodeInitMnodePeer() {
|
int32_t dnodeInitMnodePeer() {
|
||||||
tsMPeerQset = taosOpenQset();
|
tsMPeerQset = taosOpenQset();
|
||||||
|
|
||||||
tsMPeerPool.num = 1;
|
tsMPeerPool.maxNum = 1;
|
||||||
tsMPeerPool.peerWorker = (SMPeerWorker *)calloc(sizeof(SMPeerWorker), tsMPeerPool.num);
|
tsMPeerPool.curNum = 0;
|
||||||
|
tsMPeerPool.peerWorker = (SMPeerWorker *)calloc(sizeof(SMPeerWorker), tsMPeerPool.maxNum);
|
||||||
|
|
||||||
if (tsMPeerPool.peerWorker == NULL) return -1;
|
if (tsMPeerPool.peerWorker == NULL) return -1;
|
||||||
for (int32_t i = 0; i < tsMPeerPool.num; ++i) {
|
for (int32_t i = 0; i < tsMPeerPool.maxNum; ++i) {
|
||||||
SMPeerWorker *pWorker = tsMPeerPool.peerWorker + i;
|
SMPeerWorker *pWorker = tsMPeerPool.peerWorker + i;
|
||||||
pWorker->workerId = i;
|
pWorker->workerId = i;
|
||||||
|
dDebug("dnode mpeer worker:%d is created", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
dInfo("dnode mpeer is opened");
|
dDebug("dnode mpeer is opened, workers:%d qset:%p", tsMPeerPool.maxNum, tsMPeerQset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeCleanupMnodePeer() {
|
void dnodeCleanupMnodePeer() {
|
||||||
for (int32_t i = 0; i < tsMPeerPool.num; ++i) {
|
for (int32_t i = 0; i < tsMPeerPool.maxNum; ++i) {
|
||||||
SMPeerWorker *pWorker = tsMPeerPool.peerWorker + i;
|
SMPeerWorker *pWorker = tsMPeerPool.peerWorker + i;
|
||||||
if (pWorker->thread) {
|
if (pWorker->thread) {
|
||||||
taosQsetThreadResume(tsMPeerQset);
|
taosQsetThreadResume(tsMPeerQset);
|
||||||
}
|
}
|
||||||
|
dDebug("dnode mpeer worker:%d is closed", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < tsMPeerPool.num; ++i) {
|
for (int32_t i = 0; i < tsMPeerPool.maxNum; ++i) {
|
||||||
SMPeerWorker *pWorker = tsMPeerPool.peerWorker + i;
|
SMPeerWorker *pWorker = tsMPeerPool.peerWorker + i;
|
||||||
|
dDebug("dnode mpeer worker:%d start to join", i);
|
||||||
if (pWorker->thread) {
|
if (pWorker->thread) {
|
||||||
pthread_join(pWorker->thread, NULL);
|
pthread_join(pWorker->thread, NULL);
|
||||||
}
|
}
|
||||||
|
dDebug("dnode mpeer worker:%d join success", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dDebug("dnode mpeer is closed, qset:%p", tsMPeerQset);
|
||||||
|
|
||||||
taosCloseQset(tsMPeerQset);
|
taosCloseQset(tsMPeerQset);
|
||||||
|
tsMPeerQset = NULL;
|
||||||
taosTFree(tsMPeerPool.peerWorker);
|
taosTFree(tsMPeerPool.peerWorker);
|
||||||
dInfo("dnode mpeer is closed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t dnodeAllocateMnodePqueue() {
|
int32_t dnodeAllocateMnodePqueue() {
|
||||||
|
@ -85,7 +93,7 @@ int32_t dnodeAllocateMnodePqueue() {
|
||||||
|
|
||||||
taosAddIntoQset(tsMPeerQset, tsMPeerQueue, NULL);
|
taosAddIntoQset(tsMPeerQset, tsMPeerQueue, NULL);
|
||||||
|
|
||||||
for (int32_t i = 0; i < tsMPeerPool.num; ++i) {
|
for (int32_t i = tsMPeerPool.curNum; i < tsMPeerPool.maxNum; ++i) {
|
||||||
SMPeerWorker *pWorker = tsMPeerPool.peerWorker + i;
|
SMPeerWorker *pWorker = tsMPeerPool.peerWorker + i;
|
||||||
pWorker->workerId = i;
|
pWorker->workerId = i;
|
||||||
|
|
||||||
|
@ -98,7 +106,9 @@ int32_t dnodeAllocateMnodePqueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_attr_destroy(&thAttr);
|
pthread_attr_destroy(&thAttr);
|
||||||
dDebug("dnode mpeer worker:%d is launched, total:%d", pWorker->workerId, tsMPeerPool.num);
|
|
||||||
|
tsMPeerPool.curNum = i + 1;
|
||||||
|
dDebug("dnode mpeer worker:%d is launched, total:%d", pWorker->workerId, tsMPeerPool.maxNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
dDebug("dnode mpeer queue:%p is allocated", tsMPeerQueue);
|
dDebug("dnode mpeer queue:%p is allocated", tsMPeerQueue);
|
||||||
|
@ -106,6 +116,7 @@ int32_t dnodeAllocateMnodePqueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeFreeMnodePqueue() {
|
void dnodeFreeMnodePqueue() {
|
||||||
|
dDebug("dnode mpeer queue:%p is freed", tsMPeerQueue);
|
||||||
taosCloseQueue(tsMPeerQueue);
|
taosCloseQueue(tsMPeerQueue);
|
||||||
tsMPeerQueue = NULL;
|
tsMPeerQueue = NULL;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +159,7 @@ static void *dnodeProcessMnodePeerQueue(void *param) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (taosReadQitemFromQset(tsMPeerQset, &type, (void **)&pPeerMsg, &unUsed) == 0) {
|
if (taosReadQitemFromQset(tsMPeerQset, &type, (void **)&pPeerMsg, &unUsed) == 0) {
|
||||||
dDebug("dnodeProcessMnodePeerQueue: got no message from qset, exiting...");
|
dDebug("qset:%p, mnode peer got no message from qset, exiting", tsMPeerQset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ typedef struct {
|
||||||
} SMReadWorker;
|
} SMReadWorker;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t num;
|
int32_t curNum;
|
||||||
|
int32_t maxNum;
|
||||||
SMReadWorker *readWorker;
|
SMReadWorker *readWorker;
|
||||||
} SMReadWorkerPool;
|
} SMReadWorkerPool;
|
||||||
|
|
||||||
|
@ -46,40 +47,46 @@ static void *dnodeProcessMnodeReadQueue(void *param);
|
||||||
int32_t dnodeInitMnodeRead() {
|
int32_t dnodeInitMnodeRead() {
|
||||||
tsMReadQset = taosOpenQset();
|
tsMReadQset = taosOpenQset();
|
||||||
|
|
||||||
tsMReadPool.num = tsNumOfCores * tsNumOfThreadsPerCore / 2;
|
tsMReadPool.maxNum = tsNumOfCores * tsNumOfThreadsPerCore / 2;
|
||||||
tsMReadPool.num = MAX(2, tsMReadPool.num);
|
tsMReadPool.maxNum = MAX(2, tsMReadPool.maxNum);
|
||||||
tsMReadPool.num = MIN(4, tsMReadPool.num);
|
tsMReadPool.maxNum = MIN(4, tsMReadPool.maxNum);
|
||||||
tsMReadPool.readWorker = (SMReadWorker *)calloc(sizeof(SMReadWorker), tsMReadPool.num);
|
tsMReadPool.curNum = 0;
|
||||||
|
tsMReadPool.readWorker = (SMReadWorker *)calloc(sizeof(SMReadWorker), tsMReadPool.maxNum);
|
||||||
|
|
||||||
if (tsMReadPool.readWorker == NULL) return -1;
|
if (tsMReadPool.readWorker == NULL) return -1;
|
||||||
for (int32_t i = 0; i < tsMReadPool.num; ++i) {
|
for (int32_t i = 0; i < tsMReadPool.maxNum; ++i) {
|
||||||
SMReadWorker *pWorker = tsMReadPool.readWorker + i;
|
SMReadWorker *pWorker = tsMReadPool.readWorker + i;
|
||||||
pWorker->workerId = i;
|
pWorker->workerId = i;
|
||||||
|
dDebug("dnode mread worker:%d is created", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
dInfo("dnode mread is opened");
|
dDebug("dnode mread is opened, workers:%d qset:%p", tsMReadPool.maxNum, tsMReadQset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeCleanupMnodeRead() {
|
void dnodeCleanupMnodeRead() {
|
||||||
for (int32_t i = 0; i < tsMReadPool.num; ++i) {
|
for (int32_t i = 0; i < tsMReadPool.maxNum; ++i) {
|
||||||
SMReadWorker *pWorker = tsMReadPool.readWorker + i;
|
SMReadWorker *pWorker = tsMReadPool.readWorker + i;
|
||||||
if (pWorker->thread) {
|
if (pWorker->thread) {
|
||||||
taosQsetThreadResume(tsMReadQset);
|
taosQsetThreadResume(tsMReadQset);
|
||||||
}
|
}
|
||||||
|
dDebug("dnode mread worker:%d is closed", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < tsMReadPool.num; ++i) {
|
for (int32_t i = 0; i < tsMReadPool.maxNum; ++i) {
|
||||||
SMReadWorker *pWorker = tsMReadPool.readWorker + i;
|
SMReadWorker *pWorker = tsMReadPool.readWorker + i;
|
||||||
|
dDebug("dnode mread worker:%d start to join", i);
|
||||||
if (pWorker->thread) {
|
if (pWorker->thread) {
|
||||||
pthread_join(pWorker->thread, NULL);
|
pthread_join(pWorker->thread, NULL);
|
||||||
}
|
}
|
||||||
|
dDebug("dnode mread worker:%d start to join", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosCloseQset(tsMReadQset);
|
dDebug("dnode mread is closed, qset:%p", tsMReadQset);
|
||||||
free(tsMReadPool.readWorker);
|
|
||||||
|
|
||||||
dInfo("dnode mread is closed");
|
taosCloseQset(tsMReadQset);
|
||||||
|
tsMReadQset = NULL;
|
||||||
|
free(tsMReadPool.readWorker);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t dnodeAllocateMnodeRqueue() {
|
int32_t dnodeAllocateMnodeRqueue() {
|
||||||
|
@ -88,7 +95,7 @@ int32_t dnodeAllocateMnodeRqueue() {
|
||||||
|
|
||||||
taosAddIntoQset(tsMReadQset, tsMReadQueue, NULL);
|
taosAddIntoQset(tsMReadQset, tsMReadQueue, NULL);
|
||||||
|
|
||||||
for (int32_t i = 0; i < tsMReadPool.num; ++i) {
|
for (int32_t i = tsMReadPool.curNum; i < tsMReadPool.maxNum; ++i) {
|
||||||
SMReadWorker *pWorker = tsMReadPool.readWorker + i;
|
SMReadWorker *pWorker = tsMReadPool.readWorker + i;
|
||||||
pWorker->workerId = i;
|
pWorker->workerId = i;
|
||||||
|
|
||||||
|
@ -101,7 +108,8 @@ int32_t dnodeAllocateMnodeRqueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_attr_destroy(&thAttr);
|
pthread_attr_destroy(&thAttr);
|
||||||
dDebug("dnode mread worker:%d is launched, total:%d", pWorker->workerId, tsMReadPool.num);
|
tsMReadPool.curNum = i + 1;
|
||||||
|
dDebug("dnode mread worker:%d is launched, total:%d", pWorker->workerId, tsMReadPool.maxNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
dDebug("dnode mread queue:%p is allocated", tsMReadQueue);
|
dDebug("dnode mread queue:%p is allocated", tsMReadQueue);
|
||||||
|
@ -109,6 +117,7 @@ int32_t dnodeAllocateMnodeRqueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeFreeMnodeRqueue() {
|
void dnodeFreeMnodeRqueue() {
|
||||||
|
dDebug("dnode mread queue:%p is freed", tsMReadQueue);
|
||||||
taosCloseQueue(tsMReadQueue);
|
taosCloseQueue(tsMReadQueue);
|
||||||
tsMReadQueue = NULL;
|
tsMReadQueue = NULL;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +165,7 @@ static void *dnodeProcessMnodeReadQueue(void *param) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (taosReadQitemFromQset(tsMReadQset, &type, (void **)&pReadMsg, &unUsed) == 0) {
|
if (taosReadQitemFromQset(tsMReadQset, &type, (void **)&pReadMsg, &unUsed) == 0) {
|
||||||
dDebug("dnodeProcessMnodeReadQueue: got no message from qset, exiting...");
|
dDebug("qset:%p, mnode read got no message from qset, exiting", tsMReadQset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ typedef struct {
|
||||||
} SMWriteWorker;
|
} SMWriteWorker;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t num;
|
int32_t curNum;
|
||||||
|
int32_t maxNum;
|
||||||
SMWriteWorker *writeWorker;
|
SMWriteWorker *writeWorker;
|
||||||
} SMWriteWorkerPool;
|
} SMWriteWorkerPool;
|
||||||
|
|
||||||
|
@ -47,38 +48,45 @@ static void *dnodeProcessMnodeWriteQueue(void *param);
|
||||||
|
|
||||||
int32_t dnodeInitMnodeWrite() {
|
int32_t dnodeInitMnodeWrite() {
|
||||||
tsMWriteQset = taosOpenQset();
|
tsMWriteQset = taosOpenQset();
|
||||||
|
|
||||||
tsMWritePool.num = 1;
|
tsMWritePool.maxNum = 1;
|
||||||
tsMWritePool.writeWorker = (SMWriteWorker *)calloc(sizeof(SMWriteWorker), tsMWritePool.num);
|
tsMWritePool.curNum = 0;
|
||||||
|
tsMWritePool.writeWorker = (SMWriteWorker *)calloc(sizeof(SMWriteWorker), tsMWritePool.maxNum);
|
||||||
|
|
||||||
if (tsMWritePool.writeWorker == NULL) return -1;
|
if (tsMWritePool.writeWorker == NULL) return -1;
|
||||||
for (int32_t i = 0; i < tsMWritePool.num; ++i) {
|
for (int32_t i = 0; i < tsMWritePool.maxNum; ++i) {
|
||||||
SMWriteWorker *pWorker = tsMWritePool.writeWorker + i;
|
SMWriteWorker *pWorker = tsMWritePool.writeWorker + i;
|
||||||
pWorker->workerId = i;
|
pWorker->workerId = i;
|
||||||
|
dDebug("dnode mwrite worker:%d is created", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
dInfo("dnode mwrite is opened");
|
dDebug("dnode mwrite is opened, workers:%d qset:%p", tsMWritePool.maxNum, tsMWriteQset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeCleanupMnodeWrite() {
|
void dnodeCleanupMnodeWrite() {
|
||||||
for (int32_t i = 0; i < tsMWritePool.num; ++i) {
|
for (int32_t i = 0; i < tsMWritePool.maxNum; ++i) {
|
||||||
SMWriteWorker *pWorker = tsMWritePool.writeWorker + i;
|
SMWriteWorker *pWorker = tsMWritePool.writeWorker + i;
|
||||||
if (pWorker->thread) {
|
if (pWorker->thread) {
|
||||||
taosQsetThreadResume(tsMWriteQset);
|
taosQsetThreadResume(tsMWriteQset);
|
||||||
}
|
}
|
||||||
|
dDebug("dnode mwrite worker:%d is closed", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < tsMWritePool.num; ++i) {
|
for (int32_t i = 0; i < tsMWritePool.maxNum; ++i) {
|
||||||
SMWriteWorker *pWorker = tsMWritePool.writeWorker + i;
|
SMWriteWorker *pWorker = tsMWritePool.writeWorker + i;
|
||||||
|
dDebug("dnode mwrite worker:%d start to join", i);
|
||||||
if (pWorker->thread) {
|
if (pWorker->thread) {
|
||||||
pthread_join(pWorker->thread, NULL);
|
pthread_join(pWorker->thread, NULL);
|
||||||
}
|
}
|
||||||
|
dDebug("dnode mwrite worker:%d join success", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dDebug("dnode mwrite is closed, qset:%p", tsMWriteQset);
|
||||||
|
|
||||||
taosCloseQset(tsMWriteQset);
|
taosCloseQset(tsMWriteQset);
|
||||||
|
tsMWriteQset = NULL;
|
||||||
taosTFree(tsMWritePool.writeWorker);
|
taosTFree(tsMWritePool.writeWorker);
|
||||||
dInfo("dnode mwrite is closed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t dnodeAllocateMnodeWqueue() {
|
int32_t dnodeAllocateMnodeWqueue() {
|
||||||
|
@ -87,7 +95,7 @@ int32_t dnodeAllocateMnodeWqueue() {
|
||||||
|
|
||||||
taosAddIntoQset(tsMWriteQset, tsMWriteQueue, NULL);
|
taosAddIntoQset(tsMWriteQset, tsMWriteQueue, NULL);
|
||||||
|
|
||||||
for (int32_t i = 0; i < tsMWritePool.num; ++i) {
|
for (int32_t i = tsMWritePool.curNum; i < tsMWritePool.maxNum; ++i) {
|
||||||
SMWriteWorker *pWorker = tsMWritePool.writeWorker + i;
|
SMWriteWorker *pWorker = tsMWritePool.writeWorker + i;
|
||||||
pWorker->workerId = i;
|
pWorker->workerId = i;
|
||||||
|
|
||||||
|
@ -100,7 +108,8 @@ int32_t dnodeAllocateMnodeWqueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_attr_destroy(&thAttr);
|
pthread_attr_destroy(&thAttr);
|
||||||
dDebug("dnode mwrite worker:%d is launched, total:%d", pWorker->workerId, tsMWritePool.num);
|
tsMWritePool.curNum = i + 1;
|
||||||
|
dDebug("dnode mwrite worker:%d is launched, total:%d", pWorker->workerId, tsMWritePool.maxNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
dDebug("dnode mwrite queue:%p is allocated", tsMWriteQueue);
|
dDebug("dnode mwrite queue:%p is allocated", tsMWriteQueue);
|
||||||
|
@ -108,6 +117,7 @@ int32_t dnodeAllocateMnodeWqueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeFreeMnodeWqueue() {
|
void dnodeFreeMnodeWqueue() {
|
||||||
|
dDebug("dnode mwrite queue:%p is freed", tsMWriteQueue);
|
||||||
taosCloseQueue(tsMWriteQueue);
|
taosCloseQueue(tsMWriteQueue);
|
||||||
tsMWriteQueue = NULL;
|
tsMWriteQueue = NULL;
|
||||||
}
|
}
|
||||||
|
@ -122,11 +132,15 @@ void dnodeDispatchToMnodeWriteQueue(SRpcMsg *pMsg) {
|
||||||
SMnodeMsg *pWrite = (SMnodeMsg *)taosAllocateQitem(sizeof(SMnodeMsg));
|
SMnodeMsg *pWrite = (SMnodeMsg *)taosAllocateQitem(sizeof(SMnodeMsg));
|
||||||
mnodeCreateMsg(pWrite, pMsg);
|
mnodeCreateMsg(pWrite, pMsg);
|
||||||
|
|
||||||
dDebug("app:%p:%p, msg:%s is put into mwrite queue", pWrite->rpcMsg.ahandle, pWrite, taosMsg[pWrite->rpcMsg.msgType]);
|
dDebug("app:%p:%p, msg:%s is put into mwrite queue:%p", pWrite->rpcMsg.ahandle, pWrite,
|
||||||
|
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue);
|
||||||
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeFreeMnodeWriteMsg(SMnodeMsg *pWrite) {
|
static void dnodeFreeMnodeWriteMsg(SMnodeMsg *pWrite) {
|
||||||
|
dDebug("app:%p:%p, msg:%s is freed from mwrite queue:%p", pWrite->rpcMsg.ahandle, pWrite,
|
||||||
|
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue);
|
||||||
|
|
||||||
mnodeCleanupMsg(pWrite);
|
mnodeCleanupMsg(pWrite);
|
||||||
taosFreeQitem(pWrite);
|
taosFreeQitem(pWrite);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +172,7 @@ static void *dnodeProcessMnodeWriteQueue(void *param) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (taosReadQitemFromQset(tsMWriteQset, &type, (void **)&pWrite, &unUsed) == 0) {
|
if (taosReadQitemFromQset(tsMWriteQset, &type, (void **)&pWrite, &unUsed) == 0) {
|
||||||
dDebug("dnodeProcessMnodeWriteQueue: got no message from qset, exiting...");
|
dDebug("qset:%p, mnode write got no message from qset, exiting", tsMWriteQset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,8 +196,8 @@ void dnodeReprocessMnodeWriteMsg(void *pMsg) {
|
||||||
dnodeSendRedirectMsg(pMsg, true);
|
dnodeSendRedirectMsg(pMsg, true);
|
||||||
dnodeFreeMnodeWriteMsg(pWrite);
|
dnodeFreeMnodeWriteMsg(pWrite);
|
||||||
} else {
|
} else {
|
||||||
dDebug("app:%p:%p, msg:%s is reput into mwrite queue, retry times:%d", pWrite->rpcMsg.ahandle, pWrite,
|
dDebug("app:%p:%p, msg:%s is reput into mwrite queue:%p, retry times:%d", pWrite->rpcMsg.ahandle, pWrite,
|
||||||
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue, pWrite->retry);
|
||||||
|
|
||||||
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,14 +74,16 @@ static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *pMsg);
|
||||||
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *pMsg);
|
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *pMsg);
|
||||||
static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg);
|
static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg);
|
||||||
static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg);
|
static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg);
|
||||||
|
static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg);
|
||||||
static int32_t (*dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *pMsg);
|
static int32_t (*dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *pMsg);
|
||||||
|
|
||||||
int32_t dnodeInitMgmt() {
|
int32_t dnodeInitMgmt() {
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeProcessCreateVnodeMsg;
|
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeProcessCreateVnodeMsg;
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeProcessAlterVnodeMsg;
|
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeProcessAlterVnodeMsg;
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeProcessDropVnodeMsg;
|
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeProcessDropVnodeMsg;
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeProcessAlterStreamMsg;
|
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeProcessAlterStreamMsg;
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeProcessConfigDnodeMsg;
|
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeProcessConfigDnodeMsg;
|
||||||
|
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_MNODE] = dnodeProcessCreateMnodeMsg;
|
||||||
|
|
||||||
dnodeAddClientRspHandle(TSDB_MSG_TYPE_DM_STATUS_RSP, dnodeProcessStatusRsp);
|
dnodeAddClientRspHandle(TSDB_MSG_TYPE_DM_STATUS_RSP, dnodeProcessStatusRsp);
|
||||||
dnodeReadDnodeCfg();
|
dnodeReadDnodeCfg();
|
||||||
|
@ -226,7 +228,7 @@ static void *dnodeProcessMgmtQueue(void *param) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (taosReadQitemFromQset(tsMgmtQset, &type, (void **) &pMsg, &handle) == 0) {
|
if (taosReadQitemFromQset(tsMgmtQset, &type, (void **) &pMsg, &handle) == 0) {
|
||||||
dDebug("dnode mgmt got no message from qset, exit ...");
|
dDebug("qset:%p, dnode mgmt got no message from qset, exit", tsMgmtQset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,10 +453,34 @@ static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg) {
|
static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg) {
|
||||||
SMDCfgDnodeMsg *pCfg = (SMDCfgDnodeMsg *)pMsg->pCont;
|
SMDCfgDnodeMsg *pCfg = pMsg->pCont;
|
||||||
return taosCfgDynamicOptions(pCfg->config);
|
return taosCfgDynamicOptions(pCfg->config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
|
||||||
|
SMDCreateMnodeMsg *pCfg = pMsg->pCont;
|
||||||
|
pCfg->dnodeId = htonl(pCfg->dnodeId);
|
||||||
|
if (pCfg->dnodeId != dnodeGetDnodeId()) {
|
||||||
|
dError("dnodeId:%d, in create mnode msg is not equal with saved dnodeId:%d", pCfg->dnodeId, dnodeGetDnodeId());
|
||||||
|
return TSDB_CODE_MND_DNODE_ID_NOT_CONFIGURED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(pCfg->dnodeEp, tsLocalEp) != 0) {
|
||||||
|
dError("dnodeEp:%s, in create mnode msg is not equal with saved dnodeEp:%s", pCfg->dnodeEp, tsLocalEp);
|
||||||
|
return TSDB_CODE_MND_DNODE_EP_NOT_CONFIGURED;
|
||||||
|
}
|
||||||
|
|
||||||
|
dDebug("dnodeId:%d, create mnode msg is received from mnodes, numOfMnodes:%d", pCfg->dnodeId, pCfg->mnodes.nodeNum);
|
||||||
|
for (int i = 0; i < pCfg->mnodes.nodeNum; ++i) {
|
||||||
|
pCfg->mnodes.nodeInfos[i].nodeId = htonl(pCfg->mnodes.nodeInfos[i].nodeId);
|
||||||
|
dDebug("mnode index:%d, mnode:%d:%s", i, pCfg->mnodes.nodeInfos[i].nodeId, pCfg->mnodes.nodeInfos[i].nodeEp);
|
||||||
|
}
|
||||||
|
|
||||||
|
dnodeStartMnode(&pCfg->mnodes);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void dnodeUpdateMnodeEpSetForPeer(SRpcEpSet *pEpSet) {
|
void dnodeUpdateMnodeEpSetForPeer(SRpcEpSet *pEpSet) {
|
||||||
if (pEpSet->numOfEps <= 0) {
|
if (pEpSet->numOfEps <= 0) {
|
||||||
dError("mnode EP list for peer is changed, but content is invalid, discard it");
|
dError("mnode EP list for peer is changed, but content is invalid, discard it");
|
||||||
|
@ -465,13 +491,6 @@ void dnodeUpdateMnodeEpSetForPeer(SRpcEpSet *pEpSet) {
|
||||||
for (int i = 0; i < pEpSet->numOfEps; ++i) {
|
for (int i = 0; i < pEpSet->numOfEps; ++i) {
|
||||||
pEpSet->port[i] -= TSDB_PORT_DNODEDNODE;
|
pEpSet->port[i] -= TSDB_PORT_DNODEDNODE;
|
||||||
dInfo("mnode index:%d %s:%u", i, pEpSet->fqdn[i], pEpSet->port[i]);
|
dInfo("mnode index:%d %s:%u", i, pEpSet->fqdn[i], pEpSet->port[i]);
|
||||||
|
|
||||||
if (!mnodeIsRunning()) {
|
|
||||||
if (strcmp(pEpSet->fqdn[i], tsLocalFqdn) == 0 && pEpSet->port[i] == tsServerPort) {
|
|
||||||
dInfo("mnode index:%d %s:%u should work as master", i, pEpSet->fqdn[i], pEpSet->port[i]);
|
|
||||||
sdbUpdateSync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tsDMnodeEpSet = *pEpSet;
|
tsDMnodeEpSet = *pEpSet;
|
||||||
|
@ -516,7 +535,9 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
vnodeSetAccess(pStatusRsp->vgAccess, pCfg->numOfVnodes);
|
vnodeSetAccess(pStatusRsp->vgAccess, pCfg->numOfVnodes);
|
||||||
dnodeProcessModuleStatus(pCfg->moduleStatus);
|
|
||||||
|
// will not set mnode in status msg
|
||||||
|
// dnodeProcessModuleStatus(pCfg->moduleStatus);
|
||||||
dnodeUpdateDnodeCfg(pCfg);
|
dnodeUpdateDnodeCfg(pCfg);
|
||||||
|
|
||||||
dnodeUpdateMnodeInfos(pMnodes);
|
dnodeUpdateMnodeInfos(pMnodes);
|
||||||
|
@ -560,7 +581,7 @@ static void dnodeUpdateMnodeInfos(SDMMnodeInfos *pMnodes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dnodeSaveMnodeInfos();
|
dnodeSaveMnodeInfos();
|
||||||
sdbUpdateSync();
|
sdbUpdateAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dnodeReadMnodeInfos() {
|
static bool dnodeReadMnodeInfos() {
|
||||||
|
|
|
@ -146,19 +146,19 @@ void dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dnodeCheckMnodeStarting() {
|
bool dnodeStartMnode(void *pMnodes) {
|
||||||
if (tsModuleStatus & (1 << TSDB_MOD_MNODE)) return false;
|
SDMMnodeInfos *mnodes = pMnodes;
|
||||||
|
|
||||||
SDMMnodeInfos *mnodes = dnodeGetMnodeInfos();
|
if (tsModuleStatus & (1 << TSDB_MOD_MNODE)) {
|
||||||
for (int32_t i = 0; i < mnodes->nodeNum; ++i) {
|
dDebug("mnode module is already started, module status:%d", tsModuleStatus);
|
||||||
SDMMnodeInfo *node = &mnodes->nodeInfos[i];
|
return false;
|
||||||
if (node->nodeId == dnodeGetDnodeId()) {
|
|
||||||
uint32_t moduleStatus = tsModuleStatus | (1 << TSDB_MOD_MNODE);
|
|
||||||
dInfo("start mnode module, module status:%d, new status:%d", tsModuleStatus, moduleStatus);
|
|
||||||
dnodeProcessModuleStatus(moduleStatus);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
uint32_t moduleStatus = tsModuleStatus | (1 << TSDB_MOD_MNODE);
|
||||||
|
dInfo("start mnode module, module status:%d, new status:%d", tsModuleStatus, moduleStatus);
|
||||||
|
dnodeProcessModuleStatus(moduleStatus);
|
||||||
|
|
||||||
|
sdbUpdateSync(mnodes);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ int32_t dnodeInitServer() {
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeDispatchToMgmtQueue;
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeDispatchToMgmtQueue;
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeDispatchToMgmtQueue;
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeDispatchToMgmtQueue;
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeDispatchToMgmtQueue;
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeDispatchToMgmtQueue;
|
||||||
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_MNODE] = dnodeDispatchToMgmtQueue;
|
||||||
|
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_CONFIG_TABLE] = dnodeDispatchToMnodePeerQueue;
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_CONFIG_TABLE] = dnodeDispatchToMnodePeerQueue;
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_CONFIG_VNODE] = dnodeDispatchToMnodePeerQueue;
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_CONFIG_VNODE] = dnodeDispatchToMnodePeerQueue;
|
||||||
|
@ -170,8 +171,12 @@ void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg) {
|
||||||
rpcSendRequest(tsDnodeClientRpc, epSet, rpcMsg);
|
rpcSendRequest(tsDnodeClientRpc, epSet, rpcMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeSendMsgToDnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp) {
|
void dnodeSendMsgToMnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp) {
|
||||||
SRpcEpSet epSet = {0};
|
SRpcEpSet epSet = {0};
|
||||||
dnodeGetMnodeEpSetForPeer(&epSet);
|
dnodeGetMnodeEpSetForPeer(&epSet);
|
||||||
rpcSendRecv(tsDnodeClientRpc, &epSet, rpcMsg, rpcRsp);
|
rpcSendRecv(tsDnodeClientRpc, &epSet, rpcMsg, rpcRsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dnodeSendMsgToDnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp, SRpcEpSet *epSet) {
|
||||||
|
rpcSendRecv(tsDnodeClientRpc, epSet, rpcMsg, rpcRsp);
|
||||||
|
}
|
|
@ -156,7 +156,7 @@ static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char
|
||||||
|
|
||||||
dDebug("user:%s, send auth msg to mnodes", user);
|
dDebug("user:%s, send auth msg to mnodes", user);
|
||||||
SRpcMsg rpcRsp = {0};
|
SRpcMsg rpcRsp = {0};
|
||||||
dnodeSendMsgToDnodeRecv(&rpcMsg, &rpcRsp);
|
dnodeSendMsgToMnodeRecv(&rpcMsg, &rpcRsp);
|
||||||
|
|
||||||
if (rpcRsp.code != 0) {
|
if (rpcRsp.code != 0) {
|
||||||
dError("user:%s, auth msg received from mnodes, error:%s", user, tstrerror(rpcRsp.code));
|
dError("user:%s, auth msg received from mnodes, error:%s", user, tstrerror(rpcRsp.code));
|
||||||
|
@ -189,7 +189,7 @@ void *dnodeSendCfgTableToRecv(int32_t vgId, int32_t sid) {
|
||||||
rpcMsg.msgType = TSDB_MSG_TYPE_DM_CONFIG_TABLE;
|
rpcMsg.msgType = TSDB_MSG_TYPE_DM_CONFIG_TABLE;
|
||||||
|
|
||||||
SRpcMsg rpcRsp = {0};
|
SRpcMsg rpcRsp = {0};
|
||||||
dnodeSendMsgToDnodeRecv(&rpcMsg, &rpcRsp);
|
dnodeSendMsgToMnodeRecv(&rpcMsg, &rpcRsp);
|
||||||
terrno = rpcRsp.code;
|
terrno = rpcRsp.code;
|
||||||
|
|
||||||
if (rpcRsp.code != 0) {
|
if (rpcRsp.code != 0) {
|
||||||
|
|
|
@ -177,7 +177,8 @@ static void addMemoryInfo(SBufferWriter* bw) {
|
||||||
static void addVersionInfo(SBufferWriter* bw) {
|
static void addVersionInfo(SBufferWriter* bw) {
|
||||||
addStringField(bw, "version", version);
|
addStringField(bw, "version", version);
|
||||||
addStringField(bw, "buildInfo", buildinfo);
|
addStringField(bw, "buildInfo", buildinfo);
|
||||||
addStringField(bw, "gitInfo", gitinfo);
|
addStringField(bw, "gitInfo", gitinfo);
|
||||||
|
addStringField(bw, "email", tsEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addRuntimeInfo(SBufferWriter* bw) {
|
static void addRuntimeInfo(SBufferWriter* bw) {
|
||||||
|
@ -261,11 +262,27 @@ static void* telemetryThread(void* param) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dnodeGetEmail(char* filepath) {
|
||||||
|
int fd = open(filepath, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosTRead(fd, (void *)tsEmail, TSDB_FQDN_LEN) < 0) {
|
||||||
|
dError("failed to read %d bytes from file %s since %s", TSDB_FQDN_LEN, filepath, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t dnodeInitTelemetry() {
|
int32_t dnodeInitTelemetry() {
|
||||||
if (!tsEnableTelemetryReporting) {
|
if (!tsEnableTelemetryReporting) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dnodeGetEmail("/usr/local/taos/email");
|
||||||
|
|
||||||
if (tsem_init(&tsExitSem, 0, 0) == -1) {
|
if (tsem_init(&tsExitSem, 0, 0) == -1) {
|
||||||
// just log the error, it is ok for telemetry to fail
|
// just log the error, it is ok for telemetry to fail
|
||||||
dTrace("failed to create semaphore for telemetry, reason:%s", strerror(errno));
|
dTrace("failed to create semaphore for telemetry, reason:%s", strerror(errno));
|
||||||
|
|
|
@ -187,6 +187,7 @@ void dnodeSendRpcReadRsp(void *pVnode, SReadMsg *pRead, int32_t code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeDispatchNonRspMsg(void *pVnode, SReadMsg *pRead, int32_t code) {
|
void dnodeDispatchNonRspMsg(void *pVnode, SReadMsg *pRead, int32_t code) {
|
||||||
|
rpcFreeCont(pRead->rpcMsg.pCont);
|
||||||
vnodeRelease(pVnode);
|
vnodeRelease(pVnode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +199,7 @@ static void *dnodeProcessReadQueue(void *param) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (taosReadQitemFromQset(readQset, &type, (void **)&pReadMsg, &pVnode) == 0) {
|
if (taosReadQitemFromQset(readQset, &type, (void **)&pReadMsg, &pVnode) == 0) {
|
||||||
dDebug("dnodeProcessReadQueee: got no message from qset, exiting...");
|
dDebug("qset:%p dnode read got no message from qset, exiting", readQset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,19 +210,19 @@ void dnodeSendRpcVnodeWriteRsp(void *pVnode, void *param, int32_t code) {
|
||||||
|
|
||||||
static void *dnodeProcessWriteQueue(void *param) {
|
static void *dnodeProcessWriteQueue(void *param) {
|
||||||
SWriteWorker *pWorker = (SWriteWorker *)param;
|
SWriteWorker *pWorker = (SWriteWorker *)param;
|
||||||
SWriteMsg *pWrite;
|
SWriteMsg * pWrite;
|
||||||
SWalHead *pHead;
|
SWalHead * pHead;
|
||||||
int32_t numOfMsgs;
|
int32_t numOfMsgs;
|
||||||
int type;
|
int type;
|
||||||
void *pVnode, *item;
|
void * pVnode, *item;
|
||||||
SRspRet *pRspRet;
|
SRspRet * pRspRet;
|
||||||
|
|
||||||
dDebug("write worker:%d is running", pWorker->workerId);
|
dDebug("write worker:%d is running", pWorker->workerId);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
numOfMsgs = taosReadAllQitemsFromQset(pWorker->qset, pWorker->qall, &pVnode);
|
numOfMsgs = taosReadAllQitemsFromQset(pWorker->qset, pWorker->qall, &pVnode);
|
||||||
if (numOfMsgs == 0) {
|
if (numOfMsgs == 0) {
|
||||||
dDebug("dnodeProcessWriteQueee: got no message from qset, exiting...");
|
dDebug("qset:%p, dnode write got no message from qset, exiting", pWorker->qset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,16 +237,21 @@ static void *dnodeProcessWriteQueue(void *param) {
|
||||||
pHead->msgType = pWrite->rpcMsg.msgType;
|
pHead->msgType = pWrite->rpcMsg.msgType;
|
||||||
pHead->version = 0;
|
pHead->version = 0;
|
||||||
pHead->len = pWrite->contLen;
|
pHead->len = pWrite->contLen;
|
||||||
dDebug("%p, rpc msg:%s will be processed in vwrite queue", pWrite->rpcMsg.ahandle, taosMsg[pWrite->rpcMsg.msgType]);
|
dDebug("%p, rpc msg:%s will be processed in vwrite queue", pWrite->rpcMsg.ahandle,
|
||||||
|
taosMsg[pWrite->rpcMsg.msgType]);
|
||||||
} else {
|
} else {
|
||||||
pHead = (SWalHead *)item;
|
pHead = (SWalHead *)item;
|
||||||
dTrace("%p, wal msg:%s will be processed in vwrite queue, version:%" PRIu64, pHead, taosMsg[pHead->msgType], pHead->version);
|
dTrace("%p, wal msg:%s will be processed in vwrite queue, version:%" PRIu64, pHead, taosMsg[pHead->msgType],
|
||||||
|
pHead->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = vnodeProcessWrite(pVnode, type, pHead, pRspRet);
|
int32_t code = vnodeProcessWrite(pVnode, type, pHead, pRspRet);
|
||||||
if (pWrite) {
|
dTrace("%p, msg:%s is processed in vwrite queue, version:%" PRIu64 ", result:%s", pHead, taosMsg[pHead->msgType],
|
||||||
|
pHead->version, tstrerror(code));
|
||||||
|
|
||||||
|
if (pWrite) {
|
||||||
pWrite->rpcMsg.code = code;
|
pWrite->rpcMsg.code = code;
|
||||||
if (code <= 0) pWrite->processedCount = 1;
|
if (code <= 0) pWrite->processedCount = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +263,7 @@ static void *dnodeProcessWriteQueue(void *param) {
|
||||||
taosGetQitem(pWorker->qall, &type, &item);
|
taosGetQitem(pWorker->qall, &type, &item);
|
||||||
if (type == TAOS_QTYPE_RPC) {
|
if (type == TAOS_QTYPE_RPC) {
|
||||||
pWrite = (SWriteMsg *)item;
|
pWrite = (SWriteMsg *)item;
|
||||||
dnodeSendRpcVnodeWriteRsp(pVnode, item, pWrite->rpcMsg.code);
|
dnodeSendRpcVnodeWriteRsp(pVnode, item, pWrite->rpcMsg.code);
|
||||||
} else if (type == TAOS_QTYPE_FWD) {
|
} else if (type == TAOS_QTYPE_FWD) {
|
||||||
pHead = (SWalHead *)item;
|
pHead = (SWalHead *)item;
|
||||||
vnodeConfirmForward(pVnode, pHead->version, 0);
|
vnodeConfirmForward(pVnode, pHead->version, 0);
|
||||||
|
@ -279,13 +284,13 @@ static void dnodeHandleIdleWorker(SWriteWorker *pWorker) {
|
||||||
int32_t num = taosGetQueueNumber(pWorker->qset);
|
int32_t num = taosGetQueueNumber(pWorker->qset);
|
||||||
|
|
||||||
if (num > 0) {
|
if (num > 0) {
|
||||||
usleep(30000);
|
usleep(30000);
|
||||||
sched_yield();
|
sched_yield();
|
||||||
} else {
|
} else {
|
||||||
taosFreeQall(pWorker->qall);
|
taosFreeQall(pWorker->qall);
|
||||||
taosCloseQset(pWorker->qset);
|
taosCloseQset(pWorker->qset);
|
||||||
pWorker->qset = NULL;
|
pWorker->qset = NULL;
|
||||||
dDebug("write worker:%d is released", pWorker->workerId);
|
dDebug("write worker:%d is released", pWorker->workerId);
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,11 +43,12 @@ void dnodeGetMnodeEpSetForPeer(void *epSet);
|
||||||
void dnodeGetMnodeEpSetForShell(void *epSet);
|
void dnodeGetMnodeEpSetForShell(void *epSet);
|
||||||
void * dnodeGetMnodeInfos();
|
void * dnodeGetMnodeInfos();
|
||||||
int32_t dnodeGetDnodeId();
|
int32_t dnodeGetDnodeId();
|
||||||
bool dnodeCheckMnodeStarting();
|
bool dnodeStartMnode(void *pModes);
|
||||||
|
|
||||||
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
|
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
|
||||||
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
|
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
|
||||||
void dnodeSendMsgToDnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp);
|
void dnodeSendMsgToMnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp);
|
||||||
|
void dnodeSendMsgToDnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp, SRpcEpSet *epSet);
|
||||||
void *dnodeSendCfgTableToRecv(int32_t vgId, int32_t sid);
|
void *dnodeSendCfgTableToRecv(int32_t vgId, int32_t sid);
|
||||||
|
|
||||||
void *dnodeAllocateVnodeWqueue(void *pVnode);
|
void *dnodeAllocateVnodeWqueue(void *pVnode);
|
||||||
|
|
|
@ -60,7 +60,8 @@ int32_t mnodeInitSystem();
|
||||||
int32_t mnodeStartSystem();
|
int32_t mnodeStartSystem();
|
||||||
void mnodeCleanupSystem();
|
void mnodeCleanupSystem();
|
||||||
void mnodeStopSystem();
|
void mnodeStopSystem();
|
||||||
void sdbUpdateSync();
|
void sdbUpdateAsync();
|
||||||
|
void sdbUpdateSync(void *pMnodes);
|
||||||
bool mnodeIsRunning();
|
bool mnodeIsRunning();
|
||||||
int32_t mnodeProcessRead(SMnodeMsg *pMsg);
|
int32_t mnodeProcessRead(SMnodeMsg *pMsg);
|
||||||
int32_t mnodeProcessWrite(SMnodeMsg *pMsg);
|
int32_t mnodeProcessWrite(SMnodeMsg *pMsg);
|
||||||
|
|
|
@ -253,8 +253,10 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
||||||
#define TSDB_COL_NAME_LEN 65
|
#define TSDB_COL_NAME_LEN 65
|
||||||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
||||||
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
||||||
#define TSDB_MAX_SQL_SHOW_LEN 256
|
#define TSDB_MAX_SQL_SHOW_LEN 512
|
||||||
#define TSDB_MAX_ALLOWED_SQL_LEN (1*1024*1024U) // sql length should be less than 8mb
|
#define TSDB_MAX_ALLOWED_SQL_LEN (8*1024*1024U) // sql length should be less than 8mb
|
||||||
|
|
||||||
|
#define TSDB_APPNAME_LEN TSDB_UNI_LEN
|
||||||
|
|
||||||
#define TSDB_MAX_BYTES_PER_ROW 16384
|
#define TSDB_MAX_BYTES_PER_ROW 16384
|
||||||
#define TSDB_MAX_TAGS_LEN 16384
|
#define TSDB_MAX_TAGS_LEN 16384
|
||||||
|
@ -282,7 +284,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
||||||
#define TSDB_SHELL_VNODE_BITS 24
|
#define TSDB_SHELL_VNODE_BITS 24
|
||||||
#define TSDB_SHELL_SID_MASK 0xFF
|
#define TSDB_SHELL_SID_MASK 0xFF
|
||||||
#define TSDB_HTTP_TOKEN_LEN 20
|
#define TSDB_HTTP_TOKEN_LEN 20
|
||||||
#define TSDB_SHOW_SQL_LEN 64
|
#define TSDB_SHOW_SQL_LEN 512
|
||||||
#define TSDB_SLOW_QUERY_SQL_LEN 512
|
#define TSDB_SLOW_QUERY_SQL_LEN 512
|
||||||
|
|
||||||
#define TSDB_MQTT_HOSTNAME_LEN 64
|
#define TSDB_MQTT_HOSTNAME_LEN 64
|
||||||
|
|
|
@ -139,6 +139,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE, 0, 0x0339, "Vgroup alr
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_NOT_FREE, 0, 0x033A, "Dnode not avaliable")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_NOT_FREE, 0, 0x033A, "Dnode not avaliable")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CLUSTER_ID, 0, 0x033B, "Cluster id not match")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CLUSTER_ID, 0, 0x033B, "Cluster id not match")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_NOT_READY, 0, 0x033C, "Cluster not ready")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_NOT_READY, 0, 0x033C, "Cluster not ready")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_ID_NOT_CONFIGURED, 0, 0x033D, "Dnode Id not configured")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_EP_NOT_CONFIGURED, 0, 0x033E, "Dnode Ep not configured")
|
||||||
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACCT_ALREADY_EXIST, 0, 0x0340, "Account already exists")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACCT_ALREADY_EXIST, 0, 0x0340, "Account already exists")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ACCT, 0, 0x0341, "Invalid account")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ACCT, 0, 0x0341, "Invalid account")
|
||||||
|
@ -191,6 +193,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_DISK_PERMISSIONS, 0, 0x0506, "No write p
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR, 0, 0x0507, "Missing data file")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR, 0, 0x0507, "Missing data file")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_OUT_OF_MEMORY, 0, 0x0508, "Out of memory")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_OUT_OF_MEMORY, 0, 0x0508, "Out of memory")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_APP_ERROR, 0, 0x0509, "Unexpected generic error in vnode")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_APP_ERROR, 0, 0x0509, "Unexpected generic error in vnode")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_VRESION_FILE, 0, 0x050A, "Invalid version file")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, 0, 0x0511, "Database suspended")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, 0, 0x0511, "Database suspended")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, 0, 0x0512, "Write operation denied")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, 0, 0x0512, "Write operation denied")
|
||||||
|
|
||||||
|
@ -245,6 +248,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_CPU_LIMITED, 0, 0x080B, "CPU cores
|
||||||
// sync
|
// sync
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_CONFIG, 0, 0x0900, "Invalid Sync Configuration")
|
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_CONFIG, 0, 0x0900, "Invalid Sync Configuration")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_ENABLED, 0, 0x0901, "Sync module not enabled")
|
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_ENABLED, 0, 0x0901, "Sync module not enabled")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_VERSION, 0, 0x0902, "Invalid Sync version")
|
||||||
|
|
||||||
// wal
|
// wal
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_APP_ERROR, 0, 0x1000, "Unexpected generic error in wal")
|
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_APP_ERROR, 0, 0x1000, "Unexpected generic error in wal")
|
||||||
|
|
|
@ -59,7 +59,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_DROP_STABLE, "drop-stable" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_ALTER_STREAM, "alter-stream" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_ALTER_STREAM, "alter-stream" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_CONFIG_DNODE, "config-dnode" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_CONFIG_DNODE, "config-dnode" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_ALTER_VNODE, "alter-vnode" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_ALTER_VNODE, "alter-vnode" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY5, "dummy5" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_CREATE_MNODE, "create-mnode" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY6, "dummy6" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY6, "dummy6" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY7, "dummy7" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY7, "dummy7" )
|
||||||
|
|
||||||
|
@ -305,6 +305,8 @@ typedef struct {
|
||||||
char clientVersion[TSDB_VERSION_LEN];
|
char clientVersion[TSDB_VERSION_LEN];
|
||||||
char msgVersion[TSDB_VERSION_LEN];
|
char msgVersion[TSDB_VERSION_LEN];
|
||||||
char db[TSDB_TABLE_FNAME_LEN];
|
char db[TSDB_TABLE_FNAME_LEN];
|
||||||
|
char appName[TSDB_APPNAME_LEN];
|
||||||
|
int32_t pid;
|
||||||
} SCMConnectMsg;
|
} SCMConnectMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -719,6 +721,12 @@ typedef struct {
|
||||||
char ep[TSDB_EP_LEN]; // end point, hostname:port
|
char ep[TSDB_EP_LEN]; // end point, hostname:port
|
||||||
} SCMCreateDnodeMsg, SCMDropDnodeMsg;
|
} SCMCreateDnodeMsg, SCMDropDnodeMsg;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t dnodeId;
|
||||||
|
char dnodeEp[TSDB_EP_LEN]; // end point, hostname:port
|
||||||
|
SDMMnodeInfos mnodes;
|
||||||
|
} SMDCreateMnodeMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t dnodeId;
|
int32_t dnodeId;
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
|
@ -740,6 +748,7 @@ typedef struct {
|
||||||
uint32_t queryId;
|
uint32_t queryId;
|
||||||
int64_t useconds;
|
int64_t useconds;
|
||||||
int64_t stime;
|
int64_t stime;
|
||||||
|
uint64_t qHandle;
|
||||||
} SQueryDesc;
|
} SQueryDesc;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -755,8 +764,10 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t connId;
|
uint32_t connId;
|
||||||
|
int32_t pid;
|
||||||
int32_t numOfQueries;
|
int32_t numOfQueries;
|
||||||
int32_t numOfStreams;
|
int32_t numOfStreams;
|
||||||
|
char appName[TSDB_APPNAME_LEN];
|
||||||
char pData[];
|
char pData[];
|
||||||
} SCMHeartBeatMsg;
|
} SCMHeartBeatMsg;
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ int walWrite(twalh, SWalHead *);
|
||||||
void walFsync(twalh);
|
void walFsync(twalh);
|
||||||
int walRestore(twalh, void *pVnode, FWalWrite writeFp);
|
int walRestore(twalh, void *pVnode, FWalWrite writeFp);
|
||||||
int walGetWalFile(twalh, char *name, uint32_t *index);
|
int walGetWalFile(twalh, char *name, uint32_t *index);
|
||||||
|
int64_t walGetVersion(twalh);
|
||||||
|
|
||||||
extern int wDebugFlag;
|
extern int wDebugFlag;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
|
#include "tsclient.h"
|
||||||
|
|
||||||
#define MAX_USERNAME_SIZE 64
|
#define MAX_USERNAME_SIZE 64
|
||||||
#define MAX_DBNAME_SIZE 64
|
#define MAX_DBNAME_SIZE 64
|
||||||
|
|
|
@ -294,9 +294,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
||||||
|
|
||||||
st = taosGetTimestampUs();
|
st = taosGetTimestampUs();
|
||||||
|
|
||||||
TAOS_RES* pSql = taos_query(con, command);
|
TAOS_RES* pSql = taos_query_h(con, command, &result);
|
||||||
atomic_store_ptr(&result, pSql); // set the global TAOS_RES pointer
|
|
||||||
|
|
||||||
if (taos_errno(pSql)) {
|
if (taos_errno(pSql)) {
|
||||||
taos_error(pSql);
|
taos_error(pSql);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -31,7 +31,7 @@ typedef enum {
|
||||||
int32_t mnodeInitMnodes();
|
int32_t mnodeInitMnodes();
|
||||||
void mnodeCleanupMnodes();
|
void mnodeCleanupMnodes();
|
||||||
|
|
||||||
int32_t mnodeAddMnode(int32_t dnodeId);
|
void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm);
|
||||||
int32_t mnodeDropMnode(int32_t dnodeId);
|
int32_t mnodeDropMnode(int32_t dnodeId);
|
||||||
void mnodeDropMnodeLocal(int32_t dnodeId);
|
void mnodeDropMnodeLocal(int32_t dnodeId);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ extern "C" {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char user[TSDB_USER_LEN];
|
char user[TSDB_USER_LEN];
|
||||||
|
char appName[TSDB_APPNAME_LEN]; // app name that invokes taosc
|
||||||
|
uint32_t pid; // pid of app that invokes taosc
|
||||||
int8_t killed;
|
int8_t killed;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
|
@ -40,7 +42,7 @@ typedef struct {
|
||||||
int32_t mnodeInitProfile();
|
int32_t mnodeInitProfile();
|
||||||
void mnodeCleanupProfile();
|
void mnodeCleanupProfile();
|
||||||
|
|
||||||
SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port);
|
SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port, int32_t pid, const char* app);
|
||||||
SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t port);
|
SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t port);
|
||||||
void mnodeReleaseConn(SConnObj *pConn);
|
void mnodeReleaseConn(SConnObj *pConn);
|
||||||
int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SCMHeartBeatMsg *pHBMsg);
|
int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SCMHeartBeatMsg *pHBMsg);
|
||||||
|
|
|
@ -225,6 +225,7 @@ static int32_t mnodeRetrieveClusters(SShowObj *pShow, char *data, int32_t rows,
|
||||||
numOfRows++;
|
numOfRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
|
@ -648,8 +648,12 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
|
||||||
|
|
||||||
while (numOfRows < rows) {
|
while (numOfRows < rows) {
|
||||||
pShow->pIter = mnodeGetNextDb(pShow->pIter, &pDb);
|
pShow->pIter = mnodeGetNextDb(pShow->pIter, &pDb);
|
||||||
|
|
||||||
if (pDb == NULL) break;
|
if (pDb == NULL) break;
|
||||||
if (pDb->pAcct != pUser->pAcct) continue;
|
if (pDb->pAcct != pUser->pAcct) {
|
||||||
|
mnodeDecDbRef(pDb);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
cols = 0;
|
cols = 0;
|
||||||
|
|
||||||
|
@ -760,6 +764,8 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
|
||||||
}
|
}
|
||||||
|
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
|
|
||||||
mnodeDecUserRef(pUser);
|
mnodeDecUserRef(pUser);
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ static int32_t mnodeDnodeActionRestored() {
|
||||||
mnodeCreateDnode(tsLocalEp, NULL);
|
mnodeCreateDnode(tsLocalEp, NULL);
|
||||||
SDnodeObj *pDnode = mnodeGetDnodeByEp(tsLocalEp);
|
SDnodeObj *pDnode = mnodeGetDnodeByEp(tsLocalEp);
|
||||||
if (pDnode != NULL) {
|
if (pDnode != NULL) {
|
||||||
mnodeAddMnode(pDnode->dnodeId);
|
mnodeCreateMnode(pDnode->dnodeId, pDnode->dnodeEp, false);
|
||||||
mnodeDecDnodeRef(pDnode);
|
mnodeDecDnodeRef(pDnode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,7 +471,8 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
|
||||||
mnodeGetClusterId());
|
mnodeGetClusterId());
|
||||||
return TSDB_CODE_MND_INVALID_CLUSTER_ID;
|
return TSDB_CODE_MND_INVALID_CLUSTER_ID;
|
||||||
} else {
|
} else {
|
||||||
mTrace("dnode:%d, status received, access times %d", pDnode->dnodeId, pDnode->lastAccess);
|
mTrace("dnode:%d, status received, access times %d openVnodes:%d:%d", pDnode->dnodeId, pDnode->lastAccess,
|
||||||
|
htons(pStatus->openVnodes), pDnode->openVnodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -790,6 +791,7 @@ static int32_t mnodeRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
||||||
mnodeDecDnodeRef(pDnode);
|
mnodeDecDnodeRef(pDnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
@ -857,6 +859,7 @@ int32_t mnodeRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pC
|
||||||
|
|
||||||
char* pWrite;
|
char* pWrite;
|
||||||
char* moduleName[5] = { "MNODE", "HTTP", "MONITOR", "MQTT", "UNKNOWN" };
|
char* moduleName[5] = { "MNODE", "HTTP", "MONITOR", "MQTT", "UNKNOWN" };
|
||||||
|
int32_t cols;
|
||||||
|
|
||||||
while (numOfRows < rows) {
|
while (numOfRows < rows) {
|
||||||
SDnodeObj *pDnode = NULL;
|
SDnodeObj *pDnode = NULL;
|
||||||
|
@ -864,7 +867,7 @@ int32_t mnodeRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pC
|
||||||
if (pDnode == NULL) break;
|
if (pDnode == NULL) break;
|
||||||
|
|
||||||
for (int32_t moduleType = 0; moduleType < TSDB_MOD_MAX; ++moduleType) {
|
for (int32_t moduleType = 0; moduleType < TSDB_MOD_MAX; ++moduleType) {
|
||||||
int32_t cols = 0;
|
cols = 0;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
*(int16_t *)pWrite = pDnode->dnodeId;
|
*(int16_t *)pWrite = pDnode->dnodeId;
|
||||||
|
@ -891,6 +894,7 @@ int32_t mnodeRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pC
|
||||||
mnodeDecDnodeRef(pDnode);
|
mnodeDecDnodeRef(pDnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
@ -990,6 +994,7 @@ static int32_t mnodeRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
@ -1082,6 +1087,7 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
||||||
numOfRows = 0;
|
numOfRows = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ int32_t mnodeStartSystem() {
|
||||||
|
|
||||||
mInfo("mnode is initialized successfully");
|
mInfo("mnode is initialized successfully");
|
||||||
|
|
||||||
sdbUpdateSync();
|
sdbUpdateSync(NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "tsocket.h"
|
#include "tsocket.h"
|
||||||
#include "tdataformat.h"
|
#include "tdataformat.h"
|
||||||
|
#include "dnode.h"
|
||||||
|
#include "mnode.h"
|
||||||
#include "mnodeDef.h"
|
#include "mnodeDef.h"
|
||||||
#include "mnodeInt.h"
|
#include "mnodeInt.h"
|
||||||
#include "mnodeMnode.h"
|
#include "mnodeMnode.h"
|
||||||
|
@ -30,6 +32,7 @@
|
||||||
#include "mnodeSdb.h"
|
#include "mnodeSdb.h"
|
||||||
#include "mnodeShow.h"
|
#include "mnodeShow.h"
|
||||||
#include "mnodeUser.h"
|
#include "mnodeUser.h"
|
||||||
|
#include "mnodeVgroup.h"
|
||||||
|
|
||||||
static void * tsMnodeSdb = NULL;
|
static void * tsMnodeSdb = NULL;
|
||||||
static int32_t tsMnodeUpdateSize = 0;
|
static int32_t tsMnodeUpdateSize = 0;
|
||||||
|
@ -266,25 +269,87 @@ void mnodeGetMnodeInfos(void *mnodeInfos) {
|
||||||
mnodeMnodeUnLock();
|
mnodeMnodeUnLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mnodeAddMnode(int32_t dnodeId) {
|
static int32_t mnodeSendCreateMnodeMsg(int32_t dnodeId, char *dnodeEp) {
|
||||||
|
mDebug("dnode:%d, send create mnode msg to dnode %s", dnodeId, dnodeEp);
|
||||||
|
|
||||||
|
SMDCreateMnodeMsg *pCreate = rpcMallocCont(sizeof(SMDCreateMnodeMsg));
|
||||||
|
if (pCreate == NULL) {
|
||||||
|
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
} else {
|
||||||
|
pCreate->dnodeId = htonl(dnodeId);
|
||||||
|
tstrncpy(pCreate->dnodeEp, dnodeEp, sizeof(pCreate->dnodeEp));
|
||||||
|
pCreate->mnodes = tsMnodeInfos;
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < pCreate->mnodes.nodeNum; ++i) {
|
||||||
|
if (pCreate->mnodes.nodeInfos[i].nodeId == htonl(dnodeId)) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
pCreate->mnodes.nodeInfos[pCreate->mnodes.nodeNum].nodeId = htonl(dnodeId);
|
||||||
|
tstrncpy(pCreate->mnodes.nodeInfos[pCreate->mnodes.nodeNum].nodeEp, dnodeEp, sizeof(pCreate->dnodeEp));
|
||||||
|
pCreate->mnodes.nodeNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SRpcMsg rpcMsg = {0};
|
||||||
|
rpcMsg.pCont = pCreate;
|
||||||
|
rpcMsg.contLen = sizeof(SMDCreateMnodeMsg);
|
||||||
|
rpcMsg.msgType = TSDB_MSG_TYPE_MD_CREATE_MNODE;
|
||||||
|
|
||||||
|
SRpcMsg rpcRsp = {0};
|
||||||
|
SRpcEpSet epSet = mnodeGetEpSetFromIp(pCreate->dnodeEp);
|
||||||
|
dnodeSendMsgToDnodeRecv(&rpcMsg, &rpcRsp, &epSet);
|
||||||
|
|
||||||
|
if (rpcRsp.code != TSDB_CODE_SUCCESS) {
|
||||||
|
mError("dnode:%d, failed to send create mnode msg, ep:%s reason:%s", dnodeId, dnodeEp, tstrerror(rpcRsp.code));
|
||||||
|
} else {
|
||||||
|
mDebug("dnode:%d, create mnode msg is disposed, mnode is created in dnode", dnodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpcFreeCont(rpcRsp.pCont);
|
||||||
|
return rpcRsp.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeCreateMnodeCb(SMnodeMsg *pMsg, int32_t code) {
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
mError("failed to create mnode, reason:%s", tstrerror(code));
|
||||||
|
} else {
|
||||||
|
mDebug("mnode is created successfully");
|
||||||
|
mnodeUpdateMnodeEpSet();
|
||||||
|
sdbUpdateAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) {
|
||||||
SMnodeObj *pMnode = calloc(1, sizeof(SMnodeObj));
|
SMnodeObj *pMnode = calloc(1, sizeof(SMnodeObj));
|
||||||
pMnode->mnodeId = dnodeId;
|
pMnode->mnodeId = dnodeId;
|
||||||
pMnode->createdTime = taosGetTimestampMs();
|
pMnode->createdTime = taosGetTimestampMs();
|
||||||
|
|
||||||
SSdbOper oper = {
|
SSdbOper oper = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsMnodeSdb,
|
.table = tsMnodeSdb,
|
||||||
.pObj = pMnode,
|
.pObj = pMnode,
|
||||||
|
.writeCb = mnodeCreateMnodeCb
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t code = sdbInsertRow(&oper);
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
if (needConfirm) {
|
||||||
taosTFree(pMnode);
|
code = mnodeSendCreateMnodeMsg(dnodeId, dnodeEp);
|
||||||
}
|
}
|
||||||
|
|
||||||
mnodeUpdateMnodeEpSet();
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosTFree(pMnode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
code = sdbInsertRow(&oper);
|
||||||
|
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||||
|
mError("dnode:%d, failed to create mnode, ep:%s reason:%s", dnodeId, dnodeEp, tstrerror(code));
|
||||||
|
taosTFree(pMnode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mnodeDropMnodeLocal(int32_t dnodeId) {
|
void mnodeDropMnodeLocal(int32_t dnodeId) {
|
||||||
|
@ -296,6 +361,7 @@ void mnodeDropMnodeLocal(int32_t dnodeId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mnodeUpdateMnodeEpSet();
|
mnodeUpdateMnodeEpSet();
|
||||||
|
sdbUpdateAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mnodeDropMnode(int32_t dnodeId) {
|
int32_t mnodeDropMnode(int32_t dnodeId) {
|
||||||
|
@ -315,6 +381,7 @@ int32_t mnodeDropMnode(int32_t dnodeId) {
|
||||||
sdbDecRef(tsMnodeSdb, pMnode);
|
sdbDecRef(tsMnodeSdb, pMnode);
|
||||||
|
|
||||||
mnodeUpdateMnodeEpSet();
|
mnodeUpdateMnodeEpSet();
|
||||||
|
sdbUpdateAsync();
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -414,6 +481,7 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
||||||
mnodeDecMnodeRef(pMnode);
|
mnodeDecMnodeRef(pMnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
|
|
|
@ -58,10 +58,15 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) {
|
||||||
rpcRsp->rsp = epSet;
|
rpcRsp->rsp = epSet;
|
||||||
rpcRsp->len = sizeof(SRpcEpSet);
|
rpcRsp->len = sizeof(SRpcEpSet);
|
||||||
|
|
||||||
mDebug("%p, msg:%s in mpeer queue, will be redireced, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle,
|
mDebug("%p, msg:%s in mpeer queue will be redirected, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle,
|
||||||
taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse);
|
taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse);
|
||||||
for (int32_t i = 0; i < epSet->numOfEps; ++i) {
|
for (int32_t i = 0; i < epSet->numOfEps; ++i) {
|
||||||
mDebug("mnode index:%d ep:%s:%d", i, epSet->fqdn[i], htons(epSet->port[i]));
|
if (strcmp(epSet->fqdn[i], tsLocalFqdn) == 0 && htons(epSet->port[i]) == tsServerPort + TSDB_PORT_DNODEDNODE) {
|
||||||
|
epSet->inUse = (i + 1) % epSet->numOfEps;
|
||||||
|
mDebug("mnode index:%d ep:%s:%u, set inUse to %d", i, epSet->fqdn[i], htons(epSet->port[i]), epSet->inUse);
|
||||||
|
} else {
|
||||||
|
mDebug("mnode index:%d ep:%s:%u", i, epSet->fqdn[i], htons(epSet->port[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_RPC_REDIRECT;
|
return TSDB_CODE_RPC_REDIRECT;
|
||||||
|
|
|
@ -24,15 +24,9 @@
|
||||||
#include "mnode.h"
|
#include "mnode.h"
|
||||||
#include "mnodeDef.h"
|
#include "mnodeDef.h"
|
||||||
#include "mnodeInt.h"
|
#include "mnodeInt.h"
|
||||||
#include "mnodeAcct.h"
|
|
||||||
#include "mnodeDnode.h"
|
|
||||||
#include "mnodeDb.h"
|
|
||||||
#include "mnodeMnode.h"
|
|
||||||
#include "mnodeProfile.h"
|
#include "mnodeProfile.h"
|
||||||
#include "mnodeShow.h"
|
#include "mnodeShow.h"
|
||||||
#include "mnodeTable.h"
|
|
||||||
#include "mnodeUser.h"
|
#include "mnodeUser.h"
|
||||||
#include "mnodeVgroup.h"
|
|
||||||
#include "mnodeWrite.h"
|
#include "mnodeWrite.h"
|
||||||
|
|
||||||
#define CONN_KEEP_TIME (tsShellActivityTimer * 3)
|
#define CONN_KEEP_TIME (tsShellActivityTimer * 3)
|
||||||
|
@ -78,7 +72,7 @@ void mnodeCleanupProfile() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
|
SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port, int32_t pid, const char* app) {
|
||||||
#if 0
|
#if 0
|
||||||
int32_t connSize = taosHashGetSize(tsMnodeConnCache->pHashTable);
|
int32_t connSize = taosHashGetSize(tsMnodeConnCache->pHashTable);
|
||||||
if (connSize > tsMaxShellConns) {
|
if (connSize > tsMaxShellConns) {
|
||||||
|
@ -96,10 +90,13 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
|
||||||
.ip = ip,
|
.ip = ip,
|
||||||
.port = port,
|
.port = port,
|
||||||
.connId = connId,
|
.connId = connId,
|
||||||
.stime = taosGetTimestampMs()
|
.stime = taosGetTimestampMs(),
|
||||||
|
.pid = pid,
|
||||||
};
|
};
|
||||||
|
|
||||||
tstrncpy(connObj.user, user, sizeof(connObj.user));
|
tstrncpy(connObj.user, user, tListLen(connObj.user));
|
||||||
|
tstrncpy(connObj.appName, app, tListLen(connObj.appName));
|
||||||
|
|
||||||
connObj.lastAccess = connObj.stime;
|
connObj.lastAccess = connObj.stime;
|
||||||
|
|
||||||
SConnObj *pConn = taosCachePut(tsMnodeConnCache, &connId, sizeof(int32_t), &connObj, sizeof(connObj), CONN_KEEP_TIME * 1000);
|
SConnObj *pConn = taosCachePut(tsMnodeConnCache, &connId, sizeof(int32_t), &connObj, sizeof(connObj), CONN_KEEP_TIME * 1000);
|
||||||
|
@ -183,6 +180,20 @@ static int32_t mnodeGetConnsMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
|
// app name
|
||||||
|
pShow->bytes[cols] = TSDB_APPNAME_LEN + VARSTR_HEADER_SIZE;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
strcpy(pSchema[cols].name, "app_name");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
// app pid
|
||||||
|
pShow->bytes[cols] = 4;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||||
|
strcpy(pSchema[cols].name, "pid");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
pShow->bytes[cols] = TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE;
|
pShow->bytes[cols] = TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
strcpy(pSchema[cols].name, "ip:port");
|
strcpy(pSchema[cols].name, "ip:port");
|
||||||
|
@ -191,13 +202,13 @@ static int32_t mnodeGetConnsMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
|
|
||||||
pShow->bytes[cols] = 8;
|
pShow->bytes[cols] = 8;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
strcpy(pSchema[cols].name, "login time");
|
strcpy(pSchema[cols].name, "login_time");
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pShow->bytes[cols] = 8;
|
pShow->bytes[cols] = 8;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
strcpy(pSchema[cols].name, "last access");
|
strcpy(pSchema[cols].name, "last_access");
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
|
@ -236,6 +247,16 @@ static int32_t mnodeRetrieveConns(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->user, pShow->bytes[cols]);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->user, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
|
// app name
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->appName, pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
// app pid
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
*(int32_t*)pWrite = pConnObj->pid;
|
||||||
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, pShow->bytes[cols]);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, pShow->bytes[cols]);
|
||||||
|
@ -254,8 +275,7 @@ static int32_t mnodeRetrieveConns(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
}
|
}
|
||||||
|
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
const int32_t NUM_OF_COLUMNS = 5;
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
mnodeVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
|
|
||||||
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
@ -299,7 +319,7 @@ static int32_t mnodeGetQueryMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
|
|
||||||
pShow->bytes[cols] = QUERY_ID_SIZE + VARSTR_HEADER_SIZE;
|
pShow->bytes[cols] = QUERY_ID_SIZE + VARSTR_HEADER_SIZE;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
strcpy(pSchema[cols].name, "queryId");
|
strcpy(pSchema[cols].name, "query_id");
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
|
@ -315,9 +335,15 @@ static int32_t mnodeGetQueryMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = 24;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
strcpy(pSchema[cols].name, "qhandle");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
pShow->bytes[cols] = 8;
|
pShow->bytes[cols] = 8;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
strcpy(pSchema[cols].name, "created time");
|
strcpy(pSchema[cols].name, "created_time");
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
|
@ -352,7 +378,7 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
SConnObj *pConnObj = NULL;
|
SConnObj *pConnObj = NULL;
|
||||||
int32_t cols = 0;
|
int32_t cols = 0;
|
||||||
char * pWrite;
|
char * pWrite;
|
||||||
char ipStr[TSDB_IPv4ADDR_LEN + 6];
|
char str[TSDB_IPv4ADDR_LEN + 6] = {0};
|
||||||
|
|
||||||
while (numOfRows < rows) {
|
while (numOfRows < rows) {
|
||||||
pShow->pIter = mnodeGetNextConn(pShow->pIter, &pConnObj);
|
pShow->pIter = mnodeGetNextConn(pShow->pIter, &pConnObj);
|
||||||
|
@ -362,9 +388,9 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
SQueryDesc *pDesc = pConnObj->pQueries + i;
|
SQueryDesc *pDesc = pConnObj->pQueries + i;
|
||||||
cols = 0;
|
cols = 0;
|
||||||
|
|
||||||
snprintf(ipStr, QUERY_ID_SIZE + 1, "%u:%u", pConnObj->connId, htonl(pDesc->queryId));
|
snprintf(str, QUERY_ID_SIZE + 1, "%u:%u", pConnObj->connId, htonl(pDesc->queryId));
|
||||||
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, ipStr, pShow->bytes[cols]);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, str, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
@ -372,8 +398,15 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
snprintf(str, tListLen(str), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, pShow->bytes[cols]);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, str, pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
char handleBuf[24] = {0};
|
||||||
|
snprintf(handleBuf, tListLen(handleBuf), "%p", (void*)htobe64(pDesc->qHandle));
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
||||||
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, handleBuf, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
@ -393,8 +426,7 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
}
|
}
|
||||||
|
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
const int32_t NUM_OF_COLUMNS = 6;
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
mnodeVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,8 +554,7 @@ static int32_t mnodeRetrieveStreams(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
}
|
}
|
||||||
|
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
const int32_t NUM_OF_COLUMNS = 8;
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
mnodeVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,14 +51,21 @@ int32_t mnodeProcessRead(SMnodeMsg *pMsg) {
|
||||||
SMnodeRsp *rpcRsp = &pMsg->rpcRsp;
|
SMnodeRsp *rpcRsp = &pMsg->rpcRsp;
|
||||||
SRpcEpSet *epSet = rpcMallocCont(sizeof(SRpcEpSet));
|
SRpcEpSet *epSet = rpcMallocCont(sizeof(SRpcEpSet));
|
||||||
mnodeGetMnodeEpSetForShell(epSet);
|
mnodeGetMnodeEpSetForShell(epSet);
|
||||||
|
|
||||||
|
mDebug("%p, msg:%s in mread queue will be redirected, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle,
|
||||||
|
taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse);
|
||||||
|
for (int32_t i = 0; i < epSet->numOfEps; ++i) {
|
||||||
|
if (strcmp(epSet->fqdn[i], tsLocalFqdn) == 0 && htons(epSet->port[i]) == tsServerPort) {
|
||||||
|
epSet->inUse = (i + 1) % epSet->numOfEps;
|
||||||
|
mDebug("mnode index:%d ep:%s:%u, set inUse to %d", i, epSet->fqdn[i], htons(epSet->port[i]), epSet->inUse);
|
||||||
|
} else {
|
||||||
|
mDebug("mnode index:%d ep:%s:%u", i, epSet->fqdn[i], htons(epSet->port[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rpcRsp->rsp = epSet;
|
rpcRsp->rsp = epSet;
|
||||||
rpcRsp->len = sizeof(SRpcEpSet);
|
rpcRsp->len = sizeof(SRpcEpSet);
|
||||||
|
|
||||||
mDebug("%p, msg:%s in mread queue, will be redireced, inUse:%d", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], epSet->inUse);
|
|
||||||
for (int32_t i = 0; i < epSet->numOfEps; ++i) {
|
|
||||||
mDebug("mnode index:%d ep:%s:%d", i, epSet->fqdn[i], htons(epSet->port[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_RPC_REDIRECT;
|
return TSDB_CODE_RPC_REDIRECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,31 +298,25 @@ static void sdbConfirmForward(void *ahandle, void *param, int32_t code) {
|
||||||
taosFreeQitem(pOper);
|
taosFreeQitem(pOper);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdbUpdateSyncTmrFp(void *param, void *tmrId) { sdbUpdateSync(); }
|
static void sdbUpdateSyncTmrFp(void *param, void *tmrId) { sdbUpdateSync(NULL); }
|
||||||
|
|
||||||
void sdbUpdateSync() {
|
void sdbUpdateAsync() {
|
||||||
|
taosTmrReset(sdbUpdateSyncTmrFp, 200, NULL, tsMnodeTmr, &tsUpdateSyncTmr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sdbUpdateSync(void *pMnodes) {
|
||||||
|
SDMMnodeInfos *mnodes = pMnodes;
|
||||||
if (!mnodeIsRunning()) {
|
if (!mnodeIsRunning()) {
|
||||||
mDebug("mnode not start yet, update sync info later");
|
mDebug("mnode not start yet, update sync config later");
|
||||||
if (dnodeCheckMnodeStarting()) {
|
|
||||||
taosTmrReset(sdbUpdateSyncTmrFp, 1000, NULL, tsMnodeTmr, &tsUpdateSyncTmr);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mDebug("update sync info in sdb");
|
|
||||||
|
mDebug("update sync config in sync module, mnodes:%p", pMnodes);
|
||||||
|
|
||||||
SSyncCfg syncCfg = {0};
|
SSyncCfg syncCfg = {0};
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
|
|
||||||
SDMMnodeInfos *mnodes = dnodeGetMnodeInfos();
|
if (mnodes == NULL) {
|
||||||
for (int32_t i = 0; i < mnodes->nodeNum; ++i) {
|
|
||||||
SDMMnodeInfo *node = &mnodes->nodeInfos[i];
|
|
||||||
syncCfg.nodeInfo[i].nodeId = node->nodeId;
|
|
||||||
taosGetFqdnPortFromEp(node->nodeEp, syncCfg.nodeInfo[i].nodeFqdn, &syncCfg.nodeInfo[i].nodePort);
|
|
||||||
syncCfg.nodeInfo[i].nodePort += TSDB_PORT_SYNC;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == 0) {
|
|
||||||
void *pIter = NULL;
|
void *pIter = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
SMnodeObj *pMnode = NULL;
|
SMnodeObj *pMnode = NULL;
|
||||||
|
@ -342,9 +336,19 @@ void sdbUpdateSync() {
|
||||||
mnodeDecMnodeRef(pMnode);
|
mnodeDecMnodeRef(pMnode);
|
||||||
}
|
}
|
||||||
sdbFreeIter(pIter);
|
sdbFreeIter(pIter);
|
||||||
|
syncCfg.replica = index;
|
||||||
|
mDebug("mnodes info not input, use infos in sdb, numOfMnodes:%d", syncCfg.replica);
|
||||||
|
} else {
|
||||||
|
for (index = 0; index < mnodes->nodeNum; ++index) {
|
||||||
|
SDMMnodeInfo *node = &mnodes->nodeInfos[index];
|
||||||
|
syncCfg.nodeInfo[index].nodeId = node->nodeId;
|
||||||
|
taosGetFqdnPortFromEp(node->nodeEp, syncCfg.nodeInfo[index].nodeFqdn, &syncCfg.nodeInfo[index].nodePort);
|
||||||
|
syncCfg.nodeInfo[index].nodePort += TSDB_PORT_SYNC;
|
||||||
|
}
|
||||||
|
syncCfg.replica = index;
|
||||||
|
mDebug("mnodes info input, numOfMnodes:%d", syncCfg.replica);
|
||||||
}
|
}
|
||||||
|
|
||||||
syncCfg.replica = index;
|
|
||||||
syncCfg.quorum = (syncCfg.replica == 1) ? 1 : 2;
|
syncCfg.quorum = (syncCfg.replica == 1) ? 1 : 2;
|
||||||
|
|
||||||
bool hasThisDnode = false;
|
bool hasThisDnode = false;
|
||||||
|
@ -355,8 +359,15 @@ void sdbUpdateSync() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasThisDnode) return;
|
if (!hasThisDnode) {
|
||||||
if (memcmp(&syncCfg, &tsSdbObj.cfg, sizeof(SSyncCfg)) == 0) return;
|
sdbDebug("update sync config, this dnode not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(&syncCfg, &tsSdbObj.cfg, sizeof(SSyncCfg)) == 0) {
|
||||||
|
sdbDebug("update sync config, info not changed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sdbInfo("work as mnode, replica:%d", syncCfg.replica);
|
sdbInfo("work as mnode, replica:%d", syncCfg.replica);
|
||||||
for (int32_t i = 0; i < syncCfg.replica; ++i) {
|
for (int32_t i = 0; i < syncCfg.replica; ++i) {
|
||||||
|
@ -583,7 +594,7 @@ static int sdbWrite(void *param, void *data, int type) {
|
||||||
pthread_mutex_unlock(&tsSdbObj.mutex);
|
pthread_mutex_unlock(&tsSdbObj.mutex);
|
||||||
sdbError("table:%s, failed to restore %s record:%s from source(%d), ver:%" PRId64 " too large, sdb ver:%" PRId64,
|
sdbError("table:%s, failed to restore %s record:%s from source(%d), ver:%" PRId64 " too large, sdb ver:%" PRId64,
|
||||||
pTable->tableName, sdbGetActionStr(action), sdbGetKeyStr(pTable, pHead->cont), type, pHead->version, tsSdbObj.version);
|
pTable->tableName, sdbGetActionStr(action), sdbGetKeyStr(pTable, pHead->cont), type, pHead->version, tsSdbObj.version);
|
||||||
return TSDB_CODE_MND_APP_ERROR;
|
return TSDB_CODE_SYN_INVALID_VERSION;
|
||||||
} else {
|
} else {
|
||||||
tsSdbObj.version = pHead->version;
|
tsSdbObj.version = pHead->version;
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1054,7 @@ static void *sdbWorkerFp(void *param) {
|
||||||
while (1) {
|
while (1) {
|
||||||
numOfMsgs = taosReadAllQitemsFromQset(tsSdbWriteQset, tsSdbWriteQall, &unUsed);
|
numOfMsgs = taosReadAllQitemsFromQset(tsSdbWriteQset, tsSdbWriteQall, &unUsed);
|
||||||
if (numOfMsgs == 0) {
|
if (numOfMsgs == 0) {
|
||||||
sdbDebug("sdbWorkerFp: got no message from qset, exiting...");
|
sdbDebug("qset:%p, sdb got no message from qset, exiting", tsSdbWriteQset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ static int32_t mnodeProcessRetrieveMsg(SMnodeMsg *pMsg) {
|
||||||
rowsToRead = pShow->numOfRows - pShow->numOfReads;
|
rowsToRead = pShow->numOfRows - pShow->numOfReads;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return no more than 100 meters in one round trip */
|
/* return no more than 100 tables in one round trip */
|
||||||
if (rowsToRead > 100) rowsToRead = 100;
|
if (rowsToRead > 100) rowsToRead = 100;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -244,7 +244,8 @@ static int32_t mnodeProcessHeartBeatMsg(SMnodeMsg *pMsg) {
|
||||||
int32_t connId = htonl(pHBMsg->connId);
|
int32_t connId = htonl(pHBMsg->connId);
|
||||||
SConnObj *pConn = mnodeAccquireConn(connId, connInfo.user, connInfo.clientIp, connInfo.clientPort);
|
SConnObj *pConn = mnodeAccquireConn(connId, connInfo.user, connInfo.clientIp, connInfo.clientPort);
|
||||||
if (pConn == NULL) {
|
if (pConn == NULL) {
|
||||||
pConn = mnodeCreateConn(connInfo.user, connInfo.clientIp, connInfo.clientPort);
|
pHBMsg->pid = htonl(pHBMsg->pid);
|
||||||
|
pConn = mnodeCreateConn(connInfo.user, connInfo.clientIp, connInfo.clientPort, pHBMsg->pid, pHBMsg->appName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pConn == NULL) {
|
if (pConn == NULL) {
|
||||||
|
@ -325,7 +326,8 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
|
||||||
goto connect_over;
|
goto connect_over;
|
||||||
}
|
}
|
||||||
|
|
||||||
SConnObj *pConn = mnodeCreateConn(connInfo.user, connInfo.clientIp, connInfo.clientPort);
|
pConnectMsg->pid = htonl(pConnectMsg->pid);
|
||||||
|
SConnObj *pConn = mnodeCreateConn(connInfo.user, connInfo.clientIp, connInfo.clientPort, pConnectMsg->pid, pConnectMsg->appName);
|
||||||
if (pConn == NULL) {
|
if (pConn == NULL) {
|
||||||
code = terrno;
|
code = terrno;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -63,27 +63,27 @@ static int32_t mnodeRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t
|
||||||
static int32_t mnodeGetStreamTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
static int32_t mnodeGetStreamTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||||
static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||||
|
|
||||||
static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *mnodeMsg);
|
static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg);
|
static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeProcessCreateChildTableMsg(SMnodeMsg *pMsg);
|
static int32_t mnodeProcessCreateChildTableMsg(SMnodeMsg *pMsg);
|
||||||
static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg);
|
static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg);
|
||||||
|
|
||||||
static int32_t mnodeProcessDropTableMsg(SMnodeMsg *mnodeMsg);
|
static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg);
|
static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg);
|
||||||
static void mnodeProcessDropSuperTableRsp(SRpcMsg *rpcMsg);
|
static void mnodeProcessDropSuperTableRsp(SRpcMsg *rpcMsg);
|
||||||
static int32_t mnodeProcessDropChildTableMsg(SMnodeMsg *pMsg);
|
static int32_t mnodeProcessDropChildTableMsg(SMnodeMsg *pMsg);
|
||||||
static void mnodeProcessDropChildTableRsp(SRpcMsg *rpcMsg);
|
static void mnodeProcessDropChildTableRsp(SRpcMsg *rpcMsg);
|
||||||
|
|
||||||
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *mnodeMsg);
|
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *mnodeMsg);
|
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeProcessTableCfgMsg(SMnodeMsg *mnodeMsg);
|
static int32_t mnodeProcessTableCfgMsg(SMnodeMsg *pMsg);
|
||||||
|
|
||||||
static int32_t mnodeProcessTableMetaMsg(SMnodeMsg *mnodeMsg);
|
static int32_t mnodeProcessTableMetaMsg(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg);
|
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeGetChildTableMeta(SMnodeMsg *pMsg);
|
static int32_t mnodeGetChildTableMeta(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeAutoCreateChildTable(SMnodeMsg *pMsg);
|
static int32_t mnodeAutoCreateChildTable(SMnodeMsg *pMsg);
|
||||||
|
|
||||||
static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *mnodeMsg);
|
static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg);
|
||||||
static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg);
|
static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg);
|
||||||
|
|
||||||
static int32_t mnodeFindSuperTableColumnIndex(SSuperTableObj *pStable, char *colName);
|
static int32_t mnodeFindSuperTableColumnIndex(SSuperTableObj *pStable, char *colName);
|
||||||
|
@ -131,6 +131,8 @@ static int32_t mnodeChildTableActionInsert(SSdbOper *pOper) {
|
||||||
mnodeAddTableIntoStable(pTable->superTable, pTable);
|
mnodeAddTableIntoStable(pTable->superTable, pTable);
|
||||||
grantAdd(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1);
|
grantAdd(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1);
|
||||||
if (pAcct) pAcct->acctInfo.numOfTimeSeries += (pTable->superTable->numOfColumns - 1);
|
if (pAcct) pAcct->acctInfo.numOfTimeSeries += (pTable->superTable->numOfColumns - 1);
|
||||||
|
} else {
|
||||||
|
mError("table:%s:%p, correspond stable not found suid:%" PRIu64, pTable->info.tableId, pTable, pTable->suid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
grantAdd(TSDB_GRANT_TIMESERIES, pTable->numOfColumns - 1);
|
grantAdd(TSDB_GRANT_TIMESERIES, pTable->numOfColumns - 1);
|
||||||
|
@ -460,12 +462,14 @@ static int32_t mnodeSuperTableActionUpdate(SSdbOper *pOper) {
|
||||||
void *oldSchema = pTable->schema;
|
void *oldSchema = pTable->schema;
|
||||||
void *oldVgHash = pTable->vgHash;
|
void *oldVgHash = pTable->vgHash;
|
||||||
int32_t oldRefCount = pTable->refCount;
|
int32_t oldRefCount = pTable->refCount;
|
||||||
|
int32_t oldNumOfTables = pTable->numOfTables;
|
||||||
|
|
||||||
memcpy(pTable, pNew, sizeof(SSuperTableObj));
|
memcpy(pTable, pNew, sizeof(SSuperTableObj));
|
||||||
|
|
||||||
pTable->vgHash = oldVgHash;
|
pTable->vgHash = oldVgHash;
|
||||||
pTable->refCount = oldRefCount;
|
pTable->refCount = oldRefCount;
|
||||||
pTable->schema = pNew->schema;
|
pTable->schema = pNew->schema;
|
||||||
|
pTable->numOfTables = oldNumOfTables;
|
||||||
free(pNew);
|
free(pNew);
|
||||||
free(oldTableId);
|
free(oldTableId);
|
||||||
free(oldSchema);
|
free(oldSchema);
|
||||||
|
@ -837,10 +841,11 @@ static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) {
|
||||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t us = taosGetTimestampUs();
|
||||||
pStable->info.tableId = strdup(pCreate->tableId);
|
pStable->info.tableId = strdup(pCreate->tableId);
|
||||||
pStable->info.type = TSDB_SUPER_TABLE;
|
pStable->info.type = TSDB_SUPER_TABLE;
|
||||||
pStable->createdTime = taosGetTimestampMs();
|
pStable->createdTime = taosGetTimestampMs();
|
||||||
pStable->uid = (((uint64_t) pStable->createdTime) << 16) + (sdbGetVersion() & ((1ul << 16) - 1ul));
|
pStable->uid = (us << 24) + ((sdbGetVersion() & ((1ul << 16) - 1ul)) << 8) + (taosRand() & ((1ul << 8) - 1ul));
|
||||||
pStable->sversion = 0;
|
pStable->sversion = 0;
|
||||||
pStable->tversion = 0;
|
pStable->tversion = 0;
|
||||||
pStable->numOfColumns = htons(pCreate->numOfColumns);
|
pStable->numOfColumns = htons(pCreate->numOfColumns);
|
||||||
|
@ -1384,9 +1389,8 @@ int32_t mnodeRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows,
|
||||||
}
|
}
|
||||||
|
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
const int32_t NUM_OF_COLUMNS = 5;
|
|
||||||
|
|
||||||
mnodeVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
mnodeDecDbRef(pDb);
|
mnodeDecDbRef(pDb);
|
||||||
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
|
@ -1495,7 +1499,7 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (pTable->vgHash == NULL) {
|
if (pTable->vgHash == NULL) {
|
||||||
mError("app:%p:%p, stable:%s, no vgroup exist while get stable vgroup info", pMsg->rpcMsg.ahandle, pMsg,
|
mDebug("app:%p:%p, stable:%s, no vgroup exist while get stable vgroup info", pMsg->rpcMsg.ahandle, pMsg,
|
||||||
stableName);
|
stableName);
|
||||||
mnodeDecTableRef(pTable);
|
mnodeDecTableRef(pTable);
|
||||||
|
|
||||||
|
@ -1704,9 +1708,9 @@ static int32_t mnodeDoCreateChildTable(SMnodeMsg *pMsg, int32_t tid) {
|
||||||
pTable->createdTime = taosGetTimestampMs();
|
pTable->createdTime = taosGetTimestampMs();
|
||||||
pTable->sid = tid;
|
pTable->sid = tid;
|
||||||
pTable->vgId = pVgroup->vgId;
|
pTable->vgId = pVgroup->vgId;
|
||||||
|
|
||||||
if (pTable->info.type == TSDB_CHILD_TABLE) {
|
if (pTable->info.type == TSDB_CHILD_TABLE) {
|
||||||
STagData *pTagData = (STagData *) pCreate->schema; // it is a tag key
|
STagData *pTagData = (STagData *)pCreate->schema; // it is a tag key
|
||||||
if (pMsg->pSTable == NULL) pMsg->pSTable = mnodeGetSuperTable(pTagData->name);
|
if (pMsg->pSTable == NULL) pMsg->pSTable = mnodeGetSuperTable(pTagData->name);
|
||||||
if (pMsg->pSTable == NULL) {
|
if (pMsg->pSTable == NULL) {
|
||||||
mError("app:%p:%p, table:%s, corresponding super table:%s does not exist", pMsg->rpcMsg.ahandle, pMsg,
|
mError("app:%p:%p, table:%s, corresponding super table:%s does not exist", pMsg->rpcMsg.ahandle, pMsg,
|
||||||
|
@ -2251,7 +2255,8 @@ static void mnodeDropAllChildTablesInStable(SSuperTableObj *pStable) {
|
||||||
int32_t numOfTables = 0;
|
int32_t numOfTables = 0;
|
||||||
SChildTableObj *pTable = NULL;
|
SChildTableObj *pTable = NULL;
|
||||||
|
|
||||||
mInfo("stable:%s, all child tables:%d will dropped from sdb", pStable->info.tableId, pStable->numOfTables);
|
mInfo("stable:%s uid:%" PRIu64 ", all child tables:%d will be dropped from sdb", pStable->info.tableId, pStable->uid,
|
||||||
|
pStable->numOfTables);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
pIter = mnodeGetNextChildTable(pIter, &pTable);
|
pIter = mnodeGetNextChildTable(pIter, &pTable);
|
||||||
|
@ -2404,14 +2409,16 @@ static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mnodeMsg->retry++ < 10) {
|
if (mnodeMsg->retry++ < 10) {
|
||||||
mDebug("app:%p:%p, table:%s, create table rsp received, need retry, times:%d result:%s thandle:%p",
|
mDebug("app:%p:%p, table:%s, create table rsp received, need retry, times:%d vgId:%d sid:%d uid:%" PRIu64
|
||||||
mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, mnodeMsg->retry, tstrerror(rpcMsg->code),
|
" result:%s thandle:%p",
|
||||||
mnodeMsg->rpcMsg.handle);
|
mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, mnodeMsg->retry, pTable->vgId, pTable->sid,
|
||||||
|
pTable->uid, tstrerror(rpcMsg->code), mnodeMsg->rpcMsg.handle);
|
||||||
|
|
||||||
dnodeDelayReprocessMnodeWriteMsg(mnodeMsg);
|
dnodeDelayReprocessMnodeWriteMsg(mnodeMsg);
|
||||||
} else {
|
} else {
|
||||||
mError("app:%p:%p, table:%s, failed to create in dnode, result:%s thandle:%p", mnodeMsg->rpcMsg.ahandle, mnodeMsg,
|
mError("app:%p:%p, table:%s, failed to create in dnode, vgId:%d sid:%d uid:%" PRIu64 ", result:%s thandle:%p",
|
||||||
pTable->info.tableId, tstrerror(rpcMsg->code), mnodeMsg->rpcMsg.handle);
|
mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, pTable->vgId, pTable->sid, pTable->uid,
|
||||||
|
tstrerror(rpcMsg->code), mnodeMsg->rpcMsg.handle);
|
||||||
|
|
||||||
SSdbOper oper = {.type = SDB_OPER_GLOBAL, .table = tsChildTableSdb, .pObj = pTable};
|
SSdbOper oper = {.type = SDB_OPER_GLOBAL, .table = tsChildTableSdb, .pObj = pTable};
|
||||||
sdbDeleteRow(&oper);
|
sdbDeleteRow(&oper);
|
||||||
|
@ -2543,6 +2550,25 @@ static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = 8; // table uid
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_BIGINT;
|
||||||
|
strcpy(pSchema[cols].name, "uid");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = 4;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||||
|
strcpy(pSchema[cols].name, "tid");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = 4;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||||
|
strcpy(pSchema[cols].name, "vgId");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
|
||||||
pMeta->numOfColumns = htons(cols);
|
pMeta->numOfColumns = htons(cols);
|
||||||
pShow->numOfColumns = cols;
|
pShow->numOfColumns = cols;
|
||||||
|
|
||||||
|
@ -2568,6 +2594,7 @@ static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t cols = 0;
|
||||||
int32_t numOfRows = 0;
|
int32_t numOfRows = 0;
|
||||||
SChildTableObj *pTable = NULL;
|
SChildTableObj *pTable = NULL;
|
||||||
SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER;
|
SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER;
|
||||||
|
@ -2608,8 +2635,7 @@ static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t cols = 0;
|
cols = 0;
|
||||||
|
|
||||||
char *pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
char *pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, tableName, pShow->bytes[cols]);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, tableName, pShow->bytes[cols]);
|
||||||
|
@ -2638,14 +2664,29 @@ static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows
|
||||||
|
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
|
// uid
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
*(int64_t*) pWrite = pTable->uid;
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
|
||||||
|
// tid
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
*(int32_t*) pWrite = pTable->sid;
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
//vgid
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
*(int32_t*) pWrite = pTable->vgId;
|
||||||
|
cols++;
|
||||||
|
|
||||||
numOfRows++;
|
numOfRows++;
|
||||||
mnodeDecTableRef(pTable);
|
mnodeDecTableRef(pTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
const int32_t NUM_OF_COLUMNS = 4;
|
|
||||||
|
|
||||||
mnodeVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
mnodeDecDbRef(pDb);
|
mnodeDecDbRef(pDb);
|
||||||
free(pattern);
|
free(pattern);
|
||||||
|
|
||||||
|
@ -2843,9 +2884,8 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro
|
||||||
}
|
}
|
||||||
|
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
const int32_t NUM_OF_COLUMNS = 4;
|
|
||||||
|
|
||||||
mnodeVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
mnodeDecDbRef(pDb);
|
mnodeDecDbRef(pDb);
|
||||||
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
|
|
|
@ -386,6 +386,7 @@ static int32_t mnodeRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
mnodeDecUserRef(pUser);
|
mnodeDecUserRef(pUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,31 +270,34 @@ void mnodeUpdateVgroup(SVgObj *pVgroup) {
|
||||||
Traverse all vgroups on mnode, if there no such vgId on a dnode, so send msg to this dnode for re-creating this vgId/vnode
|
Traverse all vgroups on mnode, if there no such vgId on a dnode, so send msg to this dnode for re-creating this vgId/vnode
|
||||||
*/
|
*/
|
||||||
void mnodeCheckUnCreatedVgroup(SDnodeObj *pDnode, SVnodeLoad *pVloads, int32_t openVnodes) {
|
void mnodeCheckUnCreatedVgroup(SDnodeObj *pDnode, SVnodeLoad *pVloads, int32_t openVnodes) {
|
||||||
SVnodeLoad *pNextV = NULL;
|
|
||||||
|
|
||||||
void *pIter = NULL;
|
void *pIter = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
SVgObj *pVgroup;
|
SVgObj *pVgroup;
|
||||||
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
||||||
if (pVgroup == NULL) break;
|
if (pVgroup == NULL) break;
|
||||||
|
|
||||||
pNextV = pVloads;
|
for (int v = 0; v < pVgroup->numOfVnodes; ++v) {
|
||||||
int32_t i;
|
if (pVgroup->vnodeGid[v].dnodeId == pDnode->dnodeId) {
|
||||||
for (i = 0; i < openVnodes; ++i) {
|
// vgroup should have a vnode on this dnode
|
||||||
if ((pVgroup->vnodeGid[i].pDnode == pDnode) && (pVgroup->vgId == pNextV->vgId)) {
|
bool have = false;
|
||||||
break;
|
for (int32_t i = 0; i < openVnodes; ++i) {
|
||||||
}
|
SVnodeLoad *pVload = pVloads + i;
|
||||||
pNextV++;
|
if (pVgroup->vgId == pVload->vgId) {
|
||||||
}
|
have = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (i == openVnodes) {
|
if (have) continue;
|
||||||
if (pVgroup->status == TAOS_VG_STATUS_CREATING || pVgroup->status == TAOS_VG_STATUS_DROPPING) {
|
|
||||||
mDebug("vgId:%d, not exist in dnode:%d and status is %s, do nothing", pVgroup->vgId, pDnode->dnodeId,
|
if (pVgroup->status == TAOS_VG_STATUS_CREATING || pVgroup->status == TAOS_VG_STATUS_DROPPING) {
|
||||||
vgroupStatus[pVgroup->status]);
|
mDebug("vgId:%d, not exist in dnode:%d and status is %s, do nothing", pVgroup->vgId, pDnode->dnodeId,
|
||||||
} else {
|
vgroupStatus[pVgroup->status]);
|
||||||
mDebug("vgId:%d, not exist in dnode:%d and status is %s, send create msg", pVgroup->vgId, pDnode->dnodeId,
|
} else {
|
||||||
vgroupStatus[pVgroup->status]);
|
mDebug("vgId:%d, not exist in dnode:%d and status is %s, send create msg", pVgroup->vgId, pDnode->dnodeId,
|
||||||
mnodeSendCreateVgroupMsg(pVgroup, NULL);
|
vgroupStatus[pVgroup->status]);
|
||||||
|
mnodeSendCreateVgroupMsg(pVgroup, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +305,6 @@ void mnodeCheckUnCreatedVgroup(SDnodeObj *pDnode, SVnodeLoad *pVloads, int32_t o
|
||||||
}
|
}
|
||||||
|
|
||||||
sdbFreeIter(pIter);
|
sdbFreeIter(pIter);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVload) {
|
void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVload) {
|
||||||
|
@ -310,7 +312,7 @@ void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVl
|
||||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||||
SVnodeGid *pVgid = &pVgroup->vnodeGid[i];
|
SVnodeGid *pVgid = &pVgroup->vnodeGid[i];
|
||||||
if (pVgid->pDnode == pDnode) {
|
if (pVgid->pDnode == pDnode) {
|
||||||
mTrace("dnode:%d, receive status from dnode, vgId:%d status is %d", pDnode->dnodeId, pVgroup->vgId, pVgid->role);
|
mTrace("dnode:%d, receive status from dnode, vgId:%d status is %d:%s", pDnode->dnodeId, pVgroup->vgId, pVgid->role, syncRole[pVgid->role]);
|
||||||
pVgid->role = pVload->role;
|
pVgid->role = pVload->role;
|
||||||
if (pVload->role == TAOS_SYNC_ROLE_MASTER) {
|
if (pVload->role == TAOS_SYNC_ROLE_MASTER) {
|
||||||
pVgroup->inUse = i;
|
pVgroup->inUse = i;
|
||||||
|
@ -723,8 +725,16 @@ static int32_t mnodeRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
while (numOfRows < rows) {
|
while (numOfRows < rows) {
|
||||||
pShow->pIter = mnodeGetNextVgroup(pShow->pIter, &pVgroup);
|
pShow->pIter = mnodeGetNextVgroup(pShow->pIter, &pVgroup);
|
||||||
if (pVgroup == NULL) break;
|
if (pVgroup == NULL) break;
|
||||||
if (pVgroup->pDb != pDb) continue;
|
|
||||||
if (!mnodeFilterVgroups(pVgroup, pTable)) continue;
|
if (pVgroup->pDb != pDb) {
|
||||||
|
mnodeDecVgroupRef(pVgroup);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mnodeFilterVgroups(pVgroup, pTable)) {
|
||||||
|
mnodeDecVgroupRef(pVgroup);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
cols = 0;
|
cols = 0;
|
||||||
|
|
||||||
|
@ -772,6 +782,8 @@ static int32_t mnodeRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
numOfRows++;
|
numOfRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
|
|
||||||
pShow->numOfReads += numOfRows;
|
pShow->numOfReads += numOfRows;
|
||||||
mnodeDecTableRef(pTable);
|
mnodeDecTableRef(pTable);
|
||||||
mnodeDecDbRef(pDb);
|
mnodeDecDbRef(pDb);
|
||||||
|
|
|
@ -54,11 +54,17 @@ int32_t mnodeProcessWrite(SMnodeMsg *pMsg) {
|
||||||
rpcRsp->rsp = epSet;
|
rpcRsp->rsp = epSet;
|
||||||
rpcRsp->len = sizeof(SRpcEpSet);
|
rpcRsp->len = sizeof(SRpcEpSet);
|
||||||
|
|
||||||
mDebug("app:%p:%p, msg:%s will be redireced inUse:%d", pMsg->rpcMsg.ahandle, pMsg, taosMsg[pMsg->rpcMsg.msgType],
|
mDebug("app:%p:%p, msg:%s in write queue, will be redirected, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle, pMsg,
|
||||||
epSet->inUse);
|
taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse);
|
||||||
for (int32_t i = 0; i < epSet->numOfEps; ++i) {
|
for (int32_t i = 0; i < epSet->numOfEps; ++i) {
|
||||||
mDebug("app:%p:%p, mnode index:%d ep:%s:%d", pMsg->rpcMsg.ahandle, pMsg, i, epSet->fqdn[i],
|
if (strcmp(epSet->fqdn[i], tsLocalFqdn) == 0 && htons(epSet->port[i]) == tsServerPort) {
|
||||||
htons(epSet->port[i]));
|
epSet->inUse = (i + 1) % epSet->numOfEps;
|
||||||
|
mDebug("app:%p:%p, mnode index:%d ep:%s:%d, set inUse to %d", pMsg->rpcMsg.ahandle, pMsg, i, epSet->fqdn[i],
|
||||||
|
htons(epSet->port[i]), epSet->inUse);
|
||||||
|
} else {
|
||||||
|
mDebug("app:%p:%p, mnode index:%d ep:%s:%d", pMsg->rpcMsg.ahandle, pMsg, i, epSet->fqdn[i],
|
||||||
|
htons(epSet->port[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_RPC_REDIRECT;
|
return TSDB_CODE_RPC_REDIRECT;
|
||||||
|
|
|
@ -33,6 +33,8 @@ bool taosCheckPthreadValid(pthread_t thread);
|
||||||
int64_t taosGetPthreadId();
|
int64_t taosGetPthreadId();
|
||||||
void taosResetPthread(pthread_t *thread);
|
void taosResetPthread(pthread_t *thread);
|
||||||
bool taosComparePthread(pthread_t first, pthread_t second);
|
bool taosComparePthread(pthread_t first, pthread_t second);
|
||||||
|
int32_t taosGetPId();
|
||||||
|
int32_t taosGetCurrentAPPName(char *name, int32_t* len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,5 +34,31 @@ bool taosCheckPthreadValid(pthread_t thread) { return thread != 0; }
|
||||||
int64_t taosGetPthreadId() { return (int64_t)pthread_self(); }
|
int64_t taosGetPthreadId() { return (int64_t)pthread_self(); }
|
||||||
void taosResetPthread(pthread_t *thread) { *thread = 0; }
|
void taosResetPthread(pthread_t *thread) { *thread = 0; }
|
||||||
bool taosComparePthread(pthread_t first, pthread_t second) { return first == second; }
|
bool taosComparePthread(pthread_t first, pthread_t second) { return first == second; }
|
||||||
|
int32_t taosGetPId() { return getpid(); }
|
||||||
|
|
||||||
|
int32_t taosGetCurrentAPPName(char *name, int32_t* len) {
|
||||||
|
const char* self = "/proc/self/exe";
|
||||||
|
char path[PATH_MAX] = {0};
|
||||||
|
|
||||||
|
if (readlink(self, path, PATH_MAX) <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
path[PATH_MAX - 1] = 0;
|
||||||
|
char* end = strrchr(path, '/');
|
||||||
|
if (end == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
++end;
|
||||||
|
|
||||||
|
strcpy(name, end);
|
||||||
|
|
||||||
|
if (len != NULL) {
|
||||||
|
*len = strlen(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -203,7 +203,7 @@ static void taosGetSystemTimezone() {
|
||||||
snprintf(tsTimezone, TSDB_TIMEZONE_LEN, "%s (%s, %s%02d00)", buf, tzname[daylight], tz >= 0 ? "+" : "-", abs(tz));
|
snprintf(tsTimezone, TSDB_TIMEZONE_LEN, "%s (%s, %s%02d00)", buf, tzname[daylight], tz >= 0 ? "+" : "-", abs(tz));
|
||||||
|
|
||||||
// cfg_timezone->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT;
|
// cfg_timezone->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT;
|
||||||
uInfo("timezone not configured, set to system default:%s", tsTimezone);
|
uWarn("timezone not configured, set to system default:%s", tsTimezone);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -235,7 +235,7 @@ static void taosGetSystemLocale() { // get and set default locale
|
||||||
strcpy(tsLocale, "en_US.UTF-8");
|
strcpy(tsLocale, "en_US.UTF-8");
|
||||||
} else {
|
} else {
|
||||||
tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN);
|
tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN);
|
||||||
uError("locale not configured, set to system default:%s", tsLocale);
|
uWarn("locale not configured, set to system default:%s", tsLocale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,4 @@ PROJECT(TDengine)
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
|
|
||||||
ADD_LIBRARY(os ${SRC})
|
ADD_LIBRARY(os ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(os m rt)
|
TARGET_LINK_LIBRARIES(os m rt z)
|
||||||
|
|
|
@ -36,3 +36,21 @@ int64_t taosGetPthreadId() {
|
||||||
bool taosComparePthread(pthread_t first, pthread_t second) {
|
bool taosComparePthread(pthread_t first, pthread_t second) {
|
||||||
return first.p == second.p;
|
return first.p == second.p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t taosGetPId() {
|
||||||
|
return GetCurrentProcessId();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t taosGetCurrentAPPName(char *name, int32_t* len) {
|
||||||
|
char filepath[1024] = {0};
|
||||||
|
|
||||||
|
GetModuleFileName(NULL, filepath, MAX_PATH);
|
||||||
|
*strrchr(filepath,'.') = '\0';
|
||||||
|
strcpy(name, filepath);
|
||||||
|
|
||||||
|
if (len != NULL) {
|
||||||
|
*len = (int32_t) strlen(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -67,7 +67,7 @@ static void *httpProcessResultQueue(void *param) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (taosReadQitemFromQset(tsHttpQset, &type, (void **)&pMsg, &unUsed) == 0) {
|
if (taosReadQitemFromQset(tsHttpQset, &type, (void **)&pMsg, &unUsed) == 0) {
|
||||||
httpDebug("httpResultQueue: got no message from qset, exiting...");
|
httpDebug("qset:%p, http queue got no message from qset, exiting", tsHttpQset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4511,7 +4511,6 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
|
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
|
||||||
|
|
||||||
pQuery->precision = tsdbGetCfg(tsdb)->precision;
|
|
||||||
pRuntimeEnv->topBotQuery = isTopBottomQuery(pQuery);
|
pRuntimeEnv->topBotQuery = isTopBottomQuery(pQuery);
|
||||||
pRuntimeEnv->hasTagResults = hasTagValOutput(pQuery);
|
pRuntimeEnv->hasTagResults = hasTagValOutput(pQuery);
|
||||||
|
|
||||||
|
@ -6323,6 +6322,8 @@ static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQ
|
||||||
bool ret = tsBufNextPos(pTSBuf);
|
bool ret = tsBufNextPos(pTSBuf);
|
||||||
UNUSED(ret);
|
UNUSED(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pQuery->precision = tsdbGetCfg(tsdb)->precision;
|
||||||
|
|
||||||
if ((QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.skey > pQuery->window.ekey)) ||
|
if ((QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.skey > pQuery->window.ekey)) ||
|
||||||
(!QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.ekey > pQuery->window.skey))) {
|
(!QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.ekey > pQuery->window.skey))) {
|
||||||
|
|
|
@ -323,7 +323,7 @@ void *rpcMallocCont(int contLen) {
|
||||||
tError("failed to malloc msg, size:%d", size);
|
tError("failed to malloc msg, size:%d", size);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
tDebug("malloc msg: %p", start);
|
tTrace("malloc mem: %p", start);
|
||||||
}
|
}
|
||||||
|
|
||||||
return start + sizeof(SRpcReqContext) + sizeof(SRpcHead);
|
return start + sizeof(SRpcReqContext) + sizeof(SRpcHead);
|
||||||
|
@ -333,7 +333,7 @@ void rpcFreeCont(void *cont) {
|
||||||
if (cont) {
|
if (cont) {
|
||||||
char *temp = ((char *)cont) - sizeof(SRpcHead) - sizeof(SRpcReqContext);
|
char *temp = ((char *)cont) - sizeof(SRpcHead) - sizeof(SRpcReqContext);
|
||||||
free(temp);
|
free(temp);
|
||||||
tDebug("free mem: %p", temp);
|
tTrace("free mem: %p", temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,10 +542,7 @@ void rpcCancelRequest(void *handle) {
|
||||||
|
|
||||||
if (pContext->pConn) {
|
if (pContext->pConn) {
|
||||||
tDebug("%s, app tries to cancel request", pContext->pConn->info);
|
tDebug("%s, app tries to cancel request", pContext->pConn->info);
|
||||||
pContext->pConn->pReqMsg = NULL;
|
|
||||||
rpcCloseConn(pContext->pConn);
|
rpcCloseConn(pContext->pConn);
|
||||||
pContext->pConn = NULL;
|
|
||||||
rpcFreeCont(pContext->pCont);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,7 +550,7 @@ static void rpcFreeMsg(void *msg) {
|
||||||
if ( msg ) {
|
if ( msg ) {
|
||||||
char *temp = (char *)msg - sizeof(SRpcReqContext);
|
char *temp = (char *)msg - sizeof(SRpcReqContext);
|
||||||
free(temp);
|
free(temp);
|
||||||
tDebug("free msg: %p", temp);
|
tTrace("free mem: %p", temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,8 +610,10 @@ static void rpcReleaseConn(SRpcConn *pConn) {
|
||||||
if (pConn->pReqMsg) rpcFreeCont(pConn->pReqMsg); // do not use rpcFreeMsg
|
if (pConn->pReqMsg) rpcFreeCont(pConn->pReqMsg); // do not use rpcFreeMsg
|
||||||
} else {
|
} else {
|
||||||
// if there is an outgoing message, free it
|
// if there is an outgoing message, free it
|
||||||
if (pConn->outType && pConn->pReqMsg)
|
if (pConn->outType && pConn->pReqMsg) {
|
||||||
|
if (pConn->pContext) pConn->pContext->pConn = NULL;
|
||||||
rpcFreeMsg(pConn->pReqMsg);
|
rpcFreeMsg(pConn->pReqMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// memset could not be used, since lockeBy can not be reset
|
// memset could not be used, since lockeBy can not be reset
|
||||||
|
@ -819,9 +818,18 @@ static int rpcProcessReqHead(SRpcConn *pConn, SRpcHead *pHead) {
|
||||||
return TSDB_CODE_RPC_LAST_SESSION_NOT_FINISHED;
|
return TSDB_CODE_RPC_LAST_SESSION_NOT_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rpcContLenFromMsg(pHead->msgLen) <= 0) {
|
||||||
|
tDebug("%s, message body is empty, ignore", pConn->info);
|
||||||
|
return TSDB_CODE_RPC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
pConn->inTranId = pHead->tranId;
|
pConn->inTranId = pHead->tranId;
|
||||||
pConn->inType = pHead->msgType;
|
pConn->inType = pHead->msgType;
|
||||||
|
|
||||||
|
// start the progress timer to monitor the response from server app
|
||||||
|
if (pConn->connType != RPC_CONN_TCPS)
|
||||||
|
pConn->pTimer = taosTmrStart(rpcProcessProgressTimer, tsProgressTimer, pConn, pConn->pRpc->tmrCtrl);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,11 +968,7 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv, SRpcReqCont
|
||||||
pConn->pIdleTimer = taosTmrStart(rpcProcessIdleTimer, tsRpcTimer*2, pConn, pRpc->tmrCtrl);
|
pConn->pIdleTimer = taosTmrStart(rpcProcessIdleTimer, tsRpcTimer*2, pConn, pRpc->tmrCtrl);
|
||||||
} else {
|
} else {
|
||||||
terrno = rpcProcessRspHead(pConn, pHead);
|
terrno = rpcProcessRspHead(pConn, pHead);
|
||||||
if (terrno == 0) {
|
*ppContext = pConn->pContext;
|
||||||
SRpcReqContext *pContext = pConn->pContext;
|
|
||||||
*ppContext = pContext;
|
|
||||||
pConn->pContext = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1047,6 +1051,9 @@ static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) {
|
||||||
if (code != 0) { // parsing error
|
if (code != 0) { // parsing error
|
||||||
if (rpcIsReq(pHead->msgType)) {
|
if (rpcIsReq(pHead->msgType)) {
|
||||||
rpcSendErrorMsgToPeer(pRecv, code);
|
rpcSendErrorMsgToPeer(pRecv, code);
|
||||||
|
if (code == TSDB_CODE_RPC_INVALID_TIME_STAMP || code == TSDB_CODE_RPC_AUTH_FAILURE) {
|
||||||
|
rpcCloseConn(pConn);
|
||||||
|
}
|
||||||
tDebug("%s %p %p, %s is sent with error code:0x%x", pRpc->label, pConn, (void *)pHead->ahandle, taosMsg[pHead->msgType+1], code);
|
tDebug("%s %p %p, %s is sent with error code:0x%x", pRpc->label, pConn, (void *)pHead->ahandle, taosMsg[pHead->msgType+1], code);
|
||||||
}
|
}
|
||||||
} else { // msg is passed to app only parsing is ok
|
} else { // msg is passed to app only parsing is ok
|
||||||
|
@ -1094,20 +1101,11 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqConte
|
||||||
|
|
||||||
if ( rpcIsReq(pHead->msgType) ) {
|
if ( rpcIsReq(pHead->msgType) ) {
|
||||||
rpcMsg.ahandle = pConn->ahandle;
|
rpcMsg.ahandle = pConn->ahandle;
|
||||||
if (rpcMsg.contLen > 0) {
|
rpcMsg.handle = pConn;
|
||||||
rpcMsg.handle = pConn;
|
rpcAddRef(pRpc); // add the refCount for requests
|
||||||
rpcAddRef(pRpc); // add the refCount for requests
|
|
||||||
|
|
||||||
// start the progress timer to monitor the response from server app
|
// notify the server app
|
||||||
if (pConn->connType != RPC_CONN_TCPS)
|
(*(pRpc->cfp))(&rpcMsg, NULL);
|
||||||
pConn->pTimer = taosTmrStart(rpcProcessProgressTimer, tsProgressTimer, pConn, pRpc->tmrCtrl);
|
|
||||||
|
|
||||||
// notify the server app
|
|
||||||
(*(pRpc->cfp))(&rpcMsg, NULL);
|
|
||||||
} else {
|
|
||||||
tDebug("%s, message body is empty, ignore", pConn->info);
|
|
||||||
rpcFreeCont(rpcMsg.pCont);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// it's a response
|
// it's a response
|
||||||
rpcMsg.handle = pContext;
|
rpcMsg.handle = pContext;
|
||||||
|
@ -1125,9 +1123,13 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqConte
|
||||||
SRpcEpSet *pEpSet = (SRpcEpSet*)pHead->content;
|
SRpcEpSet *pEpSet = (SRpcEpSet*)pHead->content;
|
||||||
if (pEpSet->numOfEps > 0) {
|
if (pEpSet->numOfEps > 0) {
|
||||||
memcpy(&pContext->epSet, pHead->content, sizeof(pContext->epSet));
|
memcpy(&pContext->epSet, pHead->content, sizeof(pContext->epSet));
|
||||||
tDebug("%s, redirect is received, numOfEps:%d", pConn->info, pContext->epSet.numOfEps);
|
tDebug("%s, redirect is received, numOfEps:%d inUse:%d", pConn->info, pContext->epSet.numOfEps,
|
||||||
for (int i=0; i<pContext->epSet.numOfEps; ++i)
|
pContext->epSet.inUse);
|
||||||
|
for (int i = 0; i < pContext->epSet.numOfEps; ++i) {
|
||||||
pContext->epSet.port[i] = htons(pContext->epSet.port[i]);
|
pContext->epSet.port[i] = htons(pContext->epSet.port[i]);
|
||||||
|
tDebug("%s, redirect is received, index:%d ep:%s:%u", pConn->info, i, pContext->epSet.fqdn[i],
|
||||||
|
pContext->epSet.port[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rpcSendReqToServer(pRpc, pContext);
|
rpcSendReqToServer(pRpc, pContext);
|
||||||
rpcFreeCont(rpcMsg.pCont);
|
rpcFreeCont(rpcMsg.pCont);
|
||||||
|
@ -1451,7 +1453,7 @@ static SRpcHead *rpcDecompressRpcMsg(SRpcHead *pHead) {
|
||||||
pNewHead->msgLen = rpcMsgLenFromCont(origLen);
|
pNewHead->msgLen = rpcMsgLenFromCont(origLen);
|
||||||
rpcFreeMsg(pHead); // free the compressed message buffer
|
rpcFreeMsg(pHead); // free the compressed message buffer
|
||||||
pHead = pNewHead;
|
pHead = pNewHead;
|
||||||
//tTrace("decompress rpc msg, compLen:%d, after:%d", compLen, contLen);
|
tTrace("decomp malloc mem: %p", temp);
|
||||||
} else {
|
} else {
|
||||||
tError("failed to allocate memory to decompress msg, contLen:%d", contLen);
|
tError("failed to allocate memory to decompress msg, contLen:%d", contLen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -438,7 +438,7 @@ static int taosReadTcpData(SFdObj *pFdObj, SRecvInfo *pInfo) {
|
||||||
tError("%s %p TCP malloc(size:%d) fail", pThreadObj->label, pFdObj->thandle, msgLen);
|
tError("%s %p TCP malloc(size:%d) fail", pThreadObj->label, pFdObj->thandle, msgLen);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
tDebug("TCP malloc mem: %p", buffer);
|
tTrace("TCP malloc mem: %p", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = buffer + tsRpcOverhead;
|
msg = buffer + tsRpcOverhead;
|
||||||
|
@ -525,7 +525,7 @@ static void *taosProcessTcpData(void *param) {
|
||||||
while (pThreadObj->pHead) {
|
while (pThreadObj->pHead) {
|
||||||
SFdObj *pFdObj = pThreadObj->pHead;
|
SFdObj *pFdObj = pThreadObj->pHead;
|
||||||
pThreadObj->pHead = pFdObj->next;
|
pThreadObj->pHead = pFdObj->next;
|
||||||
taosFreeFdObj(pFdObj);
|
taosReportBrokenLink(pFdObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_destroy(&(pThreadObj->mutex));
|
pthread_mutex_destroy(&(pThreadObj->mutex));
|
||||||
|
|
|
@ -214,7 +214,7 @@ static void *taosRecvUdpData(void *param) {
|
||||||
tError("%s failed to allocate memory, size:%" PRId64, pConn->label, (int64_t)dataLen);
|
tError("%s failed to allocate memory, size:%" PRId64, pConn->label, (int64_t)dataLen);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
tDebug("UDP malloc mem: %p", tmsg);
|
tTrace("UDP malloc mem: %p", tmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmsg += tsRpcOverhead; // overhead for SRpcReqContext
|
tmsg += tsRpcOverhead; // overhead for SRpcReqContext
|
||||||
|
|
|
@ -215,6 +215,9 @@ void syncStop(void *param) {
|
||||||
|
|
||||||
pthread_mutex_lock(&(pNode->mutex));
|
pthread_mutex_lock(&(pNode->mutex));
|
||||||
|
|
||||||
|
if (vgIdHash) taosHashRemove(vgIdHash, (const char *)&pNode->vgId, sizeof(int32_t));
|
||||||
|
if (pNode->pFwdTimer) taosTmrStop(pNode->pFwdTimer);
|
||||||
|
|
||||||
for (int i = 0; i < pNode->replica; ++i) {
|
for (int i = 0; i < pNode->replica; ++i) {
|
||||||
pPeer = pNode->peerInfo[i];
|
pPeer = pNode->peerInfo[i];
|
||||||
if (pPeer) syncRemovePeer(pPeer);
|
if (pPeer) syncRemovePeer(pPeer);
|
||||||
|
@ -223,9 +226,6 @@ void syncStop(void *param) {
|
||||||
pPeer = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA];
|
pPeer = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA];
|
||||||
if (pPeer) syncRemovePeer(pPeer);
|
if (pPeer) syncRemovePeer(pPeer);
|
||||||
|
|
||||||
if (vgIdHash) taosHashRemove(vgIdHash, (const char *)&pNode->vgId, sizeof(int32_t));
|
|
||||||
if (pNode->pFwdTimer) taosTmrStop(pNode->pFwdTimer);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&(pNode->mutex));
|
pthread_mutex_unlock(&(pNode->mutex));
|
||||||
|
|
||||||
syncDecNodeRef(pNode);
|
syncDecNodeRef(pNode);
|
||||||
|
@ -311,8 +311,21 @@ int32_t syncForwardToPeer(void *param, void *data, void *mhandle, int qtype) {
|
||||||
|
|
||||||
if (pNode == NULL) return 0;
|
if (pNode == NULL) return 0;
|
||||||
|
|
||||||
|
if (nodeRole == TAOS_SYNC_ROLE_SLAVE && pWalHead->version != nodeVersion + 1) {
|
||||||
|
sError("vgId:%d, received ver:%" PRIu64 ", inconsistent with last ver:%" PRIu64 ", restart connection", pNode->vgId,
|
||||||
|
pWalHead->version, nodeVersion);
|
||||||
|
for (int i = 0; i < pNode->replica; ++i) {
|
||||||
|
pPeer = pNode->peerInfo[i];
|
||||||
|
syncRestartConnection(pPeer);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SYN_INVALID_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
// always update version
|
// always update version
|
||||||
nodeVersion = pWalHead->version;
|
nodeVersion = pWalHead->version;
|
||||||
|
sDebug("vgId:%d, replica:%d nodeRole:%s qtype:%d ver:%" PRIu64, pNode->vgId, pNode->replica, syncRole[nodeRole],
|
||||||
|
qtype, pWalHead->version);
|
||||||
|
|
||||||
if (pNode->replica == 1 || nodeRole != TAOS_SYNC_ROLE_MASTER) return 0;
|
if (pNode->replica == 1 || nodeRole != TAOS_SYNC_ROLE_MASTER) return 0;
|
||||||
|
|
||||||
// only pkt from RPC or CQ can be forwarded
|
// only pkt from RPC or CQ can be forwarded
|
||||||
|
@ -881,7 +894,7 @@ static void syncProcessPeersStatusMsg(char *cont, SSyncPeer *pPeer) {
|
||||||
SSyncNode * pNode = pPeer->pSyncNode;
|
SSyncNode * pNode = pPeer->pSyncNode;
|
||||||
SPeersStatus *pPeersStatus = (SPeersStatus *)cont;
|
SPeersStatus *pPeersStatus = (SPeersStatus *)cont;
|
||||||
|
|
||||||
sDebug("%s, status msg received, self:%s ver:%" PRIu64 " peer:%s ver:%" PRIu64 ", ack:%d", pPeer->id,
|
sDebug("%s, status msg is received, self:%s ver:%" PRIu64 " peer:%s ver:%" PRIu64 ", ack:%d", pPeer->id,
|
||||||
syncRole[nodeRole], nodeVersion, syncRole[pPeersStatus->role], pPeersStatus->version, pPeersStatus->ack);
|
syncRole[nodeRole], nodeVersion, syncRole[pPeersStatus->role], pPeersStatus->version, pPeersStatus->ack);
|
||||||
|
|
||||||
pPeer->version = pPeersStatus->version;
|
pPeer->version = pPeersStatus->version;
|
||||||
|
@ -968,7 +981,8 @@ static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack) {
|
||||||
|
|
||||||
int retLen = write(pPeer->peerFd, msg, statusMsgLen);
|
int retLen = write(pPeer->peerFd, msg, statusMsgLen);
|
||||||
if (retLen == statusMsgLen) {
|
if (retLen == statusMsgLen) {
|
||||||
sDebug("%s, status msg is sent", pPeer->id);
|
sDebug("%s, status msg is sent, self:%s ver:%" PRIu64 ", ack:%d", pPeer->id, syncRole[pPeersStatus->role],
|
||||||
|
pPeersStatus->version, pPeersStatus->ack);
|
||||||
} else {
|
} else {
|
||||||
sDebug("%s, failed to send status msg, restart", pPeer->id);
|
sDebug("%s, failed to send status msg, restart", pPeer->id);
|
||||||
syncRestartConnection(pPeer);
|
syncRestartConnection(pPeer);
|
||||||
|
@ -1189,6 +1203,8 @@ static void syncProcessFwdAck(SSyncNode *pNode, SFwdInfo *pFwdInfo, int32_t code
|
||||||
static void syncMonitorFwdInfos(void *param, void *tmrId) {
|
static void syncMonitorFwdInfos(void *param, void *tmrId) {
|
||||||
SSyncNode *pNode = param;
|
SSyncNode *pNode = param;
|
||||||
SSyncFwds *pSyncFwds = pNode->pSyncFwds;
|
SSyncFwds *pSyncFwds = pNode->pSyncFwds;
|
||||||
|
if (pSyncFwds == NULL) return;
|
||||||
|
|
||||||
uint64_t time = taosGetTimestampMs();
|
uint64_t time = taosGetTimestampMs();
|
||||||
|
|
||||||
if (pSyncFwds->fwds > 0) {
|
if (pSyncFwds->fwds > 0) {
|
||||||
|
|
|
@ -2639,8 +2639,7 @@ int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STa
|
||||||
pGroupInfo->pGroupList = taosArrayInit(1, POINTER_BYTES);
|
pGroupInfo->pGroupList = taosArrayInit(1, POINTER_BYTES);
|
||||||
SArray* group = taosArrayInit(1, sizeof(STableKeyInfo));
|
SArray* group = taosArrayInit(1, sizeof(STableKeyInfo));
|
||||||
|
|
||||||
int32_t i = 0;
|
for(int32_t i = 0; i < size; ++i) {
|
||||||
for(; i < size; ++i) {
|
|
||||||
STableIdInfo *id = taosArrayGet(pTableIdList, i);
|
STableIdInfo *id = taosArrayGet(pTableIdList, i);
|
||||||
|
|
||||||
STable* pTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), id->uid);
|
STable* pTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), id->uid);
|
||||||
|
@ -2665,8 +2664,12 @@ int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STa
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
pGroupInfo->numOfTables = i;
|
pGroupInfo->numOfTables = taosArrayGetSize(group);
|
||||||
taosArrayPush(pGroupInfo->pGroupList, &group);
|
if (pGroupInfo->numOfTables > 0) {
|
||||||
|
taosArrayPush(pGroupInfo->pGroupList, &group);
|
||||||
|
} else {
|
||||||
|
taosArrayDestroy(group);
|
||||||
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,12 +107,14 @@ static FORCE_INLINE void taosCacheReleaseNode(SCacheObj *pCacheObj, SCacheDataNo
|
||||||
free(pNode);
|
free(pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE void doRemoveElemInTrashcan(SCacheObj* pCacheObj, STrashElem *pElem) {
|
static FORCE_INLINE STrashElem* doRemoveElemInTrashcan(SCacheObj* pCacheObj, STrashElem *pElem) {
|
||||||
if (pElem->pData->signature != (uint64_t) pElem->pData) {
|
if (pElem->pData->signature != (uint64_t) pElem->pData) {
|
||||||
uWarn("key:sig:0x%" PRIx64 " %p data has been released, ignore", pElem->pData->signature, pElem->pData);
|
uWarn("key:sig:0x%" PRIx64 " %p data has been released, ignore", pElem->pData->signature, pElem->pData);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STrashElem* next = pElem->next;
|
||||||
|
|
||||||
pCacheObj->numOfElemsInTrash--;
|
pCacheObj->numOfElemsInTrash--;
|
||||||
if (pElem->prev) {
|
if (pElem->prev) {
|
||||||
pElem->prev->next = pElem->next;
|
pElem->prev->next = pElem->next;
|
||||||
|
@ -120,9 +122,15 @@ static FORCE_INLINE void doRemoveElemInTrashcan(SCacheObj* pCacheObj, STrashElem
|
||||||
pCacheObj->pTrash = pElem->next;
|
pCacheObj->pTrash = pElem->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pElem->next) {
|
if (next) {
|
||||||
pElem->next->prev = pElem->prev;
|
next->prev = pElem->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pCacheObj->numOfElemsInTrash == 0) {
|
||||||
|
assert(pCacheObj->pTrash == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE void doDestroyTrashcanElem(SCacheObj* pCacheObj, STrashElem *pElem) {
|
static FORCE_INLINE void doDestroyTrashcanElem(SCacheObj* pCacheObj, STrashElem *pElem) {
|
||||||
|
@ -550,8 +558,8 @@ void taosAddToTrashcan(SCacheObj *pCacheObj, SCacheDataNode *pNode) {
|
||||||
pCacheObj->numOfElemsInTrash++;
|
pCacheObj->numOfElemsInTrash++;
|
||||||
__cache_unlock(pCacheObj);
|
__cache_unlock(pCacheObj);
|
||||||
|
|
||||||
uDebug("cache:%s key:%p, %p move to trashcan, numOfElem in trashcan:%d", pCacheObj->name, pNode->key, pNode->data,
|
uDebug("cache:%s key:%p, %p move to trashcan, pTrashElem:%p, numOfElem in trashcan:%d", pCacheObj->name,
|
||||||
pCacheObj->numOfElemsInTrash);
|
pNode->key, pNode->data, pElem, pCacheObj->numOfElemsInTrash);
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) {
|
void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) {
|
||||||
|
@ -559,31 +567,30 @@ void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) {
|
||||||
|
|
||||||
if (pCacheObj->numOfElemsInTrash == 0) {
|
if (pCacheObj->numOfElemsInTrash == 0) {
|
||||||
if (pCacheObj->pTrash != NULL) {
|
if (pCacheObj->pTrash != NULL) {
|
||||||
|
pCacheObj->pTrash = NULL;
|
||||||
uError("cache:%s, key:inconsistency data in cache, numOfElem in trashcan:%d", pCacheObj->name, pCacheObj->numOfElemsInTrash);
|
uError("cache:%s, key:inconsistency data in cache, numOfElem in trashcan:%d", pCacheObj->name, pCacheObj->numOfElemsInTrash);
|
||||||
}
|
}
|
||||||
|
|
||||||
pCacheObj->pTrash = NULL;
|
|
||||||
__cache_unlock(pCacheObj);
|
__cache_unlock(pCacheObj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
STrashElem *pElem = pCacheObj->pTrash;
|
const char* stat[] = {"false", "true"};
|
||||||
|
uDebug("cache:%s start to cleanup trashcan, numOfElem in trashcan:%d, free:%s", pCacheObj->name,
|
||||||
|
pCacheObj->numOfElemsInTrash, (force? stat[1]:stat[0]));
|
||||||
|
|
||||||
|
STrashElem *pElem = pCacheObj->pTrash;
|
||||||
while (pElem) {
|
while (pElem) {
|
||||||
T_REF_VAL_CHECK(pElem->pData);
|
T_REF_VAL_CHECK(pElem->pData);
|
||||||
if (pElem->next == pElem) {
|
assert(pElem->next != pElem && pElem->prev != pElem);
|
||||||
pElem->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (force || (T_REF_VAL_GET(pElem->pData) == 0)) {
|
if (force || (T_REF_VAL_GET(pElem->pData) == 0)) {
|
||||||
uDebug("cache:%s, key:%p, %p removed from trashcan. numOfElem in trashcan:%d", pCacheObj->name, pElem->pData->key, pElem->pData->data,
|
uDebug("cache:%s, key:%p, %p removed from trashcan. numOfElem in trashcan:%d", pCacheObj->name, pElem->pData->key, pElem->pData->data,
|
||||||
pCacheObj->numOfElemsInTrash - 1);
|
pCacheObj->numOfElemsInTrash - 1);
|
||||||
|
|
||||||
STrashElem *p = pElem;
|
doRemoveElemInTrashcan(pCacheObj, pElem);
|
||||||
pElem = pElem->next;
|
doDestroyTrashcanElem(pCacheObj, pElem);
|
||||||
|
pElem = pCacheObj->pTrash;
|
||||||
doRemoveElemInTrashcan(pCacheObj, p);
|
|
||||||
doDestroyTrashcanElem(pCacheObj, p);
|
|
||||||
} else {
|
} else {
|
||||||
pElem = pElem->next;
|
pElem = pElem->next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,6 +263,7 @@ void taosCloseQset(taos_qset param) {
|
||||||
// thread to exit.
|
// thread to exit.
|
||||||
void taosQsetThreadResume(taos_qset param) {
|
void taosQsetThreadResume(taos_qset param) {
|
||||||
STaosQset *qset = (STaosQset *)param;
|
STaosQset *qset = (STaosQset *)param;
|
||||||
|
uDebug("qset:%p, it will exit", qset);
|
||||||
tsem_post(&qset->sem);
|
tsem_post(&qset->sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,8 +239,10 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
|
||||||
|
|
||||||
code = vnodeReadVersion(pVnode);
|
code = vnodeReadVersion(pVnode);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
vnodeCleanUp(pVnode);
|
vError("vgId:%d, failed to read version, generate it from data file", pVnode->vgId);
|
||||||
return code;
|
// Allow vnode start even when read version fails, set version as walVersion or zero
|
||||||
|
// vnodeCleanUp(pVnode);
|
||||||
|
// return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
pVnode->fversion = pVnode->version;
|
pVnode->fversion = pVnode->version;
|
||||||
|
@ -292,6 +294,9 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
walRestore(pVnode->wal, pVnode, vnodeWriteToQueue);
|
walRestore(pVnode->wal, pVnode, vnodeWriteToQueue);
|
||||||
|
if (pVnode->version == 0) {
|
||||||
|
pVnode->version = walGetVersion(pVnode->wal);
|
||||||
|
}
|
||||||
|
|
||||||
SSyncInfo syncInfo;
|
SSyncInfo syncInfo;
|
||||||
syncInfo.vgId = pVnode->vgId;
|
syncInfo.vgId = pVnode->vgId;
|
||||||
|
@ -947,6 +952,7 @@ static int32_t vnodeSaveVersion(SVnodeObj *pVnode) {
|
||||||
len += snprintf(content + len, maxLen - len, "}\n");
|
len += snprintf(content + len, maxLen - len, "}\n");
|
||||||
|
|
||||||
fwrite(content, 1, len, fp);
|
fwrite(content, 1, len, fp);
|
||||||
|
fflush(fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
vInfo("vgId:%d, save vnode version:%" PRId64 " succeed", pVnode->vgId, pVnode->fversion);
|
vInfo("vgId:%d, save vnode version:%" PRId64 " succeed", pVnode->vgId, pVnode->fversion);
|
||||||
|
@ -960,7 +966,7 @@ static int32_t vnodeReadVersion(SVnodeObj *pVnode) {
|
||||||
cJSON *root = NULL;
|
cJSON *root = NULL;
|
||||||
int maxLen = 100;
|
int maxLen = 100;
|
||||||
|
|
||||||
terrno = TSDB_CODE_VND_APP_ERROR;
|
terrno = TSDB_CODE_VND_INVALID_VRESION_FILE;
|
||||||
sprintf(versionFile, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
|
sprintf(versionFile, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
|
||||||
FILE *fp = fopen(versionFile, "r");
|
FILE *fp = fopen(versionFile, "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
|
@ -974,7 +980,7 @@ static int32_t vnodeReadVersion(SVnodeObj *pVnode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
content = calloc(1, maxLen + 1);
|
content = calloc(1, maxLen + 1);
|
||||||
int len = fread(content, 1, maxLen, fp);
|
int len = fread(content, 1, maxLen, fp);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
vError("vgId:%d, failed to read vnode version, content is null", pVnode->vgId);
|
vError("vgId:%d, failed to read vnode version, content is null", pVnode->vgId);
|
||||||
goto PARSE_OVER;
|
goto PARSE_OVER;
|
||||||
|
@ -999,6 +1005,6 @@ static int32_t vnodeReadVersion(SVnodeObj *pVnode) {
|
||||||
PARSE_OVER:
|
PARSE_OVER:
|
||||||
taosTFree(content);
|
taosTFree(content);
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
if(fp) fclose(fp);
|
if (fp) fclose(fp);
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,18 +49,18 @@ int32_t vnodeProcessRead(void *param, SReadMsg *pReadMsg) {
|
||||||
|
|
||||||
if (pVnode->status != TAOS_VN_STATUS_READY) {
|
if (pVnode->status != TAOS_VN_STATUS_READY) {
|
||||||
vDebug("vgId:%d, msgType:%s not processed, vnode status is %d", pVnode->vgId, taosMsg[msgType], pVnode->status);
|
vDebug("vgId:%d, msgType:%s not processed, vnode status is %d", pVnode->vgId, taosMsg[msgType], pVnode->status);
|
||||||
return TSDB_CODE_APP_NOT_READY;
|
return TSDB_CODE_APP_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tsdb may be in reset state
|
// tsdb may be in reset state
|
||||||
if (pVnode->tsdb == NULL) return TSDB_CODE_APP_NOT_READY;
|
if (pVnode->tsdb == NULL) return TSDB_CODE_APP_NOT_READY;
|
||||||
if (pVnode->status == TAOS_VN_STATUS_CLOSING)
|
if (pVnode->status == TAOS_VN_STATUS_CLOSING) return TSDB_CODE_APP_NOT_READY;
|
||||||
return TSDB_CODE_APP_NOT_READY;
|
|
||||||
|
|
||||||
// TODO: Later, let slave to support query
|
// TODO: Later, let slave to support query
|
||||||
// if (pVnode->syncCfg.replica > 1 && pVnode->role != TAOS_SYNC_ROLE_MASTER) {
|
// if (pVnode->syncCfg.replica > 1 && pVnode->role != TAOS_SYNC_ROLE_MASTER) {
|
||||||
if (pVnode->role != TAOS_SYNC_ROLE_SLAVE && pVnode->role != TAOS_SYNC_ROLE_MASTER) {
|
if (pVnode->role != TAOS_SYNC_ROLE_SLAVE && pVnode->role != TAOS_SYNC_ROLE_MASTER) {
|
||||||
vDebug("vgId:%d, msgType:%s not processed, replica:%d role:%d", pVnode->vgId, taosMsg[msgType], pVnode->syncCfg.replica, pVnode->role);
|
vDebug("vgId:%d, msgType:%s not processed, replica:%d role:%s", pVnode->vgId, taosMsg[msgType],
|
||||||
|
pVnode->syncCfg.replica, syncRole[pVnode->role]);
|
||||||
return TSDB_CODE_APP_NOT_READY;
|
return TSDB_CODE_APP_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ static void vnodePutItemIntoReadQueue(SVnodeObj *pVnode, void **qhandle) {
|
||||||
taosWriteQitem(pVnode->rqueue, TAOS_QTYPE_QUERY, pRead);
|
taosWriteQitem(pVnode->rqueue, TAOS_QTYPE_QUERY, pRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vnodeDumpQueryResult(SRspRet *pRet, void* pVnode, void** handle, bool* freeHandle) {
|
static int32_t vnodeDumpQueryResult(SRspRet *pRet, void *pVnode, void **handle, bool *freeHandle) {
|
||||||
bool continueExec = false;
|
bool continueExec = false;
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
@ -106,55 +106,56 @@ static int32_t vnodeDumpQueryResult(SRspRet *pRet, void* pVnode, void** handle,
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnodeBuildNoResultQueryRsp(SRspRet* pRet) {
|
static void vnodeBuildNoResultQueryRsp(SRspRet *pRet) {
|
||||||
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
||||||
pRet->len = sizeof(SRetrieveTableRsp);
|
pRet->len = sizeof(SRetrieveTableRsp);
|
||||||
|
|
||||||
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
||||||
SRetrieveTableRsp* pRsp = pRet->rsp;
|
SRetrieveTableRsp *pRsp = pRet->rsp;
|
||||||
|
|
||||||
pRsp->completed = true;
|
pRsp->completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
void *pCont = pReadMsg->pCont;
|
void * pCont = pReadMsg->pCont;
|
||||||
int32_t contLen = pReadMsg->contLen;
|
int32_t contLen = pReadMsg->contLen;
|
||||||
SRspRet *pRet = &pReadMsg->rspRet;
|
SRspRet *pRet = &pReadMsg->rspRet;
|
||||||
|
|
||||||
SQueryTableMsg* pQueryTableMsg = (SQueryTableMsg*) pCont;
|
SQueryTableMsg *pQueryTableMsg = (SQueryTableMsg *)pCont;
|
||||||
memset(pRet, 0, sizeof(SRspRet));
|
memset(pRet, 0, sizeof(SRspRet));
|
||||||
|
|
||||||
// qHandle needs to be freed correctly
|
// qHandle needs to be freed correctly
|
||||||
if (pReadMsg->rpcMsg.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
if (pReadMsg->rpcMsg.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||||
SRetrieveTableMsg* killQueryMsg = (SRetrieveTableMsg*) pReadMsg->pCont;
|
SRetrieveTableMsg *killQueryMsg = (SRetrieveTableMsg *)pReadMsg->pCont;
|
||||||
killQueryMsg->free = htons(killQueryMsg->free);
|
killQueryMsg->free = htons(killQueryMsg->free);
|
||||||
killQueryMsg->qhandle = htobe64(killQueryMsg->qhandle);
|
killQueryMsg->qhandle = htobe64(killQueryMsg->qhandle);
|
||||||
|
|
||||||
vWarn("QInfo:%p connection %p broken, kill query", (void*) killQueryMsg->qhandle, pReadMsg->rpcMsg.handle);
|
vWarn("QInfo:%p connection %p broken, kill query", (void *)killQueryMsg->qhandle, pReadMsg->rpcMsg.handle);
|
||||||
assert(pReadMsg->rpcMsg.contLen > 0 && killQueryMsg->free == 1);
|
assert(pReadMsg->rpcMsg.contLen > 0 && killQueryMsg->free == 1);
|
||||||
|
|
||||||
void** qhandle = qAcquireQInfo(pVnode->qMgmt, (uint64_t) killQueryMsg->qhandle);
|
void **qhandle = qAcquireQInfo(pVnode->qMgmt, (uint64_t)killQueryMsg->qhandle);
|
||||||
if (qhandle == NULL || *qhandle == NULL) {
|
if (qhandle == NULL || *qhandle == NULL) {
|
||||||
vWarn("QInfo:%p invalid qhandle, no matched query handle, conn:%p", (void*) killQueryMsg->qhandle, pReadMsg->rpcMsg.handle);
|
vWarn("QInfo:%p invalid qhandle, no matched query handle, conn:%p", (void *)killQueryMsg->qhandle,
|
||||||
|
pReadMsg->rpcMsg.handle);
|
||||||
} else {
|
} else {
|
||||||
assert(*qhandle == (void*) killQueryMsg->qhandle);
|
assert(*qhandle == (void *)killQueryMsg->qhandle);
|
||||||
|
|
||||||
qKillQuery(*qhandle);
|
qKillQuery(*qhandle);
|
||||||
qReleaseQInfo(pVnode->qMgmt, (void**) &qhandle, true);
|
qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_TSC_QUERY_CANCELLED;
|
return TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
void** handle = NULL;
|
void ** handle = NULL;
|
||||||
|
|
||||||
if (contLen != 0) {
|
if (contLen != 0) {
|
||||||
qinfo_t pQInfo = NULL;
|
qinfo_t pQInfo = NULL;
|
||||||
code = qCreateQueryInfo(pVnode->tsdb, pVnode->vgId, pQueryTableMsg, &pQInfo);
|
code = qCreateQueryInfo(pVnode->tsdb, pVnode->vgId, pQueryTableMsg, &pQInfo);
|
||||||
|
|
||||||
SQueryTableRsp *pRsp = (SQueryTableRsp *) rpcMallocCont(sizeof(SQueryTableRsp));
|
SQueryTableRsp *pRsp = (SQueryTableRsp *)rpcMallocCont(sizeof(SQueryTableRsp));
|
||||||
pRsp->code = code;
|
pRsp->code = code;
|
||||||
pRsp->qhandle = 0;
|
pRsp->qhandle = 0;
|
||||||
|
|
||||||
pRet->len = sizeof(SQueryTableRsp);
|
pRet->len = sizeof(SQueryTableRsp);
|
||||||
|
@ -163,7 +164,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
|
|
||||||
// current connect is broken
|
// current connect is broken
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
handle = qRegisterQInfo(pVnode->qMgmt, (uint64_t) pQInfo);
|
handle = qRegisterQInfo(pVnode->qMgmt, (uint64_t)pQInfo);
|
||||||
if (handle == NULL) { // failed to register qhandle, todo add error test case
|
if (handle == NULL) { // failed to register qhandle, todo add error test case
|
||||||
vError("vgId:%d QInfo:%p register qhandle failed, return to app, code:%s", pVnode->vgId, (void *)pQInfo,
|
vError("vgId:%d QInfo:%p register qhandle failed, return to app, code:%s", pVnode->vgId, (void *)pQInfo,
|
||||||
tstrerror(pRsp->code));
|
tstrerror(pRsp->code));
|
||||||
|
@ -171,13 +172,15 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
qDestroyQueryInfo(pQInfo); // destroy it directly
|
qDestroyQueryInfo(pQInfo); // destroy it directly
|
||||||
} else {
|
} else {
|
||||||
assert(*handle == pQInfo);
|
assert(*handle == pQInfo);
|
||||||
pRsp->qhandle = htobe64((uint64_t) pQInfo);
|
pRsp->qhandle = htobe64((uint64_t)pQInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle != NULL && vnodeNotifyCurrentQhandle(pReadMsg->rpcMsg.handle, *handle, pVnode->vgId) != TSDB_CODE_SUCCESS) {
|
if (handle != NULL &&
|
||||||
vError("vgId:%d, QInfo:%p, query discarded since link is broken, %p", pVnode->vgId, *handle, pReadMsg->rpcMsg.handle);
|
vnodeNotifyCurrentQhandle(pReadMsg->rpcMsg.handle, *handle, pVnode->vgId) != TSDB_CODE_SUCCESS) {
|
||||||
|
vError("vgId:%d, QInfo:%p, query discarded since link is broken, %p", pVnode->vgId, *handle,
|
||||||
|
pReadMsg->rpcMsg.handle);
|
||||||
pRsp->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
pRsp->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
||||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
|
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true);
|
||||||
return pRsp->code;
|
return pRsp->code;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -190,12 +193,12 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(pCont != NULL);
|
assert(pCont != NULL);
|
||||||
void** qhandle = (void**) pCont;
|
void **qhandle = (void **)pCont;
|
||||||
|
|
||||||
vDebug("vgId:%d, QInfo:%p, dnode continues to exec query", pVnode->vgId, *qhandle);
|
vDebug("vgId:%d, QInfo:%p, dnode continues to exec query", pVnode->vgId, *qhandle);
|
||||||
|
|
||||||
bool freehandle = false;
|
bool freehandle = false;
|
||||||
bool buildRes = qTableQuery(*qhandle); // do execute query
|
bool buildRes = qTableQuery(*qhandle); // do execute query
|
||||||
|
|
||||||
// build query rsp, the retrieve request has reached here already
|
// build query rsp, the retrieve request has reached here already
|
||||||
if (buildRes) {
|
if (buildRes) {
|
||||||
|
@ -233,16 +236,17 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
pRetrieve->free = htons(pRetrieve->free);
|
pRetrieve->free = htons(pRetrieve->free);
|
||||||
pRetrieve->qhandle = htobe64(pRetrieve->qhandle);
|
pRetrieve->qhandle = htobe64(pRetrieve->qhandle);
|
||||||
|
|
||||||
vDebug("vgId:%d, QInfo:%p, retrieve msg is disposed, free:%d, conn:%p", pVnode->vgId, (void*) pRetrieve->qhandle, pRetrieve->free, pReadMsg->rpcMsg.handle);
|
vDebug("vgId:%d, QInfo:%p, retrieve msg is disposed, free:%d, conn:%p", pVnode->vgId, (void *)pRetrieve->qhandle,
|
||||||
|
pRetrieve->free, pReadMsg->rpcMsg.handle);
|
||||||
|
|
||||||
memset(pRet, 0, sizeof(SRspRet));
|
memset(pRet, 0, sizeof(SRspRet));
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
void** handle = qAcquireQInfo(pVnode->qMgmt, pRetrieve->qhandle);
|
void ** handle = qAcquireQInfo(pVnode->qMgmt, pRetrieve->qhandle);
|
||||||
if (handle == NULL || (*handle) != (void*) pRetrieve->qhandle) {
|
if (handle == NULL || (*handle) != (void *)pRetrieve->qhandle) {
|
||||||
code = TSDB_CODE_QRY_INVALID_QHANDLE;
|
code = TSDB_CODE_QRY_INVALID_QHANDLE;
|
||||||
vDebug("vgId:%d, invalid qhandle in retrieving result, QInfo:%p", pVnode->vgId, (void*) pRetrieve->qhandle);
|
vDebug("vgId:%d, invalid qhandle in retrieving result, QInfo:%p", pVnode->vgId, (void *)pRetrieve->qhandle);
|
||||||
|
|
||||||
vnodeBuildNoResultQueryRsp(pRet);
|
vnodeBuildNoResultQueryRsp(pRet);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +254,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
if (pRetrieve->free == 1) {
|
if (pRetrieve->free == 1) {
|
||||||
vWarn("vgId:%d, QInfo:%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, *handle);
|
vWarn("vgId:%d, QInfo:%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, *handle);
|
||||||
qKillQuery(*handle);
|
qKillQuery(*handle);
|
||||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
|
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true);
|
||||||
|
|
||||||
vnodeBuildNoResultQueryRsp(pRet);
|
vnodeBuildNoResultQueryRsp(pRet);
|
||||||
code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
|
@ -259,25 +263,27 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
|
|
||||||
// register the qhandle to connect to quit query immediate if connection is broken
|
// register the qhandle to connect to quit query immediate if connection is broken
|
||||||
if (vnodeNotifyCurrentQhandle(pReadMsg->rpcMsg.handle, *handle, pVnode->vgId) != TSDB_CODE_SUCCESS) {
|
if (vnodeNotifyCurrentQhandle(pReadMsg->rpcMsg.handle, *handle, pVnode->vgId) != TSDB_CODE_SUCCESS) {
|
||||||
vError("vgId:%d, QInfo:%p, retrieve discarded since link is broken, %p", pVnode->vgId, *handle, pReadMsg->rpcMsg.handle);
|
vError("vgId:%d, QInfo:%p, retrieve discarded since link is broken, %p", pVnode->vgId, *handle,
|
||||||
|
pReadMsg->rpcMsg.handle);
|
||||||
code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
||||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
|
qKillQuery(*handle);
|
||||||
|
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool freeHandle = true;
|
bool freeHandle = true;
|
||||||
bool buildRes = false;
|
bool buildRes = false;
|
||||||
|
|
||||||
code = qRetrieveQueryResultInfo(*handle, &buildRes, pReadMsg->rpcMsg.handle);
|
code = qRetrieveQueryResultInfo(*handle, &buildRes, pReadMsg->rpcMsg.handle);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
//TODO handle malloc failure
|
// TODO handle malloc failure
|
||||||
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
||||||
pRet->len = sizeof(SRetrieveTableRsp);
|
pRet->len = sizeof(SRetrieveTableRsp);
|
||||||
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
||||||
freeHandle = true;
|
freeHandle = true;
|
||||||
} else { // result is not ready, return immediately
|
} else { // result is not ready, return immediately
|
||||||
if (!buildRes) {
|
if (!buildRes) {
|
||||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, false);
|
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, false);
|
||||||
return TSDB_CODE_QRY_NOT_READY;
|
return TSDB_CODE_QRY_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +293,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
// If qhandle is not added into vread queue, the query should be completed already or paused with error.
|
// If qhandle is not added into vread queue, the query should be completed already or paused with error.
|
||||||
// Here free qhandle immediately
|
// Here free qhandle immediately
|
||||||
if (freeHandle) {
|
if (freeHandle) {
|
||||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
|
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -295,13 +301,13 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||||
|
|
||||||
// notify connection(handle) that current qhandle is created, if current connection from
|
// notify connection(handle) that current qhandle is created, if current connection from
|
||||||
// client is broken, the query needs to be killed immediately.
|
// client is broken, the query needs to be killed immediately.
|
||||||
int32_t vnodeNotifyCurrentQhandle(void* handle, void* qhandle, int32_t vgId) {
|
int32_t vnodeNotifyCurrentQhandle(void *handle, void *qhandle, int32_t vgId) {
|
||||||
SRetrieveTableMsg* killQueryMsg = rpcMallocCont(sizeof(SRetrieveTableMsg));
|
SRetrieveTableMsg *killQueryMsg = rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||||
killQueryMsg->qhandle = htobe64((uint64_t) qhandle);
|
killQueryMsg->qhandle = htobe64((uint64_t)qhandle);
|
||||||
killQueryMsg->free = htons(1);
|
killQueryMsg->free = htons(1);
|
||||||
killQueryMsg->header.vgId = htonl(vgId);
|
killQueryMsg->header.vgId = htonl(vgId);
|
||||||
killQueryMsg->header.contLen = htonl(sizeof(SRetrieveTableMsg));
|
killQueryMsg->header.contLen = htonl(sizeof(SRetrieveTableMsg));
|
||||||
|
|
||||||
vDebug("QInfo:%p register qhandle to connect:%p", qhandle, handle);
|
vDebug("QInfo:%p register qhandle to connect:%p", qhandle, handle);
|
||||||
return rpcReportProgress(handle, (char*) killQueryMsg, sizeof(SRetrieveTableMsg));
|
return rpcReportProgress(handle, (char *)killQueryMsg, sizeof(SRetrieveTableMsg));
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,11 @@ void vnodeInitWriteFp(void) {
|
||||||
int32_t vnodeProcessWrite(void *param1, int qtype, void *param2, void *item) {
|
int32_t vnodeProcessWrite(void *param1, int qtype, void *param2, void *item) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
SVnodeObj *pVnode = (SVnodeObj *)param1;
|
SVnodeObj *pVnode = (SVnodeObj *)param1;
|
||||||
SWalHead *pHead = param2;
|
SWalHead * pHead = param2;
|
||||||
|
|
||||||
if (vnodeProcessWriteMsgFp[pHead->msgType] == NULL) {
|
if (vnodeProcessWriteMsgFp[pHead->msgType] == NULL) {
|
||||||
vDebug("vgId:%d, msgType:%s not processed, no handle", pVnode->vgId, taosMsg[pHead->msgType]);
|
vDebug("vgId:%d, msgType:%s not processed, no handle", pVnode->vgId, taosMsg[pHead->msgType]);
|
||||||
return TSDB_CODE_VND_MSG_NOT_PROCESSED;
|
return TSDB_CODE_VND_MSG_NOT_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pVnode->accessState & TSDB_VN_WRITE_ACCCESS)) {
|
if (!(pVnode->accessState & TSDB_VN_WRITE_ACCCESS)) {
|
||||||
|
@ -59,44 +59,44 @@ int32_t vnodeProcessWrite(void *param1, int qtype, void *param2, void *item) {
|
||||||
return TSDB_CODE_VND_NO_WRITE_AUTH;
|
return TSDB_CODE_VND_NO_WRITE_AUTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tsdb may be in reset state
|
// tsdb may be in reset state
|
||||||
if (pVnode->tsdb == NULL) return TSDB_CODE_APP_NOT_READY;
|
if (pVnode->tsdb == NULL) return TSDB_CODE_APP_NOT_READY;
|
||||||
if (pVnode->status == TAOS_VN_STATUS_CLOSING)
|
if (pVnode->status == TAOS_VN_STATUS_CLOSING) return TSDB_CODE_APP_NOT_READY;
|
||||||
return TSDB_CODE_APP_NOT_READY;
|
|
||||||
|
if (pHead->version == 0) { // from client or CQ
|
||||||
if (pHead->version == 0) { // from client or CQ
|
|
||||||
if (pVnode->status != TAOS_VN_STATUS_READY) {
|
if (pVnode->status != TAOS_VN_STATUS_READY) {
|
||||||
vDebug("vgId:%d, msgType:%s not processed, vnode status is %d", pVnode->vgId, taosMsg[pHead->msgType], pVnode->status);
|
vDebug("vgId:%d, msgType:%s not processed, vnode status is %d", pVnode->vgId, taosMsg[pHead->msgType],
|
||||||
|
pVnode->status);
|
||||||
return TSDB_CODE_APP_NOT_READY; // it may be in deleting or closing state
|
return TSDB_CODE_APP_NOT_READY; // it may be in deleting or closing state
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pVnode->role != TAOS_SYNC_ROLE_MASTER) {
|
if (pVnode->role != TAOS_SYNC_ROLE_MASTER) {
|
||||||
vDebug("vgId:%d, msgType:%s not processed, replica:%d role:%d", pVnode->vgId, taosMsg[pHead->msgType], pVnode->syncCfg.replica, pVnode->role);
|
vDebug("vgId:%d, msgType:%s not processed, replica:%d role:%s", pVnode->vgId, taosMsg[pHead->msgType],
|
||||||
|
pVnode->syncCfg.replica, syncRole[pVnode->role]);
|
||||||
return TSDB_CODE_APP_NOT_READY;
|
return TSDB_CODE_APP_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign version
|
// assign version
|
||||||
pVnode->version++;
|
pHead->version = pVnode->version + 1;
|
||||||
pHead->version = pVnode->version;
|
if (pVnode->delay) usleep(pVnode->delay * 1000);
|
||||||
if (pVnode->delay) usleep(pVnode->delay*1000);
|
|
||||||
|
|
||||||
} else { // from wal or forward
|
} else { // from wal or forward
|
||||||
// for data from WAL or forward, version may be smaller
|
// for data from WAL or forward, version may be smaller
|
||||||
if (pHead->version <= pVnode->version) return 0;
|
if (pHead->version <= pVnode->version) return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pVnode->version = pHead->version;
|
// forward to peers, even it is WAL/FWD, it shall be called to update version in sync
|
||||||
|
int32_t syncCode = 0;
|
||||||
|
syncCode = syncForwardToPeer(pVnode->sync, pHead, item, qtype);
|
||||||
|
if (syncCode < 0) return syncCode;
|
||||||
|
|
||||||
// write into WAL
|
// write into WAL
|
||||||
code = walWrite(pVnode->wal, pHead);
|
code = walWrite(pVnode->wal, pHead);
|
||||||
if (code < 0) return code;
|
if (code < 0) return code;
|
||||||
|
|
||||||
// forward to peers, even it is WAL/FWD, it shall be called to update version in sync
|
pVnode->version = pHead->version;
|
||||||
int32_t syncCode = 0;
|
|
||||||
syncCode = syncForwardToPeer(pVnode->sync, pHead, item, qtype);
|
|
||||||
if (syncCode < 0) return syncCode;
|
|
||||||
|
|
||||||
// write data locally
|
// write data locally
|
||||||
code = (*vnodeProcessWriteMsgFp[pHead->msgType])(pVnode, pHead->cont, item);
|
code = (*vnodeProcessWriteMsgFp[pHead->msgType])(pVnode, pHead->cont, item);
|
||||||
if (code < 0) return code;
|
if (code < 0) return code;
|
||||||
|
|
||||||
|
@ -115,14 +115,14 @@ static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pR
|
||||||
|
|
||||||
// save insert result into item
|
// save insert result into item
|
||||||
SShellSubmitRspMsg *pRsp = NULL;
|
SShellSubmitRspMsg *pRsp = NULL;
|
||||||
if (pRet) {
|
if (pRet) {
|
||||||
pRet->len = sizeof(SShellSubmitRspMsg);
|
pRet->len = sizeof(SShellSubmitRspMsg);
|
||||||
pRet->rsp = rpcMallocCont(pRet->len);
|
pRet->rsp = rpcMallocCont(pRet->len);
|
||||||
pRsp = pRet->rsp;
|
pRsp = pRet->rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsdbInsertData(pVnode->tsdb, pCont, pRsp) < 0) code = terrno;
|
if (tsdbInsertData(pVnode->tsdb, pCont, pRsp) < 0) code = terrno;
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ static int32_t vnodeProcessUpdateTagValMsg(SVnodeObj *pVnode, void *pCont, SRspR
|
||||||
|
|
||||||
int vnodeWriteToQueue(void *param, void *data, int type) {
|
int vnodeWriteToQueue(void *param, void *data, int type) {
|
||||||
SVnodeObj *pVnode = param;
|
SVnodeObj *pVnode = param;
|
||||||
SWalHead *pHead = data;
|
SWalHead * pHead = data;
|
||||||
|
|
||||||
int size = sizeof(SWalHead) + pHead->len;
|
int size = sizeof(SWalHead) + pHead->len;
|
||||||
SWalHead *pWal = (SWalHead *)taosAllocateQitem(size);
|
SWalHead *pWal = (SWalHead *)taosAllocateQitem(size);
|
||||||
|
@ -204,4 +204,3 @@ int vnodeWriteToQueue(void *param, void *data, int type) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ static void walRelease(SWal *pWal);
|
||||||
|
|
||||||
static void walModuleInitFunc() {
|
static void walModuleInitFunc() {
|
||||||
walTmrCtrl = taosTmrInit(1000, 100, 300000, "WAL");
|
walTmrCtrl = taosTmrInit(1000, 100, 300000, "WAL");
|
||||||
if (walTmrCtrl == NULL)
|
if (walTmrCtrl == NULL)
|
||||||
walModuleInit = PTHREAD_ONCE_INIT;
|
walModuleInit = PTHREAD_ONCE_INIT;
|
||||||
else
|
else
|
||||||
wDebug("WAL module is initialized");
|
wDebug("WAL module is initialized");
|
||||||
|
@ -90,7 +90,7 @@ void *walOpen(const char *path, const SWalCfg *pCfg) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_add_fetch_32(&tsWalNum, 1);
|
atomic_add_fetch_32(&tsWalNum, 1);
|
||||||
pWal->fd = -1;
|
pWal->fd = -1;
|
||||||
pWal->max = pCfg->wals;
|
pWal->max = pCfg->wals;
|
||||||
pWal->id = 0;
|
pWal->id = 0;
|
||||||
|
@ -117,18 +117,17 @@ void *walOpen(const char *path, const SWalCfg *pCfg) {
|
||||||
walRelease(pWal);
|
walRelease(pWal);
|
||||||
pWal = NULL;
|
pWal = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCfg->keep == 1) return pWal;
|
if (pCfg->keep == 1) return pWal;
|
||||||
|
|
||||||
if (walHandleExistingFiles(path) == 0)
|
if (walHandleExistingFiles(path) == 0) walRenew(pWal);
|
||||||
walRenew(pWal);
|
|
||||||
|
|
||||||
if (pWal && pWal->fd <0) {
|
if (pWal && pWal->fd < 0) {
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
wError("wal:%s, failed to open(%s)", path, strerror(errno));
|
wError("wal:%s, failed to open(%s)", path, strerror(errno));
|
||||||
walRelease(pWal);
|
walRelease(pWal);
|
||||||
pWal = NULL;
|
pWal = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pWal) wDebug("wal:%s, it is open, level:%d fsyncPeriod:%d", path, pWal->level, pWal->fsyncPeriod);
|
if (pWal) wDebug("wal:%s, it is open, level:%d fsyncPeriod:%d", path, pWal->level, pWal->fsyncPeriod);
|
||||||
return pWal;
|
return pWal;
|
||||||
|
@ -154,7 +153,7 @@ int walAlter(twalh wal, const SWalCfg *pCfg) {
|
||||||
pWal->fsyncPeriod = pCfg->fsyncPeriod;
|
pWal->fsyncPeriod = pCfg->fsyncPeriod;
|
||||||
if (walNeedFsyncTimer(pWal)) {
|
if (walNeedFsyncTimer(pWal)) {
|
||||||
wInfo("wal:%s, reset fsync timer, walLevel:%d fsyncPeriod:%d", pWal->name, pWal->level, pWal->fsyncPeriod);
|
wInfo("wal:%s, reset fsync timer, walLevel:%d fsyncPeriod:%d", pWal->name, pWal->level, pWal->fsyncPeriod);
|
||||||
taosTmrReset(walProcessFsyncTimer, pWal->fsyncPeriod, pWal, &pWal->timer,walTmrCtrl);
|
taosTmrReset(walProcessFsyncTimer, pWal->fsyncPeriod, pWal, &pWal->timer, walTmrCtrl);
|
||||||
} else {
|
} else {
|
||||||
wInfo("wal:%s, stop fsync timer, walLevel:%d fsyncPeriod:%d", pWal->name, pWal->level, pWal->fsyncPeriod);
|
wInfo("wal:%s, stop fsync timer, walLevel:%d fsyncPeriod:%d", pWal->name, pWal->level, pWal->fsyncPeriod);
|
||||||
taosTmrStop(pWal->timer);
|
taosTmrStop(pWal->timer);
|
||||||
|
@ -167,16 +166,16 @@ int walAlter(twalh wal, const SWalCfg *pCfg) {
|
||||||
|
|
||||||
void walClose(void *handle) {
|
void walClose(void *handle) {
|
||||||
if (handle == NULL) return;
|
if (handle == NULL) return;
|
||||||
|
|
||||||
SWal *pWal = handle;
|
SWal *pWal = handle;
|
||||||
taosClose(pWal->fd);
|
taosClose(pWal->fd);
|
||||||
if (pWal->timer) taosTmrStopA(&pWal->timer);
|
if (pWal->timer) taosTmrStopA(&pWal->timer);
|
||||||
|
|
||||||
if (pWal->keep == 0) {
|
if (pWal->keep == 0) {
|
||||||
// remove all files in the directory
|
// remove all files in the directory
|
||||||
for (int i=0; i<pWal->num; ++i) {
|
for (int i = 0; i < pWal->num; ++i) {
|
||||||
snprintf(pWal->name, sizeof(pWal->name), "%s/%s%d", pWal->path, walPrefix, pWal->id-i);
|
snprintf(pWal->name, sizeof(pWal->name), "%s/%s%d", pWal->path, walPrefix, pWal->id - i);
|
||||||
if (remove(pWal->name) <0) {
|
if (remove(pWal->name) < 0) {
|
||||||
wError("wal:%s, failed to remove", pWal->name);
|
wError("wal:%s, failed to remove", pWal->name);
|
||||||
} else {
|
} else {
|
||||||
wDebug("wal:%s, it is removed", pWal->name);
|
wDebug("wal:%s, it is removed", pWal->name);
|
||||||
|
@ -197,7 +196,7 @@ int walRenew(void *handle) {
|
||||||
|
|
||||||
pthread_mutex_lock(&pWal->mutex);
|
pthread_mutex_lock(&pWal->mutex);
|
||||||
|
|
||||||
if (pWal->fd >=0) {
|
if (pWal->fd >= 0) {
|
||||||
close(pWal->fd);
|
close(pWal->fd);
|
||||||
pWal->id++;
|
pWal->id++;
|
||||||
wDebug("wal:%s, it is closed", pWal->name);
|
wDebug("wal:%s, it is closed", pWal->name);
|
||||||
|
@ -218,7 +217,7 @@ int walRenew(void *handle) {
|
||||||
// remove the oldest wal file
|
// remove the oldest wal file
|
||||||
char name[TSDB_FILENAME_LEN * 3];
|
char name[TSDB_FILENAME_LEN * 3];
|
||||||
snprintf(name, sizeof(name), "%s/%s%d", pWal->path, walPrefix, pWal->id - pWal->max);
|
snprintf(name, sizeof(name), "%s/%s%d", pWal->path, walPrefix, pWal->id - pWal->max);
|
||||||
if (remove(name) <0) {
|
if (remove(name) < 0) {
|
||||||
wError("wal:%s, failed to remove(%s)", name, strerror(errno));
|
wError("wal:%s, failed to remove(%s)", name, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
wDebug("wal:%s, it is removed", name);
|
wDebug("wal:%s, it is removed", name);
|
||||||
|
@ -226,8 +225,8 @@ int walRenew(void *handle) {
|
||||||
|
|
||||||
pWal->num--;
|
pWal->num--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&pWal->mutex);
|
pthread_mutex_unlock(&pWal->mutex);
|
||||||
|
|
||||||
return terrno;
|
return terrno;
|
||||||
|
@ -239,7 +238,7 @@ int walWrite(void *handle, SWalHead *pHead) {
|
||||||
|
|
||||||
terrno = 0;
|
terrno = 0;
|
||||||
|
|
||||||
// no wal
|
// no wal
|
||||||
if (pWal->level == TAOS_WAL_NOLOG) return 0;
|
if (pWal->level == TAOS_WAL_NOLOG) return 0;
|
||||||
if (pHead->version <= pWal->version) return 0;
|
if (pHead->version <= pWal->version) return 0;
|
||||||
|
|
||||||
|
@ -247,7 +246,7 @@ int walWrite(void *handle, SWalHead *pHead) {
|
||||||
taosCalcChecksumAppend(0, (uint8_t *)pHead, sizeof(SWalHead));
|
taosCalcChecksumAppend(0, (uint8_t *)pHead, sizeof(SWalHead));
|
||||||
int contLen = pHead->len + sizeof(SWalHead);
|
int contLen = pHead->len + sizeof(SWalHead);
|
||||||
|
|
||||||
if(taosTWrite(pWal->fd, pHead, contLen) != contLen) {
|
if (taosTWrite(pWal->fd, pHead, contLen) != contLen) {
|
||||||
wError("wal:%s, failed to write(%s)", pWal->name, strerror(errno));
|
wError("wal:%s, failed to write(%s)", pWal->name, strerror(errno));
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
} else {
|
} else {
|
||||||
|
@ -258,7 +257,6 @@ int walWrite(void *handle, SWalHead *pHead) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void walFsync(void *handle) {
|
void walFsync(void *handle) {
|
||||||
|
|
||||||
SWal *pWal = handle;
|
SWal *pWal = handle;
|
||||||
if (pWal == NULL || pWal->level != TAOS_WAL_FSYNC || pWal->fd < 0) return;
|
if (pWal == NULL || pWal->level != TAOS_WAL_FSYNC || pWal->fd < 0) return;
|
||||||
|
|
||||||
|
@ -276,12 +274,11 @@ int walRestore(void *handle, void *pVnode, int (*writeFp)(void *, void *, int))
|
||||||
uint32_t maxId = 0, minId = -1, index =0;
|
uint32_t maxId = 0, minId = -1, index =0;
|
||||||
|
|
||||||
terrno = 0;
|
terrno = 0;
|
||||||
int plen = strlen(walPrefix);
|
int plen = strlen(walPrefix);
|
||||||
char opath[TSDB_FILENAME_LEN+5];
|
char opath[TSDB_FILENAME_LEN + 5];
|
||||||
|
|
||||||
int slen = snprintf(opath, sizeof(opath), "%s", pWal->path);
|
int slen = snprintf(opath, sizeof(opath), "%s", pWal->path);
|
||||||
if ( pWal->keep == 0)
|
if (pWal->keep == 0) strcpy(opath + slen, "/old");
|
||||||
strcpy(opath+slen, "/old");
|
|
||||||
|
|
||||||
DIR *dir = opendir(opath);
|
DIR *dir = opendir(opath);
|
||||||
if (dir == NULL && errno == ENOENT) return 0;
|
if (dir == NULL && errno == ENOENT) return 0;
|
||||||
|
@ -290,8 +287,8 @@ int walRestore(void *handle, void *pVnode, int (*writeFp)(void *, void *, int))
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ent = readdir(dir))!= NULL) {
|
while ((ent = readdir(dir)) != NULL) {
|
||||||
if ( strncmp(ent->d_name, walPrefix, plen) == 0) {
|
if (strncmp(ent->d_name, walPrefix, plen) == 0) {
|
||||||
index = atol(ent->d_name + plen);
|
index = atol(ent->d_name + plen);
|
||||||
if (index > maxId) maxId = index;
|
if (index > maxId) maxId = index;
|
||||||
if (index < minId) minId = index;
|
if (index < minId) minId = index;
|
||||||
|
@ -306,13 +303,13 @@ int walRestore(void *handle, void *pVnode, int (*writeFp)(void *, void *, int))
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( count != (maxId-minId+1) ) {
|
if (count != (maxId - minId + 1)) {
|
||||||
wError("wal:%s, messed up, count:%d max:%d min:%d", opath, count, maxId, minId);
|
wError("wal:%s, messed up, count:%d max:%d min:%d", opath, count, maxId, minId);
|
||||||
terrno = TSDB_CODE_WAL_APP_ERROR;
|
terrno = TSDB_CODE_WAL_APP_ERROR;
|
||||||
} else {
|
} else {
|
||||||
wDebug("wal:%s, %d files will be restored", opath, count);
|
wDebug("wal:%s, %d files will be restored", opath, count);
|
||||||
|
|
||||||
for (index = minId; index<=maxId; ++index) {
|
for (index = minId; index <= maxId; ++index) {
|
||||||
snprintf(pWal->name, sizeof(pWal->name), "%s/%s%d", opath, walPrefix, index);
|
snprintf(pWal->name, sizeof(pWal->name), "%s/%s%d", opath, walPrefix, index);
|
||||||
terrno = walRestoreWalFile(pWal, pVnode, writeFp);
|
terrno = walRestoreWalFile(pWal, pVnode, writeFp);
|
||||||
if (terrno < 0) break;
|
if (terrno < 0) break;
|
||||||
|
@ -328,7 +325,7 @@ int walRestore(void *handle, void *pVnode, int (*writeFp)(void *, void *, int))
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// open the existing WAL file in append mode
|
// open the existing WAL file in append mode
|
||||||
pWal->num = count;
|
pWal->num = count;
|
||||||
pWal->id = maxId;
|
pWal->id = maxId;
|
||||||
|
@ -345,9 +342,9 @@ int walRestore(void *handle, void *pVnode, int (*writeFp)(void *, void *, int))
|
||||||
}
|
}
|
||||||
|
|
||||||
int walGetWalFile(void *handle, char *name, uint32_t *index) {
|
int walGetWalFile(void *handle, char *name, uint32_t *index) {
|
||||||
SWal *pWal = handle;
|
SWal * pWal = handle;
|
||||||
int code = 1;
|
int code = 1;
|
||||||
int32_t first = 0;
|
int32_t first = 0;
|
||||||
|
|
||||||
name[0] = 0;
|
name[0] = 0;
|
||||||
if (pWal == NULL || pWal->num == 0) return 0;
|
if (pWal == NULL || pWal->num == 0) return 0;
|
||||||
|
@ -359,18 +356,17 @@ int walGetWalFile(void *handle, char *name, uint32_t *index) {
|
||||||
|
|
||||||
if (*index < first && *index > pWal->id) {
|
if (*index < first && *index > pWal->id) {
|
||||||
code = -1; // index out of range
|
code = -1; // index out of range
|
||||||
} else {
|
} else {
|
||||||
sprintf(name, "wal/%s%d", walPrefix, *index);
|
sprintf(name, "wal/%s%d", walPrefix, *index);
|
||||||
code = (*index == pWal->id) ? 0:1;
|
code = (*index == pWal->id) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&(pWal->mutex));
|
pthread_mutex_unlock(&(pWal->mutex));
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void walRelease(SWal *pWal) {
|
static void walRelease(SWal *pWal) {
|
||||||
|
|
||||||
pthread_mutex_destroy(&pWal->mutex);
|
pthread_mutex_destroy(&pWal->mutex);
|
||||||
pWal->signature = NULL;
|
pWal->signature = NULL;
|
||||||
free(pWal);
|
free(pWal);
|
||||||
|
@ -385,12 +381,12 @@ static void walRelease(SWal *pWal) {
|
||||||
|
|
||||||
static int walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp) {
|
static int walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp) {
|
||||||
char *name = pWal->name;
|
char *name = pWal->name;
|
||||||
int size = 1024 * 1024; // default 1M buffer size
|
int size = 1024 * 1024; // default 1M buffer size
|
||||||
|
|
||||||
terrno = 0;
|
terrno = 0;
|
||||||
char *buffer = malloc(size);
|
char *buffer = malloc(size);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +423,7 @@ static int walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp) {
|
||||||
if (!taosCheckChecksumWhole((uint8_t *)pHead, sizeof(SWalHead))) {
|
if (!taosCheckChecksumWhole((uint8_t *)pHead, sizeof(SWalHead))) {
|
||||||
wWarn("wal:%s, cksum is messed up, skip the rest of file", name);
|
wWarn("wal:%s, cksum is messed up, skip the rest of file", name);
|
||||||
terrno = TSDB_CODE_WAL_FILE_CORRUPTED;
|
terrno = TSDB_CODE_WAL_FILE_CORRUPTED;
|
||||||
ASSERT(false);
|
// ASSERT(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,21 +483,21 @@ int walHandleExistingFiles(const char *path) {
|
||||||
} else {
|
} else {
|
||||||
// move all files to old directory
|
// move all files to old directory
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while ((ent = readdir(dir))!= NULL) {
|
while ((ent = readdir(dir)) != NULL) {
|
||||||
if ( strncmp(ent->d_name, walPrefix, plen) == 0) {
|
if (strncmp(ent->d_name, walPrefix, plen) == 0) {
|
||||||
snprintf(oname, sizeof(oname), "%s/%s", path, ent->d_name);
|
snprintf(oname, sizeof(oname), "%s/%s", path, ent->d_name);
|
||||||
snprintf(nname, sizeof(nname), "%s/old/%s", path, ent->d_name);
|
snprintf(nname, sizeof(nname), "%s/old/%s", path, ent->d_name);
|
||||||
if (taosMkDir(opath, 0755) != 0) {
|
if (taosMkDir(opath, 0755) != 0) {
|
||||||
wError("wal:%s, failed to create directory:%s(%s)", oname, opath, strerror(errno));
|
wError("wal:%s, failed to create directory:%s(%s)", oname, opath, strerror(errno));
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rename(oname, nname) < 0) {
|
if (rename(oname, nname) < 0) {
|
||||||
wError("wal:%s, failed to move to new:%s", oname, nname);
|
wError("wal:%s, failed to move to new:%s", oname, nname);
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -509,34 +505,34 @@ int walHandleExistingFiles(const char *path) {
|
||||||
|
|
||||||
wDebug("wal:%s, %d files are moved for restoration", path, count);
|
wDebug("wal:%s, %d files are moved for restoration", path, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int walRemoveWalFiles(const char *path) {
|
static int walRemoveWalFiles(const char *path) {
|
||||||
int plen = strlen(walPrefix);
|
int plen = strlen(walPrefix);
|
||||||
char name[TSDB_FILENAME_LEN * 3];
|
char name[TSDB_FILENAME_LEN * 3];
|
||||||
|
|
||||||
terrno = 0;
|
terrno = 0;
|
||||||
|
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
DIR *dir = opendir(path);
|
DIR *dir = opendir(path);
|
||||||
if (dir == NULL && errno == ENOENT) return 0;
|
if (dir == NULL && errno == ENOENT) return 0;
|
||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ent = readdir(dir))!= NULL) {
|
while ((ent = readdir(dir)) != NULL) {
|
||||||
if ( strncmp(ent->d_name, walPrefix, plen) == 0) {
|
if (strncmp(ent->d_name, walPrefix, plen) == 0) {
|
||||||
snprintf(name, sizeof(name), "%s/%s", path, ent->d_name);
|
snprintf(name, sizeof(name), "%s/%s", path, ent->d_name);
|
||||||
if (remove(name) <0) {
|
if (remove(name) < 0) {
|
||||||
wError("wal:%s, failed to remove(%s)", name, strerror(errno));
|
wError("wal:%s, failed to remove(%s)", name, strerror(errno));
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
|
@ -561,3 +557,10 @@ static void walProcessFsyncTimer(void *param, void *tmrId) {
|
||||||
pWal->timer = NULL;
|
pWal->timer = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t walGetVersion(twalh param) {
|
||||||
|
SWal *pWal = param;
|
||||||
|
if (pWal == 0) return 0;
|
||||||
|
|
||||||
|
return pWal->version;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.taosdata.example.calcite</groupId>
|
||||||
|
<artifactId>calciteDemo</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- slf4j -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- calcite -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.calcite</groupId>
|
||||||
|
<artifactId>calcite-core</artifactId>
|
||||||
|
<version>1.23.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-dbcp2</artifactId>
|
||||||
|
<version>2.7.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.calcite.avatica</groupId>
|
||||||
|
<artifactId>avatica-core</artifactId>
|
||||||
|
<version>1.17.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- mysql -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>5.1.47</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- tdengine -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
|
<version>2.0.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.taosdata.example.calcite;
|
||||||
|
|
||||||
|
import org.apache.calcite.adapter.jdbc.JdbcSchema;
|
||||||
|
import org.apache.calcite.jdbc.CalciteConnection;
|
||||||
|
import org.apache.calcite.schema.Schema;
|
||||||
|
import org.apache.calcite.schema.SchemaPlus;
|
||||||
|
import org.apache.calcite.sql.parser.SqlParseException;
|
||||||
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class CalciteDemo {
|
||||||
|
|
||||||
|
private static String url_taos = "jdbc:TAOS://192.168.236.135:6030/test";
|
||||||
|
private static String url_mysql = "jdbc:mysql://master:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws SqlParseException, ClassNotFoundException, SQLException {
|
||||||
|
Class.forName("org.apache.calcite.jdbc.Driver");
|
||||||
|
Properties info = new Properties();
|
||||||
|
info.setProperty("caseSensitive", "false");
|
||||||
|
|
||||||
|
Connection connection = DriverManager.getConnection("jdbc:calcite:", info);
|
||||||
|
CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
|
||||||
|
|
||||||
|
SchemaPlus rootSchema = calciteConnection.getRootSchema();
|
||||||
|
|
||||||
|
//这里hdb是在tdengine中创建的数据库名
|
||||||
|
Schema schema = mysqlTest(rootSchema);
|
||||||
|
// Schema schema = tdengineTest(rootSchema);
|
||||||
|
|
||||||
|
//创建新的schema自动映射到原来的hdb数据库
|
||||||
|
rootSchema.add("test", schema);
|
||||||
|
|
||||||
|
Statement stmt = calciteConnection.createStatement();
|
||||||
|
//查询schema test中的表,表名是tdengine中的表
|
||||||
|
ResultSet rs = stmt.executeQuery("select * from test.t");
|
||||||
|
ResultSetMetaData metaData = rs.getMetaData();
|
||||||
|
while (rs.next()) {
|
||||||
|
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||||
|
System.out.println(metaData.getColumnLabel(i) + " : " + rs.getString(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Schema tdengineTest(SchemaPlus rootSchema) throws ClassNotFoundException {
|
||||||
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
BasicDataSource dataSource = new BasicDataSource();
|
||||||
|
dataSource.setUrl(url_taos);
|
||||||
|
dataSource.setUsername("root");
|
||||||
|
dataSource.setPassword("taosdata");
|
||||||
|
|
||||||
|
return JdbcSchema.create(rootSchema, "test", dataSource, "hdb", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Schema mysqlTest(SchemaPlus rootSchema) throws ClassNotFoundException {
|
||||||
|
Class.forName("com.mysql.jdbc.Driver");
|
||||||
|
BasicDataSource dataSource = new BasicDataSource();
|
||||||
|
dataSource.setUrl(url_mysql);
|
||||||
|
dataSource.setUsername("root");
|
||||||
|
dataSource.setPassword("123456");
|
||||||
|
|
||||||
|
//Schema schema = JdbcSchema.create(rootSchema, "test", dataSource, "hdb", null);
|
||||||
|
return JdbcSchema.create(rootSchema, "test", dataSource, "test", null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
log4j.rootLogger=info,stdout
|
||||||
|
|
||||||
|
#console
|
||||||
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.stdout.layout.ConversionPattern= [%d{yyyy-MM-dd HH:mm:ss a}]:%p %l%m%n
|
|
@ -0,0 +1,146 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import threading
|
||||||
|
import taos
|
||||||
|
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
# query sql
|
||||||
|
query_sql = [
|
||||||
|
# first supertable
|
||||||
|
"select count(*) from test.meters where c1 > 50;",
|
||||||
|
"select count(*) from test.meters where c2 >= 50 and c2 < 100;",
|
||||||
|
"select count(*) from test.meters where c3 != 5;",
|
||||||
|
"select count(*) from test.meters where t3 > 2;",
|
||||||
|
"select count(*) from test.meters where ts <> '2020-05-13 10:00:00.002';",
|
||||||
|
"select count(*) from test.meters where t7 like 'fi%';",
|
||||||
|
"select count(*) from test.meters where t7 like '_econd';",
|
||||||
|
"select count(*) from test.meters interval(1n) order by ts desc;",
|
||||||
|
"select first(*) from test.meters;",
|
||||||
|
"select last(*) from test.meters;",
|
||||||
|
"select last_row(*) from test.meters;",
|
||||||
|
"select twa(c1) from test.t1 where ts > 1500000001000 and ts < 1500000101000" ,
|
||||||
|
"select avg(c1) from test.meters;",
|
||||||
|
"select bottom(c1, 2) from test.t1;",
|
||||||
|
"select diff(c1) from test.t1;",
|
||||||
|
"select leastsquares(c1, 1, 1) from test.t1 ;",
|
||||||
|
"select max(c1) from test.meters;",
|
||||||
|
"select min(c1) from test.meters;",
|
||||||
|
"select c1 + c2 * c3 + c1 / c5 + c4 + c2 from test.t1;",
|
||||||
|
"select percentile(c1, 50) from test.t1;",
|
||||||
|
"select spread(c1) from test.t1 ;",
|
||||||
|
"select stddev(c1) from test.t1;",
|
||||||
|
"select sum(c1) from test.meters;",
|
||||||
|
"select top(c1, 2) from test.meters;"
|
||||||
|
"select twa(c6) from test.t1 where ts > 1500000001000 and ts < 1500000101000" ,
|
||||||
|
"select avg(c6) from test.meters;",
|
||||||
|
"select bottom(c6, 2) from test.t1;",
|
||||||
|
"select diff(c6) from test.t1;",
|
||||||
|
"select leastsquares(c6, 1, 1) from test.t1 ;",
|
||||||
|
"select max(c6) from test.meters;",
|
||||||
|
"select min(c6) from test.meters;",
|
||||||
|
"select c6 + c2 * c3 + c6 / c5 + c4 + c2 from test.t1;",
|
||||||
|
"select percentile(c6, 50) from test.t1;",
|
||||||
|
"select spread(c6) from test.t1 ;",
|
||||||
|
"select stddev(c6) from test.t1;",
|
||||||
|
"select sum(c6) from test.meters;",
|
||||||
|
"select top(c6, 2) from test.meters;",
|
||||||
|
# second supertable
|
||||||
|
"select count(*) from test.meters1 where c1 > 50;",
|
||||||
|
"select count(*) from test.meters1 where c2 >= 50 and c2 < 100;",
|
||||||
|
"select count(*) from test.meters1 where c3 != 5;",
|
||||||
|
"select count(*) from test.meters1 where t3 > 2;",
|
||||||
|
"select count(*) from test.meters1 where ts <> '2020-05-13 10:00:00.002';",
|
||||||
|
"select count(*) from test.meters1 where t7 like 'fi%';",
|
||||||
|
"select count(*) from test.meters1 where t7 like '_econd';",
|
||||||
|
"select count(*) from test.meters1 interval(1n) order by ts desc;",
|
||||||
|
"select first(*) from test.meters1;",
|
||||||
|
"select last(*) from test.meters1;",
|
||||||
|
"select last_row(*) from test.meters1;",
|
||||||
|
"select twa(c1) from test.m1 where ts > 1500000001000 and ts < 1500000101000" ,
|
||||||
|
"select avg(c1) from test.meters1;",
|
||||||
|
"select bottom(c1, 2) from test.m1;",
|
||||||
|
"select diff(c1) from test.m1;",
|
||||||
|
"select leastsquares(c1, 1, 1) from test.m1 ;",
|
||||||
|
"select max(c1) from test.meters1;",
|
||||||
|
"select min(c1) from test.meters1;",
|
||||||
|
"select c1 + c2 * c3 + c1 / c5 + c3 + c2 from test.m1;",
|
||||||
|
"select percentile(c1, 50) from test.m1;",
|
||||||
|
"select spread(c1) from test.m1 ;",
|
||||||
|
"select stddev(c1) from test.m1;",
|
||||||
|
"select sum(c1) from test.meters1;",
|
||||||
|
"select top(c1, 2) from test.meters1;",
|
||||||
|
"select twa(c6) from test.m1 where ts > 1500000001000 and ts < 1500000101000" ,
|
||||||
|
"select avg(c6) from test.meters1;",
|
||||||
|
"select bottom(c6, 2) from test.m1;",
|
||||||
|
"select diff(c6) from test.m1;",
|
||||||
|
"select leastsquares(c6, 1, 1) from test.m1 ;",
|
||||||
|
"select max(c6) from test.meters1;",
|
||||||
|
"select min(c6) from test.meters1;",
|
||||||
|
"select c6 + c2 * c3 + c6 / c5 + c3 + c2 from test.m1;",
|
||||||
|
"select percentile(c6, 50) from test.m1;",
|
||||||
|
"select spread(c6) from test.m1 ;",
|
||||||
|
"select stddev(c6) from test.m1;",
|
||||||
|
"select sum(c6) from test.meters1;",
|
||||||
|
"select top(c6, 2) from test.meters1;"
|
||||||
|
]
|
||||||
|
|
||||||
|
class ConcurrentInquiry:
|
||||||
|
def initConnection(self):
|
||||||
|
self.numOfTherads = 50
|
||||||
|
self.ts=1500000001000
|
||||||
|
|
||||||
|
|
||||||
|
def query_thread(self,threadID):
|
||||||
|
host = "10.211.55.14"
|
||||||
|
user = "root"
|
||||||
|
password = "taosdata"
|
||||||
|
conn = taos.connect(
|
||||||
|
host,
|
||||||
|
user,
|
||||||
|
password,
|
||||||
|
)
|
||||||
|
cl = conn.cursor()
|
||||||
|
|
||||||
|
print("Thread %d: starting" % threadID)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
ran_query_sql=query_sql
|
||||||
|
random.shuffle(ran_query_sql)
|
||||||
|
for i in ran_query_sql:
|
||||||
|
print("Thread %d : %s"% (threadID,i))
|
||||||
|
try:
|
||||||
|
cl.execute(i)
|
||||||
|
cl.fetchall
|
||||||
|
except Exception as e:
|
||||||
|
print(
|
||||||
|
"Failure thread%d, sql: %s,exception: %s" %
|
||||||
|
(threadID, str(i),str(e)))
|
||||||
|
|
||||||
|
|
||||||
|
print("Thread %d: finishing" % threadID)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
threads = []
|
||||||
|
for i in range(50):
|
||||||
|
thread = threading.Thread(target=self.query_thread, args=(i,))
|
||||||
|
threads.append(thread)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
q = ConcurrentInquiry()
|
||||||
|
q.initConnection()
|
||||||
|
q.run()
|
|
@ -35,18 +35,45 @@ CURR_DIR=`pwd`
|
||||||
IN_TDINTERNAL="community"
|
IN_TDINTERNAL="community"
|
||||||
if [[ "$CURR_DIR" == *"$IN_TDINTERNAL"* ]]; then
|
if [[ "$CURR_DIR" == *"$IN_TDINTERNAL"* ]]; then
|
||||||
TAOS_DIR=$CURR_DIR/../../..
|
TAOS_DIR=$CURR_DIR/../../..
|
||||||
|
TAOSD_DIR=`find $TAOS_DIR -name "taosd"|grep bin|head -n1`
|
||||||
|
LIB_DIR=`echo $TAOSD_DIR|rev|cut -d '/' -f 3,4,5,6,7|rev`/lib
|
||||||
else
|
else
|
||||||
TAOS_DIR=$CURR_DIR/../..
|
TAOS_DIR=$CURR_DIR/../..
|
||||||
|
TAOSD_DIR=`find $TAOS_DIR -name "taosd"|grep bin|head -n1`
|
||||||
|
LIB_DIR=`echo $TAOSD_DIR|rev|cut -d '/' -f 3,4,5,6|rev`/lib
|
||||||
fi
|
fi
|
||||||
TAOSD_DIR=`find $TAOS_DIR -name "taosd"|grep bin|head -n1`
|
|
||||||
|
|
||||||
LIB_DIR=`echo $TAOSD_DIR|rev|cut -d '/' -f 3,4,5,6|rev`/lib
|
# Now getting ready to execute Python
|
||||||
|
# The following is the default of our standard dev env (Ubuntu 20.04), modify/adjust at your own risk
|
||||||
|
PYTHON_EXEC=python3.8
|
||||||
|
|
||||||
# First we need to set up a path for Python to find our own TAOS modules, so that "import" can work.
|
# First we need to set up a path for Python to find our own TAOS modules, so that "import" can work.
|
||||||
export PYTHONPATH=$(pwd)/../../src/connector/python/linux/python3
|
export PYTHONPATH=$(pwd)/../../src/connector/python/linux/python3:$(pwd)
|
||||||
|
|
||||||
# Then let us set up the library path so that our compiled SO file can be loaded by Python
|
# Then let us set up the library path so that our compiled SO file can be loaded by Python
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIB_DIR
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIB_DIR
|
||||||
|
|
||||||
# Now we are all let, and let's see if we can find a crash. Note we pass all params
|
# Now we are all let, and let's see if we can find a crash. Note we pass all params
|
||||||
python3.8 ./crash_gen.py $@
|
if [[ $1 == '--valgrind' ]]; then
|
||||||
|
shift
|
||||||
|
export PYTHONMALLOC=malloc
|
||||||
|
VALGRIND_OUT=valgrind.out
|
||||||
|
VALGRIND_ERR=valgrind.err
|
||||||
|
# How to generate valgrind suppression file: https://stackoverflow.com/questions/17159578/generating-suppressions-for-memory-leaks
|
||||||
|
# valgrind --leak-check=full --gen-suppressions=all --log-fd=9 python3.8 ./crash_gen.py $@ 9>>memcheck.log
|
||||||
|
echo Executing under VALGRIND, with STDOUT/ERR going to $VALGRIND_OUT and $VALGRIND_ERR, please watch them from a different terminal.
|
||||||
|
valgrind \
|
||||||
|
--leak-check=yes \
|
||||||
|
--suppressions=crash_gen/valgrind_taos.supp \
|
||||||
|
$PYTHON_EXEC \
|
||||||
|
./crash_gen/crash_gen.py $@ > $VALGRIND_OUT 2> $VALGRIND_ERR
|
||||||
|
elif [[ $1 == '--helgrind' ]]; then
|
||||||
|
shift
|
||||||
|
valgrind \
|
||||||
|
--tool=helgrind \
|
||||||
|
$PYTHON_EXEC \
|
||||||
|
./crash_gen/crash_gen.py $@
|
||||||
|
else
|
||||||
|
$PYTHON_EXEC ./crash_gen/crash_gen.py $@
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -172,23 +172,23 @@ python3 testNoCompress.py
|
||||||
python3 testMinTablesPerVnode.py
|
python3 testMinTablesPerVnode.py
|
||||||
|
|
||||||
# functions
|
# functions
|
||||||
python3 ./test.py -f functions/function_avg.py
|
python3 ./test.py -f functions/function_avg.py -r 1
|
||||||
python3 ./test.py -f functions/function_bottom.py
|
python3 ./test.py -f functions/function_bottom.py -r 1
|
||||||
python3 ./test.py -f functions/function_count.py
|
python3 ./test.py -f functions/function_count.py -r 1
|
||||||
python3 ./test.py -f functions/function_diff.py
|
python3 ./test.py -f functions/function_diff.py -r 1
|
||||||
python3 ./test.py -f functions/function_first.py
|
python3 ./test.py -f functions/function_first.py -r 1
|
||||||
python3 ./test.py -f functions/function_last.py
|
python3 ./test.py -f functions/function_last.py -r 1
|
||||||
python3 ./test.py -f functions/function_last_row.py
|
python3 ./test.py -f functions/function_last_row.py -r 1
|
||||||
python3 ./test.py -f functions/function_leastsquares.py
|
python3 ./test.py -f functions/function_leastsquares.py -r 1
|
||||||
python3 ./test.py -f functions/function_max.py
|
python3 ./test.py -f functions/function_max.py -r 1
|
||||||
python3 ./test.py -f functions/function_min.py
|
python3 ./test.py -f functions/function_min.py -r 1
|
||||||
python3 ./test.py -f functions/function_operations.py
|
python3 ./test.py -f functions/function_operations.py -r 1
|
||||||
python3 ./test.py -f functions/function_percentile.py
|
python3 ./test.py -f functions/function_percentile.py
|
||||||
python3 ./test.py -f functions/function_spread.py
|
python3 ./test.py -f functions/function_spread.py -r 1
|
||||||
python3 ./test.py -f functions/function_stddev.py
|
python3 ./test.py -f functions/function_stddev.py -r 1
|
||||||
python3 ./test.py -f functions/function_sum.py
|
python3 ./test.py -f functions/function_sum.py -r 1
|
||||||
python3 ./test.py -f functions/function_top.py
|
python3 ./test.py -f functions/function_top.py -r 1
|
||||||
#python3 ./test.py -f functions/function_twa.py
|
#python3 ./test.py -f functions/function_twa.py -r 1
|
||||||
python3 queryCount.py
|
python3 queryCount.py
|
||||||
python3 ./test.py -f query/queryGroupbyWithInterval.py
|
python3 ./test.py -f query/queryGroupbyWithInterval.py
|
||||||
python3 client/twoClients.py
|
python3 client/twoClients.py
|
||||||
|
@ -200,4 +200,4 @@ python3 test.py -f tools/taosdemo.py
|
||||||
# subscribe
|
# subscribe
|
||||||
python3 test.py -f subscribe/singlemeter.py
|
python3 test.py -f subscribe/singlemeter.py
|
||||||
#python3 test.py -f subscribe/stability.py
|
#python3 test.py -f subscribe/stability.py
|
||||||
python3 test.py -f subscribe/supertable.py
|
python3 test.py -f subscribe/supertable.py
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import taos
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
|
||||||
|
self.rowNum = 10
|
||||||
|
self.ts = 1537146000000
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.execute("use db")
|
||||||
|
|
||||||
|
intData = []
|
||||||
|
floatData = []
|
||||||
|
|
||||||
|
#tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
|
# col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
|
#tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
|
for i in range(self.rowNum):
|
||||||
|
#tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
|
# % (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
|
intData.append(i + 1)
|
||||||
|
floatData.append(i + 0.1)
|
||||||
|
|
||||||
|
# average verifacation
|
||||||
|
tdSql.error("select avg(ts) from test")
|
||||||
|
tdSql.error("select avg(ts) from test1")
|
||||||
|
tdSql.error("select avg(col7) from test")
|
||||||
|
tdSql.error("select avg(col7) from test1")
|
||||||
|
tdSql.error("select avg(col8) from test")
|
||||||
|
tdSql.error("select avg(col8) from test1")
|
||||||
|
tdSql.error("select avg(col9) from test")
|
||||||
|
tdSql.error("select avg(col9) from test1")
|
||||||
|
|
||||||
|
tdSql.query("select avg(col1) from test")
|
||||||
|
tdSql.checkData(0, 0, np.average(intData))
|
||||||
|
tdSql.query("select avg(col2) from test")
|
||||||
|
tdSql.checkData(0, 0, np.average(intData))
|
||||||
|
tdSql.query("select avg(col3) from test")
|
||||||
|
tdSql.checkData(0, 0, np.average(intData))
|
||||||
|
tdSql.query("select avg(col4) from test")
|
||||||
|
tdSql.checkData(0, 0, np.average(intData))
|
||||||
|
tdSql.query("select avg(col5) from test")
|
||||||
|
tdSql.checkData(0, 0, np.average(floatData))
|
||||||
|
tdSql.query("select avg(col6) from test")
|
||||||
|
tdSql.checkData(0, 0, np.average(floatData))
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue