
eu tinha criadocinco partições HDD de 1 TB( /dev/sda1
, /dev/sdb1
, /dev/sdc1
, /dev/sde1
, e /dev/sdf1
) em umRAID 6array chamado /dev/md0
usando mdadm
no Ubuntu 14.04 LTS Trusty Tahr.
O comando sudo mdadm --detail /dev/md0
usado para mostrar todas as unidades emsincronização ativa.
Então, para teste, simulei um longo bloqueio de E/S /dev/sdb
executando estes comandos enquanto /dev/sdb1
ainda estava ativo no array:
hdparm --user-master u --security-set-pass deltik /dev/sdb
hdparm --user-master u --security-erase-enhanced deltik /dev/sdb
AVISO
NÃO TENTE ISSO COM DADOS QUE VOCÊ SE IMPORTA!
Acabei corrompendo 455681 inodes como resultado desta operação ATA. Admito minha negligência.
Esperava-se que o comando ATA para apagamento seguro fosse executado por 188 minutos, bloqueando todos os outros comandos por pelo menos esse tempo.
Eu esperava md
descartar a unidade que não respondia como um controlador RAID adequado, mas, para minha surpresa, /dev/md0
também ficou bloqueado.
mdadm --detail /dev/md0
consulta o dispositivo bloqueado, então ele congela e não gera saída.
Aqui está o layout /proc/mdstat
enquanto não posso usar mdadm --detail /dev/md0
:
root@node51 [~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid1] [raid10]
md0 : active raid6 sdf1[5] sda1[0] sdb1[4] sdc1[2] sde1[1]
2929887744 blocks super 1.2 level 6, 512k chunk, algorithm 2 [5/5] [UUUUU]
unused devices: <none>
Tentei mdadm /dev/md0 -f /dev/sdb1
falhar à força /dev/sdb1
, mas também foi bloqueado:
root@node51 [~]# ps aux | awk '{if($8~"D"||$8=="STAT"){print $0}}'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 3334 1.2 0.0 42564 1800 ? D 03:21 3:37 parted -l
root 4957 0.0 0.0 13272 900 ? D 06:19 0:00 mdadm /dev/md0 -f /dev/sdb1
root 5706 0.0 0.0 13388 1028 ? D 06:19 0:00 mdadm --detail /dev/md0
root 7541 0.5 0.0 0 0 ? D Jul19 6:12 [kworker/u16:2]
root 22420 0.0 0.0 11480 808 ? D 07:48 0:00 lsblk
root 22796 0.0 0.0 4424 360 pts/13 D+ 05:51 0:00 hdparm --user-master u --security-erase-enhanced deltik /dev/sdb
root 23312 0.0 0.0 4292 360 ? D 05:51 0:00 hdparm -I /dev/sdb
root 23594 0.1 0.0 0 0 ? D 06:11 0:07 [kworker/u16:1]
root 25205 0.0 0.0 17980 556 ? D 05:52 0:00 ls --color=auto
root 26008 0.0 0.0 13388 1032 pts/23 D+ 06:32 0:00 mdadm --detail /dev/md0
dtkms 29271 0.0 0.2 58336 10412 ? DN 05:55 0:00 python /usr/share/backintime/common/backintime.py --backup-job
root 32303 0.0 0.0 0 0 ? D 06:16 0:00 [kworker/u16:0]
ATUALIZAÇÃO (21 de julho de 2015):Depois de esperar 188 minutos completos para que o bloco de E/S fosse limpo, a surpresa se transformou em horror quando vi que md
tratava o bloco completamente apagado /dev/sdb
como se estivesse completamente intacto.
Achei que md
pelo menos teria visto que a paridade estava incompatível e depois teria caído /dev/sdb1
.
Em pânico, corri mdadm /dev/md0 -f /dev/sdb1
novamente e, como o bloco de E/S foi suspenso, o comando foi concluído rapidamente.
A corrupção do sistema de arquivos já estava acontecendo à medida que surgiam erros de entrada/saída. Ainda em pânico, desmontei preguiçosamente a partição de dados na matriz RAID e reboot -nf
percebi que não poderia piorar.
Depois de roer as unhas e2fsck
na partição, 455.681 inodes chegaram ao arquivo lost+found
.
Desde então, remontei o array, e o array em si parece bom agora:
root@node51 [~]# mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Mon Feb 16 14:34:26 2015
Raid Level : raid6
Array Size : 2929887744 (2794.16 GiB 3000.21 GB)
Used Dev Size : 976629248 (931.39 GiB 1000.07 GB)
Raid Devices : 5
Total Devices : 5
Persistence : Superblock is persistent
Update Time : Tue Jul 21 00:00:30 2015
State : active
Active Devices : 5
Working Devices : 5
Failed Devices : 0
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 512K
Name : box51:0
UUID : 6b8a654d:59deede9:c66bd472:0ceffc61
Events : 643541
Number Major Minor RaidDevice State
0 8 1 0 active sync /dev/sda1
1 8 97 1 active sync /dev/sdg1
2 8 33 2 active sync /dev/sdc1
6 8 17 3 active sync /dev/sdb1
5 8 113 4 active sync /dev/sdh1
Ainda é um grande choque para mim md
não ter duas linhas de proteção que eu esperava:
- Falha em um dispositivo quando ele trava
- Falha em um dispositivo quando os dados que ele retorna são lixo
Questões
- Por que
md
a unidade/partição que não responde falha? - Posso eliminar a unidade/partição do array enquanto a unidade estiver bloqueada?
- Um tempo limite pode ser configurado para
md
falhar automaticamente em uma unidade que não está respondendo aos comandos ATA? - Por que
md
continua usando um dispositivo com dados inválidos?
Responder1
Deltik, você não entendeu como o Linux Software RAID ( md
) funciona.
md
cria um dispositivo de bloco virtual a partir de vários dispositivos ou partições e não tem conhecimento de quais dados você está transferindo de e para o dispositivo virtual.
Você esperava que ele pudesse fazer coisas para as quais não foi projetado.
Respostas
1. Por que md
a unidade/partição que não responde falha?
Isso ocorre porque md
não tem ideia se
- a unidade está ocupada com E/S de algo que
md
solicitou ou - a unidade foi bloqueada devido a alguma circunstância externa, como a recuperação de erros da própria unidade ou, no seu caso, um ATA Secure Erase,
então md
vamos esperar para ver o que a unidade retorna. A unidade eventualmente não retornou nenhum erro de leitura ou gravação. Se houvesse um erro de leitura, o md
dispositivo teria sido corrigido automaticamente da paridade, e se houvesse um erro de gravação, md
o dispositivo teria falhado (veja a seção "Recuperação" domd
página de manual).
Como não houve erro de leitura nem de gravação, md
continuei usando o dispositivo depois que o kernel esperou que ele respondesse.
2. Posso eliminar a unidade/partição do array enquanto a unidade estiver bloqueada?
Não. O /dev/md0
dispositivo RAID está bloqueado e não pode ser modificado até que o bloqueio seja limpo.
Você passou o sinalizador -f
ou --fail
para o mdadm
modo "Gerenciar".
Aqui está um passo a passo do que isso realmente faz:
Este é o código fonte de como esse sinalizador funciona:
case 'f': /* set faulty */
/* FIXME check current member */
if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) ||
(sysfd < 0 && ioctl(fd, SET_DISK_FAULTY,
rdev))) {
if (errno == EBUSY)
busy = 1;
pr_err("set device faulty failed for %s: %s\n",
dv->devname, strerror(errno));
if (sysfd >= 0)
close(sysfd);
goto abort;
}
if (sysfd >= 0)
close(sysfd);
sysfd = -1;
count++;
if (verbose >= 0)
pr_err("set %s faulty in %s\n",
dv->devname, devname);
break;
Observe a chamada write(sysfd, "faulty", 6)
. sysfd
é uma variável definida anteriormente no arquivo:
sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");
sysfs_open()
é uma função deeste ficheiro:
int sysfs_open(char *devnm, char *devname, char *attr)
{
char fname[50];
int fd;
sprintf(fname, "/sys/block/%s/md/", devnm);
if (devname) {
strcat(fname, devname);
strcat(fname, "/");
}
strcat(fname, attr);
fd = open(fname, O_RDWR);
if (fd < 0 && errno == EACCES)
fd = open(fname, O_RDONLY);
return fd;
}
Se você seguir as funções, descobrirá que mdadm /dev/md0 -f /dev/sdb1
basicamente faz isso:
echo "faulty" > /sys/block/md0/md/dev-sdb1/block/dev
Esta solicitação estará aguardando e não será processada imediatamente porque /dev/md0
está bloqueada.
3. Um tempo limite pode ser configurado para md
falhar automaticamente em uma unidade que não está respondendo aos comandos ATA?
Sim. Na verdade,por padrão, o tempo limite é de 30 segundos:
root@node51 [~]# cat /sys/block/sdb/device/timeout
30
O problema com sua suposição era que sua unidade estava realmente ocupada executando um comando ATA (por 188 minutos), portanto o tempo limite não estava esgotado.
Para obter detalhes sobre isso, consulte oDocumentação de tratamento de erros SCSI do kernel Linux.
4. Por que md
continua usando um dispositivo com dados inválidos?
Quando o ATA Secure Erase foi concluído, a unidade não relatou nenhum problema, como um comando abortado, portanto md
não havia motivo para suspeitar que havia um problema.
Além disso, no caso de usar partições como dispositivos RAID em vez de discos inteiros, a tabela de partições na memória do kernel não foi informada de que a partição na unidade apagada havia desaparecido, então md
continuaria a acessá-la /dev/sdb1
como se nada estivesse errado.
Isto é domd
página de manual:
Esfregando e incompatibilidades
Como os dispositivos de armazenamento podem desenvolver blocos defeituosos a qualquer momento, é valioso ler regularmente todos os blocos em todos os dispositivos de uma matriz para detectar esses blocos defeituosos antecipadamente. Este processo é chamadoesfregando.
Matrizes md podem ser limpas escrevendoverificarourepararpara o arquivomd/sync_actionnosysfsdiretório do dispositivo.
Solicitar uma limpeza fará com que o md leia todos os blocos em todos os dispositivos da matriz e verifique se os dados são consistentes. Para RAID1 e RAID10, isso significa verificar se as cópias são idênticas. Para RAID4, RAID5, RAID6, isso significa verificar se o bloco de paridade está (ou os blocos estão) corretos.
Podemos inferir disso que a paridade normalmente não é verificada em todas as leituras do disco. (Além disso, verificar a paridade em cada leitura seria muito desgastante para o desempenho, pois aumentaria as transações necessárias apenas para concluir uma leitura e executaria a comparação da paridade com os dados lidos.)
Em operação normal, md
apenas assume que os dados que está lendo são válidos, deixando-o vulnerável acorrupção silenciosa de dados. No seu caso, você tinha uma unidade inteira com dados corrompidos silenciosamente porque apagou a unidade.
Seu sistema de arquivos não estava ciente da corrupção. Você viu erros de entrada/saída no nível do sistema de arquivos porque o sistema de arquivos não conseguia entender por que havia dados incorretos.
Para evitar a corrupção silenciosa de dados, primeiro,nunca mais faça o que você fez. Em segundo lugar, considere usarZFS, um sistema de arquivos que se concentra na integridade dos dados e detecta e corrige a corrupção silenciosa de dados.