数据库入门到初级 · 第 22/22 篇。实验口径:MySQL 8.4、InnoDB、utf8mb4。案例:小型商城。
“备份文件在”与“数据能恢复”是两回事。文件可能不完整,导出过程可能失败,恢复时也可能缺权限或遇到版本差异。系列最后一篇把备份、恢复和业务核对连起来,让前面学过的知识形成闭环。
1. 本篇备份的范围
mysqldump 是逻辑备份工具,会把表结构与数据写成可执行的 SQL。本例备份 shop_lab,不包含整个服务器的用户、权限配置等内容。教程没有存储过程与事件;真实系统需要根据范围决定是否增加相应选项。
以下命令针对 MySQL 8.4 的练习实例。在电脑已经安装 mysql 与 mysqldump 客户端时,可直接运行。主机和端口按你的环境修改,本系列 Docker 映射端口为 3307。
2. 导出备份文件
在电脑终端执行,而不是在 mysql> 中执行:
mysqldump -h 127.0.0.1 -P 3307 -u root -p --default-character-set=utf8mb4 --single-transaction --no-tablespaces --set-gtid-purged=OFF --result-file=shop-lab-backup.sql shop_lab
--result-file 让工具直接写文件,也避免不同终端重定向编码方式带来的额外问题。确认命令成功结束,再检查文件大小、时间和内容;不要只看文件已经出现。
若只使用 Docker 容器内工具,可改用:
docker exec -it shop-mysql mysqldump -u root -p --default-character-set=utf8mb4 --single-transaction --no-tablespaces --set-gtid-purged=OFF --result-file=/tmp/shop-lab-backup.sql shop_lab
docker cp shop-mysql:/tmp/shop-lab-backup.sql ./shop-lab-backup.sql
本机备份与容器备份两条路线任选一种。这里 --set-gtid-purged=OFF 是方便在练习库恢复,不应直接套用到复制集群或需要 GTID 连续性的生产恢复方案。
--single-transaction 适合获得 InnoDB 表的一致性数据视图;它不使所有存储引擎都具备相同保证。导出期间避免建表、改表、删表等结构变更。具体权限与限制见 mysqldump 官方文档。

3. 恢复到一个新库
使用具有建库权限的练习账号连接 MySQL。下面使用新名字 shop_lab_restore,若该名字已存在,请先换一个未使用的名字,而不是直接覆盖。
CREATE DATABASE shop_lab_restore
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
USE shop_lab_restore;
SOURCE C:/你的目录/shop-lab-backup.sql;
把路径换为实际绝对路径;Linux/macOS 使用相应路径。如果文件仍在 Docker 容器的 /tmp,进入容器 mysql 客户端后执行 SOURCE /tmp/shop-lab-backup.sql; 即可。
注意导出命令没有使用 --databases,所以这里可以先选中独立库再恢复。若备份本身包含 CREATE DATABASE 或 USE,它可能切换目标库;恢复任何来源的 SQL 前都要先检查内容。
4. 三层核对,而不是只看“执行完成”
先检查对象和行数:
USE shop_lab_restore;
SHOW TABLES;
SELECT 'users' AS table_name, COUNT(*) AS n FROM users
UNION ALL SELECT 'products', COUNT(*) FROM products
UNION ALL SELECT 'orders', COUNT(*) FROM orders
UNION ALL SELECT 'order_items', COUNT(*) FROM order_items;
如果备份前一直保持原始样例,核心表行数应为 3、5、4、5。做过提交型练习时,应与备份时的源库比较,不能机械要求相同的初始数字。其他章节创建的演示表也会被一并备份。
再检查业务金额:
SELECT status, COUNT(*) AS n, SUM(total_amount) AS amount
FROM orders GROUP BY status ORDER BY status;
SELECT o.id, o.total_amount,
COALESCE(SUM(i.unit_price * i.quantity), 0) AS detail_amount
FROM orders AS o
LEFT JOIN order_items AS i ON i.order_id = o.id
GROUP BY o.id, o.total_amount
HAVING COUNT(i.id) = 0
OR o.total_amount <> COALESCE(SUM(i.unit_price * i.quantity), 0);
原始数据中,第二条查询应返回 0 行:既没有无明细订单,也没有金额不一致。最后使用 SHOW CREATE TABLE 检查约束,并验证几个关键查询和应用读取流程。
5. 综合练习:交付一个最小商城数据库
完成四张表和样例数据;查询所有可售且有库存商品;展示全部用户的已支付消费金额;在事务中创建订单并预留库存;模拟库存不足或非法用户,确认整体回滚;为用户订单列表评估索引;最后导出并恢复到独立库。
验收时不要只说“没有报错”。应写清预期结果:小林原始已支付金额 417 元;小周和小陈为 0;并发争抢库存时只有符合条件的一次扣减成功;恢复库的行数和金额与备份时源库相符。
6. 备份策略还要回答哪些问题
真实系统要约定备份频率、保留周期、存放位置、访问权限和恢复演练。恢复点目标 RPO 描述能接受损失多长时间的数据;恢复时间目标 RTO 描述能接受多久恢复服务。
每天一次的备份,不代表能找回两次备份之间的所有修改。时间点恢复、二进制日志、物理备份、主从与高可用属于后续学习内容;复制副本也不能简单替代备份,因为误删可能同步过去。
练习与答案
练习:备份文件存在,但恢复报错,能说备份成功吗? 不能确认它满足恢复目标。必须调查错误、验证可恢复性,并保留导出和演练结果。
练习:为什么要恢复到独立库? 它让你在不覆盖源数据的情况下检查文件、结构和业务结果,也便于为第 21 篇的应用实验准备副本。
完成这个项目后,你已经具备初级数据库实践的基本链条:设计、查询、事务、并发、索引,以及可验证的备份恢复。