tsdbFile.c 10.2 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * 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
TD-353  
Hongze Cheng 已提交
15

H
refact  
Hongze Cheng 已提交
16
#include "tsdbint.h"
H
TD-353  
Hongze Cheng 已提交
17

H
refact  
Hongze Cheng 已提交
18
static const char *TSDB_FNAME_SUFFIX[] = {
H
Hongze Cheng 已提交
19 20 21 22 23
    ".head",  // TSDB_FILE_HEAD
    ".data",  // TSDB_FILE_DATA
    ".last",  // TSDB_FILE_LAST
    "",       // TSDB_FILE_MAX
    "meta"    // TSDB_FILE_META
H
refact  
Hongze Cheng 已提交
24
};
H
TD-353  
Hongze Cheng 已提交
25

H
Hongze Cheng 已提交
26 27 28 29 30 31 32 33
static void  tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, char *fname);
static int   tsdbEncodeMFInfo(void **buf, SMFInfo *pInfo);
static void *tsdbDecodeMFInfo(void *buf, SMFInfo *pInfo);
static int   tsdbRollBackMFile(SMFile *pMFile);
static int   tsdbEncodeDFInfo(void **buf, SDFInfo *pInfo);
static void *tsdbDecodeDFInfo(void *buf, SDFInfo *pInfo);
static int   tsdbRollBackDFile(SDFile *pDFile);

H
refact  
Hongze Cheng 已提交
34
// ============== SMFile
H
Hongze Cheng 已提交
35
void tsdbInitMFile(SMFile *pMFile, SDiskID did, int vid, uint32_t ver) {
H
refact  
Hongze Cheng 已提交
36 37
  char fname[TSDB_FILENAME_LEN];

H
Hongze Cheng 已提交
38
  TSDB_FILE_SET_CLOSED(pMFile);
H
refact  
Hongze Cheng 已提交
39

H
Hongze Cheng 已提交
40 41
  memset(&(pMFile->info), 0, sizeof(pMFile->info));
  pMFile->info.magic = TSDB_FILE_INIT_MAGIC;
H
Hongze Cheng 已提交
42

H
refact  
Hongze Cheng 已提交
43
  tsdbGetFilename(vid, 0, ver, TSDB_FILE_META, fname);
H
Hongze Cheng 已提交
44 45 46 47 48 49
  tfsInitFile(TSDB_FILE_F(pMFile), did.level, did.id, fname);
}

void tsdbInitMFileEx(SMFile *pMFile, SMFile *pOMFile) {
  *pMFile = *pOMFile;
  TSDB_FILE_SET_CLOSED(pMFile);
H
Hongze Cheng 已提交
50
}
H
Hongze Cheng 已提交
51

H
refact  
Hongze Cheng 已提交
52
int tsdbEncodeSMFile(void **buf, SMFile *pMFile) {
H
Hongze Cheng 已提交
53
  int tlen = 0;
H
hzcheng 已提交
54

H
Hongze Cheng 已提交
55 56
  tlen += tsdbEncodeMFInfo(buf, &(pMFile->info));
  tlen += tfsEncodeFile(buf, &(pMFile->f));
H
hzcheng 已提交
57

H
Hongze Cheng 已提交
58
  return tlen;
H
Hongze Cheng 已提交
59 60
}

H
refact  
Hongze Cheng 已提交
61
void *tsdbDecodeSMFile(void *buf, SMFile *pMFile) {
H
Hongze Cheng 已提交
62 63
  buf = tsdbDecodeMFInfo(buf, &(pMFile->info));
  buf = tfsDecodeFile(buf, &(pMFile->f));
H
Hongze Cheng 已提交
64
  TSDB_FILE_SET_CLOSED(pMFile);
H
Hongze Cheng 已提交
65

H
Hongze Cheng 已提交
66 67
  return buf;
}
H
Hongze Cheng 已提交
68

H
Hongze Cheng 已提交
69 70 71 72 73
int tsdbApplyMFileChange(SMFile *from, SMFile *to) {
  ASSERT(from != NULL || to != NULL);

  if (from != NULL) {
    if (to == NULL) {
H
Hongze Cheng 已提交
74
      return tsdbRemoveMFile(from);
H
Hongze Cheng 已提交
75 76 77
    } else {
      if (tfsIsSameFile(TSDB_FILE_F(from), TSDB_FILE_F(to))) {
        if (from->info.size > to->info.size) {
H
Hongze Cheng 已提交
78
          tsdbRollBackMFile(to);
H
Hongze Cheng 已提交
79 80
        }
      } else {
H
Hongze Cheng 已提交
81
        return tsdbRemoveMFile(from);
H
Hongze Cheng 已提交
82 83 84 85 86 87 88
      }
    }
  }

  return 0;
}

H
Hongze Cheng 已提交
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
int tsdbCreateMFile(SMFile *pMFile) {
  ASSERT(pMFile->info.size == 0 && pMFile->info.magic == TSDB_FILE_INIT_MAGIC);

  char buf[TSDB_FILE_HEAD_SIZE] = "\0";

  if (tsdbOpenMFile(pMFile, O_WRONLY | O_CREAT | O_EXCL) < 0) {
    return -1;
  }

  void *ptr = buf;
  tsdbEncodeMFInfo(&ptr, &(pMFile->info));

  if (tsdbWriteMFile(pMFile, buf, TSDB_FILE_HEAD_SIZE) < 0) {
    tsdbCloseMFile(pMFile);
    tsdbRemoveMFile(pMFile);
    return -1;
  }

  pMFile->info.size += TSDB_FILE_HEAD_SIZE;

  return 0;
}

int tsdbUpdateMFileHeader(SMFile *pMFile) {
  char buf[TSDB_FILE_HEAD_SIZE] = "\0";

  if (tsdbSeekMFile(pMFile, 0, SEEK_SET) < 0) {
    return -1;
  }

  void *ptr = buf;
H
Hongze Cheng 已提交
120
  tsdbEncodeMFInfo(&ptr, TSDB_FILE_INFO(pMFile));
H
Hongze Cheng 已提交
121 122 123 124 125 126 127 128

  if (tsdbWriteMFile(pMFile, buf, TSDB_FILE_HEAD_SIZE) < 0) {
    return -1;
  }

  return 0;
}

H
Hongze Cheng 已提交
129 130
static int tsdbEncodeMFInfo(void **buf, SMFInfo *pInfo) {
  int tlen = 0;
H
Hongze Cheng 已提交
131

H
Hongze Cheng 已提交
132 133 134 135 136
  tlen += taosEncodeVariantI64(buf, pInfo->size);
  tlen += taosEncodeVariantI64(buf, pInfo->tombSize);
  tlen += taosEncodeVariantI64(buf, pInfo->nRecords);
  tlen += taosEncodeVariantI64(buf, pInfo->nDels);
  tlen += taosEncodeFixedU32(buf, pInfo->magic);
H
Hongze Cheng 已提交
137

H
Hongze Cheng 已提交
138
  return tlen;
H
Hongze Cheng 已提交
139 140
}

H
Hongze Cheng 已提交
141 142 143 144 145 146 147 148
static void *tsdbDecodeMFInfo(void *buf, SMFInfo *pInfo) {
  buf = taosDecodeVariantI64(buf, &(pInfo->size));
  buf = taosDecodeVariantI64(buf, &(pInfo->tombSize));
  buf = taosDecodeVariantI64(buf, &(pInfo->nRecords));
  buf = taosDecodeVariantI64(buf, &(pInfo->nDels));
  buf = taosDecodeFixedU32(buf, &(pInfo->magic));

  return buf;
H
Hongze Cheng 已提交
149 150
}

H
Hongze Cheng 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
static int tsdbRollBackMFile(SMFile *pMFile) {
  SMFile mf = *pMFile;

  if (tsdbOpenMFile(&mf, O_WRONLY) < 0) {
    return -1;
  }

  if (taosFtruncate(TSDB_FILE_FD(&mf), pMFile->info.size) < 0) {
    terrno = TAOS_SYSTEM_ERROR(errno);
    tsdbCloseMFile(&mf);
    return -1;
  }

  if (tsdbUpdateMFileHeader(&mf) < 0) {
    tsdbCloseMFile(&mf);
    return -1;
  }

  TSDB_FILE_FSYNC(&mf);

  tsdbCloseMFile(&mf);
  return 0;
}

H
Hongze Cheng 已提交
175
// ============== Operations on SDFile
H
Hongze Cheng 已提交
176
void tsdbInitDFile(SDFile *pDFile, SDiskID did, int vid, int fid, uint32_t ver, TSDB_FILE_T ftype) {
H
refact  
Hongze Cheng 已提交
177 178
  char fname[TSDB_FILENAME_LEN];

H
Hongze Cheng 已提交
179
  TSDB_FILE_SET_CLOSED(pDFile);
H
refact  
Hongze Cheng 已提交
180

H
Hongze Cheng 已提交
181 182
  memset(&(pDFile->info), 0, sizeof(pDFile->info));
  pDFile->info.magic = TSDB_FILE_INIT_MAGIC;
H
refact  
Hongze Cheng 已提交
183

H
Hongze Cheng 已提交
184
  tsdbGetFilename(vid, fid, ver, ftype, fname);
H
Hongze Cheng 已提交
185
  tfsInitFile(&(pDFile->f), did.level, did.id, fname);
H
Hongze Cheng 已提交
186 187
}

H
Hongze Cheng 已提交
188 189
void tsdbInitDFileEx(SDFile *pDFile, SDFile *pODFile) {
  *pDFile = *pODFile;
H
Hongze Cheng 已提交
190 191 192
  TSDB_FILE_SET_CLOSED(pDFile);
}

H
refact  
Hongze Cheng 已提交
193
int tsdbEncodeSDFile(void **buf, SDFile *pDFile) {
H
Hongze Cheng 已提交
194
  int tlen = 0;
195

H
Hongze Cheng 已提交
196 197
  tlen += tsdbEncodeDFInfo(buf, &(pDFile->info));
  tlen += tfsEncodeFile(buf, &(pDFile->f));
H
TD-34  
hzcheng 已提交
198

H
Hongze Cheng 已提交
199
  return tlen;
H
TD-34  
hzcheng 已提交
200 201
}

H
refact  
Hongze Cheng 已提交
202
void *tsdbDecodeSDFile(void *buf, SDFile *pDFile) {
H
Hongze Cheng 已提交
203 204
  buf = tsdbDecodeDFInfo(buf, &(pDFile->info));
  buf = tfsDecodeFile(buf, &(pDFile->f));
H
Hongze Cheng 已提交
205
  TSDB_FILE_SET_CLOSED(pDFile);
H
TD-353  
Hongze Cheng 已提交
206

H
Hongze Cheng 已提交
207
  return buf;
H
TD-353  
Hongze Cheng 已提交
208
}
H
TD-353  
Hongze Cheng 已提交
209

H
Hongze Cheng 已提交
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
int tsdbCreateDFile(SDFile *pDFile) {
  ASSERT(pDFile->info.size == 0 && pDFile->info.magic == TSDB_FILE_INIT_MAGIC);

  char buf[TSDB_FILE_HEAD_SIZE] = "\0";

  if (tsdbOpenDFile(pDFile, O_WRONLY | O_CREAT | O_EXCL) < 0) {
    return -1;
  }

  void *ptr = buf;
  tsdbEncodeDFInfo(&ptr, &(pDFile->info));

  if (tsdbWriteDFile(pDFile, buf, TSDB_FILE_HEAD_SIZE) < 0) {
    tsdbCloseDFile(pDFile);
    tsdbRemoveDFile(pDFile);
    return -1;
  }

  pDFile->info.size += TSDB_FILE_HEAD_SIZE;

H
Hongze Cheng 已提交
230 231 232
  return 0;
}

H
Hongze Cheng 已提交
233 234 235 236 237 238
int tsdbUpdateDFileHeader(SDFile *pDFile) {
  char buf[TSDB_FILE_HEAD_SIZE] = "\0";

  if (tsdbSeekDFile(pDFile, 0, SEEK_SET) < 0) {
    return -1;
  }
H
Hongze Cheng 已提交
239

H
Hongze Cheng 已提交
240 241
  void *ptr = buf;
  tsdbEncodeDFInfo(&ptr, &(pDFile->info));
H
Hongze Cheng 已提交
242

H
Hongze Cheng 已提交
243
  if (tsdbWriteDFile(pDFile, buf, TSDB_FILE_HEAD_SIZE) < 0) {
H
Hongze Cheng 已提交
244 245
    return -1;
  }
H
Hongze Cheng 已提交
246 247

  return 0;
H
Hongze Cheng 已提交
248 249
}

H
Hongze Cheng 已提交
250
static int tsdbEncodeDFInfo(void **buf, SDFInfo *pInfo) {
H
TD-353  
Hongze Cheng 已提交
251
  int tlen = 0;
H
Hongze Cheng 已提交
252

H
Hongze Cheng 已提交
253
  tlen += taosEncodeFixedU32(buf, pInfo->magic);
H
TD-353  
Hongze Cheng 已提交
254 255 256
  tlen += taosEncodeFixedU32(buf, pInfo->len);
  tlen += taosEncodeFixedU32(buf, pInfo->totalBlocks);
  tlen += taosEncodeFixedU32(buf, pInfo->totalSubBlocks);
H
Hongze Cheng 已提交
257 258 259
  tlen += taosEncodeFixedU32(buf, pInfo->offset);
  tlen += taosEncodeFixedU64(buf, pInfo->size);
  tlen += taosEncodeFixedU64(buf, pInfo->tombSize);
H
TD-353  
Hongze Cheng 已提交
260

H
TD-353  
Hongze Cheng 已提交
261
  return tlen;
H
TD-353  
Hongze Cheng 已提交
262 263
}

H
Hongze Cheng 已提交
264
static void *tsdbDecodeDFInfo(void *buf, SDFInfo *pInfo) {
H
Hongze Cheng 已提交
265
  buf = taosDecodeFixedU32(buf, &(pInfo->magic));
H
TD-353  
Hongze Cheng 已提交
266 267 268
  buf = taosDecodeFixedU32(buf, &(pInfo->len));
  buf = taosDecodeFixedU32(buf, &(pInfo->totalBlocks));
  buf = taosDecodeFixedU32(buf, &(pInfo->totalSubBlocks));
H
Hongze Cheng 已提交
269 270 271
  buf = taosDecodeFixedU32(buf, &(pInfo->offset));
  buf = taosDecodeFixedU64(buf, &(pInfo->size));
  buf = taosDecodeFixedU64(buf, &(pInfo->tombSize));
H
TD-353  
Hongze Cheng 已提交
272 273 274 275

  return buf;
}

H
Hongze Cheng 已提交
276 277 278 279 280 281 282 283 284
static int tsdbApplyDFileChange(SDFile *from, SDFile *to) {
  ASSERT(from != NULL || to != NULL);

  if (from != NULL) {
    if (to == NULL) {
      tsdbRemoveDFile(from);
    } else {
      if (tfsIsSameFile(TSDB_FILE_F(from), TSDB_FILE_F(to))) {
        if (from->info.size > to->info.size) {
H
Hongze Cheng 已提交
285
          tsdbRollBackDFile(to);
H
Hongze Cheng 已提交
286 287 288 289 290 291 292 293 294 295
        }
      } else {
        tsdbRemoveDFile(from);
      }
    }
  }

  return 0;
}

H
Hongze Cheng 已提交
296
static int tsdbRollBackDFile(SDFile *pDFile) {
H
Hongze Cheng 已提交
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
  SDFile df = *pDFile;

  if (tsdbOpenDFile(&df, O_WRONLY) < 0) {
    return -1;
  }

  if (taosFtruncate(TSDB_FILE_FD(&df), pDFile->info.size) < 0) {
    terrno = TAOS_SYSTEM_ERROR(errno);
    tsdbCloseDFile(&df);
    return -1;
  }

  if (tsdbUpdateDFileHeader(&df) < 0) {
    tsdbCloseDFile(&df);
    return -1;
  }

H
Hongze Cheng 已提交
314 315
  TSDB_FILE_FSYNC(&df);

H
Hongze Cheng 已提交
316 317 318 319
  tsdbCloseDFile(&df);
  return 0;
}

H
Hongze Cheng 已提交
320
// ============== Operations on SDFileSet
H
Hongze Cheng 已提交
321
void tsdbInitDFileSet(SDFileSet *pSet, SDiskID did, int vid, int fid, uint32_t ver) {
H
Hongze Cheng 已提交
322 323
  pSet->fid = fid;
  pSet->state = 0;
H
Hongze Cheng 已提交
324

H
Hongze Cheng 已提交
325 326
  for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
    SDFile *pDFile = TSDB_DFILE_IN_SET(pSet, ftype);
H
Hongze Cheng 已提交
327
    tsdbInitDFile(pDFile, did, vid, fid, ver, ftype);
H
Hongze Cheng 已提交
328 329 330
  }
}

H
Hongze Cheng 已提交
331
void tsdbInitDFileSetEx(SDFileSet *pSet, SDFileSet *pOSet) {
H
Hongze Cheng 已提交
332
  for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
H
Hongze Cheng 已提交
333
    tsdbInitDFileEx(TSDB_DFILE_IN_SET(pSet, ftype), TSDB_DFILE_IN_SET(pOSet, ftype));
H
Hongze Cheng 已提交
334
  }
H
Hongze Cheng 已提交
335 336
}

H
Hongze Cheng 已提交
337 338
int tsdbEncodeDFileSet(void **buf, SDFileSet *pSet) {
  int tlen = 0;
H
Hongze Cheng 已提交
339

H
Hongze Cheng 已提交
340 341
  for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
    tlen += tsdbEncodeSDFile(buf, TSDB_DFILE_IN_SET(pSet, ftype));
H
Hongze Cheng 已提交
342
  }
H
Hongze Cheng 已提交
343

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

H
Hongze Cheng 已提交
347
void *tsdbDecodeDFileSet(void *buf, SDFileSet *pSet) {
H
Hongze Cheng 已提交
348
  for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
H
Hongze Cheng 已提交
349
    buf = tsdbDecodeSDFile(buf, TSDB_DFILE_IN_SET(pSet, ftype));
H
Hongze Cheng 已提交
350
  }
H
Hongze Cheng 已提交
351
  return buf;
H
Hongze Cheng 已提交
352 353
}

H
Hongze Cheng 已提交
354
int tsdbApplyDFileSetChange(SDFileSet *from, SDFileSet *to) {
H
Hongze Cheng 已提交
355 356 357 358 359 360 361 362 363
  for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
    if (tsdbApplyDFileChange(TSDB_DFILE_IN_SET(from, ftype), TSDB_DFILE_IN_SET(to, ftype)) < 0) {
      return -1;
    }
  }

  return 0;
}

H
Hongze Cheng 已提交
364 365 366 367 368 369 370 371 372
int tsdbCreateDFileSet(SDFileSet *pSet) {
  for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
    if (tsdbCreateDFile(TSDB_DFILE_IN_SET(pSet, ftype)) < 0) {
      tsdbCloseDFileSet(pSet);
      tsdbRemoveDFileSet(pSet);
      return -1;
    }
  }

H
Hongze Cheng 已提交
373 374
  return 0;
}
H
Hongze Cheng 已提交
375

H
Hongze Cheng 已提交
376
int tsdbUpdateDFileSetHeader(SDFileSet *pSet) {
H
Hongze Cheng 已提交
377
  for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
H
Hongze Cheng 已提交
378
    if (tsdbUpdateDFileHeader(TSDB_DFILE_IN_SET(pSet, ftype)) < 0) {
H
Hongze Cheng 已提交
379 380 381
      return -1;
    }
  }
H
Hongze Cheng 已提交
382
  return 0;
H
refact  
Hongze Cheng 已提交
383 384
}

H
Hongze Cheng 已提交
385
static void tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, char *fname) {
H
refact  
Hongze Cheng 已提交
386 387 388 389
  ASSERT(ftype != TSDB_FILE_MAX);

  if (ftype < TSDB_FILE_MAX) {
    if (ver == 0) {
H
Hongze Cheng 已提交
390
      snprintf(fname, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/data/v%df%d.%s", vid, vid, fid, TSDB_FNAME_SUFFIX[ftype]);
H
refact  
Hongze Cheng 已提交
391
    } else {
H
Hongze Cheng 已提交
392 393
      snprintf(fname, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/data/v%df%d.%s-ver%" PRIu32, vid, vid, fid,
               TSDB_FNAME_SUFFIX[ftype], ver);
H
refact  
Hongze Cheng 已提交
394 395 396
    }
  } else {
    if (ver == 0) {
H
Hongze Cheng 已提交
397
      snprintf(fname, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/%s", vid, TSDB_FNAME_SUFFIX[ftype]);
H
refact  
Hongze Cheng 已提交
398
    } else {
H
Hongze Cheng 已提交
399
      snprintf(fname, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/%s-ver%" PRIu32, vid, TSDB_FNAME_SUFFIX[ftype], ver);
H
refact  
Hongze Cheng 已提交
400 401
    }
  }
H
Hongze Cheng 已提交
402
}