Linuxでddの進行が無意味になるのを防ぐ方法は?

Linuxでddの進行が無意味になるのを防ぐ方法は?

LinuxでISOをコピーするコマンドを実行すると、dd長時間(数分)開いている進行状況の印刷が表示されます。そして最後にもう一つあります。

問題は、非常に大きなキャッシュが使用され、dd出力が歪んでいるようです。

sudo dd bs=4M if=my.iso of=/dev/sdc status=progress

出力(最初の行が長い間表示されます)

1535115264 bytes (1.5 GB, 1.4 GiB) copied, 1.00065 s, 1.5 GB/s
403+1 records in
403+1 records out
1692844032 bytes (1.7 GB, 1.6 GiB) copied, 561.902 s, 3.0 MB/s

進行状況出力が意味を持つように、このようなことが発生しないようにする方法はありますか?

答え1

dd最初の行を見ると、1秒間に1.5GBを読み書きすることがわかります。 SSDでさえそれほど速く書くことはできません。

/dev/sdcブロックデバイスはそれを許可しますが(再書き込み)、それをディスクに送信するのではなくバッファリングし、ディスクが許容できる速度でディスクに書き込みを開始します。約3MiB/s。

システムはこのようにデータを無期限にバッファリングすることはできず、コミットされていないデータに保持するのに十分なデータしか許可できません。汚い状態。したがって、一定時間が経過すると(あなたの場合は1.5 GB以上を書き、2秒未満が経過した後(進行線が毎秒書き込まれるため))、データがディスクにフラッシュされるまでシステムコールがブロックされますddwrite()進行メッセージを書き込めません)。時間が経過すると、dd欠落している数メガバイトが追加で送信される可能性があり、これは1秒以内に発生するため、追加の進行状況ラインのみを取得できます。

他の動作を表示するには、書き込みを同期的に強制できます。つまり、データがディスクにコミットされない場合は返されません。たとえば、oflag=sync oroflag=dsyncまたはを使用しますoflag=direct(推奨されませんが)。

答え2

ブロックデバイスにファイルを書き込むときにddwithを使用してくださいoflag=direct。これは書き込みにO_DIRECTを使用するため、RAMを書き込みストレージキャッシュとして使用しません。良好なパフォーマンスを得るには、oflag=direct通常、より大きなブロックサイズが必要です。

これにより、自分で作業を行う奇妙なデバイスがない限り、不可能なほど速い進行を避けることができます。非常に大きなRAMキャッシュを持っています。

多くのデバイスには少量のキャッシュがあります。この場合、oflag=direct現実的なスピード改善。これはもっと意味がありますが、教えてくれません。すべてあなたは知る必要があります:-)。最後の書き込みがdd完了しても完了は保証されません。このオプションを使用すると、すべての書き込みが完了したことを確認し、書き込みエラーがあるかどうかを確認できますconv=fsync。キャッシュがフラッシュされたことを確認するために、最後にfsync()を呼び出します。例は次のとおりです。

dd if=my.iso of=/dev/sdc oflag=direct bs=4M status=progress conv=fsync

後でこのコマンドを実行し、それを覚えていないことを理解している人もいsyncますconv=fsync。これは良くありません。 sync書き込みのいずれかが失敗した場合は報告されません。

デバイスに非常に大きなRAMキャッシュがある場合は使用する必要がありますが、一般的にこれがパフォーマンスに悪影響を及ぼす可能性がありますoflag=direct,syncoflag=syncキャッシュフラッシュの頻度を減らすために、ブロックサイズをさらに増やすこともできます。同期IOを実行し、複数のハードウェアブロックを同時に読み取る場合は、優れたパフォーマンスを維持するためにデュアルバッファリングを使用できます。つまり、dd下のリンクの2番目のコマンドを使用することをお勧めします。

場合によっては、他のプログラムからパイプが必要になることがあります(たとえばgunzip、良いパフォーマンスはiflag=fullblock他のコマンドによって異なり、それを介してddパイプされます)。ここに答えの完全な例があります。ddパイプラインのgunzipが遅くなるのはなぜですか?

答え3

出力フラグをoflag=nocache,sync使用すると、システムキャッシュを完全に埋め、最後に書き込むのではなく、コンテンツを一定の速度と一定のバッファサイズでドライブに書き込むことができます。

dd if=/path/to/source.iso of=/path/to/usb-drive bs=4M status=progress oflag=nocache,sync

警告する:小さいブロックサイズを使用しないでください。これにより、パフォーマンスが低下し、SSDの状態が悪化する可能性が高くなります。デフォルトは512非常に低いです。その価値はbs=4M合理的でなければなりません。

デモ- 次のコマンドを使用してテストします。

# run in background in another terminal window to monitor write cache
while true; do cat /proc/meminfo | grep Dirty; sleep 0.1s; done;

# run without flags (also, needs a manual sync to flush caches in my case)
dd if=/dev/random of=tmp.$(date '+%Y%m%d-%H%M%S') bs=1M count=128 status=progress
sync

# run with oflag=nocache,sync
dd if=/dev/random of=tmp.$(date '+%Y%m%d-%H%M%S') bs=1M count=128 status=progress oflag=nocache,sync

答え4

どのLinuxを使用していますか? Debianベース(Ubuntu、Mint、Debianなど)の場合は、Disksというプログラムを使用してください。 DDと同じことを行い、一貫した状態を提供する組み込みGUIディスクマネージャです。

関連情報