提交 77b54b57 编写于 作者: A Alex Duan

[TS-238]<feature>(tsdb): undo no use code and need not modify code

上级 7a7e8072
...@@ -560,7 +560,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -560,7 +560,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
if (pInfo == NULL || pSql == NULL) { if (pInfo == NULL || pSql == NULL) {
return TSDB_CODE_TSC_APP_ERROR; return TSDB_CODE_TSC_APP_ERROR;
} }
......
...@@ -440,7 +440,6 @@ int taos_affected_tables(TAOS_RES *tres) { ...@@ -440,7 +440,6 @@ int taos_affected_tables(TAOS_RES *tres) {
return pSql->res.numOfTables; return pSql->res.numOfTables;
} }
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
SSqlObj *pSql = (SSqlObj *)res; SSqlObj *pSql = (SSqlObj *)res;
SSqlRes *pRes = &pSql->res; SSqlRes *pRes = &pSql->res;
......
...@@ -22,9 +22,6 @@ ...@@ -22,9 +22,6 @@
extern "C" { extern "C" {
#endif #endif
// global definition
extern bool isBigEndian;
// cluster // cluster
extern char tsFirst[]; extern char tsFirst[];
extern char tsSecond[]; extern char tsSecond[];
...@@ -118,7 +115,6 @@ extern int8_t tsCacheLastRow; ...@@ -118,7 +115,6 @@ extern int8_t tsCacheLastRow;
// tsdb // tsdb
extern bool tsdbForceKeepFile; extern bool tsdbForceKeepFile;
extern bool tsdbForceTruncateFile;
extern bool tsdbForceCompactFile; extern bool tsdbForceCompactFile;
extern int32_t tsdbWalFlushSize; extern int32_t tsdbWalFlushSize;
......
...@@ -161,7 +161,6 @@ int32_t tsTsdbMetaCompactRatio = TSDB_META_COMPACT_RATIO; ...@@ -161,7 +161,6 @@ int32_t tsTsdbMetaCompactRatio = TSDB_META_COMPACT_RATIO;
// For backward compatibility // For backward compatibility
bool tsdbForceKeepFile = false; bool tsdbForceKeepFile = false;
bool tsdbForceCompactFile = false; // compact TSDB fileset forcibly bool tsdbForceCompactFile = false; // compact TSDB fileset forcibly
bool tsdbForceTruncateFile = false;
int32_t tsdbWalFlushSize = TSDB_DEFAULT_WAL_FLUSH_SIZE; // MB int32_t tsdbWalFlushSize = TSDB_DEFAULT_WAL_FLUSH_SIZE; // MB
// balance // balance
......
...@@ -24,14 +24,10 @@ static tsem_t exitSem; ...@@ -24,14 +24,10 @@ static tsem_t exitSem;
static void siguser1Handler(int32_t signum, void *sigInfo, void *context); static void siguser1Handler(int32_t signum, void *sigInfo, void *context);
static void siguser2Handler(int32_t signum, void *sigInfo, void *context); static void siguser2Handler(int32_t signum, void *sigInfo, void *context);
static void sigintHandler(int32_t signum, void *sigInfo, void *context); static void sigintHandler(int32_t signum, void *sigInfo, void *context);
static const int __TEST_NUMBER__ = 1;
bool isBigEndian = false;
int32_t main(int32_t argc, char *argv[]) { int32_t main(int32_t argc, char *argv[]) {
int dump_config = 0; int dump_config = 0;
isBigEndian = (*(char *)&__TEST_NUMBER__) == 0;
// Set global configuration file // Set global configuration file
for (int32_t i = 1; i < argc; ++i) { for (int32_t i = 1; i < argc; ++i) {
if (strcmp(argv[i], "-c") == 0) { if (strcmp(argv[i], "-c") == 0) {
...@@ -47,8 +43,6 @@ int32_t main(int32_t argc, char *argv[]) { ...@@ -47,8 +43,6 @@ int32_t main(int32_t argc, char *argv[]) {
} }
} else if (strcmp(argv[i], "-C") == 0) { } else if (strcmp(argv[i], "-C") == 0) {
dump_config = 1; dump_config = 1;
} else if (strcmp(argv[i], "--force-truncate-file") == 0) {
tsdbForceTruncateFile = true;
} else if (strcmp(argv[i], "--force-compact-file") == 0) { } else if (strcmp(argv[i], "--force-compact-file") == 0) {
tsdbForceCompactFile = true; tsdbForceCompactFile = true;
} else if (strcmp(argv[i], "--force-keep-file") == 0) { } else if (strcmp(argv[i], "--force-keep-file") == 0) {
......
...@@ -191,22 +191,11 @@ static int32_t dnodeProcessSyncVnodeMsg(SRpcMsg *rpcMsg) { ...@@ -191,22 +191,11 @@ static int32_t dnodeProcessSyncVnodeMsg(SRpcMsg *rpcMsg) {
return vnodeSync(pSyncVnode->vgId); return vnodeSync(pSyncVnode->vgId);
} }
#ifdef __TRUNCATE_TEST__
static int32_t dnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg) { static int32_t dnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg) {
SCompactVnodeMsg *pCompactVnode = rpcMsg->pCont; SCompactVnodeMsg *pCompactVnode = rpcMsg->pCont;
pCompactVnode->vgId = htonl(pCompactVnode->vgId); pCompactVnode->vgId = htonl(pCompactVnode->vgId);
return vnodeCompact(pCompactVnode->vgId); return vnodeCompact(pCompactVnode->vgId);
} }
#else
static int32_t dnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg) {
STruncateTblMsg *pTruncateMsg = rpcMsg->pCont;
return vnodeTruncateTbl(pTruncateMsg);
}
// static int32_t dnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg) {
// SDeleteDataMsg *pDeleteDataMsg = rpcMsg->pCont;
// return vnodeDeleteData(pDeleteDataMsg);
// }
#endif
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) { static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
SDropVnodeMsg *pDrop = rpcMsg->pCont; SDropVnodeMsg *pDrop = rpcMsg->pCont;
......
...@@ -96,7 +96,7 @@ int tsdbCloseRepo(STsdbRepo *repo, int toCommit); ...@@ -96,7 +96,7 @@ int tsdbCloseRepo(STsdbRepo *repo, int toCommit);
int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg); int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg);
int tsdbGetState(STsdbRepo *repo); int tsdbGetState(STsdbRepo *repo);
int8_t tsdbGetCompactState(STsdbRepo *repo); int8_t tsdbGetCompactState(STsdbRepo *repo);
int8_t tsdbGetTruncateState(STsdbRepo *repo); int8_t tsdbGetDeleteState(STsdbRepo *repo);
// --------- TSDB TABLE DEFINITION // --------- TSDB TABLE DEFINITION
typedef struct { typedef struct {
uint64_t uid; // the unique table ID uint64_t uid; // the unique table ID
...@@ -421,9 +421,6 @@ int tsdbSyncRecv(void *pRepo, SOCKET socketFd); ...@@ -421,9 +421,6 @@ int tsdbSyncRecv(void *pRepo, SOCKET socketFd);
// For TSDB Compact // For TSDB Compact
int tsdbCompact(STsdbRepo *pRepo); int tsdbCompact(STsdbRepo *pRepo);
// For TSDB truncate table
int tsdbTruncateTbl(STsdbRepo *pRepo, void *param);
// For TSDB delete data // For TSDB delete data
int tsdbDeleteData(STsdbRepo *pRepo, void *param); int tsdbDeleteData(STsdbRepo *pRepo, void *param);
......
...@@ -77,8 +77,6 @@ int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg); ...@@ -77,8 +77,6 @@ int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeSync(int32_t vgId); int32_t vnodeSync(int32_t vgId);
int32_t vnodeClose(int32_t vgId); int32_t vnodeClose(int32_t vgId);
int32_t vnodeCompact(int32_t vgId); int32_t vnodeCompact(int32_t vgId);
int32_t vnodeTruncateTbl(STruncateTblMsg *pMsg);
int32_t vnodeDeleteData(SDeleteDataMsg *pMsg);
// vnodeMgmt // vnodeMgmt
int32_t vnodeInitMgmt(); int32_t vnodeInitMgmt();
......
...@@ -146,8 +146,7 @@ typedef struct SVgObj { ...@@ -146,8 +146,7 @@ typedef struct SVgObj {
SVnodeGid vnodeGid[TSDB_MAX_REPLICA]; SVnodeGid vnodeGid[TSDB_MAX_REPLICA];
int32_t vgCfgVersion; int32_t vgCfgVersion;
int8_t compact; int8_t compact;
int8_t truncate; int8_t reserved1[8];
int8_t reserved1[6];
int8_t updateEnd[4]; int8_t updateEnd[4];
int32_t refCount; int32_t refCount;
int32_t numOfTables; int32_t numOfTables;
......
...@@ -352,8 +352,7 @@ void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVl ...@@ -352,8 +352,7 @@ void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVl
pVgroup->pDb->dbCfgVersion, pVgroup->vgCfgVersion, pVgroup->numOfVnodes); pVgroup->pDb->dbCfgVersion, pVgroup->vgCfgVersion, pVgroup->numOfVnodes);
mnodeSendAlterVgroupMsg(pVgroup,NULL); mnodeSendAlterVgroupMsg(pVgroup,NULL);
} }
pVgroup->compact = (int8_t)pVload->compact; pVgroup->compact = pVload->compact;
pVgroup->truncate = (int8_t)pVload->truncate;
} }
static int32_t mnodeAllocVgroupIdPool(SVgObj *pInputVgroup) { static int32_t mnodeAllocVgroupIdPool(SVgObj *pInputVgroup) {
...@@ -849,11 +848,6 @@ static int32_t mnodeRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, v ...@@ -849,11 +848,6 @@ static int32_t mnodeRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, v
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
*(int8_t *)pWrite = pVgroup->compact; *(int8_t *)pWrite = pVgroup->compact;
cols++; cols++;
// pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
// *(int8_t *)pWrite = pVgroup->truncate;
// cols++;
mnodeDecVgroupRef(pVgroup); mnodeDecVgroupRef(pVgroup);
numOfRows++; numOfRows++;
} }
......
...@@ -1310,22 +1310,6 @@ void setDropDbTableInfo(SSqlInfo *pInfo, int32_t type, SStrToken* pToken, SStrTo ...@@ -1310,22 +1310,6 @@ void setDropDbTableInfo(SSqlInfo *pInfo, int32_t type, SStrToken* pToken, SStrTo
pInfo->pMiscInfo->tableType = tableType; pInfo->pMiscInfo->tableType = tableType;
} }
void setTruncateTableInfo(SSqlInfo *pInfo, int32_t type, SStrToken* pToken, SStrToken* existsCheck, int16_t dbType, int16_t tableType) {
pInfo->type = type;
if (pInfo->pMiscInfo == NULL) {
pInfo->pMiscInfo = (SMiscInfo *)calloc(1, sizeof(SMiscInfo));
pInfo->pMiscInfo->a = taosArrayInit(4, sizeof(SStrToken));
}
taosArrayPush(pInfo->pMiscInfo->a, pToken);
pInfo->pMiscInfo->existsCheck = (existsCheck->n == 1);
pInfo->pMiscInfo->dbType = dbType;
pInfo->pMiscInfo->tableType = tableType;
}
void setDropFuncInfo(SSqlInfo *pInfo, int32_t type, SStrToken* pToken) { void setDropFuncInfo(SSqlInfo *pInfo, int32_t type, SStrToken* pToken) {
pInfo->type = type; pInfo->type = type;
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#define TSDB_FILE_HEAD_SIZE 512 #define TSDB_FILE_HEAD_SIZE 512
#define TSDB_FILE_DELIMITER 0xF00AFA0F #define TSDB_FILE_DELIMITER 0xF00AFA0F
#define TSDB_FILE_DELIMITER_DELETE 0xF00AFA1F
#define TSDB_FILE_INIT_MAGIC 0xFFFFFFFF #define TSDB_FILE_INIT_MAGIC 0xFFFFFFFF
#define TSDB_IVLD_FID INT_MIN #define TSDB_IVLD_FID INT_MIN
#define TSDB_FILE_STATE_OK 0 #define TSDB_FILE_STATE_OK 0
......
...@@ -48,9 +48,9 @@ typedef struct STable { ...@@ -48,9 +48,9 @@ typedef struct STable {
SDataCol *lastCols; SDataCol *lastCols;
int16_t maxColNum; int16_t maxColNum;
int16_t restoreColumnNum; int16_t restoreColumnNum;
int16_t cacheLastConfigVersion;
bool hasRestoreLastColumn; bool hasRestoreLastColumn;
int lastColSVersion; int lastColSVersion;
int16_t cacheLastConfigVersion;
T_REF_DECLARE() // int32_t T_REF_DECLARE() // int32_t
} STable; } STable;
......
...@@ -153,7 +153,7 @@ static FORCE_INLINE uint32_t tsdbGetBlockColOffset(SBlockCol *pBlockCol) { ...@@ -153,7 +153,7 @@ static FORCE_INLINE uint32_t tsdbGetBlockColOffset(SBlockCol *pBlockCol) {
} }
typedef struct { typedef struct {
int32_t delimiter; // For recovery usage(not included when calculating checksum) int32_t delimiter; // For recovery usage
int32_t numOfCols; // For recovery usage int32_t numOfCols; // For recovery usage
uint64_t uid; // For recovery usage uint64_t uid; // For recovery usage
SBlockCol cols[]; SBlockCol cols[];
......
...@@ -214,7 +214,7 @@ int tsdbGetState(STsdbRepo *repo) { return repo->state; } ...@@ -214,7 +214,7 @@ int tsdbGetState(STsdbRepo *repo) { return repo->state; }
int8_t tsdbGetCompactState(STsdbRepo *repo) { return (int8_t)(repo->compactState); } int8_t tsdbGetCompactState(STsdbRepo *repo) { return (int8_t)(repo->compactState); }
int8_t tsdbGetTruncateState(STsdbRepo *repo) { return (int8_t)(repo->deleteState); } int8_t tsdbGetDeleteState(STsdbRepo *repo) { return (int8_t)(repo->deleteState); }
void tsdbReportStat(void *repo, int64_t *totalPoints, int64_t *totalStorage, int64_t *compStorage) { void tsdbReportStat(void *repo, int64_t *totalPoints, int64_t *totalStorage, int64_t *compStorage) {
ASSERT(repo != NULL); ASSERT(repo != NULL);
......
...@@ -639,7 +639,7 @@ static int32_t lazyLoadCacheLast(STsdbQueryHandle* pQueryHandle) { ...@@ -639,7 +639,7 @@ static int32_t lazyLoadCacheLast(STsdbQueryHandle* pQueryHandle) {
initTableMemIterator(pQueryHandle, pCheckInfo); initTableMemIterator(pQueryHandle, pCheckInfo);
} }
code = tsdbLoadLastCache(pRepo, pTable); code = tsdbLoadLastCache(pRepo, pTable, false);
if (code != 0) { if (code != 0) {
tsdbError("%p uid:%" PRId64 ", tid:%d, failed to load last cache since %s", pQueryHandle, pTable->tableId.uid, tsdbError("%p uid:%" PRId64 ", tid:%d, failed to load last cache since %s", pQueryHandle, pTable->tableId.uid,
pTable->tableId.tid, tstrerror(terrno)); pTable->tableId.tid, tstrerror(terrno));
......
...@@ -449,8 +449,6 @@ static int tsdbLoadBlockStatisFromDFile(SReadH *pReadh, SBlock *pBlock) { ...@@ -449,8 +449,6 @@ static int tsdbLoadBlockStatisFromDFile(SReadH *pReadh, SBlock *pBlock) {
return -1; return -1;
} }
pReadh->pBlkData->delimiter = TSDB_FILE_DELIMITER; // reset in case of TSDB_FILE_DELIMITER_DELETE
if (!taosCheckChecksumWhole((uint8_t *)(pReadh->pBlkData), (uint32_t)size)) { if (!taosCheckChecksumWhole((uint8_t *)(pReadh->pBlkData), (uint32_t)size)) {
terrno = TSDB_CODE_TDB_FILE_CORRUPTED; terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
tsdbError("vgId:%d block statis part in file %s is corrupted since wrong checksum, offset:%" PRId64 " len :%" PRIzu, tsdbError("vgId:%d block statis part in file %s is corrupted since wrong checksum, offset:%" PRId64 " len :%" PRIzu,
...@@ -653,8 +651,6 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat ...@@ -653,8 +651,6 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat
return -1; return -1;
} }
pBlockData->delimiter = TSDB_FILE_DELIMITER; // reset in case of TSDB_FILE_DELIMITER_DELETE
int32_t tsize = (int32_t)tsdbBlockStatisSize(pBlock->numOfCols, (uint32_t)pBlock->blkVer); int32_t tsize = (int32_t)tsdbBlockStatisSize(pBlock->numOfCols, (uint32_t)pBlock->blkVer);
if (!taosCheckChecksumWhole((uint8_t *)TSDB_READ_BUF(pReadh), tsize)) { if (!taosCheckChecksumWhole((uint8_t *)TSDB_READ_BUF(pReadh), tsize)) {
terrno = TSDB_CODE_TDB_FILE_CORRUPTED; terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
......
...@@ -120,7 +120,7 @@ int32_t vnodeDrop(int32_t vgId) { ...@@ -120,7 +120,7 @@ int32_t vnodeDrop(int32_t vgId) {
int32_t vnodeCompact(int32_t vgId) { int32_t vnodeCompact(int32_t vgId) {
void *pVnode = vnodeAcquire(vgId); void *pVnode = vnodeAcquire(vgId);
if (pVnode != NULL) { if (pVnode != NULL) {
printf("vgId:%d, compact vnode msg is received\n", vgId); vDebug("vgId:%d, compact vnode msg is received\n", vgId);
//not care success or not //not care success or not
tsdbCompact(((SVnodeObj*)pVnode)->tsdb); tsdbCompact(((SVnodeObj*)pVnode)->tsdb);
vnodeRelease(pVnode); vnodeRelease(pVnode);
...@@ -128,56 +128,9 @@ int32_t vnodeCompact(int32_t vgId) { ...@@ -128,56 +128,9 @@ int32_t vnodeCompact(int32_t vgId) {
vInfo("vgId:%d, vnode not exist, can't compact it", vgId); vInfo("vgId:%d, vnode not exist, can't compact it", vgId);
return TSDB_CODE_VND_INVALID_VGROUP_ID; return TSDB_CODE_VND_INVALID_VGROUP_ID;
} }
printf("vgId:%d, compact vnode msg is finished\n", vgId);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t vnodeTruncateTbl(STruncateTblMsg *pMsg) {
int32_t vgId = 2;
void * pVnode = vnodeAcquire(vgId);
if (pVnode != NULL) {
vDebug("vgId:%d, truncate table %s msg is received", vgId, pMsg->tableFname);
// not care success or not
STruncateTblMsg *param = (STruncateTblMsg *)calloc(1, sizeof(STruncateTblMsg) + pMsg->nSpan * sizeof(STimeWindow));
param->vgId = 2;
param->uid = 562949986978880;
param->nSpan = 1;
param->span[0].skey = 1634701320001;
param->span[0].ekey = 1634701320001;
//if (tsdbTruncateTbl(((SVnodeObj *)pVnode)->tsdb, param) < 0) {
// tfree(param);
//}
vnodeRelease(pVnode);
} else {
vInfo("vgId:%d, vnode not exist, can't truncate table %s in it", vgId, pMsg->tableFname);
return TSDB_CODE_VND_INVALID_VGROUP_ID;
}
return TSDB_CODE_SUCCESS;
}
int32_t vnodeDeleteData(SDeleteDataMsg *pMsg) {
int32_t vgId = 2;
void * pVnode = vnodeAcquire(vgId);
if (pVnode != NULL) {
vDebug("vgId:%d, truncate table %s msg is received", vgId, pMsg->tableFname);
// not care success or not
SDeleteDataMsg *param = (SDeleteDataMsg *)calloc(1, sizeof(STruncateTblMsg) + pMsg->nSpan * sizeof(STimeWindow));
param->vgId = 2;
param->uid = 562949986978880;
param->nSpan = 1;
param->span[0].skey = 1634701320001;
param->span[0].ekey = 1634701320001;
//if (tsdbDeleteData(((SVnodeObj *)pVnode)->tsdb, param) < 0) {
// tfree(param);
//}
vnodeRelease(pVnode);
} else {
vInfo("vgId:%d, vnode not exist, can't truncate table %s in it", vgId, pMsg->tableFname);
return TSDB_CODE_VND_INVALID_VGROUP_ID;
}
return TSDB_CODE_SUCCESS;
}
static int32_t vnodeAlterImp(SVnodeObj *pVnode, SCreateVnodeMsg *pVnodeCfg) { static int32_t vnodeAlterImp(SVnodeObj *pVnode, SCreateVnodeMsg *pVnodeCfg) {
STsdbCfg tsdbCfg = pVnode->tsdbCfg; STsdbCfg tsdbCfg = pVnode->tsdbCfg;
SSyncCfg syncCfg = pVnode->syncCfg; SSyncCfg syncCfg = pVnode->syncCfg;
......
...@@ -163,7 +163,6 @@ static void vnodeBuildVloadMsg(SVnodeObj *pVnode, SStatusMsg *pStatus) { ...@@ -163,7 +163,6 @@ static void vnodeBuildVloadMsg(SVnodeObj *pVnode, SStatusMsg *pStatus) {
pLoad->role = pVnode->role; pLoad->role = pVnode->role;
pLoad->replica = pVnode->syncCfg.replica; pLoad->replica = pVnode->syncCfg.replica;
pLoad->compact = (pVnode->tsdb != NULL) ? tsdbGetCompactState(pVnode->tsdb) : 0; pLoad->compact = (pVnode->tsdb != NULL) ? tsdbGetCompactState(pVnode->tsdb) : 0;
pLoad->truncate = (pVnode->tsdb != NULL) ? tsdbGetCompactState(pVnode->tsdb) : 0;
} }
int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) { int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册