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

taosdata / TDengine / #4800

16 Oct 2025 09:19AM UTC coverage: 53.935% (-7.1%) from 61.083%
#4800

push

travis-ci

web-flow
Merge b32e3a393 into a190048d5

134724 of 323629 branches covered (41.63%)

Branch coverage included in aggregate %.

184803 of 268802 relevant lines covered (68.75%)

69058627.2 hits per line

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

45.19
/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) {
1,435,872✔
46
  TdThreadRwlockAttr attr;
1,435,755✔
47
  (void)taosThreadRwlockAttrInit(&attr);
1,435,872✔
48
  (void)taosThreadRwlockAttrSetKindNP(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
1,435,634!
49
  (void)taosThreadRwlockInit(&pMeta->lock, &attr);
1,435,853✔
50
  (void)taosThreadRwlockAttrDestroy(&attr);
1,435,853✔
51
  return;
1,435,629✔
52
}
53
static void metaDestroyLock(SMeta *pMeta) { (void)taosThreadRwlockDestroy(&pMeta->lock); }
1,436,119✔
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
      tDecoderClear(&dc);
×
106
      break;
×
107
    }
108

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

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

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

133
    tDecoderClear(&dc);
×
134

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

140
  tdbTbcClose(cursor);
×
141

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

151
int32_t metaOpenImpl(SVnode *pVnode, SMeta **ppMeta, const char *metaDir, int8_t rollback) {
1,435,406✔
152
  SMeta  *pMeta = NULL;
1,435,406✔
153
  int32_t code = 0;
1,435,872✔
154
  int32_t lino = 0;
1,435,872✔
155
  int32_t offset;
156
  int32_t pathLen = 0;
1,435,872✔
157
  char    path[TSDB_FILENAME_LEN] = {0};
1,435,872✔
158
  char    indexFullPath[128] = {0};
1,436,068✔
159

160
  // create handle
161
  vnodeGetPrimaryPath(pVnode, false, path, TSDB_FILENAME_LEN);
1,435,301✔
162
  offset = strlen(path);
1,436,119✔
163
  snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
1,436,119✔
164

165
  if (strncmp(metaDir, VNODE_META_TMP_DIR, strlen(VNODE_META_TMP_DIR)) == 0) {
1,436,119!
166
    taosRemoveDir(path);
×
167
  }
168

169
  pathLen = strlen(path) + 1;
1,436,119✔
170
  if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + pathLen)) == NULL) {
1,436,119!
171
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
172
  }
173

174
  metaInitLock(pMeta);
1,435,872✔
175

176
  pMeta->path = (char *)&pMeta[1];
1,435,853✔
177
  tstrncpy(pMeta->path, path, pathLen);
1,435,853!
178
  int32_t ret = taosRealPath(pMeta->path, NULL, strlen(path) + 1);
1,435,852✔
179

180
  pMeta->pVnode = pVnode;
1,435,321✔
181

182
  // create path if not created yet
183
  code = taosMkDir(pMeta->path);
1,435,330✔
184
  TSDB_CHECK_CODE(code, lino, _exit);
1,436,119!
185

186
  // open env
187
  code = tdbOpen(pMeta->path, pVnode->config.szPage, pVnode->config.szCache, &pMeta->pEnv, rollback,
1,436,119✔
188
                 pVnode->config.tdbEncryptAlgorithm, pVnode->config.tdbEncryptKey);
1,436,119✔
189
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,593!
190

191
  // open pTbDb
192
  code = tdbTbOpen("table.db", sizeof(STbDbKey), -1, tbDbKeyCmpr, pMeta->pEnv, &pMeta->pTbDb, 0);
1,435,593✔
193
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,440!
194

195
  // open pSkmDb
196
  code = tdbTbOpen("schema.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmDb, 0);
1,435,440✔
197
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,860!
198

199
  // open pUidIdx
200
  code = tdbTbOpen("uid.idx", sizeof(tb_uid_t), sizeof(SUidIdxVal), uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pUidIdx, 0);
1,435,860✔
201
  TSDB_CHECK_CODE(code, lino, _exit);
1,436,105!
202

203
  // open pNameIdx
204
  code = tdbTbOpen("name.idx", -1, sizeof(tb_uid_t), NULL, pMeta->pEnv, &pMeta->pNameIdx, 0);
1,436,105✔
205
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,185!
206

207
  // open pCtbIdx
208
  code = tdbTbOpen("ctb.idx", sizeof(SCtbIdxKey), -1, ctbIdxKeyCmpr, pMeta->pEnv, &pMeta->pCtbIdx, 0);
1,435,185✔
209
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,260!
210

211
  // open pSuidIdx
212
  code = tdbTbOpen("suid.idx", sizeof(tb_uid_t), 0, uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pSuidIdx, 0);
1,435,260✔
213
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,874!
214

215
  (void)tsnprintf(indexFullPath, sizeof(indexFullPath), "%s/%s", pMeta->path, "invert");
1,435,874✔
216
  ret = taosMkDir(indexFullPath);
1,435,979✔
217

218
  SIndexOpts opts = {.cacheSize = 8 * 1024 * 1024};
1,435,595✔
219
  code = indexOpen(&opts, indexFullPath, (SIndex **)&pMeta->pTagIvtIdx);
1,435,595✔
220
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,198!
221

222
  code = tdbTbOpen("tag.idx", -1, 0, tagIdxKeyCmpr, pMeta->pEnv, &pMeta->pTagIdx, 0);
1,435,198✔
223
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,774!
224

225
  // open pTtlMgr ("ttlv1.idx")
226
  char logPrefix[128] = {0};
1,435,774✔
227
  (void)tsnprintf(logPrefix, sizeof(logPrefix), "vgId:%d", TD_VID(pVnode));
1,436,019✔
228
  code = ttlMgrOpen(&pMeta->pTtlMgr, pMeta->pEnv, 0, logPrefix, tsTtlFlushThreshold);
1,436,019✔
229
  TSDB_CHECK_CODE(code, lino, _exit);
1,436,119!
230

231
  // open pSmaIdx
232
  code = tdbTbOpen("sma.idx", sizeof(SSmaIdxKey), 0, smaIdxKeyCmpr, pMeta->pEnv, &pMeta->pSmaIdx, 0);
1,436,119✔
233
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,379!
234

235
  // idx table create time
236
  code = tdbTbOpen("ctime.idx", sizeof(SBtimeIdxKey), 0, btimeIdxCmpr, pMeta->pEnv, &pMeta->pBtimeIdx, 0);
1,435,379✔
237
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,874!
238

239
  // idx num of col, normal table only
240
  code = tdbTbOpen("ncol.idx", sizeof(SNcolIdxKey), 0, ncolIdxCmpr, pMeta->pEnv, &pMeta->pNcolIdx, 0);
1,435,874✔
241
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,806!
242

243
  code = tdbTbOpen("stream.task.db", sizeof(int64_t), -1, taskIdxKeyCmpr, pMeta->pEnv, &pMeta->pStreamDb, 0);
1,435,806✔
244
  TSDB_CHECK_CODE(code, lino, _exit);
1,436,119!
245

246
  code = metaCacheOpen(pMeta);
1,436,119✔
247
  TSDB_CHECK_CODE(code, lino, _exit);
1,436,119!
248

249
  code = metaInitTbFilterCache(pMeta);
1,436,119✔
250
  TSDB_CHECK_CODE(code, lino, _exit);
1,435,800!
251

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

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

270
void vnodeGetMetaPath(SVnode *pVnode, const char *metaDir, char *fname) {
4,307,297✔
271
  vnodeGetPrimaryPath(pVnode, false, fname, TSDB_FILENAME_LEN);
4,307,297✔
272
  int32_t offset = strlen(fname);
4,307,891!
273
  snprintf(fname + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
4,307,891✔
274
}
4,308,119✔
275

276
bool generateNewMeta = false;
277

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

438
  tdbTbcClose(cursor);
439

440
#endif
441

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

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

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

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

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

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

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

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

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

489
  return 0;
×
490
}
491

492
int32_t metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
1,435,620✔
493
  int32_t code = TSDB_CODE_SUCCESS;
1,435,620✔
494
  char    metaDir[TSDB_FILENAME_LEN] = {0};
1,435,620✔
495
  char    metaBackupDir[TSDB_FILENAME_LEN] = {0};
1,436,119✔
496
  char    metaTempDir[TSDB_FILENAME_LEN] = {0};
1,436,119✔
497

498
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
1,436,119✔
499
  vnodeGetMetaPath(pVnode, VNODE_META_BACKUP_DIR, metaBackupDir);
1,436,119✔
500
  vnodeGetMetaPath(pVnode, VNODE_META_TMP_DIR, metaTempDir);
1,436,119✔
501

502
  bool metaExists = taosCheckExistFile(metaDir);
1,436,119✔
503
  bool metaBackupExists = taosCheckExistFile(metaBackupDir);
1,436,119✔
504
  bool metaTempExists = taosCheckExistFile(metaTempDir);
1,436,119✔
505

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

525
  // Do open meta
526
  code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
1,436,119✔
527
  if (code) {
1,435,800!
528
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
529
    TAOS_RETURN(code);
×
530
  }
531

532
  if (generateNewMeta) {
1,435,800!
533
    code = metaGenerateNewMeta(ppMeta);
×
534
    if (code) {
×
535
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
536
      TAOS_RETURN(code);
×
537
    }
538
  }
539

540
  return TSDB_CODE_SUCCESS;
1,435,800✔
541
}
542

543
int32_t metaUpgrade(SVnode *pVnode, SMeta **ppMeta) {
1,436,119✔
544
  int32_t code = TSDB_CODE_SUCCESS;
1,436,119✔
545
  int32_t lino;
546
  SMeta  *pMeta = *ppMeta;
1,436,119✔
547

548
  if (ttlMgrNeedUpgrade(pMeta->pEnv)) {
1,436,119!
549
    code = metaBegin(pMeta, META_BEGIN_HEAP_OS);
×
550
    TSDB_CHECK_CODE(code, lino, _exit);
×
551

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

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

559
_exit:
1,436,119✔
560
  if (code) {
1,436,119!
561
    metaError("vgId:%d %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
562
    metaCleanup(ppMeta);
×
563
  }
564
  return code;
1,435,988✔
565
}
566

567
void metaClose(SMeta **ppMeta) {
1,436,119✔
568
  metaCleanup(ppMeta);
1,436,119✔
569
  return;
1,436,119✔
570
}
571

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

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

584
void metaRLock(SMeta *pMeta) {
817,654,248✔
585
  metaTrace("meta rlock %p", &pMeta->lock);
817,654,248✔
586
  if (taosThreadRwlockRdlock(&pMeta->lock) != 0) {
817,654,248!
587
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
588
  }
589
}
817,800,360✔
590

591
void metaWLock(SMeta *pMeta) {
34,502,911✔
592
  metaTrace("meta wlock %p", &pMeta->lock);
34,502,911✔
593
  if (taosThreadRwlockWrlock(&pMeta->lock) != 0) {
34,502,911!
594
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
595
  }
596
}
34,510,223✔
597

598
void metaULock(SMeta *pMeta) {
852,137,112✔
599
  metaTrace("meta ulock %p", &pMeta->lock);
852,137,112✔
600
  if (taosThreadRwlockUnlock(&pMeta->lock) != 0) {
852,137,343!
601
    metaError("vgId:%d failed to unlock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
602
  }
603
}
852,131,157✔
604

605
static void metaCleanup(SMeta **ppMeta) {
1,435,859✔
606
  SMeta *pMeta = *ppMeta;
1,435,859✔
607
  if (pMeta) {
1,436,000!
608
    metaInfo("vgId:%d meta clean up, path:%s", TD_VID(pMeta->pVnode), pMeta->path);
1,436,000✔
609
    if (pMeta->pEnv) metaAbort(pMeta);
1,436,511!
610
    if (pMeta->pCache) metaCacheClose(pMeta);
1,436,119!
611
#ifdef BUILD_NO_CALL
612
    if (pMeta->pIdx) metaCloseIdx(pMeta);
613
#endif
614
    if (pMeta->pStreamDb) tdbTbClose(pMeta->pStreamDb);
1,436,119!
615
    if (pMeta->pNcolIdx) tdbTbClose(pMeta->pNcolIdx);
1,436,119!
616
    if (pMeta->pBtimeIdx) tdbTbClose(pMeta->pBtimeIdx);
1,436,119!
617
    if (pMeta->pSmaIdx) tdbTbClose(pMeta->pSmaIdx);
1,436,119!
618
    if (pMeta->pTtlMgr) ttlMgrClose(pMeta->pTtlMgr);
1,436,119!
619
    if (pMeta->pTagIvtIdx) indexClose(pMeta->pTagIvtIdx);
1,436,119!
620
    if (pMeta->pTagIdx) tdbTbClose(pMeta->pTagIdx);
1,436,119!
621
    if (pMeta->pCtbIdx) tdbTbClose(pMeta->pCtbIdx);
1,436,119!
622
    if (pMeta->pSuidIdx) tdbTbClose(pMeta->pSuidIdx);
1,436,119!
623
    if (pMeta->pNameIdx) tdbTbClose(pMeta->pNameIdx);
1,436,037✔
624
    if (pMeta->pUidIdx) tdbTbClose(pMeta->pUidIdx);
1,436,119!
625
    if (pMeta->pSkmDb) tdbTbClose(pMeta->pSkmDb);
1,436,037!
626
    if (pMeta->pTbDb) tdbTbClose(pMeta->pTbDb);
1,436,037!
627
    if (pMeta->pEnv) tdbClose(pMeta->pEnv);
1,436,037✔
628
    metaDestroyLock(pMeta);
1,436,201✔
629

630
    taosMemoryFreeClear(*ppMeta);
1,436,119!
631
  }
632
}
1,436,119✔
633

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

638
  TDB_KEY_ALIGN(pTbDbKey1, pTbDbKey2, STbDbKey);
639

640
  if (pTbDbKey1->version > pTbDbKey2->version) {
2,147,483,647✔
641
    return 1;
1,013,179,407✔
642
  } else if (pTbDbKey1->version < pTbDbKey2->version) {
1,173,254,883✔
643
    return -1;
727,382,621✔
644
  }
645

646
  if (pTbDbKey1->uid > pTbDbKey2->uid) {
445,928,287✔
647
    return 1;
9,338,487✔
648
  } else if (pTbDbKey1->uid < pTbDbKey2->uid) {
436,572,326✔
649
    return -1;
413,380✔
650
  }
651

652
  return 0;
436,168,729✔
653
}
654

655
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
74,230,791✔
656
  SSkmDbKey *pSkmDbKey1 = (SSkmDbKey *)pKey1;
74,230,791✔
657
  SSkmDbKey *pSkmDbKey2 = (SSkmDbKey *)pKey2;
74,230,791✔
658

659
  TDB_KEY_ALIGN(pSkmDbKey1, pSkmDbKey2, SSkmDbKey);
660

661
  if (pSkmDbKey1->uid > pSkmDbKey2->uid) {
74,230,791✔
662
    return 1;
20,473,252✔
663
  } else if (pSkmDbKey1->uid < pSkmDbKey2->uid) {
53,777,004✔
664
    return -1;
10,800,742✔
665
  }
666

667
  if (pSkmDbKey1->sver > pSkmDbKey2->sver) {
42,975,167✔
668
    return 1;
29,895,025✔
669
  } else if (pSkmDbKey1->sver < pSkmDbKey2->sver) {
13,079,254✔
670
    return -1;
873,669✔
671
  }
672

673
  return 0;
12,203,737✔
674
}
675

676
static int uidIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
1,476,056,936✔
677
  tb_uid_t uid1 = taosGetInt64Aligned((int64_t*)pKey1);
1,476,121,914✔
678
  tb_uid_t uid2 = taosGetInt64Aligned((int64_t*)pKey2);
1,476,179,967✔
679

680
  if (uid1 > uid2) {
1,476,179,967✔
681
    return 1;
845,265,308✔
682
  } else if (uid1 < uid2) {
630,914,659✔
683
    return -1;
367,041,188✔
684
  }
685

686
  return 0;
263,873,471✔
687
}
688

689
static int ctbIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
180,802,890✔
690
  SCtbIdxKey *pCtbIdxKey1 = (SCtbIdxKey *)pKey1;
180,802,890✔
691
  SCtbIdxKey *pCtbIdxKey2 = (SCtbIdxKey *)pKey2;
180,802,890✔
692

693
  TDB_KEY_ALIGN(pCtbIdxKey1, pCtbIdxKey2, SCtbIdxKey);
694

695
  if (pCtbIdxKey1->suid > pCtbIdxKey2->suid) {
180,802,890✔
696
    return 1;
8,529,291✔
697
  } else if (pCtbIdxKey1->suid < pCtbIdxKey2->suid) {
172,332,992✔
698
    return -1;
2,112,185✔
699
  }
700

701
  if (pCtbIdxKey1->uid > pCtbIdxKey2->uid) {
170,235,322✔
702
    return 1;
88,853,186✔
703
  } else if (pCtbIdxKey1->uid < pCtbIdxKey2->uid) {
81,398,448✔
704
    return -1;
61,605,721✔
705
  }
706

707
  return 0;
19,783,586✔
708
}
709

710
int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
93,775,178✔
711
  STagIdxKey *pTagIdxKey1 = (STagIdxKey *)pKey1;
93,775,178✔
712
  STagIdxKey *pTagIdxKey2 = (STagIdxKey *)pKey2;
93,775,178✔
713
  tb_uid_t    uid1 = 0, uid2 = 0;
93,775,178✔
714
  int         c;
715

716
  TDB_KEY_ALIGN(pTagIdxKey1, pTagIdxKey2, STagIdxKey);
717

718
  // compare suid
719
  if (pTagIdxKey1->suid > pTagIdxKey2->suid) {
93,775,178✔
720
    return 1;
1,710,266✔
721
  } else if (pTagIdxKey1->suid < pTagIdxKey2->suid) {
92,069,838✔
722
    return -1;
863,547✔
723
  }
724

725
  // compare column id
726
  if (pTagIdxKey1->cid > pTagIdxKey2->cid) {
91,204,732✔
727
    return 1;
1,395,786✔
728
  } else if (pTagIdxKey1->cid < pTagIdxKey2->cid) {
89,807,314✔
729
    return -1;
398,238✔
730
  }
731

732
  if (pTagIdxKey1->type != pTagIdxKey2->type) {
89,411,246!
733
    metaError("meta/open: incorrect tag idx type.");
×
734
    return TSDB_CODE_FAILED;
×
735
  }
736

737
  // check NULL, NULL is always the smallest
738
  if (pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
89,410,502✔
739
    return -1;
199,268✔
740
  } else if (!pTagIdxKey1->isNull && pTagIdxKey2->isNull) {
89,212,492✔
741
    return 1;
683,756✔
742
  } else if (!pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
88,528,291✔
743
    // all not NULL, compr tag vals
744
    __compar_fn_t func = getComparFunc(pTagIdxKey1->type, 0);
80,788,801✔
745
    if (func == NULL) {
80,789,658!
746
      metaError("meta/open: %s", terrstr());
×
747
      return TSDB_CODE_FAILED;
×
748
    }
749
    c = func(pTagIdxKey1->data, pTagIdxKey2->data);
80,789,658✔
750
    if (c) return c;
80,786,365✔
751
  }
752

753
  // both null or tag values are equal, then continue to compare uids
754
  if (IS_VAR_DATA_TYPE(pTagIdxKey1->type)) {
17,799,754!
755
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + varDataTLen(pTagIdxKey1->data));
3,420,846✔
756
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + varDataTLen(pTagIdxKey2->data));
3,420,846✔
757
  } else {
758
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + tDataTypes[pTagIdxKey1->type].bytes);
14,380,438✔
759
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + tDataTypes[pTagIdxKey2->type].bytes);
14,380,065✔
760
  }
761

762
  // compare uid
763
  if (uid1 < uid2) {
17,800,709✔
764
    return -1;
1,323,377✔
765
  } else if (uid1 > uid2) {
16,477,332✔
766
    return 1;
10,983,522✔
767
  } else {
768
    return 0;
5,493,810✔
769
  }
770

771
  return 0;
772
}
773

774
static int btimeIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
65,112,414✔
775
  SBtimeIdxKey *pBtimeIdxKey1 = (SBtimeIdxKey *)pKey1;
65,112,414✔
776
  SBtimeIdxKey *pBtimeIdxKey2 = (SBtimeIdxKey *)pKey2;
65,112,414✔
777

778
  TDB_KEY_ALIGN(pBtimeIdxKey1, pBtimeIdxKey2, SBtimeIdxKey);
779

780
  if (pBtimeIdxKey1->btime > pBtimeIdxKey2->btime) {
65,112,414✔
781
    return 1;
50,418,481✔
782
  } else if (pBtimeIdxKey1->btime < pBtimeIdxKey2->btime) {
14,694,132✔
783
    return -1;
2,460,995✔
784
  }
785

786
  if (pBtimeIdxKey1->uid > pBtimeIdxKey2->uid) {
12,233,137✔
787
    return 1;
7,460,818✔
788
  } else if (pBtimeIdxKey1->uid < pBtimeIdxKey2->uid) {
4,772,314✔
789
    return -1;
4,888✔
790
  }
791

792
  return 0;
4,767,426✔
793
}
794

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

799
  TDB_KEY_ALIGN(pNcolIdxKey1, pNcolIdxKey2, SNcolIdxKey);
800

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

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

813
  return 0;
×
814
}
815

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

820
  TDB_KEY_ALIGN(pSmaIdxKey1, pSmaIdxKey2, SSmaIdxKey);
821

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

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

834
  return 0;
×
835
}
836

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

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

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