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

taosdata / TDengine / #4911

04 Jan 2026 09:05AM UTC coverage: 65.028% (-0.8%) from 65.864%
#4911

push

travis-ci

web-flow
merge: from main to 3.0 branch #34156

1206 of 4524 new or added lines in 22 files covered. (26.66%)

1517 existing lines in 134 files now uncovered.

195276 of 300296 relevant lines covered (65.03%)

116931714.52 hits per line

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

51.63
/source/dnode/vnode/src/meta/metaOpen.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 "vnd.h"
18

19
#ifndef NO_UNALIGNED_ACCESS
20
#define TDB_KEY_ALIGN(k1, k2, kType)
21
#else
22
#define TDB_KEY_ALIGN(k1, k2, kType)   \
23
  kType _k1, _k2;                      \
24
  if (((uintptr_t)(k1) & 7)) {         \
25
    memcpy(&_k1, (k1), sizeof(kType)); \
26
    (k1) = &_k1;                       \
27
  }                                    \
28
  if (((uintptr_t)(k2) & 7)) {         \
29
    memcpy(&_k2, (k2), sizeof(kType)); \
30
    (k2) = &_k2;                       \
31
  }
32
#endif
33

34
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
35
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
36
static int ctbIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
37
int        tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
38
static int uidIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
39
static int smaIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
40
static int taskIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
41

42
static int btimeIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
43
static int ncolIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
44

45
static void metaInitLock(SMeta *pMeta) {
3,602,909✔
46
  TdThreadRwlockAttr attr;
3,602,522✔
47
  (void)taosThreadRwlockAttrInit(&attr);
3,603,878✔
48
  (void)taosThreadRwlockAttrSetKindNP(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
3,603,878✔
49
  (void)taosThreadRwlockInit(&pMeta->lock, &attr);
3,603,878✔
50
  (void)taosThreadRwlockAttrDestroy(&attr);
3,603,878✔
51
  return;
3,603,878✔
52
}
53
static void metaDestroyLock(SMeta *pMeta) { (void)taosThreadRwlockDestroy(&pMeta->lock); }
3,603,878✔
54

55
static void metaCleanup(SMeta **ppMeta);
56

57
static void doScan(SMeta *pMeta) {
×
58
  TBC    *cursor = NULL;
×
59
  int32_t code;
60

61
  // open file to write
62
  char path[TSDB_FILENAME_LEN] = {0};
×
63
  snprintf(path, TSDB_FILENAME_LEN - 1, "%s%s", pMeta->path, TD_DIRSEP "scan.txt");
×
64
  TdFilePtr fp = taosOpenFile(path, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
×
65
  if (fp == NULL) {
×
66
    metaError("failed to open file:%s, reason:%s", path, tstrerror(terrno));
×
67
    return;
×
68
  }
69

70
  code = tdbTbcOpen(pMeta->pTbDb, &cursor, NULL);
×
71
  if (code) {
×
72
    if (taosCloseFile(&fp) != 0) {
×
73
      metaError("failed to close file:%s, reason:%s", path, tstrerror(terrno));
×
74
    }
75
    metaError("failed to open table.db cursor, reason:%s", tstrerror(terrno));
×
76
    return;
×
77
  }
78

79
  code = tdbTbcMoveToFirst(cursor);
×
80
  if (code) {
×
81
    if (taosCloseFile(&fp) != 0) {
×
82
      metaError("failed to close file:%s, reason:%s", path, tstrerror(terrno));
×
83
    }
84
    tdbTbcClose(cursor);
×
85
    metaError("failed to move to first, reason:%s", tstrerror(terrno));
×
86
    return;
×
87
  }
88

89
  for (;;) {
×
90
    const void *pKey;
×
91
    int         kLen;
×
92
    const void *pVal;
×
93
    int         vLen;
×
94
    if (tdbTbcGet(cursor, &pKey, &kLen, &pVal, &vLen) < 0) {
×
95
      break;
×
96
    }
97

98
    // decode entry
99
    SDecoder   dc = {0};
×
100
    SMetaEntry me = {0};
×
101

102
    tDecoderInit(&dc, (uint8_t *)pVal, vLen);
×
103

104
    if (metaDecodeEntry(&dc, &me) < 0) {
×
105
      metaError("Failed to decode entry, uid:%" PRId64 ", reason:%s", me.uid, tstrerror(terrno));
×
106
      tDecoderClear(&dc);
×
107
      break;
×
108
    }
109

110
    // skip deleted entry
111
    if (tdbTbGet(pMeta->pUidIdx, &me.uid, sizeof(me.uid), NULL, NULL) == 0) {
×
112
      // print entry
113
      char buf[1024] = {0};
×
114
      if (me.type == TSDB_SUPER_TABLE) {
×
115
        snprintf(buf, sizeof(buf) - 1, "type: super table, version:%" PRId64 " uid: %" PRId64 " name: %s\n", me.version,
×
116
                 me.uid, me.name);
117

118
      } else if (me.type == TSDB_CHILD_TABLE) {
×
119
        snprintf(buf, sizeof(buf) - 1,
×
120
                 "type: child table, version:%" PRId64 " uid: %" PRId64 " name: %s suid:%" PRId64 "\n", me.version,
121
                 me.uid, me.name, me.ctbEntry.suid);
122
      } else {
123
        snprintf(buf, sizeof(buf) - 1, "type: normal table, version:%" PRId64 " uid: %" PRId64 " name: %s\n",
×
124
                 me.version, me.uid, me.name);
125
      }
126

127
      if (taosWriteFile(fp, buf, strlen(buf)) < 0) {
×
128
        metaError("failed to write file:%s, reason:%s", path, tstrerror(terrno));
×
129
        tDecoderClear(&dc);
×
130
        break;
×
131
      }
132
    }
133

134
    tDecoderClear(&dc);
×
135

136
    if (tdbTbcMoveToNext(cursor) < 0) {
×
137
      break;
×
138
    }
139
  }
140

141
  tdbTbcClose(cursor);
×
142

143
  // close file
144
  if (taosFsyncFile(fp) < 0) {
×
145
    metaError("failed to fsync file:%s, reason:%s", path, tstrerror(terrno));
×
146
  }
147
  if (taosCloseFile(&fp) < 0) {
×
148
    metaError("failed to close file:%s, reason:%s", path, tstrerror(terrno));
×
149
  }
150
}
151

152
int32_t metaOpenImpl(SVnode *pVnode, SMeta **ppMeta, const char *metaDir, int8_t rollback) {
3,602,803✔
153
  SMeta  *pMeta = NULL;
3,602,803✔
154
  int32_t code = 0;
3,602,903✔
155
  int32_t lino = 0;
3,602,903✔
156
  int32_t offset;
157
  int32_t pathLen = 0;
3,602,903✔
158
  char    path[TSDB_FILENAME_LEN] = {0};
3,602,903✔
159
  char    indexFullPath[128] = {0};
3,602,903✔
160

161
  // create handle
162
  vnodeGetPrimaryPath(pVnode, false, path, TSDB_FILENAME_LEN);
3,602,903✔
163
  offset = strlen(path);
3,603,878✔
164
  snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
3,603,878✔
165

166
  if (strncmp(metaDir, VNODE_META_TMP_DIR, strlen(VNODE_META_TMP_DIR)) == 0) {
3,603,878✔
167
    taosRemoveDir(path);
1,356✔
168
  }
169

170
  pathLen = strlen(path) + 1;
3,603,878✔
171
  if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + pathLen)) == NULL) {
3,603,878✔
172
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
173
  }
174

175
  metaInitLock(pMeta);
3,603,878✔
176

177
  pMeta->path = (char *)&pMeta[1];
3,603,878✔
178
  tstrncpy(pMeta->path, path, pathLen);
3,603,878✔
179
  int32_t ret = taosRealPath(pMeta->path, NULL, strlen(path) + 1);
3,603,688✔
180

181
  pMeta->pVnode = pVnode;
3,603,347✔
182

183
  // create path if not created yet
184
  code = taosMkDir(pMeta->path);
3,603,416✔
185
  TSDB_CHECK_CODE(code, lino, _exit);
3,602,177✔
186

187
  // open env
188
  code = tdbOpen(pMeta->path, pVnode->config.szPage, pVnode->config.szCache, &pMeta->pEnv, rollback,
3,602,177✔
189
                 &(pVnode->config.tdbEncryptData));
190
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,250✔
191

192
  // open pTbDb
193
  code = tdbTbOpen("table.db", sizeof(STbDbKey), -1, tbDbKeyCmpr, pMeta->pEnv, &pMeta->pTbDb, 0);
3,603,250✔
194
  TSDB_CHECK_CODE(code, lino, _exit);
3,602,375✔
195

196
  // open pSkmDb
197
  code = tdbTbOpen("schema.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmDb, 0);
3,602,375✔
198
  TSDB_CHECK_CODE(code, lino, _exit);
3,602,930✔
199

200
  // open pUidIdx
201
  code = tdbTbOpen("uid.idx", sizeof(tb_uid_t), sizeof(SUidIdxVal), uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pUidIdx, 0);
3,602,930✔
202
  TSDB_CHECK_CODE(code, lino, _exit);
3,602,342✔
203

204
  // open pNameIdx
205
  code = tdbTbOpen("name.idx", -1, sizeof(tb_uid_t), NULL, pMeta->pEnv, &pMeta->pNameIdx, 0);
3,602,342✔
206
  TSDB_CHECK_CODE(code, lino, _exit);
3,602,056✔
207

208
  // open pCtbIdx
209
  code = tdbTbOpen("ctb.idx", sizeof(SCtbIdxKey), -1, ctbIdxKeyCmpr, pMeta->pEnv, &pMeta->pCtbIdx, 0);
3,602,056✔
210
  TSDB_CHECK_CODE(code, lino, _exit);
3,602,827✔
211

212
  // open pSuidIdx
213
  code = tdbTbOpen("suid.idx", sizeof(tb_uid_t), 0, uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pSuidIdx, 0);
3,602,827✔
214
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,544✔
215

216
  (void)tsnprintf(indexFullPath, sizeof(indexFullPath), "%s/%s", pMeta->path, "invert");
3,603,544✔
217
  ret = taosMkDir(indexFullPath);
3,603,371✔
218

219
  SIndexOpts opts = {.cacheSize = 8 * 1024 * 1024};
3,603,544✔
220
  code = indexOpen(&opts, indexFullPath, (SIndex **)&pMeta->pTagIvtIdx);
3,603,544✔
221
  TSDB_CHECK_CODE(code, lino, _exit);
3,602,569✔
222

223
  code = tdbTbOpen("tag.idx", -1, 0, tagIdxKeyCmpr, pMeta->pEnv, &pMeta->pTagIdx, 0);
3,602,569✔
224
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,384✔
225

226
  // open pTtlMgr ("ttlv1.idx")
227
  char logPrefix[128] = {0};
3,603,384✔
228
  (void)tsnprintf(logPrefix, sizeof(logPrefix), "vgId:%d", TD_VID(pVnode));
3,603,384✔
229
  code = ttlMgrOpen(&pMeta->pTtlMgr, pMeta->pEnv, 0, logPrefix, tsTtlFlushThreshold);
3,602,579✔
230
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,878✔
231

232
  // open pSmaIdx
233
  code = tdbTbOpen("sma.idx", sizeof(SSmaIdxKey), 0, smaIdxKeyCmpr, pMeta->pEnv, &pMeta->pSmaIdx, 0);
3,603,878✔
234
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,878✔
235

236
  // idx table create time
237
  code = tdbTbOpen("ctime.idx", sizeof(SBtimeIdxKey), 0, btimeIdxCmpr, pMeta->pEnv, &pMeta->pBtimeIdx, 0);
3,603,878✔
238
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,173✔
239

240
  // idx num of col, normal table only
241
  code = tdbTbOpen("ncol.idx", sizeof(SNcolIdxKey), 0, ncolIdxCmpr, pMeta->pEnv, &pMeta->pNcolIdx, 0);
3,603,173✔
242
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,878✔
243

244
  code = tdbTbOpen("stream.task.db", sizeof(int64_t), -1, taskIdxKeyCmpr, pMeta->pEnv, &pMeta->pStreamDb, 0);
3,603,878✔
245
  TSDB_CHECK_CODE(code, lino, _exit);
3,601,614✔
246

247
  code = metaCacheOpen(pMeta);
3,601,614✔
248
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,181✔
249

250
  code = metaInitTbFilterCache(pMeta);
3,603,181✔
251
  TSDB_CHECK_CODE(code, lino, _exit);
3,603,878✔
252

253
#if 0
254
  // Do NOT remove this code, it is used to do debug stuff
255
  doScan(pMeta);
256
#endif
257

258
_exit:
3,603,878✔
259
  if (code) {
3,603,878✔
260
    metaError("vgId:%d %s failed at %s:%d since %s, path:%s", TD_VID(pVnode), __func__, __FILE__, lino, tstrerror(code),
×
261
              path);
262
    metaCleanup(&pMeta);
×
263
    *ppMeta = NULL;
×
264
  } else {
265
    metaDebug("vgId:%d %s success", TD_VID(pVnode), __func__);
3,603,878✔
266
    *ppMeta = pMeta;
3,603,878✔
267
  }
268
  TAOS_RETURN(code);
3,603,878✔
269
}
270

271
void vnodeGetMetaPath(SVnode *pVnode, const char *metaDir, char *fname) {
10,810,417✔
272
  vnodeGetPrimaryPath(pVnode, false, fname, TSDB_FILENAME_LEN);
10,810,417✔
273
  int32_t offset = strlen(fname);
10,812,712✔
274
  snprintf(fname + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
10,812,712✔
275
}
10,812,712✔
276

277
bool generateNewMeta = false;
278

279
static void metaResetStatisInfo(SMeta *pMeta) {
×
280
  pMeta->pVnode->config.vndStats.numOfSTables = 0;
×
281
  pMeta->pVnode->config.vndStats.numOfCTables = 0;
×
282
  pMeta->pVnode->config.vndStats.numOfNTables = 0;
×
283
  pMeta->pVnode->config.vndStats.numOfVTables = 0;
×
284
  pMeta->pVnode->config.vndStats.numOfVCTables = 0;
×
285
  pMeta->pVnode->config.vndStats.numOfNTimeSeries = 0;
×
286
  pMeta->pVnode->config.vndStats.numOfTimeSeries = 0;
×
287
  pMeta->pVnode->config.vndStats.numOfRSMAs = 0;
×
288
}
×
289

290
static int32_t metaGenerateNewMeta(SMeta **ppMeta) {
×
291
  SMeta  *pNewMeta = NULL;
×
292
  SMeta  *pMeta = *ppMeta;
×
293
  SVnode *pVnode = pMeta->pVnode;
×
294

295
  metaInfo("vgId:%d start to generate new meta", TD_VID(pMeta->pVnode));
×
296

297
  // Reset statistics info
298
  metaResetStatisInfo(pMeta);
×
299

300
  // Open a new meta for organization
301
  int32_t code = metaOpenImpl(pMeta->pVnode, &pNewMeta, VNODE_META_TMP_DIR, false);
×
302
  if (code) {
×
303
    return code;
×
304
  }
305

306
  code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL);
×
307
  if (code) {
×
308
    return code;
×
309
  }
310

311
#if 1
312
  // i == 0, scan super table
313
  // i == 1, scan normal table and child table
314
  for (int i = 0; i < 2; i++) {
×
315
    TBC    *uidCursor = NULL;
×
316
    int32_t counter = 0;
×
317

318
    code = tdbTbcOpen(pMeta->pUidIdx, &uidCursor, NULL);
×
319
    if (code) {
×
320
      metaError("vgId:%d failed to open uid index cursor, reason:%s", TD_VID(pVnode), tstrerror(code));
×
321
      return code;
×
322
    }
323

324
    code = tdbTbcMoveToFirst(uidCursor);
×
325
    if (code) {
×
326
      metaError("vgId:%d failed to move to first, reason:%s", TD_VID(pVnode), tstrerror(code));
×
327
      tdbTbcClose(uidCursor);
×
328
      return code;
×
329
    }
330

331
    for (;;) {
×
332
      const void *pKey;
×
333
      int         kLen;
×
334
      const void *pVal;
×
335
      int         vLen;
×
336

337
      if (tdbTbcGet(uidCursor, &pKey, &kLen, &pVal, &vLen) < 0) {
×
338
        break;
×
339
      }
340

341
      tb_uid_t    uid = *(tb_uid_t *)pKey;
×
342
      SUidIdxVal *pUidIdxVal = (SUidIdxVal *)pVal;
×
343
      if ((i == 0 && (pUidIdxVal->suid && pUidIdxVal->suid == uid))          // super table
×
344
          || (i == 1 && (pUidIdxVal->suid == 0 || pUidIdxVal->suid != uid))  // normal table and child table
×
345
      ) {
346
        counter++;
×
347
        if (i == 0) {
×
348
          metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter, "super", uid);
×
349
        } else {
350
          metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter,
×
351
                   pUidIdxVal->suid == 0 ? "normal" : "child", uid);
352
        }
353

354
        // fetch table entry
355
        void *value = NULL;
×
356
        int   valueSize = 0;
×
357
        if (tdbTbGet(pMeta->pTbDb,
×
358
                     &(STbDbKey){
×
359
                         .version = pUidIdxVal->version,
×
360
                         .uid = uid,
361
                     },
362
                     sizeof(uid), &value, &valueSize) == 0) {
363
          SDecoder   dc = {0};
×
364
          SMetaEntry me = {0};
×
365
          tDecoderInit(&dc, value, valueSize);
×
366
          if (metaDecodeEntry(&dc, &me) == 0) {
×
367
            if (me.type == TSDB_CHILD_TABLE &&
×
368
                tdbTbGet(pMeta->pUidIdx, &me.ctbEntry.suid, sizeof(me.ctbEntry.suid), NULL, NULL) != 0) {
×
369
              metaError("vgId:%d failed to get super table uid:%" PRId64 " for child table uid:%" PRId64,
×
370
                        TD_VID(pVnode), me.ctbEntry.suid, uid);
371
            } else if (metaHandleEntry2(pNewMeta, &me) != 0) {
×
372
              metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), uid);
×
373
            }
374
          }
375
          tDecoderClear(&dc);
×
376
        }
377
        tdbFree(value);
×
378
      }
379

380
      code = tdbTbcMoveToNext(uidCursor);
×
381
      if (code) {
×
382
        metaError("vgId:%d failed to move to next, reason:%s", TD_VID(pVnode), tstrerror(code));
×
383
        return code;
×
384
      }
385
    }
386

387
    tdbTbcClose(uidCursor);
×
388
  }
389
#else
390
  TBC *cursor = NULL;
391

392
  code = tdbTbcOpen(pMeta->pTbDb, &cursor, NULL);
393
  if (code) {
394
    metaError("vgId:%d failed to open table.db cursor, reason:%s", TD_VID(pVnode), tstrerror(code));
395
    return code;
396
  }
397

398
  code = tdbTbcMoveToFirst(cursor);
399
  if (code) {
400
    metaError("vgId:%d failed to move to first, reason:%s", TD_VID(pVnode), tstrerror(code));
401
    tdbTbcClose(cursor);
402
    return code;
403
  }
404

405
  while (true) {
406
    const void *pKey;
407
    int         kLen;
408
    const void *pVal;
409
    int         vLen;
410

411
    if (tdbTbcGet(cursor, &pKey, &kLen, &pVal, &vLen) < 0) {
412
      break;
413
    }
414

415
    STbDbKey  *pKeyEntry = (STbDbKey *)pKey;
416
    SDecoder   dc = {0};
417
    SMetaEntry me = {0};
418

419
    tDecoderInit(&dc, (uint8_t *)pVal, vLen);
420
    if (metaDecodeEntry(&dc, &me) < 0) {
421
      tDecoderClear(&dc);
422
      break;
423
    }
424

425
    if (metaHandleEntry2(pNewMeta, &me) != 0) {
426
      metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), pKeyEntry->uid);
427
      tDecoderClear(&dc);
428
      break;
429
    }
430
    tDecoderClear(&dc);
431

432
    code = tdbTbcMoveToNext(cursor);
433
    if (code) {
434
      metaError("vgId:%d failed to move to next, reason:%s", TD_VID(pVnode), tstrerror(code));
435
      break;
436
    }
437
  }
438

439
  tdbTbcClose(cursor);
440

441
#endif
442

443
  code = metaCommit(pNewMeta, pNewMeta->txn);
×
444
  if (code) {
×
445
    metaError("vgId:%d failed to commit, reason:%s", TD_VID(pVnode), tstrerror(code));
×
446
    return code;
×
447
  }
448

449
  code = metaFinishCommit(pNewMeta, pNewMeta->txn);
×
450
  if (code) {
×
451
    metaError("vgId:%d failed to finish commit, reason:%s", TD_VID(pVnode), tstrerror(code));
×
452
    return code;
×
453
  }
454

455
  if ((code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL)) != 0) {
×
456
    metaError("vgId:%d failed to begin new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
457
  }
458
  metaClose(&pNewMeta);
×
459
  metaInfo("vgId:%d finish to generate new meta", TD_VID(pVnode));
×
460

461
  // Commit the new metadata
462
  char metaDir[TSDB_FILENAME_LEN] = {0};
×
463
  char metaTempDir[TSDB_FILENAME_LEN] = {0};
×
464
  char metaBackupDir[TSDB_FILENAME_LEN] = {0};
×
465

466
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
×
467
  vnodeGetMetaPath(pVnode, VNODE_META_TMP_DIR, metaTempDir);
×
468
  vnodeGetMetaPath(pVnode, VNODE_META_BACKUP_DIR, metaBackupDir);
×
469

470
  metaClose(ppMeta);
×
471
  if (taosRenameFile(metaDir, metaBackupDir) != 0) {
×
472
    metaError("vgId:%d failed to rename old meta to backup, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
473
    return terrno;
×
474
  }
475

476
  // rename the new meta to old meta
477
  if (taosRenameFile(metaTempDir, metaDir) != 0) {
×
478
    metaError("vgId:%d failed to rename new meta to old meta, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
479
    return terrno;
×
480
  }
481

482
  code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, false);
×
483
  if (code) {
×
484
    metaError("vgId:%d failed to open new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
485
    return code;
×
486
  }
487

488
  metaInfo("vgId:%d successfully opened new meta", TD_VID(pVnode));
×
489

490
  return 0;
×
491
}
492

493
int32_t metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
3,599,911✔
494
  int32_t code = TSDB_CODE_SUCCESS;
3,599,911✔
495
  char    metaDir[TSDB_FILENAME_LEN] = {0};
3,599,911✔
496
  char    metaBackupDir[TSDB_FILENAME_LEN] = {0};
3,602,522✔
497
  char    metaTempDir[TSDB_FILENAME_LEN] = {0};
3,602,522✔
498

499
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
3,602,522✔
500
  vnodeGetMetaPath(pVnode, VNODE_META_BACKUP_DIR, metaBackupDir);
3,602,522✔
501
  vnodeGetMetaPath(pVnode, VNODE_META_TMP_DIR, metaTempDir);
3,602,522✔
502

503
  bool metaExists = taosCheckExistFile(metaDir);
3,602,522✔
504
  bool metaBackupExists = taosCheckExistFile(metaBackupDir);
3,602,428✔
505
  bool metaTempExists = taosCheckExistFile(metaTempDir);
3,602,522✔
506

507
  if ((!metaBackupExists && !metaExists && metaTempExists)     //
3,602,060✔
508
      || (metaBackupExists && !metaExists && !metaTempExists)  //
3,602,060✔
509
      || (metaBackupExists && metaExists && metaTempExists)    //
3,602,060✔
510
  ) {
511
    metaError("vgId:%d, invalid meta state, please check!", TD_VID(pVnode));
×
512
    TAOS_RETURN(TSDB_CODE_FAILED);
×
513
  } else if (!metaBackupExists && metaExists && metaTempExists) {
3,602,060✔
514
    taosRemoveDir(metaTempDir);
×
515
  } else if (metaBackupExists && !metaExists && metaTempExists) {
3,602,060✔
516
    code = taosRenameFile(metaTempDir, metaDir);
×
517
    if (code) {
×
518
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
519
      TAOS_RETURN(code);
×
520
    }
521
    taosRemoveDir(metaBackupDir);
×
522
  } else if (metaBackupExists && metaExists && !metaTempExists) {
3,602,060✔
523
    taosRemoveDir(metaBackupDir);
×
524
  }
525

526
  // Do open meta
527
  code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
3,602,060✔
528
  if (code) {
3,601,813✔
529
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
530
    TAOS_RETURN(code);
×
531
  }
532

533
  if (generateNewMeta) {
3,601,813✔
534
    code = metaGenerateNewMeta(ppMeta);
×
535
    if (code) {
×
UNCOV
536
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
UNCOV
537
      TAOS_RETURN(code);
×
538
    }
539
  }
540

541
  return TSDB_CODE_SUCCESS;
3,602,522✔
542
}
543

544
int32_t metaUpgrade(SVnode *pVnode, SMeta **ppMeta) {
3,598,912✔
545
  int32_t code = TSDB_CODE_SUCCESS;
3,598,912✔
546
  int32_t lino;
547
  SMeta  *pMeta = *ppMeta;
3,598,912✔
548

549
  if (ttlMgrNeedUpgrade(pMeta->pEnv)) {
3,598,912✔
550
    code = metaBegin(pMeta, META_BEGIN_HEAP_OS);
×
551
    TSDB_CHECK_CODE(code, lino, _exit);
×
552

553
    code = ttlMgrUpgrade(pMeta->pTtlMgr, pMeta);
×
554
    TSDB_CHECK_CODE(code, lino, _exit);
×
555

556
    code = metaCommit(pMeta, pMeta->txn);
×
557
    TSDB_CHECK_CODE(code, lino, _exit);
×
558
  }
559

560
_exit:
3,598,183✔
561
  if (code) {
3,598,183✔
562
    metaError("vgId:%d %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
563
    metaCleanup(ppMeta);
×
564
  }
565
  return code;
3,598,183✔
566
}
567

568
void metaClose(SMeta **ppMeta) {
3,603,631✔
569
  metaCleanup(ppMeta);
3,603,631✔
570
  return;
3,603,878✔
571
}
572

573
int metaAlterCache(SMeta *pMeta, int32_t nPage) {
4,254✔
574
  int32_t code = 0;
4,254✔
575
  metaWLock(pMeta);
4,254✔
576
  code = tdbAlter(pMeta->pEnv, nPage);
4,254✔
577
  metaULock(pMeta);
4,254✔
578

579
  if (code) {
4,254✔
580
    metaError("vgId:%d %s failed since %s", TD_VID(pMeta->pVnode), __func__, tstrerror(code));
×
581
  }
582
  return code;
4,254✔
583
}
584

585
void metaRLock(SMeta *pMeta) {
2,147,483,647✔
586
  metaTrace("meta rlock %p", &pMeta->lock);
2,147,483,647✔
587
  if (taosThreadRwlockRdlock(&pMeta->lock) != 0) {
2,147,483,647✔
588
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
589
  }
590
}
2,147,483,647✔
591

592
void metaWLock(SMeta *pMeta) {
119,239,826✔
593
  metaTrace("meta wlock %p", &pMeta->lock);
119,239,826✔
594
  if (taosThreadRwlockWrlock(&pMeta->lock) != 0) {
119,239,826✔
595
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
596
  }
597
}
119,240,671✔
598

599
void metaULock(SMeta *pMeta) {
2,147,483,647✔
600
  metaTrace("meta ulock %p", &pMeta->lock);
2,147,483,647✔
601
  if (taosThreadRwlockUnlock(&pMeta->lock) != 0) {
2,147,483,647✔
602
    metaError("vgId:%d failed to unlock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
603
  }
604
}
2,147,483,647✔
605

606
static void metaCleanup(SMeta **ppMeta) {
3,602,790✔
607
  SMeta *pMeta = *ppMeta;
3,602,790✔
608
  if (pMeta) {
3,603,631✔
609
    metaInfo("vgId:%d meta clean up, path:%s", TD_VID(pMeta->pVnode), pMeta->path);
3,603,596✔
610
    if (pMeta->pEnv) metaAbort(pMeta);
3,603,843✔
611
    if (pMeta->pCache) metaCacheClose(pMeta);
3,603,878✔
612
#ifdef BUILD_NO_CALL
613
    if (pMeta->pIdx) metaCloseIdx(pMeta);
614
#endif
615
    if (pMeta->pStreamDb) tdbTbClose(pMeta->pStreamDb);
3,604,135✔
616
    if (pMeta->pNcolIdx) tdbTbClose(pMeta->pNcolIdx);
3,603,878✔
617
    if (pMeta->pBtimeIdx) tdbTbClose(pMeta->pBtimeIdx);
3,603,878✔
618
    if (pMeta->pSmaIdx) tdbTbClose(pMeta->pSmaIdx);
3,603,878✔
619
    if (pMeta->pTtlMgr) ttlMgrClose(pMeta->pTtlMgr);
3,603,878✔
620
    if (pMeta->pTagIvtIdx) indexClose(pMeta->pTagIvtIdx);
3,603,878✔
621
    if (pMeta->pTagIdx) tdbTbClose(pMeta->pTagIdx);
3,603,878✔
622
    if (pMeta->pCtbIdx) tdbTbClose(pMeta->pCtbIdx);
3,603,878✔
623
    if (pMeta->pSuidIdx) tdbTbClose(pMeta->pSuidIdx);
3,603,878✔
624
    if (pMeta->pNameIdx) tdbTbClose(pMeta->pNameIdx);
3,603,878✔
625
    if (pMeta->pUidIdx) tdbTbClose(pMeta->pUidIdx);
3,603,878✔
626
    if (pMeta->pSkmDb) tdbTbClose(pMeta->pSkmDb);
3,603,878✔
627
    if (pMeta->pTbDb) tdbTbClose(pMeta->pTbDb);
3,603,878✔
628
    if (pMeta->pEnv) tdbClose(pMeta->pEnv);
3,603,878✔
629
    metaDestroyLock(pMeta);
3,603,878✔
630

631
    taosMemoryFreeClear(*ppMeta);
3,603,878✔
632
  }
633
}
3,603,913✔
634

635
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
2,147,483,647✔
636
  STbDbKey *pTbDbKey1 = (STbDbKey *)pKey1;
2,147,483,647✔
637
  STbDbKey *pTbDbKey2 = (STbDbKey *)pKey2;
2,147,483,647✔
638

639
  TDB_KEY_ALIGN(pTbDbKey1, pTbDbKey2, STbDbKey);
640

641
  if (pTbDbKey1->version > pTbDbKey2->version) {
2,147,483,647✔
642
    return 1;
2,147,483,647✔
643
  } else if (pTbDbKey1->version < pTbDbKey2->version) {
2,147,483,647✔
644
    return -1;
2,147,483,647✔
645
  }
646

647
  if (pTbDbKey1->uid > pTbDbKey2->uid) {
2,147,483,647✔
648
    return 1;
438,614,089✔
649
  } else if (pTbDbKey1->uid < pTbDbKey2->uid) {
1,888,137,830✔
650
    return -1;
361,186,084✔
651
  }
652

653
  return 0;
1,526,976,918✔
654
}
655

656
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
744,830,159✔
657
  SSkmDbKey *pSkmDbKey1 = (SSkmDbKey *)pKey1;
744,830,159✔
658
  SSkmDbKey *pSkmDbKey2 = (SSkmDbKey *)pKey2;
744,830,159✔
659

660
  TDB_KEY_ALIGN(pSkmDbKey1, pSkmDbKey2, SSkmDbKey);
661

662
  if (pSkmDbKey1->uid > pSkmDbKey2->uid) {
744,830,159✔
663
    return 1;
345,218,960✔
664
  } else if (pSkmDbKey1->uid < pSkmDbKey2->uid) {
400,345,769✔
665
    return -1;
219,810,209✔
666
  }
667

668
  if (pSkmDbKey1->sver > pSkmDbKey2->sver) {
180,557,383✔
669
    return 1;
80,432,908✔
670
  } else if (pSkmDbKey1->sver < pSkmDbKey2->sver) {
100,123,203✔
671
    return -1;
22,843,640✔
672
  }
673

674
  return 0;
77,284,111✔
675
}
676

677
static int uidIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
2,147,483,647✔
678
  tb_uid_t uid1 = taosGetInt64Aligned((int64_t*)pKey1);
2,147,483,647✔
679
  tb_uid_t uid2 = taosGetInt64Aligned((int64_t*)pKey2);
2,147,483,647✔
680

681
  if (uid1 > uid2) {
2,147,483,647✔
682
    return 1;
2,147,483,647✔
683
  } else if (uid1 < uid2) {
2,147,483,647✔
684
    return -1;
1,265,743,716✔
685
  }
686

687
  return 0;
890,458,804✔
688
}
689

690
static int ctbIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
971,474,563✔
691
  SCtbIdxKey *pCtbIdxKey1 = (SCtbIdxKey *)pKey1;
971,474,563✔
692
  SCtbIdxKey *pCtbIdxKey2 = (SCtbIdxKey *)pKey2;
971,474,563✔
693

694
  TDB_KEY_ALIGN(pCtbIdxKey1, pCtbIdxKey2, SCtbIdxKey);
695

696
  if (pCtbIdxKey1->suid > pCtbIdxKey2->suid) {
971,474,563✔
697
    return 1;
119,954,504✔
698
  } else if (pCtbIdxKey1->suid < pCtbIdxKey2->suid) {
851,598,703✔
699
    return -1;
33,345,128✔
700
  }
701

702
  if (pCtbIdxKey1->uid > pCtbIdxKey2->uid) {
818,266,504✔
703
    return 1;
415,144,575✔
704
  } else if (pCtbIdxKey1->uid < pCtbIdxKey2->uid) {
403,159,719✔
705
    return -1;
348,473,264✔
706
  }
707

708
  return 0;
54,668,755✔
709
}
710

711
int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
600,555,206✔
712
  STagIdxKey *pTagIdxKey1 = (STagIdxKey *)pKey1;
600,555,206✔
713
  STagIdxKey *pTagIdxKey2 = (STagIdxKey *)pKey2;
600,555,206✔
714
  tb_uid_t    uid1 = 0, uid2 = 0;
600,555,206✔
715
  int         c;
716

717
  TDB_KEY_ALIGN(pTagIdxKey1, pTagIdxKey2, STagIdxKey);
718

719
  // compare suid
720
  if (pTagIdxKey1->suid > pTagIdxKey2->suid) {
600,555,206✔
721
    return 1;
1,748,221✔
722
  } else if (pTagIdxKey1->suid < pTagIdxKey2->suid) {
598,842,131✔
723
    return -1;
11,273,068✔
724
  }
725

726
  // compare column id
727
  if (pTagIdxKey1->cid > pTagIdxKey2->cid) {
587,563,667✔
728
    return 1;
2,285,586✔
729
  } else if (pTagIdxKey1->cid < pTagIdxKey2->cid) {
585,278,025✔
730
    return -1;
649,295✔
731
  }
732

733
  if (pTagIdxKey1->type != pTagIdxKey2->type) {
584,639,234✔
734
    metaError("meta/open: incorrect tag idx type.");
×
735
    return TSDB_CODE_FAILED;
×
736
  }
737

738
  // check NULL, NULL is always the smallest
739
  if (pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
584,634,625✔
740
    return -1;
157,052✔
741
  } else if (!pTagIdxKey1->isNull && pTagIdxKey2->isNull) {
584,486,244✔
742
    return 1;
674,435✔
743
  } else if (!pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
583,807,850✔
744
    // all not NULL, compr tag vals
745
    __compar_fn_t func = getComparFunc(pTagIdxKey1->type, 0);
574,121,030✔
746
    if (func == NULL) {
574,129,408✔
747
      metaError("meta/open: %s", terrstr());
×
748
      return TSDB_CODE_FAILED;
×
749
    }
750
    c = func(pTagIdxKey1->data, pTagIdxKey2->data);
574,129,408✔
751
    if (c) return c;
574,123,839✔
752
  }
753

754
  // both null or tag values are equal, then continue to compare uids
755
  if (IS_VAR_DATA_TYPE(pTagIdxKey1->type)) {
87,774,694✔
756
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + varDataTLen(pTagIdxKey1->data));
45,517,562✔
757
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + varDataTLen(pTagIdxKey2->data));
45,518,104✔
758
  } else {
759
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + tDataTypes[pTagIdxKey1->type].bytes);
42,241,441✔
760
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + tDataTypes[pTagIdxKey2->type].bytes);
42,240,769✔
761
  }
762

763
  // compare uid
764
  if (uid1 < uid2) {
87,756,640✔
765
    return -1;
8,511,317✔
766
  } else if (uid1 > uid2) {
79,245,323✔
767
    return 1;
70,733,801✔
768
  } else {
769
    return 0;
8,511,522✔
770
  }
771

772
  return 0;
773
}
774

775
static int btimeIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
239,207,422✔
776
  SBtimeIdxKey *pBtimeIdxKey1 = (SBtimeIdxKey *)pKey1;
239,207,422✔
777
  SBtimeIdxKey *pBtimeIdxKey2 = (SBtimeIdxKey *)pKey2;
239,207,422✔
778

779
  TDB_KEY_ALIGN(pBtimeIdxKey1, pBtimeIdxKey2, SBtimeIdxKey);
780

781
  if (pBtimeIdxKey1->btime > pBtimeIdxKey2->btime) {
239,207,422✔
782
    return 1;
217,684,844✔
783
  } else if (pBtimeIdxKey1->btime < pBtimeIdxKey2->btime) {
21,529,230✔
784
    return -1;
1,778,020✔
785
  }
786

787
  if (pBtimeIdxKey1->uid > pBtimeIdxKey2->uid) {
19,750,791✔
788
    return 1;
17,585,065✔
789
  } else if (pBtimeIdxKey1->uid < pBtimeIdxKey2->uid) {
2,165,856✔
790
    return -1;
83,973✔
791
  }
792

793
  return 0;
2,081,417✔
794
}
795

796
static int ncolIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
797
  SNcolIdxKey *pNcolIdxKey1 = (SNcolIdxKey *)pKey1;
×
798
  SNcolIdxKey *pNcolIdxKey2 = (SNcolIdxKey *)pKey2;
×
799

800
  TDB_KEY_ALIGN(pNcolIdxKey1, pNcolIdxKey2, SNcolIdxKey);
801

802
  if (pNcolIdxKey1->ncol > pNcolIdxKey2->ncol) {
×
803
    return 1;
×
804
  } else if (pNcolIdxKey1->ncol < pNcolIdxKey2->ncol) {
×
805
    return -1;
×
806
  }
807

808
  if (pNcolIdxKey1->uid > pNcolIdxKey2->uid) {
×
809
    return 1;
×
810
  } else if (pNcolIdxKey1->uid < pNcolIdxKey2->uid) {
×
811
    return -1;
×
812
  }
813

814
  return 0;
×
815
}
816

817
static int smaIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
818
  SSmaIdxKey *pSmaIdxKey1 = (SSmaIdxKey *)pKey1;
×
819
  SSmaIdxKey *pSmaIdxKey2 = (SSmaIdxKey *)pKey2;
×
820

821
  TDB_KEY_ALIGN(pSmaIdxKey1, pSmaIdxKey2, SSmaIdxKey);
822

823
  if (pSmaIdxKey1->uid > pSmaIdxKey2->uid) {
×
824
    return 1;
×
825
  } else if (pSmaIdxKey1->uid < pSmaIdxKey2->uid) {
×
826
    return -1;
×
827
  }
828

829
  if (pSmaIdxKey1->smaUid > pSmaIdxKey2->smaUid) {
×
830
    return 1;
×
831
  } else if (pSmaIdxKey1->smaUid < pSmaIdxKey2->smaUid) {
×
832
    return -1;
×
833
  }
834

835
  return 0;
×
836
}
837

838
static int taskIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
839
  int32_t uid1 = *(int32_t *)pKey1;
×
840
  int32_t uid2 = *(int32_t *)pKey2;
×
841

842
  if (uid1 > uid2) {
×
843
    return 1;
×
844
  } else if (uid1 < uid2) {
×
845
    return -1;
×
846
  }
847

848
  return 0;
×
849
}
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