实验环境 : MySQL 5.7.27
适用场景 : InnoDB表空间文件(.ibd)丢失,需基于历史备份与二进制日志(binlog)进行数据恢复
技术路线: IMPORT TABLESPACE恢复基础数据 → binlog2sql解析并追加增量数据
一、故障场景还原
1.1 问题模拟
mysql表的表空间文件ibd被移除后恢复数据,仅留有表结构定义(.frm):
sql
ALTER TABLE t_binlog_test DISCARD TABLESPACE;
操作后果 :该表对应的 .ibd 文件从数据目录中移除,表变为仅含元数据的空壳结构,无法执行任何数据读写操作。
二、前置条件与环境确认
方案 :采用历史备份的 .ibd 文件通过 IMPORT TABLESPACE 恢复基础数据,再通过 binlog2sql 解析并回放 binlog 中的增量数据。
2.1 必备条件清单
- 目标表存在历史
.ibd文件备份 - MySQL 实例已开启
binlog功能 -
binlog_format设置为ROW模式(解析 DML 语句的必要条件) - 表结构定义未被破坏(
DISCARD TABLESPACE仅移除数据文件)
2.2 环境参数确认
sql
-- 确认 binlog 功能状态
SHOW VARIABLES LIKE 'log_bin';
-- 确认 binlog 记录格式
SHOW VARIABLES LIKE 'binlog_format';
-- 确认 binlog 文件基础路径
SHOW VARIABLES LIKE 'log_bin_basename';
-- 确认当前 binlog 记录的数据库范围
SHOW MASTER STATUS;
-- 检查 Binlog_Do_DB 字段值
预期输出要求 :
log_bin = ON,binlog_format = ROW。
三、实验环境构建
3.1 确认数据目录路径
sql
SHOW VARIABLES LIKE 'datadir';
预期输出示例:
/u01/my3306/data/test_ibd
3.2 创建测试数据库与表
sql
-- 确认当前数据库列表
SHOW DATABASES;
-- 创建测试数据库
CREATE DATABASE IF NOT EXISTS test_ibd;
USE test_ibd;
-- 创建测试表
CREATE TABLE t_binlog_test (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
3.3 初始化数据并模拟备份
sql
-- 插入第一条测试数据
INSERT INTO t_binlog_test() VALUES();
-- 确认数据写入成功
SELECT * FROM t_binlog_test;

模拟备份表空间文件:
bash
[root@mysql01 test_ibd]# cp t_binlog_test.* /home/mysql/bak/
3.4 模拟增量数据写入
sql
-- 模拟备份后的增量数据写入
INSERT INTO t_binlog_test() VALUES();
3.5 模拟表空间文件丢失
bash
[root@mysql01 test_ibd]# mv t_binlog_test.ibd /tmp
故障现象:MySQL 服务重启后查询该表将触发以下错误:
ERROR 1812 (HY000): Tablespace is missing for table `test_ibd`.`t_binlog_test`.
四、恢复阶段一:导入历史表空间
4.1 还原历史表空间文件
将备份的 .ibd 文件还原至数据目录,并修正文件系统权限:
bash
[root@mysql01 test_ibd]# cp /home/mysql/bak/t_binlog_test.ibd /u01/my3306/data/test_ibd
[root@mysql01 test_ibd]# chown mysql:mysql t_binlog_test.ibd
权限要求 :文件属主需为
mysql:mysql。
4.2 执行表空间导入
sql
-- 导入历史备份的表空间文件
ALTER TABLE test_ibd.t_binlog_test IMPORT TABLESPACE;
导入完成后须立即执行锁表操作,防止新数据写入导致与后续 binlog 追加产生冲突。
4.3 锁定目标表
sql
-- 导入后立即对目标表加写锁,阻断所有数据变更
LOCK TABLES test_ibd.t_binlog_test WRITE;
4.4 验证基础数据恢复情况
sql
-- 核对历史备份时间点的数据量,确认基础数据已恢复
SELECT * FROM test_ibd.t_binlog_test;
关键提示:须保留当前锁表会话窗口处于活动状态,锁表期间禁止其他会话对该表执行任何操作,直至 binlog 增量数据追加完成。
五、恢复阶段二:binlog 增量数据追加
5.1 binlog2sql 工具部署
验证工具安装状态:
需自行利用python2.7版本进行安装binlog2sql
bash
[root@mysql01 binlog2sql]# python2.7 binlog2sql/binlog2sql.py --help

5.2 解析参数确认
执行解析前须明确以下关键参数:
| 参数 | 说明 | 获取方式 |
|---|---|---|
--start-file |
起始 binlog 文件 | 首个 binlog 文件 |
--stop-file |
结束 binlog 文件 | 查询的最后一个 binlog 文件 |
--start-datetime |
解析起始时间 | 历史备份完成的精确时间点 |
--stop-datetime |
解析结束时间 | 插入的最后时间点 |
时间参数示例:
- 起始时间(备份完成时间):
2026-06-15 21:33:00 - 结束时间(故障发生时间):
2026-06-15 22:07:00
时间格式要求:%Y-%m-%d %H:%M:%S。
5.3 执行 binlog2sql 解析
数据库权限要求:执行解析的数据库用户须具备以下权限:
sql
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'root'@'localhost';
FLUSH PRIVILEGES;
解析命令:
bash
/usr/local/python2.7.9/bin/python2.7 /soft/binlog2sql-offline/binlog2sql/binlog2sql/binlog2sql.py \
-h127.0.0.1 -P3306 -uroot -p'mysql' \
-d test_ibd -t t_binlog_test \
--start-file=master-bin.000007 \
--stop-file=master-bin.000010 \
--start-datetime="2026-06-15 21:33:00" \
--stop-datetime="2026-06-15 23:19:00" \
--only-dml \
--sql-type INSERT UPDATE DELETE \
> /tmp/t_binlog_test.sql
参数说明:
| 参数 | 作用描述 |
|---|---|
-h / -P / -u / -p |
目标数据库连接信息 |
-d / -t |
指定目标数据库及数据表 |
--start-file / --stop-file |
限定 binlog 文件解析范围 |
--start-datetime / --stop-datetime |
基于时间戳精确筛选解析区间 |
--only-dml |
仅输出 DML 语句(INSERT / UPDATE / DELETE) |
--sql-type |
限定输出的 SQL 语句类型 |
5.4 回放增量数据
在持有表锁的 MySQL 会话窗口中执行以下操作(执行前确认会话不会因超时断开):
sql
-- 确认当前连接字符集
SHOW VARIABLES LIKE 'character_set%';
-- 若字符集不匹配,设置
SET NAMES utf8mb4;
-- 执行增量数据插入
SOURCE /tmp/t_binlog_test.sql;

5.5 数据验证与解锁
sql
-- 验证最终数据总量
SELECT COUNT(*) FROM t_binlog_test;
-- 数据一致性验证通过后释放表锁
UNLOCK TABLES;
六、常见问题与注意事项
6.1 binlog2sql 解析异常处理
| 异常现象 | 根因分析与解决方案 |
|---|---|
| 解析结果包含大量无关表的数据 | 核对 -d(数据库)和 -t(表名)参数是否准确 |
| 指定时间范围内无输出 | 检查 --start-datetime 是否早于实际备份完成时间点 |
6.2 锁表期间的运维约束
- 持有锁表的会话不可断开或超时,否则锁将自动释放,可能导致数据不一致;
- 建议在生产环境执行前,先在测试环境中完整验证解析生成的 SQL 文件。
"""