如何使用LVM快照将MySQL数据库备份到DigitalOcean空间

来自菜鸟教程
跳转至:导航、​搜索

介绍

定期数据库备份是防止意外数据丢失事件的关键步骤。 设计有效的备份和恢复策略通常涉及在性能影响、实施成本和数据存储成本与恢复速度、数据完整性和备份覆盖率之间进行权衡。 最佳解决方案将取决于您的恢复点和时间 目标 以及数据库规模和架构。

在本指南中,我们将演示如何使用 LVM 快照对正在运行的 MySQL 数据库执行实时(或“热”)物理备份。 然后,我们将压缩数据并将其存储在 DigitalOcean Space 中。

本教程中介绍的过程非常适合大型 MySQL 数据库、使用混合存储引擎(如 InnoDB、TokuDB 和 MyISAM)的数据库,以及附加了多个块存储卷并使用 LVM 管理的数据库服务器。

我们将首先确保我们的 Ubuntu 16.04 服务器可以拍摄和挂载 LVM 快照。 接下来,我们将拍摄包含 MySQL 数据目录的逻辑卷的 LVM 快照。 然后我们将挂载这个快照卷(冻结的逻辑卷),并将 MySQL 数据目录压缩并传送到 DigitalOcean Spaces 进行存储。 最后,我们将简要介绍一个示例恢复场景。

先决条件

要使用本指南,您需要满足以下先决条件:

完成所有这些设置后,您就可以开始阅读本指南了。

第 1 步 — 调查 MySQL 和 LVM 配置

首先,我们将找到我们的 MySQL 数据目录并记下有关我们的 LVM 配置的详细信息。

定位 MySQL datadir

要查找 MySQL 数据目录的路径,请运行以下命令:

mysqladmin -u root -p variables | grep datadir

出现提示时输入您的 MySQL root 密码。 您应该会看到类似于以下内容的输出:

Output| datadir                                                  | /data/mysql/

对于本指南中使用的 MySQL 安装,数据目录为 /data/mysql

我们现在需要确认 /data/mysql 位于 LVM 逻辑卷上。 为了确认这一点,我们将运行 lsblk

lsblk

您应该会看到类似于以下内容的输出:

OutputNAME             MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                8:0    0   600G  0 disk
└─vg1-mysql_data 252:0    0   475G  0 lvm  /data
vda              253:0    0   160G  0 disk
├─vda1           253:1    0 159.9G  0 part /
├─vda14          253:14   0     4M  0 part
└─vda15          253:15   0   106M  0 part /boot/efi

由此我们观察到 /data 实际上是名为 mysql_data 的 LVM 逻辑卷的挂载点。 它是卷组 vg1 的成员。

我们现在需要确保我们的卷组 vg1 中有足够的可用空间来拍摄 LVM 快照。

探索 LVM 配置

请务必注意,本节中描述的命令的输出将根据服务器的硬件和 LVM 配置而有所不同。 让我们快速研究一下本指南中使用的 Ubuntu 16.04 服务器的硬件和 LVM 配置。

首先,让我们看看使用 pvscan 有多少物理卷:

sudo pvscan

您应该会看到类似于以下内容的输出:

Output  PV /dev/sda   VG vg1             lvm2 [500.00 GiB / 25.00 GiB free]
  Total: 1 [500.00 GiB] / in use: 1 [500.00 GiB] / in no VG: 0 [0   ]

我们观察到我们有一个 500GB 的物理卷 (/dev/sda),它位于一个卷组 (vg1) 中。 此物理卷的 475GB 已分配给逻辑卷,而 25GB 仍可供卷组使用。

我们可以通过使用 vgdisplay 命令更深入地查看 vg1 卷组来确认这一点:

sudo vgdisplay

您应该看到类似于以下内容的输出:

Output--- Volume group ---
  VG Name               vg1
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  2
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               500.00 GiB
  PE Size               4.00 MiB
  Total PE              127999
  Alloc PE / Size       121600 / 475.00 GiB
  Free  PE / Size       6399 / 25.00 GiB
  VG UUID               KEsoDE-zON7-NdyO-ioxb-6FSl-CB4m-S3QCRj

Alloc PE / SizeFree PE / Size 行中,我们观察到在 vg1 卷组中分配了 475GB 和 25GB 空闲空间。 Cur PV 行显示我们在这个卷组中有 1 个物理卷。 Cur LV 行表明我们已使用此卷组中的空间池来创建 1 个逻辑卷。

现在让我们使用 lvdisplay 来看看这个逻辑卷:

sudo lvdisplay

您应该会看到类似于以下内容的输出:

Output  --- Logical volume ---
  LV Path                /dev/vg1/mysql_data
  LV Name                mysql_data
  VG Name                vg1
  LV UUID                T98x9c-zvC1-f0Rw-4ipn-Cxo2-duwk-KUwQQc
  LV Write Access        read/write
  LV Creation host, time LVM, 2018-04-18 20:11:48 +0000
  LV Status              available
  # open                 1
  LV Size                475.00 GiB
  Current LE             121600
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           252:0

LV Size 我们看到我们有一个 475GB 的逻辑卷,mysql_data,在 /dev/vg1/mysql_data 找到(回想 vg1mysql_data 的卷组)。

总而言之,在本教程使用的 Ubuntu 16.04 服务器上,我们有一个 500GB 物理卷 (/dev/sda) 用于支持一个卷组 (vg1),我们从中创建了一个475GB 逻辑卷 (mysql_data)。 这会在卷组中留下 25GB 的可用空间,可用于创建更多逻辑卷(和快照)。

您的硬件和 LVM 配置可能会有所不同; 您可能连接了多个块存储设备,汇集到单个或多个卷组中。 然而,为给定逻辑卷拍摄快照的过程将是相同的。

使用本节介绍的一系列命令,您现在应该对 LVM 和硬件配置有一个大致的了解。

在下一步中,我们将为您的数据库服务器准备 LVM 快照。

第 2 步 — 为 LVM 快照准备您的服务器

为了确保我们可以安全地拍摄 LVM 快照,我们需要提供足够的磁盘空间来覆盖在备份和文件传输到 Spaces 期间可能发生的任何写入或更改。 根据您的数据库的大小,此备份可能需要几个小时才能完成,因此最好谨慎行事。 如果您的快照卷在执行备份时空间不足,则快照卷将失效,您将不再拥有一致的备份。

在上一步中,我们观察到包含我们的主逻辑卷 (mysql_data) 的卷组 (vg1) 只有 25GB 可用空间。 尽管在备份我们的数据库所需的时间内可能不会将 25GB 的更改写入磁盘,但理想情况下,我们希望至少有 100GB 的安全边际。 在生产环境中,最好的做法是测量计划备份窗口期间写入磁盘的平均数据量,并相应地缩放快照卷的大小。

要向 vg1 卷组添加额外的 75GB 空间,我们可以附加块存储设备,或者增加当前附加到 Droplet 的卷的大小。 在本教程中,我们将扩展已附加的块存储卷; 要了解有关附加块存储卷的更多信息,您可以参考 DigitalOcean 块存储简介

注意: 部分地区尚不支持 Block Storage,您可能无法将 Block Storage 卷附加到您的 Droplet。 在这种情况下,一个合理的解决方法是对您的 Droplet 进行快照并使用此快照图像创建一个新的 Droplet,然后您可以向其中添加块存储。


让我们扩展附加到这个 Droplet 的块存储卷。

导航到 DigitalOcean 的 Web 控制面板,然后从仪表板导航到您的 Droplet。

在侧边栏中,单击 Volumes

在此窗格中,您应该看到附加到您的 Droplet 的任何块存储卷。 对于本指南中使用的 Ubuntu Droplet,我们有一个附加的块存储卷:

单击更多,然后单击调整音量

从这里,您可以选择几个预定义的卷大小之一,或选择您自己的卷大小。 让我们将 500GB 的卷增加 100GB 到 600GB:

继续 。 您的附加块存储卷现在增加了 100GB。

要将此设备更改传播到 LVM,我们需要运行 pvresize

登录到您的服务器,然后再次运行 pvscan 以扫描物理卷:

sudo pvscan

对于我们的 /dev/sda 物理卷,您应该看到与之前相同的输出:

Output PV /dev/sda   VG vg1             lvm2 [500.00 GiB / 25.00 GiB free]
  Total: 1 [500.00 GiB] / in use: 1 [500.00 GiB] / in no VG: 0 [0   ]

现在,在卷上运行 pvresize 以填充我们刚刚添加的额外空间:

sudo pvresize /dev/sda

您应该看到以下输出:

OutputPhysical volume "/dev/sda" changed
1 physical volume(s) resized / 0 physical volume(s) not resized

让我们通过运行另一个 pvscan 来确认我们的物理卷现在大了 100GB:

sudo pvscan

我们观察到 /dev/sda 物理卷现在是 600GB:

Output PV /dev/sda   VG vg1             lvm2 [600.00 GiB / 125.00 GiB free]
 Total: 1 [600.00 GiB] / in use: 1 [600.00 GiB] / in no VG: 0 [0   ]

现在让我们确认我们的卷组的可用空间也增加了 100GB:

sudo vgdisplay

然后,您应该会看到以下输出:

Output  --- Volume group ---
  VG Name               vg1
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               600.00 GiB
  PE Size               4.00 MiB
  Total PE              153599
  Alloc PE / Size       121600 / 475.00 GiB
  Free  PE / Size       31999 / 125.00 GiB
  VG UUID               KEsoDE-zON7-NdyO-ioxb-6FSl-CB4m-S3QCRj

这表明我们现在有 125GB 的可用空间来创建我们的快照卷。

就本教程而言,125GB 足以在备份和上传过程中吸收写入和更改,但在生产设置中,快照卷大小应与备份窗口期间的预期磁盘使用量成比例缩放。

现在我们的卷组中有足够的可用空间来覆盖快照和备份期间可能发生的任何写入或更改,我们可以继续创建快照卷。

第 3 步 — 创建和挂载 LVM 快照

警告: 当 LVM 快照处于活动状态时,写入磁盘时会出现一些性能下降。 您应该首先使用具有模拟负载的非生产数据库测试此过程,以验证此方法是否适用于您的生产部署。


我们现在将使用 lvcreate 创建 mysql_data 逻辑卷的快照。 在我们这样做之前,我们需要使用 FLUSH TABLES WITH READ LOCK 冻结对数据库的写入,以便我们可以保证数据的一致性。 这些表只需要在我们运行 lvcreate 之前被读锁定,此时它们可以被解锁。 如果您编写这一系列命令的脚本,则总锁定时间应该非常短,具体取决于当前执行的写入查询。

读锁 MySQL 数据库

让我们从刷新表开始。 从您的数据库服务器上的终端,使用 mysql 登录您的 MySQL 数据库:

mysql -u root -p

在 MySQL shell 中,运行 FLUSH TABLES 命令以读取锁定您的数据库。

警告: 运行以下命令后,所有打开的表将被关闭,所有数据库的所有表都将被全局读锁锁定。 如果在生产数据库上运行此命令,最佳实践是在副本上执行此命令或作为脚本的一部分,以最大程度地减少数据库锁定的时间。


FLUSH TABLES WITH READ LOCK;

您应该看到以下输出:

OutputQuery OK, 0 rows affected (0.00 sec)

这表明您的数据库已被读锁定。 不要退出 MySQL 提示,我们需要让它保持打开状态。

我们现在将创建并挂载用于存放 MySQL 数据的逻辑卷的 LVM 快照。

      1. 创建和挂载快照卷

保持此 MySQL 客户端连接打开,从新的终端窗口登录到您的数据库服务器。

警告: 如果关闭此连接,锁将被丢弃并恢复写入,导致快照不一致。


我们现在可以拍摄 mysql_data 逻辑卷的快照。 在执行物理备份时,我们将分配 100GB 的缓冲区空间来吸收写入和其他更改。 要创建 LVM 快照,请运行以下 lvcreate 命令:

sudo lvcreate -L 100G -s -n mysql_data_snap /dev/vg1/mysql_data

-L 标志指定逻辑卷的大小,在本例中为 100GB。 -s 表示逻辑卷将是快照,在本例中为 /dev/vg1/mysql_data 逻辑卷。 我们选择将此快照卷命名为 mysql_data_snap

您应该看到以下结果:

OutputLogical volume "mysql_data_snap" created.

这表明我们现在拥有 mysql_data 逻辑卷的副本,我们可以从中执行备份。

现在我们基本上已经在某个时间点“冻结”了我们的 MySQL 数据文件,我们可以解锁我们的数据库表并恢复写入。 从您打开的 MySQL 连接中,运行以下命令:

UNLOCK TABLES;

您应该看到以下结果:

OutputQuery OK, 0 rows affected (0.00 sec)

表已解锁,您现在可以安全地关闭此连接。

此时,您的数据库仍然处于活动状态并接受传入的连接和写入,但是我们在运行 FLUSH TABLES WITH READ LOCK 的时间点(或者完全准确地说,时间点)拥有一致的数据快照FLUSH 后的最后一次写入查询完成时)。

最后一步是挂载这个快照,以便我们可以访问这些冻结的数据文件。

首先,我们将创建一个名为 /backup_src 的挂载点:

sudo mkdir /backup_src

现在,我们将快照卷挂载到 /backup_src

sudo mount /dev/vg1/mysql_data_snap /backup_src

我们现在可以访问冻结的数据文件。 让我们来看看:

cd /backup_src
ls

你应该看到你的 MySQL 数据目录:

Outputlost+found  mysql

现在我们可以访问数据的一致快照,我们可以将其备份到 DigitalOcean Space。

第 4 步 — 压缩文件并将其上传到 DigitalOcean Spaces

要将此备份上传到我们的 DigitalOcean Space,我们将使用我们在 先决条件步骤 中安装和配置的 s3cmd 工具。

我们将首先测试我们的 s3cmd 配置并尝试访问我们的备份空间(在本教程中,我们的空间被命名为 mysql-backup-demo):

s3cmd info s3://mysql-backup-demo/

您应该看到以下输出:

Outputs3://mysql-backup-demo/ (bucket):
   Location:  nyc3
   Payer:     BucketOwner
   Expiration Rule: none
   Policy:    none
   CORS:      none
   ACL:       3587522: FULL_CONTROL

此输出表示连接成功,并且 s3cmd 可以将对象传输到空间。

我们现在将我们的 MySQL 数据目录压缩并上传到 mysql-backup-demo 空间:

sudo tar -czvf - /backup_src/mysql | s3cmd put - s3://mysql-backup-demo/mysql_backup_180423.tar.gz

在这里,我们使用 tar 来压缩和存档 MySQL 数据目录,并将输出通过管道传输到 s3cmd,我们使用它来将压缩的存档传输到 Spaces。 我们将压缩存档命名为 mysql_backup_180423.tar.gz

由于我们在详细模式下使用了 tar,您将看到正在压缩的文件列表(要隐藏此输出,请省略上述命令中的 -v 标志)。

输出将以以下文件传输信息结束:

Output...
upload: '<stdin>' -> 's3://mysql-backup-demo/mysql_backup_180423.tar.gz'  [part 1, 1417kB]
 1451996 of 1451996   100% in    0s  1993.41 kB/s  done

传输完成后,我们将通过列出空间内容来验证文件是否已成功传输到我们的空间:

s3cmd ls s3://mysql-backup-demo/

您应该看到备份存档文件:

Output2018-04-23 20:39       297   s3://mysql-backup-demo/mysql_backup_180423.tar.gz

至此,我们已经成功完成了对 DigitalOcean Spaces 的物理 MySQL 备份。

我们现在将卸载并删除快照卷,将已用空间恢复到我们的卷组 vg1

第 5 步 — 卸载和删除快照卷

现在我们的数据已经备份,我们不再使用我们在本教程前面创建的快照卷,可以安全地删除它。

要卸载卷,请运行以下命令:

sudo umount /backup_src

/backup_src 替换为您的快照卷的挂载点。

我们现在可以删除快照卷。 为此,请运行以下命令:

sudo lvremove vg1/mysql_data_snap

这里,vg1 对应您的卷组名称,mysql_data_snap 对应您的快照卷名称。

系统将提示您确认删除,您应回复 Y

您应该看到以下输出:

Output Logical volume "mysql_data_snap" successfully removed

快照卷已成功删除。 您现在已经完成了完整的 MySQL 物理备份并将其上传到您的 DigitalOcean Space。

我们将通过快速运行恢复方案来结束本教程。

第 6 步 — 从物理备份测试恢复

为了从我们之前上传到 Spaces 的物理备份中恢复我们的 MySQL 数据库,我们将备份传输到我们的数据库服务器,然后使用提取的文件作为我们恢复的 MySQL 数据目录。

让我们首先将备份从我们的空间传输回数据库服务器上用户的主目录:

s3cmd get s3://mysql-backup-demo/mysql_backup_180423.tar.gz ~/mysql_backup_180423.tar.gz

您应该看到一些文件传输输出:

Outputdownload: 's3://mysql-backup-demo/mysql_backup_180423.tar.gz' -> '~/mysql_backup_180423.tar.gz'  [1 of 1]
 1451889 of 1451889   100% in    0s    38.49 MB/s  done

我们现在将停止正在运行的数据库服务器并清除现有数据目录,因为我们想测试从物理备份文件的干净还原。

首先,停止 MySQL 服务器:

sudo service mysql stop

现在,删除 MySQL 数据目录的内容:

sudo rm -rf /data/*

回想一下,在本教程中,非默认 MySQL 数据目录路径是 /data

现在,将物理备份存档解压缩到您的 MySQL 数据目录:

sudo tar -xzvf ~/mysql_backup_180423.tar.gz -C /data

现在数据文件已经恢复,我们可以重新启动 MySQL 数据库并让它恢复:

sudo service mysql start

最后,我们可以登录到我们的数据库服务器来验证还原是否成功完成:

mysql -u root -p

输入密码后,您应该会看到 MySQL 客户端提示:

OutputWelcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.21-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

从这里您可以扫描一些表以验证您的数据是否完整。

结论

在本教程中,我们演示了如何利用 LVM 的快照功能来冻结文件系统并对正在运行的 MySQL 实例执行完整的物理备份和恢复。 如果您使用 LVM 来管理一个或多个包含 MySQL 数据的存储卷,则此功能提供了一种方便的方法来备份您的生产数据库。

在生产环境中,理想情况下,此过程应编写脚本并安排适当的日志记录、监控和警报。 此外,不应在主服务器上运行 FLUSH TABLES WITH READ LOCK(无论多么简短),而应在负载最小的副本上运行。 请注意,稍作修改,您还可以调整上述过程以从主物理备份快速启动副本。

如果您的 MySQL 实例专门使用 InnoDB 作为其存储引擎,您还可以使用 Percona XtraBackup 以类似的方式执行数据库的物理备份。 要了解更多信息,请参阅我们关于 如何在 Ubuntu 16.04 上使用 Percona 将 MySQL 数据库备份到对象存储的教程。

将物理备份文件上传到 Spaces 的合理替代方法是将 LVM 快照与 Droplet 快照结合使用。 要了解有关 Droplet 快照的更多信息,请参阅 DigitalOcean 备份和快照说明

要了解有关本指南中使用的对象存储 DigitalOcean Spaces 的更多信息,请参阅 DigitalOcean Spaces 简介