Crontab本身不提供快照能力,必须配合数据库原生命令(如mysqldump--single-transaction)或文件系统快照(如LVM/btrfs),再由Crontab精准调度;关键在于可靠性、可恢复性与业务无干扰。

直接用 Crontab 做数据库快照备份,关键不是“加个定时”,而是让每次备份真正可靠、可恢复、不干扰业务。它本身不提供快照能力,必须靠数据库原生命令(如 mysqldump、pg_basebackup)或文件系统层配合(如 LVM 快照、btrfs snapshot),再由 Crontab 精准调度执行。
选对快照方式:按数据库类型决定基础方法
不同数据库的“快照”含义不同,不能统一套用 tar 打包:
-
MySQL / MariaDB:推荐使用
mysqldump配合--single-transaction(InnoDB)或--lock-tables=false(避免全局锁),生成逻辑快照;若需物理级,可用mysqlpump或 Percona XtraBackup(需额外安装) -
PostgreSQL:用
pg_dump(逻辑)或pg_basebackup(物理全量快照),后者要求启用归档和流复制配置 -
SQLite:直接复制数据库文件即可,但需确保无写入——用
sqlite3 db.sqlite3 ".backup backup_$(date +%Y%m%d).db" - 注意:不要对正在运行的数据库目录直接 tar,除非已停库或使用支持热备的工具
脚本必须显式声明路径与环境
Crontab 执行时环境极简,PATH 往往只有 /usr/bin:/bin,很多命令会找不到:
- 脚本开头固定写:
#!/bin/bash,并立即设置完整 PATH:PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin; export PATH - 所有命令用绝对路径:
/usr/bin/mysqldump、/usr/lib/postgresql/*/bin/pg_dump,用which mysqldump确认实际位置 - 密码绝不写在命令行里(会被
ps看见),改用配置文件:~/.my.cnf(MySQL)或~/.pgpass(PostgreSQL),并设权限chmod 600
命名与存储要带节点标识和时间戳
避免覆盖、便于定位、支持多实例共存:
- 文件名含主机名+时间+类型,例如:
mysql_db01_20260613_1730.sql.gz或pg_cluster_prod_20260613T1730.basebackup - 目标目录按实例隔离:
/backup/mysql/app/、/backup/pg/reporting/,不要全堆进/backup/ - 压缩输出直接管道进 gzip/bzip2:
/usr/bin/mysqldump ... | gzip > $BACKUP_DIR/$FILE,节省磁盘且减少中间文件
定时策略要防冲突、留日志、控保留
看似简单的 0 2 * * * 可能引发 I/O 尖峰或失败静默:
- 跨节点部署时,在 crontab 中加随机延迟:
0 2 * * * /bin/bash -c 'sleep $((RANDOM % 300)); /home/db/backup.sh' - 每条 crontab 条目必须重定向输出:
>> /var/log/db_backup.log 2>&1,否则错误全丢进邮件队列(多数服务器没配 mail) - 脚本内嵌清理逻辑或单独配清理任务:用
find /backup/mysql/app -name "*.sql.gz" -mtime +3 -delete保留最近 3 天,加-maxdepth 1防误删子目录


















