Laisser un commentaire

Diagnostiquer et récupérer une défaillance RAID

Dans la quasi-totalité des cas, le RAID apporte une redondance qui permet de tolérer la perte d’un ou plusieurs disques. Néanmoins, il faut d’une part savoir lorsqu’une défaillance se produit pour agir, et d’autre part, savoir quoi faire. Il ne suffit pas d’enlever le disque défaillant et d’en mettre un autre à la place pour que tout rentre dans l’ordre. Petit manuel de survie dans l’admin d’un RAID.

Comme expliqué en introduction, tous les niveaux de RAID mis à part le RAID 0 sont tolérants aux pannes. Le seuil de tolérance dépend du nombre de disques, du niveau de RAID et de la configuration de ce dernier. Mon article sur les niveaux de RAID vous permet de calculer la tolérance aux pannes de votre configuration.

Le diagnostique

Tout commence par la connaissance. On ne peut en effet pas régler un problème que l’on ignore. Par défaut, mdstat envoie un mail à root lorsque le RAID est en état dégradé. Selon votre configuration, vous ne recevez pas forcément les mails adressés à root. Vous pouvez néanmoins modifier l’adresse à laquelle l’email est envoyé dans /etc/mdadm/mdadm.conf. Il faut alors modifier la ligne :

MAILADDR mon-email@mail.com

Néanmoins, lorsque le RAID passe en dégradé, c’est en général que vous avez totalement perdu un disque. Or plus on a connaissance des problèmes tôt, plus on peut y remédier facilement. Pour ma part, je jette souvent un coup d’œil aux logs système pour voir s’il n’y a pas trace d’erreurs ou de secteurs défaillants sur le disque.

Je vous conseille d’installer Logwatch. Ce logiciel vous permettra de recevoir tous les jours (ou toutes les semaines), un rapport de l’activité de vos serveurs. Par ailleurs, l’article explique aussi commencer installer un serveur d’envois d’email (utile si vous n’en avez pas déjà un pour recevoir les alertes mdadm).

Que vous ayez configuré Logwatch ou que vous inspectiez les logs manuellement dans /dev/log/syslog, ou recherchez des erreurs de ce type :

end_request: I/O error, dev sdb, sector 3848483864

Si vous voyez de telles erreurs disque, il est conseillé de regarder de plus prêt l’état smart de vos disques. Commencez par lister vos différents disques et partitions avec fdisk -l ou parted -l (si vous avez des partitions gpt).

root@st1:~# parted -l
Modèle: ATA ST2000DM001-1CH1 (scsi)
Disque /dev/sda : 2000GB
Taille des secteurs (logiques/physiques): 512B/4096B
Table de partitions : gpt

Numéro  Début   Fin     Taille  Système de fichiers  Nom      Fanions
 1      20,5kB  1049kB  1029kB                       primary  bios_grub
 2      2097kB  21,0GB  21,0GB  ext4                 primary  raid
 3      21,0GB  2000GB  1979GB  ext4                 primary  raid
 4      2000GB  2000GB  536MB   linux-swap(v1)       primary


Modèle: ATA HGST HUS724020AL (scsi)
Disque /dev/sdb : 2000GB
Taille des secteurs (logiques/physiques): 512B/512B
Table de partitions : gpt

Numéro  Début   Fin     Taille  Système de fichiers  Nom      Fanions
 1      20,5kB  1049kB  1029kB                       primary  bios_grub
 2      2097kB  21,0GB  21,0GB  ext4                 primary  raid
 3      21,0GB  2000GB  1979GB                       primary  raid
 4      2000GB  2000GB  536MB                        primary


Modèle: ATA HGST HUS724020AL (scsi)
Disque /dev/sdc : 2000GB
Taille des secteurs (logiques/physiques): 512B/512B
Table de partitions : gpt

Numéro  Début   Fin     Taille  Système de fichiers  Nom      Fanions
 1      20,5kB  1049kB  1029kB                       primary  bios_grub
 2      2097kB  21,0GB  21,0GB  ext4                 primary  raid
 3      21,0GB  2000GB  1979GB                       primary  raid
 4      2000GB  2000GB  536MB   linux-swap(v1)       primary


Modèle: ATA HGST HUS724020AL (scsi)
Disque /dev/sdd : 2000GB
Taille des secteurs (logiques/physiques): 512B/512B
Table de partitions : gpt

Numéro  Début   Fin     Taille  Système de fichiers  Nom      Fanions
 1      20,5kB  1049kB  1029kB                       primary  bios_grub
 2      2097kB  21,0GB  21,0GB  ext4                 primary  raid
 3      21,0GB  2000GB  1979GB                       primary  raid
 4      2000GB  2000GB  536MB   linux-swap(v1)       primary


Modèle: Matrice RAID Logiciel sous Linux (md)
Disque /dev/md2 : 21,0GB
Taille des secteurs (logiques/physiques): 512B/4096B
Table de partitions : loop

Numéro  Début  Fin     Taille  Système de fichiers  Fanions
 1      0,00B  21,0GB  21,0GB  ext4


Modèle: Matrice RAID Logiciel sous Linux (md)
Disque /dev/md3 : 3958GB
Taille des secteurs (logiques/physiques): 512B/4096B
Table de partitions : loop

Numéro  Début  Fin     Taille  Système de fichiers  Fanions
 1      0,00B  3958GB  3958GB  ext4

On constate ici que j’ai quatre disques physiques de 2TB chacun sur lesquels reposent deux RAID logiciels (/dev/md2 et /dev/md3). Comme nous l’avions vu juste au dessus, nous avons des erreurs de lecture dues à des secteurs défaillants sur le sdb. On inspecte alors plus minutieusement l’état smart de ce disque :

root@st1:~# smartctl -a -d ata /dev/sdb
smartctl 5.41 2011-06-09 r3365 [x86_64-linux-3.10.23-xxxx-std-ipv6-64-rescue] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net

[…]

SMART Attributes Data Structure revision number: 10
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000f   111   099   006    Pre-fail  Always       -       120551345
  3 Spin_Up_Time            0x0003   095   095   000    Pre-fail  Always       -       0
  4 Start_Stop_Count        0x0032   100   100   020    Old_age   Always       -       32
  5 Reallocated_Sector_Ct   0x0033   097   097   036    Pre-fail  Always       -       4008
  7 Seek_Error_Rate         0x000f   077   060   030    Pre-fail  Always       -       4351310992
  9 Power_On_Hours          0x0032   079   079   000    Old_age   Always       -       18725
 10 Spin_Retry_Count        0x0013   100   100   097    Pre-fail  Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   020    Old_age   Always       -       32
183 Runtime_Bad_Block       0x0032   100   100   000    Old_age   Always       -       0
184 End-to-End_Error        0x0032   100   100   099    Old_age   Always       -       0
187 Reported_Uncorrect      0x0032   089   089   000    Old_age   Always       -       11
188 Command_Timeout         0x0032   100   100   000    Old_age   Always       -       0 0 0
189 High_Fly_Writes         0x003a   100   100   000    Old_age   Always       -       0
190 Airflow_Temperature_Cel 0x0022   068   056   045    Old_age   Always       -       32 (Min/Max 26/35)
191 G-Sense_Error_Rate      0x0032   100   100   000    Old_age   Always       -       0
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       31
193 Load_Cycle_Count        0x0032   100   100   000    Old_age   Always       -       46
194 Temperature_Celsius     0x0022   032   044   000    Old_age   Always       -       32 (0 16 0 0)
197 Current_Pending_Sector  0x0012   082   082   000    Old_age   Always       -       3056
198 Offline_Uncorrectable   0x0010   082   082   000    Old_age   Offline      -       3056
199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
240 Head_Flying_Hours       0x0000   100   253   000    Old_age   Offline      -       18708h+109m+27.415s
241 Total_LBAs_Written      0x0000   100   253   000    Old_age   Offline      -       24242600021
242 Total_LBAs_Read         0x0000   100   253   000    Old_age   Offline      -       112149279603

[…]

Nous observons à la ligne 1 que de très nombreux secteurs – 120551345 ! – sont devenus illisibles. L’âge du disque constaté à la ligne 9 confirme qu’il est vieux – 18725/24 = 780 jours soit plus de deux ans en fonction non-stop. Au vu du nombre d’erreurs, ce disque aurait déjà dû passer à la poubelle il y a longtemps, et vu son âge, il a fait son temps. Il faut maintenant le remplacer par un neuf.

Bien qu’un disque soit fatigué, votre RAID n’est pas forcément dans un état dégradé. Lorsque le RAID est en degraded, cela signifie qu’il est toujours opérationnel mais qu’au moins un disque est sorti de l’array. Cependant, lorsque l’on constate qu’un disque est dans un état d’usure avancé, il est plus prudent de le remplacer sans attendre.

On peut vérifier l’état du raid en affichant la sortie du fichier /proc/mdstat :

root@st1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md3 : active raid6 sdc3[2] sdd3[3] sda3[0]
      3865011200 blocks level 6, 512k chunk, algorithm 2 [4/3] [U_UU]

md2 : active raid1 sdc2[2] sdd2[3] sda2[0]
      20478912 blocks [4/3] [U_UU]

On constate ici qu’un disque est sorti de l’array puisque dans le md2 comme dans le md3 on a [4/3]. Ce qui signifie que seulement trois disques sur les quatre de l’array sont en fonction et que c’est le deuxième [U_UU] qui est sorti du RAID. md3 est un raid6 constitué des partitions sdc3, sdd3 et sda3. On en déduit alors que c’est sdb qui est défaillant.

L’opération

L’opération consiste à changer le disque. En général, le plus simple est d’éteindre la machine pour changer le disque, il est cependant possible de le faire à chaud. Si vous souhaitez le faire sans éteindre la machine, il vous faudra alors retirer le disque défectueux du RAID.

Il est pour des raisons évidentes impossible de sortir un disque non défectueux d’un array en fonctionnement. On marque tout d’abord notre disque comme étant défectueux s’il n’est pas déjà hors du RAID. Dans notre cas, si sdb n’était pas sorti, nous aurions dû retirer les partitions sdb3 et sdb2 des RAID md2 et md3 :

mdadm --manage --set-faulty /dev/md2 /dev/sdb2
mdadm --manage --set-faulty /dev/md3 /dev/sdb3

Une fois que le disque défectueux est déconnecté du ou des RAID, on peut le débrancher en toute sécurité et le remplacer par un neuf.

Une fois le nouveau disque installé, il n’est même pas partitionné, vous le constaterez avec parted ou fdisk :

Erreur: Impossible d'ouvrir /dev/sdb - étiquette de disque non reconnue.

Cependant, si vous vous reportez à la sortie parted ou fdisk du début, vous constatez que nos disques ont les mêmes partitions. Chaque disque a une partition dédié au raid 6 de 1979GB.

3      21,0GB  2000GB  1979GB  ext4                 primary  raid

Nous allons donc simplement cloner la table des partitions d’un disque, le sda par exemple, vers le sdb.

# si les partitions sont gpt
sgdisk -R=/dev/sdb /dev/sda


# si la table des partitions est MBR
sfdisk -d /dev/sda | sfdisk --force /dev/sdb

Nous pouvons vérifier que notre disque est bien partitionné en ré-affichant la table des partitions. Il nous reste encore à insérer le disque dans le RAID pour commencer la reconstruction de ce dernier :

# on ajoute donc en premier la partition sdb3 au md3 (le raid 6)
mdadm --manage /dev/md3 --add /dev/sdb3

# puis on fait la même chose avec sdb2 et md2
mdadm --manage /dev/md2 --add /dev/sdb2

Et voilà, il ne nous reste plus qu’à regarder la reconstruction progresser !

# on constate ensuite que le md3 est en reconstruction et que le md2 attend son tour ;)
oot@st1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md3 : active raid6 sdb3[4] sdc3[2] sdd3[3] sda3[0]
      3865011200 blocks level 6, 512k chunk, algorithm 2 [4/3] [U_UU]
      [>....................]  recovery =  4.9% (96507008/1932505600) finish=281.9min speed=108540K/sec

md2 : active raid1 sdb2[4] sdc2[2] sdd2[3] sda2[0]
      20478912 blocks [4/3] [U_UU]
          resync=DELAYED

Ça peut prendre plus ou moins de temps selon la taille de vos disques et le niveau de RAID, soyez patient !

Alors, avez-vous réussi à sauvez les meubles ?

Commentaires

Rejoignez la discussion !

Vous pouvez utiliser Markdown pour les liens [ancre de lien](url), la mise en *italique* et en **gras**. Enfin pour le code, vous pouvez utiliser la syntaxe `inline` et la syntaxe bloc

```
ceci est un bloc
de code
```