Як я можу визначити, чи спричинить заповнення диска заповнення диска


22

Якщо я запускаю tar -cvfв каталог розміром 937MB для створення легко завантажуваної копії глибоко вкладеної структури папок, чи ризикую я заповнити диск, отримавши такий df -hвихід:

/dev/xvda1            7.9G  3.6G  4.3G  46% /
tmpfs                 298M     0  298M   0% /dev/shm

Пов’язані запитання:

  • Якщо диск може заповнити, чому саме, що робитиме Linux (Amazon AMI) та / або tarробити під кришкою?
  • Як я можу точно визначити цю інформацію сам, не запитуючи знову?

Я не впевнений, чи можливо це без обробки архіву, але можна пограти з --totalsопцією. У будь-якому випадку, якщо ви заповнили диск, ви можете просто видалити архів, imho. Щоб перевірити всі наявні варіанти, які ви могли пройти tar --help.
UVV

4
Дотично: не створюйте tarfile як root, певний відсоток місця на диску відводиться виключно для root, саме для типу "Я заповнив диск, і тепер я не можу ввійти, тому що це буде писати. bash_history або будь-яка інша ситуація.
Ульріх Шварц

Відповіді:


24

tar -c data_dir | wc -c без стиснення

або

tar -cz data_dir | wc -c зі стисненням gzip

або

tar -cj data_dir | wc -c з компресією bzip2

буде надрукувати розмір архіву, який був би створений в байтах, не записуючи на диск. Потім ви можете порівняти це з кількістю вільного місця на вашому цільовому пристрої.

Ви можете перевірити розмір самого каталогу даних у випадку, якщо було зроблено неправильне припущення про його розмір, за допомогою наступної команди:

du -h --max-depth=1 data_dir

Як уже відповіли, tar додає заголовок до кожної записи в архіві, а також округляє розмір кожного запису до кратного 512 байтів (за замовчуванням). Кінець архіву позначений щонайменше двома поспіль заповненими нулями записами. Тому завжди так, що у вас буде нестиснений файл tar, більший за самі файли, кількість файлів і те, як вони вирівнюються до меж 512 байтів, визначають додатковий простір, який використовується.

Звичайно, самі файлові системи використовують розміри блоків, які, можливо, перевищують вміст окремого файлу, тому будьте обережні, де ви його знімаєте, файлова система може не мати вмісту для малих файлів, хоча у неї є вільний простір, більший за розмір смоли!

https://en.wikipedia.org/wiki/Tar_(computing)#Format_details


Спасибі Джеймі! Що тут робить "- mysql"? Це ваше ім'я файлу?
codecowboy

Щойно змінив це ... це шлях до вашого каталогу даних.
FantasticJamieBurns

1
Мало того, що це насправді важливо, але використання комбінації аргументів -f -для tar є надлишком, оскільки ви можете просто залишити -fаргумент взагалі, щоб записати результат у stdout (тобто tar -c data_dir).

6

Розмір файлу tar буде дорівнювати 937 Мб плюс розмір метаданих, необхідних для кожного файлу чи каталогу (512 байтів на об'єкт), та додавання додатків для вирівнювання файлів до 512-байтової межі.

Дуже приблизний підрахунок говорить про те, що інша копія ваших даних залишить вам 3,4 Гб безкоштовно. В 3,4 ГБ ми маємо місце для приблизно 7 мільйонів записів метаданих, якщо не вважати прокладок або менше, якщо ви припускаєте в середньому 256 байтів. Тож якщо у вас є мільйони файлів і каталогів, на які ви можете скористатися, ви можете зіткнутися з проблемами.

Ви могли пом'якшити проблему

  • стиснення на льоту, використовуючи zабо jваріантиtar
  • робити це tarяк звичайний користувач, щоб зарезервоване місце на /розділі не торкалося, якщо у вас не вистачає місця.

2

tarсам може повідомити про розмір своїх архівів з --testможливістю:

tar -cf - ./* | tar --totals -tvf -

Вищевказана команда нічого не записує на диск і має додаткову перевагу у переліку окремих розмірів файлів кожного файлу, що міститься у тарболі. Додавання різних z/j/xzоперандів до будь-якої сторони |pipeволі оброблятиме стиснення так само, як і ви.

ВИХІД:

...
-rwxr-xr-x mikeserv/mikeserv         8 2014-03-13 20:58 ./somefile.sh
-rwxr-xr-x mikeserv/mikeserv        62 2014-03-13 20:53 ./somefile.txt
-rw-r--r-- mikeserv/mikeserv       574 2014-02-19 16:57 ./squash.sh
-rwxr-xr-x mikeserv/mikeserv        35 2014-01-28 17:25 ./ssh.shortcut
-rw-r--r-- mikeserv/mikeserv        51 2014-01-04 08:43 ./tab1.link
-rw-r--r-- mikeserv/mikeserv         0 2014-03-16 05:40 ./tee
-rw-r--r-- mikeserv/mikeserv         0 2014-04-08 10:00 ./typescript
-rw-r--r-- mikeserv/mikeserv       159 2014-02-26 18:32 ./vlc_out.sh
Total bytes read: 4300943360 (4.1GiB, 475MiB/s)

Не зовсім впевнений у своїй меті, але якщо це потрібно завантажити тарбол, це може бути більш суттєвим:

ssh you@host 'tar -cf - ./* | cat' | cat >./path/to/saved/local/tarball.tar

Або просто скопіювати за допомогою tar:

ssh you@host 'tar -cf - ./* | cat' | tar -C/path/to/download/tree/destination -vxf -

Причиною, що я це роблю, є те, що я вважаю, що каталог, про який йде мова, призвів до виходу df -i до 99%. Я хочу зберегти копію каталогу для подальшого аналізу, але хочу очистити пробіл
codecowboy

@codecowboy У цьому випадку вам обов'язково слід зробити щось на зразок вище. Потім воно буде tarкопіювати дерево на локальний диск у потоці, не зберігаючи нічого на віддаленому диску, після чого ви можете видалити його з віддаленого хоста та відновити його пізніше. Ви, ймовірно, повинні додати -zдля стиснення, як вказує золотисте, щоб заощадити на пропускній здатності в середині передачі.
mikeserv

@ TAFKA'goldilocks 'Ні, тому що це 99% введення, а не 99% місця.
Жил "ТАК - перестань бути злим"

-iправильно, вибачте!
goldilocks

@mikeserv у вашому рядку відкриття згадується варіант --test, але ви, здається, не використовуєте його у своїй команді, яка негайно випливає (вона використовує --totals)
codecowboy

2

Я зробив багато досліджень з цього приводу. Ви можете зробити тест на файл з підрахунком слів, але він не дасть вам те саме число номер, як du -sb adir.

tar -tvOf afile.tar | wc -c

duрахує кожен каталог як 4096 байт і tarвважає каталоги 0 байтами. Ви повинні додати 4096 до кожного каталогу:

$(( $(tar -tvOf afile.tar 2>&1 | grep '^d' | wc -l) * 4096)))

тоді вам доведеться додати всі символи. Щось таке, що виглядає так:

$(( $(tar -tvOf afile.tar 2>&1 | grep '^d' | wc -l) * 4096 + $(tar -xOf afile.tar | wc -c) ))

Я не впевнений, чи це ідеально, оскільки я не пробував торкнулися файлів (файлів у 0 байт) або файлів, що мають 1 символ. Це повинно вас зблизити.


1

-cvfне включає ніякого стиснення, тому виконання в папці ~ 1 ГБ призведе до отримання тар-файлу ~ 1 Гб (у відповіді Flub є додаткові відомості про додатковий розмір у файлі tar, але зауважте, навіть якщо є 10000 файлів, це лише 5 Мб). Оскільки у вас є 4+ ГБ безкоштовно, розділ не заповнюватиметься.

легко завантажувана копія

Більшість людей вважають "простішим" синонімом "менший" з точки зору завантаження, тому вам слід скористатися деяким стисненням. bzip2Якщо я думаю, повинні зараз бути доступні дні на будь-якій системі без тарифу, тому j, мабуть, найкращим вибором є включення до перемикачів. z( gzip), можливо, навіть більш поширений, і є інші (менш всюдисущі) можливості з більшою кількістю сквош.

Якщо ви хочете сказати, чи tarвикористовує додатковий дисковий простір тимчасово для виконання завдання, я впевнений, що це не з кількох причин, одна з них - це час, коли стрічкові накопичувачі були формою основного сховища, а два - це мали розвиватися десятиліття (і я впевнений, що не потрібно використовувати тимчасовий проміжний простір, навіть якщо відбувається компресія).


0

Якщо швидкість важлива, а компресія не потрібна, ви можете підключити обгортки syscall, використовувані за tarдопомогою LD_PRELOAD, щоб змінити, tarщоб обчислити її для нас. Перевизначення деякі з цих функцій , щоб задовольнити наші потреби (розрахунок розміру потенційного виведення даних гудрону), ми можемо виключити багато readі writeщо виконується при нормальній роботі tar. Це робиться tarнабагато швидше, оскільки не потрібно перемикання контексту вперед і назад в ядро ​​в будь-якому місці, і тільки statз потрібного вхідного файлу / папки (файлів) потрібно читати з диска замість фактичних даних про файл.

Нижче код включає в себе варіанти реалізації close, readі writeфункції POSIX. Макрос OUT_FDконтролює дескриптор файлу, який ми очікуємо tarвикористовувати як вихідний файл. В даний час він встановлений на stdout.

readбуло змінено, щоб просто повернути значення успішності countбайтів замість заповнення buf даними, враховуючи, що фактичні дані не були прочитані. Буф не містив би дійсних даних для переходу до стиснення, і, таким чином, якщо було використано стиснення, ми обчислимо неправильне розмір.

writeбуло змінено для підсумовування вхідних countбайтів у глобальну змінну totalта повернення значення успішності countбайтів, лише якщо дескриптор файлу збігається OUT_FD, інакше він викликає оригінальну обгортку, придбану через, dlsymщоб виконати однойменну системну виклик.

closeвсе ще заздалегідь виконує всі свої оригінальні функціональні можливості, але якщо дескриптор файлу відповідає OUT_FD, він знає, що tarробиться спроба написати файл tar, тому totalчисло остаточне, і він виводить його на stdout.

#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <errno.h>
#include <dlfcn.h>
#include <string.h>

#define OUT_FD 1
uint64_t total = 0;
ssize_t (*original_write)(int, const void *, size_t) = NULL;
int (*original_close)(int) = NULL;
void print_total(void)
{
    printf("%" PRIu64 "\n", total);
}

int close(int fd)
{
    if(! original_close)
    {
        original_close = dlsym(RTLD_NEXT, "close");
    }
    if(fd == OUT_FD)
    {
        print_total();
    }
    return original_close(fd);
}

ssize_t read(int fd, void *buf, size_t count)
{
    return count;
}

ssize_t write(int fd, const void *buf, size_t count)
{
    if(!original_write)
    {
        original_write = dlsym(RTLD_NEXT, "write");
    }
    if(fd == OUT_FD)
    {
        total += count;
        return count;
    }
    return original_write(fd, buf, count);
}

Бенчмарк порівняння рішення, де доступ до зчитуваного диска та всі системні виклики нормальної роботи тарінгу виконуються проти LD_PRELOADрішення.

$ time tar -c /media/storage/music/Macintosh\ Plus-\ Floral\ Shoppe\ \(2011\)\ \[Flac\]/ | wc -c
332308480
real    0m0.457s
user    0m0.064s
sys     0m0.772s
tarsize$ time ./tarsize.sh -c /media/storage/music/Macintosh\ Plus-\ Floral\ Shoppe\ \(2011\)\ \[Flac\]/
332308480
real    0m0.016s
user    0m0.004s
sys     0m0.008s

Код вище, базовий сценарій збірки будувати вище , в якості загальної бібліотеки, і сценарій з « LD_PRELOADтехнікою» , використовуючи його надаються в репо: https://github.com/G4Vi/tarsize

Деякі відомості про використання LD_PRELOAD: https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/


Код хороший, якщо він працює, але чи можете ви описати, що він робить? Будь ласка, не відповідайте на коментарі; відредагуйте  свою відповідь, щоб зробити її більш зрозумілою та повною.
G-Man каже "Відновити Моніку"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.