diff --git a/CMakeLists.txt b/CMakeLists.txt
index 588526c286..eb2b1cceb4 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,7 +13,6 @@ ENDIF ()
SET(TD_ACCOUNT FALSE)
SET(TD_ADMIN FALSE)
SET(TD_GRANT FALSE)
-SET(TD_SYNC TRUE)
SET(TD_MQTT TRUE)
SET(TD_TSDB_PLUGINS FALSE)
diff --git a/cmake/define.inc b/cmake/define.inc
index 6e64c2709a..782dc625bf 100755
--- a/cmake/define.inc
+++ b/cmake/define.inc
@@ -13,10 +13,6 @@ IF (TD_GRANT)
ADD_DEFINITIONS(-D_GRANT)
ENDIF ()
-IF (TD_SYNC)
- ADD_DEFINITIONS(-D_SYNC)
-ENDIF ()
-
IF (TD_MQTT)
ADD_DEFINITIONS(-D_MQTT)
ENDIF ()
diff --git a/cmake/input.inc b/cmake/input.inc
index 1ef2045f57..e8324887a0 100755
--- a/cmake/input.inc
+++ b/cmake/input.inc
@@ -47,11 +47,6 @@ IF (${MQTT} MATCHES "false")
MESSAGE(STATUS "build without mqtt module")
ENDIF ()
-IF (${SYNC} MATCHES "false")
- SET(TD_SYNC FALSE)
- MESSAGE(STATUS "build without sync module")
-ENDIF ()
-
IF (${RANDOM_FILE_FAIL} MATCHES "true")
SET(TD_RANDOM_FILE_FAIL TRUE)
MESSAGE(STATUS "build with random-file-fail enabled")
diff --git a/cmake/version.inc b/cmake/version.inc
index 2f0ec81aea..948c7d2d0b 100644
--- a/cmake/version.inc
+++ b/cmake/version.inc
@@ -4,7 +4,7 @@ PROJECT(TDengine)
IF (DEFINED VERNUMBER)
SET(TD_VER_NUMBER ${VERNUMBER})
ELSE ()
- SET(TD_VER_NUMBER "2.0.8.0")
+ SET(TD_VER_NUMBER "2.0.9.0")
ENDIF ()
IF (DEFINED VERCOMPATIBLE)
diff --git a/documentation20/webdocs/markdowndocs/Model-ch.md b/documentation20/webdocs/markdowndocs/Model-ch.md
index d698e3daaf..c0b64bde6e 100644
--- a/documentation20/webdocs/markdowndocs/Model-ch.md
+++ b/documentation20/webdocs/markdowndocs/Model-ch.md
@@ -12,7 +12,7 @@ TDengine采用关系型数据模型,需要建库、建表。因此对于一个
CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 4;
```
上述语句将创建一个名为power的库,这个库的数据将保留365天(超过365天将被自动删除),每10天一个数据文件,内存块数为4。详细的语法及参数请见TAOS SQL
-
+
创建库之后,需要使用SQL命令USE将当前库切换过来,例如:
```cmd
@@ -20,7 +20,7 @@ USE power;
```
就当前连接里操作的库换为power,否则对具体表操作前,需要使用“库名.表名”来指定库的名字。
-
+
**注意:**
- 任何一张表或超级表是属于一个库的,在创建表之前,必须先创建库。
@@ -44,15 +44,17 @@ CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);
```
其中d1001是表名,meters是超级表的表名,后面紧跟标签Location的具体标签值”Beijing.Chaoyang",标签groupId的具体标签值2。虽然在创建表时,需要指定标签值,但可以事后修改。详细细则请见 TAOS SQL。
+**注意:**目前 TDengine 没有从技术层面限制使用一个 database (dbA)的超级表作为模板建立另一个 database (dbB)的子表,后续会禁止这种用法,不建议使用这种方法建表。
+
TDengine建议将数据采集点的全局唯一ID作为表名(比如设备序列号)。但对于有的场景,并没有唯一的ID,可以将多个ID组合成一个唯一的ID。不建议将具有唯一性的ID作为标签值。
-
+
**自动建表**:在某些特殊场景中,用户在写数据时并不确定某个数据采集点的表是否存在,此时可在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。比如:
```cmd
INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);
```
上述SQL语句将记录(now, 10.2, 219, 0.32) 插入进表d1001。如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值“Beijing.Chaoyang", 2。
-
+
## 多列模型 vs 单列模型
TDengine支持多列模型,只要物理量是一个数据采集点同时采集的(时间戳一致),这些量就可以作为不同列放在一张超级表里。但还有一种极限的设计,单列模型,每个采集的物理量都单独建表,因此每种类型的物理量都单独建立一超级表。比如电流、电压、相位,就建三张超级表。
diff --git a/documentation20/webdocs/markdowndocs/faq-ch.md b/documentation20/webdocs/markdowndocs/faq-ch.md
index 42f9761c95..61f70c5962 100644
--- a/documentation20/webdocs/markdowndocs/faq-ch.md
+++ b/documentation20/webdocs/markdowndocs/faq-ch.md
@@ -36,16 +36,20 @@
5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件
-6. 检查防火墙设置,确认TCP/UDP 端口6030-6042 是打开的
+6. 检查防火墙设置(Ubuntu 使用 ufw status,CentOS 使用 firewall-cmd --list-port),确认TCP/UDP 端口6030-6042 是打开的
7. 对于Linux上的JDBC(ODBC, Python, Go等接口类似)连接, 确保*libtaos.so*在目录*/usr/local/taos/driver*里, 并且*/usr/local/taos/driver*在系统库函数搜索路径*LD_LIBRARY_PATH*里
8. 对于windows上的JDBC, ODBC, Python, Go等连接,确保*C:\TDengine\driver\taos.dll*在你的系统库函数搜索目录里 (建议*taos.dll*放在目录 *C:\Windows\System32*)
-9. 如果仍不能排除连接故障,请使用命令行工具nc来分别判断指定端口的TCP和UDP连接是否通畅
- 检查UDP端口连接是否工作:`nc -vuz {hostIP} {port} `
- 检查服务器侧TCP端口连接是否工作:`nc -l {port}`
- 检查客户端侧TCP端口连接是否工作:`nc {hostIP} {port}`
+9. 如果仍不能排除连接故障
+
+ * Linux 系统请使用命令行工具nc来分别判断指定端口的TCP和UDP连接是否通畅
+ 检查UDP端口连接是否工作:`nc -vuz {hostIP} {port} `
+ 检查服务器侧TCP端口连接是否工作:`nc -l {port}`
+ 检查客户端侧TCP端口连接是否工作:`nc {hostIP} {port}`
+
+ * Windows 系统请使用 PowerShell 命令 Net-TestConnection -ComputerName {fqdn} -Port {port} 检测服务段端口是否访问
10. 也可以使用taos程序内嵌的网络连通检测功能,来验证服务器和客户端之间指定的端口连接是否通畅(包括TCP和UDP):[TDengine 内嵌网络检测工具使用指南](https://www.taosdata.com/blog/2020/09/08/1816.html)。
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 059c0650c2..b5d06a4adb 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -1,6 +1,6 @@
name: tdengine
base: core18
-version: '2.0.8.0'
+version: '2.0.9.0'
icon: snap/gui/t-dengine.svg
summary: an open-source big data platform designed and optimized for IoT.
description: |
@@ -72,7 +72,7 @@ parts:
- usr/bin/taosd
- usr/bin/taos
- usr/bin/taosdemo
- - usr/lib/libtaos.so.2.0.8.0
+ - usr/lib/libtaos.so.2.0.9.0
- usr/lib/libtaos.so.1
- usr/lib/libtaos.so
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a2600785c3..931a0a132e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,9 +10,7 @@ ADD_SUBDIRECTORY(client)
ADD_SUBDIRECTORY(query)
ADD_SUBDIRECTORY(kit)
ADD_SUBDIRECTORY(plugins)
-IF (TD_SYNC)
- ADD_SUBDIRECTORY(sync)
-ENDIF ()
+ADD_SUBDIRECTORY(sync)
ADD_SUBDIRECTORY(balance)
ADD_SUBDIRECTORY(mnode)
ADD_SUBDIRECTORY(vnode)
diff --git a/src/balance/src/bnMain.c b/src/balance/src/bnMain.c
index 383f981913..d80488fe9f 100644
--- a/src/balance/src/bnMain.c
+++ b/src/balance/src/bnMain.c
@@ -15,6 +15,7 @@
#define _DEFAULT_SOURCE
#include "os.h"
+#include "tref.h"
#include "tsync.h"
#include "tglobal.h"
#include "dnode.h"
@@ -28,7 +29,9 @@
#include "mnodeUser.h"
#include "mnodeVgroup.h"
-static SBnMgmt tsBnMgmt;;
+extern int64_t tsDnodeRid;
+extern int64_t tsSdbRid;
+static SBnMgmt tsBnMgmt;
static void bnMonitorDnodeModule();
static void bnLock() {
@@ -529,6 +532,9 @@ void bnCheckStatus() {
void * pIter = NULL;
SDnodeObj *pDnode = NULL;
+ void *dnodeSdb = taosAcquireRef(tsSdbRid, tsDnodeRid);
+ if (dnodeSdb == NULL) return;
+
while (1) {
pIter = mnodeGetNextDnode(pIter, &pDnode);
if (pDnode == NULL) break;
@@ -543,6 +549,8 @@ void bnCheckStatus() {
}
mnodeDecDnodeRef(pDnode);
}
+
+ taosReleaseRef(tsSdbRid, tsDnodeRid);
}
void bnCheckModules() {
diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c
index 9fdadfa957..7fc5b8debb 100644
--- a/src/client/src/tscLocalMerge.c
+++ b/src/client/src/tscLocalMerge.c
@@ -1633,7 +1633,7 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
int32_t maxRowSize = MAX(rowSize, finalRowSize);
- char* pbuf = calloc(1, pOutput->num * maxRowSize);
+ char* pbuf = calloc(1, (size_t)(pOutput->num * maxRowSize));
size_t size = tscNumOfFields(pQueryInfo);
SArithmeticSupport arithSup = {0};
@@ -1660,16 +1660,16 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
tExprTreeCalcTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc);
} else {
SSqlExpr* pExpr = pSup->pSqlExpr;
- memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, pExpr->resBytes * pOutput->num);
+ memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, (size_t)(pExpr->resBytes * pOutput->num));
}
offset += pSup->field.bytes;
}
- memcpy(pOutput->data, pbuf, pOutput->num * offset);
+ memcpy(pOutput->data, pbuf, (size_t)(pOutput->num * offset));
tfree(pbuf);
tfree(arithSup.data);
return offset;
-}
\ No newline at end of file
+}
diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h
index 851ca57ba9..5b88c9b0d0 100644
--- a/src/common/inc/tglobal.h
+++ b/src/common/inc/tglobal.h
@@ -35,6 +35,7 @@ extern int32_t tsNumOfMnodes;
extern int32_t tsEnableVnodeBak;
extern int32_t tsEnableTelemetryReporting;
extern char tsEmail[];
+extern char tsArbitrator[];
// common
extern int tsRpcTimer;
diff --git a/src/common/inc/tname.h b/src/common/inc/tname.h
index 6c48ca72f3..9e0093ebfe 100644
--- a/src/common/inc/tname.h
+++ b/src/common/inc/tname.h
@@ -25,6 +25,8 @@ void extractTableName(const char *tableId, char *name);
char* extractDBName(const char *tableId, char *name);
+size_t tableIdPrefix(const char* name, char* prefix, int32_t len);
+
void extractTableNameFromToken(SStrToken *pToken, SStrToken* pTable);
SSchema tGetTableNameColumnSchema();
diff --git a/src/common/src/tname.c b/src/common/src/tname.c
index bea8c52ef2..5c351edf48 100644
--- a/src/common/src/tname.c
+++ b/src/common/src/tname.c
@@ -39,6 +39,13 @@ char* extractDBName(const char* tableId, char* name) {
return strncpy(name, &tableId[offset1 + 1], len);
}
+size_t tableIdPrefix(const char* name, char* prefix, int32_t len) {
+ tstrncpy(prefix, name, len);
+ strcat(prefix, TS_PATH_DELIMITER);
+
+ return strlen(prefix);
+}
+
SSchema tGetTableNameColumnSchema() {
SSchema s = {0};
s.bytes = TSDB_TABLE_NAME_LEN - 1 + VARSTR_HEADER_SIZE;
@@ -198,4 +205,4 @@ SSchema tscGetTbnameColumnSchema() {
strcpy(s.name, TSQL_TBNAME_L);
return s;
-}
\ No newline at end of file
+}
diff --git a/src/connector/go b/src/connector/go
index 8c58c512b6..050667e5b4 160000
--- a/src/connector/go
+++ b/src/connector/go
@@ -1 +1 @@
-Subproject commit 8c58c512b6acda8bcdfa48fdc7140227b5221766
+Subproject commit 050667e5b4d0eafa5387e4283e713559b421203f
diff --git a/src/connector/grafanaplugin b/src/connector/grafanaplugin
index d598db167e..ec77d9049a 160000
--- a/src/connector/grafanaplugin
+++ b/src/connector/grafanaplugin
@@ -1 +1 @@
-Subproject commit d598db167eb256fe67409b7bb3d0eb7fffc3ff8c
+Subproject commit ec77d9049a719dabfd1a7c1122a209e201861944
diff --git a/src/dnode/CMakeLists.txt b/src/dnode/CMakeLists.txt
index 5608cfd6d1..ebb25bf858 100644
--- a/src/dnode/CMakeLists.txt
+++ b/src/dnode/CMakeLists.txt
@@ -12,7 +12,7 @@ AUX_SOURCE_DIRECTORY(src SRC)
IF (TD_LINUX)
ADD_EXECUTABLE(taosd ${SRC})
- TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4)
+ TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync)
IF (TD_SOMODE_STATIC)
TARGET_LINK_LIBRARIES(taosd taos_static)
@@ -32,10 +32,6 @@ IF (TD_LINUX)
TARGET_LINK_LIBRARIES(taosd mqtt)
ENDIF ()
- IF (TD_SYNC)
- TARGET_LINK_LIBRARIES(taosd balance sync)
- ENDIF ()
-
SET(PREPARE_ENV_CMD "prepare_env_cmd")
SET(PREPARE_ENV_TARGET "prepare_env_target")
ADD_CUSTOM_COMMAND(OUTPUT ${PREPARE_ENV_CMD}
diff --git a/src/dnode/inc/dnodeCfg.h b/src/dnode/inc/dnodeCfg.h
index 35d8896460..d74303f325 100644
--- a/src/dnode/inc/dnodeCfg.h
+++ b/src/dnode/inc/dnodeCfg.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitCfg();
void dnodeCleanupCfg();
diff --git a/src/dnode/inc/dnodeCheck.h b/src/dnode/inc/dnodeCheck.h
index a4880b3c11..c94b9e9319 100644
--- a/src/dnode/inc/dnodeCheck.h
+++ b/src/dnode/inc/dnodeCheck.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitCheck();
void dnodeCleanupCheck();
diff --git a/src/dnode/inc/dnodeEps.h b/src/dnode/inc/dnodeEps.h
index 2a203498c1..a5840997b0 100644
--- a/src/dnode/inc/dnodeEps.h
+++ b/src/dnode/inc/dnodeEps.h
@@ -19,8 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-#include "taosmsg.h"
+#include "dnodeInt.h"
int32_t dnodeInitEps();
void dnodeCleanupEps();
diff --git a/src/dnode/inc/dnodeInt.h b/src/dnode/inc/dnodeInt.h
index f4cbee1d13..7595f5fd02 100644
--- a/src/dnode/inc/dnodeInt.h
+++ b/src/dnode/inc/dnodeInt.h
@@ -19,8 +19,13 @@
#ifdef __cplusplus
extern "C" {
#endif
-
+#include "taoserror.h"
+#include "taosmsg.h"
#include "tlog.h"
+#include "trpc.h"
+#include "tglobal.h"
+#include "dnode.h"
+#include "vnode.h"
extern int32_t dDebugFlag;
diff --git a/src/dnode/inc/dnodeMInfos.h b/src/dnode/inc/dnodeMInfos.h
index 2c3eef5d5d..f05e2b6f7b 100644
--- a/src/dnode/inc/dnodeMInfos.h
+++ b/src/dnode/inc/dnodeMInfos.h
@@ -19,8 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-#include "taosmsg.h"
+#include "dnodeInt.h"
int32_t dnodeInitMInfos();
void dnodeCleanupMInfos();
@@ -29,6 +28,10 @@ void dnodeUpdateEpSetForPeer(SRpcEpSet *pEpSet);
void dnodeGetMInfos(SMInfos *pMinfos);
bool dnodeIsMasterEp(char *ep);
+void dnodeSendRedirectMsg(SRpcMsg *rpcMsg, bool forShell);
+void dnodeGetEpSetForPeer(SRpcEpSet *epSet);
+void dnodeGetEpSetForShell(SRpcEpSet *epSet);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/dnode/inc/dnodeMPeer.h b/src/dnode/inc/dnodeMPeer.h
index 00221baa22..b7e566d7e4 100644
--- a/src/dnode/inc/dnodeMPeer.h
+++ b/src/dnode/inc/dnodeMPeer.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitMPeer();
void dnodeCleanupMPeer();
diff --git a/src/dnode/inc/dnodeMRead.h b/src/dnode/inc/dnodeMRead.h
index 8a8e71227d..279098d30e 100644
--- a/src/dnode/inc/dnodeMRead.h
+++ b/src/dnode/inc/dnodeMRead.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitMRead();
void dnodeCleanupMRead();
diff --git a/src/dnode/inc/dnodeMWrite.h b/src/dnode/inc/dnodeMWrite.h
index 6a3d41bc81..8d4fcce3be 100644
--- a/src/dnode/inc/dnodeMWrite.h
+++ b/src/dnode/inc/dnodeMWrite.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitMWrite();
void dnodeCleanupMWrite();
diff --git a/src/dnode/inc/dnodeMain.h b/src/dnode/inc/dnodeMain.h
index c1480407bd..ca79d53afd 100644
--- a/src/dnode/inc/dnodeMain.h
+++ b/src/dnode/inc/dnodeMain.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitSystem();
void dnodeCleanUpSystem();
diff --git a/src/dnode/inc/dnodeModule.h b/src/dnode/inc/dnodeModule.h
index 8618de3244..edcefbdd0c 100644
--- a/src/dnode/inc/dnodeModule.h
+++ b/src/dnode/inc/dnodeModule.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitModules();
void dnodeStartModules();
diff --git a/src/dnode/inc/dnodePeer.h b/src/dnode/inc/dnodePeer.h
index 0dcf48f232..6d337ef6dc 100644
--- a/src/dnode/inc/dnodePeer.h
+++ b/src/dnode/inc/dnodePeer.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitServer();
void dnodeCleanupServer();
diff --git a/src/dnode/inc/dnodeShell.h b/src/dnode/inc/dnodeShell.h
index 300c86c599..3fa66d6a3b 100644
--- a/src/dnode/inc/dnodeShell.h
+++ b/src/dnode/inc/dnodeShell.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitShell();
void dnodeCleanupShell();
diff --git a/src/dnode/inc/dnodeStep.h b/src/dnode/inc/dnodeStep.h
new file mode 100644
index 0000000000..e181e19c46
--- /dev/null
+++ b/src/dnode/inc/dnodeStep.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_DNODE_STEP_H
+#define TDENGINE_DNODE_STEP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "dnodeInt.h"
+
+int32_t dnodeStepInit(SStep *pSteps, int32_t stepSize);
+void dnodeStepCleanup(SStep *pSteps, int32_t stepSize);
+void dnodeReportStep(char *name, char *desc, int8_t finished);
+void dnodeSendStartupStep(SRpcMsg *pMsg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/dnode/inc/dnodeTelemetry.h b/src/dnode/inc/dnodeTelemetry.h
index 6fb62556ae..e4fd5a0376 100644
--- a/src/dnode/inc/dnodeTelemetry.h
+++ b/src/dnode/inc/dnodeTelemetry.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitTelemetry();
void dnodeCleanupTelemetry();
diff --git a/src/dnode/inc/dnodeVMgmt.h b/src/dnode/inc/dnodeVMgmt.h
new file mode 100644
index 0000000000..821196defc
--- /dev/null
+++ b/src/dnode/inc/dnodeVMgmt.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_DNODE_VMGMT_H
+#define TDENGINE_DNODE_VMGMT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "dnodeInt.h"
+
+int32_t dnodeInitVMgmt();
+void dnodeCleanupVMgmt();
+void dnodeDispatchToVMgmtQueue(SRpcMsg *rpcMsg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/dnode/inc/dnodeVRead.h b/src/dnode/inc/dnodeVRead.h
index 5b17693146..30dfb1b3a4 100644
--- a/src/dnode/inc/dnodeVRead.h
+++ b/src/dnode/inc/dnodeVRead.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitVRead();
void dnodeCleanupVRead();
diff --git a/src/dnode/inc/dnodeVWrite.h b/src/dnode/inc/dnodeVWrite.h
index 759e9ca8a5..2ddff210f8 100644
--- a/src/dnode/inc/dnodeVWrite.h
+++ b/src/dnode/inc/dnodeVWrite.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "dnodeInt.h"
int32_t dnodeInitVWrite();
void dnodeCleanupVWrite();
diff --git a/src/dnode/inc/dnodeVnodes.h b/src/dnode/inc/dnodeVnodes.h
new file mode 100644
index 0000000000..1785ed3d06
--- /dev/null
+++ b/src/dnode/inc/dnodeVnodes.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_DNODE_VNODES_H
+#define TDENGINE_DNODE_VNODES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "dnodeInt.h"
+
+int32_t dnodeInitVnodes();
+void dnodeCleanupVnodes();
+int32_t dnodeInitTimer();
+void dnodeCleanupTimer();
+void dnodeSendStatusMsgToMnode();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/dnode/src/dnodeCfg.c b/src/dnode/src/dnodeCfg.c
index 16d109a13a..89249d773b 100644
--- a/src/dnode/src/dnodeCfg.c
+++ b/src/dnode/src/dnodeCfg.c
@@ -16,9 +16,6 @@
#define _DEFAULT_SOURCE
#include "os.h"
#include "cJSON.h"
-#include "tglobal.h"
-#include "dnode.h"
-#include "dnodeInt.h"
#include "dnodeCfg.h"
static SDnodeCfg tsCfg = {0};
diff --git a/src/dnode/src/dnodeCheck.c b/src/dnode/src/dnodeCheck.c
index a9ee4ac649..be26bb967b 100644
--- a/src/dnode/src/dnodeCheck.c
+++ b/src/dnode/src/dnodeCheck.c
@@ -15,8 +15,6 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "tglobal.h"
-#include "dnodeInt.h"
#include "dnodeCheck.h"
typedef struct {
diff --git a/src/dnode/src/dnodeEps.c b/src/dnode/src/dnodeEps.c
index 83f294e05e..09151533e2 100644
--- a/src/dnode/src/dnodeEps.c
+++ b/src/dnode/src/dnodeEps.c
@@ -16,10 +16,7 @@
#define _DEFAULT_SOURCE
#include "os.h"
#include "cJSON.h"
-#include "tglobal.h"
#include "hash.h"
-#include "dnode.h"
-#include "dnodeInt.h"
#include "dnodeEps.h"
static SDnodeEps *tsEps = NULL;
@@ -236,7 +233,14 @@ PRASE_EPS_OVER:
dnodeResetEps(eps);
if (eps) free(eps);
+#if 0
dnodeUpdateEp(dnodeGetDnodeId(), tsLocalEp, tsLocalFqdn, &tsServerPort);
+#else
+ if (dnodeCheckEpChanged(dnodeGetDnodeId(), tsLocalEp)) {
+ dError("dnode:%d, localEp is changed to %s in dnodeEps.json and need reconfigured", dnodeGetDnodeId(), tsLocalEp);
+ return -1;
+ }
+#endif
terrno = 0;
return 0;
diff --git a/src/dnode/src/dnodeMInfos.c b/src/dnode/src/dnodeMInfos.c
index 162de2243e..7c385a889d 100644
--- a/src/dnode/src/dnodeMInfos.c
+++ b/src/dnode/src/dnodeMInfos.c
@@ -16,10 +16,7 @@
#define _DEFAULT_SOURCE
#include "os.h"
#include "cJSON.h"
-#include "tglobal.h"
#include "mnode.h"
-#include "dnode.h"
-#include "dnodeInt.h"
#include "dnodeMInfos.h"
static SMInfos tsMInfos;
@@ -157,12 +154,13 @@ static void dnodeResetMInfos(SMInfos *pMinfos) {
}
static int32_t dnodeReadMInfos() {
- int32_t len = 0;
- int32_t maxLen = 2000;
- char * content = calloc(1, maxLen + 1);
- cJSON * root = NULL;
- FILE * fp = NULL;
- SMInfos minfos = {0};
+ int32_t len = 0;
+ int32_t maxLen = 2000;
+ char * content = calloc(1, maxLen + 1);
+ cJSON * root = NULL;
+ FILE * fp = NULL;
+ SMInfos minfos = {0};
+ bool nodeChanged = false;
char file[TSDB_FILENAME_LEN + 20] = {0};
sprintf(file, "%s/mnodeEpSet.json", tsDnodeDir);
@@ -221,14 +219,19 @@ static int32_t dnodeReadMInfos() {
dError("failed to read mnodeEpSet.json, nodeId not found");
goto PARSE_MINFOS_OVER;
}
- minfos.mnodeInfos[i].mnodeId = nodeId->valueint;
cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
dError("failed to read mnodeEpSet.json, nodeName not found");
goto PARSE_MINFOS_OVER;
}
- strncpy(minfos.mnodeInfos[i].mnodeEp, nodeEp->valuestring, TSDB_EP_LEN);
+
+ SMInfo *pMinfo = &minfos.mnodeInfos[i];
+ pMinfo->mnodeId = nodeId->valueint;
+ tstrncpy(pMinfo->mnodeEp, nodeEp->valuestring, TSDB_EP_LEN);
+
+ bool changed = dnodeCheckEpChanged(pMinfo->mnodeId, pMinfo->mnodeEp);
+ if (changed) nodeChanged = changed;
}
dInfo("read file %s successed", file);
@@ -245,6 +248,11 @@ PARSE_MINFOS_OVER:
dnodeUpdateEp(mInfo->mnodeId, mInfo->mnodeEp, NULL, NULL);
}
dnodeResetMInfos(&minfos);
+
+ if (nodeChanged) {
+ dnodeWriteMInfos();
+ }
+
return 0;
}
@@ -286,3 +294,25 @@ static int32_t dnodeWriteMInfos() {
dInfo("successed to write %s", file);
return 0;
}
+
+void dnodeSendRedirectMsg(SRpcMsg *rpcMsg, bool forShell) {
+ SRpcConnInfo connInfo = {0};
+ rpcGetConnInfo(rpcMsg->handle, &connInfo);
+
+ SRpcEpSet epSet = {0};
+ if (forShell) {
+ dnodeGetEpSetForShell(&epSet);
+ } else {
+ dnodeGetEpSetForPeer(&epSet);
+ }
+
+ dDebug("msg:%s will be redirected, dnodeIp:%s user:%s, numOfEps:%d inUse:%d", taosMsg[rpcMsg->msgType],
+ taosIpStr(connInfo.clientIp), connInfo.user, epSet.numOfEps, epSet.inUse);
+
+ for (int32_t i = 0; i < epSet.numOfEps; ++i) {
+ dDebug("mnode index:%d %s:%d", i, epSet.fqdn[i], epSet.port[i]);
+ epSet.port[i] = htons(epSet.port[i]);
+ }
+
+ rpcSendRedirectRsp(rpcMsg->handle, &epSet);
+}
\ No newline at end of file
diff --git a/src/dnode/src/dnodeMPeer.c b/src/dnode/src/dnodeMPeer.c
index ee6dc5212e..0863666f76 100644
--- a/src/dnode/src/dnodeMPeer.c
+++ b/src/dnode/src/dnodeMPeer.c
@@ -15,16 +15,11 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taoserror.h"
-#include "taosmsg.h"
-#include "tutil.h"
#include "tqueue.h"
#include "twal.h"
-#include "tglobal.h"
#include "mnode.h"
-#include "dnode.h"
-#include "dnodeInt.h"
-#include "dnodeMgmt.h"
+#include "dnodeVMgmt.h"
+#include "dnodeMInfos.h"
#include "dnodeMWrite.h"
typedef struct {
diff --git a/src/dnode/src/dnodeMRead.c b/src/dnode/src/dnodeMRead.c
index 65f3af7b3b..0fc6400d99 100644
--- a/src/dnode/src/dnodeMRead.c
+++ b/src/dnode/src/dnodeMRead.c
@@ -15,16 +15,11 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taoserror.h"
-#include "taosmsg.h"
-#include "tutil.h"
#include "tqueue.h"
#include "twal.h"
-#include "tglobal.h"
#include "mnode.h"
-#include "dnode.h"
-#include "dnodeInt.h"
-#include "dnodeMgmt.h"
+#include "dnodeVMgmt.h"
+#include "dnodeMInfos.h"
#include "dnodeMRead.h"
typedef struct {
diff --git a/src/dnode/src/dnodeMWrite.c b/src/dnode/src/dnodeMWrite.c
index ef2d49ef42..bc387e2171 100644
--- a/src/dnode/src/dnodeMWrite.c
+++ b/src/dnode/src/dnodeMWrite.c
@@ -15,17 +15,11 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taoserror.h"
-#include "taosmsg.h"
-#include "tutil.h"
#include "ttimer.h"
#include "tqueue.h"
-#include "twal.h"
-#include "tglobal.h"
#include "mnode.h"
-#include "dnode.h"
-#include "dnodeInt.h"
-#include "dnodeMgmt.h"
+#include "dnodeVMgmt.h"
+#include "dnodeMInfos.h"
#include "dnodeMWrite.h"
typedef struct {
diff --git a/src/dnode/src/dnodeMain.c b/src/dnode/src/dnodeMain.c
index 9f52dbd331..502c410ce3 100644
--- a/src/dnode/src/dnodeMain.c
+++ b/src/dnode/src/dnodeMain.c
@@ -16,15 +16,12 @@
#define _DEFAULT_SOURCE
#include "os.h"
#include "taos.h"
-#include "tutil.h"
#include "tconfig.h"
-#include "tglobal.h"
#include "tfile.h"
#include "twal.h"
-#include "trpc.h"
-#include "dnode.h"
-#include "dnodeInt.h"
-#include "dnodeMgmt.h"
+// #include "tfs.h"
+#include "tsync.h"
+#include "dnodeStep.h"
#include "dnodePeer.h"
#include "dnodeModule.h"
#include "dnodeEps.h"
@@ -33,6 +30,8 @@
#include "dnodeCheck.h"
#include "dnodeVRead.h"
#include "dnodeVWrite.h"
+#include "dnodeVMgmt.h"
+#include "dnodeVnodes.h"
#include "dnodeMRead.h"
#include "dnodeMWrite.h"
#include "dnodeMPeer.h"
@@ -45,38 +44,32 @@ static int32_t dnodeInitStorage();
static void dnodeCleanupStorage();
static void dnodeSetRunStatus(SRunStatus status);
static void dnodeCheckDataDirOpenned(char *dir);
-static int32_t dnodeInitComponents();
-static void dnodeCleanupComponents(int32_t stepId);
static int dnodeCreateDir(const char *dir);
-typedef struct {
- const char *const name;
- int32_t (*init)();
- void (*cleanup)();
-} SDnodeComponent;
-
-static const SDnodeComponent tsDnodeComponents[] = {
- {"tfile", tfInit, tfCleanup},
- {"rpc", rpcInit, rpcCleanup},
- {"storage", dnodeInitStorage, dnodeCleanupStorage},
- {"dnodecfg", dnodeInitCfg, dnodeCleanupCfg},
- {"dnodeeps", dnodeInitEps, dnodeCleanupEps},
- {"globalcfg" ,taosCheckGlobalCfg, NULL},
- {"mnodeinfos",dnodeInitMInfos, dnodeCleanupMInfos},
- {"wal", walInit, walCleanUp},
- {"check", dnodeInitCheck, dnodeCleanupCheck}, // NOTES: dnodeInitCheck must be behind the dnodeinitStorage component !!!
- {"vread", dnodeInitVRead, dnodeCleanupVRead},
- {"vwrite", dnodeInitVWrite, dnodeCleanupVWrite},
- {"mread", dnodeInitMRead, dnodeCleanupMRead},
- {"mwrite", dnodeInitMWrite, dnodeCleanupMWrite},
- {"mpeer", dnodeInitMPeer, dnodeCleanupMPeer},
- {"client", dnodeInitClient, dnodeCleanupClient},
- {"server", dnodeInitServer, dnodeCleanupServer},
- {"mgmt", dnodeInitMgmt, dnodeCleanupMgmt},
- {"modules", dnodeInitModules, dnodeCleanupModules},
- {"mgmt-tmr", dnodeInitMgmtTimer, dnodeCleanupMgmtTimer},
- {"shell", dnodeInitShell, dnodeCleanupShell},
- {"telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
+static SStep tsDnodeSteps[] = {
+ {"dnode-tfile", tfInit, tfCleanup},
+ {"dnode-rpc", rpcInit, rpcCleanup},
+ {"dnode-globalcfg", taosCheckGlobalCfg, NULL},
+ {"dnode-storage", dnodeInitStorage, dnodeCleanupStorage},
+ {"dnode-cfg", dnodeInitCfg, dnodeCleanupCfg},
+ {"dnode-eps", dnodeInitEps, dnodeCleanupEps},
+ {"dnode-minfos", dnodeInitMInfos, dnodeCleanupMInfos},
+ {"dnode-wal", walInit, walCleanUp},
+ {"dnode-sync", syncInit, syncCleanUp},
+ {"dnode-check", dnodeInitCheck, dnodeCleanupCheck}, // NOTES: dnodeInitCheck must be behind the dnodeinitStorage component !!!
+ {"dnode-vread", dnodeInitVRead, dnodeCleanupVRead},
+ {"dnode-vwrite", dnodeInitVWrite, dnodeCleanupVWrite},
+ {"dnode-vmgmt", dnodeInitVMgmt, dnodeCleanupVMgmt},
+ {"dnode-mread", dnodeInitMRead, dnodeCleanupMRead},
+ {"dnode-mwrite", dnodeInitMWrite, dnodeCleanupMWrite},
+ {"dnode-mpeer", dnodeInitMPeer, dnodeCleanupMPeer},
+ {"dnode-client", dnodeInitClient, dnodeCleanupClient},
+ {"dnode-server", dnodeInitServer, dnodeCleanupServer},
+ {"dnode-vnodes", dnodeInitVnodes, dnodeCleanupVnodes},
+ {"dnode-modules", dnodeInitModules, dnodeCleanupModules},
+ {"dnode-tmr", dnodeInitTimer, dnodeCleanupTimer},
+ {"dnode-shell", dnodeInitShell, dnodeCleanupShell},
+ {"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
};
static int dnodeCreateDir(const char *dir) {
@@ -87,24 +80,14 @@ static int dnodeCreateDir(const char *dir) {
return 0;
}
-static void dnodeCleanupComponents(int32_t stepId) {
- for (int32_t i = stepId; i >= 0; i--) {
- if (tsDnodeComponents[i].cleanup) {
- (*tsDnodeComponents[i].cleanup)();
- }
- }
+static void dnodeCleanupComponents() {
+ int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
+ dnodeStepCleanup(tsDnodeSteps, stepSize);
}
static int32_t dnodeInitComponents() {
- int32_t code = 0;
- for (int32_t i = 0; i < sizeof(tsDnodeComponents) / sizeof(tsDnodeComponents[0]); i++) {
- if (tsDnodeComponents[i].init() != 0) {
- dnodeCleanupComponents(i);
- code = -1;
- break;
- }
- }
- return code;
+ int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
+ return dnodeStepInit(tsDnodeSteps, stepSize);
}
int32_t dnodeInitSystem() {
@@ -151,7 +134,7 @@ int32_t dnodeInitSystem() {
void dnodeCleanUpSystem() {
if (dnodeGetRunStatus() != TSDB_RUN_STATUS_STOPPED) {
dnodeSetRunStatus(TSDB_RUN_STATUS_STOPPED);
- dnodeCleanupComponents(sizeof(tsDnodeComponents) / sizeof(tsDnodeComponents[0]) - 1);
+ dnodeCleanupComponents();
taos_cleanup();
taosCloseLog();
}
diff --git a/src/dnode/src/dnodeMgmt.c b/src/dnode/src/dnodeMgmt.c
deleted file mode 100644
index 15378c77c1..0000000000
--- a/src/dnode/src/dnodeMgmt.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#define _DEFAULT_SOURCE
-#include "os.h"
-#include "cJSON.h"
-#include "taoserror.h"
-#include "taosmsg.h"
-#include "ttimer.h"
-#include "tsdb.h"
-#include "twal.h"
-#include "tqueue.h"
-#include "tsync.h"
-#include "ttimer.h"
-#include "tbn.h"
-#include "tglobal.h"
-#include "dnode.h"
-#include "vnode.h"
-#include "mnode.h"
-#include "dnodeInt.h"
-#include "dnodeMgmt.h"
-#include "dnodeEps.h"
-#include "dnodeCfg.h"
-#include "dnodeMInfos.h"
-#include "dnodeVRead.h"
-#include "dnodeVWrite.h"
-#include "dnodeModule.h"
-
-typedef struct {
- pthread_t thread;
- int32_t threadIndex;
- int32_t failed;
- int32_t opened;
- int32_t vnodeNum;
- int32_t * vnodeList;
-} SOpenVnodeThread;
-
-typedef struct {
- SRpcMsg rpcMsg;
- char pCont[];
-} SMgmtMsg;
-
-void * tsDnodeTmr = NULL;
-static void * tsStatusTimer = NULL;
-static uint32_t tsRebootTime;
-static taos_qset tsMgmtQset = NULL;
-static taos_queue tsMgmtQueue = NULL;
-static pthread_t tsQthread;
-
-static void dnodeProcessStatusRsp(SRpcMsg *pMsg);
-static void dnodeSendStatusMsg(void *handle, void *tmrId);
-static void *dnodeProcessMgmtQueue(void *param);
-
-static int32_t dnodeOpenVnodes();
-static void dnodeCloseVnodes();
-static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *pMsg);
-static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *pMsg);
-static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *pMsg);
-static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg);
-static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg);
-static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg);
-static int32_t (*dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *pMsg);
-
-int32_t dnodeInitMgmt() {
- dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeProcessCreateVnodeMsg;
- dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeProcessAlterVnodeMsg;
- dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeProcessDropVnodeMsg;
- dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeProcessAlterStreamMsg;
- dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeProcessConfigDnodeMsg;
- dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_MNODE] = dnodeProcessCreateMnodeMsg;
-
- dnodeAddClientRspHandle(TSDB_MSG_TYPE_DM_STATUS_RSP, dnodeProcessStatusRsp);
- tsRebootTime = taosGetTimestampSec();
-
- int32_t code = vnodeInitResources();
- if (code != TSDB_CODE_SUCCESS) {
- dnodeCleanupMgmt();
- return -1;
- }
-
- // create the queue and thread to handle the message
- tsMgmtQset = taosOpenQset();
- if (tsMgmtQset == NULL) {
- dError("failed to create the mgmt queue set");
- dnodeCleanupMgmt();
- return -1;
- }
-
- tsMgmtQueue = taosOpenQueue();
- if (tsMgmtQueue == NULL) {
- dError("failed to create the mgmt queue");
- dnodeCleanupMgmt();
- return -1;
- }
-
- taosAddIntoQset(tsMgmtQset, tsMgmtQueue, NULL);
-
- pthread_attr_t thAttr;
- pthread_attr_init(&thAttr);
- pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
-
- code = pthread_create(&tsQthread, &thAttr, dnodeProcessMgmtQueue, NULL);
- pthread_attr_destroy(&thAttr);
- if (code != 0) {
- dError("failed to create thread to process mgmt queue, reason:%s", strerror(errno));
- dnodeCleanupMgmt();
- return -1;
- }
-
- code = dnodeOpenVnodes();
- if (code != TSDB_CODE_SUCCESS) {
- dnodeCleanupMgmt();
- return -1;
- }
-
- dInfo("dnode mgmt is initialized");
-
- return TSDB_CODE_SUCCESS;
-}
-
-int32_t dnodeInitMgmtTimer() {
- tsDnodeTmr = taosTmrInit(100, 200, 60000, "DND-DM");
- if (tsDnodeTmr == NULL) {
- dError("failed to init dnode timer");
- dnodeCleanupMgmt();
- return -1;
- }
-
- taosTmrReset(dnodeSendStatusMsg, 500, NULL, tsDnodeTmr, &tsStatusTimer);
- dInfo("dnode mgmt timer is initialized");
- return TSDB_CODE_SUCCESS;
-}
-
-void dnodeSendStatusMsgToMnode() {
- if (tsDnodeTmr != NULL && tsStatusTimer != NULL) {
- dInfo("force send status msg to mnode");
- taosTmrReset(dnodeSendStatusMsg, 3, NULL, tsDnodeTmr, &tsStatusTimer);
- }
-}
-
-void dnodeCleanupMgmtTimer() {
- if (tsStatusTimer != NULL) {
- taosTmrStopA(&tsStatusTimer);
- tsStatusTimer = NULL;
- }
-
- if (tsDnodeTmr != NULL) {
- taosTmrCleanUp(tsDnodeTmr);
- tsDnodeTmr = NULL;
- }
-}
-
-void dnodeCleanupMgmt() {
- dnodeCleanupMgmtTimer();
- dnodeCloseVnodes();
-
- if (tsMgmtQset) taosQsetThreadResume(tsMgmtQset);
- if (tsQthread) pthread_join(tsQthread, NULL);
-
- if (tsMgmtQueue) taosCloseQueue(tsMgmtQueue);
- if (tsMgmtQset) taosCloseQset(tsMgmtQset);
- tsMgmtQset = NULL;
- tsMgmtQueue = NULL;
-
- vnodeCleanupResources();
-}
-
-static int32_t dnodeWriteToMgmtQueue(SRpcMsg *pMsg) {
- int32_t size = sizeof(SMgmtMsg) + pMsg->contLen;
- SMgmtMsg *pMgmt = taosAllocateQitem(size);
- if (pMgmt == NULL) {
- return TSDB_CODE_DND_OUT_OF_MEMORY;
- }
-
- pMgmt->rpcMsg = *pMsg;
- pMgmt->rpcMsg.pCont = pMgmt->pCont;
- memcpy(pMgmt->pCont, pMsg->pCont, pMsg->contLen);
- taosWriteQitem(tsMgmtQueue, TAOS_QTYPE_RPC, pMgmt);
-
- return TSDB_CODE_SUCCESS;
-}
-
-void dnodeDispatchToMgmtQueue(SRpcMsg *pMsg) {
- int32_t code = dnodeWriteToMgmtQueue(pMsg);
- if (code != TSDB_CODE_SUCCESS) {
- SRpcMsg rsp = {.handle = pMsg->handle, .code = code};
- rpcSendResponse(&rsp);
- }
-
- rpcFreeCont(pMsg->pCont);
-}
-
-static void *dnodeProcessMgmtQueue(void *param) {
- SMgmtMsg *pMgmt;
- SRpcMsg * pMsg;
- SRpcMsg rsp = {0};
- int32_t qtype;
- void * handle;
-
- while (1) {
- if (taosReadQitemFromQset(tsMgmtQset, &qtype, (void **)&pMgmt, &handle) == 0) {
- dDebug("qset:%p, dnode mgmt got no message from qset, exit", tsMgmtQset);
- break;
- }
-
- pMsg = &pMgmt->rpcMsg;
- dDebug("msg:%p, ahandle:%p type:%s will be processed", pMgmt, pMsg->ahandle, taosMsg[pMsg->msgType]);
- if (dnodeProcessMgmtMsgFp[pMsg->msgType]) {
- rsp.code = (*dnodeProcessMgmtMsgFp[pMsg->msgType])(pMsg);
- } else {
- rsp.code = TSDB_CODE_DND_MSG_NOT_PROCESSED;
- }
-
- rsp.handle = pMsg->handle;
- rsp.pCont = NULL;
- rpcSendResponse(&rsp);
-
- taosFreeQitem(pMsg);
- }
-
- return NULL;
-}
-
-static int32_t dnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
- DIR *dir = opendir(tsVnodeDir);
- if (dir == NULL) {
- return TSDB_CODE_DND_NO_WRITE_ACCESS;
- }
-
- *numOfVnodes = 0;
- struct dirent *de = NULL;
- while ((de = readdir(dir)) != NULL) {
- if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
- if (de->d_type & DT_DIR) {
- if (strncmp("vnode", de->d_name, 5) != 0) continue;
- int32_t vnode = atoi(de->d_name + 5);
- if (vnode == 0) continue;
-
- (*numOfVnodes)++;
-
- if (*numOfVnodes >= TSDB_MAX_VNODES) {
- dError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
- continue;
- } else {
- vnodeList[*numOfVnodes - 1] = vnode;
- }
- }
- }
- closedir(dir);
-
- return TSDB_CODE_SUCCESS;
-}
-
-static void *dnodeOpenVnode(void *param) {
- SOpenVnodeThread *pThread = param;
- char vnodeDir[TSDB_FILENAME_LEN * 3];
-
- dDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum);
-
- for (int32_t v = 0; v < pThread->vnodeNum; ++v) {
- int32_t vgId = pThread->vnodeList[v];
- snprintf(vnodeDir, TSDB_FILENAME_LEN * 3, "%s/vnode%d", tsVnodeDir, vgId);
- if (vnodeOpen(vgId, vnodeDir) < 0) {
- dError("vgId:%d, failed to open vnode by thread:%d", vgId, pThread->threadIndex);
- pThread->failed++;
- } else {
- dDebug("vgId:%d, is openned by thread:%d", vgId, pThread->threadIndex);
- pThread->opened++;
- }
- }
-
- dDebug("thread:%d, total vnodes:%d, openned:%d failed:%d", pThread->threadIndex, pThread->vnodeNum, pThread->opened,
- pThread->failed);
- return NULL;
-}
-
-static int32_t dnodeOpenVnodes() {
- int32_t vnodeList[TSDB_MAX_VNODES] = {0};
- int32_t numOfVnodes = 0;
- int32_t status = dnodeGetVnodeList(vnodeList, &numOfVnodes);
-
- if (status != TSDB_CODE_SUCCESS) {
- dInfo("get dnode list failed");
- return status;
- }
-
- int32_t threadNum = tsNumOfCores;
- int32_t vnodesPerThread = numOfVnodes / threadNum + 1;
- SOpenVnodeThread *threads = calloc(threadNum, sizeof(SOpenVnodeThread));
- for (int32_t t = 0; t < threadNum; ++t) {
- threads[t].threadIndex = t;
- threads[t].vnodeList = calloc(vnodesPerThread, sizeof(int32_t));
- }
-
- for (int32_t v = 0; v < numOfVnodes; ++v) {
- int32_t t = v % threadNum;
- SOpenVnodeThread *pThread = &threads[t];
- pThread->vnodeList[pThread->vnodeNum++] = vnodeList[v];
- }
-
- dDebug("start %d threads to open %d vnodes", threadNum, numOfVnodes);
-
- for (int32_t t = 0; t < threadNum; ++t) {
- SOpenVnodeThread *pThread = &threads[t];
- if (pThread->vnodeNum == 0) continue;
-
- pthread_attr_t thAttr;
- pthread_attr_init(&thAttr);
- pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
- if (pthread_create(&pThread->thread, &thAttr, dnodeOpenVnode, pThread) != 0) {
- dError("thread:%d, failed to create thread to open vnode, reason:%s", pThread->threadIndex, strerror(errno));
- }
-
- pthread_attr_destroy(&thAttr);
- }
-
- int32_t openVnodes = 0;
- int32_t failedVnodes = 0;
- for (int32_t t = 0; t < threadNum; ++t) {
- SOpenVnodeThread *pThread = &threads[t];
- if (pThread->vnodeNum > 0 && pThread->thread) {
- pthread_join(pThread->thread, NULL);
- }
- openVnodes += pThread->opened;
- failedVnodes += pThread->failed;
- free(pThread->vnodeList);
- }
-
- free(threads);
- dInfo("there are total vnodes:%d, openned:%d failed:%d", numOfVnodes, openVnodes, failedVnodes);
-
- return TSDB_CODE_SUCCESS;
-}
-
-static void dnodeCloseVnodes() {
- int32_t vnodeList[TSDB_MAX_VNODES]= {0};
- int32_t numOfVnodes = 0;
- int32_t status;
-
- status = vnodeGetVnodeList(vnodeList, &numOfVnodes);
-
- if (status != TSDB_CODE_SUCCESS) {
- dInfo("get dnode list failed");
- return;
- }
-
- for (int32_t i = 0; i < numOfVnodes; ++i) {
- vnodeClose(vnodeList[i]);
- }
-
- dInfo("total vnodes:%d are all closed", numOfVnodes);
-}
-
-static void* dnodeParseVnodeMsg(SRpcMsg *rpcMsg) {
- SCreateVnodeMsg *pCreate = rpcMsg->pCont;
- pCreate->cfg.vgId = htonl(pCreate->cfg.vgId);
- pCreate->cfg.cfgVersion = htonl(pCreate->cfg.cfgVersion);
- pCreate->cfg.maxTables = htonl(pCreate->cfg.maxTables);
- pCreate->cfg.cacheBlockSize = htonl(pCreate->cfg.cacheBlockSize);
- pCreate->cfg.totalBlocks = htonl(pCreate->cfg.totalBlocks);
- pCreate->cfg.daysPerFile = htonl(pCreate->cfg.daysPerFile);
- pCreate->cfg.daysToKeep1 = htonl(pCreate->cfg.daysToKeep1);
- pCreate->cfg.daysToKeep2 = htonl(pCreate->cfg.daysToKeep2);
- pCreate->cfg.daysToKeep = htonl(pCreate->cfg.daysToKeep);
- pCreate->cfg.minRowsPerFileBlock = htonl(pCreate->cfg.minRowsPerFileBlock);
- pCreate->cfg.maxRowsPerFileBlock = htonl(pCreate->cfg.maxRowsPerFileBlock);
- pCreate->cfg.fsyncPeriod = htonl(pCreate->cfg.fsyncPeriod);
- pCreate->cfg.commitTime = htonl(pCreate->cfg.commitTime);
-
- for (int32_t j = 0; j < pCreate->cfg.replications; ++j) {
- pCreate->nodes[j].nodeId = htonl(pCreate->nodes[j].nodeId);
- }
-
- return pCreate;
-}
-
-static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg) {
- SCreateVnodeMsg *pCreate = dnodeParseVnodeMsg(rpcMsg);
-
- void *pVnode = vnodeAcquire(pCreate->cfg.vgId);
- if (pVnode != NULL) {
- dDebug("vgId:%d, already exist, return success", pCreate->cfg.vgId);
- vnodeRelease(pVnode);
- return TSDB_CODE_SUCCESS;
- } else {
- dDebug("vgId:%d, create vnode msg is received", pCreate->cfg.vgId);
- return vnodeCreate(pCreate);
- }
-}
-
-static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) {
- SAlterVnodeMsg *pAlter = dnodeParseVnodeMsg(rpcMsg);
-
- void *pVnode = vnodeAcquire(pAlter->cfg.vgId);
- if (pVnode != NULL) {
- dDebug("vgId:%d, alter vnode msg is received", pAlter->cfg.vgId);
- int32_t code = vnodeAlter(pVnode, pAlter);
- vnodeRelease(pVnode);
- return code;
- } else {
- dError("vgId:%d, vnode not exist, can't alter it", pAlter->cfg.vgId);
- return TSDB_CODE_VND_INVALID_VGROUP_ID;
- }
-}
-
-static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
- SDropVnodeMsg *pDrop = rpcMsg->pCont;
- pDrop->vgId = htonl(pDrop->vgId);
-
- return vnodeDrop(pDrop->vgId);
-}
-
-static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg) {
-// SAlterStreamMsg *pStream = pCont;
-// pStream->uid = htobe64(pStream->uid);
-// pStream->stime = htobe64(pStream->stime);
-// pStream->vnode = htonl(pStream->vnode);
-// pStream->sid = htonl(pStream->sid);
-// pStream->status = htonl(pStream->status);
-//
-// int32_t code = dnodeCreateStream(pStream);
-
- return 0;
-}
-
-static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg) {
- SCfgDnodeMsg *pCfg = pMsg->pCont;
- return taosCfgDynamicOptions(pCfg->config);
-}
-
-static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
- SCreateMnodeMsg *pCfg = pMsg->pCont;
- pCfg->dnodeId = htonl(pCfg->dnodeId);
- if (pCfg->dnodeId != dnodeGetDnodeId()) {
- dDebug("dnodeId:%d, in create mnode msg is not equal with saved dnodeId:%d", pCfg->dnodeId, dnodeGetDnodeId());
- return TSDB_CODE_MND_DNODE_ID_NOT_CONFIGURED;
- }
-
- if (strcmp(pCfg->dnodeEp, tsLocalEp) != 0) {
- dDebug("dnodeEp:%s, in create mnode msg is not equal with saved dnodeEp:%s", pCfg->dnodeEp, tsLocalEp);
- return TSDB_CODE_MND_DNODE_EP_NOT_CONFIGURED;
- }
-
- dDebug("dnodeId:%d, create mnode msg is received from mnodes, numOfMnodes:%d", pCfg->dnodeId, pCfg->mnodes.mnodeNum);
- for (int i = 0; i < pCfg->mnodes.mnodeNum; ++i) {
- pCfg->mnodes.mnodeInfos[i].mnodeId = htonl(pCfg->mnodes.mnodeInfos[i].mnodeId);
- dDebug("mnode index:%d, mnode:%d:%s", i, pCfg->mnodes.mnodeInfos[i].mnodeId, pCfg->mnodes.mnodeInfos[i].mnodeEp);
- }
-
- dnodeStartMnode(&pCfg->mnodes);
-
- return TSDB_CODE_SUCCESS;
-}
-
-static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
- if (pMsg->code != TSDB_CODE_SUCCESS) {
- dError("status rsp is received, error:%s", tstrerror(pMsg->code));
- taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
- return;
- }
-
- SStatusRsp *pStatusRsp = pMsg->pCont;
- SMInfos *pMinfos = &pStatusRsp->mnodes;
- dnodeUpdateMInfos(pMinfos);
-
- SDnodeCfg *pCfg = &pStatusRsp->dnodeCfg;
- pCfg->numOfVnodes = htonl(pCfg->numOfVnodes);
- pCfg->moduleStatus = htonl(pCfg->moduleStatus);
- pCfg->dnodeId = htonl(pCfg->dnodeId);
- dnodeUpdateCfg(pCfg);
-
- vnodeSetAccess(pStatusRsp->vgAccess, pCfg->numOfVnodes);
-
- SDnodeEps *pEps = (SDnodeEps *)((char *)pStatusRsp->vgAccess + pCfg->numOfVnodes * sizeof(SVgroupAccess));
- dnodeUpdateEps(pEps);
-
- taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
-}
-
-static void dnodeSendStatusMsg(void *handle, void *tmrId) {
- if (tsDnodeTmr == NULL) {
- dError("dnode timer is already released");
- return;
- }
-
- if (tsStatusTimer == NULL) {
- taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
- dError("failed to start status timer");
- return;
- }
-
- int32_t contLen = sizeof(SStatusMsg) + TSDB_MAX_VNODES * sizeof(SVnodeLoad);
- SStatusMsg *pStatus = rpcMallocCont(contLen);
- if (pStatus == NULL) {
- taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
- dError("failed to malloc status message");
- return;
- }
-
- dnodeGetCfg(&pStatus->dnodeId, pStatus->clusterId);
- pStatus->dnodeId = htonl(dnodeGetDnodeId());
- pStatus->version = htonl(tsVersion);
- pStatus->lastReboot = htonl(tsRebootTime);
- pStatus->numOfCores = htons((uint16_t) tsNumOfCores);
- pStatus->diskAvailable = tsAvailDataDirGB;
- pStatus->alternativeRole = (uint8_t) tsAlternativeRole;
- tstrncpy(pStatus->dnodeEp, tsLocalEp, TSDB_EP_LEN);
-
- // fill cluster cfg parameters
- pStatus->clusterCfg.numOfMnodes = htonl(tsNumOfMnodes);
- pStatus->clusterCfg.enableBalance = htonl(tsEnableBalance);
- pStatus->clusterCfg.mnodeEqualVnodeNum = htonl(tsMnodeEqualVnodeNum);
- pStatus->clusterCfg.offlineThreshold = htonl(tsOfflineThreshold);
- pStatus->clusterCfg.statusInterval = htonl(tsStatusInterval);
- pStatus->clusterCfg.maxtablesPerVnode = htonl(tsMaxTablePerVnode);
- pStatus->clusterCfg.maxVgroupsPerDb = htonl(tsMaxVgroupsPerDb);
- tstrncpy(pStatus->clusterCfg.arbitrator, tsArbitrator, TSDB_EP_LEN);
- tstrncpy(pStatus->clusterCfg.timezone, tsTimezone, 64);
- pStatus->clusterCfg.checkTime = 0;
- char timestr[32] = "1970-01-01 00:00:00.00";
- (void)taosParseTime(timestr, &pStatus->clusterCfg.checkTime, strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
- tstrncpy(pStatus->clusterCfg.locale, tsLocale, TSDB_LOCALE_LEN);
- tstrncpy(pStatus->clusterCfg.charset, tsCharset, TSDB_LOCALE_LEN);
-
- vnodeBuildStatusMsg(pStatus);
- contLen = sizeof(SStatusMsg) + pStatus->openVnodes * sizeof(SVnodeLoad);
- pStatus->openVnodes = htons(pStatus->openVnodes);
-
- SRpcMsg rpcMsg = {
- .pCont = pStatus,
- .contLen = contLen,
- .msgType = TSDB_MSG_TYPE_DM_STATUS
- };
-
- SRpcEpSet epSet;
- dnodeGetEpSetForPeer(&epSet);
- dnodeSendMsgToDnode(&epSet, &rpcMsg);
-}
-
-void dnodeSendRedirectMsg(SRpcMsg *rpcMsg, bool forShell) {
- SRpcConnInfo connInfo = {0};
- rpcGetConnInfo(rpcMsg->handle, &connInfo);
-
- SRpcEpSet epSet = {0};
- if (forShell) {
- dnodeGetEpSetForShell(&epSet);
- } else {
- dnodeGetEpSetForPeer(&epSet);
- }
-
- dDebug("msg:%s will be redirected, dnodeIp:%s user:%s, numOfEps:%d inUse:%d", taosMsg[rpcMsg->msgType],
- taosIpStr(connInfo.clientIp), connInfo.user, epSet.numOfEps, epSet.inUse);
-
- for (int i = 0; i < epSet.numOfEps; ++i) {
- dDebug("mnode index:%d %s:%d", i, epSet.fqdn[i], epSet.port[i]);
- epSet.port[i] = htons(epSet.port[i]);
- }
-
- rpcSendRedirectRsp(rpcMsg->handle, &epSet);
-}
diff --git a/src/dnode/src/dnodeModule.c b/src/dnode/src/dnodeModule.c
index f664618f51..9eb52cbf5a 100644
--- a/src/dnode/src/dnodeModule.c
+++ b/src/dnode/src/dnodeModule.c
@@ -15,15 +15,10 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taosdef.h"
-#include "taosmsg.h"
-#include "tglobal.h"
#include "mnode.h"
#include "http.h"
#include "tmqtt.h"
#include "monitor.h"
-#include "dnode.h"
-#include "dnodeInt.h"
#include "dnodeModule.h"
typedef struct {
diff --git a/src/dnode/src/dnodePeer.c b/src/dnode/src/dnodePeer.c
index 6b5b28622b..bf74e14963 100644
--- a/src/dnode/src/dnodePeer.c
+++ b/src/dnode/src/dnodePeer.c
@@ -21,15 +21,12 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taosmsg.h"
-#include "tglobal.h"
#include "mnode.h"
-#include "dnode.h"
-#include "dnodeInt.h"
-#include "dnodeMgmt.h"
+#include "dnodeVMgmt.h"
#include "dnodeVWrite.h"
#include "dnodeMPeer.h"
#include "dnodeMInfos.h"
+#include "dnodeStep.h"
static void (*dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *);
static void dnodeProcessReqMsgFromDnode(SRpcMsg *pMsg, SRpcEpSet *);
@@ -44,19 +41,19 @@ int32_t dnodeInitServer() {
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_TABLE] = dnodeDispatchToVWriteQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_STABLE] = dnodeDispatchToVWriteQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeDispatchToMgmtQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeDispatchToMgmtQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeDispatchToMgmtQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeDispatchToMgmtQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeDispatchToMgmtQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_MNODE] = dnodeDispatchToMgmtQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeDispatchToVMgmtQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeDispatchToVMgmtQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeDispatchToVMgmtQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeDispatchToVMgmtQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeDispatchToVMgmtQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_MNODE] = dnodeDispatchToVMgmtQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_CONFIG_TABLE] = dnodeDispatchToMPeerQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_CONFIG_VNODE] = dnodeDispatchToMPeerQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_AUTH] = dnodeDispatchToMPeerQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_GRANT] = dnodeDispatchToMPeerQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_STATUS] = dnodeDispatchToMPeerQueue;
-
+
SRpcInit rpcInit;
memset(&rpcInit, 0, sizeof(rpcInit));
rpcInit.localPort = tsDnodeDnodePort;
@@ -91,8 +88,9 @@ static void dnodeProcessReqMsgFromDnode(SRpcMsg *pMsg, SRpcEpSet *pEpSet) {
.pCont = NULL,
.contLen = 0
};
-
+
if (pMsg->pCont == NULL) return;
+ if (pMsg->msgType == TSDB_MSG_TYPE_NETWORK_TEST) return dnodeSendStartupStep(pMsg);
if (dnodeGetRunStatus() != TSDB_RUN_STATUS_RUNING) {
rspMsg.code = TSDB_CODE_APP_NOT_READY;
diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c
index 89f657f789..d76af4e3dc 100644
--- a/src/dnode/src/dnodeShell.c
+++ b/src/dnode/src/dnodeShell.c
@@ -15,20 +15,14 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taoserror.h"
-#include "taosdef.h"
-#include "taosmsg.h"
-#include "tglobal.h"
-#include "tutil.h"
#include "http.h"
#include "mnode.h"
-#include "dnode.h"
-#include "dnodeInt.h"
#include "dnodeVRead.h"
#include "dnodeVWrite.h"
#include "dnodeMRead.h"
#include "dnodeMWrite.h"
#include "dnodeShell.h"
+#include "dnodeStep.h"
static void (*dnodeProcessShellMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *);
static void dnodeProcessMsgFromShell(SRpcMsg *pMsg, SRpcEpSet *);
@@ -74,6 +68,8 @@ int32_t dnodeInitShell() {
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_SHOW] = dnodeDispatchToMReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_RETRIEVE] = dnodeDispatchToMReadQueue;
+ dnodeProcessShellMsgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeSendStartupStep;
+
int32_t numOfThreads = tsNumOfCores * tsNumOfThreadsPerCore;
numOfThreads = (int32_t) ((1.0 - tsRatioOfQueryThreads) * numOfThreads / 2.0);
if (numOfThreads < 1) {
@@ -142,7 +138,23 @@ static void dnodeProcessMsgFromShell(SRpcMsg *pMsg, SRpcEpSet *pEpSet) {
}
}
+static int32_t dnodeAuthNettestUser(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
+ if (strcmp(user, "nettestinternal") == 0) {
+ char pass[32] = {0};
+ taosEncryptPass((uint8_t *)user, strlen(user), pass);
+ *spi = 0;
+ *encrypt = 0;
+ *ckey = 0;
+ memcpy(secret, pass, TSDB_KEY_LEN);
+ dTrace("nettest user is authorized");
+ return 0;
+ }
+
+ return -1;
+}
+
static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
+ if (dnodeAuthNettestUser(user, spi, encrypt, secret, ckey) == 0) return 0;
int code = mnodeRetriveAuth(user, spi, encrypt, secret, ckey);
if (code != TSDB_CODE_APP_NOT_READY) return code;
@@ -220,4 +232,4 @@ SStatisInfo dnodeGetStatisInfo() {
}
return info;
-}
+}
\ No newline at end of file
diff --git a/src/dnode/src/dnodeStep.c b/src/dnode/src/dnodeStep.c
new file mode 100644
index 0000000000..0f535b9470
--- /dev/null
+++ b/src/dnode/src/dnodeStep.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "dnodeStep.h"
+
+static SStartupStep tsStartupStep;
+
+void dnodeReportStep(char *name, char *desc, int8_t finished) {
+ tstrncpy(tsStartupStep.name, name, sizeof(tsStartupStep.name));
+ tstrncpy(tsStartupStep.desc, desc, sizeof(tsStartupStep.desc));
+ tsStartupStep.finished = finished;
+}
+
+void dnodeSendStartupStep(SRpcMsg *pMsg) {
+ dInfo("nettest msg is received, cont:%s", (char *)pMsg->pCont);
+
+ SStartupStep *pStep = rpcMallocCont(sizeof(SStartupStep));
+ memcpy(pStep, &tsStartupStep, sizeof(SStartupStep));
+
+ dDebug("startup msg is sent, step:%s desc:%s finished:%d", pStep->name, pStep->desc, pStep->finished);
+
+ SRpcMsg rpcRsp = {.handle = pMsg->handle, .pCont = pStep, .contLen = sizeof(SStartupStep)};
+ rpcSendResponse(&rpcRsp);
+ rpcFreeCont(pMsg->pCont);
+}
+
+void taosStepCleanupImp(SStep *pSteps, int32_t stepId) {
+ for (int32_t step = stepId; step >= 0; step--) {
+ SStep *pStep = pSteps + step;
+ dDebug("step:%s will cleanup", pStep->name);
+ if (pStep->cleanupFp != NULL) {
+ (*pStep->cleanupFp)();
+ }
+ }
+}
+
+int32_t dnodeStepInit(SStep *pSteps, int32_t stepSize) {
+ for (int32_t step = 0; step < stepSize; step++) {
+ SStep *pStep = pSteps + step;
+ if (pStep->initFp == NULL) continue;
+
+ dnodeReportStep(pStep->name, "Start initialization", 0);
+
+ int32_t code = (*pStep->initFp)();
+ if (code != 0) {
+ dDebug("step:%s will init", pStep->name);
+ taosStepCleanupImp(pSteps, step);
+ return code;
+ }
+
+ dnodeReportStep(pStep->name, "Initialization complete", step + 1 >= stepSize);
+ }
+
+ return 0;
+}
+
+void dnodeStepCleanup(SStep *pSteps, int32_t stepSize) {
+ return taosStepCleanupImp(pSteps, stepSize - 1);
+}
\ No newline at end of file
diff --git a/src/dnode/src/dnodeSystem.c b/src/dnode/src/dnodeSystem.c
index 56316e9619..a135cda055 100644
--- a/src/dnode/src/dnodeSystem.c
+++ b/src/dnode/src/dnodeSystem.c
@@ -16,9 +16,6 @@
#define _DEFAULT_SOURCE
#include "os.h"
#include "tgrant.h"
-#include "tutil.h"
-#include "tglobal.h"
-#include "dnodeInt.h"
#include "dnodeMain.h"
static void signal_handler(int32_t signum, siginfo_t *sigInfo, void *context);
diff --git a/src/dnode/src/dnodeTelemetry.c b/src/dnode/src/dnodeTelemetry.c
index e973f9901f..85f0137d89 100644
--- a/src/dnode/src/dnodeTelemetry.c
+++ b/src/dnode/src/dnodeTelemetry.c
@@ -15,9 +15,6 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taoserror.h"
-#include "tglobal.h"
-#include "tutil.h"
#include "osTime.h"
#include "tsocket.h"
#include "tbuffer.h"
@@ -32,8 +29,6 @@
#include "mnodeTable.h"
#include "mnodeSdb.h"
#include "mnodeAcct.h"
-#include "dnode.h"
-#include "dnodeInt.h"
#include "dnodeTelemetry.h"
static tsem_t tsExitSem;
@@ -313,4 +308,4 @@ void dnodeCleanupTelemetry() {
pthread_join(tsTelemetryThread, NULL);
tsem_destroy(&tsExitSem);
}
-}
+}
\ No newline at end of file
diff --git a/src/dnode/src/dnodeVMgmt.c b/src/dnode/src/dnodeVMgmt.c
new file mode 100644
index 0000000000..87302026ec
--- /dev/null
+++ b/src/dnode/src/dnodeVMgmt.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "tqueue.h"
+#include "dnodeVMgmt.h"
+
+typedef struct {
+ SRpcMsg rpcMsg;
+ char pCont[];
+} SMgmtMsg;
+
+static taos_qset tsMgmtQset = NULL;
+static taos_queue tsMgmtQueue = NULL;
+static pthread_t tsQthread;
+
+static void * dnodeProcessMgmtQueue(void *param);
+static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *pMsg);
+static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *pMsg);
+static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *pMsg);
+static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg);
+static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg);
+static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg);
+static int32_t (*dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *pMsg);
+
+int32_t dnodeInitVMgmt() {
+ dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeProcessCreateVnodeMsg;
+ dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeProcessAlterVnodeMsg;
+ dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeProcessDropVnodeMsg;
+ dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeProcessAlterStreamMsg;
+ dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeProcessConfigDnodeMsg;
+ dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_MNODE] = dnodeProcessCreateMnodeMsg;
+
+ int32_t code = vnodeInitMgmt();
+ if (code != TSDB_CODE_SUCCESS) return -1;
+
+ tsMgmtQset = taosOpenQset();
+ if (tsMgmtQset == NULL) {
+ dError("failed to create the vmgmt queue set");
+ return -1;
+ }
+
+ tsMgmtQueue = taosOpenQueue();
+ if (tsMgmtQueue == NULL) {
+ dError("failed to create the vmgmt queue");
+ return -1;
+ }
+
+ taosAddIntoQset(tsMgmtQset, tsMgmtQueue, NULL);
+
+ pthread_attr_t thAttr;
+ pthread_attr_init(&thAttr);
+ pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
+
+ code = pthread_create(&tsQthread, &thAttr, dnodeProcessMgmtQueue, NULL);
+ pthread_attr_destroy(&thAttr);
+ if (code != 0) {
+ dError("failed to create thread to process vmgmt queue, reason:%s", strerror(errno));
+ return -1;
+ }
+
+ dInfo("dnode vmgmt is initialized");
+ return TSDB_CODE_SUCCESS;
+}
+
+void dnodeCleanupVMgmt() {
+ if (tsMgmtQset) taosQsetThreadResume(tsMgmtQset);
+ if (tsQthread) pthread_join(tsQthread, NULL);
+
+ if (tsMgmtQueue) taosCloseQueue(tsMgmtQueue);
+ if (tsMgmtQset) taosCloseQset(tsMgmtQset);
+
+ tsMgmtQset = NULL;
+ tsMgmtQueue = NULL;
+
+ vnodeCleanupMgmt();
+}
+
+static int32_t dnodeWriteToMgmtQueue(SRpcMsg *pMsg) {
+ int32_t size = sizeof(SMgmtMsg) + pMsg->contLen;
+ SMgmtMsg *pMgmt = taosAllocateQitem(size);
+ if (pMgmt == NULL) return TSDB_CODE_DND_OUT_OF_MEMORY;
+
+ pMgmt->rpcMsg = *pMsg;
+ pMgmt->rpcMsg.pCont = pMgmt->pCont;
+ memcpy(pMgmt->pCont, pMsg->pCont, pMsg->contLen);
+ taosWriteQitem(tsMgmtQueue, TAOS_QTYPE_RPC, pMgmt);
+
+ return TSDB_CODE_SUCCESS;
+}
+
+void dnodeDispatchToVMgmtQueue(SRpcMsg *pMsg) {
+ int32_t code = dnodeWriteToMgmtQueue(pMsg);
+ if (code != TSDB_CODE_SUCCESS) {
+ SRpcMsg rsp = {.handle = pMsg->handle, .code = code};
+ rpcSendResponse(&rsp);
+ }
+
+ rpcFreeCont(pMsg->pCont);
+}
+
+static void *dnodeProcessMgmtQueue(void *param) {
+ SMgmtMsg *pMgmt;
+ SRpcMsg * pMsg;
+ SRpcMsg rsp = {0};
+ int32_t qtype;
+ void * handle;
+
+ while (1) {
+ if (taosReadQitemFromQset(tsMgmtQset, &qtype, (void **)&pMgmt, &handle) == 0) {
+ dDebug("qset:%p, dnode mgmt got no message from qset, exit", tsMgmtQset);
+ break;
+ }
+
+ pMsg = &pMgmt->rpcMsg;
+ dDebug("msg:%p, ahandle:%p type:%s will be processed", pMgmt, pMsg->ahandle, taosMsg[pMsg->msgType]);
+ if (dnodeProcessMgmtMsgFp[pMsg->msgType]) {
+ rsp.code = (*dnodeProcessMgmtMsgFp[pMsg->msgType])(pMsg);
+ } else {
+ rsp.code = TSDB_CODE_DND_MSG_NOT_PROCESSED;
+ }
+
+ dDebug("msg:%p, is processed, code:0x%x", pMgmt, rsp.code);
+ if (rsp.code != TSDB_CODE_DND_ACTION_IN_PROGRESS) {
+ rsp.handle = pMsg->handle;
+ rsp.pCont = NULL;
+ rpcSendResponse(&rsp);
+ }
+
+ taosFreeQitem(pMsg);
+ }
+
+ return NULL;
+}
+
+static SCreateVnodeMsg* dnodeParseVnodeMsg(SRpcMsg *rpcMsg) {
+ SCreateVnodeMsg *pCreate = rpcMsg->pCont;
+ pCreate->cfg.vgId = htonl(pCreate->cfg.vgId);
+ pCreate->cfg.cfgVersion = htonl(pCreate->cfg.cfgVersion);
+ pCreate->cfg.maxTables = htonl(pCreate->cfg.maxTables);
+ pCreate->cfg.cacheBlockSize = htonl(pCreate->cfg.cacheBlockSize);
+ pCreate->cfg.totalBlocks = htonl(pCreate->cfg.totalBlocks);
+ pCreate->cfg.daysPerFile = htonl(pCreate->cfg.daysPerFile);
+ pCreate->cfg.daysToKeep1 = htonl(pCreate->cfg.daysToKeep1);
+ pCreate->cfg.daysToKeep2 = htonl(pCreate->cfg.daysToKeep2);
+ pCreate->cfg.daysToKeep = htonl(pCreate->cfg.daysToKeep);
+ pCreate->cfg.minRowsPerFileBlock = htonl(pCreate->cfg.minRowsPerFileBlock);
+ pCreate->cfg.maxRowsPerFileBlock = htonl(pCreate->cfg.maxRowsPerFileBlock);
+ pCreate->cfg.fsyncPeriod = htonl(pCreate->cfg.fsyncPeriod);
+ pCreate->cfg.commitTime = htonl(pCreate->cfg.commitTime);
+
+ for (int32_t j = 0; j < pCreate->cfg.replications; ++j) {
+ pCreate->nodes[j].nodeId = htonl(pCreate->nodes[j].nodeId);
+ }
+
+ return pCreate;
+}
+
+static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg) {
+ SCreateVnodeMsg *pCreate = dnodeParseVnodeMsg(rpcMsg);
+
+ void *pVnode = vnodeAcquire(pCreate->cfg.vgId);
+ if (pVnode != NULL) {
+ dDebug("vgId:%d, already exist, return success", pCreate->cfg.vgId);
+ vnodeRelease(pVnode);
+ return TSDB_CODE_SUCCESS;
+ } else {
+ dDebug("vgId:%d, create vnode msg is received", pCreate->cfg.vgId);
+ return vnodeCreate(pCreate);
+ }
+}
+
+static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) {
+ SAlterVnodeMsg *pAlter = dnodeParseVnodeMsg(rpcMsg);
+
+ void *pVnode = vnodeAcquire(pAlter->cfg.vgId);
+ if (pVnode != NULL) {
+ dDebug("vgId:%d, alter vnode msg is received", pAlter->cfg.vgId);
+ int32_t code = vnodeAlter(pVnode, pAlter);
+ vnodeRelease(pVnode);
+ return code;
+ } else {
+ dError("vgId:%d, vnode not exist, can't alter it", pAlter->cfg.vgId);
+ return TSDB_CODE_VND_INVALID_VGROUP_ID;
+ }
+}
+
+static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
+ SDropVnodeMsg *pDrop = rpcMsg->pCont;
+ pDrop->vgId = htonl(pDrop->vgId);
+
+ return vnodeDrop(pDrop->vgId);
+}
+
+static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg) {
+ return 0;
+}
+
+static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg) {
+ SCfgDnodeMsg *pCfg = pMsg->pCont;
+ return taosCfgDynamicOptions(pCfg->config);
+}
+
+static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
+ SCreateMnodeMsg *pCfg = pMsg->pCont;
+ pCfg->dnodeId = htonl(pCfg->dnodeId);
+ if (pCfg->dnodeId != dnodeGetDnodeId()) {
+ dDebug("dnodeId:%d, in create mnode msg is not equal with saved dnodeId:%d", pCfg->dnodeId, dnodeGetDnodeId());
+ return TSDB_CODE_MND_DNODE_ID_NOT_CONFIGURED;
+ }
+
+ if (strcmp(pCfg->dnodeEp, tsLocalEp) != 0) {
+ dDebug("dnodeEp:%s, in create mnode msg is not equal with saved dnodeEp:%s", pCfg->dnodeEp, tsLocalEp);
+ return TSDB_CODE_MND_DNODE_EP_NOT_CONFIGURED;
+ }
+
+ dDebug("dnodeId:%d, create mnode msg is received from mnodes, numOfMnodes:%d", pCfg->dnodeId, pCfg->mnodes.mnodeNum);
+ for (int i = 0; i < pCfg->mnodes.mnodeNum; ++i) {
+ pCfg->mnodes.mnodeInfos[i].mnodeId = htonl(pCfg->mnodes.mnodeInfos[i].mnodeId);
+ dDebug("mnode index:%d, mnode:%d:%s", i, pCfg->mnodes.mnodeInfos[i].mnodeId, pCfg->mnodes.mnodeInfos[i].mnodeEp);
+ }
+
+ dnodeStartMnode(&pCfg->mnodes);
+
+ return TSDB_CODE_SUCCESS;
+}
\ No newline at end of file
diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c
index b42a627a3a..07496b142a 100644
--- a/src/dnode/src/dnodeVRead.c
+++ b/src/dnode/src/dnodeVRead.c
@@ -15,12 +15,8 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taoserror.h"
-#include "taosmsg.h"
-#include "tglobal.h"
#include "tqueue.h"
-#include "vnode.h"
-#include "dnodeInt.h"
+#include "dnodeVRead.h"
typedef struct {
pthread_t thread; // thread
diff --git a/src/dnode/src/dnodeVWrite.c b/src/dnode/src/dnodeVWrite.c
index 6d4b50ee54..a5ae8ac830 100644
--- a/src/dnode/src/dnodeVWrite.c
+++ b/src/dnode/src/dnodeVWrite.c
@@ -15,13 +15,8 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taoserror.h"
-#include "taosmsg.h"
-#include "tglobal.h"
#include "tqueue.h"
-#include "twal.h"
-#include "vnode.h"
-#include "dnodeInt.h"
+#include "dnodeVWrite.h"
typedef struct {
taos_qall qall;
diff --git a/src/dnode/src/dnodeVnodes.c b/src/dnode/src/dnodeVnodes.c
new file mode 100644
index 0000000000..ba7f7625fa
--- /dev/null
+++ b/src/dnode/src/dnodeVnodes.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "ttimer.h"
+#include "dnodeEps.h"
+#include "dnodeCfg.h"
+#include "dnodeMInfos.h"
+#include "dnodeVnodes.h"
+
+typedef struct {
+ pthread_t thread;
+ int32_t threadIndex;
+ int32_t failed;
+ int32_t opened;
+ int32_t vnodeNum;
+ int32_t * vnodeList;
+} SOpenVnodeThread;
+
+void * tsDnodeTmr = NULL;
+static void * tsStatusTimer = NULL;
+static uint32_t tsRebootTime = 0;
+
+static void dnodeSendStatusMsg(void *handle, void *tmrId);
+static void dnodeProcessStatusRsp(SRpcMsg *pMsg);
+
+int32_t dnodeInitTimer() {
+ tsDnodeTmr = taosTmrInit(100, 200, 60000, "DND-DM");
+ if (tsDnodeTmr == NULL) {
+ dError("failed to init dnode timer");
+ return -1;
+ }
+
+ dnodeAddClientRspHandle(TSDB_MSG_TYPE_DM_STATUS_RSP, dnodeProcessStatusRsp);
+
+ tsRebootTime = taosGetTimestampSec();
+ taosTmrReset(dnodeSendStatusMsg, 500, NULL, tsDnodeTmr, &tsStatusTimer);
+
+ dInfo("dnode timer is initialized");
+ return TSDB_CODE_SUCCESS;
+}
+
+void dnodeCleanupTimer() {
+ if (tsStatusTimer != NULL) {
+ taosTmrStopA(&tsStatusTimer);
+ tsStatusTimer = NULL;
+ }
+
+ if (tsDnodeTmr != NULL) {
+ taosTmrCleanUp(tsDnodeTmr);
+ tsDnodeTmr = NULL;
+ }
+}
+
+static int32_t dnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
+ DIR *dir = opendir(tsVnodeDir);
+ if (dir == NULL) return TSDB_CODE_DND_NO_WRITE_ACCESS;
+
+ *numOfVnodes = 0;
+ struct dirent *de = NULL;
+ while ((de = readdir(dir)) != NULL) {
+ if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
+ if (de->d_type & DT_DIR) {
+ if (strncmp("vnode", de->d_name, 5) != 0) continue;
+ int32_t vnode = atoi(de->d_name + 5);
+ if (vnode == 0) continue;
+
+ (*numOfVnodes)++;
+
+ if (*numOfVnodes >= TSDB_MAX_VNODES) {
+ dError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
+ continue;
+ } else {
+ vnodeList[*numOfVnodes - 1] = vnode;
+ }
+ }
+ }
+ closedir(dir);
+
+ return TSDB_CODE_SUCCESS;
+}
+
+static void *dnodeOpenVnode(void *param) {
+ SOpenVnodeThread *pThread = param;
+
+ dDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum);
+
+ for (int32_t v = 0; v < pThread->vnodeNum; ++v) {
+ int32_t vgId = pThread->vnodeList[v];
+ if (vnodeOpen(vgId) < 0) {
+ dError("vgId:%d, failed to open vnode by thread:%d", vgId, pThread->threadIndex);
+ pThread->failed++;
+ } else {
+ dDebug("vgId:%d, is openned by thread:%d", vgId, pThread->threadIndex);
+ pThread->opened++;
+ }
+ }
+
+ dDebug("thread:%d, total vnodes:%d, openned:%d failed:%d", pThread->threadIndex, pThread->vnodeNum, pThread->opened,
+ pThread->failed);
+ return NULL;
+}
+
+int32_t dnodeInitVnodes() {
+ int32_t vnodeList[TSDB_MAX_VNODES] = {0};
+ int32_t numOfVnodes = 0;
+ int32_t status = dnodeGetVnodeList(vnodeList, &numOfVnodes);
+
+ if (status != TSDB_CODE_SUCCESS) {
+ dInfo("get dnode list failed");
+ return status;
+ }
+
+ int32_t threadNum = tsNumOfCores;
+ int32_t vnodesPerThread = numOfVnodes / threadNum + 1;
+ SOpenVnodeThread *threads = calloc(threadNum, sizeof(SOpenVnodeThread));
+ for (int32_t t = 0; t < threadNum; ++t) {
+ threads[t].threadIndex = t;
+ threads[t].vnodeList = calloc(vnodesPerThread, sizeof(int32_t));
+ }
+
+ for (int32_t v = 0; v < numOfVnodes; ++v) {
+ int32_t t = v % threadNum;
+ SOpenVnodeThread *pThread = &threads[t];
+ pThread->vnodeList[pThread->vnodeNum++] = vnodeList[v];
+ }
+
+ dDebug("start %d threads to open %d vnodes", threadNum, numOfVnodes);
+
+ for (int32_t t = 0; t < threadNum; ++t) {
+ SOpenVnodeThread *pThread = &threads[t];
+ if (pThread->vnodeNum == 0) continue;
+
+ pthread_attr_t thAttr;
+ pthread_attr_init(&thAttr);
+ pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
+ if (pthread_create(&pThread->thread, &thAttr, dnodeOpenVnode, pThread) != 0) {
+ dError("thread:%d, failed to create thread to open vnode, reason:%s", pThread->threadIndex, strerror(errno));
+ }
+
+ pthread_attr_destroy(&thAttr);
+ }
+
+ int32_t openVnodes = 0;
+ int32_t failedVnodes = 0;
+ for (int32_t t = 0; t < threadNum; ++t) {
+ SOpenVnodeThread *pThread = &threads[t];
+ if (pThread->vnodeNum > 0 && pThread->thread) {
+ pthread_join(pThread->thread, NULL);
+ }
+ openVnodes += pThread->opened;
+ failedVnodes += pThread->failed;
+ free(pThread->vnodeList);
+ }
+
+ free(threads);
+ dInfo("there are total vnodes:%d, openned:%d", numOfVnodes, openVnodes);
+
+ if (failedVnodes != 0) {
+ dError("there are total vnodes:%d, failed:%d", numOfVnodes, failedVnodes);
+ return -1;
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+
+void dnodeCleanupVnodes() {
+ int32_t vnodeList[TSDB_MAX_VNODES]= {0};
+ int32_t numOfVnodes = 0;
+ int32_t status;
+
+ status = vnodeGetVnodeList(vnodeList, &numOfVnodes);
+
+ if (status != TSDB_CODE_SUCCESS) {
+ dInfo("get dnode list failed");
+ return;
+ }
+
+ for (int32_t i = 0; i < numOfVnodes; ++i) {
+ vnodeClose(vnodeList[i]);
+ }
+
+ dInfo("total vnodes:%d are all closed", numOfVnodes);
+}
+
+static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
+ if (pMsg->code != TSDB_CODE_SUCCESS) {
+ dError("status rsp is received, error:%s", tstrerror(pMsg->code));
+ taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
+ return;
+ }
+
+ SStatusRsp *pStatusRsp = pMsg->pCont;
+ SMInfos *minfos = &pStatusRsp->mnodes;
+ dnodeUpdateMInfos(minfos);
+
+ SDnodeCfg *pCfg = &pStatusRsp->dnodeCfg;
+ pCfg->numOfVnodes = htonl(pCfg->numOfVnodes);
+ pCfg->moduleStatus = htonl(pCfg->moduleStatus);
+ pCfg->dnodeId = htonl(pCfg->dnodeId);
+ dnodeUpdateCfg(pCfg);
+
+ vnodeSetAccess(pStatusRsp->vgAccess, pCfg->numOfVnodes);
+
+ SDnodeEps *pEps = (SDnodeEps *)((char *)pStatusRsp->vgAccess + pCfg->numOfVnodes * sizeof(SVgroupAccess));
+ dnodeUpdateEps(pEps);
+
+ taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
+}
+
+static void dnodeSendStatusMsg(void *handle, void *tmrId) {
+ if (tsDnodeTmr == NULL) {
+ dError("dnode timer is already released");
+ return;
+ }
+
+ if (tsStatusTimer == NULL) {
+ taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
+ dError("failed to start status timer");
+ return;
+ }
+
+ int32_t contLen = sizeof(SStatusMsg) + TSDB_MAX_VNODES * sizeof(SVnodeLoad);
+ SStatusMsg *pStatus = rpcMallocCont(contLen);
+ if (pStatus == NULL) {
+ taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
+ dError("failed to malloc status message");
+ return;
+ }
+
+ dnodeGetCfg(&pStatus->dnodeId, pStatus->clusterId);
+ pStatus->dnodeId = htonl(dnodeGetDnodeId());
+ pStatus->version = htonl(tsVersion);
+ pStatus->lastReboot = htonl(tsRebootTime);
+ pStatus->numOfCores = htons((uint16_t) tsNumOfCores);
+ pStatus->diskAvailable = tsAvailDataDirGB;
+ pStatus->alternativeRole = (uint8_t) tsAlternativeRole;
+ tstrncpy(pStatus->dnodeEp, tsLocalEp, TSDB_EP_LEN);
+
+ // fill cluster cfg parameters
+ pStatus->clusterCfg.numOfMnodes = htonl(tsNumOfMnodes);
+ pStatus->clusterCfg.enableBalance = htonl(tsEnableBalance);
+ pStatus->clusterCfg.mnodeEqualVnodeNum = htonl(tsMnodeEqualVnodeNum);
+ pStatus->clusterCfg.offlineThreshold = htonl(tsOfflineThreshold);
+ pStatus->clusterCfg.statusInterval = htonl(tsStatusInterval);
+ pStatus->clusterCfg.maxtablesPerVnode = htonl(tsMaxTablePerVnode);
+ pStatus->clusterCfg.maxVgroupsPerDb = htonl(tsMaxVgroupsPerDb);
+ tstrncpy(pStatus->clusterCfg.arbitrator, tsArbitrator, TSDB_EP_LEN);
+ tstrncpy(pStatus->clusterCfg.timezone, tsTimezone, 64);
+ pStatus->clusterCfg.checkTime = 0;
+ char timestr[32] = "1970-01-01 00:00:00.00";
+ (void)taosParseTime(timestr, &pStatus->clusterCfg.checkTime, strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
+ tstrncpy(pStatus->clusterCfg.locale, tsLocale, TSDB_LOCALE_LEN);
+ tstrncpy(pStatus->clusterCfg.charset, tsCharset, TSDB_LOCALE_LEN);
+
+ vnodeBuildStatusMsg(pStatus);
+ contLen = sizeof(SStatusMsg) + pStatus->openVnodes * sizeof(SVnodeLoad);
+ pStatus->openVnodes = htons(pStatus->openVnodes);
+
+ SRpcMsg rpcMsg = {
+ .pCont = pStatus,
+ .contLen = contLen,
+ .msgType = TSDB_MSG_TYPE_DM_STATUS
+ };
+
+ SRpcEpSet epSet;
+ dnodeGetEpSetForPeer(&epSet);
+ dnodeSendMsgToDnode(&epSet, &rpcMsg);
+}
+
+void dnodeSendStatusMsgToMnode() {
+ if (tsDnodeTmr != NULL && tsStatusTimer != NULL) {
+ dInfo("force send status msg to mnode");
+ taosTmrReset(dnodeSendStatusMsg, 3, NULL, tsDnodeTmr, &tsStatusTimer);
+ }
+}
\ No newline at end of file
diff --git a/src/inc/dnode.h b/src/inc/dnode.h
index 1efaa4a24b..9dd95e32d7 100644
--- a/src/inc/dnode.h
+++ b/src/inc/dnode.h
@@ -71,8 +71,18 @@ void dnodeDelayReprocessMWriteMsg(void *pMsg);
void dnodeSendStatusMsgToMnode();
+typedef struct {
+ char *name;
+ int32_t (*initFp)();
+ void (*cleanupFp)();
+} SStep;
+
+int32_t dnodeStepInit(SStep *pSteps, int32_t stepSize);
+void dnodeStepCleanup(SStep *pSteps, int32_t stepSize);
+void dnodeReportStep(char *name, char *desc, int8_t finished);
+
#ifdef __cplusplus
}
#endif
-#endif
+#endif
\ No newline at end of file
diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h
index ca20293392..0cc06be1db 100644
--- a/src/inc/taosdef.h
+++ b/src/inc/taosdef.h
@@ -286,6 +286,9 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
#define TSDB_SHOW_SQL_LEN 512
#define TSDB_SLOW_QUERY_SQL_LEN 512
+#define TSDB_STEP_NAME_LEN 32
+#define TSDB_STEP_DESC_LEN 128
+
#define TSDB_MQTT_HOSTNAME_LEN 64
#define TSDB_MQTT_PORT_LEN 8
#define TSDB_MQTT_USER_LEN 24
@@ -439,6 +442,10 @@ typedef enum {
TAOS_QTYPE_QUERY = 4
} EQType;
+#define TSDB_MAX_TIERS 3
+#define TSDB_MAX_DISKS_PER_TIER 16
+#define TSDB_MAX_DISKS (TSDB_MAX_TIERS * TSDB_MAX_DISKS_PER_TIER)
+
typedef enum {
TSDB_SUPER_TABLE = 0, // super table
TSDB_CHILD_TABLE = 1, // table created from super table
diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h
index a720b68e59..e0d7e01843 100644
--- a/src/inc/taoserror.h
+++ b/src/inc/taoserror.h
@@ -64,7 +64,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_TRAN_ID, 0, 0x000F, "Invalid tr
TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_SESSION_ID, 0, 0x0010, "Invalid session id")
TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_MSG_TYPE, 0, 0x0011, "Invalid message type")
TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_RESPONSE_TYPE, 0, 0x0012, "Invalid response type")
-TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_TIME_STAMP, 0, 0x0013, "Invalid timestamp")
+TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_TIME_STAMP, 0, 0x0013, "Client and server's time is not synchronized")
TAOS_DEFINE_ERROR(TSDB_CODE_APP_NOT_READY, 0, 0x0014, "Database not ready")
TAOS_DEFINE_ERROR(TSDB_CODE_RPC_FQDN_ERROR, 0, 0x0015, "Unable to resolve FQDN")
@@ -192,6 +192,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_DND_MSG_NOT_PROCESSED, 0, 0x0400, "Message no
TAOS_DEFINE_ERROR(TSDB_CODE_DND_OUT_OF_MEMORY, 0, 0x0401, "Dnode out of memory")
TAOS_DEFINE_ERROR(TSDB_CODE_DND_NO_WRITE_ACCESS, 0, 0x0402, "No permission for disk files in dnode")
TAOS_DEFINE_ERROR(TSDB_CODE_DND_INVALID_MSG_LEN, 0, 0x0403, "Invalid message length")
+TAOS_DEFINE_ERROR(TSDB_CODE_DND_ACTION_IN_PROGRESS, 0, 0x0404, "Action in progress")
// vnode
TAOS_DEFINE_ERROR(TSDB_CODE_VND_ACTION_IN_PROGRESS, 0, 0x0500, "Action in progress")
@@ -394,6 +395,18 @@ TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_BAD_SEQ, 0, 0x2113, "src bad se
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_INCOMPLETE, 0, 0x2114, "src incomplete")
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_GENERAL, 0, 0x2115, "src general")
+// tfs
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_OUT_OF_MEMORY, 0, 0x2200, "tfs out of memory")
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_INVLD_CFG, 0, 0x2201, "tfs invalid mount config")
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_TOO_MANY_MOUNT, 0, 0x2202, "tfs too many mount")
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_DUP_PRIMARY, 0, 0x2203, "tfs duplicate primary mount")
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_NO_PRIMARY_DISK, 0, 0x2204, "tfs no primary mount")
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_NO_MOUNT_AT_TIER, 0, 0x2205, "tfs no mount at tier")
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_FILE_ALREADY_EXISTS, 0, 0x2206, "tfs file already exists")
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_INVLD_LEVEL, 0, 0x2207, "tfs invalid level")
+TAOS_DEFINE_ERROR(TSDB_CODE_FS_NO_VALID_DISK, 0, 0x2208, "tfs no valid disk")
+
+
#ifdef TAOS_ERROR_C
};
#endif
diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h
index e8e3029244..ea9d608d92 100644
--- a/src/inc/taosmsg.h
+++ b/src/inc/taosmsg.h
@@ -105,10 +105,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DM_AUTH, "auth" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY12, "dummy12" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY13, "dummy13" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY14, "dummy14" )
-
-
-TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_NETWORK_TEST, "network-test" )
-
+TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_NETWORK_TEST, "nettest" )
#ifndef TAOS_MESSAGE_C
TSDB_MSG_TYPE_MAX // 105
@@ -840,6 +837,14 @@ typedef struct {
char ckey[TSDB_KEY_LEN];
} SAuthMsg, SAuthRsp;
+typedef struct {
+ int8_t finished;
+ int8_t reserved1[7];
+ char name[TSDB_STEP_NAME_LEN];
+ char desc[TSDB_STEP_DESC_LEN];
+ char reserved2[64];
+} SStartupStep;
+
#pragma pack(pop)
#ifdef __cplusplus
diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h
index 58859f42bc..1769bd6566 100644
--- a/src/inc/tsdb.h
+++ b/src/inc/tsdb.h
@@ -321,7 +321,7 @@ void tsdbCleanupQueryHandle(TsdbQueryHandleT queryHandle);
*/
void tsdbReportStat(void *repo, int64_t *totalPoints, int64_t *totalStorage, int64_t *compStorage);
-int tsdbInitCommitQueue(int nthreads);
+int tsdbInitCommitQueue();
void tsdbDestroyCommitQueue();
int tsdbSyncCommit(TSDB_REPO_T *repo);
void tsdbIncCommitRef(int vgId);
diff --git a/src/inc/vnode.h b/src/inc/vnode.h
index 5f643295d6..33bb2c278c 100644
--- a/src/inc/vnode.h
+++ b/src/inc/vnode.h
@@ -19,18 +19,9 @@
#ifdef __cplusplus
extern "C" {
#endif
-
#include "trpc.h"
#include "twal.h"
-typedef enum _VN_STATUS {
- TAOS_VN_STATUS_INIT = 0,
- TAOS_VN_STATUS_READY = 1,
- TAOS_VN_STATUS_CLOSING = 2,
- TAOS_VN_STATUS_UPDATING = 3,
- TAOS_VN_STATUS_RESET = 4,
-} EVnodeStatus;
-
typedef struct {
int32_t len;
void * rsp;
@@ -60,29 +51,35 @@ typedef struct {
SWalHead pHead[];
} SVWriteMsg;
+// vnodeStatus
extern char *vnodeStatus[];
+// vnodeMain
int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeDrop(int32_t vgId);
-int32_t vnodeOpen(int32_t vgId, char *rootDir);
+int32_t vnodeOpen(int32_t vgId);
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeClose(int32_t vgId);
-void* vnodeAcquire(int32_t vgId); // add refcount
-void vnodeRelease(void *pVnode); // dec refCount
+// vnodeMgmt
+int32_t vnodeInitMgmt();
+void vnodeCleanupMgmt();
+void* vnodeAcquire(int32_t vgId);
+void vnodeRelease(void *pVnode);
void* vnodeGetWal(void *pVnode);
+int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes);
+void vnodeBuildStatusMsg(void *pStatus);
+void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes);
+// vnodeWrite
int32_t vnodeWriteToWQueue(void *pVnode, void *pHead, int32_t qtype, void *pRpcMsg);
void vnodeFreeFromWQueue(void *pVnode, SVWriteMsg *pWrite);
int32_t vnodeProcessWrite(void *pVnode, void *pHead, int32_t qtype, void *pRspRet);
-int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes);
-void vnodeBuildStatusMsg(void *pStatus);
+
+// vnodeSync
void vnodeConfirmForward(void *pVnode, uint64_t version, int32_t code);
-void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes);
-
-int32_t vnodeInitResources();
-void vnodeCleanupResources();
+// vnodeRead
int32_t vnodeWriteToRQueue(void *pVnode, void *pCont, int32_t contLen, int8_t qtype, void *rparam);
void vnodeFreeFromRQueue(void *pVnode, SVReadMsg *pRead);
int32_t vnodeProcessRead(void *pVnode, SVReadMsg *pRead);
@@ -91,4 +88,4 @@ int32_t vnodeProcessRead(void *pVnode, SVReadMsg *pRead);
}
#endif
-#endif
+#endif
\ No newline at end of file
diff --git a/src/kit/shell/inc/shell.h b/src/kit/shell/inc/shell.h
index d65c943e28..2c6e4a308c 100644
--- a/src/kit/shell/inc/shell.h
+++ b/src/kit/shell/inc/shell.h
@@ -51,7 +51,6 @@ typedef struct SShellArguments {
char* commands;
int abort;
int port;
- int endPort;
int pktLen;
char* netTestRole;
} SShellArguments;
diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c
index 22f01ac142..af8beb7987 100644
--- a/src/kit/shell/src/shellEngine.c
+++ b/src/kit/shell/src/shellEngine.c
@@ -32,14 +32,14 @@
/**************** Global variables ****************/
#ifdef _TD_POWER_
char CLIENT_VERSION[] = "Welcome to the PowerDB shell from %s, Client Version:%s\n"
- "Copyright (c) 2017 by PowerDB, Inc. All rights reserved.\n\n";
+ "Copyright (c) 2020 by PowerDB, Inc. All rights reserved.\n\n";
char PROMPT_HEADER[] = "power> ";
char CONTINUE_PROMPT[] = " -> ";
int prompt_size = 7;
#else
char CLIENT_VERSION[] = "Welcome to the TDengine shell from %s, Client Version:%s\n"
- "Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.\n\n";
+ "Copyright (c) 2020 by TAOS Data, Inc. All rights reserved.\n\n";
char PROMPT_HEADER[] = "taos> ";
char CONTINUE_PROMPT[] = " -> ";
diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c
index 3226ad830a..f896253fb4 100644
--- a/src/kit/shell/src/shellLinux.c
+++ b/src/kit/shell/src/shellLinux.c
@@ -46,8 +46,7 @@ static struct argp_option options[] = {
{"thread", 'T', "THREADNUM", 0, "Number of threads when using multi-thread to import data."},
{"database", 'd', "DATABASE", 0, "Database to use when connecting to the server."},
{"timezone", 't', "TIMEZONE", 0, "Time zone of the shell, default is local."},
- {"netrole", 'n', "NETROLE", 0, "Net role when network connectivity test, default is NULL, options: client|clients|server."},
- {"endport", 'e', "ENDPORT", 0, "Net test end port, default is 6042."},
+ {"netrole", 'n', "NETROLE", 0, "Net role when network connectivity test, default is NULL, options: client|server|rpc|startup."},
{"pktlen", 'l', "PKTLEN", 0, "Packet length used for net test, default is 1000 bytes."},
{0}};
@@ -130,20 +129,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
case 'd':
arguments->database = arg;
break;
-
case 'n':
arguments->netTestRole = arg;
break;
-
- case 'e':
- if (arg) {
- arguments->endPort = atoi(arg);
- } else {
- fprintf(stderr, "Invalid end port\n");
- return -1;
- }
- break;
-
case 'l':
if (arg) {
arguments->pktLen = atoi(arg);
@@ -152,7 +140,6 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
return -1;
}
break;
-
case OPT_ABORT:
arguments->abort = 1;
break;
diff --git a/src/kit/shell/src/shellMain.c b/src/kit/shell/src/shellMain.c
index 2083ad3e9b..a2ce78d36f 100644
--- a/src/kit/shell/src/shellMain.c
+++ b/src/kit/shell/src/shellMain.c
@@ -61,8 +61,7 @@ SShellArguments args = {
.file = "\0",
.dir = "\0",
.threadNum = 5,
- .commands = NULL,
- .endPort = 6042,
+ .commands = NULL,
.pktLen = 1000,
.netTestRole = NULL
};
@@ -81,9 +80,7 @@ int main(int argc, char* argv[]) {
if (args.netTestRole && args.netTestRole[0] != 0) {
taos_init();
- CmdArguments cmdArgs;
- memcpy(&cmdArgs, &args, sizeof(SShellArguments));
- taosNetTest(&cmdArgs);
+ taosNetTest(args.netTestRole, args.host, args.port, args.pktLen);
exit(0);
}
diff --git a/src/mnode/src/mnodeDb.c b/src/mnode/src/mnodeDb.c
index c971a945aa..25dbb10536 100644
--- a/src/mnode/src/mnodeDb.c
+++ b/src/mnode/src/mnodeDb.c
@@ -317,13 +317,6 @@ static int32_t mnodeCheckDbCfg(SDbCfg *pCfg) {
return TSDB_CODE_MND_INVALID_DB_OPTION;
}
-#ifndef _SYNC
- if (pCfg->replications != 1) {
- mError("invalid db option replications:%d can only be 1 in this version", pCfg->replications);
- return TSDB_CODE_MND_INVALID_DB_OPTION;
- }
-#endif
-
if (pCfg->update < TSDB_MIN_DB_UPDATE || pCfg->update > TSDB_MAX_DB_UPDATE) {
mError("invalid db option update:%d valid range: [%d, %d]", pCfg->update, TSDB_MIN_DB_UPDATE, TSDB_MAX_DB_UPDATE);
return TSDB_CODE_MND_INVALID_DB_OPTION;
diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c
index 0ff50b2307..f297dd51dd 100644
--- a/src/mnode/src/mnodeDnode.c
+++ b/src/mnode/src/mnodeDnode.c
@@ -111,9 +111,6 @@ static int32_t mnodeDnodeActionInsert(SSdbRow *pRow) {
static int32_t mnodeDnodeActionDelete(SSdbRow *pRow) {
SDnodeObj *pDnode = pRow->pObj;
-#ifndef _SYNC
- mnodeDropAllDnodeVgroups(pDnode);
-#endif
mnodeDropMnodeLocal(pDnode->dnodeId);
bnNotify();
mnodeUpdateDnodeEps();
@@ -705,11 +702,7 @@ static int32_t mnodeDropDnodeByEp(char *ep, SMnodeMsg *pMsg) {
mInfo("dnode:%d, start to drop it", pDnode->dnodeId);
-#ifndef _SYNC
- int32_t code = mnodeDropDnode(pDnode, pMsg);
-#else
int32_t code = bnDropDnode(pDnode);
-#endif
mnodeDecDnodeRef(pDnode);
return code;
}
@@ -1179,58 +1172,3 @@ static char* mnodeGetDnodeAlternativeRoleStr(int32_t alternativeRole) {
default:return "any";
}
}
-
-#ifndef _SYNC
-
-int32_t bnInit() { return TSDB_CODE_SUCCESS; }
-void bnCleanUp() {}
-void bnNotify() {}
-void bnCheckModules() {}
-void bnReset() {}
-int32_t bnAlterDnode(struct SDnodeObj *pDnode, int32_t vnodeId, int32_t dnodeId) { return TSDB_CODE_SYN_NOT_ENABLED; }
-
-char* syncRole[] = {
- "offline",
- "unsynced",
- "syncing",
- "slave",
- "master"
-};
-
-int32_t bnAllocVnodes(SVgObj *pVgroup) {
- void * pIter = NULL;
- SDnodeObj *pDnode = NULL;
- SDnodeObj *pSelDnode = NULL;
- float vnodeUsage = 1000.0;
-
- while (1) {
- pIter = mnodeGetNextDnode(pIter, &pDnode);
- if (pDnode == NULL) break;
-
- if (pDnode->numOfCores > 0 && pDnode->openVnodes < TSDB_MAX_VNODES) {
- float openVnodes = pDnode->openVnodes;
- if (pDnode->isMgmt) openVnodes += tsMnodeEqualVnodeNum;
-
- float usage = openVnodes / pDnode->numOfCores;
- if (usage <= vnodeUsage) {
- pSelDnode = pDnode;
- vnodeUsage = usage;
- }
- }
- mnodeDecDnodeRef(pDnode);
- }
-
- if (pSelDnode == NULL) {
- mError("failed to alloc vnode to vgroup");
- return TSDB_CODE_MND_NO_ENOUGH_DNODES;
- }
-
- pVgroup->vnodeGid[0].dnodeId = pSelDnode->dnodeId;
- pVgroup->vnodeGid[0].pDnode = pSelDnode;
-
- mDebug("dnode:%d, alloc one vnode to vgroup, openVnodes:%d", pSelDnode->dnodeId, pSelDnode->openVnodes);
- return TSDB_CODE_SUCCESS;
-}
-
-#endif
-
diff --git a/src/mnode/src/mnodeMain.c b/src/mnode/src/mnodeMain.c
index 86f2c821f9..7b520c6022 100644
--- a/src/mnode/src/mnodeMain.c
+++ b/src/mnode/src/mnodeMain.c
@@ -37,16 +37,10 @@
#include "mnodeShow.h"
#include "mnodeProfile.h"
-typedef struct {
- const char *const name;
- int (*init)();
- void (*cleanup)();
-} SMnodeComponent;
-
void *tsMnodeTmr = NULL;
static bool tsMgmtIsRunning = false;
-static const SMnodeComponent tsMnodeComponents[] = {
+static SStep tsMnodeSteps[] = {
{"sdbref", sdbInitRef, sdbCleanUpRef},
{"profile", mnodeInitProfile, mnodeCleanupProfile},
{"cluster", mnodeInitCluster, mnodeCleanupCluster},
@@ -67,22 +61,14 @@ static void mnodeInitTimer();
static void mnodeCleanupTimer();
static bool mnodeNeedStart() ;
-static void mnodeCleanupComponents(int32_t stepId) {
- for (int32_t i = stepId; i >= 0; i--) {
- tsMnodeComponents[i].cleanup();
- }
+static void mnodeCleanupComponents() {
+ int32_t stepSize = sizeof(tsMnodeSteps) / sizeof(SStep);
+ dnodeStepCleanup(tsMnodeSteps, stepSize);
}
static int32_t mnodeInitComponents() {
- int32_t code = 0;
- for (int32_t i = 0; i < sizeof(tsMnodeComponents) / sizeof(tsMnodeComponents[0]); i++) {
- if (tsMnodeComponents[i].init() != 0) {
- mnodeCleanupComponents(i);
- code = -1;
- break;
- }
- }
- return code;
+ int32_t stepSize = sizeof(tsMnodeSteps) / sizeof(SStep);
+ return dnodeStepInit(tsMnodeSteps, stepSize);
}
int32_t mnodeStartSystem() {
@@ -132,7 +118,7 @@ void mnodeCleanupSystem() {
dnodeFreeMReadQueue();
dnodeFreeMPeerQueue();
mnodeCleanupTimer();
- mnodeCleanupComponents(sizeof(tsMnodeComponents) / sizeof(tsMnodeComponents[0]) - 1);
+ mnodeCleanupComponents();
mInfo("mnode is cleaned up");
}
diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c
index 2149cb12c0..ff81c37de7 100644
--- a/src/mnode/src/mnodeTable.c
+++ b/src/mnode/src/mnodeTable.c
@@ -1734,6 +1734,16 @@ static int32_t mnodeDoCreateChildTable(SMnodeMsg *pMsg, int32_t tid) {
if (pTable->info.type == TSDB_CHILD_TABLE) {
STagData *pTagData = (STagData *)pCreate->schema; // it is a tag key
+
+ char prefix[64] = {0};
+ size_t prefixLen = tableIdPrefix(pMsg->pDb->name, prefix, 64);
+ if (0 != strncasecmp(prefix, pTagData->name, prefixLen)) {
+ mError("msg:%p, app:%p table:%s, corresponding super table:%s not in this db", pMsg, pMsg->rpcMsg.ahandle,
+ pCreate->tableId, pTagData->name);
+ mnodeDestroyChildTable(pTable);
+ return TSDB_CODE_TDB_INVALID_CREATE_TB_MSG;
+ }
+
if (pMsg->pSTable == NULL) pMsg->pSTable = mnodeGetSuperTable(pTagData->name);
if (pMsg->pSTable == NULL) {
mError("msg:%p, app:%p table:%s, corresponding super table:%s does not exist", pMsg, pMsg->rpcMsg.ahandle,
@@ -2629,9 +2639,7 @@ static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows
SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER;
char prefix[64] = {0};
- tstrncpy(prefix, pDb->name, 64);
- strcat(prefix, TS_PATH_DELIMITER);
- int32_t prefixLen = strlen(prefix);
+ int32_t prefixLen = tableIdPrefix(pDb->name, prefix, 64);
char* pattern = NULL;
if (pShow->payloadLen > 0) {
diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c
index 1cde31cfd2..a45c0ac6ef 100644
--- a/src/query/src/qExecutor.c
+++ b/src/query/src/qExecutor.c
@@ -5837,7 +5837,7 @@ static void doSecondaryArithmeticProcess(SQuery* pQuery) {
tFilePage **data = calloc(pQuery->numOfExpr2, POINTER_BYTES);
for (int32_t i = 0; i < pQuery->numOfExpr2; ++i) {
int32_t bytes = pQuery->pExpr2[i].bytes;
- data[i] = (tFilePage *)malloc(bytes * pQuery->rec.rows + sizeof(tFilePage));
+ data[i] = (tFilePage *)malloc((size_t)(bytes * pQuery->rec.rows) + sizeof(tFilePage));
}
arithSup.offset = 0;
@@ -5859,7 +5859,7 @@ static void doSecondaryArithmeticProcess(SQuery* pQuery) {
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
if (pSqlFunc->functionId == pQuery->pExpr1[j].base.functionId &&
pSqlFunc->colInfo.colId == pQuery->pExpr1[j].base.colInfo.colId) {
- memcpy(data[i]->data, pQuery->sdata[j]->data, pQuery->pExpr1[j].bytes * pQuery->rec.rows);
+ memcpy(data[i]->data, pQuery->sdata[j]->data, (size_t)(pQuery->pExpr1[j].bytes * pQuery->rec.rows));
break;
}
}
@@ -5871,7 +5871,7 @@ static void doSecondaryArithmeticProcess(SQuery* pQuery) {
}
for (int32_t i = 0; i < pQuery->numOfExpr2; ++i) {
- memcpy(pQuery->sdata[i]->data, data[i]->data, pQuery->pExpr2[i].bytes * pQuery->rec.rows);
+ memcpy(pQuery->sdata[i]->data, data[i]->data, (size_t)(pQuery->pExpr2[i].bytes * pQuery->rec.rows));
}
for (int32_t i = 0; i < pQuery->numOfExpr2; ++i) {
diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c
index 00a97d7bc2..587c079fe6 100644
--- a/src/rpc/src/rpcMain.c
+++ b/src/rpc/src/rpcMain.c
@@ -1086,13 +1086,6 @@ static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) {
tDebug("%s %p %p, %s is sent with error code:0x%x", pRpc->label, pConn, (void *)pHead->ahandle, taosMsg[pHead->msgType+1], code);
}
} else { // msg is passed to app only parsing is ok
-
- if (pHead->msgType == TSDB_MSG_TYPE_NETWORK_TEST) {
- rpcSendQuickRsp(pConn, TSDB_CODE_SUCCESS);
- rpcFreeMsg(pRecv->msg);
- return pConn;
- }
-
rpcProcessIncomingMsg(pConn, pHead, pContext);
}
}
diff --git a/src/sync/src/syncMain.c b/src/sync/src/syncMain.c
index b73ca27ce9..c86265d556 100644
--- a/src/sync/src/syncMain.c
+++ b/src/sync/src/syncMain.c
@@ -226,7 +226,7 @@ int64_t syncStart(const SSyncInfo *pInfo) {
}
if (pNode->selfIndex < 0) {
- sInfo("vgId:%d, this node is not configured", pNode->vgId);
+ sError("vgId:%d, this node is not configured", pNode->vgId);
terrno = TSDB_CODE_SYN_INVALID_CONFIG;
syncStop(pNode->rid);
return -1;
diff --git a/src/tsdb/src/tsdbCommitQueue.c b/src/tsdb/src/tsdbCommitQueue.c
index c86b8f32b7..75a2cbcb8d 100644
--- a/src/tsdb/src/tsdbCommitQueue.c
+++ b/src/tsdb/src/tsdbCommitQueue.c
@@ -14,6 +14,7 @@
*/
#include "os.h"
+#include "tglobal.h"
#include "tlist.h"
#include "tref.h"
#include "tsdbMain.h"
@@ -36,7 +37,8 @@ static void *tsdbLoopCommit(void *arg);
SCommitQueue tsCommitQueue = {0};
-int tsdbInitCommitQueue(int nthreads) {
+int tsdbInitCommitQueue() {
+ int nthreads = tsNumOfCommitThreads;
SCommitQueue *pQueue = &tsCommitQueue;
if (nthreads < 1) nthreads = 1;
diff --git a/src/util/inc/tnettest.h b/src/util/inc/tnettest.h
index 426df5cbb2..b7585bd715 100644
--- a/src/util/inc/tnettest.h
+++ b/src/util/inc/tnettest.h
@@ -20,27 +20,7 @@
extern "C" {
#endif
-typedef struct CmdArguments {
- char* host;
- char* password;
- char* user;
- char* auth;
- char* database;
- char* timezone;
- bool is_raw_time;
- bool is_use_passwd;
- char file[TSDB_FILENAME_LEN];
- char dir[TSDB_FILENAME_LEN];
- int threadNum;
- char* commands;
- int abort;
- int port;
- int endPort;
- int pktLen;
- char* netTestRole;
-} CmdArguments;
-
-void taosNetTest(CmdArguments* args);
+void taosNetTest(char *role, char *host, int port, int pkgLen);
#ifdef __cplusplus
}
diff --git a/src/util/src/tnettest.c b/src/util/src/tnettest.c
index 6fd5265983..c269d9a1ff 100644
--- a/src/util/src/tnettest.c
+++ b/src/util/src/tnettest.c
@@ -13,50 +13,42 @@
* along with this program. If not, see .
*/
+#define _DEFAULT_SOURCE
#include "os.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "taoserror.h"
#include "tulog.h"
-#include "tconfig.h"
#include "tglobal.h"
#include "tsocket.h"
#include "trpc.h"
#include "rpcHead.h"
-#include "tutil.h"
-#include "tnettest.h"
-#define MAX_PKG_LEN (64*1000)
-#define BUFFER_SIZE (MAX_PKG_LEN + 1024)
+#define MAX_PKG_LEN (64 * 1000)
+#define BUFFER_SIZE (MAX_PKG_LEN + 1024)
+
+extern int32_t tsRpcMaxUdpSize;
typedef struct {
+ char * hostFqdn;
uint32_t hostIp;
- uint16_t port;
- uint16_t pktLen;
-} info_s;
+ int32_t port;
+ int32_t pktLen;
+} STestInfo;
-extern int tsRpcMaxUdpSize;
-
-static char g_user[TSDB_USER_LEN+1] = {0};
-static char g_pass[TSDB_PASSWORD_LEN+1] = {0};
-static char g_serverFqdn[TSDB_FQDN_LEN] = {0};
-static uint16_t g_startPort = 0;
-static uint16_t g_endPort = 6042;
-static uint32_t g_pktLen = 0;
-
-
-static void *bindUdpPort(void *sarg) {
- info_s *pinfo = (info_s *)sarg;
- int port = pinfo->port;
- SOCKET serverSocket;
+static void *taosNetBindUdpPort(void *sarg) {
+ STestInfo *pinfo = (STestInfo *)sarg;
+ int32_t port = pinfo->port;
+ SOCKET serverSocket;
+ char buffer[BUFFER_SIZE];
+ int32_t iDataNum;
+ socklen_t sin_size;
struct sockaddr_in server_addr;
struct sockaddr_in clientAddr;
- char buffer[BUFFER_SIZE];
- int iDataNum;
-
+
if ((serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
- perror("socket");
+ uError("failed to create udp socket since %s", strerror(errno));
return NULL;
}
@@ -66,28 +58,25 @@ static void *bindUdpPort(void *sarg) {
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
- perror("connect");
+ uError("failed to bind udp port:%d since %s", port, strerror(errno));
return NULL;
}
- socklen_t sin_size;
+ uInfo("udp server at port:%d is listening", port);
while (1) {
memset(buffer, 0, BUFFER_SIZE);
-
sin_size = sizeof(*(struct sockaddr *)&server_addr);
-
iDataNum = recvfrom(serverSocket, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&clientAddr, &sin_size);
if (iDataNum < 0) {
- perror("recvfrom null");
+ uDebug("failed to perform recvfrom func at %d since %s", port, strerror(errno));
continue;
}
- if (iDataNum > 0) {
- printf("recv Client: %s pkg from UDP port: %d, pkg len: %d\n", taosInetNtoa(clientAddr.sin_addr), port, iDataNum);
- //printf("Read msg from udp:%s ... %s\n", buffer, buffer+iDataNum-16);
- sendto(serverSocket, buffer, iDataNum, 0, (struct sockaddr *)&clientAddr, (int)sin_size);
+ if (iDataNum > 0) {
+ uInfo("UDP: recv:%d bytes from %s:%d", iDataNum, taosInetNtoa(clientAddr.sin_addr), port);
+ sendto(serverSocket, buffer, iDataNum, 0, (struct sockaddr *)&clientAddr, (int32_t)sin_size);
}
}
@@ -95,20 +84,20 @@ static void *bindUdpPort(void *sarg) {
return NULL;
}
-static void *bindTcpPort(void *sarg) {
- info_s *pinfo = (info_s *)sarg;
- int port = pinfo->port;
- SOCKET serverSocket;
-
+static void *taosNetBindTcpPort(void *sarg) {
struct sockaddr_in server_addr;
struct sockaddr_in clientAddr;
- int addr_len = sizeof(clientAddr);
- SOCKET client;
- char buffer[BUFFER_SIZE];
- int iDataNum = 0;
+
+ STestInfo *pinfo = sarg;
+ int32_t port = pinfo->port;
+ SOCKET serverSocket;
+ int32_t addr_len = sizeof(clientAddr);
+ SOCKET client;
+ char buffer[BUFFER_SIZE];
+ int32_t iDataNum = 0;
if ((serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
- printf("socket() fail: %s", strerror(errno));
+ uError("failed to create tcp socket since %s", strerror(errno));
return NULL;
}
@@ -118,28 +107,30 @@ static void *bindTcpPort(void *sarg) {
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
- printf("port:%d bind() fail: %s", port, strerror(errno));
+ uError("failed to bind tcp port:%d since %s", port, strerror(errno));
return NULL;
}
if (listen(serverSocket, 5) < 0) {
- printf("listen() fail: %s", strerror(errno));
+ uError("failed to listen tcp port:%d since %s", port, strerror(errno));
return NULL;
}
- //printf("Bind port: %d success\n", port);
+ uInfo("tcp server at port:%d is listening", port);
+
while (1) {
client = accept(serverSocket, (struct sockaddr *)&clientAddr, (socklen_t *)&addr_len);
if (client < 0) {
- printf("accept() fail: %s", strerror(errno));
+ uDebug("failed to accept from tcp port:%d since %s", port, strerror(errno));
continue;
}
iDataNum = 0;
memset(buffer, 0, BUFFER_SIZE);
- int nleft, nread;
- char *ptr = buffer;
+ int32_t nleft, nread;
+ char * ptr = buffer;
nleft = pinfo->pktLen;
+
while (nleft > 0) {
nread = recv(client, ptr, BUFFER_SIZE, 0);
@@ -149,7 +140,7 @@ static void *bindTcpPort(void *sarg) {
if (errno == EINTR) {
continue;
} else {
- printf("recv Client: %s pkg from TCP port: %d fail:%s.\n", taosInetNtoa(clientAddr.sin_addr), port, strerror(errno));
+ uError("failed to perform recv func at %d since %s", port, strerror(errno));
taosCloseSocket(serverSocket);
return NULL;
}
@@ -157,11 +148,11 @@ static void *bindTcpPort(void *sarg) {
nleft -= nread;
ptr += nread;
iDataNum += nread;
- }
+ }
}
-
- printf("recv Client: %s pkg from TCP port: %d, pkg len: %d\n", taosInetNtoa(clientAddr.sin_addr), port, iDataNum);
+
if (iDataNum > 0) {
+ uInfo("TCP: recv:%d bytes from %s:%d", iDataNum, taosInetNtoa(clientAddr.sin_addr), port);
send(client, buffer, iDataNum, 0);
}
}
@@ -170,39 +161,38 @@ static void *bindTcpPort(void *sarg) {
return NULL;
}
-static int checkTcpPort(info_s *info) {
+static int32_t taosNetCheckTcpPort(STestInfo *info) {
+ SOCKET clientSocket;
+ char sendbuf[BUFFER_SIZE];
+ char recvbuf[BUFFER_SIZE];
+ int32_t iDataNum = 0;
+
struct sockaddr_in serverAddr;
- SOCKET clientSocket;
- char sendbuf[BUFFER_SIZE];
- char recvbuf[BUFFER_SIZE];
- int iDataNum = 0;
if ((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("socket() fail: %s\n", strerror(errno));
+ uError("failed to create tcp client socket since %s", strerror(errno));
return -1;
}
// set send and recv overtime
- struct timeval timeout;
- timeout.tv_sec = 2; //s
- timeout.tv_usec = 0; //us
- if (setsockopt(clientSocket, SOL_SOCKET,SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval)) == -1) {
- perror("setsockopt send timer failed:");
+ struct timeval timeout;
+ timeout.tv_sec = 2; // s
+ timeout.tv_usec = 0; // us
+ if (setsockopt(clientSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval)) == -1) {
+ uError("failed to setsockopt send timer since %s", strerror(errno));
}
- if (setsockopt(clientSocket, SOL_SOCKET,SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)) == -1) {
- perror("setsockopt recv timer failed:");
+ if (setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)) == -1) {
+ uError("failed to setsockopt recv timer since %s", strerror(errno));
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(info->port);
-
serverAddr.sin_addr.s_addr = info->hostIp;
- //printf("=================================\n");
if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
- printf("connect() fail: %s\t", strerror(errno));
+ uError("failed to connect port:%d since %s", info->port, strerror(errno));
return -1;
}
- //printf("Connect to: %s:%d...success\n", host, port);
+
memset(sendbuf, 0, BUFFER_SIZE);
memset(recvbuf, 0, BUFFER_SIZE);
@@ -214,9 +204,10 @@ static int checkTcpPort(info_s *info) {
send(clientSocket, sendbuf, info->pktLen, 0);
memset(recvbuf, 0, BUFFER_SIZE);
- int nleft, nread;
- char *ptr = recvbuf;
+ int32_t nleft, nread;
+ char * ptr = recvbuf;
nleft = info->pktLen;
+
while (nleft > 0) {
nread = recv(clientSocket, ptr, BUFFER_SIZE, 0);;
@@ -226,7 +217,7 @@ static int checkTcpPort(info_s *info) {
if (errno == EINTR) {
continue;
} else {
- printf("recv ack pkg from TCP port: %d fail:%s.\n", info->port, strerror(errno));
+ uError("faild to recv pkg from TCP port:%d since %s", info->port, strerror(errno));
taosCloseSocket(clientSocket);
return -1;
}
@@ -234,45 +225,46 @@ static int checkTcpPort(info_s *info) {
nleft -= nread;
ptr += nread;
iDataNum += nread;
- }
+ }
}
if (iDataNum < info->pktLen) {
- printf("recv ack pkg len: %d, less than req pkg len: %d from tcp port: %d\n", iDataNum, info->pktLen, info->port);
+ uError("TCP: received ack:%d bytes, less than send:%d bytes from port:%d", iDataNum, info->pktLen, info->port);
return -1;
}
- //printf("Read ack pkg len:%d from tcp port: %d, buffer: %s %s\n", info->pktLen, port, recvbuf, recvbuf+iDataNum-8);
taosCloseSocket(clientSocket);
return 0;
}
-static int checkUdpPort(info_s *info) {
+static int32_t taosNetCheckUdpPort(STestInfo *info) {
+ SOCKET clientSocket;
+ char sendbuf[BUFFER_SIZE];
+ char recvbuf[BUFFER_SIZE];
+ int32_t iDataNum = 0;
+
struct sockaddr_in serverAddr;
- SOCKET clientSocket;
- char sendbuf[BUFFER_SIZE];
- char recvbuf[BUFFER_SIZE];
- int iDataNum = 0;
+
if ((clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
- perror("socket");
+ uError("failed to create udp client socket since %s", strerror(errno));
return -1;
}
- // set overtime
+ // set overtime
struct timeval timeout;
- timeout.tv_sec = 2; //s
- timeout.tv_usec = 0; //us
- if (setsockopt(clientSocket, SOL_SOCKET,SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval)) == -1) {
- perror("setsockopt send timer failed:");
+ timeout.tv_sec = 2; // s
+ timeout.tv_usec = 0; // us
+ if (setsockopt(clientSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval)) == -1) {
+ uError("failed to setsockopt send timer since %s", strerror(errno));
}
- if (setsockopt(clientSocket, SOL_SOCKET,SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)) == -1) {
- perror("setsockopt recv timer failed:");
+ if (setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)) == -1) {
+ uError("failed to setsockopt recv timer since %s", strerror(errno));
}
-
+
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(info->port);
serverAddr.sin_addr.s_addr = info->hostIp;
-
+
memset(sendbuf, 0, BUFFER_SIZE);
memset(recvbuf, 0, BUFFER_SIZE);
@@ -283,69 +275,66 @@ static int checkUdpPort(info_s *info) {
socklen_t sin_size = sizeof(*(struct sockaddr *)&serverAddr);
- int code = sendto(clientSocket, sendbuf, info->pktLen, 0, (struct sockaddr *)&serverAddr, (int)sin_size);
+ int32_t code = sendto(clientSocket, sendbuf, info->pktLen, 0, (struct sockaddr *)&serverAddr, (int32_t)sin_size);
if (code < 0) {
- perror("sendto");
+ uError("failed to perform sendto func since %s", strerror(errno));
return -1;
}
iDataNum = recvfrom(clientSocket, recvbuf, BUFFER_SIZE, 0, (struct sockaddr *)&serverAddr, &sin_size);
if (iDataNum < info->pktLen) {
- printf("Read ack pkg len: %d, less than req pkg len: %d from udp port: %d\t\t", iDataNum, info->pktLen, info->port);
+ uError("UDP: received ack:%d bytes, less than send:%d bytes from port:%d", iDataNum, info->pktLen, info->port);
return -1;
}
-
- //printf("Read ack pkg len:%d from udp port: %d, buffer: %s %s\n", info->pktLen, port, recvbuf, recvbuf+iDataNum-8);
+
taosCloseSocket(clientSocket);
return 0;
}
-static void checkPort(uint32_t hostIp, uint16_t startPort, uint16_t maxPort, uint16_t pktLen) {
- int ret;
- info_s info;
- memset(&info, 0, sizeof(info_s));
- info.hostIp = hostIp;
- info.pktLen = pktLen;
+static void taosNetCheckPort(uint32_t hostIp, int32_t startPort, int32_t endPort, int32_t pktLen) {
+ int32_t ret;
+ STestInfo info;
- for (uint16_t port = startPort; port <= maxPort; port++) {
- //printf("test: %s:%d\n", info.host, port);
- printf("\n");
+ memset(&info, 0, sizeof(STestInfo));
+ info.hostIp = hostIp;
+ info.pktLen = pktLen;
+ for (int32_t port = startPort; port <= endPort; port++) {
info.port = port;
- ret = checkTcpPort(&info);
+ ret = taosNetCheckTcpPort(&info);
if (ret != 0) {
- printf("tcp port:%d test fail.\t\n", port);
+ uError("failed to test tcp port:%d", port);
} else {
- printf("tcp port:%d test ok.\t\t", port);
+ uInfo("successed to test tcp port:%d", port);
}
-
- ret = checkUdpPort(&info);
+
+ ret = taosNetCheckUdpPort(&info);
if (ret != 0) {
- printf("udp port:%d test fail.\t\n", port);
+ uError("failed to test udp port:%d", port);
} else {
- printf("udp port:%d test ok.\t\t", port);
+ uInfo("successed to test udp port:%d", port);
}
}
-
- printf("\n");
- return ;
+ return;
}
-void* tnetInitRpc(char* secretEncrypt, char spi) {
+void *taosNetInitRpc(char *secretEncrypt, char spi) {
SRpcInit rpcInit;
- void* pRpcConn = NULL;
+ void * pRpcConn = NULL;
+
+ char user[] = "nettestinternal";
+ char pass[] = "nettestinternal";
+ taosEncryptPass((uint8_t *)pass, strlen(pass), secretEncrypt);
- taosEncryptPass((uint8_t *)g_pass, strlen(g_pass), secretEncrypt);
-
memset(&rpcInit, 0, sizeof(rpcInit));
rpcInit.localPort = 0;
- rpcInit.label = "NET-TEST";
+ rpcInit.label = "NT";
rpcInit.numOfThreads = 1; // every DB connection has only one thread
rpcInit.cfp = NULL;
rpcInit.sessions = 16;
rpcInit.connType = TAOS_CONN_CLIENT;
- rpcInit.user = g_user;
+ rpcInit.user = user;
rpcInit.idleTime = 2000;
rpcInit.ckey = "key";
rpcInit.spi = spi;
@@ -355,17 +344,18 @@ void* tnetInitRpc(char* secretEncrypt, char spi) {
return pRpcConn;
}
-static int rpcCheckPortImpl(const char* serverFqdn, uint16_t port, uint16_t pktLen, char spi) {
+static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t pktLen, char spi, SStartupStep *pStep) {
SRpcEpSet epSet;
SRpcMsg reqMsg;
SRpcMsg rspMsg;
- void* pRpcConn;
+ void * pRpcConn;
char secretEncrypt[32] = {0};
- pRpcConn = tnetInitRpc(secretEncrypt, spi);
+ pRpcConn = taosNetInitRpc(secretEncrypt, spi);
if (NULL == pRpcConn) {
- return -1;
+ uError("failed to init client rpc");
+ return TSDB_CODE_RPC_NETWORK_UNAVAIL;
}
memset(&epSet, 0, sizeof(SRpcEpSet));
@@ -373,205 +363,171 @@ static int rpcCheckPortImpl(const char* serverFqdn, uint16_t port, uint16_t pktL
epSet.numOfEps = 1;
epSet.port[0] = port;
strcpy(epSet.fqdn[0], serverFqdn);
-
+
reqMsg.msgType = TSDB_MSG_TYPE_NETWORK_TEST;
reqMsg.pCont = rpcMallocCont(pktLen);
reqMsg.contLen = pktLen;
reqMsg.code = 0;
reqMsg.handle = NULL; // rpc handle returned to app
- reqMsg.ahandle = NULL; // app handle set by client
+ reqMsg.ahandle = NULL; // app handle set by client
+ strcpy(reqMsg.pCont, "nettest");
rpcSendRecv(pRpcConn, &epSet, &reqMsg, &rspMsg);
- // handle response
if ((rspMsg.code != 0) || (rspMsg.msgType != TSDB_MSG_TYPE_NETWORK_TEST + 1)) {
- //printf("code:%d[%s]\n", rspMsg.code, tstrerror(rspMsg.code));
- return -1;
+ uDebug("ret code 0x%x %s", rspMsg.code, tstrerror(rspMsg.code));
+ return rspMsg.code;
}
-
+
+ int32_t code = 0;
+ if (pStep != NULL && rspMsg.pCont != NULL && rspMsg.contLen > 0 && rspMsg.contLen <= sizeof(SStartupStep)) {
+ memcpy(pStep, rspMsg.pCont, rspMsg.contLen);
+ code = 1;
+ }
+
rpcFreeCont(rspMsg.pCont);
-
rpcClose(pRpcConn);
-
- return 0;
+ return code;
}
-static void rpcCheckPort(uint32_t hostIp) {
- int ret;
- char spi;
+static int32_t taosNetParseStartup(SStartupStep *pCont) {
+ SStartupStep *pStep = pCont;
+ uInfo("step:%s desc:%s", pStep->name, pStep->desc);
- for (uint16_t port = g_startPort; port <= g_endPort; port++) {
- //printf("test: %s:%d\n", info.host, port);
- printf("\n");
+ if (pStep->finished) {
+ uInfo("check startup finished");
+ }
- //================ check tcp port ================
- int32_t pktLen;
- if (g_pktLen <= tsRpcMaxUdpSize) {
- pktLen = tsRpcMaxUdpSize + 1000;
- } else {
- pktLen = g_pktLen;
+ return pStep->finished ? 0 : 1;
+}
+
+static void taosNetTestStartup(char *host, int32_t port) {
+ uInfo("check startup, host:%s port:%d\n", host, port);
+
+ SStartupStep *pStep = malloc(sizeof(SStartupStep));
+ while (1) {
+ int32_t code = taosNetCheckRpc(host, port + TSDB_PORT_DNODEDNODE, 20, 0, pStep);
+ if (code > 0) {
+ code = taosNetParseStartup(pStep);
}
- spi = 1;
- ret = rpcCheckPortImpl(g_serverFqdn, port, pktLen, spi);
- if (ret != 0) {
- spi = 0;
- ret = rpcCheckPortImpl(g_serverFqdn, port, pktLen, spi);
- if (ret != 0) {
- printf("TCP port:%d test fail.\t\t", port);
- } else {
- //printf("tcp port:%d test ok.\t\t", port);
- printf("TCP port:\033[32m%d test OK\033[0m\t\t", port);
- }
+ if (code > 0) {
+ uDebug("continue check startup step");
} else {
- //printf("tcp port:%d test ok.\t\t", port);
- printf("TCP port:\033[32m%d test OK\033[0m\t\t", port);
- }
-
- //================ check udp port ================
- if (g_pktLen >= tsRpcMaxUdpSize) {
- pktLen = tsRpcMaxUdpSize - 1000;
- } else {
- pktLen = g_pktLen;
- }
-
- spi = 0;
- ret = rpcCheckPortImpl(g_serverFqdn, port, pktLen, spi);
- if (ret != 0) {
- spi = 1;
- ret = rpcCheckPortImpl(g_serverFqdn, port, pktLen, spi);
- if (ret != 0) {
- printf("udp port:%d test fail.\t\n", port);
- } else {
- //printf("udp port:%d test ok.\t\n", port);
- printf("UDP port:\033[32m%d test OK\033[0m\t\n", port);
- }
- } else {
- //printf("udp port:%d test ok.\t\n", port);
- printf("UDP port:\033[32m%d test OK\033[0m\t\n", port);
+ if (code < 0) {
+ uError("failed to check startup step, code:0x%x %s", code, tstrerror(code));
+ }
+ break;
}
}
-
- printf("\n");
- return ;
+
+ free(pStep);
}
-static void taosNetTestClient(int flag) {
- uint32_t serverIp = taosGetIpFromFqdn(g_serverFqdn);
+static void taosNetTestRpc(char *host, int32_t startPort, int32_t pkgLen) {
+ int32_t endPort = startPort + 9;
+ char spi = 0;
+
+ uInfo("check rpc, host:%s startPort:%d endPort:%d pkgLen:%d\n", host, startPort, endPort, pkgLen);
+
+ for (uint16_t port = startPort; port <= endPort; port++) {
+ int32_t sendpkgLen;
+ if (pkgLen <= tsRpcMaxUdpSize) {
+ sendpkgLen = tsRpcMaxUdpSize + 1000;
+ } else {
+ sendpkgLen = pkgLen;
+ }
+
+ int32_t ret = taosNetCheckRpc(host, port, sendpkgLen, spi, NULL);
+ if (ret < 0) {
+ uError("failed to test tcp port:%d", port);
+ } else {
+ uInfo("successed to test tcp port:%d", port);
+ }
+
+ if (pkgLen >= tsRpcMaxUdpSize) {
+ sendpkgLen = tsRpcMaxUdpSize - 1000;
+ } else {
+ sendpkgLen = pkgLen;
+ }
+
+ ret = taosNetCheckRpc(host, port, pkgLen, spi, NULL);
+ if (ret < 0) {
+ uError("failed to test udp port:%d", port);
+ } else {
+ uInfo("successed to test udp port:%d", port);
+ }
+ }
+}
+
+static void taosNetTestClient(char *host, int32_t startPort, int32_t pkgLen) {
+ int32_t endPort = startPort + 11;
+ uInfo("work as client, host:%s startPort:%d endPort:%d pkgLen:%d\n", host, startPort, endPort, pkgLen);
+
+ uint32_t serverIp = taosGetIpFromFqdn(host);
if (serverIp == 0xFFFFFFFF) {
- printf("Failed to resolve FQDN:%s", g_serverFqdn);
+ uError("failed to resolve fqdn:%s", host);
exit(-1);
}
- if (0 == flag) {
- checkPort(serverIp, g_startPort, g_endPort, g_pktLen);
- } else {
- rpcCheckPort(serverIp);
- }
-
- return;
+ uInfo("server ip:%s is resolved from host:%s", taosIpStr(serverIp), host);
+ taosNetCheckPort(serverIp, startPort, endPort, pkgLen);
}
-static void taosNetTestServer(uint16_t startPort, uint16_t endPort, int pktLen) {
+static void taosNetTestServer(char *host, int32_t startPort, int32_t pkgLen) {
+ int32_t endPort = startPort + 11;
+ uInfo("work as server, host:%s startPort:%d endPort:%d pkgLen:%d\n", host, startPort, endPort, pkgLen);
- int port = startPort;
- int num = endPort - startPort + 1;
+ int32_t port = startPort;
+ int32_t num = endPort - startPort + 1;
+ if (num < 0) num = 1;
- if (num < 0) {
- num = 1;
- }
-
pthread_t *pids = malloc(2 * num * sizeof(pthread_t));
- info_s * tinfos = malloc(num * sizeof(info_s));
- info_s * uinfos = malloc(num * sizeof(info_s));
+ STestInfo *tinfos = malloc(num * sizeof(STestInfo));
+ STestInfo *uinfos = malloc(num * sizeof(STestInfo));
- for (size_t i = 0; i < num; i++) {
- info_s *tcpInfo = tinfos + i;
- tcpInfo->port = (uint16_t)(port + i);
- tcpInfo->pktLen = pktLen;
+ for (int32_t i = 0; i < num; i++) {
+ STestInfo *tcpInfo = tinfos + i;
+ tcpInfo->port = port + i;
+ tcpInfo->pktLen = pkgLen;
- if (pthread_create(pids + i, NULL, bindTcpPort, tcpInfo) != 0)
- {
- printf("create thread fail, port:%d.\n", port);
+ if (pthread_create(pids + i, NULL, taosNetBindTcpPort, tcpInfo) != 0) {
+ uInfo("failed to create tcp test thread, %s:%d", tcpInfo->hostFqdn, tcpInfo->port);
exit(-1);
}
- info_s *udpInfo = uinfos + i;
+ STestInfo *udpInfo = uinfos + i;
udpInfo->port = (uint16_t)(port + i);
- if (pthread_create(pids + num + i, NULL, bindUdpPort, udpInfo) != 0)
- {
- printf("create thread fail, port:%d.\n", port);
+ if (pthread_create(pids + num + i, NULL, taosNetBindUdpPort, udpInfo) != 0) {
+ uInfo("failed to create udp test thread, %s:%d", tcpInfo->hostFqdn, tcpInfo->port);
exit(-1);
}
}
-
- for (int i = 0; i < num; i++) {
+
+ for (int32_t i = 0; i < num; i++) {
pthread_join(pids[i], NULL);
pthread_join(pids[(num + i)], NULL);
}
}
+void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen) {
+ tscEmbedded = 1;
+ if (host == NULL) host = tsLocalFqdn;
+ if (port == 0) port = tsServerPort;
+ if (pkgLen <= 10) pkgLen = 1000;
+ if (pkgLen > MAX_PKG_LEN) pkgLen = MAX_PKG_LEN;
-void taosNetTest(CmdArguments *args) {
- if (0 == args->pktLen) {
- g_pktLen = 1000;
+ if (0 == strcmp("client", role)) {
+ taosNetTestClient(host, port, pkgLen);
+ } else if (0 == strcmp("server", role)) {
+ taosNetTestServer(host, port, pkgLen);
+ } else if (0 == strcmp("rpc", role)) {
+ taosNetTestRpc(host, port, pkgLen);
+ } else if (0 == strcmp("startup", role)) {
+ taosNetTestStartup(host, port);
} else {
- g_pktLen = args->pktLen;
- }
-
- if (args->port && args->endPort) {
- if (args->port > args->endPort) {
- printf("endPort[%d] must not lesss port[%d]\n", args->endPort, args->port);
- exit(-1);
- }
- }
-
- if (args->host && args->host[0] != 0) {
- if (strlen(args->host) >= TSDB_EP_LEN) {
- printf("host invalid: %s\n", args->host);
- exit(-1);
- }
-
- taosGetFqdnPortFromEp(args->host, g_serverFqdn, &g_startPort);
- } else {
- tstrncpy(g_serverFqdn, "127.0.0.1", TSDB_IPv4ADDR_LEN);
- g_startPort = tsServerPort;
- }
-
- if (args->port) {
- g_startPort = args->port;
- }
-
- if (args->endPort) {
- g_endPort = args->endPort;
- }
-
- if (g_startPort > g_endPort) {
- printf("endPort[%d] must not lesss port[%d]\n", g_endPort, g_startPort);
- exit(-1);
+ taosNetTestStartup(host, port);
}
-
- if (args->is_use_passwd) {
- if (args->password == NULL) args->password = getpass("Enter password: ");
- } else {
- args->password = TSDB_DEFAULT_PASS;
- }
- tstrncpy(g_pass, args->password, TSDB_PASSWORD_LEN);
-
- if (args->user == NULL) {
- args->user = TSDB_DEFAULT_USER;
- }
- tstrncpy(g_user, args->user, TSDB_USER_LEN);
-
- if (0 == strcmp("client", args->netTestRole)) {
- printf("host: %s\tstart port: %d\tend port: %d\tpacket len: %d\n", g_serverFqdn, g_startPort, g_endPort, g_pktLen);
- taosNetTestClient(0);
- } else if (0 == strcmp("clients", args->netTestRole)) {
- printf("host: %s\tstart port: %d\tend port: %d\tpacket len: %d\n", g_serverFqdn, g_startPort, g_endPort, g_pktLen);
- taosNetTestClient(1);
- } else if (0 == strcmp("server", args->netTestRole)) {
- taosNetTestServer(g_startPort, g_endPort, g_pktLen);
- }
+ tscEmbedded = 0;
}
-
diff --git a/src/util/src/tqueue.c b/src/util/src/tqueue.c
index 143ce7c474..d72bc5f412 100644
--- a/src/util/src/tqueue.c
+++ b/src/util/src/tqueue.c
@@ -358,15 +358,15 @@ int taosReadQitemFromQset(taos_qset param, int *type, void **pitem, void **phand
if (queue->head) {
pNode = queue->head;
*pitem = pNode->item;
- *type = pNode->type;
- *phandle = queue->ahandle;
+ if (type) *type = pNode->type;
+ if (phandle) *phandle = queue->ahandle;
queue->head = pNode->next;
if (queue->head == NULL)
queue->tail = NULL;
queue->numOfItems--;
atomic_sub_fetch_32(&qset->numOfItems, 1);
code = 1;
- uTrace("item:%p is read out from queue:%p, type:%d items:%d", *pitem, queue, *type, queue->numOfItems);
+ uTrace("item:%p is read out from queue:%p, type:%d items:%d", *pitem, queue, pNode->type, queue->numOfItems);
}
pthread_mutex_unlock(&queue->mutex);
diff --git a/src/vnode/inc/vnodeCfg.h b/src/vnode/inc/vnodeCfg.h
index c5887fef5d..ba148c07c1 100644
--- a/src/vnode/inc/vnodeCfg.h
+++ b/src/vnode/inc/vnodeCfg.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "vnodeInt.h"
int32_t vnodeReadCfg(SVnodeObj *pVnode);
int32_t vnodeWriteCfg(SCreateVnodeMsg *pVnodeCfg);
diff --git a/src/vnode/inc/vnodeInt.h b/src/vnode/inc/vnodeInt.h
index e468c2e83e..401c217b9a 100644
--- a/src/vnode/inc/vnodeInt.h
+++ b/src/vnode/inc/vnodeInt.h
@@ -19,11 +19,11 @@
#ifdef __cplusplus
extern "C" {
#endif
-
#include "tlog.h"
#include "tsync.h"
-#include "twal.h"
#include "tcq.h"
+#include "tsdb.h"
+#include "vnode.h"
extern int32_t vDebugFlag;
@@ -35,39 +35,37 @@ extern int32_t vDebugFlag;
#define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
typedef struct {
- int32_t vgId; // global vnode group ID
- int32_t refCount; // reference count
- int32_t queuedWMsg;
- int32_t queuedRMsg;
- int32_t flowctrlLevel;
- int8_t status;
- int8_t role;
- int8_t accessState;
- int8_t isFull;
- int8_t isCommiting;
- uint64_t version; // current version
- uint64_t fversion; // version on saved data file
- void *wqueue;
- void *rqueue;
- void *wal;
- void *tsdb;
- int64_t sync;
- void *events;
- void *cq; // continuous query
- int32_t cfgVersion;
- STsdbCfg tsdbCfg;
- SSyncCfg syncCfg;
- SWalCfg walCfg;
- void *qMgmt;
- char *rootDir;
- tsem_t sem;
- int8_t dropped;
- char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
+ int32_t vgId; // global vnode group ID
+ int32_t refCount; // reference count
+ int32_t queuedWMsg;
+ int32_t queuedRMsg;
+ int32_t flowctrlLevel;
+ int8_t status;
+ int8_t role;
+ int8_t accessState;
+ int8_t isFull;
+ int8_t isCommiting;
+ uint64_t version; // current version
+ uint64_t fversion; // version on saved data file
+ void * wqueue;
+ void * rqueue;
+ void * wal;
+ void * tsdb;
+ int64_t sync;
+ void * events;
+ void * cq; // continuous query
+ int32_t cfgVersion;
+ STsdbCfg tsdbCfg;
+ SSyncCfg syncCfg;
+ SWalCfg walCfg;
+ void * qMgmt;
+ char * rootDir;
+ tsem_t sem;
+ int8_t dropped;
+ char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
+ pthread_mutex_t statusMutex;
} SVnodeObj;
-void vnodeInitWriteFp(void);
-void vnodeInitReadFp(void);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/vnode/inc/vnodeMain.h b/src/vnode/inc/vnodeMain.h
new file mode 100644
index 0000000000..e1ddcdc36a
--- /dev/null
+++ b/src/vnode/inc/vnodeMain.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_MAIN_H
+#define TDENGINE_VNODE_MAIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "vnodeInt.h"
+
+int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
+int32_t vnodeDrop(int32_t vgId);
+int32_t vnodeOpen(int32_t vgId);
+int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
+int32_t vnodeClose(int32_t vgId);
+
+int32_t vnodeReset(SVnodeObj *pVnode);
+void vnodeCleanUp(SVnodeObj *pVnode);
+void vnodeDestroy(SVnodeObj *pVnode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/vnode/inc/vnodeMgmt.h b/src/vnode/inc/vnodeMgmt.h
new file mode 100644
index 0000000000..5a7e745619
--- /dev/null
+++ b/src/vnode/inc/vnodeMgmt.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_MGMT_H
+#define TDENGINE_VNODE_MGMT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "vnodeInt.h"
+
+int32_t vnodeInitMgmt();
+void vnodeCleanupMgmt();
+
+void* vnodeAcquire(int32_t vgId);
+void vnodeRelease(void *pVnode);
+void* vnodeGetWal(void *pVnode);
+
+int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes);
+void vnodeBuildStatusMsg(void *pStatus);
+void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes);
+
+void vnodeAddIntoHash(SVnodeObj* pVnode);
+void vnodeRemoveFromHash(SVnodeObj * pVnode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/vnode/inc/vnodeRead.h b/src/vnode/inc/vnodeRead.h
new file mode 100644
index 0000000000..f2953d79f4
--- /dev/null
+++ b/src/vnode/inc/vnodeRead.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_READ_H
+#define TDENGINE_VNODE_READ_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "vnodeInt.h"
+
+int32_t vnodeInitRead(void);
+void vnodeCleanupRead(void);
+
+int32_t vnodeWriteToRQueue(void *pVnode, void *pCont, int32_t contLen, int8_t qtype, void *rparam);
+void vnodeFreeFromRQueue(void *pVnode, SVReadMsg *pRead);
+int32_t vnodeProcessRead(void *pVnode, SVReadMsg *pRead);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/vnode/inc/vnodeStatus.h b/src/vnode/inc/vnodeStatus.h
new file mode 100644
index 0000000000..00ac47df65
--- /dev/null
+++ b/src/vnode/inc/vnodeStatus.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_STATUS_H
+#define TDENGINE_VNODE_STATUS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "vnodeInt.h"
+
+typedef enum _VN_STATUS {
+ TAOS_VN_STATUS_INIT = 0,
+ TAOS_VN_STATUS_READY = 1,
+ TAOS_VN_STATUS_CLOSING = 2,
+ TAOS_VN_STATUS_UPDATING = 3,
+ TAOS_VN_STATUS_RESET = 4,
+} EVnodeStatus;
+
+bool vnodeSetInitStatus(SVnodeObj* pVnode);
+bool vnodeSetReadyStatus(SVnodeObj* pVnode);
+bool vnodeSetClosingStatus(SVnodeObj* pVnode);
+bool vnodeSetUpdatingStatus(SVnodeObj* pVnode);
+bool vnodeSetResetStatus(SVnodeObj* pVnode);
+
+bool vnodeInInitStatus(SVnodeObj* pVnode);
+bool vnodeInReadyStatus(SVnodeObj* pVnode);
+bool vnodeInClosingStatus(SVnodeObj* pVnode);
+bool vnodeInResetStatus(SVnodeObj* pVnode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/vnode/inc/vnodeSync.h b/src/vnode/inc/vnodeSync.h
new file mode 100644
index 0000000000..ae02ca17cb
--- /dev/null
+++ b/src/vnode/inc/vnodeSync.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_SYNC_H
+#define TDENGINE_VNODE_SYNC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "vnodeInt.h"
+
+uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fver);
+int32_t vnodeGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId);
+void vnodeNotifyRole(int32_t vgId, int8_t role);
+void vnodeCtrlFlow(int32_t vgId, int32_t level);
+int32_t vnodeNotifyFileSynced(int32_t vgId, uint64_t fversion);
+void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code);
+int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam);
+int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver);
+
+void vnodeConfirmForward(void *pVnode, uint64_t version, int32_t code);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/vnode/inc/vnodeVersion.h b/src/vnode/inc/vnodeVersion.h
index 1d086cb21f..913e3915ab 100644
--- a/src/vnode/inc/vnodeVersion.h
+++ b/src/vnode/inc/vnodeVersion.h
@@ -19,6 +19,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#include "vnodeInt.h"
int32_t vnodeReadVersion(SVnodeObj *pVnode);
int32_t vnodeSaveVersion(SVnodeObj *pVnode);
diff --git a/src/vnode/inc/vnodeWorker.h b/src/vnode/inc/vnodeWorker.h
new file mode 100644
index 0000000000..01d9d42900
--- /dev/null
+++ b/src/vnode/inc/vnodeWorker.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_WORKER_H
+#define TDENGINE_VNODE_WORKER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "vnodeInt.h"
+
+int32_t vnodeInitMWorker();
+void vnodeCleanupMWorker();
+int32_t vnodeCleanupInMWorker(SVnodeObj *pVnode);
+int32_t vnodeDestroyInMWorker(SVnodeObj *pVnode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/vnode/inc/vnodeWrite.h b/src/vnode/inc/vnodeWrite.h
new file mode 100644
index 0000000000..8b3f0fdb58
--- /dev/null
+++ b/src/vnode/inc/vnodeWrite.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_WRITE_H
+#define TDENGINE_VNODE_WRITE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "vnodeInt.h"
+
+int32_t vnodeInitWrite(void);
+void vnodeCleanupWrite(void);
+
+int32_t vnodeWriteToWQueue(void *pVnode, void *pHead, int32_t qtype, void *pRpcMsg);
+void vnodeFreeFromWQueue(void *pVnode, SVWriteMsg *pWrite);
+int32_t vnodeProcessWrite(void *pVnode, void *pHead, int32_t qtype, void *pRspRet);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/vnode/src/vnodeCfg.c b/src/vnode/src/vnodeCfg.c
index 2d56157328..e0881db000 100644
--- a/src/vnode/src/vnodeCfg.c
+++ b/src/vnode/src/vnodeCfg.c
@@ -15,13 +15,9 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taosmsg.h"
-#include "taoserror.h"
#include "cJSON.h"
#include "tglobal.h"
-#include "tsdb.h"
#include "dnode.h"
-#include "vnodeInt.h"
#include "vnodeCfg.h"
static void vnodeLoadCfg(SVnodeObj *pVnode, SCreateVnodeMsg* vnodeMsg) {
@@ -242,9 +238,8 @@ int32_t vnodeReadCfg(SVnodeObj *pVnode) {
}
tstrncpy(node->nodeEp, nodeEp->valuestring, TSDB_EP_LEN);
- if (!nodeChanged) {
- nodeChanged = dnodeCheckEpChanged(node->nodeId, node->nodeEp);
- }
+ bool changed = dnodeCheckEpChanged(node->nodeId, node->nodeEp);
+ if (changed) nodeChanged = changed;
}
ret = TSDB_CODE_SUCCESS;
diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c
index b516c9d90e..e286a972dc 100644
--- a/src/vnode/src/vnodeMain.c
+++ b/src/vnode/src/vnodeMain.c
@@ -18,77 +18,18 @@
#include "taoserror.h"
#include "taosmsg.h"
#include "tglobal.h"
-#include "trpc.h"
-#include "tsdb.h"
-#include "tutil.h"
-#include "vnode.h"
-#include "vnodeInt.h"
+// #include "tfs.h"
#include "query.h"
#include "dnode.h"
#include "vnodeCfg.h"
+#include "vnodeStatus.h"
+#include "vnodeSync.h"
#include "vnodeVersion.h"
+#include "vnodeMgmt.h"
+#include "vnodeWorker.h"
+#include "vnodeMain.h"
-static SHashObj*tsVnodesHash;
-static void vnodeCleanUp(SVnodeObj *pVnode);
-static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno);
-static uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion);
-static int32_t vnodeGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId);
-static void vnodeNotifyRole(int32_t vgId, int8_t role);
-static void vnodeCtrlFlow(int32_t vgId, int32_t level);
-static int32_t vnodeNotifyFileSynced(int32_t vgId, uint64_t fversion);
-static void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code);
-static int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam);
-static int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver);
-
-#ifndef _SYNC
-int64_t syncStart(const SSyncInfo *info) { return NULL; }
-int32_t syncForwardToPeer(int64_t rid, void *pHead, void *mhandle, int32_t qtype) { return 0; }
-void syncStop(int64_t rid) {}
-int32_t syncReconfig(int64_t rid, const SSyncCfg *cfg) { return 0; }
-int32_t syncGetNodesRole(int64_t rid, SNodesRole *cfg) { return 0; }
-void syncConfirmForward(int64_t rid, uint64_t version, int32_t code) {}
-#endif
-
-char* vnodeStatus[] = {
- "init",
- "ready",
- "closing",
- "updating",
- "reset"
-};
-
-int32_t vnodeInitResources() {
- int32_t code = syncInit();
- if (code != 0) return code;
-
- vnodeInitWriteFp();
- vnodeInitReadFp();
-
- tsVnodesHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
- if (tsVnodesHash == NULL) {
- vError("failed to init vnode list");
- return TSDB_CODE_VND_OUT_OF_MEMORY;
- }
-
- if (tsdbInitCommitQueue(tsNumOfCommitThreads) < 0) {
- vError("failed to init vnode commit queue");
- return terrno;
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-void vnodeCleanupResources() {
- tsdbDestroyCommitQueue();
-
- if (tsVnodesHash != NULL) {
- vDebug("vnode list is cleanup");
- taosHashCleanup(tsVnodesHash);
- tsVnodesHash = NULL;
- }
-
- syncCleanUp();
-}
+static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno);
int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
int32_t code;
@@ -155,7 +96,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
vInfo("vgId:%d, vnode dir is created, walLevel:%d fsyncPeriod:%d", pVnodeCfg->cfg.vgId, pVnodeCfg->cfg.walLevel,
pVnodeCfg->cfg.fsyncPeriod);
- code = vnodeOpen(pVnodeCfg->cfg.vgId, rootDir);
+ code = vnodeOpen(pVnodeCfg->cfg.vgId);
return code;
}
@@ -170,79 +111,89 @@ int32_t vnodeDrop(int32_t vgId) {
vInfo("vgId:%d, vnode will be dropped, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
pVnode->dropped = 1;
+ // remove from hash, so new messages wont be consumed
+ vnodeRemoveFromHash(pVnode);
vnodeRelease(pVnode);
- vnodeCleanUp(pVnode);
+ vnodeCleanupInMWorker(pVnode);
return TSDB_CODE_SUCCESS;
}
+static int32_t vnodeAlterImp(SVnodeObj *pVnode, SCreateVnodeMsg *pVnodeCfg) {
+ int32_t code = vnodeWriteCfg(pVnodeCfg);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ code = vnodeReadCfg(pVnode);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ code = walAlter(pVnode->wal, &pVnode->walCfg);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ code = syncReconfig(pVnode->sync, &pVnode->syncCfg);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
+ if (pVnode->tsdb) {
+ code = tsdbConfigRepo(pVnode->tsdb, &pVnode->tsdbCfg);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+ }
+
+ return 0;
+}
+
int32_t vnodeAlter(void *vparam, SCreateVnodeMsg *pVnodeCfg) {
SVnodeObj *pVnode = vparam;
// vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS
// cfgVersion can be corrected by status msg
- if (atomic_val_compare_exchange_8(&pVnode->status, TAOS_VN_STATUS_READY, TAOS_VN_STATUS_UPDATING) != TAOS_VN_STATUS_READY) {
+ if (!vnodeSetUpdatingStatus(pVnode)) {
vDebug("vgId:%d, vnode is not ready, do alter operation later", pVnode->vgId);
return TSDB_CODE_SUCCESS;
}
- int32_t code = vnodeWriteCfg(pVnodeCfg);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->status = TAOS_VN_STATUS_READY;
- return code;
+ int32_t code = vnodeAlterImp(pVnode, pVnodeCfg);
+ vnodeSetReadyStatus(pVnode);
+
+ if (code != 0) {
+ vError("vgId:%d, failed to alter vnode, code:0x%x", pVnode->vgId, code);
+ } else {
+ vDebug("vgId:%d, vnode is altered", pVnode->vgId);
}
- code = vnodeReadCfg(pVnode);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->status = TAOS_VN_STATUS_READY;
- return code;
- }
-
- code = walAlter(pVnode->wal, &pVnode->walCfg);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->status = TAOS_VN_STATUS_READY;
- return code;
- }
-
- code = syncReconfig(pVnode->sync, &pVnode->syncCfg);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->status = TAOS_VN_STATUS_READY;
- return code;
- }
-
- if (pVnode->tsdb) {
- code = tsdbConfigRepo(pVnode->tsdb, &pVnode->tsdbCfg);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->status = TAOS_VN_STATUS_READY;
- return code;
- }
- }
-
- pVnode->status = TAOS_VN_STATUS_READY;
- vDebug("vgId:%d, vnode is altered", pVnode->vgId);
-
- return TSDB_CODE_SUCCESS;
+ return code;
}
-int32_t vnodeOpen(int32_t vnode, char *rootDir) {
- char temp[TSDB_FILENAME_LEN];
+int32_t vnodeOpen(int32_t vgId) {
+ char temp[TSDB_FILENAME_LEN * 3];
+ char rootDir[TSDB_FILENAME_LEN * 2];
+ snprintf(rootDir, TSDB_FILENAME_LEN * 2, "%s/vnode%d", tsVnodeDir, vgId);
SVnodeObj *pVnode = calloc(sizeof(SVnodeObj), 1);
if (pVnode == NULL) {
- vError("vgId:%d, failed to open vnode since no enough memory", vnode);
+ vError("vgId:%d, failed to open vnode since no enough memory", vgId);
return TAOS_SYSTEM_ERROR(errno);
}
atomic_add_fetch_32(&pVnode->refCount, 1);
- pVnode->vgId = vnode;
- pVnode->status = TAOS_VN_STATUS_INIT;
+ pVnode->vgId = vgId;
pVnode->fversion = 0;
pVnode->version = 0;
pVnode->tsdbCfg.tsdbId = pVnode->vgId;
pVnode->rootDir = strdup(rootDir);
pVnode->accessState = TSDB_VN_ALL_ACCCESS;
tsem_init(&pVnode->sem, 0, 0);
+ pthread_mutex_init(&pVnode->statusMutex, NULL);
+ vnodeSetInitStatus(pVnode);
int32_t code = vnodeReadCfg(pVnode);
if (code != TSDB_CODE_SUCCESS) {
@@ -272,7 +223,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
sprintf(cqCfg.user, "_root");
strcpy(cqCfg.pass, tsInternalPass);
strcpy(cqCfg.db, pVnode->db);
- cqCfg.vgId = vnode;
+ cqCfg.vgId = vgId;
cqCfg.cqWrite = vnodeWriteToCache;
pVnode->cq = cqOpen(pVnode, &cqCfg);
if (pVnode->cq == NULL) {
@@ -341,13 +292,13 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
vDebug("vgId:%d, vnode is opened in %s, pVnode:%p", pVnode->vgId, rootDir, pVnode);
tsdbIncCommitRef(pVnode->vgId);
- taosHashPut(tsVnodesHash, &pVnode->vgId, sizeof(int32_t), &pVnode, sizeof(SVnodeObj *));
+ vnodeAddIntoHash(pVnode);
SSyncInfo syncInfo;
syncInfo.vgId = pVnode->vgId;
syncInfo.version = pVnode->version;
syncInfo.syncCfg = pVnode->syncCfg;
- sprintf(syncInfo.path, "%s", rootDir);
+ tstrncpy(syncInfo.path, rootDir, TSDB_FILENAME_LEN);
syncInfo.getWalInfo = vnodeGetWalInfo;
syncInfo.getFileInfo = vnodeGetFileInfo;
syncInfo.writeToCache = vnodeWriteToCache;
@@ -358,19 +309,15 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
syncInfo.getVersion = vnodeGetVersion;
pVnode->sync = syncStart(&syncInfo);
-#ifndef _SYNC
- pVnode->role = TAOS_SYNC_ROLE_MASTER;
-#else
if (pVnode->sync <= 0) {
- vError("vgId:%d, failed to open sync module, replica:%d reason:%s", pVnode->vgId, pVnode->syncCfg.replica,
+ vError("vgId:%d, failed to open sync, replica:%d reason:%s", pVnode->vgId, pVnode->syncCfg.replica,
tstrerror(terrno));
- vnodeRelease(pVnode);
+ vnodeRemoveFromHash(pVnode);
vnodeCleanUp(pVnode);
return terrno;
}
-#endif
- pVnode->status = TAOS_VN_STATUS_READY;
+ vnodeSetReadyStatus(pVnode);
return TSDB_CODE_SUCCESS;
}
@@ -379,30 +326,16 @@ int32_t vnodeClose(int32_t vgId) {
if (pVnode == NULL) return 0;
vDebug("vgId:%d, vnode will be closed, pVnode:%p", pVnode->vgId, pVnode);
+ vnodeRemoveFromHash(pVnode);
vnodeRelease(pVnode);
vnodeCleanUp(pVnode);
return 0;
}
-void vnodeRelease(void *vparam) {
- if (vparam == NULL) return;
- SVnodeObj *pVnode = vparam;
- int32_t code = 0;
- int32_t vgId = pVnode->vgId;
-
- int32_t refCount = atomic_sub_fetch_32(&pVnode->refCount, 1);
- vTrace("vgId:%d, release vnode, refCount:%d pVnode:%p", vgId, refCount, pVnode);
- assert(refCount >= 0);
-
- if (refCount > 0) {
- if (pVnode->status == TAOS_VN_STATUS_RESET && refCount <= 3) {
- tsem_post(&pVnode->sem);
- }
- return;
- }
-
- vDebug("vgId:%d, vnode will be destroyed, refCount:%d pVnode:%p", vgId, refCount, pVnode);
+void vnodeDestroy(SVnodeObj *pVnode) {
+ int32_t code = 0;
+ int32_t vgId = pVnode->vgId;
if (pVnode->qMgmt) {
qCleanupQueryMgmt(pVnode->qMgmt);
@@ -465,121 +398,16 @@ void vnodeRelease(void *vparam) {
}
tsem_destroy(&pVnode->sem);
+ pthread_mutex_destroy(&pVnode->statusMutex);
free(pVnode);
tsdbDecCommitRef(vgId);
-
- int32_t count = taosHashGetSize(tsVnodesHash);
- vDebug("vgId:%d, vnode is destroyed, vnodes:%d", vgId, count);
}
-static void vnodeIncRef(void *ptNode) {
- assert(ptNode != NULL);
-
- SVnodeObj **ppVnode = (SVnodeObj **)ptNode;
- assert(ppVnode);
- assert(*ppVnode);
-
- SVnodeObj *pVnode = *ppVnode;
- atomic_add_fetch_32(&pVnode->refCount, 1);
- vTrace("vgId:%d, get vnode, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
-}
-
-void *vnodeAcquire(int32_t vgId) {
- SVnodeObj **ppVnode = taosHashGetCB(tsVnodesHash, &vgId, sizeof(int32_t), vnodeIncRef, NULL, sizeof(void *));
-
- if (ppVnode == NULL || *ppVnode == NULL) {
- terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
- vDebug("vgId:%d, not exist", vgId);
- return NULL;
- }
-
- return *ppVnode;
-}
-
-void *vnodeGetWal(void *pVnode) {
- return ((SVnodeObj *)pVnode)->wal;
-}
-
-static void vnodeBuildVloadMsg(SVnodeObj *pVnode, SStatusMsg *pStatus) {
- int64_t totalStorage = 0;
- int64_t compStorage = 0;
- int64_t pointsWritten = 0;
-
- if (pVnode->status != TAOS_VN_STATUS_READY) return;
- if (pStatus->openVnodes >= TSDB_MAX_VNODES) return;
-
- if (pVnode->tsdb) {
- tsdbReportStat(pVnode->tsdb, &pointsWritten, &totalStorage, &compStorage);
- }
-
- SVnodeLoad *pLoad = &pStatus->load[pStatus->openVnodes++];
- pLoad->vgId = htonl(pVnode->vgId);
- pLoad->cfgVersion = htonl(pVnode->cfgVersion);
- pLoad->totalStorage = htobe64(totalStorage);
- pLoad->compStorage = htobe64(compStorage);
- pLoad->pointsWritten = htobe64(pointsWritten);
- pLoad->status = pVnode->status;
- pLoad->role = pVnode->role;
- pLoad->replica = pVnode->syncCfg.replica;
-}
-
-int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
- void *pIter = taosHashIterate(tsVnodesHash, NULL);
- while (pIter) {
- SVnodeObj **pVnode = pIter;
- if (*pVnode) {
-
- (*numOfVnodes)++;
- if (*numOfVnodes >= TSDB_MAX_VNODES) {
- vError("vgId:%d, too many open vnodes, exist:%d max:%d", (*pVnode)->vgId, *numOfVnodes, TSDB_MAX_VNODES);
- continue;
- } else {
- vnodeList[*numOfVnodes - 1] = (*pVnode)->vgId;
- }
-
- }
-
- pIter = taosHashIterate(tsVnodesHash, pIter);
- }
- return TSDB_CODE_SUCCESS;
-}
-
-void vnodeBuildStatusMsg(void *param) {
- SStatusMsg *pStatus = param;
-
- void *pIter = taosHashIterate(tsVnodesHash, NULL);
- while (pIter) {
- SVnodeObj **pVnode = pIter;
- if (*pVnode) {
- vnodeBuildVloadMsg(*pVnode, pStatus);
- }
- pIter = taosHashIterate(tsVnodesHash, pIter);
- }
-}
-
-void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes) {
- for (int32_t i = 0; i < numOfVnodes; ++i) {
- pAccess[i].vgId = htonl(pAccess[i].vgId);
- SVnodeObj *pVnode = vnodeAcquire(pAccess[i].vgId);
- if (pVnode != NULL) {
- pVnode->accessState = pAccess[i].accessState;
- if (pVnode->accessState != TSDB_VN_ALL_ACCCESS) {
- vDebug("vgId:%d, access state is set to %d", pAccess[i].vgId, pVnode->accessState);
- }
- vnodeRelease(pVnode);
- }
- }
-}
-
-static void vnodeCleanUp(SVnodeObj *pVnode) {
- // remove from hash, so new messages wont be consumed
- taosHashRemove(tsVnodesHash, &pVnode->vgId, sizeof(int32_t));
-
- if (pVnode->status != TAOS_VN_STATUS_INIT) {
+void vnodeCleanUp(SVnodeObj *pVnode) {
+ if (!vnodeInInitStatus(pVnode)) {
// it may be in updateing or reset state, then it shall wait
int32_t i = 0;
- while (atomic_val_compare_exchange_8(&pVnode->status, TAOS_VN_STATUS_READY, TAOS_VN_STATUS_CLOSING) !=
- TAOS_VN_STATUS_READY) {
+ while (!vnodeSetClosingStatus(pVnode)) {
if (++i % 1000 == 0) {
sched_yield();
}
@@ -615,7 +443,7 @@ static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno) {
pVnode->isCommiting = 1;
pVnode->fversion = pVnode->version;
vDebug("vgId:%d, start commit, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, pVnode->version);
- if (pVnode->status != TAOS_VN_STATUS_INIT) {
+ if (!vnodeInInitStatus(pVnode)) {
return walRenew(pVnode->wal);
}
return 0;
@@ -625,7 +453,7 @@ static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno) {
vDebug("vgId:%d, commit over, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, pVnode->version);
pVnode->isCommiting = 0;
pVnode->isFull = 0;
- if (pVnode->status != TAOS_VN_STATUS_INIT) {
+ if (!vnodeInInitStatus(pVnode)) {
walRemoveOneOldFile(pVnode->wal);
}
return vnodeSaveVersion(pVnode);
@@ -634,75 +462,12 @@ static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno) {
return 0;
}
-static uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size,
- uint64_t *fversion) {
- SVnodeObj *pVnode = vnodeAcquire(vgId);
- if (pVnode == NULL) {
- vError("vgId:%d, vnode not found while get file info", vgId);
- return 0;
- }
-
- *fversion = pVnode->fversion;
- uint32_t ret = tsdbGetFileInfo(pVnode->tsdb, name, index, eindex, size);
-
- vnodeRelease(pVnode);
- return ret;
-}
-
-static int32_t vnodeGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId) {
- SVnodeObj *pVnode = vnodeAcquire(vgId);
- if (pVnode == NULL) {
- vError("vgId:%d, vnode not found while get wal info", vgId);
- return -1;
- }
-
- int32_t code = walGetWalFile(pVnode->wal, fileName, fileId);
-
- vnodeRelease(pVnode);
- return code;
-}
-
-static void vnodeNotifyRole(int32_t vgId, int8_t role) {
- SVnodeObj *pVnode = vnodeAcquire(vgId);
- if (pVnode == NULL) {
- vTrace("vgId:%d, vnode not found while notify role", vgId);
- return;
- }
-
- vInfo("vgId:%d, sync role changed from %s to %s", pVnode->vgId, syncRole[pVnode->role], syncRole[role]);
- pVnode->role = role;
- dnodeSendStatusMsgToMnode();
-
- if (pVnode->role == TAOS_SYNC_ROLE_MASTER) {
- cqStart(pVnode->cq);
- } else {
- cqStop(pVnode->cq);
- }
-
- vnodeRelease(pVnode);
-}
-
-static void vnodeCtrlFlow(int32_t vgId, int32_t level) {
- SVnodeObj *pVnode = vnodeAcquire(vgId);
- if (pVnode == NULL) {
- vTrace("vgId:%d, vnode not found while flow ctrl", vgId);
- return;
- }
-
- if (pVnode->flowctrlLevel != level) {
- vDebug("vgId:%d, set flowctrl level from %d to %d", pVnode->vgId, pVnode->flowctrlLevel, level);
- pVnode->flowctrlLevel = level;
- }
-
- vnodeRelease(pVnode);
-}
-
-static int32_t vnodeResetTsdb(SVnodeObj *pVnode) {
+int32_t vnodeReset(SVnodeObj *pVnode) {
char rootDir[128] = "\0";
sprintf(rootDir, "%s/tsdb", pVnode->rootDir);
- if (pVnode->status != TAOS_VN_STATUS_CLOSING && pVnode->status != TAOS_VN_STATUS_INIT) {
- pVnode->status = TAOS_VN_STATUS_RESET;
+ if (!vnodeSetResetStatus(pVnode)) {
+ return -1;
}
void *tsdb = pVnode->tsdb;
@@ -725,70 +490,8 @@ static int32_t vnodeResetTsdb(SVnodeObj *pVnode) {
appH.cqDropFunc = cqDrop;
pVnode->tsdb = tsdbOpenRepo(rootDir, &appH);
- pVnode->status = TAOS_VN_STATUS_READY;
+ vnodeSetReadyStatus(pVnode);
vnodeRelease(pVnode);
return 0;
}
-
-static int32_t vnodeNotifyFileSynced(int32_t vgId, uint64_t fversion) {
- SVnodeObj *pVnode = vnodeAcquire(vgId);
- if (pVnode == NULL) {
- vError("vgId:%d, vnode not found while notify file synced", vgId);
- return 0;
- }
-
- pVnode->fversion = fversion;
- pVnode->version = fversion;
- vnodeSaveVersion(pVnode);
-
- vDebug("vgId:%d, data file is synced, fver:%" PRIu64 " vver:%" PRIu64, vgId, fversion, fversion);
- int32_t code = vnodeResetTsdb(pVnode);
-
- vnodeRelease(pVnode);
- return code;
-}
-
-void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code) {
- void *pVnode = vnodeAcquire(vgId);
- if (pVnode == NULL) {
- vError("vgId:%d, vnode not found while confirm forward", vgId);
- return;
- }
-
- dnodeSendRpcVWriteRsp(pVnode, wparam, code);
- vnodeRelease(pVnode);
-}
-
-static int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam) {
- SVnodeObj *pVnode = vnodeAcquire(vgId);
- if (pVnode == NULL) {
- vError("vgId:%d, vnode not found while write to cache", vgId);
- return TSDB_CODE_VND_INVALID_VGROUP_ID;
- }
-
- int32_t code = vnodeWriteToWQueue(pVnode, wparam, qtype, rparam);
-
- vnodeRelease(pVnode);
- return code;
-}
-
-static int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver) {
- SVnodeObj *pVnode = vnodeAcquire(vgId);
- if (pVnode == NULL) {
- vError("vgId:%d, vnode not found while write to cache", vgId);
- return -1;
- }
-
- int32_t code = 0;
- if (pVnode->isCommiting) {
- vDebug("vgId:%d, vnode is commiting while get version", vgId);
- code = -1;
- } else {
- *fver = pVnode->fversion;
- *wver = pVnode->version;
- }
-
- vnodeRelease(pVnode);
- return code;
-}
diff --git a/src/vnode/src/vnodeMgmt.c b/src/vnode/src/vnodeMgmt.c
new file mode 100644
index 0000000000..cf42690d7d
--- /dev/null
+++ b/src/vnode/src/vnodeMgmt.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "dnode.h"
+#include "vnodeStatus.h"
+#include "vnodeWorker.h"
+#include "vnodeRead.h"
+#include "vnodeWrite.h"
+#include "vnodeMain.h"
+
+static SHashObj *tsVnodesHash = NULL;
+
+static int32_t vnodeInitHash(void);
+static void vnodeCleanupHash(void);
+static void vnodeIncRef(void *ptNode);
+
+static SStep tsVnodeSteps[] = {
+ {"vnode-worker", vnodeInitMWorker, vnodeCleanupMWorker},
+ {"vnode-write", vnodeInitWrite, vnodeCleanupWrite},
+ {"vnode-read", vnodeInitRead, vnodeCleanupRead},
+ {"vnode-hash", vnodeInitHash, vnodeCleanupHash},
+ {"tsdb-queue", tsdbInitCommitQueue, tsdbDestroyCommitQueue}
+};
+
+int32_t vnodeInitMgmt() {
+ int32_t stepSize = sizeof(tsVnodeSteps) / sizeof(SStep);
+ return dnodeStepInit(tsVnodeSteps, stepSize);
+}
+
+void vnodeCleanupMgmt() {
+ int32_t stepSize = sizeof(tsVnodeSteps) / sizeof(SStep);
+ dnodeStepCleanup(tsVnodeSteps, stepSize);
+}
+
+static int32_t vnodeInitHash() {
+ tsVnodesHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
+ if (tsVnodesHash == NULL) {
+ vError("failed to init vnode mgmt");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void vnodeCleanupHash() {
+ if (tsVnodesHash != NULL) {
+ vDebug("vnode mgmt is cleanup");
+ taosHashCleanup(tsVnodesHash);
+ tsVnodesHash = NULL;
+ }
+}
+
+void *vnodeGetWal(void *pVnode) {
+ return ((SVnodeObj *)pVnode)->wal;
+}
+
+void vnodeAddIntoHash(SVnodeObj *pVnode) {
+ taosHashPut(tsVnodesHash, &pVnode->vgId, sizeof(int32_t), &pVnode, sizeof(SVnodeObj *));
+}
+
+void vnodeRemoveFromHash(SVnodeObj *pVnode) {
+ taosHashRemove(tsVnodesHash, &pVnode->vgId, sizeof(int32_t));
+}
+
+static void vnodeIncRef(void *ptNode) {
+ assert(ptNode != NULL);
+
+ SVnodeObj **ppVnode = (SVnodeObj **)ptNode;
+ assert(ppVnode);
+ assert(*ppVnode);
+
+ SVnodeObj *pVnode = *ppVnode;
+ atomic_add_fetch_32(&pVnode->refCount, 1);
+ vTrace("vgId:%d, get vnode, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
+}
+
+void *vnodeAcquire(int32_t vgId) {
+ SVnodeObj **ppVnode = taosHashGetCB(tsVnodesHash, &vgId, sizeof(int32_t), vnodeIncRef, NULL, sizeof(void *));
+
+ if (ppVnode == NULL || *ppVnode == NULL) {
+ terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
+ vDebug("vgId:%d, not exist", vgId);
+ return NULL;
+ }
+
+ return *ppVnode;
+}
+
+void vnodeRelease(void *vparam) {
+ SVnodeObj *pVnode = vparam;
+ if (vparam == NULL) return;
+
+ int32_t refCount = atomic_sub_fetch_32(&pVnode->refCount, 1);
+ vTrace("vgId:%d, release vnode, refCount:%d pVnode:%p", pVnode->vgId, refCount, pVnode);
+ assert(refCount >= 0);
+
+ if (refCount > 0) {
+ if (vnodeInResetStatus(pVnode) && refCount <= 3) {
+ tsem_post(&pVnode->sem);
+ }
+ } else {
+ vDebug("vgId:%d, vnode will be destroyed, refCount:%d pVnode:%p", pVnode->vgId, refCount, pVnode);
+ vnodeDestroyInMWorker(pVnode);
+ int32_t count = taosHashGetSize(tsVnodesHash);
+ vDebug("vgId:%d, vnode is destroyed, vnodes:%d", pVnode->vgId, count);
+ }
+}
+
+static void vnodeBuildVloadMsg(SVnodeObj *pVnode, SStatusMsg *pStatus) {
+ int64_t totalStorage = 0;
+ int64_t compStorage = 0;
+ int64_t pointsWritten = 0;
+
+ if (!vnodeInReadyStatus(pVnode)) return;
+ if (pStatus->openVnodes >= TSDB_MAX_VNODES) return;
+
+ if (pVnode->tsdb) {
+ tsdbReportStat(pVnode->tsdb, &pointsWritten, &totalStorage, &compStorage);
+ }
+
+ SVnodeLoad *pLoad = &pStatus->load[pStatus->openVnodes++];
+ pLoad->vgId = htonl(pVnode->vgId);
+ pLoad->cfgVersion = htonl(pVnode->cfgVersion);
+ pLoad->totalStorage = htobe64(totalStorage);
+ pLoad->compStorage = htobe64(compStorage);
+ pLoad->pointsWritten = htobe64(pointsWritten);
+ pLoad->status = pVnode->status;
+ pLoad->role = pVnode->role;
+ pLoad->replica = pVnode->syncCfg.replica;
+}
+
+int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
+ void *pIter = taosHashIterate(tsVnodesHash, NULL);
+ while (pIter) {
+ SVnodeObj **pVnode = pIter;
+ if (*pVnode) {
+
+ (*numOfVnodes)++;
+ if (*numOfVnodes >= TSDB_MAX_VNODES) {
+ vError("vgId:%d, too many open vnodes, exist:%d max:%d", (*pVnode)->vgId, *numOfVnodes, TSDB_MAX_VNODES);
+ continue;
+ } else {
+ vnodeList[*numOfVnodes - 1] = (*pVnode)->vgId;
+ }
+
+ }
+
+ pIter = taosHashIterate(tsVnodesHash, pIter);
+ }
+ return TSDB_CODE_SUCCESS;
+}
+
+void vnodeBuildStatusMsg(void *param) {
+ SStatusMsg *pStatus = param;
+
+ void *pIter = taosHashIterate(tsVnodesHash, NULL);
+ while (pIter) {
+ SVnodeObj **pVnode = pIter;
+ if (*pVnode) {
+ vnodeBuildVloadMsg(*pVnode, pStatus);
+ }
+ pIter = taosHashIterate(tsVnodesHash, pIter);
+ }
+}
+
+void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes) {
+ for (int32_t i = 0; i < numOfVnodes; ++i) {
+ pAccess[i].vgId = htonl(pAccess[i].vgId);
+ SVnodeObj *pVnode = vnodeAcquire(pAccess[i].vgId);
+ if (pVnode != NULL) {
+ pVnode->accessState = pAccess[i].accessState;
+ if (pVnode->accessState != TSDB_VN_ALL_ACCCESS) {
+ vDebug("vgId:%d, access state is set to %d", pAccess[i].vgId, pVnode->accessState);
+ }
+ vnodeRelease(pVnode);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c
index ed6d29505f..34921a93b3 100644
--- a/src/vnode/src/vnodeRead.c
+++ b/src/vnode/src/vnodeRead.c
@@ -16,26 +16,26 @@
#define _DEFAULT_SOURCE
#define _NON_BLOCKING_RETRIEVE 0
#include "os.h"
-#include "tglobal.h"
-#include "taoserror.h"
#include "taosmsg.h"
-#include "query.h"
-#include "trpc.h"
-#include "tsdb.h"
-#include "vnode.h"
-#include "vnodeInt.h"
#include "tqueue.h"
+#include "tglobal.h"
+#include "query.h"
+#include "vnodeStatus.h"
static int32_t (*vnodeProcessReadMsgFp[TSDB_MSG_TYPE_MAX])(SVnodeObj *pVnode, SVReadMsg *pRead);
static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead);
static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead);
static int32_t vnodeNotifyCurrentQhandle(void* handle, void* qhandle, int32_t vgId);
-void vnodeInitReadFp(void) {
+int32_t vnodeInitRead(void) {
vnodeProcessReadMsgFp[TSDB_MSG_TYPE_QUERY] = vnodeProcessQueryMsg;
vnodeProcessReadMsgFp[TSDB_MSG_TYPE_FETCH] = vnodeProcessFetchMsg;
+
+ return 0;
}
+void vnodeCleanupRead() {}
+
//
// After the fetch request enters the vnode queue, if the vnode cannot provide services, the process function are
// still required, or there will be a deadlock, so we don’t do any check here, but put the check codes before the
@@ -54,7 +54,7 @@ int32_t vnodeProcessRead(void *vparam, SVReadMsg *pRead) {
}
static int32_t vnodeCheckRead(SVnodeObj *pVnode) {
- if (pVnode->status != TAOS_VN_STATUS_READY) {
+ if (!vnodeInReadyStatus(pVnode)) {
vDebug("vgId:%d, vnode status is %s, refCount:%d pVnode:%p", pVnode->vgId, vnodeStatus[pVnode->status],
pVnode->refCount, pVnode);
return TSDB_CODE_APP_NOT_READY;
diff --git a/src/vnode/src/vnodeStatus.c b/src/vnode/src/vnodeStatus.c
new file mode 100644
index 0000000000..d09a6a8663
--- /dev/null
+++ b/src/vnode/src/vnodeStatus.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "vnodeStatus.h"
+
+char* vnodeStatus[] = {
+ "init",
+ "ready",
+ "closing",
+ "updating",
+ "reset"
+};
+
+bool vnodeSetInitStatus(SVnodeObj* pVnode) {
+ pthread_mutex_lock(&pVnode->statusMutex);
+ pVnode->status = TAOS_VN_STATUS_INIT;
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return true;
+}
+
+bool vnodeSetReadyStatus(SVnodeObj* pVnode) {
+ bool set = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_INIT || pVnode->status == TAOS_VN_STATUS_READY ||
+ pVnode->status == TAOS_VN_STATUS_UPDATING || pVnode->status == TAOS_VN_STATUS_RESET) {
+ pVnode->status = TAOS_VN_STATUS_READY;
+ set = true;
+ } else {
+ vDebug("vgId:%d, cannot set status:ready, old:%s", pVnode->vgId, vnodeStatus[pVnode->status]);
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return set;
+}
+
+bool vnodeSetClosingStatus(SVnodeObj* pVnode) {
+ bool set = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_READY) {
+ pVnode->status = TAOS_VN_STATUS_CLOSING;
+ set = true;
+ } else {
+ vTrace("vgId:%d, cannot set status:closing, old:%s", pVnode->vgId, vnodeStatus[pVnode->status]);
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return set;
+}
+
+bool vnodeSetUpdatingStatus(SVnodeObj* pVnode) {
+ bool set = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_READY) {
+ pVnode->status = TAOS_VN_STATUS_UPDATING;
+ set = true;
+ } else {
+ vDebug("vgId:%d, cannot set status:updating, old:%s", pVnode->vgId, vnodeStatus[pVnode->status]);
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return set;
+}
+
+bool vnodeSetResetStatus(SVnodeObj* pVnode) {
+ bool set = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status != TAOS_VN_STATUS_CLOSING && pVnode->status != TAOS_VN_STATUS_INIT) {
+ pVnode->status = TAOS_VN_STATUS_RESET;
+ set = true;
+ } else {
+ vDebug("vgId:%d, cannot set status:reset, old:%s", pVnode->vgId, vnodeStatus[pVnode->status]);
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return set;
+}
+
+bool vnodeInInitStatus(SVnodeObj* pVnode) {
+ bool in = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_INIT) {
+ in = true;
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return in;
+}
+
+bool vnodeInReadyStatus(SVnodeObj* pVnode) {
+ bool in = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_READY) {
+ in = true;
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return in;
+}
+
+bool vnodeInClosingStatus(SVnodeObj* pVnode) {
+ bool in = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_CLOSING) {
+ in = true;
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return in;
+}
+
+bool vnodeInResetStatus(SVnodeObj* pVnode) {
+ bool in = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_RESET) {
+ in = true;
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return in;
+}
diff --git a/src/vnode/src/vnodeSync.c b/src/vnode/src/vnodeSync.c
new file mode 100644
index 0000000000..c67132c41f
--- /dev/null
+++ b/src/vnode/src/vnodeSync.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "taosmsg.h"
+#include "query.h"
+#include "dnode.h"
+#include "vnodeVersion.h"
+#include "vnodeMain.h"
+
+uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fver) {
+ SVnodeObj *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ vError("vgId:%d, vnode not found while get file info", vgId);
+ return 0;
+ }
+
+ *fver = pVnode->fversion;
+ uint32_t ret = tsdbGetFileInfo(pVnode->tsdb, name, index, eindex, size);
+
+ vnodeRelease(pVnode);
+ return ret;
+}
+
+int32_t vnodeGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId) {
+ SVnodeObj *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ vError("vgId:%d, vnode not found while get wal info", vgId);
+ return -1;
+ }
+
+ int32_t code = walGetWalFile(pVnode->wal, fileName, fileId);
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+void vnodeNotifyRole(int32_t vgId, int8_t role) {
+ SVnodeObj *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ vTrace("vgId:%d, vnode not found while notify role", vgId);
+ return;
+ }
+
+ vInfo("vgId:%d, sync role changed from %s to %s", pVnode->vgId, syncRole[pVnode->role], syncRole[role]);
+ pVnode->role = role;
+ dnodeSendStatusMsgToMnode();
+
+ if (pVnode->role == TAOS_SYNC_ROLE_MASTER) {
+ cqStart(pVnode->cq);
+ } else {
+ cqStop(pVnode->cq);
+ }
+
+ vnodeRelease(pVnode);
+}
+
+void vnodeCtrlFlow(int32_t vgId, int32_t level) {
+ SVnodeObj *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ vTrace("vgId:%d, vnode not found while flow ctrl", vgId);
+ return;
+ }
+
+ if (pVnode->flowctrlLevel != level) {
+ vDebug("vgId:%d, set flowctrl level from %d to %d", pVnode->vgId, pVnode->flowctrlLevel, level);
+ pVnode->flowctrlLevel = level;
+ }
+
+ vnodeRelease(pVnode);
+}
+
+int32_t vnodeNotifyFileSynced(int32_t vgId, uint64_t fversion) {
+ SVnodeObj *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ vError("vgId:%d, vnode not found while notify file synced", vgId);
+ return 0;
+ }
+
+ pVnode->fversion = fversion;
+ pVnode->version = fversion;
+ vnodeSaveVersion(pVnode);
+
+ vDebug("vgId:%d, data file is synced, fver:%" PRIu64 " vver:%" PRIu64, vgId, fversion, fversion);
+ int32_t code = vnodeReset(pVnode);
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code) {
+ void *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ vError("vgId:%d, vnode not found while confirm forward", vgId);
+ return;
+ }
+
+ dnodeSendRpcVWriteRsp(pVnode, wparam, code);
+ vnodeRelease(pVnode);
+}
+
+int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam) {
+ SVnodeObj *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ vError("vgId:%d, vnode not found while write to cache", vgId);
+ return TSDB_CODE_VND_INVALID_VGROUP_ID;
+ }
+
+ int32_t code = vnodeWriteToWQueue(pVnode, wparam, qtype, rparam);
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver) {
+ SVnodeObj *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ vError("vgId:%d, vnode not found while write to cache", vgId);
+ return -1;
+ }
+
+ int32_t code = 0;
+ if (pVnode->isCommiting) {
+ vDebug("vgId:%d, vnode is commiting while get version", vgId);
+ code = -1;
+ } else {
+ *fver = pVnode->fversion;
+ *wver = pVnode->version;
+ }
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+void vnodeConfirmForward(void *vparam, uint64_t version, int32_t code) {
+ SVnodeObj *pVnode = vparam;
+ syncConfirmForward(pVnode->sync, version, code);
+}
diff --git a/src/vnode/src/vnodeVersion.c b/src/vnode/src/vnodeVersion.c
index 8f6360b4f9..fb3b3ebd9e 100644
--- a/src/vnode/src/vnodeVersion.c
+++ b/src/vnode/src/vnodeVersion.c
@@ -15,11 +15,8 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taoserror.h"
#include "cJSON.h"
#include "tglobal.h"
-#include "tsdb.h"
-#include "vnodeInt.h"
#include "vnodeVersion.h"
int32_t vnodeReadVersion(SVnodeObj *pVnode) {
diff --git a/src/vnode/src/vnodeWorker.c b/src/vnode/src/vnodeWorker.c
new file mode 100644
index 0000000000..d6053cf18e
--- /dev/null
+++ b/src/vnode/src/vnodeWorker.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "taoserror.h"
+#include "taosmsg.h"
+#include "tutil.h"
+#include "tqueue.h"
+#include "tglobal.h"
+#include "vnodeWorker.h"
+#include "vnodeMain.h"
+
+typedef enum {
+ VNODE_WORKER_ACTION_CLEANUP,
+ VNODE_WORKER_ACTION_DESTROUY
+} EVMWorkerAction;
+
+typedef struct {
+ int32_t vgId;
+ int32_t code;
+ void * rpcHandle;
+ SVnodeObj *pVnode;
+ EVMWorkerAction action;
+} SVMWorkerMsg;
+
+typedef struct {
+ pthread_t thread;
+ int32_t workerId;
+} SVMWorker;
+
+typedef struct {
+ int32_t curNum;
+ int32_t maxNum;
+ SVMWorker *worker;
+} SVMWorkerPool;
+
+static SVMWorkerPool tsVMWorkerPool;
+static taos_qset tsVMWorkerQset;
+static taos_queue tsVMWorkerQueue;
+
+static void *vnodeMWorkerFunc(void *param);
+
+static int32_t vnodeStartMWorker() {
+ tsVMWorkerQueue = taosOpenQueue();
+ if (tsVMWorkerQueue == NULL) return TSDB_CODE_DND_OUT_OF_MEMORY;
+
+ taosAddIntoQset(tsVMWorkerQset, tsVMWorkerQueue, NULL);
+
+ for (int32_t i = tsVMWorkerPool.curNum; i < tsVMWorkerPool.maxNum; ++i) {
+ SVMWorker *pWorker = tsVMWorkerPool.worker + i;
+ pWorker->workerId = i;
+
+ pthread_attr_t thAttr;
+ pthread_attr_init(&thAttr);
+ pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
+
+ if (pthread_create(&pWorker->thread, &thAttr, vnodeMWorkerFunc, pWorker) != 0) {
+ vError("failed to create thread to process vmworker queue, reason:%s", strerror(errno));
+ }
+
+ pthread_attr_destroy(&thAttr);
+
+ tsVMWorkerPool.curNum = i + 1;
+ vDebug("vmworker:%d is launched, total:%d", pWorker->workerId, tsVMWorkerPool.maxNum);
+ }
+
+ vDebug("vmworker queue:%p is allocated", tsVMWorkerQueue);
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t vnodeInitMWorker() {
+ tsVMWorkerQset = taosOpenQset();
+
+ tsVMWorkerPool.maxNum = 1;
+ tsVMWorkerPool.curNum = 0;
+ tsVMWorkerPool.worker = calloc(sizeof(SVMWorker), tsVMWorkerPool.maxNum);
+
+ if (tsVMWorkerPool.worker == NULL) return -1;
+ for (int32_t i = 0; i < tsVMWorkerPool.maxNum; ++i) {
+ SVMWorker *pWorker = tsVMWorkerPool.worker + i;
+ pWorker->workerId = i;
+ vDebug("vmworker:%d is created", i);
+ }
+
+ vDebug("vmworker is initialized, num:%d qset:%p", tsVMWorkerPool.maxNum, tsVMWorkerQset);
+
+ return vnodeStartMWorker();
+}
+
+static void vnodeStopMWorker() {
+ vDebug("vmworker queue:%p is freed", tsVMWorkerQueue);
+ taosCloseQueue(tsVMWorkerQueue);
+ tsVMWorkerQueue = NULL;
+}
+
+void vnodeCleanupMWorker() {
+ for (int32_t i = 0; i < tsVMWorkerPool.maxNum; ++i) {
+ SVMWorker *pWorker = tsVMWorkerPool.worker + i;
+ if (pWorker->thread) {
+ taosQsetThreadResume(tsVMWorkerQset);
+ }
+ vDebug("vmworker:%d is closed", i);
+ }
+
+ for (int32_t i = 0; i < tsVMWorkerPool.maxNum; ++i) {
+ SVMWorker *pWorker = tsVMWorkerPool.worker + i;
+ vDebug("vmworker:%d start to join", i);
+ if (pWorker->thread) {
+ pthread_join(pWorker->thread, NULL);
+ }
+ vDebug("vmworker:%d join success", i);
+ }
+
+ vDebug("vmworker is closed, qset:%p", tsVMWorkerQset);
+
+ taosCloseQset(tsVMWorkerQset);
+ tsVMWorkerQset = NULL;
+ tfree(tsVMWorkerPool.worker);
+
+ vnodeStopMWorker();
+}
+
+static int32_t vnodeWriteIntoMWorker(SVnodeObj *pVnode, EVMWorkerAction action, void *rpcHandle) {
+ SVMWorkerMsg *pMsg = taosAllocateQitem(sizeof(SVMWorkerMsg));
+ if (pMsg == NULL) return TSDB_CODE_VND_OUT_OF_MEMORY;
+
+ pMsg->vgId = pVnode->vgId;
+ pMsg->pVnode = pVnode;
+ pMsg->rpcHandle = rpcHandle;
+ pMsg->action = action;
+
+ int32_t code = taosWriteQitem(tsVMWorkerQueue, TAOS_QTYPE_RPC, pMsg);
+ if (code == 0) code = TSDB_CODE_DND_ACTION_IN_PROGRESS;
+
+ return code;
+}
+
+int32_t vnodeCleanupInMWorker(SVnodeObj *pVnode) {
+ vTrace("vgId:%d, will cleanup in vmworker", pVnode->vgId);
+ return vnodeWriteIntoMWorker(pVnode, VNODE_WORKER_ACTION_CLEANUP, NULL);
+}
+
+int32_t vnodeDestroyInMWorker(SVnodeObj *pVnode) {
+ vTrace("vgId:%d, will destroy in vmworker", pVnode->vgId);
+ return vnodeWriteIntoMWorker(pVnode, VNODE_WORKER_ACTION_DESTROUY, NULL);
+}
+
+static void vnodeFreeMWorkerMsg(SVMWorkerMsg *pMsg) {
+ vTrace("vgId:%d, disposed in vmworker", pMsg->vgId);
+ taosFreeQitem(pMsg);
+}
+
+static void vnodeSendVMWorkerRpcRsp(SVMWorkerMsg *pMsg) {
+ if (pMsg->rpcHandle != NULL) {
+ SRpcMsg rpcRsp = {.handle = pMsg->rpcHandle, .code = pMsg->code};
+ rpcSendResponse(&rpcRsp);
+ }
+
+ vnodeFreeMWorkerMsg(pMsg);
+}
+
+static void vnodeProcessMWorkerMsg(SVMWorkerMsg *pMsg) {
+ pMsg->code = 0;
+
+ switch (pMsg->action) {
+ case VNODE_WORKER_ACTION_CLEANUP:
+ vnodeCleanUp(pMsg->pVnode);
+ break;
+ case VNODE_WORKER_ACTION_DESTROUY:
+ vnodeDestroy(pMsg->pVnode);
+ break;
+ default:
+ break;
+ }
+}
+
+static void *vnodeMWorkerFunc(void *param) {
+ while (1) {
+ SVMWorkerMsg *pMsg = NULL;
+ if (taosReadQitemFromQset(tsVMWorkerQset, NULL, (void **)&pMsg, NULL) == 0) {
+ vDebug("qset:%p, vmworker got no message from qset, exiting", tsVMWorkerQset);
+ break;
+ }
+
+ vTrace("vgId:%d, action:%d will be processed in vmworker queue", pMsg->vgId, pMsg->action);
+ vnodeProcessMWorkerMsg(pMsg);
+ vnodeSendVMWorkerRpcRsp(pMsg);
+ }
+
+ return NULL;
+}
diff --git a/src/vnode/src/vnodeWrite.c b/src/vnode/src/vnodeWrite.c
index 268d1fb53b..a826a4903f 100644
--- a/src/vnode/src/vnodeWrite.c
+++ b/src/vnode/src/vnodeWrite.c
@@ -19,17 +19,9 @@
#include "taoserror.h"
#include "tglobal.h"
#include "tqueue.h"
-#include "trpc.h"
-#include "tsdb.h"
-#include "twal.h"
-#include "tsync.h"
#include "ttimer.h"
-#include "tdataformat.h"
-#include "vnode.h"
-#include "vnodeInt.h"
-#include "syncInt.h"
-#include "tcq.h"
#include "dnode.h"
+#include "vnodeStatus.h"
#define MAX_QUEUED_MSG_NUM 10000
@@ -43,15 +35,19 @@ static int32_t vnodeProcessDropStableMsg(SVnodeObj *pVnode, void *pCont, SRspRet
static int32_t vnodeProcessUpdateTagValMsg(SVnodeObj *pVnode, void *pCont, SRspRet *);
static int32_t vnodePerformFlowCtrl(SVWriteMsg *pWrite);
-void vnodeInitWriteFp(void) {
+int32_t vnodeInitWrite(void) {
vnodeProcessWriteMsgFp[TSDB_MSG_TYPE_SUBMIT] = vnodeProcessSubmitMsg;
vnodeProcessWriteMsgFp[TSDB_MSG_TYPE_MD_CREATE_TABLE] = vnodeProcessCreateTableMsg;
vnodeProcessWriteMsgFp[TSDB_MSG_TYPE_MD_DROP_TABLE] = vnodeProcessDropTableMsg;
vnodeProcessWriteMsgFp[TSDB_MSG_TYPE_MD_ALTER_TABLE] = vnodeProcessAlterTableMsg;
vnodeProcessWriteMsgFp[TSDB_MSG_TYPE_MD_DROP_STABLE] = vnodeProcessDropStableMsg;
vnodeProcessWriteMsgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = vnodeProcessUpdateTagValMsg;
+
+ return 0;
}
+void vnodeCleanupWrite() {}
+
int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rparam) {
int32_t code = 0;
SVnodeObj *pVnode = vparam;
@@ -68,7 +64,7 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara
taosMsg[pHead->msgType], qtypeStr[qtype], pHead->version, pVnode->version);
if (pHead->version == 0) { // from client or CQ
- if (pVnode->status != TAOS_VN_STATUS_READY) {
+ if (!vnodeInReadyStatus(pVnode)) {
vDebug("vgId:%d, msg:%s not processed since vstatus:%d, qtype:%s hver:%" PRIu64, pVnode->vgId,
taosMsg[pHead->msgType], pVnode->status, qtypeStr[qtype], pHead->version);
return TSDB_CODE_APP_NOT_READY; // it may be in deleting or closing state
@@ -118,7 +114,7 @@ static int32_t vnodeCheckWrite(void *vparam) {
return TSDB_CODE_APP_NOT_READY;
}
- if (pVnode->status == TAOS_VN_STATUS_CLOSING) {
+ if (vnodeInClosingStatus(pVnode)) {
vDebug("vgId:%d, vnode status is %s, refCount:%d pVnode:%p", pVnode->vgId, vnodeStatus[pVnode->status],
pVnode->refCount, pVnode);
return TSDB_CODE_APP_NOT_READY;
@@ -132,11 +128,6 @@ static int32_t vnodeCheckWrite(void *vparam) {
return TSDB_CODE_SUCCESS;
}
-void vnodeConfirmForward(void *vparam, uint64_t version, int32_t code) {
- SVnodeObj *pVnode = vparam;
- syncConfirmForward(pVnode->sync, version, code);
-}
-
static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pRet) {
int32_t code = TSDB_CODE_SUCCESS;
diff --git a/tests/pytest/client/noConnectionErrorTest.py b/tests/pytest/client/noConnectionErrorTest.py
new file mode 100644
index 0000000000..2c13016cf1
--- /dev/null
+++ b/tests/pytest/client/noConnectionErrorTest.py
@@ -0,0 +1,48 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import sys
+from util.log import *
+from util.cases import *
+from util.sql import *
+from util.dnodes import tdDnodes
+
+
+class TDTestCase:
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor(), logSql)
+
+ def run(self):
+ tdSql.prepare()
+
+ tdDnodes.stop(1)
+ sql = "use db"
+
+ try:
+ tdSql.execute(sql)
+ except Exception as e:
+ expectError = 'Unable to establish connection'
+ if expectError in str(e):
+ pass
+ else:
+ caller = inspect.getframeinfo(inspect.stack()[1][1])
+ tdLog.exit("%s(%d) failed: sql:%s, expect error not occured" % (caller.filename, caller.lineno, sql))
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh
index 8dbc4e3bb0..dc2c0099b4 100755
--- a/tests/pytest/fulltest.sh
+++ b/tests/pytest/fulltest.sh
@@ -161,7 +161,9 @@ python3 ./test.py -f query/bug1875.py
python3 ./test.py -f query/bug1876.py
python3 ./test.py -f query/bug2218.py
python3 ./test.py -f query/bug2117.py
-python3 ./test.py -f query/sliding.py
+python3 ./test.py -f query/bug2143.py
+python3 ./test.py -f query/sliding.py
+python3 ./test.py -f query/unionAllTest.py
#stream
python3 ./test.py -f stream/metric_1.py
@@ -178,6 +180,7 @@ python3 ./test.py -f alter/alter_table_crash.py
python3 ./test.py -f client/client.py
python3 ./test.py -f client/version.py
python3 ./test.py -f client/alterDatabase.py
+python3 ./test.py -f client/noConnectionErrorTest.py
# Misc
python3 testCompress.py
@@ -212,6 +215,7 @@ python3 test.py -f query/queryFillTest.py
python3 test.py -f tools/taosdemoTest.py
python3 test.py -f tools/taosdumpTest.py
python3 test.py -f tools/lowaTest.py
+python3 test.py -f tools/taosdemoTest2.py
# subscribe
python3 test.py -f subscribe/singlemeter.py
diff --git a/tests/pytest/query/bug2143.py b/tests/pytest/query/bug2143.py
new file mode 100644
index 0000000000..c28abba535
--- /dev/null
+++ b/tests/pytest/query/bug2143.py
@@ -0,0 +1,73 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import sys
+from util.log import *
+from util.cases import *
+from util.sql import *
+from util.dnodes import *
+class TDTestCase:
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor(), logSql)
+
+ def run(self):
+ tdSql.prepare()
+ print("==========step1")
+ print("create table && insert data")
+
+ tdSql.execute("create table mt0 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool,c8 binary(20),c9 nchar(20))")
+ insertRows = 1000
+ t0 = 1604298064000
+ tdLog.info("insert %d rows" % (insertRows))
+ for i in range(insertRows):
+ ret = tdSql.execute(
+ "insert into mt0 values (%d , %d,%d,%d,%d,%d,%d,%d,'%s','%s')" %
+ (t0+i,i%100,i/2.0,i%41,i%51,i%53,i*1.0,i%2,'taos'+str(i%43),'涛思'+str(i%41)))
+ print("==========step2")
+ print("test group by normal_col with limit offset")
+ tdSql.query('select max(c1),min(c1),first(c1),last(c1) from mt0 group by c3 limit 3 offset 2')
+ tdSql.checkData(0,0,99)
+ tdSql.checkData(0,1,2)
+ tdSql.checkData(0,2,2)
+ tdSql.checkData(0,3,86)
+ tdSql.checkData(1,0,95)
+ tdSql.checkData(2,1,1)
+ tdSql.query('select max(c1),min(c1),first(c1),last(c1) from mt0 group by c3 limit 3 offset 40')
+ tdSql.checkRows(1)
+ tdSql.query('select max(c1),min(c1),first(c1),last(c1) from mt0 group by c3 limit 3 offset 41')
+ tdSql.checkRows(0)
+ tdSql.query('select max(c1),min(c1),first(c1),last(c1) from mt0 group by c3 limit 3 offset 99')
+ tdSql.checkRows(0)
+ tdSql.query('select max(c1),min(c1),first(c1),last(c1) from mt0 group by c3 limit 70 offset 3')
+ tdSql.checkRows(38)
+ tdSql.query('select max(c1),min(c1),first(c1),last(c1) from mt0 group by c8 limit 3 offset 2')
+ tdSql.checkData(0,0,91)
+ tdSql.checkData(0,1,2)
+ tdSql.checkData(0,2,2)
+ tdSql.checkData(0,3,91)
+ tdSql.checkData(1,0,92)
+ tdSql.checkData(2,1,4)
+ tdSql.query('select max(c1),min(c1),first(c1),last(c1) from mt0 group by c9 limit 2 offset 9')
+ tdSql.checkData(0,0,96)
+ tdSql.checkData(0,1,1)
+ tdSql.checkData(0,2,9)
+ tdSql.checkData(0,3,93)
+ tdSql.checkData(1,0,97)
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success("%s successfully executed" % __file__)
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
\ No newline at end of file
diff --git a/tests/pytest/query/unionAllTest.py b/tests/pytest/query/unionAllTest.py
new file mode 100644
index 0000000000..bb4fb95de6
--- /dev/null
+++ b/tests/pytest/query/unionAllTest.py
@@ -0,0 +1,65 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import sys
+import taos
+from util.log import tdLog
+from util.cases import tdCases
+from util.sql import tdSql
+import random
+
+
+class TDTestCase:
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor(), logSql)
+
+ self.ts = 1500000000000
+ self.num = 10
+
+ def run(self):
+ tdSql.prepare()
+
+ tdSql.execute("create table st(ts timestamp, c1 int) tags(loc nchar(20))")
+ tdSql.execute("create table t0 using st tags('nchar0')")
+ tdSql.execute("create table t1 using st tags('nchar1')")
+ tdSql.execute("create table t2 using st tags('nchar2')")
+ tdSql.execute("create table t3 using st tags('nchar3')")
+ tdSql.execute("create table t4 using st tags('nchar4')")
+ tdSql.execute("create table t5 using st tags('nchar5')")
+
+ for i in range(self.num):
+ tdSql.execute("insert into t0 values(%d, %d)" % (self.ts + i, i))
+ tdSql.execute("insert into t1 values(%d, %d)" % (self.ts + i, i))
+ tdSql.execute("insert into t2 values(%d, %d)" % (self.ts + i, i))
+ tdSql.execute("insert into t3 values(%d, %d)" % (self.ts + i, i))
+ tdSql.execute("insert into t4 values(%d, %d)" % (self.ts + i, i))
+ tdSql.execute("insert into t5 values(%d, %d)" % (self.ts + i, i))
+
+ sql = ''' select * from st where loc = 'nchar0' limit 1 union all select * from st where loc = 'nchar1' limit 1 union all select * from st where loc = 'nchar2' limit 1
+ union all select * from st where loc = 'nchar3' limit 1 union all select * from st where loc = 'nchar4' limit 1'''
+ tdSql.query(sql)
+ tdSql.checkRows(5)
+
+ sql = ''' select * from st where loc = 'nchar0' limit 1 union all select * from st where loc = 'nchar1' limit 1 union all select * from st where loc = 'nchar2' limit 1
+ union all select * from st where loc = 'nchar3' limit 1 union all select * from st where loc = 'nchar4' limit 1 union all select * from st where loc = 'nchar5''''
+ tdSql.query(sql)
+ tdSql.checkRows(6)
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
\ No newline at end of file
diff --git a/tests/pytest/tools/taosdemoTest2.py b/tests/pytest/tools/taosdemoTest2.py
new file mode 100644
index 0000000000..7d5627be43
--- /dev/null
+++ b/tests/pytest/tools/taosdemoTest2.py
@@ -0,0 +1,64 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import sys
+import os
+from util.log import *
+from util.cases import *
+from util.sql import *
+from util.dnodes import *
+import threading
+import time
+
+
+class TDTestCase:
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor(), logSql)
+
+ self.numberOfTables = 10
+ self.numberOfRecords = 1000000
+
+ def insertDataAndAlterTable(self, threadID):
+ if(threadID == 0):
+ os.system("yes | taosdemo -t %d -n %d" % (self.numberOfTables, self.numberOfRecords))
+ if(threadID == 1):
+ print("use test")
+ tdSql.execute("use test")
+ print("alter table test.meters add column f4 int")
+ tdSql.execute("alter table test.meters add column f4 int")
+ print("insert into test.t0 values (now, 1, 2, 3, 4)")
+ tdSql.execute("insert into test.t0 values (now, 1, 2, 3, 4)")
+
+ def run(self):
+ tdSql.prepare()
+
+ t1 = threading.Thread(target=self.insertDataAndAlterTable, args=(0, ))
+ t2 = threading.Thread(target=self.insertDataAndAlterTable, args=(1, ))
+
+ t1.start()
+ time.sleep(2)
+ t2.start()
+ t1.join()
+ t2.join()
+
+ tdSql.query("select count(*) from test.meters")
+ tdSql.checkData(0, 0, self.numberOfRecords * self.numberOfTables + 1)
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
\ No newline at end of file
diff --git a/tests/script/general/stable/values.sim b/tests/script/general/stable/values.sim
index d0c1783851..51488aabef 100644
--- a/tests/script/general/stable/values.sim
+++ b/tests/script/general/stable/values.sim
@@ -18,16 +18,25 @@ sql create table vdb0.vtb00 using vdb0.mt tags( 0 )
sql create table vdb0.vtb01 using vdb0.mt tags( 0 )
sql create database vdb1
-sql create table vdb1.vtb10 using vdb0.mt tags( 1 )
-sql create table vdb1.vtb11 using vdb0.mt tags( 1 )
+sql create table vdb1.mt (ts timestamp, tbcol int) TAGS(tgcol int)
+sql_error create table vdb1.vtb10 using vdb0.mt tags( 1 )
+sql_error create table vdb1.vtb11 using vdb0.mt tags( 1 )
+sql create table vdb1.vtb10 using vdb1.mt tags( 1 )
+sql create table vdb1.vtb11 using vdb1.mt tags( 1 )
sql create database vdb2
-sql create table vdb2.vtb20 using vdb0.mt tags( 2 )
-sql create table vdb2.vtb21 using vdb0.mt tags( 2 )
+sql create table vdb2.mt (ts timestamp, tbcol int) TAGS(tgcol int)
+sql_error create table vdb2.vtb20 using vdb0.mt tags( 2 )
+sql_error create table vdb2.vtb21 using vdb0.mt tags( 2 )
+sql create table vdb2.vtb20 using vdb2.mt tags( 2 )
+sql create table vdb2.vtb21 using vdb2.mt tags( 2 )
sql create database vdb3
-sql create table vdb3.vtb30 using vdb0.mt tags( 3 )
-sql create table vdb3.vtb31 using vdb0.mt tags( 3 )
+sql create table vdb3.mt (ts timestamp, tbcol int) TAGS(tgcol int)
+sql_error create table vdb3.vtb20 using vdb0.mt tags( 2 )
+sql_error create table vdb3.vtb21 using vdb0.mt tags( 2 )
+sql create table vdb3.vtb30 using vdb3.mt tags( 3 )
+sql create table vdb3.vtb31 using vdb3.mt tags( 3 )
print =============== step2
sql insert into vdb0.vtb00 values (1519833600000 , 10) (1519833600001, 20) (1519833600002, 30)
@@ -40,7 +49,7 @@ sql insert into vdb3.vtb30 values (1519833600000 , 13) (1519833600001, 23) (1519
sql insert into vdb3.vtb31 values (1519833600000 , 13) (1519833600001, 23) (1519833600002, 33)
sql select * from vdb0.mt
-if $rows != 24 then
+if $rows != 6 then
return -1
endi
@@ -55,7 +64,7 @@ sql insert into vdb3.vtb30 values (1519833600003 , 43) (1519833600005, 53) (1519
sql insert into vdb3.vtb31 values (1519833600003 , 43) (1519833600005, 53) (1519833600004, 63)
sql select * from vdb0.mt
-if $rows != 48 then
+if $rows != 12 then
return -1
endi
@@ -66,7 +75,7 @@ sql insert into vdb2.vtb20 values(1519833600006, 62) (1519833600007, 72) vdb2.vt
sql insert into vdb3.vtb30 values(1519833600006, 63) (1519833600007, 73) vdb3.vtb31 values(1519833600006, 63) (1519833600007, 73)
sql select * from vdb0.mt
-if $rows != 64 then
+if $rows != 16 then
return -1
endi
@@ -77,7 +86,7 @@ sql insert into vdb2.vtb20 values(1519833600008, 82) (1519833600007, 72) vdb2.vt
sql insert into vdb3.vtb30 values(1519833600008, 83) (1519833600007, 73) vdb3.vtb31 values(1519833600006, 83) (1519833600007, 73)
sql select * from vdb0.mt
-if $rows != 68 then
+if $rows != 17 then
return -1
endi
@@ -87,7 +96,7 @@ sql insert into vdb0.vtb01 values(1519833600009, 90) (1519833600010, 100) vdb1.v
sql select * from vdb0.mt
-if $rows != 84 then
+if $rows != 21 then
return -1
endi
@@ -97,7 +106,7 @@ sql insert into vdb0.vtb01 values(1519833600012, 120) (1519833600011, 110) vdb1.
sql select * from vdb0.mt
-if $rows != 100 then
+if $rows != 25 then
return -1
endi