У меня есть 200 ГБ свободного дискового пространства, 16 ГБ ОЗУ (из которых ~ 1 ГБ занято рабочим столом и ядром) и 6 ГБ подкачки.
У меня есть внешний SSD на 240 ГБ, из которых 1 используется 70 ГБ, а остальное свободно, и мне нужно сделать резервную копию на моем диске.
Обычно я dd if=/dev/sdb of=Desktop/disk.img
сначала выполняю диск, а затем сжимаю его, но создание образа сначала не вариант, так как для этого потребуется гораздо больше места на диске, чем у меня, даже несмотря на то, что этап сжатия приведет к сжатию свободного пространства, поэтому Конечный архив легко помещается на моем диске.
dd
записывает в STDOUT по умолчанию и gzip
может читать из STDIN, поэтому теоретически я могу писать dd if=/dev/sdb | gzip -9 -
, но gzip
чтение байтов занимает значительно больше времени, чем dd
может их произвести.
От man pipe
:
Данные, записанные в конец записи канала, буферизуются ядром до тех пор, пока они не будут прочитаны из конца чтения канала.
Я представляю себя |
как настоящий канал - одно приложение помещает данные, а другое - как можно быстрее выводит данные из очереди канала.
Что, когда программа на левой стороне записывает больше данных быстрее, чем другая сторона канала, может рассчитывать на их обработку? Будет ли это вызывать чрезмерное использование памяти или подкачки, или ядро попытается создать FIFO на диске, заполнив тем самым диск? Или он просто потерпит неудачу, SIGPIPE Broken pipe
если буфер слишком велик?
По сути, это сводится к двум вопросам:
- Каковы последствия и результаты добавления большего количества данных в канал, чем считывается за раз?
- Какой надежный способ сжать поток данных на диск, не помещая весь несжатый поток данных на диск?
Примечание 1: я не могу просто скопировать точно первые 70 использованных ГБ и ожидать получить работающую систему или файловую систему из-за фрагментации и других вещей, которые потребуют целостности всего содержимого.
источник
lzop
вместоgzip
; он сжимается намного быстрее, с чуть более низкой степенью сжатия. Я нахожу это идеальным для образов дисков, где скорость сжатия может быть реальным узким местом.Ответы:
Технически вам даже не нужно
dd
:Если вы используете
dd
, вы всегда должны идти с большим, чем по умолчанию, размером блока, таким как адский вызов системного вызоваdd bs=1M
или страдать от него (поdd
умолчанию размер блока составляет 512 байт, так как этоread()
s иwrite()
s, то есть4096
syscalls perMiB
, слишком много накладных расходов).gzip -9
использует гораздо больше процессора с очень мало, чтобы показать это. Еслиgzip
это замедляет работу, снизьте уровень сжатия или используйте другой (более быстрый) метод сжатия.Если вы делаете резервные копии на основе файлов, а не
dd
изображений, у вас может быть логика, которая решает, сжимать ли вообще или нет (делать это бессмысленно для разных типов файлов).dar
(tar
альтернатива`) - один из примеров, у которого есть варианты сделать это.Если у вас свободное пространство ZERO (потому что это твердотельный накопитель, который надежно возвращает ноль после TRIM, и вы запустили
fstrim
и сбросили кэши), вы также можете использоватьdd
сconv=sparse
флагом, чтобы создать несжатый, монтируемый на петлю, разреженный образ, который использует нулевое дисковое пространство для нулевых областей. , Требует, чтобы файл образа был поддержан файловой системой, которая поддерживает разреженные файлы.В качестве альтернативы для некоторых файловых систем существуют программы, способные отображать только используемые области.
источник
dd bs=1M
», - можете, но не ожидайте слишком многого. На моем ПКdd
будет работать около 2 ГБ / с с 512-байтовыми блоками. Это не будет узким местом;gzip
будет.dd
2 ГБ / с с 512-байтовыми блоками, я был бы удивлен, если бы в этом процессе не использовалось 100% одного ядра процессора. Теперь, если ваша коробка - это четырехъядерный процессор, который все равно бездействует, вы можете не заметить разницы. Все остальные все еще делают, хотя.dd
когда упоминается размер блока, люди придираются.gzip
интенсивность работы процессора также была частью моего ответа, хорошо? И извините, я не согласен с "незначительным". Он может добавить только 1-2 с на концертgzip -9
(но это все равно составляет минуты при обработке сотен гигов), но прислушивайтесь к советуlzop -1
: 1 с на концерт против 4 с на концерт. Испытано на картофеле (одноядерный всервер). Добавление нормального размера блокаdd
ничего не стоит и имеет ноль недостатков. Не придирайся. Просто сделай это. ymmvdd
читает и записывает данные по одному блоку за раз, и у него только один ожидающий блок. Такпоказывает, что
dd
использует примерно 1 МБ памяти. Вы можете поиграть с размером блока и сброситьvalgrind
, чтобы увидеть влияние наdd
скорость.Когда вы переходите на канал
gzip
,dd
просто замедляетесь, чтобы соответствоватьgzip
скорости. Его использование памяти не увеличивается и не заставляет ядро хранить буферы на диске (ядро не знает, как это сделать, кроме как через swap). Разорванная труба случается только тогда, когда один из концов трубы умирает; смотритеsignal(7)
иwrite(2)
для деталей.таким образом
это безопасный способ сделать то, что вы после.
При передаче по трубопроводу процесс записи блокируется ядром, если процесс чтения не идет в ногу. Вы можете увидеть это, запустив
Вы увидите, что
dd
читает 1MB, а затем выдает,write()
который сидит в ожидании одной минуты, покаsleep
работает. Вот как уравновешиваются обе стороны канала: ядро блокирует запись, если процесс записи идет слишком быстро, и блокирует чтение, если процесс чтения слишком быстрый.источник
dd
известно, чтобы замедлиться, чтобы соответствоватьgzip
скорости? Он автоматический, как ядро, или он рассчитывает по метаданным о своем дескрипторе выходного файла?dd
призываетwrite()
положить данные в трубу.write()
фактически передает управление ядру, чтобы оно могло манипулировать памятью канала. Если ядро увидит, что канал заполнен, оно будет ждать («заблокировать»), пока каналу не будет достаточно места. Только после этогоwrite()
вызов завершится и вернет управление обратноdd
, после чего данные снова будут записаны в канал.Нет никаких отрицательных последствий, кроме производительности: канал имеет буфер, который обычно составляет 64 КБ, и после этого запись в канал просто блокируется, пока не будет
gzip
прочитано еще несколько данных.источник
Отвечая на реальный вопрос о том, как это работает: «что если программа на левой стороне записывает больше данных быстрее, чем другая сторона канала может рассчитывать на их обработку?»
Этого не происходит В канале имеется довольно маленький буфер ограниченного размера; Посмотрите, насколько большой буфер трубы?
Когда буфер канала заполнен, программа-отправитель блокируется . Когда он выполняет вызов записи, ядро не вернет управление программе, пока данные не будут записаны в буфер. Это дает процессору ЦП время, в течение которого необходимо очистить буфер.
источник
Может быть, вам нужны только файлы, затем используйте tar. Вы можете заполнить нулями блоки, которые не содержат ничего, что вы хотите, кто-то уже спрашивал об этом. Очистить неиспользуемое пространство с нулями (ext3, ext4)
Тогда есть,
pigz
что обычно быстрее, чемgzip
.источник