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


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

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

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

    ऐसा लगता है कि यह काम कर रहा है। जैसा कि मैंने यह लिखा है, इसने पिछले तीस मिनट में 260,000 फाइलें हटा दी हैं।


    97
    2017-09-22 23:57


    मूल


    आरएम (जीएनयू कोर्यूटिल्स) 8.4 में यह विकल्प है: "-v, --verbose समझाओ कि क्या किया जा रहा है"। यह हटाए जा रहे सभी फाइलों को प्रदर्शित करेगा। - Cristian Ciupitu
    दरअसल, यह प्रगति पट्टी करने का एक साफ तरीका होगा: चूंकि प्रत्येक फ़ाइल तीस-सात वर्ण लंबी होगी (36 + ए '\ n'), मैं इसके लिए आसानी से एक पार्सर लिख सकता हूं, और चूंकि printf () है सस्ते और आरएम कमांड में पहले से लोड की गई फ़ाइल का नाम है, कोई विशेष प्रदर्शन जुर्माना नहीं है। पूरे शेबांग करने के लिए एक गैर स्टार्टर की तरह लगता है, क्योंकि मैं कभी भी ऐसा कुछ करने के लिए "आरएम" नहीं प्राप्त कर सकता था। लेकिन यह एक इंट्रा-10,000 प्रगति पट्टी के रूप में काफी अच्छी तरह से काम कर सकता है; शायद एक "।" हर सौ फाइलों के लिए? - BMDan
    rm -rfv | pv -l >/dev/null। पीवी में उपलब्ध होना चाहिए EPEL भंडार। - Cristian Ciupitu
    पीवी भारी कमाल है। मैं अपने जागने में पीवी इंस्टॉलेशन का निशान छोड़ देता हूं। - BMDan
    मेरे पास हाल ही में एक ही समस्या थी। धन्यवाद! - richo


    जवाब:


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

    इसके अनुसार यह पन्ना,

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

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


    30
    2017-09-26 05:49



    वह समय भी बढ़ा सकता है commit  विकल्प: "यह डिफ़ॉल्ट मान (या कोई कम मूल्य) प्रदर्शन को नुकसान पहुंचाएगा, लेकिन यह डेटा-सुरक्षा के लिए अच्छा है। इसे 0 पर सेट करना उसी पर प्रभाव डालेगा जैसे इसे डिफ़ॉल्ट (5 सेकंड) पर छोड़ दिया जाता है। इसे बहुत बड़े मानों पर सेट करना होगा प्रदर्शन सुधारना"। - Cristian Ciupitu
    मैं जिस दस्तावेज को देख रहा था उसे छोड़कर, लिखना तारकीय दिखता है (gentoo.org/doc/en/articles/l-afig-p8.xml#doc_chap4) स्पष्ट रूप से उल्लेख करता है कि यह अभी भी मेटाडेटा पत्रिकाओं, जो मुझे लगता है कि मैं जो डेटा बदल रहा हूं वह शामिल है (मैं निश्चित रूप से फ़ाइलों में किसी भी डेटा को नहीं बदल रहा हूं)। क्या विकल्प की मेरी समझ गलत है? - BMDan
    आखिरकार, उस लिंक में उल्लिखित एफवाईआई यह तथ्य नहीं है कि डेटा = लेखन एक बड़ा सुरक्षा छेद हो सकता है, क्योंकि किसी दिए गए प्रविष्टि द्वारा इंगित डेटा में ऐप द्वारा लिखा गया डेटा नहीं हो सकता है, जिसका अर्थ है कि एक क्रैश परिणाम हो सकता है पुराने, संभवतः संवेदनशील / निजी डेटा का खुलासा किया जा रहा है। यहां कोई चिंता नहीं है, क्योंकि हम इसे अस्थायी रूप से बदल रहे हैं, लेकिन मैं उस चेतावनी में सभी को सतर्क करना चाहता हूं, यदि आप या अन्य सुझाव जो इस सुझाव में भागते हैं, उन्हें पता नहीं था। - BMDan
    प्रतिबद्ध: यह बहुत चालाक है! सूचक के लिए धन्यवाद। - BMDan
    data=writeback मुख्य फाइल सिस्टम में लिखने से पहले अभी भी पत्रिकाओं मेटाडेटा। जैसा कि मैं इसे समझता हूं, यह सिर्फ उन सीमाओं में डेटा लिखने और डेटा लिखने जैसी चीज़ों के बीच क्रमबद्ध करने को लागू नहीं करता है। हो सकता है कि अन्य ऑर्डरिंग बाधाएं भी आराम करें, अगर आप इससे एक लाभ प्राप्त करते हैं। बेशक, जर्नल के बिना बढ़ते हुए भी उच्च प्रदर्शन हो सकता है। (यह अनलिंक सेशन पूर्ण होने से पहले डिस्क पर कुछ भी होने की आवश्यकता के बिना, रैम में मेटाडाटा परिवर्तनों को होने दे सकता है)। - Peter Cordes


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

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

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

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

    $ 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
    

    यह आश्चर्यजनक था कि यह अभी भी बहुत अच्छा काम करता है!


    73
    2017-11-06 19:06



    दो मामूली चिंताओं: एक, [256] शायद होना चाहिए [FILENAME_MAX], और दो, मेरे लिनक्स (2.6.18 == CentOS 5.x) में dire_ में एक d_type प्रविष्टि शामिल नहीं है (कम से कम गेटेंट्स (2) के अनुसार)। - BMDan
    क्या आप कृपया btree rebalancing पर थोड़ा सा विस्तार कर सकते हैं और आदेश में हटाने से इसे रोकने में मदद मिलती है? मैंने इसके लिए गुगलिंग की कोशिश की, दुर्भाग्य से कोई फायदा नहीं हुआ। - ovgolovin
    क्योंकि अब मुझे लगता है कि अगर हम इन-ऑर्डर को हटा रहे हैं, तो हम रीबैलेंसेंसिंग को मजबूर करते हैं, क्योंकि हम एक तरफ पत्तियों को हटाते हैं और दूसरे पर जाते हैं: en.wikipedia.org/wiki/B-tree#Rebalancing_after_deletion - ovgolovin
    मुझे उम्मीद है कि मैं आपको इस मामले से परेशान नहीं करता हूं। लेकिन फिर भी मैंने फ़ाइलों को इन-ऑर्डर हटाने के बारे में एक प्रश्न शुरू किया stackoverflow.com/q/17955459/862380, जो ऐसा उत्तर नहीं प्राप्त करता है जो उदाहरण के साथ इस मुद्दे को समझाएगा, जो सामान्य प्रोग्रामर के लिए समझा जा सकता है। यदि आपके पास समय है और ऐसा लगता है, तो क्या आप इसे देख सकते हैं? शायद आप एक बेहतर स्पष्टीकरण लिख सकते हैं। - ovgolovin
    यह कोड का एक अद्भुत टुकड़ा है। यह एकमात्र ऐसा टूल था जिसे मैं कुछ 11,000,000 (ग्यारह मिलियन) सत्र फ़ाइलों को सूचीबद्ध और हटाने में सक्षम था जो शायद कुछ वर्षों में निर्देशिका में बनाया गया था। Plesk प्रक्रिया जिसे उन्हें अन्य उत्तरों में ढूंढने और अन्य युक्तियों का उपयोग करके नियंत्रण में रखना था, एक रन को पूरा करने में असमर्थ था, इसलिए फाइलें अभी भी बना रही थीं। यह बाइनरी पेड़ को श्रद्धांजलि है कि फाइल सिस्टम निर्देशिका को स्टोर करने के लिए उपयोग करता है, कि सत्र बिल्कुल काम करने में सक्षम थे - आप एक फाइल बना सकते हैं और बिना किसी देरी के इसे पुनर्प्राप्त कर सकते हैं। बस लिस्टिंग अनुपयोगी थी। - Jason


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


    31
    2017-09-23 00:27



    मुझे वास्तव में यह जवाब पसंद है। एक व्यावहारिक मामले के रूप में, इस मामले में, नहीं, लेकिन यह ऐसा नहीं है जिसे मैंने सोचा होगा। वाहवाही! - BMDan
    वास्तव में मैं भी क्या सोच रहा था। यह प्रश्न 3 का उत्तर है। आदर्श अगर आप मुझसे पूछें :) - Joshua


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

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

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


    11
    2017-09-23 05:45



    दरअसल, मैंने सबकुछ हटाने के बाद ही इस व्यवहार को देखा। सौभाग्य से, हम पहले से ही "आग की रेखा" से बाहर निर्देशिका को mv'd किया था, जैसा कि यह था, तो मैं बस इसे rmdir सकता था। - BMDan
    उस ने कहा, यदि कोई प्रति-निर्देशिका फ़ाइल सीमा नहीं है, तो मुझे "ext3_dx_add_entry: निर्देशिका अनुक्रमणिका पूर्ण क्यों मिली!" जब उस विभाजन पर अभी भी इनोड उपलब्ध थे? इस निर्देशिका के अंदर कोई उपनिर्देशिका नहीं थी। - BMDan
    हम्म मैंने थोड़ा और शोध किया और ऐसा लगता है कि निर्देशिका में कितने ब्लॉक हो सकते हैं। फ़ाइलों की सटीक संख्या कुछ चीजों पर निर्भर है जैसे फाइलनाम लंबाई। इस gossamer-threads.com/lists/linux/kernel/921942 ऐसा लगता है कि 4k ब्लॉक के साथ आपको निर्देशिका में 8 मिलियन से अधिक फाइलें मिलनी चाहिए। क्या वे विशेष रूप से लंबे फ़ाइल नाम थे? - Alex J. Roberts
    प्रत्येक फ़ाइल नाम बिल्कुल 36 वर्ण लंबा था। - BMDan
    अच्छा यह मुझे विचारों से बाहर है :) - Alex J. Roberts


    मैंने इसे बेंचमार्क नहीं किया है, लेकिन इस आदमी ने किया था:

    rsync -a --delete ./emptyDirectoty/ ./hugeDirectory/
    

    5
    2018-06-04 11:52





    ऊपर दिए गए उपयोगकर्ताओं द्वारा सुझाए गए 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


    4
    2017-12-23 19:54



    यह मुझे बचाया !! - jestro


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

    tune2fs -O ^has_journal <device>
    

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


    3
    2018-04-23 22:29



    मेटाडेटा ऑप्स जर्नलिंग से बचने के लिए, मैं इसे ext3 के बजाय ext2 के रूप में आरोहित करने का सुझाव देने जा रहा था। यह वही करना चाहिए। - Peter Cordes


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

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

    जो चीजों को थोड़ा सा गति देना चाहिए।


    3
    2017-09-27 02:03



    अच्छा कॉल, लेकिन यह पहले से ही घुमावदार है, जैसा कि मैंने प्रश्न के शीर्षलेख में उल्लेख किया है। और nodiratime अनावश्यक है; देख lwn.net/Articles/245002 । - BMDan
    पीपीएल इस मंत्र को दोहराएं "नोटाइम, नोडीरटाइम, nodevatime, noreadingdocsatime" - poige


    बहुत धीमी कमांड। प्रयत्न:

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

    2
    2017-09-23 04:04



    आरएम-आरएफ डेढ़ साल तक दौड़ गया, और आखिरकार मैंने इसे मार डाला, बिना यह जानने के कि क्या उसने वास्तव में कुछ हासिल किया था। मुझे एक प्रगति पट्टी की जरूरत थी। - BMDan
    आरएम बहुत धीमी होने के कारण, 30k फाइलों पर "समय ढूंढें। -डिलीट": 0m0.357s / 0m0.019s / 0m0.337s वास्तविक / उपयोगकर्ता / sys। "समय (ls -1U | xargs rm -f)" उन फ़ाइलों पर: 0m0.366s / 0m0.025s / 0m0.340s। जो मूल रूप से मार्जिन-एरर एरिया है। - BMDan
    आप बस दौड़ सकते थे strace -r -p <pid of rm> पहले से चल रहे आरएम प्रक्रिया से जुड़ा हुआ है। फिर आप देख सकते हैं कि कितनी तेजी से unlink सिस्टम कॉल पिछले स्क्रॉल कर रहे हैं। (-r प्रत्येक लाइन की शुरुआत में पिछले सिस्टम कॉल के बाद से समय डालता है।) - Peter Cordes


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


    2
    2017-09-27 04:18



    हाँ, यह सक्षम है, लेकिन भयानक सुझाव! - BMDan


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

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

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

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


    1
    2017-09-26 12:05



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