I have 200 GB free disk space, 16 GB of RAM (of which ~1 GB is occupied by the desktop and kernel) and 6 GB of swap.
I have a 240 GB external SSD, with 70 GB used1 and the rest free, which I need to back up to my disk.
Normally, I would dd if=/dev/sdb of=Desktop/disk.img
the disk first, and then compress it, but making the image first is not an option since doing so would require far more disk space than I have, even though the compression step will result in the free space being squashed so the final archive can easily fit on my disk.
dd
writes to STDOUT by default, and gzip
can read from STDIN, so in theory I can write dd if=/dev/sdb | gzip -9 -
, but gzip
takes significantly longer to read bytes than dd
can produce them.
From man pipe
:
Data written to the write end of the pipe is buffered by the kernel until it is read from the read end of the pipe.
I visualise a |
as being like a real pipe -- one application shoving data in and the other taking data out of the pipe's queue as quickly as possible.
What when the program on the left side writes more data more quickly than the other side of the pipe can hope to process it? Will it cause extreme memory or swap usage, or will the kernel try to create a FIFO on disk, thereby filling up the disk? Or will it just fail with SIGPIPE Broken pipe
if the buffer is too large?
Basically, this boils down to two questions:
- What are the implications and outcomes of shoving more data into a pipe than is read at a time?
- What's the reliable way to compress a datastream to disk without putting the entire uncompressed datastream on the disk?
Note 1: I cannot just copy exactly the first 70 used GB and expect to get a working system or filesystem, because of fragmentation and other things which will require the full contents to be intact.
lzop
instead ofgzip
; it compresses much faster with only a slighly lower compression ratio. I find it ideal for disk images where compression speed can be a real bottleneck.