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

taosdata / TDengine / #3549

06 Dec 2024 09:44AM UTC coverage: 59.948% (+0.1%) from 59.846%
#3549

push

travis-ci

web-flow
Merge pull request #29057 from taosdata/docs/TD-33031-3.0

docs: description of user privileges

118833 of 254191 branches covered (46.75%)

Branch coverage included in aggregate %.

199893 of 277480 relevant lines covered (72.04%)

19006119.35 hits per line

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

40.88
/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) {
1,330✔
32
  int32_t code = 0;
1,330✔
33
  mInfo("start to deploy sdb");
1,330!
34

35
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
39,900✔
36
    SdbDeployFp fp = pSdb->deployFps[i];
38,570✔
37
    if (fp == NULL) continue;
38,570✔
38

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

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

51
static void sdbResetData(SSdb *pSdb) {
484✔
52
  mInfo("start to reset sdb");
484!
53

54
  for (ESdbType i = 0; i < SDB_MAX; ++i) {
14,520✔
55
    SHashObj *hash = pSdb->hashObjs[i];
14,036✔
56
    if (hash == NULL) continue;
14,036✔
57

58
    sdbWriteLock(pSdb, i);
12,100✔
59

60
    SSdbRow **ppRow = taosHashIterate(hash, NULL);
12,100✔
61
    while (ppRow != NULL) {
12,100!
62
      SSdbRow *pRow = *ppRow;
×
63
      if (pRow == NULL) continue;
×
64

65
      sdbFreeRow(pSdb, pRow, true);
×
66
      ppRow = taosHashIterate(hash, ppRow);
×
67
    }
68

69
    taosHashClear(pSdb->hashObjs[i]);
12,100✔
70
    pSdb->tableVer[i] = 0;
12,100✔
71
    pSdb->maxId[i] = 0;
12,100✔
72

73
    sdbUnLock(pSdb, i);
12,100✔
74

75
    mInfo("sdb:%s is reset", sdbTableName(i));
12,100!
76
  }
77

78
  pSdb->applyIndex = -1;
484✔
79
  pSdb->applyTerm = -1;
484✔
80
  pSdb->applyConfig = -1;
484✔
81
  pSdb->commitIndex = -1;
484✔
82
  pSdb->commitTerm = -1;
484✔
83
  pSdb->commitConfig = -1;
484✔
84
  mInfo("sdb reset success");
484!
85
}
484✔
86

87
static int32_t sdbReadFileHead(SSdb *pSdb, TdFilePtr pFile) {
392✔
88
  int32_t code = 0;
392✔
89
  int64_t sver = 0;
392✔
90
  int32_t ret = taosReadFile(pFile, &sver, sizeof(int64_t));
392✔
91
  if (ret < 0) {
392!
92
    return terrno;
×
93
  }
94
  if (ret != sizeof(int64_t)) {
392!
95
    code = TSDB_CODE_FILE_CORRUPTED;
×
96
    TAOS_RETURN(code);
×
97
  }
98
  if (sver != SDB_FILE_VER) {
392!
99
    code = TSDB_CODE_FILE_CORRUPTED;
×
100
    TAOS_RETURN(code);
×
101
  }
102

103
  ret = taosReadFile(pFile, &pSdb->applyIndex, sizeof(int64_t));
392✔
104
  if (ret < 0) {
392!
105
    return terrno;
×
106
  }
107
  if (ret != sizeof(int64_t)) {
392!
108
    code = TSDB_CODE_FILE_CORRUPTED;
×
109
    TAOS_RETURN(code);
×
110
  }
111

112
  ret = taosReadFile(pFile, &pSdb->applyTerm, sizeof(int64_t));
392✔
113
  if (ret < 0) {
392!
114
    return terrno;
×
115
  }
116
  if (ret != sizeof(int64_t)) {
392!
117
    code = TSDB_CODE_FILE_CORRUPTED;
×
118
    TAOS_RETURN(code);
×
119
  }
120

121
  ret = taosReadFile(pFile, &pSdb->applyConfig, sizeof(int64_t));
392✔
122
  if (ret < 0) {
392!
123
    return terrno;
×
124
  }
125
  if (ret != sizeof(int64_t)) {
392!
126
    code = TSDB_CODE_FILE_CORRUPTED;
×
127
    TAOS_RETURN(code);
×
128
  }
129

130
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
9,800✔
131
    int64_t maxId = 0;
9,408✔
132
    ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
9,408✔
133
    if (ret < 0) {
9,408!
134
      return terrno;
×
135
    }
136
    if (ret != sizeof(int64_t)) {
9,408!
137
      code = TSDB_CODE_FILE_CORRUPTED;
×
138
      TAOS_RETURN(code);
×
139
    }
140
    if (i < SDB_MAX) {
9,408!
141
      pSdb->maxId[i] = maxId;
9,408✔
142
    }
143
  }
144

145
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
9,800✔
146
    int64_t ver = 0;
9,408✔
147
    ret = taosReadFile(pFile, &ver, sizeof(int64_t));
9,408✔
148
    if (ret < 0) {
9,408!
149
      return terrno;
×
150
    }
151
    if (ret != sizeof(int64_t)) {
9,408!
152
      code = TSDB_CODE_FILE_CORRUPTED;
×
153
      TAOS_RETURN(code);
×
154
    }
155
    if (i < SDB_MAX) {
9,408!
156
      pSdb->tableVer[i] = ver;
9,408✔
157
    }
158
  }
159

160
  // for sdb compatibility
161
  for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
2,352✔
162
    int64_t maxId = 0;
1,960✔
163
    ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
1,960✔
164
    if (ret < 0) {
1,960!
165
      code = TAOS_SYSTEM_ERROR(errno);
×
166
      TAOS_RETURN(code);
×
167
    }
168
    if (ret != sizeof(int64_t)) {
1,960!
169
      code = TSDB_CODE_FILE_CORRUPTED;
×
170
      TAOS_RETURN(code);
×
171
    }
172
    if (i < SDB_MAX) {
1,960!
173
      pSdb->maxId[i] = maxId;
1,960✔
174
    }
175

176
    int64_t ver = 0;
1,960✔
177
    ret = taosReadFile(pFile, &ver, sizeof(int64_t));
1,960✔
178
    if (ret < 0) {
1,960!
179
      code = TAOS_SYSTEM_ERROR(errno);
×
180
      TAOS_RETURN(code);
×
181
    }
182
    if (ret != sizeof(int64_t)) {
1,960!
183
      code = TSDB_CODE_FILE_CORRUPTED;
×
184
      TAOS_RETURN(code);
×
185
    }
186
    if (i < SDB_MAX) {
1,960!
187
      pSdb->tableVer[i] = ver;
1,960✔
188
    }
189
  }
190

191
  char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
392✔
192
  ret = taosReadFile(pFile, reserve, sizeof(reserve));
392✔
193
  if (ret < 0) {
392!
194
    return terrno;
×
195
  }
196
  if (ret != sizeof(reserve)) {
392!
197
    code = TSDB_CODE_FILE_CORRUPTED;
×
198
    TAOS_RETURN(code);
×
199
  }
200

201
  return 0;
392✔
202
}
203

204
static int32_t sdbWriteFileHead(SSdb *pSdb, TdFilePtr pFile) {
3,123✔
205
  int64_t sver = SDB_FILE_VER;
3,123✔
206
  if (taosWriteFile(pFile, &sver, sizeof(int64_t)) != sizeof(int64_t)) {
3,123!
207
    return terrno;
×
208
  }
209

210
  mInfo("vgId:1, write sdb file with sdb applyIndex:%" PRId64 " term:%" PRId64 " config:%" PRId64, pSdb->applyIndex,
3,123!
211
        pSdb->applyTerm, pSdb->applyConfig);
212
  if (taosWriteFile(pFile, &pSdb->applyIndex, sizeof(int64_t)) != sizeof(int64_t)) {
3,123!
213
    return terrno;
×
214
  }
215

216
  if (taosWriteFile(pFile, &pSdb->applyTerm, sizeof(int64_t)) != sizeof(int64_t)) {
3,123!
217
    return terrno;
×
218
  }
219

220
  if (taosWriteFile(pFile, &pSdb->applyConfig, sizeof(int64_t)) != sizeof(int64_t)) {
3,123!
221
    return terrno;
×
222
  }
223

224
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
78,075✔
225
    int64_t maxId = 0;
74,952✔
226
    if (i < SDB_MAX) {
74,952!
227
      maxId = pSdb->maxId[i];
74,952✔
228
    }
229
    if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
74,952!
230
      return terrno;
×
231
    }
232
  }
233

234
  for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
78,075✔
235
    int64_t ver = 0;
74,952✔
236
    if (i < SDB_MAX) {
74,952!
237
      ver = pSdb->tableVer[i];
74,952✔
238
    }
239
    if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
74,952!
240
      return terrno;
×
241
    }
242
  }
243

244
  // for sdb compatibility
245
  for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
18,738✔
246
    int64_t maxId = 0;
15,615✔
247
    if (i < SDB_MAX) {
15,615!
248
      maxId = pSdb->maxId[i];
15,615✔
249
    }
250
    if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
15,615!
251
      return terrno;
×
252
    }
253

254
    int64_t ver = 0;
15,615✔
255
    if (i < SDB_MAX) {
15,615!
256
      ver = pSdb->tableVer[i];
15,615✔
257
    }
258
    if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
15,615!
259
      return terrno;
×
260
    }
261
  }
262

263
  char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
3,123✔
264
  if (taosWriteFile(pFile, reserve, sizeof(reserve)) != sizeof(reserve)) {
3,123!
265
    return terrno;
×
266
  }
267

268
  return 0;
3,123✔
269
}
270

271
static int32_t sdbReadFileImp(SSdb *pSdb) {
484✔
272
  int64_t offset = 0;
484✔
273
  int32_t code = 0;
484✔
274
  int32_t readLen = 0;
484✔
275
  int64_t ret = 0;
484✔
276
  char    file[PATH_MAX] = {0};
484✔
277
  int32_t bufLen = TSDB_MAX_MSG_SIZE;
484✔
278

279
  snprintf(file, sizeof(file), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
484✔
280
  mInfo("start to read sdb file:%s", file);
484!
281

282
  SSdbRaw *pRaw = taosMemoryMalloc(bufLen + 100);
484✔
283
  if (pRaw == NULL) {
484!
284
    code = terrno;
×
285
    mError("failed read sdb file since %s", tstrerror(code));
×
286
    TAOS_RETURN(code);
×
287
  }
288

289
  TdFilePtr pFile = taosOpenFile(file, TD_FILE_READ);
484✔
290
  if (pFile == NULL) {
484✔
291
    taosMemoryFree(pRaw);
92✔
292
    code = terrno;
92✔
293
    mInfo("read sdb file:%s finished since %s", file, tstrerror(code));
92!
294
    return 0;
92✔
295
  }
296

297
  code = sdbReadFileHead(pSdb, pFile);
392✔
298
  if (code != 0) {
392!
299
    mError("failed to read sdb file:%s head since %s", file, tstrerror(code));
×
300
    taosMemoryFree(pRaw);
×
301
    int32_t ret = 0;
×
302
    if ((ret = taosCloseFile(&pFile)) != 0) {
×
303
      mError("failed to close sdb file:%s since %s", file, tstrerror(ret));
×
304
    }
305
    return code;
×
306
  }
307

308
  int64_t tableVer[SDB_MAX] = {0};
392✔
309
  memcpy(tableVer, pSdb->tableVer, sizeof(tableVer));
392✔
310

311
  while (1) {
6,287✔
312
    readLen = sizeof(SSdbRaw);
6,679✔
313
    ret = taosReadFile(pFile, pRaw, readLen);
6,679✔
314
    if (ret == 0) break;
6,679✔
315

316
    if (ret < 0) {
6,287!
317
      code = terrno;
×
318
      mError("failed to read sdb file:%s since %s", file, tstrerror(code));
×
319
      goto _OVER;
×
320
    }
321

322
    if (ret != readLen) {
6,287!
323
      code = TSDB_CODE_FILE_CORRUPTED;
×
324
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " != readLen:%d", file, tstrerror(code), ret, readLen);
×
325
      goto _OVER;
×
326
    }
327

328
    readLen = pRaw->dataLen + sizeof(int32_t);
6,287✔
329
    if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
6,287!
330
      readLen = ENCRYPTED_LEN(pRaw->dataLen) + sizeof(int32_t);
×
331
    }
332
    if (readLen >= bufLen) {
6,287!
333
      bufLen = pRaw->dataLen * 2;
×
334
      SSdbRaw *pNewRaw = taosMemoryMalloc(bufLen + 100);
×
335
      if (pNewRaw == NULL) {
×
336
        code = terrno;
×
337
        mError("failed read sdb file since malloc new sdbRaw size:%d failed", bufLen);
×
338
        goto _OVER;
×
339
      }
340
      mInfo("malloc new sdb raw size:%d, type:%d", bufLen, pRaw->type);
×
341
      memcpy(pNewRaw, pRaw, sizeof(SSdbRaw));
×
342
      sdbFreeRaw(pRaw);
×
343
      pRaw = pNewRaw;
×
344
    }
345

346
    ret = taosReadFile(pFile, pRaw->pData, readLen);
6,287✔
347
    if (ret < 0) {
6,287!
348
      code = terrno;
×
349
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " readLen:%d", file, tstrerror(code), ret, readLen);
×
350
      goto _OVER;
×
351
    }
352

353
    if (ret != readLen) {
6,287!
354
      code = TSDB_CODE_FILE_CORRUPTED;
×
355
      mError("failed to read sdb file:%s since %s, ret:%" PRId64 " != readLen:%d", file, tstrerror(code), ret, readLen);
×
356
      goto _OVER;
×
357
    }
358

359
    if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
6,287!
360
      int32_t count = 0;
×
361

362
      char *plantContent = taosMemoryMalloc(ENCRYPTED_LEN(pRaw->dataLen));
×
363
      if (plantContent == NULL) {
×
364
        code = terrno;
×
365
        goto _OVER;
×
366
      }
367

368
      SCryptOpts opts;
369
      opts.len = ENCRYPTED_LEN(pRaw->dataLen);
×
370
      opts.source = pRaw->pData;
×
371
      opts.result = plantContent;
×
372
      opts.unitLen = 16;
×
373
      strncpy(opts.key, tsEncryptKey, ENCRYPT_KEY_LEN);
×
374

375
      count = CBC_Decrypt(&opts);
×
376

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

379
      memcpy(pRaw->pData, plantContent, pRaw->dataLen);
×
380
      taosMemoryFree(plantContent);
×
381
      memcpy(pRaw->pData + pRaw->dataLen, &pRaw->pData[ENCRYPTED_LEN(pRaw->dataLen)], sizeof(int32_t));
×
382
    }
383

384
    int32_t totalLen = sizeof(SSdbRaw) + pRaw->dataLen + sizeof(int32_t);
6,287✔
385
    if ((!taosCheckChecksumWhole((const uint8_t *)pRaw, totalLen)) != 0) {
12,574!
386
      code = TSDB_CODE_CHECKSUM_ERROR;
×
387
      mError("failed to read sdb file:%s since %s, readLen:%d", file, tstrerror(code), readLen);
×
388
      goto _OVER;
×
389
    }
390

391
    if (pRaw->type >= SDB_MAX) {
6,287!
392
      mInfo("skip sdb raw type:%d since it is not supported", pRaw->type);
×
393
      continue;
×
394
    }
395

396
    code = sdbWriteWithoutFree(pSdb, pRaw);
6,287✔
397
    if (code != 0) {
6,287!
398
      mError("failed to read sdb file:%s since %s", file, terrstr());
×
399
      goto _OVER;
×
400
    }
401
  }
402

403
  code = 0;
392✔
404
  pSdb->commitIndex = pSdb->applyIndex;
392✔
405
  pSdb->commitTerm = pSdb->applyTerm;
392✔
406
  pSdb->commitConfig = pSdb->applyConfig;
392✔
407
  memcpy(pSdb->tableVer, tableVer, sizeof(tableVer));
392✔
408
  mInfo("vgId:1, trans:0, read sdb file:%s success, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64, file,
392!
409
        pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig);
410

411
_OVER:
×
412
  if ((ret = taosCloseFile(&pFile)) != 0) {
392!
413
    mError("failed to close sdb file:%s since %s", file, tstrerror(ret));
×
414
  }
415
  sdbFreeRaw(pRaw);
392✔
416

417
  TAOS_RETURN(code);
392✔
418
}
419

420
int32_t sdbReadFile(SSdb *pSdb) {
484✔
421
  (void)taosThreadMutexLock(&pSdb->filelock);
484✔
422

423
  sdbResetData(pSdb);
484✔
424
  int32_t code = sdbReadFileImp(pSdb);
484✔
425
  if (code != 0) {
484!
426
    mError("failed to read sdb file since %s", tstrerror(code));
×
427
    sdbResetData(pSdb);
×
428
  }
429

430
  (void)taosThreadMutexUnlock(&pSdb->filelock);
484✔
431
  return code;
484✔
432
}
433

434
static int32_t sdbWriteFileImp(SSdb *pSdb, int32_t skip_type) {
3,123✔
435
  int32_t code = 0;
3,123✔
436

437
  char tmpfile[PATH_MAX] = {0};
3,123✔
438
  snprintf(tmpfile, sizeof(tmpfile), "%s%ssdb.data", pSdb->tmpDir, TD_DIRSEP);
3,123✔
439
  char curfile[PATH_MAX] = {0};
3,123✔
440
  snprintf(curfile, sizeof(curfile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
3,123✔
441

442
  mInfo("start to write sdb file, apply index:%" PRId64 " term:%" PRId64 " config:%" PRId64 ", commit index:%" PRId64
3,123!
443
        " term:%" PRId64 " config:%" PRId64 ", file:%s",
444
        pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig, pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig,
445
        curfile);
446

447
  TdFilePtr pFile = taosOpenFile(tmpfile, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
3,123✔
448
  if (pFile == NULL) {
3,123!
449
    code = terrno;
×
450
    mError("failed to open sdb file:%s for write since %s", tmpfile, tstrerror(code));
×
451
    TAOS_RETURN(code);
×
452
  }
453

454
  code = sdbWriteFileHead(pSdb, pFile);
3,123✔
455
  if (code != 0) {
3,123!
456
    mError("failed to write sdb file:%s head since %s", tmpfile, tstrerror(code));
×
457
    int32_t ret = 0;
×
458
    if ((ret = taosCloseFile(&pFile)) != 0) {
×
459
      mError("failed to close sdb file:%s since %s", tmpfile, tstrerror(ret));
×
460
    }
461
    return code;
×
462
  }
463

464
  for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
93,690✔
465
    if (i == skip_type) continue;
90,567!
466
    SdbEncodeFp encodeFp = pSdb->encodeFps[i];
90,567✔
467
    if (encodeFp == NULL) continue;
90,567✔
468

469
    mInfo("write %s to sdb file, total %d rows", sdbTableName(i), sdbGetSize(pSdb, i));
78,075!
470

471
    SHashObj *hash = pSdb->hashObjs[i];
78,075✔
472
    sdbWriteLock(pSdb, i);
78,075✔
473

474
    SSdbRow **ppRow = taosHashIterate(hash, NULL);
78,075✔
475
    while (ppRow != NULL) {
134,666✔
476
      SSdbRow *pRow = *ppRow;
56,591✔
477
      if (pRow == NULL) {
56,591!
478
        ppRow = taosHashIterate(hash, ppRow);
×
479
        continue;
×
480
      }
481

482
      if (pRow->status != SDB_STATUS_READY && pRow->status != SDB_STATUS_DROPPING) {
56,591✔
483
        sdbPrintOper(pSdb, pRow, "not-write");
289✔
484
        ppRow = taosHashIterate(hash, ppRow);
289✔
485
        continue;
289✔
486
      }
487

488
      sdbPrintOper(pSdb, pRow, "write");
56,302✔
489

490
      SSdbRaw *pRaw = (*encodeFp)(pRow->pObj);
56,302✔
491
      if (pRaw != NULL) {
56,302!
492
        pRaw->status = pRow->status;
56,302✔
493

494
        if (taosWriteFile(pFile, pRaw, sizeof(SSdbRaw)) != sizeof(SSdbRaw)) {
56,302!
495
          code = terrno;
×
496
          taosHashCancelIterate(hash, ppRow);
×
497
          sdbFreeRaw(pRaw);
×
498
          break;
×
499
        }
500

501
        int32_t newDataLen = pRaw->dataLen;
56,302✔
502
        char   *newData = pRaw->pData;
56,302✔
503
        if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
56,302!
504
          newDataLen = ENCRYPTED_LEN(pRaw->dataLen);
×
505
          newData = taosMemoryMalloc(newDataLen);
×
506
          if (newData == NULL) {
×
507
            code = terrno;
×
508
            taosHashCancelIterate(hash, ppRow);
×
509
            sdbFreeRaw(pRaw);
×
510
            break;
×
511
          }
512

513
          SCryptOpts opts;
514
          opts.len = newDataLen;
×
515
          opts.source = pRaw->pData;
×
516
          opts.result = newData;
×
517
          opts.unitLen = 16;
×
518
          strncpy(opts.key, tsEncryptKey, ENCRYPT_KEY_LEN);
×
519

520
          int32_t count = CBC_Encrypt(&opts);
×
521

522
          // mDebug("write sdb, CBC_Encrypt encryptedDataLen:%d, dataLen:%d, %s",
523
          //       newDataLen, pRaw->dataLen, __FUNCTION__);
524
        }
525

526
        if (taosWriteFile(pFile, newData, newDataLen) != newDataLen) {
56,302!
527
          code = terrno;
×
528
          taosHashCancelIterate(hash, ppRow);
×
529
          sdbFreeRaw(pRaw);
×
530
          break;
×
531
        }
532

533
        if (tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_SDB) == DND_CS_SDB) {
56,302!
534
          taosMemoryFree(newData);
×
535
        }
536

537
        int32_t cksum = taosCalcChecksum(0, (const uint8_t *)pRaw, sizeof(SSdbRaw) + pRaw->dataLen);
56,302✔
538
        if (taosWriteFile(pFile, &cksum, sizeof(int32_t)) != sizeof(int32_t)) {
56,302!
539
          code = errno;
×
540
          taosHashCancelIterate(hash, ppRow);
×
541
          sdbFreeRaw(pRaw);
×
542
          break;
×
543
        }
544
      } else {
545
        code = TSDB_CODE_APP_ERROR;
×
546
        taosHashCancelIterate(hash, ppRow);
×
547
        break;
×
548
      }
549

550
      sdbFreeRaw(pRaw);
56,302✔
551
      ppRow = taosHashIterate(hash, ppRow);
56,302✔
552
    }
553
    sdbUnLock(pSdb, i);
78,075✔
554
  }
555

556
  if (code == 0) {
3,123!
557
    code = taosFsyncFile(pFile);
3,123✔
558
    if (code != 0) {
3,123!
559
      code = TAOS_SYSTEM_ERROR(errno);
×
560
      mError("failed to sync sdb file:%s since %s", tmpfile, tstrerror(code));
×
561
    }
562
  }
563

564
  if (taosCloseFile(&pFile) != 0) {
3,123!
565
    code = taosRenameFile(tmpfile, curfile);
×
566
  }
567

568
  if (code == 0) {
3,123!
569
    code = taosRenameFile(tmpfile, curfile);
3,123✔
570
    if (code != 0) {
3,123!
571
      mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
×
572
    }
573
  }
574

575
  if (code != 0) {
3,123!
576
    mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
×
577
  } else {
578
    pSdb->commitIndex = pSdb->applyIndex;
3,123✔
579
    pSdb->commitTerm = pSdb->applyTerm;
3,123✔
580
    pSdb->commitConfig = pSdb->applyConfig;
3,123✔
581
    mInfo("vgId:1, trans:0, write sdb file success, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64
3,123!
582
          " file:%s",
583
          pSdb->commitIndex, pSdb->commitTerm, pSdb->commitConfig, curfile);
584
  }
585

586
  terrno = code;
3,123✔
587
  return code;
3,123✔
588
}
589

590
int32_t sdbWriteFile(SSdb *pSdb, int32_t delta) {
98,142✔
591
  int32_t code = 0;
98,142✔
592
  if (pSdb->applyIndex == pSdb->commitIndex) {
98,142✔
593
    return 0;
1,985✔
594
  }
595

596
  if (pSdb->applyIndex - pSdb->commitIndex < delta) {
96,157✔
597
    return 0;
93,024✔
598
  }
599

600
  (void)taosThreadMutexLock(&pSdb->filelock);
3,133✔
601
  if (pSdb->pWal != NULL) {
3,133!
602
    if (pSdb->sync > 0) {
3,133!
603
      code = syncBeginSnapshot(pSdb->sync, pSdb->applyIndex);
3,133✔
604
    }
605
  }
606
  if (code == 0) {
3,133✔
607
    code = sdbWriteFileImp(pSdb, -1);
3,123✔
608
  }
609
  if (code == 0) {
3,133✔
610
    if (pSdb->pWal != NULL) {
3,123!
611
      if (pSdb->sync > 0) {
3,123!
612
        code = syncEndSnapshot(pSdb->sync);
3,123✔
613
      }
614
    }
615
  }
616
  if (code != 0) {
3,133✔
617
    mError("failed to write sdb file since %s", tstrerror(code));
10!
618
  } else {
619
    mInfo("vgId:1, trans:0, write sdb file success, apply index:%" PRId64 ", term:%" PRId64 ", config:%" PRId64,
3,123!
620
          pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig);
621
  }
622
  (void)taosThreadMutexUnlock(&pSdb->filelock);
3,133✔
623
  return code;
3,133✔
624
}
625

626
int32_t sdbWriteFileForDump(SSdb *pSdb) {
×
627
  int32_t code = 0;
×
628

629
  code = sdbWriteFileImp(pSdb, 0);
×
630

631
  return code;
×
632
}
633

634
int32_t sdbDeploy(SSdb *pSdb) {
1,330✔
635
  int32_t code = 0;
1,330✔
636
  code = sdbDeployData(pSdb);
1,330✔
637
  if (code != 0) {
1,330!
638
    TAOS_RETURN(code);
×
639
  }
640

641
  code = sdbWriteFile(pSdb, 0);
1,330✔
642
  if (code != 0) {
1,330!
643
    TAOS_RETURN(code);
×
644
  }
645

646
  return 0;
1,330✔
647
}
648

649
static SSdbIter *sdbCreateIter(SSdb *pSdb) {
×
650
  SSdbIter *pIter = taosMemoryCalloc(1, sizeof(SSdbIter));
×
651
  if (pIter == NULL) {
×
652
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
653
    return NULL;
×
654
  }
655

656
  char name[PATH_MAX + 100] = {0};
×
657
  snprintf(name, sizeof(name), "%s%ssdb.data.%" PRIu64, pSdb->tmpDir, TD_DIRSEP, (uint64_t)pIter);
×
658
  pIter->name = taosStrdup(name);
×
659
  if (pIter->name == NULL) {
×
660
    taosMemoryFree(pIter);
×
661
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
662
    return NULL;
×
663
  }
664

665
  return pIter;
×
666
}
667

668
static void sdbCloseIter(SSdbIter *pIter) {
×
669
  if (pIter == NULL) return;
×
670

671
  if (pIter->file != NULL) {
×
672
    int32_t ret = 0;
×
673
    if ((ret = taosCloseFile(&pIter->file)) != 0) {
×
674
      mError("failed to close sdb file since %s", tstrerror(ret));
×
675
    }
676
    pIter->file = NULL;
×
677
  }
678

679
  if (pIter->name != NULL) {
×
680
    int32_t ret = 0;
×
681
    if ((ret = taosRemoveFile(pIter->name)) != 0) {
×
682
      mError("failed to remove sdb file:%s since %s", pIter->name, tstrerror(ret));
×
683
    }
684
    taosMemoryFree(pIter->name);
×
685
    pIter->name = NULL;
×
686
  }
687

688
  mInfo("sdbiter:%p, is closed, total:%" PRId64, pIter, pIter->total);
×
689
  taosMemoryFree(pIter);
×
690
}
691

692
int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter, int64_t *index, int64_t *term, int64_t *config) {
×
693
  int32_t   code = 0;
×
694
  SSdbIter *pIter = sdbCreateIter(pSdb);
×
695
  if (pIter == NULL) return -1;
×
696

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

700
  (void)taosThreadMutexLock(&pSdb->filelock);
×
701
  int64_t commitIndex = pSdb->commitIndex;
×
702
  int64_t commitTerm = pSdb->commitTerm;
×
703
  int64_t commitConfig = pSdb->commitConfig;
×
704
  if (taosCopyFile(datafile, pIter->name) < 0) {
×
705
    code = terrno;
×
706
    (void)taosThreadMutexUnlock(&pSdb->filelock);
×
707
    mError("failed to copy sdb file %s to %s since %s", datafile, pIter->name, tstrerror(code));
×
708
    sdbCloseIter(pIter);
×
709
    TAOS_RETURN(code);
×
710
  }
711
  (void)taosThreadMutexUnlock(&pSdb->filelock);
×
712

713
  pIter->file = taosOpenFile(pIter->name, TD_FILE_READ);
×
714
  if (pIter->file == NULL) {
×
715
    code = terrno;
×
716
    mError("failed to open sdb file:%s since %s", pIter->name, tstrerror(code));
×
717
    sdbCloseIter(pIter);
×
718
    TAOS_RETURN(code);
×
719
  }
720

721
  *ppIter = pIter;
×
722
  if (index != NULL) *index = commitIndex;
×
723
  if (term != NULL) *term = commitTerm;
×
724
  if (config != NULL) *config = commitConfig;
×
725

726
  mInfo("sdbiter:%p, is created to read snapshot, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64 " file:%s",
×
727
        pIter, commitIndex, commitTerm, commitConfig, pIter->name);
728
  return 0;
×
729
}
730

731
void sdbStopRead(SSdb *pSdb, SSdbIter *pIter) { sdbCloseIter(pIter); }
×
732

733
int32_t sdbDoRead(SSdb *pSdb, SSdbIter *pIter, void **ppBuf, int32_t *len) {
×
734
  int32_t code = 0;
×
735
  int32_t maxlen = 4096;
×
736
  void   *pBuf = taosMemoryCalloc(1, maxlen);
×
737
  if (pBuf == NULL) {
×
738
    code = terrno;
×
739
    TAOS_RETURN(code);
×
740
  }
741

742
  int32_t readlen = taosReadFile(pIter->file, pBuf, maxlen);
×
743
  if (readlen < 0 || readlen > maxlen) {
×
744
    code = terrno;
×
745
    mError("sdbiter:%p, failed to read snapshot since %s, total:%" PRId64, pIter, tstrerror(code), pIter->total);
×
746
    *ppBuf = NULL;
×
747
    *len = 0;
×
748
    taosMemoryFree(pBuf);
×
749
    TAOS_RETURN(code);
×
750
  } else if (readlen == 0) {
×
751
    mInfo("sdbiter:%p, read snapshot to the end, total:%" PRId64, pIter, pIter->total);
×
752
    *ppBuf = NULL;
×
753
    *len = 0;
×
754
    taosMemoryFree(pBuf);
×
755
    return 0;
×
756
  } else {  // (readlen <= maxlen)
757
    pIter->total += readlen;
×
758
    mInfo("sdbiter:%p, read:%d bytes from snapshot, total:%" PRId64, pIter, readlen, pIter->total);
×
759
    *ppBuf = pBuf;
×
760
    *len = readlen;
×
761
    return 0;
×
762
  }
763
}
764

765
int32_t sdbStartWrite(SSdb *pSdb, SSdbIter **ppIter) {
×
766
  int32_t   code = 0;
×
767
  SSdbIter *pIter = sdbCreateIter(pSdb);
×
768
  if (pIter == NULL) {
×
769
    code = terrno;
×
770
    TAOS_RETURN(code);
×
771
  }
772

773
  pIter->file = taosOpenFile(pIter->name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
×
774
  if (pIter->file == NULL) {
×
775
    code = terrno;
×
776
    mError("failed to open %s since %s", pIter->name, tstrerror(code));
×
777
    sdbCloseIter(pIter);
×
778
    TAOS_RETURN(code);
×
779
  }
780

781
  *ppIter = pIter;
×
782
  mInfo("sdbiter:%p, is created to write snapshot, file:%s", pIter, pIter->name);
×
783
  return 0;
×
784
}
785

786
int32_t sdbStopWrite(SSdb *pSdb, SSdbIter *pIter, bool isApply, int64_t index, int64_t term, int64_t config) {
×
787
  int32_t code = -1;
×
788

789
  if (!isApply) {
×
790
    mInfo("sdbiter:%p, not apply to sdb", pIter);
×
791
    code = 0;
×
792
    goto _OVER;
×
793
  }
794

795
  if (taosFsyncFile(pIter->file) != 0) {
×
796
    code = TAOS_SYSTEM_ERROR(errno);
×
797
    mError("sdbiter:%p, failed to fasync file %s since %s", pIter, pIter->name, tstrerror(code));
×
798
    goto _OVER;
×
799
  }
800

801
  if (taosCloseFile(&pIter->file) != 0) {
×
802
    code = TAOS_SYSTEM_ERROR(errno);
×
803
    goto _OVER;
×
804
  }
805
  pIter->file = NULL;
×
806

807
  char datafile[PATH_MAX] = {0};
×
808
  snprintf(datafile, sizeof(datafile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
×
809
  code = taosRenameFile(pIter->name, datafile);
×
810
  if (code != 0) {
×
811
    mError("sdbiter:%p, failed to rename file %s to %s since %s", pIter, pIter->name, datafile, tstrerror(code));
×
812
    goto _OVER;
×
813
  }
814

815
  code = sdbReadFile(pSdb);
×
816
  if (code != 0) {
×
817
    mError("sdbiter:%p, failed to read from %s since %s", pIter, datafile, tstrerror(code));
×
818
    goto _OVER;
×
819
  }
820

821
  if (config > 0) {
×
822
    pSdb->commitConfig = config;
×
823
  }
824
  if (term > 0) {
×
825
    pSdb->commitTerm = term;
×
826
  }
827
  if (index > 0) {
×
828
    pSdb->commitIndex = index;
×
829
  }
830

831
  mInfo("sdbiter:%p, success applyed to sdb", pIter);
×
832
  code = 0;
×
833

834
_OVER:
×
835
  sdbCloseIter(pIter);
×
836
  return code;
×
837
}
838

839
int32_t sdbDoWrite(SSdb *pSdb, SSdbIter *pIter, void *pBuf, int32_t len) {
×
840
  int32_t code = 0;
×
841
  int32_t writelen = taosWriteFile(pIter->file, pBuf, len);
×
842
  if (writelen != len) {
×
843
    code = terrno;
×
844
    mError("failed to write len:%d since %s, total:%" PRId64, len, tstrerror(code), pIter->total);
×
845
    TAOS_RETURN(code);
×
846
  }
847

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