MySQL数据恢复实践:binlog2sql数据追加

实验环境 : 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 = ONbinlog_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 文件。

"""

相关推荐
嵌入式-老费1 小时前
esp32开发与应用(看门狗测试)
java·开发语言·数据库
czhc11400756631 小时前
615:代码细节
数据库
炘爚1 小时前
Linux——MySQL
linux·mysql
知识分享小能手1 小时前
Hadoop学习教程,从入门到精通, HBase 分布式数据库 — 完整知识点与案例代码(8)
数据库·hadoop·分布式
吴声子夜歌1 小时前
SQL经典实例——处理数字
java·数据库·sql
NineData1 小时前
日常巡检 Oracle 时,ChatDBA 怎么把会话、SQL 和等待事件一起看
数据库·sql·oracle·ninedata·故障排查·chatdba·实例巡检
海天一色y1 小时前
深入理解 RAG 技术:从语义张量到向量数据库,Milvus 与 FAISS 全面对比
数据库·milvus·faiss
爱吃羊的老虎1 小时前
【数据库】模块二:SQL 语句、高级特性与优化
数据库·oracle
Rain5091 小时前
2.4. PostgreSQL 数据库连接与实战指南
前端·数据库·人工智能·后端·postgresql·数据分析