备份单个数据库:最常用也最容易出错的场景
直接用
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"看一眼开头是否正常。
