乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 数据库基础与安装

    • MySQL 简介
    • MySQL 5.6 到 5.7 到 8.0 关键差异速查
    • 安装 MySQL 5.7
    • 连接与断开服务器
    • 创建数据库
    • 创建数据表
    • 数据库与数据表
    • 加载数据
    • 获取数据库信息
    • 批处理模式
    • SHOW 语句汇总
    • FLUSH 与 RESET 语句
    • my.cnf 核心参数
    • 字符集与排序规则
  • 第2章 SQL基础查询

    • SELECT
    • WHERE
    • ORDER BY
    • LIMIT
    • COUNT
    • 聚合函数
    • 比较运算符
    • 逻辑运算符
    • 算术运算符
    • 模式匹配
    • NULL 值处理
    • UPDATE
    • DELETE
    • REPLACE
    • SELECT INTO
  • 第3章 数据类型与运算符

    • 数值类型
    • 字符串类型
    • 日期时间类型
    • BIT 类型
    • ENUM 类型
    • SET 类型
    • JSON 类型
    • 类型转换
  • 第4章 函数与表达式

    • 字符串函数
    • 数值函数
    • 日期函数
    • 全文检索函数
  • 第5章 高级查询与子查询

    • JOIN
    • 子查询
    • UNION
    • GROUP BY
    • HAVING
    • DISTINCT
  • 第6章 表与索引

    • 数据定义语言
    • 修改表结构
    • 视图
    • 修改视图与检查选项
    • 外键
    • 索引
    • 唯一索引
    • 复合索引
    • 存储引擎对比
    • 分区表
    • 第一范式与第二范式
    • 第三范式与 BC 范式
    • 反范式设计
  • 第7章 存储过程与函数

    • 存储过程
    • 存储函数
    • 变量
    • 流程控制
    • 游标
    • 预处理语句
  • 第8章 事务与锁

    • 事务
    • 事务隔离级别
    • 锁机制
    • MVCC
    • 死锁专题分析
    • LOCK TABLES
    • XA 事务
  • 第9章 用户管理与安全

    • 用户管理
    • 权限管理
    • 角色
    • SQL 注入防范
  • 第10章 性能优化入门

    • 执行计划
    • 索引优化
    • 查询优化
    • 查询优化器提示
    • 慢查询日志
    • InnoDB 深入机制
    • InnoDB 专项优化
    • Performance Schema
    • sys Schema
  • 第11章 复制与高可用

    • 主从复制原理
    • 半同步复制配置
    • binlog 开启与 point-in-time 恢复
    • mysqldump 全库备份
    • mysqldump 单表与条件备份
    • mysqldump 恢复与导入
    • xtrabackup 全量热备
    • xtrabackup 准备与恢复
    • xtrabackup 增量与流式备份
  • 第12章 触发器与事件

    • 触发器
    • 事件调度器
  • 参考

    • MySQL 5.7 专业术语大全
    • MySQL 5.7 关键字与保留字大全

mysqldump 恢复与导入

导学

备份的价值在于恢复。.sql 文件拿到手后,如何安全、高效地还原到数据库?小文件直接 mysql < file.sql,大文件需要分步处理,生产环境还要考虑字符集、外键约束、触发器执行顺序等细节。

定义

恢复(Restore):将备份的 SQL 文件重新执行到 MySQL 服务器,重建数据库、表结构和数据。导入(Import):将数据文件加载到已有表结构中,通常指追加数据而非重建表。

场景一:全库恢复

当前数据状态:假设服务器刚重装,MySQL 为空,只有系统库。

SHOW DATABASES;
Database
information_schema
mysql
performance_schema
sys

操作语句(命令行):

mysql -u root -p < full_backup_20240115.sql

输入密码后,MySQL 逐行执行 SQL 文件中的语句。

操作后数据状态:

SHOW DATABASES;
Database
company
information_schema
mysql
performance_schema
sys
USE company;
SELECT emp_name FROM employees;
emp_name
大翔
白歌

结果解读:全库恢复会重建备份时存在的所有数据库、表、数据、存储过程、触发器等。如果目标服务器已有同名数据库,备份文件中的 DROP TABLE IF EXISTS 会先删除旧表,再创建新表。

场景二:单库恢复到新数据库名

操作语句:将 company 库的备份恢复到新库 company_backup。

# 方法:先创建目标库,然后过滤原 SQL 中的库名
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS company_backup;"

# 用 sed 替换库名(仅适用于简单场景)
sed 's/`company`/`company_backup`/g' company_backup.sql | mysql -u root -p

验证:

USE company_backup;
SELECT emp_name FROM employees;
emp_name
大翔
白歌

结果解读:mysqldump 生成的 SQL 文件包含 USE company;,直接执行会恢复到原库名。通过 sed 替换库名是一种快捷方法,但复杂场景(存储过程、触发器、事件中有硬编码库名)可能替换不全,更稳妥的方式是用 --databases 备份时只备份数据结构,恢复前手动编辑 USE 语句。

场景三:大 SQL 文件分步恢复

问题:100GB 的 SQL 文件直接 mysql < file.sql 可能因网络中断、内存不足而失败,且失败后难以定位进度。

操作语句:

# 方法 1:用 source 命令在 mysql 客户端内执行(支持断点续传感)
mysql -u root -p
-- 在 mysql> 提示符下
SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;

SOURCE /backup/full_backup.sql;

SET foreign_key_checks=1;
SET unique_checks=1;
COMMIT;

结果解读:

  • autocommit=0 + COMMIT:将所有 INSERT 包裹在一个大事务中提交,比逐条提交快数倍
  • unique_checks=0:跳过唯一性检查(恢复完再检查),加速导入
  • foreign_key_checks=0:跳过外键检查,避免导入顺序导致的外键约束失败
  • SOURCE 在客户端内执行,比管道 mysql < file 更稳定,且能看到执行进度

场景四:只导入数据(表已存在)

当前数据状态:company 库的 employees 表已存在,结构正确,但数据为空。

USE company;
SELECT COUNT(*) FROM employees;
COUNT(*)
0

操作语句:从只含数据的 SQL 文件导入。

# 假设 employees_data.sql 是用 --no-create-info 导出的
mysql -u root -p company < employees_data.sql

操作后数据状态:

SELECT emp_name FROM employees;
emp_name
大翔
白歌

结果解读:--no-create-info 导出的文件只含 INSERT,不含 DROP 和 CREATE,可以直接导入已有结构的表。如果目标表已有数据,需确保 INSERT 不会触发主键冲突——可用 INSERT IGNORE 或 REPLACE 策略。

场景五:处理字符集问题

问题:备份文件是 utf8mb4,恢复时客户端字符集不对,导致中文乱码。

操作语句:

# 恢复前设置客户端字符集
mysql -u root -p --default-character-set=utf8mb4 company < backup.sql

或在 SOURCE 前执行:

SET NAMES utf8mb4;
SOURCE /backup/backup.sql;

结果解读:--default-character-set=utf8mb4 确保客户端、连接、结果集都使用 utf8mb4,避免中文在传输过程中被错误转码。恢复后验证:

SELECT emp_name, HEX(emp_name) FROM employees WHERE emp_id = 1;

大翔 的 UTF-8 十六进制应为 E5A4A7 E7BF 94(具体值取决于编码),如果显示为 3F3F(问号),说明字符集设置有误。

常见误区

误区正解
"恢复时直接 mysql < file.sql 就行"小文件可以;大文件建议用 SOURCE + 关闭 autocommit/unique_checks/foreign_key_checks,速度提升数倍。
"恢复不会删除现有数据"会。备份文件中的 DROP TABLE IF EXISTS 会删除旧表。如需保留,先编辑 SQL 文件删除 DROP 和 CREATE。
"恢复时外键约束自动处理导入顺序"不会。如果表 A 有外键依赖表 B,但 A 的 INSERT 在 B 之前,会报错。需 SET foreign_key_checks=0; 跳过。
"SOURCE 和 mysql < file 完全一样"不完全。SOURCE 在客户端内执行,能看到进度和错误行号;管道方式错误信息可能被吞掉。

面试考点

Q:100GB 的 mysqldump 文件怎么快速恢复?

  1. SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0;;2. SOURCE file.sql;;3. COMMIT; 恢复约束。比默认逐条提交快 5~10 倍。如果仍太慢,考虑用 LOAD DATA INFILE 替代 INSERT。

Q:恢复时遇到 Duplicate entry 错误怎么办?

原因:目标表已有数据,备份文件的 INSERT 与现有数据主键冲突。解决:1. 先 TRUNCATE 清空表;2. 或编辑 SQL 文件将 INSERT INTO 改为 INSERT IGNORE INTO;3. 或用 REPLACE INTO(会覆盖现有数据)。

Q:如何只恢复备份中的某一张表?

方法 1:用 grep 提取该表的 DROP/CREATE/INSERT 语句到新文件,再执行。方法 2:用 sed 删除其他表的语句。方法 3:恢复全库到新实例,再用 mysqldump 导出目标表。

小结

  • 全库恢复:mysql -u root -p < backup.sql
  • 大文件加速恢复:SET autocommit=0; unique_checks=0; foreign_key_checks=0; SOURCE file.sql; COMMIT;
  • 字符集:--default-character-set=utf8mb4 或 SET NAMES utf8mb4;
  • 恢复前确认备份文件是否包含 DROP TABLE,避免误删生产数据

下一章引子:mysqldump 是逻辑备份,适合小库和迁移;但生产环境的大库需要更快、不锁表的物理备份方案——xtrabackup。

上一页
mysqldump 单表与条件备份
下一页
xtrabackup 全量热备