本文介绍如何将本地盘MongoDB备份数据下载后恢复至本地自建单节点或副本集MongoDB数据库。
本地盘逻辑备份恢复
注意事项
- 由于MongoDB一直在迭代更新,旧版本的Mongorestore不能兼容新版本的MongoDB。请选择合适的Mongorestore版本,以兼容MongoDB,如何选择Mongorestore版本,请参见mongorestore。 
- 当自建数据库是分片集群时,导入数据命令中的 - <hostname>参数需填写为自建数据库中Mongos组件的地址。
- 当自建数据库是分片集群时,导入数据命令中必须添加 - --nsExclude="config.*",否则数据恢复过程可能会出现报错。
- 将分片集群实例中的数据恢复至自建数据库时,需要下载分片集群实例中每个Shard组件的备份数据并导入到自建数据库。当分片集群实例存在孤立文档(Orphaned Document)时,自建数据库中可能会出现脏数据。恢复多个Shard的备份到同一个分片集群的时候,仅恢复第一个Shard备份时需使用drop参数。 
准备工作
- 下载并安装与云数据库MongoDB实例数据库版本相同的MongoDB至自建MongoDB数据库所在客户端(本地服务器或云服务器ECS实例),安装方法请参见Install MongoDB。 
- 已完成逻辑备份下载,未完成可参考下载备份文件。 
操作步骤
- 将下载的备份文件复制到自建MongoDB所在客户端(即安装有Mongorestore工具的客户端)。 
- 执行如下命令,将备份文件中的数据导入至自建MongoDB数据库中。 - mongorestore -h <hostname> --port <server port> -u <username> -p <password> --drop --gzip --archive=<backupfile> -vvvv --stopOnError- 您需要修改如下参数: - <hostname> :自建MongoDB数据库所属的服务器地址,本机可填写127.0.0.1。 - 当自建数据库是分片集群时,该参数需填写为自建数据库中Mongos组件的地址。 
- <server port>:自建MongoDB数据库的数据库端口。 
- <username>:登录自建MongoDB数据库的数据库用户名,请确保该用户拥有所有库的权限,建议使用root账号。 
- <password>:登录自建MongoDB数据库的数据库密码。 
- <backupfile>:下载的逻辑备份文件名。 
 - 命令参数无需修改,说明如下: - --drop:在恢复备份文件之前,删除集合。 说明- 当恢复多个Shard的备份到同一个分片集群的时候,仅恢复第一个Shard备份时需使用该参数。 
- --gzip:备份文件中的数据是以gzip形式压缩过的,需要先解压。 说明- 此参数从MongoDB 3.1.4版本开始支持,更多信息,请参见mongo-tools。 
- -vvvv:备份文件输出的详细程度,v越多,备份文件的数据越详细。 
- --stopOnError:导入过程中遇到任何错误后,都会停止导入数据。 
- --nsExclude:不恢复匹配成功的数据集合。例如 - --nsExclude="config.*"。
 - 示例: - mongorestore -h 127.0.0.1 --port 27017 -u root -p ******** --drop --gzip --archive=hins1111_data_20190710.ar -vvvv --stopOnError
本地盘物理备份恢复
前提条件
- 实例类型为副本集。 
- 实例未开启TDE功能。 
- 实例的存储引擎为WiredTiger或RocksDB。如果实例的存储引擎为TerarkDB ,请使用逻辑备份恢复至自建数据库。 说明- 您可以在控制台的基本信息页面中查看实例的存储引擎。 
- 实例的存储引擎为RocksDB时,您需要自行编译安装带有RocksDB存储引擎的MongoDB应用程序。 
 
数据库版本要求
云数据库MongoDB版实例的版本必须对应自建MongoDB数据库的版本。二者之间的对应关系如下:
| MongoDB实例 | 自建MongoDB数据库 | 
| 3.2版本 | 3.2或3.4版本 | 
| 3.4版本 | 3.4版本 | 
| 4.0版本 | 4.0版本 | 
| 4.2版本 | 4.2版本 | 
物理备份文件格式说明
| 物理备份文件格式 | 文件后缀 | 说明 | 
| tar格式 | .tar.gz | 2019年03月26日之前创建的实例,物理备份文件格式为tar。 | 
| xbstream格式 | _qp.xb | 2019年03月26日及之后创建的实例,物理备份文件格式为xbstream。 说明  由于Windows暂未支持解压此文件所需的percona-xtrabackup工具,因此xbstream格式仅限Linux系统中解压使用。 | 
环境说明
- 本文示例所用的服务器为阿里云ECS实例,镜像为Ubuntu 16.04(64位),创建方法请参见创建ECS实例。 
- ECS服务器已安装对应版本的MongoDB,安装方法请参见MongoDB官方文档。 
- ECS服务器已对MongoDB配置环境变量,执行命令时无需再输入可执行文件的路径。 
- /test/mongo/data作为MongoDB物理恢复操作的数据库所在目录。 
- /test/mongo/data1和/test/mongo/data2作为副本集节点的数据库目录。 
步骤一:配置环境变量
对自建库环境中的MongoDB配置环境变量,避免执行命令时繁琐的路径输入步骤。在执行此步骤前,请确认您已安装MongoDB。
如您已对MongoDB配置过环境变量,请跳过这一步进入步骤二:下载及解压物理备份文件。
- 执行如下命令打开Linux系统的 - profile环境变量文件。- sudo vi /etc/profile
- 键盘输入 - i进入编辑模式,在最后一行输入如下格式的内容:- export PATH=$PATH:/<MongoDB服务端路径>/bin说明- 本示例中,MongoDB服务端的路径为/test/mongo/bin,请根据您的实际情况配置路径。 - 示例: - export PATH=$PATH:/test/mongo/bin
- 按Esc键退出编辑模式,键盘输入 - :wq保存并退出。
- 执行如下命令使新更改的环境变量文件生效: - source /etc/profile
步骤二:下载及解压物理备份文件
- 下载MongoDB物理备份文件,您可以通过如下命令进行下载。 - wget -c '<数据备份文件外网下载地址>' -O <自定义文件名>.<后缀>- 示例: - wget -c 'http://rdsbak-hz-v3.oss-cn-hangzhou-internal.aliyuncs.com/custins5475****/hins1907****_data_20210906103710_qp.xb?Expires=......' -O backupfile._qp.xb说明- 请根据下载文件的类型,确保文件后缀名为 - .tar.gz或- _qp.xb。
- 请用英文单引号将下载地址括起来,以确保正确解析下载地址。 
 
- 执行如下命令在/test/mongo/中新建一个 - data目录,并将下载的MongoDB物理备份文件移动到/test/mongo/data/目录中。- mkdir -p /test/mongo/data && mv <物理备份文件名.后缀> /test/mongo/data
- 对物理备份文件执行解压操作。 - 当下载的物理备份文件后缀为.tar.gz时,例如文件名为hins20190412.tar.gz时,请使用下述方法解压。 - cd /test/mongo/data/ && tar xzvf hins20190412.tar.gz
- 当下载的物理备份文件后缀为_qp.xb时,例如文件名为hins20190412_qp.xb,请使用下述方法解压。 - 安装percona-xtrabackup工具和qpress软件包。详情请参见PERCONA XtraBackup官网上的安装步骤。 
- 解压物理备份文件,例如数据库备份文件名为hins20190412_qp.xb。 - # 进入文件所在目录。 cd /test/mongo/data/ # 解包。 cat hins20190412_qp.xb | xbstream -x -v # 解压物理备份文件。 innobackupex --decompress --remove-original /test/mongo/data
 
 
步骤三:以单节点模式恢复MongoDB物理备份的数据
- 执行如下命令在/test/mongo文件夹中新建配置文件mongod.conf。 - touch /test/mongo/mongod.conf
- 在命令行中输入 - vi /test/mongo/mongod.conf打开mongod.conf文件,键盘输入- i开启编辑模式。- 根据云数据库MongoDB版的存储引擎选择启动的配置模板,您可以将其复制到mongod.conf文件中。 说明- 配置文件设置了启动模式为单节点模式并开启认证功能。 - WiredTiger存储引擎 - systemLog: destination: file path: /test/mongo/mongod.log logAppend: true security: authorization: enabled storage: dbPath: /test/mongo/data directoryPerDB: true net: port: 27017 unixDomainSocket: enabled: false processManagement: fork: true pidFilePath: /test/mongo/mongod.pid说明- 云数据库MongoDB默认使用的是WiredTiger存储引擎,并且开启了directoryPerDB选项,因此配置中指定了这个选项。 
- RocksDB存储引擎 - systemLog: destination: file path: /test/mongo/logs/mongod.log logAppend: true security: authorization: enabled storage: dbPath: /test/mongo/data engine: rocksdb net: port: 27017 unixDomainSocket: enabled: false processManagement: fork: true pidFilePath: /test/mongo/mongod.pid
 
- 按Esc键退出编辑模式,键盘输入 - :wq保存并退出。
- 指定新建的配置文件mongod.conf来启动MongoDB。 - mongod -f /test/mongo/mongod.conf
- 等待启动完成后,执行如下命令登录MongoDB数据库,进入Mongo Shell。 - mongo --host 127.0.0.1 -u <username> -p <password> --authenticationDatabase admin- <username>:该MongoDB实例的数据库账号,默认为root。 
- <password>:该数据库账号对应的密码。 说明- 如果您的密码中包含特殊字符,则需要使用英文单引号(')包裹密码,如:'test123!@#'。否则可能会登录失败。 
 
- 在Mongo Shell中,执行 - show dbs查询当前本地MongoDB中所有的数据库,以验证是否恢复成功。
- 至此恢复工作已成功完成,您可以在Mongo Shell中执行 - exit命令退出Mongo Shell。
完成上述步骤后,您即可使用单节点模式启动MongoDB数据库,如需使用副本集模式启动数据库,请参见步骤四。
步骤四:副本集模式启动MongoDB数据库
由于云数据库MongoDB的物理备份默认带有原实例的副本集配置,您需要移除该配置才能使用副本集模式启动,具体操作如下:
- 在命令行中通过服务器的Mongo Shell使用test用户登录MongoDB数据库。 - mongo --host 127.0.0.1 -u test -p <test用户密码> --authenticationDatabase admin说明- 如果您的密码中包含特殊字符,则需要使用英文单引号(')包裹密码,如:'test123!@#'。否则可能会登录失败。 
- 登录成功后,执行下方代码框中的命令完成如下动作: - 在admin库中创建一个临时用户,赋予该用户临时的local库读写权限。 
- 切换至临时用户移除local库中原有副本集配置。 
- 切换回test用户删除临时用户和临时权限。 说明- 请将下列代码中的 - <test用户密码>部分替换成您test用户的密码后再执行。
 - use admin db.runCommand({ createRole: "tmprole", roles: [ { role: "test", db: "admin" } ], privileges: [ { resource: { db: 'local', collection: 'system.replset' }, actions: [ 'remove' ] } ] }) db.runCommand({ createUser: "tmpuser", pwd: "tmppwd", roles: [ 'tmprole' ] }) db.auth('tmpuser','tmppwd') use local db.system.replset.remove({}) use admin db.auth('test','<test用户密码>') db.dropRole('tmprole') db.dropUser('tmpuser')
- 执行如下命令关闭MongoDB服务并退出Mongo Shell。 - use admin db.shutdownServer() exit
- 创建副本集认证文件。 - 如需以副本集模式启动MongoDB,您需要创建一个key文件作为每个副本集节点之间的认证文件。 - 执行如下命令在mongo目录下创建keyFile文件夹作为认证文件的目录,并在该目录中创建一个key文件。 - mkdir -p /test/mongo/keyFile && touch /test/mongo/keyFile/mongodb.key
- 执行 - vi /test/mongo/keyFile/mongodb.key打开mongodb.key文件,按键盘上的- i进入编辑模式,输入加密内容。例如:- MongoDB Encrypting File说明- 加密内容有如下几个限制 - 长度必须在6~1024个字符之间。 
- 只能包含base64编码中的字符。 
- 不能包含等号(=)。 
 
- 按Esc键退出编辑模式,输入 - :wq保存并退出文件。
- 在命令行中执行如下命令将认证文件的权限修改为 - 400,保证该文件内容仅对该文件所有者可见。- sudo chmod 400 /test/mongo/keyFile/mongodb.key
 说明- 此认证文件将应用于所有副本集节点。 
- 通过下列步骤为副本集准备两个空的节点。 - 执行如下命令复制两份mongod.conf文件分别作为另外两个节点的启动配置文件。 - cp /test/mongo/mongod.conf /test/mongo/mongod1.conf && cp /test/mongo/mongod.conf /test/mongo/mongod2.conf
- 执行如下命令分别为另外两个节点创建数据目录。 - mkdir -p /test/mongo/data1 && mkdir -p /test/mongo/data2
 
- 分别通过下列指示修改各节点的配置文件: - 执行 - vi /test/mongo/mongod.conf打开节点1的配置文件,并按照如下内容修改完成后保存退出。- systemLog: destination: file path: /test/mongo/mongod.log logAppend: true security: authorization: enabled keyFile: /test/mongo/keyFile/mongodb.key storage: dbPath: /test/mongo/data directoryPerDB: true net: bindIp: 127.0.0.1 port: 27017 unixDomainSocket: enabled: false processManagement: fork: true pidFilePath: /test/mongo/mongod.pid replication: replSetName: "rs0"
- 执行 - vi /test/mongo/mongod1.conf打开节点2的配置文件,并按照如下内容修改完成后保存退出。- systemLog: destination: file path: /test/mongo/mongod1.log logAppend: true security: authorization: enabled keyFile: /test/mongo/keyFile/mongodb.key storage: dbPath: /test/mongo/data1 directoryPerDB: true net: bindIp: 127.0.0.1 port: 27018 unixDomainSocket: enabled: false processManagement: fork: true pidFilePath: /test/mongo/mongod1.pid replication: replSetName: "rs0"
- 执行 - vi /test/mongo/mongod2.conf打开节点3的配置文件,并按照如下内容修改完成后保存退出。- systemLog: destination: file path: /test/mongo/mongod2.log logAppend: true security: authorization: enabled keyFile: /test/mongo/keyFile/mongodb.key storage: dbPath: /test/mongo/data2 directoryPerDB: true net: bindIp: 127.0.0.1 port: 27019 unixDomainSocket: enabled: false processManagement: fork: true pidFilePath: /test/mongo/mongod2.pid replication: replSetName: "rs0"
 - 各重要参数说明如下: - systemLog.path下的path:当前节点的MongoDB日志文件路径, 
- dbpath:当前节点的MongoDB数据文件路径。 
- pidFilePath:当前节点的MongoDB的PID文件(记录进程ID的文件)路径。 
- keyFile:副本集认证文件路径,所有节点必须使用同一个认证文件。 
- bindIp:当前节点的IP地址。如果是在同一台服务器上部署副本集,所有节点可采用相同的IP地址。 
- port:当前节点的端口号。如果是在同一台服务器上部署副本集,所有节点应采用不同的端口号。 
- replication:副本集配置。 
- replSetName:设置副本集的名称。 
 
- 执行如下命令启动3个节点。 - mongod -f /test/mongo/mongod.conf && mongod -f /test/mongo/mongod1.conf && mongod -f /test/mongo/mongod2.conf
- 等待启动完成后,使用test账号登录MongoDB数据库。 - mongo --host 127.0.0.1 -u test -p <test账号的密码> --authenticationDatabase admin说明- 如果您的密码中包含特殊字符,则需要使用英文单引号(')包裹密码,如:'test123!@#'。否则可能会登录失败。 
- 在Mongo Shell中通过如下命令将上述步骤中创建的副本集成员节点加入副本集并初始化。 - rs.initiate( { _id : "rs0", version : 1, members: [ { _id: 0, host: "127.0.0.1:27017" , priority : 1}, { _id: 1, host: "127.0.0.1:27018" , priority : 0}, { _id: 2, host: "127.0.0.1:27019" , priority : 0} ] })- 初始化成功示例:  说明 说明- 此步骤使用 - rs.initiate()命令进行操作,详细命令用法请参见MongoDB官方文档rs.initiate()命令介绍。- 执行成功后,新加入的两个节点将会与主节点进行数据同步,注意此过程的耗时根据备份文件的大小会有较大差异。等待数据同步完成后,副本集模式启动完成。 
- 通过如下步骤验证是否启动成功。 - 执行 - exit退出Mongo Shell。
- 执行如下命令重新登录MongoDB数据库。 - mongo -u <username> -p <password> --authenticationDatabase admin- <username>:该MongoDB实例的数据库账号,默认为root。 
- <password>:该数据库账号对应的密码。 说明- 如果您的密码中包含特殊字符,则需要使用英文单引号(')包裹密码,如:'test123!@#'。否则可能会登录失败。 
 
- 观察Mongo Shell命令行左侧,显示 - <副本集名称>:PRIMARY>即代表副本集模式启动成功。