1. 项目背景与核心需求
数据库备份是每个运维工程师和开发者的必修课。记得2013年某次服务器宕机事故,由于缺乏有效的备份机制,导致公司损失了整整三天的订单数据。自那以后,我养成了给所有MySQL数据库上"双保险"的习惯——本地备份+异地容灾。
这个脚本的诞生源于一个经典场景:当你完成本地备份后,服务器机房突发火灾/水灾/断电,所有本地存储设备同时损毁。这时候,异地的备份文件就是救命稻草。我见过太多团队只做本地备份,最终在灾难发生时追悔莫及。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术方案选型
2.1 备份工具对比
bash复制# 常用备份方式对比表
| 工具 | 备份速度 | 恢复便利性 | 存储占用 | 适用场景 |
|---------------|----------|------------|----------|--------------------|
| mysqldump | 慢 | 简单 | 大 | 小型数据库全量备份 |
| xtrabackup | 快 | 复杂 | 小 | 大型数据库热备份 |
| mysqlpump | 中等 | 简单 | 中等 | 8.0+版本并行备份 |
最终选择mysqldump方案,原因有三:
- 兼容所有MySQL版本(包括老旧的5.6环境)
- 生成的SQL文件可直接阅读验证
- 恢复时无需额外工具
提示:如果数据库超过50GB,建议改用xtrabackup,本文方案可能耗时过长
2.2 传输协议选择
bash复制# 传输方式对比
| 协议 | 端口 | 安全性 | 速度 | 需开放权限 |
|---------|-------|--------|--------|------------------|
| SCP | 22 | 高 | 慢 | 服务器SSH登录权 |
| RSYNC | 873 | 中 | 快 | 守护进程配置权限 |
| FTP | 21 | 低 | 中等 | FTP账户权限 |
选择SCP的原因:
- 所有Linux服务器默认安装openssh-client
- 不需要在备份服务器额外配置服务
- 传输过程加密更安全
3. 脚本实现详解
3.1 基础备份脚本
bash复制#!/bin/bash
# 定义变量
DB_USER="backup_user"
DB_PASS="ComplexP@ssw0rd!2023"
BACKUP_DIR="/var/mysql_backups"
DATE=$(date +%Y%m%d_%H%M%S)
# 创建备份目录
mkdir -p $BACKUP_DIR/$DATE
# 获取数据库列表
DATABASES=$(mysql -u$DB_USER -p$DB_PASS -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|sys)")
# 循环备份每个数据库
for DB in $DATABASES; do
mysqldump -u$DB_USER -p$DB_PASS --single-transaction --routines --triggers $DB > $BACKUP_DIR/$DATE/$DB.sql
# 压缩备份文件
gzip $BACKUP_DIR/$DATE/$DB.sql
done
关键参数说明:
--single-transaction:保证备份时数据一致性--routines:包含存储过程--triggers:包含触发器
3.2 远程传输模块
bash复制# 添加远程服务器配置
REMOTE_USER="backup"
REMOTE_HOST="192.168.1.100"
REMOTE_PORT="2222"
REMOTE_DIR="/mnt/backup_storage"
# 使用rsync增量传输
rsync -avz -e "ssh -p $REMOTE_PORT" --delete $BACKUP_DIR/ $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR
# 带校验的SCP传输方案(备选)
scp -P $REMOTE_PORT -r $BACKUP_DIR/$DATE $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR
传输优化技巧:
- 使用
-z参数启用压缩传输 --delete删除远程已不存在的文件- 指定非标准SSH端口增强安全性
3.3 完整脚本整合
bash复制#!/bin/bash
# 定义日志函数
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> /var/log/mysql_backup.log
}
# 初始化变量
source /etc/mysql_backup.conf
# 检查备份目录
if [ ! -d "$BACKUP_DIR" ]; then
mkdir -p $BACKUP_DIR
chmod 700 $BACKUP_DIR
fi
# 执行备份
log "开始MySQL备份流程"
... [整合前文的备份代码]
# 传输备份
log "开始远程传输"
if rsync -avz -e "ssh -p $REMOTE_PORT -i /root/.ssh/backup_key" --delete $BACKUP_DIR/ $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR; then
log "远程传输成功"
else
log "远程传输失败,尝试SCP方案"
... [SCP备用方案]
fi
# 清理旧备份
find $BACKUP_DIR -type d -mtime +7 -exec rm -rf {} \;
4. 生产环境部署要点
4.1 安全配置
- 创建专用备份账户:
sql复制CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'ComplexP@ssw0rd!2023';
GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, PROCESS ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;
- SSH密钥配置:
bash复制ssh-keygen -t ed25519 -f /root/.ssh/backup_key
ssh-copy-id -i /root/.ssh/backup_key.pub -p 2222 backup@192.168.1.100
chmod 600 /root/.ssh/backup_key
4.2 定时任务设置
bash复制# 每天凌晨2点执行备份
0 2 * * * /usr/local/bin/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1
# 每周日全量备份+binlog备份
0 2 * * 0 /usr/local/bin/mysql_full_backup.sh
重要:不要直接编辑crontab,建议将脚本放在/etc/cron.daily/
5. 监控与报警机制
5.1 备份状态检查脚本
bash复制#!/bin/bash
# 检查最近备份是否成功
LAST_BACKUP=$(find $BACKUP_DIR -type d -mtime -1 | wc -l)
if [ $LAST_BACKUP -eq 0 ]; then
echo "紧急:MySQL备份失败!" | mail -s "备份告警" admin@example.com
/usr/local/bin/send_alert "DB_BACKUP_FAILED"
fi
5.2 Prometheus监控指标
yaml复制# metrics exporter配置示例
- name: mysql_backup_status
rules:
- record: mysql_backup_success
expr: time() - max(mtime{job="mysql_backup"}) < 86400
- record: mysql_backup_size
expr: sum(filesize{job="mysql_backup"})
6. 高级技巧与优化
6.1 增量备份方案
bash复制# 启用MySQL二进制日志
[mysqld]
log-bin=mysql-bin
expire_logs_days=7
# 增量备份脚本
mysqladmin flush-logs
rsync -av /var/lib/mysql/mysql-bin.* $REMOTE_DIR/binlog/
6.2 备份加密方案
bash复制# 使用GPG加密备份文件
gpg --batch --yes --passphrase "YourStrongPassphrase" -c $BACKUP_DIR/$DATE/$DB.sql.gz
6.3 多云存储支持
bash复制# 添加AWS S3上传
aws s3 sync $BACKUP_DIR/$DATE s3://your-bucket/mysql/$DATE --storage-class STANDARD_IA
7. 常见问题排查
7.1 错误代码速查表
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| Access denied for user | 密码错误/权限不足 | 检查my.cnf配置或GRANT权限 |
| SSH连接超时 | 防火墙阻挡/端口错误 | telnet测试端口连通性 |
| 备份文件损坏 | 磁盘空间不足 | df -h检查磁盘空间 |
| 传输中断 | 网络波动 | 使用rsync --partial断点续传 |
7.2 性能优化记录
- 备份加速技巧:
bash复制mysqldump --quick --skip-lock-tables # 牺牲部分一致性换取速度
- 网络传输优化:
bash复制rsync --bwlimit=10240 # 限制带宽为10MB/s避免拥塞
- 内存优化:
bash复制mysqldump --single-transaction --set-gtid-purged=OFF # 减少内存占用
8. 恢复演练流程
8.1 单库恢复示例
bash复制# 解压备份文件
gzip -d /backup/20230801_0200/mydb.sql.gz
# 恢复数据库
mysql -u root -p mydb < /backup/20230801_0200/mydb.sql
8.2 全量+增量恢复
bash复制# 先恢复全量备份
mysql -u root -p < full_backup.sql
# 应用增量日志
mysqlbinlog mysql-bin.000123 | mysql -u root -p
mysqlbinlog mysql-bin.000124 | mysql -u root -p
9. 灾备方案扩展
建议采用3-2-1备份原则:
- 3份备份副本
- 2种不同介质
- 1份异地存储
可以结合:
- 本地SSD存储(快速恢复)
- 远程NAS存储(常规备份)
- 云存储如S3/OSS(长期归档)
