2团
Published on 2024-08-16 / 19 Visits
0
0

MongoDB删除分片操作手册

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" })

待转移完毕后,重新执行移除分片命令,得到如下提示:

image-miwh.png

6.完成

此时,shard4分片已被转移,可以安全的关闭shard实例。


Comment