• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3858

17 Apr 2025 01:40PM UTC coverage: 62.968% (+0.5%) from 62.513%
#3858

push

travis-ci

web-flow
docs(opc): add perssit data support (#30783)

156194 of 316378 branches covered (49.37%)

Branch coverage included in aggregate %.

242021 of 316027 relevant lines covered (76.58%)

19473613.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.71
/source/dnode/mnode/impl/src/mndMnode.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define _DEFAULT_SOURCE
17
#include "audit.h"
18
#include "mndCluster.h"
19
#include "mndDnode.h"
20
#include "mndMnode.h"
21
#include "mndPrivilege.h"
22
#include "mndShow.h"
23
#include "mndSync.h"
24
#include "mndTrans.h"
25
#include "tmisce.h"
26

27
#define MNODE_VER_NUMBER   2
28
#define MNODE_RESERVE_SIZE 64
29

30
static int32_t  mndCreateDefaultMnode(SMnode *pMnode);
31
static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pObj);
32
static SSdbRow *mndMnodeActionDecode(SSdbRaw *pRaw);
33
static int32_t  mndMnodeActionInsert(SSdb *pSdb, SMnodeObj *pObj);
34
static int32_t  mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pObj);
35
static int32_t  mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOld, SMnodeObj *pNew);
36
static int32_t  mndProcessCreateMnodeReq(SRpcMsg *pReq);
37
static int32_t  mndProcessAlterMnodeReq(SRpcMsg *pReq);
38
static int32_t  mndProcessDropMnodeReq(SRpcMsg *pReq);
39
static int32_t  mndRetrieveMnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
40
static void     mndCancelGetNextMnode(SMnode *pMnode, void *pIter);
41
static void     mndReloadSyncConfig(SMnode *pMnode);
42

43
int32_t mndInitMnode(SMnode *pMnode) {
2,011✔
44
  SSdbTable table = {
2,011✔
45
      .sdbType = SDB_MNODE,
46
      .keyType = SDB_KEY_INT32,
47
      .deployFp = (SdbDeployFp)mndCreateDefaultMnode,
48
      .encodeFp = (SdbEncodeFp)mndMnodeActionEncode,
49
      .decodeFp = (SdbDecodeFp)mndMnodeActionDecode,
50
      .insertFp = (SdbInsertFp)mndMnodeActionInsert,
51
      .updateFp = (SdbUpdateFp)mndMnodeActionUpdate,
52
      .deleteFp = (SdbDeleteFp)mndMnodeActionDelete,
53
  };
54

55
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_MNODE, mndProcessCreateMnodeReq);
2,011✔
56
  mndSetMsgHandle(pMnode, TDMT_DND_CREATE_MNODE_RSP, mndTransProcessRsp);
2,011✔
57
  mndSetMsgHandle(pMnode, TDMT_DND_ALTER_MNODE_TYPE_RSP, mndTransProcessRsp);
2,011✔
58
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_MNODE, mndProcessAlterMnodeReq);
2,011✔
59
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_MNODE_RSP, mndTransProcessRsp);
2,011✔
60
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_MNODE, mndProcessDropMnodeReq);
2,011✔
61
  mndSetMsgHandle(pMnode, TDMT_DND_DROP_MNODE_RSP, mndTransProcessRsp);
2,011✔
62

63
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_MNODE, mndRetrieveMnodes);
2,011✔
64
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_MNODE, mndCancelGetNextMnode);
2,011✔
65

66
  return sdbSetTable(pMnode->pSdb, table);
2,011✔
67
}
68

69
void mndCleanupMnode(SMnode *pMnode) {}
2,010✔
70

71
SMnodeObj *mndAcquireMnode(SMnode *pMnode, int32_t mnodeId) {
160,454✔
72
  terrno = 0;
160,454✔
73
  SMnodeObj *pObj = sdbAcquire(pMnode->pSdb, SDB_MNODE, &mnodeId);
160,454✔
74
  if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
160,454✔
75
    terrno = TSDB_CODE_MND_MNODE_NOT_EXIST;
71,218✔
76
  }
77
  return pObj;
160,454✔
78
}
79

80
void mndReleaseMnode(SMnode *pMnode, SMnodeObj *pObj) {
89,042✔
81
  SSdb *pSdb = pMnode->pSdb;
89,042✔
82
  sdbRelease(pMnode->pSdb, pObj);
89,042✔
83
}
89,042✔
84

85
static int32_t mndCreateDefaultMnode(SMnode *pMnode) {
1,501✔
86
  int32_t   code = 0;
1,501✔
87
  SMnodeObj mnodeObj = {0};
1,501✔
88
  mnodeObj.id = 1;
1,501✔
89
  mnodeObj.createdTime = taosGetTimestampMs();
1,501✔
90
  mnodeObj.updateTime = mnodeObj.createdTime;
1,501✔
91

92
  SSdbRaw *pRaw = mndMnodeActionEncode(&mnodeObj);
1,501✔
93
  if (pRaw == NULL) {
1,501!
94
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
95
    if (terrno != 0) code = terrno;
×
96
    return -1;
×
97
  }
98
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRaw, SDB_STATUS_READY));
1,501!
99

100
  mInfo("mnode:%d, will be created when deploying, raw:%p", mnodeObj.id, pRaw);
1,501!
101

102
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, NULL, "create-mnode");
1,501✔
103
  if (pTrans == NULL) {
1,501!
104
    sdbFreeRaw(pRaw);
×
105
    mError("mnode:%d, failed to create since %s", mnodeObj.id, terrstr());
×
106
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
107
    if (terrno != 0) code = terrno;
×
108
    return -1;
×
109
  }
110
  mInfo("trans:%d, used to create mnode:%d", pTrans->id, mnodeObj.id);
1,501!
111

112
  if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
1,501!
113
    mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
×
114
    mndTransDrop(pTrans);
×
115
    TAOS_RETURN(code);
×
116
  }
117
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRaw, SDB_STATUS_READY));
1,501!
118

119
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
1,501!
120
    mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
×
121
    mndTransDrop(pTrans);
×
122
    return -1;
×
123
  }
124

125
  mndTransDrop(pTrans);
1,501✔
126
  TAOS_RETURN(code);
1,501✔
127
}
128

129
static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pObj) {
6,019✔
130
  int32_t code = 0;
6,019✔
131
  int32_t lino = 0;
6,019✔
132
  terrno = TSDB_CODE_OUT_OF_MEMORY;
6,019✔
133

134
  SSdbRaw *pRaw = sdbAllocRaw(SDB_MNODE, MNODE_VER_NUMBER, sizeof(SMnodeObj) + MNODE_RESERVE_SIZE);
6,019✔
135
  if (pRaw == NULL) goto _OVER;
6,019!
136

137
  int32_t dataPos = 0;
6,019✔
138
  SDB_SET_INT32(pRaw, dataPos, pObj->id, _OVER)
6,019!
139
  SDB_SET_INT64(pRaw, dataPos, pObj->createdTime, _OVER)
6,019!
140
  SDB_SET_INT64(pRaw, dataPos, pObj->updateTime, _OVER)
6,019!
141
  SDB_SET_INT32(pRaw, dataPos, pObj->role, _OVER)
6,019!
142
  SDB_SET_INT64(pRaw, dataPos, pObj->lastIndex, _OVER)
6,019!
143
  SDB_SET_RESERVE(pRaw, dataPos, MNODE_RESERVE_SIZE, _OVER)
6,019!
144

145
  terrno = 0;
6,019✔
146

147
_OVER:
6,019✔
148
  if (terrno != 0) {
6,019!
149
    mError("mnode:%d, failed to encode to raw:%p since %s", pObj->id, pRaw, terrstr());
×
150
    sdbFreeRaw(pRaw);
×
151
    return NULL;
×
152
  }
153

154
  mTrace("mnode:%d, encode to raw:%p, row:%p", pObj->id, pRaw, pObj);
6,019✔
155
  return pRaw;
6,019✔
156
}
157

158
static SSdbRow *mndMnodeActionDecode(SSdbRaw *pRaw) {
2,853✔
159
  int32_t code = 0;
2,853✔
160
  int32_t lino = 0;
2,853✔
161
  terrno = TSDB_CODE_OUT_OF_MEMORY;
2,853✔
162
  SSdbRow   *pRow = NULL;
2,853✔
163
  SMnodeObj *pObj = NULL;
2,853✔
164

165
  int8_t sver = 0;
2,853✔
166
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) return NULL;
2,853!
167

168
  if (sver != 1 && sver != 2) {
2,853!
169
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
170
    goto _OVER;
×
171
  }
172

173
  pRow = sdbAllocRow(sizeof(SMnodeObj));
2,853✔
174
  if (pRow == NULL) goto _OVER;
2,853!
175

176
  pObj = sdbGetRowObj(pRow);
2,853✔
177
  if (pObj == NULL) goto _OVER;
2,853!
178

179
  int32_t dataPos = 0;
2,853✔
180
  SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER)
2,853!
181
  SDB_GET_INT64(pRaw, dataPos, &pObj->createdTime, _OVER)
2,853!
182
  SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER)
2,853!
183
  if (sver >= 2) {
2,853!
184
    SDB_GET_INT32(pRaw, dataPos, &pObj->role, _OVER)
2,853!
185
    SDB_GET_INT64(pRaw, dataPos, &pObj->lastIndex, _OVER)
2,853!
186
  }
187
  SDB_GET_RESERVE(pRaw, dataPos, MNODE_RESERVE_SIZE, _OVER)
2,853!
188

189
  terrno = 0;
2,853✔
190

191
_OVER:
2,853✔
192
  if (terrno != 0) {
2,853!
193
    mError("mnode:%d, failed to decode from raw:%p since %s", pObj == NULL ? 0 : pObj->id, pRaw, terrstr());
×
194
    taosMemoryFreeClear(pRow);
×
195
    return NULL;
×
196
  }
197

198
  mTrace("mnode:%d, decode from raw:%p, row:%p", pObj->id, pRaw, pObj);
2,853✔
199
  return pRow;
2,853✔
200
}
201

202
static int32_t mndMnodeActionInsert(SSdb *pSdb, SMnodeObj *pObj) {
2,615✔
203
  int32_t code = 0;
2,615✔
204
  mTrace("mnode:%d, perform insert action, row:%p", pObj->id, pObj);
2,615✔
205
  pObj->pDnode = sdbAcquireNotReadyObj(pSdb, SDB_DNODE, &pObj->id);
2,615✔
206
  if (pObj->pDnode == NULL) {
2,615!
207
    mError("mnode:%d, failed to perform insert action since %s", pObj->id, terrstr());
×
208
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
209
    if (terrno != 0) code = terrno;
×
210
    int32_t code = 0;
×
211
  }
212

213
  pObj->syncState = TAOS_SYNC_STATE_OFFLINE;
2,615✔
214
  mndReloadSyncConfig(pSdb->pMnode);
2,615✔
215
  TAOS_RETURN(code);
2,615✔
216
}
217

218
static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pObj) {
2,852✔
219
  mTrace("mnode:%d, perform delete action, row:%p", pObj->id, pObj);
2,852✔
220
  if (pObj->pDnode != NULL) {
2,852✔
221
    sdbRelease(pSdb, pObj->pDnode);
2,614✔
222
    pObj->pDnode = NULL;
2,614✔
223
  }
224

225
  return 0;
2,852✔
226
}
227

228
static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOld, SMnodeObj *pNew) {
222✔
229
  mTrace("mnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
222!
230
  pOld->role = pNew->role;
222✔
231
  pOld->updateTime = pNew->updateTime;
222✔
232
  pOld->lastIndex = pNew->lastIndex;
222✔
233
  mndReloadSyncConfig(pSdb->pMnode);
222✔
234

235
  return 0;
222✔
236
}
237

238
bool mndIsMnode(SMnode *pMnode, int32_t dnodeId) {
472,254✔
239
  SSdb *pSdb = pMnode->pSdb;
472,254✔
240

241
  SMnodeObj *pObj = sdbAcquire(pSdb, SDB_MNODE, &dnodeId);
472,254✔
242
  if (pObj == NULL) {
472,254✔
243
    return false;
330,117✔
244
  }
245

246
  sdbRelease(pSdb, pObj);
142,137✔
247
  return true;
142,137✔
248
}
249

250
void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) {
509,529✔
251
  if (pMnode == NULL || pEpSet == NULL) {
509,529!
252
    return;
×
253
  }
254

255
  syncGetRetryEpSet(pMnode->syncMgmt.sync, pEpSet);
509,608✔
256

257
  /*
258
  SSdb   *pSdb = pMnode->pSdb;
259
  int32_t totalMnodes = sdbGetSize(pSdb, SDB_MNODE);
260
  if (totalMnodes == 0) {
261
    syncGetRetryEpSet(pMnode->syncMgmt.sync, pEpSet);
262
    return;
263
  }
264

265
  void *pIter = NULL;
266
  while (1) {
267
    SMnodeObj *pObj = NULL;
268
    pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pObj);
269
    if (pIter == NULL) break;
270

271
    if (pObj->id == pMnode->selfDnodeId) {
272
      if (mndIsLeader(pMnode)) {
273
        pEpSet->inUse = pEpSet->numOfEps;
274
      } else {
275
        pEpSet->inUse = (pEpSet->numOfEps + 1) % totalMnodes;
276
        // pEpSet->inUse = 0;
277
      }
278
    }
279
    if (pObj->pDnode != NULL) {
280
      if (addEpIntoEpSet(pEpSet, pObj->pDnode->fqdn, pObj->pDnode->port) != 0) {
281
        mError("mnode:%d, failed to add ep:%s:%d into epset", pObj->id, pObj->pDnode->fqdn, pObj->pDnode->port);
282
      }
283
      sdbRelease(pSdb, pObj);
284
    }
285

286
    if (pEpSet->numOfEps == 0) {
287
      syncGetRetryEpSet(pMnode->syncMgmt.sync, pEpSet);
288
    }
289

290
    if (pEpSet->inUse >= pEpSet->numOfEps) {
291
      pEpSet->inUse = 0;
292
    }
293
    epsetSort(pEpSet);
294
  }
295
    */
296
}
297

298
static int32_t mndSetCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) {
97✔
299
  int32_t  code = 0;
97✔
300
  SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj);
97✔
301
  if (pRedoRaw == NULL) {
97!
302
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
303
    if (terrno != 0) code = terrno;
×
304
    TAOS_RETURN(code);
×
305
  }
306
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
97!
307
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING));
97!
308
  TAOS_RETURN(code);
97✔
309
}
310

311
int32_t mndSetRestoreCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) {
×
312
  int32_t  code = 0;
×
313
  SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj);
×
314
  if (pRedoRaw == NULL) {
×
315
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
316
    if (terrno != 0) code = terrno;
×
317
    TAOS_RETURN(code);
×
318
  }
319
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
×
320
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY));
×
321
  TAOS_RETURN(code);
×
322
}
323

324
static int32_t mndSetCreateMnodeUndoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) {
×
325
  int32_t  code = 0;
×
326
  SSdbRaw *pUndoRaw = mndMnodeActionEncode(pObj);
×
327
  if (pUndoRaw == NULL) {
×
328
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
329
    if (terrno != 0) code = terrno;
×
330
    TAOS_RETURN(code);
×
331
  }
332
  TAOS_CHECK_RETURN(mndTransAppendUndolog(pTrans, pUndoRaw));
×
333
  TAOS_CHECK_RETURN(sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED));
×
334
  TAOS_RETURN(code);
×
335
}
336

337
int32_t mndSetCreateMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) {
99✔
338
  int32_t  code = 0;
99✔
339
  SSdbRaw *pCommitRaw = mndMnodeActionEncode(pObj);
99✔
340
  if (pCommitRaw == NULL) {
99!
341
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
342
    if (terrno != 0) code = terrno;
×
343
    TAOS_RETURN(code);
×
344
  }
345
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
99!
346
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
99!
347
  TAOS_RETURN(code);
99✔
348
}
349

350
static int32_t mndBuildCreateMnodeRedoAction(STrans *pTrans, SDCreateMnodeReq *pCreateReq, SEpSet *pCreateEpSet) {
99✔
351
  int32_t code = 0;
99✔
352
  int32_t contLen = tSerializeSDCreateMnodeReq(NULL, 0, pCreateReq);
99✔
353
  void   *pReq = taosMemoryMalloc(contLen);
99!
354
  if (pReq == NULL) {
99!
355
    code = terrno;
×
356
    return code;
×
357
  }
358
  code = tSerializeSDCreateMnodeReq(pReq, contLen, pCreateReq);
99✔
359
  if (code < 0) {
99!
360
    taosMemoryFree(pReq);
×
361
    TAOS_RETURN(code);
×
362
  }
363

364
  STransAction action = {
99✔
365
      .epSet = *pCreateEpSet,
366
      .pCont = pReq,
367
      .contLen = contLen,
368
      .msgType = TDMT_DND_CREATE_MNODE,
369
      .acceptableCode = TSDB_CODE_MNODE_ALREADY_DEPLOYED,
370
  };
371

372
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
99!
373
    taosMemoryFree(pReq);
×
374
    TAOS_RETURN(code);
×
375
  }
376
  TAOS_RETURN(code);
99✔
377
}
378

379
static int32_t mndBuildAlterMnodeTypeRedoAction(STrans *pTrans, SDAlterMnodeTypeReq *pAlterMnodeTypeReq,
99✔
380
                                                SEpSet *pAlterMnodeTypeEpSet) {
381
  int32_t code = 0;
99✔
382
  int32_t contLen = tSerializeSDCreateMnodeReq(NULL, 0, pAlterMnodeTypeReq);
99✔
383
  void   *pReq = taosMemoryMalloc(contLen);
99!
384
  if (pReq == NULL) {
99!
385
    code = terrno;
×
386
    return code;
×
387
  }
388
  code = tSerializeSDCreateMnodeReq(pReq, contLen, pAlterMnodeTypeReq);
99✔
389
  if (code < 0) {
99!
390
    taosMemoryFree(pReq);
×
391
    TAOS_RETURN(code);
×
392
  }
393

394
  STransAction action = {
99✔
395
      .epSet = *pAlterMnodeTypeEpSet,
396
      .pCont = pReq,
397
      .contLen = contLen,
398
      .msgType = TDMT_DND_ALTER_MNODE_TYPE,
399
      .retryCode = TSDB_CODE_MNODE_NOT_CATCH_UP,
400
      .acceptableCode = TSDB_CODE_MNODE_ALREADY_IS_VOTER,
401
  };
402

403
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
99!
404
    taosMemoryFree(pReq);
×
405
    TAOS_RETURN(code);
×
406
  }
407
  TAOS_RETURN(code);
99✔
408
}
409

410
static int32_t mndBuildAlterMnodeRedoAction(STrans *pTrans, SDCreateMnodeReq *pAlterReq, SEpSet *pAlterEpSet) {
×
411
  int32_t code = 0;
×
412
  int32_t contLen = tSerializeSDCreateMnodeReq(NULL, 0, pAlterReq);
×
413
  void   *pReq = taosMemoryMalloc(contLen);
×
414
  if (pReq == NULL) {
×
415
    code = terrno;
×
416
    return code;
×
417
  }
418
  code = tSerializeSDCreateMnodeReq(pReq, contLen, pAlterReq);
×
419
  if (code < 0) {
×
420
    taosMemoryFree(pReq);
×
421
    TAOS_RETURN(code);
×
422
  }
423
  STransAction action = {
×
424
      .epSet = *pAlterEpSet,
425
      .pCont = pReq,
426
      .contLen = contLen,
427
      .msgType = TDMT_MND_ALTER_MNODE,
428
      .acceptableCode = 0,
429
  };
430

431
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
432
    taosMemoryFree(pReq);
×
433
    TAOS_RETURN(code);
×
434
  }
435

436
  TAOS_RETURN(code);
×
437
}
438

439
static int32_t mndBuildDropMnodeRedoAction(STrans *pTrans, SDDropMnodeReq *pDropReq, SEpSet *pDroprEpSet) {
6✔
440
  int32_t code = 0;
6✔
441
  int32_t contLen = tSerializeSCreateDropMQSNodeReq(NULL, 0, pDropReq);
6✔
442
  void   *pReq = taosMemoryMalloc(contLen);
6!
443
  if (pReq == NULL) {
6!
444
    code = terrno;
×
445
    return code;
×
446
  }
447
  code = tSerializeSCreateDropMQSNodeReq(pReq, contLen, pDropReq);
6✔
448
  if (code < 0) {
6!
449
    taosMemoryFree(pReq);
×
450
    TAOS_RETURN(code);
×
451
  }
452

453
  STransAction action = {
6✔
454
      .epSet = *pDroprEpSet,
455
      .pCont = pReq,
456
      .contLen = contLen,
457
      .msgType = TDMT_DND_DROP_MNODE,
458
      .acceptableCode = TSDB_CODE_MNODE_NOT_DEPLOYED,
459
  };
460

461
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
6!
462
    taosMemoryFree(pReq);
×
463
    TAOS_RETURN(code);
×
464
  }
465
  TAOS_RETURN(code);
6✔
466
}
467

468
static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) {
97✔
469
  SSdb            *pSdb = pMnode->pSdb;
97✔
470
  void            *pIter = NULL;
97✔
471
  int32_t          numOfReplicas = 0;
97✔
472
  int32_t          numOfLearnerReplicas = 0;
97✔
473
  SDCreateMnodeReq createReq = {0};
97✔
474
  SEpSet           createEpset = {0};
97✔
475

476
  while (1) {
144✔
477
    SMnodeObj *pMObj = NULL;
241✔
478
    pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj);
241✔
479
    if (pIter == NULL) break;
241✔
480

481
    if (pMObj->role == TAOS_SYNC_ROLE_VOTER) {
144!
482
      createReq.replicas[numOfReplicas].id = pMObj->id;
144✔
483
      createReq.replicas[numOfReplicas].port = pMObj->pDnode->port;
144✔
484
      memcpy(createReq.replicas[numOfReplicas].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
144✔
485
      numOfReplicas++;
144✔
486
    } else {
487
      createReq.learnerReplicas[numOfLearnerReplicas].id = pMObj->id;
×
488
      createReq.learnerReplicas[numOfLearnerReplicas].port = pMObj->pDnode->port;
×
489
      memcpy(createReq.learnerReplicas[numOfLearnerReplicas].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
×
490
      numOfLearnerReplicas++;
×
491
    }
492

493
    sdbRelease(pSdb, pMObj);
144✔
494
  }
495

496
  createReq.replica = numOfReplicas;
97✔
497
  createReq.learnerReplica = numOfLearnerReplicas + 1;
97✔
498
  createReq.learnerReplicas[numOfLearnerReplicas].id = pDnode->id;
97✔
499
  createReq.learnerReplicas[numOfLearnerReplicas].port = pDnode->port;
97✔
500
  memcpy(createReq.learnerReplicas[numOfLearnerReplicas].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
97✔
501

502
  createReq.lastIndex = pObj->lastIndex;
97✔
503

504
  createEpset.inUse = 0;
97✔
505
  createEpset.numOfEps = 1;
97✔
506
  createEpset.eps[0].port = pDnode->port;
97✔
507
  memcpy(createEpset.eps[0].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
97✔
508

509
  TAOS_CHECK_RETURN(mndBuildCreateMnodeRedoAction(pTrans, &createReq, &createEpset));
97!
510

511
  TAOS_RETURN(0);
97✔
512
}
513

514
int32_t mndSetRestoreCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) {
2✔
515
  SSdb            *pSdb = pMnode->pSdb;
2✔
516
  void            *pIter = NULL;
2✔
517
  SDCreateMnodeReq createReq = {0};
2✔
518
  SEpSet           createEpset = {0};
2✔
519

520
  while (1) {
6✔
521
    SMnodeObj *pMObj = NULL;
8✔
522
    pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj);
8✔
523
    if (pIter == NULL) break;
8✔
524

525
    if (pMObj->id == pDnode->id) {
6✔
526
      sdbRelease(pSdb, pMObj);
2✔
527
      continue;
2✔
528
    }
529

530
    if (pMObj->role == TAOS_SYNC_ROLE_VOTER) {
4!
531
      createReq.replicas[createReq.replica].id = pMObj->id;
4✔
532
      createReq.replicas[createReq.replica].port = pMObj->pDnode->port;
4✔
533
      memcpy(createReq.replicas[createReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
4✔
534
      createReq.replica++;
4✔
535
    } else {
536
      createReq.learnerReplicas[createReq.learnerReplica].id = pMObj->id;
×
537
      createReq.learnerReplicas[createReq.learnerReplica].port = pMObj->pDnode->port;
×
538
      memcpy(createReq.learnerReplicas[createReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
×
539
      createReq.learnerReplica++;
×
540
    }
541

542
    sdbRelease(pSdb, pMObj);
4✔
543
  }
544

545
  createReq.learnerReplicas[createReq.learnerReplica].id = pDnode->id;
2✔
546
  createReq.learnerReplicas[createReq.learnerReplica].port = pDnode->port;
2✔
547
  memcpy(createReq.learnerReplicas[createReq.learnerReplica].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
2✔
548
  createReq.learnerReplica++;
2✔
549

550
  createReq.lastIndex = pObj->lastIndex;
2✔
551

552
  createEpset.inUse = 0;
2✔
553
  createEpset.numOfEps = 1;
2✔
554
  createEpset.eps[0].port = pDnode->port;
2✔
555
  memcpy(createEpset.eps[0].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
2✔
556

557
  TAOS_CHECK_RETURN(mndBuildCreateMnodeRedoAction(pTrans, &createReq, &createEpset));
2!
558

559
  TAOS_RETURN(0);
2✔
560
}
561

562
static int32_t mndSetAlterMnodeTypeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) {
97✔
563
  SSdb               *pSdb = pMnode->pSdb;
97✔
564
  void               *pIter = NULL;
97✔
565
  SDAlterMnodeTypeReq alterReq = {0};
97✔
566
  SEpSet              createEpset = {0};
97✔
567

568
  while (1) {
144✔
569
    SMnodeObj *pMObj = NULL;
241✔
570
    pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj);
241✔
571
    if (pIter == NULL) break;
241✔
572

573
    if (pMObj->role == TAOS_SYNC_ROLE_VOTER) {
144!
574
      alterReq.replicas[alterReq.replica].id = pMObj->id;
144✔
575
      alterReq.replicas[alterReq.replica].port = pMObj->pDnode->port;
144✔
576
      memcpy(alterReq.replicas[alterReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
144✔
577
      alterReq.replica++;
144✔
578
    } else {
579
      alterReq.learnerReplicas[alterReq.learnerReplica].id = pMObj->id;
×
580
      alterReq.learnerReplicas[alterReq.learnerReplica].port = pMObj->pDnode->port;
×
581
      memcpy(alterReq.learnerReplicas[alterReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
×
582
      alterReq.learnerReplica++;
×
583
    }
584

585
    sdbRelease(pSdb, pMObj);
144✔
586
  }
587

588
  alterReq.replicas[alterReq.replica].id = pDnode->id;
97✔
589
  alterReq.replicas[alterReq.replica].port = pDnode->port;
97✔
590
  memcpy(alterReq.replicas[alterReq.replica].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
97✔
591
  alterReq.replica++;
97✔
592

593
  alterReq.lastIndex = pObj->lastIndex;
97✔
594

595
  createEpset.inUse = 0;
97✔
596
  createEpset.numOfEps = 1;
97✔
597
  createEpset.eps[0].port = pDnode->port;
97✔
598
  memcpy(createEpset.eps[0].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
97✔
599

600
  TAOS_CHECK_RETURN(mndBuildAlterMnodeTypeRedoAction(pTrans, &alterReq, &createEpset));
97!
601

602
  TAOS_RETURN(0);
97✔
603
}
604

605
int32_t mndSetRestoreAlterMnodeTypeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) {
2✔
606
  SSdb               *pSdb = pMnode->pSdb;
2✔
607
  void               *pIter = NULL;
2✔
608
  SDAlterMnodeTypeReq alterReq = {0};
2✔
609
  SEpSet              createEpset = {0};
2✔
610

611
  while (1) {
6✔
612
    SMnodeObj *pMObj = NULL;
8✔
613
    pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj);
8✔
614
    if (pIter == NULL) break;
8✔
615

616
    if (pMObj->id == pDnode->id) {
6✔
617
      sdbRelease(pSdb, pMObj);
2✔
618
      continue;
2✔
619
    }
620

621
    if (pMObj->role == TAOS_SYNC_ROLE_VOTER) {
4!
622
      alterReq.replicas[alterReq.replica].id = pMObj->id;
4✔
623
      alterReq.replicas[alterReq.replica].port = pMObj->pDnode->port;
4✔
624
      memcpy(alterReq.replicas[alterReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
4✔
625
      alterReq.replica++;
4✔
626
    } else {
627
      alterReq.learnerReplicas[alterReq.learnerReplica].id = pMObj->id;
×
628
      alterReq.learnerReplicas[alterReq.learnerReplica].port = pMObj->pDnode->port;
×
629
      memcpy(alterReq.learnerReplicas[alterReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN);
×
630
      alterReq.learnerReplica++;
×
631
    }
632

633
    sdbRelease(pSdb, pMObj);
4✔
634
  }
635

636
  alterReq.replicas[alterReq.replica].id = pDnode->id;
2✔
637
  alterReq.replicas[alterReq.replica].port = pDnode->port;
2✔
638
  memcpy(alterReq.replicas[alterReq.replica].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
2✔
639
  alterReq.replica++;
2✔
640

641
  alterReq.lastIndex = pObj->lastIndex;
2✔
642

643
  createEpset.inUse = 0;
2✔
644
  createEpset.numOfEps = 1;
2✔
645
  createEpset.eps[0].port = pDnode->port;
2✔
646
  memcpy(createEpset.eps[0].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
2✔
647

648
  TAOS_CHECK_RETURN(mndBuildAlterMnodeTypeRedoAction(pTrans, &alterReq, &createEpset));
2!
649

650
  TAOS_RETURN(0);
2✔
651
}
652

653
static int32_t mndCreateMnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMCreateMnodeReq *pCreate) {
97✔
654
  int32_t code = -1;
97✔
655

656
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "create-mnode");
97✔
657
  if (pTrans == NULL) {
97!
658
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
659
    if (terrno != 0) code = terrno;
×
660
    goto _OVER;
×
661
  }
662
  mndTransSetSerial(pTrans);
97✔
663
  mInfo("trans:%d, used to create mnode:%d", pTrans->id, pCreate->dnodeId);
97!
664
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
97!
665

666
  SMnodeObj mnodeObj = {0};
97✔
667
  mnodeObj.id = pDnode->id;
97✔
668
  mnodeObj.createdTime = taosGetTimestampMs();
97✔
669
  mnodeObj.updateTime = mnodeObj.createdTime;
97✔
670
  mnodeObj.role = TAOS_SYNC_ROLE_LEARNER;
97✔
671
  mnodeObj.lastIndex = pMnode->applied;
97✔
672

673
  TAOS_CHECK_GOTO(mndSetCreateMnodeRedoActions(pMnode, pTrans, pDnode, &mnodeObj), NULL, _OVER);
97!
674
  TAOS_CHECK_GOTO(mndSetCreateMnodeRedoLogs(pMnode, pTrans, &mnodeObj), NULL, _OVER);
97!
675

676
  SMnodeObj mnodeLeaderObj = {0};
97✔
677
  mnodeLeaderObj.id = pDnode->id;
97✔
678
  mnodeLeaderObj.createdTime = taosGetTimestampMs();
97✔
679
  mnodeLeaderObj.updateTime = mnodeLeaderObj.createdTime;
97✔
680
  mnodeLeaderObj.role = TAOS_SYNC_ROLE_VOTER;
97✔
681
  mnodeLeaderObj.lastIndex = pMnode->applied + 1;
97✔
682

683
  TAOS_CHECK_GOTO(mndSetAlterMnodeTypeRedoActions(pMnode, pTrans, pDnode, &mnodeLeaderObj), NULL, _OVER);
97!
684
  TAOS_CHECK_GOTO(mndSetCreateMnodeCommitLogs(pMnode, pTrans, &mnodeLeaderObj), NULL, _OVER);
97!
685
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
97!
686

687
  code = 0;
97✔
688

689
_OVER:
97✔
690
  mndTransDrop(pTrans);
97✔
691
  TAOS_RETURN(code);
97✔
692
}
693

694
static int32_t mndProcessCreateMnodeReq(SRpcMsg *pReq) {
195✔
695
  SMnode          *pMnode = pReq->info.node;
195✔
696
  int32_t          code = -1;
195✔
697
  SMnodeObj       *pObj = NULL;
195✔
698
  SDnodeObj       *pDnode = NULL;
195✔
699
  SMCreateMnodeReq createReq = {0};
195✔
700

701
  TAOS_CHECK_GOTO(tDeserializeSCreateDropMQSNodeReq(pReq->pCont, pReq->contLen, &createReq), NULL, _OVER);
195!
702

703
  mInfo("mnode:%d, start to create", createReq.dnodeId);
195!
704
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_MNODE), NULL, _OVER);
195✔
705

706
  pObj = mndAcquireMnode(pMnode, createReq.dnodeId);
194✔
707
  if (pObj != NULL) {
194✔
708
    code = TSDB_CODE_MND_MNODE_ALREADY_EXIST;
41✔
709
    goto _OVER;
41✔
710
  } else if (terrno != TSDB_CODE_MND_MNODE_NOT_EXIST) {
153!
711
    goto _OVER;
×
712
  }
713

714
  pDnode = mndAcquireDnode(pMnode, createReq.dnodeId);
153✔
715
  if (pDnode == NULL) {
153✔
716
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
8✔
717
    goto _OVER;
8✔
718
  }
719

720
  if (sdbGetSize(pMnode->pSdb, SDB_MNODE) >= 3) {
145✔
721
    code = TSDB_CODE_MND_TOO_MANY_MNODES;
2✔
722
    goto _OVER;
2✔
723
  }
724

725
  if (!mndIsDnodeOnline(pDnode, taosGetTimestampMs())) {
143✔
726
    code = TSDB_CODE_DNODE_OFFLINE;
46✔
727
    goto _OVER;
46✔
728
  }
729

730
  code = mndCreateMnode(pMnode, pReq, pDnode, &createReq);
97✔
731
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
97!
732

733
  char    obj[40] = {0};
97✔
734
  int32_t bytes = snprintf(obj, sizeof(obj), "%d", createReq.dnodeId);
97✔
735
  if ((uint32_t)bytes < sizeof(obj)) {
97!
736
    auditRecord(pReq, pMnode->clusterId, "createMnode", "", obj, createReq.sql, createReq.sqlLen);
97✔
737
  } else {
738
    mError("mnode:%d, failed to audit create req since %s", createReq.dnodeId, tstrerror(TSDB_CODE_OUT_OF_RANGE));
×
739
  }
740

741
_OVER:
×
742
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
195!
743
    mError("mnode:%d, failed to create since %s", createReq.dnodeId, terrstr());
98!
744
  }
745

746
  mndReleaseMnode(pMnode, pObj);
195✔
747
  mndReleaseDnode(pMnode, pDnode);
195✔
748
  tFreeSMCreateQnodeReq(&createReq);
195✔
749

750
  TAOS_RETURN(code);
195✔
751
}
752

753
static int32_t mndSetDropMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) {
8✔
754
  int32_t  code = 0;
8✔
755
  SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj);
8✔
756
  if (pRedoRaw == NULL) {
8!
757
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
758
    if (terrno != 0) code = terrno;
×
759
    TAOS_RETURN(code);
×
760
  }
761
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
8!
762
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING));
8!
763
  TAOS_RETURN(code);
8✔
764
}
765

766
static int32_t mndSetDropMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) {
8✔
767
  int32_t  code = 0;
8✔
768
  SSdbRaw *pCommitRaw = mndMnodeActionEncode(pObj);
8✔
769
  if (pCommitRaw == NULL) {
8!
770
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
771
    if (terrno != 0) code = terrno;
×
772
    TAOS_RETURN(code);
×
773
  }
774
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
8!
775
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED));
8!
776
  TAOS_RETURN(code);
8✔
777
}
778

779
static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj,
8✔
780
                                          bool force) {
781
  int32_t        code = 0;
8✔
782
  SSdb          *pSdb = pMnode->pSdb;
8✔
783
  void          *pIter = NULL;
8✔
784
  SDDropMnodeReq dropReq = {0};
8✔
785
  SEpSet         dropEpSet = {0};
8✔
786

787
  dropReq.dnodeId = pDnode->id;
8✔
788
  dropEpSet.numOfEps = 1;
8✔
789
  dropEpSet.eps[0].port = pDnode->port;
8✔
790
  memcpy(dropEpSet.eps[0].fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
8✔
791

792
  int32_t totalMnodes = sdbGetSize(pSdb, SDB_MNODE);
8✔
793
  if (totalMnodes == 2) {
8✔
794
    if (force) {
2!
795
      mError("cant't force drop dnode, since a mnode on it and replica is 2");
×
796
      code = TSDB_CODE_MNODE_ONLY_TWO_MNODE;
×
797
      TAOS_RETURN(code);
×
798
    }
799
    mInfo("vgId:1, has %d mnodes, exec redo log first", totalMnodes);
2!
800
    TAOS_CHECK_RETURN(mndSetDropMnodeRedoLogs(pMnode, pTrans, pObj));
2!
801
    if (!force) {
2!
802
      TAOS_CHECK_RETURN(mndBuildDropMnodeRedoAction(pTrans, &dropReq, &dropEpSet));
2!
803
    }
804
  } else if (totalMnodes == 3) {
6!
805
    mInfo("vgId:1, has %d mnodes, exec redo action first", totalMnodes);
6!
806
    if (!force) {
6✔
807
      TAOS_CHECK_RETURN(mndBuildDropMnodeRedoAction(pTrans, &dropReq, &dropEpSet));
4!
808
    }
809
    TAOS_CHECK_RETURN(mndSetDropMnodeRedoLogs(pMnode, pTrans, pObj));
6!
810
  } else {
811
    TAOS_RETURN(-1);
×
812
  }
813

814
  TAOS_RETURN(code);
8✔
815
}
816

817
int32_t mndSetDropMnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj, bool force) {
8✔
818
  if (pObj == NULL) return 0;
8!
819
  pObj->lastIndex = pMnode->applied;
8✔
820
  TAOS_CHECK_RETURN(mndSetDropMnodeRedoActions(pMnode, pTrans, pObj->pDnode, pObj, force));
8!
821
  TAOS_CHECK_RETURN(mndSetDropMnodeCommitLogs(pMnode, pTrans, pObj));
8!
822
  return 0;
8✔
823
}
824

825
static int32_t mndDropMnode(SMnode *pMnode, SRpcMsg *pReq, SMnodeObj *pObj) {
4✔
826
  int32_t code = -1;
4✔
827
  STrans *pTrans = NULL;
4✔
828

829
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "drop-mnode");
4✔
830
  if (pTrans == NULL) {
4!
831
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
832
    if (terrno != 0) code = terrno;
×
833
    goto _OVER;
×
834
  }
835
  mndTransSetSerial(pTrans);
4✔
836
  mInfo("trans:%d, used to drop mnode:%d", pTrans->id, pObj->id);
4!
837
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
4!
838

839
  TAOS_CHECK_GOTO(mndSetDropMnodeInfoToTrans(pMnode, pTrans, pObj, false), NULL, _OVER);
4!
840
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
4!
841

842
  code = 0;
4✔
843

844
_OVER:
4✔
845
  mndTransDrop(pTrans);
4✔
846
  TAOS_RETURN(code);
4✔
847
}
848

849
static int32_t mndProcessDropMnodeReq(SRpcMsg *pReq) {
21✔
850
  SMnode        *pMnode = pReq->info.node;
21✔
851
  int32_t        code = -1;
21✔
852
  SMnodeObj     *pObj = NULL;
21✔
853
  SMDropMnodeReq dropReq = {0};
21✔
854

855
  TAOS_CHECK_GOTO(tDeserializeSCreateDropMQSNodeReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
21!
856

857
  mInfo("mnode:%d, start to drop", dropReq.dnodeId);
21!
858
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_MNODE), NULL, _OVER);
21✔
859

860
  if (dropReq.dnodeId <= 0) {
20!
861
    code = TSDB_CODE_INVALID_MSG;
×
862
    goto _OVER;
×
863
  }
864

865
  pObj = mndAcquireMnode(pMnode, dropReq.dnodeId);
20✔
866
  if (pObj == NULL) {
20✔
867
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
7✔
868
    if (terrno != 0) code = terrno;
7!
869
    goto _OVER;
7✔
870
  }
871

872
  if (pMnode->selfDnodeId == dropReq.dnodeId) {
13✔
873
    code = TSDB_CODE_MND_CANT_DROP_LEADER;
7✔
874
    goto _OVER;
7✔
875
  }
876

877
  if (sdbGetSize(pMnode->pSdb, SDB_MNODE) <= 1) {
6!
878
    code = TSDB_CODE_MND_TOO_FEW_MNODES;
×
879
    goto _OVER;
×
880
  }
881

882
  if (!mndIsDnodeOnline(pObj->pDnode, taosGetTimestampMs())) {
6✔
883
    code = TSDB_CODE_DNODE_OFFLINE;
2✔
884
    goto _OVER;
2✔
885
  }
886

887
  code = mndDropMnode(pMnode, pReq, pObj);
4✔
888
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
4!
889

890
  char obj[40] = {0};
4✔
891
  (void)tsnprintf(obj, sizeof(obj), "%d", dropReq.dnodeId);
4✔
892

893
  auditRecord(pReq, pMnode->clusterId, "dropMnode", "", obj, dropReq.sql, dropReq.sqlLen);
4✔
894

895
_OVER:
21✔
896
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
21!
897
    mError("mnode:%d, failed to drop since %s", dropReq.dnodeId, terrstr());
17!
898
  }
899

900
  mndReleaseMnode(pMnode, pObj);
21✔
901
  tFreeSMCreateQnodeReq(&dropReq);
21✔
902
  TAOS_RETURN(code);
21✔
903
}
904

905
static int32_t mndRetrieveMnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
4,571✔
906
  SMnode    *pMnode = pReq->info.node;
4,571✔
907
  SSdb      *pSdb = pMnode->pSdb;
4,571✔
908
  int32_t    numOfRows = 0;
4,571✔
909
  int32_t    cols = 0;
4,571✔
910
  SMnodeObj *pObj = NULL;
4,571✔
911
  SMnodeObj *pSelfObj = NULL;
4,571✔
912
  ESdbStatus objStatus = 0;
4,571✔
913
  char      *pWrite;
914
  int64_t    curMs = taosGetTimestampMs();
4,572✔
915
  int        code = 0;
4,572✔
916

917
  pSelfObj = sdbAcquire(pSdb, SDB_MNODE, &pMnode->selfDnodeId);
4,572✔
918
  if (pSelfObj == NULL) {
4,575!
919
    mError("mnode:%d, failed to acquire self %s", pMnode->selfDnodeId, terrstr());
×
920
    goto _out;
×
921
  }
922

923
  while (numOfRows < rows) {
9,446✔
924
    pShow->pIter = sdbFetchAll(pSdb, SDB_MNODE, pShow->pIter, (void **)&pObj, &objStatus, true);
9,438✔
925
    if (pShow->pIter == NULL) break;
9,445✔
926

927
    cols = 0;
4,869✔
928
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,869✔
929
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->id, false);
4,865✔
930
    if (code != 0) {
4,858!
931
      mError("mnode:%d, failed to set col data val since %s", pObj->id, tstrerror(code));
×
932
      sdbCancelFetch(pSdb, pShow->pIter);
×
933
      sdbRelease(pSdb, pObj);
×
934
      goto _out;
×
935
    }
936

937
    char b1[TSDB_EP_LEN + VARSTR_HEADER_SIZE] = {0};
4,858✔
938
    STR_WITH_MAXSIZE_TO_VARSTR(b1, pObj->pDnode->ep, TSDB_EP_LEN + VARSTR_HEADER_SIZE);
4,858✔
939

940
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,858✔
941
    code = colDataSetVal(pColInfo, numOfRows, b1, false);
4,859✔
942
    if (code != 0) {
4,859!
943
      mError("mnode:%d, failed to set col data val since %s", pObj->id, tstrerror(code));
×
944
      sdbCancelFetch(pSdb, pShow->pIter);
×
945
      sdbRelease(pSdb, pObj);
×
946
      goto _out;
×
947
    }
948

949
    char role[20] = "offline";
4,859✔
950
    if (pObj->id == pMnode->selfDnodeId) {
4,859✔
951
      snprintf(role, sizeof(role), "%s%s", syncStr(TAOS_SYNC_STATE_LEADER), pMnode->restored ? "" : "*");
4,563!
952
    }
953
    bool isDnodeOnline = mndIsDnodeOnline(pObj->pDnode, curMs);
4,861✔
954
    if (isDnodeOnline) {
4,862✔
955
      tstrncpy(role, syncStr(pObj->syncState), sizeof(role));
4,814✔
956
      if (pObj->syncState == TAOS_SYNC_STATE_LEADER && pObj->id != pMnode->selfDnodeId) {
4,816!
957
        tstrncpy(role, syncStr(TAOS_SYNC_STATE_ERROR), sizeof(role));
×
958
        mError("mnode:%d, is leader too", pObj->id);
×
959
      }
960
    }
961
    char b2[12 + VARSTR_HEADER_SIZE] = {0};
4,864✔
962
    STR_WITH_MAXSIZE_TO_VARSTR(b2, role, pShow->pMeta->pSchemas[cols].bytes);
4,864✔
963
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,864✔
964
    code = colDataSetVal(pColInfo, numOfRows, (const char *)b2, false);
4,857✔
965
    if (code != 0) goto _err;
4,865!
966

967
    const char *status = "ready";
4,865✔
968
    if (objStatus == SDB_STATUS_CREATING) status = "creating";
4,865!
969
    if (objStatus == SDB_STATUS_DROPPING) status = "dropping";
4,865!
970
    if (!isDnodeOnline) status = "offline";
4,865✔
971
    char b3[9 + VARSTR_HEADER_SIZE] = {0};
4,865✔
972
    STR_WITH_MAXSIZE_TO_VARSTR(b3, status, pShow->pMeta->pSchemas[cols].bytes);
4,865✔
973
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,865✔
974
    code = colDataSetVal(pColInfo, numOfRows, (const char *)b3, false);
4,858✔
975
    if (code != 0) goto _err;
4,862!
976

977
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,862✔
978
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->createdTime, false);
4,862✔
979
    if (code != 0) goto _err;
4,862!
980

981
    int64_t roleTimeMs = (isDnodeOnline) ? pObj->roleTimeMs : 0;
4,862✔
982
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,862✔
983
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&roleTimeMs, false);
4,857✔
984
    if (code != 0) goto _err;
4,859!
985

986
    numOfRows++;
4,859✔
987
    sdbRelease(pSdb, pObj);
4,859✔
988
  }
989

990
  pShow->numOfRows += numOfRows;
4,584✔
991

992
_out:
4,584✔
993
  sdbRelease(pSdb, pSelfObj);
4,584✔
994
  return numOfRows;
4,577✔
995

996
_err:
×
997
  mError("mnode:%d, failed to set col data val since %s", pObj->id, tstrerror(code));
×
998
  sdbCancelFetch(pSdb, pShow->pIter);
×
999
  sdbRelease(pSdb, pObj);
×
1000
  sdbRelease(pSdb, pSelfObj);
×
1001
  return numOfRows;
×
1002
}
1003

1004
static void mndCancelGetNextMnode(SMnode *pMnode, void *pIter) {
×
1005
  SSdb *pSdb = pMnode->pSdb;
×
1006
  sdbCancelFetchByType(pSdb, pIter, SDB_MNODE);
×
1007
}
×
1008

1009
static int32_t mndProcessAlterMnodeReq(SRpcMsg *pReq) {
×
1010
#if 1
1011
  return 0;
×
1012
#else
1013
  int32_t         code = 0;
1014
  SMnode         *pMnode = pReq->info.node;
1015
  SDAlterMnodeReq alterReq = {0};
1016

1017
  TAOS_CHECK_RETURN(tDeserializeSDCreateMnodeReq(pReq->pCont, pReq->contLen, &alterReq));
1018

1019
  SMnodeOpt option = {.deploy = true, .numOfReplicas = alterReq.replica, .selfIndex = -1};
1020
  memcpy(option.replicas, alterReq.replicas, sizeof(alterReq.replicas));
1021
  for (int32_t i = 0; i < option.numOfReplicas; ++i) {
1022
    if (alterReq.replicas[i].id == pMnode->selfDnodeId) {
1023
      option.selfIndex = i;
1024
    }
1025
  }
1026

1027
  if (option.selfIndex == -1) {
1028
    mInfo("alter mnode not processed since selfIndex is -1", terrstr());
1029
    return 0;
1030
  }
1031

1032
  if ((code = mndWriteFile(pMnode->path, &option)) != 0) {
1033
    mError("failed to write mnode file since %s", terrstr());
1034
    TAOS_RETURN(code);
1035
  }
1036

1037
  SSyncCfg cfg = {.replicaNum = alterReq.replica, .myIndex = -1};
1038
  for (int32_t i = 0; i < alterReq.replica; ++i) {
1039
    SNodeInfo *pNode = &cfg.nodeInfo[i];
1040
    tstrncpy(pNode->nodeFqdn, alterReq.replicas[i].fqdn, sizeof(pNode->nodeFqdn));
1041
    pNode->nodePort = alterReq.replicas[i].port;
1042
    if (alterReq.replicas[i].id == pMnode->selfDnodeId) {
1043
      cfg.myIndex = i;
1044
    }
1045
  }
1046

1047
  if (cfg.myIndex == -1) {
1048
    mError("failed to alter mnode since myindex is -1");
1049
    return -1;
1050
  } else {
1051
    mInfo("start to alter mnode sync, replica:%d myIndex:%d", cfg.replicaNum, cfg.myIndex);
1052
    for (int32_t i = 0; i < alterReq.replica; ++i) {
1053
      SNodeInfo *pNode = &cfg.nodeInfo[i];
1054
      mInfo("index:%d, fqdn:%s port:%d", i, pNode->nodeFqdn, pNode->nodePort);
1055
    }
1056
  }
1057

1058
  code = syncReconfig(pMnode->syncMgmt.sync, &cfg);
1059
  if (code != 0) {
1060
    mError("failed to sync reconfig since %s", terrstr());
1061
  } else {
1062
    mInfo("alter mnode sync success");
1063
  }
1064

1065
  TAOS_RETURN(code);
1066
#endif
1067
}
1068

1069
static void mndReloadSyncConfig(SMnode *pMnode) {
2,837✔
1070
  SSdb      *pSdb = pMnode->pSdb;
2,837✔
1071
  SMnodeObj *pObj = NULL;
2,837✔
1072
  ESdbStatus objStatus = 0;
2,837✔
1073
  void      *pIter = NULL;
2,837✔
1074
  int32_t    updatingMnodes = 0;
2,837✔
1075
  int32_t    readyMnodes = 0;
2,837✔
1076
  int32_t    code = 0;
2,837✔
1077
  SSyncCfg   cfg = {
2,837✔
1078
        .myIndex = -1,
1079
        .lastIndex = 0,
1080
  };
1081
  SyncIndex maxIndex = 0;
2,837✔
1082

1083
  while (1) {
1084
    pIter = sdbFetchAll(pSdb, SDB_MNODE, pIter, (void **)&pObj, &objStatus, false);
6,889✔
1085
    if (pIter == NULL) break;
6,889✔
1086
    if (objStatus == SDB_STATUS_CREATING || objStatus == SDB_STATUS_DROPPING) {
4,052✔
1087
      mInfo("vgId:1, has updating mnode:%d, status:%s", pObj->id, sdbStatusName(objStatus));
312!
1088
      updatingMnodes++;
312✔
1089
    }
1090
    if (objStatus == SDB_STATUS_READY) {
4,052✔
1091
      mInfo("vgId:1, has ready mnode:%d, status:%s", pObj->id, sdbStatusName(objStatus));
3,740!
1092
      readyMnodes++;
3,740✔
1093
    }
1094

1095
    if (objStatus == SDB_STATUS_READY || objStatus == SDB_STATUS_CREATING) {
4,052✔
1096
      SNodeInfo *pNode = &cfg.nodeInfo[cfg.totalReplicaNum];
4,036✔
1097
      pNode->nodeId = pObj->pDnode->id;
4,036✔
1098
      pNode->clusterId = mndGetClusterId(pMnode);
4,036✔
1099
      pNode->nodePort = pObj->pDnode->port;
4,036✔
1100
      pNode->nodeRole = pObj->role;
4,036✔
1101
      tstrncpy(pNode->nodeFqdn, pObj->pDnode->fqdn, TSDB_FQDN_LEN);
4,036✔
1102
      code = tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort);
4,036✔
1103
      if (code != 0) {
4,036!
1104
        mError("mnode:%d, failed to update dnode info since %s", pObj->id, terrstr());
×
1105
      }
1106
      mInfo("vgId:1, ep:%s:%u dnode:%d", pNode->nodeFqdn, pNode->nodePort, pNode->nodeId);
4,036!
1107
      if (pObj->pDnode->id == pMnode->selfDnodeId) {
4,036✔
1108
        cfg.myIndex = cfg.totalReplicaNum;
2,415✔
1109
      }
1110
      if (pNode->nodeRole == TAOS_SYNC_ROLE_VOTER) {
4,036✔
1111
        cfg.replicaNum++;
3,740✔
1112
      }
1113
      cfg.totalReplicaNum++;
4,036✔
1114
      if (pObj->lastIndex > cfg.lastIndex) {
4,036✔
1115
        cfg.lastIndex = pObj->lastIndex;
1,175✔
1116
      }
1117
    }
1118

1119
    if (objStatus == SDB_STATUS_DROPPING) {
4,052✔
1120
      if (pObj->lastIndex > cfg.lastIndex) {
16!
1121
        cfg.lastIndex = pObj->lastIndex;
16✔
1122
      }
1123
    }
1124

1125
    mInfo("vgId:1, mnode:%d, role:%d, lastIndex:%" PRId64, pObj->id, pObj->role, pObj->lastIndex);
4,052!
1126

1127
    sdbReleaseLock(pSdb, pObj, false);
4,052✔
1128
  }
1129

1130
  // if (readyMnodes <= 0 || updatingMnodes <= 0) {
1131
  //   mInfo("vgId:1, mnode sync not reconfig since readyMnodes:%d updatingMnodes:%d", readyMnodes, updatingMnodes);
1132
  //   return;
1133
  // }
1134

1135
  if (cfg.myIndex == -1) {
2,837✔
1136
#if 1
1137
    mInfo("vgId:1, mnode sync not reconfig since selfIndex is -1");
422!
1138
#else
1139
    // cannot reconfig because the leader may fail to elect after reboot
1140
    mInfo("vgId:1, mnode sync not reconfig since selfIndex is -1, do sync stop oper");
1141
    syncStop(pMnode->syncMgmt.sync);
1142
#endif
1143
    return;
422✔
1144
  }
1145

1146
  if (pMnode->syncMgmt.sync > 0) {
2,415✔
1147
    mInfo("vgId:1, mnode sync reconfig, totalReplica:%d replica:%d myIndex:%d", cfg.totalReplicaNum, cfg.replicaNum,
2,015!
1148
          cfg.myIndex);
1149

1150
    for (int32_t i = 0; i < cfg.totalReplicaNum; ++i) {
4,831✔
1151
      SNodeInfo *pNode = &cfg.nodeInfo[i];
2,816✔
1152
      mInfo("vgId:1, index:%d, ep:%s:%u dnode:%d cluster:%" PRId64 " role:%d", i, pNode->nodeFqdn, pNode->nodePort,
2,816!
1153
            pNode->nodeId, pNode->clusterId, pNode->nodeRole);
1154
    }
1155

1156
    int32_t code = syncReconfig(pMnode->syncMgmt.sync, &cfg);
2,015✔
1157
    if (code != 0) {
2,015!
1158
      mError("vgId:1, mnode sync reconfig failed since %s", terrstr());
×
1159
    } else {
1160
      mInfo("vgId:1, mnode sync reconfig success");
2,015!
1161
    }
1162
  }
1163
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc