备份与恢复:给数据买一份"后悔药"
📖 本节导读
- 明白为什么必须备份:误删、磁盘损坏随时可能发生,数据无价
- 学会用
mysqldump备份单个库、单张表、所有库(注意:这是系统命令,不在 mysql 提示符里执行!) - 掌握两种恢复方式:
mysql < 备份文件和SOURCE命令 - 完整演练一次"备份 → 删表 → 恢复",并了解定期自动备份的思路
一、为什么必须备份
先看两个真实世界里天天上演的悲剧:
- 误删:本想执行
DELETE FROM student WHERE id = 5;,手一抖,WHERE没带上,全表数据没了。或者更狠的,DROP DATABASE删错了库。 - 硬件故障:硬盘说坏就坏、服务器进水、笔记本被偷……数据所在的磁盘物理损坏,神仙也救不回来。
代码删了可以重写,数据没了就是真的没了——学生的成绩、用户的订单,都是没法"重新敲一遍"的。所以数据库领域有一条铁律:
没有备份的数据,等于随时可能消失的数据。
备份就是提前复制一份数据放到别处,出事时用它把数据"救"回来(恢复)。类比:备份就是游戏里的存档——打 BOSS 之前先存个档,团灭了还能读档重来。
二、用 mysqldump 备份
MySQL 自带一个备份工具 mysqldump。它的原理很朴素:把库里的表结构和数据,翻译成一大堆 CREATE TABLE 和 INSERT 语句,写进一个 .sql 文本文件。这种方式叫逻辑备份——备份的不是硬盘上的原始文件,而是"能重建出这些数据的 SQL 剧本"。
⚠️ 先说新手最容易犯的错
mysqldump 是系统命令行的程序,不是 SQL 语句! 它要在 Windows 的 CMD/PowerShell(或 Linux 终端)里执行,不能在 mysql> 提示符里敲。如果你在 mysql> 里输入 mysqldump,只会得到一个语法错误:
mysql> mysqldump -u root -p school > backup.sql;
ERROR 1064 (42000): You have an error in your SQL syntax; ...
看到这个报错,先检查自己是不是敲错了地方。正确姿势:先退出 mysql(输入 exit;)或另开一个命令行窗口,再执行下面的命令。
2.1 备份单个数据库
mysqldump -u root -p school > school_backup.sql
拆解一下:
-u root -p:和登录 mysql 一样,指定用户并提示输入密码school:要备份的数据库名> school_backup.sql:>是"重定向"符号,意思是把输出写进文件而不是打印在屏幕上。文件会生成在当前目录(也可以写完整路径,如> D:\backup\school_backup.sql)
执行后要求输入密码,成功时没有任何输出(沉默即成功),当前目录下会多出 school_backup.sql。
2.2 备份单张表
在库名后面跟上表名即可:
mysqldump -u root -p school student > student_backup.sql
备份多张表就并排写:mysqldump -u root -p school student score > two_tables.sql。
2.3 备份所有数据库
mysqldump -u root -p --all-databases > all_backup.sql
2.4 看看备份文件里到底是什么
用记事本或任何编辑器打开 school_backup.sql,你会发现它就是一堆普通的 SQL 语句(节选):
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: school
-- ------------------------------------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`gender` char(1) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`class_id` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `student` VALUES
(1,'张三','男','2005-03-15',1),
(2,'李四','男','2005-07-01',1),
(3,'王小红','女','2006-01-20',2),
(4,'赵敏','女','2005-11-08',2),
(5,'陈刚','男','2006-05-30',1);
所谓"恢复",本质就是把这个剧本从头到尾重新执行一遍:先建表,再把数据一行行插回去。毫无魔法,特别踏实。
三、恢复数据
恢复有两种常用方式,效果一样,选顺手的即可。
方式一:系统命令行,用 < 导入
mysql -u root -p school < school_backup.sql
注意方向:备份时用 >(数据流出到文件),恢复时用 <(文件流入数据库)。前提是 school 这个库要存在(如果整个库被删了,先登录 mysql 执行 CREATE DATABASE school; 再恢复)。
方式二:mysql 提示符里,用 SOURCE 命令
先登录 mysql,然后:
USE school;
SOURCE D:/backup/school_backup.sql
SOURCE 后面跟备份文件的完整路径,不需要引号,路径建议用正斜杠 /(Windows 下反斜杠有时会被转义出问题)。执行时屏幕会刷出一长串 Query OK,那就是剧本里的语句在一条条执行。
四、完整演练:备份 → 闯祸 → 恢复
跟着做一遍,你对备份的信心会完全不同。
第 1 步:备份 school 库(系统命令行):
mysqldump -u root -p school > school_backup.sql
第 2 步:制造"事故"——登录 mysql,把 score 表整个删掉:
USE school;
DROP TABLE score;
SHOW TABLES;
+------------------+
| Tables_in_school |
+------------------+
| class |
| course |
| student |
+------------------+
3 rows in set (0.00 sec)
score 表没了!12 条成绩记录全部消失。要是没有备份,此刻就该冒冷汗了。
第 3 步:恢复——退出 mysql(exit;),在系统命令行执行:
mysql -u root -p school < school_backup.sql
第 4 步:验证——重新登录 mysql:
USE school;
SHOW TABLES;
SELECT COUNT(*) FROM score;
+------------------+
| Tables_in_school |
+------------------+
| class |
| course |
| score |
| student |
+------------------+
4 rows in set (0.00 sec)
+----------+
| COUNT(*) |
+----------+
| 12 |
+----------+
1 row in set (0.00 sec)
score 表和 12 条成绩全部回来了。这就是备份的意义:闯了祸,还有"读档"的机会。
五、定期备份的思路
备份不该靠"想起来才做",应该让系统定时自动执行。思路简单提一下,感兴趣可以自行深入:
- Windows:用"任务计划程序"(Task Scheduler),设置每天固定时间自动运行一个
.bat脚本,脚本里就是那条 mysqldump 命令(可以在文件名里拼上日期,如school_20260726.sql,方便保留多天的存档)。 - Linux:用
crontab定时任务,例如每天凌晨 2 点执行备份脚本:0 2 * * * /home/backup/backup.sh。
另外两条朴素但重要的建议:
- 备份文件不要和数据库放在同一块磁盘上(磁盘坏了会"一锅端"),最好再同步一份到网盘或另一台机器。
- 定期试着恢复一次。没验证过能恢复的备份,等于薛定谔的备份。
六、图形化工具也能备份
如果你在用 Navicat、MySQL Workbench、DBeaver 等图形化工具,它们都内置了**导出/转储(Export/Dump)和导入(Import)**功能,本质和 mysqldump 一样——生成/执行 SQL 文件,只是换成了点鼠标。在 Workbench 里对应菜单是 Server → Data Export / Data Import。会了命令行原理,图形界面一看就懂。
⚠️ 新手常见坑
- 在
mysql>提示符里执行 mysqldump。这是本节强调多次的头号坑:mysqldump 是操作系统里的程序,必须在 CMD/PowerShell/终端里执行,在 mysql 里执行只会得到ERROR 1064语法错误。 >和<方向搞反。备份是mysqldump ... > 文件(导出),恢复是mysql ... < 文件(导入)。方向反了,轻则报错,重则用空内容覆盖了备份文件。- 提示
'mysqldump' 不是内部或外部命令。说明 MySQL 的 bin 目录没有加入系统 PATH 环境变量。解决办法:把类似C:\Program Files\MySQL\MySQL Server 8.0\bin的路径加入 PATH,或者直接 cd 到该目录下执行。 - 恢复时报错
Unknown database 'school'。mysql -u root -p school < backup.sql要求库已存在。如果整个库被删了,先登录 mysql 执行CREATE DATABASE school;,再做恢复。 - 备份文件从没打开验证过,也从没演练过恢复。备份文件损坏、备份命令其实一直在报错却没人发现——这种事故很常见。定期抽查文件内容、演练恢复流程,备份才真正可靠。
- 备份和原库放在同一块硬盘。磁盘物理损坏时会连备份一起丢。至少复制一份到别的介质或云端。
📝 小结
- 备份是数据的"后悔药":防误删、防硬件故障,没有备份 = 裸奔
mysqldump是逻辑备份工具,产物是一个装满 SQL 语句的.sql文件,必须在系统命令行执行:- 备份单库:
mysqldump -u root -p school > school_backup.sql - 备份单表:
mysqldump -u root -p school student > student_backup.sql - 备份所有库:
mysqldump -u root -p --all-databases > all_backup.sql
- 备份单库:
- 恢复两种方式:
- 系统命令行:
mysql -u root -p school < school_backup.sql - mysql 内:
SOURCE D:/backup/school_backup.sql
- 系统命令行:
- 用任务计划程序(Windows)或 crontab(Linux)实现定期自动备份;备份要异地存放、定期演练恢复
✍️ 练习题
1. 小王在 mysql> 提示符下输入 mysqldump -u root -p school > backup.sql;,得到了 ERROR 1064。请指出他的问题并给出正确做法。
参考答案
mysqldump 是操作系统的命令行程序,不是 SQL 语句,不能在 mysql 提示符里执行。正确做法:先输入 exit; 退出 mysql(或另开一个 CMD/PowerShell 窗口),再执行 mysqldump -u root -p school > backup.sql。
2. 请写出命令:只备份 school 库中的 student 和 score 两张表到文件 stu_score.sql。
参考答案
mysqldump -u root -p school student score > stu_score.sql
(在系统命令行执行,库名在前,表名跟在后面,多个表用空格隔开。)
3. school 整个数据库被误删了(DROP DATABASE school;),手里有备份文件 school_backup.sql。请写出完整的恢复步骤。
参考答案
第一步,登录 mysql 重建空库:
CREATE DATABASE school;
第二步,退出 mysql,在系统命令行导入备份:
mysql -u root -p school < school_backup.sql
(或者登录 mysql 后执行 USE school; 再 SOURCE 备份文件路径。)最后用 SHOW TABLES; 和 SELECT COUNT(*) FROM score; 验证数据是否完整回来。
4. 打开 mysqldump 生成的 .sql 备份文件,里面主要是哪两类 SQL 语句?"恢复"的本质是什么?
参考答案
主要是 CREATE TABLE(重建表结构)和 INSERT(重新插入数据)两类语句(通常每张表前还有一句 DROP TABLE IF EXISTS 用于清掉旧表)。恢复的本质就是把这个 SQL "剧本"从头到尾重新执行一遍,重建出备份时刻的结构和数据。
5. 简答:为什么说"备份文件和数据库放在同一块硬盘上"是危险的?除了异地存放,还有哪条建议能保证备份真正可用?
参考答案
如果同一块硬盘物理损坏,数据库和备份会同时丢失,备份形同虚设,所以备份应存放到另一块磁盘、另一台机器或云端。另一条关键建议:定期演练恢复——实际拿备份文件恢复一次并验证数据,确认备份文件完整可用,避免"到用时才发现备份是坏的"。