恢复自托管分片集群
本程序从现有的备份快照中恢复分片集群,例如逻辑卷管理器(LVM)快照。源和目标分片集群必须具有相同数量的分片。有关为分片集群的所有组件创建LVM快照的信息,请参阅使用文件系统快照备份自管理分片集群。
注意
要使用mongodump
和mongorestore
作为分片集群的备份策略,请参阅使用数据库转储备份自管理分片集群。
分片集群还可以使用以下协调的备份和恢复过程之一,这些过程维护跨分片事务的原子性保证
考虑因素
对于使用 AES256-GCM
加密模式的 加密存储引擎,AES256-GCM
要求每个进程使用与密钥关联的唯一计数器块值。
对于配置了 AES256-GCM
密码的 加密存储引擎
- 从热备份中恢复
- 从 4.2 版本开始,如果您从“热”备份(即
mongod
正在运行)获取的文件中恢复,MongoDB 可以在启动时检测到“脏”密钥,并自动将数据库密钥滚动以避免 IV(初始化向量)重复使用。
- 从冷备份中恢复
但是,如果您从“冷”备份(即
mongod
未运行)获取的文件中恢复,MongoDB 无法在启动时检测到“脏”密钥,IV 的重复使用会破坏机密性和完整性保证。从 4.2 版本开始,为了避免从冷文件系统快照恢复后密钥的重复使用,MongoDB 添加了一个新的命令行选项
--eseDatabaseKeyRollover
。当使用--eseDatabaseKeyRollover
选项启动时,mongod
实例会将配置了AES256-GCM
密码的数据库密钥滚动并退出。
在开始之前
从 MongoDB 8.0 开始,您可以使用 directShardOperations
角色,直接对分片执行维护操作。
警告
使用 directShardOperations
角色运行命令可能会导致您的集群停止正常工作,并可能造成数据损坏。仅将 directShardOperations
角色用于维护目的或在 MongoDB 支持的指导下。完成维护操作后,请停止使用 directShardOperations
角色。
A. (可选)审查副本集配置
此过程使用默认配置启动了用于 Config Server Replica Set (CSRS) 和每个分片副本集的新副本集。如果您想为恢复的 CSRS 和分片使用不同的副本集配置,您必须重新配置副本集。
如果您的源集群运行正确且可访问,请将 mongo
壳连接到每个副本集中的主副本集成员。接下来,运行 rs.conf()
以查看副本配置文档。
如果您无法访问源分片集群的一个或多个组件,请参考任何现有内部文档,以重建每个分片副本集和配置服务副本集的配置要求。
B. 准备目标主机以进行恢复
- 存储空间要求
- 确保目标主机硬件有足够的开放存储空间以存储恢复的数据。如果目标主机包含您想保留的现有分片集群数据,请确保您有足够的存储空间来存储现有数据和恢复的数据。
- LVM 要求
- 对于 LVM 快照,您必须至少有一个 LVM 管理的卷组以及一个逻辑卷,以便有足够的空闲空间来存储提取的快照数据。
- MongoDB 版本要求
确保目标主机和源主机具有相同的 MongoDB 服务器版本。要检查主机机器上可用的 MongoDB 版本,请在终端或 shell 中运行
mongod --version
。有关安装的完整文档,请参阅 安装 MongoDB。
- 停止正在运行的 MongoDB 进程
如果要将数据恢复到现有集群,请停止目标主机上的
mongod
或mongos
进程。对于运行
mongos
的主机,连接一个mongo
shell 到mongos
并从admin
数据库运行db.shutdownServer()
。use admin db.shutdownServer() 对于运行
mongod
的主机,连接一个mongo
shell 到mongod
并运行db.hello()
:如果
isWritablePrimary
为假,则mongod
是副本集的 次要 成员。您可以从admin
数据库运行db.shutdownServer()
来停止它。如果
isWritablePrimary
为真,则mongod
是副本集的 主要 成员。首先停止副本集的次要成员。使用rs.status()
来识别副本集的其他成员。主要成员在检测到大多数成员离线后自动降级。在降级后(
db.hello()
返回isWritablePrimary: false
),您可以安全地停止mongod
。
- 准备数据目录
在目标主机上创建一个目录,用于存放要恢复的数据库文件。确保运行
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
的原始配置文件,请将其复制到目标主机上的首选位置。重要
请确保您的配置文件包含以下设置
storage.dbPath
必须设置为您的首选数据目录的路径。systemLog.path
必须设置为您的首选日志目录的路径。net.bindIp
必须包含主机机的 IP 地址。replication.replSetName
在任何给定的副本集的每个成员中具有相同的值。sharding.clusterRole
在任何给定的副本集的每个成员中具有相同的值。您还必须指定与快照中指定的相同的 启动选项,用于您的新部署。
C. 恢复配置服务器副本集
恢复 CSRS 主要的 mongod
数据文件。
选择对应您首选备份方法的选项卡
在目标主机机器上挂载 LVM 快照。挂载 LVM 快照的具体步骤取决于您的 LVM 配置。
以下示例假设使用 创建快照 步骤在 使用文件系统快照备份和恢复自管理部署 流程中创建的 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 恢复的更完整指导。
从快照挂载点复制
mongod
数据文件到在B. 准备目标主机进行恢复:cp -a /snap/mongodb/path/to/mongodb /path/to/mongodb -a
选项递归地复制源路径的内容到目标路径,同时保留文件夹和文件权限。注释掉或省略以下 配置文件 设置
#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
数据文件到在 B. 为恢复准备目标主机cp -a /backup/mongodb/path/to/mongodb /path/to/mongodb -a
选项递归地复制源路径的内容到目标路径,同时保留文件夹和文件权限。注释掉或省略以下 配置文件 设置
#replication: # replSetName: myCSRSName #sharding: # clusterRole: configsvr 要使用配置文件启动
mongod
,请在命令行中指定--config
选项,指定配置文件的完整路径。mongod --config /path/to/mongodb/mongod.conf 如果从命名空间过滤快照恢复,也请指定
--restore
选项。mongod --config /path/to/mongod/mongod.conf --restore 注意
仅限Cloud Manager或Ops Manager
如果手动恢复Cloud Manager或Ops Manager的备份,必须在启动前指定
disableLogicalSessionCacheRefresh
服务器参数。mongod --config /path/to/mongodb/mongod.conf \ --setParameter disableLogicalSessionCacheRefresh=true 如果您已将
mongod
配置为作为系统服务运行,请使用系统服务管理器推荐的过程启动它。
删除local
数据库。
使用db.dropDatabase()
删除local
数据库
use local db.dropDatabase()
将过滤后的文件列表插入到本地数据库中。
如果是从命名空间过滤的快照恢复,则需要此步骤。
对于每个分片,找到以下名称格式的过滤文件列表:<shardRsID>-filteredFileList.txt
。该文件包含以下格式的JSON对象
{ "filename":"file1", "ns":"sampleDb1.sampleCollection1", "uuid": "3b241101-e2bb-4255-8caf-4136c566a962" }
将每个分片文件的JSON对象添加到您本地数据库中的新db.systems.collections_to_restore
集合中。您可以忽略具有空ns
或uuid
字段的条目。在插入条目时,uuid
字段必须以类型UUID()
插入。
对于任何计划或完成的分片主机名或副本集名称更改,更新 config.shards
中的元数据。
如果以下所有条件都成立,则可以跳过此步骤
在此过程中,没有分片成员主机名将更改或已更改。
在此过程中,没有分片副本集名称将更改或已更改。
在 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
字符串,以反映分片预定的副本集名称和主机名列表。例如,以下操作更新了具有 "_id" : "shard1"
的分片 host
连接字符串。
db.shards.updateOne( { "_id" : "shard1" }, { $set : { "host" : "myNewShardName/repl1.example.net:27018,repl2.example.net:27018,repl3.example.net:27018" } } )
重复此过程,直到所有分片元数据都准确反映了集群中每个分片的预定副本集名称和主机名列表。
将 mongod
作为新的单节点副本集重新启动。
replication: replSetName: myNewCSRSName sharding: clusterRole: configsvr
如果您想更改副本集名称,您必须在继续之前使用新名称更新 replSetName
字段。
使用更新后的配置文件启动 mongod
。
mongod --config /path/to/mongodb/mongod.conf
如果您已将 mongod
配置为作为系统服务运行,请使用系统服务管理器推荐的过程启动它。
启动新的副本集。
使用默认设置,通过 rs.initiate()
启动副本集。
rs.initiate()
一旦操作完成,使用 rs.status()
检查成员是否已成为 主节点。
添加额外的副本集成员。
对于 CSRS 中的每个副本集成员,在其主机机器上启动 mongod
。一旦成功启动集群的所有其他成员,将 mongo
命令行工具连接到主副本集成员。从主节点,使用 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()
。
配置任何其他所需副本集设置。
方法 rs.reconfig()
根据作为参数传入的配置文档更新副本集配置。您必须针对副本集的主成员运行 reconfig()
。
参考步骤 A. 审查副本集配置 中标识的副本集原始配置文件输出,并根据需要应用设置。
D. 恢复每个分片副本集
恢复分片主 mongod
数据文件。
选择对应您首选备份方法的选项卡
在目标主机机器上挂载 LVM 快照。挂载 LVM 快照的具体步骤取决于您的 LVM 配置。
以下示例假设使用 创建快照 步骤在 使用文件系统快照备份和恢复自管理部署 流程中创建的 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 恢复的更完整指导。
将快照挂载点上的
mongod
数据文件复制到在 B. 准备目标主机以进行恢复 中创建的数据目录。cp -a /snap/mongodb/path/to/mongodb /path/to/mongodb -a
选项递归地复制源路径的内容到目标路径,同时保留文件夹和文件权限。注释掉或省略以下 配置文件 设置
#replication: # replSetName: myShardName #sharding: # clusterRole: shardsvr 要使用配置文件启动
mongod
,请在命令行中指定--config
选项,指定配置文件的完整路径mongod --config /path/to/mongodb/mongod.conf 如果是从具有命名空间筛选器的快照进行恢复,请指定
--restore
选项。mongod --config /path/to/mongod/mongod.conf --restore 如果您已将
mongod
配置为作为系统服务运行,请使用系统服务管理器推荐的过程启动它。
使您选择的备份介质上的数据文件在主机上可访问。这可能需要挂载备份卷、在软件实用程序中打开备份或使用其他工具将数据提取到磁盘。有关访问备份中包含的数据的说明,请参阅您首选备份工具的文档。
从备份数据位置复制
mongod
数据文件到在 B. 为恢复准备目标主机cp -a /backup/mongodb/path/to/mongodb /path/to/mongodb -a
选项递归地复制源路径的内容到目标路径,同时保留文件夹和文件权限。注释掉或省略以下 配置文件 设置
#replication: # replSetName: myShardName #sharding: # clusterRole: shardsvr 要使用配置文件启动
mongod
,请在命令行中指定--config
选项,指定配置文件的完整路径mongod --config /path/to/mongodb/mongod.conf 注意
仅限Cloud Manager或Ops Manager
如果手动恢复 Cloud Manager 或 Ops Manager 备份,必须在启动前指定
disableLogicalSessionCacheRefresh
服务器参数mongod --config /path/to/mongodb/mongod.conf \ --setParameter disableLogicalSessionCacheRefresh=true 如果您已将
mongod
配置为作为系统服务运行,请使用系统服务管理器推荐的过程启动它。
使用 __system
角色创建一个临时用户。
在此过程中,您将修改 admin.system.version
集合中的文档。对于强制执行 身份验证 的集群,只有 __system
角色授予修改此集合的权限。如果集群不强制执行身份验证,则可以跳过此步骤。
警告
__system
角色允许其持有人对数据库中的任何对象采取任何行动。此过程包括删除在此步骤中创建的用户。 不要 在此过程范围之外保持此用户活动。
考虑使用具有 clientSource
身份验证限制 的用户创建此用户,以便只有指定的主机可以认证为特权用户。
以具有
userAdmin
角色在admin
数据库或userAdminAnyDatabase
角色的用户进行身份验证use admin db.auth("myUserAdmin","mySecurePassword") 创建一个具有
__system
角色的用户db.createUser( { user: "mySystemUser", pwd: "<replaceMeWithAStrongPassword>", roles: [ "__system" ] } ) 密码应该是随机的、长的且复杂的,以确保系统安全并防止或延迟恶意访问。
以特权用户身份进行认证
db.auth("mySystemUser","<replaceMeWithAStrongPassword>")
删除 local
数据库。
使用db.dropDatabase()
删除local
数据库
use local db.dropDatabase()
从 admin.system.versions
集合中删除 minOpTimeRecovery
文档。
要更新分片内部,请在 admin
数据库的 deleteOne()
集合上执行方法
use admin db.system.version.deleteOne( { _id: "minOpTimeRecovery" } )
注意
system.version
集合是内部系统集合。只有在收到此类特定指示时才应修改它。
可选:对于任何CSRS主机名或副本集名称更改,请更新每个分片的身份文档中的分片元数据。
如果以下所有条件都成立,则可以跳过此步骤
在此过程中,任何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. 恢复配置服务器副本集部分的子步骤3。
启动新的副本集。
使用默认设置,通过 rs.initiate()
启动副本集。
rs.initiate()
一旦操作完成,使用 rs.status()
检查成员是否已成为 主节点。
添加额外的副本集成员。
对于分片副本集中的每个副本集成员,在其主机上启动 mongod
。一旦成功启动集群中所有剩余成员,将一个 mongo
命令行连接到主副本集成员。从主副本集成员,使用 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()
。
配置任何其他所需的复制设置。
方法 rs.reconfig()
根据作为参数传入的配置文档更新副本集配置。您必须针对副本集的主成员运行 reconfig()
。
参考步骤 A. 审查副本集配置 中标识的副本集原始配置文件输出,并根据需要应用设置。
E. 重新启动每个 mongos
重新启动集群中的每个 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"
F. 验证集群可访问性
将 mongo
shell 连接到集群中的某个 mongos
进程。使用 sh.status()
检查集群的整体状态。如果 sh.status()
显示均衡器未运行,请使用 sh.startBalancer()
重新启动均衡器。[1]
为了确认所有分片都可访问且在通信,请向临时分片集合中插入测试数据。确认数据在您的集群中的每个分片之间被分割和迁移。您可以连接到每个分片的副本集主节点,并使用 db.collection.find()
验证数据是否按预期分片。
[1] | 从 MongoDB 6.0.3 开始,不再执行自动分片分割。这是由于平衡策略的改进。自动分割命令仍然存在,但不会执行操作。在 MongoDB 6.0.3 之前的版本中,sh.startBalancer() 还为分片集群启用自动分割。 |