不是必须,但不加会出问题;直接 mysqldump -u root -p testdb 不含 create database 和 use 语句,恢复时若库不存在则报错 error 1049。

mysqldump 备份单库时必须指定 --databases 吗?
不是必须,但不加会出问题。直接执行 mysqldump -u root -p testdb 会导出 testdb 库的所有表,但**不包含 CREATE DATABASE 和 USE 语句**。恢复时如果目标库不存在,mysql 命令会报错 ERROR 1049 (42000): Unknown database 'testdb'。
正确做法是显式加上 --databases(注意复数):
mysqldump -u root -p --databases testdb > testdb.sql
这样导出的 SQL 文件开头会有:
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `testdb` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;<br>USE `testdb`;
- 不加
--databases:适合已有同名库、只同步表结构和数据的场景 - 加
--databases:适合完整迁移或首次恢复,能重建库+表+数据 - 误用
--database(单数)会被忽略,等价于没写——这是新手高频翻车点
恢复时为什么执行 mysql 命令总卡住或报错?
常见原因不是权限或连接问题,而是 SQL 文件里含 CREATE DATABASE 语句,而目标 MySQL 实例中已存在同名库,且用户没有 DROP DATABASE 权限。此时 mysql -u root -p 会停在第一条 <code>CREATE DATABASE 并报错 ERROR 1007 (HY000): Can't create database 'testdb'; database exists。
解决方式取决于需求:
- 想覆盖重建:加
--force参数让mysql跳过错误继续执行(但不会自动删库,仍需手动DROP DATABASE testdb或在 dump 时加--add-drop-database) - 想安全追加:先用
mysql -u root -p -e "DROP DATABASE IF EXISTS testdb;"清空再导入 - 只想恢复表数据:dump 时不加
--databases,恢复前确保库已存在且字符集一致
别依赖 --force 掩盖权限缺失——它只是跳过错误,不代表操作成功。
mysqldump 备份大库时为什么慢、甚至中断?
默认情况下 mysqldump 是单线程、全表锁(MyISAM)或行级快照(InnoDB),但遇到大表(比如 >1GB)仍可能因超时或内存溢出失败。关键参数要调:
-
--single-transaction:对 InnoDB 必加,避免锁表,保证一致性快照(但要求事务隔离级别非 SERIALIZABLE) -
--skip-lock-tables:禁用FLUSH TABLES WITH READ LOCK,适用于主从架构下从库备份(但需确认无 DDL 操作) -
--net_buffer_length=1M和--max_allowed_packet=256M:防止网络缓冲区溢出导致中断(尤其跨网络备份时) -
--routines --triggers --events:如需备份存储过程、触发器、事件,必须显式加上,它们默认不导出
导出后建议立刻校验:head -n 20 testdb.sql 看是否有 CREATE DATABASE 和 USE;tail -n 10 testdb.sql 看是否以 /*...Finished dumping data for table... 结尾,避免截断。
恢复后发现中文乱码或时间字段异常?
本质是字符集不匹配。即使源库是 utf8mb4,如果 dump 文件没声明编码,或 mysql 客户端默认用 latin1 解析,就会乱码。最稳方案是全程显式指定:
- 备份时加
--default-character-set=utf8mb4 - 恢复时也加同样参数:
mysql -u root -p --default-character-set=utf8mb4 testdb - 检查源库表字符集:
SHOW CREATE TABLE t1;确认DEFAULT CHARSET=utf8mb4 - 检查目标库全局变量:
SHOW VARIABLES LIKE 'character_set%';,重点看character_set_client、character_set_connection、character_set_database是否均为utf8mb4
时间字段异常(如 0000-00-00 变成 NULL)通常因 SQL mode 不一致,比如源库开了 NO_ZERO_DATE 而目标库没开——这容易被忽略,但会导致业务逻辑错乱。











