【MySQL备份】lvm-snapshot实战篇

1.简介

LVM快照 LVM Snapshot 是Logical Volume Manager 逻辑卷管理器 的一个重要特性,它允许用户在某一时间点创建一个卷的只读副本,这个副本反映了原始卷在创建快照时刻的数据状态。这一功能对于数据备份、系统升级前的即时状态保存、数据迁移等场景非常有用。下面是LVM快照的一些关键点和工作原理:

1.1.如何工作

  • 创建快照:当创建一个LVM快照时,LVM实际上并不立即复制原始卷的所有数据到新的快照卷上,这样做会非常耗时且占用大量空间。相反,LVM仅记录自快照创建以来发生变化的块。这时,快照卷和原始卷共享未变更的数据块。

  • 独立变化:随着时间推移,如果原始卷上的数据发生变化,LVM会将变化前的数据块复制到快照卷上,以保持快照数据的一致性。这意味着快照卷会逐渐占用更多的存储空间,因为它需要存储越来越多与原始卷不同的数据块。

  • 空间管理:LVM快照的大小 即它可以记录多少更改 是在创建时指定的,随着快照使用空间的增长,达到这个限制后,如果还有更多的更改,快照可能会失效或变得不可用,因此需要合理规划快照的大小。

  • 性能影响:由于LVM快照机制涉及到数据块的复制,尤其是在写密集型的应用中,创建和维护快照可能会对I/O性能产生一定影响。因此,在生产环境中实施快照时,需要评估其对业务运行的潜在影响。

1.2.应用场景

  • 数据备份:在进行物理备份时,先创建LVM快照,然后从快照进行备份,这样可以避免备份过程中数据库的写操作影响数据一致性。
  • 系统测试:可以基于生产环境的快照创建一个测试环境,进行软件升级或配置更改的测试,而不影响生产数据。
  • 数据恢复:在数据损坏或误删的情况下,快照可以作为一种快速恢复手段,恢复到创建快照时的状态。

1.3.注意事项

  • 快照应当视为临时状态的保存,不适合长期存储,因为随着更改量的累积,快照占用的空间会持续增长。
  • 在使用LVM快照进行备份时,应确保快照的生命周期内数据变更量不要超过快照卷的容量,避免数据丢失。

1.4.优缺点

优点 缺点
即时快照:能够在几秒钟内创建一个时间点的快照,几乎不影响系统运行 空间消耗:随着数据变化,快照会占用额外的存储空间,且随时间推移可能迅速增长
一致性备份:在创建快照前后使用适当的锁机制,可以保证数据的一致性 性能影响:快照创建后,对源卷的写操作需要同时更新源卷和快照,可能导致I/O性能下降
在线备份:允许在不停机的情况下进行备份,适合生产环境的实时数据保护 快照生存周期:快照卷有最大容量限制,一旦达到,快照将失效,且无法追加新变更
灵活恢复:可以从快照恢复到任意时间点的数据,提供多种数据恢复方案 管理复杂度:需要合理规划快照大小、监控空间使用,以及适时删除不再需要的快照
灾难恢复:为灾难恢复提供快速的数据恢复点,减少RTO(恢复时间目标) 硬件依赖:仅限于使用LVM管理的卷,对于非LVM环境不适用
资源复用:快照可以用于测试、开发环境,无需额外复制大量数据,节省存储资源 潜在风险:若源卷损坏,且快照未被妥善保护或管理,可能会失去所有数据

2.为什么选择lvm快照备份?

原因:因为锁表的时间不一致,在锁表的瞬间是不能写入的,对其进行快照备份,备份完成后立即解锁,然后服务可以正常使用 写入等操作 比如数据量大的时候,做快照一下子就拍了,然后立即解锁,就不影响写入等操作。如果用mysqldump备份,那么数据量大的时候,锁表时间长,就会影响效率

3.创建LVM

图片来源:

http://Linux下的磁盘管理之LVM详解及lvm的常用磁盘操作命令_yg hunter的博客-CSDN博客_lvm命令

3.1.操作流程

  • flush table with read local;//全局加锁
  • create snapshot;//快照
  • show master status; show slave status;[可选]
  • unlock tables;//释放锁
  • Copy files from the snapshot//从快照卷中复制数据cp tar[40 m]
  • Unmount the snapshot//挂载快照卷
  • Remove snapshot//卸载并删除快照卷

3.2.正常安装MySQL后进行备份

1.安装系统
2.准备LVM
3.安装mysql,默认datadir /var/lib/mysql

3.3.MySQL运行一段时间后进行备份

3.3.1.准备lvm及文件系统//先添加一块磁盘

1
[root localhost centos]# vgcreate datavg /dev/sdb

1
2
[root localhost centos]# lvcreate -L 2G -n mysql datavg //创建2G的VG
[root localhost centos]# mkfs.xfs /dev/datavg/mysql //格式化磁盘分区

3.3.2.将数据迁移到LVM

1
2
3
4
5
6
7
8
9
10
11
[root localhost centos]# systemctl stop mysqld //停止MySQL服务
[root localhost centos]# mount /dev/datavg/mysql /mnt/ //将快照挂载到临时目录
[root localhost centos]# cp -a /var/lib/mysql/* /mnt/ //拷贝MySQL数据到挂载的临时目录

[root localhost centos]# umount /mnt/ //卸载快照
[root localhost centos]# vim /etc/fstab //更改配置文件设置自动挂载
/dev/datavg/mysql /var/lib/mysql xfs defaults 0 0

[root localhost centos]# mount -a //自动挂载/etc/fstab文件没有挂载的设备,不管已挂载过的设备
[root localhost centos]# chown -R mysql.mysql /var/lib/mysql //递归更改/var/lib/mysql主组和属组
[root localhost centos]# systemctl restart mysqld //重启MySQL

3.3.3.LVM快照备份流程

3.3.3.1.加全局锁
1
mysql>flush table with read local;
3.3.3.2.创建快照
1
2
lvcreate -L 500M -s -n mysql-snap /dev/datavg/mysql;
mysql -p'123456' -e ‘show master status’> /backup/ data %F _position.txt
3.3.3.3.释放锁
1
create snapshot;

注意事项:

加全局锁和创建快照必须在同一会话中完成

1
2
[root localhost centos]# echo FLUSH TABLES WITH READ LOCK;SYSTEM lvcreate -L 500M -s -n mysql-snap /dev/datavg/mysql;
| mysql -uroot -p'123456'

3.4.从快照中恢复

3.4.1. 停止MySQL服务

首先,优雅地停止MySQL服务,以避免数据损坏:

1
systemctl stop mysqld

或在较旧的系统中可能是:

1
service mysql stop

3.4.2. 卸载原逻辑卷

如果原逻辑卷仍然挂载,需要先卸载它。比如,如果MySQL数据目录挂载在/var/lib/mysql,则执行:

1
umount /var/lib/mysql

3.4.3. 挂载快照卷

创建一个临时目录,并将快照卷挂载到这个目录:

1
2
mkdir /mnt/mysql_snapshot_recovery
mount /dev/datavg/mysql-snap /mnt/mysql_snapshot_recovery

这里/dev/datavg/mysql-snap是之前创建的快照逻辑卷的路径。

3.4.4. 复制数据

将快照中的数据复制回原逻辑卷的位置。首先,确保原逻辑卷 例如/dev/datavg/mysql 未挂载。然后,使用rsync或cp命令将数据复制回去。rsync是一个较好的选择,因为它可以更高效地处理大文件和大量小文件:

1
rsync -avHAXS --delete /mnt/mysql_snapshot_recovery/ /var/lib/mysql/

这会将快照中的所有内容同步到MySQL的原始数据目录中,并保持权限、时间戳等元数据的一致性。

3.4.5. 卸载快照卷

完成数据复制后,卸载快照卷:

1
umount /mnt/mysql_snapshot_recovery

3.4.6. 启动MySQL服务

启动MySQL服务,检查数据是否恢复成功:

1
systemctl start mysqld

或

1
service mysql start

3.4.7. 验证数据

3.4.8. 清理和后续操作

如果一切正常,你可以考虑删除快照 如果不再需要 ,以释放存储空间:

1
lvremove /dev/datavg/mysql-snap

3.6.脚本制作快照

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash
# 定义备份目录,使用日期作为目录名以保持备份的有序性
back_dir /backup/mysql_$(date %F)

# 检查备份目录是否存在,不存在则创建
[ ! -d $back_dir ] && mkdir -p $back_dir

# 锁定MySQL表并创建LVM快照。注意,这里直接在命令中使用了MySQL的root密码,这在安全性上是个问题。
# 使用-e参数将多行命令传递给mysql,同时建议通过配置文件或环境变量安全地传递密码。
echo FLUSH TABLES WITH READ LOCK; SYSTEM lvcreate -L 500M -s -n mysql-snap /dev/datavg/mysql; | mysql -u root -p'123456'

# 挂载LVM快照为只读模式,避免对快照造成意外修改
mount -o ro,nouuid /dev/datavg/mysql-snap /mnt/

# 使用rsync进行数据同步,从快照目录到备份目录
rsync -a /mnt/ $back_dir

# 检查rsync命令执行状态,如果成功 返回值为0 则进行以下操作
if [ $? -eq 0 ]; then
# 解除MySQL锁
echo UNLOCK TABLES; | mysql -u root -p'123456'

# 卸载快照卷
umount /mnt/

# 删除快照,释放空间
lvremove -f /dev/datavg/mysql-snap
else
echo 备份过程中发生错误,未执行卸载和删除快照操作。
fi

3.7.定时任务管理Cron

要将上述LVM快照备份脚本设置为定时任务,可以使用Linux的Cron服务。以下是设置定时任务的步骤,假设脚本保存为/usr/local/bin/lvm_mysql_backup.sh,并且希望每天凌晨2点执行一次备份:

  • 编辑Crontab配置:

打开终端,运行以下命令来编辑Crontab配置 如果希望以root用户执行脚本,请使用sudo crontab -e,否则,直接使用crontab -e以当前用户身份编辑 :

1
crontab -e
  • 添加定时任务:

在打开的Crontab文件中,移动光标到文件末尾,添加以下行来设置定时任务:

1
0 2 * * * /usr/local/bin/lvm_mysql_backup.sh
  • 这行配置的意思是每天凌晨2点整执行/usr/local/bin/lvm_mysql_backup.sh脚本。

  • 保存并退出:

编辑完成后,保存文件。如果使用的是Nano编辑器,可以按Ctrl O然后回车保存,接着按Ctrl X退出编辑器。

  • 权限设置:

确保脚本具有执行权限。如果尚未设置,可以通过以下命令给予脚本执行权限:

1
sudo chmod x /usr/local/bin/lvm_mysql_backup.sh
  • 测试与验证:

可以通过查看Cron的日志 通常是/var/log/syslog或/var/log/cron.log 来确认任务是否按时执行。此外,可以在计划执行时间之前手动执行一次脚本,以确保脚本没有错误,并能正确完成备份任务。

请注意,为了安全和管理方便,确保脚本中不包含敏感信息 如数据库密码 ,而是通过安全的方式传递这些信息 例如通过环境变量或配置文件 。此外,定期检查备份目录的空间使用情况,确保有足够的空间进行备份,避免因空间不足导致备份失败。