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

taosdata / TDengine / #3558

17 Dec 2024 06:05AM UTC coverage: 59.778% (+1.6%) from 58.204%
#3558

push

travis-ci

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

merge: form main to 3.0 branch

132787 of 287595 branches covered (46.17%)

Branch coverage included in aggregate %.

104 of 191 new or added lines in 5 files covered. (54.45%)

6085 existing lines in 168 files now uncovered.

209348 of 284746 relevant lines covered (73.52%)

8164844.48 hits per line

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

40.56
/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
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
20
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
21
static int ctbIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
22
int        tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
23
static int uidIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
24
static int smaIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
25
static int taskIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
26

27
static int btimeIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
28
static int ncolIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
29

30
static void metaInitLock(SMeta *pMeta) {
10,125✔
31
  TdThreadRwlockAttr attr;
32
  (void)taosThreadRwlockAttrInit(&attr);
10,125✔
33
  (void)taosThreadRwlockAttrSetKindNP(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
10,129✔
34
  (void)taosThreadRwlockInit(&pMeta->lock, &attr);
10,129✔
35
  (void)taosThreadRwlockAttrDestroy(&attr);
10,133✔
36
  return;
10,129✔
37
}
38
static void metaDestroyLock(SMeta *pMeta) { (void)taosThreadRwlockDestroy(&pMeta->lock); }
10,146✔
39

40
static void metaCleanup(SMeta **ppMeta);
41

42
static void doScan(SMeta *pMeta) {
×
43
  TBC    *cursor = NULL;
×
44
  int32_t code;
45

46
  // open file to write
47
  char path[TSDB_FILENAME_LEN] = {0};
×
48
  snprintf(path, TSDB_FILENAME_LEN - 1, "%s%s", pMeta->path, TD_DIRSEP "scan.txt");
×
49
  TdFilePtr fp = taosOpenFile(path, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
×
50
  if (fp == NULL) {
×
51
    metaError("failed to open file:%s, reason:%s", path, tstrerror(terrno));
×
52
    return;
×
53
  }
54

55
  code = tdbTbcOpen(pMeta->pTbDb, &cursor, NULL);
×
56
  if (code) {
×
57
    if (taosCloseFile(&fp) != 0) {
×
58
      metaError("failed to close file:%s, reason:%s", path, tstrerror(terrno));
×
59
    }
60
    metaError("failed to open table.db cursor, reason:%s", tstrerror(terrno));
×
61
    return;
×
62
  }
63

64
  code = tdbTbcMoveToFirst(cursor);
×
65
  if (code) {
×
66
    if (taosCloseFile(&fp) != 0) {
×
67
      metaError("failed to close file:%s, reason:%s", path, tstrerror(terrno));
×
68
    }
69
    tdbTbcClose(cursor);
×
70
    metaError("failed to move to first, reason:%s", tstrerror(terrno));
×
71
    return;
×
72
  }
73

74
  for (;;) {
×
75
    const void *pKey;
76
    int         kLen;
77
    const void *pVal;
78
    int         vLen;
79
    if (tdbTbcGet(cursor, &pKey, &kLen, &pVal, &vLen) < 0) {
×
80
      break;
×
81
    }
82

83
    // decode entry
84
    SDecoder   dc = {0};
×
85
    SMetaEntry me = {0};
×
86

87
    tDecoderInit(&dc, (uint8_t *)pVal, vLen);
×
88

89
    if (metaDecodeEntry(&dc, &me) < 0) {
×
90
      tDecoderClear(&dc);
×
91
      break;
×
92
    }
93

94
    // skip deleted entry
95
    if (tdbTbGet(pMeta->pUidIdx, &me.uid, sizeof(me.uid), NULL, NULL) == 0) {
×
96
      // print entry
97
      char buf[1024] = {0};
×
98
      if (me.type == TSDB_SUPER_TABLE) {
×
99
        snprintf(buf, sizeof(buf) - 1, "type: super table, version:%" PRId64 " uid: %" PRId64 " name: %s\n", me.version,
×
100
                 me.uid, me.name);
101

102
      } else if (me.type == TSDB_CHILD_TABLE) {
×
103
        snprintf(buf, sizeof(buf) - 1,
×
104
                 "type: child table, version:%" PRId64 " uid: %" PRId64 " name: %s suid:%" PRId64 "\n", me.version,
105
                 me.uid, me.name, me.ctbEntry.suid);
106
      } else {
107
        snprintf(buf, sizeof(buf) - 1, "type: normal table, version:%" PRId64 " uid: %" PRId64 " name: %s\n",
×
108
                 me.version, me.uid, me.name);
109
      }
110

111
      if (taosWriteFile(fp, buf, strlen(buf)) < 0) {
×
112
        metaError("failed to write file:%s, reason:%s", path, tstrerror(terrno));
×
113
        tDecoderClear(&dc);
×
114
        break;
×
115
      }
116
    }
117

118
    tDecoderClear(&dc);
×
119

120
    if (tdbTbcMoveToNext(cursor) < 0) {
×
121
      break;
×
122
    }
123
  }
124

125
  tdbTbcClose(cursor);
×
126

127
  // close file
128
  if (taosFsyncFile(fp) < 0) {
×
129
    metaError("failed to fsync file:%s, reason:%s", path, tstrerror(terrno));
×
130
  }
131
  if (taosCloseFile(&fp) < 0) {
×
132
    metaError("failed to close file:%s, reason:%s", path, tstrerror(terrno));
×
133
  }
134
}
135

136
static int32_t metaOpenImpl(SVnode *pVnode, SMeta **ppMeta, const char *metaDir, int8_t rollback) {
10,145✔
137
  SMeta  *pMeta = NULL;
10,145✔
138
  int32_t code = 0;
10,145✔
139
  int32_t lino;
140
  int32_t offset;
141
  int32_t pathLen = 0;
10,145✔
142
  char    path[TSDB_FILENAME_LEN] = {0};
10,145✔
143
  char    indexFullPath[128] = {0};
10,145✔
144

145
  // create handle
146
  vnodeGetPrimaryDir(pVnode->path, pVnode->diskPrimary, pVnode->pTfs, path, TSDB_FILENAME_LEN);
10,145✔
147
  offset = strlen(path);
10,143✔
148
  snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
10,143✔
149

150
  if (strncmp(metaDir, VNODE_META_TMP_DIR, strlen(VNODE_META_TMP_DIR)) == 0) {
10,143!
151
    taosRemoveDir(path);
×
152
  }
153

154
  pathLen = strlen(path) + 1;
10,143✔
155
  if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + pathLen)) == NULL) {
10,143!
156
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
157
  }
158

159
  metaInitLock(pMeta);
10,129✔
160

161
  pMeta->path = (char *)&pMeta[1];
10,131✔
162
  tstrncpy(pMeta->path, path, pathLen);
10,131✔
163
  int32_t ret = taosRealPath(pMeta->path, NULL, strlen(path) + 1);
10,131✔
164

165
  pMeta->pVnode = pVnode;
10,134✔
166

167
  // create path if not created yet
168
  code = taosMkDir(pMeta->path);
10,134✔
169
  TSDB_CHECK_CODE(code, lino, _exit);
10,136!
170

171
  // open env
172
  code = tdbOpen(pMeta->path, pVnode->config.szPage, pVnode->config.szCache, &pMeta->pEnv, rollback,
10,136✔
173
                 pVnode->config.tdbEncryptAlgorithm, pVnode->config.tdbEncryptKey);
10,136✔
174
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
175

176
  // open pTbDb
177
  code = tdbTbOpen("table.db", sizeof(STbDbKey), -1, tbDbKeyCmpr, pMeta->pEnv, &pMeta->pTbDb, 0);
10,146✔
178
  TSDB_CHECK_CODE(code, lino, _exit);
10,145!
179

180
  // open pSkmDb
181
  code = tdbTbOpen("schema.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmDb, 0);
10,145✔
182
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
183

184
  // open pUidIdx
185
  code = tdbTbOpen("uid.idx", sizeof(tb_uid_t), sizeof(SUidIdxVal), uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pUidIdx, 0);
10,146✔
186
  TSDB_CHECK_CODE(code, lino, _exit);
10,143!
187

188
  // open pNameIdx
189
  code = tdbTbOpen("name.idx", -1, sizeof(tb_uid_t), NULL, pMeta->pEnv, &pMeta->pNameIdx, 0);
10,143✔
190
  TSDB_CHECK_CODE(code, lino, _exit);
10,145!
191

192
  // open pCtbIdx
193
  code = tdbTbOpen("ctb.idx", sizeof(SCtbIdxKey), -1, ctbIdxKeyCmpr, pMeta->pEnv, &pMeta->pCtbIdx, 0);
10,145✔
194
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
195

196
  // open pSuidIdx
197
  code = tdbTbOpen("suid.idx", sizeof(tb_uid_t), 0, uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pSuidIdx, 0);
10,146✔
198
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
199

200
  (void)tsnprintf(indexFullPath, sizeof(indexFullPath), "%s/%s", pMeta->path, "invert");
10,146✔
201
  ret = taosMkDir(indexFullPath);
10,143✔
202

203
  SIndexOpts opts = {.cacheSize = 8 * 1024 * 1024};
10,143✔
204
  code = indexOpen(&opts, indexFullPath, (SIndex **)&pMeta->pTagIvtIdx);
10,143✔
205
  TSDB_CHECK_CODE(code, lino, _exit);
10,132!
206

207
  code = tdbTbOpen("tag.idx", -1, 0, tagIdxKeyCmpr, pMeta->pEnv, &pMeta->pTagIdx, 0);
10,132✔
208
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
209

210
  // open pTtlMgr ("ttlv1.idx")
211
  char logPrefix[128] = {0};
10,146✔
212
  (void)tsnprintf(logPrefix, sizeof(logPrefix), "vgId:%d", TD_VID(pVnode));
10,146✔
213
  code = ttlMgrOpen(&pMeta->pTtlMgr, pMeta->pEnv, 0, logPrefix, tsTtlFlushThreshold);
10,137✔
214
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
215

216
  // open pSmaIdx
217
  code = tdbTbOpen("sma.idx", sizeof(SSmaIdxKey), 0, smaIdxKeyCmpr, pMeta->pEnv, &pMeta->pSmaIdx, 0);
10,146✔
218
  TSDB_CHECK_CODE(code, lino, _exit);
10,144!
219

220
  // idx table create time
221
  code = tdbTbOpen("ctime.idx", sizeof(SBtimeIdxKey), 0, btimeIdxCmpr, pMeta->pEnv, &pMeta->pBtimeIdx, 0);
10,144✔
222
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
223

224
  // idx num of col, normal table only
225
  code = tdbTbOpen("ncol.idx", sizeof(SNcolIdxKey), 0, ncolIdxCmpr, pMeta->pEnv, &pMeta->pNcolIdx, 0);
10,146✔
226
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
227

228
  code = tdbTbOpen("stream.task.db", sizeof(int64_t), -1, taskIdxKeyCmpr, pMeta->pEnv, &pMeta->pStreamDb, 0);
10,146✔
229
  TSDB_CHECK_CODE(code, lino, _exit);
10,146!
230

231
  code = metaCacheOpen(pMeta);
10,146✔
232
  TSDB_CHECK_CODE(code, lino, _exit);
10,144!
233

234
  code = metaInitTbFilterCache(pMeta);
10,144✔
235
  TSDB_CHECK_CODE(code, lino, _exit);
10,145!
236

237
#if 0
238
  // Do NOT remove this code, it is used to do debug stuff
239
  doScan(pMeta);
240
#endif
241

242
_exit:
10,145✔
243
  if (code) {
10,145!
244
    metaError("vgId:%d %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
245
    metaCleanup(&pMeta);
×
246
    *ppMeta = NULL;
×
247
  } else {
248
    metaDebug("vgId:%d %s success", TD_VID(pVnode), __func__);
10,145✔
249
    *ppMeta = pMeta;
10,144✔
250
  }
251
  return code;
10,144✔
252
}
253

254
bool generateNewMeta = false;
255

256
static int32_t metaGenerateNewMeta(SMeta **ppMeta) {
×
257
  SMeta  *pNewMeta = NULL;
×
258
  SMeta  *pMeta = *ppMeta;
×
259
  SVnode *pVnode = pMeta->pVnode;
×
260

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

263
  // Open a new meta for orgainzation
264
  int32_t code = metaOpenImpl(pMeta->pVnode, &pNewMeta, VNODE_META_TMP_DIR, false);
×
265
  if (code) {
×
266
    return code;
×
267
  }
268

269
  code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL);
×
270
  if (code) {
×
271
    return code;
×
272
  }
273

274
  // i == 0, scan super table
275
  // i == 1, scan normal table and child table
276
  for (int i = 0; i < 2; i++) {
×
277
    TBC    *uidCursor = NULL;
×
278
    int32_t counter = 0;
×
279

280
    code = tdbTbcOpen(pMeta->pUidIdx, &uidCursor, NULL);
×
281
    if (code) {
×
282
      metaError("vgId:%d failed to open uid index cursor, reason:%s", TD_VID(pVnode), tstrerror(code));
×
283
      return code;
×
284
    }
285

286
    code = tdbTbcMoveToFirst(uidCursor);
×
287
    if (code) {
×
288
      metaError("vgId:%d failed to move to first, reason:%s", TD_VID(pVnode), tstrerror(code));
×
289
      tdbTbcClose(uidCursor);
×
290
      return code;
×
291
    }
292

293
    for (;;) {
×
294
      const void *pKey;
295
      int         kLen;
296
      const void *pVal;
297
      int         vLen;
298

299
      if (tdbTbcGet(uidCursor, &pKey, &kLen, &pVal, &vLen) < 0) {
×
300
        break;
×
301
      }
302

303
      tb_uid_t    uid = *(tb_uid_t *)pKey;
×
304
      SUidIdxVal *pUidIdxVal = (SUidIdxVal *)pVal;
×
305
      if ((i == 0 && (pUidIdxVal->suid && pUidIdxVal->suid == uid))          // super table
×
306
          || (i == 1 && (pUidIdxVal->suid == 0 || pUidIdxVal->suid != uid))  // normal table and child table
×
307
      ) {
308
        counter++;
×
309
        if (i == 0) {
×
310
          metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter, "super", uid);
×
311
        } else {
312
          metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter,
×
313
                   pUidIdxVal->suid == 0 ? "normal" : "child", uid);
314
        }
315

316
        // fetch table entry
317
        void *value = NULL;
×
318
        int   valueSize = 0;
×
319
        if (tdbTbGet(pMeta->pTbDb,
×
320
                     &(STbDbKey){
×
321
                         .version = pUidIdxVal->version,
×
322
                         .uid = uid,
323
                     },
324
                     sizeof(uid), &value, &valueSize) == 0) {
325
          SDecoder   dc = {0};
×
326
          SMetaEntry me = {0};
×
327
          tDecoderInit(&dc, value, valueSize);
×
328
          if (metaDecodeEntry(&dc, &me) == 0) {
×
329
            if (me.type == TSDB_CHILD_TABLE &&
×
330
                tdbTbGet(pMeta->pUidIdx, &me.ctbEntry.suid, sizeof(me.ctbEntry.suid), NULL, NULL) != 0) {
×
331
              metaError("vgId:%d failed to get super table uid:%" PRId64 " for child table uid:%" PRId64,
×
332
                        TD_VID(pVnode), me.ctbEntry.suid, uid);
333
            } else if (metaHandleEntry2(pNewMeta, &me) != 0) {
×
334
              metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), uid);
×
335
            }
336
          }
337
          tDecoderClear(&dc);
×
338
        }
339
        tdbFree(value);
×
340
      }
341

342
      code = tdbTbcMoveToNext(uidCursor);
×
343
      if (code) {
×
344
        metaError("vgId:%d failed to move to next, reason:%s", TD_VID(pVnode), tstrerror(code));
×
345
        return code;
×
346
      }
347
    }
348

349
    tdbTbcClose(uidCursor);
×
350
  }
351

352
  code = metaCommit(pNewMeta, pNewMeta->txn);
×
353
  if (code) {
×
354
    metaError("vgId:%d failed to commit, reason:%s", TD_VID(pVnode), tstrerror(code));
×
355
    return code;
×
356
  }
357

358
  code = metaFinishCommit(pNewMeta, pNewMeta->txn);
×
359
  if (code) {
×
360
    metaError("vgId:%d failed to finish commit, reason:%s", TD_VID(pVnode), tstrerror(code));
×
361
    return code;
×
362
  }
363

364
  if ((code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL)) != 0) {
×
365
    metaError("vgId:%d failed to begin new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
366
  }
367
  metaClose(&pNewMeta);
×
368
  metaInfo("vgId:%d finish to generate new meta", TD_VID(pVnode));
×
369
  return 0;
×
370
}
371

372
int32_t metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
10,127✔
373
  if (generateNewMeta) {
10,127!
374
    char path[TSDB_FILENAME_LEN] = {0};
×
375
    char oldMetaPath[TSDB_FILENAME_LEN] = {0};
×
376
    char newMetaPath[TSDB_FILENAME_LEN] = {0};
×
377
    char backupMetaPath[TSDB_FILENAME_LEN] = {0};
×
378

379
    vnodeGetPrimaryDir(pVnode->path, pVnode->diskPrimary, pVnode->pTfs, path, TSDB_FILENAME_LEN);
×
380
    snprintf(oldMetaPath, sizeof(oldMetaPath) - 1, "%s%s%s", path, TD_DIRSEP, VNODE_META_DIR);
×
381
    snprintf(newMetaPath, sizeof(newMetaPath) - 1, "%s%s%s", path, TD_DIRSEP, VNODE_META_TMP_DIR);
×
382
    snprintf(backupMetaPath, sizeof(backupMetaPath) - 1, "%s%s%s", path, TD_DIRSEP, VNODE_META_BACKUP_DIR);
×
383

384
    bool oldMetaExist = taosCheckExistFile(oldMetaPath);
×
385
    bool newMetaExist = taosCheckExistFile(newMetaPath);
×
386
    bool backupMetaExist = taosCheckExistFile(backupMetaPath);
×
387

388
    if ((!backupMetaExist && !oldMetaExist && newMetaExist)     // case 2
×
389
        || (backupMetaExist && !oldMetaExist && !newMetaExist)  // case 4
×
390
        || (backupMetaExist && oldMetaExist && newMetaExist)    // case 8
×
391
    ) {
392
      metaError("vgId:%d invalid meta state, please check", TD_VID(pVnode));
×
393
      return TSDB_CODE_FAILED;
×
394
    } else if ((backupMetaExist && oldMetaExist && !newMetaExist)       // case 7
×
395
               || (!backupMetaExist && !oldMetaExist && !newMetaExist)  // case 1
×
396
    ) {
397
      return metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
×
398
    } else if (backupMetaExist && !oldMetaExist && newMetaExist) {
×
399
      if (taosRenameFile(newMetaPath, oldMetaPath) != 0) {
×
400
        metaError("vgId:%d failed to rename new meta to old meta, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
401
        return terrno;
×
402
      }
403
      return metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
×
404
    } else {
405
      int32_t code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
×
406
      if (code) {
×
407
        return code;
×
408
      }
409

410
      code = metaGenerateNewMeta(ppMeta);
×
411
      if (code) {
×
412
        metaError("vgId:%d failed to generate new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
413
      }
414

415
      metaClose(ppMeta);
×
416
      if (taosRenameFile(oldMetaPath, backupMetaPath) != 0) {
×
417
        metaError("vgId:%d failed to rename old meta to backup, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
418
        return terrno;
×
419
      }
420

421
      // rename the new meta to old meta
422
      if (taosRenameFile(newMetaPath, oldMetaPath) != 0) {
×
423
        metaError("vgId:%d failed to rename new meta to old meta, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
424
        return terrno;
×
425
      }
426
      code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, false);
×
427
      if (code) {
×
428
        metaError("vgId:%d failed to open new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
429
        return code;
×
430
      }
431
    }
432

433
  } else {
434
    return metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
10,127✔
435
  }
436

437
  return TSDB_CODE_SUCCESS;
×
438
}
439

440
int32_t metaUpgrade(SVnode *pVnode, SMeta **ppMeta) {
10,146✔
441
  int32_t code = TSDB_CODE_SUCCESS;
10,146✔
442
  int32_t lino;
443
  SMeta  *pMeta = *ppMeta;
10,146✔
444

445
  if (ttlMgrNeedUpgrade(pMeta->pEnv)) {
10,146!
446
    code = metaBegin(pMeta, META_BEGIN_HEAP_OS);
×
447
    TSDB_CHECK_CODE(code, lino, _exit);
×
448

449
    code = ttlMgrUpgrade(pMeta->pTtlMgr, pMeta);
×
450
    TSDB_CHECK_CODE(code, lino, _exit);
×
451

452
    code = metaCommit(pMeta, pMeta->txn);
×
453
    TSDB_CHECK_CODE(code, lino, _exit);
×
454
  }
455

456
_exit:
10,146✔
457
  if (code) {
10,146!
458
    metaError("vgId:%d %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
459
    metaCleanup(ppMeta);
×
460
  }
461
  return code;
10,146✔
462
}
463

464
void metaClose(SMeta **ppMeta) {
10,144✔
465
  metaCleanup(ppMeta);
10,144✔
466
  return;
10,146✔
467
}
468

469
int metaAlterCache(SMeta *pMeta, int32_t nPage) {
×
470
  int32_t code = 0;
×
471
  metaWLock(pMeta);
×
472
  code = tdbAlter(pMeta->pEnv, nPage);
×
473
  metaULock(pMeta);
×
474

475
  if (code) {
×
476
    metaError("vgId:%d %s failed since %s", TD_VID(pMeta->pVnode), __func__, tstrerror(code));
×
477
  }
478
  return code;
×
479
}
480

481
void metaRLock(SMeta *pMeta) {
33,473,935✔
482
  metaTrace("meta rlock %p", &pMeta->lock);
33,473,935✔
483
  if (taosThreadRwlockRdlock(&pMeta->lock) != 0) {
33,473,939!
484
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
485
  }
486
}
33,487,921✔
487

488
void metaWLock(SMeta *pMeta) {
387,928✔
489
  metaTrace("meta wlock %p", &pMeta->lock);
387,928✔
490
  if (taosThreadRwlockWrlock(&pMeta->lock) != 0) {
387,928!
491
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
492
  }
493
}
388,034✔
494

495
void metaULock(SMeta *pMeta) {
33,865,129✔
496
  metaTrace("meta ulock %p", &pMeta->lock);
33,865,129✔
497
  if (taosThreadRwlockUnlock(&pMeta->lock) != 0) {
33,865,135!
498
    metaError("vgId:%d failed to unlock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
499
  }
500
}
33,875,290✔
501

502
static void metaCleanup(SMeta **ppMeta) {
10,143✔
503
  SMeta *pMeta = *ppMeta;
10,143✔
504
  if (pMeta) {
10,143!
505
    metaInfo("vgId:%d meta clean up, path:%s", TD_VID(pMeta->pVnode), pMeta->path);
10,144!
506
    if (pMeta->pEnv) metaAbort(pMeta);
10,146!
507
    if (pMeta->pCache) metaCacheClose(pMeta);
10,146!
508
#ifdef BUILD_NO_CALL
509
    if (pMeta->pIdx) metaCloseIdx(pMeta);
510
#endif
511
    if (pMeta->pStreamDb) tdbTbClose(pMeta->pStreamDb);
10,146!
512
    if (pMeta->pNcolIdx) tdbTbClose(pMeta->pNcolIdx);
10,146!
513
    if (pMeta->pBtimeIdx) tdbTbClose(pMeta->pBtimeIdx);
10,146!
514
    if (pMeta->pSmaIdx) tdbTbClose(pMeta->pSmaIdx);
10,146!
515
    if (pMeta->pTtlMgr) ttlMgrClose(pMeta->pTtlMgr);
10,146!
516
    if (pMeta->pTagIvtIdx) indexClose(pMeta->pTagIvtIdx);
10,146!
517
    if (pMeta->pTagIdx) tdbTbClose(pMeta->pTagIdx);
10,146!
518
    if (pMeta->pCtbIdx) tdbTbClose(pMeta->pCtbIdx);
10,146!
519
    if (pMeta->pSuidIdx) tdbTbClose(pMeta->pSuidIdx);
10,146!
520
    if (pMeta->pNameIdx) tdbTbClose(pMeta->pNameIdx);
10,146!
521
    if (pMeta->pUidIdx) tdbTbClose(pMeta->pUidIdx);
10,146!
522
    if (pMeta->pSkmDb) tdbTbClose(pMeta->pSkmDb);
10,146!
523
    if (pMeta->pTbDb) tdbTbClose(pMeta->pTbDb);
10,146!
524
    if (pMeta->pEnv) tdbClose(pMeta->pEnv);
10,146!
525
    metaDestroyLock(pMeta);
10,146✔
526

527
    taosMemoryFreeClear(*ppMeta);
10,146!
528
  }
529
}
10,145✔
530

531
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
34,530,115✔
532
  STbDbKey *pTbDbKey1 = (STbDbKey *)pKey1;
34,530,115✔
533
  STbDbKey *pTbDbKey2 = (STbDbKey *)pKey2;
34,530,115✔
534

535
  if (pTbDbKey1->version > pTbDbKey2->version) {
34,530,115✔
536
    return 1;
14,089,483✔
537
  } else if (pTbDbKey1->version < pTbDbKey2->version) {
20,440,632✔
538
    return -1;
12,385,528✔
539
  }
540

541
  if (pTbDbKey1->uid > pTbDbKey2->uid) {
8,055,104✔
542
    return 1;
654,333✔
543
  } else if (pTbDbKey1->uid < pTbDbKey2->uid) {
7,400,771✔
544
    return -1;
393,952✔
545
  }
546

547
  return 0;
7,006,819✔
548
}
549

550
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
1,050,109✔
551
  SSkmDbKey *pSkmDbKey1 = (SSkmDbKey *)pKey1;
1,050,109✔
552
  SSkmDbKey *pSkmDbKey2 = (SSkmDbKey *)pKey2;
1,050,109✔
553

554
  if (pSkmDbKey1->uid > pSkmDbKey2->uid) {
1,050,109✔
555
    return 1;
283,793✔
556
  } else if (pSkmDbKey1->uid < pSkmDbKey2->uid) {
766,316✔
557
    return -1;
62,148✔
558
  }
559

560
  if (pSkmDbKey1->sver > pSkmDbKey2->sver) {
704,168✔
561
    return 1;
49,228✔
562
  } else if (pSkmDbKey1->sver < pSkmDbKey2->sver) {
654,940✔
563
    return -1;
253,849✔
564
  }
565

566
  return 0;
401,091✔
567
}
568

569
static int uidIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
20,910,519✔
570
  tb_uid_t uid1 = *(tb_uid_t *)pKey1;
20,910,519✔
571
  tb_uid_t uid2 = *(tb_uid_t *)pKey2;
20,910,519✔
572

573
  if (uid1 > uid2) {
20,910,519✔
574
    return 1;
12,718,669✔
575
  } else if (uid1 < uid2) {
8,191,850✔
576
    return -1;
4,627,302✔
577
  }
578

579
  return 0;
3,564,548✔
580
}
581

582
static int ctbIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
1,971,946✔
583
  SCtbIdxKey *pCtbIdxKey1 = (SCtbIdxKey *)pKey1;
1,971,946✔
584
  SCtbIdxKey *pCtbIdxKey2 = (SCtbIdxKey *)pKey2;
1,971,946✔
585

586
  if (pCtbIdxKey1->suid > pCtbIdxKey2->suid) {
1,971,946✔
587
    return 1;
358,068✔
588
  } else if (pCtbIdxKey1->suid < pCtbIdxKey2->suid) {
1,613,878✔
589
    return -1;
75,501✔
590
  }
591

592
  if (pCtbIdxKey1->uid > pCtbIdxKey2->uid) {
1,538,377✔
593
    return 1;
731,127✔
594
  } else if (pCtbIdxKey1->uid < pCtbIdxKey2->uid) {
807,250✔
595
    return -1;
799,211✔
596
  }
597

598
  return 0;
8,039✔
599
}
600

601
int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
1,735,254✔
602
  STagIdxKey *pTagIdxKey1 = (STagIdxKey *)pKey1;
1,735,254✔
603
  STagIdxKey *pTagIdxKey2 = (STagIdxKey *)pKey2;
1,735,254✔
604
  tb_uid_t    uid1 = 0, uid2 = 0;
1,735,254✔
605
  int         c;
606

607
  // compare suid
608
  if (pTagIdxKey1->suid > pTagIdxKey2->suid) {
1,735,254✔
609
    return 1;
112,842✔
610
  } else if (pTagIdxKey1->suid < pTagIdxKey2->suid) {
1,622,412✔
611
    return -1;
5,781✔
612
  }
613

614
  // compare column id
615
  if (pTagIdxKey1->cid > pTagIdxKey2->cid) {
1,616,631✔
616
    return 1;
562✔
617
  } else if (pTagIdxKey1->cid < pTagIdxKey2->cid) {
1,616,069✔
618
    return -1;
286✔
619
  }
620

621
  if (pTagIdxKey1->type != pTagIdxKey2->type) {
1,615,783!
622
    metaError("meta/open: incorrect tag idx type.");
×
623
    return TSDB_CODE_FAILED;
×
624
  }
625

626
  // check NULL, NULL is always the smallest
627
  if (pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
1,615,783✔
628
    return -1;
266✔
629
  } else if (!pTagIdxKey1->isNull && pTagIdxKey2->isNull) {
1,615,517✔
630
    return 1;
873✔
631
  } else if (!pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
1,614,644!
632
    // all not NULL, compr tag vals
633
    __compar_fn_t func = getComparFunc(pTagIdxKey1->type, 0);
1,614,368✔
634
    if (func == NULL) {
1,614,350!
635
      metaError("meta/open: %s", terrstr());
×
636
      return TSDB_CODE_FAILED;
×
637
    }
638
    c = func(pTagIdxKey1->data, pTagIdxKey2->data);
1,614,350✔
639
    if (c) return c;
1,614,365✔
640
  }
641

642
  // both null or tag values are equal, then continue to compare uids
643
  if (IS_VAR_DATA_TYPE(pTagIdxKey1->type)) {
28,026!
644
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + varDataTLen(pTagIdxKey1->data));
3,188✔
645
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + varDataTLen(pTagIdxKey2->data));
3,188✔
646
  } else {
647
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + tDataTypes[pTagIdxKey1->type].bytes);
24,838✔
648
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + tDataTypes[pTagIdxKey2->type].bytes);
24,838✔
649
  }
650

651
  // compare uid
652
  if (uid1 < uid2) {
28,026✔
653
    return -1;
663✔
654
  } else if (uid1 > uid2) {
27,363✔
655
    return 1;
18,050✔
656
  } else {
657
    return 0;
9,313✔
658
  }
659

660
  return 0;
661
}
662

663
static int btimeIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
760,778✔
664
  SBtimeIdxKey *pBtimeIdxKey1 = (SBtimeIdxKey *)pKey1;
760,778✔
665
  SBtimeIdxKey *pBtimeIdxKey2 = (SBtimeIdxKey *)pKey2;
760,778✔
666
  if (pBtimeIdxKey1->btime > pBtimeIdxKey2->btime) {
760,778✔
667
    return 1;
531,182✔
668
  } else if (pBtimeIdxKey1->btime < pBtimeIdxKey2->btime) {
229,596✔
669
    return -1;
26,027✔
670
  }
671

672
  if (pBtimeIdxKey1->uid > pBtimeIdxKey2->uid) {
203,569✔
673
    return 1;
188,335✔
674
  } else if (pBtimeIdxKey1->uid < pBtimeIdxKey2->uid) {
15,234✔
675
    return -1;
4,898✔
676
  }
677

678
  return 0;
10,336✔
679
}
680

UNCOV
681
static int ncolIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
UNCOV
682
  SNcolIdxKey *pNcolIdxKey1 = (SNcolIdxKey *)pKey1;
×
UNCOV
683
  SNcolIdxKey *pNcolIdxKey2 = (SNcolIdxKey *)pKey2;
×
684

UNCOV
685
  if (pNcolIdxKey1->ncol > pNcolIdxKey2->ncol) {
×
UNCOV
686
    return 1;
×
UNCOV
687
  } else if (pNcolIdxKey1->ncol < pNcolIdxKey2->ncol) {
×
UNCOV
688
    return -1;
×
689
  }
690

UNCOV
691
  if (pNcolIdxKey1->uid > pNcolIdxKey2->uid) {
×
UNCOV
692
    return 1;
×
UNCOV
693
  } else if (pNcolIdxKey1->uid < pNcolIdxKey2->uid) {
×
UNCOV
694
    return -1;
×
695
  }
696

UNCOV
697
  return 0;
×
698
}
699

700
static int smaIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
701
  SSmaIdxKey *pSmaIdxKey1 = (SSmaIdxKey *)pKey1;
×
702
  SSmaIdxKey *pSmaIdxKey2 = (SSmaIdxKey *)pKey2;
×
703

704
  if (pSmaIdxKey1->uid > pSmaIdxKey2->uid) {
×
705
    return 1;
×
706
  } else if (pSmaIdxKey1->uid < pSmaIdxKey2->uid) {
×
707
    return -1;
×
708
  }
709

710
  if (pSmaIdxKey1->smaUid > pSmaIdxKey2->smaUid) {
×
711
    return 1;
×
712
  } else if (pSmaIdxKey1->smaUid < pSmaIdxKey2->smaUid) {
×
713
    return -1;
×
714
  }
715

716
  return 0;
×
717
}
718

719
static int taskIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
720
  int32_t uid1 = *(int32_t *)pKey1;
×
721
  int32_t uid2 = *(int32_t *)pKey2;
×
722

723
  if (uid1 > uid2) {
×
724
    return 1;
×
725
  } else if (uid1 < uid2) {
×
726
    return -1;
×
727
  }
728

729
  return 0;
×
730
}
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