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

taosdata / TDengine / #4914

06 Jan 2026 01:30AM UTC coverage: 64.876% (-0.008%) from 64.884%
#4914

push

travis-ci

web-flow
merge: from main to 3.0 branch #34167

180 of 319 new or added lines in 14 files covered. (56.43%)

3475 existing lines in 124 files now uncovered.

194993 of 300563 relevant lines covered (64.88%)

116239151.85 hits per line

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

67.62
/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 "mndVgroup.h"
18
#include "audit.h"
19
#include "mndArbGroup.h"
20
#include "mndDb.h"
21
#include "mndDnode.h"
22
#include "mndEncryptAlgr.h"
23
#include "mndMnode.h"
24
#include "mndPrivilege.h"
25
#include "mndShow.h"
26
#include "mndStb.h"
27
#include "mndStream.h"
28
#include "mndTopic.h"
29
#include "mndTrans.h"
30
#include "mndUser.h"
31
#include "tmisce.h"
32

33
#define VGROUP_VER_COMPAT_MOUNT_KEEP_VER 2
34
#define VGROUP_VER_NUMBER                VGROUP_VER_COMPAT_MOUNT_KEEP_VER
35
#define VGROUP_RESERVE_SIZE              60
36
// since 3.3.6.32/3.3.8.6 mountId + keepVersion + keepVersionTime + VGROUP_RESERVE_SIZE = 4 + 8 + 8 + 60 = 80
37
#define DLEN_AFTER_SYNC_CONF_CHANGE_VER 80
38

39
static int32_t mndVgroupActionInsert(SSdb *pSdb, SVgObj *pVgroup);
40
static int32_t mndVgroupActionDelete(SSdb *pSdb, SVgObj *pVgroup);
41
static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew);
42
static int32_t mndNewVgActionValidate(SMnode *pMnode, STrans *pTrans, SSdbRaw *pRaw);
43

44
static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
45
static void    mndCancelGetNextVgroup(SMnode *pMnode, void *pIter);
46
static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
47
static void    mndCancelGetNextVnode(SMnode *pMnode, void *pIter);
48

49
static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq);
50
static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq);
51
static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq);
52
static int32_t mndProcessVgroupBalanceLeaderMsg(SRpcMsg *pReq);
53
static int32_t mndProcessSetVgroupKeepVersionReq(SRpcMsg *pReq);
54

55
int32_t mndInitVgroup(SMnode *pMnode) {
402,363✔
56
  SSdbTable table = {
402,363✔
57
      .sdbType = SDB_VGROUP,
58
      .keyType = SDB_KEY_INT32,
59
      .encodeFp = (SdbEncodeFp)mndVgroupActionEncode,
60
      .decodeFp = (SdbDecodeFp)mndVgroupActionDecode,
61
      .insertFp = (SdbInsertFp)mndVgroupActionInsert,
62
      .updateFp = (SdbUpdateFp)mndVgroupActionUpdate,
63
      .deleteFp = (SdbDeleteFp)mndVgroupActionDelete,
64
      .validateFp = (SdbValidateFp)mndNewVgActionValidate,
65
  };
66

67
  mndSetMsgHandle(pMnode, TDMT_DND_CREATE_VNODE_RSP, mndTransProcessRsp);
402,363✔
68
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_REPLICA_RSP, mndTransProcessRsp);
402,363✔
69
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_CONFIG_RSP, mndTransProcessRsp);
402,363✔
70
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_CONFIRM_RSP, mndTransProcessRsp);
402,363✔
71
  mndSetMsgHandle(pMnode, TDMT_VND_SET_KEEP_VERSION_RSP, mndTransProcessRsp);
402,363✔
72
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_HASHRANGE_RSP, mndTransProcessRsp);
402,363✔
73
  mndSetMsgHandle(pMnode, TDMT_DND_DROP_VNODE_RSP, mndTransProcessRsp);
402,363✔
74
  mndSetMsgHandle(pMnode, TDMT_VND_COMPACT_RSP, mndTransProcessRsp);
402,363✔
75
  mndSetMsgHandle(pMnode, TDMT_VND_SCAN_RSP, mndTransProcessRsp);
402,363✔
76
  mndSetMsgHandle(pMnode, TDMT_VND_DISABLE_WRITE_RSP, mndTransProcessRsp);
402,363✔
77
  mndSetMsgHandle(pMnode, TDMT_SYNC_FORCE_FOLLOWER_RSP, mndTransProcessRsp);
402,363✔
78
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_ELECTBASELINE_RSP, mndTransProcessRsp);
402,363✔
79
  
80
  mndSetMsgHandle(pMnode, TDMT_DND_ALTER_VNODE_TYPE_RSP, mndTransProcessRsp);
402,363✔
81
  mndSetMsgHandle(pMnode, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP_RSP, mndTransProcessRsp);
402,363✔
82
  mndSetMsgHandle(pMnode, TDMT_SYNC_CONFIG_CHANGE_RSP, mndTransProcessRsp);
402,363✔
83

84
  mndSetMsgHandle(pMnode, TDMT_MND_REDISTRIBUTE_VGROUP, mndProcessRedistributeVgroupMsg);
402,363✔
85
  mndSetMsgHandle(pMnode, TDMT_MND_SPLIT_VGROUP, mndProcessSplitVgroupMsg);
402,363✔
86
  // mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP, mndProcessVgroupBalanceLeaderMsg);
87
  mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP, mndProcessBalanceVgroupMsg);
402,363✔
88
  mndSetMsgHandle(pMnode, TDMT_MND_BALANCE_VGROUP_LEADER, mndProcessVgroupBalanceLeaderMsg);
402,363✔
89
  mndSetMsgHandle(pMnode, TDMT_MND_SET_VGROUP_KEEP_VERSION, mndProcessSetVgroupKeepVersionReq);
402,363✔
90

91
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_VGROUP, mndRetrieveVgroups);
402,363✔
92
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_VGROUP, mndCancelGetNextVgroup);
402,363✔
93
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_VNODES, mndRetrieveVnodes);
402,363✔
94
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_VNODES, mndCancelGetNextVnode);
402,363✔
95

96
  return sdbSetTable(pMnode->pSdb, table);
402,363✔
97
}
98

99
void mndCleanupVgroup(SMnode *pMnode) {}
402,302✔
100

101
SSdbRaw *mndVgroupActionEncode(SVgObj *pVgroup) {
10,342,156✔
102
  int32_t code = 0;
10,342,156✔
103
  int32_t lino = 0;
10,342,156✔
104
  terrno = TSDB_CODE_OUT_OF_MEMORY;
10,342,156✔
105

106
  SSdbRaw *pRaw = sdbAllocRaw(SDB_VGROUP, VGROUP_VER_NUMBER, sizeof(SVgObj) + VGROUP_RESERVE_SIZE);
10,342,156✔
107
  if (pRaw == NULL) goto _OVER;
10,342,156✔
108

109
  int32_t dataPos = 0;
10,342,156✔
110
  SDB_SET_INT32(pRaw, dataPos, pVgroup->vgId, _OVER)
10,342,156✔
111
  SDB_SET_INT64(pRaw, dataPos, pVgroup->createdTime, _OVER)
10,342,156✔
112
  SDB_SET_INT64(pRaw, dataPos, pVgroup->updateTime, _OVER)
10,342,156✔
113
  SDB_SET_INT32(pRaw, dataPos, pVgroup->version, _OVER)
10,342,156✔
114
  SDB_SET_INT32(pRaw, dataPos, pVgroup->hashBegin, _OVER)
10,342,156✔
115
  SDB_SET_INT32(pRaw, dataPos, pVgroup->hashEnd, _OVER)
10,342,156✔
116
  SDB_SET_BINARY(pRaw, dataPos, pVgroup->dbName, TSDB_DB_FNAME_LEN, _OVER)
10,342,156✔
117
  SDB_SET_INT64(pRaw, dataPos, pVgroup->dbUid, _OVER)
10,342,156✔
118
  SDB_SET_INT8(pRaw, dataPos, pVgroup->isTsma, _OVER)
10,342,156✔
119
  SDB_SET_INT8(pRaw, dataPos, pVgroup->replica, _OVER)
10,342,156✔
120
  for (int8_t i = 0; i < pVgroup->replica; ++i) {
22,520,409✔
121
    SVnodeGid *pVgid = &pVgroup->vnodeGid[i];
12,178,253✔
122
    SDB_SET_INT32(pRaw, dataPos, pVgid->dnodeId, _OVER)
12,178,253✔
123
  }
124
  SDB_SET_INT32(pRaw, dataPos, pVgroup->syncConfChangeVer, _OVER)
10,342,156✔
125
  SDB_SET_INT32(pRaw, dataPos, pVgroup->mountVgId, _OVER)
10,342,156✔
126
  SDB_SET_INT64(pRaw, dataPos, pVgroup->keepVersion, _OVER)
10,342,156✔
127
  SDB_SET_INT64(pRaw, dataPos, pVgroup->keepVersionTime, _OVER)
10,342,156✔
128
  SDB_SET_RESERVE(pRaw, dataPos, VGROUP_RESERVE_SIZE, _OVER)
10,342,156✔
129
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
10,342,156✔
130

131
  terrno = 0;
10,342,156✔
132

133
_OVER:
10,342,156✔
134
  if (terrno != 0) {
10,342,156✔
135
    mError("vgId:%d, failed to encode to raw:%p since %s", pVgroup->vgId, pRaw, terrstr());
×
136
    sdbFreeRaw(pRaw);
×
137
    return NULL;
×
138
  }
139

140
  mTrace("vgId:%d, encode to raw:%p, row:%p", pVgroup->vgId, pRaw, pVgroup);
10,342,156✔
141
  return pRaw;
10,342,156✔
142
}
143

144
SSdbRow *mndVgroupActionDecode(SSdbRaw *pRaw) {
9,357,774✔
145
  int32_t code = 0;
9,357,774✔
146
  int32_t lino = 0;
9,357,774✔
147
  terrno = TSDB_CODE_OUT_OF_MEMORY;
9,357,774✔
148
  SSdbRow *pRow = NULL;
9,357,774✔
149
  SVgObj  *pVgroup = NULL;
9,357,774✔
150

151
  int8_t sver = 0;
9,357,774✔
152
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
9,357,774✔
153

154
  if (sver < 1 || sver > VGROUP_VER_NUMBER) {
9,357,774✔
155
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
156
    goto _OVER;
×
157
  }
158

159
  pRow = sdbAllocRow(sizeof(SVgObj));
9,357,774✔
160
  if (pRow == NULL) goto _OVER;
9,357,774✔
161

162
  pVgroup = sdbGetRowObj(pRow);
9,357,774✔
163
  if (pVgroup == NULL) goto _OVER;
9,357,774✔
164

165
  int32_t dataPos = 0;
9,357,774✔
166
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->vgId, _OVER)
9,357,774✔
167
  SDB_GET_INT64(pRaw, dataPos, &pVgroup->createdTime, _OVER)
9,357,774✔
168
  SDB_GET_INT64(pRaw, dataPos, &pVgroup->updateTime, _OVER)
9,357,774✔
169
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->version, _OVER)
9,357,774✔
170
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->hashBegin, _OVER)
9,357,774✔
171
  SDB_GET_INT32(pRaw, dataPos, &pVgroup->hashEnd, _OVER)
9,357,774✔
172
  SDB_GET_BINARY(pRaw, dataPos, pVgroup->dbName, TSDB_DB_FNAME_LEN, _OVER)
9,357,774✔
173
  SDB_GET_INT64(pRaw, dataPos, &pVgroup->dbUid, _OVER)
9,357,774✔
174
  SDB_GET_INT8(pRaw, dataPos, &pVgroup->isTsma, _OVER)
9,357,774✔
175
  SDB_GET_INT8(pRaw, dataPos, &pVgroup->replica, _OVER)
9,357,774✔
176
  for (int8_t i = 0; i < pVgroup->replica; ++i) {
20,508,453✔
177
    SVnodeGid *pVgid = &pVgroup->vnodeGid[i];
11,150,679✔
178
    SDB_GET_INT32(pRaw, dataPos, &pVgid->dnodeId, _OVER)
11,150,679✔
179
    if (pVgroup->replica == 1) {
11,150,679✔
180
      pVgid->syncState = TAOS_SYNC_STATE_LEADER;
8,421,346✔
181
    }
182
  }
183
  if (dataPos + 2 * sizeof(int32_t) + VGROUP_RESERVE_SIZE <= pRaw->dataLen) {
9,357,774✔
184
    SDB_GET_INT32(pRaw, dataPos, &pVgroup->syncConfChangeVer, _OVER)
9,357,774✔
185
  }
186

187
  int32_t dlenAfterSyncConfChangeVer = pRaw->dataLen - dataPos;
9,357,774✔
188
  if (dataPos + sizeof(int32_t) + VGROUP_RESERVE_SIZE <= pRaw->dataLen) {
9,357,774✔
189
    SDB_GET_INT32(pRaw, dataPos, &pVgroup->mountVgId, _OVER)
9,357,774✔
190
  }
191
  if (dataPos + sizeof(int64_t) + VGROUP_RESERVE_SIZE <= pRaw->dataLen) {
9,357,774✔
192
    SDB_GET_INT64(pRaw, dataPos, &pVgroup->keepVersion, _OVER)
9,357,774✔
193
  }
194
  if (dataPos + sizeof(int64_t) + VGROUP_RESERVE_SIZE <= pRaw->dataLen) {
9,357,774✔
195
    SDB_GET_INT64(pRaw, dataPos, &pVgroup->keepVersionTime, _OVER)
9,357,774✔
196
  }
197
  if (dataPos + VGROUP_RESERVE_SIZE <= pRaw->dataLen) {
9,357,774✔
198
    SDB_GET_RESERVE(pRaw, dataPos, VGROUP_RESERVE_SIZE, _OVER)
9,357,774✔
199
  }
200

201
  if (sver < VGROUP_VER_COMPAT_MOUNT_KEEP_VER) {
9,357,774✔
202
    if (dlenAfterSyncConfChangeVer == DLEN_AFTER_SYNC_CONF_CHANGE_VER) {
×
203
      pVgroup->mountVgId = 0;
×
204
    }
205
    pVgroup->keepVersion = -1;
×
206
    pVgroup->keepVersionTime = 0;
×
207
  }
208

209
  terrno = 0;
9,357,774✔
210

211
_OVER:
9,357,774✔
212
  if (terrno != 0) {
9,357,774✔
213
    mError("vgId:%d, failed to decode from raw:%p since %s", pVgroup == NULL ? 0 : pVgroup->vgId, pRaw, terrstr());
×
214
    taosMemoryFreeClear(pRow);
×
215
    return NULL;
×
216
  }
217

218
  mTrace("vgId:%d, decode from raw:%p, row:%p", pVgroup->vgId, pRaw, pVgroup);
9,357,774✔
219
  return pRow;
9,357,774✔
220
}
221

222
static int32_t mndNewVgActionValidate(SMnode *pMnode, STrans *pTrans, SSdbRaw *pRaw) {
2,445,667✔
223
  SSdb    *pSdb = pMnode->pSdb;
2,445,667✔
224
  SSdbRow *pRow = NULL;
2,445,667✔
225
  SVgObj  *pVgroup = NULL;
2,445,667✔
226
  int      code = -1;
2,445,667✔
227

228
  pRow = mndVgroupActionDecode(pRaw);
2,445,667✔
229
  if (pRow == NULL) {
2,445,667✔
230
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
231
    if (terrno != 0) code = terrno;
×
232
    goto _OVER;
×
233
  }
234
  pVgroup = sdbGetRowObj(pRow);
2,445,667✔
235
  if (pVgroup == NULL) {
2,445,667✔
236
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
237
    if (terrno != 0) code = terrno;
×
238
    goto _OVER;
×
239
  }
240

241
  int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
2,445,667✔
242
  if (maxVgId > pVgroup->vgId) {
2,445,667✔
243
    mError("trans:%d, vgroup id %d already in use. maxVgId:%d", pTrans->id, pVgroup->vgId, maxVgId);
×
244
    goto _OVER;
×
245
  }
246

247
  code = 0;
2,445,667✔
248
_OVER:
2,445,667✔
249
  if (pVgroup) mndVgroupActionDelete(pSdb, pVgroup);
2,445,667✔
250
  taosMemoryFreeClear(pRow);
2,445,667✔
251
  TAOS_RETURN(code);
2,445,667✔
252
}
253

254
static int32_t mndVgroupActionInsert(SSdb *pSdb, SVgObj *pVgroup) {
2,738,632✔
255
  mTrace("vgId:%d, perform insert action, row:%p", pVgroup->vgId, pVgroup);
2,738,632✔
256
  return 0;
2,738,632✔
257
}
258

259
static int32_t mndVgroupActionDelete(SSdb *pSdb, SVgObj *pVgroup) {
9,347,342✔
260
  mTrace("vgId:%d, perform delete action, row:%p", pVgroup->vgId, pVgroup);
9,347,342✔
261
  return 0;
9,347,342✔
262
}
263

264
static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew) {
2,836,766✔
265
  mTrace("vgId:%d, perform update action, old row:%p new row:%p", pOld->vgId, pOld, pNew);
2,836,766✔
266
  pOld->updateTime = pNew->updateTime;
2,836,766✔
267
  pOld->version = pNew->version;
2,836,766✔
268
  pOld->hashBegin = pNew->hashBegin;
2,836,766✔
269
  pOld->hashEnd = pNew->hashEnd;
2,836,766✔
270
  pOld->replica = pNew->replica;
2,836,766✔
271
  pOld->isTsma = pNew->isTsma;
2,836,766✔
272
  pOld->keepVersion = pNew->keepVersion;
2,836,766✔
273
  pOld->keepVersionTime = pNew->keepVersionTime;
2,836,766✔
274
  for (int32_t i = 0; i < pNew->replica; ++i) {
6,600,387✔
275
    SVnodeGid *pNewGid = &pNew->vnodeGid[i];
3,763,621✔
276
    for (int32_t j = 0; j < pOld->replica; ++j) {
10,369,094✔
277
      SVnodeGid *pOldGid = &pOld->vnodeGid[j];
6,605,473✔
278
      if (pNewGid->dnodeId == pOldGid->dnodeId) {
6,605,473✔
279
        pNewGid->syncState = pOldGid->syncState;
3,541,010✔
280
        pNewGid->syncRestore = pOldGid->syncRestore;
3,541,010✔
281
        pNewGid->syncCanRead = pOldGid->syncCanRead;
3,541,010✔
282
        pNewGid->syncAppliedIndex = pOldGid->syncAppliedIndex;
3,541,010✔
283
        pNewGid->syncCommitIndex = pOldGid->syncCommitIndex;
3,541,010✔
284
        pNewGid->bufferSegmentUsed = pOldGid->bufferSegmentUsed;
3,541,010✔
285
        pNewGid->bufferSegmentSize = pOldGid->bufferSegmentSize;
3,541,010✔
286
      }
287
    }
288
  }
289
  pNew->numOfTables = pOld->numOfTables;
2,836,766✔
290
  pNew->numOfTimeSeries = pOld->numOfTimeSeries;
2,836,766✔
291
  pNew->totalStorage = pOld->totalStorage;
2,836,766✔
292
  pNew->compStorage = pOld->compStorage;
2,836,766✔
293
  pNew->pointsWritten = pOld->pointsWritten;
2,836,766✔
294
  pNew->compact = pOld->compact;
2,836,766✔
295
  memcpy(pOld->vnodeGid, pNew->vnodeGid, (TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA) * sizeof(SVnodeGid));
2,836,766✔
296
  pOld->syncConfChangeVer = pNew->syncConfChangeVer;
2,836,766✔
297
  tstrncpy(pOld->dbName, pNew->dbName, TSDB_DB_FNAME_LEN);
2,836,766✔
298
  return 0;
2,836,766✔
299
}
300

301
SVgObj *mndAcquireVgroup(SMnode *pMnode, int32_t vgId) {
116,153,167✔
302
  SSdb   *pSdb = pMnode->pSdb;
116,153,167✔
303
  SVgObj *pVgroup = sdbAcquire(pSdb, SDB_VGROUP, &vgId);
116,153,167✔
304
  if (pVgroup == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
116,153,167✔
305
    terrno = TSDB_CODE_MND_VGROUP_NOT_EXIST;
939,557✔
306
  }
307
  return pVgroup;
116,153,167✔
308
}
309

310
void mndReleaseVgroup(SMnode *pMnode, SVgObj *pVgroup) {
115,407,312✔
311
  SSdb *pSdb = pMnode->pSdb;
115,407,312✔
312
  sdbRelease(pSdb, pVgroup);
115,407,312✔
313
}
115,407,312✔
314

315
void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen) {
2,722,340✔
316
  SCreateVnodeReq createReq = {0};
2,722,340✔
317
  createReq.vgId = pVgroup->vgId;
2,722,340✔
318
  memcpy(createReq.db, pDb->name, TSDB_DB_FNAME_LEN);
2,722,340✔
319
  createReq.dbUid = pDb->uid;
2,722,340✔
320
  createReq.vgVersion = pVgroup->version;
2,722,340✔
321
  createReq.numOfStables = pDb->cfg.numOfStables;
2,722,340✔
322
  createReq.buffer = pDb->cfg.buffer;
2,722,340✔
323
  createReq.pageSize = pDb->cfg.pageSize;
2,722,340✔
324
  createReq.pages = pDb->cfg.pages;
2,722,340✔
325
  createReq.cacheLastSize = pDb->cfg.cacheLastSize;
2,722,340✔
326
  createReq.daysPerFile = pDb->cfg.daysPerFile;
2,722,340✔
327
  createReq.daysToKeep0 = pDb->cfg.daysToKeep0;
2,722,340✔
328
  createReq.daysToKeep1 = pDb->cfg.daysToKeep1;
2,722,340✔
329
  createReq.daysToKeep2 = pDb->cfg.daysToKeep2;
2,722,340✔
330
  createReq.keepTimeOffset = pDb->cfg.keepTimeOffset;
2,722,340✔
331
  createReq.ssChunkSize = pDb->cfg.ssChunkSize;
2,722,340✔
332
  createReq.ssKeepLocal = pDb->cfg.ssKeepLocal;
2,722,340✔
333
  createReq.ssCompact = pDb->cfg.ssCompact;
2,722,340✔
334
  createReq.minRows = pDb->cfg.minRows;
2,722,340✔
335
  createReq.maxRows = pDb->cfg.maxRows;
2,722,340✔
336
  createReq.walFsyncPeriod = pDb->cfg.walFsyncPeriod;
2,722,340✔
337
  createReq.walLevel = pDb->cfg.walLevel;
2,722,340✔
338
  createReq.precision = pDb->cfg.precision;
2,722,340✔
339
  createReq.compression = pDb->cfg.compression;
2,722,340✔
340
  createReq.strict = pDb->cfg.strict;
2,722,340✔
341
  createReq.cacheLast = pDb->cfg.cacheLast;
2,722,340✔
342
  createReq.replica = 0;
2,722,340✔
343
  createReq.learnerReplica = 0;
2,722,340✔
344
  createReq.selfIndex = -1;
2,722,340✔
345
  createReq.learnerSelfIndex = -1;
2,722,340✔
346
  createReq.hashBegin = pVgroup->hashBegin;
2,722,340✔
347
  createReq.hashEnd = pVgroup->hashEnd;
2,722,340✔
348
  createReq.hashMethod = pDb->cfg.hashMethod;
2,722,340✔
349
  createReq.numOfRetensions = pDb->cfg.numOfRetensions;
2,722,340✔
350
  createReq.pRetensions = pDb->cfg.pRetensions;
2,722,340✔
351
  createReq.isTsma = pVgroup->isTsma;
2,722,340✔
352
  createReq.pTsma = pVgroup->pTsma;
2,722,340✔
353
  createReq.walRetentionPeriod = pDb->cfg.walRetentionPeriod;
2,722,340✔
354
  createReq.walRetentionSize = pDb->cfg.walRetentionSize;
2,722,340✔
355
  createReq.walRollPeriod = pDb->cfg.walRollPeriod;
2,722,340✔
356
  createReq.walSegmentSize = pDb->cfg.walSegmentSize;
2,722,340✔
357
  createReq.sstTrigger = pDb->cfg.sstTrigger;
2,722,340✔
358
  createReq.hashPrefix = pDb->cfg.hashPrefix;
2,722,340✔
359
  createReq.hashSuffix = pDb->cfg.hashSuffix;
2,722,340✔
360
  createReq.tsdbPageSize = pDb->cfg.tsdbPageSize;
2,722,340✔
361
  createReq.changeVersion = ++(pVgroup->syncConfChangeVer);
2,722,340✔
362
  // createReq.encryptAlgorithm = pDb->cfg.encryptAlgorithm;
363
  memset(createReq.encryptAlgrName, 0, TSDB_ENCRYPT_ALGR_NAME_LEN);
2,722,340✔
364
  if (pDb->cfg.encryptAlgorithm > 0) {
2,722,340✔
365
    mndGetEncryptOsslAlgrNameById(pMnode, pDb->cfg.encryptAlgorithm, createReq.encryptAlgrName);
×
366
  }
367
  int32_t code = 0;
2,722,340✔
368

369
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
6,489,759✔
370
    SReplica *pReplica = NULL;
3,767,419✔
371

372
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,767,419✔
373
      pReplica = &createReq.replicas[createReq.replica];
3,662,384✔
374
    } else {
375
      pReplica = &createReq.learnerReplicas[createReq.learnerReplica];
105,035✔
376
    }
377

378
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
3,767,419✔
379
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
3,767,419✔
380
    if (pVgidDnode == NULL) {
3,767,419✔
381
      return NULL;
×
382
    }
383

384
    pReplica->id = pVgidDnode->id;
3,767,419✔
385
    pReplica->port = pVgidDnode->port;
3,767,419✔
386
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
3,767,419✔
387
    mndReleaseDnode(pMnode, pVgidDnode);
3,767,419✔
388

389
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,767,419✔
390
      if (pDnode->id == pVgid->dnodeId) {
3,662,384✔
391
        createReq.selfIndex = createReq.replica;
2,617,305✔
392
      }
393
    } else {
394
      if (pDnode->id == pVgid->dnodeId) {
105,035✔
395
        createReq.learnerSelfIndex = createReq.learnerReplica;
105,035✔
396
      }
397
    }
398

399
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,767,419✔
400
      createReq.replica++;
3,662,384✔
401
    } else {
402
      createReq.learnerReplica++;
105,035✔
403
    }
404
  }
405

406
  if (createReq.selfIndex == -1 && createReq.learnerSelfIndex == -1) {
2,722,340✔
407
    terrno = TSDB_CODE_APP_ERROR;
×
408
    return NULL;
×
409
  }
410

411
  createReq.changeVersion = pVgroup->syncConfChangeVer;
2,722,340✔
412

413
  mInfo(
2,722,340✔
414
      "vgId:%d, build create vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
415
      "changeVersion:%d",
416
      createReq.vgId, createReq.replica, createReq.selfIndex, createReq.learnerReplica, createReq.learnerSelfIndex,
417
      createReq.strict, createReq.changeVersion);
418
  for (int32_t i = 0; i < createReq.replica; ++i) {
6,384,724✔
419
    mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.replicas[i].fqdn, createReq.replicas[i].port);
3,662,384✔
420
  }
421
  for (int32_t i = 0; i < createReq.learnerReplica; ++i) {
2,827,375✔
422
    mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.learnerReplicas[i].fqdn,
105,035✔
423
          createReq.learnerReplicas[i].port);
424
  }
425

426
  int32_t contLen = tSerializeSCreateVnodeReq(NULL, 0, &createReq);
2,722,340✔
427
  if (contLen < 0) {
2,722,340✔
428
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
429
    return NULL;
×
430
  }
431

432
  void *pReq = taosMemoryMalloc(contLen);
2,722,340✔
433
  if (pReq == NULL) {
2,722,340✔
434
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
435
    return NULL;
×
436
  }
437

438
  code = tSerializeSCreateVnodeReq(pReq, contLen, &createReq);
2,722,340✔
439
  if (code < 0) {
2,722,340✔
440
    terrno = TSDB_CODE_APP_ERROR;
×
441
    taosMemoryFree(pReq);
×
442
    mError("vgId:%d, failed to serialize create vnode req,since %s", createReq.vgId, terrstr());
×
443
    return NULL;
×
444
  }
445
  *pContLen = contLen;
2,722,340✔
446
  return pReq;
2,722,340✔
447
}
448

449
static void *mndBuildAlterVnodeConfigReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen) {
189,839✔
450
  SAlterVnodeConfigReq alterReq = {0};
189,839✔
451
  alterReq.vgVersion = pVgroup->version;
189,839✔
452
  alterReq.buffer = pDb->cfg.buffer;
189,839✔
453
  alterReq.pageSize = pDb->cfg.pageSize;
189,839✔
454
  alterReq.pages = pDb->cfg.pages;
189,839✔
455
  alterReq.cacheLastSize = pDb->cfg.cacheLastSize;
189,839✔
456
  alterReq.daysPerFile = pDb->cfg.daysPerFile;
189,839✔
457
  alterReq.daysToKeep0 = pDb->cfg.daysToKeep0;
189,839✔
458
  alterReq.daysToKeep1 = pDb->cfg.daysToKeep1;
189,839✔
459
  alterReq.daysToKeep2 = pDb->cfg.daysToKeep2;
189,839✔
460
  alterReq.keepTimeOffset = pDb->cfg.keepTimeOffset;
189,839✔
461
  alterReq.walFsyncPeriod = pDb->cfg.walFsyncPeriod;
189,839✔
462
  alterReq.walLevel = pDb->cfg.walLevel;
189,839✔
463
  alterReq.strict = pDb->cfg.strict;
189,839✔
464
  alterReq.cacheLast = pDb->cfg.cacheLast;
189,839✔
465
  alterReq.sttTrigger = pDb->cfg.sstTrigger;
189,839✔
466
  alterReq.minRows = pDb->cfg.minRows;
189,839✔
467
  alterReq.walRetentionPeriod = pDb->cfg.walRetentionPeriod;
189,839✔
468
  alterReq.walRetentionSize = pDb->cfg.walRetentionSize;
189,839✔
469
  alterReq.ssKeepLocal = pDb->cfg.ssKeepLocal;
189,839✔
470
  alterReq.ssCompact = pDb->cfg.ssCompact;
189,839✔
471

472
  mInfo("vgId:%d, build alter vnode config req", pVgroup->vgId);
189,839✔
473
  int32_t contLen = tSerializeSAlterVnodeConfigReq(NULL, 0, &alterReq);
189,839✔
474
  if (contLen < 0) {
189,839✔
475
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
476
    return NULL;
×
477
  }
478
  contLen += sizeof(SMsgHead);
189,839✔
479

480
  void *pReq = taosMemoryMalloc(contLen);
189,839✔
481
  if (pReq == NULL) {
189,839✔
482
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
483
    return NULL;
×
484
  }
485

486
  SMsgHead *pHead = pReq;
189,839✔
487
  pHead->contLen = htonl(contLen);
189,839✔
488
  pHead->vgId = htonl(pVgroup->vgId);
189,839✔
489

490
  if (tSerializeSAlterVnodeConfigReq((char *)pReq + sizeof(SMsgHead), contLen, &alterReq) < 0) {
189,839✔
491
    taosMemoryFree(pReq);
×
492
    mError("vgId:%d, failed to serialize alter vnode config req,since %s", pVgroup->vgId, terrstr());
×
493
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
494
    return NULL;
×
495
  }
496
  *pContLen = contLen;
189,839✔
497
  return pReq;
189,839✔
498
}
499

500
static void *mndBuildAlterVnodeReplicaReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId,
795,926✔
501
                                          int32_t *pContLen) {
502
  SAlterVnodeReplicaReq alterReq = {
1,591,852✔
503
      .vgId = pVgroup->vgId,
795,926✔
504
      .strict = pDb->cfg.strict,
795,926✔
505
      .replica = 0,
506
      .learnerReplica = 0,
507
      .selfIndex = -1,
508
      .learnerSelfIndex = -1,
509
      .changeVersion = ++(pVgroup->syncConfChangeVer),
1,591,852✔
510
  };
511

512
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
3,256,931✔
513
    SReplica *pReplica = NULL;
2,461,005✔
514

515
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
2,461,005✔
516
      pReplica = &alterReq.replicas[alterReq.replica];
2,267,718✔
517
      alterReq.replica++;
2,267,718✔
518
    } else {
519
      pReplica = &alterReq.learnerReplicas[alterReq.learnerReplica];
193,287✔
520
      alterReq.learnerReplica++;
193,287✔
521
    }
522

523
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
2,461,005✔
524
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
2,461,005✔
525
    if (pVgidDnode == NULL) return NULL;
2,461,005✔
526

527
    pReplica->id = pVgidDnode->id;
2,461,005✔
528
    pReplica->port = pVgidDnode->port;
2,461,005✔
529
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
2,461,005✔
530
    mndReleaseDnode(pMnode, pVgidDnode);
2,461,005✔
531

532
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
2,461,005✔
533
      if (dnodeId == pVgid->dnodeId) {
2,267,718✔
534
        alterReq.selfIndex = v;
795,926✔
535
      }
536
    } else {
537
      if (dnodeId == pVgid->dnodeId) {
193,287✔
538
        alterReq.learnerSelfIndex = v;
×
539
      }
540
    }
541
  }
542

543
  mInfo(
795,926✔
544
      "vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
545
      "changeVersion:%d",
546
      alterReq.vgId, alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica, alterReq.learnerSelfIndex,
547
      alterReq.strict, alterReq.changeVersion);
548
  for (int32_t i = 0; i < alterReq.replica; ++i) {
3,063,644✔
549
    mInfo("vgId:%d, replica:%d ep:%s:%u", alterReq.vgId, i, alterReq.replicas[i].fqdn, alterReq.replicas[i].port);
2,267,718✔
550
  }
551
  for (int32_t i = 0; i < alterReq.learnerReplica; ++i) {
989,213✔
552
    mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", alterReq.vgId, i, alterReq.learnerReplicas[i].fqdn,
193,287✔
553
          alterReq.learnerReplicas[i].port);
554
  }
555

556
  if (alterReq.selfIndex == -1 && alterReq.learnerSelfIndex == -1) {
795,926✔
557
    terrno = TSDB_CODE_APP_ERROR;
×
558
    return NULL;
×
559
  }
560

561
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &alterReq);
795,926✔
562
  if (contLen < 0) {
795,926✔
563
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
564
    return NULL;
×
565
  }
566

567
  void *pReq = taosMemoryMalloc(contLen);
795,926✔
568
  if (pReq == NULL) {
795,926✔
569
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
570
    return NULL;
×
571
  }
572

573
  if (tSerializeSAlterVnodeReplicaReq(pReq, contLen, &alterReq) < 0) {
795,926✔
574
    mError("vgId:%d, failed to serialize alter vnode req,since %s", alterReq.vgId, terrstr());
×
575
    taosMemoryFree(pReq);
×
576
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
577
    return NULL;
×
578
  }
579
  *pContLen = contLen;
795,926✔
580
  return pReq;
795,926✔
581
}
582

583
static void *mndBuildCheckLearnCatchupReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId,
×
584
                                          int32_t *pContLen) {
585
  SCheckLearnCatchupReq req = {
×
586
      .vgId = pVgroup->vgId,
×
587
      .strict = pDb->cfg.strict,
×
588
      .replica = 0,
589
      .learnerReplica = 0,
590
      .selfIndex = -1,
591
      .learnerSelfIndex = -1,
592
  };
593

594
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
×
595
    SReplica *pReplica = NULL;
×
596

597
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
×
598
      pReplica = &req.replicas[req.replica];
×
599
      req.replica++;
×
600
    } else {
601
      pReplica = &req.learnerReplicas[req.learnerReplica];
×
602
      req.learnerReplica++;
×
603
    }
604

605
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
×
606
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
×
607
    if (pVgidDnode == NULL) return NULL;
×
608

609
    pReplica->id = pVgidDnode->id;
×
610
    pReplica->port = pVgidDnode->port;
×
611
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
×
612
    mndReleaseDnode(pMnode, pVgidDnode);
×
613

614
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
×
615
      if (dnodeId == pVgid->dnodeId) {
×
616
        req.selfIndex = v;
×
617
      }
618
    } else {
619
      if (dnodeId == pVgid->dnodeId) {
×
620
        req.learnerSelfIndex = v;
×
621
      }
622
    }
623
  }
624

625
  mInfo("vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d",
×
626
        req.vgId, req.replica, req.selfIndex, req.learnerReplica, req.learnerSelfIndex, req.strict);
627
  for (int32_t i = 0; i < req.replica; ++i) {
×
628
    mInfo("vgId:%d, replica:%d ep:%s:%u", req.vgId, i, req.replicas[i].fqdn, req.replicas[i].port);
×
629
  }
630
  for (int32_t i = 0; i < req.learnerReplica; ++i) {
×
631
    mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", req.vgId, i, req.learnerReplicas[i].fqdn, req.learnerReplicas[i].port);
×
632
  }
633

634
  if (req.selfIndex == -1 && req.learnerSelfIndex == -1) {
×
635
    terrno = TSDB_CODE_APP_ERROR;
×
636
    return NULL;
×
637
  }
638

639
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &req);
×
640
  if (contLen < 0) {
×
641
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
642
    return NULL;
×
643
  }
644

645
  void *pReq = taosMemoryMalloc(contLen);
×
646
  if (pReq == NULL) {
×
647
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
648
    return NULL;
×
649
  }
650

651
  if (tSerializeSAlterVnodeReplicaReq(pReq, contLen, &req) < 0) {
×
652
    mError("vgId:%d, failed to serialize alter vnode req,since %s", req.vgId, terrstr());
×
653
    taosMemoryFree(pReq);
×
654
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
655
    return NULL;
×
656
  }
657
  *pContLen = contLen;
×
658
  return pReq;
×
659
}
660

661
static void *mndBuildDisableVnodeWriteReq(SMnode *pMnode, SDbObj *pDb, int32_t vgId, int32_t *pContLen) {
32,486✔
662
  SDisableVnodeWriteReq disableReq = {
32,486✔
663
      .vgId = vgId,
664
      .disable = 1,
665
  };
666

667
  mInfo("vgId:%d, build disable vnode write req", vgId);
32,486✔
668
  int32_t contLen = tSerializeSDisableVnodeWriteReq(NULL, 0, &disableReq);
32,486✔
669
  if (contLen < 0) {
32,486✔
670
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
671
    return NULL;
×
672
  }
673

674
  void *pReq = taosMemoryMalloc(contLen);
32,486✔
675
  if (pReq == NULL) {
32,486✔
676
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
677
    return NULL;
×
678
  }
679

680
  if (tSerializeSDisableVnodeWriteReq(pReq, contLen, &disableReq) < 0) {
32,486✔
681
    mError("vgId:%d, failed to serialize disable vnode write req,since %s", vgId, terrstr());
×
682
    taosMemoryFree(pReq);
×
683
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
684
    return NULL;
×
685
  }
686
  *pContLen = contLen;
32,486✔
687
  return pReq;
32,486✔
688
}
689

690
static void *mndBuildAlterVnodeHashRangeReq(SMnode *pMnode, int32_t srcVgId, SVgObj *pVgroup, int32_t *pContLen) {
32,486✔
691
  SAlterVnodeHashRangeReq alterReq = {
64,972✔
692
      .srcVgId = srcVgId,
693
      .dstVgId = pVgroup->vgId,
32,486✔
694
      .hashBegin = pVgroup->hashBegin,
32,486✔
695
      .hashEnd = pVgroup->hashEnd,
32,486✔
696
      .changeVersion = ++(pVgroup->syncConfChangeVer),
64,972✔
697
  };
698

699
  mInfo("vgId:%d, build alter vnode hashrange req, dstVgId:%d, hashrange:[%u, %u]", srcVgId, pVgroup->vgId,
32,486✔
700
        pVgroup->hashBegin, pVgroup->hashEnd);
701
  int32_t contLen = tSerializeSAlterVnodeHashRangeReq(NULL, 0, &alterReq);
32,486✔
702
  if (contLen < 0) {
32,486✔
703
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
704
    return NULL;
×
705
  }
706

707
  void *pReq = taosMemoryMalloc(contLen);
32,486✔
708
  if (pReq == NULL) {
32,486✔
709
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
710
    return NULL;
×
711
  }
712

713
  if (tSerializeSAlterVnodeHashRangeReq(pReq, contLen, &alterReq) < 0) {
32,486✔
714
    mError("vgId:%d, failed to serialize alter vnode hashrange req,since %s", srcVgId, terrstr());
×
715
    taosMemoryFree(pReq);
×
716
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
717
    return NULL;
×
718
  }
719
  *pContLen = contLen;
32,486✔
720
  return pReq;
32,486✔
721
}
722

723
void *mndBuildDropVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen) {
4,030,037✔
724
  SDropVnodeReq dropReq = {0};
4,030,037✔
725
  dropReq.dnodeId = pDnode->id;
4,030,037✔
726
  dropReq.vgId = pVgroup->vgId;
4,030,037✔
727
  memcpy(dropReq.db, pDb->name, TSDB_DB_FNAME_LEN);
4,030,037✔
728
  dropReq.dbUid = pDb->uid;
4,030,037✔
729

730
  mInfo("vgId:%d, build drop vnode req", dropReq.vgId);
4,030,037✔
731
  int32_t contLen = tSerializeSDropVnodeReq(NULL, 0, &dropReq);
4,030,037✔
732
  if (contLen < 0) {
4,030,037✔
733
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
734
    return NULL;
×
735
  }
736

737
  void *pReq = taosMemoryMalloc(contLen);
4,030,037✔
738
  if (pReq == NULL) {
4,030,037✔
739
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
740
    return NULL;
×
741
  }
742

743
  if (tSerializeSDropVnodeReq(pReq, contLen, &dropReq) < 0) {
4,030,037✔
744
    mError("vgId:%d, failed to serialize drop vnode req,since %s", dropReq.vgId, terrstr());
×
745
    taosMemoryFree(pReq);
×
746
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
747
    return NULL;
×
748
  }
749
  *pContLen = contLen;
4,030,037✔
750
  return pReq;
4,030,037✔
751
}
752

753
static bool mndResetDnodesArrayFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
1,782,339✔
754
  SDnodeObj *pDnode = pObj;
1,782,339✔
755
  pDnode->numOfVnodes = 0;
1,782,339✔
756
  pDnode->numOfOtherNodes = 0;
1,782,339✔
757
  return true;
1,782,339✔
758
}
759

760
static bool mndBuildDnodesArrayFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
1,782,339✔
761
  SDnodeObj *pDnode = pObj;
1,782,339✔
762
  SArray    *pArray = p1;
1,782,339✔
763
  int32_t    exceptDnodeId = *(int32_t *)p2;
1,782,339✔
764
  SArray    *dnodeList = p3;
1,782,339✔
765

766
  if (exceptDnodeId == pDnode->id) {
1,782,339✔
767
    return true;
7,126✔
768
  }
769

770
  if (dnodeList != NULL) {
1,775,213✔
771
    int32_t dnodeListSize = taosArrayGetSize(dnodeList);
67,937✔
772
    if (dnodeListSize > 0) {
67,937✔
773
      bool inDnodeList = false;
67,937✔
774
      for (int32_t index = 0; index < dnodeListSize; ++index) {
221,386✔
775
        int32_t dnodeId = *(int32_t *)taosArrayGet(dnodeList, index);
153,449✔
776
        if (pDnode->id == dnodeId) {
153,449✔
777
          inDnodeList = true;
31,381✔
778
        }
779
      }
780
      if (!inDnodeList) {
67,937✔
781
        return true;
36,556✔
782
      }
783
    } else {
784
      return true;  // TS-6191
×
785
    }
786
  }
787

788
  int64_t curMs = taosGetTimestampMs();
1,738,657✔
789
  bool    online = mndIsDnodeOnline(pDnode, curMs);
1,738,657✔
790
  bool    isMnode = mndIsMnode(pMnode, pDnode->id);
1,738,657✔
791
  pDnode->numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
1,738,657✔
792
  pDnode->memUsed = mndGetVnodesMemory(pMnode, pDnode->id);
1,738,657✔
793

794
  mInfo("dnode:%d, vnodes:%d supportVnodes:%d isMnode:%d online:%d memory avail:%" PRId64 " used:%" PRId64, pDnode->id,
1,738,657✔
795
        pDnode->numOfVnodes, pDnode->numOfSupportVnodes, isMnode, online, pDnode->memAvail, pDnode->memUsed);
796

797
  if (isMnode) {
1,738,657✔
798
    pDnode->numOfOtherNodes++;
1,236,230✔
799
  }
800

801
  if (online && pDnode->numOfSupportVnodes > 0) {
1,738,657✔
802
    if (taosArrayPush(pArray, pDnode) == NULL) return false;
1,694,022✔
803
  }
804
  return true;
1,738,657✔
805
}
806

807
static bool isDnodeInList(SArray *dnodeList, int32_t dnodeId) {
×
808
  int32_t dnodeListSize = taosArrayGetSize(dnodeList);
×
809
  for (int32_t i = 0; i < dnodeListSize; ++i) {
×
810
    int32_t id = *(int32_t *)TARRAY_GET_ELEM(dnodeList, i);
×
811
    if (id == dnodeId) {
×
812
      return true;
×
813
    }
814
  }
815
  return false;
×
816
}
817

818
#ifdef TD_ENTERPRISE
819
static float mndGetDnodeScore1(SDnodeObj *pDnode, int32_t additionDnodes, float ratio) {
×
820
  float totalDnodes = pDnode->numOfVnodes + (float)pDnode->numOfOtherNodes * ratio + additionDnodes;
×
821
  float result = totalDnodes / pDnode->numOfSupportVnodes;
×
822
  return pDnode->numOfVnodes > 0 ? -result : result;
×
823
}
824

825
static int32_t mndCompareDnodeVnodes1(SDnodeObj *pDnode1, SDnodeObj *pDnode2) {
×
826
  float d1Score = mndGetDnodeScore1(pDnode1, 0, 0.9);
×
827
  float d2Score = mndGetDnodeScore1(pDnode2, 0, 0.9);
×
828
  if (d1Score == d2Score) {
×
829
    if (pDnode1->id == pDnode2->id) {
×
830
      return 0;
×
831
    }
832
    return pDnode1->id > pDnode2->id ? 1 : -1;
×
833
  }
834
  return d1Score > d2Score ? 1 : -1;
×
835
}
836

837
static bool mndBuildDnodesListFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
×
838
  SDnodeObj *pDnode = pObj;
×
839
  SArray    *pArray = p1;
×
840

841
  bool isMnode = mndIsMnode(pMnode, pDnode->id);
×
842
  pDnode->numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
×
843

844
  if (isMnode) {
×
845
    pDnode->numOfOtherNodes++;
×
846
  }
847

848
  if (pDnode->numOfSupportVnodes > 0) {
×
849
    if (taosArrayPush(pArray, pDnode) == NULL) return false;
×
850
  }
851
  return true;
×
852
}
853

854
// TS-6191
855
static int32_t mndBuildNodesCheckDualReplica(SMnode *pMnode, int32_t nDnodes, SArray *dnodeList, SArray **ppDnodeList) {
1,204,801✔
856
  int32_t code = 0;
1,204,801✔
857
  if (!grantCheckDualReplicaDnodes(pMnode)) {
1,204,801✔
858
    TAOS_RETURN(code);
1,204,801✔
859
  }
860
  SSdb   *pSdb = pMnode->pSdb;
×
861
  SArray *pArray = taosArrayInit(nDnodes, sizeof(SDnodeObj));
×
862
  if (pArray == NULL) {
×
863
    TAOS_RETURN(code = terrno);
×
864
  }
865
  *ppDnodeList = pArray;
×
866

867
  sdbTraverse(pSdb, SDB_DNODE, mndResetDnodesArrayFp, NULL, NULL, NULL);
×
868
  sdbTraverse(pSdb, SDB_DNODE, mndBuildDnodesListFp, pArray, NULL, NULL);
×
869

870
  int32_t arrSize = taosArrayGetSize(pArray);
×
871
  if (arrSize <= 0) {
×
872
    TAOS_RETURN(code);
×
873
  }
874
  if (arrSize > 1) taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes1);
×
875

876
  int32_t dnodeListSize = taosArrayGetSize(dnodeList);
×
877
  if (dnodeListSize <= 0) {
×
878
    if (arrSize > 2) taosArrayRemoveBatch(pArray, 2, arrSize - 2, NULL);
×
879
  } else {
880
    int32_t nDnodesWithVnodes = 0;
×
881
    for (int32_t i = 0; i < arrSize; ++i) {
×
882
      SDnodeObj *pDnode = TARRAY_GET_ELEM(pArray, i);
×
883
      if (pDnode->numOfVnodes <= 0) {
×
884
        break;
×
885
      }
886
      ++nDnodesWithVnodes;
×
887
    }
888
    int32_t dnodeId = -1;
×
889
    if (nDnodesWithVnodes == 1) {
×
890
      dnodeId = ((SDnodeObj *)TARRAY_GET_ELEM(pArray, 0))->id;
×
891
    } else if (nDnodesWithVnodes >= 2) {
×
892
      // must select the dnodes from the 1st 2 dnodes
893
      taosArrayRemoveBatch(pArray, 2, arrSize - 2, NULL);
×
894
    }
895
    for (int32_t i = 0; i < TARRAY_SIZE(pArray);) {
×
896
      SDnodeObj *pDnode = taosArrayGet(pArray, i);
×
897
      if (!isDnodeInList(dnodeList, pDnode->id)) {
×
898
        taosArrayRemove(pArray, i);
×
899
        continue;
×
900
      }
901
      ++i;
×
902
    }
903
    if (nDnodesWithVnodes == 1) {
×
904
      SDnodeObj *pDnode = taosArrayGet(pArray, 0);
×
905
      if (pDnode && (pDnode->id != dnodeId)) {  // the first dnode is not in dnodeList, remove the last element
×
906
        taosArrayRemove(pArray, taosArrayGetSize(pArray) - 1);
×
907
      }
908
    }
909
  }
910

911
  TAOS_RETURN(code);
×
912
}
913
#endif
914

915
SArray *mndBuildDnodesArray(SMnode *pMnode, int32_t exceptDnodeId, SArray *dnodeList) {
1,204,801✔
916
  SSdb   *pSdb = pMnode->pSdb;
1,204,801✔
917
  int32_t numOfDnodes = mndGetDnodeSize(pMnode);
1,204,801✔
918
  SArray *tDnodeList = NULL;
1,204,801✔
919
  SArray *pDnodeList = NULL;
1,204,801✔
920

921
  SArray *pArray = taosArrayInit(numOfDnodes, sizeof(SDnodeObj));
1,204,801✔
922
  if (pArray == NULL) {
1,204,801✔
923
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
924
    return NULL;
×
925
  }
926
  if (taosArrayGetSize(dnodeList) > 0) {
1,204,801✔
927
    tDnodeList = dnodeList;
13,933✔
928
  }
929
#ifdef TD_ENTERPRISE
930
  if (0 != mndBuildNodesCheckDualReplica(pMnode, numOfDnodes, tDnodeList, &pDnodeList)) {
1,204,801✔
931
    taosArrayDestroy(pArray);
×
932
    return NULL;
×
933
  }
934
#endif
935
  sdbTraverse(pSdb, SDB_DNODE, mndResetDnodesArrayFp, NULL, NULL, NULL);
1,204,801✔
936
  sdbTraverse(pSdb, SDB_DNODE, mndBuildDnodesArrayFp, pArray, &exceptDnodeId, pDnodeList ? pDnodeList : tDnodeList);
1,204,801✔
937

938
  mDebug("build %d dnodes array", (int32_t)taosArrayGetSize(pArray));
1,204,801✔
939
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
2,898,823✔
940
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
1,694,022✔
941
    mDebug("dnode:%d, vnodes:%d others:%d", pDnode->id, pDnode->numOfVnodes, pDnode->numOfOtherNodes);
1,694,022✔
942
  }
943
  taosArrayDestroy(pDnodeList);
1,204,801✔
944
  return pArray;
1,204,801✔
945
}
946

947
static int32_t mndCompareDnodeId(int32_t *dnode1Id, int32_t *dnode2Id) {
×
948
  if (*dnode1Id == *dnode2Id) {
×
949
    return 0;
×
950
  }
951
  return *dnode1Id > *dnode2Id ? 1 : -1;
×
952
}
953

954
static float mndGetDnodeScore(SDnodeObj *pDnode, int32_t additionDnodes, float ratio) {
8,768,149✔
955
  float totalDnodes = pDnode->numOfVnodes + (float)pDnode->numOfOtherNodes * ratio + additionDnodes;
8,768,149✔
956
  return totalDnodes / pDnode->numOfSupportVnodes;
8,768,149✔
957
}
958

959
static int32_t mndCompareDnodeVnodes(SDnodeObj *pDnode1, SDnodeObj *pDnode2) {
2,741,531✔
960
  float d1Score = mndGetDnodeScore(pDnode1, 0, 0.9);
2,741,531✔
961
  float d2Score = mndGetDnodeScore(pDnode2, 0, 0.9);
2,741,531✔
962
  if (d1Score == d2Score) {
2,741,531✔
963
    return 0;
910,037✔
964
  }
965
  return d1Score > d2Score ? 1 : -1;
1,831,494✔
966
}
967

968
void mndSortVnodeGid(SVgObj *pVgroup) {
2,352,423✔
969
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
5,016,836✔
970
    for (int32_t j = 0; j < pVgroup->replica - 1 - i; ++j) {
3,128,702✔
971
      if (pVgroup->vnodeGid[j].dnodeId > pVgroup->vnodeGid[j + 1].dnodeId) {
464,289✔
972
        TSWAP(pVgroup->vnodeGid[j], pVgroup->vnodeGid[j + 1]);
213,898✔
973
      }
974
    }
975
  }
976
}
2,352,423✔
977

978
static int32_t mndGetAvailableDnode(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, SArray *pArray) {
2,324,485✔
979
  mDebug("start to sort %d dnodes", (int32_t)taosArrayGetSize(pArray));
2,324,485✔
980
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
2,324,485✔
981
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
5,522,095✔
982
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
3,197,610✔
983
    mDebug("dnode:%d, score:%f", pDnode->id, mndGetDnodeScore(pDnode, 0, 0.9));
3,197,610✔
984
  }
985

986
  int32_t size = taosArrayGetSize(pArray);
2,324,485✔
987
  if (size < pVgroup->replica) {
2,324,485✔
988
    mError("db:%s, vgId:%d, no enough online dnodes:%d to alloc %d replica", pVgroup->dbName, pVgroup->vgId, size,
4,465✔
989
           pVgroup->replica);
990
    TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
4,465✔
991
  }
992

993
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
4,895,432✔
994
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
2,575,412✔
995
    SDnodeObj *pDnode = taosArrayGet(pArray, v);
2,575,412✔
996
    if (pDnode == NULL) {
2,575,412✔
997
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
×
998
    }
999
    if (pDnode->numOfVnodes >= pDnode->numOfSupportVnodes) {
2,575,412✔
1000
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_VNODES);
×
1001
    }
1002

1003
    int64_t vgMem = mndGetVgroupMemory(pMnode, pDb, pVgroup);
2,575,412✔
1004
    if (pDnode->memAvail - vgMem - pDnode->memUsed <= 0) {
2,575,412✔
1005
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d, avail:%" PRId64 " used:%" PRId64,
×
1006
             pVgroup->dbName, pVgroup->vgId, vgMem, pDnode->id, pDnode->memAvail, pDnode->memUsed);
1007
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
1008
    } else {
1009
      pDnode->memUsed += vgMem;
2,575,412✔
1010
    }
1011

1012
    pVgid->dnodeId = pDnode->id;
2,575,412✔
1013
    if (pVgroup->replica == 1) {
2,575,412✔
1014
      pVgid->syncState = TAOS_SYNC_STATE_LEADER;
2,189,314✔
1015
    } else {
1016
      pVgid->syncState = TAOS_SYNC_STATE_FOLLOWER;
386,098✔
1017
    }
1018

1019
    mInfo("db:%s, vgId:%d, vn:%d is alloced, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
2,575,412✔
1020
          pVgroup->dbName, pVgroup->vgId, v, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
1021
    pDnode->numOfVnodes++;
2,575,412✔
1022
  }
1023

1024
  mndSortVnodeGid(pVgroup);
2,320,020✔
1025
  return 0;
2,320,020✔
1026
}
1027

1028
int32_t mndAllocSmaVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup) {
×
1029
  int32_t code = 0;
×
1030
  SArray *pArray = mndBuildDnodesArray(pMnode, 0, NULL);
×
1031
  if (pArray == NULL) {
×
1032
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1033
    if (terrno != 0) code = terrno;
×
1034
    TAOS_RETURN(code);
×
1035
  }
1036

1037
  pVgroup->vgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
×
1038
  pVgroup->isTsma = 1;
×
1039
  pVgroup->createdTime = taosGetTimestampMs();
×
1040
  pVgroup->updateTime = pVgroup->createdTime;
×
1041
  pVgroup->version = 1;
×
1042
  memcpy(pVgroup->dbName, pDb->name, TSDB_DB_FNAME_LEN);
×
1043
  pVgroup->dbUid = pDb->uid;
×
1044
  pVgroup->replica = 1;
×
1045
  pVgroup->keepVersion = -1;  // default: WAL keep version disabled
×
1046
  pVgroup->keepVersionTime = 0;
×
1047

1048
  if (mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray) != 0) return -1;
×
1049
  taosArrayDestroy(pArray);
×
1050

1051
  mInfo("db:%s, sma vgId:%d is alloced", pDb->name, pVgroup->vgId);
×
1052
  return 0;
×
1053
}
1054

1055
int32_t mndAllocVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj **ppVgroups, SArray *dnodeList) {
1,089,661✔
1056
  int32_t code = -1;
1,089,661✔
1057
  SArray *pArray = NULL;
1,089,661✔
1058
  SVgObj *pVgroups = NULL;
1,089,661✔
1059

1060
  pVgroups = taosMemoryCalloc(pDb->cfg.numOfVgroups, sizeof(SVgObj));
1,089,661✔
1061
  if (pVgroups == NULL) {
1,089,661✔
1062
    code = terrno;
×
1063
    goto _OVER;
×
1064
  }
1065

1066
  pArray = mndBuildDnodesArray(pMnode, 0, dnodeList);
1,089,661✔
1067
  if (pArray == NULL) {
1,089,661✔
1068
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1069
    if (terrno != 0) code = terrno;
×
1070
    goto _OVER;
×
1071
  }
1072

1073
  mInfo("db:%s, total %d dnodes used to create %d vgroups (%d vnodes)", pDb->name, (int32_t)taosArrayGetSize(pArray),
1,089,661✔
1074
        pDb->cfg.numOfVgroups, pDb->cfg.numOfVgroups * pDb->cfg.replications);
1075

1076
  int32_t  allocedVgroups = 0;
1,089,661✔
1077
  int32_t  maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
1,089,661✔
1078
  uint32_t hashMin = 0;
1,089,661✔
1079
  uint32_t hashMax = UINT32_MAX;
1,089,661✔
1080
  uint32_t hashInterval = (hashMax - hashMin) / pDb->cfg.numOfVgroups;
1,089,661✔
1081

1082
  if (maxVgId < 2) maxVgId = 2;
1,089,661✔
1083

1084
  for (uint32_t v = 0; v < pDb->cfg.numOfVgroups; v++) {
3,409,681✔
1085
    SVgObj *pVgroup = &pVgroups[v];
2,324,485✔
1086
    pVgroup->vgId = maxVgId++;
2,324,485✔
1087
    pVgroup->createdTime = taosGetTimestampMs();
2,324,485✔
1088
    pVgroup->updateTime = pVgroups->createdTime;
2,324,485✔
1089
    pVgroup->version = 1;
2,324,485✔
1090
    pVgroup->hashBegin = hashMin + hashInterval * v;
2,324,485✔
1091
    if (v == pDb->cfg.numOfVgroups - 1) {
2,324,485✔
1092
      pVgroup->hashEnd = hashMax;
1,087,387✔
1093
    } else {
1094
      pVgroup->hashEnd = hashMin + hashInterval * (v + 1) - 1;
1,237,098✔
1095
    }
1096

1097
    memcpy(pVgroup->dbName, pDb->name, TSDB_DB_FNAME_LEN);
2,324,485✔
1098
    pVgroup->dbUid = pDb->uid;
2,324,485✔
1099
    pVgroup->replica = pDb->cfg.replications;
2,324,485✔
1100
    pVgroup->keepVersion = -1;  // default: WAL keep version disabled
2,324,485✔
1101
    pVgroup->keepVersionTime = 0;
2,324,485✔
1102

1103
    if ((code = mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray)) != 0) {
2,324,485✔
1104
      goto _OVER;
4,465✔
1105
    }
1106

1107
    allocedVgroups++;
2,320,020✔
1108
  }
1109

1110
  *ppVgroups = pVgroups;
1,085,196✔
1111
  code = 0;
1,085,196✔
1112

1113
  mInfo("db:%s, total %d vgroups is alloced, replica:%d", pDb->name, pDb->cfg.numOfVgroups, pDb->cfg.replications);
1,085,196✔
1114

1115
_OVER:
×
1116
  if (code != 0) taosMemoryFree(pVgroups);
1,089,661✔
1117
  taosArrayDestroy(pArray);
1,089,661✔
1118
  TAOS_RETURN(code);
1,089,661✔
1119
}
1120

1121
SEpSet mndGetVgroupEpset(SMnode *pMnode, const SVgObj *pVgroup) {
26,073,386✔
1122
  SEpSet epset = {0};
26,073,386✔
1123

1124
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
58,792,997✔
1125
    const SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
32,719,611✔
1126
    SDnodeObj       *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
32,719,611✔
1127
    if (pDnode == NULL) continue;
32,719,611✔
1128

1129
    if (pVgid->syncState == TAOS_SYNC_STATE_LEADER || pVgid->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
32,706,735✔
1130
      epset.inUse = epset.numOfEps;
25,684,033✔
1131
    }
1132

1133
    if (addEpIntoEpSet(&epset, pDnode->fqdn, pDnode->port) != 0) {
32,706,735✔
1134
      mWarn("vgId:%d, failed to add ep:%s:%d into epset", pVgroup->vgId, pDnode->fqdn, pDnode->port);
×
1135
    }
1136
    mndReleaseDnode(pMnode, pDnode);
32,706,735✔
1137
  }
1138
  epsetSort(&epset);
26,073,386✔
1139

1140
  return epset;
26,073,386✔
1141
}
1142

1143
SEpSet mndGetVgroupEpsetById(SMnode *pMnode, int32_t vgId) {
493,641✔
1144
  SEpSet epset = {0};
493,641✔
1145

1146
  SVgObj *pVgroup = mndAcquireVgroup(pMnode, vgId);
493,641✔
1147
  if (!pVgroup) return epset;
493,641✔
1148

1149
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
1,047,107✔
1150
    const SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
553,466✔
1151
    SDnodeObj       *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
553,466✔
1152
    if (pDnode == NULL) continue;
553,466✔
1153

1154
    if (pVgid->syncState == TAOS_SYNC_STATE_LEADER || pVgid->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
553,297✔
1155
      epset.inUse = epset.numOfEps;
465,146✔
1156
    }
1157

1158
    if (addEpIntoEpSet(&epset, pDnode->fqdn, pDnode->port) != 0) {
553,297✔
1159
      mWarn("vgId:%d, failed to add ep:%s:%d into epset", pVgroup->vgId, pDnode->fqdn, pDnode->port);
×
1160
    }
1161
    mndReleaseDnode(pMnode, pDnode);
553,297✔
1162
  }
1163

1164
  mndReleaseVgroup(pMnode, pVgroup);
493,641✔
1165
  return epset;
493,641✔
1166
}
1167

1168
static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
281,955✔
1169
  SMnode   *pMnode = pReq->info.node;
281,955✔
1170
  SSdb     *pSdb = pMnode->pSdb;
281,955✔
1171
  int32_t   numOfRows = 0;
281,955✔
1172
  SVgObj   *pVgroup = NULL;
281,955✔
1173
  SDbObj   *pVgDb = NULL;
281,955✔
1174
  int32_t   cols = 0;
281,955✔
1175
  int64_t   curMs = taosGetTimestampMs();
281,955✔
1176
  int32_t   code = 0, lino = 0;
281,955✔
1177
  SDbObj   *pDb = NULL;
281,955✔
1178
  SUserObj *pUser = NULL;
281,955✔
1179
  SDbObj   *pIterDb = NULL;
281,955✔
1180
  char      objFName[TSDB_OBJ_FNAME_LEN + 1] = {0};
281,955✔
1181
  bool      showAll = false, showIter = false;
281,955✔
1182
  int64_t   dbUid = 0;
281,955✔
1183

1184
  MND_SHOW_CHECK_OBJ_PRIVILEGE_ALL(RPC_MSG_USER(pReq), PRIV_SHOW_VGROUPS, PRIV_OBJ_DB, 0, _OVER);
281,955✔
1185

1186
  if (strlen(pShow->db) > 0) {
281,955✔
1187
    pDb = mndAcquireDb(pMnode, pShow->db);
248,433✔
1188
    if (pDb == NULL) {
248,433✔
1189
      goto _OVER;
×
1190
    }
1191
  }
1192

1193
  while (numOfRows < rows) {
1,572,563✔
1194
    pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
1,572,563✔
1195
    if (pShow->pIter == NULL) break;
1,572,563✔
1196

1197
    if (pDb != NULL && pVgroup->dbUid != pDb->uid) {
1,291,413✔
1198
      sdbRelease(pSdb, pVgroup);
431,563✔
1199
      continue;
431,563✔
1200
    }
1201

1202
    MND_SHOW_CHECK_DB_PRIVILEGE(pDb, pVgroup->dbName, pVgroup, RPC_MSG_TOKEN(pReq), MND_OPER_SHOW_VGROUPS, _OVER);
859,850✔
1203

1204
    cols = 0;
857,757✔
1205
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1206
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->vgId, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1207

1208
    SName name = {0};
857,757✔
1209
    char  db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
857,757✔
1210
    code = tNameFromString(&name, pVgroup->dbName, T_NAME_ACCT | T_NAME_DB);
857,757✔
1211
    if (code != 0) {
857,757✔
1212
      mError("vgId:%d, failed to set dbName, since %s", pVgroup->vgId, tstrerror(code));
×
1213
      sdbRelease(pSdb, pVgroup);
×
1214
      // sdbCancelFetch(pSdb, pShow->pIter);
1215
      goto _OVER;
×
1216
    }
1217
    (void)tNameGetDbName(&name, varDataVal(db));
857,757✔
1218
    varDataSetLen(db, strlen(varDataVal(db)));
857,757✔
1219

1220
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1221
    COL_DATA_SET_VAL_GOTO((const char *)db, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1222

1223
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1224
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->numOfTables, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1225

1226
    bool isReady = false;
857,757✔
1227
    bool isLeaderRestored = false;
857,757✔
1228
    bool hasFollowerRestored = false;
857,757✔
1229
    ESyncState leaderState = TAOS_SYNC_STATE_OFFLINE;
857,757✔
1230
    // default 3 replica, add 1 replica if move vnode
1231
    for (int32_t i = 0; i < 4; ++i) {
4,288,785✔
1232
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,431,028✔
1233
      if (i < pVgroup->replica) {
3,431,028✔
1234
        int16_t dnodeId = (int16_t)pVgroup->vnodeGid[i].dnodeId;
1,848,246✔
1235
        COL_DATA_SET_VAL_GOTO((const char *)&dnodeId, false, pVgroup, pShow->pIter, _OVER);
1,848,246✔
1236

1237
        bool       exist = false;
1,848,246✔
1238
        bool       online = false;
1,848,246✔
1239
        SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId);
1,848,246✔
1240
        if (pDnode != NULL) {
1,848,246✔
1241
          exist = true;
1,848,246✔
1242
          online = mndIsDnodeOnline(pDnode, curMs);
1,848,246✔
1243
          mndReleaseDnode(pMnode, pDnode);
1,848,246✔
1244
        }
1245

1246
        char buf1[20] = {0};
1,848,246✔
1247
        char role[20] = "offline";
1,848,246✔
1248
        if (!exist) {
1,848,246✔
1249
          tstrncpy(role, "dropping", sizeof(role));
×
1250
        } else if (online) {
1,848,246✔
1251
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER ||
1,830,751✔
1252
              pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
1,184,821✔
1253
            if (pVgroup->vnodeGid[i].syncRestore) {
645,930✔
1254
              isLeaderRestored = true;
565,375✔
1255
            }
1256
          } else if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_FOLLOWER) {
1,184,821✔
1257
            if (pVgroup->vnodeGid[i].syncRestore) {
982,589✔
1258
              hasFollowerRestored = true;
570,707✔
1259
            }
1260
          }
1261
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER ||
1,830,751✔
1262
              pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER)
1,184,821✔
1263
            leaderState = pVgroup->vnodeGid[i].syncState;
645,930✔
1264
          snprintf(role, sizeof(role), "%s", syncStr(pVgroup->vnodeGid[i].syncState));
1,830,751✔
1265
          /*
1266
          mInfo("db:%s, learner progress:%d", pDb->name, pVgroup->vnodeGid[i].learnerProgress);
1267

1268
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEARNER) {
1269
            if(pVgroup->vnodeGid[i].learnerProgress < 0){
1270
              snprintf(role, sizeof(role), "%s-",
1271
                syncStr(pVgroup->vnodeGid[i].syncState));
1272

1273
            }
1274
            else if(pVgroup->vnodeGid[i].learnerProgress >= 100){
1275
              snprintf(role, sizeof(role), "%s--",
1276
                syncStr(pVgroup->vnodeGid[i].syncState));
1277
            }
1278
            else{
1279
              snprintf(role, sizeof(role), "%s%d",
1280
                syncStr(pVgroup->vnodeGid[i].syncState), pVgroup->vnodeGid[i].learnerProgress);
1281
            }
1282
          }
1283
          else{
1284
            snprintf(role, sizeof(role), "%s%s", syncStr(pVgroup->vnodeGid[i].syncState), star);
1285
          }
1286
          */
1287
        } else {
1288
        }
1289
        STR_WITH_MAXSIZE_TO_VARSTR(buf1, role, pShow->pMeta->pSchemas[cols].bytes);
1,848,246✔
1290

1291
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,848,246✔
1292
        COL_DATA_SET_VAL_GOTO((const char *)buf1, false, pVgroup, pShow->pIter, _OVER);
1,848,246✔
1293

1294
        char applyStr[TSDB_SYNC_APPLY_COMMIT_LEN + 1] = {0};
1,848,246✔
1295
        char buf[TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE + 1] = {0};
1,848,246✔
1296
        snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64, pVgroup->vnodeGid[i].syncAppliedIndex,
1,848,246✔
1297
                 pVgroup->vnodeGid[i].syncCommitIndex);
1,848,246✔
1298
        STR_WITH_MAXSIZE_TO_VARSTR(buf, applyStr, pShow->pMeta->pSchemas[cols].bytes);
1,848,246✔
1299

1300
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,848,246✔
1301
        COL_DATA_SET_VAL_GOTO((const char *)&buf, false, pVgroup, pShow->pIter, _OVER);
1,848,246✔
1302
      } else {
1303
        colDataSetNULL(pColInfo, numOfRows);
1,582,782✔
1304
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,582,782✔
1305
        colDataSetNULL(pColInfo, numOfRows);
1,582,782✔
1306
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,582,782✔
1307
        colDataSetNULL(pColInfo, numOfRows);
1,582,782✔
1308
      }
1309
    }
1310

1311
    if (pVgroup->replica >= 3) {
857,757✔
1312
      if (isLeaderRestored && hasFollowerRestored) isReady = true;
389,535✔
1313
    } else if (pVgroup->replica == 2) {
468,222✔
1314
      if (leaderState == TAOS_SYNC_STATE_LEADER) {
211,419✔
1315
        if (isLeaderRestored && hasFollowerRestored) isReady = true;
83,778✔
1316
      } else if (leaderState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
127,641✔
1317
        if (isLeaderRestored) isReady = true;
×
1318
      }
1319
    } else {
1320
      if (isLeaderRestored) isReady = true;
256,803✔
1321
    }
1322
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1323
    COL_DATA_SET_VAL_GOTO((const char *)&isReady, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1324

1325
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1326
    int64_t cacheUsage = (int64_t)pVgroup->cacheUsage;
857,757✔
1327
    COL_DATA_SET_VAL_GOTO((const char *)&cacheUsage, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1328

1329
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1330
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->numOfCachedTables, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1331

1332
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1333
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->isTsma, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1334

1335
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1336
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->mountVgId, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1337

1338
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1339
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->keepVersion, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1340

1341
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
857,757✔
1342
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->keepVersionTime, false, pVgroup, pShow->pIter, _OVER);
857,757✔
1343

1344
    numOfRows++;
857,757✔
1345
    sdbRelease(pSdb, pVgroup);
857,757✔
1346
  }
1347
_OVER:
281,955✔
1348
  if (pUser) mndReleaseUser(pMnode, pUser);
281,955✔
1349
  if (pDb != NULL) {
281,955✔
1350
    mndReleaseDb(pMnode, pDb);
248,433✔
1351
  }
1352
  if (code != 0) {
281,955✔
1353
    mError("failed to retrieve vgroup info at line %d since %s", lino, tstrerror(code));
×
1354
    TAOS_RETURN(code);
×
1355
  }
1356

1357
  pShow->numOfRows += numOfRows;
281,955✔
1358
  return numOfRows;
281,955✔
1359
}
1360

1361
static void mndCancelGetNextVgroup(SMnode *pMnode, void *pIter) {
805✔
1362
  SSdb *pSdb = pMnode->pSdb;
805✔
1363
  sdbCancelFetchByType(pSdb, pIter, SDB_VGROUP);
805✔
1364
}
805✔
1365

1366
static bool mndGetVnodesNumFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
9,324,377✔
1367
  SVgObj  *pVgroup = pObj;
9,324,377✔
1368
  int32_t  dnodeId = *(int32_t *)p1;
9,324,377✔
1369
  int32_t *pNumOfVnodes = (int32_t *)p2;
9,324,377✔
1370

1371
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
24,675,188✔
1372
    if (pVgroup->vnodeGid[v].dnodeId == dnodeId) {
15,350,811✔
1373
      (*pNumOfVnodes)++;
6,073,058✔
1374
    }
1375
  }
1376

1377
  return true;
9,324,377✔
1378
}
1379

1380
int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId) {
3,650,414✔
1381
  int32_t numOfVnodes = 0;
3,650,414✔
1382
  sdbTraverse(pMnode->pSdb, SDB_VGROUP, mndGetVnodesNumFp, &dnodeId, &numOfVnodes, NULL);
3,650,414✔
1383
  return numOfVnodes;
3,650,414✔
1384
}
1385

1386
int64_t mndGetVgroupMemory(SMnode *pMnode, SDbObj *pDbInput, SVgObj *pVgroup) {
7,648,307✔
1387
  SDbObj *pDb = pDbInput;
7,648,307✔
1388
  if (pDbInput == NULL) {
7,648,307✔
1389
    pDb = mndAcquireDb(pMnode, pVgroup->dbName);
4,460,485✔
1390
  }
1391

1392
  int64_t vgroupMemroy = 0;
7,648,307✔
1393
  if (pDb != NULL) {
7,648,307✔
1394
    int64_t buffer = (int64_t)pDb->cfg.buffer * 1024 * 1024;
7,648,307✔
1395
    int64_t cache = (int64_t)pDb->cfg.pages * pDb->cfg.pageSize * 1024;
7,648,307✔
1396
    vgroupMemroy = buffer + cache;
7,648,307✔
1397
    int64_t cacheLast = (int64_t)pDb->cfg.cacheLastSize * 1024 * 1024;
7,648,307✔
1398
    if (pDb->cfg.cacheLast > 0) {
7,648,307✔
1399
      vgroupMemroy += cacheLast;
976,622✔
1400
    }
1401
    mDebug("db:%s, vgroup:%d, buffer:%" PRId64 " cache:%" PRId64 " cacheLast:%" PRId64, pDb->name, pVgroup->vgId,
7,648,307✔
1402
           buffer, cache, cacheLast);
1403
  }
1404

1405
  if (pDbInput == NULL) {
7,648,307✔
1406
    mndReleaseDb(pMnode, pDb);
4,460,485✔
1407
  }
1408
  return vgroupMemroy;
7,648,307✔
1409
}
1410

1411
static bool mndGetVnodeMemroyFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
6,198,481✔
1412
  SVgObj  *pVgroup = pObj;
6,198,481✔
1413
  int32_t  dnodeId = *(int32_t *)p1;
6,198,481✔
1414
  int64_t *pVnodeMemory = (int64_t *)p2;
6,198,481✔
1415

1416
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
14,473,612✔
1417
    if (pVgroup->vnodeGid[v].dnodeId == dnodeId) {
8,275,131✔
1418
      *pVnodeMemory += mndGetVgroupMemory(pMnode, NULL, pVgroup);
4,313,753✔
1419
    }
1420
  }
1421

1422
  return true;
6,198,481✔
1423
}
1424

1425
int64_t mndGetVnodesMemory(SMnode *pMnode, int32_t dnodeId) {
1,738,916✔
1426
  int64_t vnodeMemory = 0;
1,738,916✔
1427
  sdbTraverse(pMnode->pSdb, SDB_VGROUP, mndGetVnodeMemroyFp, &dnodeId, &vnodeMemory, NULL);
1,738,916✔
1428
  return vnodeMemory;
1,738,916✔
1429
}
1430

UNCOV
1431
void calculateRstoreFinishTime(double rate, int64_t applyCount, char *restoreStr, size_t restoreStrSize) {
×
UNCOV
1432
  if (rate == 0) {
×
UNCOV
1433
    snprintf(restoreStr, restoreStrSize, "0:0:0");
×
UNCOV
1434
    return;
×
1435
  }
1436

1437
  int64_t costTime = applyCount / rate;
×
1438
  int64_t totalSeconds = costTime / 1000;
×
1439
  int64_t hours = totalSeconds / 3600;
×
1440
  totalSeconds %= 3600;
×
1441
  int64_t minutes = totalSeconds / 60;
×
1442
  int64_t seconds = totalSeconds % 60;
×
1443
  snprintf(restoreStr, restoreStrSize, "%" PRId64 ":%" PRId64 ":%" PRId64, hours, minutes, seconds);
×
1444
}
1445

1446
static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
12,778✔
1447
  SMnode   *pMnode = pReq->info.node;
12,778✔
1448
  SSdb     *pSdb = pMnode->pSdb;
12,778✔
1449
  int32_t   numOfRows = 0;
12,778✔
1450
  SVgObj   *pVgroup = NULL;
12,778✔
1451
  SDbObj   *pVgDb = NULL;
12,778✔
1452
  int32_t   cols = 0;
12,778✔
1453
  int64_t   curMs = taosGetTimestampMs();
12,778✔
1454
  int32_t   code = 0, lino = 0;
12,778✔
1455
  SUserObj *pUser = NULL;
12,778✔
1456
  SDbObj   *pDb = NULL, *pIterDb = NULL;
12,778✔
1457
  char      objFName[TSDB_OBJ_FNAME_LEN + 1] = {0};
12,778✔
1458
  bool      showAll = false, showIter = false;
12,778✔
1459
  int64_t   dbUid = 0;
12,778✔
1460

1461
  MND_SHOW_CHECK_OBJ_PRIVILEGE_ALL(RPC_MSG_USER(pReq), PRIV_SHOW_VNODES, PRIV_OBJ_DB, 0, _OVER);
12,778✔
1462

1463
  while (numOfRows < rows - TSDB_MAX_REPLICA) {
37,927✔
1464
    pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
37,927✔
1465
    if (pShow->pIter == NULL) break;
37,927✔
1466

1467
    MND_SHOW_CHECK_DB_PRIVILEGE(pDb, pVgroup->dbName, pVgroup, RPC_MSG_TOKEN(pReq), MND_OPER_SHOW_VNODES, _OVER);
25,149✔
1468

1469
    for (int32_t i = 0; i < pVgroup->replica && numOfRows < rows; ++i) {
73,077✔
1470
      SVnodeGid       *pGid = &pVgroup->vnodeGid[i];
47,928✔
1471
      SColumnInfoData *pColInfo = NULL;
47,928✔
1472
      cols = 0;
47,928✔
1473

1474
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1475
      COL_DATA_SET_VAL_GOTO((const char *)&pGid->dnodeId, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1476
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1477
      COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->vgId, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1478

1479
      // db_name
1480
      const char *dbname = mndGetDbStr(pVgroup->dbName);
47,928✔
1481
      char        b1[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
47,928✔
1482
      if (dbname != NULL) {
47,928✔
1483
        STR_WITH_MAXSIZE_TO_VARSTR(b1, dbname, TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE);
47,928✔
1484
      } else {
1485
        STR_WITH_MAXSIZE_TO_VARSTR(b1, "NULL", TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE);
×
1486
      }
1487
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1488
      COL_DATA_SET_VAL_GOTO((const char *)b1, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1489

1490
      // dnode is online?
1491
      SDnodeObj *pDnode = mndAcquireDnode(pMnode, pGid->dnodeId);
47,928✔
1492
      if (pDnode == NULL) {
47,928✔
1493
        mError("failed to acquire dnode. dnodeId:%d", pGid->dnodeId);
×
1494
        break;
×
1495
      }
1496
      bool isDnodeOnline = mndIsDnodeOnline(pDnode, curMs);
47,928✔
1497
      sdbRelease(pSdb, pDnode);
47,928✔
1498

1499
      char       buf[20] = {0};
47,928✔
1500
      ESyncState syncState = (isDnodeOnline) ? pGid->syncState : TAOS_SYNC_STATE_OFFLINE;
47,928✔
1501
      STR_TO_VARSTR(buf, syncStr(syncState));
47,928✔
1502
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1503
      COL_DATA_SET_VAL_GOTO((const char *)buf, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1504

1505
      int64_t roleTimeMs = (isDnodeOnline) ? pGid->roleTimeMs : 0;
47,928✔
1506
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1507
      COL_DATA_SET_VAL_GOTO((const char *)&roleTimeMs, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1508

1509
      int64_t startTimeMs = (isDnodeOnline) ? pGid->startTimeMs : 0;
47,928✔
1510
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1511
      COL_DATA_SET_VAL_GOTO((const char *)&startTimeMs, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1512

1513
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1514
      COL_DATA_SET_VAL_GOTO((const char *)&pGid->syncRestore, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1515

1516
      int64_t unappliedCount = pGid->syncCommitIndex - pGid->syncAppliedIndex;
47,928✔
1517
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1518
      char restoreStr[20] = {0};
47,928✔
1519
      if (unappliedCount > 0) {
47,928✔
UNCOV
1520
        calculateRstoreFinishTime(pGid->appliedRate, unappliedCount, restoreStr, sizeof(restoreStr));
×
1521
      }
1522
      STR_TO_VARSTR(buf, restoreStr);
47,928✔
1523
      COL_DATA_SET_VAL_GOTO((const char *)&buf, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1524

1525
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1526
      COL_DATA_SET_VAL_GOTO((const char *)&unappliedCount, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1527

1528
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1529
      COL_DATA_SET_VAL_GOTO((const char *)&pGid->bufferSegmentUsed, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1530

1531
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
47,928✔
1532
      COL_DATA_SET_VAL_GOTO((const char *)&pGid->bufferSegmentSize, false, pVgroup, pShow->pIter, _OVER);
47,928✔
1533

1534
      numOfRows++;
47,928✔
1535
    }
1536
    sdbRelease(pSdb, pVgroup);
25,149✔
1537
  }
1538
_OVER:
12,778✔
1539
  if (pUser) mndReleaseUser(pMnode, pUser);
12,778✔
1540
  if (pDb) mndReleaseDb(pMnode, pDb);
12,778✔
1541
  if (code != 0) {
12,778✔
1542
    mError("failed to retrieve vnode info at line %d since %s", lino, tstrerror(code));
×
1543
    return code;
×
1544
  }
1545
  pShow->numOfRows += numOfRows;
12,778✔
1546
  return numOfRows;
12,778✔
1547
}
1548

1549
static void mndCancelGetNextVnode(SMnode *pMnode, void *pIter) {
×
1550
  SSdb *pSdb = pMnode->pSdb;
×
1551
  sdbCancelFetchByType(pSdb, pIter, SDB_VGROUP);
×
1552
}
×
1553

1554
static int32_t mndAddVnodeToVgroup(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray) {
83,104✔
1555
  int32_t code = 0;
83,104✔
1556
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
83,104✔
1557
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
330,551✔
1558
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
247,447✔
1559
    mInfo("trans:%d, dnode:%d, equivalent vnodes:%d others:%d", pTrans->id, pDnode->id, pDnode->numOfVnodes,
247,447✔
1560
          pDnode->numOfOtherNodes);
1561
  }
1562

1563
  SVnodeGid *pVgid = &pVgroup->vnodeGid[pVgroup->replica];
83,104✔
1564
  for (int32_t d = 0; d < taosArrayGetSize(pArray); ++d) {
104,313✔
1565
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
100,722✔
1566

1567
    bool used = false;
100,722✔
1568
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
236,044✔
1569
      if (pDnode->id == pVgroup->vnodeGid[vn].dnodeId) {
156,531✔
1570
        used = true;
21,209✔
1571
        break;
21,209✔
1572
      }
1573
    }
1574
    if (used) continue;
100,722✔
1575

1576
    if (pDnode == NULL) {
79,513✔
1577
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
×
1578
    }
1579
    if (pDnode->numOfVnodes >= pDnode->numOfSupportVnodes) {
79,513✔
1580
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_VNODES);
×
1581
    }
1582

1583
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
79,513✔
1584
    if (pDnode->memAvail - vgMem - pDnode->memUsed <= 0) {
79,513✔
1585
      mError("trans:%d, db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
1586
             pTrans->id, pVgroup->dbName, pVgroup->vgId, vgMem, pDnode->id, pDnode->memAvail, pDnode->memUsed);
1587
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
1588
    } else {
1589
      pDnode->memUsed += vgMem;
79,513✔
1590
    }
1591

1592
    pVgid->dnodeId = pDnode->id;
79,513✔
1593
    pVgid->syncState = TAOS_SYNC_STATE_OFFLINE;
79,513✔
1594
    mInfo("trans:%id, db:%s, vgId:%d, vn:%d is added, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
79,513✔
1595
          pTrans->id, pVgroup->dbName, pVgroup->vgId, pVgroup->replica, vgMem, pVgid->dnodeId, pDnode->memAvail,
1596
          pDnode->memUsed);
1597

1598
    pVgroup->replica++;
79,513✔
1599
    pDnode->numOfVnodes++;
79,513✔
1600

1601
    SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
79,513✔
1602
    if (pVgRaw == NULL) {
79,513✔
1603
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1604
      if (terrno != 0) code = terrno;
×
1605
      TAOS_RETURN(code);
×
1606
    }
1607
    if ((code = mndTransAppendGroupRedolog(pTrans, pVgRaw, pVgroup->vgId)) != 0) {
79,513✔
1608
      sdbFreeRaw(pVgRaw);
×
1609
      TAOS_RETURN(code);
×
1610
    }
1611
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
79,513✔
1612
    if (code != 0) {
79,513✔
1613
      mError("trans:%d, vgId:%d, failed to set raw status since %s at line:%d", pTrans->id, pVgroup->vgId,
×
1614
             tstrerror(code), __LINE__);
1615
    }
1616
    TAOS_RETURN(code);
79,513✔
1617
  }
1618

1619
  code = TSDB_CODE_MND_NO_ENOUGH_DNODES;
3,591✔
1620
  mError("trans:%d, db:%s, failed to add vnode to vgId:%d since %s", pTrans->id, pVgroup->dbName, pVgroup->vgId,
3,591✔
1621
         tstrerror(code));
1622
  TAOS_RETURN(code);
3,591✔
1623
}
1624

1625
static int32_t mndRemoveVnodeFromVgroup(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray,
16,671✔
1626
                                        SVnodeGid *pDelVgid) {
1627
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
16,671✔
1628
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
64,680✔
1629
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
48,009✔
1630
    mInfo("trans:%d, dnode:%d, equivalent vnodes:%d others:%d", pTrans->id, pDnode->id, pDnode->numOfVnodes,
48,009✔
1631
          pDnode->numOfOtherNodes);
1632
  }
1633

1634
  int32_t code = -1;
16,671✔
1635
  for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
19,407✔
1636
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
19,407✔
1637

1638
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
38,823✔
1639
      SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
36,087✔
1640
      if (pVgid->dnodeId == pDnode->id) {
36,087✔
1641
        int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
16,671✔
1642
        pDnode->memUsed -= vgMem;
16,671✔
1643
        mInfo("trans:%d, db:%s, vgId:%d, vn:%d is removed, memory:%" PRId64 ", dnode:%d avail:%" PRId64
16,671✔
1644
              " used:%" PRId64,
1645
              pTrans->id, pVgroup->dbName, pVgroup->vgId, vn, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
1646
        pDnode->numOfVnodes--;
16,671✔
1647
        pVgroup->replica--;
16,671✔
1648
        *pDelVgid = *pVgid;
16,671✔
1649
        *pVgid = pVgroup->vnodeGid[pVgroup->replica];
16,671✔
1650
        memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
16,671✔
1651
        code = 0;
16,671✔
1652
        goto _OVER;
16,671✔
1653
      }
1654
    }
1655
  }
1656

1657
_OVER:
×
1658
  if (code != 0) {
16,671✔
1659
    code = TSDB_CODE_APP_ERROR;
×
1660
    mError("trans:%d, db:%s, failed to remove vnode from vgId:%d since %s", pTrans->id, pVgroup->dbName, pVgroup->vgId,
×
1661
           tstrerror(code));
1662
    TAOS_RETURN(code);
×
1663
  }
1664

1665
  for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
46,595✔
1666
    SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
29,924✔
1667
    mInfo("trans:%d, db:%s, vgId:%d, vn:%d dnode:%d is reserved", pTrans->id, pVgroup->dbName, pVgroup->vgId, vn,
29,924✔
1668
          pVgid->dnodeId);
1669
  }
1670

1671
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
16,671✔
1672
  if (pVgRaw == NULL) {
16,671✔
1673
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1674
    if (terrno != 0) code = terrno;
×
1675
    TAOS_RETURN(code);
×
1676
  }
1677
  if (mndTransAppendGroupRedolog(pTrans, pVgRaw, pVgroup->vgId) != 0) {
16,671✔
1678
    sdbFreeRaw(pVgRaw);
×
1679
    TAOS_RETURN(code);
×
1680
  }
1681
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
16,671✔
1682
  if (code != 0) {
16,671✔
1683
    mError("trans:%d, vgId:%d, failed to set raw status since %s at line:%d", pTrans->id, pVgroup->vgId,
×
1684
           tstrerror(code), __LINE__);
1685
  }
1686

1687
  TAOS_RETURN(code);
16,671✔
1688
}
1689

1690
static int32_t mndRemoveVnodeFromVgroupWithoutSave(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray,
×
1691
                                                   SVnodeGid *pDelVgid) {
1692
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
×
1693
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
×
1694
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
×
1695
    mInfo("dnode:%d, equivalent vnodes:%d others:%d", pDnode->id, pDnode->numOfVnodes, pDnode->numOfOtherNodes);
×
1696
  }
1697

1698
  int32_t code = -1;
×
1699
  for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
×
1700
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
×
1701

1702
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
×
1703
      SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
×
1704
      if (pVgid->dnodeId == pDnode->id) {
×
1705
        int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
×
1706
        pDnode->memUsed -= vgMem;
×
1707
        mInfo("db:%s, vgId:%d, vn:%d is removed, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
×
1708
              pVgroup->dbName, pVgroup->vgId, vn, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
1709
        pDnode->numOfVnodes--;
×
1710
        pVgroup->replica--;
×
1711
        *pDelVgid = *pVgid;
×
1712
        *pVgid = pVgroup->vnodeGid[pVgroup->replica];
×
1713
        memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
×
1714
        code = 0;
×
1715
        goto _OVER;
×
1716
      }
1717
    }
1718
  }
1719

1720
_OVER:
×
1721
  if (code != 0) {
×
1722
    code = TSDB_CODE_APP_ERROR;
×
1723
    mError("db:%s, failed to remove vnode from vgId:%d since %s", pVgroup->dbName, pVgroup->vgId, tstrerror(code));
×
1724
    TAOS_RETURN(code);
×
1725
  }
1726

1727
  for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
×
1728
    SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
×
1729
    mInfo("db:%s, vgId:%d, vn:%d dnode:%d is reserved", pVgroup->dbName, pVgroup->vgId, vn, pVgid->dnodeId);
×
1730
  }
1731

1732
  TAOS_RETURN(code);
×
1733
}
1734

1735
int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid) {
2,720,010✔
1736
  int32_t      code = 0;
2,720,010✔
1737
  STransAction action = {0};
2,720,010✔
1738

1739
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
2,720,010✔
1740
  if (pDnode == NULL) return -1;
2,720,010✔
1741
  action.epSet = mndGetDnodeEpset(pDnode);
2,720,010✔
1742
  mndReleaseDnode(pMnode, pDnode);
2,720,010✔
1743

1744
  int32_t contLen = 0;
2,720,010✔
1745
  void   *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
2,720,010✔
1746
  if (pReq == NULL) return -1;
2,720,010✔
1747

1748
  action.pCont = pReq;
2,720,010✔
1749
  action.contLen = contLen;
2,720,010✔
1750
  action.msgType = TDMT_DND_CREATE_VNODE;
2,720,010✔
1751
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
2,720,010✔
1752
  action.groupId = pVgroup->vgId;
2,720,010✔
1753

1754
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2,720,010✔
1755
    taosMemoryFree(pReq);
×
1756
    TAOS_RETURN(code);
×
1757
  }
1758

1759
  TAOS_RETURN(code);
2,720,010✔
1760
}
1761

1762
int32_t mndRestoreAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
2,330✔
1763
                                       SDnodeObj *pDnode) {
1764
  int32_t      code = 0;
2,330✔
1765
  STransAction action = {0};
2,330✔
1766

1767
  action.epSet = mndGetDnodeEpset(pDnode);
2,330✔
1768

1769
  int32_t contLen = 0;
2,330✔
1770
  void   *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
2,330✔
1771
  if (pReq == NULL) {
2,330✔
1772
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1773
    if (terrno != 0) code = terrno;
×
1774
    TAOS_RETURN(code);
×
1775
  }
1776

1777
  action.pCont = pReq;
2,330✔
1778
  action.contLen = contLen;
2,330✔
1779
  action.msgType = TDMT_DND_CREATE_VNODE;
2,330✔
1780
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
2,330✔
1781
  action.groupId = pVgroup->vgId;
2,330✔
1782

1783
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2,330✔
1784
    taosMemoryFree(pReq);
×
1785
    TAOS_RETURN(code);
×
1786
  }
1787

1788
  TAOS_RETURN(code);
2,330✔
1789
}
1790

1791
int32_t mndAddAlterVnodeConfirmAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
283,666✔
1792
  int32_t      code = 0;
283,666✔
1793
  STransAction action = {0};
283,666✔
1794
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
283,666✔
1795

1796
  mInfo("trans:%d, vgId:%d, build alter vnode confirm req", pTrans->id, pVgroup->vgId);
283,666✔
1797
  int32_t   contLen = sizeof(SMsgHead);
283,666✔
1798
  SMsgHead *pHead = taosMemoryMalloc(contLen);
283,666✔
1799
  if (pHead == NULL) {
283,666✔
1800
    TAOS_RETURN(terrno);
×
1801
  }
1802

1803
  pHead->contLen = htonl(contLen);
283,666✔
1804
  pHead->vgId = htonl(pVgroup->vgId);
283,666✔
1805

1806
  action.pCont = pHead;
283,666✔
1807
  action.contLen = contLen;
283,666✔
1808
  action.msgType = TDMT_VND_ALTER_CONFIRM;
283,666✔
1809
  // incorrect redirect result will cause this erro
1810
  action.retryCode = TSDB_CODE_VND_INVALID_VGROUP_ID;
283,666✔
1811
  action.groupId = pVgroup->vgId;
283,666✔
1812

1813
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
283,666✔
1814
    taosMemoryFree(pHead);
×
1815
    TAOS_RETURN(code);
×
1816
  }
1817

1818
  TAOS_RETURN(code);
283,666✔
1819
}
1820

1821
int32_t mndAddChangeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pOldVgroup, SVgObj *pNewVgroup,
×
1822
                                 int32_t dnodeId) {
1823
  int32_t      code = 0;
×
1824
  STransAction action = {0};
×
1825
  action.epSet = mndGetVgroupEpset(pMnode, pNewVgroup);
×
1826

1827
  int32_t contLen = 0;
×
1828
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pNewVgroup, dnodeId, &contLen);
×
1829
  if (pReq == NULL) {
×
1830
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1831
    if (terrno != 0) code = terrno;
×
1832
    TAOS_RETURN(code);
×
1833
  }
1834

1835
  int32_t totallen = contLen + sizeof(SMsgHead);
×
1836

1837
  SMsgHead *pHead = taosMemoryMalloc(totallen);
×
1838
  if (pHead == NULL) {
×
1839
    taosMemoryFree(pReq);
×
1840
    TAOS_RETURN(terrno);
×
1841
  }
1842

1843
  pHead->contLen = htonl(totallen);
×
1844
  pHead->vgId = htonl(pNewVgroup->vgId);
×
1845

1846
  memcpy((void *)(pHead + 1), pReq, contLen);
×
1847
  taosMemoryFree(pReq);
×
1848

1849
  action.pCont = pHead;
×
1850
  action.contLen = totallen;
×
1851
  action.msgType = TDMT_SYNC_CONFIG_CHANGE;
×
1852

1853
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
1854
    taosMemoryFree(pHead);
×
1855
    TAOS_RETURN(code);
×
1856
  }
1857

1858
  TAOS_RETURN(code);
×
1859
}
1860

1861
static int32_t mndAddAlterVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, int32_t srcVgId, SVgObj *pVgroup) {
32,486✔
1862
  int32_t      code = 0;
32,486✔
1863
  STransAction action = {0};
32,486✔
1864
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
32,486✔
1865

1866
  int32_t contLen = 0;
32,486✔
1867
  void   *pReq = mndBuildAlterVnodeHashRangeReq(pMnode, srcVgId, pVgroup, &contLen);
32,486✔
1868
  if (pReq == NULL) {
32,486✔
1869
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1870
    if (terrno != 0) code = terrno;
×
1871
    TAOS_RETURN(code);
×
1872
  }
1873

1874
  action.pCont = pReq;
32,486✔
1875
  action.contLen = contLen;
32,486✔
1876
  action.msgType = TDMT_VND_ALTER_HASHRANGE;
32,486✔
1877
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
32,486✔
1878

1879
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
32,486✔
1880
    taosMemoryFree(pReq);
×
1881
    TAOS_RETURN(code);
×
1882
  }
1883

1884
  mInfo("trans:%d, add alter vnode hash range action for from vgId:%d to vgId:%d", pTrans->id, srcVgId, pVgroup->vgId);
32,486✔
1885
  TAOS_RETURN(code);
32,486✔
1886
}
1887

1888
int32_t mndAddAlterVnodeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
189,839✔
1889
  int32_t      code = 0;
189,839✔
1890
  STransAction action = {0};
189,839✔
1891
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
189,839✔
1892

1893
  int32_t contLen = 0;
189,839✔
1894
  void   *pReq = mndBuildAlterVnodeConfigReq(pMnode, pDb, pVgroup, &contLen);
189,839✔
1895
  if (pReq == NULL) {
189,839✔
1896
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1897
    if (terrno != 0) code = terrno;
×
1898
    TAOS_RETURN(code);
×
1899
  }
1900

1901
  action.pCont = pReq;
189,839✔
1902
  action.contLen = contLen;
189,839✔
1903
  action.msgType = TDMT_VND_ALTER_CONFIG;
189,839✔
1904
  action.groupId = pVgroup->vgId;
189,839✔
1905

1906
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
189,839✔
1907
    taosMemoryFree(pReq);
×
1908
    TAOS_RETURN(code);
×
1909
  }
1910

1911
  TAOS_RETURN(code);
189,839✔
1912
}
1913

1914
int32_t mndAddNewVgPrepareAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVg) {
2,353,542✔
1915
  int32_t  code = 0;
2,353,542✔
1916
  SSdbRaw *pRaw = mndVgroupActionEncode(pVg);
2,353,542✔
1917
  if (pRaw == NULL) {
2,353,542✔
1918
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1919
    if (terrno != 0) code = terrno;
×
1920
    goto _err;
×
1921
  }
1922

1923
  TAOS_CHECK_GOTO(mndTransAppendPrepareLog(pTrans, pRaw), NULL, _err);
2,353,542✔
1924
  if (sdbSetRawStatus(pRaw, SDB_STATUS_CREATING) != 0) {
2,353,542✔
1925
    mError("vgId:%d, failed to set raw status at line:%d", pVg->vgId, __LINE__);
×
1926
  }
1927
  if (code != 0) {
2,353,542✔
1928
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVg->vgId, tstrerror(code), __LINE__);
×
1929
    TAOS_RETURN(code);
×
1930
  }
1931
  pRaw = NULL;
2,353,542✔
1932
  TAOS_RETURN(code);
2,353,542✔
1933

1934
_err:
×
1935
  sdbFreeRaw(pRaw);
×
1936
  TAOS_RETURN(code);
×
1937
}
1938

1939
int32_t mndAddAlterVnodeReplicaAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
690,891✔
1940
  int32_t    code = 0;
690,891✔
1941
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
690,891✔
1942
  if (pDnode == NULL) {
690,891✔
1943
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1944
    if (terrno != 0) code = terrno;
×
1945
    TAOS_RETURN(code);
×
1946
  }
1947

1948
  STransAction action = {0};
690,891✔
1949
  action.epSet = mndGetDnodeEpset(pDnode);
690,891✔
1950
  mndReleaseDnode(pMnode, pDnode);
690,891✔
1951

1952
  int32_t contLen = 0;
690,891✔
1953
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
690,891✔
1954
  if (pReq == NULL) {
690,891✔
1955
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1956
    if (terrno != 0) code = terrno;
×
1957
    TAOS_RETURN(code);
×
1958
  }
1959

1960
  action.pCont = pReq;
690,891✔
1961
  action.contLen = contLen;
690,891✔
1962
  action.msgType = TDMT_VND_ALTER_REPLICA;
690,891✔
1963
  action.groupId = pVgroup->vgId;
690,891✔
1964

1965
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
690,891✔
1966
    taosMemoryFree(pReq);
×
1967
    TAOS_RETURN(code);
×
1968
  }
1969

1970
  TAOS_RETURN(code);
690,891✔
1971
}
1972

1973
int32_t mndAddCheckLearnerCatchupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
×
1974
  int32_t    code = 0;
×
1975
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
×
1976
  if (pDnode == NULL) {
×
1977
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1978
    if (terrno != 0) code = terrno;
×
1979
    TAOS_RETURN(code);
×
1980
  }
1981

1982
  STransAction action = {0};
×
1983
  action.epSet = mndGetDnodeEpset(pDnode);
×
1984
  mndReleaseDnode(pMnode, pDnode);
×
1985

1986
  int32_t contLen = 0;
×
1987
  void   *pReq = mndBuildCheckLearnCatchupReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
×
1988
  if (pReq == NULL) {
×
1989
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1990
    if (terrno != 0) code = terrno;
×
1991
    TAOS_RETURN(code);
×
1992
  }
1993

1994
  action.pCont = pReq;
×
1995
  action.contLen = contLen;
×
1996
  action.msgType = TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP;
×
1997
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
×
1998
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
×
1999

2000
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
2001
    taosMemoryFree(pReq);
×
2002
    TAOS_RETURN(code);
×
2003
  }
2004

2005
  TAOS_RETURN(code);
×
2006
}
2007

2008
int32_t mndAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
102,705✔
2009
  int32_t    code = 0;
102,705✔
2010
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
102,705✔
2011
  if (pDnode == NULL) {
102,705✔
2012
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2013
    if (terrno != 0) code = terrno;
×
2014
    TAOS_RETURN(code);
×
2015
  }
2016

2017
  STransAction action = {0};
102,705✔
2018
  action.epSet = mndGetDnodeEpset(pDnode);
102,705✔
2019
  mndReleaseDnode(pMnode, pDnode);
102,705✔
2020

2021
  int32_t contLen = 0;
102,705✔
2022
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
102,705✔
2023
  if (pReq == NULL) {
102,705✔
2024
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2025
    if (terrno != 0) code = terrno;
×
2026
    TAOS_RETURN(code);
×
2027
  }
2028

2029
  action.pCont = pReq;
102,705✔
2030
  action.contLen = contLen;
102,705✔
2031
  action.msgType = TDMT_DND_ALTER_VNODE_TYPE;
102,705✔
2032
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
102,705✔
2033
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
102,705✔
2034
  action.groupId = pVgroup->vgId;
102,705✔
2035

2036
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
102,705✔
2037
    taosMemoryFree(pReq);
×
2038
    TAOS_RETURN(code);
×
2039
  }
2040

2041
  TAOS_RETURN(code);
102,705✔
2042
}
2043

2044
int32_t mndRestoreAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
2,330✔
2045
                                          SDnodeObj *pDnode) {
2046
  int32_t      code = 0;
2,330✔
2047
  STransAction action = {0};
2,330✔
2048
  action.epSet = mndGetDnodeEpset(pDnode);
2,330✔
2049

2050
  int32_t contLen = 0;
2,330✔
2051
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, pDnode->id, &contLen);
2,330✔
2052
  if (pReq == NULL) {
2,330✔
2053
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2054
    if (terrno != 0) code = terrno;
×
2055
    TAOS_RETURN(code);
×
2056
  }
2057

2058
  action.pCont = pReq;
2,330✔
2059
  action.contLen = contLen;
2,330✔
2060
  action.msgType = TDMT_DND_ALTER_VNODE_TYPE;
2,330✔
2061
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
2,330✔
2062
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
2,330✔
2063
  action.groupId = pVgroup->vgId;
2,330✔
2064

2065
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2,330✔
2066
    taosMemoryFree(pReq);
×
2067
    TAOS_RETURN(code);
×
2068
  }
2069

2070
  TAOS_RETURN(code);
2,330✔
2071
}
2072

2073
static int32_t mndAddDisableVnodeWriteAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
32,486✔
2074
                                             int32_t dnodeId) {
2075
  int32_t    code = 0;
32,486✔
2076
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
32,486✔
2077
  if (pDnode == NULL) {
32,486✔
2078
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2079
    if (terrno != 0) code = terrno;
×
2080
    TAOS_RETURN(code);
×
2081
  }
2082

2083
  STransAction action = {0};
32,486✔
2084
  action.epSet = mndGetDnodeEpset(pDnode);
32,486✔
2085
  mndReleaseDnode(pMnode, pDnode);
32,486✔
2086

2087
  int32_t contLen = 0;
32,486✔
2088
  void   *pReq = mndBuildDisableVnodeWriteReq(pMnode, pDb, pVgroup->vgId, &contLen);
32,486✔
2089
  if (pReq == NULL) {
32,486✔
2090
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2091
    if (terrno != 0) code = terrno;
×
2092
    TAOS_RETURN(code);
×
2093
  }
2094

2095
  action.pCont = pReq;
32,486✔
2096
  action.contLen = contLen;
32,486✔
2097
  action.msgType = TDMT_VND_DISABLE_WRITE;
32,486✔
2098

2099
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
32,486✔
2100
    taosMemoryFree(pReq);
×
2101
    TAOS_RETURN(code);
×
2102
  }
2103

2104
  TAOS_RETURN(code);
32,486✔
2105
}
2106

2107
int32_t mndAddDropVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid,
4,030,037✔
2108
                              bool isRedo) {
2109
  int32_t      code = 0;
4,030,037✔
2110
  STransAction action = {0};
4,030,037✔
2111

2112
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
4,030,037✔
2113
  if (pDnode == NULL) {
4,030,037✔
2114
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2115
    if (terrno != 0) code = terrno;
×
2116
    TAOS_RETURN(code);
×
2117
  }
2118
  action.epSet = mndGetDnodeEpset(pDnode);
4,030,037✔
2119
  mndReleaseDnode(pMnode, pDnode);
4,030,037✔
2120

2121
  int32_t contLen = 0;
4,030,037✔
2122
  void   *pReq = mndBuildDropVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
4,030,037✔
2123
  if (pReq == NULL) {
4,030,037✔
2124
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2125
    if (terrno != 0) code = terrno;
×
2126
    TAOS_RETURN(code);
×
2127
  }
2128

2129
  action.pCont = pReq;
4,030,037✔
2130
  action.contLen = contLen;
4,030,037✔
2131
  action.msgType = TDMT_DND_DROP_VNODE;
4,030,037✔
2132
  action.acceptableCode = TSDB_CODE_VND_NOT_EXIST;
4,030,037✔
2133
  action.groupId = pVgroup->vgId;
4,030,037✔
2134

2135
  if (isRedo) {
4,030,037✔
2136
    if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
1,454,625✔
2137
      taosMemoryFree(pReq);
×
2138
      TAOS_RETURN(code);
×
2139
    }
2140
  } else {
2141
    if ((code = mndTransAppendUndoAction(pTrans, &action)) != 0) {
2,575,412✔
2142
      taosMemoryFree(pReq);
×
2143
      TAOS_RETURN(code);
×
2144
    }
2145
  }
2146

2147
  TAOS_RETURN(code);
4,030,037✔
2148
}
2149

2150
int32_t mndSetMoveVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t vnIndex,
14,280✔
2151
                                    SArray *pArray, bool force, bool unsafe) {
2152
  int32_t code = 0;
14,280✔
2153
  SVgObj  newVg = {0};
14,280✔
2154
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
14,280✔
2155

2156
  mInfo("vgId:%d, trans:%d, vgroup info before move, replica:%d", newVg.vgId, pTrans->id, newVg.replica);
14,280✔
2157
  for (int32_t i = 0; i < newVg.replica; ++i) {
46,030✔
2158
    mInfo("vgId:%d, trans:%d, vnode:%d dnode:%d", newVg.vgId, pTrans->id, i, newVg.vnodeGid[i].dnodeId);
31,750✔
2159
  }
2160

2161
  if (!force) {
14,280✔
2162
#if 1
2163
    {
2164
#else
2165
    if (newVg.replica == 1) {
2166
#endif
2167
      mInfo("vgId:%d, trans:%d, will add 1 vnode, replca:%d", pVgroup->vgId, pTrans->id, newVg.replica);
14,280✔
2168
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray));
14,280✔
2169
      for (int32_t i = 0; i < newVg.replica - 1; ++i) {
46,030✔
2170
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
31,750✔
2171
      }
2172
      TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[newVg.replica - 1]));
14,280✔
2173
      TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
14,280✔
2174

2175
      mInfo("vgId:%d, trans:%d, will remove 1 vnode, replca:2", pVgroup->vgId, pTrans->id);
14,280✔
2176
      newVg.replica--;
14,280✔
2177
      SVnodeGid del = newVg.vnodeGid[vnIndex];
14,280✔
2178
      newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
14,280✔
2179
      memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
14,280✔
2180
      {
2181
        SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
14,280✔
2182
        if (pRaw == NULL) {
14,280✔
2183
          code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2184
          if (terrno != 0) code = terrno;
×
2185
          TAOS_RETURN(code);
×
2186
        }
2187
        if ((code = mndTransAppendGroupRedolog(pTrans, pRaw, pVgroup->vgId)) != 0) {
14,280✔
2188
          sdbFreeRaw(pRaw);
×
2189
          TAOS_RETURN(code);
×
2190
        }
2191
        code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
14,280✔
2192
        if (code != 0) {
14,280✔
2193
          mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2194
          return code;
×
2195
        }
2196
      }
2197

2198
      TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg, &del, true));
14,280✔
2199
      for (int32_t i = 0; i < newVg.replica; ++i) {
46,030✔
2200
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
31,750✔
2201
      }
2202
      TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
14,280✔
2203
#if 1
2204
    }
2205
#else
2206
    } else {  // new replica == 3
2207
      mInfo("vgId:%d, will add 1 vnode, replca:3", pVgroup->vgId);
2208
      if (mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray) != 0) return -1;
2209
      mInfo("vgId:%d, will remove 1 vnode, replca:4", pVgroup->vgId);
2210
      newVg.replica--;
2211
      SVnodeGid del = newVg.vnodeGid[vnIndex];
2212
      newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
2213
      memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
2214
      {
2215
        SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
2216
        if (pRaw == NULL) return -1;
2217
        if (mndTransAppendRedolog(pTrans, pRaw) != 0) {
2218
          sdbFreeRaw(pRaw);
2219
          return -1;
2220
        }
2221
      }
2222

2223
      if (mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg, &del, true) != 0) return -1;
2224
      for (int32_t i = 0; i < newVg.replica; ++i) {
2225
        if (i == vnIndex) continue;
2226
        if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId) != 0) return -1;
2227
      }
2228
      if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[vnIndex]) != 0) return -1;
2229
      if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg) != 0) return -1;
2230
    }
2231
#endif
2232
  } else {
2233
    mInfo("vgId:%d, will add 1 vnode and force remove 1 vnode", pVgroup->vgId);
×
2234
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray));
×
2235
    newVg.replica--;
×
2236
    // SVnodeGid del = newVg.vnodeGid[vnIndex];
2237
    newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
×
2238
    memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
×
2239
    {
2240
      SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
×
2241
      if (pRaw == NULL) {
×
2242
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2243
        if (terrno != 0) code = terrno;
×
2244
        TAOS_RETURN(code);
×
2245
      }
2246
      if ((code = mndTransAppendGroupRedolog(pTrans, pRaw, pVgroup->vgId)) != 0) {
×
2247
        sdbFreeRaw(pRaw);
×
2248
        TAOS_RETURN(code);
×
2249
      }
2250
      code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
×
2251
      if (code != 0) {
×
2252
        mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2253
        return code;
×
2254
      }
2255
    }
2256

2257
    for (int32_t i = 0; i < newVg.replica; ++i) {
×
2258
      if (i != vnIndex) {
×
2259
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
×
2260
      }
2261
    }
2262
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[vnIndex]));
×
2263
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
×
2264

2265
    if (newVg.replica == 1) {
×
2266
      if (force && !unsafe) {
×
2267
        TAOS_RETURN(TSDB_CODE_VND_META_DATA_UNSAFE_DELETE);
×
2268
      }
2269

2270
      SSdb *pSdb = pMnode->pSdb;
×
2271
      void *pIter = NULL;
×
2272

2273
      while (1) {
×
2274
        SStbObj *pStb = NULL;
×
2275
        pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
×
2276
        if (pIter == NULL) break;
×
2277

2278
        if (strcmp(pStb->db, pDb->name) == 0) {
×
2279
          if ((code = mndSetForceDropCreateStbRedoActions(pMnode, pTrans, &newVg, pStb)) != 0) {
×
2280
            sdbCancelFetch(pSdb, pIter);
×
2281
            sdbRelease(pSdb, pStb);
×
2282
            TAOS_RETURN(code);
×
2283
          }
2284
        }
2285

2286
        sdbRelease(pSdb, pStb);
×
2287
      }
2288

2289
      mInfo("vgId:%d, all data is dropped since replica=1", pVgroup->vgId);
×
2290
    }
2291
  }
2292

2293
  {
2294
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
14,280✔
2295
    if (pRaw == NULL) {
14,280✔
2296
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2297
      if (terrno != 0) code = terrno;
×
2298
      TAOS_RETURN(code);
×
2299
    }
2300
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
14,280✔
2301
      sdbFreeRaw(pRaw);
×
2302
      TAOS_RETURN(code);
×
2303
    }
2304
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
14,280✔
2305
    if (code != 0) {
14,280✔
2306
      mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2307
      return code;
×
2308
    }
2309
  }
2310

2311
  mInfo("vgId:%d, vgroup info after move, replica:%d", newVg.vgId, newVg.replica);
14,280✔
2312
  for (int32_t i = 0; i < newVg.replica; ++i) {
46,030✔
2313
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
31,750✔
2314
  }
2315
  TAOS_RETURN(code);
14,280✔
2316
}
2317

2318
int32_t mndSetMoveVgroupsInfoToTrans(SMnode *pMnode, STrans *pTrans, int32_t delDnodeId, bool force, bool unsafe) {
7,126✔
2319
  int32_t code = 0;
7,126✔
2320
  SArray *pArray = mndBuildDnodesArray(pMnode, delDnodeId, NULL);
7,126✔
2321
  if (pArray == NULL) {
7,126✔
2322
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2323
    if (terrno != 0) code = terrno;
×
2324
    TAOS_RETURN(code);
×
2325
  }
2326

2327
  void *pIter = NULL;
7,126✔
2328
  while (1) {
21,260✔
2329
    SVgObj *pVgroup = NULL;
28,386✔
2330
    pIter = sdbFetch(pMnode->pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
28,386✔
2331
    if (pIter == NULL) break;
28,386✔
2332

2333
    int32_t vnIndex = -1;
21,260✔
2334
    for (int32_t i = 0; i < pVgroup->replica; ++i) {
42,441✔
2335
      if (pVgroup->vnodeGid[i].dnodeId == delDnodeId) {
35,461✔
2336
        vnIndex = i;
14,280✔
2337
        break;
14,280✔
2338
      }
2339
    }
2340

2341
    code = 0;
21,260✔
2342
    if (vnIndex != -1) {
21,260✔
2343
      mInfo("vgId:%d, trans:%d, vnode:%d will be removed from dnode:%d, force:%d", pVgroup->vgId, pTrans->id, vnIndex,
14,280✔
2344
            delDnodeId, force);
2345
      SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
14,280✔
2346
      code = mndSetMoveVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, vnIndex, pArray, force, unsafe);
14,280✔
2347
      mndReleaseDb(pMnode, pDb);
14,280✔
2348
    }
2349

2350
    sdbRelease(pMnode->pSdb, pVgroup);
21,260✔
2351

2352
    if (code != 0) {
21,260✔
2353
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2354
      break;
×
2355
    }
2356
  }
2357

2358
  taosArrayDestroy(pArray);
7,126✔
2359
  TAOS_RETURN(code);
7,126✔
2360
}
2361

2362
static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
65,085✔
2363
                                             int32_t newDnodeId) {
2364
  int32_t code = 0;
65,085✔
2365
  mInfo("vgId:%d, will add 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, newDnodeId);
65,085✔
2366

2367
  // assoc dnode
2368
  SVnodeGid *pGid = &pVgroup->vnodeGid[pVgroup->replica];
65,085✔
2369
  pVgroup->replica++;
65,085✔
2370
  pGid->dnodeId = newDnodeId;
65,085✔
2371
  pGid->syncState = TAOS_SYNC_STATE_OFFLINE;
65,085✔
2372
  pGid->nodeRole = TAOS_SYNC_ROLE_LEARNER;
65,085✔
2373

2374
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
65,085✔
2375
  if (pVgRaw == NULL) {
65,085✔
2376
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2377
    if (terrno != 0) code = terrno;
×
2378
    TAOS_RETURN(code);
×
2379
  }
2380
  if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
65,085✔
2381
    sdbFreeRaw(pVgRaw);
×
2382
    TAOS_RETURN(code);
×
2383
  }
2384
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
65,085✔
2385
  if (code != 0) {
65,085✔
2386
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVgroup->vgId, tstrerror(code), __LINE__);
×
2387
    TAOS_RETURN(code);
×
2388
  }
2389

2390
  // learner
2391
  for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
220,752✔
2392
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
155,667✔
2393
  }
2394
  TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, pVgroup, pGid));
65,085✔
2395

2396
  // voter
2397
  pGid->nodeRole = TAOS_SYNC_ROLE_VOTER;
65,085✔
2398
  TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, pVgroup, pGid->dnodeId));
65,085✔
2399
  for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
220,752✔
2400
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
155,667✔
2401
  }
2402

2403
  // confirm
2404
  TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup));
65,085✔
2405

2406
  TAOS_RETURN(code);
65,085✔
2407
}
2408

2409
static int32_t mndAddDecVgroupReplicaFromTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
65,085✔
2410
                                               int32_t delDnodeId) {
2411
  int32_t code = 0;
65,085✔
2412
  mInfo("vgId:%d, will remove 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, delDnodeId);
65,085✔
2413

2414
  SVnodeGid *pGid = NULL;
65,085✔
2415
  SVnodeGid  delGid = {0};
65,085✔
2416
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
113,620✔
2417
    if (pVgroup->vnodeGid[i].dnodeId == delDnodeId) {
113,620✔
2418
      pGid = &pVgroup->vnodeGid[i];
65,085✔
2419
      break;
65,085✔
2420
    }
2421
  }
2422

2423
  if (pGid == NULL) return 0;
65,085✔
2424

2425
  pVgroup->replica--;
65,085✔
2426
  memcpy(&delGid, pGid, sizeof(SVnodeGid));
65,085✔
2427
  memcpy(pGid, &pVgroup->vnodeGid[pVgroup->replica], sizeof(SVnodeGid));
65,085✔
2428
  memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
65,085✔
2429

2430
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
65,085✔
2431
  if (pVgRaw == NULL) {
65,085✔
2432
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2433
    if (terrno != 0) code = terrno;
×
2434
    TAOS_RETURN(code);
×
2435
  }
2436
  if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
65,085✔
2437
    sdbFreeRaw(pVgRaw);
×
2438
    TAOS_RETURN(code);
×
2439
  }
2440
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
65,085✔
2441
  if (code != 0) {
65,085✔
2442
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVgroup->vgId, tstrerror(code), __LINE__);
×
2443
    TAOS_RETURN(code);
×
2444
  }
2445

2446
  TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pDb, pVgroup, &delGid, true));
65,085✔
2447
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
220,752✔
2448
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
155,667✔
2449
  }
2450
  TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup));
65,085✔
2451

2452
  TAOS_RETURN(code);
65,085✔
2453
}
2454

2455
static int32_t mndRedistributeVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup, SDnodeObj *pNew1,
36,369✔
2456
                                     SDnodeObj *pOld1, SDnodeObj *pNew2, SDnodeObj *pOld2, SDnodeObj *pNew3,
2457
                                     SDnodeObj *pOld3) {
2458
  int32_t code = -1;
36,369✔
2459
  STrans *pTrans = NULL;
36,369✔
2460

2461
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "red-vgroup");
36,369✔
2462
  if (pTrans == NULL) {
36,369✔
2463
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2464
    if (terrno != 0) code = terrno;
×
2465
    goto _OVER;
×
2466
  }
2467

2468
  mndTransSetDbName(pTrans, pVgroup->dbName, NULL);
36,369✔
2469
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
36,369✔
2470
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
36,287✔
2471

2472
  mndTransSetSerial(pTrans);
36,287✔
2473
  mInfo("trans:%d, used to redistribute vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
36,287✔
2474

2475
  SVgObj newVg = {0};
36,287✔
2476
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
36,287✔
2477
  mInfo("vgId:%d, vgroup info before redistribute, replica:%d", newVg.vgId, newVg.replica);
36,287✔
2478
  for (int32_t i = 0; i < newVg.replica; ++i) {
122,280✔
2479
    mInfo("vgId:%d, vnode:%d dnode:%d role:%s", newVg.vgId, i, newVg.vnodeGid[i].dnodeId,
85,993✔
2480
          syncStr(newVg.vnodeGid[i].syncState));
2481
  }
2482

2483
  if (pNew1 != NULL && pOld1 != NULL) {
36,287✔
2484
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew1->id);
36,287✔
2485
    if (numOfVnodes >= pNew1->numOfSupportVnodes) {
36,287✔
2486
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew1->id, numOfVnodes,
673✔
2487
             pNew1->numOfSupportVnodes);
2488
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
673✔
2489
      goto _OVER;
673✔
2490
    }
2491

2492
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
35,614✔
2493
    if (pNew1->memAvail - vgMem - pNew1->memUsed <= 0) {
35,614✔
2494
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2495
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew1->id, pNew1->memAvail, pNew1->memUsed);
2496
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2497
      goto _OVER;
×
2498
    } else {
2499
      pNew1->memUsed += vgMem;
35,614✔
2500
    }
2501

2502
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew1->id), NULL, _OVER);
35,614✔
2503
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld1->id), NULL, _OVER);
35,614✔
2504
  }
2505

2506
  if (pNew2 != NULL && pOld2 != NULL) {
35,614✔
2507
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew2->id);
10,743✔
2508
    if (numOfVnodes >= pNew2->numOfSupportVnodes) {
10,743✔
2509
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew2->id, numOfVnodes,
×
2510
             pNew2->numOfSupportVnodes);
2511
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
×
2512
      goto _OVER;
×
2513
    }
2514
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
10,743✔
2515
    if (pNew2->memAvail - vgMem - pNew2->memUsed <= 0) {
10,743✔
2516
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2517
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew2->id, pNew2->memAvail, pNew2->memUsed);
2518
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2519
      goto _OVER;
×
2520
    } else {
2521
      pNew2->memUsed += vgMem;
10,743✔
2522
    }
2523
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew2->id), NULL, _OVER);
10,743✔
2524
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld2->id), NULL, _OVER);
10,743✔
2525
  }
2526

2527
  if (pNew3 != NULL && pOld3 != NULL) {
35,614✔
2528
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew3->id);
4,191✔
2529
    if (numOfVnodes >= pNew3->numOfSupportVnodes) {
4,191✔
2530
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew3->id, numOfVnodes,
×
2531
             pNew3->numOfSupportVnodes);
2532
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
×
2533
      goto _OVER;
×
2534
    }
2535
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
4,191✔
2536
    if (pNew3->memAvail - vgMem - pNew3->memUsed <= 0) {
4,191✔
2537
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2538
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew3->id, pNew3->memAvail, pNew3->memUsed);
2539
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2540
      goto _OVER;
×
2541
    } else {
2542
      pNew3->memUsed += vgMem;
4,191✔
2543
    }
2544
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew3->id), NULL, _OVER);
4,191✔
2545
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld3->id), NULL, _OVER);
4,191✔
2546
  }
2547

2548
  {
2549
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
35,614✔
2550
    if (pRaw == NULL) {
35,614✔
2551
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2552
      if (terrno != 0) code = terrno;
×
2553
      goto _OVER;
×
2554
    }
2555
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
35,614✔
2556
      sdbFreeRaw(pRaw);
×
2557
      goto _OVER;
×
2558
    }
2559
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
35,614✔
2560
    if (code != 0) {
35,614✔
2561
      mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2562
      goto _OVER;
×
2563
    }
2564
  }
2565

2566
  mInfo("vgId:%d, vgroup info after redistribute, replica:%d", newVg.vgId, newVg.replica);
35,614✔
2567
  for (int32_t i = 0; i < newVg.replica; ++i) {
119,588✔
2568
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
83,974✔
2569
  }
2570

2571
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
35,614✔
2572
  code = 0;
34,794✔
2573

2574
_OVER:
36,369✔
2575
  mndTransDrop(pTrans);
36,369✔
2576
  mndReleaseDb(pMnode, pDb);
36,369✔
2577
  TAOS_RETURN(code);
36,369✔
2578
}
2579

2580
static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq) {
44,304✔
2581
  SMnode    *pMnode = pReq->info.node;
44,304✔
2582
  SDnodeObj *pNew1 = NULL;
44,304✔
2583
  SDnodeObj *pNew2 = NULL;
44,304✔
2584
  SDnodeObj *pNew3 = NULL;
44,304✔
2585
  SDnodeObj *pOld1 = NULL;
44,304✔
2586
  SDnodeObj *pOld2 = NULL;
44,304✔
2587
  SDnodeObj *pOld3 = NULL;
44,304✔
2588
  SVgObj    *pVgroup = NULL;
44,304✔
2589
  SDbObj    *pDb = NULL;
44,304✔
2590
  int32_t    code = -1;
44,304✔
2591
  int64_t    curMs = taosGetTimestampMs();
44,304✔
2592
  int32_t    newDnodeId[3] = {0};
44,304✔
2593
  int32_t    oldDnodeId[3] = {0};
44,304✔
2594
  int32_t    newIndex = -1;
44,304✔
2595
  int32_t    oldIndex = -1;
44,304✔
2596
  int64_t    tss = taosGetTimestampMs();
44,304✔
2597

2598
  SRedistributeVgroupReq req = {0};
44,304✔
2599
  if (tDeserializeSRedistributeVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) {
44,304✔
2600
    code = TSDB_CODE_INVALID_MSG;
×
2601
    goto _OVER;
×
2602
  }
2603

2604
  mInfo("vgId:%d, start to redistribute vgroup to dnode %d:%d:%d", req.vgId, req.dnodeId1, req.dnodeId2, req.dnodeId3);
44,304✔
2605
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_REDISTRIBUTE_VGROUP)) != 0) {
44,304✔
2606
    goto _OVER;
×
2607
  }
2608

2609
  pVgroup = mndAcquireVgroup(pMnode, req.vgId);
44,304✔
2610
  if (pVgroup == NULL) {
44,304✔
2611
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
2,019✔
2612
    if (terrno != 0) code = terrno;
2,019✔
2613
    goto _OVER;
2,019✔
2614
  }
2615
  if (pVgroup->mountVgId) {
42,285✔
2616
    code = TSDB_CODE_MND_MOUNT_OBJ_NOT_SUPPORT;
×
2617
    goto _OVER;
×
2618
  }
2619
  pDb = mndAcquireDb(pMnode, pVgroup->dbName);
42,285✔
2620
  if (pDb == NULL) {
42,285✔
2621
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2622
    if (terrno != 0) code = terrno;
×
2623
    goto _OVER;
×
2624
  }
2625

2626
  if (pVgroup->replica == 1) {
42,285✔
2627
    if (req.dnodeId1 <= 0 || req.dnodeId2 > 0 || req.dnodeId3 > 0) {
10,832✔
2628
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2629
      goto _OVER;
×
2630
    }
2631

2632
    if (req.dnodeId1 == pVgroup->vnodeGid[0].dnodeId) {
10,832✔
2633
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2634
      code = 0;
×
2635
      goto _OVER;
×
2636
    }
2637

2638
    pNew1 = mndAcquireDnode(pMnode, req.dnodeId1);
10,832✔
2639
    if (pNew1 == NULL) {
10,832✔
2640
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2641
      if (terrno != 0) code = terrno;
×
2642
      goto _OVER;
×
2643
    }
2644
    if (!mndIsDnodeOnline(pNew1, curMs)) {
10,832✔
2645
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2646
      goto _OVER;
×
2647
    }
2648

2649
    pOld1 = mndAcquireDnode(pMnode, pVgroup->vnodeGid[0].dnodeId);
10,832✔
2650
    if (pOld1 == NULL) {
10,832✔
2651
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2652
      if (terrno != 0) code = terrno;
×
2653
      goto _OVER;
×
2654
    }
2655
    if (!mndIsDnodeOnline(pOld1, curMs)) {
10,832✔
2656
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2657
      goto _OVER;
×
2658
    }
2659

2660
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, NULL, NULL, NULL, NULL);
10,832✔
2661

2662
  } else if (pVgroup->replica == 3) {
31,453✔
2663
    if (req.dnodeId1 <= 0 || req.dnodeId2 <= 0 || req.dnodeId3 <= 0) {
30,085✔
2664
      code = TSDB_CODE_MND_INVALID_REPLICA;
2,692✔
2665
      goto _OVER;
2,692✔
2666
    }
2667

2668
    if (req.dnodeId1 == req.dnodeId2 || req.dnodeId1 == req.dnodeId3 || req.dnodeId2 == req.dnodeId3) {
27,393✔
2669
      code = TSDB_CODE_MND_INVALID_REPLICA;
673✔
2670
      goto _OVER;
673✔
2671
    }
2672

2673
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId &&
26,720✔
2674
        req.dnodeId1 != pVgroup->vnodeGid[2].dnodeId) {
12,570✔
2675
      newDnodeId[++newIndex] = req.dnodeId1;
11,230✔
2676
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
11,230✔
2677
    }
2678

2679
    if (req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId &&
26,720✔
2680
        req.dnodeId2 != pVgroup->vnodeGid[2].dnodeId) {
17,807✔
2681
      newDnodeId[++newIndex] = req.dnodeId2;
13,122✔
2682
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
13,122✔
2683
    }
2684

2685
    if (req.dnodeId3 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId3 != pVgroup->vnodeGid[1].dnodeId &&
26,720✔
2686
        req.dnodeId3 != pVgroup->vnodeGid[2].dnodeId) {
21,371✔
2687
      newDnodeId[++newIndex] = req.dnodeId3;
17,173✔
2688
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
17,173✔
2689
    }
2690

2691
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId &&
26,720✔
2692
        req.dnodeId3 != pVgroup->vnodeGid[0].dnodeId) {
13,196✔
2693
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[0].dnodeId;
12,526✔
2694
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
12,526✔
2695
    }
2696

2697
    if (req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId &&
26,720✔
2698
        req.dnodeId3 != pVgroup->vnodeGid[1].dnodeId) {
17,181✔
2699
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[1].dnodeId;
12,502✔
2700
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
12,502✔
2701
    }
2702

2703
    if (req.dnodeId1 != pVgroup->vnodeGid[2].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[2].dnodeId &&
26,720✔
2704
        req.dnodeId3 != pVgroup->vnodeGid[2].dnodeId) {
20,695✔
2705
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[2].dnodeId;
16,497✔
2706
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
16,497✔
2707
    }
2708

2709
    if (newDnodeId[0] != 0) {
26,720✔
2710
      pNew1 = mndAcquireDnode(pMnode, newDnodeId[0]);
25,881✔
2711
      if (pNew1 == NULL) {
25,881✔
2712
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2713
        if (terrno != 0) code = terrno;
×
2714
        goto _OVER;
×
2715
      }
2716
      if (!mndIsDnodeOnline(pNew1, curMs)) {
25,881✔
2717
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
673✔
2718
        goto _OVER;
673✔
2719
      }
2720
    }
2721

2722
    if (newDnodeId[1] != 0) {
26,047✔
2723
      pNew2 = mndAcquireDnode(pMnode, newDnodeId[1]);
10,414✔
2724
      if (pNew2 == NULL) {
10,414✔
2725
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2726
        if (terrno != 0) code = terrno;
×
2727
        goto _OVER;
×
2728
      }
2729
      if (!mndIsDnodeOnline(pNew2, curMs)) {
10,414✔
UNCOV
2730
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
UNCOV
2731
        goto _OVER;
×
2732
      }
2733
    }
2734

2735
    if (newDnodeId[2] != 0) {
26,047✔
2736
      pNew3 = mndAcquireDnode(pMnode, newDnodeId[2]);
5,230✔
2737
      if (pNew3 == NULL) {
5,230✔
2738
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2739
        if (terrno != 0) code = terrno;
×
2740
        goto _OVER;
×
2741
      }
2742
      if (!mndIsDnodeOnline(pNew3, curMs)) {
5,230✔
2743
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2744
        goto _OVER;
×
2745
      }
2746
    }
2747

2748
    if (oldDnodeId[0] != 0) {
26,047✔
2749
      pOld1 = mndAcquireDnode(pMnode, oldDnodeId[0]);
25,208✔
2750
      if (pOld1 == NULL) {
25,208✔
2751
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2752
        if (terrno != 0) code = terrno;
×
2753
        goto _OVER;
×
2754
      }
2755
      if (!mndIsDnodeOnline(pOld1, curMs)) {
25,208✔
2756
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
1,039✔
2757
        goto _OVER;
1,039✔
2758
      }
2759
    }
2760

2761
    if (oldDnodeId[1] != 0) {
25,008✔
2762
      pOld2 = mndAcquireDnode(pMnode, oldDnodeId[1]);
9,375✔
2763
      if (pOld2 == NULL) {
9,375✔
2764
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2765
        if (terrno != 0) code = terrno;
×
2766
        goto _OVER;
×
2767
      }
2768
      if (!mndIsDnodeOnline(pOld2, curMs)) {
9,375✔
2769
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2770
        goto _OVER;
×
2771
      }
2772
    }
2773

2774
    if (oldDnodeId[2] != 0) {
25,008✔
2775
      pOld3 = mndAcquireDnode(pMnode, oldDnodeId[2]);
4,191✔
2776
      if (pOld3 == NULL) {
4,191✔
2777
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2778
        if (terrno != 0) code = terrno;
×
2779
        goto _OVER;
×
2780
      }
2781
      if (!mndIsDnodeOnline(pOld3, curMs)) {
4,191✔
2782
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2783
        goto _OVER;
×
2784
      }
2785
    }
2786

2787
    if (pNew1 == NULL && pOld1 == NULL && pNew2 == NULL && pOld2 == NULL && pNew3 == NULL && pOld3 == NULL) {
25,008✔
2788
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2789
      code = 0;
839✔
2790
      goto _OVER;
839✔
2791
    }
2792

2793
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, pNew3, pOld3);
24,169✔
2794

2795
  } else if (pVgroup->replica == 2) {
1,368✔
2796
    if (req.dnodeId1 <= 0 || req.dnodeId2 <= 0) {
1,368✔
2797
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2798
      goto _OVER;
×
2799
    }
2800

2801
    if (req.dnodeId1 == req.dnodeId2) {
1,368✔
2802
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2803
      goto _OVER;
×
2804
    }
2805

2806
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId) {
1,368✔
2807
      newDnodeId[++newIndex] = req.dnodeId1;
1,368✔
2808
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
1,368✔
2809
    }
2810

2811
    if (req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId) {
1,368✔
2812
      newDnodeId[++newIndex] = req.dnodeId2;
1,368✔
2813
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
1,368✔
2814
    }
2815

2816
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId) {
1,368✔
2817
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[0].dnodeId;
1,368✔
2818
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
1,368✔
2819
    }
2820

2821
    if (req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId) {
1,368✔
2822
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[1].dnodeId;
1,368✔
2823
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
1,368✔
2824
    }
2825

2826
    if (newDnodeId[0] != 0) {
1,368✔
2827
      pNew1 = mndAcquireDnode(pMnode, newDnodeId[0]);
1,368✔
2828
      if (pNew1 == NULL) {
1,368✔
2829
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2830
        if (terrno != 0) code = terrno;
×
2831
        goto _OVER;
×
2832
      }
2833
      if (!mndIsDnodeOnline(pNew1, curMs)) {
1,368✔
2834
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2835
        goto _OVER;
×
2836
      }
2837
    }
2838

2839
    if (newDnodeId[1] != 0) {
1,368✔
2840
      pNew2 = mndAcquireDnode(pMnode, newDnodeId[1]);
1,368✔
2841
      if (pNew2 == NULL) {
1,368✔
2842
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2843
        if (terrno != 0) code = terrno;
×
2844
        goto _OVER;
×
2845
      }
2846
      if (!mndIsDnodeOnline(pNew2, curMs)) {
1,368✔
2847
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2848
        goto _OVER;
×
2849
      }
2850
    }
2851

2852
    if (oldDnodeId[0] != 0) {
1,368✔
2853
      pOld1 = mndAcquireDnode(pMnode, oldDnodeId[0]);
1,368✔
2854
      if (pOld1 == NULL) {
1,368✔
2855
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2856
        if (terrno != 0) code = terrno;
×
2857
        goto _OVER;
×
2858
      }
2859
      if (!mndIsDnodeOnline(pOld1, curMs)) {
1,368✔
2860
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2861
        goto _OVER;
×
2862
      }
2863
    }
2864

2865
    if (oldDnodeId[1] != 0) {
1,368✔
2866
      pOld2 = mndAcquireDnode(pMnode, oldDnodeId[1]);
1,368✔
2867
      if (pOld2 == NULL) {
1,368✔
2868
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2869
        if (terrno != 0) code = terrno;
×
2870
        goto _OVER;
×
2871
      }
2872
      if (!mndIsDnodeOnline(pOld2, curMs)) {
1,368✔
2873
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2874
        goto _OVER;
×
2875
      }
2876
    }
2877

2878
    if (pNew1 == NULL && pOld1 == NULL && pNew2 == NULL && pOld2 == NULL) {
1,368✔
2879
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2880
      code = 0;
×
2881
      goto _OVER;
×
2882
    }
2883

2884
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, NULL, NULL);
1,368✔
2885
  } else {
2886
    code = TSDB_CODE_MND_REQ_REJECTED;
×
2887
    goto _OVER;
×
2888
  }
2889

2890
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
36,369✔
2891

2892
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
36,369✔
2893
    char obj[33] = {0};
36,369✔
2894
    (void)tsnprintf(obj, sizeof(obj), "%d", req.vgId);
36,369✔
2895

2896
    int64_t tse = taosGetTimestampMs();
36,369✔
2897
    double  duration = (double)(tse - tss);
36,369✔
2898
    duration = duration / 1000;
36,369✔
2899
    auditRecord(pReq, pMnode->clusterId, "RedistributeVgroup", "", obj, req.sql, req.sqlLen, duration, 0);
36,369✔
2900
  }
2901
_OVER:
44,304✔
2902
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
44,304✔
2903
    mError("vgId:%d, failed to redistribute to dnode %d:%d:%d since %s", req.vgId, req.dnodeId1, req.dnodeId2,
8,671✔
2904
           req.dnodeId3, tstrerror(code));
2905
  }
2906

2907
  mndReleaseDnode(pMnode, pNew1);
44,304✔
2908
  mndReleaseDnode(pMnode, pNew2);
44,304✔
2909
  mndReleaseDnode(pMnode, pNew3);
44,304✔
2910
  mndReleaseDnode(pMnode, pOld1);
44,304✔
2911
  mndReleaseDnode(pMnode, pOld2);
44,304✔
2912
  mndReleaseDnode(pMnode, pOld3);
44,304✔
2913
  mndReleaseVgroup(pMnode, pVgroup);
44,304✔
2914
  mndReleaseDb(pMnode, pDb);
44,304✔
2915
  tFreeSRedistributeVgroupReq(&req);
44,304✔
2916

2917
  TAOS_RETURN(code);
44,304✔
2918
}
2919

2920
static void *mndBuildSForceBecomeFollowerReq(SMnode *pMnode, SVgObj *pVgroup, int32_t dnodeId, int32_t *pContLen) {
4,138✔
2921
  SForceBecomeFollowerReq balanceReq = {
4,138✔
2922
      .vgId = pVgroup->vgId,
4,138✔
2923
  };
2924

2925
  int32_t contLen = tSerializeSForceBecomeFollowerReq(NULL, 0, &balanceReq);
4,138✔
2926
  if (contLen < 0) {
4,138✔
2927
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2928
    return NULL;
×
2929
  }
2930
  contLen += sizeof(SMsgHead);
4,138✔
2931

2932
  void *pReq = taosMemoryMalloc(contLen);
4,138✔
2933
  if (pReq == NULL) {
4,138✔
2934
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2935
    return NULL;
×
2936
  }
2937

2938
  SMsgHead *pHead = pReq;
4,138✔
2939
  pHead->contLen = htonl(contLen);
4,138✔
2940
  pHead->vgId = htonl(pVgroup->vgId);
4,138✔
2941

2942
  if (tSerializeSForceBecomeFollowerReq((char *)pReq + sizeof(SMsgHead), contLen, &balanceReq) < 0) {
4,138✔
2943
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2944
    taosMemoryFree(pReq);
×
2945
    return NULL;
×
2946
  }
2947
  *pContLen = contLen;
4,138✔
2948
  return pReq;
4,138✔
2949
}
2950

2951
int32_t mndAddBalanceVgroupLeaderAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, int32_t dnodeId) {
4,138✔
2952
  int32_t    code = 0;
4,138✔
2953
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
4,138✔
2954
  if (pDnode == NULL) {
4,138✔
2955
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2956
    if (terrno != 0) code = terrno;
×
2957
    TAOS_RETURN(code);
×
2958
  }
2959

2960
  STransAction action = {0};
4,138✔
2961
  action.epSet = mndGetDnodeEpset(pDnode);
4,138✔
2962
  mndReleaseDnode(pMnode, pDnode);
4,138✔
2963

2964
  int32_t contLen = 0;
4,138✔
2965
  void   *pReq = mndBuildSForceBecomeFollowerReq(pMnode, pVgroup, dnodeId, &contLen);
4,138✔
2966
  if (pReq == NULL) {
4,138✔
2967
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2968
    if (terrno != 0) code = terrno;
×
2969
    TAOS_RETURN(code);
×
2970
  }
2971

2972
  action.pCont = pReq;
4,138✔
2973
  action.contLen = contLen;
4,138✔
2974
  action.msgType = TDMT_SYNC_FORCE_FOLLOWER;
4,138✔
2975

2976
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
4,138✔
2977
    taosMemoryFree(pReq);
×
2978
    TAOS_RETURN(code);
×
2979
  }
2980

2981
  TAOS_RETURN(code);
4,138✔
2982
}
2983

2984
static void *mndBuildAlterVnodeElectBaselineReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId,
24,828✔
2985
                                          int32_t *pContLen, int32_t ms) {
2986
  SAlterVnodeElectBaselineReq alterReq = {
24,828✔
2987
      .vgId = pVgroup->vgId,
24,828✔
2988
      .electBaseLine = ms,
2989
  };
2990

2991
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &alterReq);
24,828✔
2992
  if (contLen < 0) {
24,828✔
2993
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2994
    return NULL;
×
2995
  }
2996

2997
  void *pReq = taosMemoryMalloc(contLen);
24,828✔
2998
  if (pReq == NULL) {
24,828✔
2999
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3000
    return NULL;
×
3001
  }
3002

3003
  if (tSerializeSAlterVnodeReplicaReq(pReq, contLen, &alterReq) < 0) {
24,828✔
3004
    mError("vgId:%d, failed to serialize alter vnode req,since %s", alterReq.vgId, terrstr());
×
3005
    taosMemoryFree(pReq);
×
3006
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3007
    return NULL;
×
3008
  }
3009
  *pContLen = contLen;
24,828✔
3010
  return pReq;
24,828✔
3011
}
3012

3013
static int32_t mndAddAlterVnodeElectionBaselineActionToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId, int32_t ms) {
24,828✔
3014
  int32_t    code = 0;
24,828✔
3015
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
24,828✔
3016
  if (pDnode == NULL) {
24,828✔
3017
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3018
    if (terrno != 0) code = terrno;
×
3019
    TAOS_RETURN(code);
×
3020
  }
3021

3022
  STransAction action = {0};
24,828✔
3023
  action.epSet = mndGetDnodeEpset(pDnode);
24,828✔
3024
  mndReleaseDnode(pMnode, pDnode);
24,828✔
3025

3026
  int32_t contLen = 0;
24,828✔
3027
  void   *pReq = mndBuildAlterVnodeElectBaselineReq(pMnode, pDb, pVgroup, dnodeId, &contLen, ms);
24,828✔
3028
  if (pReq == NULL) {
24,828✔
3029
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3030
    if (terrno != 0) code = terrno;
×
3031
    TAOS_RETURN(code);
×
3032
  }
3033

3034
  action.pCont = pReq;
24,828✔
3035
  action.contLen = contLen;
24,828✔
3036
  action.msgType = TDMT_VND_ALTER_ELECTBASELINE;
24,828✔
3037
  action.groupId = pVgroup->vgId;
24,828✔
3038

3039
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
24,828✔
3040
    taosMemoryFree(pReq);
×
3041
    TAOS_RETURN(code);
×
3042
  }
3043

3044
  TAOS_RETURN(code);
24,828✔
3045
}
3046

3047
static int32_t mndAddAlterVgroupElectionBaselineActionToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans, int32_t index){
8,276✔
3048
  int32_t code = 0;
8,276✔
3049
  SSdb   *pSdb = pMnode->pSdb;
8,276✔
3050

3051
  int32_t vgid = pVgroup->vgId;
8,276✔
3052
  int8_t  replica = pVgroup->replica;
8,276✔
3053

3054
  if (pVgroup->replica <= 1) {
8,276✔
3055
    mInfo("trans:%d, vgid:%d no need to balance, replica:%d", pTrans->id, vgid, replica);
×
3056
    return -1;
×
3057
  }
3058

3059
  for(int32_t i = 0; i < 3; i++){
33,104✔
3060
    if(i == index%3){
24,828✔
3061
      mInfo("trans:%d, balance leader to dnode:%d", pTrans->id, pVgroup->vnodeGid[i].dnodeId);
4,138✔
3062
      TAOS_CHECK_RETURN(mndAddAlterVnodeElectionBaselineActionToTrans(pMnode, pTrans, NULL, pVgroup,
4,138✔
3063
                                                                      pVgroup->vnodeGid[i].dnodeId, 1500));
3064
    }
3065
    else{
3066
    TAOS_CHECK_RETURN(
20,690✔
3067
        mndAddAlterVnodeElectionBaselineActionToTrans(pMnode, pTrans, NULL, pVgroup, pVgroup->vnodeGid[i].dnodeId, 5000));
3068
    }
3069
  }
3070
  return code; 
8,276✔
3071
}
3072

3073
int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans, int32_t index) {
4,879✔
3074
  int32_t code = 0;
4,879✔
3075
  SSdb   *pSdb = pMnode->pSdb;
4,879✔
3076

3077
  int32_t vgid = pVgroup->vgId;
4,879✔
3078
  int8_t  replica = pVgroup->replica;
4,879✔
3079

3080
  if (pVgroup->replica <= 1) {
4,879✔
3081
    mInfo("trans:%d, vgid:%d no need to balance, replica:%d", pTrans->id, vgid, replica);
264✔
3082
    return -1;
264✔
3083
  }
3084

3085
  int32_t dnodeId = 0;
4,615✔
3086

3087
  for (int i = 0; i < replica; i++) {
9,696✔
3088
    if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER) {
9,219✔
3089
      dnodeId = pVgroup->vnodeGid[i].dnodeId;
4,138✔
3090
      break;
4,138✔
3091
    }
3092
  }
3093

3094
  bool       exist = false;
4,615✔
3095
  bool       online = false;
4,615✔
3096
  int64_t    curMs = taosGetTimestampMs();
4,615✔
3097
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
4,615✔
3098
  if (pDnode != NULL) {
4,615✔
3099
    exist = true;
4,138✔
3100
    online = mndIsDnodeOnline(pDnode, curMs);
4,138✔
3101
    mndReleaseDnode(pMnode, pDnode);
4,138✔
3102
  }
3103

3104
  if (exist && online) {
8,753✔
3105
    mInfo("trans:%d, vgid:%d force drop leader from dnode:%d", pTrans->id, vgid, dnodeId);    
4,138✔
3106
    TAOS_CHECK_RETURN(mndAddAlterVgroupElectionBaselineActionToTrans(pMnode, pVgroup, pTrans, index));
4,138✔
3107

3108
    if ((code = mndAddBalanceVgroupLeaderAction(pMnode, pTrans, pVgroup, dnodeId)) != 0) {
4,138✔
3109
      mError("trans:%d, vgid:%d failed to be balanced to dnode:%d", pTrans->id, vgid, dnodeId);
×
3110
      TAOS_RETURN(code);
×
3111
    }
3112

3113
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, NULL, pVgroup));
4,138✔
3114

3115
    TAOS_CHECK_RETURN(mndAddAlterVgroupElectionBaselineActionToTrans(pMnode, pVgroup, pTrans, -1));
4,138✔
3116

3117
    SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
4,138✔
3118
    if (pDb == NULL) {
4,138✔
3119
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3120
      if (terrno != 0) code = terrno;
×
3121
      mError("trans:%d, vgid:%d failed to be balanced to dnode:%d, because db not exist", pTrans->id, vgid, dnodeId);
×
3122
      TAOS_RETURN(code);
×
3123
    }
3124

3125
    mndReleaseDb(pMnode, pDb);
4,138✔
3126
  } else {
3127
    mInfo("trans:%d, vgid:%d cant be balanced to dnode:%d, exist:%d, online:%d", pTrans->id, vgid, dnodeId, exist,
477✔
3128
          online);
3129
  }
3130

3131
  TAOS_RETURN(code);
4,615✔
3132
}
3133

3134
extern int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq);
3135

3136
int32_t mndProcessVgroupBalanceLeaderMsg(SRpcMsg *pReq) { return mndProcessVgroupBalanceLeaderMsgImp(pReq); }
2,031✔
3137

3138
#ifndef TD_ENTERPRISE
3139
int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq) { return 0; }
3140
#endif
3141

3142
static int32_t mndCheckDnodeMemory(SMnode *pMnode, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pOldVgroup,
189,839✔
3143
                                   SVgObj *pNewVgroup, SArray *pArray) {
3144
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
578,106✔
3145
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
388,267✔
3146
    bool       inVgroup = false;
388,267✔
3147
    int64_t    oldMemUsed = 0;
388,267✔
3148
    int64_t    newMemUsed = 0;
388,267✔
3149
    mDebug("db:%s, vgId:%d, check dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
388,267✔
3150
           pDnode->id, pDnode->memAvail, pDnode->memUsed);
3151
    for (int32_t j = 0; j < pOldVgroup->replica; ++j) {
1,124,078✔
3152
      SVnodeGid *pVgId = &pOldVgroup->vnodeGid[j];
735,811✔
3153
      if (pDnode->id == pVgId->dnodeId) {
735,811✔
3154
        oldMemUsed = mndGetVgroupMemory(pMnode, pOldDb, pOldVgroup);
305,687✔
3155
        inVgroup = true;
305,687✔
3156
      }
3157
    }
3158
    for (int32_t j = 0; j < pNewVgroup->replica; ++j) {
1,124,078✔
3159
      SVnodeGid *pVgId = &pNewVgroup->vnodeGid[j];
735,811✔
3160
      if (pDnode->id == pVgId->dnodeId) {
735,811✔
3161
        newMemUsed = mndGetVgroupMemory(pMnode, pNewDb, pNewVgroup);
305,687✔
3162
        inVgroup = true;
305,687✔
3163
      }
3164
    }
3165

3166
    mDebug("db:%s, vgId:%d, memory in dnode:%d, oldUsed:%" PRId64 ", newUsed:%" PRId64, pNewVgroup->dbName,
388,267✔
3167
           pNewVgroup->vgId, pDnode->id, oldMemUsed, newMemUsed);
3168

3169
    pDnode->memUsed = pDnode->memUsed - oldMemUsed + newMemUsed;
388,267✔
3170
    if (pDnode->memAvail - pDnode->memUsed <= 0) {
388,267✔
3171
      mError("db:%s, vgId:%d, no enough memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName,
×
3172
             pNewVgroup->vgId, pDnode->id, pDnode->memAvail, pDnode->memUsed);
3173
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
3174
    } else if (inVgroup) {
388,267✔
3175
      mInfo("db:%s, vgId:%d, memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
305,687✔
3176
            pDnode->id, pDnode->memAvail, pDnode->memUsed);
3177
    } else {
3178
    }
3179
  }
3180
  return 0;
189,839✔
3181
}
3182

3183
int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pVgroup,
225,833✔
3184
                                  SArray *pArray, SVgObj *pNewVgroup) {
3185
  int32_t code = 0;
225,833✔
3186
  memcpy(pNewVgroup, pVgroup, sizeof(SVgObj));
225,833✔
3187

3188
  if (pVgroup->replica <= 0 || pVgroup->replica == pNewDb->cfg.replications) {
225,833✔
3189
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfigAction(pMnode, pTrans, pNewDb, pVgroup));
189,839✔
3190
    TAOS_CHECK_RETURN(mndCheckDnodeMemory(pMnode, pOldDb, pNewDb, pNewVgroup, pVgroup, pArray));
189,839✔
3191
    return 0;
189,839✔
3192
  }
3193

3194
  // mndTransSetGroupParallel(pTrans);
3195

3196
  if (pNewDb->cfg.replications == 3) {
35,994✔
3197
    mInfo("trans:%d, db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
31,204✔
3198
          pVgroup->vnodeGid[0].dnodeId);
3199

3200
    // add second
3201
    if (pNewVgroup->replica == 1) {
31,204✔
3202
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
31,204✔
3203
    }
3204

3205
    // learner stage
3206
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
30,526✔
3207
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
30,526✔
3208
    TAOS_CHECK_RETURN(
30,526✔
3209
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3210

3211
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[1]));
30,526✔
3212

3213
    // follower stage
3214
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
30,526✔
3215
    TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
30,526✔
3216
    TAOS_CHECK_RETURN(
30,526✔
3217
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3218

3219
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
30,526✔
3220

3221
    // add third
3222
    if (pNewVgroup->replica == 2) {
30,526✔
3223
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
30,526✔
3224
    }
3225

3226
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
27,613✔
3227
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
27,613✔
3228
    pNewVgroup->vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
27,613✔
3229
    TAOS_CHECK_RETURN(
27,613✔
3230
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3231
    TAOS_CHECK_RETURN(
27,613✔
3232
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
3233
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[2]));
27,613✔
3234

3235
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
27,613✔
3236
  } else if (pNewDb->cfg.replications == 1) {
4,790✔
3237
    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,
3,418✔
3238
          pVgroup->dbName, pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId, pVgroup->vnodeGid[1].dnodeId,
3239
          pVgroup->vnodeGid[2].dnodeId);
3240

3241
    SVnodeGid del1 = {0};
3,418✔
3242
    SVnodeGid del2 = {0};
3,418✔
3243
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroup(pMnode, pTrans, pNewVgroup, pArray, &del1));
3,418✔
3244
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &del1, true));
3,418✔
3245
    TAOS_CHECK_RETURN(
3,418✔
3246
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3247
    TAOS_CHECK_RETURN(
3,418✔
3248
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
3249
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
3,418✔
3250

3251
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroup(pMnode, pTrans, pNewVgroup, pArray, &del2));
3,418✔
3252
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &del2, true));
3,418✔
3253
    TAOS_CHECK_RETURN(
3,418✔
3254
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3255
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
3,418✔
3256
  } else if (pNewDb->cfg.replications == 2) {
1,372✔
3257
    mInfo("trans:%d, db:%s, vgId:%d, will add 1 vnode, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
1,372✔
3258
          pVgroup->vnodeGid[0].dnodeId);
3259

3260
    // add second
3261
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
1,372✔
3262

3263
    // learner stage
3264
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
1,372✔
3265
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
1,372✔
3266
    TAOS_CHECK_RETURN(
1,372✔
3267
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3268

3269
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[1]));
1,372✔
3270

3271
    // follower stage
3272
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
1,372✔
3273
    TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
1,372✔
3274
    TAOS_CHECK_RETURN(
1,372✔
3275
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3276

3277
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
1,372✔
3278
  } else {
3279
    return -1;
×
3280
  }
3281

3282
  mndSortVnodeGid(pNewVgroup);
32,403✔
3283

3284
  {
3285
    SSdbRaw *pVgRaw = mndVgroupActionEncode(pNewVgroup);
32,403✔
3286
    if (pVgRaw == NULL) {
32,403✔
3287
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3288
      if (terrno != 0) code = terrno;
×
3289
      TAOS_RETURN(code);
×
3290
    }
3291
    if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
32,403✔
3292
      sdbFreeRaw(pVgRaw);
×
3293
      TAOS_RETURN(code);
×
3294
    }
3295
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
32,403✔
3296
    if (code != 0) {
32,403✔
3297
      mError("vgId:%d, failed to set raw status since %s at line:%d", pNewVgroup->vgId, tstrerror(code), __LINE__);
×
3298
      TAOS_RETURN(code);
×
3299
    }
3300
  }
3301

3302
  TAOS_RETURN(code);
32,403✔
3303
}
3304

3305
int32_t mndBuildRaftAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pVgroup,
×
3306
                                      SArray *pArray) {
3307
  int32_t code = 0;
×
3308
  SVgObj  newVgroup = {0};
×
3309
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
×
3310

3311
  if (pVgroup->replica <= 0 || pVgroup->replica == pNewDb->cfg.replications) {
×
3312
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfigAction(pMnode, pTrans, pNewDb, pVgroup));
×
3313
    TAOS_CHECK_RETURN(mndCheckDnodeMemory(pMnode, pOldDb, pNewDb, &newVgroup, pVgroup, pArray));
×
3314
    return 0;
×
3315
  }
3316

3317
  mndTransSetSerial(pTrans);
×
3318

3319
  mInfo("trans:%d, vgId:%d, alter vgroup, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3320
        pVgroup->syncConfChangeVer, pVgroup->version, pVgroup->replica);
3321

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

3326
    // add second
3327
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray));
×
3328
    // add third
3329
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray));
×
3330

3331
    // add learner stage
3332
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3333
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3334
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3335
    TAOS_CHECK_RETURN(
×
3336
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3337
    mInfo("trans:%d, vgId:%d, add change config, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id,
×
3338
          pVgroup->vgId, newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3339
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[1]));
×
3340
    mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3341
          newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3342
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[2]));
×
3343
    mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3344
          newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3345

3346
    // check learner
3347
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3348
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3349
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3350
    TAOS_CHECK_RETURN(
×
3351
        mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId));
3352
    TAOS_CHECK_RETURN(
×
3353
        mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[2].dnodeId));
3354

3355
    // change raft type
3356
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3357
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3358
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3359
    TAOS_CHECK_RETURN(
×
3360
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3361

3362
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3363

3364
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3365
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3366
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3367
    TAOS_CHECK_RETURN(
×
3368
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3369

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

3372
    SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3373
    if (pVgRaw == NULL) {
×
3374
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3375
      if (terrno != 0) code = terrno;
×
3376
      TAOS_RETURN(code);
×
3377
    }
3378
    if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
×
3379
      sdbFreeRaw(pVgRaw);
×
3380
      TAOS_RETURN(code);
×
3381
    }
3382
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3383
    if (code != 0) {
×
3384
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3385
             __LINE__);
3386
      TAOS_RETURN(code);
×
3387
    }
3388
  } else if (newVgroup.replica == 3 && pNewDb->cfg.replications == 1) {
×
3389
    mInfo("db:%s, vgId:%d, will remove 2 vnodes, vn:0 dnode:%d vn:1 dnode:%d vn:2 dnode:%d", pVgroup->dbName,
×
3390
          pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId, pVgroup->vnodeGid[1].dnodeId, pVgroup->vnodeGid[2].dnodeId);
3391

3392
    SVnodeGid del1 = {0};
×
3393
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del1));
×
3394

3395
    TAOS_CHECK_RETURN(
×
3396
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3397

3398
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3399

3400
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &del1, true));
×
3401

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

3419
    SVnodeGid del2 = {0};
×
3420
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del2));
×
3421

3422
    TAOS_CHECK_RETURN(
×
3423
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3424

3425
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3426

3427
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &del2, true));
×
3428

3429
    pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3430
    if (pVgRaw == NULL) {
×
3431
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3432
      if (terrno != 0) code = terrno;
×
3433
      TAOS_RETURN(code);
×
3434
    }
3435
    if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
×
3436
      sdbFreeRaw(pVgRaw);
×
3437
      TAOS_RETURN(code);
×
3438
    }
3439
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3440
    if (code != 0) {
×
3441
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3442
             __LINE__);
3443
      TAOS_RETURN(code);
×
3444
    }
3445
  } else {
3446
    return -1;
×
3447
  }
3448

3449
  mndSortVnodeGid(&newVgroup);
×
3450

3451
  {
3452
    SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3453
    if (pVgRaw == NULL) {
×
3454
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3455
      if (terrno != 0) code = terrno;
×
3456
      TAOS_RETURN(code);
×
3457
    }
3458
    if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
×
3459
      sdbFreeRaw(pVgRaw);
×
3460
      TAOS_RETURN(code);
×
3461
    }
3462
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3463
    if (code != 0) {
×
3464
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3465
             __LINE__);
3466
      TAOS_RETURN(code);
×
3467
    }
3468
  }
3469

3470
  TAOS_RETURN(code);
×
3471
}
3472

3473
int32_t mndBuildRestoreAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *db, SVgObj *pVgroup, SDnodeObj *pDnode,
2,330✔
3474
                                         SDnodeObj *pAnotherDnode) {
3475
  int32_t code = 0;
2,330✔
3476
  SVgObj  newVgroup = {0};
2,330✔
3477
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
2,330✔
3478

3479
  mInfo("trans:%d, db:%s, vgId:%d, restore vnodes, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
2,330✔
3480
        pVgroup->vnodeGid[0].dnodeId);
3481

3482
  if (newVgroup.replica == 1) {
2,330✔
3483
    int selected = 0;
×
3484
    for (int i = 0; i < newVgroup.replica; i++) {
×
3485
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3486
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3487
        selected = i;
×
3488
      }
3489
    }
3490
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, &newVgroup.vnodeGid[selected]));
×
3491
  } else if (newVgroup.replica == 2) {
2,330✔
3492
    for (int i = 0; i < newVgroup.replica; i++) {
×
3493
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3494
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3495
      } else {
3496
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3497
      }
3498
    }
3499
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pAnotherDnode));
×
3500

3501
    for (int i = 0; i < newVgroup.replica; i++) {
×
3502
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3503
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3504
      } else {
3505
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3506
      }
3507
    }
3508
    TAOS_CHECK_RETURN(mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode));
×
3509

3510
    for (int i = 0; i < newVgroup.replica; i++) {
×
3511
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3512
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3513
      }
3514
    }
3515
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode));
×
3516
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pAnotherDnode));
×
3517
  } else if (newVgroup.replica == 3) {
2,330✔
3518
    for (int i = 0; i < newVgroup.replica; i++) {
9,320✔
3519
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
6,990✔
3520
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
2,330✔
3521
      } else {
3522
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
4,660✔
3523
      }
3524
    }
3525
    TAOS_CHECK_RETURN(mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode));
2,330✔
3526

3527
    for (int i = 0; i < newVgroup.replica; i++) {
9,320✔
3528
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
6,990✔
3529
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
6,990✔
3530
      }
3531
    }
3532
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode));
2,330✔
3533
  }
3534
  SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
2,330✔
3535
  if (pVgRaw == NULL) {
2,330✔
3536
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3537
    if (terrno != 0) code = terrno;
×
3538
    TAOS_RETURN(code);
×
3539
  }
3540
  if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
2,330✔
3541
    sdbFreeRaw(pVgRaw);
×
3542
    TAOS_RETURN(code);
×
3543
  }
3544
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
2,330✔
3545
  if (code != 0) {
2,330✔
3546
    mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code), __LINE__);
×
3547
    TAOS_RETURN(code);
×
3548
  }
3549

3550
  TAOS_RETURN(code);
2,330✔
3551
}
3552

3553
static int32_t mndAddAdjustVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
×
3554
  return 0;
×
3555
}
3556

3557
typedef int32_t (*FpTransActionCb)(STrans *pTrans, SSdbRaw *pRaw);
3558

3559
static int32_t mndAddVgStatusAction(STrans *pTrans, SVgObj *pVg, ESdbStatus vgStatus, ETrnStage stage) {
73,503✔
3560
  int32_t         code = 0;
73,503✔
3561
  FpTransActionCb appendActionCb = (stage == TRN_STAGE_COMMIT_ACTION) ? mndTransAppendCommitlog : mndTransAppendRedolog;
73,503✔
3562
  SSdbRaw        *pRaw = mndVgroupActionEncode(pVg);
73,503✔
3563
  if (pRaw == NULL) {
73,503✔
3564
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3565
    if (terrno != 0) code = terrno;
×
3566
    goto _err;
×
3567
  }
3568
  if ((code = appendActionCb(pTrans, pRaw)) != 0) goto _err;
73,503✔
3569
  code = sdbSetRawStatus(pRaw, vgStatus);
73,503✔
3570
  if (code != 0) {
73,503✔
3571
    mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", pVg->vgId, tstrerror(code), __LINE__);
×
3572
    goto _err;
×
3573
  }
3574
  pRaw = NULL;
73,503✔
3575
  TAOS_RETURN(code);
73,503✔
3576
_err:
×
3577
  sdbFreeRaw(pRaw);
×
3578
  TAOS_RETURN(code);
×
3579
}
3580

3581
static int32_t mndAddDbStatusAction(STrans *pTrans, SDbObj *pDb, ESdbStatus dbStatus, ETrnStage stage) {
29,573✔
3582
  int32_t         code = 0;
29,573✔
3583
  FpTransActionCb appendActionCb = (stage == TRN_STAGE_COMMIT_ACTION) ? mndTransAppendCommitlog : mndTransAppendRedolog;
29,573✔
3584
  SSdbRaw        *pRaw = mndDbActionEncode(pDb);
29,573✔
3585
  if (pRaw == NULL) {
29,573✔
3586
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3587
    if (terrno != 0) code = terrno;
×
3588
    goto _err;
×
3589
  }
3590
  if ((code = appendActionCb(pTrans, pRaw)) != 0) goto _err;
29,573✔
3591
  code = sdbSetRawStatus(pRaw, dbStatus);
29,573✔
3592
  if (code != 0) {
29,573✔
3593
    mError("db:%s, failed to set raw status to ready, error:%s, line:%d", pDb->name, tstrerror(code), __LINE__);
×
3594
    goto _err;
×
3595
  }
3596
  pRaw = NULL;
29,573✔
3597
  TAOS_RETURN(code);
29,573✔
3598
_err:
×
3599
  sdbFreeRaw(pRaw);
×
3600
  TAOS_RETURN(code);
×
3601
}
3602

3603
int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
16,325✔
3604
  int32_t code = -1;
16,325✔
3605
  STrans *pTrans = NULL;
16,325✔
3606
  SDbObj  dbObj = {0};
16,325✔
3607
  SArray *pArray = mndBuildDnodesArray(pMnode, 0, NULL);
16,325✔
3608

3609
#if defined(USE_SHARED_STORAGE)
3610
  if (tsSsEnabled) {
16,325✔
3611
    code = TSDB_CODE_OPS_NOT_SUPPORT;
×
3612
    mError("vgId:%d, db:%s, shared storage exists, split vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
×
3613
    goto _OVER;
×
3614
  }
3615
#endif
3616

3617
  /*
3618
    if (pDb->cfg.withArbitrator) {
3619
      code = TSDB_CODE_OPS_NOT_SUPPORT;
3620
      mError("vgId:%d, db:%s, with arbitrator, split vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
3621
      goto _OVER;
3622
    }
3623
  */
3624

3625
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "split-vgroup");
16,325✔
3626
  if (pTrans == NULL) {
16,325✔
3627
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3628
    if (terrno != 0) code = terrno;
×
3629
    goto _OVER;
×
3630
  }
3631
  mndTransSetSerial(pTrans);
16,325✔
3632
  mInfo("trans:%d, used to split vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
16,325✔
3633

3634
  mndTransSetDbName(pTrans, pDb->name, NULL);
16,325✔
3635
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
16,325✔
3636
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
16,243✔
3637

3638
  SVgObj newVg1 = {0};
16,243✔
3639
  memcpy(&newVg1, pVgroup, sizeof(SVgObj));
16,243✔
3640
  mInfo("vgId:%d, vgroup info before split, replica:%d hashBegin:%u hashEnd:%u", newVg1.vgId, newVg1.replica,
16,243✔
3641
        newVg1.hashBegin, newVg1.hashEnd);
3642
  for (int32_t i = 0; i < newVg1.replica; ++i) {
52,842✔
3643
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg1.vgId, i, newVg1.vnodeGid[i].dnodeId);
36,599✔
3644
  }
3645

3646
  if (newVg1.replica == 1) {
16,243✔
3647
    TAOS_CHECK_GOTO(mndAddVnodeToVgroup(pMnode, pTrans, &newVg1, pArray), NULL, _OVER);
5,722✔
3648

3649
    newVg1.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
5,722✔
3650
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
5,722✔
3651
                    _OVER);
3652
    TAOS_CHECK_GOTO(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg1, &newVg1.vnodeGid[1]), NULL, _OVER);
5,722✔
3653

3654
    newVg1.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
5,722✔
3655
    TAOS_CHECK_GOTO(mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[1].dnodeId), NULL, _OVER);
5,722✔
3656
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
5,722✔
3657
                    _OVER);
3658

3659
    TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
5,722✔
3660
  } else if (newVg1.replica == 3) {
10,521✔
3661
    SVnodeGid del1 = {0};
9,835✔
3662
    TAOS_CHECK_GOTO(mndRemoveVnodeFromVgroup(pMnode, pTrans, &newVg1, pArray, &del1), NULL, _OVER);
9,835✔
3663
    TAOS_CHECK_GOTO(mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg1, &del1, true), NULL, _OVER);
9,835✔
3664
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
9,835✔
3665
                    _OVER);
3666
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[1].dnodeId), NULL,
9,835✔
3667
                    _OVER);
3668
  } else {
3669
    // goto _OVER;
3670
  }
3671

3672
  for (int32_t i = 0; i < newVg1.replica; ++i) {
48,729✔
3673
    TAOS_CHECK_GOTO(mndAddDisableVnodeWriteAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[i].dnodeId), NULL,
32,486✔
3674
                    _OVER);
3675
  }
3676
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
16,243✔
3677

3678
  SVgObj newVg2 = {0};
16,243✔
3679
  memcpy(&newVg2, &newVg1, sizeof(SVgObj));
16,243✔
3680
  newVg1.replica = 1;
16,243✔
3681
  newVg1.hashEnd = newVg1.hashBegin / 2 + newVg1.hashEnd / 2;
16,243✔
3682
  memset(&newVg1.vnodeGid[1], 0, sizeof(SVnodeGid));
16,243✔
3683

3684
  newVg2.replica = 1;
16,243✔
3685
  newVg2.hashBegin = newVg1.hashEnd + 1;
16,243✔
3686
  memcpy(&newVg2.vnodeGid[0], &newVg2.vnodeGid[1], sizeof(SVnodeGid));
16,243✔
3687
  memset(&newVg2.vnodeGid[1], 0, sizeof(SVnodeGid));
16,243✔
3688

3689
  mInfo("vgId:%d, vgroup info after split, replica:%d hashrange:[%u, %u] vnode:0 dnode:%d", newVg1.vgId, newVg1.replica,
16,243✔
3690
        newVg1.hashBegin, newVg1.hashEnd, newVg1.vnodeGid[0].dnodeId);
3691
  for (int32_t i = 0; i < newVg1.replica; ++i) {
32,486✔
3692
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg1.vgId, i, newVg1.vnodeGid[i].dnodeId);
16,243✔
3693
  }
3694
  mInfo("vgId:%d, vgroup info after split, replica:%d hashrange:[%u, %u] vnode:0 dnode:%d", newVg2.vgId, newVg2.replica,
16,243✔
3695
        newVg2.hashBegin, newVg2.hashEnd, newVg2.vnodeGid[0].dnodeId);
3696
  for (int32_t i = 0; i < newVg1.replica; ++i) {
32,486✔
3697
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg2.vgId, i, newVg2.vnodeGid[i].dnodeId);
16,243✔
3698
  }
3699

3700
  // alter vgId and hash range
3701
  int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
16,243✔
3702
  int32_t srcVgId = newVg1.vgId;
16,243✔
3703
  newVg1.vgId = maxVgId;
16,243✔
3704
  TAOS_CHECK_GOTO(mndAddNewVgPrepareAction(pMnode, pTrans, &newVg1), NULL, _OVER);
16,243✔
3705
  TAOS_CHECK_GOTO(mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg1), NULL, _OVER);
16,243✔
3706

3707
  maxVgId++;
16,243✔
3708
  srcVgId = newVg2.vgId;
16,243✔
3709
  newVg2.vgId = maxVgId;
16,243✔
3710
  TAOS_CHECK_GOTO(mndAddNewVgPrepareAction(pMnode, pTrans, &newVg2), NULL, _OVER);
16,243✔
3711
  TAOS_CHECK_GOTO(mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg2), NULL, _OVER);
16,243✔
3712

3713
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
16,243✔
3714
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg2), NULL, _OVER);
16,243✔
3715

3716
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
16,243✔
3717
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
16,243✔
3718
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_REDO_ACTION), NULL, _OVER);
16,243✔
3719

3720
  // update db status
3721
  memcpy(&dbObj, pDb, sizeof(SDbObj));
16,243✔
3722
  if (dbObj.cfg.pRetensions != NULL) {
16,243✔
3723
    dbObj.cfg.pRetensions = taosArrayDup(pDb->cfg.pRetensions, NULL);
×
3724
    if (dbObj.cfg.pRetensions == NULL) {
×
3725
      code = terrno;
×
3726
      goto _OVER;
×
3727
    }
3728
  }
3729
  dbObj.vgVersion++;
16,243✔
3730
  dbObj.updateTime = taosGetTimestampMs();
16,243✔
3731
  dbObj.cfg.numOfVgroups++;
16,243✔
3732
  TAOS_CHECK_GOTO(mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
16,243✔
3733

3734
  // adjust vgroup replica
3735
  if (pDb->cfg.replications != newVg1.replica) {
16,243✔
3736
    SVgObj tmpGroup = {0};
10,521✔
3737
    TAOS_CHECK_GOTO(mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg1, pArray, &tmpGroup), NULL, _OVER);
10,521✔
3738
  } else {
3739
    TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
5,722✔
3740
  }
3741

3742
  if (pDb->cfg.replications != newVg2.replica) {
14,392✔
3743
    SVgObj tmpGroup = {0};
8,670✔
3744
    TAOS_CHECK_GOTO(mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg2, pArray, &tmpGroup), NULL, _OVER);
8,670✔
3745
  } else {
3746
    TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
5,722✔
3747
  }
3748

3749
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
13,330✔
3750

3751
  // commit db status
3752
  dbObj.vgVersion++;
13,330✔
3753
  dbObj.updateTime = taosGetTimestampMs();
13,330✔
3754
  TAOS_CHECK_GOTO(mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
13,330✔
3755

3756
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
13,330✔
3757
  code = 0;
13,330✔
3758

3759
_OVER:
16,325✔
3760
  taosArrayDestroy(pArray);
16,325✔
3761
  mndTransDrop(pTrans);
16,325✔
3762
  taosArrayDestroy(dbObj.cfg.pRetensions);
16,325✔
3763
  TAOS_RETURN(code);
16,325✔
3764
}
3765

3766
extern int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq);
3767

3768
static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) { return mndProcessSplitVgroupMsgImp(pReq); }
16,707✔
3769

3770
#ifndef TD_ENTERPRISE
3771
int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq) { return 0; }
3772
#endif
3773

3774
static int32_t mndSetBalanceVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
14,537✔
3775
                                              SDnodeObj *pSrc, SDnodeObj *pDst) {
3776
  int32_t code = 0;
14,537✔
3777
  SVgObj  newVg = {0};
14,537✔
3778
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
14,537✔
3779
  mInfo("vgId:%d, vgroup info before balance, replica:%d", newVg.vgId, newVg.replica);
14,537✔
3780
  for (int32_t i = 0; i < newVg.replica; ++i) {
42,796✔
3781
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
28,259✔
3782
  }
3783

3784
  TAOS_CHECK_RETURN(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pDst->id));
14,537✔
3785
  TAOS_CHECK_RETURN(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pSrc->id));
14,537✔
3786

3787
  {
3788
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
14,537✔
3789
    if (pRaw == NULL) {
14,537✔
3790
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3791
      if (terrno != 0) code = terrno;
×
3792
      TAOS_RETURN(code);
×
3793
    }
3794
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
14,537✔
3795
      sdbFreeRaw(pRaw);
×
3796
      TAOS_RETURN(code);
×
3797
    }
3798
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
14,537✔
3799
    if (code != 0) {
14,537✔
3800
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
3801
      TAOS_RETURN(code);
×
3802
    }
3803
  }
3804

3805
  mInfo("vgId:%d, vgroup info after balance, replica:%d", newVg.vgId, newVg.replica);
14,537✔
3806
  for (int32_t i = 0; i < newVg.replica; ++i) {
42,796✔
3807
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
28,259✔
3808
  }
3809
  TAOS_RETURN(code);
14,537✔
3810
}
3811

3812
static int32_t mndBalanceVgroupBetweenDnode(SMnode *pMnode, STrans *pTrans, SDnodeObj *pSrc, SDnodeObj *pDst,
14,537✔
3813
                                            SHashObj *pBalancedVgroups) {
3814
  void   *pIter = NULL;
14,537✔
3815
  int32_t code = -1;
14,537✔
3816
  SSdb   *pSdb = pMnode->pSdb;
14,537✔
3817

3818
  while (1) {
8,931✔
3819
    SVgObj *pVgroup = NULL;
23,468✔
3820
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
23,468✔
3821
    if (pIter == NULL) break;
23,468✔
3822
    if (taosHashGet(pBalancedVgroups, &pVgroup->vgId, sizeof(int32_t)) != NULL) {
23,468✔
3823
      sdbRelease(pSdb, pVgroup);
8,230✔
3824
      continue;
8,230✔
3825
    }
3826

3827
    bool existInSrc = false;
15,238✔
3828
    bool existInDst = false;
15,238✔
3829
    for (int32_t i = 0; i < pVgroup->replica; ++i) {
44,198✔
3830
      SVnodeGid *pGid = &pVgroup->vnodeGid[i];
28,960✔
3831
      if (pGid->dnodeId == pSrc->id) existInSrc = true;
28,960✔
3832
      if (pGid->dnodeId == pDst->id) existInDst = true;
28,960✔
3833
    }
3834

3835
    if (!existInSrc || existInDst) {
15,238✔
3836
      sdbRelease(pSdb, pVgroup);
701✔
3837
      continue;
701✔
3838
    }
3839

3840
    SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
14,537✔
3841
    if (pDb == NULL) {
14,537✔
3842
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3843
      if (terrno != 0) code = terrno;
×
3844
      mError("vgId:%d, balance vgroup can't find db obj dbName:%s", pVgroup->vgId, pVgroup->dbName);
×
3845
      goto _OUT;
×
3846
    }
3847

3848
    if (pDb->cfg.withArbitrator) {
14,537✔
3849
      mInfo("vgId:%d, db:%s, with arbitrator, balance vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
×
3850
      goto _OUT;
×
3851
    }
3852

3853
    code = mndSetBalanceVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, pSrc, pDst);
14,537✔
3854
    if (code == 0) {
14,537✔
3855
      code = taosHashPut(pBalancedVgroups, &pVgroup->vgId, sizeof(int32_t), &pVgroup->vgId, sizeof(int32_t));
14,537✔
3856
    }
3857

3858
  _OUT:
14,537✔
3859
    mndReleaseDb(pMnode, pDb);
14,537✔
3860
    sdbRelease(pSdb, pVgroup);
14,537✔
3861
    sdbCancelFetch(pSdb, pIter);
14,537✔
3862
    break;
14,537✔
3863
  }
3864

3865
  return code;
14,537✔
3866
}
3867

3868
static int32_t mndBalanceVgroup(SMnode *pMnode, SRpcMsg *pReq, SArray *pArray) {
9,948✔
3869
  int32_t   code = -1;
9,948✔
3870
  int32_t   numOfVgroups = 0;
9,948✔
3871
  STrans   *pTrans = NULL;
9,948✔
3872
  SHashObj *pBalancedVgroups = NULL;
9,948✔
3873

3874
  pBalancedVgroups = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
9,948✔
3875
  if (pBalancedVgroups == NULL) goto _OVER;
9,948✔
3876

3877
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "balance-vgroup");
9,948✔
3878
  if (pTrans == NULL) {
9,948✔
3879
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3880
    if (terrno != 0) code = terrno;
×
3881
    goto _OVER;
×
3882
  }
3883
  mndTransSetSerial(pTrans);
9,948✔
3884
  mInfo("trans:%d, used to balance vgroup", pTrans->id);
9,948✔
3885
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
9,948✔
3886
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
9,128✔
3887
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
9,046✔
3888

3889
  while (1) {
14,537✔
3890
    taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
23,583✔
3891
    for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
101,796✔
3892
      SDnodeObj *pDnode = taosArrayGet(pArray, i);
78,213✔
3893
      mInfo("dnode:%d, equivalent vnodes:%d others:%d support:%d, score:%f", pDnode->id, pDnode->numOfVnodes,
78,213✔
3894
            pDnode->numOfSupportVnodes, pDnode->numOfOtherNodes, mndGetDnodeScore(pDnode, 0, 1));
3895
    }
3896

3897
    SDnodeObj *pSrc = taosArrayGet(pArray, taosArrayGetSize(pArray) - 1);
23,583✔
3898
    SDnodeObj *pDst = taosArrayGet(pArray, 0);
23,583✔
3899

3900
    float srcScore = mndGetDnodeScore(pSrc, -1, 1);
23,583✔
3901
    float dstScore = mndGetDnodeScore(pDst, 1, 1);
23,583✔
3902
    mInfo("trans:%d, after balance, src dnode:%d score:%f, dst dnode:%d score:%f", pTrans->id, pSrc->id, dstScore,
23,583✔
3903
          pDst->id, dstScore);
3904

3905
    if (srcScore > dstScore - 0.000001) {
23,583✔
3906
      code = mndBalanceVgroupBetweenDnode(pMnode, pTrans, pSrc, pDst, pBalancedVgroups);
14,537✔
3907
      if (code == 0) {
14,537✔
3908
        pSrc->numOfVnodes--;
14,537✔
3909
        pDst->numOfVnodes++;
14,537✔
3910
        numOfVgroups++;
14,537✔
3911
        continue;
14,537✔
3912
      } else {
3913
        mInfo("trans:%d, no vgroup need to balance from dnode:%d to dnode:%d", pTrans->id, pSrc->id, pDst->id);
×
3914
        break;
×
3915
      }
3916
    } else {
3917
      mInfo("trans:%d, no vgroup need to balance any more", pTrans->id);
9,046✔
3918
      break;
9,046✔
3919
    }
3920
  }
3921

3922
  if (numOfVgroups <= 0) {
9,046✔
3923
    mInfo("no need to balance vgroup");
×
3924
    code = 0;
×
3925
  } else {
3926
    mInfo("start to balance vgroup, numOfVgroups:%d", numOfVgroups);
9,046✔
3927
    if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
9,046✔
3928
    code = TSDB_CODE_ACTION_IN_PROGRESS;
9,046✔
3929
  }
3930

3931
_OVER:
9,948✔
3932
  taosHashCleanup(pBalancedVgroups);
9,948✔
3933
  mndTransDrop(pTrans);
9,948✔
3934
  TAOS_RETURN(code);
9,948✔
3935
}
3936

3937
static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq) {
11,356✔
3938
  SMnode *pMnode = pReq->info.node;
11,356✔
3939
  int32_t code = -1;
11,356✔
3940
  SArray *pArray = NULL;
11,356✔
3941
  void   *pIter = NULL;
11,356✔
3942
  int64_t curMs = taosGetTimestampMs();
11,356✔
3943
  int64_t tss = taosGetTimestampMs();
11,356✔
3944

3945
  SBalanceVgroupReq req = {0};
11,356✔
3946
  if (tDeserializeSBalanceVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) {
11,356✔
3947
    code = TSDB_CODE_INVALID_MSG;
×
3948
    goto _OVER;
×
3949
  }
3950

3951
  mInfo("start to balance vgroup");
11,356✔
3952
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_BALANCE_VGROUP)) != 0) {
11,356✔
3953
    goto _OVER;
×
3954
  }
3955

3956
  if (sdbGetSize(pMnode->pSdb, SDB_MOUNT) > 0) {
11,356✔
3957
    code = TSDB_CODE_MND_MOUNT_NOT_EMPTY;
×
3958
    goto _OVER;
×
3959
  }
3960

3961
  while (1) {
34,682✔
3962
    SDnodeObj *pDnode = NULL;
46,038✔
3963
    pIter = sdbFetch(pMnode->pSdb, SDB_DNODE, pIter, (void **)&pDnode);
46,038✔
3964
    if (pIter == NULL) break;
46,038✔
3965
    if (!mndIsDnodeOnline(pDnode, curMs)) {
36,090✔
3966
      sdbCancelFetch(pMnode->pSdb, pIter);
1,408✔
3967
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
1,408✔
3968
      mError("failed to balance vgroup since %s, dnode:%d", terrstr(), pDnode->id);
1,408✔
3969
      sdbRelease(pMnode->pSdb, pDnode);
1,408✔
3970
      goto _OVER;
1,408✔
3971
    }
3972

3973
    sdbRelease(pMnode->pSdb, pDnode);
34,682✔
3974
  }
3975

3976
  pArray = mndBuildDnodesArray(pMnode, 0, NULL);
9,948✔
3977
  if (pArray == NULL) {
9,948✔
3978
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3979
    if (terrno != 0) code = terrno;
×
3980
    goto _OVER;
×
3981
  }
3982

3983
  if (taosArrayGetSize(pArray) < 2) {
9,948✔
3984
    mInfo("no need to balance vgroup since dnode num less than 2");
×
3985
    code = 0;
×
3986
  } else {
3987
    code = mndBalanceVgroup(pMnode, pReq, pArray);
9,948✔
3988
  }
3989

3990
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
9,948✔
3991
    int64_t tse = taosGetTimestampMs();
9,948✔
3992
    double  duration = (double)(tse - tss);
9,948✔
3993
    duration = duration / 1000;
9,948✔
3994
    auditRecord(pReq, pMnode->clusterId, "balanceVgroup", "", "", req.sql, req.sqlLen, duration, 0);
9,948✔
3995
  }
3996

3997
_OVER:
11,356✔
3998
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
11,356✔
3999
    mError("failed to balance vgroup since %s", tstrerror(code));
2,310✔
4000
  }
4001

4002
  taosArrayDestroy(pArray);
11,356✔
4003
  tFreeSBalanceVgroupReq(&req);
11,356✔
4004
  TAOS_RETURN(code);
11,356✔
4005
}
4006

4007
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; }
99,279,011✔
4008

4009
bool mndVgroupInDnode(SVgObj *pVgroup, int32_t dnodeId) {
3,728✔
4010
  for (int i = 0; i < pVgroup->replica; i++) {
9,316✔
4011
    if (pVgroup->vnodeGid[i].dnodeId == dnodeId) return true;
7,918✔
4012
  }
4013
  return false;
1,398✔
4014
}
4015

4016
static void *mndBuildCompactVnodeReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen, int64_t compactTs,
92,953✔
4017
                                     STimeWindow tw, bool metaOnly, bool force, ETsdbOpType type,
4018
                                     ETriggerType triggerType) {
4019
  SCompactVnodeReq compactReq = {0};
92,953✔
4020
  compactReq.dbUid = pDb->uid;
92,953✔
4021
  compactReq.compactStartTime = compactTs;
92,953✔
4022
  compactReq.tw = tw;
92,953✔
4023
  compactReq.metaOnly = metaOnly;
92,953✔
4024
  compactReq.force = force;
92,953✔
4025
  compactReq.optrType = type;
92,953✔
4026
  compactReq.triggerType = triggerType;
92,953✔
4027
  tstrncpy(compactReq.db, pDb->name, TSDB_DB_FNAME_LEN);
92,953✔
4028

4029
  mInfo("vgId:%d, build compact vnode config req", pVgroup->vgId);
92,953✔
4030
  int32_t contLen = tSerializeSCompactVnodeReq(NULL, 0, &compactReq);
92,953✔
4031
  if (contLen < 0) {
92,953✔
4032
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
4033
    return NULL;
×
4034
  }
4035
  contLen += sizeof(SMsgHead);
92,953✔
4036

4037
  void *pReq = taosMemoryMalloc(contLen);
92,953✔
4038
  if (pReq == NULL) {
92,953✔
4039
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
4040
    return NULL;
×
4041
  }
4042

4043
  SMsgHead *pHead = pReq;
92,953✔
4044
  pHead->contLen = htonl(contLen);
92,953✔
4045
  pHead->vgId = htonl(pVgroup->vgId);
92,953✔
4046

4047
  if (tSerializeSCompactVnodeReq((char *)pReq + sizeof(SMsgHead), contLen, &compactReq) < 0) {
92,953✔
4048
    taosMemoryFree(pReq);
×
4049
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
4050
    return NULL;
×
4051
  }
4052
  *pContLen = contLen;
92,953✔
4053
  return pReq;
92,953✔
4054
}
4055

4056
static int32_t mndAddCompactVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t compactTs,
55,611✔
4057
                                        STimeWindow tw, bool metaOnly, bool force, ETsdbOpType type,
4058
                                        ETriggerType triggerType) {
4059
  int32_t      code = 0;
55,611✔
4060
  STransAction action = {0};
55,611✔
4061
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
55,611✔
4062

4063
  int32_t contLen = 0;
55,611✔
4064
  void   *pReq =
4065
      mndBuildCompactVnodeReq(pMnode, pDb, pVgroup, &contLen, compactTs, tw, metaOnly, force, type, triggerType);
55,611✔
4066
  if (pReq == NULL) {
55,611✔
4067
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4068
    if (terrno != 0) code = terrno;
×
4069
    TAOS_RETURN(code);
×
4070
  }
4071

4072
  action.pCont = pReq;
55,611✔
4073
  action.contLen = contLen;
55,611✔
4074
  action.msgType = TDMT_VND_COMPACT;
55,611✔
4075

4076
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
55,611✔
4077
    taosMemoryFree(pReq);
×
4078
    TAOS_RETURN(code);
×
4079
  }
4080

4081
  TAOS_RETURN(code);
55,611✔
4082
}
4083

4084
int32_t mndBuildCompactVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t compactTs,
55,611✔
4085
                                    STimeWindow tw, bool metaOnly, bool force, ETsdbOpType type,
4086
                                    ETriggerType triggerType) {
4087
  TAOS_CHECK_RETURN(
55,611✔
4088
      mndAddCompactVnodeAction(pMnode, pTrans, pDb, pVgroup, compactTs, tw, metaOnly, force, type, triggerType));
4089
  return 0;
55,611✔
4090
}
4091

4092
int32_t mndBuildTrimVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t startTs,
37,342✔
4093
                                 STimeWindow tw, ETsdbOpType type, ETriggerType triggerType) {
4094
  int32_t      code = 0;
37,342✔
4095
  STransAction action = {0};
37,342✔
4096
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
37,342✔
4097

4098
  int32_t contLen = 0;
37,342✔
4099
  // reuse SCompactVnodeReq as SVTrimDbReq
4100
  void *pReq = mndBuildCompactVnodeReq(pMnode, pDb, pVgroup, &contLen, startTs, tw, false, false, type, triggerType);
37,342✔
4101
  if (pReq == NULL) {
37,342✔
4102
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4103
    if (terrno != 0) code = terrno;
×
4104
    TAOS_RETURN(code);
×
4105
  }
4106

4107
  action.pCont = pReq;
37,342✔
4108
  action.contLen = contLen;
37,342✔
4109
  action.msgType = TDMT_VND_TRIM;
37,342✔
4110

4111
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
37,342✔
4112
    taosMemoryFree(pReq);
×
4113
    TAOS_RETURN(code);
×
4114
  }
4115

4116
  TAOS_RETURN(code);
37,342✔
4117
}
4118

4119
static int32_t mndProcessSetVgroupKeepVersionReq(SRpcMsg *pReq) {
1,067✔
4120
  SMnode *pMnode = pReq->info.node;
1,067✔
4121
  int32_t code = TSDB_CODE_SUCCESS;
1,067✔
4122
  STrans *pTrans = NULL;
1,067✔
4123
  SVgObj *pVgroup = NULL;
1,067✔
4124

4125
  SMndSetVgroupKeepVersionReq req = {0};
1,067✔
4126
  if (tDeserializeSMndSetVgroupKeepVersionReq(pReq->pCont, pReq->contLen, &req) != 0) {
1,067✔
4127
    code = TSDB_CODE_INVALID_MSG;
×
4128
    goto _OVER;
×
4129
  }
4130

4131
  mInfo("start to set vgroup keep version, vgId:%d, keepVersion:%" PRId64, req.vgId, req.keepVersion);
1,067✔
4132

4133
  // Check permission
4134
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_WRITE_DB)) != 0) {
1,067✔
4135
    goto _OVER;
×
4136
  }
4137

4138
  // Get vgroup
4139
  pVgroup = mndAcquireVgroup(pMnode, req.vgId);
1,067✔
4140
  if (pVgroup == NULL) {
1,067✔
4141
    code = TSDB_CODE_MND_VGROUP_NOT_EXIST;
×
4142
    mError("vgId:%d not exist, failed to set keep version", req.vgId);
×
4143
    goto _OVER;
×
4144
  }
4145

4146
  // Create transaction
4147
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq, "set-vgroup-keep-version");
1,067✔
4148
  if (pTrans == NULL) {
1,067✔
4149
    code = terrno != 0 ? terrno : TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4150
    mndReleaseVgroup(pMnode, pVgroup);
×
4151
    goto _OVER;
×
4152
  }
4153

4154
  mndTransSetSerial(pTrans);
1,067✔
4155
  mInfo("trans:%d, used to set vgroup keep version, vgId:%d keepVersion:%" PRId64, pTrans->id, req.vgId,
1,067✔
4156
        req.keepVersion);
4157

4158
  // Update SVgObj's keepVersion in mnode
4159
  SVgObj newVgroup = {0};
1,067✔
4160
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
1,067✔
4161
  newVgroup.keepVersion = req.keepVersion;
1,067✔
4162
  newVgroup.keepVersionTime = taosGetTimestampMs();
1,067✔
4163

4164
  // Add prepare log for SDB vgroup update (execute in PREPARE stage, before redo actions)
4165
  SSdbRaw *pCommitRaw = mndVgroupActionEncode(&newVgroup);
1,067✔
4166
  if (pCommitRaw == NULL) {
1,067✔
4167
    code = TSDB_CODE_OUT_OF_MEMORY;
×
4168
    mndReleaseVgroup(pMnode, pVgroup);
×
4169
    goto _OVER;
×
4170
  }
4171
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
1,067✔
4172
    code = terrno;
×
4173
    sdbFreeRaw(pCommitRaw);
×
4174
    mndReleaseVgroup(pMnode, pVgroup);
×
4175
    goto _OVER;
×
4176
  }
4177
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) {
1,067✔
4178
    mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", pVgroup->vgId, tstrerror(code), __LINE__);
×
4179
    sdbFreeRaw(pCommitRaw);
×
4180
    mndReleaseVgroup(pMnode, pVgroup);
×
4181
    goto _OVER;
×
4182
  }
4183

4184
  // Prepare message for vnodes
4185
  SVndSetKeepVersionReq vndReq = {.keepVersion = req.keepVersion};
1,067✔
4186
  int32_t               reqLen = tSerializeSVndSetKeepVersionReq(NULL, 0, &vndReq);
1,067✔
4187
  int32_t               contLen = reqLen + sizeof(SMsgHead);
1,067✔
4188

4189
  // Send to all replicas of the vgroup
4190
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
4,268✔
4191
    SMsgHead *pHead = taosMemoryMalloc(contLen);
3,201✔
4192
    if (pHead == NULL) {
3,201✔
4193
      code = TSDB_CODE_OUT_OF_MEMORY;
×
4194
      mndReleaseVgroup(pMnode, pVgroup);
×
4195
      goto _OVER;
×
4196
    }
4197

4198
    pHead->contLen = htonl(contLen);
3,201✔
4199
    pHead->vgId = htonl(pVgroup->vgId);
3,201✔
4200

4201
    if (tSerializeSVndSetKeepVersionReq((char *)pHead + sizeof(SMsgHead), reqLen, &vndReq) < 0) {
3,201✔
4202
      taosMemoryFree(pHead);
×
4203
      code = TSDB_CODE_OUT_OF_MEMORY;
×
4204
      mndReleaseVgroup(pMnode, pVgroup);
×
4205
      goto _OVER;
×
4206
    }
4207

4208
    // Get dnode and add action to transaction
4209
    SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId);
3,201✔
4210
    if (pDnode == NULL) {
3,201✔
4211
      taosMemoryFree(pHead);
×
4212
      code = TSDB_CODE_MND_DNODE_NOT_EXIST;
×
4213
      mndReleaseVgroup(pMnode, pVgroup);
×
4214
      goto _OVER;
×
4215
    }
4216

4217
    STransAction action = {0};
3,201✔
4218
    action.epSet = mndGetDnodeEpset(pDnode);
3,201✔
4219
    mndReleaseDnode(pMnode, pDnode);
3,201✔
4220
    action.pCont = pHead;
3,201✔
4221
    action.contLen = contLen;
3,201✔
4222
    action.msgType = TDMT_VND_SET_KEEP_VERSION;
3,201✔
4223
    action.acceptableCode = TSDB_CODE_VND_STOPPED;
3,201✔
4224

4225
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
3,201✔
4226
      taosMemoryFree(pHead);
×
4227
      code = terrno;
×
4228
      mndReleaseVgroup(pMnode, pVgroup);
×
4229
      goto _OVER;
×
4230
    }
4231
  }
4232

4233
  mndReleaseVgroup(pMnode, pVgroup);
1,067✔
4234

4235
  // Prepare and execute transaction
4236
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
1,067✔
4237
    goto _OVER;
×
4238
  }
4239

4240
  code = TSDB_CODE_ACTION_IN_PROGRESS;
1,067✔
4241

4242
_OVER:
1,067✔
4243
  if (pTrans != NULL) mndTransDrop(pTrans);
1,067✔
4244

4245
  return code;
1,067✔
4246
}
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