RAID (mdadm) - Cosa succede se le unità hanno dimensioni non corrispondenti?


15

Domanda 1 - Prima di rispondere con "richiede solo il disco più piccolo", ascoltami rapidamente. I miei 3 TB WD Reds hanno una dimensione di 3001 GB. Diciamo che ho impostato un mirror tramite mdadm per sdb1 e sdc1 che coprono il 100% del disco. Ma improvvisamente, una delle unità si guasta. Il sostituto è un 3 TB, con un peso di 3000 GB. Cosa succede quando inserisco un'unità più piccola di quella attualmente presente sull'array? So che con un nuovo array che utilizza 3000 vs 3001, si creerebbe un array da 3000. Ma come ho detto, che dire di un array corrente a 3001 e aggiungo un'unità più piccola? Si ricostruisce da solo durante la ricostruzione per avere una dimensione di 3000 GB?

Domanda 2 - Nel caso in cui non riesca ad aggiungere 3000 GB all'array con 3001 GB esistenti e semplicemente ridimensiona a 3000 ... posso ridimensionare un po 'il 3001?

Domanda 3 - Oppure, un'idea migliore. E se ridimensionassi il mio disco da 3 TB a 2999 GB. In questo modo, indipendentemente dal fatto che l'unità sia corta di 1 MB, 1 byte, 10 KB, raccoglierà sempre l'unità "più piccola" a 2999 GB.

Risposte:


28

Ho trovato questa risposta per errore, ma nel caso qualcuno fosse curioso, ecco una risposta supportata da esperimenti.

La versione breve

Domanda bonus: posso creare un md(4)array RAID da dispositivi a blocchi di dimensioni diverse? Sì, ma l'array RAID avrà le dimensioni del dispositivo a blocchi più piccolo (oltre ad alcune spese generali per le proprie pulizie). Se le dimensioni del dispositivo non sono entro l'1% l'una dall'altra, viene visualizzato un avviso.

Domanda 1: posso aggiungere a un md(4)array RAID esistente un dispositivo più piccolo del membro corrente più piccolo? No scusa. mdadmrifiuterà di farlo per proteggere i tuoi dati.

Domanda 2: puoi ridimensionare un array md esistente? Sì (leggi la mdadmmanpge!), Ma potrebbe non valere la pena. Dovrai eseguire il backup di tutto, quindi ridimensionare i contenuti del dispositivo RAID, quindi ridimensionare il dispositivo stesso: tutto ciò è piuttosto soggetto a errori, calcoli errati e altre cose che ti costeranno i tuoi dati (esperienza dolorosa nel parlare) .

Non vale il rischio e lo sforzo. Se si dispone di un nuovo disco vuoto, ecco come ridimensionarlo e mantenere sempre intatte tra una e due copie di tutti i dati (supponendo che si disponga di un RAID1 a 2 dischi):

  1. Crea un nuovo md(4)array su di esso (con un disco mancante).
  2. Ricrea la struttura del contenuto dell'array (Crypto, LVM, tabelle delle partizioni, qualsiasi combinazione degli stessi, qualunque sia il galleggiante della tua barca).
  3. Copia i dati dal disco esistente in quello nuovo.
  4. Riavvia, utilizzando il nuovo disco.
  5. Cancella la tabella delle partizioni del vecchio disco (o azzera il md(4)superblocco). Se necessario, creare le partizioni richieste in modo che corrispondano allo schema sul nuovo disco.
  6. Aggiungi il vecchio disco al nuovo array.
  7. Attendere la sincronizzazione dei membri dell'array. Bevi un caffè. Vola in America Latina e scegli i tuoi chicchi di caffè, del resto. :) (Se vivi in America Latina, vola invece in Africa).

Nota: sì, questa è la stessa tecnica 0xC0000022L descritta nella sua risposta.

Domanda 3. Cosa succede se il disco è corto 1G? :) Non preoccuparti. È probabile che l'unità sostitutiva sarà più grande. In effetti, con una strategia come sopra, paga per ottenere unità più grandi più economiche ogni volta che si guasta (o per un aggiornamento più economico). È possibile ottenere un aggiornamento progressivo.

Prova sperimentale

Setup sperimentale

Innanzitutto, falsifichiamo alcuni dispositivi a blocchi. Useremo /tmp/sdxe /tmp/sdy(ogni 100 /tmp/sdzM) e (99 M).

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

Tale articolo stabilisce tre file come tre dispositivi a blocchi di loopback: /dev/loop0, /dev/loop1e /dev/loop2, per la mappatura sdx, sdye sdzrispettivamente. Controlliamo le dimensioni:

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

Come previsto, abbiamo due dispositivi loop di esattamente 100M (102400 KiB = 100 MiB) e uno di 99M (esattamente 99 × 1024 blocchi da 1K).

Creazione di un array RAID da dispositivi di dimensioni identiche

Ecco qui:

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

Controlla le dimensioni:

sudo grep md100 /proc/partitions
   9      100     102272 md100

Questo è esattamente ciò che ci aspettiamo: uno sguardo al manuale di mdadm ci ricorda che i metadati della versione 1.2 occupano 128 KB: 128 + 102272 = 102400. Ora distruggiamolo in preparazione per il secondo esperimento.

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

Creazione di un array RAID da dispositivi di dimensioni diverse

Questa volta useremo il dispositivo a blocchi piccoli.

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.

Bene, siamo stati avvertiti, ma l'array è stato realizzato. Controlliamo le dimensioni:

sudo grep md100 /proc/partitions
   9      100     101248 md100

Quello che arriviamo qui è 101.248 blocchi. 101248 + 128 = 101376 = 99 × 1024. Lo spazio utilizzabile è quello del dispositivo più piccolo (più i metadati RAID 128K). Abbassiamo di nuovo tutto per il nostro ultimo esperimento:

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

E infine: aggiungere un dispositivo più piccolo a un array in esecuzione

Innanzitutto, creiamo un array RAID1 con solo uno dei dischi da 100M. L'array verrà degradato, ma non ci interessa davvero. Vogliamo solo un array avviato . Le missingparole chiave sono un segnaposto che dice "Non ho ancora un dispositivo per te, avvia subito l'array e ne aggiungerò uno più tardi".

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

Ancora una volta, controlliamo le dimensioni:

sudo grep md100 /proc/partitions
   9      100     102272 md100

Abbastanza sicuro, è 128K corto di 102400 blocchi. Aggiunta del disco più piccolo:

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

Boom! Non ci permetterà, e l'errore è molto chiaro.


Synology Hybrid RAID (SHR) risolve questo problema.
Denis Denisov,

1

Esistono diversi modi per configurare i mdXdispositivi. Il metodo sarebbe quello di usare gdisk(o sgdiskse preferisci la versione solo da riga di comando) per partizionarlo come GPT. Se si desidera eseguire l'avvio dall'array, creare una "Partizione di avvio BIOS", digitare il codice ef02. Questo è necessario solo se si desidera avviare questo array, altrimenti non è necessario preoccuparsene. Quindi, creare una partizione delle stesse dimensioni o più piccola del disco più piccolo da aggiungere all'array. Ultimo ma non meno importante, copia i dati GPT sull'altro disco (menu esperto in gdisk, usando x, e quindi ue specifica il dispositivo di destinazione). Questo è un processo distruttivo.

Dovrebbe essere possibile - se il file system lo consente - ridimensionare una partizione esistente in qualcosa di più piccolo e quindi utilizzare lo stesso metodo per copiare i dati GPT. Tuttavia, questo ti mette in un po 'di kerfuffle. Perché ora hai due dischi, ma ancora nessun mdXdispositivo. Uno di questi deve essere preparato come mdX, partizionalmente (come ho inteso sopra) o come disco) e quindi i dati devono essere spostati dal disco esistente a quello.

Così:

  1. big disk ( /dev/sda) contiene dati, i dati sono inferiori a 3001 GB, le partizioni no
  2. il disco più piccolo /dev/sdbviene aggiunto al sistema
  3. ti dividi /dev/sdbcongdisk
  4. si crea un array da ciascuna rispettiva partizione ( mdadm -C /dev/md2 -l 1 -n 1 /dev/sdb2)
  5. si creano file system sui nuovi array
  6. copi tutti i dati, assicurandoti che il tuo sistema sarà pronto a funzionare da un disco GPT e far capire a GRUB2 le implicazioni (vedi sotto)
  7. copi i dati di partizionamento GPT da /dev/sdb a/dev/sda
  8. aggiungi le partizioni "raw" da /dev/sda array esistenti
  9. aspetti /proc/mdstatdi mostrarti che la sincronizzazione è stata eseguita

Se hai seguito tutti i passaggi, dovresti ora essere in grado di avviare il nuovo sistema dagli array mdX. Tuttavia, tieni a portata di mano un CD di ripristino o un'opzione di avvio PXE, per ogni evenienza.


GRUB2 non sarà in grado di riconoscere manualmente l'impostazione. Quindi hai bisogno di un po 'di "magia". Ecco 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

O siamo più prolissi:

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

Questo crea (o sovrascrive) il valore predefinito /boot/grub/devicemapcon uno che dice a GRUB2 dove trovare ciascun rispettivo disco. Il risultato sarebbe simile a questo elenco:

(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-...

Se usi GRUB legacy, devi anche creare la "Partizione di avvio BIOS" con metadati versione 0.9, usando mdadm -e 0 ...e il processo sarà diverso. Non l'ho fatto, comunque.


1
Grazie per la tua risposta. Questo array è in realtà solo per l'archiviazione raw sul mio server, quindi non gestirà l'avvio o qualcosa del genere. Ero solo preoccupato di mescolare e abbinare dischi rigidi di dimensioni diverse più avanti nel gioco. Voglio dire, cosa succederebbe se avessi sdb1 @ 3001 GB e sdc1 @ 3001 GB, ma sdc1 muore e la sostituzione è di 3000 GB? Sdb1 ridimensiona a 3000? L'array @ / dev / md0 si riduce a 3000 GB? Più ci penso, più ha senso lasciare spazio alla fine, come nell'esempio 2999 sopra - in questo modo dovrebbe rimuovere quel mal di testa. A meno che non mi manchi qualcosa?
JaSauders,

1
In realtà, supponendo che il livello RAID 1 qui, mdadmrifiuterebbe di costruire l'array in primo luogo se è incompatibile. In RAID 5 alla fine avresti bisogno di più dischi e in RAID 0 non te ne importerebbe, motivo per cui ho assunto RAID 1. Quindi sì, ha senso lasciare spazio.
0xC0000022L

Non intendo battere il cavallo, ma non sono sicuro dell'affermazione "incompatibile" che hai fatto. Cosa sarebbe incompatibile? Nel mio esempio hai fatto riferimento alle differenze di dimensioni in termini di 3000 GB contro 3001 GB? Ad ogni modo, ho appena eseguito il mio array con ogni partizione da 2999 GB, anche se ogni disco era 3001 GB. Questo dovrebbe semplicemente rimuovere tutti i mal di testa che si presentano nel caso in cui non riesco a ottenere unità di sostituzione identiche. Apprezzo la tua visione!
JaSauders,

@JaSauders: penso che un GiB in più o in meno sarebbe già incompatibile. Ma francamente non so dove sia il limite. So, tuttavia, che saranno tollerate lievi variazioni di dimensioni. Per tutto il resto devi migrare in un modo simile a quello che ho delineato.
0xC0000022L

@ 0xC0000022L: mdadmtollera l'1% arbitrario della differenza dimensionale nei membri dell'array.
Alexios,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.