1. Quelques mésaventures (vécues) avec le matériel
Il y a quelques années déjà, on entendait souvent que le RAID ne pouvait que se concevoir en matériel, toute autre solution n'étant que pure hérésie. Le RAID 5 a connu ses heures de gloire, on en trouvait à tous les étages, pour tous les usages, du système aux données, voire aux bases de données.
Les temps ont changé. Quelques valeureux pionniers ont soulevé de vraies questions sur les besoins et les conséquences réels sur les performances [1].
Il m'est arrivé de voir un contrôleur matériel de RAID défaillir sur un serveur. Sur cette gamme, les contrôleurs n'étaient pas redondés, d'une part, et les métadonnées de la grappe de RAID n'étaient copiés sur les disques. La conséquence évidente est qu'en plus de la rupture de service sur la panne matérielle, il a fallu repartir d'une sauvegarde pour restaurer ce qui était supposé pérenne.
Récemment, un ami m'a raconté ses malheurs sur une implémentation de RAID matériel qui, en raison d'un microcode défectueux du contrôleur a planté l'intégralité de la grappe.
En se penchant uniquement sur l'aspect des performances, on envisage généralement la solution câblée comme la plus performante, et c'est peut-être le cas, mais il est aussi des situations où le matériel ne suffit pas. Dans une grappe de RAID 0 qui comporte quelques dizaines de volumes, il est possible de saturer un processeur, généralement RISC, et limiter ainsi le débit maximal en sortie du contrôleur. Pour le même genre de situation, avec un RAID logiciel, qui utilise les processeurs du système, les performances pour l'exécution des applications sont un peu grevées, mais il y a de fortes chances pour saturer le bus avant de saturer le processeur.
Les autres cas dans lesquels le matériel ne suffit pas comptent les réplications sur des technologies différentes. Localement, ce pourrait être entre des disques sur des busIDE/SCSI/SATA/SAS/USB/IEEE1394, à distance entre des cibles iSCSI, des LUN sur Fibre Channel ou autre, comme un périphérique bloc exporté en GNBD ou répliqué par DRBD. Le RAID matériel ne se conçoit dans le matériel que sur des bus identifiés d'un même constructeur, avec des technologies identiques. À travers le réseau (SAN ou banalisé), il faut aussi compter avec les constructeurs de matériels qui ne permettent des réplications qu'entre baies de même marque/modèle.
Enfin, la mise en place d'une grappe de RAID matérielle impose de disposer de toutes les ressources en nombre suffisant. Le logiciel nous permet de forcer la création de grappes ne comportant pas tous les morceaux requis et de modeler à chaud sa disposition.
Certaines des options ou fonctionnalités décrites ci-après peuvent entraîner la suppression irréversible de toutes les données préalablement enregistrées sur vos disques. Bien entendu, je décline toute responsabilité sur les commandes que vous pourriez exécuter d'après le contenu de cet article. Avant de créer ou supprimer des volumes, assurez-vous de disposer de sauvegardes utilisables, et testez préalablement les restaurations de données.
Toute distribution qui livre mdadm et les modules noyau correspondant à ses attentes permet de mettre en place une solution à base de RAID logiciel.
Les différences seront visibles surtout sur les outils d'administration annexes et la possibilité de le gérer dès l'installation.
L'article suivant propose une comparaison de différentes solutions de RAID logiciel, soit à l'aide de mdadm, soit à l'aide de LVM2, et, si possible, grâce à la souplesse du device-mapper. Nous verrons comment quelques distributions se positionnent dans la gestion au quotidien de ces configurations.
La plupart des comparaisons portent sur le RAID 1 et les miroirs de LVM.
Néanmoins, certains exemples décrivent d'autres niveaux de RAID (comme le RAID 4 ou 5).
2. Création de RAID sans disposer de toutes les ressources
Cas pratique : Vous recevez une livraison de disques, mais il en manque une partie. La suite doit arriver sous peu. Vous pouvez déjà commencer votre configuration avec la partie à votre disposition, quitte à ajouter quelques disques plus tard.
Ceci fonctionne pour les niveaux de RAID 1, 4 et 5.
Pour les exemples, les options longues « humainement lisibles » sont utilisées, mais consultez la page de manuel de mdadm(8) [2] pour trouver les options courtes équivalentes.
Voici un exemple de création d'une matrice RAID 5 avec seulement 2 volumes en forçant une taille maximale :
% sudo mdadm --create /dev/md1 --auto=yes --force \
--level=5 --raid-devices=2 --size=$[ 1024 * 1024 * 50 ] /dev/sd{e,f}1
mdadm: largest drive (/dev/sde1) exceed size (52428800K) by more than 1%
Continue creating array? y
mdadm: array /dev/md1 started.
Le détail de la création de cette grappe de RAID est visible dans /proc/mdstat.
% cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md1 : active raid5 sdf1[1] sde1[0]
52428800 blocks level 5, 64k chunk, algorithm 2 [2/2] [UU]
[>....................] resync = 4.5% (2388736/52428800) finish=13.1min
speed=63327K/sec
unused devices: <none>
Les messages concernant la synchronisation du RAID sont consultables dans /var/log/messages. Par exemple :
Jul 8 11:48:46 localhost kernel: md: resync of RAID array md1
Jul 8 11:48:46 localhost kernel: md: minimum _guaranteed_ speed: 1000 KB/sec/disk.
Jul 8 11:48:46 localhost kernel: md: using maximum available idle IO bandwidth (but not more than 200000 KB/sec) for resync.
Jul 8 11:48:46 localhost kernel: md: using 128k window, over a total of 52428800 blocks.
Jul 8 11:53:09 localhost kernel: sd 6:0:0:0: [sdg] 625142448 512-byte hardware sectors (320073 MB)
Jul 8 11:53:09 localhost kernel: sd 6:0:0:0: [sdg] Write Protect is off
Jul 8 11:53:09 localhost kernel: sd 6:0:0:0: [sdg] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
Jul 8 11:53:09 localhost kernel: sdg: sdg1
Jul 8 11:53:11 localhost kernel: sd 6:0:0:0: [sdg] 625142448 512-byte hardware sectors (320073 MB)
Jul 8 11:53:11 localhost kernel: sd 6:0:0:0: [sdg] Write Protect is off
Jul 8 11:53:11 localhost kernel: sd 6:0:0:0: [sdg] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
Jul 8 11:53:11 localhost kernel: sdg: sdg1
Jul 8 11:53:41 localhost kernel: md: md1: resync done.
Jul 8 11:53:41 localhost kernel: md: checkpointing resync of md1.
Pour le cas du LVM, et si l'on se cantonne au RAID 1, il est possible de convertir un volume logique qui ne comporte qu'un linear mapping en un volume logique avec une copie en miroir. La création initiale est tout à fait classique, et la conversion sera traitée ci-après.
Pour réaliser cette opération, je supposerai que je dispose de trois partitions. Deux partitions ont la même taille de 5 Gio. La troisième est plus petite et ne fait que quelques Mio. Ces partitions sont intégrées dans un groupe de volumes data.
L'opération de « transformation » en miroir est réalisée à l'aide de la commande lvconvert. L'option -m 1 utilisée ici spécifie un miroir qui comporte une face (un peu comme les miroirs de la vraie vie).
% sudo pvcreate /dev/sd{e,f,g}1
Physical volume "/dev/sde1" successfully created
Physical volume "/dev/sdf1" successfully created
Physical volume "/dev/sdg1" successfully created
% sudo vgcreate data /dev/sd{e,f,g}1
Volume group "data" successfully created
% sudo pvs data
PV VG Fmt Attr PSize PFree
/dev/sde1 data lvm2 a- 93,14G 93,14G
/dev/sdf1 data lvm2 a- 93,14G 93,14G
/dev/sdg1 data lvm2 a- 100,00M 100,00M
% sudo lvcreate -L93,14G data /dev/sde1
Rounding up size to full physical extent 93,14 GB
Logical volume "lvol0" created
% sudo lvs data/lvol0
LV VG Attr LSize Origin Snap% Move Log Copy%
lvol0 data -wi-a- 93,14G
% sudo lvconvert -m1 data/lvol0
Logical volume lvol0 converted.
% sudo lvs data/lvol0
LV VG Attr LSize Origin Snap% Move Log Copy%
lvol0 data mwi-a- 93,14G lvol0_mlog 0,13
% sudo lvs data/lvol0 -o+devices
LV VG Attr LSize Origin Snap% Move Log Copy% Devices
lvol0 data mwi-a- 93,14G lvol0_mlog 4,37 lvol0_mimage_0(0),lvol0_mimage_1(0)
Sans avoir précisé d'option particulière, les commandes LVM2 sont plutôt silencieuses. Pour obtenir des informations plus détaillées lors de la création du miroir, l'option -v passée à lvconvert aurait satisfait notre curiosité, notamment en parlant de la création d'un volume logique nommé lvol0_mlog, puis de deux autres appelés lvol0_mimage_0 et lvol0_mimage_1.
La commande pvs décrit l'utilisation d'extent sur les volumes physiques. On constate alors que trois volumes physiques sont réellement utilisés. Les deux plus grands sont utilisés pour stocker les données. Le troisième (le plus petit dans ce cas) est utilisé pour le mirror log.
% sudo pvs --sort vg_name|grep data
/dev/sde1 data lvm2 a- 93,14G 0
/dev/sdf1 data lvm2 a- 93,14G 0
/dev/sdg1 data lvm2 a- 100,00M 96,00M
Pour voir plus précisément comment les extents ont été consommés dans les différents volumes physiques, la commande pvdisplay est appropriée.
% sudo pvdisplay -v -m /dev/sd{e,f,g}1
Using physical volume(s) on command line
Wiping cache of LVM-capable devices
--- Physical volume ---
PV Name /dev/sde1
VG Name data
PV Size 93,14 GB / not usable 2,06 MB
Allocatable yes (but full)
PE Size (KByte) 4096
Total PE 23844
Free PE 0
Allocated PE 23844
PV UUID Hv3Rai-UOfs-pwJW-v3S9-l6k7-vZez-mSGDN7
--- Physical Segments ---
Physical extent 0 to 23843:
Logical volume /dev/data/lvol0_mimage_0
Logical extents 0 to 23843
--- Physical volume ---
PV Name /dev/sdf1
VG Name data
PV Size 93,14 GB / not usable 2,06 MB
Allocatable yes (but full)
PE Size (KByte) 4096
Total PE 23844
Free PE 0
Allocated PE 23844
PV UUID Dq0xYY-dVJG-sEGx-Yuri-zKeF-TeuO-SZalLp
--- Physical Segments ---
Physical extent 0 to 23843:
Logical volume /dev/data/lvol0_mimage_1
Logical extents 0 to 23843
--- Physical volume ---
PV Name /dev/sdg1
VG Name data
PV Size 101,94 MB / not usable 1,94 MB
Allocatable yes
PE Size (KByte) 4096
Total PE 25
Free PE 24
Allocated PE 1
PV UUID maLyq3-s9WV-CcSp-HCUj-3IAw-F0XR-cerOzG
--- Physical Segments ---
Physical extent 0 to 0:
Logical volume /dev/data/lvol0_mlog
Logical extents 0 to 0
Physical extent 1 to 24:
FREE
LVM a beaucoup pris sur lui pour prendre des décisions judicieuses comme choisir les bons volumes physiques pour le miroir et le log. Il est aussi possible de spécifier des volumes physiques préférentiels.
3. Redimensionnement des grappes de RAID
Cas pratique : Les disques sont livrés, nous allons pouvoir les introduire dans les grappes de RAID, et, encore mieux, la livraison comprend des disques supplémentaires de taille supérieure, ce qui nous sera très utile pour cette application/base de données qui est un peu à l'étroit.
Cette intervention comprendra deux volets. Tout d'abord, nous allons introduire le volume manquant dans la grappe, puis nous allons modifier la taille de la grappe de RAID.
Deux options sont envisageables à ce niveau, la solution utilisant mdadm ou celle utilisant LVM2. En fait, il existe aussi d'autres possibilités combinant ces deux options, mais nous les évoquerons ultérieurement.
3.1 Redimensionnement avec mdadm
Le mode Grow de mdadm permet aussi bien le changement de géométrie d'une grappe de RAID, comme l'ajout de membres dans une grappe, que l'agrandissement des volumes.
3.1.1 Ajout de membres
Sur une grappe en miroir qui aurait été créée comme suit :
% sudo mdadm -C /dev/md1 -l1 -n2 /dev/sd{c,d}1
mdadm: array /dev/md1 started.
On peut ajouter un troisième membre dans la grappe. Ce membre passe immédiatement en volume de secours (spare).
% sudo mdadm /dev/md1 --add /dev/sdb1
mdadm: added /dev/sdb1
% cat /proc/mdstat
Personalities : [raid1]
md1 : active raid1 sdb1[2](S) sdd1[1] sdc1[0]
97667072 blocks [2/2] [UU]
unused devices: <none>
% sudo mdadm --grow /dev/md1 --raid-devices=3
% cat /proc/mdstat
Personalities : [raid1]
md1 : active raid1 sdb1[3] sdd1[1] sdc1[0]
97667072 blocks [3/2] [UU_]
[>....................] recovery = 1.2% (1176768/97667072) finish=25.9min speed=61935K/sec
unused devices: <none>
Si l'on surveille l'état de /proc/mdstat, on voit une synchronisation se dérouler. Au moment de l'ajout du volume comme membre de la grappe, ce nouveau volume passe en spare. Il peut être utilisé dans la grappe en cas de défaillance, mais n'est pas un membre intégrant tant que la structure de la grappe ne comporte pas explicitement le nombre de volumes requis. /proc/mdstat comprenait deux volumes (option --raid-devices=2).
3.1.2 Changement de la taille
Envisageons une grappe qui aurait été créée avec une taille de 50 Go. C'est juste la moitié de l'espace disponible.
% sudo mdadm -C /dev/md1 -a yes -l1 -n2 --size=$[ 1024 * 1024 * 50 ] /dev/sd{c,d}1
mdadm: largest drive (/dev/sdc1) exceed size (52428800K) by more than 1%
Continue creating array? y
mdadm: array /dev/md1 started.
L'agrandissement du volume au final devient possible en raison de la disponibilité des disques de taille supérieure. Nous pouvons à nouveau invoquer le mode Grow.
% sudo mdadm --grow /dev/md1 --size=max
% cat /proc/mdstat
Personalities : [raid1]
md1 : active raid1 sdd1[1] sdc1[0]
97667072 blocks [2/2] [UU]
[==========>..........] resync = 53.8% (52590848/97667072) finish=9.2min speed=81024K/sec
Là encore, en regardant le contenu de /proc/mdstat, on peut voir la synchronisation se poursuivre pour la partie non encore utilisée des disques. Il est possible à ce niveau de spécifier l'emplacement d'un journal d'activité sur disque pour assurer la section critique et récupérer en cas de panne, de crash ou de coupure de courant l'opération à partir de l'interruption.
Ce type de journal peut être particulièrement intéressant pour les changements de géométrie des grappes de niveaux de RAID 5.
3.2 Redimensionnement avec LVM2
Si certaines opérations se révèlent naturelles avec LVM, comme le déplacement de données, d'autres sont moins évidentes ou, au pire, à prévoir pour des versions futures.
Certains termes sont bien propres à LVM. On parlera de face de miroir pour évoquer une copie des données d'une source à une destination.
3.2.1 Ajout d'une face de miroir
Justement, en quoi consiste une face de miroir ? C'est tout simplement une copie réalisée dans un sens. Si on utilise une face de miroir supplémentaire, il y aura une copie supplémentaire.
En pratique, l'ajout d'une face de miroir est réalisé à l'aide de la commande lvconvert. Si un volume logique n'est pas copié en miroir, son compteur de copies (ou de faces de miroir) est de 0.
Pour une seule face de miroir, le compteur passera à 1.
L'ajout d'une première face de miroir nécessite normalement deux volumes physiques disponibles. L'un des volumes servira à la copie à proprement parler, tandis que l'autre est utilisé pour le journal du miroir. Il est possible d'utiliser un journal en mémoire, sous certaines contraintes. Pour choisir un type de journal, on utilise l'option --mirrorlog, par défaut. Il s'agit du miroir sur disque.
% sudo lvconvert -m1 data/lvol0
Pour les copies supplémentaires, un seul volume physique est nécessaire.
3.2.2 Agrandissement d'un volume logique en miroir
Le redimensionnement des volumes en miroir avec LVM2 n'est pas encore possible à chaud, mais il est possible de redimensionner à froid une grappe selon deux méthodes. La première consiste à désactiver un volume logique en miroir et le redimensionner quand il est désactivé, ce qui implique un arrêt de service.
% sudo lvcreate -L50G -m1 data
Logical volume "lvol0" created
% sudo lvresize data/lvol0 -l+50%FREE
Extending 2 mirror images.
Mirrors cannot be resized while active yet.
% sudo lvchange -an data/lvol0
% sudo lvresize data/lvol0 -l+50%LV
Extending 2 mirror images.
Extending logical volume lvol0 to 75,00 GB
Logical volume lvol0 successfully resized
% sudo lvchange -ay data/lvol0
La seconde méthode consiste à briser le miroir et à agrandir le volume logique avant de recréer le miroir. L'avantage est bien entendu que les données restent disponibles durant la procédure d'agrandissement, mais, pendant cette période critique, il n'y a plus de miroir.
% sudo lvconvert -m0 data/lvol0
Logical volume lvol0 converted.
% sudo lvresize data/lvol0 -l+50%LV
Extending logical volume lvol0 to 75,00 GB
Logical volume lvol0 successfully resized
% sudo lvconvert -m1 data/lvol0 --mirrorlog core /dev/sdf1
Logical volume lvol0 converted.
Avec cette dernière commande, le miroir initialement sur disque passe en mémoire.
4. Suppression définitive des membres d'une grappe de RAID
Pour terminer ce petit tour de chauffe, un peu de ménage permet de récupérer nos volumes pour une autre utilisation. L'option --zero-superblock permet de supprimer, comme son nom d'indique, le superblock de la grappe de RAID qui est copié dans les derniers 128 Kio de chacun de ses membres. Cette technique qui peut nous sauver de l'écrasement accidentel à coup de dd a aussi quelques inconvénients, parce qu'il faut s'assurer de supprimer cette partie pour pouvoir cesser définitivement l'utilisation d'un block device dans du RAID.
Dans le cas d'une panne franche de matériel, il n'y a pas de souci. Éventuellement, on peut vouloir supprimer en une fois tous les périphériques manquants.
% sudo mdadm /dev/md1 --fail detached --remove detached
L'utilisation du mot-clef detached fait référence à tous les périphériques pour lesquels on rencontre un ENXIO lors de l'ouverture.
Pour un disque toujours présent, mais que l'on souhaite ôter, il est possible d'utiliser --fail avant la suppression effective.
% sudo mdadm /dev/md4 --fail /dev/sde4 --remove failed
mdadm: set /dev/sde4 faulty in /dev/md4
mdadm: hot removed 7:1
On peut évidemment nommer explicitement le volume à supprimer.
% sudo mdadm /dev/md4 --remove /dev/sdf4 --remove /dev/sde4
mdadm: set /dev/sdf4 faulty in /dev/md4
mdadm: hot removed 7:2
Il est conseillé de supprimer le superblock pour effacer définitivement toute trace de l'appartenance d'un volume à une grappe.
% sudo mdadm /dev/md1 --zero-superblock /dev/sdb1
La suppression de toute la grappe avec effacement des superblocks est réalisée avec la commande :
% sudo mdadm --stop /dev/md1
% sudo mdadm --zero-superblock /dev/sd{c,d}1
4.1 Oubli de suppression du superblock avec mdadm
Il peut arriver cependant d'oublier d'effacer la copie du superblock lors d'une suppression (avec mdadm --stop), et il peut aussi arriver que l'on ne supprime pas les méta-données non plus lors de la suppression d'un membre d'une grappe RAID.
Le problème risque de n'être visible qu'au prochain assemblage de la grappe. Le problème du problème est que ça n'arrivera peut-être que lors du prochain redémarrage, et que vous aurez certainement d'autres choses à gérer à ce moment.
Si lors d'une exécution d'un mdadm --examine --scan vous avez deux lignes pour la même grappe de RAID, c'est certainement que vous n'avez pas écrasé les superblocks.
% sudo mdadm --examine --scan
ARRAY /dev/md4 level=raid4 num-devices=2 UUID=00956a87:7bea1d12:199823ab:b4c469a5
ARRAY /dev/md4 level=raid5 num-devices=2 UUID=9f514030:37ea9f87:c04be955:dbd529da
Dans cet exemple, j'ai une vieille grappe de RAID 5 qui ne peut pas être assemblée, mais qui empêchera peut-être l'assemblage de la grappe RAID 4 qui devrait être dans un état utilisable.
L'effacement définitif des scories de métadonnées de RAID peut être réalisé simplement à l'aide de la commande dd. L'exemple qui suit utilise une taille de bloc de 512 octets. Les métadonnées sont copiées sur les derniers 128 Ko de chaque membre de la grappe.
% sudo dd count=256 seek=$(( $(blockdev --getsize $DEV) -256 )) if=/dev/zero of=/dev/sdd1
Pour vérifier que la grappe de RAID 5 a bien disparu, il suffit de tout réexaminer. Ici, la sortie de la commande indique que c'est corrigé.
% sudo mdadm --examine --scan
ARRAY /dev/md0 level=raid4 num-devices=2 UUID=00956a87:7bea1d12:199823ab:b4c469a5
4.2 Suppression d'une des faces d'un miroir de volume logique
La commande lvconvert permet de modifier quelques caractéristiques des volumes logiques. L'option qui va nous intéresser ici concerne le nombre de miroirs à créer. Pour le briser, il suffit de spécifier le volume à exclure.
% sudo lvconvert -m0 data/lvol0 /dev/sde1
data/lvol0: Converted: 100,0%
Logical volume lvol0 converted.
La conversion dans ce cas consiste tout simplement à supprimer le volume physique souhaité.
Pour réintroduire le second volume physique dans le miroir :
% sudo lvconvert -m1 data/lvol0 --mirrorlog core /dev/sde1 /dev/sdf1
5. Obtenir de l'information
5.1 Information avec mdadm
- /proc/mdstat
Cette entrée de /proc permet d'obtenir des informations sur toutes les grappes assemblées. Ces informations sont néanmoins concises, mais en cas de synchronisation suite à l'ajout d'un volume dans une grappe ou en cas d'utilisation d'un volume de secours, une barre de progression est affichée.
Ces informations sont certainement à recouper avec des messages de la facility kernel qui peuvent être redirigés par syslog dans /var/log/messages, /var/log/syslog ou encore /var/log/kern.log.
% cat /proc/mdstat
Un affichage en « temps réel » s'obtient avec une commande comme :
% watch -n1 cat /proc/mdstat
- mdadm --detail /dev/mdN
La page de manuel de mdadm liste énormément d'options, et certaines sont particulièrement intéressantes pour consulter des informations détaillées grappe par grappe.
Cette commande fournit des informations précises sur les membres d'une grappe de RAID, l'état de chacun des membres et de la grappe elle-même. Normalement, on passe en argument le nœud de périphérique associé à une grappe, mais on peut aussi utiliser l'option --scan et la commande aura alors une sortie similaire à celle de mdadm --examine --scan.
- mdadm --export
Cette commande produit une sortie très compacte. C'est d'ailleurs la même sortie qu'avec mdadm --query.
% sudo mdadm --export /dev/md1
/dev/md1: 50.00GiB raid1 2 devices, 0 spares. Use mdadm --detail for more detail.
Avec l'option --detail, la sortie change radicalement pour devenir une suite de définition de variables en shell.
% sudo mdadm --export --detail /dev/md1
MD_LEVEL=raid1
MD_DEVICES=2
MD_METADATA=0.90
MD_UUID=8e5b37aa:6ae1403e:5a43d41a:774645b1
% sudo mdadm --export --detail /dev/md0
MD_LEVEL=raid4
MD_DEVICES=3
MD_METADATA=0.90
MD_UUID=00956a87:7bea1d12:199823ab:b4c469a5
Ces variables pourraient être utilisées par d'autres outils.
- mdadm --examine-bitmap
Dans le cas d'utilisation d'une intent-bitmap, d'autres informations peuvent être consultées. Comme la bitmap peut être stockée dans un fichier externe ou en interne dans la grappe elle-même, on peut soit passer en argument l'emplacement du fichier, soit l'emplacement d'un des membres de la grappe.
% sudo mdadm --examine-bitmap /dev/sdc1
Filename : /dev/sdc1
Magic : 6d746962
Version : 4
UUID : 3ba7be1c:6a2026c6:9cfd4a7e:6a1b1af6
Events : 6
Events Cleared : 6
State : OK
Chunksize : 128 KB
Daemon : 5s flush period
Write Mode : Normal
Sync Size : 52428800 (50.00 GiB 53.69 GB)
Bitmap : 409600 bits (chunks), 0 dirty (0.0%)
Ce type d'optimisation sera détaillé un peu plus tard.
5.2 Information avec LVM2
Les informations que l'on peut obtenir avec LVM viennent de deux séries d'utilitaires pvdisplay/vgdisplay/lvdisplay et pvs/vgs/lvs.
Les informations obtenues à l'aide des {pv,vg,lv}display sont en général plus détaillées, mais il est aussi possible d'obtenir des informations très intéressantes à l'aide des versions synthétiques.
La page de manuel des commandes pvs/vgs/lvs présente aussi des options pour obtenir des profils d'affichages différents. Dans le contexte qui nous intéresse pour recouper l'emplacement physique des extents réellement utilisés sur nos volumes physiques, l'utilisation de -o +devices est incontournable.
% sudo pvs -o +devices
% sudo vgs -o +devices
% sudo lvs -o +devices
De même, pour décrire l'informations relative aux différents objets de manière détaillée, on peut utiliser pvdisplay/vgdisplay/lvdisplay. Pour pvdisplay, l'option -m permet aussi d'obtenir des détails très intéressants sur les différents segments utilisés dans un volume physique avec l'énumération précise des extents de début et de fin pour chaque segment.
% sudo pvdisplay
% sudo pvdisplay -v -m /dev/{e,f,g}1
% sudo vgdisplay
% sudo lvdisplay
6. Déplacement de données
L'une des caractéristiques des miroirs que l'on ne retrouve pas dans la vraie vie est que les miroirs logiciels peuvent avoir plus de deux faces. C'est notamment grâce à cette propriété que nous pouvons créer des copies à chaud et les supprimer tout aussi facilement.
6.1 Déplacement avec mdadm
Le déplacement de données est réalisé en quelques étapes :
1. ajout du nouveau volume en tant que secours ;
2. agrandissement de la grappe ;
3. suppression si besoin de l'ancien morceau ;
4. réduction de la grappe.
Ces quelques étapes peuvent être enrichies de paramètres facultatifs et d'étapes intermédiaires facultatives. Par ailleurs, les deux premières étapes peuvent être inversées.
En pratique, on utiliserait une séquence comme ce qui suit :
% sudo mdadm -C /dev/md1 -l1 -n2 /dev/sd{c,d}1
mdadm: array /dev/md1 started.
% sudo mdadm /dev/md1 -a /dev/sdb1
mdadm: added /dev/sdb1
% sudo mdadm --grow /dev/md1 -n3
% sudo mdadm /dev/md1 -f /dev/sdc1 -r failed
mdadm: set /dev/sdc1 faulty in /dev/md1
mdadm: hot removed 8:33
% sudo mdadm --grow /dev/md1 -n2
En RAID 5, on peut modifier la géométrie d'une grappe et sauvegarder la portion critique dans un fichier externe. En cas d'interruption du processus, pour des raisons de plantage, coupure de courant, etc., on peut reprendre l'agrandissement au moment de l'interruption.
Avant de supprimer un membre d'une grappe de RAID, il faut bien entendu s'assurer que le reste est correctement synchronisé. À défaut, on peut imaginer casser la grappe et la rendre temporairement voire définitivement inutilisable. Normalement, on n'atteint jamais de telles extrémités, parce que mdadm refuse ces opérations par un Device or resource busy.
Par exemple, si l'on est un peu trop pressé, on obtiendrait un message comme :
% sudo mdadm /dev/md1 -f /dev/sdc1 -r failed
mdadm: set /dev/sdc1 faulty in /dev/md1
mdadm: hot remove failed for 8:33: Device or resource busy
Pour surveiller les grappes, on peut toujours utiliser mdadm --detail ou /proc/mdstat ou contrôler les messages envoyés à syslog.
6.2 Déplacement avec LVM2
Les étapes pour migrer les données en utilisant exclusivement LVM2 sont les suivantes :
1. ajout d'un volume physique ;
2. intégration de ce volume physique dans un groupe de volumes ;
3. extension du volume logique sur le nouveau volume physique ;
4. exclusion de l'ancien volume physique du groupe de volume ;
5. suppression du volume physique si nécessaire.
Le déplacement des données à chaud a lieu lors de la synchronisation des données à l'étape 3. On peut d'ailleurs suivra la synchronisation à l'aide de l'option -i de lvconvert pour spécifier un intervalle d'affichage de l'avancement.
% sudo pvcreate /dev/sdh1
Physical volume "/dev/sdh1" successfully created
% sudo vgextend data /dev/sdh1
Volume group "data" successfully extended
% sudo lvconvert -m2 data/lvol0 --mirrorlog core /dev/sdh1
% sudo vgextend mirror /dev/sdg4
Volume group "mirror" successfully extended
% sudo lvconvert -m2 data/lvol0 --mirrorlog core /dev/sd{e,f,h}1
data/lvol0: Converted: 0,9%
data/lvol0: Converted: 1,8%
...
data/lvol0: Converted: 100,0%
Logical volume lvol0 converted.
% sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 vg0 lvm2 a- 372,41G 32,00M
/dev/sde1 data lvm2 a- 93,14G 18,14G
/dev/sdf1 data lvm2 a- 93,14G 18,14G
/dev/sdg1 data lvm2 a- 100,00M 100,00M
/dev/sdh1 data lvm2 a- 93,14G 18,14G
% sudo lvs data -o+devices
LV VG Attr LSize Origin Snap% Move Log Copy% Convert Devices
lvol0 data mwi-a- 75,00G 14,06 lvol0_mimage_0(0),lvol0_mimage_1(0),lvol0_mimage_2(0)
La suppression du premier volume serait réalisée par la séquence ci-après :
% sudo lvconvert -m1 data/lvol0 --mirrorlog core /dev/sde1
Logical volume lvol0 converted.
% sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 vg0 lvm2 a- 372,41G 32,00M
/dev/sde1 data lvm2 a- 93,14G 93,14G
/dev/sdf1 data lvm2 a- 93,14G 18,14G
/dev/sdg1 data lvm2 a- 100,00M 100,00M
/dev/sdh1 data lvm2 a- 93,14G 18,14G
% sudo lvs data
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
lvol0 data mwi-a- 75,00G 3,42
lvol0 mirror mwi-a- 52,00M 100,00
% sudo vgreduce data /dev/sde1
Removed "/dev/sde1" from volume group "data"
% sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 vg0 lvm2 a- 372,41G 32,00M
/dev/sde1 lvm2 -- 93,14G 93,14G
/dev/sdf1 data lvm2 a- 93,14G 18,14G
/dev/sdg1 data lvm2 a- 100,00M 100,00M
/dev/sdh1 data lvm2 a- 93,14G 18,14G
% sudo pvremove /dev/sde1
Labels on physical volume "/dev/sde1" successfully wiped
Sur des volumes logiques de taille respectable, il faudra certainement s'armer de patience. Pour surveiller l'avancement de la migration, on peut utiliser lvs et lvdisplay. Dans l'exemple ci-avant, l'utilisation de pvs est également intéressante, parce qu'elle illustre l'allocation des extents sur le volume physique de destination.
Normalement, à ce moment de la lecture, l'utilisateur de LVM2 qui a déjà migré des données s'insurge parce qu'il y a beaucoup plus simple pour faire la même chose. C'est vrai, la commande pvmove sert exactement à cela, et, en une seule commande, on spécifie le ou les volumes que l'on souhaite migrer.
% sudo pvmove -n data/lvol /dev/sde1 /dev/sdh1 /dev/sde1: Moved: 100,0%
Mais en réalité, pvmove procède de la même façon, à savoir qu'il fabrique un miroir, synchronise les données, puis brise le miroir et libère les extents utilisés. Il y a surtout une limitation, c'est que pvmove n'est pas prévu pour migrer les données d'un miroir. Les synchronisations de copies multiples sont donc à exclure par ce biais.
Conclusion
Le RAID matériel n'est pas la seule et unique option de réplication. Sous certaines conditions, les miroirs logiciels sont les seuls à même de répondre aux besoins.
Pour de nombreux cas d'utilisation, les fonctionnalités de redimensionnement et de migration de données à chaud dépassent largement les alternatives uniquement matérielles.
Plusieurs solutions existent et, grâce au device-mapper de Linux, il est facile de les combiner (ou les empiler) pour obtenir des solutions à la fois technologiquement sexy et très commodes à administrer.
Bien entendu, rien n'est gratuit, et la souplesse s'acquiert certainement au prix de performances un peu moindres.
Le prochain article abordera précisément des pistes d'améliorations de performances et les combinaisons de RAID et LVM.
Références
[1] http://www.baarf.com/ – BAARF – Battle against all RAID F... level
[2] Les pages de manuel de mdadm, mdadm.conf ainsi que les multiples pages de manuel de lvm et ses sous-commandes. À ce titre, man -k lvm est votre ami.
Remerciements
Je remercie les Mongueurs francophones pour la relecture.