2022-04-19 07:43:24 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can use, redistribute, and/or modify
|
|
|
|
|
* it under the terms of the GNU Affero General Public License, version 3
|
|
|
|
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2022-05-20 02:51:53 +00:00
|
|
|
#define _DEFAULT_SOURCE
|
2023-09-20 01:54:28 +00:00
|
|
|
#include "sync.h"
|
2024-01-10 09:57:08 +00:00
|
|
|
#include "tq.h"
|
2023-09-20 01:54:28 +00:00
|
|
|
#include "tsdb.h"
|
2022-04-26 11:04:26 +00:00
|
|
|
#include "vnd.h"
|
2025-04-24 01:11:54 +00:00
|
|
|
#include "stream.h"
|
2022-04-19 07:43:24 +00:00
|
|
|
|
2022-12-02 10:59:03 +00:00
|
|
|
#define BATCH_ENABLE 0
|
2022-07-25 09:10:04 +00:00
|
|
|
|
2022-06-08 06:44:42 +00:00
|
|
|
static inline bool vnodeIsMsgWeak(tmsg_t type) { return false; }
|
2022-05-20 02:51:53 +00:00
|
|
|
|
2022-07-18 10:37:58 +00:00
|
|
|
static inline void vnodeWaitBlockMsg(SVnode *pVnode, const SRpcMsg *pMsg) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGTrace(&pMsg->info.traceId, "vgId:%d, msg:%p, wait block, type:%s sec:%d seq:%" PRId64, pVnode->config.vgId, pMsg,
|
2022-12-14 01:14:40 +00:00
|
|
|
TMSG_INFO(pMsg->msgType), pVnode->blockSec, pVnode->blockSeq);
|
2024-09-24 08:48:07 +00:00
|
|
|
if (tsem_wait(&pVnode->syncSem) != 0) {
|
|
|
|
|
vError("vgId:%d, failed to wait sem", pVnode->config.vgId);
|
|
|
|
|
}
|
2022-12-03 12:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
2022-07-18 10:37:58 +00:00
|
|
|
static inline void vnodePostBlockMsg(SVnode *pVnode, const SRpcMsg *pMsg) {
|
|
|
|
|
if (vnodeIsMsgBlock(pMsg->msgType)) {
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexLock(&pVnode->lock);
|
2022-08-12 08:32:11 +00:00
|
|
|
if (pVnode->blocked) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGTrace(&pMsg->info.traceId, "vgId:%d, msg:%p, post block, type:%s sec:%d seq:%" PRId64, pVnode->config.vgId, pMsg,
|
2022-12-14 08:09:28 +00:00
|
|
|
TMSG_INFO(pMsg->msgType), pVnode->blockSec, pVnode->blockSeq);
|
2022-08-12 08:32:11 +00:00
|
|
|
pVnode->blocked = false;
|
2022-12-14 08:09:28 +00:00
|
|
|
pVnode->blockSec = 0;
|
|
|
|
|
pVnode->blockSeq = 0;
|
2024-09-24 08:48:07 +00:00
|
|
|
if (tsem_post(&pVnode->syncSem) != 0) {
|
|
|
|
|
vError("vgId:%d, failed to post sem", pVnode->config.vgId);
|
|
|
|
|
}
|
2022-08-01 11:40:38 +00:00
|
|
|
}
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
2022-06-08 06:44:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-02 14:45:11 +00:00
|
|
|
void vnodeRedirectRpcMsg(SVnode *pVnode, SRpcMsg *pMsg, int32_t code) {
|
2022-07-06 07:15:55 +00:00
|
|
|
SEpSet newEpSet = {0};
|
|
|
|
|
syncGetRetryEpSet(pVnode->sync, &newEpSet);
|
|
|
|
|
|
2025-03-18 08:21:44 +00:00
|
|
|
vGTrace(&pMsg->info.traceId, "vgId:%d, msg:%p, is redirect since not leader, numOfEps:%d inUse:%d",
|
|
|
|
|
pVnode->config.vgId, pMsg, newEpSet.numOfEps, newEpSet.inUse);
|
2022-07-06 07:15:55 +00:00
|
|
|
for (int32_t i = 0; i < newEpSet.numOfEps; ++i) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGTrace(&pMsg->info.traceId, "vgId:%d, msg:%p, redirect:%d ep:%s:%u", pVnode->config.vgId, pMsg, i,
|
|
|
|
|
newEpSet.eps[i].fqdn, newEpSet.eps[i].port);
|
2022-07-06 07:15:55 +00:00
|
|
|
}
|
|
|
|
|
pMsg->info.hasEpSet = 1;
|
|
|
|
|
|
2022-12-02 14:45:11 +00:00
|
|
|
if (code == 0) code = TSDB_CODE_SYN_NOT_LEADER;
|
|
|
|
|
|
|
|
|
|
SRpcMsg rsp = {.code = code, .info = pMsg->info, .msgType = pMsg->msgType + 1};
|
2022-12-02 14:24:35 +00:00
|
|
|
int32_t contLen = tSerializeSEpSet(NULL, 0, &newEpSet);
|
|
|
|
|
|
|
|
|
|
rsp.pCont = rpcMallocCont(contLen);
|
|
|
|
|
if (rsp.pCont == NULL) {
|
|
|
|
|
pMsg->code = TSDB_CODE_OUT_OF_MEMORY;
|
|
|
|
|
} else {
|
2024-09-29 04:42:08 +00:00
|
|
|
if (tSerializeSEpSet(rsp.pCont, contLen, &newEpSet) < 0) {
|
2024-09-24 02:06:30 +00:00
|
|
|
vError("vgId:%d, failed to serialize ep set", pVnode->config.vgId);
|
|
|
|
|
}
|
2022-12-02 14:24:35 +00:00
|
|
|
rsp.contLen = contLen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tmsgSendRsp(&rsp);
|
2022-07-06 07:15:55 +00:00
|
|
|
}
|
|
|
|
|
|
2022-07-25 09:10:04 +00:00
|
|
|
static void inline vnodeHandleWriteMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
|
|
|
|
SRpcMsg rsp = {.code = pMsg->code, .info = pMsg->info};
|
|
|
|
|
if (vnodeProcessWriteMsg(pVnode, pMsg, pMsg->info.conn.applyIndex, &rsp) < 0) {
|
|
|
|
|
rsp.code = terrno;
|
2025-03-18 08:21:44 +00:00
|
|
|
vGError(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to apply right now since %s", pVnode->config.vgId, pMsg,
|
|
|
|
|
terrstr());
|
2022-07-25 09:10:04 +00:00
|
|
|
}
|
|
|
|
|
if (rsp.info.handle != NULL) {
|
|
|
|
|
tmsgSendRsp(&rsp);
|
2022-08-08 11:17:28 +00:00
|
|
|
} else {
|
|
|
|
|
if (rsp.pCont) {
|
|
|
|
|
rpcFreeCont(rsp.pCont);
|
|
|
|
|
}
|
2022-07-25 09:10:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void vnodeHandleProposeError(SVnode *pVnode, SRpcMsg *pMsg, int32_t code) {
|
2022-12-02 10:59:03 +00:00
|
|
|
if (code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_SYN_RESTORING) {
|
2022-12-02 14:45:11 +00:00
|
|
|
vnodeRedirectRpcMsg(pVnode, pMsg, code);
|
2024-01-23 05:53:51 +00:00
|
|
|
} else if (code == TSDB_CODE_MSG_PREPROCESSED) {
|
|
|
|
|
SRpcMsg rsp = {.code = TSDB_CODE_SUCCESS, .info = pMsg->info};
|
|
|
|
|
if (rsp.info.handle != NULL) {
|
|
|
|
|
tmsgSendRsp(&rsp);
|
|
|
|
|
}
|
2022-07-25 09:10:04 +00:00
|
|
|
} else {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGError(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to propose since %s, code:0x%x", pVnode->config.vgId, pMsg,
|
|
|
|
|
tstrerror(code), code);
|
2022-07-25 09:10:04 +00:00
|
|
|
SRpcMsg rsp = {.code = code, .info = pMsg->info};
|
|
|
|
|
if (rsp.info.handle != NULL) {
|
|
|
|
|
tmsgSendRsp(&rsp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-23 12:16:23 +00:00
|
|
|
static int32_t inline vnodeProposeMsg(SVnode *pVnode, SRpcMsg *pMsg, bool isWeak) {
|
|
|
|
|
int64_t seq = 0;
|
|
|
|
|
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexLock(&pVnode->lock);
|
2022-12-23 12:16:23 +00:00
|
|
|
int32_t code = syncPropose(pVnode->sync, pMsg, isWeak, &seq);
|
|
|
|
|
bool wait = (code == 0 && vnodeIsMsgBlock(pMsg->msgType));
|
|
|
|
|
if (wait) {
|
2024-08-22 09:28:05 +00:00
|
|
|
if (pVnode->blocked) {
|
2025-04-03 05:28:09 +00:00
|
|
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
2024-08-22 09:28:05 +00:00
|
|
|
return TSDB_CODE_INTERNAL_ERROR;
|
|
|
|
|
}
|
2022-12-23 12:16:23 +00:00
|
|
|
pVnode->blocked = true;
|
|
|
|
|
pVnode->blockSec = taosGetTimestampSec();
|
|
|
|
|
pVnode->blockSeq = seq;
|
|
|
|
|
}
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
2022-12-23 12:16:23 +00:00
|
|
|
|
|
|
|
|
if (code > 0) {
|
|
|
|
|
vnodeHandleWriteMsg(pVnode, pMsg);
|
|
|
|
|
} else if (code < 0) {
|
|
|
|
|
if (terrno != 0) code = terrno;
|
|
|
|
|
vnodeHandleProposeError(pVnode, pMsg, code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wait) vnodeWaitBlockMsg(pVnode, pMsg);
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-11 06:16:31 +00:00
|
|
|
void vnodeProposeCommitOnNeed(SVnode *pVnode, bool atExit) {
|
|
|
|
|
if (!vnodeShouldCommit(pVnode, atExit)) {
|
2022-12-23 12:16:23 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t contLen = sizeof(SMsgHead);
|
|
|
|
|
SMsgHead *pHead = rpcMallocCont(contLen);
|
|
|
|
|
pHead->contLen = contLen;
|
|
|
|
|
pHead->vgId = pVnode->config.vgId;
|
|
|
|
|
|
|
|
|
|
SRpcMsg rpcMsg = {0};
|
|
|
|
|
rpcMsg.msgType = TDMT_VND_COMMIT;
|
|
|
|
|
rpcMsg.contLen = contLen;
|
|
|
|
|
rpcMsg.pCont = pHead;
|
|
|
|
|
rpcMsg.info.noResp = 1;
|
|
|
|
|
|
2023-04-11 06:16:31 +00:00
|
|
|
vInfo("vgId:%d, propose vnode commit", pVnode->config.vgId);
|
2022-12-23 12:16:23 +00:00
|
|
|
bool isWeak = false;
|
|
|
|
|
|
2023-04-11 06:16:31 +00:00
|
|
|
if (!atExit) {
|
|
|
|
|
if (vnodeProposeMsg(pVnode, &rpcMsg, isWeak) < 0) {
|
|
|
|
|
vTrace("vgId:%d, failed to propose vnode commit since %s", pVnode->config.vgId, terrstr());
|
|
|
|
|
}
|
|
|
|
|
rpcFreeCont(rpcMsg.pCont);
|
|
|
|
|
rpcMsg.pCont = NULL;
|
|
|
|
|
} else {
|
2025-03-06 06:47:44 +00:00
|
|
|
int32_t code = 0;
|
|
|
|
|
if ((code = tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &rpcMsg)) < 0) {
|
|
|
|
|
vError("vgId:%d, failed to put vnode commit to write_queue since %s", pVnode->config.vgId, tstrerror(code));
|
2024-09-24 02:06:30 +00:00
|
|
|
}
|
2023-04-11 06:16:31 +00:00
|
|
|
}
|
2022-12-23 12:16:23 +00:00
|
|
|
}
|
|
|
|
|
|
2022-12-02 10:59:03 +00:00
|
|
|
#if BATCH_ENABLE
|
|
|
|
|
|
2022-07-25 09:16:26 +00:00
|
|
|
static void inline vnodeProposeBatchMsg(SVnode *pVnode, SRpcMsg **pMsgArr, bool *pIsWeakArr, int32_t *arrSize) {
|
2022-07-25 09:10:04 +00:00
|
|
|
if (*arrSize <= 0) return;
|
2022-12-03 12:53:41 +00:00
|
|
|
SRpcMsg *pLastMsg = pMsgArr[*arrSize - 1];
|
2022-07-25 09:10:04 +00:00
|
|
|
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexLock(&pVnode->lock);
|
2022-07-25 09:10:04 +00:00
|
|
|
int32_t code = syncProposeBatch(pVnode->sync, pMsgArr, pIsWeakArr, *arrSize);
|
2022-12-03 12:53:41 +00:00
|
|
|
bool wait = (code == 0 && vnodeIsBlockMsg(pLastMsg->msgType));
|
|
|
|
|
if (wait) {
|
|
|
|
|
pVnode->blocked = true;
|
|
|
|
|
}
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
2022-12-03 12:53:41 +00:00
|
|
|
|
2022-07-25 09:10:04 +00:00
|
|
|
if (code > 0) {
|
|
|
|
|
for (int32_t i = 0; i < *arrSize; ++i) {
|
2022-07-25 09:16:26 +00:00
|
|
|
vnodeHandleWriteMsg(pVnode, pMsgArr[i]);
|
2022-07-25 09:10:04 +00:00
|
|
|
}
|
2022-12-03 12:53:41 +00:00
|
|
|
} else if (code < 0) {
|
2022-07-25 09:10:04 +00:00
|
|
|
if (terrno != 0) code = terrno;
|
|
|
|
|
for (int32_t i = 0; i < *arrSize; ++i) {
|
2022-07-25 09:16:26 +00:00
|
|
|
vnodeHandleProposeError(pVnode, pMsgArr[i], code);
|
2022-07-25 09:10:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-03 12:53:41 +00:00
|
|
|
if (wait) vnodeWaitBlockMsg(pVnode, pLastMsg);
|
|
|
|
|
pLastMsg = NULL;
|
|
|
|
|
|
2022-07-25 09:10:04 +00:00
|
|
|
for (int32_t i = 0; i < *arrSize; ++i) {
|
2022-07-25 09:16:26 +00:00
|
|
|
SRpcMsg *pMsg = pMsgArr[i];
|
2025-03-18 08:21:44 +00:00
|
|
|
vGTrace(&pMsg->info.traceId, "vgId:%d, msg:%p, is freed, code:0x%x", pVnode->config.vgId, pMsg, code);
|
2022-07-25 09:10:04 +00:00
|
|
|
rpcFreeCont(pMsg->pCont);
|
2022-07-25 09:16:26 +00:00
|
|
|
taosFreeQitem(pMsg);
|
2022-07-25 09:10:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*arrSize = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-06 07:15:55 +00:00
|
|
|
void vnodeProposeWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
2022-07-26 03:24:39 +00:00
|
|
|
SVnode *pVnode = pInfo->ahandle;
|
|
|
|
|
int32_t vgId = pVnode->config.vgId;
|
|
|
|
|
int32_t code = 0;
|
|
|
|
|
SRpcMsg *pMsg = NULL;
|
|
|
|
|
int32_t arrayPos = 0;
|
|
|
|
|
SRpcMsg **pMsgArr = taosMemoryCalloc(numOfMsgs, sizeof(SRpcMsg *));
|
|
|
|
|
bool *pIsWeakArr = taosMemoryCalloc(numOfMsgs, sizeof(bool));
|
2022-07-18 10:37:58 +00:00
|
|
|
vTrace("vgId:%d, get %d msgs from vnode-write queue", vgId, numOfMsgs);
|
|
|
|
|
|
2022-07-25 09:10:04 +00:00
|
|
|
for (int32_t msg = 0; msg < numOfMsgs; msg++) {
|
2022-06-08 06:44:42 +00:00
|
|
|
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
|
2022-07-25 09:10:04 +00:00
|
|
|
bool isWeak = vnodeIsMsgWeak(pMsg->msgType);
|
|
|
|
|
bool isBlock = vnodeIsMsgBlock(pMsg->msgType);
|
|
|
|
|
|
2025-03-18 08:21:44 +00:00
|
|
|
vGDebug(&pMsg->info.traceId, "vgId:%d, msg:%p, get from vnode-write queue, weak:%d block:%d msg:%d:%d pos:%d, handle:%p", vgId, pMsg,
|
2022-07-25 09:10:04 +00:00
|
|
|
isWeak, isBlock, msg, numOfMsgs, arrayPos, pMsg->info.handle);
|
|
|
|
|
|
2022-07-25 11:08:08 +00:00
|
|
|
if (!pVnode->restored) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGWarn(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to process since restore not finished, type:%s", vgId, pMsg,
|
2023-12-28 09:29:49 +00:00
|
|
|
TMSG_INFO(pMsg->msgType));
|
2022-12-02 08:06:10 +00:00
|
|
|
terrno = TSDB_CODE_SYN_RESTORING;
|
|
|
|
|
vnodeHandleProposeError(pVnode, pMsg, TSDB_CODE_SYN_RESTORING);
|
2022-07-25 11:08:08 +00:00
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
taosFreeQitem(pMsg);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-25 09:10:04 +00:00
|
|
|
if (pMsgArr == NULL || pIsWeakArr == NULL) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGError(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to process since out of memory, type:%s", vgId, pMsg, TMSG_INFO(pMsg->msgType));
|
2022-07-25 11:08:08 +00:00
|
|
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
|
|
|
vnodeHandleProposeError(pVnode, pMsg, terrno);
|
2022-07-25 09:10:04 +00:00
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
taosFreeQitem(pMsg);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-06-08 06:44:42 +00:00
|
|
|
|
2023-04-11 06:16:31 +00:00
|
|
|
bool atExit = false;
|
|
|
|
|
vnodeProposeCommitOnNeed(pVnode, atExit);
|
2022-12-23 12:16:23 +00:00
|
|
|
|
2022-07-06 07:15:55 +00:00
|
|
|
code = vnodePreProcessWriteMsg(pVnode, pMsg);
|
2022-07-05 11:22:01 +00:00
|
|
|
if (code != 0) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGError(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to pre-process since %s", vgId, pMsg, terrstr());
|
2022-07-25 09:10:04 +00:00
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
taosFreeQitem(pMsg);
|
|
|
|
|
continue;
|
2022-06-08 06:44:42 +00:00
|
|
|
}
|
|
|
|
|
|
2022-12-02 10:59:03 +00:00
|
|
|
if (isBlock) {
|
2022-07-25 09:10:04 +00:00
|
|
|
vnodeProposeBatchMsg(pVnode, pMsgArr, pIsWeakArr, &arrayPos);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-25 09:16:26 +00:00
|
|
|
pMsgArr[arrayPos] = pMsg;
|
2022-07-25 09:10:04 +00:00
|
|
|
pIsWeakArr[arrayPos] = isWeak;
|
|
|
|
|
arrayPos++;
|
|
|
|
|
|
2022-12-02 10:59:03 +00:00
|
|
|
if (isBlock || msg == numOfMsgs - 1) {
|
2022-07-25 09:10:04 +00:00
|
|
|
vnodeProposeBatchMsg(pVnode, pMsgArr, pIsWeakArr, &arrayPos);
|
2022-06-08 06:44:42 +00:00
|
|
|
}
|
2022-06-01 09:26:25 +00:00
|
|
|
}
|
2022-07-25 09:10:04 +00:00
|
|
|
|
|
|
|
|
taosMemoryFree(pMsgArr);
|
|
|
|
|
taosMemoryFree(pIsWeakArr);
|
2022-06-01 09:26:25 +00:00
|
|
|
}
|
|
|
|
|
|
2022-12-02 10:59:03 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
void vnodeProposeWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
|
|
|
|
SVnode *pVnode = pInfo->ahandle;
|
|
|
|
|
int32_t vgId = pVnode->config.vgId;
|
|
|
|
|
int32_t code = 0;
|
|
|
|
|
SRpcMsg *pMsg = NULL;
|
|
|
|
|
vTrace("vgId:%d, get %d msgs from vnode-write queue", vgId, numOfMsgs);
|
|
|
|
|
|
|
|
|
|
for (int32_t msg = 0; msg < numOfMsgs; msg++) {
|
|
|
|
|
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
|
|
|
|
|
bool isWeak = vnodeIsMsgWeak(pMsg->msgType);
|
|
|
|
|
|
2025-03-18 08:21:44 +00:00
|
|
|
vGDebug(&pMsg->info.traceId, "vgId:%d, msg:%p, get from vnode-write queue, weak:%d block:%d msg:%d:%d, handle:%p",
|
|
|
|
|
vgId, pMsg, isWeak, vnodeIsMsgBlock(pMsg->msgType), msg, numOfMsgs, pMsg->info.handle);
|
2022-12-02 10:59:03 +00:00
|
|
|
|
|
|
|
|
if (!pVnode->restored) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGWarn(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to process since restore not finished, type:%s", vgId, pMsg,
|
2023-12-28 09:29:49 +00:00
|
|
|
TMSG_INFO(pMsg->msgType));
|
2022-12-02 10:59:03 +00:00
|
|
|
vnodeHandleProposeError(pVnode, pMsg, TSDB_CODE_SYN_RESTORING);
|
|
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
taosFreeQitem(pMsg);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-11 06:16:31 +00:00
|
|
|
bool atExit = false;
|
|
|
|
|
vnodeProposeCommitOnNeed(pVnode, atExit);
|
2022-12-23 12:16:23 +00:00
|
|
|
|
2022-12-02 10:59:03 +00:00
|
|
|
code = vnodePreProcessWriteMsg(pVnode, pMsg);
|
|
|
|
|
if (code != 0) {
|
2024-01-23 05:53:51 +00:00
|
|
|
if (code != TSDB_CODE_MSG_PREPROCESSED) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGError(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to pre-process since %s", vgId, pMsg, tstrerror(code));
|
2024-01-23 05:53:51 +00:00
|
|
|
}
|
2022-12-02 10:59:03 +00:00
|
|
|
vnodeHandleProposeError(pVnode, pMsg, code);
|
|
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
taosFreeQitem(pMsg);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
code = vnodeProposeMsg(pVnode, pMsg, isWeak);
|
|
|
|
|
|
2025-03-18 08:21:44 +00:00
|
|
|
vGTrace(&pMsg->info.traceId, "vgId:%d, msg:%p, is freed, code:0x%x", vgId, pMsg, code);
|
2022-12-02 10:59:03 +00:00
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
taosFreeQitem(pMsg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-07-06 07:15:55 +00:00
|
|
|
void vnodeApplyWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
2022-07-01 06:47:12 +00:00
|
|
|
SVnode *pVnode = pInfo->ahandle;
|
2022-06-08 06:44:42 +00:00
|
|
|
int32_t vgId = pVnode->config.vgId;
|
|
|
|
|
int32_t code = 0;
|
|
|
|
|
SRpcMsg *pMsg = NULL;
|
|
|
|
|
|
|
|
|
|
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
|
|
|
|
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
|
|
|
|
|
|
2022-12-03 12:53:41 +00:00
|
|
|
if (vnodeIsMsgBlock(pMsg->msgType)) {
|
2025-03-19 13:44:39 +00:00
|
|
|
vGDebug(&pMsg->info.traceId, "vgId:%d, msg:%p, get from vnode-apply queue, type:%s handle:%p index:%" PRId64
|
2022-12-14 08:09:28 +00:00
|
|
|
", blocking msg obtained sec:%d seq:%" PRId64,
|
|
|
|
|
vgId, pMsg, TMSG_INFO(pMsg->msgType), pMsg->info.handle, pMsg->info.conn.applyIndex, pVnode->blockSec,
|
|
|
|
|
pVnode->blockSeq);
|
|
|
|
|
} else {
|
2025-03-19 13:44:39 +00:00
|
|
|
vGDebug(&pMsg->info.traceId, "vgId:%d, msg:%p, get from vnode-apply queue, type:%s handle:%p index:%" PRId64, vgId, pMsg,
|
2022-12-14 08:09:28 +00:00
|
|
|
TMSG_INFO(pMsg->msgType), pMsg->info.handle, pMsg->info.conn.applyIndex);
|
2022-12-03 12:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
2022-06-08 13:17:17 +00:00
|
|
|
SRpcMsg rsp = {.code = pMsg->code, .info = pMsg->info};
|
|
|
|
|
if (rsp.code == 0) {
|
2025-07-03 01:15:59 +00:00
|
|
|
int32_t ret = 0;
|
|
|
|
|
int32_t count = 0;
|
|
|
|
|
while (1) {
|
|
|
|
|
ret = vnodeProcessWriteMsg(pVnode, pMsg, pMsg->info.conn.applyIndex, &rsp);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
rsp.code = ret;
|
|
|
|
|
vGError(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to apply since %s, index:%" PRId64, vgId, pMsg,
|
|
|
|
|
tstrerror(ret), pMsg->info.conn.applyIndex);
|
|
|
|
|
}
|
|
|
|
|
if (ret == TSDB_CODE_VND_WRITE_DISABLED) {
|
|
|
|
|
if (count % 100 == 0)
|
|
|
|
|
vGError(&pMsg->info.traceId,
|
|
|
|
|
"vgId:%d, msg:%p, failed to apply since %s, retry after 200ms, retry count:%d index:%" PRId64, vgId,
|
|
|
|
|
pMsg, tstrerror(ret), count, pMsg->info.conn.applyIndex);
|
|
|
|
|
count++;
|
|
|
|
|
taosMsleep(200); // wait for a while before retrying
|
|
|
|
|
} else{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-06-08 13:17:17 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-08 06:44:42 +00:00
|
|
|
|
2022-07-18 10:37:58 +00:00
|
|
|
vnodePostBlockMsg(pVnode, pMsg);
|
2022-06-08 13:17:17 +00:00
|
|
|
if (rsp.info.handle != NULL) {
|
2022-06-08 06:44:42 +00:00
|
|
|
tmsgSendRsp(&rsp);
|
2022-08-08 10:20:41 +00:00
|
|
|
} else {
|
|
|
|
|
if (rsp.pCont) {
|
|
|
|
|
rpcFreeCont(rsp.pCont);
|
|
|
|
|
}
|
2022-06-08 06:44:42 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-18 08:21:44 +00:00
|
|
|
vGTrace(&pMsg->info.traceId, "vgId:%d, msg:%p, is freed, code:0x%x index:%" PRId64, vgId, pMsg, rsp.code,
|
|
|
|
|
pMsg->info.conn.applyIndex);
|
2022-06-08 06:44:42 +00:00
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
taosFreeQitem(pMsg);
|
2022-06-01 09:26:25 +00:00
|
|
|
}
|
2022-04-19 07:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
2022-07-05 11:22:01 +00:00
|
|
|
int32_t vnodeProcessSyncMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGDebug(&pMsg->info.traceId, "vgId:%d, msg:%p, get from vnode-sync queue, type:%s", pVnode->config.vgId, pMsg, TMSG_INFO(pMsg->msgType));
|
2022-10-18 11:12:34 +00:00
|
|
|
|
2022-11-01 03:45:58 +00:00
|
|
|
int32_t code = syncProcessMsg(pVnode->sync, pMsg);
|
|
|
|
|
if (code != 0) {
|
2025-03-18 08:21:44 +00:00
|
|
|
vGError(&pMsg->info.traceId, "vgId:%d, msg:%p, failed to process since %s, type:%s", pVnode->config.vgId, pMsg, tstrerror(code),
|
|
|
|
|
TMSG_INFO(pMsg->msgType));
|
2022-10-18 11:12:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-13 06:37:18 +00:00
|
|
|
static int32_t vnodeSyncEqCtrlMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
2022-11-04 09:38:35 +00:00
|
|
|
if (pMsg == NULL || pMsg->pCont == NULL) {
|
2024-08-14 09:50:20 +00:00
|
|
|
return TSDB_CODE_INVALID_PARA;
|
2022-07-05 13:42:07 +00:00
|
|
|
}
|
2022-06-16 07:20:46 +00:00
|
|
|
|
2022-11-04 09:38:35 +00:00
|
|
|
if (msgcb == NULL || msgcb->putToQueueFp == NULL) {
|
|
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
pMsg->pCont = NULL;
|
2024-07-22 11:40:07 +00:00
|
|
|
return TSDB_CODE_INVALID_PARA;
|
2022-10-13 06:37:18 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-14 12:35:39 +00:00
|
|
|
int32_t code = tmsgPutToQueue(msgcb, SYNC_RD_QUEUE, pMsg);
|
2022-10-13 06:37:18 +00:00
|
|
|
if (code != 0) {
|
|
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
pMsg->pCont = NULL;
|
|
|
|
|
}
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-08 06:44:42 +00:00
|
|
|
static int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
2022-11-04 09:38:35 +00:00
|
|
|
if (pMsg == NULL || pMsg->pCont == NULL) {
|
2024-07-22 11:40:07 +00:00
|
|
|
return TSDB_CODE_INVALID_PARA;
|
2022-11-04 09:38:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msgcb == NULL || msgcb->putToQueueFp == NULL) {
|
|
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
pMsg->pCont = NULL;
|
2024-07-22 11:40:07 +00:00
|
|
|
return TSDB_CODE_INVALID_PARA;
|
2022-10-12 07:35:15 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-23 14:08:14 +00:00
|
|
|
int32_t code = tmsgPutToQueue(msgcb, SYNC_QUEUE, pMsg);
|
|
|
|
|
if (code != 0) {
|
|
|
|
|
rpcFreeCont(pMsg->pCont);
|
2022-06-01 09:26:25 +00:00
|
|
|
pMsg->pCont = NULL;
|
2022-05-23 14:08:14 +00:00
|
|
|
}
|
|
|
|
|
return code;
|
|
|
|
|
}
|
2022-04-19 07:43:24 +00:00
|
|
|
|
2022-06-08 06:44:42 +00:00
|
|
|
static int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
2024-01-10 09:57:08 +00:00
|
|
|
int32_t code = tmsgSendSyncReq(pEpSet, pMsg);
|
2022-06-01 09:26:25 +00:00
|
|
|
if (code != 0) {
|
|
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
pMsg->pCont = NULL;
|
|
|
|
|
}
|
|
|
|
|
return code;
|
|
|
|
|
}
|
2022-04-20 11:58:36 +00:00
|
|
|
|
2023-09-11 11:05:40 +00:00
|
|
|
static int32_t vnodeSyncGetSnapshotInfo(const SSyncFSM *pFsm, SSnapshot *pSnapshot) {
|
|
|
|
|
return vnodeGetSnapshot(pFsm->data, pSnapshot);
|
2022-04-19 07:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
2022-12-03 00:51:58 +00:00
|
|
|
static int32_t vnodeSyncApplyMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta *pMeta) {
|
2022-11-01 07:15:58 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2022-11-26 13:53:38 +00:00
|
|
|
pMsg->info.conn.applyIndex = pMeta->index;
|
|
|
|
|
pMsg->info.conn.applyTerm = pMeta->term;
|
2022-07-28 02:49:36 +00:00
|
|
|
|
2025-03-19 13:44:39 +00:00
|
|
|
vGDebug(&pMsg->info.traceId,
|
|
|
|
|
"vgId:%d, index:%" PRId64 ", execute commit cb, fsm:%p, term:%" PRIu64 ", msg-index:%" PRId64
|
2022-12-26 12:40:33 +00:00
|
|
|
", weak:%d, code:%d, state:%d %s, type:%s code:0x%x",
|
2025-03-19 13:44:39 +00:00
|
|
|
pVnode->config.vgId, pMeta->index, pFsm, pMeta->term, pMsg->info.conn.applyIndex, pMeta->isWeak, pMeta->code,
|
2022-12-26 12:40:33 +00:00
|
|
|
pMeta->state, syncStr(pMeta->state), TMSG_INFO(pMsg->msgType), pMsg->code);
|
2022-07-28 02:49:36 +00:00
|
|
|
|
2025-03-06 06:47:44 +00:00
|
|
|
int32_t code = tmsgPutToQueue(&pVnode->msgCb, APPLY_QUEUE, pMsg);
|
2025-04-16 07:59:03 +00:00
|
|
|
if (code < 0) {
|
|
|
|
|
if (code == TSDB_CODE_OUT_OF_RPC_MEMORY_QUEUE) {
|
|
|
|
|
pVnode->applyQueueErrorCount++;
|
|
|
|
|
if (pVnode->applyQueueErrorCount == APPLY_QUEUE_ERROR_THRESHOLD) {
|
|
|
|
|
pVnode->applyQueueErrorCount = 0;
|
|
|
|
|
vWarn("vgId:%d, failed to put into apply_queue since %s", pVnode->config.vgId, tstrerror(code));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
vError("vgId:%d, failed to put into apply_queue since %s", pVnode->config.vgId, tstrerror(code));
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-06 06:47:44 +00:00
|
|
|
return code;
|
2023-03-10 10:10:25 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-31 02:53:36 +00:00
|
|
|
static int32_t vnodeSyncCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
2023-03-09 08:18:44 +00:00
|
|
|
if (pMsg->code == 0) {
|
2023-03-10 10:10:25 +00:00
|
|
|
return vnodeSyncApplyMsg(pFsm, pMsg, pMeta);
|
2023-03-09 08:18:44 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-18 08:21:44 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2023-03-09 08:18:44 +00:00
|
|
|
vnodePostBlockMsg(pVnode, pMsg);
|
2023-03-10 10:10:25 +00:00
|
|
|
|
2025-03-19 13:44:39 +00:00
|
|
|
SRpcMsg rsp = {
|
|
|
|
|
.code = pMsg->code,
|
|
|
|
|
.info = pMsg->info,
|
|
|
|
|
};
|
|
|
|
|
|
2023-03-09 08:18:44 +00:00
|
|
|
if (rsp.info.handle != NULL) {
|
|
|
|
|
tmsgSendRsp(&rsp);
|
|
|
|
|
}
|
2023-03-10 10:10:25 +00:00
|
|
|
|
2025-03-18 08:21:44 +00:00
|
|
|
vGTrace(&pMsg->info.traceId, "vgId:%d, msg:%p, is freed, code:0x%x index:%" PRId64, TD_VID(pVnode), pMsg, rsp.code,
|
|
|
|
|
pMeta->index);
|
2023-03-09 08:18:44 +00:00
|
|
|
rpcFreeCont(pMsg->pCont);
|
|
|
|
|
pMsg->pCont = NULL;
|
|
|
|
|
return 0;
|
2022-04-19 07:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-31 02:53:36 +00:00
|
|
|
static int32_t vnodeSyncPreCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
2022-11-01 07:15:58 +00:00
|
|
|
if (pMeta->isWeak == 1) {
|
2022-12-03 00:51:58 +00:00
|
|
|
return vnodeSyncApplyMsg(pFsm, pMsg, pMeta);
|
2022-07-26 03:24:39 +00:00
|
|
|
}
|
2022-12-03 00:51:58 +00:00
|
|
|
return 0;
|
2022-04-19 07:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-09 10:12:40 +00:00
|
|
|
static SyncIndex vnodeSyncAppliedIndex(const SSyncFSM *pFSM) {
|
|
|
|
|
SVnode *pVnode = pFSM->data;
|
|
|
|
|
return atomic_load_64(&pVnode->state.applied);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 02:53:36 +00:00
|
|
|
static void vnodeSyncRollBackMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
2022-07-06 08:27:58 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2025-03-19 13:44:39 +00:00
|
|
|
vGDebug(&pMsg->info.traceId,
|
|
|
|
|
"vgId:%d, rollback-cb is excuted, fsm:%p, index:%" PRId64 ", weak:%d, code:%d, state:%d %s, type:%s",
|
|
|
|
|
pVnode->config.vgId, pFsm, pMeta->index, pMeta->isWeak, pMeta->code, pMeta->state, syncStr(pMeta->state),
|
|
|
|
|
TMSG_INFO(pMsg->msgType));
|
2022-04-19 07:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-01 07:15:58 +00:00
|
|
|
static int32_t vnodeSnapshotStartRead(const SSyncFSM *pFsm, void *pParam, void **ppReader) {
|
2024-01-10 09:57:08 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2024-07-22 11:40:07 +00:00
|
|
|
return vnodeSnapReaderOpen(pVnode, (SSnapshotParam *)pParam, (SVSnapReader **)ppReader);
|
2022-07-06 07:47:24 +00:00
|
|
|
}
|
2022-06-14 12:40:27 +00:00
|
|
|
|
2022-12-20 07:07:27 +00:00
|
|
|
static void vnodeSnapshotStopRead(const SSyncFSM *pFsm, void *pReader) {
|
2022-07-06 07:47:24 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2022-12-20 07:07:27 +00:00
|
|
|
vnodeSnapReaderClose(pReader);
|
2022-07-06 07:47:24 +00:00
|
|
|
}
|
2022-06-14 12:40:27 +00:00
|
|
|
|
2022-11-01 07:15:58 +00:00
|
|
|
static int32_t vnodeSnapshotDoRead(const SSyncFSM *pFsm, void *pReader, void **ppBuf, int32_t *len) {
|
2022-07-06 07:47:24 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2024-07-22 11:40:07 +00:00
|
|
|
return vnodeSnapRead(pReader, (uint8_t **)ppBuf, len);
|
2022-07-06 07:47:24 +00:00
|
|
|
}
|
2022-06-14 12:40:27 +00:00
|
|
|
|
2022-11-01 07:15:58 +00:00
|
|
|
static int32_t vnodeSnapshotStartWrite(const SSyncFSM *pFsm, void *pParam, void **ppWriter) {
|
2023-09-15 11:58:48 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2022-08-01 11:40:38 +00:00
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
int32_t itemSize = tmsgGetQueueSize(&pVnode->msgCb, pVnode->config.vgId, APPLY_QUEUE);
|
2022-10-22 00:47:09 +00:00
|
|
|
if (itemSize == 0) {
|
2022-08-03 02:56:37 +00:00
|
|
|
vInfo("vgId:%d, start write vnode snapshot since apply queue is empty", pVnode->config.vgId);
|
2022-08-01 11:40:38 +00:00
|
|
|
break;
|
|
|
|
|
} else {
|
2022-09-30 06:03:46 +00:00
|
|
|
vInfo("vgId:%d, write vnode snapshot later since %d items in apply queue", pVnode->config.vgId, itemSize);
|
2022-08-01 11:40:38 +00:00
|
|
|
taosMsleep(10);
|
|
|
|
|
}
|
|
|
|
|
} while (true);
|
|
|
|
|
|
2024-07-22 11:40:07 +00:00
|
|
|
return vnodeSnapWriterOpen(pVnode, (SSnapshotParam *)pParam, (SVSnapWriter **)ppWriter);
|
2022-07-10 03:33:28 +00:00
|
|
|
}
|
2022-06-14 12:40:27 +00:00
|
|
|
|
2022-11-01 07:15:58 +00:00
|
|
|
static int32_t vnodeSnapshotStopWrite(const SSyncFSM *pFsm, void *pWriter, bool isApply, SSnapshot *pSnapshot) {
|
2022-07-10 03:33:28 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2022-08-04 12:36:12 +00:00
|
|
|
vInfo("vgId:%d, stop write vnode snapshot, apply:%d, index:%" PRId64 " term:%" PRIu64 " config:%" PRId64,
|
2022-08-04 12:44:10 +00:00
|
|
|
pVnode->config.vgId, isApply, pSnapshot->lastApplyIndex, pSnapshot->lastApplyTerm, pSnapshot->lastConfigIndex);
|
2022-08-01 11:40:38 +00:00
|
|
|
|
2022-07-16 10:19:54 +00:00
|
|
|
int32_t code = vnodeSnapWriterClose(pWriter, !isApply, pSnapshot);
|
2023-10-27 07:21:55 +00:00
|
|
|
if (code != 0) {
|
|
|
|
|
vError("vgId:%d, failed to finish applying vnode snapshot since %s, code:0x%x", pVnode->config.vgId, terrstr(),
|
|
|
|
|
code);
|
|
|
|
|
}
|
2022-07-10 03:33:28 +00:00
|
|
|
return code;
|
|
|
|
|
}
|
2022-06-14 12:40:27 +00:00
|
|
|
|
2022-11-01 07:15:58 +00:00
|
|
|
static int32_t vnodeSnapshotDoWrite(const SSyncFSM *pFsm, void *pWriter, void *pBuf, int32_t len) {
|
2022-07-10 03:33:28 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2022-12-22 09:30:02 +00:00
|
|
|
vDebug("vgId:%d, continue write vnode snapshot, blockLen:%d", pVnode->config.vgId, len);
|
2022-07-10 03:33:28 +00:00
|
|
|
int32_t code = vnodeSnapWrite(pWriter, pBuf, len);
|
2022-12-22 09:30:02 +00:00
|
|
|
vDebug("vgId:%d, continue write vnode snapshot finished, blockLen:%d", pVnode->config.vgId, len);
|
2022-07-10 03:33:28 +00:00
|
|
|
return code;
|
|
|
|
|
}
|
2022-06-14 12:40:27 +00:00
|
|
|
|
2023-03-09 11:29:09 +00:00
|
|
|
static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
|
2023-06-28 09:57:08 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2023-08-16 07:24:24 +00:00
|
|
|
int32_t vgId = pVnode->config.vgId;
|
2023-03-09 11:29:09 +00:00
|
|
|
SyncIndex appliedIdx = -1;
|
2022-09-20 10:50:23 +00:00
|
|
|
|
|
|
|
|
do {
|
2023-03-09 11:29:09 +00:00
|
|
|
appliedIdx = vnodeSyncAppliedIndex(pFsm);
|
2024-08-22 09:28:05 +00:00
|
|
|
if (appliedIdx > commitIdx) {
|
|
|
|
|
vError("vgId:%d, restore failed since applied-index:%" PRId64 " is larger than commit-index:%" PRId64, vgId,
|
|
|
|
|
appliedIdx, commitIdx);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-03-09 11:29:09 +00:00
|
|
|
if (appliedIdx == commitIdx) {
|
2023-03-09 12:00:25 +00:00
|
|
|
vInfo("vgId:%d, no items to be applied, restore finish", pVnode->config.vgId);
|
2022-09-20 10:50:23 +00:00
|
|
|
break;
|
|
|
|
|
} else {
|
2025-05-09 01:16:49 +00:00
|
|
|
if (appliedIdx % 10 == 0) {
|
|
|
|
|
vInfo("vgId:%d, restore not finish since %" PRId64 " items to be applied. commit-index:%" PRId64
|
|
|
|
|
", applied-index:%" PRId64,
|
|
|
|
|
vgId, commitIdx - appliedIdx, commitIdx, appliedIdx);
|
|
|
|
|
} else {
|
|
|
|
|
vDebug("vgId:%d, restore not finish since %" PRId64 " items to be applied. commit-index:%" PRId64
|
|
|
|
|
", applied-index:%" PRId64,
|
|
|
|
|
vgId, commitIdx - appliedIdx, commitIdx, appliedIdx);
|
|
|
|
|
}
|
2022-09-20 10:50:23 +00:00
|
|
|
taosMsleep(10);
|
|
|
|
|
}
|
|
|
|
|
} while (true);
|
|
|
|
|
|
2024-09-24 02:06:30 +00:00
|
|
|
walApplyVer(pVnode->pWal, commitIdx);
|
2022-07-25 11:08:08 +00:00
|
|
|
pVnode->restored = true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-01 07:15:58 +00:00
|
|
|
static void vnodeBecomeFollower(const SSyncFSM *pFsm) {
|
2022-08-10 09:17:30 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2022-11-24 08:03:43 +00:00
|
|
|
vInfo("vgId:%d, become follower", pVnode->config.vgId);
|
2022-08-10 09:17:30 +00:00
|
|
|
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexLock(&pVnode->lock);
|
2022-08-12 08:32:11 +00:00
|
|
|
if (pVnode->blocked) {
|
|
|
|
|
pVnode->blocked = false;
|
2022-08-12 11:20:31 +00:00
|
|
|
vDebug("vgId:%d, become follower and post block", pVnode->config.vgId);
|
2024-09-24 08:48:07 +00:00
|
|
|
if (tsem_post(&pVnode->syncSem) != 0) {
|
|
|
|
|
vError("vgId:%d, failed to post sync semaphore", pVnode->config.vgId);
|
|
|
|
|
}
|
2022-08-12 08:32:11 +00:00
|
|
|
}
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
2023-08-30 09:24:13 +00:00
|
|
|
|
2025-04-17 02:45:06 +00:00
|
|
|
streamRemoveVnodeLeader(pVnode->config.vgId);
|
2022-08-10 09:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
2023-04-18 11:03:45 +00:00
|
|
|
static void vnodeBecomeLearner(const SSyncFSM *pFsm) {
|
|
|
|
|
SVnode *pVnode = pFsm->data;
|
|
|
|
|
vInfo("vgId:%d, become learner", pVnode->config.vgId);
|
|
|
|
|
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexLock(&pVnode->lock);
|
2023-04-18 11:03:45 +00:00
|
|
|
if (pVnode->blocked) {
|
|
|
|
|
pVnode->blocked = false;
|
|
|
|
|
vDebug("vgId:%d, become learner and post block", pVnode->config.vgId);
|
2024-09-24 08:48:07 +00:00
|
|
|
if (tsem_post(&pVnode->syncSem) != 0) {
|
|
|
|
|
vError("vgId:%d, failed to post sync semaphore", pVnode->config.vgId);
|
|
|
|
|
}
|
2023-04-18 11:03:45 +00:00
|
|
|
}
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
2025-04-17 02:45:06 +00:00
|
|
|
|
|
|
|
|
streamRemoveVnodeLeader(pVnode->config.vgId);
|
2023-04-18 11:03:45 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-01 07:15:58 +00:00
|
|
|
static void vnodeBecomeLeader(const SSyncFSM *pFsm) {
|
2022-08-10 09:17:30 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
2023-09-21 07:53:21 +00:00
|
|
|
vDebug("vgId:%d, become leader", pVnode->config.vgId);
|
2025-04-17 02:45:06 +00:00
|
|
|
|
|
|
|
|
streamAddVnodeLeader(pVnode->config.vgId);
|
2022-08-10 09:17:30 +00:00
|
|
|
}
|
2022-08-12 10:49:28 +00:00
|
|
|
|
2024-07-22 11:40:07 +00:00
|
|
|
static void vnodeBecomeAssignedLeader(const SSyncFSM *pFsm) {
|
2024-03-15 01:14:54 +00:00
|
|
|
SVnode *pVnode = pFsm->data;
|
|
|
|
|
vDebug("vgId:%d, become assigned leader", pVnode->config.vgId);
|
2025-04-17 02:45:06 +00:00
|
|
|
|
|
|
|
|
streamAddVnodeLeader(pVnode->config.vgId);
|
2024-03-15 01:14:54 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-07 08:40:53 +00:00
|
|
|
static bool vnodeApplyQueueEmpty(const SSyncFSM *pFsm) {
|
|
|
|
|
SVnode *pVnode = pFsm->data;
|
2022-11-09 08:18:28 +00:00
|
|
|
|
|
|
|
|
if (pVnode != NULL && pVnode->msgCb.qsizeFp != NULL) {
|
|
|
|
|
int32_t itemSize = tmsgGetQueueSize(&pVnode->msgCb, pVnode->config.vgId, APPLY_QUEUE);
|
|
|
|
|
return (itemSize == 0);
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t vnodeApplyQueueItems(const SSyncFSM *pFsm) {
|
|
|
|
|
SVnode *pVnode = pFsm->data;
|
|
|
|
|
|
|
|
|
|
if (pVnode != NULL && pVnode->msgCb.qsizeFp != NULL) {
|
|
|
|
|
int32_t itemSize = tmsgGetQueueSize(&pVnode->msgCb, pVnode->config.vgId, APPLY_QUEUE);
|
|
|
|
|
return itemSize;
|
|
|
|
|
} else {
|
2024-07-22 11:40:07 +00:00
|
|
|
return TSDB_CODE_INVALID_PARA;
|
2022-11-09 08:18:28 +00:00
|
|
|
}
|
2022-08-10 09:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
2022-06-08 06:44:42 +00:00
|
|
|
static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
|
2022-05-20 02:51:53 +00:00
|
|
|
SSyncFSM *pFsm = taosMemoryCalloc(1, sizeof(SSyncFSM));
|
2024-07-22 11:40:07 +00:00
|
|
|
if (pFsm == NULL) {
|
|
|
|
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2022-04-19 07:43:24 +00:00
|
|
|
pFsm->data = pVnode;
|
2022-05-20 02:51:53 +00:00
|
|
|
pFsm->FpCommitCb = vnodeSyncCommitMsg;
|
2023-03-09 10:12:40 +00:00
|
|
|
pFsm->FpAppliedIndexCb = vnodeSyncAppliedIndex;
|
2022-05-20 02:51:53 +00:00
|
|
|
pFsm->FpPreCommitCb = vnodeSyncPreCommitMsg;
|
|
|
|
|
pFsm->FpRollBackCb = vnodeSyncRollBackMsg;
|
2023-09-11 11:05:40 +00:00
|
|
|
pFsm->FpGetSnapshot = NULL;
|
2022-12-20 06:57:04 +00:00
|
|
|
pFsm->FpGetSnapshotInfo = vnodeSyncGetSnapshotInfo;
|
2022-07-25 11:08:08 +00:00
|
|
|
pFsm->FpRestoreFinishCb = vnodeRestoreFinish;
|
2025-01-07 07:26:01 +00:00
|
|
|
pFsm->FpAfterRestoredCb = NULL;
|
2022-11-01 07:15:58 +00:00
|
|
|
pFsm->FpLeaderTransferCb = NULL;
|
2022-11-07 08:40:53 +00:00
|
|
|
pFsm->FpApplyQueueEmptyCb = vnodeApplyQueueEmpty;
|
2022-11-09 08:18:28 +00:00
|
|
|
pFsm->FpApplyQueueItems = vnodeApplyQueueItems;
|
2022-08-10 09:17:30 +00:00
|
|
|
pFsm->FpBecomeLeaderCb = vnodeBecomeLeader;
|
2024-03-15 01:14:54 +00:00
|
|
|
pFsm->FpBecomeAssignedLeaderCb = vnodeBecomeAssignedLeader;
|
2022-08-10 09:17:30 +00:00
|
|
|
pFsm->FpBecomeFollowerCb = vnodeBecomeFollower;
|
2023-04-18 11:03:45 +00:00
|
|
|
pFsm->FpBecomeLearnerCb = vnodeBecomeLearner;
|
2022-11-01 07:15:58 +00:00
|
|
|
pFsm->FpReConfigCb = NULL;
|
2022-06-14 12:40:27 +00:00
|
|
|
pFsm->FpSnapshotStartRead = vnodeSnapshotStartRead;
|
|
|
|
|
pFsm->FpSnapshotStopRead = vnodeSnapshotStopRead;
|
|
|
|
|
pFsm->FpSnapshotDoRead = vnodeSnapshotDoRead;
|
|
|
|
|
pFsm->FpSnapshotStartWrite = vnodeSnapshotStartWrite;
|
|
|
|
|
pFsm->FpSnapshotStopWrite = vnodeSnapshotStopWrite;
|
|
|
|
|
pFsm->FpSnapshotDoWrite = vnodeSnapshotDoWrite;
|
|
|
|
|
|
2022-04-19 07:43:24 +00:00
|
|
|
return pFsm;
|
2022-06-08 06:44:42 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-21 02:31:53 +00:00
|
|
|
int32_t vnodeSyncOpen(SVnode *pVnode, char *path, int32_t vnodeVersion) {
|
2022-06-08 06:44:42 +00:00
|
|
|
SSyncInfo syncInfo = {
|
2022-07-10 11:10:06 +00:00
|
|
|
.snapshotStrategy = SYNC_STRATEGY_WAL_FIRST,
|
2022-08-01 12:26:45 +00:00
|
|
|
.batchSize = 1,
|
2022-06-08 06:44:42 +00:00
|
|
|
.vgId = pVnode->config.vgId,
|
|
|
|
|
.syncCfg = pVnode->config.syncCfg,
|
|
|
|
|
.pWal = pVnode->pWal,
|
2022-11-01 10:34:09 +00:00
|
|
|
.msgcb = &pVnode->msgCb,
|
2022-11-01 07:40:23 +00:00
|
|
|
.syncSendMSg = vnodeSyncSendMsg,
|
|
|
|
|
.syncEqMsg = vnodeSyncEqMsg,
|
|
|
|
|
.syncEqCtrlMsg = vnodeSyncEqCtrlMsg,
|
|
|
|
|
.pingMs = 5000,
|
|
|
|
|
.electMs = 4000,
|
|
|
|
|
.heartbeatMs = 700,
|
2022-06-08 06:44:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
snprintf(syncInfo.path, sizeof(syncInfo.path), "%s%ssync", path, TD_DIRSEP);
|
|
|
|
|
syncInfo.pFsm = vnodeSyncMakeFsm(pVnode);
|
|
|
|
|
|
2022-10-24 03:57:26 +00:00
|
|
|
SSyncCfg *pCfg = &syncInfo.syncCfg;
|
|
|
|
|
vInfo("vgId:%d, start to open sync, replica:%d selfIndex:%d", pVnode->config.vgId, pCfg->replicaNum, pCfg->myIndex);
|
2023-04-18 11:03:45 +00:00
|
|
|
for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) {
|
2022-10-24 03:57:26 +00:00
|
|
|
SNodeInfo *pNode = &pCfg->nodeInfo[i];
|
2023-06-28 09:57:08 +00:00
|
|
|
vInfo("vgId:%d, index:%d ep:%s:%u dnode:%d cluster:%" PRId64, pVnode->config.vgId, i, pNode->nodeFqdn,
|
|
|
|
|
pNode->nodePort, pNode->nodeId, pNode->clusterId);
|
2022-10-24 03:57:26 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-21 02:31:53 +00:00
|
|
|
pVnode->sync = syncOpen(&syncInfo, vnodeVersion);
|
2022-06-08 06:44:42 +00:00
|
|
|
if (pVnode->sync <= 0) {
|
|
|
|
|
vError("vgId:%d, failed to open sync since %s", pVnode->config.vgId, terrstr());
|
2024-07-22 11:40:07 +00:00
|
|
|
return terrno;
|
2022-06-08 06:44:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-31 04:59:42 +00:00
|
|
|
int32_t vnodeSyncStart(SVnode *pVnode) {
|
2022-11-04 08:15:37 +00:00
|
|
|
vInfo("vgId:%d, start sync", pVnode->config.vgId);
|
2024-07-22 11:40:07 +00:00
|
|
|
int32_t code = syncStart(pVnode->sync);
|
|
|
|
|
if (code) {
|
|
|
|
|
vError("vgId:%d, failed to start sync subsystem since %s", pVnode->config.vgId, tstrerror(code));
|
|
|
|
|
return code;
|
2022-10-31 04:59:42 +00:00
|
|
|
}
|
|
|
|
|
return 0;
|
2022-06-08 06:44:42 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-04 08:15:37 +00:00
|
|
|
void vnodeSyncPreClose(SVnode *pVnode) {
|
2023-02-03 06:40:12 +00:00
|
|
|
vInfo("vgId:%d, sync pre close", pVnode->config.vgId);
|
2024-09-24 02:06:30 +00:00
|
|
|
int32_t code = syncLeaderTransfer(pVnode->sync);
|
|
|
|
|
if (code) {
|
|
|
|
|
vError("vgId:%d, failed to transfer leader since %s", pVnode->config.vgId, tstrerror(code));
|
|
|
|
|
}
|
2022-11-04 08:15:37 +00:00
|
|
|
syncPreStop(pVnode->sync);
|
2022-12-05 10:50:19 +00:00
|
|
|
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexLock(&pVnode->lock);
|
2022-11-04 08:15:37 +00:00
|
|
|
if (pVnode->blocked) {
|
|
|
|
|
vInfo("vgId:%d, post block after close sync", pVnode->config.vgId);
|
|
|
|
|
pVnode->blocked = false;
|
2024-09-24 08:48:07 +00:00
|
|
|
if (tsem_post(&pVnode->syncSem) != 0) {
|
|
|
|
|
vError("vgId:%d, failed to post block", pVnode->config.vgId);
|
|
|
|
|
}
|
2022-11-04 08:15:37 +00:00
|
|
|
}
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
2022-11-04 08:15:37 +00:00
|
|
|
}
|
|
|
|
|
|
2023-01-05 04:00:27 +00:00
|
|
|
void vnodeSyncPostClose(SVnode *pVnode) {
|
2023-02-03 06:40:12 +00:00
|
|
|
vInfo("vgId:%d, sync post close", pVnode->config.vgId);
|
2023-01-05 04:00:27 +00:00
|
|
|
syncPostStop(pVnode->sync);
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-24 03:57:26 +00:00
|
|
|
void vnodeSyncClose(SVnode *pVnode) {
|
2022-11-04 08:15:37 +00:00
|
|
|
vInfo("vgId:%d, close sync", pVnode->config.vgId);
|
2022-10-24 03:57:26 +00:00
|
|
|
syncStop(pVnode->sync);
|
|
|
|
|
}
|
2022-07-06 07:15:55 +00:00
|
|
|
|
2022-12-14 01:14:40 +00:00
|
|
|
void vnodeSyncCheckTimeout(SVnode *pVnode) {
|
|
|
|
|
vTrace("vgId:%d, check sync timeout msg", pVnode->config.vgId);
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexLock(&pVnode->lock);
|
2022-12-14 01:14:40 +00:00
|
|
|
if (pVnode->blocked) {
|
|
|
|
|
int32_t curSec = taosGetTimestampSec();
|
|
|
|
|
int32_t delta = curSec - pVnode->blockSec;
|
|
|
|
|
if (delta > VNODE_TIMEOUT_SEC) {
|
|
|
|
|
vError("vgId:%d, failed to propose since timeout and post block, start:%d cur:%d delta:%d seq:%" PRId64,
|
|
|
|
|
pVnode->config.vgId, pVnode->blockSec, curSec, delta, pVnode->blockSeq);
|
2022-12-14 08:09:28 +00:00
|
|
|
if (syncSendTimeoutRsp(pVnode->sync, pVnode->blockSeq) != 0) {
|
2024-01-23 05:53:51 +00:00
|
|
|
#if 0
|
2022-12-14 08:09:28 +00:00
|
|
|
SRpcMsg rpcMsg = {.code = TSDB_CODE_SYN_TIMEOUT, .info = pVnode->blockInfo};
|
2022-12-14 11:01:31 +00:00
|
|
|
vError("send timeout response since its applyed, seq:%" PRId64 " handle:%p ahandle:%p", pVnode->blockSeq,
|
2022-12-14 08:09:28 +00:00
|
|
|
rpcMsg.info.handle, rpcMsg.info.ahandle);
|
|
|
|
|
rpcSendResponse(&rpcMsg);
|
2022-12-14 11:01:31 +00:00
|
|
|
#endif
|
2022-12-14 08:09:28 +00:00
|
|
|
}
|
2022-12-14 01:14:40 +00:00
|
|
|
pVnode->blocked = false;
|
|
|
|
|
pVnode->blockSec = 0;
|
|
|
|
|
pVnode->blockSeq = 0;
|
2024-09-24 08:48:07 +00:00
|
|
|
if (tsem_post(&pVnode->syncSem) != 0) {
|
|
|
|
|
vError("vgId:%d, failed to post block", pVnode->config.vgId);
|
|
|
|
|
}
|
2022-12-14 01:14:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
2024-07-27 10:28:26 +00:00
|
|
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
2022-12-14 01:14:40 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-02 02:24:55 +00:00
|
|
|
bool vnodeIsRoleLeader(SVnode *pVnode) {
|
|
|
|
|
SSyncState state = syncGetState(pVnode->sync);
|
|
|
|
|
return state.state == TAOS_SYNC_STATE_LEADER;
|
|
|
|
|
}
|
2022-08-15 02:50:09 +00:00
|
|
|
|
2022-07-06 07:15:55 +00:00
|
|
|
bool vnodeIsLeader(SVnode *pVnode) {
|
2022-12-02 08:06:10 +00:00
|
|
|
terrno = 0;
|
2022-11-02 02:24:55 +00:00
|
|
|
SSyncState state = syncGetState(pVnode->sync);
|
|
|
|
|
|
2022-12-02 08:06:10 +00:00
|
|
|
if (terrno != 0) {
|
|
|
|
|
vInfo("vgId:%d, vnode is stopping", pVnode->config.vgId);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state.state != TAOS_SYNC_STATE_LEADER) {
|
|
|
|
|
terrno = TSDB_CODE_SYN_NOT_LEADER;
|
|
|
|
|
vInfo("vgId:%d, vnode not leader, state:%s", pVnode->config.vgId, syncStr(state.state));
|
2022-07-06 07:15:55 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-02 08:06:10 +00:00
|
|
|
if (!state.restored || !pVnode->restored) {
|
|
|
|
|
terrno = TSDB_CODE_SYN_RESTORING;
|
|
|
|
|
vInfo("vgId:%d, vnode not restored:%d:%d", pVnode->config.vgId, state.restored, pVnode->restored);
|
2022-07-25 11:08:08 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2022-07-06 07:15:55 +00:00
|
|
|
|
|
|
|
|
return true;
|
2022-08-08 10:20:41 +00:00
|
|
|
}
|
2023-09-20 01:54:28 +00:00
|
|
|
|
2024-03-06 06:35:44 +00:00
|
|
|
int64_t vnodeClusterId(SVnode *pVnode) {
|
|
|
|
|
SSyncCfg *syncCfg = &pVnode->config.syncCfg;
|
|
|
|
|
return syncCfg->nodeInfo[syncCfg->myIndex].clusterId;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 01:52:26 +00:00
|
|
|
int32_t vnodeNodeId(SVnode *pVnode) {
|
|
|
|
|
SSyncCfg *syncCfg = &pVnode->config.syncCfg;
|
|
|
|
|
return syncCfg->nodeInfo[syncCfg->myIndex].nodeId;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 01:54:28 +00:00
|
|
|
int32_t vnodeGetSnapshot(SVnode *pVnode, SSnapshot *pSnap) {
|
2023-09-27 01:29:38 +00:00
|
|
|
int code = 0;
|
2023-09-20 01:54:28 +00:00
|
|
|
pSnap->lastApplyIndex = pVnode->state.committed;
|
|
|
|
|
pSnap->lastApplyTerm = pVnode->state.commitTerm;
|
|
|
|
|
pSnap->lastConfigIndex = -1;
|
2023-10-18 08:09:51 +00:00
|
|
|
pSnap->state = SYNC_FSM_STATE_COMPLETE;
|
2023-09-27 07:22:24 +00:00
|
|
|
|
|
|
|
|
if (tsdbSnapGetFsState(pVnode) != TSDB_FS_STATE_NORMAL) {
|
|
|
|
|
pSnap->state = SYNC_FSM_STATE_INCOMPLETE;
|
|
|
|
|
}
|
2023-09-20 01:54:28 +00:00
|
|
|
|
2023-09-27 01:29:38 +00:00
|
|
|
if (pSnap->type == TDMT_SYNC_PREP_SNAPSHOT || pSnap->type == TDMT_SYNC_PREP_SNAPSHOT_REPLY) {
|
2023-12-04 08:56:20 +00:00
|
|
|
code = tsdbSnapPrepDescription(pVnode, pSnap);
|
2023-09-27 01:29:38 +00:00
|
|
|
}
|
2023-09-20 01:54:28 +00:00
|
|
|
return code;
|
|
|
|
|
}
|