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

taosdata / TDengine / #5049

11 May 2026 06:30AM UTC coverage: 73.313% (+0.09%) from 73.222%
#5049

push

travis-ci

web-flow
feat: refactor taosdump code to improve backup speed and compression ratio (#35292)

6625 of 8435 new or added lines in 28 files covered. (78.54%)

2491 existing lines in 142 files now uncovered.

281233 of 383605 relevant lines covered (73.31%)

132489999.79 hits per line

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

68.96
/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 "tjson.h"
24
#include "wal.h"
25

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

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

33
// Forward declaration
34
static int32_t sdbWriteFileImp(SSdb *pSdb, int32_t skip_type);
35

36
static int32_t sdbDeployData(SSdb *pSdb) {
388,347✔
37
  int32_t code = 0;
388,347✔
38
  mInfo("start to deploy sdb");
388,347✔
39

40
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
19,417,350✔
41
    SdbDeployFp fp = pSdb->deployFps[i];
19,029,003✔
42
    if (fp == NULL) continue;
19,029,003✔
43

44
    mInfo("start to deploy sdb:%s", sdbTableName(i));
3,102,618✔
45
    code = (*fp)(pSdb->pMnode);
3,102,618✔
46
    if (code != 0) {
3,102,618✔
47
      mError("failed to deploy sdb:%s since %s", sdbTableName(i), tstrerror(code));
×
48
      return -1;
×
49
    }
50
  }
51

52
  mInfo("sdb deploy success");
388,347✔
53
  return 0;
388,347✔
54
}
55

56
static int32_t sdbAfterRestoredData(SSdb *pSdb) {
256,939✔
57
  int32_t code = 0;
256,939✔
58
  mInfo("start to prepare sdb");
256,939✔
59

60
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
12,846,950✔
61
    SdbAfterRestoredFp fp = pSdb->afterRestoredFps[i];
12,590,011✔
62
    if (fp == NULL) continue;
12,590,011✔
63

64
    mInfo("start to prepare sdb:%s", sdbTableName(i));
256,939✔
65
    code = (*fp)(pSdb->pMnode);
256,939✔
66
    if (code != 0) {
256,939✔
67
      mError("failed to prepare sdb:%s since %s", sdbTableName(i), tstrerror(code));
×
68
      return -1;
×
69
    }
70
  }
71

72
  mInfo("sdb prepare success");
256,939✔
73
  return 0;
256,939✔
74
}
75

76
static void sdbResetData(SSdb *pSdb) {
155,233✔
77
  mInfo("start to reset sdb");
155,233✔
78

79
  for (ESdbType i = 0; i < SDB_MAX; ++i) {
7,761,650✔
80
    SHashObj *hash = pSdb->hashObjs[i];
7,606,417✔
81
    if (hash == NULL) continue;
7,606,417✔
82

83
    sdbWriteLock(pSdb, i);
6,942,717✔
84

85
    SSdbRow **ppRow = taosHashIterate(hash, NULL);
6,942,717✔
86
    while (ppRow != NULL) {
6,943,707✔
87
      SSdbRow *pRow = *ppRow;
990✔
88
      if (pRow == NULL) continue;
990✔
89

90
      sdbFreeRow(pSdb, pRow, true);
990✔
91
      ppRow = taosHashIterate(hash, ppRow);
990✔
92
    }
93

94
    taosHashClear(pSdb->hashObjs[i]);
6,942,717✔
95
    pSdb->tableVer[i] = 0;
6,942,717✔
96
    pSdb->maxId[i] = 0;
6,942,717✔
97

98
    sdbUnLock(pSdb, i);
6,942,717✔
99

100
    mInfo("sdb:%s is reset", sdbTableName(i));
6,942,717✔
101
  }
102

103
  pSdb->applyIndex = -1;
155,233✔
104
  pSdb->applyTerm = -1;
155,233✔
105
  pSdb->applyConfig = -1;
155,233✔
106
  pSdb->commitIndex = -1;
155,233✔
107
  pSdb->commitTerm = -1;
155,233✔
108
  pSdb->commitConfig = -1;
155,233✔
109
  mInfo("sdb reset success");
155,233✔
110
}
155,233✔
111

112
static int32_t sdbReadFileHead(SSdb *pSdb, TdFilePtr pFile) {
135,549✔
113
  int32_t code = 0;
135,549✔
114
  int64_t sver = 0;
135,549✔
115
  int32_t ret = taosReadFile(pFile, &sver, sizeof(int64_t));
135,549✔
116
  if (ret < 0) {
135,549✔
UNCOV
117
    return terrno;
×
118
  }
119
  if (ret != sizeof(int64_t)) {
135,549✔
UNCOV
120
    code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
121
    TAOS_RETURN(code);
×
122
  }
123
  if (sver != SDB_FILE_VER) {
135,549✔
UNCOV
124
    code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
125
    TAOS_RETURN(code);
×
126
  }
127

128
  ret = taosReadFile(pFile, &pSdb->applyIndex, sizeof(int64_t));
135,549✔
129
  if (ret < 0) {
135,549✔
UNCOV
130
    return terrno;
×
131
  }
132
  if (ret != sizeof(int64_t)) {
135,549✔
UNCOV
133
    code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
134
    TAOS_RETURN(code);
×
135
  }
136

137
  ret = taosReadFile(pFile, &pSdb->applyTerm, sizeof(int64_t));
135,549✔
138
  if (ret < 0) {
135,549✔
UNCOV
139
    return terrno;
×
140
  }
141
  if (ret != sizeof(int64_t)) {
135,549✔
UNCOV
142
    code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
143
    TAOS_RETURN(code);
×
144
  }
145

146
  ret = taosReadFile(pFile, &pSdb->applyConfig, sizeof(int64_t));
135,549✔
147
  if (ret < 0) {
135,549✔
UNCOV
148
    return terrno;
×
149
  }
150
  if (ret != sizeof(int64_t)) {
135,549✔
UNCOV
151
    code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
152
    TAOS_RETURN(code);
×
153
  }
154

155
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
3,388,725✔
156
    int64_t maxId = 0;
3,253,176✔
157
    ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
3,253,176✔
158
    if (ret < 0) {
3,253,176✔
159
      return terrno;
×
160
    }
161
    if (ret != sizeof(int64_t)) {
3,253,176✔
162
      code = TSDB_CODE_FILE_CORRUPTED;
×
163
      TAOS_RETURN(code);
×
164
    }
165
    if (i < SDB_MAX) {
3,253,176✔
166
      pSdb->maxId[i] = maxId;
3,253,176✔
167
    }
168
  }
169

170
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
3,388,725✔
171
    int64_t ver = 0;
3,253,176✔
172
    ret = taosReadFile(pFile, &ver, sizeof(int64_t));
3,253,176✔
173
    if (ret < 0) {
3,253,176✔
UNCOV
174
      return terrno;
×
175
    }
176
    if (ret != sizeof(int64_t)) {
3,253,176✔
UNCOV
177
      code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
178
      TAOS_RETURN(code);
×
179
    }
180
    if (i < SDB_MAX) {
3,253,176✔
181
      pSdb->tableVer[i] = ver;
3,253,176✔
182
    }
183
  }
184

185
  // for sdb compatibility
186
  for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
3,524,274✔
187
    int64_t maxId = 0;
3,388,725✔
188
    ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
3,388,725✔
189
    if (ret < 0) {
3,388,725✔
UNCOV
190
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
UNCOV
191
      TAOS_RETURN(code);
×
192
    }
193
    if (ret != sizeof(int64_t)) {
3,388,725✔
194
      code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
195
      TAOS_RETURN(code);
×
196
    }
197
    if (i < SDB_MAX) {
3,388,725✔
198
      pSdb->maxId[i] = maxId;
3,388,725✔
199
    }
200

201
    int64_t ver = 0;
3,388,725✔
202
    ret = taosReadFile(pFile, &ver, sizeof(int64_t));
3,388,725✔
203
    if (ret < 0) {
3,388,725✔
UNCOV
204
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
UNCOV
205
      TAOS_RETURN(code);
×
206
    }
207
    if (ret != sizeof(int64_t)) {
3,388,725✔
UNCOV
208
      code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
209
      TAOS_RETURN(code);
×
210
    }
211
    if (i < SDB_MAX) {
3,388,725✔
212
      pSdb->tableVer[i] = ver;
3,388,725✔
213
    }
214
  }
215

216
  char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
135,549✔
217
  ret = taosReadFile(pFile, reserve, sizeof(reserve));
135,549✔
218
  if (ret < 0) {
135,549✔
UNCOV
219
    return terrno;
×
220
  }
221
  if (ret != sizeof(reserve)) {
135,549✔
UNCOV
222
    code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
223
    TAOS_RETURN(code);
×
224
  }
225

226
  return 0;
135,549✔
227
}
228

229
static int32_t sdbWriteFileHead(SSdb *pSdb, TdFilePtr pFile) {
1,027,457✔
230
  int64_t sver = SDB_FILE_VER;
1,027,457✔
231
  if (taosWriteFile(pFile, &sver, sizeof(int64_t)) != sizeof(int64_t)) {
1,027,457✔
UNCOV
232
    return terrno;
×
233
  }
234

235
  mInfo("vgId:1, write sdb file with sdb applyIndex:%" PRId64 " term:%" PRId64 " config:%" PRId64, pSdb->applyIndex,
1,027,457✔
236
        pSdb->applyTerm, pSdb->applyConfig);
237
  if (taosWriteFile(pFile, &pSdb->applyIndex, sizeof(int64_t)) != sizeof(int64_t)) {
1,027,457✔
UNCOV
238
    return terrno;
×
239
  }
240

241
  if (taosWriteFile(pFile, &pSdb->applyTerm, sizeof(int64_t)) != sizeof(int64_t)) {
1,027,457✔
242
    return terrno;
×
243
  }
244

245
  if (taosWriteFile(pFile, &pSdb->applyConfig, sizeof(int64_t)) != sizeof(int64_t)) {
1,027,457✔
UNCOV
246
    return terrno;
×
247
  }
248

249
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
25,686,425✔
250
    int64_t maxId = 0;
24,658,968✔
251
    if (i < SDB_MAX) {
24,658,968✔
252
      maxId = pSdb->maxId[i];
24,658,968✔
253
    }
254
    if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
24,658,968✔
UNCOV
255
      return terrno;
×
256
    }
257
  }
258

259
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
25,686,425✔
260
    int64_t ver = 0;
24,658,968✔
261
    if (i < SDB_MAX) {
24,658,968✔
262
      ver = pSdb->tableVer[i];
24,658,968✔
263
    }
264
    if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
24,658,968✔
UNCOV
265
      return terrno;
×
266
    }
267
  }
268

269
  // for sdb compatibility
270
  for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
26,713,882✔
271
    int64_t maxId = 0;
25,686,425✔
272
    if (i < SDB_MAX) {
25,686,425✔
273
      maxId = pSdb->maxId[i];
25,686,425✔
274
    }
275
    if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
25,686,425✔
UNCOV
276
      return terrno;
×
277
    }
278

279
    int64_t ver = 0;
25,686,425✔
280
    if (i < SDB_MAX) {
25,686,425✔
281
      ver = pSdb->tableVer[i];
25,686,425✔
282
    }
283
    if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
25,686,425✔
UNCOV
284
      return terrno;
×
285
    }
286
  }
287

288
  char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
1,027,457✔
289
  if (taosWriteFile(pFile, reserve, sizeof(reserve)) != sizeof(reserve)) {
1,027,457✔
UNCOV
290
    return terrno;
×
291
  }
292

293
  return 0;
1,027,457✔
294
}
295

296
// Read encrypted flag from mnode.json for defensive check
297
// This is more reliable than heuristics when receiving snapshots
298
static bool sdbReadEncryptedFlagFromMnodeJson(SSdb *pSdb) {
594✔
299
  if (pSdb->mnodePath[0] == '\0') {
594✔
300
    // No mnode path configured, use heuristic
UNCOV
301
    return (tsMetaKey[0] != '\0');
×
302
  }
303

304
  // Read the encrypted flag from mnode.json
305
  char file[PATH_MAX] = {0};
594✔
306
  snprintf(file, sizeof(file), "%s%smnode.json", pSdb->mnodePath, TD_DIRSEP);
594✔
307

308
  // Try to read mnode.json
309
  char   *pData = NULL;
594✔
310
  int32_t dataLen = 0;
594✔
311
  if (taosReadCfgFile(file, &pData, &dataLen) != 0) {
594✔
312
    // Cannot read, use heuristic
313
    return (tsMetaKey[0] != '\0');
198✔
314
  }
315

316
  SJson *pJson = tjsonParse(pData);
396✔
317
  taosMemoryFree(pData);
396✔
318

319
  if (pJson == NULL) {
396✔
UNCOV
320
    return (tsMetaKey[0] != '\0');
×
321
  }
322

323
  // Read encrypted field (default to false if not found)
324
  int32_t encrypted = 0;
396✔
325
  int32_t code = 0;
396✔
326
  tjsonGetInt32ValueFromDouble(pJson, "encrypted", encrypted, code);
396✔
327
  cJSON_Delete(pJson);
396✔
328

329
  return (encrypted != 0);
396✔
330
}
331

332
static int32_t sdbReadFileImp(SSdb *pSdb) {
155,233✔
333
  int64_t offset = 0;
155,233✔
334
  int32_t code = 0;
155,233✔
335
  int32_t readLen = 0;
155,233✔
336
  int64_t ret = 0;
155,233✔
337
  char    file[PATH_MAX] = {0};
155,233✔
338
  int32_t bufLen = TSDB_MAX_MSG_SIZE;
155,233✔
339
  bool    needMigration = false;
155,233✔
340

341
  snprintf(file, sizeof(file), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
155,233✔
342

343
  // Wait for encryption keys to be loaded
344
  code = taosWaitCfgKeyLoaded();
155,233✔
345
  if (code != 0) {
155,233✔
UNCOV
346
    mError("failed to wait for encryption keys since %s", tstrerror(code));
×
UNCOV
347
    return code;
×
348
  }
349

350
  // Check if sdb.data needs encryption migration
351
  // This info is stored in mnode.json encrypted flag
352
  bool isEncrypted = pSdb->encrypted;
155,233✔
353
  if (!isEncrypted && tsMetaKey[0] != '\0') {
155,233✔
354
    mInfo("sdb.data not encrypted but tsMetaKey available, checking encrypted flag from mnode.json");
396✔
355
    isEncrypted = sdbReadEncryptedFlagFromMnodeJson(pSdb);  // Fix: don't redeclare, just assign
396✔
356
    if (isEncrypted) {
396✔
UNCOV
357
      mInfo("reload encrypted flag from mnode.json is true, will not migrate after reading");
×
UNCOV
358
      needMigration = false;
×
359
    } else {
360
      mInfo("reload encrypted flag from mnode.json is false, will migrate after reading");
396✔
361
      needMigration = true;
396✔
362
    }
363
  }
364

365
  pSdb->encrypted = isEncrypted;
155,233✔
366

367
  mInfo("start to read sdb file:%s, encrypted:%d, needMigration:%d", file, isEncrypted, needMigration);
155,233✔
368

369
  SSdbRaw *pRaw = taosMemoryMalloc(bufLen + 100);
155,233✔
370
  if (pRaw == NULL) {
155,233✔
UNCOV
371
    code = terrno;
×
UNCOV
372
    mError("failed read sdb file since %s", tstrerror(code));
×
UNCOV
373
    TAOS_RETURN(code);
×
374
  }
375

376
  TdFilePtr pFile = taosOpenFile(file, TD_FILE_READ);
155,233✔
377
  if (pFile == NULL) {
155,233✔
378
    taosMemoryFree(pRaw);
19,684✔
379
    code = terrno;
19,684✔
380
    mInfo("read sdb file:%s finished since %s", file, tstrerror(code));
19,684✔
381
    return 0;
19,684✔
382
  }
383

384
  code = sdbReadFileHead(pSdb, pFile);
135,549✔
385
  if (code != 0) {
135,549✔
UNCOV
386
    mError("failed to read sdb file:%s head since %s", file, tstrerror(code));
×
UNCOV
387
    taosMemoryFree(pRaw);
×
UNCOV
388
    int32_t ret = 0;
×
UNCOV
389
    if ((ret = taosCloseFile(&pFile)) != 0) {
×
UNCOV
390
      mError("failed to close sdb file:%s since %s", file, tstrerror(ret));
×
391
    }
392
    return code;
×
393
  }
394

395
  int64_t tableVer[SDB_MAX] = {0};
135,549✔
396
  memcpy(tableVer, pSdb->tableVer, sizeof(tableVer));
135,549✔
397

398
  while (1) {
21,149,512✔
399
    readLen = sizeof(SSdbRaw);
21,285,061✔
400
    ret = taosReadFile(pFile, pRaw, readLen);
21,285,061✔
401
    if (ret == 0) break;
21,285,061✔
402

403
    if (ret < 0) {
21,149,512✔
UNCOV
404
      code = terrno;
×
UNCOV
405
      mError("failed to read sdb file:%s since %s", file, tstrerror(code));
×
406
      goto _OVER;
×
407
    }
408

409
    if (ret != readLen) {
21,149,512✔
410
      code = TSDB_CODE_FILE_CORRUPTED;
×
UNCOV
411
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " != readLen:%d", file, tstrerror(code), ret, readLen);
×
412
      goto _OVER;
×
413
    }
414

415
    readLen = pRaw->dataLen + sizeof(int32_t);
21,149,512✔
416
    if (tsMetaKey[0] != '\0' && !needMigration) {
21,149,512✔
417
      readLen = ENCRYPTED_LEN(pRaw->dataLen) + sizeof(int32_t);
251,934✔
418
    }
419
    if (readLen >= bufLen) {
21,149,512✔
UNCOV
420
      bufLen = pRaw->dataLen * 2;
×
UNCOV
421
      SSdbRaw *pNewRaw = taosMemoryMalloc(bufLen + 100);
×
UNCOV
422
      if (pNewRaw == NULL) {
×
UNCOV
423
        code = terrno;
×
424
        mError("failed read sdb file since malloc new sdbRaw size:%d failed", bufLen);
×
425
        goto _OVER;
×
426
      }
UNCOV
427
      mInfo("malloc new sdb raw size:%d, type:%d", bufLen, pRaw->type);
×
UNCOV
428
      memcpy(pNewRaw, pRaw, sizeof(SSdbRaw));
×
UNCOV
429
      sdbFreeRaw(pRaw);
×
430
      pRaw = pNewRaw;
×
431
    }
432

433
    ret = taosReadFile(pFile, pRaw->pData, readLen);
21,149,512✔
434
    if (ret < 0) {
21,149,512✔
UNCOV
435
      code = terrno;
×
UNCOV
436
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " readLen:%d", file, tstrerror(code), ret, readLen);
×
UNCOV
437
      goto _OVER;
×
438
    }
439

440
    if (ret != readLen) {
21,149,512✔
441
      code = TSDB_CODE_FILE_CORRUPTED;
×
442
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " != readLen:%d", file, tstrerror(code), ret, readLen);
×
443
      goto _OVER;
×
444
    }
445

446
    if (taosWaitCfgKeyLoaded() != 0) {
21,149,512✔
447
      code = terrno;
×
448
      goto _OVER;
×
449
    }
450

451
    if (tsMetaKey[0] != '\0' && !needMigration) {
21,149,512✔
452
      int32_t count = 0;
251,934✔
453

454
      char *plantContent = taosMemoryMalloc(ENCRYPTED_LEN(pRaw->dataLen));
251,934✔
455
      if (plantContent == NULL) {
251,934✔
456
        code = terrno;
×
457
        goto _OVER;
×
458
      }
459

460
      SCryptOpts opts = {0};
251,934✔
461
      opts.len = ENCRYPTED_LEN(pRaw->dataLen);
251,934✔
462
      opts.source = pRaw->pData;
251,934✔
463
      opts.result = plantContent;
251,934✔
464
      opts.unitLen = 16;
251,934✔
465
      opts.pOsslAlgrName = taosGetEncryptAlgoName(tsEncryptAlgorithmType);
251,934✔
466
      tstrncpy(opts.key, tsMetaKey, ENCRYPT_KEY_LEN + 1);
251,934✔
467

468
      count = CBC_Decrypt(&opts);
251,934✔
469
      if (count <= 0) {
251,934✔
UNCOV
470
        code = terrno;
×
UNCOV
471
        goto _OVER;
×
472
      }
473

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

476
      memcpy(pRaw->pData, plantContent, pRaw->dataLen);
251,934✔
477
      taosMemoryFree(plantContent);
251,934✔
478
      memcpy(pRaw->pData + pRaw->dataLen, &pRaw->pData[ENCRYPTED_LEN(pRaw->dataLen)], sizeof(int32_t));
251,934✔
479
    }
480

481
    int32_t totalLen = sizeof(SSdbRaw) + pRaw->dataLen + sizeof(int32_t);
21,149,512✔
482
    if ((!taosCheckChecksumWhole((const uint8_t *)pRaw, totalLen)) != 0) {
42,299,024✔
UNCOV
483
      code = TSDB_CODE_CHECKSUM_ERROR;
×
UNCOV
484
      mError("failed to read sdb file:%s since %s, readLen:%d", file, tstrerror(code), readLen);
×
UNCOV
485
      goto _OVER;
×
486
    }
487

488
    if (pRaw->type >= SDB_MAX) {
21,149,512✔
UNCOV
489
      mInfo("skip sdb raw type:%d since it is not supported", pRaw->type);
×
490
      continue;
×
491
    }
492

493
    code = sdbWriteWithoutFree(pSdb, pRaw);
21,149,512✔
494
    if (code != 0) {
21,149,512✔
UNCOV
495
      mError("failed to exec sdbWrite while read sdb file:%s since %s", file, terrstr());
×
UNCOV
496
      goto _OVER;
×
497
    }
498
  }
499

500
  code = 0;
135,549✔
501
  pSdb->commitIndex = pSdb->applyIndex;
135,549✔
502
  pSdb->commitTerm = pSdb->applyTerm;
135,549✔
503
  pSdb->commitConfig = pSdb->applyConfig;
135,549✔
504
  memcpy(pSdb->tableVer, tableVer, sizeof(tableVer));
135,549✔
505
  mInfo("vgId:1, trans:0, read sdb file:%s success, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64, file,
135,549✔
506
        pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig);
507

508
_OVER:
134,474✔
509
  if ((ret = taosCloseFile(&pFile)) != 0) {
135,549✔
510
    mError("failed to close sdb file:%s since %s", file, tstrerror(ret));
×
511
  }
512
  sdbFreeRaw(pRaw);
135,549✔
513

514
  TAOS_RETURN(code);
135,549✔
515
}
516

517
int32_t sdbReadFile(SSdb *pSdb) {
155,233✔
518
  (void)taosThreadMutexLock(&pSdb->filelock);
155,233✔
519

520
  sdbResetData(pSdb);
155,233✔
521
  int32_t code = sdbReadFileImp(pSdb);
155,233✔
522
  if (code != 0) {
155,233✔
UNCOV
523
    mError("failed to read sdb file since %s", tstrerror(code));
×
UNCOV
524
    sdbResetData(pSdb);
×
UNCOV
525
    return code;
×
526
  }
527

528
  // Check if sdb.data needs encryption migration
529
  bool isEncrypted = pSdb->encrypted;
155,233✔
530
  if (!isEncrypted && tsMetaKey[0] != '\0') {
155,233✔
531
    mInfo("sdb.data read successfully, now migrating to encrypted format");
396✔
532

533
    // Rewrite sdb.data with encryption (atomic operation)
534
    code = sdbWriteFileImp(pSdb, -1);
396✔
535
    if (code != 0) {
396✔
UNCOV
536
      mError("failed to migrate sdb.data to encrypted format since %s", tstrerror(code));
×
537
      // Don't fail the read, continue
UNCOV
538
      (void)taosThreadMutexUnlock(&pSdb->filelock);
×
UNCOV
539
      return code;
×
540
    }
541

542
    // Update encrypted flag and persist to mnode.json immediately (atomic operation)
543
    pSdb->encrypted = true;
396✔
544

545
    if (pSdb->persistEncryptedFlagFp != NULL && pSdb->pMnodeForCallback != NULL) {
396✔
546
      code = pSdb->persistEncryptedFlagFp(pSdb->pMnodeForCallback);
396✔
547
      if (code == 0) {
396✔
548
        mInfo("sdb.data migrated to encrypted format and persisted encrypted flag to mnode.json successfully");
396✔
549
      } else {
UNCOV
550
        mError("failed to persist encrypted flag to mnode.json since %s", tstrerror(code));
×
551
        // Rollback encrypted flag
UNCOV
552
        pSdb->encrypted = false;
×
553
      }
554
    } else {
UNCOV
555
      mWarn("sdb.data migrated to encrypted format but no callback to persist flag");
×
556
    }
557
  }
558

559
  (void)taosThreadMutexUnlock(&pSdb->filelock);
155,233✔
560
  return code;
155,233✔
561
}
562

563
int32_t sdbWriteFileImp(SSdb *pSdb, int32_t skip_type) {
1,027,457✔
564
  int32_t code = 0;
1,027,457✔
565

566
  char tmpfile[PATH_MAX] = {0};
1,027,457✔
567
  snprintf(tmpfile, sizeof(tmpfile), "%s%ssdb.data", pSdb->tmpDir, TD_DIRSEP);
1,027,457✔
568
  char curfile[PATH_MAX] = {0};
1,027,457✔
569
  snprintf(curfile, sizeof(curfile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
1,027,457✔
570

571
  mInfo("start to write sdb file, apply index:%" PRId64 " term:%" PRId64 " config:%" PRId64 ", commit index:%" PRId64
1,027,457✔
572
        " term:%" PRId64 " config:%" PRId64 ", file:%s",
573
        pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig, pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig,
574
        curfile);
575

576
  TdFilePtr pFile = taosOpenFile(tmpfile, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
1,027,457✔
577
  if (pFile == NULL) {
1,027,457✔
UNCOV
578
    code = terrno;
×
UNCOV
579
    mError("failed to open sdb file:%s for write since %s", tmpfile, tstrerror(code));
×
UNCOV
580
    TAOS_RETURN(code);
×
581
  }
582

583
  code = sdbWriteFileHead(pSdb, pFile);
1,027,457✔
584
  if (code != 0) {
1,027,457✔
UNCOV
585
    mError("failed to write sdb file:%s head since %s", tmpfile, tstrerror(code));
×
UNCOV
586
    int32_t ret = 0;
×
UNCOV
587
    if ((ret = taosCloseFile(&pFile)) != 0) {
×
UNCOV
588
      mError("failed to close sdb file:%s since %s", tmpfile, tstrerror(ret));
×
589
    }
UNCOV
590
    return code;
×
591
  }
592

593
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
51,372,850✔
594
    if (i == skip_type) continue;
50,345,393✔
595
    SdbEncodeFp encodeFp = pSdb->encodeFps[i];
50,345,393✔
596
    if (encodeFp == NULL) continue;
50,345,393✔
597

598
    mInfo("write %s to sdb file, total %d rows", sdbTableName(i), sdbGetSize(pSdb, i));
45,157,420✔
599

600
    SHashObj *hash = pSdb->hashObjs[i];
45,157,420✔
601
    sdbWriteLock(pSdb, i);
45,157,420✔
602

603
    SSdbRow **ppRow = taosHashIterate(hash, NULL);
45,157,420✔
604
    while (ppRow != NULL) {
202,186,164✔
605
      SSdbRow *pRow = *ppRow;
157,028,744✔
606
      if (pRow == NULL) {
157,028,744✔
607
        ppRow = taosHashIterate(hash, ppRow);
×
608
        continue;
×
609
      }
610

611
      if (pRow->status != SDB_STATUS_READY && pRow->status != SDB_STATUS_DROPPING) {
157,028,744✔
612
        sdbPrintOper(pSdb, pRow, "not-write");
37,832✔
613
        ppRow = taosHashIterate(hash, ppRow);
37,832✔
614
        continue;
37,832✔
615
      }
616

617
      sdbPrintOper(pSdb, pRow, "write");
156,990,912✔
618

619
      SSdbRaw *pRaw = (*encodeFp)(pRow->pObj);
156,990,912✔
620
      if (pRaw != NULL) {
156,990,912✔
621
        pRaw->status = pRow->status;
156,990,912✔
622

623
        if (taosWriteFile(pFile, pRaw, sizeof(SSdbRaw)) != sizeof(SSdbRaw)) {
156,990,912✔
UNCOV
624
          code = terrno;
×
UNCOV
625
          taosHashCancelIterate(hash, ppRow);
×
UNCOV
626
          sdbFreeRaw(pRaw);
×
627
          break;
×
628
        }
629

630
        int32_t newDataLen = pRaw->dataLen;
156,990,912✔
631
        char   *newData = pRaw->pData;
156,990,912✔
632

633
        if (taosWaitCfgKeyLoaded() != 0) {
156,990,912✔
UNCOV
634
          code = terrno;
×
UNCOV
635
          taosHashCancelIterate(hash, ppRow);
×
UNCOV
636
          sdbFreeRaw(pRaw);
×
UNCOV
637
          break;
×
638
        }
639

640
        if (tsMetaKey[0] != '\0') {
156,990,912✔
641
          newDataLen = ENCRYPTED_LEN(pRaw->dataLen);
1,259,639✔
642
          newData = taosMemoryMalloc(newDataLen);
1,259,639✔
643
          if (newData == NULL) {
1,259,639✔
644
            code = terrno;
×
645
            taosHashCancelIterate(hash, ppRow);
×
646
            sdbFreeRaw(pRaw);
×
647
            break;
×
648
          }
649

650
          SCryptOpts opts = {0};
1,259,639✔
651
          opts.len = newDataLen;
1,259,639✔
652
          opts.source = pRaw->pData;
1,259,639✔
653
          opts.result = newData;
1,259,639✔
654
          opts.unitLen = 16;
1,259,639✔
655
          opts.pOsslAlgrName = taosGetEncryptAlgoName(tsEncryptAlgorithmType);
1,259,639✔
656
          tstrncpy(opts.key, tsMetaKey, ENCRYPT_KEY_LEN + 1);
1,259,639✔
657

658
          int32_t count = CBC_Encrypt(&opts);
1,259,639✔
659
          if (count <= 0) {
1,259,639✔
UNCOV
660
            code = terrno;
×
UNCOV
661
            taosHashCancelIterate(hash, ppRow);
×
UNCOV
662
            sdbFreeRaw(pRaw);
×
UNCOV
663
            break;
×
664
          }
665

666
          // mDebug("write sdb, CBC Encrypt encryptedDataLen:%d, dataLen:%d, %s",
667
          //       newDataLen, pRaw->dataLen, __FUNCTION__);
668
        }
669

670
        if (taosWriteFile(pFile, newData, newDataLen) != newDataLen) {
156,990,912✔
UNCOV
671
          code = terrno;
×
UNCOV
672
          taosHashCancelIterate(hash, ppRow);
×
UNCOV
673
          sdbFreeRaw(pRaw);
×
UNCOV
674
          break;
×
675
        }
676

677
        if (tsMetaKey[0] != '\0') {
156,990,912✔
678
          taosMemoryFree(newData);
1,259,639✔
679
        }
680

681
        int32_t cksum = taosCalcChecksum(0, (const uint8_t *)pRaw, sizeof(SSdbRaw) + pRaw->dataLen);
156,990,912✔
682
        if (taosWriteFile(pFile, &cksum, sizeof(int32_t)) != sizeof(int32_t)) {
156,990,912✔
683
          code = terrno;
×
UNCOV
684
          taosHashCancelIterate(hash, ppRow);
×
UNCOV
685
          sdbFreeRaw(pRaw);
×
UNCOV
686
          break;
×
687
        }
688
      } else {
UNCOV
689
        code = TSDB_CODE_APP_ERROR;
×
UNCOV
690
        taosHashCancelIterate(hash, ppRow);
×
691
        break;
×
692
      }
693

694
      sdbFreeRaw(pRaw);
156,990,912✔
695
      ppRow = taosHashIterate(hash, ppRow);
156,990,912✔
696
    }
697
    sdbUnLock(pSdb, i);
45,157,420✔
698
  }
699

700
  if (code == 0) {
1,027,457✔
701
    code = taosFsyncFile(pFile);
1,027,457✔
702
    if (code != 0) {
1,027,457✔
703
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
704
      mError("failed to sync sdb file:%s since %s", tmpfile, tstrerror(code));
×
705
    }
706
  }
707

708
  if (taosCloseFile(&pFile) != 0) {
1,027,457✔
709
    code = taosRenameFile(tmpfile, curfile);
×
710
  }
711

712
  if (code == 0) {
1,027,457✔
713
    code = taosRenameFile(tmpfile, curfile);
1,027,457✔
714
    if (code != 0) {
1,027,457✔
UNCOV
715
      mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
×
716
    }
717
  }
718

719
  if (code != 0) {
1,027,457✔
UNCOV
720
    mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
×
721
  } else {
722
    pSdb->commitIndex = pSdb->applyIndex;
1,027,457✔
723
    pSdb->commitTerm = pSdb->applyTerm;
1,027,457✔
724
    pSdb->commitConfig = pSdb->applyConfig;
1,027,457✔
725
    mInfo("vgId:1, trans:0, write sdb file success, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64
1,027,457✔
726
          " file:%s",
727
          pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig, curfile);
728

729
    if (tsMetaKey[0] != '\0') {
1,027,457✔
730
      if (pSdb->persistEncryptedFlagFp != NULL && pSdb->pMnodeForCallback != NULL) {
9,101✔
731
        code = pSdb->persistEncryptedFlagFp(pSdb->pMnodeForCallback);
9,101✔
732
        if (code == 0) {
9,101✔
733
          mInfo("sdb.data now is encrypted format and persisted encrypted flag to mnode.json successfully");
9,101✔
734
          pSdb->encrypted = true;
9,101✔
735
        } else {
UNCOV
736
          mError("failed to persist encrypted flag to mnode.json since %s", tstrerror(code));
×
UNCOV
737
          return code;
×
738
        }
739
      } else {
740
        mWarn("sdb.data written in encrypted format but no callback to persist flag");
×
UNCOV
741
        pSdb->encrypted = true;
×
742
      }
743
    }
744
  }
745

746
  terrno = code;
1,027,457✔
747
  return code;
1,027,457✔
748
}
749

750
int32_t sdbWriteFile(SSdb *pSdb, int32_t delta) {
53,267,748✔
751
  int32_t code = 0;
53,267,748✔
752
  if (pSdb->applyIndex == pSdb->commitIndex) {
53,267,748✔
753
    return 0;
548,995✔
754
  }
755

756
  if (pSdb->applyIndex - pSdb->commitIndex < delta) {
52,718,753✔
757
    return 0;
51,686,647✔
758
  }
759

760
  (void)taosThreadMutexLock(&pSdb->filelock);
1,032,106✔
761
  if (pSdb->pWal != NULL) {
1,032,106✔
762
    if (pSdb->sync > 0) {
1,031,314✔
763
      code = syncBeginSnapshot(pSdb->sync, pSdb->applyIndex);
1,031,314✔
764
    }
765
  }
766
  if (code == 0) {
1,032,106✔
767
    code = sdbWriteFileImp(pSdb, -1);
1,027,061✔
768
  }
769
  if (code == 0) {
1,032,106✔
770
    if (pSdb->pWal != NULL) {
1,027,061✔
771
      if (pSdb->sync > 0) {
1,026,269✔
772
        code = syncEndSnapshot(pSdb->sync, false);
1,026,269✔
773
      }
774
    }
775
  }
776
  if (code != 0) {
1,032,106✔
777
    mError("failed to write sdb file since %s", tstrerror(code));
5,045✔
778
  } else {
779
    mInfo("vgId:1, trans:0, write sdb file success, apply index:%" PRId64 ", term:%" PRId64 ", config:%" PRId64,
1,027,061✔
780
          pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig);
781
  }
782
  (void)taosThreadMutexUnlock(&pSdb->filelock);
1,032,106✔
783

784
  return code;
1,032,106✔
785
}
786

UNCOV
787
int32_t sdbWriteFileForDump(SSdb *pSdb, int32_t skip_type) {
×
UNCOV
788
  int32_t code = 0;
×
789

UNCOV
790
  code = sdbWriteFileImp(pSdb, skip_type);
×
791

UNCOV
792
  return code;
×
793
}
794

795
int32_t sdbDeploy(SSdb *pSdb) {
388,347✔
796
  int32_t code = 0;
388,347✔
797
  code = sdbDeployData(pSdb);
388,347✔
798
  if (code != 0) {
388,347✔
UNCOV
799
    TAOS_RETURN(code);
×
800
  }
801

802
  code = sdbWriteFile(pSdb, 0);
388,347✔
803
  if (code != 0) {
388,347✔
UNCOV
804
    TAOS_RETURN(code);
×
805
  }
806

807
  return 0;
388,347✔
808
}
809

810
int32_t sdbUpgrade(SSdb *pSdb, int32_t version) {
442,252✔
811
  int32_t code = 0;
442,252✔
812
  mInfo("start to upgrade sdb");
442,252✔
813

814
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
22,112,600✔
815
    SdbUpgradeFp fp = pSdb->upgradeFps[i];
21,670,348✔
816
    if (fp == NULL) continue;
21,670,348✔
817

818
    mInfo("start to upgrade sdb:%s", sdbTableName(i));
1,326,756✔
819
    code = (*fp)(pSdb->pMnode, version);
1,326,756✔
820
    if (code != 0) {
1,326,756✔
UNCOV
821
      mError("failed to upgrade sdb:%s since %s", sdbTableName(i), tstrerror(code));
×
UNCOV
822
      TAOS_RETURN(code);
×
823
    }
824
  }
825

826
  mInfo("sdb upgrade success");
442,252✔
827
  return 0;
442,252✔
828
}
829

830
bool sdbIsUpgraded(SSdb *pSdb) {
1,373,059✔
831
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
33,518,430✔
832
    SdbIsUpgradedFp fp = pSdb->isUpgradedFps[i];
33,023,734✔
833
    if (fp == NULL) continue;
33,023,734✔
834

835
    mDebug("start to check if sdb:%s is upgraded", sdbTableName(i));
1,373,059✔
836
    bool isUpgraded = (*fp)(pSdb->pMnode);
1,373,059✔
837
    if (isUpgraded == false) {
1,373,059✔
838
      mInfo("sdb:%s is not upgraded yet", sdbTableName(i));
878,363✔
839
      return false;
878,363✔
840
    }
841
  }
842

843
  return true;
494,696✔
844
}
845

846
int32_t sdbAfterRestored(SSdb *pSdb) {
256,939✔
847
  int32_t code = 0;
256,939✔
848
  code = sdbAfterRestoredData(pSdb);
256,939✔
849
  if (code != 0) {
256,939✔
UNCOV
850
    TAOS_RETURN(code);
×
851
  }
852
  return 0;
256,939✔
853
}
854

855
static SSdbIter *sdbCreateIter(SSdb *pSdb) {
396✔
856
  SSdbIter *pIter = taosMemoryCalloc(1, sizeof(SSdbIter));
396✔
857
  if (pIter == NULL) {
396✔
858
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
859
    return NULL;
×
860
  }
861

862
  char name[PATH_MAX + 100] = {0};
396✔
863
  snprintf(name, sizeof(name), "%s%ssdb.data.%" PRIu64, pSdb->tmpDir, TD_DIRSEP, (uint64_t)pIter);
396✔
864
  pIter->name = taosStrdup(name);
396✔
865
  if (pIter->name == NULL) {
396✔
866
    taosMemoryFree(pIter);
×
867
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
868
    return NULL;
×
869
  }
870

871
  return pIter;
396✔
872
}
873

874
static void sdbCloseIter(SSdbIter *pIter) {
396✔
875
  if (pIter == NULL) return;
396✔
876

877
  if (pIter->file != NULL) {
396✔
878
    int32_t ret = 0;
198✔
879
    if ((ret = taosCloseFile(&pIter->file)) != 0) {
198✔
UNCOV
880
      mError("failed to close sdb file since %s", tstrerror(ret));
×
881
    }
882
    pIter->file = NULL;
198✔
883
  }
884

885
  if (pIter->name != NULL) {
396✔
886
    int32_t ret = 0;
396✔
887
    if ((ret = taosRemoveFile(pIter->name)) != 0) {
396✔
888
      mError("failed to remove sdb file:%s since %s", pIter->name, tstrerror(ret));
198✔
889
    }
890
    taosMemoryFree(pIter->name);
396✔
891
    pIter->name = NULL;
396✔
892
  }
893

894
  mInfo("sdbiter:%p, is closed, total:%" PRId64, pIter, pIter->total);
396✔
895
  taosMemoryFree(pIter);
396✔
896
}
897

898
int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter, int64_t *index, int64_t *term, int64_t *config) {
198✔
899
  int32_t   code = 0;
198✔
900
  SSdbIter *pIter = sdbCreateIter(pSdb);
198✔
901
  if (pIter == NULL) return -1;
198✔
902

903
  char datafile[PATH_MAX] = {0};
198✔
904
  snprintf(datafile, sizeof(datafile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
198✔
905

906
  (void)taosThreadMutexLock(&pSdb->filelock);
198✔
907
  int64_t commitIndex = pSdb->commitIndex;
198✔
908
  int64_t commitTerm = pSdb->commitTerm;
198✔
909
  int64_t commitConfig = pSdb->commitConfig;
198✔
910
  if (taosCopyFile(datafile, pIter->name) < 0) {
198✔
911
    code = terrno;
×
912
    (void)taosThreadMutexUnlock(&pSdb->filelock);
×
913
    mError("failed to copy sdb file %s to %s since %s", datafile, pIter->name, tstrerror(code));
×
914
    sdbCloseIter(pIter);
×
UNCOV
915
    TAOS_RETURN(code);
×
916
  }
917
  (void)taosThreadMutexUnlock(&pSdb->filelock);
198✔
918

919
  pIter->file = taosOpenFile(pIter->name, TD_FILE_READ);
198✔
920
  if (pIter->file == NULL) {
198✔
921
    code = terrno;
×
922
    mError("failed to open sdb file:%s since %s", pIter->name, tstrerror(code));
×
923
    sdbCloseIter(pIter);
×
UNCOV
924
    TAOS_RETURN(code);
×
925
  }
926

927
  *ppIter = pIter;
198✔
928
  if (index != NULL) *index = commitIndex;
198✔
929
  if (term != NULL) *term = commitTerm;
198✔
930
  if (config != NULL) *config = commitConfig;
198✔
931

932
  mInfo("sdbiter:%p, is created to read snapshot, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64 " file:%s",
198✔
933
        pIter, commitIndex, commitTerm, commitConfig, pIter->name);
934
  return 0;
198✔
935
}
936

937
void sdbStopRead(SSdb *pSdb, SSdbIter *pIter) { sdbCloseIter(pIter); }
198✔
938

939
int32_t sdbDoRead(SSdb *pSdb, SSdbIter *pIter, void **ppBuf, int32_t *len) {
396✔
940
  int32_t code = 0;
396✔
941
  int32_t maxlen = 4096;
396✔
942
  void   *pBuf = taosMemoryCalloc(1, maxlen);
396✔
943
  if (pBuf == NULL) {
396✔
944
    code = terrno;
×
UNCOV
945
    TAOS_RETURN(code);
×
946
  }
947

948
  int32_t readlen = taosReadFile(pIter->file, pBuf, maxlen);
396✔
949
  if (readlen < 0 || readlen > maxlen) {
396✔
950
    code = terrno;
×
951
    mError("sdbiter:%p, failed to read snapshot since %s, total:%" PRId64, pIter, tstrerror(code), pIter->total);
×
952
    *ppBuf = NULL;
×
953
    *len = 0;
×
954
    taosMemoryFree(pBuf);
×
UNCOV
955
    TAOS_RETURN(code);
×
956
  } else if (readlen == 0) {
396✔
957
    mInfo("sdbiter:%p, read snapshot to the end, total:%" PRId64, pIter, pIter->total);
198✔
958
    *ppBuf = NULL;
198✔
959
    *len = 0;
198✔
960
    taosMemoryFree(pBuf);
198✔
961
    return 0;
198✔
962
  } else {  // (readlen <= maxlen)
963
    pIter->total += readlen;
198✔
964
    mInfo("sdbiter:%p, read:%d bytes from snapshot, total:%" PRId64, pIter, readlen, pIter->total);
198✔
965
    *ppBuf = pBuf;
198✔
966
    *len = readlen;
198✔
967
    return 0;
198✔
968
  }
969
}
970

971
int32_t sdbStartWrite(SSdb *pSdb, SSdbIter **ppIter) {
198✔
972
  int32_t   code = 0;
198✔
973
  SSdbIter *pIter = sdbCreateIter(pSdb);
198✔
974
  if (pIter == NULL) {
198✔
975
    code = terrno;
×
UNCOV
976
    TAOS_RETURN(code);
×
977
  }
978

979
  pIter->file = taosOpenFile(pIter->name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
198✔
980
  if (pIter->file == NULL) {
198✔
981
    code = terrno;
×
982
    mError("failed to open %s since %s", pIter->name, tstrerror(code));
×
983
    sdbCloseIter(pIter);
×
UNCOV
984
    TAOS_RETURN(code);
×
985
  }
986

987
  *ppIter = pIter;
198✔
988
  mInfo("sdbiter:%p, is created to write snapshot, file:%s", pIter, pIter->name);
198✔
989
  return 0;
198✔
990
}
991

992
int32_t sdbStopWrite(SSdb *pSdb, SSdbIter *pIter, bool isApply, int64_t index, int64_t term, int64_t config) {
198✔
993
  int32_t code = -1;
198✔
994

995
  if (!isApply) {
198✔
996
    mInfo("sdbiter:%p, not apply to sdb", pIter);
×
997
    code = 0;
×
UNCOV
998
    goto _OVER;
×
999
  }
1000

1001
  if (taosFsyncFile(pIter->file) != 0) {
198✔
1002
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
1003
    mError("sdbiter:%p, failed to fasync file %s since %s", pIter, pIter->name, tstrerror(code));
×
UNCOV
1004
    goto _OVER;
×
1005
  }
1006

1007
  if (taosCloseFile(&pIter->file) != 0) {
198✔
1008
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
UNCOV
1009
    goto _OVER;
×
1010
  }
1011
  pIter->file = NULL;
198✔
1012

1013
  char datafile[PATH_MAX] = {0};
198✔
1014
  snprintf(datafile, sizeof(datafile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
198✔
1015
  code = taosRenameFile(pIter->name, datafile);
198✔
1016
  if (code != 0) {
198✔
1017
    mError("sdbiter:%p, failed to rename file %s to %s since %s", pIter, pIter->name, datafile, tstrerror(code));
×
UNCOV
1018
    goto _OVER;
×
1019
  }
1020

1021
  // Defensive check: re-read encrypted flag from mnode.json to ensure consistency
1022
  // This handles edge cases like CREATE MNODE where flag might not have been passed correctly
1023
  bool mnodeJsonEncrypted = sdbReadEncryptedFlagFromMnodeJson(pSdb);
198✔
1024
  if (mnodeJsonEncrypted != pSdb->encrypted) {
198✔
UNCOV
1025
    mInfo("sdbiter:%p, sdb encrypted flag mismatch: memory=%d, mnode.json=%d, correcting to %d", pIter, pSdb->encrypted,
×
1026
          mnodeJsonEncrypted, mnodeJsonEncrypted);
UNCOV
1027
    pSdb->encrypted = mnodeJsonEncrypted;
×
1028
  }
1029

1030
  code = sdbReadFile(pSdb);
198✔
1031
  if (code != 0) {
198✔
1032
    mError("sdbiter:%p, failed to read from %s since %s", pIter, datafile, tstrerror(code));
×
UNCOV
1033
    goto _OVER;
×
1034
  }
1035

1036
  if (config > 0) {
198✔
UNCOV
1037
    pSdb->commitConfig = config;
×
1038
  }
1039
  if (term > 0) {
198✔
UNCOV
1040
    pSdb->commitTerm = term;
×
1041
  }
1042
  if (index > 0) {
198✔
UNCOV
1043
    pSdb->commitIndex = index;
×
1044
  }
1045

1046
  mInfo("sdbiter:%p, success applyed to sdb", pIter);
198✔
1047
  code = 0;
198✔
1048

1049
_OVER:
198✔
1050
  sdbCloseIter(pIter);
198✔
1051
  return code;
198✔
1052
}
1053

1054
int32_t sdbDoWrite(SSdb *pSdb, SSdbIter *pIter, void *pBuf, int32_t len) {
198✔
1055
  int32_t code = 0;
198✔
1056
  int32_t writelen = taosWriteFile(pIter->file, pBuf, len);
198✔
1057
  if (writelen != len) {
198✔
1058
    code = terrno;
×
1059
    mError("failed to write len:%d since %s, total:%" PRId64, len, tstrerror(code), pIter->total);
×
UNCOV
1060
    TAOS_RETURN(code);
×
1061
  }
1062

1063
  pIter->total += writelen;
198✔
1064
  mInfo("sdbiter:%p, write:%d bytes to snapshot, total:%" PRId64, pIter, writelen, pIter->total);
198✔
1065
  return 0;
198✔
1066
}
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