From 90e23fb8c0f10c3f8fa3ce3940af701c49903c46 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Sun, 26 Jul 2020 16:33:18 +0800 Subject: [PATCH] [TD-998] --- src/inc/taosdef.h | 1 + src/inc/taosmsg.h | 1 + src/mnode/inc/mnodeCluster.h | 38 ++++++ src/mnode/inc/mnodeDef.h | 8 ++ src/mnode/inc/mnodeSdb.h | 19 +-- src/mnode/src/mnodeAcct.c | 4 +- src/mnode/src/mnodeCluster.c | 229 +++++++++++++++++++++++++++++++++++ src/mnode/src/mnodeMain.c | 2 + src/mnode/src/mnodeSdb.c | 2 + src/mnode/src/mnodeShow.c | 2 + 10 files changed, 295 insertions(+), 11 deletions(-) create mode 100644 src/mnode/inc/mnodeCluster.h create mode 100644 src/mnode/src/mnodeCluster.c diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index 30523dc25c..1bb185e448 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -377,6 +377,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size); #define TSDB_ORDER_ASC 1 #define TSDB_ORDER_DESC 2 +#define TSDB_DEFAULT_CLUSTER_HASH_SIZE 1 #define TSDB_DEFAULT_MNODES_HASH_SIZE 5 #define TSDB_DEFAULT_DNODES_HASH_SIZE 10 #define TSDB_DEFAULT_ACCOUNTS_HASH_SIZE 10 diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index e095567d75..de7c6c8268 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -139,6 +139,7 @@ enum _mgmt_table { TSDB_MGMT_TABLE_GRANTS, TSDB_MGMT_TABLE_VNODES, TSDB_MGMT_TABLE_STREAMTABLES, + TSDB_MGMT_TABLE_CLUSTER, TSDB_MGMT_TABLE_MAX, }; diff --git a/src/mnode/inc/mnodeCluster.h b/src/mnode/inc/mnodeCluster.h new file mode 100644 index 0000000000..3be5d601af --- /dev/null +++ b/src/mnode/inc/mnodeCluster.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef TDENGINE_MNODE_CLUSTER_H +#define TDENGINE_MNODE_CLUSTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct SClusterObj; + +int32_t mnodeInitCluster(); +void mnodeCleanupCluster(); +int32_t mnodeGetClusterId(); +void mnodeUpdateClusterId(); +void * mnodeGetCluster(int32_t clusterId); +void * mnodeGetNextCluster(void *pIter, struct SClusterObj **pCluster); +void mnodeIncClusterRef(struct SClusterObj *pCluster); +void mnodeDecClusterRef(struct SClusterObj *pCluster); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mnode/inc/mnodeDef.h b/src/mnode/inc/mnodeDef.h index a454f413f0..62028bc820 100644 --- a/src/mnode/inc/mnodeDef.h +++ b/src/mnode/inc/mnodeDef.h @@ -36,6 +36,14 @@ struct define notes: 3. The fields behind the updataEnd field can be changed; */ +typedef struct SClusterObj { + int32_t clusterId; + int64_t createdTime; + int8_t reserved[36]; + int8_t updateEnd[4]; + int32_t refCount; +} SClusterObj; + typedef struct SDnodeObj { int32_t dnodeId; int32_t openVnodes; diff --git a/src/mnode/inc/mnodeSdb.h b/src/mnode/inc/mnodeSdb.h index 0c47f684f8..cadd1b1f3d 100644 --- a/src/mnode/inc/mnodeSdb.h +++ b/src/mnode/inc/mnodeSdb.h @@ -23,15 +23,16 @@ extern "C" { struct SMnodeMsg; typedef enum { - SDB_TABLE_DNODE = 0, - SDB_TABLE_MNODE = 1, - SDB_TABLE_ACCOUNT = 2, - SDB_TABLE_USER = 3, - SDB_TABLE_DB = 4, - SDB_TABLE_VGROUP = 5, - SDB_TABLE_STABLE = 6, - SDB_TABLE_CTABLE = 7, - SDB_TABLE_MAX = 8 + SDB_TABLE_CLUSTER = 0, + SDB_TABLE_DNODE = 1, + SDB_TABLE_MNODE = 2, + SDB_TABLE_ACCOUNT = 3, + SDB_TABLE_USER = 4, + SDB_TABLE_DB = 5, + SDB_TABLE_VGROUP = 6, + SDB_TABLE_STABLE = 7, + SDB_TABLE_CTABLE = 8, + SDB_TABLE_MAX = 9 } ESdbTable; typedef enum { diff --git a/src/mnode/src/mnodeAcct.c b/src/mnode/src/mnodeAcct.c index 2d6e1ae007..287e8bb723 100644 --- a/src/mnode/src/mnodeAcct.c +++ b/src/mnode/src/mnodeAcct.c @@ -64,7 +64,7 @@ static int32_t mnodeAcctActionUpdate(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeActionActionEncode(SSdbOper *pOper) { +static int32_t mnodeAcctActionEncode(SSdbOper *pOper) { SAcctObj *pAcct = pOper->pObj; memcpy(pOper->rowData, pAcct, tsAcctUpdateSize); pOper->rowSize = tsAcctUpdateSize; @@ -109,7 +109,7 @@ int32_t mnodeInitAccts() { .insertFp = mnodeAcctActionInsert, .deleteFp = mnodeAcctActionDelete, .updateFp = mnodeAcctActionUpdate, - .encodeFp = mnodeActionActionEncode, + .encodeFp = mnodeAcctActionEncode, .decodeFp = mnodeAcctActionDecode, .destroyFp = mnodeAcctActionDestroy, .restoredFp = mnodeAcctActionRestored diff --git a/src/mnode/src/mnodeCluster.c b/src/mnode/src/mnodeCluster.c new file mode 100644 index 0000000000..e83f31cc44 --- /dev/null +++ b/src/mnode/src/mnodeCluster.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "os.h" +#include "taoserror.h" +#include "ttime.h" +#include "dnode.h" +#include "mnodeDef.h" +#include "mnodeInt.h" +#include "mnodeCluster.h" +#include "mnodeSdb.h" +#include "mnodeShow.h" +#include "tglobal.h" + +static void * tsClusterSdb = NULL; +static int32_t tsClusterUpdateSize; +static int32_t tsClusterId; +static int32_t mnodeCreateCluster(); + +static int32_t mnodeGetClusterMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); +static int32_t mnodeRetrieveClusters(SShowObj *pShow, char *data, int32_t rows, void *pConn); + +static int32_t mnodeClusterActionDestroy(SSdbOper *pOper) { + tfree(pOper->pObj); + return TSDB_CODE_SUCCESS; +} + +static int32_t mnodeClusterActionInsert(SSdbOper *pOper) { + return TSDB_CODE_SUCCESS; +} + +static int32_t mnodeClusterActionDelete(SSdbOper *pOper) { + return TSDB_CODE_SUCCESS; +} + +static int32_t mnodeClusterActionUpdate(SSdbOper *pOper) { + return TSDB_CODE_SUCCESS; +} + +static int32_t mnodeClusterActionEncode(SSdbOper *pOper) { + SClusterObj *pCluster = pOper->pObj; + memcpy(pOper->rowData, pCluster, tsClusterUpdateSize); + pOper->rowSize = tsClusterUpdateSize; + return TSDB_CODE_SUCCESS; +} + +static int32_t mnodeClusterActionDecode(SSdbOper *pOper) { + SClusterObj *pCluster = (SClusterObj *) calloc(1, sizeof(SClusterObj)); + if (pCluster == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; + + memcpy(pCluster, pOper->rowData, tsClusterUpdateSize); + pOper->pObj = pCluster; + return TSDB_CODE_SUCCESS; +} + +static int32_t mnodeClusterActionRestored() { + int32_t numOfRows = sdbGetNumOfRows(tsClusterSdb); + if (numOfRows <= 0 && dnodeIsFirstDeploy()) { + mInfo("dnode first deploy, create cluster"); + int32_t code = mnodeCreateCluster(); + if (code != TSDB_CODE_SUCCESS) { + mError("failed to create cluster, reason:%s", tstrerror(code)); + return code; + } + } + + return TSDB_CODE_SUCCESS; +} + +int32_t mnodeInitCluster() { + SClusterObj tObj; + tsClusterUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; + + SSdbTableDesc tableDesc = { + .tableId = SDB_TABLE_CLUSTER, + .tableName = "cluster", + .hashSessions = TSDB_DEFAULT_CLUSTER_HASH_SIZE, + .maxRowSize = tsClusterUpdateSize, + .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, + .keyType = SDB_KEY_INT, + .insertFp = mnodeClusterActionInsert, + .deleteFp = mnodeClusterActionDelete, + .updateFp = mnodeClusterActionUpdate, + .encodeFp = mnodeClusterActionEncode, + .decodeFp = mnodeClusterActionDecode, + .destroyFp = mnodeClusterActionDestroy, + .restoredFp = mnodeClusterActionRestored + }; + + tsClusterSdb = sdbOpenTable(&tableDesc); + if (tsClusterSdb == NULL) { + mError("table:%s, failed to create hash", tableDesc.tableName); + return -1; + } + + mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_CLUSTER, mnodeGetClusterMeta); + mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_CLUSTER, mnodeRetrieveClusters); + + mDebug("table:%s, hash is created", tableDesc.tableName); + return TSDB_CODE_SUCCESS; +} + +void mnodeCleanupCluster() { + sdbCloseTable(tsClusterSdb); + tsClusterSdb = NULL; +} + +void *mnodeGetCluster(int32_t clusterId) { + return sdbGetRow(tsClusterSdb, &clusterId); +} + +void *mnodeGetNextCluster(void *pIter, SClusterObj **pCluster) { + return sdbFetchRow(tsClusterSdb, pIter, (void **)pCluster); +} + +void mnodeIncClusterRef(SClusterObj *pCluster) { + sdbIncRef(tsClusterSdb, pCluster); +} + +void mnodeDecClusterRef(SClusterObj *pCluster) { + sdbDecRef(tsClusterSdb, pCluster); +} + +static int32_t mnodeCreateCluster() { + int32_t numOfClusters = sdbGetNumOfRows(tsClusterSdb); + if (numOfClusters != 0) return TSDB_CODE_SUCCESS; + + SClusterObj *pCluster = malloc(sizeof(SClusterObj)); + memset(pCluster, 0, sizeof(SClusterObj)); + pCluster->createdTime = taosGetTimestampMs(); + pCluster->clusterId = (pCluster->createdTime >> 32) & (pCluster->createdTime) & (*(int32_t*)tsFirst); + + SSdbOper oper = { + .type = SDB_OPER_GLOBAL, + .table = tsClusterSdb, + .pObj = pCluster, + }; + + return sdbInsertRow(&oper); +} + +int32_t mnodeGetClusterId() { + return tsClusterId; +} + +void mnodeUpdateClusterId() { + SClusterObj *pCluster = NULL; + mnodeGetNextCluster(NULL, &pCluster); + if (pCluster != NULL) { + tsClusterId = pCluster->clusterId; + mnodeDecClusterRef(pCluster); + mInfo("cluster id is %d", tsClusterId); + } else { + //assert(false); + } +} + + +static int32_t mnodeGetClusterMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { + int32_t cols = 0; + SSchema *pSchema = pMeta->schema; + + pShow->bytes[cols] = 4; + pSchema[cols].type = TSDB_DATA_TYPE_INT; + strcpy(pSchema[cols].name, "clusterId"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pShow->bytes[cols] = 8; + pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP; + strcpy(pSchema[cols].name, "create_time"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pMeta->numOfColumns = htons(cols); + strcpy(pMeta->tableId, "show cluster"); + pShow->numOfColumns = cols; + + pShow->offset[0] = 0; + for (int32_t i = 1; i < cols; ++i) { + pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; + } + + pShow->numOfRows = 1; + pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; + + return 0; +} + +static int32_t mnodeRetrieveClusters(SShowObj *pShow, char *data, int32_t rows, void *pConn) { + int32_t numOfRows = 0; + int32_t cols = 0; + char * pWrite; + SClusterObj *pCluster = NULL; + + while (numOfRows < rows) { + pShow->pIter = mnodeGetNextCluster(pShow->pIter, &pCluster); + if (pCluster == NULL) break; + + cols = 0; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + *(int32_t *) pWrite = pCluster->clusterId; + cols++; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + *(int32_t *) pWrite = pCluster->createdTime; + cols++; + + mnodeDecClusterRef(pCluster); + numOfRows++; + } + + pShow->numOfReads += numOfRows; + return numOfRows; +} diff --git a/src/mnode/src/mnodeMain.c b/src/mnode/src/mnodeMain.c index 042e356442..53f3474c3c 100644 --- a/src/mnode/src/mnodeMain.c +++ b/src/mnode/src/mnodeMain.c @@ -32,6 +32,7 @@ #include "mnodeVgroup.h" #include "mnodeUser.h" #include "mnodeTable.h" +#include "mnodeCluster.h" #include "mnodeShow.h" #include "mnodeProfile.h" @@ -46,6 +47,7 @@ static bool tsMgmtIsRunning = false; static const SMnodeComponent tsMnodeComponents[] = { {"profile", mnodeInitProfile, mnodeCleanupProfile}, + {"cluster", mnodeInitCluster, mnodeCleanupCluster}, {"accts", mnodeInitAccts, mnodeCleanupAccts}, {"users", mnodeInitUsers, mnodeCleanupUsers}, {"dnodes", mnodeInitDnodes, mnodeCleanupDnodes}, diff --git a/src/mnode/src/mnodeSdb.c b/src/mnode/src/mnodeSdb.c index 4b2945152b..26efcfeac0 100644 --- a/src/mnode/src/mnodeSdb.c +++ b/src/mnode/src/mnodeSdb.c @@ -29,6 +29,7 @@ #include "mnodeInt.h" #include "mnodeMnode.h" #include "mnodeDnode.h" +#include "mnodeCluster.h" #include "mnodeSdb.h" #define SDB_TABLE_LEN 12 @@ -214,6 +215,7 @@ void sdbUpdateMnodeRoles() { } } + mnodeUpdateClusterId(); mnodeUpdateMnodeEpSet(); } diff --git a/src/mnode/src/mnodeShow.c b/src/mnode/src/mnodeShow.c index 1d85a8cacd..d7f058b3a8 100644 --- a/src/mnode/src/mnodeShow.c +++ b/src/mnode/src/mnodeShow.c @@ -103,6 +103,8 @@ static char *mnodeGetShowType(int32_t showType) { case TSDB_MGMT_TABLE_SCORES: return "show scores"; case TSDB_MGMT_TABLE_GRANTS: return "show grants"; case TSDB_MGMT_TABLE_VNODES: return "show vnodes"; + case TSDB_MGMT_TABLE_CLUSTER: return "show clusters"; + case TSDB_MGMT_TABLE_STREAMTABLES : return "show streamtables"; default: return "undefined"; } } -- GitLab