前言
在 IT 圈流传着一句玩笑话:“从删库到跑路”。虽然是玩笑,但数据安全绝对是后端开发的生命线。
无论是人为误操作(DELETE 忘加 WHERE)、系统故障,还是黑客勒索,唯一能救你命的只有一样东西——备份。
很多开发者在开发环境习惯了手动导出 SQL,但在生产环境,我们需要一套全自动、可追溯、带清理策略的备份方案。今天我们就用 Linux Shell + mysqldump 来实现它。
1. 选择备份工具:mysqldump
MySQL 备份主要分为两种:
- 物理备份(XtraBackup): 直接复制磁盘文件,速度快,适合超大数据量(TB级)。
- 逻辑备份(mysqldump): 将数据导出为 SQL 语句,可读性好,跨版本兼容性强,适合中小规模数据(几十G以内)。
对于大多数中小型项目,mysqldump 是最通用、最简单的选择。
2. 编写自动备份脚本
我们将编写一个 Shell 脚本,完成以下“一条龙”服务:
- 导出数据库。
- 压缩文件(节省磁盘空间)。
- 按日期命名。
- 自动删除 30 天前的旧备份。
创建脚本文件:
Bash
vim /data/scripts/mysql_backup.sh
脚本内容(请根据你的实际情况修改配置项):
Bash
#!/bin/bash # ================= 配置区域 ================= # 数据库用户名 DB_USER="root" # 数据库密码 (建议使用 .my.cnf 配置文件以免密码泄露,此处仅为演示) DB_PASS="你的数据库密码" # 需要备份的数据库名 DB_NAME="my_app_db" # 备份文件存放路径 BACKUP_DIR="/data/backup/mysql" # 获取当前时间,用于文件名 DATE=$(date +%Y%m%d_%H%M%S) # =========================================== # 1. 检查备份目录是否存在 if [ ! -d "$BACKUP_DIR" ]; then mkdir -p "$BACKUP_DIR" fi echo "[Start] 开始备份数据库: $DB_NAME ..." # 2. 执行备份并压缩 # --single-transaction: 保证InnoDB备份时的数据一致性,不锁表 # --routines --events: 备份存储过程和事件 # | gzip: 管道传输,直接压缩,不占用临时磁盘空间 mysqldump -u$DB_USER -p$DB_PASS --single-transaction --routines --events "$DB_NAME" | gzip > "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" # 3. 检查备份结果 if [ $? -eq 0 ]; then echo "[Success] 备份文件已生成: $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" else echo "[Error] 备份失败!" exit 1 fi # 4. 清理旧备份 (保留最近30天) find "$BACKUP_DIR" -type f -name "*.sql.gz" -mtime +30 -exec rm -rf {} \; echo "[Cleanup] 已清理30天前的旧备份。"
3. 赋予权限并测试
千万别写完就丢那不管,一定要手动运行一次!
Bash
# 赋予执行权限 chmod +x /data/scripts/mysql_backup.sh # 手动执行脚本 ./mysql_backup.sh
如果看到 [Success] 并且在备份目录下生成了 .sql.gz 文件,说明脚本没问题。
4. 自动化:加入 Crontab
我们通常选择在业务低峰期(比如凌晨 3 点)进行备份。
Bash
crontab -e
添加如下一行:
Bash
# 每天凌晨 03:00 执行数据库备份 0 3 * * * /data/scripts/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1
5. 关键时刻:如何恢复?
备份的目的是为了恢复。如果不会恢复,备份就是一堆废文件。
假设数据库崩了,我们需要用备份文件 my_app_db_20231027.sql.gz 进行恢复:
Bash
# 1. 解压并导入 # gunzip -c : 解压输出到标准输出 # | mysql : 管道输入给 mysql 命令执行 gunzip -c /data/backup/mysql/my_app_db_20231027.sql.gz | mysql -u root -p my_app_db
或者分两步走:
Bash
# 1. 解压 gzip -d my_app_db_20231027.sql.gz # 2. 导入 mysql -u root -p my_app_db < my_app_db_20231027.sql
6. DBA的忠告
- 异地备份: 不要把鸡蛋放在同一个篮子里。脚本生成的备份文件,最好再同步一份到**对象存储(如阿里云OSS)**或者另一台服务器上。否则服务器硬盘坏了,备份和原数据一起没。
- 定期演练: 每个季度至少在测试环境试着恢复一次,确保你的备份文件是完好可用的。
总结
数据备份是运维工作的底线。通过这个简单的脚本,我们实现了:
- 全自动运行
- 压缩省空间
- 定期清理
睡个安稳觉,从做好备份开始。