LVM快照不能直接作MySQL备份,因InnoDB内存缓冲与redo log导致文件系统快照不保证数据页一致性;必须先FLUSH TABLES WITH READ LOCK并记录binlog位点,再秒级创建快照,且需挂载后tar导出而非直接拷贝快照LV。

为什么LVM快照不能直接当MySQL备份用
直接拿lvcreate --snapshot生成的LVM快照当MySQL备份,大概率会损坏——因为InnoDB有内存缓冲池和redo log,文件系统层面的快照不保证数据页一致性。MySQL进程还在写磁盘时拍快照,ibdata1或表空间文件可能处于中间状态,恢复后mysqld启动失败、报错InnoDB: Database page corruption很常见。
真正能用的前提只有一个:确保快照时刻MySQL所有脏页已刷盘、且无活跃事务。这需要配合FLUSH TABLES WITH READ LOCK或更稳妥的mysqldump --single-transaction流程,但后者本身不阻塞写入,不能替代锁表动作。
- 必须先执行
FLUSH TABLES WITH READ LOCK(注意:这会阻塞所有写操作) - 紧接着用
SHOW MASTER STATUS记下binlog位置,用于后续搭建从库 - 再立刻创建LVM快照,整个过程控制在秒级内
- 最后执行
UNLOCK TABLES释放锁
如何安全创建LVM快照并打包为可移植备份
LVM快照只是COW(写时复制)的元数据引用,本身不包含完整数据,不能单独拷贝出去。必须把快照LV挂载后,用tar或rsync导出实际文件内容。
假设MySQL数据目录是/var/lib/mysql,所在LV是/dev/vg0/mysql-lv,快照名为mysql-snap:
lvcreate -L 5G -s -n mysql-snap /dev/vg0/mysql-lv mkdir /mnt/mysql-snap mount /dev/vg0/mysql-snap /mnt/mysql-snap tar -czf /backup/mysql_$(date +%F).tar.gz -C /mnt/mysql-snap . umount /mnt/mysql-snap lvremove /dev/vg0/mysql-snap
注意点:
-
-L 5G不是快照大小上限,而是COW空间容量;如果备份期间原LV写入量超5G,快照会自动失效(Invalid argument错误) - 不要在快照挂载状态下启动
mysqld,会破坏一致性 -
tar必须加-C切换根路径,否则打包的是绝对路径,还原时容易覆盖原系统
还原时最容易被忽略的权限与配置问题
从tar包解压出来的数据目录,UID/GID、SELinux上下文、AppArmor标签全丢了。直接chown -R mysql:mysql不够,mysqld可能因Can't open the mysql.plugin table拒绝启动。
还原步骤必须包含:
- 停掉
mysqld:systemctl stop mysqld - 清空原数据目录(或改名备份):
mv /var/lib/mysql /var/lib/mysql.bak - 解压到目标路径:
tar -xzf /backup/mysql_2024-06-15.tar.gz -C /var/lib/ - 重置属主:
chown -R mysql:mysql /var/lib/mysql - 恢复SELinux上下文:
restorecon -Rv /var/lib/mysql(CentOS/RHEL) - 检查
my.cnf中datadir是否指向/var/lib/mysql,且innodb_log_file_size等参数与备份时一致
若备份时MySQL版本是5.7,还原到8.0会因mysql.user表结构不兼容直接失败,版本必须严格匹配。
比LVM快照更稳的替代方案其实就两步
真正在生产环境高频使用的,并不是LVM快照,而是Percona XtraBackup——它内部也用LVM快照做底层支撑,但自动处理了锁表、日志拷贝、一致性校验等所有关键环节。
一个典型备份命令:
xtrabackup --backup --target-dir=/backup/xtra_$(date +%F) --user=backup_user --password=xxx
它比手撸LVM快照多做了这些事:
- 自动调用
FLUSH NO_WRITE_TO_BINLOG TABLES减少锁表时间 - 并发拷贝
.ibd同时读取ib_logfile0,保证redo log与数据页版本对齐 - 备份完成后自动生成
xtrabackup_binlog_info,精确记录binlog位点 - 支持
--apply-log预恢复,跳过手动innodb_force_recovery的试错过程
LVM快照本身没问题,但把它当成MySQL备份方案,等于把引擎盖掀开自己调喷油嘴——能调,但没几个人敢在高速上这么干。











