Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
c8ffc27e
T
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
c8ffc27e
编写于
12月 14, 2021
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
差异文件
[td-10564] merge 3.0
上级
fb5db901
43a2bcdc
变更
42
隐藏空白更改
内联
并排
Showing
42 changed file
with
1291 addition
and
882 deletion
+1291
-882
.gitignore
.gitignore
+1
-1
CMakeLists.txt
CMakeLists.txt
+6
-2
include/dnode/vnode/tq/tq.h
include/dnode/vnode/tq/tq.h
+1
-1
include/dnode/vnode/vnode.h
include/dnode/vnode/vnode.h
+2
-0
include/libs/parser/parser.h
include/libs/parser/parser.h
+1
-1
include/libs/wal/wal.h
include/libs/wal/wal.h
+53
-47
include/util/tdlist.h
include/util/tdlist.h
+169
-0
include/util/tmacro.h
include/util/tmacro.h
+44
-0
source/dnode/mgmt/impl/test/dnode/dnode.cpp
source/dnode/mgmt/impl/test/dnode/dnode.cpp
+6
-5
source/dnode/mgmt/impl/test/user/user.cpp
source/dnode/mgmt/impl/test/user/user.cpp
+227
-320
source/dnode/mnode/impl/src/mndUser.c
source/dnode/mnode/impl/src/mndUser.c
+6
-7
source/dnode/mnode/sdb/src/sdb.c
source/dnode/mnode/sdb/src/sdb.c
+2
-2
source/dnode/vnode/impl/CMakeLists.txt
source/dnode/vnode/impl/CMakeLists.txt
+3
-3
source/dnode/vnode/impl/inc/vnodeBufferPool.h
source/dnode/vnode/impl/inc/vnodeBufferPool.h
+1
-0
source/dnode/vnode/impl/inc/vnodeCommit.h
source/dnode/vnode/impl/inc/vnodeCommit.h
+2
-2
source/dnode/vnode/impl/inc/vnodeDef.h
source/dnode/vnode/impl/inc/vnodeDef.h
+3
-1
source/dnode/vnode/impl/inc/vnodeMemAllocator.h
source/dnode/vnode/impl/inc/vnodeMemAllocator.h
+26
-4
source/dnode/vnode/impl/src/vnodeArenaMAImpl.c
source/dnode/vnode/impl/src/vnodeArenaMAImpl.c
+117
-0
source/dnode/vnode/impl/src/vnodeBufferPool.c
source/dnode/vnode/impl/src/vnodeBufferPool.c
+83
-108
source/dnode/vnode/impl/src/vnodeCfg.c
source/dnode/vnode/impl/src/vnodeCfg.c
+1
-1
source/dnode/vnode/impl/src/vnodeCommit.c
source/dnode/vnode/impl/src/vnodeCommit.c
+0
-2
source/dnode/vnode/impl/src/vnodeMain.c
source/dnode/vnode/impl/src/vnodeMain.c
+12
-1
source/dnode/vnode/impl/src/vnodeMemAllocator.c
source/dnode/vnode/impl/src/vnodeMemAllocator.c
+0
-113
source/dnode/vnode/impl/test/CMakeLists.txt
source/dnode/vnode/impl/test/CMakeLists.txt
+6
-1
source/dnode/vnode/impl/test/vnodeApiTests.cpp
source/dnode/vnode/impl/test/vnodeApiTests.cpp
+11
-0
source/libs/parser/inc/dataBlockMgt.h
source/libs/parser/inc/dataBlockMgt.h
+1
-15
source/libs/parser/src/dataBlockMgt.c
source/libs/parser/src/dataBlockMgt.c
+7
-20
source/libs/parser/src/insertParser.c
source/libs/parser/src/insertParser.c
+7
-13
source/libs/parser/test/insertTest.cpp
source/libs/parser/test/insertTest.cpp
+34
-18
source/libs/parser/test/mockCatalog.cpp
source/libs/parser/test/mockCatalog.cpp
+23
-22
source/libs/parser/test/mockCatalogService.cpp
source/libs/parser/test/mockCatalogService.cpp
+91
-14
source/libs/parser/test/mockCatalogService.h
source/libs/parser/test/mockCatalogService.h
+3
-2
source/libs/wal/inc/walInt.h
source/libs/wal/inc/walInt.h
+5
-3
source/libs/wal/src/walMeta.c
source/libs/wal/src/walMeta.c
+14
-14
source/libs/wal/src/walMgmt.c
source/libs/wal/src/walMgmt.c
+28
-32
source/libs/wal/src/walRead.c
source/libs/wal/src/walRead.c
+158
-1
source/libs/wal/src/walSeek.c
source/libs/wal/src/walSeek.c
+7
-10
source/libs/wal/src/walUtil.c
source/libs/wal/src/walUtil.c
+2
-0
source/libs/wal/src/walWrite.c
source/libs/wal/src/walWrite.c
+58
-57
source/libs/wal/test/walMetaTest.cpp
source/libs/wal/test/walMetaTest.cpp
+67
-36
source/util/src/tarray.c
source/util/src/tarray.c
+1
-1
tests/pytest/crash_gen/valgrind_taos.supp
tests/pytest/crash_gen/valgrind_taos.supp
+2
-2
未找到文件。
.gitignore
浏览文件 @
c8ffc27e
...
...
@@ -101,4 +101,4 @@ TAGS
contrib/*
!contrib/CMakeLists.txt
!contrib/test
!contrib/test
\ No newline at end of file
CMakeLists.txt
浏览文件 @
c8ffc27e
...
...
@@ -10,7 +10,7 @@ set(CMAKE_SUPPORT_DIR "${CMAKE_SOURCE_DIR}/cmake")
set
(
CMAKE_CONTRIB_DIR
"
${
CMAKE_SOURCE_DIR
}
/contrib"
)
include
(
${
CMAKE_SUPPORT_DIR
}
/cmake.options
)
SET
(
CMAKE_C_FLAGS
"
${
CMAKE_C_FLAGS
}
-fPIC -gdwarf-2 -msse4.2 -mfma"
)
SET
(
CMAKE_C_FLAGS
"
${
CMAKE_C_FLAGS
}
-fPIC -gdwarf-2 -msse4.2 -mfma
-g3
"
)
# contrib
add_subdirectory
(
contrib
)
...
...
@@ -20,9 +20,13 @@ add_library(api INTERFACE)
target_include_directories
(
api INTERFACE
"include/client"
)
# src
if
(
${
BUILD_TEST
}
)
include
(
CTest
)
enable_testing
()
endif
(
${
BUILD_TEST
}
)
add_subdirectory
(
source
)
# docs
add_subdirectory
(
docs
)
# tests (TODO)
# tests (TODO)
\ No newline at end of file
include/dnode/vnode/tq/tq.h
浏览文件 @
c8ffc27e
...
...
@@ -256,7 +256,7 @@ typedef struct STQ {
// the collection of group handle
// the handle of kvstore
char
*
path
;
STqCfg
*
tqConfig
;
STqCfg
*
tqConfig
;
TqLogReader
*
tqLogReader
;
TqMemRef
tqMemRef
;
TqMetaStore
*
tqMeta
;
...
...
include/dnode/vnode/vnode.h
浏览文件 @
c8ffc27e
...
...
@@ -36,6 +36,8 @@ typedef struct SVnodeCfg {
struct
{
/** write buffer size */
uint64_t
wsize
;
uint64_t
ssize
;
uint64_t
lsize
;
/** use heap allocator or arena allocator */
bool
isHeapAllocator
;
};
...
...
include/libs/parser/parser.h
浏览文件 @
c8ffc27e
...
...
@@ -162,7 +162,7 @@ typedef struct SVgDataBlocks {
int64_t
vgId
;
// virtual group id
int32_t
numOfTables
;
// number of tables in current submit block
uint32_t
size
;
char
*
pData
;
char
*
pData
;
// SMsgDesc + SSubmitMsg + SSubmitBlk + ...
}
SVgDataBlocks
;
typedef
struct
SInsertStmtInfo
{
...
...
include/libs/wal/wal.h
浏览文件 @
c8ffc27e
...
...
@@ -32,6 +32,23 @@ extern int32_t wDebugFlag;
#define wDebug(...) { if (wDebugFlag & DEBUG_DEBUG) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }}
#define wTrace(...) { if (wDebugFlag & DEBUG_TRACE) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }}
#define WAL_PREFIX "wal"
#define WAL_PREFIX_LEN 3
#define WAL_NOSUFFIX_LEN 20
#define WAL_SUFFIX_AT (WAL_NOSUFFIX_LEN+1)
#define WAL_LOG_SUFFIX "log"
#define WAL_INDEX_SUFFIX "idx"
#define WAL_REFRESH_MS 1000
#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + 16)
#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12)
#define WAL_FILE_LEN (WAL_PATH_LEN + 32)
#define WAL_IDX_ENTRY_SIZE (sizeof(int64_t)*2)
#define WAL_CUR_POS_WRITABLE 1
#define WAL_CUR_FILE_WRITABLE 2
#define WAL_CUR_FAILED 4
#pragma pack(push,1)
typedef
enum
{
TAOS_WAL_NOLOG
=
0
,
TAOS_WAL_WRITE
=
1
,
...
...
@@ -43,8 +60,9 @@ typedef struct SWalReadHead {
uint8_t
msgType
;
int8_t
reserved
[
2
];
int32_t
len
;
//int64_t ingestTs; //not implemented
int64_t
version
;
char
cont
[];
char
body
[];
}
SWalReadHead
;
typedef
struct
{
...
...
@@ -52,9 +70,9 @@ typedef struct {
int32_t
fsyncPeriod
;
// millisecond
int32_t
retentionPeriod
;
// secs
int32_t
rollPeriod
;
// secs
int
32_t
retentionSize
;
// secs
int
64_t
retentionSize
;
int64_t
segSize
;
EWalType
walL
evel
;
// wal level
EWalType
l
evel
;
// wal level
}
SWalCfg
;
typedef
struct
{
...
...
@@ -71,64 +89,48 @@ typedef struct {
SWalReadHead
head
;
}
SWalHead
;
#define WAL_PREFIX "wal"
#define WAL_PREFIX_LEN 3
#define WAL_NOSUFFIX_LEN 20
#define WAL_SUFFIX_AT (WAL_NOSUFFIX_LEN+1)
#define WAL_LOG_SUFFIX "log"
#define WAL_INDEX_SUFFIX "idx"
#define WAL_REFRESH_MS 1000
#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + 16)
#define WAL_SIGNATURE ((uint32_t)(0xFAFBFDFEUL))
#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12)
#define WAL_FILE_LEN (WAL_PATH_LEN + 32)
//#define WAL_FILE_NUM 1 // 3
#define WAL_FILESET_MAX 128
#define WAL_IDX_ENTRY_SIZE (sizeof(int64_t)*2)
#define WAL_CUR_POS_WRITABLE 1
#define WAL_CUR_FILE_WRITABLE 2
#define WAL_CUR_FAILED 4
typedef
struct
SWalVer
{
int64_t
firstVer
;
int64_t
verInSnapshotting
;
int64_t
snapshotVer
;
int64_t
commitVer
;
int64_t
lastVer
;
}
SWalVer
;
typedef
struct
SWal
{
// cfg
int32_t
vgId
;
int32_t
fsyncPeriod
;
// millisecond
int32_t
rollPeriod
;
// second
int64_t
segSize
;
int64_t
retentionSize
;
int32_t
retentionPeriod
;
EWalType
level
;
//total size
int64_t
totSize
;
//fsync seq
int32_t
fsyncSeq
;
//reference
int64_t
refId
;
//write tfd
int64_t
writeLogTfd
;
int64_t
writeIdxTfd
;
//wal lifecycle
int64_t
firstVersion
;
int64_t
snapshotVersion
;
int64_t
commitVersion
;
int64_t
lastVersion
;
//snapshotting version
int64_t
snapshottingVer
;
//roll status
int64_t
lastRollSeq
;
SWalCfg
cfg
;
SWalVer
vers
;
//file set
int32_t
writeCur
;
int64_t
writeLogTfd
;
int64_t
writeIdxTfd
;
SArray
*
fileInfoSet
;
//ctl
int32_t
curStatus
;
int32_t
fsyncSeq
;
int64_t
totSize
;
int64_t
refId
;
int64_t
lastRollSeq
;
pthread_mutex_t
mutex
;
//path
char
path
[
WAL_PATH_LEN
];
//reusable write head
SWalHead
h
ead
;
SWalHead
writeH
ead
;
}
SWal
;
// WAL HANDLE
typedef
struct
SWalReadHandle
{
SWal
*
pWal
;
int64_t
readLogTfd
;
int64_t
readIdxTfd
;
int64_t
curFileFirstVer
;
int64_t
curVersion
;
int64_t
capacity
;
int64_t
status
;
//if cursor valid
SWalHead
*
pHead
;
}
SWalReadHandle
;
#pragma pack(pop)
typedef
int32_t
(
*
FWalWrite
)(
void
*
ahandle
,
void
*
pHead
);
// module initialization
...
...
@@ -154,6 +156,10 @@ int32_t walEndTakeSnapshot(SWal *);
//int32_t walDataCorrupted(SWal*);
// read
SWalReadHandle
*
walOpenReadHandle
(
SWal
*
);
void
walCloseReadHandle
(
SWalReadHandle
*
);
int32_t
walReadWithHandle
(
SWalReadHandle
*
pRead
,
int64_t
ver
);
int32_t
walRead
(
SWal
*
,
SWalHead
**
,
int64_t
ver
);
int32_t
walReadWithFp
(
SWal
*
,
FWalWrite
writeFp
,
int64_t
verStart
,
int32_t
readNum
);
...
...
include/util/tdlist.h
0 → 100644
浏览文件 @
c8ffc27e
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_UTIL_TDLIST_H_
#define _TD_UTIL_TDLIST_H_
#ifdef __cplusplus
extern
"C"
{
#endif
// Single linked list
#define TD_SLIST_NODE(TYPE) \
struct { \
struct TYPE *sl_next_; \
}
#define TD_SLIST(TYPE) \
struct { \
struct TYPE *sl_head_; \
int sl_neles_; \
}
#define TD_SLIST_HEAD(sl) ((sl)->sl_head_)
#define TD_SLIST_NELES(sl) ((sl)->sl_neles_)
#define TD_SLIST_NODE_NEXT(sln) ((sln)->sl_next_)
#define tSListInit(sl) \
do { \
(sl)->sl_head_ = NULL; \
(sl)->sl_neles_ = 0; \
} while (0)
#define tSListPush(sl, sln) \
do { \
TD_SLIST_NODE_NEXT(sln) = TD_SLIST_HEAD(sl); \
TD_SLIST_HEAD(sl) = (sln); \
TD_SLIST_NELES(sl) += 1; \
} while (0)
#define tSListPop(sl) \
do { \
TD_SLIST_HEAD(sl) = TD_SLIST_NODE_NEXT(TD_SLIST_HEAD(sl)); \
TD_SLIST_NELES(sl) -= 1; \
} while (0)
// Double linked list
#define TD_DLIST_NODE(TYPE) \
struct { \
TYPE *dl_prev_; \
TYPE *dl_next_; \
}
#define TD_DLIST(TYPE) \
struct { \
struct TYPE *dl_head_; \
struct TYPE *dl_tail_; \
int dl_neles_; \
}
#define TD_DLIST_NODE_PREV(dln) ((dln)->dl_prev_)
#define TD_DLIST_NODE_NEXT(dln) ((dln)->dl_next_)
#define TD_DLIST_HEAD(dl) ((dl)->dl_head_)
#define TD_DLIST_TAIL(dl) ((dl)->dl_tail_)
#define TD_DLIST_NELES(dl) ((dl)->dl_neles_)
#define tDListInit(dl) \
do { \
TD_DLIST_HEAD(dl) = TD_DLIST_TAIL(dl) = NULL; \
TD_DLIST_NELES(dl) = 0; \
} while (0)
#define tDListAppend(dl, dln) \
do { \
if (TD_DLIST_HEAD(dl) == NULL) { \
TD_DLIST_NODE_PREV(dln) = TD_DLIST_NODE_NEXT(dln) = NULL; \
TD_DLIST_HEAD(dl) = TD_DLIST_TAIL(dl) = (dln); \
} else { \
TD_DLIST_NODE_PREV(dln) = TD_DLIST_TAIL(dl); \
TD_DLIST_NODE_NEXT(dln) = NULL; \
TD_DLIST_NODE_NEXT(TD_DLIST_TAIL(dl)) = (dln); \
TD_DLIST_TAIL(dl) = (dln); \
} \
TD_DLIST_NELES(dl) += 1; \
} while (0)
#define tDListPrepend(dl, dln) \
do { \
if (TD_DLIST_HEAD(dl) == NULL) { \
TD_DLIST_NODE_PREV(dln) = TD_DLIST_NODE_NEXT(dln) = NULL; \
TD_DLIST_HEAD(dl) = TD_DLIST_TAIL(dl) = (dln); \
} else { \
TD_DLIST_NODE_PREV(dln) = NULL; \
TD_DLIST_NODE_NEXT(dln) = TD_DLIST_HEAD(dl); \
TD_DLIST_NODE_PREV(TD_DLIST_HEAD(dl)) = (dln); \
TD_DLIST_HEAD(dl) = (dln); \
} \
TD_DLIST_NELES(dl) += 1; \
} while (0)
#define tDListPop(dl, dln) \
do { \
if (TD_DLIST_HEAD(dl) == (dln)) { \
TD_DLIST_HEAD(dl) = TD_DLIST_NODE_NEXT(dln); \
} \
if (TD_DLIST_TAIL(dl) == (dln)) { \
TD_DLIST_TAIL(dl) = TD_DLIST_NODE_PREV(dln); \
} \
if (TD_DLIST_NODE_PREV(dln) != NULL) { \
TD_DLIST_NODE_NEXT(TD_DLIST_NODE_PREV(dln)) = TD_DLIST_NODE_NEXT(dln); \
} \
if (TD_DLIST_NODE_NEXT(dln) != NULL) { \
TD_DLIST_NODE_PREV(TD_DLIST_NODE_NEXT(dln)) = TD_DLIST_NODE_PREV(dln); \
} \
TD_DLIST_NELES(dl) -= 1; \
TD_DLIST_NODE_PREV(dln) = TD_DLIST_NODE_NEXT(dln) = NULL; \
} while (0)
#if 0
// List iterator
#define TD_LIST_FITER 0
#define TD_LIST_BITER 1
#define TD_LIST_ITER(S) \
struct { \
int it_dir_; \
S * it_next_; \
S * it_ptr_; \
TD_DLIST(S) * it_list_; \
}
#define tlistIterInit(it, l, dir) \
(it)->it_dir_ = (dir); \
(it)->it_list_ = l; \
if ((dir) == TD_LIST_FITER) { \
(it)->it_next_ = (l)->dl_head_; \
} else { \
(it)->it_next_ = (l)->dl_tail_; \
}
#define tlistIterNext(it) \
({ \
(it)->it_ptr_ = (it)->it_next_; \
if ((it)->it_next_ != NULL) { \
if ((it)->it_dir_ == TD_LIST_FITER) { \
(it)->it_next_ = (it)->it_next_->next_; \
} else { \
(it)->it_next_ = (it)->it_next_->prev_; \
} \
} \
(it)->it_ptr_; \
})
#endif
#ifdef __cplusplus
}
#endif
#endif
/*_TD_UTIL_TDLIST_H_*/
\ No newline at end of file
include/util/tmacro.h
0 → 100644
浏览文件 @
c8ffc27e
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_UTIL_MACRO_H_
#define _TD_UTIL_MACRO_H_
#include "os.h"
#ifdef __cplusplus
extern
"C"
{
#endif
// Module init/clear MACRO definitions
#define TD_MOD_UNINITIALIZED 0
#define TD_MOD_INITIALIZED 1
#define TD_MOD_UNCLEARD 0
#define TD_MOD_CLEARD 1
#define TD_DEF_MOD_INIT_FLAG(MOD) static int8_t MOD##InitFlag = TD_MOD_UNINITIALIZED
#define TD_DEF_MOD_CLEAR_FLAG(MOD) static int8_t MOD##ClearFlag = TD_MOD_UNCLEARD
#define TD_CHECK_AND_SET_MODE_INIT(MOD) \
atomic_val_compare_exchange_8(&(MOD##InitFlag), TD_MOD_UNINITIALIZED, TD_MOD_INITIALIZED)
#define TD_CHECK_AND_SET_MOD_CLEAR(MOD) atomic_val_compare_exchange_8(&(MOD##ClearFlag), TD_MOD_UNCLEARD, TD_MOD_CLEARD)
#ifdef __cplusplus
}
#endif
#endif
/*_TD_UTIL_MACRO_H_*/
\ No newline at end of file
source/dnode/mgmt/impl/test/dnode/dnode.cpp
浏览文件 @
c8ffc27e
...
...
@@ -271,7 +271,6 @@ TEST_F(DndTestDnode, DropDnode_01) {
ASSERT_NE
(
pMsg
,
nullptr
);
ASSERT_EQ
(
pMsg
->
code
,
0
);
taosMsleep
(
1300
);
SendTheCheckShowMetaMsg
(
TSDB_MGMT_TABLE_DNODE
,
"show dnodes"
,
7
);
SendThenCheckShowRetrieveMsg
(
1
);
CheckInt16
(
1
);
...
...
@@ -363,7 +362,7 @@ TEST_F(DndTestDnode, CreateDnode_02) {
}
TEST_F
(
DndTestDnode
,
RestartDnode_01
)
{
uInfo
(
"
===>
stop all server"
);
uInfo
(
"stop all server"
);
stopServer
(
pServer1
);
stopServer
(
pServer2
);
stopServer
(
pServer3
);
...
...
@@ -375,14 +374,16 @@ TEST_F(DndTestDnode, RestartDnode_01) {
pServer4
=
NULL
;
pServer5
=
NULL
;
taosMsleep
(
3000
);
// wait tcp port cleanedup
uInfo
(
"===> start all server"
);
uInfo
(
"start all server"
);
const
char
*
fqdn
=
"localhost"
;
const
char
*
firstEp
=
"localhost:9521"
;
pServer1
=
startServer
(
"/tmp/dndTestDnode1"
,
fqdn
,
9521
,
firstEp
);
// pServer1 = startServer("/tmp/dndTestDnode3", fqdn, 9523, firstEp);
// pServer1 = startServer("/tmp/dndTestDnode4", fqdn, 9524, firstEp);
// pServer1 = startServer("/tmp/dndTestDnode5", fqdn, 9525, firstEp);
uInfo
(
"
===>
all server is running"
);
uInfo
(
"all server is running"
);
// taosMsleep(1300);
// SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7);
...
...
source/dnode/mgmt/impl/test/user/user.cpp
浏览文件 @
c8ffc27e
...
...
@@ -17,270 +17,223 @@
class
DndTestUser
:
public
::
testing
::
Test
{
protected:
void
SetUp
()
override
{}
void
TearDown
()
override
{}
static
SServer
*
CreateServer
(
const
char
*
path
,
const
char
*
fqdn
,
uint16_t
port
,
const
char
*
firstEp
)
{
SServer
*
pServer
=
createServer
(
path
,
fqdn
,
port
,
firstEp
);
ASSERT
(
pServer
);
return
pServer
;
}
static
void
SetUpTestSuite
()
{
const
char
*
user
=
"root"
;
const
char
*
pass
=
"taosdata"
;
const
char
*
path
=
"/tmp/dndTestUser"
;
const
char
*
fqdn
=
"localhost"
;
uint16_t
port
=
9524
;
const
char
*
firstEp
=
"localhost:9524"
;
initLog
(
"/tmp/dndTestUser"
);
pServer
=
createServer
(
path
,
fqdn
,
port
,
firstEp
);
ASSERT
(
pServer
);
pClient
=
createClient
(
user
,
pass
,
fqdn
,
port
);
const
char
*
fqdn
=
"localhost"
;
const
char
*
firstEp
=
"localhost:9530"
;
pServer
=
CreateServer
(
"/tmp/dndTestUser"
,
fqdn
,
9530
,
firstEp
);
pClient
=
createClient
(
"root"
,
"taosdata"
,
fqdn
,
9530
);
taosMsleep
(
300
);
}
static
void
TearDownTestSuite
()
{
stopServer
(
pServer
);
dropClient
(
pClient
);
pServer
=
NULL
;
pClient
=
NULL
;
}
static
SServer
*
pServer
;
static
SClient
*
pClient
;
static
int32_t
connId
;
};
SServer
*
DndTestUser
::
pServer
;
SClient
*
DndTestUser
::
pClient
;
int32_t
DndTestUser
::
connId
;
public:
void
SetUp
()
override
{}
void
TearDown
()
override
{}
#if 0
TEST_F(DndTestUser, ShowUser) {
int32_t showId = 0;
//--- meta ---
SShowMsg* pShow = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg));
pShow->type = TSDB_MGMT_TABLE_USER;
strcpy(pShow->db, "");
SRpcMsg showRpcMsg = {0};
showRpcMsg.pCont = pShow;
showRpcMsg.contLen = sizeof(SShowMsg);
showRpcMsg.msgType = TSDB_MSG_TYPE_SHOW;
sendMsg(pClient, &showRpcMsg);
ASSERT_NE(pClient->pRsp, nullptr);
SShowRsp* pShowRsp = (SShowRsp*)pClient->pRsp->pCont;
ASSERT_NE(pShowRsp, nullptr);
pShowRsp->showId = htonl(pShowRsp->showId);
STableMetaMsg* pMeta = &pShowRsp->tableMeta;
pMeta->contLen = htonl(pMeta->contLen);
pMeta->numOfColumns = htons(pMeta->numOfColumns);
pMeta->sversion = htons(pMeta->sversion);
pMeta->tversion = htons(pMeta->tversion);
pMeta->tid = htonl(pMeta->tid);
pMeta->uid = htobe64(pMeta->uid);
pMeta->suid = htobe64(pMeta->suid);
showId = pShowRsp->showId;
EXPECT_NE(pShowRsp->showId, 0);
EXPECT_EQ(pMeta->contLen, 0);
EXPECT_STREQ(pMeta->tbFname, "show users");
EXPECT_EQ(pMeta->numOfTags, 0);
EXPECT_EQ(pMeta->precision, 0);
EXPECT_EQ(pMeta->tableType, 0);
EXPECT_EQ(pMeta->numOfColumns, 4);
EXPECT_EQ(pMeta->sversion, 0);
EXPECT_EQ(pMeta->tversion, 0);
EXPECT_EQ(pMeta->tid, 0);
EXPECT_EQ(pMeta->uid, 0);
EXPECT_STREQ(pMeta->sTableName, "");
EXPECT_EQ(pMeta->suid, 0);
SSchema* pSchema = NULL;
pSchema = &pMeta->pSchema[0];
pSchema->bytes = htons(pSchema->bytes);
EXPECT_EQ(pSchema->colId, 0);
EXPECT_EQ(pSchema->type, TSDB_DATA_TYPE_BINARY);
EXPECT_EQ(pSchema->bytes, TSDB_USER_LEN + VARSTR_HEADER_SIZE);
EXPECT_STREQ(pSchema->name, "name");
pSchema = &pMeta->pSchema[1];
pSchema->bytes = htons(pSchema->bytes);
EXPECT_EQ(pSchema->colId, 0);
EXPECT_EQ(pSchema->type, TSDB_DATA_TYPE_BINARY);
EXPECT_EQ(pSchema->bytes, 10 + VARSTR_HEADER_SIZE);
EXPECT_STREQ(pSchema->name, "privilege");
pSchema = &pMeta->pSchema[2];
pSchema->bytes = htons(pSchema->bytes);
EXPECT_EQ(pSchema->colId, 0);
EXPECT_EQ(pSchema->type, TSDB_DATA_TYPE_TIMESTAMP);
EXPECT_EQ(pSchema->bytes, 8);
EXPECT_STREQ(pSchema->name, "create_time");
pSchema = &pMeta->pSchema[3];
pSchema->bytes = htons(pSchema->bytes);
EXPECT_EQ(pSchema->colId, 0);
EXPECT_EQ(pSchema->type, TSDB_DATA_TYPE_BINARY);
EXPECT_EQ(pSchema->bytes, TSDB_USER_LEN + VARSTR_HEADER_SIZE);
EXPECT_STREQ(pSchema->name, "account");
//--- retrieve ---
SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(sizeof(SRetrieveTableMsg));
pRetrieve->showId = htonl(showId);
pRetrieve->free = 0;
SRpcMsg retrieveRpcMsg = {0};
retrieveRpcMsg.pCont = pRetrieve;
retrieveRpcMsg.contLen = sizeof(SRetrieveTableMsg);
retrieveRpcMsg.msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE;
sendMsg(pClient, &retrieveRpcMsg);
ASSERT_NE(pClient->pRsp, nullptr);
ASSERT_EQ(pClient->pRsp->code, 0);
SRetrieveTableRsp* pRetrieveRsp = (SRetrieveTableRsp*)pClient->pRsp->pCont;
ASSERT_NE(pRetrieveRsp, nullptr);
pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows);
pRetrieveRsp->offset = htobe64(pRetrieveRsp->offset);
pRetrieveRsp->useconds = htobe64(pRetrieveRsp->useconds);
pRetrieveRsp->compLen = htonl(pRetrieveRsp->compLen);
EXPECT_EQ(pRetrieveRsp->numOfRows, 2);
EXPECT_EQ(pRetrieveRsp->offset, 0);
EXPECT_EQ(pRetrieveRsp->useconds, 0);
EXPECT_EQ(pRetrieveRsp->completed, 1);
EXPECT_EQ(pRetrieveRsp->precision, TSDB_TIME_PRECISION_MILLI);
EXPECT_EQ(pRetrieveRsp->compressed, 0);
EXPECT_EQ(pRetrieveRsp->reserved, 0);
EXPECT_EQ(pRetrieveRsp->compLen, 0);
char* pData = pRetrieveRsp->data;
int32_t pos = 0;
char* strVal = NULL;
int64_t int64Val = 0;
//--- name ---
{
pos += sizeof(VarDataLenT);
strVal = (char*)(pData + pos);
pos += TSDB_USER_LEN;
EXPECT_STREQ(strVal, "root");
void
SendTheCheckShowMetaMsg
(
int8_t
showType
,
const
char
*
showName
,
int32_t
columns
)
{
SShowMsg
*
pShow
=
(
SShowMsg
*
)
rpcMallocCont
(
sizeof
(
SShowMsg
));
pShow
->
type
=
showType
;
strcpy
(
pShow
->
db
,
""
);
SRpcMsg
showRpcMsg
=
{
0
};
showRpcMsg
.
pCont
=
pShow
;
showRpcMsg
.
contLen
=
sizeof
(
SShowMsg
);
showRpcMsg
.
msgType
=
TSDB_MSG_TYPE_SHOW
;
sendMsg
(
pClient
,
&
showRpcMsg
);
ASSERT_NE
(
pClient
->
pRsp
,
nullptr
);
ASSERT_EQ
(
pClient
->
pRsp
->
code
,
0
);
ASSERT_NE
(
pClient
->
pRsp
->
pCont
,
nullptr
);
SShowRsp
*
pShowRsp
=
(
SShowRsp
*
)
pClient
->
pRsp
->
pCont
;
ASSERT_NE
(
pShowRsp
,
nullptr
);
pShowRsp
->
showId
=
htonl
(
pShowRsp
->
showId
);
pMeta
=
&
pShowRsp
->
tableMeta
;
pMeta
->
numOfTags
=
htons
(
pMeta
->
numOfTags
);
pMeta
->
numOfColumns
=
htons
(
pMeta
->
numOfColumns
);
pMeta
->
sversion
=
htons
(
pMeta
->
sversion
);
pMeta
->
tversion
=
htons
(
pMeta
->
tversion
);
pMeta
->
tuid
=
htobe64
(
pMeta
->
tuid
);
pMeta
->
suid
=
htobe64
(
pMeta
->
suid
);
showId
=
pShowRsp
->
showId
;
EXPECT_NE
(
pShowRsp
->
showId
,
0
);
EXPECT_STREQ
(
pMeta
->
tbFname
,
showName
);
EXPECT_EQ
(
pMeta
->
numOfTags
,
0
);
EXPECT_EQ
(
pMeta
->
numOfColumns
,
columns
);
EXPECT_EQ
(
pMeta
->
precision
,
0
);
EXPECT_EQ
(
pMeta
->
tableType
,
0
);
EXPECT_EQ
(
pMeta
->
update
,
0
);
EXPECT_EQ
(
pMeta
->
sversion
,
0
);
EXPECT_EQ
(
pMeta
->
tversion
,
0
);
EXPECT_EQ
(
pMeta
->
tuid
,
0
);
EXPECT_EQ
(
pMeta
->
suid
,
0
);
}
pos += sizeof(VarDataLenT);
strVal = (char*)(pData + pos);
pos += TSDB_USER_LEN;
EXPECT_STREQ(strVal, "_root");
void
CheckSchema
(
int32_t
index
,
int8_t
type
,
int32_t
bytes
,
const
char
*
name
)
{
SSchema
*
pSchema
=
&
pMeta
->
pSchema
[
index
];
pSchema
->
bytes
=
htons
(
pSchema
->
bytes
);
EXPECT_EQ
(
pSchema
->
colId
,
0
);
EXPECT_EQ
(
pSchema
->
type
,
type
);
EXPECT_EQ
(
pSchema
->
bytes
,
bytes
);
EXPECT_STREQ
(
pSchema
->
name
,
name
);
}
//--- privilege ---
{
pos += sizeof(VarDataLenT);
strVal = (char*)(pData + pos);
pos += 10;
EXPECT_STREQ(strVal, "super");
void
SendThenCheckShowRetrieveMsg
(
int32_t
rows
)
{
SRetrieveTableMsg
*
pRetrieve
=
(
SRetrieveTableMsg
*
)
rpcMallocCont
(
sizeof
(
SRetrieveTableMsg
));
pRetrieve
->
showId
=
htonl
(
showId
);
pRetrieve
->
free
=
0
;
SRpcMsg
retrieveRpcMsg
=
{
0
};
retrieveRpcMsg
.
pCont
=
pRetrieve
;
retrieveRpcMsg
.
contLen
=
sizeof
(
SRetrieveTableMsg
);
retrieveRpcMsg
.
msgType
=
TSDB_MSG_TYPE_SHOW_RETRIEVE
;
sendMsg
(
pClient
,
&
retrieveRpcMsg
);
ASSERT_NE
(
pClient
->
pRsp
,
nullptr
);
ASSERT_EQ
(
pClient
->
pRsp
->
code
,
0
);
ASSERT_NE
(
pClient
->
pRsp
->
pCont
,
nullptr
);
pRetrieveRsp
=
(
SRetrieveTableRsp
*
)
pClient
->
pRsp
->
pCont
;
ASSERT_NE
(
pRetrieveRsp
,
nullptr
);
pRetrieveRsp
->
numOfRows
=
htonl
(
pRetrieveRsp
->
numOfRows
);
pRetrieveRsp
->
offset
=
htobe64
(
pRetrieveRsp
->
offset
);
pRetrieveRsp
->
useconds
=
htobe64
(
pRetrieveRsp
->
useconds
);
pRetrieveRsp
->
compLen
=
htonl
(
pRetrieveRsp
->
compLen
);
EXPECT_EQ
(
pRetrieveRsp
->
numOfRows
,
rows
);
EXPECT_EQ
(
pRetrieveRsp
->
offset
,
0
);
EXPECT_EQ
(
pRetrieveRsp
->
useconds
,
0
);
// EXPECT_EQ(pRetrieveRsp->completed, completed);
EXPECT_EQ
(
pRetrieveRsp
->
precision
,
TSDB_TIME_PRECISION_MILLI
);
EXPECT_EQ
(
pRetrieveRsp
->
compressed
,
0
);
EXPECT_EQ
(
pRetrieveRsp
->
reserved
,
0
);
EXPECT_EQ
(
pRetrieveRsp
->
compLen
,
0
);
pData
=
pRetrieveRsp
->
data
;
pos
=
0
;
}
pos += sizeof(VarDataLenT);
strVal = (char*)(pData + pos
);
pos +=
10
;
EXPECT_
STREQ(strVal, "writable"
);
void
CheckInt16
(
int16_t
val
)
{
int16_t
data
=
*
((
int16_t
*
)(
pData
+
pos
)
);
pos
+=
sizeof
(
int16_t
)
;
EXPECT_
EQ
(
data
,
val
);
}
//--- create_time ---
{
int64Val = *((int64_t*)(pData + pos));
void
CheckInt64
(
int64_t
val
)
{
int64_t
data
=
*
((
int64_t
*
)(
pData
+
pos
));
pos
+=
sizeof
(
int64_t
);
EXPECT_GT(int64Val, 0);
EXPECT_EQ
(
data
,
val
);
}
int64Val = *((int64_t*)(pData + pos));
void
CheckTimestamp
()
{
int64_t
data
=
*
((
int64_t
*
)(
pData
+
pos
));
pos
+=
sizeof
(
int64_t
);
EXPECT_GT(
int64Val
, 0);
EXPECT_GT
(
data
,
0
);
}
//--- account ---
{
pos += sizeof(VarDataLenT);
strVal = (char*)(pData + pos);
pos += TSDB_USER_LEN;
EXPECT_STREQ(strVal, "root");
void
CheckBinary
(
const
char
*
val
,
int32_t
len
)
{
pos
+=
sizeof
(
VarDataLenT
);
strVal
= (char*)(pData + pos);
pos +=
TSDB_USER_LEN
;
EXPECT_STREQ(
strVal, "root"
);
char
*
data
=
(
char
*
)(
pData
+
pos
);
pos
+=
len
;
EXPECT_STREQ
(
data
,
val
);
}
}
#endif
TEST_F
(
DndTestUser
,
CreateUser_01
)
{
ASSERT_NE
(
pClient
,
nullptr
);
//--- create user ---
SCreateUserMsg
*
pReq
=
(
SCreateUserMsg
*
)
rpcMallocCont
(
sizeof
(
SCreateUserMsg
));
strcpy
(
pReq
->
user
,
"u1"
);
strcpy
(
pReq
->
pass
,
"p1"
);
int32_t
showId
;
STableMetaMsg
*
pMeta
;
SRetrieveTableRsp
*
pRetrieveRsp
;
char
*
pData
;
int32_t
pos
;
};
SRpcMsg
rpcMsg
=
{
0
};
rpcMsg
.
pCont
=
pReq
;
rpcMsg
.
contLen
=
sizeof
(
SCreateUserMsg
);
rpcMsg
.
msgType
=
TSDB_MSG_TYPE_CREATE_USER
;
SServer
*
DndTestUser
::
pServer
;
SClient
*
DndTestUser
::
pClient
;
int32_t
DndTestUser
::
connId
;
sendMsg
(
pClient
,
&
rpcMsg
);
SRpcMsg
*
pMsg
=
pClient
->
pRsp
;
ASSERT_NE
(
pMsg
,
nullptr
);
ASSERT_EQ
(
pMsg
->
code
,
0
);
TEST_F
(
DndTestUser
,
ShowUser
)
{
SendTheCheckShowMetaMsg
(
TSDB_MGMT_TABLE_USER
,
"show users"
,
4
);
CheckSchema
(
0
,
TSDB_DATA_TYPE_BINARY
,
TSDB_USER_LEN
+
VARSTR_HEADER_SIZE
,
"name"
);
CheckSchema
(
1
,
TSDB_DATA_TYPE_BINARY
,
10
+
VARSTR_HEADER_SIZE
,
"privilege"
);
CheckSchema
(
2
,
TSDB_DATA_TYPE_TIMESTAMP
,
8
,
"create time"
);
CheckSchema
(
3
,
TSDB_DATA_TYPE_BINARY
,
TSDB_USER_LEN
+
VARSTR_HEADER_SIZE
,
"account"
);
SendThenCheckShowRetrieveMsg
(
1
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"super"
,
10
);
CheckTimestamp
();
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
}
//--- meta ---
SShowMsg
*
pShow
=
(
SShowMsg
*
)
rpcMallocCont
(
sizeof
(
SShowMsg
));
pShow
->
type
=
TSDB_MGMT_TABLE_USER
;
SRpcMsg
showRpcMsg
=
{
0
};
showRpcMsg
.
pCont
=
pShow
;
showRpcMsg
.
contLen
=
sizeof
(
SShowMsg
);
showRpcMsg
.
msgType
=
TSDB_MSG_TYPE_SHOW
;
sendMsg
(
pClient
,
&
showRpcMsg
);
SShowRsp
*
pShowRsp
=
(
SShowRsp
*
)
pClient
->
pRsp
->
pCont
;
STableMetaMsg
*
pMeta
=
&
pShowRsp
->
tableMeta
;
pMeta
->
numOfColumns
=
htons
(
pMeta
->
numOfColumns
);
EXPECT_EQ
(
pMeta
->
numOfColumns
,
4
);
//--- retrieve ---
SRetrieveTableMsg
*
pRetrieve
=
(
SRetrieveTableMsg
*
)
rpcMallocCont
(
sizeof
(
SRetrieveTableMsg
));
pRetrieve
->
showId
=
pShowRsp
->
showId
;
SRpcMsg
retrieveRpcMsg
=
{
0
};
retrieveRpcMsg
.
pCont
=
pRetrieve
;
retrieveRpcMsg
.
contLen
=
sizeof
(
SRetrieveTableMsg
);
retrieveRpcMsg
.
msgType
=
TSDB_MSG_TYPE_SHOW_RETRIEVE
;
sendMsg
(
pClient
,
&
retrieveRpcMsg
);
SRetrieveTableRsp
*
pRetrieveRsp
=
(
SRetrieveTableRsp
*
)
pClient
->
pRsp
->
pCont
;
pRetrieveRsp
->
numOfRows
=
htonl
(
pRetrieveRsp
->
numOfRows
);
EXPECT_EQ
(
pRetrieveRsp
->
numOfRows
,
3
);
char
*
pData
=
pRetrieveRsp
->
data
;
int32_t
pos
=
0
;
char
*
strVal
=
NULL
;
//--- name ---
TEST_F
(
DndTestUser
,
CreateUser_01
)
{
{
pos
+=
sizeof
(
VarDataLenT
);
strVal
=
(
char
*
)(
pData
+
pos
);
pos
+=
TSDB_USER_LEN
;
EXPECT_STREQ
(
strVal
,
"u1"
);
pos
+=
sizeof
(
VarDataLenT
);
strVal
=
(
char
*
)(
pData
+
pos
);
pos
+=
TSDB_USER_LEN
;
EXPECT_STREQ
(
strVal
,
"root"
);
SCreateUserMsg
*
pReq
=
(
SCreateUserMsg
*
)
rpcMallocCont
(
sizeof
(
SCreateUserMsg
));
strcpy
(
pReq
->
user
,
"u1"
);
strcpy
(
pReq
->
pass
,
"p1"
);
SRpcMsg
rpcMsg
=
{
0
};
rpcMsg
.
pCont
=
pReq
;
rpcMsg
.
contLen
=
sizeof
(
SCreateUserMsg
);
rpcMsg
.
msgType
=
TSDB_MSG_TYPE_CREATE_USER
;
sendMsg
(
pClient
,
&
rpcMsg
);
SRpcMsg
*
pMsg
=
pClient
->
pRsp
;
ASSERT_NE
(
pMsg
,
nullptr
);
ASSERT_EQ
(
pMsg
->
code
,
0
);
}
pos
+=
sizeof
(
VarDataLenT
);
strVal
=
(
char
*
)(
pData
+
pos
);
pos
+=
TSDB_USER_LEN
;
EXPECT_STREQ
(
strVal
,
"_root"
);
{
SCreateUserMsg
*
pReq
=
(
SCreateUserMsg
*
)
rpcMallocCont
(
sizeof
(
SCreateUserMsg
));
strcpy
(
pReq
->
user
,
"u2"
);
strcpy
(
pReq
->
pass
,
"p2"
);
SRpcMsg
rpcMsg
=
{
0
};
rpcMsg
.
pCont
=
pReq
;
rpcMsg
.
contLen
=
sizeof
(
SCreateUserMsg
);
rpcMsg
.
msgType
=
TSDB_MSG_TYPE_CREATE_USER
;
sendMsg
(
pClient
,
&
rpcMsg
);
SRpcMsg
*
pMsg
=
pClient
->
pRsp
;
ASSERT_NE
(
pMsg
,
nullptr
);
ASSERT_EQ
(
pMsg
->
code
,
0
);
}
SendTheCheckShowMetaMsg
(
TSDB_MGMT_TABLE_USER
,
"show users"
,
4
);
SendThenCheckShowRetrieveMsg
(
3
);
CheckBinary
(
"u1"
,
TSDB_USER_LEN
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"u2"
,
TSDB_USER_LEN
);
CheckBinary
(
"normal"
,
10
);
CheckBinary
(
"super"
,
10
);
CheckBinary
(
"normal"
,
10
);
CheckTimestamp
();
CheckTimestamp
();
CheckTimestamp
();
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
}
TEST_F
(
DndTestUser
,
AlterUser_01
)
{
ASSERT_NE
(
pClient
,
nullptr
);
//--- drop user ---
SAlterUserMsg
*
pReq
=
(
SAlterUserMsg
*
)
rpcMallocCont
(
sizeof
(
SAlterUserMsg
));
strcpy
(
pReq
->
user
,
"u1"
);
strcpy
(
pReq
->
pass
,
"p2"
);
...
...
@@ -295,60 +248,23 @@ TEST_F(DndTestUser, AlterUser_01) {
ASSERT_NE
(
pMsg
,
nullptr
);
ASSERT_EQ
(
pMsg
->
code
,
0
);
//--- meta ---
SShowMsg
*
pShow
=
(
SShowMsg
*
)
rpcMallocCont
(
sizeof
(
SShowMsg
));
pShow
->
type
=
TSDB_MGMT_TABLE_USER
;
SRpcMsg
showRpcMsg
=
{
0
};
showRpcMsg
.
pCont
=
pShow
;
showRpcMsg
.
contLen
=
sizeof
(
SShowMsg
);
showRpcMsg
.
msgType
=
TSDB_MSG_TYPE_SHOW
;
sendMsg
(
pClient
,
&
showRpcMsg
);
SShowRsp
*
pShowRsp
=
(
SShowRsp
*
)
pClient
->
pRsp
->
pCont
;
STableMetaMsg
*
pMeta
=
&
pShowRsp
->
tableMeta
;
pMeta
->
numOfColumns
=
htons
(
pMeta
->
numOfColumns
);
EXPECT_EQ
(
pMeta
->
numOfColumns
,
4
);
//--- retrieve ---
SRetrieveTableMsg
*
pRetrieve
=
(
SRetrieveTableMsg
*
)
rpcMallocCont
(
sizeof
(
SRetrieveTableMsg
));
pRetrieve
->
showId
=
pShowRsp
->
showId
;
SRpcMsg
retrieveRpcMsg
=
{
0
};
retrieveRpcMsg
.
pCont
=
pRetrieve
;
retrieveRpcMsg
.
contLen
=
sizeof
(
SRetrieveTableMsg
);
retrieveRpcMsg
.
msgType
=
TSDB_MSG_TYPE_SHOW_RETRIEVE
;
sendMsg
(
pClient
,
&
retrieveRpcMsg
);
SRetrieveTableRsp
*
pRetrieveRsp
=
(
SRetrieveTableRsp
*
)
pClient
->
pRsp
->
pCont
;
pRetrieveRsp
->
numOfRows
=
htonl
(
pRetrieveRsp
->
numOfRows
);
EXPECT_EQ
(
pRetrieveRsp
->
numOfRows
,
3
);
char
*
pData
=
pRetrieveRsp
->
data
;
int32_t
pos
=
0
;
char
*
strVal
=
NULL
;
//--- name ---
{
pos
+=
sizeof
(
VarDataLenT
);
strVal
=
(
char
*
)(
pData
+
pos
);
pos
+=
TSDB_USER_LEN
;
EXPECT_STREQ
(
strVal
,
"u1"
);
pos
+=
sizeof
(
VarDataLenT
);
strVal
=
(
char
*
)(
pData
+
pos
);
pos
+=
TSDB_USER_LEN
;
EXPECT_STREQ
(
strVal
,
"root"
);
pos
+=
sizeof
(
VarDataLenT
);
strVal
=
(
char
*
)(
pData
+
pos
);
pos
+=
TSDB_USER_LEN
;
EXPECT_STREQ
(
strVal
,
"_root"
);
}
SendTheCheckShowMetaMsg
(
TSDB_MGMT_TABLE_USER
,
"show users"
,
4
);
SendThenCheckShowRetrieveMsg
(
3
);
CheckBinary
(
"u1"
,
TSDB_USER_LEN
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"u2"
,
TSDB_USER_LEN
);
CheckBinary
(
"normal"
,
10
);
CheckBinary
(
"super"
,
10
);
CheckBinary
(
"normal"
,
10
);
CheckTimestamp
();
CheckTimestamp
();
CheckTimestamp
();
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
}
TEST_F
(
DndTestUser
,
DropUser_01
)
{
ASSERT_NE
(
pClient
,
nullptr
);
//--- drop user ---
SDropUserMsg
*
pReq
=
(
SDropUserMsg
*
)
rpcMallocCont
(
sizeof
(
SDropUserMsg
));
strcpy
(
pReq
->
user
,
"u1"
);
...
...
@@ -362,47 +278,38 @@ TEST_F(DndTestUser, DropUser_01) {
ASSERT_NE
(
pMsg
,
nullptr
);
ASSERT_EQ
(
pMsg
->
code
,
0
);
//--- meta ---
SShowMsg
*
pShow
=
(
SShowMsg
*
)
rpcMallocCont
(
sizeof
(
SShowMsg
));
pShow
->
type
=
TSDB_MGMT_TABLE_USER
;
SRpcMsg
showRpcMsg
=
{
0
};
showRpcMsg
.
pCont
=
pShow
;
showRpcMsg
.
contLen
=
sizeof
(
SShowMsg
);
showRpcMsg
.
msgType
=
TSDB_MSG_TYPE_SHOW
;
sendMsg
(
pClient
,
&
showRpcMsg
);
SShowRsp
*
pShowRsp
=
(
SShowRsp
*
)
pClient
->
pRsp
->
pCont
;
STableMetaMsg
*
pMeta
=
&
pShowRsp
->
tableMeta
;
pMeta
->
numOfColumns
=
htons
(
pMeta
->
numOfColumns
);
EXPECT_EQ
(
pMeta
->
numOfColumns
,
4
);
//--- retrieve ---
SRetrieveTableMsg
*
pRetrieve
=
(
SRetrieveTableMsg
*
)
rpcMallocCont
(
sizeof
(
SRetrieveTableMsg
));
pRetrieve
->
showId
=
pShowRsp
->
showId
;
SRpcMsg
retrieveRpcMsg
=
{
0
};
retrieveRpcMsg
.
pCont
=
pRetrieve
;
retrieveRpcMsg
.
contLen
=
sizeof
(
SRetrieveTableMsg
);
retrieveRpcMsg
.
msgType
=
TSDB_MSG_TYPE_SHOW_RETRIEVE
;
sendMsg
(
pClient
,
&
retrieveRpcMsg
);
SRetrieveTableRsp
*
pRetrieveRsp
=
(
SRetrieveTableRsp
*
)
pClient
->
pRsp
->
pCont
;
pRetrieveRsp
->
numOfRows
=
htonl
(
pRetrieveRsp
->
numOfRows
);
EXPECT_EQ
(
pRetrieveRsp
->
numOfRows
,
2
);
char
*
pData
=
pRetrieveRsp
->
data
;
int32_t
pos
=
0
;
char
*
strVal
=
NULL
;
//--- name ---
{
pos
+=
sizeof
(
VarDataLenT
);
strVal
=
(
char
*
)(
pData
+
pos
);
pos
+=
TSDB_USER_LEN
;
EXPECT_STREQ
(
strVal
,
"root"
);
SendTheCheckShowMetaMsg
(
TSDB_MGMT_TABLE_USER
,
"show users"
,
4
);
SendThenCheckShowRetrieveMsg
(
2
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"u2"
,
TSDB_USER_LEN
);
CheckBinary
(
"super"
,
10
);
CheckBinary
(
"normal"
,
10
);
CheckTimestamp
();
CheckTimestamp
();
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
}
pos
+=
sizeof
(
VarDataLenT
);
strVal
=
(
char
*
)(
pData
+
pos
);
pos
+=
TSDB_USER_LEN
;
EXPECT_STREQ
(
strVal
,
"_root"
);
}
}
\ No newline at end of file
TEST_F
(
DndTestUser
,
RestartDnode
)
{
stopServer
(
pServer
);
pServer
=
NULL
;
uInfo
(
"start all server"
);
const
char
*
fqdn
=
"localhost"
;
const
char
*
firstEp
=
"localhost:9530"
;
pServer
=
startServer
(
"/tmp/dndTestUser"
,
fqdn
,
9530
,
firstEp
);
uInfo
(
"all server is running"
);
SendTheCheckShowMetaMsg
(
TSDB_MGMT_TABLE_USER
,
"show users"
,
4
);
SendThenCheckShowRetrieveMsg
(
2
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"u2"
,
TSDB_USER_LEN
);
CheckBinary
(
"super"
,
10
);
CheckBinary
(
"normal"
,
10
);
CheckTimestamp
();
CheckTimestamp
();
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
CheckBinary
(
"root"
,
TSDB_USER_LEN
);
}
source/dnode/mnode/impl/src/mndUser.c
浏览文件 @
c8ffc27e
...
...
@@ -83,9 +83,11 @@ static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
return
-
1
;
}
#if 0
if (mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, "_" TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS) != 0) {
return -1;
}
#endif
return
0
;
}
...
...
@@ -459,7 +461,7 @@ static int32_t mndGetUserMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *p
pShow
->
bytes
[
cols
]
=
8
;
pSchema
[
cols
].
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
strcpy
(
pSchema
[
cols
].
name
,
"create
_
time"
);
strcpy
(
pSchema
[
cols
].
name
,
"create
time"
);
pSchema
[
cols
].
bytes
=
htons
(
pShow
->
bytes
[
cols
]);
cols
++
;
...
...
@@ -506,12 +508,9 @@ static int32_t mndRetrieveUsers(SMnodeMsg *pMsg, SShowObj *pShow, char *data, in
if
(
pUser
->
superUser
)
{
const
char
*
src
=
"super"
;
STR_WITH_SIZE_TO_VARSTR
(
pWrite
,
src
,
strlen
(
src
));
// } else if (pUser->writeAuth) {
// const char *src = "writable";
// STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
// } else {
// const char *src = "readable";
// STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
}
else
{
const
char
*
src
=
"normal"
;
STR_WITH_SIZE_TO_VARSTR
(
pWrite
,
src
,
strlen
(
src
));
}
cols
++
;
...
...
source/dnode/mnode/sdb/src/sdb.c
浏览文件 @
c8ffc27e
...
...
@@ -52,10 +52,10 @@ SSdb *sdbInit(SSdbOpt *pOption) {
void
sdbCleanup
(
SSdb
*
pSdb
)
{
mDebug
(
"start to cleanup sdb"
);
if
(
pSdb
->
curVer
!=
pSdb
->
lastCommitVer
)
{
//
if (pSdb->curVer != pSdb->lastCommitVer) {
mDebug
(
"write sdb file for curVer:% "
PRId64
" and lastVer:%"
PRId64
,
pSdb
->
curVer
,
pSdb
->
lastCommitVer
);
sdbWriteFile
(
pSdb
);
}
//
}
if
(
pSdb
->
currDir
!=
NULL
)
{
tfree
(
pSdb
->
currDir
);
...
...
source/dnode/vnode/impl/CMakeLists.txt
浏览文件 @
c8ffc27e
...
...
@@ -18,6 +18,6 @@ target_link_libraries(
)
# test
#if(${BUILD_TEST})
# add_subdirectory(test)
#endif(${BUILD_TEST})
\ No newline at end of file
if
(
${
BUILD_TEST
}
)
add_subdirectory
(
test
)
endif
(
${
BUILD_TEST
}
)
\ No newline at end of file
source/dnode/vnode/impl/inc/vnodeBufferPool.h
浏览文件 @
c8ffc27e
...
...
@@ -28,6 +28,7 @@ typedef struct SVBufPool SVBufPool;
int
vnodeOpenBufPool
(
SVnode
*
pVnode
);
void
vnodeCloseBufPool
(
SVnode
*
pVnode
);
void
*
vnodeMalloc
(
SVnode
*
pVnode
,
uint64_t
size
);
bool
vnodeBufPoolIsFull
(
SVnode
*
pVnode
);
#ifdef __cplusplus
}
...
...
source/dnode/vnode/impl/inc/vnodeCommit.h
浏览文件 @
c8ffc27e
...
...
@@ -22,8 +22,8 @@
extern
"C"
{
#endif
bool
vnodeShouldCommit
(
SVnode
*
pVnode
);
int
vnodeAsyncCommit
(
SVnode
*
pVnode
);
#define vnodeShouldCommit vnodeBufPoolIsFull
int
vnodeAsyncCommit
(
SVnode
*
pVnode
);
#ifdef __cplusplus
}
...
...
source/dnode/vnode/impl/inc/vnodeDef.h
浏览文件 @
c8ffc27e
...
...
@@ -18,15 +18,17 @@
#include "mallocator.h"
#include "sync.h"
#include "tcoding.h"
#include "tdlist.h"
#include "tlockfree.h"
#include "wal.h"
#include "tcoding.h"
#include "vnode.h"
#include "vnodeBufferPool.h"
#include "vnodeCfg.h"
#include "vnodeCommit.h"
#include "vnodeFS.h"
#include "vnodeMemAllocator.h"
#include "vnodeRequest.h"
#include "vnodeStateMgr.h"
#include "vnodeSync.h"
...
...
source/dnode/vnode/impl/inc/vnodeMemAllocator.h
浏览文件 @
c8ffc27e
...
...
@@ -16,15 +16,37 @@
#ifndef _TD_VNODE_MEM_ALLOCATOR_H_
#define _TD_VNODE_MEM_ALLOCATOR_H_
#include "mallocator.h"
#include "vnode.h"
#include "os.h"
#ifdef __cplusplus
extern
"C"
{
#endif
SMemAllocator
*
vnodeCreateMemAllocator
(
SVnode
*
pVnode
);
void
vnodeDestroyMemAllocator
(
SMemAllocator
*
pma
);
typedef
struct
SVArenaNode
SVArenaNode
;
typedef
struct
SVMemAllocator
SVMemAllocator
;
struct
SVArenaNode
{
TD_SLIST_NODE
(
SVArenaNode
);
uint64_t
size
;
// current node size
void
*
ptr
;
char
data
[];
};
struct
SVMemAllocator
{
TD_DLIST_NODE
(
SVMemAllocator
);
uint64_t
capacity
;
uint64_t
ssize
;
uint64_t
lsize
;
SVArenaNode
*
pNode
;
TD_SLIST
(
SVArenaNode
)
nlist
;
};
SVMemAllocator
*
vmaCreate
(
uint64_t
capacity
,
uint64_t
ssize
,
uint64_t
lsize
);
void
vmaDestroy
(
SVMemAllocator
*
pVMA
);
void
vmaReset
(
SVMemAllocator
*
pVMA
);
void
*
vmaMalloc
(
SVMemAllocator
*
pVMA
,
uint64_t
size
);
void
vmaFree
(
SVMemAllocator
*
pVMA
,
void
*
ptr
);
bool
vmaIsFull
(
SVMemAllocator
*
pVMA
);
#ifdef __cplusplus
}
...
...
source/dnode/vnode/impl/src/vnodeArenaMAImpl.c
0 → 100644
浏览文件 @
c8ffc27e
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "vnodeDef.h"
static
SVArenaNode
*
vArenaNodeNew
(
uint64_t
capacity
);
static
void
vArenaNodeFree
(
SVArenaNode
*
pNode
);
SVMemAllocator
*
vmaCreate
(
uint64_t
capacity
,
uint64_t
ssize
,
uint64_t
lsize
)
{
SVMemAllocator
*
pVMA
=
(
SVMemAllocator
*
)
malloc
(
sizeof
(
*
pVMA
));
if
(
pVMA
==
NULL
)
{
return
NULL
;
}
pVMA
->
capacity
=
capacity
;
pVMA
->
ssize
=
ssize
;
pVMA
->
lsize
=
lsize
;
tSListInit
(
&
(
pVMA
->
nlist
));
pVMA
->
pNode
=
vArenaNodeNew
(
capacity
);
if
(
pVMA
->
pNode
==
NULL
)
{
free
(
pVMA
);
return
NULL
;
}
tSListPush
(
&
(
pVMA
->
nlist
),
pVMA
->
pNode
);
return
pVMA
;
}
void
vmaDestroy
(
SVMemAllocator
*
pVMA
)
{
if
(
pVMA
)
{
while
(
TD_SLIST_NELES
(
&
(
pVMA
->
nlist
))
>
1
)
{
SVArenaNode
*
pNode
=
TD_SLIST_HEAD
(
&
(
pVMA
->
nlist
));
tSListPop
(
&
(
pVMA
->
nlist
));
vArenaNodeFree
(
pNode
);
}
free
(
pVMA
);
}
}
void
vmaReset
(
SVMemAllocator
*
pVMA
)
{
while
(
TD_SLIST_NELES
(
&
(
pVMA
->
nlist
))
>
1
)
{
SVArenaNode
*
pNode
=
TD_SLIST_HEAD
(
&
(
pVMA
->
nlist
));
tSListPop
(
&
(
pVMA
->
nlist
));
vArenaNodeFree
(
pNode
);
}
SVArenaNode
*
pNode
=
TD_SLIST_HEAD
(
&
(
pVMA
->
nlist
));
pNode
->
ptr
=
pNode
->
data
;
}
void
*
vmaMalloc
(
SVMemAllocator
*
pVMA
,
uint64_t
size
)
{
SVArenaNode
*
pNode
=
TD_SLIST_HEAD
(
&
(
pVMA
->
nlist
));
void
*
ptr
;
if
(
pNode
->
size
<
POINTER_DISTANCE
(
pNode
->
ptr
,
pNode
->
data
)
+
size
)
{
uint64_t
capacity
=
MAX
(
pVMA
->
ssize
,
size
);
pNode
=
vArenaNodeNew
(
capacity
);
if
(
pNode
==
NULL
)
{
// TODO: handle error
return
NULL
;
}
tSListPush
(
&
(
pVMA
->
nlist
),
pNode
);
}
ptr
=
pNode
->
ptr
;
pNode
->
ptr
=
POINTER_SHIFT
(
ptr
,
size
);
return
ptr
;
}
void
vmaFree
(
SVMemAllocator
*
pVMA
,
void
*
ptr
)
{
// TODO
}
bool
vmaIsFull
(
SVMemAllocator
*
pVMA
)
{
SVArenaNode
*
pNode
=
TD_SLIST_HEAD
(
&
(
pVMA
->
nlist
));
return
(
TD_SLIST_NELES
(
&
(
pVMA
->
nlist
))
>
1
)
||
(
pNode
->
size
<
POINTER_DISTANCE
(
pNode
->
ptr
,
pNode
->
data
)
+
pVMA
->
lsize
);
}
/* ------------------------ STATIC METHODS ------------------------ */
static
SVArenaNode
*
vArenaNodeNew
(
uint64_t
capacity
)
{
SVArenaNode
*
pNode
=
NULL
;
pNode
=
(
SVArenaNode
*
)
malloc
(
sizeof
(
*
pNode
)
+
capacity
);
if
(
pNode
==
NULL
)
{
return
NULL
;
}
pNode
->
size
=
capacity
;
pNode
->
ptr
=
pNode
->
data
;
return
pNode
;
}
static
void
vArenaNodeFree
(
SVArenaNode
*
pNode
)
{
if
(
pNode
)
{
free
(
pNode
);
}
}
\ No newline at end of file
source/dnode/vnode/impl/src/vnodeBufferPool.c
浏览文件 @
c8ffc27e
...
...
@@ -19,110 +19,59 @@
#define VNODE_BUF_POOL_SHARDS 3
struct
SVBufPool
{
// buffer pool impl
SList
free
;
SList
incycle
;
SListNode
*
inuse
;
TD_DLIST
(
SVMemAllocator
)
free
;
TD_DLIST
(
SVMemAllocator
)
incycle
;
SVMemAllocator
*
inuse
;
// MAF for submodules
SMemAllocatorFactory
maf
;
//
SMemAllocatorFactory maf;
};
typedef
enum
{
// Heap allocator
E_V_HEAP_ALLOCATOR
=
0
,
// Arena allocator
E_V_ARENA_ALLOCATOR
}
EVMemAllocatorT
;
typedef
struct
{
/* TODO */
}
SVHeapAllocator
;
typedef
struct
SVArenaNode
{
struct
SVArenaNode
*
prev
;
uint64_t
size
;
void
*
ptr
;
char
data
[];
}
SVArenaNode
;
typedef
struct
{
uint64_t
ssize
;
// step size
uint64_t
lsize
;
// limit size
SVArenaNode
*
inuse
;
SVArenaNode
node
;
}
SVArenaAllocator
;
typedef
struct
{
SVnode
*
pVnode
;
SListNode
*
pNode
;
}
SVMAWrapper
;
typedef
struct
{
T_REF_DECLARE
()
uint64_t
capacity
;
EVMemAllocatorT
type
;
union
{
SVHeapAllocator
vha
;
SVArenaAllocator
vaa
;
};
}
SVMemAllocator
;
static
SListNode
*
vBufPoolNewNode
(
uint64_t
capacity
,
EVMemAllocatorT
type
);
static
void
vBufPoolFreeNode
(
SListNode
*
pNode
);
static
SMemAllocator
*
vBufPoolCreateMA
(
SMemAllocatorFactory
*
pmaf
);
static
void
vBufPoolDestroyMA
(
SMemAllocatorFactory
*
pmaf
,
SMemAllocator
*
pma
);
static
void
*
vBufPoolMalloc
(
SVMemAllocator
*
pvma
,
uint64_t
size
);
int
vnodeOpenBufPool
(
SVnode
*
pVnode
)
{
uint64_t
capacity
;
EVMemAllocatorT
type
=
E_V_ARENA_ALLOCATOR
;
uint64_t
capacity
;
//
EVMemAllocatorT type = E_V_ARENA_ALLOCATOR;
if
((
pVnode
->
pBufPool
=
(
SVBufPool
*
)
calloc
(
1
,
sizeof
(
SVBufPool
)))
==
NULL
)
{
/* TODO */
return
-
1
;
}
t
dListInit
(
&
(
pVnode
->
pBufPool
->
free
),
0
);
t
dListInit
(
&
(
pVnode
->
pBufPool
->
incycle
),
0
);
t
DListInit
(
&
(
pVnode
->
pBufPool
->
free
)
);
t
DListInit
(
&
(
pVnode
->
pBufPool
->
incycle
)
);
pVnode
->
pBufPool
->
inuse
=
NULL
;
// TODO
capacity
=
pVnode
->
config
.
wsize
/
VNODE_BUF_POOL_SHARDS
;
if
(
pVnode
->
config
.
isHeapAllocator
)
{
type
=
E_V_HEAP_ALLOCATOR
;
}
for
(
int
i
=
0
;
i
<
VNODE_BUF_POOL_SHARDS
;
i
++
)
{
S
ListNode
*
pNode
=
vBufPoolNewNode
(
capacity
,
typ
e
);
if
(
p
Node
==
NULL
)
{
vnodeCloseBufPool
(
pVnode
);
S
VMemAllocator
*
pVMA
=
vmaCreate
(
capacity
,
pVnode
->
config
.
ssize
,
pVnode
->
config
.
lsiz
e
);
if
(
p
VMA
==
NULL
)
{
// TODO: handle error
return
-
1
;
}
t
dListAppendNode
(
&
(
pVnode
->
pBufPool
->
free
),
pNode
);
t
DListAppend
(
&
(
pVnode
->
pBufPool
->
free
),
pVMA
);
}
pVnode
->
pBufPool
->
maf
.
impl
=
pVnode
;
pVnode
->
pBufPool
->
maf
.
create
=
vBufPoolCreateMA
;
pVnode
->
pBufPool
->
maf
.
destroy
=
vBufPoolDestroyMA
;
return
0
;
}
void
vnodeCloseBufPool
(
SVnode
*
pVnode
)
{
SListNode
*
pNode
;
if
(
pVnode
->
pBufPool
)
{
// Clear free list
while
((
pNode
=
tdListPopHead
(
&
(
pVnode
->
pBufPool
->
free
)))
!=
NULL
)
{
vBufPoolFreeNode
(
pNode
);
}
vmaDestroy
(
pVnode
->
pBufPool
->
inuse
);
// Clear incycle list
while
((
pNode
=
tdListPopHead
(
&
(
pVnode
->
pBufPool
->
incycle
)))
!=
NULL
)
{
vBufPoolFreeNode
(
pNode
);
while
(
true
)
{
SVMemAllocator
*
pVMA
=
TD_DLIST_HEAD
(
&
(
pVnode
->
pBufPool
->
incycle
));
if
(
pVMA
==
NULL
)
break
;
tDListPop
(
&
(
pVnode
->
pBufPool
->
incycle
),
pVMA
);
vmaDestroy
(
pVMA
);
}
// Free inuse node
if
(
pVnode
->
pBufPool
->
inuse
)
{
vBufPoolFreeNode
(
pVnode
->
pBufPool
->
inuse
);
while
(
true
)
{
SVMemAllocator
*
pVMA
=
TD_DLIST_HEAD
(
&
(
pVnode
->
pBufPool
->
free
));
if
(
pVMA
==
NULL
)
break
;
tDListPop
(
&
(
pVnode
->
pBufPool
->
free
),
pVMA
);
vmaDestroy
(
pVMA
);
}
free
(
pVnode
->
pBufPool
);
...
...
@@ -131,48 +80,73 @@ void vnodeCloseBufPool(SVnode *pVnode) {
}
void
*
vnodeMalloc
(
SVnode
*
pVnode
,
uint64_t
size
)
{
void
*
ptr
;
if
(
pVnode
->
pBufPool
->
inuse
==
NULL
)
{
SListNode
*
pNode
;
while
((
pNode
=
tdListPopHead
(
&
(
pVnode
->
pBufPool
->
free
)))
==
NULL
)
{
// todo
// tsem_wait();
ASSERT
(
0
);
SVBufPool
*
pBufPool
=
pVnode
->
pBufPool
;
if
(
pBufPool
->
inuse
==
NULL
)
{
while
(
true
)
{
// TODO: add sem_wait and sem_post
pBufPool
->
inuse
=
TD_DLIST_HEAD
(
&
(
pBufPool
->
free
));
if
(
pBufPool
->
inuse
)
{
tDListPop
(
&
(
pBufPool
->
free
),
pBufPool
->
inuse
);
break
;
}
}
pVnode
->
pBufPool
->
inuse
=
pNode
;
}
SVMemAllocator
*
pvma
=
(
SVMemAllocator
*
)(
pVnode
->
pBufPool
->
inuse
->
data
);
return
vBufPoolMalloc
(
pvma
,
size
);
return
vmaMalloc
(
pBufPool
->
inuse
,
size
);
}
/* ------------------------ STATIC METHODS ------------------------ */
static
void
vArenaAllocatorInit
(
SVArenaAllocator
*
pvaa
,
uint64_t
capacity
,
uint64_t
ssize
,
uint64_t
lsize
)
{
/* TODO */
pvaa
->
ssize
=
ssize
;
pvaa
->
lsize
=
lsize
;
pvaa
->
inuse
=
&
pvaa
->
node
;
pvaa
->
node
.
prev
=
NULL
;
pvaa
->
node
.
size
=
capacity
;
pvaa
->
node
.
ptr
=
pvaa
->
node
.
data
;
bool
vnodeBufPoolIsFull
(
SVnode
*
pVnode
)
{
if
(
pVnode
->
pBufPool
->
inuse
==
NULL
)
return
false
;
return
vmaIsFull
(
pVnode
->
pBufPool
->
inuse
);
}
static
void
vArenaAllocatorClear
(
SVArenaAllocator
*
pvaa
)
{
/* TODO */
while
(
pvaa
->
inuse
!=
&
(
pvaa
->
node
))
{
SVArenaNode
*
pANode
=
pvaa
->
inuse
;
pvaa
->
inuse
=
pANode
->
prev
;
free
(
pANode
);
}
}
#if 0
typedef enum {
// Heap allocator
E_V_HEAP_ALLOCATOR = 0,
// Arena allocator
E_V_ARENA_ALLOCATOR
} EVMemAllocatorT;
typedef struct {
/* TODO */
} SVHeapAllocator;
typedef struct SVArenaNode {
struct SVArenaNode *prev;
uint64_t size;
void * ptr;
char data[];
} SVArenaNode;
typedef struct {
uint64_t ssize; // step size
uint64_t lsize; // limit size
SVArenaNode *inuse;
SVArenaNode node;
} SVArenaAllocator;
typedef struct {
SVnode * pVnode;
SListNode *pNode;
} SVMAWrapper;
static SListNode * vBufPoolNewNode(uint64_t capacity, EVMemAllocatorT type);
static void vBufPoolFreeNode(SListNode *pNode);
static SMemAllocator *vBufPoolCreateMA(SMemAllocatorFactory *pmaf);
static void vBufPoolDestroyMA(SMemAllocatorFactory *pmaf, SMemAllocator *pma);
static void * vBufPoolMalloc(SVMemAllocator *pvma, uint64_t size);
/* ------------------------ STATIC METHODS ------------------------ */
static SListNode *vBufPoolNewNode(uint64_t capacity, EVMemAllocatorT type) {
SListNode * pNode;
SVMemAllocator *pvma;
uint64_t msize;
uint64_t
ssize
=
0
;
// TODO
uint64_t
lsize
=
0
;
// TODO
uint64_t ssize =
4096
; // TODO
uint64_t lsize =
1024
; // TODO
msize = sizeof(SListNode) + sizeof(SVMemAllocator);
if (type == E_V_ARENA_ALLOCATOR) {
...
...
@@ -317,4 +291,5 @@ static void vBufPoolDestroyMA(SMemAllocatorFactory *pmaf, SMemAllocator *pma) {
tdListAppendNode(&(pVnode->pBufPool->free), tdListPopNode(&(pVnode->pBufPool->incycle), pNode));
// tsem_post(); todo: sem_post
}
}
\ No newline at end of file
}
#endif
\ No newline at end of file
source/dnode/vnode/impl/src/vnodeCfg.c
浏览文件 @
c8ffc27e
...
...
@@ -15,7 +15,7 @@
#include "vnodeDef.h"
const
SVnodeCfg
defaultVnodeOptions
=
{
0
};
/* TODO */
const
SVnodeCfg
defaultVnodeOptions
=
{
.
wsize
=
16
*
1024
*
1024
,
.
walCfg
=
{.
level
=
TAOS_WAL_WRITE
}
};
/* TODO */
void
vnodeOptionsInit
(
SVnodeCfg
*
pVnodeOptions
)
{
/* TODO */
vnodeOptionsCopy
(
pVnodeOptions
,
&
defaultVnodeOptions
);
...
...
source/dnode/vnode/impl/src/vnodeCommit.c
浏览文件 @
c8ffc27e
...
...
@@ -18,8 +18,6 @@
static
int
vnodeStartCommit
(
SVnode
*
pVnode
);
static
int
vnodeEndCommit
(
SVnode
*
pVnode
);
bool
vnodeShouldCommit
(
SVnode
*
pVnode
)
{
return
false
;
}
int
vnodeAsyncCommit
(
SVnode
*
pVnode
)
{
#if 0
if (vnodeStartCommit(pVnode) < 0) {
...
...
source/dnode/vnode/impl/src/vnodeMain.c
浏览文件 @
c8ffc27e
...
...
@@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tmacro.h"
#include "vnodeDef.h"
static
SVnode
*
vnodeNew
(
const
char
*
path
,
const
SVnodeCfg
*
pVnodeCfg
);
...
...
@@ -20,8 +21,14 @@ static void vnodeFree(SVnode *pVnode);
static
int
vnodeOpenImpl
(
SVnode
*
pVnode
);
static
void
vnodeCloseImpl
(
SVnode
*
pVnode
);
TD_DEF_MOD_INIT_FLAG
(
vnode
);
TD_DEF_MOD_CLEAR_FLAG
(
vnode
);
int
vnodeInit
()
{
// TODO
if
(
TD_CHECK_AND_SET_MODE_INIT
(
vnode
)
==
TD_MOD_INITIALIZED
)
{
return
0
;
}
if
(
walInit
()
<
0
)
{
return
-
1
;
}
...
...
@@ -30,6 +37,10 @@ int vnodeInit() {
}
void
vnodeClear
()
{
if
(
TD_CHECK_AND_SET_MOD_CLEAR
(
vnode
)
==
TD_MOD_CLEARD
)
{
return
;
}
walCleanUp
();
}
...
...
source/dnode/vnode/impl/src/vnodeMemAllocator.c
已删除
100644 → 0
浏览文件 @
fb5db901
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "vnodeDef.h"
SMemAllocator
*
vnodeCreateMemAllocator
(
SVnode
*
pVnode
)
{
SMemAllocator
*
pma
=
NULL
;
/* TODO */
return
pma
;
}
void
vnodeDestroyMemAllocator
(
SMemAllocator
*
pma
)
{
// TODO
}
#if 0
#define VNODE_HEAP_ALLOCATOR 0
#define VNODE_ARENA_ALLOCATOR 1
typedef struct {
uint64_t tsize;
uint64_t used;
} SVHeapAllocator;
typedef struct SVArenaNode {
struct SVArenaNode *prev;
void * nptr;
char data[];
} SVArenaNode;
typedef struct {
SVArenaNode *inuse;
SVArenaNode node;
} SVArenaAllocator;
typedef struct {
int8_t type;
uint64_t tsize;
T_REF_DECLARE()
union {
SVHeapAllocator vha;
SVArenaAllocator vaa;
};
} SVMemAllocator;
SMemAllocator *vnodeCreateMemAllocator(int8_t type, uint64_t tsize, uint64_t ssize /* step size only for arena */) {
SMemAllocator * pma;
uint64_t msize;
SVMemAllocator *pva;
msize = sizeof(*pma) + sizeof(SVMemAllocator);
if (type == VNODE_ARENA_ALLOCATOR) {
msize += tsize;
}
pma = (SMemAllocator *)calloc(1, msize);
if (pma == NULL) {
return NULL;
}
pma->impl = POINTER_SHIFT(pma, sizeof(*pma));
pva = (SVMemAllocator *)(pma->impl);
pva->type = type;
pva->tsize = tsize;
if (type == VNODE_HEAP_ALLOCATOR) {
pma->malloc = NULL;
pma->calloc = NULL;
pma->realloc = NULL;
pma->free = NULL;
pma->usage = NULL;
} else if (type == VNODE_ARENA_ALLOCATOR) {
pma->malloc = NULL;
pma->calloc = NULL;
pma->realloc = NULL;
pma->free = NULL;
pma->usage = NULL;
} else {
ASSERT(0);
}
return pma;
}
void vnodeDestroyMemAllocator(SMemAllocator *pma) {
// TODO
}
void vnodeRefMemAllocator(SMemAllocator *pma) {
// TODO
}
void vnodeUnrefMemAllocator(SMemAllocator *pma) {
// TODO
}
/* ------------------------ Heap Allocator IMPL ------------------------ */
/* ------------------------ Arena Allocator IMPL ------------------------ */
#endif
\ No newline at end of file
source/dnode/vnode/impl/test/CMakeLists.txt
浏览文件 @
c8ffc27e
...
...
@@ -4,4 +4,9 @@ target_sources(vnodeApiTests
PRIVATE
"vnodeApiTests.cpp"
)
target_link_libraries
(
vnodeApiTests vnode gtest gtest_main
)
\ No newline at end of file
target_link_libraries
(
vnodeApiTests vnode gtest gtest_main
)
add_test
(
NAME vnode_api_tests
COMMAND
${
CMAKE_CURRENT_BINARY_DIR
}
/vnodeApiTests
)
\ No newline at end of file
source/dnode/vnode/impl/test/vnodeApiTests.cpp
浏览文件 @
c8ffc27e
/**
* @file vnodeApiTests.cpp
* @author hzcheng (hzcheng@taosdata.com)
* @brief VNODE module API tests
* @version 0.1
* @date 2021-12-13
*
* @copyright Copyright (c) 2021
*
*/
#include <gtest/gtest.h>
#include <iostream>
...
...
source/libs/parser/inc/dataBlockMgt.h
浏览文件 @
c8ffc27e
...
...
@@ -75,16 +75,7 @@ typedef struct {
SMemRowInfo
*
rowInfo
;
}
SMemRowBuilder
;
typedef
struct
SParamInfo
{
int32_t
idx
;
uint8_t
type
;
uint8_t
timePrec
;
int16_t
bytes
;
uint32_t
offset
;
}
SParamInfo
;
typedef
struct
STableDataBlocks
{
SName
tableName
;
int8_t
tsSource
;
// where does the UNIX timestamp come from, server or client
bool
ordered
;
// if current rows are ordered or not
int64_t
vgId
;
// virtual group id
...
...
@@ -100,11 +91,6 @@ typedef struct STableDataBlocks {
STagData
tagData
;
SParsedDataColInfo
boundColumnInfo
;
// for parameter ('?') binding
uint32_t
numOfAllocedParams
;
uint32_t
numOfParams
;
SParamInfo
*
params
;
SMemRowBuilder
rowBuilder
;
}
STableDataBlocks
;
...
...
@@ -187,7 +173,7 @@ void destroyBoundColumnInfo(SParsedDataColInfo* pColList);
int32_t
initMemRowBuilder
(
SMemRowBuilder
*
pBuilder
,
uint32_t
nRows
,
uint32_t
nCols
,
uint32_t
nBoundCols
,
int32_t
allNullLen
);
int32_t
allocateMemIfNeed
(
STableDataBlocks
*
pDataBlock
,
int32_t
rowSize
,
int32_t
*
numOfRows
);
int32_t
getDataBlockFromList
(
SHashObj
*
pHashList
,
int64_t
id
,
int32_t
size
,
int32_t
startOffset
,
int32_t
rowSize
,
SName
*
name
,
const
STableMeta
*
pTableMeta
,
STableDataBlocks
**
dataBlocks
,
SArray
*
pBlockList
);
const
STableMeta
*
pTableMeta
,
STableDataBlocks
**
dataBlocks
,
SArray
*
pBlockList
);
int32_t
mergeTableDataBlocks
(
SHashObj
*
pHashObj
,
int8_t
schemaAttached
,
uint8_t
payloadType
,
bool
freeBlockMap
);
#endif // TDENGINE_DATABLOCKMGT_H
source/libs/parser/src/dataBlockMgt.c
浏览文件 @
c8ffc27e
...
...
@@ -108,7 +108,7 @@ void destroyBoundColumnInfo(SParsedDataColInfo* pColList) {
tfree
(
pColList
->
colIdxInfo
);
}
static
int32_t
createDataBlock
(
size_t
defaultSize
,
int32_t
rowSize
,
int32_t
startOffset
,
SName
*
name
,
static
int32_t
createDataBlock
(
size_t
defaultSize
,
int32_t
rowSize
,
int32_t
startOffset
,
const
STableMeta
*
pTableMeta
,
STableDataBlocks
**
dataBlocks
)
{
STableDataBlocks
*
dataBuf
=
(
STableDataBlocks
*
)
calloc
(
1
,
sizeof
(
STableDataBlocks
));
if
(
dataBuf
==
NULL
)
{
...
...
@@ -145,7 +145,7 @@ static int32_t createDataBlock(size_t defaultSize, int32_t rowSize, int32_t star
dataBuf
->
tsSource
=
-
1
;
dataBuf
->
vgId
=
dataBuf
->
pTableMeta
->
vgId
;
tNameAssign
(
&
dataBuf
->
tableName
,
name
);
//
tNameAssign(&dataBuf->tableName, name);
assert
(
defaultSize
>
0
&&
pTableMeta
!=
NULL
&&
dataBuf
->
pTableMeta
!=
NULL
);
...
...
@@ -154,8 +154,7 @@ static int32_t createDataBlock(size_t defaultSize, int32_t rowSize, int32_t star
}
int32_t
getDataBlockFromList
(
SHashObj
*
pHashList
,
int64_t
id
,
int32_t
size
,
int32_t
startOffset
,
int32_t
rowSize
,
SName
*
name
,
const
STableMeta
*
pTableMeta
,
STableDataBlocks
**
dataBlocks
,
SArray
*
pBlockList
)
{
const
STableMeta
*
pTableMeta
,
STableDataBlocks
**
dataBlocks
,
SArray
*
pBlockList
)
{
*
dataBlocks
=
NULL
;
STableDataBlocks
**
t1
=
(
STableDataBlocks
**
)
taosHashGet
(
pHashList
,
(
const
char
*
)
&
id
,
sizeof
(
id
));
if
(
t1
!=
NULL
)
{
...
...
@@ -163,7 +162,7 @@ int32_t getDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int3
}
if
(
*
dataBlocks
==
NULL
)
{
int32_t
ret
=
createDataBlock
((
size_t
)
size
,
rowSize
,
startOffset
,
name
,
pTableMeta
,
dataBlocks
);
int32_t
ret
=
createDataBlock
((
size_t
)
size
,
rowSize
,
startOffset
,
pTableMeta
,
dataBlocks
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
}
...
...
@@ -253,23 +252,13 @@ static FORCE_INLINE void convertSMemRow(SMemRow dest, SMemRow src, STableDataBlo
}
}
void
destroyDataBlock
(
STableDataBlocks
*
pDataBlock
,
bool
removeMeta
)
{
void
destroyDataBlock
(
STableDataBlocks
*
pDataBlock
)
{
if
(
pDataBlock
==
NULL
)
{
return
;
}
tfree
(
pDataBlock
->
pData
);
if
(
removeMeta
)
{
char
name
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
tNameExtractFullName
(
&
pDataBlock
->
tableName
,
name
);
// taosHashRemove(tscTableMetaMap, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
}
if
(
!
pDataBlock
->
cloned
)
{
tfree
(
pDataBlock
->
params
);
// free the refcount for metermeta
if
(
pDataBlock
->
pTableMeta
!=
NULL
)
{
tfree
(
pDataBlock
->
pTableMeta
);
...
...
@@ -277,7 +266,6 @@ void destroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta) {
destroyBoundColumnInfo
(
&
pDataBlock
->
boundColumnInfo
);
}
tfree
(
pDataBlock
);
}
...
...
@@ -289,7 +277,7 @@ void* destroyBlockArrayList(SArray* pDataBlockList) {
size_t
size
=
taosArrayGetSize
(
pDataBlockList
);
for
(
int32_t
i
=
0
;
i
<
size
;
i
++
)
{
void
*
d
=
taosArrayGetP
(
pDataBlockList
,
i
);
destroyDataBlock
(
d
,
false
);
destroyDataBlock
(
d
);
}
taosArrayDestroy
(
pDataBlockList
);
...
...
@@ -505,7 +493,7 @@ int32_t mergeTableDataBlocks(SHashObj* pHashObj, int8_t schemaAttached, uint8_t
if
(
pBlocks
->
numOfRows
>
0
)
{
STableDataBlocks
*
dataBuf
=
NULL
;
int32_t
ret
=
getDataBlockFromList
(
pVnodeDataBlockHashList
,
pOneTableBlock
->
vgId
,
TSDB_PAYLOAD_SIZE
,
INSERT_HEAD_SIZE
,
0
,
&
pOneTableBlock
->
tableName
,
pOneTableBlock
->
pTableMeta
,
&
dataBuf
,
pVnodeDataBlockList
);
INSERT_HEAD_SIZE
,
0
,
pOneTableBlock
->
pTableMeta
,
&
dataBuf
,
pVnodeDataBlockList
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
taosHashCleanup
(
pVnodeDataBlockHashList
);
destroyBlockArrayList
(
pVnodeDataBlockList
);
...
...
@@ -580,7 +568,6 @@ int32_t mergeTableDataBlocks(SHashObj* pHashObj, int8_t schemaAttached, uint8_t
extractTableNameList
(
pHashObj
,
freeBlockMap
);
// free the table data blocks;
// pInsertParam->pDataBlocks = pVnodeDataBlockList;
taosHashCleanup
(
pVnodeDataBlockHashList
);
tfree
(
blkKeyInfo
.
pKeyTuple
);
...
...
source/libs/parser/src/insertParser.c
浏览文件 @
c8ffc27e
...
...
@@ -167,11 +167,12 @@ static int32_t skipInsertInto(SInsertParseContext* pCxt) {
static
int32_t
buildTableName
(
SInsertParseContext
*
pCxt
,
SToken
*
pStname
,
SArray
*
tableNameList
)
{
if
(
parserValidateIdToken
(
pStname
)
!=
TSDB_CODE_SUCCESS
)
{
return
build
InvalidOperationMsg
(
&
pCxt
->
msg
,
"invalid table name"
);
return
build
SyntaxErrMsg
(
&
pCxt
->
msg
,
"invalid table name"
,
pStname
->
z
);
}
SName
name
=
{
0
};
strndequote
(
name
.
tname
,
pStname
->
z
,
pStname
->
n
);
strcpy
(
name
.
dbname
,
pCxt
->
pComCxt
->
pDbname
);
strncpy
(
name
.
tname
,
pStname
->
z
,
pStname
->
n
);
taosArrayPush
(
tableNameList
,
&
name
);
return
TSDB_CODE_SUCCESS
;
...
...
@@ -686,7 +687,6 @@ static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks,
// 1. set the parsed value from sql string
for
(
int
i
=
0
;
i
<
spd
->
numOfBound
;
++
i
)
{
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
// todo bind param
SSchema
*
pSchema
=
&
schema
[
spd
->
boundedColumns
[
i
]];
param
.
schema
=
pSchema
;
param
.
compareStat
=
pBuilder
->
compareStat
;
...
...
@@ -770,14 +770,6 @@ static int32_t parseValuesClause(SInsertParseContext* pCxt, STableDataBlocks* da
int32_t
numOfRows
=
0
;
CHECK_CODE
(
parseValues
(
pCxt
,
dataBuf
,
maxNumOfRows
,
&
numOfRows
));
for
(
uint32_t
i
=
0
;
i
<
dataBuf
->
numOfParams
;
++
i
)
{
SParamInfo
*
param
=
dataBuf
->
params
+
i
;
if
(
param
->
idx
==
-
1
)
{
// param->idx = pInsertParam->numOfParams++;
param
->
offset
-=
sizeof
(
SSubmitBlk
);
}
}
SSubmitBlk
*
pBlocks
=
(
SSubmitBlk
*
)(
dataBuf
->
pData
);
if
(
TSDB_CODE_SUCCESS
!=
setBlockInfo
(
pBlocks
,
dataBuf
->
pTableMeta
,
numOfRows
))
{
return
buildInvalidOperationMsg
(
&
pCxt
->
msg
,
"too many rows in sql, total number of rows should be less than 32767"
);
...
...
@@ -815,12 +807,12 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
CHECK_CODE
(
parseUsingClause
(
pCxt
,
&
tbnameToken
));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
}
else
{
CHECK_CODE
(
getTableMeta
(
pCxt
,
&
s
Token
));
CHECK_CODE
(
getTableMeta
(
pCxt
,
&
tbname
Token
));
}
STableDataBlocks
*
dataBuf
=
NULL
;
CHECK_CODE
(
getDataBlockFromList
(
pCxt
->
pTableBlockHashObj
,
pCxt
->
pTableMeta
->
uid
,
TSDB_DEFAULT_PAYLOAD_SIZE
,
sizeof
(
SSubmitBlk
),
getTableInfo
(
pCxt
->
pTableMeta
).
rowSize
,
NULL
/* tbname */
,
pCxt
->
pTableMeta
,
&
dataBuf
,
NULL
));
sizeof
(
SSubmitBlk
),
getTableInfo
(
pCxt
->
pTableMeta
).
rowSize
,
pCxt
->
pTableMeta
,
&
dataBuf
,
NULL
));
if
(
TK_LP
==
sToken
.
type
)
{
// pSql -> field1_name, ...)
...
...
@@ -831,6 +823,7 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
if
(
TK_VALUES
==
sToken
.
type
)
{
// pSql -> (field1_value, ...) [(field1_value2, ...) ...]
CHECK_CODE
(
parseValuesClause
(
pCxt
,
dataBuf
));
pCxt
->
pOutput
->
insertType
=
TSDB_QUERY_TYPE_INSERT
;
continue
;
}
...
...
@@ -842,6 +835,7 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
return
buildSyntaxErrMsg
(
&
pCxt
->
msg
,
"file path is required following keyword FILE"
,
sToken
.
z
);
}
// todo
pCxt
->
pOutput
->
insertType
=
TSDB_QUERY_TYPE_FILE_INSERT
;
continue
;
}
...
...
source/libs/parser/test/insertTest.cpp
浏览文件 @
c8ffc27e
...
...
@@ -36,51 +36,67 @@ namespace {
// [...];
class
InsertTest
:
public
Test
{
protected:
void
setDatabase
(
const
string
&
db
)
{
db_
=
db
;
}
void
bind
(
const
char
*
sql
)
{
reset
();
cxt
.
pSql
=
sql
;
cxt
.
sqlLen
=
strlen
(
sql
);
cxt_
.
sqlLen
=
strlen
(
sql
);
strcpy
(
sqlBuf_
,
sql
);
sqlBuf_
[
cxt_
.
sqlLen
]
=
'\0'
;
cxt_
.
pSql
=
sqlBuf_
;
cxt_
.
pDbname
=
db_
.
c_str
();
}
int32_t
run
()
{
code
=
parseInsertSql
(
&
cxt
,
&
res
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
cout
<<
"code:"
<<
toString
(
code
)
<<
", msg:"
<<
errMagBuf
<<
endl
;
code
_
=
parseInsertSql
(
&
cxt_
,
&
res_
);
if
(
code
_
!=
TSDB_CODE_SUCCESS
)
{
cout
<<
"code:"
<<
toString
(
code
_
)
<<
", msg:"
<<
errMagBuf_
<<
endl
;
}
return
code
;
return
code
_
;
}
SInsertStmtInfo
*
reslut
()
{
return
res
;
return
res
_
;
}
private:
static
const
int
max_err_len
=
1024
;
static
const
int
max_sql_len
=
1024
*
1024
;
void
reset
()
{
memset
(
&
cxt
,
0
,
sizeof
(
cxt
));
memset
(
errMagBuf
,
0
,
max_err_len
);
cxt
.
pMsg
=
errMagBuf
;
cxt
.
msgLen
=
max_err_len
;
code
=
TSDB_CODE_SUCCESS
;
res
=
nullptr
;
memset
(
&
cxt
_
,
0
,
sizeof
(
cxt_
));
memset
(
errMagBuf
_
,
0
,
max_err_len
);
cxt
_
.
pMsg
=
errMagBuf_
;
cxt
_
.
msgLen
=
max_err_len
;
code
_
=
TSDB_CODE_SUCCESS
;
res
_
=
nullptr
;
}
char
errMagBuf
[
max_err_len
];
SParseContext
cxt
;
int32_t
code
;
SInsertStmtInfo
*
res
;
string
db_
;
char
errMagBuf_
[
max_err_len
];
char
sqlBuf_
[
max_sql_len
];
SParseContext
cxt_
;
int32_t
code_
;
SInsertStmtInfo
*
res_
;
};
// INSERT INTO tb_name VALUES (field1_value, ...)
TEST_F
(
InsertTest
,
simpleTest
)
{
bind
(
"insert into .. values (...)"
);
setDatabase
(
"test"
);
bind
(
"insert into t1 values (now, 1,
\"
wxy
\"
)"
);
ASSERT_EQ
(
run
(),
TSDB_CODE_SUCCESS
);
SInsertStmtInfo
*
res
=
reslut
();
// todo check
ASSERT_EQ
(
res
->
insertType
,
TSDB_QUERY_TYPE_INSERT
);
// ASSERT_EQ(taosArrayGetSize(res->pDataBlocks), 1);
}
TEST_F
(
InsertTest
,
toleranceTest
)
{
setDatabase
(
"test"
);
bind
(
"insert into"
);
ASSERT_NE
(
run
(),
TSDB_CODE_SUCCESS
);
bind
(
"insert into t"
);
...
...
source/libs/parser/test/mockCatalog.cpp
浏览文件 @
c8ffc27e
...
...
@@ -17,29 +17,30 @@
#include <iostream>
namespace
{
void
generateTestT1
(
MockCatalogService
*
mcs
)
{
ITableBuilder
&
builder
=
mcs
->
createTableBuilder
(
"test"
,
"t1"
,
TSDB_NORMAL_TABLE
,
3
)
.
setPrecision
(
TSDB_TIME_PRECISION_MILLI
).
setVgid
(
1
).
addColumn
(
"ts"
,
TSDB_DATA_TYPE_TIMESTAMP
)
.
addColumn
(
"c1"
,
TSDB_DATA_TYPE_INT
).
addColumn
(
"c2"
,
TSDB_DATA_TYPE_BINARY
,
10
);
builder
.
done
();
}
void
generateTestST1
(
MockCatalogService
*
mcs
)
{
ITableBuilder
&
builder
=
mcs
->
createTableBuilder
(
"test"
,
"st1"
,
TSDB_SUPER_TABLE
,
3
,
2
)
.
setPrecision
(
TSDB_TIME_PRECISION_MILLI
).
addColumn
(
"ts"
,
TSDB_DATA_TYPE_TIMESTAMP
)
.
addTag
(
"tag1"
,
TSDB_DATA_TYPE_INT
).
addTag
(
"tag2"
,
TSDB_DATA_TYPE_BINARY
,
10
)
.
addColumn
(
"c1"
,
TSDB_DATA_TYPE_INT
).
addColumn
(
"c2"
,
TSDB_DATA_TYPE_BINARY
,
10
);
builder
.
done
();
mcs
->
createSubTable
(
"test"
,
"st1"
,
"st1s1"
,
1
);
mcs
->
createSubTable
(
"test"
,
"st1"
,
"st1s2"
,
2
);
}
}
void
generateMetaData
(
MockCatalogService
*
mcs
)
{
{
ITableBuilder
&
builder
=
mcs
->
createTableBuilder
(
"test"
,
"t1"
,
TSDB_NORMAL_TABLE
,
MockCatalogService
::
numOfDataTypes
)
.
setPrecision
(
TSDB_TIME_PRECISION_MILLI
).
setVgid
(
1
).
addColumn
(
"ts"
,
TSDB_DATA_TYPE_TIMESTAMP
);
for
(
int32_t
i
=
0
;
i
<
MockCatalogService
::
numOfDataTypes
;
++
i
)
{
if
(
TSDB_DATA_TYPE_NULL
==
tDataTypes
[
i
].
type
)
{
continue
;
}
builder
=
builder
.
addColumn
(
"c"
+
std
::
to_string
(
i
+
1
),
tDataTypes
[
i
].
type
);
}
builder
.
done
();
}
{
ITableBuilder
&
builder
=
mcs
->
createTableBuilder
(
"test"
,
"st1"
,
TSDB_SUPER_TABLE
,
MockCatalogService
::
numOfDataTypes
,
2
)
.
setPrecision
(
TSDB_TIME_PRECISION_MILLI
).
setVgid
(
2
).
addColumn
(
"ts"
,
TSDB_DATA_TYPE_TIMESTAMP
);
for
(
int32_t
i
=
0
;
i
<
MockCatalogService
::
numOfDataTypes
;
++
i
)
{
if
(
TSDB_DATA_TYPE_NULL
==
tDataTypes
[
i
].
type
)
{
continue
;
}
builder
=
builder
.
addColumn
(
"c"
+
std
::
to_string
(
i
+
1
),
tDataTypes
[
i
].
type
);
}
builder
.
done
();
}
generateTestT1
(
mcs
);
generateTestST1
(
mcs
);
mcs
->
showTables
();
}
...
...
source/libs/parser/test/mockCatalogService.cpp
浏览文件 @
c8ffc27e
...
...
@@ -19,6 +19,7 @@
#include <iostream>
#include <map>
#include "tname.h"
#include "ttypes.h"
std
::
unique_ptr
<
MockCatalogService
>
mockCatalogService
;
...
...
@@ -82,12 +83,26 @@ public:
MockCatalogServiceImpl
()
{
}
struct
SCatalog
*
getCatalogHandle
(
const
SEpSet
*
pMgmtEps
)
{
struct
SCatalog
*
getCatalogHandle
(
const
SEpSet
*
pMgmtEps
)
const
{
return
(
struct
SCatalog
*
)
0x01
;
}
int32_t
catalogGetMetaData
(
struct
SCatalog
*
pCatalog
,
const
SMetaReq
*
pMetaReq
,
SMetaData
*
pMetaData
)
{
return
0
;
int32_t
catalogGetMetaData
(
struct
SCatalog
*
pCatalog
,
const
SMetaReq
*
pMetaReq
,
SMetaData
*
pMetaData
)
const
{
assert
(
nullptr
!=
pMetaReq
&&
1
==
taosArrayGetSize
(
pMetaReq
->
pTableName
));
SName
*
fullName
=
(
SName
*
)
taosArrayGet
(
pMetaReq
->
pTableName
,
0
);
std
::
unique_ptr
<
STableMeta
>
table
;
int32_t
code
=
copyTableMeta
(
fullName
->
dbname
,
fullName
->
tname
,
&
table
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
std
::
unique_ptr
<
SArray
>
tables
((
SArray
*
)
taosArrayInit
(
1
,
sizeof
(
STableMeta
*
)));
if
(
!
tables
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
STableMeta
*
elem
=
table
.
release
();
taosArrayPush
(
tables
.
get
(),
&
elem
);
pMetaData
->
pTableMeta
=
tables
.
release
();
return
TSDB_CODE_SUCCESS
;
}
TableBuilder
&
createTableBuilder
(
const
std
::
string
&
db
,
const
std
::
string
&
tbname
,
int8_t
tableType
,
int32_t
numOfColumns
,
int32_t
numOfTags
)
{
...
...
@@ -97,6 +112,15 @@ public:
return
*
(
builder_
.
get
());
}
void
createSubTable
(
const
std
::
string
&
db
,
const
std
::
string
&
stbname
,
const
std
::
string
&
tbname
,
int16_t
vgid
)
{
std
::
unique_ptr
<
STableMeta
>
table
;
if
(
TSDB_CODE_SUCCESS
!=
copyTableMeta
(
db
,
stbname
,
&
table
))
{
throw
std
::
runtime_error
(
"copyTableMeta failed"
);
}
meta_
[
db
][
tbname
].
reset
(
table
.
release
());
meta_
[
db
][
tbname
]
->
uid
=
id_
++
;
}
void
showTables
()
const
{
// number of forward fills
#define NOF(n) ((n) / 2)
...
...
@@ -120,20 +144,35 @@ public:
#define SL(sn, in) std::setfill('=') << std::setw((sn) * (SFL + 1) + (in) * (IFL + 1)) << "" << std::setfill(' ')
for
(
const
auto
&
db
:
meta_
)
{
std
::
cout
<<
SH
(
"Database"
)
<<
SH
(
"Table"
)
<<
SH
(
"Type"
)
<<
SH
(
"Precision"
)
<<
IH
(
std
::
string
(
"Vgid"
))
<<
std
::
endl
;
std
::
cout
<<
SL
(
4
,
1
)
<<
std
::
endl
;
std
::
cout
<<
"Databse:"
<<
db
.
first
<<
std
::
endl
;
std
::
cout
<<
SH
(
"Table"
)
<<
SH
(
"Type"
)
<<
SH
(
"Precision"
)
<<
IH
(
"Vgid"
)
<<
std
::
endl
;
std
::
cout
<<
SL
(
3
,
1
)
<<
std
::
endl
;
for
(
const
auto
&
table
:
db
.
second
)
{
std
::
cout
<<
SF
(
db
.
first
)
<<
SF
(
table
.
first
)
<<
SF
(
ttToString
(
table
.
second
->
tableType
))
<<
SF
(
pToString
(
table
.
second
->
tableInfo
.
precision
))
<<
IF
(
table
.
second
->
vgId
)
<<
std
::
endl
;
// int16_t numOfFields = table.second->tableInfo.numOfTags + table.second->tableInfo.numOfColumns;
// for (int16_t i = 0; i < numOfFields; ++i) {
// const SSchema* schema = table.second->schema + i;
// std::cout << schema->name << " " << schema->type << " " << schema->bytes << std::endl;
// }
std
::
cout
<<
SF
(
table
.
first
)
<<
SF
(
ttToString
(
table
.
second
->
tableType
))
<<
SF
(
pToString
(
table
.
second
->
tableInfo
.
precision
))
<<
IF
(
table
.
second
->
vgId
)
<<
std
::
endl
;
}
std
::
cout
<<
std
::
endl
;
}
for
(
const
auto
&
db
:
meta_
)
{
for
(
const
auto
&
table
:
db
.
second
)
{
std
::
cout
<<
"Table:"
<<
table
.
first
<<
std
::
endl
;
std
::
cout
<<
SH
(
"Field"
)
<<
SH
(
"Type"
)
<<
SH
(
"DataType"
)
<<
IH
(
"Bytes"
)
<<
std
::
endl
;
std
::
cout
<<
SL
(
3
,
1
)
<<
std
::
endl
;
int16_t
numOfTags
=
table
.
second
->
tableInfo
.
numOfTags
;
int16_t
numOfFields
=
numOfTags
+
table
.
second
->
tableInfo
.
numOfColumns
;
for
(
int16_t
i
=
0
;
i
<
numOfFields
;
++
i
)
{
const
SSchema
*
schema
=
table
.
second
->
schema
+
i
;
std
::
cout
<<
SF
(
std
::
string
(
schema
->
name
))
<<
SH
(
ftToString
(
i
,
numOfTags
))
<<
SH
(
dtToString
(
schema
->
type
))
<<
IF
(
schema
->
bytes
)
<<
std
::
endl
;
}
std
::
cout
<<
std
::
endl
;
}
}
}
private:
typedef
std
::
map
<
std
::
string
,
std
::
shared_ptr
<
STableMeta
>
>
TableMetaCache
;
typedef
std
::
map
<
std
::
string
,
TableMetaCache
>
DbMetaCache
;
std
::
string
ttToString
(
int8_t
tableType
)
const
{
switch
(
tableType
)
{
case
TSDB_SUPER_TABLE
:
...
...
@@ -160,9 +199,43 @@ private:
}
}
std
::
string
dtToString
(
int8_t
type
)
const
{
return
tDataTypes
[
type
].
name
;
}
std
::
string
ftToString
(
int16_t
colid
,
int16_t
numOfTags
)
const
{
return
(
0
==
colid
?
"column"
:
(
colid
<=
numOfTags
?
"tag"
:
"column"
));
}
std
::
shared_ptr
<
STableMeta
>
getTableMeta
(
const
std
::
string
&
db
,
const
std
::
string
&
tbname
)
const
{
DbMetaCache
::
const_iterator
it
=
meta_
.
find
(
db
);
if
(
meta_
.
end
()
==
it
)
{
return
std
::
shared_ptr
<
STableMeta
>
();
}
TableMetaCache
::
const_iterator
tit
=
it
->
second
.
find
(
tbname
);
if
(
it
->
second
.
end
()
==
tit
)
{
return
std
::
shared_ptr
<
STableMeta
>
();
}
return
tit
->
second
;
}
int32_t
copyTableMeta
(
const
std
::
string
&
db
,
const
std
::
string
&
tbname
,
std
::
unique_ptr
<
STableMeta
>*
dst
)
const
{
std
::
shared_ptr
<
STableMeta
>
src
=
getTableMeta
(
db
,
tbname
);
if
(
!
src
)
{
return
TSDB_CODE_TSC_INVALID_TABLE_NAME
;
}
int32_t
len
=
sizeof
(
STableMeta
)
+
sizeof
(
SSchema
)
*
(
src
->
tableInfo
.
numOfTags
+
src
->
tableInfo
.
numOfColumns
);
dst
->
reset
((
STableMeta
*
)
std
::
calloc
(
1
,
len
));
if
(
!
dst
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
memcpy
(
dst
->
get
(),
src
.
get
(),
len
);
return
TSDB_CODE_SUCCESS
;
}
uint64_t
id_
;
std
::
unique_ptr
<
TableBuilder
>
builder_
;
std
::
map
<
std
::
string
,
std
::
map
<
std
::
string
,
std
::
shared_ptr
<
STableMeta
>
>
>
meta_
;
DbMetaCache
meta_
;
};
MockCatalogService
::
MockCatalogService
()
:
impl_
(
new
MockCatalogServiceImpl
())
{
...
...
@@ -171,11 +244,11 @@ MockCatalogService::MockCatalogService() : impl_(new MockCatalogServiceImpl()) {
MockCatalogService
::~
MockCatalogService
()
{
}
struct
SCatalog
*
MockCatalogService
::
getCatalogHandle
(
const
SEpSet
*
pMgmtEps
)
{
struct
SCatalog
*
MockCatalogService
::
getCatalogHandle
(
const
SEpSet
*
pMgmtEps
)
const
{
return
impl_
->
getCatalogHandle
(
pMgmtEps
);
}
int32_t
MockCatalogService
::
catalogGetMetaData
(
struct
SCatalog
*
pCatalog
,
const
SMetaReq
*
pMetaReq
,
SMetaData
*
pMetaData
)
{
int32_t
MockCatalogService
::
catalogGetMetaData
(
struct
SCatalog
*
pCatalog
,
const
SMetaReq
*
pMetaReq
,
SMetaData
*
pMetaData
)
const
{
return
impl_
->
catalogGetMetaData
(
pCatalog
,
pMetaReq
,
pMetaData
);
}
...
...
@@ -183,6 +256,10 @@ ITableBuilder& MockCatalogService::createTableBuilder(const std::string& db, con
return
impl_
->
createTableBuilder
(
db
,
tbname
,
tableType
,
numOfColumns
,
numOfTags
);
}
void
MockCatalogService
::
createSubTable
(
const
std
::
string
&
db
,
const
std
::
string
&
stbname
,
const
std
::
string
&
tbname
,
int16_t
vgid
)
{
impl_
->
createSubTable
(
db
,
stbname
,
tbname
,
vgid
);
}
void
MockCatalogService
::
showTables
()
const
{
impl_
->
showTables
();
}
\ No newline at end of file
source/libs/parser/test/mockCatalogService.h
浏览文件 @
c8ffc27e
...
...
@@ -49,9 +49,10 @@ public:
MockCatalogService
();
~
MockCatalogService
();
struct
SCatalog
*
getCatalogHandle
(
const
SEpSet
*
pMgmtEps
);
int32_t
catalogGetMetaData
(
struct
SCatalog
*
pCatalog
,
const
SMetaReq
*
pMetaReq
,
SMetaData
*
pMetaData
);
struct
SCatalog
*
getCatalogHandle
(
const
SEpSet
*
pMgmtEps
)
const
;
int32_t
catalogGetMetaData
(
struct
SCatalog
*
pCatalog
,
const
SMetaReq
*
pMetaReq
,
SMetaData
*
pMetaData
)
const
;
ITableBuilder
&
createTableBuilder
(
const
std
::
string
&
db
,
const
std
::
string
&
tbname
,
int8_t
tableType
,
int32_t
numOfColumns
,
int32_t
numOfTags
=
0
);
void
createSubTable
(
const
std
::
string
&
db
,
const
std
::
string
&
stbname
,
const
std
::
string
&
tbname
,
int16_t
vgid
);
void
showTables
()
const
;
private:
...
...
source/libs/wal/inc/walInt.h
浏览文件 @
c8ffc27e
...
...
@@ -33,10 +33,12 @@ typedef struct WalFileInfo {
int64_t
fileSize
;
}
WalFileInfo
;
#pragma pack(push,1)
typedef
struct
WalIdxEntry
{
int64_t
ver
;
int64_t
offset
;
}
WalIdxEntry
;
#pragma pack(pop)
static
inline
int32_t
compareWalFileInfo
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
WalFileInfo
*
pInfoLeft
=
(
WalFileInfo
*
)
pLeft
;
...
...
@@ -78,11 +80,11 @@ static inline WalFileInfo* walGetCurFileInfo(SWal* pWal) {
}
static
inline
int
walBuildLogName
(
SWal
*
pWal
,
int64_t
fileFirstVer
,
char
*
buf
)
{
return
sprintf
(
buf
,
"%s/%"
PRId64
"."
WAL_LOG_SUFFIX
,
pWal
->
path
,
fileFirstVer
);
return
sprintf
(
buf
,
"%s/%
020
"
PRId64
"."
WAL_LOG_SUFFIX
,
pWal
->
path
,
fileFirstVer
);
}
static
inline
int
walBuildIdxName
(
SWal
*
pWal
,
int64_t
fileFirstVer
,
char
*
buf
)
{
return
sprintf
(
buf
,
"%s/%"
PRId64
"."
WAL_INDEX_SUFFIX
,
pWal
->
path
,
fileFirstVer
);
return
sprintf
(
buf
,
"%s/%
020
"
PRId64
"."
WAL_INDEX_SUFFIX
,
pWal
->
path
,
fileFirstVer
);
}
static
inline
int
walValidHeadCksum
(
SWalHead
*
pHead
)
{
...
...
@@ -90,7 +92,7 @@ static inline int walValidHeadCksum(SWalHead* pHead) {
}
static
inline
int
walValidBodyCksum
(
SWalHead
*
pHead
)
{
return
taosCheckChecksum
((
uint8_t
*
)
pHead
->
head
.
cont
,
pHead
->
head
.
len
,
pHead
->
cksumBody
);
return
taosCheckChecksum
((
uint8_t
*
)
pHead
->
head
.
body
,
pHead
->
head
.
len
,
pHead
->
cksumBody
);
}
static
inline
int
walValidCksum
(
SWalHead
*
pHead
,
void
*
body
,
int64_t
bodyLen
)
{
...
...
source/libs/wal/src/walMeta.c
浏览文件 @
c8ffc27e
...
...
@@ -25,15 +25,15 @@
#include <regex.h>
int64_t
walGetFirstVer
(
SWal
*
pWal
)
{
return
pWal
->
firstVersion
;
return
pWal
->
vers
.
firstVer
;
}
int64_t
walGetSnaphostVer
(
SWal
*
pWal
)
{
return
pWal
->
snapshotVersion
;
return
pWal
->
vers
.
snapshotVer
;
}
int64_t
walGetLastVer
(
SWal
*
pWal
)
{
return
pWal
->
lastVersion
;
return
pWal
->
vers
.
lastVer
;
}
int
walRollFileInfo
(
SWal
*
pWal
)
{
...
...
@@ -42,7 +42,7 @@ int walRollFileInfo(SWal* pWal) {
SArray
*
pArray
=
pWal
->
fileInfoSet
;
if
(
taosArrayGetSize
(
pArray
)
!=
0
)
{
WalFileInfo
*
pInfo
=
taosArrayGetLast
(
pArray
);
pInfo
->
lastVer
=
pWal
->
lastVersion
;
pInfo
->
lastVer
=
pWal
->
vers
.
lastVer
;
pInfo
->
closeTs
=
ts
;
}
...
...
@@ -51,7 +51,7 @@ int walRollFileInfo(SWal* pWal) {
if
(
pNewInfo
==
NULL
)
{
return
-
1
;
}
pNewInfo
->
firstVer
=
pWal
->
lastVersion
+
1
;
pNewInfo
->
firstVer
=
pWal
->
vers
.
lastVer
+
1
;
pNewInfo
->
lastVer
=
-
1
;
pNewInfo
->
createTs
=
ts
;
pNewInfo
->
closeTs
=
-
1
;
...
...
@@ -74,13 +74,13 @@ char* walMetaSerialize(SWal* pWal) {
return
NULL
;
}
cJSON_AddItemToObject
(
pRoot
,
"meta"
,
pMeta
);
sprintf
(
buf
,
"%"
PRId64
,
pWal
->
firstVersion
);
sprintf
(
buf
,
"%"
PRId64
,
pWal
->
vers
.
firstVer
);
cJSON_AddStringToObject
(
pMeta
,
"firstVer"
,
buf
);
sprintf
(
buf
,
"%"
PRId64
,
pWal
->
snapshotVersion
);
sprintf
(
buf
,
"%"
PRId64
,
pWal
->
vers
.
snapshotVer
);
cJSON_AddStringToObject
(
pMeta
,
"snapshotVer"
,
buf
);
sprintf
(
buf
,
"%"
PRId64
,
pWal
->
commitVersion
);
sprintf
(
buf
,
"%"
PRId64
,
pWal
->
vers
.
commitVer
);
cJSON_AddStringToObject
(
pMeta
,
"commitVer"
,
buf
);
sprintf
(
buf
,
"%"
PRId64
,
pWal
->
lastVersion
);
sprintf
(
buf
,
"%"
PRId64
,
pWal
->
vers
.
lastVer
);
cJSON_AddStringToObject
(
pMeta
,
"lastVer"
,
buf
);
cJSON_AddItemToObject
(
pRoot
,
"files"
,
pFiles
);
...
...
@@ -116,13 +116,13 @@ int walMetaDeserialize(SWal* pWal, const char* bytes) {
pRoot
=
cJSON_Parse
(
bytes
);
pMeta
=
cJSON_GetObjectItem
(
pRoot
,
"meta"
);
pField
=
cJSON_GetObjectItem
(
pMeta
,
"firstVer"
);
pWal
->
firstVersion
=
atoll
(
cJSON_GetStringValue
(
pField
));
pWal
->
vers
.
firstVer
=
atoll
(
cJSON_GetStringValue
(
pField
));
pField
=
cJSON_GetObjectItem
(
pMeta
,
"snapshotVer"
);
pWal
->
snapshotVersion
=
atoll
(
cJSON_GetStringValue
(
pField
));
pWal
->
vers
.
snapshotVer
=
atoll
(
cJSON_GetStringValue
(
pField
));
pField
=
cJSON_GetObjectItem
(
pMeta
,
"commitVer"
);
pWal
->
commitVersion
=
atoll
(
cJSON_GetStringValue
(
pField
));
pWal
->
vers
.
commitVer
=
atoll
(
cJSON_GetStringValue
(
pField
));
pField
=
cJSON_GetObjectItem
(
pMeta
,
"lastVer"
);
pWal
->
lastVersion
=
atoll
(
cJSON_GetStringValue
(
pField
));
pWal
->
vers
.
lastVer
=
atoll
(
cJSON_GetStringValue
(
pField
));
pFiles
=
cJSON_GetObjectItem
(
pRoot
,
"files"
);
int
sz
=
cJSON_GetArraySize
(
pFiles
);
...
...
@@ -161,7 +161,7 @@ static int walFindCurMetaVer(SWal* pWal) {
DIR
*
dir
=
opendir
(
pWal
->
path
);
if
(
dir
==
NULL
)
{
wError
(
"vgId:%d, path:%s, failed to open since %s"
,
pWal
->
vgId
,
pWal
->
path
,
strerror
(
errno
));
wError
(
"vgId:%d, path:%s, failed to open since %s"
,
pWal
->
cfg
.
vgId
,
pWal
->
path
,
strerror
(
errno
));
return
-
1
;
}
...
...
source/libs/wal/src/walMgmt.c
浏览文件 @
c8ffc27e
...
...
@@ -68,9 +68,12 @@ int32_t walInit() {
}
void
walCleanUp
()
{
int
old
=
atomic_val_compare_exchange_8
(
&
tsWal
.
inited
,
1
,
0
);
if
(
old
==
0
)
{
return
;
}
walStopThread
();
taosCloseRef
(
tsWal
.
refSetId
);
atomic_store_8
(
&
tsWal
.
inited
,
0
);
wInfo
(
"wal module is cleaned up"
);
}
...
...
@@ -86,21 +89,15 @@ SWal *walOpen(const char *path, SWalCfg *pCfg) {
pWal
->
writeCur
=
-
1
;
//set config
pWal
->
vgId
=
pCfg
->
vgId
;
pWal
->
fsyncPeriod
=
pCfg
->
fsyncPeriod
;
pWal
->
rollPeriod
=
pCfg
->
rollPeriod
;
pWal
->
segSize
=
pCfg
->
segSize
;
pWal
->
retentionSize
=
pCfg
->
retentionSize
;
pWal
->
retentionPeriod
=
pCfg
->
retentionPeriod
;
pWal
->
level
=
pCfg
->
walLevel
;
memcpy
(
&
pWal
->
cfg
,
pCfg
,
sizeof
(
SWalCfg
));
//init version info
pWal
->
firstVersion
=
-
1
;
pWal
->
commitVersion
=
-
1
;
pWal
->
snapshotVersion
=
-
1
;
pWal
->
lastVersion
=
-
1
;
pWal
->
vers
.
firstVer
=
-
1
;
pWal
->
vers
.
commitVer
=
-
1
;
pWal
->
vers
.
snapshotVer
=
-
1
;
pWal
->
vers
.
lastVer
=
-
1
;
pWal
->
snapshottingVer
=
-
1
;
pWal
->
vers
.
verInSnapshotting
=
-
1
;
pWal
->
totSize
=
0
;
...
...
@@ -108,8 +105,8 @@ SWal *walOpen(const char *path, SWalCfg *pCfg) {
pWal
->
lastRollSeq
=
-
1
;
//init write buffer
memset
(
&
pWal
->
h
ead
,
0
,
sizeof
(
SWalHead
));
pWal
->
h
ead
.
head
.
sver
=
0
;
memset
(
&
pWal
->
writeH
ead
,
0
,
sizeof
(
SWalHead
));
pWal
->
writeH
ead
.
head
.
sver
=
0
;
tstrncpy
(
pWal
->
path
,
path
,
sizeof
(
pWal
->
path
));
pthread_mutex_init
(
&
pWal
->
mutex
,
NULL
);
...
...
@@ -129,7 +126,7 @@ SWal *walOpen(const char *path, SWalCfg *pCfg) {
}
walReadMeta
(
pWal
);
wDebug
(
"vgId:%d, wal:%p is opened, level:%d fsyncPeriod:%d"
,
pWal
->
vgId
,
pWal
,
pWal
->
level
,
pWal
->
fsyncPeriod
);
wDebug
(
"vgId:%d, wal:%p is opened, level:%d fsyncPeriod:%d"
,
pWal
->
cfg
.
vgId
,
pWal
,
pWal
->
cfg
.
level
,
pWal
->
cfg
.
fsyncPeriod
);
return
pWal
;
}
...
...
@@ -137,17 +134,17 @@ SWal *walOpen(const char *path, SWalCfg *pCfg) {
int32_t
walAlter
(
SWal
*
pWal
,
SWalCfg
*
pCfg
)
{
if
(
pWal
==
NULL
)
return
TSDB_CODE_WAL_APP_ERROR
;
if
(
pWal
->
level
==
pCfg
->
walLevel
&&
pWal
->
fsyncPeriod
==
pCfg
->
fsyncPeriod
)
{
wDebug
(
"vgId:%d, old walLevel:%d fsync:%d, new walLevel:%d fsync:%d not change"
,
pWal
->
vgId
,
pWal
->
level
,
pWal
->
fsyncPeriod
,
pCfg
->
walL
evel
,
pCfg
->
fsyncPeriod
);
if
(
pWal
->
cfg
.
level
==
pCfg
->
level
&&
pWal
->
cfg
.
fsyncPeriod
==
pCfg
->
fsyncPeriod
)
{
wDebug
(
"vgId:%d, old walLevel:%d fsync:%d, new walLevel:%d fsync:%d not change"
,
pWal
->
cfg
.
vgId
,
pWal
->
cfg
.
level
,
pWal
->
cfg
.
fsyncPeriod
,
pCfg
->
l
evel
,
pCfg
->
fsyncPeriod
);
return
0
;
}
wInfo
(
"vgId:%d, change old walLevel:%d fsync:%d, new walLevel:%d fsync:%d"
,
pWal
->
vgId
,
pWal
->
level
,
pWal
->
fsyncPeriod
,
pCfg
->
walL
evel
,
pCfg
->
fsyncPeriod
);
wInfo
(
"vgId:%d, change old walLevel:%d fsync:%d, new walLevel:%d fsync:%d"
,
pWal
->
cfg
.
vgId
,
pWal
->
cfg
.
level
,
pWal
->
cfg
.
fsyncPeriod
,
pCfg
->
l
evel
,
pCfg
->
fsyncPeriod
);
pWal
->
level
=
pCfg
->
walL
evel
;
pWal
->
fsyncPeriod
=
pCfg
->
fsyncPeriod
;
pWal
->
cfg
.
level
=
pCfg
->
l
evel
;
pWal
->
cfg
.
fsyncPeriod
=
pCfg
->
fsyncPeriod
;
pWal
->
fsyncSeq
=
pCfg
->
fsyncPeriod
/
1000
;
if
(
pWal
->
fsyncSeq
<=
0
)
pWal
->
fsyncSeq
=
1
;
...
...
@@ -171,22 +168,22 @@ void walClose(SWal *pWal) {
static
int32_t
walInitObj
(
SWal
*
pWal
)
{
if
(
taosMkDir
(
pWal
->
path
)
!=
0
)
{
wError
(
"vgId:%d, path:%s, failed to create directory since %s"
,
pWal
->
vgId
,
pWal
->
path
,
strerror
(
errno
));
wError
(
"vgId:%d, path:%s, failed to create directory since %s"
,
pWal
->
cfg
.
vgId
,
pWal
->
path
,
strerror
(
errno
));
return
TAOS_SYSTEM_ERROR
(
errno
);
}
pWal
->
fileInfoSet
=
taosArrayInit
(
8
,
sizeof
(
WalFileInfo
));
if
(
pWal
->
fileInfoSet
==
NULL
)
{
wError
(
"vgId:%d, path:%s, failed to init taosArray %s"
,
pWal
->
vgId
,
pWal
->
path
,
strerror
(
errno
));
wError
(
"vgId:%d, path:%s, failed to init taosArray %s"
,
pWal
->
cfg
.
vgId
,
pWal
->
path
,
strerror
(
errno
));
return
TAOS_SYSTEM_ERROR
(
errno
);
}
wDebug
(
"vgId:%d, object is initialized"
,
pWal
->
vgId
);
wDebug
(
"vgId:%d, object is initialized"
,
pWal
->
cfg
.
vgId
);
return
0
;
}
static
void
walFreeObj
(
void
*
wal
)
{
SWal
*
pWal
=
wal
;
wDebug
(
"vgId:%d, wal:%p is freed"
,
pWal
->
vgId
,
pWal
);
wDebug
(
"vgId:%d, wal:%p is freed"
,
pWal
->
cfg
.
vgId
,
pWal
);
tfClose
(
pWal
->
writeLogTfd
);
tfClose
(
pWal
->
writeIdxTfd
);
...
...
@@ -197,7 +194,7 @@ static void walFreeObj(void *wal) {
}
static
bool
walNeedFsync
(
SWal
*
pWal
)
{
if
(
pWal
->
fsyncPeriod
<=
0
||
pWal
->
level
!=
TAOS_WAL_FSYNC
)
{
if
(
pWal
->
cfg
.
fsyncPeriod
<=
0
||
pWal
->
cfg
.
level
!=
TAOS_WAL_FSYNC
)
{
return
false
;
}
...
...
@@ -217,10 +214,10 @@ static void walFsyncAll() {
SWal
*
pWal
=
taosIterateRef
(
tsWal
.
refSetId
,
0
);
while
(
pWal
)
{
if
(
walNeedFsync
(
pWal
))
{
wTrace
(
"vgId:%d, do fsync, level:%d seq:%d rseq:%d"
,
pWal
->
vgId
,
pWal
->
level
,
pWal
->
fsyncSeq
,
atomic_load_32
(
&
tsWal
.
seq
));
wTrace
(
"vgId:%d, do fsync, level:%d seq:%d rseq:%d"
,
pWal
->
cfg
.
vgId
,
pWal
->
cfg
.
level
,
pWal
->
fsyncSeq
,
atomic_load_32
(
&
tsWal
.
seq
));
int32_t
code
=
tfFsync
(
pWal
->
writeLogTfd
);
if
(
code
!=
0
)
{
wError
(
"vgId:%d, file:%"
PRId64
".log, failed to fsync since %s"
,
pWal
->
vgId
,
walGetLastFileFirstVer
(
pWal
),
strerror
(
code
));
wError
(
"vgId:%d, file:%"
PRId64
".log, failed to fsync since %s"
,
pWal
->
cfg
.
vgId
,
walGetLastFileFirstVer
(
pWal
),
strerror
(
code
));
}
}
pWal
=
taosIterateRef
(
tsWal
.
refSetId
,
pWal
->
refId
);
...
...
@@ -258,9 +255,8 @@ static int32_t walCreateThread() {
static
void
walStopThread
()
{
atomic_store_8
(
&
tsWal
.
stop
,
1
);
if
(
t
sWal
.
thread
!=
NULL
&&
t
aosCheckPthreadValid
(
tsWal
.
thread
))
{
if
(
taosCheckPthreadValid
(
tsWal
.
thread
))
{
pthread_join
(
tsWal
.
thread
,
NULL
);
tsWal
.
thread
=
NULL
;
}
wDebug
(
"wal thread is stopped"
);
...
...
source/libs/wal/src/walRead.c
浏览文件 @
c8ffc27e
...
...
@@ -16,6 +16,163 @@
#include "walInt.h"
#include "tfile.h"
SWalReadHandle
*
walOpenReadHandle
(
SWal
*
pWal
)
{
SWalReadHandle
*
pRead
=
malloc
(
sizeof
(
SWalReadHandle
));
if
(
pRead
==
NULL
)
{
return
NULL
;
}
pRead
->
pWal
=
pWal
;
pRead
->
readIdxTfd
=
-
1
;
pRead
->
readLogTfd
=
-
1
;
pRead
->
curVersion
=
-
1
;
pRead
->
curFileFirstVer
=
-
1
;
pRead
->
capacity
=
0
;
pRead
->
status
=
0
;
pRead
->
pHead
=
malloc
(
sizeof
(
SWalHead
));
if
(
pRead
->
pHead
==
NULL
)
{
free
(
pRead
);
return
NULL
;
}
return
pRead
;
}
void
walCloseReadHandle
(
SWalReadHandle
*
pRead
)
{
tfClose
(
pRead
->
readIdxTfd
);
tfClose
(
pRead
->
readLogTfd
);
tfree
(
pRead
->
pHead
);
free
(
pRead
);
}
int32_t
walRegisterRead
(
SWalReadHandle
*
pRead
,
int64_t
ver
)
{
return
0
;
}
static
int32_t
walReadSeekFilePos
(
SWalReadHandle
*
pRead
,
int64_t
fileFirstVer
,
int64_t
ver
)
{
int
code
=
0
;
int64_t
idxTfd
=
pRead
->
readIdxTfd
;
int64_t
logTfd
=
pRead
->
readLogTfd
;
//seek position
int64_t
offset
=
(
ver
-
fileFirstVer
)
*
WAL_IDX_ENTRY_SIZE
;
code
=
tfLseek
(
idxTfd
,
offset
,
SEEK_SET
);
if
(
code
<
0
)
{
return
-
1
;
}
WalIdxEntry
entry
;
if
(
tfRead
(
idxTfd
,
&
entry
,
sizeof
(
WalIdxEntry
))
!=
sizeof
(
WalIdxEntry
))
{
return
-
1
;
}
//TODO:deserialize
ASSERT
(
entry
.
ver
==
ver
);
code
=
tfLseek
(
logTfd
,
entry
.
offset
,
SEEK_SET
);
if
(
code
<
0
)
{
return
-
1
;
}
return
code
;
}
static
int32_t
walReadChangeFile
(
SWalReadHandle
*
pRead
,
int64_t
fileFirstVer
)
{
char
fnameStr
[
WAL_FILE_LEN
];
tfClose
(
pRead
->
readIdxTfd
);
tfClose
(
pRead
->
readLogTfd
);
walBuildLogName
(
pRead
->
pWal
,
fileFirstVer
,
fnameStr
);
int64_t
logTfd
=
tfOpenRead
(
fnameStr
);
if
(
logTfd
<
0
)
{
return
-
1
;
}
walBuildIdxName
(
pRead
->
pWal
,
fileFirstVer
,
fnameStr
);
int64_t
idxTfd
=
tfOpenRead
(
fnameStr
);
if
(
idxTfd
<
0
)
{
return
-
1
;
}
pRead
->
readLogTfd
=
logTfd
;
pRead
->
readIdxTfd
=
idxTfd
;
return
0
;
}
static
int32_t
walReadSeekVer
(
SWalReadHandle
*
pRead
,
int64_t
ver
)
{
int
code
;
SWal
*
pWal
=
pRead
->
pWal
;
if
(
ver
==
pRead
->
curVersion
)
{
return
0
;
}
if
(
ver
>
pWal
->
vers
.
lastVer
||
ver
<
pWal
->
vers
.
firstVer
)
{
return
-
1
;
}
if
(
ver
<
pWal
->
vers
.
snapshotVer
)
{
}
WalFileInfo
tmpInfo
;
tmpInfo
.
firstVer
=
ver
;
//bsearch in fileSet
WalFileInfo
*
pRet
=
taosArraySearch
(
pWal
->
fileInfoSet
,
&
tmpInfo
,
compareWalFileInfo
,
TD_LE
);
ASSERT
(
pRet
!=
NULL
);
if
(
pRead
->
curFileFirstVer
!=
pRet
->
firstVer
)
{
code
=
walReadChangeFile
(
pRead
,
pRet
->
firstVer
);
if
(
code
<
0
)
{
//TODO: set error flag
return
-
1
;
}
}
code
=
walReadSeekFilePos
(
pRead
,
pRet
->
firstVer
,
ver
);
if
(
code
<
0
)
{
return
-
1
;
}
pRead
->
curVersion
=
ver
;
return
0
;
}
int32_t
walReadWithHandle
(
SWalReadHandle
*
pRead
,
int64_t
ver
)
{
int
code
;
//TODO: check wal life
if
(
pRead
->
curVersion
!=
ver
)
{
code
=
walReadSeekVer
(
pRead
,
ver
);
if
(
code
!=
0
)
{
return
-
1
;
}
}
if
(
!
tfValid
(
pRead
->
readLogTfd
))
return
-
1
;
code
=
tfRead
(
pRead
->
readLogTfd
,
pRead
->
pHead
,
sizeof
(
SWalHead
));
if
(
code
!=
sizeof
(
SWalHead
))
{
return
-
1
;
}
code
=
walValidHeadCksum
(
pRead
->
pHead
);
if
(
code
!=
0
)
{
return
-
1
;
}
if
(
pRead
->
capacity
<
pRead
->
pHead
->
head
.
len
)
{
void
*
ptr
=
realloc
(
pRead
->
pHead
,
sizeof
(
SWalHead
)
+
pRead
->
pHead
->
head
.
len
);
if
(
ptr
==
NULL
)
{
return
-
1
;
}
pRead
->
pHead
=
ptr
;
pRead
->
capacity
=
pRead
->
pHead
->
head
.
len
;
}
if
(
pRead
->
pHead
->
head
.
len
!=
tfRead
(
pRead
->
readLogTfd
,
pRead
->
pHead
->
head
.
body
,
pRead
->
pHead
->
head
.
len
))
{
return
-
1
;
}
/*code = walValidBodyCksum(pRead->pHead);*/
ASSERT
(
pRead
->
pHead
->
head
.
version
==
ver
);
if
(
code
!=
0
)
{
return
-
1
;
}
pRead
->
curVersion
++
;
return
0
;
}
int32_t
walRead
(
SWal
*
pWal
,
SWalHead
**
ppHead
,
int64_t
ver
)
{
int
code
;
code
=
walSeekVer
(
pWal
,
ver
);
...
...
@@ -42,7 +199,7 @@ int32_t walRead(SWal *pWal, SWalHead **ppHead, int64_t ver) {
*
ppHead
=
NULL
;
return
-
1
;
}
if
(
tfRead
(
pWal
->
writeLogTfd
,
(
*
ppHead
)
->
head
.
cont
,
(
*
ppHead
)
->
head
.
len
)
!=
(
*
ppHead
)
->
head
.
len
)
{
if
(
tfRead
(
pWal
->
writeLogTfd
,
(
*
ppHead
)
->
head
.
body
,
(
*
ppHead
)
->
head
.
len
)
!=
(
*
ppHead
)
->
head
.
len
)
{
return
-
1
;
}
//TODO: endian compatibility processing after read
...
...
source/libs/wal/src/walSeek.c
浏览文件 @
c8ffc27e
...
...
@@ -78,10 +78,12 @@ int walChangeFile(SWal *pWal, int64_t ver) {
code
=
tfClose
(
pWal
->
writeLogTfd
);
if
(
code
!=
0
)
{
//TODO
return
-
1
;
}
code
=
tfClose
(
pWal
->
writeIdxTfd
);
if
(
code
!=
0
)
{
//TODO
return
-
1
;
}
WalFileInfo
tmpInfo
;
tmpInfo
.
firstVer
=
ver
;
...
...
@@ -106,24 +108,19 @@ int walChangeFile(SWal *pWal, int64_t ver) {
pWal
->
writeLogTfd
=
logTfd
;
pWal
->
writeIdxTfd
=
idxTfd
;
return
code
;
}
int
walGetVerOffset
(
SWal
*
pWal
,
int64_t
ver
)
{
int
code
;
return
0
;
return
fileFirstVer
;
}
int
walSeekVer
(
SWal
*
pWal
,
int64_t
ver
)
{
int
code
;
if
(
ver
==
pWal
->
lastVersion
)
{
if
(
ver
==
pWal
->
vers
.
lastVer
)
{
return
0
;
}
if
(
ver
>
pWal
->
lastVersion
||
ver
<
pWal
->
firstVersion
)
{
if
(
ver
>
pWal
->
vers
.
lastVer
||
ver
<
pWal
->
vers
.
firstVer
)
{
return
-
1
;
}
if
(
ver
<
pWal
->
snapshotVersion
)
{
//TODO: set flag to prevent roll back
if
(
ver
<
pWal
->
vers
.
snapshotVer
)
{
}
if
(
ver
<
walGetCurFileFirstVer
(
pWal
)
||
(
ver
>
walGetCurFileLastVer
(
pWal
)))
{
code
=
walChangeFile
(
pWal
,
ver
);
...
...
source/libs/wal/src/walUtil.c
浏览文件 @
c8ffc27e
...
...
@@ -17,6 +17,7 @@
#include "os.h"
#include "walInt.h"
#if 0
int32_t walGetNextFile(SWal *pWal, int64_t *nextFileId) {
int64_t curFileId = *nextFileId;
int64_t minFileId = INT64_MAX;
...
...
@@ -116,3 +117,4 @@ int32_t walGetNewFile(SWal *pWal, int64_t *newFileId) {
return 0;
}
#endif
source/libs/wal/src/walWrite.c
浏览文件 @
c8ffc27e
...
...
@@ -114,22 +114,22 @@ void walRemoveAllOldFiles(void *handle) {
#endif
int32_t
walCommit
(
SWal
*
pWal
,
int64_t
ver
)
{
ASSERT
(
pWal
->
commitVersion
>=
pWal
->
snapshotVersion
);
ASSERT
(
pWal
->
commitVersion
<=
pWal
->
lastVersion
);
if
(
ver
<
pWal
->
commitVersion
||
ver
>
pWal
->
lastVersion
)
{
ASSERT
(
pWal
->
vers
.
commitVer
>=
pWal
->
vers
.
snapshotVer
);
ASSERT
(
pWal
->
vers
.
commitVer
<=
pWal
->
vers
.
lastVer
);
if
(
ver
<
pWal
->
vers
.
commitVer
||
ver
>
pWal
->
vers
.
lastVer
)
{
return
-
1
;
}
pWal
->
commitVersion
=
ver
;
pWal
->
vers
.
commitVer
=
ver
;
return
0
;
}
int32_t
walRollback
(
SWal
*
pWal
,
int64_t
ver
)
{
int
code
;
char
fnameStr
[
WAL_FILE_LEN
];
if
(
ver
==
pWal
->
lastVersion
)
{
if
(
ver
==
pWal
->
vers
.
lastVer
)
{
return
0
;
}
if
(
ver
>
pWal
->
lastVersion
||
ver
<
pWal
->
commitVersion
)
{
if
(
ver
>
pWal
->
vers
.
lastVer
||
ver
<
pWal
->
vers
.
commitVer
)
{
return
-
1
;
}
pthread_mutex_lock
(
&
pWal
->
mutex
);
...
...
@@ -220,7 +220,7 @@ int32_t walRollback(SWal *pWal, int64_t ver) {
if
(
code
<
0
)
{
return
-
1
;
}
pWal
->
lastVersion
=
ver
-
1
;
pWal
->
vers
.
lastVer
=
ver
-
1
;
((
WalFileInfo
*
)
taosArrayGetLast
(
pWal
->
fileInfoSet
))
->
lastVer
=
ver
-
1
;
((
WalFileInfo
*
)
taosArrayGetLast
(
pWal
->
fileInfoSet
))
->
fileSize
=
entry
.
offset
;
...
...
@@ -230,9 +230,9 @@ int32_t walRollback(SWal *pWal, int64_t ver) {
}
int32_t
walBeginTakeSnapshot
(
SWal
*
pWal
,
int64_t
ver
)
{
pWal
->
snapshottingVer
=
ver
;
pWal
->
vers
.
verInSnapshotting
=
ver
;
//check file rolling
if
(
pWal
->
retentionPeriod
==
0
)
{
if
(
pWal
->
cfg
.
retentionPeriod
==
0
)
{
walRoll
(
pWal
);
}
...
...
@@ -240,10 +240,10 @@ int32_t walBeginTakeSnapshot(SWal* pWal, int64_t ver) {
}
int32_t
walEndTakeSnapshot
(
SWal
*
pWal
)
{
int64_t
ver
=
pWal
->
snapshottingVer
;
int64_t
ver
=
pWal
->
vers
.
verInSnapshotting
;
if
(
ver
==
-
1
)
return
-
1
;
pWal
->
snapshotVersion
=
ver
;
pWal
->
vers
.
snapshotVer
=
ver
;
int
ts
=
taosGetTimestampSec
();
int
deleteCnt
=
0
;
...
...
@@ -257,8 +257,8 @@ int32_t walEndTakeSnapshot(SWal *pWal) {
}
//iterate files, until the searched result
for
(
WalFileInfo
*
iter
=
pWal
->
fileInfoSet
->
pData
;
iter
<
pInfo
;
iter
++
)
{
if
(
pWal
->
totSize
>
pWal
->
retentionSize
||
iter
->
closeTs
+
pWal
->
retentionPeriod
>
ts
)
{
if
(
pWal
->
totSize
>
pWal
->
cfg
.
retentionSize
||
iter
->
closeTs
+
pWal
->
cfg
.
retentionPeriod
>
ts
)
{
//delete according to file size or close time
deleteCnt
++
;
newTotSize
-=
iter
->
fileSize
;
...
...
@@ -278,13 +278,13 @@ int32_t walEndTakeSnapshot(SWal *pWal) {
taosArrayPopFrontBatch
(
pWal
->
fileInfoSet
,
deleteCnt
);
if
(
taosArrayGetSize
(
pWal
->
fileInfoSet
)
==
0
)
{
pWal
->
writeCur
=
-
1
;
pWal
->
firstVersion
=
-
1
;
pWal
->
vers
.
firstVer
=
-
1
;
}
else
{
pWal
->
firstVersion
=
((
WalFileInfo
*
)
taosArrayGet
(
pWal
->
fileInfoSet
,
0
))
->
firstVer
;
pWal
->
vers
.
firstVer
=
((
WalFileInfo
*
)
taosArrayGet
(
pWal
->
fileInfoSet
,
0
))
->
firstVer
;
}
pWal
->
writeCur
=
taosArrayGetSize
(
pWal
->
fileInfoSet
)
-
1
;;
pWal
->
totSize
=
newTotSize
;
pWal
->
snapshottingVer
=
-
1
;
pWal
->
vers
.
verInSnapshotting
=
-
1
;
//save snapshot ver, commit ver
int
code
=
walWriteMeta
(
pWal
);
...
...
@@ -311,7 +311,7 @@ int walRoll(SWal *pWal) {
}
int64_t
idxTfd
,
logTfd
;
//create new file
int64_t
newFileFirstVersion
=
pWal
->
lastVersion
+
1
;
int64_t
newFileFirstVersion
=
pWal
->
vers
.
lastVer
+
1
;
char
fnameStr
[
WAL_FILE_LEN
];
walBuildIdxName
(
pWal
,
newFileFirstVersion
,
fnameStr
);
idxTfd
=
tfOpenCreateWrite
(
fnameStr
);
...
...
@@ -357,18 +357,18 @@ int64_t walWrite(SWal *pWal, int64_t index, uint8_t msgType, const void *body, i
int
code
=
0
;
// no wal
if
(
pWal
->
level
==
TAOS_WAL_NOLOG
)
return
0
;
if
(
pWal
->
cfg
.
level
==
TAOS_WAL_NOLOG
)
return
0
;
if
(
index
==
pWal
->
lastVersion
+
1
)
{
if
(
index
==
pWal
->
vers
.
lastVer
+
1
)
{
if
(
taosArrayGetSize
(
pWal
->
fileInfoSet
)
==
0
)
{
pWal
->
firstVersion
=
index
;
pWal
->
vers
.
firstVer
=
index
;
code
=
walRoll
(
pWal
);
ASSERT
(
code
==
0
);
}
else
{
int64_t
passed
=
walGetSeq
()
-
pWal
->
lastRollSeq
;
if
(
pWal
->
rollPeriod
!=
-
1
&&
pWal
->
rollPeriod
!=
0
&&
passed
>
pWal
->
rollPeriod
)
{
if
(
pWal
->
cfg
.
rollPeriod
!=
-
1
&&
pWal
->
cfg
.
rollPeriod
!=
0
&&
passed
>
pWal
->
cfg
.
rollPeriod
)
{
walRoll
(
pWal
);
}
else
if
(
pWal
->
segSize
!=
-
1
&&
pWal
->
segSize
!=
0
&&
walGetLastFileSize
(
pWal
)
>
pWal
->
segSize
)
{
}
else
if
(
pWal
->
cfg
.
segSize
!=
-
1
&&
pWal
->
cfg
.
segSize
!=
0
&&
walGetLastFileSize
(
pWal
)
>
pWal
->
cfg
.
segSize
)
{
walRoll
(
pWal
);
}
}
...
...
@@ -377,35 +377,36 @@ int64_t walWrite(SWal *pWal, int64_t index, uint8_t msgType, const void *body, i
//must truncate explicitly first
return
-
1
;
}
/*if (!tfValid(pWal->
curLogTfd)) return 0
;*/
/*if (!tfValid(pWal->
writeLogTfd)) return -1
;*/
pthread_mutex_lock
(
&
pWal
->
mutex
);
pWal
->
h
ead
.
head
.
version
=
index
;
pWal
->
writeH
ead
.
head
.
version
=
index
;
pWal
->
head
.
head
.
len
=
bodyLen
;
pWal
->
head
.
head
.
msgType
=
msgType
;
pWal
->
head
.
cksumHead
=
walCalcHeadCksum
(
&
pWal
->
head
);
pWal
->
head
.
cksumBody
=
walCalcBodyCksum
(
body
,
bodyLen
);
int64_t
offset
=
walGetCurFileOffset
(
pWal
);
pWal
->
writeHead
.
head
.
len
=
bodyLen
;
pWal
->
writeHead
.
head
.
msgType
=
msgType
;
pWal
->
writeHead
.
cksumHead
=
walCalcHeadCksum
(
&
pWal
->
writeHead
);
pWal
->
writeHead
.
cksumBody
=
walCalcBodyCksum
(
body
,
bodyLen
);
if
(
tfWrite
(
pWal
->
writeLogTfd
,
&
pWal
->
h
ead
,
sizeof
(
SWalHead
))
!=
sizeof
(
SWalHead
))
{
if
(
tfWrite
(
pWal
->
writeLogTfd
,
&
pWal
->
writeH
ead
,
sizeof
(
SWalHead
))
!=
sizeof
(
SWalHead
))
{
//ftruncate
code
=
TAOS_SYSTEM_ERROR
(
errno
);
wError
(
"vgId:%d, file:%"
PRId64
".log, failed to write since %s"
,
pWal
->
vgId
,
walGetLastFileFirstVer
(
pWal
),
strerror
(
errno
));
wError
(
"vgId:%d, file:%"
PRId64
".log, failed to write since %s"
,
pWal
->
cfg
.
vgId
,
walGetLastFileFirstVer
(
pWal
),
strerror
(
errno
));
}
if
(
tfWrite
(
pWal
->
writeLogTfd
,
&
body
,
bodyLen
)
!=
bodyLen
)
{
if
(
tfWrite
(
pWal
->
writeLogTfd
,
(
char
*
)
body
,
bodyLen
)
!=
bodyLen
)
{
//ftruncate
code
=
TAOS_SYSTEM_ERROR
(
errno
);
wError
(
"vgId:%d, file:%"
PRId64
".log, failed to write since %s"
,
pWal
->
vgId
,
walGetLastFileFirstVer
(
pWal
),
strerror
(
errno
));
wError
(
"vgId:%d, file:%"
PRId64
".log, failed to write since %s"
,
pWal
->
cfg
.
vgId
,
walGetLastFileFirstVer
(
pWal
),
strerror
(
errno
));
}
code
=
walWriteIndex
(
pWal
,
index
,
walGetCurFileOffset
(
pWal
)
);
code
=
walWriteIndex
(
pWal
,
index
,
offset
);
if
(
code
!=
0
)
{
//TODO
return
-
1
;
}
//set status
pWal
->
lastVersion
=
index
;
pWal
->
vers
.
lastVer
=
index
;
pWal
->
totSize
+=
sizeof
(
SWalHead
)
+
bodyLen
;
walGetCurFileInfo
(
pWal
)
->
lastVer
=
index
;
walGetCurFileInfo
(
pWal
)
->
fileSize
+=
sizeof
(
SWalHead
)
+
bodyLen
;
...
...
@@ -416,10 +417,10 @@ int64_t walWrite(SWal *pWal, int64_t index, uint8_t msgType, const void *body, i
}
void
walFsync
(
SWal
*
pWal
,
bool
forceFsync
)
{
if
(
forceFsync
||
(
pWal
->
level
==
TAOS_WAL_FSYNC
&&
pWal
->
fsyncPeriod
==
0
))
{
wTrace
(
"vgId:%d, fileId:%"
PRId64
".log, do fsync"
,
pWal
->
vgId
,
walGetCurFileFirstVer
(
pWal
));
if
(
forceFsync
||
(
pWal
->
cfg
.
level
==
TAOS_WAL_FSYNC
&&
pWal
->
cfg
.
fsyncPeriod
==
0
))
{
wTrace
(
"vgId:%d, fileId:%"
PRId64
".log, do fsync"
,
pWal
->
cfg
.
vgId
,
walGetCurFileFirstVer
(
pWal
));
if
(
tfFsync
(
pWal
->
writeLogTfd
)
<
0
)
{
wError
(
"vgId:%d, file:%"
PRId64
".log, fsync failed since %s"
,
pWal
->
vgId
,
walGetCurFileFirstVer
(
pWal
),
strerror
(
errno
));
wError
(
"vgId:%d, file:%"
PRId64
".log, fsync failed since %s"
,
pWal
->
cfg
.
vgId
,
walGetCurFileFirstVer
(
pWal
),
strerror
(
errno
));
}
}
}
...
...
@@ -492,29 +493,29 @@ int32_t walGetWalFile(void *handle, char *fileName, int64_t *fileId) {
}
#endif
static
int
walValidateOffset
(
SWal
*
pWal
,
int64_t
ver
)
{
int
code
=
0
;
SWalHead
*
pHead
=
NULL
;
code
=
(
int
)
walRead
(
pWal
,
&
pHead
,
ver
);
if
(
pHead
->
head
.
version
!=
ver
)
{
return
-
1
;
}
return
0
;
}
/*static int walValidateOffset(SWal* pWal, int64_t ver) {*/
/*int code = 0;*/
/*SWalHead *pHead = NULL;*/
/*code = (int)walRead(pWal, &pHead, ver);*/
/*if(pHead->head.version != ver) {*/
/*return -1;*/
/*}*/
/*return 0;*/
/*}*/
static
int64_t
walGetOffset
(
SWal
*
pWal
,
int64_t
ver
)
{
int
code
=
walSeekVer
(
pWal
,
ver
);
if
(
code
!=
0
)
{
return
-
1
;
}
/*static int64_t walGetOffset(SWal* pWal, int64_t ver) {*/
/*int code = walSeekVer(pWal, ver);*/
/*if(code != 0) {*/
/*return -1;*/
/*}*/
code
=
walValidateOffset
(
pWal
,
ver
);
if
(
code
!=
0
)
{
return
-
1
;
}
/*code = walValidateOffset(pWal, ver);*/
/*if(code != 0) {*/
/*return -1;*/
/*}*/
return
0
;
}
/*return 0;*/
/*}*/
#if 0
static int32_t walSkipCorruptedRecord(SWal *pWal, SWalHead *pHead, int64_t tfd, int64_t *offset) {
...
...
source/libs/wal/test/walMetaTest.cpp
浏览文件 @
c8ffc27e
...
...
@@ -5,6 +5,9 @@
#include "walInt.h"
const
char
*
ranStr
=
"tvapq02tcp"
;
const
int
ranStrLen
=
strlen
(
ranStr
);
class
WalCleanEnv
:
public
::
testing
::
Test
{
protected:
static
void
SetUpTestCase
()
{
...
...
@@ -24,7 +27,7 @@ class WalCleanEnv : public ::testing::Test {
pCfg
->
segSize
=
-
1
;
pCfg
->
retentionPeriod
=
0
;
pCfg
->
retentionSize
=
0
;
pCfg
->
walL
evel
=
TAOS_WAL_FSYNC
;
pCfg
->
l
evel
=
TAOS_WAL_FSYNC
;
pWal
=
walOpen
(
pathName
,
pCfg
);
free
(
pCfg
);
ASSERT
(
pWal
!=
NULL
);
...
...
@@ -56,7 +59,7 @@ class WalCleanDeleteEnv : public ::testing::Test {
memset
(
pCfg
,
0
,
sizeof
(
SWalCfg
));
pCfg
->
retentionPeriod
=
0
;
pCfg
->
retentionSize
=
0
;
pCfg
->
walL
evel
=
TAOS_WAL_FSYNC
;
pCfg
->
l
evel
=
TAOS_WAL_FSYNC
;
pWal
=
walOpen
(
pathName
,
pCfg
);
free
(
pCfg
);
ASSERT
(
pWal
!=
NULL
);
...
...
@@ -95,7 +98,7 @@ class WalKeepEnv : public ::testing::Test {
pCfg
->
segSize
=
-
1
;
pCfg
->
retentionPeriod
=
0
;
pCfg
->
retentionSize
=
0
;
pCfg
->
walL
evel
=
TAOS_WAL_FSYNC
;
pCfg
->
l
evel
=
TAOS_WAL_FSYNC
;
pWal
=
walOpen
(
pathName
,
pCfg
);
free
(
pCfg
);
ASSERT
(
pWal
!=
NULL
);
...
...
@@ -157,29 +160,27 @@ TEST_F(WalCleanEnv, removeOldMeta) {
TEST_F
(
WalKeepEnv
,
readOldMeta
)
{
walResetEnv
();
const
char
*
ranStr
=
"tvapq02tcp"
;
int
len
=
strlen
(
ranStr
);
int
code
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
code
=
walWrite
(
pWal
,
i
,
i
+
1
,
(
void
*
)
ranStr
,
l
en
);
code
=
walWrite
(
pWal
,
i
,
i
+
1
,
(
void
*
)
ranStr
,
ranStrL
en
);
ASSERT_EQ
(
code
,
0
);
ASSERT_EQ
(
pWal
->
lastVersion
,
i
);
code
=
walWrite
(
pWal
,
i
+
2
,
i
,
(
void
*
)
ranStr
,
l
en
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
i
);
code
=
walWrite
(
pWal
,
i
+
2
,
i
,
(
void
*
)
ranStr
,
ranStrL
en
);
ASSERT_EQ
(
code
,
-
1
);
ASSERT_EQ
(
pWal
->
lastVersion
,
i
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
i
);
}
char
*
oldss
=
walMetaSerialize
(
pWal
);
TearDown
();
SetUp
();
ASSERT_EQ
(
pWal
->
firstVersion
,
0
);
ASSERT_EQ
(
pWal
->
lastVersion
,
9
);
ASSERT_EQ
(
pWal
->
vers
.
firstVer
,
0
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
9
);
char
*
newss
=
walMetaSerialize
(
pWal
);
len
=
strlen
(
oldss
);
int
len
=
strlen
(
oldss
);
ASSERT_EQ
(
len
,
strlen
(
newss
));
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
EXPECT_EQ
(
oldss
[
i
],
newss
[
i
]);
...
...
@@ -189,72 +190,102 @@ TEST_F(WalKeepEnv, readOldMeta) {
}
TEST_F
(
WalCleanEnv
,
write
)
{
const
char
*
ranStr
=
"tvapq02tcp"
;
const
int
len
=
strlen
(
ranStr
);
int
code
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
code
=
walWrite
(
pWal
,
i
,
i
+
1
,
(
void
*
)
ranStr
,
l
en
);
code
=
walWrite
(
pWal
,
i
,
i
+
1
,
(
void
*
)
ranStr
,
ranStrL
en
);
ASSERT_EQ
(
code
,
0
);
ASSERT_EQ
(
pWal
->
lastVersion
,
i
);
code
=
walWrite
(
pWal
,
i
+
2
,
i
,
(
void
*
)
ranStr
,
l
en
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
i
);
code
=
walWrite
(
pWal
,
i
+
2
,
i
,
(
void
*
)
ranStr
,
ranStrL
en
);
ASSERT_EQ
(
code
,
-
1
);
ASSERT_EQ
(
pWal
->
lastVersion
,
i
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
i
);
}
code
=
walWriteMeta
(
pWal
);
ASSERT_EQ
(
code
,
0
);
}
TEST_F
(
WalCleanEnv
,
rollback
)
{
const
char
*
ranStr
=
"tvapq02tcp"
;
const
int
len
=
strlen
(
ranStr
);
int
code
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
code
=
walWrite
(
pWal
,
i
,
i
+
1
,
(
void
*
)
ranStr
,
l
en
);
code
=
walWrite
(
pWal
,
i
,
i
+
1
,
(
void
*
)
ranStr
,
ranStrL
en
);
ASSERT_EQ
(
code
,
0
);
ASSERT_EQ
(
pWal
->
lastVersion
,
i
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
i
);
}
code
=
walRollback
(
pWal
,
5
);
ASSERT_EQ
(
code
,
0
);
ASSERT_EQ
(
pWal
->
lastVersion
,
4
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
4
);
code
=
walRollback
(
pWal
,
3
);
ASSERT_EQ
(
code
,
0
);
ASSERT_EQ
(
pWal
->
lastVersion
,
2
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
2
);
code
=
walWriteMeta
(
pWal
);
ASSERT_EQ
(
code
,
0
);
}
TEST_F
(
WalCleanDeleteEnv
,
roll
)
{
const
char
*
ranStr
=
"tvapq02tcp"
;
const
int
len
=
strlen
(
ranStr
);
int
code
;
int
i
;
for
(
i
=
0
;
i
<
100
;
i
++
)
{
code
=
walWrite
(
pWal
,
i
,
0
,
(
void
*
)
ranStr
,
l
en
);
code
=
walWrite
(
pWal
,
i
,
0
,
(
void
*
)
ranStr
,
ranStrL
en
);
ASSERT_EQ
(
code
,
0
);
ASSERT_EQ
(
pWal
->
lastVersion
,
i
);
ASSERT_EQ
(
pWal
->
vers
.
lastVer
,
i
);
code
=
walCommit
(
pWal
,
i
);
ASSERT_EQ
(
pWal
->
commitVersion
,
i
);
ASSERT_EQ
(
pWal
->
vers
.
commitVer
,
i
);
}
walBeginTakeSnapshot
(
pWal
,
i
-
1
);
ASSERT_EQ
(
pWal
->
snapshottingVer
,
i
-
1
);
ASSERT_EQ
(
pWal
->
vers
.
verInSnapshotting
,
i
-
1
);
walEndTakeSnapshot
(
pWal
);
ASSERT_EQ
(
pWal
->
snapshotVersion
,
i
-
1
);
ASSERT_EQ
(
pWal
->
snapshottingVer
,
-
1
);
ASSERT_EQ
(
pWal
->
vers
.
snapshotVer
,
i
-
1
);
ASSERT_EQ
(
pWal
->
vers
.
verInSnapshotting
,
-
1
);
code
=
walWrite
(
pWal
,
5
,
0
,
(
void
*
)
ranStr
,
l
en
);
code
=
walWrite
(
pWal
,
5
,
0
,
(
void
*
)
ranStr
,
ranStrL
en
);
ASSERT_NE
(
code
,
0
);
for
(;
i
<
200
;
i
++
)
{
code
=
walWrite
(
pWal
,
i
,
0
,
(
void
*
)
ranStr
,
l
en
);
code
=
walWrite
(
pWal
,
i
,
0
,
(
void
*
)
ranStr
,
ranStrL
en
);
ASSERT_EQ
(
code
,
0
);
code
=
walCommit
(
pWal
,
i
);
ASSERT_EQ
(
pWal
->
commitVersion
,
i
);
ASSERT_EQ
(
pWal
->
vers
.
commitVer
,
i
);
}
//code = walWriteMeta(pWal);
code
=
walBeginTakeSnapshot
(
pWal
,
i
-
1
);
ASSERT_EQ
(
code
,
0
);
code
=
walEndTakeSnapshot
(
pWal
);
ASSERT_EQ
(
code
,
0
);
}
TEST_F
(
WalKeepEnv
,
readHandleRead
)
{
walResetEnv
();
int
code
;
SWalReadHandle
*
pRead
=
walOpenReadHandle
(
pWal
);
ASSERT
(
pRead
!=
NULL
);
int
i
;
for
(
i
=
0
;
i
<
100
;
i
++
)
{
char
newStr
[
100
];
sprintf
(
newStr
,
"%s-%d"
,
ranStr
,
i
);
int
len
=
strlen
(
newStr
);
code
=
walWrite
(
pWal
,
i
,
0
,
newStr
,
len
);
ASSERT_EQ
(
code
,
0
);
}
for
(
int
i
=
0
;
i
<
1000
;
i
++
)
{
int
ver
=
rand
()
%
100
;
code
=
walReadWithHandle
(
pRead
,
ver
);
ASSERT_EQ
(
code
,
0
);
//printf("rrbody: \n");
//for(int i = 0; i < pRead->pHead->head.len; i++) {
//printf("%d ", pRead->pHead->head.body[i]);
//}
//printf("\n");
ASSERT_EQ
(
pRead
->
pHead
->
head
.
version
,
ver
);
ASSERT_EQ
(
pRead
->
curVersion
,
ver
+
1
);
char
newStr
[
100
];
sprintf
(
newStr
,
"%s-%d"
,
ranStr
,
ver
);
int
len
=
strlen
(
newStr
);
ASSERT_EQ
(
pRead
->
pHead
->
head
.
len
,
len
);
for
(
int
j
=
0
;
j
<
len
;
j
++
)
{
EXPECT_EQ
(
newStr
[
j
],
pRead
->
pHead
->
head
.
body
[
j
]);
}
}
}
source/util/src/tarray.c
浏览文件 @
c8ffc27e
...
...
@@ -250,7 +250,7 @@ void taosArrayPopFrontBatch(SArray* pArray, size_t cnt) {
if
(
pArray
->
size
==
0
)
{
return
;
}
memmove
(
pArray
->
pData
,
(
char
*
)
pArray
->
pData
+
cnt
*
pArray
->
elemSize
,
pArray
->
size
);
memmove
(
pArray
->
pData
,
(
char
*
)
pArray
->
pData
+
cnt
*
pArray
->
elemSize
,
pArray
->
size
*
pArray
->
elemSize
);
}
void
taosArrayPopTailBatch
(
SArray
*
pArray
,
size_t
cnt
)
{
...
...
tests/pytest/crash_gen/valgrind_taos.supp
浏览文件 @
c8ffc27e
...
...
@@ -17515,7 +17515,7 @@
fun:gaih_inet.constprop.0
fun:getaddrinfo
fun:taosGetFqdn
fun:taosCheck
Global
Cfg
fun:taosCheck
AndPrint
Cfg
fun:taos_init_imp
}
{
...
...
@@ -17740,7 +17740,7 @@
fun:gaih_inet.constprop.7
fun:getaddrinfo
fun:taosGetFqdn
fun:taosCheck
Global
Cfg
fun:taosCheck
AndPrint
Cfg
fun:taos_init_imp
}
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录