私のSSDにある種のハードウェア障害があるため、まだ保証期間中なので修理できますが、そのサービスにはデータ復旧は含まれていません。ここから作業ファイルを収集しましたが、個人ファイルとプラグインがまだ残っているので、復元したいと思います。
問題は…帯域幅と総コピーサイズが問題のようです。読みすぎるとドライブがクラッシュする可能性があります。どこでも不良セクタ(エラー)を報告するか、オペレーティングシステム全体をシャットダウンしてください。そのため、メモリバッファに問題があると思われ、ドライブをホットスワップできるようにエンクロージャに入れました。もう1つの質問では、帯域幅制限のあるrsyncを使用することを検討しましたが、バッファを自分で消去または冷却できるようにコピープロセスに時間差を置く必要があると思います。
失われたデータを回復するには、スクリプトまたはツールが必要です。
答え1
不良セクタ(エラー)がどこでも報告されている
SSDには「セクタ」はありません。 「ブロック」はそうです。ドライブが故障していると報告している場合、これは機械的に何も失敗しないためです。
- ブロックのこれらのビットを取得するには、アドレスラインを確認してください。
- 「電圧読み出しベクトルを得た」を意味するメモリセルを読み出す。
- やや複雑なソフト入力エラー訂正コードを適用してビットに変換してみてください。
- (成功とデータ)または(エラー)を返します。
- これを復号しようとする試み(繰り返し)が成功すると、ある時点でゼロになるエラー用語(デコーダの「症候群」)が生成されます。
- ソフト値が実際には修正されず、エラーのない単語を生成するためにエラーが修正されるとエラーが発生します。
したがって、エラーが発生します。これは、コンテンツが読み取れないことを意味します。 「SSDはありません。間違った回復不能なデータ情報": 常に読みます。一部すべてがどんなに損傷していても、電圧が検査に合格していることを確認し、必要に応じて修正してください。そして可能。
だから:
どこでも不良セクタが報告されている
SSDを信頼する必要があります。 SSDは実際にデータを読み取ることができません。メモリセル(特定の電圧で充電された小さなコンデンサ)は損傷していませんが、「グローバルに」変更できる唯一のことは、アナログを変換するADCの基準電圧を「移動」することです。読み出し電圧をデジタル値に変換することは難しくなる。これにより、実際のメモリが良好であってもデコーダは誤ったソフト入力を受け取ります。
ただし、この電圧が発生します。同じ枠内でフラッシュチップ内のADCは、電源電圧などの変化に非常に弾力的でなければならないためです。
したがって、これは実際には熱問題であるか、またはある種のシリコンモードエラーであり得る。
どちらの方法でも、ドライブからデータをインポートするためにrsyncやファイルシステムレベルのツールを使用したくないようです。これを行うには、どのデータがどのファイルにあるかを理解するために、オペレーティングシステムが同じデータポイントに非常に頻繁にアクセスできる必要があります。
あなたがしなければならないことは、ブロックデバイスレベルのコピーを作成し、小さなステップで行うことです。たとえば、16MB をイメージファイルとして読み込みます。しばらくお待ちください。 16MBの読み取りなど。
dd
これは、チャンクを順番に読み込んだ後にwaitを呼び出し、次のチャンクを読み取るなどのループを使用するZSH / bashシェルスクリプトsleep
またはPythonの数行で実行できます。後で同じ時点で再開できるように、読み取りプロセスにエラーがあることを確認し、エラーが発生した場合はプロセスを中断することを忘れないでください。
実際にソリューションを準備する必要があるので:
#!/usr/bin/zsh
# Copyright 2022 Marcus Müller
# SPDX-License-Identifier: BSD-3-Clause
# Find the license text under https://spdx.org/licenses/BSD-3-Clause.html
# THIS SCRIPT IS UNTESTED AND COMES WITH NO WARRANTIES, FOLKS.
IN_DEVICE=/dev/yoursource_ssd
BACKUP_IMG=myimage
LOGFILE=broken_mbs.txt
# get size, round up to full MB
size_in_bytes=$(blockdev "${IN_DEVICE}")
size_in_MB=$(( ( ${size_in_bytes} + 2**20 - 1) / 2**20 ))
#check whether size > 0
if [[ ! ${size_in_MB} -gt 0 ]]; then
logger -p user.crit "Nope, can't determine size of ${IN_DEVICE}. I'm outta here."
echo "Failure on input" >&2
exit -1
else
logger -p user.info "Trying to back up ${IN_DEVICE}, size ${size_in_MB} MB"
fi
if fallocate -l "${size_in_MB}MiB" "${BACKUP_IMG}" ; then
logger -p user.info "preallocated ${BACKUP_IMG}"
else
logger -p user.crit "failed to preallocate ${BACKUP_IMG}"
echo "failure on output" >&2
exit -2
fi
failcounter=0
MB=$((2**20))
for i in {0..$((${size_in_MB}-1))}; do
if \
dd \
"if=${IN_DEVICE}" \
"of=${BACKUP_IMG}" \
"ibs=${MB}" "obs=${MB}" \
"skip=${i}" "seek=${i}" ; \
then
echo "backed up MB nr. ${i}"
else
failcounter=$(( ${failcounter} + 1 ))
echo "${failcounter}. error: couldn't backup MB nr. $i" > &2
echo "${i}" >> ${LOGFILE}
logger -p user.err "couldn't backup MB nr. $i"
fi
sleep 0.5
done
echo "Got ${failcounter} failures"
exit ${failcounter}