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
블록 장치에 파일을 쓸 때 dd
with 를 사용하세요 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 디스크 관리자입니다.