提交 e28d6599 编写于 作者: Z zyyang

Merge branch 'develop' into feature/TD-2271

...@@ -15,6 +15,7 @@ SET(TD_ADMIN FALSE) ...@@ -15,6 +15,7 @@ SET(TD_ADMIN FALSE)
SET(TD_GRANT FALSE) SET(TD_GRANT FALSE)
SET(TD_MQTT FALSE) SET(TD_MQTT FALSE)
SET(TD_TSDB_PLUGINS FALSE) SET(TD_TSDB_PLUGINS FALSE)
SET(TD_STORAGE FALSE)
SET(TD_COVER FALSE) SET(TD_COVER FALSE)
SET(TD_MEM_CHECK FALSE) SET(TD_MEM_CHECK FALSE)
......
...@@ -45,6 +45,7 @@ def pre_test(){ ...@@ -45,6 +45,7 @@ def pre_test(){
git pull git pull
git fetch origin +refs/pull/${CHANGE_ID}/merge git fetch origin +refs/pull/${CHANGE_ID}/merge
git checkout -qf FETCH_HEAD git checkout -qf FETCH_HEAD
git --no-pager diff --name-only FETCH_HEAD $(git merge-base FETCH_HEAD develop)|grep -v -E '.*md|//src//connector|Jenkinsfile' || exit 0
cd ${WK} cd ${WK}
git reset --hard HEAD~10 git reset --hard HEAD~10
git checkout develop git checkout develop
...@@ -79,13 +80,14 @@ pipeline { ...@@ -79,13 +80,14 @@ pipeline {
changeRequest() changeRequest()
} }
parallel { parallel {
stage('python_1') { stage('python_1_s1') {
agent{label 'p1'} agent{label 'p1'}
steps { steps {
pre_test() pre_test()
timeout(time: 90, unit: 'MINUTES'){ timeout(time: 45, unit: 'MINUTES'){
sh ''' sh '''
date
cd ${WKC}/tests cd ${WKC}/tests
find pytest -name '*'sql|xargs rm -rf find pytest -name '*'sql|xargs rm -rf
./test-all.sh p1 ./test-all.sh p1
...@@ -94,23 +96,35 @@ pipeline { ...@@ -94,23 +96,35 @@ pipeline {
} }
} }
stage('python_2') { stage('python_2_s5') {
agent{label 'p2'} agent{label 'p2'}
steps { steps {
pre_test() pre_test()
timeout(time: 45, unit: 'MINUTES'){
sh ''' sh '''
date
cd ${WKC}/tests cd ${WKC}/tests
find pytest -name '*'sql|xargs rm -rf find pytest -name '*'sql|xargs rm -rf
./test-all.sh p2 ./test-all.sh p2
date''' date'''
sh ''' }
cd ${WKC}/tests }
./test-all.sh b4fq }
''' stage('python_3_s6') {
agent{label 'p3'}
steps {
timeout(time: 45, unit: 'MINUTES'){
pre_test()
sh '''
date
cd ${WKC}/tests
./test-all.sh p3
date'''
}
} }
} }
stage('test_b1') { stage('test_b1_s2') {
agent{label 'b1'} agent{label 'b1'}
steps { steps {
timeout(time: 90, unit: 'MINUTES'){ timeout(time: 90, unit: 'MINUTES'){
...@@ -123,7 +137,7 @@ pipeline { ...@@ -123,7 +137,7 @@ pipeline {
} }
} }
stage('test_crash_gen') { stage('test_crash_gen_s3') {
agent{label "b2"} agent{label "b2"}
steps { steps {
pre_test() pre_test()
...@@ -139,7 +153,7 @@ pipeline { ...@@ -139,7 +153,7 @@ pipeline {
./handle_crash_gen_val_log.sh ./handle_crash_gen_val_log.sh
''' '''
} }
timeout(time: 90, unit: 'MINUTES'){ timeout(time: 45, unit: 'MINUTES'){
sh ''' sh '''
date date
cd ${WKC}/tests cd ${WKC}/tests
...@@ -150,7 +164,7 @@ pipeline { ...@@ -150,7 +164,7 @@ pipeline {
} }
} }
stage('test_valgrind') { stage('test_valgrind_s4') {
agent{label "b3"} agent{label "b3"}
steps { steps {
...@@ -162,7 +176,7 @@ pipeline { ...@@ -162,7 +176,7 @@ pipeline {
./handle_val_log.sh ./handle_val_log.sh
''' '''
} }
timeout(time: 90, unit: 'MINUTES'){ timeout(time: 45, unit: 'MINUTES'){
sh ''' sh '''
date date
cd ${WKC}/tests cd ${WKC}/tests
...@@ -171,8 +185,58 @@ pipeline { ...@@ -171,8 +185,58 @@ pipeline {
} }
} }
} }
stage('test_b4_s7') {
agent{label 'b4'}
steps {
timeout(time: 45, unit: 'MINUTES'){
pre_test()
sh '''
date
cd ${WKC}/tests
./test-all.sh b4fq
date'''
}
}
}
stage('test_b5_s8') {
agent{label 'b5'}
steps {
timeout(time: 45, unit: 'MINUTES'){
pre_test()
sh '''
date
cd ${WKC}/tests
./test-all.sh b5fq
date'''
}
}
}
stage('test_b6_s9') {
agent{label 'b6'}
steps {
timeout(time: 45, unit: 'MINUTES'){
pre_test()
sh '''
date
cd ${WKC}/tests
./test-all.sh b6fq
date'''
}
}
}
stage('test_b7_s10') {
agent{label 'b7'}
steps {
timeout(time: 45, unit: 'MINUTES'){
pre_test()
sh '''
date
cd ${WKC}/tests
./test-all.sh b7fq
date'''
}
}
}
} }
} }
} }
......
...@@ -21,6 +21,10 @@ IF (TD_TSDB_PLUGINS) ...@@ -21,6 +21,10 @@ IF (TD_TSDB_PLUGINS)
ADD_DEFINITIONS(-D_TSDB_PLUGINS) ADD_DEFINITIONS(-D_TSDB_PLUGINS)
ENDIF () ENDIF ()
IF (TD_STORAGE)
ADD_DEFINITIONS(-D_STORAGE)
ENDIF ()
IF (TD_GODLL) IF (TD_GODLL)
ADD_DEFINITIONS(-D_TD_GO_DLL_) ADD_DEFINITIONS(-D_TD_GO_DLL_)
ENDIF () ENDIF ()
......
...@@ -9,6 +9,7 @@ ADD_SUBDIRECTORY(lz4) ...@@ -9,6 +9,7 @@ ADD_SUBDIRECTORY(lz4)
ADD_SUBDIRECTORY(cJson) ADD_SUBDIRECTORY(cJson)
ADD_SUBDIRECTORY(wepoll) ADD_SUBDIRECTORY(wepoll)
ADD_SUBDIRECTORY(MsvcLibX) ADD_SUBDIRECTORY(MsvcLibX)
ADD_SUBDIRECTORY(rmonotonic)
IF (TD_LINUX AND TD_MQTT) IF (TD_LINUX AND TD_MQTT)
ADD_SUBDIRECTORY(MQTT-C) ADD_SUBDIRECTORY(MQTT-C)
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
typedef int clockid_t; typedef int clockid_t;
/* Supported values for clockid_t */ /* Supported values for clockid_t */
#define CLOCK_REALTIME 0 #define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
int clock_gettime(clockid_t clock_id, struct timespec *tp); int clock_gettime(clockid_t clock_id, struct timespec *tp);
......
...@@ -34,15 +34,56 @@ ...@@ -34,15 +34,56 @@
#include "msvcTime.h" #include "msvcTime.h"
#include "sys/msvcStat.h" /* For MsvcLibX's Filetime2Timespec */ #include "sys/msvcStat.h" /* For MsvcLibX's Filetime2Timespec */
int clock_gettime(clockid_t clock_id, struct timespec *pTS) { #define MS_PER_SEC 1000ULL // MS = milliseconds
FILETIME ft; #define US_PER_MS 1000ULL // US = microseconds
if (clock_id != CLOCK_REALTIME) { #define HNS_PER_US 10ULL // HNS = hundred-nanoseconds (e.g., 1 hns = 100 ns)
errno = EINVAL; #define NS_PER_US 1000ULL
return -1;
#define HNS_PER_SEC (MS_PER_SEC * US_PER_MS * HNS_PER_US)
#define NS_PER_HNS (100ULL) // NS = nanoseconds
#define NS_PER_SEC (MS_PER_SEC * US_PER_MS * NS_PER_US)
int clock_gettime_monotonic(struct timespec *tv) {
static LARGE_INTEGER ticksPerSec;
LARGE_INTEGER ticks;
double seconds;
if (!ticksPerSec.QuadPart) {
QueryPerformanceFrequency(&ticksPerSec);
if (!ticksPerSec.QuadPart) {
errno = ENOTSUP;
return -1;
}
} }
QueryPerformanceCounter(&ticks);
seconds = (double) ticks.QuadPart / (double) ticksPerSec.QuadPart;
tv->tv_sec = (time_t)seconds;
tv->tv_nsec = (long)((ULONGLONG)(seconds * NS_PER_SEC) % NS_PER_SEC);
return 0;
}
int clock_gettime_realtime(struct timespec *pTS) {
FILETIME ft;
GetSystemTimeAsFileTime(&ft); GetSystemTimeAsFileTime(&ft);
Filetime2Timespec(&ft, pTS); Filetime2Timespec(&ft, pTS);
return 0; return 0;
} }
int clock_gettime(clockid_t clock_id, struct timespec *pTS) {
if (clock_id == CLOCK_MONOTONIC) {
return clock_gettime_monotonic(pTS);
} else if (clock_id == CLOCK_REALTIME) {
return clock_gettime_realtime(pTS);
}
errno = ENOTSUP;
return -1;
}
#endif /* defined(_WIN32) */ #endif /* defined(_WIN32) */
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src SOURCE_LIST)
add_definitions(-DUSE_PROCESSOR_CLOCK)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../MsvcLibX/include)
ADD_LIBRARY(rmonotonic ${SOURCE_LIST})
TARGET_INCLUDE_DIRECTORIES(rmonotonic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc)
IF (TD_WINDOWS)
TARGET_LINK_LIBRARIES(rmonotonic MsvcLibXw)
ENDIF ()
#ifndef __MONOTONIC_H
#define __MONOTONIC_H
/* The monotonic clock is an always increasing clock source. It is unrelated to
* the actual time of day and should only be used for relative timings. The
* monotonic clock is also not guaranteed to be chronologically precise; there
* may be slight skew/shift from a precise clock.
*
* Depending on system architecture, the monotonic time may be able to be
* retrieved much faster than a normal clock source by using an instruction
* counter on the CPU. On x86 architectures (for example), the RDTSC
* instruction is a very fast clock source for this purpose.
*/
//#include "fmacros.h"
#include <stdint.h>
//#include <unistd.h>
#if defined(_WIN32) || defined(_WIN64)
#define inline
#endif
/* A counter in micro-seconds. The 'monotime' type is provided for variables
* holding a monotonic time. This will help distinguish & document that the
* variable is associated with the monotonic clock and should not be confused
* with other types of time.*/
typedef uint64_t monotime;
/* Retrieve counter of micro-seconds relative to an arbitrary point in time. */
extern monotime (*getMonotonicUs)(void);
/* Call once at startup to initialize the monotonic clock. Though this only
* needs to be called once, it may be called additional times without impact.
* Returns a printable string indicating the type of clock initialized.
* (The returned string is static and doesn't need to be freed.) */
const char * monotonicInit();
/* Functions to measure elapsed time. Example:
* monotime myTimer;
* elapsedStart(&myTimer);
* while (elapsedMs(myTimer) < 10) {} // loops for 10ms
*/
static inline void elapsedStart(monotime *start_time) {
*start_time = getMonotonicUs();
}
static inline uint64_t elapsedUs(monotime start_time) {
return getMonotonicUs() - start_time;
}
static inline uint64_t elapsedMs(monotime start_time) {
return elapsedUs(start_time) / 1000;
}
#endif
#include "monotonic.h"
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#undef NDEBUG
#include <assert.h>
#if defined(_WIN32) || defined(_WIN64)
#include "msvcTime.h"
#include "msvcStdio.h"
#endif
/* The function pointer for clock retrieval. */
monotime (*getMonotonicUs)(void) = NULL;
static char monotonic_info_string[32];
/* Using the processor clock (aka TSC on x86) can provide improved performance
* throughout Redis wherever the monotonic clock is used. The processor clock
* is significantly faster than calling 'clock_getting' (POSIX). While this is
* generally safe on modern systems, this link provides additional information
* about use of the x86 TSC: http://oliveryang.net/2015/09/pitfalls-of-TSC-usage
*
* To use the processor clock, either uncomment this line, or build with
* CFLAGS="-DUSE_PROCESSOR_CLOCK"
#define USE_PROCESSOR_CLOCK
*/
#if defined(USE_PROCESSOR_CLOCK) && defined(__x86_64__) && defined(__linux__)
#include <regex.h>
#include <x86intrin.h>
static long mono_ticksPerMicrosecond = 0;
static monotime getMonotonicUs_x86() {
return __rdtsc() / mono_ticksPerMicrosecond;
}
static void monotonicInit_x86linux() {
const int bufflen = 256;
char buf[bufflen];
regex_t cpuGhzRegex, constTscRegex;
const size_t nmatch = 2;
regmatch_t pmatch[nmatch];
int constantTsc = 0;
int rc;
/* Determine the number of TSC ticks in a micro-second. This is
* a constant value matching the standard speed of the processor.
* On modern processors, this speed remains constant even though
* the actual clock speed varies dynamically for each core. */
rc = regcomp(&cpuGhzRegex, "^model name\\s+:.*@ ([0-9.]+)GHz", REG_EXTENDED);
assert(rc == 0);
/* Also check that the constant_tsc flag is present. (It should be
* unless this is a really old CPU. */
rc = regcomp(&constTscRegex, "^flags\\s+:.* constant_tsc", REG_EXTENDED);
assert(rc == 0);
FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
if (cpuinfo != NULL) {
while (fgets(buf, bufflen, cpuinfo) != NULL) {
if (regexec(&cpuGhzRegex, buf, nmatch, pmatch, 0) == 0) {
buf[pmatch[1].rm_eo] = '\0';
double ghz = atof(&buf[pmatch[1].rm_so]);
mono_ticksPerMicrosecond = (long)(ghz * 1000);
break;
}
}
while (fgets(buf, bufflen, cpuinfo) != NULL) {
if (regexec(&constTscRegex, buf, nmatch, pmatch, 0) == 0) {
constantTsc = 1;
break;
}
}
fclose(cpuinfo);
}
regfree(&cpuGhzRegex);
regfree(&constTscRegex);
if (mono_ticksPerMicrosecond == 0) {
fprintf(stderr, "monotonic: x86 linux, unable to determine clock rate");
return;
}
if (!constantTsc) {
fprintf(stderr, "monotonic: x86 linux, 'constant_tsc' flag not present");
return;
}
snprintf(monotonic_info_string, sizeof(monotonic_info_string),
"X86 TSC @ %ld ticks/us", mono_ticksPerMicrosecond);
getMonotonicUs = getMonotonicUs_x86;
}
#endif
#if defined(USE_PROCESSOR_CLOCK) && defined(__aarch64__)
static long mono_ticksPerMicrosecond = 0;
/* Read the clock value. */
static inline uint64_t __cntvct() {
uint64_t virtual_timer_value;
__asm__ volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
return virtual_timer_value;
}
/* Read the Count-timer Frequency. */
static inline uint32_t cntfrq_hz() {
uint64_t virtual_freq_value;
__asm__ volatile("mrs %0, cntfrq_el0" : "=r"(virtual_freq_value));
return (uint32_t)virtual_freq_value; /* top 32 bits are reserved */
}
static monotime getMonotonicUs_aarch64() {
return __cntvct() / mono_ticksPerMicrosecond;
}
static void monotonicInit_aarch64() {
mono_ticksPerMicrosecond = (long)cntfrq_hz() / 1000L / 1000L;
if (mono_ticksPerMicrosecond == 0) {
fprintf(stderr, "monotonic: aarch64, unable to determine clock rate");
return;
}
snprintf(monotonic_info_string, sizeof(monotonic_info_string),
"ARM CNTVCT @ %ld ticks/us", mono_ticksPerMicrosecond);
getMonotonicUs = getMonotonicUs_aarch64;
}
#endif
static monotime getMonotonicUs_posix(void) {
/* clock_gettime() is specified in POSIX.1b (1993). Even so, some systems
* did not support this until much later. CLOCK_MONOTONIC is technically
* optional and may not be supported - but it appears to be universal.
* If this is not supported, provide a system-specific alternate version. */
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ((uint64_t)ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;
}
static void monotonicInit_posix() {
/* Ensure that CLOCK_MONOTONIC is supported. This should be supported
* on any reasonably current OS. If the assertion below fails, provide
* an appropriate alternate implementation. */
struct timespec ts;
int rc = clock_gettime(CLOCK_MONOTONIC, &ts);
assert(rc == 0);
snprintf(monotonic_info_string, sizeof(monotonic_info_string),
"POSIX clock_gettime");
getMonotonicUs = getMonotonicUs_posix;
}
const char * monotonicInit() {
#if defined(USE_PROCESSOR_CLOCK) && defined(__x86_64__) && defined(__linux__)
if (getMonotonicUs == NULL) monotonicInit_x86linux();
#endif
#if defined(USE_PROCESSOR_CLOCK) && defined(__aarch64__)
if (getMonotonicUs == NULL) monotonicInit_aarch64();
#endif
if (getMonotonicUs == NULL) monotonicInit_posix();
return monotonic_info_string;
}
...@@ -270,3 +270,9 @@ ...@@ -270,3 +270,9 @@
# in retrieve blocking model, only in 50% query threads will be used in query processing in dnode # in retrieve blocking model, only in 50% query threads will be used in query processing in dnode
# retrieveBlockingModel 0 # retrieveBlockingModel 0
# the maximum allowed query buffer size in MB during query processing for each data node
# -1 no limit (default)
# 0 no query allowed, queries are disabled
# queryBufferSize -1
...@@ -47,6 +47,9 @@ cp ${compile_dir}/../packaging/cfg/taos.cfg ${pkg_dir}${install_home_pat ...@@ -47,6 +47,9 @@ cp ${compile_dir}/../packaging/cfg/taos.cfg ${pkg_dir}${install_home_pat
cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d
cp ${compile_dir}/../packaging/tools/post.sh ${pkg_dir}${install_home_path}/script cp ${compile_dir}/../packaging/tools/post.sh ${pkg_dir}${install_home_path}/script
cp ${compile_dir}/../packaging/tools/preun.sh ${pkg_dir}${install_home_path}/script cp ${compile_dir}/../packaging/tools/preun.sh ${pkg_dir}${install_home_path}/script
cp ${compile_dir}/../packaging/tools/startPre.sh ${pkg_dir}${install_home_path}/bin
cp ${compile_dir}/../packaging/tools/set_core.sh ${pkg_dir}${install_home_path}/bin
cp ${compile_dir}/../packaging/tools/taosd-dump-cfg.gdb ${pkg_dir}${install_home_path}/bin
cp ${compile_dir}/build/bin/taosdemo ${pkg_dir}${install_home_path}/bin cp ${compile_dir}/build/bin/taosdemo ${pkg_dir}${install_home_path}/bin
cp ${compile_dir}/build/bin/taosdemox ${pkg_dir}${install_home_path}/bin cp ${compile_dir}/build/bin/taosdemox ${pkg_dir}${install_home_path}/bin
cp ${compile_dir}/build/bin/taosdump ${pkg_dir}${install_home_path}/bin cp ${compile_dir}/build/bin/taosdump ${pkg_dir}${install_home_path}/bin
......
...@@ -55,6 +55,9 @@ cp %{_compiledir}/../packaging/cfg/taos.cfg %{buildroot}%{homepath}/cfg ...@@ -55,6 +55,9 @@ cp %{_compiledir}/../packaging/cfg/taos.cfg %{buildroot}%{homepath}/cfg
cp %{_compiledir}/../packaging/rpm/taosd %{buildroot}%{homepath}/init.d cp %{_compiledir}/../packaging/rpm/taosd %{buildroot}%{homepath}/init.d
cp %{_compiledir}/../packaging/tools/post.sh %{buildroot}%{homepath}/script cp %{_compiledir}/../packaging/tools/post.sh %{buildroot}%{homepath}/script
cp %{_compiledir}/../packaging/tools/preun.sh %{buildroot}%{homepath}/script cp %{_compiledir}/../packaging/tools/preun.sh %{buildroot}%{homepath}/script
cp %{_compiledir}/../packaging/tools/startPre.sh %{buildroot}%{homepath}/bin
cp %{_compiledir}/../packaging/tools/set_core.sh %{buildroot}%{homepath}/bin
cp %{_compiledir}/../packaging/tools/taosd-dump-cfg.gdb %{buildroot}%{homepath}/bin
cp %{_compiledir}/build/bin/taos %{buildroot}%{homepath}/bin cp %{_compiledir}/build/bin/taos %{buildroot}%{homepath}/bin
cp %{_compiledir}/build/bin/taosd %{buildroot}%{homepath}/bin cp %{_compiledir}/build/bin/taosd %{buildroot}%{homepath}/bin
cp %{_compiledir}/build/bin/taosdemo %{buildroot}%{homepath}/bin cp %{_compiledir}/build/bin/taosdemo %{buildroot}%{homepath}/bin
......
...@@ -168,6 +168,7 @@ function install_main_path() { ...@@ -168,6 +168,7 @@ function install_main_path() {
if [ "$verMode" == "cluster" ]; then if [ "$verMode" == "cluster" ]; then
${csudo} mkdir -p ${nginx_dir} ${csudo} mkdir -p ${nginx_dir}
fi fi
${csudo} cp ${script_dir}/email ${install_main_dir}/ ||:
} }
function install_bin() { function install_bin() {
...@@ -604,9 +605,7 @@ function install_service_on_systemd() { ...@@ -604,9 +605,7 @@ function install_service_on_systemd() {
${csudo} bash -c "echo '[Service]' >> ${taosd_service_config}" ${csudo} bash -c "echo '[Service]' >> ${taosd_service_config}"
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}" ${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
#${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/setDelay.sh' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
#${csudo} bash -c "echo 'ExecStartPost=/usr/local/taos/bin/resetDelay.sh' >> ${taosd_service_config}"
#${csudo} bash -c "echo 'ExecStopPost=/usr/local/taos/bin/resetDelay.sh' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
......
...@@ -578,6 +578,7 @@ function install_service_on_systemd() { ...@@ -578,6 +578,7 @@ function install_service_on_systemd() {
${csudo} bash -c "echo '[Service]' >> ${powerd_service_config}" ${csudo} bash -c "echo '[Service]' >> ${powerd_service_config}"
${csudo} bash -c "echo 'Type=simple' >> ${powerd_service_config}" ${csudo} bash -c "echo 'Type=simple' >> ${powerd_service_config}"
${csudo} bash -c "echo 'ExecStart=/usr/bin/powerd' >> ${powerd_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/powerd' >> ${powerd_service_config}"
${csudo} bash -c "echo 'ExecStartPre=/usr/local/power/bin/startPre.sh' >> ${powerd_service_config}"
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${powerd_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${powerd_service_config}"
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${powerd_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${powerd_service_config}"
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${powerd_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${powerd_service_config}"
......
...@@ -149,10 +149,12 @@ function install_bin() { ...@@ -149,10 +149,12 @@ function install_bin() {
${csudo} rm -f ${bin_link_dir}/rmtaos || : ${csudo} rm -f ${bin_link_dir}/rmtaos || :
${csudo} cp -r ${binary_dir}/build/bin/* ${install_main_dir}/bin ${csudo} cp -r ${binary_dir}/build/bin/* ${install_main_dir}/bin
${csudo} cp -r ${script_dir}/taosd-dump-cfg.gdb ${install_main_dir}/bin
if [ "$osType" != "Darwin" ]; then if [ "$osType" != "Darwin" ]; then
${csudo} cp -r ${script_dir}/remove.sh ${install_main_dir}/bin ${csudo} cp -r ${script_dir}/remove.sh ${install_main_dir}/bin
${csudo} cp -r ${script_dir}/set_core.sh ${install_main_dir}/bin ${csudo} cp -r ${script_dir}/set_core.sh ${install_main_dir}/bin
${csudo} cp -r ${script_dir}/startPre.sh ${install_main_dir}/bin
else else
${csudo} cp -r ${script_dir}/remove_client.sh ${install_main_dir}/bin ${csudo} cp -r ${script_dir}/remove_client.sh ${install_main_dir}/bin
fi fi
...@@ -330,6 +332,7 @@ function install_service_on_systemd() { ...@@ -330,6 +332,7 @@ function install_service_on_systemd() {
${csudo} bash -c "echo '[Service]' >> ${taosd_service_config}" ${csudo} bash -c "echo '[Service]' >> ${taosd_service_config}"
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}" ${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
......
...@@ -45,7 +45,8 @@ if [ "$osType" != "Darwin" ]; then ...@@ -45,7 +45,8 @@ if [ "$osType" != "Darwin" ]; then
strip ${build_dir}/bin/taos strip ${build_dir}/bin/taos
bin_files="${build_dir}/bin/taos ${script_dir}/remove_client.sh" bin_files="${build_dir}/bin/taos ${script_dir}/remove_client.sh"
else else
bin_files="${build_dir}/bin/taos ${build_dir}/bin/taosdump ${build_dir}/bin/taosdemo ${build_dir}/bin/taosdemox ${script_dir}/remove_client.sh ${script_dir}/set_core.sh ${script_dir}/get_client.sh" bin_files="${build_dir}/bin/taos ${build_dir}/bin/taosdump ${build_dir}/bin/taosdemo ${build_dir}/bin/taosdemox\
${script_dir}/remove_client.sh ${script_dir}/set_core.sh ${script_dir}/get_client.sh ${script_dir}/taosd-dump-cfg.gdb"
fi fi
lib_files="${build_dir}/lib/libtaos.so.${version}" lib_files="${build_dir}/lib/libtaos.so.${version}"
else else
......
...@@ -81,6 +81,7 @@ if [ "$osType" != "Darwin" ]; then ...@@ -81,6 +81,7 @@ if [ "$osType" != "Darwin" ]; then
cp ${build_dir}/bin/taosdump ${install_dir}/bin/powerdump cp ${build_dir}/bin/taosdump ${install_dir}/bin/powerdump
cp ${script_dir}/set_core.sh ${install_dir}/bin cp ${script_dir}/set_core.sh ${install_dir}/bin
cp ${script_dir}/get_client.sh ${install_dir}/bin cp ${script_dir}/get_client.sh ${install_dir}/bin
cp ${script_dir}/taosd-dump-cfg.gdb ${install_dir}/bin
fi fi
else else
cp ${bin_files} ${install_dir}/bin cp ${bin_files} ${install_dir}/bin
......
...@@ -36,7 +36,8 @@ if [ "$pagMode" == "lite" ]; then ...@@ -36,7 +36,8 @@ if [ "$pagMode" == "lite" ]; then
strip ${build_dir}/bin/taos strip ${build_dir}/bin/taos
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${script_dir}/remove.sh" bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${script_dir}/remove.sh"
else else
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${build_dir}/bin/taosdump ${build_dir}/bin/taosdemo ${build_dir}/bin/taosdemox ${build_dir}/bin/tarbitrator ${script_dir}/remove.sh ${script_dir}/set_core.sh ${script_dir}/get_client.sh" bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${build_dir}/bin/taosdump ${build_dir}/bin/taosdemo ${build_dir}/bin/taosdemox ${build_dir}/bin/tarbitrator\
${script_dir}/remove.sh ${script_dir}/set_core.sh ${script_dir}/startPre.sh ${script_dir}/taosd-dump-cfg.gdb"
fi fi
lib_files="${build_dir}/lib/libtaos.so.${version}" lib_files="${build_dir}/lib/libtaos.so.${version}"
......
...@@ -36,7 +36,8 @@ fi ...@@ -36,7 +36,8 @@ fi
# strip ${build_dir}/bin/taos # strip ${build_dir}/bin/taos
# bin_files="${build_dir}/bin/powerd ${build_dir}/bin/power ${script_dir}/remove_power.sh" # bin_files="${build_dir}/bin/powerd ${build_dir}/bin/power ${script_dir}/remove_power.sh"
#else #else
# bin_files="${build_dir}/bin/powerd ${build_dir}/bin/power ${build_dir}/bin/powerdemo ${build_dir}/bin/tarbitrator ${script_dir}/remove_power.sh ${script_dir}/set_core.sh" # bin_files="${build_dir}/bin/powerd ${build_dir}/bin/power ${build_dir}/bin/powerdemo ${build_dir}/bin/tarbitrator ${script_dir}/remove_power.sh\
# ${script_dir}/set_core.sh ${script_dir}/startPre.sh ${script_dir}/taosd-dump-cfg.gdb"
#fi #fi
lib_files="${build_dir}/lib/libtaos.so.${version}" lib_files="${build_dir}/lib/libtaos.so.${version}"
...@@ -82,6 +83,8 @@ else ...@@ -82,6 +83,8 @@ else
cp ${build_dir}/bin/tarbitrator ${install_dir}/bin cp ${build_dir}/bin/tarbitrator ${install_dir}/bin
cp ${script_dir}/set_core.sh ${install_dir}/bin cp ${script_dir}/set_core.sh ${install_dir}/bin
cp ${script_dir}/get_client.sh ${install_dir}/bin cp ${script_dir}/get_client.sh ${install_dir}/bin
cp ${script_dir}/startPre.sh ${install_dir}/bin
cp ${script_dir}/taosd-dump-cfg.gdb ${install_dir}/bin
fi fi
chmod a+x ${install_dir}/bin/* || : chmod a+x ${install_dir}/bin/* || :
......
...@@ -406,6 +406,7 @@ function install_service_on_systemd() { ...@@ -406,6 +406,7 @@ function install_service_on_systemd() {
${csudo} bash -c "echo '[Service]' >> ${taosd_service_config}" ${csudo} bash -c "echo '[Service]' >> ${taosd_service_config}"
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}" ${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
......
#!/bin/bash
#
# if enable core dump, set start count to 3, disable core dump, set start count to 20.
# set -e
# set -x
taosd=/etc/systemd/system/taosd.service
line=`grep StartLimitBurst ${taosd}`
num=${line##*=}
#echo "burst num: ${num}"
startSeqFile=/usr/local/taos/.startSeq
recordFile=/usr/local/taos/.startRecord
startSeq=0
if [[ ! -e ${startSeqFile} ]]; then
startSeq=0
else
startSeq=$(cat ${startSeqFile})
fi
nextSeq=`expr $startSeq + 1`
echo "${nextSeq}" > ${startSeqFile}
curTime=$(date "+%Y-%m-%d %H:%M:%S")
echo "startSeq:${startSeq} startPre.sh exec ${curTime}, burstCnt:${num}" >> ${recordFile}
coreFlag=`ulimit -c`
echo "coreFlag: ${coreFlag}" >> ${recordFile}
if [ ${coreFlag} = "0" ];then
#echo "core is 0"
if [ ${num} != "20" ];then
sed -i "s/^.*StartLimitBurst.*$/StartLimitBurst=20/" ${taosd}
systemctl daemon-reload
echo "modify burst count from ${num} to 20" >> ${recordFile}
fi
fi
if [ ${coreFlag} = "unlimited" ];then
#echo "core is unlimited"
if [ ${num} != "3" ];then
sed -i "s/^.*StartLimitBurst.*$/StartLimitBurst=3/" ${taosd}
systemctl daemon-reload
echo "modify burst count from ${num} to 3" >> ${recordFile}
fi
fi
...@@ -5,6 +5,7 @@ PROJECT(TDengine) ...@@ -5,6 +5,7 @@ PROJECT(TDengine)
ADD_SUBDIRECTORY(os) ADD_SUBDIRECTORY(os)
ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(util) ADD_SUBDIRECTORY(util)
ADD_SUBDIRECTORY(tfs)
ADD_SUBDIRECTORY(rpc) ADD_SUBDIRECTORY(rpc)
ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(client)
ADD_SUBDIRECTORY(query) ADD_SUBDIRECTORY(query)
......
...@@ -3440,6 +3440,7 @@ static int32_t getTagCondString(tSQLExpr* pExpr, char** str) { ...@@ -3440,6 +3440,7 @@ static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) { static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
const char* msg0 = "invalid table name list"; const char* msg0 = "invalid table name list";
const char* msg1 = "not string following like";
if (pTableCond == NULL) { if (pTableCond == NULL) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -3457,6 +3458,10 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* ...@@ -3457,6 +3458,10 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
if (pTableCond->nSQLOptr == TK_IN) { if (pTableCond->nSQLOptr == TK_IN) {
ret = tablenameListToString(pRight, sb); ret = tablenameListToString(pRight, sb);
} else if (pTableCond->nSQLOptr == TK_LIKE) { } else if (pTableCond->nSQLOptr == TK_LIKE) {
if (pRight->nSQLOptr != TK_STRING) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
ret = tablenameCondToString(pRight, sb); ret = tablenameCondToString(pRight, sb);
} }
...@@ -5427,6 +5432,7 @@ int32_t validateColumnName(char* name) { ...@@ -5427,6 +5432,7 @@ int32_t validateColumnName(char* name) {
if (token.type == TK_STRING) { if (token.type == TK_STRING) {
strdequote(token.z); strdequote(token.z);
strntolower(token.z, token.z, token.n);
token.n = (uint32_t)strtrim(token.z); token.n = (uint32_t)strtrim(token.z);
int32_t k = tSQLGetToken(token.z, &token.type); int32_t k = tSQLGetToken(token.z, &token.type);
......
...@@ -296,8 +296,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { ...@@ -296,8 +296,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
if (pObj->signature != pObj) { if (pObj->signature != pObj) {
tscDebug("%p DB connection is closed, cmd:%d pObj:%p signature:%p", pSql, pCmd->command, pObj, pObj->signature); tscDebug("%p DB connection is closed, cmd:%d pObj:%p signature:%p", pSql, pCmd->command, pObj, pObj->signature);
taosRemoveRef(tscObjRef, pSql->self); taosRemoveRef(tscObjRef, handle);
taosReleaseRef(tscObjRef, pSql->self); taosReleaseRef(tscObjRef, handle);
rpcFreeCont(rpcMsg->pCont); rpcFreeCont(rpcMsg->pCont);
return; return;
} }
...@@ -307,8 +307,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { ...@@ -307,8 +307,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
tscDebug("%p sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p", tscDebug("%p sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p",
pSql, pCmd->command, pQueryInfo->type, pObj, pObj->signature); pSql, pCmd->command, pQueryInfo->type, pObj, pObj->signature);
taosRemoveRef(tscObjRef, pSql->self); taosRemoveRef(tscObjRef, handle);
taosReleaseRef(tscObjRef, pSql->self); taosReleaseRef(tscObjRef, handle);
rpcFreeCont(rpcMsg->pCont); rpcFreeCont(rpcMsg->pCont);
return; return;
} }
...@@ -354,7 +354,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { ...@@ -354,7 +354,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
// if there is an error occurring, proceed to the following error handling procedure. // if there is an error occurring, proceed to the following error handling procedure.
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
taosReleaseRef(tscObjRef, pSql->self); taosReleaseRef(tscObjRef, handle);
rpcFreeCont(rpcMsg->pCont); rpcFreeCont(rpcMsg->pCont);
return; return;
} }
...@@ -422,13 +422,15 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { ...@@ -422,13 +422,15 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
(*pSql->fp)(pSql->param, pSql, rpcMsg->code); (*pSql->fp)(pSql->param, pSql, rpcMsg->code);
} }
taosReleaseRef(tscObjRef, pSql->self);
if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it
taosRemoveRef(tscObjRef, pSql->self); taosRemoveRef(tscObjRef, handle);
tscDebug("%p sqlObj is automatically freed", pSql); tscDebug("%p sqlObj is automatically freed", pSql);
} }
taosReleaseRef(tscObjRef, handle);
rpcFreeCont(rpcMsg->pCont); rpcFreeCont(rpcMsg->pCont);
} }
......
...@@ -61,7 +61,7 @@ TSKEY tscGetSubscriptionProgress(void* sub, int64_t uid, TSKEY dflt) { ...@@ -61,7 +61,7 @@ TSKEY tscGetSubscriptionProgress(void* sub, int64_t uid, TSKEY dflt) {
SSub* pSub = (SSub*)sub; SSub* pSub = (SSub*)sub;
SSubscriptionProgress target = {.uid = uid, .key = 0}; SSubscriptionProgress target = {.uid = uid, .key = 0};
SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress); SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress, TD_EQ);
if (p == NULL) { if (p == NULL) {
return dflt; return dflt;
} }
...@@ -76,7 +76,7 @@ void tscUpdateSubscriptionProgress(void* sub, int64_t uid, TSKEY ts) { ...@@ -76,7 +76,7 @@ void tscUpdateSubscriptionProgress(void* sub, int64_t uid, TSKEY ts) {
SSub* pSub = (SSub*)sub; SSub* pSub = (SSub*)sub;
SSubscriptionProgress target = {.uid = uid, .key = ts}; SSubscriptionProgress target = {.uid = uid, .key = ts};
SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress); SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress, TD_EQ);
if (p != NULL) { if (p != NULL) {
p->key = ts; p->key = ts;
tscDebug("subscribe:%s, uid:%"PRIu64" update sub start ts:%"PRId64, pSub->topic, p->uid, p->key); tscDebug("subscribe:%s, uid:%"PRIu64" update sub start ts:%"PRId64, pSub->topic, p->uid, p->key);
...@@ -270,7 +270,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { ...@@ -270,7 +270,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
SSubscriptionProgress target = {.uid = pTableMeta->id.uid, .key = 0}; SSubscriptionProgress target = {.uid = pTableMeta->id.uid, .key = 0};
SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress); SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress, TD_EQ);
if (p == NULL) { if (p == NULL) {
taosArrayClear(pSub->progress); taosArrayClear(pSub->progress);
taosArrayPush(pSub->progress, &target); taosArrayPush(pSub->progress, &target);
......
...@@ -2410,7 +2410,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) ...@@ -2410,7 +2410,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
// record the total inserted rows // record the total inserted rows
if (numOfRows > 0) { if (numOfRows > 0) {
pParentObj->res.numOfRows += numOfRows; atomic_add_fetch_32(&pParentObj->res.numOfRows, numOfRows);
} }
if (taos_errno(tres) != TSDB_CODE_SUCCESS) { if (taos_errno(tres) != TSDB_CODE_SUCCESS) {
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "tref.h" #include "tref.h"
#include "trpc.h" #include "trpc.h"
#include "tnote.h" #include "tnote.h"
#include "tsystem.h"
#include "ttimer.h" #include "ttimer.h"
#include "tutil.h" #include "tutil.h"
#include "tsched.h" #include "tsched.h"
...@@ -49,7 +48,7 @@ int32_t tscNumOfThreads = 1; // num of rpc threads ...@@ -49,7 +48,7 @@ int32_t tscNumOfThreads = 1; // num of rpc threads
static pthread_mutex_t rpcObjMutex; // mutex to protect open the rpc obj concurrently static pthread_mutex_t rpcObjMutex; // mutex to protect open the rpc obj concurrently
static pthread_once_t tscinit = PTHREAD_ONCE_INIT; static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void* UNUSED_PARAM(param)) { void tscCheckDiskUsage(void *UNUSED_PARAM(para), void *UNUSED_PARAM(param)) {
taosGetDisk(); taosGetDisk();
taosTmrReset(tscCheckDiskUsage, 1000, NULL, tscTmr, &tscCheckDiskUsageTmr); taosTmrReset(tscCheckDiskUsage, 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);
} }
...@@ -65,7 +64,7 @@ void tscReleaseRpc(void *param) { ...@@ -65,7 +64,7 @@ void tscReleaseRpc(void *param) {
return; return;
} }
pthread_mutex_lock(&rpcObjMutex); pthread_mutex_lock(&rpcObjMutex);
taosCacheRelease(tscRpcCache, (void *)&param, false); taosCacheRelease(tscRpcCache, (void *)&param, true);
pthread_mutex_unlock(&rpcObjMutex); pthread_mutex_unlock(&rpcObjMutex);
} }
...@@ -88,7 +87,7 @@ int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncry ...@@ -88,7 +87,7 @@ int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncry
rpcInit.sessions = tsMaxConnections; rpcInit.sessions = tsMaxConnections;
rpcInit.connType = TAOS_CONN_CLIENT; rpcInit.connType = TAOS_CONN_CLIENT;
rpcInit.user = (char *)user; rpcInit.user = (char *)user;
rpcInit.idleTime = 2000; rpcInit.idleTime = tsShellActivityTimer * 1000;
rpcInit.ckey = "key"; rpcInit.ckey = "key";
rpcInit.spi = 1; rpcInit.spi = 1;
rpcInit.secret = (char *)secretEncrypt; rpcInit.secret = (char *)secretEncrypt;
...@@ -216,7 +215,6 @@ void taos_cleanup(void) { ...@@ -216,7 +215,6 @@ void taos_cleanup(void) {
taosCloseRef(id); taosCloseRef(id);
taosCleanupKeywordsTable(); taosCleanupKeywordsTable();
taosCloseLog();
p = tscRpcCache; p = tscRpcCache;
tscRpcCache = NULL; tscRpcCache = NULL;
...@@ -226,7 +224,10 @@ void taos_cleanup(void) { ...@@ -226,7 +224,10 @@ void taos_cleanup(void) {
pthread_mutex_destroy(&rpcObjMutex); pthread_mutex_destroy(&rpcObjMutex);
} }
if (tscEmbedded == 0) rpcCleanup(); if (tscEmbedded == 0) {
rpcCleanup();
taosCloseLog();
};
p = tscTmr; p = tscTmr;
tscTmr = NULL; tscTmr = NULL;
......
...@@ -32,6 +32,14 @@ ...@@ -32,6 +32,14 @@
static void freeQueryInfoImpl(SQueryInfo* pQueryInfo); static void freeQueryInfoImpl(SQueryInfo* pQueryInfo);
static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo); static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo);
static void tscStrToLower(char *str, int32_t n) {
if (str == NULL || n <= 0) { return;}
for (int32_t i = 0; i < n; i++) {
if (str[i] >= 'A' && str[i] <= 'Z') {
str[i] -= ('A' - 'a');
}
}
}
SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) { SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) {
if (pTagCond->pCond == NULL) { if (pTagCond->pCond == NULL) {
return NULL; return NULL;
...@@ -1413,9 +1421,11 @@ int32_t tscValidateName(SStrToken* pToken) { ...@@ -1413,9 +1421,11 @@ int32_t tscValidateName(SStrToken* pToken) {
char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true); char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
if (sep == NULL) { // single part if (sep == NULL) { // single part
if (pToken->type == TK_STRING) { if (pToken->type == TK_STRING) {
strdequote(pToken->z); strdequote(pToken->z);
tscStrToLower(pToken->z, pToken->n);
pToken->n = (uint32_t)strtrim(pToken->z); pToken->n = (uint32_t)strtrim(pToken->z);
int len = tSQLGetToken(pToken->z, &pToken->type); int len = tSQLGetToken(pToken->z, &pToken->type);
// single token, validate it // single token, validate it
...@@ -1467,7 +1477,7 @@ int32_t tscValidateName(SStrToken* pToken) { ...@@ -1467,7 +1477,7 @@ int32_t tscValidateName(SStrToken* pToken) {
if (pToken->type == TK_STRING && validateQuoteToken(pToken) != TSDB_CODE_SUCCESS) { if (pToken->type == TK_STRING && validateQuoteToken(pToken) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL; return TSDB_CODE_TSC_INVALID_SQL;
} }
// re-build the whole name string // re-build the whole name string
if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) { if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) {
// first part do not have quote do nothing // first part do not have quote do nothing
...@@ -1479,6 +1489,8 @@ int32_t tscValidateName(SStrToken* pToken) { ...@@ -1479,6 +1489,8 @@ int32_t tscValidateName(SStrToken* pToken) {
} }
pToken->n += (firstPartLen + sizeof(TS_PATH_DELIMITER[0])); pToken->n += (firstPartLen + sizeof(TS_PATH_DELIMITER[0]));
pToken->z = pStr; pToken->z = pStr;
tscStrToLower(pToken->z,pToken->n);
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
......
...@@ -68,9 +68,9 @@ typedef struct { ...@@ -68,9 +68,9 @@ typedef struct {
typedef struct { typedef struct {
int version; // version int version; // version
int numOfCols; // Number of columns appended int numOfCols; // Number of columns appended
int tlen; // maximum length of a SDataRow without the header part int tlen; // maximum length of a SDataRow without the header part (sizeof(VarDataOffsetT) + sizeof(VarDataLenT) + (bytes))
uint16_t flen; // First part length in a SDataRow after the header part uint16_t flen; // First part length in a SDataRow after the header part
uint16_t vlen; // pure value part length, excluded the overhead uint16_t vlen; // pure value part length, excluded the overhead (bytes only)
STColumn columns[]; STColumn columns[];
} STSchema; } STSchema;
...@@ -278,7 +278,7 @@ SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows); ...@@ -278,7 +278,7 @@ SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows);
void tdResetDataCols(SDataCols *pCols); void tdResetDataCols(SDataCols *pCols);
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema); int tdInitDataCols(SDataCols *pCols, STSchema *pSchema);
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData); SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
void tdFreeDataCols(SDataCols *pCols); SDataCols *tdFreeDataCols(SDataCols *pCols);
void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols); void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols);
int tdMergeDataCols(SDataCols *target, SDataCols *src, int rowsToMerge); int tdMergeDataCols(SDataCols *target, SDataCols *src, int rowsToMerge);
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#ifndef TDENGINE_COMMON_GLOBAL_H #ifndef TDENGINE_COMMON_GLOBAL_H
#define TDENGINE_COMMON_GLOBAL_H #define TDENGINE_COMMON_GLOBAL_H
#include "taosdef.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
...@@ -57,7 +59,8 @@ extern int32_t tsCompressMsgSize; ...@@ -57,7 +59,8 @@ extern int32_t tsCompressMsgSize;
extern char tsTempDir[]; extern char tsTempDir[];
//query buffer management //query buffer management
extern int32_t tsQueryBufferSize; // maximum allowed usage buffer for each data node during query processing extern int32_t tsQueryBufferSize; // maximum allowed usage buffer size in MB for each data node during query processing
extern int64_t tsQueryBufferSizeBytes; // maximum allowed usage buffer size in byte for each data node during query processing
extern int32_t tsRetrieveBlockingModel;// retrieve threads will be blocked extern int32_t tsRetrieveBlockingModel;// retrieve threads will be blocked
extern int8_t tsKeepOriginalColumnName; extern int8_t tsKeepOriginalColumnName;
...@@ -146,7 +149,6 @@ extern char tsDataDir[]; ...@@ -146,7 +149,6 @@ extern char tsDataDir[];
extern char tsLogDir[]; extern char tsLogDir[];
extern char tsScriptDir[]; extern char tsScriptDir[];
extern int64_t tsMsPerDay[3]; extern int64_t tsMsPerDay[3];
extern char tsVnodeBakDir[];
// system info // system info
extern char tsOsName[]; extern char tsOsName[];
...@@ -195,6 +197,14 @@ extern int32_t wDebugFlag; ...@@ -195,6 +197,14 @@ extern int32_t wDebugFlag;
extern int32_t cqDebugFlag; extern int32_t cqDebugFlag;
extern int32_t debugFlag; extern int32_t debugFlag;
typedef struct {
char dir[TSDB_FILENAME_LEN];
int level;
int primary;
} SDiskCfg;
extern int32_t tsDiskCfgNum;
extern SDiskCfg tsDiskCfg[];
#define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize) #define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize)
void taosInitGlobalCfg(); void taosInitGlobalCfg();
...@@ -203,6 +213,9 @@ void taosSetAllDebugFlag(); ...@@ -203,6 +213,9 @@ void taosSetAllDebugFlag();
bool taosCfgDynamicOptions(char *msg); bool taosCfgDynamicOptions(char *msg);
int taosGetFqdnPortFromEp(const char *ep, char *fqdn, uint16_t *port); int taosGetFqdnPortFromEp(const char *ep, char *fqdn, uint16_t *port);
bool taosCheckBalanceCfgOptions(const char *option, int32_t *vnodeId, int32_t *dnodeId); bool taosCheckBalanceCfgOptions(const char *option, int32_t *vnodeId, int32_t *dnodeId);
void taosAddDataDir(int index, char *v1, int level, int primary);
void taosReadDataDirCfg(char *v1, char *v2, char *v3);
void taosPrintDataDirCfg();
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -289,23 +289,31 @@ SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows) { ...@@ -289,23 +289,31 @@ SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows) {
return NULL; return NULL;
} }
pCols->cols = (SDataCol *)calloc(maxCols, sizeof(SDataCol)); pCols->maxPoints = maxRows;
if (pCols->cols == NULL) {
uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCol) * maxCols, strerror(errno)); if (maxCols > 0) {
tdFreeDataCols(pCols); pCols->cols = (SDataCol *)calloc(maxCols, sizeof(SDataCol));
return NULL; if (pCols->cols == NULL) {
uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCol) * maxCols,
strerror(errno));
tdFreeDataCols(pCols);
return NULL;
}
pCols->maxCols = maxCols;
} }
pCols->maxRowSize = maxRowSize; pCols->maxRowSize = maxRowSize;
pCols->maxCols = maxCols;
pCols->maxPoints = maxRows;
pCols->bufSize = maxRowSize * maxRows; pCols->bufSize = maxRowSize * maxRows;
pCols->buf = malloc(pCols->bufSize); if (pCols->bufSize > 0) {
if (pCols->buf == NULL) { pCols->buf = malloc(pCols->bufSize);
uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCol) * maxCols, strerror(errno)); if (pCols->buf == NULL) {
tdFreeDataCols(pCols); uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCol) * maxCols,
return NULL; strerror(errno));
tdFreeDataCols(pCols);
return NULL;
}
} }
return pCols; return pCols;
...@@ -337,12 +345,13 @@ int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) { ...@@ -337,12 +345,13 @@ int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
return 0; return 0;
} }
void tdFreeDataCols(SDataCols *pCols) { SDataCols *tdFreeDataCols(SDataCols *pCols) {
if (pCols) { if (pCols) {
tfree(pCols->buf); tfree(pCols->buf);
tfree(pCols->cols); tfree(pCols->cols);
free(pCols); free(pCols);
} }
return NULL;
} }
SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) { SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) {
......
...@@ -105,6 +105,7 @@ int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance ...@@ -105,6 +105,7 @@ int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance
// 0 no query allowed, queries are disabled // 0 no query allowed, queries are disabled
// positive value (in MB) // positive value (in MB)
int32_t tsQueryBufferSize = -1; int32_t tsQueryBufferSize = -1;
int64_t tsQueryBufferSizeBytes = -1;
// in retrieve blocking model, the retrieve threads will wait for the completion of the query processing. // in retrieve blocking model, the retrieve threads will wait for the completion of the query processing.
int32_t tsRetrieveBlockingModel = 0; int32_t tsRetrieveBlockingModel = 0;
...@@ -181,7 +182,14 @@ char tsDnodeDir[TSDB_FILENAME_LEN] = {0}; ...@@ -181,7 +182,14 @@ char tsDnodeDir[TSDB_FILENAME_LEN] = {0};
char tsMnodeDir[TSDB_FILENAME_LEN] = {0}; char tsMnodeDir[TSDB_FILENAME_LEN] = {0};
char tsDataDir[TSDB_FILENAME_LEN] = {0}; char tsDataDir[TSDB_FILENAME_LEN] = {0};
char tsScriptDir[TSDB_FILENAME_LEN] = {0}; char tsScriptDir[TSDB_FILENAME_LEN] = {0};
char tsVnodeBakDir[TSDB_FILENAME_LEN] = {0};
int32_t tsDiskCfgNum = 0;
#ifndef _STORAGE
SDiskCfg tsDiskCfg[1];
#else
SDiskCfg tsDiskCfg[TSDB_MAX_DISKS];
#endif
/* /*
* minimum scale for whole system, millisecond by default * minimum scale for whole system, millisecond by default
...@@ -226,6 +234,7 @@ int32_t sDebugFlag = 135; ...@@ -226,6 +234,7 @@ int32_t sDebugFlag = 135;
int32_t wDebugFlag = 135; int32_t wDebugFlag = 135;
int32_t tsdbDebugFlag = 131; int32_t tsdbDebugFlag = 131;
int32_t cqDebugFlag = 131; int32_t cqDebugFlag = 131;
int32_t fsDebugFlag = 135;
int32_t (*monStartSystemFp)() = NULL; int32_t (*monStartSystemFp)() = NULL;
void (*monStopSystemFp)() = NULL; void (*monStopSystemFp)() = NULL;
...@@ -283,7 +292,7 @@ bool taosCfgDynamicOptions(char *msg) { ...@@ -283,7 +292,7 @@ bool taosCfgDynamicOptions(char *msg) {
int32_t cfgLen = (int32_t)strlen(cfg->option); int32_t cfgLen = (int32_t)strlen(cfg->option);
if (cfgLen != olen) continue; if (cfgLen != olen) continue;
if (strncasecmp(option, cfg->option, olen) != 0) continue; if (strncasecmp(option, cfg->option, olen) != 0) continue;
if (cfg->valType != TAOS_CFG_VTYPE_INT32) { if (cfg->valType == TAOS_CFG_VTYPE_INT32) {
*((int32_t *)cfg->ptr) = vint; *((int32_t *)cfg->ptr) = vint;
} else { } else {
*((int8_t *)cfg->ptr) = (int8_t)vint; *((int8_t *)cfg->ptr) = (int8_t)vint;
...@@ -333,6 +342,39 @@ bool taosCfgDynamicOptions(char *msg) { ...@@ -333,6 +342,39 @@ bool taosCfgDynamicOptions(char *msg) {
return false; return false;
} }
void taosAddDataDir(int index, char *v1, int level, int primary) {
tstrncpy(tsDiskCfg[index].dir, v1, TSDB_FILENAME_LEN);
tsDiskCfg[index].level = level;
tsDiskCfg[index].primary = primary;
uTrace("dataDir:%s, level:%d primary:%d is configured", v1, level, primary);
}
#ifndef _STORAGE
void taosReadDataDirCfg(char *v1, char *v2, char *v3) {
if (tsDiskCfgNum == 1) {
SDiskCfg *cfg = &tsDiskCfg[0];
uInfo("dataDir:%s, level:%d primary:%d is replaced by %s", cfg->dir, cfg->level, cfg->primary, v1);
}
taosAddDataDir(0, v1, 0, 1);
tsDiskCfgNum = 1;
}
void taosPrintDataDirCfg() {
for (int i = 0; i < tsDiskCfgNum; ++i) {
SDiskCfg *cfg = &tsDiskCfg[i];
uInfo(" dataDir: %s", cfg->dir);
}
}
#endif
static void taosCheckDataDirCfg() {
if (tsDiskCfgNum <= 0) {
taosAddDataDir(0, tsDataDir, 0, 1);
tsDiskCfgNum = 1;
uTrace("dataDir:%s, level:0 primary:1 is configured by default", tsDataDir);
}
}
static void doInitGlobalConfig(void) { static void doInitGlobalConfig(void) {
osInit(); osInit();
srand(taosSafeRand()); srand(taosSafeRand());
...@@ -414,7 +456,7 @@ static void doInitGlobalConfig(void) { ...@@ -414,7 +456,7 @@ static void doInitGlobalConfig(void) {
cfg.option = "dataDir"; cfg.option = "dataDir";
cfg.ptr = tsDataDir; cfg.ptr = tsDataDir;
cfg.valType = TAOS_CFG_VTYPE_DIRECTORY; cfg.valType = TAOS_CFG_VTYPE_DATA_DIRCTORY;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG; cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
cfg.minValue = 0; cfg.minValue = 0;
cfg.maxValue = 0; cfg.maxValue = 0;
...@@ -1447,6 +1489,7 @@ int32_t taosCheckGlobalCfg() { ...@@ -1447,6 +1489,7 @@ int32_t taosCheckGlobalCfg() {
snprintf(tsSecond, sizeof(tsSecond), "%s:%u", fqdn, port); snprintf(tsSecond, sizeof(tsSecond), "%s:%u", fqdn, port);
} }
taosCheckDataDirCfg();
taosGetSystemInfo(); taosGetSystemInfo();
tsSetLocale(); tsSetLocale();
...@@ -1488,6 +1531,10 @@ int32_t taosCheckGlobalCfg() { ...@@ -1488,6 +1531,10 @@ int32_t taosCheckGlobalCfg() {
tsSyncPort = tsServerPort + TSDB_PORT_SYNC; tsSyncPort = tsServerPort + TSDB_PORT_SYNC;
tsHttpPort = tsServerPort + TSDB_PORT_HTTP; tsHttpPort = tsServerPort + TSDB_PORT_HTTP;
if (tsQueryBufferSize >= 0) {
tsQueryBufferSizeBytes = tsQueryBufferSize * 1048576UL;
}
taosPrintGlobalCfg(); taosPrintGlobalCfg();
return 0; return 0;
......
...@@ -632,7 +632,7 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo ...@@ -632,7 +632,7 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo
} }
// the string may be overflow according to errno // the string may be overflow according to errno
*value = issigned? strtoll(z, &endPtr, radix):strtoul(z, &endPtr, radix); *value = issigned? strtoll(z, &endPtr, radix):strtoull(z, &endPtr, radix);
// not a valid integer number, return error // not a valid integer number, return error
if (endPtr - z != n || errno == ERANGE) { if (endPtr - z != n || errno == ERANGE) {
......
...@@ -50,10 +50,13 @@ typedef struct { ...@@ -50,10 +50,13 @@ typedef struct {
void *dbConn; void *dbConn;
void *tmrCtrl; void *tmrCtrl;
pthread_mutex_t mutex; pthread_mutex_t mutex;
int32_t delete;
int32_t cqObjNum;
} SCqContext; } SCqContext;
typedef struct SCqObj { typedef struct SCqObj {
tmr_h tmrId; tmr_h tmrId;
int64_t rid;
uint64_t uid; uint64_t uid;
int32_t tid; // table ID int32_t tid; // table ID
int32_t rowSize; // bytes of a row int32_t rowSize; // bytes of a row
...@@ -69,6 +72,82 @@ typedef struct SCqObj { ...@@ -69,6 +72,82 @@ typedef struct SCqObj {
static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row); static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row);
static void cqCreateStream(SCqContext *pContext, SCqObj *pObj); static void cqCreateStream(SCqContext *pContext, SCqObj *pObj);
int32_t cqObjRef = -1;
void cqRmFromList(SCqObj *pObj) {
//LOCK in caller
SCqContext *pContext = pObj->pContext;
if (pObj->prev) {
pObj->prev->next = pObj->next;
} else {
pContext->pHead = pObj->next;
}
if (pObj->next) {
pObj->next->prev = pObj->prev;
}
}
void cqFree(void *handle) {
if (tsEnableStream == 0) {
return;
}
SCqObj *pObj = handle;
SCqContext *pContext = pObj->pContext;
int32_t delete = 0;
pthread_mutex_lock(&pContext->mutex);
// free the resources associated
if (pObj->pStream) {
taos_close_stream(pObj->pStream);
pObj->pStream = NULL;
} else {
taosTmrStop(pObj->tmrId);
pObj->tmrId = 0;
}
cInfo("vgId:%d, id:%d CQ:%s is dropped", pContext->vgId, pObj->tid, pObj->sqlStr);
tdFreeSchema(pObj->pSchema);
free(pObj->dstTable);
free(pObj->sqlStr);
free(pObj);
pContext->cqObjNum--;
if (pContext->cqObjNum <= 0 && pContext->delete) {
delete = 1;
}
pthread_mutex_unlock(&pContext->mutex);
if (delete) {
pthread_mutex_destroy(&pContext->mutex);
taosTmrCleanUp(pContext->tmrCtrl);
pContext->tmrCtrl = NULL;
cDebug("vgId:%d, CQ is closed", pContext->vgId);
free(pContext);
}
}
void cqCreateRef() {
int32_t ref = atomic_load_32(&cqObjRef);
if (ref == -1) {
ref = taosOpenRef(4096, cqFree);
if (atomic_val_compare_exchange_32(&cqObjRef, -1, ref) != -1) {
taosCloseRef(ref);
}
}
}
void *cqOpen(void *ahandle, const SCqCfg *pCfg) { void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
if (tsEnableStream == 0) { if (tsEnableStream == 0) {
return NULL; return NULL;
...@@ -79,6 +158,8 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) { ...@@ -79,6 +158,8 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
return NULL; return NULL;
} }
cqCreateRef();
pContext->tmrCtrl = taosTmrInit(0, 0, 0, "CQ"); pContext->tmrCtrl = taosTmrInit(0, 0, 0, "CQ");
tstrncpy(pContext->user, pCfg->user, sizeof(pContext->user)); tstrncpy(pContext->user, pCfg->user, sizeof(pContext->user));
...@@ -97,11 +178,24 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) { ...@@ -97,11 +178,24 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
pthread_mutex_init(&pContext->mutex, NULL); pthread_mutex_init(&pContext->mutex, NULL);
cDebug("vgId:%d, CQ is opened", pContext->vgId); cDebug("vgId:%d, CQ is opened", pContext->vgId);
return pContext; return pContext;
} }
static void freeSCqContext(void *handle) {
if (handle == NULL) {
return;
}
SCqContext *pContext = handle;
pthread_mutex_destroy(&pContext->mutex);
taosTmrCleanUp(pContext->tmrCtrl);
pContext->tmrCtrl = NULL;
cDebug("vgId:%d, CQ is closed", pContext->vgId);
free(pContext);
}
void cqClose(void *handle) { void cqClose(void *handle) {
if (tsEnableStream == 0) { if (tsEnableStream == 0) {
return; return;
...@@ -109,30 +203,32 @@ void cqClose(void *handle) { ...@@ -109,30 +203,32 @@ void cqClose(void *handle) {
SCqContext *pContext = handle; SCqContext *pContext = handle;
if (handle == NULL) return; if (handle == NULL) return;
pContext->delete = 1;
// stop all CQs // stop all CQs
cqStop(pContext); cqStop(pContext);
// free all resources int64_t rid = 0;
pthread_mutex_lock(&pContext->mutex);
SCqObj *pObj = pContext->pHead; while (1) {
while (pObj) { pthread_mutex_lock(&pContext->mutex);
SCqObj *pTemp = pObj;
pObj = pObj->next;
tdFreeSchema(pTemp->pSchema);
tfree(pTemp->sqlStr);
free(pTemp);
}
pthread_mutex_unlock(&pContext->mutex);
pthread_mutex_destroy(&pContext->mutex); SCqObj *pObj = pContext->pHead;
if (pObj) {
cqRmFromList(pObj);
taosTmrCleanUp(pContext->tmrCtrl); rid = pObj->rid;
pContext->tmrCtrl = NULL; } else {
pthread_mutex_unlock(&pContext->mutex);
break;
}
pthread_mutex_unlock(&pContext->mutex);
taosRemoveRef(cqObjRef, rid);
}
cDebug("vgId:%d, CQ is closed", pContext->vgId); freeSCqContext(pContext);
free(pContext);
} }
void cqStart(void *handle) { void cqStart(void *handle) {
...@@ -191,7 +287,8 @@ void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, ch ...@@ -191,7 +287,8 @@ void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, ch
return NULL; return NULL;
} }
SCqContext *pContext = handle; SCqContext *pContext = handle;
int64_t rid = 0;
SCqObj *pObj = calloc(sizeof(SCqObj), 1); SCqObj *pObj = calloc(sizeof(SCqObj), 1);
if (pObj == NULL) return NULL; if (pObj == NULL) return NULL;
...@@ -213,32 +310,36 @@ void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, ch ...@@ -213,32 +310,36 @@ void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, ch
if (pContext->pHead) pContext->pHead->prev = pObj; if (pContext->pHead) pContext->pHead->prev = pObj;
pContext->pHead = pObj; pContext->pHead = pObj;
pContext->cqObjNum++;
pObj->rid = taosAddRef(cqObjRef, pObj);
cqCreateStream(pContext, pObj); cqCreateStream(pContext, pObj);
rid = pObj->rid;
pthread_mutex_unlock(&pContext->mutex); pthread_mutex_unlock(&pContext->mutex);
return pObj;
return (void *)rid;
} }
void cqDrop(void *handle) { void cqDrop(void *handle) {
if (tsEnableStream == 0) { if (tsEnableStream == 0) {
return; return;
} }
SCqObj *pObj = handle;
SCqContext *pContext = pObj->pContext;
pthread_mutex_lock(&pContext->mutex);
if (pObj->prev) {
pObj->prev->next = pObj->next;
} else {
pContext->pHead = pObj->next;
}
if (pObj->next) { SCqObj* pObj = (SCqObj*)taosAcquireRef(cqObjRef, (int64_t)handle);
pObj->next->prev = pObj->prev; if (pObj == NULL) {
return;
} }
SCqContext *pContext = pObj->pContext;
pthread_mutex_lock(&pContext->mutex);
cqRmFromList(pObj);
// free the resources associated // free the resources associated
if (pObj->pStream) { if (pObj->pStream) {
taos_close_stream(pObj->pStream); taos_close_stream(pObj->pStream);
...@@ -248,17 +349,18 @@ void cqDrop(void *handle) { ...@@ -248,17 +349,18 @@ void cqDrop(void *handle) {
pObj->tmrId = 0; pObj->tmrId = 0;
} }
cInfo("vgId:%d, id:%d CQ:%s is dropped", pContext->vgId, pObj->tid, pObj->sqlStr);
tdFreeSchema(pObj->pSchema);
free(pObj->dstTable);
free(pObj->sqlStr);
free(pObj);
pthread_mutex_unlock(&pContext->mutex); pthread_mutex_unlock(&pContext->mutex);
taosRemoveRef(cqObjRef, (int64_t)handle);
taosReleaseRef(cqObjRef, (int64_t)handle);
} }
static void doCreateStream(void *param, TAOS_RES *result, int32_t code) { static void doCreateStream(void *param, TAOS_RES *result, int32_t code) {
SCqObj* pObj = (SCqObj*)param; SCqObj* pObj = (SCqObj*)taosAcquireRef(cqObjRef, (int64_t)param);
if (pObj == NULL) {
return;
}
SCqContext* pContext = pObj->pContext; SCqContext* pContext = pObj->pContext;
SSqlObj* pSql = (SSqlObj*)result; SSqlObj* pSql = (SSqlObj*)result;
if (atomic_val_compare_exchange_ptr(&(pContext->dbConn), NULL, pSql->pTscObj) != NULL) { if (atomic_val_compare_exchange_ptr(&(pContext->dbConn), NULL, pSql->pTscObj) != NULL) {
...@@ -267,10 +369,16 @@ static void doCreateStream(void *param, TAOS_RES *result, int32_t code) { ...@@ -267,10 +369,16 @@ static void doCreateStream(void *param, TAOS_RES *result, int32_t code) {
pthread_mutex_lock(&pContext->mutex); pthread_mutex_lock(&pContext->mutex);
cqCreateStream(pContext, pObj); cqCreateStream(pContext, pObj);
pthread_mutex_unlock(&pContext->mutex); pthread_mutex_unlock(&pContext->mutex);
taosReleaseRef(cqObjRef, (int64_t)param);
} }
static void cqProcessCreateTimer(void *param, void *tmrId) { static void cqProcessCreateTimer(void *param, void *tmrId) {
SCqObj* pObj = (SCqObj*)param; SCqObj* pObj = (SCqObj*)taosAcquireRef(cqObjRef, (int64_t)param);
if (pObj == NULL) {
return;
}
SCqContext* pContext = pObj->pContext; SCqContext* pContext = pObj->pContext;
if (pContext->dbConn == NULL) { if (pContext->dbConn == NULL) {
...@@ -281,6 +389,8 @@ static void cqProcessCreateTimer(void *param, void *tmrId) { ...@@ -281,6 +389,8 @@ static void cqProcessCreateTimer(void *param, void *tmrId) {
cqCreateStream(pContext, pObj); cqCreateStream(pContext, pObj);
pthread_mutex_unlock(&pContext->mutex); pthread_mutex_unlock(&pContext->mutex);
} }
taosReleaseRef(cqObjRef, (int64_t)param);
} }
static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) { static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
...@@ -288,13 +398,13 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) { ...@@ -288,13 +398,13 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
if (pContext->dbConn == NULL) { if (pContext->dbConn == NULL) {
cDebug("vgId:%d, create dbConn after 1000 ms", pContext->vgId); cDebug("vgId:%d, create dbConn after 1000 ms", pContext->vgId);
pObj->tmrId = taosTmrStart(cqProcessCreateTimer, 1000, pObj, pContext->tmrCtrl); pObj->tmrId = taosTmrStart(cqProcessCreateTimer, 1000, (void *)pObj->rid, pContext->tmrCtrl);
return; return;
} }
pObj->tmrId = 0; pObj->tmrId = 0;
if (pObj->pStream == NULL) { if (pObj->pStream == NULL) {
pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, 0, pObj, NULL); pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, 0, (void *)pObj->rid, NULL);
// TODO the pObj->pStream may be released if error happens // TODO the pObj->pStream may be released if error happens
if (pObj->pStream) { if (pObj->pStream) {
...@@ -308,18 +418,28 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) { ...@@ -308,18 +418,28 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
} }
static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) { static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
SCqObj *pObj = (SCqObj *)param; SCqObj* pObj = (SCqObj*)taosAcquireRef(cqObjRef, (int64_t)param);
if (pObj == NULL) {
return;
}
if (tres == NULL && row == NULL) { if (tres == NULL && row == NULL) {
taos_close_stream(pObj->pStream); taos_close_stream(pObj->pStream);
pObj->pStream = NULL; pObj->pStream = NULL;
taosReleaseRef(cqObjRef, (int64_t)param);
return; return;
} }
SCqContext *pContext = pObj->pContext; SCqContext *pContext = pObj->pContext;
STSchema *pSchema = pObj->pSchema; STSchema *pSchema = pObj->pSchema;
if (pObj->pStream == NULL) return; if (pObj->pStream == NULL) {
taosReleaseRef(cqObjRef, (int64_t)param);
return;
}
cDebug("vgId:%d, id:%d CQ:%s stream result is ready", pContext->vgId, pObj->tid, pObj->sqlStr); cDebug("vgId:%d, id:%d CQ:%s stream result is ready", pContext->vgId, pObj->tid, pObj->sqlStr);
int32_t size = sizeof(SWalHead) + sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + TD_DATA_ROW_HEAD_SIZE + pObj->rowSize; int32_t size = sizeof(SWalHead) + sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + TD_DATA_ROW_HEAD_SIZE + pObj->rowSize;
...@@ -370,5 +490,7 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) { ...@@ -370,5 +490,7 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
// write into vnode write queue // write into vnode write queue
pContext->cqWrite(pContext->vgId, pHead, TAOS_QTYPE_CQ, NULL); pContext->cqWrite(pContext->vgId, pHead, TAOS_QTYPE_CQ, NULL);
free(buffer); free(buffer);
taosReleaseRef(cqObjRef, (int64_t)param);
} }
...@@ -27,7 +27,7 @@ IF (TD_GRANT) ...@@ -27,7 +27,7 @@ IF (TD_GRANT)
TARGET_LINK_LIBRARIES(taosd grant) TARGET_LINK_LIBRARIES(taosd grant)
ENDIF () ENDIF ()
IF ((TD_LINUX OR TD_WINDOWS) AND TD_MQTT) IF (TD_MQTT)
TARGET_LINK_LIBRARIES(taosd mqtt) TARGET_LINK_LIBRARIES(taosd mqtt)
ENDIF () ENDIF ()
...@@ -43,5 +43,6 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PREPARE_ENV_CMD} ...@@ -43,5 +43,6 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PREPARE_ENV_CMD}
COMMAND ${CMAKE_COMMAND} -E echo dataDir ${TD_TESTS_OUTPUT_DIR}/data > ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg COMMAND ${CMAKE_COMMAND} -E echo dataDir ${TD_TESTS_OUTPUT_DIR}/data > ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
COMMAND ${CMAKE_COMMAND} -E echo logDir ${TD_TESTS_OUTPUT_DIR}/log >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg COMMAND ${CMAKE_COMMAND} -E echo logDir ${TD_TESTS_OUTPUT_DIR}/log >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
COMMAND ${CMAKE_COMMAND} -E echo charset UTF-8 >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg COMMAND ${CMAKE_COMMAND} -E echo charset UTF-8 >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
COMMAND ${CMAKE_COMMAND} -E echo monitor 0 >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
COMMENT "prepare taosd environment") COMMENT "prepare taosd environment")
ADD_CUSTOM_TARGET(${PREPARE_ENV_TARGET} ALL WORKING_DIRECTORY ${TD_EXECUTABLE_OUTPUT_PATH} DEPENDS ${PREPARE_ENV_CMD}) ADD_CUSTOM_TARGET(${PREPARE_ENV_TARGET} ALL WORKING_DIRECTORY ${TD_EXECUTABLE_OUTPUT_PATH} DEPENDS ${PREPARE_ENV_CMD})
...@@ -156,7 +156,7 @@ static int32_t dnodeWriteCfg() { ...@@ -156,7 +156,7 @@ static int32_t dnodeWriteCfg() {
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); fsync(fileno(fp));
fclose(fp); fclose(fp);
free(content); free(content);
terrno = 0; terrno = 0;
......
...@@ -277,7 +277,7 @@ static int32_t dnodeWriteEps() { ...@@ -277,7 +277,7 @@ static int32_t dnodeWriteEps() {
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); fsync(fileno(fp));
fclose(fp); fclose(fp);
free(content); free(content);
terrno = 0; terrno = 0;
......
...@@ -286,7 +286,7 @@ static int32_t dnodeWriteMInfos() { ...@@ -286,7 +286,7 @@ static int32_t dnodeWriteMInfos() {
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); fsync(fileno(fp));
fclose(fp); fclose(fp);
free(content); free(content);
terrno = 0; terrno = 0;
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "tconfig.h" #include "tconfig.h"
#include "tfile.h" #include "tfile.h"
#include "twal.h" #include "twal.h"
// #include "tfs.h" #include "tfs.h"
#include "tsync.h" #include "tsync.h"
#include "dnodeStep.h" #include "dnodeStep.h"
#include "dnodePeer.h" #include "dnodePeer.h"
...@@ -189,32 +189,35 @@ static void dnodeCheckDataDirOpenned(char *dir) { ...@@ -189,32 +189,35 @@ static void dnodeCheckDataDirOpenned(char *dir) {
} }
static int32_t dnodeInitStorage() { static int32_t dnodeInitStorage() {
if (dnodeCreateDir(tsDataDir) < 0) { if (tfsInit(tsDiskCfg, tsDiskCfgNum) < 0) {
dError("failed to create dir: %s, reason: %s", tsDataDir, strerror(errno)); dError("failed to init TFS since %s", tstrerror(terrno));
return -1; return -1;
} }
strncpy(tsDataDir, TFS_PRIMARY_PATH(), TSDB_FILENAME_LEN);
sprintf(tsMnodeDir, "%s/mnode", tsDataDir); sprintf(tsMnodeDir, "%s/mnode", tsDataDir);
sprintf(tsVnodeDir, "%s/vnode", tsDataDir); sprintf(tsVnodeDir, "%s/vnode", tsDataDir);
sprintf(tsDnodeDir, "%s/dnode", tsDataDir); sprintf(tsDnodeDir, "%s/dnode", tsDataDir);
sprintf(tsVnodeBakDir, "%s/vnode_bak", tsDataDir); // sprintf(tsVnodeBakDir, "%s/vnode_bak", tsDataDir);
//TODO(dengyihao): no need to init here //TODO(dengyihao): no need to init here
if (dnodeCreateDir(tsMnodeDir) < 0) { if (dnodeCreateDir(tsMnodeDir) < 0) {
dError("failed to create dir: %s, reason: %s", tsMnodeDir, strerror(errno)); dError("failed to create dir: %s, reason: %s", tsMnodeDir, strerror(errno));
return -1; return -1;
} }
//TODO(dengyihao): no need to init here
if (dnodeCreateDir(tsVnodeDir) < 0) {
dError("failed to create dir: %s, reason: %s", tsVnodeDir, strerror(errno));
return -1;
}
if (dnodeCreateDir(tsDnodeDir) < 0) { if (dnodeCreateDir(tsDnodeDir) < 0) {
dError("failed to create dir: %s, reason: %s", tsDnodeDir, strerror(errno)); dError("failed to create dir: %s, reason: %s", tsDnodeDir, strerror(errno));
return -1; return -1;
} }
if (dnodeCreateDir(tsVnodeBakDir) < 0) {
dError("failed to create dir: %s, reason: %s", tsVnodeBakDir, strerror(errno)); if (tfsMkdir("vnode") < 0) {
return -1; dError("failed to create vnode dir since %s", tstrerror(terrno));
return -1;
}
if (tfsMkdir("vnode_bak") < 0) {
dError("failed to create vnode_bak dir since %s", tstrerror(terrno));
return -1;
} }
dnodeCheckDataDirOpenned(tsDnodeDir); dnodeCheckDataDirOpenned(tsDnodeDir);
...@@ -223,7 +226,7 @@ static int32_t dnodeInitStorage() { ...@@ -223,7 +226,7 @@ static int32_t dnodeInitStorage() {
return 0; return 0;
} }
static void dnodeCleanupStorage() {} static void dnodeCleanupStorage() { tfsDestroy(); }
bool dnodeIsFirstDeploy() { bool dnodeIsFirstDeploy() {
return strcmp(tsFirst, tsLocalEp) == 0; return strcmp(tsFirst, tsLocalEp) == 0;
......
...@@ -174,7 +174,7 @@ static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) { ...@@ -174,7 +174,7 @@ static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) {
vnodeRelease(pVnode); vnodeRelease(pVnode);
return code; return code;
} else { } else {
dError("vgId:%d, vnode not exist, can't alter it", pAlter->cfg.vgId); dInfo("vgId:%d, vnode not exist, can't alter it", pAlter->cfg.vgId);
return TSDB_CODE_VND_INVALID_VGROUP_ID; return TSDB_CODE_VND_INVALID_VGROUP_ID;
} }
} }
......
...@@ -242,6 +242,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM, 0, 0x060F, "No table d ...@@ -242,6 +242,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM, 0, 0x060F, "No table d
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_FILE_ALREADY_EXISTS, 0, 0x0610, "File already exists") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_FILE_ALREADY_EXISTS, 0, 0x0610, "File already exists")
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_TABLE_RECONFIGURE, 0, 0x0611, "Need to reconfigure table") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_TABLE_RECONFIGURE, 0, 0x0611, "Need to reconfigure table")
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO, 0, 0x0612, "Invalid information to create table") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO, 0, 0x0612, "Invalid information to create table")
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_AVAIL_DISK, 0, 0x0613, "No available disk")
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_MESSED_MSG, 0, 0x0614, "TSDB messed message")
// query // query
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_QHANDLE, 0, 0x0700, "Invalid handle") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_QHANDLE, 0, 0x0700, "Invalid handle")
......
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TD_TFS_H
#define TD_TFS_H
#include "tglobal.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int level;
int id;
} SDiskID;
#define TFS_UNDECIDED_LEVEL -1
#define TFS_UNDECIDED_ID -1
#define TFS_PRIMARY_LEVEL 0
#define TFS_PRIMARY_ID 0
// FS APIs ====================================
typedef struct {
int64_t tsize;
int64_t avail;
} SFSMeta;
int tfsInit(SDiskCfg *pDiskCfg, int ndisk);
void tfsDestroy();
void tfsUpdateInfo(SFSMeta *pFSMeta);
void tfsGetMeta(SFSMeta *pMeta);
void tfsAllocDisk(int expLevel, int *level, int *id);
const char *TFS_PRIMARY_PATH();
const char *TFS_DISK_PATH(int level, int id);
// TFILE APIs ====================================
typedef struct {
int level;
int id;
char rname[TSDB_FILENAME_LEN]; // REL name
char aname[TSDB_FILENAME_LEN]; // ABS name
} TFILE;
#define TFILE_LEVEL(pf) ((pf)->level)
#define TFILE_ID(pf) ((pf)->id)
#define TFILE_NAME(pf) ((pf)->aname)
#define TFILE_REL_NAME(pf) ((pf)->rname)
#define tfsopen(pf, flags) open(TFILE_NAME(pf), flags)
#define tfsclose(fd) close(fd)
#define tfsremove(pf) remove(TFILE_NAME(pf))
#define tfscopy(sf, df) taosCopy(TFILE_NAME(sf), TFILE_NAME(df))
#define tfsrename(sf, df) rename(TFILE_NAME(sf), TFILE_NAME(df))
void tfsInitFile(TFILE *pf, int level, int id, const char *bname);
bool tfsIsSameFile(const TFILE *pf1, const TFILE *pf2);
int tfsEncodeFile(void **buf, TFILE *pf);
void *tfsDecodeFile(void *buf, TFILE *pf);
void tfsbasename(const TFILE *pf, char *dest);
void tfsdirname(const TFILE *pf, char *dest);
// DIR APIs ====================================
int tfsMkdirAt(const char *rname, int level, int id);
int tfsMkdirRecurAt(const char *rname, int level, int id);
int tfsMkdir(const char *rname);
int tfsRmdir(const char *rname);
int tfsRename(char *orname, char *nrname);
typedef struct TDIR TDIR;
TDIR * tfsOpendir(const char *rname);
const TFILE *tfsReaddir(TDIR *tdir);
void tfsClosedir(TDIR *tdir);
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
...@@ -40,7 +40,8 @@ extern "C" { ...@@ -40,7 +40,8 @@ extern "C" {
// TSDB STATE DEFINITION // TSDB STATE DEFINITION
#define TSDB_STATE_OK 0x0 #define TSDB_STATE_OK 0x0
#define TSDB_STATE_BAD_FILE 0x1 #define TSDB_STATE_BAD_META 0x1
#define TSDB_STATE_BAD_DATA 0x2
// --------- TSDB APPLICATION HANDLE DEFINITION // --------- TSDB APPLICATION HANDLE DEFINITION
typedef struct { typedef struct {
...@@ -48,7 +49,7 @@ typedef struct { ...@@ -48,7 +49,7 @@ typedef struct {
void *cqH; void *cqH;
int (*notifyStatus)(void *, int status, int eno); int (*notifyStatus)(void *, int status, int eno);
int (*eventCallBack)(void *); int (*eventCallBack)(void *);
void *(*cqCreateFunc)(void *handle, uint64_t uid, int32_t sid, const char* dstTable, char *sqlStr, STSchema *pSchema); void *(*cqCreateFunc)(void *handle, uint64_t uid, int32_t sid, const char *dstTable, char *sqlStr, STSchema *pSchema);
void (*cqDropFunc)(void *handle); void (*cqDropFunc)(void *handle);
} STsdbAppH; } STsdbAppH;
...@@ -76,17 +77,17 @@ typedef struct { ...@@ -76,17 +77,17 @@ typedef struct {
int64_t pointsWritten; // total data points written int64_t pointsWritten; // total data points written
} STsdbStat; } STsdbStat;
typedef void TSDB_REPO_T; // use void to hide implementation details from outside typedef struct STsdbRepo STsdbRepo;
STsdbCfg *tsdbGetCfg(const TSDB_REPO_T *repo); STsdbCfg *tsdbGetCfg(const STsdbRepo *repo);
// --------- TSDB REPOSITORY DEFINITION // --------- TSDB REPOSITORY DEFINITION
int tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg); int32_t tsdbCreateRepo(int repoid);
int32_t tsdbDropRepo(char *rootDir); int32_t tsdbDropRepo(int repoid);
TSDB_REPO_T *tsdbOpenRepo(char *rootDir, STsdbAppH *pAppH); STsdbRepo *tsdbOpenRepo(STsdbCfg *pCfg, STsdbAppH *pAppH);
int tsdbCloseRepo(TSDB_REPO_T *repo, int toCommit); int tsdbCloseRepo(STsdbRepo *repo, int toCommit);
int32_t tsdbConfigRepo(TSDB_REPO_T *repo, STsdbCfg *pCfg); int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg);
int tsdbGetState(TSDB_REPO_T *repo); int tsdbGetState(STsdbRepo *repo);
// --------- TSDB TABLE DEFINITION // --------- TSDB TABLE DEFINITION
typedef struct { typedef struct {
...@@ -110,8 +111,8 @@ typedef struct { ...@@ -110,8 +111,8 @@ typedef struct {
void tsdbClearTableCfg(STableCfg *config); void tsdbClearTableCfg(STableCfg *config);
void* tsdbGetTableTagVal(const void* pTable, int32_t colId, int16_t type, int16_t bytes); void *tsdbGetTableTagVal(const void *pTable, int32_t colId, int16_t type, int16_t bytes);
char* tsdbGetTableName(void *pTable); char *tsdbGetTableName(void *pTable);
#define TSDB_TABLEID(_table) ((STableId*) (_table)) #define TSDB_TABLEID(_table) ((STableId*) (_table))
#define TSDB_PREV_ROW 0x1 #define TSDB_PREV_ROW 0x1
...@@ -119,12 +120,11 @@ char* tsdbGetTableName(void *pTable); ...@@ -119,12 +120,11 @@ char* tsdbGetTableName(void *pTable);
STableCfg *tsdbCreateTableCfgFromMsg(SMDCreateTableMsg *pMsg); STableCfg *tsdbCreateTableCfgFromMsg(SMDCreateTableMsg *pMsg);
int tsdbCreateTable(TSDB_REPO_T *repo, STableCfg *pCfg); int tsdbCreateTable(STsdbRepo *repo, STableCfg *pCfg);
int tsdbDropTable(TSDB_REPO_T *pRepo, STableId tableId); int tsdbDropTable(STsdbRepo *pRepo, STableId tableId);
int tsdbUpdateTableTagValue(TSDB_REPO_T *repo, SUpdateTableTagValMsg *pMsg); int tsdbUpdateTableTagValue(STsdbRepo *repo, SUpdateTableTagValMsg *pMsg);
// TSKEY tsdbGetTableLastKey(TSDB_REPO_T *repo, uint64_t uid);
uint32_t tsdbGetFileInfo(TSDB_REPO_T *repo, char *name, uint32_t *index, uint32_t eindex, int64_t *size); uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t eindex, int64_t *size);
// the TSDB repository info // the TSDB repository info
typedef struct STsdbRepoInfo { typedef struct STsdbRepoInfo {
...@@ -134,7 +134,7 @@ typedef struct STsdbRepoInfo { ...@@ -134,7 +134,7 @@ typedef struct STsdbRepoInfo {
int64_t tsdbTotalDiskSize; // the total disk size taken by this TSDB repository int64_t tsdbTotalDiskSize; // the total disk size taken by this TSDB repository
// TODO: Other informations to add // TODO: Other informations to add
} STsdbRepoInfo; } STsdbRepoInfo;
STsdbRepoInfo *tsdbGetStatus(TSDB_REPO_T *pRepo); STsdbRepoInfo *tsdbGetStatus(STsdbRepo *pRepo);
// the meter information report structure // the meter information report structure
typedef struct { typedef struct {
...@@ -152,7 +152,7 @@ typedef struct { ...@@ -152,7 +152,7 @@ typedef struct {
* *
* @return the number of points inserted, -1 for failure and the error number is set * @return the number of points inserted, -1 for failure and the error number is set
*/ */
int32_t tsdbInsertData(TSDB_REPO_T *repo, SSubmitMsg *pMsg, SShellSubmitRspMsg *pRsp); int32_t tsdbInsertData(STsdbRepo *repo, SSubmitMsg *pMsg, SShellSubmitRspMsg *pRsp);
// -- FOR QUERY TIME SERIES DATA // -- FOR QUERY TIME SERIES DATA
...@@ -168,9 +168,9 @@ typedef struct STsdbQueryCond { ...@@ -168,9 +168,9 @@ typedef struct STsdbQueryCond {
} STsdbQueryCond; } STsdbQueryCond;
typedef struct SMemRef { typedef struct SMemRef {
int32_t ref; int32_t ref;
void *mem; void * mem;
void *imem; void * imem;
} SMemRef; } SMemRef;
typedef struct SDataBlockInfo { typedef struct SDataBlockInfo {
...@@ -182,14 +182,14 @@ typedef struct SDataBlockInfo { ...@@ -182,14 +182,14 @@ typedef struct SDataBlockInfo {
} SDataBlockInfo; } SDataBlockInfo;
typedef struct { typedef struct {
void *pTable; void *pTable;
TSKEY lastKey; TSKEY lastKey;
} STableKeyInfo; } STableKeyInfo;
typedef struct { typedef struct {
size_t numOfTables; size_t numOfTables;
SArray *pGroupList; SArray * pGroupList;
SHashObj *map; // speedup acquire the tableQueryInfo by table uid SHashObj *map; // speedup acquire the tableQueryInfo by table uid
} STableGroupInfo; } STableGroupInfo;
/** /**
...@@ -202,7 +202,8 @@ typedef struct { ...@@ -202,7 +202,8 @@ typedef struct {
* @param qinfo query info handle from query processor * @param qinfo query info handle from query processor
* @return * @return
*/ */
TsdbQueryHandleT *tsdbQueryTables(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfoGroup, void *qinfo, SMemRef* pRef); TsdbQueryHandleT *tsdbQueryTables(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfoGroup, void *qinfo,
SMemRef *pRef);
/** /**
* Get the last row of the given query time window for all the tables in STableGroupInfo object. * Get the last row of the given query time window for all the tables in STableGroupInfo object.
...@@ -214,14 +215,15 @@ TsdbQueryHandleT *tsdbQueryTables(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STab ...@@ -214,14 +215,15 @@ TsdbQueryHandleT *tsdbQueryTables(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STab
* @param tableInfo table list. * @param tableInfo table list.
* @return * @return
*/ */
TsdbQueryHandleT tsdbQueryLastRow(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, void *qinfo, SMemRef* pRef); TsdbQueryHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, void *qinfo,
SMemRef *pRef);
/** /**
* get the queried table object list * get the queried table object list
* @param pHandle * @param pHandle
* @return * @return
*/ */
SArray* tsdbGetQueriedTableList(TsdbQueryHandleT *pHandle); SArray *tsdbGetQueriedTableList(TsdbQueryHandleT *pHandle);
/** /**
* get the group list according to table id from client * get the group list according to table id from client
...@@ -231,8 +233,8 @@ SArray* tsdbGetQueriedTableList(TsdbQueryHandleT *pHandle); ...@@ -231,8 +233,8 @@ SArray* tsdbGetQueriedTableList(TsdbQueryHandleT *pHandle);
* @param qinfo * @param qinfo
* @return * @return
*/ */
TsdbQueryHandleT tsdbQueryRowsInExternalWindow(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, TsdbQueryHandleT tsdbQueryRowsInExternalWindow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList,
void *qinfo, SMemRef* pRef); void *qinfo, SMemRef *pRef);
/** /**
...@@ -268,7 +270,7 @@ SArray* tsdbGetExternalRow(TsdbQueryHandleT *pHandle, SMemRef* pMemRef, int16_t ...@@ -268,7 +270,7 @@ SArray* tsdbGetExternalRow(TsdbQueryHandleT *pHandle, SMemRef* pMemRef, int16_t
* @param pBlockInfo * @param pBlockInfo
* @return * @return
*/ */
void tsdbRetrieveDataBlockInfo(TsdbQueryHandleT *pQueryHandle, SDataBlockInfo* pBlockInfo); void tsdbRetrieveDataBlockInfo(TsdbQueryHandleT *pQueryHandle, SDataBlockInfo *pBlockInfo);
/** /**
* *
...@@ -299,7 +301,7 @@ SArray *tsdbRetrieveDataBlock(TsdbQueryHandleT *pQueryHandle, SArray *pColumnIdL ...@@ -299,7 +301,7 @@ SArray *tsdbRetrieveDataBlock(TsdbQueryHandleT *pQueryHandle, SArray *pColumnIdL
* @param stableid. super table sid * @param stableid. super table sid
* @param pTagCond. tag query condition * @param pTagCond. tag query condition
*/ */
int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T *tsdb, uint64_t uid, TSKEY key, const char *pTagCond, size_t len, int32_t tsdbQuerySTableByTagCond(STsdbRepo *tsdb, uint64_t uid, TSKEY key, const char *pTagCond, size_t len,
int16_t tagNameRelType, const char *tbnameCond, STableGroupInfo *pGroupList, int16_t tagNameRelType, const char *tbnameCond, STableGroupInfo *pGroupList,
SColIndex *pColIndex, int32_t numOfCols); SColIndex *pColIndex, int32_t numOfCols);
...@@ -317,7 +319,7 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList); ...@@ -317,7 +319,7 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList);
* @param pGroupInfo the generated result * @param pGroupInfo the generated result
* @return * @return
*/ */
int32_t tsdbGetOneTableGroup(TSDB_REPO_T *tsdb, uint64_t uid, TSKEY startKey, STableGroupInfo *pGroupInfo); int32_t tsdbGetOneTableGroup(STsdbRepo *tsdb, uint64_t uid, TSKEY startKey, STableGroupInfo *pGroupInfo);
/** /**
* *
...@@ -326,7 +328,7 @@ int32_t tsdbGetOneTableGroup(TSDB_REPO_T *tsdb, uint64_t uid, TSKEY startKey, ST ...@@ -326,7 +328,7 @@ int32_t tsdbGetOneTableGroup(TSDB_REPO_T *tsdb, uint64_t uid, TSKEY startKey, ST
* @param pGroupInfo * @param pGroupInfo
* @return * @return
*/ */
int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STableGroupInfo* pGroupInfo); int32_t tsdbGetTableGroupFromIdList(STsdbRepo *tsdb, SArray *pTableIdList, STableGroupInfo *pGroupInfo);
/** /**
* clean up the query handle * clean up the query handle
...@@ -345,10 +347,14 @@ void tsdbReportStat(void *repo, int64_t *totalPoints, int64_t *totalStorage, int ...@@ -345,10 +347,14 @@ void tsdbReportStat(void *repo, int64_t *totalPoints, int64_t *totalStorage, int
int tsdbInitCommitQueue(); int tsdbInitCommitQueue();
void tsdbDestroyCommitQueue(); void tsdbDestroyCommitQueue();
int tsdbSyncCommit(TSDB_REPO_T *repo); int tsdbSyncCommit(STsdbRepo *repo);
void tsdbIncCommitRef(int vgId); void tsdbIncCommitRef(int vgId);
void tsdbDecCommitRef(int vgId); void tsdbDecCommitRef(int vgId);
// For TSDB file sync
int tsdbSyncSend(void *pRepo, SOCKET socketFd);
int tsdbSyncRecv(void *pRepo, SOCKET socketFd);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -56,16 +56,6 @@ typedef struct { ...@@ -56,16 +56,6 @@ typedef struct {
int32_t role[TAOS_SYNC_MAX_REPLICA]; int32_t role[TAOS_SYNC_MAX_REPLICA];
} SNodesRole; } SNodesRole;
/*
if name is empty(name[0] is zero), get the file from index or after, but not larger than eindex. If a file
is found between index and eindex, index shall be updated, name shall be set, size shall be set to
file size, and file magic number shall be returned.
if name is provided(name[0] is not zero), get the named file at the specified index. If not there, return
zero. If it is there, set the size to file size, and return file magic number. Index shall not be updated.
*/
typedef uint32_t (*FGetFileInfo)(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion);
// get the wal file from index or after // get the wal file from index or after
// return value, -1: error, 1:more wal files, 0:last WAL. if name[0]==0, no WAL file // return value, -1: error, 1:more wal files, 0:last WAL. if name[0]==0, no WAL file
typedef int32_t (*FGetWalInfo)(int32_t vgId, char *fileName, int64_t *fileId); typedef int32_t (*FGetWalInfo)(int32_t vgId, char *fileName, int64_t *fileId);
...@@ -83,24 +73,31 @@ typedef void (*FNotifyRole)(int32_t vgId, int8_t role); ...@@ -83,24 +73,31 @@ typedef void (*FNotifyRole)(int32_t vgId, int8_t role);
typedef void (*FNotifyFlowCtrl)(int32_t vgId, int32_t level); typedef void (*FNotifyFlowCtrl)(int32_t vgId, int32_t level);
// when data file is synced successfully, notity app // when data file is synced successfully, notity app
typedef int32_t (*FNotifyFileSynced)(int32_t vgId, uint64_t fversion); typedef void (*FStartSyncFile)(int32_t vgId);
typedef void (*FStopSyncFile)(int32_t vgId, uint64_t fversion);
// get file version // get file version
typedef int32_t (*FGetVersion)(int32_t vgId, uint64_t *fver, uint64_t *vver); typedef int32_t (*FGetVersion)(int32_t vgId, uint64_t *fver, uint64_t *vver);
typedef int32_t (*FSendFile)(void *tsdb, SOCKET socketFd);
typedef int32_t (*FRecvFile)(void *tsdb, SOCKET socketFd);
typedef struct { typedef struct {
int32_t vgId; // vgroup ID int32_t vgId; // vgroup ID
uint64_t version; // initial version uint64_t version; // initial version
SSyncCfg syncCfg; // configuration from mgmt SSyncCfg syncCfg; // configuration from mgmt
char path[TSDB_FILENAME_LEN]; // path to the file char path[TSDB_FILENAME_LEN]; // path to the file
FGetFileInfo getFileInfo; void * pTsdb;
FGetWalInfo getWalInfo; FGetWalInfo getWalInfoFp;
FWriteToCache writeToCache; FWriteToCache writeToCacheFp;
FConfirmForward confirmForward; FConfirmForward confirmForward;
FNotifyRole notifyRole; FNotifyRole notifyRoleFp;
FNotifyFlowCtrl notifyFlowCtrl; FNotifyFlowCtrl notifyFlowCtrlFp;
FNotifyFileSynced notifyFileSynced; FStartSyncFile startSyncFileFp;
FGetVersion getVersion; FStopSyncFile stopSyncFileFp;
FGetVersion getVersionFp;
FSendFile sendFileFp;
FRecvFile recvFileFp;
} SSyncInfo; } SSyncInfo;
typedef void *tsync_h; typedef void *tsync_h;
......
...@@ -470,7 +470,7 @@ static int dumpResultToFile(const char* fname, TAOS_RES* tres) { ...@@ -470,7 +470,7 @@ static int dumpResultToFile(const char* fname, TAOS_RES* tres) {
wordexp_t full_path; wordexp_t full_path;
if (wordexp(fname, &full_path, 0) != 0) { if (wordexp((char *)fname, &full_path, 0) != 0) {
fprintf(stderr, "ERROR: invalid file name: %s\n", fname); fprintf(stderr, "ERROR: invalid file name: %s\n", fname);
return -1; return -1;
} }
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "os.h" #include "os.h"
#include "taoserror.h" #include "taoserror.h"
#include "tsched.h" #include "tsched.h"
#include "tsystem.h"
#include "tutil.h" #include "tutil.h"
#include "tgrant.h" #include "tgrant.h"
#include "tbn.h" #include "tbn.h"
......
...@@ -242,11 +242,6 @@ void sdbUpdateMnodeRoles() { ...@@ -242,11 +242,6 @@ void sdbUpdateMnodeRoles() {
mnodeUpdateMnodeEpSet(NULL); mnodeUpdateMnodeEpSet(NULL);
} }
static uint32_t sdbGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion) {
sdbUpdateMnodeRoles();
return 0;
}
static int32_t sdbGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId) { static int32_t sdbGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId) {
return walGetWalFile(tsSdbMgmt.wal, fileName, fileId); return walGetWalFile(tsSdbMgmt.wal, fileName, fileId);
} }
...@@ -262,7 +257,9 @@ static void sdbNotifyRole(int32_t vgId, int8_t role) { ...@@ -262,7 +257,9 @@ static void sdbNotifyRole(int32_t vgId, int8_t role) {
sdbUpdateMnodeRoles(); sdbUpdateMnodeRoles();
} }
static int32_t sdbNotifyFileSynced(int32_t vgId, uint64_t fversion) { return 0; } static void sdbStartFileSync(int32_t vgId) {}
static void sdbStopFileSync(int32_t vgId, uint64_t fversion) {}
static void sdbNotifyFlowCtrl(int32_t vgId, int32_t level) {} static void sdbNotifyFlowCtrl(int32_t vgId, int32_t level) {}
...@@ -396,14 +393,14 @@ int32_t sdbUpdateSync(void *pMnodes) { ...@@ -396,14 +393,14 @@ int32_t sdbUpdateSync(void *pMnodes) {
syncInfo.version = sdbGetVersion(); syncInfo.version = sdbGetVersion();
syncInfo.syncCfg = syncCfg; syncInfo.syncCfg = syncCfg;
sprintf(syncInfo.path, "%s", tsMnodeDir); sprintf(syncInfo.path, "%s", tsMnodeDir);
syncInfo.getFileInfo = sdbGetFileInfo; syncInfo.getWalInfoFp = sdbGetWalInfo;
syncInfo.getWalInfo = sdbGetWalInfo; syncInfo.writeToCacheFp = sdbWriteFwdToQueue;
syncInfo.writeToCache = sdbWriteFwdToQueue;
syncInfo.confirmForward = sdbConfirmForward; syncInfo.confirmForward = sdbConfirmForward;
syncInfo.notifyRole = sdbNotifyRole; syncInfo.notifyRoleFp = sdbNotifyRole;
syncInfo.notifyFileSynced = sdbNotifyFileSynced; syncInfo.startSyncFileFp = sdbStartFileSync;
syncInfo.notifyFlowCtrl = sdbNotifyFlowCtrl; syncInfo.stopSyncFileFp = sdbStopFileSync;
syncInfo.getVersion = sdbGetSyncVersion; syncInfo.notifyFlowCtrlFp = sdbNotifyFlowCtrl;
syncInfo.getVersionFp = sdbGetSyncVersion;
tsSdbMgmt.cfg = syncCfg; tsSdbMgmt.cfg = syncCfg;
if (tsSdbMgmt.sync) { if (tsSdbMgmt.sync) {
......
...@@ -123,7 +123,7 @@ static void mnodePrintUserAuth() { ...@@ -123,7 +123,7 @@ static void mnodePrintUserAuth() {
mnodeDecUserRef(pUser); mnodeDecUserRef(pUser);
} }
fflush(fp); fsync(fileno(fp));
fclose(fp); fclose(fp);
} }
......
...@@ -105,6 +105,8 @@ typedef int(*__compar_fn_t)(const void *, const void *); ...@@ -105,6 +105,8 @@ typedef int(*__compar_fn_t)(const void *, const void *);
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#endif #endif
#define TAOS_OS_FUNC_PTHREAD_RWLOCK
int64_t tsosStr2int64(char *str); int64_t tsosStr2int64(char *str);
#include "eok.h" #include "eok.h"
......
...@@ -26,6 +26,7 @@ int64_t taosReadImp(int32_t fd, void *buf, int64_t count); ...@@ -26,6 +26,7 @@ int64_t taosReadImp(int32_t fd, void *buf, int64_t count);
int64_t taosWriteImp(int32_t fd, void *buf, int64_t count); int64_t taosWriteImp(int32_t fd, void *buf, int64_t count);
int64_t taosLSeekImp(int32_t fd, int64_t offset, int32_t whence); int64_t taosLSeekImp(int32_t fd, int64_t offset, int32_t whence);
int32_t taosRenameFile(char *fullPath, char *suffix, char delimiter, char **dstPath); int32_t taosRenameFile(char *fullPath, char *suffix, char delimiter, char **dstPath);
int64_t taosCopy(char *from, char *to);
#define taosRead(fd, buf, count) taosReadImp(fd, buf, count) #define taosRead(fd, buf, count) taosReadImp(fd, buf, count)
#define taosWrite(fd, buf, count) taosWriteImp(fd, buf, count) #define taosWrite(fd, buf, count) taosWriteImp(fd, buf, count)
......
...@@ -35,7 +35,7 @@ void taosDumpMemoryLeak(); ...@@ -35,7 +35,7 @@ void taosDumpMemoryLeak();
void * taosTMalloc(size_t size); void * taosTMalloc(size_t size);
void * taosTCalloc(size_t nmemb, size_t size); void * taosTCalloc(size_t nmemb, size_t size);
void * taosTRealloc(void *ptr, size_t size); void * taosTRealloc(void *ptr, size_t size);
void taosTZfree(void *ptr); void * taosTZfree(void *ptr);
size_t taosTSizeof(void *ptr); size_t taosTSizeof(void *ptr);
void taosTMemset(void *ptr, int c); void taosTMemset(void *ptr, int c);
......
...@@ -28,6 +28,21 @@ extern "C" { ...@@ -28,6 +28,21 @@ extern "C" {
#define tsem_destroy sem_destroy #define tsem_destroy sem_destroy
#endif #endif
#ifdef TAOS_OS_FUNC_PTHREAD_RWLOCK
#define pthread_rwlock_t pthread_mutex_t
#define pthread_rwlock_init(lock, NULL) pthread_mutex_init(lock, NULL)
#define pthread_rwlock_destroy(lock) pthread_mutex_destroy(lock)
#define pthread_rwlock_wrlock(lock) pthread_mutex_lock(lock)
#define pthread_rwlock_rdlock(lock) pthread_mutex_lock(lock)
#define pthread_rwlock_unlock(lock) pthread_mutex_unlock(lock)
#define pthread_spinlock_t pthread_mutex_t
#define pthread_spin_init(lock, NULL) pthread_mutex_init(lock, NULL)
#define pthread_spin_destroy(lock) pthread_mutex_destroy(lock)
#define pthread_spin_lock(lock) pthread_mutex_lock(lock)
#define pthread_spin_unlock(lock) pthread_mutex_unlock(lock)
#endif
// TAOS_OS_FUNC_SEMPHONE_PTHREAD // TAOS_OS_FUNC_SEMPHONE_PTHREAD
bool taosCheckPthreadValid(pthread_t thread); bool taosCheckPthreadValid(pthread_t thread);
int64_t taosGetSelfPthreadId(); int64_t taosGetSelfPthreadId();
......
...@@ -21,10 +21,16 @@ extern "C" { ...@@ -21,10 +21,16 @@ extern "C" {
#endif #endif
// TAOS_OS_FUNC_SYSINFO // TAOS_OS_FUNC_SYSINFO
typedef struct {
int64_t tsize;
int64_t avail;
} SysDiskSize;
int32_t taosGetDiskSize(char *dataDir, SysDiskSize *diskSize);
void taosGetSystemInfo(); void taosGetSystemInfo();
bool taosGetProcIO(float *readKB, float *writeKB); bool taosGetProcIO(float *readKB, float *writeKB);
bool taosGetBandSpeed(float *bandSpeedKb); bool taosGetBandSpeed(float *bandSpeedKb);
bool taosGetDisk(); void taosGetDisk();
bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) ; bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) ;
bool taosGetProcMemory(float *memoryUsedMB) ; bool taosGetProcMemory(float *memoryUsedMB) ;
bool taosGetSysMemory(float *memoryUsedMB); bool taosGetSysMemory(float *memoryUsedMB);
......
...@@ -201,13 +201,15 @@ int gettimeofday(struct timeval *ptv, void *pTimeZone); ...@@ -201,13 +201,15 @@ int gettimeofday(struct timeval *ptv, void *pTimeZone);
typedef struct { typedef struct {
int we_wordc; int we_wordc;
char **we_wordv; char *we_wordv[1];
int we_offs; int we_offs;
char wordPos[20]; char wordPos[1025];
} wordexp_t; } wordexp_t;
int wordexp(const char *words, wordexp_t *pwordexp, int flags); int wordexp(char *words, wordexp_t *pwordexp, int flags);
void wordfree(wordexp_t *pwordexp); void wordfree(wordexp_t *pwordexp);
char *realpath(char *path, char *resolved_path);
#define openlog(a, b, c) #define openlog(a, b, c)
#define closelog() #define closelog()
#define LOG_ERR 0 #define LOG_ERR 0
......
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
#include "tconfig.h" #include "tconfig.h"
#include "tglobal.h" #include "tglobal.h"
#include "tulog.h" #include "tulog.h"
#include "taoserror.h"
#include <errno.h>
#include <libproc.h>
static void taosGetSystemTimezone() { static void taosGetSystemTimezone() {
// get and set default timezone // get and set default timezone
...@@ -67,8 +71,6 @@ void taosGetSystemInfo() { ...@@ -67,8 +71,6 @@ void taosGetSystemInfo() {
taosGetSystemLocale(); taosGetSystemLocale();
} }
bool taosGetDisk() { return true; }
bool taosGetProcIO(float *readKB, float *writeKB) { bool taosGetProcIO(float *readKB, float *writeKB) {
*readKB = 0; *readKB = 0;
*writeKB = 0; *writeKB = 0;
...@@ -103,8 +105,31 @@ int taosSystem(const char *cmd) { ...@@ -103,8 +105,31 @@ int taosSystem(const char *cmd) {
void taosSetCoreDump() {} void taosSetCoreDump() {}
int32_t taosGetDiskSize(char *dataDir, SysDiskSize *diskSize) {
struct statvfs info;
if (statvfs(tsDataDir, &info)) {
uError("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
} else {
diskSize->tsize = info.f_blocks * info.f_frsize;
diskSize->avail = info.f_bavail * info.f_frsize;
return 0;
}
}
char cmdline[1024];
char *taosGetCmdlineByPID(int pid) { char *taosGetCmdlineByPID(int pid) {
return "[not supported yet]";
errno = 0;
if (proc_pidpath(pid, cmdline, sizeof(cmdline)) <= 0) {
fprintf(stderr, "PID is %d, %s", pid, strerror(errno));
return strerror(errno);
}
return cmdline;
} }
bool taosGetSystemUid(char *uid) { bool taosGetSystemUid(char *uid) {
......
...@@ -119,6 +119,40 @@ int64_t taosLSeekImp(int32_t fd, int64_t offset, int32_t whence) { ...@@ -119,6 +119,40 @@ int64_t taosLSeekImp(int32_t fd, int64_t offset, int32_t whence) {
return (int64_t)lseek(fd, (long)offset, whence); return (int64_t)lseek(fd, (long)offset, whence);
} }
int64_t taosCopy(char *from, char *to) {
char buffer[4096];
int fidto = -1, fidfrom = -1;
int64_t size = 0;
int64_t bytes;
fidfrom = open(from, O_RDONLY | O_BINARY);
if (fidfrom < 0) goto _err;
fidto = open(to, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0755);
if (fidto < 0) goto _err;
while (true) {
bytes = taosRead(fidfrom, buffer, sizeof(buffer));
if (bytes < 0) goto _err;
if (bytes == 0) break;
size += bytes;
if (taosWrite(fidto, (void *)buffer, bytes) < bytes) goto _err;
if (bytes < sizeof(buffer)) break;
}
close(fidfrom);
close(fidto);
return size;
_err:
if (fidfrom >= 0) close(fidfrom);
if (fidto >= 0) close(fidto);
remove(to);
return -1;
}
#ifndef TAOS_OS_FUNC_FILE_SENDIFLE #ifndef TAOS_OS_FUNC_FILE_SENDIFLE
int64_t taosSendFile(SOCKET dfd, int32_t sfd, int64_t *offset, int64_t size) { int64_t taosSendFile(SOCKET dfd, int32_t sfd, int64_t *offset, int64_t size) {
......
...@@ -512,8 +512,9 @@ void * taosTRealloc(void *ptr, size_t size) { ...@@ -512,8 +512,9 @@ void * taosTRealloc(void *ptr, size_t size) {
return (void *)((char *)tptr + sizeof(size_t)); return (void *)((char *)tptr + sizeof(size_t));
} }
void taosTZfree(void *ptr) { void* taosTZfree(void* ptr) {
if (ptr) { if (ptr) {
free((void *)((char *)ptr - sizeof(size_t))); free((void*)((char*)ptr - sizeof(size_t)));
} }
return NULL;
} }
\ No newline at end of file
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "tconfig.h" #include "tconfig.h"
#include "tglobal.h" #include "tglobal.h"
#include "tulog.h" #include "tulog.h"
#include "taoserror.h"
#ifndef TAOS_OS_FUNC_SYSINFO #ifndef TAOS_OS_FUNC_SYSINFO
...@@ -316,37 +317,17 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) { ...@@ -316,37 +317,17 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) {
return true; return true;
} }
bool taosGetDisk() { int32_t taosGetDiskSize(char *dataDir, SysDiskSize *diskSize) {
struct statvfs info; struct statvfs info;
const double unit = 1024 * 1024 * 1024; if (statvfs(tsDataDir, &info)) {
uError("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno));
if (tscEmbedded) { terrno = TAOS_SYSTEM_ERROR(errno);
if (statvfs(tsDataDir, &info)) { return -1;
uError("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno));
return false;
} else {
tsTotalDataDirGB = (float)((double)info.f_blocks * (double)info.f_frsize / unit);
tsAvailDataDirGB = (float)((double)info.f_bavail * (double)info.f_frsize / unit);
}
}
if (statvfs(tsLogDir, &info)) {
uError("failed to get disk size, logDir:%s errno:%s", tsLogDir, strerror(errno));
return false;
} else {
tsTotalLogDirGB = (float)((double)info.f_blocks * (double)info.f_frsize / unit);
tsAvailLogDirGB = (float)((double)info.f_bavail * (double)info.f_frsize / unit);
}
if (statvfs("/tmp", &info)) {
uError("failed to get disk size, tmpDir:/tmp errno:%s", strerror(errno));
return false;
} else { } else {
tsTotalTmpDirGB = (float)((double)info.f_blocks * (double)info.f_frsize / unit); diskSize->tsize = info.f_blocks * info.f_frsize;
tsAvailTmpDirectorySpace = (float)((double)info.f_bavail * (double)info.f_frsize / unit); diskSize->avail = info.f_bavail * info.f_frsize;
return 0;
} }
return true;
} }
static bool taosGetCardInfo(int64_t *bytes) { static bool taosGetCardInfo(int64_t *bytes) {
...@@ -510,7 +491,7 @@ void taosGetSystemInfo() { ...@@ -510,7 +491,7 @@ void taosGetSystemInfo() {
float tmp1, tmp2; float tmp1, tmp2;
taosGetSysMemory(&tmp1); taosGetSysMemory(&tmp1);
taosGetProcMemory(&tmp2); taosGetProcMemory(&tmp2);
taosGetDisk(); // taosGetDisk();
taosGetBandSpeed(&tmp1); taosGetBandSpeed(&tmp1);
taosGetCpuUsage(&tmp1, &tmp2); taosGetCpuUsage(&tmp1, &tmp2);
taosGetProcIO(&tmp1, &tmp2); taosGetProcIO(&tmp1, &tmp2);
...@@ -537,7 +518,6 @@ void taosPrintOsInfo() { ...@@ -537,7 +518,6 @@ void taosPrintOsInfo() {
uInfo(" os release: %s", buf.release); uInfo(" os release: %s", buf.release);
uInfo(" os version: %s", buf.version); uInfo(" os version: %s", buf.version);
uInfo(" os machine: %s", buf.machine); uInfo(" os machine: %s", buf.machine);
uInfo("==================================");
} }
void taosKillSystem() { void taosKillSystem() {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "ttimer.h" #include "ttimer.h"
#include "tulog.h" #include "tulog.h"
#include "tutil.h" #include "tutil.h"
#include "taoserror.h"
#if (_WIN64) #if (_WIN64)
#include <iphlpapi.h> #include <iphlpapi.h>
#include <mswsock.h> #include <mswsock.h>
...@@ -126,37 +127,22 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) { ...@@ -126,37 +127,22 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) {
return true; return true;
} }
bool taosGetDisk() { int32_t taosGetDiskSize(char *dataDir, SysDiskSize *diskSize) {
const double unit = 1024 * 1024 * 1024;
BOOL fResult;
unsigned _int64 i64FreeBytesToCaller; unsigned _int64 i64FreeBytesToCaller;
unsigned _int64 i64TotalBytes; unsigned _int64 i64TotalBytes;
unsigned _int64 i64FreeBytes; unsigned _int64 i64FreeBytes;
if (tscEmbedded) { BOOL fResult = GetDiskFreeSpaceExA(dataDir, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes,
fResult = GetDiskFreeSpaceExA(tsDataDir, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes, (PULARGE_INTEGER)&i64FreeBytes);
(PULARGE_INTEGER)&i64FreeBytes);
if (fResult) {
tsTotalDataDirGB = (float)(i64TotalBytes / unit);
tsAvailDataDirGB = (float)(i64FreeBytes / unit);
}
}
fResult = GetDiskFreeSpaceExA(tsLogDir, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes,
(PULARGE_INTEGER)&i64FreeBytes);
if (fResult) { if (fResult) {
tsTotalLogDirGB = (float)(i64TotalBytes / unit); diskSize->tsize = (int64_t)(i64TotalBytes);
tsAvailLogDirGB = (float)(i64FreeBytes / unit); diskSize->avail = (int64_t)(i64FreeBytes);
} return 0;
} else {
fResult = GetDiskFreeSpaceExA(tsTempDir, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes, uError("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno));
(PULARGE_INTEGER)&i64FreeBytes); terrno = TAOS_SYSTEM_ERROR(errno);
if (fResult) { return -1;
tsTotalTmpDirGB = (float)(i64TotalBytes / unit);
tsAvailTmpDirectorySpace = (float)(i64FreeBytes / unit);
} }
return true;
} }
bool taosGetBandSpeed(float *bandSpeedKb) { bool taosGetBandSpeed(float *bandSpeedKb) {
...@@ -207,7 +193,7 @@ void taosGetSystemInfo() { ...@@ -207,7 +193,7 @@ void taosGetSystemInfo() {
tsTotalMemoryMB = taosGetTotalMemory(); tsTotalMemoryMB = taosGetTotalMemory();
float tmp1, tmp2; float tmp1, tmp2;
taosGetDisk(); // taosGetDisk();
taosGetBandSpeed(&tmp1); taosGetBandSpeed(&tmp1);
taosGetCpuUsage(&tmp1, &tmp2); taosGetCpuUsage(&tmp1, &tmp2);
taosGetProcIO(&tmp1, &tmp2); taosGetProcIO(&tmp1, &tmp2);
......
...@@ -21,13 +21,24 @@ ...@@ -21,13 +21,24 @@
#include "tulog.h" #include "tulog.h"
#include "tutil.h" #include "tutil.h"
int wordexp(const char *words, wordexp_t *pwordexp, int flags) { int wordexp(char *words, wordexp_t *pwordexp, int flags) {
pwordexp->we_offs = 0; pwordexp->we_offs = 0;
pwordexp->we_wordc = 1; pwordexp->we_wordc = 1;
pwordexp->we_wordv = (char **)(pwordexp->wordPos); pwordexp->we_wordv[0] = pwordexp->wordPos;
pwordexp->we_wordv[0] = (char *)words;
memset(pwordexp->wordPos, 0, 1025);
if (_fullpath(pwordexp->wordPos, words, 1024) == NULL) {
pwordexp->we_wordv[0] = words;
uError("failed to parse relative path:%s to abs path", words);
return -1;
}
uTrace("parse relative path:%s to abs path:%s", words, pwordexp->wordPos);
return 0; return 0;
} }
void wordfree(wordexp_t *pwordexp) {} void wordfree(wordexp_t *pwordexp) {}
char *realpath(char *path, char *resolved_path) {
return _fullpath(path, resolved_path, TSDB_FILENAME_LEN - 1);
}
\ No newline at end of file
...@@ -35,7 +35,7 @@ void restBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int32_t ...@@ -35,7 +35,7 @@ void restBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int32_t
// data row array end // data row array end
httpJsonToken(jsonBuf, JsonArrEnd); httpJsonToken(jsonBuf, JsonArrEnd);
cmd->numOfRows = affect_rows; cmd->numOfRows = 1;
} }
void restStartSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result) { void restStartSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result) {
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include "tlog.h" #include "tlog.h"
#include "ttimer.h" #include "ttimer.h"
#include "tutil.h" #include "tutil.h"
#include "tsystem.h"
#include "tscUtil.h" #include "tscUtil.h"
#include "tsclient.h" #include "tsclient.h"
#include "dnode.h" #include "dnode.h"
......
...@@ -30,6 +30,7 @@ extern uint32_t qDebugFlag; ...@@ -30,6 +30,7 @@ extern uint32_t qDebugFlag;
#define qInfo(...) do { if (qDebugFlag & DEBUG_INFO) { taosPrintLog("QRY ", 255, __VA_ARGS__); }} while(0) #define qInfo(...) do { if (qDebugFlag & DEBUG_INFO) { taosPrintLog("QRY ", 255, __VA_ARGS__); }} while(0)
#define qDebug(...) do { if (qDebugFlag & DEBUG_DEBUG) { taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); }} while(0) #define qDebug(...) do { if (qDebugFlag & DEBUG_DEBUG) { taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); }} while(0)
#define qTrace(...) do { if (qDebugFlag & DEBUG_TRACE) { taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); }} while(0) #define qTrace(...) do { if (qDebugFlag & DEBUG_TRACE) { taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); }} while(0)
#define qDump(a, l) do { if (qDebugFlag & DEBUG_DUMP) { taosDumpData((unsigned char *)a, l); }} while(0)
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -7160,14 +7160,23 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { ...@@ -7160,14 +7160,23 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
if (f) { if (f) {
off_t s = lseek(fileno(f), 0, SEEK_END); off_t s = lseek(fileno(f), 0, SEEK_END);
qDebug("QInfo:%p ts comp data return, file:%p, size:%"PRId64, pQInfo, f, s); qDebug("QInfo:%p ts comp data return, file:%p, size:%"PRId64, pQInfo, f, (uint64_t)s);
if (fseek(f, 0, SEEK_SET) >= 0) { if (fseek(f, 0, SEEK_SET) >= 0) {
size_t sz = fread(data, 1, s, f); size_t sz = fread(data, 1, s, f);
if(sz < s) { // todo handle error if(sz < s) { // todo handle error
qError("fread(f:%p,%d) failed, rsize:%" PRId64 ", expect size:%" PRId64, f, fileno(f), (uint64_t)sz, (uint64_t)s);
assert(0); assert(0);
} }
} else { } else {
UNUSED(s); UNUSED(s);
qError("fseek(f:%p,%d) failed, error:%s", f, fileno(f), strerror(errno));
assert(0);
}
if (s <= (sizeof(STSBufFileHeader) + sizeof(STSGroupBlockInfo) + 6 * sizeof(int32_t))) {
qDump(data, s);
assert(0);
} }
fclose(f); fclose(f);
...@@ -7730,15 +7739,15 @@ static int64_t getQuerySupportBufSize(size_t numOfTables) { ...@@ -7730,15 +7739,15 @@ static int64_t getQuerySupportBufSize(size_t numOfTables) {
int32_t checkForQueryBuf(size_t numOfTables) { int32_t checkForQueryBuf(size_t numOfTables) {
int64_t t = getQuerySupportBufSize(numOfTables); int64_t t = getQuerySupportBufSize(numOfTables);
if (tsQueryBufferSize < 0) { if (tsQueryBufferSizeBytes < 0) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} else if (tsQueryBufferSize > 0) { } else if (tsQueryBufferSizeBytes > 0) {
while(1) { while(1) {
int64_t s = tsQueryBufferSize; int64_t s = tsQueryBufferSizeBytes;
int64_t remain = s - t; int64_t remain = s - t;
if (remain >= 0) { if (remain >= 0) {
if (atomic_val_compare_exchange_64(&tsQueryBufferSize, s, remain) == s) { if (atomic_val_compare_exchange_64(&tsQueryBufferSizeBytes, s, remain) == s) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
} else { } else {
...@@ -7752,14 +7761,14 @@ int32_t checkForQueryBuf(size_t numOfTables) { ...@@ -7752,14 +7761,14 @@ int32_t checkForQueryBuf(size_t numOfTables) {
} }
void releaseQueryBuf(size_t numOfTables) { void releaseQueryBuf(size_t numOfTables) {
if (tsQueryBufferSize <= 0) { if (tsQueryBufferSizeBytes < 0) {
return; return;
} }
int64_t t = getQuerySupportBufSize(numOfTables); int64_t t = getQuerySupportBufSize(numOfTables);
// restore value is not enough buffer available // restore value is not enough buffer available
atomic_add_fetch_64(&tsQueryBufferSize, t); atomic_add_fetch_64(&tsQueryBufferSizeBytes, t);
} }
void* qGetResultRetrieveMsg(qinfo_t qinfo) { void* qGetResultRetrieveMsg(qinfo_t qinfo) {
......
...@@ -364,10 +364,11 @@ void *taosInitTcpClient(uint32_t ip, uint16_t port, char *label, int numOfThread ...@@ -364,10 +364,11 @@ void *taosInitTcpClient(uint32_t ip, uint16_t port, char *label, int numOfThread
} }
void taosStopTcpClient(void *chandle) { void taosStopTcpClient(void *chandle) {
SThreadObj *pThreadObj = chandle; SClientObj *pClientObj = chandle;
if (pThreadObj == NULL) return;
if (pClientObj == NULL) return;
tDebug ("%s TCP client is stopped", pThreadObj->label); tDebug ("%s TCP client is stopped", pClientObj->label);
} }
void taosCleanUpTcpClient(void *chandle) { void taosCleanUpTcpClient(void *chandle) {
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "os.h" #include "os.h"
#include "tsocket.h" #include "tsocket.h"
#include "tsystem.h"
#include "ttimer.h" #include "ttimer.h"
#include "tutil.h" #include "tutil.h"
#include "taosdef.h" #include "taosdef.h"
......
...@@ -108,14 +108,17 @@ typedef struct SSyncNode { ...@@ -108,14 +108,17 @@ typedef struct SSyncNode {
SSyncFwds * pSyncFwds; // saved forward info if quorum >1 SSyncFwds * pSyncFwds; // saved forward info if quorum >1
void * pFwdTimer; void * pFwdTimer;
void * pRoleTimer; void * pRoleTimer;
FGetFileInfo getFileInfo; void * pTsdb;
FGetWalInfo getWalInfo; FGetWalInfo getWalInfoFp;
FWriteToCache writeToCache; FWriteToCache writeToCacheFp;
FConfirmForward confirmForward; FConfirmForward confirmForward;
FNotifyRole notifyRole; FNotifyRole notifyRoleFp;
FNotifyFlowCtrl notifyFlowCtrl; FNotifyFlowCtrl notifyFlowCtrlFp;
FNotifyFileSynced notifyFileSynced; FStartSyncFile startSyncFileFp;
FGetVersion getVersion; FStopSyncFile stopSyncFileFp;
FGetVersion getVersionFp;
FSendFile sendFileFp;
FRecvFile recvFileFp;
pthread_mutex_t mutex; pthread_mutex_t mutex;
} SSyncNode; } SSyncNode;
......
...@@ -99,16 +99,12 @@ typedef struct { ...@@ -99,16 +99,12 @@ typedef struct {
typedef struct { typedef struct {
SSyncHead head; SSyncHead head;
char name[TSDB_FILENAME_LEN];
uint32_t magic;
uint32_t index;
uint64_t fversion; uint64_t fversion;
int64_t size; } SFileVersion;
} SFileInfo;
typedef struct { typedef struct {
SSyncHead head; SSyncHead head;
int8_t sync; int8_t ack;
} SFileAck; } SFileAck;
typedef struct { typedef struct {
...@@ -136,7 +132,7 @@ void syncBuildPeersStatus(SPeersStatus *pMsg, int32_t vgId); ...@@ -136,7 +132,7 @@ void syncBuildPeersStatus(SPeersStatus *pMsg, int32_t vgId);
void syncBuildSyncTestMsg(SSyncMsg *pMsg, int32_t vgId); void syncBuildSyncTestMsg(SSyncMsg *pMsg, int32_t vgId);
void syncBuildFileAck(SFileAck *pMsg, int32_t vgId); void syncBuildFileAck(SFileAck *pMsg, int32_t vgId);
void syncBuildFileInfo(SFileInfo *pMsg, int32_t vgId); void syncBuildFileVersion(SFileVersion *pMsg, int32_t vgId);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -174,19 +174,22 @@ int64_t syncStart(const SSyncInfo *pInfo) { ...@@ -174,19 +174,22 @@ int64_t syncStart(const SSyncInfo *pInfo) {
tstrncpy(pNode->path, pInfo->path, sizeof(pNode->path)); tstrncpy(pNode->path, pInfo->path, sizeof(pNode->path));
pthread_mutex_init(&pNode->mutex, NULL); pthread_mutex_init(&pNode->mutex, NULL);
pNode->getFileInfo = pInfo->getFileInfo; pNode->getWalInfoFp = pInfo->getWalInfoFp;
pNode->getWalInfo = pInfo->getWalInfo; pNode->writeToCacheFp = pInfo->writeToCacheFp;
pNode->writeToCache = pInfo->writeToCache; pNode->notifyRoleFp = pInfo->notifyRoleFp;
pNode->notifyRole = pInfo->notifyRole;
pNode->confirmForward = pInfo->confirmForward; pNode->confirmForward = pInfo->confirmForward;
pNode->notifyFlowCtrl = pInfo->notifyFlowCtrl; pNode->notifyFlowCtrlFp = pInfo->notifyFlowCtrlFp;
pNode->notifyFileSynced = pInfo->notifyFileSynced; pNode->startSyncFileFp = pInfo->startSyncFileFp;
pNode->getVersion = pInfo->getVersion; pNode->stopSyncFileFp = pInfo->stopSyncFileFp;
pNode->getVersionFp = pInfo->getVersionFp;
pNode->sendFileFp = pInfo->sendFileFp;
pNode->recvFileFp = pInfo->recvFileFp;
pNode->selfIndex = -1; pNode->selfIndex = -1;
pNode->vgId = pInfo->vgId; pNode->vgId = pInfo->vgId;
pNode->replica = pCfg->replica; pNode->replica = pCfg->replica;
pNode->quorum = pCfg->quorum; pNode->quorum = pCfg->quorum;
pNode->pTsdb = pInfo->pTsdb;
if (pNode->quorum > pNode->replica) pNode->quorum = pNode->replica; if (pNode->quorum > pNode->replica) pNode->quorum = pNode->replica;
pNode->refCount = 1; pNode->refCount = 1;
...@@ -248,8 +251,8 @@ int64_t syncStart(const SSyncInfo *pInfo) { ...@@ -248,8 +251,8 @@ int64_t syncStart(const SSyncInfo *pInfo) {
syncAddArbitrator(pNode); syncAddArbitrator(pNode);
taosHashPut(tsVgIdHash, &pNode->vgId, sizeof(int32_t), &pNode, sizeof(SSyncNode *)); taosHashPut(tsVgIdHash, &pNode->vgId, sizeof(int32_t), &pNode, sizeof(SSyncNode *));
if (pNode->notifyRole) { if (pNode->notifyRoleFp) {
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
} }
syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb
...@@ -357,7 +360,7 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) { ...@@ -357,7 +360,7 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) {
if (pNewCfg->replica <= 1) { if (pNewCfg->replica <= 1) {
sInfo("vgId:%d, no peers are configured, work as master!", pNode->vgId); sInfo("vgId:%d, no peers are configured, work as master!", pNode->vgId);
nodeRole = TAOS_SYNC_ROLE_MASTER; nodeRole = TAOS_SYNC_ROLE_MASTER;
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
} }
syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb
...@@ -417,7 +420,7 @@ void syncRecover(int64_t rid) { ...@@ -417,7 +420,7 @@ void syncRecover(int64_t rid) {
// if take this node to unsync state, the whole system may not work // if take this node to unsync state, the whole system may not work
nodeRole = TAOS_SYNC_ROLE_UNSYNCED; nodeRole = TAOS_SYNC_ROLE_UNSYNCED;
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
nodeVersion = 0; nodeVersion = 0;
pthread_mutex_lock(&pNode->mutex); pthread_mutex_lock(&pNode->mutex);
...@@ -625,8 +628,8 @@ static void syncResetFlowCtrl(SSyncNode *pNode) { ...@@ -625,8 +628,8 @@ static void syncResetFlowCtrl(SSyncNode *pNode) {
pNode->peerInfo[index]->numOfRetrieves = 0; pNode->peerInfo[index]->numOfRetrieves = 0;
} }
if (pNode->notifyFlowCtrl) { if (pNode->notifyFlowCtrlFp) {
(*pNode->notifyFlowCtrl)(pNode->vgId, 0); (*pNode->notifyFlowCtrlFp)(pNode->vgId, 0);
} }
} }
...@@ -694,7 +697,7 @@ static void syncChooseMaster(SSyncNode *pNode) { ...@@ -694,7 +697,7 @@ static void syncChooseMaster(SSyncNode *pNode) {
taosMsleep(SYNC_WAIT_AFTER_CHOOSE_MASTER); taosMsleep(SYNC_WAIT_AFTER_CHOOSE_MASTER);
syncResetFlowCtrl(pNode); syncResetFlowCtrl(pNode);
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
} else { } else {
pPeer = pNode->peerInfo[index]; pPeer = pNode->peerInfo[index];
sInfo("%s, it shall work as master", pPeer->id); sInfo("%s, it shall work as master", pPeer->id);
...@@ -730,7 +733,7 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { ...@@ -730,7 +733,7 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) {
nodeRole = TAOS_SYNC_ROLE_UNSYNCED; nodeRole = TAOS_SYNC_ROLE_UNSYNCED;
sInfo("vgId:%d, self change to unsynced state, online:%d replica:%d", pNode->vgId, onlineNum, replica); sInfo("vgId:%d, self change to unsynced state, online:%d replica:%d", pNode->vgId, onlineNum, replica);
} }
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
} }
} else { } else {
for (int32_t index = 0; index < pNode->replica; ++index) { for (int32_t index = 0; index < pNode->replica; ++index) {
...@@ -742,7 +745,7 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { ...@@ -742,7 +745,7 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) {
if (masterIndex == pNode->selfIndex) { if (masterIndex == pNode->selfIndex) {
sError("%s, peer is master, work as slave instead", pTemp->id); sError("%s, peer is master, work as slave instead", pTemp->id);
nodeRole = TAOS_SYNC_ROLE_SLAVE; nodeRole = TAOS_SYNC_ROLE_SLAVE;
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
} }
} }
} }
...@@ -759,7 +762,7 @@ static int32_t syncValidateMaster(SSyncPeer *pPeer) { ...@@ -759,7 +762,7 @@ static int32_t syncValidateMaster(SSyncPeer *pPeer) {
if (nodeRole == TAOS_SYNC_ROLE_MASTER && nodeVersion < pPeer->version) { if (nodeRole == TAOS_SYNC_ROLE_MASTER && nodeVersion < pPeer->version) {
sDebug("%s, peer has higher sver:%" PRIu64 ", restart all peer connections", pPeer->id, pPeer->version); sDebug("%s, peer has higher sver:%" PRIu64 ", restart all peer connections", pPeer->id, pPeer->version);
nodeRole = TAOS_SYNC_ROLE_UNSYNCED; nodeRole = TAOS_SYNC_ROLE_UNSYNCED;
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
code = -1; code = -1;
for (int32_t index = 0; index < pNode->replica; ++index) { for (int32_t index = 0; index < pNode->replica; ++index) {
...@@ -796,7 +799,7 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t new ...@@ -796,7 +799,7 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t new
} else { } else {
sInfo("%s, is master, work as slave, self sver:%" PRIu64, pMaster->id, nodeVersion); sInfo("%s, is master, work as slave, self sver:%" PRIu64, pMaster->id, nodeVersion);
nodeRole = TAOS_SYNC_ROLE_SLAVE; nodeRole = TAOS_SYNC_ROLE_SLAVE;
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
} }
} else if (nodeRole == TAOS_SYNC_ROLE_SLAVE && pMaster == pPeer) { } else if (nodeRole == TAOS_SYNC_ROLE_SLAVE && pMaster == pPeer) {
sDebug("%s, is master, continue work as slave, self sver:%" PRIu64, pMaster->id, nodeVersion); sDebug("%s, is master, continue work as slave, self sver:%" PRIu64, pMaster->id, nodeVersion);
...@@ -989,7 +992,7 @@ static void syncProcessForwardFromPeer(char *cont, SSyncPeer *pPeer) { ...@@ -989,7 +992,7 @@ static void syncProcessForwardFromPeer(char *cont, SSyncPeer *pPeer) {
if (nodeRole == TAOS_SYNC_ROLE_SLAVE) { if (nodeRole == TAOS_SYNC_ROLE_SLAVE) {
// nodeVersion = pHead->version; // nodeVersion = pHead->version;
(*pNode->writeToCache)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL); (*pNode->writeToCacheFp)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL);
} else { } else {
if (nodeSStatus != TAOS_SYNC_STATUS_INIT) { if (nodeSStatus != TAOS_SYNC_STATUS_INIT) {
syncSaveIntoBuffer(pPeer, pHead); syncSaveIntoBuffer(pPeer, pHead);
......
...@@ -102,9 +102,9 @@ void syncBuildFileAck(SFileAck *pMsg, int32_t vgId) { ...@@ -102,9 +102,9 @@ void syncBuildFileAck(SFileAck *pMsg, int32_t vgId) {
syncBuildHead(&pMsg->head); syncBuildHead(&pMsg->head);
} }
void syncBuildFileInfo(SFileInfo *pMsg, int32_t vgId) { void syncBuildFileVersion(SFileVersion *pMsg, int32_t vgId) {
pMsg->head.type = TAOS_SMSG_SYNC_FILE; pMsg->head.type = TAOS_SMSG_SYNC_FILE;
pMsg->head.vgId = vgId; pMsg->head.vgId = vgId;
pMsg->head.len = sizeof(SFileInfo) - sizeof(SSyncHead); pMsg->head.len = sizeof(SFileVersion) - sizeof(SSyncHead);
syncBuildHead(&pMsg->head); syncBuildHead(&pMsg->head);
} }
\ No newline at end of file
...@@ -25,139 +25,44 @@ ...@@ -25,139 +25,44 @@
#include "tsync.h" #include "tsync.h"
#include "syncInt.h" #include "syncInt.h"
static void syncRemoveExtraFile(SSyncPeer *pPeer, int32_t sindex, int32_t eindex) { static int32_t syncRecvFileVersion(SSyncPeer *pPeer, uint64_t *fversion) {
char name[TSDB_FILENAME_LEN * 2] = {0};
char fname[TSDB_FILENAME_LEN * 3] = {0};
uint32_t magic;
uint64_t fversion;
int64_t size;
uint32_t index = sindex;
SSyncNode *pNode = pPeer->pSyncNode; SSyncNode *pNode = pPeer->pSyncNode;
if (sindex < 0 || eindex < sindex) return; SFileVersion fileVersion;
memset(&fileVersion, 0, sizeof(SFileVersion));
sDebug("%s, extra files will be removed between sindex:%d and eindex:%d", pPeer->id, sindex, eindex); int32_t ret = taosReadMsg(pPeer->syncFd, &fileVersion, sizeof(SFileVersion));
if (ret != sizeof(SFileVersion)) {
while (1) { sError("%s, failed to read fver since %s", pPeer->id, strerror(errno));
name[0] = 0; return -1;
magic = (*pNode->getFileInfo)(pNode->vgId, name, &index, eindex, &size, &fversion); }
if (magic == 0) break;
snprintf(fname, sizeof(fname), "%s/%s", pNode->path, name);
(void)remove(fname);
sInfo("%s, %s is removed for its extra", pPeer->id, fname);
index++; SFileAck fileVersionAck;
if (index > eindex) break; memset(&fileVersionAck, 0, sizeof(SFileAck));
syncBuildFileAck(&fileVersionAck, pNode->vgId);
ret = taosWriteMsg(pPeer->syncFd, &fileVersionAck, sizeof(SFileAck));
if (ret != sizeof(SFileAck)) {
sError("%s, failed to write fver ack since %s", pPeer->id, strerror(errno));
return -1;
} }
*fversion = htobe64(fileVersion.fversion);
return 0;
} }
static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) { static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
SSyncNode *pNode = pPeer->pSyncNode; SSyncNode *pNode = pPeer->pSyncNode;
SFileInfo minfo; memset(&minfo, 0, sizeof(SFileInfo)); /* = {0}; */
SFileInfo sinfo; memset(&sinfo, 0, sizeof(SFileInfo)); /* = {0}; */
SFileAck fileAck; memset(&fileAck, 0, sizeof(SFileAck));
int32_t code = -1;
char name[TSDB_FILENAME_LEN * 2] = {0};
uint32_t pindex = 0; // index in last restore
bool fileChanged = false;
*fversion = 0;
sinfo.index = -1;
while (1) {
// read file info
minfo.index = -1;
int32_t ret = taosReadMsg(pPeer->syncFd, &minfo, sizeof(SFileInfo));
if (ret != sizeof(SFileInfo) || minfo.index == -1) {
sError("%s, failed to read fileinfo while restore file since %s", pPeer->id, strerror(errno));
break;
}
assert(ret == sizeof(SFileInfo));
ret = syncCheckHead((SSyncHead *)(&minfo));
if (ret != 0) {
sError("%s, failed to check fileinfo while restore file since %s", pPeer->id, strerror(ret));
break;
}
// if no more file from master, break;
if (minfo.name[0] == 0 || minfo.magic == 0) {
sDebug("%s, no more files to restore", pPeer->id);
// remove extra files after the current index if (pNode->recvFileFp && (*pNode->recvFileFp)(pNode->pTsdb, pPeer->syncFd) != 0) {
if (sinfo.index != -1) syncRemoveExtraFile(pPeer, sinfo.index + 1, TAOS_SYNC_MAX_INDEX); sError("%s, failed to restore file", pPeer->id);
code = 0; return -1;
break;
}
sDebug("%s, file:%s info is received from master, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%u", pPeer->id,
minfo.name, minfo.index, minfo.size, minfo.fversion, minfo.magic);
// remove extra files on slave between the current and last index
syncRemoveExtraFile(pPeer, pindex + 1, minfo.index - 1);
pindex = minfo.index;
// check the file info
sinfo = minfo;
sinfo.magic = (*pNode->getFileInfo)(pNode->vgId, sinfo.name, &sinfo.index, TAOS_SYNC_MAX_INDEX, &sinfo.size, &sinfo.fversion);
sDebug("%s, local file:%s info, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%u", pPeer->id, sinfo.name,
sinfo.index, sinfo.size, sinfo.fversion, sinfo.magic);
// if file not there or magic is not the same, file shall be synced
memset(&fileAck, 0, sizeof(SFileAck));
syncBuildFileAck(&fileAck, pNode->vgId);
fileAck.sync = (sinfo.magic != minfo.magic || sinfo.size != minfo.size || sinfo.name[0] == 0) ? 1 : 0;
// send file ack
ret = taosWriteMsg(pPeer->syncFd, &fileAck, sizeof(SFileAck));
if (ret != sizeof(SFileAck)) {
sError("%s, failed to write file:%s ack while restore file since %s", pPeer->id, minfo.name, strerror(errno));
break;
}
// if sync is not required, continue
if (fileAck.sync == 0) {
sDebug("%s, %s is the same", pPeer->id, minfo.name);
continue;
} else {
sDebug("%s, %s will be received, size:%" PRId64, pPeer->id, minfo.name, minfo.size);
}
// if sync is required, open file, receive from master, and write to file
// get the full path to file
minfo.name[sizeof(minfo.name) - 1] = 0;
snprintf(name, sizeof(name), "%s/%s", pNode->path, minfo.name);
int32_t dfd = open(name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU | S_IRWXG | S_IRWXO);
if (dfd < 0) {
sError("%s, failed to open file:%s while restore file since %s", pPeer->id, minfo.name, strerror(errno));
break;
}
ret = taosCopyFds(pPeer->syncFd, dfd, minfo.size);
fsync(dfd);
close(dfd);
if (ret < 0) {
sError("%s, failed to copy file:%s while restore file since %s", pPeer->id, minfo.name, strerror(errno));
break;
}
fileChanged = true;
sDebug("%s, %s is received, size:%" PRId64, pPeer->id, minfo.name, minfo.size);
}
if (code == 0 && fileChanged) {
// data file is changed, code shall be set to 1
*fversion = minfo.fversion;
code = 1;
sDebug("%s, file changed after restore file, fver:%" PRIu64, pPeer->id, *fversion);
} }
if (code < 0) { if (syncRecvFileVersion(pPeer, fversion) < 0) {
sError("%s, failed to restore %s since %s", pPeer->id, name, strerror(errno)); return -1;
} }
return code; sInfo("%s, all files are restored, fver:%" PRIu64, pPeer->id, *fversion);
return 0;
} }
static int32_t syncRestoreWal(SSyncPeer *pPeer, uint64_t *wver) { static int32_t syncRestoreWal(SSyncPeer *pPeer, uint64_t *wver) {
...@@ -195,7 +100,7 @@ static int32_t syncRestoreWal(SSyncPeer *pPeer, uint64_t *wver) { ...@@ -195,7 +100,7 @@ static int32_t syncRestoreWal(SSyncPeer *pPeer, uint64_t *wver) {
} }
lastVer = pHead->version; lastVer = pHead->version;
ret = (*pNode->writeToCache)(pNode->vgId, pHead, TAOS_QTYPE_WAL, NULL); ret = (*pNode->writeToCacheFp)(pNode->vgId, pHead, TAOS_QTYPE_WAL, NULL);
if (ret != 0) { if (ret != 0) {
sError("%s, failed to restore record since %s, hver:%" PRIu64, pPeer->id, tstrerror(ret), pHead->version); sError("%s, failed to restore record since %s, hver:%" PRIu64, pPeer->id, tstrerror(ret), pHead->version);
break; break;
...@@ -215,7 +120,7 @@ static char *syncProcessOneBufferedFwd(SSyncPeer *pPeer, char *offset) { ...@@ -215,7 +120,7 @@ static char *syncProcessOneBufferedFwd(SSyncPeer *pPeer, char *offset) {
SSyncNode *pNode = pPeer->pSyncNode; SSyncNode *pNode = pPeer->pSyncNode;
SWalHead * pHead = (SWalHead *)offset; SWalHead * pHead = (SWalHead *)offset;
(*pNode->writeToCache)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL); (*pNode->writeToCacheFp)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL);
offset += pHead->len + sizeof(SWalHead); offset += pHead->len + sizeof(SWalHead);
return offset; return offset;
...@@ -315,20 +220,16 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) { ...@@ -315,20 +220,16 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) {
sDebug("%s, send sync rsp to peer, tranId:%u", pPeer->id, rsp.tranId); sDebug("%s, send sync rsp to peer, tranId:%u", pPeer->id, rsp.tranId);
sInfo("%s, start to restore file, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]); sInfo("%s, start to restore file, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
(*pNode->startSyncFileFp)(pNode->vgId);
int32_t code = syncRestoreFile(pPeer, &fversion); int32_t code = syncRestoreFile(pPeer, &fversion);
if (code < 0) { if (code < 0) {
sError("%s, failed to restore file", pPeer->id); (*pNode->stopSyncFileFp)(pNode->vgId, fversion);
sError("%s, failed to restore files", pPeer->id);
return -1; return -1;
} }
// if code > 0, data file is changed, notify app, and pass the version (*pNode->stopSyncFileFp)(pNode->vgId, fversion);
if (code > 0 && pNode->notifyFileSynced) {
if ((*pNode->notifyFileSynced)(pNode->vgId, fversion) < 0) {
sError("%s, app not in ready state", pPeer->id);
return -1;
}
}
nodeVersion = fversion; nodeVersion = fversion;
sInfo("%s, start to restore wal, fver:%" PRIu64, pPeer->id, nodeVersion); sInfo("%s, start to restore wal, fver:%" PRIu64, pPeer->id, nodeVersion);
...@@ -368,7 +269,7 @@ void *syncRestoreData(void *param) { ...@@ -368,7 +269,7 @@ void *syncRestoreData(void *param) {
atomic_add_fetch_32(&tsSyncNum, 1); atomic_add_fetch_32(&tsSyncNum, 1);
sInfo("%s, start to restore data, sstatus:%s", pPeer->id, syncStatus[nodeSStatus]); sInfo("%s, start to restore data, sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
(*pNode->notifyRole)(pNode->vgId, TAOS_SYNC_ROLE_SYNCING); (*pNode->notifyRoleFp)(pNode->vgId, TAOS_SYNC_ROLE_SYNCING);
if (syncOpenRecvBuffer(pNode) < 0) { if (syncOpenRecvBuffer(pNode) < 0) {
sError("%s, failed to allocate recv buffer, restart connection", pPeer->id); sError("%s, failed to allocate recv buffer, restart connection", pPeer->id);
...@@ -385,7 +286,7 @@ void *syncRestoreData(void *param) { ...@@ -385,7 +286,7 @@ void *syncRestoreData(void *param) {
} }
} }
(*pNode->notifyRole)(pNode->vgId, nodeRole); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole);
nodeSStatus = TAOS_SYNC_STATUS_INIT; nodeSStatus = TAOS_SYNC_STATUS_INIT;
sInfo("%s, restore data over, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]); sInfo("%s, restore data over, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
static int32_t syncGetWalVersion(SSyncNode *pNode, SSyncPeer *pPeer) { static int32_t syncGetWalVersion(SSyncNode *pNode, SSyncPeer *pPeer) {
uint64_t fver, wver; uint64_t fver, wver;
int32_t code = (*pNode->getVersion)(pNode->vgId, &fver, &wver); int32_t code = (*pNode->getVersionFp)(pNode->vgId, &fver, &wver);
if (code != 0) { if (code != 0) {
sDebug("%s, vnode is commiting while retrieve, last wver:%" PRIu64, pPeer->id, pPeer->lastWalVer); sDebug("%s, vnode is commiting while retrieve, last wver:%" PRIu64, pPeer->id, pPeer->lastWalVer);
return -1; return -1;
...@@ -39,7 +39,7 @@ static int32_t syncGetWalVersion(SSyncNode *pNode, SSyncPeer *pPeer) { ...@@ -39,7 +39,7 @@ static int32_t syncGetWalVersion(SSyncNode *pNode, SSyncPeer *pPeer) {
static bool syncIsWalModified(SSyncNode *pNode, SSyncPeer *pPeer) { static bool syncIsWalModified(SSyncNode *pNode, SSyncPeer *pPeer) {
uint64_t fver, wver; uint64_t fver, wver;
int32_t code = (*pNode->getVersion)(pNode->vgId, &fver, &wver); int32_t code = (*pNode->getVersionFp)(pNode->vgId, &fver, &wver);
if (code != 0) { if (code != 0) {
sDebug("%s, vnode is commiting while retrieve, last wver:%" PRIu64, pPeer->id, pPeer->lastWalVer); sDebug("%s, vnode is commiting while retrieve, last wver:%" PRIu64, pPeer->id, pPeer->lastWalVer);
return true; return true;
...@@ -55,7 +55,7 @@ static bool syncIsWalModified(SSyncNode *pNode, SSyncPeer *pPeer) { ...@@ -55,7 +55,7 @@ static bool syncIsWalModified(SSyncNode *pNode, SSyncPeer *pPeer) {
static int32_t syncGetFileVersion(SSyncNode *pNode, SSyncPeer *pPeer) { static int32_t syncGetFileVersion(SSyncNode *pNode, SSyncPeer *pPeer) {
uint64_t fver, wver; uint64_t fver, wver;
int32_t code = (*pNode->getVersion)(pNode->vgId, &fver, &wver); int32_t code = (*pNode->getVersionFp)(pNode->vgId, &fver, &wver);
if (code != 0) { if (code != 0) {
sDebug("%s, vnode is commiting while get fver for retrieve, last fver:%" PRIu64, pPeer->id, pPeer->lastFileVer); sDebug("%s, vnode is commiting while get fver for retrieve, last fver:%" PRIu64, pPeer->id, pPeer->lastFileVer);
return -1; return -1;
...@@ -67,7 +67,7 @@ static int32_t syncGetFileVersion(SSyncNode *pNode, SSyncPeer *pPeer) { ...@@ -67,7 +67,7 @@ static int32_t syncGetFileVersion(SSyncNode *pNode, SSyncPeer *pPeer) {
static bool syncAreFilesModified(SSyncNode *pNode, SSyncPeer *pPeer) { static bool syncAreFilesModified(SSyncNode *pNode, SSyncPeer *pPeer) {
uint64_t fver, wver; uint64_t fver, wver;
int32_t code = (*pNode->getVersion)(pNode->vgId, &fver, &wver); int32_t code = (*pNode->getVersionFp)(pNode->vgId, &fver, &wver);
if (code != 0) { if (code != 0) {
sDebug("%s, vnode is commiting while retrieve, last fver:%" PRIu64, pPeer->id, pPeer->lastFileVer); sDebug("%s, vnode is commiting while retrieve, last fver:%" PRIu64, pPeer->id, pPeer->lastFileVer);
pPeer->fileChanged = 1; pPeer->fileChanged = 1;
...@@ -84,104 +84,54 @@ static bool syncAreFilesModified(SSyncNode *pNode, SSyncPeer *pPeer) { ...@@ -84,104 +84,54 @@ static bool syncAreFilesModified(SSyncNode *pNode, SSyncPeer *pPeer) {
return false; return false;
} }
static int32_t syncRetrieveFile(SSyncPeer *pPeer) { static int32_t syncSendFileVersion(SSyncPeer *pPeer) {
SSyncNode *pNode = pPeer->pSyncNode; SSyncNode *pNode = pPeer->pSyncNode;
SFileInfo fileInfo; memset(&fileInfo, 0, sizeof(SFileInfo));
SFileAck fileAck; memset(&fileAck, 0, sizeof(SFileAck));
int32_t code = -1;
char name[TSDB_FILENAME_LEN * 2] = {0};
if (syncGetFileVersion(pNode, pPeer) < 0) { SFileVersion fileVersion;
pPeer->fileChanged = 1; memset(&fileVersion, 0, sizeof(SFileVersion));
syncBuildFileVersion(&fileVersion, pNode->vgId);
uint64_t fver = pPeer->lastFileVer;
fileVersion.fversion = htobe64(fver);
int32_t ret = taosWriteMsg(pPeer->syncFd, &fileVersion, sizeof(SFileVersion));
if (ret != sizeof(SFileVersion)) {
sError("%s, failed to write fver:%" PRIu64 " since %s", pPeer->id, fver, strerror(errno));
return -1; return -1;
} }
while (1) { SFileAck fileAck;
// retrieve file info memset(&fileAck, 0, sizeof(SFileAck));
fileInfo.name[0] = 0; ret = taosReadMsg(pPeer->syncFd, &fileAck, sizeof(SFileAck));
fileInfo.size = 0; if (ret != sizeof(SFileAck)) {
fileInfo.magic = (*pNode->getFileInfo)(pNode->vgId, fileInfo.name, &fileInfo.index, TAOS_SYNC_MAX_INDEX, sError("%s, failed to read fver ack since %s", pPeer->id, strerror(errno));
&fileInfo.size, &fileInfo.fversion); return -1;
syncBuildFileInfo(&fileInfo, pNode->vgId); }
sDebug("%s, file:%s info is sent, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%u", pPeer->id, fileInfo.name,
fileInfo.index, fileInfo.size, fileInfo.fversion, fileInfo.magic);
// send the file info
int32_t ret = taosWriteMsg(pPeer->syncFd, &(fileInfo), sizeof(SFileInfo));
if (ret != sizeof(SFileInfo)) {
code = -1;
sError("%s, failed to write file:%s info while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
break;
}
// if no file anymore, break
if (fileInfo.magic == 0 || fileInfo.name[0] == 0) {
code = 0;
sDebug("%s, no more files to sync", pPeer->id);
break;
}
// wait for the ack from peer
ret = taosReadMsg(pPeer->syncFd, &fileAck, sizeof(SFileAck));
if (ret != sizeof(SFileAck)) {
code = -1;
sError("%s, failed to read file:%s ack while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
break;
}
ret = syncCheckHead((SSyncHead*)(&fileAck));
if (ret != 0) {
code = -1;
sError("%s, failed to check file:%s ack while retrieve file since %s", pPeer->id, fileInfo.name, strerror(ret));
break;
}
// set the peer sync version
pPeer->sversion = fileInfo.fversion;
// if sync is not required, continue
if (fileAck.sync == 0) {
fileInfo.index++;
sDebug("%s, %s is the same, fver:%" PRIu64, pPeer->id, fileInfo.name, fileInfo.fversion);
continue;
} else {
sDebug("%s, %s will be sent, fver:%" PRIu64, pPeer->id, fileInfo.name, fileInfo.fversion);
}
// get the full path to file // set the peer sync version
snprintf(name, sizeof(name), "%s/%s", pNode->path, fileInfo.name); pPeer->sversion = fver;
// send the file to peer return 0;
int32_t sfd = open(name, O_RDONLY | O_BINARY); }
if (sfd < 0) {
code = -1;
sError("%s, failed to open file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
break;
}
ret = (int32_t)taosSendFile(pPeer->syncFd, sfd, NULL, fileInfo.size); static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
close(sfd); SSyncNode *pNode = pPeer->pSyncNode;
if (ret < 0) {
code = -1;
sError("%s, failed to send file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
break;
}
sDebug("%s, file:%s is sent, size:%" PRId64, pPeer->id, fileInfo.name, fileInfo.size); if (syncGetFileVersion(pNode, pPeer) < 0) {
fileInfo.index++; pPeer->fileChanged = 1;
return -1;
}
// check if processed files are modified if (pNode->sendFileFp && (*pNode->sendFileFp)(pNode->pTsdb, pPeer->syncFd) != 0) {
if (syncAreFilesModified(pNode, pPeer)) { sError("%s, failed to retrieve file", pPeer->id);
code = -1; return -1;
break;
}
} }
if (code != TSDB_CODE_SUCCESS) { if (syncSendFileVersion(pPeer) < 0) {
sError("%s, failed to retrieve file, code:0x%x", pPeer->id, code); return -1;
} }
return code; sInfo("%s, all files are retrieved", pPeer->id);
return 0;
} }
// if only a partial record is read out, upper layer will reload the file to get a complete record // if only a partial record is read out, upper layer will reload the file to get a complete record
...@@ -345,7 +295,7 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) { ...@@ -345,7 +295,7 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) {
while (1) { while (1) {
// retrieve wal info // retrieve wal info
wname[0] = 0; wname[0] = 0;
code = (*pNode->getWalInfo)(pNode->vgId, wname, &index); code = (*pNode->getWalInfoFp)(pNode->vgId, wname, &index);
if (code < 0) { if (code < 0) {
sError("%s, failed to get wal info since:%s, code:0x%x", pPeer->id, strerror(errno), code); sError("%s, failed to get wal info since:%s, code:0x%x", pPeer->id, strerror(errno), code);
break; break;
...@@ -477,7 +427,7 @@ void *syncRetrieveData(void *param) { ...@@ -477,7 +427,7 @@ void *syncRetrieveData(void *param) {
sInfo("%s, start to retrieve data, sstatus:%s, numOfRetrieves:%d", pPeer->id, syncStatus[pPeer->sstatus], sInfo("%s, start to retrieve data, sstatus:%s, numOfRetrieves:%d", pPeer->id, syncStatus[pPeer->sstatus],
pPeer->numOfRetrieves); pPeer->numOfRetrieves);
if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->vgId, pPeer->numOfRetrieves); if (pNode->notifyFlowCtrlFp) (*pNode->notifyFlowCtrlFp)(pNode->vgId, pPeer->numOfRetrieves);
pPeer->syncFd = taosOpenTcpClientSocket(pPeer->ip, pPeer->port, 0); pPeer->syncFd = taosOpenTcpClientSocket(pPeer->ip, pPeer->port, 0);
if (pPeer->syncFd < 0) { if (pPeer->syncFd < 0) {
...@@ -497,10 +447,10 @@ void *syncRetrieveData(void *param) { ...@@ -497,10 +447,10 @@ void *syncRetrieveData(void *param) {
pPeer->numOfRetrieves++; pPeer->numOfRetrieves++;
} else { } else {
pPeer->numOfRetrieves = 0; pPeer->numOfRetrieves = 0;
// if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->vgId, 0); // if (pNode->notifyFlowCtrlFp) (*pNode->notifyFlowCtrlFp)(pNode->vgId, 0);
} }
if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->vgId, 0); if (pNode->notifyFlowCtrlFp) (*pNode->notifyFlowCtrlFp)(pNode->vgId, 0);
pPeer->fileChanged = 0; pPeer->fileChanged = 0;
taosCloseSocket(pPeer->syncFd); taosCloseSocket(pPeer->syncFd);
......
...@@ -296,11 +296,10 @@ void initSync() { ...@@ -296,11 +296,10 @@ void initSync() {
pCfg->replica = 1; pCfg->replica = 1;
pCfg->quorum = 1; pCfg->quorum = 1;
syncInfo.vgId = 1; syncInfo.vgId = 1;
syncInfo.getFileInfo = getFileInfo; syncInfo.getWalInfoFp = getWalInfo;
syncInfo.getWalInfo = getWalInfo; syncInfo.writeToCacheFp = writeToCache;
syncInfo.writeToCache = writeToCache;
syncInfo.confirmForward = confirmForward; syncInfo.confirmForward = confirmForward;
syncInfo.notifyRole = notifyRole; syncInfo.notifyRoleFp = notifyRole;
pCfg->nodeInfo[0].nodeId = 1; pCfg->nodeInfo[0].nodeId = 1;
pCfg->nodeInfo[0].nodePort = 7010; pCfg->nodeInfo[0].nodePort = 7010;
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
AUX_SOURCE_DIRECTORY(src SRC)
ADD_LIBRARY(tfs ${SRC})
TARGET_LINK_LIBRARIES(tfs tutil)
IF (TD_LINUX)
# Someone has no gtest directory, so comment it
# ADD_SUBDIRECTORY(tests)
ENDIF ()
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TD_TFSINT_H
#define TD_TFSINT_H
#include "tlog.h"
#include "tglobal.h"
#include "tfs.h"
#include "tcoding.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int fsDebugFlag;
// For debug purpose
#define fFatal(...) { if (fsDebugFlag & DEBUG_FATAL) { taosPrintLog("TFS FATAL ", 255, __VA_ARGS__); }}
#define fError(...) { if (fsDebugFlag & DEBUG_ERROR) { taosPrintLog("TFS ERROR ", 255, __VA_ARGS__); }}
#define fWarn(...) { if (fsDebugFlag & DEBUG_WARN) { taosPrintLog("TFS WARN ", 255, __VA_ARGS__); }}
#define fInfo(...) { if (fsDebugFlag & DEBUG_INFO) { taosPrintLog("TFS ", 255, __VA_ARGS__); }}
#define fDebug(...) { if (fsDebugFlag & DEBUG_DEBUG) { taosPrintLog("TFS ", cqDebugFlag, __VA_ARGS__); }}
#define fTrace(...) { if (fsDebugFlag & DEBUG_TRACE) { taosPrintLog("TFS ", cqDebugFlag, __VA_ARGS__); }}
// Global Definitions
#define TFS_MIN_DISK_FREE_SIZE 50 * 1024 * 1024
// tdisk.c ======================================================
typedef struct {
int64_t size;
int64_t free;
} SDiskMeta;
typedef struct SDisk {
int level;
int id;
char dir[TSDB_FILENAME_LEN];
SDiskMeta dmeta;
} SDisk;
#define DISK_LEVEL(pd) ((pd)->level)
#define DISK_ID(pd) ((pd)->id)
#define DISK_DIR(pd) ((pd)->dir)
#define DISK_META(pd) ((pd)->dmeta)
#define DISK_SIZE(pd) ((pd)->dmeta.size)
#define DISK_FREE_SIZE(pd) ((pd)->dmeta.free)
SDisk *tfsNewDisk(int level, int id, const char *dir);
SDisk *tfsFreeDisk(SDisk *pDisk);
int tfsUpdateDiskInfo(SDisk *pDisk);
// ttier.c ======================================================
typedef struct {
int64_t size;
int64_t free;
int16_t nAvailDisks; // # of Available disks
} STierMeta;
typedef struct STier {
pthread_spinlock_t lock;
int level;
int16_t ndisk; // # of disks mounted to this tier
int16_t nextid; // next disk id to allocate
STierMeta tmeta;
SDisk * disks[TSDB_MAX_DISKS_PER_TIER];
} STier;
#define TIER_LEVEL(pt) ((pt)->level)
#define TIER_NDISKS(pt) ((pt)->ndisk)
#define TIER_SIZE(pt) ((pt)->tmeta.size)
#define TIER_FREE_SIZE(pt) ((pt)->tmeta.free)
#define TIER_AVAIL_DISKS(pt) ((pt)->tmeta.nAvailDisks)
#define DISK_AT_TIER(pt, id) ((pt)->disks[id])
int tfsInitTier(STier *pTier, int level);
void tfsDestroyTier(STier *pTier);
SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg);
void tfsUpdateTierInfo(STier *pTier, STierMeta *pTierMeta);
int tfsAllocDiskOnTier(STier *pTier);
void tfsGetTierMeta(STier *pTier, STierMeta *pTierMeta);
void tfsPosNextId(STier *pTier);
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os.h"
#include "taoserror.h"
#include "tfsint.h"
// PROTECTED ====================================
SDisk *tfsNewDisk(int level, int id, const char *dir) {
SDisk *pDisk = (SDisk *)calloc(1, sizeof(*pDisk));
if (pDisk == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
return NULL;
}
pDisk->level = level;
pDisk->id = id;
strncpy(pDisk->dir, dir, TSDB_FILENAME_LEN);
return pDisk;
}
SDisk *tfsFreeDisk(SDisk *pDisk) {
if (pDisk) {
free(pDisk);
}
return NULL;
}
int tfsUpdateDiskInfo(SDisk *pDisk) {
ASSERT(pDisk != NULL);
SysDiskSize diskSize = {0};
int code = taosGetDiskSize(pDisk->dir, &diskSize);
if (code != 0) {
fError("failed to update disk information at level %d id %d dir %s since %s", pDisk->level, pDisk->id, pDisk->dir,
strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
}
pDisk->dmeta.size = diskSize.tsize;
pDisk->dmeta.free = diskSize.tsize - diskSize.avail;
return code;
}
\ No newline at end of file
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os.h"
#include "hash.h"
#include "taosdef.h"
#include "taoserror.h"
#include "tfs.h"
#include "tfsint.h"
#define TMPNAME_LEN (TSDB_FILENAME_LEN * 2 + 32)
typedef struct {
pthread_spinlock_t lock;
SFSMeta meta;
int nlevel;
STier tiers[TSDB_MAX_TIERS];
SHashObj * map; // name to did map
} SFS;
typedef struct {
SDisk *pDisk;
} SDiskIter;
#define TFS_META() (pfs->meta)
#define TFS_NLEVEL() (pfs->nlevel)
#define TFS_TIERS() (pfs->tiers)
#define TFS_TIER_AT(level) (TFS_TIERS() + (level))
#define TFS_DISK_AT(level, id) DISK_AT_TIER(TFS_TIER_AT(level), id)
#define TFS_PRIMARY_DISK() TFS_DISK_AT(TFS_PRIMARY_LEVEL, TFS_PRIMARY_ID)
#define TFS_IS_VALID_LEVEL(level) (((level) >= 0) && ((level) < TFS_NLEVEL()))
#define TFS_IS_VALID_ID(level, id) (((id) >= 0) && ((id) < TIER_NDISKS(TFS_TIER_AT(level))))
#define TFS_IS_VALID_DISK(level, id) (TFS_IS_VALID_LEVEL(level) && TFS_IS_VALID_ID(level, id))
#define tfsLock() pthread_spin_lock(&(pfs->lock))
#define tfsUnLock() pthread_spin_unlock(&(pfs->lock))
static SFS tfs = {0};
static SFS *pfs = &tfs;
// STATIC DECLARATION
static int tfsMount(SDiskCfg *pCfg);
static int tfsCheck();
static int tfsCheckAndFormatCfg(SDiskCfg *pCfg);
static int tfsFormatDir(char *idir, char *odir);
static SDisk *tfsGetDiskByID(SDiskID did);
static SDisk *tfsGetDiskByName(const char *dir);
static int tfsOpendirImpl(TDIR *tdir);
static void tfsInitDiskIter(SDiskIter *pIter);
static SDisk *tfsNextDisk(SDiskIter *pIter);
// FS APIs ====================================
int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
ASSERT(ndisk > 0);
for (int level = 0; level < TSDB_MAX_TIERS; level++) {
if (tfsInitTier(TFS_TIER_AT(level), level) < 0) {
while (true) {
level--;
if (level < 0) break;
tfsDestroyTier(TFS_TIER_AT(level));
}
return -1;
}
}
pthread_spin_init(&(pfs->lock), 0);
pfs->map = taosHashInit(TSDB_MAX_TIERS * TSDB_MAX_DISKS_PER_TIER * 2,
taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
if (pfs->map == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
tfsDestroy();
return -1;
}
for (int idisk = 0; idisk < ndisk; idisk++) {
if (tfsMount(pDiskCfg + idisk) < 0) {
tfsDestroy();
return -1;
}
}
if (tfsCheck() < 0) {
tfsDestroy();
return -1;
}
tfsUpdateInfo(NULL);
for (int level = 0; level < TFS_NLEVEL(); level++) {
tfsPosNextId(TFS_TIER_AT(level));
}
return 0;
}
void tfsDestroy() {
taosHashCleanup(pfs->map);
pfs->map = NULL;
pthread_spin_destroy(&(pfs->lock));
for (int level = 0; level < TFS_NLEVEL(); level++) {
tfsDestroyTier(TFS_TIER_AT(level));
}
}
void tfsUpdateInfo(SFSMeta *pFSMeta) {
SFSMeta fsMeta;
STierMeta tierMeta;
if (pFSMeta == NULL) {
pFSMeta = &fsMeta;
}
memset(pFSMeta, 0, sizeof(*pFSMeta));
for (int level = 0; level < TFS_NLEVEL(); level++) {
STier *pTier = TFS_TIER_AT(level);
tfsUpdateTierInfo(pTier, &tierMeta);
pFSMeta->tsize += tierMeta.size;
pFSMeta->avail += tierMeta.free;
}
tfsLock();
pfs->meta = *pFSMeta;
tfsUnLock();
}
void tfsGetMeta(SFSMeta *pMeta) {
ASSERT(pMeta);
tfsLock();
*pMeta = pfs->meta;
tfsUnLock();
}
/* Allocate an existing available tier level
*/
void tfsAllocDisk(int expLevel, int *level, int *id) {
ASSERT(expLevel >= 0);
*level = expLevel;
*id = TFS_UNDECIDED_ID;
if (*level >= TFS_NLEVEL()) {
*level = TFS_NLEVEL() - 1;
}
while (*level >= 0) {
*id = tfsAllocDiskOnTier(TFS_TIER_AT(*level));
if (*id == TFS_UNDECIDED_ID) {
(*level)--;
continue;
}
return;
}
*level = TFS_UNDECIDED_LEVEL;
*id = TFS_UNDECIDED_ID;
}
const char *TFS_PRIMARY_PATH() { return DISK_DIR(TFS_PRIMARY_DISK()); }
const char *TFS_DISK_PATH(int level, int id) { return DISK_DIR(TFS_DISK_AT(level, id)); }
// TFILE APIs ====================================
void tfsInitFile(TFILE *pf, int level, int id, const char *bname) {
ASSERT(TFS_IS_VALID_DISK(level, id));
SDisk *pDisk = TFS_DISK_AT(level, id);
pf->level = level;
pf->id = id;
strncpy(pf->rname, bname, TSDB_FILENAME_LEN);
char tmpName[TMPNAME_LEN] = {0};
snprintf(tmpName, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), bname);
tstrncpy(pf->aname, tmpName, TSDB_FILENAME_LEN);
}
bool tfsIsSameFile(const TFILE *pf1, const TFILE *pf2) {
ASSERT(pf1 != NULL || pf2 != NULL);
if (pf1 == NULL || pf2 == NULL) return false;
if (pf1->level != pf2->level) return false;
if (pf1->id != pf2->id) return false;
if (strncmp(pf1->rname, pf2->rname, TSDB_FILENAME_LEN) != 0) return false;
return true;
}
int tfsEncodeFile(void **buf, TFILE *pf) {
int tlen = 0;
tlen += taosEncodeVariantI32(buf, pf->level);
tlen += taosEncodeVariantI32(buf, pf->id);
tlen += taosEncodeString(buf, pf->rname);
return tlen;
}
void *tfsDecodeFile(void *buf, TFILE *pf) {
int32_t level, id;
char * rname;
buf = taosDecodeVariantI32(buf, &(level));
buf = taosDecodeVariantI32(buf, &(id));
buf = taosDecodeString(buf, &rname);
tfsInitFile(pf, level, id, rname);
tfree(rname);
return buf;
}
void tfsbasename(const TFILE *pf, char *dest) {
char tname[TSDB_FILENAME_LEN] = "\0";
strncpy(tname, pf->aname, TSDB_FILENAME_LEN);
strncpy(dest, basename(tname), TSDB_FILENAME_LEN);
}
void tfsdirname(const TFILE *pf, char *dest) {
char tname[TSDB_FILENAME_LEN] = "\0";
strncpy(tname, pf->aname, TSDB_FILENAME_LEN);
strncpy(dest, dirname(tname), TSDB_FILENAME_LEN);
}
// DIR APIs ====================================
int tfsMkdirAt(const char *rname, int level, int id) {
SDisk *pDisk = TFS_DISK_AT(level, id);
char aname[TMPNAME_LEN];
snprintf(aname, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), rname);
if (taosMkDir(aname, 0755) != 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return 0;
}
int tfsMkdirRecurAt(const char *rname, int level, int id) {
if (tfsMkdirAt(rname, level, id) < 0) {
if (errno == ENOENT) {
// Try to create upper
char *s = strdup(rname);
if (tfsMkdirRecurAt(dirname(s), level, id) < 0) {
tfree(s);
return -1;
}
tfree(s);
if (tfsMkdirAt(rname, level, id) < 0) {
return -1;
}
} else {
return -1;
}
}
return 0;
}
int tfsMkdir(const char *rname) {
for (int level = 0; level < TFS_NLEVEL(); level++) {
STier *pTier = TFS_TIER_AT(level);
for (int id = 0; id < TIER_NDISKS(pTier); id++) {
if (tfsMkdirAt(rname, level, id) < 0) {
return -1;
}
}
}
return 0;
}
int tfsRmdir(const char *rname) {
char aname[TMPNAME_LEN] = "\0";
for (int level = 0; level < TFS_NLEVEL(); level++) {
STier *pTier = TFS_TIER_AT(level);
for (int id = 0; id < TIER_NDISKS(pTier); id++) {
SDisk *pDisk = DISK_AT_TIER(pTier, id);
snprintf(aname, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), rname);
taosRemoveDir(aname);
}
}
return 0;
}
int tfsRename(char *orname, char *nrname) {
char oaname[TMPNAME_LEN] = "\0";
char naname[TMPNAME_LEN] = "\0";
for (int level = 0; level < pfs->nlevel; level++) {
STier *pTier = TFS_TIER_AT(level);
for (int id = 0; id < TIER_NDISKS(pTier); id++) {
SDisk *pDisk = DISK_AT_TIER(pTier, id);
snprintf(oaname, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), orname);
snprintf(naname, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), nrname);
taosRename(oaname, naname);
}
}
return 0;
}
struct TDIR {
SDiskIter iter;
int level;
int id;
char dirname[TSDB_FILENAME_LEN];
TFILE tfile;
DIR * dir;
};
TDIR *tfsOpendir(const char *rname) {
TDIR *tdir = (TDIR *)calloc(1, sizeof(*tdir));
if (tdir == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
return NULL;
}
tfsInitDiskIter(&(tdir->iter));
strncpy(tdir->dirname, rname, TSDB_FILENAME_LEN);
if (tfsOpendirImpl(tdir) < 0) {
free(tdir);
return NULL;
}
return tdir;
}
const TFILE *tfsReaddir(TDIR *tdir) {
if (tdir == NULL || tdir->dir == NULL) return NULL;
char bname[TMPNAME_LEN * 2] = "\0";
while (true) {
struct dirent *dp = NULL;
dp = readdir(tdir->dir);
if (dp != NULL) {
// Skip . and ..
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue;
snprintf(bname, TMPNAME_LEN * 2, "%s/%s", tdir->dirname, dp->d_name);
tfsInitFile(&(tdir->tfile), tdir->level, tdir->id, bname);
return &(tdir->tfile);
}
if (tfsOpendirImpl(tdir) < 0) {
return NULL;
}
if (tdir->dir == NULL) {
terrno = TSDB_CODE_SUCCESS;
return NULL;
}
}
}
void tfsClosedir(TDIR *tdir) {
if (tdir) {
if (tdir->dir != NULL) {
closedir(tdir->dir);
tdir->dir = NULL;
}
free(tdir);
}
}
// private
static int tfsMount(SDiskCfg *pCfg) {
SDiskID did;
SDisk * pDisk = NULL;
if (tfsCheckAndFormatCfg(pCfg) < 0) return -1;
did.level = pCfg->level;
pDisk = tfsMountDiskToTier(TFS_TIER_AT(did.level), pCfg);
if (pDisk == NULL) {
fError("failed to mount disk %s to level %d since %s", pCfg->dir, pCfg->level, tstrerror(terrno));
return -1;
}
did.id = DISK_ID(pDisk);
taosHashPut(pfs->map, (void *)(pCfg->dir), strnlen(pCfg->dir, TSDB_FILENAME_LEN), (void *)(&did), sizeof(did));
if (pfs->nlevel < pCfg->level + 1) pfs->nlevel = pCfg->level + 1;
return 0;
}
static int tfsCheckAndFormatCfg(SDiskCfg *pCfg) {
char dirName[TSDB_FILENAME_LEN] = "\0";
struct stat pstat;
if (pCfg->level < 0 || pCfg->level >= TSDB_MAX_TIERS) {
fError("failed to mount %s to FS since invalid level %d", pCfg->dir, pCfg->level);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (pCfg->primary) {
if (pCfg->level != 0) {
fError("failed to mount %s to FS since disk is primary but level %d not 0", pCfg->dir, pCfg->level);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (TFS_PRIMARY_DISK() != NULL) {
fError("failed to mount %s to FS since duplicate primary mount", pCfg->dir);
terrno = TSDB_CODE_FS_DUP_PRIMARY;
return -1;
}
}
if (tfsFormatDir(pCfg->dir, dirName) < 0) {
fError("failed to mount %s to FS since invalid dir format", pCfg->dir);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (tfsGetDiskByName(dirName) != NULL) {
fError("failed to mount %s to FS since duplicate mount", pCfg->dir);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (access(dirName, W_OK | R_OK | F_OK) != 0) {
fError("failed to mount %s to FS since no R/W access rights", pCfg->dir);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (stat(dirName, &pstat) < 0) {
fError("failed to mount %s to FS since %s", pCfg->dir, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
if (!S_ISDIR(pstat.st_mode)) {
fError("failed to mount %s to FS since not a directory", pCfg->dir);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
strncpy(pCfg->dir, dirName, TSDB_FILENAME_LEN);
return 0;
}
static int tfsFormatDir(char *idir, char *odir) {
wordexp_t wep = {0};
int code = wordexp(idir, &wep, 0);
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(code);
return -1;
}
if (realpath(wep.we_wordv[0], odir) == NULL) {
terrno = TAOS_SYSTEM_ERROR(errno);
wordfree(&wep);
return -1;
}
wordfree(&wep);
return 0;
}
static int tfsCheck() {
if (TFS_PRIMARY_DISK() == NULL) {
fError("no primary disk is set");
terrno = TSDB_CODE_FS_NO_PRIMARY_DISK;
return -1;
}
for (int level = 0; level < TFS_NLEVEL(); level++) {
if (TIER_NDISKS(TFS_TIER_AT(level)) == 0) {
fError("no disk at level %d", level);
terrno = TSDB_CODE_FS_NO_MOUNT_AT_TIER;
return -1;
}
}
return 0;
}
static SDisk *tfsGetDiskByID(SDiskID did) { return TFS_DISK_AT(did.level, did.id); }
static SDisk *tfsGetDiskByName(const char *dir) {
SDiskID did;
SDisk * pDisk = NULL;
void * pr = NULL;
pr = taosHashGet(pfs->map, (void *)dir, strnlen(dir, TSDB_FILENAME_LEN));
if (pr == NULL) return NULL;
did = *(SDiskID *)pr;
pDisk = tfsGetDiskByID(did);
ASSERT(pDisk != NULL);
return pDisk;
}
static int tfsOpendirImpl(TDIR *tdir) {
SDisk *pDisk = NULL;
char adir[TMPNAME_LEN * 2] = "\0";
if (tdir->dir != NULL) {
closedir(tdir->dir);
tdir->dir = NULL;
}
while (true) {
pDisk = tfsNextDisk(&(tdir->iter));
if (pDisk == NULL) return 0;
tdir->level = DISK_LEVEL(pDisk);
tdir->id = DISK_ID(pDisk);
snprintf(adir, TMPNAME_LEN * 2, "%s/%s", DISK_DIR(pDisk), tdir->dirname);
tdir->dir = opendir(adir);
if (tdir->dir != NULL) break;
}
return 0;
}
static void tfsInitDiskIter(SDiskIter *pIter) { pIter->pDisk = TFS_DISK_AT(0, 0); }
static SDisk *tfsNextDisk(SDiskIter *pIter) {
SDisk *pDisk = pIter->pDisk;
if (pDisk == NULL) return NULL;
int level = DISK_LEVEL(pDisk);
int id = DISK_ID(pDisk);
id++;
if (id < TIER_NDISKS(TFS_TIER_AT(level))) {
pIter->pDisk = TFS_DISK_AT(level, id);
ASSERT(pIter->pDisk != NULL);
} else {
level++;
id = 0;
if (level < TFS_NLEVEL()) {
pIter->pDisk = TFS_DISK_AT(level, id);
ASSERT(pIter->pDisk != NULL);
} else {
pIter->pDisk = NULL;
}
}
return pDisk;
}
// OTHER FUNCTIONS ===================================
void taosGetDisk() {
const double unit = 1024 * 1024 * 1024;
SysDiskSize diskSize;
SFSMeta fsMeta;
if (tscEmbedded) {
tfsUpdateInfo(&fsMeta);
tsTotalDataDirGB = (float)(fsMeta.tsize / unit);
tsAvailDataDirGB = (float)(fsMeta.avail / unit);
}
if (taosGetDiskSize(tsLogDir, &diskSize) == 0) {
tsTotalLogDirGB = (float)(diskSize.tsize / unit);
tsAvailLogDirGB = (float)(diskSize.avail / unit);
}
if (taosGetDiskSize("/tmp", &diskSize) == 0) {
tsTotalTmpDirGB = (float)(diskSize.tsize / unit);
tsAvailTmpDirectorySpace = (float)(diskSize.avail / unit);
}
}
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os.h"
#include "taosdef.h"
#include "taoserror.h"
#include "tfsint.h"
#define tfsLockTier(pTier) pthread_spin_lock(&((pTier)->lock))
#define tfsUnLockTier(pTier) pthread_spin_unlock(&((pTier)->lock))
// PROTECTED ==========================================
int tfsInitTier(STier *pTier, int level) {
memset((void *)pTier, 0, sizeof(*pTier));
int code = pthread_spin_init(&(pTier->lock), 0);
if (code) {
terrno = TAOS_SYSTEM_ERROR(code);
return -1;
}
pTier->level = level;
return 0;
}
void tfsDestroyTier(STier *pTier) {
for (int id = 0; id < TSDB_MAX_DISKS_PER_TIER; id++) {
DISK_AT_TIER(pTier, id) = tfsFreeDisk(DISK_AT_TIER(pTier, id));
}
pTier->ndisk = 0;
pthread_spin_destroy(&(pTier->lock));
}
SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) {
ASSERT(pTier->level == pCfg->level);
int id = 0;
SDisk *pDisk;
if (TIER_NDISKS(pTier) >= TSDB_MAX_DISKS_PER_TIER) {
terrno = TSDB_CODE_FS_TOO_MANY_MOUNT;
return NULL;
}
if (pTier->level == 0) {
if (DISK_AT_TIER(pTier, 0) != NULL) {
id = pTier->ndisk;
} else {
if (pCfg->primary) {
id = 0;
} else {
id = pTier->ndisk + 1;
}
if (id >= TSDB_MAX_DISKS_PER_TIER) {
terrno = TSDB_CODE_FS_TOO_MANY_MOUNT;
return NULL;
}
}
} else {
id = pTier->ndisk;
}
pDisk = tfsNewDisk(pCfg->level, id, pCfg->dir);
if (pDisk == NULL) return NULL;
DISK_AT_TIER(pTier, id) = pDisk;
pTier->ndisk++;
fInfo("disk %s is mounted to tier level %d id %d", pCfg->dir, pCfg->level, id);
return DISK_AT_TIER(pTier, id);
}
void tfsUpdateTierInfo(STier *pTier, STierMeta *pTierMeta) {
STierMeta tmeta;
if (pTierMeta == NULL) {
pTierMeta = &tmeta;
}
memset(pTierMeta, 0, sizeof(*pTierMeta));
tfsLockTier(pTier);
for (int id = 0; id < pTier->ndisk; id++) {
if (tfsUpdateDiskInfo(DISK_AT_TIER(pTier, id)) < 0) {
continue;
}
pTierMeta->size += DISK_SIZE(DISK_AT_TIER(pTier, id));
pTierMeta->free += DISK_FREE_SIZE(DISK_AT_TIER(pTier, id));
pTierMeta->nAvailDisks++;
}
pTier->tmeta = *pTierMeta;
tfsUnLockTier(pTier);
}
// Round-Robin to allocate disk on a tier
int tfsAllocDiskOnTier(STier *pTier) {
ASSERT(pTier->ndisk > 0);
int id = TFS_UNDECIDED_ID;
SDisk *pDisk;
tfsLockTier(pTier);
if (TIER_AVAIL_DISKS(pTier) <= 0) {
tfsUnLockTier(pTier);
return id;
}
id = pTier->nextid;
while (true) {
pDisk = DISK_AT_TIER(pTier, id);
ASSERT(pDisk != NULL);
if (DISK_FREE_SIZE(pDisk) < TFS_MIN_DISK_FREE_SIZE) {
id = (id + 1) % pTier->ndisk;
if (id == pTier->nextid) {
tfsUnLockTier(pTier);
return TFS_UNDECIDED_ID;
} else {
continue;
}
} else {
pTier->nextid = (id + 1) % pTier->ndisk;
break;
}
}
tfsUnLockTier(pTier);
return id;
}
void tfsGetTierMeta(STier *pTier, STierMeta *pTierMeta) {
ASSERT(pTierMeta != NULL);
tfsLockTier(pTier);
*pTierMeta = pTier->tmeta;
tfsUnLockTier(pTier);
}
void tfsPosNextId(STier *pTier) {
ASSERT(pTier->ndisk > 0);
int nextid = 0;
for (int id = 1; id < pTier->ndisk; id++) {
SDisk *pLDisk = DISK_AT_TIER(pTier, nextid);
SDisk *pDisk = DISK_AT_TIER(pTier, id);
if (DISK_FREE_SIZE(pDisk) > TFS_MIN_DISK_FREE_SIZE && DISK_FREE_SIZE(pDisk) > DISK_FREE_SIZE(pLDisk)) {
nextid = id;
}
}
pTier->nextid = nextid;
}
\ No newline at end of file
...@@ -4,7 +4,7 @@ PROJECT(TDengine) ...@@ -4,7 +4,7 @@ PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc) INCLUDE_DIRECTORIES(inc)
AUX_SOURCE_DIRECTORY(src SRC) AUX_SOURCE_DIRECTORY(src SRC)
ADD_LIBRARY(tsdb ${SRC}) ADD_LIBRARY(tsdb ${SRC})
TARGET_LINK_LIBRARIES(tsdb common tutil) TARGET_LINK_LIBRARIES(tsdb tfs common tutil)
IF (TD_LINUX) IF (TD_LINUX)
# Someone has no gtest directory, so comment it # Someone has no gtest directory, so comment it
......
...@@ -12,56 +12,32 @@ ...@@ -12,56 +12,32 @@
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _TD_KVSTORE_H_
#define _TD_KVSTORE_H_
#ifdef __cplusplus #ifndef _TD_TSDB_BUFFER_H_
extern "C" { #define _TD_TSDB_BUFFER_H_
#endif
#include <stdint.h>
#define KVSTORE_FILE_VERSION ((uint32_t)0)
typedef int (*iterFunc)(void *, void *cont, int contLen);
typedef void (*afterFunc)(void *);
typedef struct { typedef struct {
int64_t size; // including 512 bytes of header size int64_t blockId;
int64_t tombSize; int offset;
int64_t nRecords; int remain;
int64_t nDels; char data[];
uint32_t magic; } STsdbBufBlock;
} SStoreInfo;
typedef struct { typedef struct {
char * fname; pthread_cond_t poolNotEmpty;
int fd; int bufBlockSize;
char * fsnap; int tBufBlocks;
int sfd; int nBufBlocks;
char * fnew; int64_t index;
int nfd; SList* bufBlockList;
SHashObj * map; } STsdbBufPool;
iterFunc iFunc;
afterFunc aFunc; #define TSDB_BUFFER_RESERVE 1024 // Reseve 1K as commit threshold
void * appH;
SStoreInfo info; STsdbBufPool* tsdbNewBufPool();
} SKVStore; void tsdbFreeBufPool(STsdbBufPool* pBufPool);
int tsdbOpenBufPool(STsdbRepo* pRepo);
#define KVSTORE_MAGIC(s) (s)->info.magic void tsdbCloseBufPool(STsdbRepo* pRepo);
SListNode* tsdbAllocBufBlockFromPool(STsdbRepo* pRepo);
int tdCreateKVStore(char *fname);
int tdDestroyKVStore(char *fname); #endif /* _TD_TSDB_BUFFER_H_ */
SKVStore *tdOpenKVStore(char *fname, iterFunc iFunc, afterFunc aFunc, void *appH); \ No newline at end of file
void tdCloseKVStore(SKVStore *pStore);
int tdKVStoreStartCommit(SKVStore *pStore);
int tdUpdateKVStoreRecord(SKVStore *pStore, uint64_t uid, void *cont, int contLen);
int tdDropKVStoreRecord(SKVStore *pStore, uint64_t uid);
int tdKVStoreEndCommit(SKVStore *pStore);
void tsdbGetStoreInfo(char *fname, uint32_t *magic, int64_t *size);
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
...@@ -13,35 +13,37 @@ ...@@ -13,35 +13,37 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef TDENGINE_DNODE_MGMT_H #ifndef _TD_TSDB_COMMIT_H_
#define TDENGINE_DNODE_MGMT_H #define _TD_TSDB_COMMIT_H_
#ifdef __cplusplus typedef struct {
extern "C" { int minFid;
#endif int midFid;
int maxFid;
#include "trpc.h" TSKEY minKey;
} SRtn;
int32_t dnodeInitMgmt();
void dnodeCleanupMgmt(); typedef struct {
int32_t dnodeInitMgmtTimer(); uint64_t uid;
void dnodeCleanupMgmtTimer(); int64_t offset;
void dnodeDispatchToMgmtQueue(SRpcMsg *rpcMsg); int64_t size;
} SKVRecord;
void* dnodeGetVnode(int32_t vgId);
int32_t dnodeGetVnodeStatus(void *pVnode); void tsdbGetRtnSnap(STsdbRepo *pRepo, SRtn *pRtn);
void* dnodeGetVnodeRworker(void *pVnode); int tsdbEncodeKVRecord(void **buf, SKVRecord *pRecord);
void* dnodeGetVnodeWworker(void *pVnode); void *tsdbDecodeKVRecord(void *buf, SKVRecord *pRecord);
void* dnodeGetVnodeWal(void *pVnode); void *tsdbCommitData(STsdbRepo *pRepo);
void* dnodeGetVnodeTsdb(void *pVnode);
void dnodeReleaseVnode(void *pVnode); static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) {
if (fid >= pRtn->maxFid) {
void dnodeSendRedirectMsg(SRpcMsg *rpcMsg, bool forShell); return 0;
void dnodeGetEpSetForPeer(SRpcEpSet *epSet); } else if (fid >= pRtn->midFid) {
void dnodeGetEpSetForShell(SRpcEpSet *epSet); return 1;
} else if (fid >= pRtn->minFid) {
#ifdef __cplusplus return 2;
} else {
return -1;
}
} }
#endif
#endif #endif /* _TD_TSDB_COMMIT_H_ */
\ No newline at end of file
...@@ -13,26 +13,9 @@ ...@@ -13,26 +13,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef TDENGINE_TSYSTEM_H #ifndef _TD_TSDB_COMMIT_QUEUE_H_
#define TDENGINE_TSYSTEM_H #define _TD_TSDB_COMMIT_QUEUE_H_
#ifdef __cplusplus int tsdbScheduleCommit(STsdbRepo *pRepo);
extern "C" {
#endif
bool taosGetSysMemory(float *memoryUsedMB); #endif /* _TD_TSDB_COMMIT_QUEUE_H_ */
bool taosGetProcMemory(float *memoryUsedMB); \ No newline at end of file
bool taosGetDisk();
bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage);
bool taosGetBandSpeed(float *bandSpeedKb);
bool taosGetProcIO(float *readKB, float *writeKB);
void taosGetSystemInfo();
void taosPrintOsInfo();
void taosKillSystem();
void taosSetCoreDump();
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_TSDB_FS_H_
#define _TD_TSDB_FS_H_
#define TSDB_FS_VERSION 0
// ================== CURRENT file header info
typedef struct {
uint32_t version; // Current file system version (relating to code)
uint32_t len; // Encode content length (including checksum)
} SFSHeader;
// ================== TSDB File System Meta
typedef struct {
uint32_t version; // Commit version from 0 to increase
int64_t totalPoints; // total points
int64_t totalStorage; // Uncompressed total storage
} STsdbFSMeta;
// ==================
typedef struct {
STsdbFSMeta meta; // FS meta
SMFile* pmf; // meta file pointer
SMFile mf; // meta file
SArray* df; // data file array
} SFSStatus;
typedef struct {
pthread_rwlock_t lock;
SFSStatus* cstatus; // current status
SHashObj* metaCache; // meta cache
bool intxn;
SFSStatus* nstatus; // new status
} STsdbFS;
#define FS_CURRENT_STATUS(pfs) ((pfs)->cstatus)
#define FS_NEW_STATUS(pfs) ((pfs)->nstatus)
#define FS_IN_TXN(pfs) (pfs)->intxn
#define FS_VERSION(pfs) ((pfs)->cstatus->meta.version)
#define FS_TXN_VERSION(pfs) ((pfs)->nstatus->meta.version)
typedef struct {
int direction;
uint64_t version; // current FS version
STsdbFS* pfs;
int index; // used to position next fset when version the same
int fid; // used to seek when version is changed
SDFileSet* pSet;
} SFSIter;
#define TSDB_FS_ITER_FORWARD TSDB_ORDER_ASC
#define TSDB_FS_ITER_BACKWARD TSDB_ORDER_DESC
STsdbFS *tsdbNewFS(STsdbCfg *pCfg);
void * tsdbFreeFS(STsdbFS *pfs);
int tsdbOpenFS(STsdbRepo *pRepo);
void tsdbCloseFS(STsdbRepo *pRepo);
void tsdbStartFSTxn(STsdbRepo *pRepo, int64_t pointsAdd, int64_t storageAdd);
int tsdbEndFSTxn(STsdbRepo *pRepo);
int tsdbEndFSTxnWithError(STsdbFS *pfs);
void tsdbUpdateFSTxnMeta(STsdbFS *pfs, STsdbFSMeta *pMeta);
void tsdbUpdateMFile(STsdbFS *pfs, const SMFile *pMFile);
int tsdbUpdateDFileSet(STsdbFS *pfs, const SDFileSet *pSet);
void tsdbFSIterInit(SFSIter *pIter, STsdbFS *pfs, int direction);
void tsdbFSIterSeek(SFSIter *pIter, int fid);
SDFileSet *tsdbFSIterNext(SFSIter *pIter);
int tsdbLoadMetaCache(STsdbRepo *pRepo, bool recoverMeta);
static FORCE_INLINE int tsdbRLockFS(STsdbFS* pFs) {
int code = pthread_rwlock_rdlock(&(pFs->lock));
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(code);
return -1;
}
return 0;
}
static FORCE_INLINE int tsdbWLockFS(STsdbFS* pFs) {
int code = pthread_rwlock_wrlock(&(pFs->lock));
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(code);
return -1;
}
return 0;
}
static FORCE_INLINE int tsdbUnLockFS(STsdbFS* pFs) {
int code = pthread_rwlock_unlock(&(pFs->lock));
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(code);
return -1;
}
return 0;
}
#endif /* _TD_TSDB_FS_H_ */
\ No newline at end of file
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TS_TSDB_FILE_H_
#define _TS_TSDB_FILE_H_
#define TSDB_FILE_HEAD_SIZE 512
#define TSDB_FILE_DELIMITER 0xF00AFA0F
#define TSDB_FILE_INIT_MAGIC 0xFFFFFFFF
#define TSDB_IVLD_FID INT_MIN
#define TSDB_FILE_INFO(tf) (&((tf)->info))
#define TSDB_FILE_F(tf) (&((tf)->f))
#define TSDB_FILE_FD(tf) ((tf)->fd)
#define TSDB_FILE_FULL_NAME(tf) TFILE_NAME(TSDB_FILE_F(tf))
#define TSDB_FILE_OPENED(tf) (TSDB_FILE_FD(tf) >= 0)
#define TSDB_FILE_CLOSED(tf) (!TSDB_FILE_OPENED(tf))
#define TSDB_FILE_SET_CLOSED(f) (TSDB_FILE_FD(f) = -1)
#define TSDB_FILE_LEVEL(tf) TFILE_LEVEL(TSDB_FILE_F(tf))
#define TSDB_FILE_ID(tf) TFILE_ID(TSDB_FILE_F(tf))
#define TSDB_FILE_FSYNC(tf) fsync(TSDB_FILE_FD(tf))
typedef enum { TSDB_FILE_HEAD = 0, TSDB_FILE_DATA, TSDB_FILE_LAST, TSDB_FILE_MAX, TSDB_FILE_META } TSDB_FILE_T;
// =============== SMFile
typedef struct {
int64_t size;
int64_t tombSize;
int64_t nRecords;
int64_t nDels;
uint32_t magic;
} SMFInfo;
typedef struct {
SMFInfo info;
TFILE f;
int fd;
} SMFile;
void tsdbInitMFile(SMFile* pMFile, SDiskID did, int vid, uint32_t ver);
void tsdbInitMFileEx(SMFile* pMFile, SMFile* pOMFile);
int tsdbEncodeSMFile(void** buf, SMFile* pMFile);
void* tsdbDecodeSMFile(void* buf, SMFile* pMFile);
int tsdbEncodeSMFileEx(void** buf, SMFile* pMFile);
void* tsdbDecodeSMFileEx(void* buf, SMFile* pMFile);
int tsdbApplyMFileChange(SMFile* from, SMFile* to);
int tsdbCreateMFile(SMFile* pMFile, bool updateHeader);
int tsdbUpdateMFileHeader(SMFile* pMFile);
int tsdbLoadMFileHeader(SMFile* pMFile, SMFInfo* pInfo);
int tsdbScanAndTryFixMFile(STsdbRepo* pRepo);
int tsdbEncodeMFInfo(void** buf, SMFInfo* pInfo);
void* tsdbDecodeMFInfo(void* buf, SMFInfo* pInfo);
static FORCE_INLINE void tsdbSetMFileInfo(SMFile* pMFile, SMFInfo* pInfo) { pMFile->info = *pInfo; }
static FORCE_INLINE int tsdbOpenMFile(SMFile* pMFile, int flags) {
ASSERT(TSDB_FILE_CLOSED(pMFile));
pMFile->fd = open(TSDB_FILE_FULL_NAME(pMFile), flags);
if (pMFile->fd < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return 0;
}
static FORCE_INLINE void tsdbCloseMFile(SMFile* pMFile) {
if (TSDB_FILE_OPENED(pMFile)) {
close(pMFile->fd);
TSDB_FILE_SET_CLOSED(pMFile);
}
}
static FORCE_INLINE int64_t tsdbSeekMFile(SMFile* pMFile, int64_t offset, int whence) {
ASSERT(TSDB_FILE_OPENED(pMFile));
int64_t loffset = taosLSeek(TSDB_FILE_FD(pMFile), offset, whence);
if (loffset < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return loffset;
}
static FORCE_INLINE int64_t tsdbWriteMFile(SMFile* pMFile, void* buf, int64_t nbyte) {
ASSERT(TSDB_FILE_OPENED(pMFile));
int64_t nwrite = taosWrite(pMFile->fd, buf, nbyte);
if (nwrite < nbyte) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return nwrite;
}
static FORCE_INLINE void tsdbUpdateMFileMagic(SMFile* pMFile, void* pCksum) {
pMFile->info.magic = taosCalcChecksum(pMFile->info.magic, (uint8_t*)(pCksum), sizeof(TSCKSUM));
}
static FORCE_INLINE int tsdbAppendMFile(SMFile* pMFile, void* buf, int64_t nbyte, int64_t* offset) {
ASSERT(TSDB_FILE_OPENED(pMFile));
int64_t toffset;
if ((toffset = tsdbSeekMFile(pMFile, 0, SEEK_END)) < 0) {
return -1;
}
ASSERT(pMFile->info.size == toffset);
if (offset) {
*offset = toffset;
}
if (tsdbWriteMFile(pMFile, buf, nbyte) < 0) {
return -1;
}
pMFile->info.size += nbyte;
return (int)nbyte;
}
static FORCE_INLINE int tsdbRemoveMFile(SMFile* pMFile) { return tfsremove(TSDB_FILE_F(pMFile)); }
static FORCE_INLINE int64_t tsdbReadMFile(SMFile* pMFile, void* buf, int64_t nbyte) {
ASSERT(TSDB_FILE_OPENED(pMFile));
int64_t nread = taosRead(pMFile->fd, buf, nbyte);
if (nread < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return nread;
}
// =============== SDFile
typedef struct {
uint32_t magic;
uint32_t len;
uint32_t totalBlocks;
uint32_t totalSubBlocks;
uint32_t offset;
uint64_t size;
uint64_t tombSize;
} SDFInfo;
typedef struct {
SDFInfo info;
TFILE f;
int fd;
} SDFile;
void tsdbInitDFile(SDFile* pDFile, SDiskID did, int vid, int fid, uint32_t ver, TSDB_FILE_T ftype);
void tsdbInitDFileEx(SDFile* pDFile, SDFile* pODFile);
int tsdbEncodeSDFile(void** buf, SDFile* pDFile);
void* tsdbDecodeSDFile(void* buf, SDFile* pDFile);
int tsdbCreateDFile(SDFile* pDFile, bool updateHeader);
int tsdbUpdateDFileHeader(SDFile* pDFile);
int tsdbLoadDFileHeader(SDFile* pDFile, SDFInfo* pInfo);
int tsdbParseDFilename(const char* fname, int* vid, int* fid, TSDB_FILE_T* ftype, uint32_t* version);
static FORCE_INLINE void tsdbSetDFileInfo(SDFile* pDFile, SDFInfo* pInfo) { pDFile->info = *pInfo; }
static FORCE_INLINE int tsdbOpenDFile(SDFile* pDFile, int flags) {
ASSERT(!TSDB_FILE_OPENED(pDFile));
pDFile->fd = open(TSDB_FILE_FULL_NAME(pDFile), flags);
if (pDFile->fd < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return 0;
}
static FORCE_INLINE void tsdbCloseDFile(SDFile* pDFile) {
if (TSDB_FILE_OPENED(pDFile)) {
close(pDFile->fd);
TSDB_FILE_SET_CLOSED(pDFile);
}
}
static FORCE_INLINE int64_t tsdbSeekDFile(SDFile* pDFile, int64_t offset, int whence) {
ASSERT(TSDB_FILE_OPENED(pDFile));
int64_t loffset = taosLSeek(TSDB_FILE_FD(pDFile), offset, whence);
if (loffset < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return loffset;
}
static FORCE_INLINE int64_t tsdbWriteDFile(SDFile* pDFile, void* buf, int64_t nbyte) {
ASSERT(TSDB_FILE_OPENED(pDFile));
int64_t nwrite = taosWrite(pDFile->fd, buf, nbyte);
if (nwrite < nbyte) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return nwrite;
}
static FORCE_INLINE void tsdbUpdateDFileMagic(SDFile* pDFile, void* pCksm) {
pDFile->info.magic = taosCalcChecksum(pDFile->info.magic, (uint8_t*)(pCksm), sizeof(TSCKSUM));
}
static FORCE_INLINE int tsdbAppendDFile(SDFile* pDFile, void* buf, int64_t nbyte, int64_t* offset) {
ASSERT(TSDB_FILE_OPENED(pDFile));
int64_t toffset;
if ((toffset = tsdbSeekDFile(pDFile, 0, SEEK_END)) < 0) {
return -1;
}
ASSERT(pDFile->info.size == toffset);
if (offset) {
*offset = toffset;
}
if (tsdbWriteDFile(pDFile, buf, nbyte) < 0) {
return -1;
}
pDFile->info.size += nbyte;
return (int)nbyte;
}
static FORCE_INLINE int tsdbRemoveDFile(SDFile* pDFile) { return tfsremove(TSDB_FILE_F(pDFile)); }
static FORCE_INLINE int64_t tsdbReadDFile(SDFile* pDFile, void* buf, int64_t nbyte) {
ASSERT(TSDB_FILE_OPENED(pDFile));
int64_t nread = taosRead(pDFile->fd, buf, nbyte);
if (nread < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return nread;
}
static FORCE_INLINE int tsdbCopyDFile(SDFile* pSrc, SDFile* pDest) {
if (tfscopy(TSDB_FILE_F(pSrc), TSDB_FILE_F(pDest)) < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
tsdbSetDFileInfo(pDest, TSDB_FILE_INFO(pSrc));
return 0;
}
// =============== SDFileSet
typedef struct {
int fid;
int state;
SDFile files[TSDB_FILE_MAX];
} SDFileSet;
#define TSDB_FSET_FID(s) ((s)->fid)
#define TSDB_DFILE_IN_SET(s, t) ((s)->files + (t))
#define TSDB_FSET_LEVEL(s) TSDB_FILE_LEVEL(TSDB_DFILE_IN_SET(s, 0))
#define TSDB_FSET_ID(s) TSDB_FILE_ID(TSDB_DFILE_IN_SET(s, 0))
#define TSDB_FSET_SET_CLOSED(s) \
do { \
for (TSDB_FILE_T ftype = TSDB_FILE_HEAD; ftype < TSDB_FILE_MAX; ftype++) { \
TSDB_FILE_SET_CLOSED(TSDB_DFILE_IN_SET(s, ftype)); \
} \
} while (0);
#define TSDB_FSET_FSYNC(s) \
do { \
for (TSDB_FILE_T ftype = TSDB_FILE_HEAD; ftype < TSDB_FILE_MAX; ftype++) { \
TSDB_FILE_FSYNC(TSDB_DFILE_IN_SET(s, ftype)); \
} \
} while (0);
void tsdbInitDFileSet(SDFileSet* pSet, SDiskID did, int vid, int fid, uint32_t ver);
void tsdbInitDFileSetEx(SDFileSet* pSet, SDFileSet* pOSet);
int tsdbEncodeDFileSet(void** buf, SDFileSet* pSet);
void* tsdbDecodeDFileSet(void* buf, SDFileSet* pSet);
int tsdbEncodeDFileSetEx(void** buf, SDFileSet* pSet);
void* tsdbDecodeDFileSetEx(void* buf, SDFileSet* pSet);
int tsdbApplyDFileSetChange(SDFileSet* from, SDFileSet* to);
int tsdbCreateDFileSet(SDFileSet* pSet, bool updateHeader);
int tsdbUpdateDFileSetHeader(SDFileSet* pSet);
int tsdbScanAndTryFixDFileSet(STsdbRepo *pRepo, SDFileSet* pSet);
static FORCE_INLINE void tsdbCloseDFileSet(SDFileSet* pSet) {
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
tsdbCloseDFile(TSDB_DFILE_IN_SET(pSet, ftype));
}
}
static FORCE_INLINE int tsdbOpenDFileSet(SDFileSet* pSet, int flags) {
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
if (tsdbOpenDFile(TSDB_DFILE_IN_SET(pSet, ftype), flags) < 0) {
tsdbCloseDFileSet(pSet);
return -1;
}
}
return 0;
}
static FORCE_INLINE void tsdbRemoveDFileSet(SDFileSet* pSet) {
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
tsdbRemoveDFile(TSDB_DFILE_IN_SET(pSet, ftype));
}
}
static FORCE_INLINE int tsdbCopyDFileSet(SDFileSet* pSrc, SDFileSet* pDest) {
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
if (tsdbCopyDFile(TSDB_DFILE_IN_SET(pSrc, ftype), TSDB_DFILE_IN_SET(pDest, ftype)) < 0) {
tsdbRemoveDFileSet(pDest);
return -1;
}
}
return 0;
}
static FORCE_INLINE void tsdbGetFidKeyRange(int days, int8_t precision, int fid, TSKEY* minKey, TSKEY* maxKey) {
*minKey = fid * days * tsMsPerDay[precision];
*maxKey = *minKey + days * tsMsPerDay[precision] - 1;
}
#endif /* _TS_TSDB_FILE_H_ */
\ No newline at end of file
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_TSDB_LOG_H_
#define _TD_TSDB_LOG_H_
extern int32_t tsdbDebugFlag;
#define tsdbFatal(...) do { if (tsdbDebugFlag & DEBUG_FATAL) { taosPrintLog("TDB FATAL ", 255, __VA_ARGS__); }} while(0)
#define tsdbError(...) do { if (tsdbDebugFlag & DEBUG_ERROR) { taosPrintLog("TDB ERROR ", 255, __VA_ARGS__); }} while(0)
#define tsdbWarn(...) do { if (tsdbDebugFlag & DEBUG_WARN) { taosPrintLog("TDB WARN ", 255, __VA_ARGS__); }} while(0)
#define tsdbInfo(...) do { if (tsdbDebugFlag & DEBUG_INFO) { taosPrintLog("TDB ", 255, __VA_ARGS__); }} while(0)
#define tsdbDebug(...) do { if (tsdbDebugFlag & DEBUG_DEBUG) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }} while(0)
#define tsdbTrace(...) do { if (tsdbDebugFlag & DEBUG_TRACE) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }} while(0)
#endif /* _TD_TSDB_LOG_H_ */
\ No newline at end of file
此差异已折叠。
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_TSDB_MEMTABLE_H_
#define _TD_TSDB_MEMTABLE_H_
typedef struct {
int rowsInserted;
int rowsUpdated;
int rowsDeleteSucceed;
int rowsDeleteFailed;
int nOperations;
TSKEY keyFirst;
TSKEY keyLast;
} SMergeInfo;
typedef struct {
STable * pTable;
SSkipListIterator *pIter;
} SCommitIter;
typedef struct {
uint64_t uid;
TSKEY keyFirst;
TSKEY keyLast;
int64_t numOfRows;
SSkipList* pData;
} STableData;
typedef struct {
T_REF_DECLARE()
SRWLatch latch;
TSKEY keyFirst;
TSKEY keyLast;
int64_t numOfRows;
int32_t maxTables;
STableData** tData;
SList* actList;
SList* extraBuffList;
SList* bufBlockList;
int64_t pointsAdd; // TODO
int64_t storageAdd; // TODO
} SMemTable;
enum { TSDB_UPDATE_META, TSDB_DROP_META };
#ifdef WINDOWS
#pragma pack(push ,1)
typedef struct {
#else
typedef struct __attribute__((packed)){
#endif
char act;
uint64_t uid;
} SActObj;
#ifdef WINDOWS
#pragma pack(pop)
#endif
typedef struct {
int len;
char cont[];
} SActCont;
int tsdbRefMemTable(STsdbRepo* pRepo, SMemTable* pMemTable);
int tsdbUnRefMemTable(STsdbRepo* pRepo, SMemTable* pMemTable);
int tsdbTakeMemSnapshot(STsdbRepo* pRepo, SMemTable** pMem, SMemTable** pIMem);
void tsdbUnTakeMemSnapShot(STsdbRepo* pRepo, SMemTable* pMem, SMemTable* pIMem);
void* tsdbAllocBytes(STsdbRepo* pRepo, int bytes);
int tsdbAsyncCommit(STsdbRepo* pRepo);
int tsdbLoadDataFromCache(STable* pTable, SSkipListIterator* pIter, TSKEY maxKey, int maxRowsToRead, SDataCols* pCols,
TKEY* filterKeys, int nFilterKeys, bool keepDup, SMergeInfo* pMergeInfo);
void* tsdbCommitData(STsdbRepo* pRepo);
static FORCE_INLINE SDataRow tsdbNextIterRow(SSkipListIterator* pIter) {
if (pIter == NULL) return NULL;
SSkipListNode* node = tSkipListIterGet(pIter);
if (node == NULL) return NULL;
return (SDataRow)SL_GET_NODE_DATA(node);
}
static FORCE_INLINE TSKEY tsdbNextIterKey(SSkipListIterator* pIter) {
SDataRow row = tsdbNextIterRow(pIter);
if (row == NULL) return TSDB_DATA_TIMESTAMP_NULL;
return dataRowKey(row);
}
static FORCE_INLINE TKEY tsdbNextIterTKey(SSkipListIterator* pIter) {
SDataRow row = tsdbNextIterRow(pIter);
if (row == NULL) return TKEY_NULL;
return dataRowTKey(row);
}
#endif /* _TD_TSDB_MEMTABLE_H_ */
\ No newline at end of file
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_TSDB_META_H_
#define _TD_TSDB_META_H_
#define TSDB_MAX_TABLE_SCHEMAS 16
typedef struct STable {
STableId tableId;
ETableType type;
tstr* name; // NOTE: there a flexible string here
uint64_t suid;
struct STable* pSuper; // super table pointer
uint8_t numOfSchemas;
STSchema* schema[TSDB_MAX_TABLE_SCHEMAS];
STSchema* tagSchema;
SKVRow tagVal;
SSkipList* pIndex; // For TSDB_SUPER_TABLE, it is the skiplist index
void* eventHandler; // TODO
void* streamHandler; // TODO
TSKEY lastKey;
SDataRow lastRow;
char* sql;
void* cqhandle;
SRWLatch latch; // TODO: implementa latch functions
T_REF_DECLARE()
} STable;
typedef struct {
pthread_rwlock_t rwLock;
int32_t nTables;
int32_t maxTables;
STable** tables;
SList* superList;
SHashObj* uidMap;
int maxRowBytes;
int maxCols;
} STsdbMeta;
#define TSDB_INIT_NTABLES 1024
#define TABLE_TYPE(t) (t)->type
#define TABLE_NAME(t) (t)->name
#define TABLE_CHAR_NAME(t) TABLE_NAME(t)->data
#define TABLE_UID(t) (t)->tableId.uid
#define TABLE_TID(t) (t)->tableId.tid
#define TABLE_SUID(t) (t)->suid
// #define TSDB_META_FILE_MAGIC(m) KVSTORE_MAGIC((m)->pStore)
#define TSDB_RLOCK_TABLE(t) taosRLockLatch(&((t)->latch))
#define TSDB_RUNLOCK_TABLE(t) taosRUnLockLatch(&((t)->latch))
#define TSDB_WLOCK_TABLE(t) taosWLockLatch(&((t)->latch))
#define TSDB_WUNLOCK_TABLE(t) taosWUnLockLatch(&((t)->latch))
STsdbMeta* tsdbNewMeta(STsdbCfg* pCfg);
void tsdbFreeMeta(STsdbMeta* pMeta);
int tsdbOpenMeta(STsdbRepo* pRepo);
int tsdbCloseMeta(STsdbRepo* pRepo);
STable* tsdbGetTableByUid(STsdbMeta* pMeta, uint64_t uid);
STSchema* tsdbGetTableSchemaByVersion(STable* pTable, int16_t version);
int tsdbWLockRepoMeta(STsdbRepo* pRepo);
int tsdbRLockRepoMeta(STsdbRepo* pRepo);
int tsdbUnlockRepoMeta(STsdbRepo* pRepo);
void tsdbRefTable(STable* pTable);
void tsdbUnRefTable(STable* pTable);
void tsdbUpdateTableSchema(STsdbRepo* pRepo, STable* pTable, STSchema* pSchema, bool insertAct);
int tsdbRestoreTable(STsdbRepo* pRepo, void* cont, int contLen);
void tsdbOrgMeta(STsdbRepo* pRepo);
static FORCE_INLINE int tsdbCompareSchemaVersion(const void *key1, const void *key2) {
if (*(int16_t *)key1 < schemaVersion(*(STSchema **)key2)) {
return -1;
} else if (*(int16_t *)key1 > schemaVersion(*(STSchema **)key2)) {
return 1;
} else {
return 0;
}
}
static FORCE_INLINE STSchema* tsdbGetTableSchemaImpl(STable* pTable, bool lock, bool copy, int16_t version) {
STable* pDTable = (TABLE_TYPE(pTable) == TSDB_CHILD_TABLE) ? pTable->pSuper : pTable;
STSchema* pSchema = NULL;
STSchema* pTSchema = NULL;
if (lock) TSDB_RLOCK_TABLE(pDTable);
if (version < 0) { // get the latest version of schema
pTSchema = pDTable->schema[pDTable->numOfSchemas - 1];
} else { // get the schema with version
void* ptr = taosbsearch(&version, pDTable->schema, pDTable->numOfSchemas, sizeof(STSchema*),
tsdbCompareSchemaVersion, TD_EQ);
if (ptr == NULL) {
terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION;
goto _exit;
}
pTSchema = *(STSchema**)ptr;
}
ASSERT(pTSchema != NULL);
if (copy) {
if ((pSchema = tdDupSchema(pTSchema)) == NULL) terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
} else {
pSchema = pTSchema;
}
_exit:
if (lock) TSDB_RUNLOCK_TABLE(pDTable);
return pSchema;
}
static FORCE_INLINE STSchema* tsdbGetTableSchema(STable* pTable) {
return tsdbGetTableSchemaImpl(pTable, false, false, -1);
}
static FORCE_INLINE STSchema *tsdbGetTableTagSchema(STable *pTable) {
if (pTable->type == TSDB_CHILD_TABLE) { // check child table first
STable *pSuper = pTable->pSuper;
if (pSuper == NULL) return NULL;
return pSuper->tagSchema;
} else if (pTable->type == TSDB_SUPER_TABLE) {
return pTable->tagSchema;
} else {
return NULL;
}
}
static FORCE_INLINE TSKEY tsdbGetTableLastKeyImpl(STable* pTable) {
ASSERT(pTable->lastRow == NULL || pTable->lastKey == dataRowKey(pTable->lastRow));
return pTable->lastKey;
}
#endif /* _TD_TSDB_META_H_ */
\ No newline at end of file
此差异已折叠。
此差异已折叠。
...@@ -13,8 +13,7 @@ ...@@ -13,8 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "tsdb.h" #include "tsdbint.h"
#include "tsdbMain.h"
#define POOL_IS_EMPTY(b) (listNEles((b)->bufBlockList) == 0) #define POOL_IS_EMPTY(b) (listNEles((b)->bufBlockList) == 0)
......
此差异已折叠。
...@@ -13,11 +13,7 @@ ...@@ -13,11 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "os.h" #include "tsdbint.h"
#include "tglobal.h"
#include "tlist.h"
#include "tref.h"
#include "tsdbMain.h"
typedef struct { typedef struct {
bool stop; bool stop;
...@@ -35,7 +31,7 @@ typedef struct { ...@@ -35,7 +31,7 @@ typedef struct {
static void *tsdbLoopCommit(void *arg); static void *tsdbLoopCommit(void *arg);
SCommitQueue tsCommitQueue = {0}; static SCommitQueue tsCommitQueue = {0};
int tsdbInitCommitQueue() { int tsdbInitCommitQueue() {
int nthreads = tsNumOfCommitThreads; int nthreads = tsNumOfCommitThreads;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -13,12 +13,23 @@ ...@@ -13,12 +13,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "tsdb.h" #include "tsdbint.h"
#include "tsdbMain.h"
#define TSDB_DATA_SKIPLIST_LEVEL 5 #define TSDB_DATA_SKIPLIST_LEVEL 5
#define TSDB_MAX_INSERT_BATCH 512 #define TSDB_MAX_INSERT_BATCH 512
typedef struct {
int32_t totalLen;
int32_t len;
SDataRow row;
} SSubmitBlkIter;
typedef struct {
int32_t totalLen;
int32_t len;
void * pMsg;
} SSubmitMsgIter;
static SMemTable * tsdbNewMemTable(STsdbRepo *pRepo); static SMemTable * tsdbNewMemTable(STsdbRepo *pRepo);
static void tsdbFreeMemTable(SMemTable *pMemTable); static void tsdbFreeMemTable(SMemTable *pMemTable);
static STableData *tsdbNewTableData(STsdbCfg *pCfg, STable *pTable); static STableData *tsdbNewTableData(STsdbCfg *pCfg, STable *pTable);
...@@ -41,8 +52,8 @@ static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, ...@@ -41,8 +52,8 @@ static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable,
static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SDataRow row, TSKEY minKey, TSKEY maxKey, static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SDataRow row, TSKEY minKey, TSKEY maxKey,
TSKEY now); TSKEY now);
int32_t tsdbInsertData(TSDB_REPO_T *repo, SSubmitMsg *pMsg, SShellSubmitRspMsg *pRsp) { int32_t tsdbInsertData(STsdbRepo *repo, SSubmitMsg *pMsg, SShellSubmitRspMsg *pRsp) {
STsdbRepo * pRepo = (STsdbRepo *)repo; STsdbRepo * pRepo = repo;
SSubmitMsgIter msgIter = {0}; SSubmitMsgIter msgIter = {0};
SSubmitBlk * pBlock = NULL; SSubmitBlk * pBlock = NULL;
int32_t affectedrows = 0; int32_t affectedrows = 0;
...@@ -225,8 +236,8 @@ int tsdbAsyncCommit(STsdbRepo *pRepo) { ...@@ -225,8 +236,8 @@ int tsdbAsyncCommit(STsdbRepo *pRepo) {
return 0; return 0;
} }
int tsdbSyncCommit(TSDB_REPO_T *repo) { int tsdbSyncCommit(STsdbRepo *repo) {
STsdbRepo *pRepo = (STsdbRepo *)repo; STsdbRepo *pRepo = repo;
tsdbAsyncCommit(pRepo); tsdbAsyncCommit(pRepo);
tsem_wait(&(pRepo->readyToCommit)); tsem_wait(&(pRepo->readyToCommit));
...@@ -254,14 +265,17 @@ int tsdbSyncCommit(TSDB_REPO_T *repo) { ...@@ -254,14 +265,17 @@ int tsdbSyncCommit(TSDB_REPO_T *repo) {
*/ */
int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead, SDataCols *pCols, int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead, SDataCols *pCols,
TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo) { TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo) {
ASSERT(maxRowsToRead > 0 && nFilterKeys >= 0 && pMergeInfo != NULL); ASSERT(maxRowsToRead > 0 && nFilterKeys >= 0);
if (pIter == NULL) return 0; if (pIter == NULL) return 0;
STSchema *pSchema = NULL; STSchema * pSchema = NULL;
TSKEY rowKey = 0; TSKEY rowKey = 0;
TSKEY fKey = 0; TSKEY fKey = 0;
bool isRowDel = false; bool isRowDel = false;
int filterIter = 0; int filterIter = 0;
SDataRow row = NULL; SDataRow row = NULL;
SMergeInfo mInfo;
if (pMergeInfo == NULL) pMergeInfo = &mInfo;
memset(pMergeInfo, 0, sizeof(*pMergeInfo)); memset(pMergeInfo, 0, sizeof(*pMergeInfo));
pMergeInfo->keyFirst = INT64_MAX; pMergeInfo->keyFirst = INT64_MAX;
...@@ -452,11 +466,6 @@ static void tsdbFreeTableData(STableData *pTableData) { ...@@ -452,11 +466,6 @@ static void tsdbFreeTableData(STableData *pTableData) {
static char *tsdbGetTsTupleKey(const void *data) { return dataRowTuple((SDataRow)data); } static char *tsdbGetTsTupleKey(const void *data) { return dataRowTuple((SDataRow)data); }
void tsdbGetFidKeyRange(int daysPerFile, int8_t precision, int fileId, TSKEY *minKey, TSKEY *maxKey) {
*minKey = fileId * daysPerFile * tsMsPerDay[precision];
*maxKey = *minKey + daysPerFile * tsMsPerDay[precision] - 1;
}
static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables) { static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables) {
ASSERT(pMemTable->maxTables < maxTables); ASSERT(pMemTable->maxTables < maxTables);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册