2021-11-07 07:58:32 +00:00
|
|
|
/*
|
|
|
|
|
* 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/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2022-04-08 06:01:01 +00:00
|
|
|
#include "vnodeInt.h"
|
2021-11-07 07:58:32 +00:00
|
|
|
|
2022-01-12 00:44:11 +00:00
|
|
|
static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg);
|
2021-11-08 02:04:24 +00:00
|
|
|
static void vnodeFree(SVnode *pVnode);
|
2021-11-08 02:17:51 +00:00
|
|
|
static int vnodeOpenImpl(SVnode *pVnode);
|
|
|
|
|
static void vnodeCloseImpl(SVnode *pVnode);
|
2021-11-08 02:04:24 +00:00
|
|
|
|
2022-04-14 12:36:35 +00:00
|
|
|
int vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
|
2022-04-15 05:47:57 +00:00
|
|
|
SVnodeInfo info = {0};
|
|
|
|
|
char dir[TSDB_FILENAME_LEN];
|
2022-04-15 03:48:51 +00:00
|
|
|
|
2022-04-14 12:36:35 +00:00
|
|
|
// TODO: check if directory exists
|
|
|
|
|
|
|
|
|
|
// check config
|
|
|
|
|
if (vnodeCheckCfg(pCfg) < 0) {
|
|
|
|
|
vError("vgId: %d failed to create vnode since: %s", pCfg->vgId, tstrerror(terrno));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create vnode env
|
2022-04-15 05:47:57 +00:00
|
|
|
if (tfsMkdir(pTfs, path) < 0) {
|
|
|
|
|
vError("vgId: %d failed to create vnode since: %s", pCfg->vgId, tstrerror(terrno));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-14 12:36:35 +00:00
|
|
|
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pTfs), TD_DIRSEP, path);
|
2022-04-15 05:47:57 +00:00
|
|
|
info.config = *pCfg;
|
|
|
|
|
|
|
|
|
|
if (vnodeSaveInfo(dir, &info) < 0 || vnodeCommitInfo(dir, &info) < 0) {
|
2022-04-14 12:36:35 +00:00
|
|
|
vError("vgId: %d failed to save vnode config since %s", pCfg->vgId, tstrerror(terrno));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-15 06:27:04 +00:00
|
|
|
vInfo("vgId: %d vnode is created", pCfg->vgId);
|
|
|
|
|
|
2022-04-14 12:36:35 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-16 07:04:25 +00:00
|
|
|
void vnodeDestroy(const char *path, STfs *pTfs) { tfsRmdir(pTfs, path); }
|
|
|
|
|
|
2022-04-16 07:16:10 +00:00
|
|
|
SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|
|
|
|
SVnode *pVnode = NULL;
|
|
|
|
|
SVnodeInfo info = {0};
|
|
|
|
|
char dir[TSDB_FILENAME_LEN];
|
|
|
|
|
int ret;
|
2021-11-08 02:04:24 +00:00
|
|
|
|
2022-04-16 07:16:10 +00:00
|
|
|
snprintf(dir, TSDB_FILENAME_LEN, "%s%s%s", tfsGetPrimaryPath(pTfs), TD_DIRSEP, path);
|
|
|
|
|
|
|
|
|
|
// load vnode info
|
|
|
|
|
ret = vnodeLoadInfo(dir, &info);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
vError("failed to open vnode from %s since %s", path, tstrerror(terrno));
|
2021-11-08 02:04:24 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-16 07:16:10 +00:00
|
|
|
info.config.pTfs = pTfs;
|
|
|
|
|
info.config.msgCb = msgCb;
|
|
|
|
|
|
|
|
|
|
// crate handle
|
|
|
|
|
pVnode = vnodeNew(dir, &info.config);
|
2021-11-08 02:04:24 +00:00
|
|
|
if (pVnode == NULL) {
|
|
|
|
|
// TODO: handle error
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-08 02:17:51 +00:00
|
|
|
// Open the vnode
|
|
|
|
|
if (vnodeOpenImpl(pVnode) < 0) {
|
|
|
|
|
// TODO: handle error
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-07 07:58:32 +00:00
|
|
|
return pVnode;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-08 02:17:51 +00:00
|
|
|
void vnodeClose(SVnode *pVnode) {
|
|
|
|
|
if (pVnode) {
|
|
|
|
|
vnodeCloseImpl(pVnode);
|
|
|
|
|
vnodeFree(pVnode);
|
|
|
|
|
}
|
2021-11-08 02:04:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------ STATIC METHODS ------------------------ */
|
2022-01-12 00:44:11 +00:00
|
|
|
static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg) {
|
2021-11-08 02:17:51 +00:00
|
|
|
SVnode *pVnode = NULL;
|
|
|
|
|
|
2022-03-25 16:29:53 +00:00
|
|
|
pVnode = (SVnode *)taosMemoryCalloc(1, sizeof(*pVnode));
|
2021-11-08 02:17:51 +00:00
|
|
|
if (pVnode == NULL) {
|
|
|
|
|
// TODO
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-21 11:08:25 +00:00
|
|
|
pVnode->msgCb = pVnodeCfg->msgCb;
|
2022-01-19 05:39:32 +00:00
|
|
|
pVnode->pTfs = pVnodeCfg->pTfs;
|
2021-11-08 02:17:51 +00:00
|
|
|
pVnode->path = strdup(path);
|
2021-11-22 07:02:53 +00:00
|
|
|
vnodeOptionsCopy(&(pVnode->config), pVnodeCfg);
|
2021-11-08 02:17:51 +00:00
|
|
|
|
2021-12-20 08:52:39 +00:00
|
|
|
tsem_init(&(pVnode->canCommit), 0, 1);
|
|
|
|
|
|
2021-11-08 05:55:51 +00:00
|
|
|
return pVnode;
|
2021-11-07 07:58:32 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-08 02:04:24 +00:00
|
|
|
static void vnodeFree(SVnode *pVnode) {
|
|
|
|
|
if (pVnode) {
|
2021-12-20 08:52:39 +00:00
|
|
|
tsem_destroy(&(pVnode->canCommit));
|
2022-03-25 16:29:53 +00:00
|
|
|
taosMemoryFreeClear(pVnode->path);
|
|
|
|
|
taosMemoryFree(pVnode);
|
2021-11-08 02:04:24 +00:00
|
|
|
}
|
2021-11-08 02:17:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int vnodeOpenImpl(SVnode *pVnode) {
|
2021-11-08 05:40:45 +00:00
|
|
|
char dir[TSDB_FILENAME_LEN];
|
|
|
|
|
|
2021-11-12 09:50:46 +00:00
|
|
|
if (vnodeOpenBufPool(pVnode) < 0) {
|
2021-11-08 06:50:20 +00:00
|
|
|
// TODO: handle error
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-08 05:40:45 +00:00
|
|
|
// Open meta
|
|
|
|
|
sprintf(dir, "%s/meta", pVnode->path);
|
2022-04-16 08:03:19 +00:00
|
|
|
pVnode->pMeta = metaOpen(dir, vBufPoolGetMAF(pVnode));
|
2021-11-08 06:21:10 +00:00
|
|
|
if (pVnode->pMeta == NULL) {
|
2021-11-08 05:40:45 +00:00
|
|
|
// TODO: handle error
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Open tsdb
|
|
|
|
|
sprintf(dir, "%s/tsdb", pVnode->path);
|
2022-03-23 02:44:32 +00:00
|
|
|
pVnode->pTsdb =
|
2022-04-16 07:50:05 +00:00
|
|
|
tsdbOpen(dir, TD_VID(pVnode), &(pVnode->config.tsdbCfg), vBufPoolGetMAF(pVnode), pVnode->pMeta, pVnode->pTfs);
|
2021-11-08 06:21:10 +00:00
|
|
|
if (pVnode->pTsdb == NULL) {
|
2021-11-08 05:40:45 +00:00
|
|
|
// TODO: handle error
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 07:49:05 +00:00
|
|
|
// Open WAL
|
|
|
|
|
sprintf(dir, "%s/wal", pVnode->path);
|
2021-11-24 10:37:15 +00:00
|
|
|
pVnode->pWal = walOpen(dir, &(pVnode->config.walCfg));
|
2021-11-16 07:49:05 +00:00
|
|
|
if (pVnode->pWal == NULL) {
|
|
|
|
|
// TODO: handle error
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2021-11-08 05:40:45 +00:00
|
|
|
|
2022-01-20 07:39:28 +00:00
|
|
|
// Open TQ
|
|
|
|
|
sprintf(dir, "%s/tq", pVnode->path);
|
2022-04-16 08:03:19 +00:00
|
|
|
pVnode->pTq = tqOpen(dir, pVnode, pVnode->pWal, pVnode->pMeta, vBufPoolGetMAF(pVnode));
|
2022-01-20 07:39:28 +00:00
|
|
|
if (pVnode->pTq == NULL) {
|
|
|
|
|
// TODO: handle error
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-24 01:41:09 +00:00
|
|
|
// Open Query
|
|
|
|
|
if (vnodeQueryOpen(pVnode)) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-08 02:17:51 +00:00
|
|
|
// TODO
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void vnodeCloseImpl(SVnode *pVnode) {
|
2022-01-07 09:55:23 +00:00
|
|
|
vnodeSyncCommit(pVnode);
|
2021-11-08 05:40:45 +00:00
|
|
|
if (pVnode) {
|
2021-11-16 07:49:05 +00:00
|
|
|
vnodeCloseBufPool(pVnode);
|
2021-11-08 05:40:45 +00:00
|
|
|
metaClose(pVnode->pMeta);
|
2021-12-16 07:24:33 +00:00
|
|
|
tsdbClose(pVnode->pTsdb);
|
|
|
|
|
tqClose(pVnode->pTq);
|
|
|
|
|
walClose(pVnode->pWal);
|
2022-03-09 08:13:46 +00:00
|
|
|
vnodeQueryClose(pVnode);
|
2021-11-08 05:40:45 +00:00
|
|
|
}
|
2022-01-20 07:18:33 +00:00
|
|
|
}
|