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

taosdata / TDengine / #5056

17 May 2026 01:15AM UTC coverage: 73.384% (+0.03%) from 73.355%
#5056

push

travis-ci

web-flow
feat (TDgpt): Dynamic Model Synchronization Enhancements (#35344)

* refactor: do some internal refactor.

* fix: fix multiprocess sync issue.

* feat: add dynamic anomaly detection and forecasting services

* fix: log error message for undeploying model in exception handling

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: handle undeploy when model exists only on disk

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/286aafa0-c3ce-4c27-b803-2707571e9dc1

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: guard dynamic registry concurrent access

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: tighten service list locking scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: restore prophet support and update tests per review feedback

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: improve test name and move copy inside lock scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* Potential fix for pull request finding

Co-au... (continued)

281643 of 383795 relevant lines covered (73.38%)

135942701.67 hits per line

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

66.3
/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 "thash.h"
19
#include "vnd.h"
20

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

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

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

47
static void metaInitLock(SMeta *pMeta) {
4,875,952✔
48
  TdThreadRwlockAttr attr;
4,871,239✔
49
  (void)taosThreadRwlockAttrInit(&attr);
4,876,543✔
50
  (void)taosThreadRwlockAttrSetKindNP(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
4,875,173✔
51
  (void)taosThreadRwlockInit(&pMeta->lock, &attr);
4,875,142✔
52
  (void)taosThreadRwlockAttrDestroy(&attr);
4,875,628✔
53
  return;
4,875,916✔
54
}
55
static void metaDestroyLock(SMeta *pMeta) { (void)taosThreadRwlockDestroy(&pMeta->lock); }
4,877,407✔
56

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

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

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

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

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

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

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

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

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

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

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

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

136
    tDecoderClear(&dc);
×
137

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

143
  tdbTbcClose(cursor);
×
144

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

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

163
  // create handle
164
  vnodeGetPrimaryPath(pVnode, false, path, TSDB_FILENAME_LEN);
4,869,373✔
165
  offset = strlen(path);
4,874,932✔
166
  snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
4,874,932✔
167

168
  if (strncmp(metaDir, VNODE_META_TMP_DIR, strlen(VNODE_META_TMP_DIR)) == 0) {
4,875,801✔
169
    taosRemoveDir(path);
1,789✔
170
  }
171

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

177
  metaInitLock(pMeta);
4,875,714✔
178

179
  pMeta->path = (char *)&pMeta[1];
4,877,294✔
180
  tstrncpy(pMeta->path, path, pathLen);
4,877,292✔
181
  int32_t ret = taosRealPath(pMeta->path, NULL, strlen(path) + 1);
4,873,961✔
182

183
  pMeta->pVnode = pVnode;
4,873,755✔
184

185
  // create path if not created yet
186
  code = taosMkDir(pMeta->path);
4,874,185✔
187
  TSDB_CHECK_CODE(code, lino, _exit);
4,875,629✔
188

189
  // open env
190
  code = tdbOpen(pMeta->path, pVnode->config.szPage, pVnode->config.szCache, &pMeta->pEnv, rollback,
4,875,629✔
191
                 &(pVnode->config.tdbEncryptData));
192
  TSDB_CHECK_CODE(code, lino, _exit);
4,871,250✔
193

194
  // open pTbDb
195
  code = tdbTbOpen("table.db", sizeof(STbDbKey), -1, tbDbKeyCmpr, pMeta->pEnv, &pMeta->pTbDb, 0);
4,871,250✔
196
  TSDB_CHECK_CODE(code, lino, _exit);
4,875,090✔
197

198
  // open pSkmDb
199
  code = tdbTbOpen("schema.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmDb, 0);
4,875,090✔
200
  TSDB_CHECK_CODE(code, lino, _exit);
4,871,444✔
201

202
  // open pSkmExtDb
203
  code = tdbTbOpen("schema_ext.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmExtDb, 0);
4,871,444✔
204
  TSDB_CHECK_CODE(code, lino, _exit);
4,874,786✔
205

206
  // open pUidIdx
207
  code = tdbTbOpen("uid.idx", sizeof(tb_uid_t), sizeof(SUidIdxVal), uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pUidIdx, 0);
4,874,786✔
208
  TSDB_CHECK_CODE(code, lino, _exit);
4,874,849✔
209

210
  // open pNameIdx
211
  code = tdbTbOpen("name.idx", -1, sizeof(tb_uid_t), NULL, pMeta->pEnv, &pMeta->pNameIdx, 0);
4,874,849✔
212
  TSDB_CHECK_CODE(code, lino, _exit);
4,875,970✔
213

214
  // open pCtbIdx
215
  code = tdbTbOpen("ctb.idx", sizeof(SCtbIdxKey), -1, ctbIdxKeyCmpr, pMeta->pEnv, &pMeta->pCtbIdx, 0);
4,875,970✔
216
  TSDB_CHECK_CODE(code, lino, _exit);
4,873,943✔
217

218
  // open pSuidIdx
219
  code = tdbTbOpen("suid.idx", sizeof(tb_uid_t), 0, uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pSuidIdx, 0);
4,873,943✔
220
  TSDB_CHECK_CODE(code, lino, _exit);
4,874,225✔
221

222
  (void)snprintf(indexFullPath, sizeof(indexFullPath), "%s/%s", pMeta->path, "invert");
4,874,225✔
223
  ret = taosMkDir(indexFullPath);
4,874,580✔
224

225
  SIndexOpts opts = {.cacheSize = 8 * 1024 * 1024};
4,875,112✔
226
  code = indexOpen(&opts, indexFullPath, (SIndex **)&pMeta->pTagIvtIdx);
4,875,877✔
227
  TSDB_CHECK_CODE(code, lino, _exit);
4,876,627✔
228

229
  code = tdbTbOpen("tag.idx", -1, 0, tagIdxKeyCmpr, pMeta->pEnv, &pMeta->pTagIdx, 0);
4,876,627✔
230
  TSDB_CHECK_CODE(code, lino, _exit);
4,874,761✔
231

232
  // open pTtlMgr ("ttlv1.idx")
233
  char logPrefix[128] = {0};
4,874,761✔
234
  (void)snprintf(logPrefix, sizeof(logPrefix), "vgId:%d", TD_VID(pVnode));
4,875,625✔
235
  code = ttlMgrOpen(&pMeta->pTtlMgr, pMeta->pEnv, 0, logPrefix, tsTtlFlushThreshold);
4,871,777✔
236
  TSDB_CHECK_CODE(code, lino, _exit);
4,877,407✔
237

238
  // open pSmaIdx
239
  code = tdbTbOpen("sma.idx", sizeof(SSmaIdxKey), 0, smaIdxKeyCmpr, pMeta->pEnv, &pMeta->pSmaIdx, 0);
4,877,407✔
240
  TSDB_CHECK_CODE(code, lino, _exit);
4,874,432✔
241

242
  // idx table create time
243
  code = tdbTbOpen("ctime.idx", sizeof(SBtimeIdxKey), 0, btimeIdxCmpr, pMeta->pEnv, &pMeta->pBtimeIdx, 0);
4,874,432✔
244
  TSDB_CHECK_CODE(code, lino, _exit);
4,874,423✔
245

246
  // idx num of col, normal table only
247
  code = tdbTbOpen("ncol.idx", sizeof(SNcolIdxKey), 0, ncolIdxCmpr, pMeta->pEnv, &pMeta->pNcolIdx, 0);
4,874,423✔
248
  TSDB_CHECK_CODE(code, lino, _exit);
4,875,169✔
249

250
  code = tdbTbOpen("stream.task.db", sizeof(int64_t), -1, taskIdxKeyCmpr, pMeta->pEnv, &pMeta->pStreamDb, 0);
4,875,169✔
251
  TSDB_CHECK_CODE(code, lino, _exit);
4,876,635✔
252

253
  code = metaCacheOpen(pMeta);
4,876,635✔
254
  TSDB_CHECK_CODE(code, lino, _exit);
4,877,407✔
255

256
  code = metaInitTbFilterCache(pMeta);
4,877,407✔
257
  TSDB_CHECK_CODE(code, lino, _exit);
4,876,536✔
258

259
  pMeta->uidSuidHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
4,876,536✔
260
  TSDB_CHECK_NULL(pMeta->uidSuidHash, code, lino, _exit, terrno);
4,876,581✔
261

262
  pMeta->uidNameHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
4,876,481✔
263
  TSDB_CHECK_NULL(pMeta->uidNameHash, code, lino, _exit, terrno);
4,877,407✔
264

265
#if 0
266
  // Do NOT remove this code, it is used to do debug stuff
267
  doScan(pMeta);
268
#endif
269

270
_exit:
4,877,407✔
271
  if (code) {
4,877,307✔
272
    metaError("vgId:%d %s failed at %s:%d since %s, path:%s", TD_VID(pVnode), __func__, __FILE__, lino, tstrerror(code),
×
273
              path);
274
    metaCleanup(&pMeta);
×
275
    *ppMeta = NULL;
×
276
  } else {
277
    metaDebug("vgId:%d %s success", TD_VID(pVnode), __func__);
4,877,307✔
278
    *ppMeta = pMeta;
4,877,307✔
279
  }
280
  TAOS_RETURN(code);
4,877,307✔
281
}
282

283
void vnodeGetMetaPath(SVnode *pVnode, const char *metaDir, char *fname) {
14,618,769✔
284
  vnodeGetPrimaryPath(pVnode, false, fname, TSDB_FILENAME_LEN);
14,618,769✔
285
  int32_t offset = strlen(fname);
14,633,360✔
286
  snprintf(fname + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
14,633,360✔
287
}
14,630,608✔
288

289
static bool metaShouldForceRepair(SVnode *pVnode, EDmRepairStrategy *pStrategy) {
4,874,503✔
290
  if (!dmRepairFlowEnabled()) {
4,874,503✔
291
    return false;
4,870,773✔
292
  }
293

294
  int32_t vgId = TD_VID(pVnode);
4,597✔
295
  const SRepairMetaVnodeOpt *pOpt = dmRepairGetMetaVnodeOpt(vgId);
4,597✔
296
  if (pOpt == NULL) {
4,597✔
297
    return false;
4,315✔
298
  }
299

300
  if (pStrategy != NULL) {
282✔
301
    *pStrategy = pOpt->strategy;
282✔
302
  }
303
  return true;
282✔
304
}
305

306
static int32_t metaCopyDirRecursive(const char *srcDir, const char *dstDir) {
378✔
307
  int32_t code = taosMulMkDir(dstDir);
378✔
308
  if (code != 0) {
378✔
309
    return code;
×
310
  }
311

312
  TdDirPtr pDir = taosOpenDir(srcDir);
378✔
313
  if (pDir == NULL) {
378✔
314
    return terrno;
×
315
  }
316

317
  while (true) {
1,134✔
318
    TdDirEntryPtr pEntry = taosReadDir(pDir);
1,512✔
319
    if (pEntry == NULL) {
1,512✔
320
      break;
378✔
321
    }
322

323
    char *name = taosGetDirEntryName(pEntry);
1,134✔
324
    if (name == NULL || strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
1,134✔
325
      continue;
756✔
326
    }
327

328
    char srcPath[TSDB_FILENAME_LEN] = {0};
378✔
329
    char dstPath[TSDB_FILENAME_LEN] = {0};
378✔
330
    snprintf(srcPath, sizeof(srcPath), "%s%s%s", srcDir, TD_DIRSEP, name);
378✔
331
    snprintf(dstPath, sizeof(dstPath), "%s%s%s", dstDir, TD_DIRSEP, name);
378✔
332

333
    if (taosDirEntryIsDir(pEntry)) {
378✔
334
      code = metaCopyDirRecursive(srcPath, dstPath);
189✔
335
    } else {
336
      if (taosCopyFile(srcPath, dstPath) < 0) {
189✔
337
        code = terrno != 0 ? terrno : TSDB_CODE_FAILED;
×
338
      } else {
339
        code = 0;
189✔
340
      }
341
    }
342

343
    if (code != 0) {
378✔
344
      (void)taosCloseDir(&pDir);
×
345
      return code;
×
346
    }
347
  }
348

349
  return taosCloseDir(&pDir);
378✔
350
}
351

352
static int32_t metaBuildRepairBackupDir(SVnode *pVnode, char *buf, int32_t bufLen) {
282✔
353
  const char *root = dmRepairHasBackupPath() ? dmRepairBackupPath() : TD_TMP_DIR_PATH;
282✔
354
  const char *sep = root[strlen(root) - 1] == TD_DIRSEP[0] ? "" : TD_DIRSEP;
282✔
355
  time_t      now = (time_t)taosGetTimestampSec();
282✔
356
  struct tm   tmInfo = {0};
282✔
357
  if (taosLocalTime(&now, &tmInfo, NULL, 0, NULL) == NULL) {
282✔
358
    return TSDB_CODE_FAILED;
×
359
  }
360

361
  char dateBuf[16] = {0};
282✔
362
  if (taosStrfTime(dateBuf, sizeof(dateBuf), "%Y%m%d", &tmInfo) == 0) {
282✔
363
    return TSDB_CODE_FAILED;
×
364
  }
365

366
  snprintf(buf, bufLen, "%s%staos_backup_%s%svnode%d%smeta", root, sep, dateBuf, TD_DIRSEP, TD_VID(pVnode), TD_DIRSEP);
282✔
367
  return TSDB_CODE_SUCCESS;
282✔
368
}
369

370
static int32_t metaBackupCurrentMeta(SVnode *pVnode) {
282✔
371
  char metaDir[TSDB_FILENAME_LEN] = {0};
282✔
372
  char backupDir[TSDB_FILENAME_LEN] = {0};
282✔
373

374
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
282✔
375

376
  int32_t code = metaBuildRepairBackupDir(pVnode, backupDir, sizeof(backupDir));
282✔
377
  if (code != 0) {
282✔
378
    return code;
×
379
  }
380

381
  if (taosCheckExistFile(backupDir)) {
282✔
382
    metaError("vgId:%d repair backup dir already exists: %s", TD_VID(pVnode), backupDir);
93✔
383
    return TSDB_CODE_FS_FILE_ALREADY_EXISTS;
93✔
384
  }
385

386
  code = metaCopyDirRecursive(metaDir, backupDir);
189✔
387
  if (code != 0) {
189✔
388
    metaError("vgId:%d failed to back up meta from %s to %s, reason:%s", TD_VID(pVnode), metaDir, backupDir,
×
389
              tstrerror(code));
390
    return code;
×
391
  }
392

393
  metaInfo("vgId:%d backed up meta to %s", TD_VID(pVnode), backupDir);
189✔
394
  return TSDB_CODE_SUCCESS;
189✔
395
}
396

397
static void metaResetStatisInfo(SMeta *pMeta) {
189✔
398
  pMeta->pVnode->config.vndStats.numOfSTables = 0;
189✔
399
  pMeta->pVnode->config.vndStats.numOfCTables = 0;
189✔
400
  pMeta->pVnode->config.vndStats.numOfNTables = 0;
189✔
401
  pMeta->pVnode->config.vndStats.numOfVTables = 0;
189✔
402
  pMeta->pVnode->config.vndStats.numOfVCTables = 0;
189✔
403
  pMeta->pVnode->config.vndStats.numOfNTimeSeries = 0;
189✔
404
  pMeta->pVnode->config.vndStats.numOfTimeSeries = 0;
189✔
405
  pMeta->pVnode->config.vndStats.numOfRSMAs = 0;
189✔
406
}
189✔
407

408
typedef enum {
409
  E_META_REPAIR_FROM_UID,
410
  E_META_REPAIR_FROM_REDO,
411
} EMetaRepairStrategy;
412

413
static EMetaRepairStrategy metaGetRepairStrategy(EDmRepairStrategy strategy) {
189✔
414
  if (strategy == DM_REPAIR_STRATEGY_META_FROM_REDO) {
189✔
415
    return E_META_REPAIR_FROM_REDO;
×
416
  }
417

418
  return E_META_REPAIR_FROM_UID;
189✔
419
}
420

421
static int32_t metaForceRepairFromUid(SVnode *pVnode, SMeta *pMeta, SMeta *pNewMeta) {
189✔
422
  int32_t code = TSDB_CODE_SUCCESS;
189✔
423

424
  // i == 0, scan super table
425
  // i == 1, scan normal table and child table
426
  for (int i = 0; i < 2; i++) {
567✔
427
    TBC    *uidCursor = NULL;
378✔
428
    int32_t counter = 0;
378✔
429

430
    code = tdbTbcOpen(pMeta->pUidIdx, &uidCursor, NULL);
378✔
431
    if (code) {
378✔
432
      metaError("vgId:%d failed to open uid index cursor, reason:%s", TD_VID(pVnode), tstrerror(code));
×
433
      return code;
×
434
    }
435

436
    code = tdbTbcMoveToFirst(uidCursor);
378✔
437
    if (code) {
378✔
438
      metaError("vgId:%d failed to move to first, reason:%s", TD_VID(pVnode), tstrerror(code));
×
439
      tdbTbcClose(uidCursor);
×
440
      return code;
×
441
    }
442

443
    for (;;) {
378✔
444
      const void *pKey;
756✔
445
      int         kLen;
756✔
446
      const void *pVal;
756✔
447
      int         vLen;
756✔
448

449
      if (tdbTbcGet(uidCursor, &pKey, &kLen, &pVal, &vLen) < 0) {
756✔
450
        break;
378✔
451
      }
452

453
      tb_uid_t    uid = *(tb_uid_t *)pKey;
378✔
454
      SUidIdxVal *pUidIdxVal = (SUidIdxVal *)pVal;
378✔
455
      if ((i == 0 && (pUidIdxVal->suid && pUidIdxVal->suid == uid))          // super table
378✔
456
          || (i == 1 && (pUidIdxVal->suid == 0 || pUidIdxVal->suid != uid))  // normal table and child table
378✔
457
      ) {
458
        counter++;
189✔
459
        if (i == 0) {
189✔
460
          metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter, "super", uid);
×
461
        } else {
462
          metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter,
189✔
463
                   pUidIdxVal->suid == 0 ? "normal" : "child", uid);
464
        }
465

466
        // fetch table entry
467
        void *value = NULL;
189✔
468
        int   valueSize = 0;
189✔
469
        if (tdbTbGet(pMeta->pTbDb,
189✔
470
                     &(STbDbKey){
189✔
471
                         .version = pUidIdxVal->version,
189✔
472
                         .uid = uid,
473
                     },
474
                     sizeof(uid), &value, &valueSize) == 0) {
475
          SDecoder   dc = {0};
189✔
476
          SMetaEntry me = {0};
189✔
477
          tDecoderInit(&dc, value, valueSize);
189✔
478
          if (metaDecodeEntry(&dc, &me) == 0) {
189✔
479
            if (me.type == TSDB_CHILD_TABLE &&
189✔
480
                tdbTbGet(pMeta->pUidIdx, &me.ctbEntry.suid, sizeof(me.ctbEntry.suid), NULL, NULL) != 0) {
×
481
              metaError("vgId:%d failed to get super table uid:%" PRId64 " for child table uid:%" PRId64,
×
482
                        TD_VID(pVnode), me.ctbEntry.suid, uid);
483
            } else if (metaHandleEntry2(pNewMeta, &me) != 0) {
189✔
484
              metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), uid);
×
485
            }
486
          }
487
          tDecoderClear(&dc);
189✔
488
        }
489
        tdbFree(value);
189✔
490
      }
491

492
      code = tdbTbcMoveToNext(uidCursor);
378✔
493
      if (code) {
378✔
494
        metaError("vgId:%d failed to move to next, reason:%s", TD_VID(pVnode), tstrerror(code));
×
495
        return code;
×
496
      }
497
    }
498

499
    tdbTbcClose(uidCursor);
378✔
500
  }
501

502
  return code;
189✔
503
}
504

505
static int32_t metaForceRepairFromRedo(SVnode *pVnode, SMeta *pMeta, SMeta *pNewMeta) {
×
506
  int32_t code = TSDB_CODE_SUCCESS;
×
507

508
  TBC *cursor = NULL;
×
509

510
  code = tdbTbcOpen(pMeta->pTbDb, &cursor, NULL);
×
511
  if (code) {
×
512
    metaError("vgId:%d failed to open table.db cursor, reason:%s", TD_VID(pVnode), tstrerror(code));
×
513
    return code;
×
514
  }
515

516
  code = tdbTbcMoveToFirst(cursor);
×
517
  if (code) {
×
518
    metaError("vgId:%d failed to move to first, reason:%s", TD_VID(pVnode), tstrerror(code));
×
519
    tdbTbcClose(cursor);
×
520
    return code;
×
521
  }
522

523
  while (true) {
×
524
    const void *pKey;
×
525
    int         kLen;
×
526
    const void *pVal;
×
527
    int         vLen;
×
528

529
    if (tdbTbcGet(cursor, &pKey, &kLen, &pVal, &vLen) < 0) {
×
530
      break;
×
531
    }
532

533
    STbDbKey  *pKeyEntry = (STbDbKey *)pKey;
×
534
    SDecoder   dc = {0};
×
535
    SMetaEntry me = {0};
×
536

537
    tDecoderInit(&dc, (uint8_t *)pVal, vLen);
×
538
    if (metaDecodeEntry(&dc, &me) < 0) {
×
539
      tDecoderClear(&dc);
×
540
      break;
×
541
    }
542

543
    if (metaHandleEntry2(pNewMeta, &me) != 0) {
×
544
      metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), pKeyEntry->uid);
×
545
      tDecoderClear(&dc);
×
546
      break;
×
547
    }
548
    tDecoderClear(&dc);
×
549

550
    code = tdbTbcMoveToNext(cursor);
×
551
    if (code) {
×
552
      metaError("vgId:%d failed to move to next, reason:%s", TD_VID(pVnode), tstrerror(code));
×
553
      break;
×
554
    }
555
  }
556

557
  tdbTbcClose(cursor);
×
558
  return code;
×
559
}
560

561
int32_t metaForceRepairCleanupTmpDir(const char *tmpDir) {
×
562
  if (tmpDir == NULL || tmpDir[0] == '\0' || !taosCheckExistFile(tmpDir)) {
×
563
    return 0;
×
564
  }
565

566
  taosRemoveDir(tmpDir);
×
567
  return 0;
×
568
}
569

570
static int32_t metaForceRepair(SMeta **ppMeta, EDmRepairStrategy repairStrategy) {
282✔
571
  int32_t code = TSDB_CODE_SUCCESS;
282✔
572
  SMeta  *pNewMeta = NULL;
282✔
573
  SMeta  *pMeta = *ppMeta;
282✔
574
  SVnode *pVnode = pMeta->pVnode;
282✔
575
  bool    cleanupTmpDirOnError = false;
282✔
576
  char    metaDir[TSDB_FILENAME_LEN] = {0};
282✔
577
  char    metaTempDir[TSDB_FILENAME_LEN] = {0};
282✔
578
  char    metaBackupDir[TSDB_FILENAME_LEN] = {0};
282✔
579

580
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
282✔
581
  vnodeGetMetaPath(pVnode, VNODE_META_TMP_DIR, metaTempDir);
282✔
582
  vnodeGetMetaPath(pVnode, VNODE_META_BACKUP_DIR, metaBackupDir);
282✔
583

584
  metaInfo("vgId:%d start to generate new meta", TD_VID(pMeta->pVnode));
282✔
585

586
  code = metaBackupCurrentMeta(pVnode);
282✔
587
  if (code != 0) {
282✔
588
    metaError("vgId:%d failed to back up current meta, reason:%s", TD_VID(pVnode), tstrerror(code));
93✔
589
    return code;
93✔
590
  }
591
  // Reset statistics info
592
  metaResetStatisInfo(pMeta);
189✔
593

594
  // Open a new meta for organization
595
  code = metaOpenImpl(pMeta->pVnode, &pNewMeta, VNODE_META_TMP_DIR, false);
189✔
596
  if (code) {
189✔
597
    goto _exit;
×
598
  }
599
  cleanupTmpDirOnError = true;
189✔
600

601
  code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL);
189✔
602
  if (code) {
189✔
603
    goto _exit;
×
604
  }
605

606
  EMetaRepairStrategy strategy = metaGetRepairStrategy(repairStrategy);
189✔
607
  if (strategy == E_META_REPAIR_FROM_UID) {
189✔
608
    code = metaForceRepairFromUid(pVnode, pMeta, pNewMeta);
189✔
609
    if (code) {
189✔
610
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
611
      goto _exit;
×
612
    }
613
  } else if (strategy == E_META_REPAIR_FROM_REDO) {
×
614
    code = metaForceRepairFromRedo(pVnode, pMeta, pNewMeta);
×
615
    if (code) {
×
616
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
617
      goto _exit;
×
618
    }
619
  }
620

621
  code = metaCommit(pNewMeta, pNewMeta->txn);
189✔
622
  if (code) {
189✔
623
    metaError("vgId:%d failed to commit, reason:%s", TD_VID(pVnode), tstrerror(code));
×
624
    goto _exit;
×
625
  }
626

627
  code = metaFinishCommit(pNewMeta, pNewMeta->txn);
189✔
628
  if (code) {
189✔
629
    metaError("vgId:%d failed to finish commit, reason:%s", TD_VID(pVnode), tstrerror(code));
×
630
    goto _exit;
×
631
  }
632

633
  if ((code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL)) != 0) {
189✔
634
    metaError("vgId:%d failed to begin new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
635
  }
636
  metaClose(&pNewMeta);
189✔
637
  cleanupTmpDirOnError = false;
189✔
638
  metaInfo("vgId:%d finish to generate new meta", TD_VID(pVnode));
189✔
639

640
  // Commit the new metadata
641
  metaClose(ppMeta);
189✔
642
  if (taosRenameFile(metaDir, metaBackupDir) != 0) {
189✔
643
    metaError("vgId:%d failed to rename old meta to backup, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
644
    return terrno;
×
645
  }
646

647
  // rename the new meta to old meta
648
  if (taosRenameFile(metaTempDir, metaDir) != 0) {
189✔
649
    metaError("vgId:%d failed to rename new meta to old meta, reason:%s", TD_VID(pVnode), tstrerror(terrno));
×
650
    return terrno;
×
651
  }
652

653
  code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, false);
189✔
654
  if (code) {
189✔
655
    metaError("vgId:%d failed to open new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
×
656
    return code;
×
657
  }
658

659
  metaInfo("vgId:%d successfully opened new meta", TD_VID(pVnode));
189✔
660

661
  return 0;
189✔
662

663
_exit:
×
664
  if (pNewMeta != NULL) {
×
665
    metaClose(&pNewMeta);
×
666
  }
667

668
  if (cleanupTmpDirOnError) {
×
669
    int32_t cleanupCode = metaForceRepairCleanupTmpDir(metaTempDir);
×
670
    if (cleanupCode != 0) {
×
671
      metaError("vgId:%d failed to clean tmp meta dir:%s, reason:%s", TD_VID(pVnode), metaTempDir,
×
672
                tstrerror(cleanupCode));
673
      if (code == 0) {
×
674
        code = cleanupCode;
×
675
      }
676
    }
677
  }
678

679
  return code;
×
680
}
681

682
static int32_t metaRollbackFromRepair(SVnode *pVnode) {
4,872,477✔
683
  int32_t code = TSDB_CODE_SUCCESS;
4,872,477✔
684
  char    metaDir[TSDB_FILENAME_LEN] = {0};
4,872,477✔
685
  char    metaBackupDir[TSDB_FILENAME_LEN] = {0};
4,873,299✔
686
  char    metaTempDir[TSDB_FILENAME_LEN] = {0};
4,874,702✔
687

688
  vnodeGetMetaPath(pVnode, VNODE_META_DIR, metaDir);
4,875,429✔
689
  vnodeGetMetaPath(pVnode, VNODE_META_BACKUP_DIR, metaBackupDir);
4,874,545✔
690
  vnodeGetMetaPath(pVnode, VNODE_META_TMP_DIR, metaTempDir);
4,874,699✔
691

692
  bool metaExists = taosCheckExistFile(metaDir);
4,875,319✔
693
  bool metaBackupExists = taosCheckExistFile(metaBackupDir);
4,874,274✔
694
  bool metaTempExists = taosCheckExistFile(metaTempDir);
4,873,846✔
695

696
  if ((!metaBackupExists && !metaExists && metaTempExists)     //
4,874,607✔
697
      || (metaBackupExists && !metaExists && !metaTempExists)  //
4,874,607✔
698
      || (metaBackupExists && metaExists && metaTempExists)    //
4,874,607✔
699
  ) {
700
    metaError("vgId:%d, invalid meta state, please check!", TD_VID(pVnode));
×
701
    TAOS_RETURN(TSDB_CODE_FAILED);
×
702
  } else if (!metaBackupExists && metaExists && metaTempExists) {
4,874,607✔
703
    taosRemoveDir(metaTempDir);
×
704
  } else if (metaBackupExists && !metaExists && metaTempExists) {
4,874,607✔
705
    code = taosRenameFile(metaTempDir, metaDir);
×
706
    if (code) {
×
707
      metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
708
      TAOS_RETURN(code);
×
709
    }
710
    taosRemoveDir(metaBackupDir);
×
711
  } else if (metaBackupExists && metaExists && !metaTempExists) {
4,874,607✔
712
    taosRemoveDir(metaBackupDir);
184✔
713
  }
714
  return code;
4,870,765✔
715
}
716

717
static int32_t metaForceRepairIfShould(SVnode *pVnode, SMeta **ppMeta) {
4,873,776✔
718
  int32_t           code = TSDB_CODE_SUCCESS;
4,873,776✔
719
  EDmRepairStrategy strategy = DM_REPAIR_STRATEGY_META_FROM_UID;
4,873,776✔
720
  bool              shouldForceRepair = metaShouldForceRepair(pVnode, &strategy);
4,873,776✔
721

722
  // Check if meta should repair
723
  if (!shouldForceRepair) {
4,875,329✔
724
    metaDebug("vgId:%d, meta should not repair!", TD_VID(pVnode));
4,875,047✔
725
    return code;
4,874,221✔
726
  }
727

728
  // Do repair
729
  code = metaForceRepair(ppMeta, strategy);
282✔
730
  if (code) {
282✔
731
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
93✔
732
    return code;
93✔
733
  }
734

735
  return code;
189✔
736
}
737

738
int32_t metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
4,863,730✔
739
  int32_t code = TSDB_CODE_SUCCESS;
4,863,730✔
740

741
  // Rollback if in the middle stage of a repair mode
742
  code = metaRollbackFromRepair(pVnode);
4,863,730✔
743
  if (code) {
4,871,368✔
744
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
745
    TAOS_RETURN(code);
×
746
  }
747

748
  // Do open meta
749
  code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
4,871,368✔
750
  if (code) {
4,875,329✔
751
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
752
    TAOS_RETURN(code);
×
753
  }
754

755
  // Repair meta data if should
756
  code = metaForceRepairIfShould(pVnode, ppMeta);
4,875,329✔
757
  if (code) {
4,875,329✔
758
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
93✔
759
    TAOS_RETURN(code);
93✔
760
  }
761

762
  return TSDB_CODE_SUCCESS;
4,875,236✔
763
}
764

765
int32_t metaUpgrade(SVnode *pVnode, SMeta **ppMeta) {
4,870,184✔
766
  int32_t code = TSDB_CODE_SUCCESS;
4,870,184✔
767
  int32_t lino;
768
  SMeta  *pMeta = *ppMeta;
4,870,184✔
769

770
  if (ttlMgrNeedUpgrade(pMeta->pEnv)) {
4,870,184✔
771
    code = metaBegin(pMeta, META_BEGIN_HEAP_OS);
×
772
    TSDB_CHECK_CODE(code, lino, _exit);
×
773

774
    code = ttlMgrUpgrade(pMeta->pTtlMgr, pMeta);
×
775
    TSDB_CHECK_CODE(code, lino, _exit);
×
776

777
    code = metaCommit(pMeta, pMeta->txn);
×
778
    TSDB_CHECK_CODE(code, lino, _exit);
×
779
  }
780

781
_exit:
4,869,344✔
782
  if (code) {
4,869,344✔
783
    metaError("vgId:%d %s failed at %s:%d since %s", TD_VID(pVnode), __func__, __FILE__, __LINE__, tstrerror(code));
×
784
    metaCleanup(ppMeta);
×
785
  }
786
  return code;
4,869,344✔
787
}
788

789
void metaClose(SMeta **ppMeta) {
4,876,311✔
790
  metaCleanup(ppMeta);
4,876,311✔
791
  return;
4,877,407✔
792
}
793

794
int metaAlterCache(SMeta *pMeta, int32_t nPage) {
5,118✔
795
  int32_t code = 0;
5,118✔
796
  metaWLock(pMeta);
5,118✔
797
  code = tdbAlter(pMeta->pEnv, nPage);
5,118✔
798
  metaULock(pMeta);
5,118✔
799

800
  if (code) {
5,118✔
801
    metaError("vgId:%d %s failed since %s", TD_VID(pMeta->pVnode), __func__, tstrerror(code));
×
802
  }
803
  return code;
5,118✔
804
}
805

806
void metaRLock(SMeta *pMeta) {
2,147,483,647✔
807
  metaTrace("meta rlock %p", &pMeta->lock);
2,147,483,647✔
808
  if (taosThreadRwlockRdlock(&pMeta->lock) != 0) {
2,147,483,647✔
809
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
810
  }
811
}
2,147,483,647✔
812

813
void metaWLock(SMeta *pMeta) {
169,955,349✔
814
  metaTrace("meta wlock %p", &pMeta->lock);
169,955,349✔
815
  if (taosThreadRwlockWrlock(&pMeta->lock) != 0) {
169,955,349✔
816
    metaError("vgId:%d failed to lock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
817
  }
818
}
169,976,281✔
819

820
void metaULock(SMeta *pMeta) {
2,147,483,647✔
821
  metaTrace("meta ulock %p", &pMeta->lock);
2,147,483,647✔
822
  if (taosThreadRwlockUnlock(&pMeta->lock) != 0) {
2,147,483,647✔
823
    metaError("vgId:%d failed to unlock %p", TD_VID(pMeta->pVnode), &pMeta->lock);
×
824
  }
825
}
2,147,483,647✔
826

827
static void metaCleanup(SMeta **ppMeta) {
4,875,418✔
828
  SMeta *pMeta = *ppMeta;
4,875,418✔
829
  if (pMeta) {
4,875,902✔
830
    metaInfo("vgId:%d meta clean up, path:%s", TD_VID(pMeta->pVnode), pMeta->path);
4,876,249✔
831
    if (pMeta->pEnv) metaAbort(pMeta);
4,878,732✔
832
    if (pMeta->pCache) metaCacheClose(pMeta);
4,876,549✔
833
#ifdef BUILD_NO_CALL
834
    if (pMeta->pIdx) metaCloseIdx(pMeta);
835
#endif
836
    if (pMeta->pStreamDb) tdbTbClose(pMeta->pStreamDb);
4,877,407✔
837
    if (pMeta->pNcolIdx) tdbTbClose(pMeta->pNcolIdx);
4,877,407✔
838
    if (pMeta->pBtimeIdx) tdbTbClose(pMeta->pBtimeIdx);
4,877,407✔
839
    if (pMeta->pSmaIdx) tdbTbClose(pMeta->pSmaIdx);
4,877,407✔
840
    if (pMeta->pTtlMgr) ttlMgrClose(pMeta->pTtlMgr);
4,877,407✔
841
    if (pMeta->pTagIvtIdx) indexClose(pMeta->pTagIvtIdx);
4,877,407✔
842
    if (pMeta->pTagIdx) tdbTbClose(pMeta->pTagIdx);
4,877,407✔
843
    if (pMeta->pCtbIdx) tdbTbClose(pMeta->pCtbIdx);
4,877,407✔
844
    if (pMeta->pSuidIdx) tdbTbClose(pMeta->pSuidIdx);
4,877,407✔
845
    if (pMeta->pNameIdx) tdbTbClose(pMeta->pNameIdx);
4,877,407✔
846
    if (pMeta->pUidIdx) tdbTbClose(pMeta->pUidIdx);
4,877,167✔
847
    if (pMeta->pSkmDb) tdbTbClose(pMeta->pSkmDb);
4,876,927✔
848
    if (pMeta->pSkmExtDb) tdbTbClose(pMeta->pSkmExtDb);
4,877,167✔
849
    if (pMeta->pTbDb) tdbTbClose(pMeta->pTbDb);
4,877,167✔
850
    if (pMeta->pEnv) tdbClose(pMeta->pEnv);
4,877,167✔
851
    metaDestroyLock(pMeta);
4,877,407✔
852

853
    taosHashCleanup(pMeta->uidSuidHash);
4,877,407✔
854
    taosHashCleanup(pMeta->uidNameHash);
4,877,407✔
855
    taosMemoryFreeClear(*ppMeta);
4,877,407✔
856
  }
857
}
4,877,060✔
858

859
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
2,147,483,647✔
860
  STbDbKey *pTbDbKey1 = (STbDbKey *)pKey1;
2,147,483,647✔
861
  STbDbKey *pTbDbKey2 = (STbDbKey *)pKey2;
2,147,483,647✔
862

863
  TDB_KEY_ALIGN(pTbDbKey1, pTbDbKey2, STbDbKey);
864

865
  if (pTbDbKey1->version > pTbDbKey2->version) {
2,147,483,647✔
866
    return 1;
2,147,483,647✔
867
  } else if (pTbDbKey1->version < pTbDbKey2->version) {
2,147,483,647✔
868
    return -1;
2,147,483,647✔
869
  }
870

871
  if (pTbDbKey1->uid > pTbDbKey2->uid) {
2,147,483,647✔
872
    return 1;
775,037,752✔
873
  } else if (pTbDbKey1->uid < pTbDbKey2->uid) {
2,147,483,647✔
874
    return -1;
644,895,772✔
875
  }
876

877
  return 0;
2,147,483,647✔
878
}
879

880
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
458,190,933✔
881
  SSkmDbKey *pSkmDbKey1 = (SSkmDbKey *)pKey1;
458,190,933✔
882
  SSkmDbKey *pSkmDbKey2 = (SSkmDbKey *)pKey2;
458,190,933✔
883

884
  TDB_KEY_ALIGN(pSkmDbKey1, pSkmDbKey2, SSkmDbKey);
885

886
  if (pSkmDbKey1->uid > pSkmDbKey2->uid) {
458,190,933✔
887
    return 1;
160,529,421✔
888
  } else if (pSkmDbKey1->uid < pSkmDbKey2->uid) {
297,947,625✔
889
    return -1;
77,802,129✔
890
  }
891

892
  if (pSkmDbKey1->sver > pSkmDbKey2->sver) {
220,149,980✔
893
    return 1;
128,733,233✔
894
  } else if (pSkmDbKey1->sver < pSkmDbKey2->sver) {
91,387,513✔
895
    return -1;
15,547,348✔
896
  }
897

898
  return 0;
75,853,795✔
899
}
900

901
static int uidIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
2,147,483,647✔
902
  tb_uid_t uid1 = taosGetInt64Aligned((int64_t *)pKey1);
2,147,483,647✔
903
  tb_uid_t uid2 = taosGetInt64Aligned((int64_t *)pKey2);
2,147,483,647✔
904

905
  if (uid1 > uid2) {
2,147,483,647✔
906
    return 1;
2,147,483,647✔
907
  } else if (uid1 < uid2) {
2,147,483,647✔
908
    return -1;
1,782,666,811✔
909
  }
910

911
  return 0;
1,276,001,999✔
912
}
913

914
static int ctbIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
1,110,615,322✔
915
  SCtbIdxKey *pCtbIdxKey1 = (SCtbIdxKey *)pKey1;
1,110,615,322✔
916
  SCtbIdxKey *pCtbIdxKey2 = (SCtbIdxKey *)pKey2;
1,110,615,322✔
917

918
  TDB_KEY_ALIGN(pCtbIdxKey1, pCtbIdxKey2, SCtbIdxKey);
919

920
  if (pCtbIdxKey1->suid > pCtbIdxKey2->suid) {
1,110,615,322✔
921
    return 1;
117,021,095✔
922
  } else if (pCtbIdxKey1->suid < pCtbIdxKey2->suid) {
993,692,239✔
923
    return -1;
47,871,823✔
924
  }
925

926
  if (pCtbIdxKey1->uid > pCtbIdxKey2->uid) {
945,838,115✔
927
    return 1;
531,993,864✔
928
  } else if (pCtbIdxKey1->uid < pCtbIdxKey2->uid) {
413,995,922✔
929
    return -1;
347,055,761✔
930
  }
931

932
  return 0;
66,950,404✔
933
}
934

935
int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
901,813,126✔
936
  STagIdxKey *pTagIdxKey1 = (STagIdxKey *)pKey1;
901,813,126✔
937
  STagIdxKey *pTagIdxKey2 = (STagIdxKey *)pKey2;
901,813,126✔
938
  tb_uid_t    uid1 = 0, uid2 = 0;
901,813,126✔
939
  int         c;
940

941
  TDB_KEY_ALIGN(pTagIdxKey1, pTagIdxKey2, STagIdxKey);
942

943
  // compare suid
944
  if (pTagIdxKey1->suid > pTagIdxKey2->suid) {
901,813,126✔
945
    return 1;
15,208,072✔
946
  } else if (pTagIdxKey1->suid < pTagIdxKey2->suid) {
886,637,752✔
947
    return -1;
2,481,693✔
948
  }
949

950
  // compare column id
951
  if (pTagIdxKey1->cid > pTagIdxKey2->cid) {
884,151,007✔
952
    return 1;
31,639,056✔
953
  } else if (pTagIdxKey1->cid < pTagIdxKey2->cid) {
852,514,490✔
954
    return -1;
16,109,756✔
955
  }
956

957
  if (pTagIdxKey1->type != pTagIdxKey2->type) {
836,416,059✔
958
    metaError("meta/open: incorrect tag idx type.");
×
959
    return TSDB_CODE_FAILED;
×
960
  }
961

962
  // check NULL, NULL is always the smallest
963
  if (pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
836,406,114✔
964
    return -1;
251,963✔
965
  } else if (!pTagIdxKey1->isNull && pTagIdxKey2->isNull) {
836,165,991✔
966
    return 1;
830,020✔
967
  } else if (!pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
835,350,921✔
968
    // all not NULL, compr tag vals
969
    __compar_fn_t func = getComparFunc(pTagIdxKey1->type, 0);
823,600,800✔
970
    if (func == NULL) {
823,574,897✔
971
      metaError("meta/open: %s", terrstr());
×
972
      return TSDB_CODE_FAILED;
×
973
    }
974
    c = func(pTagIdxKey1->data, pTagIdxKey2->data);
823,574,897✔
975
    if (c) return c;
823,549,550✔
976
  }
977

978
  // both null or tag values are equal, then continue to compare uids
979
  if (IS_VAR_DATA_TYPE(pTagIdxKey1->type)) {
130,757,066✔
980
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + varDataTLen(pTagIdxKey1->data));
55,789,468✔
981
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + varDataTLen(pTagIdxKey2->data));
55,791,154✔
982
  } else {
983
    uid1 = *(tb_uid_t *)(pTagIdxKey1->data + tDataTypes[pTagIdxKey1->type].bytes);
74,983,450✔
984
    uid2 = *(tb_uid_t *)(pTagIdxKey2->data + tDataTypes[pTagIdxKey2->type].bytes);
74,984,636✔
985
  }
986

987
  // compare uid
988
  if (uid1 < uid2) {
130,773,731✔
989
    return -1;
12,038,002✔
990
  } else if (uid1 > uid2) {
118,735,729✔
991
    return 1;
102,074,092✔
992
  } else {
993
    return 0;
16,661,637✔
994
  }
995

996
  return 0;
997
}
998

999
static int btimeIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
278,563,640✔
1000
  SBtimeIdxKey *pBtimeIdxKey1 = (SBtimeIdxKey *)pKey1;
278,563,640✔
1001
  SBtimeIdxKey *pBtimeIdxKey2 = (SBtimeIdxKey *)pKey2;
278,563,640✔
1002

1003
  TDB_KEY_ALIGN(pBtimeIdxKey1, pBtimeIdxKey2, SBtimeIdxKey);
1004

1005
  if (pBtimeIdxKey1->btime > pBtimeIdxKey2->btime) {
278,563,640✔
1006
    return 1;
248,837,688✔
1007
  } else if (pBtimeIdxKey1->btime < pBtimeIdxKey2->btime) {
29,736,778✔
1008
    return -1;
2,338,308✔
1009
  }
1010

1011
  if (pBtimeIdxKey1->uid > pBtimeIdxKey2->uid) {
27,398,005✔
1012
    return 1;
23,692,481✔
1013
  } else if (pBtimeIdxKey1->uid < pBtimeIdxKey2->uid) {
3,706,091✔
1014
    return -1;
743,951✔
1015
  }
1016

1017
  return 0;
2,962,140✔
1018
}
1019

1020
static int ncolIdxCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
1021
  SNcolIdxKey *pNcolIdxKey1 = (SNcolIdxKey *)pKey1;
×
1022
  SNcolIdxKey *pNcolIdxKey2 = (SNcolIdxKey *)pKey2;
×
1023

1024
  TDB_KEY_ALIGN(pNcolIdxKey1, pNcolIdxKey2, SNcolIdxKey);
1025

1026
  if (pNcolIdxKey1->ncol > pNcolIdxKey2->ncol) {
×
1027
    return 1;
×
1028
  } else if (pNcolIdxKey1->ncol < pNcolIdxKey2->ncol) {
×
1029
    return -1;
×
1030
  }
1031

1032
  if (pNcolIdxKey1->uid > pNcolIdxKey2->uid) {
×
1033
    return 1;
×
1034
  } else if (pNcolIdxKey1->uid < pNcolIdxKey2->uid) {
×
1035
    return -1;
×
1036
  }
1037

1038
  return 0;
×
1039
}
1040

1041
static int smaIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
1042
  SSmaIdxKey *pSmaIdxKey1 = (SSmaIdxKey *)pKey1;
×
1043
  SSmaIdxKey *pSmaIdxKey2 = (SSmaIdxKey *)pKey2;
×
1044

1045
  TDB_KEY_ALIGN(pSmaIdxKey1, pSmaIdxKey2, SSmaIdxKey);
1046

1047
  if (pSmaIdxKey1->uid > pSmaIdxKey2->uid) {
×
1048
    return 1;
×
1049
  } else if (pSmaIdxKey1->uid < pSmaIdxKey2->uid) {
×
1050
    return -1;
×
1051
  }
1052

1053
  if (pSmaIdxKey1->smaUid > pSmaIdxKey2->smaUid) {
×
1054
    return 1;
×
1055
  } else if (pSmaIdxKey1->smaUid < pSmaIdxKey2->smaUid) {
×
1056
    return -1;
×
1057
  }
1058

1059
  return 0;
×
1060
}
1061

1062
static int taskIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
×
1063
  int32_t uid1 = *(int32_t *)pKey1;
×
1064
  int32_t uid2 = *(int32_t *)pKey2;
×
1065

1066
  if (uid1 > uid2) {
×
1067
    return 1;
×
1068
  } else if (uid1 < uid2) {
×
1069
    return -1;
×
1070
  }
1071

1072
  return 0;
×
1073
}
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