将自管理分片集群转换为副本集
本教程介绍如何将 分片集群转换为非分副本集。要将副本集转换为分片集群,请参阅将自管理副本集转换为分片集群。有关分片的集群的更多信息,请参阅分片文档。
开始之前
从 MongoDB 8.0 开始,您可以使用 directShardOperations
角色来执行需要您直接对分片执行命令的维护操作。
警告
使用directShardOperations
角色运行命令可能会导致集群停止正常工作,并可能导致数据损坏。 仅将directShardOperations
角色用于维护目的或在MongoDB支持的指导下使用。 执行完维护操作后,请停止使用directShardOperations
角色。
版本兼容性
本教程中的步骤需要MongoDB 6.0 或更高版本。
授权
fsync
和fsyncUnlock
命令需要fsync
授权动作,可以通过hostManager
角色或自定义角色分配该操作。
安排集群转换
通常不执行数据块迁移、重新分片和模式转换时转换集群。
禁用负载均衡器并锁定集群
要禁用负载均衡器并锁集群:
要停止负载均衡器,运行:
sh.stopBalancer() 要验证负载均衡器是否已禁用,运行以下命令并确保输出为
false
:sh.getBalancerState() 要锁分片集群以防止数据库写入,运行:
db.getSiblingDB( "admin" ).fsyncLock() 要确认锁,运行:
db.getSiblingDB( "admin" ).aggregate( [ { $currentOp: { } }, { $facet: { "locked": [ { $match: { $and: [ { fsyncLock: { $exists: true } } ] } } ], "unlocked": [ { $match: { fsyncLock: { $exists: false } } } ] } }, { $project: { "fsyncLocked": { $gt: [ { $size: "$locked" }, 0 ] }, "fsyncUnlocked": { $gt: [ { $size: "$unlocked" }, 0 ] } } } ] ) 确保输出显示
fsyncLocked
istrue
,这意味着集群已锁定:[ { fsyncLocked: true }, { fsyncUnlocked: false } ]
将具有单个分片的集群转换为副本集
对于只有一个分片的分片集群,该分片包含完整数据集。使用以下步骤将该集群转换为非分片副本集:
重新配置应用程序以连接到托管单个分片的副本集的主节点,该系统将成为新的副本集。
从
mongod
中删除--shardsvr
选项提示
更改
--shardsvr
选项将会更改mongod
侦听传入连接的端口。
单分片集群现在是一个非分片副本集,将接受针对数据集的读写操作。
将分片集群转换为副本集
锁定分片集群并禁用负载均衡器后,除了分片集群之外,还部署新的副本集。副本集必须有足够的容量来容纳当前所有组合分片的所有数据文件。在数据传输完成之前,请勿将应用程序配置为连接到新副本集。
重新配置应用程序或停止所有
mongos
实例。如果停止所有mongos
实例,应用程序将无法从数据库读取数据。如果停止所有mongos
实例,请启动一个临时mongos
实例,应用程序无法在数据迁移过程中访问权限该实例。使用 mongodump 和 mongorestore 将数据从
mongos
实例迁移到新副本集。运行 时排除
config
mongorestore
数据库。使用--nsExclude
选项,如下示例所示:mongorestore --nsExclude="config.*" <connection-string> /data/backup 注意
并非所有数据库上的所有集合都必须进行分片。不要仅迁移分片集合。确保所有数据库和所有集合均正确迁移。
将应用程序重新配置为使用非分片副本集,而不是
mongos
实例。将分片集群转换为副本集后,将应用程序使用的连接字符串更新为副本集的连接字符串。然后,重新启动您的应用程序。
应用程序现在将使用未分片的副本集进行读取和写入。您现在可以停用其余未使用的分片集群基础架构。
后续步骤
将分片集群转换为副本集后,请执行以下步骤来解锁集群:
要解锁集群并允许恢复数据库写入,运行:
db.getSiblingDB( "admin" ).fsyncLock() 要确认解锁,运行:
db.getSiblingDB("admin").aggregate( [ { $currentOp: { } }, { $facet: { "locked": [ { $match: { $and: [ { fsyncLock: { $exists: true } } ] } } ], "unlocked": [ { $match: { fsyncLock: { $exists: false } } } ] } }, { $project: { "fsyncLocked": { $gt: [ { $size: "$locked" }, 0 ] }, "fsyncUnlocked": { $gt: [ { $size: "$unlocked" }, 0 ] } } } ] ) 确保输出显示
fsyncLocked
isfalse
,这意味着集群已解锁:[ { fsyncLocked: false }, { fsyncUnlocked: true } ]