备份和恢复本质是两个方向相反但强耦合的操作
备份是把当前数据“存下来”,恢复是把存下来的数据“放回去”——听起来简单,但实际中,一次失败的恢复会让备份完全失效。很多团队花大力气做每日全量备份,却从不验证能否真正还原,直到某天
drop database执行后才意识到:备份文件能
ls出来,不代表能
mysql导入成功。
逻辑备份(mysqldump)与物理备份(xtrabackup)的根本差异
区别不在“快不快”,而在“能不能跨版本、跨平台、保事务一致性”:
mysqldump输出的是 SQL 文本,可被
vim编辑、
grep过滤、在 MySQL 5.7 和 8.0 甚至 MariaDB 上执行(需注意语法兼容性),但导入时要重放所有
INSERT,大表可能卡住数小时;
xtrabackup复制的是 InnoDB 的页文件,恢复就是把文件拷回
datadir并启动服务,秒级完成,但必须保证源库和目标库的 MySQL 版本、架构(x86/ARM)、InnoDB page size 完全一致,否则直接启动失败; 一致性保障方式不同:
mysqldump --single-transaction依赖 MVCC 快照,而
xtrabackup依赖
ib_logfile回滚未提交事务,两者都要求引擎为 InnoDB;MyISAM 表在热备下极易不一致,应避免使用。
增量备份不是“只备份变化”,而是依赖 binlog 或 xtrabackup 的 checkpoint
MySQL 原生不支持传统意义上的增量物理备份。所谓“增量”,其实是两种路径:
用xtrabackup --incremental-basedir做基于上一次全量或增量备份的差异页拷贝,恢复时必须按顺序
--apply-log全量 + 所有增量,漏一个就无法前滚; 靠
binlog实现准实时增量:全量备份后开启
log_bin,定期滚动并归档
mysql-bin.0000xx文件;恢复时先还原全量,再用
mysqlbinlog --stop-datetime回放到故障前一秒——但前提是
binlog_format=ROW且没被 purged。 常见坑:
mysqldump默认不导出
binlog位置,若没加
--master-data=2,就无法精准定位起点;而
xtrabackup备份完成时生成的
xtrabackup_binlog_info文件若被误删,增量链就断了。
恢复失败最常卡在权限、路径和时序这三点
别急着
mysql -u root -p —— 先确认三件事:目标实例的
sql_mode是否和备份时一致?比如备份含
STRICT_TRANS_TABLES,而恢复库关了严格模式,可能跳过报错但写入脏数据;
backup.sql里是否有
CREATE DATABASE语句?用了
mysqldump -B就有,直接
mysql导入即可;若没加
-B,得先手动
CREATE DATABASE再导入,否则报错
Unknown database; 物理恢复后,必须确保
chown -R mysql:mysql /var/lib/mysql,且
innodb_data_home_dir和
datadir配置指向正确路径,否则 MySQL 启动日志里只显示
InnoDB: Database page corruption,不告诉你哪一页坏了。
真正难的从来不是备份,而是让恢复过程可预测、可验证、可重复。每次备份后,至少应在测试环境跑一次
innobackupex --apply-log && --copy-back或
mysql ,并校验几条关键记录的 <code>CHECKSUM TABLE值是否一致。
