mysqldump 必须加 --single-transaction(innodb)、--lock-all-tables(myisam)、--routines、--events、--default-character-set=utf8mb4,密码用 ~/.my.cnf 管理;脚本需检查 $?、绝对路径调用、日志写绝对路径、定期恢复验证。

mysqldump 命令怎么写才不丢数据
直接用 mysqldump 默认参数备份,大概率漏掉事务中未提交的数据、跳过视图权限报错、或因字符集不一致导致恢复失败。关键不是“能不能导出”,而是“导出的内容能否原样恢复”。
-
--single-transaction必加(InnoDB 表),避免备份时锁表又保证一致性;MyISAM 表得换--lock-all-tables -
--routines和--events要显式带上,否则存储过程、事件不会进备份文件 -
--default-character-set=utf8mb4明确指定,防止客户端默认 latin1 导致中文乱码 - 不要省略
-p后的密码——但更别写在命令里!用~/.my.cnf配置文件存凭证,权限设为600
示例安全写法:
mysqldump --single-transaction --routines --events --default-character-set=utf8mb4 -u backup_user -h 127.0.0.1 mydb > /backup/mydb_$(date +\%F).sql
shell 脚本里怎么处理备份失败和文件轮转
脚本跑一半出错却没通知,或者每天备份塞满磁盘,是比“不会写 cron”更常见的问题。重点不在执行,而在兜底。
- 每次
mysqldump后立刻检查$?:非 0 就exit 1,让 cron 知道任务失败 - 用
find /backup -name "mydb_*.sql" -mtime +7 -delete清理 7 天前的文件,别用rm -f /backup/*.sql误删当天刚生成的 - 压缩备份文件:加
| gzip > ...sql.gz,节省空间且减少 I/O 压力;解压验证可选,但首次上线建议加一句gzip -t $file - 日志写绝对路径,比如
echo "$(date): backup done" >> /var/log/mysql-backup.log,别用相对路径,cron 执行时工作目录不确定
cron 为什么总提示 “command not found” 或根本没运行
cron 的环境变量和你终端完全不一样,mysqldump 找不到、date 格式报错、甚至脚本里写的 ~/bin/backup.sh 中的 ~ 都不展开。
- 脚本第一行必须是
#!/bin/bash,且用绝对路径调用:在 crontab 里写/bin/bash /home/user/bin/backup.sh - 所有命令用全路径:
/usr/bin/mysqldump、/bin/date、/usr/bin/find——查路径用which mysqldump - crontab 条目末尾加
>> /var/log/backup-cron.log 2>&1,否则错误全丢进黑洞 - 测试时先用
run-parts --test /etc/cron.daily或手动执行脚本,确认权限(chmod +x)和内容无语法错误
备份文件权限和存放位置容易被忽略的细节
备份文件权限不对,可能让数据库用户无法读取(恢复时卡住);放在 /tmp 或 /home 下,系统更新或磁盘满时直接失效。
- 备份目录归属设为
mysql:mysql或至少chmod 750 /backup,避免敏感 SQL 文件被普通用户 ls 到 - 别把备份和 MySQL 数据目录放同一块物理盘——硬盘坏了就真没了
- 远程备份更可靠,但
scp不要裸写密码;可用rsync --rsync-path="sudo rsync" ...配合免密 sudo,或走 SSH key 认证 - 如果用云存储,
aws s3 cp或gsutil cp命令本身不失败不代表上传成功,得加--storage-class STANDARD_IA类参数并检查返回值
最常被绕开的一步:定期手动拿一个备份文件,新建空库,mysql -u root mydb 测试恢复流程。不试,就不知道 dump 里有没有注释掉的 <code>DROP TABLE 或权限语句缺失。











