Abordagem empírica. Eu decidi fazer um teste. Resposta curta: o teste não mostrou que o procedimento é inseguro.
Testbed
uname -a
:
Linux foobar 3.2.0-4-amd64 #1 SMP Debian 3.2.86-1 x86_64 GNU/Linux
Um trecho de smartctl -a /dev/sdc
:
Model Family: Western Digital Caviar Blue EIDE
Device Model: WDC WD5000AAKB-00H8A0
Firmware Version: 05.04E05
User Capacity: 500,107,862,016 bytes [500 GB]
Sector Size: 512 bytes logical/physical
A SMART também mostra que o disco está íntegro.
Ele foi conectado via ponte USB (ao hub USB 2.0). lsusb | grep SATA
:
Bus 001 Device 003: ID 152d:2509 JMicron Technology Corp. / JMicron USA Technology Corp. JMS539 SuperSpeed SATA II 3.0G Bridge
Uma partição, quase sem espaço não alocado. fdisk -l /dev/sdc
:
Disk /dev/sdc: 465,8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x202b0b89
Device Boot Start End Sectors Size Id Type
/dev/sdc1 2048 976773167 976771120 465,8G 83 Linux
Sistema de arquivos ext4 saudável, desmontado. file -s /dev/sdc1
:
/dev/sdc1: Linux rev 1.0 ext4 filesystem data, UUID=… (extents) (large files) (huge files)
O uso do sistema de arquivos foi de cerca de 20%, mas:
- ele foi usado extensivamente, então o espaço livre não era todo zeros com certeza;
- Eu não confiaria no sistema de arquivos, calculei
md5sum
de todo o dispositivo (veja abaixo).
Teste
Primeiro, salvei a soma de verificação do conteúdo inteiro do dispositivo:
md5sum -b /dev/sdc > sdc.before.md5
# the throughput was about 24 MB/s
Atual dd
-ing:
dd if=/dev/sdc of=/dev/sdc
# took 800 minutes, 10,4 MB/s
dd if=/dev/sdc of=/dev/sdc bs=128M conv=sync
# 630 minutes, 13,2 MB/s
dd if=/dev/sdc of=/dev/sdc bs=512 conv=sync
# 795 minutes, 10,5 MB/s
Após cada dd
, corro sync
e, em seguida, md5sum -b /dev/sdc
. Todas as somas de verificação correspondem a sdc.before.md5
.
Eu também gostei de strace dd if=/dev/sdc of=/dev/sdc
e ele inundou meu terminal com pares de linhas como:
read(0, "]3read(0, "A0_45631p3102243365734\fx@=01+"..., 134217728) = 134217728
write(1, "A0_45631p3102243365734\fx@=01+"..., 134217728) = 134217728
Linux foobar 3.2.0-4-amd64 #1 SMP Debian 3.2.86-1 x86_64 GNU/Linux
]3Model Family: Western Digital Caviar Blue EIDE
Device Model: WDC WD5000AAKB-00H8A0
Firmware Version: 05.04E05
User Capacity: 500,107,862,016 bytes [500 GB]
Sector Size: 512 bytes logical/physical
]3Bus 001 Device 003: ID 152d:2509 JMicron Technology Corp. / JMicron USA Technology Corp. JMS539 SuperSpeed SATA II 3.0G Bridge
]3Disk /dev/sdc: 465,8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x202b0b89
Device Boot Start End Sectors Size Id Type
/dev/sdc1 2048 976773167 976771120 465,8G 83 Linux
]3/dev/sdc1: Linux rev 1.0 ext4 filesystem data, UUID=… (extents) (large files) (huge files)
]3\fmd5sum -b /dev/sdc > sdc.before.md5
# the throughput was about 24 MB/s
]3\rdd if=/dev/sdc of=/dev/sdc
# took 800 minutes, 10,4 MB/s
dd if=/dev/sdc of=/dev/sdc bs=128M conv=sync
# 630 minutes, 13,2 MB/s
dd if=/dev/sdc of=/dev/sdc bs=512 conv=sync
# 795 minutes, 10,5 MB/s
]3read(0, "]3read(0, "A0_45631p3102243365734\fx@=01+"..., 134217728) = 134217728
write(1, "A0_45631p3102243365734\fx@=01+"..., 134217728) = 134217728
%pre%]3%pre%]3%pre%]3%pre%]3%pre%]3\f%pre%]3\r%pre%]3%pre%"..., 512) = 512
write(1, "]3%pre%%pre%]3%pre%]3%pre%]3%pre%]3%pre%]3\f%pre%]3\r%pre%]3%pre%"..., 512) = 512
"..., 512) = 512
write(1, "]3%pre%%pre%]3%pre%]3%pre%]3%pre%]3%pre%]3\f%pre%]3\r%pre%]3%pre%"..., 512) = 512
ou (para o grande bs
)
Conclusões e respostas
- Is it safe regardless of file system?
A soma de verificação permanece a mesma e não há nada específico do sistema de arquivos aqui. Sobrescrever dados com os mesmos dados deve ser seguro.
Nota: isto é verdade para os drives magnéticos que sobrescrevem os setores diretamente. Por outro lado, os SSDs (e não tenho certeza se todos eles) precisam apagar um setor (ou vários setores de uma só vez) antes que ele possa ser gravado novamente. O mesmo setor lógico pode ser gravado em uma "célula" física diferente, etc. Em caso de falta de energia, isso pode levar à corrupção de dados (ou não, eu sei pouco sobre precauções em SSDs). Você mencionou o fluxo magnético, então acho que os SSDs estão fora do escopo de qualquer maneira.
- Does this process do what I expect it to do, i.e. read a sector, then immediately rewrite it?
strace
mostra que isso é exatamente o que acontece. Os buffers podem atrasar as gravações, mas parece que todos os setores lidos serão reescritos mais cedo ou mais tarde.
Posso pensar em uma "otimização" (no SO ou no firmware do HDD) que compararia uma solicitação de gravação às leituras em cache e poderia descartar a gravação como desnecessária se os dados já estivessem lá. Poderia tornar seu procedimento inútil. No entanto, parece improvável porque:
- a correspondência raramente ocorreria, a menos que você queira deliberadamente que isso aconteça;
- o cache não grande o suficiente não faria diferença para grandes valores
bs
.
Então, em caso de dúvida, use apenas bs
grande. Grande bs
é bom para o desempenho também.
- Does this have the desired practical effects, or is preventing some forms of bit rot in this way snake oil?
Concordo com um dos comentários:
Ainda assim, para confirmar isso na prática, precisamos de análise estatística de muitos discos (alguns "rejuvenescidos", outros não) por um longo tempo. Meu único teste não pode responder isso.It does rewrite each sector, so presumably that is the "cure" for the alleged bit rot.