运行中文件为什么不能直接拷
数据库数据文件、虚拟机磁盘、正在追加写的日志,在备份期间都可能被应用改写。直接 cp 或 tar 这类文件,得到的副本里既有旧页也有新页,写入还可能在偏移量上重叠,恢复时表现为页损坏、索引不一致或实例起不来。热备份的正确路径是让应用或存储先提供一个时间点一致的视图。
基本信息
| 风险对象 | 数据库数据文件与 redo、虚拟机磁盘、正在写入的日志与队列文件 |
|---|---|
| 应对手段 | 存储或文件系统快照、应用静默与锁、逻辑导出、轮转后备份 |
| 典型工具 | LVM/Btrfs 快照、VSS、mysqldump、XtraBackup、pg_basebackup |
| 判断标准 | 副本能否在不做长时间恢复的前提下直接使用 |
典型使用场景
- MySQL/PostgreSQL 在线备份:用数据库自带的备份接口而不是拷贝数据目录
- 日志类文件备份:等完成一次轮转后再备份切分好的历史文件
- 虚拟机备份:先创建快照,再从快照导出磁盘
- 队列与消息目录:停机或让消费者暂停后再取副本
- 文件服务器热文件:用户持续写入的文档由快照解决时间点问题
反例与正例
反例与正例
# 反例:直接拷贝运行中的数据库目录,可能得到无法启动的副本
# cp -a /var/lib/mysql /backup/mysql/
# 正例一:逻辑一致性导出后再落盘
mysqldump --single-transaction --all-databases | gzip > /backup/all-$(date +%F).sql.gz
# 正例二:物理友好工具做在线备份
xtrabackup --backup --target-dir=/backup/xtra/full
# 正例三:打快照后从快照读数据(只读挂载,避免污染)
lvcreate -L 20G -s -n db_snap /dev/vg_data/mysql && mount -o ro /dev/vg_data/db_snap /mnt/snap常见热文件与应对
| 对象 | 直接拷贝的问题 | 正确做法 |
|---|---|---|
| 数据库数据目录 | 页半写、事务截断,实例无法启动 | 用备份工具或先加锁/检查点再打快照 |
| 正在写入的日志 | 尾部行不完整、读取到半行 | 等轮转切分后再备份历史文件 |
| 虚拟机磁盘 | 来宾文件系统不一致,恢复后需 fsck | 快照或让虚拟机进入静默状态再导出 |
| 稀疏大文件 | cp 不做稀疏处理,体积暴涨且仍不一致 | 用支持稀疏与快照的工具或先静默 |
虚拟机场景可用快照后导出;日志类文件按轮转机制在切分完成后备份,能天然规避尾部不完整的问题。
『拷贝过程没报错、校验和也对得上』不代表逻辑一致:文件级校验和只能证明字节没变,证明不了副本内部事务自洽,需要应用层校验(如导出重放、实例启动检查)才能确认。