几种常用的备份选项:
只有在紧急情况下有信心迅速完成对备份的部署时,备份才是有用的,因此对于选择的任何备份技术,都要确保同时对备份和恢复的操作进行练习,直到熟悉恢复过程为止。
备份操作都会对系统造成压力:
文件系统快照使用系统级别的工具创建保存MongoDB数据文件的设备的副本。这种方式的完成过程耗时非常短,并且很可靠,但需要在MongoDB之外进行额外的系统配置。
MongoDB 3.2中增加了在使用WiredTiger存储引擎时对MongoDB实例进行磁盘卷级别备份的支持,即使实例中的数据文件和日志文件位于不同的卷上。为了备份的一致性,必须对数据库进行锁定,并且在备份过程中挂起对数据库的所有写操作。
如果mongod实例启用了日志功能,那么可以使用任何类型的文件系统或卷/块级别的快照工具来创建备份。
如果允许在基于Linux的系统中对基础架构进行管理,那么可以使用Linux逻辑卷管理器(LVM)来配置系统,以提供磁盘打包和快照的能力。LVM可以灵活地组合和拆分物理磁盘分区,从而支持动态调整大小的文件系统。同样也可以在云/虚拟化的环境中使用基于LVM的设置。
在LVM的初始设置中,首先需要将磁盘分区分配给物理卷(pvcreate),然后将其中一个或多个卷分配给卷组(vgcreate),接下来创建引用卷组的逻辑卷(lvcreate)。可以在逻辑卷上构建一个文件系统(mkfs),构建完成后可以挂载该逻辑卷来使用(mount)。
下面介绍Linux系统中使用LVM进行简单备份的过程。
要使用LVM创建快照,需要以root用户身份运行如下命令:
lvcreate --size 100M --snapshot --name mdb-snap01 /dev/vg0/mongodb
当命令返回时,快照就创建完毕了,可以在任何时候直接从快照进行恢复,也可以创建新的逻辑卷,并从快照恢复到备用映像。
创建快照后,挂载快照并将数据复制到独立的存储。或者使用以下命令获取快照映像的块级副本。
umount /dev/vg0/mdb-snap01
dd if=/dev/vg0/mdb-snap01 | gzip > mdb-snap01.gz
这些命令会执行以下操作:
要恢复使用LVM创建的快照,可以使用如下命令:
lvcreate --size 1G --name mdb-new vg0
gzip -d -c mdb-snap01.gz | dd of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb
这些命令会执行以下操作:
恢复的快照会有一个旧的mongod.lock文件。如果没有从快照中删除该文件,那么MongoDB可能会认为这个旧的mongod.lock文件意味着之前系统存在非正常的关闭。如果在运行时启用了storage.journal.enabled并且没有使用db.fsyncLock(),则不需要移除mongod.lock文件。如果使用了db.fsyncLock()文件,就需要将其删除。
要对未写入压缩的.gz文件的备份进行恢复,可以使用以下命令:
umount /dev/vg0/mdb-snap01
lvcreate --size 1G --name mdb-new vg0
dd if=/dev/vg0/mdb-snap01 of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /src/mongodb
还可以使用组合进程和SSH来实现脱机备份,命令与之前流程相同,只是使用了SSH在远程系统中进行归档并对备份进行压缩:
umount /dev/vg0/mdb-snap01
dd if=/dev/vg0/mdb-snap01 | ssh [email protected]/bin/bash -c"gzip > opt/backup/mdb-snap01.gz"
lvcreate --size 1G --name mdb-new vg0
ssh [email protected] gzip -d -c /opt/backup/mdb-snap01.gz | dd 0f=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb
如果mongo实例在运行时没有记录日志,或者日志文件位于单独的卷上,则必须将所有写操作刷新到磁盘并锁定数据库,以防止在备份过程中发生写操作。如果配有一个副本集,可以使用不接收读请求的从节点(比如一个隐藏的成员)来进行备份。
要实现这个目的,可以在mongo shell中调用db.fsyncLock()方法:
db.fsyncLock();
然后执行前面描述的备份操作。快照完成后,在mongo shell中执行以下命令解锁数据库:
db.fsyncUnlock();
创建单服务器备份必须防止数据文件发生变化,可以通过一个名为fsyncLock的命令来实现。
db.fsyncLock()
该命令会对数据库进行锁定以禁止任何写操作,然后将所有脏数据刷新到磁盘上(fsync),确保数据目录中的文件具有最新的一致信息,不会发生更改。
运行此命令后,mongod会将所有接收到的写操作放入队列中。在解锁之前,不会再处理任何写操作。注意,这个命令会停止对所有数据库而不仅仅是连接的那个数据库的写操作。
将数据目录中的所有文件复制到一个用于备份的位置
cp -R /data/db/* /mnt/external-drive/backup
完成数据的复制后,就可以解锁数据库,使其再次进行写操作了:
db.fsyncUnlock();
数据库将重新正常地开始处理写操作。
作为fsyncLock的替代方案,还可以关闭mongod,复制文件,然后重新启动mongod。关闭mongod可以有效地将所有更改刷新到磁盘,并防止在备份期间发生新的写操作。
如果从数据目录的副本进行恢复,请确保mongod没有处于运行状态,且需要恢复的数据目录为空。将备份的数据文件复制到数据目录中,然后启动mongod。
以下命令将恢复所备份的文件:
cp -R /mnt/external-drive/backup/* /data/db/
mongod -f mongod.conf