> 文章列表 > MongoDB数据库从入门到精通系列之十:MongoDB数据库备份之文件系统快照

MongoDB数据库从入门到精通系列之十:MongoDB数据库备份之文件系统快照

MongoDB数据库从入门到精通系列之十:MongoDB数据库备份之文件系统快照

MongoDB数据库从入门到精通系列之十:MongoDB数据库备份文件系统快照

  • 一、背景
  • 二、对服务器进行备份
  • 三、文件系统快照
  • 四、快照的备份与恢复过程
  • 五、复制数据文件

一、背景

  • 定期对系统进行备份很重要。备份可以很好地防止大多数类型的故障,只有极少数的故障是无法通过从干净的备份中恢复来解决大的。

几种常用的备份选项:

  • 对单一服务器进行备份,包括快照的备份与恢复过程。
  • 对副本集进行备份时的特别考虑。
  • 对分片集群进行备份。

只有在紧急情况下有信心迅速完成对备份的部署时,备份才是有用的,因此对于选择的任何备份技术,都要确保同时对备份和恢复的操作进行练习,直到熟悉恢复过程为止。

二、对服务器进行备份

备份操作都会对系统造成压力:

  • 备份通常需要将所有数据读入内存中。
  • 备份通常应该在副本集从节点而不是主节点上进行。
  • 如果是单机服务器,则应该在空闲时进行备份。

三、文件系统快照

文件系统快照使用系统级别的工具创建保存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
  • 以上命令创建了一个名为mdb-snap01的LVM快照(使用–snapshot选项),该快照属于vg0卷组中的mongodb卷,位于/dev/vg0/mdb-snap01中。系统、卷组及设备的位置和路径可能会根据操作系统的LVM配置略有不同。
  • 由于参数为–size 100M,因此快照的上线为100MB。这个大小并不反映磁盘上的数据总量,而是反映了/dev/vg0/mongodb的当前状态与快照(/dev/vg0/mdb-snap01)之间的差异。

当命令返回时,快照就创建完毕了,可以在任何时候直接从快照进行恢复,也可以创建新的逻辑卷,并从快照恢复到备用映像。

创建快照后,挂载快照并将数据复制到独立的存储。或者使用以下命令获取快照映像的块级副本。

umount /dev/vg0/mdb-snap01dd if=/dev/vg0/mdb-snap01 | gzip > mdb-snap01.gz

这些命令会执行以下操作:

  • 确保/dev/vg0/mdb-snap01设备没有被挂载
  • 使用dd命令执行整个快照映像的块级别复制,并将结果压缩到当前工作目录的一个gzip文件中。(dd命令会在当前目录中创建一个较大的.gz文件,请确保在有足够剩余空间的文件系统中运行此命令。)

要恢复使用LVM创建的快照,可以使用如下命令:

lvcreate --size 1G --name mdb-new vg0gzip -d -c mdb-snap01.gz | dd of=/dev/vg0/mdb-newmount /dev/vg0/mdb-new /srv/mongodb

这些命令会执行以下操作:

  • 在/dev/vg0卷组中创建名为mdb-new的新逻辑卷。新设备的路径为/dev/vg0/mdb-new。可以使用不同的名称,并将1G更改为所需的卷大小。
  • 将mdb-snap01.gz文件解压缩到mdb-new磁盘映像。
  • 将mdb-new磁盘映像挂载到/srv/mongodb目录下。根据需要修改挂载点,使其与MongoDB数据文件的位置或其他位置相对应。

恢复的快照会有一个旧的mongod.lock文件。如果没有从快照中删除该文件,那么MongoDB可能会认为这个旧的mongod.lock文件意味着之前系统存在非正常的关闭。如果在运行时启用了storage.journal.enabled并且没有使用db.fsyncLock(),则不需要移除mongod.lock文件。如果使用了db.fsyncLock()文件,就需要将其删除。

要对未写入压缩的.gz文件的备份进行恢复,可以使用以下命令:

umount /dev/vg0/mdb-snap01lvcreate --size 1G --name mdb-new vg0dd if=/dev/vg0/mdb-snap01 of=/dev/vg0/mdb-newmount /dev/vg0/mdb-new /src/mongodb

还可以使用组合进程和SSH来实现脱机备份,命令与之前流程相同,只是使用了SSH在远程系统中进行归档并对备份进行压缩:

umount /dev/vg0/mdb-snap01dd if=/dev/vg0/mdb-snap01 | ssh username@example.com/bin/bash -c"gzip > opt/backup/mdb-snap01.gz"lvcreate --size 1G --name mdb-new vg0ssh username@example.com gzip -d -c /opt/backup/mdb-snap01.gz | dd 0f=/dev/vg0/mdb-newmount /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

中国互联网产业年会