# ZFS-to-Ceph Migration Analysis (2026-07-03)

## Context

User wants to decommission osd.1 (USB-connected Hitachi HDD on proxmox1, slow BlueStore ops)
and replace it with disks from the ZFS pool on 10.0.30.100. Initial assumption was "9×2.7TB"
but actual inventory revealed 4×3TB in RAIDZ2 + 2 free disks + 2 already in Ceph.

## Disk Inventory (10.0.30.100, 2026-07-03)

| Disk | Model | Serial | Size | POH | Age | SMART | Role | Verdict |
|------|-------|--------|------|-----|-----|-------|------|---------|
| sda | Crucial MX300 SSD | 164914EEB886 | 275GB | 81,871 | 9.3y | ✅ 0/0/0 | Boot SSD (swap→DB for osd.8) | Keep — sda3 now DB device |
| sdb | WD30EFRX Red+ | WCC4N4VRJ5UU | 3TB | 81,786 | 9.3y | ✅ 0/0/0, CRC=3 | ZFS pool | Oldest in pool, first offline candidate |
| sdc | WD30EZRX Green | WMC1T2256499 | 3TB | 89,262 | 10.2y | ⛔ 371 pending, 243 uncorr | Free | REJECT — defective |
| sdd | WD30EFRX Red+ | WCC4N4SVR8JL | 3TB | 57,925 | 6.6y | ⚠️ 16 pending, 15 uncorr, Self-test FAIL | Free | REJECT — confirmed read failure |
| sde | WD30EFRX Red+ | WMC4N2399595 | 3TB | 104,327 | 11.9y | ✅ 0/0/0 | Ceph osd.8 | Active, very old. NOW HAS DB ON SSD |
| sdf | WD30EFRX Red+ | WMC4N2400243 | 3TB | 98,475 | 11.2y | ✅ 0/0/0 | Ceph osd.9 | Active, very old. NO DB device |
| sdg | WD30EFZX Purple | WX12DA01FUA7 | 3TB | 30,901 | 3.5y | ✅ 0/0/0 | ZFS pool | Best candidate |
| sdh | WD30EFZX Purple | WX12DA0R1NFH | 3TB | 30,901 | 3.5y | ✅ 0/0/0 | ZFS pool | Best candidate |
| sdi | WD30EFZX Purple | WX22DA0D7EP3 | 3TB | 30,900 | 3.5y | ✅ 0/0/0 | ZFS pool | Best candidate |

## SMART Self-Test History (sdd)

```
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Short offline       Completed: read failure       90%     57925         62939576
# 2  Short offline       Completed without error       00%     50673         -
# 3  Extended offline    Completed: read failure       10%     50659         63009384
# 4  Short offline       Completed without error       00%     50651         -
```

Two read failures at LBA ~63M (~32GB region), 7000h apart. Progressive degradation.

## badblocks Test (sdd)

- Command: `badblocks -wsv -b 4096 /dev/sdd`
- Started: 2026-07-03 12:25:31 CEST
- Killed by user request at ~3.4% (Pattern 1/4: 0xaa)
- Errors found: 0 (but test was aborted early)
- Log: `/tmp/badblocks_sdd.log` on 10.0.30.100
- Verdict: Inconclusive (early abort), but SMART self-test failure already disqualifies disk

## ZFS Pool Details

```
Pool: pool01_n2_redundant
Type: RAIDZ2 (2 parity)
Disks: sdg, sdh, sdi, sdb (4× 2.73TB)
Raw: 10.9TB
Usable: ~5.46TB (2 data + 2 parity)
Used: 3.63TB (66%)
Free: 1.87TB
Fragmentation: 57%
Health: ONLINE, 0 errors
Dedup: 1.12x
Scrub: Monthly, last 2026-06-28, 0 errors
```

Datasets: Docker volumes, TimeMachine (~951GB), proxmox_nfs (~963GB), HomeAssistant.

## Ceph State (2026-07-03)

- Health: HEALTH_WARN (BLUESTORE_SLOW_OP_ALERT on osd.0 & osd.1)
- 10 OSDs up/in, 12TB raw, 5.1TB used, 7.0TB free
- osd.1: USB Hitachi HDD 3.6TiB on proxmox1 (10.0.20.10), slow ops
- 7 pools active

## Migration Strategies Evaluated

### Option A: One-shot migration (recommended)
1. Migrate all 3.63TB ZFS data → Ceph (has 7.0TB free)
2. `zpool destroy` → all 4 disks freed
3. Create 4 new Ceph OSDs on n5pro
4. Purge osd.1

### Option B: Phased with ZFS degradation (CHOSEN)
1. `zpool offline pool sdb` (oldest disk) → wipe → Ceph OSD (+3TB)
2. ZFS now degraded (1 parity left), migrate data to Ceph
3. `zpool destroy` → wipe sdg/sdh/sdi → 3 more Ceph OSDs (+9TB)

**Chosen**: Option B — allows incremental Ceph growth while ZFS data is migrated gradually.

### Rejected: 2-disk offline
Offlining 2 disks from RAIDZ2 leaves 0 redundancy. Too risky during active data migration.

## OSD DB/WAL Acceleration Analysis (2026-07-03)

### Which OSDs Have/Lack DB Devices

| OSD | Host | HDD | DB on Flash? | Flash Available | Free on Flash |
|-----|------|-----|-------------|-----------------|---------------|
| osd.1 | proxmox1 | sdc 3.6TB | ❌ | ✅ 1TB Toshiba NVMe | 848 GB — BUT osd.1 being decommissioned |
| osd.7 | proxmox7 | sda 982GB | ✅ 50GB ceph-db | ✅ 256GB Toshiba NVMe | 110 GB |
| osd.8 | ubuntu(.30.100) | sde 2.7TB | ✅ NOW 30GB on sda3 | 256GB Crucial SSD | 0 (swap consumed) |
| osd.9 | ubuntu(.30.100) | sdf 2.7TB | ❌ | Same SSD, no space | ❌ Needs root shrink or new SSD |
| osd.10 | proxmox6 | sda 982GB | ✅ 50GB ceph-db | ✅ 256GB Toshiba NVMe | 110 GB |

### DB Device Addition: osd.8 (2026-07-03, SUCCESSFUL)

**Method**: Repurposed 32GB swap partition (sda3) on boot SSD as LVM-backed DB device.

Steps taken:
1. `swapoff /dev/sda3` (1.5GB used, 6.4GB RAM free — safe)
2. `wipefs -a /dev/sda3`
3. `pvcreate /dev/sda3` → `vgcreate ceph-db-vg /dev/sda3` → `lvcreate -L 30G -n osd-8-db ceph-db-vg`
4. `systemctl stop ceph-osd@8`
5. `ceph-volume lvm new-db --osd-id 8 --osd-fsid <fsid> --target ceph-db-vg/osd-8-db`
6. `systemctl start ceph-osd@8`

Result: osd.8 up with `block.db → /dev/dm-2`, `devices = sda,sde`. BlueFS spillover warning (1.1GB on HDD, 231MB on SSD) — expected to clear as compaction migrates data.

### Key Lesson: ceph-bluestore-tool vs ceph-volume

`ceph-bluestore-tool --command bluefs-bdev-new-db` FAILS on Ceph Squid 19.2.x with `"No valid bdev label found"` — tried raw partition, LVM LV, with/without zap, as root and ceph user. The working tool is `ceph-volume lvm new-db` (requires LVM-formatted target, not raw partition).

## Key Lessons

1. **RAIDZ cannot shrink** — `zpool remove` doesn't work on RAIDZ vdevs. Only `zpool offline` (temporary) or `zpool destroy` (permanent) can free disks.
2. **SMART PASSED ≠ healthy** — sdd passed overall SMART assessment but had confirmed self-test read failures. Always check self-test log, not just overall health.
3. **Assumptions about disk counts are dangerous** — "9×2.7TB" was wrong; actual was 4×3TB in ZFS + 2 free + 2 in Ceph. Always verify with `lsblk` + `zpool status` before planning.
4. **badblocks -wsv is destructive and slow** — 4 patterns × ~5h per 3TB = ~20h total. Only run on disks committed to repurposing. Can be killed early if SMART already disqualifies.
5. **SSH key selection** — 10.0.30.100 accepts `~/.ssh/id_ed25519_proxmox` (root), NOT the Galera key from 1Password.
6. **ceph-bluestore-tool bluefs-bdev-new-db is broken on Squid** — Use `ceph-volume lvm new-db` instead. Requires LVM LV as target, not raw partition.
7. **BlueFS spillover after adding DB is normal** — Existing RocksDB SSTs stay on HDD, new writes go to flash. Warning clears as compaction progresses.
8. **Swap can be safely repurposed for DB** — If RAM is adequate (>4GB free with swap nearly empty), disabling swap to reclaim flash for Ceph DB is viable. Consider zram as swap replacement.
9. **ZFS has no defrag command** — Fragmentation (e.g. 57%) only affects freespace map efficiency, not file integrity. The ONLY way to "defrag" ZFS is: copy data elsewhere -> destroy pool -> recreate -> copy back. Irrelevant if migrating off ZFS entirely.
10. **RAIDZ disk removal is permanent degradation** — Pulling 1 disk from RAIDZ2 drops to RAIDZ1-equivalent (1 parity). ZFS marks the disk UNAVAIL but it stays in the vdev config. `zpool detach` does NOT work on RAIDZ members. Pool continues degraded until destroyed.
11. **zfs destroy -r enters D-state on degraded pools** — On RAIDZ2 with defective disks, `zfs destroy -r` can hang in uninterruptible I/O (D-state) for 10+ minutes. Cannot be killed. Plan accordingly -- run in background.
12. **ZFS async free lag** — After `rm -rf` on ZFS, `zfs list` shows OLD usage for minutes/hours. `du -sh` shows actual live data. The gap is TXG-async free, resolves automatically. Don't panic if `zfs list` says 290GB but `du` says 3GB.
13. **Background monitor processes block zfs destroy** — Processes with `cwd` inside the dataset (including your own polling loops) prevent `zfs destroy`. Use `lsof +D <path>` and `fuser -mv <path>` to find ALL blockers, kill them first.
14. **n5pro WAL/DB prep pattern** — Remove unused `pve/data` thin pool (0% allocated, not in storage.cfg) via `lvremove pve/data`, then `lvcreate -L 30G -n wal-db-osd-X pve` for each new OSD. Verified on n5pro (10.0.20.91, 128GB NVMe, gained 70GB for 2x 30GB DB LVs).
