walMeta.c 14.6 KB
Newer Older
L
Liu Jicong 已提交
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/>.
 */

L
Liu Jicong 已提交
16
#include "cJSON.h"
L
Liu Jicong 已提交
17 18
#include "os.h"
#include "taoserror.h"
L
Liu Jicong 已提交
19
#include "tutil.h"
L
Liu Jicong 已提交
20 21
#include "walInt.h"

22 23 24 25
bool FORCE_INLINE walLogExist(SWal* pWal, int64_t ver) {
  return !walIsEmpty(pWal) && walGetFirstVer(pWal) <= ver && walGetLastVer(pWal) >= ver;
}

L
Liu Jicong 已提交
26 27
bool FORCE_INLINE walIsEmpty(SWal* pWal) { return pWal->vers.firstVer == -1; }

L
Liu Jicong 已提交
28
int64_t FORCE_INLINE walGetFirstVer(SWal* pWal) { return pWal->vers.firstVer; }
L
Liu Jicong 已提交
29

L
Liu Jicong 已提交
30
int64_t FORCE_INLINE walGetSnaphostVer(SWal* pWal) { return pWal->vers.snapshotVer; }
L
Liu Jicong 已提交
31

L
Liu Jicong 已提交
32
int64_t FORCE_INLINE walGetLastVer(SWal* pWal) { return pWal->vers.lastVer; }
L
Liu Jicong 已提交
33

L
Liu Jicong 已提交
34 35
int64_t FORCE_INLINE walGetCommittedVer(SWal* pWal) { return pWal->vers.commitVer; }

L
Liu Jicong 已提交
36 37
int64_t FORCE_INLINE walGetAppliedVer(SWal* pWal) { return pWal->vers.appliedVer; }

L
Liu Jicong 已提交
38
static FORCE_INLINE int walBuildMetaName(SWal* pWal, int metaVer, char* buf) {
L
Liu Jicong 已提交
39 40 41
  return sprintf(buf, "%s/meta-ver%d", pWal->path, metaVer);
}

L
Liu Jicong 已提交
42
static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal) {
L
Liu Jicong 已提交
43
  int32_t sz = taosArrayGetSize(pWal->fileInfoSet);
L
Liu Jicong 已提交
44
  ASSERT(sz > 0);
L
Liu Jicong 已提交
45
#if 0
L
Liu Jicong 已提交
46 47 48
  for (int i = 0; i < sz; i++) {
    SWalFileInfo* pFileInfo = taosArrayGet(pWal->fileInfoSet, i);
  }
L
Liu Jicong 已提交
49 50
#endif

L
Liu Jicong 已提交
51 52
  SWalFileInfo* pLastFileInfo = taosArrayGet(pWal->fileInfoSet, sz - 1);
  char          fnameStr[WAL_FILE_LEN];
L
Liu Jicong 已提交
53 54
  walBuildLogName(pWal, pLastFileInfo->firstVer, fnameStr);

L
Liu Jicong 已提交
55 56
  int64_t fileSize = 0;
  taosStatFile(fnameStr, &fileSize, NULL);
57
  int32_t readSize = TMIN(WAL_SCAN_BUF_SIZE, fileSize);
L
Liu Jicong 已提交
58
  pLastFileInfo->fileSize = fileSize;
L
Liu Jicong 已提交
59

60 61
  TdFilePtr pFile = taosOpenFile(fnameStr, TD_FILE_READ);
  if (pFile == NULL) {
L
Liu Jicong 已提交
62 63 64 65 66 67
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

  uint64_t magic = WAL_MAGIC;

wafwerar's avatar
wafwerar 已提交
68
  char* buf = taosMemoryMalloc(readSize + 5);
L
Liu Jicong 已提交
69
  if (buf == NULL) {
70
    taosCloseFile(&pFile);
L
Liu Jicong 已提交
71 72 73 74
    terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
    return -1;
  }

75 76
  int64_t offset;
  offset = taosLSeekFile(pFile, -readSize, SEEK_END);
77
  if (readSize != taosReadFile(pFile, buf, readSize)) {
wafwerar's avatar
wafwerar 已提交
78
    taosMemoryFree(buf);
79
    taosCloseFile(&pFile);
L
Liu Jicong 已提交
80 81 82
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }
L
Liu Jicong 已提交
83

L
Liu Jicong 已提交
84
  char* found = NULL;
85 86 87 88 89 90 91 92 93 94
  while (1) {
    char* haystack = buf;
    char* candidate;
    while ((candidate = tmemmem(haystack, readSize - (haystack - buf), (char*)&magic, sizeof(uint64_t))) != NULL) {
      // read and validate
      SWalCkHead* logContent = (SWalCkHead*)candidate;
      if (walValidHeadCksum(logContent) == 0 && walValidBodyCksum(logContent) == 0) {
        found = candidate;
      }
      haystack = candidate + 1;
L
Liu Jicong 已提交
95
    }
96
    if (found || offset == 0) break;
L
Liu Jicong 已提交
97
    offset = TMIN(0, offset - readSize + sizeof(uint64_t));
98 99 100
    int64_t offset2 = taosLSeekFile(pFile, offset, SEEK_SET);
    ASSERT(offset == offset2);
    if (readSize != taosReadFile(pFile, buf, readSize)) {
wafwerar's avatar
wafwerar 已提交
101
      taosMemoryFree(buf);
102
      taosCloseFile(&pFile);
103
      terrno = TAOS_SYSTEM_ERROR(errno);
L
Liu Jicong 已提交
104
      return -1;
L
Liu Jicong 已提交
105
    }
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
#if 0
    if (found == buf) {
      SWalCkHead* logContent = (SWalCkHead*)found;
      if (walValidHeadCksum(logContent) != 0 || walValidBodyCksum(logContent) != 0) {
        // file has to be deleted
        taosMemoryFree(buf);
        taosCloseFile(&pFile);
        terrno = TSDB_CODE_WAL_FILE_CORRUPTED;
        return -1;
      }
    }
#endif
  }
  // TODO truncate file

  if (found == NULL) {
    // file corrupted, no complete log
    // TODO delete and search in previous files
124
    /*ASSERT(0);*/
125 126
    terrno = TSDB_CODE_WAL_FILE_CORRUPTED;
    return -1;
L
Liu Jicong 已提交
127
  }
L
Liu Jicong 已提交
128
  SWalCkHead* lastEntry = (SWalCkHead*)found;
L
Liu Jicong 已提交
129
  int64_t     retVer = lastEntry->head.version;
130 131
  taosCloseFile(&pFile);
  taosMemoryFree(buf);
L
Liu Jicong 已提交
132

L
Liu Jicong 已提交
133
  return retVer;
L
Liu Jicong 已提交
134 135
}

L
Liu Jicong 已提交
136 137 138 139
int walCheckAndRepairMeta(SWal* pWal) {
  // load log files, get first/snapshot/last version info
  const char* logPattern = "^[0-9]+.log$";
  const char* idxPattern = "^[0-9]+.idx$";
L
Liu Jicong 已提交
140 141
  regex_t     logRegPattern;
  regex_t     idxRegPattern;
142
  SArray*     actualLog = taosArrayInit(8, sizeof(SWalFileInfo));
L
Liu Jicong 已提交
143 144 145

  regcomp(&logRegPattern, logPattern, REG_EXTENDED);
  regcomp(&idxRegPattern, idxPattern, REG_EXTENDED);
L
Liu Jicong 已提交
146

wafwerar's avatar
wafwerar 已提交
147 148
  TdDirPtr pDir = taosOpenDir(pWal->path);
  if (pDir == NULL) {
L
Liu Jicong 已提交
149 150 151 152
    wError("vgId:%d, path:%s, failed to open since %s", pWal->cfg.vgId, pWal->path, strerror(errno));
    return -1;
  }

L
Liu Jicong 已提交
153
  // scan log files and build new meta
wafwerar's avatar
wafwerar 已提交
154 155 156
  TdDirEntryPtr pDirEntry;
  while ((pDirEntry = taosReadDir(pDir)) != NULL) {
    char* name = taosDirEntryBaseName(taosGetDirEntryName(pDirEntry));
L
Liu Jicong 已提交
157 158
    int   code = regexec(&logRegPattern, name, 0, NULL, 0);
    if (code == 0) {
L
Liu Jicong 已提交
159 160 161
      SWalFileInfo fileInfo;
      memset(&fileInfo, -1, sizeof(SWalFileInfo));
      sscanf(name, "%" PRId64 ".log", &fileInfo.firstVer);
162
      taosArrayPush(actualLog, &fileInfo);
L
Liu Jicong 已提交
163 164 165
    }
  }

wafwerar's avatar
wafwerar 已提交
166
  taosCloseDir(&pDir);
L
Liu Jicong 已提交
167 168 169
  regfree(&logRegPattern);
  regfree(&idxRegPattern);

170
  taosArraySort(actualLog, compareWalFileInfo);
L
Liu Jicong 已提交
171

L
Liu Jicong 已提交
172
  int metaFileNum = taosArrayGetSize(pWal->fileInfoSet);
173
  int actualFileNum = taosArrayGetSize(actualLog);
L
Liu Jicong 已提交
174

L
Liu Jicong 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
#if 0
  for (int32_t fileNo = actualFileNum - 1; fileNo >= 0; fileNo--) {
    SWalFileInfo* pFileInfo = taosArrayGet(pLogInfoArray, fileNo);
    char          fnameStr[WAL_FILE_LEN];
    walBuildLogName(pWal, pFileInfo->firstVer, fnameStr);
    int64_t fileSize = 0;
    taosStatFile(fnameStr, &fileSize, NULL);
    if (fileSize == 0) {
      taosRemoveFile(fnameStr);
      walBuildIdxName(pWal, pFileInfo->firstVer, fnameStr);
      taosRemoveFile(fnameStr);
      taosArrayPop(pLogInfoArray);
    } else {
      break;
    }
  }

  actualFileNum = taosArrayGetSize(pLogInfoArray);
#endif

L
Liu Jicong 已提交
195 196 197 198
  if (metaFileNum > actualFileNum) {
    taosArrayPopFrontBatch(pWal->fileInfoSet, metaFileNum - actualFileNum);
  } else if (metaFileNum < actualFileNum) {
    for (int i = metaFileNum; i < actualFileNum; i++) {
199
      SWalFileInfo* pFileInfo = taosArrayGet(actualLog, i);
L
Liu Jicong 已提交
200 201
      taosArrayPush(pWal->fileInfoSet, pFileInfo);
    }
L
Liu Jicong 已提交
202
  }
203
  taosArrayDestroy(actualLog);
L
Liu Jicong 已提交
204

L
Liu Jicong 已提交
205 206
  pWal->writeCur = actualFileNum - 1;
  if (actualFileNum > 0) {
L
Liu Jicong 已提交
207 208
    pWal->vers.firstVer = ((SWalFileInfo*)taosArrayGet(pWal->fileInfoSet, 0))->firstVer;

L
Liu Jicong 已提交
209
    SWalFileInfo* pLastFileInfo = taosArrayGet(pWal->fileInfoSet, actualFileNum - 1);
L
Liu Jicong 已提交
210
    char          fnameStr[WAL_FILE_LEN];
L
Liu Jicong 已提交
211
    walBuildLogName(pWal, pLastFileInfo->firstVer, fnameStr);
L
Liu Jicong 已提交
212 213
    int64_t fileSize = 0;
    taosStatFile(fnameStr, &fileSize, NULL);
L
Liu Jicong 已提交
214
    /*ASSERT(fileSize != 0);*/
L
Liu Jicong 已提交
215

L
Liu Jicong 已提交
216 217
    if (metaFileNum != actualFileNum || pLastFileInfo->fileSize != fileSize) {
      pLastFileInfo->fileSize = fileSize;
L
Liu Jicong 已提交
218 219 220 221 222 223 224
      pWal->vers.lastVer = walScanLogGetLastVer(pWal);
      ((SWalFileInfo*)taosArrayGetLast(pWal->fileInfoSet))->lastVer = pWal->vers.lastVer;
      ASSERT(pWal->vers.lastVer != -1);

      int code = walSaveMeta(pWal);
      if (code < 0) {
        return -1;
L
Liu Jicong 已提交
225 226 227 228
      }
    }
  }

L
Liu Jicong 已提交
229 230
  // TODO: set fileSize and lastVer if necessary

L
Liu Jicong 已提交
231 232 233 234
  return 0;
}

int walCheckAndRepairIdx(SWal* pWal) {
L
Liu Jicong 已提交
235 236 237 238
  // TODO: iterate all log files
  // if idx not found, scan log and write idx
  // if found, check complete by first and last entry of each idx file
  // if idx incomplete, binary search last valid entry, and then build other part
L
Liu Jicong 已提交
239 240 241
  return 0;
}

L
Liu Jicong 已提交
242 243 244 245
int walRollFileInfo(SWal* pWal) {
  int64_t ts = taosGetTimestampSec();

  SArray* pArray = pWal->fileInfoSet;
L
Liu Jicong 已提交
246
  if (taosArrayGetSize(pArray) != 0) {
L
Liu Jicong 已提交
247
    SWalFileInfo* pInfo = taosArrayGetLast(pArray);
L
Liu Jicong 已提交
248
    pInfo->lastVer = pWal->vers.lastVer;
L
Liu Jicong 已提交
249 250 251
    pInfo->closeTs = ts;
  }

L
Liu Jicong 已提交
252
  // TODO: change to emplace back
wafwerar's avatar
wafwerar 已提交
253
  SWalFileInfo* pNewInfo = taosMemoryMalloc(sizeof(SWalFileInfo));
L
Liu Jicong 已提交
254
  if (pNewInfo == NULL) {
L
Liu Jicong 已提交
255
    terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
L
Liu Jicong 已提交
256 257
    return -1;
  }
L
Liu Jicong 已提交
258
  pNewInfo->firstVer = pWal->vers.lastVer + 1;
L
Liu Jicong 已提交
259 260 261 262
  pNewInfo->lastVer = -1;
  pNewInfo->createTs = ts;
  pNewInfo->closeTs = -1;
  pNewInfo->fileSize = 0;
L
Liu Jicong 已提交
263
  taosArrayPush(pArray, pNewInfo);
wafwerar's avatar
wafwerar 已提交
264
  taosMemoryFree(pNewInfo);
L
Liu Jicong 已提交
265 266 267
  return 0;
}

268
char* walMetaSerialize(SWal* pWal) {
L
Liu Jicong 已提交
269
  char buf[30];
L
Liu Jicong 已提交
270
  ASSERT(pWal->fileInfoSet);
L
Liu Jicong 已提交
271
  int    sz = taosArrayGetSize(pWal->fileInfoSet);
272 273 274 275
  cJSON* pRoot = cJSON_CreateObject();
  cJSON* pMeta = cJSON_CreateObject();
  cJSON* pFiles = cJSON_CreateArray();
  cJSON* pField;
L
Liu Jicong 已提交
276
  if (pRoot == NULL || pMeta == NULL || pFiles == NULL) {
L
Liu Jicong 已提交
277
    if (pRoot) {
L
Liu Jicong 已提交
278 279
      cJSON_Delete(pRoot);
    }
L
Liu Jicong 已提交
280
    if (pMeta) {
L
Liu Jicong 已提交
281 282
      cJSON_Delete(pMeta);
    }
L
Liu Jicong 已提交
283
    if (pFiles) {
L
Liu Jicong 已提交
284 285 286
      cJSON_Delete(pFiles);
    }
    terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
L
Liu Jicong 已提交
287 288
    return NULL;
  }
289
  cJSON_AddItemToObject(pRoot, "meta", pMeta);
L
Liu Jicong 已提交
290
  sprintf(buf, "%" PRId64, pWal->vers.firstVer);
291
  cJSON_AddStringToObject(pMeta, "firstVer", buf);
L
Liu Jicong 已提交
292
  sprintf(buf, "%" PRId64, pWal->vers.snapshotVer);
293
  cJSON_AddStringToObject(pMeta, "snapshotVer", buf);
L
Liu Jicong 已提交
294
  sprintf(buf, "%" PRId64, pWal->vers.commitVer);
295
  cJSON_AddStringToObject(pMeta, "commitVer", buf);
L
Liu Jicong 已提交
296
  sprintf(buf, "%" PRId64, pWal->vers.lastVer);
297 298 299
  cJSON_AddStringToObject(pMeta, "lastVer", buf);

  cJSON_AddItemToObject(pRoot, "files", pFiles);
L
Liu Jicong 已提交
300
  SWalFileInfo* pData = pWal->fileInfoSet->pData;
L
Liu Jicong 已提交
301
  for (int i = 0; i < sz; i++) {
L
Liu Jicong 已提交
302
    SWalFileInfo* pInfo = &pData[i];
303
    cJSON_AddItemToArray(pFiles, pField = cJSON_CreateObject());
L
Liu Jicong 已提交
304
    if (pField == NULL) {
305
      cJSON_Delete(pRoot);
L
Liu Jicong 已提交
306 307
      return NULL;
    }
L
Liu Jicong 已提交
308 309
    // cjson only support int32_t or double
    // string are used to prohibit the loss of precision
310 311 312 313 314 315 316 317 318 319
    sprintf(buf, "%" PRId64, pInfo->firstVer);
    cJSON_AddStringToObject(pField, "firstVer", buf);
    sprintf(buf, "%" PRId64, pInfo->lastVer);
    cJSON_AddStringToObject(pField, "lastVer", buf);
    sprintf(buf, "%" PRId64, pInfo->createTs);
    cJSON_AddStringToObject(pField, "createTs", buf);
    sprintf(buf, "%" PRId64, pInfo->closeTs);
    cJSON_AddStringToObject(pField, "closeTs", buf);
    sprintf(buf, "%" PRId64, pInfo->fileSize);
    cJSON_AddStringToObject(pField, "fileSize", buf);
L
Liu Jicong 已提交
320
  }
L
Liu Jicong 已提交
321 322 323
  char* serialized = cJSON_Print(pRoot);
  cJSON_Delete(pRoot);
  return serialized;
L
Liu Jicong 已提交
324 325
}

326 327 328 329 330 331
int walMetaDeserialize(SWal* pWal, const char* bytes) {
  ASSERT(taosArrayGetSize(pWal->fileInfoSet) == 0);
  cJSON *pRoot, *pMeta, *pFiles, *pInfoJson, *pField;
  pRoot = cJSON_Parse(bytes);
  pMeta = cJSON_GetObjectItem(pRoot, "meta");
  pField = cJSON_GetObjectItem(pMeta, "firstVer");
L
Liu Jicong 已提交
332
  pWal->vers.firstVer = atoll(cJSON_GetStringValue(pField));
333
  pField = cJSON_GetObjectItem(pMeta, "snapshotVer");
L
Liu Jicong 已提交
334
  pWal->vers.snapshotVer = atoll(cJSON_GetStringValue(pField));
335
  pField = cJSON_GetObjectItem(pMeta, "commitVer");
L
Liu Jicong 已提交
336
  pWal->vers.commitVer = atoll(cJSON_GetStringValue(pField));
337
  pField = cJSON_GetObjectItem(pMeta, "lastVer");
L
Liu Jicong 已提交
338
  pWal->vers.lastVer = atoll(cJSON_GetStringValue(pField));
339 340 341

  pFiles = cJSON_GetObjectItem(pRoot, "files");
  int sz = cJSON_GetArraySize(pFiles);
L
Liu Jicong 已提交
342
  // deserialize
L
Liu Jicong 已提交
343 344
  SArray* pArray = pWal->fileInfoSet;
  taosArrayEnsureCap(pArray, sz);
L
Liu Jicong 已提交
345
  SWalFileInfo* pData = pArray->pData;
L
Liu Jicong 已提交
346
  for (int i = 0; i < sz; i++) {
L
Liu Jicong 已提交
347 348
    cJSON*        pInfoJson = cJSON_GetArrayItem(pFiles, i);
    SWalFileInfo* pInfo = &pData[i];
L
Liu Jicong 已提交
349 350 351 352 353 354 355 356 357 358 359 360
    pField = cJSON_GetObjectItem(pInfoJson, "firstVer");
    pInfo->firstVer = atoll(cJSON_GetStringValue(pField));
    pField = cJSON_GetObjectItem(pInfoJson, "lastVer");
    pInfo->lastVer = atoll(cJSON_GetStringValue(pField));
    pField = cJSON_GetObjectItem(pInfoJson, "createTs");
    pInfo->createTs = atoll(cJSON_GetStringValue(pField));
    pField = cJSON_GetObjectItem(pInfoJson, "closeTs");
    pInfo->closeTs = atoll(cJSON_GetStringValue(pField));
    pField = cJSON_GetObjectItem(pInfoJson, "fileSize");
    pInfo->fileSize = atoll(cJSON_GetStringValue(pField));
  }
  taosArraySetSize(pArray, sz);
361
  pWal->fileInfoSet = pArray;
L
Liu Jicong 已提交
362
  pWal->writeCur = sz - 1;
L
Liu Jicong 已提交
363
  cJSON_Delete(pRoot);
364
  return 0;
L
Liu Jicong 已提交
365 366 367
}

static int walFindCurMetaVer(SWal* pWal) {
L
Liu Jicong 已提交
368 369
  const char* pattern = "^meta-ver[0-9]+$";
  regex_t     walMetaRegexPattern;
L
Liu Jicong 已提交
370 371
  regcomp(&walMetaRegexPattern, pattern, REG_EXTENDED);

wafwerar's avatar
wafwerar 已提交
372 373
  TdDirPtr pDir = taosOpenDir(pWal->path);
  if (pDir == NULL) {
L
Liu Jicong 已提交
374
    wError("vgId:%d, path:%s, failed to open since %s", pWal->cfg.vgId, pWal->path, strerror(errno));
L
Liu Jicong 已提交
375 376 377
    return -1;
  }

wafwerar's avatar
wafwerar 已提交
378
  TdDirEntryPtr pDirEntry;
L
Liu Jicong 已提交
379

L
Liu Jicong 已提交
380
  // find existing meta-ver[x].json
L
Liu Jicong 已提交
381
  int metaVer = -1;
wafwerar's avatar
wafwerar 已提交
382 383
  while ((pDirEntry = taosReadDir(pDir)) != NULL) {
    char* name = taosDirEntryBaseName(taosGetDirEntryName(pDirEntry));
L
Liu Jicong 已提交
384 385
    int   code = regexec(&walMetaRegexPattern, name, 0, NULL, 0);
    if (code == 0) {
L
Liu Jicong 已提交
386
      sscanf(name, "meta-ver%d", &metaVer);
L
Liu Jicong 已提交
387
      wDebug("vgId:%d, wal find current meta: %s is the meta file, ver %d", pWal->cfg.vgId, name, metaVer);
L
Liu Jicong 已提交
388 389
      break;
    }
L
Liu Jicong 已提交
390
    wDebug("vgId:%d, wal find current meta: %s is not meta file", pWal->cfg.vgId, name);
L
Liu Jicong 已提交
391
  }
wafwerar's avatar
wafwerar 已提交
392
  taosCloseDir(&pDir);
L
Liu Jicong 已提交
393
  regfree(&walMetaRegexPattern);
L
Liu Jicong 已提交
394 395 396
  return metaVer;
}

L
Liu Jicong 已提交
397
int walSaveMeta(SWal* pWal) {
L
Liu Jicong 已提交
398
  int  metaVer = walFindCurMetaVer(pWal);
L
Liu Jicong 已提交
399
  char fnameStr[WAL_FILE_LEN];
L
Liu Jicong 已提交
400
  walBuildMetaName(pWal, metaVer + 1, fnameStr);
401
  TdFilePtr pMataFile = taosOpenFile(fnameStr, TD_FILE_CREATE | TD_FILE_WRITE);
402
  if (pMataFile == NULL) {
L
Liu Jicong 已提交
403 404
    return -1;
  }
405
  char* serialized = walMetaSerialize(pWal);
L
Liu Jicong 已提交
406
  int   len = strlen(serialized);
407
  if (len != taosWriteFile(pMataFile, serialized, len)) {
L
Liu Jicong 已提交
408
    // TODO:clean file
L
Liu Jicong 已提交
409 410
    return -1;
  }
L
Liu Jicong 已提交
411

412
  taosCloseFile(&pMataFile);
L
Liu Jicong 已提交
413 414
  // delete old file
  if (metaVer > -1) {
L
Liu Jicong 已提交
415
    walBuildMetaName(pWal, metaVer, fnameStr);
416
    taosRemoveFile(fnameStr);
L
Liu Jicong 已提交
417
  }
wafwerar's avatar
wafwerar 已提交
418
  taosMemoryFree(serialized);
L
Liu Jicong 已提交
419 420 421
  return 0;
}

L
Liu Jicong 已提交
422
int walLoadMeta(SWal* pWal) {
L
Liu Jicong 已提交
423
  ASSERT(pWal->fileInfoSet->size == 0);
L
Liu Jicong 已提交
424
  // find existing meta file
L
Liu Jicong 已提交
425
  int metaVer = walFindCurMetaVer(pWal);
L
Liu Jicong 已提交
426
  if (metaVer == -1) {
L
Liu Jicong 已提交
427
    return -1;
L
Liu Jicong 已提交
428 429 430
  }
  char fnameStr[WAL_FILE_LEN];
  walBuildMetaName(pWal, metaVer, fnameStr);
L
Liu Jicong 已提交
431
  // read metafile
L
Liu Jicong 已提交
432 433 434
  int64_t fileSize = 0;
  taosStatFile(fnameStr, &fileSize, NULL);
  int   size = (int)fileSize;
wafwerar's avatar
wafwerar 已提交
435
  char* buf = taosMemoryMalloc(size + 5);
L
Liu Jicong 已提交
436
  if (buf == NULL) {
L
Liu Jicong 已提交
437
    terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
L
Liu Jicong 已提交
438 439
    return -1;
  }
L
Liu Jicong 已提交
440
  memset(buf, 0, size + 5);
441 442
  TdFilePtr pFile = taosOpenFile(fnameStr, TD_FILE_READ);
  if (pFile == NULL) {
L
Liu Jicong 已提交
443 444 445
    terrno = TSDB_CODE_WAL_FILE_CORRUPTED;
    return -1;
  }
446
  if (taosReadFile(pFile, buf, size) != size) {
L
Liu Jicong 已提交
447
    terrno = TAOS_SYSTEM_ERROR(errno);
448
    taosCloseFile(&pFile);
wafwerar's avatar
wafwerar 已提交
449
    taosMemoryFree(buf);
L
Liu Jicong 已提交
450 451
    return -1;
  }
L
Liu Jicong 已提交
452
  // load into fileInfoSet
453
  int code = walMetaDeserialize(pWal, buf);
454
  taosCloseFile(&pFile);
wafwerar's avatar
wafwerar 已提交
455
  taosMemoryFree(buf);
L
Liu Jicong 已提交
456
  return code;
L
Liu Jicong 已提交
457
}
458 459 460 461 462 463 464 465 466

int walRemoveMeta(SWal* pWal) {
  int metaVer = walFindCurMetaVer(pWal);
  if (metaVer == -1) return 0;
  char fnameStr[WAL_FILE_LEN];
  walBuildMetaName(pWal, metaVer, fnameStr);
  taosRemoveFile(fnameStr);
  return 0;
}