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

taosdata / TDengine / #4829

30 Oct 2025 09:25AM UTC coverage: 49.734% (-11.3%) from 61.071%
#4829

push

travis-ci

web-flow
Merge pull request #33435 from taosdata/3.0

merge 3.0

123072 of 323930 branches covered (37.99%)

Branch coverage included in aggregate %.

7 of 25 new or added lines in 3 files covered. (28.0%)

35232 existing lines in 327 files now uncovered.

172062 of 269495 relevant lines covered (63.85%)

70709785.06 hits per line

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

38.6
/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 "tglobal.h"
22
#include "wal.h"
23

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

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

31
static int32_t sdbDeployData(SSdb *pSdb) {
79,202✔
32
  int32_t code = 0;
79,202✔
33
  mInfo("start to deploy sdb");
79,202!
34

35
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
3,088,878✔
36
    SdbDeployFp fp = pSdb->deployFps[i];
3,009,676✔
37
    if (fp == NULL) continue;
3,009,676✔
38

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

47
  mInfo("sdb deploy success");
79,202!
48
  return 0;
79,202✔
49
}
50

51
static int32_t sdbAfterRestoredData(SSdb *pSdb) {
67,368✔
52
  int32_t code = 0;
67,368✔
53
  mInfo("start to prepare sdb");
67,368!
54

55
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
2,627,352✔
56
    SdbAfterRestoredFp fp = pSdb->afterRestoredFps[i];
2,559,984✔
57
    if (fp == NULL) continue;
2,559,984✔
58

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

67
  mInfo("sdb prepare success");
67,368!
68
  return 0;
67,368✔
69
}
70

71
static void sdbResetData(SSdb *pSdb) {
43,061✔
72
  mInfo("start to reset sdb");
43,061!
73

74
  for (ESdbType i = 0; i < SDB_MAX; ++i) {
1,679,379✔
75
    SHashObj *hash = pSdb->hashObjs[i];
1,636,318✔
76
    if (hash == NULL) continue;
1,636,318✔
77

78
    sdbWriteLock(pSdb, i);
1,464,074✔
79

80
    SSdbRow **ppRow = taosHashIterate(hash, NULL);
1,464,074✔
81
    while (ppRow != NULL) {
1,464,074!
UNCOV
82
      SSdbRow *pRow = *ppRow;
×
UNCOV
83
      if (pRow == NULL) continue;
×
84

UNCOV
85
      sdbFreeRow(pSdb, pRow, true);
×
UNCOV
86
      ppRow = taosHashIterate(hash, ppRow);
×
87
    }
88

89
    taosHashClear(pSdb->hashObjs[i]);
1,464,074✔
90
    pSdb->tableVer[i] = 0;
1,464,074✔
91
    pSdb->maxId[i] = 0;
1,464,074✔
92

93
    sdbUnLock(pSdb, i);
1,464,074✔
94

95
    mInfo("sdb:%s is reset", sdbTableName(i));
1,464,074!
96
  }
97

98
  pSdb->applyIndex = -1;
43,061✔
99
  pSdb->applyTerm = -1;
43,061✔
100
  pSdb->applyConfig = -1;
43,061✔
101
  pSdb->commitIndex = -1;
43,061✔
102
  pSdb->commitTerm = -1;
43,061✔
103
  pSdb->commitConfig = -1;
43,061✔
104
  mInfo("sdb reset success");
43,061!
105
}
43,061✔
106

107
static int32_t sdbReadFileHead(SSdb *pSdb, TdFilePtr pFile) {
35,806✔
108
  int32_t code = 0;
35,806✔
109
  int64_t sver = 0;
35,806✔
110
  int32_t ret = taosReadFile(pFile, &sver, sizeof(int64_t));
35,806✔
111
  if (ret < 0) {
35,806!
112
    return terrno;
×
113
  }
114
  if (ret != sizeof(int64_t)) {
35,806!
115
    code = TSDB_CODE_FILE_CORRUPTED;
×
116
    TAOS_RETURN(code);
×
117
  }
118
  if (sver != SDB_FILE_VER) {
35,806!
119
    code = TSDB_CODE_FILE_CORRUPTED;
×
120
    TAOS_RETURN(code);
×
121
  }
122

123
  ret = taosReadFile(pFile, &pSdb->applyIndex, sizeof(int64_t));
35,806✔
124
  if (ret < 0) {
35,806!
125
    return terrno;
×
126
  }
127
  if (ret != sizeof(int64_t)) {
35,806!
128
    code = TSDB_CODE_FILE_CORRUPTED;
×
129
    TAOS_RETURN(code);
×
130
  }
131

132
  ret = taosReadFile(pFile, &pSdb->applyTerm, sizeof(int64_t));
35,806✔
133
  if (ret < 0) {
35,806!
134
    return terrno;
×
135
  }
136
  if (ret != sizeof(int64_t)) {
35,806!
137
    code = TSDB_CODE_FILE_CORRUPTED;
×
138
    TAOS_RETURN(code);
×
139
  }
140

141
  ret = taosReadFile(pFile, &pSdb->applyConfig, sizeof(int64_t));
35,806✔
142
  if (ret < 0) {
35,806!
143
    return terrno;
×
144
  }
145
  if (ret != sizeof(int64_t)) {
35,806!
146
    code = TSDB_CODE_FILE_CORRUPTED;
×
147
    TAOS_RETURN(code);
×
148
  }
149

150
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
895,150✔
151
    int64_t maxId = 0;
859,344✔
152
    ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
859,344✔
153
    if (ret < 0) {
859,344!
154
      return terrno;
×
155
    }
156
    if (ret != sizeof(int64_t)) {
859,344!
157
      code = TSDB_CODE_FILE_CORRUPTED;
×
158
      TAOS_RETURN(code);
×
159
    }
160
    if (i < SDB_MAX) {
859,344!
161
      pSdb->maxId[i] = maxId;
859,344✔
162
    }
163
  }
164

165
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
895,150✔
166
    int64_t ver = 0;
859,344✔
167
    ret = taosReadFile(pFile, &ver, sizeof(int64_t));
859,344✔
168
    if (ret < 0) {
859,344!
169
      return terrno;
×
170
    }
171
    if (ret != sizeof(int64_t)) {
859,344!
172
      code = TSDB_CODE_FILE_CORRUPTED;
×
173
      TAOS_RETURN(code);
×
174
    }
175
    if (i < SDB_MAX) {
859,344!
176
      pSdb->tableVer[i] = ver;
859,344✔
177
    }
178
  }
179

180
  // for sdb compatibility
181
  for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
537,090✔
182
    int64_t maxId = 0;
501,284✔
183
    ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
501,284✔
184
    if (ret < 0) {
501,284!
185
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
186
      TAOS_RETURN(code);
×
187
    }
188
    if (ret != sizeof(int64_t)) {
501,284!
189
      code = TSDB_CODE_FILE_CORRUPTED;
×
190
      TAOS_RETURN(code);
×
191
    }
192
    if (i < SDB_MAX) {
501,284!
193
      pSdb->maxId[i] = maxId;
501,284✔
194
    }
195

196
    int64_t ver = 0;
501,284✔
197
    ret = taosReadFile(pFile, &ver, sizeof(int64_t));
501,284✔
198
    if (ret < 0) {
501,284!
199
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
200
      TAOS_RETURN(code);
×
201
    }
202
    if (ret != sizeof(int64_t)) {
501,284!
203
      code = TSDB_CODE_FILE_CORRUPTED;
×
204
      TAOS_RETURN(code);
×
205
    }
206
    if (i < SDB_MAX) {
501,284!
207
      pSdb->tableVer[i] = ver;
501,284✔
208
    }
209
  }
210

211
  char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
35,806✔
212
  ret = taosReadFile(pFile, reserve, sizeof(reserve));
35,806✔
213
  if (ret < 0) {
35,806!
214
    return terrno;
×
215
  }
216
  if (ret != sizeof(reserve)) {
35,806!
217
    code = TSDB_CODE_FILE_CORRUPTED;
×
218
    TAOS_RETURN(code);
×
219
  }
220

221
  return 0;
35,806✔
222
}
223

224
static int32_t sdbWriteFileHead(SSdb *pSdb, TdFilePtr pFile) {
211,426✔
225
  int64_t sver = SDB_FILE_VER;
211,426✔
226
  if (taosWriteFile(pFile, &sver, sizeof(int64_t)) != sizeof(int64_t)) {
211,426!
227
    return terrno;
×
228
  }
229

230
  mInfo("vgId:1, write sdb file with sdb applyIndex:%" PRId64 " term:%" PRId64 " config:%" PRId64, pSdb->applyIndex,
211,426!
231
        pSdb->applyTerm, pSdb->applyConfig);
232
  if (taosWriteFile(pFile, &pSdb->applyIndex, sizeof(int64_t)) != sizeof(int64_t)) {
211,426!
233
    return terrno;
×
234
  }
235

236
  if (taosWriteFile(pFile, &pSdb->applyTerm, sizeof(int64_t)) != sizeof(int64_t)) {
211,426!
237
    return terrno;
×
238
  }
239

240
  if (taosWriteFile(pFile, &pSdb->applyConfig, sizeof(int64_t)) != sizeof(int64_t)) {
211,426!
241
    return terrno;
×
242
  }
243

244
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
5,285,650✔
245
    int64_t maxId = 0;
5,074,224✔
246
    if (i < SDB_MAX) {
5,074,224!
247
      maxId = pSdb->maxId[i];
5,074,224✔
248
    }
249
    if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
5,074,224!
250
      return terrno;
×
251
    }
252
  }
253

254
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
5,285,650✔
255
    int64_t ver = 0;
5,074,224✔
256
    if (i < SDB_MAX) {
5,074,224!
257
      ver = pSdb->tableVer[i];
5,074,224✔
258
    }
259
    if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
5,074,224!
260
      return terrno;
×
261
    }
262
  }
263

264
  // for sdb compatibility
265
  for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
3,171,390✔
266
    int64_t maxId = 0;
2,959,964✔
267
    if (i < SDB_MAX) {
2,959,964!
268
      maxId = pSdb->maxId[i];
2,959,964✔
269
    }
270
    if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
2,959,964!
271
      return terrno;
×
272
    }
273

274
    int64_t ver = 0;
2,959,964✔
275
    if (i < SDB_MAX) {
2,959,964!
276
      ver = pSdb->tableVer[i];
2,959,964✔
277
    }
278
    if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
2,959,964!
279
      return terrno;
×
280
    }
281
  }
282

283
  char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
211,426✔
284
  if (taosWriteFile(pFile, reserve, sizeof(reserve)) != sizeof(reserve)) {
211,426!
285
    return terrno;
×
286
  }
287

288
  return 0;
211,426✔
289
}
290

291
static int32_t sdbReadFileImp(SSdb *pSdb) {
43,061✔
292
  int64_t offset = 0;
43,061✔
293
  int32_t code = 0;
43,061✔
294
  int32_t readLen = 0;
43,061✔
295
  int64_t ret = 0;
43,061✔
296
  char    file[PATH_MAX] = {0};
43,061✔
297
  int32_t bufLen = TSDB_MAX_MSG_SIZE;
43,061✔
298

299
  snprintf(file, sizeof(file), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
43,061✔
300
  mInfo("start to read sdb file:%s", file);
43,061!
301

302
  SSdbRaw *pRaw = taosMemoryMalloc(bufLen + 100);
43,061!
303
  if (pRaw == NULL) {
43,061!
304
    code = terrno;
×
305
    mError("failed read sdb file since %s", tstrerror(code));
×
306
    TAOS_RETURN(code);
×
307
  }
308

309
  TdFilePtr pFile = taosOpenFile(file, TD_FILE_READ);
43,061✔
310
  if (pFile == NULL) {
43,061✔
311
    taosMemoryFree(pRaw);
7,255!
312
    code = terrno;
7,255✔
313
    mInfo("read sdb file:%s finished since %s", file, tstrerror(code));
7,255!
314
    return 0;
7,255✔
315
  }
316

317
  code = sdbReadFileHead(pSdb, pFile);
35,806✔
318
  if (code != 0) {
35,806!
319
    mError("failed to read sdb file:%s head since %s", file, tstrerror(code));
×
320
    taosMemoryFree(pRaw);
×
321
    int32_t ret = 0;
×
322
    if ((ret = taosCloseFile(&pFile)) != 0) {
×
323
      mError("failed to close sdb file:%s since %s", file, tstrerror(ret));
×
324
    }
325
    return code;
×
326
  }
327

328
  int64_t tableVer[SDB_MAX] = {0};
35,806✔
329
  memcpy(tableVer, pSdb->tableVer, sizeof(tableVer));
35,806!
330

331
  while (1) {
4,751,555✔
332
    readLen = sizeof(SSdbRaw);
4,787,361✔
333
    ret = taosReadFile(pFile, pRaw, readLen);
4,787,361✔
334
    if (ret == 0) break;
4,787,361✔
335

336
    if (ret < 0) {
4,751,555!
337
      code = terrno;
×
338
      mError("failed to read sdb file:%s since %s", file, tstrerror(code));
×
339
      goto _OVER;
×
340
    }
341

342
    if (ret != readLen) {
4,751,555!
343
      code = TSDB_CODE_FILE_CORRUPTED;
×
344
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " != readLen:%d", file, tstrerror(code), ret, readLen);
×
345
      goto _OVER;
×
346
    }
347

348
    readLen = pRaw->dataLen + sizeof(int32_t);
4,751,555✔
349
    if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
4,751,555!
350
      readLen = ENCRYPTED_LEN(pRaw->dataLen) + sizeof(int32_t);
×
351
    }
352
    if (readLen >= bufLen) {
4,751,555!
353
      bufLen = pRaw->dataLen * 2;
×
354
      SSdbRaw *pNewRaw = taosMemoryMalloc(bufLen + 100);
×
355
      if (pNewRaw == NULL) {
×
356
        code = terrno;
×
357
        mError("failed read sdb file since malloc new sdbRaw size:%d failed", bufLen);
×
358
        goto _OVER;
×
359
      }
360
      mInfo("malloc new sdb raw size:%d, type:%d", bufLen, pRaw->type);
×
361
      memcpy(pNewRaw, pRaw, sizeof(SSdbRaw));
×
362
      sdbFreeRaw(pRaw);
×
363
      pRaw = pNewRaw;
×
364
    }
365

366
    ret = taosReadFile(pFile, pRaw->pData, readLen);
4,751,555✔
367
    if (ret < 0) {
4,751,555!
368
      code = terrno;
×
369
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " readLen:%d", file, tstrerror(code), ret, readLen);
×
370
      goto _OVER;
×
371
    }
372

373
    if (ret != readLen) {
4,751,555!
374
      code = TSDB_CODE_FILE_CORRUPTED;
×
375
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " != readLen:%d", file, tstrerror(code), ret, readLen);
×
376
      goto _OVER;
×
377
    }
378

379
    if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
4,751,555!
380
      int32_t count = 0;
×
381

382
      char *plantContent = taosMemoryMalloc(ENCRYPTED_LEN(pRaw->dataLen));
×
383
      if (plantContent == NULL) {
×
384
        code = terrno;
×
385
        goto _OVER;
×
386
      }
387

388
      SCryptOpts opts;
×
389
      opts.len = ENCRYPTED_LEN(pRaw->dataLen);
×
390
      opts.source = pRaw->pData;
×
391
      opts.result = plantContent;
×
392
      opts.unitLen = 16;
×
393
      tstrncpy(opts.key, tsEncryptKey, ENCRYPT_KEY_LEN + 1);
×
394

395
      count = CBC_Decrypt(&opts);
×
396

397
      // mDebug("read sdb, CBC_Decrypt dataLen:%d, descrypted len:%d, %s", pRaw->dataLen, count, __FUNCTION__);
398

399
      memcpy(pRaw->pData, plantContent, pRaw->dataLen);
×
400
      taosMemoryFree(plantContent);
×
401
      memcpy(pRaw->pData + pRaw->dataLen, &pRaw->pData[ENCRYPTED_LEN(pRaw->dataLen)], sizeof(int32_t));
×
402
    }
403

404
    int32_t totalLen = sizeof(SSdbRaw) + pRaw->dataLen + sizeof(int32_t);
4,751,555✔
405
    if ((!taosCheckChecksumWhole((const uint8_t *)pRaw, totalLen)) != 0) {
9,503,110!
406
      code = TSDB_CODE_CHECKSUM_ERROR;
×
407
      mError("failed to read sdb file:%s since %s, readLen:%d", file, tstrerror(code), readLen);
×
408
      goto _OVER;
×
409
    }
410

411
    if (pRaw->type >= SDB_MAX) {
4,751,555!
412
      mInfo("skip sdb raw type:%d since it is not supported", pRaw->type);
×
413
      continue;
×
414
    }
415

416
    code = sdbWriteWithoutFree(pSdb, pRaw);
4,751,555✔
417
    if (code != 0) {
4,751,555!
418
      mError("failed to exec sdbWrite while read sdb file:%s since %s", file, terrstr());
×
419
      goto _OVER;
×
420
    }
421
  }
422

423
  code = 0;
35,806✔
424
  pSdb->commitIndex = pSdb->applyIndex;
35,806✔
425
  pSdb->commitTerm = pSdb->applyTerm;
35,806✔
426
  pSdb->commitConfig = pSdb->applyConfig;
35,806✔
427
  memcpy(pSdb->tableVer, tableVer, sizeof(tableVer));
35,806!
428
  mInfo("vgId:1, trans:0, read sdb file:%s success, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64, file,
35,806!
429
        pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig);
430

431
_OVER:
35,670✔
432
  if ((ret = taosCloseFile(&pFile)) != 0) {
35,806!
433
    mError("failed to close sdb file:%s since %s", file, tstrerror(ret));
×
434
  }
435
  sdbFreeRaw(pRaw);
35,806✔
436

437
  TAOS_RETURN(code);
35,806✔
438
}
439

440
int32_t sdbReadFile(SSdb *pSdb) {
43,061✔
441
  (void)taosThreadMutexLock(&pSdb->filelock);
43,061✔
442

443
  sdbResetData(pSdb);
43,061✔
444
  int32_t code = sdbReadFileImp(pSdb);
43,061✔
445
  if (code != 0) {
43,061!
446
    mError("failed to read sdb file since %s", tstrerror(code));
×
447
    sdbResetData(pSdb);
×
448
  }
449

450
  (void)taosThreadMutexUnlock(&pSdb->filelock);
43,061✔
451
  return code;
43,061✔
452
}
453

454
static int32_t sdbWriteFileImp(SSdb *pSdb, int32_t skip_type) {
211,426✔
455
  int32_t code = 0;
211,426✔
456

457
  char tmpfile[PATH_MAX] = {0};
211,426✔
458
  snprintf(tmpfile, sizeof(tmpfile), "%s%ssdb.data", pSdb->tmpDir, TD_DIRSEP);
211,426✔
459
  char curfile[PATH_MAX] = {0};
211,426✔
460
  snprintf(curfile, sizeof(curfile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
211,426✔
461

462
  mInfo("start to write sdb file, apply index:%" PRId64 " term:%" PRId64 " config:%" PRId64 ", commit index:%" PRId64
211,426!
463
        " term:%" PRId64 " config:%" PRId64 ", file:%s",
464
        pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig, pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig,
465
        curfile);
466

467
  TdFilePtr pFile = taosOpenFile(tmpfile, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
211,426✔
468
  if (pFile == NULL) {
211,426!
469
    code = terrno;
×
470
    mError("failed to open sdb file:%s for write since %s", tmpfile, tstrerror(code));
×
471
    TAOS_RETURN(code);
×
472
  }
473

474
  code = sdbWriteFileHead(pSdb, pFile);
211,426✔
475
  if (code != 0) {
211,426!
476
    mError("failed to write sdb file:%s head since %s", tmpfile, tstrerror(code));
×
477
    int32_t ret = 0;
×
478
    if ((ret = taosCloseFile(&pFile)) != 0) {
×
479
      mError("failed to close sdb file:%s since %s", tmpfile, tstrerror(ret));
×
480
    }
481
    return code;
×
482
  }
483

484
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
8,245,614✔
485
    if (i == skip_type) continue;
8,034,188!
486
    SdbEncodeFp encodeFp = pSdb->encodeFps[i];
8,034,188✔
487
    if (encodeFp == NULL) continue;
8,034,188✔
488

489
    mInfo("write %s to sdb file, total %d rows", sdbTableName(i), sdbGetSize(pSdb, i));
7,188,484!
490

491
    SHashObj *hash = pSdb->hashObjs[i];
7,188,484✔
492
    sdbWriteLock(pSdb, i);
7,188,484✔
493

494
    SSdbRow **ppRow = taosHashIterate(hash, NULL);
7,188,484✔
495
    while (ppRow != NULL) {
32,562,227✔
496
      SSdbRow *pRow = *ppRow;
25,373,743✔
497
      if (pRow == NULL) {
25,373,743!
498
        ppRow = taosHashIterate(hash, ppRow);
×
499
        continue;
×
500
      }
501

502
      if (pRow->status != SDB_STATUS_READY && pRow->status != SDB_STATUS_DROPPING) {
25,373,743!
503
        sdbPrintOper(pSdb, pRow, "not-write");
16,777✔
504
        ppRow = taosHashIterate(hash, ppRow);
16,777✔
505
        continue;
16,777✔
506
      }
507

508
      sdbPrintOper(pSdb, pRow, "write");
25,356,966✔
509

510
      SSdbRaw *pRaw = (*encodeFp)(pRow->pObj);
25,356,966✔
511
      if (pRaw != NULL) {
25,356,966!
512
        pRaw->status = pRow->status;
25,356,966✔
513

514
        if (taosWriteFile(pFile, pRaw, sizeof(SSdbRaw)) != sizeof(SSdbRaw)) {
25,356,966!
515
          code = terrno;
×
516
          taosHashCancelIterate(hash, ppRow);
×
517
          sdbFreeRaw(pRaw);
×
518
          break;
×
519
        }
520

521
        int32_t newDataLen = pRaw->dataLen;
25,356,966✔
522
        char   *newData = pRaw->pData;
25,356,966✔
523
        if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
25,356,966!
524
          newDataLen = ENCRYPTED_LEN(pRaw->dataLen);
×
525
          newData = taosMemoryMalloc(newDataLen);
×
526
          if (newData == NULL) {
×
527
            code = terrno;
×
528
            taosHashCancelIterate(hash, ppRow);
×
529
            sdbFreeRaw(pRaw);
×
530
            break;
×
531
          }
532

533
          SCryptOpts opts;
×
534
          opts.len = newDataLen;
×
535
          opts.source = pRaw->pData;
×
536
          opts.result = newData;
×
537
          opts.unitLen = 16;
×
538
          tstrncpy(opts.key, tsEncryptKey, ENCRYPT_KEY_LEN + 1);
×
539

540
          int32_t count = CBC_Encrypt(&opts);
×
541

542
          // mDebug("write sdb, CBC_Encrypt encryptedDataLen:%d, dataLen:%d, %s",
543
          //       newDataLen, pRaw->dataLen, __FUNCTION__);
544
        }
545

546
        if (taosWriteFile(pFile, newData, newDataLen) != newDataLen) {
25,356,966!
547
          code = terrno;
×
548
          taosHashCancelIterate(hash, ppRow);
×
549
          sdbFreeRaw(pRaw);
×
550
          break;
×
551
        }
552

553
        if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
25,356,966!
554
          taosMemoryFree(newData);
×
555
        }
556

557
        int32_t cksum = taosCalcChecksum(0, (const uint8_t *)pRaw, sizeof(SSdbRaw) + pRaw->dataLen);
25,356,966✔
558
        if (taosWriteFile(pFile, &cksum, sizeof(int32_t)) != sizeof(int32_t)) {
25,356,966!
559
          code = terrno;
×
560
          taosHashCancelIterate(hash, ppRow);
×
561
          sdbFreeRaw(pRaw);
×
562
          break;
×
563
        }
564
      } else {
565
        code = TSDB_CODE_APP_ERROR;
×
566
        taosHashCancelIterate(hash, ppRow);
×
567
        break;
×
568
      }
569

570
      sdbFreeRaw(pRaw);
25,356,966✔
571
      ppRow = taosHashIterate(hash, ppRow);
25,356,966✔
572
    }
573
    sdbUnLock(pSdb, i);
7,188,484✔
574
  }
575

576
  if (code == 0) {
211,426!
577
    code = taosFsyncFile(pFile);
211,426✔
578
    if (code != 0) {
211,426!
579
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
580
      mError("failed to sync sdb file:%s since %s", tmpfile, tstrerror(code));
×
581
    }
582
  }
583

584
  if (taosCloseFile(&pFile) != 0) {
211,426!
585
    code = taosRenameFile(tmpfile, curfile);
×
586
  }
587

588
  if (code == 0) {
211,426!
589
    code = taosRenameFile(tmpfile, curfile);
211,426✔
590
    if (code != 0) {
211,426!
591
      mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
×
592
    }
593
  }
594

595
  if (code != 0) {
211,426!
596
    mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
×
597
  } else {
598
    pSdb->commitIndex = pSdb->applyIndex;
211,426✔
599
    pSdb->commitTerm = pSdb->applyTerm;
211,426✔
600
    pSdb->commitConfig = pSdb->applyConfig;
211,426✔
601
    mInfo("vgId:1, trans:0, write sdb file success, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64
211,426!
602
          " file:%s",
603
          pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig, curfile);
604
  }
605

606
  terrno = code;
211,426✔
607
  return code;
211,426✔
608
}
609

610
int32_t sdbWriteFile(SSdb *pSdb, int32_t delta) {
7,153,707✔
611
  int32_t code = 0;
7,153,707✔
612
  if (pSdb->applyIndex == pSdb->commitIndex) {
7,153,707✔
613
    return 0;
124,127✔
614
  }
615

616
  if (pSdb->applyIndex - pSdb->commitIndex < delta) {
7,029,580✔
617
    return 0;
6,817,319✔
618
  }
619

620
  (void)taosThreadMutexLock(&pSdb->filelock);
212,261✔
621
  if (pSdb->pWal != NULL) {
212,261!
622
    if (pSdb->sync > 0) {
212,261!
623
      code = syncBeginSnapshot(pSdb->sync, pSdb->applyIndex);
212,261✔
624
    }
625
  }
626
  if (code == 0) {
212,261✔
627
    code = sdbWriteFileImp(pSdb, -1);
211,426✔
628
  }
629
  if (code == 0) {
212,261✔
630
    if (pSdb->pWal != NULL) {
211,426!
631
      if (pSdb->sync > 0) {
211,426!
632
        code = syncEndSnapshot(pSdb->sync);
211,426✔
633
      }
634
    }
635
  }
636
  if (code != 0) {
212,261✔
637
    mError("failed to write sdb file since %s", tstrerror(code));
835!
638
  } else {
639
    mInfo("vgId:1, trans:0, write sdb file success, apply index:%" PRId64 ", term:%" PRId64 ", config:%" PRId64,
211,426!
640
          pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig);
641
  }
642
  (void)taosThreadMutexUnlock(&pSdb->filelock);
212,261✔
643
  return code;
212,261✔
644
}
645

646
int32_t sdbWriteFileForDump(SSdb *pSdb) {
×
647
  int32_t code = 0;
×
648

649
  code = sdbWriteFileImp(pSdb, 0);
×
650

651
  return code;
×
652
}
653

654
int32_t sdbDeploy(SSdb *pSdb) {
79,202✔
655
  int32_t code = 0;
79,202✔
656
  code = sdbDeployData(pSdb);
79,202✔
657
  if (code != 0) {
79,202!
658
    TAOS_RETURN(code);
×
659
  }
660

661
  code = sdbWriteFile(pSdb, 0);
79,202✔
662
  if (code != 0) {
79,202!
663
    TAOS_RETURN(code);
×
664
  }
665

666
  return 0;
79,202✔
667
}
668

669
int32_t sdbAfterRestored(SSdb *pSdb) {
67,368✔
670
  int32_t code = 0;
67,368✔
671
  code = sdbAfterRestoredData(pSdb);
67,368✔
672
  if (code != 0) {
67,368!
673
    TAOS_RETURN(code);
×
674
  }
675
  return 0;
67,368✔
676
}
677

UNCOV
678
static SSdbIter *sdbCreateIter(SSdb *pSdb) {
×
UNCOV
679
  SSdbIter *pIter = taosMemoryCalloc(1, sizeof(SSdbIter));
×
UNCOV
680
  if (pIter == NULL) {
×
681
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
682
    return NULL;
×
683
  }
684

UNCOV
685
  char name[PATH_MAX + 100] = {0};
×
UNCOV
686
  snprintf(name, sizeof(name), "%s%ssdb.data.%" PRIu64, pSdb->tmpDir, TD_DIRSEP, (uint64_t)pIter);
×
UNCOV
687
  pIter->name = taosStrdup(name);
×
UNCOV
688
  if (pIter->name == NULL) {
×
689
    taosMemoryFree(pIter);
×
690
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
691
    return NULL;
×
692
  }
693

UNCOV
694
  return pIter;
×
695
}
696

UNCOV
697
static void sdbCloseIter(SSdbIter *pIter) {
×
UNCOV
698
  if (pIter == NULL) return;
×
699

UNCOV
700
  if (pIter->file != NULL) {
×
UNCOV
701
    int32_t ret = 0;
×
UNCOV
702
    if ((ret = taosCloseFile(&pIter->file)) != 0) {
×
703
      mError("failed to close sdb file since %s", tstrerror(ret));
×
704
    }
UNCOV
705
    pIter->file = NULL;
×
706
  }
707

UNCOV
708
  if (pIter->name != NULL) {
×
UNCOV
709
    int32_t ret = 0;
×
UNCOV
710
    if ((ret = taosRemoveFile(pIter->name)) != 0) {
×
UNCOV
711
      mError("failed to remove sdb file:%s since %s", pIter->name, tstrerror(ret));
×
712
    }
UNCOV
713
    taosMemoryFree(pIter->name);
×
UNCOV
714
    pIter->name = NULL;
×
715
  }
716

UNCOV
717
  mInfo("sdbiter:%p, is closed, total:%" PRId64, pIter, pIter->total);
×
UNCOV
718
  taosMemoryFree(pIter);
×
719
}
720

UNCOV
721
int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter, int64_t *index, int64_t *term, int64_t *config) {
×
UNCOV
722
  int32_t   code = 0;
×
UNCOV
723
  SSdbIter *pIter = sdbCreateIter(pSdb);
×
UNCOV
724
  if (pIter == NULL) return -1;
×
725

UNCOV
726
  char datafile[PATH_MAX] = {0};
×
UNCOV
727
  snprintf(datafile, sizeof(datafile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
×
728

UNCOV
729
  (void)taosThreadMutexLock(&pSdb->filelock);
×
UNCOV
730
  int64_t commitIndex = pSdb->commitIndex;
×
UNCOV
731
  int64_t commitTerm = pSdb->commitTerm;
×
UNCOV
732
  int64_t commitConfig = pSdb->commitConfig;
×
UNCOV
733
  if (taosCopyFile(datafile, pIter->name) < 0) {
×
734
    code = terrno;
×
735
    (void)taosThreadMutexUnlock(&pSdb->filelock);
×
736
    mError("failed to copy sdb file %s to %s since %s", datafile, pIter->name, tstrerror(code));
×
737
    sdbCloseIter(pIter);
×
738
    TAOS_RETURN(code);
×
739
  }
UNCOV
740
  (void)taosThreadMutexUnlock(&pSdb->filelock);
×
741

UNCOV
742
  pIter->file = taosOpenFile(pIter->name, TD_FILE_READ);
×
UNCOV
743
  if (pIter->file == NULL) {
×
744
    code = terrno;
×
745
    mError("failed to open sdb file:%s since %s", pIter->name, tstrerror(code));
×
746
    sdbCloseIter(pIter);
×
747
    TAOS_RETURN(code);
×
748
  }
749

UNCOV
750
  *ppIter = pIter;
×
UNCOV
751
  if (index != NULL) *index = commitIndex;
×
UNCOV
752
  if (term != NULL) *term = commitTerm;
×
UNCOV
753
  if (config != NULL) *config = commitConfig;
×
754

UNCOV
755
  mInfo("sdbiter:%p, is created to read snapshot, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64 " file:%s",
×
756
        pIter, commitIndex, commitTerm, commitConfig, pIter->name);
UNCOV
757
  return 0;
×
758
}
759

UNCOV
760
void sdbStopRead(SSdb *pSdb, SSdbIter *pIter) { sdbCloseIter(pIter); }
×
761

UNCOV
762
int32_t sdbDoRead(SSdb *pSdb, SSdbIter *pIter, void **ppBuf, int32_t *len) {
×
UNCOV
763
  int32_t code = 0;
×
UNCOV
764
  int32_t maxlen = 4096;
×
UNCOV
765
  void   *pBuf = taosMemoryCalloc(1, maxlen);
×
UNCOV
766
  if (pBuf == NULL) {
×
767
    code = terrno;
×
768
    TAOS_RETURN(code);
×
769
  }
770

UNCOV
771
  int32_t readlen = taosReadFile(pIter->file, pBuf, maxlen);
×
UNCOV
772
  if (readlen < 0 || readlen > maxlen) {
×
773
    code = terrno;
×
774
    mError("sdbiter:%p, failed to read snapshot since %s, total:%" PRId64, pIter, tstrerror(code), pIter->total);
×
775
    *ppBuf = NULL;
×
776
    *len = 0;
×
777
    taosMemoryFree(pBuf);
×
778
    TAOS_RETURN(code);
×
UNCOV
779
  } else if (readlen == 0) {
×
UNCOV
780
    mInfo("sdbiter:%p, read snapshot to the end, total:%" PRId64, pIter, pIter->total);
×
UNCOV
781
    *ppBuf = NULL;
×
UNCOV
782
    *len = 0;
×
UNCOV
783
    taosMemoryFree(pBuf);
×
UNCOV
784
    return 0;
×
785
  } else {  // (readlen <= maxlen)
UNCOV
786
    pIter->total += readlen;
×
UNCOV
787
    mInfo("sdbiter:%p, read:%d bytes from snapshot, total:%" PRId64, pIter, readlen, pIter->total);
×
UNCOV
788
    *ppBuf = pBuf;
×
UNCOV
789
    *len = readlen;
×
UNCOV
790
    return 0;
×
791
  }
792
}
793

UNCOV
794
int32_t sdbStartWrite(SSdb *pSdb, SSdbIter **ppIter) {
×
UNCOV
795
  int32_t   code = 0;
×
UNCOV
796
  SSdbIter *pIter = sdbCreateIter(pSdb);
×
UNCOV
797
  if (pIter == NULL) {
×
798
    code = terrno;
×
799
    TAOS_RETURN(code);
×
800
  }
801

UNCOV
802
  pIter->file = taosOpenFile(pIter->name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
×
UNCOV
803
  if (pIter->file == NULL) {
×
804
    code = terrno;
×
805
    mError("failed to open %s since %s", pIter->name, tstrerror(code));
×
806
    sdbCloseIter(pIter);
×
807
    TAOS_RETURN(code);
×
808
  }
809

UNCOV
810
  *ppIter = pIter;
×
UNCOV
811
  mInfo("sdbiter:%p, is created to write snapshot, file:%s", pIter, pIter->name);
×
UNCOV
812
  return 0;
×
813
}
814

UNCOV
815
int32_t sdbStopWrite(SSdb *pSdb, SSdbIter *pIter, bool isApply, int64_t index, int64_t term, int64_t config) {
×
UNCOV
816
  int32_t code = -1;
×
817

UNCOV
818
  if (!isApply) {
×
819
    mInfo("sdbiter:%p, not apply to sdb", pIter);
×
820
    code = 0;
×
821
    goto _OVER;
×
822
  }
823

UNCOV
824
  if (taosFsyncFile(pIter->file) != 0) {
×
825
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
826
    mError("sdbiter:%p, failed to fasync file %s since %s", pIter, pIter->name, tstrerror(code));
×
827
    goto _OVER;
×
828
  }
829

UNCOV
830
  if (taosCloseFile(&pIter->file) != 0) {
×
831
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
832
    goto _OVER;
×
833
  }
UNCOV
834
  pIter->file = NULL;
×
835

UNCOV
836
  char datafile[PATH_MAX] = {0};
×
UNCOV
837
  snprintf(datafile, sizeof(datafile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
×
UNCOV
838
  code = taosRenameFile(pIter->name, datafile);
×
UNCOV
839
  if (code != 0) {
×
840
    mError("sdbiter:%p, failed to rename file %s to %s since %s", pIter, pIter->name, datafile, tstrerror(code));
×
841
    goto _OVER;
×
842
  }
843

UNCOV
844
  code = sdbReadFile(pSdb);
×
UNCOV
845
  if (code != 0) {
×
846
    mError("sdbiter:%p, failed to read from %s since %s", pIter, datafile, tstrerror(code));
×
847
    goto _OVER;
×
848
  }
849

UNCOV
850
  if (config > 0) {
×
851
    pSdb->commitConfig = config;
×
852
  }
UNCOV
853
  if (term > 0) {
×
854
    pSdb->commitTerm = term;
×
855
  }
UNCOV
856
  if (index > 0) {
×
857
    pSdb->commitIndex = index;
×
858
  }
859

UNCOV
860
  mInfo("sdbiter:%p, success applyed to sdb", pIter);
×
UNCOV
861
  code = 0;
×
862

UNCOV
863
_OVER:
×
UNCOV
864
  sdbCloseIter(pIter);
×
UNCOV
865
  return code;
×
866
}
867

UNCOV
868
int32_t sdbDoWrite(SSdb *pSdb, SSdbIter *pIter, void *pBuf, int32_t len) {
×
UNCOV
869
  int32_t code = 0;
×
UNCOV
870
  int32_t writelen = taosWriteFile(pIter->file, pBuf, len);
×
UNCOV
871
  if (writelen != len) {
×
872
    code = terrno;
×
873
    mError("failed to write len:%d since %s, total:%" PRId64, len, tstrerror(code), pIter->total);
×
874
    TAOS_RETURN(code);
×
875
  }
876

UNCOV
877
  pIter->total += writelen;
×
UNCOV
878
  mInfo("sdbiter:%p, write:%d bytes to snapshot, total:%" PRId64, pIter, writelen, pIter->total);
×
UNCOV
879
  return 0;
×
880
}
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