挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

时间:2022-06-07 07:41:31

一  研究背景需求

目前作者所在公司的MongoDB数据库是每天凌晨做一次全库完整备份,但数据库出现故障时,只能保证恢复到全备时间点,比如,00:30 做的完整备份,而出现故障是下午18:00,那么现有的备份机制只可以恢复到00:30,即丢失00:30 – 18:00 的操作数据。

此外,我们现在的副本集没有delay节点,当出现误操作或需要恢复到指定时间点操作时,目前灾备机制也不支持此操作。上线这种备份方案,心里总是惶惶的。

并且细究mongodump机制原理,此命令在运行过程中并不会把数据库锁死(或建立快照,以保证整个库冻结在一个固定的时间点),实现数据库完整性,而是细化到集合级别,如此,会导致数据完整性问题。 例如,集合A中存放了订单概要信息,集合B中存放了订单的所有明细,那么只有一个订单有完整的明细时才是正确的状态。那么备份时,如果备份集合A处于时间点x,而备份集合B处于x之后的一个时间点y时,可以想象A和B中的数据极有可能不对应而失去意义(部分订单有订单明细而没有订单概要信息)。

二  原理分析

关系型数据库,例如MySQL ,SQL Server 都有事务日志(或bin log),会将数据库的DML  DDL、DCL等操作记录在事务文件中,可以通过日志备份搭建还原体系。MongoDB没有此类机制和数据文件,难以实现。

但MongoDB 副本集 有通过 oplog(主要记录在local数据库oplog.rs集合中) 实现节点间的同步,此集合记录了数据库的OP操作,记录的是整个mongod实例一段时间内的所有变更(插入/更新/删除)操作。

是否可以考虑通过oplog.rs集合的备份还原来解决以上问题(数据完整性;不能还原到指定时间点;时效性差。)。

值得注意的是,oplog为replica set或者master/slave模式专用,standalone模式运行mongodb并不推荐。

查看mongodb备份命令Mongodump,其中有一个相关参数oplog。

Mongodump --oplog参数

参数

参数说明

--oplog

Use oplog for taking a point-in-time snapshot

该参数的主要作用是我们在导出库集合数据的同时生成一个oplog.bson文件,里面存放了开始进行dump到dump结束之间所有的op log 操作。

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

注意:--oplog选项只对全库导出有效。

相应的 Mongorestore 中与 Oplog 相关的参数

参数

参数说明

oplogReplay

replay oplog for point-in-time restore

oplogLimit

only include oplog entries before the provided Timestamp

oplogFile

oplog file to use for replay of oplog

三 验证测试

3.1 场景1  备份还原后,如何保证数据一致性、完整性

在Insert数据过程中,备份数据库,为说明问题,数据插入跨越整个备份过程。

3.1.1 在不使用--oplog 参数下备份还原

Step 1 向数据库ygtest041602插入数据,源库没有集合order0531、orderdetial

插入语句:

for(var i = 0; i < 10000; i++)

{ db.order0531.insert({a: i});};

for(i=0;i<300000;i++)

{ db.orderdetial.insert({"id":i,"name":"shenzheng","addr":"龙岗","date":new Date()}); };

step 2  在上述命令执行期间 执行mongodump 备份

./mongodump -h 172.177.XXX.XXX --port 端口 --authenticationDatabase admin -u 用户名 -p 密码 --gzip -o /data/mongodb_back/mongotestdump

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

Step 3 还原上述备份文件

./mongorestore -h 172.177.XXX.XXX --port 端口  --authenticationDatabase admin -u 用户名 -p 密码  --gzip /data/mongodb_back/mongotestdump

Step 4 检查源库Insert 语句, 执行完毕(一定是mongodump完毕,再insert结束;但不强调,mongorestoreinsert的时间关系)

Step 5 待语句执行完毕后,比较 源库和 还原库 的数据。

源库

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

还原库

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

我们看到集合orderdetial在两个数据库不一致,有差异。即这种备份还原 无法保证数据一致性。

3.1.2 增加 参数--oplog 参数下备份还原

Step 1 删除 上次测试中遗留的集合 和 备份文件

Step 2 启动insert命令

for(var i = 0; i < 10000; i++)

{ db.order0531.insert({a: i});};

for(i=0;i<150000;i++)

{ db.orderdetial.insert({"id":i,"name":"shenzheng","addr":"龙岗","date":new Date()}); };

Step 3 执行备份命令

./mongodump -h 172.177.XXX.XXX --port 端口  --oplog --authenticationDatabase admin -u 用户名 -p密码  --gzip -o /data/mongodb_back/mongotestdump

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

从打印结果来看,有对oplog命令的输出,查看备份文件 多了一个 oplog.bson 文件

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

Step 4 执行还原命令,增加参数  --oplogReplay

./mongorestore -h 172.177.XXX.XXX --port 端口  --oplogReplay --authenticationDatabase admin -u 用户名 -p 密码  --gzip /data/mongodb_back/mongotestdump

从执行情况来看,此类还原命令有还原oplog

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

Step 5 比对数据

源库

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

还原库

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

本场景测试结论:

虽然结果数据仍不一致,但从后者的备份还原过程可以看出,有对oplog做单独的处理。

数据可以保证以oplog结尾为准,实现了多集合(表)的时间一致性(MongoDB本身特性,不保证体现数据库的事务一致性)。

3.2 场景二  还原到指定时间点

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

使用场景3.1.2 的备份文件,测试还原到备份过程中的某个时刻。从上次备份过程可知,开始时间为2018-05-31T11:13:46.501+0800,结束时间为 2018-05-31T11:14:12.961+0800

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

此轮测试还原点选择在此时间段内。时间还原点的选择,假如我们还原到orderdetial 集合"_id" : ObjectId("5b0f6876c52291864d3485b9")的插入时的时间点。

查看此时间点对应的时间和操作序列,在源库local中的oplog.rs 集合查询。

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

(oplog.rs集合的数据意义,我们在其他章节介绍,在此不做赘述)

"ts" : Timestamp(1527736438, 858)

此文档对应的 "id" : 9719.0,插入时间为2018-05-31T11:13:58.721+0800 【正好,在mongodump的过程中】

Step 1 删除还原服务器中的还原库(上面测试遗留的数据库)

Step 2 执行还原命令,通过--oplogLimit 参数指定时间点,时间点为上一步查到的Timestamp(1527736438, 858)

./mongorestore -h 172.177.XXX.XXX --port 端口  --oplogReplay --oplogLimit "1527736438:858" --authenticationDatabase admin -u 用户名 -p 密码  /data/mongodb_back/mongotestdump

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

Step 3 结果验证

从print 出来的执行过程来看,相同的备份文件,相同的还原环境,添加--oplogLimit "1527736438:858" 参数的 replay Oplog,要小于上次不带--oplogLimit参数的全还原。

本次还原,添加 --oplogLimit,只还原了 824 KB 的oplog

2018-05-31T16:55:21.975+0800     replaying oplog

2018-05-31T16:55:22.724+0800     oplog  85.9KB

2018-05-31T16:55:25.720+0800     oplog  575KB

2018-05-31T16:55:27.231+0800     oplog  842KB

2018-05-31T16:55:27.231+0800     done

 上次,没有添加 --oplogLimit,默认全还原,所以还原了3.22MB oplog。

2018-05-31T11:23:33.770+0800     replaying oplog

2018-05-31T11:23:34.682+0800     oplog  146KB

2018-05-31T11:23:40.686+0800     oplog  1.10MB

2018-05-31T11:23:49.688+0800     oplog  2.61MB

2018-05-31T11:23:52.680+0800     oplog  3.11MB

2018-05-31T11:23:53.246+0800     oplog  3.22MB

2018-05-31T11:23:53.246+0800     done

这也容易理解。全还原一定大于指定时间的部分还原。

数据检验 :

(1)此时最大ID为"id" : 9718.0,和参数值对应的ID值连续

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

(2)此过程共还原数据9719,低于全还原的63862

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

本场景测试结论:

使用参数--oplogReplay –oplogLimit 可以将数据库还原到指定时刻。

3.3 场景三 oplog.rs 集合中导出数据进行还原

在场景2 中的 oplog.bson 是我们在mongodump 全库时,添加参数--oplog参数后自动生成的 全库备份,受限于性能损耗和资源限制,不能高频率执行和长时间存储。考虑到副本集的oplog保存在oplog.rs集合中,此轮测试验证是否只从oplog.rs导出,就可以保证数据连续性。即从oplog.rs导出的数据是否可以替代mongodump过程中产生的oplog.bson.

类似于我们从oplog.rs集合中导出MySQL的binlog文件,也类似于SQL Server Log日志,可以实现增量备份与增量还原。

Step 1 在上述场景中继续测试,我们已经执行全库还原,只是时间点还原到"id" : 9718.0 对应的数据。

Step 2 删除 上次全备过程中产生的备份文件

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

Step 3 为增加试验效果,再次在源库插入部分数据

for(var i = 0; i < 10000; i++)

{ db.order0531.insert({a: i});};

for(i=0;i<200000;i++)

{ db.orderdetial.insert({"id":i,"name":"shenzheng","addr":"龙岗","date":new Date()}); };

step 4 将数据库local中集合oplog.rs 导出(建议导出时,增加时间参数,例如一小时内的或大于某时间时刻。注意,此处的测试场景中,我们选择的Timestamp(1527552239,1),在我们场景2中的Timestamp(1527736438, 858)的前面,故意时间重叠)

./mongodump -h 172.177.XXX.XXX --port 端口 --authenticationDatabase admin -u 用户名 -p 密码 -d local -c oplog.rs  --query '{ts:{$gte:Timestamp(1527552239,1)}}' -o /data/mongodb_back/mongotestoplog

step 5 将备份产生的文件local/oplog.rs.bson,copy至还原路径下,并将其命名为oplog.bson

cp ./mongotestoplog/local/oplog.rs.bson ./mongotestdump/oplog.bson

step 6 执行还原命令

./mongorestore -h 172.177.XXX.XXX --port 端口  --oplogReplay --authenticationDatabase admin -u 用户名 –p 密码  /data/mongodb_back/mongotestdump

step 7 数据验证

还原库

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

源库

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)

两者数据一致

本场景测试结论:

(1)dumprestor 命令,可以接受从别处而来,除了--oplog之外,可人为获取的从oplog.rs中导出;还原时需重命名(step 5)。

(2)可以实现数据库的增量备份与增量还原。我们可以设置Job,每小时从集合oplog.rs中导出一份操作日志。然后再利用这些文件中进行还原。注意此处的增量,是针对数据变化的,不是针对上次的全库备份。此概念与关系型数据库中的增量备份还原不同,其实更像关系型数据库中的日志备份和还原。

(3)oplog有一个非常重要的特性——幂等性(idempotent)。即对一个数据集合,使用oplog中记录的操作重放时,无论被重放多少次,其结果会是一样的。举例来说,如果oplog中记录的是一个插入操作,并不会因为你重放了两次,数据库中就得到两条相同的记录。

四 总结

1. MongoDB 不支持事务,无法保证备份还原命令中的事务完整性、业务一致性(无关系数型据库中基于事务日志的重做还原机制)。但结合命令参数--oplog,可以实现数据、业务的时间一致性。

2. 数据库还原时,结合参数--oplogReplay  --oplogLimit实现指定时间点的还原。

3. 搭建副本集的MongoDB,定期导出oplog.rs,可以实现增量备份与增量还原。

本文版权归作者所有,未经作者同意不得转载,谢谢配合!!!

挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)的更多相关文章

  1. sql2008 误操作还原至指定时间点

    --drop database db --创建一个测试库 create database db go --备份一个完整备份文件 backup database db to disk = 'd:\db. ...

  2. 批处理向FTP上传指定属性的文件 批处理增量备份的例子

    使用windows批处理向FTP上传具有指定属性的文件,类似增量备份功能. 对一个目录里的几个文件自动上传FTP时只上传有归档属性的文件,然后FTP上传成功后自动清除(本机)刚上传文件的归档属性. 类 ...

  3. &lbrack; Mongodb &rsqb; 全量备份和增量备份

    1. 前言 由于线上的mongodb 数据体量越来越大,如果没有完善的备份方案,发生故障势必造成业务很长时间的暂停.参考了网上方案,写出以下总结和备份方案: 备份方案分为两种:全备和增量备份,二者结合 ...

  4. Xtrabackup 增量备份 和 增量还原

    目录 测试数据准备 进行全量备份 第一次增量插入一条数据 进行第一次增量备份 注意 第二次增量插入一条数据 进行第二次增量备份 注意 查看xtrabackup_binlog_info中的binlog位 ...

  5. Mysql数据库之备份还原(mysqldump,LVM快照,select备份,xtrabackup)

    备份类型: 热备份:读写不受影响 温备份:仅可执行读备份 冷备份:离线备份,读写均不能执行,关机备份 物理备份和逻辑备份 物理备份:复制数据文件,速度快. 逻辑备份:将数据导出之文本文件中,必要时候, ...

  6. HBase备份还原OpenTSDB数据之Export&sol;Import(增量&plus;全量)

    前言 本文基于伪分布式搭建 hadoop+zookeeper+hbase+opentsdb之后,文章链接:https://www.cnblogs.com/yybrhr/p/11128149.html, ...

  7. Oracle 差异增量和累计增量备份

    网址: http://www.eygle.com/digest/2009/04/oracle_rman_incremental_backup.html 在rman增量备份中,有差异增量和累积增量的概念 ...

  8. MariaDB之基于Percona Xtrabackup备份大数据库&lbrack;完整备份与增量备份&rsqb;

    MariaDB之基于Percona Xtrabackup备份大数据库[完整备份与增量备份] 1.Xtrabackup的安装 percona-xtrabackup-2.2.3-4982.el6.x86_ ...

  9. Percona Xtrabackup备份mysql全库及指定数据库&lpar;完整备份与增量备份&rpar;

    原文地址:http://www.tuicool.com/articles/RZRnq2 Xtrabackup简介 Percona XtraBackup是开源免费的MySQL数据库热备份软件,它能对In ...

随机推荐

  1. 阿里笔试题:在n个人中找明星

    题目描述:有N个人,其中一个明星和n-1个群众,群众都认识明星,明星不认识任何群众,群众和群众之间的认识关系不知道,现在如果你是机器人R2T2,你每次问一个人是否认识另外一个人的代价为O(1),试设计 ...

  2. linux目录结构详细介绍

    目录1.树状目录结构图2./目录3./etc/目录4./usr/目录5./var/目录6./proc/目录7./dev/目录 该文章主要来自于网络进行整理.目录结构参考地址:http://www.hu ...

  3. 初尝 JFinal 项目(一)

    temp1: JFinal项目与JAVA项目类似,有属性方法.操作方法.Sql语句操作.jdbc.配置文件 对比:|| JAVA: Bean / Srv(Server) / SqlMap / jdbc ...

  4. ssm框架理解

    SSM框架理解 最近两星期一直在学JavaEE的MVC框架,因为之前学校开的JavaEE课程就一直学的吊儿郎当的,所以现在真正需要掌握就非常手忙脚乱,在此记录下这段时间学习的感悟,如有错误,希望大牛毫 ...

  5. 在单链表和双链表中删除倒数第K个节点

    [说明]: 本文是左程云老师所著的<程序员面试代码指南>第二章中“在单链表和双链表中删除倒数第K个节点”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解 ...

  6. POJ 3624 Charm Bracelet 简单01背包

    题目大意:有n件珠宝,每个珠宝的魅力值为v,重量为w,求在重量不超过m的情况下能达到的最大魅力值. 题目思路:简单的01背包,由于二维数组会超内存所以应该压缩成一维数组. dp[i][j],表示选取i ...

  7. Android网络开发之OkHttp--基本用法实例化各个对象

    1.实例化OkHttpClient对象,OkHttpClient包含了以下属性,以及set()和get()方法.但并没有包含具体的执行方法,详情见源码. //实例化OkHttpClent对象 priv ...

  8. JAVA内部类&lowbar;1

    使用内部类的原因: (1)可以访问该类定义所在作用域中的数据,包括私有数据. (2)可以对同一个包中的其它类隐藏起来. (3)当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷. 下面 ...

  9. Knowledge From Practice(JavaScript)

    1.HTML事件对象 onmouseover:鼠标移入事件 onmouseout:鼠标移出事件 onmousedown:鼠标落下事件 onmouseup:鼠标抬起事件 例子: onclick:鼠标点击 ...

  10. 【java工具】java常用工具

    java反编译工具 可以将看不懂的.class文件转换成看得懂的.java文件,这样一来就能很方便的读懂别人编写的java代码. findbugs FindBugs-IDEA插件的使用 阿里巴巴Jav ...