LVM快照实现MySQL秒级物理备份需先执行FLUSH TABLES WITH READ LOCK、FLUSH LOGS、FLUSH ENGINE LOGS并记录binlog位置,再创建快照;xfs快照挂载前须运行xfs_repair -o force_geometry,ext4可直接只读挂载;恢复时必须删除ib_logfile*并核对innodb_log_file_size。

FLUSH TABLES WITH READ LOCK 不是零延迟,但可以做到秒级锁定;真正“零延迟”物理备份在 MySQL + LVM 场景下并不存在——它依赖一次极短的全局读锁,目的是冻结逻辑一致性点。只要步骤严谨、顺序不乱,实际业务中断可控制在 2–5 秒内。
为什么必须执行 FLUSH TABLES WITH READ LOCK 和 FLUSH ENGINE LOGS
InnoDB 的数据页和 redo 日志是异步刷盘的。如果跳过锁表和日志刷新,快照里可能包含:已写入数据文件但未刷 redo 的脏页,或已刷 redo 但未更新数据页的“半提交”事务。恢复时必然报 InnoDB: Database page corruption 或启动失败。
-
FLUSH TABLES WITH READ LOCK:强制所有存储引擎(包括 MyISAM)落盘,并阻断新写入,为一致性打基础 -
FLUSH LOGS:滚动 binlog,确保后续 binlog 位置准确 -
FLUSH ENGINE LOGS:InnoDB 专用,强制将内存中所有 redo 日志刷到ib_logfile*磁盘文件 - 三者必须在
lvcreate前完成,且UNLOCK TABLES必须在快照创建后立即执行
lvcreate -s 执行时机与常见挂载失败原因
快照命令本身毫秒级完成,但错误常发生在后续挂载环节。核心问题不是快照没建好,而是文件系统元数据状态不匹配。
- xfs 快照卷挂载前必须跑
xfs_repair -o force_geometry /dev/vg0/mysql_snap,否则mount直接报错或挂载后看不到文件 - ext4 一般可直接
mount -o ro,nouuid /dev/vg0/mysql_snap /mnt/snap,但若提示wrong fs type,先检查lvs -o +attr,origin—— Attr 列第 5 位必须是s(snapshot),不是S(suspended) - 若为
S,用lvchange -ay /dev/vg0/mysql_snap激活;挂载时务必加nouuid,避免与原卷 UUID 冲突导致 mount 失败
备份时拷贝慢?别怪快照,要优化 rsync/tar 策略
LVM 快照本身只有几 MB(COW 元数据),你看到的“备份慢”,其实是把整个 /mnt/snap 下数 GB 数据复制出去的过程。这不是快照的问题,而是 I/O 路径选择问题。
- 不要用
cp -r,优先用rsync -a --numeric-ids --delete-after,跳过 socket、pipe 等特殊文件 - 若目标是异地备份,建议挂载后立刻
tar -cf - -C /mnt/snap . | gzip -c > backup.tar.gz,避免中间落盘 - 快照存活时间不宜超过 24 小时:原卷每写一次块,快照就多存一份旧数据,空间增长不可逆;写入越频繁,快照膨胀越快
恢复时最易忽略的两个 InnoDB 强制动作
从快照恢复不是简单拷回文件就能启动 mysqld。InnoDB 启动校验非常严格,漏掉任何一步都会卡在 recovery 阶段或直接拒绝启动。
- 恢复前必须删除原数据目录下的
ib_logfile*(ib_logfile0,ib_logfile1),否则 InnoDB 认为日志文件大小与innodb_log_file_size不匹配 - 必须核对
my.cnf中的innodb_log_file_size是否与备份时一致;若不一致,启动会报InnoDB: Error: log file ./ib_logfile0 is of different size - 恢复后首次启动建议加
--innodb-force-recovery=1测试能否读出数据,确认无页损坏再切生产
真正危险的不是操作步骤多,而是把 FLUSH ENGINE LOGS 当成可选,或以为 xfs 快照能像 ext4 一样直挂——这两点踩中任意一个,备份就等于没做。


















