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

taosdata / TDengine / #4926

13 Jan 2026 05:43AM UTC coverage: 66.053% (-0.05%) from 66.107%
#4926

push

travis-ci

web-flow
feat: [6654385780] show snap progress (#34203)

48 of 59 new or added lines in 7 files covered. (81.36%)

582 existing lines in 124 files now uncovered.

200362 of 303334 relevant lines covered (66.05%)

132283104.31 hits per line

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

68.1
/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) {
399,541✔
56
  SSdbTable table = {
399,541✔
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);
399,541✔
68
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_REPLICA_RSP, mndTransProcessRsp);
399,541✔
69
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_CONFIG_RSP, mndTransProcessRsp);
399,541✔
70
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_CONFIRM_RSP, mndTransProcessRsp);
399,541✔
71
  mndSetMsgHandle(pMnode, TDMT_VND_SET_KEEP_VERSION_RSP, mndTransProcessRsp);
399,541✔
72
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_HASHRANGE_RSP, mndTransProcessRsp);
399,541✔
73
  mndSetMsgHandle(pMnode, TDMT_DND_DROP_VNODE_RSP, mndTransProcessRsp);
399,541✔
74
  mndSetMsgHandle(pMnode, TDMT_VND_COMPACT_RSP, mndTransProcessRsp);
399,541✔
75
  mndSetMsgHandle(pMnode, TDMT_VND_SCAN_RSP, mndTransProcessRsp);
399,541✔
76
  mndSetMsgHandle(pMnode, TDMT_VND_DISABLE_WRITE_RSP, mndTransProcessRsp);
399,541✔
77
  mndSetMsgHandle(pMnode, TDMT_SYNC_FORCE_FOLLOWER_RSP, mndTransProcessRsp);
399,541✔
78
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_ELECTBASELINE_RSP, mndTransProcessRsp);
399,541✔
79
  
80
  mndSetMsgHandle(pMnode, TDMT_DND_ALTER_VNODE_TYPE_RSP, mndTransProcessRsp);
399,541✔
81
  mndSetMsgHandle(pMnode, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP_RSP, mndTransProcessRsp);
399,541✔
82
  mndSetMsgHandle(pMnode, TDMT_SYNC_CONFIG_CHANGE_RSP, mndTransProcessRsp);
399,541✔
83

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

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

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

99
void mndCleanupVgroup(SMnode *pMnode) {}
399,481✔
100

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

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

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

131
  terrno = 0;
10,366,164✔
132

133
_OVER:
10,366,164✔
134
  if (terrno != 0) {
10,366,164✔
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,366,164✔
141
  return pRaw;
10,366,164✔
142
}
143

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

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

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

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

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

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

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

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

210
  terrno = 0;
9,367,219✔
211

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

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

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

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

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

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

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

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

265
static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew) {
2,847,468✔
266
  mTrace("vgId:%d, perform update action, old row:%p new row:%p", pOld->vgId, pOld, pNew);
2,847,468✔
267
  pOld->updateTime = pNew->updateTime;
2,847,468✔
268
  pOld->version = pNew->version;
2,847,468✔
269
  pOld->hashBegin = pNew->hashBegin;
2,847,468✔
270
  pOld->hashEnd = pNew->hashEnd;
2,847,468✔
271
  pOld->replica = pNew->replica;
2,847,468✔
272
  pOld->isTsma = pNew->isTsma;
2,847,468✔
273
  pOld->keepVersion = pNew->keepVersion;
2,847,468✔
274
  pOld->keepVersionTime = pNew->keepVersionTime;
2,847,468✔
275
  for (int32_t i = 0; i < pNew->replica; ++i) {
6,615,319✔
276
    SVnodeGid *pNewGid = &pNew->vnodeGid[i];
3,767,851✔
277
    for (int32_t j = 0; j < pOld->replica; ++j) {
10,358,704✔
278
      SVnodeGid *pOldGid = &pOld->vnodeGid[j];
6,590,853✔
279
      if (pNewGid->dnodeId == pOldGid->dnodeId) {
6,590,853✔
280
        pNewGid->syncState = pOldGid->syncState;
3,547,189✔
281
        pNewGid->syncRestore = pOldGid->syncRestore;
3,547,189✔
282
        pNewGid->syncCanRead = pOldGid->syncCanRead;
3,547,189✔
283
        pNewGid->syncAppliedIndex = pOldGid->syncAppliedIndex;
3,547,189✔
284
        pNewGid->syncCommitIndex = pOldGid->syncCommitIndex;
3,547,189✔
285
        pNewGid->bufferSegmentUsed = pOldGid->bufferSegmentUsed;
3,547,189✔
286
        pNewGid->bufferSegmentSize = pOldGid->bufferSegmentSize;
3,547,189✔
287
        pNewGid->learnerProgress = pOldGid->learnerProgress;
3,547,189✔
288
        pNewGid->snapSeq = pOldGid->snapSeq;
3,547,189✔
289
        pNewGid->syncTotalIndex = pOldGid->syncTotalIndex;
3,547,189✔
290
      }
291
    }
292
  }
293
  pNew->numOfTables = pOld->numOfTables;
2,847,468✔
294
  pNew->numOfTimeSeries = pOld->numOfTimeSeries;
2,847,468✔
295
  pNew->totalStorage = pOld->totalStorage;
2,847,468✔
296
  pNew->compStorage = pOld->compStorage;
2,847,468✔
297
  pNew->pointsWritten = pOld->pointsWritten;
2,847,468✔
298
  pNew->compact = pOld->compact;
2,847,468✔
299
  memcpy(pOld->vnodeGid, pNew->vnodeGid, (TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA) * sizeof(SVnodeGid));
2,847,468✔
300
  pOld->syncConfChangeVer = pNew->syncConfChangeVer;
2,847,468✔
301
  tstrncpy(pOld->dbName, pNew->dbName, TSDB_DB_FNAME_LEN);
2,847,468✔
302
  return 0;
2,847,468✔
303
}
304

305
SVgObj *mndAcquireVgroup(SMnode *pMnode, int32_t vgId) {
123,563,294✔
306
  SSdb   *pSdb = pMnode->pSdb;
123,563,294✔
307
  SVgObj *pVgroup = sdbAcquire(pSdb, SDB_VGROUP, &vgId);
123,563,294✔
308
  if (pVgroup == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
123,563,294✔
309
    terrno = TSDB_CODE_MND_VGROUP_NOT_EXIST;
970,789✔
310
  }
311
  return pVgroup;
123,563,294✔
312
}
313

314
void mndReleaseVgroup(SMnode *pMnode, SVgObj *pVgroup) {
122,825,525✔
315
  SSdb *pSdb = pMnode->pSdb;
122,825,525✔
316
  sdbRelease(pSdb, pVgroup);
122,825,525✔
317
}
122,825,525✔
318

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

373
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
6,478,316✔
374
    SReplica *pReplica = NULL;
3,752,316✔
375

376
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,752,316✔
377
      pReplica = &createReq.replicas[createReq.replica];
3,649,416✔
378
    } else {
379
      pReplica = &createReq.learnerReplicas[createReq.learnerReplica];
102,900✔
380
    }
381

382
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
3,752,316✔
383
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
3,752,316✔
384
    if (pVgidDnode == NULL) {
3,752,316✔
385
      return NULL;
×
386
    }
387

388
    pReplica->id = pVgidDnode->id;
3,752,316✔
389
    pReplica->port = pVgidDnode->port;
3,752,316✔
390
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
3,752,316✔
391
    mndReleaseDnode(pMnode, pVgidDnode);
3,752,316✔
392

393
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,752,316✔
394
      if (pDnode->id == pVgid->dnodeId) {
3,649,416✔
395
        createReq.selfIndex = createReq.replica;
2,623,100✔
396
      }
397
    } else {
398
      if (pDnode->id == pVgid->dnodeId) {
102,900✔
399
        createReq.learnerSelfIndex = createReq.learnerReplica;
102,900✔
400
      }
401
    }
402

403
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,752,316✔
404
      createReq.replica++;
3,649,416✔
405
    } else {
406
      createReq.learnerReplica++;
102,900✔
407
    }
408
  }
409

410
  if (createReq.selfIndex == -1 && createReq.learnerSelfIndex == -1) {
2,726,000✔
411
    terrno = TSDB_CODE_APP_ERROR;
×
412
    return NULL;
×
413
  }
414

415
  createReq.changeVersion = pVgroup->syncConfChangeVer;
2,726,000✔
416

417
  mInfo(
2,726,000✔
418
      "vgId:%d, build create vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
419
      "changeVersion:%d",
420
      createReq.vgId, createReq.replica, createReq.selfIndex, createReq.learnerReplica, createReq.learnerSelfIndex,
421
      createReq.strict, createReq.changeVersion);
422
  for (int32_t i = 0; i < createReq.replica; ++i) {
6,375,416✔
423
    mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.replicas[i].fqdn, createReq.replicas[i].port);
3,649,416✔
424
  }
425
  for (int32_t i = 0; i < createReq.learnerReplica; ++i) {
2,828,900✔
426
    mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.learnerReplicas[i].fqdn,
102,900✔
427
          createReq.learnerReplicas[i].port);
428
  }
429

430
  int32_t contLen = tSerializeSCreateVnodeReq(NULL, 0, &createReq);
2,726,000✔
431
  if (contLen < 0) {
2,726,000✔
432
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
433
    return NULL;
×
434
  }
435

436
  void *pReq = taosMemoryMalloc(contLen);
2,726,000✔
437
  if (pReq == NULL) {
2,726,000✔
438
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
439
    return NULL;
×
440
  }
441

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

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

476
  mInfo("vgId:%d, build alter vnode config req", pVgroup->vgId);
198,917✔
477
  int32_t contLen = tSerializeSAlterVnodeConfigReq(NULL, 0, &alterReq);
198,917✔
478
  if (contLen < 0) {
198,917✔
479
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
480
    return NULL;
×
481
  }
482
  contLen += sizeof(SMsgHead);
198,917✔
483

484
  void *pReq = taosMemoryMalloc(contLen);
198,917✔
485
  if (pReq == NULL) {
198,917✔
486
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
487
    return NULL;
×
488
  }
489

490
  SMsgHead *pHead = pReq;
198,917✔
491
  pHead->contLen = htonl(contLen);
198,917✔
492
  pHead->vgId = htonl(pVgroup->vgId);
198,917✔
493

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

504
static void *mndBuildAlterVnodeReplicaReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId,
784,014✔
505
                                          int32_t *pContLen) {
506
  SAlterVnodeReplicaReq alterReq = {
1,568,028✔
507
      .vgId = pVgroup->vgId,
784,014✔
508
      .strict = pDb->cfg.strict,
784,014✔
509
      .replica = 0,
510
      .learnerReplica = 0,
511
      .selfIndex = -1,
512
      .learnerSelfIndex = -1,
513
      .changeVersion = ++(pVgroup->syncConfChangeVer),
1,568,028✔
514
  };
515

516
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
3,214,890✔
517
    SReplica *pReplica = NULL;
2,430,876✔
518

519
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
2,430,876✔
520
      pReplica = &alterReq.replicas[alterReq.replica];
2,239,904✔
521
      alterReq.replica++;
2,239,904✔
522
    } else {
523
      pReplica = &alterReq.learnerReplicas[alterReq.learnerReplica];
190,972✔
524
      alterReq.learnerReplica++;
190,972✔
525
    }
526

527
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
2,430,876✔
528
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
2,430,876✔
529
    if (pVgidDnode == NULL) return NULL;
2,430,876✔
530

531
    pReplica->id = pVgidDnode->id;
2,430,876✔
532
    pReplica->port = pVgidDnode->port;
2,430,876✔
533
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
2,430,876✔
534
    mndReleaseDnode(pMnode, pVgidDnode);
2,430,876✔
535

536
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
2,430,876✔
537
      if (dnodeId == pVgid->dnodeId) {
2,239,904✔
538
        alterReq.selfIndex = v;
784,014✔
539
      }
540
    } else {
541
      if (dnodeId == pVgid->dnodeId) {
190,972✔
542
        alterReq.learnerSelfIndex = v;
×
543
      }
544
    }
545
  }
546

547
  mInfo(
784,014✔
548
      "vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
549
      "changeVersion:%d",
550
      alterReq.vgId, alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica, alterReq.learnerSelfIndex,
551
      alterReq.strict, alterReq.changeVersion);
552
  for (int32_t i = 0; i < alterReq.replica; ++i) {
3,023,918✔
553
    mInfo("vgId:%d, replica:%d ep:%s:%u", alterReq.vgId, i, alterReq.replicas[i].fqdn, alterReq.replicas[i].port);
2,239,904✔
554
  }
555
  for (int32_t i = 0; i < alterReq.learnerReplica; ++i) {
974,986✔
556
    mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", alterReq.vgId, i, alterReq.learnerReplicas[i].fqdn,
190,972✔
557
          alterReq.learnerReplicas[i].port);
558
  }
559

560
  if (alterReq.selfIndex == -1 && alterReq.learnerSelfIndex == -1) {
784,014✔
561
    terrno = TSDB_CODE_APP_ERROR;
×
562
    return NULL;
×
563
  }
564

565
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &alterReq);
784,014✔
566
  if (contLen < 0) {
784,014✔
567
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
568
    return NULL;
×
569
  }
570

571
  void *pReq = taosMemoryMalloc(contLen);
784,014✔
572
  if (pReq == NULL) {
784,014✔
573
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
574
    return NULL;
×
575
  }
576

577
  if (tSerializeSAlterVnodeReplicaReq(pReq, contLen, &alterReq) < 0) {
784,014✔
578
    mError("vgId:%d, failed to serialize alter vnode req,since %s", alterReq.vgId, terrstr());
×
579
    taosMemoryFree(pReq);
×
580
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
581
    return NULL;
×
582
  }
583
  *pContLen = contLen;
784,014✔
584
  return pReq;
784,014✔
585
}
586

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

598
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
×
599
    SReplica *pReplica = NULL;
×
600

601
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
×
602
      pReplica = &req.replicas[req.replica];
×
603
      req.replica++;
×
604
    } else {
605
      pReplica = &req.learnerReplicas[req.learnerReplica];
×
606
      req.learnerReplica++;
×
607
    }
608

609
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
×
610
    SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
×
611
    if (pVgidDnode == NULL) return NULL;
×
612

613
    pReplica->id = pVgidDnode->id;
×
614
    pReplica->port = pVgidDnode->port;
×
615
    memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN);
×
616
    mndReleaseDnode(pMnode, pVgidDnode);
×
617

618
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
×
619
      if (dnodeId == pVgid->dnodeId) {
×
620
        req.selfIndex = v;
×
621
      }
622
    } else {
623
      if (dnodeId == pVgid->dnodeId) {
×
624
        req.learnerSelfIndex = v;
×
625
      }
626
    }
627
  }
628

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

638
  if (req.selfIndex == -1 && req.learnerSelfIndex == -1) {
×
639
    terrno = TSDB_CODE_APP_ERROR;
×
640
    return NULL;
×
641
  }
642

643
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &req);
×
644
  if (contLen < 0) {
×
645
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
646
    return NULL;
×
647
  }
648

649
  void *pReq = taosMemoryMalloc(contLen);
×
650
  if (pReq == NULL) {
×
651
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
652
    return NULL;
×
653
  }
654

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

665
static void *mndBuildDisableVnodeWriteReq(SMnode *pMnode, SDbObj *pDb, int32_t vgId, int32_t *pContLen) {
31,006✔
666
  SDisableVnodeWriteReq disableReq = {
31,006✔
667
      .vgId = vgId,
668
      .disable = 1,
669
  };
670

671
  mInfo("vgId:%d, build disable vnode write req", vgId);
31,006✔
672
  int32_t contLen = tSerializeSDisableVnodeWriteReq(NULL, 0, &disableReq);
31,006✔
673
  if (contLen < 0) {
31,006✔
674
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
675
    return NULL;
×
676
  }
677

678
  void *pReq = taosMemoryMalloc(contLen);
31,006✔
679
  if (pReq == NULL) {
31,006✔
680
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
681
    return NULL;
×
682
  }
683

684
  if (tSerializeSDisableVnodeWriteReq(pReq, contLen, &disableReq) < 0) {
31,006✔
685
    mError("vgId:%d, failed to serialize disable vnode write req,since %s", vgId, terrstr());
×
686
    taosMemoryFree(pReq);
×
687
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
688
    return NULL;
×
689
  }
690
  *pContLen = contLen;
31,006✔
691
  return pReq;
31,006✔
692
}
693

694
static void *mndBuildAlterVnodeHashRangeReq(SMnode *pMnode, int32_t srcVgId, SVgObj *pVgroup, int32_t *pContLen) {
31,006✔
695
  SAlterVnodeHashRangeReq alterReq = {
62,012✔
696
      .srcVgId = srcVgId,
697
      .dstVgId = pVgroup->vgId,
31,006✔
698
      .hashBegin = pVgroup->hashBegin,
31,006✔
699
      .hashEnd = pVgroup->hashEnd,
31,006✔
700
      .changeVersion = ++(pVgroup->syncConfChangeVer),
62,012✔
701
  };
702

703
  mInfo("vgId:%d, build alter vnode hashrange req, dstVgId:%d, hashrange:[%u, %u]", srcVgId, pVgroup->vgId,
31,006✔
704
        pVgroup->hashBegin, pVgroup->hashEnd);
705
  int32_t contLen = tSerializeSAlterVnodeHashRangeReq(NULL, 0, &alterReq);
31,006✔
706
  if (contLen < 0) {
31,006✔
707
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
708
    return NULL;
×
709
  }
710

711
  void *pReq = taosMemoryMalloc(contLen);
31,006✔
712
  if (pReq == NULL) {
31,006✔
713
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
714
    return NULL;
×
715
  }
716

717
  if (tSerializeSAlterVnodeHashRangeReq(pReq, contLen, &alterReq) < 0) {
31,006✔
718
    mError("vgId:%d, failed to serialize alter vnode hashrange req,since %s", srcVgId, terrstr());
×
719
    taosMemoryFree(pReq);
×
720
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
721
    return NULL;
×
722
  }
723
  *pContLen = contLen;
31,006✔
724
  return pReq;
31,006✔
725
}
726

727
void *mndBuildDropVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen) {
4,023,526✔
728
  SDropVnodeReq dropReq = {0};
4,023,526✔
729
  dropReq.dnodeId = pDnode->id;
4,023,526✔
730
  dropReq.vgId = pVgroup->vgId;
4,023,526✔
731
  memcpy(dropReq.db, pDb->name, TSDB_DB_FNAME_LEN);
4,023,526✔
732
  dropReq.dbUid = pDb->uid;
4,023,526✔
733

734
  mInfo("vgId:%d, build drop vnode req", dropReq.vgId);
4,023,526✔
735
  int32_t contLen = tSerializeSDropVnodeReq(NULL, 0, &dropReq);
4,023,526✔
736
  if (contLen < 0) {
4,023,526✔
737
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
738
    return NULL;
×
739
  }
740

741
  void *pReq = taosMemoryMalloc(contLen);
4,023,526✔
742
  if (pReq == NULL) {
4,023,526✔
743
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
744
    return NULL;
×
745
  }
746

747
  if (tSerializeSDropVnodeReq(pReq, contLen, &dropReq) < 0) {
4,023,526✔
748
    mError("vgId:%d, failed to serialize drop vnode req,since %s", dropReq.vgId, terrstr());
×
749
    taosMemoryFree(pReq);
×
750
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
751
    return NULL;
×
752
  }
753
  *pContLen = contLen;
4,023,526✔
754
  return pReq;
4,023,526✔
755
}
756

757
static bool mndResetDnodesArrayFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
1,771,871✔
758
  SDnodeObj *pDnode = pObj;
1,771,871✔
759
  pDnode->numOfVnodes = 0;
1,771,871✔
760
  pDnode->numOfOtherNodes = 0;
1,771,871✔
761
  return true;
1,771,871✔
762
}
763

764
static bool mndBuildDnodesArrayFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
1,771,871✔
765
  SDnodeObj *pDnode = pObj;
1,771,871✔
766
  SArray    *pArray = p1;
1,771,871✔
767
  int32_t    exceptDnodeId = *(int32_t *)p2;
1,771,871✔
768
  SArray    *dnodeList = p3;
1,771,871✔
769

770
  if (exceptDnodeId == pDnode->id) {
1,771,871✔
771
    return true;
6,977✔
772
  }
773

774
  if (dnodeList != NULL) {
1,764,894✔
775
    int32_t dnodeListSize = taosArrayGetSize(dnodeList);
68,321✔
776
    if (dnodeListSize > 0) {
68,321✔
777
      bool inDnodeList = false;
68,321✔
778
      for (int32_t index = 0; index < dnodeListSize; ++index) {
222,638✔
779
        int32_t dnodeId = *(int32_t *)taosArrayGet(dnodeList, index);
154,317✔
780
        if (pDnode->id == dnodeId) {
154,317✔
781
          inDnodeList = true;
31,557✔
782
        }
783
      }
784
      if (!inDnodeList) {
68,321✔
785
        return true;
36,764✔
786
      }
787
    } else {
788
      return true;  // TS-6191
×
789
    }
790
  }
791

792
  int64_t curMs = taosGetTimestampMs();
1,728,130✔
793
  bool    online = mndIsDnodeOnline(pDnode, curMs);
1,728,130✔
794
  bool    isMnode = mndIsMnode(pMnode, pDnode->id);
1,728,130✔
795
  pDnode->numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
1,728,130✔
796
  pDnode->memUsed = mndGetVnodesMemory(pMnode, pDnode->id);
1,728,130✔
797

798
  mInfo("dnode:%d, vnodes:%d supportVnodes:%d isMnode:%d online:%d memory avail:%" PRId64 " used:%" PRId64, pDnode->id,
1,728,130✔
799
        pDnode->numOfVnodes, pDnode->numOfSupportVnodes, isMnode, online, pDnode->memAvail, pDnode->memUsed);
800

801
  if (isMnode) {
1,728,130✔
802
    pDnode->numOfOtherNodes++;
1,232,705✔
803
  }
804

805
  if (online && pDnode->numOfSupportVnodes > 0) {
1,728,130✔
806
    if (taosArrayPush(pArray, pDnode) == NULL) return false;
1,682,356✔
807
  }
808
  return true;
1,728,130✔
809
}
810

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

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

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

841
static bool mndBuildDnodesListFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
×
842
  SDnodeObj *pDnode = pObj;
×
843
  SArray    *pArray = p1;
×
844

845
  bool isMnode = mndIsMnode(pMnode, pDnode->id);
×
846
  pDnode->numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
×
847

848
  if (isMnode) {
×
849
    pDnode->numOfOtherNodes++;
×
850
  }
851

852
  if (pDnode->numOfSupportVnodes > 0) {
×
853
    if (taosArrayPush(pArray, pDnode) == NULL) return false;
×
854
  }
855
  return true;
×
856
}
857

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

871
  sdbTraverse(pSdb, SDB_DNODE, mndResetDnodesArrayFp, NULL, NULL, NULL);
×
872
  sdbTraverse(pSdb, SDB_DNODE, mndBuildDnodesListFp, pArray, NULL, NULL);
×
873

874
  int32_t arrSize = taosArrayGetSize(pArray);
×
875
  if (arrSize <= 0) {
×
876
    TAOS_RETURN(code);
×
877
  }
878
  if (arrSize > 1) taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes1);
×
879

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

915
  TAOS_RETURN(code);
×
916
}
917
#endif
918

919
SArray *mndBuildDnodesArray(SMnode *pMnode, int32_t exceptDnodeId, SArray *dnodeList) {
1,201,049✔
920
  SSdb   *pSdb = pMnode->pSdb;
1,201,049✔
921
  int32_t numOfDnodes = mndGetDnodeSize(pMnode);
1,201,049✔
922
  SArray *tDnodeList = NULL;
1,201,049✔
923
  SArray *pDnodeList = NULL;
1,201,049✔
924

925
  SArray *pArray = taosArrayInit(numOfDnodes, sizeof(SDnodeObj));
1,201,049✔
926
  if (pArray == NULL) {
1,201,049✔
927
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
928
    return NULL;
×
929
  }
930
  if (taosArrayGetSize(dnodeList) > 0) {
1,201,049✔
931
    tDnodeList = dnodeList;
14,011✔
932
  }
933
#ifdef TD_ENTERPRISE
934
  if (0 != mndBuildNodesCheckDualReplica(pMnode, numOfDnodes, tDnodeList, &pDnodeList)) {
1,201,049✔
935
    taosArrayDestroy(pArray);
×
936
    return NULL;
×
937
  }
938
#endif
939
  sdbTraverse(pSdb, SDB_DNODE, mndResetDnodesArrayFp, NULL, NULL, NULL);
1,201,049✔
940
  sdbTraverse(pSdb, SDB_DNODE, mndBuildDnodesArrayFp, pArray, &exceptDnodeId, pDnodeList ? pDnodeList : tDnodeList);
1,201,049✔
941

942
  mDebug("build %d dnodes array", (int32_t)taosArrayGetSize(pArray));
1,201,049✔
943
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
2,883,405✔
944
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
1,682,356✔
945
    mDebug("dnode:%d, vnodes:%d others:%d", pDnode->id, pDnode->numOfVnodes, pDnode->numOfOtherNodes);
1,682,356✔
946
  }
947
  taosArrayDestroy(pDnodeList);
1,201,049✔
948
  return pArray;
1,201,049✔
949
}
950

951
static int32_t mndCompareDnodeId(int32_t *dnode1Id, int32_t *dnode2Id) {
×
952
  if (*dnode1Id == *dnode2Id) {
×
953
    return 0;
×
954
  }
955
  return *dnode1Id > *dnode2Id ? 1 : -1;
×
956
}
957

958
static float mndGetDnodeScore(SDnodeObj *pDnode, int32_t additionDnodes, float ratio) {
8,640,683✔
959
  float totalDnodes = pDnode->numOfVnodes + (float)pDnode->numOfOtherNodes * ratio + additionDnodes;
8,640,683✔
960
  return totalDnodes / pDnode->numOfSupportVnodes;
8,640,683✔
961
}
962

963
static int32_t mndCompareDnodeVnodes(SDnodeObj *pDnode1, SDnodeObj *pDnode2) {
2,690,189✔
964
  float d1Score = mndGetDnodeScore(pDnode1, 0, 0.9);
2,690,189✔
965
  float d2Score = mndGetDnodeScore(pDnode2, 0, 0.9);
2,690,189✔
966
  if (d1Score == d2Score) {
2,690,189✔
967
    return 0;
892,786✔
968
  }
969
  return d1Score > d2Score ? 1 : -1;
1,797,403✔
970
}
971

972
void mndSortVnodeGid(SVgObj *pVgroup) {
2,362,971✔
973
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
5,031,523✔
974
    for (int32_t j = 0; j < pVgroup->replica - 1 - i; ++j) {
3,123,221✔
975
      if (pVgroup->vnodeGid[j].dnodeId > pVgroup->vnodeGid[j + 1].dnodeId) {
454,669✔
976
        TSWAP(pVgroup->vnodeGid[j], pVgroup->vnodeGid[j + 1]);
204,386✔
977
      }
978
    }
979
  }
980
}
2,362,971✔
981

982
static int32_t mndGetAvailableDnode(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, SArray *pArray) {
2,335,992✔
983
  mDebug("start to sort %d dnodes", (int32_t)taosArrayGetSize(pArray));
2,335,992✔
984
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
2,335,992✔
985
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
5,530,408✔
986
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
3,194,416✔
987
    mDebug("dnode:%d, score:%f", pDnode->id, mndGetDnodeScore(pDnode, 0, 0.9));
3,194,416✔
988
  }
989

990
  int32_t size = taosArrayGetSize(pArray);
2,335,992✔
991
  if (size < pVgroup->replica) {
2,335,992✔
992
    mError("db:%s, vgId:%d, no enough online dnodes:%d to alloc %d replica", pVgroup->dbName, pVgroup->vgId, size,
4,440✔
993
           pVgroup->replica);
994
    TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
4,440✔
995
  }
996

997
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
4,913,969✔
998
    SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
2,582,417✔
999
    SDnodeObj *pDnode = taosArrayGet(pArray, v);
2,582,417✔
1000
    if (pDnode == NULL) {
2,582,417✔
1001
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
×
1002
    }
1003
    if (pDnode->numOfVnodes >= pDnode->numOfSupportVnodes) {
2,582,417✔
1004
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_VNODES);
×
1005
    }
1006

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

1016
    pVgid->dnodeId = pDnode->id;
2,582,417✔
1017
    if (pVgroup->replica == 1) {
2,582,417✔
1018
      pVgid->syncState = TAOS_SYNC_STATE_LEADER;
2,203,100✔
1019
    } else {
1020
      pVgid->syncState = TAOS_SYNC_STATE_FOLLOWER;
379,317✔
1021
    }
1022

1023
    mInfo("db:%s, vgId:%d, vn:%d is alloced, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
2,582,417✔
1024
          pVgroup->dbName, pVgroup->vgId, v, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
1025
    pDnode->numOfVnodes++;
2,582,417✔
1026
  }
1027

1028
  mndSortVnodeGid(pVgroup);
2,331,552✔
1029
  return 0;
2,331,552✔
1030
}
1031

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

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

1052
  if (mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray) != 0) return -1;
×
1053
  taosArrayDestroy(pArray);
×
1054

1055
  mInfo("db:%s, sma vgId:%d is alloced", pDb->name, pVgroup->vgId);
×
1056
  return 0;
×
1057
}
1058

1059
int32_t mndAllocVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj **ppVgroups, SArray *dnodeList) {
1,086,805✔
1060
  int32_t code = -1;
1,086,805✔
1061
  SArray *pArray = NULL;
1,086,805✔
1062
  SVgObj *pVgroups = NULL;
1,086,805✔
1063

1064
  pVgroups = taosMemoryCalloc(pDb->cfg.numOfVgroups, sizeof(SVgObj));
1,086,805✔
1065
  if (pVgroups == NULL) {
1,086,805✔
1066
    code = terrno;
×
1067
    goto _OVER;
×
1068
  }
1069

1070
  pArray = mndBuildDnodesArray(pMnode, 0, dnodeList);
1,086,805✔
1071
  if (pArray == NULL) {
1,086,805✔
1072
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1073
    if (terrno != 0) code = terrno;
×
1074
    goto _OVER;
×
1075
  }
1076

1077
  mInfo("db:%s, total %d dnodes used to create %d vgroups (%d vnodes)", pDb->name, (int32_t)taosArrayGetSize(pArray),
1,086,805✔
1078
        pDb->cfg.numOfVgroups, pDb->cfg.numOfVgroups * pDb->cfg.replications);
1079

1080
  int32_t  allocedVgroups = 0;
1,086,805✔
1081
  int32_t  maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
1,086,805✔
1082
  uint32_t hashMin = 0;
1,086,805✔
1083
  uint32_t hashMax = UINT32_MAX;
1,086,805✔
1084
  uint32_t hashInterval = (hashMax - hashMin) / pDb->cfg.numOfVgroups;
1,086,805✔
1085

1086
  if (maxVgId < 2) maxVgId = 2;
1,086,805✔
1087

1088
  for (uint32_t v = 0; v < pDb->cfg.numOfVgroups; v++) {
3,418,357✔
1089
    SVgObj *pVgroup = &pVgroups[v];
2,335,992✔
1090
    pVgroup->vgId = maxVgId++;
2,335,992✔
1091
    pVgroup->createdTime = taosGetTimestampMs();
2,335,992✔
1092
    pVgroup->updateTime = pVgroups->createdTime;
2,335,992✔
1093
    pVgroup->version = 1;
2,335,992✔
1094
    pVgroup->hashBegin = hashMin + hashInterval * v;
2,335,992✔
1095
    if (v == pDb->cfg.numOfVgroups - 1) {
2,335,992✔
1096
      pVgroup->hashEnd = hashMax;
1,084,555✔
1097
    } else {
1098
      pVgroup->hashEnd = hashMin + hashInterval * (v + 1) - 1;
1,251,437✔
1099
    }
1100

1101
    memcpy(pVgroup->dbName, pDb->name, TSDB_DB_FNAME_LEN);
2,335,992✔
1102
    pVgroup->dbUid = pDb->uid;
2,335,992✔
1103
    pVgroup->replica = pDb->cfg.replications;
2,335,992✔
1104
    pVgroup->keepVersion = -1;  // default: WAL keep version disabled
2,335,992✔
1105
    pVgroup->keepVersionTime = 0;
2,335,992✔
1106

1107
    if ((code = mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray)) != 0) {
2,335,992✔
1108
      goto _OVER;
4,440✔
1109
    }
1110

1111
    allocedVgroups++;
2,331,552✔
1112
  }
1113

1114
  *ppVgroups = pVgroups;
1,082,365✔
1115
  code = 0;
1,082,365✔
1116

1117
  mInfo("db:%s, total %d vgroups is alloced, replica:%d", pDb->name, pDb->cfg.numOfVgroups, pDb->cfg.replications);
1,082,365✔
1118

1119
_OVER:
×
1120
  if (code != 0) taosMemoryFree(pVgroups);
1,086,805✔
1121
  taosArrayDestroy(pArray);
1,086,805✔
1122
  TAOS_RETURN(code);
1,086,805✔
1123
}
1124

1125
SEpSet mndGetVgroupEpset(SMnode *pMnode, const SVgObj *pVgroup) {
27,235,003✔
1126
  SEpSet epset = {0};
27,235,003✔
1127

1128
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
60,837,212✔
1129
    const SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
33,602,209✔
1130
    SDnodeObj       *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
33,602,209✔
1131
    if (pDnode == NULL) continue;
33,602,209✔
1132

1133
    if (pVgid->syncState == TAOS_SYNC_STATE_LEADER || pVgid->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
33,586,254✔
1134
      epset.inUse = epset.numOfEps;
26,842,665✔
1135
    }
1136

1137
    if (addEpIntoEpSet(&epset, pDnode->fqdn, pDnode->port) != 0) {
33,586,254✔
1138
      mWarn("vgId:%d, failed to add ep:%s:%d into epset", pVgroup->vgId, pDnode->fqdn, pDnode->port);
×
1139
    }
1140
    mndReleaseDnode(pMnode, pDnode);
33,586,254✔
1141
  }
1142
  epsetSort(&epset);
27,235,003✔
1143

1144
  return epset;
27,235,003✔
1145
}
1146

1147
SEpSet mndGetVgroupEpsetById(SMnode *pMnode, int32_t vgId) {
489,281✔
1148
  SEpSet epset = {0};
489,281✔
1149

1150
  SVgObj *pVgroup = mndAcquireVgroup(pMnode, vgId);
489,281✔
1151
  if (!pVgroup) return epset;
489,281✔
1152

1153
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
1,041,866✔
1154
    const SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
552,585✔
1155
    SDnodeObj       *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
552,585✔
1156
    if (pDnode == NULL) continue;
552,585✔
1157

1158
    if (pVgid->syncState == TAOS_SYNC_STATE_LEADER || pVgid->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
552,585✔
1159
      epset.inUse = epset.numOfEps;
458,755✔
1160
    }
1161

1162
    if (addEpIntoEpSet(&epset, pDnode->fqdn, pDnode->port) != 0) {
552,585✔
1163
      mWarn("vgId:%d, failed to add ep:%s:%d into epset", pVgroup->vgId, pDnode->fqdn, pDnode->port);
×
1164
    }
1165
    mndReleaseDnode(pMnode, pDnode);
552,585✔
1166
  }
1167

1168
  mndReleaseVgroup(pMnode, pVgroup);
489,281✔
1169
  return epset;
489,281✔
1170
}
1171

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

1188
  MND_SHOW_CHECK_OBJ_PRIVILEGE_ALL(RPC_MSG_USER(pReq), PRIV_SHOW_VGROUPS, PRIV_OBJ_DB, 0, _OVER);
247,658✔
1189

1190
  if (strlen(pShow->db) > 0) {
247,658✔
1191
    pDb = mndAcquireDb(pMnode, pShow->db);
215,221✔
1192
    if (pDb == NULL) {
215,221✔
1193
      goto _OVER;
×
1194
    }
1195
  }
1196

1197
  while (numOfRows < rows) {
1,358,737✔
1198
    pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
1,358,737✔
1199
    if (pShow->pIter == NULL) break;
1,358,737✔
1200

1201
    if (pDb != NULL && pVgroup->dbUid != pDb->uid) {
1,111,884✔
1202
      sdbRelease(pSdb, pVgroup);
358,333✔
1203
      continue;
358,333✔
1204
    }
1205

1206
    MND_SHOW_CHECK_DB_PRIVILEGE(pDb, pVgroup->dbName, pVgroup, RPC_MSG_TOKEN(pReq), MND_OPER_SHOW_VGROUPS, _OVER);
753,551✔
1207

1208
    cols = 0;
751,458✔
1209
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
751,458✔
1210
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->vgId, false, pVgroup, pShow->pIter, _OVER);
751,458✔
1211

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

1224
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
751,458✔
1225
    COL_DATA_SET_VAL_GOTO((const char *)db, false, pVgroup, pShow->pIter, _OVER);
751,458✔
1226

1227
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
751,458✔
1228
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->numOfTables, false, pVgroup, pShow->pIter, _OVER);
751,458✔
1229

1230
    bool isReady = false;
751,458✔
1231
    bool isLeaderRestored = false;
751,458✔
1232
    bool hasFollowerRestored = false;
751,458✔
1233
    ESyncState leaderState = TAOS_SYNC_STATE_OFFLINE;
751,458✔
1234
    // default 3 replica, add 1 replica if move vnode
1235
    for (int32_t i = 0; i < 4; ++i) {
3,757,290✔
1236
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3,005,832✔
1237
      if (i < pVgroup->replica) {
3,005,832✔
1238
        int16_t dnodeId = (int16_t)pVgroup->vnodeGid[i].dnodeId;
1,577,943✔
1239
        COL_DATA_SET_VAL_GOTO((const char *)&dnodeId, false, pVgroup, pShow->pIter, _OVER);
1,577,943✔
1240

1241
        bool       exist = false;
1,577,943✔
1242
        bool       online = false;
1,577,943✔
1243
        SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId);
1,577,943✔
1244
        if (pDnode != NULL) {
1,577,943✔
1245
          exist = true;
1,577,943✔
1246
          online = mndIsDnodeOnline(pDnode, curMs);
1,577,943✔
1247
          mndReleaseDnode(pMnode, pDnode);
1,577,943✔
1248
        }
1249

1250
        char buf1[20] = {0};
1,577,943✔
1251
        char role[20] = "offline";
1,577,943✔
1252
        if (!exist) {
1,577,943✔
1253
          tstrncpy(role, "dropping", sizeof(role));
×
1254
        } else if (online) {
1,577,943✔
1255
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER ||
1,560,192✔
1256
              pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
972,664✔
1257
            if (pVgroup->vnodeGid[i].syncRestore) {
587,528✔
1258
              isLeaderRestored = true;
498,044✔
1259
            }
1260
          } else if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_FOLLOWER) {
972,664✔
1261
            if (pVgroup->vnodeGid[i].syncRestore) {
816,654✔
1262
              hasFollowerRestored = true;
470,870✔
1263
            }
1264
          }
1265
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER ||
1,560,192✔
1266
              pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER)
972,664✔
1267
            leaderState = pVgroup->vnodeGid[i].syncState;
587,528✔
1268
          snprintf(role, sizeof(role), "%s", syncStr(pVgroup->vnodeGid[i].syncState));
1,560,192✔
1269
        }
1270
        STR_WITH_MAXSIZE_TO_VARSTR(buf1, role, pShow->pMeta->pSchemas[cols].bytes);
1,577,943✔
1271

1272
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,577,943✔
1273
        COL_DATA_SET_VAL_GOTO((const char *)buf1, false, pVgroup, pShow->pIter, _OVER);
1,577,943✔
1274

1275
        char applyStr[TSDB_SYNC_APPLY_COMMIT_LEN + 1] = {0};
1,577,943✔
1276
        char buf[TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE + 1] = {0};
1,577,943✔
1277

1278
        if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEARNER &&
1,577,943✔
1279
            (pVgroup->vnodeGid[i].snapSeq > 0 && pVgroup->vnodeGid[i].snapSeq < SYNC_SNAPSHOT_SEQ_END)) {
33,897✔
NEW
1280
          mInfo("db:%s, learner progress:%d", pDb->name, pVgroup->vnodeGid[i].learnerProgress);
×
1281

NEW
1282
          snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64 "/%" PRId64 "(snap:%d)(learner:%d)",
×
NEW
1283
                   pVgroup->vnodeGid[i].syncAppliedIndex, pVgroup->vnodeGid[i].syncCommitIndex,
×
NEW
1284
                   pVgroup->vnodeGid[i].syncTotalIndex, pVgroup->vnodeGid[i].snapSeq,
×
NEW
1285
                   pVgroup->vnodeGid[i].learnerProgress);
×
1286
        } else if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEARNER) {
1,577,943✔
1287
          mInfo("db:%s, learner progress:%d", pDb->name, pVgroup->vnodeGid[i].learnerProgress);
33,897✔
1288

1289
          snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64 "/%" PRId64 "(learner:%d)",
135,588✔
1290
                   pVgroup->vnodeGid[i].syncAppliedIndex, pVgroup->vnodeGid[i].syncCommitIndex,
67,794✔
1291
                   pVgroup->vnodeGid[i].syncTotalIndex, pVgroup->vnodeGid[i].learnerProgress);
67,794✔
1292
        } else if (pVgroup->vnodeGid[i].snapSeq > 0 && pVgroup->vnodeGid[i].snapSeq < SYNC_SNAPSHOT_SEQ_END) {
1,544,046✔
1293
          snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64 "(snap:%d)",
369✔
1294
                   pVgroup->vnodeGid[i].syncAppliedIndex, pVgroup->vnodeGid[i].syncCommitIndex,
246✔
1295
                   pVgroup->vnodeGid[i].snapSeq);
123✔
1296
        } else {
1297
          snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64, pVgroup->vnodeGid[i].syncAppliedIndex,
1,543,923✔
1298
                   pVgroup->vnodeGid[i].syncCommitIndex);
1,543,923✔
1299
        }
1300

1301
        STR_WITH_MAXSIZE_TO_VARSTR(buf, applyStr, pShow->pMeta->pSchemas[cols].bytes);
1,577,943✔
1302

1303
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,577,943✔
1304
        COL_DATA_SET_VAL_GOTO((const char *)&buf, false, pVgroup, pShow->pIter, _OVER);
1,577,943✔
1305
      } else {
1306
        colDataSetNULL(pColInfo, numOfRows);
1,427,889✔
1307
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,427,889✔
1308
        colDataSetNULL(pColInfo, numOfRows);
1,427,889✔
1309
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,427,889✔
1310
        colDataSetNULL(pColInfo, numOfRows);
1,427,889✔
1311
      }
1312
    }
1313

1314
    if (pVgroup->replica >= 3) {
751,458✔
1315
      if (isLeaderRestored && hasFollowerRestored) isReady = true;
329,146✔
1316
    } else if (pVgroup->replica == 2) {
422,312✔
1317
      if (leaderState == TAOS_SYNC_STATE_LEADER) {
168,193✔
1318
        if (isLeaderRestored && hasFollowerRestored) isReady = true;
85,600✔
1319
      } else if (leaderState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
82,593✔
1320
        if (isLeaderRestored) isReady = true;
×
1321
      }
1322
    } else {
1323
      if (isLeaderRestored) isReady = true;
254,119✔
1324
    }
1325
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
751,458✔
1326
    COL_DATA_SET_VAL_GOTO((const char *)&isReady, false, pVgroup, pShow->pIter, _OVER);
751,458✔
1327

1328
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
751,458✔
1329
    int64_t cacheUsage = (int64_t)pVgroup->cacheUsage;
751,458✔
1330
    COL_DATA_SET_VAL_GOTO((const char *)&cacheUsage, false, pVgroup, pShow->pIter, _OVER);
751,458✔
1331

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

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

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

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

1344
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
751,458✔
1345
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->keepVersionTime, false, pVgroup, pShow->pIter, _OVER);
751,458✔
1346

1347
    numOfRows++;
751,458✔
1348
    sdbRelease(pSdb, pVgroup);
751,458✔
1349
  }
1350
_OVER:
247,658✔
1351
  if (pUser) mndReleaseUser(pMnode, pUser);
247,658✔
1352
  if (pDb != NULL) {
247,658✔
1353
    mndReleaseDb(pMnode, pDb);
215,221✔
1354
  }
1355
  if (code != 0) {
247,658✔
1356
    mError("failed to retrieve vgroup info at line %d since %s", lino, tstrerror(code));
×
1357
    TAOS_RETURN(code);
×
1358
  }
1359

1360
  pShow->numOfRows += numOfRows;
247,658✔
1361
  return numOfRows;
247,658✔
1362
}
1363

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

1369
static bool mndGetVnodesNumFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
9,408,363✔
1370
  SVgObj  *pVgroup = pObj;
9,408,363✔
1371
  int32_t  dnodeId = *(int32_t *)p1;
9,408,363✔
1372
  int32_t *pNumOfVnodes = (int32_t *)p2;
9,408,363✔
1373

1374
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
25,014,925✔
1375
    if (pVgroup->vnodeGid[v].dnodeId == dnodeId) {
15,606,562✔
1376
      (*pNumOfVnodes)++;
6,096,252✔
1377
    }
1378
  }
1379

1380
  return true;
9,408,363✔
1381
}
1382

1383
int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId) {
3,607,082✔
1384
  int32_t numOfVnodes = 0;
3,607,082✔
1385
  sdbTraverse(pMnode->pSdb, SDB_VGROUP, mndGetVnodesNumFp, &dnodeId, &numOfVnodes, NULL);
3,607,082✔
1386
  return numOfVnodes;
3,607,082✔
1387
}
1388

1389
int64_t mndGetVgroupMemory(SMnode *pMnode, SDbObj *pDbInput, SVgObj *pVgroup) {
7,633,700✔
1390
  SDbObj *pDb = pDbInput;
7,633,700✔
1391
  if (pDbInput == NULL) {
7,633,700✔
1392
    pDb = mndAcquireDb(pMnode, pVgroup->dbName);
4,421,425✔
1393
  }
1394

1395
  int64_t vgroupMemroy = 0;
7,633,700✔
1396
  if (pDb != NULL) {
7,633,700✔
1397
    int64_t buffer = (int64_t)pDb->cfg.buffer * 1024 * 1024;
7,633,700✔
1398
    int64_t cache = (int64_t)pDb->cfg.pages * pDb->cfg.pageSize * 1024;
7,633,700✔
1399
    vgroupMemroy = buffer + cache;
7,633,700✔
1400
    int64_t cacheLast = (int64_t)pDb->cfg.cacheLastSize * 1024 * 1024;
7,633,700✔
1401
    if (pDb->cfg.cacheLast > 0) {
7,633,700✔
1402
      vgroupMemroy += cacheLast;
986,520✔
1403
    }
1404
    mDebug("db:%s, vgroup:%d, buffer:%" PRId64 " cache:%" PRId64 " cacheLast:%" PRId64, pDb->name, pVgroup->vgId,
7,633,700✔
1405
           buffer, cache, cacheLast);
1406
  }
1407

1408
  if (pDbInput == NULL) {
7,633,700✔
1409
    mndReleaseDb(pMnode, pDb);
4,421,425✔
1410
  }
1411
  return vgroupMemroy;
7,633,700✔
1412
}
1413

1414
static bool mndGetVnodeMemroyFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
6,119,502✔
1415
  SVgObj  *pVgroup = pObj;
6,119,502✔
1416
  int32_t  dnodeId = *(int32_t *)p1;
6,119,502✔
1417
  int64_t *pVnodeMemory = (int64_t *)p2;
6,119,502✔
1418

1419
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
14,289,275✔
1420
    if (pVgroup->vnodeGid[v].dnodeId == dnodeId) {
8,169,773✔
1421
      *pVnodeMemory += mndGetVgroupMemory(pMnode, NULL, pVgroup);
4,278,546✔
1422
    }
1423
  }
1424

1425
  return true;
6,119,502✔
1426
}
1427

1428
int64_t mndGetVnodesMemory(SMnode *pMnode, int32_t dnodeId) {
1,728,382✔
1429
  int64_t vnodeMemory = 0;
1,728,382✔
1430
  sdbTraverse(pMnode->pSdb, SDB_VGROUP, mndGetVnodeMemroyFp, &dnodeId, &vnodeMemory, NULL);
1,728,382✔
1431
  return vnodeMemory;
1,728,382✔
1432
}
1433

1434
void calculateRstoreFinishTime(double rate, int64_t applyCount, char *restoreStr, size_t restoreStrSize) {
558✔
1435
  if (rate == 0) {
558✔
1436
    snprintf(restoreStr, restoreStrSize, "0:0:0");
558✔
1437
    return;
558✔
1438
  }
1439

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

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

1464
  MND_SHOW_CHECK_OBJ_PRIVILEGE_ALL(RPC_MSG_USER(pReq), PRIV_SHOW_VNODES, PRIV_OBJ_DB, 0, _OVER);
13,051✔
1465

1466
  while (numOfRows < rows - TSDB_MAX_REPLICA) {
38,401✔
1467
    pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
38,401✔
1468
    if (pShow->pIter == NULL) break;
38,401✔
1469

1470
    MND_SHOW_CHECK_DB_PRIVILEGE(pDb, pVgroup->dbName, pVgroup, RPC_MSG_TOKEN(pReq), MND_OPER_SHOW_VNODES, _OVER);
25,350✔
1471

1472
    for (int32_t i = 0; i < pVgroup->replica && numOfRows < rows; ++i) {
74,032✔
1473
      SVnodeGid       *pGid = &pVgroup->vnodeGid[i];
48,682✔
1474
      SColumnInfoData *pColInfo = NULL;
48,682✔
1475
      cols = 0;
48,682✔
1476

1477
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
48,682✔
1478
      COL_DATA_SET_VAL_GOTO((const char *)&pGid->dnodeId, false, pVgroup, pShow->pIter, _OVER);
48,682✔
1479
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
48,682✔
1480
      COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->vgId, false, pVgroup, pShow->pIter, _OVER);
48,682✔
1481

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

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

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

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

1512
      int64_t startTimeMs = (isDnodeOnline) ? pGid->startTimeMs : 0;
48,682✔
1513
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
48,682✔
1514
      COL_DATA_SET_VAL_GOTO((const char *)&startTimeMs, false, pVgroup, pShow->pIter, _OVER);
48,682✔
1515

1516
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
48,682✔
1517
      COL_DATA_SET_VAL_GOTO((const char *)&pGid->syncRestore, false, pVgroup, pShow->pIter, _OVER);
48,682✔
1518

1519
      int64_t unappliedCount = pGid->syncCommitIndex - pGid->syncAppliedIndex;
48,682✔
1520
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
48,682✔
1521
      char restoreStr[20] = {0};
48,682✔
1522
      if (unappliedCount > 0) {
48,682✔
1523
        calculateRstoreFinishTime(pGid->appliedRate, unappliedCount, restoreStr, sizeof(restoreStr));
558✔
1524
      }
1525
      STR_TO_VARSTR(buf, restoreStr);
48,682✔
1526
      COL_DATA_SET_VAL_GOTO((const char *)&buf, false, pVgroup, pShow->pIter, _OVER);
48,682✔
1527

1528
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
48,682✔
1529
      COL_DATA_SET_VAL_GOTO((const char *)&unappliedCount, false, pVgroup, pShow->pIter, _OVER);
48,682✔
1530

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

1534
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
48,682✔
1535
      COL_DATA_SET_VAL_GOTO((const char *)&pGid->bufferSegmentSize, false, pVgroup, pShow->pIter, _OVER);
48,682✔
1536

1537
      numOfRows++;
48,682✔
1538
    }
1539
    sdbRelease(pSdb, pVgroup);
25,350✔
1540
  }
1541
_OVER:
13,051✔
1542
  if (pUser) mndReleaseUser(pMnode, pUser);
13,051✔
1543
  if (pDb) mndReleaseDb(pMnode, pDb);
13,051✔
1544
  if (code != 0) {
13,051✔
1545
    mError("failed to retrieve vnode info at line %d since %s", lino, tstrerror(code));
×
1546
    return code;
×
1547
  }
1548
  pShow->numOfRows += numOfRows;
13,051✔
1549
  return numOfRows;
13,051✔
1550
}
1551

1552
static void mndCancelGetNextVnode(SMnode *pMnode, void *pIter) {
×
1553
  SSdb *pSdb = pMnode->pSdb;
×
1554
  sdbCancelFetchByType(pSdb, pIter, SDB_VGROUP);
×
1555
}
×
1556

1557
static int32_t mndAddVnodeToVgroup(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray) {
79,818✔
1558
  int32_t code = 0;
79,818✔
1559
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
79,818✔
1560
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
319,375✔
1561
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
239,557✔
1562
    mInfo("trans:%d, dnode:%d, equivalent vnodes:%d others:%d", pTrans->id, pDnode->id, pDnode->numOfVnodes,
239,557✔
1563
          pDnode->numOfOtherNodes);
1564
  }
1565

1566
  SVnodeGid *pVgid = &pVgroup->vnodeGid[pVgroup->replica];
79,818✔
1567
  for (int32_t d = 0; d < taosArrayGetSize(pArray); ++d) {
99,668✔
1568
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
96,595✔
1569

1570
    bool used = false;
96,595✔
1571
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
227,289✔
1572
      if (pDnode->id == pVgroup->vnodeGid[vn].dnodeId) {
150,544✔
1573
        used = true;
19,850✔
1574
        break;
19,850✔
1575
      }
1576
    }
1577
    if (used) continue;
96,595✔
1578

1579
    if (pDnode == NULL) {
76,745✔
1580
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
×
1581
    }
1582
    if (pDnode->numOfVnodes >= pDnode->numOfSupportVnodes) {
76,745✔
1583
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_VNODES);
×
1584
    }
1585

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

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

1601
    pVgroup->replica++;
76,745✔
1602
    pDnode->numOfVnodes++;
76,745✔
1603

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

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

1628
static int32_t mndRemoveVnodeFromVgroup(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray,
16,478✔
1629
                                        SVnodeGid *pDelVgid) {
1630
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
16,478✔
1631
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
62,563✔
1632
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
46,085✔
1633
    mInfo("trans:%d, dnode:%d, equivalent vnodes:%d others:%d", pTrans->id, pDnode->id, pDnode->numOfVnodes,
46,085✔
1634
          pDnode->numOfOtherNodes);
1635
  }
1636

1637
  int32_t code = -1;
16,478✔
1638
  for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
19,090✔
1639
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
18,558✔
1640

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

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

1668
  for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
44,460✔
1669
    SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
28,514✔
1670
    mInfo("trans:%d, db:%s, vgId:%d, vn:%d dnode:%d is reserved", pTrans->id, pVgroup->dbName, pVgroup->vgId, vn,
28,514✔
1671
          pVgid->dnodeId);
1672
  }
1673

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

1690
  TAOS_RETURN(code);
15,946✔
1691
}
1692

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

1701
  int32_t code = -1;
×
1702
  for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
×
1703
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
×
1704

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

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

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

1735
  TAOS_RETURN(code);
×
1736
}
1737

1738
int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid) {
2,723,880✔
1739
  int32_t      code = 0;
2,723,880✔
1740
  STransAction action = {0};
2,723,880✔
1741

1742
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
2,723,880✔
1743
  if (pDnode == NULL) return -1;
2,723,880✔
1744
  action.epSet = mndGetDnodeEpset(pDnode);
2,723,880✔
1745
  mndReleaseDnode(pMnode, pDnode);
2,723,880✔
1746

1747
  int32_t contLen = 0;
2,723,880✔
1748
  void   *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
2,723,880✔
1749
  if (pReq == NULL) return -1;
2,723,880✔
1750

1751
  action.pCont = pReq;
2,723,880✔
1752
  action.contLen = contLen;
2,723,880✔
1753
  action.msgType = TDMT_DND_CREATE_VNODE;
2,723,880✔
1754
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
2,723,880✔
1755
  action.groupId = pVgroup->vgId;
2,723,880✔
1756

1757
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2,723,880✔
1758
    taosMemoryFree(pReq);
×
1759
    TAOS_RETURN(code);
×
1760
  }
1761

1762
  TAOS_RETURN(code);
2,723,880✔
1763
}
1764

1765
int32_t mndRestoreAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
2,120✔
1766
                                       SDnodeObj *pDnode) {
1767
  int32_t      code = 0;
2,120✔
1768
  STransAction action = {0};
2,120✔
1769

1770
  action.epSet = mndGetDnodeEpset(pDnode);
2,120✔
1771

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

1780
  action.pCont = pReq;
2,120✔
1781
  action.contLen = contLen;
2,120✔
1782
  action.msgType = TDMT_DND_CREATE_VNODE;
2,120✔
1783
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
2,120✔
1784
  action.groupId = pVgroup->vgId;
2,120✔
1785

1786
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2,120✔
1787
    taosMemoryFree(pReq);
×
1788
    TAOS_RETURN(code);
×
1789
  }
1790

1791
  TAOS_RETURN(code);
2,120✔
1792
}
1793

1794
int32_t mndAddAlterVnodeConfirmAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
277,458✔
1795
  int32_t      code = 0;
277,458✔
1796
  STransAction action = {0};
277,458✔
1797
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
277,458✔
1798

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

1806
  pHead->contLen = htonl(contLen);
277,458✔
1807
  pHead->vgId = htonl(pVgroup->vgId);
277,458✔
1808

1809
  action.pCont = pHead;
277,458✔
1810
  action.contLen = contLen;
277,458✔
1811
  action.msgType = TDMT_VND_ALTER_CONFIRM;
277,458✔
1812
  // incorrect redirect result will cause this erro
1813
  action.retryCode = TSDB_CODE_VND_INVALID_VGROUP_ID;
277,458✔
1814
  action.groupId = pVgroup->vgId;
277,458✔
1815

1816
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
277,458✔
1817
    taosMemoryFree(pHead);
×
1818
    TAOS_RETURN(code);
×
1819
  }
1820

1821
  TAOS_RETURN(code);
277,458✔
1822
}
1823

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

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

1838
  int32_t totallen = contLen + sizeof(SMsgHead);
×
1839

1840
  SMsgHead *pHead = taosMemoryMalloc(totallen);
×
1841
  if (pHead == NULL) {
×
1842
    taosMemoryFree(pReq);
×
1843
    TAOS_RETURN(terrno);
×
1844
  }
1845

1846
  pHead->contLen = htonl(totallen);
×
1847
  pHead->vgId = htonl(pNewVgroup->vgId);
×
1848

1849
  memcpy((void *)(pHead + 1), pReq, contLen);
×
1850
  taosMemoryFree(pReq);
×
1851

1852
  action.pCont = pHead;
×
1853
  action.contLen = totallen;
×
1854
  action.msgType = TDMT_SYNC_CONFIG_CHANGE;
×
1855

1856
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
1857
    taosMemoryFree(pHead);
×
1858
    TAOS_RETURN(code);
×
1859
  }
1860

1861
  TAOS_RETURN(code);
×
1862
}
1863

1864
static int32_t mndAddAlterVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, int32_t srcVgId, SVgObj *pVgroup) {
31,006✔
1865
  int32_t      code = 0;
31,006✔
1866
  STransAction action = {0};
31,006✔
1867
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
31,006✔
1868

1869
  int32_t contLen = 0;
31,006✔
1870
  void   *pReq = mndBuildAlterVnodeHashRangeReq(pMnode, srcVgId, pVgroup, &contLen);
31,006✔
1871
  if (pReq == NULL) {
31,006✔
1872
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1873
    if (terrno != 0) code = terrno;
×
1874
    TAOS_RETURN(code);
×
1875
  }
1876

1877
  action.pCont = pReq;
31,006✔
1878
  action.contLen = contLen;
31,006✔
1879
  action.msgType = TDMT_VND_ALTER_HASHRANGE;
31,006✔
1880
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
31,006✔
1881

1882
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
31,006✔
1883
    taosMemoryFree(pReq);
×
1884
    TAOS_RETURN(code);
×
1885
  }
1886

1887
  mInfo("trans:%d, add alter vnode hash range action for from vgId:%d to vgId:%d", pTrans->id, srcVgId, pVgroup->vgId);
31,006✔
1888
  TAOS_RETURN(code);
31,006✔
1889
}
1890

1891
int32_t mndAddAlterVnodeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
198,917✔
1892
  int32_t      code = 0;
198,917✔
1893
  STransAction action = {0};
198,917✔
1894
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
198,917✔
1895

1896
  int32_t contLen = 0;
198,917✔
1897
  void   *pReq = mndBuildAlterVnodeConfigReq(pMnode, pDb, pVgroup, &contLen);
198,917✔
1898
  if (pReq == NULL) {
198,917✔
1899
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1900
    if (terrno != 0) code = terrno;
×
1901
    TAOS_RETURN(code);
×
1902
  }
1903

1904
  action.pCont = pReq;
198,917✔
1905
  action.contLen = contLen;
198,917✔
1906
  action.msgType = TDMT_VND_ALTER_CONFIG;
198,917✔
1907
  action.groupId = pVgroup->vgId;
198,917✔
1908

1909
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
198,917✔
1910
    taosMemoryFree(pReq);
×
1911
    TAOS_RETURN(code);
×
1912
  }
1913

1914
  TAOS_RETURN(code);
198,917✔
1915
}
1916

1917
int32_t mndAddNewVgPrepareAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVg) {
2,363,566✔
1918
  int32_t  code = 0;
2,363,566✔
1919
  SSdbRaw *pRaw = mndVgroupActionEncode(pVg);
2,363,566✔
1920
  if (pRaw == NULL) {
2,363,566✔
1921
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1922
    if (terrno != 0) code = terrno;
×
1923
    goto _err;
×
1924
  }
1925

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

1937
_err:
×
1938
  sdbFreeRaw(pRaw);
×
1939
  TAOS_RETURN(code);
×
1940
}
1941

1942
int32_t mndAddAlterVnodeReplicaAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
681,114✔
1943
  int32_t    code = 0;
681,114✔
1944
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
681,114✔
1945
  if (pDnode == NULL) {
681,114✔
1946
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1947
    if (terrno != 0) code = terrno;
×
1948
    TAOS_RETURN(code);
×
1949
  }
1950

1951
  STransAction action = {0};
681,114✔
1952
  action.epSet = mndGetDnodeEpset(pDnode);
681,114✔
1953
  mndReleaseDnode(pMnode, pDnode);
681,114✔
1954

1955
  int32_t contLen = 0;
681,114✔
1956
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
681,114✔
1957
  if (pReq == NULL) {
681,114✔
1958
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1959
    if (terrno != 0) code = terrno;
×
1960
    TAOS_RETURN(code);
×
1961
  }
1962

1963
  action.pCont = pReq;
681,114✔
1964
  action.contLen = contLen;
681,114✔
1965
  action.msgType = TDMT_VND_ALTER_REPLICA;
681,114✔
1966
  action.groupId = pVgroup->vgId;
681,114✔
1967

1968
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
681,114✔
1969
    taosMemoryFree(pReq);
×
1970
    TAOS_RETURN(code);
×
1971
  }
1972

1973
  TAOS_RETURN(code);
681,114✔
1974
}
1975

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

1985
  STransAction action = {0};
×
1986
  action.epSet = mndGetDnodeEpset(pDnode);
×
1987
  mndReleaseDnode(pMnode, pDnode);
×
1988

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

1997
  action.pCont = pReq;
×
1998
  action.contLen = contLen;
×
1999
  action.msgType = TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP;
×
2000
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
×
2001
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
×
2002

2003
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
2004
    taosMemoryFree(pReq);
×
2005
    TAOS_RETURN(code);
×
2006
  }
2007

2008
  TAOS_RETURN(code);
×
2009
}
2010

2011
int32_t mndAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
100,780✔
2012
  int32_t    code = 0;
100,780✔
2013
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
100,780✔
2014
  if (pDnode == NULL) {
100,780✔
2015
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2016
    if (terrno != 0) code = terrno;
×
2017
    TAOS_RETURN(code);
×
2018
  }
2019

2020
  STransAction action = {0};
100,780✔
2021
  action.epSet = mndGetDnodeEpset(pDnode);
100,780✔
2022
  mndReleaseDnode(pMnode, pDnode);
100,780✔
2023

2024
  int32_t contLen = 0;
100,780✔
2025
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
100,780✔
2026
  if (pReq == NULL) {
100,780✔
2027
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2028
    if (terrno != 0) code = terrno;
×
2029
    TAOS_RETURN(code);
×
2030
  }
2031

2032
  action.pCont = pReq;
100,780✔
2033
  action.contLen = contLen;
100,780✔
2034
  action.msgType = TDMT_DND_ALTER_VNODE_TYPE;
100,780✔
2035
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
100,780✔
2036
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
100,780✔
2037
  action.groupId = pVgroup->vgId;
100,780✔
2038

2039
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
100,780✔
2040
    taosMemoryFree(pReq);
×
2041
    TAOS_RETURN(code);
×
2042
  }
2043

2044
  TAOS_RETURN(code);
100,780✔
2045
}
2046

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

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

2061
  action.pCont = pReq;
2,120✔
2062
  action.contLen = contLen;
2,120✔
2063
  action.msgType = TDMT_DND_ALTER_VNODE_TYPE;
2,120✔
2064
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
2,120✔
2065
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
2,120✔
2066
  action.groupId = pVgroup->vgId;
2,120✔
2067

2068
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2,120✔
2069
    taosMemoryFree(pReq);
×
2070
    TAOS_RETURN(code);
×
2071
  }
2072

2073
  TAOS_RETURN(code);
2,120✔
2074
}
2075

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

2086
  STransAction action = {0};
31,006✔
2087
  action.epSet = mndGetDnodeEpset(pDnode);
31,006✔
2088
  mndReleaseDnode(pMnode, pDnode);
31,006✔
2089

2090
  int32_t contLen = 0;
31,006✔
2091
  void   *pReq = mndBuildDisableVnodeWriteReq(pMnode, pDb, pVgroup->vgId, &contLen);
31,006✔
2092
  if (pReq == NULL) {
31,006✔
2093
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2094
    if (terrno != 0) code = terrno;
×
2095
    TAOS_RETURN(code);
×
2096
  }
2097

2098
  action.pCont = pReq;
31,006✔
2099
  action.contLen = contLen;
31,006✔
2100
  action.msgType = TDMT_VND_DISABLE_WRITE;
31,006✔
2101

2102
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
31,006✔
2103
    taosMemoryFree(pReq);
×
2104
    TAOS_RETURN(code);
×
2105
  }
2106

2107
  TAOS_RETURN(code);
31,006✔
2108
}
2109

2110
int32_t mndAddDropVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid,
4,023,526✔
2111
                              bool isRedo) {
2112
  int32_t      code = 0;
4,023,526✔
2113
  STransAction action = {0};
4,023,526✔
2114

2115
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
4,023,526✔
2116
  if (pDnode == NULL) {
4,023,526✔
2117
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2118
    if (terrno != 0) code = terrno;
×
2119
    TAOS_RETURN(code);
×
2120
  }
2121
  action.epSet = mndGetDnodeEpset(pDnode);
4,023,526✔
2122
  mndReleaseDnode(pMnode, pDnode);
4,023,526✔
2123

2124
  int32_t contLen = 0;
4,023,526✔
2125
  void   *pReq = mndBuildDropVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
4,023,526✔
2126
  if (pReq == NULL) {
4,023,526✔
2127
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2128
    if (terrno != 0) code = terrno;
×
2129
    TAOS_RETURN(code);
×
2130
  }
2131

2132
  action.pCont = pReq;
4,023,526✔
2133
  action.contLen = contLen;
4,023,526✔
2134
  action.msgType = TDMT_DND_DROP_VNODE;
4,023,526✔
2135
  action.acceptableCode = TSDB_CODE_VND_NOT_EXIST;
4,023,526✔
2136
  action.groupId = pVgroup->vgId;
4,023,526✔
2137

2138
  if (isRedo) {
4,023,526✔
2139
    if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
1,441,109✔
2140
      taosMemoryFree(pReq);
×
2141
      TAOS_RETURN(code);
×
2142
    }
2143
  } else {
2144
    if ((code = mndTransAppendUndoAction(pTrans, &action)) != 0) {
2,582,417✔
2145
      taosMemoryFree(pReq);
×
2146
      TAOS_RETURN(code);
×
2147
    }
2148
  }
2149

2150
  TAOS_RETURN(code);
4,023,526✔
2151
}
2152

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

2159
  mInfo("vgId:%d, trans:%d, vgroup info before move, replica:%d", newVg.vgId, pTrans->id, newVg.replica);
14,008✔
2160
  for (int32_t i = 0; i < newVg.replica; ++i) {
45,206✔
2161
    mInfo("vgId:%d, trans:%d, vnode:%d dnode:%d", newVg.vgId, pTrans->id, i, newVg.vnodeGid[i].dnodeId);
31,198✔
2162
  }
2163

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

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

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

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

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

2268
    if (newVg.replica == 1) {
×
2269
      if (force && !unsafe) {
×
2270
        TAOS_RETURN(TSDB_CODE_VND_META_DATA_UNSAFE_DELETE);
×
2271
      }
2272

2273
      SSdb *pSdb = pMnode->pSdb;
×
2274
      void *pIter = NULL;
×
2275

2276
      while (1) {
×
2277
        SStbObj *pStb = NULL;
×
2278
        pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
×
2279
        if (pIter == NULL) break;
×
2280

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

2289
        sdbRelease(pSdb, pStb);
×
2290
      }
2291

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

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

2314
  mInfo("vgId:%d, vgroup info after move, replica:%d", newVg.vgId, newVg.replica);
14,008✔
2315
  for (int32_t i = 0; i < newVg.replica; ++i) {
45,206✔
2316
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
31,198✔
2317
  }
2318
  TAOS_RETURN(code);
14,008✔
2319
}
2320

2321
int32_t mndSetMoveVgroupsInfoToTrans(SMnode *pMnode, STrans *pTrans, int32_t delDnodeId, bool force, bool unsafe) {
6,977✔
2322
  int32_t code = 0;
6,977✔
2323
  SArray *pArray = mndBuildDnodesArray(pMnode, delDnodeId, NULL);
6,977✔
2324
  if (pArray == NULL) {
6,977✔
2325
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2326
    if (terrno != 0) code = terrno;
×
2327
    TAOS_RETURN(code);
×
2328
  }
2329

2330
  void *pIter = NULL;
6,977✔
2331
  while (1) {
20,923✔
2332
    SVgObj *pVgroup = NULL;
27,900✔
2333
    pIter = sdbFetch(pMnode->pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
27,900✔
2334
    if (pIter == NULL) break;
27,900✔
2335

2336
    int32_t vnIndex = -1;
20,923✔
2337
    for (int32_t i = 0; i < pVgroup->replica; ++i) {
41,938✔
2338
      if (pVgroup->vnodeGid[i].dnodeId == delDnodeId) {
35,023✔
2339
        vnIndex = i;
14,008✔
2340
        break;
14,008✔
2341
      }
2342
    }
2343

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

2353
    sdbRelease(pMnode->pSdb, pVgroup);
20,923✔
2354

2355
    if (code != 0) {
20,923✔
2356
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2357
      break;
×
2358
    }
2359
  }
2360

2361
  taosArrayDestroy(pArray);
6,977✔
2362
  TAOS_RETURN(code);
6,977✔
2363
}
2364

2365
static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
64,718✔
2366
                                             int32_t newDnodeId) {
2367
  int32_t code = 0;
64,718✔
2368
  mInfo("vgId:%d, will add 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, newDnodeId);
64,718✔
2369

2370
  // assoc dnode
2371
  SVnodeGid *pGid = &pVgroup->vnodeGid[pVgroup->replica];
64,718✔
2372
  pVgroup->replica++;
64,718✔
2373
  pGid->dnodeId = newDnodeId;
64,718✔
2374
  pGid->syncState = TAOS_SYNC_STATE_OFFLINE;
64,718✔
2375
  pGid->nodeRole = TAOS_SYNC_ROLE_LEARNER;
64,718✔
2376

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

2393
  // learner
2394
  for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
219,628✔
2395
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
154,910✔
2396
  }
2397
  TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, pVgroup, pGid));
64,718✔
2398

2399
  // voter
2400
  pGid->nodeRole = TAOS_SYNC_ROLE_VOTER;
64,718✔
2401
  TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, pVgroup, pGid->dnodeId));
64,718✔
2402
  for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
219,628✔
2403
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
154,910✔
2404
  }
2405

2406
  // confirm
2407
  TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup));
64,718✔
2408

2409
  TAOS_RETURN(code);
64,718✔
2410
}
2411

2412
static int32_t mndAddDecVgroupReplicaFromTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
64,718✔
2413
                                               int32_t delDnodeId) {
2414
  int32_t code = 0;
64,718✔
2415
  mInfo("vgId:%d, will remove 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, delDnodeId);
64,718✔
2416

2417
  SVnodeGid *pGid = NULL;
64,718✔
2418
  SVnodeGid  delGid = {0};
64,718✔
2419
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
113,719✔
2420
    if (pVgroup->vnodeGid[i].dnodeId == delDnodeId) {
113,719✔
2421
      pGid = &pVgroup->vnodeGid[i];
64,718✔
2422
      break;
64,718✔
2423
    }
2424
  }
2425

2426
  if (pGid == NULL) return 0;
64,718✔
2427

2428
  pVgroup->replica--;
64,718✔
2429
  memcpy(&delGid, pGid, sizeof(SVnodeGid));
64,718✔
2430
  memcpy(pGid, &pVgroup->vnodeGid[pVgroup->replica], sizeof(SVnodeGid));
64,718✔
2431
  memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
64,718✔
2432

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

2449
  TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pDb, pVgroup, &delGid, true));
64,718✔
2450
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
219,628✔
2451
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
154,910✔
2452
  }
2453
  TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup));
64,718✔
2454

2455
  TAOS_RETURN(code);
64,718✔
2456
}
2457

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

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

2471
  mndTransSetDbName(pTrans, pVgroup->dbName, NULL);
36,037✔
2472
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
36,037✔
2473
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
35,973✔
2474

2475
  mndTransSetSerial(pTrans);
35,973✔
2476
  mInfo("trans:%d, used to redistribute vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
35,973✔
2477

2478
  SVgObj newVg = {0};
35,973✔
2479
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
35,973✔
2480
  mInfo("vgId:%d, vgroup info before redistribute, replica:%d", newVg.vgId, newVg.replica);
35,973✔
2481
  for (int32_t i = 0; i < newVg.replica; ++i) {
121,366✔
2482
    mInfo("vgId:%d, vnode:%d dnode:%d role:%s", newVg.vgId, i, newVg.vnodeGid[i].dnodeId,
85,393✔
2483
          syncStr(newVg.vnodeGid[i].syncState));
2484
  }
2485

2486
  if (pNew1 != NULL && pOld1 != NULL) {
35,973✔
2487
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew1->id);
35,973✔
2488
    if (numOfVnodes >= pNew1->numOfSupportVnodes) {
35,973✔
2489
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew1->id, numOfVnodes,
665✔
2490
             pNew1->numOfSupportVnodes);
2491
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
665✔
2492
      goto _OVER;
665✔
2493
    }
2494

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

2505
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew1->id), NULL, _OVER);
35,308✔
2506
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld1->id), NULL, _OVER);
35,308✔
2507
  }
2508

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

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

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

2569
  mInfo("vgId:%d, vgroup info after redistribute, replica:%d", newVg.vgId, newVg.replica);
35,308✔
2570
  for (int32_t i = 0; i < newVg.replica; ++i) {
118,706✔
2571
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
83,398✔
2572
  }
2573

2574
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
35,308✔
2575
  code = 0;
34,668✔
2576

2577
_OVER:
36,037✔
2578
  mndTransDrop(pTrans);
36,037✔
2579
  mndReleaseDb(pMnode, pDb);
36,037✔
2580
  TAOS_RETURN(code);
36,037✔
2581
}
2582

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

2601
  SRedistributeVgroupReq req = {0};
43,841✔
2602
  if (tDeserializeSRedistributeVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) {
43,841✔
2603
    code = TSDB_CODE_INVALID_MSG;
×
2604
    goto _OVER;
×
2605
  }
2606

2607
  mInfo("vgId:%d, start to redistribute vgroup to dnode %d:%d:%d", req.vgId, req.dnodeId1, req.dnodeId2, req.dnodeId3);
43,841✔
2608
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_REDISTRIBUTE_VGROUP)) != 0) {
43,841✔
2609
    goto _OVER;
×
2610
  }
2611

2612
  pVgroup = mndAcquireVgroup(pMnode, req.vgId);
43,841✔
2613
  if (pVgroup == NULL) {
43,841✔
2614
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
1,995✔
2615
    if (terrno != 0) code = terrno;
1,995✔
2616
    goto _OVER;
1,995✔
2617
  }
2618
  if (pVgroup->mountVgId) {
41,846✔
2619
    code = TSDB_CODE_MND_MOUNT_OBJ_NOT_SUPPORT;
×
2620
    goto _OVER;
×
2621
  }
2622
  pDb = mndAcquireDb(pMnode, pVgroup->dbName);
41,846✔
2623
  if (pDb == NULL) {
41,846✔
2624
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2625
    if (terrno != 0) code = terrno;
×
2626
    goto _OVER;
×
2627
  }
2628

2629
  if (pVgroup->replica == 1) {
41,846✔
2630
    if (req.dnodeId1 <= 0 || req.dnodeId2 > 0 || req.dnodeId3 > 0) {
10,644✔
2631
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2632
      goto _OVER;
×
2633
    }
2634

2635
    if (req.dnodeId1 == pVgroup->vnodeGid[0].dnodeId) {
10,644✔
2636
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2637
      code = 0;
×
2638
      goto _OVER;
×
2639
    }
2640

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

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

2663
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, NULL, NULL, NULL, NULL);
10,644✔
2664

2665
  } else if (pVgroup->replica == 3) {
31,202✔
2666
    if (req.dnodeId1 <= 0 || req.dnodeId2 <= 0 || req.dnodeId3 <= 0) {
29,836✔
2667
      code = TSDB_CODE_MND_INVALID_REPLICA;
2,660✔
2668
      goto _OVER;
2,660✔
2669
    }
2670

2671
    if (req.dnodeId1 == req.dnodeId2 || req.dnodeId1 == req.dnodeId3 || req.dnodeId2 == req.dnodeId3) {
27,176✔
2672
      code = TSDB_CODE_MND_INVALID_REPLICA;
665✔
2673
      goto _OVER;
665✔
2674
    }
2675

2676
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId &&
26,511✔
2677
        req.dnodeId1 != pVgroup->vnodeGid[2].dnodeId) {
13,255✔
2678
      newDnodeId[++newIndex] = req.dnodeId1;
11,144✔
2679
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
11,144✔
2680
    }
2681

2682
    if (req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId &&
26,511✔
2683
        req.dnodeId2 != pVgroup->vnodeGid[2].dnodeId) {
17,709✔
2684
      newDnodeId[++newIndex] = req.dnodeId2;
13,055✔
2685
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
13,055✔
2686
    }
2687

2688
    if (req.dnodeId3 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId3 != pVgroup->vnodeGid[1].dnodeId &&
26,511✔
2689
        req.dnodeId3 != pVgroup->vnodeGid[2].dnodeId) {
21,063✔
2690
      newDnodeId[++newIndex] = req.dnodeId3;
17,076✔
2691
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
17,076✔
2692
    }
2693

2694
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId &&
26,511✔
2695
        req.dnodeId3 != pVgroup->vnodeGid[0].dnodeId) {
14,557✔
2696
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[0].dnodeId;
11,118✔
2697
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
11,118✔
2698
    }
2699

2700
    if (req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId &&
26,511✔
2701
        req.dnodeId3 != pVgroup->vnodeGid[1].dnodeId) {
16,407✔
2702
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[1].dnodeId;
14,398✔
2703
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
14,398✔
2704
    }
2705

2706
    if (req.dnodeId1 != pVgroup->vnodeGid[2].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[2].dnodeId &&
26,511✔
2707
        req.dnodeId3 != pVgroup->vnodeGid[2].dnodeId) {
19,746✔
2708
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[2].dnodeId;
15,759✔
2709
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
15,759✔
2710
    }
2711

2712
    if (newDnodeId[0] != 0) {
26,511✔
2713
      pNew1 = mndAcquireDnode(pMnode, newDnodeId[0]);
25,715✔
2714
      if (pNew1 == NULL) {
25,715✔
2715
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2716
        if (terrno != 0) code = terrno;
×
2717
        goto _OVER;
×
2718
      }
2719
      if (!mndIsDnodeOnline(pNew1, curMs)) {
25,715✔
2720
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
665✔
2721
        goto _OVER;
665✔
2722
      }
2723
    }
2724

2725
    if (newDnodeId[1] != 0) {
25,846✔
2726
      pNew2 = mndAcquireDnode(pMnode, newDnodeId[1]);
10,384✔
2727
      if (pNew2 == NULL) {
10,384✔
2728
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2729
        if (terrno != 0) code = terrno;
×
2730
        goto _OVER;
×
2731
      }
2732
      if (!mndIsDnodeOnline(pNew2, curMs)) {
10,384✔
2733
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
255✔
2734
        goto _OVER;
255✔
2735
      }
2736
    }
2737

2738
    if (newDnodeId[2] != 0) {
25,591✔
2739
      pNew3 = mndAcquireDnode(pMnode, newDnodeId[2]);
4,921✔
2740
      if (pNew3 == NULL) {
4,921✔
2741
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2742
        if (terrno != 0) code = terrno;
×
2743
        goto _OVER;
×
2744
      }
2745
      if (!mndIsDnodeOnline(pNew3, curMs)) {
4,921✔
2746
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2747
        goto _OVER;
×
2748
      }
2749
    }
2750

2751
    if (oldDnodeId[0] != 0) {
25,591✔
2752
      pOld1 = mndAcquireDnode(pMnode, oldDnodeId[0]);
24,795✔
2753
      if (pOld1 == NULL) {
24,795✔
2754
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2755
        if (terrno != 0) code = terrno;
×
2756
        goto _OVER;
×
2757
      }
2758
      if (!mndIsDnodeOnline(pOld1, curMs)) {
24,795✔
2759
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
768✔
2760
        goto _OVER;
768✔
2761
      }
2762
    }
2763

2764
    if (oldDnodeId[1] != 0) {
24,823✔
2765
      pOld2 = mndAcquireDnode(pMnode, oldDnodeId[1]);
9,361✔
2766
      if (pOld2 == NULL) {
9,361✔
2767
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2768
        if (terrno != 0) code = terrno;
×
2769
        goto _OVER;
×
2770
      }
2771
      if (!mndIsDnodeOnline(pOld2, curMs)) {
9,361✔
2772
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2773
        goto _OVER;
×
2774
      }
2775
    }
2776

2777
    if (oldDnodeId[2] != 0) {
24,823✔
2778
      pOld3 = mndAcquireDnode(pMnode, oldDnodeId[2]);
4,153✔
2779
      if (pOld3 == NULL) {
4,153✔
2780
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2781
        if (terrno != 0) code = terrno;
×
2782
        goto _OVER;
×
2783
      }
2784
      if (!mndIsDnodeOnline(pOld3, curMs)) {
4,153✔
2785
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2786
        goto _OVER;
×
2787
      }
2788
    }
2789

2790
    if (pNew1 == NULL && pOld1 == NULL && pNew2 == NULL && pOld2 == NULL && pNew3 == NULL && pOld3 == NULL) {
24,823✔
2791
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2792
      code = 0;
796✔
2793
      goto _OVER;
796✔
2794
    }
2795

2796
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, pNew3, pOld3);
24,027✔
2797

2798
  } else if (pVgroup->replica == 2) {
1,366✔
2799
    if (req.dnodeId1 <= 0 || req.dnodeId2 <= 0) {
1,366✔
2800
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2801
      goto _OVER;
×
2802
    }
2803

2804
    if (req.dnodeId1 == req.dnodeId2) {
1,366✔
2805
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2806
      goto _OVER;
×
2807
    }
2808

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

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

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

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

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

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

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

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

2881
    if (pNew1 == NULL && pOld1 == NULL && pNew2 == NULL && pOld2 == NULL) {
1,366✔
2882
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2883
      code = 0;
×
2884
      goto _OVER;
×
2885
    }
2886

2887
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, NULL, NULL);
1,366✔
2888
  } else {
2889
    code = TSDB_CODE_MND_REQ_REJECTED;
×
2890
    goto _OVER;
×
2891
  }
2892

2893
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
36,037✔
2894

2895
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
36,037✔
2896
    char obj[33] = {0};
36,037✔
2897
    (void)tsnprintf(obj, sizeof(obj), "%d", req.vgId);
36,037✔
2898

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

2910
  mndReleaseDnode(pMnode, pNew1);
43,841✔
2911
  mndReleaseDnode(pMnode, pNew2);
43,841✔
2912
  mndReleaseDnode(pMnode, pNew3);
43,841✔
2913
  mndReleaseDnode(pMnode, pOld1);
43,841✔
2914
  mndReleaseDnode(pMnode, pOld2);
43,841✔
2915
  mndReleaseDnode(pMnode, pOld3);
43,841✔
2916
  mndReleaseVgroup(pMnode, pVgroup);
43,841✔
2917
  mndReleaseDb(pMnode, pDb);
43,841✔
2918
  tFreeSRedistributeVgroupReq(&req);
43,841✔
2919

2920
  TAOS_RETURN(code);
43,841✔
2921
}
2922

2923
static void *mndBuildSForceBecomeFollowerReq(SMnode *pMnode, SVgObj *pVgroup, int32_t dnodeId, int32_t *pContLen) {
4,004✔
2924
  SForceBecomeFollowerReq balanceReq = {
4,004✔
2925
      .vgId = pVgroup->vgId,
4,004✔
2926
  };
2927

2928
  int32_t contLen = tSerializeSForceBecomeFollowerReq(NULL, 0, &balanceReq);
4,004✔
2929
  if (contLen < 0) {
4,004✔
2930
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2931
    return NULL;
×
2932
  }
2933
  contLen += sizeof(SMsgHead);
4,004✔
2934

2935
  void *pReq = taosMemoryMalloc(contLen);
4,004✔
2936
  if (pReq == NULL) {
4,004✔
2937
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2938
    return NULL;
×
2939
  }
2940

2941
  SMsgHead *pHead = pReq;
4,004✔
2942
  pHead->contLen = htonl(contLen);
4,004✔
2943
  pHead->vgId = htonl(pVgroup->vgId);
4,004✔
2944

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

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

2963
  STransAction action = {0};
4,004✔
2964
  action.epSet = mndGetDnodeEpset(pDnode);
4,004✔
2965
  mndReleaseDnode(pMnode, pDnode);
4,004✔
2966

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

2975
  action.pCont = pReq;
4,004✔
2976
  action.contLen = contLen;
4,004✔
2977
  action.msgType = TDMT_SYNC_FORCE_FOLLOWER;
4,004✔
2978

2979
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
4,004✔
2980
    taosMemoryFree(pReq);
×
2981
    TAOS_RETURN(code);
×
2982
  }
2983

2984
  TAOS_RETURN(code);
4,004✔
2985
}
2986

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

2994
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &alterReq);
24,024✔
2995
  if (contLen < 0) {
24,024✔
2996
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2997
    return NULL;
×
2998
  }
2999

3000
  void *pReq = taosMemoryMalloc(contLen);
24,024✔
3001
  if (pReq == NULL) {
24,024✔
3002
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3003
    return NULL;
×
3004
  }
3005

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

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

3025
  STransAction action = {0};
24,024✔
3026
  action.epSet = mndGetDnodeEpset(pDnode);
24,024✔
3027
  mndReleaseDnode(pMnode, pDnode);
24,024✔
3028

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

3037
  action.pCont = pReq;
24,024✔
3038
  action.contLen = contLen;
24,024✔
3039
  action.msgType = TDMT_VND_ALTER_ELECTBASELINE;
24,024✔
3040
  action.groupId = pVgroup->vgId;
24,024✔
3041

3042
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
24,024✔
3043
    taosMemoryFree(pReq);
×
3044
    TAOS_RETURN(code);
×
3045
  }
3046

3047
  TAOS_RETURN(code);
24,024✔
3048
}
3049

3050
static int32_t mndAddAlterVgroupElectionBaselineActionToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans, int32_t index){
8,008✔
3051
  int32_t code = 0;
8,008✔
3052
  SSdb   *pSdb = pMnode->pSdb;
8,008✔
3053

3054
  int32_t vgid = pVgroup->vgId;
8,008✔
3055
  int8_t  replica = pVgroup->replica;
8,008✔
3056

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

3062
  for(int32_t i = 0; i < 3; i++){
32,032✔
3063
    if(i == index%3){
24,024✔
3064
      mInfo("trans:%d, balance leader to dnode:%d", pTrans->id, pVgroup->vnodeGid[i].dnodeId);
4,004✔
3065
      TAOS_CHECK_RETURN(mndAddAlterVnodeElectionBaselineActionToTrans(pMnode, pTrans, NULL, pVgroup,
4,004✔
3066
                                                                      pVgroup->vnodeGid[i].dnodeId, 1500));
3067
    }
3068
    else{
3069
    TAOS_CHECK_RETURN(
20,020✔
3070
        mndAddAlterVnodeElectionBaselineActionToTrans(pMnode, pTrans, NULL, pVgroup, pVgroup->vnodeGid[i].dnodeId, 5000));
3071
    }
3072
  }
3073
  return code; 
8,008✔
3074
}
3075

3076
int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans, int32_t index) {
4,711✔
3077
  int32_t code = 0;
4,711✔
3078
  SSdb   *pSdb = pMnode->pSdb;
4,711✔
3079

3080
  int32_t vgid = pVgroup->vgId;
4,711✔
3081
  int8_t  replica = pVgroup->replica;
4,711✔
3082

3083
  if (pVgroup->replica <= 1) {
4,711✔
3084
    mInfo("trans:%d, vgid:%d no need to balance, replica:%d", pTrans->id, vgid, replica);
261✔
3085
    return -1;
261✔
3086
  }
3087

3088
  int32_t dnodeId = 0;
4,450✔
3089

3090
  for (int i = 0; i < replica; i++) {
11,178✔
3091
    if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER) {
10,732✔
3092
      dnodeId = pVgroup->vnodeGid[i].dnodeId;
4,004✔
3093
      break;
4,004✔
3094
    }
3095
  }
3096

3097
  bool       exist = false;
4,450✔
3098
  bool       online = false;
4,450✔
3099
  int64_t    curMs = taosGetTimestampMs();
4,450✔
3100
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
4,450✔
3101
  if (pDnode != NULL) {
4,450✔
3102
    exist = true;
4,004✔
3103
    online = mndIsDnodeOnline(pDnode, curMs);
4,004✔
3104
    mndReleaseDnode(pMnode, pDnode);
4,004✔
3105
  }
3106

3107
  if (exist && online) {
8,454✔
3108
    mInfo("trans:%d, vgid:%d force drop leader from dnode:%d", pTrans->id, vgid, dnodeId);    
4,004✔
3109
    TAOS_CHECK_RETURN(mndAddAlterVgroupElectionBaselineActionToTrans(pMnode, pVgroup, pTrans, index));
4,004✔
3110

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

3116
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, NULL, pVgroup));
4,004✔
3117

3118
    TAOS_CHECK_RETURN(mndAddAlterVgroupElectionBaselineActionToTrans(pMnode, pVgroup, pTrans, -1));
4,004✔
3119

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

3128
    mndReleaseDb(pMnode, pDb);
4,004✔
3129
  } else {
3130
    mInfo("trans:%d, vgid:%d cant be balanced to dnode:%d, exist:%d, online:%d", pTrans->id, vgid, dnodeId, exist,
446✔
3131
          online);
3132
  }
3133

3134
  TAOS_RETURN(code);
4,450✔
3135
}
3136

3137
extern int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq);
3138

3139
int32_t mndProcessVgroupBalanceLeaderMsg(SRpcMsg *pReq) { return mndProcessVgroupBalanceLeaderMsgImp(pReq); }
1,985✔
3140

3141
#ifndef TD_ENTERPRISE
3142
int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq) { return 0; }
3143
#endif
3144

3145
static int32_t mndCheckDnodeMemory(SMnode *pMnode, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pOldVgroup,
198,917✔
3146
                                   SVgObj *pNewVgroup, SArray *pArray) {
3147
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
595,308✔
3148
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
396,391✔
3149
    bool       inVgroup = false;
396,391✔
3150
    int64_t    oldMemUsed = 0;
396,391✔
3151
    int64_t    newMemUsed = 0;
396,391✔
3152
    mDebug("db:%s, vgId:%d, check dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
396,391✔
3153
           pDnode->id, pDnode->memAvail, pDnode->memUsed);
3154
    for (int32_t j = 0; j < pOldVgroup->replica; ++j) {
1,139,306✔
3155
      SVnodeGid *pVgId = &pOldVgroup->vnodeGid[j];
742,915✔
3156
      if (pDnode->id == pVgId->dnodeId) {
742,915✔
3157
        oldMemUsed = mndGetVgroupMemory(pMnode, pOldDb, pOldVgroup);
314,425✔
3158
        inVgroup = true;
314,425✔
3159
      }
3160
    }
3161
    for (int32_t j = 0; j < pNewVgroup->replica; ++j) {
1,139,306✔
3162
      SVnodeGid *pVgId = &pNewVgroup->vnodeGid[j];
742,915✔
3163
      if (pDnode->id == pVgId->dnodeId) {
742,915✔
3164
        newMemUsed = mndGetVgroupMemory(pMnode, pNewDb, pNewVgroup);
314,425✔
3165
        inVgroup = true;
314,425✔
3166
      }
3167
    }
3168

3169
    mDebug("db:%s, vgId:%d, memory in dnode:%d, oldUsed:%" PRId64 ", newUsed:%" PRId64, pNewVgroup->dbName,
396,391✔
3170
           pNewVgroup->vgId, pDnode->id, oldMemUsed, newMemUsed);
3171

3172
    pDnode->memUsed = pDnode->memUsed - oldMemUsed + newMemUsed;
396,391✔
3173
    if (pDnode->memAvail - pDnode->memUsed <= 0) {
396,391✔
3174
      mError("db:%s, vgId:%d, no enough memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName,
×
3175
             pNewVgroup->vgId, pDnode->id, pDnode->memAvail, pDnode->memUsed);
3176
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
3177
    } else if (inVgroup) {
396,391✔
3178
      mInfo("db:%s, vgId:%d, memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
314,425✔
3179
            pDnode->id, pDnode->memAvail, pDnode->memUsed);
3180
    } else {
3181
    }
3182
  }
3183
  return 0;
198,917✔
3184
}
3185

3186
int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pVgroup,
233,409✔
3187
                                  SArray *pArray, SVgObj *pNewVgroup) {
3188
  int32_t code = 0;
233,409✔
3189
  memcpy(pNewVgroup, pVgroup, sizeof(SVgObj));
233,409✔
3190

3191
  if (pVgroup->replica <= 0 || pVgroup->replica == pNewDb->cfg.replications) {
233,409✔
3192
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfigAction(pMnode, pTrans, pNewDb, pVgroup));
198,917✔
3193
    TAOS_CHECK_RETURN(mndCheckDnodeMemory(pMnode, pOldDb, pNewDb, pNewVgroup, pVgroup, pArray));
198,917✔
3194
    return 0;
198,917✔
3195
  }
3196

3197
  // mndTransSetGroupParallel(pTrans);
3198

3199
  if (pNewDb->cfg.replications == 3) {
34,492✔
3200
    mInfo("trans:%d, db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
29,748✔
3201
          pVgroup->vnodeGid[0].dnodeId);
3202

3203
    // add second
3204
    if (pNewVgroup->replica == 1) {
29,748✔
3205
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
29,748✔
3206
    }
3207

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

3214
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[1]));
29,066✔
3215

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

3222
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
29,066✔
3223

3224
    // add third
3225
    if (pNewVgroup->replica == 2) {
29,066✔
3226
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
29,066✔
3227
    }
3228

3229
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
26,675✔
3230
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
26,675✔
3231
    pNewVgroup->vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
26,675✔
3232
    TAOS_CHECK_RETURN(
26,675✔
3233
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3234
    TAOS_CHECK_RETURN(
26,675✔
3235
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
3236
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[2]));
26,675✔
3237

3238
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
26,675✔
3239
  } else if (pNewDb->cfg.replications == 1) {
4,744✔
3240
    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,378✔
3241
          pVgroup->dbName, pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId, pVgroup->vnodeGid[1].dnodeId,
3242
          pVgroup->vnodeGid[2].dnodeId);
3243

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

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

3263
    // add second
3264
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
1,366✔
3265

3266
    // learner stage
3267
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
1,366✔
3268
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
1,366✔
3269
    TAOS_CHECK_RETURN(
1,366✔
3270
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3271

3272
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[1]));
1,366✔
3273

3274
    // follower stage
3275
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
1,366✔
3276
    TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
1,366✔
3277
    TAOS_CHECK_RETURN(
1,366✔
3278
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3279

3280
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
1,366✔
3281
  } else {
3282
    return -1;
×
3283
  }
3284

3285
  mndSortVnodeGid(pNewVgroup);
31,419✔
3286

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

3305
  TAOS_RETURN(code);
31,419✔
3306
}
3307

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

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

3320
  mndTransSetSerial(pTrans);
×
3321

3322
  mInfo("trans:%d, vgId:%d, alter vgroup, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3323
        pVgroup->syncConfChangeVer, pVgroup->version, pVgroup->replica);
3324

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

3329
    // add second
3330
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray));
×
3331
    // add third
3332
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray));
×
3333

3334
    // add learner stage
3335
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3336
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3337
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3338
    TAOS_CHECK_RETURN(
×
3339
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3340
    mInfo("trans:%d, vgId:%d, add change config, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id,
×
3341
          pVgroup->vgId, newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3342
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[1]));
×
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
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[2]));
×
3346
    mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3347
          newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3348

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

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

3365
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3366

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

3373
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3374

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

3395
    SVnodeGid del1 = {0};
×
3396
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del1));
×
3397

3398
    TAOS_CHECK_RETURN(
×
3399
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3400

3401
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3402

3403
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &del1, true));
×
3404

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

3422
    SVnodeGid del2 = {0};
×
3423
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del2));
×
3424

3425
    TAOS_CHECK_RETURN(
×
3426
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3427

3428
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3429

3430
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &del2, true));
×
3431

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

3452
  mndSortVnodeGid(&newVgroup);
×
3453

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

3473
  TAOS_RETURN(code);
×
3474
}
3475

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

3482
  mInfo("trans:%d, db:%s, vgId:%d, restore vnodes, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
2,120✔
3483
        pVgroup->vnodeGid[0].dnodeId);
3484

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

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

3513
    for (int i = 0; i < newVgroup.replica; i++) {
×
3514
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3515
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3516
      }
3517
    }
3518
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode));
×
3519
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pAnotherDnode));
×
3520
  } else if (newVgroup.replica == 3) {
2,120✔
3521
    for (int i = 0; i < newVgroup.replica; i++) {
8,480✔
3522
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
6,360✔
3523
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
2,120✔
3524
      } else {
3525
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
4,240✔
3526
      }
3527
    }
3528
    TAOS_CHECK_RETURN(mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode));
2,120✔
3529

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

3553
  TAOS_RETURN(code);
2,120✔
3554
}
3555

3556
static int32_t mndAddAdjustVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
×
3557
  return 0;
×
3558
}
3559

3560
typedef int32_t (*FpTransActionCb)(STrans *pTrans, SSdbRaw *pRaw);
3561

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

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

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

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

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

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

3637
  mndTransSetDbName(pTrans, pDb->name, NULL);
16,099✔
3638
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
16,099✔
3639
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
16,035✔
3640

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

3649
  if (newVg1.replica == 1) {
16,035✔
3650
    TAOS_CHECK_GOTO(mndAddVnodeToVgroup(pMnode, pTrans, &newVg1, pArray), NULL, _OVER);
5,630✔
3651

3652
    newVg1.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
5,630✔
3653
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
5,630✔
3654
                    _OVER);
3655
    TAOS_CHECK_GOTO(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg1, &newVg1.vnodeGid[1]), NULL, _OVER);
5,630✔
3656

3657
    newVg1.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
5,630✔
3658
    TAOS_CHECK_GOTO(mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[1].dnodeId), NULL, _OVER);
5,630✔
3659
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
5,630✔
3660
                    _OVER);
3661

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

3675
  for (int32_t i = 0; i < newVg1.replica; ++i) {
46,509✔
3676
    TAOS_CHECK_GOTO(mndAddDisableVnodeWriteAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[i].dnodeId), NULL,
31,006✔
3677
                    _OVER);
3678
  }
3679
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
15,503✔
3680

3681
  SVgObj newVg2 = {0};
15,503✔
3682
  memcpy(&newVg2, &newVg1, sizeof(SVgObj));
15,503✔
3683
  newVg1.replica = 1;
15,503✔
3684
  newVg1.hashEnd = newVg1.hashBegin / 2 + newVg1.hashEnd / 2;
15,503✔
3685
  memset(&newVg1.vnodeGid[1], 0, sizeof(SVnodeGid));
15,503✔
3686

3687
  newVg2.replica = 1;
15,503✔
3688
  newVg2.hashBegin = newVg1.hashEnd + 1;
15,503✔
3689
  memcpy(&newVg2.vnodeGid[0], &newVg2.vnodeGid[1], sizeof(SVnodeGid));
15,503✔
3690
  memset(&newVg2.vnodeGid[1], 0, sizeof(SVnodeGid));
15,503✔
3691

3692
  mInfo("vgId:%d, vgroup info after split, replica:%d hashrange:[%u, %u] vnode:0 dnode:%d", newVg1.vgId, newVg1.replica,
15,503✔
3693
        newVg1.hashBegin, newVg1.hashEnd, newVg1.vnodeGid[0].dnodeId);
3694
  for (int32_t i = 0; i < newVg1.replica; ++i) {
31,006✔
3695
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg1.vgId, i, newVg1.vnodeGid[i].dnodeId);
15,503✔
3696
  }
3697
  mInfo("vgId:%d, vgroup info after split, replica:%d hashrange:[%u, %u] vnode:0 dnode:%d", newVg2.vgId, newVg2.replica,
15,503✔
3698
        newVg2.hashBegin, newVg2.hashEnd, newVg2.vnodeGid[0].dnodeId);
3699
  for (int32_t i = 0; i < newVg1.replica; ++i) {
31,006✔
3700
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg2.vgId, i, newVg2.vnodeGid[i].dnodeId);
15,503✔
3701
  }
3702

3703
  // alter vgId and hash range
3704
  int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
15,503✔
3705
  int32_t srcVgId = newVg1.vgId;
15,503✔
3706
  newVg1.vgId = maxVgId;
15,503✔
3707
  TAOS_CHECK_GOTO(mndAddNewVgPrepareAction(pMnode, pTrans, &newVg1), NULL, _OVER);
15,503✔
3708
  TAOS_CHECK_GOTO(mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg1), NULL, _OVER);
15,503✔
3709

3710
  maxVgId++;
15,503✔
3711
  srcVgId = newVg2.vgId;
15,503✔
3712
  newVg2.vgId = maxVgId;
15,503✔
3713
  TAOS_CHECK_GOTO(mndAddNewVgPrepareAction(pMnode, pTrans, &newVg2), NULL, _OVER);
15,503✔
3714
  TAOS_CHECK_GOTO(mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg2), NULL, _OVER);
15,503✔
3715

3716
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
15,503✔
3717
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg2), NULL, _OVER);
15,503✔
3718

3719
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
15,503✔
3720
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
15,503✔
3721
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_REDO_ACTION), NULL, _OVER);
15,503✔
3722

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

3737
  // adjust vgroup replica
3738
  if (pDb->cfg.replications != newVg1.replica) {
15,503✔
3739
    SVgObj tmpGroup = {0};
9,873✔
3740
    TAOS_CHECK_GOTO(mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg1, pArray, &tmpGroup), NULL, _OVER);
9,873✔
3741
  } else {
3742
    TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
5,630✔
3743
  }
3744

3745
  if (pDb->cfg.replications != newVg2.replica) {
13,645✔
3746
    SVgObj tmpGroup = {0};
8,015✔
3747
    TAOS_CHECK_GOTO(mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg2, pArray, &tmpGroup), NULL, _OVER);
8,015✔
3748
  } else {
3749
    TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
5,630✔
3750
  }
3751

3752
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
13,112✔
3753

3754
  // commit db status
3755
  dbObj.vgVersion++;
13,112✔
3756
  dbObj.updateTime = taosGetTimestampMs();
13,112✔
3757
  TAOS_CHECK_GOTO(mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
13,112✔
3758

3759
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
13,112✔
3760
  code = 0;
13,112✔
3761

3762
_OVER:
16,099✔
3763
  taosArrayDestroy(pArray);
16,099✔
3764
  mndTransDrop(pTrans);
16,099✔
3765
  taosArrayDestroy(dbObj.cfg.pRetensions);
16,099✔
3766
  TAOS_RETURN(code);
16,099✔
3767
}
3768

3769
extern int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq);
3770

3771
static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) { return mndProcessSplitVgroupMsgImp(pReq); }
16,463✔
3772

3773
#ifndef TD_ENTERPRISE
3774
int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq) { return 0; }
3775
#endif
3776

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

3787
  TAOS_CHECK_RETURN(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pDst->id));
14,530✔
3788
  TAOS_CHECK_RETURN(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pSrc->id));
14,530✔
3789

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

3808
  mInfo("vgId:%d, vgroup info after balance, replica:%d", newVg.vgId, newVg.replica);
14,530✔
3809
  for (int32_t i = 0; i < newVg.replica; ++i) {
42,768✔
3810
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
28,238✔
3811
  }
3812
  TAOS_RETURN(code);
14,530✔
3813
}
3814

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

3821
  while (1) {
8,975✔
3822
    SVgObj *pVgroup = NULL;
23,505✔
3823
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
23,505✔
3824
    if (pIter == NULL) break;
23,505✔
3825
    if (taosHashGet(pBalancedVgroups, &pVgroup->vgId, sizeof(int32_t)) != NULL) {
23,505✔
3826
      sdbRelease(pSdb, pVgroup);
8,219✔
3827
      continue;
8,219✔
3828
    }
3829

3830
    bool existInSrc = false;
15,286✔
3831
    bool existInDst = false;
15,286✔
3832
    for (int32_t i = 0; i < pVgroup->replica; ++i) {
44,280✔
3833
      SVnodeGid *pGid = &pVgroup->vnodeGid[i];
28,994✔
3834
      if (pGid->dnodeId == pSrc->id) existInSrc = true;
28,994✔
3835
      if (pGid->dnodeId == pDst->id) existInDst = true;
28,994✔
3836
    }
3837

3838
    if (!existInSrc || existInDst) {
15,286✔
3839
      sdbRelease(pSdb, pVgroup);
756✔
3840
      continue;
756✔
3841
    }
3842

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

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

3856
    code = mndSetBalanceVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, pSrc, pDst);
14,530✔
3857
    if (code == 0) {
14,530✔
3858
      code = taosHashPut(pBalancedVgroups, &pVgroup->vgId, sizeof(int32_t), &pVgroup->vgId, sizeof(int32_t));
14,530✔
3859
    }
3860

3861
  _OUT:
14,530✔
3862
    mndReleaseDb(pMnode, pDb);
14,530✔
3863
    sdbRelease(pSdb, pVgroup);
14,530✔
3864
    sdbCancelFetch(pSdb, pIter);
14,530✔
3865
    break;
14,530✔
3866
  }
3867

3868
  return code;
14,530✔
3869
}
3870

3871
static int32_t mndBalanceVgroup(SMnode *pMnode, SRpcMsg *pReq, SArray *pArray) {
9,497✔
3872
  int32_t   code = -1;
9,497✔
3873
  int32_t   numOfVgroups = 0;
9,497✔
3874
  STrans   *pTrans = NULL;
9,497✔
3875
  SHashObj *pBalancedVgroups = NULL;
9,497✔
3876

3877
  pBalancedVgroups = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
9,497✔
3878
  if (pBalancedVgroups == NULL) goto _OVER;
9,497✔
3879

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

3892
  while (1) {
14,530✔
3893
    taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
23,579✔
3894
    for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
101,793✔
3895
      SDnodeObj *pDnode = taosArrayGet(pArray, i);
78,214✔
3896
      mInfo("dnode:%d, equivalent vnodes:%d others:%d support:%d, score:%f", pDnode->id, pDnode->numOfVnodes,
78,214✔
3897
            pDnode->numOfSupportVnodes, pDnode->numOfOtherNodes, mndGetDnodeScore(pDnode, 0, 1));
3898
    }
3899

3900
    SDnodeObj *pSrc = taosArrayGet(pArray, taosArrayGetSize(pArray) - 1);
23,579✔
3901
    SDnodeObj *pDst = taosArrayGet(pArray, 0);
23,579✔
3902

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

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

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

3934
_OVER:
9,497✔
3935
  taosHashCleanup(pBalancedVgroups);
9,497✔
3936
  mndTransDrop(pTrans);
9,497✔
3937
  TAOS_RETURN(code);
9,497✔
3938
}
3939

3940
static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq) {
10,913✔
3941
  SMnode *pMnode = pReq->info.node;
10,913✔
3942
  int32_t code = -1;
10,913✔
3943
  SArray *pArray = NULL;
10,913✔
3944
  void   *pIter = NULL;
10,913✔
3945
  int64_t curMs = taosGetTimestampMs();
10,913✔
3946
  int64_t tss = taosGetTimestampMs();
10,913✔
3947

3948
  SBalanceVgroupReq req = {0};
10,913✔
3949
  if (tDeserializeSBalanceVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) {
10,913✔
3950
    code = TSDB_CODE_INVALID_MSG;
×
3951
    goto _OVER;
×
3952
  }
3953

3954
  mInfo("start to balance vgroup");
10,913✔
3955
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_BALANCE_VGROUP)) != 0) {
10,913✔
3956
    goto _OVER;
×
3957
  }
3958

3959
  if (sdbGetSize(pMnode->pSdb, SDB_MOUNT) > 0) {
10,913✔
3960
    code = TSDB_CODE_MND_MOUNT_NOT_EMPTY;
×
3961
    goto _OVER;
×
3962
  }
3963

3964
  while (1) {
33,362✔
3965
    SDnodeObj *pDnode = NULL;
44,275✔
3966
    pIter = sdbFetch(pMnode->pSdb, SDB_DNODE, pIter, (void **)&pDnode);
44,275✔
3967
    if (pIter == NULL) break;
44,275✔
3968
    if (!mndIsDnodeOnline(pDnode, curMs)) {
34,778✔
3969
      sdbCancelFetch(pMnode->pSdb, pIter);
1,416✔
3970
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
1,416✔
3971
      mError("failed to balance vgroup since %s, dnode:%d", terrstr(), pDnode->id);
1,416✔
3972
      sdbRelease(pMnode->pSdb, pDnode);
1,416✔
3973
      goto _OVER;
1,416✔
3974
    }
3975

3976
    sdbRelease(pMnode->pSdb, pDnode);
33,362✔
3977
  }
3978

3979
  pArray = mndBuildDnodesArray(pMnode, 0, NULL);
9,497✔
3980
  if (pArray == NULL) {
9,497✔
3981
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3982
    if (terrno != 0) code = terrno;
×
3983
    goto _OVER;
×
3984
  }
3985

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

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

4000
_OVER:
10,913✔
4001
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
10,913✔
4002
    mError("failed to balance vgroup since %s", tstrerror(code));
1,864✔
4003
  }
4004

4005
  taosArrayDestroy(pArray);
10,913✔
4006
  tFreeSBalanceVgroupReq(&req);
10,913✔
4007
  TAOS_RETURN(code);
10,913✔
4008
}
4009

4010
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; }
106,165,881✔
4011

4012
bool mndVgroupInDnode(SVgObj *pVgroup, int32_t dnodeId) {
3,392✔
4013
  for (int i = 0; i < pVgroup->replica; i++) {
8,472✔
4014
    if (pVgroup->vnodeGid[i].dnodeId == dnodeId) return true;
7,200✔
4015
  }
4016
  return false;
1,272✔
4017
}
4018

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

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

4040
  void *pReq = taosMemoryMalloc(contLen);
91,798✔
4041
  if (pReq == NULL) {
91,798✔
4042
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
4043
    return NULL;
×
4044
  }
4045

4046
  SMsgHead *pHead = pReq;
91,798✔
4047
  pHead->contLen = htonl(contLen);
91,798✔
4048
  pHead->vgId = htonl(pVgroup->vgId);
91,798✔
4049

4050
  if (tSerializeSCompactVnodeReq((char *)pReq + sizeof(SMsgHead), contLen, &compactReq) < 0) {
91,798✔
4051
    taosMemoryFree(pReq);
×
4052
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
4053
    return NULL;
×
4054
  }
4055
  *pContLen = contLen;
91,798✔
4056
  return pReq;
91,798✔
4057
}
4058

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

4066
  int32_t contLen = 0;
54,962✔
4067
  void   *pReq =
4068
      mndBuildCompactVnodeReq(pMnode, pDb, pVgroup, &contLen, compactTs, tw, metaOnly, force, type, triggerType);
54,962✔
4069
  if (pReq == NULL) {
54,962✔
4070
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4071
    if (terrno != 0) code = terrno;
×
4072
    TAOS_RETURN(code);
×
4073
  }
4074

4075
  action.pCont = pReq;
54,962✔
4076
  action.contLen = contLen;
54,962✔
4077
  action.msgType = TDMT_VND_COMPACT;
54,962✔
4078

4079
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
54,962✔
4080
    taosMemoryFree(pReq);
×
4081
    TAOS_RETURN(code);
×
4082
  }
4083

4084
  TAOS_RETURN(code);
54,962✔
4085
}
4086

4087
int32_t mndBuildCompactVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t compactTs,
54,962✔
4088
                                    STimeWindow tw, bool metaOnly, bool force, ETsdbOpType type,
4089
                                    ETriggerType triggerType) {
4090
  TAOS_CHECK_RETURN(
54,962✔
4091
      mndAddCompactVnodeAction(pMnode, pTrans, pDb, pVgroup, compactTs, tw, metaOnly, force, type, triggerType));
4092
  return 0;
54,962✔
4093
}
4094

4095
int32_t mndBuildTrimVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t startTs,
36,836✔
4096
                                 STimeWindow tw, ETsdbOpType type, ETriggerType triggerType) {
4097
  int32_t      code = 0;
36,836✔
4098
  STransAction action = {0};
36,836✔
4099
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
36,836✔
4100

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

4110
  action.pCont = pReq;
36,836✔
4111
  action.contLen = contLen;
36,836✔
4112
  action.msgType = TDMT_VND_TRIM;
36,836✔
4113

4114
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
36,836✔
4115
    taosMemoryFree(pReq);
×
4116
    TAOS_RETURN(code);
×
4117
  }
4118

4119
  TAOS_RETURN(code);
36,836✔
4120
}
4121

4122
static int32_t mndProcessSetVgroupKeepVersionReq(SRpcMsg *pReq) {
1,069✔
4123
  SMnode *pMnode = pReq->info.node;
1,069✔
4124
  int32_t code = TSDB_CODE_SUCCESS;
1,069✔
4125
  STrans *pTrans = NULL;
1,069✔
4126
  SVgObj *pVgroup = NULL;
1,069✔
4127

4128
  SMndSetVgroupKeepVersionReq req = {0};
1,069✔
4129
  if (tDeserializeSMndSetVgroupKeepVersionReq(pReq->pCont, pReq->contLen, &req) != 0) {
1,069✔
4130
    code = TSDB_CODE_INVALID_MSG;
×
4131
    goto _OVER;
×
4132
  }
4133

4134
  mInfo("start to set vgroup keep version, vgId:%d, keepVersion:%" PRId64, req.vgId, req.keepVersion);
1,069✔
4135

4136
  // Check permission
4137
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_WRITE_DB)) != 0) {
1,069✔
4138
    goto _OVER;
×
4139
  }
4140

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

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

4157
  mndTransSetSerial(pTrans);
1,069✔
4158
  mInfo("trans:%d, used to set vgroup keep version, vgId:%d keepVersion:%" PRId64, pTrans->id, req.vgId,
1,069✔
4159
        req.keepVersion);
4160

4161
  // Update SVgObj's keepVersion in mnode
4162
  SVgObj newVgroup = {0};
1,069✔
4163
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
1,069✔
4164
  newVgroup.keepVersion = req.keepVersion;
1,069✔
4165
  newVgroup.keepVersionTime = taosGetTimestampMs();
1,069✔
4166

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

4187
  // Prepare message for vnodes
4188
  SVndSetKeepVersionReq vndReq = {.keepVersion = req.keepVersion};
1,069✔
4189
  int32_t               reqLen = tSerializeSVndSetKeepVersionReq(NULL, 0, &vndReq);
1,069✔
4190
  int32_t               contLen = reqLen + sizeof(SMsgHead);
1,069✔
4191

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

4201
    pHead->contLen = htonl(contLen);
3,207✔
4202
    pHead->vgId = htonl(pVgroup->vgId);
3,207✔
4203

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

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

4220
    STransAction action = {0};
3,207✔
4221
    action.epSet = mndGetDnodeEpset(pDnode);
3,207✔
4222
    mndReleaseDnode(pMnode, pDnode);
3,207✔
4223
    action.pCont = pHead;
3,207✔
4224
    action.contLen = contLen;
3,207✔
4225
    action.msgType = TDMT_VND_SET_KEEP_VERSION;
3,207✔
4226
    action.acceptableCode = TSDB_CODE_VND_STOPPED;
3,207✔
4227

4228
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
3,207✔
4229
      taosMemoryFree(pHead);
×
4230
      code = terrno;
×
4231
      mndReleaseVgroup(pMnode, pVgroup);
×
4232
      goto _OVER;
×
4233
    }
4234
  }
4235

4236
  mndReleaseVgroup(pMnode, pVgroup);
1,069✔
4237

4238
  // Prepare and execute transaction
4239
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
1,069✔
4240
    goto _OVER;
×
4241
  }
4242

4243
  code = TSDB_CODE_ACTION_IN_PROGRESS;
1,069✔
4244

4245
_OVER:
1,069✔
4246
  if (pTrans != NULL) mndTransDrop(pTrans);
1,069✔
4247

4248
  return code;
1,069✔
4249
}
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