web-dev-qa-db-fra.com

RAID (mdadm) - Que se passe-t-il si les disques ne sont pas de la même taille?

Question 1 - Avant de répondre avec "ça prend juste le plus petit disque", écoutez-moi vite. Mes 3TB WD Reds ont une taille de 3001 Go. Disons que j'ai configuré un miroir via mdadm pour sdb1 et sdc1 qui couvrent 100% du lecteur. Mais tout à coup, l'un des lecteurs échoue. Le remplacement est un 3To, pesant 3000 Go. Que se passe-t-il lorsque je mets dans un lecteur plus petit que celui qui existe actuellement sur le tableau? Je sais qu'avec un nouveau tableau utilisant 3000 vs 3001, le tableau serait de 3000. Mais comme je l'ai dit, qu'en est-il d'un tableau actuel @ 3001 et d'ajouter un disque plus petit? Est-ce qu'il se re-structure pendant la reconstruction pour atteindre une taille de 3 000 Go?

Question 2 - Si je ne peux pas ajouter 3 000 Go à la baie avec un fichier existant de 3001 Go et simplement réduire la taille à 3 000 ... puis-je redimensionner un peu le 3001?

Question 3 - Ou, une meilleure idée. Et si je réduisais la taille de mon lecteur de 3 To à 2999 Go. Ainsi, que le disque soit court de 1 Mo, 1 octet ou 10 Ko, peu importe, le lecteur "plus petit" sera toujours pris à 2999 Go.

15
JaSauders

Je suis tombé sur cette réponse par erreur, mais au cas où quelqu'un serait curieux, voici une réponse appuyée par des expériences.

La version courte

Question boni: puis-je créer une grappe md(4) de périphériques de bloc de taille inégale? Oui, mais la grappe RAID aura la taille du plus petit bloquer le périphérique (plus quelques frais généraux pour son propre entretien). Si la taille des appareils n'est pas inférieure à 1%, vous recevez un avertissement.

Question 1: puis-je ajouter à un md(4) RAID existant un périphérique plus petit que le plus petit membre actuel? Non, désolé. mdadmrefusera carrément de le faire pour protéger vos données.

Question 2: pouvez-vous redimensionner un tableau md existant? Oui (lisez le mdadmmanpge!), Mais cela ne vaut peut-être pas la peine. Vous devrez tout sauvegarder, puis redimensionner le contenu du périphérique RAID, puis redimensionner le périphérique lui-même - tout cela est sujet à des erreurs, à des erreurs de calcul et à d'autres coûts qui vous coûteront vos données (expérience douloureuse). .

Cela ne vaut pas le risque et l'effort. Si vous avez un nouveau disque vierge, voici comment le redimensionner et conserver en tout temps entre une et deux copies de toutes vos données (en supposant que vous disposiez d'un RAID1 à 2 disques):

  1. Créez un nouveau tableau md(4) (avec un disque manquant).
  2. Recréez la structure du contenu de la matrice (Crypto, LVM, tables de partitions, toute combinaison de celles-ci, quel que soit le comportement de votre bateau).
  3. Copiez les données du disque existant vers le nouveau.
  4. Redémarrez en utilisant le nouveau disque.
  5. Effacez la table de partition de l'ancien disque (ou remettez à zéro le superbloc md(4)). Si nécessaire, créez les partitions requises pour correspondre au schéma sur le nouveau disque.
  6. Ajoutez l'ancien disque à la nouvelle matrice.
  7. Attendez que les membres du groupe se synchronisent. Prends un café. Envolez-vous vers l’Amérique latine et cueillez vos propres grains de café. :) (Si vous habitez en en Amérique latine, envolez-vous vers l’Afrique).

Remarque: oui, il s'agit de la même technique que 0xC0000022L décrite dans sa réponse.

Question 3. Et si le lecteur est 1G court? :) Ne t'inquiète pas pour ça. Les chances sont que votre disque de remplacement sera plus grand. En fait, avec une stratégie comme celle-ci , il est payant d’obtenir des disques plus volumineux moins chers, chaque fois qu’on échoue (ou pour une mise à niveau moins chère). Vous pouvez obtenir une mise à niveau progressive.

Preuve expérimentale

Montage expérimental

Commençons par simuler certains périphériques en mode bloc. Nous utiliserons /tmp/sdx et /tmp/sdy (chaque 100M), et /tmp/sdz (99M).

cd /tmp
dd if=/dev/zero of=sdx bs=1M count=100
Sudo losetup -f sdx
dd if=/dev/zero of=sdy bs=1M count=100
Sudo losetup -f sdy
dd if=/dev/zero of=sdz bs=1M count=99  # Here's a smaller one!
Sudo losetup -f sdz

Cela configure trois fichiers en tant que trois périphériques de bloc de bouclage: /dev/loop0, /dev/loop1 et /dev/loop2, mappant à sdxname__, sdyet sdzname__. Vérifions les tailles:

Sudo grep loop[012] /proc/partitions
   7        0     102400 loop0
   7        1     102400 loop1
   7        2     101376 loop2

Comme prévu, nous avons deux dispositifs de boucle d’exactement 100M (102400 KiB = 100 MiB) et un de 99M (exactement 99 × 1024 blocs 1K).

Création d'une matrice RAID à partir de périphériques de taille identique

Voici:

Sudo mdadm  --create -e 1.2 -n 2 -l 1 /dev/md100 /dev/loop0 /dev/loop1
mdadm: array /dev/md100 started.

Vérifiez la taille:

Sudo grep md100 /proc/partitions
   9      100     102272 md100

C’est précisément ce à quoi nous nous attendons: un regard sur le manuel de mdadm nous rappelle que les métadonnées de la version 1.2 occupent 128 K: 128 + 102272 = 102400. Détruisons-le maintenant en prévision de la deuxième expérience.

Sudo mdadm --stop /dev/md100
Sudo mdadm --misc --zero-superblock /dev/loop0
Sudo mdadm --misc --zero-superblock /dev/loop1

Création d'une matrice RAID à partir de périphériques de taille inégale

Cette fois, nous allons utiliser le périphérique de petit bloc.

Sudo mdadm  --create -e 1.2 -n 2 -l 1 /dev/md100 /dev/loop0 /dev/loop2
mdadm: largest drive (/dev/loop0) exceeds size (101248K) by more than 1%
Continue creating array? y
mdadm: array /dev/md100 started.

Eh bien, nous avons été prévenus, mais le tableau a été fait. Vérifions la taille:

Sudo grep md100 /proc/partitions
   9      100     101248 md100

Nous avons ici 101,248 blocs. 101248 + 128 = 101376 = 99 × 1024. L'espace utilisable est celui du plus petit périphérique (plus les métadonnées RAID à 128K). Reprenons le tout pour notre dernière expérience:

Sudo mdadm --stop /dev/md100
Sudo mdadm --misc --zero-superblock /dev/loop0
Sudo mdadm --misc --zero-superblock /dev/loop2

Et enfin: Ajouter un plus petit périphérique à un tableau en cours d'exécution

Commençons par créer une matrice RAID1 avec un seul des 100 millions de disques. Le tableau sera dégradé, mais nous ne nous en soucions pas vraiment. Nous voulons juste un commencé tableau. Le mot clé missingest un espace réservé indiquant "Je ne dispose pas encore de périphérique pour vous, démarrez le tableau maintenant et je vous en ajouterai un".

Sudo mdadm  --create -e 1.2 -n 2 -l 1 /dev/md100 /dev/loop0 missing

Encore une fois, vérifions la taille:

Sudo grep md100 /proc/partitions
   9      100     102272 md100

Effectivement, il lui manque 128 Ko de 102400 blocs. Ajout du disque plus petit:

Sudo mdadm  --add /dev/md100 /dev/loop2
mdadm: /dev/loop2 not large enough to join array

Boom! Cela ne nous laissera pas et l'erreur est très claire.

28
Alexios

Il existe plusieurs façons de configurer les périphériques mdXname__. La méthode consisterait à utiliser gdisk(ou sgdisksi vous préférez la version en ligne de commande uniquement) pour le partitionner en tant que GPT. Si vous souhaitez démarrer à partir de la matrice, créez une "partition de démarrage BIOS", tapez le code ef02. Cela n'est nécessaire que si vous voulez démarrer à partir de ce tableau, sinon inutile de vous en soucier. Créez ensuite une partition de même taille ou plus petite que le plus petit disque à ajouter à la matrice. Enfin, copiez les données GPT sur l’autre disque (menu expert dans gdiskname__, en utilisant xname__, puis uet indiquez le périphérique cible). C'est un processus destructeur.

Il devrait être possible - si le système de fichiers le permet - de redimensionner une partition existante en un fichier plus petit, puis d'utiliser la même méthode pour copier les données GPT. Cependant, cela vous plonge dans un brouhaha. Parce que maintenant vous avez deux disques, mais toujours pas de mdXname__. L’un d’eux doit être préparé sous la forme mdXname__, en partition (ce que j’implique ci-dessus) ou en disque), puis les données doivent être déplacées du disque existant vers celui-ci.

Alors:

  1. le gros disque (/dev/sda) contient des données, les données sont inférieures à 3001 Go, les partitions ne sont pas
  2. le plus petit disque /dev/sdb est ajouté au système
  3. vous partitionnez /dev/sdb avec gdiskname__
  4. vous créez un tableau à partir de chaque partition respective (mdadm -C /dev/md2 -l 1 -n 1 /dev/sdb2)
  5. vous créez des systèmes de fichiers sur les nouveaux tableaux
  6. vous copiez toutes les données, en vous assurant que votre système sera prêt à utiliser un disque GPT et en permettant à GRUB2 de comprendre les implications (voir ci-dessous)
  7. vous copiez les données de partitionnement GPT de /dev/sdb à /dev/sda
  8. vous ajoutez les partitions "brutes" de /dev/sda dans les tableaux existants
  9. vous attendez /proc/mdstat pour vous montrer que la synchronisation est terminée

Si vous avez suivi toutes les étapes, vous devriez maintenant pouvoir démarrer sur le nouveau système à partir des baies mdX. Cependant, conservez un CD de secours ou une option de démarrage PXE à portée de main, juste au cas où.


GRUB2 ne sera pas capable de reconnaître la configuration de la main. Donc, vous avez besoin de "magie". Voici un one-liner:

for i in /dev/disk/by-id/md-uuid-*; do DEV=$(readlink $i); echo "(${DEV##*/}) $i"; done|sort|tee /boot/grub/devicemap

Ou soyons plus verbeux:

for i in /dev/disk/by-id/md-uuid-*
do
  DEV=$(readlink $i)
  echo "(${DEV##*/}) $i"
done|sort|Sudo tee /boot/grub/devicemap

Cela crée (ou écrase) le /boot/grub/devicemap par défaut avec un qui indique à GRUB2 où trouver chaque disque respectif. Le résultat serait quelque chose comme cette liste:

(md0) /dev/disk/by-id/md-uuid-...
(md2) /dev/disk/by-id/md-uuid-...
(md3) /dev/disk/by-id/md-uuid-...
(md4) /dev/disk/by-id/md-uuid-...

Si vous utilisez l'ancienne version de GRUB, vous devez également créer la "partition de démarrage du BIOS" avec les métadonnées version 0.9, à l'aide de mdadm -e 0 ... et le processus sera différent. Je n'ai pas fait cela, cependant.

1
0xC0000022L