mysqldump 单表与条件备份
导学
全库备份耗时久、体积大。日常运维中更常见的需求是:只备份一张表、只备份某个部门的数据、或者只备份某个时间段内的记录。mysqldump 支持库级、表级、甚至行级的精细化备份。
定义
单表备份:只导出指定数据库中的某一张表的结构和数据。条件备份:在单表备份基础上,通过 --where 参数附加 SQL WHERE 条件,只导出满足条件的行。
场景一:单表备份
当前数据状态:company 库的 employees 表。
USE company;
SELECT * FROM employees;
| emp_id | emp_name | dept | score |
|---|---|---|---|
| 1 | 大翔 | 技术部 | 100 |
| 2 | 白歌 | 技术部 | NULL |
操作语句(命令行):
mysqldump -u root -p company employees > employees_backup.sql
验证备份文件内容:
grep -n "DROP TABLE\|CREATE TABLE\|INSERT INTO" employees_backup.sql | head -n 5
预期输出:
1:--
22:DROP TABLE IF EXISTS `employees`;
25:CREATE TABLE `employees` (
35:INSERT INTO `employees` VALUES (1,'大翔','技术部',100.00);
36:INSERT INTO `employees` VALUES (2,'白歌','技术部',NULL);
结果解读:单表备份文件包含 DROP TABLE IF EXISTS、CREATE TABLE 和 INSERT INTO 语句。恢复时会先删除旧表再重建,注意这会丢失恢复前表中的现有数据。
场景二:多表备份
操作语句:
mysqldump -u root -p company employees scores > company_two_tables.sql
验证:
grep "CREATE TABLE" company_two_tables.sql
预期输出包含 employees 和 scores 两张表的 CREATE TABLE 语句。
结果解读:在 --databases 和表名混用时要注意:不加 --databases 时,company employees scores 表示 company 库中的 employees 和 scores 表。如果写成 --databases company employees,则会被理解为备份 company 和 employees 两个数据库。
场景三:条件备份(--where)
当前数据状态:company 库的 employees 表有技术部和产品部员工。
INSERT INTO employees (emp_name, dept, score) VALUES ('孔蓝', '产品部', 88);
SELECT emp_name, dept FROM employees;
| emp_name | dept |
|---|---|
| 大翔 | 技术部 |
| 白歌 | 技术部 |
| 孔蓝 | 产品部 |
操作语句:只备份技术部员工。
mysqldump -u root -p company employees --where "dept = '技术部'" > tech_employees.sql
验证:
grep "INSERT INTO" tech_employees.sql
预期输出:
INSERT INTO `employees` VALUES (1,'大翔','技术部',100.00);
INSERT INTO `employees` VALUES (2,'白歌','技术部',NULL);
结果解读:--where 对单表备份附加 WHERE 条件,只导出满足条件的行。注意:条件备份的文件仍然包含 CREATE TABLE 和 DROP TABLE,恢复时会清空目标表。如果只想追加数据,需要手动编辑文件或改用 SELECT ... INTO OUTFILE。
场景四:按时间范围条件备份
当前数据状态:company 库有 orders 表。
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
amount DECIMAL(10,2),
created_at DATETIME
);
INSERT INTO orders (user_id, amount, created_at) VALUES
(1, 199.00, '2024-01-10 10:00:00'),
(2, 299.00, '2024-01-15 14:30:00'),
(1, 99.00, '2024-02-01 09:00:00');
操作语句:只备份 2024 年 1 月的订单。
mysqldump -u root -p company orders \
--where "created_at >= '2024-01-01' AND created_at < '2024-02-01'" \
> orders_202401.sql
验证:
grep "INSERT INTO" orders_202401.sql
预期只包含 order_id = 1 和 order_id = 2 的两条记录,order_id = 3(2 月)不出现。
结果解读:时间范围条件备份常用于历史数据归档——将过期数据备份到文件后,从生产表删除,减小表体积。
场景五:排除某些表(--ignore-table)
操作语句:备份 company 库,但排除日志表(通常体积大、价值低)。
mysqldump -u root -p --databases company \
--ignore-table=company.access_logs \
--ignore-table=company.operation_logs \
> company_no_logs.sql
验证:
grep "access_logs\|operation_logs" company_no_logs.sql | wc -l
预期输出:0
结果解读:--ignore-table=数据库.表名 可多次使用,排除不需要备份的表。适合跳过临时表、日志表、缓存表等。
常见误区
| 误区 | 正解 |
|---|---|
"--where 可以多表同时用" | 不能。--where 只对紧跟其后的单表生效,多表备份时每个表的条件不同,需分别执行。 |
| "条件备份恢复时不会删除其他数据" | 会。备份文件包含 DROP TABLE + CREATE TABLE,恢复时整表重建。如需追加,应去掉 DROP 和 CREATE,只保留 INSERT。 |
"mysqldump 可以导出为 CSV" | 不是原生支持。用 --tab=/path 可导出为 .txt(TSV 格式),或用 SELECT ... INTO OUTFILE 导出 CSV。 |
面试考点
Q:如何只备份表结构不备份数据?
mysqldump --no-data -u root -p db_name table_name > schema.sql
Q:如何备份时排除某些大表?
mysqldump --databases db_name --ignore-table=db_name.big_table1 --ignore-table=db_name.big_table2 > backup.sql
Q:条件备份的文件能直接恢复吗?
能,但会清空目标表(因为有
DROP TABLE+CREATE TABLE)。如果目标表已有其他数据,需要先编辑 SQL 文件删除DROP和CREATE语句,只执行INSERT。
小结
- 单表备份:
mysqldump db_name table_name > file.sql - 多表备份:
mysqldump db_name table1 table2 > file.sql - 条件备份:
--where "条件",只对单表生效 - 排除表:
--ignore-table=db.table,可多次使用 - 条件备份恢复时注意
DROP TABLE会清空目标表
下一章引子:备份文件生成了,但怎么把它恢复到数据库里?恢复不只是 mysql < file.sql 那么简单。