SSD Nodes Learn 🎉 VPS $5.50/महिन्यापासून
मार्गदर्शक Matt Connorद्वारे Matt Connor

df आणि du मध्ये फरक का? डिस्क स्पेस कशी शोधायची

तुमच्या VPS वर डिस्क फुल असूनही जागा सापडत नाहीये का? lsof कमांड वापरून हटवलेली पण प्रोसेसने धरून ठेवलेली फाईल कशी शोधायची आणि रीबूट न करता डिस्क स्पेस कशी मोकळी करायची ते शिका.

df पूर्ण का दाखवते आणि du वेगळे का दाखवते

df डिस्क पूर्ण असल्याचे दर्शवते, तर du ला ती जागा सापडत नाही कारण एका प्रक्रियेने (process) हटवलेली फाईल अजूनही धरून ठेवली आहे. फाईल हटवल्यामुळे डिरेक्टरीमधून तिचे नाव निघून जाते. जेव्हा त्या inode कडे निर्देश करणारे शेवटचे open file descriptor बंद होते, तेव्हाच डेटा ब्लॉक्स मोकळे होतात. du फक्त नावांची गणना करते, त्यामुळे त्याला काहीही सापडत नाही. df फाईलसिस्टमला विचारते की किती ब्लॉक्स वाटप केले आहेत, त्यामुळे ज्या फाईलला आता नाव नाही, ती सुद्धा त्यात मोजली जाते.

हे मार्गदर्शक एका साध्या Ubuntu VPS वर आधीच इन्स्टॉल असलेल्या टूल्सचा वापर करून ही स्थिती पुन्हा निर्माण करते, /proc द्वारे ती फाईल धरून ठेवणारी प्रक्रिया शोधते आणि रीबूट न करता जागा मोकळी करते. याच लक्षणाची इतर कारणे खालीलप्रमाणे आहेत: मोकळ्या नोंदी नसलेले inode टेबल, माऊंट पॉईंटच्या खाली दडलेल्या फाईल्स आणि root साठी राखीव ठेवलेले ब्लॉक्स.

प्रत्येक कमांड चालवा आणि स्वतःचे आउटपुट वाचा. मूल्ये तुमच्या डिस्कवर अवलंबून असतात, त्यामुळे मार्गदर्शकामध्ये छापलेल्या आकड्यांशी तुलना करण्याऐवजी तुमच्या स्वतःच्या मशीनवरील आधीची आणि नंतरची स्थिती तपासा.

df आणि du काय मोजतात

df (disk free) प्रत्येक माउंट केलेल्या फाइलसिस्टमला तिची स्वतःची माहिती विचारते: किती ब्लॉक्स अस्तित्वात आहेत, किती वाटप केले आहेत आणि किती मोकळे आहेत. हे कधीही डिरेक्टरी उघडत नाही. याचे उत्तर प्रत्येक वाटप केलेल्या ब्लॉकचा समावेश करते, ज्यामध्ये अशा फाइलचे ब्लॉक्सही असतात ज्यांचा कोणताही डिरेक्टरी एन्ट्रीशी संबंध नाही.

du (disk usage) याच्या अगदी उलट काम करते. हे तुम्ही दिलेल्या पाथपासून सुरुवात करते, डिरेक्टरी वाचते, सापडलेल्या प्रत्येक एन्ट्रीची माहिती (stats) घेते आणि ब्लॉक्सची बेरीज करते. ज्या फाइलला नाव नाही, ती याला दिसत नाही. तसेच, ज्या डिरेक्टरी वाचण्याची परवानगी नाही, ती सुद्धा याला दिसत नाही; म्हणूनच सामान्य वापरकर्त्याला root पेक्षा कमी एकूण आकार मिळतो. तुलना करण्यापूर्वी du ला sudo अंतर्गत चालवा.

तुलना करताना दोन पर्याय नेहमी महत्त्वाचे ठरतात.

  • -x हे du ला एकाच फाइलसिस्टमवर मर्यादित ठेवते. याशिवाय, du / हे / च्या खाली माउंट केलेल्या प्रत्येक फाइलसिस्टममध्ये शिरते आणि अशी बेरीज देते जी df / कधीही मोजत नव्हते.
  • -s हे प्रत्येक डिरेक्टरीसाठी एक ओळ देण्याऐवजी प्रत्येक आर्ग्युमेंटसाठी एक सारांश ओळ छापते.

यामुळे तुम्हाला हव्या असलेल्या फाइलसिस्टमवर दोन्ही कमांड्स एकत्र चालवता येतात.

df -h /
sudo du -xhs / 2>/dev/null

df त्वरित उत्तर देते. मोठ्या फाइलसिस्टमवर du ला काही मिनिटे लागतात, कारण ते वाटेतील प्रत्येक फाइलची माहिती (stats) घेते. जेव्हा दोन्ही बेरजांमध्ये खूप फरक असतो आणि du हे root म्हणून -x सह चालवले जाते, तेव्हा याचा अर्थ असा की गहाळ झालेली जागा अशा गोष्टीला वाटप केली गेली आहे ज्याला नाव नाही.

मुद्दाम विसंगती निर्माण करणे

हे एका टेस्ट VPS वर करा. खालील सर्व कमांड्स bash आणि coreutils वापरतात, त्यामुळे काहीही नवीन इन्स्टॉल करण्याची गरज नाही.

/var/tmp असलेल्या फाइलसिस्टमची सुरुवातीची स्थिती नोंदवा.

cd /var/tmp
df -h .
df --output=used -B1 .

दुसरी कमांड वापरलेली बाइट्स कोणत्याही राउंडिंगशिवाय प्रिंट करते, ज्यामुळे शेवटी केलेली तपासणी अचूक ठरते.

आता एक फाइल तयार करा. तिची साईज मशीन स्वतः रिपोर्ट करत असलेल्या मोकळ्या जागेवरून घेतली जाते, त्यामुळे हे प्रात्यक्षिक तुमच्या डिस्कच्या क्षमतेनुसार जुळवून घेते.

free=$(df --output=avail -B1 . | tail -n 1)
fallocate -l $((free / 10)) ghost.bin
ls -l ghost.bin
df -h .

$(...) हे कमांड सबस्टिट्यूशन आहे: शेल त्यातील कमांड रन करते आणि त्याचे आउटपुट free ची व्हॅल्यू बनते. जर हे सिंटॅक्स तुमच्यासाठी नवीन असेल, तर bash मधील कमांड सबस्टिट्यूशन मध्ये याची सविस्तर माहिती दिली आहे. fallocate डेटा न लिहिता प्रत्यक्ष ब्लॉक्स रिझर्व्ह करते, म्हणूनच ती लगेच पूर्ण होते. ज्या फाइलसिस्टमवर हे सपोर्टेड नाही तिथे ही कमांड फेल होते आणि head -c $((free / 10)) /dev/zero > ghost.bin हे काम बाइट्स लिहून पूर्ण करते.

या df -h . ची तुलना तुम्ही नोंदवलेल्या स्थितीशी करा. 'used' कॉलम वाढला आहे आणि 'available' कॉलम कमी झाला आहे.

आता दुसऱ्या प्रोसेसद्वारे फाइल ओपन ठेवा आणि त्यानंतर ती डिलीट करा.

sleep infinity < ghost.bin &
holder=$!
rm ghost.bin
ls -l ghost.bin
df -h .
sudo du -xhs . 2>/dev/null

ही रिडायरेक्शनची युक्ती आहे. sleep infinity < ghost.bin & एक बॅकग्राउंड प्रोसेस सुरू करते ज्याचे स्टँडर्ड इनपुट ती फाइल आहे, त्यामुळे शेल फाइल ओपन करते आणि त्याचे डिस्क्रिप्टर sleep ला देते, जे ती फाइल ओपन ठेवते. $! मध्ये त्या बॅकग्राउंड जॉबचा प्रोसेस ID साठवला जातो. त्यानंतर rm फाइलचे नाव काढून टाकते, परंतु डिस्क्रिप्टर अजूनही ओपन असतो.

आउटपुट वाचा. ls ला फाइल सापडत नाही, कारण तिचे नाव आता अस्तित्वात नाही. du पुन्हा सुरुवातीच्या स्थितीजवळ पोहोचले आहे, कारण ते नावांच्या आधारे फाइलसिस्टम स्कॅन करते. df मध्ये कोणताही बदल झालेला नाही, कारण ब्लॉक्स अजूनही अलोकेट केलेले आहेत. फाइलसिस्टम आणि डिरेक्टरी ट्री आता एकमेकांशी असहमत आहेत आणि त्यांच्यातील हा फरक म्हणजे ती फाइल आहे जी तुम्ही नुकतीच डिलीट केली आहे.

हटवलेली फाईल वापरणारी प्रक्रिया शोधा

प्रत्येक ओपन फाईल डिस्क्रिप्टर /proc/<pid>/fd/ अंतर्गत त्या फाईलचा सिम्बॉलिक लिंक म्हणून दिसतो. जेव्हा फाईल अनलिंक केली जाते, तेव्हा कर्नल त्या लिंकचे लक्ष्य 'हटवलेले' (deleted) म्हणून चिन्हांकित करते. त्यामुळे, फाईल कोण वापरत आहे हे शोधणे म्हणजे अशी लिंक शोधणे होय ज्याचे लक्ष्य हा मार्कर दर्शवते.

sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null

-lname हे सिम्बॉलिक लिंकच्या नावाऐवजी त्याच्या लक्ष्याशी जुळते, %p डिस्क्रिप्टरचा मार्ग प्रिंट करते आणि %l ते कशाकडे निर्देश करते ते प्रिंट करते. प्रिंट झालेल्या मार्गातील दुसरा घटक म्हणजे प्रोसेस आयडी (PID) असतो. हे कमांड sudo सह चालवा, अन्यथा तुम्ही फक्त तुमच्या स्वतःच्या प्रक्रियांसाठी /proc/<pid>/fd वाचू शकाल. stderr रिडायरेक्ट अशा प्रक्रियांकडून येणारा गोंधळ काढून टाकते ज्या find चालत असताना बंद होतात.

एका व्यस्त सर्व्हरवर कोणत्याही क्षणी अनेक हटवलेल्या फाईल्स असू शकतात आणि त्यातील बहुतेक लहान व निरुपद्रवी असतात. त्यांना आकारानुसार लावा जेणेकरून फक्त महत्त्वाच्या फाईल्स वरच्या बाजूला राहतील.

sudo bash -c 'for fd in /proc/[0-9]*/fd/*; do
  target=$(readlink "$fd" 2>/dev/null) || continue
  case "$target" in
    *"(deleted)") echo "$(stat -Lc %s "$fd" 2>/dev/null) $fd $target" ;;
  esac
done' | sort -rn | head

stat -L हे लिंकचा मागोवा घेऊन थेट inode पर्यंत जाते, त्यामुळे %s अशा फाईलचा आकार सांगते ज्याला आता नाव उरलेले नाही. या संख्येनुसार सॉर्ट केल्यास सर्वात मोठी फाईल प्रथम दिसते.

त्यानंतर, संबंधित डिस्क्रिप्टर वापरणारी प्रक्रिया ओळखा. त्या यादीच्या वरच्या बाजूला असलेला मार्ग तुम्हाला आवश्यक असलेले दोन्ही क्रमांक दर्शवतो, म्हणून त्यांना व्हेरिएबल्समध्ये ठेवा आणि PID व N च्या जागी तुमच्या लिस्टिंगमध्ये दिसणारे क्रमांक वापरा.

pid=PID
n=N
ps -o pid,user,etime,args -p "$pid"
sudo stat -L "/proc/$pid/fd/$n"

ps प्रोग्रामचे नाव सांगते आणि तो किती काळापासून सुरू आहे हे दर्शवते. stat -L हटवलेल्या inode चा आकार आणि वाटप केलेले ब्लॉक काउंट प्रिंट करते. एकत्रितपणे, ही माहिती महत्त्वाच्या प्रश्नाचे उत्तर देते: कोणती सेवा ही फाईल जिवंत ठेवत आहे.

जर मशीनवर आधीच lsof उपलब्ध असेल, तर sudo lsof +L1 अशा ओपन फाईल्सची यादी देते ज्यांची लिंक काउंट शून्य झाली आहे आणि त्यांचे आकार एका टेबलमध्ये दाखवते. हे किमान (minimal) Ubuntu इमेजवर उपलब्ध नसते आणि जिथे मोकळी जागा नाही अशा फाईलसिस्टमवर नवीन पॅकेज इन्स्टॉल करणे अपयशी ठरू शकते, म्हणून /proc वापरून केलेली तपासणी ही अशी आवृत्ती आहे जी नेहमी काम करते.

रीबूट न करता जागा मोकळी करणे

रीबूट केल्याने समस्या सुटते, परंतु ही पहिली पायरी म्हणून चुकीची कृती आहे: यामुळे सेवा बंद होते आणि पुराव्याचा नाश होतो. चार सौम्य पर्याय उपलब्ध आहेत, ते खालील क्रमाने वापरून पहा.

प्रथम, जर तुम्हाला डेटा हवा असेल तर तो कॉपी करून घ्या. डिस्क्रिप्टर पाथ वाचल्याने लाइव्ह inode वाचला जातो.

sudo cp /proc/<pid>/fd/<n> /root/recovered.log

ही एकमेव अशी स्थिती आहे जिथे डिलीट केलेली फाईल परत मिळवणे सोपे असते, म्हणूनच rm -rf ने डिलीट केलेल्या फाईल्स रिकव्हर करणे या प्रक्रियेत फाईल अजूनही एखाद्या प्रोसेसने उघडी ठेवली आहे का, हे विचारले जाते. एकदा शेवटचा डिस्क्रिप्टर बंद झाला की, हा मार्ग बंद होतो.

दुसरे, डिस्क्रिप्टरद्वारे फाईल रिकामी करा. /proc पाथ त्याच inode कडे नेतो, त्यामुळे ती ट्रंकेट (truncate) केल्यास प्रोसेस चालू असतानाही ब्लॉक्स मोकळे होतात.

sudo truncate -s 0 "/proc/$pid/fd/$n"
df -h /

जेव्हा रायटरने फाईल 'append' मोडमध्ये उघडली असते, तेव्हा हे उत्तम काम करते, कारण प्रत्येक राईट फाईलच्या शेवटच्या भागावर होतो. जर तसे नसेल, तर प्रोसेस आपला जुना राईट ऑफसेट कायम ठेवते, त्यामुळे पुढचा राईट फाईलमध्ये खूप पुढे होतो आणि सुरुवातीला एक 'hole' तयार होतो. 'hole' साठी जागा अलोकेट केलेली नसते, त्यामुळे ब्लॉक्स मोकळे राहतात आणि df ती जागा मोकळी ठेवते. फक्त फाईलचा आकार पुन्हा वाढलेला दिसतो: प्रोसेसने राईट केल्यानंतर पुन्हा sudo stat -L "/proc/$pid/fd/$n" चालवा, तेव्हा ते जुना आकार दाखवेल पण ब्लॉक काउंट मात्र जुळणार नाही. जर तुम्हाला आकार शून्यापासून सुरू करायचा असेल, तर प्रोसेस रीस्टार्ट करा.

तिसरे, सर्व्हिसला तिचे लॉग्स पुन्हा उघडण्यास सांगा. ज्या डेमनची लॉग फाईल डिलीट झाली आहे, ही समस्या अशा वेळी सामान्यतः उद्भवते. अनेक डेमन्स सिग्नल मिळाल्यावर लॉग फाईल्स पुन्हा उघडतात: nginx साठी SIGUSR1 आणि rsyslog साठी SIGHUP वापरले जाते. अंदाज लावण्याऐवजी संबंधित डेमनचे डॉक्युमेंटेशन तपासा, कारण चुकीच्या डेमनला चुकीचा सिग्नल पाठवल्यास तो बंद होऊ शकतो.

sudo systemctl kill -s USR1 nginx

चौथे, युनिट रीस्टार्ट करा. sudo systemctl restart <unit> जुन्या प्रोसेसने धरून ठेवलेले सर्व डिस्क्रिप्टर बंद करते, त्यामुळे ब्लॉक्स निश्चितपणे परत मिळतात. वरील उदाहरणासाठी, होल्डर एक sleep आहे जो तुम्ही स्वतः सुरू केला होता, त्यामुळे तो थांबवणे पुरेसे आहे.

kill $holder
df -h .
df --output=used -B1 .
sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null

वापरलेल्या बाइट्सची तुलना तुम्ही फाईल तयार करण्यापूर्वी नोंदवलेल्या मूल्याशी करा. ती पुन्हा जुळतात आणि find आता तुमचा डिस्क्रिप्टर दाखवत नाही. ज्या कमांडने समस्या शोधली होती, त्याच कमांडने पडताळणी करण्याची सवय लावणे फायदेशीर ठरते.

ते मूल्य बदलताना पाहणे, वारंवार हाताने df चालवण्यापेक्षा सोपे आहे. watch एका ठराविक अंतराने कमांड पुन्हा चालवते आणि आउटपुट त्याच ठिकाणी पुन्हा प्रिंट करते, त्यामुळे df वापरून watch df -h / द्वारे जागा परत येताना 'used' कॉलममध्ये होणारा बदल पाहता येतो.

जेव्हा एकूण आकडे जुळतात आणि तरीही डिस्क पूर्ण भरलेली असते

जर df आणि root du -x एकमेकांशी जुळत असतील, तर कोणतीही फाईल डिलीट झालेली नाही. उरलेली कारणे वेगळ्या प्रकारची आहेत आणि प्रत्येकाची तपासणी स्वतंत्रपणे करावी लागते.

ब्लॉक्स संपलेले नसतानाही इनोड्स (inodes) संपणे

इनोड (inode) एका फाईलची मेटाडेटा माहिती साठवते. फाईलसिस्टम तयार करताना ext4 मध्ये इनोड्सची संख्या निश्चित केली जाते, त्यामुळे फाईलसिस्टममध्ये मोकळे ब्लॉक्स असूनही इनोड्स संपू शकतात. अशा वेळी df -h मध्ये जागा दिसत असली तरी नवीन फाईल्स तयार होऊ शकत नाहीत.

df -h /
df -i /

पहिली कमांड ब्लॉक्सची गणना करते आणि दुसरी इनोड्सची. दोन्हीच्या 'use' कॉलमची तुलना करा. जर ब्लॉकचा वापर कमी असेल आणि इनोड्सचा वापर मर्यादेपर्यंत पोहोचला असेल, तर याचा अर्थ खूप मोठ्या संख्येने लहान फाईल्स तयार झाल्या आहेत.

df एकाच वेळी -i आणि --output स्वीकारत नाही, त्यामुळे जेव्हा तुम्हाला कच्ची आकडेवारी वाचण्यासाठी किंवा दुसऱ्या कमांडला देण्यासाठी हवी असते, तेव्हा इनोड फील्ड्सना नावाने निवडा आणि -i वापरू नका.

df --output=itotal,iused,iavail,ipcent /

हे कॉलम्स df -i द्वारे छापल्या जाणाऱ्या हिशोबासारखेच असतात, जे तुम्ही सहजपणे वेगळे करू शकता.

फाईल्स शोधण्यासाठी बाइट्सऐवजी एन्ट्रीजची गणना करा.

sudo du --inodes -x -d 1 / 2>/dev/null | sort -rn | head

सर्वात जास्त फाईल्स असलेल्या डिरेक्टरीवर जाऊन हीच कमांड पुन्हा चालवा, जोपर्यंत तुम्हाला फाईल्स तयार करणारा ट्री सापडत नाही. जर तुमच्या du मध्ये --inodes सपोर्ट नसेल, तर sudo find /var -xdev -type f | wc -l वापरून सबट्रीची गणना करा, ही पद्धत थोडी संथ आहे.

यावर उपाय म्हणजे त्या फाईल्स हटवणे किंवा हलवणे. अस्तित्वात असलेल्या ext4 फाईलसिस्टममध्ये तुम्ही इनोड्स वाढवू शकत नाही, कारण त्यांची संख्या mkfs वेळीच निश्चित केलेली असते. ती वाढवण्यासाठी फाईलसिस्टम पुन्हा तयार करून बॅकअपमधून डेटा रिस्टोर करावा लागतो. XFS गरजेनुसार इनोड्स अलोकेट करते, त्यामुळे तिथे अशा प्रकारची निश्चित मर्यादा नसते. कंटेनर चालवणाऱ्या मशीनवर दोन्ही मर्यादा लवकर गाठल्या जातात, कारण इमेज लेयर्समध्ये अनेक लहान फाईल्स असतात. अशा मशीनवर VPS वरील Docker डिस्क वापराचे व्यवस्थापन हाच विशिष्ट उपाय आहे, जो फाईलसिस्टमच्या सामान्य साफसफाईपेक्षा जास्त जागा मोकळी करतो.

माउंट पॉइंटखाली लपलेली जागा

एखाद्या डिरेक्टरीवर काहीही माउंट करण्यापूर्वी त्यात फाइल्स असू शकतात. त्या डिरेक्टरीवर फाइलसिस्टम माउंट केल्यास, खाली असलेल्या फाइल्स त्यांच्या मूळ जागीच राहतात: त्या अजूनही अलोकेट केलेल्या असतात, df द्वारे मोजल्या जातात, परंतु आता त्या नावाने शोधता येत नाहीत. du त्यांना पाहू शकत नाही कारण माउंट त्यांना झाकून टाकते.

हे tmpfs वापरून तपासा, ज्यासाठी अतिरिक्त डिस्कची गरज नसते. या भागासाठी तुम्हाला माउंट करण्याची परवानगी असलेले मशीन आवश्यक आहे, त्यामुळे हे KVM VPS वर काम करते.

sudo mkdir -p /srv/covered
sudo cp /etc/services /srv/covered/
ls /srv/covered
sudo mount -t tmpfs tmpfs /srv/covered
ls /srv/covered
sudo umount /srv/covered
ls /srv/covered

मधला ls एक रिकामी डिरेक्टरी दाखवतो. कॉपी कुठेही गेली नाही: ती अजूनही रूट फाइलसिस्टमवर आहे आणि अनमाउंट करताच ती पुन्हा दिसते. आता अशा सेवेचा विचार करा जिने एखाद्याने त्यावर व्हॉल्यूम माउंट करण्यापूर्वी महिनाभर त्या मार्गावर लॉग्स लिहिले होते.

चालू सर्व्हरवर मूळ फाइल्स शोधण्यासाठी, रूट फाइलसिस्टम दुसऱ्या ठिकाणी पुन्हा माउंट करा. बाइंड माउंट (bind mount) अशा फाइलसिस्टमला दाखवते ज्यामध्ये इतर फाइलसिस्टम माउंट केलेल्या नसतात.

sudo mkdir -p /mnt/rootcheck
sudo mount --bind / /mnt/rootcheck
sudo du -xhs /mnt/rootcheck/* 2>/dev/null | sort -h
sudo umount /mnt/rootcheck

या लिस्टिंगमध्ये दिसणारी पण सामान्य मार्गावर न दिसणारी कोणतीही गोष्ट माउंट पॉइंटखाली गाडली गेली आहे. काम पूर्ण झाल्यावर बाइंड माउंट अनमाउंट करा, अन्यथा -x शिवाय चालवलेले du त्याच फाइल्स दोनदा मोजेल.

root साठी राखीव ब्लॉक्स

ext4 फाइलसिस्टम root वापरकर्त्यासाठी काही ब्लॉक्स राखून ठेवते. यामुळे डिस्क पूर्ण भरली तरी root ला लॉग-इन करून सिस्टिम दुरुस्त करता येते. सामान्य वापरकर्त्याच्या अधिकाराने चालणारी प्रक्रिया आधी मर्यादेला धडकते, तर df मध्ये अजूनही थोडी जागा शिल्लक असल्याचे दिसते. डीफॉल्ट सेटिंगवर अवलंबून राहण्याऐवजी तुमच्या फाइलसिस्टमवरील सेटिंग तपासा.

dev=$(df --output=source / | tail -n 1)
sudo tune2fs -l "$dev" | grep -i 'block count'

हे कमांड एकूण ब्लॉक्सची संख्या आणि राखीव ब्लॉक्सची संख्या समान युनिट्समध्ये दर्शवते, त्यामुळे त्यांच्यातील गुणोत्तर थेट समजते. df मध्ये 'available' कॉलम सामान्य वापरकर्ता वापरू शकणारी जागा दर्शवतो, म्हणूनच 'used' आणि 'available' यांची बेरीज एकूण आकारापेक्षा कमी येते. हा फरक म्हणजे राखीव जागा होय.

ती बदलण्यासाठी sudo tune2fs -m <percent> "$dev" वापरा. हा बदल त्वरित लागू होतो आणि फाइलसिस्टम पुन्हा माउंट (remount) करण्याची गरज नसते. स्वतंत्र डेटा फाइलसिस्टमवर राखीव जागा कमी करणे योग्य ठरू शकते. मात्र, root फाइलसिस्टमवर पुरेशी जागा शिल्लक ठेवा जेणेकरून root ला लिहिता येईल, कारण पूर्णपणे भरलेली root फाइलसिस्टम दुरुस्त करणे खूप कठीण असते. tune2fs हे ext2, ext3 आणि ext4 वर काम करते. XFS मध्ये अशी कोणतीही सेटिंग उपलब्ध नाही.

du जिथे तुम्हाला चुकीची माहिती देऊ शकते

du च्या चार सवयींमुळे मिळणारी एकूण बेरीज चुकीची वाटू शकते.

  • Hard links: du एका इनोडची (inode) गणना एकदाच करते, जरी अनेक नावे त्याकडे निर्देश करत असली तरीही. त्यामुळे, हार्ड लिंक्सने भरलेल्या ट्रीची एकूण साईज ही त्यातील फाईल्सच्या बेरजेपेक्षा कमी दिसते.
  • Sparse files: du प्रत्यक्ष वाटप केलेल्या ब्लॉक्सची माहिती देते, तर ls -l फाईलची एकूण (apparent) साईज दर्शवते. दुसरी संख्या पाहण्यासाठी --apparent-size वापरा.
  • Permissions: सामान्य युजर म्हणून कमांड चालवल्यास, du ज्या फाईल्स वाचू शकत नाही त्या वगळते आणि कमी आकडेवारी दाखवते. ते जे एरर मेसेज प्रिंट करते, ते लोक अनेकदा /dev/null कडे वळवतात आणि वाचणे थांबवतात.
  • Filesystem boundaries: -x शिवाय, du / हे / च्या खाली माउंट केलेल्या प्रत्येक फाईलसिस्टमची गणना करते. त्यामुळे, याची एकूण बेरीज df / ने दिलेल्या माहितीपेक्षा जास्त असू शकते.

df ची देखील एक सवय लक्षात ठेवण्यासारखी आहे. ती प्रत्येक फाईलसिस्टमची माहिती स्वतंत्रपणे देते. त्यामुळे, जिथे राईट (write) करताना एरर येत आहे, त्या नेमक्या पाथवर ही कमांड चालवा. कर्नल पॅकेजेस जमा झाल्यामुळे एक स्वतंत्र /boot भरून जातो. त्यामुळे Ubuntu वर जुने कर्नल काढणे हे / वरील जागा मोकळी करण्यापेक्षा वेगळे काम आहे.

प्रत्यक्ष घटनेच्या वेळी कामाची योग्य पद्धत

  1. ज्या फाइलसिस्टमवर लिहिताना त्रुटी आली आहे, त्यावर df -h <path> आणि df -i <path> चालवा. केवळ सवयीने / वर हे करू नका.
  2. sudo du -xh -d 1 <mountpoint> 2>/dev/null | sort -h चालवा आणि त्यानंतर सर्वात मोठ्या डिरेक्टरीमध्ये जाऊन तपासणी करा.
  3. जर df ने दर्शवलेली जागा आणि du ने मोजलेली जागा यात तफावत असेल, तर /proc मध्ये अशा फाइल्स शोधा ज्या डिलीट झाल्या आहेत पण अजूनही ओपन आहेत.
  4. जर दोन्ही आकडे जुळत असतील, तर फाइलसिस्टमला दुसऱ्या ठिकाणी bind mount करा आणि mount point च्या खाली असलेल्या फाइल्स तपासा.
  5. जर inode चा वापर मर्यादेपर्यंत पोहोचला असेल, तर बाइट्सऐवजी फाइल्सची संख्या मोजा.

येथील प्रत्येक पायरीवर एक कमांड आहे ज्याचे आउटपुट तुम्ही वाचू शकता. समस्या सोडवणे आणि केवळ अंदाज लावणे यातला हाच मुख्य फरक आहे.

FAQ

df कमांड डिस्क पूर्ण असल्याचे का दाखवते, तर du कमांडला कमी जागा का दिसते?

याचे सामान्य कारण म्हणजे एखादी फाईल डिलीट केली गेली आहे, परंतु ती अजूनही एखाद्या प्रोसेसद्वारे उघडी ठेवली गेली आहे. फाईल डिलीट केल्यामुळे तिची डिरेक्टरी एंट्री निघून जाते, त्यामुळे du ला ती फाईल मोजण्यासाठी सापडत नाही. जोपर्यंत शेवटचा फाईल डिस्क्रिप्टर बंद होत नाही, तोपर्यंत त्या फाईलचे आयनोड (inode) आणि ब्लॉक्स अलोकेटेड राहतात आणि df हे अलोकेटेड ब्लॉक्स मोजते. /proc/<pid>/fd मध्ये अशा सिम्बॉलिक लिंक्स शोधा ज्यांचे टार्गेट डिलीट झाल्याचे दर्शवले आहे; तिथे तुम्हाला ती फाईल आणि ती वापरणारी प्रोसेस दोन्ही मिळतील. या तुलनेवर विश्वास ठेवण्यापूर्वी, तुम्ही du कमांड root युजर म्हणून आणि -x फ्लॅगसह चालवली आहे याची खात्री करा, कारण सामान्य युजर ज्या डिरेक्टरीज वाचू शकत नाही, त्या आपोआप वगळल्या जातात.

lsof शिवाय उघडी असलेली डिलीट झालेली फाईल कशी शोधायची?

कर्नेलच्या ओपन डिस्क्रिप्टर्सच्या रेकॉर्डचा वापर करा. sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null अशा प्रत्येक डिस्क्रिप्टरची यादी देते जो अशा फाईलला पॉइंट करत आहे जिचे नाव आता अस्तित्वात नाही, आणि त्या पाथमध्ये प्रोसेस आयडी (PID) समाविष्ट असतो. त्यापैकी एका डिस्क्रिप्टर पाथवर sudo stat -Lc %s चालवल्यास त्याचा आकार समजतो, ज्यामुळे तुम्ही त्यांना सॉर्ट करून महत्त्वाची फाईल निवडू शकता. यासाठी कोणत्याही अतिरिक्त पॅकेजची गरज नसते, जे अशा वेळी महत्त्वाचे ठरते जेव्हा डिस्कवर जागा नसल्यामुळे नवीन सॉफ्टवेअर इन्स्टॉल करणे अशक्य असते.

प्रोसेस बंद न करता मी जागा मोकळी करू शकतो का?

कधीकधी हे शक्य असते. sudo truncate -s 0 /proc/<pid>/fd/<n> डिस्क्रिप्टरद्वारे त्याच आयनोडपर्यंत पोहोचते आणि प्रोसेस चालू असतानाही तिचे ब्लॉक्स मोकळे करते. जर प्रोसेसने फाईल 'append' मोडमध्ये उघडली असेल, तर हे सर्वात सुरक्षित असते, कारण तिचे रायटिंग नेहमी फाईलच्या शेवटी होते. जर तसे नसेल, तर रायटिंग ऑफसेट तिथेच राहतो आणि पुढील रायटिंगमुळे फाईलच्या सुरुवातीला रिकामी जागा (hole) तयार होते; यामुळे रिपोर्ट केलेला आकार पुन्हा वाढतो, जरी मधले ब्लॉक्स मोकळे राहिलेले असतात. युनिट रीस्टार्ट करणे किंवा त्याच्या डॉक्युमेंटेशनमध्ये नमूद केलेल्या सिग्नलद्वारे त्याला लॉग्स पुन्हा उघडण्यास सांगणे, हाच यावरचा कायमस्वरूपी उपाय आहे, ज्यामुळे कोणतीही 'sparse file' मागे राहत नाही.

df कमांड मोकळी जागा दाखवते पण रायटिंग फेल होते, याचे कारण काय असू शकते?

त्याच पाथवर df -i वापरून आयनोड्स तपासा, कारण जर फाईलसिस्टममध्ये ब्लॉक्स मोकळे असतील पण आयनोड्स संपले असतील, तर नवीन फाईल्स तयार होऊ शकत नाहीत. रायटिंग करणारा युजर root नसेल आणि फाईलसिस्टम ext4 असेल, तर फक्त राखीव (reserved) ब्लॉक्स शिल्लक असू शकतात, जे डिव्हाइसवर sudo tune2fs -l चालवल्यास समजेल. तुम्ही ज्या फाईलसिस्टमवर रायटिंग करत आहात, तीच तपासत आहात ना याची खात्री करा, कारण एखादे वेगळे /boot किंवा /var हे / पासून स्वतंत्रपणे भरू शकते.

du कमांड df पेक्षा जास्त टोटल का दाखवते?

-x शिवाय चालवलेली du कमांड दिलेल्या पाथखाली माऊंट असलेल्या प्रत्येक फाईलसिस्टममध्ये प्रवेश करते, त्यामुळे ती अनेक फाईलसिस्टम्सची बेरीज करते, तर df फक्त एका फाईलसिस्टमची माहिती देते. 'Bind mounts' मुळे ही समस्या अधिक वाढते, कारण एकाच फाईल्स प्रत्येक पाथवर पुन्हा मोजल्या जातात. du ला एकाच फाईलसिस्टमवर मर्यादित ठेवण्यासाठी -x जोडा आणि df ला तोच पाथ द्या, जेणेकरून दोन्ही कमांड्स एकाच गोष्टीचे वर्णन करतील.