RAID (mdadm): ¿qué sucede si las unidades no coinciden en tamaño?

15

Pregunta 1 - Antes de responder con "solo toma el disco más pequeño", escúchame rápido. Mis 3TB WD Reds tienen un tamaño de 3001 GB. Digamos que configuré un espejo a través de mdadm para sdb1 y sdc1 que abarcan el 100% de la unidad. Pero de repente, uno de los discos falla. El reemplazo es de 3 TB, con un peso de 3000 GB. ¿Qué sucede cuando coloco una unidad que es más pequeña que la que existe actualmente en la matriz? Sé que con una nueva matriz que usa 3000 vs 3001, construiría la matriz para ser 3000. Pero como dije, ¿qué pasa con una matriz actual @ 3001 y agrego una unidad más pequeña? ¿Se reestructura durante la reconstrucción para tener un tamaño de 3000 GB?

Pregunta 2: en el caso de que no pueda agregar 3000 GB a la matriz con un 3001 GB existente y simplemente reduzca su tamaño a 3000 ... ¿puedo cambiar el tamaño del 3001 un poco?

Pregunta 3 - O, una mejor idea. ¿Qué sucede si reduzco el tamaño de mi unidad de 3 TB a 2999 GB? De esa manera, si la unidad es corta en 1 MB, 1 byte, 10 KB, no importa, siempre recogerá la unidad "más pequeña" a 2999 GB.

JaSauders
fuente

Respuestas:

28

Encontré esta respuesta por error, pero en caso de que alguien tenga curiosidad, aquí hay una respuesta respaldada por experimentos.

La versión corta

Pregunta adicional: ¿puedo crear una md(4)matriz RAID a partir de dispositivos de bloque de tamaño desigual? Sí, pero la matriz RAID tendrá el tamaño del dispositivo de bloque más pequeño (más algunos gastos generales para su propio mantenimiento). Si los tamaños de los dispositivos no están dentro del 1% entre sí, recibirá una advertencia.

Pregunta 1: ¿puedo agregar a una md(4)matriz RAID existente un dispositivo más pequeño que el miembro actual más pequeño? No, lo siento. mdadmse negará rotundamente a hacer eso para proteger sus datos.

Pregunta 2: ¿puede cambiar el tamaño de una matriz md existente? Sí (¡lea el mdadmmensaje!), Pero puede que no valga la pena el esfuerzo. Tendrá que hacer una copia de seguridad de todo, luego cambiar el tamaño del contenido del dispositivo RAID, luego cambiar el tamaño del dispositivo en sí mismo; todo esto es bastante propenso a errores, errores de cálculo y otras cosas que le costarán sus datos (experiencia dolorosa al hablar) .

No vale la pena el riesgo y el esfuerzo. Si tiene un disco nuevo en blanco, aquí le mostramos cómo cambiar su tamaño y también mantener intactas entre una y dos copias de todos sus datos en todo momento (suponiendo que tenga RAID1 de 2 discos):

  1. Cree una nueva md(4)matriz en él (con un disco faltante).
  2. Recree la estructura del contenido de la matriz (Crypto, LVM, tablas de particiones, cualquier combinación de las mismas, lo que sea que flote en su bote).
  3. Copie los datos del disco existente al nuevo.
  4. Reiniciar, utilizando el nuevo disco.
  5. Limpie la tabla de particiones del disco anterior (o md(4)ponga a cero el superbloque). Si es necesario, cree las particiones necesarias para que coincidan con el esquema en el nuevo disco.
  6. Agregue el disco viejo a la nueva matriz.
  7. Espere a que los miembros de la matriz se sincronicen. Toma algo de café. Vuela a América Latina y elige tus propios granos de café. :) (Si vives en América Latina, vuela a África).

Nota: sí, esta es la misma técnica que 0xC0000022L describe en su respuesta.

Pregunta 3. ¿Qué sucede si la unidad tiene 1G de corto? :) No te preocupes por eso. Lo más probable es que su unidad de reemplazo sea más grande. De hecho, con una estrategia como la anterior, vale la pena obtener unidades más grandes y baratas cada vez que falla (o para una actualización más barata). Puede obtener una actualización progresiva.

Prueba experimental

Configuración experimental

Primero, simulemos algunos dispositivos de bloque. Usaremos /tmp/sdxy /tmp/sdy(cada 100M) y /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

Esto crea tres archivos como tres dispositivos de bloque de bucle invertido: /dev/loop0, /dev/loop1y /dev/loop2, a la cartografía sdx, sdyy sdzrespectivamente. Vamos a ver los tamaños:

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

Como se esperaba, tenemos dos dispositivos de bucle de exactamente 100M (102400 KiB = 100 MiB) y uno de 99M (exactamente 99 × 1024 bloques de 1K).

Hacer una matriz RAID de dispositivos de tamaño idéntico

Aquí va:

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

Comprueba el tamaño:

sudo grep md100 /proc/partitions
   9      100     102272 md100

Esto es precisamente lo que esperamos: una mirada al manual de mdadm nos recuerda que los metadatos de la versión 1.2 ocupan 128K: 128 + 102272 = 102400. Ahora destruyémoslo en preparación para el segundo experimento.

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

Hacer una matriz RAID de dispositivos de tamaño desigual

Esta vez usaremos el dispositivo de bloque pequeño.

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.

Bueno, nos avisaron, pero la matriz estaba hecha. Vamos a ver el tamaño:

sudo grep md100 /proc/partitions
   9      100     101248 md100

Lo que tenemos aquí es 101,248 bloques. 101248 + 128 = 101376 = 99 × 1024. El espacio utilizable es el del dispositivo más pequeño (más los metadatos RAID de 128K). Bajemos todo de nuevo para nuestro último experimento:

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

Y finalmente: Agregar un dispositivo más pequeño a una matriz en ejecución

Primero, hagamos una matriz RAID1 con solo uno de los discos de 100M. La matriz se degradará, pero realmente no nos importa. Solo queremos una matriz iniciada . Las missingpalabras clave son un marcador de posición que dice "Todavía no tengo un dispositivo para usted, inicie la matriz ahora y agregaré uno más tarde".

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

Nuevamente, verifiquemos el tamaño:

sudo grep md100 /proc/partitions
   9      100     102272 md100

Efectivamente, tiene 128K menos de 102400 bloques. Agregar el disco más pequeño:

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

¡Auge! No nos dejará, y el error es muy claro.

Alexios
fuente
Synology Hybrid RAID (SHR) resuelve este problema.
Denis Denisov
1

Hay varias formas de configurar mdXdispositivos. El método sería usar gdisk(o sgdisksi prefiere la versión solo de línea de comandos) para particionar esto como GPT. Si desea iniciar desde la matriz, cree una "Partición de inicio de BIOS", escriba el código ef02. Esto solo es necesario si desea arrancar esta matriz, de lo contrario no necesita preocuparse. Luego, cree una partición del mismo tamaño o menor que el disco más pequeño que se agregará a la matriz. Por último, pero no menos importante, copie los datos GPT en el otro disco (menú experto en gdisk, usando xy luego uy especifique el dispositivo de destino). Este es un proceso destructivo.

Debería ser posible, si el sistema de archivos lo permite, cambiar el tamaño de una partición existente a algo más pequeño y luego usar el mismo método para copiar los datos GPT. Sin embargo, esto te lleva a un poco de confusión. Porque ahora tienes dos discos, pero aún no tienes ningún mdXdispositivo. Uno de ellos tiene que estar preparado como mdXpartición (lo que implicaba anteriormente) o en forma de disco) y luego los datos se deben mover del disco existente a eso.

Entonces:

  1. disco grande ( /dev/sda) contiene datos, los datos son más pequeños que 3001 GB, las particiones no son
  2. /dev/sdbse agrega un disco más pequeño al sistema
  3. particionas /dev/sdbcongdisk
  4. crea una matriz de cada partición respectiva ( mdadm -C /dev/md2 -l 1 -n 1 /dev/sdb2)
  5. crea sistemas de archivos en las nuevas matrices
  6. copia todos los datos, asegurándose de que su sistema esté preparado para ejecutarse en un disco GPT y haciendo que GRUB2 comprenda las implicaciones (ver más abajo)
  7. copia los datos de partición GPT de /dev/sdba/dev/sda
  8. agrega las particiones "en bruto" de /dev/sdalas matrices existentes
  9. esperas para /proc/mdstatmostrarte que la sincronización ha terminado

Si siguió todos los pasos, ahora debería poder iniciar en el nuevo sistema desde las matrices mdX. Sin embargo, tenga a mano un CD de rescate o una opción de arranque PXE, por si acaso.


GRUB2 no podrá reconocer la configuración de forma manual. Entonces necesitas algo de "magia". Aquí hay una frase:

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

O seamos más detallados:

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

Esto crea (o sobrescribe) el valor predeterminado /boot/grub/devicemapcon uno que le dice a GRUB2 dónde encontrar cada disco respectivo. El resultado sería algo así como esta lista:

(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 utiliza GRUB heredado, también debe crear la "Partición de arranque del BIOS" con metadatos versión 0.9, mdadm -e 0 ...y el proceso será diferente. Sin embargo, no he hecho eso.

0xC0000022L
fuente
1
Gracias por su respuesta. Esta matriz es en realidad solo para almacenamiento sin procesar en mi servidor, por lo que no manejará el arranque ni nada de eso. Solo estaba preocupado por mezclar y combinar discos duros de diferentes tamaños más adelante en el juego. Quiero decir, ¿qué pasaría si tengo sdb1 @ 3001 GB y sdc1 @ 3001 GB, pero sdc1 muere y el reemplazo es de 3000 GB? ¿Sdb1 reduce a 3000? ¿La matriz @ / dev / md0 se reduce a 3000 GB? Cuanto más lo pienso, más tiene sentido dejar espacio al final, como en el ejemplo 2999 anterior, de esa manera debería eliminar ese dolor de cabeza. ¿A menos que me falte algo?
JaSauders 01 de
1
En realidad, suponiendo que el nivel RAID 1 aquí, mdadmse negaría a construir la matriz en primer lugar si es incompatible. En RAID 5 necesitaría más discos eventualmente y en RAID 0 no le importaría, por eso asumí RAID 1. Entonces sí, tiene sentido dejar espacio.
0xC0000022L
No pretendo vencer al caballo, pero estoy un poco inseguro sobre la declaración "incompatible" que hiciste. ¿Qué sería incompatible? ¿Hacía referencia a las diferencias de tamaño en términos de 3000 GB frente a 3001 GB en mi ejemplo? De cualquier manera, acabo de ejecutar mi matriz con cada partición de 2999 GB, a pesar de que cada disco tenía 3001 GB. Esto debería eliminar los dolores de cabeza que surjan en el caso de que no pueda obtener unidades de reemplazo idénticas. ¡Aprecio tu perspicacia!
JaSauders 01 de
@JaSauders: Creo que un GiB más o menos ya sería incompatible. Pero, francamente, no sé dónde está el límite. Sin embargo, sé que se tolerarán pequeñas variaciones de tamaño. Para todo lo demás, debe migrar de una manera similar a lo que describí.
0xC0000022L
@ 0xC0000022L: mdadmtolera un 1% arbitrario de diferencia de tamaño en los miembros de la matriz.
Alexios