Merge branch 'develop' into test/testcase
This commit is contained in:
commit
9fad9318fb
|
@ -333,7 +333,7 @@ typedef struct STscObj {
|
||||||
char superAuth : 1;
|
char superAuth : 1;
|
||||||
uint32_t connId;
|
uint32_t connId;
|
||||||
uint64_t rid; // ref ID returned by taosAddRef
|
uint64_t rid; // ref ID returned by taosAddRef
|
||||||
struct SSqlObj * pHb;
|
int64_t hbrid;
|
||||||
struct SSqlObj * sqlList;
|
struct SSqlObj * sqlList;
|
||||||
struct SSqlStream *streamList;
|
struct SSqlStream *streamList;
|
||||||
void* pDnodeConn;
|
void* pDnodeConn;
|
||||||
|
@ -373,7 +373,7 @@ typedef struct SSqlObj {
|
||||||
struct SSqlObj **pSubs;
|
struct SSqlObj **pSubs;
|
||||||
|
|
||||||
struct SSqlObj *prev, *next;
|
struct SSqlObj *prev, *next;
|
||||||
struct SSqlObj **self;
|
int64_t self;
|
||||||
} SSqlObj;
|
} SSqlObj;
|
||||||
|
|
||||||
typedef struct SSqlStream {
|
typedef struct SSqlStream {
|
||||||
|
@ -507,7 +507,7 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
|
||||||
}
|
}
|
||||||
|
|
||||||
extern SCacheObj* tscMetaCache;
|
extern SCacheObj* tscMetaCache;
|
||||||
extern SCacheObj* tscObjCache;
|
extern int tscObjRef;
|
||||||
extern void * tscTmr;
|
extern void * tscTmr;
|
||||||
extern void * tscQhandle;
|
extern void * tscQhandle;
|
||||||
extern int tscKeepConn[];
|
extern int tscKeepConn[];
|
||||||
|
|
|
@ -825,8 +825,11 @@ static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
||||||
static int32_t tscProcessServStatus(SSqlObj *pSql) {
|
static int32_t tscProcessServStatus(SSqlObj *pSql) {
|
||||||
STscObj* pObj = pSql->pTscObj;
|
STscObj* pObj = pSql->pTscObj;
|
||||||
|
|
||||||
if (pObj->pHb != NULL) {
|
SSqlObj* pHb = (SSqlObj*)taosAcquireRef(tscObjRef, pObj->hbrid);
|
||||||
if (pObj->pHb->res.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
if (pHb != NULL) {
|
||||||
|
int32_t code = pHb->res.code;
|
||||||
|
taosReleaseRef(tscObjRef, pObj->hbrid);
|
||||||
|
if (code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||||
pSql->res.code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
pSql->res.code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
||||||
return pSql->res.code;
|
return pSql->res.code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,10 +175,10 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
||||||
if (pRsp->streamId) tscKillStream(pObj, htonl(pRsp->streamId));
|
if (pRsp->streamId) tscKillStream(pObj, htonl(pRsp->streamId));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tscDebug("%p heartbeat failed, code:%s", pObj->pHb, tstrerror(code));
|
tscDebug("%" PRId64 " heartbeat failed, code:%s", pObj->hbrid, tstrerror(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pObj->pHb != NULL) {
|
if (pObj->hbrid != 0) {
|
||||||
int32_t waitingDuring = tsShellActivityTimer * 500;
|
int32_t waitingDuring = tsShellActivityTimer * 500;
|
||||||
tscDebug("%p send heartbeat in %dms", pSql, waitingDuring);
|
tscDebug("%p send heartbeat in %dms", pSql, waitingDuring);
|
||||||
|
|
||||||
|
@ -193,20 +193,12 @@ void tscProcessActivityTimer(void *handle, void *tmrId) {
|
||||||
STscObj *pObj = taosAcquireRef(tscRefId, rid);
|
STscObj *pObj = taosAcquireRef(tscRefId, rid);
|
||||||
if (pObj == NULL) return;
|
if (pObj == NULL) return;
|
||||||
|
|
||||||
SSqlObj* pHB = pObj->pHb;
|
SSqlObj* pHB = taosAcquireRef(tscObjRef, pObj->hbrid);
|
||||||
|
assert(pHB->self == pObj->hbrid);
|
||||||
void** p = taosCacheAcquireByKey(tscObjCache, &pHB, sizeof(TSDB_CACHE_PTR_TYPE));
|
|
||||||
if (p == NULL) {
|
|
||||||
tscWarn("%p HB object has been released already", pHB);
|
|
||||||
taosReleaseRef(tscRefId, pObj->rid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(*pHB->self == pHB);
|
|
||||||
|
|
||||||
pHB->retry = 0;
|
pHB->retry = 0;
|
||||||
int32_t code = tscProcessSql(pHB);
|
int32_t code = tscProcessSql(pHB);
|
||||||
taosCacheRelease(tscObjCache, (void**) &p, false);
|
taosReleaseRef(tscObjRef, pObj->hbrid);
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
tscError("%p failed to sent HB to server, reason:%s", pHB, tstrerror(code));
|
tscError("%p failed to sent HB to server, reason:%s", pHB, tstrerror(code));
|
||||||
|
@ -236,7 +228,7 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
||||||
.msgType = pSql->cmd.msgType,
|
.msgType = pSql->cmd.msgType,
|
||||||
.pCont = pMsg,
|
.pCont = pMsg,
|
||||||
.contLen = pSql->cmd.payloadLen,
|
.contLen = pSql->cmd.payloadLen,
|
||||||
.ahandle = pSql,
|
.ahandle = (void*)pSql->self,
|
||||||
.handle = NULL,
|
.handle = NULL,
|
||||||
.code = 0
|
.code = 0
|
||||||
};
|
};
|
||||||
|
@ -247,26 +239,24 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
||||||
|
|
||||||
void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||||
TSDB_CACHE_PTR_TYPE handle = (TSDB_CACHE_PTR_TYPE) rpcMsg->ahandle;
|
TSDB_CACHE_PTR_TYPE handle = (TSDB_CACHE_PTR_TYPE) rpcMsg->ahandle;
|
||||||
void** p = taosCacheAcquireByKey(tscObjCache, &handle, sizeof(TSDB_CACHE_PTR_TYPE));
|
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, handle);
|
||||||
if (p == NULL) {
|
if (pSql == NULL) {
|
||||||
rpcFreeCont(rpcMsg->pCont);
|
rpcFreeCont(rpcMsg->pCont);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
assert(pSql->self == handle);
|
||||||
SSqlObj* pSql = *p;
|
|
||||||
assert(pSql != NULL);
|
|
||||||
|
|
||||||
STscObj *pObj = pSql->pTscObj;
|
STscObj *pObj = pSql->pTscObj;
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
assert(*pSql->self == pSql);
|
|
||||||
pSql->rpcRid = -1;
|
pSql->rpcRid = -1;
|
||||||
|
|
||||||
if (pObj->signature != pObj) {
|
if (pObj->signature != pObj) {
|
||||||
tscDebug("%p DB connection is closed, cmd:%d pObj:%p signature:%p", pSql, pCmd->command, pObj, pObj->signature);
|
tscDebug("%p DB connection is closed, cmd:%d pObj:%p signature:%p", pSql, pCmd->command, pObj, pObj->signature);
|
||||||
|
|
||||||
taosCacheRelease(tscObjCache, (void**) &p, true);
|
taosRemoveRef(tscObjRef, pSql->self);
|
||||||
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
rpcFreeCont(rpcMsg->pCont);
|
rpcFreeCont(rpcMsg->pCont);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -276,10 +266,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||||
tscDebug("%p sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p",
|
tscDebug("%p sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p",
|
||||||
pSql, pCmd->command, pQueryInfo->type, pObj, pObj->signature);
|
pSql, pCmd->command, pQueryInfo->type, pObj, pObj->signature);
|
||||||
|
|
||||||
void** p1 = p;
|
taosRemoveRef(tscObjRef, pSql->self);
|
||||||
taosCacheRelease(tscObjCache, (void**) &p1, false);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
|
|
||||||
taosCacheRelease(tscObjCache, (void**) &p, true);
|
|
||||||
rpcFreeCont(rpcMsg->pCont);
|
rpcFreeCont(rpcMsg->pCont);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +310,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||||
|
|
||||||
// if there is an error occurring, proceed to the following error handling procedure.
|
// if there is an error occurring, proceed to the following error handling procedure.
|
||||||
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
taosCacheRelease(tscObjCache, (void**) &p, false);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
rpcFreeCont(rpcMsg->pCont);
|
rpcFreeCont(rpcMsg->pCont);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -390,11 +378,10 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||||
(*pSql->fp)(pSql->param, pSql, rpcMsg->code);
|
(*pSql->fp)(pSql->param, pSql, rpcMsg->code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void** p1 = p;
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
taosCacheRelease(tscObjCache, (void**) &p1, false);
|
|
||||||
|
|
||||||
if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it
|
if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it
|
||||||
taosCacheRelease(tscObjCache, (void **)&p, true);
|
taosRemoveRef(tscObjRef, pSql->self);
|
||||||
tscDebug("%p sqlObj is automatically freed", pSql);
|
tscDebug("%p sqlObj is automatically freed", pSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2020,7 +2007,7 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
// TODO multithread problem
|
// TODO multithread problem
|
||||||
static void createHBObj(STscObj* pObj) {
|
static void createHBObj(STscObj* pObj) {
|
||||||
if (pObj->pHb != NULL) {
|
if (pObj->hbrid != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2052,7 +2039,7 @@ static void createHBObj(STscObj* pObj) {
|
||||||
registerSqlObj(pSql);
|
registerSqlObj(pSql);
|
||||||
tscDebug("%p HB is allocated, pObj:%p", pSql, pObj);
|
tscDebug("%p HB is allocated, pObj:%p", pSql, pObj);
|
||||||
|
|
||||||
pObj->pHb = pSql;
|
pObj->hbrid = pSql->self;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscProcessConnectRsp(SSqlObj *pSql) {
|
int tscProcessConnectRsp(SSqlObj *pSql) {
|
||||||
|
|
|
@ -276,8 +276,8 @@ void taos_close(TAOS *taos) {
|
||||||
pObj->signature = NULL;
|
pObj->signature = NULL;
|
||||||
taosTmrStopA(&(pObj->pTimer));
|
taosTmrStopA(&(pObj->pTimer));
|
||||||
|
|
||||||
SSqlObj* pHb = pObj->pHb;
|
SSqlObj* pHb = (SSqlObj*)taosAcquireRef(tscObjRef, pObj->hbrid);
|
||||||
if (pHb != NULL && atomic_val_compare_exchange_ptr(&pObj->pHb, pHb, 0) == pHb) {
|
if (pHb != NULL) {
|
||||||
if (pHb->rpcRid > 0) { // wait for rsp from dnode
|
if (pHb->rpcRid > 0) { // wait for rsp from dnode
|
||||||
rpcCancelRequest(pHb->rpcRid);
|
rpcCancelRequest(pHb->rpcRid);
|
||||||
pHb->rpcRid = -1;
|
pHb->rpcRid = -1;
|
||||||
|
@ -285,6 +285,7 @@ void taos_close(TAOS *taos) {
|
||||||
|
|
||||||
tscDebug("%p HB is freed", pHb);
|
tscDebug("%p HB is freed", pHb);
|
||||||
taos_free_result(pHb);
|
taos_free_result(pHb);
|
||||||
|
taosReleaseRef(tscObjRef, pHb->self);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ref = T_REF_DEC(pObj);
|
int32_t ref = T_REF_DEC(pObj);
|
||||||
|
@ -606,8 +607,7 @@ void taos_free_result(TAOS_RES *res) {
|
||||||
bool freeNow = tscKillQueryInDnode(pSql);
|
bool freeNow = tscKillQueryInDnode(pSql);
|
||||||
if (freeNow) {
|
if (freeNow) {
|
||||||
tscDebug("%p free sqlObj in cache", pSql);
|
tscDebug("%p free sqlObj in cache", pSql);
|
||||||
SSqlObj** p = pSql->self;
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
taosCacheRelease(tscObjCache, (void**) &p, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,13 +700,7 @@ static void tscKillSTableQuery(SSqlObj *pSql) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void** p = taosCacheAcquireByKey(tscObjCache, &pSub, sizeof(TSDB_CACHE_PTR_TYPE));
|
SSqlObj* pSubObj = pSub;
|
||||||
if (p == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSqlObj* pSubObj = (SSqlObj*) (*p);
|
|
||||||
assert(pSubObj->self == (SSqlObj**) p);
|
|
||||||
|
|
||||||
pSubObj->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
pSubObj->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
if (pSubObj->rpcRid > 0) {
|
if (pSubObj->rpcRid > 0) {
|
||||||
|
@ -715,7 +709,7 @@ static void tscKillSTableQuery(SSqlObj *pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tscQueueAsyncRes(pSubObj);
|
tscQueueAsyncRes(pSubObj);
|
||||||
taosCacheRelease(tscObjCache, (void**) &p, false);
|
taosReleaseRef(tscObjRef, pSubObj->self);
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("%p super table query cancelled", pSql);
|
tscDebug("%p super table query cancelled", pSql);
|
||||||
|
|
|
@ -179,8 +179,8 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
||||||
fail:
|
fail:
|
||||||
tscError("tscCreateSubscription failed at line %d, reason: %s", line, tstrerror(code));
|
tscError("tscCreateSubscription failed at line %d, reason: %s", line, tstrerror(code));
|
||||||
if (pSql != NULL) {
|
if (pSql != NULL) {
|
||||||
if (pSql->self != NULL) {
|
if (pSql->self != 0) {
|
||||||
taos_free_result(pSql);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
} else {
|
} else {
|
||||||
tscFreeSqlObj(pSql);
|
tscFreeSqlObj(pSql);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2198,6 +2198,9 @@ int32_t tscHandleInsertRetry(SSqlObj* pSql) {
|
||||||
STableDataBlocks* pTableDataBlock = taosArrayGetP(pCmd->pDataBlocks, pSupporter->index);
|
STableDataBlocks* pTableDataBlock = taosArrayGetP(pCmd->pDataBlocks, pSupporter->index);
|
||||||
int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock);
|
int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock);
|
||||||
|
|
||||||
|
// free the data block created from insert sql string
|
||||||
|
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||||
|
|
||||||
if ((pRes->code = code)!= TSDB_CODE_SUCCESS) {
|
if ((pRes->code = code)!= TSDB_CODE_SUCCESS) {
|
||||||
tscQueueAsyncRes(pSql);
|
tscQueueAsyncRes(pSql);
|
||||||
return code; // here the pSql may have been released already.
|
return code; // here the pSql may have been released already.
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tcache.h"
|
#include "tref.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "tsystem.h"
|
#include "tsystem.h"
|
||||||
#include "ttimer.h"
|
#include "ttimer.h"
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
// global, not configurable
|
// global, not configurable
|
||||||
SCacheObj* tscMetaCache;
|
SCacheObj* tscMetaCache;
|
||||||
SCacheObj* tscObjCache;
|
int tscObjRef = -1;
|
||||||
void * tscTmr;
|
void * tscTmr;
|
||||||
void * tscQhandle;
|
void * tscQhandle;
|
||||||
void * tscCheckDiskUsageTmr;
|
void * tscCheckDiskUsageTmr;
|
||||||
|
@ -144,7 +144,7 @@ void taos_init_imp(void) {
|
||||||
int64_t refreshTime = 10; // 10 seconds by default
|
int64_t refreshTime = 10; // 10 seconds by default
|
||||||
if (tscMetaCache == NULL) {
|
if (tscMetaCache == NULL) {
|
||||||
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, tscFreeTableMetaHelper, "tableMeta");
|
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, tscFreeTableMetaHelper, "tableMeta");
|
||||||
tscObjCache = taosCacheInit(TSDB_CACHE_PTR_KEY, refreshTime / 2, false, tscFreeRegisteredSqlObj, "sqlObj");
|
tscObjRef = taosOpenRef(4096, tscFreeRegisteredSqlObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
||||||
|
@ -167,9 +167,9 @@ void taos_cleanup(void) {
|
||||||
taosCacheCleanup(m);
|
taosCacheCleanup(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
m = tscObjCache;
|
int refId = atomic_exchange_32(&tscObjRef, -1);
|
||||||
if (m != NULL && atomic_val_compare_exchange_ptr(&tscObjCache, m, 0) == m) {
|
if (refId != -1) {
|
||||||
taosCacheCleanup(m);
|
taosCloseRef(refId);
|
||||||
}
|
}
|
||||||
|
|
||||||
m = tscQhandle;
|
m = tscQhandle;
|
||||||
|
|
|
@ -447,20 +447,18 @@ static void tscFreeSubobj(SSqlObj* pSql) {
|
||||||
void tscFreeRegisteredSqlObj(void *pSql) {
|
void tscFreeRegisteredSqlObj(void *pSql) {
|
||||||
assert(pSql != NULL);
|
assert(pSql != NULL);
|
||||||
|
|
||||||
SSqlObj** p = (SSqlObj**)pSql;
|
SSqlObj* p = *(SSqlObj**)pSql;
|
||||||
STscObj* pTscObj = (*p)->pTscObj;
|
STscObj* pTscObj = p->pTscObj;
|
||||||
|
|
||||||
assert((*p)->self != 0 && (*p)->self == (p));
|
assert(p->self != 0);
|
||||||
|
tscFreeSqlObj(p);
|
||||||
SSqlObj* ptr = *p;
|
|
||||||
tscFreeSqlObj(*p);
|
|
||||||
|
|
||||||
int32_t ref = T_REF_DEC(pTscObj);
|
int32_t ref = T_REF_DEC(pTscObj);
|
||||||
assert(ref >= 0);
|
assert(ref >= 0);
|
||||||
|
|
||||||
tscDebug("%p free sqlObj completed, tscObj:%p ref:%d", ptr, pTscObj, ref);
|
tscDebug("%p free sqlObj completed, tscObj:%p ref:%d", p, pTscObj, ref);
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
tscDebug("%p all sqlObj freed, free tscObj:%p", ptr, pTscObj);
|
tscDebug("%p all sqlObj freed, free tscObj:%p", p, pTscObj);
|
||||||
taosRemoveRef(tscRefId, pTscObj->rid);
|
taosRemoveRef(tscRefId, pTscObj->rid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -840,7 +838,6 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SArray* pTableDataBlockList) {
|
||||||
|
|
||||||
// the length does not include the SSubmitBlk structure
|
// the length does not include the SSubmitBlk structure
|
||||||
pBlocks->dataLen = htonl(finalLen);
|
pBlocks->dataLen = htonl(finalLen);
|
||||||
|
|
||||||
dataBuf->numOfTables += 1;
|
dataBuf->numOfTables += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1565,19 +1562,6 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscSetFreeHeatBeat(STscObj* pObj) {
|
|
||||||
if (pObj == NULL || pObj->signature != pObj || pObj->pHb == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSqlObj* pHeatBeat = pObj->pHb;
|
|
||||||
assert(pHeatBeat == pHeatBeat->signature);
|
|
||||||
|
|
||||||
// to denote the heart-beat timer close connection and free all allocated resources
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pHeatBeat->cmd, 0);
|
|
||||||
pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the following four kinds of SqlObj should not be freed
|
* the following four kinds of SqlObj should not be freed
|
||||||
* 1. SqlObj for stream computing
|
* 1. SqlObj for stream computing
|
||||||
|
@ -1596,7 +1580,7 @@ bool tscShouldBeFreed(SSqlObj* pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
STscObj* pTscObj = pSql->pTscObj;
|
STscObj* pTscObj = pSql->pTscObj;
|
||||||
if (pSql->pStream != NULL || pTscObj->pHb == pSql || pSql->pSubscription != NULL) {
|
if (pSql->pStream != NULL || pTscObj->hbrid == pSql->self || pSql->pSubscription != NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1888,13 +1872,10 @@ void tscResetForNextRetrieve(SSqlRes* pRes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerSqlObj(SSqlObj* pSql) {
|
void registerSqlObj(SSqlObj* pSql) {
|
||||||
int32_t DEFAULT_LIFE_TIME = 2 * 600 * 1000; // 1200 sec
|
|
||||||
|
|
||||||
int32_t ref = T_REF_INC(pSql->pTscObj);
|
int32_t ref = T_REF_INC(pSql->pTscObj);
|
||||||
tscDebug("%p add to tscObj:%p, ref:%d", pSql, pSql->pTscObj, ref);
|
tscDebug("%p add to tscObj:%p, ref:%d", pSql, pSql->pTscObj, ref);
|
||||||
|
|
||||||
TSDB_CACHE_PTR_TYPE p = (TSDB_CACHE_PTR_TYPE) pSql;
|
pSql->self = taosAddRef(tscObjRef, pSql);
|
||||||
pSql->self = taosCachePut(tscObjCache, &p, sizeof(TSDB_CACHE_PTR_TYPE), &p, sizeof(TSDB_CACHE_PTR_TYPE), DEFAULT_LIFE_TIME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cmd) {
|
SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cmd) {
|
||||||
|
|
|
@ -40,15 +40,14 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
|
int32_t master;
|
||||||
|
int32_t num; // number of continuous streams
|
||||||
char user[TSDB_USER_LEN];
|
char user[TSDB_USER_LEN];
|
||||||
char pass[TSDB_PASSWORD_LEN];
|
char pass[TSDB_PASSWORD_LEN];
|
||||||
char db[TSDB_DB_NAME_LEN];
|
char db[TSDB_DB_NAME_LEN];
|
||||||
FCqWrite cqWrite;
|
FCqWrite cqWrite;
|
||||||
void *ahandle;
|
|
||||||
int32_t num; // number of continuous streams
|
|
||||||
struct SCqObj *pHead;
|
struct SCqObj *pHead;
|
||||||
void *dbConn;
|
void *dbConn;
|
||||||
int32_t master;
|
|
||||||
void *tmrCtrl;
|
void *tmrCtrl;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
} SCqContext;
|
} SCqContext;
|
||||||
|
@ -90,7 +89,6 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
|
||||||
tstrncpy(pContext->db, db, sizeof(pContext->db));
|
tstrncpy(pContext->db, db, sizeof(pContext->db));
|
||||||
pContext->vgId = pCfg->vgId;
|
pContext->vgId = pCfg->vgId;
|
||||||
pContext->cqWrite = pCfg->cqWrite;
|
pContext->cqWrite = pCfg->cqWrite;
|
||||||
pContext->ahandle = ahandle;
|
|
||||||
tscEmbedded = 1;
|
tscEmbedded = 1;
|
||||||
|
|
||||||
pthread_mutex_init(&pContext->mutex, NULL);
|
pthread_mutex_init(&pContext->mutex, NULL);
|
||||||
|
@ -342,7 +340,7 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
|
||||||
pHead->version = 0;
|
pHead->version = 0;
|
||||||
|
|
||||||
// write into vnode write queue
|
// write into vnode write queue
|
||||||
pContext->cqWrite(pContext->ahandle, pHead, TAOS_QTYPE_CQ, NULL);
|
pContext->cqWrite(pContext->vgId, pHead, TAOS_QTYPE_CQ, NULL);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
int64_t ver = 0;
|
int64_t ver = 0;
|
||||||
void *pCq = NULL;
|
void *pCq = NULL;
|
||||||
|
|
||||||
int writeToQueue(void *pVnode, void *data, int type, void *pMsg) {
|
int writeToQueue(int32_t vgId, void *data, int type, void *pMsg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,11 +122,16 @@ void dnodeFreeMPeerQueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeDispatchToMPeerQueue(SRpcMsg *pMsg) {
|
void dnodeDispatchToMPeerQueue(SRpcMsg *pMsg) {
|
||||||
if (!mnodeIsRunning() || tsMPeerQueue == NULL) {
|
if (!mnodeIsRunning()) {
|
||||||
dnodeSendRedirectMsg(pMsg, false);
|
dnodeSendRedirectMsg(pMsg, false);
|
||||||
} else {
|
} else {
|
||||||
SMnodeMsg *pPeer = mnodeCreateMsg(pMsg);
|
if (!mnodeIsReady()) {
|
||||||
taosWriteQitem(tsMPeerQueue, TAOS_QTYPE_RPC, pPeer);
|
SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = mnodeInitCode(), .pCont = NULL};
|
||||||
|
rpcSendResponse(&rpcRsp);
|
||||||
|
} else {
|
||||||
|
SMnodeMsg *pPeer = mnodeCreateMsg(pMsg);
|
||||||
|
taosWriteQitem(tsMPeerQueue, TAOS_QTYPE_RPC, pPeer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
|
|
@ -123,11 +123,16 @@ void dnodeFreeMReadQueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeDispatchToMReadQueue(SRpcMsg *pMsg) {
|
void dnodeDispatchToMReadQueue(SRpcMsg *pMsg) {
|
||||||
if (!mnodeIsRunning() || tsMReadQueue == NULL) {
|
if (!mnodeIsRunning()) {
|
||||||
dnodeSendRedirectMsg(pMsg, true);
|
dnodeSendRedirectMsg(pMsg, true);
|
||||||
} else {
|
} else {
|
||||||
SMnodeMsg *pRead = mnodeCreateMsg(pMsg);
|
if (!mnodeIsReady()) {
|
||||||
taosWriteQitem(tsMReadQueue, TAOS_QTYPE_RPC, pRead);
|
SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = mnodeInitCode(), .pCont = NULL};
|
||||||
|
rpcSendResponse(&rpcRsp);
|
||||||
|
} else {
|
||||||
|
SMnodeMsg *pRead = mnodeCreateMsg(pMsg);
|
||||||
|
taosWriteQitem(tsMReadQueue, TAOS_QTYPE_RPC, pRead);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
|
|
@ -123,13 +123,18 @@ void dnodeFreeMWritequeue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeDispatchToMWriteQueue(SRpcMsg *pMsg) {
|
void dnodeDispatchToMWriteQueue(SRpcMsg *pMsg) {
|
||||||
if (!mnodeIsRunning() || tsMWriteQueue == NULL) {
|
if (!mnodeIsRunning()) {
|
||||||
dnodeSendRedirectMsg(pMsg, true);
|
dnodeSendRedirectMsg(pMsg, true);
|
||||||
} else {
|
} else {
|
||||||
SMnodeMsg *pWrite = mnodeCreateMsg(pMsg);
|
if (!mnodeIsReady()) {
|
||||||
dDebug("msg:%p, app:%p type:%s is put into mwrite queue:%p", pWrite, pWrite->rpcMsg.ahandle,
|
SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = mnodeInitCode(), .pCont = NULL};
|
||||||
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue);
|
rpcSendResponse(&rpcRsp);
|
||||||
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
} else {
|
||||||
|
SMnodeMsg *pWrite = mnodeCreateMsg(pMsg);
|
||||||
|
dDebug("msg:%p, app:%p type:%s is put into mwrite queue:%p", pWrite, pWrite->rpcMsg.ahandle,
|
||||||
|
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue);
|
||||||
|
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
@ -187,7 +192,7 @@ static void *dnodeProcessMWriteQueue(void *param) {
|
||||||
void dnodeReprocessMWriteMsg(void *pMsg) {
|
void dnodeReprocessMWriteMsg(void *pMsg) {
|
||||||
SMnodeMsg *pWrite = pMsg;
|
SMnodeMsg *pWrite = pMsg;
|
||||||
|
|
||||||
if (!mnodeIsRunning() || tsMWriteQueue == NULL) {
|
if (!mnodeIsRunning()) {
|
||||||
dDebug("msg:%p, app:%p type:%s is redirected for mnode not running, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
dDebug("msg:%p, app:%p type:%s is redirected for mnode not running, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
||||||
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
||||||
|
|
||||||
|
@ -196,7 +201,6 @@ void dnodeReprocessMWriteMsg(void *pMsg) {
|
||||||
} else {
|
} else {
|
||||||
dDebug("msg:%p, app:%p type:%s is reput into mwrite queue:%p, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
dDebug("msg:%p, app:%p type:%s is reput into mwrite queue:%p, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
||||||
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue, pWrite->retry);
|
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue, pWrite->retry);
|
||||||
|
|
||||||
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ static const SDnodeComponent tsDnodeComponents[] = {
|
||||||
{"dnodeeps", dnodeInitEps, dnodeCleanupEps},
|
{"dnodeeps", dnodeInitEps, dnodeCleanupEps},
|
||||||
{"globalcfg" ,taosCheckGlobalCfg, NULL},
|
{"globalcfg" ,taosCheckGlobalCfg, NULL},
|
||||||
{"mnodeinfos",dnodeInitMInfos, dnodeCleanupMInfos},
|
{"mnodeinfos",dnodeInitMInfos, dnodeCleanupMInfos},
|
||||||
|
{"shell", dnodeInitShell, dnodeCleanupShell},
|
||||||
{"wal", walInit, walCleanUp},
|
{"wal", walInit, walCleanUp},
|
||||||
{"check", dnodeInitCheck, dnodeCleanupCheck}, // NOTES: dnodeInitCheck must be behind the dnodeinitStorage component !!!
|
{"check", dnodeInitCheck, dnodeCleanupCheck}, // NOTES: dnodeInitCheck must be behind the dnodeinitStorage component !!!
|
||||||
{"vread", dnodeInitVRead, dnodeCleanupVRead},
|
{"vread", dnodeInitVRead, dnodeCleanupVRead},
|
||||||
|
@ -75,7 +76,6 @@ static const SDnodeComponent tsDnodeComponents[] = {
|
||||||
{"mgmt", dnodeInitMgmt, dnodeCleanupMgmt},
|
{"mgmt", dnodeInitMgmt, dnodeCleanupMgmt},
|
||||||
{"modules", dnodeInitModules, dnodeCleanupModules},
|
{"modules", dnodeInitModules, dnodeCleanupModules},
|
||||||
{"mgmt-tmr", dnodeInitMgmtTimer, dnodeCleanupMgmtTimer},
|
{"mgmt-tmr", dnodeInitMgmtTimer, dnodeCleanupMgmtTimer},
|
||||||
{"shell", dnodeInitShell, dnodeCleanupShell},
|
|
||||||
{"telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
{"telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ static void dnodeProcessMsgFromShell(SRpcMsg *pMsg, SRpcEpSet *pEpSet) {
|
||||||
|
|
||||||
static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||||
int code = mnodeRetriveAuth(user, spi, encrypt, secret, ckey);
|
int code = mnodeRetriveAuth(user, spi, encrypt, secret, ckey);
|
||||||
if (code != TSDB_CODE_APP_NOT_READY) return code;
|
if (code != TSDB_CODE_RPC_REDIRECT) return code;
|
||||||
|
|
||||||
SAuthMsg *pMsg = rpcMallocCont(sizeof(SAuthMsg));
|
SAuthMsg *pMsg = rpcMallocCont(sizeof(SAuthMsg));
|
||||||
tstrncpy(pMsg->user, user, sizeof(pMsg->user));
|
tstrncpy(pMsg->user, user, sizeof(pMsg->user));
|
||||||
|
|
|
@ -65,12 +65,15 @@ void mnodeStopSystem();
|
||||||
void sdbUpdateAsync();
|
void sdbUpdateAsync();
|
||||||
void sdbUpdateSync(void *pMnodes);
|
void sdbUpdateSync(void *pMnodes);
|
||||||
bool mnodeIsRunning();
|
bool mnodeIsRunning();
|
||||||
|
bool mnodeIsReady();
|
||||||
|
int32_t mnodeInitCode();
|
||||||
int32_t mnodeProcessRead(SMnodeMsg *pMsg);
|
int32_t mnodeProcessRead(SMnodeMsg *pMsg);
|
||||||
int32_t mnodeProcessWrite(SMnodeMsg *pMsg);
|
int32_t mnodeProcessWrite(SMnodeMsg *pMsg);
|
||||||
int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg);
|
int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg);
|
||||||
void mnodeProcessPeerRsp(SRpcMsg *pMsg);
|
void mnodeProcessPeerRsp(SRpcMsg *pMsg);
|
||||||
int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -257,7 +257,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
||||||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
||||||
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
||||||
#define TSDB_MAX_SQL_SHOW_LEN 512
|
#define TSDB_MAX_SQL_SHOW_LEN 512
|
||||||
#define TSDB_MAX_ALLOWED_SQL_LEN (8*1024*1024U) // sql length should be less than 8mb
|
#define TSDB_MAX_ALLOWED_SQL_LEN (1*1024*1024U) // sql length should be less than 1mb
|
||||||
|
|
||||||
#define TSDB_APPNAME_LEN TSDB_UNI_LEN
|
#define TSDB_APPNAME_LEN TSDB_UNI_LEN
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SHOWOBJ, 0, 0x030B, "Data expir
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, 0, 0x030C, "Invalid query id")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, 0, 0x030C, "Invalid query id")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_ID, 0, 0x030D, "Invalid stream id")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_ID, 0, 0x030D, "Invalid stream id")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, 0, 0x030E, "Invalid connection id")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, 0, 0x030E, "Invalid connection id")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INIT, 0, 0x030F, "Mnode is initializing")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INIT_SDB, 0, 0x0310, "Mnode is initializing meta data, it takes a while if many tables exists")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INIT_OTHER, 0, 0x0311, "Mnode is initializing other data")
|
||||||
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE, 0, 0x0320, "Object already there")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE, 0, 0x0320, "Object already there")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_ERROR, 0, 0x0321, "Unexpected generic error in sdb")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_ERROR, 0, 0x0321, "Unexpected generic error in sdb")
|
||||||
|
@ -184,6 +187,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_DATABASES, 0, 0x0385, "Too many d
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_IN_DROPPING, 0, 0x0386, "Database not available")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_IN_DROPPING, 0, 0x0386, "Database not available")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_READY, 0, 0x0387, "Database unsynced")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_READY, 0, 0x0387, "Database unsynced")
|
||||||
|
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_OPTION_DAYS, 0, 0x0390, "Invalid database option: days out of range")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_OPTION_KEEP, 0, 0x0391, "Invalid database option: keep >= keep2 >= keep1 >= days")
|
||||||
|
|
||||||
// dnode
|
// dnode
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MSG_NOT_PROCESSED, 0, 0x0400, "Message not processed")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MSG_NOT_PROCESSED, 0, 0x0400, "Message not processed")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_OUT_OF_MEMORY, 0, 0x0401, "Dnode out of memory")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_OUT_OF_MEMORY, 0, 0x0401, "Dnode out of memory")
|
||||||
|
@ -261,9 +267,6 @@ TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_CONFIG, 0, 0x0900, "Invalid Sy
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_ENABLED, 0, 0x0901, "Sync module not enabled")
|
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_ENABLED, 0, 0x0901, "Sync module not enabled")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_VERSION, 0, 0x0902, "Invalid Sync version")
|
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_VERSION, 0, 0x0902, "Invalid Sync version")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_CONFIRM_EXPIRED, 0, 0x0903, "Sync confirm expired")
|
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_CONFIRM_EXPIRED, 0, 0x0903, "Sync confirm expired")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_VND_COMMITING, 0, 0x0904, "Vnode is commiting")
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_FILE_CHNAGED, 0, 0x0905, "Vnode file is changed")
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_APP_ERROR, 0, 0x1000, "Unexpected generic error in sync")
|
|
||||||
|
|
||||||
// wal
|
// wal
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_APP_ERROR, 0, 0x1000, "Unexpected generic error in wal")
|
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_APP_ERROR, 0, 0x1000, "Unexpected generic error in wal")
|
||||||
|
|
|
@ -21,7 +21,7 @@ extern "C" {
|
||||||
|
|
||||||
#include "tdataformat.h"
|
#include "tdataformat.h"
|
||||||
|
|
||||||
typedef int32_t (*FCqWrite)(void *ahandle, void *pHead, int32_t qtype, void *pMsg);
|
typedef int32_t (*FCqWrite)(int32_t vgId, void *pHead, int32_t qtype, void *pMsg);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
|
|
|
@ -86,7 +86,7 @@ typedef void (*FNotifyFlowCtrl)(int32_t vgId, int32_t level);
|
||||||
typedef int32_t (*FNotifyFileSynced)(int32_t vgId, uint64_t fversion);
|
typedef int32_t (*FNotifyFileSynced)(int32_t vgId, uint64_t fversion);
|
||||||
|
|
||||||
// get file version
|
// get file version
|
||||||
typedef int32_t (*FGetFileVersion)(int32_t vgId, uint64_t *fver);
|
typedef int32_t (*FGetVersion)(int32_t vgId, uint64_t *fver, uint64_t *vver);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t vgId; // vgroup ID
|
int32_t vgId; // vgroup ID
|
||||||
|
@ -100,7 +100,7 @@ typedef struct {
|
||||||
FNotifyRole notifyRole;
|
FNotifyRole notifyRole;
|
||||||
FNotifyFlowCtrl notifyFlowCtrl;
|
FNotifyFlowCtrl notifyFlowCtrl;
|
||||||
FNotifyFileSynced notifyFileSynced;
|
FNotifyFileSynced notifyFileSynced;
|
||||||
FGetFileVersion getFileVersion;
|
FGetVersion getVersion;
|
||||||
} SSyncInfo;
|
} SSyncInfo;
|
||||||
|
|
||||||
typedef void *tsync_h;
|
typedef void *tsync_h;
|
||||||
|
|
|
@ -236,30 +236,28 @@ static int32_t mnodeCheckDbCfg(SDbCfg *pCfg) {
|
||||||
if (pCfg->daysPerFile < TSDB_MIN_DAYS_PER_FILE || pCfg->daysPerFile > TSDB_MAX_DAYS_PER_FILE) {
|
if (pCfg->daysPerFile < TSDB_MIN_DAYS_PER_FILE || pCfg->daysPerFile > TSDB_MAX_DAYS_PER_FILE) {
|
||||||
mError("invalid db option daysPerFile:%d valid range: [%d, %d]", pCfg->daysPerFile, TSDB_MIN_DAYS_PER_FILE,
|
mError("invalid db option daysPerFile:%d valid range: [%d, %d]", pCfg->daysPerFile, TSDB_MIN_DAYS_PER_FILE,
|
||||||
TSDB_MAX_DAYS_PER_FILE);
|
TSDB_MAX_DAYS_PER_FILE);
|
||||||
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
return TSDB_CODE_MND_INVALID_DB_OPTION_DAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCfg->daysToKeep < TSDB_MIN_KEEP || pCfg->daysToKeep > TSDB_MAX_KEEP) {
|
if (pCfg->daysToKeep < TSDB_MIN_KEEP || pCfg->daysToKeep > TSDB_MAX_KEEP) {
|
||||||
mError("invalid db option daysToKeep:%d valid range: [%d, %d]", pCfg->daysToKeep, TSDB_MIN_KEEP, TSDB_MAX_KEEP);
|
mError("invalid db option daysToKeep:%d valid range: [%d, %d]", pCfg->daysToKeep, TSDB_MIN_KEEP, TSDB_MAX_KEEP);
|
||||||
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
return TSDB_CODE_MND_INVALID_DB_OPTION_KEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCfg->daysToKeep < pCfg->daysPerFile) {
|
if (pCfg->daysToKeep < pCfg->daysPerFile) {
|
||||||
mError("invalid db option daysToKeep:%d should larger than daysPerFile:%d", pCfg->daysToKeep, pCfg->daysPerFile);
|
mError("invalid db option daysToKeep:%d should larger than daysPerFile:%d", pCfg->daysToKeep, pCfg->daysPerFile);
|
||||||
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
return TSDB_CODE_MND_INVALID_DB_OPTION_KEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (pCfg->daysToKeep2 < TSDB_MIN_KEEP || pCfg->daysToKeep2 > pCfg->daysToKeep) {
|
if (pCfg->daysToKeep2 < TSDB_MIN_KEEP || pCfg->daysToKeep2 > pCfg->daysToKeep) {
|
||||||
mError("invalid db option daysToKeep2:%d valid range: [%d, %d]", pCfg->daysToKeep, TSDB_MIN_KEEP, pCfg->daysToKeep);
|
mError("invalid db option daysToKeep2:%d valid range: [%d, %d]", pCfg->daysToKeep, TSDB_MIN_KEEP, pCfg->daysToKeep);
|
||||||
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
return TSDB_CODE_MND_INVALID_DB_OPTION_KEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCfg->daysToKeep1 < TSDB_MIN_KEEP || pCfg->daysToKeep1 > pCfg->daysToKeep2) {
|
if (pCfg->daysToKeep1 < TSDB_MIN_KEEP || pCfg->daysToKeep1 > pCfg->daysToKeep2) {
|
||||||
mError("invalid db option daysToKeep1:%d valid range: [%d, %d]", pCfg->daysToKeep1, TSDB_MIN_KEEP, pCfg->daysToKeep2);
|
mError("invalid db option daysToKeep1:%d valid range: [%d, %d]", pCfg->daysToKeep1, TSDB_MIN_KEEP, pCfg->daysToKeep2);
|
||||||
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
return TSDB_CODE_MND_INVALID_DB_OPTION_KEEP;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pCfg->maxRowsPerFileBlock < TSDB_MIN_MAX_ROW_FBLOCK || pCfg->maxRowsPerFileBlock > TSDB_MAX_MAX_ROW_FBLOCK) {
|
if (pCfg->maxRowsPerFileBlock < TSDB_MIN_MAX_ROW_FBLOCK || pCfg->maxRowsPerFileBlock > TSDB_MAX_MAX_ROW_FBLOCK) {
|
||||||
mError("invalid db option maxRowsPerFileBlock:%d valid range: [%d, %d]", pCfg->maxRowsPerFileBlock,
|
mError("invalid db option maxRowsPerFileBlock:%d valid range: [%d, %d]", pCfg->maxRowsPerFileBlock,
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tsched.h"
|
#include "tsched.h"
|
||||||
|
#include "taoserror.h"
|
||||||
#include "tbalance.h"
|
#include "tbalance.h"
|
||||||
#include "tgrant.h"
|
#include "tgrant.h"
|
||||||
#include "ttimer.h"
|
#include "ttimer.h"
|
||||||
|
@ -37,30 +38,41 @@
|
||||||
#include "mnodeShow.h"
|
#include "mnodeShow.h"
|
||||||
#include "mnodeProfile.h"
|
#include "mnodeProfile.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TSDB_MND_STATUS_NOT_RUNNING,
|
||||||
|
TSDB_MND_STATUS_INIT,
|
||||||
|
TSDB_MND_STATUS_INIT_SDB,
|
||||||
|
TSDB_MND_STATUS_INIT_OTHER,
|
||||||
|
TSDB_MND_STATUS_READY,
|
||||||
|
TSDB_MND_STATUS_CLEANING,
|
||||||
|
} EMndStatus;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *const name;
|
const char *const name;
|
||||||
int (*init)();
|
int (*init)();
|
||||||
void (*cleanup)();
|
void (*cleanup)();
|
||||||
|
EMndStatus status;
|
||||||
} SMnodeComponent;
|
} SMnodeComponent;
|
||||||
|
|
||||||
void *tsMnodeTmr = NULL;
|
void *tsMnodeTmr = NULL;
|
||||||
static bool tsMgmtIsRunning = false;
|
static bool tsMgmtIsRunning = false;
|
||||||
|
static EMndStatus tsMgmtStatus = TSDB_MND_STATUS_NOT_RUNNING;
|
||||||
|
|
||||||
static const SMnodeComponent tsMnodeComponents[] = {
|
static const SMnodeComponent tsMnodeComponents[] = {
|
||||||
{"sdbref", sdbInitRef, sdbCleanUpRef},
|
{"sdbref", sdbInitRef, sdbCleanUpRef, TSDB_MND_STATUS_INIT},
|
||||||
{"profile", mnodeInitProfile, mnodeCleanupProfile},
|
{"profile", mnodeInitProfile, mnodeCleanupProfile, TSDB_MND_STATUS_INIT},
|
||||||
{"cluster", mnodeInitCluster, mnodeCleanupCluster},
|
{"cluster", mnodeInitCluster, mnodeCleanupCluster, TSDB_MND_STATUS_INIT},
|
||||||
{"accts", mnodeInitAccts, mnodeCleanupAccts},
|
{"accts", mnodeInitAccts, mnodeCleanupAccts, TSDB_MND_STATUS_INIT},
|
||||||
{"users", mnodeInitUsers, mnodeCleanupUsers},
|
{"users", mnodeInitUsers, mnodeCleanupUsers, TSDB_MND_STATUS_INIT},
|
||||||
{"dnodes", mnodeInitDnodes, mnodeCleanupDnodes},
|
{"dnodes", mnodeInitDnodes, mnodeCleanupDnodes, TSDB_MND_STATUS_INIT},
|
||||||
{"dbs", mnodeInitDbs, mnodeCleanupDbs},
|
{"dbs", mnodeInitDbs, mnodeCleanupDbs, TSDB_MND_STATUS_INIT},
|
||||||
{"vgroups", mnodeInitVgroups, mnodeCleanupVgroups},
|
{"vgroups", mnodeInitVgroups, mnodeCleanupVgroups, TSDB_MND_STATUS_INIT},
|
||||||
{"tables", mnodeInitTables, mnodeCleanupTables},
|
{"tables", mnodeInitTables, mnodeCleanupTables, TSDB_MND_STATUS_INIT},
|
||||||
{"mnodes", mnodeInitMnodes, mnodeCleanupMnodes},
|
{"mnodes", mnodeInitMnodes, mnodeCleanupMnodes, TSDB_MND_STATUS_INIT},
|
||||||
{"sdb", sdbInit, sdbCleanUp},
|
{"sdb", sdbInit, sdbCleanUp, TSDB_MND_STATUS_INIT_SDB},
|
||||||
{"balance", balanceInit, balanceCleanUp},
|
{"balance", balanceInit, balanceCleanUp, TSDB_MND_STATUS_INIT_OTHER},
|
||||||
{"grant", grantInit, grantCleanUp},
|
{"grant", grantInit, grantCleanUp, TSDB_MND_STATUS_INIT_OTHER},
|
||||||
{"show", mnodeInitShow, mnodeCleanUpShow}
|
{"show", mnodeInitShow, mnodeCleanUpShow, TSDB_MND_STATUS_INIT_OTHER},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mnodeInitTimer();
|
static void mnodeInitTimer();
|
||||||
|
@ -76,21 +88,24 @@ static void mnodeCleanupComponents(int32_t stepId) {
|
||||||
static int32_t mnodeInitComponents() {
|
static int32_t mnodeInitComponents() {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
for (int32_t i = 0; i < sizeof(tsMnodeComponents) / sizeof(tsMnodeComponents[0]); i++) {
|
for (int32_t i = 0; i < sizeof(tsMnodeComponents) / sizeof(tsMnodeComponents[0]); i++) {
|
||||||
|
tsMgmtStatus = tsMnodeComponents[i].status;
|
||||||
if (tsMnodeComponents[i].init() != 0) {
|
if (tsMnodeComponents[i].init() != 0) {
|
||||||
mnodeCleanupComponents(i);
|
mnodeCleanupComponents(i);
|
||||||
code = -1;
|
code = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// sleep(3);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mnodeStartSystem() {
|
int32_t mnodeStartSystem() {
|
||||||
if (tsMgmtIsRunning) {
|
if (tsMgmtStatus != TSDB_MND_STATUS_NOT_RUNNING) {
|
||||||
mInfo("mnode module already started...");
|
mInfo("mnode module already started...");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tsMgmtStatus = TSDB_MND_STATUS_INIT;
|
||||||
mInfo("starting to initialize mnode ...");
|
mInfo("starting to initialize mnode ...");
|
||||||
if (mkdir(tsMnodeDir, 0755) != 0 && errno != EEXIST) {
|
if (mkdir(tsMnodeDir, 0755) != 0 && errno != EEXIST) {
|
||||||
mError("failed to init mnode dir:%s, reason:%s", tsMnodeDir, strerror(errno));
|
mError("failed to init mnode dir:%s, reason:%s", tsMnodeDir, strerror(errno));
|
||||||
|
@ -106,7 +121,7 @@ int32_t mnodeStartSystem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
grantReset(TSDB_GRANT_ALL, 0);
|
grantReset(TSDB_GRANT_ALL, 0);
|
||||||
tsMgmtIsRunning = true;
|
tsMgmtStatus = TSDB_MND_STATUS_READY;
|
||||||
|
|
||||||
mInfo("mnode is initialized successfully");
|
mInfo("mnode is initialized successfully");
|
||||||
|
|
||||||
|
@ -126,7 +141,7 @@ int32_t mnodeInitSystem() {
|
||||||
void mnodeCleanupSystem() {
|
void mnodeCleanupSystem() {
|
||||||
if (tsMgmtIsRunning) {
|
if (tsMgmtIsRunning) {
|
||||||
mInfo("starting to clean up mnode");
|
mInfo("starting to clean up mnode");
|
||||||
tsMgmtIsRunning = false;
|
tsMgmtStatus = TSDB_MND_STATUS_CLEANING;
|
||||||
|
|
||||||
dnodeFreeMWritequeue();
|
dnodeFreeMWritequeue();
|
||||||
dnodeFreeMReadQueue();
|
dnodeFreeMReadQueue();
|
||||||
|
@ -134,6 +149,7 @@ void mnodeCleanupSystem() {
|
||||||
mnodeCleanupTimer();
|
mnodeCleanupTimer();
|
||||||
mnodeCleanupComponents(sizeof(tsMnodeComponents) / sizeof(tsMnodeComponents[0]) - 1);
|
mnodeCleanupComponents(sizeof(tsMnodeComponents) / sizeof(tsMnodeComponents[0]) - 1);
|
||||||
|
|
||||||
|
tsMgmtStatus = TSDB_MND_STATUS_NOT_RUNNING;
|
||||||
mInfo("mnode is cleaned up");
|
mInfo("mnode is cleaned up");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,5 +200,29 @@ static bool mnodeNeedStart() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mnodeIsRunning() {
|
bool mnodeIsRunning() {
|
||||||
return tsMgmtIsRunning;
|
return (tsMgmtStatus != TSDB_MND_STATUS_NOT_RUNNING && tsMgmtStatus != TSDB_MND_STATUS_CLEANING);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mnodeIsReady() {
|
||||||
|
return (tsMgmtStatus == TSDB_MND_STATUS_READY);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mnodeInitCode() {
|
||||||
|
int32_t code = -1;
|
||||||
|
|
||||||
|
switch (tsMgmtStatus) {
|
||||||
|
case TSDB_MND_STATUS_INIT:
|
||||||
|
code = TSDB_CODE_MND_INIT;
|
||||||
|
break;
|
||||||
|
case TSDB_MND_STATUS_INIT_SDB:
|
||||||
|
code = TSDB_CODE_MND_INIT_SDB;
|
||||||
|
break;
|
||||||
|
case TSDB_MND_STATUS_INIT_OTHER:
|
||||||
|
code = TSDB_CODE_MND_INIT_OTHER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
code = TSDB_CODE_MND_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,6 +251,16 @@ static void sdbNotifyRole(int32_t vgId, int8_t role) {
|
||||||
sdbUpdateMnodeRoles();
|
sdbUpdateMnodeRoles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t sdbNotifyFileSynced(int32_t vgId, uint64_t fversion) { return 0; }
|
||||||
|
|
||||||
|
static void sdbNotifyFlowCtrl(int32_t vgId, int32_t level) {}
|
||||||
|
|
||||||
|
static int32_t sdbGetSyncVersion(int32_t vgId, uint64_t *fver, uint64_t *vver) {
|
||||||
|
*fver = 0;
|
||||||
|
*vver = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// failed to forward, need revert insert
|
// failed to forward, need revert insert
|
||||||
static void sdbHandleFailedConfirm(SSdbRow *pRow) {
|
static void sdbHandleFailedConfirm(SSdbRow *pRow) {
|
||||||
SWalHead *pHead = pRow->pHead;
|
SWalHead *pHead = pRow->pHead;
|
||||||
|
@ -299,7 +309,7 @@ void sdbUpdateAsync() {
|
||||||
|
|
||||||
void sdbUpdateSync(void *pMnodes) {
|
void sdbUpdateSync(void *pMnodes) {
|
||||||
SMnodeInfos *mnodes = pMnodes;
|
SMnodeInfos *mnodes = pMnodes;
|
||||||
if (!mnodeIsRunning()) {
|
if (!mnodeIsReady()) {
|
||||||
mDebug("vgId:1, mnode not start yet, update sync config later");
|
mDebug("vgId:1, mnode not start yet, update sync config later");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -372,11 +382,14 @@ void sdbUpdateSync(void *pMnodes) {
|
||||||
syncInfo.version = sdbGetVersion();
|
syncInfo.version = sdbGetVersion();
|
||||||
syncInfo.syncCfg = syncCfg;
|
syncInfo.syncCfg = syncCfg;
|
||||||
sprintf(syncInfo.path, "%s", tsMnodeDir);
|
sprintf(syncInfo.path, "%s", tsMnodeDir);
|
||||||
syncInfo.getWalInfo = sdbGetWalInfo;
|
|
||||||
syncInfo.getFileInfo = sdbGetFileInfo;
|
syncInfo.getFileInfo = sdbGetFileInfo;
|
||||||
|
syncInfo.getWalInfo = sdbGetWalInfo;
|
||||||
syncInfo.writeToCache = sdbWriteFwdToQueue;
|
syncInfo.writeToCache = sdbWriteFwdToQueue;
|
||||||
syncInfo.confirmForward = sdbConfirmForward;
|
syncInfo.confirmForward = sdbConfirmForward;
|
||||||
syncInfo.notifyRole = sdbNotifyRole;
|
syncInfo.notifyRole = sdbNotifyRole;
|
||||||
|
syncInfo.notifyFileSynced = sdbNotifyFileSynced;
|
||||||
|
syncInfo.notifyFlowCtrl = sdbNotifyFlowCtrl;
|
||||||
|
syncInfo.getVersion = sdbGetSyncVersion;
|
||||||
tsSdbMgmt.cfg = syncCfg;
|
tsSdbMgmt.cfg = syncCfg;
|
||||||
|
|
||||||
if (tsSdbMgmt.sync) {
|
if (tsSdbMgmt.sync) {
|
||||||
|
|
|
@ -585,10 +585,21 @@ void mnodeDropAllUsers(SAcctObj *pAcct) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||||
|
*secret = 0;
|
||||||
|
|
||||||
|
if (!mnodeIsRunning()) {
|
||||||
|
mDebug("user:%s, mnode is not running, fail to auth", user);
|
||||||
|
return TSDB_CODE_RPC_REDIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mnodeIsReady()) {
|
||||||
|
mDebug("user:%s, failed to auth user, mnode is not ready", user);
|
||||||
|
return mnodeInitCode();
|
||||||
|
}
|
||||||
|
|
||||||
if (!sdbIsMaster()) {
|
if (!sdbIsMaster()) {
|
||||||
*secret = 0;
|
|
||||||
mDebug("user:%s, failed to auth user, mnode is not master", user);
|
mDebug("user:%s, failed to auth user, mnode is not master", user);
|
||||||
return TSDB_CODE_APP_NOT_READY;
|
return TSDB_CODE_RPC_REDIRECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
SUserObj *pUser = mnodeGetUser(user);
|
SUserObj *pUser = mnodeGetUser(user);
|
||||||
|
|
|
@ -630,8 +630,16 @@ static void rpcReleaseConn(SRpcConn *pConn) {
|
||||||
} else {
|
} else {
|
||||||
// if there is an outgoing message, free it
|
// if there is an outgoing message, free it
|
||||||
if (pConn->outType && pConn->pReqMsg) {
|
if (pConn->outType && pConn->pReqMsg) {
|
||||||
if (pConn->pContext) pConn->pContext->pConn = NULL;
|
SRpcReqContext *pContext = pConn->pContext;
|
||||||
taosRemoveRef(tsRpcRefId, pConn->pContext->rid);
|
if (pContext->pRsp) {
|
||||||
|
// for synchronous API, post semaphore to unblock app
|
||||||
|
pContext->pRsp->code = TSDB_CODE_RPC_APP_ERROR;
|
||||||
|
pContext->pRsp->pCont = NULL;
|
||||||
|
pContext->pRsp->contLen = 0;
|
||||||
|
tsem_post(pContext->pSem);
|
||||||
|
}
|
||||||
|
pContext->pConn = NULL;
|
||||||
|
taosRemoveRef(tsRpcRefId, pContext->rid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1551,10 +1559,9 @@ static int rpcCheckAuthentication(SRpcConn *pConn, char *msg, int msgLen) {
|
||||||
if ( !rpcIsReq(pHead->msgType) ) {
|
if ( !rpcIsReq(pHead->msgType) ) {
|
||||||
// for response, if code is auth failure, it shall bypass the auth process
|
// for response, if code is auth failure, it shall bypass the auth process
|
||||||
code = htonl(pHead->code);
|
code = htonl(pHead->code);
|
||||||
if (code == TSDB_CODE_RPC_INVALID_TIME_STAMP || code == TSDB_CODE_RPC_AUTH_FAILURE ||
|
if (code != 0) {
|
||||||
code == TSDB_CODE_RPC_AUTH_REQUIRED || code == TSDB_CODE_MND_INVALID_USER || code == TSDB_CODE_RPC_NOT_READY) {
|
|
||||||
pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen);
|
|
||||||
// tTrace("%s, dont check authentication since code is:0x%x", pConn->info, code);
|
// tTrace("%s, dont check authentication since code is:0x%x", pConn->info, code);
|
||||||
|
pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,16 +139,14 @@ typedef struct SsyncPeer {
|
||||||
char id[TSDB_EP_LEN + 32]; // peer vgId + end point
|
char id[TSDB_EP_LEN + 32]; // peer vgId + end point
|
||||||
uint64_t version;
|
uint64_t version;
|
||||||
uint64_t sversion; // track the peer version in retrieve process
|
uint64_t sversion; // track the peer version in retrieve process
|
||||||
uint64_t lastVer; // track the file version while retrieve
|
uint64_t lastFileVer; // track the file version while retrieve
|
||||||
|
uint64_t lastWalVer; // track the wal version while retrieve
|
||||||
int32_t syncFd;
|
int32_t syncFd;
|
||||||
int32_t peerFd; // forward FD
|
int32_t peerFd; // forward FD
|
||||||
int32_t numOfRetrieves; // number of retrieves tried
|
int32_t numOfRetrieves; // number of retrieves tried
|
||||||
int32_t fileChanged; // a flag to indicate file is changed during retrieving process
|
int32_t fileChanged; // a flag to indicate file is changed during retrieving process
|
||||||
void * timer;
|
void * timer;
|
||||||
void * pConn;
|
void * pConn;
|
||||||
int32_t notifyFd;
|
|
||||||
int32_t watchNum;
|
|
||||||
int32_t *watchFd;
|
|
||||||
int32_t refCount; // reference count
|
int32_t refCount; // reference count
|
||||||
struct SSyncNode *pSyncNode;
|
struct SSyncNode *pSyncNode;
|
||||||
} SSyncPeer;
|
} SSyncPeer;
|
||||||
|
@ -173,7 +171,7 @@ typedef struct SSyncNode {
|
||||||
FNotifyRole notifyRole;
|
FNotifyRole notifyRole;
|
||||||
FNotifyFlowCtrl notifyFlowCtrl;
|
FNotifyFlowCtrl notifyFlowCtrl;
|
||||||
FNotifyFileSynced notifyFileSynced;
|
FNotifyFileSynced notifyFileSynced;
|
||||||
FGetFileVersion getFileVersion;
|
FGetVersion getVersion;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
} SSyncNode;
|
} SSyncNode;
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ int64_t syncStart(const SSyncInfo *pInfo) {
|
||||||
pNode->confirmForward = pInfo->confirmForward;
|
pNode->confirmForward = pInfo->confirmForward;
|
||||||
pNode->notifyFlowCtrl = pInfo->notifyFlowCtrl;
|
pNode->notifyFlowCtrl = pInfo->notifyFlowCtrl;
|
||||||
pNode->notifyFileSynced = pInfo->notifyFileSynced;
|
pNode->notifyFileSynced = pInfo->notifyFileSynced;
|
||||||
pNode->getFileVersion = pInfo->getFileVersion;
|
pNode->getVersion = pInfo->getVersion;
|
||||||
|
|
||||||
pNode->selfIndex = -1;
|
pNode->selfIndex = -1;
|
||||||
pNode->vgId = pInfo->vgId;
|
pNode->vgId = pInfo->vgId;
|
||||||
|
@ -498,7 +498,6 @@ int32_t syncDecPeerRef(SSyncPeer *pPeer) {
|
||||||
taosReleaseRef(tsSyncRefId, pPeer->pSyncNode->rid);
|
taosReleaseRef(tsSyncRefId, pPeer->pSyncNode->rid);
|
||||||
|
|
||||||
sDebug("%s, resource is freed", pPeer->id);
|
sDebug("%s, resource is freed", pPeer->id);
|
||||||
tfree(pPeer->watchFd);
|
|
||||||
tfree(pPeer);
|
tfree(pPeer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,39 +26,78 @@
|
||||||
#include "tsync.h"
|
#include "tsync.h"
|
||||||
#include "syncInt.h"
|
#include "syncInt.h"
|
||||||
|
|
||||||
static int32_t syncAreFilesModified(SSyncNode *pNode, SSyncPeer *pPeer) {
|
static int32_t syncGetWalVersion(SSyncNode *pNode, SSyncPeer *pPeer) {
|
||||||
if (pNode->getFileVersion == NULL) return TSDB_CODE_SUCCESS;
|
uint64_t fver, wver;
|
||||||
|
int32_t code = (*pNode->getVersion)(pNode->vgId, &fver, &wver);
|
||||||
uint64_t fver = 0;
|
|
||||||
int32_t code = (*pNode->getFileVersion)(pNode->vgId, &fver);
|
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
sInfo("%s, vnode is commiting while retrieve, last fver:%" PRIu64, pPeer->id, pPeer->lastVer);
|
sDebug("%s, vnode is commiting while retrieve, last wver:%" PRIu64, pPeer->id, pPeer->lastWalVer);
|
||||||
pPeer->fileChanged = 1;
|
return -1;
|
||||||
return TSDB_CODE_SYN_VND_COMMITING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fver != pPeer->lastVer) {
|
pPeer->lastWalVer = wver;
|
||||||
sInfo("%s, files are modified while retrieve, fver:%" PRIu64 ", last fver:%" PRIu64, pPeer->id, fver, pPeer->lastVer);
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool syncIsWalModified(SSyncNode *pNode, SSyncPeer *pPeer) {
|
||||||
|
uint64_t fver, wver;
|
||||||
|
int32_t code = (*pNode->getVersion)(pNode->vgId, &fver, &wver);
|
||||||
|
if (code != 0) {
|
||||||
|
sDebug("%s, vnode is commiting while retrieve, last wver:%" PRIu64, pPeer->id, pPeer->lastWalVer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wver != pPeer->lastWalVer) {
|
||||||
|
sDebug("%s, wal is modified while retrieve, wver:%" PRIu64 ", last:%" PRIu64, pPeer->id, wver, pPeer->lastWalVer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t syncGetFileVersion(SSyncNode *pNode, SSyncPeer *pPeer) {
|
||||||
|
uint64_t fver, wver;
|
||||||
|
int32_t code = (*pNode->getVersion)(pNode->vgId, &fver, &wver);
|
||||||
|
if (code != 0) {
|
||||||
|
sDebug("%s, vnode is commiting while retrieve, last fver:%" PRIu64, pPeer->id, pPeer->lastFileVer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPeer->lastFileVer = fver;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool syncAreFilesModified(SSyncNode *pNode, SSyncPeer *pPeer) {
|
||||||
|
uint64_t fver, wver;
|
||||||
|
int32_t code = (*pNode->getVersion)(pNode->vgId, &fver, &wver);
|
||||||
|
if (code != 0) {
|
||||||
|
sDebug("%s, vnode is commiting while retrieve, last fver:%" PRIu64, pPeer->id, pPeer->lastFileVer);
|
||||||
pPeer->fileChanged = 1;
|
pPeer->fileChanged = 1;
|
||||||
return TSDB_CODE_SYN_FILE_CHNAGED;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fver != pPeer->lastFileVer) {
|
||||||
|
sDebug("%s, files are modified while retrieve, fver:%" PRIu64 ", last:%" PRIu64, pPeer->id, fver, pPeer->lastFileVer);
|
||||||
|
pPeer->fileChanged = 1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPeer->fileChanged = 0;
|
pPeer->fileChanged = 0;
|
||||||
return TSDB_CODE_SUCCESS;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
||||||
SSyncNode *pNode = pPeer->pSyncNode;
|
SSyncNode *pNode = pPeer->pSyncNode;
|
||||||
SFileInfo fileInfo; memset(&fileInfo, 0, sizeof(SFileInfo));
|
SFileInfo fileInfo; memset(&fileInfo, 0, sizeof(SFileInfo));
|
||||||
SFileAck fileAck = {0};
|
SFileAck fileAck = {0};
|
||||||
int32_t code = TSDB_CODE_SYN_APP_ERROR;
|
int32_t code = -1;
|
||||||
char name[TSDB_FILENAME_LEN * 2] = {0};
|
char name[TSDB_FILENAME_LEN * 2] = {0};
|
||||||
|
|
||||||
if (pNode->getFileVersion) (*pNode->getFileVersion)(pNode->vgId, &pPeer->lastVer);
|
if (syncGetFileVersion(pNode, pPeer) < 0) return -1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// retrieve file info
|
// retrieve file info
|
||||||
fileInfo.name[0] = 0;
|
fileInfo.name[0] = 0;
|
||||||
|
fileInfo.size = 0;
|
||||||
fileInfo.magic = (*pNode->getFileInfo)(pNode->vgId, fileInfo.name, &fileInfo.index, TAOS_SYNC_MAX_INDEX,
|
fileInfo.magic = (*pNode->getFileInfo)(pNode->vgId, fileInfo.name, &fileInfo.index, TAOS_SYNC_MAX_INDEX,
|
||||||
&fileInfo.size, &fileInfo.fversion);
|
&fileInfo.size, &fileInfo.fversion);
|
||||||
// fileInfo.size = htonl(size);
|
// fileInfo.size = htonl(size);
|
||||||
|
@ -67,14 +106,14 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
||||||
// send the file info
|
// send the file info
|
||||||
int32_t ret = taosWriteMsg(pPeer->syncFd, &(fileInfo), sizeof(fileInfo));
|
int32_t ret = taosWriteMsg(pPeer->syncFd, &(fileInfo), sizeof(fileInfo));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
code = TAOS_SYSTEM_ERROR(errno);
|
code = -1;
|
||||||
sError("%s, failed to write file:%s info while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
sError("%s, failed to write file:%s info while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no file anymore, break
|
// if no file anymore, break
|
||||||
if (fileInfo.magic == 0 || fileInfo.name[0] == 0) {
|
if (fileInfo.magic == 0 || fileInfo.name[0] == 0) {
|
||||||
code = TSDB_CODE_SUCCESS;
|
code = 0;
|
||||||
sDebug("%s, no more files to sync", pPeer->id);
|
sDebug("%s, no more files to sync", pPeer->id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +121,7 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
||||||
// wait for the ack from peer
|
// wait for the ack from peer
|
||||||
ret = taosReadMsg(pPeer->syncFd, &fileAck, sizeof(fileAck));
|
ret = taosReadMsg(pPeer->syncFd, &fileAck, sizeof(fileAck));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
code = TAOS_SYSTEM_ERROR(errno);
|
code = -1;
|
||||||
sError("%s, failed to read file:%s ack while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
sError("%s, failed to read file:%s ack while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +142,7 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
||||||
// send the file to peer
|
// send the file to peer
|
||||||
int32_t sfd = open(name, O_RDONLY);
|
int32_t sfd = open(name, O_RDONLY);
|
||||||
if (sfd < 0) {
|
if (sfd < 0) {
|
||||||
code = TAOS_SYSTEM_ERROR(errno);
|
code = -1;
|
||||||
sError("%s, failed to open file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
sError("%s, failed to open file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +150,7 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
||||||
ret = taosSendFile(pPeer->syncFd, sfd, NULL, fileInfo.size);
|
ret = taosSendFile(pPeer->syncFd, sfd, NULL, fileInfo.size);
|
||||||
close(sfd);
|
close(sfd);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
code = TAOS_SYSTEM_ERROR(errno);
|
code = -1;
|
||||||
sError("%s, failed to send file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
sError("%s, failed to send file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -120,128 +159,103 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
||||||
fileInfo.index++;
|
fileInfo.index++;
|
||||||
|
|
||||||
// check if processed files are modified
|
// check if processed files are modified
|
||||||
code = syncAreFilesModified(pNode, pPeer);
|
if (syncAreFilesModified(pNode, pPeer)) {
|
||||||
if (code != TSDB_CODE_SUCCESS) break;
|
code = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
sError("%s, failed to retrieve file since %s", pPeer->id, tstrerror(code));
|
sError("%s, failed to retrieve file, code:0x%x", pPeer->id, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if only a partial record is read out, set the IN_MODIFY flag in event,
|
// if only a partial record is read out, upper layer will reload the file to get a complete record
|
||||||
so upper layer will reload the file to get a complete record */
|
static int32_t syncReadOneWalRecord(int32_t sfd, SWalHead *pHead) {
|
||||||
static int32_t syncReadOneWalRecord(int32_t sfd, SWalHead *pHead, uint32_t *pEvent) {
|
int32_t ret = read(sfd, pHead, sizeof(SWalHead));
|
||||||
int32_t ret;
|
if (ret < 0) {
|
||||||
|
sError("sfd:%d, failed to read wal head since %s, ret:%d", sfd, strerror(errno), ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = read(sfd, pHead, sizeof(SWalHead));
|
if (ret == 0) {
|
||||||
if (ret < 0) return -1;
|
sTrace("sfd:%d, read to the end of file, ret:%d", sfd, ret);
|
||||||
if (ret == 0) return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret != sizeof(SWalHead)) {
|
if (ret != sizeof(SWalHead)) {
|
||||||
// file is not at end yet, it shall be reloaded
|
// file is not at end yet, it shall be reloaded
|
||||||
*pEvent = *pEvent | IN_MODIFY;
|
sDebug("sfd:%d, a partial wal head is read out, ret:%d", sfd, ret);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pHead->len <= TSDB_MAX_WAL_SIZE);
|
assert(pHead->len <= TSDB_MAX_WAL_SIZE);
|
||||||
|
|
||||||
ret = read(sfd, pHead->cont, pHead->len);
|
ret = read(sfd, pHead->cont, pHead->len);
|
||||||
if (ret < 0) return -1;
|
if (ret < 0) {
|
||||||
|
sError("sfd:%d, failed to read wal content since %s, ret:%d", sfd, strerror(errno), ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret != pHead->len) {
|
if (ret != pHead->len) {
|
||||||
// file is not at end yet, it shall be reloaded
|
// file is not at end yet, it shall be reloaded
|
||||||
*pEvent = *pEvent | IN_MODIFY;
|
sDebug("sfd:%d, a partial wal conetnt is read out, ret:%d", sfd, ret);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizeof(SWalHead) + pHead->len;
|
return sizeof(SWalHead) + pHead->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t syncMonitorLastWal(SSyncPeer *pPeer, char *name) {
|
static int32_t syncRetrieveLastWal(SSyncPeer *pPeer, char *name, uint64_t fversion, int64_t offset) {
|
||||||
pPeer->watchNum = 0;
|
int32_t sfd = open(name, O_RDONLY);
|
||||||
taosClose(pPeer->notifyFd);
|
|
||||||
pPeer->notifyFd = inotify_init1(IN_NONBLOCK);
|
|
||||||
if (pPeer->notifyFd < 0) {
|
|
||||||
sError("%s, failed to init inotify since %s", pPeer->id, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pPeer->watchFd == NULL) pPeer->watchFd = malloc(sizeof(int32_t) * tsMaxWatchFiles);
|
|
||||||
if (pPeer->watchFd == NULL) {
|
|
||||||
sError("%s, failed to allocate watchFd", pPeer->id);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(pPeer->watchFd, -1, sizeof(int32_t) * tsMaxWatchFiles);
|
|
||||||
int32_t *wd = pPeer->watchFd;
|
|
||||||
|
|
||||||
*wd = inotify_add_watch(pPeer->notifyFd, name, IN_MODIFY | IN_CLOSE_WRITE);
|
|
||||||
if (*wd == -1) {
|
|
||||||
sError("%s, failed to watch last wal since %s", pPeer->id, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t syncCheckLastWalChanges(SSyncPeer *pPeer, uint32_t *pEvent) {
|
|
||||||
char buf[2048];
|
|
||||||
int32_t len = read(pPeer->notifyFd, buf, sizeof(buf));
|
|
||||||
if (len < 0 && errno != EAGAIN) {
|
|
||||||
sError("%s, failed to read notify FD since %s", pPeer->id, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len == 0) return 0;
|
|
||||||
|
|
||||||
struct inotify_event *event;
|
|
||||||
for (char *ptr = buf; ptr < buf + len; ptr += sizeof(struct inotify_event) + event->len) {
|
|
||||||
event = (struct inotify_event *)ptr;
|
|
||||||
if (event->mask & IN_MODIFY) *pEvent = *pEvent | IN_MODIFY;
|
|
||||||
if (event->mask & IN_CLOSE_WRITE) *pEvent = *pEvent | IN_CLOSE_WRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pEvent != 0) sDebug("%s, last wal event:0x%x", pPeer->id, *pEvent);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t syncRetrieveLastWal(SSyncPeer *pPeer, char *name, uint64_t fversion, int64_t offset, uint32_t *pEvent) {
|
|
||||||
SWalHead *pHead = malloc(SYNC_MAX_SIZE);
|
|
||||||
int32_t code = -1;
|
|
||||||
int32_t bytes = 0;
|
|
||||||
int32_t sfd;
|
|
||||||
|
|
||||||
sfd = open(name, O_RDONLY);
|
|
||||||
if (sfd < 0) {
|
if (sfd < 0) {
|
||||||
free(pHead);
|
sError("%s, failed to open wal:%s for retrieve since:%s", pPeer->id, name, tstrerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)lseek(sfd, offset, SEEK_SET);
|
int32_t code = taosLSeek(sfd, offset, SEEK_SET);
|
||||||
sDebug("%s, retrieve last wal, offset:%" PRId64 " fver:%" PRIu64, pPeer->id, offset, fversion);
|
if (code < 0) {
|
||||||
|
sError("%s, failed to seek %" PRId64 " in wal:%s for retrieve since:%s", pPeer->id, offset, name, tstrerror(errno));
|
||||||
|
close(sfd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sDebug("%s, retrieve last wal:%s, offset:%" PRId64 " fver:%" PRIu64, pPeer->id, name, offset, fversion);
|
||||||
|
|
||||||
|
SWalHead *pHead = malloc(SYNC_MAX_SIZE);
|
||||||
|
int32_t bytes = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int32_t wsize = syncReadOneWalRecord(sfd, pHead, pEvent);
|
code = syncReadOneWalRecord(sfd, pHead);
|
||||||
if (wsize < 0) break;
|
if (code < 0) {
|
||||||
if (wsize == 0) {
|
sError("%s, failed to read one record from wal:%s", pPeer->id, name);
|
||||||
code = 0;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == 0) {
|
||||||
|
code = bytes;
|
||||||
|
sDebug("%s, read to the end of wal, bytes:%d", pPeer->id, bytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sTrace("%s, last wal is forwarded, hver:%" PRIu64, pPeer->id, pHead->version);
|
sTrace("%s, last wal is forwarded, hver:%" PRIu64, pPeer->id, pHead->version);
|
||||||
int32_t ret = taosWriteMsg(pPeer->syncFd, pHead, wsize);
|
|
||||||
if (ret != wsize) break;
|
|
||||||
pPeer->sversion = pHead->version;
|
|
||||||
|
|
||||||
|
int32_t wsize = code;
|
||||||
|
int32_t ret = taosWriteMsg(pPeer->syncFd, pHead, wsize);
|
||||||
|
if (ret != wsize) {
|
||||||
|
code = -1;
|
||||||
|
sError("%s, failed to forward wal since %s, hver:%" PRIu64, pPeer->id, strerror(errno), pHead->version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPeer->sversion = pHead->version;
|
||||||
bytes += wsize;
|
bytes += wsize;
|
||||||
|
|
||||||
if (pHead->version >= fversion && fversion > 0) {
|
if (pHead->version >= fversion && fversion > 0) {
|
||||||
code = 0;
|
code = 0;
|
||||||
bytes = 0;
|
sDebug("%s, retrieve wal finished, hver:%" PRIu64 " fver:%" PRIu64, pPeer->id, pHead->version, fversion);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,92 +263,62 @@ static int32_t syncRetrieveLastWal(SSyncPeer *pPeer, char *name, uint64_t fversi
|
||||||
free(pHead);
|
free(pHead);
|
||||||
close(sfd);
|
close(sfd);
|
||||||
|
|
||||||
if (code == 0) return bytes;
|
return code;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index) {
|
static int32_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index) {
|
||||||
SSyncNode *pNode = pPeer->pSyncNode;
|
SSyncNode *pNode = pPeer->pSyncNode;
|
||||||
int32_t code = -1;
|
int32_t once = 0; // last WAL has once ever been processed
|
||||||
|
int64_t offset = 0;
|
||||||
|
uint64_t fversion = 0;
|
||||||
char fname[TSDB_FILENAME_LEN * 2] = {0}; // full path to wal file
|
char fname[TSDB_FILENAME_LEN * 2] = {0}; // full path to wal file
|
||||||
|
|
||||||
if (syncAreFilesModified(pNode, pPeer) != 0) return -1;
|
// get full path to wal file
|
||||||
|
snprintf(fname, sizeof(fname), "%s/%s", pNode->path, wname);
|
||||||
|
sDebug("%s, start to retrieve last wal:%s", pPeer->id, fname);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int32_t once = 0; // last WAL has once ever been processed
|
if (syncAreFilesModified(pNode, pPeer)) return -1;
|
||||||
int64_t offset = 0;
|
if (syncGetWalVersion(pNode, pPeer) < 0) return -1;
|
||||||
uint64_t fversion = 0;
|
|
||||||
uint32_t event = 0;
|
|
||||||
|
|
||||||
// get full path to wal file
|
int32_t bytes = syncRetrieveLastWal(pPeer, fname, fversion, offset);
|
||||||
snprintf(fname, sizeof(fname), "%s/%s", pNode->path, wname);
|
if (bytes < 0) {
|
||||||
sDebug("%s, start to retrieve last wal:%s", pPeer->id, fname);
|
sDebug("%s, failed to retrieve last wal", pPeer->id);
|
||||||
|
return bytes;
|
||||||
// monitor last wal
|
|
||||||
if (syncMonitorLastWal(pPeer, fname) < 0) break;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
int32_t bytes = syncRetrieveLastWal(pPeer, fname, fversion, offset, &event);
|
|
||||||
if (bytes < 0) break;
|
|
||||||
|
|
||||||
// check file changes
|
|
||||||
if (syncCheckLastWalChanges(pPeer, &event) < 0) break;
|
|
||||||
|
|
||||||
// if file is not updated or updated once, set the fversion and sstatus
|
|
||||||
if (((event & IN_MODIFY) == 0) || once) {
|
|
||||||
if (fversion == 0) {
|
|
||||||
pPeer->sstatus = TAOS_SYNC_STATUS_CACHE; // start to forward pkt
|
|
||||||
sDebug("%s, fversion is 0 then set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
|
||||||
fversion = nodeVersion; // must read data to fversion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if all data up to fversion is read out, it is over
|
|
||||||
if (pPeer->sversion >= fversion && fversion > 0) {
|
|
||||||
code = 0;
|
|
||||||
sDebug("%s, data up to fver:%" PRIu64 " has been read out, bytes:%d", pPeer->id, fversion, bytes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if all data are read out, and no update
|
|
||||||
if ((bytes == 0) && ((event & IN_MODIFY) == 0)) {
|
|
||||||
// wal file is closed, break
|
|
||||||
if (event & IN_CLOSE_WRITE) {
|
|
||||||
code = 0;
|
|
||||||
sDebug("%s, current wal is closed", pPeer->id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// wal not closed, it means some data not flushed to disk, wait for a while
|
|
||||||
usleep(10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if bytes>0, file is updated, or fversion is not reached but file still open, read again
|
|
||||||
once = 1;
|
|
||||||
offset += bytes;
|
|
||||||
sDebug("%s, retrieve last wal, bytes:%d", pPeer->id, bytes);
|
|
||||||
event = event & (~IN_MODIFY); // clear IN_MODIFY flag
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code < 0) break;
|
// check file changes
|
||||||
if (pPeer->sversion >= fversion && fversion > 0) break;
|
bool walModified = syncIsWalModified(pNode, pPeer);
|
||||||
|
|
||||||
index++;
|
// if file is not updated or updated once, set the fversion and sstatus
|
||||||
wname[0] = 0;
|
if (!walModified || once) {
|
||||||
code = (*pNode->getWalInfo)(pNode->vgId, wname, &index);
|
if (fversion == 0) {
|
||||||
if (code < 0) break;
|
pPeer->sstatus = TAOS_SYNC_STATUS_CACHE; // start to forward pkt
|
||||||
if (wname[0] == 0) {
|
fversion = nodeVersion; // must read data to fversion
|
||||||
code = 0;
|
sDebug("%s, set sstatus:%s and fver:%" PRIu64, pPeer->id, syncStatus[pPeer->sstatus], fversion);
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// current last wal is closed, there is a new one
|
// if all data up to fversion is read out, it is over
|
||||||
sDebug("%s, last wal is closed, try new one", pPeer->id);
|
if (pPeer->sversion >= fversion && fversion > 0) {
|
||||||
|
sDebug("%s, data up to fver:%" PRIu64 " has been read out, bytes:%d sver:%" PRIu64, pPeer->id, fversion, bytes,
|
||||||
|
pPeer->sversion);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if all data are read out, and no update
|
||||||
|
if (bytes == 0 && !walModified) {
|
||||||
|
// wal not closed, it means some data not flushed to disk, wait for a while
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if bytes > 0, file is updated, or fversion is not reached but file still open, read again
|
||||||
|
once = 1;
|
||||||
|
offset += bytes;
|
||||||
|
sDebug("%s, continue retrieve last wal, bytes:%d offset:%" PRId64, pPeer->id, bytes, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosClose(pPeer->notifyFd);
|
return -1;
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t syncRetrieveWal(SSyncPeer *pPeer) {
|
static int32_t syncRetrieveWal(SSyncPeer *pPeer) {
|
||||||
|
@ -342,7 +326,6 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) {
|
||||||
char fname[TSDB_FILENAME_LEN * 3];
|
char fname[TSDB_FILENAME_LEN * 3];
|
||||||
char wname[TSDB_FILENAME_LEN * 2];
|
char wname[TSDB_FILENAME_LEN * 2];
|
||||||
int32_t size;
|
int32_t size;
|
||||||
struct stat fstat;
|
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
int64_t index = 0;
|
int64_t index = 0;
|
||||||
|
|
||||||
|
@ -350,9 +333,14 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) {
|
||||||
// retrieve wal info
|
// retrieve wal info
|
||||||
wname[0] = 0;
|
wname[0] = 0;
|
||||||
code = (*pNode->getWalInfo)(pNode->vgId, wname, &index);
|
code = (*pNode->getWalInfo)(pNode->vgId, wname, &index);
|
||||||
if (code < 0) break; // error
|
if (code < 0) {
|
||||||
|
sError("%s, failed to get wal info since:%s, code:0x%x", pPeer->id, strerror(errno), code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (wname[0] == 0) { // no wal file
|
if (wname[0] == 0) { // no wal file
|
||||||
sDebug("%s, no wal file", pPeer->id);
|
code = 0;
|
||||||
|
sDebug("%s, no wal file anymore", pPeer->id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,20 +352,35 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) {
|
||||||
// get the full path to wal file
|
// get the full path to wal file
|
||||||
snprintf(fname, sizeof(fname), "%s/%s", pNode->path, wname);
|
snprintf(fname, sizeof(fname), "%s/%s", pNode->path, wname);
|
||||||
|
|
||||||
// send wal file,
|
// send wal file, old wal file won't be modified, even remove is ok
|
||||||
// inotify is not required, old wal file won't be modified, even remove is ok
|
struct stat fstat;
|
||||||
if (stat(fname, &fstat) < 0) break;
|
if (stat(fname, &fstat) < 0) {
|
||||||
size = fstat.st_size;
|
code = -1;
|
||||||
|
sDebug("%s, failed to stat wal:%s for retrieve since %s, code:0x%x", pPeer->id, fname, strerror(errno), code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = fstat.st_size;
|
||||||
sDebug("%s, retrieve wal:%s size:%d", pPeer->id, fname, size);
|
sDebug("%s, retrieve wal:%s size:%d", pPeer->id, fname, size);
|
||||||
|
|
||||||
int32_t sfd = open(fname, O_RDONLY);
|
int32_t sfd = open(fname, O_RDONLY);
|
||||||
if (sfd < 0) break;
|
if (sfd < 0) {
|
||||||
|
code = -1;
|
||||||
|
sError("%s, failed to open wal:%s for retrieve since %s, code:0x%x", pPeer->id, fname, strerror(errno), code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
code = taosSendFile(pPeer->syncFd, sfd, NULL, size);
|
code = taosSendFile(pPeer->syncFd, sfd, NULL, size);
|
||||||
close(sfd);
|
close(sfd);
|
||||||
if (code < 0) break;
|
if (code < 0) {
|
||||||
|
sError("%s, failed to send wal:%s for retrieve since %s, code:0x%x", pPeer->id, fname, strerror(errno), code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (syncAreFilesModified(pNode, pPeer) != 0) break;
|
if (syncAreFilesModified(pNode, pPeer)) {
|
||||||
|
code = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
|
@ -386,9 +389,9 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) {
|
||||||
|
|
||||||
SWalHead walHead;
|
SWalHead walHead;
|
||||||
memset(&walHead, 0, sizeof(walHead));
|
memset(&walHead, 0, sizeof(walHead));
|
||||||
code = taosWriteMsg(pPeer->syncFd, &walHead, sizeof(walHead));
|
taosWriteMsg(pPeer->syncFd, &walHead, sizeof(walHead));
|
||||||
} else {
|
} else {
|
||||||
sError("%s, failed to send wal since %s", pPeer->id, strerror(errno));
|
sError("%s, failed to send wal since %s, code:0x%x", pPeer->id, strerror(errno), code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -428,7 +431,7 @@ static int32_t syncRetrieveDataStepByStep(SSyncPeer *pPeer) {
|
||||||
pPeer->sversion = 0;
|
pPeer->sversion = 0;
|
||||||
pPeer->sstatus = TAOS_SYNC_STATUS_FILE;
|
pPeer->sstatus = TAOS_SYNC_STATUS_FILE;
|
||||||
sInfo("%s, start to retrieve files, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
sInfo("%s, start to retrieve files, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||||
if (syncRetrieveFile(pPeer) < 0) {
|
if (syncRetrieveFile(pPeer) != 0) {
|
||||||
sError("%s, failed to retrieve files", pPeer->id);
|
sError("%s, failed to retrieve files", pPeer->id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -437,8 +440,9 @@ static int32_t syncRetrieveDataStepByStep(SSyncPeer *pPeer) {
|
||||||
if (pPeer->sversion == 0) pPeer->sversion = 1;
|
if (pPeer->sversion == 0) pPeer->sversion = 1;
|
||||||
|
|
||||||
sInfo("%s, start to retrieve wals", pPeer->id);
|
sInfo("%s, start to retrieve wals", pPeer->id);
|
||||||
if (syncRetrieveWal(pPeer) < 0) {
|
int32_t code = syncRetrieveWal(pPeer);
|
||||||
sError("%s, failed to retrieve wals", pPeer->id);
|
if (code != 0) {
|
||||||
|
sError("%s, failed to retrieve wals, code:0x%x", pPeer->id, code);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +478,6 @@ void *syncRetrieveData(void *param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pPeer->fileChanged = 0;
|
pPeer->fileChanged = 0;
|
||||||
taosClose(pPeer->notifyFd);
|
|
||||||
taosClose(pPeer->syncFd);
|
taosClose(pPeer->syncFd);
|
||||||
syncDecPeerRef(pPeer);
|
syncDecPeerRef(pPeer);
|
||||||
|
|
||||||
|
|
|
@ -917,6 +917,8 @@ static int tsdbInsertSuperBlock(SRWHelper *pHelper, SCompBlock *pCompBlock, int
|
||||||
ASSERT(pHelper->pCompInfo->blocks[0].keyLast < pHelper->pCompInfo->blocks[1].keyFirst);
|
ASSERT(pHelper->pCompInfo->blocks[0].keyLast < pHelper->pCompInfo->blocks[1].keyFirst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT((blkIdx == pIdx->numOfBlocks -1) || (!pCompBlock->last));
|
||||||
|
|
||||||
tsdbDebug("vgId:%d tid:%d a super block is inserted at index %d", REPO_ID(pHelper->pRepo), pHelper->tableInfo.tid,
|
tsdbDebug("vgId:%d tid:%d a super block is inserted at index %d", REPO_ID(pHelper->pRepo), pHelper->tableInfo.tid,
|
||||||
blkIdx);
|
blkIdx);
|
||||||
|
|
||||||
|
@ -1042,6 +1044,8 @@ static int tsdbUpdateSuperBlock(SRWHelper *pHelper, SCompBlock *pCompBlock, int
|
||||||
pIdx->maxKey = blockAtIdx(pHelper, pIdx->numOfBlocks - 1)->keyLast;
|
pIdx->maxKey = blockAtIdx(pHelper, pIdx->numOfBlocks - 1)->keyLast;
|
||||||
pIdx->hasLast = (uint32_t)blockAtIdx(pHelper, pIdx->numOfBlocks - 1)->last;
|
pIdx->hasLast = (uint32_t)blockAtIdx(pHelper, pIdx->numOfBlocks - 1)->last;
|
||||||
|
|
||||||
|
ASSERT((blkIdx == pIdx->numOfBlocks-1) || (!pCompBlock->last));
|
||||||
|
|
||||||
tsdbDebug("vgId:%d tid:%d a super block is updated at index %d", REPO_ID(pHelper->pRepo), pHelper->tableInfo.tid,
|
tsdbDebug("vgId:%d tid:%d a super block is updated at index %d", REPO_ID(pHelper->pRepo), pHelper->tableInfo.tid,
|
||||||
blkIdx);
|
blkIdx);
|
||||||
|
|
||||||
|
@ -1622,11 +1626,7 @@ static int tsdbProcessMergeCommit(SRWHelper *pHelper, SCommitIter *pCommitIter,
|
||||||
pCfg->update);
|
pCfg->update);
|
||||||
|
|
||||||
if (pDataCols->numOfRows == 0) break;
|
if (pDataCols->numOfRows == 0) break;
|
||||||
if (tblkIdx == pIdx->numOfBlocks - 1) {
|
if (tsdbWriteBlockToFile(pHelper, helperDataF(pHelper), pDataCols, &compBlock, false, true) < 0) return -1;
|
||||||
if (tsdbWriteBlockToProperFile(pHelper, pDataCols, &compBlock) < 0) return -1;
|
|
||||||
} else {
|
|
||||||
if (tsdbWriteBlockToFile(pHelper, helperDataF(pHelper), pDataCols, &compBlock, false, true) < 0) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (round == 0) {
|
if (round == 0) {
|
||||||
if (oBlock.last && pHelper->hasOldLastBlock) pHelper->hasOldLastBlock = false;
|
if (oBlock.last && pHelper->hasOldLastBlock) pHelper->hasOldLastBlock = false;
|
||||||
|
|
|
@ -560,37 +560,6 @@ void taosTmrCleanUp(void* handle) {
|
||||||
tmrDebug("%s timer controller is cleaned up.", ctrl->label);
|
tmrDebug("%s timer controller is cleaned up.", ctrl->label);
|
||||||
ctrl->label[0] = 0;
|
ctrl->label[0] = 0;
|
||||||
|
|
||||||
// cancel all timers of this controller
|
|
||||||
for (size_t i = 0; i < timerMap.size; i++) {
|
|
||||||
timer_list_t* list = timerMap.slots + i;
|
|
||||||
lockTimerList(list);
|
|
||||||
|
|
||||||
tmr_obj_t* t = list->timers;
|
|
||||||
tmr_obj_t* prev = NULL;
|
|
||||||
while (t != NULL) {
|
|
||||||
tmr_obj_t* next = t->mnext;
|
|
||||||
if (t->ctrl != ctrl) {
|
|
||||||
prev = t;
|
|
||||||
t = next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t state = atomic_val_compare_exchange_8(&t->state, TIMER_STATE_WAITING, TIMER_STATE_CANCELED);
|
|
||||||
if (state == TIMER_STATE_WAITING) {
|
|
||||||
removeFromWheel(t);
|
|
||||||
}
|
|
||||||
timerDecRef(t);
|
|
||||||
if (prev == NULL) {
|
|
||||||
list->timers = next;
|
|
||||||
} else {
|
|
||||||
prev->mnext = next;
|
|
||||||
}
|
|
||||||
t = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
unlockTimerList(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(&tmrCtrlMutex);
|
pthread_mutex_lock(&tmrCtrlMutex);
|
||||||
ctrl->next = unusedTmrCtrl;
|
ctrl->next = unusedTmrCtrl;
|
||||||
numOfTmrCtrl--;
|
numOfTmrCtrl--;
|
||||||
|
|
|
@ -38,7 +38,7 @@ static void vnodeCtrlFlow(int32_t vgId, int32_t level);
|
||||||
static int32_t vnodeNotifyFileSynced(int32_t vgId, uint64_t fversion);
|
static int32_t vnodeNotifyFileSynced(int32_t vgId, uint64_t fversion);
|
||||||
static void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code);
|
static void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code);
|
||||||
static int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam);
|
static int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam);
|
||||||
static int32_t vnodeGetFileVersion(int32_t vgId, uint64_t *fver);
|
static int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver);
|
||||||
|
|
||||||
#ifndef _SYNC
|
#ifndef _SYNC
|
||||||
int64_t syncStart(const SSyncInfo *info) { return NULL; }
|
int64_t syncStart(const SSyncInfo *info) { return NULL; }
|
||||||
|
@ -272,7 +272,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
|
||||||
strcpy(cqCfg.pass, tsInternalPass);
|
strcpy(cqCfg.pass, tsInternalPass);
|
||||||
strcpy(cqCfg.db, pVnode->db);
|
strcpy(cqCfg.db, pVnode->db);
|
||||||
cqCfg.vgId = vnode;
|
cqCfg.vgId = vnode;
|
||||||
cqCfg.cqWrite = vnodeWriteToWQueue;
|
cqCfg.cqWrite = vnodeWriteToCache;
|
||||||
pVnode->cq = cqOpen(pVnode, &cqCfg);
|
pVnode->cq = cqOpen(pVnode, &cqCfg);
|
||||||
if (pVnode->cq == NULL) {
|
if (pVnode->cq == NULL) {
|
||||||
vnodeCleanUp(pVnode);
|
vnodeCleanUp(pVnode);
|
||||||
|
@ -353,7 +353,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
|
||||||
syncInfo.notifyRole = vnodeNotifyRole;
|
syncInfo.notifyRole = vnodeNotifyRole;
|
||||||
syncInfo.notifyFlowCtrl = vnodeCtrlFlow;
|
syncInfo.notifyFlowCtrl = vnodeCtrlFlow;
|
||||||
syncInfo.notifyFileSynced = vnodeNotifyFileSynced;
|
syncInfo.notifyFileSynced = vnodeNotifyFileSynced;
|
||||||
syncInfo.getFileVersion = vnodeGetFileVersion;
|
syncInfo.getVersion = vnodeGetVersion;
|
||||||
pVnode->sync = syncStart(&syncInfo);
|
pVnode->sync = syncStart(&syncInfo);
|
||||||
|
|
||||||
#ifndef _SYNC
|
#ifndef _SYNC
|
||||||
|
@ -771,7 +771,7 @@ static int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vnodeGetFileVersion(int32_t vgId, uint64_t *fver) {
|
static int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver) {
|
||||||
SVnodeObj *pVnode = vnodeAcquire(vgId);
|
SVnodeObj *pVnode = vnodeAcquire(vgId);
|
||||||
if (pVnode == NULL) {
|
if (pVnode == NULL) {
|
||||||
vError("vgId:%d, vnode not found while write to cache", vgId);
|
vError("vgId:%d, vnode not found while write to cache", vgId);
|
||||||
|
@ -780,10 +780,11 @@ static int32_t vnodeGetFileVersion(int32_t vgId, uint64_t *fver) {
|
||||||
|
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
if (pVnode->isCommiting) {
|
if (pVnode->isCommiting) {
|
||||||
vDebug("vgId:%d, vnode is commiting while get file version", vgId);
|
vDebug("vgId:%d, vnode is commiting while get version", vgId);
|
||||||
code = -1;
|
code = -1;
|
||||||
} else {
|
} else {
|
||||||
*fver = pVnode->fversion;
|
*fver = pVnode->fversion;
|
||||||
|
*wver = pVnode->version;
|
||||||
}
|
}
|
||||||
|
|
||||||
vnodeRelease(pVnode);
|
vnodeRelease(pVnode);
|
||||||
|
|
Loading…
Reference in New Issue