Çalışan tar'in diskin dolmasına neden olup olmayacağını nasıl belirleyebilirim


22

Koşarsam tar -cvfderinden iç içe klasör yapısının kolayca indirilebilir kopyasını oluşturmak için boyut 937MB bir dizin, şu verilen diski dolduruyor riske mi df -hçıktı:

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

İlgili sorular:

  • Eğer disk doluyorsa, neden Linux (Amazon AMI) ve / veya tarkaputun altında ne yapacaksınız ?
  • Tekrar sormadan bu bilgiyi kendim nasıl doğru bir şekilde belirleyebilirim?

Arşivi işlemeden mümkün olup olmadığından emin değilim, ancak --totalsseçenekle oynayabilirsiniz . Her iki durumda da, diski doldurursanız, arşivi silebilirsiniz, yani. Mevcut tüm seçenekleri kontrol etmek için gidebilirsiniz tar --help.
UVV

4
Teğetsel olarak: tar dosyasını root olarak oluşturma, diskteki belirli bir alan yüzdesi yalnızca root için ayrılır, aynen "disk doldurdum ve şimdi giriş yapamıyorum çünkü yazacağım. bash_history veya her neyse "durum.
Ulrich Schwarz

Yanıtlar:


24

tar -c data_dir | wc -c sıkıştırma olmadan

veya

tar -cz data_dir | wc -c gzip sıkıştırmalı

veya

tar -cj data_dir | wc -c bzip2 sıkıştırması ile

bayt olarak oluşturulacak arşivin boyutunu diske yazmadan yazdıracaktır. Daha sonra bunu hedef cihazınızdaki boş alan miktarıyla karşılaştırabilirsiniz.

Aşağıdaki komutla, boyutu hakkında yanlış bir varsayım yapılması durumunda, veri dizininin boyutunu kontrol edebilirsiniz:

du -h --max-depth=1 data_dir

Daha önce cevaplandığı gibi, tar, arşivdeki her kayda bir başlık ekler ve ayrıca her kaydın boyutunu 512 baytın katlarına çıkarır (varsayılan olarak). Bir arşivin sonu, en az iki ardışık sıfır dolu kayıtla işaretlenir. Bu yüzden her zaman, dosyaların kendisinden daha büyük, sıkıştırılmamış bir tar dosyasına sahip olacaksınız, dosya sayısı ve 512 bayt sınırlarına nasıl hizalandıkları, kullanılan fazladan alanı belirler.

Elbette, dosya sistemlerinin kendisi, tek bir dosyanın içeriğinden daha büyük olan blok boyutlarını kullanır; bu nedenle, başlattığınız yerde dikkatli olun; dosya sistemi, tar boyutundan daha fazla boş alana sahip olmasına rağmen, çok sayıda küçük dosyayı tutamayabilir!

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


Jamie'ye teşekkürler! '- mysql' burada ne arıyor? Bu senin dosya adın mı?
codecowboy

Sadece değişti ... veri dizininizin yolu.
FantasticJamieBurns

1
Gerçekten önemli değil, ancak -f -tar için argüman kombinasyonunu kullanmak gereksizdir, çünkü -fsonucu stdout'a (yani tar -c data_dir) yazmak için argümanı tamamen bırakabilirsiniz .

6

Tar dosyanızın boyutu 937MB, her dosya veya dizin için gereken meta veri boyutunu (nesne başına 512 bayt) ve dosyaları 512 bayt sınırla aynı hizada tutmak için eklenebilir.

Çok kaba bir hesaplama bize, verilerinizin başka bir kopyasının sizi 3.4GB ücretsiz bırakacağını söyler. 3.4GB’de, dosya başına ortalama 256 bayt dolgusu varsayarsak, doldurma olmadığı varsayılarak, yaklaşık 7 milyon meta veri kaydına yer var. Yani, tar için milyonlarca dosya ve diziniz varsa, sorun yaşayabilirsiniz.

Sorunu hafifletebilirsin

  • seçeneğini kullanarak zveyajtar
  • tarnormal bir kullanıcı olarak yaptığınız için , /eğer alanınız tükenirse bölümdeki ayrılmış alana dokunulmaz.

2

tarkendisi --testseçeneği ile arşivlerinin boyutunu bildirebilir :

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

Yukarıdaki komut diske hiçbir şey yazmaz ve tarball'da yer alan her bir dosyanın bireysel dosya boyutlarını listeleme avantajına sahiptir. Çeşitli z/j/xzişlenenleri, istediğiniz |pipegibi sıkıştırmayı işlemek için her iki tarafına da ekleyebilirsiniz .

ÇIKTI:

...
-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)

Amacınızdan tam olarak emin değilsiniz ancak tarball'ı indirmek istiyorsanız, bu daha çok önemli olabilir:

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

Veya sadece kopyalamak için tar:

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

Bunu yapmamın nedeni, söz konusu dizinin df -i çıktısının% 99'a ulaşmasına neden olduğuna inanıyorum. Daha fazla analiz için dizinin bir kopyasını saklamak istiyorum ancak alanı temizlemek istiyorum
codecowboy

@codecowboy Bu durumda, kesinlikle yukarıda belirtilenlere benzer bir şey yapmalısınız. Daha tarsonra ağacı, herhangi bir şeyi uzak diske kaydetmeden bir akıştaki yerel diskinize kopyalar, daha sonra uzak ana bilgisayardan silebilir ve daha sonra geri yükleyebilirsiniz. -zOrta bant transferinde orta bant tasarrufundan tasarruf etmek için muhtemelen goldilocks işaret ettiği gibi sıkıştırma eklemelisiniz .
mikeserv

@ TAFKA'goldilock 'Hayır, çünkü% 99 inode'lar, alanın% 99'u.
Gilles 'SO- kötülük olmayı'

-itamam üzgünüm!
goldilocks

@mikeserv açılış çizginiz --test seçeneğinden bahseder, ancak daha sonra derhal izleyen emrinizde kullanmazsınız (--totals kullanır)
codecowboy

2

Bu konuda çok araştırma yaptım. Bir kelime sayımı ile dosya üzerinde bir test yapabilirsiniz, ancak bu size a ile aynı sayıyı vermez du -sb adir.

tar -tvOf afile.tar | wc -c

duher dizini 4096 bayt, tarsayıları ise 0 bayt olarak sayar. Her bir dizine 4096 eklemelisiniz:

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

o zaman tüm karakterleri eklemek zorundasın. Buna benzeyen bir şey için:

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

Dokunulan dosyaları (0 byte'lık dosyaları) veya 1 karakterli dosyaları denemedim, çünkü bunun mükemmel olup olmadığından emin değilim. Bu seni daha da yakınlaştırmalı.


1

-cvfherhangi bir sıkıştırma içermez, bu nedenle ~ 1 GB'lık bir klasörde yapmak ~ 1 GB'lık tar dosyasına yol açacaktır (Flub'un cevabı tar dosyasındaki ek boyut hakkında daha fazla ayrıntıya sahiptir, ancak 10.000 dosya olsa bile not alın. 5 MB). 4+ GB ücretsiz olduğundan, bölümü doldurmayacaksınız.

Kolayca indirilebilir bir kopya

Çoğu kişi, indirme açısından "daha küçük" ile eşanlamlı "kolay" olarak değerlendirir, bu nedenle burada biraz sıkıştırma kullanmanız gerekir. bzip2Bir gün şimdi herhangi bir sistemde w / tar mevcut olmalı, bence, janahtarlarınız da dahil olmak üzere muhtemelen en iyi seçimdir. z( gzip) belki daha da yaygındır ve daha fazla kabak içeren başka (daha az yaygın) olanaklar vardır.

Demek istediğim, targörevi yerine getirirken geçici olarak ek disk alanı kullanıyorsa, bunun bir kaç nedenden dolayı olmadığından eminim, biri teyp sürücülerinin birincil depolama biçimi olduğu bir zamana dayanıyor ve ikisi de gelişmeye yıllardır (ve sıkıştırma dahil olsa bile geçici ara alan kullanmanın gerekli olmadığından eminim).


0

Hız önemlidir ve sıkıştırma gerekli değilse, sen kullandığı syscall sarmalayıcılarını kanca tarkullanarak LD_PRELOADdeğiştirmek, tarbizim için hesaplamak için. Bu fonksiyonlardan bir kaçını ihtiyacımıza uyacak şekilde yeniden uygulayarak (potansiyel çıktı katran verilerinin boyutunu hesaplayarak), birçoğunu ortadan kaldırabiliriz readve writebu normal çalışmasında gerçekleştirilir tar. Bu tarbağlamda çekirdeğe ileri ve geri çevrilmesi gerekmediği için çok daha hızlı hale gelir statve istenen dosya / klasörlerin sadece istenen dosya verileri yerine diskten okunması gerekir.

Aşağıdaki kod uygulamalarını içerir close, readve writePOSIX işlevleri. Makro , çıktı dosyası olarak OUT_FDhangi dosya tanımlayıcısını tarkullanacağımızı kontrol eder . Şu anda stdout olarak ayarlanmış.

readcountgerçek veriyi okumayan buf sıkıştırmaya geçmek için geçerli veri içermeyeceği göz önüne alındığında, veriyi buf ile veriyi doldurmak yerine yalnızca bayt başarı değerini döndürmek için değiştirildi ve bu nedenle sıkıştırma kullanılırsa yanlış hesaplardık boyut.

writegiriş countbaytlarını global değişkene toplamak ve sadece dosya tanımlayıcısı eşleşirse baytların totalbaşarı değerini döndürmek için değiştirildi , aksi takdirde aynı adın çağrısını gerçekleştirmek için elde edilen orijinal sarmalayıcıyı çağırır .countOUT_FDdlsym

closehala orijinal işlevlerinin tamamını hazırlar, ancak dosya tanımlayıcısı OUT_FD ile eşleşiyorsa, bunun tarbir tar dosyası yazmaya çalışıldığını bilir , bu nedenle totalsayı kesindir ve stdout'a yazdırır.

#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);
}

Okunan diske erişimin ve normal katran işleminin tüm sistem çağrılarının LD_PRELOADçözüme karşı gerçekleştirildiği bir çözümü karşılaştıran kıyaslama .

$ 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

Yukarıdaki kod, yukarıdakileri paylaşılan bir kütüphane olarak oluşturmak için temel bir derleme betiği ve repo'da " LD_PRELOADtekniği" olan bir betik verilmiştir: https://github.com/G4Vi/tarsize

LD_PRELOAD'ı kullanmayla ilgili bazı bilgiler: https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/


Kod işe yarıyorsa iyidir, ancak ne yaptığını açıklayabilir misiniz ? Lütfen yorumlara cevap vermeyin;  cevabınızı daha net ve daha eksiksiz hale getirmek için düzenleyin .
G-Man
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.