提交 8d256e88 编写于 作者: W wpan

support index tag filter

上级 fcb26c88
......@@ -83,6 +83,12 @@ enum {
RANGE_TYPE_MR_CTX = 3,
};
enum {
FI_ACTION_NO_NEED = 1,
FI_ACTION_CONTINUE,
FI_ACTION_STOP,
};
typedef struct OptrStr {
uint16_t optr;
char *str;
......@@ -332,7 +338,8 @@ extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows,
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
extern void filterFreeInfo(SFilterInfo *info);
extern bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t numOfCols, int32_t numOfRows);
extern int32_t filterIsIndexedQuery(SFilterInfo* info, int32_t idxId, bool *res);
extern int32_t filterIsIndexedColumnQuery(SFilterInfo* info, int32_t idxId, bool *res);
extern int32_t filterGetIndexedColumnInfo(SFilterInfo* info, char** val, int32_t *order, int32_t *flag);
#ifdef __cplusplus
}
......
......@@ -2765,8 +2765,10 @@ bool filterExecuteBasedOnStatisImpl(void *pinfo, int32_t numOfRows, int8_t** p,
bool all = true;
uint16_t *unitIdx = NULL;
*p = calloc(numOfRows, sizeof(int8_t));
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
//FILTER_UNIT_CLR_F(info);
......@@ -2868,7 +2870,9 @@ static FORCE_INLINE bool filterExecuteImplIsNull(void *pinfo, int32_t numOfRows,
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
uint16_t uidx = info->groups[0].unitIdxs[0];
......@@ -2889,8 +2893,10 @@ static FORCE_INLINE bool filterExecuteImplNotNull(void *pinfo, int32_t numOfRows
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
uint16_t uidx = info->groups[0].unitIdxs[0];
void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i;
......@@ -2917,7 +2923,9 @@ bool filterExecuteImplRange(void *pinfo, int32_t numOfRows, int8_t** p, SDataSta
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
if (isNull(colData, info->cunits[0].dataType)) {
......@@ -2945,13 +2953,16 @@ bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, int8_t** p, SDataStat
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
uint16_t uidx = info->groups[0].unitIdxs[0];
void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i;
if (isNull(colData, info->cunits[uidx].dataType)) {
(*p)[i] = 0;
all = false;
continue;
}
......@@ -2975,8 +2986,10 @@ bool filterExecuteImpl(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
//FILTER_UNIT_CLR_F(info);
......@@ -3414,7 +3427,7 @@ int32_t filterFreeNcharColumns(SFilterInfo* info) {
return TSDB_CODE_SUCCESS;
}
int32_t filterIsIndexedQuery(SFilterInfo* info, int32_t idxId, bool *res) {
int32_t filterIsIndexedColumnQuery(SFilterInfo* info, int32_t idxId, bool *res) {
CHK_LRET(info == NULL, TSDB_CODE_QRY_APP_ERROR, "null parameter");
CHK_JMP(info->fields[FLD_TYPE_COLUMN].num > 1 || info->fields[FLD_TYPE_COLUMN].num <= 0);
......@@ -3425,7 +3438,8 @@ int32_t filterIsIndexedQuery(SFilterInfo* info, int32_t idxId, bool *res) {
int32_t optr = FILTER_UNIT_OPTR(info->units);
CHK_JMP(optr == TSDB_RELATION_LIKE || optr == TSDB_RELATION_IN);
CHK_JMP(optr == TSDB_RELATION_LIKE || optr == TSDB_RELATION_IN || optr == TSDB_RELATION_MATCH
|| optr == TSDB_RELATION_ISNULL || optr == TSDB_RELATION_NOTNULL);
*res = true;
......@@ -3438,4 +3452,28 @@ _return:
}
int32_t filterGetIndexedColumnInfo(SFilterInfo* info, char** val, int32_t *order, int32_t *flag) {
SFilterComUnit *cunit = info->cunits;
uint8_t optr = cunit->optr;
*val = cunit->valData;
*order = TSDB_ORDER_ASC;
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
*order = TSDB_ORDER_DESC;
}
if (optr == TSDB_RELATION_NOT_EQUAL) {
*order = TSDB_ORDER_ASC|TSDB_ORDER_DESC;
}
if (cunit->valData2 == cunit->valData && optr != TSDB_RELATION_EQUAL) {
FILTER_SET_FLAG(*flag, FI_ACTION_NO_NEED);
}
return TSDB_CODE_SUCCESS;
}
......@@ -3887,165 +3887,78 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) {
}
#if 0
static void queryIndexedColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) {
SSkipListIterator* iter = NULL;
SQueryCond cond = {0};
if (setQueryCond(pQueryInfo, &cond) != TSDB_CODE_SUCCESS) {
//todo handle error
}
if (cond.start != NULL) {
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->type, TSDB_ORDER_ASC);
static FORCE_INLINE int32_t tsdbGetTagDataFromId(void *param, int32_t id, void **data) {
STable* pTable = (STable*)(SL_GET_NODE_DATA((SSkipListNode *)param));
if (id == TSDB_TBNAME_COLUMN_INDEX) {
*data = TABLE_NAME(pTable);
} else {
iter = tSkipListCreateIterFromVal(pSkipList, (char*)(cond.end ? cond.end->v: NULL), pSkipList->type, TSDB_ORDER_DESC);
*data = tdGetKVRowValOfCol(pTable->tagVal, id);
}
if (cond.start != NULL) {
int32_t optr = cond.start->optr;
if (optr == TSDB_RELATION_EQUAL) { // equals
while(tSkipListIterNext(iter)) {
SSkipListNode* pNode = tSkipListIterGet(iter);
int32_t ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
if (ret != 0) {
break;
}
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
}
} else if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL) { // greater equal
bool comp = true;
int32_t ret = 0;
while(tSkipListIterNext(iter)) {
SSkipListNode* pNode = tSkipListIterGet(iter);
if (comp) {
ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
assert(ret >= 0);
}
if (ret == 0 && optr == TSDB_RELATION_GREATER) {
continue;
} else {
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
comp = false;
}
}
} else if (optr == TSDB_RELATION_NOT_EQUAL) { // not equal
bool comp = true;
while(tSkipListIterNext(iter)) {
SSkipListNode* pNode = tSkipListIterGet(iter);
comp = comp && (pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v) == 0);
if (comp) {
continue;
}
return TSDB_CODE_SUCCESS;
}
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
}
tSkipListDestroyIter(iter);
comp = true;
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->type, TSDB_ORDER_DESC);
while(tSkipListIterNext(iter)) {
SSkipListNode* pNode = tSkipListIterGet(iter);
comp = comp && (pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v) == 0);
if (comp) {
continue;
}
static void queryIndexedColumn(SSkipList* pSkipList, void* filterInfo, SArray* res) {
SSkipListIterator* iter = NULL;
char *startVal = NULL;
int32_t order = 0;
int32_t inRange = 0;
int32_t flag = 0;
bool all = false;
int8_t *addToResult = NULL;
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
}
filterGetIndexedColumnInfo(filterInfo, &startVal, &order, &flag);
} else if (optr == TSDB_RELATION_IN) {
while(tSkipListIterNext(iter)) {
SSkipListNode* pNode = tSkipListIterGet(iter);
tsdbDebug("filter index column start, order:%d, flag:%d", order, flag);
int32_t ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
if (ret != 0) {
break;
}
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
}
while (order) {
if (FILTER_GET_FLAG(order, TSDB_ORDER_ASC)) {
iter = tSkipListCreateIterFromVal(pSkipList, startVal, pSkipList->type, TSDB_ORDER_ASC);
FILTER_CLR_FLAG(order, TSDB_ORDER_ASC);
} else {
assert(0);
iter = tSkipListCreateIterFromVal(pSkipList, startVal, pSkipList->type, TSDB_ORDER_DESC);
FILTER_CLR_FLAG(order, TSDB_ORDER_DESC);
}
} else {
int32_t optr = cond.end ? cond.end->optr : TSDB_RELATION_INVALID;
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
bool comp = true;
int32_t ret = 0;
while (tSkipListIterNext(iter)) {
SSkipListNode *pNode = tSkipListIterGet(iter);
if (comp) {
ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.end->v);
assert(ret <= 0);
}
while (tSkipListIterNext(iter)) {
SSkipListNode *pNode = tSkipListIterGet(iter);
if (ret == 0 && optr == TSDB_RELATION_LESS) {
continue;
} else {
STableKeyInfo info = {.pTable = (void *)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
comp = false; // no need to compare anymore
}
if (inRange == 0 || !FILTER_GET_FLAG(flag, FI_ACTION_NO_NEED)) {
tsdbDebug("filter index column, filter it");
filterSetColFieldData(filterInfo, pNode, tsdbGetTagDataFromId);
all = filterExecute(filterInfo, 1, &addToResult, NULL, 0);
}
} else {
assert(pQueryInfo->optr == TSDB_RELATION_ISNULL || pQueryInfo->optr == TSDB_RELATION_NOTNULL);
char *pData = SL_GET_NODE_DATA(pNode);
while (tSkipListIterNext(iter)) {
SSkipListNode *pNode = tSkipListIterGet(iter);
tsdbDebug("filter index column, table:%s, result:%d", ((STable *)pData)->name->data, all);
bool isnull = isNull(SL_GET_NODE_KEY(pSkipList, pNode), pQueryInfo->sch.type);
if ((pQueryInfo->optr == TSDB_RELATION_ISNULL && isnull) ||
(pQueryInfo->optr == TSDB_RELATION_NOTNULL && (!isnull))) {
STableKeyInfo info = {.pTable = (void *)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
}
if (all || (addToResult && *addToResult)) {
STableKeyInfo info = {.pTable = (void*)pData, .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(res, &info);
inRange = 1;
} else if (inRange){
break;
}
}
}
free(cond.start);
free(cond.end);
tSkipListDestroyIter(iter);
}
#endif
inRange = 0;
static FORCE_INLINE int32_t tsdbGetTagDataFromId(void *param, int32_t id, void **data) {
STable* pTable = (STable*)(SL_GET_NODE_DATA((SSkipListNode *)param));
if (id == TSDB_TBNAME_COLUMN_INDEX) {
*data = TABLE_NAME(pTable);
} else {
*data = tdGetKVRowValOfCol(pTable->tagVal, id);
tfree(addToResult);
tSkipListDestroyIter(iter);
}
return TSDB_CODE_SUCCESS;
tsdbDebug("filter index column end");
}
static void queryIndexlessColumn(SSkipList* pSkipList, void* filterInfo, SArray* res) {
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
int8_t *addToResult = NULL;
while (tSkipListIterNext(iter)) {
int8_t *addToResult = NULL;
SSkipListNode *pNode = tSkipListIterGet(iter);
......@@ -4058,9 +3971,11 @@ static void queryIndexlessColumn(SSkipList* pSkipList, void* filterInfo, SArray*
if (all || (addToResult && *addToResult)) {
STableKeyInfo info = {.pTable = (void*)pData, .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(res, &info);
}
}
}
tfree(addToResult);
tSkipListDestroyIter(iter);
}
......@@ -4070,13 +3985,13 @@ static int32_t tsdbQueryTableList(STable* pTable, SArray* pRes, void* filterInfo
bool indexQuery = false;
SSkipList *pSkipList = pTable->pIndex;
filterIsIndexedQuery(filterInfo, pTSSchema->columns->colId, &indexQuery);
filterIsIndexedColumnQuery(filterInfo, pTSSchema->columns->colId, &indexQuery);
//if (indexQuery) {
//queryIndexedColumn(pSkipList, filterInfo, pRes);
//} else {
if (indexQuery) {
queryIndexedColumn(pSkipList, filterInfo, pRes);
} else {
queryIndexlessColumn(pSkipList, filterInfo, pRes);
//}
}
return TSDB_CODE_SUCCESS;
}
......
......@@ -203,3 +203,91 @@ sleep 100
run general/parser/condition_query.sim
run general/parser/condition_query2.sim
sql drop database if exists cdb
system sh/exec.sh -n dnode1 -s stop -x SIGINT
sleep 100
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 1000
system sh/cfg.sh -n dnode1 -c minTablesPerVnode -v 1000
system sh/exec.sh -n dnode1 -s start
sql create database if not exists cdb
sql use cdb
sql create table stba (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int)
sql create table stbb (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 bool)
sql create table stbc (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 float)
sql create table stbd (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 binary(10))
sql create table stbe (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 nchar(10))
sql create table tba_0 using stba tags(0)
sql create table tba_1 using stba tags(1)
sql create table tba_2 using stba tags(2)
sql create table tba_3 using stba tags(3)
sql create table tba_4 using stba tags(4)
sql create table tba_5 using stba tags(5)
sql create table tba_6 using stba tags(6)
sql create table tba_7 using stba tags(7)
sql create table tba_8 using stba tags(8)
sql create table tba_9 using stba tags(9)
sql create table tbb_0 using stbb tags(true)
sql create table tbb_1 using stbb tags(false)
sql create table tbb_2 using stbb tags(true)
sql create table tbb_3 using stbb tags(false)
sql create table tbb_4 using stbb tags(true)
sql create table tbb_5 using stbb tags(false)
sql create table tbb_6 using stbb tags(true)
sql create table tbb_7 using stbb tags(false)
sql create table tbb_8 using stbb tags(true)
sql create table tbb_9 using stbb tags(false)
sql create table tbc_0 using stbc tags(0)
sql create table tbc_1 using stbc tags(1)
sql create table tbc_2 using stbc tags(2)
sql create table tbc_3 using stbc tags(3)
sql create table tbc_4 using stbc tags(4)
sql create table tbc_5 using stbc tags(5)
sql create table tbc_6 using stbc tags(6)
sql create table tbc_7 using stbc tags(7)
sql create table tbc_8 using stbc tags(8)
sql create table tbc_9 using stbc tags(9)
sql create table tbd_0 using stbd tags('0000')
sql create table tbd_1 using stbd tags('1111')
sql create table tbd_2 using stbd tags('2222')
sql create table tbd_3 using stbd tags('3333')
sql create table tbd_4 using stbd tags('4444')
sql create table tbd_5 using stbd tags('5555')
sql create table tbd_6 using stbd tags('6666')
sql create table tbd_7 using stbd tags('7777')
sql create table tbd_8 using stbd tags('8888')
sql create table tbd_9 using stbd tags('9999')
sql create table tbe_0 using stbe tags('0000')
sql create table tbe_1 using stbe tags('1111')
sql create table tbe_2 using stbe tags('2222')
sql create table tbe_3 using stbe tags('3333')
sql create table tbe_4 using stbe tags('4444')
sql create table tbe_5 using stbe tags('5555')
sql create table tbe_6 using stbe tags('6666')
sql create table tbe_7 using stbe tags('7777')
sql create table tbe_8 using stbe tags('8888')
sql create table tbe_9 using stbe tags('9999')
run general/parser/condition_query3.sim
system sh/exec.sh -n dnode1 -s stop -x SIGINT
sleep 100
system sh/exec.sh -n dnode1 -s start
run general/parser/condition_query3.sim
......@@ -1159,6 +1159,27 @@ if $data30 != @21-05-05 18:19:11.000@ then
return -1
endi
sql select * from stb5 where t1 <> 1;
if $rows != 34 then
return -1
endi
sql select t1,ts,c1 from stb5 where t1 <> '2021-05-05 18:19:01.000'
if $rows != 26 then
return -1
endi
sql select t1,ts,c1 from stb5 where t1 <> '2021-05-05 18:19:01.000' and t1 <> '2021-05-05 18:19:08.000';
if $rows != 21 then
return -1
endi
sql select t1,ts,c1 from stb5 where t1 > '2021-05-05 18:19:02.000';
if $rows != 22 then
return -1
endi
print "join test"
sql_error select * from tb1, tb2_1 where tb1.ts=tb2_1.ts or tb1.ts =tb2_1.ts;
sql select tb1.ts from tb1, tb2_1 where tb1.ts=tb2_1.ts and tb1.ts > '2021-05-05 18:19:03.000' and tb2_1.ts < '2021-05-05 18:19:06.000';
......
sql use cdb;
print "index tag test"
sql select tbname,t1 from stba;
if $rows != 10 then
return -1
endi
sql select tbname,t1 from stba where t1 > 2;
if $rows != 7 then
return -1
endi
sql select tbname,t1 from stba where t1 >= 4;
if $rows != 6 then
return -1
endi
sql select tbname,t1 from stba where t1 >= 3 and t1 <= 6;
if $rows != 4 then
return -1
endi
sql select tbname,t1 from stba where t1 = 3;
if $rows != 1 then
return -1
endi
sql select tbname,t1 from stba where t1 <> 6;
if $rows != 9 then
return -1
endi
sql select tbname,t1 from stba where t1 < 6;
if $rows != 6 then
return -1
endi
sql select tbname,t1 from stba where t1 < 6 and t1 >= 2;
if $rows != 4 then
return -1
endi
sql_error select tbname,t1 from stbb where t1 > true;
sql select tbname,t1 from stbb where t1 = true;
if $rows != 5 then
return -1
endi
sql select tbname,t1 from stbb where t1 <> true;
if $rows != 5 then
return -1
endi
sql select tbname,t1 from stbc;
if $rows != 10 then
return -1
endi
sql select tbname,t1 from stbc where t1 > 2;
if $rows != 7 then
return -1
endi
sql select tbname,t1 from stbc where t1 >= 4;
if $rows != 6 then
return -1
endi
sql select tbname,t1 from stbc where t1 >= 3 and t1 <= 6;
if $rows != 4 then
return -1
endi
sql select tbname,t1 from stbc where t1 = 3;
if $rows != 1 then
return -1
endi
sql select tbname,t1 from stbc where t1 <> 6;
if $rows != 9 then
return -1
endi
sql select tbname,t1 from stbc where t1 < 6;
if $rows != 6 then
return -1
endi
sql select tbname,t1 from stbc where t1 < 6 and t1 >= 2;
if $rows != 4 then
return -1
endi
sql select tbname,t1 from stbd where t1 > '2222';
if $rows != 7 then
return -1
endi
sql select tbname,t1 from stbd where t1 >= '4444';
if $rows != 6 then
return -1
endi
sql select tbname,t1 from stbd where t1 >= '3333' and t1 <= '6666';
if $rows != 4 then
return -1
endi
sql select tbname,t1 from stbd where t1 = '3333';
if $rows != 1 then
return -1
endi
sql select tbname,t1 from stbd where t1 <> '6666';
if $rows != 9 then
return -1
endi
sql select tbname,t1 from stbd where t1 < '6666';
if $rows != 6 then
return -1
endi
sql select tbname,t1 from stbd where t1 < '6666' and t1 >= '2222';
if $rows != 4 then
return -1
endi
sql select tbname,t1 from stbe where t1 > '2222';
if $rows != 7 then
return -1
endi
sql select tbname,t1 from stbe where t1 >= '4444';
if $rows != 6 then
return -1
endi
sql select tbname,t1 from stbe where t1 >= '3333' and t1 <= '6666';
if $rows != 4 then
return -1
endi
sql select tbname,t1 from stbe where t1 = '3333';
if $rows != 1 then
return -1
endi
sql select tbname,t1 from stbe where t1 <> '6666';
if $rows != 9 then
return -1
endi
sql select tbname,t1 from stbe where t1 < '6666';
if $rows != 6 then
return -1
endi
sql select tbname,t1 from stbe where t1 < '6666' and t1 >= '2222';
if $rows != 4 then
return -1
endi
#system sh/exec.sh -n dnode1 -s stop -x SIGINT
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册