本文介绍如何将MongoDB物理备份文件中的数据恢复至本地自建MongoDB数据库。

前提条件

  • 实例类型为副本集。
  • 实例存储类型为本地盘版。
  • 实例未开启TDE功能
  • 实例的存储引擎为WiredTigerRocksDB。如果实例的存储引擎为TerarkDB ,请使用逻辑备份恢复至自建数据库
    说明
    • 您可以在控制台的基本信息页面中查看实例的存储引擎。
    • 实例的存储引擎为RocksDB时,您需要自行编译安装带有RocksDB存储引擎的MongoDB应用程序。

数据库版本要求

云数据库MongoDB版实例的版本必须对应自建MongoDB数据库的版本。二者之间的对应关系如下:

MongoDB实例自建MongoDB数据库
3.2版本3.23.4版本
3.4版本3.4版本
4.0版本4.0版本
4.2版本4.2版本

物理备份文件格式说明

物理备份文件格式文件后缀说明
tar格式.tar.gz20190326日之前创建的实例,物理备份文件格式为tar。
xbstream格式_qp.xb20190326日及之后创建的实例,物理备份文件格式为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配置过环境变量,请跳过这一步进入步骤二:下载及解压物理备份文件

  1. 执行如下命令打开Linux系统的profile环境变量文件。
    sudo vi /etc/profile
  2. 键盘输入i进入编辑模式,在最后一行输入如下格式的内容:
    export PATH=$PATH:/<MongoDB服务端路径>/bin
    说明 本示例中,MongoDB服务端的路径为/test/mongo/bin,请根据您的实际情况配置路径。
    示例:
    export PATH=$PATH:/test/mongo/bin
  3. Esc键退出编辑模式,键盘输入:wq保存并退出。
  4. 执行如下命令使新更改的环境变量文件生效:
    source /etc/profile

步骤二:下载及解压物理备份文件

  1. 下载MongoDB物理备份文件,您可以通过如下命令进行下载。
    wget -c '<数据备份文件外网下载地址>' -O <自定义文件名>.<后缀>
    说明 请根据下载文件的类型,确保文件后缀名为.tar.gz_qp.xb
  2. 执行如下命令在/test/mongo/中新建一个data目录,并将下载的MongoDB物理备份文件移动到/test/mongo/data/目录中。
    mkdir -p /test/mongo/data && mv <物理备份文件名.后缀> /test/mongo/data
  3. 对物理备份文件执行解压操作。
    • 当下载的物理备份文件后缀为.tar.gz时,例如文件名为hins20190412.tar.gz时,请使用下述方法解压。
      cd /test/mongo/data/ && tar xzvf hins20190412.tar.gz 
    • 当下载的物理备份文件后缀为_qp.xb时,例如文件名为hins20190412_qp.xb,请使用下述方法解压。
      1. 安装percona-xtrabackup工具和qpress软件包。详情请参见PERCONA XtraBackup官网上的安装步骤
      2. 解压物理备份文件,例如数据库备份文件名为hins20190412_qp.xb。
        # 进入文件所在目录。
        cd /test/mongo/data/
        # 解包。
        cat hins20190412_qp.xb | xbstream -x -v
        # 解压物理备份文件。
        innobackupex --decompress --remove-original /test/mongo/data

步骤三:以单节点模式恢复MongoDB物理备份的数据

  1. 执行如下命令在/test/mongo文件夹中新建配置文件mongod.conf。
    touch /test/mongo/mongod.conf
  2. 在命令行中输入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
  3. Esc键退出编辑模式,键盘输入:wq保存并退出。
  4. 指定新建的配置文件mongod.conf来启动MongoDB。
    mongod -f /test/mongo/mongod.conf
  5. 等待启动完成后,执行如下命令登录MongoDB数据库,进入Mongo Shell。
    mongo --host 127.0.0.1 -u <username> -p <password> --authenticationDatabase admin
    • <username>:该MongoDB实例的数据库账号,默认为root。
    • <password>:该数据库账号对应的密码。
      说明 如果您的密码中包含特殊字符,则需要使用英文单引号(')包裹密码,如:'test123!@#'。否则可能会登录失败。
  6. Mongo Shell中,执行show dbs查询当前本地MongoDB中所有的数据库,以验证是否恢复成功。
  7. 至此恢复工作已成功完成,您可以在Mongo Shell中执行exit命令退出Mongo Shell。

步骤四:副本集模式启动MongoDB数据库

云数据库MongoDB的物理备份默认带有原实例的副本集配置。启动时需以单节点模式启动,否则可能无法访问。

如需以副本集模式启动,需要先以单节点模式恢复MongoDB数据,再按照以下步骤执行:

  1. 在命令行中通过服务器的Mongo Shell使用test用户登录MongoDB数据库。
    mongo --host 127.0.0.1 -u test -p <test用户密码> --authenticationDatabase admin
    说明 如果您的密码中包含特殊字符,则需要使用英文单引号(')包裹密码,如:'test123!@#'。否则可能会登录失败。
  2. 登录成功后,执行下方代码框中的命令完成如下动作:
    1. admin库中创建一个临时用户,赋予该用户临时的local库读写权限。
    2. 切换至临时用户移除local库中原有副本集配置。
    3. 切换回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')
  3. 执行如下命令关闭MongoDB服务并退出Mongo Shell。
    use admin
    db.shutdownServer()
    exit
  4. 创建副本集认证文件。

    如需以副本集模式启动MongoDB,您需要创建一个key文件作为每个副本集节点之间的认证文件。

    1. 执行如下命令在mongo目录下创建keyFile文件夹作为认证文件的目录,并在该目录中创建一个key文件。
      mkdir -p /test/mongo/keyFile && touch /test/mongo/keyFile/mongodb.key
    2. 执行vi /test/mongo/keyFile/mongodb.key打开mongodb.key文件,按键盘上的i进入编辑模式,输入加密内容。例如:
      MongoDB Encrypting File
      说明 加密内容有如下几个限制
      • 长度必须在6~1024个字符之间。
      • 只能包含base64编码中的字符。
      • 不能包含等号(=)。
    3. Esc键退出编辑模式,输入:wq保存并退出文件。
    4. 在命令行中执行如下命令将认证文件的权限修改为400,保证该文件内容仅对该文件所有者可见。
      sudo chmod 400 /test/mongo/keyFile/mongodb.key
    说明 此认证文件将应用于所有副本集节点。
  5. 通过下列步骤为副本集准备两个空的节点。
    1. 执行如下命令复制两份mongod.conf文件分别作为另外两个节点的启动配置文件。
      cp /test/mongo/mongod.conf /test/mongo/mongod1.conf && cp /test/mongo/mongod.conf /test/mongo/mongod2.conf
    2. 执行如下命令分别为另外两个节点创建数据目录。
      mkdir -p /test/mongo/data1 && mkdir -p /test/mongo/data2
  6. 分别通过下列指示修改各节点的配置文件:
    • 执行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:当前节点的MongoDBPID文件(记录进程ID的文件)路径。
    • keyFile:副本集认证文件路径,所有节点必须使用同一个认证文件。
    • bindIp:当前节点的IP地址。如果是在同一台服务器上部署副本集,所有节点可采用相同的IP地址。
    • port:当前节点的端口号。如果是在同一台服务器上部署副本集,所有节点应采用不同的端口号。
    • replication:副本集配置。
    • replSetName:设置副本集的名称。
  7. 执行如下命令启动3个节点。
    mongod -f /test/mongo/mongod.conf && mongod -f /test/mongo/mongod1.conf && mongod -f /test/mongo/mongod2.conf
  8. 等待启动完成后,使用test账号登录MongoDB数据库。
    mongo --host 127.0.0.1 -u test -p <test账号的密码> --authenticationDatabase admin
    说明 如果您的密码中包含特殊字符,则需要使用英文单引号(')包裹密码,如:'test123!@#'。否则可能会登录失败。
  9. 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()命令介绍

    执行成功后,新加入的两个节点将会与主节点进行数据同步,注意此过程的耗时根据备份文件的大小会有较大差异。等待数据同步完成后,副本集模式启动完成。

  10. 通过如下步骤验证是否启动成功。
    1. 执行exit退出Mongo Shell。
    2. 执行如下命令重新登录MongoDB数据库。
      mongo -u <username> -p <password> --authenticationDatabase admin
      • <username>:该MongoDB实例的数据库账号,默认为root。
      • <password>:该数据库账号对应的密码。
        说明 如果您的密码中包含特殊字符,则需要使用英文单引号(')包裹密码,如:'test123!@#'。否则可能会登录失败。
    3. 观察Mongo Shell命令行左侧,显示<副本集名称>:PRIMARY>即代表副本集模式启动成功。

常见问题

Q:为什么我使用指定的mongod.conf配置文件启动自建数据库报错?

A:常见原因如下:
  • 您可能在指定mongod.conf配置文件之前已经启动过一次数据库,导致data目录下自动生成了storage.bson文件。只需要移走这个文件并重新指定mongod.conf配置文件启动数据库即可。
  • 当前系统中可能已经有正在执行中的mongod进程,您可以通过ps -e | grep mongod命令查询到mongod的进程ID,并通过kill <进程ID>命令关闭mongod进程并重新指定mongod.conf配置文件启动数据库即可。
  • 您可能没有在mongod.conf配置文件中指定正确的systemLog.path日志路径。请确保指定的路径存在并且必须指定日志文件的名称。如:path: /<日志文件路径>/<日志文件名称>.log

Q:为什么我使用指定的mongod.conf配置文件启动副本集模式报错?

A:您可能没有将指定的keyFile认证文件的权限修改为600。请在命令行中通过sudo chmod 600 <keyFile文件路径>修改权限后重新尝试即可。

Q:为什么通过副本集模式启动MongoDB数据库后系统变得很卡?

A:因为启动完成后系统会自动开始同步Primary节点的数据到其他节点,等待数据同步完成即可。