du podaje dwa różne wyniki dla tego samego pliku

23

Jestem absolwentem chemii obliczeniowej z dostępem do klastra Linux. Klaster składa się z bardzo dużego (25 TB) serwera plików, do którego podłączonych jest kilkadziesiąt węzłów obliczeniowych. Każdy węzeł obliczeniowy składa się z 8 do 24 rdzeni Intel Xeon. Każdy węzeł obliczeniowy zawiera także dysk lokalny o wielkości około 365 TB.

Ponieważ serwer plików jest rutynowo dostępny dla kilkunastu użytkowników w grupie badawczej, serwer plików jest używany głównie do długotrwałego przechowywania plików (jest on tworzony kopii zapasowej co noc, podczas gdy dyski lokalne węzłów obliczeniowych nigdy nie są tworzone). Dlatego administrator systemu polecił nam przeprowadzać symulacje na dyskach lokalnych - które mają szybsze operacje we / wy niż serwer plików - aby nie spowalniać serwera plików dla innych użytkowników.

Tak więc uruchamiam symulacje na lokalnych dyskach, a następnie, po ich zakończeniu, kopiuję pliki trajektorii - prowadzę symulacje dynamiki molekularnej - na serwer plików w celu przechowywania. Załóżmy, że mam plik o nazwie trajektorii traj.trrw katalogu na dysku lokalnym węzła, /home/myusername/mysimulation1/traj.trr. Do długotrwałego przechowywania, zawsze skopiować traj.trrdo katalogu na serwerze plików, ~/mysimulation1/traj.trrgdzie ~reprezentuje mój katalog na serwerze plików, /export/home/myusername. Po skopiowaniu go zwykle używam du -hdo sprawdzenia, czy /home/myusername/mysimulation1/traj.trrma ten sam rozmiar pliku co ~/mysimulation1/traj.trr. W ten sposób mogę przynajmniej mieć pewność, że transfer do serwera plików powiódł się. Na przykład:

cd /home/myusername/mysimulation1/
cp -v traj.trr ~/mysimulation1/
du /home/myusername/mysimulation1/traj.trr -h
du ~/mysimulation1/traj.trr -h

Jeśli dwa wywołania du -hdadzą ten sam rozmiar pliku, który można odczytać dla człowieka, to mogę być całkiem pewny, że przesyłanie / kopiowanie powiodło się. (Moje typowe traj.trrpliki mają rozmiar od około 15 do 20 GB, w zależności od dokładnej symulacji, którą uruchomiłem.) Jeśli uruchomię du(tj. Bez -hprzełącznika) na dwóch traj.trrplikach, ich rozmiary w bajtach są zwykle bardzo, bardzo podobne - - zwykle w ciągu zaledwie kilku bajtów. Używam tej ogólnej metody przez ostatnie półtora roku, bez żadnych problemów.

Jednak ostatnio napotkałem następujący problem: czasamidu -hzgłasza, że ​​rozmiar dwóchtraj.trrplików jest różny o kilka GB. Oto przykład:

cd /home/myusername/mysimulation1/            # this is the local disk
cp -v traj.trr ~/mysimulation1/
du traj.trr -h
cd ~/mysimulation1/                           # this is the fileserver
du traj.trr -h

Dane wyjściowe z obu wywołań du -hsą odpowiednio następujące:

20G     traj.trr
28G     traj.trr

Uważam, że ten pierwszy (tj. Na traj.trrdysku lokalnym /home/myusername/mysimulation1/) ma prawidłowy rozmiar pliku, ponieważ oczekuje się, że moje trajektorie symulacji będą miały około 15 do 20 GB każdy. Ale w jaki sposób plik na serwerze plików może być większy ? Widziałem, jak może być mniejszy, jeśli jakoś się cpnie powiedzie. Ale nie rozumiem, jak może być większy .

Otrzymuję podobne wyniki, gdy wykonuję te same polecenia, co powyżej, ale bez -hprzełącznika podanego do du:

20717480        traj.trr
28666688        traj.trr

Czy potrafisz wymyślić jakiś powód różnicy?

Jeśli przez jakiś nieoczekiwany przypadek dujakoś źle funkcjonuje, mogę się z tym pogodzić. Ale naprawdę muszę się upewnić, że kopia traj.trrna serwerze plików jest kompletna i identyczna z wersją źródłową na dysku lokalnym. Muszę usunąć plik lokalny, aby mieć wystarczającą ilość miejsca na dysku lokalnym, aby uruchomić nowe symulacje, ale nie mogę sobie pozwolić na traj.trruszkodzenie wersji serwera plików.

Format .trr (od GROMACS dynamiki molekularnej opakowaniu) to format binarny, a nie tekst. Dlatego nie jestem pewien, czy pliki mogą być wiarygodnie porównane przez program taki jak diff.

Andrzej
źródło
5
Spróbuj uruchomić md5sumlub sha1sumna plikach. Czy oni pasują?
cjm
2
@cjm Właśnie uruchomiłem md5sumdwa pliki. Dwie sumy kontrolne są zgodne. To chyba dwa pliki są takie same?
Andrew
3
Jakie rozmiary są zgłaszane ls -l? Polecenie duinformuje, ile miejsca na dysku zajmuje plik, a nie jak duży jest plik. Na rozmiar dysku może mieć wpływ system plików i jego strategie alokacji.
Casey
2
@casey ls -l -hmówi, że oba pliki mają 20 GB. Podobnie, ls -lmówi, że oba pliki mają 21214683940 bajtów. Sądzę więc, że pliki mają ten sam rozmiar, ale nie używają takiej samej ilości miejsca na dysku (zgodnie z du).
Andrew
2
@Andrew, biorąc pod uwagę, że rozmiary zgłaszane przez ls są takie same, a skróty są takie same, można stwierdzić, że pliki są takie same. Te narzędzia dają ci pewność, której potrzebujesz, i pokazują, że du nie jest narzędziem do zaspokojenia twoich potrzeb.
Casey

Odpowiedzi:

32

Naprawdę powinieneś użyć czegoś takiego jak md5sumlub, sha1sumaby sprawdzić integralność.

Jeśli naprawdę chcesz użyć rozmiaru użyj ls -llub du -b.

duNarzędzie normalnie pokazuje tylko użycie dysku pliku, czyli ile z systemu plików używanego przez nią. Ta wartość zależy całkowicie od systemu plików kopii zapasowej i innych czynników, takich jak pliki rzadkie.

Przykład:

$ truncate -s 512M foo
$ cat foo >bar
$ ls -l foo bar
-rw-r--r-- 1 michas users 536870912 23. Dez 00:06 bar
-rw-r--r-- 1 michas users 536870912 23. Dez 00:03 foo
$ du foo bar
0       foo
524288  bar
$ du -b foo bar
536870912       foo
536870912       bar

Mamy dwa pliki zawierające 512 MB zer. Pierwszy z nich jest przechowywany rzadko i nie zajmuje miejsca na dysku, a drugi zapisuje każdy bajt jawnie na dysku. - Ten sam plik, ale zupełnie inne użycie dysku.

Ta -bopcja może być dla Ciebie dobra:

   -b, --bytes
          equivalent to '--apparent-size --block-size=1'

   --apparent-size
          print apparent sizes, rather than disk usage; although the apparent
          size is  usually  smaller,  it  may  be  larger  due  to  holes  in
          ('sparse')  files, internal fragmentation, indirect blocks, and the
          like
michas
źródło
8

Jest to powszechny problem, gdy umieszczasz te same dane na 2 różnych dyskach twardych. Będziesz chciał uruchomić dukomendę z dodatkowym przełącznikiem, zakładając, że ma go - co powinno, biorąc pod uwagę, że są to węzły Linux.

Przełącznik?

   --apparent-size
          print  apparent  sizes,  rather  than  disk  usage;  although the 
          apparent size is usually smaller, it may be larger due to holes in
          ('sparse') files, internal fragmentation, indirect blocks, and the 
          like

Przykład

$ du -sh --apparent-size /home/sam/scsconfig.log ~/scsconfig.log 
93K /home/sam/scsconfig.log
93K /root/scsconfig.log

Powyższe systemy plików są dyskami lokalnymi ( /root), a drugi /home/samto udział NFS z mojego serwera NAS.

$ df -h . /home/sam
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                      222G  118G   92G  57% /
mulder:/export/raid1/home/sam
                      917G  566G  305G  65% /home/sam

Więc co tam?

To wprawia w zakłopotanie wiele osób, ale pamiętaj, że kiedy pliki są przechowywane na dysku, zajmują bloki miejsca, nawet jeśli wykorzystują tylko część tych bloków. Po uruchomieniu dubez --apparent-sizerozmiaru uzyskuje się rozmiar na podstawie ilości wykorzystanego miejsca na dysku, a nie faktycznego miejsca zajętego przez plik (i).

zamiast tego używasz sumy kontrolnej?

Jest to prawdopodobnie lepsza opcja, jeśli martwisz się porównaniem 2 drzew plików. Za pomocą tego polecenia można obliczyć sumę kontrolną dla wszystkich plików, a następnie obliczyć końcową sumę kontrolną sum kontrolnych. W tym przykładzie użyto, sha1sumale można równie łatwo użyć md5sumzamiast tego.

$ cd /some/dir
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum

Przykład

$ cd ~/dir1
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum
55e2672f8d6fccff6d83f0bffba1b67aeab87911  -

$ cd ~/dir2
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum
55e2672f8d6fccff6d83f0bffba1b67aeab87911  -

Widzimy więc, że 2 drzewa są identyczne.

(Uwaga: polecenie find wyświetli listę plików, które pojawiły się w systemie plików. Jeśli więc porównujesz dwa katalogi z innego systemu plików (np. Ext3 vs. APFS), musisz najpierw posortować pliki przed ostatecznym sha1sum. (Dodane przez Xianjun Dong)

slm
źródło
5

Krótka odpowiedź: nie testuj rozmiaru pliku, sprawdź status powrotu polecenia. Status zwrotu jest jedynym wiarygodnym wskaźnikiem powodzenia kopiowania (bez porównania dwóch bajtów bajt po bajcie, bezpośrednio lub pośrednio - co jest zbędne, jeśli kopiowanie się powiodło).

Sprawdzanie rozmiaru pliku nie jest bardzo użytecznym sposobem sprawdzania, czy kopiowanie się powiodło. W niektórych przypadkach może to być przydatny sprawdzian poczytalności, na przykład podczas pobierania pliku z sieci. Ale tutaj jest lepszy sposób.

Wszystkie polecenia uniksowe zwracają status wskazujący, czy się udało: 0 dla sukcesu, 1 lub więcej dla błędów. Więc sprawdź status wyjścia cp. cpnormalnie wydrukuje komunikat błędu, jeśli się nie powiedzie, wskazując, jaki jest błąd. W skrypcie status wyjścia ostatniego polecenia znajduje się w zmiennej magicznej $?.

cp -v traj.trr ~/mysimulation1/
if [ $? -ne 0 ]; then
  echo 1>&2 "cp failed due to the error above"
  exit 2
 fi

Zamiast sprawdzać, czy $?wynosi zero, możesz użyć operatorów logicznych.

cp -v traj.trr ~/mysimulation1/ || exit 2

Jeśli uruchamiasz skrypt i chcesz, aby skrypt przestał działać w przypadku niepowodzenia dowolnego polecenia, uruchom set -e. Jeśli dowolne polecenie zakończy się niepowodzeniem (tzn. Zwróci niezerowy status), skrypt natychmiast zakończy działanie z tym samym statusem co polecenie.

set -e
…
cp -v traj.trr ~/mysimulation1/

Powód, dla którego skopiowany plik był większy, musi być taki, że był to plik rzadki . Plik rzadki to surowa forma kompresji, w której bloki zawierające tylko bajty puste nie są przechowywane. Podczas kopiowania pliku cppolecenie odczytuje i zapisuje bajty zerowe, więc tam, gdzie w oryginale brakowało bloków, kopia zawiera bloki pełne bajtów zerowych. W systemie Linux cppolecenie próbuje wykryć rzadkie pliki, ale nie zawsze się to udaje; cp --sparse=alwaysczyni to trudniejszym kosztem bardzo niewielkiego wzrostu czasu procesora.

Mówiąc bardziej ogólnie, dumogą zwracać różne wyniki z powodu innych form kompresji. Skompresowane systemy plików są jednak rzadkie. Jeśli chcesz poznać rozmiar pliku wyrażony w liczbie bajtów w pliku, w przeciwieństwie do liczby bloków dysku, których używa, użyj ls -lzamiast du.

Gilles „SO- przestań być zły”
źródło
Dzięki wielkie! Czy wiesz, czy istnieje (osobne) narzędzie, które może mi powiedzieć, czy mój plik jest rzadki?
Andrew
@Andrew Zobacz Jak znaleźć rzadkie pliki? oraz szczegółowe informacje o plikach rzadkich w systemie Linux
Gilles „SO- przestań być zły”