Linux SW RAID

Z Wiki UnArt Slavičín
Verze z 7. 5. 2012, 09:18, kterou vytvořil Dulik (diskuse | příspěvky) (→‎Přidání disku do pole)
(rozdíl) ← Starší verze | zobrazit aktuální verzi (rozdíl) | Novější verze → (rozdíl)
Skočit na navigaciSkočit na vyhledávání

V Linuxu můžeme použít 3 typy RAIDů:

  • Linux SW RAID, který je realizován kompletně Linux-em
  • FakeRAID neboli SW RAID v BIOSu počítače, který je realizován BIOSem, ale nad kterým v Linux-u máme kontrolu jen v případě, že máme funkční Linux driver k chipsetu, který tento SW RAID realizuje
  • plně HW RAID - v základních sestavách běžných počítačů a serverů jej nehledejte, za řadič plně HW RAID si musíte připlatit. Z vlastní neblahé zkušenosti HW RAID doporučuji pouze v případě, kdy máte více strojů se stejným řadičem, jinak v případě, že máte stroj pouze 1, řadič umře a stejný se už dávno neprodává, už z disků s např. RAID5 data neodstanete. Proto HW RAID v tomto článku nebudu vůbec řešit.

Výhody a nevýhody FakeRAIDu a Linux SW RAIDu

Jeden aspekt, který nemůžu srovnat, je hotswap disků. V Linux SW RAID je hotswap jednoduchý (viz níže). Jak se hotswap disků dělá v BIOS (Fake) RAIDu, netuším, nikdy jsem to nezkoušel.

Linux SW RAID

  • Výhody:
    • pokud máte hotswap disky a správně nakonfigurovaný systém (viz kapitola o Hotswap), můžete za plného provozu serveru (bez výpadku služeb) odstranit pokažený disk a místo něj dát čerstvý nový. Nastavení nového disku totiž děláte z příkazové řádky Linuxu.
    • do Linux SW RAIDu lze zapojit různě velké disky - nezapojují se totiž celé disky, ale jejich partitions. Pokud po letech provozu selže jeden ze starých disků a do RAIDu vložíme nový disk s násobnou velikostí, není jeho zbylá volná kapacita promarněna - můžeme ji využít na ukládání nekritických dat, popř. můžeme zbylou kapacitu do RAIDu zapojit později, až vyměníme i ten zbývající starý malý disk
    • Linux SW RAID je nezávislý na HW počítače. Pokud shoří základní deska a disky přežijí, můžete disky vložit do jakéhokoli jiného počítače a server máte okamžitě znovu online, v plné parádě včetně funkčního RAIDu, bez potřeby jakéhokoli nastavování v Linuxu.
    • Linux SW RAID je plně funkční, odladěný a stabilní systém, určený pro nasazení v ostrém provozu. Což se mnohdy od Linux driverech BIOS SW RAIDu nedá říci.


  • Nevýhody:
    • je potřeba se naučit syntaxi příkazů mdadm :-)
    • ve srovnání s plně HW RAIDem asi menší rychlost a větší zátěž CPU

FakeRAID - BIOS SW RAID

  • Výhody:
    • Je možný dual-boot Windows-Linux, oba OS vidí RAID jako jeden disk (u Linux serverů vás ale tato výhoda asi nezaujme..)
    • Jednoduché ovládání - nemusíte se učit syntaxi příkazů mdadm :-)
    • disky v SW BIOS RAIDu se v Linux-u tváří jako jeden disk, takže můžete nabootovat např. z nějakého live CD, které nemusí podporovat Linux SW RAID, a přesto uvidíte ten samý disk, který je stále plně funkční RAID, zatímco u disků Linux SW RAIDu byste viděli jeho jednotlivé komponenty. Novější Live CD si ale Linux SW RAID dokážou nadetekovat a normálně poskládat.


  • Nevýhody:
    • Problémy s výkonem - viz tento report problému 50% výkonu čtení a 25% výkonu zápisu ve srovnání s Linux SW RAID
    • pokud jeden z disků v RAIDu umře a výrobce FakeRAIDu neposkytuje SW k jeho správě přímo ve vašem OS, pak musíte po vložení nového disku rebootovat a v BIOSu nový disk nastavit. Váš server bude v té době offline. Toto u Linux RAIDu nehrozí, pokud jsou vaše disky hotswap.
    • Pokud umře základní deska, musíte najít nějakou se stejným BIOSem/chipsetem, jinak svoje diskové pole nesložíte. U RAID1 (mirroring) budete schopni provozovat aspoň jeden disk, ale pokud budete chtít poskládat z disků svého bývalého RAIDu opět funkční pole, s jiným BIOSem/chipsetem budete mít asi smůlu. V takovém případě budete muset vytvořit nové prázdné pole a na ně nahrát data ze zálohy.
    • Linux nemusí mít ovladač pro daný BIOS SW RAID, nebo ovladač nemusí být stabilní - viz např. FakeRAID pro chipset ICH9. Což je u nového HW vcelku běžný problém. Pokud nemáte funkční ovladač, nedokážete pole z Linuxu ovládat, tj. nedokážete za provozu přidávat další disky, neuvidíte vzniklé chyby, neuvidíte postup synchronizace u nového disku atd.
    • Většina BIOS SW RAIDů neumožňuje nastavovat parametry typu "Minimální/maximální rychlost synchronizace", což může ovlivnit výkon vašeho serveru v době, kdy by se synchornizace prováděla

Ovládání Linux SW RAID

Hotswap disků

Správná otázka: umí Linux SW RAID hotswap? Tj. můžu přijít k serveru, vytrhnout z něj za provozu disk bez toho, abych jej musel nejdřív na příkazové řádce označit jako vadný, a pak jej do systému za provozu vrátit? Tak, jak to umožňují plně HW RAID řadiče?

Odpověď je: ano, je to možné. Návod jsem sepsal na wiki Linux RAIDu.

Přidání disku do pole

Pokud chceme přidat do pole disk (např. poté, co jsme jej odstranili při výpadku pomocí mdadm -f), použijeme např. tyto příkazy:

mdadm -a /dev/md0 /dev/sda1
mdadm -a /dev/md1 /dev/sda2
mdadm -a /dev/md2 /dev/sda3

Popřípadě se dá použít i

mdadm --re-add /dev/md0 /dev/sda1

Pokud chcete v modu RAID1 spustit resynchronizaci ihned po přidání disku do serveru, pak zvyšte počet disků v RAID1:

mdadm --grow -n 3 /dev/md0

Rozdíl mezi "--add" a "--re-add" by měl být v tom, že re-add by při přidávání disku, který jsme před chvílí odebrali, při použití "write-intent bitmap" neměl dělat kompletní resync. Skutečnost je taková, že v takovém případě kompletní resync nevyvolá ani "--add".

Místo ručního přidávání disků můžete použít i tento skript, který výše uvedené příkazy udělá za vás - ale jen v případě, kdy již disk byl v poli zapojen a jednotlivé jeho RAID partitions mají na sobě všechna potřebná metadata, takže příkaz "mdadm --examine --scan /dev/sda1" vytiskne "ARRAY /dev/md0 level=raid1 num-devices=2 UUID=...", tj zjistí, do kterého RAID zařízení daná partition patří:

#!/bin/bash
# Tento skript uložte v /usr/local/sbin/add-all-raid-parts
for i in $( ls $1* ); do
       #split the output of mdadm scan ("ARRAY /dev/md? level=raid1 num-devices=2 UUID=...")
       #so MD_DEVICE will contain /dev/md?
       read -d ] ARR MD_DEVICE REST< <(IFS=' '; echo `mdadm --examine --scan $i`)
       if [ "" != "$MD_DEVICE" ]; then
               echo "Adding $i into RAID device=$MD_DEVICE"
               mdadm -a $MD_DEVICE $i
       fi
done

Skript pak můžete zavolat např. takto:

add-all-raid-parts /dev/sda

Výpadek disku

Odstranění vadného disku

Pokud je disk zcela mrtvý nebo odpojený - prostě není v zařízeních /dev/ a nemáte rozjetý hotplug, musíte odstranit tento disk z vašeho pole takto:

mdadm /dev/mdX --fail detached --remove detached

Pokud disk ještě máte v zařízeních /dev (tj. pokud ještě nějakým způsobem žije, UDEV systém nebo reboot jej ještě neodstranil), označte jej jako vadný a odstraňte jej z pole, například takto:

mdadm -f /dev/md0 /dev/sda1; mdadm -r /dev/md0 /dev/sda1
mdadm -f /dev/md1 /dev/sda2; mdadm -r /dev/md1 /dev/sda2
mdadm -f /dev/md2 /dev/sda3; mdadm -r /dev/md2 /dev/sda3
...

Option -f označí partition jako vadnou ("failed"), option -W (--wait) čeká na dokončení předchozí operace, option -r odstraní partition z RAIDu.

To samé za vás provede tento skript:

#!/bin/bash
#Tento skript uložte v /usr/local/sbin/fail-all-raid-parts
MDADM=/sbin/mdadm
for i in $( ls $1* ); do
       #split the output of mdadm scan ("ARRAY /dev/md? level=raid1 num-devices=2 UUID=...")
       #so MD_DEVICE will contain /dev/md?
       read -d ] ARR MD_DEVICE REST< <(IFS=' '; echo `$MDADM --examine --scan $i`)
       if [ "" != "$MD_DEVICE" ]; then
               echo "Failing $i from RAID device=$MD_DEVICE"
               $MDADM -f $MD_DEVICE $i
               $MDADM -W $MD_DEVICE
               $MDADM -r $MD_DEVICE $i
       fi
done


Pro testování kompletního výpadku disku můžete využít tento skript.

Přidání nového disku místo vadného

Nejdřív si ze zbylého dobrého disku (např. /dev/sda) zkopírujeme partition table na nový (např. /dev/sdc):

# sfdisk -d /dev/sda | sfdisk /dev/sdc

Pak přidáme nové partitions do jednotlivých raid polí pomocí

#mdadm --add /dev/mdX /dev/sdXY

Pokud těch partitions (nebo disků) máte moc nechce se vám to dělat ručně, můžete si napsat skriptík jako např.:

#for mdnr in 0 1 2; do pnr=$((mdnr+1)); mdadm --add /dev/md$mdnr /dev/sdc$pnr /dev/sdd$pnr; done

Bootovatelnost: nahrání GRUB bootloaderu do MBR nového

Pokud je na disku systém a má být bootovatelný, musíme ještě do MBR nainstalovat grub. O tom, že disk nemá v MBR boot loader, se můžete přesvědčit třeba takto:

xeric:~# dd if=/dev/sdd bs=512 count=1 | hexdump
1+0 records in
1+0 records out
512 bytes (512 B) copied0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
, 2.5337e-05 s, 20.2 MB/s
00001b0 0000 0000 0000 0000 0000 0000 0000 0180
00001c0 0001 fefd ffff 003f 0000 2941 0254 fe00
00001d0 ffff fefd ffff 2980 0254 f08b 0380 fe00
00001e0 ffff fefd ffff 1a0b 05d5 2b76 1747 fe00
00001f0 ffff fefd ffff 4581 1d1c 8e3a 1d1a aa55
0000200

Vidíme, že až do adresy 0x1b0 jsou v MBR samé nuly, což asi nebude bootloader.

Proto uděláme toto:

#grub
grub> find /boot/grub/stage1

Tento příkaz najde všechny disky, na kterých je soubor "stage1", který GRUB potřebuje při boot-u. Příkaz vypíše třeba toto:

find /boot/grub/stage1
 (hd0,0)
 (hd1,0)
 (hd3,0)

Můj nový disk je "hd3", takže udělám toto:

grub> root (hd3,0)
root (hd3,0)
 Filesystem type is ext2fs, partition type 0xfd
grub> setup (hd3)
setup (hd3)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd3)"...  17 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd3) (hd3)1+17 p (hd3,0)/boot/grub/stage2 /boot/grub/menu.lst"... succeeded
Done.
grub> quit
quit

O tom, že se dílo podařilo, se můžete přesvědčit opět příkazem

xeric:~# dd if=/dev/sdc bs=512 count=1 | hexdump
1+0 records in
1+0 records out
512 bytes (512 B) copied, 2.2194e-05 s, 23.1 MB/s
0000000 48eb 0090 0000 0000 0000 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
0000030 0000 0000 0000 0000 0000 0000 0000 0203
0000040 00ff 2000 0001 0000 0200 90fa f690 80c2

(atd)

0000190 7369 006b 6552 6461 2000 7245 6f72 0072
00001a0 01bb b400 cd0e ac10 003c f475 00c3 0000
00001b0 0000 0000 0000 0000 0000 0000 0000 0180
00001c0 0001 fefd ffff 003f 0000 2941 0254 fe00
00001d0 ffff fefd ffff 2980 0254 f08b 0380 fe00
00001e0 ffff fefd ffff 1a0b 05d5 2b76 1747 fe00
00001f0 ffff fefd ffff 4581 1d1c 8e3a 1d1a aa55
0000200

Nastavení parametrů synchronizace

Po přidání disku do pole začne Linux na něj synchronizovat data RAID pole. Jak rychle se bude tato synchronizace provádět, můžeme sami ovládat a tím určovat, kolik % volného CPU a IO času sychronizace zabere, a to pomocí nastavení proměnných /proc/sys/dev/raid/speed_limit_min (defaultně má hodnotu 1000) a /proc/sys/dev/raid/speed_limit_max (defaultně má hodnotu 200000).

Pokud chceme synchronizaci rychlejší, proveďte tento příkaz

echo 200000 > /proc/sys/dev/raid/speed_limit_min

Jak zabránit plné resynchronizaci při pádu systému nebo vyjmutí disku

Pokud následkem nějaké chyby (násilné vyjmutí disku, pád OS) dojde k tomu, že se pole rozsynchronizuje, čeká vás zdlouhavá resynchronizace - defaultně se resync dělá v RAID1 jako prostá kopie "čisté" RAID partitiony do té "špinavé" (dirty). U RAID partitions, které mají stovky GB, si počkáte i několik hodin.

V těchto případech se ale dá kompletní resynchronizaci zabránit použitím tzv. "write intent bitmapy", kterou vytvoříte takto:

for mddev in /dev/md[0-9]*; do mdadm --grow --bitmap=internal $mddev; done

Popř. pokud chcete přidat bitmapu jen na některá RAID pole:

for mdnr in 3 4 5; do mdadm --grow --bitmap=internal /dev/md$mdnr; done

Více viz stránka o Linux SW RAID bitmapách na RAID wiki kernel.org

Monitoring RAIDu

Postup synchronizace

Pokud přidáme do RAIDu disk, můžeme sledovat postup jeho synchronizace např. takto:

watch cat /proc/mdstat

Což vypíše u plně synchronizovaných RAID zařízení:

md0 : active raid1 sda1[0] sdb1[1]
     497856 blocks [2/2] [UU]

A u RAID zařízení, kde synchornizace právě probíhá:

md1 : active raid1 sda2[2] sdb2[1]
     468752512 blocks [2/1] [_U]
     [=>...................]  recovery =  5.4% (25333888/468752512) finish=66.8min speed=110468K/sec

Status synchronizace se vypisuje také příkazem

mdadm --detail /dev/md1

Který při synchronizaci vypíše toto:

/dev/md1:
       Version : 00.90
 Creation Time : Mon Jan  4 15:06:14 2010
    Raid Level : raid1
    Array Size : 468752512 (447.04 GiB 480.00 GB)
 Used Dev Size : 468752512 (447.04 GiB 480.00 GB)
  Raid Devices : 2
 Total Devices : 2
Preferred Minor : 1
   Persistence : Superblock is persistent

   Update Time : Thu Mar 18 10:34:57 2010
         State : clean, degraded, recovering
Active Devices : 1
Working Devices : 2
Failed Devices : 0
 Spare Devices : 1

Rebuild Status : 6% complete

          UUID : 511ea31a:0a968ed8:25791403:81883028
        Events : 0.826942

   Number   Major   Minor   RaidDevice State
      2       8        2        0      spare rebuilding   /dev/sda2
      1       8       18        1      active sync   /dev/sdb2

Zasílání emailů

Ze všeho nejvíc nás zajímá chvíle, kdy jeden disk v RAIDu selže - budeme chtít, aby nám systém poslal email. V Debian-u je to jednoduché - při instalaci balíku mdadm se také automaticky spustí mdadm v monitor módu jako démon, takže stačí jen v souboru /etc/mdadm/mdadm.conf nastavit řádky

MAILADDR mujmail@mojedomena.cz
MAILFROM mujmail@mojedomena.cz

Pojmenování disků podle šachty, ve které jsou zastrčené

Viz můj článek na wiki Debianu

Přejmenování RAID zařízení: mdX->mdY

Tuto operaci budete potřebovat asi jen v případě, kdy budete chtít přidat disky s RAIDem z jednoho počítače do jiného, ve kterém už RAID je, a budete jim chtít přidělit nějaké vaše vlastní jméno. Příklad přejmenování md0 na md6:

mdadm --stop /dev/md0
mdadm --assemble /dev/md6 [--super-minor=0] --update=super-minor /dev/sda5 /dev/sdb5

První příkaz stopne RAID na /dev/md0, aby mohl provést změny v superblocích jeho disků. Druhý příkaz poskládá ("assemble") RAID /dev/md6 z disků, které byly součástí /dev/md0, což zařídí nepovinná podmínka "--super-minor=0". Vysvětlení: Každý disk, který je součástí RAIDu, má ve svém superbloku zapsáno číslo "minor", které odpovídá číslu N jména RAID zařízení /dev/mdN. Proto také u libovolného disku, který byl součástí Linux RAID pole a který připojíte do počítače, můžete zjistit jméno mdN RAID zařízení, do kterého disk patřil, pomocí příkazu "mdadm --examine --scan /dev/sdXY"

Option "--update=super-minor" pak zařídí, aby se při operaci assemble v superblocích disku přepsalo minor číslo disku z (/dev/md)0 na (/dev/md)6

Vynulování superblock-u

Pokud uděláte při správě chybu jako já:

#mdadm --add /dev/md0 /dev/sdc

Tj. přidáte do pole celý disk místo jedné partition (což samozřejmě jde), je jediným řešením pro návrat zpátky odstranění superblock-u:

#mdadm --zero-superblock /dev/sdc

Zvětšení RAID zařízení včetně LVM

Lze udělat plně online. Postup:

  • z mdX, které chci zvětšit, odeberu 1 starý disk (--fail a --remove)
  • přidám do mdX nový disk s větší partition a udělám
mdadm --grow /dev/mdX --size=max

následně vyhodím i druhý starý disk a přidám jeho novou větší partition-u do mdX také. Nakonec zvětším LVM physical volume:

pvresize /dev/mdX

Potřebuju změnit velikost partitions (včetně systémového), na nové není místo, co dělat?

  • zapojte do systému jakýkoli nový disk, na kterém vytvoříme správný partitioning.
  • boot from SystemRescueCD (výhoda: malé CD, které umí 32bit i 64bit a má všechny nástroje pro správu disků)
  • Stopněte md0, pokud jede:
mdadm --stop /dev/md0
  • a nahoďte si jej pod jiným jménem (nebojte, změna jména nemá žádné trvalé následky:)
mdadm --assemble /dev/md10 /dev/sd?? /dev/sd??
  • vytvořte nový md0 s novým diskem
mdadm --create /dev/md0 --level=raid1 --raid-devices=1 /dev/nejaky_novy_disk
mkfs.ext2 /dev/md0
  • namountujte obě RAID zařízení:
mount /dev/md10 /media/old
mount /dev/md0 /media/new
  • zkopírujte obsah:
rsync -a /media/old /media/new
  • nainstalujte grub:
mount -o bind /dev/ /media/new/dev
mount -o bind /proc/ md0/proc
mount -o bind /sys/ md0/sys
chroot /dev/new
grub-install /dev/md0
  • zkuste, jestli nabootujete. Já jsem nenabootoval a musel jsem udělat ještě toto:
#grub
grub> find /boot/grub/stage1
find /boot/grub/stage1
 (hd0,0)
 (hd1,0)
 (hd3,0)
grub> root (hd0,0)
root (hd0,0)
 Filesystem type is ext2fs, partition type 0xfd
grub> setup (hd0)
setup (hd0)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd0)"...  17 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd0) (hd0)1+17 p (hd0,0)/boot/grub/stage2 /boot/grub/menu.lst"... succeeded
Done.
grub> root (hd1,0)
root (hd1,0)
 Filesystem type is ext2fs, partition type 0xfd
grub> setup (hd1)
setup (hd1)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd1)"...  17 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd1) (hd1)1+17 p (hd1,0)/boot/grub/stage2 /boot/grub/menu.lst"... succeeded
Done.
grub> root (hd3,0)
root (hd3,0)
 Filesystem type is ext2fs, partition type 0xfd
grub> setup (hd3)
setup (hd3)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd3)"...  17 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd3) (hd3)1+17 p (hd3,0)/boot/grub/stage2 /boot/grub/menu.lst"... succeeded
Done.
grub> quit
quit
  • Obsah boot sektoru si můžete prohlédnout např. takto:
dd if=/dev/sda bs=512 count=1 | hexdump
  • pokud ano, zkopírujte na nový disk i obsah ostatních disků
  • Namountuj
  • mount -o bind /dev/ /media/md0