Szybko utwórz duży plik w systemie Linux

438

Jak mogę szybko utworzyć duży plik w systemie Linux ( Red Hat Linux )?

dd wykona zadanie, ale czytanie /dev/zeroi zapisywanie na dysku może zająć dużo czasu, gdy potrzebujesz pliku o wielkości kilkuset GB do testowania ... Jeśli musisz to powtarzać, czas naprawdę się sumuje.

Nie dbam o zawartość pliku, chcę tylko, aby został on szybko utworzony. Jak można to zrobić?

Użycie rzadkiego pliku nie zadziała w tym przypadku. Potrzebuję pliku do przydzielenia miejsca na dysku.

DrStalker
źródło
1
Ext4 ma znacznie lepszą wydajność alokacji plików, ponieważ można jednocześnie przydzielić całe bloki do 100 MB.
martinus
5
Nawiasem mówiąc, polecenie „obcięcie” tworzy rzadki plik. Np. Patrz en.wikipedia.org/wiki/Sparse_file
Jason Drew
2
Ludzie wydają się rażąco ignorować „rzadki plik nie będzie z tym działał”, a ich obcięcie i dd szuka poniżej.
hpavc
1
Powinieneś był zdefiniować, co rozumiesz przez „testowanie”. Testujesz szybkość zapisu na dysku twardym? Testujesz, co dfzgłosi? Testowanie aplikacji, która robi coś szczególnego. Odpowiedź zależy od tego, co chcesz przetestować. W każdym razie jestem trochę spóźniony - teraz widzę, że
minęły
1
Na wypadek, gdybyś szukał sposobu na symulację pełnej partycji, tak jak ja, nie szukaj dalej niż / dev / full
Julian

Odpowiedzi:

509

ddz innych odpowiedzi jest dobrym rozwiązaniem, ale jest powolne w tym celu. W Linuksie (i innych systemach POSIX) mamy fallocate, która wykorzystuje żądaną przestrzeń bez konieczności pisania do niej, działa z większością nowoczesnych systemów plików na dyskach, bardzo szybko:

Na przykład:

fallocate -l 10G gentoo_root.img
Franta
źródło
5
Czy to możliwe, że dd już tego używa wewnętrznie? Jeśli zrobię 'dd if = / dev / zero of = zeroofile bs = 1G count = 1' na jądrze 3.0.0, zapis kończy się w 2 sekundy, z szybkością zapisu ponad 500 megabajtów na sekundę. Jest to oczywiście niemożliwe na 2,5
calowym
21
fallocatejest dokładnie tym, czego szukałem.
AB
7
Ta funkcja ( fallocate) również nie będzie działać w systemie plików Linux ZFS - github.com/zfsonlinux/zfs/issues/326
Joe,
5
fallocate nie jest również obsługiwany przez ext3. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie
3
W Debianie GNU / Linux fallocatejest częścią util-linuxpakietu. To narzędzie zostało napisane przez Karela Zaka z RedHat, a kod źródłowy można znaleźć tutaj: kernel.org/pub/linux/utils/util-linux
Franta
295

To częste pytanie - szczególnie w dzisiejszym środowisku środowisk wirtualnych. Niestety odpowiedź nie jest tak prosta, jak można by przypuszczać.

dd jest oczywistym pierwszym wyborem, ale dd jest zasadniczo kopią, która zmusza cię do zapisania każdego bloku danych (w ten sposób inicjując zawartość pliku) ... I ta inicjalizacja zajmuje tyle czasu we / wy. (Chcesz, aby trwało to jeszcze dłużej? Użyj / dev / random zamiast / dev / zero ! Wtedy użyjesz procesora, a także czasu I / O!) Ostatecznie jednak dd jest złym wyborem (choć zasadniczo domyślnie używane przez GUI maszyn wirtualnych „utwórz”). Na przykład:

dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G

obcięcie to kolejny wybór - i prawdopodobnie jest najszybszy ... Ale to dlatego, że tworzy „rzadki plik”. Zasadniczo rzadki plik to sekcja dysku, która ma wiele takich samych danych, a podstawowy system plików „oszukuje”, nie przechowując wszystkich danych, a jedynie „udając”, że wszystko tam jest. Tak więc, gdy używasz skracania, aby utworzyć dysk o pojemności 20 GB dla maszyny wirtualnej, system plików tak naprawdę nie przydziela 20 GB, ale oszukuje i mówi, że jest tam 20 GB zer, mimo że na dysku jest tylko jedna ścieżka może faktycznie (naprawdę) być w użyciu. Na przykład:

 truncate -s 10G gentoo_root.img

fallocate jest ostatecznym - i najlepszym - wyborem do użycia z alokacją dysku VM, ponieważ zasadniczo „rezerwuje” (lub „przydziela” całą przestrzeń, której szukasz, ale nie zawraca sobie głowy pisaniem czegokolwiek. kiedy używasz fallocate do utworzenia 20 GB miejsca na dysku wirtualnym, tak naprawdę dostajesz 20 GB pliku (nie jest to „rzadki plik” i nie będziesz się martwić, aby coś do niego zapisać - co oznacza, że ​​praktycznie wszystko może być w tam - trochę jak nowy dysk!) Np .:

fallocate -l 10G gentoo_root.img
Dan McAllister
źródło
4
+1 truncatedziała w JFS; fallocate, nie tak bardzo. Jeden punkt: nie można podać liczby dziesiętnej w liczbach, musiałem to określić 1536G, a nie 1.5T.
Calrion
1
Według mojej fallocatestronie człowieka, to jest obsługiwane tylko na btrfs, ext4, ocfs2oraz xfssystemów plików
Nathan S. Watson-Haigh
Uwaga swaponniestety nie działa na wstępnie przydzielonych zakresach, ostatnio sprawdziłem. Na liście mailingowej XFS pojawiła się dyskusja na temat opcji fallocate, która zamiast tego ujawnia stare dane z wolnego miejsca i nie ma zakresu oznaczonego jako wstępnie przydzielony, więc swapon będzie działać. Ale nie sądzę, żeby cokolwiek zostało zrobione.
Peter Cordes,
1
Do Twojej wiadomości, próba odczytania zbyt dużej ilości danych /dev/randommoże skończyć się przypadkowymi danymi i „Gdy pula entropii jest pusta, odczyty z / dev / random będą blokować do momentu zebrania dodatkowego hałasu otoczenia”, więc może to potrwać bardzo, bardzo długi czas
Xen2050
154

Linux i wszystkie systemy plików

xfs_mkfile 10240m 10Gigfile

Linux i niektóre systemy plików (ext4, xfs, btrfs i ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS i prawdopodobnie inne UNIXy

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

Wyjaśnienie

Wypróbuj mkfile <size>mój plik jako alternatywę dla dd. Z -nopcją zapisywany jest rozmiar, ale bloki dyskowe nie są przydzielane, dopóki dane nie zostaną do nich zapisane. Bez tej -nopcji miejsce jest wypełnione zerami, co oznacza zapis na dysk, co oznacza poświęcenie czasu.

mkfile pochodzi z SunOS i nie jest dostępny wszędzie. Większość systemów Linux xfs_mkfiledziała dokładnie tak samo, a nie tylko na systemach plików XFS, pomimo nazwy. Jest zawarty w xfsprogs (dla Debian / Ubuntu) lub podobnych nazwanych pakietach.

Większość systemów Linux również ma fallocatetę funkcję, która działa tylko na niektórych systemach plików (takich jak btrfs, ext4, ocfs2 i xfs), ale jest najszybsza, ponieważ przydziela całą przestrzeń plików (tworzy pliki nie dziurawe), ale nie inicjuje żadnych z tego.

CMS
źródło
5
Gdzie jest ten plik mk, o którym mówisz, nieznajomy? Nie ma go w domyślnej instalacji RHEL.
paxdiablo
2
To narzędzie solaris. jeśli szukasz gk mkfile, znajdziesz kilka przykładów kodu źródłowego.
Martin Beckett,
5
Działa jako urok w OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose
2
xfs_mkfilejest zawarty w xfsprogs na Ubuntu i działa jak urok na moim ext3 fs. :)
Greg Dubicki,
97
truncate -s 10M output.file

natychmiast utworzy plik o rozmiarze 10 M (M oznacza 1024 * 1024 bajtów, MB oznacza 1000 * 1000 - to samo co K, KB, G, GB ...)

EDYCJA: jak wielu zauważyło, nie spowoduje to fizycznego przydzielenia pliku na twoim urządzeniu. Dzięki temu możesz faktycznie utworzyć dowolny duży plik, niezależnie od dostępnego miejsca na urządzeniu, ponieważ tworzy on plik „rzadki”.

Robiąc to, będziesz odkładał fizyczny przydział do momentu uzyskania dostępu do pliku. Jeśli mapujesz ten plik do pamięci, możesz nie mieć oczekiwanej wydajności.

Ale nadal jest to przydatne polecenie, aby wiedzieć

kiv
źródło
1
Próbowałem tego, ale nie wpływa to na dostępne miejsce na dysku. Musi, ponieważ jest to rzadki plik, jak opisano wcześniej.
Gringo Suave,
7
To nie powinna być najlepsza odpowiedź, ponieważ nie rozwiązuje problemu, fallocateodpowiedź poniżej.
Gringo Suave,
4
@GringoSuave, ale nadal jest to przydatne dla niektórych osób, które mogą mieć podobny, ale nieco inny problem.
AJMansfield,
@GringoSuave: Wydaje się, że tworzy duży plik zgodnie z żądaniem, dlaczego to nie rozwiązuje problemu? Istnieją również uwagi pod fałszywą odpowiedzią, że w większości przypadków nawet nie działa.
Pavel Šimerda
1
Po co sugerować tworzenie rzadkich plików, gdy powiedział, że to nie zadziała?
hpavc
44

Gdzie seek jest rozmiarem pliku, który chcesz w bajtach - 1.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
Zoredache
źródło
6
Podoba mi się to podejście, ale komentator z jakiegoś powodu nie chce rzadkiego pliku. :(
ephemient
3
dd if = / dev / zero of = 1 GB file bs = 1000 count = 1000000
Damien
7
dd if = / dev / zero of = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret
1
W przypadku plików rzadkich truncatewydaje się być znacznie lepsza.
Pavel Šimerda
36

Przykłady, w których seek jest rozmiarem pliku, który chcesz w bajtach

#kilobytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200K

#megabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200M

#gigabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200G

#terabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200T


Z strony podręcznika dd:

BLOKI i BYTES mogą być poprzedzone następującymi multiplikatywnymi sufiksami: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * 1000, G = 1024 * 1024 * 1024 itd. Dla T, P, E, Z, Y.

Sepero
źródło
Wygląda to znacznie lepiej niż w trybie n-1 , więc w zasadzie jest to odpowiednik truncate.
Pavel Šimerda
19

Aby utworzyć plik 1 GB:

dd if=/dev/zero of=filename bs=1G count=1
max
źródło
7
Uważam, że liczba musi wynosić 1. (testowane na centos)
SvennD
dd if=/dev/zero of=filename bs=20G count=1utworzy tylko plik 2 GB! nie 20 GB.
Maulik Gangani,
18

Nie wiem dużo o Linuksie, ale oto kod C, który napisałem, aby sfałszować ogromne pliki w DC Share wiele lat temu.

#include < stdio.h >
#include < stdlib.h >

int main() {
    int i;
    FILE *fp;

    fp=fopen("bigfakefile.txt","w");

    for(i=0;i<(1024*1024);i++) {
        fseek(fp,(1024*1024),SEEK_CUR);
        fprintf(fp,"C");
    }
}
Humungous Hippo
źródło
w C. muszą być lepsze podejścia. Musisz także zamknąć plik. Iteracja do miliona piszących po 1 znaku na raz ...
ACV
10

Możesz także użyć polecenia „tak”. Składnia jest dość prosta:

#yes >> myfile

Naciśnij „Ctrl + C”, aby zatrzymać to, w przeciwnym razie zajmie całą dostępną przestrzeń.

Aby wyczyścić ten plik, uruchom:

#>myfile

wyczyści ten plik.

Jog
źródło
7

Nie sądzę, że będziesz dużo szybszy niż dd. Wąskim gardłem jest dysk; zapisanie setek GB danych zajmie to dużo czasu, bez względu na to, jak to zrobisz.

Ale oto możliwość, która może zadziałać dla twojej aplikacji. Jeśli nie zależy ci na zawartości pliku, co powiesz na utworzenie pliku „wirtualnego”, którego zawartość stanowi dynamiczne wyjście programu? Zamiast open () ing pliku, użyj popen (), aby otworzyć potok do zewnętrznego programu. Zewnętrzny program generuje dane, gdy tylko są potrzebne. Po otwarciu potoku działa on tak jak zwykły plik, ponieważ program, który otworzył potok, może fseek (), przewinąć do tyłu () itp. Będziesz musiał użyć pclose () zamiast close (), gdy jesteś zrobione z rurą.

Jeśli twoja aplikacja potrzebuje pliku o określonym rozmiarze, to do zewnętrznego programu będzie należeć śledzenie, gdzie jest „plik”, i wysłanie eof po osiągnięciu „końca”.

Barry Brown
źródło
4

Jedno podejście: jeśli możesz zagwarantować, że niepowiązane aplikacje nie będą używać plików w sposób powodujący konflikt, po prostu utwórz pulę plików o różnych rozmiarach w określonym katalogu, a następnie w razie potrzeby utwórz łącza do nich.

Na przykład masz pulę plików o nazwie:

  • / home / bigfiles / 512M-A
  • / home / bigfiles / 512M-B
  • / home / bigfiles / 1024M-A
  • / home / bigfiles / 1024M-B

Następnie, jeśli masz aplikację, która potrzebuje pliku 1G o nazwie / home / oracle / logfile, uruchom „ ln /home/bigfiles/1024M-A /home/oracle/logfile”.

Jeśli znajduje się w osobnym systemie plików, będziesz musiał użyć dowiązania symbolicznego.

Pliki A / B / etc mogą być użyte, aby zapewnić, że nie będzie konfliktu między niepowiązanymi aplikacjami.

Operacja łącza przebiega tak szybko, jak to tylko możliwe.

paxdiablo
źródło
Możesz mieć mały basen lub duży basen, to twój wybór. I tak będziesz potrzebował przynajmniej jednego pliku, ponieważ o to pytał pytający. Jeśli twoja pula składa się z jednego pliku, nic nie tracisz. Jeśli masz mnóstwo dysków (i powinieneś, biorąc pod uwagę jego niską cenę), nie ma problemu.
paxdiablo
3

Plik mk GPL jest tylko opakowaniem skryptu (ba) sh wokół dd; Plik mk BSD po prostu ustawia bufor na niezerowy i zapisuje go wielokrotnie. Nie spodziewałbym się, że ten pierwszy wykona dd. Ten ostatni może nieco przewyższyć dd, jeśli = / dev / zero, ponieważ pomija odczyty, ale wszystko, co robi znacznie lepsze, to prawdopodobnie tylko tworzenie rzadkiego pliku.

W przypadku braku wywołania systemowego, które faktycznie przydziela miejsce dla pliku bez zapisywania danych (a Linux i BSD tego brakuje, prawdopodobnie również Solaris), możesz uzyskać niewielką poprawę wydajności, używając ftrunc (2) / truncate (1) do rozszerzenia pliku do żądanego rozmiaru, zamapuj plik w pamięci, a następnie zapisz niezerowe dane w pierwszych bajtach każdego bloku dysku (użyj fgetconf, aby znaleźć rozmiar bloku dysku).

Alex Dupuy
źródło
4
BSD i Linux faktycznie się zmieniły (edytuj: jest teraz POSIX i szeroko dostępne).
Tobu,
3

Bezwstydna wtyczka: OTFFS zapewnia system plików, który zapewnia dowolnie duże (cóż, prawie. Exabytes to obecny limit) pliki generowanej zawartości. Jest to tylko Linux, zwykły C i wczesna wersja alfa.

Zobacz https://github.com/s5k6/otffs .

Stefan
źródło
3

To najszybsze, co mogę zrobić (co nie jest szybkie) z następującymi ograniczeniami:

  • Celem dużego pliku jest wypełnienie dysku, więc nie można go skompresować.
  • Korzystanie z systemu plików ext3. ( fallocateniedostępne)

To jest sedno tego ...

// include stdlib.h, stdio.h, and stdint.h
int32_t buf[256]; // Block size.
for (int i = 0; i < 256; ++i)
{
    buf[i] = rand(); // random to be non-compressible.
}
FILE* file = fopen("/file/on/your/system", "wb");
int blocksToWrite = 1024 * 1024; // 1 GB
for (int i = 0; i < blocksToWrite; ++i)
{
   fwrite(buf, sizeof(int32_t), 256, file);
}

W naszym przypadku dotyczy to wbudowanego systemu linux i działa to wystarczająco dobrze, ale wolałoby coś szybszego.

Do waszej dyspozycji polecenie dd if=/dev/urandom of=outputfile bs=1024 count = XXbyło tak wolne, że było bezużyteczne.

użytkownik79878
źródło