• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3543

29 Nov 2024 02:58AM UTC coverage: 60.842% (+0.02%) from 60.819%
#3543

push

travis-ci

web-flow
Merge pull request #28973 from taosdata/merge/mainto3.0

merge: from main to 3.0

120460 of 253224 branches covered (47.57%)

Branch coverage included in aggregate %.

706 of 908 new or added lines in 18 files covered. (77.75%)

2401 existing lines in 137 files now uncovered.

201633 of 276172 relevant lines covered (73.01%)

19045673.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.28
/source/dnode/vnode/src/vnd/vnodeSync.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define _DEFAULT_SOURCE
17
#include "sync.h"
18
#include "tq.h"
19
#include "tqCommon.h"
20
#include "tsdb.h"
21
#include "vnd.h"
22

23
#define BATCH_ENABLE 0
24

25
static inline bool vnodeIsMsgWeak(tmsg_t type) { return false; }
10,547,704✔
26

27
static inline void vnodeWaitBlockMsg(SVnode *pVnode, const SRpcMsg *pMsg) {
2,640✔
28
  const STraceId *trace = &pMsg->info.traceId;
2,640✔
29
  vGTrace("vgId:%d, msg:%p wait block, type:%s sec:%d seq:%" PRId64, pVnode->config.vgId, pMsg,
2,640!
30
          TMSG_INFO(pMsg->msgType), pVnode->blockSec, pVnode->blockSeq);
31
  if (tsem_wait(&pVnode->syncSem) != 0) {
2,640!
32
    vError("vgId:%d, failed to wait sem", pVnode->config.vgId);
×
33
  }
34
}
2,640✔
35

36
static inline void vnodePostBlockMsg(SVnode *pVnode, const SRpcMsg *pMsg) {
3,138,031✔
37
  if (vnodeIsMsgBlock(pMsg->msgType)) {
3,138,031✔
38
    const STraceId *trace = &pMsg->info.traceId;
19,765✔
39
    (void)taosThreadMutexLock(&pVnode->lock);
19,765✔
40
    if (pVnode->blocked) {
19,766✔
41
      vGTrace("vgId:%d, msg:%p post block, type:%s sec:%d seq:%" PRId64, pVnode->config.vgId, pMsg,
2,639!
42
              TMSG_INFO(pMsg->msgType), pVnode->blockSec, pVnode->blockSeq);
43
      pVnode->blocked = false;
2,639✔
44
      pVnode->blockSec = 0;
2,639✔
45
      pVnode->blockSeq = 0;
2,639✔
46
      if (tsem_post(&pVnode->syncSem) != 0) {
2,639!
47
        vError("vgId:%d, failed to post sem", pVnode->config.vgId);
×
48
      }
49
    }
50
    (void)taosThreadMutexUnlock(&pVnode->lock);
19,766✔
51
  }
52
}
3,138,039✔
53

54
void vnodeRedirectRpcMsg(SVnode *pVnode, SRpcMsg *pMsg, int32_t code) {
41,394✔
55
  SEpSet newEpSet = {0};
41,394✔
56
  syncGetRetryEpSet(pVnode->sync, &newEpSet);
41,394✔
57

58
  const STraceId *trace = &pMsg->info.traceId;
41,394✔
59
  vGTrace("vgId:%d, msg:%p is redirect since not leader, numOfEps:%d inUse:%d", pVnode->config.vgId, pMsg,
41,394!
60
          newEpSet.numOfEps, newEpSet.inUse);
61
  for (int32_t i = 0; i < newEpSet.numOfEps; ++i) {
156,250✔
62
    vGTrace("vgId:%d, msg:%p redirect:%d ep:%s:%u", pVnode->config.vgId, pMsg, i, newEpSet.eps[i].fqdn,
114,856!
63
            newEpSet.eps[i].port);
64
  }
65
  pMsg->info.hasEpSet = 1;
41,394✔
66

67
  if (code == 0) code = TSDB_CODE_SYN_NOT_LEADER;
41,394!
68

69
  SRpcMsg rsp = {.code = code, .info = pMsg->info, .msgType = pMsg->msgType + 1};
41,394✔
70
  int32_t contLen = tSerializeSEpSet(NULL, 0, &newEpSet);
41,394✔
71

72
  rsp.pCont = rpcMallocCont(contLen);
41,394✔
73
  if (rsp.pCont == NULL) {
41,394!
74
    pMsg->code = TSDB_CODE_OUT_OF_MEMORY;
×
75
  } else {
76
    if (tSerializeSEpSet(rsp.pCont, contLen, &newEpSet) < 0) {
41,394!
77
      vError("vgId:%d, failed to serialize ep set", pVnode->config.vgId);
×
78
    }
79
    rsp.contLen = contLen;
41,394✔
80
  }
81

82
  tmsgSendRsp(&rsp);
41,394✔
83
}
41,394✔
84

85
static void inline vnodeHandleWriteMsg(SVnode *pVnode, SRpcMsg *pMsg) {
10,270,145✔
86
  SRpcMsg rsp = {.code = pMsg->code, .info = pMsg->info};
10,270,145✔
87
  if (vnodeProcessWriteMsg(pVnode, pMsg, pMsg->info.conn.applyIndex, &rsp) < 0) {
10,270,145✔
88
    rsp.code = terrno;
599✔
89
    const STraceId *trace = &pMsg->info.traceId;
546✔
90
    vGError("vgId:%d, msg:%p failed to apply right now since %s", pVnode->config.vgId, pMsg, terrstr());
546!
91
  }
92
  if (rsp.info.handle != NULL) {
10,270,185✔
93
    tmsgSendRsp(&rsp);
10,233,056✔
94
  } else {
95
    if (rsp.pCont) {
37,129✔
96
      rpcFreeCont(rsp.pCont);
26,222✔
97
    }
98
  }
99
}
10,270,504✔
100

101
static void vnodeHandleProposeError(SVnode *pVnode, SRpcMsg *pMsg, int32_t code) {
129,103✔
102
  if (code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_SYN_RESTORING) {
129,103✔
103
    vnodeRedirectRpcMsg(pVnode, pMsg, code);
35,583✔
104
  } else if (code == TSDB_CODE_MSG_PREPROCESSED) {
93,520✔
105
    SRpcMsg rsp = {.code = TSDB_CODE_SUCCESS, .info = pMsg->info};
92,540✔
106
    if (rsp.info.handle != NULL) {
92,540!
107
      tmsgSendRsp(&rsp);
92,727✔
108
    }
109
  } else {
110
    const STraceId *trace = &pMsg->info.traceId;
980✔
111
    vGError("vgId:%d, msg:%p failed to propose since %s, code:0x%x", pVnode->config.vgId, pMsg, tstrerror(code), code);
980!
112
    SRpcMsg rsp = {.code = code, .info = pMsg->info};
980✔
113
    if (rsp.info.handle != NULL) {
980✔
114
      tmsgSendRsp(&rsp);
495✔
115
    }
116
  }
117
}
129,401✔
118

119
static int32_t inline vnodeProposeMsg(SVnode *pVnode, SRpcMsg *pMsg, bool isWeak) {
10,429,474✔
120
  int64_t seq = 0;
10,429,474✔
121

122
  (void)taosThreadMutexLock(&pVnode->lock);
10,429,474✔
123
  int32_t code = syncPropose(pVnode->sync, pMsg, isWeak, &seq);
10,429,864✔
124
  bool    wait = (code == 0 && vnodeIsMsgBlock(pMsg->msgType));
10,429,462✔
125
  if (wait) {
10,429,463✔
126
    if (pVnode->blocked) {
2,640!
127
      return TSDB_CODE_INTERNAL_ERROR;
×
128
    }
129
    pVnode->blocked = true;
2,640✔
130
    pVnode->blockSec = taosGetTimestampSec();
2,640✔
131
    pVnode->blockSeq = seq;
2,640✔
132
  }
133
  (void)taosThreadMutexUnlock(&pVnode->lock);
10,429,463✔
134

135
  if (code > 0) {
10,429,834✔
136
    vnodeHandleWriteMsg(pVnode, pMsg);
10,270,517✔
137
  } else if (code < 0) {
159,317✔
138
    if (terrno != 0) code = terrno;
10,408!
139
    vnodeHandleProposeError(pVnode, pMsg, code);
10,408✔
140
  }
141

142
  if (wait) vnodeWaitBlockMsg(pVnode, pMsg);
10,429,788✔
143
  return code;
10,429,799✔
144
}
145

146
void vnodeProposeCommitOnNeed(SVnode *pVnode, bool atExit) {
10,533,363✔
147
  if (!vnodeShouldCommit(pVnode, atExit)) {
10,533,363✔
148
    return;
10,525,329✔
149
  }
150

151
  int32_t   contLen = sizeof(SMsgHead);
8,836✔
152
  SMsgHead *pHead = rpcMallocCont(contLen);
8,836✔
153
  pHead->contLen = contLen;
8,839✔
154
  pHead->vgId = pVnode->config.vgId;
8,839✔
155

156
  SRpcMsg rpcMsg = {0};
8,839✔
157
  rpcMsg.msgType = TDMT_VND_COMMIT;
8,839✔
158
  rpcMsg.contLen = contLen;
8,839✔
159
  rpcMsg.pCont = pHead;
8,839✔
160
  rpcMsg.info.noResp = 1;
8,839✔
161

162
  vInfo("vgId:%d, propose vnode commit", pVnode->config.vgId);
8,839!
163
  bool isWeak = false;
8,837✔
164

165
  if (!atExit) {
8,837✔
166
    if (vnodeProposeMsg(pVnode, &rpcMsg, isWeak) < 0) {
762!
167
      vTrace("vgId:%d, failed to propose vnode commit since %s", pVnode->config.vgId, terrstr());
×
168
    }
169
    rpcFreeCont(rpcMsg.pCont);
762✔
170
    rpcMsg.pCont = NULL;
762✔
171
  } else {
172
    if (tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &rpcMsg) < 0) {
8,075✔
173
      vTrace("vgId:%d, failed to put vnode commit to queue since %s", pVnode->config.vgId, terrstr());
3,639✔
174
    }
175
  }
176
}
177

178
#if BATCH_ENABLE
179

180
static void inline vnodeProposeBatchMsg(SVnode *pVnode, SRpcMsg **pMsgArr, bool *pIsWeakArr, int32_t *arrSize) {
181
  if (*arrSize <= 0) return;
182
  SRpcMsg *pLastMsg = pMsgArr[*arrSize - 1];
183

184
  (void)taosThreadMutexLock(&pVnode->lock);
185
  int32_t code = syncProposeBatch(pVnode->sync, pMsgArr, pIsWeakArr, *arrSize);
186
  bool    wait = (code == 0 && vnodeIsBlockMsg(pLastMsg->msgType));
187
  if (wait) {
188
    pVnode->blocked = true;
189
  }
190
  (void)taosThreadMutexUnlock(&pVnode->lock);
191

192
  if (code > 0) {
193
    for (int32_t i = 0; i < *arrSize; ++i) {
194
      vnodeHandleWriteMsg(pVnode, pMsgArr[i]);
195
    }
196
  } else if (code < 0) {
197
    if (terrno != 0) code = terrno;
198
    for (int32_t i = 0; i < *arrSize; ++i) {
199
      vnodeHandleProposeError(pVnode, pMsgArr[i], code);
200
    }
201
  }
202

203
  if (wait) vnodeWaitBlockMsg(pVnode, pLastMsg);
204
  pLastMsg = NULL;
205

206
  for (int32_t i = 0; i < *arrSize; ++i) {
207
    SRpcMsg        *pMsg = pMsgArr[i];
208
    const STraceId *trace = &pMsg->info.traceId;
209
    vGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->config.vgId, pMsg, code);
210
    rpcFreeCont(pMsg->pCont);
211
    taosFreeQitem(pMsg);
212
  }
213

214
  *arrSize = 0;
215
}
216

217
void vnodeProposeWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
218
  SVnode   *pVnode = pInfo->ahandle;
219
  int32_t   vgId = pVnode->config.vgId;
220
  int32_t   code = 0;
221
  SRpcMsg  *pMsg = NULL;
222
  int32_t   arrayPos = 0;
223
  SRpcMsg **pMsgArr = taosMemoryCalloc(numOfMsgs, sizeof(SRpcMsg *));
224
  bool     *pIsWeakArr = taosMemoryCalloc(numOfMsgs, sizeof(bool));
225
  vTrace("vgId:%d, get %d msgs from vnode-write queue", vgId, numOfMsgs);
226

227
  for (int32_t msg = 0; msg < numOfMsgs; msg++) {
228
    if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
229
    bool isWeak = vnodeIsMsgWeak(pMsg->msgType);
230
    bool isBlock = vnodeIsMsgBlock(pMsg->msgType);
231

232
    const STraceId *trace = &pMsg->info.traceId;
233
    vGTrace("vgId:%d, msg:%p get from vnode-write queue, weak:%d block:%d msg:%d:%d pos:%d, handle:%p", vgId, pMsg,
234
            isWeak, isBlock, msg, numOfMsgs, arrayPos, pMsg->info.handle);
235

236
    if (!pVnode->restored) {
237
      vGWarn("vgId:%d, msg:%p failed to process since restore not finished, type:%s", vgId, pMsg,
238
             TMSG_INFO(pMsg->msgType));
239
      terrno = TSDB_CODE_SYN_RESTORING;
240
      vnodeHandleProposeError(pVnode, pMsg, TSDB_CODE_SYN_RESTORING);
241
      rpcFreeCont(pMsg->pCont);
242
      taosFreeQitem(pMsg);
243
      continue;
244
    }
245

246
    if (pMsgArr == NULL || pIsWeakArr == NULL) {
247
      vGError("vgId:%d, msg:%p failed to process since out of memory, type:%s", vgId, pMsg, TMSG_INFO(pMsg->msgType));
248
      terrno = TSDB_CODE_OUT_OF_MEMORY;
249
      vnodeHandleProposeError(pVnode, pMsg, terrno);
250
      rpcFreeCont(pMsg->pCont);
251
      taosFreeQitem(pMsg);
252
      continue;
253
    }
254

255
    bool atExit = false;
256
    vnodeProposeCommitOnNeed(pVnode, atExit);
257

258
    code = vnodePreProcessWriteMsg(pVnode, pMsg);
259
    if (code != 0) {
260
      vGError("vgId:%d, msg:%p failed to pre-process since %s", vgId, pMsg, terrstr());
261
      rpcFreeCont(pMsg->pCont);
262
      taosFreeQitem(pMsg);
263
      continue;
264
    }
265

266
    if (isBlock) {
267
      vnodeProposeBatchMsg(pVnode, pMsgArr, pIsWeakArr, &arrayPos);
268
    }
269

270
    pMsgArr[arrayPos] = pMsg;
271
    pIsWeakArr[arrayPos] = isWeak;
272
    arrayPos++;
273

274
    if (isBlock || msg == numOfMsgs - 1) {
275
      vnodeProposeBatchMsg(pVnode, pMsgArr, pIsWeakArr, &arrayPos);
276
    }
277
  }
278

279
  taosMemoryFree(pMsgArr);
280
  taosMemoryFree(pIsWeakArr);
281
}
282

283
#else
284

285
void vnodeProposeWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
9,110,882✔
286
  SVnode  *pVnode = pInfo->ahandle;
9,110,882✔
287
  int32_t  vgId = pVnode->config.vgId;
9,110,882✔
288
  int32_t  code = 0;
9,110,882✔
289
  SRpcMsg *pMsg = NULL;
9,110,882✔
290
  vTrace("vgId:%d, get %d msgs from vnode-write queue", vgId, numOfMsgs);
9,110,882✔
291

292
  for (int32_t msg = 0; msg < numOfMsgs; msg++) {
19,659,403✔
293
    if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
10,547,889!
294
    bool isWeak = vnodeIsMsgWeak(pMsg->msgType);
10,548,029✔
295

296
    const STraceId *trace = &pMsg->info.traceId;
10,547,789✔
297
    vGTrace("vgId:%d, msg:%p get from vnode-write queue, weak:%d block:%d msg:%d:%d, handle:%p", vgId, pMsg, isWeak,
10,547,789!
298
            vnodeIsMsgBlock(pMsg->msgType), msg, numOfMsgs, pMsg->info.handle);
299

300
    if (!pVnode->restored) {
10,547,789✔
301
      vGWarn("vgId:%d, msg:%p failed to process since restore not finished, type:%s", vgId, pMsg,
25,801!
302
             TMSG_INFO(pMsg->msgType));
303
      vnodeHandleProposeError(pVnode, pMsg, TSDB_CODE_SYN_RESTORING);
25,801✔
304
      rpcFreeCont(pMsg->pCont);
25,801✔
305
      taosFreeQitem(pMsg);
25,801✔
306
      continue;
25,801✔
307
    }
308

309
    bool atExit = false;
10,521,988✔
310
    vnodeProposeCommitOnNeed(pVnode, atExit);
10,521,988✔
311

312
    code = vnodePreProcessWriteMsg(pVnode, pMsg);
10,522,353✔
313
    if (code != 0) {
10,521,653✔
314
      if (code != TSDB_CODE_MSG_PREPROCESSED) {
92,941✔
315
        vGError("vgId:%d, msg:%p failed to pre-process since %s", vgId, pMsg, tstrerror(code));
495!
316
        if (terrno != 0) code = terrno;
495!
317
      }
318
      vnodeHandleProposeError(pVnode, pMsg, code);
92,941✔
319
      rpcFreeCont(pMsg->pCont);
93,156✔
320
      taosFreeQitem(pMsg);
93,327✔
321
      continue;
93,295✔
322
    }
323

324
    code = vnodeProposeMsg(pVnode, pMsg, isWeak);
10,428,712✔
325

326
    vGTrace("vgId:%d, msg:%p is freed, code:0x%x", vgId, pMsg, code);
10,429,004!
327
    rpcFreeCont(pMsg->pCont);
10,429,004✔
328
    taosFreeQitem(pMsg);
10,429,106✔
329
  }
330
}
9,111,514✔
331

332
#endif
333

334
void vnodeApplyWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
2,098,517✔
335
  SVnode  *pVnode = pInfo->ahandle;
2,098,517✔
336
  int32_t  vgId = pVnode->config.vgId;
2,098,517✔
337
  int32_t  code = 0;
2,098,517✔
338
  SRpcMsg *pMsg = NULL;
2,098,517✔
339

340
  for (int32_t i = 0; i < numOfMsgs; ++i) {
5,236,573✔
341
    if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
3,138,054!
342
    const STraceId *trace = &pMsg->info.traceId;
3,138,056✔
343

344
    if (vnodeIsMsgBlock(pMsg->msgType)) {
3,138,056✔
345
      vGTrace("vgId:%d, msg:%p get from vnode-apply queue, type:%s handle:%p index:%" PRId64
19,763!
346
              ", blocking msg obtained sec:%d seq:%" PRId64,
347
              vgId, pMsg, TMSG_INFO(pMsg->msgType), pMsg->info.handle, pMsg->info.conn.applyIndex, pVnode->blockSec,
348
              pVnode->blockSeq);
349
    } else {
350
      vGTrace("vgId:%d, msg:%p get from vnode-apply queue, type:%s handle:%p index:%" PRId64, vgId, pMsg,
3,118,291!
351
              TMSG_INFO(pMsg->msgType), pMsg->info.handle, pMsg->info.conn.applyIndex);
352
    }
353

354
    SRpcMsg rsp = {.code = pMsg->code, .info = pMsg->info};
3,138,054✔
355
    if (rsp.code == 0) {
3,138,054!
356
      if (vnodeProcessWriteMsg(pVnode, pMsg, pMsg->info.conn.applyIndex, &rsp) < 0) {
3,138,074!
357
        rsp.code = terrno;
×
358
        vGError("vgId:%d, msg:%p failed to apply since %s, index:%" PRId64, vgId, pMsg, terrstr(),
×
359
                pMsg->info.conn.applyIndex);
360
      }
361
    }
362

363
    vnodePostBlockMsg(pVnode, pMsg);
3,138,017✔
364
    if (rsp.info.handle != NULL) {
3,138,028✔
365
      tmsgSendRsp(&rsp);
148,877✔
366
    } else {
367
      if (rsp.pCont) {
2,989,151✔
368
        rpcFreeCont(rsp.pCont);
2,936,041✔
369
      }
370
    }
371

372
    vGTrace("vgId:%d, msg:%p is freed, code:0x%x index:%" PRId64, vgId, pMsg, rsp.code, pMsg->info.conn.applyIndex);
3,138,035!
373
    rpcFreeCont(pMsg->pCont);
3,138,035✔
374
    taosFreeQitem(pMsg);
3,138,022✔
375
  }
376
}
2,098,519✔
377

378
int32_t vnodeProcessSyncMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
6,094,663✔
379
  const STraceId *trace = &pMsg->info.traceId;
6,094,663✔
380
  vGTrace("vgId:%d, sync msg:%p will be processed, type:%s", pVnode->config.vgId, pMsg, TMSG_INFO(pMsg->msgType));
6,094,663!
381

382
  int32_t code = syncProcessMsg(pVnode->sync, pMsg);
6,094,663✔
383
  if (code != 0) {
6,094,755✔
384
    vGError("vgId:%d, failed to process sync msg:%p type:%s, reason: %s", pVnode->config.vgId, pMsg,
22!
385
            TMSG_INFO(pMsg->msgType), tstrerror(code));
386
  }
387

388
  return code;
6,094,755✔
389
}
390

391
static int32_t vnodeSyncEqCtrlMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
×
392
  if (pMsg == NULL || pMsg->pCont == NULL) {
×
393
    return TSDB_CODE_INVALID_PARA;
×
394
  }
395

396
  if (msgcb == NULL || msgcb->putToQueueFp == NULL) {
×
397
    rpcFreeCont(pMsg->pCont);
×
398
    pMsg->pCont = NULL;
×
399
    return TSDB_CODE_INVALID_PARA;
×
400
  }
401

402
  int32_t code = tmsgPutToQueue(msgcb, SYNC_RD_QUEUE, pMsg);
×
403
  if (code != 0) {
×
404
    rpcFreeCont(pMsg->pCont);
×
405
    pMsg->pCont = NULL;
×
406
  }
407
  return code;
×
408
}
409

410
static int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
384,129✔
411
  if (pMsg == NULL || pMsg->pCont == NULL) {
384,129!
412
    return TSDB_CODE_INVALID_PARA;
×
413
  }
414

415
  if (msgcb == NULL || msgcb->putToQueueFp == NULL) {
384,130!
416
    rpcFreeCont(pMsg->pCont);
2✔
417
    pMsg->pCont = NULL;
×
418
    return TSDB_CODE_INVALID_PARA;
×
419
  }
420

421
  int32_t code = tmsgPutToQueue(msgcb, SYNC_QUEUE, pMsg);
384,128✔
422
  if (code != 0) {
384,129✔
423
    rpcFreeCont(pMsg->pCont);
1,444✔
424
    pMsg->pCont = NULL;
1,444✔
425
  }
426
  return code;
384,129✔
427
}
428

429
static int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) {
5,732,002✔
430
  int32_t code = tmsgSendSyncReq(pEpSet, pMsg);
5,732,002✔
431
  if (code != 0) {
5,732,025!
432
    rpcFreeCont(pMsg->pCont);
×
433
    pMsg->pCont = NULL;
×
434
  }
435
  return code;
5,732,025✔
436
}
437

438
static int32_t vnodeSyncGetSnapshotInfo(const SSyncFSM *pFsm, SSnapshot *pSnapshot) {
503,494✔
439
  return vnodeGetSnapshot(pFsm->data, pSnapshot);
503,494✔
440
}
441

442
static int32_t vnodeSyncApplyMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta *pMeta) {
3,138,948✔
443
  SVnode *pVnode = pFsm->data;
3,138,948✔
444
  pMsg->info.conn.applyIndex = pMeta->index;
3,138,948✔
445
  pMsg->info.conn.applyTerm = pMeta->term;
3,138,948✔
446

447
  const STraceId *trace = &pMsg->info.traceId;
3,138,948✔
448
  vGTrace("vgId:%d, commit-cb is excuted, fsm:%p, index:%" PRId64 ", term:%" PRIu64 ", msg-index:%" PRId64
3,138,948!
449
          ", weak:%d, code:%d, state:%d %s, type:%s code:0x%x",
450
          pVnode->config.vgId, pFsm, pMeta->index, pMeta->term, pMsg->info.conn.applyIndex, pMeta->isWeak, pMeta->code,
451
          pMeta->state, syncStr(pMeta->state), TMSG_INFO(pMsg->msgType), pMsg->code);
452

453
  return tmsgPutToQueue(&pVnode->msgCb, APPLY_QUEUE, pMsg);
3,138,948✔
454
}
455

456
static int32_t vnodeSyncCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
3,138,951✔
457
  if (pMsg->code == 0) {
3,138,951!
458
    return vnodeSyncApplyMsg(pFsm, pMsg, pMeta);
3,138,952✔
459
  }
460

461
  const STraceId *trace = &pMsg->info.traceId;
×
462
  SVnode         *pVnode = pFsm->data;
×
463
  vnodePostBlockMsg(pVnode, pMsg);
×
464

465
  SRpcMsg rsp = {.code = pMsg->code, .info = pMsg->info};
×
466
  if (rsp.info.handle != NULL) {
×
467
    tmsgSendRsp(&rsp);
×
468
  }
469

470
  vGTrace("vgId:%d, msg:%p is freed, code:0x%x index:%" PRId64, TD_VID(pVnode), pMsg, rsp.code, pMeta->index);
×
471
  rpcFreeCont(pMsg->pCont);
×
472
  pMsg->pCont = NULL;
×
473
  return 0;
×
474
}
475

476
static int32_t vnodeSyncPreCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
×
477
  if (pMeta->isWeak == 1) {
×
478
    return vnodeSyncApplyMsg(pFsm, pMsg, pMeta);
×
479
  }
480
  return 0;
×
481
}
482

483
static SyncIndex vnodeSyncAppliedIndex(const SSyncFSM *pFSM) {
10,649,659✔
484
  SVnode *pVnode = pFSM->data;
10,649,659✔
485
  return atomic_load_64(&pVnode->state.applied);
10,649,659✔
486
}
487

488
static void vnodeSyncRollBackMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
×
489
  SVnode *pVnode = pFsm->data;
×
490
  vTrace("vgId:%d, rollback-cb is excuted, fsm:%p, index:%" PRId64 ", weak:%d, code:%d, state:%d %s, type:%s",
×
491
         pVnode->config.vgId, pFsm, pMeta->index, pMeta->isWeak, pMeta->code, pMeta->state, syncStr(pMeta->state),
492
         TMSG_INFO(pMsg->msgType));
493
}
×
494

495
static int32_t vnodeSnapshotStartRead(const SSyncFSM *pFsm, void *pParam, void **ppReader) {
106✔
496
  SVnode *pVnode = pFsm->data;
106✔
497
  return vnodeSnapReaderOpen(pVnode, (SSnapshotParam *)pParam, (SVSnapReader **)ppReader);
106✔
498
}
499

500
static void vnodeSnapshotStopRead(const SSyncFSM *pFsm, void *pReader) {
106✔
501
  SVnode *pVnode = pFsm->data;
106✔
502
  vnodeSnapReaderClose(pReader);
106✔
503
}
106✔
504

505
static int32_t vnodeSnapshotDoRead(const SSyncFSM *pFsm, void *pReader, void **ppBuf, int32_t *len) {
85,434✔
506
  SVnode *pVnode = pFsm->data;
85,434✔
507
  return vnodeSnapRead(pReader, (uint8_t **)ppBuf, len);
85,434✔
508
}
509

510
static int32_t vnodeSnapshotStartWrite(const SSyncFSM *pFsm, void *pParam, void **ppWriter) {
105✔
511
  SVnode *pVnode = pFsm->data;
105✔
512

513
  do {
×
514
    int32_t itemSize = tmsgGetQueueSize(&pVnode->msgCb, pVnode->config.vgId, APPLY_QUEUE);
105✔
515
    if (itemSize == 0) {
105!
516
      vInfo("vgId:%d, start write vnode snapshot since apply queue is empty", pVnode->config.vgId);
105!
517
      break;
105✔
518
    } else {
519
      vInfo("vgId:%d, write vnode snapshot later since %d items in apply queue", pVnode->config.vgId, itemSize);
×
520
      taosMsleep(10);
×
521
    }
522
  } while (true);
523

524
  return vnodeSnapWriterOpen(pVnode, (SSnapshotParam *)pParam, (SVSnapWriter **)ppWriter);
105✔
525
}
526

527
static int32_t vnodeSnapshotStopWrite(const SSyncFSM *pFsm, void *pWriter, bool isApply, SSnapshot *pSnapshot) {
105✔
528
  SVnode *pVnode = pFsm->data;
105✔
529
  vInfo("vgId:%d, stop write vnode snapshot, apply:%d, index:%" PRId64 " term:%" PRIu64 " config:%" PRId64,
105!
530
        pVnode->config.vgId, isApply, pSnapshot->lastApplyIndex, pSnapshot->lastApplyTerm, pSnapshot->lastConfigIndex);
531

532
  int32_t code = vnodeSnapWriterClose(pWriter, !isApply, pSnapshot);
105✔
533
  if (code != 0) {
105!
534
    vError("vgId:%d, failed to finish applying vnode snapshot since %s, code:0x%x", pVnode->config.vgId, terrstr(),
×
535
           code);
536
  }
537
  return code;
105✔
538
}
539

540
static int32_t vnodeSnapshotDoWrite(const SSyncFSM *pFsm, void *pWriter, void *pBuf, int32_t len) {
85,299✔
541
  SVnode *pVnode = pFsm->data;
85,299✔
542
  vDebug("vgId:%d, continue write vnode snapshot, blockLen:%d", pVnode->config.vgId, len);
85,299!
543
  int32_t code = vnodeSnapWrite(pWriter, pBuf, len);
85,299✔
544
  vDebug("vgId:%d, continue write vnode snapshot finished, blockLen:%d", pVnode->config.vgId, len);
85,299!
545
  return code;
85,299✔
546
}
547

548
static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
13,720✔
549
  SVnode   *pVnode = pFsm->data;
13,720✔
550
  int32_t   vgId = pVnode->config.vgId;
13,720✔
551
  SyncIndex appliedIdx = -1;
13,720✔
552

553
  do {
554
    appliedIdx = vnodeSyncAppliedIndex(pFsm);
27,897✔
555
    if (appliedIdx > commitIdx) {
27,903!
556
      vError("vgId:%d, restore failed since applied-index:%" PRId64 " is larger than commit-index:%" PRId64, vgId,
×
557
             appliedIdx, commitIdx);
558
      break;
×
559
    }
560
    if (appliedIdx == commitIdx) {
27,904✔
561
      vInfo("vgId:%d, no items to be applied, restore finish", pVnode->config.vgId);
13,722!
562
      break;
13,722✔
563
    } else {
564
      vInfo("vgId:%d, restore not finish since %" PRId64 " items to be applied. commit-index:%" PRId64
14,182!
565
            ", applied-index:%" PRId64,
566
            vgId, commitIdx - appliedIdx, commitIdx, appliedIdx);
567
      taosMsleep(10);
14,183✔
568
    }
569
  } while (true);
570

571
  walApplyVer(pVnode->pWal, commitIdx);
13,722✔
572
  pVnode->restored = true;
13,722✔
573

574
  SStreamMeta *pMeta = pVnode->pTq->pStreamMeta;
13,722✔
575
  streamMetaWLock(pMeta);
13,722✔
576

577
  if (pMeta->startInfo.tasksWillRestart) {
13,722!
578
    vInfo("vgId:%d, sync restore finished, stream tasks will be launched by other thread", vgId);
×
579
    streamMetaWUnLock(pMeta);
×
580
    return;
×
581
  }
582

583
  if (vnodeIsRoleLeader(pVnode)) {
13,722✔
584
    // start to restore all stream tasks
585
    if (tsDisableStream) {
11,719!
586
      vInfo("vgId:%d, sync restore finished, not launch stream tasks, since stream tasks are disabled", vgId);
×
587
    } else {
588
      vInfo("vgId:%d sync restore finished, start to launch stream task(s)", vgId);
11,719!
589
      if (pMeta->startInfo.startAllTasks == 1) {
11,719✔
590
        pMeta->startInfo.restartCount += 1;
6✔
591
        vDebug("vgId:%d in start tasks procedure, inc restartCounter by 1, remaining restart:%d", vgId,
6!
592
               pMeta->startInfo.restartCount);
593
      } else {
594
        pMeta->startInfo.startAllTasks = 1;
11,713✔
595
        streamMetaWUnLock(pMeta);
11,713✔
596

597
        tqInfo("vgId:%d stream task already loaded, start them", vgId);
11,713!
598
        int32_t code = streamTaskSchedTask(&pVnode->msgCb, TD_VID(pVnode), 0, 0, STREAM_EXEC_T_START_ALL_TASKS);
11,713✔
599
        if (code != 0) {
11,713!
600
          tqError("vgId:%d failed to sched stream task, code:%s", vgId, tstrerror(code));
×
601
        }
602
        return;
11,713✔
603
      }
604
    }
605
  } else {
606
    vInfo("vgId:%d, sync restore finished, not launch stream tasks since not leader", vgId);
2,003!
607
  }
608

609
  streamMetaWUnLock(pMeta);
2,009✔
610
}
611

612
static void vnodeBecomeFollower(const SSyncFSM *pFsm) {
5,077✔
613
  SVnode *pVnode = pFsm->data;
5,077✔
614
  vInfo("vgId:%d, become follower", pVnode->config.vgId);
5,077!
615

616
  (void)taosThreadMutexLock(&pVnode->lock);
5,077✔
617
  if (pVnode->blocked) {
5,077!
618
    pVnode->blocked = false;
×
619
    vDebug("vgId:%d, become follower and post block", pVnode->config.vgId);
×
620
    if (tsem_post(&pVnode->syncSem) != 0) {
×
621
      vError("vgId:%d, failed to post sync semaphore", pVnode->config.vgId);
×
622
    }
623
  }
624
  (void)taosThreadMutexUnlock(&pVnode->lock);
5,077✔
625

626
  if (pVnode->pTq) {
5,077!
627
    tqUpdateNodeStage(pVnode->pTq, false);
5,077✔
628
    if (tqStopStreamTasksAsync(pVnode->pTq) != 0) {
5,077!
629
      vError("vgId:%d, failed to stop stream tasks", pVnode->config.vgId);
×
630
    }
631
  }
632
}
5,077✔
633

634
static void vnodeBecomeLearner(const SSyncFSM *pFsm) {
217✔
635
  SVnode *pVnode = pFsm->data;
217✔
636
  vInfo("vgId:%d, become learner", pVnode->config.vgId);
217!
637

638
  (void)taosThreadMutexLock(&pVnode->lock);
217✔
639
  if (pVnode->blocked) {
217!
640
    pVnode->blocked = false;
×
641
    vDebug("vgId:%d, become learner and post block", pVnode->config.vgId);
×
642
    if (tsem_post(&pVnode->syncSem) != 0) {
×
643
      vError("vgId:%d, failed to post sync semaphore", pVnode->config.vgId);
×
644
    }
645
  }
646
  (void)taosThreadMutexUnlock(&pVnode->lock);
217✔
647
}
217✔
648

649
static void vnodeBecomeLeader(const SSyncFSM *pFsm) {
11,719✔
650
  SVnode *pVnode = pFsm->data;
11,719✔
651
  vDebug("vgId:%d, become leader", pVnode->config.vgId);
11,719✔
652
  if (pVnode->pTq) {
11,719!
653
    tqUpdateNodeStage(pVnode->pTq, true);
11,719✔
654
  }
655
}
11,719✔
656

657
static void vnodeBecomeAssignedLeader(const SSyncFSM *pFsm) {
×
658
  SVnode *pVnode = pFsm->data;
×
659
  vDebug("vgId:%d, become assigned leader", pVnode->config.vgId);
×
660
  if (pVnode->pTq) {
×
661
    tqUpdateNodeStage(pVnode->pTq, true);
×
662
  }
663
}
×
664

665
static bool vnodeApplyQueueEmpty(const SSyncFSM *pFsm) {
×
666
  SVnode *pVnode = pFsm->data;
×
667

668
  if (pVnode != NULL && pVnode->msgCb.qsizeFp != NULL) {
×
669
    int32_t itemSize = tmsgGetQueueSize(&pVnode->msgCb, pVnode->config.vgId, APPLY_QUEUE);
×
670
    return (itemSize == 0);
×
671
  } else {
672
    return true;
×
673
  }
674
}
675

676
static int32_t vnodeApplyQueueItems(const SSyncFSM *pFsm) {
190,906✔
677
  SVnode *pVnode = pFsm->data;
190,906✔
678

679
  if (pVnode != NULL && pVnode->msgCb.qsizeFp != NULL) {
190,906✔
680
    int32_t itemSize = tmsgGetQueueSize(&pVnode->msgCb, pVnode->config.vgId, APPLY_QUEUE);
190,904✔
681
    return itemSize;
190,912✔
682
  } else {
683
    return TSDB_CODE_INVALID_PARA;
2✔
684
  }
685
}
686

687
static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
13,901✔
688
  SSyncFSM *pFsm = taosMemoryCalloc(1, sizeof(SSyncFSM));
13,901✔
689
  if (pFsm == NULL) {
13,901!
690
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
691
    return NULL;
×
692
  }
693
  pFsm->data = pVnode;
13,901✔
694
  pFsm->FpCommitCb = vnodeSyncCommitMsg;
13,901✔
695
  pFsm->FpAppliedIndexCb = vnodeSyncAppliedIndex;
13,901✔
696
  pFsm->FpPreCommitCb = vnodeSyncPreCommitMsg;
13,901✔
697
  pFsm->FpRollBackCb = vnodeSyncRollBackMsg;
13,901✔
698
  pFsm->FpGetSnapshot = NULL;
13,901✔
699
  pFsm->FpGetSnapshotInfo = vnodeSyncGetSnapshotInfo;
13,901✔
700
  pFsm->FpRestoreFinishCb = vnodeRestoreFinish;
13,901✔
701
  pFsm->FpLeaderTransferCb = NULL;
13,901✔
702
  pFsm->FpApplyQueueEmptyCb = vnodeApplyQueueEmpty;
13,901✔
703
  pFsm->FpApplyQueueItems = vnodeApplyQueueItems;
13,901✔
704
  pFsm->FpBecomeLeaderCb = vnodeBecomeLeader;
13,901✔
705
  pFsm->FpBecomeAssignedLeaderCb = vnodeBecomeAssignedLeader;
13,901✔
706
  pFsm->FpBecomeFollowerCb = vnodeBecomeFollower;
13,901✔
707
  pFsm->FpBecomeLearnerCb = vnodeBecomeLearner;
13,901✔
708
  pFsm->FpReConfigCb = NULL;
13,901✔
709
  pFsm->FpSnapshotStartRead = vnodeSnapshotStartRead;
13,901✔
710
  pFsm->FpSnapshotStopRead = vnodeSnapshotStopRead;
13,901✔
711
  pFsm->FpSnapshotDoRead = vnodeSnapshotDoRead;
13,901✔
712
  pFsm->FpSnapshotStartWrite = vnodeSnapshotStartWrite;
13,901✔
713
  pFsm->FpSnapshotStopWrite = vnodeSnapshotStopWrite;
13,901✔
714
  pFsm->FpSnapshotDoWrite = vnodeSnapshotDoWrite;
13,901✔
715

716
  return pFsm;
13,901✔
717
}
718

719
int32_t vnodeSyncOpen(SVnode *pVnode, char *path, int32_t vnodeVersion) {
13,899✔
720
  SSyncInfo syncInfo = {
13,899✔
721
      .snapshotStrategy = SYNC_STRATEGY_WAL_FIRST,
722
      .batchSize = 1,
723
      .vgId = pVnode->config.vgId,
13,899✔
724
      .syncCfg = pVnode->config.syncCfg,
725
      .pWal = pVnode->pWal,
13,899✔
726
      .msgcb = &pVnode->msgCb,
13,899✔
727
      .syncSendMSg = vnodeSyncSendMsg,
728
      .syncEqMsg = vnodeSyncEqMsg,
729
      .syncEqCtrlMsg = vnodeSyncEqCtrlMsg,
730
      .pingMs = 5000,
731
      .electMs = 4000,
732
      .heartbeatMs = 700,
733
  };
734

735
  snprintf(syncInfo.path, sizeof(syncInfo.path), "%s%ssync", path, TD_DIRSEP);
13,899✔
736
  syncInfo.pFsm = vnodeSyncMakeFsm(pVnode);
13,899✔
737

738
  SSyncCfg *pCfg = &syncInfo.syncCfg;
13,901✔
739
  vInfo("vgId:%d, start to open sync, replica:%d selfIndex:%d", pVnode->config.vgId, pCfg->replicaNum, pCfg->myIndex);
13,901!
740
  for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) {
34,447✔
741
    SNodeInfo *pNode = &pCfg->nodeInfo[i];
20,546✔
742
    vInfo("vgId:%d, index:%d ep:%s:%u dnode:%d cluster:%" PRId64, pVnode->config.vgId, i, pNode->nodeFqdn,
20,546!
743
          pNode->nodePort, pNode->nodeId, pNode->clusterId);
744
  }
745

746
  pVnode->sync = syncOpen(&syncInfo, vnodeVersion);
13,901✔
747
  if (pVnode->sync <= 0) {
13,901!
748
    vError("vgId:%d, failed to open sync since %s", pVnode->config.vgId, terrstr());
×
749
    return terrno;
×
750
  }
751

752
  return 0;
13,901✔
753
}
754

755
int32_t vnodeSyncStart(SVnode *pVnode) {
13,901✔
756
  vInfo("vgId:%d, start sync", pVnode->config.vgId);
13,901!
757
  int32_t code = syncStart(pVnode->sync);
13,901✔
758
  if (code) {
13,901!
759
    vError("vgId:%d, failed to start sync subsystem since %s", pVnode->config.vgId, tstrerror(code));
×
760
    return code;
×
761
  }
762
  return 0;
13,901✔
763
}
764

765
void vnodeSyncPreClose(SVnode *pVnode) {
13,896✔
766
  vInfo("vgId:%d, sync pre close", pVnode->config.vgId);
13,896!
767
  int32_t code = syncLeaderTransfer(pVnode->sync);
13,901✔
768
  if (code) {
13,901✔
769
    vError("vgId:%d, failed to transfer leader since %s", pVnode->config.vgId, tstrerror(code));
987!
770
  }
771
  syncPreStop(pVnode->sync);
13,901✔
772

773
  (void)taosThreadMutexLock(&pVnode->lock);
13,899✔
774
  if (pVnode->blocked) {
13,893✔
775
    vInfo("vgId:%d, post block after close sync", pVnode->config.vgId);
1!
776
    pVnode->blocked = false;
1✔
777
    if (tsem_post(&pVnode->syncSem) != 0) {
1!
778
      vError("vgId:%d, failed to post block", pVnode->config.vgId);
×
779
    }
780
  }
781
  (void)taosThreadMutexUnlock(&pVnode->lock);
13,893✔
782
}
13,901✔
783

784
void vnodeSyncPostClose(SVnode *pVnode) {
13,900✔
785
  vInfo("vgId:%d, sync post close", pVnode->config.vgId);
13,900!
786
  syncPostStop(pVnode->sync);
13,901✔
787
}
13,900✔
788

789
void vnodeSyncClose(SVnode *pVnode) {
13,901✔
790
  vInfo("vgId:%d, close sync", pVnode->config.vgId);
13,901!
791
  syncStop(pVnode->sync);
13,901✔
792
}
13,897✔
793

794
void vnodeSyncCheckTimeout(SVnode *pVnode) {
31,172✔
795
  vTrace("vgId:%d, check sync timeout msg", pVnode->config.vgId);
31,172✔
796
  (void)taosThreadMutexLock(&pVnode->lock);
31,172✔
797
  if (pVnode->blocked) {
31,172!
UNCOV
798
    int32_t curSec = taosGetTimestampSec();
×
UNCOV
799
    int32_t delta = curSec - pVnode->blockSec;
×
UNCOV
800
    if (delta > VNODE_TIMEOUT_SEC) {
×
801
      vError("vgId:%d, failed to propose since timeout and post block, start:%d cur:%d delta:%d seq:%" PRId64,
×
802
             pVnode->config.vgId, pVnode->blockSec, curSec, delta, pVnode->blockSeq);
803
      if (syncSendTimeoutRsp(pVnode->sync, pVnode->blockSeq) != 0) {
×
804
#if 0
805
        SRpcMsg rpcMsg = {.code = TSDB_CODE_SYN_TIMEOUT, .info = pVnode->blockInfo};
806
        vError("send timeout response since its applyed, seq:%" PRId64 " handle:%p ahandle:%p", pVnode->blockSeq,
807
              rpcMsg.info.handle, rpcMsg.info.ahandle);
808
        rpcSendResponse(&rpcMsg);
809
#endif
810
      }
811
      pVnode->blocked = false;
×
812
      pVnode->blockSec = 0;
×
813
      pVnode->blockSeq = 0;
×
814
      if (tsem_post(&pVnode->syncSem) != 0) {
×
815
        vError("vgId:%d, failed to post block", pVnode->config.vgId);
×
816
      }
817
    }
818
  }
819
  (void)taosThreadMutexUnlock(&pVnode->lock);
31,172✔
820
}
31,172✔
821

822
bool vnodeIsRoleLeader(SVnode *pVnode) {
731,850✔
823
  SSyncState state = syncGetState(pVnode->sync);
731,850✔
824
  return state.state == TAOS_SYNC_STATE_LEADER;
731,980✔
825
}
826

827
bool vnodeIsLeader(SVnode *pVnode) {
16,715✔
828
  terrno = 0;
16,715✔
829
  SSyncState state = syncGetState(pVnode->sync);
16,717✔
830

831
  if (terrno != 0) {
16,718✔
832
    vInfo("vgId:%d, vnode is stopping", pVnode->config.vgId);
2,253!
833
    return false;
2,253✔
834
  }
835

836
  if (state.state != TAOS_SYNC_STATE_LEADER) {
14,465!
837
    terrno = TSDB_CODE_SYN_NOT_LEADER;
×
838
    vInfo("vgId:%d, vnode not leader, state:%s", pVnode->config.vgId, syncStr(state.state));
×
839
    return false;
×
840
  }
841

842
  if (!state.restored || !pVnode->restored) {
14,465!
843
    terrno = TSDB_CODE_SYN_RESTORING;
×
844
    vInfo("vgId:%d, vnode not restored:%d:%d", pVnode->config.vgId, state.restored, pVnode->restored);
×
845
    return false;
×
846
  }
847

848
  return true;
14,465✔
849
}
850

851
int64_t vnodeClusterId(SVnode *pVnode) {
×
852
  SSyncCfg *syncCfg = &pVnode->config.syncCfg;
×
853
  return syncCfg->nodeInfo[syncCfg->myIndex].clusterId;
×
854
}
855

856
int32_t vnodeNodeId(SVnode *pVnode) {
496,129✔
857
  SSyncCfg *syncCfg = &pVnode->config.syncCfg;
496,129✔
858
  return syncCfg->nodeInfo[syncCfg->myIndex].nodeId;
496,129✔
859
}
860

861
int32_t vnodeGetSnapshot(SVnode *pVnode, SSnapshot *pSnap) {
503,578✔
862
  int code = 0;
503,578✔
863
  pSnap->lastApplyIndex = pVnode->state.committed;
503,578✔
864
  pSnap->lastApplyTerm = pVnode->state.commitTerm;
503,578✔
865
  pSnap->lastConfigIndex = -1;
503,578✔
866
  pSnap->state = SYNC_FSM_STATE_COMPLETE;
503,578✔
867

868
  if (tsdbSnapGetFsState(pVnode) != TSDB_FS_STATE_NORMAL) {
503,578!
869
    pSnap->state = SYNC_FSM_STATE_INCOMPLETE;
×
870
  }
871

872
  if (pSnap->type == TDMT_SYNC_PREP_SNAPSHOT || pSnap->type == TDMT_SYNC_PREP_SNAPSHOT_REPLY) {
503,574✔
873
    code = tsdbSnapPrepDescription(pVnode, pSnap);
208✔
874
  }
875
  return code;
503,591✔
876
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc