Mongodb增量备份和基于时间点恢复

AI 摘要 / TL;DR

Mongodb增量备份和基于时间点恢复 数据库备份是DBA的一种日常工作,备份包括物理备份和逻辑备份。每一种DBMS产品都提供了自己的备份和恢复的工具,如Oracle的rman和数据泵就是实现数据库备份工具的代表。 要实现数据库增量备份一般都是基于物理备份备份来实现,如rman0级+N级+归档日志,但是Mongodb官

来源: https://www.ucloud.cn/yun/129954.html 作者: IT那活儿 发布日期: 发布于2023-01-11 13:20

Mongodb增量备份和基于时间点恢复

数据库备份是DBA的一种日常工作,备份包括物理备份和逻辑备份。每一种DBMS产品都提供了自己的备份和恢复的工具,如Oracle的rman和数据泵就是实现数据库备份工具的代表。

要实现数据库增量备份一般都是基于物理备份备份来实现,如rman0级+N级+归档日志,但是Mongodb官方以及第三方都没有提供物理备份工具(基于文件系统的除外),仅提供了用于逻辑备份的mongoexport或者Mongodump。一般来说逻辑备份是无法实现增量的,但在Mongodb复制集中,提供了一个名为oplog的固定大小集合(默认为磁盘空间的5%,可手动修改)来存储所有的数据变更操作(复制集架构就利用此集合来进行数据同步),并且其具有幂等性的特点,因此可通过备份oplog的方式来进行增量备份和增量恢复。

由于oplog的幂等性,即做了多次oplog恢复或者多次重复的操作,也能保证其数据跟只执行一次的结果相同,所以我们使用如下方案来实现增量备份和恢复:

**1、全备:**按固定频率进行mongodump全库导出备份,如每天一次

**2、增量备份:**按固定频率使用Mongodump进行oplog备份,且每次备份时指定备份的起始位置为上次备份时间的前面几分钟,即多备份几分钟的oplog数据,这样可确保数据不丢失。此处要注意,oplog是一个capped集合,所以备份周期必须在oplog保留的时间范围内(即按照当前数据库的oplog大小,假如oplog集合可以保存3小时的数据,那么备份频率不能高于3小时)。例:每小时备份一次oplog

starttime=date-d -62 Minutes +%s mongodump--host=127.0.0.1 --port=27017 --authenticationDatabase admin -uroot-p*** -d local -c oplog.rs --gzip --query{ts:{$gte:Timestamp($starttime, 1)}} --out=/backupdir 在本例中,每小时备份一次oplog,每次备份的起始时间点为当前时间的前面62min,这样每次重复备份2min的oplog。

若出现了故障导致数据丢失或者人为误操作,可以将数据恢复到任意时间点

**3、全库恢复:**利用步骤1的全备进行恢复。

**4、指定从全备开始前的上一个oplog备份集开始进行恢复,一直恢复到指定的时间点。**例:多次恢复oplog直到指定的时间点。

mongorestore-h 127.0.0.1 --port 27017 --oplogReplay  /backup/oplog2021032714

mongorestore-h 127.0.0.1 --port 27017 --oplogReplay  /backup/oplog2021032715

…………

mongorestore-h 127.0.0.1 --port 27017 --oplogReplay --oplogLimit /backup/oplog/oplog.rs.bson

需要注意的是,oplog只存在于复制集架构中,单机数据库是不会写oplog的,所以针对单机架构,如果要实现增量备份的话,若有多的机器,可改成复制集,如果没有多余的机器,则可将单机改成单节点的复制集。对于分片集群架构,要求将所有分片部署成复制集架构,备份需基于所有的分片进行备份,而不能基于mongos进行备份。

附:增量备份脚本:

#!/bin/bash ##env set mongobin="/usr/local/mongodb/bin" host=localhost mongouser="admin" mongopwd="123456" mongoport=27017 fullbakdir=/home/mongo/backup/full-date+%F inc_bakdir=/home/mongo/backup/inc-date+"%Y-%m-%d-%H%M%S" #starttime=date-d -1 hours +%s starttime=date-d -62 Minutes +%s checktime=3900 ##Make needs dirs functionfulldir() { if[ ! -d "${fullbakdir}" ]; then mkdir-p ${fullbakdir} else echo"已经存在备份目录,本次备份退出,请检查环境" exit fi } functionincdir() { if[ ! -d "${inc_bakdir}" ]; then mkdir-p ${inc_bakdir} fi } functionfullback() { ${mongobin}/mongodump--host=${host} --port=${mongoport} --authenticationDatabase admin-u${mongouser} -p${mongopwd} -j 8 --oplog --gzip --out=${fullbakdir} } functioninclback() { ${mongobin}/mongodump--host=${host} --port=${mongoport} --authenticationDatabase admin-u${mongouser} -p${mongopwd} -d local -c oplog.rs --gzip --query{ts:{$gte:Timestamp($starttime, 1)}} --out=${inc_bakdir} } functionchkoplog() { oplogtime=`mongo--eval "rs.printReplicationInfo()"

通过在crontab中部署定时任务来实现固定频率备份

13 * * * sh /home/mongo/scripts/backup.sh full

30*/1 * * * sh /home/mongo/scripts/backup.sh inc

END