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

H
Hongze Cheng 已提交
16
#include "tsdb.h"
17
#include "vnd.h"
H
Hongze Cheng 已提交
18

H
Hongze Cheng 已提交
19
// =================================================================================================
H
Hongze Cheng 已提交
20
static int32_t tsdbFSToBinary(uint8_t *p, STsdbFS *pFS) {
H
Hongze Cheng 已提交
21
  int32_t  n = 0;
H
Hongze Cheng 已提交
22 23
  int8_t   hasDel = pFS->pDelFile ? 1 : 0;
  uint32_t nSet = taosArrayGetSize(pFS->aDFileSet);
H
Hongze Cheng 已提交
24

H
Hongze Cheng 已提交
25 26 27
  // version
  n += tPutI8(p ? p + n : p, 0);

H
Hongze Cheng 已提交
28 29 30
  // SDelFile
  n += tPutI8(p ? p + n : p, hasDel);
  if (hasDel) {
H
Hongze Cheng 已提交
31
    n += tPutDelFile(p ? p + n : p, pFS->pDelFile);
H
Hongze Cheng 已提交
32 33
  }

H
Hongze Cheng 已提交
34
  // SArray<SDFileSet>
H
Hongze Cheng 已提交
35 36 37
  n += tPutU32v(p ? p + n : p, nSet);
  for (uint32_t iSet = 0; iSet < nSet; iSet++) {
    n += tPutDFileSet(p ? p + n : p, (SDFileSet *)taosArrayGet(pFS->aDFileSet, iSet));
H
Hongze Cheng 已提交
38 39
  }

H
Hongze Cheng 已提交
40
  return n;
H
Hongze Cheng 已提交
41 42
}

H
Hongze Cheng 已提交
43 44 45
static int32_t tsdbBinaryToFS(uint8_t *pData, int64_t nData, STsdbFS *pFS) {
  int32_t code = 0;
  int32_t n = 0;
H
Hongze Cheng 已提交
46

H
Hongze Cheng 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
  // version
  n += tGetI8(pData + n, NULL);

  // SDelFile
  int8_t hasDel = 0;
  n += tGetI8(pData + n, &hasDel);
  if (hasDel) {
    pFS->pDelFile = (SDelFile *)taosMemoryCalloc(1, sizeof(SDelFile));
    if (pFS->pDelFile == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
      goto _exit;
    }

    n += tGetDelFile(pData + n, pFS->pDelFile);
    pFS->pDelFile->nRef = 1;
  } else {
    pFS->pDelFile = NULL;
  }

  // aDFileSet
  taosArrayClear(pFS->aDFileSet);
  uint32_t nSet = 0;
  n += tGetU32v(pData + n, &nSet);
  for (uint32_t iSet = 0; iSet < nSet; iSet++) {
    SDFileSet fSet = {0};

    int32_t nt = tGetDFileSet(pData + n, &fSet);
    if (nt < 0) {
      code = TSDB_CODE_OUT_OF_MEMORY;
      goto _exit;
    }

    n += nt;
    if (taosArrayPush(pFS->aDFileSet, &fSet) == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
      goto _exit;
    }
  }

86
  ASSERT(n + sizeof(TSCKSUM) == nData);
H
Hongze Cheng 已提交
87 88 89 90 91 92 93 94 95 96 97 98

_exit:
  return code;
}

static int32_t tsdbSaveFSToFile(STsdbFS *pFS, const char *fname) {
  int32_t code = 0;
  int32_t lino = 0;

  // encode to binary
  int32_t  size = tsdbFSToBinary(NULL, pFS) + sizeof(TSCKSUM);
  uint8_t *pData = taosMemoryMalloc(size);
H
Hongze Cheng 已提交
99 100
  if (pData == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
101
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
102
  }
H
Hongze Cheng 已提交
103
  tsdbFSToBinary(pData, pFS);
H
Hongze Cheng 已提交
104
  taosCalcChecksumAppend(0, pData, size);
H
Hongze Cheng 已提交
105

H
Hongze Cheng 已提交
106 107
  // save to file
  TdFilePtr pFD = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
H
Hongze Cheng 已提交
108 109
  if (pFD == NULL) {
    code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
110
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
111 112
  }

H
Hongze Cheng 已提交
113
  int64_t n = taosWriteFile(pFD, pData, size);
H
Hongze Cheng 已提交
114 115
  if (n < 0) {
    code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
116 117
    taosCloseFile(&pFD);
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
118 119 120 121
  }

  if (taosFsyncFile(pFD) < 0) {
    code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
122 123
    taosCloseFile(&pFD);
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
124 125 126 127
  }

  taosCloseFile(&pFD);

H
Hongze Cheng 已提交
128
_exit:
H
Hongze Cheng 已提交
129
  if (pData) taosMemoryFree(pData);
H
Hongze Cheng 已提交
130 131 132
  if (code) {
    tsdbError("%s failed at line %d since %s, fname:%s", __func__, lino, tstrerror(code), fname);
  }
H
Hongze Cheng 已提交
133 134 135
  return code;
}

H
Hongze Cheng 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148
int32_t tsdbFSCreate(STsdbFS *pFS) {
  int32_t code = 0;

  pFS->pDelFile = NULL;
  pFS->aDFileSet = taosArrayInit(0, sizeof(SDFileSet));
  if (pFS->aDFileSet == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
  }

_exit:
  return code;
}
H
Hongze Cheng 已提交
149 150 151

void tsdbFSDestroy(STsdbFS *pFS) {
  if (pFS->pDelFile) {
152
    taosMemoryFree(pFS->pDelFile);
H
Hongze Cheng 已提交
153
    pFS->pDelFile = NULL;
H
Hongze Cheng 已提交
154
  }
H
Hongze Cheng 已提交
155

H
Hongze Cheng 已提交
156 157 158 159 160
  for (int32_t iSet = 0; iSet < taosArrayGetSize(pFS->aDFileSet); iSet++) {
    SDFileSet *pSet = (SDFileSet *)taosArrayGet(pFS->aDFileSet, iSet);
    taosMemoryFree(pSet->pHeadF);
    taosMemoryFree(pSet->pDataF);
    taosMemoryFree(pSet->pSmaF);
H
Hongze Cheng 已提交
161 162
    for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
      taosMemoryFree(pSet->aSttF[iStt]);
H
Hongze Cheng 已提交
163
    }
H
Hongze Cheng 已提交
164
  }
H
Hongze Cheng 已提交
165

166
  taosArrayDestroy(pFS->aDFileSet);
H
Hongze Cheng 已提交
167
  pFS->aDFileSet = NULL;
H
Hongze Cheng 已提交
168 169 170 171
}

static int32_t tsdbScanAndTryFixFS(STsdb *pTsdb) {
  int32_t code = 0;
H
Hongze Cheng 已提交
172 173 174
  int32_t lino = 0;
  int64_t size = 0;
  char    fname[TSDB_FILENAME_LEN] = {0};
H
Hongze Cheng 已提交
175 176 177 178 179

  // SDelFile
  if (pTsdb->fs.pDelFile) {
    tsdbDelFileName(pTsdb, pTsdb->fs.pDelFile, fname);
    if (taosStatFile(fname, &size, NULL)) {
H
Hongze Cheng 已提交
180
      code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
181
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
182 183
    }

184
    if (size != tsdbLogicToFileSize(pTsdb->fs.pDelFile->size, pTsdb->pVnode->config.tsdbPageSize)) {
H
Hongze Cheng 已提交
185
      code = TSDB_CODE_FILE_CORRUPTED;
H
Hongze Cheng 已提交
186
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
187
    }
H
Hongze Cheng 已提交
188
  }
H
Hongze Cheng 已提交
189

H
Hongze Cheng 已提交
190
  // SArray<SDFileSet>
H
Hongze Cheng 已提交
191
  int32_t fid = 0;
H
Hongze Cheng 已提交
192 193
  for (int32_t iSet = 0; iSet < taosArrayGetSize(pTsdb->fs.aDFileSet); iSet++) {
    SDFileSet *pSet = (SDFileSet *)taosArrayGet(pTsdb->fs.aDFileSet, iSet);
H
Hongze Cheng 已提交
194
    fid = pSet->fid;
H
Hongze Cheng 已提交
195 196 197 198 199

    // head =========
    tsdbHeadFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pHeadF, fname);
    if (taosStatFile(fname, &size, NULL)) {
      code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
200
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
201
    }
H
Hongze Cheng 已提交
202
    if (size != tsdbLogicToFileSize(pSet->pHeadF->size, pTsdb->pVnode->config.tsdbPageSize)) {
H
Hongze Cheng 已提交
203
      code = TSDB_CODE_FILE_CORRUPTED;
H
Hongze Cheng 已提交
204
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
205 206
    }

H
Hongze Cheng 已提交
207 208 209
    // data =========
    tsdbDataFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pDataF, fname);
    if (taosStatFile(fname, &size, NULL)) {
H
Hongze Cheng 已提交
210
      code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
211
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
212
    }
H
Hongze Cheng 已提交
213
    if (size < tsdbLogicToFileSize(pSet->pDataF->size, pTsdb->pVnode->config.tsdbPageSize)) {
H
Hongze Cheng 已提交
214
      code = TSDB_CODE_FILE_CORRUPTED;
H
Hongze Cheng 已提交
215
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
216
    }
H
Hongze Cheng 已提交
217 218 219 220
    // else if (size > tsdbLogicToFileSize(pSet->pDataF->size, pTsdb->pVnode->config.tsdbPageSize)) {
    //   code = tsdbDFileRollback(pTsdb, pSet, TSDB_DATA_FILE);
    //   TSDB_CHECK_CODE(code, lino, _exit);
    // }
H
Hongze Cheng 已提交
221

H
Hongze Cheng 已提交
222 223 224 225
    // sma =============
    tsdbSmaFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pSmaF, fname);
    if (taosStatFile(fname, &size, NULL)) {
      code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
226
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
227
    }
H
Hongze Cheng 已提交
228
    if (size < tsdbLogicToFileSize(pSet->pSmaF->size, pTsdb->pVnode->config.tsdbPageSize)) {
H
Hongze Cheng 已提交
229
      code = TSDB_CODE_FILE_CORRUPTED;
H
Hongze Cheng 已提交
230
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
231
    }
H
Hongze Cheng 已提交
232 233 234 235
    // else if (size > tsdbLogicToFileSize(pSet->pSmaF->size, pTsdb->pVnode->config.tsdbPageSize)) {
    //   code = tsdbDFileRollback(pTsdb, pSet, TSDB_SMA_FILE);
    //   TSDB_CHECK_CODE(code, lino, _exit);
    // }
H
Hongze Cheng 已提交
236

H
Hongze Cheng 已提交
237 238 239
    // stt ===========
    for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
      tsdbSttFileName(pTsdb, pSet->diskId, pSet->fid, pSet->aSttF[iStt], fname);
H
Hongze Cheng 已提交
240 241
      if (taosStatFile(fname, &size, NULL)) {
        code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
242
        TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
243
      }
H
Hongze Cheng 已提交
244
      if (size != tsdbLogicToFileSize(pSet->aSttF[iStt]->size, pTsdb->pVnode->config.tsdbPageSize)) {
H
Hongze Cheng 已提交
245
        code = TSDB_CODE_FILE_CORRUPTED;
H
Hongze Cheng 已提交
246
        TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
247 248
      }
    }
H
Hongze Cheng 已提交
249
  }
H
Hongze Cheng 已提交
250

H
Hongze Cheng 已提交
251 252
  {
    // remove those invalid files (todo)
H
Hongze Cheng 已提交
253 254
  }

H
Hongze Cheng 已提交
255 256
_exit:
  if (code) {
S
Shengliang Guan 已提交
257
    tsdbError("vgId:%d, %s failed at line %d since %s, fid:%d", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code),
H
Hongze Cheng 已提交
258 259
              fid);
  }
H
Hongze Cheng 已提交
260 261 262
  return code;
}

H
Hongze Cheng 已提交
263 264 265 266 267 268 269 270 271
int32_t tDFileSetCmprFn(const void *p1, const void *p2) {
  if (((SDFileSet *)p1)->fid < ((SDFileSet *)p2)->fid) {
    return -1;
  } else if (((SDFileSet *)p1)->fid > ((SDFileSet *)p2)->fid) {
    return 1;
  }

  return 0;
}
H
Hongze Cheng 已提交
272

273
static void tsdbGetCurrentFName(STsdb *pTsdb, char *current, char *current_t) {
H
Hongze Cheng 已提交
274
  SVnode *pVnode = pTsdb->pVnode;
275 276 277 278
  int32_t offset = 0;

  // CURRENT
  if (current) {
279
    vnodeGetPrimaryDir(pTsdb->path, pVnode->pTfs, current, TSDB_FILENAME_LEN);
280 281 282 283 284 285
    offset = strlen(current);
    snprintf(current + offset, TSDB_FILENAME_LEN - offset - 1, "%sCURRENT", TD_DIRSEP);
  }

  // CURRENT.t
  if (current_t) {
286
    vnodeGetPrimaryDir(pTsdb->path, pVnode->pTfs, current_t, TSDB_FILENAME_LEN);
287 288
    offset = strlen(current_t);
    snprintf(current_t + offset, TSDB_FILENAME_LEN - offset - 1, "%sCURRENT.t", TD_DIRSEP);
H
Hongze Cheng 已提交
289 290 291
  }
}

H
Hongze Cheng 已提交
292 293 294 295 296 297 298 299
static int32_t tsdbLoadFSFromFile(const char *fname, STsdbFS *pFS) {
  int32_t  code = 0;
  int32_t  lino = 0;
  uint8_t *pData = NULL;

  // load binary
  TdFilePtr pFD = taosOpenFile(fname, TD_FILE_READ);
  if (pFD == NULL) {
H
Hongze Cheng 已提交
300
    code = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
    TSDB_CHECK_CODE(code, lino, _exit);
  }

  int64_t size;
  if (taosFStatFile(pFD, &size, NULL) < 0) {
    code = TAOS_SYSTEM_ERROR(errno);
    taosCloseFile(&pFD);
    TSDB_CHECK_CODE(code, lino, _exit);
  }

  pData = taosMemoryMalloc(size);
  if (pData == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    taosCloseFile(&pFD);
    TSDB_CHECK_CODE(code, lino, _exit);
  }

  if (taosReadFile(pFD, pData, size) < 0) {
    code = TAOS_SYSTEM_ERROR(errno);
    taosCloseFile(&pFD);
    TSDB_CHECK_CODE(code, lino, _exit);
  }

  if (!taosCheckChecksumWhole(pData, size)) {
    code = TSDB_CODE_FILE_CORRUPTED;
    taosCloseFile(&pFD);
    TSDB_CHECK_CODE(code, lino, _exit);
  }

  taosCloseFile(&pFD);

  // decode binary
  code = tsdbBinaryToFS(pData, size, pFS);
  TSDB_CHECK_CODE(code, lino, _exit);

_exit:
  if (pData) taosMemoryFree(pData);
  if (code) {
    tsdbError("%s failed at line %d since %s, fname:%s", __func__, lino, tstrerror(code), fname);
  }
  return code;
}

static int32_t tsdbRemoveFileSet(STsdb *pTsdb, SDFileSet *pSet) {
  int32_t code = 0;
  char    fname[TSDB_FILENAME_LEN] = {0};

  int32_t nRef = atomic_sub_fetch_32(&pSet->pHeadF->nRef, 1);
  if (nRef == 0) {
    tsdbHeadFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pHeadF, fname);
    (void)taosRemoveFile(fname);
    taosMemoryFree(pSet->pHeadF);
  }

  nRef = atomic_sub_fetch_32(&pSet->pDataF->nRef, 1);
  if (nRef == 0) {
    tsdbDataFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pDataF, fname);
H
Hongze Cheng 已提交
358
    (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
359 360 361 362 363 364
    taosMemoryFree(pSet->pDataF);
  }

  nRef = atomic_sub_fetch_32(&pSet->pSmaF->nRef, 1);
  if (nRef == 0) {
    tsdbSmaFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pSmaF, fname);
H
Hongze Cheng 已提交
365
    (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
366 367 368 369 370 371 372
    taosMemoryFree(pSet->pSmaF);
  }

  for (int8_t iStt = 0; iStt < pSet->nSttF; iStt++) {
    nRef = atomic_sub_fetch_32(&pSet->aSttF[iStt]->nRef, 1);
    if (nRef == 0) {
      tsdbSttFileName(pTsdb, pSet->diskId, pSet->fid, pSet->aSttF[iStt], fname);
H
Hongze Cheng 已提交
373
      (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
374 375 376 377 378 379 380 381 382
      taosMemoryFree(pSet->aSttF[iStt]);
    }
  }

_exit:
  return code;
}

static int32_t tsdbNewFileSet(STsdb *pTsdb, SDFileSet *pSetTo, SDFileSet *pSetFrom) {
H
Hongze Cheng 已提交
383
  int32_t code = 0;
H
Hongze Cheng 已提交
384
  int32_t lino = 0;
H
Hongze Cheng 已提交
385

H
Hongze Cheng 已提交
386
  *pSetTo = (SDFileSet){.diskId = pSetFrom->diskId, .fid = pSetFrom->fid, .nSttF = 0};
H
Hongze Cheng 已提交
387

H
Hongze Cheng 已提交
388 389 390 391 392 393 394 395
  // head
  pSetTo->pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile));
  if (pSetTo->pHeadF == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    TSDB_CHECK_CODE(code, lino, _exit);
  }
  *pSetTo->pHeadF = *pSetFrom->pHeadF;
  pSetTo->pHeadF->nRef = 1;
H
Hongze Cheng 已提交
396

H
Hongze Cheng 已提交
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
  // data
  pSetTo->pDataF = (SDataFile *)taosMemoryMalloc(sizeof(SDataFile));
  if (pSetTo->pDataF == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    TSDB_CHECK_CODE(code, lino, _exit);
  }
  *pSetTo->pDataF = *pSetFrom->pDataF;
  pSetTo->pDataF->nRef = 1;

  // sma
  pSetTo->pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
  if (pSetTo->pSmaF == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    TSDB_CHECK_CODE(code, lino, _exit);
  }
  *pSetTo->pSmaF = *pSetFrom->pSmaF;
  pSetTo->pSmaF->nRef = 1;

  // stt
  for (int32_t iStt = 0; iStt < pSetFrom->nSttF; iStt++) {
    pSetTo->aSttF[iStt] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
    if (pSetTo->aSttF[iStt] == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
420
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
421
    }
H
Hongze Cheng 已提交
422

H
Hongze Cheng 已提交
423 424 425 426 427 428 429
    pSetTo->nSttF++;
    *pSetTo->aSttF[iStt] = *pSetFrom->aSttF[iStt];
    pSetTo->aSttF[iStt]->nRef = 1;
  }

_exit:
  if (code) {
S
Shengliang Guan 已提交
430
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
  }
  return code;
}

static int32_t tsdbMergeFileSet(STsdb *pTsdb, SDFileSet *pSetOld, SDFileSet *pSetNew) {
  int32_t code = 0;
  int32_t lino = 0;
  int32_t nRef = 0;
  bool    sameDisk = ((pSetOld->diskId.level == pSetNew->diskId.level) && (pSetOld->diskId.id == pSetNew->diskId.id));
  char    fname[TSDB_FILENAME_LEN] = {0};

  // head
  SHeadFile *pHeadF = pSetOld->pHeadF;
  if ((!sameDisk) || (pHeadF->commitID != pSetNew->pHeadF->commitID)) {
    pSetOld->pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile));
    if (pSetOld->pHeadF == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
448
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
449
    }
H
Hongze Cheng 已提交
450 451 452 453 454 455 456 457 458 459
    *pSetOld->pHeadF = *pSetNew->pHeadF;
    pSetOld->pHeadF->nRef = 1;

    nRef = atomic_sub_fetch_32(&pHeadF->nRef, 1);
    if (nRef == 0) {
      tsdbHeadFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pHeadF, fname);
      (void)taosRemoveFile(fname);
      taosMemoryFree(pHeadF);
    }
  } else {
K
kailixu 已提交
460 461
    ASSERT(pHeadF->offset == pSetNew->pHeadF->offset);
    ASSERT(pHeadF->size == pSetNew->pHeadF->size);
H
Hongze Cheng 已提交
462
  }
H
Hongze Cheng 已提交
463

H
Hongze Cheng 已提交
464 465 466 467 468
  // data
  SDataFile *pDataF = pSetOld->pDataF;
  if ((!sameDisk) || (pDataF->commitID != pSetNew->pDataF->commitID)) {
    pSetOld->pDataF = (SDataFile *)taosMemoryMalloc(sizeof(SDataFile));
    if (pSetOld->pDataF == NULL) {
H
Hongze Cheng 已提交
469
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
470
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
471
    }
H
Hongze Cheng 已提交
472 473 474 475 476 477 478 479 480 481
    *pSetOld->pDataF = *pSetNew->pDataF;
    pSetOld->pDataF->nRef = 1;

    nRef = atomic_sub_fetch_32(&pDataF->nRef, 1);
    if (nRef == 0) {
      tsdbDataFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pDataF, fname);
      (void)taosRemoveFile(fname);
      taosMemoryFree(pDataF);
    }
  } else {
K
kailixu 已提交
482
    pDataF->size = pSetNew->pDataF->size;
H
Hongze Cheng 已提交
483
  }
H
Hongze Cheng 已提交
484

H
Hongze Cheng 已提交
485 486 487 488 489 490
  // sma
  SSmaFile *pSmaF = pSetOld->pSmaF;
  if ((!sameDisk) || (pSmaF->commitID != pSetNew->pSmaF->commitID)) {
    pSetOld->pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
    if (pSetOld->pSmaF == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
491
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
492
    }
H
Hongze Cheng 已提交
493 494 495 496 497 498 499 500 501 502
    *pSetOld->pSmaF = *pSetNew->pSmaF;
    pSetOld->pSmaF->nRef = 1;

    nRef = atomic_sub_fetch_32(&pSmaF->nRef, 1);
    if (nRef == 0) {
      tsdbSmaFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSmaF, fname);
      (void)taosRemoveFile(fname);
      taosMemoryFree(pSmaF);
    }
  } else {
K
kailixu 已提交
503
    pSmaF->size = pSetNew->pSmaF->size;
H
Hongze Cheng 已提交
504
  }
H
Hongze Cheng 已提交
505

H
Hongze Cheng 已提交
506 507 508
  // stt
  if (sameDisk) {
    if (pSetNew->nSttF > pSetOld->nSttF) {
509
      ASSERT(pSetNew->nSttF == pSetOld->nSttF + 1);
H
Hongze Cheng 已提交
510 511 512 513 514 515 516 517 518
      pSetOld->aSttF[pSetOld->nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
      if (pSetOld->aSttF[pSetOld->nSttF] == NULL) {
        code = TSDB_CODE_OUT_OF_MEMORY;
        TSDB_CHECK_CODE(code, lino, _exit);
      }
      *pSetOld->aSttF[pSetOld->nSttF] = *pSetNew->aSttF[pSetOld->nSttF];
      pSetOld->aSttF[pSetOld->nSttF]->nRef = 1;
      pSetOld->nSttF++;
    } else if (pSetNew->nSttF < pSetOld->nSttF) {
519
      ASSERT(pSetNew->nSttF == 1);
H
Hongze Cheng 已提交
520 521 522 523 524
      for (int32_t iStt = 0; iStt < pSetOld->nSttF; iStt++) {
        SSttFile *pSttFile = pSetOld->aSttF[iStt];
        nRef = atomic_sub_fetch_32(&pSttFile->nRef, 1);
        if (nRef == 0) {
          tsdbSttFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSttFile, fname);
H
Hongze Cheng 已提交
525
          (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
          taosMemoryFree(pSttFile);
        }
        pSetOld->aSttF[iStt] = NULL;
      }

      pSetOld->nSttF = 1;
      pSetOld->aSttF[0] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
      if (pSetOld->aSttF[0] == NULL) {
        code = TSDB_CODE_OUT_OF_MEMORY;
        TSDB_CHECK_CODE(code, lino, _exit);
      }
      *pSetOld->aSttF[0] = *pSetNew->aSttF[0];
      pSetOld->aSttF[0]->nRef = 1;
    } else {
      for (int32_t iStt = 0; iStt < pSetOld->nSttF; iStt++) {
        if (pSetOld->aSttF[iStt]->commitID != pSetNew->aSttF[iStt]->commitID) {
          SSttFile *pSttFile = pSetOld->aSttF[iStt];
          nRef = atomic_sub_fetch_32(&pSttFile->nRef, 1);
          if (nRef == 0) {
            tsdbSttFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSttFile, fname);
H
Hongze Cheng 已提交
546
            (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
547 548 549 550 551 552 553 554 555 556 557
            taosMemoryFree(pSttFile);
          }

          pSetOld->aSttF[iStt] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
          if (pSetOld->aSttF[iStt] == NULL) {
            code = TSDB_CODE_OUT_OF_MEMORY;
            TSDB_CHECK_CODE(code, lino, _exit);
          }
          *pSetOld->aSttF[iStt] = *pSetNew->aSttF[iStt];
          pSetOld->aSttF[iStt]->nRef = 1;
        } else {
558 559
          ASSERT(pSetOld->aSttF[iStt]->size == pSetOld->aSttF[iStt]->size);
          ASSERT(pSetOld->aSttF[iStt]->offset == pSetOld->aSttF[iStt]->offset);
H
Hongze Cheng 已提交
560 561 562 563 564 565 566 567 568 569 570 571
        }
      }
    }
  } else {
    for (int32_t iStt = 0; iStt < pSetOld->nSttF; iStt++) {
      SSttFile *pSttFile = pSetOld->aSttF[iStt];
      nRef = atomic_sub_fetch_32(&pSttFile->nRef, 1);
      if (nRef == 0) {
        tsdbSttFileName(pTsdb, pSetOld->diskId, pSetOld->fid, pSttFile, fname);
        (void)taosRemoveFile(fname);
        taosMemoryFree(pSttFile);
      }
H
Hongze Cheng 已提交
572 573
    }

H
Hongze Cheng 已提交
574 575 576 577 578 579 580 581 582 583
    pSetOld->nSttF = 0;
    for (int32_t iStt = 0; iStt < pSetNew->nSttF; iStt++) {
      pSetOld->aSttF[iStt] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
      if (pSetOld->aSttF[iStt] == NULL) {
        code = TSDB_CODE_OUT_OF_MEMORY;
        TSDB_CHECK_CODE(code, lino, _exit);
      }

      *pSetOld->aSttF[iStt] = *pSetNew->aSttF[iStt];
      pSetOld->aSttF[iStt]->nRef = 1;
H
Hongze Cheng 已提交
584

H
Hongze Cheng 已提交
585 586 587 588 589 590 591 592 593 594
      pSetOld->nSttF++;
    }
  }

  if (!sameDisk) {
    pSetOld->diskId = pSetNew->diskId;
  }

_exit:
  if (code) {
S
Shengliang Guan 已提交
595
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630
  }
  return code;
}

static int32_t tsdbFSApplyChange(STsdb *pTsdb, STsdbFS *pFS) {
  int32_t code = 0;
  int32_t lino = 0;

  int32_t nRef = 0;
  char    fname[TSDB_FILENAME_LEN] = {0};

  // SDelFile
  if (pFS->pDelFile) {
    SDelFile *pDelFile = pTsdb->fs.pDelFile;

    if (pDelFile == NULL || (pDelFile->commitID != pFS->pDelFile->commitID)) {
      pTsdb->fs.pDelFile = (SDelFile *)taosMemoryMalloc(sizeof(SDelFile));
      if (pTsdb->fs.pDelFile == NULL) {
        code = TSDB_CODE_OUT_OF_MEMORY;
        TSDB_CHECK_CODE(code, lino, _exit);
      }

      *pTsdb->fs.pDelFile = *pFS->pDelFile;
      pTsdb->fs.pDelFile->nRef = 1;

      if (pDelFile) {
        nRef = atomic_sub_fetch_32(&pDelFile->nRef, 1);
        if (nRef == 0) {
          tsdbDelFileName(pTsdb, pDelFile, fname);
          (void)taosRemoveFile(fname);
          taosMemoryFree(pDelFile);
        }
      }
    }
  } else {
H
Hongze Cheng 已提交
631 632 633 634 635 636 637 638 639
    if (pTsdb->fs.pDelFile) {
      nRef = atomic_sub_fetch_32(&pTsdb->fs.pDelFile->nRef, 1);
      if (nRef == 0) {
        tsdbDelFileName(pTsdb, pTsdb->fs.pDelFile, fname);
        (void)taosRemoveFile(fname);
        taosMemoryFree(pTsdb->fs.pDelFile);
      }
      pTsdb->fs.pDelFile = NULL;
    }
H
Hongze Cheng 已提交
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
  }

  // aDFileSet
  int32_t iOld = 0;
  int32_t iNew = 0;
  while (true) {
    int32_t   nOld = taosArrayGetSize(pTsdb->fs.aDFileSet);
    int32_t   nNew = taosArrayGetSize(pFS->aDFileSet);
    SDFileSet fSet = {0};
    int8_t    sameDisk = 0;

    if (iOld >= nOld && iNew >= nNew) break;

    SDFileSet *pSetOld = (iOld < nOld) ? taosArrayGet(pTsdb->fs.aDFileSet, iOld) : NULL;
    SDFileSet *pSetNew = (iNew < nNew) ? taosArrayGet(pFS->aDFileSet, iNew) : NULL;

    if (pSetOld && pSetNew) {
      if (pSetOld->fid == pSetNew->fid) {
        code = tsdbMergeFileSet(pTsdb, pSetOld, pSetNew);
        TSDB_CHECK_CODE(code, lino, _exit);

        iOld++;
        iNew++;
      } else if (pSetOld->fid < pSetNew->fid) {
        code = tsdbRemoveFileSet(pTsdb, pSetOld);
        TSDB_CHECK_CODE(code, lino, _exit);
        taosArrayRemove(pTsdb->fs.aDFileSet, iOld);
      } else {
        code = tsdbNewFileSet(pTsdb, &fSet, pSetNew);
        TSDB_CHECK_CODE(code, lino, _exit)

        if (taosArrayInsert(pTsdb->fs.aDFileSet, iOld, &fSet) == NULL) {
          code = TSDB_CODE_OUT_OF_MEMORY;
          TSDB_CHECK_CODE(code, lino, _exit);
        }

        iOld++;
        iNew++;
      }
    } else if (pSetOld) {
      code = tsdbRemoveFileSet(pTsdb, pSetOld);
H
Hongze Cheng 已提交
681
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
682 683 684 685 686 687 688 689 690 691 692 693
      taosArrayRemove(pTsdb->fs.aDFileSet, iOld);
    } else {
      code = tsdbNewFileSet(pTsdb, &fSet, pSetNew);
      TSDB_CHECK_CODE(code, lino, _exit)

      if (taosArrayInsert(pTsdb->fs.aDFileSet, iOld, &fSet) == NULL) {
        code = TSDB_CODE_OUT_OF_MEMORY;
        TSDB_CHECK_CODE(code, lino, _exit);
      }

      iOld++;
      iNew++;
H
Hongze Cheng 已提交
694
    }
H
Hongze Cheng 已提交
695 696 697 698
  }

_exit:
  if (code) {
S
Shengliang Guan 已提交
699
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
700 701 702 703
  }
  return code;
}

704 705
// EXPOSED APIS ====================================================================================
int32_t tsdbFSCommit(STsdb *pTsdb) {
H
Hongze Cheng 已提交
706 707
  int32_t code = 0;
  int32_t lino = 0;
H
Hongze Cheng 已提交
708
  STsdbFS fs = {0};
H
Hongze Cheng 已提交
709

710 711 712 713 714
  char current[TSDB_FILENAME_LEN] = {0};
  char current_t[TSDB_FILENAME_LEN] = {0};
  tsdbGetCurrentFName(pTsdb, current, current_t);

  if (!taosCheckExistFile(current_t)) goto _exit;
H
Hongze Cheng 已提交
715

H
Hongze Cheng 已提交
716
  // rename the file
717
  if (taosRenameFile(current_t, current) < 0) {
H
Hongze Cheng 已提交
718 719 720 721 722 723 724 725
    code = TAOS_SYSTEM_ERROR(errno);
    TSDB_CHECK_CODE(code, lino, _exit);
  }

  // Load the new FS
  code = tsdbFSCreate(&fs);
  TSDB_CHECK_CODE(code, lino, _exit);

726
  code = tsdbLoadFSFromFile(current, &fs);
H
Hongze Cheng 已提交
727
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
728

H
Hongze Cheng 已提交
729 730 731 732 733 734 735
  // apply file change
  code = tsdbFSApplyChange(pTsdb, &fs);
  TSDB_CHECK_CODE(code, lino, _exit);

_exit:
  tsdbFSDestroy(&fs);
  if (code) {
S
Shengliang Guan 已提交
736
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
737 738 739 740
  }
  return code;
}

H
Hongze Cheng 已提交
741
int32_t tsdbFSRollback(STsdb *pTsdb) {
H
Hongze Cheng 已提交
742
  int32_t code = 0;
743 744 745 746 747 748 749 750 751 752
  int32_t lino = 0;

  char current_t[TSDB_FILENAME_LEN] = {0};
  tsdbGetCurrentFName(pTsdb, NULL, current_t);
  (void)taosRemoveFile(current_t);

_exit:
  if (code) {
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(errno));
  }
H
Hongze Cheng 已提交
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
  return code;
}

int32_t tsdbFSOpen(STsdb *pTsdb, int8_t rollback) {
  int32_t code = 0;
  int32_t lino = 0;
  SVnode *pVnode = pTsdb->pVnode;

  // open handle
  code = tsdbFSCreate(&pTsdb->fs);
  TSDB_CHECK_CODE(code, lino, _exit);

  // open impl
  char current[TSDB_FILENAME_LEN] = {0};
  char current_t[TSDB_FILENAME_LEN] = {0};
768
  tsdbGetCurrentFName(pTsdb, current, current_t);
H
Hongze Cheng 已提交
769 770 771 772 773 774 775 776 777 778 779 780 781 782

  if (taosCheckExistFile(current)) {
    code = tsdbLoadFSFromFile(current, &pTsdb->fs);
    TSDB_CHECK_CODE(code, lino, _exit);

    if (taosCheckExistFile(current_t)) {
      if (rollback) {
        code = tsdbFSRollback(pTsdb);
        TSDB_CHECK_CODE(code, lino, _exit);
      } else {
        code = tsdbFSCommit(pTsdb);
        TSDB_CHECK_CODE(code, lino, _exit);
      }
    }
H
Hongze Cheng 已提交
783
  } else {
784 785
    // empty one
    code = tsdbSaveFSToFile(&pTsdb->fs, current);
H
Hongze Cheng 已提交
786
    TSDB_CHECK_CODE(code, lino, _exit);
787 788

    ASSERT(!rollback);
H
Hongze Cheng 已提交
789 790
  }

H
Hongze Cheng 已提交
791 792
  // scan and fix FS
  code = tsdbScanAndTryFixFS(pTsdb);
H
Hongze Cheng 已提交
793
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
794

H
Hongze Cheng 已提交
795 796
_exit:
  if (code) {
S
Shengliang Guan 已提交
797
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
798
  }
H
Hongze Cheng 已提交
799 800 801
  return code;
}

H
Hongze Cheng 已提交
802 803
int32_t tsdbFSClose(STsdb *pTsdb) {
  int32_t code = 0;
H
Hongze Cheng 已提交
804

H
Hongze Cheng 已提交
805
  if (pTsdb->fs.pDelFile) {
806
    ASSERT(pTsdb->fs.pDelFile->nRef == 1);
H
Hongze Cheng 已提交
807 808
    taosMemoryFree(pTsdb->fs.pDelFile);
  }
H
Hongze Cheng 已提交
809

H
Hongze Cheng 已提交
810 811
  for (int32_t iSet = 0; iSet < taosArrayGetSize(pTsdb->fs.aDFileSet); iSet++) {
    SDFileSet *pSet = (SDFileSet *)taosArrayGet(pTsdb->fs.aDFileSet, iSet);
H
Hongze Cheng 已提交
812

H
Hongze Cheng 已提交
813
    // head
814
    ASSERT(pSet->pHeadF->nRef == 1);
H
Hongze Cheng 已提交
815
    taosMemoryFree(pSet->pHeadF);
H
Hongze Cheng 已提交
816

H
Hongze Cheng 已提交
817
    // data
818
    ASSERT(pSet->pDataF->nRef == 1);
H
Hongze Cheng 已提交
819
    taosMemoryFree(pSet->pDataF);
H
Hongze Cheng 已提交
820

H
Hongze Cheng 已提交
821
    // sma
822
    ASSERT(pSet->pSmaF->nRef == 1);
H
Hongze Cheng 已提交
823
    taosMemoryFree(pSet->pSmaF);
H
Hongze Cheng 已提交
824

H
Hongze Cheng 已提交
825 826
    // stt
    for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
827
      ASSERT(pSet->aSttF[iStt]->nRef == 1);
H
Hongze Cheng 已提交
828
      taosMemoryFree(pSet->aSttF[iStt]);
H
Hongze Cheng 已提交
829
    }
H
Hongze Cheng 已提交
830 831
  }

H
Hongze Cheng 已提交
832
  taosArrayDestroy(pTsdb->fs.aDFileSet);
H
Hongze Cheng 已提交
833

H
Hongze Cheng 已提交
834 835 836 837 838
  return code;
}

int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS) {
  int32_t code = 0;
H
Hongze Cheng 已提交
839
  int32_t lino = 0;
H
Hongze Cheng 已提交
840 841

  pFS->pDelFile = NULL;
H
Hongze Cheng 已提交
842 843 844 845 846 847 848 849
  if (pFS->aDFileSet) {
    taosArrayClear(pFS->aDFileSet);
  } else {
    pFS->aDFileSet = taosArrayInit(taosArrayGetSize(pTsdb->fs.aDFileSet), sizeof(SDFileSet));
    if (pFS->aDFileSet == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
      TSDB_CHECK_CODE(code, lino, _exit);
    }
H
Hongze Cheng 已提交
850 851
  }

H
Hongze Cheng 已提交
852 853 854 855
  if (pTsdb->fs.pDelFile) {
    pFS->pDelFile = (SDelFile *)taosMemoryMalloc(sizeof(SDelFile));
    if (pFS->pDelFile == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
856
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
857
    }
H
Hongze Cheng 已提交
858

H
Hongze Cheng 已提交
859
    *pFS->pDelFile = *pTsdb->fs.pDelFile;
H
Hongze Cheng 已提交
860
  }
H
Hongze Cheng 已提交
861 862 863

  for (int32_t iSet = 0; iSet < taosArrayGetSize(pTsdb->fs.aDFileSet); iSet++) {
    SDFileSet *pSet = (SDFileSet *)taosArrayGet(pTsdb->fs.aDFileSet, iSet);
H
Hongze Cheng 已提交
864
    SDFileSet  fSet = {.diskId = pSet->diskId, .fid = pSet->fid};
H
Hongze Cheng 已提交
865 866 867 868 869

    // head
    fSet.pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile));
    if (fSet.pHeadF == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
870
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
871
    }
H
Hongze Cheng 已提交
872
    *fSet.pHeadF = *pSet->pHeadF;
H
Hongze Cheng 已提交
873 874 875 876 877

    // data
    fSet.pDataF = (SDataFile *)taosMemoryMalloc(sizeof(SDataFile));
    if (fSet.pDataF == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
878
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
879
    }
H
Hongze Cheng 已提交
880
    *fSet.pDataF = *pSet->pDataF;
H
Hongze Cheng 已提交
881

H
Hongze Cheng 已提交
882
    // sma
H
Hongze Cheng 已提交
883 884 885
    fSet.pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
    if (fSet.pSmaF == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
886
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
887
    }
H
Hongze Cheng 已提交
888
    *fSet.pSmaF = *pSet->pSmaF;
H
Hongze Cheng 已提交
889

H
Hongze Cheng 已提交
890 891 892 893
    // stt
    for (fSet.nSttF = 0; fSet.nSttF < pSet->nSttF; fSet.nSttF++) {
      fSet.aSttF[fSet.nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
      if (fSet.aSttF[fSet.nSttF] == NULL) {
H
Hongze Cheng 已提交
894
        code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
895
        TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
896
      }
H
Hongze Cheng 已提交
897
      *fSet.aSttF[fSet.nSttF] = *pSet->aSttF[fSet.nSttF];
H
Hongze Cheng 已提交
898
    }
H
Hongze Cheng 已提交
899 900 901

    if (taosArrayPush(pFS->aDFileSet, &fSet) == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
902
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
903
    }
H
Hongze Cheng 已提交
904 905 906
  }

_exit:
H
Hongze Cheng 已提交
907
  if (code) {
S
Shengliang Guan 已提交
908
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
909
  }
H
Hongze Cheng 已提交
910 911 912
  return code;
}

H
Hongze Cheng 已提交
913 914
int32_t tsdbFSUpsertDelFile(STsdbFS *pFS, SDelFile *pDelFile) {
  int32_t code = 0;
H
Hongze Cheng 已提交
915

H
Hongze Cheng 已提交
916
  if (pDelFile) {
H
Hongze Cheng 已提交
917
    if (pFS->pDelFile == NULL) {
H
Hongze Cheng 已提交
918 919 920 921 922 923 924 925 926 927 928
      pFS->pDelFile = (SDelFile *)taosMemoryMalloc(sizeof(SDelFile));
      if (pFS->pDelFile == NULL) {
        code = TSDB_CODE_OUT_OF_MEMORY;
        goto _exit;
      }
    }
    *pFS->pDelFile = *pDelFile;
  } else {
    if (pFS->pDelFile) {
      taosMemoryFree(pFS->pDelFile);
      pFS->pDelFile = NULL;
H
Hongze Cheng 已提交
929 930
    }
  }
H
Hongze Cheng 已提交
931 932 933

_exit:
  return code;
H
Hongze Cheng 已提交
934 935
}

H
Hongze Cheng 已提交
936 937 938 939 940 941 942 943 944 945 946 947 948
int32_t tsdbFSUpsertFSet(STsdbFS *pFS, SDFileSet *pSet) {
  int32_t code = 0;
  int32_t idx = taosArraySearchIdx(pFS->aDFileSet, pSet, tDFileSetCmprFn, TD_GE);

  if (idx < 0) {
    idx = taosArrayGetSize(pFS->aDFileSet);
  } else {
    SDFileSet *pDFileSet = (SDFileSet *)taosArrayGet(pFS->aDFileSet, idx);
    int32_t    c = tDFileSetCmprFn(pSet, pDFileSet);
    if (c == 0) {
      *pDFileSet->pHeadF = *pSet->pHeadF;
      *pDFileSet->pDataF = *pSet->pDataF;
      *pDFileSet->pSmaF = *pSet->pSmaF;
H
Hongze Cheng 已提交
949 950
      // stt
      if (pSet->nSttF > pDFileSet->nSttF) {
951
        ASSERT(pSet->nSttF == pDFileSet->nSttF + 1);
H
Hongze Cheng 已提交
952

H
Hongze Cheng 已提交
953 954
        pDFileSet->aSttF[pDFileSet->nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
        if (pDFileSet->aSttF[pDFileSet->nSttF] == NULL) {
H
Hongze Cheng 已提交
955 956 957
          code = TSDB_CODE_OUT_OF_MEMORY;
          goto _exit;
        }
H
Hongze Cheng 已提交
958 959 960
        *pDFileSet->aSttF[pDFileSet->nSttF] = *pSet->aSttF[pSet->nSttF - 1];
        pDFileSet->nSttF++;
      } else if (pSet->nSttF < pDFileSet->nSttF) {
961
        ASSERT(pSet->nSttF == 1);
H
Hongze Cheng 已提交
962 963
        for (int32_t iStt = 1; iStt < pDFileSet->nSttF; iStt++) {
          taosMemoryFree(pDFileSet->aSttF[iStt]);
H
Hongze Cheng 已提交
964 965
        }

H
Hongze Cheng 已提交
966 967
        *pDFileSet->aSttF[0] = *pSet->aSttF[0];
        pDFileSet->nSttF = 1;
H
Hongze Cheng 已提交
968
      } else {
H
Hongze Cheng 已提交
969 970
        for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
          *pDFileSet->aSttF[iStt] = *pSet->aSttF[iStt];
H
Hongze Cheng 已提交
971
        }
H
Hongze Cheng 已提交
972
      }
H
Hongze Cheng 已提交
973

K
kailixu 已提交
974
      pDFileSet->diskId = pSet->diskId;
H
Hongze Cheng 已提交
975 976 977 978
      goto _exit;
    }
  }

979
  ASSERT(pSet->nSttF == 1);
H
Hongze Cheng 已提交
980
  SDFileSet fSet = {.diskId = pSet->diskId, .fid = pSet->fid, .nSttF = 1};
H
Hongze Cheng 已提交
981 982 983 984

  // head
  fSet.pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile));
  if (fSet.pHeadF == NULL) {
H
Hongze Cheng 已提交
985
    code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
986
    goto _exit;
H
Hongze Cheng 已提交
987
  }
H
Hongze Cheng 已提交
988
  *fSet.pHeadF = *pSet->pHeadF;
H
Hongze Cheng 已提交
989

H
Hongze Cheng 已提交
990 991 992
  // data
  fSet.pDataF = (SDataFile *)taosMemoryMalloc(sizeof(SDataFile));
  if (fSet.pDataF == NULL) {
H
Hongze Cheng 已提交
993
    code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
994
    goto _exit;
H
Hongze Cheng 已提交
995
  }
H
Hongze Cheng 已提交
996 997
  *fSet.pDataF = *pSet->pDataF;

H
Hongze Cheng 已提交
998
  // sma
H
Hongze Cheng 已提交
999 1000
  fSet.pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
  if (fSet.pSmaF == NULL) {
H
Hongze Cheng 已提交
1001
    code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
1002
    goto _exit;
H
Hongze Cheng 已提交
1003
  }
H
Hongze Cheng 已提交
1004 1005
  *fSet.pSmaF = *pSet->pSmaF;

H
Hongze Cheng 已提交
1006 1007 1008
  // stt
  fSet.aSttF[0] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
  if (fSet.aSttF[0] == NULL) {
H
Hongze Cheng 已提交
1009 1010 1011
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
  }
H
Hongze Cheng 已提交
1012
  *fSet.aSttF[0] = *pSet->aSttF[0];
H
Hongze Cheng 已提交
1013

H
Hongze Cheng 已提交
1014
  if (taosArrayInsert(pFS->aDFileSet, idx, &fSet) == NULL) {
H
Hongze Cheng 已提交
1015
    code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
1016 1017 1018 1019 1020 1021
    goto _exit;
  }

_exit:
  return code;
}
1022

H
Hongze Cheng 已提交
1023
int32_t tsdbFSPrepareCommit(STsdb *pTsdb, STsdbFS *pFSNew) {
1024
  int32_t code = 0;
H
Hongze Cheng 已提交
1025
  int32_t lino = 0;
1026
  char    tfname[TSDB_FILENAME_LEN];
1027

1028
  tsdbGetCurrentFName(pTsdb, NULL, tfname);
1029

1030 1031
  // gnrt CURRENT.t
  code = tsdbSaveFSToFile(pFSNew, tfname);
H
Hongze Cheng 已提交
1032
  TSDB_CHECK_CODE(code, lino, _exit);
1033

H
Hongze Cheng 已提交
1034
_exit:
1035
  if (code) {
S
Shengliang Guan 已提交
1036
    tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
1037 1038 1039 1040
  }
  return code;
}

C
Cary Xu 已提交
1041
int32_t tsdbFSRef(STsdb *pTsdb, STsdbFS *pFS) {
H
Hongze Cheng 已提交
1042
  int32_t code = 0;
H
Hongze Cheng 已提交
1043
  int32_t nRef;
H
Hongze Cheng 已提交
1044

H
Hongze Cheng 已提交
1045 1046 1047 1048
  pFS->aDFileSet = taosArrayInit(taosArrayGetSize(pTsdb->fs.aDFileSet), sizeof(SDFileSet));
  if (pFS->aDFileSet == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
H
Hongze Cheng 已提交
1049 1050
  }

H
Hongze Cheng 已提交
1051 1052 1053
  pFS->pDelFile = pTsdb->fs.pDelFile;
  if (pFS->pDelFile) {
    nRef = atomic_fetch_add_32(&pFS->pDelFile->nRef, 1);
1054
    ASSERT(nRef > 0);
H
Hongze Cheng 已提交
1055 1056
  }

H
Hongze Cheng 已提交
1057 1058 1059 1060
  SDFileSet fSet;
  for (int32_t iSet = 0; iSet < taosArrayGetSize(pTsdb->fs.aDFileSet); iSet++) {
    SDFileSet *pSet = (SDFileSet *)taosArrayGet(pTsdb->fs.aDFileSet, iSet);
    fSet = *pSet;
H
Hongze Cheng 已提交
1061

H
Hongze Cheng 已提交
1062
    nRef = atomic_fetch_add_32(&pSet->pHeadF->nRef, 1);
1063
    ASSERT(nRef > 0);
H
Hongze Cheng 已提交
1064

H
Hongze Cheng 已提交
1065
    nRef = atomic_fetch_add_32(&pSet->pDataF->nRef, 1);
1066
    ASSERT(nRef > 0);
H
Hongze Cheng 已提交
1067

H
Hongze Cheng 已提交
1068
    nRef = atomic_fetch_add_32(&pSet->pSmaF->nRef, 1);
1069
    ASSERT(nRef > 0);
H
Hongze Cheng 已提交
1070

H
Hongze Cheng 已提交
1071 1072
    for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
      nRef = atomic_fetch_add_32(&pSet->aSttF[iStt]->nRef, 1);
1073
      ASSERT(nRef > 0);
H
Hongze Cheng 已提交
1074 1075
    }

H
Hongze Cheng 已提交
1076
    if (taosArrayPush(pFS->aDFileSet, &fSet) == NULL) {
H
Hongze Cheng 已提交
1077
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
1078
      goto _exit;
H
Hongze Cheng 已提交
1079 1080 1081
    }
  }

H
Hongze Cheng 已提交
1082
_exit:
H
Hongze Cheng 已提交
1083 1084 1085
  return code;
}

H
Hongze Cheng 已提交
1086 1087 1088
void tsdbFSUnref(STsdb *pTsdb, STsdbFS *pFS) {
  int32_t nRef;
  char    fname[TSDB_FILENAME_LEN];
H
Hongze Cheng 已提交
1089

H
Hongze Cheng 已提交
1090 1091
  if (pFS->pDelFile) {
    nRef = atomic_sub_fetch_32(&pFS->pDelFile->nRef, 1);
1092
    ASSERT(nRef >= 0);
H
Hongze Cheng 已提交
1093 1094
    if (nRef == 0) {
      tsdbDelFileName(pTsdb, pFS->pDelFile, fname);
H
Hongze Cheng 已提交
1095
      (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
1096 1097
      taosMemoryFree(pFS->pDelFile);
    }
H
Hongze Cheng 已提交
1098 1099
  }

H
Hongze Cheng 已提交
1100 1101
  for (int32_t iSet = 0; iSet < taosArrayGetSize(pFS->aDFileSet); iSet++) {
    SDFileSet *pSet = (SDFileSet *)taosArrayGet(pFS->aDFileSet, iSet);
H
Hongze Cheng 已提交
1102

H
Hongze Cheng 已提交
1103 1104
    // head
    nRef = atomic_sub_fetch_32(&pSet->pHeadF->nRef, 1);
1105
    ASSERT(nRef >= 0);
H
Hongze Cheng 已提交
1106 1107
    if (nRef == 0) {
      tsdbHeadFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pHeadF, fname);
H
Hongze Cheng 已提交
1108
      (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
1109 1110
      taosMemoryFree(pSet->pHeadF);
    }
H
Hongze Cheng 已提交
1111

H
Hongze Cheng 已提交
1112 1113
    // data
    nRef = atomic_sub_fetch_32(&pSet->pDataF->nRef, 1);
1114
    ASSERT(nRef >= 0);
H
Hongze Cheng 已提交
1115 1116
    if (nRef == 0) {
      tsdbDataFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pDataF, fname);
H
Hongze Cheng 已提交
1117
      (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
1118 1119
      taosMemoryFree(pSet->pDataF);
    }
H
Hongze Cheng 已提交
1120

H
Hongze Cheng 已提交
1121 1122
    // sma
    nRef = atomic_sub_fetch_32(&pSet->pSmaF->nRef, 1);
1123
    ASSERT(nRef >= 0);
H
Hongze Cheng 已提交
1124 1125
    if (nRef == 0) {
      tsdbSmaFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pSmaF, fname);
H
Hongze Cheng 已提交
1126
      (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
1127
      taosMemoryFree(pSet->pSmaF);
H
Hongze Cheng 已提交
1128
    }
H
Hongze Cheng 已提交
1129

H
Hongze Cheng 已提交
1130 1131 1132
    // stt
    for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
      nRef = atomic_sub_fetch_32(&pSet->aSttF[iStt]->nRef, 1);
1133
      ASSERT(nRef >= 0);
H
Hongze Cheng 已提交
1134
      if (nRef == 0) {
H
Hongze Cheng 已提交
1135
        tsdbSttFileName(pTsdb, pSet->diskId, pSet->fid, pSet->aSttF[iStt], fname);
H
Hongze Cheng 已提交
1136
        (void)taosRemoveFile(fname);
H
Hongze Cheng 已提交
1137
        taosMemoryFree(pSet->aSttF[iStt]);
H
Hongze Cheng 已提交
1138 1139 1140
        /* code */
      }
    }
H
Hongze Cheng 已提交
1141 1142
  }

H
Hongze Cheng 已提交
1143
  taosArrayDestroy(pFS->aDFileSet);
1144
}