数据库数据文件误删恢复工具FGFDU(FGEDU File DUL)
数据库数据文件误删恢复工具FGFDU(FGEDU File DUL)
FGFDU — FGEDU File DUL,专业的数据库数据文件误删恢复工具。
适用于 Oracle / MySQL / PostgreSQL / SQL Server / 达梦 / 金仓 / 崖山 / openGauss / MongoDB / Redis / SQLite / DB2 / GBase / OceanBase / TDengine 等多种数据库数据文件、在 Linux 与 Windows 双平台下,通过底层磁盘块特征指纹扫描直接提取被rm/mv/Shift+Delete删除但尚未被覆写的数据文件。
目录
一、程序介绍
1.1 概述
FGFDU(全称 FGEDU File DUL,FGEDU 文件数据卸载与恢复工具)是一款面向数据库运维与灾难恢复场景的底层磁盘级数据恢复工具。它突破了传统文件系统恢复工具必须依赖 inode、目录项、文件系统元数据完整的局限,能够在不挂载文件系统、不访问任何元数据的前提下,通过直接扫描磁盘块层数据,依据各类数据库文件的"特征指纹"(magic number、头部签名、固定偏移字段、块校验值等)定位已被操作系统从目录项中移除、但磁盘物理块中数据尚未被覆写的数据文件,并把它们以原始字节的方式重新提取出来。
FGFDU 的设计目标是:在数据库因人为误操作(rm -rf、mv、Shift+Delete)、磁盘分区表丢失、LVM 元数据损坏、文件系统 superblock 损坏、或数据库无法正常启动等极端故障下,为 DBA 与系统管理员提供一条"最后一公里"的数据抢救通道,使其能在 RMAN、Data Pump、expdp、mysqldump、物理备份等常规手段全部失效的情况下,仍能从底层磁盘块中最大限度地捞回业务数据。
1.2 设计哲学
FGFDU 在工程实现上遵循以下设计哲学:
- 不依赖文件系统:传统恢复工具需要 ext4/xfs/ntfs 的 inode 与目录结构完好才能工作;FGFDU 直接以只读方式打开块设备或镜像文件,从字节流中识别数据库块签名,即使文件系统元数据全部丢失也能工作。
- 只读与零破坏:FGFDU 对故障盘始终以只读模式打开,所有写入操作仅发生在另一块磁盘上的输出目录中;恢复出的文件权限自动设置为只读(0444),输出目录若存在同名文件会自动追加
_dupN后缀,从不覆盖已有文件,避免对原始介质造成二次破坏。 - 静态二进制与零依赖:FGFDU 编译后为单一静态链接可执行文件(约 855KB),不依赖 glibc 动态库、不依赖任何运行时环境,可以放到任何一台 Linux/Windows 机器上直接运行,特别适合"故障机器不敢动、用 WinPE/U 盘启动救援系统"的场景。
- 多数据库统一引擎:同一套扫描引擎内置 15+ 种数据库块识别器,运维人员无需针对每种数据库学习不同工具,一套命令解决全栈数据库恢复需求。
- 激进与安全并存:提供
scan/recover/maxrecover三档扫描强度,从只识别不写入、到标准恢复、再到激进碎片合并,让用户根据业务场景选择"先验证后恢复"的渐进式流程。
1.3 工作原理
FGFDU 的核心恢复流程可以归纳为四步:
- 设备只读打开:使用系统调用
open(O_RDONLY)打开块设备(/dev/sdX、/dev/mapper/...)或镜像文件,整个生命周期内不会对源设备发起任何写操作。 - 块级特征扫描:以可配置的步长(默认按数据块大小,如 8K)顺序读取设备,对每个数据块调用内置的多数据库识别引擎,根据 magic number、头部签名、固定偏移字段、校验和等特征判断该块是否属于某个数据库文件。
- 片段聚合与去重:将相邻的、属于同一数据库文件的块合并为连续片段;对碎片化的文件尝试通过
maxrecover模式合并,输出时按<db_type>_<序号>_<置信度>pct<扩展名>命名规则单独保存,并自动去重。 - 输出与归位:把恢复出的字节流写到
--output指定的目录,文件权限设置为只读,配套生成运行日志;运维人员使用数据库自带的校验工具(如dbv、innochecksum)校验块一致性后,再用cp -p归位回原数据目录并尝试启动数据库。
对于 LVM 与分区表故障场景,FGFDU 还内置了独立的元数据解析模块:
- 分区表恢复(
partition命令):先尽力解析残留的 MBR/GPT 分区表;若分区表已损坏,则以 1MB 步长全盘扫描文件系统 superblock 签名(ext2/3/4、XFS、NTFS、btrfs、swap、LVM2 PV、FAT),发现丢失的分区边界,再在每个分区范围内运行数据库文件扫描恢复。 - LVM 故障恢复(
lvm命令):扫描设备前 4MB 查找 LVM2 PV 标签(LABELONE魔术字),解析 PV 头部、读取 LVM2 文本元数据,重建 VG/PV/LV 结构与 LE→PE(逻辑盘区→物理盘区)映射表,最后通过映射直接读取逻辑卷数据,无需主机 LVM 配置即可恢复。 - 数据库全库 unload(
unload命令):当 Oracle 因控制文件损坏、SYSTEM 头块损坏、REDO 全部丢失等原因无法启动时,采用两趟扫描:第一趟解析数据字典(USER$/OBJ$/COL$)构建data_obj_id → 用户名/表名/列名映射;第二趟遍历所有数据块提取行数据,按用户名导出每张表为 CSV 文件。
1.4 适用场景
FGFDU 适合以下典型故障场景:
| 故障类型 | 描述 | FGFDU 应对方式 |
|---|---|---|
| 误删数据文件 | DBA 执行 rm、mv 或在图形界面按 Shift+Delete 误删数据库数据文件 |
scan 验证识别率 → maxrecover 恢复 |
| 文件系统损坏 | superblock 损坏、inode 表损坏,文件系统无法挂载 | 跳过文件系统,直接块设备扫描 |
| 分区表丢失/损坏 | MBR/GPT 被 dd 破坏、被病毒覆盖、误删分区 |
partition 命令自动发现丢失分区 |
| LVM 元数据损坏 | VG 元数据损坏、LV 配置丢失、/etc/lvm/backup 被删 |
lvm 命令直接解析磁盘上的 LVM 元数据 |
| 数据库无法启动 | 控制文件损坏、SYSTEM 头块损坏、REDO 全部丢失 | unload 命令按用户名全库导出 CSV |
| 跨虚拟化磁盘恢复 | VMware/KVM 虚拟磁盘文件丢失数据 | 把虚拟磁盘映射成 nbd 设备或直接作为 image 文件扫描 |
| 国产数据库故障 | 达梦、金仓、崖山、openGauss 数据文件误删 | 内置国产数据库块识别引擎 |
1.5 关键术语
| 术语 | 含义 |
|---|---|
| 块设备(block device) | 以固定大小块为单位随机访问的设备,如 /dev/sda1、/dev/mapper/vg-lv |
| 镜像文件(image file) | 通过 dd 把块设备拷贝出来的整盘文件,如 sda.img |
| 数据库块(database block) | 数据库文件内部以固定大小组织的存储单元,Oracle 通常 8K/16K/32K,MySQL InnoDB 默认 16K |
| 特征指纹(fingerprint) | 用于识别数据库块的字节模式,如 Oracle 尾部的 0x0B1B + filenum + tsnum,SQLite 头部的 SQLite format 3 |
| 置信度(confidence) | FGFDU 对识别出的文件可信度评估,0-100,分数越高表示数据完整性越好 |
| LE / PE | Logical Extent / Physical Extent,LVM 中的逻辑盘区与物理盘区 |
二、作者信息
作者:风哥
官方网站: http://www.fgedu.net.cn , http://www.itpux.com
数据库教程: https://edu.51cto.com/lecturer/8020378.html
三、程序功能与特性
3.1 核心功能
FGFDU 提供以下 6 大核心功能模块,每个模块对应一个独立的命令行子命令:
3.1.1 扫描识别(scan 命令)
- 用途:扫描指定设备或镜像文件,识别已删除的数据库文件,只识别不写入,用于恢复前快速验证识别效果。
- 支持参数:
--output、--db、--block-size、--start、--end、--mode - 扫描模式:
normal:默认模式,按数据块大小步长顺序扫描,速度最快max:最大恢复模式,启用激进的碎片合并,识别率更高deep:深度扫描模式,扇区级全盘扫描,速度最慢但最彻底
- 数据库类型过滤:支持按
oracle、mysql、pgsql、sqlserver、dameng、kingbase、yashan、opengauss、all进行过滤,避免无关数据库误识别。
3.1.2 标准恢复(recover 命令)
- 用途:扫描设备后立即恢复所有识别到的文件到
--output指定的目录。 - 输出文件命名规则:
<db_type>_<序号>_<置信度>pct<扩展名>,如oracle_00001_098.dbf表示 Oracle 文件、序号 1、置信度 98%、扩展名.dbf。 - 冲突处理:若文件名已存在,自动追加
_dup1、_dup2... 后缀,从不覆盖已有文件。
3.1.3 最大恢复(maxrecover 命令,生产推荐)
- 用途:生产故障恢复的推荐模式,结合最大扫描 + 深度扫描 + 激进碎片合并 + 可选的目标目录路径提示,把识别率推到最高。
- 特有参数:
--target-dir:原始数据目录路径提示(如/u01/app/oracle/oradata/ORCL),用于辅助识别文件归属,进一步提升识别率。 - 使用建议:先
scan验证识别率,再maxrecover --target-dir=...执行正式恢复。
3.1.4 分区表丢失/损坏恢复(partition 命令)
- 用途:当磁盘 MBR/GPT 分区表丢失或损坏,导致分区无法挂载时,自动解析残留分区表 + 全盘扫描丢失分区 + 恢复各分区中的数据库文件。
- 支持分区表类型:MBR、GPT、损坏(自动降级为全盘扫描)、无(扇区 0 全零时全盘扫描)。
- 支持文件系统签名:ext2/3/4、XFS、NTFS、btrfs、swap、LVM2 PV、FAT。
- 工作流程:
- 解析磁盘上的 MBR/GPT 分区表(即使部分损坏也能尽力解析);
- 以 1MB 为步长扫描全盘,通过文件系统超级块签名发现丢失的分区边界;
- 对每个识别到的分区,在其字节范围内运行扫描/恢复引擎;
- 将所有分区中恢复的数据库文件汇总输出。
3.1.5 LVM 故障恢复(lvm 命令)
- 用途:当 LVM2 的 PV/VG/LV 元数据损坏,导致逻辑卷无法挂载或
lvdisplay无法识别时,直接从物理设备解析 LVM 元数据并恢复逻辑卷中的数据库文件。 - 支持场景:VG 元数据损坏、LV 配置丢失、
/etc/lvm/backup被删、多 PV 组成的 VG(单 PV 设备恢复,跨 PV 条带化 LV 为近似映射)。 - 工作流程:
- 扫描设备前 4MB 查找 LVM2 PV 标签(
LABELONE魔术字); - 解析 PV 头部:PV UUID、设备大小、数据区位置、元数据区位置;
- 读取并解析 LVM2 文本元数据,重建 VG/PV/LV 结构;
- 根据 LV 段映射(segment)构建 LE→PE(逻辑盘区→物理盘区)映射表;
- 通过 LE→PE 映射直接读取逻辑卷数据,识别并恢复数据库文件。
- 扫描设备前 4MB 查找 LVM2 PV 标签(
- 核心优势:无需主机 LVM 配置即可恢复,适用于
/etc/lvm/backup全部丢失等极端场景。
3.1.6 数据库全库卸载(unload 命令)
- 用途:当 Oracle 数据库因控制文件损坏、SYSTEM 头块损坏、REDO 日志全部丢失等原因无法启动(无法 MOUNT/OPEN),传统 RMAN / Data Pump / expdp 全部失效时,直接从数据文件按用户名导出所有表为 CSV 文件。
- 适用数据库:Oracle 9i ~ 26ai(含 CDB/PDB 架构)。
- 工作原理:
- 第一趟扫描:解析 Oracle 数据字典(USER$/OBJ$/COL$),构建
data_obj_id → 用户名/表名/列名映射; - 第二趟扫描:遍历所有数据块,提取行数据,按用户名/表名写入 CSV 文件。
- 第一趟扫描:解析 Oracle 数据字典(USER$/OBJ$/COL$),构建
- 输出目录结构:
<output_dir>/<username>/<table_name>.csv(首行为列名,后续为数据行)<output_dir>/_UNKNOWN/OBJ_<id>.csv(无法匹配数据字典的块)
- 支持数据类型:VARCHAR2、CHAR、NUMBER、DATE 等 Oracle 常用类型。
- CDB/PDB 架构:建议按容器分别 unload 以避免同名用户冲突。
3.1.7 辅助命令
version:打印版本信息与版权声明。help:打印命令行使用帮助,列出全部子命令与参数说明。list:列出扫描结果中的文件(当前为占位桩,输出用法提示)。
3.2 程序特性
3.2.1 跨平台与零依赖
| 特性 | 说明 |
|---|---|
| 单一静态二进制 | 编译后约 855KB 单个可执行文件,无任何动态依赖,ldd 输出"不是动态可执行文件" |
| Linux 全系支持 | RHEL/CentOS 5-10、Oracle Linux、Kylin、EulerOS/openEuler、Ubuntu、Debian、SUSE 全系列 |
| Windows 双平台 | Windows Server 2008R2 ~ 2022、Windows 7 SP1 ~ 11,建议通过 WinPE 启动盘离线操作 |
| 即拷即用 | 无需安装、无需配置环境变量,拷贝到任意救援系统直接执行 |
3.2.2 多数据库统一引擎
FGFDU 内置 15+ 种数据库块识别器,覆盖主流商业数据库、开源数据库与国产数据库:
| 类别 | 覆盖数据库 |
|---|---|
| 商业数据库 | Oracle、SQL Server、IBM DB2 |
| 开源数据库 | MySQL(InnoDB + MyISAM)、PostgreSQL、SQLite、MongoDB、Redis |
| 国产数据库 | 达梦 DM7/8/9、金仓 KingbaseES V8/V9、崖山 YashanDB、openGauss、GBase、OceanBase、TDengine |
详细的数据库版本与文件扩展名支持矩阵见 4.4 支持的数据库。
3.2.3 三档扫描模式
| 模式 | 速度 | 识别率 | 适用场景 |
|---|---|---|---|
normal |
最快 | 标准 | 首次快速验证识别效果 |
max |
中等 | 高 | 推荐用于生产恢复,启用激进碎片合并 |
deep |
最慢 | 最高 | 极度碎片化、normal/max 识别不全时使用 |
3.2.4 安全保护机制
- 只读打开源设备:全程
O_RDONLY,对故障盘零写入。 - 输出目录隔离:要求
--output必须位于另一块磁盘或 NFS 挂载,与故障盘物理隔离。 - 文件只读权限:恢复出的文件权限自动设置为 0444,防止运维人员误覆盖。
- 从不覆盖:输出目录若存在同名文件,自动追加
_dup1、_dup2... 后缀。 - 退出码语义清晰:0 成功、1 用法错误、2 权限拒绝、3 I/O 错误、4 内存不足、5 部分成功,便于脚本化判断。
3.2.5 范围与参数可控
--start/--end:支持指定扫描的起止字节偏移,方便分批扫描超大磁盘。--block-size:支持手动指定块大小(4096 / 8192 / 16384 / 32768),覆盖 Oracle 不同db_block_size配置。--db:支持按数据库类型过滤,避免无关数据库误识别干扰结果。--target-dir:maxrecover专用,提供原始数据目录路径作为提示,提升识别率。
3.2.6 完善的工程化与可测试性
- 模块化源码结构:
platform / io / scan / identify / recover / partition / lvm / unload / cli各司其职,便于维护与扩展。 - 配套测试数据生成器:
make_fake_dev、make_mbr_dev、make_lvm_dev、make_oracle_unload_dev,可生成 8-16MB 的合成测试镜像,覆盖全部恢复场景。 - 识别引擎单元测试:
run_identify_tests验证 13+ 种数据库块的签名识别。 - 一键自动化测试脚本:
run_all_tests.sh自动编译、生成镜像、执行 62 项测试、输出彩色 PASS/FAIL 结果与汇总报告。 - 详细文档体系:包含《用户手册》《快速开始指南》《实验测试手册》《非 CDB 测试文档》《CDB/PDB 测试文档》等多份配套资料。
3.3 功能矩阵速查
| 命令 | 作用 | 是否写入数据 | 推荐使用时机 |
|---|---|---|---|
version |
打印版本信息 | 否 | 验证编译产物 |
help |
打印使用帮助 | 否 | 查询参数说明 |
scan |
扫描识别,只识别不写入 | 否 | 恢复前先验证识别率 |
recover |
标准扫描 + 恢复 | 是(写到输出目录) | 普通恢复场景 |
maxrecover |
最大恢复(激进碎片合并 + target-dir 提示) | 是(写到输出目录) | 生产推荐 |
partition |
分区表丢失/损坏恢复 | 是(写到输出目录) | MBR/GPT 损坏场景 |
lvm |
LVM 故障恢复 | 是(写到输出目录) | VG/LV 元数据损坏场景 |
unload |
Oracle 数据库无法启动时全库导出 CSV | 是(写到输出目录) | 控制文件/SYSTEM/REDO 损坏场景 |
list |
列出扫描结果(占位桩) | 否 | 暂未实现 |
四、支持环境
4.1 支持的操作系统
4.1.1 Linux 平台(推荐)
| 发行版 | 支持版本 |
|---|---|
| RHEL / CentOS | 5、6、7、8、9、10 |
| Oracle Linux (OEL) | 全系列 |
| 麒麟 Kylin | 银河麒麟 V10 / V4 |
| 欧拉 EulerOS / openEuler | 全系列 |
| Ubuntu | 14.04 ~ 最新 |
| Debian | 8 ~ 最新 |
| SUSE | 12 ~ 最新 |
4.1.2 Windows 平台
| 版本 | 支持范围 |
|---|---|
| Windows Server | 2008 R2 / 2012 / 2016 / 2019 / 2022 |
| Windows Desktop | 7 SP1 / 8.1 / 10 / 11 |
建议:优先使用 Linux 环境。Windows 建议通过 WinPE 启动盘离线操作,避免在故障系统上运行任何可能写盘的程序。
4.2 编译环境要求
| 项目 | 要求 |
|---|---|
| 编译器 | GCC 4.4 或更高版本(Windows 用 MinGW-w64 / MSYS2) |
| 构建工具 | GNU Make 3.81+ |
| 静态链接依赖 | glibc-static 包(用于 Linux 静态链接) |
| 权限 | 普通用户即可编译;make install 安装到系统目录需要 root |
| 磁盘空间 | ≥ 100MB(源码 + 编译产物 + 测试镜像) |
4.3 运行权限要求
| 操作场景 | 是否需要 root |
|---|---|
扫描块设备(/dev/sdX、/dev/mapper/...) |
需要 root |
扫描普通镜像文件(.img) |
不需要 root |
| 写入输出目录 | 需要对输出目录有写权限 |
安装到系统目录(make install) |
需要 root |
建议:始终使用
sudo运行,避免权限不足导致扫描失败。
4.4 支持的数据库
FGFDU 支持的数据库与其典型文件扩展名矩阵如下:
| 数据库 | 版本范围 | 典型文件扩展名 |
|---|---|---|
| Oracle | 9i、10g、11g、12c、18c、19c、21c、23ai、26ai | .dbf、.ora(控制文件)、redo log |
| MySQL InnoDB | 5.0 ~ 5.7、8.0、8.4、9.x | ibdata*、*.ibd、undo/redo |
| MySQL MyISAM | 5.x、8.x | *.MYD、*.MYI |
| PostgreSQL | 8.x、9.x、10 ~ 17 | base/、global/、pg_wal/ |
| SQL Server | 2005、2008/2012/2014/2016/2019/2022 | .mdf、.ndf、.ldf |
| SQLite | 全系列 | .db、.sqlite、.sqlite3 |
| MongoDB | 3.0 ~ 7.x(WiredTiger 引擎) | .wt、WiredTiger* |
| Redis | 全系列 | dump.rdb、appendonly.aof |
| IBM DB2 | 9.x ~ 最新 | tablespace containers |
| 达梦 DM8 | DM7、DM8、DM9 | .dbf |
| 金仓 KingbaseES V8 | V8、V9 | data files |
| 崖山 YashanDB | 全系列 | .dbf |
| openGauss | 1.0 ~ 最新 | data files |
| GBase | 8a / 8s / 8t | .dat |
| OceanBase | 全系列 | SSTable data files |
| TDengine | 2.x、3.x | .data |
4.5 支持的存储与虚拟化
| 存储类型 | 支持方式 |
|---|---|
| 物理磁盘 / 分区 | 直接扫描 /dev/sda、/dev/sda1 |
| LVM2 逻辑卷 | 正常挂载时扫 /dev/mapper/vg-lv;元数据损坏用 lvm 命令 |
| Linux 软 RAID(mdadm) | 组装后扫描 /dev/md0,或扫描成员盘 |
| 硬 RAID / HBA 卡 | 直接扫描呈现给操作系统的块设备 |
| Oracle ASM | 扫描 ASM 磁盘 /dev/oracleasm/disks/*,配合 --db=oracle --mode=deep |
| VMware VMDK | 挂载到宿主机后扫描对应设备 |
| KVM QCOW2 | 用 qemu-nbd 映射成 nbd 设备后扫描 |
| 镜像文件 | 直接作为 image 文件交给 FGFDU 扫描 |
五、程序使用
5.1 编译与安装
5.1.1 Linux 环境(推荐)
# 1. 进入项目目录
cd /fgedu/fgedudb/FGFDU
# 2. 安装静态链接依赖(以 RHEL/CentOS 为例)
sudo yum install -y glibc-static make gcc
# 3. 编译发行版(静态链接、优化 O2、自动 strip)
make clean && make
# 4. 编译调试版(带 -g 调试符号、不 strip)
make debug
# 5. 安装到系统(可选,需要 root)
sudo make install
# 6. 查看二进制
ls -lh bin/fgfdu
file bin/fgfdu
预期输出:
bin/fgfdu: ELF 64-bit LSB executable, x86_64, version 1 (GNU/Linux),
statically linked, for GNU/Linux 2.6.32, stripped
5.1.2 Windows 环境(MinGW / MSYS2)
# 安装 MinGW-w64 + MSYS2
# 进入 MSYS2 shell
cd /c/fgedudb/FGFDU
make clean && make
# 产物:bin/fgfdu.exe
5.2 命令行总览
fgfdu <subcommand> <device_or_file> [options]
| 子命令 | 作用 | 必填参数 | 可选参数 |
|---|---|---|---|
version |
打印版本信息 | 无 | 无 |
scan |
扫描识别,只识别不写入 | --output |
--db、--block-size、--start、--end、--mode |
recover |
标准扫描 + 恢复 | --output |
--db、--block-size、--start、--end、--mode |
maxrecover |
最大恢复(生产推荐) | --output |
--target-dir、--db、--block-size、--mode |
partition |
分区表丢失/损坏恢复 | --output |
--db、--block-size |
lvm |
LVM 故障恢复 | --output |
--db、--block-size |
unload |
Oracle 全库导出 CSV | --output |
--block-size |
list |
列出扫描结果(占位桩) | 无 | 无 |
help |
打印使用帮助 | 无 | 无 |
5.3 通用参数详解
| 参数 | 说明 | 默认值 | 示例 |
|---|---|---|---|
--output=<dir> |
输出目录(必填,自动创建) | - | --output=/mnt/recover/out |
--db=<type> |
数据库类型过滤 | all |
--db=oracle、--db=mysql |
--block-size=N |
块大小(字节) | 自动检测 | --block-size=8192 |
--start=N |
起始扫描偏移(字节) | 0 | --start=1048576 |
--end=N |
结束扫描偏移(字节) | 设备末尾 | --end=$((100*1024*1024*1024)) |
--mode=<mode> |
扫描模式 | normal |
--mode=max、--mode=deep |
--target-dir=<path> |
原始数据目录路径提示(maxrecover 专用) |
无 | --target-dir=/u01/app/oracle/oradata/ORCL |
--db 参数支持的取值:
all(默认,识别全部数据库)oracle:仅 Oraclemysql:仅 MySQL InnoDBpgsql或postgresql:仅 PostgreSQLsqlserver:仅 SQL Serverdameng:仅达梦kingbase:仅金仓yashan:仅崖山opengauss:仅 openGauss
5.4 输出目录说明
--output 指定的目录下,每个恢复的文件会单独保存,命名规则:
<db_type>_<id>_<confidence>pct<ext>
例如:oracle_00001_098.dbf # Oracle 文件,序号 1,置信度 98%
mysql_00010_090.ibd # MySQL InnoDB 文件,序号 10,置信度 90%
pgsql_00102_073 # PostgreSQL 文件,序号 102,置信度 73%
输出目录结构示例:
./recover_out/
├── oracle_00001_098.dbf # system01.dbf,置信度98%
├── oracle_00002_095.dbf # sysaux01.dbf,置信度95%
├── oracle_00003_087.dbf # users01.dbf,置信度87%
├── oracle_00004_062.dbf_dup1 # 同名重复,自动加_dupN后缀
├── mysql_00010_090.ibd
├── pgsql_00201_073
└── fgfdu.log # 运行日志(如启用)
文件权限:所有恢复出的文件权限自动被设为 只读(0444),防止意外二次破坏。
冲突处理:若文件名已存在,自动追加 _dup1、_dup2... 后缀,从不覆盖已有文件。
5.5 退出码
| 退出码 | 含义 | 脚本判定建议 |
|---|---|---|
| 0 | 成功 | PASS |
| 1 | 参数错误 / 用法错误 | FAIL |
| 2 | 权限不足 | 检查 sudo |
| 3 | I/O 错误(磁盘、文件读写错误) | 检查磁盘健康 |
| 4 | 内存不足 | 检查内存或缩小扫描范围 |
| 5 | 部分成功(恢复了至少 1 个文件但未全部成功) | 可接受,验证文件 |
5.6 常用命令速查表
| 需求 | 命令 |
|---|---|
| 查看版本 | fgfdu version |
| 查看帮助 | fgfdu help |
| 先扫描验证识别率 | fgfdu scan /dev/sda1 --output=./out --mode=max --db=all |
| 标准恢复 | fgfdu recover /dev/sda1 --output=./out |
| 生产推荐:最大恢复 | fgfdu maxrecover /dev/sda2 --output=./out --target-dir=<原始数据目录> |
| 分区表丢失/损坏 | fgfdu partition /dev/sda --output=./out |
| LVM 故障恢复 | fgfdu lvm /dev/sda2 --output=./out |
| Oracle 无法启动时全库导出 | fgfdu unload /dev/sdb --output=/tmp/unload_out |
| 仅扫描 Oracle | 加 --db=oracle |
| 仅扫描 MySQL InnoDB | 加 --db=mysql |
| 指定块大小 | 加 --block-size=8192 |
| 深度扫描(慢但全) | 加 --mode=deep |
六、程序各种案例场景与操作过程
6.1 案例一:Oracle 数据文件 rm 误删恢复
场景:DBA 误执行
rm /u01/app/oracle/oradata/ORCL/*.dbf,数据库无法启动。
Step 1 — 立即停止一切写入
# 立刻停库,不要 shutdown immediate(会写 checkpoint 覆盖更多块)
ps -ef | grep pmon | grep -v grep
kill -9 <pmon_pid> # 或者 shutdown abort
# 不要启动任何可能写盘的服务
Step 2 — 确认故障盘
df -h /u01/app/oracle/oradata
# 假设对应块设备是 /dev/mapper/vg_oracle-lv_oradata
ls -l /dev/mapper/vg_oracle-lv_oradata
Step 3 — 扫描验证(先确认能识别)
# 找一块空盘,把恢复结果写到别的盘!!
mkdir -p /mnt/recover/oracle_out
sudo ./bin/fgfdu scan /dev/mapper/vg_oracle-lv_oradata \
--output=/mnt/recover/scan_report \
--mode=max --db=oracle
观察输出中 Files identified 是否 > 0。
Step 4 — 最大恢复(生产推荐)
sudo ./bin/fgfdu maxrecover /dev/mapper/vg_oracle-lv_oradata \
--output=/mnt/recover/oracle_out \
--target-dir=/u01/app/oracle/oradata/ORCL \
--db=oracle
Step 5 — 校验 + 归位
ls -lh /mnt/recover/oracle_out/
# 文件名形如 oracle_00001_098.dbf
# 用 Oracle dbv 校验块
dbv file=/mnt/recover/oracle_out/oracle_00001_098.dbf blocksize=8192
# 校验通过后,重命名回正确文件名,用 oracle 用户归位
chown oracle:oinstall /mnt/recover/oracle_out/*.dbf
chmod 640 /mnt/recover/oracle_out/*.dbf
cp -p /mnt/recover/oracle_out/oracle_00001_098.dbf \
/u01/app/oracle/oradata/ORCL/system01.dbf
# 然后尝试 startup mount 恢复
6.2 案例二:MySQL InnoDB 表文件误删恢复
场景:
rm /var/lib/mysql/mydb/*.ibd,MySQL InnoDB 表无法访问。
Step 1 — 停 MySQL
sudo systemctl stop mysqld # 或 kill -9 mysqld_pid
# 不要再启动!
Step 2 — 执行恢复
mkdir -p /mnt/recover/mysql_out
sudo ./bin/fgfdu maxrecover /dev/mapper/vg_mysql-lv_data \
--output=/mnt/recover/mysql_out \
--target-dir=/var/lib/mysql/mydb \
--db=mysql
Step 3 — 校验 + 归位
# 用 innochecksum 校验
innochecksum /mnt/recover/mysql_out/mysql_00010_090.ibd
# 重命名后拷贝回数据目录
chown mysql:mysql /mnt/recover/mysql_out/*.ibd
cp -p /mnt/recover/mysql_out/mysql_00010_090.ibd /var/lib/mysql/mydb/employees.ibd
6.3 案例三:分区表丢失/损坏恢复
场景:MBR/GPT 分区表被
dd if=/dev/zero of=/dev/sda bs=512 count=1破坏、病毒覆盖、或误删,导致分区无法挂载。
# 自动解析残留分区表 + 全盘扫描丢失分区 + 恢复各分区中的数据库文件
sudo ./bin/fgfdu partition /dev/sda --output=/mnt/recover/part_out
# 镜像文件
./bin/fgfdu partition /mnt/usb/sda.img --output=./out --db=oracle
工具会自动完成:
- 尽力解析残留的 MBR/GPT 分区表;
- 以 1MB 步长扫描文件系统超级块签名(ext2/3/4、XFS、NTFS、btrfs、LVM PV)发现丢失分区;
- 在每个分区字节范围内运行数据库文件扫描恢复;
- 汇总所有分区中恢复的数据库文件。
预期输出示例:
Partition Table: mbr
Corrupted : no
Sector size: 512
Partitions : 2
Idx StartLBA Sectors FS Boot Lost Name
0 2048 4096 raw no no mbr_part0
1 8192 4096 raw no no mbr_part1
Partition recovery complete:
Files identified: 5
Files recovered: 5
Total bytes: 53248
6.4 案例四:LVM 故障恢复
场景:LVM VG 元数据损坏、LV 配置丢失、
/etc/lvm/backup被删,lvdisplay无法识别逻辑卷。
# 直接从物理设备解析 LVM2 PV 标签和 VG 元数据
sudo ./bin/fgfdu lvm /dev/sda2 --output=/mnt/recover/lvm_out
# PV 镜像文件
./bin/fgfdu lvm /mnt/usb/lvm_pv.img --output=./out --db=oracle
工具会自动完成:
- 扫描
LABELONE魔术字定位 LVM2 PV 标签; - 解析 PV 头部和元数据区文本,重建 VG/PV/LV 结构;
- 根据 LV 段映射构建 LE→PE 映射表;
- 通过映射直接读取逻辑卷数据,识别并恢复数据库文件。
核心优势:无需主机 LVM 配置即可恢复,适用于 VG 元数据损坏、LV 配置丢失等场景。
预期输出示例:
=== Volume Group ===
name : vg_data
uuid : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
pe_size : 4194304 bytes (8192 sectors)
pe_total : 100
pe_free : 30
valid : yes
pv_count : 1
lv_count : 2
--- Logical Volumes ---
LV[0] name=lv_oracle uuid=... le_count=50 size=209715200 valid=yes
LV[1] name=lv_mysql uuid=... le_count=20 size=83886080 valid=yes
LVM recovery complete:
Files identified: 22
Files recovered: 22
Total bytes: 227328
6.5 案例五:Oracle 数据库无法启动时全库 Unload
场景:Oracle 数据库因控制文件损坏、SYSTEM 头块损坏、REDO 日志全部丢失等原因无法启动(无法 MOUNT/OPEN),传统 RMAN/Data Pump/expdp 全部失效。
Step 1 — 执行 unload
# 从整个磁盘设备 unload
sudo ./bin/fgfdu unload /dev/sdb --output=/tmp/unload_out
# 从单个数据文件 unload
fgfdu unload /u01/app/oracle/oradata/ORCL/system01.dbf --output=/tmp/unload_out
# 指定块大小
fgfdu unload /dev/sdb --output=/tmp/unload_out --block-size=8192
Step 2 — 验证输出
预期输出示例:
DATABASE UNLOAD MODE (按用户名导出)
Data file : /dev/sdb
Output dir: /tmp/unload_out
=== Unload Summary ===
Blocks scanned : 13107200
Tables unloaded : 3120
Tables failed : 0
Total rows extracted: 8542100
Total bytes written : 456789012
--- Tables ---
SYS USER$ 45 rows
SYS OBJ$ 3120 rows
SCOTT EMP 8 rows
HR EMPLOYEES 107 rows
...
Step 3 — 检查导出的 CSV
# 查看目录结构:按用户名分目录
find /tmp/unload_out -type d | sort
# 输出:
# /tmp/unload_out
# /tmp/unload_out/SCOTT
# /tmp/unload_out/SYS
# /tmp/unload_out/HR
# 查看 SCOTT.EMP 表的 CSV
cat /tmp/unload_out/SCOTT/EMP.csv
# 预期:
# EMPNO,ENAME,JOB,SAL
# 7369,SMITH,CLERK,800
# 7499,ALLEN,SALESMAN,1600
# ...
注意事项:
- 需要包含 SYSTEM 表空间文件以解析数据字典,否则所有表将导出到
_UNKNOWN/目录; - CDB/PDB 架构下,建议按容器分别 unload 以避免同名用户冲突;
- 支持 VARCHAR2/CHAR/NUMBER/DATE 等 Oracle 常用数据类型;
- 导出的 CSV 可直接用
sqlldr、LOAD DATA INFILE、COPY等方式导入到新数据库中。
6.6 案例六:国产数据库(达梦/金仓)误删恢复
场景:达梦 DM8 或金仓 KingbaseES 数据文件被
rm误删。
# 达梦 DM8 恢复
sudo ./bin/fgfdu maxrecover /dev/mapper/vg_dameng-lv_data \
--output=/mnt/recover/dm_out \
--target-dir=/opt/dmdbms/data/DAMENG \
--db=dameng
# 金仓 KingbaseES 恢复
sudo ./bin/fgfdu maxrecover /dev/mapper/vg_kingbase-lv_data \
--output=/mnt/recover/kingbase_out \
--target-dir=/opt/KingbaseES/data/base \
--db=kingbase
6.7 案例七:虚拟机磁盘数据恢复
场景:VMware/KVM 虚拟机内数据库文件丢失,需从宿主机恢复 VMDK/QCOW2 磁盘文件中的数据。
# 方式 1:VMDK 挂载到宿主机后扫描对应设备
sudo ./bin/fgfdu maxrecover /dev/sdb1 --output=/mnt/recover/vm_out --db=oracle
# 方式 2:QCOW2 用 qemu-nbd 映射成 nbd 设备后扫描
sudo modprobe nbd max_part=8
sudo qemu-nbd --connect=/dev/nbd0 /var/lib/libvirt/images/vm.qcow2
sudo ./bin/fgfdu maxrecover /dev/nbd0p1 --output=/mnt/recover/vm_out --db=mysql
sudo qemu-nbd --disconnect /dev/nbd0
# 方式 3:直接把虚拟磁盘文件作为 image 文件交给 fgfdu scan
./bin/fgfdu scan /var/lib/libvirt/images/vm.qcow2 --output=./out --mode=deep
6.8 案例八:分批扫描超大磁盘
场景:磁盘超过 10TB,一次扫描时间过长,希望分批执行。
# 第 1 批:0 ~ 5TB
sudo ./bin/fgfdu maxrecover /dev/sda --output=/mnt/recover/batch1 \
--start=0 --end=$((5*1024*1024*1024*1024)) --db=oracle
# 第 2 批:5TB ~ 10TB
sudo ./bin/fgfdu maxrecover /dev/sda --output=/mnt/recover/batch2 \
--start=$((5*1024*1024*1024*1024)) --end=$((10*1024*1024*1024*1024)) --db=oracle
# 后续批次以此类推
6.9 紧急情况 Checklist
✅ 数据删除后第一时间按此表操作,避免数据被覆盖永久丢失!
| 步骤 | 操作 | 状态 |
|---|---|---|
| 1 | 立刻停数据库(Oracle: shutdown abort;MySQL: kill -9) |
☐ |
| 2 | 禁止写入故障盘:不要 mkdir/touch/vi 故障分区任何文件 |
☐ |
| 3 | 不要重启服务器(除非有 UPS 且不自动启库) | ☐ |
| 4 | 不要执行 fsck | ☐ |
| 5 | 确认输出目录在另一块磁盘(U盘/备份盘/NFS 均可) | ☐ |
| 6 | 先 scan 确认识别率,再执行 maxrecover |
☐ |
| 7 | 恢复出的文件用 dbv / innochecksum 校验后再归位 |
☐ |
6.10 推荐恢复流程
第1步:对故障盘做 dd 镜像(强烈建议!)
$ sudo dd if=/dev/sda2 of=/mnt/usb/sda2.img bs=4M status=progress
或使用 fgfdu 直接扫描 /dev/sda2(只读打开,安全)
第2步:先 scan 确认识别效果
$ sudo fgfdu scan /dev/sda2 --output=./scan_report --mode=max --db=oracle
第3步:确认无误后执行恢复
$ sudo fgfdu maxrecover /dev/sda2 --output=./recover --target-dir=...
第4步:校验恢复出的文件
- Oracle: dbv 检查 .dbf 块一致性
- MySQL: innochecksum 校验 .ibd
- 用 md5sum/sha256sum 与备份对比(如有)
七、常用问题与排查
7.1 恢复能力相关
Q1: 误 rm -rf 删除了 Oracle 的 datafile,能恢复吗?
A:如果删除后磁盘没有被大量写入(例如数据库没有启动大事务、没有大量归档生成),FGFDU 恢复率在 80% ~ 99%。删除后越快执行越好——Linux 文件系统删除文件只是把 inode 标记为 free,磁盘块上的实际数据在未被新数据覆写前仍然存在,FGFDU 就是利用这一点进行恢复。
Q2: 能恢复被 shred 或 dd if=/dev/zero 覆写过的文件吗?
A:不能。被覆写的数据无法用任何软件恢复。FGFDU 仅针对"删除但尚未被覆写"的块。这也是为什么强调"数据丢失后第一时间停库、停止写入"——任何写入都可能覆写掉可恢复的数据。
Q3: 恢复出来的文件块不连续怎么办?
A:FGFDU 的 maxrecover 模式会自动尝试合并碎片。对于极度碎片化的文件,置信度会降低(< 50%)。恢复后建议用数据库自带工具校验:
- Oracle:
dbv file=xxx.dbf blocksize=8192检查坏块 - MySQL:
innochecksum xxx.ibd校验页一致性 - 若坏块较多,可在数据库启动后用
RMAN BLOCKRECOVER或mysqlcheck --repair修复
Q4: 支持 LVM / ASM 吗?
A:支持。
- LVM 恢复:使用
fgfdu lvm <设备>命令,直接从物理设备解析 LVM2 PV 标签和 VG 元数据,重建 LE→PE 映射,无需主机 LVM 配置即可恢复逻辑卷中的数据库文件。适用于 VG 元数据损坏、LV 配置丢失、/etc/lvm/backup丢失等场景。 - LVM 正常扫描:若逻辑卷仍可正常挂载,可直接扫描
/dev/mapper/vg-lv设备。 - Oracle ASM:扫描 ASM 磁盘
/dev/oracleasm/disks/*,并配合--db=oracle --mode=deep。
Q5: 分区表损坏后能恢复数据吗?
A:可以。使用 fgfdu partition <设备> 命令,工具会:
- 尽力解析残留的 MBR/GPT 分区表;
- 全盘扫描文件系统超级块签名,发现丢失的分区边界;
- 在每个分区范围内运行数据库文件扫描恢复。
适用于 dd if=/dev/zero of=/dev/sda bs=512 count=1 破坏 MBR、分区表被病毒覆盖、GPT 备份头损坏等场景。
Q6: 支持 VMware / KVM 虚拟机磁盘吗?
A:支持。
- VMDK:挂载到宿主机后扫描对应设备;
- QCOW2:
qemu-nbd映射成 nbd 设备后扫描; - 或者直接把虚拟磁盘文件作为 image 文件交给
fgfdu scan。
7.2 性能相关
Q7: 扫描速度如何?
A:通常 每 TB 大约 30 ~ 120 分钟,取决于:
- 磁盘转速(SSD 快于 HDD);
- 块大小设置(越小越慢);
- 扫描模式(
deep>max>normal); - HBA 卡 / RAID 卡性能;
- 是否使用镜像文件 vs 直接块设备(镜像文件多一层文件系统开销)。
Q8: 扫描超大磁盘内存占用如何?
A:FGFDU 采用流式扫描,内存占用与磁盘大小无关,典型场景下常驻内存在数十 MB 量级。若出现 Out of memory(退出码 4),建议:
- 用
--start/--end分批扫描; - 检查系统是否启用了超大 swap 导致 OOM killer 误杀;
- 关闭其他大型进程。
7.3 权限与报错相关
Q9: 扫描时提示 permission denied?
A:按顺序检查:
- 是否加了
sudo(扫描/dev/sdX必须 root); /dev/sdX设备权限:ls -l /dev/sda1,正常应为brw-rw----属主 root:disk;- 是否有安全软件限制(AppArmor / SELinux),可临时
setenforce 0或调整 AppArmor profile; - 容器内扫描需确保容器以
--privileged启动并挂载了/dev。
Q10: 提示 device or resource busy?
A:设备正被其他进程占用。检查:
- 是否文件系统还挂载着:
mount | grep sda1,先umount; - 是否 LVM 还激活着:
lvdisplay,先lvchange -an; - 是否被其他恢复工具占用:
lsof /dev/sda1。
Q11: --output 目录写不下怎么办?
A:恢复出的文件大小通常接近原始数据文件大小。提前用 df -h <output_dir> 确认空间。空间不足会返回退出码 3(I/O 错误)或 4(内存不足)。建议:
- 把输出目录放到一块大于故障盘已用容量的空盘上;
- 使用 NFS 挂载远程存储;
- 分批扫描,每批输出到不同目录。
Q12: 退出码 5(部分成功)算成功吗?
A:算成功。退出码 5 表示"恢复了至少 1 个文件但未全部成功",这是恢复场景下最常见的退出码。建议:
- 检查输出目录中实际恢复出的文件数量与
scan报告的Files identified对比; - 对置信度较低的文件(< 70%)重点用
dbv/innochecksum校验; - 必要时切换到
--mode=deep重新扫描。
7.4 输出与归位相关
Q13: 恢复出来的文件名是 oracle_00001_098.dbf,怎么对应回原始文件名?
A:FGFDU 通过块特征识别,无法直接得到原始文件名(文件名信息存储在文件系统目录项中,删除后已丢失)。归位方法:
- 根据文件大小、块数推断:例如
system01.dbf通常最大且包含 SYSTEM 表空间标识; - 用
dbv校验后看kcvfh头部信息中的ts#(表空间号); - 如果使用了
--target-dir提示,FGFDU 会尽量按原始路径辅助匹配; - 必要时按文件大小排序,先恢复最大的几个文件(通常对应 SYSTEM/USERS 表空间)。
Q14: 归位后数据库起不来怎么办?
A:按以下顺序排查:
- 权限:
chown oracle:oinstall *.dbf && chmod 640 *.dbf; - 文件名:核对
v$datafile中记录的文件名与归位后的文件名是否一致; - 块校验:
dbv file=xxx.dbf blocksize=8192,修复坏块; - 控制文件:若控制文件也丢失,需要
CREATE CONTROLFILE重建; - REDO:若 REDO 全部丢失,可能需要
UNRECOVERABLE DATAFILE或_allow_resetlogs_corruption; - 如果都不行:用
fgfdu unload命令把表数据按用户名导出为 CSV,然后导入到新数据库。
7.5 收费与支持相关
Q15: 收费 / 开源吗?
A:FGFDU 由 FGEDU 提供,分免费版与商业版:
- 免费版:包含核心扫描与恢复能力,覆盖主流数据库与常规故障场景;
- 商业版:提供以下增强能力:
- 更多数据库指纹(自研数据库、小众数据库);
- Oracle ASM diskgroup 解析;
- 7x24 工程师远程恢复支持;
- 现场紧急救援服务;
- 定制化恢复方案。
请联系 FGEDU 技术支持获取商业授权。
Q16: 出现文档未覆盖的问题怎么办?
A:按以下顺序自救:
- 查看运行日志:
--output目录下的fgfdu.log; - 用
fgfdu version确认版本,升级到最新版后重试; - 用
--mode=deep重新扫描; - 把故障盘
dd成镜像后用只读模式反复试验; - 联系 FGEDU 技术支持:support@fgedu.com,提供
fgfdu.log与fgfdu version输出。
八、附录
8.1 相关文档
| 文档名 | 说明 |
|---|---|
docs/README.md |
FGFDU 快速开始指南 |
docs/fgfdu_manual.md |
FGFDU 完整用户手册 |
docs/test_manual.md |
FGFDU 实验测试手册(62 项自动化测试) |
docs/testdoc-nopdb.md |
Oracle 非 CDB 架构测试文档 |
docs/testdoc-pdb.md |
Oracle CDB/PDB 架构测试文档 |
8.2 工程目录结构
FGFDU/
├── Makefile # 构建脚本(GNU Make)
├── bin/ # 编译产物(fgfdu / fgfdu.exe)
├── include/ # 头文件
│ ├── fgfdu.h # 主头文件:版本、类型、常量
│ ├── cli/cli.h # 命令行接口
│ ├── identify/ # 数据库块识别引擎
│ ├── io/ # I/O 抽象层
│ ├── lvm/ # LVM 元数据解析
│ ├── partition/ # 分区表解析
│ ├── platform/ # 平台抽象(Linux/Windows)
│ ├── recover/ # 恢复引擎
│ ├── scan/ # 扫描引擎
│ └── unload/ # Oracle 全库卸载
├── src/ # 源文件(与 include 一一对应)
├── obj/ # 编译中间产物
├── tests/ # 测试数据生成器与单元测试
│ ├── make_fake_dev.c # 生成扁平设备镜像
│ ├── make_mbr_dev.c # 生成 MBR 分区设备镜像
│ ├── make_lvm_dev.c # 生成 LVM PV 设备镜像
│ ├── make_oracle_unload_dev.c # 生成 Oracle 数据字典镜像
│ ├── run_identify_tests.c # 识别引擎单元测试
│ ├── run_scan_smoke.c # 扫描冒烟测试
│ └── run_all_tests.sh # 一键全量测试脚本
└── docs/ # 文档目录
8.3 编译产物校验
# 大小约 855KB
ls -lh bin/fgfdu
# -rwxr-xr-x 1 root root 855K Aug 24 10:00 bin/fgfdu
# 静态链接、已 strip
file bin/fgfdu
# bin/fgfdu: ELF 64-bit LSB executable, x86_64, version 1 (GNU/Linux),
# statically linked, for GNU/Linux 2.6.32, stripped
# 无任何动态依赖
ldd bin/fgfdu
# not a dynamic executable
8.4 作者信息
作者:风哥
官方网站: http://www.fgedu.net.cn , http://www.itpux.com
数据库教程: https://edu.51cto.com/lecturer/8020378.html

浙公网安备 33010602011771号