365 lines
11 KiB
Markdown
365 lines
11 KiB
Markdown
---
|
||
title: Howto RAID logiciel sous Linux
|
||
categories: RAID
|
||
...
|
||
|
||
* Documentation : <https://raid.wiki.kernel.org/index.php/Linux_Raid>
|
||
|
||
Sous Linux, on peut utiliser du [RAID](https://fr.wikipedia.org/wiki/RAID_%28informatique%29) logiciel : c'est géré via le module noyau **md-mod** qui permet de faire des volumes RAID0/1/5 (et [autres](https://raid.wiki.kernel.org/index.php/Introduction#The_RAID_levels)) sur des périphériques bloc.
|
||
|
||
|
||
## Installation
|
||
|
||
~~~
|
||
# apt install mdadm
|
||
|
||
$ /sbin/mdadm -V
|
||
mdadm - v3.3.2 - 21st August 2014
|
||
$ /sbin/modinfo md_mod
|
||
filename: /lib/modules/3.16.0-4-amd64/kernel/drivers/md/md-mod.ko
|
||
alias: block-major-9-*
|
||
alias: md
|
||
description: MD RAID framework
|
||
license: GPL
|
||
depends:
|
||
intree: Y
|
||
vermagic: 3.16.0-4-amd64 SMP mod_unload modversions
|
||
parm: start_dirty_degraded:int
|
||
~~~
|
||
|
||
## Création d'un volume RAID
|
||
|
||
On doit ensuite créer des partitions de type *Linux raid autodetect* (code *'FD*') :
|
||
|
||
Par exemple avec `parted` :
|
||
|
||
~~~
|
||
# parted /dev/sdz
|
||
(parted) mkpart logical 51,5GB 200GB
|
||
(parted) align-check optimal 8
|
||
8 aligned
|
||
(parted) set 8 raid on
|
||
(parted) p
|
||
[...]
|
||
8 51,5GB 200GB 148GB logical raid
|
||
~~~
|
||
|
||
Par exemple 2 partitions */dev/sdy1* et */dev/sdz1* de tailles identiques pour créer un volume RAID1.
|
||
On initialise le ainsi le RAID :
|
||
|
||
~~~
|
||
# mdadm --create /dev/md42 --chunk=64 --metadata=default --level=raid1 --raid-devices=2 /dev/sdy1 /dev/sdz1
|
||
# mdadm --query /dev/md42
|
||
/dev/md0: 1332.53GiB raid1 2 devices, 0 spares. Use mdadm --detail for more detail.
|
||
# mdadm --detail /dev/md42
|
||
/dev/md0:
|
||
Version : 1.2
|
||
Creation Time : Fri Nov 19 17:22:46 2010
|
||
Raid Level : raid1
|
||
Array Size : 1397260542 (1332.53 GiB 1430.79 GB)
|
||
Used Dev Size : 1397260542 (1332.53 GiB 1430.79 GB)
|
||
Raid Devices : 2
|
||
Total Devices : 2
|
||
Persistence : Superblock is persistent
|
||
|
||
Update Time : Sat Nov 20 01:05:41 2010
|
||
State : active
|
||
Active Devices : 2
|
||
Working Devices : 2
|
||
Failed Devices : 0
|
||
Spare Devices : 0
|
||
|
||
Name : cap:0 (local to host cap)
|
||
UUID : 02549957:1e2c95c8:306391ad:c979ee50
|
||
Events : 35
|
||
|
||
Number Major Minor RaidDevice State
|
||
0 8 33 0 active sync /dev/sdy1
|
||
1 8 49 1 active sync /dev/sdz1
|
||
~~~
|
||
|
||
Vous avez donc */dev/md42* : un périphérique de stockage utilisable.
|
||
Vous pouvez maintenant le formater, par exemple en _ext4_ :
|
||
|
||
~~~
|
||
# mkfs.ext4 /dev/md42
|
||
~~~
|
||
|
||
Vous devez répéter cette opération pour avoir plusieurs volumes RAID, notamment
|
||
pour avoir plusieurs partitions (/var, /usr/, /home, etc.), vous aurez donc de
|
||
multiples partitions *Linux raid autodetect* sur vos disques.
|
||
|
||
Chaque volume RAID doit être présent dans `/etc/mdadm/mdadm.conf` avec son UUID (c'est géré automatiquement en thérie) :
|
||
|
||
~~~
|
||
ARRAY /dev/md42 UUID=457bb528:02ab827a:a7d2dac2:42fd5302
|
||
~~~
|
||
|
||
## Opérations sur les disques et volumes RAID
|
||
|
||
### Remplacer un disque
|
||
|
||
Cas classique : vous avez un disque défectueux (prenons */dev/sdz*) et plusieurs volumes RAID,
|
||
par exemple *md1*, *md2*, etc. Voici précisément comment le remettre en place :
|
||
|
||
En table de partitions DOS :
|
||
|
||
~~~
|
||
# sfdisk -d /dev/sda > /tmp/part.out
|
||
# sfdisk -f /dev/sdz < /tmp/part.out
|
||
# partprobe /dev/sdz
|
||
~~~
|
||
|
||
En table de partitions GPT (valable à partir de Debian 7) :
|
||
|
||
~~~
|
||
# apt install gdisk
|
||
# sgdisk -R=/dev/sdz /dev/sda
|
||
# sgdisk -G /dev/sdz
|
||
~~~
|
||
|
||
Puis on restaure les partitions, par exemple :
|
||
|
||
~~~
|
||
# mdadm /dev/md1 --add /dev/sdz1
|
||
mdadm: added /dev/sdz1
|
||
# mdadm /dev/md2 --add /dev/sdz2
|
||
mdadm: added /dev/sdz2
|
||
# mdadm /dev/md3 --add /dev/sdz3
|
||
mdadm: added /dev/sdz3
|
||
# mdadm /dev/md5 --add /dev/sdz5
|
||
mdadm: added /dev/sdz5
|
||
# mdadm /dev/md6 --add /dev/sdz7
|
||
mdadm: added /dev/sdz7
|
||
~~~
|
||
|
||
> *Note* : `sfdisk` peut nécessiter d'avoir un disque déjà partitionné, le contournement est de créer une partition quelconque avant de l'utiliser avec un disque vierge.
|
||
|
||
### Sortir une partition d'un volume RAID
|
||
|
||
Si vous devez sortir un disque d'un volume RAID pour une raison ou une autre :
|
||
|
||
~~~
|
||
# mdadm /dev/md42 --fail /dev/sdz1
|
||
mdadm: set /dev/sdz1 faulty in /dev/md42
|
||
# mdadm /dev/md42 --remove /dev/sdz1
|
||
mdadm: hot removed /dev/sdz1 from /dev/md42
|
||
~~~
|
||
|
||
### Désactiver un volume RAID
|
||
|
||
~~~
|
||
# mdadm --stop /dev/md42
|
||
mdadm: stopped /dev/md42
|
||
~~~
|
||
|
||
|
||
### Créer un volume RAID sans disposer de tous les disques
|
||
|
||
On peut vouloir (re-)créer un volume RAID sans pour autant disposer de tous les disques au moment de l'opération (récupération des données d'un ancien disque lorsqu'on ne dispose que de deux emplacements par exemple) :
|
||
|
||
~~~
|
||
# mdadm --create /dev/md42 --level=1 --force --raid-devices=1 /dev/sdy1
|
||
~~~
|
||
|
||
On peut alors formater */dev/md42*, et copier les fichiers dessus, avant d'ajouter le disque manquant à la grappe (remplacement du disque original dans cet exemple) :
|
||
|
||
~~~
|
||
# mdadm --manage /dev/md42 --add /dev/sdz1
|
||
# mdadm --grow /dev/md42 --raid-devices=2
|
||
# cat /proc/mdstat
|
||
Personalities : [raid1]
|
||
md42: active raid1 sdy1[1] sdz1[0]
|
||
1893933820 blocks super 1.2 [2/1] [U_]
|
||
[>....................] recovery = 4.0% (75859776/1893933820) finish=493.5min speed=61391K/sec
|
||
~~~
|
||
|
||
### Vérification d'un volume RAID
|
||
|
||
Pour lancer une vérification d'un volume RAID :
|
||
|
||
~~~
|
||
# /usr/share/mdadm/checkarray /dev/md42
|
||
checkarray: I: check queued for array md42.
|
||
|
||
# cat /proc/mdstat
|
||
md42: active raid1 sdw1[3] sdx1[0] sdy1[1] sdy1[2]
|
||
203712 blocks [4/4] [UUUU]
|
||
[==========>..........] check = 52.0% (106240/203712) finish=1.5min speed=1032K/sec
|
||
~~~
|
||
|
||
> *Note* : attention, cette vérification est évidemment gourmande en I/O disque
|
||
|
||
Pour annuler une vérification en cours :
|
||
|
||
~~~
|
||
# /usr/share/mdadm/checkarray --cancel /dev/md42
|
||
checkarray: I: cancel request queued for array md42.
|
||
~~~
|
||
|
||
|
||
## Monitoring
|
||
|
||
Pour voir les volumes RAID en activité :
|
||
|
||
~~~
|
||
# mdadm --detail --scan
|
||
~~~
|
||
|
||
### Le fichier /proc/mdstat
|
||
|
||
Ce pseudo-fichier contient la liste des volumes RAID avec le type, l'état, les disques utilisés :
|
||
|
||
~~~
|
||
# cat /proc/mdstat
|
||
md1 : active raid1 sdb1[1] sda1[0]
|
||
512896 blocks [2/2] [UU]
|
||
|
||
md2 : active raid1 sdb2[1] sda2[0]
|
||
1023936 blocks [2/2] [UU]
|
||
|
||
md3 : active raid1 sdb3[1] sda3[0]
|
||
10239936 blocks [2/2] [UU]
|
||
~~~
|
||
|
||
Le *[UU]* indique que les disques sont opérationnels. Si un des disques est en erreur, le *U* sera remplacé par un _.
|
||
|
||
|
||
### Le démon mdadm
|
||
|
||
Un démon _mdadm_ est lancé par défaut pour détecter la panne d'un disque dur (entre autre), et envoyer un email le cas échéant.
|
||
|
||
~~~
|
||
# ps -ef |grep mdadm
|
||
root 3858 1 0 Apr15 ? 00:00:19 /sbin/mdadm --monitor --pid-file /var/run/mdadm/monitor.pid --daemonise --scan --syslog
|
||
~~~
|
||
|
||
On s'assurera que le fichier */etc/default/mdadm* contient les informations :
|
||
|
||
~~~
|
||
INITRDSTART='all'
|
||
AUTOSTART=true
|
||
AUTOCHECK=true
|
||
START_DAEMON=true
|
||
~~~
|
||
|
||
Dès qu'une panne disque est détectée, mdadm inscrit l'information dans _syslog_ :
|
||
|
||
~~~
|
||
May 10 14:28:44 serveur mdadm[3858]: Fail event detected on md device /dev/md42, component device /dev/sdz1
|
||
~~~
|
||
|
||
Un mail est également envoyé à root (par défaut) pour l'informer de la situation. Le destinataire du mail peut se changer dans le fichier de configuration */etc/mdadm/mdadm.conf* grâce à la directive *MAILADDR* :
|
||
|
||
~~~
|
||
MAILADDR notification@example.com
|
||
~~~
|
||
|
||
### mdadm day
|
||
|
||
Tous les 1er dimanches du mois, un script est lancé en crontab pour lancer une vérification de tous les volumes RAID :
|
||
|
||
~~~
|
||
$ grep -v ^# /etc/cron.d/mdadm
|
||
|
||
57 0 * * 0 root if [ -x /usr/share/mdadm/checkarray ] && [ $(date +\%d) -le 7 ]; then /usr/share/mdadm/checkarray --cron --all --idle --quiet; fi
|
||
~~~
|
||
|
||
Si nécessaire d'interrompre cette vérification : `/usr/share/mdadm/checkarray --cancel --all`
|
||
|
||
## Plomberie
|
||
|
||
### superblock
|
||
|
||
<https://raid.wiki.kernel.org/index.php/RAID_superblock_formats>
|
||
|
||
Le RAID logiciel sous Linux réserve un peu de place sur chaque périphérique : c'est le **superblock**.
|
||
Cet espace contient les _metadatas_ : taille, journal, bitmap (si activé), bad blocks log, etc.
|
||
Il y a plusieurs formats de superblock (0.9, 1, 1.0, 1.1…) : le défaut est désormais **1.2**
|
||
|
||
Avec le format 1.2, 4K sont réservés au début du périphérique pour les _metadatas_. Cela rend indispensable la compréhension de ce format pour son utilise (exemple : GRUB doit forcément comprendre le format 1.2 pour pouvoir lire les données).
|
||
|
||
|
||
## FAQ
|
||
|
||
### Changer la taille du cache
|
||
|
||
Pour synchroniser un volume RAID (la valeur par défaut de 4096K) :
|
||
|
||
~~~
|
||
# echo 32768 > /sys/block/md42/md/stripe_cache_size
|
||
~~~
|
||
|
||
> *Note* : Attention, cela consomme davantage de CPU/RAM.
|
||
|
||
### Activer le bitmap
|
||
|
||
Cela permet d'identifier les blocs modifiés et gagner du temps en cas de future resynchronisation.
|
||
|
||
~~~
|
||
# mdadm --grow --bitmap=internal /dev/md42
|
||
~~~
|
||
|
||
> **Note** : C'est activé par défaut en Debian 8. Avec des méta-donées en v1.20.
|
||
|
||
### Erreur "does not have a valid v0.90 superblock"
|
||
|
||
Si vous obtenez des erreurs du type :
|
||
|
||
~~~
|
||
kernel: md: invalid raid superblock magic on sda1
|
||
kernel: md: sda1 does not have a valid v0.90 superblock, not importing!
|
||
~~~
|
||
|
||
C'est que l'auto-détection du noyau Linux n'a pas fonctionné (il paraît que c'est [obsolète](http://bugs.debian.org/627281)).
|
||
|
||
Il faut donc manuellement ajouter les lignes correspondant au volume RAID dans le fichier `/etc/mdadm/mdadm.conf` grâce à l'outil `/usr/share/mdadm/mkconf`.
|
||
|
||
### Erreur "does not appear to be active"
|
||
|
||
Si un volume est inactif (par exemple après le changement d'un disque) :
|
||
|
||
~~~
|
||
# cat /proc/mdstat
|
||
Personalities : [raid1] [raid6] [raid5] [raid4]
|
||
md9 : inactive sda10[0](S) sdc10[2](S) sdb10[5](S)
|
||
5568856791 blocks super 1.2
|
||
~~~
|
||
|
||
Vous avez beau tout faire pour le réactiver :
|
||
|
||
~~~
|
||
# mdadm /dev/md9 --remove /dev/sdd10
|
||
# mdadm --stop /dev/md9
|
||
# mdadm --assemble /dev/md9
|
||
# mdadm --detail /dev/md9
|
||
mdadm: md device /dev/md9 does not appear to be active.
|
||
# mdadm --stop /dev/md9
|
||
# mdadm --assemble --force /dev/md9
|
||
mdadm: device 4 in /dev/md9 has wrong state in superblock, but /dev/sdd10 seems ok
|
||
mdadm: /dev/md9 assembled from 3 drives and 1 spare - not enough to start the array while not clean - consider --force.
|
||
~~~
|
||
|
||
Mais rien à faire, votre volume reste inactif… même avec 4 disques :
|
||
|
||
~~~
|
||
# cat /proc/mdstat
|
||
Personalities : [raid1] [raid6] [raid5] [raid4]
|
||
md9 : inactive sda10[0](S) sdd10[4](S) sdc10[2](S) sdb10[5](S)
|
||
7425142388 blocks super 1.2
|
||
~~~
|
||
|
||
La solution est d'invoquer une prière vaudoue et de lancer `--assemble --force --scan` :
|
||
|
||
~~~
|
||
# mdadm --stop /dev/md9
|
||
mdadm: stopped /dev/md9
|
||
# mdadm --assemble --force --scan /dev/md9
|
||
mdadm: clearing FAULTY flag for device 3 in /dev/md9 for /dev/sdd10
|
||
mdadm: Marking array /dev/md9 as 'clean'
|
||
mdadm: failed to add /dev/sdd10 to /dev/md9: Device or resource busy
|
||
mdadm: /dev/md9 has been started with 3 drives (out of 4).
|
||
~~~
|
||
|
||
Votre volume est désormais actif, il vous reste qu'à ajouter le nouveau disque pour lancer la reconstruction.
|