web-dev-qa-db-ja.com

なぜddは時間がかかりすぎるのですか?

ディスクを別のディスクにコピーする必要があります。以下のコマンドを試してみましたが、1 TB federoのディスクをコピーするのに1日近くかかります。

dd if=/dev/sda of=/dev/sdb 

以下のコマンドを使用してUnix(HP-UX)システムで同じことを試しましたが、数時間以内に完了します

dd if=/dev/sda of=/dev/rdsk

ディスクからディスクに高速でコピーするために使用できる代替手段は何ですか?

19
KKD

ddには多くの(奇妙な)オプションがあります。 dd(1) を参照してください。

バッファサイズを明示的に指定する必要があるので、

dd if=/dev/sda of=/dev/sdb bs=16M

IIRC、デフォルトのバッファサイズは512バイトのみです。上記のコマンドは、16メガバイトに設定します。もっと小さいものを試すことができます(例:bs=1M)ですが、デフォルトよりも多く使用する必要があります(特に、4Kバイトのセクターを持つ最近のディスクハードウェア、つまり Advanced Format )。私は単純に、少なくともメガバイトである2の累乗をお勧めします。

デフォルトの512バイトのバッファーサイズでは、ハードウェアがカーネルに512バイトのブロックごとに4Kを転送する必要があると思います(ただし、非常に間違っている可能性があります) 。

rdskについては、 sd(4) のmanページに次のように記載されています。

現時点では、ブロックデバイスのみが提供されています。 Rawデバイスはまだ実装されていません。

Ddのバッファーサイズを大きくすると、読み取りおよび書き込み操作のパフォーマンスが向上します。これで、すべてのディスクにハードウェアの読み取り/書き込みバッファーがあります。ただし、ハードウェアバッファーよりもddのバッファーサイズを大きくすると、2番目のディスクが独自のハードウェアバッファーからすべて書き込んだときにddが最初のディスクからバッファーに読み取るため、パフォーマンスが低下します。デバイスごとに異なる値を設定するたびに、ddコマンドのbsオプションを設定する必要があります。

29

Unixランドに数年前のddは、ブロックデバイスをコピーするために必要な方法でした。 (少なくともLinuxベースのシステムでは)catはほとんど常にddより高速ですが、それはカーゴカルトの知識として引き継がれています。

ただし、各システムコールがI/O操作をトリガーした場合、歴史に戻ってさえ、適切なブロックサイズはシステムコール(低速)の数を減らすのに役立ちました。デフォルトのブロックサイズは512バイト(1ディスクセクター)です。複数のディスクブロックをまとめて1回の読み取りにまとめることも可能であり、許容されます。この例では、32MBのブロックサイズを使用しています。

dd bs=$((512*2048*32)) if=/dev/source of=/dev/target

ただし、現在のLinuxベースのシステムでは、単純なcatでディスクを最も効率的にコピーできます。

cat /dev/source >/dev/target

(質問のコメントで述べたように、pvcatの代わりに使用でき、進行状況とスループットを示します。)

17
roaima

一般的に、ddはいくつかの代替案を優先して回避できます。代わりにGNU ddrescueを使用する理由はいくつかあります。Ubuntuでは、次のコマンドでインストールできます。

Sudo apt-get install gddrescue

単純なddrescueを使用します。パッケージ名とは異なり、実行可能ファイルしないの頭文字はgです。

使い方は次のように簡単です:

ddrescue inputFile outputFile logFile

ログファイル(任意の名前)を使用すると、前の作業をやり直すことなく、一時停止/停止して再起動できます。これは、大規模なクローンやディスクのリカバリを行うときに役立ちます。デフォルトでは、進行状況、現在のコピー速度、平均コピー速度、見つかった不良ブロックの数が表示されます。

それはブロックサイズに適切なデフォルトを使用するため、少なくとも私の経験では、コピー速度は常にデバイスが処理できる速度と同じです(私は、何百ものドライブをすべてのサイズとタイプで複製しました)。

多くの場合、障害が発生し始めたドライブには、速度の問題、平均速度の低下、突然の長い休止(不良セクター)、または完全なリセット(重大な表面エラー)などの速度の問題があります。 ddrescueは、ドライブがそれ自体をリセットしている場合でも、上記すべてを識別し、クローンを再起動するのに役立ちます(ログファイルを指定した場合)。

7
technicalbloke

とてもいい質問です。 rawインターフェースは一部のunixシステム(tru64、hpux、solaris)に実装されていますが、linuxには実装されていません。 unix I/Oがスキップされるため、Rawインターフェイスは転送を高速化します。ブロックインターフェイス(/dev/dskまたは/dev/disk)は、UNIX I/Oシステムを使用しているため、速度が遅くなります。 dd(gnu dd can)を高速化するには、ハードウェアに応じてbs=30Mまたはbs=20Mを使用します。簡単に言えば、少なくとも私が知る限り、それは実装されていません。カーネルバージョン2.2の昔からLinuxを使用しており、UNIXでrdskを使用したことはありません。

6
elbarna