Docs 菜单
Docs 主页
/
MongoDB Manual
/ / / /

恢复自管理分片集群

在此页面上

此过程从现有备份快照(例如 逻辑卷经理(逻辑卷管理器(LVM) ) 快照)恢复分片集群。源分片集群和目标分片分片集群必须具有相同数量的分片。 有关为分片分片集群的所有组件创建逻辑卷管理器(LVM)快照的信息,请参阅使用文件系统Atlas 备份快照备份自管理分片集群。

注意

要使用 mongodump mongorestore 作为分片集群的备份策略,请参阅使用数据库转储备份自管理分片集群。

分片集群还可以使用以下协调备份和恢复流程之一,以确保跨分片事务的原子性:

对于使用 AES256-GCM 加密模式的加密存储引擎AES256-GCM 要求每个进程使用带有密钥的唯一计数器块值。

对于使用 AES256-GCM 密码配置的加密存储引擎

  • 从热备份恢复
    从 4.2 开始,如果从通过“热”备份(即 mongod 正在运行)获取的文件进行恢复,MongoDB 可以在启动时检测到“脏”密钥,并自动滚动更新数据库密钥以避免重用 IV(初始化向量)。
  • 从冷备份恢复

    不过,如果从通过“冷”备份(即 mongod 未运行)获取的文件进行恢复,MongoDB 无法在启动时检测到“脏”密钥,重用 IV 将导致机密性和完整性保证失效。

    从 4.2 版开始,为了避免从冷文件系统快照恢复后重用密钥,MongoDB 添加了一个新的命令行选项 --eseDatabaseKeyRollover。使用 --eseDatabaseKeyRollover 选项启动时,mongod 实例会滚动使用 AES256-GCM 密码配置的数据库密钥并退出。

此过程使用默认配置为配置服务器副本集 (CSRS) 和每个分片副本集启动一个新的副本集。要为恢复的 CSRS 和分片使用不同的副本集配置,您必须重新配置副本集。

如果源集群运行正常且可访问,请将mongoshell Shell连接到每个副本集的主节点 (primary node in the replica set)副本集。接下来,运行rs.conf() 以查看副本配置文档。

如果您无法访问源分片集群的一个或多个组件,请参阅任何现有的内部文档,重新构建每个分片副本集和配置服务器副本集的配置要求。

存储空间要求
确保目标主机硬件具有足够的空闲存储空间用于恢复数据。如果目标主机包含要保留的现有分片集群数据,请确保有足够的存储空间用于存储现有数据和恢复数据。
LVM 要求
对于逻辑卷管理器(LVM)快照,您必须至少有一个逻辑卷管理器(LVM)托管卷群组和一个逻辑卷,为提取的快照数据提供足够的可用空间。
MongoDB 版本要求

确保目标主机和源主机具有相同的 MongoDB Server 版本。要检查主机可用的 MongoDB 版本,请从终端或 Shell 运行 mongod --version

有关安装的完整文档,请参阅安装 MongoDB

关闭正在运行的 MongoDB 进程

如果恢复到现有集群,请关闭目标主机上的 mongodmongos 进程。

对于运行 mongos 的主机,将 mongo Shell 连接到 mongos 并从 admin 数据库运行 db.shutdownServer()

use admin
db.shutdownServer()

对于运行 mongod 的主机,请将 mongo Shell 连接 mongod 并运行 db.hello()

准备数据目录

在目标主机上为恢复的数据库文件创建一个目录。确保运行 mongod 的用户对该目录下的所有文件和子文件夹都有读取、写入和执行权限:

sudo mkdir /path/to/mongodb
sudo chown -R mongodb:mongodb /path/to/mongodb
sudo chmod -R 770 /path/to/mongodb

/path/to/mongodb 替换为所创建数据目录的路径。在 RHEL / CentOS、Amazon Linux 和 SuSE 上,默认用户名为 mongod

准备日志目录

在目标主机上为 mongod 日志文件创建一个目录。确保运行 mongod 的用户对该目录下的所有文件和子文件夹都有读取、写入和执行权限:

sudo mkdir /path/to/mongodb/logs
sudo chown -R mongodb:mongodb /path/to/mongodb/logs
sudo chmod -R 770 /path/to/mongodb/logs

/path/to/mongodb/logs 替换为您创建的日志目录的路径。在RHEL / CentOS、Amazon Linux 和 SUSE 上,默认用户名是 mongod

创建配置文件

此过程假设使用配置文件启动 mongod

在首选位置创建配置文件。确保运行 mongod 的用户对配置文件具有读写权限:

sudo touch /path/to/mongod.conf
sudo chown mongodb:mongodb /path/to/mongodb/mongod.conf
sudo chmod 644 /path/to/mongodb/mongod.conf

RHEL / CentOS、Amazon Linux 和 SuSE 上,默认用户名为 mongod

在偏好的文本编辑器中打开配置文件,并根据部署要求进行修改。或者,如果您有权访问 mongod 的原始配置文件,请将其复制到目标主机的偏好位置。

重要

验证配置文件是否包含以下设置:

1

选择与偏好备份方法对应的标签页:

  1. 在目标主机上挂载 LVM 快照。挂载 LVM 快照的具体步骤取决于您的 LVM 配置。

    以下示例假定使用“ 使用文件系统Atlas 备份快照备份和恢复自托管部署” 过程中的“ 创建快照” 步骤创建了逻辑卷管理器(LVM)快照。

    lvcreate --size 250GB --name mongod-datafiles-snapshot vg0
    gzip -d -c mongod-datafiles-snapshot.gz | dd o/dev/vg0/mongod-datafiles-snapshot
    mount /dev/vg0/mongod-datafiles-snapshot /snap/mongodb

    此示例可能不适用于所有可实现的逻辑卷管理器(LVM)配置。要查看更加完整的逻辑卷管理器(LVM)恢复指南,请参阅您所用系统的逻辑卷管理器(LVM)文档。

  2. mongod数据文件从快照挂载复制到 B. Prepare the Target Host for Restoration中创建的数据目录:

    cp -a /snap/mongodb/path/to/mongodb /path/to/mongodb

    -a 选项会将源路径的内容递归复制到目标路径,并同时保留文件夹和文件权限。

  3. 注释掉或省略以下配置文件设置:

    #replication
    # replSetName: myCSRSName
    #sharding
    # clusterRole: configsvr

    要使用配置文件启动 mongod,请在命令行中指定 --config 选项,指明配置文件的完整路径。

    mongod --config /path/to/mongodb/mongod.conf

    如果要从经过命名空间过滤的快照中恢复,请指定 --restore 选项。

    mongod --config /path/to/mongod/mongod.conf --restore

    如果已将 mongod 配置为系统服务运行,请使用系统服务管理器推荐的进程启动它。

    mongod 启动后,使用 mongo Shell 与其连接。

  1. 使存储在所选备份介质中的数据文件可在托管上访问。 这可能需要安装备份卷,在实用软件中打开备份,或使用其他工具将数据提取到磁盘。 有关访问备份中包含的数据的说明,请参阅首选备份工具的文档。

  2. mongod数据文件从备份数据位置复制到B. Prepare the Target Host for Restoration中创建的数据目录:

    cp -a /backup/mongodb/path/to/mongodb /path/to/mongodb

    -a 选项会将源路径的内容递归复制到目标路径,并同时保留文件夹和文件权限。

  3. 注释掉或省略以下配置文件设置:

    #replication
    # replSetName: myCSRSName
    #sharding
    # clusterRole: configsvr
  4. 要使用配置文件启动 mongod,请在命令行中指定 --config 选项,指明配置文件的完整路径。

    mongod --config /path/to/mongodb/mongod.conf

    如果从经过命名空间筛选的快照恢复,还请指定--restore选项。

    mongod --config /path/to/mongod/mongod.conf --restore

    注意

    仅限Cloud Manager或MongoDB Ops Manager

    如果要手动恢复Cloud Manager或MongoDB Ops Manager备份,则必须在初创企业前指定 disableLogicalSessionCacheRefresh服务器参数。

    mongod --config /path/to/mongodb/mongod.conf \
    --setParameter disableLogicalSessionCacheRefresh=true

    如果已将 mongod 配置为系统服务运行,请使用系统服务管理器推荐的进程启动它。

    mongod 启动后,使用 mongo Shell 与其连接。

2

使用 db.dropDatabase() 删除 local 数据库:

use local
db.dropDatabase()
3

仅当从经过命名空间过滤的快照中还原时,才需要此步骤。

对于每个分片,找到具有以下名称格式的已过滤文件列表:<shardRsID>-filteredFileList.txt。此文件包含具有以下格式的 JSON 对象列表:

{
"filename":"file1",
"ns":"sampleDb1.sampleCollection1",
"uuid": "3b241101-e2bb-4255-8caf-4136c566a962"
}

将每个分片文件中的每个 JSON 对象添加到 local 数据库中的新 db.systems.collections_to_restore 集合中。您可以忽略 nsuuid 字段为空的条目。插入条目时,必须将 uuid 字段作为 UUID() 类型插入。

4

仅当从经过命名空间过滤的快照中还原时,才需要此步骤。

插入所有条目后,运行以下命令:

use admin
db.runCommand({"_configsvrRunRestore":1})
5

如果满足以下所有条件,则可以跳过此步骤:

  • 在此过程中,任何分片成员主机的主机名都不会发生变更。

  • 在此过程中,任何分片副本集的名称都不会发生变更。

配置数据库中的 shards 集合发出以下 find() 方法。将 <shardName> 替换为分片的名称。默认情况下,分片名称是其副本集名称。如果使用 addShard 命令添加分片指定自定义 name,则您必须将 name 指定为 <shardName>

use config
db.shards.find( { "_id" : "<shardName>" } )

此操作将返回类似于以下内容的文档:

{
"_id" : "shard1",
"host" : "myShardName/alpha.example.net:27018,beta.example.net:27018,charlie.example.net:27018",
"state" : 1
}

重要

_id 值必须与相应分片的 _id : "shardIdentity" 文档中的 shardName 值匹配。稍后在此过程中恢复分片时,请验证 shards_id 字段是否与分片的 shardName 值匹配。

使用 updateOne() 方法更新 hosts 字符串以反映分片的计划副本集名称和主机名列表。例如,以下操作将分片的 host 连接字符串更新为 "_id" : "shard1"

db.shards.updateOne(
{ "_id" : "shard1" },
{ $set : { "host" : "myNewShardName/repl1.example.net:27018,repl2.example.net:27018,repl3.example.net:27018" } }
)

重复此过程,直到所有分片元数据准确反映集群中每个分片的计划副本集名称和主机名列表。

注意

如果您不知道分片名称,请使用空过滤器文档 {}shards 集合发出 find() 方法:

use config
db.shards.find({})

结果集中的每个文档都表示集群中的一个分片。对于每个文档,检查 host 字段中是否有与相关分片匹配的连接字符串,即匹配的副本集名称和成员主机名列表。使用该文档的 _id 代替 <shardName>

6

关闭 mongod。取消注释或添加以下配置文件选项:

replication
replSetName: myNewCSRSName
sharding
clusterRole: configsvr

如果要更改副本集名称,必须在继续之前使用新名称更新 replSetName 字段。

使用更新的配置文件启动 mongod

mongod --config /path/to/mongodb/mongod.conf

如果已将 mongod 配置为系统服务运行,请使用系统服务管理器推荐的进程启动它。

mongod 启动后,使用 mongo Shell 与其连接。

7

使用 rs.initiate() 和默认设置启动副本集。

rs.initiate()

操作完成后,使用 rs.status() 检查该成员是否已成为主节点

8

对于 CSRS 中的每个副本集节点,在其主机上启动 mongod。成功启动集群的所有剩余节点后,将 mongo Shell 连接到主副本集节点。在主节点中,使用 rs.add() 方法添加副本集的每个节点。将副本集名称作为前缀,然后是节点的 mongod 进程的主机名和端口:

rs.add("config2.example.net:27019")
rs.add("config3.example.net:27019")

如果要添加具有特定副本 member 配置设置的成员,则可以向 rs.add() 传递一个用于定义成员主机名及部署所需的任何 members 设置的文档。

rs.add(
{
"host" : "config2.example.net:27019",
priority: <int>,
votes: <int>,
tags: <int>
}
)

每个新成员执行初始同步,从而与主节点同步。根据要同步的数据量、网络拓扑结构和运行状况以及每台主机的功率等因素,可能需要较长时间才能完成初始同步。

添加其他节点时,副本集可能会选出一个新的主节点。使用 rs.status() 确定哪个节点是当前的主节点。只能从主节点运行 rs.add()

9

rs.reconfig() 方法根据作为参数传递的配置文档更新副本集配置。您必须对副本集的主节点运行 reconfig()

参考步骤 A. Review Replica Set Configurations 所确定的副本集原始配置文件输出,并根据需要应用设置。

1

选择与偏好备份方法对应的标签页:

  1. 在目标主机上挂载 LVM 快照。挂载 LVM 快照的具体步骤取决于您的 LVM 配置。

    以下示例假定使用“ 使用文件系统Atlas 备份快照备份和恢复自托管部署” 过程中的“ 创建快照” 步骤创建了逻辑卷管理器(LVM)快照。

    lvcreate --size 250GB --name mongod-datafiles-snapshot vg0
    gzip -d -c mongod-datafiles-snapshot.gz | dd o/dev/vg0/mongod-datafiles-snapshot
    mount /dev/vg0/mongod-datafiles-snapshot /snap/mongodb

    此示例可能不适用于所有可实现的逻辑卷管理器(LVM)配置。要查看更加完整的逻辑卷管理器(LVM)恢复指南,请参阅您所用系统的逻辑卷管理器(LVM)文档。

  2. mongod 数据文件从快照挂载复制到 B. Prepare the Target Host for Restoration 中创建的数据目录:

    cp -a /snap/mongodb/path/to/mongodb /path/to/mongodb

    -a 选项会将源路径的内容递归复制到目标路径,并同时保留文件夹和文件权限。

  3. 注释掉或省略以下配置文件设置:

    #replication
    # replSetName: myShardName
    #sharding
    # clusterRole: shardsvr

    要使用配置文件启动 mongod,请在命令行中指定 --config 选项,指明配置文件的完整路径:

    mongod --config /path/to/mongodb/mongod.conf

    如果已将 mongod 配置为系统服务运行,请使用系统服务管理器推荐的进程启动它。

    mongod 启动后,使用 mongo Shell 与其连接。

  1. 使存储在所选备份介质中的数据文件可在托管上访问。 这可能需要安装备份卷,在实用软件中打开备份,或使用其他工具将数据提取到磁盘。 有关访问备份中包含的数据的说明,请参阅首选备份工具的文档。

  2. mongod数据文件从备份数据位置复制到B. Prepare the Target Host for Restoration中创建的数据目录:

    cp -a /backup/mongodb/path/to/mongodb /path/to/mongodb

    -a 选项会将源路径的内容递归复制到目标路径,并同时保留文件夹和文件权限。

  3. 注释掉或省略以下配置文件设置:

    #replication
    # replSetName: myShardName
    #sharding
    # clusterRole: shardsvr
  4. 要使用配置文件启动 mongod,请在命令行中指定 --config 选项,指明配置文件的完整路径:

    mongod --config /path/to/mongodb/mongod.conf

    注意

    仅限Cloud Manager或MongoDB Ops Manager

    如果要手动恢复Cloud Manager或MongoDB Ops Manager备份,则必须在初创企业前指定 disableLogicalSessionCacheRefresh服务器参数:

    mongod --config /path/to/mongodb/mongod.conf \
    --setParameter disableLogicalSessionCacheRefresh=true

    如果已将 mongod 配置为系统服务运行,请使用系统服务管理器推荐的进程启动它。

    mongod 启动后,使用 mongo Shell 与其连接。

2

在此过程中,您将修改 admin.system.version 集合中的文档。对于强制执行身份验证的集群,只有 __system 角色才有权限修改该集合。如果集群不强制执行身份验证,则您可以跳过此步骤。

警告

__system 角色授权其持有者对数据库中的任何对象执行任何操作。此过程包括删除在此步骤所创建用户的指示。在此过程的作用域之外,请勿让此用户继续处于活动状态。

请考虑创建此用户并配置 clientSource 身份验证限制,使只有指定的主机才能作为特权用户进行身份验证。

  1. 以在 admin 数据库具有 userAdmin 角色或 userAdminAnyDatabase 角色的用户身份进行身份验证:

    use admin
    db.auth("myUserAdmin","mySecurePassword")
  2. 创建具有 __system 角色的用户:

    db.createUser(
    {
    user: "mySystemUser",
    pwd: "<replaceMeWithAStrongPassword>",
    roles: [ "__system" ]
    }
    )

    密码应随机、长且复杂,以确保系统安全并防止或延迟恶意访问。

  3. 以特权用户身份进行身份验证:

    db.auth("mySystemUser","<replaceMeWithAStrongPassword>")
3

使用 db.dropDatabase() 删除 local 数据库:

use local
db.dropDatabase()
4

要更新分片内部结构,请在 admin 数据库中的 system.version 集合上发布以下 deleteOne() 方法:

use admin
db.system.version.deleteOne( { _id: "minOpTimeRecovery" } )

注意

system.version 集合是内部系统集合。只有在得到类似的具体指示时,您才可以修改。

5

如果满足以下所有条件,则可以跳过此步骤:

  • 在此过程中,任何 CSRS 主机的主机名均未更改。

  • 在此过程中,CSRS 副本集名称不会发生更改。

admin 数据库上的 system.version 集合包含与分片相关的元数据,包括 CSRS 连接字符串。在恢复 CSRS 时,如果 CSRS 名称或任何节点主机名发生变化,则必须更新此元数据。

admin 中的 system.version 集合发出以下 find() 方法:

use admin
db.system.version.find( {"_id" : "shardIdentity" } )

find() 方法返回类似于以下内容的文档:

{
"_id" : "shardIdentity",
"clusterId" : ObjectId("2bba123c6eeedcd192b19024"),
"shardName" : "shard1",
"configsvrConnectionString" : "myCSRSName/alpha.example.net:27019,beta.example.net:27019,charlie.example.net:27019" }

以下 updateOne() 方法更新文档,使 host 字符串表示最新的 CSRS 连接字符串:

db.system.version.updateOne(
{ "_id" : "shardIdentity" },
{ $set :
{ "configsvrConnectionString" : "myNewCSRSName/config1.example.net:27019,config2.example.net:27019,config3.example.net:27019"}
}
)

重要

shardName 值必须与 CSRS 上 shards 集合中的 _id 值相匹配。验证 CSRS 上的元数据是否与分片的元数据相匹配。有关查看 CSRS 元数据的说明,请参阅此过程的 C. Restore Config Server Replica Set 部分中的子步骤 3

6

关闭 mongod。取消注释或添加以下配置文件选项:

replication
replSetName: myNewShardName
sharding
clusterRole: shardsvr

如果要更改副本集名称,必须在继续之前使用新名称更新 replSetName 字段。

使用更新的配置文件启动 mongod

mongod --config /path/to/mongodb/mongod.conf

如果已将 mongod 配置为系统服务运行,请使用系统服务管理器推荐的进程启动它。

mongod 启动后,使用 mongo Shell 与其连接。

7

使用 rs.initiate() 和默认设置启动副本集。

rs.initiate()

操作完成后,使用 rs.status() 检查该成员是否已成为主节点

8

对于分片副本集中的每个副本集成员,在其主机上启动 mongod。成功启动集群的所有剩余节点后,将 mongo Shell 连接到主副本集节点。在主节点中,使用 rs.add() 方法添加副本集的每个节点。将副本集名称作为前缀,然后是节点的 mongod 进程的主机名和端口:

rs.add("repl2.example.net:27018")
rs.add("repl3.example.net:27018")

如果要添加具有特定副本 member 配置设置的成员,则可以向 rs.add() 传递一个用于定义成员主机名及部署所需的任何 members 设置的文档。

rs.add(
{
"host" : "repl2.example.net:27018",
priority: <int>,
votes: <int>,
tags: <int>
}
)

每个新成员执行初始同步,从而与主节点同步。根据要同步的数据量、网络拓扑结构和运行状况以及每台主机的功率等因素,可能需要较长时间才能完成初始同步。

添加其他节点时,副本集可能会选出一个新的主节点。使用 rs.status() 确定哪个节点是当前的主节点。只能从主节点运行 rs.add()

9

rs.reconfig() 方法根据作为参数传递的配置文档更新副本集配置。您必须对副本集的主节点运行 reconfig()

参考步骤 A. Review Replica Set Configurations 所确定的副本集原始配置文件输出,并根据需要应用设置。

10

对于强制执行身份验证的集群,请删除在此过程之前所创建的特权用户:

  1. 以在 admin 数据库具有 userAdmin 角色或 userAdminAnyDatabase 角色的用户身份进行身份验证:

    use admin
    db.auth("myUserAdmin","mySecurePassword")
  2. 删除特权用户:

    db.removeUser("mySystemUser")

重新启动集群中的每个 mongos

mongos --config /path/to/config/mongos.conf

包括部署所需的所有其他命令行选项。

如果 CSRS 副本集名称或任何成员主机名发生变更,请使用更新的配置服务器连接字符串更新 mongos 配置文件设置 sharding.configDB

sharding:
configDB: "myNewCSRSName/config1.example.net:27019,config2.example.net:27019,config3.example.net:27019"

mongo shell 连接到集群的 mongos 进程之一。使用 sh.status() 检查整个集群状态。如果 sh.status() 显示负载均衡器未运行,则使用 sh.startBalancer() 重新启动负载均衡器。[1]

要确认所有分片均可访问和通信,请将测试数据插入临时分片集合中。确认数据正在集群中的每个分片之间进行拆分和迁移。您可以将 mongo Shell 连接到每个主分片,并使用 db.collection.find() 来验证数据是否按预期进行分片。

[1] 从 MongoDB 6.0.3 开始,不再执行自动数据块分割。这是因为均衡策略的改进。自动分割命令仍然存在,但不执行操作。在 6.0.3 之前的 MongoDB 版本中,sh.startBalancer() 还支持分片集群的自动分割。

后退

计划备份