بررسی فضای دیسک در لینوکس با df، du و ncdu

برای بررسی فضای دیسک در لینوکس، دستور df -h فضای کل، مصرف‌شده و آزاد هر پارتیشن را نشان می‌دهد و du -sh /مسیر اندازه یک پوشه را می‌دهد. وقتی دیسک پر شده، معمولاً با du -ah /var | sort -rh | head -20 بزرگ‌ترین فایل‌ها و پوشه‌ها پیدا می‌شوند. دستور df -i هم وضعیت inodeها را می‌گوید؛ دیسکی که فضا دارد ولی inodeهایش تمام شده، همان‌قدر نمی‌تواند فایل جدید بسازد.

پر شدن دیسک یکی از رایج‌ترین علت‌های خطای ناگهانی سرور است: دیتابیس متوقف می‌شود، لاگ نوشته نمی‌شود، وردپرس خطا می‌دهد و ایمیل‌ها گیر می‌کنند. پس بررسی دوره‌ای آن بخشی از نگهداری سرور است و در چک لیست نگهداری سرور هم آمده است.

مرحله اول: بررسی فضای دیسک در لینوکس با df

df -h
df -hT
df -h /var

خروجی نمونه:

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        50G   47G  1.2G  98% /
tmpfs           2.0G     0  2.0G   0% /dev/shm

ستون Use% مهم‌ترین است. بالای 85 تا 90 درصد باید اقدام کنید. گزینه -T نوع فایل‌سیستم را هم نشان می‌دهد. پارتیشن‌های tmpfs و overlay (مثلاً Docker) را جدا از دیسک واقعی بخوانید.

مرحله دوم: پیدا کردن مصرف‌کننده با du

sudo du -sh /var/* 2>/dev/null | sort -rh | head
sudo du -h --max-depth=1 / 2>/dev/null | sort -rh | head -15

از ریشه شروع کنید و هر بار وارد بزرگ‌ترین پوشه شوید. گزینه -x از رد شدن به پارتیشن‌های دیگر جلوگیری می‌کند:

sudo du -xh --max-depth=1 / | sort -rh | head

برای تحلیل تعاملی، ابزار ncdu بسیار راحت است:

sudo apt install ncdu
sudo ncdu -x /

با کلیدهای جهت‌دار پوشه‌ها را مرور می‌کنید و با d فایل را حذف می‌کنید؛ قبل از حذف مطمئن شوید فایل چیست. روش‌های پیدا کردن فایل با اندازه و تاریخ در راهنمای grep و find آمده است.

مقصرهای رایج

مسیرمحتوااقدام
/var/logلاگ‌های بزرگ و چرخش‌نشدهتنظیم logrotate، پاک‌سازی لاگ قدیمی
/var/lib/dockerایمیج، کانتینر و Volumedocker system df و پاک‌سازی ایمیج‌های بی‌استفاده
/var/lib/mysqlداده و باینری‌لاگ MySQLپاک‌سازی binlog قدیمی، بهینه‌سازی
/var/cache/aptبسته‌های دانلودشدهsudo apt clean
/home و /var/wwwبکاپ‌های فراموش‌شده، آپلودهابررسی و انتقال
/var/spool، /tmpصف ایمیل و فایل موقتبررسی صف و حذف قدیمی‌ها
journalلاگ systemdjournalctl --vacuum-size=500M

پاک‌سازی ایمن

همیشه قبل از حذف بدانید فایل چیست. چند اقدام کم‌خطر:

sudo apt clean
sudo apt autoremove
sudo journalctl --vacuum-time=14d
sudo docker system df
sudo docker image prune

دستور docker image prune ایمیج‌های بدون برچسب را حذف می‌کند. دستور docker system prune -a خیلی گسترده‌تر است و ایمیج‌های بی‌استفاده را هم پاک می‌کند؛ فقط وقتی مطمئن هستید اجرا کنید. برای لاگ‌ها، فایل را حذف نکنید، چون برنامه ممکن است هنوز به آن نوشته باشد و فضا آزاد نشود. در عوض خالی‌اش کنید:

sudo truncate -s 0 /var/log/example.log

روش درست‌تر، تنظیم logrotate است تا لاگ‌ها خودکار فشرده و حذف شوند.

فایل حذف‌شده که فضا را آزاد نمی‌کند

گاهی فایلی را حذف می‌کنید ولی df هنوز فضا را مصرف‌شده نشان می‌دهد. علت این است که پردازشی هنوز فایل را باز نگه داشته است:

sudo lsof +L1
sudo lsof | grep deleted

سرویس مربوط را ری‌استارت کنید تا فضا آزاد شود. این اتفاق برای لاگ‌های بزرگ رایج است.

مشکل inode

هر فایل یک inode مصرف می‌کند. اگر میلیون‌ها فایل کوچک (کش، نشست PHP، صف ایمیل) دارید، ممکن است inode تمام شود:

df -i
sudo find /var -xdev -type f | cut -d/ -f1-4 | sort | uniq -c | sort -rn | head

پوشه‌ای که بیشترین تعداد فایل را دارد، مقصر است. نشانه این مشکل، خطای No space left on device است در حالی که df -h فضای آزاد نشان می‌دهد. بعد از پیدا کردن پوشه، فایل‌های قدیمی را حذف کنید، مثلاً نشست‌ها و کش‌های قدیمی.

افزایش حجم دیسک بعد از بررسی فضای دیسک در لینوکس

اگر مصرف واقعی است و پاک‌سازی کافی نیست، حجم را افزایش دهید. اگر از LVM استفاده می‌کنید، می‌توان بدون راه‌اندازی مجدد حجم را زیاد کرد؛ مراحل آن در افزایش حجم دیسک لینوکس با LVM آمده است. اگر LVM ندارید، حجم دیسک را در پنل ارائه‌دهنده افزایش دهید و بعد پارتیشن و فایل‌سیستم را بزرگ کنید:

sudo growpart /dev/vda 1
sudo resize2fs /dev/vda1

برای XFS به‌جای resize2fs از xfs_growfs / استفاده کنید. نام دیسک و پارتیشن نمونه است؛ با lsblk مقدار واقعی را ببینید و پیش از تغییر، بکاپ بگیرید.

هشدار پیش از پر شدن

بهتر از واکنش بعد از پر شدن، هشدار زودهنگام است. ساده‌ترین روش، یک اسکریپت کرون است:

#!/bin/bash
USE=$(df / --output=pcent | tail -1 | tr -dc '0-9')
if [ "$USE" -ge 85 ]; then
  echo "Disk usage on $(hostname) is ${USE}%" | mail -s "Disk warning" admin@example.com
fi

آدرس ایمیل نمونه است و ارسال ایمیل به یک MTA تنظیم‌شده نیاز دارد. زمان‌بندی کرون در آموزش cron job لینوکس آمده است. برای راهکار کامل‌تر، از ابزار پایش مثل Zabbix یا Uptime Kuma استفاده کنید؛ مقایسه آن‌ها در مقایسه Zabbix، Prometheus و Nagios آمده است. دیگر دستورات پایش را در دستورات مانیتورینگ سرور لینوکس ببینید.

خطاهای رایج

نشانهعلت و راه حل
No space left on device با فضای آزاد در dfinode تمام شده؛ df -i را ببینید
فایل حذف کردم، فضا آزاد نشدپردازش فایل را باز نگه داشته؛ lsof +L1 و ری‌استارت سرویس
du و df اعداد متفاوت می‌دهندفایل‌های حذف‌شده‌ی باز، یا مصرف زیر نقطه‌اتصال دیگر
دیسک بعد از پاک‌سازی دوباره پر می‌شودلاگ یا کش بدون چرخش؛ logrotate را تنظیم کنید
du خیلی کند استاز -x و محدودکردن مسیر یا ncdu استفاده کنید
بعد از resize2fs تغییری نیستپارتیشن بزرگ نشده؛ lsblk و growpart را بررسی کنید

سوالات متداول

چقدر فضای آزاد لازم است؟

قاعده ثابتی نیست، ولی پایین‌تر از 10 تا 15 درصد آزاد برای سرور تولیدی خطرناک است. دیتابیس و لاگ به فضای نوشتن نیاز دارند.

آیا حذف /var/log امن است؟

کل پوشه را حذف نکنید. فایل‌های لاگ قدیمی و فشرده را پاک کنید یا logrotate را تنظیم کنید و فایل‌های فعال را فقط خالی کنید.

چرا df و du اندازه متفاوتی نشان می‌دهند؟

df اندازه کل فایل‌سیستم را از دید سیستم می‌دهد. du فقط فایل‌های قابل مشاهده را جمع می‌زند. فایل‌های حذف‌شده‌ی باز و پارتیشن‌های دیگر این تفاوت را می‌سازند.

چطور از تکرار آن جلوگیری کنم؟

چرخش لاگ، پاک‌سازی دوره‌ای، هشدار در 80 تا 85 درصد، و بررسی ماهانه رشد مصرف.

منابع