数据库数据文件误删恢复工具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. 程序介绍
  2. 作者信息
  3. 程序功能与特性
  4. 支持环境
  5. 程序使用
  6. 程序各种案例场景与操作过程
  7. 常用问题与排查
  8. 附录

一、程序介绍

1.1 概述

FGFDU(全称 FGEDU File DUL,FGEDU 文件数据卸载与恢复工具)是一款面向数据库运维与灾难恢复场景的底层磁盘级数据恢复工具。它突破了传统文件系统恢复工具必须依赖 inode、目录项、文件系统元数据完整的局限,能够在不挂载文件系统、不访问任何元数据的前提下,通过直接扫描磁盘块层数据,依据各类数据库文件的"特征指纹"(magic number、头部签名、固定偏移字段、块校验值等)定位已被操作系统从目录项中移除、但磁盘物理块中数据尚未被覆写的数据文件,并把它们以原始字节的方式重新提取出来。

FGFDU 的设计目标是:在数据库因人为误操作(rm -rfmvShift+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 的核心恢复流程可以归纳为四步:

  1. 设备只读打开:使用系统调用 open(O_RDONLY) 打开块设备(/dev/sdX/dev/mapper/...)或镜像文件,整个生命周期内不会对源设备发起任何写操作。
  2. 块级特征扫描:以可配置的步长(默认按数据块大小,如 8K)顺序读取设备,对每个数据块调用内置的多数据库识别引擎,根据 magic number、头部签名、固定偏移字段、校验和等特征判断该块是否属于某个数据库文件。
  3. 片段聚合与去重:将相邻的、属于同一数据库文件的块合并为连续片段;对碎片化的文件尝试通过 maxrecover 模式合并,输出时按 <db_type>_<序号>_<置信度>pct<扩展名> 命名规则单独保存,并自动去重。
  4. 输出与归位:把恢复出的字节流写到 --output 指定的目录,文件权限设置为只读,配套生成运行日志;运维人员使用数据库自带的校验工具(如 dbvinnochecksum)校验块一致性后,再用 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 配置即可恢复。
  • 数据库全库 unloadunload 命令):当 Oracle 因控制文件损坏、SYSTEM 头块损坏、REDO 全部丢失等原因无法启动时,采用两趟扫描:第一趟解析数据字典(USER$/OBJ$/COL$)构建 data_obj_id → 用户名/表名/列名 映射;第二趟遍历所有数据块提取行数据,按用户名导出每张表为 CSV 文件。

1.4 适用场景

FGFDU 适合以下典型故障场景:

故障类型 描述 FGFDU 应对方式
误删数据文件 DBA 执行 rmmv 或在图形界面按 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:深度扫描模式,扇区级全盘扫描,速度最慢但最彻底
  • 数据库类型过滤:支持按 oraclemysqlpgsqlsqlserverdamengkingbaseyashanopengaussall 进行过滤,避免无关数据库误识别。

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。
  • 工作流程
    1. 解析磁盘上的 MBR/GPT 分区表(即使部分损坏也能尽力解析);
    2. 以 1MB 为步长扫描全盘,通过文件系统超级块签名发现丢失的分区边界;
    3. 对每个识别到的分区,在其字节范围内运行扫描/恢复引擎;
    4. 将所有分区中恢复的数据库文件汇总输出。

3.1.5 LVM 故障恢复(lvm 命令)

  • 用途:当 LVM2 的 PV/VG/LV 元数据损坏,导致逻辑卷无法挂载或 lvdisplay 无法识别时,直接从物理设备解析 LVM 元数据并恢复逻辑卷中的数据库文件。
  • 支持场景:VG 元数据损坏、LV 配置丢失、/etc/lvm/backup 被删、多 PV 组成的 VG(单 PV 设备恢复,跨 PV 条带化 LV 为近似映射)。
  • 工作流程
    1. 扫描设备前 4MB 查找 LVM2 PV 标签(LABELONE 魔术字);
    2. 解析 PV 头部:PV UUID、设备大小、数据区位置、元数据区位置;
    3. 读取并解析 LVM2 文本元数据,重建 VG/PV/LV 结构;
    4. 根据 LV 段映射(segment)构建 LE→PE(逻辑盘区→物理盘区)映射表;
    5. 通过 LE→PE 映射直接读取逻辑卷数据,识别并恢复数据库文件。
  • 核心优势无需主机 LVM 配置即可恢复,适用于 /etc/lvm/backup 全部丢失等极端场景。

3.1.6 数据库全库卸载(unload 命令)

  • 用途:当 Oracle 数据库因控制文件损坏、SYSTEM 头块损坏、REDO 日志全部丢失等原因无法启动(无法 MOUNT/OPEN),传统 RMAN / Data Pump / expdp 全部失效时,直接从数据文件按用户名导出所有表为 CSV 文件
  • 适用数据库:Oracle 9i ~ 26ai(含 CDB/PDB 架构)。
  • 工作原理
    1. 第一趟扫描:解析 Oracle 数据字典(USER$/OBJ$/COL$),构建 data_obj_id → 用户名/表名/列名 映射;
    2. 第二趟扫描:遍历所有数据块,提取行数据,按用户名/表名写入 CSV 文件。
  • 输出目录结构
    • <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-dirmaxrecover 专用,提供原始数据目录路径作为提示,提升识别率。

3.2.6 完善的工程化与可测试性

  • 模块化源码结构platform / io / scan / identify / recover / partition / lvm / unload / cli 各司其职,便于维护与扩展。
  • 配套测试数据生成器make_fake_devmake_mbr_devmake_lvm_devmake_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 引擎) .wtWiredTiger*
Redis 全系列 dump.rdbappendonly.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:仅 Oracle
  • mysql:仅 MySQL InnoDB
  • pgsqlpostgresql:仅 PostgreSQL
  • sqlserver:仅 SQL Server
  • dameng:仅达梦
  • 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

工具会自动完成:

  1. 尽力解析残留的 MBR/GPT 分区表;
  2. 以 1MB 步长扫描文件系统超级块签名(ext2/3/4、XFS、NTFS、btrfs、LVM PV)发现丢失分区;
  3. 在每个分区字节范围内运行数据库文件扫描恢复;
  4. 汇总所有分区中恢复的数据库文件。

预期输出示例:

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

工具会自动完成:

  1. 扫描 LABELONE 魔术字定位 LVM2 PV 标签;
  2. 解析 PV 头部和元数据区文本,重建 VG/PV/LV 结构;
  3. 根据 LV 段映射构建 LE→PE 映射表;
  4. 通过映射直接读取逻辑卷数据,识别并恢复数据库文件。

核心优势:无需主机 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 可直接用 sqlldrLOAD DATA INFILECOPY 等方式导入到新数据库中。

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: 能恢复被 shreddd if=/dev/zero 覆写过的文件吗?

A不能。被覆写的数据无法用任何软件恢复。FGFDU 仅针对"删除但尚未被覆写"的块。这也是为什么强调"数据丢失后第一时间停库、停止写入"——任何写入都可能覆写掉可恢复的数据。

Q3: 恢复出来的文件块不连续怎么办?

A:FGFDU 的 maxrecover 模式会自动尝试合并碎片。对于极度碎片化的文件,置信度会降低(< 50%)。恢复后建议用数据库自带工具校验:

  • Oracle:dbv file=xxx.dbf blocksize=8192 检查坏块
  • MySQL:innochecksum xxx.ibd 校验页一致性
  • 若坏块较多,可在数据库启动后用 RMAN BLOCKRECOVERmysqlcheck --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 <设备> 命令,工具会:

  1. 尽力解析残留的 MBR/GPT 分区表;
  2. 全盘扫描文件系统超级块签名,发现丢失的分区边界;
  3. 在每个分区范围内运行数据库文件扫描恢复。

适用于 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:按顺序检查:

  1. 是否加了 sudo(扫描 /dev/sdX 必须 root);
  2. /dev/sdX 设备权限:ls -l /dev/sda1,正常应为 brw-rw---- 属主 root:disk;
  3. 是否有安全软件限制(AppArmor / SELinux),可临时 setenforce 0 或调整 AppArmor profile;
  4. 容器内扫描需确保容器以 --privileged 启动并挂载了 /dev

Q10: 提示 device or resource busy

A:设备正被其他进程占用。检查:

  1. 是否文件系统还挂载着:mount | grep sda1,先 umount
  2. 是否 LVM 还激活着:lvdisplay,先 lvchange -an
  3. 是否被其他恢复工具占用: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 通过块特征识别,无法直接得到原始文件名(文件名信息存储在文件系统目录项中,删除后已丢失)。归位方法:

  1. 根据文件大小、块数推断:例如 system01.dbf 通常最大且包含 SYSTEM 表空间标识;
  2. dbv 校验后看 kcvfh 头部信息中的 ts#(表空间号);
  3. 如果使用了 --target-dir 提示,FGFDU 会尽量按原始路径辅助匹配;
  4. 必要时按文件大小排序,先恢复最大的几个文件(通常对应 SYSTEM/USERS 表空间)。

Q14: 归位后数据库起不来怎么办?

A:按以下顺序排查:

  1. 权限chown oracle:oinstall *.dbf && chmod 640 *.dbf
  2. 文件名:核对 v$datafile 中记录的文件名与归位后的文件名是否一致;
  3. 块校验dbv file=xxx.dbf blocksize=8192,修复坏块;
  4. 控制文件:若控制文件也丢失,需要 CREATE CONTROLFILE 重建;
  5. REDO:若 REDO 全部丢失,可能需要 UNRECOVERABLE DATAFILE_allow_resetlogs_corruption
  6. 如果都不行:用 fgfdu unload 命令把表数据按用户名导出为 CSV,然后导入到新数据库。

7.5 收费与支持相关

Q15: 收费 / 开源吗?

A:FGFDU 由 FGEDU 提供,分免费版与商业版:

  • 免费版:包含核心扫描与恢复能力,覆盖主流数据库与常规故障场景;
  • 商业版:提供以下增强能力:
    • 更多数据库指纹(自研数据库、小众数据库);
    • Oracle ASM diskgroup 解析;
    • 7x24 工程师远程恢复支持;
    • 现场紧急救援服务;
    • 定制化恢复方案。

请联系 FGEDU 技术支持获取商业授权。

Q16: 出现文档未覆盖的问题怎么办?

A:按以下顺序自救:

  1. 查看运行日志:--output 目录下的 fgfdu.log
  2. fgfdu version 确认版本,升级到最新版后重试;
  3. --mode=deep 重新扫描;
  4. 把故障盘 dd 成镜像后用只读模式反复试验;
  5. 联系 FGEDU 技术支持:support@fgedu.com,提供 fgfdu.logfgfdu 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

posted @ 2026-08-30 10:58  风哥数据库教程  阅读(5)  评论(0)    收藏  举报