MongoDB迁移的那些事:冷备份+增量备份恢复

    xiaoxiao2025-12-25  12

    作者介绍

    胡国青,DBAplus社群群副,Oracle OCM10G。曾任职惠普、快乐购-芒果TV等公司服务,主要负责DBA和技术架构工作。热衷于Oracle、MySQL、MongoDB、Redis、 Linux、Java、Python、shell等技术。目前服务于初创公司和没有DBA的部分公司,负责SQL优化、DB培训、DB架构设计等相关工作。

     

    本文分享某客户实施方案,在今年9月中旬已经实施完毕。

     

    一、环境构建步骤

     

    1线上环境

     

    都是副本集模式看,3个业务访问节点+1个隐藏节点+1个延迟节点(隐藏节点做Hadoop、Spark数据同步使用以及数据报表查询等)。

     

    2主机以及配置说明

     

    10.21.18.21  primary节点      优先级为100

    10.21.18.22  secondary节点  优先级为90

    10.21.18.23  secondary节点  优先级为80

    10.21.18.24  隐藏节点            优先级为0

     

    系统配置:128G内存,64Core CPU,2TB SSD硬盘

     

    3MongoDB版本

     

    percona-server-mongodb-3.0.12-1.8

     

    4数据量

     

    目前该副本集数据量为1.3TB;

    单个集合最大数据量目前为6.7亿+,超过5亿+的集合有11张,超过2亿+的集合有27个;

    没有做sharding集群,副本集支撑现有业务。

     

    5参数配置

     

    几台服务器配置完全一样。

     

    vim mguserinfo.conf

    # for documentation of all options, see:

    #   http://docs.mongodb.org/manual/reference/configuration-options/

     

    # where to write logging data.

    systemLog:

      destination: file

      logAppend: true

      logRotate: reopen

      path: /data/users/mgousr01/mongodb/logs/userinfo01.log

     

    # Where and how to store data.

    storage:

      dbPath: /data/users/mgousr01/mongodb/dbdata

      journal:

        enabled: true

      directoryPerDB: true

      engine: wiredTiger

    #########storage.wiredTiger Options

      wiredTiger:

        engineConfig:

          cacheSizeGB: 64

          directoryForIndexes: true

        indexConfig:

          prefixCompression: true

     

    ##########operationProfiling Options

    operationProfiling:

       slowOpThresholdMs: 50

       mode: "all"

     

    ########ProcessManagement Options

    processManagement:

      fork: true

      pidFilePath: /data/users/mgousr01/mongodb/dbdata/userinfo01.pid

     

    # network interfaces

    net:

      port: 28010

      #bindIp:

      maxIncomingConnections: 27600

    security:

      keyFile: /data/users/mgousr01/mongodb/etc/keyFile/keyFilers0.key

     

    #operationProfiling:

    ##########replication Options

    replication:

      replSetName: userRS

      oplogSizeMB: 95360

      secondaryIndexPrefetch: all

     

    #sharding:

      #clusterRole: shardsvr    #configsvr or shardsvr

     

    ## Enterprise-Only Options

     

    #auditLog:

     

    #snmp:

    setParameter:

      enableLocalhostAuthBypass: true

      #replWriterThreadCount: 32

      #wiredTigerConcurrentReadTransactions: 1000

         #wiredTigerConcurrentWriteTransactions: 1000

     

    注意说明:keyFilers0.key表示认证文件,需要自己生成;权限为600否则启动失败,几台key也都是一样。

     

    先将security和keyFile参数注释,待如下(4)(5)(6)操作完毕后,在将security和keyFile参数注释去掉即可。

     

    6启动

     

    mongod –f mguserinfo.conf

     

    7配置副本集的方法

     

    登陆10.46.183.219主机操作

     

    1)

    >config={_id:"userRS",members:[{_id:1,host:"10.21.18.21:28010",priority:100,tags:{'use':'usersinfo-01-312'}}]}

    > rs.initiate(config)

     

    2)添加节点

    userRS:PRIMARY> rs.add({_id:2, host:"10.21.18.22:28010", priority:90, tags:{'use':'usersinfo-02-312'}})

    userRS:PRIMARY> rs.add({_id:3, host:"10.21.18.23:28010", priority:80, tags:{'use':'usersinfo-03-312'}})

    userRS:PRIMARY> rs.add({_id:5, host:"10.21.18.24:28010", priority:0,hidden:true, tags:{'use':'usersinfo-03-312-hidden'}})

     

    3)创建用户

    use admin

    db.createUser( 

        user: "admin", 

        pwd: "123456", 

        roles: 

        [ 

          {role: "userAdminAnyDatabase", db: "admin"},

          { role: "readAnyDatabase", db: "admin" },

          { role: "dbOwner", db: "admin" },

          { role: "userAdmin", db: "admin" },

          { role: "root", db: "admin" },

          { role: "clusterMonitor", db: "admin" },

          { role: "dbAdmin", db: "admin" },

        ] 

      } 

    )

     

    用户名为admin,密码为123456

     

    二、如何实现增量备份

     

    1上述环境是我们线上的生产环境

     

    2将其中一个secondary节点关闭

     

    我选择了10.21.18.22:28010主机节点

     

    1)登陆主节点操作如下

    rs.remove("10.21.18.22:28010");

    从现有集群中移除该节点

     

    2)shutdown mongod进程

     

    登陆10.21.18.22主机 将mongod进程shutdown

    mongod –f mguserinfo.conf --shutdown

     

    3参数调整

     

    将10.21.18.22:28010该节点参数中的replSetNamekeyfile以及security注释,并启动到单节点模式(以减少应用业务访问或者链接没有释放的线程,选择了业务最低峰凌晨3点操作,如果不及时操作的话,将该节点设置为隐藏节点即可,然后在进行后续操作)。

     

    启动:

    mongod –f mguserinfo.conf

     

    4登陆到该节点做如下操作

     

    1)

    mongo 10.21.18.22:28010

    > use admin

    > db.system.version.find()

    { "_id" : "authSchema", "currentVersion" : 5 }

     

    2)当前认证级别为5,将其修改为3

    >db.system.version.update({ "_id" : "authSchema"},{$set: {"currentVersion" : 3} })

     

    3)重启

     

    将10.21.18.22:28010该节点参数中的replSetNamekeyfile以及security注释去掉启动即可

    mongod –f mguserinfo.conf –shutdown

    mongod –f mguserinfo.conf

    这样该节点又加入到该集群中。

     

    5切换primary节点

     

    切换现有primary节点到10.21.18.22 secondary主机

     

    1)调整优先级

     

    将10.21.18.21主机mongodb primary节点的优先级修改为85即可

     

    2)操作命令

    cfg = rs.conf()

    cfg.members[1].priority = 85

    rs.reconfig(cfg)

     

    核心提示:我的主机节点members是1,下标从0开始。大家操作时需要仔细观察自己环境的配置,以免带来不必要的麻烦。

     

    6主节点创建备份用户

     

    根据调整优先级,已将primary节点切换到10.21.18.22主机

     

    登陆22主机

    use admin

    db.createUser( 

        user: "bakinc", 

        pwd: "Uk#R$K25A9", 

        roles: 

        [ 

          {role: "userAdminAnyDatabase", db: "admin"},

          { role: "readAnyDatabase", db: "admin" },

          { role: "dbOwner", db: "admin" },

          { role: "userAdmin", db: "admin" },

          { role: "root", db: "admin" },

          { role: "dbAdmin", db: "admin" },

        ] 

      } 

    )

     

    三、冷备份

     

    --将隐藏节点主机shutdown

     

    1登陆主节点操作如下

    rs.remove("10.21.18.24:28010");

    从现有集群中移除该节点。

     

    2登陆10.21.18.24主机 将mongod进程shutdown

     

    mongod –f mguserinfo.conf --shutdown

     

    3将数据目录dbdata全部copy到上海数据中心 使用nohup后台copy

     

    4记录shutdown时的时间点

     

    5数据copy完后,将该节点启动,加入副本集模式中

     

    mongod –f mguserinfo.conf

    将隐藏节点shutdown的原因是因为隐藏节点不会接受到业务处理的线程数据。

     

    四、增量备份

     

    1使用mongobackup 在primary节点操作备份oplog即可

     

    mongo_inc.sh内容如下:

    #!/bin/bash

    DATA1=`date +%Y%m%d%H%M%S`  #当前时间

    DATA2=`date +%s`

    DATA3=`echo $((${DATA2}-10860))`  #当前时间 减去 3个小时零1分 多备份恢复之后的一分钟数据,以免有写数据没有恢复到目标主机

    echo $DATA2

    echo $DATA3

    /data/mongodb/users/mgousr02/mongobackup -h10.21.18.22 --port 28010 -u bakinc -p " Uk#R$K25A9" --authenticationDatabase admin

    --backup -s ${DATA3},0  -t ${DATA2},0 -o backup${DATA1}

     

    该脚本是每天生成一个备份目录,有可以几个小时备份一次,根据自己的业务来。

     

    2增量恢复

     

    将备份文件scp到目标主机进行

    ./mongobackup -h10.66.168.68 --port 28010 --recovery   -s 1475031191,0  -t 1475032271,0  ./backup20160928110254

    说明:-s是开始时间,-t是结束时间。

     

    五、问题说明

     

    不修改system.version集合,进行备份出现如下错误:

     

    查看日志,发现有一句:

    .Failed to authenticate admin@admin with mechanism MONGODB-CR: AuthenticationFailed MONGODB-CR credentials missing in the user document 

     

    在一个国外网站发现原来还是mongodb数据库的版本问题,查询版本

     

    解决思路:在非权限验证状态下,首先,删除已有用户并;其次,修改version表的currentVersion,功能后在重新创建用户;当然也可以不删除之前的用户。

     

    五、测试数据

     

    1、

    for(var i=1;i<=100000;i++) db.users.insert({"_id":i,"ip" : "192.168.168.254","g_roup" : "kiwi","mac" : "of:fd:67:8c:2f:8f","address" : "hongmei1801num","user_id" : i,"name" : "user10000000"+i,"title" : "system","database" : "mongodb","telphone" : NumberLong("15718441234"),"mail" : "yj@chinapnr.com","os" : "win7","company" : "chinapnr","created":new Date(),"age":Math.floor(Math.random()*120)})

    2、

    for(var i=1;i<=1000000;i++) db.infos.insert({"_id":i,"ip" : "192.168.168.254","g_roup" : "kiwi","mac" : "of:fd:67:8c:2f:8f","address" : "hongmei1801num","user_id" : i,"name" : "user10000000"+i,"title" : "system","database" : "mongodb","telphone" : NumberLong("15718441234"),"mail" : "yj@chinapnr.com","os" : "win7","company" : "chinapnr","created":new Date(),"age":Math.floor(Math.random()*120)})

    3、

    for(var i=1;i<=600000;i++) db.addrs.insert({"_id":i,"ip" : "192.168.168.254","g_roup" : "kiwi","mac" : "of:fd:67:8c:2f:8f","address" : "hongmei1801num","user_id" : i,"name" : "user10000000"+i,"title" : "system","database" : "mongodb","telphone" : NumberLong("15718441234"),"mail" : "yj@chinapnr.com","os" : "win7","company" : "chinapnr","created":new Date(),"age":Math.floor(Math.random()*120)})

     

    插入数据后,将数据全量恢复到目标后,再源库进行插入、修改、删除后,进行增量备份后,然后再次进行增量恢复到目标主机。

     

    六、阐述

     

    MongoDB增量迁移的方法有多种:

     

    第一种是使用脚本语言实现,我这边实现了数据DML后的闪回操作;方便开发人员对数据进行DML误操作后能进行及时恢复(但是要保证oplog不被覆盖的情况下);

    第二种是使用现有工具集实现,比如我们使用了mongobackup,还有其他工具;

    第三种是使用程序迁移,我们之前使用Java程序将MongoDB历史数据迁移到了HBase中;

     

    前两种都是根据MongoDB的oplog日志操作。

     

    MongoDB增量备份恢复方案目前开源方面还不太理想,商业版MongoDB没有接触过,也不清楚有哪些功能。一款开源NoSQL能够得到大家的认可并在生产环境大规模使用,MongoDB的诞生无疑是一件意义深远的事情。那么多的NoSQL,为什么MongoDB在NoSQL中排名第一,在所有DB中排名第4?说明了可信度、稳定性以及其自带的功能等足够优越。我不是MongoDB公司的员工,只是其使用者之一,作为技术人员使用MongoDB服务客户,了解什么样的业务场景选择MongoDB比较适合,我觉得就是成功的关键。

    本文来自云栖社区合作伙伴"DBAplus",原文发布时间:2016-10-18

    相关资源:python入门教程(PDF版)
    最新回复(0)