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

taosdata / TDengine / #4991

17 Mar 2026 07:57AM UTC coverage: 69.756% (+0.4%) from 69.348%
#4991

push

travis-ci

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

14 of 16 new or added lines in 5 files covered. (87.5%)

3928 existing lines in 138 files now uncovered.

192146 of 275455 relevant lines covered (69.76%)

137208686.18 hits per line

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

49.91
/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#include "crypt.h"
17
#include "tss.h"
18
#include "tsdb.h"
19
#include "tsdbDef.h"
20
#include "vnd.h"
21

22
static int32_t tsdbOpenFileImpl(STsdbFD *pFD) {
384,835,023✔
23
  int32_t     code = 0;
384,835,023✔
24
  int32_t     lino;
25
  const char *path = pFD->path;
384,835,023✔
26
  int32_t     szPage = pFD->szPage;
385,327,923✔
27
  int32_t     flag = pFD->flag;
385,429,948✔
28
  int64_t     lc_size = 0;
385,365,403✔
29

30
  pFD->pFD = taosOpenFile(path, flag);
385,436,685✔
31
  if (pFD->pFD == NULL) {
385,657,976✔
32
    if (TD_FILE_READ == flag) {
2,984✔
33
      int32_t expired = grantCheck(TSDB_GRANT_SHARED_STORAGE);
2,984✔
34
      if (expired && tsSsEnabled) {
2,984✔
35
        tsdbWarn("s3 grant expired: %d", expired);
×
36
        tsSsEnabled = false;
×
37
      } else if (!expired && tsSsEnabled) {
2,984✔
38
        tsSsEnabled = true;
2,984✔
39
      }
40
    }
41

42
    if (tsSsEnabled && pFD->lcn > 1 && !strncmp(path + strlen(path) - 5, ".data", 5)) {
5,968✔
43
      char lc_path[TSDB_FILENAME_LEN];
2,984✔
44
      tstrncpy(lc_path, path, TSDB_FQDN_LEN);
2,984✔
45

46
      int32_t     vid = 0;
2,984✔
47
      const char *object_name = taosDirEntryBaseName((char *)path);
2,984✔
48
      (void)sscanf(object_name, "v%df%dver%" PRId64, &vid, &pFD->fid, &pFD->cid);
2,984✔
49

50
      char *dot = strrchr(lc_path, '.');
2,984✔
51
      if (!dot) {
2,984✔
52
        tsdbError("unexpected path: %s", lc_path);
×
53
        TSDB_CHECK_CODE(code = TAOS_SYSTEM_ERROR(ENOENT), lino, _exit);
×
54
      }
55
      snprintf(dot + 1, TSDB_FQDN_LEN - (dot + 1 - lc_path), "%d.data", pFD->lcn);
2,984✔
56

57
      pFD->pFD = taosOpenFile(lc_path, flag);
2,984✔
58
      if (pFD->pFD == NULL) {
2,984✔
59
        TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
60
      }
61
      if (taosStatFile(lc_path, &lc_size, NULL, NULL) < 0) {
2,984✔
62
        TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
63
      }
64
    } else {
65
      tsdbInfo("no file: %s", path);
×
66
      TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
67
    }
68
    pFD->ssFile = 1;
2,984✔
69
  }
70

71
  pFD->pBuf = taosMemoryCalloc(1, szPage);
385,672,546✔
72
  if (pFD->pBuf == NULL) {
385,465,004✔
73
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
74
  }
75

76
  if (lc_size > 0) {
385,505,817✔
77
    SVnodeCfg *pCfg = &pFD->pTsdb->pVnode->config;
2,984✔
78
    int64_t    chunksize = (int64_t)pCfg->tsdbPageSize * pCfg->ssChunkSize;
2,984✔
79

80
    pFD->szFile = lc_size + chunksize * (pFD->lcn - 1);
2,984✔
81
  }
82

83
  // not check file size when reading data files.
84
  if (flag != TD_FILE_READ /* && !pFD->s3File*/) {
385,505,817✔
85
    if (!lc_size && taosStatFile(path, &pFD->szFile, NULL, NULL) < 0) {
19,958,974✔
86
      TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
87
    }
88
  }
89

90
  if (pFD->szFile % szPage != 0) {
385,485,171✔
91
    TSDB_CHECK_CODE(code = TSDB_CODE_INVALID_PARA, lino, _exit);
×
92
  }
93
  pFD->szFile = pFD->szFile / szPage;
385,455,064✔
94

95
_exit:
385,686,232✔
96
  if (code) {
385,618,426✔
97
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
98
  }
99
  return code;
385,618,441✔
100
}
101

102
// =============== PAGE-WISE FILE ===============
103
int32_t tsdbOpenFile(const char *path, STsdb *pTsdb, int32_t flag, STsdbFD **ppFD, int32_t lcn) {
413,905,245✔
104
  int32_t  code = 0;
413,905,245✔
105
  int32_t  lino;
106
  STsdbFD *pFD = NULL;
413,905,245✔
107
  int32_t  szPage = pTsdb->pVnode->config.tsdbPageSize;
413,905,245✔
108

109
  *ppFD = NULL;
414,147,840✔
110

111
  pFD = (STsdbFD *)taosMemoryCalloc(1, sizeof(*pFD) + strlen(path) + 1);
414,071,060✔
112
  if (pFD == NULL) {
412,678,687✔
113
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
114
  }
115

116
  pFD->path = (char *)&pFD[1];
412,678,687✔
117
  memcpy(pFD->path, path, strlen(path) + 1);
412,795,866✔
118
  pFD->szPage = szPage;
414,134,565✔
119
  pFD->flag = flag;
414,182,042✔
120
  pFD->szPage = szPage;
414,158,350✔
121
  pFD->pgno = 0;
414,094,913✔
122
  pFD->lcn = lcn;
413,992,564✔
123
  pFD->pTsdb = pTsdb;
413,738,527✔
124

125
  *ppFD = pFD;
414,060,813✔
126

127
_exit:
413,762,509✔
128
  if (code) {
413,762,509✔
129
    TSDB_ERROR_LOG(TD_VID(pTsdb->pVnode), lino, code);
×
130
  }
131
  return code;
413,620,277✔
132
}
133

134
void tsdbCloseFile(STsdbFD **ppFD) {
414,061,014✔
135
  STsdbFD *pFD = *ppFD;
414,061,014✔
136
  if (pFD) {
414,134,003✔
137
    taosMemoryFree(pFD->pBuf);
414,198,960✔
138
    int32_t code = taosCloseFile(&pFD->pFD);
414,155,164✔
139
    if (code) {
413,881,079✔
140
      tsdbError("failed to close file: %s, code:%d reason:%s", pFD->path, code, tstrerror(code));
×
141
    } else {
142
      tsdbTrace("close file: %s", pFD->path);
413,881,079✔
143
    }
144
    taosMemoryFree(pFD);
413,795,899✔
145
    *ppFD = NULL;
414,106,757✔
146
  }
147
}
414,037,054✔
148

149
static int32_t tsdbWriteFilePage(STsdbFD *pFD, SEncryptData *encryptData) {
557,589,581✔
150
  int32_t code = 0;
557,589,581✔
151
  int32_t lino;
152

153
  if (!pFD->pFD) {
557,589,581✔
154
    code = tsdbOpenFileImpl(pFD);
19,945,813✔
155
    TSDB_CHECK_CODE(code, lino, _exit);
19,930,579✔
156
  }
157

158
  if (pFD->pgno > 0) {
557,592,330✔
159
    int64_t offset = PAGE_OFFSET(pFD->pgno, pFD->szPage);
537,688,936✔
160
    if (pFD->ssFile && pFD->lcn > 1) {
537,689,390✔
161
      SVnodeCfg *pCfg = &pFD->pTsdb->pVnode->config;
×
162
      int64_t    chunksize = (int64_t)pCfg->tsdbPageSize * pCfg->ssChunkSize;
×
163
      int64_t    chunkoffset = chunksize * (pFD->lcn - 1);
×
164

165
      offset -= chunkoffset;
×
166
    }
167

168
    int64_t n = taosLSeekFile(pFD->pFD, offset, SEEK_SET);
537,687,265✔
169
    if (n < 0) {
537,686,895✔
170
      TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
171
    }
172

173
    code = taosCalcChecksumAppend(0, pFD->pBuf, pFD->szPage);
537,686,925✔
174
    TSDB_CHECK_CODE(code, lino, _exit);
537,719,868✔
175

176
    if (encryptData != NULL && encryptData->encryptAlgrName[0] != '\0') {
537,719,868✔
177
      // if(tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_TSDB) == DND_CS_TSDB){
178
      unsigned char PacketData[128];
3,225✔
179
      int           newLen = 0;
3,225✔
180
      int32_t       count = 0;
3,225✔
181
      while (count < pFD->szPage) {
106,425✔
182
        SCryptOpts opts = {0};
103,200✔
183
        opts.len = 128;
103,200✔
184
        opts.source = pFD->pBuf + count;
103,200✔
185
        opts.result = PacketData;
103,200✔
186
        opts.unitLen = 128;
103,200✔
187
        opts.pOsslAlgrName = encryptData->encryptAlgrName;
103,200✔
188
        tstrncpy(opts.key, encryptData->encryptKey, ENCRYPT_KEY_LEN + 1);
103,200✔
189

190
        newLen = CBC_Encrypt(&opts);
103,200✔
191
        if (newLen != opts.len) TSDB_CHECK_CODE(code = terrno, lino, _exit);
103,200✔
192

193
        memcpy(pFD->pBuf + count, PacketData, newLen);
103,200✔
194
        count += newLen;
103,200✔
195
      }
196
      // tsdbDebug("CBC Encrypt count:%d %s", count, __FUNCTION__);
197
    }
198

199
    n = taosWriteFile(pFD->pFD, pFD->pBuf, pFD->szPage);
537,710,636✔
200
    if (n < 0) {
537,682,372✔
201
      TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
202
    }
203

204
    if (pFD->szFile < pFD->pgno) {
537,682,372✔
205
      pFD->szFile = pFD->pgno;
537,220,325✔
206
    }
207
  }
208
  pFD->pgno = 0;
557,652,243✔
209

210
_exit:
557,666,215✔
211
  if (code) {
557,666,215✔
212
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
213
  }
214
  return code;
557,620,883✔
215
}
216

217
static int32_t tsdbReadFilePage(STsdbFD *pFD, int64_t pgno, SEncryptData *encryptData) {
1,306,432,246✔
218
  int32_t code = 0;
1,306,432,246✔
219
  int32_t lino;
220

221
  if (!pFD->pFD) {
1,306,432,246✔
222
    code = tsdbOpenFileImpl(pFD);
×
223
    TSDB_CHECK_CODE(code, lino, _exit);
×
224
  }
225

226
  int64_t offset = PAGE_OFFSET(pgno, pFD->szPage);
1,306,918,944✔
227
  if (pFD->lcn > 1) {
1,306,812,003✔
228
    SVnodeCfg *pCfg = &pFD->pTsdb->pVnode->config;
×
229
    int64_t    chunksize = (int64_t)pCfg->tsdbPageSize * pCfg->ssChunkSize;
×
230
    int64_t    chunkoffset = chunksize * (pFD->lcn - 1);
×
231

232
    offset -= chunkoffset;
×
233
  }
234

235
  // seek
236
  int64_t n = taosLSeekFile(pFD->pFD, offset, SEEK_SET);
1,306,877,621✔
237
  if (n < 0) {
1,306,966,891✔
238
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
239
  }
240

241
  // read
242
  n = taosReadFile(pFD->pFD, pFD->pBuf, pFD->szPage);
1,306,966,891✔
243
  if (n < 0) {
1,307,000,227✔
244
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
245
  } else if (n < pFD->szPage) {
1,307,000,227✔
246
    tsdbError(
×
247
        "vgId:%d %s failed at %s:%d since read file size is less than page size, "
248
        "read size: %" PRId64 ", page size: %d, fname:%s, pgno:%" PRId64,
249
        TD_VID(pFD->pTsdb->pVnode), __func__, __FILE__, __LINE__, n, pFD->szPage, pFD->path, pFD->pgno);
250
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
251
  }
252
  //}
253

254
  if (encryptData != NULL && encryptData->encryptAlgrName[0] != '\0') {
1,307,344,059✔
255
    // if(tsiEncryptAlgorithm == DND_CA_SM4 && (tsiEncryptScope & DND_CS_TSDB) == DND_CS_TSDB){
256
    unsigned char PacketData[128];
×
257
    int           newLen = 0;
×
258

259
    int32_t count = 0;
×
260
    while (count < pFD->szPage) {
×
261
      SCryptOpts opts = {0};
×
262
      opts.len = 128;
×
263
      opts.source = pFD->pBuf + count;
×
264
      opts.result = PacketData;
×
265
      opts.unitLen = 128;
×
266
      opts.pOsslAlgrName = encryptData->encryptAlgrName;
×
267
      tstrncpy(opts.key, encryptData->encryptKey, ENCRYPT_KEY_LEN + 1);
×
268

269
      newLen = CBC_Decrypt(&opts);
×
270
      if (newLen != opts.len) TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
271

272
      memcpy(pFD->pBuf + count, PacketData, newLen);
×
273
      count += newLen;
×
274
    }
275
    // tsdbDebug("CBC Decrypt count:%d %s", count, __FUNCTION__);
276
  }
277

278
  // check
279
  if (pgno > 1 && !taosCheckChecksumWhole(pFD->pBuf, pFD->szPage)) {
2,147,483,647✔
280
    tsdbError("vgId:%d %s failed at %s:%d since checksum mismatch, fname:%s, pgno:%" PRId64, TD_VID(pFD->pTsdb->pVnode),
×
281
              __func__, __FILE__, __LINE__, pFD->path, pgno);
282
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
283
  }
284

285
  pFD->pgno = pgno;
1,307,148,084✔
286

287
_exit:
1,307,703,471✔
288
  if (code) {
1,307,703,471✔
289
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
290
  }
291
  return code;
1,307,024,635✔
292
}
293

294
int32_t tsdbWriteFile(STsdbFD *pFD, int64_t offset, const uint8_t *pBuf, int64_t size, SEncryptData *encryptData) {
515,446,177✔
295
  int32_t code = 0;
515,446,177✔
296
  int32_t lino;
297
  int64_t fOffset = LOGIC_TO_FILE_OFFSET(offset, pFD->szPage);
515,446,177✔
298
  int64_t pgno = OFFSET_PGNO(fOffset, pFD->szPage);
515,636,456✔
299
  int64_t bOffset = fOffset % pFD->szPage;
515,654,434✔
300
  int64_t n = 0;
515,654,268✔
301

302
  do {
303
    if (pFD->pgno != pgno) {
1,033,485,166✔
304
      code = tsdbWriteFilePage(pFD, encryptData);
537,666,192✔
305
      TSDB_CHECK_CODE(code, lino, _exit);
537,638,197✔
306

307
      if (pgno <= pFD->szFile) {
537,638,197✔
308
        code = tsdbReadFilePage(pFD, pgno, encryptData);
474,134✔
309
        TSDB_CHECK_CODE(code, lino, _exit);
474,134✔
310
      } else {
311
        pFD->pgno = pgno;
537,173,378✔
312
      }
313
    }
314

315
    int64_t nWrite = TMIN(PAGE_CONTENT_SIZE(pFD->szPage) - bOffset, size - n);
1,033,235,782✔
316
    memcpy(pFD->pBuf + bOffset, pBuf + n, nWrite);
1,033,262,220✔
317

318
    pgno++;
1,033,270,632✔
319
    bOffset = 0;
1,033,270,632✔
320
    n += nWrite;
1,033,270,632✔
321
  } while (n < size);
1,033,270,632✔
322

323
_exit:
515,439,734✔
324
  if (code) {
515,439,734✔
325
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
326
  }
327
  return code;
515,431,350✔
328
}
329

330
static int32_t tsdbReadFileImp(STsdbFD *pFD, int64_t offset, uint8_t *pBuf, int64_t size, SEncryptData *encryptData) {
2,147,483,647✔
331
  int32_t code = 0;
2,147,483,647✔
332
  int32_t lino;
333
  int64_t n = 0;
2,147,483,647✔
334
  int64_t fOffset = LOGIC_TO_FILE_OFFSET(offset, pFD->szPage);
2,147,483,647✔
335
  int64_t pgno = OFFSET_PGNO(fOffset, pFD->szPage);
2,147,483,647✔
336
  int32_t szPgCont = PAGE_CONTENT_SIZE(pFD->szPage);
2,147,483,647✔
337
  int64_t bOffset = fOffset % pFD->szPage;
2,147,483,647✔
338

339
  if (bOffset >= szPgCont) {
2,147,483,647✔
340
    TSDB_CHECK_CODE(code = TSDB_CODE_INVALID_PARA, lino, _exit);
×
341
  }
342

343
  while (n < size) {
2,147,483,647✔
344
    if (pFD->pgno != pgno) {
2,147,483,647✔
345
      code = tsdbReadFilePage(pFD, pgno, encryptData);
1,306,439,143✔
346
      TSDB_CHECK_CODE(code, lino, _exit);
1,306,518,849✔
347
    }
348

349
    int64_t nRead = TMIN(szPgCont - bOffset, size - n);
2,147,483,647✔
350
    memcpy(pBuf + n, pFD->pBuf + bOffset, nRead);
2,147,483,647✔
351

352
    n += nRead;
2,147,483,647✔
353
    pgno++;
2,147,483,647✔
354
    bOffset = 0;
2,147,483,647✔
355
  }
356

357
_exit:
2,147,483,647✔
358
  if (code) {
2,147,483,647✔
359
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
360
  }
361
  return code;
2,147,483,647✔
362
}
363

364
#ifdef USE_SHARED_STORAGE
365
static int32_t tsdbReadFileBlock(STsdbFD *pFD, int64_t offset, int64_t size, uint8_t **ppBlock) {
4,476✔
366
  int32_t code = 0, lino, vid = TD_VID(pFD->pTsdb->pVnode);
4,476✔
367

368
  char* buf = taosMemoryCalloc(1, size);
4,476✔
369
  if (buf == NULL) {
4,476✔
370
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
371
  }
372

373
  SVnodeCfg *pCfg = &pFD->pTsdb->pVnode->config;
4,476✔
374
  int64_t szChunk = (int64_t)pCfg->tsdbPageSize * pCfg->ssChunkSize;
4,476✔
375

376
  for (int64_t n = 0, nRead = 0; n < size; n += nRead, offset += nRead) {
10,444✔
377
    int chunk = offset / szChunk + 1;
5,968✔
378

379
    if (chunk >= pFD->lcn) {
5,968✔
380
      if (taosLSeekFile(pFD->pFD, offset - szChunk * (pFD->lcn - 1), SEEK_SET) < 0) {
1,492✔
381
        TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
382
      }
383

384
      int64_t toRead = size - n;
1,492✔
385
      nRead = taosReadFile(pFD->pFD, buf + n, toRead);
1,492✔
386
      if (nRead < 0) {
1,492✔
387
        TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
388
      } else if (nRead < toRead) {
1,492✔
389
        TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
390
      }
391
    } else if (tsSsEnabled) {
4,476✔
392
      int64_t toRead = TMIN(szChunk - offset % szChunk, size - n);
4,476✔
393
      nRead = toRead;
4,476✔
394

395
      char path[TSDB_FILENAME_LEN];
4,476✔
396
      snprintf(path, sizeof(path), "vnode%d/f%d/v%df%dver%" PRId64 ".%d.data", vid, pFD->fid, vid, pFD->fid, pFD->cid,
4,476✔
397
               chunk);
398

399
      code = tssReadFileFromDefault(path, offset % szChunk, buf + n, &nRead);
4,476✔
400
      TSDB_CHECK_CODE(code, lino, _exit);
4,476✔
401
      if (nRead < toRead) {
4,476✔
UNCOV
402
        TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
403
      }
404
    } else {
UNCOV
405
      TSDB_CHECK_CODE(code = TSDB_CODE_OPS_NOT_SUPPORT, lino, _exit);
×
406
    }
407
  }
408

409
_exit:
4,476✔
410
  if (code) {
4,476✔
411
    TSDB_ERROR_LOG(vid, lino, code);
×
UNCOV
412
    taosMemoryFree(buf);
×
413
  } else {
414
    *ppBlock = (uint8_t *)buf;
4,476✔
415
  }
416
  return code;
4,476✔
417
}
418
#endif
419

420

421

422
static int32_t tsdbReadFileSs(STsdbFD *pFD, int64_t offset, uint8_t *pBuf, int64_t size, int64_t szHint) {
11,936✔
423
#ifdef USE_SHARED_STORAGE
424
  int32_t code = 0;
11,936✔
425
  int32_t lino;
426
  int64_t n = 0;
11,936✔
427
  int32_t szPgCont = PAGE_CONTENT_SIZE(pFD->szPage);
11,936✔
428
  int64_t fOffset = LOGIC_TO_FILE_OFFSET(offset, pFD->szPage);
11,936✔
429
  int64_t pgno = OFFSET_PGNO(fOffset, pFD->szPage);
11,936✔
430
  int64_t bOffset = fOffset % pFD->szPage;
11,936✔
431

432
  if (bOffset >= szPgCont) {
11,936✔
UNCOV
433
    TSDB_CHECK_CODE(code = TSDB_CODE_INVALID_PARA, lino, _exit);
×
434
  }
435

436
  // 1, find pgnoStart & pgnoEnd to fetch from s3, if all pgs are local, no need to fetch
437
  // 2, fetch pgnoStart ~ pgnoEnd from s3
438
  // 3, store pgs to pcache & last pg to pFD->pBuf
439
  // 4, deliver pgs to [pBuf, pBuf + size)
440

441
  while (n < size) {
2,090,292✔
442
    if (pFD->pgno != pgno) {
2,082,832✔
443
      LRUHandle *handle = NULL;
2,073,880✔
444
      code = tsdbCacheGetPageSs(pFD->pTsdb->pgCache, pFD, pgno, &handle);
2,073,880✔
445
      if (code != TSDB_CODE_SUCCESS) {
2,073,880✔
446
        if (handle) {
×
UNCOV
447
          tsdbCacheRelease(pFD->pTsdb->pgCache, handle);
×
448
        }
UNCOV
449
        TSDB_CHECK_CODE(code, lino, _exit);
×
450
      }
451

452
      if (!handle) {
2,073,880✔
453
        break;
4,476✔
454
      }
455

456
      uint8_t *pPage = (uint8_t *)taosLRUCacheValue(pFD->pTsdb->pgCache, handle);
2,069,404✔
457
      memcpy(pFD->pBuf, pPage, pFD->szPage);
2,069,404✔
458
      tsdbCacheRelease(pFD->pTsdb->pgCache, handle);
2,069,404✔
459

460
      // check
461
      if (pgno > 1 && !taosCheckChecksumWhole(pFD->pBuf, pFD->szPage)) {
4,138,062✔
UNCOV
462
        TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
463
      }
464

465
      pFD->pgno = pgno;
2,069,404✔
466
    }
467

468
    int64_t nRead = TMIN(szPgCont - bOffset, size - n);
2,078,356✔
469
    memcpy(pBuf + n, pFD->pBuf + bOffset, nRead);
2,078,356✔
470

471
    n += nRead;
2,078,356✔
472
    ++pgno;
2,078,356✔
473
    bOffset = 0;
2,078,356✔
474
  }
475

476
  if (n < size) {
11,936✔
477
    // 2, retrieve pgs from s3
478
    uint8_t *pBlock = NULL;
4,476✔
479
    int64_t  retrieve_offset = PAGE_OFFSET(pgno, pFD->szPage);
4,476✔
480
    int64_t  pgnoEnd = pgno - 1 + (bOffset + size - n + szPgCont - 1) / szPgCont;
4,476✔
481

482
    if (szHint > 0) {
4,476✔
UNCOV
483
      pgnoEnd = pgno - 1 + (bOffset + szHint - n + szPgCont - 1) / szPgCont;
×
484
    }
485

486
    int64_t retrieve_size = (pgnoEnd - pgno + 1) * pFD->szPage;
4,476✔
487

488
    code = tsdbReadFileBlock(pFD, retrieve_offset, retrieve_size, &pBlock);
4,476✔
489
    TSDB_CHECK_CODE(code, lino, _exit);
4,476✔
490
    // 3, Store Pages in Cache
491
    int nPage = pgnoEnd - pgno + 1;
4,476✔
492
    for (int i = 0; i < nPage; ++i) {
9,547,308✔
493
      if (pFD->szFile != pgno) {  // DONOT cache last volatile page
9,542,832✔
494
        tsdbCacheSetPageSs(pFD->pTsdb->pgCache, pFD, pgno, pBlock + i * pFD->szPage);
9,541,340✔
495
      }
496

497
      if (szHint > 0 && n >= size) {
9,542,832✔
498
        ++pgno;
×
UNCOV
499
        continue;
×
500
      }
501
      memcpy(pFD->pBuf, pBlock + i * pFD->szPage, pFD->szPage);
9,542,832✔
502

503
      // check
504
      if (pgno > 1 && !taosCheckChecksumWhole(pFD->pBuf, pFD->szPage)) {
19,083,426✔
UNCOV
505
        TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
506
      }
507

508
      pFD->pgno = pgno;
9,542,832✔
509

510
      int64_t nRead = TMIN(szPgCont - bOffset, size - n);
9,542,832✔
511
      memcpy(pBuf + n, pFD->pBuf + bOffset, nRead);
9,542,832✔
512

513
      n += nRead;
9,542,832✔
514
      ++pgno;
9,542,832✔
515
      bOffset = 0;
9,542,832✔
516
    }
517

518
    taosMemoryFree(pBlock);
4,476✔
519
  }
520

521
_exit:
7,460✔
522
  if (code) {
11,936✔
UNCOV
523
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
524
  }
525
  return code;
11,936✔
526
#else
527
  return TSDB_CODE_INTERNAL_ERROR;
528
#endif
529
}
530

531
int32_t tsdbReadFile(STsdbFD *pFD, int64_t offset, uint8_t *pBuf, int64_t size, int64_t szHint,
2,147,483,647✔
532
                     SEncryptData *encryptData) {
533
  int32_t code = 0;
2,147,483,647✔
534
  int32_t lino;
535

536
  if (!pFD->pFD) {
2,147,483,647✔
537
    code = tsdbOpenFileImpl(pFD);
365,814,919✔
538
    TSDB_CHECK_CODE(code, lino, _exit);
365,484,756✔
539
  }
540

541
  if (pFD->ssFile && pFD->lcn > 1 /* && tsSsBlockSize < 0*/) {
2,147,483,647✔
542
    code = tsdbReadFileSs(pFD, offset, pBuf, size, szHint);
11,936✔
543
    TSDB_CHECK_CODE(code, lino, _exit);
11,936✔
544
  } else {
545
    code = tsdbReadFileImp(pFD, offset, pBuf, size, encryptData);
2,147,483,647✔
546
    TSDB_CHECK_CODE(code, lino, _exit);
2,147,483,647✔
547
  }
548

549
_exit:
2,147,483,647✔
550
  if (code) {
2,147,483,647✔
UNCOV
551
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
552
  }
553
  return code;
2,147,483,647✔
554
}
555

556
int32_t tsdbReadFileToBuffer(STsdbFD *pFD, int64_t offset, int64_t size, SBuffer *buffer, int64_t szHint,
1,664,927,148✔
557
                             SEncryptData *encryptData) {
558
  int32_t code;
559
  int32_t lino;
560

561
  code = tBufferEnsureCapacity(buffer, buffer->size + size);
1,664,927,148✔
562
  TSDB_CHECK_CODE(code, lino, _exit);
1,665,081,739✔
563

564
  code = tsdbReadFile(pFD, offset, (uint8_t *)tBufferGetDataEnd(buffer), size, szHint, encryptData);
1,665,081,739✔
565
  TSDB_CHECK_CODE(code, lino, _exit);
1,666,548,611✔
566

567
  buffer->size += size;
1,666,548,611✔
568

569
_exit:
1,666,585,676✔
570
  if (code) {
1,666,585,676✔
UNCOV
571
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
572
  }
573
  return code;
1,666,204,639✔
574
}
575

576
int32_t tsdbFsyncFile(STsdbFD *pFD, SEncryptData *encryptData) {
19,961,535✔
577
  int32_t code = 0;
19,961,535✔
578
  int32_t lino;
579

580
  code = tsdbWriteFilePage(pFD, encryptData);
19,961,535✔
581
  TSDB_CHECK_CODE(code, lino, _exit);
19,961,004✔
582

583
  if (taosFsyncFile(pFD->pFD) < 0) {
19,961,004✔
UNCOV
584
    TSDB_CHECK_CODE(code = TAOS_SYSTEM_ERROR(ERRNO), lino, _exit);
×
585
  }
586

587
_exit:
19,958,070✔
588
  if (code) {
19,958,070✔
UNCOV
589
    TSDB_ERROR_LOG(TD_VID(pFD->pTsdb->pVnode), lino, code);
×
590
  }
591
  return code;
19,955,370✔
592
}
593

594
// SDataFReader ====================================================
595
int32_t tsdbDataFReaderOpen(SDataFReader **ppReader, STsdb *pTsdb, SDFileSet *pSet) {
×
596
  int32_t       code = 0;
×
597
  int32_t       lino = 0;
×
598
  SDataFReader *pReader = NULL;
×
599
  int32_t       szPage = pTsdb->pVnode->config.tsdbPageSize;
×
UNCOV
600
  char          fname[TSDB_FILENAME_LEN];
×
601

602
  // alloc
603
  pReader = (SDataFReader *)taosMemoryCalloc(1, sizeof(*pReader));
×
604
  if (pReader == NULL) {
×
UNCOV
605
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
606
  }
607
  pReader->pTsdb = pTsdb;
×
UNCOV
608
  pReader->pSet = pSet;
×
609

610
  // head
611
  tsdbHeadFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pHeadF, fname);
×
612
  code = tsdbOpenFile(fname, pTsdb, TD_FILE_READ, &pReader->pHeadFD, 0);
×
UNCOV
613
  TSDB_CHECK_CODE(code, lino, _exit);
×
614

615
  // data
616
  tsdbDataFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pDataF, fname);
×
617
  code = tsdbOpenFile(fname, pTsdb, TD_FILE_READ, &pReader->pDataFD, 0);
×
UNCOV
618
  TSDB_CHECK_CODE(code, lino, _exit);
×
619

620
  // sma
621
  tsdbSmaFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pSmaF, fname);
×
622
  code = tsdbOpenFile(fname, pTsdb, TD_FILE_READ, &pReader->pSmaFD, 0);
×
UNCOV
623
  TSDB_CHECK_CODE(code, lino, _exit);
×
624

625
  // stt
626
  for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
×
627
    tsdbSttFileName(pTsdb, pSet->diskId, pSet->fid, pSet->aSttF[iStt], fname);
×
628
    code = tsdbOpenFile(fname, pTsdb, TD_FILE_READ, &pReader->aSttFD[iStt], 0);
×
UNCOV
629
    TSDB_CHECK_CODE(code, lino, _exit);
×
630
  }
631

632
_exit:
×
633
  if (code) {
×
634
    *ppReader = NULL;
×
UNCOV
635
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
×
636

637
    if (pReader) {
×
638
      for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) tsdbCloseFile(&pReader->aSttFD[iStt]);
×
639
      tsdbCloseFile(&pReader->pSmaFD);
×
640
      tsdbCloseFile(&pReader->pDataFD);
×
641
      tsdbCloseFile(&pReader->pHeadFD);
×
UNCOV
642
      taosMemoryFree(pReader);
×
643
    }
644
  } else {
UNCOV
645
    *ppReader = pReader;
×
646
  }
UNCOV
647
  return code;
×
648
}
649

650
void tsdbDataFReaderClose(SDataFReader **ppReader) {
×
UNCOV
651
  if (*ppReader == NULL) return;
×
652

653
  // head
UNCOV
654
  tsdbCloseFile(&(*ppReader)->pHeadFD);
×
655

656
  // data
UNCOV
657
  tsdbCloseFile(&(*ppReader)->pDataFD);
×
658

659
  // sma
UNCOV
660
  tsdbCloseFile(&(*ppReader)->pSmaFD);
×
661

662
  // stt
663
  for (int32_t iStt = 0; iStt < TSDB_STT_TRIGGER_ARRAY_SIZE; iStt++) {
×
664
    if ((*ppReader)->aSttFD[iStt]) {
×
UNCOV
665
      tsdbCloseFile(&(*ppReader)->aSttFD[iStt]);
×
666
    }
667
  }
668

669
  for (int32_t iBuf = 0; iBuf < sizeof((*ppReader)->aBuf) / sizeof(uint8_t *); iBuf++) {
×
UNCOV
670
    tFree((*ppReader)->aBuf[iBuf]);
×
671
  }
672
  taosMemoryFree(*ppReader);
×
UNCOV
673
  *ppReader = NULL;
×
674
}
675

676
int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx) {
×
UNCOV
677
  int32_t    code = 0;
×
678
  int32_t    lino;
679
  SHeadFile *pHeadFile = pReader->pSet->pHeadF;
×
680
  int64_t    offset = pHeadFile->offset;
×
UNCOV
681
  int64_t    size = pHeadFile->size - offset;
×
682

683
  taosArrayClear(aBlockIdx);
×
684
  if (size == 0) {
×
UNCOV
685
    return code;
×
686
  }
687

688
  // alloc
689
  code = tRealloc(&pReader->aBuf[0], size);
×
UNCOV
690
  TSDB_CHECK_CODE(code, lino, _exit);
×
691

692
  // read
693
  SEncryptData *pEncryptData = &(pReader->pTsdb->pVnode->config.tsdbCfg.encryptData);
×
694
  code = tsdbReadFile(pReader->pHeadFD, offset, pReader->aBuf[0], size, 0, pEncryptData);
×
UNCOV
695
  TSDB_CHECK_CODE(code, lino, _exit);
×
696

697
  // decode
698
  int64_t n = 0;
×
699
  while (n < size) {
×
700
    SBlockIdx blockIdx;
×
UNCOV
701
    n += tGetBlockIdx(pReader->aBuf[0] + n, &blockIdx);
×
702

703
    if (taosArrayPush(aBlockIdx, &blockIdx) == NULL) {
×
UNCOV
704
      TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
705
    }
706
  }
707
  if (n != size) {
×
UNCOV
708
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
709
  }
710

711
_exit:
×
712
  if (code) {
×
UNCOV
713
    TSDB_ERROR_LOG(TD_VID(pReader->pTsdb->pVnode), lino, code);
×
714
  }
UNCOV
715
  return code;
×
716
}
717

718
int32_t tsdbReadSttBlk(SDataFReader *pReader, int32_t iStt, SArray *aSttBlk) {
×
UNCOV
719
  int32_t   code = 0;
×
720
  int32_t   lino;
721
  SSttFile *pSttFile = pReader->pSet->aSttF[iStt];
×
722
  int64_t   offset = pSttFile->offset;
×
UNCOV
723
  int64_t   size = pSttFile->size - offset;
×
724

725
  taosArrayClear(aSttBlk);
×
726
  if (size == 0) {
×
UNCOV
727
    return 0;
×
728
  }
729

730
  // alloc
731
  code = tRealloc(&pReader->aBuf[0], size);
×
UNCOV
732
  TSDB_CHECK_CODE(code, lino, _exit);
×
733

734
  // read
735
  SEncryptData *pEncryptData = &(pReader->pTsdb->pVnode->config.tsdbCfg.encryptData);
×
736
  code = tsdbReadFile(pReader->aSttFD[iStt], offset, pReader->aBuf[0], size, 0, pEncryptData);
×
UNCOV
737
  TSDB_CHECK_CODE(code, lino, _exit);
×
738

739
  // decode
740
  int64_t n = 0;
×
741
  while (n < size) {
×
742
    SSttBlk sttBlk;
×
UNCOV
743
    n += tGetSttBlk(pReader->aBuf[0] + n, &sttBlk);
×
744

745
    if (taosArrayPush(aSttBlk, &sttBlk) == NULL) {
×
UNCOV
746
      TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
747
    }
748
  }
749
  if (n != size) {
×
UNCOV
750
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
751
  }
752

753
_exit:
×
754
  if (code) {
×
UNCOV
755
    TSDB_ERROR_LOG(TD_VID(pReader->pTsdb->pVnode), lino, code);
×
756
  }
UNCOV
757
  return code;
×
758
}
759

760
int32_t tsdbReadDataBlk(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *mDataBlk) {
×
UNCOV
761
  int32_t code = 0;
×
762
  int32_t lino;
763
  int64_t offset = pBlockIdx->offset;
×
UNCOV
764
  int64_t size = pBlockIdx->size;
×
765

766
  // alloc
767
  code = tRealloc(&pReader->aBuf[0], size);
×
UNCOV
768
  TSDB_CHECK_CODE(code, lino, _exit);
×
769

770
  // read
UNCOV
771
  SEncryptData *pEncryptData = &(pReader->pTsdb->pVnode->config.tsdbCfg.encryptData);
×
772

773
  code = tsdbReadFile(pReader->pHeadFD, offset, pReader->aBuf[0], size, 0, pEncryptData);
×
UNCOV
774
  TSDB_CHECK_CODE(code, lino, _exit);
×
775

776
  // decode
777
  int32_t n;
×
778
  code = tGetMapData(pReader->aBuf[0], mDataBlk, &n);
×
779
  if (code) goto _exit;
×
780
  if (n != size) {
×
UNCOV
781
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
782
  }
783

784
_exit:
×
785
  if (code) {
×
UNCOV
786
    TSDB_ERROR_LOG(TD_VID(pReader->pTsdb->pVnode), lino, code);
×
787
  }
UNCOV
788
  return code;
×
789
}
790

791
// SDelFReader ====================================================
792
struct SDelFReader {
793
  STsdb   *pTsdb;
794
  SDelFile fDel;
795
  STsdbFD *pReadH;
796
  uint8_t *aBuf[1];
797
};
798

799
int32_t tsdbDelFReaderOpen(SDelFReader **ppReader, SDelFile *pFile, STsdb *pTsdb) {
×
800
  int32_t      code = 0;
×
801
  int32_t      lino = 0;
×
802
  char         fname[TSDB_FILENAME_LEN];
×
UNCOV
803
  SDelFReader *pDelFReader = NULL;
×
804

805
  // alloc
806
  pDelFReader = (SDelFReader *)taosMemoryCalloc(1, sizeof(*pDelFReader));
×
807
  if (pDelFReader == NULL) {
×
UNCOV
808
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
809
  }
810

811
  // open impl
812
  pDelFReader->pTsdb = pTsdb;
×
UNCOV
813
  pDelFReader->fDel = *pFile;
×
814

815
  tsdbDelFileName(pTsdb, pFile, fname);
×
816
  code = tsdbOpenFile(fname, pTsdb, TD_FILE_READ, &pDelFReader->pReadH, 0);
×
UNCOV
817
  TSDB_CHECK_CODE(code, lino, _exit);
×
818

819
_exit:
×
820
  if (code) {
×
821
    *ppReader = NULL;
×
822
    TSDB_ERROR_LOG(TD_VID(pTsdb->pVnode), lino, code);
×
UNCOV
823
    taosMemoryFree(pDelFReader);
×
824
  } else {
UNCOV
825
    *ppReader = pDelFReader;
×
826
  }
UNCOV
827
  return code;
×
828
}
829

830
void tsdbDelFReaderClose(SDelFReader **ppReader) {
×
831
  int32_t      code = 0;
×
UNCOV
832
  SDelFReader *pReader = *ppReader;
×
833

834
  if (pReader) {
×
835
    tsdbCloseFile(&pReader->pReadH);
×
836
    for (int32_t iBuf = 0; iBuf < sizeof(pReader->aBuf) / sizeof(uint8_t *); iBuf++) {
×
UNCOV
837
      tFree(pReader->aBuf[iBuf]);
×
838
    }
UNCOV
839
    taosMemoryFree(pReader);
×
840
  }
841

842
  *ppReader = NULL;
×
UNCOV
843
}
×
844

845
int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData) {
×
UNCOV
846
  return tsdbReadDelDatav1(pReader, pDelIdx, aDelData, INT64_MAX);
×
847
}
848

849
int32_t tsdbReadDelDatav1(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData, int64_t maxVer) {
×
UNCOV
850
  int32_t code = 0;
×
851
  int32_t lino;
852
  int64_t offset = pDelIdx->offset;
×
UNCOV
853
  int64_t size = pDelIdx->size;
×
854
  int64_t n;
855

UNCOV
856
  taosArrayClear(aDelData);
×
857

858
  // alloc
859
  code = tRealloc(&pReader->aBuf[0], size);
×
UNCOV
860
  TSDB_CHECK_CODE(code, lino, _exit);
×
861

862
  // read
UNCOV
863
  SEncryptData *pEncryptData = &(pReader->pTsdb->pVnode->config.tsdbCfg.encryptData);
×
864

865
  code = tsdbReadFile(pReader->pReadH, offset, pReader->aBuf[0], size, 0, pEncryptData);
×
UNCOV
866
  TSDB_CHECK_CODE(code, lino, _exit);
×
867

868
  // // decode
869
  n = 0;
×
870
  while (n < size) {
×
871
    SDelData delData;
×
UNCOV
872
    n += tGetDelData(pReader->aBuf[0] + n, &delData);
×
873

874
    if (delData.version > maxVer) {
×
UNCOV
875
      continue;
×
876
    }
877
    if (taosArrayPush(aDelData, &delData) == NULL) {
×
UNCOV
878
      TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
879
    }
880
  }
881

882
  if (n != size) {
×
UNCOV
883
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
884
  }
885

886
_exit:
×
887
  if (code) {
×
UNCOV
888
    TSDB_ERROR_LOG(TD_VID(pReader->pTsdb->pVnode), lino, code);
×
889
  }
UNCOV
890
  return code;
×
891
}
892

893
int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx) {
×
UNCOV
894
  int32_t code = 0;
×
895
  int32_t lino;
896
  int32_t n;
897
  int64_t offset = pReader->fDel.offset;
×
UNCOV
898
  int64_t size = pReader->fDel.size - offset;
×
899

UNCOV
900
  taosArrayClear(aDelIdx);
×
901

902
  // alloc
903
  code = tRealloc(&pReader->aBuf[0], size);
×
UNCOV
904
  TSDB_CHECK_CODE(code, lino, _exit);
×
905

906
  // read
UNCOV
907
  SEncryptData *pEncryptData = &(pReader->pTsdb->pVnode->config.tsdbCfg.encryptData);
×
908

909
  code = tsdbReadFile(pReader->pReadH, offset, pReader->aBuf[0], size, 0, pEncryptData);
×
UNCOV
910
  TSDB_CHECK_CODE(code, lino, _exit);
×
911

912
  // decode
913
  n = 0;
×
914
  while (n < size) {
×
UNCOV
915
    SDelIdx delIdx;
×
916

UNCOV
917
    n += tGetDelIdx(pReader->aBuf[0] + n, &delIdx);
×
918

919
    if (taosArrayPush(aDelIdx, &delIdx) == NULL) {
×
UNCOV
920
      TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
921
    }
922
  }
923

924
  if (n != size) {
×
UNCOV
925
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
926
  }
927

928
_exit:
×
929
  if (code) {
×
UNCOV
930
    TSDB_ERROR_LOG(TD_VID(pReader->pTsdb->pVnode), lino, code);
×
931
  }
UNCOV
932
  return code;
×
933
}
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