metaTable.c 11.9 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
  int         kLen = 0;
  int         vLen = 0;
  const void *pKey = NULL;
  const void *pVal = NULL;
  void       *pBuf = NULL;
  int32_t     szBuf = 0;
  void       *p = NULL;
H
Hongze Cheng 已提交
36 37 38
  SMetaReader mr = {0};

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

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

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

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

  return 0;

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

int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) {
H
Hongze Cheng 已提交
74 75 76 77 78 79 80 81 82
  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 已提交
83

H
Hongze Cheng 已提交
84 85 86 87 88 89
  // 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 已提交
90 91 92
    goto _err;
  }

H
Hongze Cheng 已提交
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 120 121 122 123 124 125
  // 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 已提交
126
  return 0;
H
Hongze Cheng 已提交
127 128 129 130 131

_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 已提交
132 133
}

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

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

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

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

  // build SMetaEntry
H
Hongze Cheng 已提交
158
  me.version = version;
H
Hongze Cheng 已提交
159 160 161 162 163 164 165 166 167 168 169
  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 已提交
170
    me.ntbEntry.schema = pReq->ntb.schema;
H
more  
Hongze Cheng 已提交
171 172
  }

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

H
Hongze Cheng 已提交
175 176
  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 已提交
177
  return 0;
H
Hongze Cheng 已提交
178 179 180 181 182

_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 已提交
183 184
}

H
Hongze Cheng 已提交
185 186 187 188 189 190 191 192 193
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};
H
Hongze Cheng 已提交
194
  SDecoder    coder = {0};
H
Hongze Cheng 已提交
195 196 197
  int8_t      type;
  int64_t     ctime;
  tb_uid_t    suid;
H
Hongze Cheng 已提交
198
  int         c = 0, ret;
H
Hongze Cheng 已提交
199 200 201 202

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

H
Hongze Cheng 已提交
209 210 211
  ret = tdbDbcGet(pNameIdxc, NULL, NULL, &pData, &nData);
  if (ret < 0) {
    ASSERT(0);
H
more  
Hongze Cheng 已提交
212 213
    return -1;
  }
H
Hongze Cheng 已提交
214 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

  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 已提交
252 253 254
  // decode entry
  void *pDataCopy = taosMemoryMalloc(nData);  // remove the copy (todo)
  memcpy(pDataCopy, pData, nData);
H
Hongze Cheng 已提交
255
  tDecoderInit(&coder, pDataCopy, nData);
H
Hongze Cheng 已提交
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
  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 已提交
272

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

H
Hongze Cheng 已提交
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
  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 已提交
302 303
  return 0;
}
H
Hongze Cheng 已提交
304

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

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

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

wafwerar's avatar
wafwerar 已提交
320 321 322
  int32_t ret = 0;
  tEncodeSize(metaEncodeEntry, pME, vLen, ret);
  if (ret < 0) {
H
Hongze Cheng 已提交
323 324 325 326 327 328 329 330 331
    goto _err;
  }

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

H
Hongze Cheng 已提交
332
  tEncoderInit(&coder, pVal, vLen);
H
Hongze Cheng 已提交
333 334 335 336 337

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

H
Hongze Cheng 已提交
338
  tEncoderClear(&coder);
H
Hongze Cheng 已提交
339 340

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

  taosMemoryFree(pVal);
  return 0;

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

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

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

H
Hongze Cheng 已提交
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
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 已提交
381
  return tdbDbInsert(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, &pMeta->txn);
H
Hongze Cheng 已提交
382 383
}

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

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

H
Hongze Cheng 已提交
394
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
395
  SEncoder              coder = {0};
H
Hongze Cheng 已提交
396 397 398 399 400 401 402 403 404 405 406 407
  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 已提交
408 409
  }

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

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

H
Hongze Cheng 已提交
424
  tEncoderInit(&coder, pVal, vLen);
H
Hongze Cheng 已提交
425 426
  tEncodeSSchemaWrapper(&coder, pSW);

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

_exit:
H
Hongze Cheng 已提交
433
  taosMemoryFree(pVal);
H
Hongze Cheng 已提交
434
  tEncoderClear(&coder);
H
Hongze Cheng 已提交
435 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
  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 已提交
463 464
  return 0;
}