RAID (mdadm) - O que acontece se as unidades tiverem um tamanho incompatível?

15

Pergunta 1 - Antes de responder com "basta o disco menor", ouça-me rapidamente. Meus 3TB WD Reds têm 3001 GB de tamanho. Digamos que eu configurei um espelho via mdadm para sdb1 e sdc1, que abrangem 100% da unidade. Mas, de repente, uma das unidades falha. A substituição é de 3 TB, pesando 3000 GB. O que acontece quando eu coloco uma unidade menor que a existente no array? Eu sei que com um novo array usando 3000 vs 3001, ele criaria o array para 3000. Mas, como eu disse, o que dizer de um array atual @ 3001 e adiciono uma unidade menor? Ele se reestruturou durante a reconstrução para ter 3000 GB de tamanho?

Pergunta 2 - No caso de eu não conseguir adicionar 3000 GB ao array com 3001 GB existentes e simplesmente reduzir para 3000 ... posso redimensionar um pouco o 3001?

Pergunta 3 - Ou, uma ideia melhor. E se eu reduzir o tamanho da minha unidade de 3 TB para 2999 GB. Dessa forma, independentemente de a unidade ter 1 MB, 1 byte, 10 KB, não importa, ela sempre pegará a unidade "menor" a 2999 GB.

JaSauders
fonte

Respostas:

28

Me deparei com essa resposta por engano, mas caso alguém esteja curioso, aqui está uma resposta apoiada por experimentos.

A versão curta

Pergunta bônus: posso criar uma md(4)matriz RAID a partir de dispositivos de bloco de tamanho desigual? Sim, mas a matriz RAID terá o tamanho do menor dispositivo de bloco (mais algumas despesas gerais para sua própria limpeza). Se o tamanho do dispositivo não estiver a 1% um do outro, você receberá um aviso.

Pergunta 1: posso adicionar a uma md(4)matriz RAID existente um dispositivo menor que o menor membro atual? Não desculpe. mdadmse recusará a fazer isso para proteger seus dados.

Pergunta 2: você pode redimensionar uma matriz md existente? Sim (leia o mdadmmanual!), Mas pode não valer a pena. Você terá que fazer backup de tudo, redimensionar o conteúdo do dispositivo RAID e redimensionar o próprio dispositivo - tudo isso é bastante propenso a erros, erros de cálculo e outras coisas que custarão seus dados (experiência dolorosa ao falar) .

Não vale a pena o risco e o esforço. Se você tiver um novo disco em branco, veja como redimensioná-lo e mantenha sempre uma e duas cópias de todos os seus dados intactos o tempo todo (supondo que você tenha RAID1 de 2 discos):

  1. Crie uma nova md(4)matriz nele (com um disco ausente).
  2. Recrie a estrutura do conteúdo do array (Crypto, LVM, tabelas de partições, qualquer combinação dos mesmos, o que flutua em seu barco).
  3. Copie os dados do disco existente para o novo.
  4. Reinicie, usando o novo disco.
  5. Limpe a tabela de partição do disco antigo (ou zere o md(4)superbloco). Se necessário, crie as partições necessárias para corresponder ao esquema no novo disco.
  6. Adicione o disco antigo à nova matriz.
  7. Aguarde a sincronização dos membros da matriz. Tome um café. Voe para a América Latina e escolha seus próprios grãos de café. :) (Se você mora na América Latina, voe para a África).

Nota: sim, esta é a mesma técnica 0xC0000022L descrita em sua resposta.

Pergunta 3. E se a unidade tiver 1G de comprimento? :) Não se preocupe. Provavelmente, sua unidade de substituição será maior. De fato, com uma estratégia como a acima, vale a pena obter unidades maiores e mais baratas sempre que houver uma falha (ou uma atualização mais barata). Você pode obter uma atualização progressiva.

Prova Experimental

Configuração Experimental

Primeiro, vamos fingir alguns dispositivos de bloco. Usaremos /tmp/sdxe /tmp/sdy(cada 100 milhões) e /tmp/sdz(99 milhões).

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

Isso configura três arquivos como três dispositivos de bloco loopback: /dev/loop0, /dev/loop1e /dev/loop2, mapeamento para sdx, sdye sdzrespectivamente. Vamos verificar os tamanhos:

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

Como esperado, temos dois dispositivos de loop de exatamente 100M (102400 KiB = 100 MiB) e um de 99M (exatamente 99 × 1024 blocos de 1K).

Criando uma matriz RAID com dispositivos de tamanho idêntico

Aqui vai:

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

Verifique o tamanho:

sudo grep md100 /proc/partitions
   9      100     102272 md100

É exatamente o que esperamos: uma olhada no manual mdadm nos lembra que os metadados da versão 1.2 ocupam 128K: 128 + 102272 = 102400. Agora vamos destruí-lo em preparação para o segundo experimento.

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

Criando uma matriz RAID com dispositivos de tamanho desigual

Desta vez, usaremos o pequeno dispositivo de bloco.

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.

Bem, fomos avisados, mas a matriz foi feita. Vamos verificar o tamanho:

sudo grep md100 /proc/partitions
   9      100     101248 md100

O que chegamos aqui são 101.248 blocos. 101248 + 128 = 101376 = 99 × 1024. O espaço utilizável é o do menor dispositivo (mais os metadados de 128K RAID). Vamos resumir tudo novamente para o nosso último experimento:

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

E finalmente: adicionando um dispositivo menor a uma matriz em execução

Primeiro, vamos criar uma matriz RAID1 com apenas um dos discos de 100M. A matriz será degradada, mas realmente não nos importamos. Nós apenas queremos uma matriz iniciada . As missingpalavras-chave são um espaço reservado que diz 'Ainda não tenho um dispositivo para você, inicie a matriz agora e adicionarei mais tarde'.

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

Mais uma vez, vamos verificar o tamanho:

sudo grep md100 /proc/partitions
   9      100     102272 md100

Com certeza, é 128K a menos de 102400 blocos. Adicionando o disco menor:

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

Estrondo! Não vai nos deixar, e o erro é muito claro.

Alexios
fonte
O Synology Hybrid RAID (SHR) resolve esse problema.
Denis Denisov
1

Existem várias maneiras de configurar mdXdispositivos. O método seria usar gdisk(ou sgdiskse você preferir a versão apenas da linha de comando) para particionar isso como GPT. Se você deseja inicializar a partir da matriz, crie uma "Partição de inicialização do BIOS", digite o código ef02. Isso é necessário apenas se você deseja inicializar essa matriz, caso contrário não há necessidade de se preocupar. Em seguida, crie uma partição do mesmo tamanho ou menor que o menor disco a ser adicionado à matriz. Por último, mas não menos importante, copie os dados da GPT para o outro disco (menu especialista em gdisk, usando xe, em seguida, ue especifique o dispositivo de destino). Este é um processo destrutivo.

Deve ser possível - se o sistema de arquivos permitir - redimensionar uma partição existente para algo menor e usar o mesmo método para copiar os dados da GPT. No entanto, isso deixa você meio confuso. Porque agora você tem dois discos, mas ainda não possui mdXdispositivo. Um deles deve ser preparado como mdXem partição (como eu impliquei acima) ou em disco) e, em seguida, os dados devem ser movidos do disco existente para esse.

Então:

  1. disco grande ( /dev/sda) contém dados, dados são menores que 3001 GB, partições não são
  2. um disco menor /dev/sdbé adicionado ao sistema
  3. você particiona /dev/sdbcomgdisk
  4. você cria uma matriz de cada respectiva partição ( mdadm -C /dev/md2 -l 1 -n 1 /dev/sdb2)
  5. você cria sistemas de arquivos nas novas matrizes
  6. você copia todos os dados, certificando-se de que seu sistema esteja preparado para executar um disco GPT e fazendo o GRUB2 entender as implicações (veja abaixo)
  7. você copia os dados de particionamento da GPT de /dev/sdbpara/dev/sda
  8. você adiciona as partições "brutas" /dev/sdadas matrizes existentes
  9. você espera para /proc/mdstatmostrar que a sincronização está concluída

Se você seguiu todas as etapas, agora poderá inicializar o novo sistema a partir das matrizes mdX. No entanto, mantenha um CD de resgate ou uma opção de inicialização PXE à mão, apenas por precaução.


O GRUB2 não poderá reconhecer a configuração manualmente. Então você precisa de alguma "mágica". Aqui está uma frase:

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

Ou vamos ser mais detalhados:

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

Isso cria (ou substitui) o padrão /boot/grub/devicemappor um que diz ao GRUB2 onde encontrar cada disco respectivo. O resultado seria algo 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-...

Se você usa o GRUB legado, também precisa criar a "Partição de inicialização do BIOS" com metadados versão 0.9, usando mdadm -e 0 ...e o processo será diferente. Eu não fiz isso, no entanto.

0xC0000022L
fonte
11
Obrigado pela sua resposta. Essa matriz é na verdade apenas para armazenamento bruto no meu servidor, portanto não manipulará a inicialização ou algo assim. Eu só estava preocupado em misturar e combinar discos rígidos de tamanhos diferentes posteriormente no jogo. Quero dizer, o que aconteceria se eu tivesse sdb1 a 3001 GB e sdc1 a 3001 GB, mas o sdc1 morrer e a substituição for 3000 GB? O sdb1 reduz para 3000? A matriz @ / dev / md0 reduz para 3000 GB? Quanto mais eu penso sobre isso, mais faz sentido deixar espaço no final, como no exemplo 2999 acima - dessa forma ele deve remover essa dor de cabeça. A menos que eu esteja perdendo alguma coisa?
JaSauders
11
Na verdade, assumindo o RAID nível 1 aqui, mdadmse recusaria a construir a matriz em primeiro lugar, se for incompatível. No RAID 5, você precisaria de mais discos e, no RAID 0, não se importaria com isso, e é por isso que eu assumi o RAID 1. Então, sim, faz sentido deixar espaço.
0xC0000022L
Não pretendo bater no cavalo, mas estou um pouco inseguro sobre a afirmação "incompatível" que você fez. O que seria incompatível? Você estava referenciando as diferenças de tamanho em termos de 3000 GB vs 3001 GB no meu exemplo? De qualquer maneira, eu apenas executei minha matriz com cada partição com 2999 GB, mesmo que cada disco tivesse 3001 GB. Isso deve apenas remover quaisquer dores de cabeça que surjam na linha no caso de eu não conseguir unidades de substituição idênticas. Aprecie sua visão!
JaSauders
@ JaSauders: Eu acho que um GiB mais ou menos já seria incompatível. Mas, francamente, não sei onde está o limite. Eu sei, no entanto, que pequenas variações de tamanho serão toleradas. Para todo o resto, você precisa migrar de maneira semelhante ao que descrevi.
0xC0000022L
@ 0xC0000022L: mdadmtolera uma diferença arbitrária de 1% do tamanho nos membros da matriz.
Alexios #