使用 Zmanda Recovery Manager for MySQL 轻松进行数据库备份

作者:Daniel Bartholomew

最近,我有机会测试了 Zmanda Recovery Manager for MySQL 的社区版。我部分是为了测试它是否适用于 MariaDB,Monty Program 公司用于替代 MySQL 的即插即用型产品,但我也想测试它是否能很好地用于我们自己的数据库备份。

Monty Program 公司可以说是地球上最了解 MySQL 代码库的公司。但除了我们用于性能和其他测试的一些大型服务器外,我们实际的数据库使用情况和需求与许多其他中小型公司相似。对于我们的网站,我们只需要几个小型数据库服务器。每个数据库的数据集都不大,每个只有几百兆字节。但是,我们仍然不想丢失任何数据,因此备份是必须的。

长期以来,我一直使用一套自制的 shell 脚本来管理数据库备份。它们很简单,并且工作得足够好以完成工作。它们缺少一些我一直没有时间实现的功能,例如自动保留期限和轻松恢复。设置过程也比我希望的要复杂。它们可以完成工作,但我一直想要一些更好的东西,但我一直没有时间自己做。

这就是 Zmanda Recovery Manager for MySQL 发挥作用的地方。ZRM 企业版在 2008 年 9 月号的 Linux Journal 上由 Alolita Sharma 进行了评论,但我从来没有对企业版很感兴趣。它们总是包含专有部分,而且我从来没有像信任命令行对应工具那样信任 GUI 工具。幸运的是,在有“企业”版本的地方,几乎总是在某个阴影中潜伏着“社区”版本。

像许多其他社区版一样,Zmanda Recovery Manager for MySQL 社区版(我们简称 ZRM)缺少“花哨的功能”。企业版同类产品的高调功能,如图形“控制台”应用程序、Windows 兼容性、24x7 支持和其他高级功能在社区版中都缺失了。但基本要素都在那里,它有一个我喜欢的大功能:它是完全开源的 (GPL v2)。然而,关键指标是它是否能完成我需要它做的事情?

为了找出答案,我建立了一个小型测试环境(我不想在实时的生产数据库上进行测试),并试用了一下。请参阅“设置测试环境”侧边栏,了解我在安装和测试 ZRM 之前所做工作的详细信息。

设置测试环境

为了测试和评估 ZRM,我设置了三台运行 Ubuntu 10.04 LTS 的虚拟机服务器,在它们上面安装了 MariaDB,然后从 launchpad.net/test-db 下载了示例“employees”测试数据库。

由于 OurDelta.org 维护的一些 MariaDB 仓库,在 Debian、Ubuntu 和 CentOS 上安装 MariaDB 非常容易。该站点上有关于如何配置您的系统以使用这些仓库的说明。对于 Ubuntu 10.04,我执行了以下操作

1. 将以下行添加到 /etc/apt/sources.list.d/mariadb.list

# MariaDB OurDelta repository for Ubuntu 10.04 "Lucid Lynx"
deb http://mirror.ourdelta.org/deb lucid mariadb-ourdelta
deb-src http://mirror.ourdelta.org/deb lucid mariadb-ourdelta

2. 将仓库密钥添加到 apt

apt-key adv --recv-keys \
            --keyserver keyserver.ubuntu.com 3EA4DFD8A29A9ED6

3. 更新 apt 并安装 mariadb-server

apt-get update
apt-get install mariadb-server

安装 mariadb-server 的外观和行为就像安装 mysql-server 一样。

在安装数据库服务器后,我加载了测试数据库。要将 employees 测试数据库加载到 MariaDB 中,我首先下载并解压了它,然后使用 mysql 命令行程序将其加载到 MariaDB 中,如下所示

tar -jxvf employees_db-full-1.0.6.tar.bz2
cd employees_db/
mysql -u root -p -t < employees.sql

employees 测试数据库使用了几百兆字节的磁盘空间。这与我们“真实”数据库的大小一致。但更重要的是,employees 测试数据库附带了一个方便的验证脚本,可以让我测试数据是否正确。验证数据就像这样简单

mysql -u root -p -t < test_employees_sha.sql

在设置好测试数据库服务器后,我然后创建了第四台虚拟机,其上安装了基本的 Ubuntu Server,作为我的备份服务器。现在我准备好使用 ZRM 进行备份和恢复测试,并能够验证恢复是否成功。

安装和使用 ZRM

Zmanda 在其网站上为 Debian、RPM 和 Solaris/OpenSolaris 系统及其衍生产品提供软件包。源代码包也可用。因为我使用的是 Ubuntu 10.04,所以我从 ZRM 下载页面下载了最新的稳定 Debian 软件包(撰写本文时为 mysql-zrm_2.2.0_all.deb)。

ZRM 需要 libxml-parser-perl 和 libdbi-perl 软件包、mariadb-client 或 mysql-client 软件包,以及允许它发送电子邮件消息的东西(用于通知正确的人备份是否成功或失败)。如果您在与数据库相同的服务器上运行 ZRM,则 Perl 和客户端软件包可能已经安装。如果您选择像我一样从专用备份服务器运行 ZRM,则需要安装这些软件包

apt-get install libxml-parser-perl libdbi-perl \
                mariadb-client bsd-mailx

当在 Ubuntu 上安装 mailx 时,它也会安装 postfix(除非您已经安装了不同的 MTA),但其他 MTA(邮件传输代理)可能是您发行版的默认设置。在安装 postfix 软件包期间,我选择了基本的“互联网站点”设置,这提供了足够的配置以允许服务器发送电子邮件。

ZRM 软件包期望存在名为“mysql”的用户。此用户通常在安装 MySQL 或 MariaDB 时创建,但由于我的备份服务器仅安装了 mariadb-client 软件包,因此 mysql 用户不存在,因此我需要创建它。我还选择为新用户提供与该用户作为 Ubuntu mariadb-server 安装的一部分创建时相同的用户主目录

sudo adduser --system --group --home="/var/lib/mysql" mysql

在终于解决了依赖项问题后,我准备安装 Zmanda Recovery Manager。我像这样安装了它

dpkg -i mysql-zrm_2.2.0_all.deb

安装本身非常枯燥,看起来与任何其他软件包安装没有什么不同

me@backuphost:~$ sudo dpkg -i mysql-zrm_2.2.0_all.deb
Selecting previously deselected package mysql-zrm.
(Reading database ...
    42938 files and directories currently installed.)
Unpacking mysql-zrm (from mysql-zrm_2.2.0_all.deb) ...
Setting up mysql-zrm (2.2.0) ...
Updating ownership of previously backed up data sets

Processing triggers for man-db ...
me@backuphost:~$

那么软件包安装了什么呢?查看以下命令的输出dpkg -L mysql-zrm显示该软件包将几个 Perl 脚本安装到 /usr/bin/ 文件夹中,并创建以下目录

  • /usr/share/mysql-zrm — 一个“plugins”文件夹,其中包含几个 Perl 脚本。

  • /usr/share/doc/mysql-zrm — 各种文档和 README 文件。

  • /usr/lib/mysql-zrm — 各种 Perl 模块。

  • /etc/mysql-zrm — 配置文件。

  • /var/log/mysql-zrm — 用于日志文件的空目录。

  • /var/lib/mysql-zrm — 备份存放的文件夹(最初为空)。

该软件包还为脚本和配置文件以及 xinetd 和 logrotate 配置文件安装了手册页。

现在我准备好设置一些备份了。ZRM 使用“备份集”的概念来指代单个服务器或备份作业的备份设置。要创建新的备份集,您需要在 /etc/mysql-zrm/ 下创建一个新目录,并将默认配置文件复制到新目录中,如下所示

cd /etc/mysql-zrm
mkdir -v backupsetname
cp -vi mysql-zrm.conf backupsetname/

该文件夹可以使用您想要的任何名称。默认情况下,mysql-zrm.conf 文件完全被注释掉。该文件具有每个配置指令的内联文档,并且非常易于阅读。对于我的项目,我想要压缩和加密的逻辑备份,因此我自定义和取消注释的行是这些

backup-mode=logical
backup-type=regular
retention-policy=30D
compress=1
compress-plugin=/bin/gzip
encrypt=1
encrypt-plugin="/usr/share/mysql-zrm/plugins/encrypt.pl"
all-databases=1
user="backup-user"
password="examplepassword"
host="db1.example.org"
mailto="my-email@example.org"

用户密码在上面的一组变量中,是 MariaDB 数据库用户,而不是系统用户。此用户像其他数据库用户一样使用 mysql 命令行工具和 GRANT 语句创建。以下是 Zmanda 推荐的 GRANT 语句

GRANT select, show view, create view, insert, update,
      create, drop, reload, shutdown, alter, super, lock tables,
      replication client
          on *.*
          to 'backup-user'@'backuphost'
          identified by 'examplepassword';

如果您在要备份的主机上设置 ZRM,backuphost在上面的语句中将更改为localhost。此时,我还需要配置我们的一个数据库服务器以允许远程登录。这是通过将 /etc/mysql/my.cnf 文件中的 bind-address 变量设置为数据库服务器的 IP 地址,然后重启 mysqld 来完成的。

备份可以是“原始”的或“逻辑”的。原始备份是数据库文件的实际副本。逻辑备份是数据库内容在 SQL 中的转储(使用 mysqldump)。原始备份只能恢复到运行相同 MariaDB 或 MySQL 版本的服务器。逻辑备份没有此限制,可以成功加载到运行较旧或较新 MariaDB/MySQL 版本的服务器上(取决于您要恢复到的新服务器是否支持旧服务器支持的相同功能)。

备份类型有“常规”和“快速”。快速类型仅适用于原始备份,并且仅当您的数据库存储在 LVM 逻辑卷上时才适用。raw+regular 备份是使用 mysqlhotcopy 制作的 MariaDB/MySQL 数据文件的副本。raw+quick 备份是这些数据文件的 LVM 快照。如果您正在进行逻辑备份,则快速备份类型不可用。

retention-policy 变量告诉 ZRM 您要保留备份多长时间。默认值为 10W,代表十周。您可以指定的其他后缀包括 D 代表天,M 代表月或 Y 代表年。

ZRM 使用“插件”来扩展其功能。ZRM 附带了几个插件,包括几个可用于将备份从远程数据库服务器复制到运行 ZRM 的服务器的插件,以及一个用于加密备份的插件。一些插件只是包装脚本,例如加密插件,它是 GPG 的包装器。其他插件只是系统二进制文件。例如,默认的“compress”插件只是 gzip 程序,无需包装脚本。这些插件中的任何一个或全部都可以替换为您自己首选的解决方案。

每个插件的配置和设置各不相同。例如,加密插件需要在 /etc/mysql-zrm/ 文件夹中创建一个名为 .passphrase 的文件。此文件包含加密备份时使用的密码。我创建此文件时遵循的步骤是

touch /etc/mysql-zrm/.passphrase
echo 'mysupercoolhardtoguesspassword' > /etc/mysql-zrm/.passphrase
chmod -v 700 /etc/mysql-zrm/.passphrase

此外,由于加密插件使用 GPG,因此 .gnupg 文件夹需要存在于 root 用户的主目录中(备份由 root 派生)。它对我来说不存在,所以我创建了它

mkdir -v /root/.gnupg
chmod -v 600 /root/.gnupg

最后,我准备好执行一些备份了。运行手动备份非常容易

mysql-zrm-scheduler --backup-set backupsetname \
                    --backup-level 0 --now

计划备份也很容易。与运行手动备份一样,要计划备份,您可以使用 mysql-zrm-scheduler 脚本,但不是让备份“立即”开始,而是设置一个间隔和开始时间,如下所示

sudo mysql-zrm-scheduler --add --backup-set backupsetname \
                         --backup-level 0 \
                         --interval daily --start-time 01:00

上述备份将每天凌晨 1 点开始运行。您可以使用以下命令查看计划mysql-zrm-scheduler --query,或者因为 ZRM 使用 cron 计划备份,所以您只需使用以下命令查询 root crontabcrontab -l(以 root 身份运行命令)。

当您添加您的第一个计划时,ZRM 还会添加一个 cron 作业,用于运行“purge”操作,以删除早于保留期限的备份。

要检查您的备份数据自备份以来是否已损坏,请使用带有verify-backup操作的 mysql-zrm 脚本

mysql-zrm --action verify-backup --backup-set backupsetname

要查看最近备份的统计信息,mysql-zrm-reporter 可以提供帮助

mysql-zrm-reporter --show backup-performance-info

如果灾难发生并且您需要将备份恢复到服务器,首先要确定最近一次成功的备份的位置,然后使用它。mysql-zrm-reporter 脚本是显示位置的简便方法

mysql-zrm-reporter --show restore-info \
                   --where backup-set=backupsetname

在输出中,查找备份状态为“Backup succeeded”的最新备份的 backup_directory。backup_directory 路径将类似于这样

/var/lib/mysql-zrm/backupsetname/20100607141122

有了这些信息,您就可以执行恢复,如下所示

backup_dir=/var/lib/mysql-zrm/backupsetname/20100607141122
mysql-zrm-restore --backup-set backupsetname \
                  --source-directory $backup_dir

预计恢复需要一段时间,具体取决于数据库的大小。在我的测试设置中,恢复完成后,我按照“设置测试环境”侧边栏中的描述验证了数据,并且一切都检查通过了。

结论

在我的评估结束时,我决定使用 ZRM 进行数据库备份。我的用例是通过网络进行逻辑备份,对于这些备份,ZRM 的开源社区版非常好用。

我喜欢计划新备份和创建新备份作业的简易程度。使用 Zmanda,我可以毫不费力地为新的数据库服务器配置备份,这对于我自制的解决方案来说是无法实现的。恢复也很容易,如果发生不可思议的事情并且我需要从备份中恢复,这将非常受欢迎。而且,由于 ZRM 使用标准工具,即使我无法使用 ZRM 恢复,备份也包含一个文件,我可以将其手动加载到数据库中,无论是按原样加载(如果我不加密或压缩备份),还是在使用标准的 gunzip 和 GPG 工具进行少量处理后加载。

Zmanda Recovery Manager for MySQL 并非完美。例如,在我的测试期间,我从未能够让原始备份通过网络正常工作。另一个问题(虽然是小问题)是,手册页存在格式问题,使其难以阅读。一些错误消息也不是最有用的,文档可以改进和扩展。但是,该软件是使用可靠的开源工具构建的,它并没有试图在每个转弯处重复发明轮子,并且它适用于我想要做的备份。

最后,使我倾向于它的原因是 ZRM 提供了我的自制脚本不提供的几件事。这些包括自动创建校验和以验证备份是否仍然良好、为新的数据库服务器提供更快且高度可定制的设置以及轻松恢复。如果有时间,我可以将所有这些添加到我的脚本中。但这是我现在没有的时间,而且我似乎永远没有足够的时间(如果您知道在哪里可以找到一些时间,请告诉我)。因此,尽管存在一些粗糙之处,但我发现 Zmanda Recovery Manager for MySQL 社区版对于我的所有 MariaDB 服务器来说都是一个良好的备份解决方案。

资源

Zmanda Recovery Manager for MySQL:zmanda.com/backup-mysql.html

社区下载页面:www.zmanda.com/download-zrm.php

Daniel Bartholomew 在 Monty Program (montyprogram.com) 担任技术作家和系统管理员。他与妻子和孩子住在北卡罗来纳州,并且经常可以在 Freenode IRC 上的 #maria 和 #linuxjournal 频道找到他。

加载 Disqus 评论