tsdbFS.c 38.7 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 "vnodeInt.h"
H
Hongze Cheng 已提交
17

H
Hongze Cheng 已提交
18 19
typedef enum { TSDB_TXN_TEMP_FILE = 0, TSDB_TXN_CURR_FILE } TSDB_TXN_FILE_T;
static const char *tsdbTxnFname[] = {"current.t", "current"};
H
Hongze Cheng 已提交
20
#define TSDB_MAX_FSETS(keep, days) ((keep) / (days) + 3)
H
Hongze Cheng 已提交
21

H
Hongze Cheng 已提交
22 23
static int  tsdbComparFidFSet(const void *arg1, const void *arg2);
static void tsdbResetFSStatus(SFSStatus *pStatus);
S
Shengliang Guan 已提交
24
static int  tsdbSaveFSStatus(STsdb *pRepo, SFSStatus *pStatus);
H
Hongze Cheng 已提交
25
static void tsdbApplyFSTxnOnDisk(SFSStatus *pFrom, SFSStatus *pTo);
S
Shengliang Guan 已提交
26
static void tsdbGetTxnFname(STsdb *pRepo, TSDB_TXN_FILE_T ftype, char fname[]);
H
Hongze Cheng 已提交
27 28 29 30
static int  tsdbOpenFSFromCurrent(STsdb *pRepo);
static int  tsdbScanAndTryFixFS(STsdb *pRepo);
static int  tsdbScanRootDir(STsdb *pRepo);
static int  tsdbScanDataDir(STsdb *pRepo);
S
Shengliang Guan 已提交
31
static bool tsdbIsTFileInFS(STsdbFS *pfs, const STfsFile *pf);
H
Hongze Cheng 已提交
32
static int  tsdbRestoreCurrent(STsdb *pRepo);
H
Hongze Cheng 已提交
33
static int  tsdbComparTFILE(const void *arg1, const void *arg2);
H
Hongze Cheng 已提交
34
static void tsdbScanAndTryFixDFilesHeader(STsdb *pRepo, int32_t *nExpired);
H
Hongze Cheng 已提交
35 36 37 38 39 40 41 42 43 44
// static int  tsdbProcessExpiredFS(STsdb *pRepo);
// static int  tsdbCreateMeta(STsdb *pRepo);

static void tsdbGetRootDir(int repoid, char dirName[]) {
  snprintf(dirName, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb", repoid);
}

static void tsdbGetDataDir(int repoid, char dirName[]) {
  snprintf(dirName, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/data", repoid);
}
H
Hongze Cheng 已提交
45

46
// For backward compatibility
H
Hongze Cheng 已提交
47 48 49 50 51 52 53 54 55 56
// ================== CURRENT file header info
static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) {
  int tlen = 0;

  tlen += taosEncodeFixedU32(buf, pHeader->version);
  tlen += taosEncodeFixedU32(buf, pHeader->len);

  return tlen;
}

H
Hongze Cheng 已提交
57
static void *tsdbDecodeFSHeader(void *buf, SFSHeader *pHeader) {
H
Hongze Cheng 已提交
58 59
  buf = taosDecodeFixedU32(buf, &(pHeader->version));
  buf = taosDecodeFixedU32(buf, &(pHeader->len));
H
Hongze Cheng 已提交
60 61 62 63 64 65 66 67

  return buf;
}

// ================== STsdbFSMeta
static int tsdbEncodeFSMeta(void **buf, STsdbFSMeta *pMeta) {
  int tlen = 0;

H
Hongze Cheng 已提交
68
  tlen += taosEncodeFixedU32(buf, pMeta->version);
H
Hongze Cheng 已提交
69 70 71 72 73 74
  tlen += taosEncodeFixedI64(buf, pMeta->totalPoints);
  tlen += taosEncodeFixedI64(buf, pMeta->totalStorage);

  return tlen;
}

H
Hongze Cheng 已提交
75
static void *tsdbDecodeFSMeta(void *buf, STsdbFSMeta *pMeta) {
H
Hongze Cheng 已提交
76
  buf = taosDecodeFixedU32(buf, &(pMeta->version));
H
Hongze Cheng 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
  buf = taosDecodeFixedI64(buf, &(pMeta->totalPoints));
  buf = taosDecodeFixedI64(buf, &(pMeta->totalStorage));

  return buf;
}

// ================== SFSStatus
static int tsdbEncodeDFileSetArray(void **buf, SArray *pArray) {
  int      tlen = 0;
  uint64_t nset = taosArrayGetSize(pArray);

  tlen += taosEncodeFixedU64(buf, nset);
  for (size_t i = 0; i < nset; i++) {
    SDFileSet *pSet = taosArrayGet(pArray, i);

    tlen += tsdbEncodeDFileSet(buf, pSet);
  }

  return tlen;
}

H
Hongze Cheng 已提交
98 99
static void *tsdbDecodeDFileSetArray(STsdb *pRepo, void *buf, SArray *pArray) {
  uint64_t nset = 0;
H
Hongze Cheng 已提交
100 101 102 103 104

  taosArrayClear(pArray);

  buf = taosDecodeFixedU64(buf, &nset);
  for (size_t i = 0; i < nset; i++) {
C
update  
Cary Xu 已提交
105
    SDFileSet dset = {0};
S
Shengliang Guan 已提交
106
    buf = tsdbDecodeDFileSet(pRepo, buf, &dset);
H
Hongze Cheng 已提交
107 108 109 110 111 112
    taosArrayPush(pArray, (void *)(&dset));
  }
  return buf;
}

static int tsdbEncodeFSStatus(void **buf, SFSStatus *pStatus) {
H
Hongze Cheng 已提交
113
  // ASSERT(pStatus->pmf);
H
Hongze Cheng 已提交
114

H
Hongze Cheng 已提交
115 116
  int tlen = 0;

H
Hongze Cheng 已提交
117
  // tlen += tsdbEncodeSMFile(buf, pStatus->pmf);
H
Hongze Cheng 已提交
118 119 120 121 122
  tlen += tsdbEncodeDFileSetArray(buf, pStatus->df);

  return tlen;
}

H
Hongze Cheng 已提交
123
static void *tsdbDecodeFSStatus(STsdb *pRepo, void *buf, SFSStatus *pStatus) {
H
Hongze Cheng 已提交
124 125
  tsdbResetFSStatus(pStatus);

H
Hongze Cheng 已提交
126
  // pStatus->pmf = &(pStatus->mf);
H
Hongze Cheng 已提交
127

H
Hongze Cheng 已提交
128
  // buf = tsdbDecodeSMFile(buf, pStatus->pmf);
S
Shengliang Guan 已提交
129
  buf = tsdbDecodeDFileSetArray(pRepo, buf, pStatus->df);
H
Hongze Cheng 已提交
130 131 132 133 134

  return buf;
}

static SFSStatus *tsdbNewFSStatus(int maxFSet) {
wafwerar's avatar
wafwerar 已提交
135
  SFSStatus *pStatus = (SFSStatus *)taosMemoryCalloc(1, sizeof(*pStatus));
H
Hongze Cheng 已提交
136 137 138 139 140
  if (pStatus == NULL) {
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
    return NULL;
  }

H
Hongze Cheng 已提交
141
  // TSDB_FILE_SET_CLOSED(&(pStatus->mf));
H
Hongze Cheng 已提交
142

H
Hongze Cheng 已提交
143
  pStatus->df = taosArrayInit(maxFSet, sizeof(SDFileSet));
H
Hongze Cheng 已提交
144
  if (pStatus->df == NULL) {
H
Hongze Cheng 已提交
145
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
wafwerar's avatar
wafwerar 已提交
146
    taosMemoryFree(pStatus);
H
Hongze Cheng 已提交
147 148 149 150 151 152 153 154 155
    return NULL;
  }

  return pStatus;
}

static SFSStatus *tsdbFreeFSStatus(SFSStatus *pStatus) {
  if (pStatus) {
    pStatus->df = taosArrayDestroy(pStatus->df);
wafwerar's avatar
wafwerar 已提交
156
    taosMemoryFree(pStatus);
H
Hongze Cheng 已提交
157 158 159 160 161 162 163 164 165 166
  }

  return NULL;
}

static void tsdbResetFSStatus(SFSStatus *pStatus) {
  if (pStatus == NULL) {
    return;
  }

H
Hongze Cheng 已提交
167
  // TSDB_FILE_SET_CLOSED(&(pStatus->mf));
H
Hongze Cheng 已提交
168

H
Hongze Cheng 已提交
169
  // pStatus->pmf = NULL;
H
Hongze Cheng 已提交
170 171 172
  taosArrayClear(pStatus->df);
}

H
Hongze Cheng 已提交
173 174
// static void tsdbSetStatusMFile(SFSStatus *pStatus, const SMFile *pMFile) {
//   ASSERT(pStatus->pmf == NULL);
H
Hongze Cheng 已提交
175

H
Hongze Cheng 已提交
176 177 178
//   pStatus->pmf = &(pStatus->mf);
//   tsdbInitMFileEx(pStatus->pmf, (SMFile *)pMFile);
// }
H
Hongze Cheng 已提交
179 180

static int tsdbAddDFileSetToStatus(SFSStatus *pStatus, const SDFileSet *pSet) {
H
Hongze Cheng 已提交
181
  if (taosArrayPush(pStatus->df, (void *)pSet) == NULL) {
H
Hongze Cheng 已提交
182 183 184 185
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
    return -1;
  }

H
refact  
Hongze Cheng 已提交
186 187
  TSDB_FSET_SET_CLOSED(((SDFileSet *)taosArrayGetLast(pStatus->df)));

H
Hongze Cheng 已提交
188 189 190
  return 0;
}

H
Hongze Cheng 已提交
191
// ================== STsdbFS
H
more  
Hongze Cheng 已提交
192
STsdbFS *tsdbNewFS(const STsdbCfg *pCfg) {
H
Hongze Cheng 已提交
193 194
  int      keep = pCfg->keep;
  int      days = pCfg->daysPerFile;
H
Hongze Cheng 已提交
195 196 197
  int      maxFSet = TSDB_MAX_FSETS(keep, days);
  STsdbFS *pfs;

wafwerar's avatar
wafwerar 已提交
198
  pfs = (STsdbFS *)taosMemoryCalloc(1, sizeof(*pfs));
H
Hongze Cheng 已提交
199
  if (pfs == NULL) {
H
Hongze Cheng 已提交
200 201 202 203
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
204
  int code = taosThreadRwlockInit(&(pfs->lock), NULL);
H
Hongze Cheng 已提交
205 206
  if (code) {
    terrno = TAOS_SYSTEM_ERROR(code);
wafwerar's avatar
wafwerar 已提交
207
    taosMemoryFree(pfs);
H
Hongze Cheng 已提交
208 209 210
    return NULL;
  }

H
Hongze Cheng 已提交
211 212 213
  pfs->cstatus = tsdbNewFSStatus(maxFSet);
  if (pfs->cstatus == NULL) {
    tsdbFreeFS(pfs);
H
Hongze Cheng 已提交
214 215 216
    return NULL;
  }

H
Hongze Cheng 已提交
217 218
  pfs->metaCache = taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
  if (pfs->metaCache == NULL) {
H
Hongze Cheng 已提交
219
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
220
    tsdbFreeFS(pfs);
H
Hongze Cheng 已提交
221 222 223
    return NULL;
  }

224
  pfs->intxn = false;
225
  pfs->metaCacheComp = NULL;
226

H
Hongze Cheng 已提交
227 228 229
  pfs->nstatus = tsdbNewFSStatus(maxFSet);
  if (pfs->nstatus == NULL) {
    tsdbFreeFS(pfs);
H
Hongze Cheng 已提交
230 231 232
    return NULL;
  }

H
Hongze Cheng 已提交
233
  return pfs;
H
Hongze Cheng 已提交
234 235
}

H
Hongze Cheng 已提交
236 237 238 239 240 241
void *tsdbFreeFS(STsdbFS *pfs) {
  if (pfs) {
    pfs->nstatus = tsdbFreeFSStatus(pfs->nstatus);
    taosHashCleanup(pfs->metaCache);
    pfs->metaCache = NULL;
    pfs->cstatus = tsdbFreeFSStatus(pfs->cstatus);
wafwerar's avatar
wafwerar 已提交
242
    taosThreadRwlockDestroy(&(pfs->lock));
wafwerar's avatar
wafwerar 已提交
243
    taosMemoryFree(pfs);
H
Hongze Cheng 已提交
244
  }
H
Hongze Cheng 已提交
245

H
Hongze Cheng 已提交
246 247 248
  return NULL;
}

H
Hongze Cheng 已提交
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
// static int tsdbProcessExpiredFS(STsdb *pRepo) {
//   tsdbStartFSTxn(pRepo, 0, 0);
//   // if (tsdbCreateMeta(pRepo) < 0) {
//   //   tsdbError("vgId:%d failed to create meta since %s", REPO_ID(pRepo), tstrerror(terrno));
//   //   return -1;
//   // }

//   if (tsdbApplyRtn(pRepo) < 0) {
//     tsdbEndFSTxnWithError(REPO_FS(pRepo));
//     tsdbError("vgId:%d failed to apply rtn since %s", REPO_ID(pRepo), tstrerror(terrno));
//     return -1;
//   }
//   if (tsdbEndFSTxn(pRepo) < 0) {
//     tsdbError("vgId:%d failed to end fs txn since %s", REPO_ID(pRepo), tstrerror(terrno));
//     return -1;
//   }
//   return 0;
// }

// static int tsdbCreateMeta(STsdb *pRepo) {
//   STsdbFS *pfs = REPO_FS(pRepo);
//   SMFile * pOMFile = pfs->cstatus->pmf;
//   SMFile   mf;
//   SDiskID  did;

//   if (pOMFile != NULL) {
//     // keep the old meta file
//     tsdbUpdateMFile(pfs, pOMFile);
//     return 0;
//   }

//   // Create a new meta file
//   did.level = TFS_PRIMARY_LEVEL;
//   did.id = TFS_PRIMARY_ID;
//   tsdbInitMFile(&mf, did, REPO_ID(pRepo), FS_TXN_VERSION(REPO_FS(pRepo)));

//   if (tsdbCreateMFile(&mf, true) < 0) {
//     tsdbError("vgId:%d failed to create META file since %s", REPO_ID(pRepo), tstrerror(terrno));
//     return -1;
//   }

//   tsdbInfo("vgId:%d meta file %s is created", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(&mf));

//   if (tsdbUpdateMFileHeader(&mf) < 0) {
//     tsdbError("vgId:%d failed to update META file header since %s, revert it", REPO_ID(pRepo), tstrerror(terrno));
//     tsdbApplyMFileChange(&mf, pOMFile);
//     return -1;
//   }

//   TSDB_FILE_FSYNC(&mf);
//   tsdbCloseMFile(&mf);
//   tsdbUpdateMFile(pfs, &mf);

//   return 0;
// }
304

H
Hongze Cheng 已提交
305
int tsdbOpenFS(STsdb *pRepo) {
H
refact  
Hongze Cheng 已提交
306 307
  STsdbFS *pfs = REPO_FS(pRepo);
  char     current[TSDB_FILENAME_LEN] = "\0";
308
  int      nExpired = 0;
H
Hongze Cheng 已提交
309 310 311

  ASSERT(pfs != NULL);

S
Shengliang Guan 已提交
312
  tsdbGetTxnFname(pRepo, TSDB_TXN_CURR_FILE, current);
H
Hongze Cheng 已提交
313

314
  tsdbGetRtnSnap(pRepo, &pRepo->rtn);
315
  if (taosCheckExistFile(current)) {
H
Hongze Cheng 已提交
316 317 318 319
    if (tsdbOpenFSFromCurrent(pRepo) < 0) {
      tsdbError("vgId:%d failed to open FS since %s", REPO_ID(pRepo), tstrerror(terrno));
      return -1;
    }
H
Hongze Cheng 已提交
320

321
    tsdbScanAndTryFixDFilesHeader(pRepo, &nExpired);
H
Hongze Cheng 已提交
322 323 324
    // if (nExpired > 0) {
    //   tsdbProcessExpiredFS(pRepo);
    // }
H
refact  
Hongze Cheng 已提交
325
  } else {
326
    // should skip expired fileset inside of the function
H
refact  
Hongze Cheng 已提交
327 328 329 330 331 332 333 334 335
    if (tsdbRestoreCurrent(pRepo) < 0) {
      tsdbError("vgId:%d failed to restore current file since %s", REPO_ID(pRepo), tstrerror(terrno));
      return -1;
    }
  }

  if (tsdbScanAndTryFixFS(pRepo) < 0) {
    tsdbError("vgId:%d failed to scan and fix FS since %s", REPO_ID(pRepo), tstrerror(terrno));
    return -1;
H
Hongze Cheng 已提交
336
  }
H
Hongze Cheng 已提交
337

H
Hongze Cheng 已提交
338 339 340 341 342
  // // Load meta cache if has meta file
  // if ((!(pRepo->state & TSDB_STATE_BAD_META)) && tsdbLoadMetaCache(pRepo, true) < 0) {
  //   tsdbError("vgId:%d failed to open FS while loading meta cache since %s", REPO_ID(pRepo), tstrerror(terrno));
  //   return -1;
  // }
H
Hongze Cheng 已提交
343

H
Hongze Cheng 已提交
344 345 346
  return 0;
}

H
Hongze Cheng 已提交
347
void tsdbCloseFS(STsdb *pRepo) {
H
refact  
Hongze Cheng 已提交
348
  // Do nothing
H
Hongze Cheng 已提交
349 350
}

H
Hongze Cheng 已提交
351
// Start a new transaction to modify the file system
H
Hongze Cheng 已提交
352
void tsdbStartFSTxn(STsdb *pRepo, int64_t pointsAdd, int64_t storageAdd) {
H
Hongze Cheng 已提交
353
  STsdbFS *pfs = REPO_FS(pRepo);
H
Hongze Cheng 已提交
354
  ASSERT(pfs->intxn == false);
H
Hongze Cheng 已提交
355

H
Hongze Cheng 已提交
356 357
  pfs->intxn = true;
  tsdbResetFSStatus(pfs->nstatus);
H
Hongze Cheng 已提交
358
  pfs->nstatus->meta = pfs->cstatus->meta;
H
Hongze Cheng 已提交
359
  // if (pfs->cstatus->pmf == NULL) {
H
Hongze Cheng 已提交
360
  pfs->nstatus->meta.version += 1;
H
Hongze Cheng 已提交
361 362 363
  // } else {
  //   pfs->nstatus->meta.version = pfs->cstatus->meta.version + 1;
  // }
H
Hongze Cheng 已提交
364
  pfs->nstatus->meta.totalPoints = pfs->cstatus->meta.totalPoints + pointsAdd;
H
Hongze Cheng 已提交
365
  pfs->nstatus->meta.totalStorage = pfs->cstatus->meta.totalStorage += storageAdd;
H
Hongze Cheng 已提交
366
}
H
Hongze Cheng 已提交
367

H
Hongze Cheng 已提交
368 369
void tsdbUpdateFSTxnMeta(STsdbFS *pfs, STsdbFSMeta *pMeta) { pfs->nstatus->meta = *pMeta; }

H
Hongze Cheng 已提交
370
int tsdbEndFSTxn(STsdb *pRepo) {
H
Hongze Cheng 已提交
371
  STsdbFS *pfs = REPO_FS(pRepo);
H
Hongze Cheng 已提交
372 373
  ASSERT(FS_IN_TXN(pfs));
  SFSStatus *pStatus;
H
Hongze Cheng 已提交
374

H
Hongze Cheng 已提交
375
  // Write current file system snapshot
S
Shengliang Guan 已提交
376
  if (tsdbSaveFSStatus(pRepo, pfs->nstatus) < 0) {
H
Hongze Cheng 已提交
377
    tsdbEndFSTxnWithError(pfs);
H
Hongze Cheng 已提交
378 379
    return -1;
  }
H
Hongze Cheng 已提交
380

H
Hongze Cheng 已提交
381
  // Make new
H
Hongze Cheng 已提交
382 383 384 385 386
  tsdbWLockFS(pfs);
  pStatus = pfs->cstatus;
  pfs->cstatus = pfs->nstatus;
  pfs->nstatus = pStatus;
  tsdbUnLockFS(pfs);
H
Hongze Cheng 已提交
387

H
Hongze Cheng 已提交
388
  // Apply actual change to each file and SDFileSet
H
Hongze Cheng 已提交
389
  tsdbApplyFSTxnOnDisk(pfs->nstatus, pfs->cstatus);
H
Hongze Cheng 已提交
390

H
Hongze Cheng 已提交
391
  pfs->intxn = false;
H
Hongze Cheng 已提交
392 393 394
  return 0;
}

H
Hongze Cheng 已提交
395
int tsdbEndFSTxnWithError(STsdbFS *pfs) {
H
Hongze Cheng 已提交
396 397
  tsdbApplyFSTxnOnDisk(pfs->nstatus, pfs->cstatus);
  // TODO: if mf change, reload pfs->metaCache
H
Hongze Cheng 已提交
398 399
  pfs->intxn = false;
  return 0;
H
Hongze Cheng 已提交
400 401
}

H
Hongze Cheng 已提交
402
// void tsdbUpdateMFile(STsdbFS *pfs, const SMFile *pMFile) { tsdbSetStatusMFile(pfs->nstatus, pMFile); }
H
Hongze Cheng 已提交
403

H
Hongze Cheng 已提交
404
int tsdbUpdateDFileSet(STsdbFS *pfs, const SDFileSet *pSet) { return tsdbAddDFileSetToStatus(pfs->nstatus, pSet); }
H
Hongze Cheng 已提交
405

S
Shengliang Guan 已提交
406
static int tsdbSaveFSStatus(STsdb *pRepo, SFSStatus *pStatus) {
H
Hongze Cheng 已提交
407
  SFSHeader fsheader;
H
Hongze Cheng 已提交
408 409
  void     *pBuf = NULL;
  void     *ptr;
H
Hongze Cheng 已提交
410
  char      hbuf[TSDB_FILE_HEAD_SIZE] = "\0";
H
Hongze Cheng 已提交
411 412
  char      tfname[TSDB_FILENAME_LEN] = "\0";
  char      cfname[TSDB_FILENAME_LEN] = "\0";
H
Hongze Cheng 已提交
413

S
Shengliang Guan 已提交
414 415
  tsdbGetTxnFname(pRepo, TSDB_TXN_TEMP_FILE, tfname);
  tsdbGetTxnFname(pRepo, TSDB_TXN_CURR_FILE, cfname);
H
Hongze Cheng 已提交
416

417
  TdFilePtr pFile = taosOpenFile(tfname, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
418
  if (pFile == NULL) {
H
Hongze Cheng 已提交
419
    terrno = TAOS_SYSTEM_ERROR(errno);
H
Hongze Cheng 已提交
420 421 422
    return -1;
  }

423
  fsheader.version = TSDB_LATEST_SFS_VER;
H
Hongze Cheng 已提交
424
  if (taosArrayGetSize(pStatus->df) == 0) {
H
Hongze Cheng 已提交
425 426
    fsheader.len = 0;
  } else {
H
Hongze Cheng 已提交
427
    fsheader.len = tsdbEncodeFSStatus(NULL, pStatus) + sizeof(TSCKSUM);
H
Hongze Cheng 已提交
428 429
  }

H
Hongze Cheng 已提交
430 431 432
  // Encode header part and write
  ptr = hbuf;
  tsdbEncodeFSHeader(&ptr, &fsheader);
H
Hongze Cheng 已提交
433
  tsdbEncodeFSMeta(&ptr, &(pStatus->meta));
H
Hongze Cheng 已提交
434

H
Hongze Cheng 已提交
435
  taosCalcChecksumAppend(0, (uint8_t *)hbuf, TSDB_FILE_HEAD_SIZE);
H
Hongze Cheng 已提交
436

437
  if (taosWriteFile(pFile, hbuf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
H
Hongze Cheng 已提交
438
    terrno = TAOS_SYSTEM_ERROR(errno);
439
    taosCloseFile(&pFile);
440
    taosRemoveFile(tfname);
H
Hongze Cheng 已提交
441 442 443
    return -1;
  }

H
Hongze Cheng 已提交
444 445 446
  // Encode file status and write to file
  if (fsheader.len > 0) {
    if (tsdbMakeRoom(&(pBuf), fsheader.len) < 0) {
447
      taosCloseFile(&pFile);
448
      taosRemoveFile(tfname);
H
Hongze Cheng 已提交
449
      return -1;
H
Hongze Cheng 已提交
450 451
    }

H
Hongze Cheng 已提交
452
    ptr = pBuf;
H
Hongze Cheng 已提交
453
    tsdbEncodeFSStatus(&ptr, pStatus);
H
Hongze Cheng 已提交
454
    taosCalcChecksumAppend(0, (uint8_t *)pBuf, fsheader.len);
H
Hongze Cheng 已提交
455

456
    if (taosWriteFile(pFile, pBuf, fsheader.len) < fsheader.len) {
H
Hongze Cheng 已提交
457
      terrno = TAOS_SYSTEM_ERROR(errno);
458
      taosCloseFile(&pFile);
459
      (void)taosRemoveFile(tfname);
H
Hongze Cheng 已提交
460
      taosTZfree(pBuf);
H
Hongze Cheng 已提交
461 462 463 464
      return -1;
    }
  }

H
Hongze Cheng 已提交
465
  // fsync, close and rename
466
  if (taosFsyncFile(pFile) < 0) {
H
Hongze Cheng 已提交
467
    terrno = TAOS_SYSTEM_ERROR(errno);
468
    taosCloseFile(&pFile);
469
    taosRemoveFile(tfname);
H
Hongze Cheng 已提交
470 471
    taosTZfree(pBuf);
    return -1;
H
Hongze Cheng 已提交
472
  }
H
Hongze Cheng 已提交
473

474
  (void)taosCloseFile(&pFile);
H
Hongze Cheng 已提交
475
  (void)taosRenameFile(tfname, cfname);
H
Hongze Cheng 已提交
476
  taosTZfree(pBuf);
H
Hongze Cheng 已提交
477

H
Hongze Cheng 已提交
478 479
  return 0;
}
H
Hongze Cheng 已提交
480

H
Hongze Cheng 已提交
481
static void tsdbApplyFSTxnOnDisk(SFSStatus *pFrom, SFSStatus *pTo) {
H
Hongze Cheng 已提交
482 483 484 485 486
  int        ifrom = 0;
  int        ito = 0;
  size_t     sizeFrom, sizeTo;
  SDFileSet *pSetFrom;
  SDFileSet *pSetTo;
H
Hongze Cheng 已提交
487

H
Hongze Cheng 已提交
488 489
  sizeFrom = taosArrayGetSize(pFrom->df);
  sizeTo = taosArrayGetSize(pTo->df);
H
Hongze Cheng 已提交
490

H
Hongze Cheng 已提交
491
  // Apply meta file change
H
Hongze Cheng 已提交
492
  // (void)tsdbApplyMFileChange(pFrom->pmf, pTo->pmf);
H
Hongze Cheng 已提交
493

H
Hongze Cheng 已提交
494 495 496
  // Apply SDFileSet change
  if (ifrom >= sizeFrom) {
    pSetFrom = NULL;
H
Hongze Cheng 已提交
497
  } else {
H
Hongze Cheng 已提交
498
    pSetFrom = taosArrayGet(pFrom->df, ifrom);
H
Hongze Cheng 已提交
499 500
  }

H
Hongze Cheng 已提交
501 502 503 504 505
  if (ito >= sizeTo) {
    pSetTo = NULL;
  } else {
    pSetTo = taosArrayGet(pTo->df, ito);
  }
H
Hongze Cheng 已提交
506

H
Hongze Cheng 已提交
507 508
  while (true) {
    if ((pSetTo == NULL) && (pSetFrom == NULL)) break;
H
Hongze Cheng 已提交
509

H
Hongze Cheng 已提交
510 511
    if (pSetTo == NULL || (pSetFrom && pSetFrom->fid < pSetTo->fid)) {
      tsdbApplyDFileSetChange(pSetFrom, NULL);
H
Hongze Cheng 已提交
512

H
Hongze Cheng 已提交
513 514 515 516 517 518 519 520
      ifrom++;
      if (ifrom >= sizeFrom) {
        pSetFrom = NULL;
      } else {
        pSetFrom = taosArrayGet(pFrom->df, ifrom);
      }
    } else if (pSetFrom == NULL || pSetFrom->fid > pSetTo->fid) {
      // Do nothing
H
Hongze Cheng 已提交
521 522 523 524 525
      ito++;
      if (ito >= sizeTo) {
        pSetTo = NULL;
      } else {
        pSetTo = taosArrayGet(pTo->df, ito);
H
Hongze Cheng 已提交
526 527 528
      }
    } else {
      tsdbApplyDFileSetChange(pSetFrom, pSetTo);
H
Hongze Cheng 已提交
529

H
Hongze Cheng 已提交
530 531 532 533 534 535
      ifrom++;
      if (ifrom >= sizeFrom) {
        pSetFrom = NULL;
      } else {
        pSetFrom = taosArrayGet(pFrom->df, ifrom);
      }
H
Hongze Cheng 已提交
536

H
Hongze Cheng 已提交
537 538 539 540 541 542 543 544
      ito++;
      if (ito >= sizeTo) {
        pSetTo = NULL;
      } else {
        pSetTo = taosArrayGet(pTo->df, ito);
      }
    }
  }
H
Hongze Cheng 已提交
545 546
}

H
Hongze Cheng 已提交
547 548 549 550 551
// ================== SFSIter
// ASSUMPTIONS: the FS Should be read locked when calling these functions
void tsdbFSIterInit(SFSIter *pIter, STsdbFS *pfs, int direction) {
  pIter->pfs = pfs;
  pIter->direction = direction;
H
Hongze Cheng 已提交
552

H
Hongze Cheng 已提交
553
  size_t size = taosArrayGetSize(pfs->cstatus->df);
H
Hongze Cheng 已提交
554

H
Hongze Cheng 已提交
555
  pIter->version = pfs->cstatus->meta.version;
H
Hongze Cheng 已提交
556

H
Hongze Cheng 已提交
557 558 559 560 561 562 563
  if (size == 0) {
    pIter->index = -1;
    pIter->fid = TSDB_IVLD_FID;
  } else {
    if (direction == TSDB_FS_ITER_FORWARD) {
      pIter->index = 0;
    } else {
S
TD-1207  
Shengliang Guan 已提交
564
      pIter->index = (int)(size - 1);
H
Hongze Cheng 已提交
565
    }
H
Hongze Cheng 已提交
566

H
Hongze Cheng 已提交
567
    pIter->fid = ((SDFileSet *)taosArrayGet(pfs->cstatus->df, pIter->index))->fid;
H
Hongze Cheng 已提交
568 569 570
  }
}

H
Hongze Cheng 已提交
571 572 573
void tsdbFSIterSeek(SFSIter *pIter, int fid) {
  STsdbFS *pfs = pIter->pfs;
  size_t   size = taosArrayGetSize(pfs->cstatus->df);
H
Hongze Cheng 已提交
574

H
Hongze Cheng 已提交
575 576 577 578 579
  int flags;
  if (pIter->direction == TSDB_FS_ITER_FORWARD) {
    flags = TD_GE;
  } else {
    flags = TD_LE;
H
Hongze Cheng 已提交
580 581
  }

H
Hongze Cheng 已提交
582
  void *ptr = taosbsearch(&fid, pfs->cstatus->df->pData, size, sizeof(SDFileSet), tsdbComparFidFSet, flags);
H
Hongze Cheng 已提交
583 584 585 586
  if (ptr == NULL) {
    pIter->index = -1;
    pIter->fid = TSDB_IVLD_FID;
  } else {
S
TD-1207  
Shengliang Guan 已提交
587
    pIter->index = (int)(TARRAY_ELEM_IDX(pfs->cstatus->df, ptr));
H
Hongze Cheng 已提交
588
    pIter->fid = ((SDFileSet *)ptr)->fid;
H
Hongze Cheng 已提交
589 590 591
  }
}

H
Hongze Cheng 已提交
592
SDFileSet *tsdbFSIterNext(SFSIter *pIter) {
H
Hongze Cheng 已提交
593
  STsdbFS   *pfs = pIter->pfs;
H
Hongze Cheng 已提交
594
  SDFileSet *pSet;
H
Hongze Cheng 已提交
595

H
Hongze Cheng 已提交
596 597
  if (pIter->index < 0) {
    ASSERT(pIter->fid == TSDB_IVLD_FID);
H
Hongze Cheng 已提交
598 599 600
    return NULL;
  }

H
Hongze Cheng 已提交
601
  ASSERT(pIter->fid != TSDB_IVLD_FID);
H
Hongze Cheng 已提交
602

H
Hongze Cheng 已提交
603
  if (pIter->version != pfs->cstatus->meta.version) {
604
    pIter->version = pfs->cstatus->meta.version;
H
Hongze Cheng 已提交
605
    tsdbFSIterSeek(pIter, pIter->fid);
H
Hongze Cheng 已提交
606 607
  }

H
Hongze Cheng 已提交
608 609
  if (pIter->index < 0) {
    return NULL;
H
Hongze Cheng 已提交
610 611
  }

H
Hongze Cheng 已提交
612 613
  pSet = (SDFileSet *)taosArrayGet(pfs->cstatus->df, pIter->index);
  ASSERT(pSet->fid == pIter->fid);
H
Hongze Cheng 已提交
614

H
Hongze Cheng 已提交
615 616 617 618
  if (pIter->direction == TSDB_FS_ITER_FORWARD) {
    pIter->index++;
    if (pIter->index >= taosArrayGetSize(pfs->cstatus->df)) {
      pIter->index = -1;
H
Hongze Cheng 已提交
619 620
    }
  } else {
H
Hongze Cheng 已提交
621
    pIter->index--;
H
Hongze Cheng 已提交
622 623
  }

H
Hongze Cheng 已提交
624
  if (pIter->index >= 0) {
H
Hongze Cheng 已提交
625
    pIter->fid = ((SDFileSet *)taosArrayGet(pfs->cstatus->df, pIter->index))->fid;
H
Hongze Cheng 已提交
626
  } else {
H
Hongze Cheng 已提交
627
    pIter->fid = TSDB_IVLD_FID;
H
Hongze Cheng 已提交
628 629
  }

H
Hongze Cheng 已提交
630
  return pSet;
H
Hongze Cheng 已提交
631 632 633 634 635 636 637 638 639 640 641 642 643
}

static int tsdbComparFidFSet(const void *arg1, const void *arg2) {
  int        fid = *(int *)arg1;
  SDFileSet *pSet = (SDFileSet *)arg2;

  if (fid < pSet->fid) {
    return -1;
  } else if (fid == pSet->fid) {
    return 0;
  } else {
    return 1;
  }
H
Hongze Cheng 已提交
644 645
}

S
Shengliang Guan 已提交
646 647 648
static void tsdbGetTxnFname(STsdb *pRepo, TSDB_TXN_FILE_T ftype, char fname[]) {
  snprintf(fname, TSDB_FILENAME_LEN, "%s/vnode/vnode%d/tsdb/%s", tfsGetPrimaryPath(pRepo->pTfs), pRepo->vgId,
           tsdbTxnFname[ftype]);
H
Hongze Cheng 已提交
649 650
}

H
Hongze Cheng 已提交
651
static int tsdbOpenFSFromCurrent(STsdb *pRepo) {
H
Hongze Cheng 已提交
652
  STsdbFS  *pfs = REPO_FS(pRepo);
653
  TdFilePtr pFile = NULL;
H
Hongze Cheng 已提交
654
  void     *buffer = NULL;
H
Hongze Cheng 已提交
655 656
  SFSHeader fsheader;
  char      current[TSDB_FILENAME_LEN] = "\0";
H
Hongze Cheng 已提交
657
  void     *ptr;
H
Hongze Cheng 已提交
658

S
Shengliang Guan 已提交
659
  tsdbGetTxnFname(pRepo, TSDB_TXN_CURR_FILE, current);
H
Hongze Cheng 已提交
660 661

  // current file exists, try to recover
662 663
  pFile = taosOpenFile(current, TD_FILE_READ);
  if (pFile == NULL) {
H
Hongze Cheng 已提交
664 665 666 667 668 669 670 671 672
    tsdbError("vgId:%d failed to open file %s since %s", REPO_ID(pRepo), current, strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    goto _err;
  }

  if (tsdbMakeRoom(&buffer, TSDB_FILE_HEAD_SIZE) < 0) {
    goto _err;
  }

673
  int nread = (int)taosReadFile(pFile, buffer, TSDB_FILE_HEAD_SIZE);
H
Hongze Cheng 已提交
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
  if (nread < 0) {
    tsdbError("vgId:%d failed to read %d bytes from file %s since %s", REPO_ID(pRepo), TSDB_FILENAME_LEN, current,
              strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    goto _err;
  }

  if (nread < TSDB_FILE_HEAD_SIZE) {
    tsdbError("vgId:%d failed to read header of file %s, read bytes:%d", REPO_ID(pRepo), current, nread);
    terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
    goto _err;
  }

  if (!taosCheckChecksumWhole((uint8_t *)buffer, TSDB_FILE_HEAD_SIZE)) {
    tsdbError("vgId:%d header of file %s failed checksum check", REPO_ID(pRepo), current);
    terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
    goto _err;
  }

H
Hongze Cheng 已提交
693
  SFSStatus *pStatus = pfs->cstatus;
H
Hongze Cheng 已提交
694 695
  ptr = buffer;
  ptr = tsdbDecodeFSHeader(ptr, &fsheader);
H
Hongze Cheng 已提交
696
  ptr = tsdbDecodeFSMeta(ptr, &(pStatus->meta));
H
Hongze Cheng 已提交
697

698
  if (fsheader.version != TSDB_LATEST_SFS_VER) {
H
Hongze Cheng 已提交
699 700 701 702 703 704 705 706
    // TODO: handle file version change
  }

  if (fsheader.len > 0) {
    if (tsdbMakeRoom(&buffer, fsheader.len) < 0) {
      goto _err;
    }

707
    nread = (int)taosReadFile(pFile, buffer, fsheader.len);
H
Hongze Cheng 已提交
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
    if (nread < 0) {
      tsdbError("vgId:%d failed to read file %s since %s", REPO_ID(pRepo), current, strerror(errno));
      terrno = TAOS_SYSTEM_ERROR(errno);
      goto _err;
    }

    if (nread < fsheader.len) {
      tsdbError("vgId:%d failed to read %d bytes from file %s", REPO_ID(pRepo), fsheader.len, current);
      terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
      goto _err;
    }

    if (!taosCheckChecksumWhole((uint8_t *)buffer, fsheader.len)) {
      tsdbError("vgId:%d file %s is corrupted since wrong checksum", REPO_ID(pRepo), current);
      terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
      goto _err;
    }

    ptr = buffer;
S
Shengliang Guan 已提交
727
    ptr = tsdbDecodeFSStatus(pRepo, ptr, pStatus);
H
Hongze Cheng 已提交
728 729 730 731 732
  } else {
    tsdbResetFSStatus(pStatus);
  }

  taosTZfree(buffer);
733
  taosCloseFile(&pFile);
H
Hongze Cheng 已提交
734 735 736 737

  return 0;

_err:
738 739
  if (pFile != NULL) {
    taosCloseFile(&pFile);
H
Hongze Cheng 已提交
740 741 742 743 744 745
  }
  taosTZfree(buffer);
  return -1;
}

// Scan and try to fix incorrect files
H
Hongze Cheng 已提交
746
static int tsdbScanAndTryFixFS(STsdb *pRepo) {
H
Hongze Cheng 已提交
747
  STsdbFS   *pfs = REPO_FS(pRepo);
H
Hongze Cheng 已提交
748 749
  SFSStatus *pStatus = pfs->cstatus;

H
Hongze Cheng 已提交
750 751 752 753
  // if (tsdbScanAndTryFixMFile(pRepo) < 0) {
  //   tsdbError("vgId:%d failed to fix MFile since %s", REPO_ID(pRepo), tstrerror(terrno));
  //   return -1;
  // }
H
Hongze Cheng 已提交
754 755 756 757 758 759

  size_t size = taosArrayGetSize(pStatus->df);

  for (size_t i = 0; i < size; i++) {
    SDFileSet *pSet = (SDFileSet *)taosArrayGet(pStatus->df, i);

H
Hongze Cheng 已提交
760
    if (tsdbScanAndTryFixDFileSet(pRepo, pSet) < 0) {
H
Hongze Cheng 已提交
761 762 763 764 765
      tsdbError("vgId:%d failed to fix MFile since %s", REPO_ID(pRepo), tstrerror(terrno));
      return -1;
    }
  }

H
Hongze Cheng 已提交
766
  // remove those unused files
767 768
  tsdbScanRootDir(pRepo);
  tsdbScanDataDir(pRepo);
H
Hongze Cheng 已提交
769 770 771
  return 0;
}

H
Hongze Cheng 已提交
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
// int tsdbLoadMetaCache(STsdb *pRepo, bool recoverMeta) {
//   char      tbuf[128];
//   STsdbFS * pfs = REPO_FS(pRepo);
//   SMFile    mf;
//   SMFile *  pMFile = &mf;
//   void *    pBuf = NULL;
//   SKVRecord rInfo;
//   int64_t   maxBufSize = 0;
//   SMFInfo   minfo;

//   taosHashClear(pfs->metaCache);

//   // No meta file, just return
//   if (pfs->cstatus->pmf == NULL) return 0;

//   mf = pfs->cstatus->mf;
//   // Load cache first
//   if (tsdbOpenMFile(pMFile, O_RDONLY) < 0) {
//     return -1;
//   }

//   if (tsdbLoadMFileHeader(pMFile, &minfo) < 0) {
//     tsdbCloseMFile(pMFile);
//     return -1;
//   }

//   while (true) {
//     int64_t tsize = tsdbReadMFile(pMFile, tbuf, sizeof(SKVRecord));
//     if (tsize == 0) break;

//     if (tsize < 0) {
//       tsdbError("vgId:%d failed to read META file since %s", REPO_ID(pRepo), tstrerror(terrno));
//       return -1;
//     }

//     if (tsize < sizeof(SKVRecord)) {
//       tsdbError("vgId:%d failed to read %" PRIzu " bytes from file %s", REPO_ID(pRepo), sizeof(SKVRecord),
//                 TSDB_FILE_FULL_NAME(pMFile));
//       terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
//       tsdbCloseMFile(pMFile);
//       return -1;
//     }

//     void *ptr = tsdbDecodeKVRecord(tbuf, &rInfo);
//     ASSERT(POINTER_DISTANCE(ptr, tbuf) == sizeof(SKVRecord));
//     // ASSERT((rInfo.offset > 0) ? (pStore->info.size == rInfo.offset) : true);

//     if (rInfo.offset < 0) {
//       taosHashRemove(pfs->metaCache, (void *)(&rInfo.uid), sizeof(rInfo.uid));
// #if 0
//       pStore->info.size += sizeof(SKVRecord);
//       pStore->info.nRecords--;
//       pStore->info.nDels++;
//       pStore->info.tombSize += (rInfo.size + sizeof(SKVRecord) * 2);
// #endif
//     } else {
//       ASSERT(rInfo.offset > 0 && rInfo.size > 0);
//       if (taosHashPut(pfs->metaCache, (void *)(&rInfo.uid), sizeof(rInfo.uid), &rInfo, sizeof(rInfo)) < 0) {
//         tsdbError("vgId:%d failed to load meta cache from file %s since OOM", REPO_ID(pRepo),
//                   TSDB_FILE_FULL_NAME(pMFile));
//         terrno = TSDB_CODE_COM_OUT_OF_MEMORY;
//         tsdbCloseMFile(pMFile);
//         return -1;
//       }

dengyihao's avatar
dengyihao 已提交
837
//       maxBufSize = TMAX(maxBufSize, rInfo.size);
H
Hongze Cheng 已提交
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853

//       if (tsdbSeekMFile(pMFile, rInfo.size, SEEK_CUR) < 0) {
//         tsdbError("vgId:%d failed to lseek file %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
//                   tstrerror(terrno));
//         tsdbCloseMFile(pMFile);
//         return -1;
//       }

// #if 0
//       pStore->info.size += (sizeof(SKVRecord) + rInfo.size);
//       pStore->info.nRecords++;
// #endif
//     }
//   }

//   if (recoverMeta) {
wafwerar's avatar
wafwerar 已提交
854
//     pBuf = taosMemoryMalloc((size_t)maxBufSize);
H
Hongze Cheng 已提交
855 856 857 858 859 860 861 862 863 864 865
//     if (pBuf == NULL) {
//       terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
//       tsdbCloseMFile(pMFile);
//       return -1;
//     }

//     SKVRecord *pRecord = taosHashIterate(pfs->metaCache, NULL);
//     while (pRecord) {
//       if (tsdbSeekMFile(pMFile, pRecord->offset + sizeof(SKVRecord), SEEK_SET) < 0) {
//         tsdbError("vgId:%d failed to seek file %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
//                   tstrerror(terrno));
wafwerar's avatar
wafwerar 已提交
866
//         taosMemoryFreeClear(pBuf);
H
Hongze Cheng 已提交
867 868 869 870 871 872 873 874
//         tsdbCloseMFile(pMFile);
//         return -1;
//       }

//       int nread = (int)tsdbReadMFile(pMFile, pBuf, pRecord->size);
//       if (nread < 0) {
//         tsdbError("vgId:%d failed to read file %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
//                   tstrerror(terrno));
wafwerar's avatar
wafwerar 已提交
875
//         taosMemoryFreeClear(pBuf);
H
Hongze Cheng 已提交
876 877 878 879 880 881 882 883
//         tsdbCloseMFile(pMFile);
//         return -1;
//       }

//       if (nread < pRecord->size) {
//         tsdbError("vgId:%d failed to read file %s since file corrupted, expected read:%" PRId64 " actual read:%d",
//                   REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile), pRecord->size, nread);
//         terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
wafwerar's avatar
wafwerar 已提交
884
//         taosMemoryFreeClear(pBuf);
H
Hongze Cheng 已提交
885 886 887 888 889 890 891
//         tsdbCloseMFile(pMFile);
//         return -1;
//       }

//       if (tsdbRestoreTable(pRepo, pBuf, (int)pRecord->size) < 0) {
//         tsdbError("vgId:%d failed to restore table, uid %" PRId64 ", since %s" PRIu64, REPO_ID(pRepo), pRecord->uid,
//                   tstrerror(terrno));
wafwerar's avatar
wafwerar 已提交
892
//         taosMemoryFreeClear(pBuf);
H
Hongze Cheng 已提交
893 894 895 896 897 898 899 900 901 902 903
//         tsdbCloseMFile(pMFile);
//         return -1;
//       }

//       pRecord = taosHashIterate(pfs->metaCache, pRecord);
//     }

//     tsdbOrgMeta(pRepo);
//   }

//   tsdbCloseMFile(pMFile);
wafwerar's avatar
wafwerar 已提交
904
//   taosMemoryFreeClear(pBuf);
H
Hongze Cheng 已提交
905 906
//   return 0;
// }
907

H
Hongze Cheng 已提交
908
static int tsdbScanRootDir(STsdb *pRepo) {
H
Hongze Cheng 已提交
909 910 911
  char            rootDir[TSDB_FILENAME_LEN];
  char            bname[TSDB_FILENAME_LEN];
  STsdbFS        *pfs = REPO_FS(pRepo);
S
Shengliang Guan 已提交
912
  const STfsFile *pf;
913 914

  tsdbGetRootDir(REPO_ID(pRepo), rootDir);
S
Shengliang Guan 已提交
915
  STfsDir *tdir = tfsOpendir(pRepo->pTfs, rootDir);
916 917 918 919 920 921
  if (tdir == NULL) {
    tsdbError("vgId:%d failed to open directory %s since %s", REPO_ID(pRepo), rootDir, tstrerror(terrno));
    return -1;
  }

  while ((pf = tfsReaddir(tdir))) {
S
Shengliang Guan 已提交
922
    tfsBasename(pf, bname);
923 924 925 926 927 928

    if (strcmp(bname, tsdbTxnFname[TSDB_TXN_CURR_FILE]) == 0 || strcmp(bname, "data") == 0) {
      // Skip current file and data directory
      continue;
    }

H
Hongze Cheng 已提交
929 930 931
    // if (/*pfs->cstatus->pmf && */ tfsIsSameFile(pf, &(pfs->cstatus->pmf->f))) {
    //   continue;
    // }
932

S
Shengliang Guan 已提交
933 934
    (void)tfsRemoveFile(pf);
    tsdbDebug("vgId:%d invalid file %s is removed", REPO_ID(pRepo), pf->aname);
935 936 937 938 939 940 941
  }

  tfsClosedir(tdir);

  return 0;
}

H
Hongze Cheng 已提交
942
static int tsdbScanDataDir(STsdb *pRepo) {
H
Hongze Cheng 已提交
943 944 945
  char            dataDir[TSDB_FILENAME_LEN];
  char            bname[TSDB_FILENAME_LEN];
  STsdbFS        *pfs = REPO_FS(pRepo);
S
Shengliang Guan 已提交
946
  const STfsFile *pf;
947 948

  tsdbGetDataDir(REPO_ID(pRepo), dataDir);
S
Shengliang Guan 已提交
949
  STfsDir *tdir = tfsOpendir(pRepo->pTfs, dataDir);
950 951 952 953 954 955
  if (tdir == NULL) {
    tsdbError("vgId:%d failed to open directory %s since %s", REPO_ID(pRepo), dataDir, tstrerror(terrno));
    return -1;
  }

  while ((pf = tfsReaddir(tdir))) {
S
Shengliang Guan 已提交
956
    tfsBasename(pf, bname);
957 958

    if (!tsdbIsTFileInFS(pfs, pf)) {
S
Shengliang Guan 已提交
959 960
      (void)tfsRemoveFile(pf);
      tsdbDebug("vgId:%d invalid file %s is removed", REPO_ID(pRepo), pf->aname);
961 962 963 964 965 966 967 968
    }
  }

  tfsClosedir(tdir);

  return 0;
}

S
Shengliang Guan 已提交
969
static bool tsdbIsTFileInFS(STsdbFS *pfs, const STfsFile *pf) {
970 971 972 973 974 975 976 977 978 979 980 981 982 983
  SFSIter fsiter;
  tsdbFSIterInit(&fsiter, pfs, TSDB_FS_ITER_FORWARD);
  SDFileSet *pSet;

  while ((pSet = tsdbFSIterNext(&fsiter))) {
    for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
      SDFile *pDFile = TSDB_DFILE_IN_SET(pSet, ftype);
      if (tfsIsSameFile(pf, TSDB_FILE_F(pDFile))) {
        return true;
      }
    }
  }

  return false;
H
Hongze Cheng 已提交
984 985
}

H
Hongze Cheng 已提交
986 987 988
// static int tsdbRestoreMeta(STsdb *pRepo) {
//   char         rootDir[TSDB_FILENAME_LEN];
//   char         bname[TSDB_FILENAME_LEN];
S
Shengliang Guan 已提交
989 990
//   STfsDir *       tdir = NULL;
//   const STfsFile *pf = NULL;
H
Hongze Cheng 已提交
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
//   const char * pattern = "^meta(-ver[0-9]+)?$";
//   regex_t      regex;
//   STsdbFS *    pfs = REPO_FS(pRepo);

//   regcomp(&regex, pattern, REG_EXTENDED);

//   tsdbInfo("vgId:%d try to restore meta", REPO_ID(pRepo));

//   tsdbGetRootDir(REPO_ID(pRepo), rootDir);

//   tdir = tfsOpendir(rootDir);
//   if (tdir == NULL) {
//     tsdbError("vgId:%d failed to open dir %s since %s", REPO_ID(pRepo), rootDir, tstrerror(terrno));
//     regfree(&regex);
//     return -1;
//   }

//   while ((pf = tfsReaddir(tdir))) {
S
Shengliang Guan 已提交
1009
//     tfsBasename(pf, bname);
H
Hongze Cheng 已提交
1010 1011 1012 1013 1014 1015 1016 1017

//     if (strcmp(bname, "data") == 0) {
//       // Skip the data/ directory
//       continue;
//     }

//     if (strcmp(bname, tsdbTxnFname[TSDB_TXN_TEMP_FILE]) == 0) {
//       // Skip current.t file
S
Shengliang Guan 已提交
1018
//       tsdbInfo("vgId:%d file %s exists, remove it", REPO_ID(pRepo), pf->aname);
H
Hongze Cheng 已提交
1019 1020 1021 1022 1023 1024 1025 1026 1027
//       (void)tfsremove(pf);
//       continue;
//     }

//     int code = regexec(&regex, bname, 0, NULL, 0);
//     if (code == 0) {
//       // Match
//       if (pfs->cstatus->pmf != NULL) {
//         tsdbError("vgId:%d failed to restore meta since two file exists, file1 %s and file2 %s", REPO_ID(pRepo),
S
Shengliang Guan 已提交
1028
//                   TSDB_FILE_FULL_NAME(pfs->cstatus->pmf), pf->aname);
H
Hongze Cheng 已提交
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
//         terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
//         tfsClosedir(tdir);
//         regfree(&regex);
//         return -1;
//       } else {
//         uint32_t _version = 0;
//         if (strcmp(bname, "meta") != 0) {
//           sscanf(bname, "meta-ver%" PRIu32, &_version);
//           pfs->cstatus->meta.version = _version;
//         }

//         pfs->cstatus->pmf = &(pfs->cstatus->mf);
//         pfs->cstatus->pmf->f = *pf;
//         TSDB_FILE_SET_CLOSED(pfs->cstatus->pmf);

//         if (tsdbOpenMFile(pfs->cstatus->pmf, O_RDONLY) < 0) {
//           tsdbError("vgId:%d failed to restore meta since %s", REPO_ID(pRepo), tstrerror(terrno));
//           tfsClosedir(tdir);
//           regfree(&regex);
//           return -1;
//         }

//         if (tsdbLoadMFileHeader(pfs->cstatus->pmf, &(pfs->cstatus->pmf->info)) < 0) {
//           tsdbError("vgId:%d failed to restore meta since %s", REPO_ID(pRepo), tstrerror(terrno));
//           tsdbCloseMFile(pfs->cstatus->pmf);
//           tfsClosedir(tdir);
//           regfree(&regex);
//           return -1;
//         }

//         if (tsdbForceKeepFile) {
//           struct stat tfstat;

//           // Get real file size
//           if (fstat(pfs->cstatus->pmf->fd, &tfstat) < 0) {
//             terrno = TAOS_SYSTEM_ERROR(errno);
//             tsdbCloseMFile(pfs->cstatus->pmf);
//             tfsClosedir(tdir);
//             regfree(&regex);
//             return -1;
//           }

//           if (pfs->cstatus->pmf->info.size != tfstat.st_size) {
//             int64_t tfsize = pfs->cstatus->pmf->info.size;
//             pfs->cstatus->pmf->info.size = tfstat.st_size;
//             tsdbInfo("vgId:%d file %s header size is changed from %" PRId64 " to %" PRId64, REPO_ID(pRepo),
//                      TSDB_FILE_FULL_NAME(pfs->cstatus->pmf), tfsize, pfs->cstatus->pmf->info.size);
//           }
//         }

//         tsdbCloseMFile(pfs->cstatus->pmf);
//       }
//     } else if (code == REG_NOMATCH) {
//       // Not match
S
Shengliang Guan 已提交
1083
//       tsdbInfo("vgId:%d invalid file %s exists, remove it", REPO_ID(pRepo), pf->aname);
H
Hongze Cheng 已提交
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
//       tfsremove(pf);
//       continue;
//     } else {
//       // Has other error
//       tsdbError("vgId:%d failed to restore meta file while run regexec since %s", REPO_ID(pRepo), strerror(code));
//       terrno = TAOS_SYSTEM_ERROR(code);
//       tfsClosedir(tdir);
//       regfree(&regex);
//       return -1;
//     }
//   }

//   if (pfs->cstatus->pmf) {
//     tsdbInfo("vgId:%d meta file %s is restored", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pfs->cstatus->pmf));
//   } else {
//     tsdbInfo("vgId:%d no meta file is restored", REPO_ID(pRepo));
//   }

//   tfsClosedir(tdir);
//   regfree(&regex);
//   return 0;
// }
H
Hongze Cheng 已提交
1106

H
Hongze Cheng 已提交
1107
static int tsdbRestoreDFileSet(STsdb *pRepo) {
H
Hongze Cheng 已提交
1108 1109 1110
  char            dataDir[TSDB_FILENAME_LEN];
  char            bname[TSDB_FILENAME_LEN];
  STfsDir        *tdir = NULL;
S
Shengliang Guan 已提交
1111
  const STfsFile *pf = NULL;
H
Hongze Cheng 已提交
1112 1113 1114 1115
  const char     *pattern = "^v[0-9]+f[0-9]+\\.(head|data|last|smad|smal)(-ver[0-9]+)?$";
  SArray         *fArray = NULL;
  regex_t         regex;
  STsdbFS        *pfs = REPO_FS(pRepo);
H
Hongze Cheng 已提交
1116 1117

  tsdbGetDataDir(REPO_ID(pRepo), dataDir);
H
Hongze Cheng 已提交
1118 1119 1120 1121

  // Resource allocation and init
  regcomp(&regex, pattern, REG_EXTENDED);

S
Shengliang Guan 已提交
1122
  fArray = taosArrayInit(1024, sizeof(STfsFile));
H
Hongze Cheng 已提交
1123 1124 1125 1126 1127 1128 1129 1130
  if (fArray == NULL) {
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
    tsdbError("vgId:%d failed to restore DFileSet while open directory %s since %s", REPO_ID(pRepo), dataDir,
              tstrerror(terrno));
    regfree(&regex);
    return -1;
  }

S
Shengliang Guan 已提交
1131
  tdir = tfsOpendir(pRepo->pTfs, dataDir);
H
Hongze Cheng 已提交
1132
  if (tdir == NULL) {
H
Hongze Cheng 已提交
1133 1134 1135 1136
    tsdbError("vgId:%d failed to restore DFileSet while open directory %s since %s", REPO_ID(pRepo), dataDir,
              tstrerror(terrno));
    taosArrayDestroy(fArray);
    regfree(&regex);
H
Hongze Cheng 已提交
1137 1138 1139
    return -1;
  }

H
Hongze Cheng 已提交
1140
  while ((pf = tfsReaddir(tdir))) {
S
Shengliang Guan 已提交
1141
    tfsBasename(pf, bname);
H
Hongze Cheng 已提交
1142 1143 1144

    int code = regexec(&regex, bname, 0, NULL, 0);
    if (code == 0) {
1145
      if (taosArrayPush(fArray, (void *)pf) == NULL) {
H
Hongze Cheng 已提交
1146 1147 1148 1149 1150 1151 1152 1153
        terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
        tfsClosedir(tdir);
        taosArrayDestroy(fArray);
        regfree(&regex);
        return -1;
      }
    } else if (code == REG_NOMATCH) {
      // Not match
S
Shengliang Guan 已提交
1154 1155
      tsdbInfo("vgId:%d invalid file %s exists, remove it", REPO_ID(pRepo), pf->aname);
      (void)tfsRemoveFile(pf);
H
Hongze Cheng 已提交
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
      continue;
    } else {
      // Has other error
      tsdbError("vgId:%d failed to restore DFileSet Array while run regexec since %s", REPO_ID(pRepo), strerror(code));
      terrno = TAOS_SYSTEM_ERROR(code);
      tfsClosedir(tdir);
      taosArrayDestroy(fArray);
      regfree(&regex);
      return -1;
    }
  }
H
Hongze Cheng 已提交
1167 1168

  tfsClosedir(tdir);
H
Hongze Cheng 已提交
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
  regfree(&regex);

  // Sort the array according to file name
  taosArraySort(fArray, tsdbComparTFILE);

  size_t index = 0;
  // Loop to recover each file set
  for (;;) {
    if (index >= taosArrayGetSize(fArray)) {
      break;
    }

    SDFileSet fset = {0};

    TSDB_FSET_SET_CLOSED(&fset);

    // Loop to recover ONE fset
    for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
      SDFile *pDFile = TSDB_DFILE_IN_SET(&fset, ftype);

      if (index >= taosArrayGetSize(fArray)) {
        tsdbError("vgId:%d incomplete DFileSet, fid:%d", REPO_ID(pRepo), fset.fid);
        taosArrayDestroy(fArray);
        return -1;
      }

      pf = taosArrayGet(fArray, index);

      int         tvid, tfid;
      TSDB_FILE_T ttype;
      uint32_t    tversion;
1200
      char        _bname[TSDB_FILENAME_LEN];
H
Hongze Cheng 已提交
1201

S
Shengliang Guan 已提交
1202
      tfsBasename(pf, _bname);
1203
      tsdbParseDFilename(_bname, &tvid, &tfid, &ttype, &tversion);
H
Hongze Cheng 已提交
1204 1205 1206

      ASSERT(tvid == REPO_ID(pRepo));

1207 1208 1209 1210 1211
      if (tfid < pRepo->rtn.minFid) {  // skip file expired
        ++index;
        continue;
      }

H
Hongze Cheng 已提交
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
      if (ftype == 0) {
        fset.fid = tfid;
      } else {
        if (tfid != fset.fid) {
          tsdbError("vgId:%d incomplete dFileSet, fid:%d", REPO_ID(pRepo), fset.fid);
          taosArrayDestroy(fArray);
          return -1;
        }
      }

      if (ttype != ftype) {
        tsdbError("vgId:%d incomplete dFileSet, fid:%d", REPO_ID(pRepo), fset.fid);
        taosArrayDestroy(fArray);
        return -1;
      }

      pDFile->f = *pf;
H
Hongze Cheng 已提交
1229

1230 1231
      // if (tsdbOpenDFile(pDFile, O_RDONLY) < 0) {
      if (tsdbOpenDFile(pDFile, TD_FILE_READ) < 0) {
H
Hongze Cheng 已提交
1232 1233
        tsdbError("vgId:%d failed to open DFile %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile),
                  tstrerror(terrno));
H
Hongze Cheng 已提交
1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244
        taosArrayDestroy(fArray);
        return -1;
      }

      if (tsdbLoadDFileHeader(pDFile, &(pDFile->info)) < 0) {
        tsdbError("vgId:%d failed to load DFile %s header since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile),
                  tstrerror(terrno));
        taosArrayDestroy(fArray);
        return -1;
      }

1245
      if (tsdbForceKeepFile) {
1246
        int64_t file_size;
1247
        // Get real file size
1248
        if (taosFStatFile(pDFile->pFile, &file_size, NULL) < 0) {
1249 1250 1251 1252 1253
          terrno = TAOS_SYSTEM_ERROR(errno);
          taosArrayDestroy(fArray);
          return -1;
        }

1254
        if (pDFile->info.size != file_size) {
1255
          int64_t tfsize = pDFile->info.size;
1256
          pDFile->info.size = file_size;
1257 1258 1259 1260 1261
          tsdbInfo("vgId:%d file %s header size is changed from %" PRId64 " to %" PRId64, REPO_ID(pRepo),
                   TSDB_FILE_FULL_NAME(pDFile), tfsize, pDFile->info.size);
        }
      }

H
Hongze Cheng 已提交
1262
      tsdbCloseDFile(pDFile);
H
Hongze Cheng 已提交
1263
      index++;
H
Hongze Cheng 已提交
1264 1265
    }

H
Hongze Cheng 已提交
1266
    tsdbInfo("vgId:%d FSET %d is restored", REPO_ID(pRepo), fset.fid);
H
Hongze Cheng 已提交
1267 1268 1269 1270 1271
    taosArrayPush(pfs->cstatus->df, &fset);
  }

  // Resource release
  taosArrayDestroy(fArray);
H
Hongze Cheng 已提交
1272 1273

  return 0;
H
Hongze Cheng 已提交
1274 1275
}

H
Hongze Cheng 已提交
1276
static int tsdbRestoreCurrent(STsdb *pRepo) {
H
Hongze Cheng 已提交
1277 1278 1279 1280 1281
  // // Loop to recover mfile
  // if (tsdbRestoreMeta(pRepo) < 0) {
  //   tsdbError("vgId:%d failed to restore current since %s", REPO_ID(pRepo), tstrerror(terrno));
  //   return -1;
  // }
H
Hongze Cheng 已提交
1282 1283 1284 1285 1286 1287 1288

  // Loop to recover dfile set
  if (tsdbRestoreDFileSet(pRepo) < 0) {
    tsdbError("vgId:%d failed to restore DFileSet since %s", REPO_ID(pRepo), tstrerror(terrno));
    return -1;
  }

S
Shengliang Guan 已提交
1289
  if (tsdbSaveFSStatus(pRepo, pRepo->fs->cstatus) < 0) {
S
Shengliang Guan 已提交
1290
    tsdbError("vgId:%d failed to restore current since %s", REPO_ID(pRepo), tstrerror(terrno));
H
Hongze Cheng 已提交
1291 1292 1293 1294 1295 1296 1297
    return -1;
  }

  return 0;
}

static int tsdbComparTFILE(const void *arg1, const void *arg2) {
S
Shengliang Guan 已提交
1298 1299
  STfsFile *pf1 = (STfsFile *)arg1;
  STfsFile *pf2 = (STfsFile *)arg2;
H
Hongze Cheng 已提交
1300 1301 1302 1303

  int         vid1, fid1, vid2, fid2;
  TSDB_FILE_T ftype1, ftype2;
  uint32_t    version1, version2;
H
Hongze Cheng 已提交
1304 1305
  char        bname1[TSDB_FILENAME_LEN];
  char        bname2[TSDB_FILENAME_LEN];
H
Hongze Cheng 已提交
1306

S
Shengliang Guan 已提交
1307 1308
  tfsBasename(pf1, bname1);
  tfsBasename(pf2, bname2);
H
Hongze Cheng 已提交
1309 1310
  tsdbParseDFilename(bname1, &vid1, &fid1, &ftype1, &version1);
  tsdbParseDFilename(bname2, &vid2, &fid2, &ftype2, &version2);
H
Hongze Cheng 已提交
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324

  if (fid1 < fid2) {
    return -1;
  } else if (fid1 > fid2) {
    return 1;
  } else {
    if (ftype1 < ftype2) {
      return -1;
    } else if (ftype1 > ftype2) {
      return 1;
    } else {
      return 0;
    }
  }
H
Hongze Cheng 已提交
1325 1326
}

H
Hongze Cheng 已提交
1327
static void tsdbScanAndTryFixDFilesHeader(STsdb *pRepo, int32_t *nExpired) {
H
Hongze Cheng 已提交
1328
  STsdbFS   *pfs = REPO_FS(pRepo);
H
Hongze Cheng 已提交
1329 1330 1331 1332 1333 1334
  SFSStatus *pStatus = pfs->cstatus;
  SDFInfo    info;

  for (size_t i = 0; i < taosArrayGetSize(pStatus->df); i++) {
    SDFileSet fset;
    tsdbInitDFileSetEx(&fset, (SDFileSet *)taosArrayGet(pStatus->df, i));
1335 1336 1337
    if (fset.fid < pRepo->rtn.minFid) {
      ++*nExpired;
    }
H
Hongze Cheng 已提交
1338 1339
    tsdbDebug("vgId:%d scan DFileSet %d header", REPO_ID(pRepo), fset.fid);

1340 1341
    // if (tsdbOpenDFileSet(&fset, O_RDWR) < 0) {
    if (tsdbOpenDFileSet(&fset, TD_FILE_WRITE | TD_FILE_READ) < 0) {
H
Hongze Cheng 已提交
1342 1343 1344 1345 1346 1347 1348
      tsdbError("vgId:%d failed to open DFileSet %d since %s, continue", REPO_ID(pRepo), fset.fid, tstrerror(terrno));
      continue;
    }

    for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
      SDFile *pDFile = TSDB_DFILE_IN_SET(&fset, ftype);

H
Hongze Cheng 已提交
1349 1350
      if ((tsdbLoadDFileHeader(pDFile, &info) < 0) || pDFile->info.size != info.size ||
          pDFile->info.magic != info.magic) {
H
Hongze Cheng 已提交
1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364
        if (tsdbUpdateDFileHeader(pDFile) < 0) {
          tsdbError("vgId:%d failed to update DFile header of %s since %s, continue", REPO_ID(pRepo),
                    TSDB_FILE_FULL_NAME(pDFile), tstrerror(terrno));
        } else {
          tsdbInfo("vgId:%d DFile header of %s is updated", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile));
          TSDB_FILE_FSYNC(pDFile);
        }
      } else {
        tsdbDebug("vgId:%d DFile header of %s is correct", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile));
      }
    }

    tsdbCloseDFileSet(&fset);
  }
L
Liu Jicong 已提交
1365
}