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

taosdata / TDengine / #4917

07 Jan 2026 03:52PM UTC coverage: 65.42% (+0.02%) from 65.402%
#4917

push

travis-ci

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

31 of 34 new or added lines in 2 files covered. (91.18%)

819 existing lines in 129 files now uncovered.

202679 of 309814 relevant lines covered (65.42%)

116724351.99 hits per line

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

46.94
/source/dnode/mnode/sdb/src/sdbFile.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
#define _DEFAULT_SOURCE
17
#include "crypt.h"
18
#include "sdb.h"
19
#include "sync.h"
20
#include "tchecksum.h"
21
#include "tencrypt.h"
22
#include "tglobal.h"
23
#include "wal.h"
24

25
#define SDB_TABLE_SIZE   24
26
#define SDB_RESERVE_SIZE 512
27
#define SDB_FILE_VER     1
28

29
#define SDB_TABLE_SIZE_EXTRA   SDB_MAX
30
#define SDB_RESERVE_SIZE_EXTRA (512 - (SDB_TABLE_SIZE_EXTRA - SDB_TABLE_SIZE) * 2 * sizeof(int64_t))
31

32
static int32_t sdbDeployData(SSdb *pSdb) {
277,230✔
33
  int32_t code = 0;
277,230✔
34
  mInfo("start to deploy sdb");
277,230✔
35

36
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
13,307,040✔
37
    SdbDeployFp fp = pSdb->deployFps[i];
13,029,810✔
38
    if (fp == NULL) continue;
13,029,810✔
39

40
    mInfo("start to deploy sdb:%s", sdbTableName(i));
1,940,610✔
41
    code = (*fp)(pSdb->pMnode);
1,940,610✔
42
    if (code != 0) {
1,940,610✔
43
      mError("failed to deploy sdb:%s since %s", sdbTableName(i), tstrerror(code));
×
44
      return -1;
×
45
    }
46
  }
47

48
  mInfo("sdb deploy success");
277,230✔
49
  return 0;
277,230✔
50
}
51

52
static int32_t sdbUpgradeData(SSdb *pSdb, int32_t version) {
349,575✔
53
  int32_t code = 0;
349,575✔
54
  mInfo("start to upgrade sdb");
349,575✔
55

56
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
16,779,600✔
57
    SdbUpgradeFp fp = pSdb->upgradeFps[i];
16,430,025✔
58
    if (fp == NULL) continue;
16,430,025✔
59

60
    mInfo("start to upgrade sdb:%s", sdbTableName(i));
349,575✔
61
    code = (*fp)(pSdb->pMnode, version);
349,575✔
62
    if (code != 0) {
349,575✔
63
      mError("failed to upgrade sdb:%s since %s", sdbTableName(i), tstrerror(code));
×
64
      return -1;
×
65
    }
66
  }
67

68
  mInfo("sdb upgrade success");
349,575✔
69
  return 0;
349,575✔
70
}
71

72
static int32_t sdbAfterRestoredData(SSdb *pSdb) {
182,994✔
73
  int32_t code = 0;
182,994✔
74
  mInfo("start to prepare sdb");
182,994✔
75

76
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
8,783,712✔
77
    SdbAfterRestoredFp fp = pSdb->afterRestoredFps[i];
8,600,718✔
78
    if (fp == NULL) continue;
8,600,718✔
79

80
    mInfo("start to prepare sdb:%s", sdbTableName(i));
182,994✔
81
    code = (*fp)(pSdb->pMnode);
182,994✔
82
    if (code != 0) {
182,994✔
UNCOV
83
      mError("failed to prepare sdb:%s since %s", sdbTableName(i), tstrerror(code));
×
UNCOV
84
      return -1;
×
85
    }
86
  }
87

88
  mInfo("sdb prepare success");
182,994✔
89
  return 0;
182,994✔
90
}
91

92
static void sdbResetData(SSdb *pSdb) {
107,654✔
93
  mInfo("start to reset sdb");
107,654✔
94

95
  for (ESdbType i = 0; i < SDB_MAX; ++i) {
5,167,392✔
96
    SHashObj *hash = pSdb->hashObjs[i];
5,059,738✔
97
    if (hash == NULL) continue;
5,059,738✔
98

99
    sdbWriteLock(pSdb, i);
4,521,468✔
100

101
    SSdbRow **ppRow = taosHashIterate(hash, NULL);
4,521,468✔
102
    while (ppRow != NULL) {
4,521,468✔
103
      SSdbRow *pRow = *ppRow;
×
104
      if (pRow == NULL) continue;
×
105

106
      sdbFreeRow(pSdb, pRow, true);
×
107
      ppRow = taosHashIterate(hash, ppRow);
×
108
    }
109

110
    taosHashClear(pSdb->hashObjs[i]);
4,521,468✔
111
    pSdb->tableVer[i] = 0;
4,521,468✔
112
    pSdb->maxId[i] = 0;
4,521,468✔
113

114
    sdbUnLock(pSdb, i);
4,521,468✔
115

116
    mInfo("sdb:%s is reset", sdbTableName(i));
4,521,468✔
117
  }
118

119
  pSdb->applyIndex = -1;
107,654✔
120
  pSdb->applyTerm = -1;
107,654✔
121
  pSdb->applyConfig = -1;
107,654✔
122
  pSdb->commitIndex = -1;
107,654✔
123
  pSdb->commitTerm = -1;
107,654✔
124
  pSdb->commitConfig = -1;
107,654✔
125
  mInfo("sdb reset success");
107,654✔
126
}
107,654✔
127

128
static int32_t sdbReadFileHead(SSdb *pSdb, TdFilePtr pFile) {
95,416✔
129
  int32_t code = 0;
95,416✔
130
  int64_t sver = 0;
95,416✔
131
  int32_t ret = taosReadFile(pFile, &sver, sizeof(int64_t));
95,416✔
132
  if (ret < 0) {
95,416✔
133
    return terrno;
×
134
  }
135
  if (ret != sizeof(int64_t)) {
95,416✔
136
    code = TSDB_CODE_FILE_CORRUPTED;
×
137
    TAOS_RETURN(code);
×
138
  }
139
  if (sver != SDB_FILE_VER) {
95,416✔
140
    code = TSDB_CODE_FILE_CORRUPTED;
×
141
    TAOS_RETURN(code);
×
142
  }
143

144
  ret = taosReadFile(pFile, &pSdb->applyIndex, sizeof(int64_t));
95,416✔
145
  if (ret < 0) {
95,416✔
146
    return terrno;
×
147
  }
148
  if (ret != sizeof(int64_t)) {
95,416✔
149
    code = TSDB_CODE_FILE_CORRUPTED;
×
150
    TAOS_RETURN(code);
×
151
  }
152

153
  ret = taosReadFile(pFile, &pSdb->applyTerm, sizeof(int64_t));
95,416✔
154
  if (ret < 0) {
95,416✔
155
    return terrno;
×
156
  }
157
  if (ret != sizeof(int64_t)) {
95,416✔
158
    code = TSDB_CODE_FILE_CORRUPTED;
×
159
    TAOS_RETURN(code);
×
160
  }
161

162
  ret = taosReadFile(pFile, &pSdb->applyConfig, sizeof(int64_t));
95,416✔
163
  if (ret < 0) {
95,416✔
164
    return terrno;
×
165
  }
166
  if (ret != sizeof(int64_t)) {
95,416✔
167
    code = TSDB_CODE_FILE_CORRUPTED;
×
168
    TAOS_RETURN(code);
×
169
  }
170

171
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
2,385,400✔
172
    int64_t maxId = 0;
2,289,984✔
173
    ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
2,289,984✔
174
    if (ret < 0) {
2,289,984✔
175
      return terrno;
×
176
    }
177
    if (ret != sizeof(int64_t)) {
2,289,984✔
178
      code = TSDB_CODE_FILE_CORRUPTED;
×
179
      TAOS_RETURN(code);
×
180
    }
181
    if (i < SDB_MAX) {
2,289,984✔
182
      pSdb->maxId[i] = maxId;
2,289,984✔
183
    }
184
  }
185

186
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
2,385,400✔
187
    int64_t ver = 0;
2,289,984✔
188
    ret = taosReadFile(pFile, &ver, sizeof(int64_t));
2,289,984✔
189
    if (ret < 0) {
2,289,984✔
190
      return terrno;
×
191
    }
192
    if (ret != sizeof(int64_t)) {
2,289,984✔
193
      code = TSDB_CODE_FILE_CORRUPTED;
×
194
      TAOS_RETURN(code);
×
195
    }
196
    if (i < SDB_MAX) {
2,289,984✔
197
      pSdb->tableVer[i] = ver;
2,289,984✔
198
    }
199
  }
200

201
  // for sdb compatibility
202
  for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
2,289,984✔
203
    int64_t maxId = 0;
2,194,568✔
204
    ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
2,194,568✔
205
    if (ret < 0) {
2,194,568✔
206
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
207
      TAOS_RETURN(code);
×
208
    }
209
    if (ret != sizeof(int64_t)) {
2,194,568✔
210
      code = TSDB_CODE_FILE_CORRUPTED;
×
211
      TAOS_RETURN(code);
×
212
    }
213
    if (i < SDB_MAX) {
2,194,568✔
214
      pSdb->maxId[i] = maxId;
2,194,568✔
215
    }
216

217
    int64_t ver = 0;
2,194,568✔
218
    ret = taosReadFile(pFile, &ver, sizeof(int64_t));
2,194,568✔
219
    if (ret < 0) {
2,194,568✔
220
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
221
      TAOS_RETURN(code);
×
222
    }
223
    if (ret != sizeof(int64_t)) {
2,194,568✔
224
      code = TSDB_CODE_FILE_CORRUPTED;
×
225
      TAOS_RETURN(code);
×
226
    }
227
    if (i < SDB_MAX) {
2,194,568✔
228
      pSdb->tableVer[i] = ver;
2,194,568✔
229
    }
230
  }
231

232
  char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
95,416✔
233
  ret = taosReadFile(pFile, reserve, sizeof(reserve));
95,416✔
234
  if (ret < 0) {
95,416✔
235
    return terrno;
×
236
  }
237
  if (ret != sizeof(reserve)) {
95,416✔
238
    code = TSDB_CODE_FILE_CORRUPTED;
×
239
    TAOS_RETURN(code);
×
240
  }
241

242
  return 0;
95,416✔
243
}
244

245
static int32_t sdbWriteFileHead(SSdb *pSdb, TdFilePtr pFile) {
741,279✔
246
  int64_t sver = SDB_FILE_VER;
741,279✔
247
  if (taosWriteFile(pFile, &sver, sizeof(int64_t)) != sizeof(int64_t)) {
741,279✔
248
    return terrno;
×
249
  }
250

251
  mInfo("vgId:1, write sdb file with sdb applyIndex:%" PRId64 " term:%" PRId64 " config:%" PRId64, pSdb->applyIndex,
741,279✔
252
        pSdb->applyTerm, pSdb->applyConfig);
253
  if (taosWriteFile(pFile, &pSdb->applyIndex, sizeof(int64_t)) != sizeof(int64_t)) {
741,279✔
254
    return terrno;
×
255
  }
256

257
  if (taosWriteFile(pFile, &pSdb->applyTerm, sizeof(int64_t)) != sizeof(int64_t)) {
741,279✔
258
    return terrno;
×
259
  }
260

261
  if (taosWriteFile(pFile, &pSdb->applyConfig, sizeof(int64_t)) != sizeof(int64_t)) {
741,279✔
262
    return terrno;
×
263
  }
264

265
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
18,531,975✔
266
    int64_t maxId = 0;
17,790,696✔
267
    if (i < SDB_MAX) {
17,790,696✔
268
      maxId = pSdb->maxId[i];
17,790,696✔
269
    }
270
    if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
17,790,696✔
271
      return terrno;
×
272
    }
273
  }
274

275
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
18,531,975✔
276
    int64_t ver = 0;
17,790,696✔
277
    if (i < SDB_MAX) {
17,790,696✔
278
      ver = pSdb->tableVer[i];
17,790,696✔
279
    }
280
    if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
17,790,696✔
281
      return terrno;
×
282
    }
283
  }
284

285
  // for sdb compatibility
286
  for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
17,790,696✔
287
    int64_t maxId = 0;
17,049,417✔
288
    if (i < SDB_MAX) {
17,049,417✔
289
      maxId = pSdb->maxId[i];
17,049,417✔
290
    }
291
    if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
17,049,417✔
292
      return terrno;
×
293
    }
294

295
    int64_t ver = 0;
17,049,417✔
296
    if (i < SDB_MAX) {
17,049,417✔
297
      ver = pSdb->tableVer[i];
17,049,417✔
298
    }
299
    if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
17,049,417✔
300
      return terrno;
×
301
    }
302
  }
303

304
  char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
741,279✔
305
  if (taosWriteFile(pFile, reserve, sizeof(reserve)) != sizeof(reserve)) {
741,279✔
306
    return terrno;
×
307
  }
308

309
  return 0;
741,279✔
310
}
311

312
static int32_t sdbReadFileImp(SSdb *pSdb) {
107,654✔
313
  int64_t offset = 0;
107,654✔
314
  int32_t code = 0;
107,654✔
315
  int32_t readLen = 0;
107,654✔
316
  int64_t ret = 0;
107,654✔
317
  char    file[PATH_MAX] = {0};
107,654✔
318
  int32_t bufLen = TSDB_MAX_MSG_SIZE;
107,654✔
319

320
  snprintf(file, sizeof(file), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
107,654✔
321
  mInfo("start to read sdb file:%s", file);
107,654✔
322

323
  SSdbRaw *pRaw = taosMemoryMalloc(bufLen + 100);
107,654✔
324
  if (pRaw == NULL) {
107,654✔
325
    code = terrno;
×
326
    mError("failed read sdb file since %s", tstrerror(code));
×
327
    TAOS_RETURN(code);
×
328
  }
329

330
  TdFilePtr pFile = taosOpenFile(file, TD_FILE_READ);
107,654✔
331
  if (pFile == NULL) {
107,654✔
332
    taosMemoryFree(pRaw);
12,238✔
333
    code = terrno;
12,238✔
334
    mInfo("read sdb file:%s finished since %s", file, tstrerror(code));
12,238✔
335
    return 0;
12,238✔
336
  }
337

338
  code = sdbReadFileHead(pSdb, pFile);
95,416✔
339
  if (code != 0) {
95,416✔
340
    mError("failed to read sdb file:%s head since %s", file, tstrerror(code));
×
341
    taosMemoryFree(pRaw);
×
342
    int32_t ret = 0;
×
343
    if ((ret = taosCloseFile(&pFile)) != 0) {
×
344
      mError("failed to close sdb file:%s since %s", file, tstrerror(ret));
×
345
    }
346
    return code;
×
347
  }
348

349
  int64_t tableVer[SDB_MAX] = {0};
95,416✔
350
  memcpy(tableVer, pSdb->tableVer, sizeof(tableVer));
95,416✔
351

352
  while (1) {
13,657,282✔
353
    readLen = sizeof(SSdbRaw);
13,752,698✔
354
    ret = taosReadFile(pFile, pRaw, readLen);
13,752,698✔
355
    if (ret == 0) break;
13,752,698✔
356

357
    if (ret < 0) {
13,657,282✔
358
      code = terrno;
×
359
      mError("failed to read sdb file:%s since %s", file, tstrerror(code));
×
360
      goto _OVER;
×
361
    }
362

363
    if (ret != readLen) {
13,657,282✔
364
      code = TSDB_CODE_FILE_CORRUPTED;
×
365
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " != readLen:%d", file, tstrerror(code), ret, readLen);
×
366
      goto _OVER;
×
367
    }
368

369
    readLen = pRaw->dataLen + sizeof(int32_t);
13,657,282✔
370
    if (tsMetaKey[0] != '\0') {
13,657,282✔
371
      readLen = ENCRYPTED_LEN(pRaw->dataLen) + sizeof(int32_t);
×
372
    }
373
    if (readLen >= bufLen) {
13,657,282✔
374
      bufLen = pRaw->dataLen * 2;
×
375
      SSdbRaw *pNewRaw = taosMemoryMalloc(bufLen + 100);
×
376
      if (pNewRaw == NULL) {
×
377
        code = terrno;
×
378
        mError("failed read sdb file since malloc new sdbRaw size:%d failed", bufLen);
×
379
        goto _OVER;
×
380
      }
381
      mInfo("malloc new sdb raw size:%d, type:%d", bufLen, pRaw->type);
×
382
      memcpy(pNewRaw, pRaw, sizeof(SSdbRaw));
×
383
      sdbFreeRaw(pRaw);
×
384
      pRaw = pNewRaw;
×
385
    }
386

387
    ret = taosReadFile(pFile, pRaw->pData, readLen);
13,657,282✔
388
    if (ret < 0) {
13,657,282✔
389
      code = terrno;
×
390
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " readLen:%d", file, tstrerror(code), ret, readLen);
×
391
      goto _OVER;
×
392
    }
393

394
    if (ret != readLen) {
13,657,282✔
395
      code = TSDB_CODE_FILE_CORRUPTED;
×
396
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " != readLen:%d", file, tstrerror(code), ret, readLen);
×
397
      goto _OVER;
×
398
    }
399

400
    if (taosWaitCfgKeyLoaded() != 0) {
13,657,282✔
401
      code = terrno;
×
402
      goto _OVER;
×
403
    }
404

405
    if (tsMetaKey[0] != '\0') {
13,657,282✔
406
      int32_t count = 0;
×
407

408
      char *plantContent = taosMemoryMalloc(ENCRYPTED_LEN(pRaw->dataLen));
×
409
      if (plantContent == NULL) {
×
410
        code = terrno;
×
411
        goto _OVER;
×
412
      }
413

414
      SCryptOpts opts = {0};
×
415
      opts.len = ENCRYPTED_LEN(pRaw->dataLen);
×
416
      opts.source = pRaw->pData;
×
417
      opts.result = plantContent;
×
418
      opts.unitLen = 16;
×
419
      opts.pOsslAlgrName = taosGetEncryptAlgoName(tsEncryptAlgorithmType);
×
420
      tstrncpy(opts.key, tsMetaKey, ENCRYPT_KEY_LEN + 1);
×
421

422
      count = CBC_Decrypt(&opts);
×
423
      if (count <= 0) {
×
424
        code = terrno;
×
425
        goto _OVER;
×
426
      }
427

428
      // mDebug("read sdb, CBC Decrypt dataLen:%d, descrypted len:%d, %s", pRaw->dataLen, count, __FUNCTION__);
429

430
      memcpy(pRaw->pData, plantContent, pRaw->dataLen);
×
431
      taosMemoryFree(plantContent);
×
432
      memcpy(pRaw->pData + pRaw->dataLen, &pRaw->pData[ENCRYPTED_LEN(pRaw->dataLen)], sizeof(int32_t));
×
433
    }
434

435
    int32_t totalLen = sizeof(SSdbRaw) + pRaw->dataLen + sizeof(int32_t);
13,657,282✔
436
    if ((!taosCheckChecksumWhole((const uint8_t *)pRaw, totalLen)) != 0) {
27,314,564✔
437
      code = TSDB_CODE_CHECKSUM_ERROR;
×
438
      mError("failed to read sdb file:%s since %s, readLen:%d", file, tstrerror(code), readLen);
×
439
      goto _OVER;
×
440
    }
441

442
    if (pRaw->type >= SDB_MAX) {
13,657,282✔
443
      mInfo("skip sdb raw type:%d since it is not supported", pRaw->type);
×
444
      continue;
×
445
    }
446

447
    code = sdbWriteWithoutFree(pSdb, pRaw);
13,657,282✔
448
    if (code != 0) {
13,657,282✔
449
      mError("failed to exec sdbWrite while read sdb file:%s since %s", file, terrstr());
×
450
      goto _OVER;
×
451
    }
452
  }
453

454
  code = 0;
95,416✔
455
  pSdb->commitIndex = pSdb->applyIndex;
95,416✔
456
  pSdb->commitTerm = pSdb->applyTerm;
95,416✔
457
  pSdb->commitConfig = pSdb->applyConfig;
95,416✔
458
  memcpy(pSdb->tableVer, tableVer, sizeof(tableVer));
95,416✔
459
  mInfo("vgId:1, trans:0, read sdb file:%s success, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64, file,
95,416✔
460
        pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig);
461

462
_OVER:
95,350✔
463
  if ((ret = taosCloseFile(&pFile)) != 0) {
95,416✔
464
    mError("failed to close sdb file:%s since %s", file, tstrerror(ret));
×
465
  }
466
  sdbFreeRaw(pRaw);
95,416✔
467

468
  TAOS_RETURN(code);
95,416✔
469
}
470

471
int32_t sdbReadFile(SSdb *pSdb) {
107,654✔
472
  (void)taosThreadMutexLock(&pSdb->filelock);
107,654✔
473

474
  sdbResetData(pSdb);
107,654✔
475
  int32_t code = sdbReadFileImp(pSdb);
107,654✔
476
  if (code != 0) {
107,654✔
477
    mError("failed to read sdb file since %s", tstrerror(code));
×
478
    sdbResetData(pSdb);
×
479
  }
480

481
  (void)taosThreadMutexUnlock(&pSdb->filelock);
107,654✔
482
  return code;
107,654✔
483
}
484

485
static int32_t sdbWriteFileImp(SSdb *pSdb, int32_t skip_type) {
741,279✔
486
  int32_t code = 0;
741,279✔
487

488
  char tmpfile[PATH_MAX] = {0};
741,279✔
489
  snprintf(tmpfile, sizeof(tmpfile), "%s%ssdb.data", pSdb->tmpDir, TD_DIRSEP);
741,279✔
490
  char curfile[PATH_MAX] = {0};
741,279✔
491
  snprintf(curfile, sizeof(curfile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
741,279✔
492

493
  mInfo("start to write sdb file, apply index:%" PRId64 " term:%" PRId64 " config:%" PRId64 ", commit index:%" PRId64
741,279✔
494
        " term:%" PRId64 " config:%" PRId64 ", file:%s",
495
        pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig, pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig,
496
        curfile);
497

498
  TdFilePtr pFile = taosOpenFile(tmpfile, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
741,279✔
499
  if (pFile == NULL) {
741,279✔
500
    code = terrno;
×
501
    mError("failed to open sdb file:%s for write since %s", tmpfile, tstrerror(code));
×
502
    TAOS_RETURN(code);
×
503
  }
504

505
  code = sdbWriteFileHead(pSdb, pFile);
741,279✔
506
  if (code != 0) {
741,279✔
507
    mError("failed to write sdb file:%s head since %s", tmpfile, tstrerror(code));
×
508
    int32_t ret = 0;
×
509
    if ((ret = taosCloseFile(&pFile)) != 0) {
×
510
      mError("failed to close sdb file:%s since %s", tmpfile, tstrerror(ret));
×
511
    }
512
    return code;
×
513
  }
514

515
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
35,581,392✔
516
    if (i == skip_type) continue;
34,840,113✔
517
    SdbEncodeFp encodeFp = pSdb->encodeFps[i];
34,840,113✔
518
    if (encodeFp == NULL) continue;
34,840,113✔
519

520
    mInfo("write %s to sdb file, total %d rows", sdbTableName(i), sdbGetSize(pSdb, i));
30,392,439✔
521

522
    SHashObj *hash = pSdb->hashObjs[i];
30,392,439✔
523
    sdbWriteLock(pSdb, i);
30,392,439✔
524

525
    SSdbRow **ppRow = taosHashIterate(hash, NULL);
30,392,439✔
526
    while (ppRow != NULL) {
131,863,818✔
527
      SSdbRow *pRow = *ppRow;
101,471,379✔
528
      if (pRow == NULL) {
101,471,379✔
529
        ppRow = taosHashIterate(hash, ppRow);
×
530
        continue;
×
531
      }
532

533
      if (pRow->status != SDB_STATUS_READY && pRow->status != SDB_STATUS_DROPPING) {
101,471,379✔
534
        sdbPrintOper(pSdb, pRow, "not-write");
26,677✔
535
        ppRow = taosHashIterate(hash, ppRow);
26,677✔
536
        continue;
26,677✔
537
      }
538

539
      sdbPrintOper(pSdb, pRow, "write");
101,444,702✔
540

541
      SSdbRaw *pRaw = (*encodeFp)(pRow->pObj);
101,444,702✔
542
      if (pRaw != NULL) {
101,444,702✔
543
        pRaw->status = pRow->status;
101,444,702✔
544

545
        if (taosWriteFile(pFile, pRaw, sizeof(SSdbRaw)) != sizeof(SSdbRaw)) {
101,444,702✔
546
          code = terrno;
×
547
          taosHashCancelIterate(hash, ppRow);
×
548
          sdbFreeRaw(pRaw);
×
549
          break;
×
550
        }
551

552
        int32_t newDataLen = pRaw->dataLen;
101,444,702✔
553
        char   *newData = pRaw->pData;
101,444,702✔
554

555
        if (taosWaitCfgKeyLoaded() != 0) {
101,444,702✔
556
          code = terrno;
×
557
          taosHashCancelIterate(hash, ppRow);
×
558
          sdbFreeRaw(pRaw);
×
559
          break;
×
560
        }
561

562
        if (tsMetaKey[0] != '\0') {
101,444,702✔
563
          newDataLen = ENCRYPTED_LEN(pRaw->dataLen);
×
564
          newData = taosMemoryMalloc(newDataLen);
×
565
          if (newData == NULL) {
×
566
            code = terrno;
×
567
            taosHashCancelIterate(hash, ppRow);
×
568
            sdbFreeRaw(pRaw);
×
569
            break;
×
570
          }
571

572
          SCryptOpts opts = {0};
×
573
          opts.len = newDataLen;
×
574
          opts.source = pRaw->pData;
×
575
          opts.result = newData;
×
576
          opts.unitLen = 16;
×
577
          opts.pOsslAlgrName = taosGetEncryptAlgoName(tsEncryptAlgorithmType);
×
578
          tstrncpy(opts.key, tsMetaKey, ENCRYPT_KEY_LEN + 1);
×
579

580
          int32_t count = CBC_Encrypt(&opts);
×
581
          if (count <= 0) {
×
582
            code = terrno;
×
583
            taosHashCancelIterate(hash, ppRow);
×
584
            sdbFreeRaw(pRaw);
×
585
            break;
×
586
          }
587

588
          // mDebug("write sdb, CBC Encrypt encryptedDataLen:%d, dataLen:%d, %s",
589
          //       newDataLen, pRaw->dataLen, __FUNCTION__);
590
        }
591

592
        if (taosWriteFile(pFile, newData, newDataLen) != newDataLen) {
101,444,702✔
593
          code = terrno;
×
594
          taosHashCancelIterate(hash, ppRow);
×
595
          sdbFreeRaw(pRaw);
×
596
          break;
×
597
        }
598

599
        if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
101,444,702✔
600
          taosMemoryFree(newData);
×
601
        }
602

603
        int32_t cksum = taosCalcChecksum(0, (const uint8_t *)pRaw, sizeof(SSdbRaw) + pRaw->dataLen);
101,444,702✔
604
        if (taosWriteFile(pFile, &cksum, sizeof(int32_t)) != sizeof(int32_t)) {
101,444,702✔
605
          code = terrno;
×
606
          taosHashCancelIterate(hash, ppRow);
×
607
          sdbFreeRaw(pRaw);
×
608
          break;
×
609
        }
610
      } else {
611
        code = TSDB_CODE_APP_ERROR;
×
612
        taosHashCancelIterate(hash, ppRow);
×
613
        break;
×
614
      }
615

616
      sdbFreeRaw(pRaw);
101,444,702✔
617
      ppRow = taosHashIterate(hash, ppRow);
101,444,702✔
618
    }
619
    sdbUnLock(pSdb, i);
30,392,439✔
620
  }
621

622
  if (code == 0) {
741,279✔
623
    code = taosFsyncFile(pFile);
741,279✔
624
    if (code != 0) {
741,279✔
625
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
626
      mError("failed to sync sdb file:%s since %s", tmpfile, tstrerror(code));
×
627
    }
628
  }
629

630
  if (taosCloseFile(&pFile) != 0) {
741,279✔
631
    code = taosRenameFile(tmpfile, curfile);
×
632
  }
633

634
  if (code == 0) {
741,279✔
635
    code = taosRenameFile(tmpfile, curfile);
741,279✔
636
    if (code != 0) {
741,279✔
637
      mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
×
638
    }
639
  }
640

641
  if (code != 0) {
741,279✔
642
    mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
×
643
  } else {
644
    pSdb->commitIndex = pSdb->applyIndex;
741,279✔
645
    pSdb->commitTerm = pSdb->applyTerm;
741,279✔
646
    pSdb->commitConfig = pSdb->applyConfig;
741,279✔
647
    mInfo("vgId:1, trans:0, write sdb file success, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64
741,279✔
648
          " file:%s",
649
          pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig, curfile);
650
  }
651

652
  terrno = code;
741,279✔
653
  return code;
741,279✔
654
}
655

656
int32_t sdbWriteFile(SSdb *pSdb, int32_t delta) {
36,858,437✔
657
  int32_t code = 0;
36,858,437✔
658
  if (pSdb->applyIndex == pSdb->commitIndex) {
36,858,437✔
659
    return 0;
727,189✔
660
  }
661

662
  if (pSdb->applyIndex - pSdb->commitIndex < delta) {
36,131,248✔
663
    return 0;
35,387,403✔
664
  }
665

666
  (void)taosThreadMutexLock(&pSdb->filelock);
743,845✔
667
  if (pSdb->pWal != NULL) {
743,845✔
668
    if (pSdb->sync > 0) {
743,845✔
669
      code = syncBeginSnapshot(pSdb->sync, pSdb->applyIndex);
743,845✔
670
    }
671
  }
672
  if (code == 0) {
743,845✔
673
    code = sdbWriteFileImp(pSdb, -1);
741,279✔
674
  }
675
  if (code == 0) {
743,845✔
676
    if (pSdb->pWal != NULL) {
741,279✔
677
      if (pSdb->sync > 0) {
741,279✔
678
        code = syncEndSnapshot(pSdb->sync, false);
741,279✔
679
      }
680
    }
681
  }
682
  if (code != 0) {
743,845✔
683
    mError("failed to write sdb file since %s", tstrerror(code));
2,566✔
684
  } else {
685
    mInfo("vgId:1, trans:0, write sdb file success, apply index:%" PRId64 ", term:%" PRId64 ", config:%" PRId64,
741,279✔
686
          pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig);
687
  }
688
  (void)taosThreadMutexUnlock(&pSdb->filelock);
743,845✔
689
  return code;
743,845✔
690
}
691

692
int32_t sdbWriteFileForDump(SSdb *pSdb, int32_t skip_type) {
×
693
  int32_t code = 0;
×
694

695
  code = sdbWriteFileImp(pSdb, skip_type);
×
696

697
  return code;
×
698
}
699

700
int32_t sdbDeploy(SSdb *pSdb) {
277,230✔
701
  int32_t code = 0;
277,230✔
702
  code = sdbDeployData(pSdb);
277,230✔
703
  if (code != 0) {
277,230✔
704
    TAOS_RETURN(code);
×
705
  }
706

707
  code = sdbWriteFile(pSdb, 0);
277,230✔
708
  if (code != 0) {
277,230✔
709
    TAOS_RETURN(code);
×
710
  }
711

712
  return 0;
277,230✔
713
}
714

715
int32_t sdbUpgrade(SSdb *pSdb, int32_t version) {
349,575✔
716
  int32_t code = 0;
349,575✔
717
  code = sdbUpgradeData(pSdb, version);
349,575✔
718
  if (code != 0) {
349,575✔
719
    TAOS_RETURN(code);
×
720
  }
721

722
  code = sdbWriteFile(pSdb, 0);
349,575✔
723
  if (code != 0) {
349,575✔
724
    TAOS_RETURN(code);
×
725
  }
726

727
  return 0;
349,575✔
728
}
729

730
int32_t sdbAfterRestored(SSdb *pSdb) {
182,994✔
731
  int32_t code = 0;
182,994✔
732
  code = sdbAfterRestoredData(pSdb);
182,994✔
733
  if (code != 0) {
182,994✔
UNCOV
734
    TAOS_RETURN(code);
×
735
  }
736
  return 0;
182,994✔
737
}
738

739
static SSdbIter *sdbCreateIter(SSdb *pSdb) {
×
740
  SSdbIter *pIter = taosMemoryCalloc(1, sizeof(SSdbIter));
×
741
  if (pIter == NULL) {
×
742
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
743
    return NULL;
×
744
  }
745

746
  char name[PATH_MAX + 100] = {0};
×
747
  snprintf(name, sizeof(name), "%s%ssdb.data.%" PRIu64, pSdb->tmpDir, TD_DIRSEP, (uint64_t)pIter);
×
748
  pIter->name = taosStrdup(name);
×
749
  if (pIter->name == NULL) {
×
750
    taosMemoryFree(pIter);
×
751
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
752
    return NULL;
×
753
  }
754

755
  return pIter;
×
756
}
757

758
static void sdbCloseIter(SSdbIter *pIter) {
×
759
  if (pIter == NULL) return;
×
760

761
  if (pIter->file != NULL) {
×
762
    int32_t ret = 0;
×
763
    if ((ret = taosCloseFile(&pIter->file)) != 0) {
×
764
      mError("failed to close sdb file since %s", tstrerror(ret));
×
765
    }
766
    pIter->file = NULL;
×
767
  }
768

769
  if (pIter->name != NULL) {
×
770
    int32_t ret = 0;
×
771
    if ((ret = taosRemoveFile(pIter->name)) != 0) {
×
772
      mError("failed to remove sdb file:%s since %s", pIter->name, tstrerror(ret));
×
773
    }
774
    taosMemoryFree(pIter->name);
×
775
    pIter->name = NULL;
×
776
  }
777

778
  mInfo("sdbiter:%p, is closed, total:%" PRId64, pIter, pIter->total);
×
779
  taosMemoryFree(pIter);
×
780
}
781

782
int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter, int64_t *index, int64_t *term, int64_t *config) {
×
783
  int32_t   code = 0;
×
784
  SSdbIter *pIter = sdbCreateIter(pSdb);
×
785
  if (pIter == NULL) return -1;
×
786

787
  char datafile[PATH_MAX] = {0};
×
788
  snprintf(datafile, sizeof(datafile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
×
789

790
  (void)taosThreadMutexLock(&pSdb->filelock);
×
791
  int64_t commitIndex = pSdb->commitIndex;
×
792
  int64_t commitTerm = pSdb->commitTerm;
×
793
  int64_t commitConfig = pSdb->commitConfig;
×
794
  if (taosCopyFile(datafile, pIter->name) < 0) {
×
795
    code = terrno;
×
796
    (void)taosThreadMutexUnlock(&pSdb->filelock);
×
797
    mError("failed to copy sdb file %s to %s since %s", datafile, pIter->name, tstrerror(code));
×
798
    sdbCloseIter(pIter);
×
799
    TAOS_RETURN(code);
×
800
  }
801
  (void)taosThreadMutexUnlock(&pSdb->filelock);
×
802

803
  pIter->file = taosOpenFile(pIter->name, TD_FILE_READ);
×
804
  if (pIter->file == NULL) {
×
805
    code = terrno;
×
806
    mError("failed to open sdb file:%s since %s", pIter->name, tstrerror(code));
×
807
    sdbCloseIter(pIter);
×
808
    TAOS_RETURN(code);
×
809
  }
810

811
  *ppIter = pIter;
×
812
  if (index != NULL) *index = commitIndex;
×
813
  if (term != NULL) *term = commitTerm;
×
814
  if (config != NULL) *config = commitConfig;
×
815

816
  mInfo("sdbiter:%p, is created to read snapshot, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64 " file:%s",
×
817
        pIter, commitIndex, commitTerm, commitConfig, pIter->name);
818
  return 0;
×
819
}
820

821
void sdbStopRead(SSdb *pSdb, SSdbIter *pIter) { sdbCloseIter(pIter); }
×
822

823
int32_t sdbDoRead(SSdb *pSdb, SSdbIter *pIter, void **ppBuf, int32_t *len) {
×
824
  int32_t code = 0;
×
825
  int32_t maxlen = 4096;
×
826
  void   *pBuf = taosMemoryCalloc(1, maxlen);
×
827
  if (pBuf == NULL) {
×
828
    code = terrno;
×
829
    TAOS_RETURN(code);
×
830
  }
831

832
  int32_t readlen = taosReadFile(pIter->file, pBuf, maxlen);
×
833
  if (readlen < 0 || readlen > maxlen) {
×
834
    code = terrno;
×
835
    mError("sdbiter:%p, failed to read snapshot since %s, total:%" PRId64, pIter, tstrerror(code), pIter->total);
×
836
    *ppBuf = NULL;
×
837
    *len = 0;
×
838
    taosMemoryFree(pBuf);
×
839
    TAOS_RETURN(code);
×
840
  } else if (readlen == 0) {
×
841
    mInfo("sdbiter:%p, read snapshot to the end, total:%" PRId64, pIter, pIter->total);
×
842
    *ppBuf = NULL;
×
843
    *len = 0;
×
844
    taosMemoryFree(pBuf);
×
845
    return 0;
×
846
  } else {  // (readlen <= maxlen)
847
    pIter->total += readlen;
×
848
    mInfo("sdbiter:%p, read:%d bytes from snapshot, total:%" PRId64, pIter, readlen, pIter->total);
×
849
    *ppBuf = pBuf;
×
850
    *len = readlen;
×
851
    return 0;
×
852
  }
853
}
854

855
int32_t sdbStartWrite(SSdb *pSdb, SSdbIter **ppIter) {
×
856
  int32_t   code = 0;
×
857
  SSdbIter *pIter = sdbCreateIter(pSdb);
×
858
  if (pIter == NULL) {
×
859
    code = terrno;
×
860
    TAOS_RETURN(code);
×
861
  }
862

863
  pIter->file = taosOpenFile(pIter->name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
×
864
  if (pIter->file == NULL) {
×
865
    code = terrno;
×
866
    mError("failed to open %s since %s", pIter->name, tstrerror(code));
×
867
    sdbCloseIter(pIter);
×
868
    TAOS_RETURN(code);
×
869
  }
870

871
  *ppIter = pIter;
×
872
  mInfo("sdbiter:%p, is created to write snapshot, file:%s", pIter, pIter->name);
×
873
  return 0;
×
874
}
875

876
int32_t sdbStopWrite(SSdb *pSdb, SSdbIter *pIter, bool isApply, int64_t index, int64_t term, int64_t config) {
×
877
  int32_t code = -1;
×
878

879
  if (!isApply) {
×
880
    mInfo("sdbiter:%p, not apply to sdb", pIter);
×
881
    code = 0;
×
882
    goto _OVER;
×
883
  }
884

885
  if (taosFsyncFile(pIter->file) != 0) {
×
886
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
887
    mError("sdbiter:%p, failed to fasync file %s since %s", pIter, pIter->name, tstrerror(code));
×
888
    goto _OVER;
×
889
  }
890

891
  if (taosCloseFile(&pIter->file) != 0) {
×
892
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
893
    goto _OVER;
×
894
  }
895
  pIter->file = NULL;
×
896

897
  char datafile[PATH_MAX] = {0};
×
898
  snprintf(datafile, sizeof(datafile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
×
899
  code = taosRenameFile(pIter->name, datafile);
×
900
  if (code != 0) {
×
901
    mError("sdbiter:%p, failed to rename file %s to %s since %s", pIter, pIter->name, datafile, tstrerror(code));
×
902
    goto _OVER;
×
903
  }
904

905
  code = sdbReadFile(pSdb);
×
906
  if (code != 0) {
×
907
    mError("sdbiter:%p, failed to read from %s since %s", pIter, datafile, tstrerror(code));
×
908
    goto _OVER;
×
909
  }
910

911
  if (config > 0) {
×
912
    pSdb->commitConfig = config;
×
913
  }
914
  if (term > 0) {
×
915
    pSdb->commitTerm = term;
×
916
  }
917
  if (index > 0) {
×
918
    pSdb->commitIndex = index;
×
919
  }
920

921
  mInfo("sdbiter:%p, success applyed to sdb", pIter);
×
922
  code = 0;
×
923

924
_OVER:
×
925
  sdbCloseIter(pIter);
×
926
  return code;
×
927
}
928

929
int32_t sdbDoWrite(SSdb *pSdb, SSdbIter *pIter, void *pBuf, int32_t len) {
×
930
  int32_t code = 0;
×
931
  int32_t writelen = taosWriteFile(pIter->file, pBuf, len);
×
932
  if (writelen != len) {
×
933
    code = terrno;
×
934
    mError("failed to write len:%d since %s, total:%" PRId64, len, tstrerror(code), pIter->total);
×
935
    TAOS_RETURN(code);
×
936
  }
937

938
  pIter->total += writelen;
×
939
  mInfo("sdbiter:%p, write:%d bytes to snapshot, total:%" PRId64, pIter, writelen, pIter->total);
×
940
  return 0;
×
941
}
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