dr: como eu faria para consertar um bloco defeituoso em 1 disco em uma matriz RAID1?
Mas, por favor, leia tudo isso para saber o que já tentei e possíveis erros em meus métodos. Tentei ser o mais detalhado possível e espero realmente algum feedback
Esta é a minha situação: tenho dois discos de 2 TB (mesmo modelo) configurados em um array RAID1 gerenciado por mdadm
. Cerca de 6 meses atrás, notei o primeiro bloqueio incorreto quando a SMART o relatou. Hoje percebi mais e agora estou tentando consertar.
Esta página COMO FAZERparece ser o único artigo ao qual todos vinculam para corrigir bloqueios defeituosos que a SMART está relatando. É uma página ótima, cheia de informações, porém está bastante desatualizada e não aborda minha configuração específica. Aqui está como minha configuração é diferente:
- Em vez de um disco, estou usando dois discos em uma matriz RAID1. Um disco está relatando erros enquanto o outro está bem. O HOWTO foi escrito com apenas um disco em mente, o que levanta várias questões como 'devo usar este comando no dispositivo de disco ou no dispositivo RAID'?
- Estou usando GPT, que o fdisk não suporta. Em vez disso, tenho usado o gdisk e espero que ele esteja me fornecendo as mesmas informações de que preciso
Então, vamos direto ao assunto. Isso é o que eu fiz, mas não parece estar funcionando. Sinta-se à vontade para verificar meus cálculos e métodos em busca de erros. Os erros de relatório do disco são /dev/sda:
# smartctl -l selftest /dev/sda
smartctl 5.42 2011-10-20 r3458 [x86_64-linux-3.4.4-2-ARCH] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net
=== START OF READ SMART DATA SECTION ===
SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Short offline Completed: read failure 90% 12169 3212761936
Com isso, concluímos que o erro reside no LBA 3212761936. Seguindo o HOWTO, utilizo o gdisk para encontrar o setor inicial a ser usado posteriormente na determinação do número do bloco (já que não posso usar o fdisk, pois ele não suporta GPT):
# gdisk -l /dev/sda
GPT fdisk (gdisk) version 0.8.5
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 3907029168 sectors, 1.8 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): CFB87C67-1993-4517-8301-76E16BBEA901
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 3907029134
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 3907029134 1.8 TiB FD00 Linux RAID
Usando tunefs
, acho que o tamanho do bloco é 4096
. Usando esta informação e o cálculo do HOWTO, concluo que o bloco em questão é ((3212761936 - 2048) * 512) / 4096 = 401594986
.
O HOWTO então me orienta para debugfs
ver se o bloco está em uso (eu uso o dispositivo RAID pois ele precisa de um sistema de arquivos EXT, esse foi um dos comandos que me confundiu pois a princípio não sabia se deveria usar / dev/sda ou /dev/md0):
# debugfs
debugfs 1.42.4 (12-June-2012)
debugfs: open /dev/md0
debugfs: testb 401594986
Block 401594986 not in use
Portanto, o bloco 401594986 é um espaço vazio, devo poder escrever sobre ele sem problemas. Antes de escrever, porém, tento ter certeza de que, de fato, não pode ser lido:
# dd if=/dev/sda1 of=/dev/null bs=4096 count=1 seek=401594986
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000198887 s, 20.6 MB/s
Se o bloco não pudesse ser lido, eu não esperaria que isso funcionasse. No entanto, isso acontece. Repito usando /dev/sda
, /dev/sda1
, /dev/sdb
, /dev/sdb1
, /dev/md0
e +-5 para o número do bloco para pesquisar o bloco defeituoso. Tudo funciona. Encolho os ombros e sigo em frente e confirmo a gravação e sincronização (eu uso /dev/md0 porque imaginei que modificar um disco e não o outro poderia causar problemas, desta forma ambos os discos substituem o bloco defeituoso):
# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=401594986
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000142366 s, 28.8 MB/s
# sync
Eu esperaria que a gravação no bloco defeituoso fizesse com que os discos reatribuíssem o bloco para um bloco bom, no entanto, a execução de outro teste SMART mostra uma diferença diferente:
# 1 Short offline Completed: read failure 90% 12170 3212761936
De volta à estaca zero. Então, basicamente, como eu consertaria um bloco defeituoso em 1 disco em uma matriz RAID1? Tenho certeza de que não fiz algo corretamente...
Obrigado pelo seu tempo e paciência.
EDITAR 1:
Tentei executar um longo teste SMART, com o mesmo LBA retornando como ruim (a única diferença é que ele relata 30% restantes em vez de 90%):
SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Extended offline Completed: read failure 30% 12180 3212761936
# 2 Short offline Completed: read failure 90% 12170 3212761936
Também usei badblocks com a seguinte saída. A saída é estranha e parece estar formatada incorretamente, mas tentei testar os números gerados como blocos, mas o debugfs apresenta um erro
# badblocks -sv /dev/sda
Checking blocks 0 to 1953514583
Checking for bad blocks (read-only test): 1606380968ne, 3:57:08 elapsed. (0/0/0 errors)
1606380969ne, 3:57:39 elapsed. (1/0/0 errors)
1606380970ne, 3:58:11 elapsed. (2/0/0 errors)
1606380971ne, 3:58:43 elapsed. (3/0/0 errors)
done
Pass completed, 4 bad blocks found. (4/0/0 errors)
# debugfs
debugfs 1.42.4 (12-June-2012)
debugfs: open /dev/md0
debugfs: testb 1606380968
Illegal block number passed to ext2fs_test_block_bitmap #1606380968 for block bitmap for /dev/md0
Block 1606380968 not in use
Não tenho certeza para onde ir a partir daqui. badblocks
definitivamente encontrei algo, mas não tenho certeza do que fazer com as informações apresentadas ...
EDITAR 2
Mais comandos e informações.
Eu me sinto um idiota por esquecer de incluir isso originalmente. Estes são os valores SMART para /dev/sda
. Tenho 1 Current_Pending_Sector e 0 Offline_Uncorrectable.
SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
1 Raw_Read_Error_Rate 0x002f 100 100 051 Pre-fail Always - 166
2 Throughput_Performance 0x0026 055 055 000 Old_age Always - 18345
3 Spin_Up_Time 0x0023 084 068 025 Pre-fail Always - 5078
4 Start_Stop_Count 0x0032 100 100 000 Old_age Always - 75
5 Reallocated_Sector_Ct 0x0033 252 252 010 Pre-fail Always - 0
7 Seek_Error_Rate 0x002e 252 252 051 Old_age Always - 0
8 Seek_Time_Performance 0x0024 252 252 015 Old_age Offline - 0
9 Power_On_Hours 0x0032 100 100 000 Old_age Always - 12224
10 Spin_Retry_Count 0x0032 252 252 051 Old_age Always - 0
11 Calibration_Retry_Count 0x0032 252 252 000 Old_age Always - 0
12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 75
181 Program_Fail_Cnt_Total 0x0022 100 100 000 Old_age Always - 1646911
191 G-Sense_Error_Rate 0x0022 100 100 000 Old_age Always - 12
192 Power-Off_Retract_Count 0x0022 252 252 000 Old_age Always - 0
194 Temperature_Celsius 0x0002 064 059 000 Old_age Always - 36 (Min/Max 22/41)
195 Hardware_ECC_Recovered 0x003a 100 100 000 Old_age Always - 0
196 Reallocated_Event_Count 0x0032 252 252 000 Old_age Always - 0
197 Current_Pending_Sector 0x0032 100 100 000 Old_age Always - 1
198 Offline_Uncorrectable 0x0030 252 100 000 Old_age Offline - 0
199 UDMA_CRC_Error_Count 0x0036 200 200 000 Old_age Always - 0
200 Multi_Zone_Error_Rate 0x002a 100 100 000 Old_age Always - 30
223 Load_Retry_Count 0x0032 252 252 000 Old_age Always - 0
225 Load_Cycle_Count 0x0032 100 100 000 Old_age Always - 77
# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Thu May 5 06:30:21 2011
Raid Level : raid1
Array Size : 1953512383 (1863.01 GiB 2000.40 GB)
Used Dev Size : 1953512383 (1863.01 GiB 2000.40 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Update Time : Tue Jul 3 22:15:51 2012
State : clean
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Name : server:0 (local to host server)
UUID : e7ebaefd:e05c9d6e:3b558391:9b131afb
Events : 67889
Number Major Minor RaidDevice State
2 8 1 0 active sync /dev/sda1
1 8 17 1 active sync /dev/sdb1
De acordo com uma das respostas: parece que mudei seek
e skip
para dd
. Eu estava usando seek porque é isso que é usado no HOWTO. Usar este comando causa dd
o travamento: # dd if=/dev/sda1 of=/dev/null bs=4096 count=1 skip=401594986
Usar blocos em torno desse (..84, ..85, ..87, ..88) parece funcionar muito bem, e usar /dev/sdb1 com bloco 401594986
também funciona bem (como esperado, já que o disco passou no teste SMART ). Agora a dúvida que tenho é: Ao escrever nesta área para reatribuir os blocos, devo usar /dev/sda1
ou /dev/md0
? Não quero causar problemas com a matriz RAID gravando diretamente em um disco e não atualizando o outro disco.
EDITAR 3
Escrever no bloco produzia erros diretamente no sistema de arquivos. Escolhi uma resposta que resolveu o problema rapidamente:
# 1 Short offline Completed without error 00% 14211 -
# 2 Extended offline Completed: read failure 30% 12244 3212761936
Obrigado a todos que ajudaram. =)
Responder1
Todas estas respostas de “cutucar o sector” são, francamente, uma loucura. Eles correm o risco de corrupção (possivelmente oculta) do sistema de arquivos. Se os dados já tivessem desaparecido, porque aquele disco armazenava a única cópia, seria razoável. Mas há uma cópia perfeitamente boa no espelho.
Você só precisa que o mdraid esfregue o espelho. Ele notará o setor defeituoso e o reescreverá automaticamente.
# echo 'check' > /sys/block/mdX/md/sync_action # use 'repair' instead for older kernels
Você precisa colocar o dispositivo correto lá (por exemplo, md0 em vez de mdX). Isso demorará um pouco, pois acontece com todo o array por padrão. Em um kernel novo o suficiente, você pode escrever números de setor primeiro em sync_min/sync_max, para limitá-lo a apenas uma parte da matriz.
Esta é uma operação segura. Você pode fazer isso em todos os seus dispositivos mdraid. Na verdade, vocêdevefaça isso em todos os seus dispositivos mdraid regularmente. Sua distro provavelmente vem com um cronjob para lidar com isso, talvez você precise fazer algo para habilitá-lo?
Script para todos os dispositivos RAID no sistema
Há algum tempo, escrevi este script para "reparar" todos os dispositivos RAID no sistema. Isto foi escrito para versões mais antigas do kernel, onde apenas 'reparar' consertaria o setor defeituoso; agora apenas fazer a verificação é suficiente (o reparo ainda funciona bem em kernels mais novos, mas também copia/reconstrói a paridade, o que nem sempre é o que você deseja, especialmente em unidades flash)
#!/bin/bash
save="$(tput sc)";
clear="$(tput rc)$(tput el)";
for sync in /sys/block/md*/md/sync_action; do
md="$(echo "$sync" | cut -d/ -f4)"
cmpl="/sys/block/$md/md/sync_completed"
# check current state and get it repairing.
read current < "$sync"
case "$current" in
idle)
echo 'repair' > "$sync"
true
;;
repair)
echo "WARNING: $md already repairing"
;;
check)
echo "WARNING: $md checking, aborting check and starting repair"
echo 'idle' > "$sync"
echo 'repair' > "$sync"
;;
*)
echo "ERROR: $md in unknown state $current. ABORT."
exit 1
;;
esac
echo -n "Repair $md...$save" >&2
read current < "$sync"
while [ "$current" != "idle" ]; do
read stat < "$cmpl"
echo -n "$clear $stat" >&2
sleep 1
read current < "$sync"
done
echo "$clear done." >&2;
done
for dev in /dev/sd?; do
echo "Starting offline data collection for $dev."
smartctl -t offline "$dev"
done
Se você quiser fazer check
em vez de repair
, então este primeiro bloco (não testado) deve funcionar:
case "$current" in
idle)
echo 'check' > "$sync"
true
;;
repair|check)
echo "NOTE: $md $current already in progress."
;;
*)
echo "ERROR: $md in unknown state $current. ABORT."
exit 1
;;
esac
Responder2
Acabei de ter praticamente o mesmo problema com um array RAID1. O setor defeituoso estava logo no início de uma das partições - setor 16 de /dev/sdb2. Segui as instruções acima: depois de verificar se o bloco lógico 2 não estava em uso pelo sistema de arquivos e tomando cuidado para obter dd seek e skip da maneira correta, e zerei 1 bloco do sistema de arquivos:
# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=2
O que isso fez? Não corrigiu o setor defeituoso. Agora eu sei que isso ocorre porque /dev/md0 não mapeia diretamente para /dev/sdb2, você deve levar em consideração o RAID DATA OFFSET! Mais sobre isso abaixo. O que ele fez foi uma bosta pequena, mas potencialmente devastadora, no meu sistema de arquivos. Acontece que o bloco lógico 2 de /dev/md0 continha metadados úteis do sistema de arquivos e funcionava bem em ambos os discos, até que eu cagueiamboscópias escrevendo para /dev/md0. Felizmente, e2fsck -y /dev/md0 corrigiu o problema (depois de gerar uma quantidade alarmante de resultados) sem perda aparente de dados. Lição aprendida: se debugfs icheck disser 'bloco não encontrado', isso não significa necessariamente que os setores correspondentes não sejam usados.
De volta ao deslocamento de dados: use mdadm para encontrar o deslocamento assim:
# mdadm --examine /dev/sdb2
/dev/sdb2:
Magic : a92b4efc
Version : 1.2
Feature Map : 0x0
Array UUID : ef7934b9:24696df9:b89ff03e:b4e5a05b
Name : XXXXXXXX
Creation Time : Sat Sep 1 01:20:22 2012
Raid Level : raid1
Raid Devices : 2
Avail Dev Size : 1953241856 (931.38 GiB 1000.06 GB)
Array Size : 976620736 (931.38 GiB 1000.06 GB)
Used Dev Size : 1953241472 (931.38 GiB 1000.06 GB)
Data Offset : 262144 sectors
Super Offset : 8 sectors
State : clean
Device UUID : f3b5d515:446d4225:c2191fa0:9a9847b8
Update Time : Thu Sep 6 12:11:24 2012
Checksum : abb47d8b - correct
Events : 54
Device Role : Active device 0
Array State : AA ('A' == active, '.' == missing)
Neste caso, o deslocamento de dados é de 262.144 setores de 512 bytes. Se você dd de /dev/md0 e compará-lo com os dados da partição bruta com um deslocamento de 131072K, você descobrirá que eles correspondem. Portanto, no meu caso, o bloco lógico 2 (setores 16--23) de /dev/sdb2 nem sequer está no sistema de arquivos; eles estão no superbloco RAID, sobre o qual você pode ler aqui: https://raid.wiki.kernel.org/index.php/RAID_superblock_formats- para a versão 1.2, consiste em 256 bytes + 2 bytes por dispositivo no array, todos começando com 4096 bytes, então no meu caso o setor defeituoso não foi utilizado. Os setores correspondentes de /dev/sdc2 (a outra metade do array RAID1) são zero, então imaginei que seria seguro fazer isso:
# dd if=/dev/zero of=/dev/sdb2 bs=4096 count=1 seek=2
Funcionou!
Responder3
Se estiver executando o debian, você provavelmente terá um trabalho em /etc/cron.d/mdadm . Isso acontecerá /usr/share/mdadm/checkarray --cron --all --idle --quiet
no primeiro domingo de cada mês. Execute-o manualmente quando ocorrer erros de hardware incorrigíveis para agilizar a reescrita.
Responder4
Se você tiver um sw-raid1 e gravar dados diretamente em um dos membros, você terá um ataque corrompido imediatamente. NÃO grave dados em um sdaX ou sdbX se eles fizerem parte de um mdX. Se você gravar no mdX, os dados serão copiados para ambas as unidades; se você ler no mdX, os dados serão lidos em uma das unidades.