备份无小事:MySQL 数据备份与恢复的几种正确姿势

0 阅读9分钟

数据一夜蒸发,百万订单化为乌有?别等出事故才后悔!MySQL备份的这几种正确姿势,你知道多少?逻辑备份、物理备份、全量增量策略一网打尽。误删表、硬盘损坏、数据库崩溃,关键时刻这份指南能救命。

MySQL 数据库在数据驱动的业务环境里,尤其是在一众互联网为代表的企业里的重要性无需多言,但实际上数据库也是非常脆弱的,可能一次误操作、一次停电、一场服务器故障,都可能让辛苦积累的数据付之东流,所以备份真的是无小事。今天就来聊聊 MySQL 常用的几种备份与恢复方案,对比 mysqldump、物理备份、主从同步等的适用场景,帮你找到最适合自己的那套方案。 image

一、mysqldump

mysqldump 是 MySQL 自带的逻辑备份工具,核心原理是把数据库的结构和数据转换成 SQL 语句保存到文本文件里,恢复时在执行这些 SQL 就能重建数据。

如下是常见的数据备份脚本示例:

# 备份单个数据库
mysqldump -u root -p database_name > backup.sql

# 备份多个数据库
mysqldump -u root -p --databases db1 db2 > backup.sql

# 备份所有数据库
mysqldump -u root -p --all-databases > full_backup.sql

# 仅备份表结构(不含数据)
mysqldump -u root -p --no-data database_name > structure.sql

# 仅备份数据(不含结构)
mysqldump -u root -p --no-create-info database_name > data.sql

# 压缩备份
mysqldump -u root -p database_name | gzip > backup.sql.gz

# 下面是恢复方式

# 恢复数据库
mysql -u root -p database_name < backup.sql

# 恢复压缩备份
gunzip < backup.sql.gz | mysql -u root -p database_name

主要是特点有:

  • ✅ 生成 SQL 文本文件,可读性强
  • ✅ 跨版本、跨平台兼容性好
  • ✅ 可以选择性备份表或数据
  • ❌ 大数据量时速度慢
  • ❌ 备份和恢复时间较长

它的优势很明显,跨平台跨版本兼容性拉满,毕竟SQL语法基本行不会有什么很大变化,比如从 MySQL5.7 备份的文件,能直接恢复到 8.0 版本里,甚至从 Linux 服务器备份的内容,拿到 Windows 上也能正常用。而且只要用对参数,比如给 InnoDB 引擎加上--single-transaction,就能实现热备份,不用停服务,完全不影响业务读写。备份出来的 SQL 文件是纯文本,还能直接编辑,比如你只想恢复某几张表,或者要过滤掉部分测试数据,直接改文件就行。而且在MySQL 5.7.6+ 以上版本还支持并行备份。mysqldump算得上是中小规模场景的灵活之选了。

但是mysqldump 的缺点也很明显,备份和恢复速度都比较慢,每次都要把数据转换成 SQL 再执行,数据量越大越明显感受到它的速度慢,所以一般建议数据量小于 10GB 的场景使用。而且备份文件的体积会比原数据大很多,毕竟要含有大量的 SQL 语法冗余部分。

所以它适用的场景是:中小型数据库。比如开发测试环境的数据同步,或者需要跨平台、跨版本迁移数据的情况,又或者你需要灵活筛选备份内容,比如只备份某几个表、某条业务线的数据,用 mysqldump 就比较合适。另外,备份的时候记得加上--single-transaction,避免锁表影响业务。之前有一次手滑忘了加这个,导致测试环境的写入请求卡了半小时,现在还忘不了同事想刀人的眼神。

二、物理备份

物理备份和逻辑备份完全不同,可以理解为直接复制 MySQL 的数据文件,比如 InnoDB 的.ibd文件、MyISAM 的.MYD.MYI文件,还有日志文件这些。

这种备份方式的最大优势就是速度快,备份和恢复的速度大概是逻辑备份的 5 到 10 倍,10GB 的数据可能 几分钟就能搞定(具体还是看磁盘读写速度),要是到了 TB 级别的数据,物理备份的速度优势就更明显了。这种备份文件的大小和原数据差不多,不会有 SQL 语法的冗余,占用的存储空间更小,数据一致性也更高,因为复制的是数据的物理快照,恢复完和备份时的状态完全一致。这种方式可以算是最简单的大数据库快速备份了。

这种方式的缺点也非常明显。物理备份的限制多,首先是不可移植,备份文件只能在和原服务器 MySQL 版本、存储引擎完全一致的环境里恢复,比如你用 8.0 版本的 InnoDB 备份的文件,拿到 5.7 版本的服务器上就用不了。如果是冷备份的话,还要停掉 MySQL 服务或者把数据库设为只读模式,不然复制的文件可能会损坏。

所以物理备份更适合数据量大于 10GB 的生产环境,比如核心业务的全量备份,对备份和恢复速度要求很高的场景,而且服务器的 MySQL 版本、存储引擎都固定不变的话,选物理备份准没错。

不过,别用简单的cp命令做热备份,很容易出数据一致性问题,建议用 Percona XtraBackup 这种专业工具,它能在不影响业务的前提下,保证备份的一致性。不过用 Percona XtraBackup 这种热备份工具,虽然不用停服务,但学习成本和配置复杂度也会高一些。

下面是XtraBackup示例:

# 全量备份
xtrabackup --backup --target-dir=/backup/full

# 准备备份(应用日志)
xtrabackup --prepare --target-dir=/backup/full

# 恢复备份
# 1. 停止 MySQL
# 2. 清空数据目录
# 3. 复制备份
xtrabackup --copy-back --target-dir=/backup/full
chown -R mysql:mysql /var/lib/mysql

主要特点有:

  • ✅ 热备份,不锁表(对 InnoDB)
  • ✅ 支持增量备份
  • ✅ 备份和恢复速度快
  • ❌ 需要额外安装工具

三、主从同步

主从同步本质上是基于 MySQL 的binlog复制功能,把主库的实时数据同步到从库,备份操作都在从库上执行,完全不会影响主库的业务。

这种方案的优势首先是几乎不影响业务,不管你在从库上做逻辑备份还是物理备份,主库该怎么读写就怎么读写,对生产业务没有影响。其次,从库还能兼做灾备节点,要是主库出故障了,能快速切换到从库上,提升整个系统的高可用性。而且你还能根据需求选择备份类型,比如从库数据量小就用 mysqldump,数据量大就用物理备份,灵活性很高。

但是吧,主从同步的成本不低,你需要额外准备一台甚至多台服务器来做从库,硬件配置还要和主库差不多,不然同步速度跟不上。另外,异步复制模式下,从库的数据可能会比主库有延迟,要是主库刚写入数据就出故障,从库可能还没同步到这部分数据,所以需要监控Seconds_Behind_Master这个指标,确保延迟在可接受的范围内。

主从同步最适合生产环境的核心库,比如电商的订单库、用户中心库,这些业务对可用性要求极高,绝对不能因为备份操作影响业务,同时又需要可靠的数据备份和灾备能力,这时候主从同步就是最优解。另外,主从同步的配置要注意细节,比如 server-id 不能重复,binlog 格式建议用 ROW 模式,避免一些复制异常。 生成 MySQL 主从同步架构图.png

四、增量备份

上面说的主要是全量备份的方案(当然XtraBackup也可以增量备份),虽然全量备份数据完整,但是备份速度较慢、备份时间长,由于数据量较大,恢复时间也长,而增量备份一般是作为全量备份的补充,它依赖 MySQL 的二进制日志(binlog),只备份全量备份之后发生变化的数据。 以xtrabackup增量备份为例:

# 增量备份
xtrabackup --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/full

增量备份的优势是备份速度极快,体积也小,比如每天的增量备份可能只有几十 MB,对服务器性能的影响也很小。而且它能实现点时间恢复,比如你误删了数据,能恢复到误删之前的任意时间点,这对金融交易这种对 RPO(恢复点目标)要求极高的场景来说,是必不可少的。

不过增量备份不能单独使用,必须先恢复全量备份,再依次应用增量的 binlog 日志,恢复流程比较复杂,要是中间某个 binlog 文件丢失或者损坏,整个恢复过程就会失败。所以平时要做好 binlog 的归档和备份,确保日志文件不会丢失。

增量备份适合那些需要高 RPO 的场景,比如金融交易库、支付系统,这些场景要求故障后能恢复到故障前几秒的数据,这时候全量备份加增量备份的组合,就能满足需求。

其实备份方案没有绝对的好坏,只有适不适合:数据量小、需要灵活操作选 mysqldump;数据量大、追求速度选物理备份;核心生产库、零业务影响要求选主从同步;对恢复点要求极高的场景,通常加上增量备份。另外,不管用哪种方案,都要定期测试恢复流程,我见过很多人备份了一堆文件,真到需要恢复的时候才发现备份文件损坏了,那可就麻烦大了。

其实最好就是做组合备份策略。利用这些方案的特点和优势,例如:

1. 每周六凌晨:XtraBackup 全量物理备份
2. 每天凌晨:XtraBackup 增量备份
3. 实时:同步复制到从库
4. 持续:备份二进制日志(binlog)
5. 每周:mysqldump 逻辑备份(用于跨版本恢复)

还有个特别提醒,备份文件一定要异地存储,别和服务器放在同一个机房,不然机房出故障,备份文件也跟着没了,那可就真的叫天天不应了。像我们之前公司有一次机房真的着火了,幸好做了两地三中心的设计,否则不只是业务中断、有可能数据都全完了。

不知道你们是怎么做备份和恢复方案的呢?欢迎在评论区留言说说你们的方案