首页
学习
活动
专区
圈层
工具
发布
50 篇文章
1
Vibe Coding这一年:从“代码苦力”到“超级个体”,我如何把3天的工作压缩进2小时?
2
小程序项目架构设计与基础页面搭建(基础)
3
微信小程序送补贴!手把手教你薅免费云开发资源+混元Token(附使用教程)
4
如何创建一个有效的阅读清单?
5
踩坑记:Elasticsearch 索引写不进去了?可能是触碰了这个隐藏限制
6
RoLID-11K:面向小目标检测的行车记录仪路边垃圾数据集
7
mysql报错通用排查方法 排查MY-001312 can't return a result set in the given context
8
安装并使用谷歌AI编程工具Antigravity(亲测有效)
9
解密Prompt系列68. 告别逐词蹦字 - Transformer 的新推理范式
10
技术人的人生战略:在代码与成长中寻找平衡
11
JavaScript 文件分析与漏洞挖掘指南
12
多 Agent 视角下的自动驾驶系统设计:车端 Agent 与 RSU Agent 协同机制解析
13
构建AI智能体:潜藏秩序的发现:隐因子视角下的SVD推荐知识提取与机理阐释
14
告别浏览器!用Rust打造一键JSON处理神器
15
仅需1元,基于 LangChain 和腾讯混元大模型,实现知识图谱
16
轻量高效!用Docker运行Gogs,搭建属于你的私有GitHub
17
构建AI智能体:SVD知识整理与降维:从数据混沌到语义秩序的智能转换
18
2025年CodeBuddy是如何拯救职场危机中的我?
19
轻量化知识库方案:Docker部署Dokuwiki 的最佳实践
20
踩坑实录:别被 extended_bounds 骗了!ES 直方图聚合的边界陷阱
21
步履不停,共鸣常在:我的 2025 技术旅程与回响
22
构建AI智能体:从SVD的理论到LoRA的实践:大模型低秩微调的内在逻辑
23
[MYSQL] 恢复被drop/truncate的表
24
Sugo Protector 代码保护效果分析报告
25
前端平台大仓应用稳定性治理之路|得物技术
26
C++的5种高级初始化技术:从reserve到piecewise_construct等
27
HierLight-YOLO:面向无人机航拍的层次化轻量目标检测网络
28
金融服务领域的智能体革命:AI智能体解决方案、产业分析与技术实施的战略分析
29
大模型提示词-新手篇
30
2025,一个普通开发者的社区成长地图
31
“氛围编程”正让创意本身成为最终技能
32
AD域攻防权威指南:九.利用备份组获取域Hash
33
【跟着AI学】H5射击游戏开发实录:射击游戏
34
这一年,熬过许过夜,也有些许收获 | 2025年终总结
35
2025,一个技术徘徊者的AI工具真实答卷
36
告别手撸架构图!AI+Ooder实现漂亮架构+动态交互+全栈可视化实战指南
37
GitHub 霸榜:让你的 Claude 拥有“设计总监”级的品味,只要一行命令
38
构建AI智能体:AI古典文学:基于LoRA微调本地大模型打造唐诗生成器
39
拥抱人机共生,锻造不可替代的“金头脑”
40
[MYSQL] 5.7能否从ibdata1中提取出表DDL
41
Spring Boot 实战:手把手教你实现腾讯云 COS 对象存储文件上传
42
解密Prompt系列67. 智能体的经济学:从架构选型到工具预算
43
Google OCS光路解耦揭秘:寒武纪大爆发,从供应链双轨到CPO百万卡全光计算织物
44
未来已来 | 写给 .NET 开发者的 2025 年度总结
45
MYSQL实战:深入理解内存临时表优化
46
Ooder框架规范执行计划:企业级AI实施流程与大模型协作指南
47
openGauss 核心体系架构深度解析
48
架构视角:Jackson3新特性
49
LLM架构机制管窥:作为黑板的上下文窗口
50
LiveKit Agents 深度技术架构剖析
清单首页123文章详情

[MYSQL] 恢复被drop/truncate的表

导读

ibd2sql v2.2版本新增了恢复drop和truncate的表的功能. 这么叼? 我来瞅瞅呢

原理

虽然之前讲过原理, 但还是来简单回顾回顾:

DROP TABLE是delete和insert系统表, 那么被删表之前的元数据信息就能找到, 虽然数据文件没了,但磁盘不会马上覆盖, 我们就能拿着元数据信息去磁盘找相关的PAGE.

TRUNCATE TABLE 是对系统表做的update,看不到被删表之前的元数据信息了; 5.7之前和现在元数据信息一样, 无所谓, 8.0的话就只能使用排除法了, 即排除有主的page,剩下的再一个个试.

可能有很多小伙伴关心: 怎么判断是需要的page呢?

从磁盘读N个块,然后判断是否是page,是否是index page,是否页校验通过... 大概如下:

现在来看看ibd2sql该怎么使用才能恢复数据

流程就是上面的从系统表提取元数据信息, 然后再扫描磁盘匹配即可. 当然每一步都是可以拆开的.

看着头都大了. 我们直接实践吧.

5.7的元数据文件是ibdata1, 8.0是mysql.ibd, 请自己根据自己的版本做替换, 演示例子可能会交换着来.

恢复被drop的表

实际使用可能需要考虑很多情况, 我这里简单列出一些场景.

这里使用的是5.7的环境; 如果是你是mysql 8.0环境, 请将 ibdata1换成mysql.ibd 其它不变场景1: 直接恢复

不小心drop了一张表, 啥也不管,直接干.

代码语言:sql
复制
-- 查看表数据,方便验证 
select * from t20260108_101;
-- 直接drop
drop table t20260108_101;

然后我们扫描磁盘恢复被删除的数据:

代码语言:shell
复制
python3 main.py /data/mysql_5744/mysqldata/ibdata1 --scan /dev/vdb --sql

是不是嘎嘎简单?

场景2 存在多张表被drop的时候

实际中, 可能有多张表被删除, 我们需要先筛选一番

代码语言:shell
复制
python3 main.py /data/mysql_5744/mysqldata/ibdata1 --scan  --ddl

这里有2张表, 我们可以使用--set table来指定需要的表, 并且我们不要直接输出sql, 先输出为page (不要--sql就是输出page形式,也就是二进制文件)

代码语言:shell
复制
python3 main.py /data/mysql_5744/mysqldata/ibdata1 --scan /dev/vdb --set table=t20260108_101

然后我们再扫描上面获取的目录

代码语言:shell
复制
python3 main.py /data/mysql_5744/mysqldata/ibdata1 --scan ./ibd2sql_auto_dir_20260108_155924 --sql

场景3 全都要

磁盘下所有的index page我全都要, 主要是怕万一被覆盖了.

代码语言:shell
复制
python3 main.py --scan /dev/vdb --set indexid=0,all --parallel 8

然后再自己去找需要的page并解析. 比如我要解析ibd2sql_auto_dir_20260108_160541/index/0_0000000037_0000000000000058.page则可以使用

代码语言:shell
复制
python3 main.py ibd2sql_auto_dir_20260108_160541/index/0_0000000037_0000000000000058.page --sdi /data2/db1/t20260108_101.ibd --set leafno=0 --set rootno=0 --force --sql

5.7的ibdata1中能得到的元数据信息不多, 所以需要提供相关的表结构元数据信息, 然后使用--sdi指定即可.

恢复被truncate的表

mysql 5.7恢复被truncate的表

truncate相当于drop+create, drop的数据很快会被重写, 所以我们整个大点的表.

然后我们找下相关表的tableid值为62

再根据tableid去找indexid,值为62(这里和table_id巧合的重合了...)

然后我们扫描indexid=62的page

代码语言:shell
复制
python3 main.py --scan /dev/vdb --set indexid=62

最后我们指定sdi/frm信息去解析对于的页即可.

代码语言:shell
复制
python3 main.py ./ibd2sql_auto_dir_20260108_162317/index/0_0000000041_0000000000000062.page  --sdi /data/mysql_5744/mysqldata/db1/t20260108_105.frm --set leafno=0 --set rootno=0 --force --sql --limit 1

419W的数据量,恢复了411W 还行.

8.0 恢复被truncate的表

8.0的就有难度了, 因为truncate的表是update的系统表, 看不到truncate之前的indexid了, 而且测试发现truncate前后表的indexid是变化的, 也就是无法根据indexid直接去找了.

但也不是完全没办法:

  1. 扫描所有的page,
  2. 排除当前已使用的indexid,
  3. 从剩下得到page里面一个个试.

先准备环境, 这次就200W数据吧.

扫描所有page

代码语言:shell
复制
python3 main.py --scan /dev/vdc --set indexid=0,all

然后我们排除下已有的Indexid

可以简单使用shell筛选下:

代码语言:shell
复制
ls ./ibd2sql_auto_dir_20260108_163711/index/ | awk -F '_' '{print $NF}' | awk -F '.' '{print $1}' | sort > /tmp/t20250108_01.txt
python3 main.py /data2/mysql.ibd --set table=indexes --sql --delete with  | grep PRIMARY | awk -F ',' '{printf "%016d\n",$2}' | sort > /tmp/t20250108_02.txt
diff /tmp/t20250108_01.txt /tmp/t20250108_02.txt | grep '^<' | wc -l

还有85个, 就一个个试呗... 当然了, 还可以看下大小, 太小的也可以排除. 我这块盘就一个大表, 所以直接就定位到了. 然后解析下数据:

truncate之前是2097152条数据, 现在恢复的是2095322条数据, 就丢几千条, 还是能接受的.

总结

ibd2sql v2.2版本支持了 mysql 5.7和8.0的DROP TABLETRUNCATE TABLE的恢复, 但drop/truncate表的恢复技术只是保底的, 备份是很重要的.

本次只列出了一些用法, 更多用法可自行组合.

参考:

https://github.com/ddcw/ibd2sql/releases/tag/v2.2

软件下载地址: https://github.com/ddcw/ibd2sql/archive/refs/tags/v2.2.tar.gz

下一篇
举报
领券