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

taosdata / TDengine / #4987

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

push

travis-ci

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

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

3062 existing lines in 140 files now uncovered.

261133 of 353439 relevant lines covered (73.88%)

121262425.02 hits per line

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

65.81
/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 "dmRepair.h"
17
#include "meta.h"
18
#include "vnd.h"
19

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

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

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

46
static void metaInitLock(SMeta *pMeta) {
4,230,558✔
47
  TdThreadRwlockAttr attr;
4,227,901✔
48
  (void)taosThreadRwlockAttrInit(&attr);
4,232,505✔
49
  (void)taosThreadRwlockAttrSetKindNP(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
4,232,505✔
50
  (void)taosThreadRwlockInit(&pMeta->lock, &attr);
4,232,344✔
51
  (void)taosThreadRwlockAttrDestroy(&attr);
4,232,362✔
52
  return;
4,229,915✔
53
}
54
static void metaDestroyLock(SMeta *pMeta) { (void)taosThreadRwlockDestroy(&pMeta->lock); }
4,232,505✔
55

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

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

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

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

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

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

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

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

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

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

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

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

UNCOV
135
    tDecoderClear(&dc);
×
136

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

UNCOV
142
  tdbTbcClose(cursor);
×
143

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

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

162
  // create handle
163
  vnodeGetPrimaryPath(pVnode, false, path, TSDB_FILENAME_LEN);
4,230,641✔
164
  offset = strlen(path);
4,232,047✔
165
  snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
4,232,047✔
166

167
  if (strncmp(metaDir, VNODE_META_TMP_DIR, strlen(VNODE_META_TMP_DIR)) == 0) {
4,231,155✔
168
    taosRemoveDir(path);
1,634✔
169
  }
170

171
  pathLen = strlen(path) + 1;
4,231,155✔
172
  if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + pathLen)) == NULL) {
4,231,155✔
UNCOV
173
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
174
  }
175

176
  metaInitLock(pMeta);
4,232,484✔
177

178
  pMeta->path = (char *)&pMeta[1];
4,231,444✔
179
  tstrncpy(pMeta->path, path, pathLen);
4,231,444✔
180
  int32_t ret = taosRealPath(pMeta->path, NULL, strlen(path) + 1);
4,230,767✔
181

182
  pMeta->pVnode = pVnode;
4,232,208✔
183

184
  // create path if not created yet
185
  code = taosMkDir(pMeta->path);
4,232,208✔
186
  TSDB_CHECK_CODE(code, lino, _exit);
4,230,183✔
187

188
  // open env
189
  code = tdbOpen(pMeta->path, pVnode->config.szPage, pVnode->config.szCache, &pMeta->pEnv, rollback,
4,230,183✔
190
                 &(pVnode->config.tdbEncryptData));
191
  TSDB_CHECK_CODE(code, lino, _exit);
4,231,071✔
192

193
  // open pTbDb
194
  code = tdbTbOpen("table.db", sizeof(STbDbKey), -1, tbDbKeyCmpr, pMeta->pEnv, &pMeta->pTbDb, 0);
4,231,071✔
195
  TSDB_CHECK_CODE(code, lino, _exit);
4,231,785✔
196

197
  // open pSkmDb
198
  code = tdbTbOpen("schema.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmDb, 0);
4,231,785✔
199
  TSDB_CHECK_CODE(code, lino, _exit);
4,230,248✔
200

201
  // open pUidIdx
202
  code = tdbTbOpen("uid.idx", sizeof(tb_uid_t), sizeof(SUidIdxVal), uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pUidIdx, 0);
4,230,248✔
203
  TSDB_CHECK_CODE(code, lino, _exit);
4,231,210✔
204

205
  // open pNameIdx
206
  code = tdbTbOpen("name.idx", -1, sizeof(tb_uid_t), NULL, pMeta->pEnv, &pMeta->pNameIdx, 0);
4,231,210✔
207
  TSDB_CHECK_CODE(code, lino, _exit);
4,231,937✔
208

209
  // open pCtbIdx
210
  code = tdbTbOpen("ctb.idx", sizeof(SCtbIdxKey), -1, ctbIdxKeyCmpr, pMeta->pEnv, &pMeta->pCtbIdx, 0);
4,231,937✔
211
  TSDB_CHECK_CODE(code, lino, _exit);
4,230,993✔
212

213
  // open pSuidIdx
214
  code = tdbTbOpen("suid.idx", sizeof(tb_uid_t), 0, uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pSuidIdx, 0);
4,230,993✔
215
  TSDB_CHECK_CODE(code, lino, _exit);
4,231,809✔
216

217
  (void)tsnprintf(indexFullPath, sizeof(indexFullPath), "%s/%s", pMeta->path, "invert");
4,231,809✔
218
  ret = taosMkDir(indexFullPath);
4,232,505✔
219

220
  SIndexOpts opts = {.cacheSize = 8 * 1024 * 1024};
4,232,505✔
221
  code = indexOpen(&opts, indexFullPath, (SIndex **)&pMeta->pTagIvtIdx);
4,232,505✔
222
  TSDB_CHECK_CODE(code, lino, _exit);
4,230,955✔
223

224
  code = tdbTbOpen("tag.idx", -1, 0, tagIdxKeyCmpr, pMeta->pEnv, &pMeta->pTagIdx, 0);
4,230,955✔
225
  TSDB_CHECK_CODE(code, lino, _exit);
4,231,223✔
226

227
  // open pTtlMgr ("ttlv1.idx")
228
  char logPrefix[128] = {0};
4,231,223✔
229
  (void)tsnprintf(logPrefix, sizeof(logPrefix), "vgId:%d", TD_VID(pVnode));
4,231,943✔
230
  code = ttlMgrOpen(&pMeta->pTtlMgr, pMeta->pEnv, 0, logPrefix, tsTtlFlushThreshold);
4,230,805✔
231
  TSDB_CHECK_CODE(code, lino, _exit);
4,232,505✔
232

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

237
  // idx table create time
238
  code = tdbTbOpen("ctime.idx", sizeof(SBtimeIdxKey), 0, btimeIdxCmpr, pMeta->pEnv, &pMeta->pBtimeIdx, 0);
4,232,145✔
239
  TSDB_CHECK_CODE(code, lino, _exit);
4,232,505✔
240

241
  // idx num of col, normal table only
242
  code = tdbTbOpen("ncol.idx", sizeof(SNcolIdxKey), 0, ncolIdxCmpr, pMeta->pEnv, &pMeta->pNcolIdx, 0);
4,232,505✔
243
  TSDB_CHECK_CODE(code, lino, _exit);
4,232,505✔
244

245
  code = tdbTbOpen("stream.task.db", sizeof(int64_t), -1, taskIdxKeyCmpr, pMeta->pEnv, &pMeta->pStreamDb, 0);
4,232,505✔
246
  TSDB_CHECK_CODE(code, lino, _exit);
4,232,422✔
247

248
  code = metaCacheOpen(pMeta);
4,232,422✔
249
  TSDB_CHECK_CODE(code, lino, _exit);
4,232,505✔
250

251
  code = metaInitTbFilterCache(pMeta);
4,232,505✔
252
  TSDB_CHECK_CODE(code, lino, _exit);
4,231,888✔
253

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

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

272
void vnodeGetMetaPath(SVnode *pVnode, const char *metaDir, char *fname) {
12,689,434✔
273
  vnodeGetPrimaryPath(pVnode, false, fname, TSDB_FILENAME_LEN);
12,689,434✔
274
  int32_t offset = strlen(fname);
12,696,636✔
275
  snprintf(fname + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
12,696,636✔
276
}
12,697,393✔
277

278
static bool metaShouldForceRepair(SVnode *pVnode, EDmRepairStrategy *pStrategy) {
4,230,703✔
279
  if (!dmRepairFlowEnabled()) {
4,230,703✔
280
    return false;
4,226,748✔
281
  }
282

283
  int32_t vgId = TD_VID(pVnode);
3,955✔
284
  const SRepairMetaVnodeOpt *pOpt = dmRepairGetMetaVnodeOpt(vgId);
3,955✔
285
  if (pOpt == NULL) {
3,955✔
286
    return false;
3,703✔
287
  }
288

289
  if (pStrategy != NULL) {
252✔
290
    *pStrategy = pOpt->strategy;
252✔
291
  }
292
  return true;
252✔
293
}
294

295
static int32_t metaCopyDirRecursive(const char *srcDir, const char *dstDir) {
336✔
296
  int32_t code = taosMulMkDir(dstDir);
336✔
297
  if (code != 0) {
336✔
298
    return code;
×
299
  }
300

301
  TdDirPtr pDir = taosOpenDir(srcDir);
336✔
302
  if (pDir == NULL) {
336✔
303
    return terrno;
×
304
  }
305

306
  while (true) {
1,008✔
307
    TdDirEntryPtr pEntry = taosReadDir(pDir);
1,344✔
308
    if (pEntry == NULL) {
1,344✔
309
      break;
336✔
310
    }
311

312
    char *name = taosGetDirEntryName(pEntry);
1,008✔
313
    if (name == NULL || strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
1,008✔
314
      continue;
672✔
315
    }
316

317
    char srcPath[TSDB_FILENAME_LEN] = {0};
336✔
318
    char dstPath[TSDB_FILENAME_LEN] = {0};
336✔
319
    snprintf(srcPath, sizeof(srcPath), "%s%s%s", srcDir, TD_DIRSEP, name);
336✔
320
    snprintf(dstPath, sizeof(dstPath), "%s%s%s", dstDir, TD_DIRSEP, name);
336✔
321

322
    if (taosDirEntryIsDir(pEntry)) {
336✔
323
      code = metaCopyDirRecursive(srcPath, dstPath);
168✔
324
    } else {
325
      if (taosCopyFile(srcPath, dstPath) < 0) {
168✔
326
        code = terrno != 0 ? terrno : TSDB_CODE_FAILED;
×
327
      } else {
328
        code = 0;
168✔
329
      }
330
    }
331

332
    if (code != 0) {
336✔
UNCOV
333
      (void)taosCloseDir(&pDir);
×
UNCOV
334
      return code;
×
335
    }
336
  }
337

338
  return taosCloseDir(&pDir);
336✔
339
}
340

341
static int32_t metaBuildRepairBackupDir(SVnode *pVnode, char *buf, int32_t bufLen) {
252✔
342
  const char *root = dmRepairHasBackupPath() ? dmRepairBackupPath() : TD_TMP_DIR_PATH;
252✔
343
  const char *sep = root[strlen(root) - 1] == TD_DIRSEP[0] ? "" : TD_DIRSEP;
252✔
344
  time_t      now = (time_t)taosGetTimestampSec();
252✔
345
  struct tm   tmInfo = {0};
252✔
346
  if (taosLocalTime(&now, &tmInfo, NULL, 0, NULL) == NULL) {
252✔
347
    return TSDB_CODE_FAILED;
×
348
  }
349

350
  char dateBuf[16] = {0};
252✔
351
  if (taosStrfTime(dateBuf, sizeof(dateBuf), "%Y%m%d", &tmInfo) == 0) {
252✔
UNCOV
352
    return TSDB_CODE_FAILED;
×
353
  }
354

355
  snprintf(buf, bufLen, "%s%staos_backup_%s%svnode%d%smeta", root, sep, dateBuf, TD_DIRSEP, TD_VID(pVnode), TD_DIRSEP);
252✔
356
  return TSDB_CODE_SUCCESS;
252✔
357
}
358

359
static int32_t metaBackupCurrentMeta(SVnode *pVnode) {
252✔
360
  char metaDir[TSDB_FILENAME_LEN] = {0};
252✔
361
  char backupDir[TSDB_FILENAME_LEN] = {0};
252✔
362

363
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
252✔
364

365
  int32_t code = metaBuildRepairBackupDir(pVnode, backupDir, sizeof(backupDir));
252✔
366
  if (code != 0) {
252✔
367
    return code;
×
368
  }
369

370
  if (taosCheckExistFile(backupDir)) {
252✔
371
    metaError("vgId:%d repair backup dir already exists: %s", TD_VID(pVnode), backupDir);
84✔
372
    return TSDB_CODE_FS_FILE_ALREADY_EXISTS;
84✔
373
  }
374

375
  code = metaCopyDirRecursive(metaDir, backupDir);
168✔
376
  if (code != 0) {
168✔
377
    metaError("vgId:%d failed to back up meta from %s to %s, reason:%s", TD_VID(pVnode), metaDir, backupDir,
×
378
              tstrerror(code));
UNCOV
379
    return code;
×
380
  }
381

382
  metaInfo("vgId:%d backed up meta to %s", TD_VID(pVnode), backupDir);
168✔
383
  return TSDB_CODE_SUCCESS;
168✔
384
}
385

386
static void metaResetStatisInfo(SMeta *pMeta) {
168✔
387
  pMeta->pVnode->config.vndStats.numOfSTables = 0;
168✔
388
  pMeta->pVnode->config.vndStats.numOfCTables = 0;
168✔
389
  pMeta->pVnode->config.vndStats.numOfNTables = 0;
168✔
390
  pMeta->pVnode->config.vndStats.numOfVTables = 0;
168✔
391
  pMeta->pVnode->config.vndStats.numOfVCTables = 0;
168✔
392
  pMeta->pVnode->config.vndStats.numOfNTimeSeries = 0;
168✔
393
  pMeta->pVnode->config.vndStats.numOfTimeSeries = 0;
168✔
394
  pMeta->pVnode->config.vndStats.numOfRSMAs = 0;
168✔
395
}
168✔
396

397
typedef enum {
398
  E_META_REPAIR_FROM_UID,
399
  E_META_REPAIR_FROM_REDO,
400
} EMetaRepairStrategy;
401

402
static EMetaRepairStrategy metaGetRepairStrategy(EDmRepairStrategy strategy) {
168✔
403
  if (strategy == DM_REPAIR_STRATEGY_META_FROM_REDO) {
168✔
UNCOV
404
    return E_META_REPAIR_FROM_REDO;
×
405
  }
406

407
  return E_META_REPAIR_FROM_UID;
168✔
408
}
409

410
static int32_t metaForceRepairFromUid(SVnode *pVnode, SMeta *pMeta, SMeta *pNewMeta) {
168✔
411
  int32_t code = TSDB_CODE_SUCCESS;
168✔
412

413
  // i == 0, scan super table
414
  // i == 1, scan normal table and child table
415
  for (int i = 0; i < 2; i++) {
504✔
416
    TBC    *uidCursor = NULL;
336✔
417
    int32_t counter = 0;
336✔
418

419
    code = tdbTbcOpen(pMeta->pUidIdx, &uidCursor, NULL);
336✔
420
    if (code) {
336✔
UNCOV
421
      metaError("vgId:%d failed to open uid index cursor, reason:%s", TD_VID(pVnode), tstrerror(code));
×
UNCOV
422
      return code;
×
423
    }
424

425
    code = tdbTbcMoveToFirst(uidCursor);
336✔
426
    if (code) {
336✔
UNCOV
427
      metaError("vgId:%d failed to move to first, reason:%s", TD_VID(pVnode), tstrerror(code));
×
UNCOV
428
      tdbTbcClose(uidCursor);
×
UNCOV
429
      return code;
×
430
    }
431

432
    for (;;) {
336✔
433
      const void *pKey;
672✔
434
      int         kLen;
672✔
435
      const void *pVal;
672✔
436
      int         vLen;
672✔
437

438
      if (tdbTbcGet(uidCursor, &pKey, &kLen, &pVal, &vLen) < 0) {
672✔
439
        break;
336✔
440
      }
441

442
      tb_uid_t    uid = *(tb_uid_t *)pKey;
336✔
443
      SUidIdxVal *pUidIdxVal = (SUidIdxVal *)pVal;
336✔
444
      if ((i == 0 && (pUidIdxVal->suid && pUidIdxVal->suid == uid))          // super table
336✔
445
          || (i == 1 && (pUidIdxVal->suid == 0 || pUidIdxVal->suid != uid))  // normal table and child table
336✔
446
      ) {
447
        counter++;
168✔
448
        if (i == 0) {
168✔
449
          metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter, "super", uid);
×
450
        } else {
451
          metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter,
168✔
452
                   pUidIdxVal->suid == 0 ? "normal" : "child", uid);
453
        }
454

455
        // fetch table entry
456
        void *value = NULL;
168✔
457
        int   valueSize = 0;
168✔
458
        if (tdbTbGet(pMeta->pTbDb,
168✔
459
                     &(STbDbKey){
168✔
460
                         .version = pUidIdxVal->version,
168✔
461
                         .uid = uid,
462
                     },
463
                     sizeof(uid), &value, &valueSize) == 0) {
464
          SDecoder   dc = {0};
168✔
465
          SMetaEntry me = {0};
168✔
466
          tDecoderInit(&dc, value, valueSize);
168✔
467
          if (metaDecodeEntry(&dc, &me) == 0) {
168✔
468
            if (me.type == TSDB_CHILD_TABLE &&
168✔
UNCOV
469
                tdbTbGet(pMeta->pUidIdx, &me.ctbEntry.suid, sizeof(me.ctbEntry.suid), NULL, NULL) != 0) {
×
470
              metaError("vgId:%d failed to get super table uid:%" PRId64 " for child table uid:%" PRId64,
×
471
                        TD_VID(pVnode), me.ctbEntry.suid, uid);
472
            } else if (metaHandleEntry2(pNewMeta, &me) != 0) {
168✔
473
              metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), uid);
×
474
            }
475
          }
476
          tDecoderClear(&dc);
168✔
477
        }
478
        tdbFree(value);
168✔
479
      }
480

481
      code = tdbTbcMoveToNext(uidCursor);
336✔
482
      if (code) {
336✔
483
        metaError("vgId:%d failed to move to next, reason:%s", TD_VID(pVnode), tstrerror(code));
×
484
        return code;
×
485
      }
486
    }
487

488
    tdbTbcClose(uidCursor);
336✔
489
  }
490

491
  return code;
168✔
492
}
493

UNCOV
494
static int32_t metaForceRepairFromRedo(SVnode *pVnode, SMeta *pMeta, SMeta *pNewMeta) {
×
UNCOV
495
  int32_t code = TSDB_CODE_SUCCESS;
×
496

UNCOV
497
  TBC *cursor = NULL;
×
498

UNCOV
499
  code = tdbTbcOpen(pMeta->pTbDb, &cursor, NULL);
×
UNCOV
500
  if (code) {
×
UNCOV
501
    metaError("vgId:%d failed to open table.db cursor, reason:%s", TD_VID(pVnode), tstrerror(code));
×
UNCOV
502
    return code;
×
503
  }
504

UNCOV
505
  code = tdbTbcMoveToFirst(cursor);
×
UNCOV
506
  if (code) {
×
UNCOV
507
    metaError("vgId:%d failed to move to first, reason:%s", TD_VID(pVnode), tstrerror(code));
×
UNCOV
508
    tdbTbcClose(cursor);
×
UNCOV
509
    return code;
×
510
  }
511

512
  while (true) {
×
UNCOV
513
    const void *pKey;
×
514
    int         kLen;
×
UNCOV
515
    const void *pVal;
×
516
    int         vLen;
×
517

518
    if (tdbTbcGet(cursor, &pKey, &kLen, &pVal, &vLen) < 0) {
×
519
      break;
×
520
    }
521

UNCOV
522
    STbDbKey  *pKeyEntry = (STbDbKey *)pKey;
×
523
    SDecoder   dc = {0};
×
UNCOV
524
    SMetaEntry me = {0};
×
525

UNCOV
526
    tDecoderInit(&dc, (uint8_t *)pVal, vLen);
×
UNCOV
527
    if (metaDecodeEntry(&dc, &me) < 0) {
×
UNCOV
528
      tDecoderClear(&dc);
×
529
      break;
×
530
    }
531

UNCOV
532
    if (metaHandleEntry2(pNewMeta, &me) != 0) {
×
UNCOV
533
      metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), pKeyEntry->uid);
×
534
      tDecoderClear(&dc);
×
535
      break;
×
536
    }
537
    tDecoderClear(&dc);
×
538

UNCOV
539
    code = tdbTbcMoveToNext(cursor);
×
UNCOV
540
    if (code) {
×
UNCOV
541
      metaError("vgId:%d failed to move to next, reason:%s", TD_VID(pVnode), tstrerror(code));
×
UNCOV
542
      break;
×
543
    }
544
  }
545

UNCOV
546
  tdbTbcClose(cursor);
×
UNCOV
547
  return code;
×
548
}
549

550
int32_t metaForceRepairCleanupTmpDir(const char *tmpDir) {
×
551
  if (tmpDir == NULL || tmpDir[0] == '\0' || !taosCheckExistFile(tmpDir)) {
×
UNCOV
552
    return 0;
×
553
  }
554

UNCOV
555
  taosRemoveDir(tmpDir);
×
556
  return 0;
×
557
}
558

559
static int32_t metaForceRepair(SMeta **ppMeta, EDmRepairStrategy repairStrategy) {
252✔
560
  int32_t code = TSDB_CODE_SUCCESS;
252✔
561
  SMeta  *pNewMeta = NULL;
252✔
562
  SMeta  *pMeta = *ppMeta;
252✔
563
  SVnode *pVnode = pMeta->pVnode;
252✔
564
  bool    cleanupTmpDirOnError = false;
252✔
565
  char    metaDir[TSDB_FILENAME_LEN] = {0};
252✔
566
  char    metaTempDir[TSDB_FILENAME_LEN] = {0};
252✔
567
  char    metaBackupDir[TSDB_FILENAME_LEN] = {0};
252✔
568

569
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
252✔
570
  vnodeGetMetaPath(pVnode, VNODE_META_TMP_DIR, metaTempDir);
252✔
571
  vnodeGetMetaPath(pVnode, VNODE_META_BACKUP_DIR, metaBackupDir);
252✔
572

573
  metaInfo("vgId:%d start to generate new meta", TD_VID(pMeta->pVnode));
252✔
574

575
  code = metaBackupCurrentMeta(pVnode);
252✔
576
  if (code != 0) {
252✔
577
    metaError("vgId:%d failed to back up current meta, reason:%s", TD_VID(pVnode), tstrerror(code));
84✔
578
    return code;
84✔
579
  }
580
  // Reset statistics info
581
  metaResetStatisInfo(pMeta);
168✔
582

583
  // Open a new meta for organization
584
  code = metaOpenImpl(pMeta->pVnode, &pNewMeta, VNODE_META_TMP_DIR, false);
168✔
585
  if (code) {
168✔
UNCOV
586
    goto _exit;
×
587
  }
588
  cleanupTmpDirOnError = true;
168✔
589

590
  code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL);
168✔
591
  if (code) {
168✔
UNCOV
592
    goto _exit;
×
593
  }
594

595
  EMetaRepairStrategy strategy = metaGetRepairStrategy(repairStrategy);
168✔
596
  if (strategy == E_META_REPAIR_FROM_UID) {
168✔
597
    code = metaForceRepairFromUid(pVnode, pMeta, pNewMeta);
168✔
598
    if (code) {
168✔
UNCOV
599
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
UNCOV
600
      goto _exit;
×
601
    }
602
  } else if (strategy == E_META_REPAIR_FROM_REDO) {
×
UNCOV
603
    code = metaForceRepairFromRedo(pVnode, pMeta, pNewMeta);
×
UNCOV
604
    if (code) {
×
UNCOV
605
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
UNCOV
606
      goto _exit;
×
607
    }
608
  }
609

610
  code = metaCommit(pNewMeta, pNewMeta->txn);
168✔
611
  if (code) {
168✔
UNCOV
612
    metaError("vgId:%d failed to commit, reason:%s", TD_VID(pVnode), tstrerror(code));
×
UNCOV
613
    goto _exit;
×
614
  }
615

616
  code = metaFinishCommit(pNewMeta, pNewMeta->txn);
168✔
617
  if (code) {
168✔
UNCOV
618
    metaError("vgId:%d failed to finish commit, reason:%s", TD_VID(pVnode), tstrerror(code));
×
UNCOV
619
    goto _exit;
×
620
  }
621

622
  if ((code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL)) != 0) {
168✔
UNCOV
623
    metaError("vgId:%d failed to begin new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
624
  }
625
  metaClose(&pNewMeta);
168✔
626
  cleanupTmpDirOnError = false;
168✔
627
  metaInfo("vgId:%d finish to generate new meta", TD_VID(pVnode));
168✔
628

629
  // Commit the new metadata
630
  metaClose(ppMeta);
168✔
631
  if (taosRenameFile(metaDir, metaBackupDir) != 0) {
168✔
UNCOV
632
    metaError("vgId:%d failed to rename old meta to backup, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
UNCOV
633
    return terrno;
×
634
  }
635

636
  // rename the new meta to old meta
637
  if (taosRenameFile(metaTempDir, metaDir) != 0) {
168✔
UNCOV
638
    metaError("vgId:%d failed to rename new meta to old meta, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
UNCOV
639
    return terrno;
×
640
  }
641

642
  code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, false);
168✔
643
  if (code) {
168✔
644
    metaError("vgId:%d failed to open new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
UNCOV
645
    return code;
×
646
  }
647

648
  metaInfo("vgId:%d successfully opened new meta", TD_VID(pVnode));
168✔
649

650
  return 0;
168✔
651

UNCOV
652
_exit:
×
UNCOV
653
  if (pNewMeta != NULL) {
×
UNCOV
654
    metaClose(&pNewMeta);
×
655
  }
656

UNCOV
657
  if (cleanupTmpDirOnError) {
×
UNCOV
658
    int32_t cleanupCode = metaForceRepairCleanupTmpDir(metaTempDir);
×
UNCOV
659
    if (cleanupCode != 0) {
×
UNCOV
660
      metaError("vgId:%d failed to clean tmp meta dir:%s, reason:%s", TD_VID(pVnode), metaTempDir,
×
661
                tstrerror(cleanupCode));
UNCOV
662
      if (code == 0) {
×
663
        code = cleanupCode;
×
664
      }
665
    }
666
  }
667

UNCOV
668
  return code;
×
669
}
670

671
static int32_t metaRollbackFromRepair(SVnode *pVnode) {
4,230,703✔
672
  int32_t code = TSDB_CODE_SUCCESS;
4,230,703✔
673
  char    metaDir[TSDB_FILENAME_LEN] = {0};
4,230,703✔
674
  char    metaBackupDir[TSDB_FILENAME_LEN] = {0};
4,230,703✔
675
  char    metaTempDir[TSDB_FILENAME_LEN] = {0};
4,230,703✔
676

677
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
4,230,703✔
678
  vnodeGetMetaPath(pVnode, VNODE_META_BACKUP_DIR, metaBackupDir);
4,230,703✔
679
  vnodeGetMetaPath(pVnode, VNODE_META_TMP_DIR, metaTempDir);
4,229,788✔
680

681
  bool metaExists = taosCheckExistFile(metaDir);
4,229,949✔
682
  bool metaBackupExists = taosCheckExistFile(metaBackupDir);
4,230,416✔
683
  bool metaTempExists = taosCheckExistFile(metaTempDir);
4,229,764✔
684

685
  if ((!metaBackupExists && !metaExists && metaTempExists)     //
4,230,542✔
686
      || (metaBackupExists && !metaExists && !metaTempExists)  //
4,230,542✔
687
      || (metaBackupExists && metaExists && metaTempExists)    //
4,230,542✔
688
  ) {
UNCOV
689
    metaError("vgId:%d, invalid meta state, please check!", TD_VID(pVnode));
×
690
    TAOS_RETURN(TSDB_CODE_FAILED);
×
691
  } else if (!metaBackupExists && metaExists && metaTempExists) {
4,230,542✔
692
    taosRemoveDir(metaTempDir);
×
693
  } else if (metaBackupExists && !metaExists && metaTempExists) {
4,230,542✔
UNCOV
694
    code = taosRenameFile(metaTempDir, metaDir);
×
UNCOV
695
    if (code) {
×
696
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
697
      TAOS_RETURN(code);
×
698
    }
699
    taosRemoveDir(metaBackupDir);
×
700
  } else if (metaBackupExists && metaExists && !metaTempExists) {
4,230,542✔
701
    taosRemoveDir(metaBackupDir);
164✔
702
  }
703
  return code;
4,229,764✔
704
}
705

706
static int32_t metaForceRepairIfShould(SVnode *pVnode, SMeta **ppMeta) {
4,230,703✔
707
  int32_t           code = TSDB_CODE_SUCCESS;
4,230,703✔
708
  EDmRepairStrategy strategy = DM_REPAIR_STRATEGY_META_FROM_UID;
4,230,703✔
709
  bool              shouldForceRepair = metaShouldForceRepair(pVnode, &strategy);
4,230,703✔
710

711
  // Check if meta should repair
712
  if (!shouldForceRepair) {
4,230,703✔
713
    metaDebug("vgId:%d, meta should not repair!", TD_VID(pVnode));
4,230,451✔
714
    return code;
4,230,451✔
715
  }
716

717
  // Do repair
718
  code = metaForceRepair(ppMeta, strategy);
252✔
719
  if (code) {
252✔
720
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
84✔
721
    return code;
84✔
722
  }
723

724
  return code;
168✔
725
}
726

727
int32_t metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
4,223,732✔
728
  int32_t code = TSDB_CODE_SUCCESS;
4,223,732✔
729

730
  // Rollback if in the middle stage of a repair mode
731
  code = metaRollbackFromRepair(pVnode);
4,223,732✔
732
  if (code) {
4,229,764✔
733
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
734
    TAOS_RETURN(code);
×
735
  }
736

737
  // Do open meta
738
  code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
4,229,764✔
739
  if (code) {
4,230,703✔
740
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
741
    TAOS_RETURN(code);
×
742
  }
743

744
  // Repair meta data if should
745
  code = metaForceRepairIfShould(pVnode, ppMeta);
4,230,703✔
746
  if (code) {
4,230,703✔
747
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
84✔
748
    TAOS_RETURN(code);
84✔
749
  }
750

751
  return TSDB_CODE_SUCCESS;
4,230,619✔
752
}
753

754
int32_t metaUpgrade(SVnode *pVnode, SMeta **ppMeta) {
4,226,079✔
755
  int32_t code = TSDB_CODE_SUCCESS;
4,226,079✔
756
  int32_t lino;
757
  SMeta  *pMeta = *ppMeta;
4,226,079✔
758

759
  if (ttlMgrNeedUpgrade(pMeta->pEnv)) {
4,226,079✔
760
    code = metaBegin(pMeta, META_BEGIN_HEAP_OS);
×
UNCOV
761
    TSDB_CHECK_CODE(code, lino, _exit);
×
762

UNCOV
763
    code = ttlMgrUpgrade(pMeta->pTtlMgr, pMeta);
×
764
    TSDB_CHECK_CODE(code, lino, _exit);
×
765

766
    code = metaCommit(pMeta, pMeta->txn);
×
767
    TSDB_CHECK_CODE(code, lino, _exit);
×
768
  }
769

770
_exit:
4,225,895✔
771
  if (code) {
4,225,895✔
UNCOV
772
    metaError("vgId:%d %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
UNCOV
773
    metaCleanup(ppMeta);
×
774
  }
775
  return code;
4,225,895✔
776
}
777

778
void metaClose(SMeta **ppMeta) {
4,231,753✔
779
  metaCleanup(ppMeta);
4,231,753✔
780
  return;
4,231,991✔
781
}
782

783
int metaAlterCache(SMeta *pMeta, int32_t nPage) {
4,668✔
784
  int32_t code = 0;
4,668✔
785
  metaWLock(pMeta);
4,668✔
786
  code = tdbAlter(pMeta->pEnv, nPage);
4,668✔
787
  metaULock(pMeta);
4,668✔
788

789
  if (code) {
4,668✔
790
    metaError("vgId:%d %s failed since %s", TD_VID(pMeta->pVnode), __func__, tstrerror(code));
×
791
  }
792
  return code;
4,668✔
793
}
794

795
void metaRLock(SMeta *pMeta) {
2,147,483,647✔
796
  metaTrace("meta rlock %p", &pMeta->lock);
2,147,483,647✔
797
  if (taosThreadRwlockRdlock(&pMeta->lock) != 0) {
2,147,483,647✔
798
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
799
  }
800
}
2,147,483,647✔
801

802
void metaWLock(SMeta *pMeta) {
154,032,788✔
803
  metaTrace("meta wlock %p", &pMeta->lock);
154,032,788✔
804
  if (taosThreadRwlockWrlock(&pMeta->lock) != 0) {
154,032,788✔
805
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
806
  }
807
}
154,042,730✔
808

809
void metaULock(SMeta *pMeta) {
2,147,483,647✔
810
  metaTrace("meta ulock %p", &pMeta->lock);
2,147,483,647✔
811
  if (taosThreadRwlockUnlock(&pMeta->lock) != 0) {
2,147,483,647✔
UNCOV
812
    metaError("vgId:%d failed to unlock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
813
  }
814
}
2,147,483,647✔
815

816
static void metaCleanup(SMeta **ppMeta) {
4,231,572✔
817
  SMeta *pMeta = *ppMeta;
4,231,572✔
818
  if (pMeta) {
4,231,572✔
819
    metaInfo("vgId:%d meta clean up, path:%s", TD_VID(pMeta->pVnode), pMeta->path);
4,231,569✔
820
    if (pMeta->pEnv) metaAbort(pMeta);
4,232,958✔
821
    if (pMeta->pCache) metaCacheClose(pMeta);
4,232,396✔
822
#ifdef BUILD_NO_CALL
823
    if (pMeta->pIdx) metaCloseIdx(pMeta);
824
#endif
825
    if (pMeta->pStreamDb) tdbTbClose(pMeta->pStreamDb);
4,232,505✔
826
    if (pMeta->pNcolIdx) tdbTbClose(pMeta->pNcolIdx);
4,232,505✔
827
    if (pMeta->pBtimeIdx) tdbTbClose(pMeta->pBtimeIdx);
4,232,505✔
828
    if (pMeta->pSmaIdx) tdbTbClose(pMeta->pSmaIdx);
4,232,505✔
829
    if (pMeta->pTtlMgr) ttlMgrClose(pMeta->pTtlMgr);
4,232,505✔
830
    if (pMeta->pTagIvtIdx) indexClose(pMeta->pTagIvtIdx);
4,232,505✔
831
    if (pMeta->pTagIdx) tdbTbClose(pMeta->pTagIdx);
4,232,505✔
832
    if (pMeta->pCtbIdx) tdbTbClose(pMeta->pCtbIdx);
4,232,505✔
833
    if (pMeta->pSuidIdx) tdbTbClose(pMeta->pSuidIdx);
4,232,505✔
834
    if (pMeta->pNameIdx) tdbTbClose(pMeta->pNameIdx);
4,232,505✔
835
    if (pMeta->pUidIdx) tdbTbClose(pMeta->pUidIdx);
4,232,505✔
836
    if (pMeta->pSkmDb) tdbTbClose(pMeta->pSkmDb);
4,232,505✔
837
    if (pMeta->pTbDb) tdbTbClose(pMeta->pTbDb);
4,232,505✔
838
    if (pMeta->pEnv) tdbClose(pMeta->pEnv);
4,232,505✔
839
    metaDestroyLock(pMeta);
4,232,505✔
840

841
    taosMemoryFreeClear(*ppMeta);
4,232,505✔
842
  }
843
}
4,232,508✔
844

845
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
2,147,483,647✔
846
  STbDbKey *pTbDbKey1 = (STbDbKey *)pKey1;
2,147,483,647✔
847
  STbDbKey *pTbDbKey2 = (STbDbKey *)pKey2;
2,147,483,647✔
848

849
  TDB_KEY_ALIGN(pTbDbKey1, pTbDbKey2, STbDbKey);
850

851
  if (pTbDbKey1->version > pTbDbKey2->version) {
2,147,483,647✔
852
    return 1;
2,147,483,647✔
853
  } else if (pTbDbKey1->version < pTbDbKey2->version) {
2,147,483,647✔
854
    return -1;
2,147,483,647✔
855
  }
856

857
  if (pTbDbKey1->uid > pTbDbKey2->uid) {
2,147,483,647✔
858
    return 1;
629,838,241✔
859
  } else if (pTbDbKey1->uid < pTbDbKey2->uid) {
2,147,483,647✔
860
    return -1;
535,683,525✔
861
  }
862

863
  return 0;
2,092,260,820✔
864
}
865

866
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
390,243,095✔
867
  SSkmDbKey *pSkmDbKey1 = (SSkmDbKey *)pKey1;
390,243,095✔
868
  SSkmDbKey *pSkmDbKey2 = (SSkmDbKey *)pKey2;
390,243,095✔
869

870
  TDB_KEY_ALIGN(pSkmDbKey1, pSkmDbKey2, SSkmDbKey);
871

872
  if (pSkmDbKey1->uid > pSkmDbKey2->uid) {
390,243,095✔
873
    return 1;
142,138,530✔
874
  } else if (pSkmDbKey1->uid < pSkmDbKey2->uid) {
248,453,712✔
875
    return -1;
68,323,315✔
876
  }
877

878
  if (pSkmDbKey1->sver > pSkmDbKey2->sver) {
180,147,848✔
879
    return 1;
83,223,409✔
880
  } else if (pSkmDbKey1->sver < pSkmDbKey2->sver) {
96,935,073✔
881
    return -1;
24,916,008✔
882
  }
883

884
  return 0;
72,019,526✔
885
}
886

887
static int uidIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
2,147,483,647✔
888
  tb_uid_t uid1 = taosGetInt64Aligned((int64_t *)pKey1);
2,147,483,647✔
889
  tb_uid_t uid2 = taosGetInt64Aligned((int64_t *)pKey2);
2,147,483,647✔
890

891
  if (uid1 > uid2) {
2,147,483,647✔
892
    return 1;
2,147,483,647✔
893
  } else if (uid1 < uid2) {
2,147,483,647✔
894
    return -1;
1,552,020,930✔
895
  }
896

897
  return 0;
1,104,581,091✔
898
}
899

900
static int ctbIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
1,007,120,814✔
901
  SCtbIdxKey *pCtbIdxKey1 = (SCtbIdxKey *)pKey1;
1,007,120,814✔
902
  SCtbIdxKey *pCtbIdxKey2 = (SCtbIdxKey *)pKey2;
1,007,120,814✔
903

904
  TDB_KEY_ALIGN(pCtbIdxKey1, pCtbIdxKey2, SCtbIdxKey);
905

906
  if (pCtbIdxKey1->suid > pCtbIdxKey2->suid) {
1,007,120,814✔
907
    return 1;
104,010,668✔
908
  } else if (pCtbIdxKey1->suid < pCtbIdxKey2->suid) {
903,173,586✔
909
    return -1;
40,665,312✔
910
  }
911

912
  if (pCtbIdxKey1->uid > pCtbIdxKey2->uid) {
862,504,798✔
913
    return 1;
487,495,998✔
914
  } else if (pCtbIdxKey1->uid < pCtbIdxKey2->uid) {
375,087,863✔
915
    return -1;
315,634,441✔
916
  }
917

918
  return 0;
59,462,807✔
919
}
920

921
int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
840,084,847✔
922
  STagIdxKey *pTagIdxKey1 = (STagIdxKey *)pKey1;
840,084,847✔
923
  STagIdxKey *pTagIdxKey2 = (STagIdxKey *)pKey2;
840,084,847✔
924
  tb_uid_t    uid1 = 0, uid2 = 0;
840,084,847✔
925
  int         c;
926

927
  TDB_KEY_ALIGN(pTagIdxKey1, pTagIdxKey2, STagIdxKey);
928

929
  // compare suid
930
  if (pTagIdxKey1->suid > pTagIdxKey2->suid) {
840,084,847✔
931
    return 1;
12,640,118✔
932
  } else if (pTagIdxKey1->suid < pTagIdxKey2->suid) {
827,476,004✔
933
    return -1;
1,938,916✔
934
  }
935

936
  // compare column id
937
  if (pTagIdxKey1->cid > pTagIdxKey2->cid) {
825,532,161✔
938
    return 1;
29,867,362✔
939
  } else if (pTagIdxKey1->cid < pTagIdxKey2->cid) {
795,670,941✔
940
    return -1;
15,191,442✔
941
  }
942

943
  if (pTagIdxKey1->type != pTagIdxKey2->type) {
780,481,293✔
UNCOV
944
    metaError("meta/open: incorrect tag idx type.");
×
UNCOV
945
    return TSDB_CODE_FAILED;
×
946
  }
947

948
  // check NULL, NULL is always the smallest
949
  if (pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
780,473,333✔
950
    return -1;
168,439✔
951
  } else if (!pTagIdxKey1->isNull && pTagIdxKey2->isNull) {
780,317,662✔
952
    return 1;
723,856✔
953
  } else if (!pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
779,589,754✔
954
    // all not NULL, compr tag vals
955
    __compar_fn_t func = getComparFunc(pTagIdxKey1->type, 0);
769,143,028✔
956
    if (func == NULL) {
769,139,017✔
UNCOV
957
      metaError("meta/open: %s", terrstr());
×
UNCOV
958
      return TSDB_CODE_FAILED;
×
959
    }
960
    c = func(pTagIdxKey1->data, pTagIdxKey2->data);
769,139,017✔
961
    if (c) return c;
769,127,979✔
962
  }
963

964
  // both null or tag values are equal, then continue to compare uids
965
  if (IS_VAR_DATA_TYPE(pTagIdxKey1->type)) {
129,837,902✔
966
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + varDataTLen(pTagIdxKey1->data));
51,730,107✔
967
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + varDataTLen(pTagIdxKey2->data));
51,727,842✔
968
  } else {
969
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + tDataTypes[pTagIdxKey1->type].bytes);
78,152,788✔
970
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + tDataTypes[pTagIdxKey2->type].bytes);
78,151,305✔
971
  }
972

973
  // compare uid
974
  if (uid1 < uid2) {
129,877,770✔
975
    return -1;
10,966,249✔
976
  } else if (uid1 > uid2) {
118,911,521✔
977
    return 1;
104,011,524✔
978
  } else {
979
    return 0;
14,899,997✔
980
  }
981

982
  return 0;
983
}
984

985
static int btimeIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
258,316,151✔
986
  SBtimeIdxKey *pBtimeIdxKey1 = (SBtimeIdxKey *)pKey1;
258,316,151✔
987
  SBtimeIdxKey *pBtimeIdxKey2 = (SBtimeIdxKey *)pKey2;
258,316,151✔
988

989
  TDB_KEY_ALIGN(pBtimeIdxKey1, pBtimeIdxKey2, SBtimeIdxKey);
990

991
  if (pBtimeIdxKey1->btime > pBtimeIdxKey2->btime) {
258,316,151✔
992
    return 1;
231,641,606✔
993
  } else if (pBtimeIdxKey1->btime < pBtimeIdxKey2->btime) {
26,684,528✔
994
    return -1;
2,092,665✔
995
  }
996

997
  if (pBtimeIdxKey1->uid > pBtimeIdxKey2->uid) {
24,591,694✔
998
    return 1;
21,752,672✔
999
  } else if (pBtimeIdxKey1->uid < pBtimeIdxKey2->uid) {
2,839,022✔
1000
    return -1;
401,653✔
1001
  }
1002

1003
  return 0;
2,437,013✔
1004
}
1005

UNCOV
1006
static int ncolIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
UNCOV
1007
  SNcolIdxKey *pNcolIdxKey1 = (SNcolIdxKey *)pKey1;
×
UNCOV
1008
  SNcolIdxKey *pNcolIdxKey2 = (SNcolIdxKey *)pKey2;
×
1009

1010
  TDB_KEY_ALIGN(pNcolIdxKey1, pNcolIdxKey2, SNcolIdxKey);
1011

UNCOV
1012
  if (pNcolIdxKey1->ncol > pNcolIdxKey2->ncol) {
×
UNCOV
1013
    return 1;
×
UNCOV
1014
  } else if (pNcolIdxKey1->ncol < pNcolIdxKey2->ncol) {
×
UNCOV
1015
    return -1;
×
1016
  }
1017

UNCOV
1018
  if (pNcolIdxKey1->uid > pNcolIdxKey2->uid) {
×
UNCOV
1019
    return 1;
×
UNCOV
1020
  } else if (pNcolIdxKey1->uid < pNcolIdxKey2->uid) {
×
UNCOV
1021
    return -1;
×
1022
  }
1023

UNCOV
1024
  return 0;
×
1025
}
1026

UNCOV
1027
static int smaIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
UNCOV
1028
  SSmaIdxKey *pSmaIdxKey1 = (SSmaIdxKey *)pKey1;
×
UNCOV
1029
  SSmaIdxKey *pSmaIdxKey2 = (SSmaIdxKey *)pKey2;
×
1030

1031
  TDB_KEY_ALIGN(pSmaIdxKey1, pSmaIdxKey2, SSmaIdxKey);
1032

UNCOV
1033
  if (pSmaIdxKey1->uid > pSmaIdxKey2->uid) {
×
UNCOV
1034
    return 1;
×
UNCOV
1035
  } else if (pSmaIdxKey1->uid < pSmaIdxKey2->uid) {
×
UNCOV
1036
    return -1;
×
1037
  }
1038

UNCOV
1039
  if (pSmaIdxKey1->smaUid > pSmaIdxKey2->smaUid) {
×
UNCOV
1040
    return 1;
×
UNCOV
1041
  } else if (pSmaIdxKey1->smaUid < pSmaIdxKey2->smaUid) {
×
UNCOV
1042
    return -1;
×
1043
  }
1044

UNCOV
1045
  return 0;
×
1046
}
1047

UNCOV
1048
static int taskIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
UNCOV
1049
  int32_t uid1 = *(int32_t *)pKey1;
×
UNCOV
1050
  int32_t uid2 = *(int32_t *)pKey2;
×
1051

UNCOV
1052
  if (uid1 > uid2) {
×
UNCOV
1053
    return 1;
×
UNCOV
1054
  } else if (uid1 < uid2) {
×
UNCOV
1055
    return -1;
×
1056
  }
1057

UNCOV
1058
  return 0;
×
1059
}
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