Linux 下如何编写 Shell 脚本自动备份 MySQL 数据库?

文章导读
最稳妥的方式是使用 mysqldump 配合 cron 定时任务,适合大多数中小规模数据库的逻辑备份场景,重点在于保护密码安全和定期清理旧文件。
📋 目录
  1. 命令速用版
  2. 核心原理
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

最稳妥的方式是使用 mysqldump 配合 cron 定时任务,适合大多数中小规模数据库的逻辑备份场景,重点在于保护密码安全和定期清理旧文件。

先说结论:Shell 脚本备份 MySQL 是运维基础操作,但安全性比脚本本身更重要,务必避免明文密码。

  • 适合:中小规模数据、需要逻辑备份(可跨版本恢复)的场景
  • 先看:磁盘剩余空间、数据库账号权限、备份保留策略
  • 建议:使用配置文件存储密码,并定期测试恢复流程

命令速用版

#!/bin/bash
# 配置区域
BACKUP_DIR="/data/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="your_database"
# 必须指向运行 cron 任务用户的家目录下的配置文件
MY_CNF="/home/backup_user/.my.cnf"

# 确保备份目录存在
mkdir -p $BACKUP_DIR

# 执行备份并检查退出码
mysqldump `--defaults-file`=$MY_CNF `--single-transaction` $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz

if [ $? -ne 0 ]; then
    echo "$(date): Backup Failed" >> /var/log/backup_mysql_error.log
    exit 1
fi

# 清理 7 天前的旧备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

核心原理

Linux 下自动化备份的核心是“工具 + 调度”。mysqldump 是 MySQL 官方提供的逻辑备份工具,生成的是 SQL 语句,兼容性好,适合异构恢复或版本升级。cron 是 Linux 系统标准的任务调度服务,能保证脚本在指定时间自动运行。这种组合不需要额外安装复杂软件,依赖少,故障点也少。

但直接写在脚本里有很多隐患,比如密码泄露、磁盘写满导致服务挂掉、旧备份堆积占用空间。所以脚本只是载体,周边的权限控制和清理策略才是保证长期稳定的关键。

分步处理

1. 准备专用账号

不要使用 root 账号备份。在 MySQL 中创建一个仅拥有 SELECT 和 LOCK TABLES 权限的账号,降低泄露风险。

CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON *.* TO 'backup_user'@'localhost';

2. 安全存储密码

避免在脚本中明文写密码。创建执行定时任务用户家目录下的 ~/.my.cnf 文件(如 root 用户则为 /root/.my.cnf,普通用户则为 /home/username/.my.cnf):

[client]
user=backup_user
password=strong_password

设置权限为仅所有者可读:

chmod 600 ~/.my.cnf

这样 mysqldump 会自动读取该文件,无需在命令行输入密码。

3. 编写备份脚本

将速用版命令保存为 /usr/local/bin/backup_mysql.sh,注意修改 BACKUP_DIR、DB_NAME 和 MY_CNF 路径。加上执行权限:

chmod +x /usr/local/bin/backup_mysql.sh

4. 配置定时任务

使用 crontab -e 编辑任务,务必确保当前登录用户与步骤 2 中创建 .my.cnf 的用户一致。例如每天凌晨 3 点执行:

0 3 * * * /usr/local/bin/backup_mysql.sh >> /var/log/backup_mysql.log 2>&1

如果是 root 用户替其他用户配置,需指定用户家目录路径或使用 sudo。

5. 设置保留策略

脚本中的 find 命令用于删除 7 天前的备份,根据磁盘大小调整 -mtime 参数,防止磁盘写满。

怎么验证是否生效

1. 手动执行一次

Linux 下如何编写 Shell 脚本自动备份 MySQL 数据库?

运行脚本,检查退出码:

/usr/local/bin/backup_mysql.sh
echo $?

返回 0 表示成功。检查备份目录是否有新生成的 .sql.gz 文件。

2. 检查日志与文件完整性

查看 /var/log/backup_mysql.log,确认没有报错信息。同时检查备份文件大小是否合理(非 0 字节):

ls -lh /data/backup/mysql/*.sql.gz

如果是 cron 自动执行,也可以查看系统邮件或 cron 日志(/var/log/cron 或 /var/log/syslog)。

3. 尝试恢复测试

备份的最终目的是恢复。定期在测试环境解压并导入备份文件,验证数据完整性:

gunzip < backup_file.sql.gz | mysql -u root -p test_db

常见坑

1. 密码明文泄露

很多教程直接把密码写在脚本里,一旦脚本权限设置不当(如 777),任何用户都能看到密码。务必使用 .my.cnf 并设置 600 权限。

2. 磁盘空间不足

如果没有清理旧备份的策略,备份文件会无限增长。务必在脚本中加入删除旧文件的命令,并监控磁盘使用率。

3. 锁表影响业务

对于 InnoDB 引擎,务必加上 `--single-transaction` 参数,避免备份时锁表影响业务读写。如果是 MyISAM 引擎,该参数无效,会隐式锁表。

4. 字符集问题

如果数据库包含特殊字符,建议在 mysqldump 命令中指定 `--default-character-set`=utf8mb4,防止恢复时出现乱码。

5. Cron 环境变量缺失

Cron 执行环境 PATH 变量通常较短,可能导致找不到 mysqldump 命令。建议在脚本开头显式声明 PATH 或使用命令绝对路径(如 /usr/bin/mysqldump)。

参考来源