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

taosdata / TDengine / #4898

26 Dec 2025 09:58AM UTC coverage: 65.061% (-0.7%) from 65.717%
#4898

push

travis-ci

web-flow
feat: support encryption of configuration files, data files and metadata files (#33801)

350 of 1333 new or added lines in 31 files covered. (26.26%)

2796 existing lines in 159 files now uncovered.

184024 of 282850 relevant lines covered (65.06%)

113940470.33 hits per line

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

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

16
#define _DEFAULT_SOURCE
17
#include "mndVgroup.h"
18
#include "audit.h"
19
#include "mndArbGroup.h"
20
#include "mndDb.h"
21
#include "mndDnode.h"
22
#include "mndEncryptAlgr.h"
23
#include "mndMnode.h"
24
#include "mndPrivilege.h"
25
#include "mndShow.h"
26
#include "mndStb.h"
27
#include "mndStream.h"
28
#include "mndTopic.h"
29
#include "mndTrans.h"
30
#include "mndUser.h"
31
#include "tmisce.h"
32

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

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

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

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

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

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

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

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

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

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

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

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

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

131
  terrno = 0;
10,416,600✔
132

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

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

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

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

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

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

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

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

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

209
  terrno = 0;
9,451,571✔
210

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

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

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

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

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

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

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

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

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

301
SVgObj *mndAcquireVgroup(SMnode *pMnode, int32_t vgId) {
119,085,063✔
302
  SSdb   *pSdb = pMnode->pSdb;
119,085,063✔
303
  SVgObj *pVgroup = sdbAcquire(pSdb, SDB_VGROUP, &vgId);
119,085,063✔
304
  if (pVgroup == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
119,085,063✔
305
    terrno = TSDB_CODE_MND_VGROUP_NOT_EXIST;
882,788✔
306
  }
307
  return pVgroup;
119,085,063✔
308
}
309

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

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

369
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
6,524,549✔
370
    SReplica *pReplica = NULL;
3,783,333✔
371

372
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,783,333✔
373
      pReplica = &createReq.replicas[createReq.replica];
3,679,187✔
374
    } else {
375
      pReplica = &createReq.learnerReplicas[createReq.learnerReplica];
104,146✔
376
    }
377

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

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

389
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,783,333✔
390
      if (pDnode->id == pVgid->dnodeId) {
3,679,187✔
391
        createReq.selfIndex = createReq.replica;
2,637,070✔
392
      }
393
    } else {
394
      if (pDnode->id == pVgid->dnodeId) {
104,146✔
395
        createReq.learnerSelfIndex = createReq.learnerReplica;
104,146✔
396
      }
397
    }
398

399
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
3,783,333✔
400
      createReq.replica++;
3,679,187✔
401
    } else {
402
      createReq.learnerReplica++;
104,146✔
403
    }
404
  }
405

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

411
  createReq.changeVersion = pVgroup->syncConfChangeVer;
2,741,216✔
412

413
  mInfo(
2,741,216✔
414
      "vgId:%d, build create vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
415
      "changeVersion:%d",
416
      createReq.vgId, createReq.replica, createReq.selfIndex, createReq.learnerReplica, createReq.learnerSelfIndex,
417
      createReq.strict, createReq.changeVersion);
418
  for (int32_t i = 0; i < createReq.replica; ++i) {
6,420,403✔
419
    mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.replicas[i].fqdn, createReq.replicas[i].port);
3,679,187✔
420
  }
421
  for (int32_t i = 0; i < createReq.learnerReplica; ++i) {
2,845,362✔
422
    mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.learnerReplicas[i].fqdn,
104,146✔
423
          createReq.learnerReplicas[i].port);
424
  }
425

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

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

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

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

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

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

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

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

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

512
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
3,231,445✔
513
    SReplica *pReplica = NULL;
2,441,594✔
514

515
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
2,441,594✔
516
      pReplica = &alterReq.replicas[alterReq.replica];
2,250,076✔
517
      alterReq.replica++;
2,250,076✔
518
    } else {
519
      pReplica = &alterReq.learnerReplicas[alterReq.learnerReplica];
191,518✔
520
      alterReq.learnerReplica++;
191,518✔
521
    }
522

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

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

532
    if (pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER) {
2,441,594✔
533
      if (dnodeId == pVgid->dnodeId) {
2,250,076✔
534
        alterReq.selfIndex = v;
789,851✔
535
      }
536
    } else {
537
      if (dnodeId == pVgid->dnodeId) {
191,518✔
538
        alterReq.learnerSelfIndex = v;
×
539
      }
540
    }
541
  }
542

543
  mInfo(
789,851✔
544
      "vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d "
545
      "changeVersion:%d",
546
      alterReq.vgId, alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica, alterReq.learnerSelfIndex,
547
      alterReq.strict, alterReq.changeVersion);
548
  for (int32_t i = 0; i < alterReq.replica; ++i) {
3,039,927✔
549
    mInfo("vgId:%d, replica:%d ep:%s:%u", alterReq.vgId, i, alterReq.replicas[i].fqdn, alterReq.replicas[i].port);
2,250,076✔
550
  }
551
  for (int32_t i = 0; i < alterReq.learnerReplica; ++i) {
981,369✔
552
    mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", alterReq.vgId, i, alterReq.learnerReplicas[i].fqdn,
191,518✔
553
          alterReq.learnerReplicas[i].port);
554
  }
555

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

766
  if (exceptDnodeId == pDnode->id) {
1,779,970✔
767
    return true;
7,084✔
768
  }
769

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

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

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

797
  if (isMnode) {
1,736,278✔
798
    pDnode->numOfOtherNodes++;
1,235,021✔
799
  }
800

801
  if (online && pDnode->numOfSupportVnodes > 0) {
1,736,278✔
802
    if (taosArrayPush(pArray, pDnode) == NULL) return false;
1,691,570✔
803
  }
804
  return true;
1,736,278✔
805
}
806

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

959
static int32_t mndCompareDnodeVnodes(SDnodeObj *pDnode1, SDnodeObj *pDnode2) {
2,741,807✔
960
  float d1Score = mndGetDnodeScore(pDnode1, 0, 0.9);
2,741,807✔
961
  float d2Score = mndGetDnodeScore(pDnode2, 0, 0.9);
2,741,807✔
962
  if (d1Score == d2Score) {
2,741,807✔
963
    return 0;
912,609✔
964
  }
965
  return d1Score > d2Score ? 1 : -1;
1,829,198✔
966
}
967

968
void mndSortVnodeGid(SVgObj *pVgroup) {
2,372,744✔
969
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
5,057,447✔
970
    for (int32_t j = 0; j < pVgroup->replica - 1 - i; ++j) {
3,148,940✔
971
      if (pVgroup->vnodeGid[j].dnodeId > pVgroup->vnodeGid[j + 1].dnodeId) {
464,237✔
972
        TSWAP(pVgroup->vnodeGid[j], pVgroup->vnodeGid[j + 1]);
207,223✔
973
      }
974
    }
975
  }
976
}
2,372,744✔
977

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

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

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

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

1012
    pVgid->dnodeId = pDnode->id;
2,595,056✔
1013
    if (pVgroup->replica == 1) {
2,595,056✔
1014
      pVgid->syncState = TAOS_SYNC_STATE_LEADER;
2,209,633✔
1015
    } else {
1016
      pVgid->syncState = TAOS_SYNC_STATE_FOLLOWER;
385,423✔
1017
    }
1018

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

1024
  mndSortVnodeGid(pVgroup);
2,340,117✔
1025
  return 0;
2,340,117✔
1026
}
1027

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

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

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

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

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

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

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

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

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

1082
  if (maxVgId < 2) maxVgId = 2;
1,088,387✔
1083

1084
  for (uint32_t v = 0; v < pDb->cfg.numOfVgroups; v++) {
3,428,504✔
1085
    SVgObj *pVgroup = &pVgroups[v];
2,344,524✔
1086
    pVgroup->vgId = maxVgId++;
2,344,524✔
1087
    pVgroup->createdTime = taosGetTimestampMs();
2,344,524✔
1088
    pVgroup->updateTime = pVgroups->createdTime;
2,344,524✔
1089
    pVgroup->version = 1;
2,344,524✔
1090
    pVgroup->hashBegin = hashMin + hashInterval * v;
2,344,524✔
1091
    if (v == pDb->cfg.numOfVgroups - 1) {
2,344,524✔
1092
      pVgroup->hashEnd = hashMax;
1,086,174✔
1093
    } else {
1094
      pVgroup->hashEnd = hashMin + hashInterval * (v + 1) - 1;
1,258,350✔
1095
    }
1096

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

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

1107
    allocedVgroups++;
2,340,117✔
1108
  }
1109

1110
  *ppVgroups = pVgroups;
1,083,980✔
1111
  code = 0;
1,083,980✔
1112

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

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

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

1124
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
59,950,364✔
1125
    const SVnodeGid *pVgid = &pVgroup->vnodeGid[v];
33,251,012✔
1126
    SDnodeObj       *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
33,251,012✔
1127
    if (pDnode == NULL) continue;
33,251,012✔
1128

1129
    if (pVgid->syncState == TAOS_SYNC_STATE_LEADER || pVgid->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
33,236,126✔
1130
      epset.inUse = epset.numOfEps;
26,305,384✔
1131
    }
1132

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

1140
  return epset;
26,699,352✔
1141
}
1142

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

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

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

1154
    if (pVgid->syncState == TAOS_SYNC_STATE_LEADER || pVgid->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
527,141✔
1155
      epset.inUse = epset.numOfEps;
444,872✔
1156
    }
1157

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

1164
  mndReleaseVgroup(pMnode, pVgroup);
471,985✔
1165
  return epset;
471,985✔
1166
}
1167

1168
static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
241,746✔
1169
  SMnode *pMnode = pReq->info.node;
241,746✔
1170
  SSdb   *pSdb = pMnode->pSdb;
241,746✔
1171
  int32_t numOfRows = 0;
241,746✔
1172
  SVgObj *pVgroup = NULL;
241,746✔
1173
  int32_t cols = 0;
241,746✔
1174
  int64_t curMs = taosGetTimestampMs();
241,746✔
1175
  int32_t code = 0, lino = 0;
241,746✔
1176

1177
  SDbObj *pDb = NULL;
241,746✔
1178
  if (strlen(pShow->db) > 0) {
241,746✔
1179
    pDb = mndAcquireDb(pMnode, pShow->db);
207,810✔
1180
    if (pDb == NULL) {
207,810✔
1181
      return 0;
×
1182
    }
1183
  }
1184

1185
  while (numOfRows < rows) {
1,337,350✔
1186
    pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
1,337,350✔
1187
    if (pShow->pIter == NULL) break;
1,337,350✔
1188

1189
    if (pDb != NULL && pVgroup->dbUid != pDb->uid) {
1,095,604✔
1190
      sdbRelease(pSdb, pVgroup);
357,365✔
1191
      continue;
357,365✔
1192
    }
1193

1194
    cols = 0;
738,239✔
1195
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1196
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->vgId, false, pVgroup, pShow->pIter, _OVER);
738,239✔
1197

1198
    SName name = {0};
738,239✔
1199
    char  db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
738,239✔
1200
    code = tNameFromString(&name, pVgroup->dbName, T_NAME_ACCT | T_NAME_DB);
738,239✔
1201
    if (code != 0) {
738,239✔
1202
      mError("vgId:%d, failed to set dbName, since %s", pVgroup->vgId, tstrerror(code));
×
1203
      sdbRelease(pSdb, pVgroup);
×
1204
      sdbCancelFetch(pSdb, pShow->pIter);
×
1205
      return code;
×
1206
    }
1207
    (void)tNameGetDbName(&name, varDataVal(db));
738,239✔
1208
    varDataSetLen(db, strlen(varDataVal(db)));
738,239✔
1209

1210
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1211
    COL_DATA_SET_VAL_GOTO((const char *)db, false, pVgroup, pShow->pIter, _OVER);
738,239✔
1212

1213
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1214
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->numOfTables, false, pVgroup, pShow->pIter, _OVER);
738,239✔
1215

1216
    bool isReady = false;
738,239✔
1217
    bool isLeaderRestored = false;
738,239✔
1218
    bool hasFollowerRestored = false;
738,239✔
1219
    ESyncState leaderState = TAOS_SYNC_STATE_OFFLINE;
738,239✔
1220
    // default 3 replica, add 1 replica if move vnode
1221
    for (int32_t i = 0; i < 4; ++i) {
3,691,195✔
1222
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,952,956✔
1223
      if (i < pVgroup->replica) {
2,952,956✔
1224
        int16_t dnodeId = (int16_t)pVgroup->vnodeGid[i].dnodeId;
1,538,068✔
1225
        COL_DATA_SET_VAL_GOTO((const char *)&dnodeId, false, pVgroup, pShow->pIter, _OVER);
1,538,068✔
1226

1227
        bool       exist = false;
1,538,068✔
1228
        bool       online = false;
1,538,068✔
1229
        SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId);
1,538,068✔
1230
        if (pDnode != NULL) {
1,538,068✔
1231
          exist = true;
1,538,068✔
1232
          online = mndIsDnodeOnline(pDnode, curMs);
1,538,068✔
1233
          mndReleaseDnode(pMnode, pDnode);
1,538,068✔
1234
        }
1235

1236
        char buf1[20] = {0};
1,538,068✔
1237
        char role[20] = "offline";
1,538,068✔
1238
        if (!exist) {
1,538,068✔
1239
          tstrncpy(role, "dropping", sizeof(role));
×
1240
        } else if (online) {
1,538,068✔
1241
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER ||
1,520,269✔
1242
              pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
949,312✔
1243
            if (pVgroup->vnodeGid[i].syncRestore) {
570,957✔
1244
              isLeaderRestored = true;
494,247✔
1245
            }
1246
          } else if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_FOLLOWER) {
949,312✔
1247
            if (pVgroup->vnodeGid[i].syncRestore) {
797,962✔
1248
              hasFollowerRestored = true;
437,465✔
1249
            }
1250
          }
1251
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER ||
1,520,269✔
1252
              pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER)
949,312✔
1253
            leaderState = pVgroup->vnodeGid[i].syncState;
570,957✔
1254
          snprintf(role, sizeof(role), "%s", syncStr(pVgroup->vnodeGid[i].syncState));
1,520,269✔
1255
          /*
1256
          mInfo("db:%s, learner progress:%d", pDb->name, pVgroup->vnodeGid[i].learnerProgress);
1257

1258
          if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEARNER) {
1259
            if(pVgroup->vnodeGid[i].learnerProgress < 0){
1260
              snprintf(role, sizeof(role), "%s-",
1261
                syncStr(pVgroup->vnodeGid[i].syncState));
1262

1263
            }
1264
            else if(pVgroup->vnodeGid[i].learnerProgress >= 100){
1265
              snprintf(role, sizeof(role), "%s--",
1266
                syncStr(pVgroup->vnodeGid[i].syncState));
1267
            }
1268
            else{
1269
              snprintf(role, sizeof(role), "%s%d",
1270
                syncStr(pVgroup->vnodeGid[i].syncState), pVgroup->vnodeGid[i].learnerProgress);
1271
            }
1272
          }
1273
          else{
1274
            snprintf(role, sizeof(role), "%s%s", syncStr(pVgroup->vnodeGid[i].syncState), star);
1275
          }
1276
          */
1277
        } else {
1278
        }
1279
        STR_WITH_MAXSIZE_TO_VARSTR(buf1, role, pShow->pMeta->pSchemas[cols].bytes);
1,538,068✔
1280

1281
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,538,068✔
1282
        COL_DATA_SET_VAL_GOTO((const char *)buf1, false, pVgroup, pShow->pIter, _OVER);
1,538,068✔
1283

1284
        char applyStr[TSDB_SYNC_APPLY_COMMIT_LEN + 1] = {0};
1,538,068✔
1285
        char buf[TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE + 1] = {0};
1,538,068✔
1286
        snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64, pVgroup->vnodeGid[i].syncAppliedIndex,
1,538,068✔
1287
                 pVgroup->vnodeGid[i].syncCommitIndex);
1,538,068✔
1288
        STR_WITH_MAXSIZE_TO_VARSTR(buf, applyStr, pShow->pMeta->pSchemas[cols].bytes);
1,538,068✔
1289

1290
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,538,068✔
1291
        COL_DATA_SET_VAL_GOTO((const char *)&buf, false, pVgroup, pShow->pIter, _OVER);
1,538,068✔
1292
      } else {
1293
        colDataSetNULL(pColInfo, numOfRows);
1,414,888✔
1294
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,414,888✔
1295
        colDataSetNULL(pColInfo, numOfRows);
1,414,888✔
1296
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1,414,888✔
1297
        colDataSetNULL(pColInfo, numOfRows);
1,414,888✔
1298
      }
1299
    }
1300

1301
    if (pVgroup->replica >= 3) {
738,239✔
1302
      if (isLeaderRestored && hasFollowerRestored) isReady = true;
318,414✔
1303
    } else if (pVgroup->replica == 2) {
419,825✔
1304
      if (leaderState == TAOS_SYNC_STATE_LEADER) {
163,001✔
1305
        if (isLeaderRestored && hasFollowerRestored) isReady = true;
81,349✔
1306
      } else if (leaderState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
81,652✔
1307
        if (isLeaderRestored) isReady = true;
×
1308
      }
1309
    } else {
1310
      if (isLeaderRestored) isReady = true;
256,824✔
1311
    }
1312
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1313
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&isReady, false);
738,239✔
1314
    if (code != 0) {
738,239✔
1315
      mError("vgId:%d, failed to set is_ready, since %s", pVgroup->vgId, tstrerror(code));
×
1316
      return code;
×
1317
    }
1318

1319
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1320
    int32_t cacheUsage = (int32_t)pVgroup->cacheUsage;
738,239✔
1321
    COL_DATA_SET_VAL_GOTO((const char *)&cacheUsage, false, pVgroup, pShow->pIter, _OVER);
738,239✔
1322

1323
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1324
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->numOfCachedTables, false, pVgroup, pShow->pIter, _OVER);
738,239✔
1325

1326
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1327
    COL_DATA_SET_VAL_GOTO((const char *)&pVgroup->isTsma, false, pVgroup, pShow->pIter, _OVER);
738,239✔
1328

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

1332
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1333
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pVgroup->keepVersion, false);
738,239✔
1334
    if (code != 0) {
738,239✔
1335
      mError("vgId:%d, failed to set keepVersion, since %s", pVgroup->vgId, tstrerror(code));
×
1336
      return code;
×
1337
    }
1338

1339
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
738,239✔
1340
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pVgroup->keepVersionTime, false);
738,239✔
1341
    if (code != 0) {
738,239✔
1342
      mError("vgId:%d, failed to set keepVersionTime, since %s", pVgroup->vgId, tstrerror(code));
×
1343
      return code;
×
1344
    }
1345

1346
    numOfRows++;
738,239✔
1347
    sdbRelease(pSdb, pVgroup);
738,239✔
1348
  }
1349
_OVER:
241,746✔
1350
  if (pDb != NULL) {
241,746✔
1351
    mndReleaseDb(pMnode, pDb);
207,810✔
1352
  }
1353
  if (code != 0) {
241,746✔
1354
    mError("failed to retrieve vgroup info at line %d since %s", lino, tstrerror(code));
×
1355
    TAOS_RETURN(code);
×
1356
  }
1357

1358
  pShow->numOfRows += numOfRows;
241,746✔
1359
  return numOfRows;
241,746✔
1360
}
1361

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

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

1372
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
24,998,755✔
1373
    if (pVgroup->vnodeGid[v].dnodeId == dnodeId) {
15,620,084✔
1374
      (*pNumOfVnodes)++;
6,093,515✔
1375
    }
1376
  }
1377

1378
  return true;
9,378,671✔
1379
}
1380

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

1387
int64_t mndGetVgroupMemory(SMnode *pMnode, SDbObj *pDbInput, SVgObj *pVgroup) {
7,657,172✔
1388
  SDbObj *pDb = pDbInput;
7,657,172✔
1389
  if (pDbInput == NULL) {
7,657,172✔
1390
    pDb = mndAcquireDb(pMnode, pVgroup->dbName);
4,434,136✔
1391
  }
1392

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

1406
  if (pDbInput == NULL) {
7,657,172✔
1407
    mndReleaseDb(pMnode, pDb);
4,434,136✔
1408
  }
1409
  return vgroupMemroy;
7,657,172✔
1410
}
1411

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

1417
  for (int32_t v = 0; v < pVgroup->replica; ++v) {
14,425,849✔
1418
    if (pVgroup->vnodeGid[v].dnodeId == dnodeId) {
8,262,734✔
1419
      *pVnodeMemory += mndGetVgroupMemory(pMnode, NULL, pVgroup);
4,287,994✔
1420
    }
1421
  }
1422

1423
  return true;
6,163,115✔
1424
}
1425

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

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

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

1447
static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
12,421✔
1448
  SMnode *pMnode = pReq->info.node;
12,421✔
1449
  SSdb   *pSdb = pMnode->pSdb;
12,421✔
1450
  int32_t numOfRows = 0;
12,421✔
1451
  SVgObj *pVgroup = NULL;
12,421✔
1452
  int32_t cols = 0;
12,421✔
1453
  int64_t curMs = taosGetTimestampMs();
12,421✔
1454
  int32_t code = 0;
12,421✔
1455

1456
  while (numOfRows < rows - TSDB_MAX_REPLICA) {
37,148✔
1457
    pShow->pIter = sdbFetch(pSdb, SDB_VGROUP, pShow->pIter, (void **)&pVgroup);
37,148✔
1458
    if (pShow->pIter == NULL) break;
37,148✔
1459

1460
    for (int32_t i = 0; i < pVgroup->replica && numOfRows < rows; ++i) {
71,539✔
1461
      SVnodeGid       *pGid = &pVgroup->vnodeGid[i];
46,812✔
1462
      SColumnInfoData *pColInfo = NULL;
46,812✔
1463
      cols = 0;
46,812✔
1464

1465
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1466
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->dnodeId, false);
46,812✔
1467
      if (code != 0) {
46,812✔
1468
        mError("vgId:%d, failed to set dnodeId, since %s", pVgroup->vgId, tstrerror(code));
×
1469
        return code;
×
1470
      }
1471
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1472
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pVgroup->vgId, false);
46,812✔
1473
      if (code != 0) {
46,812✔
1474
        mError("vgId:%d, failed to set vgId, since %s", pVgroup->vgId, tstrerror(code));
×
1475
        return code;
×
1476
      }
1477

1478
      // db_name
1479
      const char *dbname = mndGetDbStr(pVgroup->dbName);
46,812✔
1480
      char        b1[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
46,812✔
1481
      if (dbname != NULL) {
46,812✔
1482
        STR_WITH_MAXSIZE_TO_VARSTR(b1, dbname, TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE);
46,812✔
1483
      } else {
1484
        STR_WITH_MAXSIZE_TO_VARSTR(b1, "NULL", TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE);
×
1485
      }
1486
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1487
      code = colDataSetVal(pColInfo, numOfRows, (const char *)b1, false);
46,812✔
1488
      if (code != 0) {
46,812✔
1489
        mError("vgId:%d, failed to set dbName, since %s", pVgroup->vgId, tstrerror(code));
×
1490
        return code;
×
1491
      }
1492

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

1501
      char       buf[20] = {0};
46,812✔
1502
      ESyncState syncState = (isDnodeOnline) ? pGid->syncState : TAOS_SYNC_STATE_OFFLINE;
46,812✔
1503
      STR_TO_VARSTR(buf, syncStr(syncState));
46,812✔
1504
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1505
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
46,812✔
1506
      if (code != 0) {
46,812✔
1507
        mError("vgId:%d, failed to set syncState, since %s", pVgroup->vgId, tstrerror(code));
×
1508
        return code;
×
1509
      }
1510

1511
      int64_t roleTimeMs = (isDnodeOnline) ? pGid->roleTimeMs : 0;
46,812✔
1512
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1513
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&roleTimeMs, false);
46,812✔
1514
      if (code != 0) {
46,812✔
1515
        mError("vgId:%d, failed to set roleTimeMs, since %s", pVgroup->vgId, tstrerror(code));
×
1516
        return code;
×
1517
      }
1518

1519
      int64_t startTimeMs = (isDnodeOnline) ? pGid->startTimeMs : 0;
46,812✔
1520
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1521
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&startTimeMs, false);
46,812✔
1522
      if (code != 0) {
46,812✔
1523
        mError("vgId:%d, failed to set startTimeMs, since %s", pVgroup->vgId, tstrerror(code));
×
1524
        return code;
×
1525
      }
1526

1527
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1528
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->syncRestore, false);
46,812✔
1529
      if (code != 0) {
46,812✔
1530
        mError("vgId:%d, failed to set syncRestore, since %s", pVgroup->vgId, tstrerror(code));
×
1531
        return code;
×
1532
      }
1533

1534
      int64_t unappliedCount = pGid->syncCommitIndex - pGid->syncAppliedIndex;
46,812✔
1535
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1536
      char restoreStr[20] = {0};
46,812✔
1537
      if (unappliedCount > 0) {
46,812✔
1538
        calculateRstoreFinishTime(pGid->appliedRate, unappliedCount, restoreStr, sizeof(restoreStr));
538✔
1539
      }
1540
      STR_TO_VARSTR(buf, restoreStr);
46,812✔
1541
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&buf, false);
46,812✔
1542
      if (code != 0) {
46,812✔
1543
        mError("vgId:%d, failed to set syncRestore finish time, since %s", pVgroup->vgId, tstrerror(code));
×
1544
        return code;
×
1545
      }
1546

1547
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1548
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&unappliedCount, false);
46,812✔
1549
      if (code != 0) {
46,812✔
1550
        mError("vgId:%d, failed to set syncRestore, since %s", pVgroup->vgId, tstrerror(code));
×
1551
        return code;
×
1552
      }
1553

1554
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1555
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->bufferSegmentUsed, false);
46,812✔
1556
      if (code != 0) {
46,812✔
1557
        mError("vgId:%d, failed to set buffer segment used, since %s", pVgroup->vgId, tstrerror(code));
×
1558
        return code;
×
1559
      }
1560

1561
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
46,812✔
1562
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->bufferSegmentSize, false);
46,812✔
1563
      if (code != 0) {
46,812✔
1564
        mError("vgId:%d, failed to set buffer segment size, since %s", pVgroup->vgId, tstrerror(code));
×
1565
        return code;
×
1566
      }
1567

1568
      numOfRows++;
46,812✔
1569
      sdbRelease(pSdb, pDnode);
46,812✔
1570
    }
1571

1572
    sdbRelease(pSdb, pVgroup);
24,727✔
1573
  }
1574

1575
  pShow->numOfRows += numOfRows;
12,421✔
1576
  return numOfRows;
12,421✔
1577
}
1578

1579
static void mndCancelGetNextVnode(SMnode *pMnode, void *pIter) {
×
1580
  SSdb *pSdb = pMnode->pSdb;
×
1581
  sdbCancelFetchByType(pSdb, pIter, SDB_VGROUP);
×
1582
}
×
1583

1584
static int32_t mndAddVnodeToVgroup(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray) {
83,339✔
1585
  int32_t code = 0;
83,339✔
1586
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
83,339✔
1587
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
331,645✔
1588
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
248,306✔
1589
    mInfo("trans:%d, dnode:%d, equivalent vnodes:%d others:%d", pTrans->id, pDnode->id, pDnode->numOfVnodes,
248,306✔
1590
          pDnode->numOfOtherNodes);
1591
  }
1592

1593
  SVnodeGid *pVgid = &pVgroup->vnodeGid[pVgroup->replica];
83,339✔
1594
  for (int32_t d = 0; d < taosArrayGetSize(pArray); ++d) {
105,159✔
1595
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
101,573✔
1596

1597
    bool used = false;
101,573✔
1598
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
237,152✔
1599
      if (pDnode->id == pVgroup->vnodeGid[vn].dnodeId) {
157,399✔
1600
        used = true;
21,820✔
1601
        break;
21,820✔
1602
      }
1603
    }
1604
    if (used) continue;
101,573✔
1605

1606
    if (pDnode == NULL) {
79,753✔
1607
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_DNODES);
×
1608
    }
1609
    if (pDnode->numOfVnodes >= pDnode->numOfSupportVnodes) {
79,753✔
1610
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_VNODES);
×
1611
    }
1612

1613
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
79,753✔
1614
    if (pDnode->memAvail - vgMem - pDnode->memUsed <= 0) {
79,753✔
1615
      mError("trans:%d, db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
1616
             pTrans->id, pVgroup->dbName, pVgroup->vgId, vgMem, pDnode->id, pDnode->memAvail, pDnode->memUsed);
1617
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
1618
    } else {
1619
      pDnode->memUsed += vgMem;
79,753✔
1620
    }
1621

1622
    pVgid->dnodeId = pDnode->id;
79,753✔
1623
    pVgid->syncState = TAOS_SYNC_STATE_OFFLINE;
79,753✔
1624
    mInfo("trans:%id, db:%s, vgId:%d, vn:%d is added, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
79,753✔
1625
          pTrans->id, pVgroup->dbName, pVgroup->vgId, pVgroup->replica, vgMem, pVgid->dnodeId, pDnode->memAvail,
1626
          pDnode->memUsed);
1627

1628
    pVgroup->replica++;
79,753✔
1629
    pDnode->numOfVnodes++;
79,753✔
1630

1631
    SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
79,753✔
1632
    if (pVgRaw == NULL) {
79,753✔
1633
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1634
      if (terrno != 0) code = terrno;
×
1635
      TAOS_RETURN(code);
×
1636
    }
1637
    if ((code = mndTransAppendGroupRedolog(pTrans, pVgRaw, pVgroup->vgId)) != 0) {
79,753✔
1638
      sdbFreeRaw(pVgRaw);
×
1639
      TAOS_RETURN(code);
×
1640
    }
1641
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
79,753✔
1642
    if (code != 0) {
79,753✔
1643
      mError("trans:%d, vgId:%d, failed to set raw status since %s at line:%d", pTrans->id, pVgroup->vgId,
×
1644
             tstrerror(code), __LINE__);
1645
    }
1646
    TAOS_RETURN(code);
79,753✔
1647
  }
1648

1649
  code = TSDB_CODE_MND_NO_ENOUGH_DNODES;
3,586✔
1650
  mError("trans:%d, db:%s, failed to add vnode to vgId:%d since %s", pTrans->id, pVgroup->dbName, pVgroup->vgId,
3,586✔
1651
         tstrerror(code));
1652
  TAOS_RETURN(code);
3,586✔
1653
}
1654

1655
static int32_t mndRemoveVnodeFromVgroup(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray,
16,772✔
1656
                                        SVnodeGid *pDelVgid) {
1657
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
16,772✔
1658
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
65,297✔
1659
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
48,525✔
1660
    mInfo("trans:%d, dnode:%d, equivalent vnodes:%d others:%d", pTrans->id, pDnode->id, pDnode->numOfVnodes,
48,525✔
1661
          pDnode->numOfOtherNodes);
1662
  }
1663

1664
  int32_t code = -1;
16,772✔
1665
  for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
19,494✔
1666
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
19,494✔
1667

1668
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
38,095✔
1669
      SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
35,373✔
1670
      if (pVgid->dnodeId == pDnode->id) {
35,373✔
1671
        int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
16,772✔
1672
        pDnode->memUsed -= vgMem;
16,772✔
1673
        mInfo("trans:%d, db:%s, vgId:%d, vn:%d is removed, memory:%" PRId64 ", dnode:%d avail:%" PRId64
16,772✔
1674
              " used:%" PRId64,
1675
              pTrans->id, pVgroup->dbName, pVgroup->vgId, vn, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
1676
        pDnode->numOfVnodes--;
16,772✔
1677
        pVgroup->replica--;
16,772✔
1678
        *pDelVgid = *pVgid;
16,772✔
1679
        *pVgid = pVgroup->vnodeGid[pVgroup->replica];
16,772✔
1680
        memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
16,772✔
1681
        code = 0;
16,772✔
1682
        goto _OVER;
16,772✔
1683
      }
1684
    }
1685
  }
1686

UNCOV
1687
_OVER:
×
1688
  if (code != 0) {
16,772✔
UNCOV
1689
    code = TSDB_CODE_APP_ERROR;
×
UNCOV
1690
    mError("trans:%d, db:%s, failed to remove vnode from vgId:%d since %s", pTrans->id, pVgroup->dbName, pVgroup->vgId,
×
1691
           tstrerror(code));
UNCOV
1692
    TAOS_RETURN(code);
×
1693
  }
1694

1695
  for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
46,886✔
1696
    SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
30,114✔
1697
    mInfo("trans:%d, db:%s, vgId:%d, vn:%d dnode:%d is reserved", pTrans->id, pVgroup->dbName, pVgroup->vgId, vn,
30,114✔
1698
          pVgid->dnodeId);
1699
  }
1700

1701
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
16,772✔
1702
  if (pVgRaw == NULL) {
16,772✔
1703
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1704
    if (terrno != 0) code = terrno;
×
1705
    TAOS_RETURN(code);
×
1706
  }
1707
  if (mndTransAppendGroupRedolog(pTrans, pVgRaw, pVgroup->vgId) != 0) {
16,772✔
1708
    sdbFreeRaw(pVgRaw);
×
1709
    TAOS_RETURN(code);
×
1710
  }
1711
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
16,772✔
1712
  if (code != 0) {
16,772✔
1713
    mError("trans:%d, vgId:%d, failed to set raw status since %s at line:%d", pTrans->id, pVgroup->vgId,
×
1714
           tstrerror(code), __LINE__);
1715
  }
1716

1717
  TAOS_RETURN(code);
16,772✔
1718
}
1719

1720
static int32_t mndRemoveVnodeFromVgroupWithoutSave(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SArray *pArray,
×
1721
                                                   SVnodeGid *pDelVgid) {
1722
  taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
×
1723
  for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
×
1724
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
×
1725
    mInfo("dnode:%d, equivalent vnodes:%d others:%d", pDnode->id, pDnode->numOfVnodes, pDnode->numOfOtherNodes);
×
1726
  }
1727

1728
  int32_t code = -1;
×
1729
  for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
×
1730
    SDnodeObj *pDnode = taosArrayGet(pArray, d);
×
1731

1732
    for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
×
1733
      SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
×
1734
      if (pVgid->dnodeId == pDnode->id) {
×
1735
        int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
×
1736
        pDnode->memUsed -= vgMem;
×
1737
        mInfo("db:%s, vgId:%d, vn:%d is removed, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64,
×
1738
              pVgroup->dbName, pVgroup->vgId, vn, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed);
1739
        pDnode->numOfVnodes--;
×
1740
        pVgroup->replica--;
×
1741
        *pDelVgid = *pVgid;
×
1742
        *pVgid = pVgroup->vnodeGid[pVgroup->replica];
×
1743
        memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
×
1744
        code = 0;
×
1745
        goto _OVER;
×
1746
      }
1747
    }
1748
  }
1749

1750
_OVER:
×
1751
  if (code != 0) {
×
1752
    code = TSDB_CODE_APP_ERROR;
×
1753
    mError("db:%s, failed to remove vnode from vgId:%d since %s", pVgroup->dbName, pVgroup->vgId, tstrerror(code));
×
1754
    TAOS_RETURN(code);
×
1755
  }
1756

1757
  for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
×
1758
    SVnodeGid *pVgid = &pVgroup->vnodeGid[vn];
×
1759
    mInfo("db:%s, vgId:%d, vn:%d dnode:%d is reserved", pVgroup->dbName, pVgroup->vgId, vn, pVgid->dnodeId);
×
1760
  }
1761

1762
  TAOS_RETURN(code);
×
1763
}
1764

1765
int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid) {
2,738,916✔
1766
  int32_t      code = 0;
2,738,916✔
1767
  STransAction action = {0};
2,738,916✔
1768

1769
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
2,738,916✔
1770
  if (pDnode == NULL) return -1;
2,738,916✔
1771
  action.epSet = mndGetDnodeEpset(pDnode);
2,738,916✔
1772
  mndReleaseDnode(pMnode, pDnode);
2,738,916✔
1773

1774
  int32_t contLen = 0;
2,738,916✔
1775
  void   *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
2,738,916✔
1776
  if (pReq == NULL) return -1;
2,738,916✔
1777

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

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

1789
  TAOS_RETURN(code);
2,738,916✔
1790
}
1791

1792
int32_t mndRestoreAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
2,300✔
1793
                                       SDnodeObj *pDnode) {
1794
  int32_t      code = 0;
2,300✔
1795
  STransAction action = {0};
2,300✔
1796

1797
  action.epSet = mndGetDnodeEpset(pDnode);
2,300✔
1798

1799
  int32_t contLen = 0;
2,300✔
1800
  void   *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
2,300✔
1801
  if (pReq == NULL) {
2,300✔
1802
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1803
    if (terrno != 0) code = terrno;
×
1804
    TAOS_RETURN(code);
×
1805
  }
1806

1807
  action.pCont = pReq;
2,300✔
1808
  action.contLen = contLen;
2,300✔
1809
  action.msgType = TDMT_DND_CREATE_VNODE;
2,300✔
1810
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
2,300✔
1811
  action.groupId = pVgroup->vgId;
2,300✔
1812

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

1818
  TAOS_RETURN(code);
2,300✔
1819
}
1820

1821
int32_t mndAddAlterVnodeConfirmAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
281,753✔
1822
  int32_t      code = 0;
281,753✔
1823
  STransAction action = {0};
281,753✔
1824
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
281,753✔
1825

1826
  mInfo("trans:%d, vgId:%d, build alter vnode confirm req", pTrans->id, pVgroup->vgId);
281,753✔
1827
  int32_t   contLen = sizeof(SMsgHead);
281,753✔
1828
  SMsgHead *pHead = taosMemoryMalloc(contLen);
281,753✔
1829
  if (pHead == NULL) {
281,753✔
1830
    TAOS_RETURN(terrno);
×
1831
  }
1832

1833
  pHead->contLen = htonl(contLen);
281,753✔
1834
  pHead->vgId = htonl(pVgroup->vgId);
281,753✔
1835

1836
  action.pCont = pHead;
281,753✔
1837
  action.contLen = contLen;
281,753✔
1838
  action.msgType = TDMT_VND_ALTER_CONFIRM;
281,753✔
1839
  // incorrect redirect result will cause this erro
1840
  action.retryCode = TSDB_CODE_VND_INVALID_VGROUP_ID;
281,753✔
1841
  action.groupId = pVgroup->vgId;
281,753✔
1842

1843
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
281,753✔
1844
    taosMemoryFree(pHead);
×
1845
    TAOS_RETURN(code);
×
1846
  }
1847

1848
  TAOS_RETURN(code);
281,753✔
1849
}
1850

1851
int32_t mndAddChangeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pOldVgroup, SVgObj *pNewVgroup,
×
1852
                                 int32_t dnodeId) {
1853
  int32_t      code = 0;
×
1854
  STransAction action = {0};
×
1855
  action.epSet = mndGetVgroupEpset(pMnode, pNewVgroup);
×
1856

1857
  int32_t contLen = 0;
×
1858
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pNewVgroup, dnodeId, &contLen);
×
1859
  if (pReq == NULL) {
×
1860
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1861
    if (terrno != 0) code = terrno;
×
1862
    TAOS_RETURN(code);
×
1863
  }
1864

1865
  int32_t totallen = contLen + sizeof(SMsgHead);
×
1866

1867
  SMsgHead *pHead = taosMemoryMalloc(totallen);
×
1868
  if (pHead == NULL) {
×
1869
    taosMemoryFree(pReq);
×
1870
    TAOS_RETURN(terrno);
×
1871
  }
1872

1873
  pHead->contLen = htonl(totallen);
×
1874
  pHead->vgId = htonl(pNewVgroup->vgId);
×
1875

1876
  memcpy((void *)(pHead + 1), pReq, contLen);
×
1877
  taosMemoryFree(pReq);
×
1878

1879
  action.pCont = pHead;
×
1880
  action.contLen = totallen;
×
1881
  action.msgType = TDMT_SYNC_CONFIG_CHANGE;
×
1882

1883
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
1884
    taosMemoryFree(pHead);
×
1885
    TAOS_RETURN(code);
×
1886
  }
1887

1888
  TAOS_RETURN(code);
×
1889
}
1890

1891
static int32_t mndAddAlterVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, int32_t srcVgId, SVgObj *pVgroup) {
32,476✔
1892
  int32_t      code = 0;
32,476✔
1893
  STransAction action = {0};
32,476✔
1894
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
32,476✔
1895

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

1904
  action.pCont = pReq;
32,476✔
1905
  action.contLen = contLen;
32,476✔
1906
  action.msgType = TDMT_VND_ALTER_HASHRANGE;
32,476✔
1907
  action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
32,476✔
1908

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

1914
  mInfo("trans:%d, add alter vnode hash range action for from vgId:%d to vgId:%d", pTrans->id, srcVgId, pVgroup->vgId);
32,476✔
1915
  TAOS_RETURN(code);
32,476✔
1916
}
1917

1918
int32_t mndAddAlterVnodeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
197,490✔
1919
  int32_t      code = 0;
197,490✔
1920
  STransAction action = {0};
197,490✔
1921
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
197,490✔
1922

1923
  int32_t contLen = 0;
197,490✔
1924
  void   *pReq = mndBuildAlterVnodeConfigReq(pMnode, pDb, pVgroup, &contLen);
197,490✔
1925
  if (pReq == NULL) {
197,490✔
1926
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1927
    if (terrno != 0) code = terrno;
×
1928
    TAOS_RETURN(code);
×
1929
  }
1930

1931
  action.pCont = pReq;
197,490✔
1932
  action.contLen = contLen;
197,490✔
1933
  action.msgType = TDMT_VND_ALTER_CONFIG;
197,490✔
1934
  action.groupId = pVgroup->vgId;
197,490✔
1935

1936
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
197,490✔
1937
    taosMemoryFree(pReq);
×
1938
    TAOS_RETURN(code);
×
1939
  }
1940

1941
  TAOS_RETURN(code);
197,490✔
1942
}
1943

1944
int32_t mndAddNewVgPrepareAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVg) {
2,373,625✔
1945
  int32_t  code = 0;
2,373,625✔
1946
  SSdbRaw *pRaw = mndVgroupActionEncode(pVg);
2,373,625✔
1947
  if (pRaw == NULL) {
2,373,625✔
1948
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1949
    if (terrno != 0) code = terrno;
×
1950
    goto _err;
×
1951
  }
1952

1953
  TAOS_CHECK_GOTO(mndTransAppendPrepareLog(pTrans, pRaw), NULL, _err);
2,373,625✔
1954
  if (sdbSetRawStatus(pRaw, SDB_STATUS_CREATING) != 0) {
2,373,625✔
1955
    mError("vgId:%d, failed to set raw status at line:%d", pVg->vgId, __LINE__);
×
1956
  }
1957
  if (code != 0) {
2,373,625✔
1958
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVg->vgId, tstrerror(code), __LINE__);
×
1959
    TAOS_RETURN(code);
×
1960
  }
1961
  pRaw = NULL;
2,373,625✔
1962
  TAOS_RETURN(code);
2,373,625✔
1963

1964
_err:
×
1965
  sdbFreeRaw(pRaw);
×
1966
  TAOS_RETURN(code);
×
1967
}
1968

1969
int32_t mndAddAlterVnodeReplicaAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
685,705✔
1970
  int32_t    code = 0;
685,705✔
1971
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
685,705✔
1972
  if (pDnode == NULL) {
685,705✔
1973
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1974
    if (terrno != 0) code = terrno;
×
1975
    TAOS_RETURN(code);
×
1976
  }
1977

1978
  STransAction action = {0};
685,705✔
1979
  action.epSet = mndGetDnodeEpset(pDnode);
685,705✔
1980
  mndReleaseDnode(pMnode, pDnode);
685,705✔
1981

1982
  int32_t contLen = 0;
685,705✔
1983
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
685,705✔
1984
  if (pReq == NULL) {
685,705✔
1985
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1986
    if (terrno != 0) code = terrno;
×
1987
    TAOS_RETURN(code);
×
1988
  }
1989

1990
  action.pCont = pReq;
685,705✔
1991
  action.contLen = contLen;
685,705✔
1992
  action.msgType = TDMT_VND_ALTER_REPLICA;
685,705✔
1993
  action.groupId = pVgroup->vgId;
685,705✔
1994

1995
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
685,705✔
1996
    taosMemoryFree(pReq);
×
1997
    TAOS_RETURN(code);
×
1998
  }
1999

2000
  TAOS_RETURN(code);
685,705✔
2001
}
2002

2003
int32_t mndAddCheckLearnerCatchupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
×
2004
  int32_t    code = 0;
×
2005
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
×
2006
  if (pDnode == NULL) {
×
2007
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2008
    if (terrno != 0) code = terrno;
×
2009
    TAOS_RETURN(code);
×
2010
  }
2011

2012
  STransAction action = {0};
×
2013
  action.epSet = mndGetDnodeEpset(pDnode);
×
2014
  mndReleaseDnode(pMnode, pDnode);
×
2015

2016
  int32_t contLen = 0;
×
2017
  void   *pReq = mndBuildCheckLearnCatchupReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
×
2018
  if (pReq == NULL) {
×
2019
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2020
    if (terrno != 0) code = terrno;
×
2021
    TAOS_RETURN(code);
×
2022
  }
2023

2024
  action.pCont = pReq;
×
2025
  action.contLen = contLen;
×
2026
  action.msgType = TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP;
×
2027
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
×
2028
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
×
2029

2030
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
2031
    taosMemoryFree(pReq);
×
2032
    TAOS_RETURN(code);
×
2033
  }
2034

2035
  TAOS_RETURN(code);
×
2036
}
2037

2038
int32_t mndAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
101,846✔
2039
  int32_t    code = 0;
101,846✔
2040
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
101,846✔
2041
  if (pDnode == NULL) {
101,846✔
2042
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2043
    if (terrno != 0) code = terrno;
×
2044
    TAOS_RETURN(code);
×
2045
  }
2046

2047
  STransAction action = {0};
101,846✔
2048
  action.epSet = mndGetDnodeEpset(pDnode);
101,846✔
2049
  mndReleaseDnode(pMnode, pDnode);
101,846✔
2050

2051
  int32_t contLen = 0;
101,846✔
2052
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen);
101,846✔
2053
  if (pReq == NULL) {
101,846✔
2054
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2055
    if (terrno != 0) code = terrno;
×
2056
    TAOS_RETURN(code);
×
2057
  }
2058

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

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

2071
  TAOS_RETURN(code);
101,846✔
2072
}
2073

2074
int32_t mndRestoreAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
2,300✔
2075
                                          SDnodeObj *pDnode) {
2076
  int32_t      code = 0;
2,300✔
2077
  STransAction action = {0};
2,300✔
2078
  action.epSet = mndGetDnodeEpset(pDnode);
2,300✔
2079

2080
  int32_t contLen = 0;
2,300✔
2081
  void   *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, pDnode->id, &contLen);
2,300✔
2082
  if (pReq == NULL) {
2,300✔
2083
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2084
    if (terrno != 0) code = terrno;
×
2085
    TAOS_RETURN(code);
×
2086
  }
2087

2088
  action.pCont = pReq;
2,300✔
2089
  action.contLen = contLen;
2,300✔
2090
  action.msgType = TDMT_DND_ALTER_VNODE_TYPE;
2,300✔
2091
  action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
2,300✔
2092
  action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
2,300✔
2093
  action.groupId = pVgroup->vgId;
2,300✔
2094

2095
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2,300✔
2096
    taosMemoryFree(pReq);
×
2097
    TAOS_RETURN(code);
×
2098
  }
2099

2100
  TAOS_RETURN(code);
2,300✔
2101
}
2102

2103
static int32_t mndAddDisableVnodeWriteAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
32,476✔
2104
                                             int32_t dnodeId) {
2105
  int32_t    code = 0;
32,476✔
2106
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
32,476✔
2107
  if (pDnode == NULL) {
32,476✔
2108
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2109
    if (terrno != 0) code = terrno;
×
2110
    TAOS_RETURN(code);
×
2111
  }
2112

2113
  STransAction action = {0};
32,476✔
2114
  action.epSet = mndGetDnodeEpset(pDnode);
32,476✔
2115
  mndReleaseDnode(pMnode, pDnode);
32,476✔
2116

2117
  int32_t contLen = 0;
32,476✔
2118
  void   *pReq = mndBuildDisableVnodeWriteReq(pMnode, pDb, pVgroup->vgId, &contLen);
32,476✔
2119
  if (pReq == NULL) {
32,476✔
2120
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2121
    if (terrno != 0) code = terrno;
×
2122
    TAOS_RETURN(code);
×
2123
  }
2124

2125
  action.pCont = pReq;
32,476✔
2126
  action.contLen = contLen;
32,476✔
2127
  action.msgType = TDMT_VND_DISABLE_WRITE;
32,476✔
2128

2129
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
32,476✔
2130
    taosMemoryFree(pReq);
×
2131
    TAOS_RETURN(code);
×
2132
  }
2133

2134
  TAOS_RETURN(code);
32,476✔
2135
}
2136

2137
int32_t mndAddDropVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid,
4,062,723✔
2138
                              bool isRedo) {
2139
  int32_t      code = 0;
4,062,723✔
2140
  STransAction action = {0};
4,062,723✔
2141

2142
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
4,062,723✔
2143
  if (pDnode == NULL) {
4,062,723✔
2144
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2145
    if (terrno != 0) code = terrno;
×
2146
    TAOS_RETURN(code);
×
2147
  }
2148
  action.epSet = mndGetDnodeEpset(pDnode);
4,062,723✔
2149
  mndReleaseDnode(pMnode, pDnode);
4,062,723✔
2150

2151
  int32_t contLen = 0;
4,062,723✔
2152
  void   *pReq = mndBuildDropVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
4,062,723✔
2153
  if (pReq == NULL) {
4,062,723✔
2154
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2155
    if (terrno != 0) code = terrno;
×
2156
    TAOS_RETURN(code);
×
2157
  }
2158

2159
  action.pCont = pReq;
4,062,723✔
2160
  action.contLen = contLen;
4,062,723✔
2161
  action.msgType = TDMT_DND_DROP_VNODE;
4,062,723✔
2162
  action.acceptableCode = TSDB_CODE_VND_NOT_EXIST;
4,062,723✔
2163
  action.groupId = pVgroup->vgId;
4,062,723✔
2164

2165
  if (isRedo) {
4,062,723✔
2166
    if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
1,467,667✔
2167
      taosMemoryFree(pReq);
×
2168
      TAOS_RETURN(code);
×
2169
    }
2170
  } else {
2171
    if ((code = mndTransAppendUndoAction(pTrans, &action)) != 0) {
2,595,056✔
2172
      taosMemoryFree(pReq);
×
2173
      TAOS_RETURN(code);
×
2174
    }
2175
  }
2176

2177
  TAOS_RETURN(code);
4,062,723✔
2178
}
2179

2180
int32_t mndSetMoveVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t vnIndex,
14,191✔
2181
                                    SArray *pArray, bool force, bool unsafe) {
2182
  int32_t code = 0;
14,191✔
2183
  SVgObj  newVg = {0};
14,191✔
2184
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
14,191✔
2185

2186
  mInfo("vgId:%d, trans:%d, vgroup info before move, replica:%d", newVg.vgId, pTrans->id, newVg.replica);
14,191✔
2187
  for (int32_t i = 0; i < newVg.replica; ++i) {
45,756✔
2188
    mInfo("vgId:%d, trans:%d, vnode:%d dnode:%d", newVg.vgId, pTrans->id, i, newVg.vnodeGid[i].dnodeId);
31,565✔
2189
  }
2190

2191
  if (!force) {
14,191✔
2192
#if 1
2193
    {
2194
#else
2195
    if (newVg.replica == 1) {
2196
#endif
2197
      mInfo("vgId:%d, trans:%d, will add 1 vnode, replca:%d", pVgroup->vgId, pTrans->id, newVg.replica);
14,191✔
2198
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray));
14,191✔
2199
      for (int32_t i = 0; i < newVg.replica - 1; ++i) {
45,756✔
2200
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
31,565✔
2201
      }
2202
      TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[newVg.replica - 1]));
14,191✔
2203
      TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
14,191✔
2204

2205
      mInfo("vgId:%d, trans:%d, will remove 1 vnode, replca:2", pVgroup->vgId, pTrans->id);
14,191✔
2206
      newVg.replica--;
14,191✔
2207
      SVnodeGid del = newVg.vnodeGid[vnIndex];
14,191✔
2208
      newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
14,191✔
2209
      memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
14,191✔
2210
      {
2211
        SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
14,191✔
2212
        if (pRaw == NULL) {
14,191✔
2213
          code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2214
          if (terrno != 0) code = terrno;
×
2215
          TAOS_RETURN(code);
×
2216
        }
2217
        if ((code = mndTransAppendGroupRedolog(pTrans, pRaw, pVgroup->vgId)) != 0) {
14,191✔
2218
          sdbFreeRaw(pRaw);
×
2219
          TAOS_RETURN(code);
×
2220
        }
2221
        code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
14,191✔
2222
        if (code != 0) {
14,191✔
2223
          mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2224
          return code;
×
2225
        }
2226
      }
2227

2228
      TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg, &del, true));
14,191✔
2229
      for (int32_t i = 0; i < newVg.replica; ++i) {
45,756✔
2230
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
31,565✔
2231
      }
2232
      TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
14,191✔
2233
#if 1
2234
    }
2235
#else
2236
    } else {  // new replica == 3
2237
      mInfo("vgId:%d, will add 1 vnode, replca:3", pVgroup->vgId);
2238
      if (mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray) != 0) return -1;
2239
      mInfo("vgId:%d, will remove 1 vnode, replca:4", pVgroup->vgId);
2240
      newVg.replica--;
2241
      SVnodeGid del = newVg.vnodeGid[vnIndex];
2242
      newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
2243
      memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
2244
      {
2245
        SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
2246
        if (pRaw == NULL) return -1;
2247
        if (mndTransAppendRedolog(pTrans, pRaw) != 0) {
2248
          sdbFreeRaw(pRaw);
2249
          return -1;
2250
        }
2251
      }
2252

2253
      if (mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg, &del, true) != 0) return -1;
2254
      for (int32_t i = 0; i < newVg.replica; ++i) {
2255
        if (i == vnIndex) continue;
2256
        if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId) != 0) return -1;
2257
      }
2258
      if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[vnIndex]) != 0) return -1;
2259
      if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg) != 0) return -1;
2260
    }
2261
#endif
2262
  } else {
2263
    mInfo("vgId:%d, will add 1 vnode and force remove 1 vnode", pVgroup->vgId);
×
2264
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVg, pArray));
×
2265
    newVg.replica--;
×
2266
    // SVnodeGid del = newVg.vnodeGid[vnIndex];
2267
    newVg.vnodeGid[vnIndex] = newVg.vnodeGid[newVg.replica];
×
2268
    memset(&newVg.vnodeGid[newVg.replica], 0, sizeof(SVnodeGid));
×
2269
    {
2270
      SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
×
2271
      if (pRaw == NULL) {
×
2272
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2273
        if (terrno != 0) code = terrno;
×
2274
        TAOS_RETURN(code);
×
2275
      }
2276
      if ((code = mndTransAppendGroupRedolog(pTrans, pRaw, pVgroup->vgId)) != 0) {
×
2277
        sdbFreeRaw(pRaw);
×
2278
        TAOS_RETURN(code);
×
2279
      }
2280
      code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
×
2281
      if (code != 0) {
×
2282
        mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2283
        return code;
×
2284
      }
2285
    }
2286

2287
    for (int32_t i = 0; i < newVg.replica; ++i) {
×
2288
      if (i != vnIndex) {
×
2289
        TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg, newVg.vnodeGid[i].dnodeId));
×
2290
      }
2291
    }
2292
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg, &newVg.vnodeGid[vnIndex]));
×
2293
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg));
×
2294

2295
    if (newVg.replica == 1) {
×
2296
      if (force && !unsafe) {
×
2297
        TAOS_RETURN(TSDB_CODE_VND_META_DATA_UNSAFE_DELETE);
×
2298
      }
2299

2300
      SSdb *pSdb = pMnode->pSdb;
×
2301
      void *pIter = NULL;
×
2302

2303
      while (1) {
×
2304
        SStbObj *pStb = NULL;
×
2305
        pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
×
2306
        if (pIter == NULL) break;
×
2307

2308
        if (strcmp(pStb->db, pDb->name) == 0) {
×
2309
          if ((code = mndSetForceDropCreateStbRedoActions(pMnode, pTrans, &newVg, pStb)) != 0) {
×
2310
            sdbCancelFetch(pSdb, pIter);
×
2311
            sdbRelease(pSdb, pStb);
×
2312
            TAOS_RETURN(code);
×
2313
          }
2314
        }
2315

2316
        sdbRelease(pSdb, pStb);
×
2317
      }
2318

2319
      mInfo("vgId:%d, all data is dropped since replica=1", pVgroup->vgId);
×
2320
    }
2321
  }
2322

2323
  {
2324
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
14,191✔
2325
    if (pRaw == NULL) {
14,191✔
2326
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2327
      if (terrno != 0) code = terrno;
×
2328
      TAOS_RETURN(code);
×
2329
    }
2330
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
14,191✔
2331
      sdbFreeRaw(pRaw);
×
2332
      TAOS_RETURN(code);
×
2333
    }
2334
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
14,191✔
2335
    if (code != 0) {
14,191✔
2336
      mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2337
      return code;
×
2338
    }
2339
  }
2340

2341
  mInfo("vgId:%d, vgroup info after move, replica:%d", newVg.vgId, newVg.replica);
14,191✔
2342
  for (int32_t i = 0; i < newVg.replica; ++i) {
45,756✔
2343
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
31,565✔
2344
  }
2345
  TAOS_RETURN(code);
14,191✔
2346
}
2347

2348
int32_t mndSetMoveVgroupsInfoToTrans(SMnode *pMnode, STrans *pTrans, int32_t delDnodeId, bool force, bool unsafe) {
7,084✔
2349
  int32_t code = 0;
7,084✔
2350
  SArray *pArray = mndBuildDnodesArray(pMnode, delDnodeId, NULL);
7,084✔
2351
  if (pArray == NULL) {
7,084✔
2352
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2353
    if (terrno != 0) code = terrno;
×
2354
    TAOS_RETURN(code);
×
2355
  }
2356

2357
  void *pIter = NULL;
7,084✔
2358
  while (1) {
21,142✔
2359
    SVgObj *pVgroup = NULL;
28,226✔
2360
    pIter = sdbFetch(pMnode->pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
28,226✔
2361
    if (pIter == NULL) break;
28,226✔
2362

2363
    int32_t vnIndex = -1;
21,142✔
2364
    for (int32_t i = 0; i < pVgroup->replica; ++i) {
42,255✔
2365
      if (pVgroup->vnodeGid[i].dnodeId == delDnodeId) {
35,304✔
2366
        vnIndex = i;
14,191✔
2367
        break;
14,191✔
2368
      }
2369
    }
2370

2371
    code = 0;
21,142✔
2372
    if (vnIndex != -1) {
21,142✔
2373
      mInfo("vgId:%d, trans:%d, vnode:%d will be removed from dnode:%d, force:%d", pVgroup->vgId, pTrans->id, vnIndex,
14,191✔
2374
            delDnodeId, force);
2375
      SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
14,191✔
2376
      code = mndSetMoveVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, vnIndex, pArray, force, unsafe);
14,191✔
2377
      mndReleaseDb(pMnode, pDb);
14,191✔
2378
    }
2379

2380
    sdbRelease(pMnode->pSdb, pVgroup);
21,142✔
2381

2382
    if (code != 0) {
21,142✔
2383
      sdbCancelFetch(pMnode->pSdb, pIter);
×
2384
      break;
×
2385
    }
2386
  }
2387

2388
  taosArrayDestroy(pArray);
7,084✔
2389
  TAOS_RETURN(code);
7,084✔
2390
}
2391

2392
static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
64,107✔
2393
                                             int32_t newDnodeId) {
2394
  int32_t code = 0;
64,107✔
2395
  mInfo("vgId:%d, will add 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, newDnodeId);
64,107✔
2396

2397
  // assoc dnode
2398
  SVnodeGid *pGid = &pVgroup->vnodeGid[pVgroup->replica];
64,107✔
2399
  pVgroup->replica++;
64,107✔
2400
  pGid->dnodeId = newDnodeId;
64,107✔
2401
  pGid->syncState = TAOS_SYNC_STATE_OFFLINE;
64,107✔
2402
  pGid->nodeRole = TAOS_SYNC_ROLE_LEARNER;
64,107✔
2403

2404
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
64,107✔
2405
  if (pVgRaw == NULL) {
64,107✔
2406
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2407
    if (terrno != 0) code = terrno;
×
2408
    TAOS_RETURN(code);
×
2409
  }
2410
  if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
64,107✔
2411
    sdbFreeRaw(pVgRaw);
×
2412
    TAOS_RETURN(code);
×
2413
  }
2414
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
64,107✔
2415
  if (code != 0) {
64,107✔
2416
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVgroup->vgId, tstrerror(code), __LINE__);
×
2417
    TAOS_RETURN(code);
×
2418
  }
2419

2420
  // learner
2421
  for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
217,886✔
2422
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
153,779✔
2423
  }
2424
  TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pDb, pVgroup, pGid));
64,107✔
2425

2426
  // voter
2427
  pGid->nodeRole = TAOS_SYNC_ROLE_VOTER;
64,107✔
2428
  TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, pVgroup, pGid->dnodeId));
64,107✔
2429
  for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
217,886✔
2430
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
153,779✔
2431
  }
2432

2433
  // confirm
2434
  TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup));
64,107✔
2435

2436
  TAOS_RETURN(code);
64,107✔
2437
}
2438

2439
static int32_t mndAddDecVgroupReplicaFromTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
64,107✔
2440
                                               int32_t delDnodeId) {
2441
  int32_t code = 0;
64,107✔
2442
  mInfo("vgId:%d, will remove 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, delDnodeId);
64,107✔
2443

2444
  SVnodeGid *pGid = NULL;
64,107✔
2445
  SVnodeGid  delGid = {0};
64,107✔
2446
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
111,435✔
2447
    if (pVgroup->vnodeGid[i].dnodeId == delDnodeId) {
111,435✔
2448
      pGid = &pVgroup->vnodeGid[i];
64,107✔
2449
      break;
64,107✔
2450
    }
2451
  }
2452

2453
  if (pGid == NULL) return 0;
64,107✔
2454

2455
  pVgroup->replica--;
64,107✔
2456
  memcpy(&delGid, pGid, sizeof(SVnodeGid));
64,107✔
2457
  memcpy(pGid, &pVgroup->vnodeGid[pVgroup->replica], sizeof(SVnodeGid));
64,107✔
2458
  memset(&pVgroup->vnodeGid[pVgroup->replica], 0, sizeof(SVnodeGid));
64,107✔
2459

2460
  SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
64,107✔
2461
  if (pVgRaw == NULL) {
64,107✔
2462
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2463
    if (terrno != 0) code = terrno;
×
2464
    TAOS_RETURN(code);
×
2465
  }
2466
  if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
64,107✔
2467
    sdbFreeRaw(pVgRaw);
×
2468
    TAOS_RETURN(code);
×
2469
  }
2470
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
64,107✔
2471
  if (code != 0) {
64,107✔
2472
    mError("vgId:%d, failed to set raw status since %s at line:%d", pVgroup->vgId, tstrerror(code), __LINE__);
×
2473
    TAOS_RETURN(code);
×
2474
  }
2475

2476
  TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pDb, pVgroup, &delGid, true));
64,107✔
2477
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
217,886✔
2478
    TAOS_CHECK_RETURN(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId));
153,779✔
2479
  }
2480
  TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup));
64,107✔
2481

2482
  TAOS_RETURN(code);
64,107✔
2483
}
2484

2485
static int32_t mndRedistributeVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup, SDnodeObj *pNew1,
35,624✔
2486
                                     SDnodeObj *pOld1, SDnodeObj *pNew2, SDnodeObj *pOld2, SDnodeObj *pNew3,
2487
                                     SDnodeObj *pOld3) {
2488
  int32_t code = -1;
35,624✔
2489
  STrans *pTrans = NULL;
35,624✔
2490

2491
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "red-vgroup");
35,624✔
2492
  if (pTrans == NULL) {
35,624✔
2493
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2494
    if (terrno != 0) code = terrno;
×
2495
    goto _OVER;
×
2496
  }
2497

2498
  mndTransSetDbName(pTrans, pVgroup->dbName, NULL);
35,624✔
2499
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
35,624✔
2500
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
35,590✔
2501

2502
  mndTransSetSerial(pTrans);
35,590✔
2503
  mInfo("trans:%d, used to redistribute vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
35,590✔
2504

2505
  SVgObj newVg = {0};
35,590✔
2506
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
35,590✔
2507
  mInfo("vgId:%d, vgroup info before redistribute, replica:%d", newVg.vgId, newVg.replica);
35,590✔
2508
  for (int32_t i = 0; i < newVg.replica; ++i) {
120,462✔
2509
    mInfo("vgId:%d, vnode:%d dnode:%d role:%s", newVg.vgId, i, newVg.vnodeGid[i].dnodeId,
84,872✔
2510
          syncStr(newVg.vnodeGid[i].syncState));
2511
  }
2512

2513
  if (pNew1 != NULL && pOld1 != NULL) {
35,590✔
2514
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew1->id);
35,590✔
2515
    if (numOfVnodes >= pNew1->numOfSupportVnodes) {
35,590✔
2516
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew1->id, numOfVnodes,
675✔
2517
             pNew1->numOfSupportVnodes);
2518
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
675✔
2519
      goto _OVER;
675✔
2520
    }
2521

2522
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
34,915✔
2523
    if (pNew1->memAvail - vgMem - pNew1->memUsed <= 0) {
34,915✔
2524
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2525
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew1->id, pNew1->memAvail, pNew1->memUsed);
2526
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2527
      goto _OVER;
×
2528
    } else {
2529
      pNew1->memUsed += vgMem;
34,915✔
2530
    }
2531

2532
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew1->id), NULL, _OVER);
34,915✔
2533
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld1->id), NULL, _OVER);
34,915✔
2534
  }
2535

2536
  if (pNew2 != NULL && pOld2 != NULL) {
34,915✔
2537
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew2->id);
10,526✔
2538
    if (numOfVnodes >= pNew2->numOfSupportVnodes) {
10,526✔
2539
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew2->id, numOfVnodes,
×
2540
             pNew2->numOfSupportVnodes);
2541
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
×
2542
      goto _OVER;
×
2543
    }
2544
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
10,526✔
2545
    if (pNew2->memAvail - vgMem - pNew2->memUsed <= 0) {
10,526✔
2546
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2547
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew2->id, pNew2->memAvail, pNew2->memUsed);
2548
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2549
      goto _OVER;
×
2550
    } else {
2551
      pNew2->memUsed += vgMem;
10,526✔
2552
    }
2553
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew2->id), NULL, _OVER);
10,526✔
2554
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld2->id), NULL, _OVER);
10,526✔
2555
  }
2556

2557
  if (pNew3 != NULL && pOld3 != NULL) {
34,915✔
2558
    int32_t numOfVnodes = mndGetVnodesNum(pMnode, pNew3->id);
4,176✔
2559
    if (numOfVnodes >= pNew3->numOfSupportVnodes) {
4,176✔
2560
      mError("vgId:%d, no enough vnodes in dnode:%d, numOfVnodes:%d support:%d", newVg.vgId, pNew3->id, numOfVnodes,
×
2561
             pNew3->numOfSupportVnodes);
2562
      code = TSDB_CODE_MND_NO_ENOUGH_VNODES;
×
2563
      goto _OVER;
×
2564
    }
2565
    int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup);
4,176✔
2566
    if (pNew3->memAvail - vgMem - pNew3->memUsed <= 0) {
4,176✔
2567
      mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64,
×
2568
             pVgroup->dbName, pVgroup->vgId, vgMem, pNew3->id, pNew3->memAvail, pNew3->memUsed);
2569
      code = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE;
×
2570
      goto _OVER;
×
2571
    } else {
2572
      pNew3->memUsed += vgMem;
4,176✔
2573
    }
2574
    TAOS_CHECK_GOTO(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew3->id), NULL, _OVER);
4,176✔
2575
    TAOS_CHECK_GOTO(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld3->id), NULL, _OVER);
4,176✔
2576
  }
2577

2578
  {
2579
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
34,915✔
2580
    if (pRaw == NULL) {
34,915✔
2581
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2582
      if (terrno != 0) code = terrno;
×
2583
      goto _OVER;
×
2584
    }
2585
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
34,915✔
2586
      sdbFreeRaw(pRaw);
×
2587
      goto _OVER;
×
2588
    }
2589
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
34,915✔
2590
    if (code != 0) {
34,915✔
2591
      mError("vgId:%d, failed to set raw status since %s at line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
2592
      goto _OVER;
×
2593
    }
2594
  }
2595

2596
  mInfo("vgId:%d, vgroup info after redistribute, replica:%d", newVg.vgId, newVg.replica);
34,915✔
2597
  for (int32_t i = 0; i < newVg.replica; ++i) {
117,762✔
2598
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
82,847✔
2599
  }
2600

2601
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
34,915✔
2602
  code = 0;
34,575✔
2603

2604
_OVER:
35,624✔
2605
  mndTransDrop(pTrans);
35,624✔
2606
  mndReleaseDb(pMnode, pDb);
35,624✔
2607
  TAOS_RETURN(code);
35,624✔
2608
}
2609

2610
static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq) {
43,720✔
2611
  SMnode    *pMnode = pReq->info.node;
43,720✔
2612
  SDnodeObj *pNew1 = NULL;
43,720✔
2613
  SDnodeObj *pNew2 = NULL;
43,720✔
2614
  SDnodeObj *pNew3 = NULL;
43,720✔
2615
  SDnodeObj *pOld1 = NULL;
43,720✔
2616
  SDnodeObj *pOld2 = NULL;
43,720✔
2617
  SDnodeObj *pOld3 = NULL;
43,720✔
2618
  SVgObj    *pVgroup = NULL;
43,720✔
2619
  SDbObj    *pDb = NULL;
43,720✔
2620
  int32_t    code = -1;
43,720✔
2621
  int64_t    curMs = taosGetTimestampMs();
43,720✔
2622
  int32_t    newDnodeId[3] = {0};
43,720✔
2623
  int32_t    oldDnodeId[3] = {0};
43,720✔
2624
  int32_t    newIndex = -1;
43,720✔
2625
  int32_t    oldIndex = -1;
43,720✔
2626
  int64_t    tss = taosGetTimestampMs();
43,720✔
2627

2628
  SRedistributeVgroupReq req = {0};
43,720✔
2629
  if (tDeserializeSRedistributeVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) {
43,720✔
2630
    code = TSDB_CODE_INVALID_MSG;
×
2631
    goto _OVER;
×
2632
  }
2633

2634
  mInfo("vgId:%d, start to redistribute vgroup to dnode %d:%d:%d", req.vgId, req.dnodeId1, req.dnodeId2, req.dnodeId3);
43,720✔
2635
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_REDISTRIBUTE_VGROUP)) != 0) {
43,720✔
2636
    goto _OVER;
162✔
2637
  }
2638

2639
  pVgroup = mndAcquireVgroup(pMnode, req.vgId);
43,558✔
2640
  if (pVgroup == NULL) {
43,558✔
2641
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
2,025✔
2642
    if (terrno != 0) code = terrno;
2,025✔
2643
    goto _OVER;
2,025✔
2644
  }
2645
  if (pVgroup->mountVgId) {
41,533✔
2646
    code = TSDB_CODE_MND_MOUNT_OBJ_NOT_SUPPORT;
×
2647
    goto _OVER;
×
2648
  }
2649
  pDb = mndAcquireDb(pMnode, pVgroup->dbName);
41,533✔
2650
  if (pDb == NULL) {
41,533✔
2651
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2652
    if (terrno != 0) code = terrno;
×
2653
    goto _OVER;
×
2654
  }
2655

2656
  if (pVgroup->replica == 1) {
41,533✔
2657
    if (req.dnodeId1 <= 0 || req.dnodeId2 > 0 || req.dnodeId3 > 0) {
10,296✔
2658
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2659
      goto _OVER;
×
2660
    }
2661

2662
    if (req.dnodeId1 == pVgroup->vnodeGid[0].dnodeId) {
10,296✔
2663
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2664
      code = 0;
×
2665
      goto _OVER;
×
2666
    }
2667

2668
    pNew1 = mndAcquireDnode(pMnode, req.dnodeId1);
10,296✔
2669
    if (pNew1 == NULL) {
10,296✔
2670
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2671
      if (terrno != 0) code = terrno;
×
2672
      goto _OVER;
×
2673
    }
2674
    if (!mndIsDnodeOnline(pNew1, curMs)) {
10,296✔
UNCOV
2675
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
UNCOV
2676
      goto _OVER;
×
2677
    }
2678

2679
    pOld1 = mndAcquireDnode(pMnode, pVgroup->vnodeGid[0].dnodeId);
10,296✔
2680
    if (pOld1 == NULL) {
10,296✔
2681
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2682
      if (terrno != 0) code = terrno;
×
2683
      goto _OVER;
×
2684
    }
2685
    if (!mndIsDnodeOnline(pOld1, curMs)) {
10,296✔
UNCOV
2686
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
UNCOV
2687
      goto _OVER;
×
2688
    }
2689

2690
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, NULL, NULL, NULL, NULL);
10,296✔
2691

2692
  } else if (pVgroup->replica == 3) {
31,237✔
2693
    if (req.dnodeId1 <= 0 || req.dnodeId2 <= 0 || req.dnodeId3 <= 0) {
29,863✔
2694
      code = TSDB_CODE_MND_INVALID_REPLICA;
2,700✔
2695
      goto _OVER;
2,700✔
2696
    }
2697

2698
    if (req.dnodeId1 == req.dnodeId2 || req.dnodeId1 == req.dnodeId3 || req.dnodeId2 == req.dnodeId3) {
27,163✔
2699
      code = TSDB_CODE_MND_INVALID_REPLICA;
675✔
2700
      goto _OVER;
675✔
2701
    }
2702

2703
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId &&
26,488✔
2704
        req.dnodeId1 != pVgroup->vnodeGid[2].dnodeId) {
13,154✔
2705
      newDnodeId[++newIndex] = req.dnodeId1;
11,150✔
2706
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
11,150✔
2707
    }
2708

2709
    if (req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId &&
26,488✔
2710
        req.dnodeId2 != pVgroup->vnodeGid[2].dnodeId) {
17,738✔
2711
      newDnodeId[++newIndex] = req.dnodeId2;
12,912✔
2712
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
12,912✔
2713
    }
2714

2715
    if (req.dnodeId3 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId3 != pVgroup->vnodeGid[1].dnodeId &&
26,488✔
2716
        req.dnodeId3 != pVgroup->vnodeGid[2].dnodeId) {
19,672✔
2717
      newDnodeId[++newIndex] = req.dnodeId3;
16,979✔
2718
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
16,979✔
2719
    }
2720

2721
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId &&
26,488✔
2722
        req.dnodeId3 != pVgroup->vnodeGid[0].dnodeId) {
17,105✔
2723
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[0].dnodeId;
13,758✔
2724
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
13,758✔
2725
    }
2726

2727
    if (req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId &&
26,488✔
2728
        req.dnodeId3 != pVgroup->vnodeGid[1].dnodeId) {
13,787✔
2729
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[1].dnodeId;
10,318✔
2730
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
10,318✔
2731
    }
2732

2733
    if (req.dnodeId1 != pVgroup->vnodeGid[2].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[2].dnodeId &&
26,488✔
2734
        req.dnodeId3 != pVgroup->vnodeGid[2].dnodeId) {
19,658✔
2735
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[2].dnodeId;
16,965✔
2736
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
16,965✔
2737
    }
2738

2739
    if (newDnodeId[0] != 0) {
26,488✔
2740
      pNew1 = mndAcquireDnode(pMnode, newDnodeId[0]);
25,657✔
2741
      if (pNew1 == NULL) {
25,657✔
2742
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2743
        if (terrno != 0) code = terrno;
×
2744
        goto _OVER;
×
2745
      }
2746
      if (!mndIsDnodeOnline(pNew1, curMs)) {
25,657✔
2747
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
675✔
2748
        goto _OVER;
675✔
2749
      }
2750
    }
2751

2752
    if (newDnodeId[1] != 0) {
25,813✔
2753
      pNew2 = mndAcquireDnode(pMnode, newDnodeId[1]);
10,180✔
2754
      if (pNew2 == NULL) {
10,180✔
2755
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2756
        if (terrno != 0) code = terrno;
×
2757
        goto _OVER;
×
2758
      }
2759
      if (!mndIsDnodeOnline(pNew2, curMs)) {
10,180✔
2760
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2761
        goto _OVER;
×
2762
      }
2763
    }
2764

2765
    if (newDnodeId[2] != 0) {
25,813✔
2766
      pNew3 = mndAcquireDnode(pMnode, newDnodeId[2]);
5,204✔
2767
      if (pNew3 == NULL) {
5,204✔
2768
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2769
        if (terrno != 0) code = terrno;
×
2770
        goto _OVER;
×
2771
      }
2772
      if (!mndIsDnodeOnline(pNew3, curMs)) {
5,204✔
2773
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
258✔
2774
        goto _OVER;
258✔
2775
      }
2776
    }
2777

2778
    if (oldDnodeId[0] != 0) {
25,555✔
2779
      pOld1 = mndAcquireDnode(pMnode, oldDnodeId[0]);
24,724✔
2780
      if (pOld1 == NULL) {
24,724✔
2781
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2782
        if (terrno != 0) code = terrno;
×
2783
        goto _OVER;
×
2784
      }
2785
      if (!mndIsDnodeOnline(pOld1, curMs)) {
24,724✔
2786
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
770✔
2787
        goto _OVER;
770✔
2788
      }
2789
    }
2790

2791
    if (oldDnodeId[1] != 0) {
24,785✔
2792
      pOld2 = mndAcquireDnode(pMnode, oldDnodeId[1]);
9,152✔
2793
      if (pOld2 == NULL) {
9,152✔
2794
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2795
        if (terrno != 0) code = terrno;
×
2796
        goto _OVER;
×
2797
      }
2798
      if (!mndIsDnodeOnline(pOld2, curMs)) {
9,152✔
2799
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2800
        goto _OVER;
×
2801
      }
2802
    }
2803

2804
    if (oldDnodeId[2] != 0) {
24,785✔
2805
      pOld3 = mndAcquireDnode(pMnode, oldDnodeId[2]);
4,176✔
2806
      if (pOld3 == NULL) {
4,176✔
2807
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2808
        if (terrno != 0) code = terrno;
×
2809
        goto _OVER;
×
2810
      }
2811
      if (!mndIsDnodeOnline(pOld3, curMs)) {
4,176✔
2812
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2813
        goto _OVER;
×
2814
      }
2815
    }
2816

2817
    if (pNew1 == NULL && pOld1 == NULL && pNew2 == NULL && pOld2 == NULL && pNew3 == NULL && pOld3 == NULL) {
24,785✔
2818
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2819
      code = 0;
831✔
2820
      goto _OVER;
831✔
2821
    }
2822

2823
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, pNew3, pOld3);
23,954✔
2824

2825
  } else if (pVgroup->replica == 2) {
1,374✔
2826
    if (req.dnodeId1 <= 0 || req.dnodeId2 <= 0) {
1,374✔
2827
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2828
      goto _OVER;
×
2829
    }
2830

2831
    if (req.dnodeId1 == req.dnodeId2) {
1,374✔
2832
      code = TSDB_CODE_MND_INVALID_REPLICA;
×
2833
      goto _OVER;
×
2834
    }
2835

2836
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId) {
1,374✔
2837
      newDnodeId[++newIndex] = req.dnodeId1;
1,374✔
2838
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
1,374✔
2839
    }
2840

2841
    if (req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId) {
1,374✔
2842
      newDnodeId[++newIndex] = req.dnodeId2;
1,374✔
2843
      mInfo("vgId:%d, dnode:%d will be added, index:%d", pVgroup->vgId, newDnodeId[newIndex], newIndex);
1,374✔
2844
    }
2845

2846
    if (req.dnodeId1 != pVgroup->vnodeGid[0].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[0].dnodeId) {
1,374✔
2847
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[0].dnodeId;
1,374✔
2848
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
1,374✔
2849
    }
2850

2851
    if (req.dnodeId1 != pVgroup->vnodeGid[1].dnodeId && req.dnodeId2 != pVgroup->vnodeGid[1].dnodeId) {
1,374✔
2852
      oldDnodeId[++oldIndex] = pVgroup->vnodeGid[1].dnodeId;
1,374✔
2853
      mInfo("vgId:%d, dnode:%d will be removed, index:%d", pVgroup->vgId, oldDnodeId[oldIndex], oldIndex);
1,374✔
2854
    }
2855

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

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

2882
    if (oldDnodeId[0] != 0) {
1,374✔
2883
      pOld1 = mndAcquireDnode(pMnode, oldDnodeId[0]);
1,374✔
2884
      if (pOld1 == NULL) {
1,374✔
2885
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2886
        if (terrno != 0) code = terrno;
×
2887
        goto _OVER;
×
2888
      }
2889
      if (!mndIsDnodeOnline(pOld1, curMs)) {
1,374✔
2890
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2891
        goto _OVER;
×
2892
      }
2893
    }
2894

2895
    if (oldDnodeId[1] != 0) {
1,374✔
2896
      pOld2 = mndAcquireDnode(pMnode, oldDnodeId[1]);
1,374✔
2897
      if (pOld2 == NULL) {
1,374✔
2898
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2899
        if (terrno != 0) code = terrno;
×
2900
        goto _OVER;
×
2901
      }
2902
      if (!mndIsDnodeOnline(pOld2, curMs)) {
1,374✔
2903
        code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
×
2904
        goto _OVER;
×
2905
      }
2906
    }
2907

2908
    if (pNew1 == NULL && pOld1 == NULL && pNew2 == NULL && pOld2 == NULL) {
1,374✔
2909
      // terrno = TSDB_CODE_MND_VGROUP_UN_CHANGED;
2910
      code = 0;
×
2911
      goto _OVER;
×
2912
    }
2913

2914
    code = mndRedistributeVgroup(pMnode, pReq, pDb, pVgroup, pNew1, pOld1, pNew2, pOld2, NULL, NULL);
1,374✔
2915
  } else {
2916
    code = TSDB_CODE_MND_REQ_REJECTED;
×
2917
    goto _OVER;
×
2918
  }
2919

2920
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
35,624✔
2921

2922
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
35,624✔
2923
    char obj[33] = {0};
35,624✔
2924
    (void)tsnprintf(obj, sizeof(obj), "%d", req.vgId);
35,624✔
2925

2926
    int64_t tse = taosGetTimestampMs();
35,624✔
2927
    double  duration = (double)(tse - tss);
35,624✔
2928
    duration = duration / 1000;
35,624✔
2929
    auditRecord(pReq, pMnode->clusterId, "RedistributeVgroup", "", obj, req.sql, req.sqlLen, duration, 0);
35,624✔
2930
  }
2931
_OVER:
43,720✔
2932
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
43,720✔
2933
    mError("vgId:%d, failed to redistribute to dnode %d:%d:%d since %s", req.vgId, req.dnodeId1, req.dnodeId2,
8,314✔
2934
           req.dnodeId3, tstrerror(code));
2935
  }
2936

2937
  mndReleaseDnode(pMnode, pNew1);
43,720✔
2938
  mndReleaseDnode(pMnode, pNew2);
43,720✔
2939
  mndReleaseDnode(pMnode, pNew3);
43,720✔
2940
  mndReleaseDnode(pMnode, pOld1);
43,720✔
2941
  mndReleaseDnode(pMnode, pOld2);
43,720✔
2942
  mndReleaseDnode(pMnode, pOld3);
43,720✔
2943
  mndReleaseVgroup(pMnode, pVgroup);
43,720✔
2944
  mndReleaseDb(pMnode, pDb);
43,720✔
2945
  tFreeSRedistributeVgroupReq(&req);
43,720✔
2946

2947
  TAOS_RETURN(code);
43,720✔
2948
}
2949

2950
static void *mndBuildSForceBecomeFollowerReq(SMnode *pMnode, SVgObj *pVgroup, int32_t dnodeId, int32_t *pContLen) {
4,021✔
2951
  SForceBecomeFollowerReq balanceReq = {
4,021✔
2952
      .vgId = pVgroup->vgId,
4,021✔
2953
  };
2954

2955
  int32_t contLen = tSerializeSForceBecomeFollowerReq(NULL, 0, &balanceReq);
4,021✔
2956
  if (contLen < 0) {
4,021✔
2957
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2958
    return NULL;
×
2959
  }
2960
  contLen += sizeof(SMsgHead);
4,021✔
2961

2962
  void *pReq = taosMemoryMalloc(contLen);
4,021✔
2963
  if (pReq == NULL) {
4,021✔
2964
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2965
    return NULL;
×
2966
  }
2967

2968
  SMsgHead *pHead = pReq;
4,021✔
2969
  pHead->contLen = htonl(contLen);
4,021✔
2970
  pHead->vgId = htonl(pVgroup->vgId);
4,021✔
2971

2972
  if (tSerializeSForceBecomeFollowerReq((char *)pReq + sizeof(SMsgHead), contLen, &balanceReq) < 0) {
4,021✔
2973
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2974
    taosMemoryFree(pReq);
×
2975
    return NULL;
×
2976
  }
2977
  *pContLen = contLen;
4,021✔
2978
  return pReq;
4,021✔
2979
}
2980

2981
int32_t mndAddBalanceVgroupLeaderAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, int32_t dnodeId) {
4,021✔
2982
  int32_t    code = 0;
4,021✔
2983
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
4,021✔
2984
  if (pDnode == NULL) {
4,021✔
2985
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2986
    if (terrno != 0) code = terrno;
×
2987
    TAOS_RETURN(code);
×
2988
  }
2989

2990
  STransAction action = {0};
4,021✔
2991
  action.epSet = mndGetDnodeEpset(pDnode);
4,021✔
2992
  mndReleaseDnode(pMnode, pDnode);
4,021✔
2993

2994
  int32_t contLen = 0;
4,021✔
2995
  void   *pReq = mndBuildSForceBecomeFollowerReq(pMnode, pVgroup, dnodeId, &contLen);
4,021✔
2996
  if (pReq == NULL) {
4,021✔
2997
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2998
    if (terrno != 0) code = terrno;
×
2999
    TAOS_RETURN(code);
×
3000
  }
3001

3002
  action.pCont = pReq;
4,021✔
3003
  action.contLen = contLen;
4,021✔
3004
  action.msgType = TDMT_SYNC_FORCE_FOLLOWER;
4,021✔
3005

3006
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
4,021✔
3007
    taosMemoryFree(pReq);
×
3008
    TAOS_RETURN(code);
×
3009
  }
3010

3011
  TAOS_RETURN(code);
4,021✔
3012
}
3013

3014
static void *mndBuildAlterVnodeElectBaselineReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId,
24,126✔
3015
                                          int32_t *pContLen, int32_t ms) {
3016
  SAlterVnodeElectBaselineReq alterReq = {
24,126✔
3017
      .vgId = pVgroup->vgId,
24,126✔
3018
      .electBaseLine = ms,
3019
  };
3020

3021
  int32_t contLen = tSerializeSAlterVnodeReplicaReq(NULL, 0, &alterReq);
24,126✔
3022
  if (contLen < 0) {
24,126✔
3023
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3024
    return NULL;
×
3025
  }
3026

3027
  void *pReq = taosMemoryMalloc(contLen);
24,126✔
3028
  if (pReq == NULL) {
24,126✔
3029
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3030
    return NULL;
×
3031
  }
3032

3033
  if (tSerializeSAlterVnodeReplicaReq(pReq, contLen, &alterReq) < 0) {
24,126✔
3034
    mError("vgId:%d, failed to serialize alter vnode req,since %s", alterReq.vgId, terrstr());
×
3035
    taosMemoryFree(pReq);
×
3036
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3037
    return NULL;
×
3038
  }
3039
  *pContLen = contLen;
24,126✔
3040
  return pReq;
24,126✔
3041
}
3042

3043
static int32_t mndAddAlterVnodeElectionBaselineActionToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId, int32_t ms) {
24,126✔
3044
  int32_t    code = 0;
24,126✔
3045
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
24,126✔
3046
  if (pDnode == NULL) {
24,126✔
3047
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3048
    if (terrno != 0) code = terrno;
×
3049
    TAOS_RETURN(code);
×
3050
  }
3051

3052
  STransAction action = {0};
24,126✔
3053
  action.epSet = mndGetDnodeEpset(pDnode);
24,126✔
3054
  mndReleaseDnode(pMnode, pDnode);
24,126✔
3055

3056
  int32_t contLen = 0;
24,126✔
3057
  void   *pReq = mndBuildAlterVnodeElectBaselineReq(pMnode, pDb, pVgroup, dnodeId, &contLen, ms);
24,126✔
3058
  if (pReq == NULL) {
24,126✔
3059
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3060
    if (terrno != 0) code = terrno;
×
3061
    TAOS_RETURN(code);
×
3062
  }
3063

3064
  action.pCont = pReq;
24,126✔
3065
  action.contLen = contLen;
24,126✔
3066
  action.msgType = TDMT_VND_ALTER_ELECTBASELINE;
24,126✔
3067
  action.groupId = pVgroup->vgId;
24,126✔
3068

3069
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
24,126✔
3070
    taosMemoryFree(pReq);
×
3071
    TAOS_RETURN(code);
×
3072
  }
3073

3074
  TAOS_RETURN(code);
24,126✔
3075
}
3076

3077
static int32_t mndAddAlterVgroupElectionBaselineActionToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans, int32_t index){
8,042✔
3078
  int32_t code = 0;
8,042✔
3079
  SSdb   *pSdb = pMnode->pSdb;
8,042✔
3080

3081
  int32_t vgid = pVgroup->vgId;
8,042✔
3082
  int8_t  replica = pVgroup->replica;
8,042✔
3083

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

3089
  for(int32_t i = 0; i < 3; i++){
32,168✔
3090
    if(i == index%3){
24,126✔
3091
      mInfo("trans:%d, balance leader to dnode:%d", pTrans->id, pVgroup->vnodeGid[i].dnodeId);
4,021✔
3092
      TAOS_CHECK_RETURN(mndAddAlterVnodeElectionBaselineActionToTrans(pMnode, pTrans, NULL, pVgroup,
4,021✔
3093
                                                                      pVgroup->vnodeGid[i].dnodeId, 1500));
3094
    }
3095
    else{
3096
    TAOS_CHECK_RETURN(
20,105✔
3097
        mndAddAlterVnodeElectionBaselineActionToTrans(pMnode, pTrans, NULL, pVgroup, pVgroup->vnodeGid[i].dnodeId, 5000));
3098
    }
3099
  }
3100
  return code; 
8,042✔
3101
}
3102

3103
int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTrans, int32_t index) {
4,709✔
3104
  int32_t code = 0;
4,709✔
3105
  SSdb   *pSdb = pMnode->pSdb;
4,709✔
3106

3107
  int32_t vgid = pVgroup->vgId;
4,709✔
3108
  int8_t  replica = pVgroup->replica;
4,709✔
3109

3110
  if (pVgroup->replica <= 1) {
4,709✔
3111
    mInfo("trans:%d, vgid:%d no need to balance, replica:%d", pTrans->id, vgid, replica);
213✔
3112
    return -1;
213✔
3113
  }
3114

3115
  int32_t dnodeId = 0;
4,496✔
3116

3117
  for (int i = 0; i < replica; i++) {
9,406✔
3118
    if (pVgroup->vnodeGid[i].syncState == TAOS_SYNC_STATE_LEADER) {
8,931✔
3119
      dnodeId = pVgroup->vnodeGid[i].dnodeId;
4,021✔
3120
      break;
4,021✔
3121
    }
3122
  }
3123

3124
  bool       exist = false;
4,496✔
3125
  bool       online = false;
4,496✔
3126
  int64_t    curMs = taosGetTimestampMs();
4,496✔
3127
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
4,496✔
3128
  if (pDnode != NULL) {
4,496✔
3129
    exist = true;
4,021✔
3130
    online = mndIsDnodeOnline(pDnode, curMs);
4,021✔
3131
    mndReleaseDnode(pMnode, pDnode);
4,021✔
3132
  }
3133

3134
  if (exist && online) {
8,517✔
3135
    mInfo("trans:%d, vgid:%d force drop leader from dnode:%d", pTrans->id, vgid, dnodeId);    
4,021✔
3136
    TAOS_CHECK_RETURN(mndAddAlterVgroupElectionBaselineActionToTrans(pMnode, pVgroup, pTrans, index));
4,021✔
3137

3138
    if ((code = mndAddBalanceVgroupLeaderAction(pMnode, pTrans, pVgroup, dnodeId)) != 0) {
4,021✔
3139
      mError("trans:%d, vgid:%d failed to be balanced to dnode:%d", pTrans->id, vgid, dnodeId);
×
3140
      TAOS_RETURN(code);
×
3141
    }
3142

3143
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, NULL, pVgroup));
4,021✔
3144

3145
    TAOS_CHECK_RETURN(mndAddAlterVgroupElectionBaselineActionToTrans(pMnode, pVgroup, pTrans, -1));
4,021✔
3146

3147
    SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
4,021✔
3148
    if (pDb == NULL) {
4,021✔
3149
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3150
      if (terrno != 0) code = terrno;
×
3151
      mError("trans:%d, vgid:%d failed to be balanced to dnode:%d, because db not exist", pTrans->id, vgid, dnodeId);
×
3152
      TAOS_RETURN(code);
×
3153
    }
3154

3155
    mndReleaseDb(pMnode, pDb);
4,021✔
3156
  } else {
3157
    mInfo("trans:%d, vgid:%d cant be balanced to dnode:%d, exist:%d, online:%d", pTrans->id, vgid, dnodeId, exist,
475✔
3158
          online);
3159
  }
3160

3161
  TAOS_RETURN(code);
4,496✔
3162
}
3163

3164
extern int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq);
3165

3166
int32_t mndProcessVgroupBalanceLeaderMsg(SRpcMsg *pReq) { return mndProcessVgroupBalanceLeaderMsgImp(pReq); }
2,137✔
3167

3168
#ifndef TD_ENTERPRISE
3169
int32_t mndProcessVgroupBalanceLeaderMsgImp(SRpcMsg *pReq) { return 0; }
3170
#endif
3171

3172
static int32_t mndCheckDnodeMemory(SMnode *pMnode, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pOldVgroup,
197,490✔
3173
                                   SVgObj *pNewVgroup, SArray *pArray) {
3174
  for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
593,584✔
3175
    SDnodeObj *pDnode = taosArrayGet(pArray, i);
396,094✔
3176
    bool       inVgroup = false;
396,094✔
3177
    int64_t    oldMemUsed = 0;
396,094✔
3178
    int64_t    newMemUsed = 0;
396,094✔
3179
    mDebug("db:%s, vgId:%d, check dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
396,094✔
3180
           pDnode->id, pDnode->memAvail, pDnode->memUsed);
3181
    for (int32_t j = 0; j < pOldVgroup->replica; ++j) {
1,140,140✔
3182
      SVnodeGid *pVgId = &pOldVgroup->vnodeGid[j];
744,046✔
3183
      if (pDnode->id == pVgId->dnodeId) {
744,046✔
3184
        oldMemUsed = mndGetVgroupMemory(pMnode, pOldDb, pOldVgroup);
313,474✔
3185
        inVgroup = true;
313,474✔
3186
      }
3187
    }
3188
    for (int32_t j = 0; j < pNewVgroup->replica; ++j) {
1,140,140✔
3189
      SVnodeGid *pVgId = &pNewVgroup->vnodeGid[j];
744,046✔
3190
      if (pDnode->id == pVgId->dnodeId) {
744,046✔
3191
        newMemUsed = mndGetVgroupMemory(pMnode, pNewDb, pNewVgroup);
313,474✔
3192
        inVgroup = true;
313,474✔
3193
      }
3194
    }
3195

3196
    mDebug("db:%s, vgId:%d, memory in dnode:%d, oldUsed:%" PRId64 ", newUsed:%" PRId64, pNewVgroup->dbName,
396,094✔
3197
           pNewVgroup->vgId, pDnode->id, oldMemUsed, newMemUsed);
3198

3199
    pDnode->memUsed = pDnode->memUsed - oldMemUsed + newMemUsed;
396,094✔
3200
    if (pDnode->memAvail - pDnode->memUsed <= 0) {
396,094✔
3201
      mError("db:%s, vgId:%d, no enough memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName,
×
3202
             pNewVgroup->vgId, pDnode->id, pDnode->memAvail, pDnode->memUsed);
3203
      TAOS_RETURN(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE);
×
3204
    } else if (inVgroup) {
396,094✔
3205
      mInfo("db:%s, vgId:%d, memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
313,474✔
3206
            pDnode->id, pDnode->memAvail, pDnode->memUsed);
3207
    } else {
3208
    }
3209
  }
3210
  return 0;
197,490✔
3211
}
3212

3213
int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pVgroup,
233,703✔
3214
                                  SArray *pArray, SVgObj *pNewVgroup) {
3215
  int32_t code = 0;
233,703✔
3216
  memcpy(pNewVgroup, pVgroup, sizeof(SVgObj));
233,703✔
3217

3218
  if (pVgroup->replica <= 0 || pVgroup->replica == pNewDb->cfg.replications) {
233,703✔
3219
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfigAction(pMnode, pTrans, pNewDb, pVgroup));
197,490✔
3220
    TAOS_CHECK_RETURN(mndCheckDnodeMemory(pMnode, pOldDb, pNewDb, pNewVgroup, pVgroup, pArray));
197,490✔
3221
    return 0;
197,490✔
3222
  }
3223

3224
  // mndTransSetGroupParallel(pTrans);
3225

3226
  if (pNewDb->cfg.replications == 3) {
36,213✔
3227
    mInfo("trans:%d, db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
31,409✔
3228
          pVgroup->vnodeGid[0].dnodeId);
3229

3230
    // add second
3231
    if (pNewVgroup->replica == 1) {
31,409✔
3232
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
31,409✔
3233
    }
3234

3235
    // learner stage
3236
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
30,726✔
3237
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
30,726✔
3238
    TAOS_CHECK_RETURN(
30,726✔
3239
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3240

3241
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[1]));
30,726✔
3242

3243
    // follower stage
3244
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
30,726✔
3245
    TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
30,726✔
3246
    TAOS_CHECK_RETURN(
30,726✔
3247
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3248

3249
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
30,726✔
3250

3251
    // add third
3252
    if (pNewVgroup->replica == 2) {
30,726✔
3253
      TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
30,726✔
3254
    }
3255

3256
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
27,823✔
3257
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
27,823✔
3258
    pNewVgroup->vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
27,823✔
3259
    TAOS_CHECK_RETURN(
27,823✔
3260
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3261
    TAOS_CHECK_RETURN(
27,823✔
3262
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
3263
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[2]));
27,823✔
3264

3265
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
27,823✔
3266
  } else if (pNewDb->cfg.replications == 1) {
4,804✔
3267
    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,430✔
3268
          pVgroup->dbName, pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId, pVgroup->vnodeGid[1].dnodeId,
3269
          pVgroup->vnodeGid[2].dnodeId);
3270

3271
    SVnodeGid del1 = {0};
3,430✔
3272
    SVnodeGid del2 = {0};
3,430✔
3273
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroup(pMnode, pTrans, pNewVgroup, pArray, &del1));
3,430✔
3274
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &del1, true));
3,430✔
3275
    TAOS_CHECK_RETURN(
3,430✔
3276
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3277
    TAOS_CHECK_RETURN(
3,430✔
3278
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
3279
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
3,430✔
3280

3281
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroup(pMnode, pTrans, pNewVgroup, pArray, &del2));
3,430✔
3282
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &del2, true));
3,430✔
3283
    TAOS_CHECK_RETURN(
3,430✔
3284
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3285
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
3,430✔
3286
  } else if (pNewDb->cfg.replications == 2) {
1,374✔
3287
    mInfo("trans:%d, db:%s, vgId:%d, will add 1 vnode, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
1,374✔
3288
          pVgroup->vnodeGid[0].dnodeId);
3289

3290
    // add second
3291
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray));
1,374✔
3292

3293
    // learner stage
3294
    pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
1,374✔
3295
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
1,374✔
3296
    TAOS_CHECK_RETURN(
1,374✔
3297
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3298

3299
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &pNewVgroup->vnodeGid[1]));
1,374✔
3300

3301
    // follower stage
3302
    pNewVgroup->vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
1,374✔
3303
    TAOS_CHECK_RETURN(mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[1].dnodeId));
1,374✔
3304
    TAOS_CHECK_RETURN(
1,374✔
3305
        mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId));
3306

3307
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup));
1,374✔
3308
  } else {
3309
    return -1;
×
3310
  }
3311

3312
  mndSortVnodeGid(pNewVgroup);
32,627✔
3313

3314
  {
3315
    SSdbRaw *pVgRaw = mndVgroupActionEncode(pNewVgroup);
32,627✔
3316
    if (pVgRaw == NULL) {
32,627✔
3317
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3318
      if (terrno != 0) code = terrno;
×
3319
      TAOS_RETURN(code);
×
3320
    }
3321
    if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
32,627✔
3322
      sdbFreeRaw(pVgRaw);
×
3323
      TAOS_RETURN(code);
×
3324
    }
3325
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
32,627✔
3326
    if (code != 0) {
32,627✔
3327
      mError("vgId:%d, failed to set raw status since %s at line:%d", pNewVgroup->vgId, tstrerror(code), __LINE__);
×
3328
      TAOS_RETURN(code);
×
3329
    }
3330
  }
3331

3332
  TAOS_RETURN(code);
32,627✔
3333
}
3334

3335
int32_t mndBuildRaftAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb, SDbObj *pNewDb, SVgObj *pVgroup,
×
3336
                                      SArray *pArray) {
3337
  int32_t code = 0;
×
3338
  SVgObj  newVgroup = {0};
×
3339
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
×
3340

3341
  if (pVgroup->replica <= 0 || pVgroup->replica == pNewDb->cfg.replications) {
×
3342
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfigAction(pMnode, pTrans, pNewDb, pVgroup));
×
3343
    TAOS_CHECK_RETURN(mndCheckDnodeMemory(pMnode, pOldDb, pNewDb, &newVgroup, pVgroup, pArray));
×
3344
    return 0;
×
3345
  }
3346

3347
  mndTransSetSerial(pTrans);
×
3348

3349
  mInfo("trans:%d, vgId:%d, alter vgroup, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3350
        pVgroup->syncConfChangeVer, pVgroup->version, pVgroup->replica);
3351

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

3356
    // add second
3357
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray));
×
3358
    // add third
3359
    TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray));
×
3360

3361
    // add learner stage
3362
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3363
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3364
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3365
    TAOS_CHECK_RETURN(
×
3366
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3367
    mInfo("trans:%d, vgId:%d, add change config, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id,
×
3368
          pVgroup->vgId, newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3369
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[1]));
×
3370
    mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3371
          newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3372
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[2]));
×
3373
    mInfo("trans:%d, vgId:%d, create vnode, syncConfChangeVer:%d, version:%d, replica:%d", pTrans->id, pVgroup->vgId,
×
3374
          newVgroup.syncConfChangeVer, pVgroup->version, pVgroup->replica);
3375

3376
    // check learner
3377
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3378
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3379
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3380
    TAOS_CHECK_RETURN(
×
3381
        mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId));
3382
    TAOS_CHECK_RETURN(
×
3383
        mndAddCheckLearnerCatchupAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[2].dnodeId));
3384

3385
    // change raft type
3386
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3387
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3388
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3389
    TAOS_CHECK_RETURN(
×
3390
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3391

3392
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3393

3394
    newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3395
    newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3396
    newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3397
    TAOS_CHECK_RETURN(
×
3398
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3399

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

3402
    SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3403
    if (pVgRaw == NULL) {
×
3404
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3405
      if (terrno != 0) code = terrno;
×
3406
      TAOS_RETURN(code);
×
3407
    }
3408
    if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
×
3409
      sdbFreeRaw(pVgRaw);
×
3410
      TAOS_RETURN(code);
×
3411
    }
3412
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3413
    if (code != 0) {
×
3414
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3415
             __LINE__);
3416
      TAOS_RETURN(code);
×
3417
    }
3418
  } else if (newVgroup.replica == 3 && pNewDb->cfg.replications == 1) {
×
3419
    mInfo("db:%s, vgId:%d, will remove 2 vnodes, vn:0 dnode:%d vn:1 dnode:%d vn:2 dnode:%d", pVgroup->dbName,
×
3420
          pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId, pVgroup->vnodeGid[1].dnodeId, pVgroup->vnodeGid[2].dnodeId);
3421

3422
    SVnodeGid del1 = {0};
×
3423
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del1));
×
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, &del1, true));
×
3431

3432
    SSdbRaw *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

3449
    SVnodeGid del2 = {0};
×
3450
    TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroupWithoutSave(pMnode, pTrans, &newVgroup, pArray, &del2));
×
3451

3452
    TAOS_CHECK_RETURN(
×
3453
        mndAddChangeConfigAction(pMnode, pTrans, pNewDb, pVgroup, &newVgroup, newVgroup.vnodeGid[0].dnodeId));
3454

3455
    TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup));
×
3456

3457
    TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &del2, true));
×
3458

3459
    pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3460
    if (pVgRaw == NULL) {
×
3461
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3462
      if (terrno != 0) code = terrno;
×
3463
      TAOS_RETURN(code);
×
3464
    }
3465
    if ((code = mndTransAppendRedolog(pTrans, pVgRaw)) != 0) {
×
3466
      sdbFreeRaw(pVgRaw);
×
3467
      TAOS_RETURN(code);
×
3468
    }
3469
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3470
    if (code != 0) {
×
3471
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3472
             __LINE__);
3473
      TAOS_RETURN(code);
×
3474
    }
3475
  } else {
3476
    return -1;
×
3477
  }
3478

3479
  mndSortVnodeGid(&newVgroup);
×
3480

3481
  {
3482
    SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
×
3483
    if (pVgRaw == NULL) {
×
3484
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3485
      if (terrno != 0) code = terrno;
×
3486
      TAOS_RETURN(code);
×
3487
    }
3488
    if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
×
3489
      sdbFreeRaw(pVgRaw);
×
3490
      TAOS_RETURN(code);
×
3491
    }
3492
    code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
×
3493
    if (code != 0) {
×
3494
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code),
×
3495
             __LINE__);
3496
      TAOS_RETURN(code);
×
3497
    }
3498
  }
3499

3500
  TAOS_RETURN(code);
×
3501
}
3502

3503
int32_t mndBuildRestoreAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *db, SVgObj *pVgroup, SDnodeObj *pDnode,
2,300✔
3504
                                         SDnodeObj *pAnotherDnode) {
3505
  int32_t code = 0;
2,300✔
3506
  SVgObj  newVgroup = {0};
2,300✔
3507
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
2,300✔
3508

3509
  mInfo("trans:%d, db:%s, vgId:%d, restore vnodes, vn:0 dnode:%d", pTrans->id, pVgroup->dbName, pVgroup->vgId,
2,300✔
3510
        pVgroup->vnodeGid[0].dnodeId);
3511

3512
  if (newVgroup.replica == 1) {
2,300✔
3513
    int selected = 0;
×
3514
    for (int i = 0; i < newVgroup.replica; i++) {
×
3515
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3516
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3517
        selected = i;
×
3518
      }
3519
    }
3520
    TAOS_CHECK_RETURN(mndAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, &newVgroup.vnodeGid[selected]));
×
3521
  } else if (newVgroup.replica == 2) {
2,300✔
3522
    for (int i = 0; i < newVgroup.replica; i++) {
×
3523
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3524
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3525
      } else {
3526
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3527
      }
3528
    }
3529
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pAnotherDnode));
×
3530

3531
    for (int i = 0; i < newVgroup.replica; i++) {
×
3532
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3533
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
×
3534
      } else {
3535
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3536
      }
3537
    }
3538
    TAOS_CHECK_RETURN(mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode));
×
3539

3540
    for (int i = 0; i < newVgroup.replica; i++) {
×
3541
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
×
3542
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
×
3543
      }
3544
    }
3545
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode));
×
3546
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pAnotherDnode));
×
3547
  } else if (newVgroup.replica == 3) {
2,300✔
3548
    for (int i = 0; i < newVgroup.replica; i++) {
9,200✔
3549
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
6,900✔
3550
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER;
2,300✔
3551
      } else {
3552
        newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
4,600✔
3553
      }
3554
    }
3555
    TAOS_CHECK_RETURN(mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode));
2,300✔
3556

3557
    for (int i = 0; i < newVgroup.replica; i++) {
9,200✔
3558
      newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER;
6,900✔
3559
      if (newVgroup.vnodeGid[i].dnodeId == pDnode->id) {
6,900✔
3560
      }
3561
    }
3562
    TAOS_CHECK_RETURN(mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode));
2,300✔
3563
  }
3564
  SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
2,300✔
3565
  if (pVgRaw == NULL) {
2,300✔
3566
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3567
    if (terrno != 0) code = terrno;
×
3568
    TAOS_RETURN(code);
×
3569
  }
3570
  if ((code = mndTransAppendCommitlog(pTrans, pVgRaw)) != 0) {
2,300✔
3571
    sdbFreeRaw(pVgRaw);
×
3572
    TAOS_RETURN(code);
×
3573
  }
3574
  code = sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
2,300✔
3575
  if (code != 0) {
2,300✔
3576
    mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVgroup.vgId, tstrerror(code), __LINE__);
×
3577
    TAOS_RETURN(code);
×
3578
  }
3579

3580
  TAOS_RETURN(code);
2,300✔
3581
}
3582

3583
static int32_t mndAddAdjustVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
×
3584
  return 0;
×
3585
}
3586

3587
typedef int32_t (*FpTransActionCb)(STrans *pTrans, SSdbRaw *pRaw);
3588

3589
static int32_t mndAddVgStatusAction(STrans *pTrans, SVgObj *pVg, ESdbStatus vgStatus, ETrnStage stage) {
73,327✔
3590
  int32_t         code = 0;
73,327✔
3591
  FpTransActionCb appendActionCb = (stage == TRN_STAGE_COMMIT_ACTION) ? mndTransAppendCommitlog : mndTransAppendRedolog;
73,327✔
3592
  SSdbRaw        *pRaw = mndVgroupActionEncode(pVg);
73,327✔
3593
  if (pRaw == NULL) {
73,327✔
3594
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3595
    if (terrno != 0) code = terrno;
×
3596
    goto _err;
×
3597
  }
3598
  if ((code = appendActionCb(pTrans, pRaw)) != 0) goto _err;
73,327✔
3599
  code = sdbSetRawStatus(pRaw, vgStatus);
73,327✔
3600
  if (code != 0) {
73,327✔
3601
    mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", pVg->vgId, tstrerror(code), __LINE__);
×
3602
    goto _err;
×
3603
  }
3604
  pRaw = NULL;
73,327✔
3605
  TAOS_RETURN(code);
73,327✔
3606
_err:
×
3607
  sdbFreeRaw(pRaw);
×
3608
  TAOS_RETURN(code);
×
3609
}
3610

3611
static int32_t mndAddDbStatusAction(STrans *pTrans, SDbObj *pDb, ESdbStatus dbStatus, ETrnStage stage) {
29,573✔
3612
  int32_t         code = 0;
29,573✔
3613
  FpTransActionCb appendActionCb = (stage == TRN_STAGE_COMMIT_ACTION) ? mndTransAppendCommitlog : mndTransAppendRedolog;
29,573✔
3614
  SSdbRaw        *pRaw = mndDbActionEncode(pDb);
29,573✔
3615
  if (pRaw == NULL) {
29,573✔
3616
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3617
    if (terrno != 0) code = terrno;
×
3618
    goto _err;
×
3619
  }
3620
  if ((code = appendActionCb(pTrans, pRaw)) != 0) goto _err;
29,573✔
3621
  code = sdbSetRawStatus(pRaw, dbStatus);
29,573✔
3622
  if (code != 0) {
29,573✔
3623
    mError("db:%s, failed to set raw status to ready, error:%s, line:%d", pDb->name, tstrerror(code), __LINE__);
×
3624
    goto _err;
×
3625
  }
3626
  pRaw = NULL;
29,573✔
3627
  TAOS_RETURN(code);
29,573✔
3628
_err:
×
3629
  sdbFreeRaw(pRaw);
×
3630
  TAOS_RETURN(code);
×
3631
}
3632

3633
int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
16,272✔
3634
  int32_t code = -1;
16,272✔
3635
  STrans *pTrans = NULL;
16,272✔
3636
  SDbObj  dbObj = {0};
16,272✔
3637
  SArray *pArray = mndBuildDnodesArray(pMnode, 0, NULL);
16,272✔
3638

3639
#if defined(USE_SHARED_STORAGE)
3640
  if (tsSsEnabled) {
16,272✔
3641
    code = TSDB_CODE_OPS_NOT_SUPPORT;
×
3642
    mError("vgId:%d, db:%s, shared storage exists, split vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
×
3643
    goto _OVER;
×
3644
  }
3645
#endif
3646

3647
  /*
3648
    if (pDb->cfg.withArbitrator) {
3649
      code = TSDB_CODE_OPS_NOT_SUPPORT;
3650
      mError("vgId:%d, db:%s, with arbitrator, split vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
3651
      goto _OVER;
3652
    }
3653
  */
3654

3655
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "split-vgroup");
16,272✔
3656
  if (pTrans == NULL) {
16,272✔
3657
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3658
    if (terrno != 0) code = terrno;
×
3659
    goto _OVER;
×
3660
  }
3661
  mndTransSetSerial(pTrans);
16,272✔
3662
  mInfo("trans:%d, used to split vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
16,272✔
3663

3664
  mndTransSetDbName(pTrans, pDb->name, NULL);
16,272✔
3665
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
16,272✔
3666
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
16,238✔
3667

3668
  SVgObj newVg1 = {0};
16,238✔
3669
  memcpy(&newVg1, pVgroup, sizeof(SVgObj));
16,238✔
3670
  mInfo("vgId:%d, vgroup info before split, replica:%d hashBegin:%u hashEnd:%u", newVg1.vgId, newVg1.replica,
16,238✔
3671
        newVg1.hashBegin, newVg1.hashEnd);
3672
  for (int32_t i = 0; i < newVg1.replica; ++i) {
52,987✔
3673
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg1.vgId, i, newVg1.vnodeGid[i].dnodeId);
36,749✔
3674
  }
3675

3676
  if (newVg1.replica == 1) {
16,238✔
3677
    TAOS_CHECK_GOTO(mndAddVnodeToVgroup(pMnode, pTrans, &newVg1, pArray), NULL, _OVER);
5,639✔
3678

3679
    newVg1.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER;
5,639✔
3680
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
5,639✔
3681
                    _OVER);
3682
    TAOS_CHECK_GOTO(mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVg1, &newVg1.vnodeGid[1]), NULL, _OVER);
5,639✔
3683

3684
    newVg1.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER;
5,639✔
3685
    TAOS_CHECK_GOTO(mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[1].dnodeId), NULL, _OVER);
5,639✔
3686
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
5,639✔
3687
                    _OVER);
3688

3689
    TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
5,639✔
3690
  } else if (newVg1.replica == 3) {
10,599✔
3691
    SVnodeGid del1 = {0};
9,912✔
3692
    TAOS_CHECK_GOTO(mndRemoveVnodeFromVgroup(pMnode, pTrans, &newVg1, pArray, &del1), NULL, _OVER);
9,912✔
3693
    TAOS_CHECK_GOTO(mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg1, &del1, true), NULL, _OVER);
9,912✔
3694
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[0].dnodeId), NULL,
9,912✔
3695
                    _OVER);
3696
    TAOS_CHECK_GOTO(mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[1].dnodeId), NULL,
9,912✔
3697
                    _OVER);
3698
  } else {
3699
    // goto _OVER;
3700
  }
3701

3702
  for (int32_t i = 0; i < newVg1.replica; ++i) {
48,714✔
3703
    TAOS_CHECK_GOTO(mndAddDisableVnodeWriteAction(pMnode, pTrans, pDb, &newVg1, newVg1.vnodeGid[i].dnodeId), NULL,
32,476✔
3704
                    _OVER);
3705
  }
3706
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
16,238✔
3707

3708
  SVgObj newVg2 = {0};
16,238✔
3709
  memcpy(&newVg2, &newVg1, sizeof(SVgObj));
16,238✔
3710
  newVg1.replica = 1;
16,238✔
3711
  newVg1.hashEnd = newVg1.hashBegin / 2 + newVg1.hashEnd / 2;
16,238✔
3712
  memset(&newVg1.vnodeGid[1], 0, sizeof(SVnodeGid));
16,238✔
3713

3714
  newVg2.replica = 1;
16,238✔
3715
  newVg2.hashBegin = newVg1.hashEnd + 1;
16,238✔
3716
  memcpy(&newVg2.vnodeGid[0], &newVg2.vnodeGid[1], sizeof(SVnodeGid));
16,238✔
3717
  memset(&newVg2.vnodeGid[1], 0, sizeof(SVnodeGid));
16,238✔
3718

3719
  mInfo("vgId:%d, vgroup info after split, replica:%d hashrange:[%u, %u] vnode:0 dnode:%d", newVg1.vgId, newVg1.replica,
16,238✔
3720
        newVg1.hashBegin, newVg1.hashEnd, newVg1.vnodeGid[0].dnodeId);
3721
  for (int32_t i = 0; i < newVg1.replica; ++i) {
32,476✔
3722
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg1.vgId, i, newVg1.vnodeGid[i].dnodeId);
16,238✔
3723
  }
3724
  mInfo("vgId:%d, vgroup info after split, replica:%d hashrange:[%u, %u] vnode:0 dnode:%d", newVg2.vgId, newVg2.replica,
16,238✔
3725
        newVg2.hashBegin, newVg2.hashEnd, newVg2.vnodeGid[0].dnodeId);
3726
  for (int32_t i = 0; i < newVg1.replica; ++i) {
32,476✔
3727
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg2.vgId, i, newVg2.vnodeGid[i].dnodeId);
16,238✔
3728
  }
3729

3730
  // alter vgId and hash range
3731
  int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
16,238✔
3732
  int32_t srcVgId = newVg1.vgId;
16,238✔
3733
  newVg1.vgId = maxVgId;
16,238✔
3734
  TAOS_CHECK_GOTO(mndAddNewVgPrepareAction(pMnode, pTrans, &newVg1), NULL, _OVER);
16,238✔
3735
  TAOS_CHECK_GOTO(mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg1), NULL, _OVER);
16,238✔
3736

3737
  maxVgId++;
16,238✔
3738
  srcVgId = newVg2.vgId;
16,238✔
3739
  newVg2.vgId = maxVgId;
16,238✔
3740
  TAOS_CHECK_GOTO(mndAddNewVgPrepareAction(pMnode, pTrans, &newVg2), NULL, _OVER);
16,238✔
3741
  TAOS_CHECK_GOTO(mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg2), NULL, _OVER);
16,238✔
3742

3743
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1), NULL, _OVER);
16,238✔
3744
  TAOS_CHECK_GOTO(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg2), NULL, _OVER);
16,238✔
3745

3746
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
16,238✔
3747
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
16,238✔
3748
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_REDO_ACTION), NULL, _OVER);
16,238✔
3749

3750
  // update db status
3751
  memcpy(&dbObj, pDb, sizeof(SDbObj));
16,238✔
3752
  if (dbObj.cfg.pRetensions != NULL) {
16,238✔
3753
    dbObj.cfg.pRetensions = taosArrayDup(pDb->cfg.pRetensions, NULL);
×
3754
    if (dbObj.cfg.pRetensions == NULL) {
×
3755
      code = terrno;
×
3756
      goto _OVER;
×
3757
    }
3758
  }
3759
  dbObj.vgVersion++;
16,238✔
3760
  dbObj.updateTime = taosGetTimestampMs();
16,238✔
3761
  dbObj.cfg.numOfVgroups++;
16,238✔
3762
  TAOS_CHECK_GOTO(mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION), NULL, _OVER);
16,238✔
3763

3764
  // adjust vgroup replica
3765
  if (pDb->cfg.replications != newVg1.replica) {
16,238✔
3766
    SVgObj tmpGroup = {0};
10,599✔
3767
    TAOS_CHECK_GOTO(mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg1, pArray, &tmpGroup), NULL, _OVER);
10,599✔
3768
  } else {
3769
    TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
5,639✔
3770
  }
3771

3772
  if (pDb->cfg.replications != newVg2.replica) {
14,638✔
3773
    SVgObj tmpGroup = {0};
8,999✔
3774
    TAOS_CHECK_GOTO(mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg2, pArray, &tmpGroup), NULL, _OVER);
8,999✔
3775
  } else {
3776
    TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
5,639✔
3777
  }
3778

3779
  TAOS_CHECK_GOTO(mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
13,335✔
3780

3781
  // commit db status
3782
  dbObj.vgVersion++;
13,335✔
3783
  dbObj.updateTime = taosGetTimestampMs();
13,335✔
3784
  TAOS_CHECK_GOTO(mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION), NULL, _OVER);
13,335✔
3785

3786
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
13,335✔
3787
  code = 0;
13,335✔
3788

3789
_OVER:
16,272✔
3790
  taosArrayDestroy(pArray);
16,272✔
3791
  mndTransDrop(pTrans);
16,272✔
3792
  taosArrayDestroy(dbObj.cfg.pRetensions);
16,272✔
3793
  TAOS_RETURN(code);
16,272✔
3794
}
3795

3796
extern int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq);
3797

3798
static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) { return mndProcessSplitVgroupMsgImp(pReq); }
16,652✔
3799

3800
#ifndef TD_ENTERPRISE
3801
int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq) { return 0; }
3802
#endif
3803

3804
static int32_t mndSetBalanceVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
14,490✔
3805
                                              SDnodeObj *pSrc, SDnodeObj *pDst) {
3806
  int32_t code = 0;
14,490✔
3807
  SVgObj  newVg = {0};
14,490✔
3808
  memcpy(&newVg, pVgroup, sizeof(SVgObj));
14,490✔
3809
  mInfo("vgId:%d, vgroup info before balance, replica:%d", newVg.vgId, newVg.replica);
14,490✔
3810
  for (int32_t i = 0; i < newVg.replica; ++i) {
42,690✔
3811
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
28,200✔
3812
  }
3813

3814
  TAOS_CHECK_RETURN(mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pDst->id));
14,490✔
3815
  TAOS_CHECK_RETURN(mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pSrc->id));
14,490✔
3816

3817
  {
3818
    SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
14,490✔
3819
    if (pRaw == NULL) {
14,490✔
3820
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3821
      if (terrno != 0) code = terrno;
×
3822
      TAOS_RETURN(code);
×
3823
    }
3824
    if ((code = mndTransAppendCommitlog(pTrans, pRaw)) != 0) {
14,490✔
3825
      sdbFreeRaw(pRaw);
×
3826
      TAOS_RETURN(code);
×
3827
    }
3828
    code = sdbSetRawStatus(pRaw, SDB_STATUS_READY);
14,490✔
3829
    if (code != 0) {
14,490✔
3830
      mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", newVg.vgId, tstrerror(code), __LINE__);
×
3831
      TAOS_RETURN(code);
×
3832
    }
3833
  }
3834

3835
  mInfo("vgId:%d, vgroup info after balance, replica:%d", newVg.vgId, newVg.replica);
14,490✔
3836
  for (int32_t i = 0; i < newVg.replica; ++i) {
42,690✔
3837
    mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId);
28,200✔
3838
  }
3839
  TAOS_RETURN(code);
14,490✔
3840
}
3841

3842
static int32_t mndBalanceVgroupBetweenDnode(SMnode *pMnode, STrans *pTrans, SDnodeObj *pSrc, SDnodeObj *pDst,
14,490✔
3843
                                            SHashObj *pBalancedVgroups) {
3844
  void   *pIter = NULL;
14,490✔
3845
  int32_t code = -1;
14,490✔
3846
  SSdb   *pSdb = pMnode->pSdb;
14,490✔
3847

3848
  while (1) {
8,915✔
3849
    SVgObj *pVgroup = NULL;
23,405✔
3850
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
23,405✔
3851
    if (pIter == NULL) break;
23,405✔
3852
    if (taosHashGet(pBalancedVgroups, &pVgroup->vgId, sizeof(int32_t)) != NULL) {
23,405✔
3853
      sdbRelease(pSdb, pVgroup);
8,224✔
3854
      continue;
8,224✔
3855
    }
3856

3857
    bool existInSrc = false;
15,181✔
3858
    bool existInDst = false;
15,181✔
3859
    for (int32_t i = 0; i < pVgroup->replica; ++i) {
44,072✔
3860
      SVnodeGid *pGid = &pVgroup->vnodeGid[i];
28,891✔
3861
      if (pGid->dnodeId == pSrc->id) existInSrc = true;
28,891✔
3862
      if (pGid->dnodeId == pDst->id) existInDst = true;
28,891✔
3863
    }
3864

3865
    if (!existInSrc || existInDst) {
15,181✔
3866
      sdbRelease(pSdb, pVgroup);
691✔
3867
      continue;
691✔
3868
    }
3869

3870
    SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
14,490✔
3871
    if (pDb == NULL) {
14,490✔
3872
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3873
      if (terrno != 0) code = terrno;
×
3874
      mError("vgId:%d, balance vgroup can't find db obj dbName:%s", pVgroup->vgId, pVgroup->dbName);
×
3875
      goto _OUT;
×
3876
    }
3877

3878
    if (pDb->cfg.withArbitrator) {
14,490✔
3879
      mInfo("vgId:%d, db:%s, with arbitrator, balance vgroup not allowed", pVgroup->vgId, pVgroup->dbName);
×
3880
      goto _OUT;
×
3881
    }
3882

3883
    code = mndSetBalanceVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, pSrc, pDst);
14,490✔
3884
    if (code == 0) {
14,490✔
3885
      code = taosHashPut(pBalancedVgroups, &pVgroup->vgId, sizeof(int32_t), &pVgroup->vgId, sizeof(int32_t));
14,490✔
3886
    }
3887

3888
  _OUT:
14,490✔
3889
    mndReleaseDb(pMnode, pDb);
14,490✔
3890
    sdbRelease(pSdb, pVgroup);
14,490✔
3891
    sdbCancelFetch(pSdb, pIter);
14,490✔
3892
    break;
14,490✔
3893
  }
3894

3895
  return code;
14,490✔
3896
}
3897

3898
static int32_t mndBalanceVgroup(SMnode *pMnode, SRpcMsg *pReq, SArray *pArray) {
9,381✔
3899
  int32_t   code = -1;
9,381✔
3900
  int32_t   numOfVgroups = 0;
9,381✔
3901
  STrans   *pTrans = NULL;
9,381✔
3902
  SHashObj *pBalancedVgroups = NULL;
9,381✔
3903

3904
  pBalancedVgroups = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
9,381✔
3905
  if (pBalancedVgroups == NULL) goto _OVER;
9,381✔
3906

3907
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "balance-vgroup");
9,381✔
3908
  if (pTrans == NULL) {
9,381✔
3909
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
3910
    if (terrno != 0) code = terrno;
×
3911
    goto _OVER;
×
3912
  }
3913
  mndTransSetSerial(pTrans);
9,381✔
3914
  mInfo("trans:%d, used to balance vgroup", pTrans->id);
9,381✔
3915
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
9,381✔
3916
  TAOS_CHECK_GOTO(mndTransCheckConflictWithCompact(pMnode, pTrans), NULL, _OVER);
9,041✔
3917
  TAOS_CHECK_GOTO(mndTransCheckConflictWithRetention(pMnode, pTrans), NULL, _OVER);
9,007✔
3918

3919
  while (1) {
14,490✔
3920
    taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
23,497✔
3921
    for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
101,420✔
3922
      SDnodeObj *pDnode = taosArrayGet(pArray, i);
77,923✔
3923
      mInfo("dnode:%d, equivalent vnodes:%d others:%d support:%d, score:%f", pDnode->id, pDnode->numOfVnodes,
77,923✔
3924
            pDnode->numOfSupportVnodes, pDnode->numOfOtherNodes, mndGetDnodeScore(pDnode, 0, 1));
3925
    }
3926

3927
    SDnodeObj *pSrc = taosArrayGet(pArray, taosArrayGetSize(pArray) - 1);
23,497✔
3928
    SDnodeObj *pDst = taosArrayGet(pArray, 0);
23,497✔
3929

3930
    float srcScore = mndGetDnodeScore(pSrc, -1, 1);
23,497✔
3931
    float dstScore = mndGetDnodeScore(pDst, 1, 1);
23,497✔
3932
    mInfo("trans:%d, after balance, src dnode:%d score:%f, dst dnode:%d score:%f", pTrans->id, pSrc->id, dstScore,
23,497✔
3933
          pDst->id, dstScore);
3934

3935
    if (srcScore > dstScore - 0.000001) {
23,497✔
3936
      code = mndBalanceVgroupBetweenDnode(pMnode, pTrans, pSrc, pDst, pBalancedVgroups);
14,490✔
3937
      if (code == 0) {
14,490✔
3938
        pSrc->numOfVnodes--;
14,490✔
3939
        pDst->numOfVnodes++;
14,490✔
3940
        numOfVgroups++;
14,490✔
3941
        continue;
14,490✔
3942
      } else {
3943
        mInfo("trans:%d, no vgroup need to balance from dnode:%d to dnode:%d", pTrans->id, pSrc->id, pDst->id);
×
3944
        break;
×
3945
      }
3946
    } else {
3947
      mInfo("trans:%d, no vgroup need to balance any more", pTrans->id);
9,007✔
3948
      break;
9,007✔
3949
    }
3950
  }
3951

3952
  if (numOfVgroups <= 0) {
9,007✔
3953
    mInfo("no need to balance vgroup");
×
3954
    code = 0;
×
3955
  } else {
3956
    mInfo("start to balance vgroup, numOfVgroups:%d", numOfVgroups);
9,007✔
3957
    if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
9,007✔
3958
    code = TSDB_CODE_ACTION_IN_PROGRESS;
9,007✔
3959
  }
3960

3961
_OVER:
9,381✔
3962
  taosHashCleanup(pBalancedVgroups);
9,381✔
3963
  mndTransDrop(pTrans);
9,381✔
3964
  TAOS_RETURN(code);
9,381✔
3965
}
3966

3967
static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq) {
10,953✔
3968
  SMnode *pMnode = pReq->info.node;
10,953✔
3969
  int32_t code = -1;
10,953✔
3970
  SArray *pArray = NULL;
10,953✔
3971
  void   *pIter = NULL;
10,953✔
3972
  int64_t curMs = taosGetTimestampMs();
10,953✔
3973
  int64_t tss = taosGetTimestampMs();
10,953✔
3974

3975
  SBalanceVgroupReq req = {0};
10,953✔
3976
  if (tDeserializeSBalanceVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) {
10,953✔
3977
    code = TSDB_CODE_INVALID_MSG;
×
3978
    goto _OVER;
×
3979
  }
3980

3981
  mInfo("start to balance vgroup");
10,953✔
3982
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_BALANCE_VGROUP)) != 0) {
10,953✔
3983
    goto _OVER;
162✔
3984
  }
3985

3986
  if (sdbGetSize(pMnode->pSdb, SDB_MOUNT) > 0) {
10,791✔
3987
    code = TSDB_CODE_MND_MOUNT_NOT_EMPTY;
×
3988
    goto _OVER;
×
3989
  }
3990

3991
  while (1) {
32,975✔
3992
    SDnodeObj *pDnode = NULL;
43,766✔
3993
    pIter = sdbFetch(pMnode->pSdb, SDB_DNODE, pIter, (void **)&pDnode);
43,766✔
3994
    if (pIter == NULL) break;
43,766✔
3995
    if (!mndIsDnodeOnline(pDnode, curMs)) {
34,385✔
3996
      sdbCancelFetch(pMnode->pSdb, pIter);
1,410✔
3997
      code = TSDB_CODE_MND_HAS_OFFLINE_DNODE;
1,410✔
3998
      mError("failed to balance vgroup since %s, dnode:%d", terrstr(), pDnode->id);
1,410✔
3999
      sdbRelease(pMnode->pSdb, pDnode);
1,410✔
4000
      goto _OVER;
1,410✔
4001
    }
4002

4003
    sdbRelease(pMnode->pSdb, pDnode);
32,975✔
4004
  }
4005

4006
  pArray = mndBuildDnodesArray(pMnode, 0, NULL);
9,381✔
4007
  if (pArray == NULL) {
9,381✔
4008
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4009
    if (terrno != 0) code = terrno;
×
4010
    goto _OVER;
×
4011
  }
4012

4013
  if (taosArrayGetSize(pArray) < 2) {
9,381✔
4014
    mInfo("no need to balance vgroup since dnode num less than 2");
×
4015
    code = 0;
×
4016
  } else {
4017
    code = mndBalanceVgroup(pMnode, pReq, pArray);
9,381✔
4018
  }
4019

4020
  if (tsAuditLevel >= AUDIT_LEVEL_CLUSTER) {
9,381✔
4021
    int64_t tse = taosGetTimestampMs();
9,381✔
4022
    double  duration = (double)(tse - tss);
9,381✔
4023
    duration = duration / 1000;
9,381✔
4024
    auditRecord(pReq, pMnode->clusterId, "balanceVgroup", "", "", req.sql, req.sqlLen, duration, 0);
9,381✔
4025
  }
4026

4027
_OVER:
10,953✔
4028
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
10,953✔
4029
    mError("failed to balance vgroup since %s", tstrerror(code));
1,946✔
4030
  }
4031

4032
  taosArrayDestroy(pArray);
10,953✔
4033
  tFreeSBalanceVgroupReq(&req);
10,953✔
4034
  TAOS_RETURN(code);
10,953✔
4035
}
4036

4037
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; }
97,408,987✔
4038

4039
bool mndVgroupInDnode(SVgObj *pVgroup, int32_t dnodeId) {
3,680✔
4040
  for (int i = 0; i < pVgroup->replica; i++) {
9,188✔
4041
    if (pVgroup->vnodeGid[i].dnodeId == dnodeId) return true;
7,808✔
4042
  }
4043
  return false;
1,380✔
4044
}
4045

4046
static void *mndBuildCompactVnodeReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen, int64_t compactTs,
98,899✔
4047
                                     STimeWindow tw, bool metaOnly, bool force, ETsdbOpType type,
4048
                                     ETriggerType triggerType) {
4049
  SCompactVnodeReq compactReq = {0};
98,899✔
4050
  compactReq.dbUid = pDb->uid;
98,899✔
4051
  compactReq.compactStartTime = compactTs;
98,899✔
4052
  compactReq.tw = tw;
98,899✔
4053
  compactReq.metaOnly = metaOnly;
98,899✔
4054
  compactReq.force = force;
98,899✔
4055
  compactReq.optrType = type;
98,899✔
4056
  compactReq.triggerType = triggerType;
98,899✔
4057
  tstrncpy(compactReq.db, pDb->name, TSDB_DB_FNAME_LEN);
98,899✔
4058

4059
  mInfo("vgId:%d, build compact vnode config req", pVgroup->vgId);
98,899✔
4060
  int32_t contLen = tSerializeSCompactVnodeReq(NULL, 0, &compactReq);
98,899✔
4061
  if (contLen < 0) {
98,899✔
4062
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
4063
    return NULL;
×
4064
  }
4065
  contLen += sizeof(SMsgHead);
98,899✔
4066

4067
  void *pReq = taosMemoryMalloc(contLen);
98,899✔
4068
  if (pReq == NULL) {
98,899✔
4069
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
4070
    return NULL;
×
4071
  }
4072

4073
  SMsgHead *pHead = pReq;
98,899✔
4074
  pHead->contLen = htonl(contLen);
98,899✔
4075
  pHead->vgId = htonl(pVgroup->vgId);
98,899✔
4076

4077
  if (tSerializeSCompactVnodeReq((char *)pReq + sizeof(SMsgHead), contLen, &compactReq) < 0) {
98,899✔
4078
    taosMemoryFree(pReq);
×
4079
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
4080
    return NULL;
×
4081
  }
4082
  *pContLen = contLen;
98,899✔
4083
  return pReq;
98,899✔
4084
}
4085

4086
static int32_t mndAddCompactVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t compactTs,
55,067✔
4087
                                        STimeWindow tw, bool metaOnly, bool force, ETsdbOpType type,
4088
                                        ETriggerType triggerType) {
4089
  int32_t      code = 0;
55,067✔
4090
  STransAction action = {0};
55,067✔
4091
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
55,067✔
4092

4093
  int32_t contLen = 0;
55,067✔
4094
  void   *pReq =
4095
      mndBuildCompactVnodeReq(pMnode, pDb, pVgroup, &contLen, compactTs, tw, metaOnly, force, type, triggerType);
55,067✔
4096
  if (pReq == NULL) {
55,067✔
4097
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4098
    if (terrno != 0) code = terrno;
×
4099
    TAOS_RETURN(code);
×
4100
  }
4101

4102
  action.pCont = pReq;
55,067✔
4103
  action.contLen = contLen;
55,067✔
4104
  action.msgType = TDMT_VND_COMPACT;
55,067✔
4105

4106
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
55,067✔
4107
    taosMemoryFree(pReq);
×
4108
    TAOS_RETURN(code);
×
4109
  }
4110

4111
  TAOS_RETURN(code);
55,067✔
4112
}
4113

4114
int32_t mndBuildCompactVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t compactTs,
55,067✔
4115
                                    STimeWindow tw, bool metaOnly, bool force, ETsdbOpType type,
4116
                                    ETriggerType triggerType) {
4117
  TAOS_CHECK_RETURN(
55,067✔
4118
      mndAddCompactVnodeAction(pMnode, pTrans, pDb, pVgroup, compactTs, tw, metaOnly, force, type, triggerType));
4119
  return 0;
55,067✔
4120
}
4121

4122
int32_t mndBuildTrimVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int64_t startTs,
43,832✔
4123
                                 STimeWindow tw, ETsdbOpType type, ETriggerType triggerType) {
4124
  int32_t      code = 0;
43,832✔
4125
  STransAction action = {0};
43,832✔
4126
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
43,832✔
4127

4128
  int32_t contLen = 0;
43,832✔
4129
  // reuse SCompactVnodeReq as SVTrimDbReq
4130
  void *pReq = mndBuildCompactVnodeReq(pMnode, pDb, pVgroup, &contLen, startTs, tw, false, false, type, triggerType);
43,832✔
4131
  if (pReq == NULL) {
43,832✔
4132
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4133
    if (terrno != 0) code = terrno;
×
4134
    TAOS_RETURN(code);
×
4135
  }
4136

4137
  action.pCont = pReq;
43,832✔
4138
  action.contLen = contLen;
43,832✔
4139
  action.msgType = TDMT_VND_TRIM;
43,832✔
4140

4141
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
43,832✔
4142
    taosMemoryFree(pReq);
×
4143
    TAOS_RETURN(code);
×
4144
  }
4145

4146
  TAOS_RETURN(code);
43,832✔
4147
}
4148

4149
static int32_t mndProcessSetVgroupKeepVersionReq(SRpcMsg *pReq) {
1,068✔
4150
  SMnode *pMnode = pReq->info.node;
1,068✔
4151
  int32_t code = TSDB_CODE_SUCCESS;
1,068✔
4152
  STrans *pTrans = NULL;
1,068✔
4153
  SVgObj *pVgroup = NULL;
1,068✔
4154

4155
  SMndSetVgroupKeepVersionReq req = {0};
1,068✔
4156
  if (tDeserializeSMndSetVgroupKeepVersionReq(pReq->pCont, pReq->contLen, &req) != 0) {
1,068✔
4157
    code = TSDB_CODE_INVALID_MSG;
×
4158
    goto _OVER;
×
4159
  }
4160

4161
  mInfo("start to set vgroup keep version, vgId:%d, keepVersion:%" PRId64, req.vgId, req.keepVersion);
1,068✔
4162

4163
  // Check permission
4164
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_WRITE_DB)) != 0) {
1,068✔
4165
    goto _OVER;
×
4166
  }
4167

4168
  // Get vgroup
4169
  pVgroup = mndAcquireVgroup(pMnode, req.vgId);
1,068✔
4170
  if (pVgroup == NULL) {
1,068✔
4171
    code = TSDB_CODE_MND_VGROUP_NOT_EXIST;
×
4172
    mError("vgId:%d not exist, failed to set keep version", req.vgId);
×
4173
    goto _OVER;
×
4174
  }
4175

4176
  // Create transaction
4177
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq, "set-vgroup-keep-version");
1,068✔
4178
  if (pTrans == NULL) {
1,068✔
4179
    code = terrno != 0 ? terrno : TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4180
    mndReleaseVgroup(pMnode, pVgroup);
×
4181
    goto _OVER;
×
4182
  }
4183

4184
  mndTransSetSerial(pTrans);
1,068✔
4185
  mInfo("trans:%d, used to set vgroup keep version, vgId:%d keepVersion:%" PRId64, pTrans->id, req.vgId,
1,068✔
4186
        req.keepVersion);
4187

4188
  // Update SVgObj's keepVersion in mnode
4189
  SVgObj newVgroup = {0};
1,068✔
4190
  memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
1,068✔
4191
  newVgroup.keepVersion = req.keepVersion;
1,068✔
4192
  newVgroup.keepVersionTime = taosGetTimestampMs();
1,068✔
4193

4194
  // Add prepare log for SDB vgroup update (execute in PREPARE stage, before redo actions)
4195
  SSdbRaw *pCommitRaw = mndVgroupActionEncode(&newVgroup);
1,068✔
4196
  if (pCommitRaw == NULL) {
1,068✔
4197
    code = TSDB_CODE_OUT_OF_MEMORY;
×
4198
    mndReleaseVgroup(pMnode, pVgroup);
×
4199
    goto _OVER;
×
4200
  }
4201
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
1,068✔
4202
    code = terrno;
×
4203
    sdbFreeRaw(pCommitRaw);
×
4204
    mndReleaseVgroup(pMnode, pVgroup);
×
4205
    goto _OVER;
×
4206
  }
4207
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) {
1,068✔
4208
    mError("vgId:%d, failed to set raw status to ready, error:%s, line:%d", pVgroup->vgId, tstrerror(code), __LINE__);
×
4209
    sdbFreeRaw(pCommitRaw);
×
4210
    mndReleaseVgroup(pMnode, pVgroup);
×
4211
    goto _OVER;
×
4212
  }
4213

4214
  // Prepare message for vnodes
4215
  SVndSetKeepVersionReq vndReq = {.keepVersion = req.keepVersion};
1,068✔
4216
  int32_t               reqLen = tSerializeSVndSetKeepVersionReq(NULL, 0, &vndReq);
1,068✔
4217
  int32_t               contLen = reqLen + sizeof(SMsgHead);
1,068✔
4218

4219
  // Send to all replicas of the vgroup
4220
  for (int32_t i = 0; i < pVgroup->replica; ++i) {
4,272✔
4221
    SMsgHead *pHead = taosMemoryMalloc(contLen);
3,204✔
4222
    if (pHead == NULL) {
3,204✔
4223
      code = TSDB_CODE_OUT_OF_MEMORY;
×
4224
      mndReleaseVgroup(pMnode, pVgroup);
×
4225
      goto _OVER;
×
4226
    }
4227

4228
    pHead->contLen = htonl(contLen);
3,204✔
4229
    pHead->vgId = htonl(pVgroup->vgId);
3,204✔
4230

4231
    if (tSerializeSVndSetKeepVersionReq((char *)pHead + sizeof(SMsgHead), reqLen, &vndReq) < 0) {
3,204✔
4232
      taosMemoryFree(pHead);
×
4233
      code = TSDB_CODE_OUT_OF_MEMORY;
×
4234
      mndReleaseVgroup(pMnode, pVgroup);
×
4235
      goto _OVER;
×
4236
    }
4237

4238
    // Get dnode and add action to transaction
4239
    SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId);
3,204✔
4240
    if (pDnode == NULL) {
3,204✔
4241
      taosMemoryFree(pHead);
×
4242
      code = TSDB_CODE_MND_DNODE_NOT_EXIST;
×
4243
      mndReleaseVgroup(pMnode, pVgroup);
×
4244
      goto _OVER;
×
4245
    }
4246

4247
    STransAction action = {0};
3,204✔
4248
    action.epSet = mndGetDnodeEpset(pDnode);
3,204✔
4249
    mndReleaseDnode(pMnode, pDnode);
3,204✔
4250
    action.pCont = pHead;
3,204✔
4251
    action.contLen = contLen;
3,204✔
4252
    action.msgType = TDMT_VND_SET_KEEP_VERSION;
3,204✔
4253
    action.acceptableCode = TSDB_CODE_VND_STOPPED;
3,204✔
4254

4255
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
3,204✔
4256
      taosMemoryFree(pHead);
×
4257
      code = terrno;
×
4258
      mndReleaseVgroup(pMnode, pVgroup);
×
4259
      goto _OVER;
×
4260
    }
4261
  }
4262

4263
  mndReleaseVgroup(pMnode, pVgroup);
1,068✔
4264

4265
  // Prepare and execute transaction
4266
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
1,068✔
4267
    goto _OVER;
×
4268
  }
4269

4270
  code = TSDB_CODE_ACTION_IN_PROGRESS;
1,068✔
4271

4272
_OVER:
1,068✔
4273
  if (pTrans != NULL) mndTransDrop(pTrans);
1,068✔
4274

4275
  return code;
1,068✔
4276
}
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