metaTable.c 12.0 KB
Newer Older
H
more  
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * 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
refact  
Hongze Cheng 已提交
14 15
 */

H
Hongze Cheng 已提交
16
#include "meta.h"
H
refact  
Hongze Cheng 已提交
17

H
Hongze Cheng 已提交
18 19 20 21 22 23 24 25
static int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME);
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME);
static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME);
static int metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME);
static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME);
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME);
static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME);
static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pME);
H
Hongze Cheng 已提交
26 27

int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
H
Hongze Cheng 已提交
28
  SMetaEntry  me = {0};
H
Hongze Cheng 已提交
29 30 31 32 33 34 35 36
  int         kLen = 0;
  int         vLen = 0;
  const void *pKey = NULL;
  const void *pVal = NULL;
  void       *pBuf = NULL;
  int32_t     szBuf = 0;
  void       *p = NULL;
  SCoder      coder = {0};
H
Hongze Cheng 已提交
37 38 39
  SMetaReader mr = {0};

  // validate req
H
Hongze Cheng 已提交
40
  metaReaderInit(&mr, pMeta, 0);
H
Hongze Cheng 已提交
41
  if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
H
Hongze Cheng 已提交
42 43
// TODO: just for pass case
#if 0
H
Hongze Cheng 已提交
44 45 46
    terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
    metaReaderClear(&mr);
    return -1;
H
Hongze Cheng 已提交
47 48 49 50
#else
    metaReaderClear(&mr);
    return 0;
#endif
H
Hongze Cheng 已提交
51
  }
H
Hongze Cheng 已提交
52
  metaReaderClear(&mr);
H
Hongze Cheng 已提交
53 54

  // set structs
H
Hongze Cheng 已提交
55
  me.version = version;
H
Hongze Cheng 已提交
56 57 58
  me.type = TSDB_SUPER_TABLE;
  me.uid = pReq->suid;
  me.name = pReq->name;
H
Hongze Cheng 已提交
59 60
  me.stbEntry.schema = pReq->schema;
  me.stbEntry.schemaTag = pReq->schemaTag;
H
Hongze Cheng 已提交
61

H
Hongze Cheng 已提交
62
  if (metaHandleEntry(pMeta, &me) < 0) goto _err;
H
Hongze Cheng 已提交
63

H
Hongze Cheng 已提交
64
  metaDebug("vgId:%d super table is created, name:%s uid: %" PRId64, TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
H
Hongze Cheng 已提交
65 66 67 68

  return 0;

_err:
H
Hongze Cheng 已提交
69
  metaError("vgId:%d failed to create super table: %s uid: %" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
H
Hongze Cheng 已提交
70 71 72 73 74
            pReq->suid, tstrerror(terrno));
  return -1;
}

int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) {
H
Hongze Cheng 已提交
75 76 77 78 79 80 81 82 83
  TDBC       *pNameIdxc = NULL;
  TDBC       *pUidIdxc = NULL;
  TDBC       *pCtbIdxc = NULL;
  SCtbIdxKey *pCtbIdxKey;
  const void *pKey = NULL;
  int         nKey;
  const void *pData = NULL;
  int         nData;
  int         c, ret;
H
Hongze Cheng 已提交
84

H
Hongze Cheng 已提交
85 86 87 88 89 90
  // prepare uid idx cursor
  tdbDbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  ret = tdbDbcMoveTo(pUidIdxc, &pReq->suid, sizeof(tb_uid_t), &c);
  if (ret < 0 || c != 0) {
    terrno = TSDB_CODE_VND_TB_NOT_EXIST;
    tdbDbcClose(pUidIdxc);
H
Hongze Cheng 已提交
91 92 93
    goto _err;
  }

H
Hongze Cheng 已提交
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 120 121 122 123 124 125 126
  // prepare name idx cursor
  tdbDbcOpen(pMeta->pNameIdx, &pNameIdxc, &pMeta->txn);
  ret = tdbDbcMoveTo(pNameIdxc, pReq->name, strlen(pReq->name) + 1, &c);
  if (ret < 0 || c != 0) {
    ASSERT(0);
  }

  tdbDbcDelete(pUidIdxc);
  tdbDbcDelete(pNameIdxc);
  tdbDbcClose(pUidIdxc);
  tdbDbcClose(pNameIdxc);

  // loop to drop each child table
  tdbDbcOpen(pMeta->pCtbIdx, &pCtbIdxc, &pMeta->txn);
  ret = tdbDbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = pReq->suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
  if (ret < 0 || (c < 0 && tdbDbcMoveToNext(pCtbIdxc) < 0)) {
    tdbDbcClose(pCtbIdxc);
    goto _exit;
  }

  for (;;) {
    tdbDbcGet(pCtbIdxc, &pKey, &nKey, NULL, NULL);
    pCtbIdxKey = (SCtbIdxKey *)pKey;

    if (pCtbIdxKey->suid > pReq->suid) break;

    // drop the child table (TODO)

    if (tdbDbcMoveToNext(pCtbIdxc) < 0) break;
  }

_exit:
  metaDebug("vgId:%d  super table %s uid:%" PRId64 " is dropped", TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
H
Hongze Cheng 已提交
127
  return 0;
H
Hongze Cheng 已提交
128 129 130 131 132

_err:
  metaError("vgId:%d failed to drop super table %s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
            pReq->suid, tstrerror(terrno));
  return -1;
H
Hongze Cheng 已提交
133 134
}

H
Hongze Cheng 已提交
135
int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq) {
H
Hongze Cheng 已提交
136 137
  SMetaEntry  me = {0};
  SMetaReader mr = {0};
H
Hongze Cheng 已提交
138 139 140 141 142

  // validate message
  if (pReq->type != TSDB_CHILD_TABLE && pReq->type != TSDB_NORMAL_TABLE) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto _err;
H
more  
Hongze Cheng 已提交
143 144
  }

H
Hongze Cheng 已提交
145 146
  // preprocess req
  pReq->uid = tGenIdPI64();
147
  pReq->ctime = taosGetTimestampMs();
H
Hongze Cheng 已提交
148

H
Hongze Cheng 已提交
149
  // validate req
H
Hongze Cheng 已提交
150
  metaReaderInit(&mr, pMeta, 0);
H
Hongze Cheng 已提交
151 152 153 154
  if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
    terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
    metaReaderClear(&mr);
    return -1;
H
Hongze Cheng 已提交
155
  }
H
Hongze Cheng 已提交
156
  metaReaderClear(&mr);
H
Hongze Cheng 已提交
157 158

  // build SMetaEntry
H
Hongze Cheng 已提交
159
  me.version = version;
H
Hongze Cheng 已提交
160 161 162 163 164 165 166 167 168 169 170
  me.type = pReq->type;
  me.uid = pReq->uid;
  me.name = pReq->name;
  if (me.type == TSDB_CHILD_TABLE) {
    me.ctbEntry.ctime = pReq->ctime;
    me.ctbEntry.ttlDays = pReq->ttl;
    me.ctbEntry.suid = pReq->ctb.suid;
    me.ctbEntry.pTags = pReq->ctb.pTag;
  } else {
    me.ntbEntry.ctime = pReq->ctime;
    me.ntbEntry.ttlDays = pReq->ttl;
H
Hongze Cheng 已提交
171
    me.ntbEntry.schema = pReq->ntb.schema;
H
more  
Hongze Cheng 已提交
172 173
  }

H
Hongze Cheng 已提交
174
  if (metaHandleEntry(pMeta, &me) < 0) goto _err;
H
Hongze Cheng 已提交
175

H
Hongze Cheng 已提交
176 177
  metaDebug("vgId:%d table %s uid %" PRId64 " is created, type:%" PRId8, TD_VID(pMeta->pVnode), pReq->name, pReq->uid,
            pReq->type);
H
refact  
Hongze Cheng 已提交
178
  return 0;
H
Hongze Cheng 已提交
179 180 181 182 183

_err:
  metaError("vgId:%d failed to create table:%s type:%s since %s", TD_VID(pMeta->pVnode), pReq->name,
            pReq->type == TSDB_CHILD_TABLE ? "child table" : "normal table", tstrerror(terrno));
  return -1;
H
refact  
Hongze Cheng 已提交
184 185
}

H
Hongze Cheng 已提交
186 187 188 189 190 191 192 193 194 195
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq) {
  TDBC       *pTbDbc = NULL;
  TDBC       *pUidIdxc = NULL;
  TDBC       *pNameIdxc = NULL;
  const void *pData;
  int         nData;
  tb_uid_t    uid;
  int64_t     tver;
  SMetaEntry  me = {0};
  SCoder      coder = {0};
H
Hongze Cheng 已提交
196 197 198
  int8_t      type;
  int64_t     ctime;
  tb_uid_t    suid;
H
Hongze Cheng 已提交
199
  int         c = 0, ret;
H
Hongze Cheng 已提交
200 201 202 203

  // search & delete the name idx
  tdbDbcOpen(pMeta->pNameIdx, &pNameIdxc, &pMeta->txn);
  ret = tdbDbcMoveTo(pNameIdxc, pReq->name, strlen(pReq->name) + 1, &c);
H
Hongze Cheng 已提交
204
  if (ret < 0 || !tdbDbcIsValid(pNameIdxc) || c) {
H
Hongze Cheng 已提交
205 206
    tdbDbcClose(pNameIdxc);
    terrno = TSDB_CODE_VND_TABLE_NOT_EXIST;
H
more  
Hongze Cheng 已提交
207 208 209
    return -1;
  }

H
Hongze Cheng 已提交
210 211 212
  ret = tdbDbcGet(pNameIdxc, NULL, NULL, &pData, &nData);
  if (ret < 0) {
    ASSERT(0);
H
more  
Hongze Cheng 已提交
213 214
    return -1;
  }
H
Hongze Cheng 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252

  uid = *(tb_uid_t *)pData;

  tdbDbcDelete(pNameIdxc);
  tdbDbcClose(pNameIdxc);

  // search & delete uid idx
  tdbDbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  ret = tdbDbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
  if (ret < 0 || c != 0) {
    ASSERT(0);
    return -1;
  }

  ret = tdbDbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
  if (ret < 0) {
    ASSERT(0);
    return -1;
  }

  tver = *(int64_t *)pData;
  tdbDbcDelete(pUidIdxc);
  tdbDbcClose(pUidIdxc);

  // search and get meta entry
  tdbDbcOpen(pMeta->pTbDb, &pTbDbc, &pMeta->txn);
  ret = tdbDbcMoveTo(pTbDbc, &(STbDbKey){.uid = uid, .version = tver}, sizeof(STbDbKey), &c);
  if (ret < 0 || c != 0) {
    ASSERT(0);
    return -1;
  }

  ret = tdbDbcGet(pTbDbc, NULL, NULL, &pData, &nData);
  if (ret < 0) {
    ASSERT(0);
    return -1;
  }

H
Hongze Cheng 已提交
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
  // decode entry
  void *pDataCopy = taosMemoryMalloc(nData);  // remove the copy (todo)
  memcpy(pDataCopy, pData, nData);
  tCoderInit(&coder, TD_LITTLE_ENDIAN, pDataCopy, nData, TD_DECODER);
  ret = metaDecodeEntry(&coder, &me);
  if (ret < 0) {
    ASSERT(0);
    return -1;
  }

  type = me.type;
  if (type == TSDB_CHILD_TABLE) {
    ctime = me.ctbEntry.ctime;
    suid = me.ctbEntry.suid;
  } else if (type == TSDB_NORMAL_TABLE) {
    ctime = me.ntbEntry.ctime;
    suid = 0;
  } else {
    ASSERT(0);
  }
H
Hongze Cheng 已提交
273

H
Hongze Cheng 已提交
274
  taosMemoryFree(pDataCopy);
H
Hongze Cheng 已提交
275 276
  tCoderClear(&coder);
  tdbDbcClose(pTbDbc);
H
more  
Hongze Cheng 已提交
277

H
Hongze Cheng 已提交
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
  if (type == TSDB_CHILD_TABLE) {
    // remove the pCtbIdx
    TDBC *pCtbIdxc = NULL;
    tdbDbcOpen(pMeta->pCtbIdx, &pCtbIdxc, &pMeta->txn);

    ret = tdbDbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = uid}, sizeof(SCtbIdxKey), &c);
    if (ret < 0 || c != 0) {
      ASSERT(0);
      return -1;
    }

    tdbDbcDelete(pCtbIdxc);
    tdbDbcClose(pCtbIdxc);

    // remove tags from pTagIdx (todo)
  } else if (type == TSDB_NORMAL_TABLE) {
    // remove from pSkmDb
  } else {
    ASSERT(0);
  }

  // remove from ttl (todo)
  if (ctime > 0) {
  }

H
refact  
Hongze Cheng 已提交
303 304
  return 0;
}
H
Hongze Cheng 已提交
305

H
Hongze Cheng 已提交
306
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
307 308 309 310 311 312
  STbDbKey tbDbKey;
  void    *pKey = NULL;
  void    *pVal = NULL;
  int      kLen = 0;
  int      vLen = 0;
  SCoder   coder = {0};
H
Hongze Cheng 已提交
313 314

  // set key and value
H
Hongze Cheng 已提交
315
  tbDbKey.version = pME->version;
H
Hongze Cheng 已提交
316 317 318 319
  tbDbKey.uid = pME->uid;

  pKey = &tbDbKey;
  kLen = sizeof(tbDbKey);
H
Hongze Cheng 已提交
320

wafwerar's avatar
wafwerar 已提交
321 322 323
  int32_t ret = 0;
  tEncodeSize(metaEncodeEntry, pME, vLen, ret);
  if (ret < 0) {
H
Hongze Cheng 已提交
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
    goto _err;
  }

  pVal = taosMemoryMalloc(vLen);
  if (pVal == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _err;
  }

  tCoderInit(&coder, TD_LITTLE_ENDIAN, pVal, vLen, TD_ENCODER);

  if (metaEncodeEntry(&coder, pME) < 0) {
    goto _err;
  }

  tCoderClear(&coder);

  // write to table.db
H
Hongze Cheng 已提交
342
  if (tdbDbInsert(pMeta->pTbDb, pKey, kLen, pVal, vLen, &pMeta->txn) < 0) {
H
Hongze Cheng 已提交
343 344 345 346 347 348 349 350 351 352 353
    goto _err;
  }

  taosMemoryFree(pVal);
  return 0;

_err:
  taosMemoryFree(pVal);
  return -1;
}

H
Hongze Cheng 已提交
354
static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
355
  return tdbDbInsert(pMeta->pUidIdx, &pME->uid, sizeof(tb_uid_t), &pME->version, sizeof(int64_t), &pMeta->txn);
H
Hongze Cheng 已提交
356 357
}

H
Hongze Cheng 已提交
358
static int metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
359
  return tdbDbInsert(pMeta->pNameIdx, pME->name, strlen(pME->name) + 1, &pME->uid, sizeof(tb_uid_t), &pMeta->txn);
H
Hongze Cheng 已提交
360 361
}

H
Hongze Cheng 已提交
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
  int32_t    ttlDays;
  int64_t    ctime;
  STtlIdxKey ttlKey;

  if (pME->type == TSDB_CHILD_TABLE) {
    ctime = pME->ctbEntry.ctime;
    ttlDays = pME->ctbEntry.ttlDays;
  } else if (pME->type == TSDB_NORMAL_TABLE) {
    ctime = pME->ntbEntry.ctime;
    ttlDays = pME->ntbEntry.ttlDays;
  } else {
    ASSERT(0);
  }

  if (ttlDays <= 0) return 0;

  ttlKey.dtime = ctime + ttlDays * 24 * 60 * 60;
  ttlKey.uid = pME->uid;

H
Hongze Cheng 已提交
382
  return tdbDbInsert(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, &pMeta->txn);
H
Hongze Cheng 已提交
383 384
}

H
Hongze Cheng 已提交
385 386
static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SCtbIdxKey ctbIdxKey = {.suid = pME->ctbEntry.suid, .uid = pME->uid};
H
Hongze Cheng 已提交
387
  return tdbDbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), NULL, 0, &pMeta->txn);
H
Hongze Cheng 已提交
388 389 390
}

static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
391 392 393 394
  // TODO
  return 0;
}

H
Hongze Cheng 已提交
395 396 397 398 399 400 401 402 403 404 405 406 407 408
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
  SCoder                coder = {0};
  void                 *pVal = NULL;
  int                   vLen = 0;
  int                   rcode = 0;
  SSkmDbKey             skmDbKey = {0};
  const SSchemaWrapper *pSW;

  if (pME->type == TSDB_SUPER_TABLE) {
    pSW = &pME->stbEntry.schema;
  } else if (pME->type == TSDB_NORMAL_TABLE) {
    pSW = &pME->ntbEntry.schema;
  } else {
    ASSERT(0);
H
Hongze Cheng 已提交
409 410
  }

H
Hongze Cheng 已提交
411 412
  skmDbKey.uid = pME->uid;
  skmDbKey.sver = pSW->sver;
H
Hongze Cheng 已提交
413 414

  // encode schema
wafwerar's avatar
wafwerar 已提交
415 416 417
  int32_t ret = 0;
  tEncodeSize(tEncodeSSchemaWrapper, pSW, vLen, ret);
  if (ret < 0) return -1;
H
Hongze Cheng 已提交
418
  pVal = taosMemoryMalloc(vLen);
H
Hongze Cheng 已提交
419 420 421 422 423 424
  if (pVal == NULL) {
    rcode = -1;
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
  }

H
Hongze Cheng 已提交
425 426 427
  tCoderInit(&coder, TD_LITTLE_ENDIAN, pVal, vLen, TD_ENCODER);
  tEncodeSSchemaWrapper(&coder, pSW);

H
Hongze Cheng 已提交
428
  if (tdbDbInsert(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), pVal, vLen, &pMeta->txn) < 0) {
H
Hongze Cheng 已提交
429 430 431 432 433
    rcode = -1;
    goto _exit;
  }

_exit:
H
Hongze Cheng 已提交
434
  taosMemoryFree(pVal);
H
Hongze Cheng 已提交
435
  tCoderClear(&coder);
H
Hongze Cheng 已提交
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
  return rcode;
}

static int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME) {
  // save to table.db
  if (metaSaveToTbDb(pMeta, pME) < 0) return -1;

  // update uid.idx
  if (metaUpdateUidIdx(pMeta, pME) < 0) return -1;

  // update name.idx
  if (metaUpdateNameIdx(pMeta, pME) < 0) return -1;

  if (pME->type == TSDB_CHILD_TABLE) {
    // update ctb.idx
    if (metaUpdateCtbIdx(pMeta, pME) < 0) return -1;

    // update tag.idx
    if (metaUpdateTagIdx(pMeta, pME) < 0) return -1;
  } else {
    // update schema.db
    if (metaSaveToSkmDb(pMeta, pME) < 0) return -1;
  }

  if (pME->type != TSDB_SUPER_TABLE) {
    if (metaUpdateTtlIdx(pMeta, pME) < 0) return -1;
  }

H
Hongze Cheng 已提交
464 465
  return 0;
}