sync refactor
This commit is contained in:
parent
996886e726
commit
d5188f14f9
|
@ -158,10 +158,10 @@ typedef struct SSyncNode SSyncNode;
|
||||||
int32_t syncInit();
|
int32_t syncInit();
|
||||||
void syncCleanUp();
|
void syncCleanUp();
|
||||||
|
|
||||||
int64_t syncStart(const SSyncInfo* pSyncInfo);
|
int64_t syncStart(const SSyncInfo* pSyncInfo);
|
||||||
void syncStop(int64_t rid);
|
void syncStop(int64_t rid);
|
||||||
int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg);
|
int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg);
|
||||||
int32_t syncPropose(int64_t rid, const SRpcMsg* pMsg, bool isWeak);
|
int32_t syncPropose(int64_t rid, const SRpcMsg* pMsg, bool isWeak);
|
||||||
ESyncState syncGetMyRole(int64_t rid);
|
ESyncState syncGetMyRole(int64_t rid);
|
||||||
|
|
||||||
// propose with sequence number, to implement linearizable semantics
|
// propose with sequence number, to implement linearizable semantics
|
||||||
|
|
|
@ -155,102 +155,60 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||||
|
|
||||||
// accept request
|
// accept request
|
||||||
if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_FOLLOWER && logOK) {
|
if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_FOLLOWER && logOK) {
|
||||||
/*
|
// preIndex = -1, or has preIndex entry in local log
|
||||||
bool preMatch = false;
|
assert(pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore));
|
||||||
if (pMsg->prevLogIndex == SYNC_INDEX_INVALID &&
|
|
||||||
ths->pLogStore->getLastIndex(ths->pLogStore) == SYNC_INDEX_INVALID) {
|
// has extra entries (> preIndex) in local log
|
||||||
preMatch = true;
|
bool hasExtraEntries = pMsg->prevLogIndex < ths->pLogStore->getLastIndex(ths->pLogStore);
|
||||||
}
|
|
||||||
if (pMsg->prevLogIndex >= SYNC_INDEX_BEGIN && pMsg->prevLogIndex <=
|
// has entries in SyncAppendEntries msg
|
||||||
ths->pLogStore->getLastIndex(ths->pLogStore)) { SSyncRaftEntry* pPreEntry = logStoreGetEntry(ths->pLogStore,
|
bool hasAppendEntries = pMsg->dataLen > 0;
|
||||||
pMsg->prevLogIndex); assert(pPreEntry != NULL); if (pMsg->prevLogTerm == pPreEntry->term) { preMatch = true;
|
|
||||||
|
sTrace(
|
||||||
|
"syncNodeOnAppendEntriesCb --> accept, pMsg->term:%lu, ths->pRaftStore->currentTerm:%lu, ths->state:%d, "
|
||||||
|
"logOK:%d, hasExtraEntries:%d, hasAppendEntries:%d",
|
||||||
|
pMsg->term, ths->pRaftStore->currentTerm, ths->state, logOK, hasExtraEntries, hasAppendEntries);
|
||||||
|
|
||||||
|
if (hasExtraEntries && hasAppendEntries) {
|
||||||
|
// not conflict by default
|
||||||
|
bool conflict = false;
|
||||||
|
|
||||||
|
SyncIndex extraIndex = pMsg->prevLogIndex + 1;
|
||||||
|
SSyncRaftEntry* pExtraEntry = logStoreGetEntry(ths->pLogStore, extraIndex);
|
||||||
|
assert(pExtraEntry != NULL);
|
||||||
|
|
||||||
|
SSyncRaftEntry* pAppendEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen);
|
||||||
|
assert(pAppendEntry != NULL);
|
||||||
|
|
||||||
|
// log not match, conflict
|
||||||
|
assert(extraIndex == pAppendEntry->index);
|
||||||
|
if (pExtraEntry->term != pAppendEntry->term) {
|
||||||
|
conflict = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conflict) {
|
||||||
|
// roll back
|
||||||
|
SyncIndex delBegin = ths->pLogStore->getLastIndex(ths->pLogStore);
|
||||||
|
SyncIndex delEnd = extraIndex;
|
||||||
|
|
||||||
|
sTrace("syncNodeOnAppendEntriesCb --> conflict:%d, delBegin:%ld, delEnd:%ld", conflict, delBegin, delEnd);
|
||||||
|
|
||||||
|
// notice! reverse roll back!
|
||||||
|
for (SyncIndex index = delEnd; index >= delBegin; --index) {
|
||||||
|
if (ths->pFsm->FpRollBackCb != NULL) {
|
||||||
|
SSyncRaftEntry* pRollBackEntry = logStoreGetEntry(ths->pLogStore, index);
|
||||||
|
assert(pRollBackEntry != NULL);
|
||||||
|
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncEntry2OriginalRpc(pRollBackEntry, &rpcMsg);
|
||||||
|
ths->pFsm->FpRollBackCb(ths->pFsm, &rpcMsg, pRollBackEntry->index, pRollBackEntry->isWeak, 0, ths->state);
|
||||||
|
rpcFreeCont(rpcMsg.pCont);
|
||||||
|
syncEntryDestory(pRollBackEntry);
|
||||||
}
|
}
|
||||||
syncEntryDestory(pPreEntry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sTrace(
|
// delete confict entries
|
||||||
"syncNodeOnAppendEntriesCb --> accept, pMsg->term:%lu, ths->pRaftStore->currentTerm:%lu, "
|
ths->pLogStore->truncate(ths->pLogStore, extraIndex);
|
||||||
"ths->state:%d, logOK:%d, preMatch:%d",
|
|
||||||
pMsg->term, ths->pRaftStore->currentTerm, ths->state, logOK, preMatch);
|
|
||||||
|
|
||||||
if (preMatch) {
|
|
||||||
*/
|
|
||||||
|
|
||||||
{
|
|
||||||
// preIndex = -1, or has preIndex entry in local log
|
|
||||||
assert(pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore));
|
|
||||||
|
|
||||||
// has extra entries (> preIndex) in local log
|
|
||||||
bool hasExtraEntries = pMsg->prevLogIndex < ths->pLogStore->getLastIndex(ths->pLogStore);
|
|
||||||
|
|
||||||
// has entries in SyncAppendEntries msg
|
|
||||||
bool hasAppendEntries = pMsg->dataLen > 0;
|
|
||||||
|
|
||||||
if (hasExtraEntries && hasAppendEntries) {
|
|
||||||
// not conflict by default
|
|
||||||
bool conflict = false;
|
|
||||||
|
|
||||||
SyncIndex extraIndex = pMsg->prevLogIndex + 1;
|
|
||||||
SSyncRaftEntry* pExtraEntry = logStoreGetEntry(ths->pLogStore, extraIndex);
|
|
||||||
assert(pExtraEntry != NULL);
|
|
||||||
|
|
||||||
SSyncRaftEntry* pAppendEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen);
|
|
||||||
assert(pAppendEntry != NULL);
|
|
||||||
|
|
||||||
// log not match, conflict
|
|
||||||
assert(extraIndex == pAppendEntry->index);
|
|
||||||
if (pExtraEntry->term != pAppendEntry->term) {
|
|
||||||
conflict = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conflict) {
|
|
||||||
// roll back
|
|
||||||
SyncIndex delBegin = ths->pLogStore->getLastIndex(ths->pLogStore);
|
|
||||||
SyncIndex delEnd = extraIndex;
|
|
||||||
|
|
||||||
sTrace("syncNodeOnAppendEntriesCb --> conflict:%d, delBegin:%ld, delEnd:%ld", conflict, delBegin, delEnd);
|
|
||||||
|
|
||||||
// notice! reverse roll back!
|
|
||||||
for (SyncIndex index = delEnd; index >= delBegin; --index) {
|
|
||||||
if (ths->pFsm->FpRollBackCb != NULL) {
|
|
||||||
SSyncRaftEntry* pRollBackEntry = logStoreGetEntry(ths->pLogStore, index);
|
|
||||||
assert(pRollBackEntry != NULL);
|
|
||||||
|
|
||||||
SRpcMsg rpcMsg;
|
|
||||||
syncEntry2OriginalRpc(pRollBackEntry, &rpcMsg);
|
|
||||||
ths->pFsm->FpRollBackCb(ths->pFsm, &rpcMsg, pRollBackEntry->index, pRollBackEntry->isWeak, 0, ths->state);
|
|
||||||
rpcFreeCont(rpcMsg.pCont);
|
|
||||||
syncEntryDestory(pRollBackEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete confict entries
|
|
||||||
ths->pLogStore->truncate(ths->pLogStore, extraIndex);
|
|
||||||
|
|
||||||
// append new entries
|
|
||||||
ths->pLogStore->appendEntry(ths->pLogStore, pAppendEntry);
|
|
||||||
|
|
||||||
// pre commit
|
|
||||||
SRpcMsg rpcMsg;
|
|
||||||
syncEntry2OriginalRpc(pAppendEntry, &rpcMsg);
|
|
||||||
if (ths->pFsm != NULL) {
|
|
||||||
if (ths->pFsm->FpPreCommitCb != NULL) {
|
|
||||||
ths->pFsm->FpPreCommitCb(ths->pFsm, &rpcMsg, pAppendEntry->index, pAppendEntry->isWeak, 2, ths->state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rpcFreeCont(rpcMsg.pCont);
|
|
||||||
}
|
|
||||||
|
|
||||||
// free memory
|
|
||||||
syncEntryDestory(pExtraEntry);
|
|
||||||
syncEntryDestory(pAppendEntry);
|
|
||||||
|
|
||||||
} else if (hasExtraEntries && !hasAppendEntries) {
|
|
||||||
// do nothing
|
|
||||||
|
|
||||||
} else if (!hasExtraEntries && hasAppendEntries) {
|
|
||||||
SSyncRaftEntry* pAppendEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen);
|
|
||||||
assert(pAppendEntry != NULL);
|
|
||||||
|
|
||||||
// append new entries
|
// append new entries
|
||||||
ths->pLogStore->appendEntry(ths->pLogStore, pAppendEntry);
|
ths->pLogStore->appendEntry(ths->pLogStore, pAppendEntry);
|
||||||
|
@ -260,55 +218,62 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||||
syncEntry2OriginalRpc(pAppendEntry, &rpcMsg);
|
syncEntry2OriginalRpc(pAppendEntry, &rpcMsg);
|
||||||
if (ths->pFsm != NULL) {
|
if (ths->pFsm != NULL) {
|
||||||
if (ths->pFsm->FpPreCommitCb != NULL) {
|
if (ths->pFsm->FpPreCommitCb != NULL) {
|
||||||
ths->pFsm->FpPreCommitCb(ths->pFsm, &rpcMsg, pAppendEntry->index, pAppendEntry->isWeak, 3, ths->state);
|
ths->pFsm->FpPreCommitCb(ths->pFsm, &rpcMsg, pAppendEntry->index, pAppendEntry->isWeak, 2, ths->state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rpcFreeCont(rpcMsg.pCont);
|
rpcFreeCont(rpcMsg.pCont);
|
||||||
|
|
||||||
// free memory
|
|
||||||
syncEntryDestory(pAppendEntry);
|
|
||||||
|
|
||||||
} else if (!hasExtraEntries && !hasAppendEntries) {
|
|
||||||
// do nothing
|
|
||||||
|
|
||||||
} else {
|
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild();
|
// free memory
|
||||||
pReply->srcId = ths->myRaftId;
|
syncEntryDestory(pExtraEntry);
|
||||||
pReply->destId = pMsg->srcId;
|
syncEntryDestory(pAppendEntry);
|
||||||
pReply->term = ths->pRaftStore->currentTerm;
|
|
||||||
pReply->success = true;
|
|
||||||
|
|
||||||
if (hasAppendEntries) {
|
} else if (hasExtraEntries && !hasAppendEntries) {
|
||||||
pReply->matchIndex = pMsg->prevLogIndex + 1;
|
// do nothing
|
||||||
} else {
|
|
||||||
pReply->matchIndex = pMsg->prevLogIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} else if (!hasExtraEntries && hasAppendEntries) {
|
||||||
|
SSyncRaftEntry* pAppendEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen);
|
||||||
|
assert(pAppendEntry != NULL);
|
||||||
|
|
||||||
|
// append new entries
|
||||||
|
ths->pLogStore->appendEntry(ths->pLogStore, pAppendEntry);
|
||||||
|
|
||||||
|
// pre commit
|
||||||
SRpcMsg rpcMsg;
|
SRpcMsg rpcMsg;
|
||||||
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
syncEntry2OriginalRpc(pAppendEntry, &rpcMsg);
|
||||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
if (ths->pFsm != NULL) {
|
||||||
|
if (ths->pFsm->FpPreCommitCb != NULL) {
|
||||||
|
ths->pFsm->FpPreCommitCb(ths->pFsm, &rpcMsg, pAppendEntry->index, pAppendEntry->isWeak, 3, ths->state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rpcFreeCont(rpcMsg.pCont);
|
||||||
|
|
||||||
syncAppendEntriesReplyDestroy(pReply);
|
// free memory
|
||||||
|
syncEntryDestory(pAppendEntry);
|
||||||
|
|
||||||
|
} else if (!hasExtraEntries && !hasAppendEntries) {
|
||||||
|
// do nothing
|
||||||
|
|
||||||
|
} else {
|
||||||
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild();
|
||||||
else {
|
pReply->srcId = ths->myRaftId;
|
||||||
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild();
|
pReply->destId = pMsg->srcId;
|
||||||
pReply->srcId = ths->myRaftId;
|
pReply->term = ths->pRaftStore->currentTerm;
|
||||||
pReply->destId = pMsg->srcId;
|
pReply->success = true;
|
||||||
pReply->term = ths->pRaftStore->currentTerm;
|
|
||||||
pReply->success = false;
|
|
||||||
pReply->matchIndex = SYNC_INDEX_INVALID;
|
|
||||||
|
|
||||||
SRpcMsg rpcMsg;
|
if (hasAppendEntries) {
|
||||||
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
pReply->matchIndex = pMsg->prevLogIndex + 1;
|
||||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
} else {
|
||||||
syncAppendEntriesReplyDestroy(pReply);
|
pReply->matchIndex = pMsg->prevLogIndex;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||||
|
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||||
|
syncAppendEntriesReplyDestroy(pReply);
|
||||||
|
|
||||||
// maybe update commit index from leader
|
// maybe update commit index from leader
|
||||||
if (pMsg->commitIndex > ths->commitIndex) {
|
if (pMsg->commitIndex > ths->commitIndex) {
|
||||||
|
|
|
@ -63,7 +63,14 @@ void syncMaybeAdvanceCommitIndex(SSyncNode* pSyncNode) {
|
||||||
if (pEntry->term == pSyncNode->pRaftStore->currentTerm) {
|
if (pEntry->term == pSyncNode->pRaftStore->currentTerm) {
|
||||||
// update commit index
|
// update commit index
|
||||||
newCommitIndex = index;
|
newCommitIndex = index;
|
||||||
|
sTrace("syncMaybeAdvanceCommitIndex maybe to update, newCommitIndex:%ld commit, pSyncNode->commitIndex:%ld",
|
||||||
|
newCommitIndex, pSyncNode->commitIndex);
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
sTrace(
|
||||||
|
"syncMaybeAdvanceCommitIndex can not commit due to term not equal, pEntry->term:%lu, "
|
||||||
|
"pSyncNode->pRaftStore->currentTerm:%lu",
|
||||||
|
pEntry->term, pSyncNode->pRaftStore->currentTerm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ SSyncFSM* pFsm;
|
||||||
SWal* pWal;
|
SWal* pWal;
|
||||||
SSyncNode* pSyncNode;
|
SSyncNode* pSyncNode;
|
||||||
|
|
||||||
SSyncNode* syncNodeInit(const char *path) {
|
SSyncNode* syncNodeInit(const char* path) {
|
||||||
syncInfo.vgId = 1234;
|
syncInfo.vgId = 1234;
|
||||||
syncInfo.rpcClient = gSyncIO->clientRpc;
|
syncInfo.rpcClient = gSyncIO->clientRpc;
|
||||||
syncInfo.FpSendMsg = syncIOSendMsg;
|
syncInfo.FpSendMsg = syncIOSendMsg;
|
||||||
|
@ -78,9 +78,7 @@ SSyncNode* syncNodeInit(const char *path) {
|
||||||
return pSyncNode;
|
return pSyncNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSyncNode* logStoreCheck(const char *path) { return syncNodeInit(path); }
|
SSyncNode* logStoreCheck(const char* path) { return syncNodeInit(path); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
// taosInitLog((char *)"syncTest.log", 100000, 10);
|
// taosInitLog((char *)"syncTest.log", 100000, 10);
|
||||||
|
|
Loading…
Reference in New Issue