linux

Como migrar o mdadm RAID10 com 4 discos para RAID5

Eu tenho um software RAID10 baseado no mdadm do Linux sob Debian Buster.Originalmente,descobri que o RAID10 tinha o melhor desempenho.Mas preciso de mais espaço e aceito trocar algum desempenho de escrita por +50% de espaço.

# cat /proc/mdstat
Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4]
md1 : active raid10 sdd1[5] sda1[4] sdb1[1] sdc1[2]
      3899738112 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU]
      bitmap: 3/30 pages [12KB], 65536KB chunk

unused devices: <none>

Este armazenamento é servido via NFS e,idealmente,o RAID poderia ser transformado sem tempos de paragem.Sim,tenho backups e uma falha não seria crítica,mas porque não migrar sem interrupção se funcionar.

Encontrei um artigo de 2012 descrevendo o processo. Os comandos se mostraram bastante corretos. Naquela época, o autor teve problemas que o utilitário mdadm (ou provavelmente o driver do kernel) imediatamente travava o sistema com o primeiro comando. Este problema parece ter sido corrigido desde então.

https://www.tummy.com/blogs/2012/03/29/changing-a-raid-10-into-a-raid-5/

Não há nenhum caminho directo de RAID10→RAID5 em mdadm.Em vez disso,é preciso primeiro degradá-lo RAID0:

# mdadm --grow /dev/md1 --level=0 --raid-devices=2
mdadm: /dev/md1: could not set level to raid0

Isso foi instantaneamente eficaz e fez com que 2 dispositivos falhassem e fossem removidos do array. Infelizmente, o nível de RAID não foi definido como RAID0. dmesg mostrou:

md/raid0:md1: All mirrors must be already degraded!
md: md1: raid0 would not accept array

Descobri que o problema era que o sysfs relatou que o array não estava sendo degradado, embora na verdade estivesse e mdadm e cat /proc/mdstat mostrassem corretamente:

# cat /sys/block/md1/md/degraded
0

Não encontrei outra forma de corrigir isto como parar o servidor NFS,desmontar o sistema de ficheiros,fechar o dispositivo LUKS,parar a matriz RAID,remontar a matriz RAID e reiniciar todos os serviços.Posteriormente,foi correctamente reportado como degradado e poderia ser transformado em RAID0.

Depois poderia voltar a cultivá-lo para 4 dispositivos com RAID5:

# mdadm --grow /dev/md1 --level=5 --raid-devices=5 --add /dev/sdb1 /dev/sdd1

Ao contrário de sempre cat /proc/mdstat não mostrou uma “reconstrução” em andamento, mas uma “reforma”. Isso demorou um pouco (cerca de 10 horas) e o sistema respondeu muito mais lentamente do que durante as reconstruções do RAID10. Deixei-o sozinho para o tempo de reconstrução.

Desde que o RAID5 foi reformulado,o RAID5 está limpo e a velocidade é boa.Provavelmente cometi erros ao medir mas a velocidade de leitura é agora mais rápida do que a que tinha registado anteriormente e a velocidade de escrita também é aceitável para mim.

# cat /proc/mdstat
Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] 
md1 : active raid5 sdd1[5] sdb1[3] sda1[4] sdc1[7]
      5849607168 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]

unused devices: <none>

(disclaimer: Toda a história foi escrita quando a migração já estava concluída. Tentei cuidadosamente descrever os comandos reais e as mensagens de erro, mas pode haver pequenos erros. O processo geral funcionou como descrito.)




Não (ainda) testado (não confie em dados importantes nas etapas abaixo), mas aqui uma ideia para qualquer cenário em que o espaço utilizável seja aumentado e mdadm --grow diz "layout RAID10 muito complexo para operação Grow":

  1. Parar a md
  2. Cópia de segurança dos primeiros MiB de cada partição do md (assumindo que os superblocos RAID estão próximos do início de cada partição)
  3. Limpar os super-blocos
  4. Crie um RAID5 (ou outro RAID) com --assume-clean usando as partições
  5. Crie snapshots de cada partição do md, por exemplo siga https://gist.github.com/jowagner/b36024636140ddf453c12eaf6e590b5d
  6. Restaurar o backup das divisórias do passo 2 em instantâneos das divisórias
  7. Montar o RAID10 a partir dos instantâneos
  8. dd todos os dados do RAID10 para o RAID5. Usar o mínimo múltiplo comum dos 2 tamanhos de distribuição provavelmente é melhor para o desempenho, mas qualquer tamanho de bloco deve servir. As primeiras leituras não serão corrompidas pelas gravações porque vêm de dados copy-on-write gravados na etapa 5. As leituras restantes não serão corrompidas, pois estão à frente com uma distância segura das gravações em cada partição (daí o limitação desta ideia para cenários onde o espaço útil é aumentado).
  9. Parar o RAID10
  10. Descartar os instantâneos

Isto pressupõe que um instantâneo apenas redirecciona as imagens para um dispositivo COW e que as gravações para o dispositivo de origem não activam uma cópia dos dados antigos a serem armazenados no dispositivo COW (caso contrário,a solução não seria prática,pois é necessário muito espaço extra).

Além disso,se os super blocos do antigo RAID estiverem perto do fim de cada partição,estes dados também precisam de ser copiados antes da etapa 3.Calcular uma posição adequada a procurar e a quantidade de dados.Usaria algumas linhas de Python,mas provavelmente existe uma ferramenta de linha de comando que o pode fazer.