Snímky súborového systému ZFS

2. 2. 2011
Doba čtení: 11 minut

Sdílet

Dnes nás čaká určite najzaujímavejší diel venovaný ZFS. V tomto pokračovaní sa budeme zaoberať vytváraním aktuálnych snímkov stavu nášho súborového systému. Zaujíma vás, ako si vytvoriť zálohu systému v určitom stave a následne jedným príkazom obnoviť celý systém naspäť?

ZFS SNAPSHOT

ZFS snapshot (snímka) je read-only kópia filesystému v danom čase kedy bol vytvorený. Snapshot môže byť vytvorený takmer okamžite, v počiatku nespotrebováva dodatočný priestor v poole, avšak ak sa dáta v datasete zmenia (niečo sa vymaže, zmení…), prvý snapshot stále odkazuje na dáta prvého a v poradí druhý snapshot obsahuje rozdiel prvého snapshotu. Dá sa povedať, že každý snapshot je rozdiel predchádzajúceho.

Príklad:

Ak pridáme na disk 2GB súbor a spravíme snapshot, tak bude mať skoro nulovú veľkosť. To je spôsobené tým, že snapshot iba odkazuje na dáta vo filesystéme. Pokiaľ však tento súbor vymažeme, pridáme iný napr. 3GB a spravíme opäť snapshot, tak kvôli prvému snapshotu bude dodatočný priestor na disku +2GB (dáta prvého súboru), až pokým samozrejme nevymažeme počiatočný snapshot.

Ako sa dostaneme k snapshotom?

Snapshoty sú dostupné v skrytom priečinku „.zfs“ v každom datasete v tejto forme:

[cesta k namapovanému datasetu]/.zfs/snapshot/[názov_snapshotu]/...

Príklad:

Vytvoríme dataset pool/test/skuska1, ktorý je namapovaný v /test/skuska1, pridáme súbory do umiestnenia /test/skuska1 a spravíme snapshot pool/test/skuska1@piatok, tak k dátam v snapshote sa dostanete v umiestnení /test/skuska1/.zfs/snapshot/piatok.

# ls -la /test/skuska1/.zfs/snapshot/
pondelok utorok streda stvrtok piatok

ZFS CLONE

ZFS clone je read/write kópia filesystému vytvorená zo snapshotu. Klon sa vždy vytvára zo snapshotu!

Príklad:

Ukážeme si, ako vytvoriť klon zo snapshotu s názvom pool/test@mysql_zaloha a to tak, že vytvoríme dataset (namapovaný do /test), následne nakopírujeme do neho mysql dump, spravíme snapshot ( pool/test@mysql_zaloha) a nakoniec spravíme zo snapshotu klon a namapujeme ho do /clone:

# zfs create -o mountpoint=/test pool/test
# cp mysql_dump.sql /test
# zfs snapshot pool/test@mysql_zaloha
# zfs clone -o mountpoint=/clone  pool/test@mysql_zaloha pool/test/clone_mysql

Teraz vieme do klonu aj zapisovať. Klon sa nachádza v /clone.

ZFS CREATE

Jednoduchým príkazom ZFS create vieme vytvoriť dataset, ktorý môže a nemusí obsahovať ďalšie poddatasety.

# zfs create pool/test
# zfs set mountpoint=/test pool/test
# zfs set compression=on pool/test

# zfs list
NAME                USED  AVAIL  REFER  MOUNTPOINT
pool                 21.7G  13.0G    18K  none
pool/root           6.72G  13.0G  4.99G  /
pool/test             20K  13.0G    20K  /test

Týmto príkazom sme vytvorili nový pool s názvom pool/test, ktorý sme namapovali do /test. Ekvivalent týchto troch príkazov by bol:

# zfs create -o mountpoint=/test -o compression=on pool/test pool/test

Dedenie (Inherit)

Použijem jednoduchú ukážku, ako zdedia poddatasety všetky vlastnosti ich hlavného datasetu. Vytvorím hlavný (parent) dataset pool/share a jeho poddatasety pool/share/peto a pool/share/jano, vytvorím priečinok /share a namapujem pool dataset pool/share do /share:

# zfs create pool/share
# zfs create pool/share/peto
# zfs create pool/share/jano

# mkdir /share
# zfs set mountpoint=/share pool/share

# zfs list
NAME                       USED  AVAIL  REFER  MOUNTPOINT
pool/share                  57K  13.0G    19K  /share
pool/share/jano      19K  13.0G    19K  /share/jano
pool/share/peto        19K  13.0G    19K  /share/peto

Všimnite si, že namapovaním poolu pool/share si automaticky preberú všetky vlastnosti jeho „deti“ poddatasety pool/share/peto a pool/share/jano.

ZFS LIST

Ak sme už vytvorili nejaké pooly, bolo by dobré si ich vypísať. To spravíme príkazom ZFS list:

# zfs list
NAME                 USED  AVAIL  REFER  MOUNTPOINT
pool                     21.7G  13.0G    18K  none
pool/root               6.72G  13.0G  4.99G  /
pool/root/tmp        165M  13.0G   165M  /tmp
pool/root/var        192M  13.0G   192M  /var
pool/samba          10.0G  10.0G  21.5K  /samba
....

Bez ďalších prepínačov sme dostali kompletný výpis datasetov, ktorý obsahuje náš systém. Môžeme však chcieť vypísať informácie iba o určitom poole:

# zfs list pool/test
NAME USED AVAIL REFER MOUNTPOINT
pool/test 57K 8.58G 19K /test

Alebo vypísať iba snapshoty v systéme:

# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
pool/test@zaloha 169M - 2.72G /test
pool/test@20101213 140M - 2.79G /test
....

Dá sa vypísať aj všetko, t.j. všetky datasety, snapshoty, clony atď. To docielime, ak zadáme za prepínačom -t parameter all:

# zfs list -t all
NAME USED AVAIL REFER
pool 26.1G 8.58G 18K none
pool/root 6.11G 8.58G 5.08G /
pool/test@zaloha 169M -
....

Niekedy je potrebné zistiť, aké snapshoty sa viažu na dataset prepínačom -r [názov datasetu]:

# zfs list -r pool/test
NAME USED AVAIL REFER MOUNTPOINT
pool/test 277K 16.5G 277K /test
pool/test@zaloha 0 - 277K -
pool/test@zaloha2 0 - 5GK -
....

Pri skriptoch sa hodí vypísať sformátovaný výstup príkazu zfs list. Na to nám slúži prepínač -o a za ním meno stĺpca oddelený čiarkami:

# zfs list -o name,used,avail,refer
NAME USED AVAIL REFER
pool 7.81G 3.45M 19K
pool/clone 0 3.45M 19K
pool/root 7.79G 3.45M 4.37G
pool/root/tmp 5.09M 3.45M 5.09M
pool/root/var 305M 3.45M 281M
pool/skuska 84K 3.45M 3.65G
....

ZFS DESTROY

Príkazom zfs destroy zmažeme daný snapshot alebo dataset.

# zfs destroy pool/test@snapshot1 <-- snapshot
# zfs destroy pool/test <-- dataset

Ak by obsahoval dataset pool/test 20 snapshotov, museli by sme ich ručne vymazať, alebo použiť prepínač „-R“, ktorý vymaže všetky poddatasety a jeho snasphoty:

# zfs destroy -R pool/test

ZFS QUOTA

ZFS quota je definícia diskového priestoru pre dataset a jeho poddatasety, t.j. nastavujeme, koľko môže maximálne „spotrebovať“ dát bez ohľadu na celkovú veľkosť priestoru na disku.

V ZFS vieme teda veľmi jednoducho definovať systémové kvóty jediným príkazom, a to zfs set quota=[k,M,G] názov_poolu.

# zfs set quota=5G pool/test/samba

Môžeme nastaviť kvótu aj pre jednotlivého užívateľa alebo skupinu použitím zfs userquota a zfs groupquota:

# zfs create pool/ftpusers
# zfs set userquota@uzivatel1=10G pool/ftpusers
# zfs create pool/manazment
# zfs set groupquota@riaditel=20GB pool/manazment

Zobrazíme si ešte aktuálny stav user a group kvót:

# zfs get userquota@student1 pool/ftpusers
NAME              PROPERTY            VALUE               SOURCE
pool/ftpusers  userquota@uzivatel1    10G                 local

# zfs get groupquota@manazment pool/manazment
NAME               PROPERTY            VALUE             SOURCE
students/labstaff  groupquota@riaditel  20G               local

ZFS RESERVATION

ZFS reservation je definícia minimálneho garantovaného objemu dát pre dataset a jeho poddatasety. Vieme teda garantovať (narozdiel od zfs quota) určitú veľkosť kvóty pre dataset, ktorá bude dodržaná.

# zfs set reservation=5G pool/test/samba

ZFS RENAME

Niekedy sa môže hodiť premenovať datasety. To sa robí príkazom rename.

# zfs rename pool/test/A pool/test/B

ZFS COMPRESSION

Datasetu vieme prideliť aj kompresiu príkazom zfs compression. Možné kompresie sú on, off, lzjb, gzip, gzip-[1-9].

Príklad:

Chceme nastaviť najmenšiu(9) kompresiu gzip pre pool pool/test a zistiť zmeny príkazom get.

# zfs set compression=gzip-9 pool/test
# zfs get -r compression pool/test
NAME PROPERTY VALUE SOURCE
pool/test compression gzip-9 local

Ak sme vytvorili pool s názvom pool/test a pridelili mu kompresiu gzip-9, tak ak neskôr vytvoríme pool/test/test1 a pool/test/test2, všimnite si, že kompresné hodnoty zdedia od svojho „rodiča“ (parentu) pool/test:

# zfs get -r compression pool/test
NAME PROPERTY VALUE SOURCE
pool/test compression gzip-9 local
pool/test/A1 compression gzip-9 inherited from pool/test
pool/test/A2 compression gzip-9 inherited from pool/test

ZFS SEND A RECEIVE

Príkaz zfs send vytvorí zo snapshotu dátový tok a zfs receive premení dátový tok opäť na snapshot.

Posielanie snapshotu lokálne

# zfs send pool/samba@20101212 | zfs receive pool/samba_dir

Posielame snapshot pool/samba@20101212, ktorý následne prijmeme do  pool/samba_dir.

Posielanie snapshotu na vzdialený server

1.

(serverA)# zfs send pool/samba@20110110 | ssh server2 zfs recv pool/samba_dir

V tomto prípade sme poslali snapshot pool/samba@20110110 na server server2, kde sme ho následne prijali a namapovali do  pool/samba_dir.

2.

(serverB)# ssh server2 zfs send pool/test@test | zfs recv -vF -d pool
receiving full stream of pool/test@test into pool/test@test
received 249KB stream in 1 seconds (249KB/sec)

Cez ssh sme povedali, aby server server2 poslal snapshot s názvom pool/test@test, ktorý sme následne prijali na lokálnom serveri  serverB.

Tento príkaz môžeme použiť aj na zálohu napr. celého operačného systému, ktorý je v jaily. Jail mal 850MB a po komprimácii iba 353MB:

# zfs send pool/virtual_server@jail | gzip -9 > jail_virtual.gz

Inkrementálna záloha

Inkrementálna, teda prírastková záloha je zálohovací model, pri ktorom sa zálohujú iba zmenené údaje v dátach, t.j. obsahuje informácie o zmenách voči predchádzajúcej zálohe. Prenášajú sa teda iba zmeny v predchádzajúcom snapshote.

Príklad:

Vytvoríme prvý snapshot pool/test@transfer, nakopírujeme nejaké dáta a neskôr vytvoríme snapshot pool/test@2, prenesieme prvý snapshot pool/test@transfer na iný systém.

# zfs send pool/test@transfer | ssh server2 zfs recv -vF tank/test
receiving full stream of  pool/test@transfer into tank/test
received 327MB stream in 54 seconds (6.06MB/sec)

Keďže po prvom snapshote ( pool/test@transfer) som nakopíroval do datasetu nejaké dáta (±200kb), druhý snapshot pool/test@2 bude už obsahovať aj tento prírastok. Teraz môžeme vykonať inkrementálnu zálohu na iný systém, kde sa budú prenášať iba rozdiely predchádzajúceho snapshotu.

# zfs send -i pool/test@transfer pool/test@2 | zfs recv -vF tank/test
receiving incremental stream of pool/test@transfer into pool/test@2
received 372KB stream in 1 seconds (372KB/sec)

ZFS ROLLBACK

Príkaz zfs rollback slúži na vrátenie predošlého stavu datasetu k danému času kedy bol vytvorený teda obnoví sa dátová štruktúra súborov, do daného okamihu kedy bol vytvorený snapshot. Pozor, staršie zfs snapshoty ako rollback snapshot budú po aplikácii zfs rollback vymazané!

Príklad:

Vytvoríme si tri súbory a pri každom spravíme snapshot:

# touch snapshot1
# zfs snapshot pool/test@snapshot1

# touch snapshot2
# zfs snapshot pool/test@snapshot2

# touch zly_snapshot
# zfs snapshot pool/test@snapshot3

# zfs list -t all
NAME USED AVAIL REFER MOUNTPOINT
pool 3.37G 4.44G 19K none
pool/root 3.37G 4.44G 3.28G /
pool/root/tmp 31K 4.44G 31K /tmp
pool/root/var 95.7M 4.44G 95.7M /var
pool/test 54K 4.44G 20K /test
pool/test@snapshot1 0K - 20K /test
pool/test@snapshot2 2M - 20K /test
pool/test@snapshot3 0 - 20K /test

Vidíme, že v priečinku test sa vytvorili tri súbory:

# ls -la
total 3
-rw-r--r-- 1 root wheel 850B Dec 20 11:45 snapshot1
-rw-r--r-- 1 root wheel 70B Dec 20 11:45 snapshot2
-rw-r--r-- 1 root wheel 3B Nov 25 11:46 zly_subor

Teraz chceme napríklad vrátiť pôvodný stav do doby kedy sa vytvoril snapshot2, pretože sa tam objavil súbor zly_subor, ktorý tam nechceme:

# zfs rollback pool/test@snapshot2
cannot rollback to 'pool/test@snapshot2': more recent snapshots exist
use '-r' to force deletion of the following snapshots:
pool/test@snapshot3

Budeme musieť pridať prepínač -r, pretože existuje novší snapshot (snapshot3):

# zfs rollback -r pool/test@snapshot2
# ls -la
total 1
-rw-r--r-- 1 root wheel 850B Dec 20 11:45 snapshot1
-rw-r--r-- 1 root wheel 70B Dec 20 11:45 snapshot2

Ako vidíme, dostal som priečinok test do pôvodného stavu, kedy bol vytvorený snapshot2 a odstránil nežiadaný stav (zly_subor) s tým, že všetky snapshoty po snapshote2 sa automaticky odstránili.

ZFS HOLD

Niekedy sa nám môže stať, že stratíme prehľad pri veľkom počte snapshotov a nejaký si omylom vymažeme. V ZFS si vieme povedať, ktorý snapshot si chceme ponechať teda označiť ho ako nevyzmazateľný. Docielime to príkazom zfs hold keep snapshot, ktorý nám ho zabráni odstrániť:

# zfs hold keep pool/root@prva_instalacia
# zfs destroy pool/root@prva_instalacia
cannot destroy ’pool/root@prva_instalacia’: dataset is busy

Môžeme sa však neskôr rozhodnúť takýto „nevymazateľný“ snapshot aj tak vymazať. Musíme použiť prepínač -d:

# zfs destroy -d pool/root@prva_instalacia

Alebo zbaviť snapshot tagu „hold“:

# zfs release pool/root@prva_instalacia

Ďalej môžeme potrebovať zistiť informáciu, kedy sme označili snapshot ako neodstrániteľný:

# zfs holds pool/root@OK
NAME           TAG TIMESTAMP
pool/root@OK keep Thu Jan 15 11:25:39 2010

ZFS ALLOW A UNALLOW

V ZFS vieme nastavovať práva pre pooly príkazom zfs allow. Opačným krokom je práva odobrať, a to príkazom zfs unallow.

Príklad:

Chceme, aby užívateľ testuser mohol robiť s poolom pool/testuser úkony: create, destroy, mount a snapshot. Následne pridelíme vytvorené práva pre daný pool príkazom allow.

# zfs allow testuser create,destroy,mount,snapshot pool/testuser
# zfs allow pool/testuser
-------------------------------------------------------------
Local+Descendent permissions on (pool/testuser)
user testuser create,destroy,mount,snapshot
-------------------------------------------------------------

Pre odstránenie týchto práv použijeme príkaz unallow, odoberieme už vytvorené práva pre užívateľa testuser a následne aplikujeme vykonané zmeny pre pool príkazom allow.

# zfs unallow testuser pool/testuser
# zfs allow pool/testuser

ZFS SET

Príkazom zfs set nastavujeme vlastnosti pre snapshoty (quota, reservation atď…).

ZFS GET

Príkaz zfs get nám slúži na zobrazenie informácií napr. o compress ratiu pre dataset:

# zfs get compressratio pool/root
NAME       PROPERTY       VALUE  SOURCE
pool/root  compressratio  1.00x  -

Záver

Dostali sme sa až na záver seriálu. Je toho veľmi veľa čo ZFS dokáže a určite som nespomenul veľa vecí, pretože som sa zameral iba na základy. Verím, že moja séria článkov niekomu pomohla a zorientoval sa v tomto veľmi užitočnom súborovom systéme.

ict ve školství 24

Zdroje:

MAN ZFS
MAN ZPOOL
FreeBSD ZFS wiki
ZFS tunning 32bit system
Oracle Solaris ZFS Administration Guide