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.5GB 이상 쓰고 2초 미만이 경과한 후(진행 라인이 매초 기록되기 때문에)) 데이터가 디스크에 플러시될 때까지 시스템 호출이 차단됩니다 dd. write()진행 메시지를 쓸 수 없습니다). 시간이 지나면 dd누락된 몇 메가바이트가 추가로 전송될 수 있으며 이는 1초 이내에 발생하므로 추가 진행률 라인만 얻을 수 있습니다.

다른 동작을 보려면 쓰기를 동기식으로 강제할 수 있습니다. 즉, 데이터가 디스크에 커밋되지 않으면 반환되지 않습니다. 예를 들어 oflag=sync or oflag=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,sync봅니다 . oflag=sync캐시 플러시 빈도를 줄이기 위해 블록 크기를 더 늘릴 수도 있습니다. 동기식 IO를 수행하고 여러 하드웨어 블록을 동시에 읽는 경우 우수한 성능을 유지하기 위해 이중 버퍼링을 사용할 수 있습니다. 즉, dd아래 링크의 두 번째 명령을 사용하는 것이 좋습니다.

때로는 다른 프로그램에서 파이프를 원할 수도 있습니다(예 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

어떤 리눅스를 사용하고 있나요? 데비안 기반(Ubuntu, Mint, Debian 등)이라면 Disks라는 프로그램을 사용합니다. DD와 동일한 작업을 수행하고 일관된 상태를 제공하는 내장 GUI 디스크 관리자입니다.

관련 정보