一、为什么需要备份?
数据库备份是数据安全的最后防线,任何意外都可能导致数据丢失。
1.1 数据丢失风险
1 2 3 4 5 6 7 8 9 10 11 12
| ┌─────────────────────────────────────────────────────────────────┐ │ 数据丢失原因 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 💻 硬件故障 → 硬盘损坏、服务器宕机 │ │ 🦠 人为失误 → 误删数据、误操作 │ │ 🐛 软件错误 → 程序BUG导致数据损坏 │ │ 🦹 恶意攻击 → 黑客攻击、勒索病毒 │ │ 🌋 自然灾害 → 机房故障、火宅等 │ │ 🔄 升级失败 → 数据库升级失败 │ │ │ └─────────────────────────────────────────────────────────────────┘
|
1.2 备份策略
| 策略 |
说明 |
频率 |
适用场景 |
| 全量备份 |
备份所有数据 |
每天 |
小型数据库 |
| 增量备份 |
备份新增数据 |
每小时 |
大型数据库 |
| 差异备份 |
备份与全量的差异 |
每天 |
中型数据库 |
二、备份工具介绍
2.1 常用工具
| 工具 |
类型 |
特点 |
| mysqldump |
逻辑备份 |
跨版本、通用性强 |
| mysqlpump |
逻辑备份 |
并行备份、速度更快 |
| mydumper |
逻辑备份 |
多线程、热备份 |
| xtrabackup |
物理备份 |
热备份、增量支持 |
| mysqlbackup |
物理备份 |
Oracle官方工具 |
2.2 工具对比
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ┌─────────────────────────────────────────────────────────────────┐ │ 备份工具对比 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ mysqldump │ │ ✅ 优点:简单、跨版本、备份文件小 │ │ ❌ 缺点:慢、大数据量不适合 │ │ │ │ mydumper │ │ ✅ 优点:多线程、热备、可并行 │ │ ❌ 缺点:需要安装 │ │ │ │ xtrabackup │ │ ✅ 优点:热备、增量快、在线备份 │ │ ❌ 缺点:只支持InnoDB/XtraDB │ │ │ └─────────────────────────────────────────────────────────────────┘
|
三、mysqldump备份
3.1 基本使用
1 2 3 4 5 6 7 8 9 10 11
| mysqldump -uroot -p mydb > mydb.sql
mysqldump -uroot -p --databases db1 db2 > dbs.sql
mysqldump -uroot -p --all-databases > all.sql
mysqldump -uroot -p mydb users orders > tables.sql
|
3.2 常用参数
1 2 3 4 5 6 7 8 9 10 11 12 13
| -uroot -p --single-transaction --lock-tables --routines --triggers --events --master-data --flush-logs --quick --set-charset --default-character-set=utf8mb4
|
3.3 示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| mysqldump -uroot -p \ --single-transaction \ --routines \ --triggers \ --events \ --master-data=2 \ --flush-logs \ mydb > mydb_$(date +%Y%m%d).sql
mysqldump -uroot -p mydb | gzip > mydb_$(date +%Y%m%d).sql.gz
mysqldump -uroot -p \ --single-transaction \ --master-data=2 \ --flush-logs \ mydb > mydb_backup.sql
mysqldump -uroot -p --no-data mydb > mydb_schema.sql
mysqldump -uroot -p --no-tablespaces mydb > mydb_data.sql
|
四、mysqlpump备份
4.1 基本使用
1 2 3 4 5 6 7 8 9 10
|
mysqlpump -uroot -p mydb > mydb.sql
mysqlpump -uroot -p \ --default-parallelism=4 \ --databases mydb > mydb.sql
|
4.2 特点
1 2 3 4 5 6 7 8 9 10 11
|
mysqlpump -uroot -p \ --exclude-databases=information_schema \ --exclude-tables=test% \ --databases mydb > mydb.sql
|
五、物理备份(xtrabackup)
5.1 安装
1 2 3 4 5 6 7 8
| sudo apt install xtrabackup
sudo yum install percona-xtrabackup
xtrabackup --version
|
5.2 全量备份
1 2 3 4 5 6 7 8 9 10 11 12
| sudo mkdir -p /backup/full sudo chown -R mysql:mysql /backup
xtrabackup --backup \ --target-dir=/backup/full \ --user=root \ --password=your_password
ls -la /backup/full
|
5.3 增量备份
1 2 3 4 5 6 7 8 9 10 11 12 13
| xtrabackup --backup \ --target-dir=/backup/inc1 \ --incremental-basedir=/backup/full \ --user=root \ --password=your_password
xtrabackup --backup \ --target-dir=/backup/inc2 \ --incremental-basedir=/backup/inc1 \ --user=root \ --password=your_password
|
5.4 备份恢复
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| xtrabackup --prepare --target-dir=/backup/full
xtrabackup --prepare --target-dir=/backup/full \ --incremental-dir=/backup/inc1
sudo systemctl stop mysql
sudo rm -rf /var/lib/mysql/*
xtrabackup --copy-back --target-dir=/backup/full \ --user=root \ --password=your_password
sudo chown -R mysql:mysql /var/lib/mysql
sudo systemctl start mysql
|
六、逻辑备份(mydumper)
6.1 安装
1 2 3 4 5 6 7 8
| sudo apt install mydumper
sudo yum install mydumper
mydumper --version
|
6.2 备份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| mydumper -u root -p password \ -o /backup/mydumper \ -B mydb
mydumper -u root -p password \ -o /backup/mydumper \ -A
mydumper -u root -p password \ -o /backup/mydumper \ -B mydb \ -t 4
|
6.3 恢复
1 2 3 4 5 6 7 8 9
| myloader -u root -p password \ -# 恢复数据库d /backup/mydumper \ -B mydb
myloader -u root -p password \ -d /backup/mydumper \ -A
|
七、数据恢复
7.1 恢复SQL文件
1 2 3 4 5 6 7 8
| mysql -uroot -p mydb < mydb.sql
gunzip < mydb.sql.gz | mysql -uroot -p mydb
mysql -uroot -p < all.sql
|
7.2 恢复指定表
1 2 3 4 5 6 7 8
| sed -n '/CREATE TABLE.*users/,/UNLOCK TABLES/p' mydb.sql > users_table.sql
grep -A 50 'CREATE TABLE.*users' mydb.sql > users_table.sql
mysql -uroot -p mydb < users_table.sql
|
7.3 基于时间点恢复
1 2 3 4 5 6 7 8
| mysqlbinlog mysql-bin.000001 > binlog.sql
mysqlbinlog
mysqlbinlog
|
7.4 恢复误删数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
mysql -uroot -p mydb < mydb_backup.sql
mysqlbinlog mysql-bin.000001 | mysql -uroot -p
# 安装 pip install binlog2sql
# 分析binlog,生成反向SQL python binlog2sql.py -h127.0.0.1 -P3306 -uroot -p'password' -d mydb -t users \ > flashback.sql
# 恢复 mysql -uroot -p mydb < flashback.sql
|
八、定时自动备份
8.1 备份脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #!/bin/bash
DB_NAME="mydb" DB_USER="root" DB_PASS="password" BACKUP_DIR="/backup" DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
echo "Starting backup at $(date)" mysqldump -u$DB_USER -p$DB_PASS \ --single-transaction \ --routines \ --triggers \ --events \ --master-data=2 \ --flush-logs \ $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
echo "Backup completed at $(date)"
|
8.2 添加定时任务
1 2 3 4 5 6 7 8
| crontab -e
0 2 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1
sudo systemctl restart cron
|
8.3 定时任务示例
1 2 3 4 5 6 7 8
| 0 2 * * * /path/to/backup.sh
0 3 * * 0 /path/to/backup.sh
0 * * * * /path/to/inc_backup.sh
|
九、备份验证
9.1 验证备份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ls -lh /backup/
gzip -t mydb_20260214.sql.gz
head -20 mydb_20260214.sql tail -20 mydb_20260214.sql
mysql -uroot -p testdb < mydb_20260214.sql
mysql -uroot -p -e "USE testdb; SELECT COUNT(*) FROM users;"
|
9.2 恢复演练
十、云备份方案
10.1 阿里云RDS
1 2 3 4 5 6 7 8
| -- 登录阿里云RDS控制台 -- 配置自动备份策略 -- 设置备份保留时间
-- 手动创建备份 -- 下载备份文件
|
10.2 AWS RDS
1 2 3 4 5 6 7 8 9
| -- 默认开启自动备份 -- 可配置保留天数(1-35天) -- 创建手动快照
-- 进入RDS控制台 -- 选择快照 -- 恢复实例
|
10.3 自建+对象存储
1 2 3 4 5 6 7
|
ossutil cp mydb_$(date +%Y%m%d).sql.gz oss://mybucket/backup/
|
十一、常见问题
11.1 备份文件太大
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
mysqldump ... | gzip > backup.sql.gz
mysqldump -uroot -p mydb
for table in $(mysql -uroot -p mydb -N -e "SHOW TABLES"); do mysqldump -uroot -p mydb $table | gzip > ${table}.sql.gz done
xtrabackup ...
|
11.2 备份超时
1 2 3 4 5 6 7 8 9
|
mysqldump
xtrabackup ...
|
11.3 恢复失败
1 2 3 4 5 6 7 8 9 10 11 12
|
mysql
mysql -uroot -p
mysqldump ...
|
十二、备份策略建议
12.1 中小网站
| 备份类型 |
频率 |
保留时间 |
| 全量备份 |
每天 |
7天 |
| Binlog |
实时 |
3天 |
12.2 中大型网站
| 备份类型 |
频率 |
保留时间 |
| 全量备份 |
每天 |
30天 |
| 增量备份 |
每小时 |
7天 |
| Binlog |
实时 |
3天 |
12.3 核心业务
| 备份类型 |
频率 |
保留时间 |
| 全量备份 |
每天 |
90天 |
| 增量备份 |
每小时 |
7天 |
| Binlog |
实时 |
7天 |
| 异地备份 |
每天 |
30天 |
十三、监控与告警
13.1 备份监控
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [ -f /backup/mydb_$(date +%Y%m%d).sql.gz ] || echo "Backup failed!"
SIZE=$(stat -c%s /backup/mydb_$(date +%Y%m%d).sql.gz) if [ $SIZE -lt 1000 ]; then echo "Backup file too small!" fi
LAST_BACKUP=$(stat -c %Y /backup/mydb_latest.sql.gz) NOW=$(date +%s) DIFF=$((NOW - LAST_BACKUP)) if [ $DIFF -gt 86400 ]; then echo "Backup too old!" fi
|
13.2 告警配置
1 2 3 4 5 6 7
|
if [ $? -ne 0 ]; then curl -X POST "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=XXX" \ -H 'Content-Type: application/json' \ -d '{"msgtype": "text", "text": {"content": "Backup failed!"}}' fi
|
参考资料
持续更新中…欢迎收藏!
#MySQL #备份 #恢复 #数据安全 #运维 #教程