在Linux服务器上运行MySQL时,最让人安心的做法就是让系统每天自己把数据库导出来存好。实现这件事并不需要额外安装复杂的软件,利用系统自带的cron调度器和MySQL官方的mysqldump工具就能完成。下面直接说明具体做法和技术细节。

一、为什么用crontab加mysqldump
很多刚接触运维的同学会想自己写个守护进程,其实完全没必要。Linux的cron服务本来就是为周期性任务设计的,它稳定、日志清晰,而且所有发行版都自带。mysqldump则是MySQL安装后就有的逻辑备份工具,可以把库表结构和数据生成标准的SQL文本,恢复时只要重新执行即可。
把两者结合起来,思路就非常直接:先写一个shell脚本调用mysqldump把数据库导出成文件,再用crontab让这个脚本每天固定时间跑一次。这种做法资源占用极低,备份期间数据库仍可正常读写,适合绝大多数中小型业务场景。
二、编写备份脚本
我们先准备一个备份目录,比如/data/backup/mysql,然后创建脚本/usr/local/bin/mysql_backup.sh。脚本里要处理几件事:生成带日期的文件名、执行导出、压缩文件、删除旧备份。
为了避免在命令行明文写密码,我们采用MySQL的配置文件方式。在/etc/mysql/backup.cnf中写入账号信息,并设权限为600,这样只有root能读。下面给出完整脚本示例:
#!/bin/bash
# MySQL自动备份脚本
# 配置文件路径,内含user和password
CONFIG_FILE="/etc/mysql/backup.cnf"
# 备份存放目录
BACKUP_DIR="/data/backup/mysql"
# 需要备份的数据库名
DB_NAME="app_db"
# 保留天数
KEEP_DAYS=7
# 日期串
DATE_STR=$(date +%Y%m%d_%H%M%S)
# 导出并压缩
mysqldump --defaults-extra-file=$CONFIG_FILE $DB_NAME | gzip > $BACKUP_DIR/$DB_NAME_$DATE_STR.sql.gz
# 删除过期文件
find $BACKUP_DIR -name "$DB_NAME_*.sql.gz" -mtime +$KEEP_DAYS -exec rm -f {} ;
上面代码中,--defaults-extra-file参数指定了含密码的配置文件,避开了把密码写在进程列表里的风险。gzip管道压缩可以大幅节省空间。最后的find命令负责清理七天前的备份,防止磁盘被慢慢占满。
给脚本加上执行权限:chmod +x /usr/local/bin/mysql_backup.sh,然后手动跑一次确认能正常生成.sql.gz文件,再进入下一步。
三、用crontab设置每天执行
crontab是用户的定时任务表,使用crontab -e编辑当前用户的计划。假如希望每天凌晨两点十分执行备份,就添加下面一行:
10 2 * * * /usr/local/bin/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1
这段配置的含义是:分=10、时=2、日=每日期、月=每月、周=每星期,后面接绝对路径的脚本,并把输出和错误都追加到日志文件。这样如果哪天备份失败,查/var/log/mysql_backup.log就能看到mysqldump报了什么错。
有一点容易忽略:crontab运行时的环境变量很少,如果mysqldump不在默认PATH里,脚本要写全路径,例如/usr/bin/mysqldump。另外,某些系统开启了SELinux,可能限制cron写备份目录,需要相应调整安全上下文或目录权限。
四、备份策略的优化建议
每天全量备份虽然简单,但如果数据库很大,单日文件可能达到数GB。此时可以保留策略改为:本周每天全量,上周仅留周末一份,再早的每月留一份。用脚本判断星期几即可实现,不需要引入新工具。
如果业务不允许备份时短暂的性能波动,可以改为在从库上执行mysqldump,或者采用MySQL Enterprise Backup、Percona XtraBackup这类物理备份工具。不过对普通站点而言,crontab加mysqldump已经足够可靠,关键是真的每天自动跑起来并偶尔抽查恢复演练。
五、验证与恢复演练
自动备份不等于高枕无忧,必须定期做恢复测试。随便找一台空闲机,把.sql.gz解压后通过mysql命令导入,看业务表是否齐全。恢复命令很简单:
gunzip < app_db_20240101_020000.sql.gz | mysql -u root -p app_db
只要恢复出来的数据和预期一致,就说明整套自动备份链路是健康的。建议每月挑一个备份文件演练一次,并把结果记到运维文档里。这样当真正发生误删表或磁盘损坏时,你就能从容地从最近的那份备份里把服务拉起来。