MySQL数据库导出与隔离恢复教程
适用环境:MySQL 8.0/8.4 的业务库逻辑备份,示例在 Linux Bash 中执行。MariaDB、复制拓扑、全实例灾备和时间点恢复不直接套用本示例。
本教程备份一个业务数据库,不是复制运行中的 MySQL 数据目录。操作前准备有必要导出权限的账号、数据库名称、存储空间,以及与生产隔离的恢复实例。密码通过 -p 提示输入,不直接写在命令里。分段命令使用同一个Bash会话;若重连,先按记录重新设置 dump_dir 等变量,不使用空路径继续恢复。
先确认事务与版本条件
mysqldump --version
mysql -h 127.0.0.1 -P 3306 -u app_backup -p -e "SELECT @@version, @@version_comment, @@gtid_mode;"
mysql -h 127.0.0.1 -P 3306 -u app_backup -p -e "SELECT ENGINE,COUNT(*) FROM information_schema.tables WHERE table_schema='example_app' GROUP BY ENGINE;"
将 app_backup、example_app、地址和端口替换为实际值。--single-transaction 依赖事务引擎的一致性快照,不能让 MyISAM 等非事务表自动一致;导出过程中也不要执行 ALTER、DROP、RENAME、TRUNCATE 等结构变更。存在混合引擎或文件与数据库需要同一时间点时,应安排应用维护窗口,并选择匹配的备份方案。
导出到独立文件,并保留错误日志
umask 077
dump_dir=$(mktemp -d /var/tmp/baole-mysql.XXXXXXXX)
mysqldump -h 127.0.0.1 -P 3306 -u app_backup -p \
--single-transaction --quick --no-tablespaces \
--routines --events --triggers --set-gtid-purged=OFF \
--result-file="$dump_dir/example_app.sql" example_app \
2> "$dump_dir/dump.err"
dump_status=$?
printf 'mysqldump exit=%s\n' "$dump_status"
wc -c "$dump_dir/example_app.sql"
cat "$dump_dir/dump.err"
退出码为 0 且没有未处理错误后,才能把本次导出记为完成。空文件、权限错误、连接中断或磁盘写入失败都不合格。--routines 和 --events 会增加相关对象及权限要求;若确实没有这些对象,也要在备份清单里记录,不应为消除报错直接删掉参数而遗漏业务逻辑。本例关闭导出中的 GTID_PURGED 设置,不用它建立复制关系。
使用 --result-file 可避免某些 Windows PowerShell 重定向编码差异;Windows 用户仍需使用本机真实可写路径。SQL 文件包含业务数据,应限制访问。导出后记录服务器版本、字符集、时间、文件大小、校验值和对象范围。
只在独立测试实例中导入
测试实例应与生产分开,关闭业务定时事件和外部支付、通知等调用,准备同版本或已验证兼容的 MySQL。SQL 可能含视图、例程、触发器和原账号 DEFINER,单纯换一个数据库名不等于完成隔离。不要把未知来源 SQL 导入正式数据库。
restore_host=203.0.113.20
mysql -h "$restore_host" -P 3306 -u restore_admin -p -e "SELECT @@hostname, @@port, @@version;"
203.0.113.20 是文档示例地址,必须改成真实隔离测试机地址。先人工确认上面的主机、端口和版本输出无误,确认导出文件已成功完成,再执行下面的写入步骤。字符集和排序规则应按源库记录设置;测试库名称必须尚不存在。
if mysql -h "$restore_host" -P 3306 -u restore_admin -p \
-e "CREATE DATABASE baole_restore_check CHARACTER SET utf8mb4;"; then
mysql -h "$restore_host" -P 3306 -u restore_admin -p baole_restore_check \
< "$dump_dir/example_app.sql"
restore_status=$?
printf 'mysql restore exit=%s\n' "$restore_status"
test "$restore_status" -eq 0
else
printf '%s\n' '新测试库创建失败,未执行导入。保留现场,检查错误或换一个新的演练库名。' >&2
false
fi
只有创建新库成功的分支才会导入。库已存在、没有建库权限或连接失败都会跳过导入;不要删除这个分支,也不要改成 CREATE DATABASE IF NOT EXISTS。导入失败后先保留日志,在另一个全新测试库重做,不添加 --force 绕过错误。
验证到业务数据这一层
- 查看表、视图、例程和触发器是否齐全;处理缺少 DEFINER、权限或不兼容语法的错误。
- 对关键业务表比较记录数量、最近数据时间和几条已知记录;不要只看“导入已结束”。
- 让隔离应用连接测试库,检查登录、读取、附件关联等核心功能,并记录恢复耗时。
- 保留原导出文件及日志,再将备份复制到服务器之外。逻辑导出恢复较大的库可能耗时很长,应在维护计划中预留实测时间。