Many ZFS users have faced the nightmare scenario where zfs destroy
was mistakenly executed before zpool destroy
, leading to potential data loss. This typically happens during pool migration or restructuring operations.
First, stop all writes to the affected disks immediately. Then attempt to import the destroyed pool:
# List available destroyed pools
zpool import -D
# Import a specific destroyed pool
zpool import -D yourPoolName
If the import fails due to repartitioned disks, you'll need to recreate the exact original partition layout:
# Using fdisk to recreate exact partitions
fdisk /dev/sdX
# Create partitions with original start/end sectors
# Set partition type to Solaris / ZFS (usually type BF00)
ZFS stores changes in transaction groups (TXGs). To identify the last good state:
# View detailed transaction history
zpool history -il
When standard methods fail, consider these approaches:
1. Using zfs_revert Python Script
The zfs_revert-0.1.py
script can help revert to previous TXGs:
python zfs_revert-0.1.py /dev/sdX1
# Follow interactive prompts to select TXG to revert to
2. VM-Based Recovery
For complex cases, set up a VM with disk images:
# Create raw disk images from physical devices
dd if=/dev/sdX of=disk1.img bs=1M
# Configure VM with identical disk geometry
- Always maintain multiple verified backups before pool operations
- Use
zpool export
instead of destroy when possible - Consider snapshot-based migration instead of pool destruction
# Check pool status
zpool status
# Scrub for errors
zpool scrub tank
# Export pool safely
zpool export tank
If recovery attempts are unsuccessful, professional data recovery services specializing in ZFS may be your last resort. Some specialize in ZFS metadata reconstruction.
When facing data loss after zfs destroy
followed by zpool destroy
, we're dealing with a multi-layered recovery challenge. ZFS maintains transactional consistency through TXGs (transaction groups), but destructive operations present unique obstacles.
Begin with these essential commands to assess the damage:
# List available destroyed pools
zpool import -D
# View detailed pool history
zpool history -il
# Attempt read-only import
zpool import -o readonly=on -D -f damagedPool recoveryPool
The zfs_revert-0.1.py
script provides granular control over transaction groups. Here's an enhanced version with better error handling:
#!/usr/bin/python
import os
import sys
import struct
import subprocess
def revert_txg(device, txg):
try:
with open(device, 'r+b') as f:
# ZFS uberblock structure (simplified)
f.seek(0)
data = f.read(4096)
# Modify TXG in uberblock
new_data = data[:112] + struct.pack('<Q', txg) + data[120:]
f.seek(0)
f.write(new_data)
except Exception as e:
print(f"Error processing {device}: {str(e)}")
return False
return True
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: zfs_revert.py device txg")
sys.exit(1)
success = revert_txg(sys.argv[1], int(sys.argv[2]))
if success:
print(f"Successfully reverted {sys.argv[1]} to TXG {sys.argv[2]}")
When working with disk images in VMware, maintain consistent identifiers:
# Force import with changed device paths
zpool import -d /vmfs/devices/ -f -D recoveryPool
# Alternative device scanning
ls -l /dev/disk/by-id/ > disk_ids.txt
zpool import -d /dev/disk/by-id/ -D recoveryPool
For critical situations where standard tools fail:
# Create forensic images while preserving metadata
dd if=/dev/sdX of=recovery_image.img bs=1M conv=noerror,sync
# Scan for remaining ZFS structures
strings recovery_image.img | grep -A 5 -B 5 "zpool"
# Advanced hex editing (example for uberblock)
hexdump -C -n 256 -s 0x40000 recovery_image.img
Implement these safeguards in your ZFS management scripts:
#!/bin/bash
# Safe pool destruction wrapper
function safe_zpool_destroy {
local pool=$1
local safety_check=$(zfs list -t filesystem -r $pool | wc -l)
if [[ $safety_check -gt 1 ]]; then
echo "ERROR: Pool contains datasets. Use -r flag explicitly if intended."
return 1
fi
echo "Creating emergency backup..."
zfs snapshot -r ${pool}@emergency_destroy_$(date +%s)
zpool export $pool || return 1
zpool import $pool || return 1
zpool destroy $pool
}
When standard methods fail, consider:
- Using
zdb -e poolname
for low-level analysis - Extracting individual files with
photorec
ortestdisk
- Commercial tools like Klennet ZFS Recovery for complex cases
Essential practices for ZFS administrators:
# Always maintain multiple backups
zfs send pool/dataset@snapshot | ssh backup "zfs recv backup/dataset"
# Implement automatic safeguards
alias zfs-destroy='echo "Use explicit -r flag with caution" && false'
alias zpool-destroy='echo "Verify pool contents first" && false'