DBA MongoDB 备份恢复

mongodump

功能概述

​ mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘。

​ 但是存在的问题是使用mongodump产生的备份不一定是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和Mongodb实时数据相等,必须配合oplog才能达到热备份的效果。

​ 另外在备份时可能会对其它客户端性能产生不利的影响。

​ 命令行中执行:

T > mongodump --help

​ 参数说明:

参数 描述
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-o 指明到要导出的文件名
-q 指明导出数据的过滤条件
-j 并行备份多个集合,默认4个
--port 端口号
--uri 使用链接字符串进行链接
--authenticationDatabase 验证库
--oplog 备份的同时备份oplog
--gzip 压缩备份

​ 备份的用户应该是管理员用户。

全库备份

​ 需要注意的是在进行全备时,必须关闭节点才能复制,否则复制的文件无效。

​ 所以推荐在从节点上做备份。

​ 也可以选择db.fsyncLock()进行节点锁定,在备份完成后不要忘记db.fsyncUnlock()进行解锁(不推荐)。

​ 命令如下:

T > mongodump -uroot -p密码 --port 27018 --authenticationDatabase admin -o /mongodb/backup/ --oplog

单库备份

​ 命令如下:

T > mongodump -uroot -p密码 --port 27018 --authenticationDatabase admin -d 库名 -o /mongodb/backup/ --oplog

单表备份

​ 备份某个库下的某个集合:

T > mongodump -uroot -p密码 --port 27018 --authenticationDatabase admin -d 库名 -c 集合名 -o /mongodb/backup/ --oplog

压缩备份

​ 命令如下,以全库示例:

T > mongodump -uroot -p密码 --port 27018 --authenticationDatabase admin -o /mongodb/backup --gzip --oplog

备份目录

​ 在备份完成后会获得以下的目录:

|- backup
|---- admin
|-------- system.version
|-------- system.version
|---- oplog.bson               # oplog
|---- 库名
|-------- 集合名.bson           # 备份的数据文件
|-------- 集合名.metadata.json  # 集合元数据

mongorestore

功能概述

​ 用于恢复由mongodump备份的文件。

​ 命令行中执行:

T > mongorestore --help

​ 参数说明:

参数 描述
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-j 并行恢复多个集合,默认4个
--port 端口号
--uri 使用链接字符串进行链接
--authenticationDatabase 验证库
--drop 在恢复时先执行删除命令(慎用)
--gzip 恢复压缩备份
--oplogFile 指定需要恢复的oplog文件位置
--oplogLimit 恢复记录至某一时间点
--oplogReplay 恢复时也随着恢复oplog

恢复全库

​ 命令如下:

T > mongorestore -uroot -p密码 --port 27018 --authenticationDatabase admin --oplogReplay /mongodb/backup/

恢复单库

​ 命令如下:

T > mongorestore -uroot -p密码 --port 27018 --authenticationDatabase admin -d 库名 --oplogReplay /mongodb/backup/库名 

恢复单表

​ 命令如下:

T > mongorestore -uroot -p密码 --port 27018 --authenticationDatabase admin -d 库名 -c 表名 --oplogReplay /mongodb/backup/库名/表名.bson

恢复压缩

​ 命令如下,恢复全库压缩:

T > mongorestore -uroot -p密码 --port 27018 --authenticationDatabase admin --oplogReplay /mongodb/backup --gzip

oplog

基本介绍

​ oplog仅用于复制集中,是一个定容集合,位于local库的db.oplog.rs中,其大小默认为磁盘空间的5%。

​ 其中记录的是整个MongoDB实例一段时间内数据库的所有变更(插入/更新/删除)操作,当空间用完时新记录自动覆盖最老的记录。

​ 由于oplog是一个定容集合,里面的内容会进行迭代更新,那么一组oplog的最大存活时长被称为窗口期。

​ 想要查看当前的oplog时间窗口预计存活时间,可以使用以下命令:

rs0:PRIMARY> use local
rs0:PRIMARY> rs.printReplicationInfo()
configured oplog size:   2048MB  # 集合大小
log length start to end: 944secs (0.26hrs)  # 预计窗口覆盖时间
oplog first event time:  Fri Mar 19 2021 23:14:47 GMT-0700 (PDT)  # 第一个时间点
oplog last event time:   Fri Mar 19 2021 23:30:31 GMT-0700 (PDT)  # 最后一个时间点
now:                     Fri Mar 19 2021 23:30:37 GMT-0700 (PDT)  # 最新的时间点(跟随当前时间不短变化)

​ 查看oplog相关信息:

rs0:PRIMARY> db.oplog.rs.find().pretty()

​ 信息如下,仅截取一条:

{
	"ts" : Timestamp(1616220887, 1),
	"h" : NumberLong(0),
	"v" : 2,
	"op" : "n",
	"ns" : "",
	"wall" : ISODate("2021-03-20T06:14:47.449Z"),
	"o" : {
		"msg" : "initiating set"
	}
}

恢复某一时间点

​ 背景:每天0点全备,oplog恢复窗口为48小时

​ 某天,上午10点world.city 业务表被误删除

​ 恢复思路:

  1. 停应用挂维护页
  2. 找测试库
  3. 恢复昨晚全备
  4. 截取全备之后到world.city误删除时间点的oplog,并恢复到测试库
  5. 将误删除表导出,恢复到生产库

​ 先全备数据库,首先模拟原始数据,在主库上插入:

mongo --port 27017

use world

for(var i = 1 ;i < 20; i++) {
    db.ci.insert({a: i});
}

​ 全备,从从库上备份(非延迟):

rm -rf /mongodb/backup/*
mongodump --port 27018 --oplog -o /mongodb/backup

​ 再次模拟数据,主库插入:

db.ci1.insert({id:1})
db.ci2.insert({id:2})

​ 上午10点,误删除world库下的ci表,主库删除:

db.ci.drop()

​ 备份现有的中oplog.rs表,从从库备份:

mongodump --port 27018 -d local -c oplog.rs  -o /mongodb/backup

​ 截取oplog并恢复到drop()之前的位置,先登录原数据库:

mongo --port 27017

use local
db.oplog.rs.find({op:"c"}).pretty();

{
    "ts" : Timestamp(1553659908, 1),  # oplog误删除时间点位置
    "t" : NumberLong(2),
    "h" : NumberLong("-7439981700218302504"),
    "v" : 2,
    "op" : "c",
    "ns" : "wo.$cmd",
    "ui" : UUID("db70fa45-edde-4945-ade3-747224745725"),
    "wall" : ISODate("2019-03-27T04:11:48.890Z"),
    "o" : {   # 找操作
        "drop" : "ci"
    }
}

​ 恢复备份+oplog

cd /mongodb/backup/local/
cp oplog.rs.bson ../oplog.bson 
rm -rf /mongodb/backup/local/

# 先在本地测试库进行恢复
mongorestore --port 28017  --oplogReplay --oplogLimit "1553659908:1"  --drop   /mongodb/backup/

​ 如果恢复成功,导出测试库的全备,再恢复到线上主库。

posted @ 2021-03-20 14:54  云崖君  阅读(72)  评论(0编辑  收藏  举报