[[zfs]]
 

ZFS

Dieses Dateisystem verwendet dynamische Inodes.

Stand 2010

Leider gibt es unter Linux (und NetBSD) kein natives (und freies) ZFS (-Kernelmodul), es muss per FUSE eingebunden werden.

Weiterhin gibt es mit ZFS im Zusammenhang mit großen Datenmengen und weniger als 4GB RAM Probleme. Unter FUSE (egal ob Linux oder NetBSD) gibt es noch eine deutliche Verschärfung dieser Probleme.

So ist bei mir in einem Test auf einem Rechner mit 2GB RAM der FUSE-Daemon immer ausgestiegen, wenn ich 300GB oder mehr auf die ZFS-Platte kopieren wollte (egal ob lokal oder übers Netz). ZFS ist immer bei ca. 300GB ausgestiegen, diese Tests habe ich mit verschiedenen Linuxdistributionen mehrfach durchgeführt.

Aus diesem Grund würde ich ZFS unter Linux nur für USB-Sticks verwenden, auf großen Speichermedien nur mit Solaris oder FreeBSD. Unter FreeBSD und Solaris ist es dagegen mein absolutes Lieblingsdateisystem! Soein genial einfach zu bedienendes und zuverlässiges Dateisystem ist momentan absolut konkurenzlos!

Unterstützung

ZFS wird natürlich von Solaris unterstützt, mittlerweile hat ja auch FreeBSD ZFS in den Kernel auf genommen und Apple setzt ebenfalls in McOS den ZFS-Treiber in der Art von FreeBSD erfolgreich ein. Nur Linux hat noch keine zufriedenstellende ZFS-Unterstützung zu bieten.

Allerdings gibt es hier drei verschiedene Lösungswege:

  1. Fuse (ist im Paketsystem fast jeder Linux-Distribution enthalten), hier arbeitet ein sehr aktueller ZFS-Treiber im User-Land, ist aber sehr langsam und instabil bei großen Datenmengen;
  2. mit kFreeBSD setzt man auf einem FreeBSD-Kernel ein Debian User-Land auf, diese Lösung ist beim schreiben sogar etwas schneller als das native FreeBSD aber beim lesen deutlich langsamer;
  3. mit KQ wird ein propritärer ZFS-Treiber für Linux bereit gestellt, der in etwa so schnell ist wie FreeBSD, der Treiber wird aber nur für Fedora, RHEL und Ubuntu angeboten;

Allgemeines

Eine komplette Platte auf die schnelle mit ZFS versehen:

# dd if=/dev/zero of=/dev/da4 bs=1k count=1000
# fdisk -I /dev/da4
# disklabel -w /dev/da4
# zpool create BACKUP3TB /dev/da4
# zpool list
NAME        SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
BACKUP3TB  2.72T   400K  2.72T     0%  ONLINE  -

Alle gemounteten ZFS-Pool's (Container des ZFS-Dateisystems) anzeigen:

# zpool list
NAME           SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
BACKUP3000GB  2.72T   714G  2.02T    25%  ONLINE  -
home          1.36T  1.30T  57.0G    95%  ONLINE  -

Alle gemounteten ZFS - on-disk's (Dateisysteme) anzeigen:

# zfs list               
NAME           USED  AVAIL  REFER  MOUNTPOINT
BACKUP3000GB   712G  1.98T   712G  /BACKUP3000GB
home          1.30T  38.0G  1.30T  /home

ZFS-SnapShot (Beispiel mit MySQL): http://dev.mysql.com/doc/refman/5.1/en/ha-zfs-replication.html

alle ZFS-Tuning-Parameter anzeigen:

# zfs get
missing property argument
usage:
      get [-rHp] [-d max] [-o field[,...]] [-s source[,...]]
          <"all" | property[,...]> [filesystem|volume|snapshot] ...
The following properties are supported:
      PROPERTY       EDIT  INHERIT   VALUES
      available        NO       NO   <size>
      compressratio    NO       NO   <1.00x or higher if compressed>
      creation         NO       NO   <date>
      mounted          NO       NO   yes | no
      origin           NO       NO   <snapshot>
      referenced       NO       NO   <size>
      type             NO       NO   filesystem | volume | snapshot
      used             NO       NO   <size>
      usedbychildren   NO       NO   <size>
      usedbydataset    NO       NO   <size>
      usedbyrefreservation  NO       NO   <size>
      usedbysnapshots  NO       NO   <size>
      aclinherit      YES      YES   discard | noallow | restricted | passthrough | passthrough-x
      aclmode         YES      YES   discard | groupmask | passthrough
      atime           YES      YES   on | off
      canmount        YES       NO   on | off | noauto
      casesensitivity  NO      YES   sensitive | insensitive | mixed
      checksum        YES      YES   on | off | fletcher2 | fletcher4 | sha256
      compression     YES      YES   on | off | lzjb | gzip | gzip-[1-9]
      copies          YES      YES   1 | 2 | 3
      devices         YES      YES   on | off
      exec            YES      YES   on | off
      jailed          YES      YES   on | off
      mountpoint      YES      YES   <path> | legacy | none
      nbmand          YES      YES   on | off
      normalization    NO      YES   none | formC | formD | formKC | formKD
      primarycache    YES      YES   all | none | metadata
      quota           YES       NO   <size> | none
      readonly        YES      YES   on | off
      recordsize      YES      YES   512 to 128k, power of 2
      refquota        YES       NO   <size> | none
      refreservation  YES       NO   <size> | none
      reservation     YES       NO   <size> | none
      secondarycache  YES      YES   all | none | metadata
      setuid          YES      YES   on | off
      shareiscsi      YES      YES   on | off | type=<type>
      sharenfs        YES      YES   on | off | share(1M) options
      sharesmb        YES      YES   on | off | sharemgr(1M) options
      snapdir         YES      YES   hidden | visible
      utf8only         NO      YES   on | off
      version         YES       NO   1 | 2 | 3 | current
      volblocksize     NO      YES   512 to 128k, power of 2
      volsize         YES       NO   <size>
      vscan           YES      YES   on | off
      xattr           YES      YES   on | off
Sizes are specified in bytes with standard units such as K, M, G, etc.
User-defined properties can be specified by using a name containing a colon (:).
# zpool get all                       
usage:
        get <"all" | property[,...]> <pool> ...
the following properties are supported:
        PROPERTY       EDIT  VALUES
        available        NO   <size>
        capacity         NO   <size>
        guid             NO   <guid>
        health           NO   <state>
        size             NO   <size>
        used             NO   <size>
        altroot         YES    <path>
        autoreplace     YES    on | off
        bootfs          YES    <filesystem>
        cachefile       YES    <file> | none
        delegation      YES    on | off
        failmode        YES    wait | continue | panic
        listsnapshots   YES    on | off
        version         YES    <version>

ZFS-„on-disk“-Version (Dateisystemversion) der gemounteten Pool's (ZFS-Dateisystem-Container) anzeigen:

# zfs get version               
NAME          PROPERTY  VALUE         SOURCE
BACKUP3000GB  version   3             -
home          version   3             -

ZFS-Pool-Version (Container-Version) des „BACKUP3000GB“-Pool's anzeigen:

# zpool get version BACKUP3000GB
NAME          PROPERTY  VALUE         SOURCE
BACKUP3000GB  version   14            default

ZFS-Pool-Version (Container-Version) des „home“-Pool's anzeigen:

# zpool get version home        
NAME  PROPERTY  VALUE    SOURCE
home  version   14       default

Statistik:

# zpool iostat
               capacity     operations    bandwidth
pool         used  avail   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
BACKUP3000GB   712G  2.02T      4     85   567K  10.4M
home        1.30T  59.7G     69      3  8.53M  26.1K
----------  -----  -----  -----  -----  -----  -----

Version der aktuellen ZFS-Installation anzeigen:

# zpool upgrade
This system is currently running ZFS pool version 14.
All pools are formatted using this version.

Version der aktuellen ZFS-Installation und alle Eigenschaften aller bisherigen ZFS-Pool-Versionen anzeigen:

# zpool upgrade -v
This system is currently running ZFS pool version 14.
The following versions are supported:
VER  DESCRIPTION
---  --------------------------------------------------------
 1   Initial ZFS version
 2   Ditto blocks (replicated metadata)
 3   Hot spares and double parity RAID-Z
 4   zpool history
 5   Compression using the gzip algorithm
 6   bootfs pool property
 7   Separate intent log devices
 8   Delegated administration
 9   refquota and refreservation properties
 10  Cache devices
 11  Improved scrub performance
 12  Snapshot properties
 13  snapused property
 14  passthrough-x aclinherit support
For more information on a particular version, including supported releases, see:
http://www.opensolaris.org/os/community/zfs/version/N
Where 'N' is the version number.

alle ZFS-Pool's auf aktuelle Version upgraden:

# zpool upgrade -a

Hat man einen Pool über USB angeschlossen, kann es sein, das der erste Zugriff recht lange dauert, wenn die Platten „eingeschlafen“ sind. Um die Platten vor einem regelmäßigen Zugriff automatisiert (z.B. per Cron) aufzuwecken, habe ich diese Kommandozeile geschrieben. Es setzt einfach nur ein „ls“ auf dem Mount-Point ab:

# for mp in $(zpool list -H -o name); do zmp="$(mount|egrep "^${mp}"|awk '{print $3}')";ls ${zmp}/ >/dev/null;done

ein ZFS-Volumen

Alle ZFS-Informationen anzeigen:

# zfs get -s local all home
# zfs get -s default all home
# zfs get -s temporary all home
# zfs get -s inherited all home
# zfs get -s none all home

NFS einschalten:

# zfs set sharenfs=on home

kontrollieren:

# zfs get -s local all home              
NAME  PROPERTY              VALUE                  SOURCE
home  sharenfs              on                     local

Alle gemounteten ZFS-Volumen anzeigen:

# zpool list
NAME   SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
home  1.36T  1.25T   114G    91%  ONLINE  -

Den status aller gemounteten ZFS-Volumen anzeigen:

# zpool status
  pool: home
 state: ONLINE
 scrub: none requested
config:
      NAME        STATE     READ WRITE CKSUM
      home        ONLINE       0     0     0
        mirror    ONLINE       0     0     0
          ad6     ONLINE       0     0     0
          ad8     ONLINE       0     0     0
errors: No known data errors

Das ZFS-Volumen BACKUP1000GB auflösen:

# zpool import BACKUP1000GB
# zpool destroy BACKUP1000GB
# zpool list

Test-Volumen auf Dateibasis anlegen

eine 100MB-Test-Pool-Datei erstellen

# dd if=/dev/zero of=/home/zfs.img bs=10240 count=10240

einen Pool erstellen

# zpool create tank /home/zfs.img

verfühgbare Pools zeigen

# zpool import -d /home/

Pool importieren

# zpool import -d /home/ tank

Pool exportieren

# zpool export tank

ZFS-Volumen auf Platte anlegen

einfaches Volumen

einen Pool erstellen

# zpool create BACKUP1000GB /dev/da2

verfühgbare Pools zeigen

# zpool import

Pool importieren

# zpool import BACKUP1000GB

Pool schreibgeschützt importieren

# zpool import -o ro BACKUP1000GB

Pool exportieren

# zpool export BACKUP1000GB

RAID-1 Volumen (Spiegel)

Der einfachste „Spiegel“ besteht aus 2 Platten. In der Beschreibung von SUN steht, dass der sinnvollste Spiegen aus 3 Platten besteht, da er in dieser Konfiguration die höchste Sicherheit bietet. Der Sicherheitsgewinn bei 4 und mehr Platten ist zu klein um wirtschaftlich sinnvoll zu sein.

einen Pool erstellen

# zpool create home mirror /dev/ad6 /dev/ad8

Pool exportieren

# zpool export home

verfühgbare Pools zeigen

# zpool import

Pool importieren

# zpool import home

Pool schreibgeschützt importieren

# zpool import -o ro home

Mount-Point

Konfiguriert man keinen speziellen Mount-Point, dann wird von ZFS automatisch ein Top-Level-Verzeichnis mit Pool-Namen angelegt (“/home“).

# zpool import home

ergibt das Verzeichnis:

/home

Will man einen speziellen mount-Point angeben, dann geht das so:

Beispiele

Beispiel 1

# zfs set mountpoint=/home/fritz home/fritz

Hier wird das Volumen (fritz) aus dem Pool (home) als “/home/fritz“ gemountet.

Beispiel aus dem Handbuch

# zfs create tank/home
# zfs set mountpoint=/export/zfs tank/home
# zfs set sharenfs=on tank/home
# zfs set compression=on tank/home

oder

# zfs create -o mountpoint=/export/zfs -o sharenfs=on -o compression=on tank/home

Und dann überprüfen:

# zfs get mountpoint,compression tank/home

Beispiel 2

# zfs set mountpoint=/opt tank/opt

Hier wird das Volumen (opt) aus dem Pool (tank) als “/opt“ gemountet.

Reparieren von Schäden am gesamten ZFS-Speicher-Pool

aus einem einfachen Pool ein RAID1 machen

In diesem Beispiel verwende ich an Stelle von Festplatten nur Dateien. Das ist zum testen besser geeignet.

So bekommt man ein gutes Gefühl für den Vorgang und kann so eine „Trockenübung“ vor dem „Ernstfall“ durchgehen.

Als erstes müssen wir uns die beiden Image-Dateien als Plattenersatz erstellen:

# dd if=/dev/zero of=/tmp/zfs1.img bs=10240 count=10240
# dd if=/dev/zero of=/tmp/zfs2.img bs=10240 count=10240

oder so

# truncate -s +100M /tmp/zfs1.img
# truncate -s +100M /tmp/zfs2.img

jetzt bauen wir unsere Ausgangsbasis, ein einfachen Pool:

# zpool create TEST01 /tmp/zfs1.img

so, das haben wir erstmal geschaft:

# zpool list
NAME     SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
TEST01  95.5M    84K  95.4M     0%  ONLINE  -

hier sieht man, dass es sich hier um unsere Dateien (und keine Festplatten) handelt:

# zpool status
  pool: TEST01
 state: ONLINE
 scrub: none requested
config:
        NAME             STATE     READ WRITE CKSUM
        TEST01           ONLINE       0     0     0
          /tmp/zfs1.img  ONLINE       0     0     0
errors: No known data errors

jetzt legen wir unsere Testdaten ab:

# echo "Test 001" > /TEST01/test.txt

und sie sind auch angekommen:

# cat /TEST01/test.txt
Test 001

hier machen wir aus unserem einfachen Pool ein RAID-1:

# zpool attach TEST01 /tmp/zfs1.img /tmp/zfs2.img

Wichtig: Die Platte mit den Daten muss als erstes (/tmp/zfs1.img) angegeben werden!

und wir sehen, dass der Pool jetzt aus zwei Dateien (Platten) besteht:

# zpool status
  pool: TEST01
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Wed Jan 19 00:49:32 2011
config:
        NAME               STATE     READ WRITE CKSUM
        TEST01             ONLINE       0     0     0
          mirror           ONLINE       0     0     0
            /tmp/zfs1.img  ONLINE       0     0     0
            /tmp/zfs2.img  ONLINE       0     0     0  96K resilvered
errors: No known data errors

und jetzt der finale Test, sind unsere Daten noch da?

# cat /TEST01/test.txt
Test 001

… es hat geklappt, die Daten sind erhalten geblieben! ;-)

einen Pool vergrößern (so etwas ähnliches wie RAID0)

Die Vorbereitungen sehen genauso aus, wie bei dem Test mit dem RAID-1:

# truncate -s +100M /tmp/zfs3.img
# truncate -s +100M /tmp/zfs4.img
# zpool create TEST02 /tmp/zfs3.img
# echo "Test 002" > /TEST01/test.txt
# cat /TEST02/test.txt
Test 001

und jetzt werden die beiden Platten zusammen gesetzt, hierbei bleiben

# zpool add TEST02 /tmp/zfs4.img

die Daten sind noch da:

# cat /TEST02/test.txt
Test 001

der Pool ist jetzt doppelt so groß:

# zpool list
NAME        SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
TEST02      191M   150K   191M     0%  1.00x  ONLINE  -

beide Platten sind im Pool und es ist kein Mirror:

# zpool status TEST02
  pool: TEST02
 state: ONLINE
 scrub: none requested
config:
        NAME             STATE     READ WRITE CKSUM
        TEST02           ONLINE       0     0     0
          /tmp/zfs3.img  ONLINE       0     0     0
          /tmp/zfs4.img  ONLINE       0     0     0
errors: No known data errors

ZFS-Probleme

ZFS: checksum mismatch

Das Problem sieht in der Logdatei wie folgt aus:

Mar 31 23:30:50 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=297610772480 size=131072
Mar 31 23:30:50 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=297610772480 size=131072
Mar 31 23:30:50 plebeian root: ZFS: zpool I/O failure, zpool=storage error=86
Mar 31 23:31:20 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=23159373824 size=131072
Mar 31 23:31:20 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=23159373824 size=131072
Mar 31 23:31:20 plebeian root: ZFS: zpool I/O failure, zpool=storage error=86
Mar 31 23:31:34 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=18063163392 size=131072
Mar 31 23:31:34 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=18063163392 size=131072
Mar 31 23:31:34 plebeian root: ZFS: zpool I/O failure, zpool=storage error=86
Mar 31 23:31:34 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=18062901248 size=131072
Mar 31 23:31:34 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=18062901248 size=131072
Mar 31 23:31:34 plebeian root: ZFS: zpool I/O failure, zpool=storage error=86
Mar 31 23:31:35 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=17453809664 size=131072
Mar 31 23:31:35 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=17453809664 size=131072
Mar 31 23:31:35 plebeian root: ZFS: zpool I/O failure, zpool=storage error=86
Mar 31 23:31:35 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=17453809664 size=131072
Mar 31 23:31:35 plebeian root: ZFS: checksum mismatch, zpool=storage path=/dev/ad4s1d.eli offset=17453809664 size=131072
Mar 31 23:31:35 plebeian root: ZFS: zpool I/O failure, zpool=storage error=86
# sysctl kern.smp.disabled=1

ZFS Tuning

Tuning is Evil

Tuning is often evil and should rarely be done.

First, consider that the default values are set by the people who know the most about the effects of the tuning on the software that they supply. If a better value exists, it should be the default. While alternative values might help a given workload, it could quite possibly degrade some other aspects of performance. Occasionally, catastrophically so.

interessante Optionen:

  • compression:“ der Speicherplatzbedarf sinkt dramatisch, ebenso sinkt die Datensicherheit;
  • deduplication:“ der Speicherplatzbedarf sinkt nur leicht (2-5GB bei 1TB) und die Geschwindigkeit sinkt ebenfalls;

Trivial

Die Speicherung oder Übertragung einer Informationseinheit (z. B. ein Bit) ist an die Speicherung oder Übertragung von Energie gekoppelt, da Information ohne ein Medium nicht existieren kann, d. h. Information ist an die Existenz unterscheidbarer Zustände gekoppelt. Da die Energie Quantisiert ist (es eine aller kleinste unteilbare Energiemenge gibt), ist eine Mindestmenge von Energie pro Informationseinheit notwendig, sonst geht die Information verloren. Um einen Speicherpool mit 128-Bit-Adressierung zu füllen, wäre eine Energiemenge notwendig, die größer ist als die Menge an Energie, die ausreichen würde, um die irdischen Ozeane zu verdampfen. Deshalb geht man davon aus, dass die Kapazität von ZFS für immer ausreichen wird.

 
Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht:GNU Free Documentation License 1.2
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki