gongxiangp2/detailed-recovery-plan.md

451 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据恢复详细执行计划
## 目标
恢复 `/mnt/PoolOne/apps/youyidian-3d/uploads` 目录中被删除的数据。
## 当前状态确认
### 存储池信息
- **存储池名称**: PoolOne
- **配置类型**: raidz2(7块硬盘,可容忍2块硬盘故障)
- **存储池状态**: ONLINE(正常)
- **总容量**: 约50.5TB
- **已使用**: 约7.96TB
- **可用空间**: 约25.3TB
### 硬盘信息
7块 WDC WD80EFBX 8TB 硬盘:
1. ata-WDC_WD80EFBX-68AZZN0_VRGYN7GK-part2
2. ata-WDC_WD80EFBX-68AZZN0_VRGZW7VK-part2
3. ata-WDC_WD80EFBX-68AZZN0_VRGZT7LK-part2
4. ata-WDC_WD80EFBX-68AZZN0_VRGZVR2K-part2
5. ata-WDC_WD80EFBX-68AZZN0_VRH01V0K-part2
6. ata-WDC_WD80EFBX-68AZZN0_VRGZSHZK-part2
7. ata-WDC_WD80EFBX-68AZZN0_VRGSYK4K-part2
### uploads目录状态
- **路径**: `/mnt/PoolOne/apps/youyidian-3d/uploads`
- **当前状态**: 目录存在但为空(512字节)
- **数据丢失时间**: 2026年1月13日09:15
- **删除操作**: 由部署脚本的 `rm -rf` 或 `git clean -fd` 命令导致
### 数据集信息
- **类型**: filesystem(数据集,不是Zvol)
- **挂载点**: `/mnt/PoolOne`
- **快照状态**: 无快照可用
## 恢复方案详细步骤
## 方案1:Ubuntu设备 + ZFS存储池导入(最优先)⭐⭐⭐⭐⭐
### 前置条件检查清单
#### 硬件要求
- [ ] Ubuntu设备(Ubuntu 20.04或更高版本)
- [ ] 所有7块硬盘(必须全部连接)
- [ ] 足够的SATA接口(7个)或USB 3.0硬盘盒
- [ ] 足够的电源供应(7块8TB硬盘需要大量电源)
- [ ] **至少2TB可用空间**(用于恢复的文件,实际需要恢复的数据约1.5TB)
#### 软件要求
- [ ] Ubuntu系统已安装
- [ ] 网络连接(用于下载工具)
- [ ] root或sudo权限
### 详细执行步骤
#### 阶段1:Ubuntu环境准备
**步骤1.1:验证Ubuntu版本**
```bash
# 检查Ubuntu版本
lsb_release -a
# 要求:Ubuntu 20.04或更高版本
# 如果版本过低,需要升级或使用Live CD
```
**步骤1.2:安装ZFS工具**
```bash
# 更新软件包列表
sudo apt-get update
# 安装ZFS工具
sudo apt-get install -y zfsutils-linux
# 验证安装
zfs --version
zpool --version
# 预期输出:ZFS版本信息
```
**步骤1.3:安装数据恢复工具**
```bash
# 安装testdisk和photorec
sudo apt-get install -y testdisk
# 安装其他恢复工具
sudo apt-get install -y foremost scalpel
# 验证安装
testdisk --version
photorec --version
```
**步骤1.4:创建恢复工作目录**
```bash
# 创建工作目录
RECOVERY_DIR="/tmp/recovery_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$RECOVERY_DIR"
echo "恢复目录: $RECOVERY_DIR"
# 确保有足够空间(至少100GB)
df -h /tmp
```
#### 阶段2:硬盘连接和识别
**步骤2.1:连接所有硬盘**
**选项A:直接SATA连接**
- 将7块硬盘连接到Ubuntu设备的SATA接口
- 确保电源充足(每块硬盘约10W,7块约70W)
- 开机后检查设备
**选项B:USB硬盘盒(推荐)**
- 使用USB 3.0多盘位硬盘盒
- 或使用多个单盘位USB硬盘盒
- 确保USB 3.0接口(速度要求)
**步骤2.2:识别硬盘设备**
```bash
# 查看所有块设备
lsblk
# 预期输出:应该能看到7块硬盘(sdc, sdd, sde, sdf, sdg, sdh, sdi等)
# 查看硬盘ID(匹配TrueNAS中的硬盘ID)
ls -la /dev/disk/by-id/ | grep WDC_WD80EFBX
# 预期输出:应该能看到7块硬盘的part2分区,例如:
# ata-WDC_WD80EFBX-68AZZN0_VRGYN7GK-part2 -> ../../sdc2
# ata-WDC_WD80EFBX-68AZZN0_VRGZW7VK-part2 -> ../../sdd2
# ... (共7块)
# 记录设备映射关系
ls -la /dev/disk/by-id/ | grep WDC_WD80EFBX > "$RECOVERY_DIR/disk-mapping.txt"
cat "$RECOVERY_DIR/disk-mapping.txt"
```
**步骤2.3:验证所有硬盘已连接**
```bash
# 统计匹配的硬盘数量
DISK_COUNT=$(ls -la /dev/disk/by-id/ | grep -c "WDC_WD80EFBX.*part2")
echo "找到硬盘数量: $DISK_COUNT"
# 必须等于7
if [ "$DISK_COUNT" -eq 7 ]; then
echo "✅ 所有7块硬盘已连接"
else
echo "❌ 错误: 只找到 $DISK_COUNT 块硬盘,需要7块"
exit 1
fi
```
#### 阶段3:导入ZFS存储池
**步骤3.1:查看可导入的存储池**
```bash
# 查看可导入的存储池
sudo zpool import
# 预期输出:
# pool: PoolOne
# id: 162731025200795572
# state: ONLINE
# action: The pool can be imported using its name or numeric identifier.
```
**步骤3.2:导入存储池(只读模式尝试)**
```bash
# 先尝试只读导入(如果支持)
# 注意:zpool import 默认是读写模式,但我们可以先检查
# 查看导入选项
sudo zpool import -n PoolOne
# 实际导入(使用-f强制,因为来自不同系统)
sudo zpool import -f PoolOne
# 预期输出:存储池导入成功
```
**步骤3.3:验证存储池状态**
```bash
# 检查存储池状态
sudo zpool status PoolOne
# 预期输出:
# pool: PoolOne
# state: ONLINE
# status: 所有硬盘状态为ONLINE
# 检查存储池信息
sudo zpool list PoolOne
# 查看数据集列表
sudo zfs list -o name,type,used,avail,refer,mountpoint -r PoolOne | head -20
```
**步骤3.4:确认挂载点**
```bash
# 查看挂载点
df -h | grep PoolOne
# 可能的位置:
# /PoolOne 或 /mnt/PoolOne
# 检查uploads目录
if [ -d "/PoolOne/apps/youyidian-3d/uploads" ]; then
UPLOADS_PATH="/PoolOne/apps/youyidian-3d/uploads"
elif [ -d "/mnt/PoolOne/apps/youyidian-3d/uploads" ]; then
UPLOADS_PATH="/mnt/PoolOne/apps/youyidian-3d/uploads"
else
# 查找uploads目录
UPLOADS_PATH=$(find /PoolOne /mnt/PoolOne -type d -name "uploads" -path "*/youyidian-3d/*" 2>/dev/null | head -1)
fi
echo "uploads目录路径: $UPLOADS_PATH"
```
#### 阶段4:数据状态检查和分析
**步骤4.1:检查uploads目录状态**
```bash
# 查看目录内容
ls -lah "$UPLOADS_PATH"
# 查看目录大小
du -sh "$UPLOADS_PATH"
# 统计文件数量
find "$UPLOADS_PATH" -type f 2>/dev/null | wc -l
# 查看目录的inode信息
stat "$UPLOADS_PATH"
```
**步骤4.2:查看ZFS操作历史**
```bash
# 查看存储池的操作历史
sudo zfs history PoolOne > "$RECOVERY_DIR/zfs-history-full.txt"
# 查看最近100条记录
tail -100 "$RECOVERY_DIR/zfs-history-full.txt"
# 搜索与uploads或删除相关的操作
grep -i "upload\|delete\|rm\|clean" "$RECOVERY_DIR/zfs-history-full.txt" > "$RECOVERY_DIR/zfs-history-uploads.txt"
cat "$RECOVERY_DIR/zfs-history-uploads.txt"
```
**步骤4.3:导出ZFS元数据**
```bash
# 导出ZFS标签信息
sudo zdb -l PoolOne > "$RECOVERY_DIR/zfs-label.txt" 2>&1
# 导出ZFS对象信息(可能需要较长时间)
echo "正在导出ZFS对象信息(这可能需要很长时间)..."
sudo zdb -o PoolOne > "$RECOVERY_DIR/zfs-objects.txt" 2>&1 &
# 导出事务组信息
sudo zdb -u PoolOne > "$RECOVERY_DIR/zfs-uberblock.txt" 2>&1
# 导出数据集信息
sudo zdb -d PoolOne > "$RECOVERY_DIR/zfs-dataset.txt" 2>&1
echo "元数据导出完成,文件保存在: $RECOVERY_DIR"
```
**步骤4.4:分析ZFS元数据**
```bash
# 在对象信息中搜索uploads相关的内容
if [ -f "$RECOVERY_DIR/zfs-objects.txt" ]; then
echo "搜索uploads相关的对象..."
grep -i "upload" "$RECOVERY_DIR/zfs-objects.txt" | head -50 > "$RECOVERY_DIR/zfs-objects-uploads.txt"
cat "$RECOVERY_DIR/zfs-objects-uploads.txt"
fi
# 查看事务组信息(可能包含删除操作的时间戳)
if [ -f "$RECOVERY_DIR/zfs-uberblock.txt" ]; then
echo "查看事务组信息..."
head -100 "$RECOVERY_DIR/zfs-uberblock.txt"
fi
```
#### 阶段5:尝试恢复方法
**方法5.1:ZFS调试工具深度分析**
```bash
# 查看块指针信息
sudo zdb -bb PoolOne > "$RECOVERY_DIR/zfs-blocks.txt" 2>&1
# 查看数据集树结构
sudo zdb -P -t PoolOne > "$RECOVERY_DIR/zfs-tree.txt" 2>&1
# 尝试查找已删除的对象ID
# 这需要深入分析ZFS的内部结构
```
**方法5.2:文件系统级别扫描(如果ZFS允许)**
```bash
# 注意:ZFS限制了底层访问,此方法效果有限
# 在uploads目录中使用find查找可能的残留
find "$UPLOADS_PATH" -type f -name ".*" 2>/dev/null
# 检查是否有隐藏文件
find "$UPLOADS_PATH" -type f 2>/dev/null
```
**方法5.3:底层块设备扫描(最后手段)**
```bash
# ⚠️ 警告:此操作需要导出存储池,风险较高
# 1. 导出存储池
sudo zfs unmount PoolOne
sudo zpool export PoolOne
# 2. 对每块硬盘进行扫描
# 注意:raidz2配置下,单块硬盘无法完整恢复数据
# 识别设备(从之前的记录中获取)
# 假设设备为:sdc2, sdd2, sde2, sdf2, sdg2, sdh2, sdi2
# 使用photorec扫描(交互式)
# sudo photorec /dev/sdc2
# 或使用命令行模式
# sudo photorec /log /d /tmp/recovered /cmd /dev/sdc2 partition_none,fileopt,everything,enable,search
```
## 方案2:专业ZFS恢复工具
### 工具选项
#### 选项2.1:R-Studio(商业软件)
- **支持ZFS**: 是
- **支持raidz2**: 是
- **价格**: 约$80-900(根据版本)
- **使用方法**:
1. 在Ubuntu设备上安装R-Studio
2. 导入ZFS存储池
3. 使用ZFS恢复功能
#### 选项2.2:UFS Explorer(商业软件)
- **支持ZFS**: 是
- **支持raidz2**: 是
- **价格**: 约$50-500
- **使用方法**: 类似R-Studio
#### 选项2.3:专业数据恢复服务
- **优势**: 专业工具和技术
- **劣势**: 成本高(通常数万元)
- **适用**: 数据非常重要且预算充足
## 方案3:ZFS元数据手动分析(高级)
### 前提条件
- 深入理解ZFS文件系统结构
- 熟悉ZFS元数据格式
- 编程能力(可能需要编写脚本)
### 步骤概述
1. 导出所有ZFS元数据
2. 分析对象ID映射
3. 查找已删除文件的元数据
4. 重建目录结构
5. 提取数据块
## 不确定因素排查清单
### ✅ 已确认的信息
- [x] 存储池名称:PoolOne
- [x] 配置类型:raidz2(7块硬盘)
- [x] 存储池状态:ONLINE
- [x] uploads目录路径:/mnt/PoolOne/apps/youyidian-3d/uploads
- [x] 数据集类型:filesystem(不是Zvol)
- [x] 快照状态:无快照
- [x] 硬盘型号:WDC WD80EFBX 8TB
- [x] 数据丢失时间:2026年1月13日09:15
### ❓ 需要确认的信息
- [ ] Ubuntu设备的具体型号和配置
- [ ] Ubuntu设备的SATA接口数量
- [ ] 是否有USB硬盘盒可用
- [ ] Ubuntu设备的电源容量
- [ ] Ubuntu系统版本
- [ ] 是否有足够的存储空间(至少100GB)
- [ ] ZFS版本兼容性(TrueNAS使用的ZFS版本 vs Ubuntu的ZFS版本)
- [ ] 存储池导入后是否会自动挂载
- [ ] 存储池导入后的挂载点路径
### ⚠️ 风险和限制
- [ ] ZFS删除机制:ZFS不提供原生的undelete功能
- [ ] raidz2配置:数据条带化分布,需要所有硬盘
- [ ] 时间窗口:删除后时间越长,恢复可能性越低
- [ ] 写入操作:如果删除后有大量写入,数据可能已被覆盖
- [ ] ZFS版本兼容性:不同版本的ZFS可能有兼容性问题
## 执行优先级
### 第一优先级(立即执行)
1. ✅ **准备Ubuntu设备**
2. ✅ **连接所有7块硬盘**
3. ✅ **导入ZFS存储池**
4. ✅ **检查数据状态**
5. ✅ **查看ZFS历史记录**
### 第二优先级(深度分析)
1. ✅ **导出ZFS元数据**
2. ✅ **分析ZFS历史记录**
3. ✅ **搜索uploads相关对象**
### 第三优先级(尝试恢复)
1. ✅ **使用ZFS调试工具**
2. ✅ **分析ZFS元数据**
3. ✅ **尝试手动恢复**
### 第四优先级(最后手段)
1. ⚠️ **底层块设备扫描**(风险高)
2. ⚠️ **专业数据恢复工具/服务**
## 成功概率评估
| 方案 | 成功概率 | 原因 |
|------|---------|------|
| ZFS历史记录分析 | 10% | ZFS历史记录可能包含删除操作的线索,但无法直接恢复数据 |
| ZFS元数据分析 | 20% | 需要深入理解ZFS结构,可能找到已删除对象的元数据 |
| 底层块设备扫描 | 5% | raidz2配置和ZFS限制使恢复非常困难 |
| 专业工具/服务 | 60-80% | 专业工具和技术,但成本高 |
## 关键检查点
在执行每个阶段后,需要检查:
1. ✅ 所有硬盘是否正常识别
2. ✅ 存储池是否成功导入
3. ✅ uploads目录是否存在
4. ✅ ZFS历史记录是否包含有用信息
5. ✅ ZFS元数据是否成功导出
6. ✅ 是否有任何恢复线索
## 下一步行动
1. **确认Ubuntu设备准备情况**
2. **确认所有7块硬盘可以连接**
3. **开始执行方案1的阶段1和阶段2**
4. **根据检查结果决定后续步骤**