200 GBの空きディスク領域、16 GBのRAM(そのうち1 GBはデスクトップとカーネルによって占有されています)、および6 GBのスワップがあります。
240 GBの外部SSDがあり、70 GBを使用しています1 残りは無料で、ディスクにバックアップする必要があります。
通常、私は最初にディスクをdd if=/dev/sdb of=Desktop/disk.img
し、次にそれを圧縮しますが、最初にイメージを作成することはオプションではありません。圧縮ステップを実行すると、最終的なアーカイブが私のディスクに簡単に収まるように、スペースが押しつぶされています。
dd
はデフォルトでSTDOUTに書き込み、gzip
はSTDINから読み取ることができるため、理論的にはdd if=/dev/sdb | gzip -9 -
を書き込むことができますが、gzip
はバイトの読み取りにかなり時間がかかりますdd
はそれらを生成できます。
man pipe
から:
パイプの書き込み側に書き込まれたデータは、パイプの読み取り側から読み取られるまでカーネルによってバッファリングされます。
私は|
を実際のパイプのように視覚化します。1つのアプリケーションがデータを入力し、もう1つのアプリケーションがパイプのキューからデータをできるだけ早く取り出します。
左側のプログラムがパイプの反対側で処理できるよりも多くのデータをより速く書き込むとどうなるでしょうか。極端なメモリまたはスワップの使用を引き起こすか、またはカーネルがFIFO=を作成してディスクをいっぱいにしようとしますか?または、バッファがSIGPIPE Broken pipe
で失敗するだけです。大きすぎる?
基本的に、これは2つの質問に要約されます:
注1:最初の70使用済みGBを正確にコピーすることはできません。断片化やその他の完全なコンテンツを完全な状態にする必要があるため、システムまたはファイルシステムが動作することを期待しています。
技術的には、dd
も必要ありません。
_gzip < /dev/drive > drive.img.gz
_
dd
を使用する場合は、常に_dd bs=1M
_のようなデフォルトのブロックサイズよりも大きくするか、syscall hell(dd
のデフォルトのブロックサイズは512バイトであるため、read()
およびwrite()
は、MiB
ごとの_4096
_システムコールです。オーバーヘッドが多すぎます)。
_gzip -9
_は、表示するCPUが非常に少ない状態で、より多くのCPUを使用します。 gzip
によって速度が低下する場合は、圧縮レベルを下げるか、別の(高速な)圧縮方法を使用してください。
dd
イメージの代わりにファイルベースのバックアップを実行している場合は、圧縮するかどうかを決定するロジックを使用できます(さまざまなファイルタイプに対して圧縮する意味はありません)。 dar
(tar
Alternative`)は、そのためのオプションがある1つの例です。
空き容量がゼロの場合(TRIMの後に確実にゼロを返すSSDであり、fstrim
を実行してキャッシュを削除したため)、dd
を_conv=sparse
_フラグとともに使用して、ゼロ領域にゼロディスクスペースを使用する、非圧縮のループマウント可能なスパースイメージ。スパースファイルをサポートするファイルシステムで画像ファイルをバックアップする必要があります。
あるいは、一部のファイルシステムでは、使用された領域のみを画像化できるプログラムが存在します。
dd
は、一度に1ブロックずつデータを読み書きします。未処理のブロックは1つだけです。そう
_valgrind dd if=/dev/zero status=progress of=/dev/null bs=1M
_
は、dd
が約1MBのメモリを使用することを示しています。ブロックサイズをいじってvalgrind
をドロップすると、dd
の速度への影響を確認できます。
gzip
にパイプすると、dd
はgzip
の速度に合わせて単に減速します。そのメモリ使用量は増加せず、カーネルがバッファをディスクに保存することもありません(カーネルはvia swapを除いて、その方法を知りません)。パイプの破損は、パイプの一方の端が死んだときにのみ発生します。詳細については、signal(7)
およびwrite(2)
を参照してください。
したがって
_dd if=... iconv=fullblock bs=1M | gzip -9 > ...
_
あなたがしていることをするための安全な方法です。
パイプするとき、読み取りプロセスが追いついていない場合、書き込みプロセスはカーネルによってブロックされます。あなたは実行することでこれを見ることができます
_strace dd if=/dev/zero bs=1M | (sleep 60; cat > /dev/null)
_
dd
が1 MBを読み取り、次にwrite()
を発行して、sleep
の実行中に1分間待機します。これがパイプの両側のバランスです。カーネルは、書き込みプロセスが速すぎる場合は書き込みをブロックし、読み込みプロセスが速すぎる場合は読み取りをブロックします。
パフォーマンス以外に悪影響はありません。パイプには通常64Kのバッファーがあり、その後、パイプへの書き込みはgzip
がさらにデータを読み取るまで単純にブロックされます。
それがどのように機能するかについての実際の質問に答える:「左側のプログラムがパイプの反対側がそれを処理することを期待できるよりも速くより多くのデータを書き込む場合はどうなりますか?」
これは起こりません。パイプには、かなり小さく制限されたサイズのバッファがあります。参照 パイプバッファの大きさ
パイプバッファがいっぱいになると、送信プログラムはblocksします。書き込み呼び出しを行うと、データがバッファーに書き込まれるまで、カーネルは制御をプログラムに返しません。これは、バッファを空にするための読み取りプログラムのCPU時間を与えます。
たぶん、必要なのはファイルだけで、次にtarを使用します。あなたが欲しいものを何も含まないブロックをゼロで埋めることができます、誰かがすでにそれについて尋ねました。 ゼロで未使用のスペースをクリア(ext3、ext4)
次に、pigz
があり、これは通常gzip
より高速です。