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 文件。

"""

相关推荐
运维行者_15 小时前
企业无线网络监控的挑战与智能化演进趋势
大数据·运维·服务器·网络·数据库
国强_dev16 小时前
技术探讨:使用 stunnel 加密转发数据库连接时,如何获取客户端真实 IP?
数据库·网络协议·tcp/ip
@insist12316 小时前
系统规划与管理师-信息系统规划核心工作要点解析
数据库·软考·系统规划与管理师·软件水平考试·系统规划与管理工程师
超级数据查看器16 小时前
超级数据查看器 v10.0 发布
java·大数据·数据库·sqlite·安卓
数安3000天17 小时前
增量数据如何自动分类分级,避免目录“过期“?
大数据·数据库
南墙上的石头18 小时前
麒麟 V10 重装人大金仓 V8R6 踩坑实录(含 MySQL 兼容模式)
数据库·mysql
画中有画19 小时前
论向量数据库在项目中的应用
数据库
spider_xcxc19 小时前
Redis 数据库高质量实践指南(一)
运维·数据库·redis·oracle·云计算
l1t20 小时前
在linux和windows中解决duckdb 1.6dev版本输出执行计划报错问题
linux·运维·数据库·windows·duckdb
执子手 吹散苍茫茫烟波20 小时前
RC 隔离级别下 MySQL InnoDB 死锁典型案例
数据库·mysql