अगर टार चल रहा है तो डिस्क को भरने के लिए मैं कैसे निर्धारित कर सकता हूं


22

यदि मैं tar -cvfगहराई से नेस्टेड फ़ोल्डर संरचना की आसानी से डाउनलोड करने योग्य प्रतिलिपि बनाने के लिए 937MB आकार की निर्देशिका पर चलता हूं , तो क्या मैं निम्नलिखित df -hआउटपुट को देखते हुए डिस्क को भरने का जोखिम उठाता हूं :

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

संबंधित सवाल:

  • यदि डिस्क भर सकता है, तो लिनक्स (अमेज़ॅन एएमआई) और / या tarहुड के तहत क्या कर रहा है?
  • फिर से पूछे बिना मैं इस जानकारी को कैसे सही ढंग से निर्धारित कर सकता हूं?

मुझे यकीन नहीं है कि यह संग्रह को संसाधित किए बिना संभव है, लेकिन आप --totalsविकल्प के साथ चारों ओर खेल सकते हैं । किसी भी तरह से यदि आप डिस्क को भरते हैं तो आप केवल आर्काइव, इमो को हटा सकते हैं। उपलब्ध सभी विकल्पों की जांच करने के लिए आप इससे गुजर सकते हैं tar --help
UVV

4
मूर्त रूप से: टारफाइल को रूट के रूप में निर्मित न करें, डिस्क पर एक निश्चित प्रतिशत विशेष रूप से रूट के लिए अलग सेट है, ठीक उसी तरह के लिए "मैंने डिस्क को भर दिया है और अब मैं लॉगिन नहीं कर सकता क्योंकि वह लिख देगा। bash_history या जो भी "स्थिति।
उलरिच श्वार्ज

जवाबों:


24

tar -c data_dir | wc -c बिना संपीड़न के

या

tar -cz data_dir | wc -c गज़िप संपीड़न के साथ

या

tar -cj data_dir | wc -c bzip2 संपीड़न के साथ

डिस्क में लिखे बिना, संग्रह के आकार को बाइट्स में बनाया जाएगा। फिर आप अपने लक्ष्य डिवाइस पर खाली स्थान की मात्रा की तुलना कर सकते हैं।

आप डेटा निर्देशिका के आकार की स्वयं जांच कर सकते हैं, यदि इसके आदेश के बारे में एक गलत धारणा बनाई गई थी, तो निम्न आदेश के साथ:

du -h --max-depth=1 data_dir

जैसा कि पहले ही उत्तर दिया गया है, टर्क आर्काइव में प्रत्येक रिकॉर्ड के लिए एक हेडर जोड़ता है और प्रत्येक रिकॉर्ड के आकार को 512 बाइट्स (डिफ़ॉल्ट रूप से) से कई तक गोल करता है। एक पुरालेख का अंत कम से कम दो लगातार शून्य-भरे रिकॉर्ड द्वारा चिह्नित किया गया है। तो यह हमेशा ऐसा होता है कि आपके पास फ़ाइलों से बड़ी एक असम्पीडित टार फाइल होगी, फाइलों की संख्या और वे 512 बाइट की सीमाओं के साथ कैसे संरेखित होती हैं, इसका उपयोग अतिरिक्त स्थान निर्धारित करता है।

बेशक, फाइलसिस्टम स्वयं ब्लॉक साइज का उपयोग करते हैं, जो शायद एक व्यक्तिगत फाइल की सामग्री से बड़ा होता है इसलिए सावधान रहें कि आप इसे कहां अनटेयर करते हैं, फाइल सिस्टम बहुत सारी छोटी फाइलों को रखने में सक्षम नहीं हो सकता है, भले ही यह टार साइज से ज्यादा खाली जगह हो!

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


धन्यवाद जेमी! यहाँ क्या है - 'mysql'? क्या आपका नाम यही है?
कोडेकोवॉय

बस यह बदल गया है ... यह आपके डेटा निर्देशिका का पथ है।
फैंटास्टिकजैमीबर्न्स

1
ऐसा नहीं है कि यह वास्तव में मायने रखता है, लेकिन -f -टार के लिए तर्क संयोजन का उपयोग करना बेमानी है, क्योंकि आप -fपरिणाम को पूरी तरह से लिखने के लिए तर्क को पूरी तरह से छोड़ सकते हैं (यानी tar -c data_dir)।

6

आपकी टार फ़ाइल का आकार 937MB प्लस होगा जो प्रत्येक फ़ाइल या निर्देशिका (512 बाइट प्रति ऑब्जेक्ट) के लिए आवश्यक मेटाडेटा का आकार होगा, और पैडिंग को 512-बाइट सीमा में फ़ाइलों को संरेखित करने के लिए जोड़ा गया है।

एक बहुत ही कठिन गणना हमें बताती है कि आपके डेटा की एक और कॉपी आपको 3.4GB मुफ्त देगी। 3.4GB में हमारे पास लगभग 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 उस मामले में, आपको निश्चित रूप से उपरोक्त जैसा कुछ करना चाहिए। यह tarतब आपके स्थानीय डिस्क पर एक स्ट्रीम में पेड़ को कॉपी करेगा , जो दूरस्थ डिस्क पर कुछ भी सहेजे बिना, जिसके बाद आप इसे दूरस्थ होस्ट से हटा सकते हैं और बाद में इसे पुनर्स्थापित कर सकते हैं। आपको संभवतः -zगोल्डीलॉक्स बिंदु के रूप में संपीड़न के लिए जोड़ना चाहिए , बैंडविड्थ मध्य-स्थानांतरण पर बचाने के लिए।
mikeserv

@ TAFKA'goldilocks 'नहीं, क्योंकि यह 99% स्थान है, 99% स्थान नहीं है।
गिलेस एसओ-

-iसही है, क्षमा करें!
गोल्डीलॉक्स

@mikeserv आपकी प्रारंभिक लाइन में thetest विकल्प का उल्लेख करता है, लेकिन तब आप इसे अपने कमांड में इस्तेमाल नहीं करते हैं, जो तुरंत इस प्रकार है (यह उपयोग करता है --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 GB फ़ोल्डर पर ऐसा करने के परिणामस्वरूप ~ 1 GB टार फ़ाइल होगी (Flub के उत्तर में टार फ़ाइल में अतिरिक्त आकार के बारे में अधिक विवरण है, लेकिन ध्यान दें कि 10,000 फाइलें हैं या नहीं 5 एमबी)। चूंकि आपके पास 4+ जीबी मुफ्त है, नहीं, आप विभाजन नहीं भरेंगे।

एक आसानी से डाउनलोड करने योग्य प्रतिलिपि

ज्यादातर लोग डाउनलोड करने के मामले में "छोटे" के पर्यायवाची "आसान" पर विचार करेंगे, इसलिए आपको यहां कुछ संपीड़न का उपयोग करना चाहिए। bzip2अब मुझे किसी भी सिस्टम पर उपलब्ध होना चाहिए w / tar, मुझे लगता है, इसलिए jआपके स्विच में शामिल करना शायद सबसे अच्छा विकल्प है। z( gzip) शायद और भी अधिक सामान्य है, और अधिक स्क्वैश के साथ अन्य (कम सर्वव्यापी) संभावनाएं हैं।

यदि आपका मतलब है, tarकार्य करने में अस्थायी रूप से अतिरिक्त डिस्क स्थान का उपयोग करता है , तो मुझे पूरा यकीन है कि यह कुछ कारणों से नहीं होता है, एक यह है कि यह एक समय पहले वापस आता है जब टेप ड्राइव प्राथमिक भंडारण का एक रूप था, और दो होने के नाते दशकों से विकसित था (और मुझे यकीन है कि अस्थायी मध्यवर्ती स्थान का उपयोग करना आवश्यक नहीं है, भले ही संपीड़न शामिल हो)।


0

यदि गति महत्वपूर्ण है और संपीड़न की आवश्यकता नहीं है, तो आप हमारे द्वारा इसकी गणना करने के लिए बदलने के लिए tarउपयोग किए जाने वाले syscall रैपर को हुक कर सकते हैं। हमारी आवश्यकताओं के अनुरूप इन कार्यों में से कुछ को फिर से लागू करके (संभावित आउटपुट टार डेटा के आकार की गणना), हम बहुत कुछ खत्म करने में सक्षम हैं और जो सामान्य ऑपरेशन में किया जाता है । यह बहुत तेजी से बनाता है क्योंकि इसे संदर्भ में आगे और पीछे कर्नेल में कहीं भी स्विच करने की आवश्यकता नहीं होती है और केवल अनुरोधित इनपुट फ़ाइल / फ़ोल्डर (डिस्क) को वास्तविक फ़ाइल डेटा के बजाय डिस्क से पढ़ने की आवश्यकता होती है।LD_PRELOADtarreadwritetartarstat

नीचे दिए गए कोड के कार्यान्वयन में शामिल हैं close, readऔर writePOSIX कार्य करता है। मैक्रो OUT_FDकंट्रोल जो फाइल डिस्क्रिप्टर tarको आउटपुट फाइल के रूप में उपयोग करने की उम्मीद करते हैं। वर्तमान में यह stdout पर सेट है।

readकेवल countडेटा के साथ buf भरने के बजाय बाइट्स की सफलता का मूल्य वापस करने के लिए बदल दिया गया था , यह देखते हुए कि वास्तविक डेटा को buf नहीं पढ़ा गया था जिसमें संपीड़न पर गुजरने के लिए मान्य डेटा नहीं होगा, और इस प्रकार यदि संपीड़न का उपयोग किया गया था तो हम एक गलत गणना करेंगे। आकार।

writeइनपुट countबाइट्स को ग्लोबल वैरिएबल में समिट करने के लिए बदल दिया गया था totalऔर countबाइट्स के सक्सेस वैल्यू को तभी लौटाया जाता है, जब फाइल डिस्क्रिप्टर मैच करता है OUT_FD, अन्यथा यह dlsymउसी नाम के syscall को करने के लिए अधिग्रहीत मूल रैपर को कॉल करता है ।

closeअभी भी अपनी मूल कार्यक्षमता के बारे में सबकुछ बताता है, लेकिन यदि फाइल डिस्क्रिप्टर OUT_FD से मेल खाता है, तो यह जानता है कि tarएक टार फाइल लिखने का प्रयास किया जाता है, इसलिए यह totalसंख्या अंतिम है और यह इसे स्टडआउट करने के लिए प्रिंट करता है।

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

बेंचमार्क एक समाधान की तुलना करता है, जहां रीड डिस्क एक्सेस और सामान्य टार ऑपरेशन के सभी syscalls 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/ का उपयोग करने पर कुछ जानकारी


कोड अच्छा है, अगर यह काम करता है, लेकिन क्या आप इसका वर्णन कर सकते हैं कि यह क्या करता है? कृपया टिप्पणियों में प्रतिक्रिया न दें;  इसे स्पष्ट और अधिक पूर्ण बनाने के लिए अपना उत्तर संपादित करें।
जी-मैन का कहना है कि 'मोनिका की बहाली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.