最稳妥的单库备份命令是:mysqldump -u root -p --single-transaction --routines --triggers --events --default-character-set=utf8mb4 myproject_db > myproject_$(date +%y%m%d).sql,必须包含--single-transaction(innodb热备)、--routines/--triggers/--events(保留逻辑对象)及utf8mb4字符集,且密码交互输入、文件名带日期。

直接用 mysqldump 备份单个项目数据库最稳妥
绝大多数项目数据库(innodb 引擎、50GB 以内、无特殊高可用架构)直接用 mysqldump 就够了,不用折腾其他工具。它生成标准 SQL 文件,可读、可审计、可跨版本恢复,是开发和运维交接时最不容易出错的方式。
常见错误现象:备份后恢复时报错 ERROR 1062 (23000): Duplicate entry 或缺失触发器/存储过程——往往是因为没加关键参数。
- 必须加上
--single-transaction(innodb表)或--lock-tables(myisam表),否则备份期间写入会导致数据不一致 - 要保留逻辑对象,得显式加
--routines --triggers --events - 如果项目含中文或 emoji,务必加
--default-character-set=utf8mb4,否则可能乱码 - 大表导出容易卡住或超内存,加
--quick和--skip-buffer避免客户端缓存整张表
mysqldump 命令里哪些参数不能省
一个能直接用于生产环境的最小安全命令长这样:
mysqldump -u root -p --single-transaction --routines --triggers --events --default-character-set=utf8mb4 myproject_db > myproject_$(date +%Y%m%d).sql
注意几个硬性条件:
-
--single-transaction只对innodb有效;如果库混用myisam表,它不起作用,必须改用--lock-all-tables -
--routines不会导出函数权限,恢复后需手动授权GRANT EXECUTE ON FUNCTION ... - 输出文件名带日期是基本操作,但别只靠文件名判断“最新”——
ls -lt看修改时间更可靠 - 密码不要写在命令行里(会留痕),用
~/.my.cnf配置文件更安全
备份文件太大或太慢?先确认是不是真需要全量
很多项目其实不需要每天全库备份。比如日志表、监控表、临时计算结果表,完全可以排除在外,既减小体积又加快速度。
- 用
--ignore-table=myproject_db.audit_log排除指定表(可多次使用) - 想只备份某些表,直接把表名列在命令末尾:
mysqldump ... myproject_db user_order user_profile > partial.sql - 增量备份不是靠
mysqldump参数实现的,而是配合二进制日志(binlog)+ 全量备份做 PITR(基于时间点恢复),单独用mysqldump加--where很容易漏数据或重复 - 如果单次备份耗时超过 15 分钟,优先检查是否开启了
slow_query_log或有大 BLOB 字段——这些才是瓶颈,不是工具问题
备份完别急着删旧文件,先验证能不能恢复
90% 的备份失效发生在恢复环节。没人真去试,直到出事那天才发现 SQL 文件损坏、字符集错位、或缺少 CREATE DATABASE 语句。
- 用
head -n 20 backup.sql看开头是否有CREATE DATABASE和USE语句;没有就加--databases参数重备 - 快速验证语法:
mysql -u test -e "source /path/to/backup.sql" 2>/dev/null || echo "syntax error" - 真正恢复测试建议在隔离环境跑一次
mysql -u root -p myproject_test ,至少确认主键和索引重建成功 - 自动备份脚本里一定要加
md5sum校验和保留最近 3 份,而不是“每天覆盖一个文件”
真正麻烦的从来不是怎么备份,而是怎么确认这份备份在关键时刻能用。校验、隔离测试、保留多版本——这三件事漏掉任何一项,备份就只是心理安慰。











