SSD Nodes Learn Hosting plans →
கல்வி வழிகாட்டிகள் Matt Connorஆல் Matt Connor · புதுப்பிக்கப்பட்டது 2026-08-30

df மற்றும் du கட்டளைகளில் வட்டு அளவு வேறுபாடு ஏன்?

df கட்டளை வட்டு நிரம்பியதாகக் காட்டி, du மாறுபட்ட முடிவைத் தருவதற்கான காரணங்களை அறியுங்கள். நீக்கப்பட்ட கோப்பை ஒரு process பிடித்து வைத்திருப்பதை lsof மூலம் கண்டறிந்து சரிசெய்யும் முறை.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, August 15, 2026.

df கட்டளை வட்டு நிரம்பியதாகக் காட்டுவதற்கும் du கட்டளை மாறுபட்ட முடிவைத் தருவதற்கும் காரணம் என்ன

df வட்டு நிரம்பியதாகக் காட்டுகிறது, ஆனால் du அந்த இடத்தைக் கண்டறிய முடியவில்லை. இதற்கு ஒரு செயல்முறை (process) நீக்கப்பட்ட கோப்பை இன்னும் வைத்திருப்பதே காரணம். ஒரு கோப்பை நீக்கும்போது, அதன் பெயர் கோப்பகத்திலிருந்து (directory) நீக்கப்படும். அந்த inode-ஐக் குறிக்கும் கடைசி கோப்பு விவரிப்பான் (file descriptor) மூடப்படும்போது மட்டுமே தரவுத் தொகுதிகள் (data blocks) விடுவிக்கப்படும். du கோப்புப் பெயர்களை மட்டுமே கணக்கிடுவதால், நீக்கப்பட்ட கோப்பை அது கணக்கிடாது. df கோப்பு முறைமையிடம் (filesystem) எத்தனை தொகுதிகள் ஒதுக்கப்பட்டுள்ளன என்று கேட்கிறது, எனவே பெயரில்லாத அந்த கோப்பையும் அது கணக்கிடுகிறது.

இந்த வழிகாட்டி, ஏற்கனவே நிறுவப்பட்ட கருவிகளைக் கொண்டு ஒரு சாதாரண Ubuntu VPS-ல் இந்தச் சூழலை உருவாக்குகிறது, /proc மூலம் அந்த கோப்பை வைத்திருக்கும் செயல்முறையைக் கண்டறிகிறது, மேலும் கணினியை மறுதொடக்கம் (reboot) செய்யாமலேயே இடத்தைச் சுத்தம் செய்கிறது. இதே அறிகுறிகளை ஏற்படுத்தும் பிற காரணங்கள் பின்வருமாறு: காலியான இடமில்லாத inode அட்டவணை, mount point-க்கு அடியில் மறைந்துள்ள கோப்புகள் மற்றும் root பயனருக்காக ஒதுக்கப்பட்ட தொகுதிகள்.

ஒவ்வொரு கட்டளையையும் இயக்கி, உங்கள் வெளியீட்டைப் படியுங்கள். மதிப்புகள் உங்கள் வட்டைப் பொறுத்து மாறுபடும். எனவே, வழிகாட்டியில் உள்ள எண்களுடன் ஒப்பிடாமல், உங்கள் கணினியில் கட்டளைக்கு முன்னும் பின்னும் உள்ள மதிப்புகளை ஒப்பிட்டுப் பாருங்கள்.

df மற்றும் du எவற்றைக் கணக்கிடுகின்றன

df (disk free) ஒவ்வொரு mounted filesystem-மிடமும் அதன் கணக்கீட்டைக் கேட்கிறது: எத்தனை blocks உள்ளன, எத்தனை ஒதுக்கப்பட்டுள்ளன, எத்தனை காலியாக உள்ளன. இது எந்த directory-யையும் திறப்பதில்லை. எந்த directory entry-யும் சுட்டிக்காட்டாத கோப்புக்குச் சொந்தமான blocks உட்பட, ஒதுக்கப்பட்ட அனைத்து blocks-களையும் இந்த விடை உள்ளடக்கும்.

du (disk usage) இதற்கு நேர்மாறாகச் செயல்படுகிறது. நீங்கள் கொடுக்கும் பாதையில் தொடங்கி, directory-களை வாசித்து, அதில் உள்ள ஒவ்வொரு entry-யையும் stat செய்து, blocks-களைக் கூட்டுகிறது. பெயரில்லாத ஒரு கோப்பு இதற்குத் தெரிவதில்லை. அதேபோல், வாசிக்க அனுமதி இல்லாத எந்த directory-யும் இதற்குத் தெரிவதில்லை; இதனால்தான் ஒரு சாதாரண பயனர் பெறும் மொத்த அளவு root பயனர் பெறுவதை விடக் குறைவாக இருக்கிறது. ஒப்பீட்டின் அடிப்படையில் ஏதேனும் முடிவுக்கு வரும் முன், sudo-ன் கீழ் du-ஐ இயக்கவும்.

இவ்விரண்டையும் ஒப்பிடும்போது ஒவ்வொரு முறையும் இரண்டு விருப்பங்கள் முக்கியமானவை.

  • -x என்பது du-ஐ ஒரே filesystem-க்குள் வைத்திருக்கும். இது இல்லையென்றால், du / என்பது /-க்குக் கீழே உள்ள ஒவ்வொரு filesystem-க்குள்ளும் சென்று, df / அளவிடாத ஒரு மொத்தத்தைக் காட்டும்.
  • -s என்பது ஒவ்வொரு directory-க்கும் ஒரு வரிக்கு பதிலாக, ஒவ்வொரு argument-க்கும் ஒரு சுருக்க வரியை அச்சிடும்.

நீங்கள் கவனிக்க வேண்டிய filesystem-ல் பக்கவாட்டில் இயக்க வேண்டிய ஜோடி இதுதான்.

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

df உடனடியாக விடையளிக்கும். du பெரிய filesystem-ல் பல நிமிடங்கள் எடுத்துக்கொள்ளும், ஏனெனில் அது வழியில் உள்ள ஒவ்வொரு கோப்பையும் stat செய்கிறது. இவ்விரண்டு மொத்தங்களும் வெகுவாக வேறுபடும்போது, மற்றும் du ஆனது -x உடன் root ஆக இயக்கப்பட்டிருந்தால், விடுபட்ட இடம் பெயரில்லாத ஏதோ ஒன்றுக்கு ஒதுக்கப்பட்டுள்ளது என்று பொருள்.

முரண்பாட்டை வேண்டுமென்றே உருவாக்குதல்

இதை ஒரு சோதனை VPS-ல் செய்யவும். கீழே உள்ள அனைத்தும் bash மற்றும் coreutils என்பதால், எதையும் புதிதாக நிறுவ வேண்டியதில்லை.

/var/tmp-ஐக் கொண்டுள்ள filesystem-ன் தொடக்க நிலையைப் பதிவு செய்யவும்.

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

இரண்டாவது கட்டளை பயன்படுத்தப்பட்ட bytes-களை எந்தவிதமான rounding-ம் இன்றி அச்சிடுகிறது, இது இறுதியில் செய்யப்படும் சரிபார்ப்பை துல்லியமாக்குகிறது.

இப்போது ஒரு கோப்பை உருவாக்கவும். அந்த இயந்திரம் தெரிவிக்கும் காலி இடத்திலிருந்து அதன் அளவு கணக்கிடப்படுவதால், உங்களிடம் உள்ள எந்த வட்டுக்கும் (disk) இந்த செயல்முறை பொருந்தும்.

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

$(...) என்பது command substitution ஆகும்: shell அதற்குள் உள்ள கட்டளையை இயக்கும், அதன் வெளியீடு free-ன் மதிப்பாக மாறும். இந்த syntax உங்களுக்குப் புதியது என்றால், command substitution in bash பகுதியில் இதைப் பற்றி விரிவாகக் காணலாம். fallocate தரவுகளை எழுதாமலேயே உண்மையான blocks-களை ஒதுக்குகிறது, அதனால்தான் அது உடனடியாக முடிவடைகிறது. இதை ஆதரிக்காத filesystem-ல் இந்த கட்டளை தோல்வியடையும், அப்போது head -c $((free / 10)) /dev/zero > ghost.bin அந்த bytes-களை எழுதி அதே வேலையைச் செய்யும்.

இந்த df -h .-ஐ நீங்கள் பதிவு செய்தவற்றுடன் ஒப்பிடவும். பயன்படுத்தப்பட்ட (used) நெடுவரிசை அதிகரித்திருக்கும் மற்றும் கிடைக்கக்கூடிய (available) நெடுவரிசை குறைந்திருக்கும்.

இப்போது மற்றொரு process மூலம் அந்தக் கோப்பைத் திறந்து வைத்துவிட்டு, பின் அதை நீக்கவும்.

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

இந்த redirection-தான் முழு தந்திரமும். sleep infinity < ghost.bin & ஒரு background process-ஐத் தொடங்குகிறது, அதன் standard input அந்தக் கோப்பாகும்; எனவே shell அந்தக் கோப்பைத் திறந்து, அதன் descriptor-ஐ sleep-க்கு வழங்குகிறது, அது அதைத் திறந்து வைத்திருக்கும். $! அந்த background job-ன் process ID-ஐக் கொண்டிருக்கும். அதன் பிறகு rm அந்தக் கோப்பின் பெயரை நீக்குகிறது, ஆனால் descriptor இன்னும் திறந்தே இருக்கும்.

வெளியீட்டைப் படிக்கவும். ls-ஆல் கோப்பைக் கண்டறிய முடியாது, ஏனெனில் அதன் பெயர் நீக்கப்பட்டுவிட்டது. du மீண்டும் தொடக்க நிலைக்கு அருகில் வந்துவிட்டது, ஏனெனில் அது கோப்புப் பெயர்களை அடிப்படையாகக் கொண்டே கணக்கிடுகிறது. df மாறவில்லை, ஏனெனில் blocks இன்னும் ஒதுக்கீடு செய்யப்பட்டே உள்ளன. இப்போது filesystem-க்கும் directory tree-க்கும் இடையே முரண்பாடு உள்ளது; அந்த இடைவெளிதான் நீங்கள் இப்போது நீக்கிய கோப்பு.

நீக்கப்பட்ட கோப்பை வைத்திருக்கும் process-ஐக் கண்டறிதல்

ஒவ்வொரு திறந்த கோப்பு descriptor-ம் /proc/<pid>/fd/-ன் கீழ், அது குறிக்கும் கோப்பிற்கான symbolic link-ஆகக் காணப்படும். ஒரு கோப்பு unlinked செய்யப்பட்டால், அந்த link-ன் இலக்கை kernel நீக்கப்பட்டதாகக் குறிக்கும். எனவே, அந்த கோப்பை வைத்திருக்கும் process-ஐக் கண்டறிய, நீக்கப்பட்டதைக் குறிக்கும் குறியீட்டைக் கொண்ட link-ஐத் தேட வேண்டும்.

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

-lname என்பது symbolic link-ன் பெயரைத் தேடாமல் அதன் இலக்கைத் தேடுகிறது, %p என்பது descriptor பாதையை அச்சிடுகிறது, மற்றும் %l என்பது அது எதைக் குறிக்கிறது என்பதை அச்சிடுகிறது. அது அச்சிடும் பாதையின் இரண்டாவது உறுப்பு process ID ஆகும். இதை sudo உடன் இயக்கவும், இல்லையெனில் உங்களது சொந்த process-களுக்கான /proc/<pid>/fd-ஐ மட்டுமே உங்களால் படிக்க முடியும். stderr redirect, find இயங்கும்போது வெளியேறும் process-களால் ஏற்படும் தேவையற்ற தகவல்களை நீக்குகிறது.

ஒரு busy server-ல் எப்போதும் பல நீக்கப்பட்ட கோப்புகள் இருக்கும், அவற்றில் பெரும்பாலானவை சிறியவை மற்றும் பாதிப்பில்லாதவை. அவற்றை அளவின் அடிப்படையில் வரிசைப்படுத்தினால் மட்டுமே முக்கியமானவை மேலே தெரியும்.

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 என்பது link-ஐத் தொடர்ந்து inode-ஐ அடைகிறது, எனவே %s என்பது பெயர் இல்லாத கோப்பின் அளவை அறிக்கையிடுகிறது. அந்த எண்ணின் அடிப்படையில் வரிசைப்படுத்தினால், மிகப்பெரிய கோப்பு முதலில் வரும்.

பின்னர், அந்த descriptor-க்கு காரணமான process-ஐ அடையாளம் காணவும். அந்தப் பட்டியலின் உச்சியில் உள்ள பாதையில் உங்களுக்குத் தேவையான இரண்டு எண்களும் இருக்கும், எனவே அவற்றை முதலில் variables-ல் சேமிக்கவும்; 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-ன் அளவு மற்றும் ஒதுக்கப்பட்ட block எண்ணிக்கையை அச்சிடுகிறது. இவை இரண்டும் சேர்ந்து, எந்த service இந்த கோப்பைத் தக்கவைத்துள்ளது என்ற முக்கியமான கேள்விக்கு விடையளிக்கிறது.

இயந்திரத்தில் ஏற்கனவே lsof இருந்தால், sudo lsof +L1 என்பது link எண்ணிக்கை பூஜ்ஜியமாகக் குறைந்த திறந்த கோப்புகளைப் பட்டியலிட்டு, அவற்றின் அளவுகளை ஒரே அட்டவணையில் காட்டுகிறது. இது minimal Ubuntu image-ல் இருக்காது, மேலும் இடவசதி இல்லாத filesystem-ல் ஒரு package-ஐ நிறுவுவது தோல்வியடையலாம், எனவே /proc முறை எப்போதும் வேலை செய்யும் பதிப்பாகும்.

Reboot செய்யாமல் இடவசதியை விடுவித்தல்

Reboot செய்வது சிக்கலைச் சரிசெய்யும், ஆனால் அதுவே முதல் தீர்வாக இருக்கக்கூடாது: அது சேவையை நிறுத்துவதுடன், சிக்கலுக்கான ஆதாரங்களையும் அழித்துவிடும். இதைச் சரிசெய்ய நான்கு மென்மையான வழிகள் உள்ளன; அவற்றை வரிசைப்படி முயற்சிக்கவும்.

முதலில், உங்களுக்குத் தரவு தேவைப்பட்டால் அதை நகலெடுக்கவும். Descriptor path-ஐ வாசிப்பது நேரடி inode-ஐ வாசிப்பதற்குச் சமம்.

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

நீக்கப்பட்ட கோப்பை மீட்டெடுக்கக்கூடிய ஒரே சந்தர்ப்பம் இதுதான். இதனால்தான் rm -rf மூலம் நீக்கப்பட்ட கோப்புகளை மீட்டெடுத்தல் பகுதியில், ஒரு process இன்னும் கோப்பைத் திறந்து வைத்துள்ளதா என்று முதலில் கேட்கப்படுகிறது. கடைசி descriptor மூடப்பட்டவுடன், அந்த வழி அடைக்கப்பட்டுவிடும்.

இரண்டாவதாக, descriptor வழியாகக் கோப்பை காலி செய்யவும். /proc பாதை அதே inode-ஐக் குறிப்பதால், அதைத் துண்டிப்பது (truncate) process இயங்கிக்கொண்டிருக்கும்போதே கோப்பின் தொகுதிகளை (blocks) விடுவிக்கும்.

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

எழுதும் process கோப்பை append mode-ல் திறந்திருந்தால் இது சரியாகச் செயல்படும், ஏனெனில் ஒவ்வொரு எழுதும் செயலும் கோப்பின் தற்போதைய இறுதிப் பகுதிக்குச் செல்லும். இல்லையெனில், process அதன் பழைய write offset-ஐ வைத்திருக்கும்; எனவே அடுத்த எழுதும் செயல் கோப்பின் ஆழமான பகுதிக்குச் சென்று, முன்னால் ஒரு துளையுடன் (hole) கோப்பை மீண்டும் உருவாக்கும். துளைகளுக்கு இட ஒதுக்கீடு செய்யப்படுவதில்லை, எனவே தொகுதிகள் காலியாகவே இருக்கும் மற்றும் df விடுவிக்கப்பட்ட இடத்தைத் தக்கவைக்கும். கோப்பின் அளவு மட்டுமே மீண்டும் அதிகரிக்கும்: process எழுதிய பிறகு மீண்டும் sudo stat -L "/proc/$pid/fd/$n"-ஐ இயக்கினால், அது பழைய அளவையும், அதற்குப் பொருந்தாத தொகுதி எண்ணிக்கையையும் காட்டும். அளவு பூஜ்ஜியத்திலிருந்து தொடங்க வேண்டும் எனில், process-ஐ restart செய்யவும்.

மூன்றாவதாக, log கோப்புகளை மீண்டும் திறக்குமாறு சேவையிடம் கேட்கவும். ஒரு daemon இயங்கிக்கொண்டிருக்கும்போதே அதன் log கோப்பு நீக்கப்படுவதுதான் இந்தச் சிக்கலின் பொதுவான வடிவம். பல daemon-கள் ஒரு signal மூலம் தங்கள் log கோப்புகளை மீண்டும் திறக்கும்: nginx-க்கு SIGUSR1 மற்றும் rsyslog-க்கு SIGHUP பயன்படுத்தப்படுகிறது. யூகிக்காமல், அந்தந்த daemon-ன் ஆவணங்களைச் சரிபார்க்கவும், ஏனெனில் தவறான daemon-க்குத் தவறான signal-ஐ அனுப்பினால் அது நின்றுவிடும்.

sudo systemctl kill -s USR1 nginx

இது systemd-ல் அந்த unit-ன் முதன்மை process-ஆகப் பதிவுசெய்யப்பட்டதற்கு signal-ஐ அனுப்பும். எனவே, daemon தொடங்கும் முறைக்குத் தவறான Type= என்று குறிப்பிடும் unit, நீக்கப்பட்ட கோப்பை வைத்திருக்காத ஒரு process-க்கு signal-ஐ அனுப்பிவிடும், இதனால் இடவசதி விடுவிக்கப்படாது.

நான்காவதாக, unit-ஐ restart செய்யவும். sudo systemctl restart <unit> பழைய process வைத்திருந்த அனைத்து descriptor-களையும் மூடிவிடும், எனவே தொகுதிகள் நிச்சயமாகத் திரும்பக் கிடைக்கும். மேலே உள்ள உதாரணத்திற்கு, நீங்கள் நீங்களே தொடங்கிய sleep போதுமானது, எனவே அதை முடிப்பதே போதுமானது.

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

கோப்பை உருவாக்குவதற்கு முன் நீங்கள் பதிவு செய்த மதிப்போடு தற்போதைய பயன்படுத்தப்பட்ட bytes-ஐ ஒப்பிடவும். அவை மீண்டும் ஒத்துப்போகும், மேலும் find உங்கள் descriptor-ஐக் காட்டாது. சிக்கலைக் கண்டறிந்த அதே கட்டளையைக் கொண்டு சரிபார்ப்பது ஒரு நல்ல பழக்கம்.

அந்த மதிப்பின் மாற்றத்தைக் கவனிப்பது, df-ஐ மீண்டும் மீண்டும் கைகளால் இயக்குவதை விட எளிதானது. watch ஒரு கட்டளையை குறிப்பிட்ட இடைவெளியில் மீண்டும் இயக்குகிறது மற்றும் வெளியீட்டை அதே இடத்தில் புதுப்பிக்கும், எனவே watch df -h / இடவசதி திரும்பக் கிடைக்கும்போது பயன்படுத்தப்பட்ட நெடுவரிசை (used column) மாறுவதைக் காட்டும்.

மொத்த அளவு சரியாக இருந்து, disk இன்னும் நிறைந்திருந்தால்

df மற்றும் root du -x ஆகியவற்றுக்கு இடையே கணக்கீடு ஒத்துப்போனால், நீக்கப்பட்ட கோப்புகள் (deleted files) எதற்கும் தொடர்பில்லை என்று அர்த்தம். மீதமுள்ள காரணங்கள் வேறுபட்டவை, ஒவ்வொன்றையும் தனித்தனியாகச் சரிபார்க்க வேண்டும்.

Blocks தீர்ந்துவிடவில்லை, ஆனால் inodes தீர்ந்துவிட்டன

ஒரு inode என்பது ஒரு கோப்பின் metadata-வைச் சேமிக்கும் இடமாகும். ஒரு filesystem உருவாக்கப்படும்போது ext4 ஒரு குறிப்பிட்ட எண்ணிக்கையிலான inodes-ஐ மட்டுமே உருவாக்குகிறது. எனவே, filesystem-ல் காலியான blocks இருந்தாலும், inodes தீர்ந்துபோக வாய்ப்புள்ளது. அப்போது df -h கட்டளை இடமிருப்பதாகக் காட்டினாலும், புதிய கோப்புகளை உருவாக்க முடியாது.

df -h /
df -i /

முதல் கட்டளை blocks-ஐயும், இரண்டாவது கட்டளை inodes-ஐயும் கணக்கிடுகிறது. ஒவ்வொன்றின் use column-ஐயும் ஒப்பிட்டுப் பார்க்கவும். Block பயன்பாடு குறைவாக இருந்து, inode பயன்பாடு உச்சத்தில் இருந்தால், மிகச்சிறிய கோப்புகள் அதிக எண்ணிக்கையில் இருப்பதுதான் பிரச்சினை.

df கட்டளையானது -i மற்றும் --output ஆகியவற்றை ஒரே நேரத்தில் ஏற்காது. எனவே, raw counts-ஐப் பெற அல்லது பிற கட்டளைகளுக்கு உள்ளீடாக வழங்க, inode புலங்களை மட்டும் பெயரிட்டுத் தேர்வு செய்யவும், -i-ஐத் தவிர்க்கவும்.

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

அந்தக் columns, df -i வெளியிடும் அதே கணக்கீட்டுத் தகவல்களைக் கொண்டுள்ளன. இவற்றை நீங்கள் எளிதாகப் பிரித்தெடுக்க முடியும்.

கோப்புகளின் அளவை (bytes) கணக்கிடுவதற்குப் பதிலாக, கோப்புகளின் எண்ணிக்கையை (entries) வைத்து அவற்றைக் கண்டறியவும்.

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

அதிக எண்ணிக்கையிலான கோப்புகளைக் கொண்ட directory-ஐக் கண்டறிந்து, அந்த directory-க்குள் சென்று இதே கட்டளையை மீண்டும் இயக்கவும். கோப்புகளை உருவாக்கும் directory-ஐ அடையும் வரை இதைத் தொடரவும். உங்கள் du கட்டளை --inodes-ஐ ஆதரிக்கவில்லை என்றால், sudo find /var -xdev -type f | wc -l கட்டளையைப் பயன்படுத்தி ஒரு subtree-ஐ மெதுவான முறையில் கணக்கிடலாம்.

இதற்கான தீர்வு, அந்தத் தேவையற்ற கோப்புகளை நீக்குவது அல்லது நகர்த்துவதுதான். ஏற்கனவே உள்ள ext4 filesystem-ல் inodes எண்ணிக்கையை அதிகரிக்க முடியாது, ஏனெனில் அது mkfs நேரத்திலேயே நிர்ணயிக்கப்பட்டுவிடுகிறது. எண்ணிக்கையை அதிகரிக்க வேண்டுமெனில், filesystem-ஐ மீண்டும் உருவாக்கி, backup-லிருந்து தரவுகளை மீட்க வேண்டும். XFS filesystem தேவைக்கேற்ப inodes-ஐ ஒதுக்கீடு செய்வதால், அதற்கு இத்தகைய நிலையான வரம்பு கிடையாது. Containers இயங்கும் ஒரு machine-ல், image layers பல சிறிய கோப்புகளைக் கொண்டிருப்பதால், இந்த இரண்டு வரம்புகளும் விரைவில் எட்டப்படும். அத்தகைய சூழலில், VPS-ல் Docker disk பயன்பாட்டைச் சுத்தப்படுத்துதல் என்பதே சரியான தீர்வாகும்; இது filesystem-ஐப் பொதுப்படையாகச் சுத்தப்படுத்துவதை விட அதிக இடத்தைச் சேமித்துத் தரும்.

Mount point-க்கு அடியில் மறைந்துள்ள இடம்

ஒரு directory-ல் எதையும் mount செய்வதற்கு முன்பே அதில் கோப்புகள் இருக்கலாம். அந்த directory-ன் மீது ஒரு filesystem-ஐ mount செய்தால், அடியில் உள்ள கோப்புகள் அப்படியே இருக்கும்: அவை தொடர்ந்து ஒதுக்கீடு செய்யப்பட்டிருக்கும், df மூலம் கணக்கிடப்படும், ஆனால் அவற்றின் பெயரால் அவற்றை அணுக முடியாது. அந்த mount அவற்றை மறைத்துவிடுவதால் du-ஆல் அவற்றைப் பார்க்க முடியாது.

இதை tmpfs கொண்டு நிரூபிக்கலாம், இதற்கு கூடுதல் disk தேவையில்லை. இந்தச் சோதனையைச் செய்ய உங்களுக்கு mount செய்யும் அனுமதி உள்ள ஒரு machine தேவை, எனவே இது 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 ஒரு காலி directory-ஐக் காட்டுகிறது. அந்த நகல் எங்கும் செல்லவில்லை: அது root filesystem-லேயே உள்ளது, நீங்கள் unmount செய்தவுடன் மீண்டும் தெரிந்துவிடும். யாராவது ஒரு volume-ஐ mount செய்வதற்கு முன்பு, ஒரு மாதம் அந்தப் பாதையில் log செய்த ஒரு service-ஐக் கற்பனை செய்து பாருங்கள்.

இயங்கிக்கொண்டிருக்கும் server-ல் உண்மையான கோப்புகளைக் கண்டறிய, root filesystem-ஐ வேறொரு இடத்தில் இரண்டாவது முறையாக mount செய்யவும். ஒரு bind mount, அதற்குள் mount செய்யப்பட்டுள்ள பிற filesystem-கள் இல்லாமல், அந்த ஒரு filesystem-ஐ மட்டும் காட்டும்.

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

அந்தப் பட்டியலில் தோன்றி, சாதாரண பாதையில் இல்லாத எதுவாக இருந்தாலும், அது ஒரு mount point-க்கு அடியில் புதைந்து கிடக்கிறது என்று அர்த்தம். உங்கள் வேலை முடிந்ததும் அந்த bind mount-ஐ unmount செய்யவும், இல்லையெனில் -x இல்லாத ஒரு du அதே கோப்புகளை இரண்டு முறை கணக்கிடும்.

root பயனருக்காக ஒதுக்கப்பட்ட தொகுதிகள் (Blocks)

ext4 கோப்பு முறைமையானது, வட்டு முழுமையாக நிரம்பினாலும் root பயனர் உள்நுழைந்து கணினியைச் சரிசெய்யும் வகையில், சில தொகுதிகளை root பயனருக்காக ஒதுக்கி வைக்கிறது. சாதாரண பயனர் இயக்கும் ஒரு செயல்முறை (process) வட்டு நிரம்பியதாகக் கருதி முதலில் தடையைச் சந்திக்கும், ஆனால் df கட்டளை இன்னும் சிறிது இடம் இருப்பதைக்காட்டும். இயல்பான அமைப்பை அப்படியே நம்பாமல், உங்கள் கோப்பு முறைமையில் உள்ள அமைப்பைச் சரிபார்க்கவும்.

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

இது மொத்த தொகுதி எண்ணிக்கை மற்றும் ஒதுக்கப்பட்ட தொகுதி எண்ணிக்கையை ஒரே அலகுகளில் அச்சிடும், எனவே அவற்றுக்கு இடையேயான விகிதத்தை நேரடியாக அறியலாம். df கட்டளையானது, சாதாரண பயனர் பயன்படுத்தக்கூடிய இடத்தையே 'available' நெடுவரிசையில் காட்டுகிறது; இதனால்தான் 'used' மற்றும் 'available' ஆகியவற்றின் கூடுதல், மொத்த அளவை விடக் குறைவாக உள்ளது. இந்த இடைவெளிதான் ஒதுக்கப்பட்ட பகுதி (reserve).

இதை மாற்ற sudo tune2fs -m <percent> "$dev" கட்டளையைப் பயன்படுத்தவும். இந்த மாற்றம் உடனடியாகச் செயல்படும், கோப்பு முறைமையை மீண்டும் mount செய்யத் தேவையில்லை. தரவுகளை மட்டும் கொண்ட தனி கோப்பு முறைமையில் இந்த ஒதுக்கப்பட்ட அளவைக் குறைப்பது நியாயமானது. ஆனால் root கோப்பு முறைமையில், root பயனர் எழுதுவதற்குத் தேவையான அளவு இடத்தைப் பராமரிக்க வேண்டும்; ஏனெனில் முற்றிலும் காலியாக இல்லாத root கோப்பு முறைமையைச் சரிசெய்வது மிகவும் கடினம். இதுவே உங்களை கணினியிலிருந்து வெளியேற்றப்படாமல் பாதுகாக்கிறது: வட்டில் இடமில்லாதபோது authorized_keys கோப்பில் சேர்க்கப்படும் ஒரு cryptographic key முழுமையாக எழுதப்படாமல் போகலாம் அல்லது எழுதப்படாமலே போகலாம். இதனால் அடுத்த முறை உள்நுழையும்போது Permission denied (publickey) என்ற பிழை ஏற்படும்; இதற்கும் அந்த key-க்கும் எந்தத் தொடர்பும் இருக்காது. tune2fs கட்டளை ext2, ext3 மற்றும் ext4 ஆகியவற்றில் செயல்படும். XFS கோப்பு முறைமையில் இதற்கு இணையான அமைப்பு இல்லை.

du கட்டளை தவறான தகவல்களைத் தரும் சூழல்கள்

du-ன் நான்கு பழக்கவழக்கங்கள் தவறான மொத்த அளவுகளைக் காட்டக்கூடும்.

  • Hard links: பல பெயர்கள் ஒரே inode-ஐக் குறிப்பிட்டாலும், du அதை ஒருமுறை மட்டுமே கணக்கிடும். எனவே, hard links நிறைந்த ஒரு கோப்பகத்தில் உள்ள கோப்புகளின் மொத்த அளவை விட, அதன் கோப்பக அளவு குறைவாகக் காட்டப்படும்.
  • Sparse files: du தற்போது ஒதுக்கப்பட்டுள்ள blocks-ன் அளவை மட்டுமே காட்டும், ஆனால் ls -l கோப்பின் உண்மையான அளவைக் (apparent size) காட்டும். மற்றொன்றைக் காண --apparent-size-ஐச் சேர்க்கவும்.
  • Permissions: சாதாரண பயனராக இயக்கும்போது, du தம்மால் படிக்க முடியாத கோப்புகளைத் தவிர்த்துவிடும், இதனால் அளவு குறைவாகக் காட்டப்படும். இது காட்டும் பிழைகளை மக்கள் /dev/null-க்குத் திருப்பிவிட்டு, அவற்றைப் படிக்காமல் விட்டுவிடுவார்கள்.
  • Filesystem boundaries: -x இல்லாமல் இயக்கும்போது, /-க்குக் கீழே mount செய்யப்பட்டுள்ள அனைத்து filesystem-களையும் du / கணக்கிடும். இதனால், df / காட்டும் அளவை விட இதன் மொத்த அளவு அதிகமாக இருக்கலாம்.

df-க்கும் கவனிக்க வேண்டிய ஒரு பழக்கம் உள்ளது. இது ஒவ்வொரு filesystem-ஐயும் தனித்தனியாகக் காட்டும். எனவே, எழுதும் பணி தோல்வியடையும் குறிப்பிட்ட பாதையில் இதை இயக்கவும். kernel தொகுப்புகள் சேரும்போது, ஒரு தனிப்பட்ட /boot தானாகவே நிரம்பும். Ubuntu-வில் பழைய kernel-களை நீக்குவது என்பது /-ல் இடத்தைச் சுத்தம் செய்வதிலிருந்து மாறுபட்ட ஒரு பணியாகும்.

ஒரு உண்மையான சம்பவத்திற்கான செயல்பாட்டு முறை

  1. தோல்வியடைந்த write செயல்பாடு எந்த filesystem-ஐ இலக்காகக் கொண்டதோ, அதில் df -h <path> மற்றும் df -i <path> கட்டளைகளை இயக்கவும். மாறாக, வழக்கமான பழக்கத்தின் அடிப்படையில் /-ல் இயக்க வேண்டாம்.
  2. sudo du -xh -d 1 <mountpoint> 2>/dev/null | sort -h கட்டளையை இயக்கி, அதன் பிறகு அதிக அளவு இடத்தைப் பயன்படுத்தும் directory-க்குள் சென்று ஆய்வு செய்யவும்.
  3. df காட்டும் பயன்பாட்டிற்கு, du கட்டளையால் கணக்கு காட்ட முடியவில்லை என்றால், நீக்கப்பட்டும் இன்னும் open நிலையில் உள்ள கோப்புகளைக் கண்டறிய /proc-ல் தேடவும்.
  4. இரண்டும் ஒத்துப்போனால், அந்த filesystem-ஐ வேறொரு இடத்தில் bind mount செய்து, mount point-க்கு அடியில் மறைந்திருக்கும் கோப்புகளைத் தேடவும்.
  5. inode பயன்பாடு வரம்பை எட்டியிருந்தால், பைட்டுகளைக் கணக்கிடுவதற்குப் பதிலாக கோப்புகளின் எண்ணிக்கையைக் கணக்கிடவும்.

மேலே உள்ள ஒவ்வொரு படியிலும் ஒரு கட்டளை உள்ளது, அதன் வெளியீட்டை நீங்கள் வாசிக்க முடியும். இதுவே, ஊகித்துச் செயல்படுவதற்கும், சிக்கலைச் சரியாகத் தீர்ப்பதற்கும் உள்ள வேறுபாடாகும்.

FAQ

df கட்டளை வட்டு நிரம்பியதாகக் காட்டுகிறது, ஆனால் du கட்டளை குறைவான அளவையே காட்டுகிறதே, ஏன்?

ஒரு கோப்பு (file) நீக்கப்பட்ட பிறகும், ஒரு process அதைத் தொடர்ந்து திறந்து வைத்திருப்பதே இதற்குப் பொதுவான காரணம். கோப்பை நீக்கும்போது அதன் directory entry நீக்கப்பட்டுவிடுகிறது, எனவே du அந்த கோப்பின் பெயரைத் தேட முடியாமல் அதன் அளவைக் கணக்கிடுவதை நிறுத்திவிடுகிறது. அந்த கோப்பின் inode மற்றும் அதன் blocks, கடைசி descriptor மூடப்படும் வரை ஒதுக்கீடு செய்யப்பட்டே இருக்கும், மேலும் df ஒதுக்கீடு செய்யப்பட்ட அனைத்து blocks-களையும் கணக்கிடுகிறது. நீக்கப்பட்டதாகக் குறிக்கப்பட்ட symbolic links-களைக் கண்டறிய /proc/<pid>/fd-ல் தேடினால், அந்த கோப்பையும் அதை வைத்திருக்கும் process-ஐயும் கண்டறியலாம். இந்த ஒப்பீட்டை நம்புவதற்கு முன், du கட்டளையை root பயனராகவும் -x flag-உடனும் இயக்கியுள்ளீர்களா என்பதை உறுதிப்படுத்தவும், ஏனெனில் சாதாரண பயனர் படிக்க முடியாத directories-ஐ அந்த கட்டளை அமைதியாகத் தவிர்த்துவிடும்.

lsof இல்லாமல், நீக்கப்பட்ட ஆனால் இன்னும் திறந்திருக்கும் கோப்பை எவ்வாறு கண்டறிவது?

Kernel-ன் open descriptors பதிவுகளைப் பயன்படுத்தவும். sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null, பெயரில்லாத கோப்புகளைச் சுட்டிக்காட்டும் ஒவ்வொரு descriptor-ஐயும் பட்டியலிடுகிறது, மேலும் அந்தப் பாதையில் process ID-யும் இருக்கும். அந்த descriptor பாதைகளில் ஒன்றில் sudo stat -Lc %s கட்டளையை இயக்கினால் அதன் அளவு தெரியும், அதன் மூலம் நீங்கள் முக்கியமான கோப்பை வரிசைப்படுத்தித் தேர்ந்தெடுக்கலாம். இதற்கு எந்தப் புதிய package-ம் தேவையில்லை; வட்டில் இடமில்லாதபோது புதிய மென்பொருளை நிறுவுவது தோல்வியடையக்கூடும் என்பதால் இது முக்கியமானது.

process-ஐ நிறுத்தாமலேயே வட்டு இடத்தை விடுவிக்க முடியுமா?

சில நேரங்களில் முடியும். sudo truncate -s 0 /proc/<pid>/fd/<n> அந்த descriptor வழியாக அதே inode-ஐ அடைந்து, process இயங்கிக்கொண்டிருக்கும்போதே அதன் blocks-ஐ விடுவிக்கிறது. process அந்த கோப்பை append mode-ல் திறந்திருந்தால் இது மிகவும் பாதுகாப்பானது, ஏனெனில் அதன் தரவுகள் எப்போதும் கோப்பின் இறுதிப்பகுதியிலேயே எழுதப்படும். இல்லையெனில், write offset பழைய இடத்திலேயே இருக்கும், அடுத்த முறை எழுதும்போது கோப்பின் முன்பகுதியில் இடைவெளியுடன் (hole) கோப்பு மீண்டும் உருவாகும்; இதனால் கோப்பின் அளவு மீண்டும் அதிகரித்தாலும், அந்த இடைவெளிக்குக் கீழே உள்ள blocks காலியாகவே இருக்கும். அந்த unit-ஐ restart செய்வது அல்லது அதன் ஆவணங்களில் குறிப்பிடப்பட்டுள்ள signal-ஐ அனுப்பி logs-ஐ மீண்டும் திறக்கச் செய்வதுதான் எந்தப் பிரச்சினையும் இல்லாத தீர்வாகும்.

df கட்டளை வட்டில் இடம் இருப்பதாகக் காட்டுகிறது, ஆனால் கோப்புகளை எழுத முடியவில்லை. வேறு என்ன காரணமாக இருக்கலாம்?

df -i கட்டளையைப் பயன்படுத்தி inodes-ஐச் சரிபார்க்கவும், ஏனெனில் வட்டில் blocks காலியாக இருந்தாலும் inodes காலியாக இல்லையென்றால் புதிய கோப்புகளை உருவாக்க முடியாது. ext4 filesystem-ல் reserved blocks மட்டுமே எஞ்சியிருக்கிறதா என்பதைச் சரிபார்க்கவும், இதை அந்த device-ல் sudo tune2fs -l மூலம் அறியலாம். நீங்கள் எழுதும் filesystem-ஐத்தான் df காட்டுகிறதா என்பதை உறுதிப்படுத்தவும், ஏனெனில் தனித்தனி /boot அல்லது /var போன்றவை /-லிருந்து சுதந்திரமாக நிரம்பக்கூடும்.

du கட்டளை ஏன் df-ஐ விட அதிக அளவைக் காட்டுகிறது?

-x flag இல்லாமல் du-ஐ இயக்கினால், அது நீங்கள் கொடுத்த பாதைக்குக் கீழே உள்ள அனைத்து mounted filesystems-களையும் சேர்த்து கணக்கிடும், ஆனால் df ஒரு குறிப்பிட்ட filesystem-ஐ மட்டுமே விவரிக்கும். Bind mounts இருந்தால் இது இன்னும் சிக்கலாகும், ஏனெனில் ஒரே கோப்பு பல பாதைகளில் தோன்றுவதால் ஒவ்வொரு முறையும் அது கணக்கிடப்படும். du ஒரே filesystem-க்குள் இருக்க -x-ஐச் சேர்க்கவும், மேலும் df-க்கு அதே பாதையைக் கொடுத்தால், இரண்டு கட்டளைகளும் ஒரே விஷயத்தை விவரிப்பதை உறுதி செய்யலாம்.