1737 字
9 分钟
MySQL逻辑备份与恢复指南:mysqldump与source全解析

备份恢复是DBA与运维工程师的底层基本功。相比于物理备份(如XtraBackup),逻辑备份工具 mysqldump 以其极高的兼容性和灵活度稳居日常运维C位。本文将从底层原理到高阶命令,带你一次性吃透 mysqldump 逻辑备份与 source 恢复的生产级最佳实践。

[!NOTE] 逻辑备份的本质 mysqldump 的核心机制是将数据库的结构(Schema)和数据(Data),逆向解析并转换为一条条标准的 SQL 语句(CREATE、INSERT 等),最终写入纯文本文件中。 优势:文本高度可读、支持跨大版本/跨平台迁移、可精准到单表甚至单行备份。 劣势:备份和恢复速度受限于SQL解析引擎,TB级大库导入耗时较长(针对超大库建议参考物理备份方案或使用多线程工具如 ::github{repo="mydumper/mydumper"})。


1. 生产级备份命令与核心原理解析#

1.1 基础备份场景速查#

TIP参数解析

使用 --databases 时,SQL文件会自带 CREATE DATABASE 和 USE 语句;如果不加此参数备份单库的多表,恢复时必须手动指定目标库。 ::

Terminal
# 1. 备份整个实例(包含 mysql 系统库及用户权限)
mysqldump -u root -p --all-databases > /backup/all_$(date +%F).sql
# 2. 备份单个/多个指定库
mysqldump -u root -p --databases mydb1 mydb2 > /backup/dbs.sql
# 3. 备份单个库中的指定表(不带建库语句)
mysqldump -u root -p mydb table1 table2 > /backup/tables.sql

1.2 生产环境“黄金标准”参数(InnoDB不锁表)#

在生产环境中直接全备极易引发锁表事故,必须组合使用以下参数保证业务的连续性:

Terminal
mysqldump -u root -p \
--single-transaction \
--routines \
--triggers \
--events \
--hex-blob \
--default-character-set=utf8mb4 \
--set-gtid-purged=OFF \
mydb > mydb.sql
IMPORTANT核心参数底层逻辑
  • --single-transaction:绝对核心。基于InnoDB的MVCC(多版本并发控制)机制,在备份开始前执行 START TRANSACTION WITH CONSISTENT SNAPSHOT 获取一致性视图。导出期间完全不阻塞业务侧的 INSERT/UPDATE/DELETE。
  • --routines / --triggers / --events:确保存储过程、触发器、定时任务一并导出,防止业务逻辑残缺。
  • --hex-blob:将 BINARY, VARBINARY, BLOB 等二进制字段转换为十六进制字符串,彻底杜绝特殊字符导致的乱码或转义截断问题。
  • --set-gtid-purged=OFF:在开启GTID的集群中,如果仅为了备份部分数据而非搭建从库,必须关闭GTID导出,否则导入时会报 GTID_PURGED 冲突错误。 ::

1.3 高级过滤:只导结构、只导数据、按条件导出#

Terminal
# 仅备份表结构(不要数据,常用于环境初始化)
mysqldump -u root -p --no-data mydb > schema_only.sql
# 仅备份数据(不要建表语句,常用于数据追加)
mysqldump -u root -p --no-create-info mydb > data_only.sql
# 按 WHERE 条件精准备份(例如只备份最近7天的数据)
mysqldump -u root -p mydb my_table --where="create_time > DATE_SUB(NOW(), INTERVAL 7 DAY)" > latest_data.sql

2. 企业级安全与全自动化备份#

在脚本中直接明文暴露 :spoiler[root:MySecretPwd123!] 是极度危险的。推荐使用 mysql_config_editor 或 .my.cnf 实现免密安全备份。

2.1 配置免密凭证#

~/.my.cnf
[mysqldump]
user=backup_user
password=YourSecurePassword
host=127.0.0.01

设置严格权限:chmod 600 ~/.my.cnf。

2.2 编写自动化轮转备份脚本#

mysql_auto_backup.sh
#!/bin/bash
# MySQL全自动化备份脚本,保留7天
BACKUP_DIR="/data/backup/mysql"
DATE=$(date +%Y%m%d_%H%M)
RETENTION_DAYS=7
mkdir -p $BACKUP_DIR
echo "[$(date)] 开始执行全库逻辑备份..."
13 collapsed lines
# 使用管道直接压缩,极大节省磁盘IO与空间
mysqldump --defaults-extra-file=~/.my.cnf \
--single-transaction \
--routines --triggers --events \
--all-databases | gzip > ${BACKUP_DIR}/full_backup_${DATE}.sql.gz
if [ $? -eq 0 ]; then
echo "[$(date)] 备份成功:full_backup_${DATE}.sql.gz"
else
echo "[$(date)] 备份失败!请检查错误日志。"
exit 1
fi
# 清理过期备份
find $BACKUP_DIR -name "full_backup_*.sql.gz" -type f -mtime +$RETENTION_DAYS -exec rm -f {} \;
echo "[$(date)] 历史备份清理完成。"

3. 数据恢复的两种核心方式#

3.1 Shell 管道重定向(无人值守/大文件首选)#

利用系统底层的管道符直接将数据灌入 MySQL,效率高,适合静默执行。

Terminal
# 常规 SQL 文件导入
mysql -u root -p mydb < /backup/mydb.sql
# 压缩包流式导入(无需提前解压,节省磁盘空间)
zcat /backup/mydb.sql.gz | mysql -u root -p mydb

3.2 交互式 source 命令(调试/排错首选)#

登录 MySQL 终端后执行,优势在于能实时观测到执行过程中的 Warning 和 Error,适合复杂依赖的建库脚本。

MySQL-Console
-- 1. 如果备份包内无 CREATE DATABASE 语句,需手动创建并指定字符集
CREATE DATABASE IF NOT EXISTS mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE mydb;
-- 2. 临时关闭 Binlog(极其重要!防止恢复过程产生海量日志或同步到从库)
SET SESSION sql_log_bin = 0;
-- 3. 加载 SQL 文件(Windows环境也强烈建议使用正斜杠 '/')
source /backup/mydb.sql;

4. 运维修炼:从百GB全备中提取单表#

[!WARNING] 灾难场景 某开发误删了 user_logs 表的数据,但你手头只有整个实例几百 GB 的 all_databases.sql 全备文件。重新导入整个实例需要数小时,如何在一分钟内仅恢复这张表?

利用 sed 命令的文本流截取功能,可以精准提取目标表的建表和插入语句:

Terminal
# 提取 user_logs 表的结构和数据到单文件
sed -e '/./{H;$!d;}' -e 'x;/CREATE TABLE `user_logs`/!d;q' /backup/all_databases.sql > extract_struct.sql
sed -n -e '/INSERT INTO `user_logs`/,/UNLOCK TABLES/p' /backup/all_databases.sql > extract_data.sql
# 合并后直接导入
cat extract_struct.sql extract_data.sql | mysql -u root -p mydb

5. 极限优化:超大 SQL 文件极速恢复方案#

当导入几十 GB 的 SQL 文件时,默认配置可能会让你等上几天几夜。通过临时调整以下 InnoDB 参数,可将恢复速度提升 300% ~ 500%。

5.1 数据库参数临时调优#

在导入前,进入 MySQL 执行以下配置:

MySQL-Console
-- 临时扩大允许接收的最大数据包,防止长 INSERT 报错
SET GLOBAL max_allowed_packet = 1073741824; -- 1GB
-- 关闭双1验证,将磁盘刷写频率降到最低(极大降低IO等待)
SET GLOBAL innodb_flush_log_at_trx_commit = 2;
SET GLOBAL sync_binlog = 0;
-- 禁用唯一性检查和外键检查(提速神器)
SET unique_checks = 0;
SET foreign_key_checks = 0;
CAUTION安全警告

数据导入完成后,必须将 innodb_flush_log_at_trx_commit 和 sync_binlog 恢复为 1,并开启外键和唯一性检查,否则一旦服务器宕机将面临数据丢失风险。 ::

5.2 进度可视化监控#

面对大文件,盲目等待是运维大忌。组合使用 pv (Pipe Viewer) 工具可以实时掌握导入进度与带宽:

Terminal
# 安装 pv (CentOS: yum install pv / Ubuntu: apt install pv)
pv /backup/huge_dump.sql | mysql -u root -p mydb
# 压缩包边解压边监控边导入
gunzip -c /backup/huge_dump.sql.gz | pv | mysql -u root -p mydb

输出效果示例: 2.54GiB 0:12:34 [3.45MiB/s] [===> ] 24% ETA 0:38:12


定期做恢复演练,把备份文件导入到测试环境,验证数据的完整性和可用性——这是不仅是运维铁律,更是保住饭碗的最后防线。掌握上述底层原理与性能调优手段,日常 99% 的 MySQL 逻辑备份恢复场景你都能游刃有余。

MySQL逻辑备份与恢复指南:mysqldump与source全解析
https://www.6ixblog.site/posts/linux-basic-13-3/
作者
Licwic
发布于
2025-04-25
许可协议
CC BY-NC-SA 4.0