MongoDB——从集群中删除分片,根据官网教程实际操作记录

从mongo分片集群中删除分片,其中mongo为docker容器启动。

当前状态

docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
25a8a909d180        redis30000          0.27%               7.91MiB / 3.692GiB   0.21%               143MB / 9.5MB       0B / 20.2MB         5
ed0e541e8088        mongos              0.19%               19.23MiB / 1GiB      1.88%               480MB / 249MB       0B / 0B             47
ed7841a8e162        mongoshard3         0.60%               84.78MiB / 1GiB      8.28%               47.3MB / 34.6MB     0B / 8.53MB         33
9e82f149c2b5        mongoshard2         1.67%               89.49MiB / 1GiB      8.74%               62.3MB / 46.2MB     0B / 109MB          41
f17f9a1841db        mongoshard1         0.80%               91.19MiB / 1GiB      8.91%               62.2MB / 45.9MB     0B / 106MB          41
6cd12b08bd83        mongoconfig         5.10%               129.7MiB / 1GiB      12.66%              167MB / 161MB       0B / 914MB          90

用mongos操作集群,删除 replshard3

查看当前均衡是否开启、分片状态

[root@bogon mongo]# docker exec -it mongos mongo 192.168.1.22:27017 -eval "sh.getBalancerState()"
MongoDB shell version v4.0.24
connecting to: mongodb://192.168.1.22:27017/test?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a83c008b-c69f-47bc-90c1-7b5f547b354d") }
MongoDB server version: 4.0.24
true
docker exec -it mongos mongo 192.168.1.22:27017 -eval "sh.status()"
docker exec -it mongos mongo 192.168.1.22:27017 -eval "db.adminCommand( { listShards: 1 } )"
docker exec -it mongos mongo 192.168.1.22:27017 -eval "sh.getBalancerState()"
docker exec -it mongos mongo 192.168.1.22:27017 -eval "db.printShardingStatus()"
docker exec -it mongos mongo 192.168.1.22:27017/admin -eval "db.runCommand( { listShards: 1 } )"
docker exec -it mongos mongo 192.168.1.22:27017/test -eval "db.adminCommand( { listShards: 1 } )"
docker exec -it mongos mongo 192.168.1.22:27017/admin -eval "db.adminCommand( { listShards: 1 } )"
以上三句都可执行
以下语句无法执行
docker exec -it mongos mongo 192.168.1.22:27017/test -eval "db.runCommand( { listShards: 1 } )"
{
    "ok" : 0,
    "errmsg" : "listShards may only be run against the admin database.",
    "code" : 13,
    ...

开始执行删除  replshard3

docker exec -it mongos mongo 192.168.1.22:27017/admin -eval "db.runCommand( { removeShard: 'replshard3' } )"
{
    "msg" : "draining started successfully",
    "state" : "started",
    "shard" : "replshard3",
    "note" : "you need to drop or movePrimary these databases",
    "dbsToMove" : [
        "dragon_1251"
    ],
    "ok" : 1
}

再次执行可查询状态

docker exec -it mongos mongo 192.168.1.22:27017/admin -eval "db.runCommand( { removeShard: 'replshard3' } )"
{
    "msg" : "draining ongoing",
    "state" : "ongoing",
    "remaining" : {
        "chunks" : NumberLong(320),
        "dbs" : NumberLong(1),
        "jumboChunks" : NumberLong(0)
    },
    "note" : "you need to drop or movePrimary these databases",
    "dbsToMove" : [
        "dragon_1251"
    ],
    "ok" : 1
}
docker exec -it mongos mongo 192.168.1.22:27017/admin -eval "db.runCommand( { removeShard: 'replshard3' } )"
{
    "msg" : "draining ongoing",
    "state" : "ongoing",
    "remaining" : {
        "chunks" : NumberLong(211),
        "dbs" : NumberLong(1),
        "jumboChunks" : NumberLong(0)
    },
    "note" : "you need to drop or movePrimary these databases",
    "dbsToMove" : [
        "dragon_1251"
    ],
    "ok" : 1
}

直到 remaining 中 chunks 都为0

 

下面迁主,

对于没有分片,且以replshard3作为主分片的库,需要迁主,命令如下,

(花费时间视数据量和带宽而定)

docker exec -it mongos mongo 192.168.1.22:27017/admin -eval "db.runCommand({movePrimary:'dragon_1251', to:'replshard1'})"
{
    "ok" : 1,
    "operationTime" : Timestamp(1621307578, 26),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1621307578, 26),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

 

迁走replshard3上的主分片后 ,再次执行移除 replshard3分片,确定完成删片

 docker exec -it mongos mongo 192.168.1.22:27017/admin -eval "db.runCommand( { removeShard: 'replshard3' } )"
MongoDB shell version v4.0.24
{
    "msg" : "removeshard completed successfully",
    "state" : "completed",
    "shard" : "replshard3",
    "ok" : 1,
    "operationTime" : Timestamp(1621307651, 2),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1621307651, 2),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

自些replshard3分片删除完成,数据已迁到replshard1上,再看分片状态将不再存在replshard3。

现在可以停止关于replshard3的所有进程,

[root@bogon mongo]# docker stop mongoshard3
mongoshard3
[root@bogon mongo]# 
[root@bogon mongo]# docker rm  mongoshard3
mongoshard3
[root@bogon mongo]#

 

以下转自官网教程 : https://mongoing.com/docs/tutorial/remove-shards-from-cluster.html

 

要删除一个 shard ,必须确定这个分片的数据已经被迁移到了集群中的其他分片中.这篇教程描述了如何安全地迁移数据和删除分片.

这篇教程描述的是如何安全地删除 一个 分片, 不要 使用这篇教程迁移一整个集群到新系统中.要想将整个集群迁移到一个新的系统,需要挨个迁移每个分片.

要想删除一个分片,需要首先使用 mongo 终端连接到 mongos ,并使用这篇文档中的一系列任务完成删除工作:

To remove a shard, first connect to one of the cluster’s mongos instances using mongo shell. Then use the sequence of tasks in this document to remove a shard from the cluster.

Ensure the Balancer Process is Enabled

为了使得数据迁移能够成功, balancer 必须 是开启的.在 mongo 终端中使用 sh.getBalancerState() 确定这一点.参见 均衡器选项 以获得更多信息.

确定要删除的分片的名字

要确定删除分片的名字,使用 mongo 终端连接到 mongos 或者:

shards._id 字段列出了每个分片的名字.

从分片中迁移数据块

在 admin 数据库中,运行 removeShard 命令.运行之后会开始将这个分片的数据块”转移”到其他分片的过程,比如,对一个命名为 mongodb0 的分片,运行:

use admin
db.runCommand( { removeShard: "mongodb0" } )

这个操作是立刻返回的,返回为:

{
    "msg" : "draining started successfully",
    "state" : "started",
    "shard" : "mongodb0",
    "ok" : 1
}

Depending on your network capacity and the amount of data, this operation can take from a few minutes to several days to complete.

检查迁移的状态

检查迁移的状态,再次在 admin 数据库运行 removeShard 命令,比如,对一个命名为 mongodb0 的分片,运行:

use admin
db.runCommand( { removeShard: "mongodb0" } )

这条命令返回类似如下的输出:

{
     "msg" : "draining ongoing",
    "state" : "ongoing",
    "remaining" : {
        "chunks" : 42,
        "dbs" : 1
    },
    "ok" : 1
}

在输出结果中, remaining 文档显示的是MongoDB必须迁移到其他分片的数据块中剩余的数据块数量与”primary”在这个分片的数据库数量.

在 remaining 字段变为0之前,持续运行 removeShard 命令检查状态.这个命令需要在 admin 数据库上运行,在其他库可以使用 sh._adminCommand 命令操作.

迁移没有分片的数据

如果这个分片是一个或多个数据库的 primary shard ,上面会存储没有分片的数据,如果不是,则跳过 完成迁移 任务.

在集群中,没有分片的数据库只会将数据存放在一个分片上,这个分片就是这个数据库的主分片.(不同的数据库可以有不同的主分片.)

警告

Do not perform this procedure until you have finished draining the shard.

  1. To determine if the shard you are removing is the primary shard for any of the cluster’s databases, issue one of the following methods:

    在返回的文档中, databases 字段列出了所有数据库和它的主分片.比如,以下的 databases 字段显示了 products 数据库使用 mongodb0 作为主分片.

    {  "_id" : "products",  "partitioned" : true,  "primary" : "mongodb0" }
    
  2. 将数据库迁移到另一个分片,需要使用 movePrimary 命令.使用如下命令将所有的剩余的未分片的数据从 mongodb0 迁移到 mongodb1 上.

    db.runCommand( { movePrimary: "products", to: "mongodb1" })
    

    This command does not return until MongoDB completes moving all data, which may take a long time. The response from this command will resemble the following:

    { "primary" : "mongodb1", "ok" : 1 }
    

警告

这个命令直到全部数据迁移完成才会返回,可能会花费较长时间.最后返回的结果类似这样:

完成迁移

为了清除所有的元信息,并结束删除分片的过程,再次执行 removeShard , 比如,对 mongodb0 这个分片,执行:

use admin
db.runCommand( { removeShard: "mongodb0" } )

在完成时会显示出成功的信息:

{
    "msg" : "removeshard completed successfully",
    "state" : "completed",
    "shard" : "mongodb0",
    "ok" : 1
}

一旦 state 的值变为 “completed”,就可以安全地停止 mongodb0` 分片上的monod进程.

上一篇:MongoDB 分片的原理、搭建、应用 (转)


下一篇:MongoDB 分片问题汇总