备份与恢复是方向相反但强耦合的操作:备份存数据,恢复放回数据;逻辑备份(mysqldump)跨版本兼容但导入慢,物理备份(xtrabackup)秒级恢复但要求环境严格一致;增量依赖binlog或xtrabackup差异页,恢复失败多因权限、路径及时序错误。
备份是把当前数据“存下来”,恢复是把存下来的数据“放回去”——听起来简单,但实际中,一次失败的恢复会让备份完全失效。很多团队花大力气做每日全量备份,却从不验证能否真正还原,直到某天 drop database 执行后才意识到:备份文件能 ls 出来,不代表能 mysql 导入成功。
区别不在“快不快”,而在“能不能跨版本、跨平台、保事务一致性”:
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 表在热备下极易不一致,应避免使用。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 ,并校验几条关键记录的 CHECKSUM TABLE 值是否一致。