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

taosdata / TDengine / #4836

31 Oct 2025 03:37AM UTC coverage: 58.728% (+0.2%) from 58.506%
#4836

push

travis-ci

SallyHuo-TAOS
Merge remote-tracking branch 'origin/cover/3.0' into cover/3.0

# Conflicts:
#	test/ci/run.sh

149727 of 324176 branches covered (46.19%)

Branch coverage included in aggregate %.

198923 of 269498 relevant lines covered (73.81%)

238054213.11 hits per line

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

55.16
/source/dnode/mnode/impl/src/mndVgroup.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 "mndArbGroup.h"
19
#include "mndDb.h"
20
#include "mndDnode.h"
21
#include "mndMnode.h"
22
#include "mndPrivilege.h"
23
#include "mndShow.h"
24
#include "mndStb.h"
25
#include "mndStream.h"
26
#include "mndTopic.h"
27
#include "mndTrans.h"
28
#include "mndUser.h"
29
#include "mndVgroup.h"
30
#include "tmisce.h"
31

32
#define VGROUP_VER_NUMBER   1
33
#define VGROUP_RESERVE_SIZE 60
34

35
static int32_t mndVgroupActionInsert(SSdb *pSdb, SVgObj *pVgroup);
36
static int32_t mndVgroupActionDelete(SSdb *pSdb, SVgObj *pVgroup);
37
static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew);
38
static int32_t mndNewVgActionValidate(SMnode *pMnode, STrans *pTrans, SSdbRaw *pRaw);
39

40
static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
41
static void    mndCancelGetNextVgroup(SMnode *pMnode, void *pIter);
42
static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
43
static void    mndCancelGetNextVnode(SMnode *pMnode, void *pIter);
44

45
static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq);
46
static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq);
47
static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq);
48
static int32_t mndProcessVgroupBalanceLeaderMsg(SRpcMsg *pReq);
49

50
int32_t mndInitVgroup(SMnode *pMnode) {
1,746,882✔
51
  SSdbTable table = {
1,746,882✔
52
      .sdbType = SDB_VGROUP,
53
      .keyType = SDB_KEY_INT32,
54
      .encodeFp = (SdbEncodeFp)mndVgroupActionEncode,
55
      .decodeFp = (SdbDecodeFp)mndVgroupActionDecode,
56
      .insertFp = (SdbInsertFp)mndVgroupActionInsert,
57
      .updateFp = (SdbUpdateFp)mndVgroupActionUpdate,
58
      .deleteFp = (SdbDeleteFp)mndVgroupActionDelete,
59
      .validateFp = (SdbValidateFp)mndNewVgActionValidate,
60
  };
61

62
  mndSetMsgHandle(pMnode, TDMT_DND_CREATE_VNODE_RSP, mndTransProcessRsp);
1,746,882✔
63
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_REPLICA_RSP, mndTransProcessRsp);
1,746,882✔
64
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_CONFIG_RSP, mndTransProcessRsp);
1,746,882✔
65
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_CONFIRM_RSP, mndTransProcessRsp);
1,746,882✔
66
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_HASHRANGE_RSP, mndTransProcessRsp);
1,746,882✔
67
  mndSetMsgHandle(pMnode, TDMT_DND_DROP_VNODE_RSP, mndTransProcessRsp);
1,746,882✔
68
  mndSetMsgHandle(pMnode, TDMT_VND_COMPACT_RSP, mndTransProcessRsp);
1,746,882✔
69
  mndSetMsgHandle(pMnode, TDMT_VND_SCAN_RSP, mndTransProcessRsp);
1,746,882✔
70
  mndSetMsgHandle(pMnode, TDMT_VND_DISABLE_WRITE_RSP, mndTransProcessRsp);
1,746,882✔
71
  mndSetMsgHandle(pMnode, TDMT_SYNC_FORCE_FOLLOWER_RSP, mndTransProcessRsp);
1,746,882✔
72
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_ELECTBASELINE_RSP, mndTransProcessRsp);
1,746,882✔
73
  
74
  mndSetMsgHandle(pMnode, TDMT_DND_ALTER_VNODE_TYPE_RSP, mndTransProcessRsp);
1,746,882✔
75
  mndSetMsgHandle(pMnode, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP_RSP, mndTransProcessRsp);
1,746,882✔
76
  mndSetMsgHandle(pMnode, TDMT_SYNC_CONFIG_CHANGE_RSP, mndTransProcessRsp);
1,746,882✔
77

78
  mndSetMsgHandle(pMnode, TDMT_MND_REDISTRIBUTE_VGROUP, mndProcessRedistributeVgroupMsg);
1,746,882✔
79
  mndSetMsgHandle(pMnode, TDMT_MND_SPLIT_VGROUP, mndProcessSplitVgroupMsg);
1,746,882✔
80
  // mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP, mndProcessVgroupBalanceLeaderMsg);
81
  mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP, mndProcessBalanceVgroupMsg);
1,746,882✔
82
  mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP_LEADER, mndProcessVgroupBalanceLeaderMsg);
1,746,882✔
83

84
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_VGROUP, mndRetrieveVgroups);
1,746,882✔
85
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_VGROUP, mndCancelGetNextVgroup);
1,746,882✔
86
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_VNODES, mndRetrieveVnodes);
1,746,882✔
87
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_VNODES, mndCancelGetNextVnode);
1,746,882✔
88

89
  return sdbSetTable(pMnode->pSdb, table);
1,746,882✔
90
}
91

92
void mndCleanupVgroup(SMnode *pMnode) {}
1,746,589✔
93

94
SSdbRaw *mndVgroupActionEncode(SVgObj *pVgroup) {
35,390,239✔
95
  int32_t code = 0;
35,390,239✔
96
  int32_t lino = 0;
35,390,239✔
97
  terrno = TSDB_CODE_OUT_OF_MEMORY;
35,390,239✔
98

99
  SSdbRaw *pRaw = sdbAllocRaw(SDB_VGROUP, VGROUP_VER_NUMBER, sizeof(SVgObj) + VGROUP_RESERVE_SIZE);
35,390,239✔
100
  if (pRaw == NULL) goto _OVER;
35,390,239!
101

102
  int32_t dataPos = 0;
35,390,239✔
103
  SDB_SET_INT32(pRaw, dataPos, pVgroup->vgId, _OVER)
35,390,239!
104
  SDB_SET_INT64(pRaw, dataPos, pVgroup->createdTime, _OVER)
35,390,239!
105
  SDB_SET_INT64(pRaw, dataPos, pVgroup->updateTime, _OVER)
35,390,239!
106
  SDB_SET_INT32(pRaw, dataPos, pVgroup->version, _OVER)
35,390,239!
107
  SDB_SET_INT32(pRaw, dataPos, pVgroup->hashBegin, _OVER)
35,390,239!
108
  SDB_SET_INT32(pRaw, dataPos, pVgroup->hashEnd, _OVER)
35,390,239!
109
  SDB_SET_BINARY(pRaw, dataPos, pVgroup->dbName, TSDB_DB_FNAME_LEN, _OVER)
35,390,239!
110
  SDB_SET_INT64(pRaw, dataPos, pVgroup->dbUid, _OVER)
35,390,239!
111
  SDB_SET_INT8(pRaw, dataPos, pVgroup->isTsma, _OVER)
35,390,239!
112
  SDB_SET_INT8(pRaw, dataPos, pVgroup->replica, _OVER)
35,390,239!
113
  for (int8_t i = 0; i < pVgroup->replica; ++i) {
77,643,215✔
114
    SVnodeGid *pVgid = &pVgroup->vnodeGid[i];
42,252,976✔
115
    SDB_SET_INT32(pRaw, dataPos, pVgid->dnodeId, _OVER)
42,252,976!
116
  }
117
  SDB_SET_INT32(pRaw, dataPos, pVgroup->syncConfChangeVer, _OVER)
35,390,239!
118
  SDB_SET_INT32(pRaw, dataPos, pVgroup->mountVgId, _OVER)
35,390,239!
119
  SDB_SET_RESERVE(pRaw, dataPos, VGROUP_RESERVE_SIZE, _OVER)
35,390,239!
120
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
35,390,239!
121

122
  terrno = 0;
35,390,239✔
123

124
_OVER:
35,390,239✔
125
  if (terrno != 0) {
35,390,239!
126
    mError("vgId:%d, failed to encode to raw:%p since %s", pVgroup->vgId, pRaw, terrstr());
×
127
    sdbFreeRaw(pRaw);
×
128
    return NULL;
×
129
  }
130

131
  mTrace("vgId:%d, encode to raw:%p, row:%p", pVgroup->vgId, pRaw, pVgroup);
35,390,239✔
132
  return pRaw;
35,390,239✔
133
}
134

135
SSdbRow *mndVgroupActionDecode(SSdbRaw *pRaw) {
32,472,783✔
136
  int32_t code = 0;
32,472,783✔
137
  int32_t lino = 0;
32,472,783✔
138
  terrno = TSDB_CODE_OUT_OF_MEMORY;
32,472,783✔
139
  SSdbRow *pRow = NULL;
32,472,783✔
140
  SVgObj  *pVgroup = NULL;
32,472,783✔
141

142
  int8_t sver = 0;
32,472,783✔
143
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
32,472,783!
144

145
  if (sver < 1 || sver > VGROUP_VER_NUMBER) {
32,472,783!
146
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
147
    goto _OVER;
×
148
  }
149

150
  pRow = sdbAllocRow(sizeof(SVgObj));
32,472,783✔
151
  if (pRow == NULL) goto _OVER;
32,472,783!
152

153
  pVgroup = sdbGetRowObj(pRow);
32,472,783✔
154
  if (pVgroup == NULL) goto _OVER;
32,472,783!
155

156
  int32_t dataPos = 0;
32,472,783✔
157
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->vgId, _OVER)
32,472,783!
158
  SDB_GET_INT64(pRaw, dataPos, &pVgroup->createdTime, _OVER)
32,472,783!
159
  SDB_GET_INT64(pRaw, dataPos, &pVgroup->updateTime, _OVER)
32,472,783!
160
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->version, _OVER)
32,472,783!
161
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->hashBegin, _OVER)
32,472,783!
162
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->hashEnd, _OVER)
32,472,783!
163
  SDB_GET_BINARY(pRaw, dataPos, pVgroup->dbName, TSDB_DB_FNAME_LEN, _OVER)
32,472,783!
164
  SDB_GET_INT64(pRaw, dataPos, &pVgroup->dbUid, _OVER)
32,472,783!
165
  SDB_GET_INT8(pRaw, dataPos, &pVgroup->isTsma, _OVER)
32,472,783!
166
  SDB_GET_INT8(pRaw, dataPos, &pVgroup->replica, _OVER)
32,472,783!
167
  for (int8_t i = 0; i < pVgroup->replica; ++i) {
72,441,039✔
168
    SVnodeGid *pVgid = &pVgroup->vnodeGid[i];
39,968,256✔
169
    SDB_GET_INT32(pRaw, dataPos, &pVgid->dnodeId, _OVER)
39,968,256!
170
    if (pVgroup->replica == 1) {
39,968,256✔
171
      pVgid->syncState = TAOS_SYNC_STATE_LEADER;
28,580,359✔
172
    }
173
  }
174
  if (dataPos + 2 * sizeof(int32_t) + VGROUP_RESERVE_SIZE <= pRaw->dataLen) {
32,472,783!
175
    SDB_GET_INT32(pRaw, dataPos, &pVgroup->syncConfChangeVer, _OVER)
32,472,783!
176
  }
177
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->mountVgId, _OVER)
32,472,783!
178
  SDB_GET_RESERVE(pRaw, dataPos, VGROUP_RESERVE_SIZE, _OVER)
32,472,783!
179

180
  terrno = 0;
32,472,783✔
181

182
_OVER:
32,472,783✔
183
  if (terrno != 0) {
32,472,783!
184
    mError("vgId:%d, failed to decode from raw:%p since %s", pVgroup == NULL ? 0 : pVgroup->vgId, pRaw, terrstr());
×
185
    taosMemoryFreeClear(pRow);
×
186
    return NULL;
×
187
  }
188

189
  mTrace("vgId:%d, decode from raw:%p, row:%p", pVgroup->vgId, pRaw, pVgroup);
32,472,783✔
190
  return pRow;
32,472,783✔
191
}
192

193
static int32_t mndNewVgActionValidate(SMnode *pMnode, STrans *pTrans, SSdbRaw *pRaw) {
8,721,130✔
194
  SSdb    *pSdb = pMnode->pSdb;
8,721,130✔
195
  SSdbRow *pRow = NULL;
8,721,130✔
196
  SVgObj  *pVgroup = NULL;
8,721,130✔
197
  int      code = -1;
8,721,130✔
198

199
  pRow = mndVgroupActionDecode(pRaw);
8,721,130✔
200
  if (pRow == NULL) {
8,721,130!
201
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
202
    if (terrno != 0) code = terrno;
×
203
    goto _OVER;
×
204
  }
205
  pVgroup = sdbGetRowObj(pRow);
8,721,130✔
206
  if (pVgroup == NULL) {
8,721,130!
207
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
208
    if (terrno != 0) code = terrno;
×
209
    goto _OVER;
×
210
  }
211

212
  int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
8,721,130✔
213
  if (maxVgId > pVgroup->vgId) {
8,721,130!
214
    mError("trans:%d, vgroup id %d already in use. maxVgId:%d", pTrans->id, pVgroup->vgId, maxVgId);
×
215
    goto _OVER;
×
216
  }
217

218
  code = 0;
8,721,130✔
219
_OVER:
8,721,130✔
220
  if (pVgroup) mndVgroupActionDelete(pSdb, pVgroup);
8,721,130!
221
  taosMemoryFreeClear(pRow);
8,721,130!
222
  TAOS_RETURN(code);
8,721,130✔
223
}
224

225
static int32_t mndVgroupActionInsert(SSdb *pSdb, SVgObj *pVgroup) {
10,068,248✔
226
  mTrace("vgId:%d, perform insert action, row:%p", pVgroup->vgId, pVgroup);
10,068,248✔
227
  return 0;
10,068,248✔
228
}
229

230
static int32_t mndVgroupActionDelete(SSdb *pSdb, SVgObj *pVgroup) {
32,413,583✔
231
  mTrace("vgId:%d, perform delete action, row:%p", pVgroup->vgId, pVgroup);
32,413,583✔
232
  return 0;
32,413,583✔
233
}
234

235
static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew) {
9,761,606✔
236
  mTrace("vgId:%d, perform update action, old row:%p new row:%p", pOld->vgId, pOld, pNew);
9,761,606✔
237
  pOld->updateTime = pNew->updateTime;
9,761,606✔
238
  pOld->version = pNew->version;
9,761,606✔
239
  pOld->hashBegin = pNew->hashBegin;
9,761,606✔
240
  pOld->hashEnd = pNew->hashEnd;
9,761,606✔
241
  pOld->replica = pNew->replica;
9,761,606✔
242
  pOld->isTsma = pNew->isTsma;
9,761,606✔
243
  for (int32_t i = 0; i < pNew->replica; ++i) {
22,679,843✔
244
    SVnodeGid *pNewGid = &pNew->vnodeGid[i];
12,918,237✔
245
    for (int32_t j = 0; j < pOld->replica; ++j) {
35,380,202✔
246
      SVnodeGid *pOldGid = &pOld->vnodeGid[j];
22,461,965✔
247
      if (pNewGid->dnodeId == pOldGid->dnodeId) {
22,461,965✔
248
        pNewGid->syncState = pOldGid->syncState;
12,357,977✔
249
        pNewGid->syncRestore = pOldGid->syncRestore;
12,357,977!
250
        pNewGid->syncCanRead = pOldGid->syncCanRead;
12,357,977!
251
        pNewGid->syncAppliedIndex = pOldGid->syncAppliedIndex;
12,357,977✔
252
        pNewGid->syncCommitIndex = pOldGid->syncCommitIndex;
12,357,977✔
253
        pNewGid->bufferSegmentUsed = pOldGid->bufferSegmentUsed;
12,357,977✔
254
        pNewGid->bufferSegmentSize = pOldGid->bufferSegmentSize;
12,357,977✔
255
      }
256
    }
257
  }
258
  pNew->numOfTables = pOld->numOfTables;
9,761,606✔
259
  pNew->numOfTimeSeries = pOld->numOfTimeSeries;
9,761,606✔
260
  pNew->totalStorage = pOld->totalStorage;
9,761,606✔
261
  pNew->compStorage = pOld->compStorage;
9,761,606✔
262
  pNew->pointsWritten = pOld->pointsWritten;
9,761,606✔
263
  pNew->compact = pOld->compact;
9,761,606✔
264
  memcpy(pOld->vnodeGid, pNew->vnodeGid, (TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA) * sizeof(SVnodeGid));
9,761,606!
265
  pOld->syncConfChangeVer = pNew->syncConfChangeVer;
9,761,606✔
266
  return 0;
9,761,606✔
267
}
268

269
SVgObj *mndAcquireVgroup(SMnode *pMnode, int32_t vgId) {
444,331,522✔
270
  SSdb   *pSdb = pMnode->pSdb;
444,331,522✔
271
  SVgObj *pVgroup = sdbAcquire(pSdb, SDB_VGROUP, &vgId);
444,331,522✔
272
  if (pVgroup == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
444,331,522✔
273
    terrno = TSDB_CODE_MND_VGROUP_NOT_EXIST;
2,724,711✔
274
  }
275
  return pVgroup;
444,331,522✔
276
}
277

278
void mndReleaseVgroup(SMnode *pMnode, SVgObj *pVgroup) {
442,185,448✔
279
  SSdb *pSdb = pMnode->pSdb;
442,185,448✔
280
  sdbRelease(pSdb, pVgroup);
442,185,448✔
281
}
442,185,448✔
282

283
void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen) {
9,276,114✔
284
  SCreateVnodeReq createReq = {0};
9,276,114✔
285
  createReq.vgId = pVgroup->vgId;
9,276,114✔
286
  memcpy(createReq.db, pDb->name, TSDB_DB_FNAME_LEN);
9,276,114✔
287
  createReq.dbUid = pDb->uid;
9,276,114✔
288
  createReq.vgVersion = pVgroup->version;
9,276,114✔
289
  createReq.numOfStables = pDb->cfg.numOfStables;
9,276,114✔
290
  createReq.buffer = pDb->cfg.buffer;
9,276,114✔
291
  createReq.pageSize = pDb->cfg.pageSize;
9,276,114✔
292
  createReq.pages = pDb->cfg.pages;
9,276,114✔
293
  createReq.cacheLastSize = pDb->cfg.cacheLastSize;
9,276,114✔
294
  createReq.daysPerFile = pDb->cfg.daysPerFile;
9,276,114✔
295
  createReq.daysToKeep0 = pDb->cfg.daysToKeep0;
9,276,114✔
296
  createReq.daysToKeep1 = pDb->cfg.daysToKeep1;
9,276,114✔
297
  createReq.daysToKeep2 = pDb->cfg.daysToKeep2;
9,276,114✔
298
  createReq.keepTimeOffset = pDb->cfg.keepTimeOffset;
9,276,114✔
299
  createReq.ssChunkSize = pDb->cfg.ssChunkSize;
9,276,114✔
300
  createReq.ssKeepLocal = pDb->cfg.ssKeepLocal;
9,276,114✔
301
  createReq.ssCompact = pDb->cfg.ssCompact;
9,276,114✔
302
  createReq.minRows = pDb->cfg.minRows;
9,276,114✔
303
  createReq.maxRows = pDb->cfg.maxRows;
9,276,114✔
304
  createReq.walFsyncPeriod = pDb->cfg.walFsyncPeriod;
9,276,114✔
305
  createReq.walLevel = pDb->cfg.walLevel;
9,276,114✔
306
  createReq.precision = pDb->cfg.precision;
9,276,114✔
307
  createReq.compression = pDb->cfg.compression;
9,276,114✔
308
  createReq.strict = pDb->cfg.strict;
9,276,114✔
309
  createReq.cacheLast = pDb->cfg.cacheLast;
9,276,114✔
310
  createReq.replica = 0;
9,276,114✔
311
  createReq.learnerReplica = 0;
9,276,114✔
312
  createReq.selfIndex = -1;
9,276,114✔
313
  createReq.learnerSelfIndex = -1;
9,276,114✔
314
  createReq.hashBegin = pVgroup->hashBegin;
9,276,114✔
315
  createReq.hashEnd = pVgroup->hashEnd;
9,276,114✔
316
  createReq.hashMethod = pDb->cfg.hashMethod;
9,276,114✔
317
  createReq.numOfRetensions = pDb->cfg.numOfRetensions;
9,276,114✔
318
  createReq.pRetensions = pDb->cfg.pRetensions;
9,276,114✔
319
  createReq.isTsma = pVgroup->isTsma;
9,276,114✔
320
  createReq.pTsma = pVgroup->pTsma;
9,276,114✔
321
  createReq.walRetentionPeriod = pDb->cfg.walRetentionPeriod;
9,276,114✔
322
  createReq.walRetentionSize = pDb->cfg.walRetentionSize;
9,276,114✔
323
  createReq.walRollPeriod = pDb->cfg.walRollPeriod;
9,276,114✔
324
  createReq.walSegmentSize = pDb->cfg.walSegmentSize;
9,276,114✔
325
  createReq.sstTrigger = pDb->cfg.sstTrigger;
9,276,114✔
326
  createReq.hashPrefix = pDb->cfg.hashPrefix;
9,276,114✔
327
  createReq.hashSuffix = pDb->cfg.hashSuffix;
9,276,114✔
328
  createReq.tsdbPageSize = pDb->cfg.tsdbPageSize;
9,276,114✔
329
  createReq.changeVersion = ++(pVgroup->syncConfChangeVer);
9,276,114✔
330
  createReq.encryptAlgorithm = pDb->cfg.encryptAlgorithm;
9,276,114✔
331
  int32_t code = 0;
9,276,114✔
332

333
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
22,127,301✔
334
    SReplica *pReplica = NULL;
12,851,187✔
335

336
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
12,851,187✔
337
      pReplica = &createReq.replicas[createReq.replica];
12,573,852✔
338
    } else {
339
      pReplica = &createReq.learnerReplicas[createReq.learnerReplica];
277,335✔
340
    }
341

342
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
12,851,187✔
343
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
12,851,187✔
344
    if (pVgidDnode == NULL) {
12,851,187!
345
      return NULL;
×
346
    }
347

348
    pReplica->id = pVgidDnode->id;
12,851,187✔
349
    pReplica->port = pVgidDnode->port;
12,851,187✔
350
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
12,851,187!
351
    mndReleaseDnode(pMnode, pVgidDnode);
12,851,187✔
352

353
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
12,851,187✔
354
      if (pDnode->id == pVgid->dnodeId) {
12,573,852✔
355
        createReq.selfIndex = createReq.replica;
8,998,779✔
356
      }
357
    } else {
358
      if (pDnode->id == pVgid->dnodeId) {
277,335!
359
        createReq.learnerSelfIndex = createReq.learnerReplica;
277,335✔
360
      }
361
    }
362

363
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
12,851,187✔
364
      createReq.replica++;
12,573,852✔
365
    } else {
366
      createReq.learnerReplica++;
277,335✔
367
    }
368
  }
369

370
  if (createReq.selfIndex == -1 && createReq.learnerSelfIndex == -1) {
9,276,114!
371
    terrno = TSDB_CODE_APP_ERROR;
×
372
    return NULL;
×
373
  }
374

375
  createReq.changeVersion = pVgroup->syncConfChangeVer;
9,276,114✔
376

377
  mInfo(
9,276,114!
378
      "vgId:%d, build create vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
379
      "changeVersion:%d",
380
      createReq.vgId, createReq.replica, createReq.selfIndex, createReq.learnerReplica, createReq.learnerSelfIndex,
381
      createReq.strict, createReq.changeVersion);
382
  for (int32_t i = 0; i < createReq.replica; ++i) {
21,849,966✔
383
    mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.replicas[i].fqdn, createReq.replicas[i].port);
12,573,852!
384
  }
385
  for (int32_t i = 0; i < createReq.learnerReplica; ++i) {
9,553,449✔
386
    mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.learnerReplicas[i].fqdn,
277,335!
387
          createReq.learnerReplicas[i].port);
388
  }
389

390
  int32_t contLen = tSerializeSCreateVnodeReq(NULL, 0, &createReq);
9,276,114✔
391
  if (contLen < 0) {
9,276,114!
392
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
393
    return NULL;
×
394
  }
395

396
  void *pReq = taosMemoryMalloc(contLen);
9,276,114!
397
  if (pReq == NULL) {
9,276,114!
398
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
399
    return NULL;
×
400
  }
401

402
  code = tSerializeSCreateVnodeReq(pReq, contLen, &createReq);
9,276,114✔
403
  if (code < 0) {
9,276,114!
404
    terrno = TSDB_CODE_APP_ERROR;
×
405
    taosMemoryFree(pReq);
×
406
    mError("vgId:%d, failed to serialize create vnode req,since %s", createReq.vgId, terrstr());
×
407
    return NULL;
×
408
  }
409
  *pContLen = contLen;
9,276,114✔
410
  return pReq;
9,276,114✔
411
}
412

413
static void *mndBuildAlterVnodeConfigReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen) {
510,002✔
414
  SAlterVnodeConfigReq alterReq = {0};
510,002✔
415
  alterReq.vgVersion = pVgroup->version;
510,002✔
416
  alterReq.buffer = pDb->cfg.buffer;
510,002✔
417
  alterReq.pageSize = pDb->cfg.pageSize;
510,002✔
418
  alterReq.pages = pDb->cfg.pages;
510,002✔
419
  alterReq.cacheLastSize = pDb->cfg.cacheLastSize;
510,002✔
420
  alterReq.daysPerFile = pDb->cfg.daysPerFile;
510,002✔
421
  alterReq.daysToKeep0 = pDb->cfg.daysToKeep0;
510,002✔
422
  alterReq.daysToKeep1 = pDb->cfg.daysToKeep1;
510,002✔
423
  alterReq.daysToKeep2 = pDb->cfg.daysToKeep2;
510,002✔
424
  alterReq.keepTimeOffset = pDb->cfg.keepTimeOffset;
510,002✔
425
  alterReq.walFsyncPeriod = pDb->cfg.walFsyncPeriod;
510,002✔
426
  alterReq.walLevel = pDb->cfg.walLevel;
510,002✔
427
  alterReq.strict = pDb->cfg.strict;
510,002✔
428
  alterReq.cacheLast = pDb->cfg.cacheLast;
510,002✔
429
  alterReq.sttTrigger = pDb->cfg.sstTrigger;
510,002✔
430
  alterReq.minRows = pDb->cfg.minRows;
510,002✔
431
  alterReq.walRetentionPeriod = pDb->cfg.walRetentionPeriod;
510,002✔
432
  alterReq.walRetentionSize = pDb->cfg.walRetentionSize;
510,002✔
433
  alterReq.ssKeepLocal = pDb->cfg.ssKeepLocal;
510,002✔
434
  alterReq.ssCompact = pDb->cfg.ssCompact;
510,002✔
435

436
  mInfo("vgId:%d, build alter vnode config req", pVgroup->vgId);
510,002!
437
  int32_t contLen = tSerializeSAlterVnodeConfigReq(NULL, 0, &alterReq);
510,002✔
438
  if (contLen < 0) {
510,002!
439
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
440
    return NULL;
×
441
  }
442
  contLen += sizeof(SMsgHead);
510,002✔
443

444
  void *pReq = taosMemoryMalloc(contLen);
510,002!
445
  if (pReq == NULL) {
510,002!
446
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
447
    return NULL;
×
448
  }
449

450
  SMsgHead *pHead = pReq;
510,002✔
451
  pHead->contLen = htonl(contLen);
510,002✔
452
  pHead->vgId = htonl(pVgroup->vgId);
510,002✔
453

454
  if (tSerializeSAlterVnodeConfigReq((char *)pReq + sizeof(SMsgHead), contLen, &alterReq) < 0) {
510,002!
455
    taosMemoryFree(pReq);
×
456
    mError("vgId:%d, failed to serialize alter vnode config req,since %s", pVgroup->vgId, terrstr());
×
457
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
458
    return NULL;
×
459
  }
460
  *pContLen = contLen;
510,002✔
461
  return pReq;
510,002✔
462
}
463

464
static void *mndBuildAlterVnodeReplicaReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId,
2,043,594✔
465
                                          int32_t *pContLen) {
466
  SAlterVnodeReplicaReq alterReq = {
4,087,188✔
467
      .vgId = pVgroup->vgId,
2,043,594✔
468
      .strict = pDb->cfg.strict,
2,043,594✔
469
      .replica = 0,
470
      .learnerReplica = 0,
471
      .selfIndex = -1,
472
      .learnerSelfIndex = -1,
473
      .changeVersion = ++(pVgroup->syncConfChangeVer),
4,087,188✔
474
  };
475

476
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
8,221,249✔
477
    SReplica *pReplica = NULL;
6,177,655✔
478

479
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
6,177,655✔
480
      pReplica = &alterReq.replicas[alterReq.replica];
5,702,633✔
481
      alterReq.replica++;
5,702,633✔
482
    } else {
483
      pReplica = &alterReq.learnerReplicas[alterReq.learnerReplica];
475,022✔
484
      alterReq.learnerReplica++;
475,022✔
485
    }
486

487
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
6,177,655✔
488
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
6,177,655✔
489
    if (pVgidDnode == NULL) return NULL;
6,177,655!
490

491
    pReplica->id = pVgidDnode->id;
6,177,655✔
492
    pReplica->port = pVgidDnode->port;
6,177,655✔
493
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
6,177,655!
494
    mndReleaseDnode(pMnode, pVgidDnode);
6,177,655✔
495

496
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
6,177,655✔
497
      if (dnodeId == pVgid->dnodeId) {
5,702,633✔
498
        alterReq.selfIndex = v;
2,043,594✔
499
      }
500
    } else {
501
      if (dnodeId == pVgid->dnodeId) {
475,022!
502
        alterReq.learnerSelfIndex = v;
×
503
      }
504
    }
505
  }
506

507
  mInfo(
2,043,594!
508
      "vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
509
      "changeVersion:%d",
510
      alterReq.vgId, alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica, alterReq.learnerSelfIndex,
511
      alterReq.strict, alterReq.changeVersion);
512
  for (int32_t i = 0; i < alterReq.replica; ++i) {
7,746,227✔
513
    mInfo("vgId:%d, replica:%d ep:%s:%u", alterReq.vgId, i, alterReq.replicas[i].fqdn, alterReq.replicas[i].port);
5,702,633!
514
  }
515
  for (int32_t i = 0; i < alterReq.learnerReplica; ++i) {
2,518,616✔
516
    mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", alterReq.vgId, i, alterReq.learnerReplicas[i].fqdn,
475,022!
517
          alterReq.learnerReplicas[i].port);
518
  }
519

520
  if (alterReq.selfIndex == -1 && alterReq.learnerSelfIndex == -1) {
2,043,594!
521
    terrno = TSDB_CODE_APP_ERROR;
×
522
    return NULL;
×
523
  }
524

525
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &alterReq);
2,043,594✔
526
  if (contLen < 0) {
2,043,594!
527
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
528
    return NULL;
×
529
  }
530

531
  void *pReq = taosMemoryMalloc(contLen);
2,043,594!
532
  if (pReq == NULL) {
2,043,594!
533
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
534
    return NULL;
×
535
  }
536

537
  if (tSerializeSAlterVnodeReplicaReq(pReq, contLen, &alterReq) < 0) {
2,043,594!
538
    mError("vgId:%d, failed to serialize alter vnode req,since %s", alterReq.vgId, terrstr());
×
539
    taosMemoryFree(pReq);
×
540
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
541
    return NULL;
×
542
  }
543
  *pContLen = contLen;
2,043,594✔
544
  return pReq;
2,043,594✔
545
}
546

547
static void *mndBuildCheckLearnCatchupReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId,
×
548
                                          int32_t *pContLen) {
549
  SCheckLearnCatchupReq req = {
×
550
      .vgId = pVgroup->vgId,
×
551
      .strict = pDb->cfg.strict,
×
552
      .replica = 0,
553
      .learnerReplica = 0,
554
      .selfIndex = -1,
555
      .learnerSelfIndex = -1,
556
  };
557

558
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
×
559
    SReplica *pReplica = NULL;
×
560

561
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
×
562
      pReplica = &req.replicas[req.replica];
×
563
      req.replica++;
×
564
    } else {
565
      pReplica = &req.learnerReplicas[req.learnerReplica];
×
566
      req.learnerReplica++;
×
567
    }
568

569
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
×
570
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
×
571
    if (pVgidDnode == NULL) return NULL;
×
572

573
    pReplica->id = pVgidDnode->id;
×
574
    pReplica->port = pVgidDnode->port;
×
575
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
×
576
    mndReleaseDnode(pMnode, pVgidDnode);
×
577

578
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
×
579
      if (dnodeId == pVgid->dnodeId) {
×
580
        req.selfIndex = v;
×
581
      }
582
    } else {
583
      if (dnodeId == pVgid->dnodeId) {
×
584
        req.learnerSelfIndex = v;
×
585
      }
586
    }
587
  }
588

589
  mInfo("vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d",
×
590
        req.vgId, req.replica, req.selfIndex, req.learnerReplica, req.learnerSelfIndex, req.strict);
591
  for (int32_t i = 0; i < req.replica; ++i) {
×
592
    mInfo("vgId:%d, replica:%d ep:%s:%u", req.vgId, i, req.replicas[i].fqdn, req.replicas[i].port);
×
593
  }
594
  for (int32_t i = 0; i < req.learnerReplica; ++i) {
×
595
    mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", req.vgId, i, req.learnerReplicas[i].fqdn, req.learnerReplicas[i].port);
×
596
  }
597

598
  if (req.selfIndex == -1 && req.learnerSelfIndex == -1) {
×
599
    terrno = TSDB_CODE_APP_ERROR;
×
600
    return NULL;
×
601
  }
602

603
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &req);
×
604
  if (contLen < 0) {
×
605
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
606
    return NULL;
×
607
  }
608

609
  void *pReq = taosMemoryMalloc(contLen);
×
610
  if (pReq == NULL) {
×
611
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
612
    return NULL;
×
613
  }
614

615
  if (tSerializeSAlterVnodeReplicaReq(pReq, contLen, &req) < 0) {
×
616
    mError("vgId:%d, failed to serialize alter vnode req,since %s", req.vgId, terrstr());
×
617
    taosMemoryFree(pReq);
×
618
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
619
    return NULL;
×
620
  }
621
  *pContLen = contLen;
×
622
  return pReq;
×
623
}
624

625
static void *mndBuildDisableVnodeWriteReq(SMnode *pMnode, SDbObj *pDb, int32_t vgId, int32_t *pContLen) {
82,290✔
626
  SDisableVnodeWriteReq disableReq = {
82,290✔
627
      .vgId = vgId,
628
      .disable = 1,
629
  };
630

631
  mInfo("vgId:%d, build disable vnode write req", vgId);
82,290!
632
  int32_t contLen = tSerializeSDisableVnodeWriteReq(NULL, 0, &disableReq);
82,290✔
633
  if (contLen < 0) {
82,290!
634
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
635
    return NULL;
×
636
  }
637

638
  void *pReq = taosMemoryMalloc(contLen);
82,290!
639
  if (pReq == NULL) {
82,290!
640
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
641
    return NULL;
×
642
  }
643

644
  if (tSerializeSDisableVnodeWriteReq(pReq, contLen, &disableReq) < 0) {
82,290!
645
    mError("vgId:%d, failed to serialize disable vnode write req,since %s", vgId, terrstr());
×
646
    taosMemoryFree(pReq);
×
647
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
648
    return NULL;
×
649
  }
650
  *pContLen = contLen;
82,290✔
651
  return pReq;
82,290✔
652
}
653

654
static void *mndBuildAlterVnodeHashRangeReq(SMnode *pMnode, int32_t srcVgId, SVgObj *pVgroup, int32_t *pContLen) {
82,290✔
655
  SAlterVnodeHashRangeReq alterReq = {
164,580✔
656
      .srcVgId = srcVgId,
657
      .dstVgId = pVgroup->vgId,
82,290✔
658
      .hashBegin = pVgroup->hashBegin,
82,290✔
659
      .hashEnd = pVgroup->hashEnd,
82,290✔
660
      .changeVersion = ++(pVgroup->syncConfChangeVer),
164,580✔
661
  };
662

663
  mInfo("vgId:%d, build alter vnode hashrange req, dstVgId:%d, hashrange:[%u, %u]", srcVgId, pVgroup->vgId,
82,290!
664
        pVgroup->hashBegin, pVgroup->hashEnd);
665
  int32_t contLen = tSerializeSAlterVnodeHashRangeReq(NULL, 0, &alterReq);
82,290✔
666
  if (contLen < 0) {
82,290!
667
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
668
    return NULL;
×
669
  }
670

671
  void *pReq = taosMemoryMalloc(contLen);
82,290!
672
  if (pReq == NULL) {
82,290!
673
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
674
    return NULL;
×
675
  }
676

677
  if (tSerializeSAlterVnodeHashRangeReq(pReq, contLen, &alterReq) < 0) {
82,290!
678
    mError("vgId:%d, failed to serialize alter vnode hashrange req,since %s", srcVgId, terrstr());
×
679
    taosMemoryFree(pReq);
×
680
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
681
    return NULL;
×
682
  }
683
  *pContLen = contLen;
82,290✔
684
  return pReq;
82,290✔
685
}
686

687
void *mndBuildDropVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen) {
12,989,171✔
688
  SDropVnodeReq dropReq = {0};
12,989,171✔
689
  dropReq.dnodeId = pDnode->id;
12,989,171✔
690
  dropReq.vgId = pVgroup->vgId;
12,989,171✔
691
  memcpy(dropReq.db, pDb->name, TSDB_DB_FNAME_LEN);
12,989,171✔
692
  dropReq.dbUid = pDb->uid;
12,989,171✔
693

694
  mInfo("vgId:%d, build drop vnode req", dropReq.vgId);
12,989,171!
695
  int32_t contLen = tSerializeSDropVnodeReq(NULL, 0, &dropReq);
12,989,171✔
696
  if (contLen < 0) {
12,989,171!
697
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
698
    return NULL;
×
699
  }
700

701
  void *pReq = taosMemoryMalloc(contLen);
12,989,171!
702
  if (pReq == NULL) {
12,989,171!
703
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
704
    return NULL;
×
705
  }
706

707
  if (tSerializeSDropVnodeReq(pReq, contLen, &dropReq) < 0) {
12,989,171!
708
    mError("vgId:%d, failed to serialize drop vnode req,since %s", dropReq.vgId, terrstr());
×
709
    taosMemoryFree(pReq);
×
710
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
711
    return NULL;
×
712
  }
713
  *pContLen = contLen;
12,989,171✔
714
  return pReq;
12,989,171✔
715
}
716

717
static bool mndResetDnodesArrayFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
5,758,479✔
718
  SDnodeObj *pDnode = pObj;
5,758,479✔
719
  pDnode->numOfVnodes = 0;
5,758,479✔
720
  pDnode->numOfOtherNodes = 0;
5,758,479✔
721
  return true;
5,758,479✔
722
}
723

724
static bool mndBuildDnodesArrayFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
5,758,479✔
725
  SDnodeObj *pDnode = pObj;
5,758,479✔
726
  SArray    *pArray = p1;
5,758,479✔
727
  int32_t    exceptDnodeId = *(int32_t *)p2;
5,758,479✔
728
  SArray    *dnodeList = p3;
5,758,479✔
729

730
  if (exceptDnodeId == pDnode->id) {
5,758,479✔
731
    return true;
20,412✔
732
  }
733

734
  if (dnodeList != NULL) {
5,738,067✔
735
    int32_t dnodeListSize = taosArrayGetSize(dnodeList);
151,240✔
736
    if (dnodeListSize > 0) {
151,240!
737
      bool inDnodeList = false;
151,240✔
738
      for (int32_t index = 0; index < dnodeListSize; ++index) {
493,520✔
739
        int32_t dnodeId = *(int32_t *)taosArrayGet(dnodeList, index);
342,280✔
740
        if (pDnode->id == dnodeId) {
342,280✔
741
          inDnodeList = true;
68,456✔
742
        }
743
      }
744
      if (!inDnodeList) {
151,240✔
745
        return true;
82,784✔
746
      }
747
    } else {
748
      return true;  // TS-6191
×
749
    }
750
  }
751

752
  int64_t curMs = taosGetTimestampMs();
5,655,283✔
753
  bool    online = mndIsDnodeOnline(pDnode, curMs);
5,655,283✔
754
  bool    isMnode = mndIsMnode(pMnode, pDnode->id);
5,655,283✔
755
  pDnode->numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
5,655,283✔
756
  pDnode->memUsed = mndGetVnodesMemory(pMnode, pDnode->id);
5,655,283✔
757

758
  mInfo("dnode:%d, vnodes:%d supportVnodes:%d isMnode:%d online:%d memory avail:%" PRId64 " used:%" PRId64, pDnode->id,
5,655,283!
759
        pDnode->numOfVnodes, pDnode->numOfSupportVnodes, isMnode, online, pDnode->memAvail, pDnode->memUsed);
760

761
  if (isMnode) {
5,655,283✔
762
    pDnode->numOfOtherNodes++;
4,265,327✔
763
  }
764

765
  if (online && pDnode->numOfSupportVnodes > 0) {
5,655,283✔
766
    if (taosArrayPush(pArray, pDnode) == NULL) return false;
5,528,984!
767
  }
768
  return true;
5,655,283✔
769
}
770

771
static bool isDnodeInList(SArray *dnodeList, int32_t dnodeId) {
×
772
  int32_t dnodeListSize = taosArrayGetSize(dnodeList);
×
773
  for (int32_t i = 0; i < dnodeListSize; ++i) {
×
774
    int32_t id = *(int32_t *)TARRAY_GET_ELEM(dnodeList, i);
×
775
    if (id == dnodeId) {
×
776
      return true;
×
777
    }
778
  }
779
  return false;
×
780
}
781

782
#ifdef TD_ENTERPRISE
783
static float mndGetDnodeScore1(SDnodeObj *pDnode, int32_t additionDnodes, float ratio) {
×
784
  float totalDnodes = pDnode->numOfVnodes + (float)pDnode->numOfOtherNodes * ratio + additionDnodes;
×
785
  float result = totalDnodes / pDnode->numOfSupportVnodes;
×
786
  return pDnode->numOfVnodes > 0 ? -result : result;
×
787
}
788

789
static int32_t mndCompareDnodeVnodes1(SDnodeObj *pDnode1, SDnodeObj *pDnode2) {
×
790
  float d1Score = mndGetDnodeScore1(pDnode1, 0, 0.9);
×
791
  float d2Score = mndGetDnodeScore1(pDnode2, 0, 0.9);
×
792
  if (d1Score == d2Score) {
×
793
    if (pDnode1->id == pDnode2->id) {
×
794
      return 0;
×
795
    }
796
    return pDnode1->id > pDnode2->id ? 1 : -1;
×
797
  }
798
  return d1Score > d2Score ? 1 : -1;
×
799
}
800

801
static bool mndBuildDnodesListFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
×
802
  SDnodeObj *pDnode = pObj;
×
803
  SArray    *pArray = p1;
×
804

805
  bool isMnode = mndIsMnode(pMnode, pDnode->id);
×
806
  pDnode->numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
×
807

808
  if (isMnode) {
×
809
    pDnode->numOfOtherNodes++;
×
810
  }
811

812
  if (pDnode->numOfSupportVnodes > 0) {
×
813
    if (taosArrayPush(pArray, pDnode) == NULL) return false;
×
814
  }
815
  return true;
×
816
}
817

818
// TS-6191
819
static int32_t mndBuildNodesCheckDualReplica(SMnode *pMnode, int32_t nDnodes, SArray *dnodeList, SArray **ppDnodeList) {
4,047,714✔
820
  int32_t code = 0;
4,047,714✔
821
  if (!grantCheckDualReplicaDnodes(pMnode)) {
4,047,714!
822
    TAOS_RETURN(code);
4,047,714✔
823
  }
824
  SSdb   *pSdb = pMnode->pSdb;
×
825
  SArray *pArray = taosArrayInit(nDnodes, sizeof(SDnodeObj));
×
826
  if (pArray == NULL) {
×
827
    TAOS_RETURN(code = terrno);
×
828
  }
829
  *ppDnodeList = pArray;
×
830

831
  sdbTraverse(pSdb, SDB_DNODE, mndResetDnodesArrayFp, NULL, NULL, NULL);
×
832
  sdbTraverse(pSdb, SDB_DNODE, mndBuildDnodesListFp, pArray, NULL, NULL);
×
833

834
  int32_t arrSize = taosArrayGetSize(pArray);
×
835
  if (arrSize <= 0) {
×
836
    TAOS_RETURN(code);
×
837
  }
838
  if (arrSize > 1) taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes1);
×
839

840
  int32_t dnodeListSize = taosArrayGetSize(dnodeList);
×
841
  if (dnodeListSize <= 0) {
×
842
    if (arrSize > 2) taosArrayRemoveBatch(pArray, 2, arrSize - 2, NULL);
×
843
  } else {
844
    int32_t nDnodesWithVnodes = 0;
×
845
    for (int32_t i = 0; i < arrSize; ++i) {
×
846
      SDnodeObj *pDnode = TARRAY_GET_ELEM(pArray, i);
×
847
      if (pDnode->numOfVnodes <= 0) {
×
848
        break;
×
849
      }
850
      ++nDnodesWithVnodes;
×
851
    }
852
    int32_t dnodeId = -1;
×
853
    if (nDnodesWithVnodes == 1) {
×
854
      dnodeId = ((SDnodeObj *)TARRAY_GET_ELEM(pArray, 0))->id;
×
855
    } else if (nDnodesWithVnodes >= 2) {
×
856
      // must select the dnodes from the 1st 2 dnodes
857
      taosArrayRemoveBatch(pArray, 2, arrSize - 2, NULL);
×
858
    }
859
    for (int32_t i = 0; i < TARRAY_SIZE(pArray);) {
×
860
      SDnodeObj *pDnode = taosArrayGet(pArray, i);
×
861
      if (!isDnodeInList(dnodeList, pDnode->id)) {
×
862
        taosArrayRemove(pArray, i);
×
863
        continue;
×
864
      }
865
      ++i;
×
866
    }
867
    if (nDnodesWithVnodes == 1) {
×
868
      SDnodeObj *pDnode = taosArrayGet(pArray, 0);
×
869
      if (pDnode && (pDnode->id != dnodeId)) {  // the first dnode is not in dnodeList, remove the last element
×
870
        taosArrayRemove(pArray, taosArrayGetSize(pArray) - 1);
×
871
      }
872
    }
873
  }
874

875
  TAOS_RETURN(code);
×
876
}
877
#endif
878

879
SArray *mndBuildDnodesArray(SMnode *pMnode, int32_t exceptDnodeId, SArray *dnodeList) {
4,047,714✔
880
  SSdb   *pSdb = pMnode->pSdb;
4,047,714✔
881
  int32_t numOfDnodes = mndGetDnodeSize(pMnode);
4,047,714✔
882
  SArray *tDnodeList = NULL;
4,047,714✔
883
  SArray *pDnodeList = NULL;
4,047,714✔
884

885
  SArray *pArray = taosArrayInit(numOfDnodes, sizeof(SDnodeObj));
4,047,714✔
886
  if (pArray == NULL) {
4,047,714!
887
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
888
    return NULL;
×
889
  }
890
  if (taosArrayGetSize(dnodeList) > 0) {
4,047,714✔
891
    tDnodeList = dnodeList;
30,248✔
892
  }
893
#ifdef TD_ENTERPRISE
894
  if (0 != mndBuildNodesCheckDualReplica(pMnode, numOfDnodes, tDnodeList, &pDnodeList)) {
4,047,714!
895
    taosArrayDestroy(pArray);
×
896
    return NULL;
×
897
  }
898
#endif
899
  sdbTraverse(pSdb, SDB_DNODE, mndResetDnodesArrayFp, NULL, NULL, NULL);
4,047,714✔
900
  sdbTraverse(pSdb, SDB_DNODE, mndBuildDnodesArrayFp, pArray, &exceptDnodeId, pDnodeList ? pDnodeList : tDnodeList);
4,047,714!
901

902
  mDebug("build %d dnodes array", (int32_t)taosArrayGetSize(pArray));
4,047,714✔
903
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
9,576,698✔
904
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
5,528,984✔
905
    mDebug("dnode:%d, vnodes:%d others:%d", pDnode->id, pDnode->numOfVnodes, pDnode->numOfOtherNodes);
5,528,984✔
906
  }
907
  taosArrayDestroy(pDnodeList);
4,047,714✔
908
  return pArray;
4,047,714✔
909
}
910

911
static int32_t mndCompareDnodeId(int32_t *dnode1Id, int32_t *dnode2Id) {
×
912
  if (*dnode1Id == *dnode2Id) {
×
913
    return 0;
×
914
  }
915
  return *dnode1Id > *dnode2Id ? 1 : -1;
×
916
}
917

918
static float mndGetDnodeScore(SDnodeObj *pDnode, int32_t additionDnodes, float ratio) {
30,112,938✔
919
  float totalDnodes = pDnode->numOfVnodes + (float)pDnode->numOfOtherNodes * ratio + additionDnodes;
30,112,938✔
920
  return totalDnodes / pDnode->numOfSupportVnodes;
30,112,938!
921
}
922

923
static int32_t mndCompareDnodeVnodes(SDnodeObj *pDnode1, SDnodeObj *pDnode2) {
9,505,106✔
924
  float d1Score = mndGetDnodeScore(pDnode1, 0, 0.9);
9,505,106✔
925
  float d2Score = mndGetDnodeScore(pDnode2, 0, 0.9);
9,505,106✔
926
  if (d1Score == d2Score) {
9,505,106✔
927
    return 0;
3,607,101✔
928
  }
929
  return d1Score > d2Score ? 1 : -1;
5,898,005✔
930
}
931

932
void mndSortVnodeGid(SVgObj *pVgroup) {
8,029,332✔
933
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
17,181,011✔
934
    for (int32_t j = 0; j < pVgroup->replica - 1 - i; ++j) {
10,826,837✔
935
      if (pVgroup->vnodeGid[j].dnodeId > pVgroup->vnodeGid[j + 1].dnodeId) {
1,675,158✔
936
        TSWAP(pVgroup->vnodeGid[j], pVgroup->vnodeGid[j + 1]);
643,325!
937
      }
938
    }
939
  }
940
}
8,029,332✔
941

942
static int32_t mndGetAvailableDnode(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, SArray *pArray) {
7,939,003✔
943
  mDebug("start to sort %d dnodes", (int32_t)taosArrayGetSize(pArray));
7,939,003✔
944
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
7,939,003✔
945
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
19,006,111✔
946
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
11,067,108✔
947
    mDebug("dnode:%d, score:%f", pDnode->id, mndGetDnodeScore(pDnode, 0, 0.9));
11,067,108✔
948
  }
949

950
  int32_t size = taosArrayGetSize(pArray);
7,939,003✔
951
  if (size < pVgroup->replica) {
7,939,003✔
952
    mError("db:%s, vgId:%d, no enough online dnodes:%d to alloc %d replica", pVgroup->dbName, pVgroup->vgId, size,
11,941!
953
           pVgroup->replica);
954
    TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
11,941✔
955
  }
956

957
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
16,794,525✔
958
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
8,867,463✔
959
    SDnodeObj *pDnode = taosArrayGet(pArray, v);
8,867,463✔
960
    if (pDnode == NULL) {
8,867,463!
961
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
×
962
    }
963
    if (pDnode->numOfVnodes >= pDnode->numOfSupportVnodes) {
8,867,463!
964
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_VNODES);
×
965
    }
966

967
    int64_t vgMem = mndGetVgroupMemory(pMnode, pDb, pVgroup);
8,867,463✔
968
    if (pDnode->memAvail - vgMem - pDnode->memUsed <= 0) {
8,867,463!
969
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d, avail:%" PRId64 " used:%" PRId64,
×
970
             pVgroup->dbName, pVgroup->vgId, vgMem, pDnode->id, pDnode->memAvail, pDnode->memUsed);
971
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
972
    } else {
973
      pDnode->memUsed += vgMem;
8,867,463✔
974
    }
975

976
    pVgid->dnodeId = pDnode->id;
8,867,463✔
977
    if (pVgroup->replica == 1) {
8,867,463✔
978
      pVgid->syncState = TAOS_SYNC_STATE_LEADER;
7,450,089✔
979
    } else {
980
      pVgid->syncState = TAOS_SYNC_STATE_FOLLOWER;
1,417,374✔
981
    }
982

983
    mInfo("db:%s, vgId:%d, vn:%d is alloced, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
8,867,463!
984
          pVgroup->dbName, pVgroup->vgId, v, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
985
    pDnode->numOfVnodes++;
8,867,463✔
986
  }
987

988
  mndSortVnodeGid(pVgroup);
7,927,062✔
989
  return 0;
7,927,062✔
990
}
991

992
int32_t mndAllocSmaVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup) {
×
993
  int32_t code = 0;
×
994
  SArray *pArray = mndBuildDnodesArray(pMnode, 0, NULL);
×
995
  if (pArray == NULL) {
×
996
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
997
    if (terrno != 0) code = terrno;
×
998
    TAOS_RETURN(code);
×
999
  }
1000

1001
  pVgroup->vgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
×
1002
  pVgroup->isTsma = 1;
×
1003
  pVgroup->createdTime = taosGetTimestampMs();
×
1004
  pVgroup->updateTime = pVgroup->createdTime;
×
1005
  pVgroup->version = 1;
×
1006
  memcpy(pVgroup->dbName, pDb->name, TSDB_DB_FNAME_LEN);
×
1007
  pVgroup->dbUid = pDb->uid;
×
1008
  pVgroup->replica = 1;
×
1009

1010
  if (mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray) != 0) return -1;
×
1011
  taosArrayDestroy(pArray);
×
1012

1013
  mInfo("db:%s, sma vgId:%d is alloced", pDb->name, pVgroup->vgId);
×
1014
  return 0;
×
1015
}
1016

1017
int32_t mndAllocVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj **ppVgroups, SArray *dnodeList) {
3,751,438✔
1018
  int32_t code = -1;
3,751,438✔
1019
  SArray *pArray = NULL;
3,751,438✔
1020
  SVgObj *pVgroups = NULL;
3,751,438✔
1021

1022
  pVgroups = taosMemoryCalloc(pDb->cfg.numOfVgroups, sizeof(SVgObj));
3,751,438!
1023
  if (pVgroups == NULL) {
3,751,438!
1024
    code = terrno;
×
1025
    goto _OVER;
×
1026
  }
1027

1028
  pArray = mndBuildDnodesArray(pMnode, 0, dnodeList);
3,751,438✔
1029
  if (pArray == NULL) {
3,751,438!
1030
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1031
    if (terrno != 0) code = terrno;
×
1032
    goto _OVER;
×
1033
  }
1034

1035
  mInfo("db:%s, total %d dnodes used to create %d vgroups (%d vnodes)", pDb->name, (int32_t)taosArrayGetSize(pArray),
3,751,438!
1036
        pDb->cfg.numOfVgroups, pDb->cfg.numOfVgroups * pDb->cfg.replications);
1037

1038
  int32_t  allocedVgroups = 0;
3,751,438✔
1039
  int32_t  maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
3,751,438✔
1040
  uint32_t hashMin = 0;
3,751,438✔
1041
  uint32_t hashMax = UINT32_MAX;
3,751,438✔
1042
  uint32_t hashInterval = (hashMax - hashMin) / pDb->cfg.numOfVgroups;
3,751,438!
1043

1044
  if (maxVgId < 2) maxVgId = 2;
3,751,438✔
1045

1046
  for (uint32_t v = 0; v < pDb->cfg.numOfVgroups; v++) {
11,678,500✔
1047
    SVgObj *pVgroup = &pVgroups[v];
7,939,003✔
1048
    pVgroup->vgId = maxVgId++;
7,939,003✔
1049
    pVgroup->createdTime = taosGetTimestampMs();
7,939,003✔
1050
    pVgroup->updateTime = pVgroups->createdTime;
7,939,003✔
1051
    pVgroup->version = 1;
7,939,003✔
1052
    pVgroup->hashBegin = hashMin + hashInterval * v;
7,939,003✔
1053
    if (v == pDb->cfg.numOfVgroups - 1) {
7,939,003✔
1054
      pVgroup->hashEnd = hashMax;
3,745,483✔
1055
    } else {
1056
      pVgroup->hashEnd = hashMin + hashInterval * (v + 1) - 1;
4,193,520✔
1057
    }
1058

1059
    memcpy(pVgroup->dbName, pDb->name, TSDB_DB_FNAME_LEN);
7,939,003!
1060
    pVgroup->dbUid = pDb->uid;
7,939,003✔
1061
    pVgroup->replica = pDb->cfg.replications;
7,939,003✔
1062

1063
    if ((code = mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray)) != 0) {
7,939,003✔
1064
      goto _OVER;
11,941✔
1065
    }
1066

1067
    allocedVgroups++;
7,927,062✔
1068
  }
1069

1070
  *ppVgroups = pVgroups;
3,739,497✔
1071
  code = 0;
3,739,497✔
1072

1073
  mInfo("db:%s, total %d vgroups is alloced, replica:%d", pDb->name, pDb->cfg.numOfVgroups, pDb->cfg.replications);
3,739,497!
1074

1075
_OVER:
×
1076
  if (code != 0) taosMemoryFree(pVgroups);
3,751,438!
1077
  taosArrayDestroy(pArray);
3,751,438✔
1078
  TAOS_RETURN(code);
3,751,438✔
1079
}
1080

1081
SEpSet mndGetVgroupEpset(SMnode *pMnode, const SVgObj *pVgroup) {
93,971,025✔
1082
  SEpSet epset = {0};
93,971,025✔
1083

1084
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
210,436,899✔
1085
    const SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
116,465,874✔
1086
    SDnodeObj       *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
116,465,874✔
1087
    if (pDnode == NULL) continue;
116,465,874✔
1088

1089
    if (pVgid->syncState == TAOS_SYNC_STATE_LEADER || pVgid->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
116,423,939!
1090
      epset.inUse = epset.numOfEps;
92,873,611✔
1091
    }
1092

1093
    if (addEpIntoEpSet(&epset, pDnode->fqdn, pDnode->port) != 0) {
116,423,939!
1094
      mWarn("vgId:%d, failed to add ep:%s:%d into epset", pVgroup->vgId, pDnode->fqdn, pDnode->port);
×
1095
    }
1096
    mndReleaseDnode(pMnode, pDnode);
116,423,939✔
1097
  }
1098
  epsetSort(&epset);
93,971,025✔
1099

1100
  return epset;
93,971,025✔
1101
}
1102

1103
SEpSet mndGetVgroupEpsetById(SMnode *pMnode, int32_t vgId) {
1,063,147✔
1104
  SEpSet epset = {0};
1,063,147✔
1105

1106
  SVgObj *pVgroup = mndAcquireVgroup(pMnode, vgId);
1,063,147✔
1107
  if (!pVgroup) return epset;
1,063,147!
1108

1109
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
2,223,444✔
1110
    const SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
1,160,297✔
1111
    SDnodeObj       *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
1,160,297✔
1112
    if (pDnode == NULL) continue;
1,160,297!
1113

1114
    if (pVgid->syncState == TAOS_SYNC_STATE_LEADER || pVgid->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
1,160,297!
1115
      epset.inUse = epset.numOfEps;
1,043,234✔
1116
    }
1117

1118
    if (addEpIntoEpSet(&epset, pDnode->fqdn, pDnode->port) != 0) {
1,160,297!
1119
      mWarn("vgId:%d, failed to add ep:%s:%d into epset", pVgroup->vgId, pDnode->fqdn, pDnode->port);
×
1120
    }
1121
    mndReleaseDnode(pMnode, pDnode);
1,160,297✔
1122
  }
1123

1124
  mndReleaseVgroup(pMnode, pVgroup);
1,063,147✔
1125
  return epset;
1,063,147✔
1126
}
1127

1128
static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
741,833✔
1129
  SMnode *pMnode = pReq->info.node;
741,833✔
1130
  SSdb   *pSdb = pMnode->pSdb;
741,833✔
1131
  int32_t numOfRows = 0;
741,833✔
1132
  SVgObj *pVgroup = NULL;
741,833✔
1133
  int32_t cols = 0;
741,833✔
1134
  int64_t curMs = taosGetTimestampMs();
741,833✔
1135
  int32_t code = 0, lino = 0;
741,833✔
1136

1137
  SDbObj *pDb = NULL;
741,833✔
1138
  if (strlen(pShow->db) > 0) {
741,833✔
1139
    pDb = mndAcquireDb(pMnode, pShow->db);
623,925✔
1140
    if (pDb == NULL) {
623,925!
1141
      return 0;
×
1142
    }
1143
  }
1144

1145
  while (numOfRows < rows) {
3,789,697!
1146
    pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
3,789,697✔
1147
    if (pShow->pIter == NULL) break;
3,789,697✔
1148

1149
    if (pDb != NULL && pVgroup->dbUid != pDb->uid) {
3,047,864✔
1150
      sdbRelease(pSdb, pVgroup);
1,039,006✔
1151
      continue;
1,039,006✔
1152
    }
1153

1154
    cols = 0;
2,008,858✔
1155
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,008,858✔
1156
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->vgId, false, pVgroup, pShow->pIter, _OVER);
2,008,858!
1157

1158
    SName name = {0};
2,008,858✔
1159
    char  db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
2,008,858✔
1160
    code = tNameFromString(&name, pVgroup->dbName, T_NAME_ACCT | T_NAME_DB);
2,008,858✔
1161
    if (code != 0) {
2,008,858!
1162
      mError("vgId:%d, failed to set dbName, since %s", pVgroup->vgId, tstrerror(code));
×
1163
      sdbRelease(pSdb, pVgroup);
×
1164
      sdbCancelFetch(pSdb, pShow->pIter);
×
1165
      return code;
×
1166
    }
1167
    (void)tNameGetDbName(&name, varDataVal(db));
2,008,858✔
1168
    varDataSetLen(db, strlen(varDataVal(db)));
2,008,858!
1169

1170
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,008,858✔
1171
    COL_DATA_SET_VAL_GOTO((const char *)db, false, pVgroup, pShow->pIter, _OVER);
2,008,858!
1172

1173
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,008,858✔
1174
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->numOfTables, false, pVgroup, pShow->pIter, _OVER);
2,008,858!
1175

1176
    // default 3 replica, add 1 replica if move vnode
1177
    for (int32_t i = 0; i < 4; ++i) {
10,044,290✔
1178
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8,035,432✔
1179
      if (i < pVgroup->replica) {
8,035,432✔
1180
        int16_t dnodeId = (int16_t)pVgroup->vnodeGid[i].dnodeId;
4,134,312✔
1181
        COL_DATA_SET_VAL_GOTO((const char *)&dnodeId, false, pVgroup, pShow->pIter, _OVER);
4,134,312!
1182

1183
        bool       exist = false;
4,134,312✔
1184
        bool       online = false;
4,134,312✔
1185
        SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId);
4,134,312✔
1186
        if (pDnode != NULL) {
4,134,312!
1187
          exist = true;
4,134,312✔
1188
          online = mndIsDnodeOnline(pDnode, curMs);
4,134,312✔
1189
          mndReleaseDnode(pMnode, pDnode);
4,134,312✔
1190
        }
1191

1192
        char buf1[20] = {0};
4,134,312✔
1193
        char role[20] = "offline";
4,134,312✔
1194
        if (!exist) {
4,134,312!
1195
          tstrncpy(role, "dropping", sizeof(role));
×
1196
        } else if (online) {
4,134,312✔
1197
          char *star = "";
4,042,724✔
1198
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER ||
4,042,724✔
1199
              pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
2,523,096!
1200
            if (!pVgroup->vnodeGid[i].syncRestore && !pVgroup->vnodeGid[i].syncCanRead) {
1,519,628!
1201
              star = "**";
275,354✔
1202
            } else if (!pVgroup->vnodeGid[i].syncRestore && pVgroup->vnodeGid[i].syncCanRead) {
1,244,274!
1203
              star = "*";
×
1204
            } else {
1205
            }
1206
          }
1207
          snprintf(role, sizeof(role), "%s%s", syncStr(pVgroup->vnodeGid[i].syncState), star);
4,042,724✔
1208
          /*
1209
          mInfo("db:%s, learner progress:%d", pDb->name, pVgroup->vnodeGid[i].learnerProgress);
1210

1211
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEARNER) {
1212
            if(pVgroup->vnodeGid[i].learnerProgress < 0){
1213
              snprintf(role, sizeof(role), "%s-",
1214
                syncStr(pVgroup->vnodeGid[i].syncState));
1215

1216
            }
1217
            else if(pVgroup->vnodeGid[i].learnerProgress >= 100){
1218
              snprintf(role, sizeof(role), "%s--",
1219
                syncStr(pVgroup->vnodeGid[i].syncState));
1220
            }
1221
            else{
1222
              snprintf(role, sizeof(role), "%s%d",
1223
                syncStr(pVgroup->vnodeGid[i].syncState), pVgroup->vnodeGid[i].learnerProgress);
1224
            }
1225
          }
1226
          else{
1227
            snprintf(role, sizeof(role), "%s%s", syncStr(pVgroup->vnodeGid[i].syncState), star);
1228
          }
1229
          */
1230
        } else {
1231
        }
1232
        STR_WITH_MAXSIZE_TO_VARSTR(buf1, role, pShow->pMeta->pSchemas[cols].bytes);
4,134,312!
1233

1234
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,134,312✔
1235
        COL_DATA_SET_VAL_GOTO((const char *)buf1, false, pVgroup, pShow->pIter, _OVER);
4,134,312!
1236

1237
        char applyStr[TSDB_SYNC_APPLY_COMMIT_LEN + 1] = {0};
4,134,312✔
1238
        char buf[TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE + 1] = {0};
4,134,312✔
1239
        snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64, pVgroup->vnodeGid[i].syncAppliedIndex,
4,134,312✔
1240
                 pVgroup->vnodeGid[i].syncCommitIndex);
4,134,312✔
1241
        STR_WITH_MAXSIZE_TO_VARSTR(buf, applyStr, pShow->pMeta->pSchemas[cols].bytes);
4,134,312!
1242

1243
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,134,312✔
1244
        COL_DATA_SET_VAL_GOTO((const char *)&buf, false, pVgroup, pShow->pIter, _OVER);
4,134,312!
1245
      } else {
1246
        colDataSetNULL(pColInfo, numOfRows);
3,901,120!
1247
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,901,120✔
1248
        colDataSetNULL(pColInfo, numOfRows);
3,901,120!
1249
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,901,120✔
1250
        colDataSetNULL(pColInfo, numOfRows);
3,901,120!
1251
      }
1252
    }
1253

1254
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,008,858✔
1255
    int32_t cacheUsage = (int32_t)pVgroup->cacheUsage;
2,008,858✔
1256
    COL_DATA_SET_VAL_GOTO((const char *)&cacheUsage, false, pVgroup, pShow->pIter, _OVER);
2,008,858!
1257

1258
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,008,858✔
1259
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->numOfCachedTables, false, pVgroup, pShow->pIter, _OVER);
2,008,858!
1260

1261
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,008,858✔
1262
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->isTsma, false, pVgroup, pShow->pIter, _OVER);
2,008,858!
1263

1264
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,008,858✔
1265
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->mountVgId, false, pVgroup, pShow->pIter, _OVER);
2,008,858!
1266

1267
    numOfRows++;
2,008,858✔
1268
    sdbRelease(pSdb, pVgroup);
2,008,858✔
1269
  }
1270
_OVER:
741,833✔
1271
  if (pDb != NULL) {
741,833✔
1272
    mndReleaseDb(pMnode, pDb);
623,925✔
1273
  }
1274
  if (code != 0) {
741,833!
1275
    mError("failed to retrieve vgroup info at line %d since %s", lino, tstrerror(code));
×
1276
    TAOS_RETURN(code);
×
1277
  }
1278

1279
  pShow->numOfRows += numOfRows;
741,833✔
1280
  return numOfRows;
741,833✔
1281
}
1282

1283
static void mndCancelGetNextVgroup(SMnode *pMnode, void *pIter) {
×
1284
  SSdb *pSdb = pMnode->pSdb;
×
1285
  sdbCancelFetchByType(pSdb, pIter, SDB_VGROUP);
×
1286
}
×
1287

1288
static bool mndGetVnodesNumFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
30,146,067✔
1289
  SVgObj  *pVgroup = pObj;
30,146,067✔
1290
  int32_t  dnodeId = *(int32_t *)p1;
30,146,067✔
1291
  int32_t *pNumOfVnodes = (int32_t *)p2;
30,146,067✔
1292

1293
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
86,816,870✔
1294
    if (pVgroup->vnodeGid[v].dnodeId == dnodeId) {
56,670,803✔
1295
      (*pNumOfVnodes)++;
17,389,913✔
1296
    }
1297
  }
1298

1299
  return true;
30,146,067✔
1300
}
1301

1302
int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId) {
12,502,310✔
1303
  int32_t numOfVnodes = 0;
12,502,310✔
1304
  sdbTraverse(pMnode->pSdb, SDB_VGROUP, mndGetVnodesNumFp, &dnodeId, &numOfVnodes, NULL);
12,502,310✔
1305
  return numOfVnodes;
12,502,310✔
1306
}
1307

1308
int64_t mndGetVgroupMemory(SMnode *pMnode, SDbObj *pDbInput, SVgObj *pVgroup) {
20,580,104✔
1309
  SDbObj *pDb = pDbInput;
20,580,104✔
1310
  if (pDbInput == NULL) {
20,580,104✔
1311
    pDb = mndAcquireDb(pMnode, pVgroup->dbName);
10,157,373✔
1312
  }
1313

1314
  int64_t vgroupMemroy = 0;
20,580,104✔
1315
  if (pDb != NULL) {
20,580,104!
1316
    int64_t buffer = (int64_t)pDb->cfg.buffer * 1024 * 1024;
20,580,104✔
1317
    int64_t cache = (int64_t)pDb->cfg.pages * pDb->cfg.pageSize * 1024;
20,580,104✔
1318
    vgroupMemroy = buffer + cache;
20,580,104✔
1319
    int64_t cacheLast = (int64_t)pDb->cfg.cacheLastSize * 1024 * 1024;
20,580,104✔
1320
    if (pDb->cfg.cacheLast > 0) {
20,580,104✔
1321
      vgroupMemroy += cacheLast;
2,427,669✔
1322
    }
1323
    mDebug("db:%s, vgroup:%d, buffer:%" PRId64 " cache:%" PRId64 " cacheLast:%" PRId64, pDb->name, pVgroup->vgId,
20,580,104✔
1324
           buffer, cache, cacheLast);
1325
  }
1326

1327
  if (pDbInput == NULL) {
20,580,104✔
1328
    mndReleaseDb(pMnode, pDb);
10,157,373✔
1329
  }
1330
  return vgroupMemroy;
20,580,104✔
1331
}
1332

1333
static bool mndGetVnodeMemroyFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
13,454,834✔
1334
  SVgObj  *pVgroup = pObj;
13,454,834✔
1335
  int32_t  dnodeId = *(int32_t *)p1;
13,454,834✔
1336
  int64_t *pVnodeMemory = (int64_t *)p2;
13,454,834✔
1337

1338
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
34,229,382✔
1339
    if (pVgroup->vnodeGid[v].dnodeId == dnodeId) {
20,774,548✔
1340
      *pVnodeMemory += mndGetVgroupMemory(pMnode, NULL, pVgroup);
9,743,563✔
1341
    }
1342
  }
1343

1344
  return true;
13,454,834✔
1345
}
1346

1347
int64_t mndGetVnodesMemory(SMnode *pMnode, int32_t dnodeId) {
5,657,187✔
1348
  int64_t vnodeMemory = 0;
5,657,187✔
1349
  sdbTraverse(pMnode->pSdb, SDB_VGROUP, mndGetVnodeMemroyFp, &dnodeId, &vnodeMemory, NULL);
5,657,187✔
1350
  return vnodeMemory;
5,657,187✔
1351
}
1352

1353
void calculateRstoreFinishTime(double rate, int64_t applyCount, char *restoreStr, size_t restoreStrSize) {
1,626✔
1354
  if (rate == 0) {
1,626!
1355
    snprintf(restoreStr, restoreStrSize, "0:0:0");
1,626!
1356
    return;
1,626✔
1357
  }
1358

1359
  int64_t costTime = applyCount / rate;
×
1360
  int64_t totalSeconds = costTime / 1000;
×
1361
  int64_t hours = totalSeconds / 3600;
×
1362
  totalSeconds %= 3600;
×
1363
  int64_t minutes = totalSeconds / 60;
×
1364
  int64_t seconds = totalSeconds % 60;
×
1365
  snprintf(restoreStr, restoreStrSize, "%" PRId64 ":%" PRId64 ":%" PRId64, hours, minutes, seconds);
×
1366
}
1367

1368
static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
42,024✔
1369
  SMnode *pMnode = pReq->info.node;
42,024✔
1370
  SSdb   *pSdb = pMnode->pSdb;
42,024✔
1371
  int32_t numOfRows = 0;
42,024✔
1372
  SVgObj *pVgroup = NULL;
42,024✔
1373
  int32_t cols = 0;
42,024✔
1374
  int64_t curMs = taosGetTimestampMs();
42,024✔
1375
  int32_t code = 0;
42,024✔
1376

1377
  while (numOfRows < rows - TSDB_MAX_REPLICA) {
122,040!
1378
    pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
122,040✔
1379
    if (pShow->pIter == NULL) break;
122,040✔
1380

1381
    for (int32_t i = 0; i < pVgroup->replica && numOfRows < rows; ++i) {
230,904!
1382
      SVnodeGid       *pGid = &pVgroup->vnodeGid[i];
150,888✔
1383
      SColumnInfoData *pColInfo = NULL;
150,888✔
1384
      cols = 0;
150,888✔
1385

1386
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1387
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->dnodeId, false);
150,888✔
1388
      if (code != 0) {
150,888!
1389
        mError("vgId:%d, failed to set dnodeId, since %s", pVgroup->vgId, tstrerror(code));
×
1390
        return code;
×
1391
      }
1392
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1393
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pVgroup->vgId, false);
150,888✔
1394
      if (code != 0) {
150,888!
1395
        mError("vgId:%d, failed to set vgId, since %s", pVgroup->vgId, tstrerror(code));
×
1396
        return code;
×
1397
      }
1398

1399
      // db_name
1400
      const char *dbname = mndGetDbStr(pVgroup->dbName);
150,888✔
1401
      char        b1[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
150,888✔
1402
      if (dbname != NULL) {
150,888!
1403
        STR_WITH_MAXSIZE_TO_VARSTR(b1, dbname, TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE);
150,888!
1404
      } else {
1405
        STR_WITH_MAXSIZE_TO_VARSTR(b1, "NULL", TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE);
×
1406
      }
1407
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1408
      code = colDataSetVal(pColInfo, numOfRows, (const char *)b1, false);
150,888✔
1409
      if (code != 0) {
150,888!
1410
        mError("vgId:%d, failed to set dbName, since %s", pVgroup->vgId, tstrerror(code));
×
1411
        return code;
×
1412
      }
1413

1414
      // dnode is online?
1415
      SDnodeObj *pDnode = mndAcquireDnode(pMnode, pGid->dnodeId);
150,888✔
1416
      if (pDnode == NULL) {
150,888!
1417
        mError("failed to acquire dnode. dnodeId:%d", pGid->dnodeId);
×
1418
        break;
×
1419
      }
1420
      bool isDnodeOnline = mndIsDnodeOnline(pDnode, curMs);
150,888✔
1421

1422
      char       buf[20] = {0};
150,888✔
1423
      ESyncState syncState = (isDnodeOnline) ? pGid->syncState : TAOS_SYNC_STATE_OFFLINE;
150,888✔
1424
      STR_TO_VARSTR(buf, syncStr(syncState));
150,888!
1425
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1426
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
150,888✔
1427
      if (code != 0) {
150,888!
1428
        mError("vgId:%d, failed to set syncState, since %s", pVgroup->vgId, tstrerror(code));
×
1429
        return code;
×
1430
      }
1431

1432
      int64_t roleTimeMs = (isDnodeOnline) ? pGid->roleTimeMs : 0;
150,888✔
1433
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1434
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&roleTimeMs, false);
150,888✔
1435
      if (code != 0) {
150,888!
1436
        mError("vgId:%d, failed to set roleTimeMs, since %s", pVgroup->vgId, tstrerror(code));
×
1437
        return code;
×
1438
      }
1439

1440
      int64_t startTimeMs = (isDnodeOnline) ? pGid->startTimeMs : 0;
150,888✔
1441
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1442
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&startTimeMs, false);
150,888✔
1443
      if (code != 0) {
150,888!
1444
        mError("vgId:%d, failed to set startTimeMs, since %s", pVgroup->vgId, tstrerror(code));
×
1445
        return code;
×
1446
      }
1447

1448
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1449
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->syncRestore, false);
150,888✔
1450
      if (code != 0) {
150,888!
1451
        mError("vgId:%d, failed to set syncRestore, since %s", pVgroup->vgId, tstrerror(code));
×
1452
        return code;
×
1453
      }
1454

1455
      int64_t unappliedCount = pGid->syncCommitIndex - pGid->syncAppliedIndex;
150,888✔
1456
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1457
      char restoreStr[20] = {0};
150,888✔
1458
      if (unappliedCount > 0) {
150,888✔
1459
        calculateRstoreFinishTime(pGid->appliedRate, unappliedCount, restoreStr, sizeof(restoreStr));
1,626✔
1460
      }
1461
      STR_TO_VARSTR(buf, restoreStr);
150,888!
1462
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&buf, false);
150,888✔
1463
      if (code != 0) {
150,888!
1464
        mError("vgId:%d, failed to set syncRestore finish time, since %s", pVgroup->vgId, tstrerror(code));
×
1465
        return code;
×
1466
      }
1467

1468
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1469
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&unappliedCount, false);
150,888✔
1470
      if (code != 0) {
150,888!
1471
        mError("vgId:%d, failed to set syncRestore, since %s", pVgroup->vgId, tstrerror(code));
×
1472
        return code;
×
1473
      }
1474

1475
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1476
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->bufferSegmentUsed, false);
150,888✔
1477
      if (code != 0) {
150,888!
1478
        mError("vgId:%d, failed to set buffer segment used, since %s", pVgroup->vgId, tstrerror(code));
×
1479
        return code;
×
1480
      }
1481

1482
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
150,888✔
1483
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->bufferSegmentSize, false);
150,888✔
1484
      if (code != 0) {
150,888!
1485
        mError("vgId:%d, failed to set buffer segment size, since %s", pVgroup->vgId, tstrerror(code));
×
1486
        return code;
×
1487
      }
1488

1489
      numOfRows++;
150,888✔
1490
      sdbRelease(pSdb, pDnode);
150,888✔
1491
    }
1492

1493
    sdbRelease(pSdb, pVgroup);
80,016✔
1494
  }
1495

1496
  pShow->numOfRows += numOfRows;
42,024✔
1497
  return numOfRows;
42,024✔
1498
}
1499

1500
static void mndCancelGetNextVnode(SMnode *pMnode, void *pIter) {
×
1501
  SSdb *pSdb = pMnode->pSdb;
×
1502
  sdbCancelFetchByType(pSdb, pIter, SDB_VGROUP);
×
1503
}
×
1504

1505
static int32_t mndAddVnodeToVgroup(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray) {
254,725✔
1506
  int32_t code = 0;
254,725✔
1507
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
254,725✔
1508
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
994,143✔
1509
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
739,418✔
1510
    mInfo("trans:%d, dnode:%d, equivalent vnodes:%d others:%d", pTrans->id, pDnode->id, pDnode->numOfVnodes,
739,418!
1511
          pDnode->numOfOtherNodes);
1512
  }
1513

1514
  SVnodeGid *pVgid = &pVgroup->vnodeGid[pVgroup->replica];
254,725✔
1515
  for (int32_t d = 0; d < taosArrayGetSize(pArray); ++d) {
326,164✔
1516
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
314,899✔
1517

1518
    bool used = false;
314,899✔
1519
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
733,155✔
1520
      if (pDnode->id == pVgroup->vnodeGid[vn].dnodeId) {
489,695✔
1521
        used = true;
71,439✔
1522
        break;
71,439✔
1523
      }
1524
    }
1525
    if (used) continue;
314,899✔
1526

1527
    if (pDnode == NULL) {
243,460!
1528
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
×
1529
    }
1530
    if (pDnode->numOfVnodes >= pDnode->numOfSupportVnodes) {
243,460!
1531
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_VNODES);
×
1532
    }
1533

1534
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
243,460✔
1535
    if (pDnode->memAvail - vgMem - pDnode->memUsed <= 0) {
243,460!
1536
      mError("trans:%d, db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
1537
             pTrans->id, pVgroup->dbName, pVgroup->vgId, vgMem, pDnode->id, pDnode->memAvail, pDnode->memUsed);
1538
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
1539
    } else {
1540
      pDnode->memUsed += vgMem;
243,460✔
1541
    }
1542

1543
    pVgid->dnodeId = pDnode->id;
243,460✔
1544
    pVgid->syncState = TAOS_SYNC_STATE_OFFLINE;
243,460✔
1545
    mInfo("trans:%id, db:%s, vgId:%d, vn:%d is added, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
243,460!
1546
          pTrans->id, pVgroup->dbName, pVgroup->vgId, pVgroup->replica, vgMem, pVgid->dnodeId, pDnode->memAvail,
1547
          pDnode->memUsed);
1548

1549
    pVgroup->replica++;
243,460✔
1550
    pDnode->numOfVnodes++;
243,460✔
1551

1552
    SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
243,460✔
1553
    if (pVgRaw == NULL) {
243,460!
1554
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1555
      if (terrno != 0) code = terrno;
×
1556
      TAOS_RETURN(code);
×
1557
    }
1558
    if ((code = mndTransAppendGroupRedolog(pTrans, pVgRaw, pVgroup->vgId)) != 0) {
243,460!
1559
      sdbFreeRaw(pVgRaw);
×
1560
      TAOS_RETURN(code);
×
1561
    }
1562
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
243,460✔
1563
    if (code != 0) {
243,460!
1564
      mError("trans:%d, vgId:%d, failed to set raw status since %s at line:%d", pTrans->id, pVgroup->vgId,
×
1565
             tstrerror(code), __LINE__);
1566
    }
1567
    TAOS_RETURN(code);
243,460✔
1568
  }
1569

1570
  code = TSDB_CODE_MND_NO_ENOUGH_DNODES;
11,265✔
1571
  mError("trans:%d, db:%s, failed to add vnode to vgId:%d since %s", pTrans->id, pVgroup->dbName, pVgroup->vgId,
11,265!
1572
         tstrerror(code));
1573
  TAOS_RETURN(code);
11,265✔
1574
}
1575

1576
static int32_t mndRemoveVnodeFromVgroup(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray,
48,262✔
1577
                                        SVnodeGid *pDelVgid) {
1578
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
48,262✔
1579
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
180,155✔
1580
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
131,893✔
1581
    mInfo("trans:%d, dnode:%d, equivalent vnodes:%d others:%d", pTrans->id, pDnode->id, pDnode->numOfVnodes,
131,893!
1582
          pDnode->numOfOtherNodes);
1583
  }
1584

1585
  int32_t code = -1;
48,262✔
1586
  for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
51,398!
1587
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
51,398✔
1588

1589
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
93,838✔
1590
      SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
90,702✔
1591
      if (pVgid->dnodeId == pDnode->id) {
90,702✔
1592
        int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
48,262✔
1593
        pDnode->memUsed -= vgMem;
48,262✔
1594
        mInfo("trans:%d, db:%s, vgId:%d, vn:%d is removed, memory:%" PRId64 ", dnode:%d avail:%" PRId64
48,262!
1595
              " used:%" PRId64,
1596
              pTrans->id, pVgroup->dbName, pVgroup->vgId, vn, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
1597
        pDnode->numOfVnodes--;
48,262✔
1598
        pVgroup->replica--;
48,262✔
1599
        *pDelVgid = *pVgid;
48,262✔
1600
        *pVgid = pVgroup->vnodeGid[pVgroup->replica];
48,262✔
1601
        memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
48,262!
1602
        code = 0;
48,262✔
1603
        goto _OVER;
48,262✔
1604
      }
1605
    }
1606
  }
1607

1608
_OVER:
×
1609
  if (code != 0) {
48,262!
1610
    code = TSDB_CODE_APP_ERROR;
×
1611
    mError("trans:%d, db:%s, failed to remove vnode from vgId:%d since %s", pTrans->id, pVgroup->dbName, pVgroup->vgId,
×
1612
           tstrerror(code));
1613
    TAOS_RETURN(code);
×
1614
  }
1615

1616
  for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
135,079✔
1617
    SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
86,817✔
1618
    mInfo("trans:%d, db:%s, vgId:%d, vn:%d dnode:%d is reserved", pTrans->id, pVgroup->dbName, pVgroup->vgId, vn,
86,817!
1619
          pVgid->dnodeId);
1620
  }
1621

1622
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
48,262✔
1623
  if (pVgRaw == NULL) {
48,262!
1624
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1625
    if (terrno != 0) code = terrno;
×
1626
    TAOS_RETURN(code);
×
1627
  }
1628
  if (mndTransAppendGroupRedolog(pTrans, pVgRaw, pVgroup->vgId) != 0) {
48,262!
1629
    sdbFreeRaw(pVgRaw);
×
1630
    TAOS_RETURN(code);
×
1631
  }
1632
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
48,262✔
1633
  if (code != 0) {
48,262!
1634
    mError("trans:%d, vgId:%d, failed to set raw status since %s at line:%d", pTrans->id, pVgroup->vgId,
×
1635
           tstrerror(code), __LINE__);
1636
  }
1637

1638
  TAOS_RETURN(code);
48,262✔
1639
}
1640

1641
static int32_t mndRemoveVnodeFromVgroupWithoutSave(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray,
×
1642
                                                   SVnodeGid *pDelVgid) {
1643
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
×
1644
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
×
1645
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
×
1646
    mInfo("dnode:%d, equivalent vnodes:%d others:%d", pDnode->id, pDnode->numOfVnodes, pDnode->numOfOtherNodes);
×
1647
  }
1648

1649
  int32_t code = -1;
×
1650
  for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
×
1651
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
×
1652

1653
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
×
1654
      SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
×
1655
      if (pVgid->dnodeId == pDnode->id) {
×
1656
        int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
×
1657
        pDnode->memUsed -= vgMem;
×
1658
        mInfo("db:%s, vgId:%d, vn:%d is removed, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
×
1659
              pVgroup->dbName, pVgroup->vgId, vn, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
1660
        pDnode->numOfVnodes--;
×
1661
        pVgroup->replica--;
×
1662
        *pDelVgid = *pVgid;
×
1663
        *pVgid = pVgroup->vnodeGid[pVgroup->replica];
×
1664
        memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
×
1665
        code = 0;
×
1666
        goto _OVER;
×
1667
      }
1668
    }
1669
  }
1670

1671
_OVER:
×
1672
  if (code != 0) {
×
1673
    code = TSDB_CODE_APP_ERROR;
×
1674
    mError("db:%s, failed to remove vnode from vgId:%d since %s", pVgroup->dbName, pVgroup->vgId, tstrerror(code));
×
1675
    TAOS_RETURN(code);
×
1676
  }
1677

1678
  for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
×
1679
    SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
×
1680
    mInfo("db:%s, vgId:%d, vn:%d dnode:%d is reserved", pVgroup->dbName, pVgroup->vgId, vn, pVgid->dnodeId);
×
1681
  }
1682

1683
  TAOS_RETURN(code);
×
1684
}
1685

1686
int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid) {
9,266,239✔
1687
  int32_t      code = 0;
9,266,239✔
1688
  STransAction action = {0};
9,266,239✔
1689

1690
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
9,266,239✔
1691
  if (pDnode == NULL) return -1;
9,266,239!
1692
  action.epSet = mndGetDnodeEpset(pDnode);
9,266,239✔
1693
  mndReleaseDnode(pMnode, pDnode);
9,266,239✔
1694

1695
  int32_t contLen = 0;
9,266,239✔
1696
  void   *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
9,266,239✔
1697
  if (pReq == NULL) return -1;
9,266,239!
1698

1699
  action.pCont = pReq;
9,266,239✔
1700
  action.contLen = contLen;
9,266,239✔
1701
  action.msgType = TDMT_DND_CREATE_VNODE;
9,266,239✔
1702
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
9,266,239✔
1703
  action.groupId = pVgroup->vgId;
9,266,239✔
1704

1705
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
9,266,239!
1706
    taosMemoryFree(pReq);
×
1707
    TAOS_RETURN(code);
×
1708
  }
1709

1710
  TAOS_RETURN(code);
9,266,239✔
1711
}
1712

1713
int32_t mndRestoreAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
9,875✔
1714
                                       SDnodeObj *pDnode) {
1715
  int32_t      code = 0;
9,875✔
1716
  STransAction action = {0};
9,875✔
1717

1718
  action.epSet = mndGetDnodeEpset(pDnode);
9,875✔
1719

1720
  int32_t contLen = 0;
9,875✔
1721
  void   *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
9,875✔
1722
  if (pReq == NULL) {
9,875!
1723
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1724
    if (terrno != 0) code = terrno;
×
1725
    TAOS_RETURN(code);
×
1726
  }
1727

1728
  action.pCont = pReq;
9,875✔
1729
  action.contLen = contLen;
9,875✔
1730
  action.msgType = TDMT_DND_CREATE_VNODE;
9,875✔
1731
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
9,875✔
1732
  action.groupId = pVgroup->vgId;
9,875✔
1733

1734
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
9,875!
1735
    taosMemoryFree(pReq);
×
1736
    TAOS_RETURN(code);
×
1737
  }
1738

1739
  TAOS_RETURN(code);
9,875✔
1740
}
1741

1742
int32_t mndAddAlterVnodeConfirmAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
760,755✔
1743
  int32_t      code = 0;
760,755✔
1744
  STransAction action = {0};
760,755✔
1745
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
760,755✔
1746

1747
  mInfo("trans:%d, vgId:%d, build alter vnode confirm req", pTrans->id, pVgroup->vgId);
760,755!
1748
  int32_t   contLen = sizeof(SMsgHead);
760,755✔
1749
  SMsgHead *pHead = taosMemoryMalloc(contLen);
760,755!
1750
  if (pHead == NULL) {
760,755!
1751
    TAOS_RETURN(terrno);
×
1752
  }
1753

1754
  pHead->contLen = htonl(contLen);
760,755✔
1755
  pHead->vgId = htonl(pVgroup->vgId);
760,755✔
1756

1757
  action.pCont = pHead;
760,755✔
1758
  action.contLen = contLen;
760,755✔
1759
  action.msgType = TDMT_VND_ALTER_CONFIRM;
760,755✔
1760
  // incorrect redirect result will cause this erro
1761
  action.retryCode = TSDB_CODE_VND_INVALID_VGROUP_ID;
760,755✔
1762
  action.groupId = pVgroup->vgId;
760,755✔
1763

1764
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
760,755!
1765
    taosMemoryFree(pHead);
×
1766
    TAOS_RETURN(code);
×
1767
  }
1768

1769
  TAOS_RETURN(code);
760,755✔
1770
}
1771

1772
int32_t mndAddChangeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pOldVgroup, SVgObj *pNewVgroup,
×
1773
                                 int32_t dnodeId) {
1774
  int32_t      code = 0;
×
1775
  STransAction action = {0};
×
1776
  action.epSet = mndGetVgroupEpset(pMnode, pNewVgroup);
×
1777

1778
  int32_t contLen = 0;
×
1779
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pNewVgroup, dnodeId, &contLen);
×
1780
  if (pReq == NULL) {
×
1781
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1782
    if (terrno != 0) code = terrno;
×
1783
    TAOS_RETURN(code);
×
1784
  }
1785

1786
  int32_t totallen = contLen + sizeof(SMsgHead);
×
1787

1788
  SMsgHead *pHead = taosMemoryMalloc(totallen);
×
1789
  if (pHead == NULL) {
×
1790
    taosMemoryFree(pReq);
×
1791
    TAOS_RETURN(terrno);
×
1792
  }
1793

1794
  pHead->contLen = htonl(totallen);
×
1795
  pHead->vgId = htonl(pNewVgroup->vgId);
×
1796

1797
  memcpy((void *)(pHead + 1), pReq, contLen);
×
1798
  taosMemoryFree(pReq);
×
1799

1800
  action.pCont = pHead;
×
1801
  action.contLen = totallen;
×
1802
  action.msgType = TDMT_SYNC_CONFIG_CHANGE;
×
1803

1804
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
1805
    taosMemoryFree(pHead);
×
1806
    TAOS_RETURN(code);
×
1807
  }
1808

1809
  TAOS_RETURN(code);
×
1810
}
1811

1812
static int32_t mndAddAlterVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, int32_t srcVgId, SVgObj *pVgroup) {
82,290✔
1813
  int32_t      code = 0;
82,290✔
1814
  STransAction action = {0};
82,290✔
1815
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
82,290✔
1816

1817
  int32_t contLen = 0;
82,290✔
1818
  void   *pReq = mndBuildAlterVnodeHashRangeReq(pMnode, srcVgId, pVgroup, &contLen);
82,290✔
1819
  if (pReq == NULL) {
82,290!
1820
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1821
    if (terrno != 0) code = terrno;
×
1822
    TAOS_RETURN(code);
×
1823
  }
1824

1825
  action.pCont = pReq;
82,290✔
1826
  action.contLen = contLen;
82,290✔
1827
  action.msgType = TDMT_VND_ALTER_HASHRANGE;
82,290✔
1828
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
82,290✔
1829

1830
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
82,290!
1831
    taosMemoryFree(pReq);
×
1832
    TAOS_RETURN(code);
×
1833
  }
1834

1835
  mInfo("trans:%d, add alter vnode hash range action for from vgId:%d to vgId:%d", pTrans->id, srcVgId, pVgroup->vgId);
82,290!
1836
  TAOS_RETURN(code);
82,290✔
1837
}
1838

1839
int32_t mndAddAlterVnodeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
510,002✔
1840
  int32_t      code = 0;
510,002✔
1841
  STransAction action = {0};
510,002✔
1842
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
510,002✔
1843

1844
  int32_t contLen = 0;
510,002✔
1845
  void   *pReq = mndBuildAlterVnodeConfigReq(pMnode, pDb, pVgroup, &contLen);
510,002✔
1846
  if (pReq == NULL) {
510,002!
1847
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1848
    if (terrno != 0) code = terrno;
×
1849
    TAOS_RETURN(code);
×
1850
  }
1851

1852
  action.pCont = pReq;
510,002✔
1853
  action.contLen = contLen;
510,002✔
1854
  action.msgType = TDMT_VND_ALTER_CONFIG;
510,002✔
1855
  action.groupId = pVgroup->vgId;
510,002✔
1856

1857
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
510,002!
1858
    taosMemoryFree(pReq);
×
1859
    TAOS_RETURN(code);
×
1860
  }
1861

1862
  TAOS_RETURN(code);
510,002✔
1863
}
1864

1865
int32_t mndAddNewVgPrepareAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVg) {
8,016,968✔
1866
  int32_t  code = 0;
8,016,968✔
1867
  SSdbRaw *pRaw = mndVgroupActionEncode(pVg);
8,016,968✔
1868
  if (pRaw == NULL) {
8,016,968!
1869
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1870
    if (terrno != 0) code = terrno;
×
1871
    goto _err;
×
1872
  }
1873

1874
  TAOS_CHECK_GOTO(mndTransAppendPrepareLog(pTrans, pRaw), NULL, _err);
8,016,968!
1875
  if (sdbSetRawStatus(pRaw, SDB_STATUS_CREATING) != 0) {
8,016,968!
1876
    mError("vgId:%d, failed to set raw status at line:%d", pVg->vgId, __LINE__);
×
1877
  }
1878
  if (code != 0) {
8,016,968!
1879
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVg->vgId, tstrerror(code), __LINE__);
×
1880
    TAOS_RETURN(code);
×
1881
  }
1882
  pRaw = NULL;
8,016,968✔
1883
  TAOS_RETURN(code);
8,016,968✔
1884

1885
_err:
×
1886
  sdbFreeRaw(pRaw);
×
1887
  TAOS_RETURN(code);
×
1888
}
1889

1890
int32_t mndAddAlterVnodeReplicaAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
1,766,259✔
1891
  int32_t    code = 0;
1,766,259✔
1892
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
1,766,259✔
1893
  if (pDnode == NULL) {
1,766,259!
1894
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1895
    if (terrno != 0) code = terrno;
×
1896
    TAOS_RETURN(code);
×
1897
  }
1898

1899
  STransAction action = {0};
1,766,259✔
1900
  action.epSet = mndGetDnodeEpset(pDnode);
1,766,259✔
1901
  mndReleaseDnode(pMnode, pDnode);
1,766,259✔
1902

1903
  int32_t contLen = 0;
1,766,259✔
1904
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
1,766,259✔
1905
  if (pReq == NULL) {
1,766,259!
1906
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1907
    if (terrno != 0) code = terrno;
×
1908
    TAOS_RETURN(code);
×
1909
  }
1910

1911
  action.pCont = pReq;
1,766,259✔
1912
  action.contLen = contLen;
1,766,259✔
1913
  action.msgType = TDMT_VND_ALTER_REPLICA;
1,766,259✔
1914
  action.groupId = pVgroup->vgId;
1,766,259✔
1915

1916
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
1,766,259!
1917
    taosMemoryFree(pReq);
×
1918
    TAOS_RETURN(code);
×
1919
  }
1920

1921
  TAOS_RETURN(code);
1,766,259✔
1922
}
1923

1924
int32_t mndAddCheckLearnerCatchupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
×
1925
  int32_t    code = 0;
×
1926
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
×
1927
  if (pDnode == NULL) {
×
1928
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1929
    if (terrno != 0) code = terrno;
×
1930
    TAOS_RETURN(code);
×
1931
  }
1932

1933
  STransAction action = {0};
×
1934
  action.epSet = mndGetDnodeEpset(pDnode);
×
1935
  mndReleaseDnode(pMnode, pDnode);
×
1936

1937
  int32_t contLen = 0;
×
1938
  void   *pReq = mndBuildCheckLearnCatchupReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
×
1939
  if (pReq == NULL) {
×
1940
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1941
    if (terrno != 0) code = terrno;
×
1942
    TAOS_RETURN(code);
×
1943
  }
1944

1945
  action.pCont = pReq;
×
1946
  action.contLen = contLen;
×
1947
  action.msgType = TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP;
×
1948
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
×
1949
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
×
1950

1951
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
1952
    taosMemoryFree(pReq);
×
1953
    TAOS_RETURN(code);
×
1954
  }
1955

1956
  TAOS_RETURN(code);
×
1957
}
1958

1959
int32_t mndAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
267,460✔
1960
  int32_t    code = 0;
267,460✔
1961
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
267,460✔
1962
  if (pDnode == NULL) {
267,460!
1963
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1964
    if (terrno != 0) code = terrno;
×
1965
    TAOS_RETURN(code);
×
1966
  }
1967

1968
  STransAction action = {0};
267,460✔
1969
  action.epSet = mndGetDnodeEpset(pDnode);
267,460✔
1970
  mndReleaseDnode(pMnode, pDnode);
267,460✔
1971

1972
  int32_t contLen = 0;
267,460✔
1973
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
267,460✔
1974
  if (pReq == NULL) {
267,460!
1975
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1976
    if (terrno != 0) code = terrno;
×
1977
    TAOS_RETURN(code);
×
1978
  }
1979

1980
  action.pCont = pReq;
267,460✔
1981
  action.contLen = contLen;
267,460✔
1982
  action.msgType = TDMT_DND_ALTER_VNODE_TYPE;
267,460✔
1983
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
267,460✔
1984
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
267,460✔
1985
  action.groupId = pVgroup->vgId;
267,460✔
1986

1987
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
267,460!
1988
    taosMemoryFree(pReq);
×
1989
    TAOS_RETURN(code);
×
1990
  }
1991

1992
  TAOS_RETURN(code);
267,460✔
1993
}
1994

1995
int32_t mndRestoreAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
9,875✔
1996
                                          SDnodeObj *pDnode) {
1997
  int32_t      code = 0;
9,875✔
1998
  STransAction action = {0};
9,875✔
1999
  action.epSet = mndGetDnodeEpset(pDnode);
9,875✔
2000

2001
  int32_t contLen = 0;
9,875✔
2002
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, pDnode->id, &contLen);
9,875✔
2003
  if (pReq == NULL) {
9,875!
2004
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2005
    if (terrno != 0) code = terrno;
×
2006
    TAOS_RETURN(code);
×
2007
  }
2008

2009
  action.pCont = pReq;
9,875✔
2010
  action.contLen = contLen;
9,875✔
2011
  action.msgType = TDMT_DND_ALTER_VNODE_TYPE;
9,875✔
2012
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
9,875✔
2013
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
9,875✔
2014
  action.groupId = pVgroup->vgId;
9,875✔
2015

2016
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
9,875!
2017
    taosMemoryFree(pReq);
×
2018
    TAOS_RETURN(code);
×
2019
  }
2020

2021
  TAOS_RETURN(code);
9,875✔
2022
}
2023

2024
static int32_t mndAddDisableVnodeWriteAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
82,290✔
2025
                                             int32_t dnodeId) {
2026
  int32_t    code = 0;
82,290✔
2027
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
82,290✔
2028
  if (pDnode == NULL) {
82,290!
2029
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2030
    if (terrno != 0) code = terrno;
×
2031
    TAOS_RETURN(code);
×
2032
  }
2033

2034
  STransAction action = {0};
82,290✔
2035
  action.epSet = mndGetDnodeEpset(pDnode);
82,290✔
2036
  mndReleaseDnode(pMnode, pDnode);
82,290✔
2037

2038
  int32_t contLen = 0;
82,290✔
2039
  void   *pReq = mndBuildDisableVnodeWriteReq(pMnode, pDb, pVgroup->vgId, &contLen);
82,290✔
2040
  if (pReq == NULL) {
82,290!
2041
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2042
    if (terrno != 0) code = terrno;
×
2043
    TAOS_RETURN(code);
×
2044
  }
2045

2046
  action.pCont = pReq;
82,290✔
2047
  action.contLen = contLen;
82,290✔
2048
  action.msgType = TDMT_VND_DISABLE_WRITE;
82,290✔
2049

2050
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
82,290!
2051
    taosMemoryFree(pReq);
×
2052
    TAOS_RETURN(code);
×
2053
  }
2054

2055
  TAOS_RETURN(code);
82,290✔
2056
}
2057

2058
int32_t mndAddDropVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid,
12,989,171✔
2059
                              bool isRedo) {
2060
  int32_t      code = 0;
12,989,171✔
2061
  STransAction action = {0};
12,989,171✔
2062

2063
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
12,989,171✔
2064
  if (pDnode == NULL) {
12,989,171!
2065
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2066
    if (terrno != 0) code = terrno;
×
2067
    TAOS_RETURN(code);
×
2068
  }
2069
  action.epSet = mndGetDnodeEpset(pDnode);
12,989,171✔
2070
  mndReleaseDnode(pMnode, pDnode);
12,989,171✔
2071

2072
  int32_t contLen = 0;
12,989,171✔
2073
  void   *pReq = mndBuildDropVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
12,989,171✔
2074
  if (pReq == NULL) {
12,989,171!
2075
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2076
    if (terrno != 0) code = terrno;
×
2077
    TAOS_RETURN(code);
×
2078
  }
2079

2080
  action.pCont = pReq;
12,989,171✔
2081
  action.contLen = contLen;
12,989,171✔
2082
  action.msgType = TDMT_DND_DROP_VNODE;
12,989,171✔
2083
  action.acceptableCode = TSDB_CODE_VND_NOT_EXIST;
12,989,171✔
2084
  action.groupId = pVgroup->vgId;
12,989,171✔
2085

2086
  if (isRedo) {
12,989,171✔
2087
    if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
4,121,708!
2088
      taosMemoryFree(pReq);
×
2089
      TAOS_RETURN(code);
×
2090
    }
2091
  } else {
2092
    if ((code = mndTransAppendUndoAction(pTrans, &action)) != 0) {
8,867,463!
2093
      taosMemoryFree(pReq);
×
2094
      TAOS_RETURN(code);
×
2095
    }
2096
  }
2097

2098
  TAOS_RETURN(code);
12,989,171✔
2099
}
2100

2101
int32_t mndSetMoveVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t vnIndex,
41,933✔
2102
                                    SArray *pArray, bool force, bool unsafe) {
2103
  int32_t code = 0;
41,933✔
2104
  SVgObj  newVg = {0};
41,933✔
2105
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
41,933!
2106

2107
  mInfo("vgId:%d, trans:%d, vgroup info before move, replica:%d", newVg.vgId, pTrans->id, newVg.replica);
41,933!
2108
  for (int32_t i = 0; i < newVg.replica; ++i) {
135,810✔
2109
    mInfo("vgId:%d, trans:%d, vnode:%d dnode:%d", newVg.vgId, pTrans->id, i, newVg.vnodeGid[i].dnodeId);
93,877!
2110
  }
2111

2112
  if (!force) {
41,933!
2113
#if 1
2114
    {
2115
#else
2116
    if (newVg.replica == 1) {
2117
#endif
2118
      mInfo("vgId:%d, trans:%d, will add 1 vnode, replca:%d", pVgroup->vgId, pTrans->id, newVg.replica);
41,933!
2119
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray));
41,933!
2120
      for (int32_t i = 0; i < newVg.replica - 1; ++i) {
135,810✔
2121
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
93,877!
2122
      }
2123
      TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[newVg.replica - 1]));
41,933!
2124
      TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
41,933!
2125

2126
      mInfo("vgId:%d, trans:%d, will remove 1 vnode, replca:2", pVgroup->vgId, pTrans->id);
41,933!
2127
      newVg.replica--;
41,933✔
2128
      SVnodeGid del = newVg.vnodeGid[vnIndex];
41,933✔
2129
      newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
41,933✔
2130
      memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
41,933!
2131
      {
2132
        SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
41,933✔
2133
        if (pRaw == NULL) {
41,933!
2134
          code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2135
          if (terrno != 0) code = terrno;
×
2136
          TAOS_RETURN(code);
×
2137
        }
2138
        if ((code = mndTransAppendGroupRedolog(pTrans, pRaw, pVgroup->vgId)) != 0) {
41,933!
2139
          sdbFreeRaw(pRaw);
×
2140
          TAOS_RETURN(code);
×
2141
        }
2142
        code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
41,933✔
2143
        if (code != 0) {
41,933!
2144
          mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2145
          return code;
×
2146
        }
2147
      }
2148

2149
      TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg, &del, true));
41,933!
2150
      for (int32_t i = 0; i < newVg.replica; ++i) {
135,810✔
2151
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
93,877!
2152
      }
2153
      TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
41,933!
2154
#if 1
2155
    }
2156
#else
2157
    } else {  // new replica == 3
2158
      mInfo("vgId:%d, will add 1 vnode, replca:3", pVgroup->vgId);
2159
      if (mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray) != 0) return -1;
2160
      mInfo("vgId:%d, will remove 1 vnode, replca:4", pVgroup->vgId);
2161
      newVg.replica--;
2162
      SVnodeGid del = newVg.vnodeGid[vnIndex];
2163
      newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
2164
      memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
2165
      {
2166
        SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
2167
        if (pRaw == NULL) return -1;
2168
        if (mndTransAppendRedolog(pTrans, pRaw) != 0) {
2169
          sdbFreeRaw(pRaw);
2170
          return -1;
2171
        }
2172
      }
2173

2174
      if (mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg, &del, true) != 0) return -1;
2175
      for (int32_t i = 0; i < newVg.replica; ++i) {
2176
        if (i == vnIndex) continue;
2177
        if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId) != 0) return -1;
2178
      }
2179
      if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[vnIndex]) != 0) return -1;
2180
      if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg) != 0) return -1;
2181
    }
2182
#endif
2183
  } else {
2184
    mInfo("vgId:%d, will add 1 vnode and force remove 1 vnode", pVgroup->vgId);
×
2185
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray));
×
2186
    newVg.replica--;
×
2187
    // SVnodeGid del = newVg.vnodeGid[vnIndex];
2188
    newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
×
2189
    memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
×
2190
    {
2191
      SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
×
2192
      if (pRaw == NULL) {
×
2193
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2194
        if (terrno != 0) code = terrno;
×
2195
        TAOS_RETURN(code);
×
2196
      }
2197
      if ((code = mndTransAppendGroupRedolog(pTrans, pRaw, pVgroup->vgId)) != 0) {
×
2198
        sdbFreeRaw(pRaw);
×
2199
        TAOS_RETURN(code);
×
2200
      }
2201
      code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
×
2202
      if (code != 0) {
×
2203
        mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2204
        return code;
×
2205
      }
2206
    }
2207

2208
    for (int32_t i = 0; i < newVg.replica; ++i) {
×
2209
      if (i != vnIndex) {
×
2210
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
×
2211
      }
2212
    }
2213
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[vnIndex]));
×
2214
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
×
2215

2216
    if (newVg.replica == 1) {
×
2217
      if (force && !unsafe) {
×
2218
        TAOS_RETURN(TSDB_CODE_VND_META_DATA_UNSAFE_DELETE);
×
2219
      }
2220

2221
      SSdb *pSdb = pMnode->pSdb;
×
2222
      void *pIter = NULL;
×
2223

2224
      while (1) {
×
2225
        SStbObj *pStb = NULL;
×
2226
        pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
×
2227
        if (pIter == NULL) break;
×
2228

2229
        if (strcmp(pStb->db, pDb->name) == 0) {
×
2230
          if ((code = mndSetForceDropCreateStbRedoActions(pMnode, pTrans, &newVg, pStb)) != 0) {
×
2231
            sdbCancelFetch(pSdb, pIter);
×
2232
            sdbRelease(pSdb, pStb);
×
2233
            TAOS_RETURN(code);
×
2234
          }
2235
        }
2236

2237
        sdbRelease(pSdb, pStb);
×
2238
      }
2239

2240
      mInfo("vgId:%d, all data is dropped since replica=1", pVgroup->vgId);
×
2241
    }
2242
  }
2243

2244
  {
2245
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
41,933✔
2246
    if (pRaw == NULL) {
41,933!
2247
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2248
      if (terrno != 0) code = terrno;
×
2249
      TAOS_RETURN(code);
×
2250
    }
2251
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
41,933!
2252
      sdbFreeRaw(pRaw);
×
2253
      TAOS_RETURN(code);
×
2254
    }
2255
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
41,933✔
2256
    if (code != 0) {
41,933!
2257
      mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2258
      return code;
×
2259
    }
2260
  }
2261

2262
  mInfo("vgId:%d, vgroup info after move, replica:%d", newVg.vgId, newVg.replica);
41,933!
2263
  for (int32_t i = 0; i < newVg.replica; ++i) {
135,810✔
2264
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
93,877!
2265
  }
2266
  TAOS_RETURN(code);
41,933✔
2267
}
2268

2269
int32_t mndSetMoveVgroupsInfoToTrans(SMnode *pMnode, STrans *pTrans, int32_t delDnodeId, bool force, bool unsafe) {
20,412✔
2270
  int32_t code = 0;
20,412✔
2271
  SArray *pArray = mndBuildDnodesArray(pMnode, delDnodeId, NULL);
20,412✔
2272
  if (pArray == NULL) {
20,412!
2273
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2274
    if (terrno != 0) code = terrno;
×
2275
    TAOS_RETURN(code);
×
2276
  }
2277

2278
  void *pIter = NULL;
20,412✔
2279
  while (1) {
57,749✔
2280
    SVgObj *pVgroup = NULL;
78,161✔
2281
    pIter = sdbFetch(pMnode->pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
78,161✔
2282
    if (pIter == NULL) break;
78,161✔
2283

2284
    int32_t vnIndex = -1;
57,749✔
2285
    for (int32_t i = 0; i < pVgroup->replica; ++i) {
107,671✔
2286
      if (pVgroup->vnodeGid[i].dnodeId == delDnodeId) {
91,855✔
2287
        vnIndex = i;
41,933✔
2288
        break;
41,933✔
2289
      }
2290
    }
2291

2292
    code = 0;
57,749✔
2293
    if (vnIndex != -1) {
57,749✔
2294
      mInfo("vgId:%d, trans:%d, vnode:%d will be removed from dnode:%d, force:%d", pVgroup->vgId, pTrans->id, vnIndex,
41,933!
2295
            delDnodeId, force);
2296
      SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
41,933✔
2297
      code = mndSetMoveVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, vnIndex, pArray, force, unsafe);
41,933✔
2298
      mndReleaseDb(pMnode, pDb);
41,933✔
2299
    }
2300

2301
    sdbRelease(pMnode->pSdb, pVgroup);
57,749✔
2302

2303
    if (code != 0) {
57,749!
2304
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2305
      break;
×
2306
    }
2307
  }
2308

2309
  taosArrayDestroy(pArray);
20,412✔
2310
  TAOS_RETURN(code);
20,412✔
2311
}
2312

2313
static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
155,316✔
2314
                                             int32_t newDnodeId) {
2315
  int32_t code = 0;
155,316✔
2316
  mInfo("vgId:%d, will add 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, newDnodeId);
155,316!
2317

2318
  // assoc dnode
2319
  SVnodeGid *pGid = &pVgroup->vnodeGid[pVgroup->replica];
155,316✔
2320
  pVgroup->replica++;
155,316✔
2321
  pGid->dnodeId = newDnodeId;
155,316✔
2322
  pGid->syncState = TAOS_SYNC_STATE_OFFLINE;
155,316✔
2323
  pGid->nodeRole = TAOS_SYNC_ROLE_LEARNER;
155,316✔
2324

2325
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
155,316✔
2326
  if (pVgRaw == NULL) {
155,316!
2327
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2328
    if (terrno != 0) code = terrno;
×
2329
    TAOS_RETURN(code);
×
2330
  }
2331
  if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
155,316!
2332
    sdbFreeRaw(pVgRaw);
×
2333
    TAOS_RETURN(code);
×
2334
  }
2335
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
155,316✔
2336
  if (code != 0) {
155,316!
2337
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVgroup->vgId, tstrerror(code), __LINE__);
×
2338
    TAOS_RETURN(code);
×
2339
  }
2340

2341
  // learner
2342
  for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
518,194✔
2343
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
362,878!
2344
  }
2345
  TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, pVgroup, pGid));
155,316!
2346

2347
  // voter
2348
  pGid->nodeRole = TAOS_SYNC_ROLE_VOTER;
155,316✔
2349
  TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, pVgroup, pGid->dnodeId));
155,316!
2350
  for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
518,194✔
2351
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
362,878!
2352
  }
2353

2354
  // confirm
2355
  TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup));
155,316!
2356

2357
  TAOS_RETURN(code);
155,316✔
2358
}
2359

2360
static int32_t mndAddDecVgroupReplicaFromTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
155,316✔
2361
                                               int32_t delDnodeId) {
2362
  int32_t code = 0;
155,316✔
2363
  mInfo("vgId:%d, will remove 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, delDnodeId);
155,316!
2364

2365
  SVnodeGid *pGid = NULL;
155,316✔
2366
  SVnodeGid  delGid = {0};
155,316✔
2367
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
267,744!
2368
    if (pVgroup->vnodeGid[i].dnodeId == delDnodeId) {
267,744✔
2369
      pGid = &pVgroup->vnodeGid[i];
155,316✔
2370
      break;
155,316✔
2371
    }
2372
  }
2373

2374
  if (pGid == NULL) return 0;
155,316!
2375

2376
  pVgroup->replica--;
155,316✔
2377
  memcpy(&delGid, pGid, sizeof(SVnodeGid));
155,316!
2378
  memcpy(pGid, &pVgroup->vnodeGid[pVgroup->replica], sizeof(SVnodeGid));
155,316!
2379
  memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
155,316!
2380

2381
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
155,316✔
2382
  if (pVgRaw == NULL) {
155,316!
2383
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2384
    if (terrno != 0) code = terrno;
×
2385
    TAOS_RETURN(code);
×
2386
  }
2387
  if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
155,316!
2388
    sdbFreeRaw(pVgRaw);
×
2389
    TAOS_RETURN(code);
×
2390
  }
2391
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
155,316✔
2392
  if (code != 0) {
155,316!
2393
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVgroup->vgId, tstrerror(code), __LINE__);
×
2394
    TAOS_RETURN(code);
×
2395
  }
2396

2397
  TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pDb, pVgroup, &delGid, true));
155,316!
2398
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
518,194✔
2399
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
362,878!
2400
  }
2401
  TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup));
155,316!
2402

2403
  TAOS_RETURN(code);
155,316✔
2404
}
2405

2406
static int32_t mndRedistributeVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup, SDnodeObj *pNew1,
90,236✔
2407
                                     SDnodeObj *pOld1, SDnodeObj *pNew2, SDnodeObj *pOld2, SDnodeObj *pNew3,
2408
                                     SDnodeObj *pOld3) {
2409
  int32_t code = -1;
90,236✔
2410
  STrans *pTrans = NULL;
90,236✔
2411

2412
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "red-vgroup");
90,236✔
2413
  if (pTrans == NULL) {
90,236!
2414
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2415
    if (terrno != 0) code = terrno;
×
2416
    goto _OVER;
×
2417
  }
2418

2419
  mndTransSetDbName(pTrans, pVgroup->dbName, NULL);
90,236✔
2420
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
90,236✔
2421
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
89,291!
2422

2423
  mndTransSetSerial(pTrans);
89,291✔
2424
  mInfo("trans:%d, used to redistribute vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
89,291!
2425

2426
  SVgObj newVg = {0};
89,291✔
2427
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
89,291!
2428
  mInfo("vgId:%d, vgroup info before redistribute, replica:%d", newVg.vgId, newVg.replica);
89,291!
2429
  for (int32_t i = 0; i < newVg.replica; ++i) {
292,096✔
2430
    mInfo("vgId:%d, vnode:%d dnode:%d role:%s", newVg.vgId, i, newVg.vnodeGid[i].dnodeId,
202,805!
2431
          syncStr(newVg.vnodeGid[i].syncState));
2432
  }
2433

2434
  if (pNew1 != NULL && pOld1 != NULL) {
89,291!
2435
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew1->id);
89,291✔
2436
    if (numOfVnodes >= pNew1->numOfSupportVnodes) {
89,291✔
2437
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew1->id, numOfVnodes,
1,561!
2438
             pNew1->numOfSupportVnodes);
2439
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
1,561✔
2440
      goto _OVER;
1,561✔
2441
    }
2442

2443
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
87,730✔
2444
    if (pNew1->memAvail - vgMem - pNew1->memUsed <= 0) {
87,730!
2445
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2446
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew1->id, pNew1->memAvail, pNew1->memUsed);
2447
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2448
      goto _OVER;
×
2449
    } else {
2450
      pNew1->memUsed += vgMem;
87,730✔
2451
    }
2452

2453
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew1->id), NULL, _OVER);
87,730!
2454
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld1->id), NULL, _OVER);
87,730!
2455
  }
2456

2457
  if (pNew2 != NULL && pOld2 != NULL) {
87,730!
2458
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew2->id);
24,926✔
2459
    if (numOfVnodes >= pNew2->numOfSupportVnodes) {
24,926!
2460
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew2->id, numOfVnodes,
×
2461
             pNew2->numOfSupportVnodes);
2462
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
×
2463
      goto _OVER;
×
2464
    }
2465
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
24,926✔
2466
    if (pNew2->memAvail - vgMem - pNew2->memUsed <= 0) {
24,926!
2467
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2468
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew2->id, pNew2->memAvail, pNew2->memUsed);
2469
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2470
      goto _OVER;
×
2471
    } else {
2472
      pNew2->memUsed += vgMem;
24,926✔
2473
    }
2474
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew2->id), NULL, _OVER);
24,926!
2475
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld2->id), NULL, _OVER);
24,926!
2476
  }
2477

2478
  if (pNew3 != NULL && pOld3 != NULL) {
87,730!
2479
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew3->id);
9,432✔
2480
    if (numOfVnodes >= pNew3->numOfSupportVnodes) {
9,432!
2481
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew3->id, numOfVnodes,
×
2482
             pNew3->numOfSupportVnodes);
2483
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
×
2484
      goto _OVER;
×
2485
    }
2486
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
9,432✔
2487
    if (pNew3->memAvail - vgMem - pNew3->memUsed <= 0) {
9,432!
2488
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2489
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew3->id, pNew3->memAvail, pNew3->memUsed);
2490
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2491
      goto _OVER;
×
2492
    } else {
2493
      pNew3->memUsed += vgMem;
9,432✔
2494
    }
2495
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew3->id), NULL, _OVER);
9,432!
2496
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld3->id), NULL, _OVER);
9,432!
2497
  }
2498

2499
  {
2500
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
87,730✔
2501
    if (pRaw == NULL) {
87,730!
2502
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2503
      if (terrno != 0) code = terrno;
×
2504
      goto _OVER;
×
2505
    }
2506
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
87,730!
2507
      sdbFreeRaw(pRaw);
×
2508
      goto _OVER;
×
2509
    }
2510
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
87,730✔
2511
    if (code != 0) {
87,730!
2512
      mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2513
      goto _OVER;
×
2514
    }
2515
  }
2516

2517
  mInfo("vgId:%d, vgroup info after redistribute, replica:%d", newVg.vgId, newVg.replica);
87,730!
2518
  for (int32_t i = 0; i < newVg.replica; ++i) {
285,852✔
2519
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
198,122!
2520
  }
2521

2522
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
87,730✔
2523
  code = 0;
78,280✔
2524

2525
_OVER:
90,236✔
2526
  mndTransDrop(pTrans);
90,236✔
2527
  mndReleaseDb(pMnode, pDb);
90,236✔
2528
  TAOS_RETURN(code);
90,236✔
2529
}
2530

2531
static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq) {
111,579✔
2532
  SMnode    *pMnode = pReq->info.node;
111,579✔
2533
  SDnodeObj *pNew1 = NULL;
111,579✔
2534
  SDnodeObj *pNew2 = NULL;
111,579✔
2535
  SDnodeObj *pNew3 = NULL;
111,579✔
2536
  SDnodeObj *pOld1 = NULL;
111,579✔
2537
  SDnodeObj *pOld2 = NULL;
111,579✔
2538
  SDnodeObj *pOld3 = NULL;
111,579✔
2539
  SVgObj    *pVgroup = NULL;
111,579✔
2540
  SDbObj    *pDb = NULL;
111,579✔
2541
  int32_t    code = -1;
111,579✔
2542
  int64_t    curMs = taosGetTimestampMs();
111,579✔
2543
  int32_t    newDnodeId[3] = {0};
111,579✔
2544
  int32_t    oldDnodeId[3] = {0};
111,579✔
2545
  int32_t    newIndex = -1;
111,579✔
2546
  int32_t    oldIndex = -1;
111,579✔
2547

2548
  SRedistributeVgroupReq req = {0};
111,579✔
2549
  if (tDeserializeSRedistributeVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) {
111,579!
2550
    code = TSDB_CODE_INVALID_MSG;
×
2551
    goto _OVER;
×
2552
  }
2553

2554
  mInfo("vgId:%d, start to redistribute vgroup to dnode %d:%d:%d", req.vgId, req.dnodeId1, req.dnodeId2, req.dnodeId3);
111,579!
2555
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_REDISTRIBUTE_VGROUP)) != 0) {
111,579✔
2556
    goto _OVER;
1,241✔
2557
  }
2558

2559
  pVgroup = mndAcquireVgroup(pMnode, req.vgId);
110,338✔
2560
  if (pVgroup == NULL) {
110,338✔
2561
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
4,683✔
2562
    if (terrno != 0) code = terrno;
4,683!
2563
    goto _OVER;
4,683✔
2564
  }
2565
  if (pVgroup->mountVgId) {
105,655!
2566
    code = TSDB_CODE_MND_MOUNT_OBJ_NOT_SUPPORT;
×
2567
    goto _OVER;
×
2568
  }
2569
  pDb = mndAcquireDb(pMnode, pVgroup->dbName);
105,655✔
2570
  if (pDb == NULL) {
105,655!
2571
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2572
    if (terrno != 0) code = terrno;
×
2573
    goto _OVER;
×
2574
  }
2575

2576
  if (pVgroup->replica == 1) {
105,655✔
2577
    if (req.dnodeId1 <= 0 || req.dnodeId2 > 0 || req.dnodeId3 > 0) {
33,535!
2578
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2579
      goto _OVER;
×
2580
    }
2581

2582
    if (req.dnodeId1 == pVgroup->vnodeGid[0].dnodeId) {
33,535!
2583
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2584
      code = 0;
×
2585
      goto _OVER;
×
2586
    }
2587

2588
    pNew1 = mndAcquireDnode(pMnode, req.dnodeId1);
33,535✔
2589
    if (pNew1 == NULL) {
33,535!
2590
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2591
      if (terrno != 0) code = terrno;
×
2592
      goto _OVER;
×
2593
    }
2594
    if (!mndIsDnodeOnline(pNew1, curMs)) {
33,535✔
2595
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
823✔
2596
      goto _OVER;
823✔
2597
    }
2598

2599
    pOld1 = mndAcquireDnode(pMnode, pVgroup->vnodeGid[0].dnodeId);
32,712✔
2600
    if (pOld1 == NULL) {
32,712!
2601
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2602
      if (terrno != 0) code = terrno;
×
2603
      goto _OVER;
×
2604
    }
2605
    if (!mndIsDnodeOnline(pOld1, curMs)) {
32,712✔
2606
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
816✔
2607
      goto _OVER;
816✔
2608
    }
2609

2610
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, NULL, NULL, NULL, NULL);
31,896✔
2611

2612
  } else if (pVgroup->replica == 3) {
72,120✔
2613
    if (req.dnodeId1 <= 0 || req.dnodeId2 <= 0 || req.dnodeId3 <= 0) {
68,954!
2614
      code = TSDB_CODE_MND_INVALID_REPLICA;
6,244✔
2615
      goto _OVER;
6,244✔
2616
    }
2617

2618
    if (req.dnodeId1 == req.dnodeId2 || req.dnodeId1 == req.dnodeId3 || req.dnodeId2 == req.dnodeId3) {
62,710!
2619
      code = TSDB_CODE_MND_INVALID_REPLICA;
1,561✔
2620
      goto _OVER;
1,561✔
2621
    }
2622

2623
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId &&
61,149✔
2624
        req.dnodeId1 != pVgroup->vnodeGid[2].dnodeId) {
30,039✔
2625
      newDnodeId[++newIndex] = req.dnodeId1;
24,438✔
2626
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
24,438!
2627
    }
2628

2629
    if (req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId &&
61,149✔
2630
        req.dnodeId2 != pVgroup->vnodeGid[2].dnodeId) {
39,931✔
2631
      newDnodeId[++newIndex] = req.dnodeId2;
29,647✔
2632
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
29,647!
2633
    }
2634

2635
    if (req.dnodeId3 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId3 != pVgroup->vnodeGid[1].dnodeId &&
61,149✔
2636
        req.dnodeId3 != pVgroup->vnodeGid[2].dnodeId) {
49,295✔
2637
      newDnodeId[++newIndex] = req.dnodeId3;
38,684✔
2638
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
38,684!
2639
    }
2640

2641
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId &&
61,149✔
2642
        req.dnodeId3 != pVgroup->vnodeGid[0].dnodeId) {
32,189✔
2643
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[0].dnodeId;
24,392✔
2644
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
24,392!
2645
    }
2646

2647
    if (req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId &&
61,149✔
2648
        req.dnodeId3 != pVgroup->vnodeGid[1].dnodeId) {
37,781✔
2649
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[1].dnodeId;
33,724✔
2650
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
33,724!
2651
    }
2652

2653
    if (req.dnodeId1 != pVgroup->vnodeGid[2].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[2].dnodeId &&
61,149✔
2654
        req.dnodeId3 != pVgroup->vnodeGid[2].dnodeId) {
45,264✔
2655
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[2].dnodeId;
34,653✔
2656
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
34,653!
2657
    }
2658

2659
    if (newDnodeId[0] != 0) {
61,149✔
2660
      pNew1 = mndAcquireDnode(pMnode, newDnodeId[0]);
58,349✔
2661
      if (pNew1 == NULL) {
58,349!
2662
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2663
        if (terrno != 0) code = terrno;
×
2664
        goto _OVER;
×
2665
      }
2666
      if (!mndIsDnodeOnline(pNew1, curMs)) {
58,349✔
2667
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
1,561✔
2668
        goto _OVER;
1,561✔
2669
      }
2670
    }
2671

2672
    if (newDnodeId[1] != 0) {
59,588✔
2673
      pNew2 = mndAcquireDnode(pMnode, newDnodeId[1]);
23,374✔
2674
      if (pNew2 == NULL) {
23,374!
2675
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2676
        if (terrno != 0) code = terrno;
×
2677
        goto _OVER;
×
2678
      }
2679
      if (!mndIsDnodeOnline(pNew2, curMs)) {
23,374✔
2680
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
798✔
2681
        goto _OVER;
798✔
2682
      }
2683
    }
2684

2685
    if (newDnodeId[2] != 0) {
58,790✔
2686
      pNew3 = mndAcquireDnode(pMnode, newDnodeId[2]);
10,248✔
2687
      if (pNew3 == NULL) {
10,248!
2688
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2689
        if (terrno != 0) code = terrno;
×
2690
        goto _OVER;
×
2691
      }
2692
      if (!mndIsDnodeOnline(pNew3, curMs)) {
10,248!
2693
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2694
        goto _OVER;
×
2695
      }
2696
    }
2697

2698
    if (oldDnodeId[0] != 0) {
58,790✔
2699
      pOld1 = mndAcquireDnode(pMnode, oldDnodeId[0]);
55,990✔
2700
      if (pOld1 == NULL) {
55,990!
2701
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2702
        if (terrno != 0) code = terrno;
×
2703
        goto _OVER;
×
2704
      }
2705
      if (!mndIsDnodeOnline(pOld1, curMs)) {
55,990✔
2706
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
816✔
2707
        goto _OVER;
816✔
2708
      }
2709
    }
2710

2711
    if (oldDnodeId[1] != 0) {
57,974✔
2712
      pOld2 = mndAcquireDnode(pMnode, oldDnodeId[1]);
21,760✔
2713
      if (pOld2 == NULL) {
21,760!
2714
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2715
        if (terrno != 0) code = terrno;
×
2716
        goto _OVER;
×
2717
      }
2718
      if (!mndIsDnodeOnline(pOld2, curMs)) {
21,760!
2719
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2720
        goto _OVER;
×
2721
      }
2722
    }
2723

2724
    if (oldDnodeId[2] != 0) {
57,974✔
2725
      pOld3 = mndAcquireDnode(pMnode, oldDnodeId[2]);
9,432✔
2726
      if (pOld3 == NULL) {
9,432!
2727
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2728
        if (terrno != 0) code = terrno;
×
2729
        goto _OVER;
×
2730
      }
2731
      if (!mndIsDnodeOnline(pOld3, curMs)) {
9,432!
2732
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2733
        goto _OVER;
×
2734
      }
2735
    }
2736

2737
    if (pNew1 == NULL && pOld1 == NULL && pNew2 == NULL && pOld2 == NULL && pNew3 == NULL && pOld3 == NULL) {
57,974!
2738
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2739
      code = 0;
2,800✔
2740
      goto _OVER;
2,800✔
2741
    }
2742

2743
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, pNew3, pOld3);
55,174✔
2744

2745
  } else if (pVgroup->replica == 2) {
3,166!
2746
    if (req.dnodeId1 <= 0 || req.dnodeId2 <= 0) {
3,166!
2747
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2748
      goto _OVER;
×
2749
    }
2750

2751
    if (req.dnodeId1 == req.dnodeId2) {
3,166!
2752
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2753
      goto _OVER;
×
2754
    }
2755

2756
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId) {
3,166!
2757
      newDnodeId[++newIndex] = req.dnodeId1;
3,166✔
2758
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
3,166!
2759
    }
2760

2761
    if (req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId) {
3,166!
2762
      newDnodeId[++newIndex] = req.dnodeId2;
3,166✔
2763
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
3,166!
2764
    }
2765

2766
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId) {
3,166!
2767
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[0].dnodeId;
3,166✔
2768
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
3,166!
2769
    }
2770

2771
    if (req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId) {
3,166!
2772
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[1].dnodeId;
3,166✔
2773
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
3,166!
2774
    }
2775

2776
    if (newDnodeId[0] != 0) {
3,166!
2777
      pNew1 = mndAcquireDnode(pMnode, newDnodeId[0]);
3,166✔
2778
      if (pNew1 == NULL) {
3,166!
2779
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2780
        if (terrno != 0) code = terrno;
×
2781
        goto _OVER;
×
2782
      }
2783
      if (!mndIsDnodeOnline(pNew1, curMs)) {
3,166!
2784
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2785
        goto _OVER;
×
2786
      }
2787
    }
2788

2789
    if (newDnodeId[1] != 0) {
3,166!
2790
      pNew2 = mndAcquireDnode(pMnode, newDnodeId[1]);
3,166✔
2791
      if (pNew2 == NULL) {
3,166!
2792
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2793
        if (terrno != 0) code = terrno;
×
2794
        goto _OVER;
×
2795
      }
2796
      if (!mndIsDnodeOnline(pNew2, curMs)) {
3,166!
2797
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2798
        goto _OVER;
×
2799
      }
2800
    }
2801

2802
    if (oldDnodeId[0] != 0) {
3,166!
2803
      pOld1 = mndAcquireDnode(pMnode, oldDnodeId[0]);
3,166✔
2804
      if (pOld1 == NULL) {
3,166!
2805
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2806
        if (terrno != 0) code = terrno;
×
2807
        goto _OVER;
×
2808
      }
2809
      if (!mndIsDnodeOnline(pOld1, curMs)) {
3,166!
2810
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2811
        goto _OVER;
×
2812
      }
2813
    }
2814

2815
    if (oldDnodeId[1] != 0) {
3,166!
2816
      pOld2 = mndAcquireDnode(pMnode, oldDnodeId[1]);
3,166✔
2817
      if (pOld2 == NULL) {
3,166!
2818
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2819
        if (terrno != 0) code = terrno;
×
2820
        goto _OVER;
×
2821
      }
2822
      if (!mndIsDnodeOnline(pOld2, curMs)) {
3,166!
2823
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2824
        goto _OVER;
×
2825
      }
2826
    }
2827

2828
    if (pNew1 == NULL && pOld1 == NULL && pNew2 == NULL && pOld2 == NULL) {
3,166!
2829
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2830
      code = 0;
×
2831
      goto _OVER;
×
2832
    }
2833

2834
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, NULL, NULL);
3,166✔
2835
  } else {
2836
    code = TSDB_CODE_MND_REQ_REJECTED;
×
2837
    goto _OVER;
×
2838
  }
2839

2840
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
90,236✔
2841

2842
  char obj[33] = {0};
90,236✔
2843
  (void)tsnprintf(obj, sizeof(obj), "%d", req.vgId);
90,236✔
2844

2845
  auditRecord(pReq, pMnode->clusterId, "RedistributeVgroup", "", obj, req.sql, req.sqlLen);
90,236✔
2846

2847
_OVER:
111,579✔
2848
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
111,579✔
2849
    mError("vgId:%d, failed to redistribute to dnode %d:%d:%d since %s", req.vgId, req.dnodeId1, req.dnodeId2,
30,499!
2850
           req.dnodeId3, tstrerror(code));
2851
  }
2852

2853
  mndReleaseDnode(pMnode, pNew1);
111,579✔
2854
  mndReleaseDnode(pMnode, pNew2);
111,579✔
2855
  mndReleaseDnode(pMnode, pNew3);
111,579✔
2856
  mndReleaseDnode(pMnode, pOld1);
111,579✔
2857
  mndReleaseDnode(pMnode, pOld2);
111,579✔
2858
  mndReleaseDnode(pMnode, pOld3);
111,579✔
2859
  mndReleaseVgroup(pMnode, pVgroup);
111,579✔
2860
  mndReleaseDb(pMnode, pDb);
111,579✔
2861
  tFreeSRedistributeVgroupReq(&req);
111,579✔
2862

2863
  TAOS_RETURN(code);
111,579✔
2864
}
2865

2866
static void *mndBuildSForceBecomeFollowerReq(SMnode *pMnode, SVgObj *pVgroup, int32_t dnodeId, int32_t *pContLen) {
21,881✔
2867
  SForceBecomeFollowerReq balanceReq = {
21,881✔
2868
      .vgId = pVgroup->vgId,
21,881✔
2869
  };
2870

2871
  int32_t contLen = tSerializeSForceBecomeFollowerReq(NULL, 0, &balanceReq);
21,881✔
2872
  if (contLen < 0) {
21,881!
2873
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2874
    return NULL;
×
2875
  }
2876
  contLen += sizeof(SMsgHead);
21,881✔
2877

2878
  void *pReq = taosMemoryMalloc(contLen);
21,881!
2879
  if (pReq == NULL) {
21,881!
2880
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2881
    return NULL;
×
2882
  }
2883

2884
  SMsgHead *pHead = pReq;
21,881✔
2885
  pHead->contLen = htonl(contLen);
21,881✔
2886
  pHead->vgId = htonl(pVgroup->vgId);
21,881✔
2887

2888
  if (tSerializeSForceBecomeFollowerReq((char *)pReq + sizeof(SMsgHead), contLen, &balanceReq) < 0) {
21,881!
2889
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2890
    taosMemoryFree(pReq);
×
2891
    return NULL;
×
2892
  }
2893
  *pContLen = contLen;
21,881✔
2894
  return pReq;
21,881✔
2895
}
2896

2897
int32_t mndAddBalanceVgroupLeaderAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, int32_t dnodeId) {
21,881✔
2898
  int32_t    code = 0;
21,881✔
2899
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
21,881✔
2900
  if (pDnode == NULL) {
21,881!
2901
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2902
    if (terrno != 0) code = terrno;
×
2903
    TAOS_RETURN(code);
×
2904
  }
2905

2906
  STransAction action = {0};
21,881✔
2907
  action.epSet = mndGetDnodeEpset(pDnode);
21,881✔
2908
  mndReleaseDnode(pMnode, pDnode);
21,881✔
2909

2910
  int32_t contLen = 0;
21,881✔
2911
  void   *pReq = mndBuildSForceBecomeFollowerReq(pMnode, pVgroup, dnodeId, &contLen);
21,881✔
2912
  if (pReq == NULL) {
21,881!
2913
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2914
    if (terrno != 0) code = terrno;
×
2915
    TAOS_RETURN(code);
×
2916
  }
2917

2918
  action.pCont = pReq;
21,881✔
2919
  action.contLen = contLen;
21,881✔
2920
  action.msgType = TDMT_SYNC_FORCE_FOLLOWER;
21,881✔
2921

2922
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
21,881!
2923
    taosMemoryFree(pReq);
×
2924
    TAOS_RETURN(code);
×
2925
  }
2926

2927
  TAOS_RETURN(code);
21,881✔
2928
}
2929

2930
static void *mndBuildAlterVnodeElectBaselineReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId,
131,286✔
2931
                                          int32_t *pContLen, int32_t ms) {
2932
  SAlterVnodeElectBaselineReq alterReq = {
131,286✔
2933
      .vgId = pVgroup->vgId,
131,286✔
2934
      .electBaseLine = ms,
2935
  };
2936

2937
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &alterReq);
131,286✔
2938
  if (contLen < 0) {
131,286!
2939
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2940
    return NULL;
×
2941
  }
2942

2943
  void *pReq = taosMemoryMalloc(contLen);
131,286!
2944
  if (pReq == NULL) {
131,286!
2945
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2946
    return NULL;
×
2947
  }
2948

2949
  if (tSerializeSAlterVnodeReplicaReq(pReq, contLen, &alterReq) < 0) {
131,286!
2950
    mError("vgId:%d, failed to serialize alter vnode req,since %s", alterReq.vgId, terrstr());
×
2951
    taosMemoryFree(pReq);
×
2952
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2953
    return NULL;
×
2954
  }
2955
  *pContLen = contLen;
131,286✔
2956
  return pReq;
131,286✔
2957
}
2958

2959
static int32_t mndAddAlterVnodeElectionBaselineActionToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId, int32_t ms) {
131,286✔
2960
  int32_t    code = 0;
131,286✔
2961
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
131,286✔
2962
  if (pDnode == NULL) {
131,286!
2963
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2964
    if (terrno != 0) code = terrno;
×
2965
    TAOS_RETURN(code);
×
2966
  }
2967

2968
  STransAction action = {0};
131,286✔
2969
  action.epSet = mndGetDnodeEpset(pDnode);
131,286✔
2970
  mndReleaseDnode(pMnode, pDnode);
131,286✔
2971

2972
  int32_t contLen = 0;
131,286✔
2973
  void   *pReq = mndBuildAlterVnodeElectBaselineReq(pMnode, pDb, pVgroup, dnodeId, &contLen, ms);
131,286✔
2974
  if (pReq == NULL) {
131,286!
2975
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2976
    if (terrno != 0) code = terrno;
×
2977
    TAOS_RETURN(code);
×
2978
  }
2979

2980
  action.pCont = pReq;
131,286✔
2981
  action.contLen = contLen;
131,286✔
2982
  action.msgType = TDMT_VND_ALTER_ELECTBASELINE;
131,286✔
2983
  action.groupId = pVgroup->vgId;
131,286✔
2984

2985
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
131,286!
2986
    taosMemoryFree(pReq);
×
2987
    TAOS_RETURN(code);
×
2988
  }
2989

2990
  TAOS_RETURN(code);
131,286✔
2991
}
2992

2993
static int32_t mndAddAlterVgroupElectionBaselineActionToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans, int32_t index){
43,762✔
2994
  int32_t code = 0;
43,762✔
2995
  SSdb   *pSdb = pMnode->pSdb;
43,762✔
2996

2997
  int32_t vgid = pVgroup->vgId;
43,762✔
2998
  int8_t  replica = pVgroup->replica;
43,762✔
2999

3000
  if (pVgroup->replica <= 1) {
43,762!
3001
    mInfo("trans:%d, vgid:%d no need to balance, replica:%d", pTrans->id, vgid, replica);
×
3002
    return -1;
×
3003
  }
3004

3005
  for(int32_t i = 0; i < 3; i++){
175,048✔
3006
    if(i == index%3){
131,286✔
3007
    TAOS_CHECK_RETURN(
21,881!
3008
        mndAddAlterVnodeElectionBaselineActionToTrans(pMnode, pTrans, NULL, pVgroup, pVgroup->vnodeGid[i].dnodeId, 1500));
3009
    }
3010
    else{
3011
    TAOS_CHECK_RETURN(
109,405!
3012
        mndAddAlterVnodeElectionBaselineActionToTrans(pMnode, pTrans, NULL, pVgroup, pVgroup->vnodeGid[i].dnodeId, 5000));
3013
    }
3014
  }
3015
  return code; 
43,762✔
3016
}
3017

3018
int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans, int32_t index) {
25,709✔
3019
  int32_t code = 0;
25,709✔
3020
  SSdb   *pSdb = pMnode->pSdb;
25,709✔
3021

3022
  int32_t vgid = pVgroup->vgId;
25,709✔
3023
  int8_t  replica = pVgroup->replica;
25,709✔
3024

3025
  if (pVgroup->replica <= 1) {
25,709✔
3026
    mInfo("trans:%d, vgid:%d no need to balance, replica:%d", pTrans->id, vgid, replica);
798!
3027
    return -1;
798✔
3028
  }
3029

3030
  int32_t dnodeId = 0;
24,911✔
3031

3032
  for (int i = 0; i < replica; i++) {
62,937✔
3033
    if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER) {
59,907✔
3034
      dnodeId = pVgroup->vnodeGid[i].dnodeId;
21,881✔
3035
      break;
21,881✔
3036
    }
3037
  }
3038

3039
  bool       exist = false;
24,911✔
3040
  bool       online = false;
24,911✔
3041
  int64_t    curMs = taosGetTimestampMs();
24,911✔
3042
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
24,911✔
3043
  if (pDnode != NULL) {
24,911✔
3044
    exist = true;
21,881✔
3045
    online = mndIsDnodeOnline(pDnode, curMs);
21,881✔
3046
    mndReleaseDnode(pMnode, pDnode);
21,881✔
3047
  }
3048

3049
  if (exist && online) {
46,792!
3050
    mInfo("trans:%d, vgid:%d leader to dnode:%d", pTrans->id, vgid, dnodeId);
21,881!
3051
    
3052
    TAOS_CHECK_RETURN(mndAddAlterVgroupElectionBaselineActionToTrans(pMnode, pVgroup, pTrans, index));
21,881!
3053

3054
    if ((code = mndAddBalanceVgroupLeaderAction(pMnode, pTrans, pVgroup, dnodeId)) != 0) {
21,881!
3055
      mError("trans:%d, vgid:%d failed to be balanced to dnode:%d", pTrans->id, vgid, dnodeId);
×
3056
      TAOS_RETURN(code);
×
3057
    }
3058

3059
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, NULL, pVgroup));
21,881!
3060

3061
    TAOS_CHECK_RETURN(mndAddAlterVgroupElectionBaselineActionToTrans(pMnode, pVgroup, pTrans, -1));
21,881!
3062

3063
    SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
21,881✔
3064
    if (pDb == NULL) {
21,881!
3065
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3066
      if (terrno != 0) code = terrno;
×
3067
      mError("trans:%d, vgid:%d failed to be balanced to dnode:%d, because db not exist", pTrans->id, vgid, dnodeId);
×
3068
      TAOS_RETURN(code);
×
3069
    }
3070

3071
    mndReleaseDb(pMnode, pDb);
21,881✔
3072
  } else {
3073
    mInfo("trans:%d, vgid:%d cant be balanced to dnode:%d, exist:%d, online:%d", pTrans->id, vgid, dnodeId, exist,
3,030!
3074
          online);
3075
  }
3076

3077
  TAOS_RETURN(code);
24,911✔
3078
}
3079

3080
extern int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq);
3081

3082
int32_t mndProcessVgroupBalanceLeaderMsg(SRpcMsg *pReq) { return mndProcessVgroupBalanceLeaderMsgImp(pReq); }
11,746✔
3083

3084
#ifndef TD_ENTERPRISE
3085
int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq) { return 0; }
3086
#endif
3087

3088
static int32_t mndCheckDnodeMemory(SMnode *pMnode, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pOldVgroup,
510,002✔
3089
                                   SVgObj *pNewVgroup, SArray *pArray) {
3090
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
1,428,412✔
3091
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
918,410✔
3092
    bool       inVgroup = false;
918,410✔
3093
    int64_t    oldMemUsed = 0;
918,410✔
3094
    int64_t    newMemUsed = 0;
918,410✔
3095
    mDebug("db:%s, vgId:%d, check dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
918,410!
3096
           pDnode->id, pDnode->memAvail, pDnode->memUsed);
3097
    for (int32_t j = 0; j < pOldVgroup->replica; ++j) {
2,628,292✔
3098
      SVnodeGid *pVgId = &pOldVgroup->vnodeGid[j];
1,709,882✔
3099
      if (pDnode->id == pVgId->dnodeId) {
1,709,882✔
3100
        oldMemUsed = mndGetVgroupMemory(pMnode, pOldDb, pOldVgroup);
773,826✔
3101
        inVgroup = true;
773,826✔
3102
      }
3103
    }
3104
    for (int32_t j = 0; j < pNewVgroup->replica; ++j) {
2,628,292✔
3105
      SVnodeGid *pVgId = &pNewVgroup->vnodeGid[j];
1,709,882✔
3106
      if (pDnode->id == pVgId->dnodeId) {
1,709,882✔
3107
        newMemUsed = mndGetVgroupMemory(pMnode, pNewDb, pNewVgroup);
773,826✔
3108
        inVgroup = true;
773,826✔
3109
      }
3110
    }
3111

3112
    mDebug("db:%s, vgId:%d, memory in dnode:%d, oldUsed:%" PRId64 ", newUsed:%" PRId64, pNewVgroup->dbName,
918,410!
3113
           pNewVgroup->vgId, pDnode->id, oldMemUsed, newMemUsed);
3114

3115
    pDnode->memUsed = pDnode->memUsed - oldMemUsed + newMemUsed;
918,410✔
3116
    if (pDnode->memAvail - pDnode->memUsed <= 0) {
918,410!
3117
      mError("db:%s, vgId:%d, no enough memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName,
×
3118
             pNewVgroup->vgId, pDnode->id, pDnode->memAvail, pDnode->memUsed);
3119
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
3120
    } else if (inVgroup) {
918,410✔
3121
      mInfo("db:%s, vgId:%d, memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
773,826!
3122
            pDnode->id, pDnode->memAvail, pDnode->memUsed);
3123
    } else {
3124
    }
3125
  }
3126
  return 0;
510,002✔
3127
}
3128

3129
int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pVgroup,
622,714✔
3130
                                  SArray *pArray, SVgObj *pNewVgroup) {
3131
  int32_t code = 0;
622,714✔
3132
  memcpy(pNewVgroup, pVgroup, sizeof(SVgObj));
622,714!
3133

3134
  if (pVgroup->replica <= 0 || pVgroup->replica == pNewDb->cfg.replications) {
622,714!
3135
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfigAction(pMnode, pTrans, pNewDb, pVgroup));
510,002!
3136
    TAOS_CHECK_RETURN(mndCheckDnodeMemory(pMnode, pOldDb, pNewDb, pNewVgroup, pVgroup, pArray));
510,002!
3137
    return 0;
510,002✔
3138
  }
3139

3140
  // mndTransSetGroupParallel(pTrans);
3141

3142
  if (pNewDb->cfg.replications == 3) {
112,712✔
3143
    mInfo("trans:%d, db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
99,825!
3144
          pVgroup->vnodeGid[0].dnodeId);
3145

3146
    // add second
3147
    if (pNewVgroup->replica == 1) {
99,825!
3148
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
99,825✔
3149
    }
3150

3151
    // learner stage
3152
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
98,257✔
3153
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
98,257✔
3154
    TAOS_CHECK_RETURN(
98,257!
3155
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3156

3157
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[1]));
98,257!
3158

3159
    // follower stage
3160
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
98,257✔
3161
    TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
98,257!
3162
    TAOS_CHECK_RETURN(
98,257!
3163
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3164

3165
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
98,257!
3166

3167
    // add third
3168
    if (pNewVgroup->replica == 2) {
98,257!
3169
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
98,257✔
3170
    }
3171

3172
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
89,383✔
3173
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
89,383✔
3174
    pNewVgroup->vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
89,383✔
3175
    TAOS_CHECK_RETURN(
89,383!
3176
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3177
    TAOS_CHECK_RETURN(
89,383!
3178
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
3179
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[2]));
89,383!
3180

3181
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
89,383!
3182
  } else if (pNewDb->cfg.replications == 1) {
12,887✔
3183
    mInfo("trans:%d, db:%s, vgId:%d, will remove 2 vnodes, vn:0 dnode:%d vn:1 dnode:%d vn:2 dnode:%d", pTrans->id,
9,707!
3184
          pVgroup->dbName, pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId, pVgroup->vnodeGid[1].dnodeId,
3185
          pVgroup->vnodeGid[2].dnodeId);
3186

3187
    SVnodeGid del1 = {0};
9,707✔
3188
    SVnodeGid del2 = {0};
9,707✔
3189
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroup(pMnode, pTrans, pNewVgroup, pArray, &del1));
9,707!
3190
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &del1, true));
9,707!
3191
    TAOS_CHECK_RETURN(
9,707!
3192
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3193
    TAOS_CHECK_RETURN(
9,707!
3194
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
3195
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
9,707!
3196

3197
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroup(pMnode, pTrans, pNewVgroup, pArray, &del2));
9,707!
3198
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &del2, true));
9,707!
3199
    TAOS_CHECK_RETURN(
9,707!
3200
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3201
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
9,707!
3202
  } else if (pNewDb->cfg.replications == 2) {
3,180!
3203
    mInfo("trans:%d, db:%s, vgId:%d, will add 1 vnode, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
3,180!
3204
          pVgroup->vnodeGid[0].dnodeId);
3205

3206
    // add second
3207
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
3,180!
3208

3209
    // learner stage
3210
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
3,180✔
3211
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
3,180✔
3212
    TAOS_CHECK_RETURN(
3,180!
3213
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3214

3215
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[1]));
3,180!
3216

3217
    // follower stage
3218
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
3,180✔
3219
    TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
3,180!
3220
    TAOS_CHECK_RETURN(
3,180!
3221
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3222

3223
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
3,180!
3224
  } else {
3225
    return -1;
×
3226
  }
3227

3228
  mndSortVnodeGid(pNewVgroup);
102,270✔
3229

3230
  {
3231
    SSdbRaw *pVgRaw = mndVgroupActionEncode(pNewVgroup);
102,270✔
3232
    if (pVgRaw == NULL) {
102,270!
3233
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3234
      if (terrno != 0) code = terrno;
×
3235
      TAOS_RETURN(code);
×
3236
    }
3237
    if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
102,270!
3238
      sdbFreeRaw(pVgRaw);
×
3239
      TAOS_RETURN(code);
×
3240
    }
3241
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
102,270✔
3242
    if (code != 0) {
102,270!
3243
      mError("vgId:%d, failed to set raw status since %s at line:%d", pNewVgroup->vgId, tstrerror(code), __LINE__);
×
3244
      TAOS_RETURN(code);
×
3245
    }
3246
  }
3247

3248
  TAOS_RETURN(code);
102,270✔
3249
}
3250

3251
int32_t mndBuildRaftAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pVgroup,
×
3252
                                      SArray *pArray) {
3253
  int32_t code = 0;
×
3254
  SVgObj  newVgroup = {0};
×
3255
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
×
3256

3257
  if (pVgroup->replica <= 0 || pVgroup->replica == pNewDb->cfg.replications) {
×
3258
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfigAction(pMnode, pTrans, pNewDb, pVgroup));
×
3259
    TAOS_CHECK_RETURN(mndCheckDnodeMemory(pMnode, pOldDb, pNewDb, &newVgroup, pVgroup, pArray));
×
3260
    return 0;
×
3261
  }
3262

3263
  mndTransSetSerial(pTrans);
×
3264

3265
  mInfo("trans:%d, vgId:%d, alter vgroup, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3266
        pVgroup->syncConfChangeVer, pVgroup->version, pVgroup->replica);
3267

3268
  if (newVgroup.replica == 1 && pNewDb->cfg.replications == 3) {
×
3269
    mInfo("db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId,
×
3270
          pVgroup->vnodeGid[0].dnodeId);
3271

3272
    // add second
3273
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray));
×
3274
    // add third
3275
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray));
×
3276

3277
    // add learner stage
3278
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3279
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3280
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3281
    TAOS_CHECK_RETURN(
×
3282
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3283
    mInfo("trans:%d, vgId:%d, add change config, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id,
×
3284
          pVgroup->vgId, newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3285
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[1]));
×
3286
    mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3287
          newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3288
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[2]));
×
3289
    mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3290
          newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3291

3292
    // check learner
3293
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3294
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3295
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3296
    TAOS_CHECK_RETURN(
×
3297
        mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId));
3298
    TAOS_CHECK_RETURN(
×
3299
        mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[2].dnodeId));
3300

3301
    // change raft type
3302
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3303
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3304
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3305
    TAOS_CHECK_RETURN(
×
3306
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3307

3308
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3309

3310
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3311
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3312
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3313
    TAOS_CHECK_RETURN(
×
3314
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3315

3316
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3317

3318
    SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3319
    if (pVgRaw == NULL) {
×
3320
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3321
      if (terrno != 0) code = terrno;
×
3322
      TAOS_RETURN(code);
×
3323
    }
3324
    if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
×
3325
      sdbFreeRaw(pVgRaw);
×
3326
      TAOS_RETURN(code);
×
3327
    }
3328
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3329
    if (code != 0) {
×
3330
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3331
             __LINE__);
3332
      TAOS_RETURN(code);
×
3333
    }
3334
  } else if (newVgroup.replica == 3 && pNewDb->cfg.replications == 1) {
×
3335
    mInfo("db:%s, vgId:%d, will remove 2 vnodes, vn:0 dnode:%d vn:1 dnode:%d vn:2 dnode:%d", pVgroup->dbName,
×
3336
          pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId, pVgroup->vnodeGid[1].dnodeId, pVgroup->vnodeGid[2].dnodeId);
3337

3338
    SVnodeGid del1 = {0};
×
3339
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del1));
×
3340

3341
    TAOS_CHECK_RETURN(
×
3342
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3343

3344
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3345

3346
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &del1, true));
×
3347

3348
    SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3349
    if (pVgRaw == NULL) {
×
3350
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3351
      if (terrno != 0) code = terrno;
×
3352
      TAOS_RETURN(code);
×
3353
    }
3354
    if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
×
3355
      sdbFreeRaw(pVgRaw);
×
3356
      TAOS_RETURN(code);
×
3357
    }
3358
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3359
    if (code != 0) {
×
3360
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3361
             __LINE__);
3362
      TAOS_RETURN(code);
×
3363
    }
3364

3365
    SVnodeGid del2 = {0};
×
3366
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del2));
×
3367

3368
    TAOS_CHECK_RETURN(
×
3369
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3370

3371
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3372

3373
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &del2, true));
×
3374

3375
    pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3376
    if (pVgRaw == NULL) {
×
3377
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3378
      if (terrno != 0) code = terrno;
×
3379
      TAOS_RETURN(code);
×
3380
    }
3381
    if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
×
3382
      sdbFreeRaw(pVgRaw);
×
3383
      TAOS_RETURN(code);
×
3384
    }
3385
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3386
    if (code != 0) {
×
3387
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3388
             __LINE__);
3389
      TAOS_RETURN(code);
×
3390
    }
3391
  } else {
3392
    return -1;
×
3393
  }
3394

3395
  mndSortVnodeGid(&newVgroup);
×
3396

3397
  {
3398
    SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3399
    if (pVgRaw == NULL) {
×
3400
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3401
      if (terrno != 0) code = terrno;
×
3402
      TAOS_RETURN(code);
×
3403
    }
3404
    if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
×
3405
      sdbFreeRaw(pVgRaw);
×
3406
      TAOS_RETURN(code);
×
3407
    }
3408
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3409
    if (code != 0) {
×
3410
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3411
             __LINE__);
3412
      TAOS_RETURN(code);
×
3413
    }
3414
  }
3415

3416
  TAOS_RETURN(code);
×
3417
}
3418

3419
int32_t mndBuildRestoreAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *db, SVgObj *pVgroup, SDnodeObj *pDnode,
9,875✔
3420
                                         SDnodeObj *pAnotherDnode) {
3421
  int32_t code = 0;
9,875✔
3422
  SVgObj  newVgroup = {0};
9,875✔
3423
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
9,875!
3424

3425
  mInfo("trans:%d, db:%s, vgId:%d, restore vnodes, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
9,875!
3426
        pVgroup->vnodeGid[0].dnodeId);
3427

3428
  if (newVgroup.replica == 1) {
9,875!
3429
    int selected = 0;
×
3430
    for (int i = 0; i < newVgroup.replica; i++) {
×
3431
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3432
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3433
        selected = i;
×
3434
      }
3435
    }
3436
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, &newVgroup.vnodeGid[selected]));
×
3437
  } else if (newVgroup.replica == 2) {
9,875!
3438
    for (int i = 0; i < newVgroup.replica; i++) {
×
3439
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3440
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3441
      } else {
3442
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3443
      }
3444
    }
3445
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pAnotherDnode));
×
3446

3447
    for (int i = 0; i < newVgroup.replica; i++) {
×
3448
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3449
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3450
      } else {
3451
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3452
      }
3453
    }
3454
    TAOS_CHECK_RETURN(mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode));
×
3455

3456
    for (int i = 0; i < newVgroup.replica; i++) {
×
3457
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3458
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3459
      }
3460
    }
3461
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode));
×
3462
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pAnotherDnode));
×
3463
  } else if (newVgroup.replica == 3) {
9,875!
3464
    for (int i = 0; i < newVgroup.replica; i++) {
39,500✔
3465
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
29,625✔
3466
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
9,875✔
3467
      } else {
3468
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
19,750✔
3469
      }
3470
    }
3471
    TAOS_CHECK_RETURN(mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode));
9,875!
3472

3473
    for (int i = 0; i < newVgroup.replica; i++) {
39,500✔
3474
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
29,625✔
3475
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
29,625✔
3476
      }
3477
    }
3478
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode));
9,875!
3479
  }
3480
  SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
9,875✔
3481
  if (pVgRaw == NULL) {
9,875!
3482
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3483
    if (terrno != 0) code = terrno;
×
3484
    TAOS_RETURN(code);
×
3485
  }
3486
  if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
9,875!
3487
    sdbFreeRaw(pVgRaw);
×
3488
    TAOS_RETURN(code);
×
3489
  }
3490
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
9,875✔
3491
  if (code != 0) {
9,875!
3492
    mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code), __LINE__);
×
3493
    TAOS_RETURN(code);
×
3494
  }
3495

3496
  TAOS_RETURN(code);
9,875✔
3497
}
3498

3499
static int32_t mndAddAdjustVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
×
3500
  return 0;
×
3501
}
3502

3503
typedef int32_t (*FpTransActionCb)(STrans *pTrans, SSdbRaw *pRaw);
3504

3505
static int32_t mndAddVgStatusAction(STrans *pTrans, SVgObj *pVg, ESdbStatus vgStatus, ETrnStage stage) {
177,120✔
3506
  int32_t         code = 0;
177,120✔
3507
  FpTransActionCb appendActionCb = (stage == TRN_STAGE_COMMIT_ACTION) ? mndTransAppendCommitlog : mndTransAppendRedolog;
177,120✔
3508
  SSdbRaw        *pRaw = mndVgroupActionEncode(pVg);
177,120✔
3509
  if (pRaw == NULL) {
177,120!
3510
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3511
    if (terrno != 0) code = terrno;
×
3512
    goto _err;
×
3513
  }
3514
  if ((code = appendActionCb(pTrans, pRaw)) != 0) goto _err;
177,120!
3515
  code = sdbSetRawStatus(pRaw, vgStatus);
177,120✔
3516
  if (code != 0) {
177,120!
3517
    mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", pVg->vgId, tstrerror(code), __LINE__);
×
3518
    goto _err;
×
3519
  }
3520
  pRaw = NULL;
177,120✔
3521
  TAOS_RETURN(code);
177,120✔
3522
_err:
×
3523
  sdbFreeRaw(pRaw);
×
3524
  TAOS_RETURN(code);
×
3525
}
3526

3527
static int32_t mndAddDbStatusAction(STrans *pTrans, SDbObj *pDb, ESdbStatus dbStatus, ETrnStage stage) {
73,416✔
3528
  int32_t         code = 0;
73,416✔
3529
  FpTransActionCb appendActionCb = (stage == TRN_STAGE_COMMIT_ACTION) ? mndTransAppendCommitlog : mndTransAppendRedolog;
73,416✔
3530
  SSdbRaw        *pRaw = mndDbActionEncode(pDb);
73,416✔
3531
  if (pRaw == NULL) {
73,416!
3532
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3533
    if (terrno != 0) code = terrno;
×
3534
    goto _err;
×
3535
  }
3536
  if ((code = appendActionCb(pTrans, pRaw)) != 0) goto _err;
73,416!
3537
  code = sdbSetRawStatus(pRaw, dbStatus);
73,416✔
3538
  if (code != 0) {
73,416!
3539
    mError("db:%s, failed to set raw status to ready, error:%s, line:%d", pDb->name, tstrerror(code), __LINE__);
×
3540
    goto _err;
×
3541
  }
3542
  pRaw = NULL;
73,416✔
3543
  TAOS_RETURN(code);
73,416✔
3544
_err:
×
3545
  sdbFreeRaw(pRaw);
×
3546
  TAOS_RETURN(code);
×
3547
}
3548

3549
int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
42,913✔
3550
  int32_t code = -1;
42,913✔
3551
  STrans *pTrans = NULL;
42,913✔
3552
  SDbObj  dbObj = {0};
42,913✔
3553
  SArray *pArray = mndBuildDnodesArray(pMnode, 0, NULL);
42,913✔
3554

3555
#if defined(USE_SHARED_STORAGE)
3556
  if (tsSsEnabled) {
42,913!
3557
    code = TSDB_CODE_OPS_NOT_SUPPORT;
×
3558
    mError("vgId:%d, db:%s, shared storage exists, split vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
×
3559
    goto _OVER;
×
3560
  }
3561
#endif
3562

3563
  /*
3564
    if (pDb->cfg.withArbitrator) {
3565
      code = TSDB_CODE_OPS_NOT_SUPPORT;
3566
      mError("vgId:%d, db:%s, with arbitrator, split vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
3567
      goto _OVER;
3568
    }
3569
  */
3570

3571
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "split-vgroup");
42,913✔
3572
  if (pTrans == NULL) {
42,913!
3573
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3574
    if (terrno != 0) code = terrno;
×
3575
    goto _OVER;
×
3576
  }
3577
  mndTransSetSerial(pTrans);
42,913✔
3578
  mInfo("trans:%d, used to split vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
42,913!
3579

3580
  mndTransSetDbName(pTrans, pDb->name, NULL);
42,913✔
3581
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
42,913✔
3582
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
41,968!
3583

3584
  SVgObj newVg1 = {0};
41,968✔
3585
  memcpy(&newVg1, pVgroup, sizeof(SVgObj));
41,968!
3586
  mInfo("vgId:%d, vgroup info before split, replica:%d hashBegin:%u hashEnd:%u", newVg1.vgId, newVg1.replica,
41,968!
3587
        newVg1.hashBegin, newVg1.hashEnd);
3588
  for (int32_t i = 0; i < newVg1.replica; ++i) {
143,222✔
3589
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg1.vgId, i, newVg1.vnodeGid[i].dnodeId);
101,254!
3590
  }
3591

3592
  if (newVg1.replica == 1) {
41,968✔
3593
    TAOS_CHECK_GOTO(mndAddVnodeToVgroup(pMnode, pTrans, &newVg1, pArray), NULL, _OVER);
11,530✔
3594

3595
    newVg1.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
10,707✔
3596
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
10,707!
3597
                    _OVER);
3598
    TAOS_CHECK_GOTO(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg1, &newVg1.vnodeGid[1]), NULL, _OVER);
10,707!
3599

3600
    newVg1.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
10,707✔
3601
    TAOS_CHECK_GOTO(mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[1].dnodeId), NULL, _OVER);
10,707!
3602
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
10,707!
3603
                    _OVER);
3604

3605
    TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
10,707!
3606
  } else if (newVg1.replica == 3) {
30,438✔
3607
    SVnodeGid del1 = {0};
28,848✔
3608
    TAOS_CHECK_GOTO(mndRemoveVnodeFromVgroup(pMnode, pTrans, &newVg1, pArray, &del1), NULL, _OVER);
28,848!
3609
    TAOS_CHECK_GOTO(mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg1, &del1, true), NULL, _OVER);
28,848!
3610
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
28,848!
3611
                    _OVER);
3612
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[1].dnodeId), NULL,
28,848!
3613
                    _OVER);
3614
  } else {
3615
    // goto _OVER;
3616
  }
3617

3618
  for (int32_t i = 0; i < newVg1.replica; ++i) {
123,435✔
3619
    TAOS_CHECK_GOTO(mndAddDisableVnodeWriteAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[i].dnodeId), NULL,
82,290!
3620
                    _OVER);
3621
  }
3622
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
41,145!
3623

3624
  SVgObj newVg2 = {0};
41,145✔
3625
  memcpy(&newVg2, &newVg1, sizeof(SVgObj));
41,145✔
3626
  newVg1.replica = 1;
41,145✔
3627
  newVg1.hashEnd = newVg1.hashBegin / 2 + newVg1.hashEnd / 2;
41,145✔
3628
  memset(&newVg1.vnodeGid[1], 0, sizeof(SVnodeGid));
41,145✔
3629

3630
  newVg2.replica = 1;
41,145✔
3631
  newVg2.hashBegin = newVg1.hashEnd + 1;
41,145✔
3632
  memcpy(&newVg2.vnodeGid[0], &newVg2.vnodeGid[1], sizeof(SVnodeGid));
41,145✔
3633
  memset(&newVg2.vnodeGid[1], 0, sizeof(SVnodeGid));
41,145✔
3634

3635
  mInfo("vgId:%d, vgroup info after split, replica:%d hashrange:[%u, %u] vnode:0 dnode:%d", newVg1.vgId, newVg1.replica,
41,145!
3636
        newVg1.hashBegin, newVg1.hashEnd, newVg1.vnodeGid[0].dnodeId);
3637
  for (int32_t i = 0; i < newVg1.replica; ++i) {
82,290✔
3638
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg1.vgId, i, newVg1.vnodeGid[i].dnodeId);
41,145!
3639
  }
3640
  mInfo("vgId:%d, vgroup info after split, replica:%d hashrange:[%u, %u] vnode:0 dnode:%d", newVg2.vgId, newVg2.replica,
41,145!
3641
        newVg2.hashBegin, newVg2.hashEnd, newVg2.vnodeGid[0].dnodeId);
3642
  for (int32_t i = 0; i < newVg1.replica; ++i) {
82,290✔
3643
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg2.vgId, i, newVg2.vnodeGid[i].dnodeId);
41,145!
3644
  }
3645

3646
  // alter vgId and hash range
3647
  int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
41,145✔
3648
  int32_t srcVgId = newVg1.vgId;
41,145✔
3649
  newVg1.vgId = maxVgId;
41,145✔
3650
  TAOS_CHECK_GOTO(mndAddNewVgPrepareAction(pMnode, pTrans, &newVg1), NULL, _OVER);
41,145!
3651
  TAOS_CHECK_GOTO(mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg1), NULL, _OVER);
41,145!
3652

3653
  maxVgId++;
41,145✔
3654
  srcVgId = newVg2.vgId;
41,145✔
3655
  newVg2.vgId = maxVgId;
41,145✔
3656
  TAOS_CHECK_GOTO(mndAddNewVgPrepareAction(pMnode, pTrans, &newVg2), NULL, _OVER);
41,145!
3657
  TAOS_CHECK_GOTO(mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg2), NULL, _OVER);
41,145!
3658

3659
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
41,145!
3660
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg2), NULL, _OVER);
41,145!
3661

3662
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
41,145!
3663
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
41,145!
3664
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_REDO_ACTION), NULL, _OVER);
41,145!
3665

3666
  // update db status
3667
  memcpy(&dbObj, pDb, sizeof(SDbObj));
41,145!
3668
  if (dbObj.cfg.pRetensions != NULL) {
41,145!
3669
    dbObj.cfg.pRetensions = taosArrayDup(pDb->cfg.pRetensions, NULL);
×
3670
    if (dbObj.cfg.pRetensions == NULL) {
×
3671
      code = terrno;
×
3672
      goto _OVER;
×
3673
    }
3674
  }
3675
  dbObj.vgVersion++;
41,145✔
3676
  dbObj.updateTime = taosGetTimestampMs();
41,145✔
3677
  dbObj.cfg.numOfVgroups++;
41,145✔
3678
  TAOS_CHECK_GOTO(mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
41,145!
3679

3680
  // adjust vgroup replica
3681
  if (pDb->cfg.replications != newVg1.replica) {
41,145✔
3682
    SVgObj tmpGroup = {0};
30,438✔
3683
    TAOS_CHECK_GOTO(mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg1, pArray, &tmpGroup), NULL, _OVER);
30,438✔
3684
  } else {
3685
    TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
10,707!
3686
  }
3687

3688
  if (pDb->cfg.replications != newVg2.replica) {
37,126✔
3689
    SVgObj tmpGroup = {0};
26,419✔
3690
    TAOS_CHECK_GOTO(mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg2, pArray, &tmpGroup), NULL, _OVER);
26,419✔
3691
  } else {
3692
    TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
10,707!
3693
  }
3694

3695
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
32,271!
3696

3697
  // commit db status
3698
  dbObj.vgVersion++;
32,271✔
3699
  dbObj.updateTime = taosGetTimestampMs();
32,271✔
3700
  TAOS_CHECK_GOTO(mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
32,271!
3701

3702
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
32,271!
3703
  code = 0;
32,271✔
3704

3705
_OVER:
42,913✔
3706
  taosArrayDestroy(pArray);
42,913✔
3707
  mndTransDrop(pTrans);
42,913✔
3708
  taosArrayDestroy(dbObj.cfg.pRetensions);
42,913✔
3709
  TAOS_RETURN(code);
42,913✔
3710
}
3711

3712
extern int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq);
3713

3714
static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) { return mndProcessSplitVgroupMsgImp(pReq); }
45,403✔
3715

3716
#ifndef TD_ENTERPRISE
3717
int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq) { return 0; }
3718
#endif
3719

3720
static int32_t mndSetBalanceVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
33,228✔
3721
                                              SDnodeObj *pSrc, SDnodeObj *pDst) {
3722
  int32_t code = 0;
33,228✔
3723
  SVgObj  newVg = {0};
33,228✔
3724
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
33,228!
3725
  mInfo("vgId:%d, vgroup info before balance, replica:%d", newVg.vgId, newVg.replica);
33,228!
3726
  for (int32_t i = 0; i < newVg.replica; ++i) {
98,076✔
3727
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
64,848!
3728
  }
3729

3730
  TAOS_CHECK_RETURN(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pDst->id));
33,228!
3731
  TAOS_CHECK_RETURN(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pSrc->id));
33,228!
3732

3733
  {
3734
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
33,228✔
3735
    if (pRaw == NULL) {
33,228!
3736
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3737
      if (terrno != 0) code = terrno;
×
3738
      TAOS_RETURN(code);
×
3739
    }
3740
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
33,228!
3741
      sdbFreeRaw(pRaw);
×
3742
      TAOS_RETURN(code);
×
3743
    }
3744
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
33,228✔
3745
    if (code != 0) {
33,228!
3746
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
3747
      TAOS_RETURN(code);
×
3748
    }
3749
  }
3750

3751
  mInfo("vgId:%d, vgroup info after balance, replica:%d", newVg.vgId, newVg.replica);
33,228!
3752
  for (int32_t i = 0; i < newVg.replica; ++i) {
98,076✔
3753
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
64,848!
3754
  }
3755
  TAOS_RETURN(code);
33,228✔
3756
}
3757

3758
static int32_t mndBalanceVgroupBetweenDnode(SMnode *pMnode, STrans *pTrans, SDnodeObj *pSrc, SDnodeObj *pDst,
33,228✔
3759
                                            SHashObj *pBalancedVgroups) {
3760
  void   *pIter = NULL;
33,228✔
3761
  int32_t code = -1;
33,228✔
3762
  SSdb   *pSdb = pMnode->pSdb;
33,228✔
3763

3764
  while (1) {
20,552✔
3765
    SVgObj *pVgroup = NULL;
53,780✔
3766
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
53,780✔
3767
    if (pIter == NULL) break;
53,780!
3768
    if (taosHashGet(pBalancedVgroups, &pVgroup->vgId, sizeof(int32_t)) != NULL) {
53,780✔
3769
      sdbRelease(pSdb, pVgroup);
18,969✔
3770
      continue;
18,969✔
3771
    }
3772

3773
    bool existInSrc = false;
34,811✔
3774
    bool existInDst = false;
34,811✔
3775
    for (int32_t i = 0; i < pVgroup->replica; ++i) {
101,242✔
3776
      SVnodeGid *pGid = &pVgroup->vnodeGid[i];
66,431✔
3777
      if (pGid->dnodeId == pSrc->id) existInSrc = true;
66,431✔
3778
      if (pGid->dnodeId == pDst->id) existInDst = true;
66,431!
3779
    }
3780

3781
    if (!existInSrc || existInDst) {
34,811!
3782
      sdbRelease(pSdb, pVgroup);
1,583✔
3783
      continue;
1,583✔
3784
    }
3785

3786
    SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
33,228✔
3787
    if (pDb == NULL) {
33,228!
3788
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3789
      if (terrno != 0) code = terrno;
×
3790
      mError("vgId:%d, balance vgroup can't find db obj dbName:%s", pVgroup->vgId, pVgroup->dbName);
×
3791
      goto _OUT;
×
3792
    }
3793

3794
    if (pDb->cfg.withArbitrator) {
33,228!
3795
      mInfo("vgId:%d, db:%s, with arbitrator, balance vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
×
3796
      goto _OUT;
×
3797
    }
3798

3799
    code = mndSetBalanceVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, pSrc, pDst);
33,228✔
3800
    if (code == 0) {
33,228!
3801
      code = taosHashPut(pBalancedVgroups, &pVgroup->vgId, sizeof(int32_t), &pVgroup->vgId, sizeof(int32_t));
33,228✔
3802
    }
3803

3804
  _OUT:
33,228✔
3805
    mndReleaseDb(pMnode, pDb);
33,228✔
3806
    sdbRelease(pSdb, pVgroup);
33,228✔
3807
    sdbCancelFetch(pSdb, pIter);
33,228✔
3808
    break;
33,228✔
3809
  }
3810

3811
  return code;
33,228✔
3812
}
3813

3814
static int32_t mndBalanceVgroup(SMnode *pMnode, SRpcMsg *pReq, SArray *pArray) {
30,975✔
3815
  int32_t   code = -1;
30,975✔
3816
  int32_t   numOfVgroups = 0;
30,975✔
3817
  STrans   *pTrans = NULL;
30,975✔
3818
  SHashObj *pBalancedVgroups = NULL;
30,975✔
3819

3820
  pBalancedVgroups = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
30,975✔
3821
  if (pBalancedVgroups == NULL) goto _OVER;
30,975!
3822

3823
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "balance-vgroup");
30,975✔
3824
  if (pTrans == NULL) {
30,975!
3825
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3826
    if (terrno != 0) code = terrno;
×
3827
    goto _OVER;
×
3828
  }
3829
  mndTransSetSerial(pTrans);
30,975✔
3830
  mInfo("trans:%d, used to balance vgroup", pTrans->id);
30,975!
3831
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
30,975✔
3832
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
21,525✔
3833
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
20,580!
3834

3835
  while (1) {
33,228✔
3836
    taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
53,808✔
3837
    for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
232,560✔
3838
      SDnodeObj *pDnode = taosArrayGet(pArray, i);
178,752✔
3839
      mInfo("dnode:%d, equivalent vnodes:%d others:%d support:%d, score:%f", pDnode->id, pDnode->numOfVnodes,
178,752!
3840
            pDnode->numOfSupportVnodes, pDnode->numOfOtherNodes, mndGetDnodeScore(pDnode, 0, 1));
3841
    }
3842

3843
    SDnodeObj *pSrc = taosArrayGet(pArray, taosArrayGetSize(pArray) - 1);
53,808✔
3844
    SDnodeObj *pDst = taosArrayGet(pArray, 0);
53,808✔
3845

3846
    float srcScore = mndGetDnodeScore(pSrc, -1, 1);
53,808✔
3847
    float dstScore = mndGetDnodeScore(pDst, 1, 1);
53,808✔
3848
    mInfo("trans:%d, after balance, src dnode:%d score:%f, dst dnode:%d score:%f", pTrans->id, pSrc->id, dstScore,
53,808!
3849
          pDst->id, dstScore);
3850

3851
    if (srcScore > dstScore - 0.000001) {
53,808✔
3852
      code = mndBalanceVgroupBetweenDnode(pMnode, pTrans, pSrc, pDst, pBalancedVgroups);
33,228✔
3853
      if (code == 0) {
33,228!
3854
        pSrc->numOfVnodes--;
33,228✔
3855
        pDst->numOfVnodes++;
33,228✔
3856
        numOfVgroups++;
33,228✔
3857
        continue;
33,228✔
3858
      } else {
3859
        mInfo("trans:%d, no vgroup need to balance from dnode:%d to dnode:%d", pTrans->id, pSrc->id, pDst->id);
×
3860
        break;
×
3861
      }
3862
    } else {
3863
      mInfo("trans:%d, no vgroup need to balance any more", pTrans->id);
20,580!
3864
      break;
20,580✔
3865
    }
3866
  }
3867

3868
  if (numOfVgroups <= 0) {
20,580!
3869
    mInfo("no need to balance vgroup");
×
3870
    code = 0;
×
3871
  } else {
3872
    mInfo("start to balance vgroup, numOfVgroups:%d", numOfVgroups);
20,580!
3873
    if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
20,580!
3874
    code = TSDB_CODE_ACTION_IN_PROGRESS;
20,580✔
3875
  }
3876

3877
_OVER:
30,975✔
3878
  taosHashCleanup(pBalancedVgroups);
30,975✔
3879
  mndTransDrop(pTrans);
30,975✔
3880
  TAOS_RETURN(code);
30,975✔
3881
}
3882

3883
static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq) {
35,416✔
3884
  SMnode *pMnode = pReq->info.node;
35,416✔
3885
  int32_t code = -1;
35,416✔
3886
  SArray *pArray = NULL;
35,416✔
3887
  void   *pIter = NULL;
35,416✔
3888
  int64_t curMs = taosGetTimestampMs();
35,416✔
3889

3890
  SBalanceVgroupReq req = {0};
35,416✔
3891
  if (tDeserializeSBalanceVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) {
35,416!
3892
    code = TSDB_CODE_INVALID_MSG;
×
3893
    goto _OVER;
×
3894
  }
3895

3896
  mInfo("start to balance vgroup");
35,416!
3897
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_BALANCE_VGROUP)) != 0) {
35,416✔
3898
    goto _OVER;
1,241✔
3899
  }
3900

3901
  if (sdbGetSize(pMnode->pSdb, SDB_MOUNT) > 0) {
34,175!
3902
    code = TSDB_CODE_MND_MOUNT_NOT_EMPTY;
×
3903
    goto _OVER;
×
3904
  }
3905

3906
  while (1) {
104,065✔
3907
    SDnodeObj *pDnode = NULL;
138,240✔
3908
    pIter = sdbFetch(pMnode->pSdb, SDB_DNODE, pIter, (void **)&pDnode);
138,240✔
3909
    if (pIter == NULL) break;
138,240✔
3910
    if (!mndIsDnodeOnline(pDnode, curMs)) {
107,265✔
3911
      sdbCancelFetch(pMnode->pSdb, pIter);
3,200✔
3912
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
3,200✔
3913
      mError("failed to balance vgroup since %s, dnode:%d", terrstr(), pDnode->id);
3,200!
3914
      sdbRelease(pMnode->pSdb, pDnode);
3,200✔
3915
      goto _OVER;
3,200✔
3916
    }
3917

3918
    sdbRelease(pMnode->pSdb, pDnode);
104,065✔
3919
  }
3920

3921
  pArray = mndBuildDnodesArray(pMnode, 0, NULL);
30,975✔
3922
  if (pArray == NULL) {
30,975!
3923
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3924
    if (terrno != 0) code = terrno;
×
3925
    goto _OVER;
×
3926
  }
3927

3928
  if (taosArrayGetSize(pArray) < 2) {
30,975!
3929
    mInfo("no need to balance vgroup since dnode num less than 2");
×
3930
    code = 0;
×
3931
  } else {
3932
    code = mndBalanceVgroup(pMnode, pReq, pArray);
30,975✔
3933
  }
3934

3935
  auditRecord(pReq, pMnode->clusterId, "balanceVgroup", "", "", req.sql, req.sqlLen);
30,975✔
3936

3937
_OVER:
35,416✔
3938
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
35,416!
3939
    mError("failed to balance vgroup since %s", tstrerror(code));
14,836!
3940
  }
3941

3942
  taosArrayDestroy(pArray);
35,416✔
3943
  tFreeSBalanceVgroupReq(&req);
35,416✔
3944
  TAOS_RETURN(code);
35,416✔
3945
}
3946

3947
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; }
355,681,592✔
3948

3949
bool mndVgroupInDnode(SVgObj *pVgroup, int32_t dnodeId) {
15,800✔
3950
  for (int i = 0; i < pVgroup->replica; i++) {
41,472✔
3951
    if (pVgroup->vnodeGid[i].dnodeId == dnodeId) return true;
35,547✔
3952
  }
3953
  return false;
5,925✔
3954
}
3955

3956
static void *mndBuildCompactVnodeReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen, int64_t compactTs,
216,386✔
3957
                                     STimeWindow tw, bool metaOnly, ETsdbOpType type, ETriggerType triggerType) {
3958
  SCompactVnodeReq compactReq = {0};
216,386✔
3959
  compactReq.dbUid = pDb->uid;
216,386✔
3960
  compactReq.compactStartTime = compactTs;
216,386✔
3961
  compactReq.tw = tw;
216,386✔
3962
  compactReq.metaOnly = metaOnly;
216,386✔
3963
  compactReq.optrType = type;
216,386✔
3964
  compactReq.triggerType = triggerType;
216,386✔
3965
  tstrncpy(compactReq.db, pDb->name, TSDB_DB_FNAME_LEN);
216,386!
3966

3967
  mInfo("vgId:%d, build compact vnode config req", pVgroup->vgId);
216,386!
3968
  int32_t contLen = tSerializeSCompactVnodeReq(NULL, 0, &compactReq);
216,386✔
3969
  if (contLen < 0) {
216,386!
3970
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3971
    return NULL;
×
3972
  }
3973
  contLen += sizeof(SMsgHead);
216,386✔
3974

3975
  void *pReq = taosMemoryMalloc(contLen);
216,386!
3976
  if (pReq == NULL) {
216,386!
3977
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3978
    return NULL;
×
3979
  }
3980

3981
  SMsgHead *pHead = pReq;
216,386✔
3982
  pHead->contLen = htonl(contLen);
216,386✔
3983
  pHead->vgId = htonl(pVgroup->vgId);
216,386✔
3984

3985
  if (tSerializeSCompactVnodeReq((char *)pReq + sizeof(SMsgHead), contLen, &compactReq) < 0) {
216,386!
3986
    taosMemoryFree(pReq);
×
3987
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3988
    return NULL;
×
3989
  }
3990
  *pContLen = contLen;
216,386✔
3991
  return pReq;
216,386✔
3992
}
3993

3994
static int32_t mndAddCompactVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t compactTs,
131,719✔
3995
                                        STimeWindow tw, bool metaOnly, ETsdbOpType type, ETriggerType triggerType) {
3996
  int32_t      code = 0;
131,719✔
3997
  STransAction action = {0};
131,719✔
3998
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
131,719✔
3999

4000
  int32_t contLen = 0;
131,719✔
4001
  void   *pReq = mndBuildCompactVnodeReq(pMnode, pDb, pVgroup, &contLen, compactTs, tw, metaOnly, type, triggerType);
131,719✔
4002
  if (pReq == NULL) {
131,719!
4003
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4004
    if (terrno != 0) code = terrno;
×
4005
    TAOS_RETURN(code);
×
4006
  }
4007

4008
  action.pCont = pReq;
131,719✔
4009
  action.contLen = contLen;
131,719✔
4010
  action.msgType = TDMT_VND_COMPACT;
131,719✔
4011

4012
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
131,719!
4013
    taosMemoryFree(pReq);
×
4014
    TAOS_RETURN(code);
×
4015
  }
4016

4017
  TAOS_RETURN(code);
131,719✔
4018
}
4019

4020
int32_t mndBuildCompactVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t compactTs,
131,719✔
4021
                                    STimeWindow tw, bool metaOnly, ETsdbOpType type, ETriggerType triggerType) {
4022
  TAOS_CHECK_RETURN(mndAddCompactVnodeAction(pMnode, pTrans, pDb, pVgroup, compactTs, tw, metaOnly, type, triggerType));
131,719!
4023
  return 0;
131,719✔
4024
}
4025

4026
int32_t mndBuildTrimVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t startTs,
84,667✔
4027
                                 STimeWindow tw, ETsdbOpType type, ETriggerType triggerType) {
4028
  int32_t      code = 0;
84,667✔
4029
  STransAction action = {0};
84,667✔
4030
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
84,667✔
4031

4032
  int32_t contLen = 0;
84,667✔
4033
  // reuse SCompactVnodeReq as SVTrimDbReq
4034
  void *pReq = mndBuildCompactVnodeReq(pMnode, pDb, pVgroup, &contLen, startTs, tw, false, type, triggerType);
84,667✔
4035
  if (pReq == NULL) {
84,667!
4036
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4037
    if (terrno != 0) code = terrno;
×
4038
    TAOS_RETURN(code);
×
4039
  }
4040

4041
  action.pCont = pReq;
84,667✔
4042
  action.contLen = contLen;
84,667✔
4043
  action.msgType = TDMT_VND_TRIM;
84,667✔
4044

4045
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
84,667!
4046
    taosMemoryFree(pReq);
×
4047
    TAOS_RETURN(code);
×
4048
  }
4049

4050
  TAOS_RETURN(code);
84,667✔
4051
}
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