惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
小众软件
小众软件
MongoDB | Blog
MongoDB | Blog
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
大猫的无限游戏
大猫的无限游戏
量子位
A
About on SuperTechFans
G
Google Developers Blog
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Vercel News
Vercel News
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
U
Unit 42
Apple Machine Learning Research
Apple Machine Learning Research

博客园 - 风哥数据库教程

数据库教程FGMT20‑Oracle容灾体系架构与数据库升级迁移方案 数据库教程FGMT19‑Oracle多租户容器架构与新特性总结 数据库教程FGMT18‑Oracle‑EMCC智能化集中运维管理系统 数据库教程FGMT17‑Oracle性能优化之故障诊断与性能优化 数据库教程FGMT16‑Oracle性能优化之操作系统诊断与分析 数据库教程FGMT15‑Oracle性能优化之物化视图与任务管理 数据库教程FGMT14‑Oracle性能优化之资源限制与资源管理 数据库教程FGMT13‑Oracle性能优化之数据仓库与分区表 数据库教程FGMT12‑Oracle性能诊断与综合分析 数据库教程FGMT11‑Oracle性能优化之性能收集与报告分析 数据库教程FGMT10‑Oracle性能优化之统计信息管理与维护 数据库教程FGMT09‑Oracle性能优化之执行计划与基线管理 数据库教程FGMT08‑Oracle性能优化之基准测试与案例分析 数据库教程FGMT06‑Oracle数据库日常管理维护操作 数据库教程FGMT07‑Oracle数据库备份恢复与数据迁移 数据库教程FGMT05‑Oracle数据库SQL语言开发与应用实战 数据库教程FGMT03‑生产环境Linux+Oracle19c+ASM安装配置与项目实战 数据库教程FGMT01‑Oracle数据库基础知识与版本特性 数据库教程FGMT00‑教程学习大纲与学习指南(第一部) MySQL 8/9集群InnoDB Cluster自动化安装过程-Fgedu MySQL8/9 MGR组复制集群安装自动化全过程-Fgedu MySQL8/9主从复制集群安装自动化全过程-Fgedu MySQL8.x/9.x数据库安装自动化全过程-Fgedu 异构数据库迁移全过程-FGO2ODB工具 从国外数据库迁移到国产数据库全过程-FGO2CDB工具 Oracle迁移到PostgreSQL数据库-FGOracle2PG工具 MySQL迁移到PostgreSQL数据库-FGMySQL2PG工具 Oracle 26ai数据库一键自动安装 for Fgedu Oracle 19c数据库一键自动安装 for Fgedu 华为高斯数据库恢复工具FGOGDU(FGEDU openGauss DUL)
数据库数据文件误删恢复工具FGFDU(FGEDU File DUL)
风哥数据库教程 · 2026-08-30 · via 博客园 - 风哥数据库教程

数据库数据文件误删恢复工具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 -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 的核心恢复流程可以归纳为四步:

1. **设备只读打开**:使用系统调用 `open(O_RDONLY)` 打开块设备(`/dev/sdX`、`/dev/mapper/...`)或镜像文件,整个生命周期内不会对源设备发起任何写操作。

2. **块级特征扫描**:以可配置的步长(默认按数据块大小,如 8K)顺序读取设备,对每个数据块调用内置的多数据库识别引擎,根据 magic number、头部签名、固定偏移字段、校验和等特征判断该块是否属于某个数据库文件。

3. **片段聚合与去重**:将相邻的、属于同一数据库文件的块合并为连续片段;对碎片化的文件尝试通过 `maxrecover` 模式合并,输出时按 `<db_type>_<序号>_<置信度>pct<扩展名>` 命名规则单独保存,并自动去重。

4. **输出与归位**:把恢复出的字节流写到 `--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。

- **工作流程**:

  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 支持的数据库](#44-支持的数据库)。

#### 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 环境(推荐)

```bash

# 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)

```bash

# 安装 MinGW-w64 + MSYS2

# 进入 MSYS2 shell

cd /c/fgedudb/FGFDU

make clean && make

# 产物:bin/fgfdu.exe

```

### 5.2 命令行总览

```bash

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

- `pgsql` 或 `postgresql`:仅 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 — 立即停止一切写入

```bash

# 立刻停库,不要 shutdown immediate(会写 checkpoint 覆盖更多块)

ps -ef | grep pmon | grep -v grep

kill -9 <pmon_pid>   # 或者 shutdown abort

# 不要启动任何可能写盘的服务

```

#### Step 2 — 确认故障盘

```bash

df -h /u01/app/oracle/oradata

# 假设对应块设备是 /dev/mapper/vg_oracle-lv_oradata

ls -l /dev/mapper/vg_oracle-lv_oradata

```

#### Step 3 — 扫描验证(先确认能识别)

```bash

# 找一块空盘,把恢复结果写到别的盘!!

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 — 最大恢复(生产推荐)

```bash

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 — 校验 + 归位

```bash

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

```bash

sudo systemctl stop mysqld   # 或 kill -9 mysqld_pid

# 不要再启动!

```

#### Step 2 — 执行恢复

```bash

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 — 校验 + 归位

```bash

# 用 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` 破坏、病毒覆盖、或误删,导致分区无法挂载。

```bash

# 自动解析残留分区表 + 全盘扫描丢失分区 + 恢复各分区中的数据库文件

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` 无法识别逻辑卷。

```bash

# 直接从物理设备解析 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

```bash

# 从整个磁盘设备 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

```bash

# 查看目录结构:按用户名分目录

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` 误删。

```bash

# 达梦 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 磁盘文件中的数据。

```bash

# 方式 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,一次扫描时间过长,希望分批执行。

```bash

# 第 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 <设备>` 命令,工具会:

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.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 编译产物校验

```bash

# 大小约 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