Mam 200 GB wolnego miejsca na dysku, 16 GB pamięci RAM (z czego ~ 1 GB zajmuje komputer i jądro) oraz 6 GB wymiany.
Mam zewnętrzny dysk SSD o pojemności 240 GB, z 70 GB wykorzystałem 1, a resztę bezpłatnie, i muszę wykonać kopię zapasową na dysku.
Zwykle dd if=/dev/sdb of=Desktop/disk.img
najpierw najpierw dysk, a następnie kompresję, ale najpierw nie jest możliwe zrobienie obrazu, ponieważ wymagałoby to znacznie więcej miejsca na dysku niż ja, nawet jeśli krok kompresji spowoduje, że wolne miejsce zostanie zmiażdżone, więc końcowe archiwum można łatwo zmieścić na moim dysku.
dd
domyślnie zapisuje do STDOUT i gzip
może czytać ze STDIN, więc teoretycznie mogę pisać dd if=/dev/sdb | gzip -9 -
, ale gzip
czytanie bajtów zajmuje znacznie więcej czasu niż dd
ich wytworzenie.
Od man pipe
:
Dane zapisywane na końcu zapisu potoku są buforowane przez jądro, dopóki nie zostaną odczytane z końca odczytu potoku.
Wizualizuję, |
że jest jak prawdziwa potok - jedna aplikacja wpycha dane, a druga pobiera dane z kolejki potoku tak szybko, jak to możliwe.
Co się stanie, gdy program po lewej stronie będzie zapisywał więcej danych szybciej niż druga strona potoku może mieć nadzieję na ich przetworzenie? Czy spowoduje to ekstremalne użycie pamięci lub zamiany, czy też jądro spróbuje utworzyć FIFO na dysku, wypełniając w ten sposób dysk? A może po prostu zawiedzie, SIGPIPE Broken pipe
jeśli bufor jest zbyt duży?
Zasadniczo sprowadza się to do dwóch pytań:
- Jakie są implikacje i wyniki wrzucania większej ilości danych do potoku niż odczytywane jednocześnie?
- Jaki jest niezawodny sposób kompresji strumienia danych na dysk bez umieszczania całego nieskompresowanego strumienia danych na dysku?
Uwaga 1: Nie mogę po prostu skopiować dokładnie pierwszych 70 używanych GB i oczekiwać, że dostanę działający system lub system plików, z powodu fragmentacji i innych rzeczy, które będą wymagały nienaruszonej pełnej zawartości.
źródło
lzop
zamiastgzip
; kompresuje się znacznie szybciej przy jedynie nieco niższym stopniu kompresji. Uważam, że idealnie nadaje się do obrazów dysków, na których szybkość kompresji może być prawdziwym wąskim gardłem.Odpowiedzi:
Technicznie nie potrzebujesz nawet
dd
:Jeśli używasz
dd
, powinieneś zawsze korzystać z większego niż domyślny rozmiaru bloków, takiego jakdd bs=1M
lub cierpieć z powodu piekła systemowego (dd
domyślny rozmiar bloku to 512 bajtów, ponieważ jest toread()
s iwrite()
s4096
wywołań naMiB
, zbyt duży narzut).gzip -9
używa dużo DUŻO procesora, a do tego niewiele. Jeśligzip
spowalnia Cię, obniż poziom kompresji lub użyj innej (szybszej) metody kompresji.Jeśli tworzysz kopie zapasowe oparte na plikach zamiast
dd
obrazów, możesz mieć logikę, która decyduje, czy w ogóle kompresować, czy nie (nie ma sensu robić tego dla różnych typów plików).dar
(tar
alternatywny`) to jeden przykład, który ma takie opcje.Jeśli ilość wolnego miejsca jest równa zero (bo to SSD, które niezawodnie zwraca zero po TRIM i pobiegł
fstrim
i spadł bufory) można również korzystaćdd
zconv=sparse
flagą na tworzenie nieskompresowanego, Pętla scianie, rzadki obraz zastosowania zerowej przestrzeni dyskowej dla obszarów zerowych . Wymaga, aby plik obrazu był wspierany przez system plików, który obsługuje rzadkie pliki.Alternatywnie dla niektórych systemów plików istnieją programy zdolne do obrazowania tylko używanych obszarów.
źródło
dd bs=1M
” - Możesz, ale nie oczekuj zbyt wiele. Na moim komputerzedd
wystarczy około 2 GB / s przy 512-bajtowych blokach. To nie będzie wąskie gardło;gzip
będzie.dd
2 GB / s z 512-bajtowymi blokami, byłbym zaskoczony, gdyby nie zmaksymalizował jednego rdzenia procesora w 100%. Teraz, jeśli twoje pudełko jest quadcore, które i tak pozostaje bezczynne, możesz nie zauważyć różnicy. Jednak wszyscy inni to robią.dd
pojawia się wzmianka o wielkości bloków, ludzie przychodzą do gry.gzip
intensywność procesorów również była częścią mojej odpowiedzi, dobrze? I przepraszam, nie zgadzam się z „nieistotnym”. Może dodać tylko 1-2 sekundy na koncertgzip -9
(ale to wciąż trwa kilka minut podczas przetwarzania setek koncertów), ale biorąc pod uwagę twoją radę,lzop -1
to 1s na koncert vs. 4s na koncert. Testowany na ziemniaku (vserver z jednym rdzeniem). Dodanie rozsądnego rozmiaru blokudd
nic nie kosztuje i ma zero wad. Nie chwytaj się. Po prostu to zrób. ymmvdd
odczytuje i zapisuje dane jeden blok naraz, i zawsze ma tylko jeden blok zaległy. Więcpokazuje, że
dd
zużywa około 1 MB pamięci. Możesz bawić się wielkością bloku i upuszczaćvalgrind
, aby zobaczyć wpływ nadd
szybkość.Kiedy wpadasz
gzip
,dd
po prostu zwalnia, aby dopasowaćgzip
prędkość. Jej użycie pamięci nie zwiększa, ani nie powodują jądro do przechowywania buforów na dysk (jądro nie wie, jak to zrobić, z wyjątkiem poprzez zamiany). Zepsuta rura zdarza się tylko wtedy, gdy umiera jeden z końców rury; zobaczsignal(7)
iwrite(2)
po szczegóły.A zatem
to bezpieczny sposób na robienie tego, czego szukasz.
Podczas pipowania proces zapisu zostaje zablokowany przez jądro, jeśli proces odczytu nie nadąża. Możesz to zobaczyć, uruchamiając
Zobaczysz, że
dd
odczytuje 1 MB, a następnie wydaje,write()
który siedzi tam i czeka przez minutę podczassleep
biegu. W ten sposób równoważą się obie strony potoku: bloki jądra zapisują, jeśli proces zapisu jest zbyt szybki, a blokują odczyt, jeśli proces odczytu jest zbyt szybki.źródło
dd
wie, aby spowolnić, aby dopasowaćgzip
prędkość? Jest to automatyczne, podobnie jak jądro, czy oblicza na podstawie metadanych dotyczących deskryptora pliku wyjściowego?dd
wywołania wwrite()
celu umieszczenia danych w potoku.write()
faktycznie przekazuje kontrolę do jądra, aby mógł manipulować pamięcią potoku. Jeśli jądro zobaczy, że potok jest pełny, zaczeka („blok”), aż potok będzie miał wystarczająco dużo miejsca. Tylko wtedywrite()
połączenie zakończy się i przekaże kontrolę z powrotem dodd
, który następnie ponownie zapisze dane do potoku.Nie ma żadnych negatywnych konsekwencji poza wydajnością: potok ma bufor, który zwykle wynosi 64 KB, a następnie zapis do potoku będzie po prostu blokowany, dopóki nie
gzip
odczyta więcej danych.źródło
Odpowiadając na rzeczywiste pytanie, jak to działa: „co, jeśli program po lewej stronie zapisuje więcej danych szybciej niż druga strona potoku może liczyć na ich przetworzenie?”
To się nie zdarza. W rurze znajduje się dość mały bufor o ograniczonym rozmiarze; zobacz Jak duży jest bufor rurowy?
Po zapełnieniu bufora potoku program wysyłający blokuje się . Kiedy wykonuje polecenie zapisu, jądro nie zwróci kontroli do programu, dopóki dane nie zostaną zapisane w buforze. Daje to czas procesora programu czytającego na opróżnienie bufora.
źródło
Może potrzebujesz tylko plików, a następnie użyj tar. Możesz wypełnić zerami bloki, które nie zawierają niczego, czego chcesz, ktoś już o to zapytał. Wyczyść nieużywane miejsce zerami (ext3, ext4)
Następnie jest coś,
pigz
co jest zwykle szybsze niżgzip
.źródło