mysqldump逻辑备份文件恢复总结:全库恢复、单库恢复,一篇讲明白

mysqldump 导出的备份文件,本质上就是一份 SQL 脚本。

恢复时,本质上就是把这份 SQL 再交给 mysql 执行。

命令看起来不复杂,但真正容易踩坑的地方主要有这些:

  • 恢复到测试服务器,还是恢复到源库

  • 恢复全库,还是只恢复单库

  • 备份文件里是否带了系统库

  • 单库恢复时目标库是否提前创建

  • 源库和目标库字符集、排序规则是否一致

  • 恢复完成后如何快速核对结果

这篇文章就把这些关键点一次讲清楚。


一、恢复前先记住 4 个原则

1. 恢复前先看字符集和排序规则

尤其是从生产恢复到测试时,建议先对比源库和目标库的字符集、排序规则是否一致。

常用 SQL:

复制代码
SHOW CREATE DATABASE demo_app;

或者:

复制代码
SELECT schema_name, default_character_set_name, default_collation_name
FROM information_schema.schemata
WHERE schema_name = 'demo_app';

重点看两项:

  • default_character_set_name

  • default_collation_name

如果两边不一致,恢复后可能会出现乱码、排序不一致、索引比较异常等问题。


2. 全库备份和单库恢复不是一回事

如果导出时用了:

复制代码
mysqldump --all-databases

那备份文件里通常会带多几个系统库,甚至可能带 mysql 系统库。

这时候:

  • 全库恢复:可以直接整体导入

  • 单库恢复 :不能无脑直接导,要用 --one-database


3. 单库恢复时,目标库必须先存在

这是最容易忽略的点。

如果直接执行:

复制代码
mysql --one-database demo_app -u root -p < all_no_mysql.sql

而目标实例里还没有 demo_app 这个库,就会报:

复制代码
ERROR 1049 (42000): Unknown database 'demo_app'

所以单库恢复前,必须先把目标库建出来


4. 恢复到测试服务器和恢复到源库,风险完全不同

恢复到测试服务器,主要是验证和测试,风险可控。

恢复到源库,直接影响业务,必须更谨慎。

一句话记住:

测试服务器恢复,重点是恢复成功。
源库恢复,重点是恢复安全。


二、恢复到测试服务器


场景 1:全库恢复

适合这种情况:

  • 测试实例里没有重要数据

  • 允许整体覆盖

  • 目标就是把整批业务库恢复进去

如果备份文件已经去掉了系统库,比如:

复制代码
all_no_mysql.sql

那恢复命令最简单:

复制代码
mysql -P 3308 -u root -p < /soft/all_no_mysql.sql

恢复后检查:

复制代码
mysql -P 3308 -u root -p -e "SHOW DATABASES;"

如果业务库都在,说明整体恢复基本成功。


场景 2:只恢复单库

这是更常见、也更稳的操作。

假设现在只想恢复 demo_app 这个库。

第一步:先创建目标库(字符集和源库一致)
复制代码
mysql -P 3308 -u root -p -e "CREATE DATABASE IF NOT EXISTS \`demo_app\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"

这里要注意:

  • 库名要和你要恢复的库名一致

  • 字符集、排序规则尽量和源库保持一致

第二步:执行单库恢复
复制代码
mysql --one-database demo_app -P 3308 -u root -p < /soft/all_no_mysql.sql
第三步:恢复后检查
复制代码
mysql -P 3308 -u root -p -e "SHOW TABLES FROM \`demo_app\`;"

如果表都出来了,单库恢复就基本完成了。


三、恢复到源库

这里要先讲一句实话:

源库恢复比测试服务器恢复危险得多。

因为一旦操作不对,容易覆盖现有数据。

所以恢复到源库前,建议先再备份一次当前库,留退路。


场景 1:源库全库恢复

这种情况一般只在明确要整体回退时才做。

如果你确认要整体恢复业务库:

复制代码
mysql -u root -p < /data/backup/mysql/all_no_mysql.sql

如果是原始整包备份文件,也可以:

复制代码
mysql -u root -p < /data/backup/mysql/all_2026-03-28_09-51-25.sql

但这类操作风险最大,不建议随便做。


场景 2:源库单库恢复

这是生产上更常见、更稳妥的方式。

假设要恢复 demo_app

第一步:删除旧库

如果确认要覆盖原库,先删旧库:

复制代码
mysql -u root -p -e "DROP DATABASE IF EXISTS \`demo_app\`;"
第二步:重新建库

建库时字符集和排序规则尽量与原库一致:

复制代码
mysql -u root -p -e "CREATE DATABASE \`demo_app\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
第三步:恢复单库
复制代码
mysql --one-database demo_app -u root -p < /data/backup/mysql/all_no_mysql.sql
第四步:检查恢复结果
复制代码
mysql -u root -p -e "SHOW TABLES FROM \`demo_app\`;"

四、为什么单库恢复必须先建库

这是恢复单库时最关键的细节。

mysql --one-database 库名 的作用,不是"自动把这个库恢复出来",而是:

只执行 SQL 文件中属于这个库的语句。

也就是说,它只是"过滤执行",不是"自动建库"。

它不是按文件名识别,也不是按表名猜,而是按 SQL 文件里的 USE 库名 来判断哪些语句该执行。

所以如果目标库不存在,它一开始就会失败。

这就是为什么:

  • 全库恢复 通常不需要手工建库

  • 单库恢复 通常必须先建好库

因为全库恢复的 SQL 文件里一般自带:

复制代码
CREATE DATABASE ...
USE ...

而单库恢复时你用的是 --one-database 过滤执行,目标库得先存在。


五、为什么不建议备份时带系统库

实际恢复过程中,最麻烦的地方往往就是系统库。

如果备份文件里带了 mysql 系统库,恢复到测试服务器时可能会带来这些问题:

  • 修改测试实例的 root 密码

  • 覆盖用户和权限

  • 恢复过程中更容易出错

  • 单库恢复时处理更麻烦

所以更推荐的做法是:

1. 如果只是业务恢复,导出时就不要带系统库

不要再用:

复制代码
mysqldump --all-databases

更推荐:

复制代码
mysqldump -uroot -p \
  --databases \
  demo_app demo_order demo_report \
  --routines --events --triggers \
  --single-transaction --quick --hex-blob \
  --default-character-set=utf8mb4 \
  > business_all.sql

这样导出来的文件只包含业务库,不包含 mysql 系统库。


2. 如果以后经常只恢复单库,最好直接做单库备份

复制代码
mysqldump -uroot -p \
  --databases demo_app \
  --routines --events --triggers \
  --single-transaction --quick --hex-blob \
  --default-character-set=utf8mb4 \
  > demo_app.sql

这样以后恢复最简单:

复制代码
mysql -u root -p < demo_app.sql

六、恢复完成后,源库和测试库可以对比什么

恢复完成后,建议至少对比以下几个维度:

  • 库是否存在

  • 每个业务库有多少张表

  • 某个库里有哪些表

  • 核心表有多少行数据

  • 字符集和排序规则是否一致


1. 对比有哪些库

复制代码
SHOW DATABASES;

如果只想看业务库,不看系统库,可以用:

复制代码
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name NOT IN ('mysql','information_schema','performance_schema','sys')
ORDER BY schema_name;

2. 对比每个业务库有多少张表

复制代码
SELECT table_schema, COUNT(*) AS table_cnt
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys')
GROUP BY table_schema
ORDER BY table_cnt DESC;

这条 SQL 很实用,能快速看出:

  • 哪些库恢复进来了

  • 每个库有多少张表

  • 源库和测试库表数量是否一致


3. 对比某个库里有哪些表

例如查看 demo_app

复制代码
SHOW TABLES FROM `demo_app`;

或者:

复制代码
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'demo_app'
ORDER BY table_name;

4. 对比某个库里有多少张表

复制代码
SELECT COUNT(*) AS table_cnt
FROM information_schema.tables
WHERE table_schema = 'demo_app';

5. 对比核心表的行数

例如对比 users 表和 orders 表:

复制代码
SELECT COUNT(*) AS row_cnt FROM demo_app.users;
SELECT COUNT(*) AS row_cnt FROM demo_app.orders;

源库执行一次,测试库执行一次,直接比结果。

说明一下:

如果表很多,不建议一上来每张表都 COUNT(*) ,太重。

实际工作中一般抽查:

  • 主业务表

  • 大表

  • 关键配置表

  • 最近变更过的表

这样就够用了。


6. 快速看某个库里每张表的大概行数

复制代码
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = 'demo_app'
ORDER BY table_rows DESC;

这个更快,但要注意:
对于 InnoDB 表,这个行数通常是估算值,不一定绝对准确。

如果要精确对比,还是以 COUNT(*) 为准。


7. 对比字符集和排序规则

复制代码
SELECT schema_name, default_character_set_name, default_collation_name
FROM information_schema.schemata
WHERE schema_name = 'demo_app';

主要对比:

  • default_character_set_name

  • default_collation_name

如果源库和测试库不一致,恢复后可能会有乱码、排序差异等问题。


七、以后可以直接照着用的命令

测试服务器全库恢复

复制代码
mysql -P 3308 -u root -p < /soft/all_no_mysql.sql

测试服务器单库恢复

复制代码
mysql -P 3308 -u root -p -e "CREATE DATABASE IF NOT EXISTS \`demo_app\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
mysql --one-database demo_app -P 3308 -u root -p < /soft/all_no_mysql.sql

源库全库恢复

复制代码
mysql -u root -p < /data/backup/mysql/all_no_mysql.sql

源库单库恢复

复制代码
mysql -u root -p -e "DROP DATABASE IF EXISTS \`demo_app\`;"
mysql -u root -p -e "CREATE DATABASE \`demo_app\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
mysql --one-database demo_app -u root -p < /data/backup/mysql/all_no_mysql.sql

八、总结

MySQL 逻辑备份恢复,命令其实不复杂,真正要记住的是流程和细节:

  • 恢复前先对比字符集、排序规则

  • 恢复到测试服务器和恢复到源库要分开看

  • 全库恢复可以直接导

  • 单库恢复一定记得先建库

  • 备份时尽量不要把系统库一起带进去

  • 恢复完成后,要核对库、表、表数量和核心表数据量

一句话收尾:

全库恢复靠整体导入,单库恢复靠先建库再过滤恢复。

如果你后面想把这篇再改成更像"运维经验总结"的风格,我也可以继续帮你润成更适合发博客的版本。

相关推荐
舰长1152 小时前
linux系统服务器加固1、中风险 未设置登录失败处理功能和登录连接超时处理功能。2、中风险 未限制默认账户的访问权限。3、中风险 未实现管理用户的权限分离。
linux·运维·服务器
ybwycx2 小时前
mysql重置root密码(适用于5.7和8.0)
数据库·mysql·adb
mounter6252 小时前
Linux 7.0 重磅更新:详解 nullfs 如何重塑根文件系统挂载与内核线程隔离
linux·运维·服务器·kernel
色空大师3 小时前
【网站搭建实操(一)环境部署】
java·linux·数据库·mysql·网站搭建
亚历克斯神3 小时前
Flutter for OpenHarmony: Flutter 三方库 mutex 为鸿蒙异步任务提供可靠的临界资源互斥锁(并发安全基石)
android·数据库·安全·flutter·华为·harmonyos
-Da-3 小时前
Unix哲学:一切皆文件与网络通信的统一抽象
服务器·unix
江南风月3 小时前
日志审计系统WGLOG支持syslog吗
运维·网络·日志审计
IAUTOMOBILE3 小时前
用Python批量处理Excel和CSV文件
jvm·数据库·python
常利兵4 小时前
Spring项目新姿势:Lambda封装Service调用,告别繁琐注入!
java·数据库·spring