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

taosdata / TDengine / #4987

16 Mar 2026 12:26PM UTC coverage: 73.883% (+36.6%) from 37.305%
#4987

push

travis-ci

web-flow
feat: support secure delete option. (#34591)

209 of 391 new or added lines in 24 files covered. (53.45%)

3062 existing lines in 140 files now uncovered.

261133 of 353439 relevant lines covered (73.88%)

121262425.02 hits per line

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

79.68
/source/dnode/vnode/src/vnd/vnodeCommit.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
#include "meta.h"
17
#include "sync.h"
18
#include "tencrypt.h"
19
#include "vnd.h"
20
#include "vnodeInt.h"
21

22
extern int32_t tsdbPreCommit(STsdb *pTsdb);
23
extern int32_t tsdbCommitBegin(STsdb *pTsdb, SCommitInfo *pInfo);
24
extern int32_t tsdbCommitCommit(STsdb *pTsdb);
25
extern int32_t tsdbCommitAbort(STsdb *pTsdb);
26

27
#define VND_INFO_FNAME_TMP "vnode_tmp.json"
28

29
static int vnodeEncodeInfo(const SVnodeInfo *pInfo, char **ppData);
30
static int vnodeCommitImpl(SCommitInfo *pInfo);
31

32
#define WAIT_TIME_MILI_SEC 10  // miliseconds
33

34
static int32_t vnodeTryRecycleBufPool(SVnode *pVnode) {
×
35
  int32_t code = 0;
×
36

37
  if (pVnode->onRecycle == NULL) {
×
38
    if (pVnode->recycleHead == NULL) {
×
39
      vDebug("vgId:%d, no recyclable buffer pool", TD_VID(pVnode));
×
40
      goto _exit;
×
41
    } else {
42
      vDebug("vgId:%d, buffer pool %p of id %d on recycle queue, try to recycle", TD_VID(pVnode), pVnode->recycleHead,
×
43
             pVnode->recycleHead->id);
44

45
      pVnode->onRecycle = pVnode->recycleHead;
×
46
      if (pVnode->recycleHead == pVnode->recycleTail) {
×
47
        pVnode->recycleHead = pVnode->recycleTail = NULL;
×
48
      } else {
49
        pVnode->recycleHead = pVnode->recycleHead->recycleNext;
×
50
        pVnode->recycleHead->recyclePrev = NULL;
×
51
      }
52
      pVnode->onRecycle->recycleNext = pVnode->onRecycle->recyclePrev = NULL;
×
53
    }
54
  }
55

56
  code = vnodeBufPoolRecycle(pVnode->onRecycle);
×
57
  if (code) goto _exit;
×
58

59
_exit:
×
60
  if (code) {
×
61
    vError("vgId:%d, %s failed since %s", TD_VID(pVnode), __func__, tstrerror(code));
×
62
  }
63
  return code;
×
64
}
65
static int32_t vnodeGetBufPoolToUse(SVnode *pVnode) {
9,497,073✔
66
  int32_t code = 0;
9,497,073✔
67
  int32_t lino = 0;
9,497,073✔
68

69
  (void)taosThreadMutexLock(&pVnode->mutex);
9,497,073✔
70

71
  int32_t nTry = 0;
9,499,171✔
72
  for (;;) {
73
    ++nTry;
9,499,171✔
74

75
    if (pVnode->freeList) {
9,499,171✔
76
      vDebug("vgId:%d, allocate free buffer pool on %d try, pPool:%p id:%d", TD_VID(pVnode), nTry, pVnode->freeList,
9,499,171✔
77
             pVnode->freeList->id);
78

79
      pVnode->inUse = pVnode->freeList;
9,499,171✔
80
      pVnode->inUse->nRef = 1;
9,499,171✔
81
      pVnode->freeList = pVnode->inUse->freeNext;
9,499,171✔
82
      pVnode->inUse->freeNext = NULL;
9,499,171✔
83
      break;
9,499,171✔
84
    } else {
85
      vDebug("vgId:%d, no free buffer pool on %d try, try to recycle...", TD_VID(pVnode), nTry);
×
86

87
      code = vnodeTryRecycleBufPool(pVnode);
×
88
      TSDB_CHECK_CODE(code, lino, _exit);
×
89

90
      if (pVnode->freeList == NULL) {
×
91
        vDebug("vgId:%d, no free buffer pool on %d try, wait %d ms...", TD_VID(pVnode), nTry, WAIT_TIME_MILI_SEC);
×
92

UNCOV
93
        struct timeval  tv;
×
UNCOV
94
        struct timespec ts;
×
95
        if (taosGetTimeOfDay(&tv) != 0) {
×
96
          continue;
×
97
        }
98
        ts.tv_nsec = tv.tv_usec * 1000 + WAIT_TIME_MILI_SEC * 1000000;
×
99
        if (ts.tv_nsec > 999999999l) {
×
100
          ts.tv_sec = tv.tv_sec + 1;
×
101
          ts.tv_nsec -= 1000000000l;
×
102
        } else {
103
          ts.tv_sec = tv.tv_sec;
×
104
        }
105

106
        code = taosThreadCondTimedWait(&pVnode->poolNotEmpty, &pVnode->mutex, &ts);
×
107
        // ignore timeout error and retry
108
        if (code == TSDB_CODE_TIMEOUT_ERROR) {
×
109
          code = TSDB_CODE_SUCCESS;
×
110
        }
111
        TSDB_CHECK_CODE(code, lino, _exit);
×
112
      }
113
    }
114
  }
115

116
_exit:
9,499,171✔
117
  (void)taosThreadMutexUnlock(&pVnode->mutex);
9,499,171✔
118
  if (code) {
9,499,171✔
119
    vError("vgId:%d, %s failed at line %d since %s", TD_VID(pVnode), __func__, lino, tstrerror(code));
×
120
  }
121
  return code;
9,499,171✔
122
}
123
int vnodeBegin(SVnode *pVnode) {
9,499,171✔
124
  int32_t code = 0;
9,499,171✔
125
  int32_t lino = 0;
9,499,171✔
126

127
  // alloc buffer pool
128
  code = vnodeGetBufPoolToUse(pVnode);
9,499,171✔
129
  TSDB_CHECK_CODE(code, lino, _exit);
9,499,171✔
130

131
  // begin meta
132
  code = metaBegin(pVnode->pMeta, META_BEGIN_HEAP_BUFFERPOOL);
9,499,171✔
133
  TSDB_CHECK_CODE(code, lino, _exit);
9,496,640✔
134

135
  // begin tsdb
136
  code = tsdbBegin(pVnode->pTsdb);
9,496,640✔
137
  TSDB_CHECK_CODE(code, lino, _exit);
9,498,218✔
138

139
_exit:
9,498,218✔
140
  if (code) {
9,498,218✔
141
    terrno = code;
×
142
    vError("vgId:%d, %s failed at line %d since %s", TD_VID(pVnode), __func__, lino, tstrerror(code));
×
143
  }
144
  return code;
9,498,551✔
145
}
146

147
int vnodeShouldCommit(SVnode *pVnode, bool atExit) {
623,371,422✔
148
  bool diskAvail = osDataSpaceAvailable();
623,371,422✔
149
  bool needCommit = false;
623,374,996✔
150

151
  (void)taosThreadMutexLock(&pVnode->mutex);
623,374,996✔
152
  if (pVnode->inUse && diskAvail) {
623,381,705✔
153
    needCommit = (pVnode->inUse->size > pVnode->inUse->node.size) ||
626,680,638✔
154
                 (atExit && (pVnode->inUse->size > 0 || pVnode->pMeta->changed ||
3,301,124✔
155
                             pVnode->state.applied - pVnode->state.committed > 4096));
1,384,047✔
156
  }
157
  vTrace("vgId:%d, should commit:%d, disk available:%d, buffer size:%" PRId64 ", node size:%" PRId64
623,376,340✔
158
         ", meta changed:%d"
159
         ", state:[%" PRId64 ",%" PRId64 "]",
160
         TD_VID(pVnode), needCommit, diskAvail, pVnode->inUse ? pVnode->inUse->size : 0,
161
         pVnode->inUse ? pVnode->inUse->node.size : 0, pVnode->pMeta->changed, pVnode->state.applied,
162
         pVnode->state.committed);
163
  (void)taosThreadMutexUnlock(&pVnode->mutex);
623,376,340✔
164
  return needCommit;
623,381,067✔
165
}
166

167
int vnodeSaveInfo(const char *dir, const SVnodeInfo *pInfo) {
9,180,432✔
168
  int32_t   code = 0;
9,180,432✔
169
  int32_t   lino;
170
  char      fname[TSDB_FILENAME_LEN];
9,177,324✔
171
  char     *data = NULL;
9,181,184✔
172

173
  snprintf(fname, TSDB_FILENAME_LEN, "%s%s%s", dir, TD_DIRSEP, VND_INFO_FNAME_TMP);
9,181,184✔
174

175
  code = vnodeEncodeInfo(pInfo, &data);
9,181,184✔
176
  TSDB_CHECK_CODE(code, lino, _exit);
9,179,222✔
177

178
  int32_t len = strlen(data);
9,179,222✔
179
  
180
  // Use encrypted write if tsCfgKey is enabled
181
  code = taosWriteCfgFile(fname, data, len);
9,179,222✔
182
  if (code != 0) {
9,164,775✔
183
    TSDB_CHECK_CODE(code, lino, _exit);
×
184
  }
185

186
_exit:
9,164,775✔
187
  if (code) {
9,165,051✔
188
    vError("vgId:%d %s failed at %s:%d since %s", pInfo->config.vgId, __func__, __FILE__, lino, tstrerror(code));
×
189
  } else {
190
    vInfo("vgId:%d, vnode info is saved, fname:%s replica:%d selfIndex:%d changeVersion:%d", pInfo->config.vgId, fname,
9,165,051✔
191
          pInfo->config.syncCfg.replicaNum, pInfo->config.syncCfg.myIndex, pInfo->config.syncCfg.changeVersion);
192
  }
193
  taosMemoryFree(data);
9,182,468✔
194
  TAOS_RETURN(code);
9,182,136✔
195
}
196

197
int vnodeCommitInfo(const char *dir) {
9,182,257✔
198
  char fname[TSDB_FILENAME_LEN];
9,179,149✔
199
  char tfname[TSDB_FILENAME_LEN];
9,179,149✔
200

201
  snprintf(fname, TSDB_FILENAME_LEN, "%s%s%s", dir, TD_DIRSEP, VND_INFO_FNAME);
9,182,257✔
202
  snprintf(tfname, TSDB_FILENAME_LEN, "%s%s%s", dir, TD_DIRSEP, VND_INFO_FNAME_TMP);
9,182,257✔
203

204
  int32_t code = taosRenameFile(tfname, fname);
9,182,257✔
205
  if (code < 0) {
9,180,672✔
206
    return code;
×
207
  }
208

209
  vInfo("vnode info is committed, dir:%s", dir);
9,180,672✔
210
  return 0;
9,182,257✔
211
}
212

213
int vnodeLoadInfo(const char *dir, SVnodeInfo *pInfo) {
8,104,823✔
214
  int32_t   code = 0;
8,104,823✔
215
  int32_t   lino;
216
  char      fname[TSDB_FILENAME_LEN];
8,099,597✔
217
  char     *pData = NULL;
8,108,039✔
218
  int32_t   dataLen = 0;
8,108,039✔
219

220
  if (taosWaitCfgKeyLoaded() != 0) {
8,108,039✔
221
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
222
  }
223

224
  snprintf(fname, TSDB_FILENAME_LEN, "%s%s%s", dir, TD_DIRSEP, VND_INFO_FNAME);
8,107,854✔
225

226
  // Use taosReadCfgFile for automatic decryption support (returns null-terminated string)
227
  code = taosReadCfgFile(fname, &pData, &dataLen);
8,107,854✔
228
  if (code != 0) {
8,104,111✔
229
    TSDB_CHECK_CODE(code, lino, _exit);
3,068,851✔
230
  }
231

232
  // decode info
233
  code = vnodeDecodeInfo(pData, pInfo);
5,035,260✔
234
  TSDB_CHECK_CODE(code, lino, _exit);
5,035,883✔
235

236
  pInfo->config.walCfg.committed = pInfo->state.committed;
5,035,883✔
237
_exit:
8,105,466✔
238
  if (code) {
8,107,294✔
239
    vError("vgId:%d %s failed at %s:%d since %s, file:%s", pInfo->config.vgId, __func__, __FILE__, lino,
3,068,851✔
240
           tstrerror(code), fname);
241
  }
242
  taosMemoryFree(pData);
8,106,489✔
243
  return code;
8,102,967✔
244
}
245

246
static int32_t vnodePrepareCommit(SVnode *pVnode, SCommitInfo *pInfo) {
5,272,457✔
247
  int32_t code = 0;
5,272,457✔
248
  int32_t lino = 0;
5,272,457✔
249
  char    dir[TSDB_FILENAME_LEN] = {0};
5,272,457✔
250
  int64_t lastCommitted = pInfo->info.state.committed;
5,272,457✔
251

252
  // wait last commit task
253
  vnodeAWait(&pVnode->commitTask);
5,271,332✔
254

255
  code = syncNodeGetConfig(pVnode->sync, &pVnode->config.syncCfg);
5,272,457✔
256
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,251✔
257

258
  pVnode->state.commitTerm = pVnode->state.applyTerm;
5,272,251✔
259

260
  pInfo->info.config = pVnode->config;
5,272,457✔
261
  pInfo->info.state.committed = pVnode->state.applied;
5,272,251✔
262
  pInfo->info.state.commitTerm = pVnode->state.applyTerm;
5,272,457✔
263
  pInfo->info.state.commitID = ++pVnode->state.commitID;
5,272,457✔
264
  pInfo->pVnode = pVnode;
5,271,873✔
265
  pInfo->txn = metaGetTxn(pVnode->pMeta);
5,271,873✔
266

267
  // save info
268
  vnodeGetPrimaryPath(pVnode, false, dir, TSDB_FILENAME_LEN);
5,271,794✔
269

270
  vDebug("vgId:%d, save config while prepare commit", TD_VID(pVnode));
5,271,794✔
271
  code = vnodeSaveInfo(dir, &pInfo->info);
5,272,533✔
272
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,457✔
273

274
  code = tsdbPreCommit(pVnode->pTsdb);
5,272,457✔
275
  TSDB_CHECK_CODE(code, lino, _exit);
5,271,729✔
276

277
  code = metaPrepareAsyncCommit(pVnode->pMeta);
5,271,729✔
278
  TSDB_CHECK_CODE(code, lino, _exit);
5,270,407✔
279

280
  (void)taosThreadMutexLock(&pVnode->mutex);
5,270,407✔
281
  pVnode->onCommit = pVnode->inUse;
5,271,547✔
282
  pVnode->inUse = NULL;
5,268,961✔
283
  (void)taosThreadMutexUnlock(&pVnode->mutex);
5,264,696✔
284

285
_exit:
5,269,762✔
286
  if (code) {
5,269,762✔
287
    vError("vgId:%d, %s failed at line %d since %s, commit id:%" PRId64, TD_VID(pVnode), __func__, lino,
×
288
           tstrerror(code), pVnode->state.commitID);
289
  } else {
290
    vDebug("vgId:%d, %s done, commit id:%" PRId64, TD_VID(pVnode), __func__, pInfo->info.state.commitID);
5,269,762✔
291
  }
292

293
  return code;
5,275,736✔
294
}
295
static void vnodeReturnBufPool(SVnode *pVnode) {
5,272,457✔
296
  (void)taosThreadMutexLock(&pVnode->mutex);
5,272,457✔
297

298
  SVBufPool *pPool = pVnode->onCommit;
5,272,457✔
299
  int32_t    nRef = atomic_sub_fetch_32(&pPool->nRef, 1);
5,272,457✔
300

301
  pVnode->onCommit = NULL;
5,272,457✔
302
  if (nRef == 0) {
5,272,457✔
303
    vnodeBufPoolAddToFreeList(pPool);
5,222,560✔
304
  } else if (nRef > 0) {
49,897✔
305
    vDebug("vgId:%d, buffer pool %p of id %d is added to recycle queue", TD_VID(pVnode), pPool, pPool->id);
49,897✔
306

307
    if (pVnode->recycleTail == NULL) {
49,897✔
308
      pPool->recyclePrev = pPool->recycleNext = NULL;
49,897✔
309
      pVnode->recycleHead = pVnode->recycleTail = pPool;
49,897✔
310
    } else {
311
      pPool->recyclePrev = pVnode->recycleTail;
×
312
      pPool->recycleNext = NULL;
×
313
      pVnode->recycleTail->recycleNext = pPool;
×
314
      pVnode->recycleTail = pPool;
×
315
    }
316
  } else {
317
    vError("vgId:%d, buffer pool %p of id %d nRef:%d", TD_VID(pVnode), pPool, pPool->id, nRef);
×
318
  }
319

320
  (void)taosThreadMutexUnlock(&pVnode->mutex);
5,272,457✔
321
}
5,272,457✔
322
static int32_t vnodeCommit(void *arg) {
5,272,457✔
323
  int32_t code = 0;
5,272,457✔
324

325
  SCommitInfo *pInfo = (SCommitInfo *)arg;
5,272,457✔
326
  SVnode      *pVnode = pInfo->pVnode;
5,272,457✔
327

328
  // commit
329
  METRICS_TIMING_BLOCK(pVnode->writeMetrics.commit_time, METRIC_LEVEL_HIGH, {
5,272,457✔
330
    if ((code = vnodeCommitImpl(pInfo))) {
331
      vFatal("vgId:%d, failed to commit vnode since %s", TD_VID(pVnode), terrstr());
332
      taosMsleep(100);
333
      exit(EXIT_FAILURE);
334
      goto _exit;
335
    }
336
  });
337

338
  METRICS_UPDATE(pVnode->writeMetrics.commit_count, METRIC_LEVEL_HIGH, 1);
5,272,457✔
339

340
  vnodeReturnBufPool(pVnode);
5,272,457✔
341

342
_exit:
5,272,457✔
343
  taosMemoryFree(arg);
5,272,457✔
344
  return code;
5,272,457✔
345
}
346

347
static void vnodeCommitCancel(void *arg) { taosMemoryFree(arg); }
×
348

349
int vnodeAsyncCommitEx(SVnode *pVnode, bool forceTrim) {
5,271,794✔
350
  int32_t code = 0;
5,271,794✔
351
  int32_t lino = 0;
5,271,794✔
352

353
  SCommitInfo *pInfo = (SCommitInfo *)taosMemoryCalloc(1, sizeof(*pInfo));
5,271,794✔
354
  if (NULL == pInfo) {
5,271,903✔
355
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
356
  }
357

358
  pInfo->forceTrim = forceTrim;
5,271,903✔
359

360
  // prepare to commit
361
  code = vnodePrepareCommit(pVnode, pInfo);
5,271,903✔
362
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,221✔
363

364
  // schedule the task
365
  code = vnodeAsync(COMMIT_TASK_ASYNC, EVA_PRIORITY_HIGH, vnodeCommit, vnodeCommitCancel, pInfo, &pVnode->commitTask);
5,272,221✔
366
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,457✔
367

368
_exit:
5,272,457✔
369
  if (code) {
5,272,457✔
370
    taosMemoryFree(pInfo);
×
371
    vError("vgId:%d %s failed at line %d since %s" PRId64, TD_VID(pVnode), __func__, lino, tstrerror(code));
×
372
  } else {
373
    vInfo("vgId:%d, vnode async commit done, commitId:%" PRId64 " term:%" PRId64 " applied:%" PRId64 " forceTrim:%d",
5,272,457✔
374
          TD_VID(pVnode), pVnode->state.commitID, pVnode->state.applyTerm, pVnode->state.applied, forceTrim);
375
  }
376
  return code;
5,272,457✔
377
}
378

379
int vnodeAsyncCommit(SVnode *pVnode, bool forceTrimWal) { return vnodeAsyncCommitEx(pVnode, forceTrimWal); }
5,271,794✔
380

381
int32_t vnodeSyncCommit(SVnode *pVnode) {
58,695✔
382
  int32_t lino;
383
  int32_t code = vnodeAsyncCommit(pVnode, false);
58,695✔
384
  TSDB_CHECK_CODE(code, lino, _exit);
58,695✔
385
  vnodeAWait(&pVnode->commitTask);
58,695✔
386

387
_exit:
58,695✔
388
  if (code) {
58,695✔
389
    vError("vgId:%d, %s failed at line %d since %s", TD_VID(pVnode), __func__, lino, tstrerror(code));
×
390
  } else {
391
    vInfo("vgId:%d, sync commit end", TD_VID(pVnode));
58,695✔
392
  }
393

394
  return code;
58,695✔
395
}
396

397
static int vnodeCommitImpl(SCommitInfo *pInfo) {
5,272,457✔
398
  int32_t code = 0;
5,272,457✔
399
  int32_t lino = 0;
5,272,457✔
400

401
  char    dir[TSDB_FILENAME_LEN] = {0};
5,272,457✔
402
  SVnode *pVnode = pInfo->pVnode;
5,272,457✔
403

404
  vInfo("vgId:%d, start to commit, commitId:%" PRId64 " version:%" PRId64 " term: %" PRId64, TD_VID(pVnode),
5,272,457✔
405
        pInfo->info.state.commitID, pInfo->info.state.committed, pInfo->info.state.commitTerm);
406

407
  // persist wal before starting
408
  if ((code = walPersist(pVnode->pWal)) < 0) {
5,272,457✔
409
    vError("vgId:%d, failed to persist wal since %s", TD_VID(pVnode), tstrerror(code));
×
410
    return code;
×
411
  }
412

413
  vnodeGetPrimaryPath(pVnode, false, dir, TSDB_FILENAME_LEN);
5,272,457✔
414

415
  code = syncBeginSnapshot(pVnode->sync, pInfo->info.state.committed);
5,272,457✔
416
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,457✔
417

418
  code = tsdbCommitBegin(pVnode->pTsdb, pInfo);
5,272,457✔
419
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,457✔
420

421
  if (!TSDB_CACHE_NO(pVnode->config)) {
5,272,457✔
422
    METRICS_TIMING_BLOCK(pVnode->writeMetrics.last_cache_commit_time, METRIC_LEVEL_HIGH,
76,260✔
423
                         { code = tsdbCacheCommit(pVnode->pTsdb); });
424
    METRICS_UPDATE(pVnode->writeMetrics.last_cache_commit_count, METRIC_LEVEL_HIGH, 1);
76,260✔
425
    TSDB_CHECK_CODE(code, lino, _exit);
76,260✔
426
  }
427

428
  // blob storage engine commit
429
  code = bseCommit(pVnode->pBse);
5,272,457✔
430
  // commit info
431
  code = vnodeCommitInfo(dir);
5,272,457✔
432
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,457✔
433

434
  code = tsdbCommitCommit(pVnode->pTsdb);
5,272,457✔
435
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,457✔
436

437
  code = metaFinishCommit(pVnode->pMeta, pInfo->txn);
5,272,457✔
438
  TSDB_CHECK_CODE(code, lino, _exit);
5,271,965✔
439

440
  pVnode->state.committed = pInfo->info.state.committed;
5,271,965✔
441

442
  code = syncEndSnapshot(pVnode->sync, pInfo->forceTrim);
5,271,830✔
443
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,457✔
444

445
  code = tqCommitOffset(pVnode->pTq);
5,272,457✔
446
  TSDB_CHECK_CODE(code, lino, _exit);
5,272,457✔
447
  
448
_exit:
5,272,457✔
449
  if (code) {
5,272,457✔
450
    vError("vgId:%d, %s failed at line %d since %s", TD_VID(pVnode), __func__, lino, tstrerror(code));
×
451
  } else {
452
    vInfo("vgId:%d, commit end", TD_VID(pVnode));
5,272,457✔
453
  }
454
  return code;
5,272,457✔
455
}
456

457
bool vnodeShouldRollback(SVnode *pVnode) {
4,227,416✔
458
  char    tFName[TSDB_FILENAME_LEN] = {0};
4,227,416✔
459
  int32_t offset = 0;
4,227,416✔
460

461
  vnodeGetPrimaryPath(pVnode, false, tFName, TSDB_FILENAME_LEN);
4,227,416✔
462
  offset = strlen(tFName);
4,226,807✔
463
  snprintf(tFName + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, VND_INFO_FNAME_TMP);
4,226,807✔
464

465
  return taosCheckExistFile(tFName);
4,226,807✔
466
}
467

468
void vnodeRollback(SVnode *pVnode) {
211✔
469
  char    tFName[TSDB_FILENAME_LEN] = {0};
211✔
470
  int32_t offset = 0;
211✔
471

472
  vnodeGetPrimaryPath(pVnode, false, tFName, TSDB_FILENAME_LEN);
211✔
473
  offset = strlen(tFName);
211✔
474
  snprintf(tFName + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, VND_INFO_FNAME_TMP);
211✔
475

476
  if (taosRemoveFile(tFName) != 0) {
211✔
477
    vError("vgId:%d, failed to remove file %s since %s", TD_VID(pVnode), tFName, tstrerror(terrno));
×
478
  }
479
}
211✔
480

481
static int vnodeEncodeState(const void *pObj, SJson *pJson) {
9,181,275✔
482
  const SVState *pState = (SVState *)pObj;
9,181,275✔
483

484
  TAOS_CHECK_RETURN(tjsonAddIntegerToObject(pJson, "commit version", pState->committed));
9,181,275✔
485
  TAOS_CHECK_RETURN(tjsonAddIntegerToObject(pJson, "commit ID", pState->commitID));
9,180,387✔
486
  TAOS_CHECK_RETURN(tjsonAddIntegerToObject(pJson, "commit term", pState->commitTerm));
9,181,232✔
487

488
  return 0;
9,178,636✔
489
}
490

491
static int vnodeDecodeState(const SJson *pJson, void *pObj) {
5,068,810✔
492
  SVState *pState = (SVState *)pObj;
5,068,810✔
493

494
  int32_t code;
495
  tjsonGetNumberValue(pJson, "commit version", pState->committed, code);
5,068,810✔
496
  if (code) return code;
5,068,625✔
497
  tjsonGetNumberValue(pJson, "commit ID", pState->commitID, code);
5,068,625✔
498
  if (code) return code;
5,068,032✔
499
  tjsonGetNumberValue(pJson, "commit term", pState->commitTerm, code);
5,068,032✔
500
  if (code) return code;
5,067,625✔
501

502
  return 0;
5,067,625✔
503
}
504

505
static int vnodeEncodeInfo(const SVnodeInfo *pInfo, char **ppData) {
9,178,900✔
506
  int32_t code = 0;
9,178,900✔
507
  int32_t lino;
508
  SJson  *pJson = NULL;
9,178,900✔
509
  char   *pData = NULL;
9,178,900✔
510

511
  pJson = tjsonCreateObject();
9,178,900✔
512
  if (pJson == NULL) {
9,182,468✔
513
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
514
  }
515

516
  code = tjsonAddObject(pJson, "config", vnodeEncodeConfig, (void *)&pInfo->config);
9,182,468✔
517
  TSDB_CHECK_CODE(code, lino, _exit);
9,181,754✔
518

519
  code = tjsonAddObject(pJson, "state", vnodeEncodeState, (void *)&pInfo->state);
9,181,754✔
520
  TSDB_CHECK_CODE(code, lino, _exit);
9,182,468✔
521

522
  pData = tjsonToString(pJson);
9,182,468✔
523
  if (pData == NULL) {
9,182,468✔
524
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
525
  }
526

527
  tjsonDelete(pJson);
9,182,468✔
528

529
_exit:
9,178,302✔
530
  if (code) {
9,178,302✔
531
    tjsonDelete(pJson);
×
532
    *ppData = NULL;
×
533
  } else {
534
    *ppData = pData;
9,178,302✔
535
  }
536
  return code;
9,179,418✔
537
}
538

539
int vnodeDecodeInfo(uint8_t *pData, SVnodeInfo *pInfo) {
5,064,993✔
540
  int32_t code = 0;
5,064,993✔
541
  int32_t lino;
542
  SJson  *pJson = NULL;
5,064,993✔
543

544
  pJson = tjsonParse(pData);
5,064,993✔
545
  if (pJson == NULL) {
5,069,187✔
546
    TSDB_CHECK_CODE(code = TSDB_CODE_INVALID_DATA_FMT, lino, _exit);
×
547
  }
548

549
  code = tjsonToObject(pJson, "config", vnodeDecodeConfig, (void *)&pInfo->config);
5,069,187✔
550
  TSDB_CHECK_CODE(code, lino, _exit);
5,068,664✔
551

552
  code = tjsonToObject(pJson, "state", vnodeDecodeState, (void *)&pInfo->state);
5,068,664✔
553
  TSDB_CHECK_CODE(code, lino, _exit);
5,068,288✔
554

555
_exit:
5,068,288✔
556
  tjsonDelete(pJson);
5,068,288✔
557
  return code;
5,067,927✔
558
}
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

© 2026 Coveralls, Inc