200GBの空きディスク容量、16GBのRAM(デスクトップとカーネルが約1GBを占める)、6GBのスワップ領域があります。
240GBの外付けSSDがあり、そのうち70GBを使用し、残りは無料なので、ディスクにバックアップする必要があります。
通常、dd if=/dev/sdb of=Desktop/disk.img
最初にディスクを作成してから圧縮しますが、最初にイメージを作成することはオプションではありません。これは、圧縮段階で空き容量が圧縮され、最終イメージが圧縮されても必要以上のディスク容量が必要になるためです。アーカイブは私のディスクに簡単に入れることができます。
dd
デフォルトでは、STDOUTに書き込んでgzip
STDINから読み取ることができるので、理論的には書き込むことができますが、バイトをdd if=/dev/sdb | gzip -9 -
生成するよりも読み込むgzip
のにはるかに時間がかかります。dd
~からman pipe
:
パイプの書き込みの終わりに書き込まれたデータは、パイプの読み取りの最後から読み取られるまでカーネルによってバッファリングされます。
私は|
パイプラインを実際のパイプラインとして想像しています。あるアプリケーションはデータをパイプラインキューにプッシュし、他のアプリケーションはできるだけ早くパイプラインキューからデータを取得します。
パイプの反対側で処理できるデータよりも左側のプログラムがより速くデータを書き込むとどうなりますか?過度のメモリやスワップ領域の使用は発生しますか?または、カーネルはディスクにFIFOを作成してディスクを埋めようとしますか?それともSIGPIPE Broken pipe
バッファが大きすぎると失敗しますか?
デフォルトでは、これは2つの質問に帰結します。
- 一度に読み取ることができるよりも多くのデータがパイプにプッシュされると、どのような影響と結果が発生しますか?
- 圧縮されていないデータストリーム全体をディスクに保存せずにデータストリームをディスクに圧縮する安定した方法は何ですか?
注 1: 断片化やその他の要因によってコンテンツ全体が破損しないようにするため、最初に使用した 70 GB の正確なコピーを作成して動作するシステムやファイルシステムを取得することは期待できません。
ベストアンサー1
dd
データブロックは一度に1つずつ読み書きし、未解決のデータブロックは1つだけです。だから
valgrind dd if=/dev/zero status=progress of=/dev/null bs=1M
約dd
1MBのメモリが使用されます。チャンクのサイズを変更して削除すると、valgrind
速度に与える影響を確認できます。dd
gzip
入力するときはdd
一致速度を遅くしてくださいgzip
。メモリ使用量が増えず、カーネルがディスクにバッファを保存することもできません(カーネルはこれを行う方法がわかりません)。渡す交換)。チューブ破裂signal(7)
は、チューブの一端が死んだときにのみ発生しますwrite(2)
。
だから
dd if=... iconv=fullblock bs=1M | gzip -9 > ...
欲しいものを達成する安全な方法です。
パイピング中に読み取りプロセスが維持されない場合、最終的に書き込みプロセスはカーネルによってブロックされます。これを実行すると見ることができます
strace dd if=/dev/zero bs=1M | (sleep 60; cat > /dev/null)
1MBの読み取りが表示されdd
たら、aを実行しwrite()
、実行中にしばらく待ちますsleep
。これがパイプの両側がバランスをとる方法です。書き込みプロセスが速すぎる場合、カーネルは書き込みをブロックし、読み取りプロセスが速すぎるとカーネルは読み取りをブロックします。