必须加--single-transaction(InnoDB)或--lock-all-tables(混合引擎),否则备份不一致;推荐组合:mysqldump --single-transaction --routines --triggers --events -u root -p${PASS} ${DB_NAME} > backup.sql,且需校验文件非空、含CREATE TABLE、用绝对路径、密码存~/.my.cnf、定期清理过期文件。

MySQL 备份脚本怎么写才不会丢数据
直接用 mysqldump 做全量导出是可行的,但必须加 --single-transaction(InnoDB)或 --lock-all-tables(混合引擎),否则备份中途写入会导致不一致。不加锁参数的脚本在业务高峰期跑,大概率导出的是“半截状态”——表A是10:00的数据,表B却是10:05的,恢复后主从延迟、唯一键冲突都是常见后果。
推荐组合:
mysqldump --single-transaction --routines --triggers --events -u root -p${PASS} ${DB_NAME} > backup.sql- 如果库含 MyISAM 表,必须改用
--lock-all-tables,且不能和--single-transaction共存 - 务必用
-p${PASS}而非-p ${PASS}(空格会导致密码被当成下一个参数,mysqldump报错Access denied)
cron 定时执行时权限和路径经常出错
cron 环境变量极简,PATH 通常不含 /usr/local/mysql/bin,所以脚本里必须写 /usr/bin/mysqldump 这类绝对路径,否则日志里只看到 /bin/sh: mysqldump: command not found。
另一个高频问题是当前工作目录不明确:cron 默认在用户 home 目录执行,而脚本里写的 ./backup/ 会落到 /root/backup/(root 用户)或 /home/ops/backup/(普通用户)。更稳妥的做法是:
- 脚本开头加
cd /data/backup(先切到固定目录) - 所有输出路径用绝对路径,比如
/data/backup/${DB_NAME}_$(date +\%F).sql - 把 MySQL 密码存在
~/.my.cnf(权限600),避免密码明文出现在 cron 日志里
备份文件怎么保留7天又不手动删
每天生成一个文件,不清理迟早磁盘爆掉。别用 rm -f *.sql 这种粗暴方式——万一脚本路径写错,可能删掉其他重要文件。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
安全做法是只删指定前缀+过期时间的文件:
find /data/backup -name "myapp_*.sql" -mtime +7 -delete-
-mtime +7表示“修改时间超过7天”,注意不是“创建时间”;mysqldump输出文件的 mtime 就是备份完成时刻 - 首次运行前先手动建好目录:
mkdir -p /data/backup && chmod 755 /data/backup,否则脚本失败且无提示
怎么确认某次备份真的成功了
光看 cron 是否报错没用。mysqldump 即使连接失败、权限不足,也可能静默退出并生成空文件(大小为 0 字节),这种备份恢复时直接报语法错误。
必须加校验逻辑:
- 检查文件大小:
if [ ! -s "${BACKUP_FILE}" ]; then echo "empty backup"; exit 1; fi - 检查是否包含关键内容:
head -n 20 "${BACKUP_FILE}" | grep -q "CREATE TABLE" - 把每次执行结果追加进日志:
mysqldump ... >> /var/log/mysql-backup.log 2>&1,并用date打标时间戳
真正麻烦的不是写脚本,而是备份后没验证就以为万事大吉——等哪天要恢复才发现最近三天的备份全是空文件。










