安全可靠的 mysqldump 命令需指定 --default-character-set=utf8mb4、--single-transaction(InnoDB)、--routines --triggers --events,并通过 ~/.my.cnf 管理密码;crontab 中须声明 PATH、用绝对路径、重定向日志;备份脚本应先 dump 再清理旧文件,远程推送需免密 SSH 并添加失败告警。

mysqldump 导出命令怎么写才安全可靠
直接用 mysqldump 而不加关键参数,导出的 SQL 文件很可能无法还原:缺少建库语句、字符集错乱、视图或存储过程报错。必须显式指定 --default-character-set=utf8mb4 和 --single-transaction(对 InnoDB 有效),并用 --routines --triggers --events 补全逻辑对象。
推荐基础命令模板:
mysqldump -u<code>root</code> -p<code>your_password</code> --default-character-set=utf8mb4 --single-transaction --routines --triggers --events --databases <code>db1</code> <code>db2</code> > /backup/mysql_$(date +\%Y\%m\%d_\%H\%M\%S).sql
- 密码不要明写在命令里(会暴露在
ps aux中),改用配置文件方式:创建~/.my.cnf,权限设为600,内容含[client]段和user/password - 导出路径需确保 MySQL 进程有写权限;若用
sudo运行脚本,注意环境变量和家目录路径差异 -
--single-transaction不适用于 MyISAM 表,混合引擎库建议停写或用--lock-all-tables
crontab 定时任务为什么总不执行
最常见原因是环境变量缺失:crontab 默认只加载 minimal PATH(通常不含 /usr/bin 或 /usr/local/bin),mysqldump 命令找不到,日志里只显示“command not found”却无具体路径提示。
解决方法:
- 在 crontab 条目开头显式声明 PATH:
PATH=/usr/local/bin:/usr/bin:/bin - 所有命令用绝对路径:查
which mysqldump得到真实路径,比如/usr/bin/mysqldump - 重定向 stderr 到日志文件,方便排查:
2>&1 >> /var/log/mysql_backup.log - 测试时先设为每分钟执行一次(
* * * * *),确认日志有输出再调回正式周期
备份文件怎么自动轮转不占满磁盘
单纯靠 cron 每天 dump 一个文件,不出三个月就撑爆磁盘。必须加清理逻辑,但别在 dump 命令后直接 rm —— 若 dump 失败,上一轮备份也被误删。
稳妥做法是把 dump 和清理拆成两个步骤,用脚本封装:
#!/bin/bash BACKUP_DIR="/backup" DATE=$(date +\%Y\%m\%d_\%H\%M\%S) mysqldump -u<code>root</code> --defaults-file=<code>~/.my.cnf</code> --single-transaction --routines --triggers --events --databases <code>app_db</code> > $BACKUP_DIR/app_db_$DATE.sql 2>&1 if [ $? -eq 0 ]; then find $BACKUP_DIR -name "app_db_*.sql" -mtime +7 -delete fi
-
--defaults-file比-p更安全,避免密码泄露风险 -
find ... -mtime +7删除 7 天前的文件,注意-mtime按 24 小时整数倍计算,不是精确到秒 - 脚本保存为
/opt/scripts/mysql_backup.sh,chmod +x 后在 crontab 中调用完整路径
远程备份到另一台服务器是否可行
可以,但别用 ssh user@host 'mysqldump ...' 这种写法 —— 远程 shell 环境通常没加载 .my.cnf,且交互式密码输入在 cron 下必然失败。
更稳的方式是本地 dump 完,再用 rsync 或 scp 推送:
- 确保目标机器已配好 SSH 免密登录(用
ssh-keygen+ssh-copy-id) - 推送命令加
-e "ssh -o StrictHostKeyChecking=no"避免首次连接交互阻塞 - 推送成功后再本地清理旧文件,顺序不能反:先
rsync,再find ... -delete - 如果网络不稳定,考虑加
timeout 300限制 rsync 最长耗时,防止 cron 任务堆积
异地备份的关键不是“能不能传”,而是“传失败了有没有告警”。至少加一行 || echo "$(date): backup push failed" | mail -s "MySQL Backup Alert" admin@example.com。


















