1.查看集群分片
登录Mongo shell,查看集群当前的分片信息:
db.adminCommand( { listShards: 1 } )
得到集群当前分片状态如下所示:
{
shards: [
{
_id: 'shard1',
host: 'shard1/10.14.2.11:27001,10.14.2.2:27001,10.14.2.26:27001',
state: 1
},
{
_id: 'shard2',
host: 'shard2/10.14.2.11:27002,10.14.2.26:27002,10.14.2.6:27002',
state: 1
},
{
_id: 'shard3',
host: 'shard3/10.14.2.24:27003,10.14.2.26:27003,10.14.2.6:27003',
state: 1
},
{
_id: 'shard4',
host: 'shard4/10.14.2.11:27004,10.14.2.2:27004,10.14.2.24:27004',
state: 1
},
{
_id: 'shard5',
host: 'shard5/10.14.2.2:27005,10.14.2.24:27005,10.14.2.6:27005',
state: 1
}
],
ok: 1,
operationTime: Timestamp({ t: 1698034755, i: 1689 }),
'$clusterTime': {
clusterTime: Timestamp({ t: 1698034755, i: 1689 }),
signature: {
hash: Binary(Buffer.from("3dfd6a51076aaec1a6f6ef66fd6480d451b1343d", "hex"), 0),
keyId: Long("7292435404353962007")
}
}
}
可知当前集群中存在5个分片。
2.检查均衡器状态
sh.getBalancerState()
# 输出为true
在移除分片前,需要确保balancer处于开启状态,这样才能保证被移除的分片数据转移至其他分片中,避免数据丢失。
3.移除分片
use admin
db.runCommand( { removeShard: "shard4" } )
执行如上操作,将在后台执行移除分片操作,输出如下所示:
{
msg: 'draining started successfully',
state: 'started',
shard: 'shard4',
note: 'you need to drop or movePrimary these databases',
dbsToMove: [ 'collection_name' ],
ok: 1,
operationTime: Timestamp({ t: 1698034787, i: 3587 }),
'$clusterTime': {
clusterTime: Timestamp({ t: 1698034787, i: 3720 }),
signature: {
hash: Binary(Buffer.from("e55c91a4d4791a4d09717d8ea1d62adbb673cc23", "hex"), 0),
keyId: Long("7292435404353962007")
}
}
}
由输出可知,移除分片shard4任务已开启,dbsToMove字段表示当前分片上待转移至其他分片的collection。
4.检查移除进度
db.runCommand( { removeShard: "shard4" } )
再次执行移除操作,得到如下输出:
{
msg: 'draining ongoing',
state: 'ongoing',
remaining: { chunks: Long("608"), dbs: Long("1"), jumboChunks: Long("0") },
note: 'you need to drop or movePrimary these databases',
dbsToMove: [ 'collection_name' ],
ok: 1,
operationTime: Timestamp({ t: 1698034810, i: 6695 }),
'$clusterTime': {
clusterTime: Timestamp({ t: 1698034810, i: 8462 }),
signature: {
hash: Binary(Buffer.from("758e3a43368e3781914895c34d63f03cd54a51ac", "hex"), 0),
keyId: Long("7292435404353962007")
}
}
}
由输出可知,当前移除操作正在进行中,有一个collection正在转移(参见remaining.dbs),有608个chunk等待被转移至其他分片(参见remaining.chunks字段)。
多次执行上述命令,可发现chunks字段数值不断减少,说明shard4上的数据正在转移过程中。
5. 迁移没有分片的数据
如果当前被移除的分片是一个或多个数据库的primary shard,上面会存储没有分片的数据;如果不是,则跳过当前章节。
在集群中,没有分片的数据库只会将数据存放在一个分片上,这个分片就是这个数据库的主分片(不同的数据库可以有不同的主分片)。
5.1 查看未分片collection
sh.status()
db.printShardingStatus()
使用以上两个命令中任一,可以查询未分片collection的存放分片信息。例如:
{ "_id" : "products", "partitioned" : true, "primary" : "mongodb0" }
上面表示products数据库使用mongodb0作为主分片。
5.2 转移分片
将数据库迁移至另一个分片,需要使用movePrimary命令,如下所示:
db.runCommand( { movePrimary: "products", to: "mongodb1" })
上面的命令,将products数据库从mongodb0分片转移至mongodb1分片。
6.完成迁移
执行以下命令:
use admin
db.runCommand( { removeShard: "shard4" } )
得到如下输出:
{
"msg" : "draining ongoing",
"state" : "ongoing",
"remaining" : {
"chunks" : NumberLong(0),
"dbs" : NumberLong(2),
"jumboChunks" : NumberLong(0)
},
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [
"collection_name",
],
"ok" : 1.0,
"operationTime" : Timestamp(1698045036, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1698045036, 568),
"signature" : {
"hash" : BinData(0, "rO0tK8XKhuVmXTVQ9U14PiQzsDM="),
"keyId" : NumberLong(7292435404353962007)
}
}
}
参照章节5,将collection_name(按照实际情况更换)数据库的存放位置迁移至其他分片:
db.runCommand( { movePrimary: "collection_name", to: "shard3" })
待转移完毕后,重新执行移除分片命令,得到如下提示:
6.完成
此时,shard4分片已被转移,可以安全的关闭shard实例。