介绍
定期的数据库备份是防止意外数据丢失事件的关键步骤. 设计有效的备份和恢复策略通常涉及交易性能影响,实施成本和数据存储成本,包括恢复速度,数据完整性和备份覆盖。 最佳解决方案将取决于您的恢复点和时间(目标)(https://en.wikipedia.org/wiki/Recovery_point_objective)和数据库规模和架构。
在本指南中,我们将展示如何使用LVM快照执行运行MySQL数据库的实时(或)物理备份,然后将数据压缩和存储在DigitalOcean空间中。
本教程中介绍的程序适用于大型MySQL数据库,使用混合的存储引擎(如InnoDB、TokuDB 和 MyISAM)的数据库,以及使用 LVM 管理的具有多个块存储量的数据库服务器。
我们将首先确保我们的 Ubuntu 16.04 服务器可以拍摄并安装 LVM 快照,接下来,我们将拍摄包含 MySQL 数据目录的逻辑卷的 LVM 快照,然后安装此快照卷(冻结的逻辑卷),并将 MySQL 数据目录压缩并发送到 DigitalOcean Spaces 进行存储。
前提条件
要使用本指南,您需要具备以下先决条件:
- Ubuntu 16.04 Drotlet 具有sudo权限的非根用户,详见 [Initial Server setup with Ubuntu 16.04] (https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-16-04).
- 运行中的MySQL 5.7+安装,详见[How To Introduction MySQL on Ubuntu 16.04] (https://andsky.com/tech/tutorials/how-to-install-mysql-on-ubuntu-16-04)
- 联合国 用于存储您的 MySQL 数据库数据目录的 LVM 逻辑卷 :
- 为了更多地了解LVM和如何建立逻辑卷,请查阅LVM概念、术语和业务简介
- 要进一步了解MySQL的数据目录从默认的'/var/lib/mysql'位置移动,请查阅[如何将 MySQL 数据目录移动到Ubuntu 16.04] (https://andsky.com/tech/tutorials/how-to-move-a-mysql-data-directory-to-a-new-location-on-ubuntu-16-04)
- 数字海洋空间和一套API证书,详见[如何创建数字海洋空间和API Key.] (https://andsky.com/tech/tutorials/how-to-create-a-digitalocean-space-and-api-key)
- 联合国 `s3cmd' 命令行文件传输客户端( 2.X) 已安装,详见[ Step 1** How To Logrotate and S3cmd to Archive Logs to Object Survey on Ubuntu 16.04] (https://andsky.com/tech/tutorials/how-to-use-logrotate-and-s3cmd-to-archive-logs-to-object-storage-on-ubuntu-16-04# step-1-%E2%80%94-installing-s3cmd).
- 为访问您的空间而配置的`s3cmd',详见[如何配置 s3cmd 2.x 管理数字海洋空间] (https://andsky.com/tech/tutorials/how-to-configure-s3cmd-2-x-to-manage-digitalocean-spaces)
一旦你已经设置了所有这些,你已经准备好开始这个指南。
第1步:研究MySQL和LVM配置
首先,我们将找到我们的MySQL数据目录,并记住有关LVM配置的这些细节。
定位 MySQL datadir
要找到通往您的 MySQL 数据目录的路径,请运行以下命令:
1mysqladmin -u root -p variables | grep datadir
请在提示时输入您的MySQL根
密码,您应该看到类似于以下的输出:
1[secondary_label Output]
2| datadir | /data/mysql/
对于本指南中使用的 MySQL 安装,数据目录为 /data/mysql
。
现在我们需要确认 /data/mysql' 生活在一个 LVM 逻辑卷上. 为了确认这一点,我们将运行
lsblk`:
1lsblk
你应该看到类似于以下的输出:
1[secondary_label Output]
2NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
3sda 8:0 0 600G 0 disk
4└─vg1-mysql_data 252:0 0 475G 0 lvm /data
5vda 253:0 0 160G 0 disk
6├─vda1 253:1 0 159.9G 0 part /
7├─vda14 253:14 0 4M 0 part
8└─vda15 253:15 0 106M 0 part /boot/efi
从此我们观察到,‘/data’实际上是LVM逻辑卷名为‘mysql_data’的安装点,它是卷组‘vg1’的一员。
我们现在需要确保在我们的卷组vg1
中有足够的可用空间来拍摄LVM截图。
探索 LVM 配置
重要的是要注意,本节所描述的命令的输出将取决于您的服务器的硬件和LVM配置,让我们快速研究本指南使用的Ubuntu 16.04服务器的硬件和LVM配置。
首先,让我们看看我们使用pvscan
有多少物理卷:
1sudo pvscan
你应该看到类似于以下的输出:
1[secondary_label Output]
2 PV /dev/sda VG vg1 lvm2 [500.00 GiB / 25.00 GiB free]
3 Total: 1 [500.00 GiB] / in use: 1 [500.00 GiB] / in no VG: 0 [0 ]
我们观察到,我们有一个500GB的物理体积(/dev/sda
)在一个体积组(vg1
)。
我们可以通过使用vgdisplay
命令更深入地研究vg1
卷组:
1sudo vgdisplay
您应该看到类似于以下的输出:
1[secondary_label Output]
2--- Volume group ---
3 VG Name vg1
4 System ID
5 Format lvm2
6 Metadata Areas 1
7 Metadata Sequence No 2
8 VG Access read/write
9 VG Status resizable
10 MAX LV 0
11 Cur LV 1
12 Open LV 1
13 Max PV 0
14 Cur PV 1
15 Act PV 1
16 VG Size 500.00 GiB
17 PE Size 4.00 MiB
18 Total PE 127999
19 Alloc PE / Size 121600 / 475.00 GiB
20 Free PE / Size 6399 / 25.00 GiB
21 VG UUID KEsoDE-zON7-NdyO-ioxb-6FSl-CB4m-S3QCRj
从 Alloc PE / Size 和** Free PE / Size** 线上,我们观察到我们有475GB分配,并且在vg1
卷组中有25GB免费。
现在让我们用lvdisplay
来看看这个逻辑卷:
1sudo lvdisplay
你应该看到类似于以下的输出:
1[secondary_label Output]
2 --- Logical volume ---
3 LV Path /dev/vg1/mysql_data
4 LV Name mysql_data
5 VG Name vg1
6 LV UUID T98x9c-zvC1-f0Rw-4ipn-Cxo2-duwk-KUwQQc
7 LV Write Access read/write
8 LV Creation host, time LVM, 2018-04-18 20:11:48 +0000
9 LV Status available
10 # open 1
11 LV Size 475.00 GiB
12 Current LE 121600
13 Segments 1
14 Allocation inherit
15 Read ahead sectors auto
16 - currently set to 256
17 Block device 252:0
从 LV Size 我们可以看到,我们有一个475GB的逻辑卷,)。
要总结一下,在本教程中使用的Ubuntu 16.04服务器上,我们有一个500GB的物理体积(/dev/sda
)用于支持一个体积组(vg1
),从中我们创建了一个单一的475GB的逻辑体积(mysql_data
)。
您的硬件和 LVM 配置可能会有所不同;您可能有多个区块存储设备附加,聚合到单个或多个卷组中。
使用本节中列出的命令系列,您现在应该对 LVM 和硬件配置有一个一般的感觉。
在下一步中,我们将为您的数据库服务器准备LVM snapshotting。
步骤 2 — 准备您的服务器为 LVM 快照
为了确保我们可以安全地拍摄 LVM 快照,我们需要提供足够的磁盘空间来覆盖在备份和文件传输到 Spaces 期间可能发生的任何写作或更改。 根据您的数据库的大小,此备份可能需要几个小时才能完成,所以最好在这里小心错误。
在前一个步骤中,我们看到包含我们主要逻辑量的卷组(`vg1')只有25GB自由。 虽然25GB的更改可能不会在备份我们数据库的时间内被写入磁盘,但我们希望至少100GB的安全范围. 在制作环境中,衡量预定备份窗口内向磁盘所写数据的平均数量并相应扩大快照体积大小是最佳做法.
要将额外的75GB空间添加到)。
<$>[注] 注: 某些区域尚未支持区块存储,您可能无法将区块存储量附加到您的Droplet。
让我们扩展附加到此Droplet的区块存储量。
导航到DigitalOcean的Web控制面板,然后从仪表板导航到您的Droplet。
在侧面栏中,单击 Volumes :
从此窗格,您应该看到任何附加到您的Droplet的区块存储量。对于本指南中使用的Ubuntu Droplet,我们有一个附加的区块存储量:
点击 更多 ,然后点击** 更大音量** 。
从这里,你可以选择几个预定义的音量大小之一,或者选择自己的音量大小. 让我们将500GB的音量增加100GB到600GB:
按 继续 . 您的附加区块存储容量现在增加了 100GB。
要将此设备变更传播到LVM,我们需要运行pvresize
。
登录到您的服务器,然后再次运行pvscan
来扫描物理卷:
1sudo pvscan
您应该看到我们 `/dev/sda’ 物理体积的相同输出:
1[secondary_label Output]
2 PV /dev/sda VG vg1 lvm2 [500.00 GiB / 25.00 GiB free]
3 Total: 1 [500.00 GiB] / in use: 1 [500.00 GiB] / in no VG: 0 [0 ]
现在,在音量上运行pvresize
,以填补我们刚刚添加的额外空间:
1sudo pvresize /dev/sda
你应该看到以下结果:
1[secondary_label Output]
2Physical volume "/dev/sda" changed
31 physical volume(s) resized / 0 physical volume(s) not resized
让我们通过运行另一个pvscan
来确认我们的物理容量现在大于100GB:
1sudo pvscan
我们观察到 `/dev/sda’的物理容量现在为600GB:
1[secondary_label Output]
2 PV /dev/sda VG vg1 lvm2 [600.00 GiB / 125.00 GiB free]
3 Total: 1 [600.00 GiB] / in use: 1 [600.00 GiB] / in no VG: 0 [0 ]
现在让我们确认,我们体积组的可用空间也增加了100GB:
1sudo vgdisplay
然后你应该看到以下的输出:
1[secondary_label Output]
2 --- Volume group ---
3 VG Name vg1
4 System ID
5 Format lvm2
6 Metadata Areas 1
7 Metadata Sequence No 3
8 VG Access read/write
9 VG Status resizable
10 MAX LV 0
11 Cur LV 1
12 Open LV 1
13 Max PV 0
14 Cur PV 1
15 Act PV 1
16 VG Size 600.00 GiB
17 PE Size 4.00 MiB
18 Total PE 153599
19 Alloc PE / Size 121600 / 475.00 GiB
20 Free PE / Size 31999 / 125.00 GiB
21 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数据库:
1mysql -u root -p
从MySQL壳中运行FLUSH TABLES
命令来读取数据库。
<$>[警告] 警告: 执行下列命令后,所有打开的表将被关闭,所有数据库的所有表将被锁定以全球读取锁。
1FLUSH TABLES WITH READ LOCK;
你应该看到以下结果:
1[secondary_label Output]
2Query OK, 0 rows affected (0.00 sec)
这表明您的数据库已被读取锁定,不要退出MySQL提示,我们需要保持它打开。
我们现在将创建并安装一个LVM截图,用于存储我们的MySQL数据的逻辑量。
创建和 Mount Snapshot 卷
保持这个 MySQL 客户端连接打开时,请从新的终端窗口登录您的数据库服务器。
<$>[警告] 警告: 如果关闭此连接,锁将被抛弃,写字将恢复,使快照不一致。
我们现在可以拍摄mysql_data
的逻辑量。我们将分配100GB的缓冲空间来吸收写作和其他更改,当我们进行物理备份时。
1sudo lvcreate -L 100G -s -n mysql_data_snap /dev/vg1/mysql_data
-L
标志指定了逻辑卷的大小,在这种情况下是 100GB. -s
表示逻辑卷将是一个瞬间截图,在这种情况下是 `/dev/vg1/mysql_data' 逻辑卷。
你应该看到以下结果:
1[secondary_label Output]
2Logical volume "mysql_data_snap" created.
这表明我们现在有一个mysql_data
逻辑卷的副本,从中我们可以进行备份。
现在我们在某个时候基本上已经冻结
了我们的MySQL数据文件,我们可以解锁我们的数据库表并恢复写作。
1UNLOCK TABLES;
你应该看到以下结果:
1[secondary_label Output]
2Query OK, 0 rows affected (0.00 sec)
表已解锁,您现在可以安全地关闭此连接。
在此时刻,您的数据库仍然活跃并接受接入连接和写入,但我们在我们运行)有数据的一致截图。
最后一步是安装此快照,以便我们可以访问这些冻结的数据文件。
首先,我们将创建一个名为 /backup_src
的安装点:
1sudo mkdir /backup_src
现在,我们会将 snapshot 音量设置为 /backup_src
:
1sudo mount /dev/vg1/mysql_data_snap /backup_src
我们现在可以访问被冻结的数据文件,让我们看看:
1cd /backup_src
2ls
您应该看到您的MySQL数据目录:
1[secondary_label Output]
2lost+found mysql
现在我们可以访问我们数据的一致截图,我们可以将其备份到数字海洋空间。
步骤4 - 压缩和上传文件到DigitalOcean空间
要将此备份上传到我们的DigitalOcean Space,我们将使用我们在 [前提步骤]中安装和配置的 s3cmd
工具(https://andsky.com/tech/tutorials/how-to-back-up-a-mysql-database-to-spaces-using-lvm-snapshots# prerequisites)。
我们将首先测试我们的):
1s3cmd info s3://mysql-backup-demo/
你应该看到以下结果:
1[secondary_label Output]
2s3://mysql-backup-demo/ (bucket):
3 Location: nyc3
4 Payer: BucketOwner
5 Expiration Rule: none
6 Policy: none
7 CORS: none
8 ACL: 3587522: FULL_CONTROL
此输出表明连接成功,‘s3cmd’可以将对象传输到太空。
我们现在将压缩并上传我们的MySQL数据目录到mysql备份演示
空间:
1sudo tar -czvf - /backup_src/mysql | s3cmd put - s3://mysql-backup-demo/mysql_backup_180423.tar.gz
在这里,我们使用tar
来压缩和存档MySQL数据目录,并将输出输出到s3cmd
,我们使用它来将压缩的档案转移到Spaces。
由于我们在语音模式中使用了)。
输出将以以下文件传输信息结束:
1[secondary_label Output]
2...
3upload: '<stdin>' -> 's3://mysql-backup-demo/mysql_backup_180423.tar.gz' [part 1, 1417kB]
4 1451996 of 1451996 100% in 0s 1993.41 kB/s done
一旦转移完成,我们将通过列出空间内容来验证该文件已成功转移到我们的空间:
1s3cmd ls s3://mysql-backup-demo/
你应该看到备份档案文件:
1[secondary_label Output]
22018-04-23 20:39 297 s3://mysql-backup-demo/mysql_backup_180423.tar.gz
此时,我们已经成功完成了对 DigitalOcean Spaces 的物理MySQL备份。
现在我们将拆卸并放下即刻拍摄的音量,将所使用的空间恢复到我们的音量组 vg1
。
步骤5 - 解除和放下快照卷
现在,我们的数据已备份,我们不再有任何用途为我们在本教程中早些时候创建的快照量,可以安全地放下它。
要卸载音量,运行以下命令:
1sudo umount /backup_src
将 /backup_src
替换为您的 snapshot 卷的安装点。
我们现在可以放下快照的音量. 要做到这一点,运行以下命令:
1sudo lvremove vg1/mysql_data_snap
在这里,‘vg1’相当于您的卷组名称,而‘mysql_data_snap’则相当于您的 snapshot 卷名。
您将被要求确认删除,您应该回答 Y 。
你应该看到以下结果:
1[secondary_label Output]
2 Logical volume "mysql_data_snap" successfully removed
你已经完成了完整的MySQL物理备份,并将其上传到你的DigitalOcean空间。
我们将通过快速运行恢复场景来完成本教程。
步骤 6 – 测试从物理备份恢复
为了从我们之前上传到 Spaces 的物理备份中恢复我们的 MySQL 数据库,我们会将备份转移到我们的数据库服务器,然后将提取的文件用作恢复的 MySQL 数据目录。
让我们先将备份从我们的空间转移到数据库服务器上的用户主目录:
1s3cmd get s3://mysql-backup-demo/mysql_backup_180423.tar.gz ~/mysql_backup_180423.tar.gz
你应该看到一些文件传输的输出:
1[secondary_label Output]
2download: 's3://mysql-backup-demo/mysql_backup_180423.tar.gz' -> '~/mysql_backup_180423.tar.gz' [1 of 1]
3 1451889 of 1451889 100% in 0s 38.49 MB/s done
现在我们将停止运行数据库服务器并清除现有数据目录,因为我们希望从物理备份文件中测试清洁恢复。
首先,停止 MySQL 服务器:
1sudo service mysql stop
现在,删除您的MySQL数据目录的内容:
1sudo rm -rf /data/*
请记住,在本教程中,非默认的MySQL数据目录路径是/data
。
现在,将物理备份档案提取到您的MySQL数据目录:
1sudo tar -xzvf ~/mysql_backup_180423.tar.gz -C /data
现在数据文件已经恢复,我们可以重新启动MySQL数据库并允许它恢复:
1sudo service mysql start
最后,我们可以登录到我们的数据库服务器,以验证恢复成功完成:
1mysql -u root -p
输入密码后,您应该看到MySQL客户端提示:
1[secondary_label Output]
2Welcome to the MySQL monitor. Commands end with ; or \g.
3Your MySQL connection id is 4
4Server version: 5.7.21-0ubuntu0.16.04.1 (Ubuntu)
5
6Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
7
8Oracle is a registered trademark of Oracle Corporation and/or its
9affiliates. Other names may be trademarks of their respective
10owners.
11
12Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
13
14mysql>
从这里,您可以扫描一些表以验证您的数据是完整的。
结论
在本教程中,我们展示了如何利用LVM的快照功能来冻结文件系统并执行完整的物理备份和运行MySQL实例的恢复。
在生产设置中,这个过程最好是用适当的日志、监控和警报来编写并安排的。此外,一个‘FLUSH TABLES WITH READ LOCK’(不论是多么短暂)不应该在主服务器上运行,而应该在负载最小的副本上运行。
如果您的 MySQL 实例仅使用 InnoDB 作为存储引擎,您也可以使用 Percona XtraBackup 以类似的方式对您的数据库进行物理备份。 要了解更多信息,请参阅我们的教程(How To Back Up MySQL Databases to Object Storage with Percona on Ubuntu 16.04)(https://andsky.com/tech/tutorials/how-to-back-up-mysql-databases-to-object-storage-with-percona-on-ubuntu-16-04)。
将物理备份文件上传到 Spaces 的合理替代方案是使用 LVM 快照与 Droplet Snapshots 结合使用。 有关 Droplet Snapshots 的更多信息,请参阅 DigitalOcean Backups and Snapshots Explained。
要了解更多关于DigitalOcean空间,这个指南中使用的对象商店,请参阅 An Introduction To DigitalOcean Spaces。