लाखों फाइलों के साथ एक निर्देशिका पर आर.एम.


104

पृष्ठभूमि: भौतिक सर्वर, लगभग दो वर्ष पुराना, 7200-RPM SATA ड्राइव जो कि 3Ware RAID कार्ड से जुड़ा हुआ है, ext3 FS माउंटेड नॉटाइम और डेटा = क्रॉस्ड लोड के अंतर्गत नहीं, क्रमबद्ध 2.6.18-92.1.22.el5, अपटाइम 545 दिन । निर्देशिका में कोई उपनिर्देशिका नहीं होती है, बस कुछ छोटी (~ 100 बाइट) फाइलें, कुछ बड़ी (कुछ KB) वाली होती हैं।

हमारे पास एक सर्वर है जो पिछले कुछ महीनों के दौरान थोड़ा कोयल हो गया है, लेकिन हमने इसे केवल दूसरे दिन देखा जब यह बहुत सारी फाइलों के साथ एक निर्देशिका में लिखने में असमर्थ होने लगा। विशेष रूप से, इस त्रुटि को / var / log / संदेश में फेंकना शुरू कर दिया:

ext3_dx_add_entry: Directory index full!

विचाराधीन डिस्क में बहुत सारे कोड शेष हैं:

Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/sda3            60719104 3465660 57253444    6% /

इसलिए मैं अनुमान लगा रहा हूं कि इसका मतलब है कि हम इस सीमा को मारते हैं कि निर्देशिका फ़ाइल में कितनी प्रविष्टियाँ हो सकती हैं। पता नहीं कितनी फाइलें होंगी, लेकिन यह अधिक नहीं हो सकती, जैसा कि आप देख सकते हैं, तीन मिलियन या उससे अधिक। ऐसा नहीं है कि अच्छा है, तुम मन! लेकिन यह मेरे सवाल का एक हिस्सा है: वास्तव में वह ऊपरी सीमा क्या है? क्या यह ट्यून करने योग्य है? इससे पहले कि मैं चिल्लाता हूं - मैं इसे नीचे गिराना चाहता हूं ; इस विशाल निर्देशिका ने सभी प्रकार के मुद्दों का कारण बना।

वैसे भी, हमने उस कोड में समस्या को ट्रैक किया जो उन सभी फ़ाइलों को उत्पन्न कर रहा था, और हमने इसे ठीक कर दिया है। अब मैं निर्देशिका को हटाने के साथ फंस गया हूं।

यहाँ कुछ विकल्प:

  1. rm -rf (dir)

    मैंने पहले यही कोशिश की। डेढ़ दिन तक बिना किसी प्रभाव के चलने के बाद मैंने इसे छोड़ दिया और इसे मार दिया।

  2. निर्देशिका पर अनलिंक (2): निश्चित रूप से विचार के लायक है, लेकिन सवाल यह है कि क्या यह अनलिंक (2) के माध्यम से हटाने के लिए fsck के माध्यम से निर्देशिका के अंदर फ़ाइलों को हटाने के लिए तेज़ होगा। यही है, एक तरह से या किसी अन्य, मैं उन inodes को अप्रयुक्त के रूप में चिह्नित करने के लिए मिला हूं। यह मानता है, निश्चित रूप से, मैं fsck को बता सकता हूं कि फाइलों में प्रविष्टियों को ड्रॉप न करें / खोया + पाया; अन्यथा, मैं सिर्फ अपनी समस्या को आगे बढ़ाता हूं। अन्य सभी चिंताओं के अलावा, इस बारे में थोड़ा और पढ़ने के बाद, यह पता चला है कि मुझे शायद कुछ आंतरिक एफएस फ़ंक्शन को कॉल करना होगा, क्योंकि मुझे जो भी अनलिंक (2) वेरिएंट में से कोई नहीं मिल सकता है, वह मुझे ब्लिटली हटाने की अनुमति देगा इसमें प्रविष्टियों के साथ एक निर्देशिका। पूह।
  3. while [ true ]; do ls -Uf | head -n 10000 | xargs rm -f 2>/dev/null; done )

    यह वास्तव में छोटा संस्करण है; जो मैं चला रहा हूँ, वह वास्तविक है, जो कुछ प्रगति-रिपोर्टिंग और एक स्वच्छ पड़ाव जोड़ता है जब हम हटाने के लिए फाइलों से बाहर निकलते हैं, वह है:

    निर्यात i = 0;
    समय (जबकि [सच] ;;
      ls -Uf | सिर -n 3 | grep -qF '.png' || टूटना;
      ls -Uf | हेड-एन 10000 | xargs rm -f 2> / dev / null;
      निर्यात i = $ (($ i + 10000));
      गूंज "$ i ...";
    किया हुआ )

    यह अच्छी तरह से काम करने लगता है। जैसा कि मैंने इसे लिखा है, इसने पिछले तीस मिनटों में 260,000 फाइलें डिलीट की हैं।

अब, प्रश्नों के लिए:
  1. जैसा कि ऊपर उल्लेख किया गया है, क्या प्रति-निर्देशिका प्रविष्टि सीमा ट्यूनेबल है?
  2. किसी एकल फ़ाइल को हटाने के लिए "वास्तविक 7m9.561s / उपयोगकर्ता 0m0.001s / sys 0m0.001s" को क्यों लिया गया, जो उस सूची में पहले वाला था, जिसके द्वारा लौटाया गया था ls -U, और इसके साथ पहली 10,000 प्रविष्टियों को हटाने में शायद दस मिनट लगे # 3 में कमांड, लेकिन अब यह बहुत खुशी के साथ शासन कर रहा है? उस मामले के लिए, इसने लगभग तीस मिनट में 260,000 डिलीट कर दिए, लेकिन अब 60,000 और डिलीट करने में पंद्रह मिनट लग गए हैं। गति में विशाल झूलें क्यों?
  3. क्या इस तरह का काम करने का कोई बेहतर तरीका है? एक निर्देशिका में लाखों फ़ाइलों को संग्रहीत न करें; मुझे पता है कि यह मूर्खतापूर्ण है, और यह मेरी घड़ी पर नहीं हुआ होगा। समस्या को देखते हुए और एसएफ और एसओ के माध्यम से देखने से कई प्रकार की विविधताएं मिलती findहैं जो कई स्व-स्पष्ट कारणों से मेरे दृष्टिकोण से काफी तेज नहीं होने वाली हैं। लेकिन क्या डिलीट-थ्रू- fsck आइडिया का कोई पैर है? या कुछ और पूरी तरह से? मैं आउट-ऑफ-द-बॉक्स (या अंदर-ही-नहीं-प्रसिद्ध-बॉक्स) सोच को सुनने के लिए उत्सुक हूं।
छोटे उपन्यास को पढ़ने के लिए धन्यवाद; प्रश्न पूछने के लिए स्वतंत्र महसूस करें और मैं प्रतिक्रिया देना सुनिश्चित करूंगा। मैं फ़ाइलों की अंतिम संख्या के साथ प्रश्न को भी अपडेट करूंगा और मेरे पास एक बार डिलीट स्क्रिप्ट कितनी देर तक चलेगी।

अंतिम स्क्रिप्ट आउटपुट !:

2970000...
2980000...
2990000...
3000000...
3010000...

real    253m59.331s
user    0m6.061s
sys     5m4.019s

इसलिए, चार घंटों में तीन मिलियन फाइलें कुछ ही समय में हटा दी गईं।


1
rm (GNU coreutils) 8.4 में यह विकल्प है: "-v, --verbose समझाएं कि क्या किया जा रहा है" । यह उन सभी फाइलों को प्रदर्शित करेगा जिन्हें हटाया जा रहा है।
क्रिस्टियन सियुपिटु

2
वास्तव में, यह एक प्रगति बार करने के लिए एक साफ तरीका होगा: चूंकि प्रत्येक फ़ाइल सैंतीस वर्ण लंबा (36 + एक '\ n') होगी, मैं आसानी से उस के लिए एक पार्सर लिख सकता हूं, और चूंकि प्रिंटफ () है सस्ते और rm कमांड में पहले से ही भरी हुई फ़ाइल का नाम है, कोई विशिष्ट प्रदर्शन जुर्माना नहीं है। पूरे शेबांग करने के लिए एक गैर-स्टार्टर की तरह लगता है, क्योंकि मुझे कभी भी ऐसा कुछ भी करने के लिए "आरएम" नहीं मिला। लेकिन यह इंट्रा 10,000 प्रगति बार के रूप में काफी अच्छी तरह से काम कर सकता है; शायद एक "।" हर सौ फाइलों के लिए?
बीएमडीएन

8
rm -rfv | pv -l >/dev/null। pv EPEL रिपॉजिटरी में उपलब्ध होना चाहिए ।
क्रिस्टियन सियुपिटु

5
pv अत्यधिक भयानक है। मैं अपने उठाव में pv स्थापनाओं का निशान छोड़ देता हूँ।
बीएमडीएन

हाल ही में मेरा भी यही मुद्दा था। धन्यवाद!
रिचो

जवाबों:


30

data=writebackमाउंट विकल्प, की कोशिश की जा करने के लिए फाइल सिस्टम की दैनिकी को रोकने के लिए योग्य है। यह केवल हटाने के समय के दौरान किया जाना चाहिए, हालांकि एक जोखिम है, अगर सर्वर को हटाए जाने या ऑपरेशन के दौरान रिबूट किया जा रहा है।

इस पृष्ठ के अनुसार ,

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

विकल्प को या तो fstabमाउंट ऑपरेशन के दौरान या उसके साथ सेट data=orderedकिया गया है data=writeback। डिलीट की जाने वाली फाइल सिस्टम फाइल को रिमूव करना होगा।


1
वह commit विकल्प से समय भी बढ़ा सकता है : "यह डिफ़ॉल्ट मान (या कोई भी कम मान) प्रदर्शन को नुकसान पहुंचाएगा, लेकिन यह डेटा-सुरक्षा के लिए अच्छा है। इसे 0 पर सेट करने का डिफ़ॉल्ट (5 सेकंड) पर छोड़ने के समान प्रभाव होगा। )। इसे बहुत बड़े मूल्यों पर सेट करने से प्रदर्शन में सुधार होगा "।
क्रिस्टियन सियुपिटु

1
राइटबैक तारकीय दिखता है, सिवाय उस दस्तावेज़ को छोड़कर, जिसे मैं देख रहा था ( gentoo.org/doc/en/articles/l-afig-p8.xml#doc_chap4 ) स्पष्ट रूप से उल्लेख है कि यह अभी भी जन्नत को प्रकाशित करता है, जिसके बारे में मुझे पता है कि मेरे पास सभी डेटा शामिल हैं परिवर्तन (मैं निश्चित रूप से फ़ाइलों में कोई डेटा नहीं बदल रहा हूँ)। क्या विकल्प के बारे में मेरी समझ गलत है?
बीएमडीएन

अंत में, FYI करें, उस लिंक में उल्लेख नहीं किया गया है कि तथ्य यह है कि डेटा = राइटबैक एक बहुत बड़ा सुरक्षा छेद हो सकता है, क्योंकि किसी दिए गए प्रविष्टि द्वारा इंगित किए गए डेटा में ऐप द्वारा लिखे गए डेटा नहीं हो सकते हैं, जिसका अर्थ है कि दुर्घटना हो सकती है। पुराने, संभवतः संवेदनशील / निजी डेटा को उजागर किया जा रहा है। यहाँ कोई चिंता की बात नहीं है, क्योंकि हम इसे केवल अस्थायी रूप से चालू कर रहे हैं, लेकिन मैं हर किसी को या तो उस चेतावनी के प्रति सचेत करना चाहता था जब आप या अन्य जो उस सुझाव पर चल रहे थे वे जागरूक नहीं थे।
बीएमडीएन

प्रतिबद्ध: यह बहुत चालाक है! सूचक के लिए धन्यवाद।
बीएमडीएन

2
data=writebackअभी भी पत्रिकाओं ने इसे मुख्य फाइल सिस्टम में लिखने से पहले मेटाडेटा दिया। जैसा कि मैं इसे समझता हूं, यह सिर्फ एक हद तक नक्शा लिखने और उन extents में डेटा लिखने जैसी चीजों के बीच आदेश को लागू नहीं करता है। हो सकता है कि कोई अन्य ऑर्डर देने में बाधा हो, यह आराम करता है, अगर आपने इससे एक संपूर्ण लाभ देखा है। बेशक, जर्नल के बिना बढ़ते हुए भी उच्च प्रदर्शन हो सकता है। (यह मेटाडेटा को केवल RAM में घटित होने दे सकता है, बिना डिस्क के पूर्ण होने से पहले डिस्क पर कुछ भी करने की आवश्यकता के बिना)।
पीटर कॉर्डेस

80

जबकि इस समस्या का एक प्रमुख कारण लाखों फाइलों के साथ प्रदर्शन 3 है, इस समस्या का वास्तविक मूल कारण अलग है।

जब एक निर्देशिका को रीडडीर () सूचीबद्ध करने की आवश्यकता होती है, तो उस निर्देशिका को कहा जाता है जो फाइलों की सूची तैयार करती है। readdir एक पॉज़िक्स कॉल है, लेकिन यहाँ उपयोग किए जा रहे वास्तविक लिनक्स सिस्टम कॉल को 'getdents' कहा जाता है। प्रविष्टियों के साथ एक बफर भरकर गेट्स की सूची निर्देशिका प्रविष्टियों।

समस्या मुख्य रूप से इस तथ्य से कम है कि फाइल को लाने के लिए रीडडीर () 32Kb के एक निश्चित बफर आकार का उपयोग करता है। जैसे-जैसे कोई निर्देशिका बड़ी और बड़ी होती जाती है (फ़ाइल के आकार में वृद्धि होती जाती है) ext3 को प्रविष्टियाँ प्राप्त करने के लिए धीमी और धीमी होती जाती है और अतिरिक्त रीडडीर का 32Kb बफर आकार केवल निर्देशिका में प्रविष्टियों के एक अंश को शामिल करने के लिए पर्याप्त है। यह रेडीयर को बार-बार लूप करने का कारण बनता है और महंगी प्रणाली कॉल को बार-बार लागू करता है।

उदाहरण के लिए, एक परीक्षण निर्देशिका पर मैंने 2.6 मिलियन से अधिक फाइलों के साथ बनाया, "ls -1 | wc-l" को चलाने से कई getdent सिस्टम कॉल का एक बड़ा स्ट्रेस आउटपुट दिखाई देता है।

$ strace ls -1 | wc -l
brk(0x4949000)                          = 0x4949000
getdents(3, /* 1025 entries */, 32768)  = 32752
getdents(3, /* 1024 entries */, 32768)  = 32752
getdents(3, /* 1025 entries */, 32768)  = 32760
getdents(3, /* 1025 entries */, 32768)  = 32768
brk(0)                                  = 0x4949000
brk(0x496a000)                          = 0x496a000
getdents(3, /* 1024 entries */, 32768)  = 32752
getdents(3, /* 1026 entries */, 32768)  = 32760
...

इसके अतिरिक्त इस निर्देशिका में बिताया गया समय महत्वपूर्ण था।

$ time ls -1 | wc -l
2616044

real    0m20.609s
user    0m16.241s
sys 0m3.639s

इसे और अधिक कुशल प्रक्रिया बनाने की विधि है कि ज्यादा बड़े बफर के साथ मैन्युअल रूप से कॉल किया जाए। इससे प्रदर्शन में काफी सुधार होता है।

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

यह इन फ़ाइलों को लाने में लगने वाले समय को काफी कम कर देता है। मैंने एक प्रोग्राम लिखा जो ऐसा करता है।

/* I can be compiled with the command "gcc -o dentls dentls.c" */

#define _GNU_SOURCE

#include <dirent.h>     /* Defines DT_* constants */
#include <err.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

struct linux_dirent {
        long           d_ino;
        off_t          d_off;
        unsigned short d_reclen;
        char           d_name[256];
        char           d_type;
};

static int delete = 0;
char *path = NULL;

static void parse_config(
        int argc,
        char **argv)
{
    int option_idx = 0;
    static struct option loptions[] = {
      { "delete", no_argument, &delete, 1 },
      { "help", no_argument, NULL, 'h' },
      { 0, 0, 0, 0 }
    };

    while (1) {
        int c = getopt_long(argc, argv, "h", loptions, &option_idx);
        if (c < 0)
            break;

        switch(c) {
          case 0: {
              break;
          }

          case 'h': {
              printf("Usage: %s [--delete] DIRECTORY\n"
                     "List/Delete files in DIRECTORY.\n"
                     "Example %s --delete /var/spool/postfix/deferred\n",
                     argv[0], argv[0]);
              exit(0);                      
              break;
          }

          default:
          break;
        }
    }

    if (optind >= argc)
      errx(EXIT_FAILURE, "Must supply a valid directory\n");

    path = argv[optind];
}

int main(
    int argc,
    char** argv)
{

    parse_config(argc, argv);

    int totalfiles = 0;
    int dirfd = -1;
    int offset = 0;
    int bufcount = 0;
    void *buffer = NULL;
    char *d_type;
    struct linux_dirent *dent = NULL;
    struct stat dstat;

    /* Standard sanity checking stuff */
    if (access(path, R_OK) < 0) 
        err(EXIT_FAILURE, "Could not access directory");

    if (lstat(path, &dstat) < 0) 
        err(EXIT_FAILURE, "Unable to lstat path");

    if (!S_ISDIR(dstat.st_mode))
        errx(EXIT_FAILURE, "The path %s is not a directory.\n", path);

    /* Allocate a buffer of equal size to the directory to store dents */
    if ((buffer = calloc(dstat.st_size*3, 1)) == NULL)
        err(EXIT_FAILURE, "Buffer allocation failure");

    /* Open the directory */
    if ((dirfd = open(path, O_RDONLY)) < 0) 
        err(EXIT_FAILURE, "Open error");

    /* Switch directories */
    fchdir(dirfd);

    if (delete) {
        printf("Deleting files in ");
        for (int i=5; i > 0; i--) {
            printf("%u. . . ", i);
            fflush(stdout);
            sleep(1);
        }
        printf("\n");
    }

    while (bufcount = syscall(SYS_getdents, dirfd, buffer, dstat.st_size*3)) {
        offset = 0;
        dent = buffer;
        while (offset < bufcount) {
            /* Don't print thisdir and parent dir */
            if (!((strcmp(".",dent->d_name) == 0) || (strcmp("..",dent->d_name) == 0))) {
                d_type = (char *)dent + dent->d_reclen-1;
                /* Only print files */
                if (*d_type == DT_REG) {
                    printf ("%s\n", dent->d_name);
                    if (delete) {
                        if (unlink(dent->d_name) < 0)
                            warn("Cannot delete file \"%s\"", dent->d_name);
                    }
                    totalfiles++;
                }
            }
            offset += dent->d_reclen;
            dent = buffer + offset;
        }
    }
    fprintf(stderr, "Total files: %d\n", totalfiles);
    close(dirfd);
    free(buffer);

    exit(0);
}

जब तक यह अंतर्निहित मूलभूत समस्या (बहुत सारी फाइलें, एक फाइल सिस्टम में खराब प्रदर्शन करने वाली) का मुकाबला नहीं करता है। यह बहुत अधिक होने की संभावना है, बहुत से विकल्प पोस्ट किए जा रहे हैं।

एक विचार के रूप में, किसी को प्रभावित निर्देशिका को हटा देना चाहिए और उसके बाद उसका रीमेक बनाना चाहिए। निर्देशिकाएं केवल आकार में वृद्धि करती हैं और निर्देशिका के आकार के कारण कुछ फाइलों के साथ भी खराब प्रदर्शन कर सकती हैं।

संपादित करें: मैंने इसे काफी साफ किया है। आपको रनटाइम पर कमांड लाइन पर हटाने की अनुमति देने के लिए एक विकल्प जोड़ा गया और ट्रेवेल सामान का एक गुच्छा हटा दिया गया, जो ईमानदारी से पीछे मुड़कर देखना सबसे अच्छा था। स्मृति भ्रष्टाचार का उत्पादन करने के लिए भी दिखाया गया था।

अब आप कर सकते हैं dentls --delete /my/path

नए परिणाम। 1.82 मिलियन फ़ाइलों वाली निर्देशिका के आधार पर।

## Ideal ls Uncached
$ time ls -u1 data >/dev/null

real    0m44.948s
user    0m1.737s
sys 0m22.000s

## Ideal ls Cached
$ time ls -u1 data >/dev/null

real    0m46.012s
user    0m1.746s
sys 0m21.805s


### dentls uncached
$ time ./dentls data >/dev/null
Total files: 1819292

real    0m1.608s
user    0m0.059s
sys 0m0.791s

## dentls cached
$ time ./dentls data >/dev/null
Total files: 1819292

real    0m0.771s
user    0m0.057s
sys 0m0.711s

क्या यह अभी भी इतनी अच्छी तरह से काम करता है आश्चर्यचकित था!


1
दो छोटी चिंताएँ: एक, [256]शायद [FILENAME_MAX]और दो, मेरी लिनक्स (२.६.१ 5. == सेंटोस ५x) को dirent में d_type प्रविष्टि (कम से कम getdents (२)) के अनुसार शामिल नहीं लगती है।
बीएमडीएन

1
क्या आप कृपया btree रीबैलेंसिंग पर थोड़ा विस्तार कर सकते हैं और क्रम में विलोपन इसे रोकने में मदद क्यों करता है? मैंने इसके लिए Googling की कोशिश की, दुर्भाग्य से कोई फायदा नहीं हुआ।
ओगगोलोविन

1
क्योंकि अब मुझे यह प्रतीत होता है कि यदि हम इन-ऑर्डर को हटा रहे हैं, तो हम पुनर्संतुलन के लिए बाध्य करते हैं, क्योंकि हम पत्तियों को एक तरफ से हटाते हैं और दूसरे पर छोड़ते हैं: en.wikipedia.org/wiki/B-tree#Rebalancing_after-deletion
ovgolovin

1
मुझे आशा है कि मैं आपको इस मामले से परेशान नहीं करूंगा। लेकिन फिर भी मैंने फाइलों को इन-ऑर्डर स्टैकओवरफ़्लो / q / 17955459 / 862380 को हटाने के बारे में एक सवाल शुरू किया , जो लगता है कि एक जवाब नहीं मिलता है जो इस मुद्दे को उदाहरण के साथ समझाएगा, जो सामान्य प्रोग्रामर के लिए समझ में आएगा। यदि आपके पास समय है और ऐसा लगता है, तो क्या आप इस पर गौर कर सकते हैं? शायद आप एक बेहतर स्पष्टीकरण लिख सकते हैं।
Ovgolovin

2
यह कोड का एक अद्भुत टुकड़ा है। यह एकमात्र उपकरण था जो मैं 11,000,000 (ग्यारह मिलियन) सत्र फ़ाइलों को सूचीबद्ध करने और हटाने में सक्षम हो सकता था, जो कि कुछ वर्षों में एक निर्देशिका में निर्मित हुए थे। Plesk प्रक्रिया जो उन्हें अन्य उत्तरों में खोज और अन्य चालों का उपयोग करके नियंत्रण में रखने वाली थी, एक रन पूरा करने में असमर्थ थी, इसलिए फाइलें बस निर्माण करती रहीं। यह बाइनरी ट्री के लिए एक श्रद्धांजलि है जिसे फाइलसिस्टम डायरेक्टरी को स्टोर करने के लिए उपयोग करता है, जो सत्र बिल्कुल काम करने में सक्षम थे - आप एक फ़ाइल बना सकते हैं और इसे बिना किसी देरी के पुनः प्राप्त कर सकते हैं। बस लिस्टिंग बेकार थी।
जेसन

31

क्या इस फ़ाइल सिस्टम से अन्य फ़ाइलों का सभी बैकअप एक अस्थायी स्टोरेज लोकेशन, पार्टीशन में सुधार और फिर फ़ाइलों को पुनर्स्थापित करना संभव होगा?


3
मुझे वास्तव में यह उत्तर पसंद है। एक व्यावहारिक मामले के रूप में, इस मामले में, नहीं, लेकिन यह एक ऐसा नहीं है जिसके बारे में मैंने सोचा होगा। वाहवाही!
BMDAN

बिल्कुल वही जो मैं भी सोच रहा था। यह प्रश्न 3 का उत्तर है। आदर्श यदि आप मुझसे पूछें :)
जोशुआ

12

Ext3 में प्रति डायरेक्टरी फ़ाइल की कोई सीमा नहीं है। फाइलसिस्टम इनोड लिमिट (मुझे लगता है कि हालांकि सबडायरेक्ट की संख्या पर एक सीमा है)।

फ़ाइलों को हटाने के बाद भी आपको समस्याएँ हो सकती हैं।

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


वास्तव में, मैंने सब कुछ हटाने के बाद बस इस व्यवहार को देखा। सौभाग्य से, हमने पहले ही निर्देशिका को "आग की रेखा" से बाहर कर दिया था, जैसा कि यह था, इसलिए मैं इसे फिर से याद कर सकता था।
BMDAN

2
उस ने कहा, अगर कोई प्रति-निर्देशिका फ़ाइल सीमा नहीं है, तो मुझे "ext3_dx_add_entry" निर्देशिका सूचकांक पूर्ण क्यों मिला! " जब उस विभाजन पर अभी भी इनोड उपलब्ध थे? इस निर्देशिका के अंदर कोई उपनिर्देशिका नहीं थीं।
BMDAN

3
हम्म मैं एक छोटे से अधिक शोध किया था और ऐसा लगता है कि एक निर्देशिका लेने वाले ब्लॉक की संख्या की सीमा हो सकती है। फाइलों की सही संख्या कुछ चीजों पर निर्भर है, जैसे फ़ाइल नाम लंबाई। यह gossamer-threads.com/lists/linux/kernel/921942 इंगित करता है कि 4k ब्लॉक के साथ आपको एक निर्देशिका में 8 मिलियन से अधिक फाइलें रखने में सक्षम होना चाहिए। क्या वे विशेष रूप से लंबे फ़ाइल नाम थे?
एलेक्स जे। रॉबर्ट्स

प्रत्येक फ़ाइलनाम वास्तव में 36 वर्ण लंबा था।
BMDAN

अच्छी तरह से मुझे विचारों से बाहर है :)
एलेक्स जे। रॉबर्ट्स


4

ऊपर दिए गए उपयोगकर्ताओं द्वारा सुझाए अनुसार ext3 fs के मापदंडों को बदलने के बाद भी बस मेरे लिए काम नहीं किया। बहुत ज्यादा मेमोरी वाला तरीका। इस PHP स्क्रिप्ट ने चाल चली - तेज, तुच्छ CPU उपयोग, महत्वहीन स्मृति उपयोग:

<?php 
$dir = '/directory/in/question';
$dh = opendir($dir)) { 
while (($file = readdir($dh)) !== false) { 
    unlink($dir . '/' . $file); 
} 
closedir($dh); 
?>

मैंने इस मुसीबत के बारे में एक बग रिपोर्ट पोस्ट की है: http://savannah.gnu.org/bugs/?31961


इसने मुझे बचाया !!
jestro

3

मुझे हाल ही में इसी तरह के मुद्दे का सामना करना पड़ा और काम करने के लिए ring0 के data=writebackसुझाव को प्राप्त करने में असमर्थ था (संभवतः इस तथ्य के कारण कि फाइलें मेरे मुख्य विभाजन पर हैं)। वर्कअराउंड पर शोध करते समय मैं इस पर लड़खड़ाया:

tune2fs -O ^has_journal <device>

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


मैं मेटाडेटा ऑप्स की पत्रकारिता से बचने के लिए, इसे ext3 के बजाय ext2 के रूप में माउंट करने का सुझाव देने जा रहा था। ऐसा ही करना चाहिए।
पीटर कॉर्डेस

3

सुनिश्चित करें कि आप करते हैं:

mount -o remount,rw,noatime,nodiratime /mountpoint

जो चीजों को थोड़ा और तेज करना चाहिए।


4
अच्छी कॉल, लेकिन यह पहले से ही घुड़सवार है, जैसा कि मैंने हेडर में सवाल किया था। और नोडियोटाइम निरर्थक है; lwn.net/Articles/245002 देखें ।
बीएमडीएन

1
पीपीएल इस मंत्र को दोहराते हैं "नटाइम, नॉडिर्माइम, नोडवेटाइम, नॉरएडिंगडॉस्कैटाइम"
पूजन

2

ls बहुत धीमी कमांड। प्रयत्न, कोशिश:

find /dir_to_delete ! -iname "*.png" -type f -delete

rm -rf एक और डेढ़ दिन तक चला, और मैंने आखिरकार इसे मार डाला, बिना यह जाने कि क्या यह वास्तव में कुछ भी पूरा कर चुका है। मुझे एक प्रगति पट्टी की आवश्यकता थी।
BMDAN

4
Rm बहुत धीमी गति से होने के कारण, 30k फ़ाइलों पर "टाइम ढूंढे-हटाएं": 0m0.357s / 0m0.019s / 0m0.337s वास्तविक / उपयोगकर्ता / sys। "समय (ls -1U | xargs rm -f)" उन्हीं फाइलों पर: 0m0.366s / 0m0.025s / 0m0.340s। जो मूल रूप से मार्जिन ऑफ एरर है।
BMDAN

1
आप strace -r -p <pid of rm>पहले से ही चल रहे आरएम प्रक्रिया से जुड़ने के लिए दौड़ सकते हैं। फिर आप देख सकते हैं कि कितनी तेजी से unlinkसिस्टम कॉल अतीत को स्क्रॉल कर रहे हैं। ( -rपिछली पंक्ति को हर पंक्ति के प्रारंभ में कॉल करने के बाद से समय देता है।)
पीटर कॉर्डेस

2

है dir_indexफाइल सिस्टम के लिए सेट? ( tune2fs -l | grep dir_index) यदि नहीं, तो इसे सक्षम करें। यह आमतौर पर नए आरएचईएल के लिए है।


1
हाँ, यह सक्षम है, लेकिन भयानक सुझाव!
बीएमडीएन

2

कुछ साल पहले, मुझे फाइल सिस्टम में 16 मिलियन XML फाइलों के साथ एक निर्देशिका मिली /। सर्वर की आलोचना के कारण, हमने निम्नलिखित कमांड का उपयोग किया जिसे समाप्त होने में लगभग 30 घंटे लगे :

perl -e 'for(<*>){((stat)[9]<(unlink))}'

यह एक पुराना 7200 आरपीएम एचडीडी था, और आईओ टोंटी और सीपीयू स्पाइक्स के बावजूद, पुराने वेबसर्वर ने अपनी सेवा जारी रखी।


1

मेरा पसंदीदा विकल्प नयाफ्स दृष्टिकोण है, जो पहले से ही सुझाया गया है। मूल समस्या, फिर से पहले से ही उल्लेख किया गया है, हटाने को संभालने के लिए रैखिक स्कैन समस्याग्रस्त है।

rm -rfएक स्थानीय फाइल सिस्टम के लिए इष्टतम के पास होना चाहिए (NFS अलग होगा)। लेकिन लाखों फाइलों में, प्रति फ़ाइल नाम 36 बाइट्स और 4 इनोड (एक अनुमान, ext3 के लिए मूल्य की जांच नहीं करना), यह 40 * लाखों है, केवल डायरेक्टरी के लिए रैम में रखा जाना चाहिए।

एक अनुमान के अनुसार, आप लिनक्स में फाइल सिस्टम मेटाडेटा कैश मेमोरी को जोर से दबा रहे हैं, ताकि निर्देशिका फ़ाइल के एक पृष्ठ के लिए ब्लॉक किया जा रहा है, जबकि आप अभी भी दूसरे भाग का उपयोग कर रहे हैं, केवल कैश के उस पृष्ठ को फिर से हिट करने के लिए जब अगला फ़ाइल हटा दी गई है। लिनक्स प्रदर्शन ट्यूनिंग मेरा क्षेत्र नहीं है, लेकिन / proc / sys / {vm, fs} / शायद कुछ प्रासंगिक है।

यदि आप डाउनटाइम खर्च कर सकते हैं, तो आप dir_index सुविधा को चालू करने पर विचार कर सकते हैं। यह बड़ी निर्देशिकाओं (हैशेड बी-ट्री) में विलोपन के लिए निर्देशिका सूचकांक को रैखिक से कुछ अधिक इष्टतम पर स्विच करता है। tune2fs -O dir_index ...इसके बाद e2fsck -Dकाम करेगा। हालाँकि, जब मुझे विश्वास है कि इससे पहले कि समस्याएँ हैं, मुझे पता नहीं है कि -Dमौजूदा v.large निर्देशिका के साथ काम करते समय रूपांतरण (e2fsck के साथ ) कैसे करता है। बैकअप + चूसना-और-देखना।


1
pubbs.net/201008/squid/… पता चलता है कि /proc/sys/fs/vfs_cache_pressureउपयोग करने के लिए मूल्य हो सकता है, लेकिन मुझे नहीं पता कि क्या निर्देशिका स्वयं पेज कैश की ओर गिना जाता है (क्योंकि यही है) या इनोड कैश (क्योंकि, नहीं होने के बावजूद) इनोड, यह एफएस मेटाडेटा है और उस कारण से इसमें बंडल किया गया है)। जैसा कि मैं कहता हूं, लिनक्स वीएम ट्यूनिंग मेरा क्षेत्र नहीं है। खेलो और देखो क्या मदद करता है।
फिल पी।

1

जाहिर है कि यहां सेब नहीं हैं, लेकिन मैंने थोड़ा परीक्षण किया और निम्नलिखित किया:

एक निर्देशिका ( ddऔर /dev/urandomएक लूप में) में 100,000 512-बाइट फ़ाइलें बनाई गईं ; इसे भूल गए, लेकिन उन फाइलों को बनाने में लगभग 15 मिनट का समय लगा।

कहा फ़ाइलों को हटाने के लिए निम्नलिखित भाग गया:

ls -1 | wc -l && time find . -type f -delete

100000

real    0m4.208s
user    0m0.270s
sys     0m3.930s 

यह एक पेंटियम 4 2.8GHz बॉक्स (युगल सौ GB IDE 7200 RPM मुझे लगता है; EXT3) है। कर्नेल 2.6.27।


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

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

1
rm धीमा होगा क्योंकि यह नाम से एक फ़ाइल की तलाश कर रहा है, जिसका अर्थ है कि जब तक यह नहीं मिल जाता है तब तक एक-एक करके निर्देशिका प्रविष्टियों के माध्यम से पुनरावृत्ति करता है। इस मामले में, हालांकि, चूंकि प्रत्येक प्रविष्टि दी जा रही है (उस बिंदु पर) सूची में पहला (ls -U / ls -f), यह लगभग उतना ही तेज़ होना चाहिए । उस ने कहा, rm -rf <dir>, जिसे एक विजेता की तरह चलना चाहिए था, वह धीमी गति से हो सकता था। शायद यह बड़े पैमाने पर हटाए जाने की गति के लिए कोरूटिल्स पर एक पैच लिखने का समय है? शायद यह rm -rf को लागू करने के लिए कुछ पुनरावर्ती तरीके से चुपके से गोलाबारी / छँटाई कर रहा है? इस तरह की अनिश्चितताओं के कारण मैंने सवाल पूछा है। ;)
बीएमडीएन

1
निर्माण चरण चलाने के बाद मशीन को रिबूट करें। आपको एक बिल्कुल धीमा हटाना चाहिए।
मैट

1

कभी-कभी पर्ल इस तरह के मामलों में अद्भुत काम कर सकते हैं। क्या आपने पहले से ही कोशिश की है अगर एक छोटी स्क्रिप्ट जैसे कि यह बैश और बेसिक शेल कमांड को बेहतर बना सकती है?

#!/usr/bin/perl 
open(ANNOYINGDIR,"/path/to/your/directory");
@files = grep("/*\.png/", readdir(ANNOYINGDIR));
close(ANNOYINGDIR);

for (@files) {
    printf "Deleting %s\n",$_;
    unlink $_;
}

या एक और, शायद और भी तेज, पर्ल दृष्टिकोण:

#!/usr/bin/perl
unlink(glob("/path/to/your/directory/*.png")) or die("Could not delete files, this happened: $!");

संपादित करें: मैंने अभी अपनी पर्ल स्क्रिप्ट को आज़माया है। अधिक क्रिया एक सही कुछ करता है। मेरे मामले में मैंने 256 एमबी रैम और आधा मिलियन फाइलों के साथ एक वर्चुअल सर्वर के साथ यह कोशिश की।

time find /test/directory | xargs rm परिणाम:

real    2m27.631s
user    0m1.088s
sys     0m13.229s

की तुलना में

time perl -e 'opendir(FOO,"./"); @files = readdir(FOO); closedir(FOO); for (@files) { unlink $_; }'

real    0m59.042s
user    0m0.888s
sys     0m18.737s

मैं कल्पना करने में संकोच करता हूं कि उस ग्लोब () कॉल क्या करेगा; मुझे लगता है कि यह एक स्कैंडिर () करता है। यदि ऐसा है, तो लौटने के लिए हमेशा के लिए ले जा रहा है। पहले सुझाव का एक संशोधन जो सभी डीआईआर प्रविष्टियों को पूर्व-पढ़ा नहीं करता है, उसमें कुछ पैर हो सकते हैं; हालाँकि, अपने वर्तमान स्वरूप में, यह, केवल एक बार में सभी निर्देशिका प्रविष्टियों को पढ़ने पर CPU की अपवित्र राशि का उपयोग करेगा। यहाँ लक्ष्य का हिस्सा विभाजित करना और जीतना है; यह कोड मौलिक रूप से 'rm -f * .png' से अलग नहीं है, शेल विस्तार के साथ कोई समस्या नहीं है। यदि यह मदद करता है, तो निर्देशिका में कुछ भी नहीं है जिसे मैं हटाना नहीं चाहता था
बीएमडीएन

मुझे काम मिलते ही ज्यादा कोशिश करनी चाहिए। मैंने सिर्फ एक निर्देशिका में 100 000 फाइलें बनाने और + xargs + rm संयोजन को 7.3 सेकंड, पर्ल + अनलिंक (ग्लोब) ... संयोजन को 2.7 सेकंड में समाप्त करने की कोशिश की। उस समय की कोशिश की, परिणाम हमेशा एक ही था। काम पर मैं इसे और अधिक फ़ाइलों के साथ कोशिश करूँगा।
जने पिक्कारेनैन

मैंने यह परीक्षण करते समय कुछ नया सीखा। कम से कम ext3 और ext4 के साथ निर्देशिका प्रविष्टि स्वयं ही सभी फ़ाइलों को वहाँ से हटाने के बाद भी बहुत बड़ी बनी हुई है। कुछ परीक्षणों के बाद मेरी / tmp / परीक्षण निर्देशिका 15 MB डिस्क स्थान ले रही थी। क्या निर्देशिका को हटाने और इसे फिर से बनाने के अलावा इसे साफ करने का कोई और तरीका है?
जेन पिक्कारेनैन २

2
नहीं, आपको इसे फिर से बनाने की जरूरत है। जब मैं मेल-सिस्टम और फ़ोल्डर-प्रति-प्राप्तकर्ता और क्लीनअप से निपटता हूं तो महत्वपूर्ण मुद्दों के बाद: कोई रास्ता नहीं है, एक नई निर्देशिका बनाने के अलावा और निर्देशिका के बारे में फेरबदल करने के अलावा, पुराने को नाक में डालना। इसलिए आप समय खिड़की को कम कर सकते हैं जब कोई निर्देशिका न हो, लेकिन इसे समाप्त न करें।
फिल पी।

ध्यान दें कि ग्लोब () परिणामों को क्रमबद्ध करेगा, जितना शेल गोलाबारी सामान्य रूप से करता है, इसलिए क्योंकि आपके पास केवल 100k फाइलें हैं, सब कुछ आसानी से फिट हो जाता है और क्रम तेजी से होता है। बहुत बड़ी निर्देशिका के साथ, आप केवल इस प्रकार से बचने के लिए opendir () / readdir () / shutir () चाहते हैं। [मैं सामान्य रूप से शेल के लिए कहता हूं , क्योंकि zsh के पास क्रमबद्ध ऑर्डर को अनसोल्ड बनाने के लिए एक ग्लोब संशोधक है, जो बड़ी संख्या में फाइलों से निपटने के दौरान उपयोगी है; *(oN)]
फिल पी।

1

क्या मुझे याद है कि ext filesystems में इनोड्स को डिलीट करना O (n ^ 2) है, इसलिए जितनी ज्यादा फाइल्स आप डिलीट करेंगे उतनी ही तेजी से बाकी चीजें चली जाएंगी।

एक समय था जब मैं इसी तरह की समस्या का सामना कर रहा था (हालांकि मेरे अनुमान ~ 7h विलोपन के समय को देखते थे), अंत में पहली टिप्पणी में jftuga का सुझाव दिया मार्ग गया


0

खैर, यह असली जवाब नहीं है, लेकिन ...

क्या फाइलसिस्टम को ext4 में बदलना और देखना संभव होगा कि क्या चीजें बदल जाती हैं?


ऐसा प्रतीत होता है कि इस "लाइव" को माउंटेड फाइलसिस्टम पर एक fsck की आवश्यकता है, जो कि ... खतरनाक है। एक बेहतर तरीका है?
बीएमडीएन

फाइलसिस्टम को रूपांतरण से पहले, यानी आवश्यक ट्यूनफॉर्म्स कमांड से पहले अनमाउंट करना पड़ता है।
7

0

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

इनकोड एक मोटा अनुमान है, जो मुझे लगता है कि .. लेकिन आपके उपयोग के मामले पर आधारित है, यह काफी सटीक हो सकता है ...


1
सही होने पर मुझे सही करें, लेकिन अनलिंक (2) इनकोड शून्य नहीं करता है, यह सिर्फ डायरेक्टरी से इसका संदर्भ हटाता है। मैं इस दृष्टिकोण के chutzpah पसंद है, यद्यपि। कुछ समय-परीक्षण चलाने और यह देखने के लिए कि क्या यह सच है?
बीएमडीएन

0

मैं शायद एक सी संकलक को मार दिया था और अपनी स्क्रिप्ट के नैतिक समकक्ष किया होगा। यही है, opendir(3)एक निर्देशिका हैंडल readdir(3)प्राप्त करने के लिए उपयोग करें, फिर फ़ाइलों का नाम प्राप्त करने के लिए उपयोग करें, फिर फ़ाइलों को टैली करें क्योंकि मैं उन्हें अनलिंक करता हूं और एक बार थोड़ी देर में "% डी फाइलें हटा दी जाती हैं" (और संभवतः बीता हुआ समय या वर्तमान समय टिकट) प्रिंट करें।

मुझे उम्मीद नहीं है कि यह शेल स्क्रिप्ट संस्करण की तुलना में अधिक तेज़ होगा, यह सिर्फ इतना है कि मुझे अब और फिर से कंपाइलर को चीरने की आदत है, क्योंकि शेल से या जो मैं चाहता हूं, उसे करने का कोई साफ तरीका नहीं है। शेल में उल्लेखनीय होने के बावजूद, यह इस तरह से अनपेक्षित रूप से धीमा है।


वह कम से कम कोरोडिल्स से आरएम के स्रोत कोड को संशोधित करके शुरू कर सकता है ।
क्रिस्टियन सियुपिटु

0

आप निर्देशिका के साथ मुद्दों को फिर से लिखने की संभावना में हैं। पहले नई फ़ाइलों को हटाने का प्रयास करें। माउंट विकल्पों को देखें जो डिस्क में राइटबैक को डिफर करेगा।

एक प्रगति बार के लिए जैसे कुछ चलाने की कोशिश करें rm -rv /mystuff 2>&1 | pv -brtl > /dev/null


सबसे पहले नवीनतम फ़ाइलों को हटाने के संदर्भ में: ls -Ur? मुझे पूरा यकीन है कि वह dir प्रविष्टियों को लोड करेगा, फिर उन्हें उल्टा करेगा; मेरा मानना ​​है कि डीआईएस प्रविष्टि सूची के अंत में शुरू करने के लिए एलएस काफी स्मार्ट है और शुरुआत में वापस अपना रास्ता बनाता है। "ls -1" भी शायद एक बहुत अच्छा विचार नहीं है, क्योंकि यह संभवतः 50+ MB का कोर और कई मिनट चलने के लिए ले जाएगा; आप "ls -U" या "ls -f" चाहते हैं।
BMDAN

यह केवल व्यावहारिक है अगर फ़ाइल नाम प्रेडिक्टेबल पैटर्न में बढ़ता है। हालाँकि आप मेरी कोशिश ls -1 को रिवर्स करने के लिए पाइप करते हैं, और xargs पर पाइप करते हैं। यदि आप अपने मध्यवर्ती परिणाम देखना चाहते हैं, तो पाइप के बजाय फ़ाइलों का उपयोग करें। आपने फ़ाइल नाम पर कोई जानकारी नहीं दी है। आप पैटर्न का उपयोग करके फाइल को रिवर्स में डिलीट करेंगे और फाइल को डिलीट करेंगे। आपको लापता फ़ाइल प्रविष्टियों को संभालने की आवश्यकता हो सकती है। आवश्यक स्मृति पर आपकी टिप्पणी को देखते हुए, आपके पास निर्देशिका को फिर से लिखने के लिए I / O का विचार है।
बिलथोर

0

यहां बताया गया है कि मैं लाखों ट्रेस फ़ाइलों को कैसे हटाता हूं जो कभी-कभी बड़े ओरेकल डेटाबेस सर्वर पर इकट्ठा हो सकते हैं:

for i in /u*/app/*/diag/*/*/*/trace/*.tr? ; do rm $i; echo -n . ;  done

मुझे लगता है कि यह काफी धीमी गति से विलोपन का परिणाम है जो सर्वर के प्रदर्शन पर कम प्रभाव डालता है, आमतौर पर "ठेठ" 10,000 IOPS सेटअप पर प्रति मिलियन फ़ाइलों की एक घंटे की तर्ज पर कुछ होता है।

निर्देशिकाओं को स्कैन किए जाने से पहले, आरंभिक फ़ाइल सूची उत्पन्न होने और पहली फ़ाइल हटा दिए जाने में अक्सर कई मिनट लगेंगे। वहीं से और ए। हटाए गए हर फ़ाइल के लिए प्रतिध्वनित होता है।

विलम्ब से प्रगति करते समय टर्मिनल पर गूँज के कारण होने वाली देरी किसी भी महत्वपूर्ण भार को रोकने के लिए पर्याप्त देरी साबित हुई है।


आपको ग्लोबिंग करके जिंदा खाया जा रहा है। कैसे के बारे में कुछ और अधिक की तरह find /u* -maxdepth 3 -mindepth 3 -type d -path '*/app/*' -name diag -print0 | xargs -0I = find = -mindepth 4 -maxdepth 4 -type d -name 'trace' -print0 | xargs -0I = find = -mindepth 1 -maxdepth 1 -name '*.tr':? -deleteवास्तव में चीजों को हटाने के लिए पिछले एक में जोड़ें ; जैसा कि लिखा गया है, यह सिर्फ यह बताता है कि यह क्या हटाएगा। ध्यान दें कि यह उन परिस्थितियों के लिए अनुकूलित है जहां आपके पास पास की निर्देशिकाओं में बहुत सी अनर्गल चीजें हैं; यदि ऐसा नहीं है, तो आप तर्क को बहुत हद तक सरल कर सकते हैं।
BMDan

ढूँढें -टेली बहुत ज्यादा I / O पैदा करता है और उत्पादन प्रदर्शन को आसानी से प्रभावित करता है। शायद आयनिस के साथ।
रॉय

यह सब है कि मैं / ओ बस अधिक कुशल होने के कारण, हालांकि! ग्लोबिंग आपके उदाहरण के लिए सभी फ्रंट-लोडेड है (अर्थात, फ़ाइलों की पूरी सूची पहले होने से पहले उत्पन्न rmहोती है), इसलिए आपके पास स्टार्टअप में अपेक्षाकृत कुशल I / O है, उसके बाद दर्दनाक, आउट-ऑफ-ऑर्डर rms संभवत: इससे I / O का कारण नहीं बनता है, लेकिन scandirनिर्देशिका को बार-बार चलना शामिल है (I / O के कारण नहीं क्योंकि यह पहले से ही ब्लॉक कैश में लोड किया गया है; देखें vfs_cache_pressure)। यदि आप चीजों को धीमा करना चाहते हैं, ioniceतो एक विकल्प है, लेकिन मैं शायद आंशिक-सेकेंड का उपयोग करूंगा sleep
बीएमडीएन

find /u*/app/*/diag -path '*/trace/*.tr' -execdir rm {} +rmप्रति निर्देशिका में एक चलेगा , इसलिए आपके पास सीपीयू ओवरहेड कम होगा। जब तक आपके पास rmहर समय unlinkकाम के लिए पूरी प्रक्रिया को रोककर डिस्क आईओ को खाली करने, थ्रॉटलिंग करने के लिए सीपीयू समय होता है , मुझे लगता है, लेकिन यह बदसूरत है। एक नींद के साथ perl प्रति अनलिंक अच्छा होगा अगर rmएक समय में पूरी निर्देशिकाओं के बीच सो रहा हो तो वह बहुत अधिक फट जाता है। ( -execdir sh -c ...हो सकता है)
पीटर कॉर्ड्स

-1

आप 'xargs' समानांतरण सुविधाओं का उपयोग कर सकते हैं:

ls -1|xargs -P nb_concurrent_jobs -n nb_files_by_job rm -rf

1
यह मदद नहीं करेगा। अड़चन ड्राइव पर खराब यादृच्छिक I / O है। समानांतर डिलीट करने से यह और भी खराब हो सकता है और बस सीपीयू लोड बढ़ा सकता है।
विम केरखॉफ

-2
ls|cut -c -4|sort|uniq|awk '{ print "rm -rf " $1 }' | sh -x

1
वाह। मुझे लगता है कि "स्किन टू ए कैट 'कैंप में बहुत मजबूती से गिरता है। गंभीरता से, हालांकि, सॉर्ट और यूनीक के साथ? डिफ़ॉल्ट रूप से "ls" प्रकार, और मुझे यकीन है कि फ़ाइलनाम अद्वितीय हैं। : /
BMDAN

-2

वास्तव में, यह एक छोटा सा बेहतर है यदि आप जिस शेल का उपयोग करते हैं वह कमांड लाइन विस्तार करता है:

ls|cut -c -4|sort|uniq|awk '{ print "echo " $1 ";rm -rf " $1 "*"}' |sh
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.