Portál AbcLinuxu, 30. dubna 2025 11:25
Zhruba před rokem jsem na novém serveru vytvářel úložiště ze 4 kusů Hitachi 4 TB disků. Z hlediska bezpečnosti uložení dat jsem požadoval redundanci uložení (stačí dvě kopie) a samozřejmě čím vyšší rychlost, tím lépe. Už v té době jsem také předpokládal, že časem do serveru přibudou další disky a úložiště se bude rozšiřovat. Když k tomu ale teď došlo, tak jsem narazil u ext4 na limit 16 TiB velikosti filesystému. Skončilo to přechodem na Btrfs (podrobnosti dále) v produkčním provozu (byť ne kritickém), tak mi držte palce.
Vzhledem k uvedeným požadavkům a dostupnosti 4 disků jsem se tenkrát rozhodl pro RAID10. A to linuxový softwarový mdraid, protože s hardwarovými RAIDy jsou potenciálně potíže s rychlostí a určitě potíže s obnovou dat v případě havárie hardware. (Mimochodem mi zrovna teď leží na stole 10 let staré hardwarové pole Promise VTrak M500i, které z neznámého důvodu po nastartování nezprovozní síťová rozhraní pro iSCSI přístup k datům ani webový management pro správu. Přes konzolu na sériovém rozhraní je vidět, že bootování neproběhne korektně do konce. Data na něm uložená nebyla moc důležitá [a byla zálohovaná], takže mne to zas až tak moc netrápí, ale když bych je potřeboval dostat zpět, tak bych měl problém. Dosavadní pokusy o zprovoznění té škatule k úspěchu nevedly. V případě linuxového softwarového RAIDu bych disky jednoduše přestrkal do funkčního počítače s linuxem a bylo by.)
Instalovalo se na (v té době aktuálním) Debian 7 (Wheezy). Konzultací kernel Wiki a další zdrojů na webu jsem dospěl k závěru, že chci RAID10 ve far layoutu.
$ mdadm --create /dev/md0 --name storage --chunk=1024 --level 10 --raid-devices=4 --layout f2 --bitmap=internal /dev/sd[bcde]1 $ mdadm --detail --scan >> /etc/mdadm/mdadm.conf $ dpkg-reconfigure mdadm $ cat /proc/mdstat
Nastavení chunk size vzešlo tuším z nějakého přepočtu pro plánované LVM a ext4 filesystém.
Mimochodem, i po těch letech stále nedám dopustit na skvělou sérii Správa linuxového serveru na LinuxExpres.cz, která pokrývá např. i práci s Linux RAID.
Protože jsem už v té době tušil, že u 4 disků nezůstane, nedal jsem filesystém přímo na RAID pole, ale použil jsem mezivrstvu LVM.
Ne že by tedy vůbec nešlo rozšiřovat mdraid, ale je to výrazně komplikovanější a s omezeními. Pokud vím, tak mnou zvolený mód RAID10 (navíc ve far layoutu) pod mdraid stále není možné rozšířit o další zařízení. (A to ani na současném nejnovějším jádře, kterému to samozřejmě do stabilního Debianu ještě nějakou dobu potrvá.) Zpětně to považuji za velké štěstí, že jsem to vůbec neuvažoval dělat tímto způsobem, protože bych pak měl navíc velký problém nové disky z RAIDu uvolnit, až bych narazil na problém se zvětšením ext4, viz dále.
Postup přes LVM je jednoduchý:
$ pvcreate -M2 --dataalignment 1024K /dev/md0 $ pvdisplay $ vgcreate --physicalextentsize 2048K mdraid10s /dev/md0 $ vgdisplay $ lvcreate -n storage -l 100%VG mdraid10s $ lvdisplay $ pvs $ vgs $ lvs
Ani u LVM nezklame seriál LinuxExpres.cz.
Pak už zbývalo jen vytvořit filesystém. Vzhledem ke stabilitě a dobrým zkušenostem jsem sáhl po klasice – ext4. Dá se zvětšovat (on-line) i zmenšovat (jen odpojený) a věřil jsem, že by neměl mít problém ani později na větších oddílech. Později se ukázalo, že jsem se měl více zajímat o reálné limity; moje zkušenost „nedostanu se k hardware, na který by současný běžně užívaný filesystém nestačil, není potřeba nad tím nějak hluboce dumat“ asi přestává platit.
Vytvoření jsem udělal dle spočtených parametrů:
$ mkfs.ext4 -b 4096 -E stride=256,stripe-width=512,resize=9766950400 -L storage -m 1 -T huge -v /dev/mapper/mdraid10s-storage
Od té doby úložiště bez problémů dobře sloužilo, v mezičase jsme také přešli na aktuální Debian 8 (Jessie).
Nyní se stalo dříve očekávané, přišly další 4 disky, tentokrát 6 TB Western Digital Red, o které mělo být úložiště rozšířeno. Jal jsem se tedy aplikovat dříve plánovanou strategii – vytvoření nového samostatného RAID10 z nových disků, přidání pod LVM a roztažení ext4 přes celou nově dostupnou kapacitu logického oddílu.
I když to jde, nepovažuji za vhodné vytvářet RAID/LVM/Btrfs přímo na discích bez vytvoření patition tabulky (na jednom serveru jsem zdědil LVM přímo na discích a při instalaci operačního systému to vždycky bylo o jediný Enter od smazání všech dat, protože pro instalátor se disky jevily jako neinicializované). U 6 TB disků už je nutnost GPT, pro vytvoření jsem použil gdisk
. Na každém disku jsem vytvořil jediný oddíl (s typem fd00 Linux RAID
) přes skoro celý disk, protože jsem kdysi četl doporučení nevytvářet RAID přes úplně plnou kapacitu disků. Pokud je později potřeba nějaký disk vyměnit a bude to jiný model, může se stát, že i při proklamované stejné kapacitě to úplně na sektor sedět nebude a nastal by problém, pokud by takový disk byl menší než původní disky v poli.
U nového pole jsem jen zopakoval to stejné, jako u pole minulého.
$ mdadm --create /dev/md1 --name storage2 --chunk=1024 --level 10 --raid-devices=4 --layout f2 --bitmap=internal /dev/sd[fghi]1 $ mdadm --detail --scan /dev/md1 >> /etc/mdadm/mdadm.conf $ dpkg-reconfigure mdadm $ cat /proc/mdstat
Nové pole jsem hned přidal do LVM a jediný logický svazek, který v LVM mám (slouží pro dané úložiště), jsem zvětšil na maximální velikost, aby pokryl celou nově dostupnou kapacitu.
$ pvdisplay $ pvcreate -M2 --dataalignment 1024K /dev/md1 $ pvdisplay $ vgdisplay $ vgextend mdraid10s /dev/md1 $ vgdisplay $ lvdisplay $ lvextend -l+100%FREE /dev/mdraid10s/storage $ lvdisplay $ pvs $ vgs $ lvs
Všechno šlo hladce bez nejmenšího problému, a tak jsem poslední krok – rozšíření souborového systému ext4 na nově dostupnou kapacitu, tj. zhruba 18,3 TiB, – považoval za jasně bezproblémový. Úložiště jsem ani neodpojoval a jal se ho zvětšit za provozu:
$ resize2fs -p /dev/mapper/mdraid10s-storage resize2fs 1.42.12 (29-Aug-2014) resize2fs: New size too large to be expressed in 32 bits
Tak to jsem vůbec nečekal. A když jsem si přečetl chybové hlášení, tak jsem hned tušil, že to asi nepůjde jen tak snadno spravit na již existujícím souborovém systému bez jeho nového vytvoření.
Přiznám se, že jsem se tenkrát nepodíval, jaké že má ext4 vlastně limity. Když jsem to teď pohledal, tak se ukázalo, že schopnosti ext4, respektive doporučené limity použití, se s časem vyvíjely, a i teď je u ext4 hranice velikosti oddílu 16 TiB stále významná, i když ne nepřekonatelná.
Nepouštěl jsem se do hlubších analýz, ale dle dvou článků nalezených na první pokus s vyhledávačem jsem nabyl dojmu, že mám čtyři možnosti:
/etc/mke2fs.conf
to vypadá, že v Debian 8 už je to při vytváření ext4 filesystému default; můžu jen hádat, že na Debian 7 to tak ještě nebylo), přesunout tam data ze starého ext4 oddílu, a po jeho uvolnění staré RAID pole přidat do toho nového LVM oddílu a nový ext4 pak roztáhnout přes celou kapacitu obou polí.
resize2fs
z Debian 8 nebude umět zvětšit 64bitový ext4, takže bych si nepomohl. Jestli to tak opravdu je, nebo není, to jsem dále neověřoval, protože tu byla ta lákavá čtvrtá možnost, kterou jsem nakonec vyhodnotil jako nejlepší.Btrfs sice umí konvertovat ext4 oddíl na Btrfs i přímo, ale já se chtěl zbavit i níže ležící LVM a RAID vrstvy, protože Btrfs umí tohle všechno zastat sám. Musel jsem tedy nové disky zase vyprostit ze sevření LVM a rozbít na nich vytvořený RAID.
V tomto místě jsem trošku zazmatkoval a zbytečně si to zkomplikoval. Vzhledem k tomu, že ext4 se zvětšit nepodařilo (tj. na jeho velikost a umístění na LVM oddílu se vůbec nesáhlo), bývalo by bylo stačilo zjistit velikost LVM oddílu náležejícího původnímu poli a LVM logický svazek takto zmenšit. Já však sáhl k bezpečnějšímu způsobu zmenšením existujícího ext4 oddílu (měl něco kolem 7,6 TiB) bezpečně pod velikost pole starých disků, zmenšení LVM logického svazku s bezpečnou rezervou tak, aby byl jistě větší než zmenšený ext4, a zároveň bezpečně menší než LVM fyzický svazek starého pole, aby bylo určitě možné fyzický svazek nového pole z LVM odebrat (tj. aby bylo kam přesunout data, která by na něm případně byla).
$ umount /mnt/storage $ e2fsck -f /dev/mapper/mdraid10s-storage $ resize2fs -p /dev/mapper/mdraid10s-storage 6400G $ lvreduce -L 7200G /dev/mdraid10s/storage $ pvmove /dev/md1 $ vgreduce mdraid10s /dev/md1 $ pvremove /dev/md1
Teď bylo možné zrušit softwarový RAID nad novými disky, aby se daly použít pro Btrfs pool.
$ mdadm --stop /dev/md1 $ mdadm --zero-superblock /dev/sd[fghi]1 $ vim /etc/mdadm/mdadm.conf # Odstranit záznam pro /dev/md1 $ dpkg-reconfigure mdadm
Jak jsem psal výše, preferuji existenci diskového oddílu i při použití Btrfs. Pomocí gdisk
jsem původní GPT zahodil a vytvořil novou, potřeba byly jen dvě změny – jako typ oddílu jsem nastavil 8300 Linux filesystem
a oddíl jsem udělal opravdu přes celý disk, protože Btrfs nemá problém ani s kombinováním různě velkých disků.
I v případě Btrfs jsem sáhl po RAID10, a to pro data i metadata.
$ mkfs.btrfs -L 'btrfs-pool' -m raid10 -d raid10 /dev/sd[fghi]1
Vytvoření okamžité, žádná dlouhá synchronizace jako v případě linuxového softwarového RAID. Vytvořený filesystém bylo možné okamžitě namountovat a začít používat.
Z hlediska budoucího využívání je u Btrfs vždy dobré necpat jakákoliv data přímo na kořen úložiště (tj. do subvolume 0), ale vytvořit si na vše podsvazky, ty samostatně připojit a data dávat tam. Pokud pak budete potřebovat dát na pole data mimo viditelnost běžných uživatelů, založit jiné logicky samostatné úložiště pro jiný typ dat atd., tak není nic jednoduššího, než přidat další podsvazky. Do /etc/fstab
jsem tedy přidal
UUID=81616a44-bf88-4e99-a0c8-4d9d76c12aeb /mnt/btrfs-pool btrfs noauto,relatime,subvolid=0 0 0 UUID=81616a44-bf88-4e99-a0c8-4d9d76c12aeb /mnt/storage btrfs relatime,subvol=storage 0 0a provedl
$ mkdir /mnt/btrfs-pool /mnt/storage $ mount /mnt/btrfs-pool/ $ btrfs subvolume create /mnt/btrfs-pool/storage $ rsync -avh --progress --delete /puvodni/uloziste/ /mnt/btrfs-pool/storage/ $ mount /mnt/storage/
Přípojný bod /mnt/btrfs-pool
tedy slouží jako „servisní“, je připojován jen na vyžádání (ne automaticky po startu stroje) a vždy mountuje kořenový svazek Btrfs poolu (parametr subvolid=0
ve fstab
) bez ohledu na to, co je případně jako defaultní svazek pro mount nastaveno. Skrze něj je tedy vždy dostupný kompletní obsah Btrfs poolu. Připojení /mnt/storage
pak zpřístupňuje jen obsah podsvazku storage
a je určen pro běžné použití úložiště i koncovým uživatelům.
Vzhledem k tomu, že nyní již byla všechna data na novém Btrfs úložišti (viz rsync
výše), tak bylo možné zrušit původní ext4 + LVM + RAID, aby bylo možné staré disky přidat do Btrfs poolu.
# Zrušení LVM $ lvremove /dev/mdraid10s/storage $ vgremove mdraid10s $ pvremove /dev/md0 # Zrušení mdraid ze starých disků $ mdadm --stop /dev/md0 $ mdadm --zero-superblock /dev/sd[bcde]1 $ vim /etc/mdadm/mdadm.conf # Odstranit záznam pro /dev/md0 $ dpkg-reconfigure mdadm # Vytvoření GUID diskových oddílů na starých discích $ for i in b c d e; do > gdisk /dev/sd"${i}" > done
Zbývá poslední krok – uvolněné staré 4 kusy 4 TB disků přidat do Btrfs poolu, abychom tedy konečně měli k dispozici jeden souborový systém přes všechny disky. V případně Btrfs jednoduchá operace, která probíhá za plného provozu souborového systému, /mnt/storage/
teď už bylo celou dobu připojené a plně k dispozici uživatelům pro normální použití.
$ btrfs device add /dev/sd[bcde]1 /mnt/btrfs-pool/ $ btrfs balance start /mnt/btrfs-pool/ $ umount /mnt/btrfs-pool/
Po rozšíření Btrfs svazku přes všechny disky je pro uživatelská data dostupných zhruba 18,5 TiB (fyzicky je na discích místa zhruba dvakrát tolik, ale je tam ta RAID10 redundance). V okamžiku před přidáním nových disků do serveru nebylo původní úložiště úplně plné, bylo tam uloženo jen asi 4,3 TiB dat, což byla tedy také zabraná kapacita (logická, fyzicky to je dvakrát tolik kvůli té RAID10 redundanci + servisní data filesystému) na Btrfs svazku po rozšíření přes všechny disky. Celkem to bylo něco kolem 2,5 milionu souborů. Za těchto podmínek ta balance operace (tj. rovnoměrné rozprostření dat z disků použitých už při vytvoření svazku také na disky do svazku nově přidaných) běžela zhruba 7,5 hodiny.
Stejně jako umí mdadm
provádět kontroly shody redundantně uložených dat na mdraid (součástí dpkg-reconfigure
je i načasování těchto kontrol), tak je vhodné provádět pravidelné kontroly a údržbu na Btrfs. Existuje na to i sada skriptů btrfsmaintenance, které jsou i standardní součástí v openSUSE repositářích. Pod Debianem o takovém balíčku nevím, takže jsem si skripty vyrobil sám přiohnutím těch z openSUSE.
„Překartáčování“ úložiště jednoduše přečte všechna data ze všech disků a ověřuje přitom kontrolní součty, které si Btrfs interně pro všechna data vede. Pokud by narazil na chybu, tak by ji rovnou opravil, pokud by existovala jiná korektní kopie daných dat. Běží to s nízkou io prioritou, takže by to nemělo mít prakticky žádný vliv na běžné používání úložiště.
$ cat ~/bin/btrfs-maintenance-scrub.sh #!/bin/bash # Paths to work on mountpoints=(/mnt/storage/) for MNT in ${mountpoints[@]}; do echo "Running scrub on ${MNT}" if [ $(stat -f --format=%T "${MNT}") != "btrfs" ]; then echo "Path ${MNT} is not btrfs, skipping" continue fi /bin/btrfs scrub start -Bd "${MNT}" if [ "$?" != "0" ]; then echo "Scrub cancelled at ${MNT}" exit 1 fi done
Není špatný nápad čas od času přerozdělit data ze skupin bloků, které jsou málo využité (tj. je alokováno hodně místa na úložišti, ale je do něj zapsáno jen málo dat). Předchází se tak problémům, kdy je na discích dost místa, ale nejde využít, protože je rozkouskováno do mnoha málo využitých bloků).
$ cat ~/bin/btrfs-maintenance-balance.sh #!/bin/bash # Paths to work on mountpoints=(/mnt/storage/) # The usage percent for balancing data block groups. # Caveat: the higher the longer it will need BTRFS_BALANCE_DUSAGE="1 5 10 20 30 40 50" # The usage percent for balancing metadata block groups. # Caveat: the higher the longer it will need BTRFS_BALANCE_MUSAGE="1 5 10 20 30" /bin/btrfs filesystem show -d echo for MNT in ${mountpoints[@]}; do echo "Running balance on ${MNT}" if [ $(stat -f --format=%T "${MNT}") != "btrfs" ]; then echo "Path ${MNT} is not btrfs, skipping" continue fi echo echo "Before balance of ${MNT}" echo /bin/btrfs filesystem df -h "${MNT}" echo df -h "${MNT}" echo /bin/btrfs balance start -dusage=0 "${MNT}" for BB in $BTRFS_BALANCE_DUSAGE; do # quick round to clean up the unused block groups /bin/btrfs balance start -v -dusage=$BB "${MNT}" done /bin/btrfs balance start -musage=0 "${MNT}" for BB in $BTRFS_BALANCE_MUSAGE; do # quick round to clean up the unused block groups /bin/btrfs balance start -v -musage="$BB" "${MNT}" done echo echo "After balance of ${MNT}" echo /bin/btrfs filesystem df -h "${MNT}" echo df -h "${MNT}" echo done echo /bin/btrfs filesystem show -d
Skript na defragmentaci jsem si připravil taky, ale pravda je, že prakticky jsem jej zatím nikdy nepoužil.
$ cat ~/bin/btrfs-maintenance-defrag.sh #!/bin/bash # Paths to work on mountpoints=(/mnt/storage/) # Minimal file size to consider for defragmentation BTRFS_DEFRAG_MIN_SIZE="+1M" for MNT in ${mountpoints[@]}; do echo "Running defrag on ${MNT}" if [ $(stat -f --format=%T "${MNT}") != "btrfs" ]; then echo "Path ${MNT} is not btrfs, skipping" continue fi find "${MNT}" -xdev -size "$BTRFS_DEFRAG_MIN_SIZE" -type f \ -exec /bin/btrfs filesystem defrag -t 32m -f -v '{}' \; done
Údržba se provádí Cronem, překartáčování úložiště jednou za měsíc, balancování každý týden.
crontab -l -u root | grep btrfs @monthly /root/bin/btrfs-maintenance-scrub.sh @weekly /root/bin/btrfs-maintenance-balance.sh
Je potřeba myslet na to, že podsvazky vytvořené na Btrfs úložišti se tváří jako přechod mezi různými filesystémy, což může být podstatné, když např. pustíte find
s volbou -xdev
. Do podadresářů, které jsou ve skutečnosti Btrfs podsvazky, pak find nesestoupí.
$ cd /mnt/storage/ $ btrfs subvolume create zzz-podsvazek $ touch zzz-podsvazek/zzz-soubor-na-podsvazku $ find . -maxdepth 2 -type f | grep 'zzz' ./zzz-podsvazek/zzz-soubor-na-podsvazku $ find . -xdev -maxdepth 2 -type f | grep 'zzz' # tady se nevypíše nic, protože find do /mnt/storage/zzz-podsvazek/ nesestoupí $ btrfs subvolume delete zzz-podsvazek/
Pro mne to má závažný praktický význam např. v tom, že klient páskové knihovny, kterou používáme pro zálohování, potřebuje vyjmenovat seznam filesystémů, které má zálohovat. Když mu řeknu zálohovat /
a /mnt/storage/
, tak musím myslet na to, že když někdo vytvoří na /mnt/storage/
podsvazky, tak ty nebudou zálohovány na pásky. To bohužel nebude zjevné např. ani z reportu, kterým si (ne)proběhnuvší zálohy sleduji, protože ostatní data z /mnt/storage/
budou korektně zálohovaná. V reportu tedy nebude vidět zjevná chyba ani nulová velikost zálohovaných dat z daného mountpointu. Tohle je ideální situace k tomu, aby člověk zjistil, že zálohu nemá, až v okamžiku, kdy ji bude potřebovat obnovit. :-/ Pozor na to!
Do budoucna by nám přechod na Btrfs snad měl poskytnout větší bezpečnost dat (ve smyslu odolnosti vůči chybám hardware, bit rot apod.; naopak je možná vyšší riziko rozsypání se filesystému kvůli chybě v implementaci, protože je mladší a méně otestovaný než třeba ext2/3/4, XFS nebo ZFS), spoustu šikovných možností při používání úložiště (např. rychlé kopírování [díky copy-on-write pomocí cp --reflink
], snapshoty podsvazků pro snadné uchování historických verzí dat, inkrementální zálohování, send/receive posílání dat na jiné úložiště, úsporu místa díky kompresi dat a deduplikaci apod.) a zejména volnost v další manipulaci s disky a růstu úložiště. Reálné limity velikosti filesystému a souborů jsou u Btrfs v exabytech, limit počtu souborů je 264. Netvrdím, že to už přece musí opravdu stačit každému (nemyslím si, že to inženýři od Sunu zbytečně přestřelili, když ZFS projektovali ještě výše), ale věřím, že pro naše použití to stačit bude.
V tuto chvíli je pro mne podstatnější, že až vytáhnu směsku starších malých disků z té Promise škatule, kterou už se asi nebudu snažit dále resuscitovat, tak je můžu za plného provozu nejen fyzicky strčit do serveru, ale také začlenit do Btrfs uložiště a začít je používat. A to dost pravděpodobně i bez nevyužitelné kapacity, protože Btrfs je s rozdělováním dat mnohem gumovější než klasický linuxový softwarový RAID. A když v serveru dojdou pozice pro disky, tak můžu – stále za plného provozu filesystému pro koncové uživatele – starší disky průběžně vyndávat a nahrazovat je novějšími A když dojde místo a nebudou peníze na další disky, tak (opět za plného provozu) zdvojnásobíme dostupnou kapacitu přechodem z RAID10 na uložení dat bez redundance (a budeme spoléhat jen na zálohy). Tohle by tuším mělo jít definovat i na úrovni podsvazků (nebo dokonce i obyčejných adresářů?), takže je možné rozhodnout se, kde je vhodné držet data redundantně a kde si můžeme dovolit přejít na jednoduché uložení.
A že Btrfs ještě není dostatečně otestovaný pro produkční nasazení? No, to asi nepůjde udělat jinak, než se s tím někdo začne. Tak mi držte palce.
Tiskni
Sdílej:
rsync
ze starého pole s LVM a ext4 na nový Btrfs osciloval mezi 250–350 MiB/s, což mi přijde dobré. Dle nmon
byly všechny disky rovnoměnrě vytížené plus mínus na 95 %, takže se nezdá, že by jedna strana (tj. softwarový RAID s LVM a ext4 nebo naopak ten Btrfs svazek měla být brzda procesu). Nějaký návrh na způsob testování rychlosti úložiště?
Výpadek disku (pokud nepadneme pod limit redundance, takže bychom přišli o data) by samozřejmě neměl být problém – existuje degraded
mount volba, ale ta by neměla být potřeba, pokud je čitelný superblock, vadný disk by mělo stačit prostě za provozu ze svazku odebrat a případně nahradit jiným. Předpokládám, že ta degraded
mount volba by měla jít kombinovat s remount
, tj. nemělo by být nutné filesystém ani na chvíli odpojit.
Ne, nezkoušel.
Tím Heronem myšleno toto? No, to co píše mi trošku kazí představu o slučitelnosti mount voleb degraded
a remount
. Nepíše sice explicitně, že by to nešlo, ale předpokládám, že to nepůjde, když to tak neuděl. :-/
No, nebudeme se bát a zkusíme to:
$ mount | grep btrfs /dev/sdb1 on /mnt/storage type btrfs (rw,relatime,space_cache) $ mount -o remount,degraded /mnt/storage/ $ mount | grep btrfs /dev/sdb1 on /mnt/storage type btrfs (rw,relatime,degraded,space_cache) $ mount -o remount /mnt/storage/ $ mount | grep btrfs /dev/sdb1 on /mnt/storage type btrfs (rw,relatime,degraded,space_cache) $ mount -o remount,rw /mnt/storage/ $ mount | grep btrfs /dev/sdb1 on /mnt/storage type btrfs (rw,relatime,degraded,space_cache) $ mount -o remount,ro /mnt/storage/ $ mount | grep btrfs /dev/sdb1 on /mnt/storage type btrfs (ro,relatime,degraded,space_cache) $ mount -o remount /mnt/storage/ $ mount | grep btrfs /dev/sdb1 on /mnt/storage type btrfs (rw,relatime,degraded,space_cache) $ umount /mnt/storage $ mount /mnt/storage $ mount | grep btrfs /dev/sdb1 on /mnt/storage type btrfs (rw,relatime,space_cache)
Zdá se tedy, že přepnout svazek do degradovaného módu je možné bez jeho odpojení, stačí použít mount volbu remount
. Ale jak ho dostat pak zpět do normálního režimu jsem už jinak než s umount
a mount
nevymyslel.
Na druhou stranu je otázka, jestli by něčemu vadilo, pokud by po výměně disku zůstal filesystém připojený s flagem degraded
, než by se např. stroj rebootoval nebo oddíle odpojoval z jiného důvodu. Myslím, že ne, a tak věřím, že by tedy disk mělo jít vyměnit bez nutnosti odpojení svazku.
Tím Heronem myšleno toto?
Asi jo
V mém případě ani nešlo udělat remount,degraded
. Musel jsem ten FS skutečně odpojit (ze všech mountpointů - připojuji si ještě i nějaké subvolumy zvlášť) a potom připojit jako degraded.
Zpět to také nejde, žádná volba "not degraded
" neexistuje.
Na druhou stranu je otázka, jestli by něčemu vadilo, pokud by po výměně disku zůstal filesystém připojený s flagem degraded, než by se např. stroj rebootoval nebo oddíle odpojoval z jiného důvodu.
Ano, nad tím jsem také uvažoval a nějakou dobu jsem jel na degradovaném fs a vše bylo ok. Do vnitřností btrfs nevidím, ale z toho, jak se to chová, tak degraded je možná jen o nějakých kontrolách při mountu, dovolí běžet s menším počtem disků apod. a zbytek běhu fs je již stejný v obou případech.
Ono stejně je otázka, do jaké míry to vadí. V mnoha případech se ten komp stejně musí vypnout pro přendání disku a tam, kde není možné si výpadek dovolit, to mám řešené jako btrfs multidevice nad několika mdadm raid1. Takže btrfs výpadek disku nikdy neuvidí.
V každém případě je dobré o tomto chování vědět, způsobů, jak to obejít je dost. BTRFS se vyplatí i nad HW raidem, už jen pro ty vlastnosti, které nabízí.
Mimochodem, co deduplikace dat na Btrfs? Nějaké praktické zkušenosti nebo doporučení?
Dělat deduplikaci nad obecnými bloky (tzn si někam ukládat jejich hash + bezpečné manipulace při změnách) je velmi náročné na paměť a má to negativní dopad na výkon za mizivého přínosu co se ušetřeného místa týče.
Pro ZFS se tuším doporučuje 1 GiB RAM na 1 TiB úložiště, což tedy není málo.
To už je lepší se zamyslet nad způsobem ukládání dat a třeba se inspirovat od jiných projektů (git, backuppc, squashfs, některá řešení využívající db místo fs). Některé přístupy k problému jsou překvapivě jednoduché a účinné.
No, Btrfs stejně (zatím?) umí jen out-of-band deduplication. Kdysi jsem jen zkusmo párkrát použil v kernel wiki zmiňovaný duperemove, který pracuje, co si vzpomínám, tak, že se mu řekne, které soubory/adresáře má prohledat a deduplikovat. On si na datech napočítá kontrolní součty, a kde to vypadá na shodu, tam to nechá (kernel?) deduplikovat. Tohle mi právě smysluplné přijde – vím, že jsem zkopíroval velký soubor bez cp --reflink
, tak na něj poštvu duperemove
, vím, že jsem někam zkopíroval velký podstrom a udělal v něm sice změny, ale ne rozsáhlé, tak tam zase poštvu duperemove
apod.
Z rychlého koukání do dokumentace si ale nejsem jistý, kdo že vlastně dělá tu vlastní deduplikaci, a jestli je to tedy bezpečné. Pokud by userspace nástroj napočítal kontrolní součty dvou bloků, zjistil, že jsou stejné a sám je nějakým systémovým voláním napojil na jedinou kopii, tak by IMHO hrozilo, že to spočítal blbě, nebo že se mu jeden z bloků změní v průběhu operace pod rukama. Předpokládám tedy, že takto to nefunguje. Víc o tom ale nevím a tam jsem tedy směřoval dotaz.
On si na datech napočítá kontrolní součty, a kde to vypadá na shodu, tam to nechá (kernel?) deduplikovat. Tohle mi právě smysluplné přijde – vím, že jsem zkopíroval velký soubor bez cp --reflink, tak na něj poštvu duperemove, vím, že jsem někam zkopíroval velký podstrom a udělal v něm sice změny, ale ne rozsáhlé, tak tam zase poštvu duperemove apod.Tak zrovna toto je triviálně proveditelné v userspace. Existují programy (např. hardlink), které nahradí stejné soubory hardlinky. Stačí příslušnou část programu upravit tak, aby na cow fs místo hardlinků dělal reflinky a je to.
nebo že se mu jeden z bloků změní v průběhu operace pod rukamaMůže měnit jen soubory, které nejsou otevřené jiným procesem (nebo jen pro čtení).
Máte někdo zkušenost jak postupovat s BTRFS v případě, že dojde k (možná dočasné) chybě SATA řadič nebo disku?
Z nějakého důvodu přestal 3TB Seagate disk ST3000VN000-1H4167 komunikovat po SATA. HDPARM ho neviděl, smartclt se snažil asi přejít na starou verzi IOCTL, když nová neprošla a jádro si stěžovalo. Obecně byl disk nedostupný. BTRFS korektně po několik dní pokračovalo v režimu RAID1 a bez potíží zvládalo i zápis. Disk byl přítomný, jen nekomunikoval.
ata2.00: failed command: WRITE FPDMA QUEUED ... ata2: hard resetting link ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300) ata2.00: both IDENTIFYs aborted, assuming NODEV ata2.00: revalidation failed (errno=-2) ata2.00: disabled ata2: EH complete sd 1:0:0:0: [sdb] tag#1 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK sd 1:0:0:0: [sdb] tag#1 CDB: Write(16) 8a 00 00 00 00 00 06 01 09 00 00 00 00 18 00 00 sd 1:0:0:0: [sdb] tag#2 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK sd 1:0:0:0: [sdb] tag#2 CDB: Write(16) 8a 00 00 00 00 00 06 01 08 80 00 00 00 80 00 00 blk_update_request: I/O error, dev sdb, sector 100731008 BTRFS: bdev /dev/sdb5 errs: wr 1, rd 0, flush 0, corrupt 0, gen 0 sd 1:0:0:0: [sdb] tag#3 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK sd 1:0:0:0: [sdb] tag#3 CDB: Write(16) 8a 00 00 00 00 00 06 01 08 00 00 00 00 80 00 00 blk_update_request: I/O error, dev sdb, sector 100730880 BTRFS: bdev /dev/sdb5 errs: wr 2, rd 0, flush 0, corrupt 0, gen 0 ...
Přes všechny snahy resetovat SATA disk (hdparm -w) a řadič se mi nepodařilo disk kontaktovat. Zjistil jsem, o který fyzický disk se jedná a zkusil vyměnit SATA kabel. Při snaze o scan
# readlink -f /sys/block/sdb /sys/devices/pci0000:00/0000:00:1f.2/ata2/host1/target1:0:0/1:0:0:0/block/sde echo '- - -' >/sys/devices/pci0000:00/0000:00:1f.2/ata2/host1/scsi_host/host1/scan
hlásí dmesg stále
ata2: hard resetting link ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 300) ata2.00: both IDENTIFYs aborted, assuming NODEV ata2: EH complete
Po dokončení zálohy na externí USB disk jsem přikročil k násilnému vyjmutí a zasunutí napájecího konektoru problematického disku. Nyní již echo '- - -' >scan vypadá až na rychlost relativně dobře.
ata2: hard resetting link ata2: link is slow to respond, please be patient (ready=0) ata2: COMRESET failed (errno=-16) ata2: hard resetting link ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 310) ata2.00: ACPI cmd ef/10:06:00:00:00:00 (SET FEATURES) succeeded ata2.00: ACPI cmd f5/00:00:00:00:00:00 (SECURITY FREEZE LOCK) filtered out ata2.00: ACPI cmd b1/c1:00:00:00:00:00 (DEVICE CONFIGURATION OVERLAY) filtered out ata2.00: ATA-9: ST3000VN000-1H4167, SC43, max UDMA/133 ata2.00: 5860533168 sectors, multi 0: LBA48 NCQ (depth 31/32), AA ata2.00: ACPI cmd ef/10:06:00:00:00:00 (SET FEATURES) succeeded ata2.00: ACPI cmd f5/00:00:00:00:00:00 (SECURITY FREEZE LOCK) filtered out ata2.00: ACPI cmd b1/c1:00:00:00:00:00 (DEVICE CONFIGURATION OVERLAY) filtered out ata2.00: configured for UDMA/133 ata2: EH complete scsi 1:0:0:0: Direct-Access ATA ST3000VN000-1H41 SC43 PQ: 0 ANSI: 5 sd 1:0:0:0: [sde] 5860533168 512-byte logical blocks: (3.00 TB/2.72 TiB) sd 1:0:0:0: [sde] 4096-byte physical blocks sd 1:0:0:0: [sde] Write Protect is off sd 1:0:0:0: Attached scsi generic sg1 type 0 sd 1:0:0:0: [sde] Mode Sense: 00 3a 00 00 sd 1:0:0:0: [sde] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA BTRFS: bdev /dev/sdb5 errs: wr 8494906, rd 6076119, flush 29099, corrupt 0, gen 0 BTRFS: bdev /dev/sdb5 errs: wr 8494907, rd 6076119, flush 29099, corrupt 0, gen 0 ... sde: sde1 sde2 sde3 sde4 sde5 sde6 sd 1:0:0:0: [sde] Attached SCSI disk ata2: hard resetting link ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 310) ata2.00: ACPI cmd ef/10:06:00:00:00:00 (SET FEATURES) succeeded ata2.00: ACPI cmd f5/00:00:00:00:00:00 (SECURITY FREEZE LOCK) filtered out ata2.00: ACPI cmd b1/c1:00:00:00:00:00 (DEVICE CONFIGURATION OVERLAY) filtered out ata2.00: ACPI cmd ef/10:06:00:00:00:00 (SET FEATURES) succeeded ata2.00: ACPI cmd b1/c1:00:00:00:00:00 (DEVICE CONFIGURATION OVERLAY) filtered out ata2.00: ACPI cmd ef/10:06:00:00:00:00 (SET FEATURES) succeeded ata2.00: ACPI cmd f5/00:00:00:00:00:00 (SECURITY FREEZE LOCK) filtered out ata2.00: ACPI cmd b1/c1:00:00:00:00:00 (DEVICE CONFIGURATION OVERLAY) filtered out ata2.00: configured for UDMA/133 ata2: EH complete
Je disk dostupný jako /dev/sde. Stále je asi v jeho připojení něco divného, ale nezávislá samostatná EXTč partition lze normálně mountovat a lze do ní zapisovat. smartcl hlásí vše v pořádku a v uvádí jen jeden rok a půl starý problém Error: ABRT at LBA, pravděpodobně výpadek napájení. Jinak je čistý.
BTRFS sice správně po po načtení tabulky GPT oddílů detekuje příslušnost /dev/sdb5 k aktivnímu RAID1. Přesto sále vypisuje:
BTRFS: lost page write due to I/O error on /dev/sde5 BTRFS: bdev /dev/sde5 errs: wr 11007593, rd 8526080, flush 29099, corrupt 0, gen 0 ...
Zkoušel jsem pustit scrub, ale jen hlásí chyby na sda5. Nepodařilo se mi najít žádný jiný příkaz, který by měl v popisu, že zkusí vše načíst a srovná verze mezi kopiemi dat. Doufám, že alespoň stará data nebudou nikde použita na místo nových. Jsem přesvědčený, že přidání nového disku a
btrfs replace
by fungovalo. Ale zatím další disk po ruce nemám a běží mi
smartctl -t long /dev/sde
a pokud nevyhlásí chybu, tak nejsem přesvědčený, že je nutné disk vyřadit. Řešení by také bylo
btrfs device delete /dev/sde5 / btrfs device add /dev/sde5 / btrfs balance start -mconvert=RAID1 -dconvert=RAID1 -sconvert=RAID1 /
Není ale nějaký jednodušší způsob kdy i se využijí i data, co jsou disku který vypadl. Teoreticky vyjmutí disku při nějaké nepovšimnuté chybě na disku co běží stále, znamená ztrátu dat. Pokud by se jednlo o klasický RAID1 tak se při synchronizaci použijí data z obou disků. Věřím/doufám, že BTRFS je také v tuto chvíli třeba pro rescue, restore a i čtení za běhu použít dokáže.
Pokud byl vyřazený tak s tím souhlasím. Ale pokud se jedná jen o dočasnou ztrátu komunikace, tak bych preferoval řešení, kdy se dají ta data, která jsou na trvale běžícím disku nečitelná, nahradit daty z druhého disku. I když je pravda, že alespoň servisní informace o aktuálnosti bloků musí být čitelná z obou disků.
Vzhledem k tomu, že BTRFS drží generace k jednotlivým inode/záznamům, tak si představuji, že by se ty části, kde se ještě generace ani na trvale přítomném disku nezměnila, mohly v případě problému využít z toho dočasně vypadlého disku. Zároveň po kontrole konzistence dat na vypadlém disku není důvod data, která se neměnila, přesouvat.
Alespoň si myslím, že by to takto mělo jít zařídit, výrazně by to zkrátilo synchronizaci a zároveň by to dávalo naději získat kompletní neporušená data, pokud se vyskytne jen malé množství chyb na obou discích nebo disku, který byl trvale přítomný.
Nezkoumal jsem, jestli výše popsané možnosti nějaká implementace RAID nabízí a zatím se mi zdá, že BTRFS je nenabízí. Takže děkuji za názor, který výše uvedené možnosti zamítá. Předpokládal jsem že servisní data (checsum/nějaká informace o pořadí v sekvenci zápisu) by u klasického RAID to mohla řešit stejně jako případ chybě čtených bloků, ale do kódu jsem se zatím nedíval. Budu rád, pokud mi neexistenci této možnosti potvrdí i další.
PS: smarctl -t long doběhl bez chyby. U předchozí jediné logované chyby jsem se spletl ve výpočtu času a ve skutečnosti power-up hours spadá do období, kdy došlo k ztrátě komunikace s diskem. Logovaná událost
Error 1 occurred at disk power-on lifetime: 10879 hours (453 days + 7 hours) When the command that caused the error occurred, the device was active or idle. After command completion occurred, registers were: ER ST SC SN CL CH DH -- -- -- -- -- -- -- 04 71 09 a9 00 80 40 Device Fault; Error: ABRT at LBA = 0x008000a9 = 8388777 Commands leading to the command that caused the error were: CR FR SC SN CL CH DH DC Powered_Up_Time Command/Feature_Name -- -- -- -- -- -- -- -- ---------------- -------------------- 61 00 18 00 09 01 46 00 4d+15:27:59.335 WRITE FPDMA QUEUED 61 00 80 80 08 01 46 00 4d+15:27:59.335 WRITE FPDMA QUEUED 61 00 80 00 08 01 46 00 4d+15:27:59.335 WRITE FPDMA QUEUED 61 00 80 80 07 01 46 00 4d+15:27:59.335 WRITE FPDMA QUEUED 61 00 68 18 07 01 46 00 4d+15:27:59.335 WRITE FPDMA QUEUED SMART Self-test log structure revision number 1 Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error # 1 Extended offline Completed without error 00% 11260 - # 2 Short offline Completed without error 00% 11253 -
btrfsck
(ten se obvykle nalézá v adresáři /bin
a knihovna libgcc_s.so.1
, která je v /lib/x86_64-linux-gnu
. Bez btrfsck
nelze v ramdisku provést opravu nakopnutého BTRFS a bez té knihovny se zase pro změnu nedá spustit scrub.
Háček je v tom, že btrfsck
se nespouští na namountovaný BTRFS FS, ale přímo na zařízení. Pokud je FS namountované - byť v read-only režimu, tak příkaz selže. Tudíž je třeba, aby byl tento nástroj v ramdisku. Pro scrub platí naopak, že FS musí být namountovaný v rw režimu, jinak nepjede. Takže..
btrfsck --repair --init-extent-tree --init-csum-tree /dev/sda1
Vyzvracelo to za běhu na konzoli hromadu děsivých zpráv, ale výsledek je funkční FS a bez chyb.
Tak nakonec jsem zvolil strategii, btrfs replace dočasně vypadlého disku za nový a druhý replace, abych data dostal na disk zpět. Zdá se, že update s udržením možnosti čtení dat z kopie bez přesunu dat možný není - inplace sync. Diskutovaná byla alternativa na disku, který má data zastaralá zlikvidovat identifikaci BTRFS (první sektory smazat) a pak provést remove missing nebo provést delete a pak opět add a balance. Ale to je všechno se značným rizikem, protože po dobu obnovování budou data jen v jedné kopii. Odpověď na můj dotaz v BTRFS mailing listu:
http://article.gmane.org/gmane.comp.file-systems.btrfs/48930/match=
nebo zde, kdy6 m8 GMANE potížehttps://www.marc.info/?l=linux-btrfs&m=144430491713231&w=2
Obecně se zdá, že BTRFS vždy pracovalo s aktuálními daty a data plněně ochránilo.
A že Btrfs ještě není dostatečně otestovaný pro produkční nasazení? No, to asi nepůjde udělat jinak, než se s tím někdo začne. Tak mi držte palce.Šoupání s daty - publikováno 29.1.2012; Fanless computer - bezvětrákový stroj bez kompromisů - publikováno 7.1.2013; V obou případech jde o jeden a týž Btrfs souborový systém, který si to kroutí už čtvrtým rokem na našem domácím úložišti. V produkčním nasazení používám Btrfs od října 2012 (viz Využití Btrfs k denním zálohám studentských účtů (říjen 2012). A na rozdíl od ext4 jsem u tohoto FS o data nikdy nepřišel - byť mi místy řádně lepilo. Co si tedy představujete pod pojmem - "dostatečně otestovaný"?
To, že to zatím není tak skvělé a radostné jako u mdadm je taky třeba dáno tím, jak dlouho tady ten projekt je a co všechno řeší.A možná taky tím, že se vývojáři btrfs neobtěžovali zjistit, jestli by náhodou nešlo využít existující jaderné implementace kombinování blokových zařízení a případně je rozšířit o to, co ten filesystém potřebuje navíc. Jednodušší zjevně bylo přidat do jádra třetí implementaci RAIDu.
Jednodušší zjevně bylo přidat do jádra třetí implementaci RAIDu.Pojetí redundace v btrfs je zcela odlišné od raidů nad blokovým zařízením exportující další blokové zařízení. Btrfs nemá žádnou raid vrstvu, která by šla (i třeba jen teoreticky) exportovat jako blokové zařízení*. Btrfs řeší redundanci jen jako zápis extentů na vícero zařízení, přičemž ty bloky na dvou různých zařízeních snad ani nejsou stejné a už vůbec ne na stejném místě. Ty bloky by se klidně mohly ukládat i třeba s jinou kompresí (podpora pro to samozřejmě není, ale návrhu to neodporuje). *) Tak to má třeba ZFS, které spojuje device do vdev a vdevy do poolu, ze kterého můžete exportovat block device a filesystem. Tohle má některé výhody (jako třeba možnost snapshotů těch zvolů), ale taky nevýhody v podobě neměnnosti vdevů (pokud se něco nezměnilo, tak jednou postavení vdev nelze měnit - přidat, odebrat disk). Btrfs toto řeší jinak, bloková zařízení jsou prostě jen zásobárna bloků a btrfs nad tím rozhazuje bloky souborů po různých block device. (Což s sebou přináší další možnosti, třeba v podobě možnosti kdykoliv kterýkoliv disk nechat uklidit a odebrat z btrfs apod. a samozřejmě zase jiné problémy.)
Jo, snapshoty jsou (vedle checksumů všech dat) jednou z hlavních killer features Btrfs. Sám ho na zálohování taky používám. (Ovšem čestně přiznávám, že zatím stále ještě v kombinaci s rdiff-backup na ext4. Ono je ale asi vždycky lepší zálohovat alespoň na dva různé filesystémy.) Existuje na to několik nástrojů, ale IMHO je to všechno na téma rsync && read-only snapshot (maximálně doplněné o send/receive s jiným strojem), takže jsem si to napsal taky po svém.
Podstatné je asi jen pouštět ten rsync
s parametry --inplace
a --no-whole-file
, aby se pokud možno nesahalo na části souborů, které nebyly změněné, a tak se maximálně šetřilo místo zachováním jediné kopie dat, která je pak odkazovaná ze všech snapshotů.
Ovšem čestně přiznávám, že zatím stále ještě v kombinaci s rdiff-backup na ext4.Já kombinuju zálohování pomocí snapshotů:
pekny clanek, neresil jsi nahodou i situaci, kde by raidX btrfs bezel na vice zakryptovanych discich? (vcetne rootu)
disk 1 - LUKS -- btrfs raid nad temi LUKSy?
disk 2 - LUKS -/
Vlastne otazka je, jak odemknout oba zakryptovane disky a teprve potom nad tim sestavovat ten btrfs a mountovat rot
... aniz bych musel delat vlastni initram...
Kryptování? To je nějaká zábavná hra v kryptách? Z odkazů na LUKS odhaduji, že mohlo být myšleno šifrování, ale co to má společného s kryptami...
To jsem ale nezkoušel, takže neporadím. :-/ Typově mne ale nenapadá, proč by se to mělo lišit od libovolného jiného filesystému. Jen je tedy potřeba dešifrovat všechna používaná zařízení na začátku, než může dojít k pokusu o mount Btrfs RAIDu. Jaký je problém s tím odemčením obou disků současně?
u jinych fs jsem to resil mdraidem a ten LUKS byl az nad nim. Slo by to tak i u btrfs, ale chci prave zkusit tu mdraid vrsvtu vynechat...
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.