最常用备份单个数据库的正确命令是mysqldump -uroot -p --single-transaction --routines --triggers myapp_db > /backup/myapp_db_$(date +%y%m%d_%h%m).sql,需避免锁表、覆盖备份及遗漏存储过程和触发器。

备份单个数据库:最常用也最容易出错的场景
直接用 mysqldump -u root -p database_name > backup.sql 就能完成,但生产环境几乎不能这么干。问题在于:没加 --single-transaction 会导致 InnoDB 表锁表(尤其大表),业务写入可能卡住;没加日期变量会覆盖上次备份;没指定路径可能生成在当前目录,找不到文件。
推荐写法:
mysqldump -uroot -p --single-transaction --routines --triggers myapp_db > /backup/myapp_db_$(date +%Y%m%d_%H%M).sql-
--routines和--triggers默认不导出存储过程和触发器,漏了就恢复不全 -
$(date +%Y%m%d_%H%M)精确到分钟,避免同天多次备份被覆盖 - 执行后会提示
Enter password:,密码不显示——这是正常行为,别误以为卡死
备份多个库或全库:别用 --databases 混淆语义
--databases 和 --all-databases 是两回事:--databases db1 db2 会显式在 SQL 文件里加上 CREATE DATABASE IF NOT EXISTS `db1` 语句;而直接写 mysqldump -u... db1 db2(无 --databases)则不会建库,只导表结构和数据,还原时必须提前创建好库。
常见误操作:
- 想备份 db1、db2,却写成
mysqldump -u... db1 db2 > backup.sql→ 还原时报错Unknown database 'db1' - 用
--all-databases但没加--routines→ 所有库的存储过程全部丢失 - 远程备份时漏掉
-h或写错端口-P(注意是大写 P),连接直接超时
正确示例:mysqldump -uroot -p -h10.0.1.5 --single-transaction --routines --triggers --databases app_db log_db > /backup/multi_$(date +%Y%m%d).sql
压缩备份与大表优化:体积和一致性必须兼顾
10GB 以上的库直接导出 SQL 文件,不仅占空间,传输慢,还容易因磁盘满或超时中断。但简单加 | gzip 不够——如果没加 --single-transaction,gzip 过程中数据还在变,备份就不一致。
关键组合:
mysqldump -uroot -p --single-transaction --skip-lock-tables --quick mybigdb | gzip > /backup/mybigdb_$(date +%Y%m%d).sql.gz-
--quick强制逐行读取,避免内存爆掉(尤其 MyISAM 或未优化的 InnoDB 表) -
--skip-lock-tables必须和--single-transaction配合使用,否则 mysqldump 会报冲突错误 - 解压还原时不能直接
mysql -u... db ,得用 <code>gunzip
还原命令不是 mysqldump:名字和用法常被搞反
很多人搜“mysqldump 还原”,结果照着抄 mysqldump -u... db ——这命令根本不存在,会报 <code>unknown option '-- 错误。还原必须用 <code>mysql 客户端命令,且目标库必须已存在(除非备份里含 CREATE DATABASE)。
典型失败场景:
- 备份用了
--databases,还原时却写mysql -u... newdb → 报错 <code>ERROR 1049 (42000): Unknown database 'newdb',因为 SQL 文件里已经指定了库名 - 备份是 gzip 压缩的,却用
mysql -u... db → 导入一堆乱码,实际是二进制内容 - 还原前没检查字符集,备份用 utf8mb4,目标库默认 latin1 → 中文变问号,且不可逆
安全还原姿势:mysql -uroot -p myapp_db (确认库已存在);压缩包则用 <code>zcat /backup/myapp_db_20260203.sql.gz | mysql -uroot -p myapp_db。
真正麻烦的从来不是命令敲不对,而是备份时没验证一致性、没留日志、没定期试还原。哪怕加了 --single-transaction,如果实例开启了 read_only=ON 或权限不足,备份仍会静默失败——所以每次备份后,至少 head -20 backup.sql | grep "CREATE TABLE" 看一眼开头是否正常。










