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

S
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
S
Shengliang Guan 已提交
17
#include "mndDnode.h"
18
#include "mndDb.h"
S
Shengliang Guan 已提交
19
#include "mndMnode.h"
20
#include "mndPrivilege.h"
D
dapan1121 已提交
21
#include "mndQnode.h"
S
Shengliang Guan 已提交
22
#include "mndShow.h"
23
#include "mndSnode.h"
S
Shengliang Guan 已提交
24
#include "mndTrans.h"
S
Shengliang Guan 已提交
25
#include "mndUser.h"
S
Shengliang Guan 已提交
26
#include "mndVgroup.h"
H
Haojun Liao 已提交
27
#include "tmisce.h"
C
cadem 已提交
28
#include "mndCluster.h"
S
Shengliang Guan 已提交
29

S
Shengliang Guan 已提交
30
#define TSDB_DNODE_VER_NUMBER   1
31
#define TSDB_DNODE_RESERVE_SIZE 64
S
Shengliang Guan 已提交
32

S
Shengliang Guan 已提交
33
static const char *offlineReason[] = {
S
Shengliang Guan 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46
    "",
    "status msg timeout",
    "status not received",
    "version not match",
    "dnodeId not match",
    "clusterId not match",
    "interval not match",
    "timezone not match",
    "locale not match",
    "charset not match",
    "unknown",
};

S
Shengliang Guan 已提交
47 48 49 50 51
static int32_t  mndCreateDefaultDnode(SMnode *pMnode);
static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode);
static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw);
static int32_t  mndDnodeActionInsert(SSdb *pSdb, SDnodeObj *pDnode);
static int32_t  mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode);
52
static int32_t  mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOld, SDnodeObj *pNew);
D
dapan1121 已提交
53
static int32_t  mndProcessDnodeListReq(SRpcMsg *pReq);
D
dapan1121 已提交
54
static int32_t  mndProcessShowVariablesReq(SRpcMsg *pReq);
S
Shengliang Guan 已提交
55

S
Shengliang Guan 已提交
56 57 58 59 60
static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq);
static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq);
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq);
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp);
static int32_t mndProcessStatusReq(SRpcMsg *pReq);
S
Shengliang Guan 已提交
61

S
Shengliang Guan 已提交
62
static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
S
Shengliang Guan 已提交
63
static void    mndCancelGetNextConfig(SMnode *pMnode, void *pIter);
S
Shengliang Guan 已提交
64
static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
S
Shengliang Guan 已提交
65
static void    mndCancelGetNextDnode(SMnode *pMnode, void *pIter);
S
Shengliang Guan 已提交
66 67

int32_t mndInitDnode(SMnode *pMnode) {
68 69 70 71 72 73 74 75 76 77
  SSdbTable table = {
      .sdbType = SDB_DNODE,
      .keyType = SDB_KEY_INT32,
      .deployFp = (SdbDeployFp)mndCreateDefaultDnode,
      .encodeFp = (SdbEncodeFp)mndDnodeActionEncode,
      .decodeFp = (SdbDecodeFp)mndDnodeActionDecode,
      .insertFp = (SdbInsertFp)mndDnodeActionInsert,
      .updateFp = (SdbUpdateFp)mndDnodeActionUpdate,
      .deleteFp = (SdbDeleteFp)mndDnodeActionDelete,
  };
S
Shengliang Guan 已提交
78

S
Shengliang Guan 已提交
79 80 81
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_DNODE, mndProcessCreateDnodeReq);
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_DNODE, mndProcessDropDnodeReq);
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
H
Hongze Cheng 已提交
82
  mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp);
S
Shengliang Guan 已提交
83
  mndSetMsgHandle(pMnode, TDMT_MND_STATUS, mndProcessStatusReq);
D
dapan1121 已提交
84
  mndSetMsgHandle(pMnode, TDMT_MND_DNODE_LIST, mndProcessDnodeListReq);
D
dapan1121 已提交
85
  mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
S
Shengliang Guan 已提交
86

87 88
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndRetrieveConfigs);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndCancelGetNextConfig);
S
Shengliang Guan 已提交
89 90 91
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_DNODE, mndRetrieveDnodes);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_DNODE, mndCancelGetNextDnode);

S
Shengliang Guan 已提交
92 93 94 95 96 97
  return sdbSetTable(pMnode->pSdb, table);
}

void mndCleanupDnode(SMnode *pMnode) {}

static int32_t mndCreateDefaultDnode(SMnode *pMnode) {
S
Shengliang Guan 已提交
98 99 100 101
  int32_t  code = -1;
  SSdbRaw *pRaw = NULL;
  STrans  *pTrans = NULL;

S
Shengliang Guan 已提交
102 103 104 105
  SDnodeObj dnodeObj = {0};
  dnodeObj.id = 1;
  dnodeObj.createdTime = taosGetTimestampMs();
  dnodeObj.updateTime = dnodeObj.createdTime;
S
Shengliang Guan 已提交
106
  dnodeObj.port = tsServerPort;
S
Shengliang Guan 已提交
107 108
  tstrncpy(dnodeObj.fqdn, tsLocalFqdn, TSDB_FQDN_LEN);
  dnodeObj.fqdn[TSDB_FQDN_LEN - 1] = 0;
S
Shengliang Guan 已提交
109
  snprintf(dnodeObj.ep, TSDB_EP_LEN - 1, "%s:%u", tsLocalFqdn, tsServerPort);
S
Shengliang Guan 已提交
110

111
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, NULL, "create-dnode");
S
Shengliang Guan 已提交
112
  if (pTrans == NULL) goto _OVER;
113
  mInfo("trans:%d, used to create dnode:%s on first deploy", pTrans->id, dnodeObj.ep);
114

S
Shengliang Guan 已提交
115 116
  pRaw = mndDnodeActionEncode(&dnodeObj);
  if (pRaw == NULL || mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER;
S
Shengliang Guan 已提交
117
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
118
  pRaw = NULL;
119

S
Shengliang Guan 已提交
120 121
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
  code = 0;
122

S
Shengliang Guan 已提交
123
_OVER:
124
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
125 126
  sdbFreeRaw(pRaw);
  return code;
S
Shengliang Guan 已提交
127 128
}

S
Shengliang Guan 已提交
129
static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode) {
130 131
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
132
  SSdbRaw *pRaw = sdbAllocRaw(SDB_DNODE, TSDB_DNODE_VER_NUMBER, sizeof(SDnodeObj) + TSDB_DNODE_RESERVE_SIZE);
S
Shengliang Guan 已提交
133
  if (pRaw == NULL) goto _OVER;
S
Shengliang Guan 已提交
134 135

  int32_t dataPos = 0;
S
Shengliang Guan 已提交
136 137 138 139 140 141 142
  SDB_SET_INT32(pRaw, dataPos, pDnode->id, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pDnode->createdTime, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pDnode->updateTime, _OVER)
  SDB_SET_INT16(pRaw, dataPos, pDnode->port, _OVER)
  SDB_SET_BINARY(pRaw, dataPos, pDnode->fqdn, TSDB_FQDN_LEN, _OVER)
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_DNODE_RESERVE_SIZE, _OVER)
  SDB_SET_DATALEN(pRaw, dataPos, _OVER);
143 144 145

  terrno = 0;

S
Shengliang Guan 已提交
146
_OVER:
147 148 149 150 151
  if (terrno != 0) {
    mError("dnode:%d, failed to encode to raw:%p since %s", pDnode->id, pRaw, terrstr());
    sdbFreeRaw(pRaw);
    return NULL;
  }
S
Shengliang Guan 已提交
152

153
  mTrace("dnode:%d, encode to raw:%p, row:%p", pDnode->id, pRaw, pDnode);
S
Shengliang Guan 已提交
154 155 156 157
  return pRaw;
}

static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw) {
158
  terrno = TSDB_CODE_OUT_OF_MEMORY;
159 160
  SSdbRow   *pRow = NULL;
  SDnodeObj *pDnode = NULL;
161

S
Shengliang Guan 已提交
162
  int8_t sver = 0;
S
Shengliang Guan 已提交
163
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
S
Shengliang Guan 已提交
164
  if (sver != TSDB_DNODE_VER_NUMBER) {
S
Shengliang Guan 已提交
165
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
S
Shengliang Guan 已提交
166
    goto _OVER;
S
Shengliang Guan 已提交
167 168
  }

S
Shengliang Guan 已提交
169 170
  pRow = sdbAllocRow(sizeof(SDnodeObj));
  if (pRow == NULL) goto _OVER;
171 172

  pDnode = sdbGetRowObj(pRow);
S
Shengliang Guan 已提交
173
  if (pDnode == NULL) goto _OVER;
S
Shengliang Guan 已提交
174 175

  int32_t dataPos = 0;
S
Shengliang Guan 已提交
176 177 178 179 180 181
  SDB_GET_INT32(pRaw, dataPos, &pDnode->id, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pDnode->createdTime, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pDnode->updateTime, _OVER)
  SDB_GET_INT16(pRaw, dataPos, &pDnode->port, _OVER)
  SDB_GET_BINARY(pRaw, dataPos, pDnode->fqdn, TSDB_FQDN_LEN, _OVER)
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_DNODE_RESERVE_SIZE, _OVER)
182 183

  terrno = 0;
184 185 186
  if (tmsgUpdateDnodeInfo(&pDnode->id, NULL, pDnode->fqdn, &pDnode->port)) {
    mInfo("dnode:%d, endpoint changed", pDnode->id);
  }
187

S
Shengliang Guan 已提交
188
_OVER:
189
  if (terrno != 0) {
190
    mError("dnode:%d, failed to decode from raw:%p since %s", pDnode == NULL ? 0 : pDnode->id, pRaw, terrstr());
wafwerar's avatar
wafwerar 已提交
191
    taosMemoryFreeClear(pRow);
192 193
    return NULL;
  }
S
Shengliang Guan 已提交
194

195
  mTrace("dnode:%d, decode from raw:%p, row:%p ep:%s:%u", pDnode->id, pRaw, pDnode, pDnode->fqdn, pDnode->port);
S
Shengliang Guan 已提交
196 197 198
  return pRow;
}

199
static int32_t mndDnodeActionInsert(SSdb *pSdb, SDnodeObj *pDnode) {
200
  mTrace("dnode:%d, perform insert action, row:%p", pDnode->id, pDnode);
S
Shengliang Guan 已提交
201
  pDnode->offlineReason = DND_REASON_STATUS_NOT_RECEIVED;
S
Shengliang Guan 已提交
202 203 204 205

  char ep[TSDB_EP_LEN] = {0};
  snprintf(ep, TSDB_EP_LEN - 1, "%s:%u", pDnode->fqdn, pDnode->port);
  tstrncpy(pDnode->ep, ep, TSDB_EP_LEN);
S
Shengliang Guan 已提交
206 207 208
  return 0;
}

S
Shengliang Guan 已提交
209
static int32_t mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode) {
210
  mTrace("dnode:%d, perform delete action, row:%p", pDnode->id, pDnode);
S
Shengliang Guan 已提交
211 212
  return 0;
}
S
Shengliang Guan 已提交
213

214
static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOld, SDnodeObj *pNew) {
S
Shengliang Guan 已提交
215
  mTrace("dnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
216
  pOld->updateTime = pNew->updateTime;
S
Shengliang Guan 已提交
217
  return 0;
S
Shengliang Guan 已提交
218 219
}

S
Shengliang Guan 已提交
220
SDnodeObj *mndAcquireDnode(SMnode *pMnode, int32_t dnodeId) {
S
Shengliang Guan 已提交
221 222 223
  SSdb      *pSdb = pMnode->pSdb;
  SDnodeObj *pDnode = sdbAcquire(pSdb, SDB_DNODE, &dnodeId);
  if (pDnode == NULL) {
224 225 226 227 228 229 230 231 232 233
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
      terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
    } else if (terrno == TSDB_CODE_SDB_OBJ_CREATING) {
      terrno = TSDB_CODE_MND_DNODE_IN_CREATING;
    } else if (terrno == TSDB_CODE_SDB_OBJ_DROPPING) {
      terrno = TSDB_CODE_MND_DNODE_IN_DROPPING;
    } else {
      terrno = TSDB_CODE_APP_ERROR;
      mFatal("dnode:%d, failed to acquire db since %s", dnodeId, terrstr());
    }
S
Shengliang Guan 已提交
234
  }
235

S
Shengliang Guan 已提交
236
  return pDnode;
S
Shengliang Guan 已提交
237
}
S
Shengliang Guan 已提交
238

S
Shengliang Guan 已提交
239 240 241
void mndReleaseDnode(SMnode *pMnode, SDnodeObj *pDnode) {
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pDnode);
S
Shengliang Guan 已提交
242 243
}

S
Shengliang Guan 已提交
244
SEpSet mndGetDnodeEpset(SDnodeObj *pDnode) {
H
Haojun Liao 已提交
245 246
  SEpSet epSet = {0};
  addEpIntoEpSet(&epSet, pDnode->fqdn, pDnode->port);
S
Shengliang Guan 已提交
247 248 249
  return epSet;
}

S
Shengliang Guan 已提交
250 251 252 253 254 255 256 257 258 259 260 261 262
static SDnodeObj *mndAcquireDnodeByEp(SMnode *pMnode, char *pEpStr) {
  SSdb *pSdb = pMnode->pSdb;

  void *pIter = NULL;
  while (1) {
    SDnodeObj *pDnode = NULL;
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
    if (pIter == NULL) break;

    if (strncasecmp(pEpStr, pDnode->ep, TSDB_EP_LEN) == 0) {
      sdbCancelFetch(pSdb, pIter);
      return pDnode;
    }
S
Shengliang Guan 已提交
263 264

    sdbRelease(pSdb, pDnode);
S
Shengliang Guan 已提交
265 266
  }

S
Shengliang Guan 已提交
267
  terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
S
Shengliang Guan 已提交
268 269 270
  return NULL;
}

271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
static SDnodeObj *mndAcquireDnodeAllStatusByEp(SMnode *pMnode, char *pEpStr) {
  SSdb *pSdb = pMnode->pSdb;

  void *pIter = NULL;
  while (1) {
    SDnodeObj *pDnode = NULL;
    ESdbStatus objStatus = 0;
    pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true);
    if (pIter == NULL) break;

    if (strncasecmp(pEpStr, pDnode->ep, TSDB_EP_LEN) == 0) {
      sdbCancelFetch(pSdb, pIter);
      return pDnode;
    }

    sdbRelease(pSdb, pDnode);
  }

  return NULL;
}

S
Shengliang Guan 已提交
292
int32_t mndGetDnodeSize(SMnode *pMnode) {
S
Shengliang Guan 已提交
293 294 295 296
  SSdb *pSdb = pMnode->pSdb;
  return sdbGetSize(pSdb, SDB_DNODE);
}

S
Shengliang Guan 已提交
297
bool mndIsDnodeOnline(SDnodeObj *pDnode, int64_t curMs) {
dengyihao's avatar
dengyihao 已提交
298
  int64_t interval = TABS(pDnode->lastAccessTime - curMs);
S
Shengliang Guan 已提交
299
  if (interval > 5000 * (int64_t)tsStatusInterval) {
S
Shengliang Guan 已提交
300 301 302
    if (pDnode->rebootTime > 0) {
      pDnode->offlineReason = DND_REASON_STATUS_MSG_TIMEOUT;
    }
S
Shengliang Guan 已提交
303 304 305 306 307
    return false;
  }
  return true;
}

C
Cary Xu 已提交
308
void mndGetDnodeData(SMnode *pMnode, SArray *pDnodeEps) {
S
Shengliang Guan 已提交
309 310
  SSdb *pSdb = pMnode->pSdb;

311
  int32_t numOfEps = 0;
S
Shengliang Guan 已提交
312 313 314
  void   *pIter = NULL;
  while (1) {
    SDnodeObj *pDnode = NULL;
315 316
    ESdbStatus objStatus = 0;
    pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true);
S
Shengliang Guan 已提交
317 318
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
319 320 321
    SDnodeEp dnodeEp = {0};
    dnodeEp.id = pDnode->id;
    dnodeEp.ep.port = pDnode->port;
S
Shengliang Guan 已提交
322
    tstrncpy(dnodeEp.ep.fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
S
Shengliang Guan 已提交
323
    sdbRelease(pSdb, pDnode);
S
Shengliang Guan 已提交
324

S
Shengliang Guan 已提交
325
    dnodeEp.isMnode = 0;
S
Shengliang Guan 已提交
326
    if (mndIsMnode(pMnode, pDnode->id)) {
S
Shengliang Guan 已提交
327
      dnodeEp.isMnode = 1;
S
Shengliang Guan 已提交
328
    }
S
Shengliang Guan 已提交
329
    taosArrayPush(pDnodeEps, &dnodeEp);
S
Shengliang Guan 已提交
330 331 332
  }
}

S
Shengliang Guan 已提交
333
static int32_t mndCheckClusterCfgPara(SMnode *pMnode, SDnodeObj *pDnode, const SClusterCfg *pCfg) {
S
Shengliang Guan 已提交
334
  if (pCfg->statusInterval != tsStatusInterval) {
S
Shengliang Guan 已提交
335 336
    mError("dnode:%d, statusInterval:%d inconsistent with cluster:%d", pDnode->id, pCfg->statusInterval,
           tsStatusInterval);
S
Shengliang Guan 已提交
337 338 339
    return DND_REASON_STATUS_INTERVAL_NOT_MATCH;
  }

wafwerar's avatar
wafwerar 已提交
340
  if ((0 != strcasecmp(pCfg->timezone, tsTimezoneStr)) && (pMnode->checkTime != pCfg->checkTime)) {
S
Shengliang Guan 已提交
341 342
    mError("dnode:%d, timezone:%s checkTime:%" PRId64 " inconsistent with cluster %s %" PRId64, pDnode->id,
           pCfg->timezone, pCfg->checkTime, tsTimezoneStr, pMnode->checkTime);
S
Shengliang Guan 已提交
343 344 345
    return DND_REASON_TIME_ZONE_NOT_MATCH;
  }

S
os env  
Shengliang Guan 已提交
346
  if (0 != strcasecmp(pCfg->locale, tsLocale)) {
S
Shengliang Guan 已提交
347
    mError("dnode:%d, locale:%s inconsistent with cluster:%s", pDnode->id, pCfg->locale, tsLocale);
S
Shengliang Guan 已提交
348 349 350
    return DND_REASON_LOCALE_NOT_MATCH;
  }

S
os env  
Shengliang Guan 已提交
351
  if (0 != strcasecmp(pCfg->charset, tsCharset)) {
S
Shengliang Guan 已提交
352
    mError("dnode:%d, charset:%s inconsistent with cluster:%s", pDnode->id, pCfg->charset, tsCharset);
S
Shengliang Guan 已提交
353 354 355 356 357 358
    return DND_REASON_CHARSET_NOT_MATCH;
  }

  return 0;
}

S
Shengliang Guan 已提交
359 360
static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
  SMnode    *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
361 362 363
  SStatusReq statusReq = {0};
  SDnodeObj *pDnode = NULL;
  int32_t    code = -1;
S
Shengliang Guan 已提交
364

S
Shengliang Guan 已提交
365
  if (tDeserializeSStatusReq(pReq->pCont, pReq->contLen, &statusReq) != 0) {
S
Shengliang Guan 已提交
366
    terrno = TSDB_CODE_INVALID_MSG;
S
Shengliang Guan 已提交
367
    goto _OVER;
S
Shengliang Guan 已提交
368
  }
S
Shengliang Guan 已提交
369

C
cadem 已提交
370 371 372 373
  int64_t clusterid = mndGetClusterId(pMnode);
  if(statusReq.clusterId != 0 && statusReq.clusterId != clusterid)
  {
    int32_t err = TSDB_CODE_MND_DNODE_DIFF_CLUSTER;
C
cadem 已提交
374
    mWarn("dnode:%d, %s, its clusterid:%" PRId64 " differ from current cluster:%" PRId64 ", code:0x%x", statusReq.dnodeId, statusReq.dnodeEp, statusReq.clusterId, clusterid, err);
C
cadem 已提交
375 376 377 378
    code = TSDB_CODE_MND_DNODE_DIFF_CLUSTER;
    goto _OVER;
  }

S
Shengliang Guan 已提交
379 380
  if (statusReq.dnodeId == 0) {
    pDnode = mndAcquireDnodeByEp(pMnode, statusReq.dnodeEp);
S
Shengliang Guan 已提交
381
    if (pDnode == NULL) {
382
      mInfo("dnode:%s, not created yet", statusReq.dnodeEp);
S
Shengliang Guan 已提交
383
      goto _OVER;
S
Shengliang Guan 已提交
384 385
    }
  } else {
S
Shengliang Guan 已提交
386
    pDnode = mndAcquireDnode(pMnode, statusReq.dnodeId);
S
Shengliang Guan 已提交
387
    if (pDnode == NULL) {
388
      int32_t err = terrno;
S
Shengliang Guan 已提交
389
      pDnode = mndAcquireDnodeByEp(pMnode, statusReq.dnodeEp);
S
Shengliang Guan 已提交
390
      if (pDnode != NULL) {
S
Shengliang Guan 已提交
391
        pDnode->offlineReason = DND_REASON_DNODE_ID_NOT_MATCH;
392 393 394 395 396 397 398 399 400 401 402
        terrno = err;
        goto _OVER;
      }

      mError("dnode:%d, %s not exist, code:0x%x", statusReq.dnodeId, statusReq.dnodeEp, err);
      if (err == TSDB_CODE_MND_DNODE_NOT_EXIST) {
        terrno = err;
        goto _OVER;
      } else {
        pDnode = mndAcquireDnodeAllStatusByEp(pMnode, statusReq.dnodeEp);
        if (pDnode == NULL) goto _OVER;
S
Shengliang Guan 已提交
403 404 405 406
      }
    }
  }

407 408 409 410 411 412 413 414 415
  int64_t dnodeVer = sdbGetTableVer(pMnode->pSdb, SDB_DNODE) + sdbGetTableVer(pMnode->pSdb, SDB_MNODE);
  int64_t curMs = taosGetTimestampMs();
  bool    online = mndIsDnodeOnline(pDnode, curMs);
  bool    dnodeChanged = (statusReq.dnodeVer == 0) || (statusReq.dnodeVer != dnodeVer);
  bool    reboot = (pDnode->rebootTime != statusReq.rebootTime);
  bool    needCheck = !online || dnodeChanged || reboot;

  const STraceId *trace = &pReq->info.traceId;
  mGTrace("dnode:%d, status received, accessTimes:%d check:%d online:%d reboot:%d changed:%d statusSeq:%d", pDnode->id,
416
          pDnode->accessTimes, needCheck, online, reboot, dnodeChanged, statusReq.statusSeq);
417

S
Shengliang Guan 已提交
418
  for (int32_t v = 0; v < taosArrayGetSize(statusReq.pVloads); ++v) {
S
Shengliang Guan 已提交
419 420 421 422
    SVnodeLoad *pVload = taosArrayGet(statusReq.pVloads, v);

    SVgObj *pVgroup = mndAcquireVgroup(pMnode, pVload->vgId);
    if (pVgroup != NULL) {
S
Shengliang Guan 已提交
423
      if (pVload->syncState == TAOS_SYNC_STATE_LEADER) {
424
        pVgroup->cacheUsage = pVload->cacheUsage;
S
Shengliang Guan 已提交
425 426 427 428 429 430
        pVgroup->numOfTables = pVload->numOfTables;
        pVgroup->numOfTimeSeries = pVload->numOfTimeSeries;
        pVgroup->totalStorage = pVload->totalStorage;
        pVgroup->compStorage = pVload->compStorage;
        pVgroup->pointsWritten = pVload->pointsWritten;
      }
L
Liu Jicong 已提交
431
      bool roleChanged = false;
S
Shengliang Guan 已提交
432
      for (int32_t vg = 0; vg < pVgroup->replica; ++vg) {
433 434 435 436 437 438
        SVnodeGid *pGid = &pVgroup->vnodeGid[vg];
        if (pGid->dnodeId == statusReq.dnodeId) {
          if (pGid->syncState != pVload->syncState || pGid->syncRestore != pVload->syncRestore ||
              pGid->syncCanRead != pVload->syncCanRead) {
            mInfo(
                "vgId:%d, state changed by status msg, old state:%s restored:%d canRead:%d new state:%s restored:%d "
439
                "canRead:%d, dnode:%d",
440
                pVgroup->vgId, syncStr(pGid->syncState), pGid->syncRestore, pGid->syncCanRead,
441
                syncStr(pVload->syncState), pVload->syncRestore, pVload->syncCanRead, pDnode->id);
442 443 444
            pGid->syncState = pVload->syncState;
            pGid->syncRestore = pVload->syncRestore;
            pGid->syncCanRead = pVload->syncCanRead;
M
Minghao Li 已提交
445 446
            roleChanged = true;
          }
S
Shengliang Guan 已提交
447
          break;
L
Liu Jicong 已提交
448
        }
S
Shengliang Guan 已提交
449
      }
L
Liu Jicong 已提交
450
      if (roleChanged) {
451
        SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
452
        if (pDb != NULL && pDb->stateTs != curMs) {
dengyihao's avatar
dengyihao 已提交
453 454
          mInfo("db:%s, stateTs changed by status msg, old stateTs:%" PRId64 " new stateTs:%" PRId64, pDb->name,
                pDb->stateTs, curMs);
455 456 457
          pDb->stateTs = curMs;
        }
        mndReleaseDb(pMnode, pDb);
L
Liu Jicong 已提交
458
      }
S
Shengliang Guan 已提交
459 460 461 462 463
    }

    mndReleaseVgroup(pMnode, pVgroup);
  }

464 465
  SMnodeObj *pObj = mndAcquireMnode(pMnode, pDnode->id);
  if (pObj != NULL) {
466 467 468 469 470
    if (pObj->syncState != statusReq.mload.syncState || pObj->syncRestore != statusReq.mload.syncRestore) {
      mInfo("dnode:%d, mnode syncState from %s to %s, restoreState from %d to %d", pObj->id, syncStr(pObj->syncState),
            syncStr(statusReq.mload.syncState), pObj->syncRestore, statusReq.mload.syncRestore);
      pObj->syncState = statusReq.mload.syncState;
      pObj->syncRestore = statusReq.mload.syncRestore;
471 472 473 474 475
      pObj->stateStartTime = taosGetTimestampMs();
    }
    mndReleaseMnode(pMnode, pObj);
  }

D
dapan1121 已提交
476 477 478 479 480 481
  SQnodeObj *pQnode = mndAcquireQnode(pMnode, statusReq.qload.dnodeId);
  if (pQnode != NULL) {
    pQnode->load = statusReq.qload;
    mndReleaseQnode(pMnode, pQnode);
  }

482
  if (needCheck) {
S
Shengliang Guan 已提交
483
    if (statusReq.sver != tsVersion) {
S
Shengliang Guan 已提交
484
      if (pDnode != NULL) {
S
Shengliang Guan 已提交
485
        pDnode->offlineReason = DND_REASON_VERSION_NOT_MATCH;
S
Shengliang Guan 已提交
486
      }
S
Shengliang Guan 已提交
487
      mError("dnode:%d, status msg version:%d not match cluster:%d", statusReq.dnodeId, statusReq.sver, tsVersion);
488
      terrno = TSDB_CODE_VERSION_NOT_COMPATIBLE;
S
Shengliang Guan 已提交
489
      goto _OVER;
S
Shengliang Guan 已提交
490 491
    }

S
Shengliang Guan 已提交
492
    if (statusReq.dnodeId == 0) {
S
Shengliang Guan 已提交
493
      mInfo("dnode:%d, %s first access, clusterId:%" PRId64, pDnode->id, pDnode->ep, pMnode->clusterId);
S
Shengliang Guan 已提交
494
    } else {
S
Shengliang Guan 已提交
495
      if (statusReq.clusterId != pMnode->clusterId) {
S
Shengliang Guan 已提交
496 497 498
        if (pDnode != NULL) {
          pDnode->offlineReason = DND_REASON_CLUSTER_ID_NOT_MATCH;
        }
S
Shengliang Guan 已提交
499
        mError("dnode:%d, clusterId %" PRId64 " not match exist %" PRId64, pDnode->id, statusReq.clusterId,
S
Shengliang Guan 已提交
500 501
               pMnode->clusterId);
        terrno = TSDB_CODE_MND_INVALID_CLUSTER_ID;
S
Shengliang Guan 已提交
502
        goto _OVER;
S
Shengliang Guan 已提交
503
      }
S
Shengliang Guan 已提交
504 505 506
    }

    // Verify whether the cluster parameters are consistent when status change from offline to ready
S
Shengliang Guan 已提交
507 508 509
    pDnode->offlineReason = mndCheckClusterCfgPara(pMnode, pDnode, &statusReq.clusterCfg);
    if (pDnode->offlineReason != 0) {
      mError("dnode:%d, cluster cfg inconsistent since:%s", pDnode->id, offlineReason[pDnode->offlineReason]);
510
      terrno = TSDB_CODE_MND_INVALID_CLUSTER_CFG;
S
Shengliang Guan 已提交
511
      goto _OVER;
S
Shengliang Guan 已提交
512 513
    }

514
    if (!online) {
515 516
      mInfo("dnode:%d, from offline to online, memory avail:%" PRId64 " total:%" PRId64 " cores:%.2f", pDnode->id,
            statusReq.memAvail, statusReq.memTotal, statusReq.numOfCores);
517
    } else {
518
      mInfo("dnode:%d, send dnode epset, online:%d dnodeVer:%" PRId64 ":%" PRId64 " reboot:%d", pDnode->id, online,
H
Hongze Cheng 已提交
519
            statusReq.dnodeVer, dnodeVer, reboot);
520
    }
S
Shengliang Guan 已提交
521

S
Shengliang Guan 已提交
522 523 524
    pDnode->rebootTime = statusReq.rebootTime;
    pDnode->numOfCores = statusReq.numOfCores;
    pDnode->numOfSupportVnodes = statusReq.numOfSupportVnodes;
525 526
    pDnode->memAvail = statusReq.memAvail;
    pDnode->memTotal = statusReq.memTotal;
S
Shengliang Guan 已提交
527

S
Shengliang Guan 已提交
528
    SStatusRsp statusRsp = {0};
529
    statusRsp.statusSeq++;
530
    statusRsp.dnodeVer = dnodeVer;
S
Shengliang Guan 已提交
531 532 533 534
    statusRsp.dnodeCfg.dnodeId = pDnode->id;
    statusRsp.dnodeCfg.clusterId = pMnode->clusterId;
    statusRsp.pDnodeEps = taosArrayInit(mndGetDnodeSize(pMnode), sizeof(SDnodeEp));
    if (statusRsp.pDnodeEps == NULL) {
S
Shengliang Guan 已提交
535
      terrno = TSDB_CODE_OUT_OF_MEMORY;
S
Shengliang Guan 已提交
536
      goto _OVER;
S
Shengliang Guan 已提交
537 538
    }

S
Shengliang Guan 已提交
539 540
    mndGetDnodeData(pMnode, statusRsp.pDnodeEps);

S
Shengliang Guan 已提交
541
    int32_t contLen = tSerializeSStatusRsp(NULL, 0, &statusRsp);
S
Shengliang Guan 已提交
542
    void   *pHead = rpcMallocCont(contLen);
S
Shengliang Guan 已提交
543
    tSerializeSStatusRsp(pHead, contLen, &statusRsp);
S
Shengliang Guan 已提交
544
    taosArrayDestroy(statusRsp.pDnodeEps);
S
Shengliang Guan 已提交
545

S
Shengliang Guan 已提交
546 547
    pReq->info.rspLen = contLen;
    pReq->info.rsp = pHead;
S
Shengliang Guan 已提交
548
  }
S
Shengliang Guan 已提交
549

550 551
  pDnode->accessTimes++;
  pDnode->lastAccessTime = curMs;
S
Shengliang Guan 已提交
552 553
  code = 0;

S
Shengliang Guan 已提交
554
_OVER:
S
Shengliang Guan 已提交
555
  mndReleaseDnode(pMnode, pDnode);
S
Shengliang Guan 已提交
556
  taosArrayDestroy(statusReq.pVloads);
S
Shengliang Guan 已提交
557
  return code;
S
Shengliang Guan 已提交
558 559
}

S
Shengliang Guan 已提交
560
static int32_t mndCreateDnode(SMnode *pMnode, SRpcMsg *pReq, SCreateDnodeReq *pCreate) {
S
Shengliang Guan 已提交
561 562 563 564
  int32_t  code = -1;
  SSdbRaw *pRaw = NULL;
  STrans  *pTrans = NULL;

S
Shengliang Guan 已提交
565
  SDnodeObj dnodeObj = {0};
S
Shengliang Guan 已提交
566
  dnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_DNODE);
S
Shengliang Guan 已提交
567 568
  dnodeObj.createdTime = taosGetTimestampMs();
  dnodeObj.updateTime = dnodeObj.createdTime;
S
Shengliang Guan 已提交
569
  dnodeObj.port = pCreate->port;
S
Shengliang Guan 已提交
570
  tstrncpy(dnodeObj.fqdn, pCreate->fqdn, TSDB_FQDN_LEN);
S
Shengliang Guan 已提交
571
  snprintf(dnodeObj.ep, TSDB_EP_LEN - 1, "%s:%u", pCreate->fqdn, pCreate->port);
S
Shengliang Guan 已提交
572

573
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_GLOBAL, pReq, "create-dnode");
S
Shengliang Guan 已提交
574
  if (pTrans == NULL) goto _OVER;
575
  mInfo("trans:%d, used to create dnode:%s", pTrans->id, dnodeObj.ep);
576
  if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
577

S
Shengliang Guan 已提交
578 579
  pRaw = mndDnodeActionEncode(&dnodeObj);
  if (pRaw == NULL || mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER;
S
Shengliang Guan 已提交
580
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
581
  pRaw = NULL;
S
Shengliang Guan 已提交
582

S
Shengliang Guan 已提交
583 584
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
  code = 0;
S
Shengliang Guan 已提交
585

S
Shengliang Guan 已提交
586
_OVER:
S
Shengliang Guan 已提交
587
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
588 589
  sdbFreeRaw(pRaw);
  return code;
S
Shengliang Guan 已提交
590 591
}

D
dapan1121 已提交
592
static int32_t mndProcessDnodeListReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
593 594 595 596
  SMnode       *pMnode = pReq->info.node;
  SSdb         *pSdb = pMnode->pSdb;
  SDnodeObj    *pObj = NULL;
  void         *pIter = NULL;
D
dapan1121 已提交
597
  SDnodeListRsp rsp = {0};
S
Shengliang Guan 已提交
598 599
  int32_t       code = -1;

D
dapan1121 已提交
600 601 602 603 604 605
  rsp.dnodeList = taosArrayInit(5, sizeof(SEpSet));
  if (NULL == rsp.dnodeList) {
    mError("failed to alloc epSet while process dnode list req");
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _OVER;
  }
S
Shengliang Guan 已提交
606

D
dapan1121 已提交
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
  while (1) {
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pObj);
    if (pIter == NULL) break;

    SEpSet epSet = {0};
    epSet.numOfEps = 1;
    tstrncpy(epSet.eps[0].fqdn, pObj->fqdn, TSDB_FQDN_LEN);
    epSet.eps[0].port = pObj->port;

    (void)taosArrayPush(rsp.dnodeList, &epSet);

    sdbRelease(pSdb, pObj);
  }

  int32_t rspLen = tSerializeSDnodeListRsp(NULL, 0, &rsp);
  void   *pRsp = rpcMallocCont(rspLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _OVER;
  }

  tSerializeSDnodeListRsp(pRsp, rspLen, &rsp);

  pReq->info.rspLen = rspLen;
  pReq->info.rsp = pRsp;
  code = 0;

_OVER:

  if (code != 0) {
    mError("failed to get dnode list since %s", terrstr());
  }

  tFreeSDnodeListRsp(&rsp);

  return code;
}

D
dapan1121 已提交
645 646
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) {
  SShowVariablesRsp rsp = {0};
647 648 649 650 651
  int32_t           code = -1;

  if (mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_SHOW_VARIBALES) != 0) {
    goto _OVER;
  }
D
dapan1121 已提交
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668

  rsp.variables = taosArrayInit(4, sizeof(SVariablesInfo));
  if (NULL == rsp.variables) {
    mError("failed to alloc SVariablesInfo array while process show variables req");
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _OVER;
  }

  SVariablesInfo info = {0};

  strcpy(info.name, "statusInterval");
  snprintf(info.value, TSDB_CONFIG_VALUE_LEN, "%d", tsStatusInterval);
  taosArrayPush(rsp.variables, &info);

  strcpy(info.name, "timezone");
  snprintf(info.value, TSDB_CONFIG_VALUE_LEN, "%s", tsTimezoneStr);
  taosArrayPush(rsp.variables, &info);
669

D
dapan1121 已提交
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
  strcpy(info.name, "locale");
  snprintf(info.value, TSDB_CONFIG_VALUE_LEN, "%s", tsLocale);
  taosArrayPush(rsp.variables, &info);

  strcpy(info.name, "charset");
  snprintf(info.value, TSDB_CONFIG_VALUE_LEN, "%s", tsCharset);
  taosArrayPush(rsp.variables, &info);

  int32_t rspLen = tSerializeSShowVariablesRsp(NULL, 0, &rsp);
  void   *pRsp = rpcMallocCont(rspLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _OVER;
  }

  tSerializeSShowVariablesRsp(pRsp, rspLen, &rsp);

  pReq->info.rspLen = rspLen;
  pReq->info.rsp = pRsp;
  code = 0;

_OVER:

  if (code != 0) {
    mError("failed to get show variables info since %s", terrstr());
  }

  tFreeSShowVariablesRsp(&rsp);

  return code;
}

S
Shengliang Guan 已提交
702 703
static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) {
  SMnode         *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
704 705 706 707
  int32_t         code = -1;
  SDnodeObj      *pDnode = NULL;
  SCreateDnodeReq createReq = {0};

C
Cary Xu 已提交
708 709 710 711
  if ((terrno = grantCheck(TSDB_GRANT_DNODE)) != 0) {
    code = terrno;
    goto _OVER;
  }
712

S
Shengliang Guan 已提交
713
  if (tDeserializeSCreateDnodeReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
714
    terrno = TSDB_CODE_INVALID_MSG;
S
Shengliang Guan 已提交
715
    goto _OVER;
S
Shengliang Guan 已提交
716 717
  }

S
Shengliang Guan 已提交
718
  mInfo("dnode:%s:%d, start to create", createReq.fqdn, createReq.port);
719
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DNODE) != 0) {
S
Shengliang Guan 已提交
720 721
    goto _OVER;
  }
S
Shengliang Guan 已提交
722

S
Shengliang Guan 已提交
723
  if (createReq.fqdn[0] == 0 || createReq.port <= 0 || createReq.port > UINT16_MAX) {
724
    terrno = TSDB_CODE_MND_INVALID_DNODE_EP;
S
Shengliang Guan 已提交
725
    goto _OVER;
S
Shengliang Guan 已提交
726 727
  }

S
Shengliang Guan 已提交
728
  char ep[TSDB_EP_LEN];
S
Shengliang Guan 已提交
729 730
  snprintf(ep, TSDB_EP_LEN, "%s:%d", createReq.fqdn, createReq.port);
  pDnode = mndAcquireDnodeByEp(pMnode, ep);
S
Shengliang Guan 已提交
731
  if (pDnode != NULL) {
732
    terrno = TSDB_CODE_MND_DNODE_ALREADY_EXIST;
S
Shengliang Guan 已提交
733
    goto _OVER;
S
Shengliang Guan 已提交
734
  }
S
Shengliang Guan 已提交
735

S
Shengliang Guan 已提交
736
  code = mndCreateDnode(pMnode, pReq, &createReq);
S
Shengliang Guan 已提交
737
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
738

S
Shengliang Guan 已提交
739
_OVER:
S
Shengliang Guan 已提交
740
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
741
    mError("dnode:%s:%d, failed to create since %s", createReq.fqdn, createReq.port, terrstr());
S
Shengliang Guan 已提交
742 743
  }

S
Shengliang Guan 已提交
744 745
  mndReleaseDnode(pMnode, pDnode);
  return code;
S
Shengliang Guan 已提交
746 747
}

748
static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMnodeObj *pMObj, SQnodeObj *pQObj,
S
Shengliang Guan 已提交
749
                            SSnodeObj *pSObj, int32_t numOfVnodes, bool force) {
S
Shengliang Guan 已提交
750 751 752 753
  int32_t  code = -1;
  SSdbRaw *pRaw = NULL;
  STrans  *pTrans = NULL;

754
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "drop-dnode");
S
Shengliang Guan 已提交
755
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
756
  mndTransSetSerial(pTrans);
S
Shengliang Guan 已提交
757
  mInfo("trans:%d, used to drop dnode:%d, force:%d", pTrans->id, pDnode->id, force);
758
  if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
759

S
Shengliang Guan 已提交
760
  pRaw = mndDnodeActionEncode(pDnode);
S
Shengliang Guan 已提交
761 762
  if (pRaw == NULL) goto _OVER;
  if (mndTransAppendRedolog(pTrans, pRaw) != 0) goto _OVER;
S
Shengliang Guan 已提交
763
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_DROPPING);
S
Shengliang Guan 已提交
764
  pRaw = NULL;
S
Shengliang Guan 已提交
765

S
Shengliang Guan 已提交
766
  pRaw = mndDnodeActionEncode(pDnode);
S
Shengliang Guan 已提交
767 768
  if (pRaw == NULL) goto _OVER;
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER;
S
Shengliang Guan 已提交
769
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_DROPPED);
S
Shengliang Guan 已提交
770 771
  pRaw = NULL;

S
Shengliang Guan 已提交
772
  if (pMObj != NULL) {
S
Shengliang Guan 已提交
773
    mInfo("trans:%d, mnode on dnode:%d will be dropped", pTrans->id, pDnode->id);
S
Shengliang Guan 已提交
774
    if (mndSetDropMnodeInfoToTrans(pMnode, pTrans, pMObj, force) != 0) goto _OVER;
S
Shengliang Guan 已提交
775
  }
776 777 778

  if (pQObj != NULL) {
    mInfo("trans:%d, qnode on dnode:%d will be dropped", pTrans->id, pDnode->id);
S
Shengliang Guan 已提交
779
    if (mndSetDropQnodeInfoToTrans(pMnode, pTrans, pQObj, force) != 0) goto _OVER;
780 781 782 783
  }

  if (pSObj != NULL) {
    mInfo("trans:%d, snode on dnode:%d will be dropped", pTrans->id, pDnode->id);
S
Shengliang Guan 已提交
784
    if (mndSetDropSnodeInfoToTrans(pMnode, pTrans, pSObj, force) != 0) goto _OVER;
785 786
  }

S
Shengliang Guan 已提交
787
  if (numOfVnodes > 0) {
S
Shengliang Guan 已提交
788
    mInfo("trans:%d, %d vnodes on dnode:%d will be dropped", pTrans->id, numOfVnodes, pDnode->id);
S
Shengliang Guan 已提交
789
    if (mndSetMoveVgroupsInfoToTrans(pMnode, pTrans, pDnode->id, force) != 0) goto _OVER;
S
Shengliang Guan 已提交
790
  }
S
Shengliang Guan 已提交
791

S
Shengliang Guan 已提交
792
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
793

S
Shengliang Guan 已提交
794 795 796
  code = 0;

_OVER:
S
Shengliang Guan 已提交
797
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
798 799
  sdbFreeRaw(pRaw);
  return code;
S
Shengliang Guan 已提交
800 801
}

S
Shengliang Guan 已提交
802
static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) {
803 804 805 806 807 808 809 810 811
  SMnode       *pMnode = pReq->info.node;
  int32_t       code = -1;
  SDnodeObj    *pDnode = NULL;
  SMnodeObj    *pMObj = NULL;
  SQnodeObj    *pQObj = NULL;
  SSnodeObj    *pSObj = NULL;
  SDropDnodeReq dropReq = {0};

  if (tDeserializeSDropDnodeReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
812
    terrno = TSDB_CODE_INVALID_MSG;
S
Shengliang Guan 已提交
813
    goto _OVER;
S
Shengliang Guan 已提交
814
  }
S
Shengliang Guan 已提交
815

816
  mInfo("dnode:%d, start to drop, ep:%s:%d", dropReq.dnodeId, dropReq.fqdn, dropReq.port);
817
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_MNODE) != 0) {
S
Shengliang Guan 已提交
818 819
    goto _OVER;
  }
S
Shengliang Guan 已提交
820

S
Shengliang Guan 已提交
821
  pDnode = mndAcquireDnode(pMnode, dropReq.dnodeId);
S
Shengliang Guan 已提交
822
  if (pDnode == NULL) {
823 824
    int32_t err = terrno;
    char    ep[TSDB_EP_LEN + 1] = {0};
825 826 827
    snprintf(ep, sizeof(ep), dropReq.fqdn, dropReq.port);
    pDnode = mndAcquireDnodeByEp(pMnode, ep);
    if (pDnode == NULL) {
828
      terrno = err;
829 830
      goto _OVER;
    }
S
Shengliang Guan 已提交
831 832
  }

833 834
  pQObj = mndAcquireQnode(pMnode, dropReq.dnodeId);
  pSObj = mndAcquireSnode(pMnode, dropReq.dnodeId);
835 836
  pMObj = mndAcquireMnode(pMnode, dropReq.dnodeId);
  if (pMObj != NULL) {
S
Shengliang Guan 已提交
837 838 839 840 841
    if (sdbGetSize(pMnode->pSdb, SDB_MNODE) <= 1) {
      terrno = TSDB_CODE_MND_TOO_FEW_MNODES;
      goto _OVER;
    }
    if (pMnode->selfDnodeId == dropReq.dnodeId) {
S
Shengliang Guan 已提交
842 843 844 845 846 847
      terrno = TSDB_CODE_MND_CANT_DROP_LEADER;
      goto _OVER;
    }
  }

  int32_t numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
S
Shengliang Guan 已提交
848
  if ((numOfVnodes > 0 || pMObj != NULL || pSObj != NULL || pQObj != NULL) && !dropReq.force) {
S
Shengliang Guan 已提交
849
    if (!mndIsDnodeOnline(pDnode, taosGetTimestampMs())) {
850
      terrno = TSDB_CODE_DNODE_OFFLINE;
S
Shengliang Guan 已提交
851 852
      mError("dnode:%d, failed to drop since %s, vnodes:%d mnode:%d qnode:%d snode:%d", pDnode->id, terrstr(),
             numOfVnodes, pMObj != NULL, pQObj != NULL, pSObj != NULL);
S
Shengliang Guan 已提交
853 854
      goto _OVER;
    }
855 856
  }

S
Shengliang Guan 已提交
857
  code = mndDropDnode(pMnode, pReq, pDnode, pMObj, pQObj, pSObj, numOfVnodes, dropReq.force);
S
Shengliang Guan 已提交
858
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
859

S
Shengliang Guan 已提交
860
_OVER:
S
Shengliang Guan 已提交
861
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
862
    mError("dnode:%d, failed to drop since %s", dropReq.dnodeId, terrstr());
S
Shengliang Guan 已提交
863 864
  }

865
  mndReleaseDnode(pMnode, pDnode);
866
  mndReleaseMnode(pMnode, pMObj);
867 868
  mndReleaseQnode(pMnode, pQObj);
  mndReleaseSnode(pMnode, pSObj);
S
Shengliang Guan 已提交
869
  return code;
S
Shengliang Guan 已提交
870 871
}

S
Shengliang Guan 已提交
872
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
873 874
  SMnode     *pMnode = pReq->info.node;
  const char *options[] = {
875 876 877
      "debugFlag",   "dDebugFlag",   "vDebugFlag",   "mDebugFlag",   "wDebugFlag",    "sDebugFlag",   "tsdbDebugFlag",
      "tqDebugFlag", "fsDebugFlag",  "udfDebugFlag", "smaDebugFlag", "idxDebugFlag",  "tdbDebugFlag", "tmrDebugFlag",
      "uDebugFlag",  "smaDebugFlag", "rpcDebugFlag", "qDebugFlag",   "metaDebugFlag",
878 879
  };
  int32_t optionSize = tListLen(options);
S
Shengliang Guan 已提交
880 881

  SMCfgDnodeReq cfgReq = {0};
S
Shengliang Guan 已提交
882
  if (tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq) != 0) {
S
Shengliang Guan 已提交
883 884 885
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
  }
S
Shengliang Guan 已提交
886

887
  mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
888
  if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE) != 0) {
S
Shengliang Guan 已提交
889 890 891
    return -1;
  }

S
Shengliang Guan 已提交
892
  SDCfgDnodeReq dcfgReq = {0};
893 894 895
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
    strcpy(dcfgReq.config, "resetlog");
  } else if (strncasecmp(cfgReq.config, "monitor", 7) == 0) {
896 897 898 899 900 901
    if (' ' != cfgReq.config[7] && 0 != cfgReq.config[7]) {
      mError("dnode:%d, failed to config monitor since invalid conf:%s", cfgReq.dnodeId, cfgReq.config);
      terrno = TSDB_CODE_INVALID_CFG;
      return -1;
    }

S
Shengliang Guan 已提交
902 903 904
    const char *value = cfgReq.value;
    int32_t     flag = atoi(value);
    if (flag <= 0) {
905
      flag = atoi(cfgReq.config + 8);
S
Shengliang Guan 已提交
906
    }
907 908
    if (flag < 0 || flag > 2) {
      mError("dnode:%d, failed to config monitor since value:%d", cfgReq.dnodeId, flag);
S
Shengliang Guan 已提交
909 910 911 912
      terrno = TSDB_CODE_INVALID_CFG;
      return -1;
    }

913
    strcpy(dcfgReq.config, "monitor");
S
Shengliang Guan 已提交
914 915
    snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
  } else {
916 917 918 919 920 921
    bool findOpt = false;
    for (int32_t d = 0; d < optionSize; ++d) {
      const char *optName = options[d];
      int32_t     optLen = strlen(optName);
      if (strncasecmp(cfgReq.config, optName, optLen) != 0) continue;

922 923 924 925 926 927
      if (' ' != cfgReq.config[optLen] && 0 != cfgReq.config[optLen]) {
        mError("dnode:%d, failed to config since invalid conf:%s", cfgReq.dnodeId, cfgReq.config);
        terrno = TSDB_CODE_INVALID_CFG;
        return -1;
      }

928
      const char *value = cfgReq.value;
M
Minglei Jin 已提交
929
      int32_t     flag = atoi(value);
930 931 932
      if (flag <= 0) {
        flag = atoi(cfgReq.config + optLen + 1);
      }
933
      if (flag < 0 || flag > 255) {
934 935 936 937 938 939 940 941 942 943 944 945 946 947 948
        mError("dnode:%d, failed to config %s since value:%d", cfgReq.dnodeId, optName, flag);
        terrno = TSDB_CODE_INVALID_CFG;
        return -1;
      }

      tstrncpy(dcfgReq.config, optName, optLen + 1);
      snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
      findOpt = true;
    }

    if (!findOpt) {
      terrno = TSDB_CODE_INVALID_CFG;
      mError("dnode:%d, failed to config since %s", cfgReq.dnodeId, terrstr());
      return -1;
    }
S
Shengliang Guan 已提交
949 950
  }

S
Shengliang Guan 已提交
951
  int32_t code = -1;
952 953
  SSdb   *pSdb = pMnode->pSdb;
  void   *pIter = NULL;
S
Shengliang Guan 已提交
954 955 956 957
  while (1) {
    SDnodeObj *pDnode = NULL;
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
958

S
Shengliang Guan 已提交
959 960 961 962 963 964 965 966 967
    if (pDnode->id == cfgReq.dnodeId || cfgReq.dnodeId == -1 || cfgReq.dnodeId == 0) {
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, &dcfgReq);
      void   *pBuf = rpcMallocCont(bufLen);

      if (pBuf != NULL) {
        tSerializeSDCfgDnodeReq(pBuf, bufLen, &dcfgReq);
        mInfo("dnode:%d, send config req to dnode, app:%p config:%s value:%s", cfgReq.dnodeId, pReq->info.ahandle,
              dcfgReq.config, dcfgReq.value);
dengyihao's avatar
dengyihao 已提交
968
        SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen, .info = pReq->info};
S
Shengliang Guan 已提交
969 970 971 972
        tmsgSendReq(&epSet, &rpcMsg);
        code = 0;
      }
    }
S
Shengliang Guan 已提交
973

S
Shengliang Guan 已提交
974 975
    sdbRelease(pSdb, pDnode);
  }
976

S
Shengliang Guan 已提交
977 978 979 980
  if (code == -1) {
    terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
  }
  return code;
S
Shengliang Guan 已提交
981 982
}

S
Shengliang Guan 已提交
983
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
984
  mInfo("config rsp from dnode");
S
Shengliang Guan 已提交
985
  return 0;
986
}
S
Shengliang Guan 已提交
987

S
Shengliang Guan 已提交
988 989
static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
990
  int32_t totalRows = 0;
S
Shengliang Guan 已提交
991 992
  int32_t numOfRows = 0;
  char   *cfgOpts[TSDB_CONFIG_NUMBER] = {0};
D
dapan1121 已提交
993
  char    cfgVals[TSDB_CONFIG_NUMBER][TSDB_CONFIG_VALUE_LEN + 1] = {0};
S
Shengliang Guan 已提交
994
  char   *pWrite = NULL;
S
Shengliang Guan 已提交
995 996
  int32_t cols = 0;

S
Shengliang Guan 已提交
997
  cfgOpts[totalRows] = "statusInterval";
D
dapan1121 已提交
998
  snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsStatusInterval);
S
Shengliang Guan 已提交
999
  totalRows++;
S
Shengliang Guan 已提交
1000

S
Shengliang Guan 已提交
1001
  cfgOpts[totalRows] = "timezone";
D
dapan1121 已提交
1002
  snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsTimezoneStr);
S
Shengliang Guan 已提交
1003
  totalRows++;
S
Shengliang Guan 已提交
1004

S
Shengliang Guan 已提交
1005
  cfgOpts[totalRows] = "locale";
D
dapan1121 已提交
1006
  snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsLocale);
S
Shengliang Guan 已提交
1007
  totalRows++;
S
Shengliang Guan 已提交
1008

S
Shengliang Guan 已提交
1009
  cfgOpts[totalRows] = "charset";
D
dapan1121 已提交
1010
  snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsCharset);
S
Shengliang Guan 已提交
1011
  totalRows++;
S
Shengliang Guan 已提交
1012

1013
  char buf[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
D
dapan1121 已提交
1014
  char bufVal[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
1015

S
Shengliang Guan 已提交
1016
  for (int32_t i = 0; i < totalRows; i++) {
S
Shengliang Guan 已提交
1017 1018
    cols = 0;

1019
    STR_WITH_MAXSIZE_TO_VARSTR(buf, cfgOpts[i], TSDB_CONFIG_OPTION_LEN);
M
Minghao Li 已提交
1020
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1021
    colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
S
Shengliang Guan 已提交
1022

D
dapan1121 已提交
1023
    STR_WITH_MAXSIZE_TO_VARSTR(bufVal, cfgVals[i], TSDB_CONFIG_VALUE_LEN);
1024
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1025
    colDataSetVal(pColInfo, numOfRows, (const char *)bufVal, false);
S
Shengliang Guan 已提交
1026 1027

    numOfRows++;
S
Shengliang Guan 已提交
1028 1029
  }

1030
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
1031 1032 1033 1034 1035
  return numOfRows;
}

static void mndCancelGetNextConfig(SMnode *pMnode, void *pIter) {}

S
Shengliang Guan 已提交
1036 1037
static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode    *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1038 1039 1040
  SSdb      *pSdb = pMnode->pSdb;
  int32_t    numOfRows = 0;
  int32_t    cols = 0;
1041
  ESdbStatus objStatus = 0;
S
Shengliang Guan 已提交
1042
  SDnodeObj *pDnode = NULL;
S
Shengliang Guan 已提交
1043
  int64_t    curMs = taosGetTimestampMs();
S
Shengliang Guan 已提交
1044 1045

  while (numOfRows < rows) {
1046
    pShow->pIter = sdbFetchAll(pSdb, SDB_DNODE, pShow->pIter, (void **)&pDnode, &objStatus, true);
S
Shengliang Guan 已提交
1047
    if (pShow->pIter == NULL) break;
S
Shengliang Guan 已提交
1048
    bool online = mndIsDnodeOnline(pDnode, curMs);
S
Shengliang Guan 已提交
1049 1050 1051

    cols = 0;

M
Minghao Li 已提交
1052
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1053
    colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->id, false);
1054 1055

    char buf[tListLen(pDnode->ep) + VARSTR_HEADER_SIZE] = {0};
1056
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pDnode->ep, pShow->pMeta->pSchemas[cols].bytes);
1057 1058

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1059
    colDataSetVal(pColInfo, numOfRows, buf, false);
1060 1061 1062

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    int16_t id = mndGetVnodesNum(pMnode, pDnode->id);
1063
    colDataSetVal(pColInfo, numOfRows, (const char *)&id, false);
S
Shengliang Guan 已提交
1064

1065
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1066
    colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->numOfSupportVnodes, false);
S
Shengliang Guan 已提交
1067

1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
    const char *status = "ready";
    if (objStatus == SDB_STATUS_CREATING) status = "creating";
    if (objStatus == SDB_STATUS_DROPPING) status = "dropping";
    if (!online) {
      if (objStatus == SDB_STATUS_CREATING)
        status = "creating*";
      else if (objStatus == SDB_STATUS_DROPPING)
        status = "dropping*";
      else
        status = "offline";
    }

1080
    char b1[16] = {0};
1081
    STR_TO_VARSTR(b1, status);
1082
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1083
    colDataSetVal(pColInfo, numOfRows, b1, false);
S
Shengliang Guan 已提交
1084

1085
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1086
    colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->createdTime, false);
S
Shengliang Guan 已提交
1087

C
cadem 已提交
1088 1089 1090
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->rebootTime, false);

wafwerar's avatar
wafwerar 已提交
1091
    char *b = taosMemoryCalloc(VARSTR_HEADER_SIZE + strlen(offlineReason[pDnode->offlineReason]) + 1, 1);
1092
    STR_TO_VARSTR(b, online ? "" : offlineReason[pDnode->offlineReason]);
S
Shengliang Guan 已提交
1093

1094
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1095
    colDataSetVal(pColInfo, numOfRows, b, false);
wafwerar's avatar
wafwerar 已提交
1096
    taosMemoryFreeClear(b);
S
Shengliang Guan 已提交
1097 1098 1099 1100 1101

    numOfRows++;
    sdbRelease(pSdb, pDnode);
  }

1102
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
1103 1104 1105 1106 1107 1108
  return numOfRows;
}

static void mndCancelGetNextDnode(SMnode *pMnode, void *pIter) {
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
L
Liu Jicong 已提交
1109
}