Ich glaube es müssen heute nicht mehr viele Worte verloren werden, wie großartig ZFS als Dateisystem ist. Das hat sich rumgesprochen. Hier wird aufgeführt wie neue Festplatten in einen ZFS Pool integriert werden und was die ersten Schritte damit sind, so das die eigenen Daten ein ordentliches Zuhause bekommen. In diesem Artikel werden die Festplatten vorbereitet, die ZFS Pools angelegt und einige Optimierungen vorgenommen.
NEU: Für ganz ungeduldige habe ich einen Konsole only Abschnitt. Da gibts nur Befehle, keine Erklärungen.
Letzte Aktualisierung:
glabel
und gpart
. Fehler behoben bei zpool create
. TRIM
und SCRUB
aktiviert. Platzhalter Dataset eingefügt.ada0 - ada3
aufgeführt.ada4 - ada5
.Bevor die Festplatten in einem ZFS-Pool zusammengefasst werden, empfehle ich einige Vorbereitungen zu treffen, um sicherzustellen, dass die Festplatten auf jeden Fall leer sind, immer das gleiche Partitionsschema haben und vor allem auch einen sinnvollen Namen tragen.
Mit gpart destroy DEVICE
wird die Festplatte einmal komplett von allem befreit, was später stören könnte.
Eine Liste mit den erkannten Festplatten lässt sich mit camcontrol devlist
erstellen:
<WDC WD40EFPX-68C6CN0 81.00A81> at scbus0 target 0 lun 0 (pass0,ada0)
<WDC WD40EFPX-68C6CN0 81.00A81> at scbus1 target 0 lun 0 (pass1,ada1)
<WDC WD40EFPX-68C6CN0 81.00A81> at scbus2 target 0 lun 0 (pass2,ada2)
<WDC WD40EFPX-68C6CN0 81.00A81> at scbus3 target 0 lun 0 (pass3,ada3)
<SAMSUNG MZ7LH480HAHQ-00005 HXT7404Q> at scbus4 target 0 lun 0 (pass4,ada4)
<SAMSUNG MZ7LH480HAHQ-00005 HXT7904Q> at scbus5 target 0 lun 0 (pass5,ada5)
<AHCI SGPIO Enclosure 2.00 0001> at scbus6 target 0 lun 0 (ses0,pass6)
<ATP NVMe M.2 2280 SSD A230W2EJ> at scbus7 target 0 lun 1 (pass7,nda0)
**Wichtig: Passt die Geräte an! Eventuell bereits auf den Festplatten vorhandene Daten werden unwiederbringlich zerstört.
gpart destroy -F ada0 # Zerstört die Partitionstabelle auf ada0
gpart destroy -F ada1
gpart destroy -F ada2
gpart destroy -F ada3
gpart destroy -F ada4
gpart destroy -F ada5
Mit gpart create -s TYPE DEVICE
bekommen die Festplatten eine gewisse Grundstruktur, was besonders für den späteren Fall wichtig ist, wenn eine Festplatte ausfällt und ersetzt werden muss.
gpart create -s gpt ada0 # Erstellt eine neue Partitionstabelle auf ada0
gpart create -s gpt ada1
gpart create -s gpt ada2
gpart create -s gpt ada3
gpart create -s gpt ada4
gpart create -s gpt ada5
Was hier schon deutlich wird, ada0 - ada5
ist wenig "griffig und nachvollziehbar", auch kann sich die Reihenfolge und die Gerätenamen durchaus mal ändern. Problematisch wird es auf jeden Fall, wenn die Festplatten mal auf einen neuen Server umgezogen werden, was die Gerätenamen komplett auf den Kopf stellt. Eine Zuordnung ist dann schwierig. Auch in einem größeren Festplattenverbund ist es mühsam, eine defekte Festplatte zu identifizieren und gezielt auszutauschen. Die Lösung: Um die Festplatte mit einem Namen ansprechen zu können, bekommt sie einfach einen. Am besten mit etwas, das sowieso schon auf der Festplatte steht: Die Seriennummer.
Ganz mutige können das auch in einer Schleife ablaufen lassen (ada0 ada1 ada2 ada3 ada4 ada5
anpassen!).
DEVICELIST="ada0 ada1 ada2 ada3 ada4 ada5"; for DEVICE in $DEVICELIST; do gpart create -s gpt $DEVICE && gpart add -t freebsd-zfs -l "$(camcontrol identify $DEVICE | sed -n 's/.*serial number.*\(.\{4\}\)$/\1/p')" -a 4K "$DEVICE"; done
Welche Festplatte dann welches Label erhalten hat, lässt sich mit diesem Befehl kontrollieren:
glabel list | grep -E "Geom name|1\. Name: gpt" | awk -F": " '/Geom name/ {geom=$2}/1\. Name/ {name=$2; print geom " = " name}' | sort
Wem die Schleife nicht geheuer ist, die einzelnen Schritte sind wie folgt:
Mit camcontrol identify DEVICE | sed -n 's/.*serial number.*\(.\{4\}\)$/\1/p'
werden die letzten 4 Stellen der Seriennummer ermittelt und notiert.
ada0: HPAS (aus serial number WD-XXXXXXXXHPAS)
ada1: E9EY (aus serial number WD-XXXXXXXXE9EY)
ada2: 46EE (aus serial number WD-XXXXXXXX46EE)
ada3: LLAK (aus serial number WD-XXXXXXXXLLAK)
ada4: 2482 (aus serial number SXXXXXXX2482)
ada5: 7815 (aus serial number SXXXXXXX7815)
Bei der Partitionierung mit gpart add -t FILESYSTEM -l LABEL -a BLOCKSIZE DEVICE
wird der ermittelte Name direkt als Label gespeichert. Praktisch, oder?
gpart add -t freebsd-zfs -l "HPAS" -a 4K "ada0" # Erstellt eine neue FreeBSD Partition mit dem Namen HPAS
gpart add -t freebsd-zfs -l "E9EY" -a 4K "ada1"
gpart add -t freebsd-zfs -l "46EE" -a 4K "ada2"
gpart add -t freebsd-zfs -l "LLAK" -a 4K "ada3"
gpart add -t freebsd-zfs -l "2482" -a 4K "ada4"
gpart add -t freebsd-zfs -l "7815" -a 4K "ada5"
Damit sind die Platten bereit, um mit zpool create -m MOUNTPOINT POOLNAME RAIDTYPE DEVICELIST
zu ZFS-Pools zusammengefasst zu werden. Hier wird nun deutlich, wie hilfreich die neu vergebenen Namen sind. Diese neuen Pools werden im klassischen TrueNAS-Stil unter /mnt/
gemountet.
zpool create -m /mnt/data data raidz2 /dev/gpt/HPAS /dev/gpt/E9EY /dev/gpt/46EE /dev/gpt/LLAK # Erstellt Zpool data als raidz2
zpool create -m /mnt/work work mirror /dev/gpt/2482 /dev/gpt/7815 # Erstellt Zpool work als Spiegelung
Das ist ein bisschen Geschmackssache. Aus meiner Sicht sind aber einige Attribute durchaus sinnvoll, um die Daten effizient zu speichern und die Festplatten zu entlasten. Dies wird mit sogenannten ZFS-Attributen erreicht, die später von der Hauptebene auf die darunter angelegten Volumes und Datasets vererbt werden. Daher ist es sinnvoll, diese direkt bei der Installation zu setzen.
zfs set compression=lz4
= Komprimiert Dateien im laufenden Betrieb und ermöglicht so die Speicherung von mehr Daten auf begrenztem Speicherplatzzfs set atime=off
= Verbesserung der Leistung auf Dateisystemen mit vielen kleinen Dateien, auf die häufig zugegriffen wirdzfs set xattr=sa
= Speichert erweiterte Attribute in Inodes, was zu weniger Festplattenanforderungen führtzfs set acltype=posixacl
= Ermöglicht die Verwendung von getfacl, setfacl
für zusätzliche Zugriffsrechtezfs set compression=lz4 atime=off xattr=sa acltype=posixacl data # Schreibt die Attribute auf den Pool data
zfs set compression=lz4 atime=off xattr=sa acltype=posixacl work
sysrc -f /etc/periodic.conf daily_scrub_zfs_enable="YES"
sysrc -f /etc/periodic.conf daily_trim_zfs_enable="YES"
sysrc -f /etc/periodic.conf daily_status_zfs_enable="YES"
zfs create data/reserved && zfs set reservation=5G data/reserved
zfs create work/reserved && zfs set reservation=5G work/reserved
zfs create zroot/reserved && zfs set reservation=5G zroot/reserved
Mit zpool status data
kann das Ergebnis überprüft werden.
pool: data
state: ONLINE
scan: scrub repaired 0B in 00:03:52 with 0 errors on Fri Nov 8 00:07:34 2024
config:
NAME STATE READ WRITE CKSUM
data ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
gpt/HPAS ONLINE 0 0 0
gpt/E9EY ONLINE 0 0 0
gpt/46EE ONLINE 0 0 0
gpt/LLAK ONLINE 0 0 0
Damit haben wir die Festplatten eingerichtet und die Daten können sicher gespeichert werden.
Festplatten gehen kaputt. Es ist keine Frage ob, sondern nur wann. Mit ZFS hat das seinen Schrecken verloren. Durch die doppelte Redundanz ist der Zeitdruck nicht so groß und durch die Einfachheit des Austausches wird es zur reinen Routine. Hier ist kurz erklärt, was zu tun ist, wenn Monit einen ZFS Fehler per E-Mail berichtet hat.
zpool status data
zur Identifizierung der Festplatte und wir sehen:
Die Festplatte ada1
mit dem Label E9EY
fehlt im Pool data
pool: data
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-2Q
scan: resilvered 37.0G in 00:07:13 with 0 errors on Fri Dec 13 19:37:47 2024
config:
NAME STATE READ WRITE CKSUM
data DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
gpt/HTYM ONLINE 0 0 0
15911638719903526001 UNAVAIL 0 0 0 was /dev/gpt/E9EY
gpt/46EE ONLINE 0 0 0
gpt/LLAK ONLINE 0 0 0
camcontrol devlist
identifizieren, welches der adaX
-Geräte die neue Festplatte ist = ada1
Hier darf es keine Verwechslungen geben!
<HGST HUS728T8TALE6L4 V8GNW9U0> at scbus0 target 0 lun 0 (pass0,ada0)
<HGST HUS728T8TALE6L4 V8GNW9U0> at scbus1 target 0 lun 0 (pass1,ada1)
<WDC WD40EFPX-68C6CN0 81.00A81> at scbus2 target 0 lun 0 (pass2,ada2)
<WDC WD40EFPX-68C6CN0 81.00A81> at scbus3 target 0 lun 0 (pass3,ada3)
<SAMSUNG MZ7LH480HAHQ-00005 HXT7404Q> at scbus4 target 0 lun 0 (pass4,ada4)
<SAMSUNG MZ7LH480HAHQ-00005 HXT7904Q> at scbus5 target 0 lun 0 (pass5,ada5)
<AHCI SGPIO Enclosure 2.00 0001> at scbus6 target 0 lun 0 (ses0,pass6)
<ATP NVMe M.2 2280 SSD A230W2EJ> at scbus7 target 0 lun 1 (pass7,nda0)
camcontrol identify ada1 | sed -n 's/.*serial number.*\(.\{4\}\)$/\1/p'
ermittelt die letzten vier Stellen der Seriennummer = HDSM
. Auf jeden Fall vergleichen, damit auch wirklich die richtige Festplatte "getroffen" wirdgpart destroy ada1
löscht die Festplatte damit sichergestellt wird, das auch wirklich nix drauf ist. Der Befehl erzeugt einen "Fehler" ala gpart: arg0 'ada1': Invalid argument
wenn es nichts zu zerstören gibt. Das kann dann ignoriert werden!gpart create -s gpt ada1
erstellt die GPT Partitionstabellegpart add -t freebsd-zfs -l HDSM -a 4K ada1
erstellte eine FreeBSD Partition mit dem Label HDSM
data
mit zpool replace POOLNAME OLDDISK NEWDISK
die alte durch neue Festplatte ersetzen, also in meinem Beispiel: zpool replace data gpt/E9EY gpt/HDSM
Am Beispiel mit ada0 - ada3
für zpool data
und ada4 - ada5
für zpool work
.
Wichtig: Passt die Geräte an! Eventuell bereits auf den Festplatten vorhandene Daten werden unwiederbringlich zerstört.
Voilá