目前集群架构
mongos + config server * 3 + shard * 2 ( replication * 3)
首先使用mongo终端连接到mongos.
检查 balancer 是否开启 (必须为开启)
mongos> sh.getBalancerState()
true
确定要删除的分片的名字,查看分片状态
mongos> db.printShardingStatus()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5dfba2392238d44d0911df5a")
}
shards:
{ "_id" : "shard1", "host" : "rs-shard1/xxx.xxx.xxx.xxx:27017,xxx.xxx.xxx.xxx:27017,xxx.xxx.xxx.xxx:27017", "state" : 1 }
{ "_id" : "shard2", "host" : "rs-shard2/xxx.xxx.xxx.xxx:27017,xxx.xxx.xxx.xxx:27017,xxx.xxx.xxx.xxx:27017", "state" : 1 }
databases:
{ "_id" : "results", "primary" : "shard1", "partitioned" : false, "version" : { "uuid" : UUID("da62d295-1932-4f2b-b815-289215c748cc"), "lastMod" : 1 } }
{ "_id" : "config", "primary" : "config", "partitioned" : true }
shards._id 字段列出了每个分片的名字.
从分片中迁移数据块
在 admin 数据库中,运行 removeShard 命令.运行之后会开始将这个分片的数据块”转移”到其他分片的过程
mongos> use admin
mongos> db.runCommand( { removeShard: "shard1" } )
{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "shard1",
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [
"aaa"
],
"ok" : 1,
"operationTime" : Timestamp(1637806857, 31),
"$clusterTime" : {
"clusterTime" : Timestamp(1637806857, 52),
"signature" : {
"hash" : BinData(0,"0S8Z96nkykT9TRyNZRter/75zpk="),
"keyId" : NumberLong("6972904148362592258")
}
}
}
检查迁移的状态
mongos> db.runCommand( { removeShard: "shard1" } )
{
"msg" : "draining ongoing",
"state" : "ongoing",
"remaining" : {
"chunks" : NumberLong(4255),
"dbs" : NumberLong(6),
"jumboChunks" : NumberLong(0)
},
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [
"aaa"
],
"ok" : 1,
"operationTime" : Timestamp(1637819063, 5),
"$clusterTime" : {
"clusterTime" : Timestamp(1637819067, 376),
"signature" : {
"hash" : BinData(0,"jpm5n4yuZN5+hp56RBebdCFuyvs="),
"keyId" : NumberLong("6972904148362592258")
}
}
}
在输出结果中, remaining 文档显示的是MongoDB必须迁移到其他分片的数据块中剩余的数据块数量与”primary”在这个分片的数据库数量.
在 remaining 字段变为0之前,持续运行 removeShard 命令检查状态.这个命令需要在 admin 数据库上运行,在其他库可以使用 sh.adminCommond 命令操作.
迁移没有分片的数据
如果这个分片是一个或多个数据库的 primary shard, 上面会存储没有分片的数据,如果不是,则跳至 完成迁移 任务.
在集群中,没有分片的数据库只会将数据存放在一个分片上,这个分片就是这个数据库的主分片.(不同的数据库可以有不同的主分片.)
注意: 在分片迁移未完成之前不要执行以下操作。
1. 使用 db.printShardingStatus() 命令可以看到,有一些库是的主分片(primary shard)就是我们要迁移的分片。比如:results 就使用 shard1 作为主分片。
{ "_id" : "results", "primary" : "shard1", "partitioned" : false, "version" : { "uuid" : UUID("da62d295-1932-4f2b-b815-289215c748cc"), "lastMod" : 1 } }
2. 将数据库迁移到另一个分片,需要使用 movePrimary. 将所有的剩余的未分片的数据从 shard1 迁移至 shard2 上:
mongos> db.runCommand( { movePrimary: "products", to: "shard2" })
迁移成功后会返回:
{ "primary" : "mongodb1", "ok" : 1 }
完成迁移
为了清除所有的元信息,并结束删除分片的过程,再次执行 removeShard 命令:
mongos> db.runCommand( { removeShard: "shard1" } )
在完成时会显示出成功的信息:
{
"msg" : "removeshard completed successfully",
"state" : "completed",
"shard" : "shard1",
"ok" : 1
}
一旦 state 的值变为 “completed”,就可以安全地停止 shard1 分片上的monod进程.