mndDnode.c 32.0 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 18
#include "mndDnode.h"
#include "mndMnode.h"
19
#include "mndPrivilege.h"
D
dapan1121 已提交
20
#include "mndQnode.h"
S
Shengliang Guan 已提交
21
#include "mndShow.h"
22
#include "mndSnode.h"
S
Shengliang Guan 已提交
23
#include "mndTrans.h"
S
Shengliang Guan 已提交
24
#include "mndUser.h"
S
Shengliang Guan 已提交
25
#include "mndVgroup.h"
S
Shengliang Guan 已提交
26

S
Shengliang Guan 已提交
27
#define TSDB_DNODE_VER_NUMBER   1
28
#define TSDB_DNODE_RESERVE_SIZE 64
S
Shengliang Guan 已提交
29

S
Shengliang Guan 已提交
30
static const char *offlineReason[] = {
S
Shengliang Guan 已提交
31 32 33 34 35 36 37 38 39 40 41 42 43
    "",
    "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 已提交
44 45 46 47 48
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);
49
static int32_t  mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOld, SDnodeObj *pNew);
D
dapan1121 已提交
50
static int32_t  mndProcessDnodeListReq(SRpcMsg *pReq);
D
dapan1121 已提交
51
static int32_t  mndProcessShowVariablesReq(SRpcMsg *pReq);
S
Shengliang Guan 已提交
52

S
Shengliang Guan 已提交
53 54 55 56 57
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 已提交
58

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

int32_t mndInitDnode(SMnode *pMnode) {
65 66 67 68 69 70 71 72 73 74
  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 已提交
75

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

84 85
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndRetrieveConfigs);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndCancelGetNextConfig);
S
Shengliang Guan 已提交
86 87 88
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_DNODE, mndRetrieveDnodes);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_DNODE, mndCancelGetNextDnode);

S
Shengliang Guan 已提交
89 90 91 92 93 94
  return sdbSetTable(pMnode->pSdb, table);
}

void mndCleanupDnode(SMnode *pMnode) {}

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

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

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

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

S
Shengliang Guan 已提交
117 118
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
  code = 0;
119

S
Shengliang Guan 已提交
120
_OVER:
121
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
122 123
  sdbFreeRaw(pRaw);
  return code;
S
Shengliang Guan 已提交
124 125
}

S
Shengliang Guan 已提交
126
static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode) {
127 128
  terrno = TSDB_CODE_OUT_OF_MEMORY;

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

  int32_t dataPos = 0;
S
Shengliang Guan 已提交
133 134 135 136 137 138 139
  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);
140 141 142

  terrno = 0;

S
Shengliang Guan 已提交
143
_OVER:
144 145 146 147 148
  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 已提交
149

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

static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw) {
S
Shengliang Guan 已提交
155
  SSdbRow *pRow = NULL;
156 157
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
158
  int8_t sver = 0;
S
Shengliang Guan 已提交
159
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
S
Shengliang Guan 已提交
160
  if (sver != TSDB_DNODE_VER_NUMBER) {
S
Shengliang Guan 已提交
161
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
S
Shengliang Guan 已提交
162
    goto _OVER;
S
Shengliang Guan 已提交
163 164
  }

S
Shengliang Guan 已提交
165 166
  pRow = sdbAllocRow(sizeof(SDnodeObj));
  if (pRow == NULL) goto _OVER;
S
Shengliang Guan 已提交
167
  SDnodeObj *pDnode = sdbGetRowObj(pRow);
S
Shengliang Guan 已提交
168
  if (pDnode == NULL) goto _OVER;
S
Shengliang Guan 已提交
169 170

  int32_t dataPos = 0;
S
Shengliang Guan 已提交
171 172 173 174 175 176
  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)
177 178 179

  terrno = 0;

S
Shengliang Guan 已提交
180
_OVER:
181 182
  if (terrno != 0) {
    mError("dnode:%d, failed to decode from raw:%p since %s", pDnode->id, pRaw, terrstr());
wafwerar's avatar
wafwerar 已提交
183
    taosMemoryFreeClear(pRow);
184 185
    return NULL;
  }
S
Shengliang Guan 已提交
186

187
  mTrace("dnode:%d, decode from raw:%p, row:%p", pDnode->id, pRaw, pDnode);
S
Shengliang Guan 已提交
188 189 190
  return pRow;
}

191
static int32_t mndDnodeActionInsert(SSdb *pSdb, SDnodeObj *pDnode) {
192
  mTrace("dnode:%d, perform insert action, row:%p", pDnode->id, pDnode);
S
Shengliang Guan 已提交
193
  pDnode->offlineReason = DND_REASON_STATUS_NOT_RECEIVED;
S
Shengliang Guan 已提交
194 195 196 197

  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 已提交
198 199 200
  return 0;
}

S
Shengliang Guan 已提交
201
static int32_t mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode) {
202
  mTrace("dnode:%d, perform delete action, row:%p", pDnode->id, pDnode);
S
Shengliang Guan 已提交
203 204
  return 0;
}
S
Shengliang Guan 已提交
205

206
static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOld, SDnodeObj *pNew) {
S
Shengliang Guan 已提交
207
  mTrace("dnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
208
  pOld->updateTime = pNew->updateTime;
S
Shengliang Guan 已提交
209
  return 0;
S
Shengliang Guan 已提交
210 211
}

S
Shengliang Guan 已提交
212
SDnodeObj *mndAcquireDnode(SMnode *pMnode, int32_t dnodeId) {
S
Shengliang Guan 已提交
213 214 215 216 217 218
  SSdb      *pSdb = pMnode->pSdb;
  SDnodeObj *pDnode = sdbAcquire(pSdb, SDB_DNODE, &dnodeId);
  if (pDnode == NULL) {
    terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
  }
  return pDnode;
S
Shengliang Guan 已提交
219
}
S
Shengliang Guan 已提交
220

S
Shengliang Guan 已提交
221 222 223
void mndReleaseDnode(SMnode *pMnode, SDnodeObj *pDnode) {
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pDnode);
S
Shengliang Guan 已提交
224 225
}

S
Shengliang Guan 已提交
226
SEpSet mndGetDnodeEpset(SDnodeObj *pDnode) {
H
Haojun Liao 已提交
227 228
  SEpSet epSet = {0};
  addEpIntoEpSet(&epSet, pDnode->fqdn, pDnode->port);
S
Shengliang Guan 已提交
229 230 231
  return epSet;
}

S
Shengliang Guan 已提交
232 233 234 235 236 237 238 239 240 241 242 243 244
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 已提交
245 246

    sdbRelease(pSdb, pDnode);
S
Shengliang Guan 已提交
247 248
  }

S
Shengliang Guan 已提交
249
  terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
S
Shengliang Guan 已提交
250 251 252
  return NULL;
}

S
Shengliang Guan 已提交
253
int32_t mndGetDnodeSize(SMnode *pMnode) {
S
Shengliang Guan 已提交
254 255 256 257
  SSdb *pSdb = pMnode->pSdb;
  return sdbGetSize(pSdb, SDB_DNODE);
}

S
Shengliang Guan 已提交
258
bool mndIsDnodeOnline(SDnodeObj *pDnode, int64_t curMs) {
dengyihao's avatar
dengyihao 已提交
259
  int64_t interval = TABS(pDnode->lastAccessTime - curMs);
S
Shengliang Guan 已提交
260
  if (interval > 5000 * (int64_t)tsStatusInterval) {
S
Shengliang Guan 已提交
261 262 263
    if (pDnode->rebootTime > 0) {
      pDnode->offlineReason = DND_REASON_STATUS_MSG_TIMEOUT;
    }
S
Shengliang Guan 已提交
264 265 266 267 268
    return false;
  }
  return true;
}

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

272
  int32_t numOfEps = 0;
S
Shengliang Guan 已提交
273 274 275 276 277 278
  void   *pIter = NULL;
  while (1) {
    SDnodeObj *pDnode = NULL;
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
279 280 281
    SDnodeEp dnodeEp = {0};
    dnodeEp.id = pDnode->id;
    dnodeEp.ep.port = pDnode->port;
S
Shengliang Guan 已提交
282
    tstrncpy(dnodeEp.ep.fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
S
Shengliang Guan 已提交
283
    sdbRelease(pSdb, pDnode);
S
Shengliang Guan 已提交
284

S
Shengliang Guan 已提交
285
    dnodeEp.isMnode = 0;
S
Shengliang Guan 已提交
286
    if (mndIsMnode(pMnode, pDnode->id)) {
S
Shengliang Guan 已提交
287
      dnodeEp.isMnode = 1;
S
Shengliang Guan 已提交
288
    }
S
Shengliang Guan 已提交
289
    taosArrayPush(pDnodeEps, &dnodeEp);
S
Shengliang Guan 已提交
290 291 292
  }
}

S
Shengliang Guan 已提交
293
static int32_t mndCheckClusterCfgPara(SMnode *pMnode, SDnodeObj *pDnode, const SClusterCfg *pCfg) {
S
Shengliang Guan 已提交
294
  if (pCfg->statusInterval != tsStatusInterval) {
S
Shengliang Guan 已提交
295 296
    mError("dnode:%d, statusInterval:%d inconsistent with cluster:%d", pDnode->id, pCfg->statusInterval,
           tsStatusInterval);
S
Shengliang Guan 已提交
297 298 299
    return DND_REASON_STATUS_INTERVAL_NOT_MATCH;
  }

wafwerar's avatar
wafwerar 已提交
300
  if ((0 != strcasecmp(pCfg->timezone, tsTimezoneStr)) && (pMnode->checkTime != pCfg->checkTime)) {
S
Shengliang Guan 已提交
301 302
    mError("dnode:%d, timezone:%s checkTime:%" PRId64 " inconsistent with cluster %s %" PRId64, pDnode->id,
           pCfg->timezone, pCfg->checkTime, tsTimezoneStr, pMnode->checkTime);
S
Shengliang Guan 已提交
303 304 305
    return DND_REASON_TIME_ZONE_NOT_MATCH;
  }

S
os env  
Shengliang Guan 已提交
306
  if (0 != strcasecmp(pCfg->locale, tsLocale)) {
S
Shengliang Guan 已提交
307
    mError("dnode:%d, locale:%s inconsistent with cluster:%s", pDnode->id, pCfg->locale, tsLocale);
S
Shengliang Guan 已提交
308 309 310
    return DND_REASON_LOCALE_NOT_MATCH;
  }

S
os env  
Shengliang Guan 已提交
311
  if (0 != strcasecmp(pCfg->charset, tsCharset)) {
S
Shengliang Guan 已提交
312
    mError("dnode:%d, charset:%s inconsistent with cluster:%s", pDnode->id, pCfg->charset, tsCharset);
S
Shengliang Guan 已提交
313 314 315 316 317 318
    return DND_REASON_CHARSET_NOT_MATCH;
  }

  return 0;
}

S
Shengliang Guan 已提交
319 320
static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
  SMnode    *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
321 322 323
  SStatusReq statusReq = {0};
  SDnodeObj *pDnode = NULL;
  int32_t    code = -1;
S
Shengliang Guan 已提交
324

S
Shengliang Guan 已提交
325
  if (tDeserializeSStatusReq(pReq->pCont, pReq->contLen, &statusReq) != 0) {
S
Shengliang Guan 已提交
326
    terrno = TSDB_CODE_INVALID_MSG;
S
Shengliang Guan 已提交
327
    goto _OVER;
S
Shengliang Guan 已提交
328
  }
S
Shengliang Guan 已提交
329

S
Shengliang Guan 已提交
330 331
  if (statusReq.dnodeId == 0) {
    pDnode = mndAcquireDnodeByEp(pMnode, statusReq.dnodeEp);
S
Shengliang Guan 已提交
332
    if (pDnode == NULL) {
333
      mInfo("dnode:%s, not created yet", statusReq.dnodeEp);
S
Shengliang Guan 已提交
334
      goto _OVER;
S
Shengliang Guan 已提交
335 336
    }
  } else {
S
Shengliang Guan 已提交
337
    pDnode = mndAcquireDnode(pMnode, statusReq.dnodeId);
S
Shengliang Guan 已提交
338
    if (pDnode == NULL) {
S
Shengliang Guan 已提交
339
      pDnode = mndAcquireDnodeByEp(pMnode, statusReq.dnodeEp);
S
Shengliang Guan 已提交
340
      if (pDnode != NULL) {
S
Shengliang Guan 已提交
341 342
        pDnode->offlineReason = DND_REASON_DNODE_ID_NOT_MATCH;
      }
S
Shengliang Guan 已提交
343
      mError("dnode:%d, %s not exist", statusReq.dnodeId, statusReq.dnodeEp);
S
Shengliang Guan 已提交
344
      goto _OVER;
S
Shengliang Guan 已提交
345 346 347
    }
  }

S
Shengliang Guan 已提交
348
  for (int32_t v = 0; v < taosArrayGetSize(statusReq.pVloads); ++v) {
S
Shengliang Guan 已提交
349 350 351 352
    SVnodeLoad *pVload = taosArrayGet(statusReq.pVloads, v);

    SVgObj *pVgroup = mndAcquireVgroup(pMnode, pVload->vgId);
    if (pVgroup != NULL) {
S
Shengliang Guan 已提交
353
      if (pVload->syncState == TAOS_SYNC_STATE_LEADER) {
354
        pVgroup->cacheUsage = pVload->cacheUsage;
S
Shengliang Guan 已提交
355 356 357 358 359 360
        pVgroup->numOfTables = pVload->numOfTables;
        pVgroup->numOfTimeSeries = pVload->numOfTimeSeries;
        pVgroup->totalStorage = pVload->totalStorage;
        pVgroup->compStorage = pVload->compStorage;
        pVgroup->pointsWritten = pVload->pointsWritten;
      }
L
Liu Jicong 已提交
361
      bool roleChanged = false;
S
Shengliang Guan 已提交
362
      for (int32_t vg = 0; vg < pVgroup->replica; ++vg) {
M
Minghao Li 已提交
363
        if (pVgroup->vnodeGid[vg].dnodeId == statusReq.dnodeId) {
M
Minghao Li 已提交
364
          if (pVgroup->vnodeGid[vg].role != pVload->syncState) {
M
Minghao Li 已提交
365 366
            roleChanged = true;
          }
M
Minghao Li 已提交
367
          pVgroup->vnodeGid[vg].role = pVload->syncState;
S
Shengliang Guan 已提交
368
          break;
L
Liu Jicong 已提交
369
        }
S
Shengliang Guan 已提交
370
      }
L
Liu Jicong 已提交
371 372 373
      if (roleChanged) {
        // notify scheduler role has changed
      }
S
Shengliang Guan 已提交
374 375 376 377 378
    }

    mndReleaseVgroup(pMnode, pVgroup);
  }

379 380 381
  SMnodeObj *pObj = mndAcquireMnode(pMnode, pDnode->id);
  if (pObj != NULL) {
    if (pObj->state != statusReq.mload.syncState) {
382 383
      mInfo("dnode:%d, mnode syncstate from %s to %s", pObj->id, syncStr(pObj->state),
            syncStr(statusReq.mload.syncState));
384 385 386 387 388 389
      pObj->state = statusReq.mload.syncState;
      pObj->stateStartTime = taosGetTimestampMs();
    }
    mndReleaseMnode(pMnode, pObj);
  }

D
dapan1121 已提交
390 391 392 393 394 395
  SQnodeObj *pQnode = mndAcquireQnode(pMnode, statusReq.qload.dnodeId);
  if (pQnode != NULL) {
    pQnode->load = statusReq.qload;
    mndReleaseQnode(pMnode, pQnode);
  }

396
  int64_t dnodeVer = sdbGetTableVer(pMnode->pSdb, SDB_DNODE) + sdbGetTableVer(pMnode->pSdb, SDB_MNODE);
S
Shengliang Guan 已提交
397
  int64_t curMs = taosGetTimestampMs();
S
Shengliang Guan 已提交
398
  bool    online = mndIsDnodeOnline(pDnode, curMs);
399
  bool    dnodeChanged = (statusReq.dnodeVer == 0) || (statusReq.dnodeVer != dnodeVer);
S
Shengliang Guan 已提交
400
  bool    reboot = (pDnode->rebootTime != statusReq.rebootTime);
401
  bool    needCheck = !online || dnodeChanged || reboot;
S
Shengliang Guan 已提交
402

403
  if (needCheck) {
S
Shengliang Guan 已提交
404
    if (statusReq.sver != tsVersion) {
S
Shengliang Guan 已提交
405
      if (pDnode != NULL) {
S
Shengliang Guan 已提交
406
        pDnode->offlineReason = DND_REASON_VERSION_NOT_MATCH;
S
Shengliang Guan 已提交
407
      }
S
Shengliang Guan 已提交
408
      mError("dnode:%d, status msg version:%d not match cluster:%d", statusReq.dnodeId, statusReq.sver, tsVersion);
409
      terrno = TSDB_CODE_VERSION_NOT_COMPATIBLE;
S
Shengliang Guan 已提交
410
      goto _OVER;
S
Shengliang Guan 已提交
411 412
    }

S
Shengliang Guan 已提交
413
    if (statusReq.dnodeId == 0) {
S
Shengliang Guan 已提交
414
      mInfo("dnode:%d, %s first access, clusterId:%" PRId64, pDnode->id, pDnode->ep, pMnode->clusterId);
S
Shengliang Guan 已提交
415
    } else {
S
Shengliang Guan 已提交
416
      if (statusReq.clusterId != pMnode->clusterId) {
S
Shengliang Guan 已提交
417 418 419
        if (pDnode != NULL) {
          pDnode->offlineReason = DND_REASON_CLUSTER_ID_NOT_MATCH;
        }
S
Shengliang Guan 已提交
420
        mError("dnode:%d, clusterId %" PRId64 " not match exist %" PRId64, pDnode->id, statusReq.clusterId,
S
Shengliang Guan 已提交
421 422
               pMnode->clusterId);
        terrno = TSDB_CODE_MND_INVALID_CLUSTER_ID;
S
Shengliang Guan 已提交
423
        goto _OVER;
S
Shengliang Guan 已提交
424 425 426 427
      } else {
        pDnode->accessTimes++;
        mTrace("dnode:%d, status received, access times %d", pDnode->id, pDnode->accessTimes);
      }
S
Shengliang Guan 已提交
428 429 430
    }

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

438
    if (!online) {
439 440
      mInfo("dnode:%d, from offline to online, memory avail:%" PRId64 " total:%" PRId64 " cores:%.2f", pDnode->id,
            statusReq.memAvail, statusReq.memTotal, statusReq.numOfCores);
441
    } else {
442
      mInfo("dnode:%d, send dnode epset, online:%d dnodeVer:%" PRId64 ":%" PRId64 " reboot:%d", pDnode->id, online,
443
             statusReq.dnodeVer, dnodeVer, reboot);
444
    }
S
Shengliang Guan 已提交
445

S
Shengliang Guan 已提交
446 447 448
    pDnode->rebootTime = statusReq.rebootTime;
    pDnode->numOfCores = statusReq.numOfCores;
    pDnode->numOfSupportVnodes = statusReq.numOfSupportVnodes;
449 450
    pDnode->memAvail = statusReq.memAvail;
    pDnode->memTotal = statusReq.memTotal;
S
Shengliang Guan 已提交
451

S
Shengliang Guan 已提交
452
    SStatusRsp statusRsp = {0};
453
    statusRsp.dnodeVer = dnodeVer;
S
Shengliang Guan 已提交
454 455 456 457
    statusRsp.dnodeCfg.dnodeId = pDnode->id;
    statusRsp.dnodeCfg.clusterId = pMnode->clusterId;
    statusRsp.pDnodeEps = taosArrayInit(mndGetDnodeSize(pMnode), sizeof(SDnodeEp));
    if (statusRsp.pDnodeEps == NULL) {
S
Shengliang Guan 已提交
458
      terrno = TSDB_CODE_OUT_OF_MEMORY;
S
Shengliang Guan 已提交
459
      goto _OVER;
S
Shengliang Guan 已提交
460 461
    }

S
Shengliang Guan 已提交
462 463
    mndGetDnodeData(pMnode, statusRsp.pDnodeEps);

S
Shengliang Guan 已提交
464
    int32_t contLen = tSerializeSStatusRsp(NULL, 0, &statusRsp);
S
Shengliang Guan 已提交
465
    void   *pHead = rpcMallocCont(contLen);
S
Shengliang Guan 已提交
466
    tSerializeSStatusRsp(pHead, contLen, &statusRsp);
S
Shengliang Guan 已提交
467
    taosArrayDestroy(statusRsp.pDnodeEps);
S
Shengliang Guan 已提交
468

S
Shengliang Guan 已提交
469 470
    pReq->info.rspLen = contLen;
    pReq->info.rsp = pHead;
S
Shengliang Guan 已提交
471
  }
S
Shengliang Guan 已提交
472

S
Shengliang Guan 已提交
473
  pDnode->lastAccessTime = curMs;
S
Shengliang Guan 已提交
474 475
  code = 0;

S
Shengliang Guan 已提交
476
_OVER:
S
Shengliang Guan 已提交
477
  mndReleaseDnode(pMnode, pDnode);
S
Shengliang Guan 已提交
478
  taosArrayDestroy(statusReq.pVloads);
S
Shengliang Guan 已提交
479
  return code;
S
Shengliang Guan 已提交
480 481
}

S
Shengliang Guan 已提交
482
static int32_t mndCreateDnode(SMnode *pMnode, SRpcMsg *pReq, SCreateDnodeReq *pCreate) {
S
Shengliang Guan 已提交
483 484 485 486
  int32_t  code = -1;
  SSdbRaw *pRaw = NULL;
  STrans  *pTrans = NULL;

S
Shengliang Guan 已提交
487
  SDnodeObj dnodeObj = {0};
S
Shengliang Guan 已提交
488
  dnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_DNODE);
S
Shengliang Guan 已提交
489 490
  dnodeObj.createdTime = taosGetTimestampMs();
  dnodeObj.updateTime = dnodeObj.createdTime;
S
Shengliang Guan 已提交
491
  dnodeObj.port = pCreate->port;
S
Shengliang Guan 已提交
492
  tstrncpy(dnodeObj.fqdn, pCreate->fqdn, TSDB_FQDN_LEN);
S
Shengliang Guan 已提交
493
  snprintf(dnodeObj.ep, TSDB_EP_LEN - 1, "%s:%u", pCreate->fqdn, pCreate->port);
S
Shengliang Guan 已提交
494

495
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_GLOBAL, pReq, "create-dnode");
S
Shengliang Guan 已提交
496
  if (pTrans == NULL) goto _OVER;
497
  mInfo("trans:%d, used to create dnode:%s", pTrans->id, dnodeObj.ep);
S
Shengliang Guan 已提交
498

S
Shengliang Guan 已提交
499 500
  pRaw = mndDnodeActionEncode(&dnodeObj);
  if (pRaw == NULL || mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER;
S
Shengliang Guan 已提交
501
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
S
Shengliang Guan 已提交
502
  pRaw = NULL;
S
Shengliang Guan 已提交
503

S
Shengliang Guan 已提交
504 505
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
  code = 0;
S
Shengliang Guan 已提交
506

S
Shengliang Guan 已提交
507
_OVER:
S
Shengliang Guan 已提交
508
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
509 510
  sdbFreeRaw(pRaw);
  return code;
S
Shengliang Guan 已提交
511 512
}

D
dapan1121 已提交
513
static int32_t mndProcessDnodeListReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
514 515 516 517
  SMnode       *pMnode = pReq->info.node;
  SSdb         *pSdb = pMnode->pSdb;
  SDnodeObj    *pObj = NULL;
  void         *pIter = NULL;
D
dapan1121 已提交
518
  SDnodeListRsp rsp = {0};
S
Shengliang Guan 已提交
519 520
  int32_t       code = -1;

D
dapan1121 已提交
521 522 523 524 525 526
  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 已提交
527

D
dapan1121 已提交
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
  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 已提交
566 567
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) {
  SShowVariablesRsp rsp = {0};
568 569 570 571 572
  int32_t           code = -1;

  if (mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_SHOW_VARIBALES) != 0) {
    goto _OVER;
  }
D
dapan1121 已提交
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589

  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);
590

D
dapan1121 已提交
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
  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 已提交
623 624
static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) {
  SMnode         *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
625 626 627 628
  int32_t         code = -1;
  SDnodeObj      *pDnode = NULL;
  SCreateDnodeReq createReq = {0};

C
Cary Xu 已提交
629 630 631 632
  if ((terrno = grantCheck(TSDB_GRANT_DNODE)) != 0) {
    code = terrno;
    goto _OVER;
  }
633

S
Shengliang Guan 已提交
634
  if (tDeserializeSCreateDnodeReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
635
    terrno = TSDB_CODE_INVALID_MSG;
S
Shengliang Guan 已提交
636
    goto _OVER;
S
Shengliang Guan 已提交
637 638
  }

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

S
Shengliang Guan 已提交
644
  if (createReq.fqdn[0] == 0 || createReq.port <= 0 || createReq.port > UINT16_MAX) {
645
    terrno = TSDB_CODE_MND_INVALID_DNODE_EP;
S
Shengliang Guan 已提交
646
    goto _OVER;
S
Shengliang Guan 已提交
647 648
  }

S
Shengliang Guan 已提交
649
  char ep[TSDB_EP_LEN];
S
Shengliang Guan 已提交
650 651
  snprintf(ep, TSDB_EP_LEN, "%s:%d", createReq.fqdn, createReq.port);
  pDnode = mndAcquireDnodeByEp(pMnode, ep);
S
Shengliang Guan 已提交
652
  if (pDnode != NULL) {
S
Shengliang Guan 已提交
653
    goto _OVER;
S
Shengliang Guan 已提交
654
  }
S
Shengliang Guan 已提交
655

S
Shengliang Guan 已提交
656
  code = mndCreateDnode(pMnode, pReq, &createReq);
S
Shengliang Guan 已提交
657
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
658

S
Shengliang Guan 已提交
659
_OVER:
S
Shengliang Guan 已提交
660
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
661
    mError("dnode:%s:%d, failed to create since %s", createReq.fqdn, createReq.port, terrstr());
S
Shengliang Guan 已提交
662 663
  }

S
Shengliang Guan 已提交
664 665
  mndReleaseDnode(pMnode, pDnode);
  return code;
S
Shengliang Guan 已提交
666 667
}

668 669
static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMnodeObj *pMObj, SQnodeObj *pQObj,
                            SSnodeObj *pSObj, int32_t numOfVnodes) {
S
Shengliang Guan 已提交
670 671 672 673
  int32_t  code = -1;
  SSdbRaw *pRaw = NULL;
  STrans  *pTrans = NULL;

674
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "drop-dnode");
S
Shengliang Guan 已提交
675
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
676
  mndTransSetSerial(pTrans);
S
Shengliang Guan 已提交
677
  mInfo("trans:%d, used to drop dnode:%d", pTrans->id, pDnode->id);
S
Shengliang Guan 已提交
678

S
Shengliang Guan 已提交
679
  pRaw = mndDnodeActionEncode(pDnode);
S
Shengliang Guan 已提交
680 681
  if (pRaw == NULL) goto _OVER;
  if (mndTransAppendRedolog(pTrans, pRaw) != 0) goto _OVER;
S
Shengliang Guan 已提交
682
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_DROPPING);
S
Shengliang Guan 已提交
683
  pRaw = NULL;
S
Shengliang Guan 已提交
684

S
Shengliang Guan 已提交
685
  pRaw = mndDnodeActionEncode(pDnode);
S
Shengliang Guan 已提交
686 687
  if (pRaw == NULL) goto _OVER;
  if (mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER;
S
Shengliang Guan 已提交
688
  (void)sdbSetRawStatus(pRaw, SDB_STATUS_DROPPED);
S
Shengliang Guan 已提交
689 690
  pRaw = NULL;

S
Shengliang Guan 已提交
691
  if (pMObj != NULL) {
S
Shengliang Guan 已提交
692
    mInfo("trans:%d, mnode on dnode:%d will be dropped", pTrans->id, pDnode->id);
S
Shengliang Guan 已提交
693 694
    if (mndSetDropMnodeInfoToTrans(pMnode, pTrans, pMObj) != 0) goto _OVER;
  }
695 696 697 698 699 700 701 702 703 704 705

  if (pQObj != NULL) {
    mInfo("trans:%d, qnode on dnode:%d will be dropped", pTrans->id, pDnode->id);
    if (mndSetDropQnodeInfoToTrans(pMnode, pTrans, pQObj) != 0) goto _OVER;
  }

  if (pSObj != NULL) {
    mInfo("trans:%d, snode on dnode:%d will be dropped", pTrans->id, pDnode->id);
    if (mndSetDropSnodeInfoToTrans(pMnode, pTrans, pSObj) != 0) goto _OVER;
  }

S
Shengliang Guan 已提交
706
  if (numOfVnodes > 0) {
S
Shengliang Guan 已提交
707
    mInfo("trans:%d, %d vnodes on dnode:%d will be dropped", pTrans->id, numOfVnodes, pDnode->id);
S
Shengliang Guan 已提交
708 709
    if (mndSetMoveVgroupsInfoToTrans(pMnode, pTrans, pDnode->id) != 0) goto _OVER;
  }
S
Shengliang Guan 已提交
710

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

S
Shengliang Guan 已提交
713 714 715
  code = 0;

_OVER:
S
Shengliang Guan 已提交
716
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
717 718
  sdbFreeRaw(pRaw);
  return code;
S
Shengliang Guan 已提交
719 720
}

S
Shengliang Guan 已提交
721
static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) {
722 723 724 725 726 727 728 729 730
  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 已提交
731
    terrno = TSDB_CODE_INVALID_MSG;
S
Shengliang Guan 已提交
732
    goto _OVER;
S
Shengliang Guan 已提交
733
  }
S
Shengliang Guan 已提交
734

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

S
Shengliang Guan 已提交
740
  pDnode = mndAcquireDnode(pMnode, dropReq.dnodeId);
S
Shengliang Guan 已提交
741
  if (pDnode == NULL) {
742 743 744 745 746 747 748
    char ep[TSDB_EP_LEN + 1] = {0};
    snprintf(ep, sizeof(ep), dropReq.fqdn, dropReq.port);
    pDnode = mndAcquireDnodeByEp(pMnode, ep);
    if (pDnode == NULL) {
      terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
      goto _OVER;
    }
S
Shengliang Guan 已提交
749 750
  }

751 752
  pQObj = mndAcquireQnode(pMnode, dropReq.dnodeId);
  pSObj = mndAcquireSnode(pMnode, dropReq.dnodeId);
753 754
  pMObj = mndAcquireMnode(pMnode, dropReq.dnodeId);
  if (pMObj != NULL) {
S
Shengliang Guan 已提交
755 756 757 758 759
    if (sdbGetSize(pMnode->pSdb, SDB_MNODE) <= 1) {
      terrno = TSDB_CODE_MND_TOO_FEW_MNODES;
      goto _OVER;
    }
    if (pMnode->selfDnodeId == dropReq.dnodeId) {
S
Shengliang Guan 已提交
760 761 762 763 764 765 766 767 768 769 770
      terrno = TSDB_CODE_MND_CANT_DROP_LEADER;
      goto _OVER;
    }
  }

  int32_t numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
  if (numOfVnodes > 0 || pMObj != NULL) {
    if (!mndIsDnodeOnline(pDnode, taosGetTimestampMs())) {
      terrno = TSDB_CODE_NODE_OFFLINE;
      mError("dnode:%d, failed to drop since %s, has_mnode:%d numOfVnodes:%d", pDnode->id, terrstr(), pMObj != NULL,
             numOfVnodes);
S
Shengliang Guan 已提交
771 772
      goto _OVER;
    }
773 774
  }

775 776 777 778 779
  if (numOfVnodes > 0) {
    terrno = TSDB_CODE_OPS_NOT_SUPPORT;
    goto _OVER;
  }

780
  code = mndDropDnode(pMnode, pReq, pDnode, pMObj, pQObj, pSObj, numOfVnodes);
S
Shengliang Guan 已提交
781
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
782

S
Shengliang Guan 已提交
783
_OVER:
S
Shengliang Guan 已提交
784
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
785
    mError("dnode:%d, failed to drop since %s", dropReq.dnodeId, terrstr());
S
Shengliang Guan 已提交
786 787
  }

788
  mndReleaseDnode(pMnode, pDnode);
789
  mndReleaseMnode(pMnode, pMObj);
790 791
  mndReleaseQnode(pMnode, pQObj);
  mndReleaseSnode(pMnode, pSObj);
S
Shengliang Guan 已提交
792
  return code;
S
Shengliang Guan 已提交
793 794
}

S
Shengliang Guan 已提交
795
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
796 797
  SMnode     *pMnode = pReq->info.node;
  const char *options[] = {
798 799 800
      "debugFlag",   "dDebugFlag",   "vDebugFlag",   "mDebugFlag",   "wDebugFlag",    "sDebugFlag",   "tsdbDebugFlag",
      "tqDebugFlag", "fsDebugFlag",  "udfDebugFlag", "smaDebugFlag", "idxDebugFlag",  "tdbDebugFlag", "tmrDebugFlag",
      "uDebugFlag",  "smaDebugFlag", "rpcDebugFlag", "qDebugFlag",   "metaDebugFlag",
801 802
  };
  int32_t optionSize = tListLen(options);
S
Shengliang Guan 已提交
803 804

  SMCfgDnodeReq cfgReq = {0};
S
Shengliang Guan 已提交
805
  if (tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq) != 0) {
S
Shengliang Guan 已提交
806 807 808
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
  }
S
Shengliang Guan 已提交
809

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

S
Shengliang Guan 已提交
815
  SDCfgDnodeReq dcfgReq = {0};
816 817 818
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
    strcpy(dcfgReq.config, "resetlog");
  } else if (strncasecmp(cfgReq.config, "monitor", 7) == 0) {
S
Shengliang Guan 已提交
819 820 821
    const char *value = cfgReq.value;
    int32_t     flag = atoi(value);
    if (flag <= 0) {
822
      flag = atoi(cfgReq.config + 8);
S
Shengliang Guan 已提交
823
    }
824 825
    if (flag < 0 || flag > 2) {
      mError("dnode:%d, failed to config monitor since value:%d", cfgReq.dnodeId, flag);
S
Shengliang Guan 已提交
826 827 828 829
      terrno = TSDB_CODE_INVALID_CFG;
      return -1;
    }

830
    strcpy(dcfgReq.config, "monitor");
S
Shengliang Guan 已提交
831 832
    snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
  } else {
833 834 835 836 837 838 839
    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;

      const char *value = cfgReq.value;
M
Minglei Jin 已提交
840
      int32_t     flag = atoi(value);
841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859
      if (flag <= 0) {
        flag = atoi(cfgReq.config + optLen + 1);
      }
      if (flag <= 0 || flag > 255) {
        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 已提交
860 861
  }

S
Shengliang Guan 已提交
862
  int32_t code = -1;
863 864
  SSdb   *pSdb = pMnode->pSdb;
  void   *pIter = NULL;
S
Shengliang Guan 已提交
865 866 867 868
  while (1) {
    SDnodeObj *pDnode = NULL;
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
869

S
Shengliang Guan 已提交
870 871 872 873 874 875 876 877 878 879 880 881 882 883
    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);
        SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
        tmsgSendReq(&epSet, &rpcMsg);
        code = 0;
      }
    }
S
Shengliang Guan 已提交
884

S
Shengliang Guan 已提交
885 886
    sdbRelease(pSdb, pDnode);
  }
887

S
Shengliang Guan 已提交
888 889 890 891
  if (code == -1) {
    terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
  }
  return code;
S
Shengliang Guan 已提交
892 893
}

S
Shengliang Guan 已提交
894
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
895
  mInfo("config rsp from dnode");
S
Shengliang Guan 已提交
896
  return 0;
897
}
S
Shengliang Guan 已提交
898

S
Shengliang Guan 已提交
899 900
static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
901
  int32_t totalRows = 0;
S
Shengliang Guan 已提交
902 903
  int32_t numOfRows = 0;
  char   *cfgOpts[TSDB_CONFIG_NUMBER] = {0};
D
dapan1121 已提交
904
  char    cfgVals[TSDB_CONFIG_NUMBER][TSDB_CONFIG_VALUE_LEN + 1] = {0};
S
Shengliang Guan 已提交
905
  char   *pWrite = NULL;
S
Shengliang Guan 已提交
906 907
  int32_t cols = 0;

S
Shengliang Guan 已提交
908
  cfgOpts[totalRows] = "statusInterval";
D
dapan1121 已提交
909
  snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsStatusInterval);
S
Shengliang Guan 已提交
910
  totalRows++;
S
Shengliang Guan 已提交
911

S
Shengliang Guan 已提交
912
  cfgOpts[totalRows] = "timezone";
D
dapan1121 已提交
913
  snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsTimezoneStr);
S
Shengliang Guan 已提交
914
  totalRows++;
S
Shengliang Guan 已提交
915

S
Shengliang Guan 已提交
916
  cfgOpts[totalRows] = "locale";
D
dapan1121 已提交
917
  snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsLocale);
S
Shengliang Guan 已提交
918
  totalRows++;
S
Shengliang Guan 已提交
919

S
Shengliang Guan 已提交
920
  cfgOpts[totalRows] = "charset";
D
dapan1121 已提交
921
  snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsCharset);
S
Shengliang Guan 已提交
922
  totalRows++;
S
Shengliang Guan 已提交
923

924
  char buf[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
D
dapan1121 已提交
925
  char bufVal[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
926

S
Shengliang Guan 已提交
927
  for (int32_t i = 0; i < totalRows; i++) {
S
Shengliang Guan 已提交
928 929
    cols = 0;

930
    STR_WITH_MAXSIZE_TO_VARSTR(buf, cfgOpts[i], TSDB_CONFIG_OPTION_LEN);
M
Minghao Li 已提交
931 932
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataAppend(pColInfo, numOfRows, (const char *)buf, false);
S
Shengliang Guan 已提交
933

D
dapan1121 已提交
934
    STR_WITH_MAXSIZE_TO_VARSTR(bufVal, cfgVals[i], TSDB_CONFIG_VALUE_LEN);
935
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
M
Minghao Li 已提交
936
    colDataAppend(pColInfo, numOfRows, (const char *)bufVal, false);
S
Shengliang Guan 已提交
937 938

    numOfRows++;
S
Shengliang Guan 已提交
939 940
  }

941
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
942 943 944 945 946
  return numOfRows;
}

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

S
Shengliang Guan 已提交
947 948
static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode    *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
949 950 951 952
  SSdb      *pSdb = pMnode->pSdb;
  int32_t    numOfRows = 0;
  int32_t    cols = 0;
  SDnodeObj *pDnode = NULL;
S
Shengliang Guan 已提交
953
  int64_t    curMs = taosGetTimestampMs();
S
Shengliang Guan 已提交
954 955 956 957

  while (numOfRows < rows) {
    pShow->pIter = sdbFetch(pSdb, SDB_DNODE, pShow->pIter, (void **)&pDnode);
    if (pShow->pIter == NULL) break;
S
Shengliang Guan 已提交
958
    bool online = mndIsDnodeOnline(pDnode, curMs);
S
Shengliang Guan 已提交
959 960 961

    cols = 0;

M
Minghao Li 已提交
962 963
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataAppend(pColInfo, numOfRows, (const char *)&pDnode->id, false);
964 965

    char buf[tListLen(pDnode->ep) + VARSTR_HEADER_SIZE] = {0};
966
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pDnode->ep, pShow->pMeta->pSchemas[cols].bytes);
967 968 969 970 971 972

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataAppend(pColInfo, numOfRows, buf, false);

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    int16_t id = mndGetVnodesNum(pMnode, pDnode->id);
M
Minghao Li 已提交
973
    colDataAppend(pColInfo, numOfRows, (const char *)&id, false);
S
Shengliang Guan 已提交
974

975 976
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataAppend(pColInfo, numOfRows, (const char *)&pDnode->numOfSupportVnodes, false);
S
Shengliang Guan 已提交
977

978
    char b1[9] = {0};
M
Minghao Li 已提交
979
    STR_TO_VARSTR(b1, online ? "ready" : "offline");
980 981
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataAppend(pColInfo, numOfRows, b1, false);
S
Shengliang Guan 已提交
982

983
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
M
Minghao Li 已提交
984
    colDataAppend(pColInfo, numOfRows, (const char *)&pDnode->createdTime, false);
S
Shengliang Guan 已提交
985

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

989 990
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataAppend(pColInfo, numOfRows, b, false);
wafwerar's avatar
wafwerar 已提交
991
    taosMemoryFreeClear(b);
S
Shengliang Guan 已提交
992 993 994 995 996

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

997
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
998 999 1000 1001 1002 1003
  return numOfRows;
}

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