دستورات دیسک در لینوکس: فضا، inode و سلامت دیسک

راهنمای عملی دستورات دیسک در لینوکس؛ از df و du تا tune2fs و smartctl، همراه با خطاهای واقعی مثل No space left on device و رفع آن‌ها.

۶ دقیقه به‌روزرسانی ۱۵ مهر ۱۴۰۵

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

df و du: تفاوت را از کجا بفهمیم

دو دستور، دو سؤال متفاوت. df از فایل‌سیستم می‌پرسد «چقدر جا داری؟» و du از دایرکتوری‌ها می‌پرسد «چقدر مصرف کرده‌ای؟».

df -hT
df -i
du -sh /var/log/*
du -xhd1 / 2>/dev/null | sort -h

سوییچ -T نوع فایل‌سیستم را نشان می‌دهد (ext4، xfs، overlay). -i تعداد inode مصرف‌شده را می‌آورد و همان دستوری است که وقتی df -h فضا نشان می‌دهد ولی نوشتن ممکن نیست، باید اول اجرا کنی. سوییچ -x در du باعث می‌شود از مرز فایل‌سیستم عبور نکند؛ بدون آن، روی سروری که چند مانت دارد، خروجی بی‌معنی می‌شود و ممکن است دقیقه‌ها طول بکشد.

نکته‌ای که خیلی‌ها را غافلگیر می‌کند: اگر فایلی را حذف کرده‌ای ولی پروسه‌ای هنوز باز نگهش داشته، du آن را نمی‌بیند اما فضا آزاد نشده. این‌جا باید سراغ lsof +L1 بروی و پروسه را ری‌استارت کنی.

inode تمام شده ولی فضا آزاد است

این خطا را در عمل زیاد می‌بینم، مخصوصاً روی سرورهایی که session یا cache با فایل‌های ریز زیاد کار می‌کنند. علائم دقیقاً این‌هاست:

  • df -h فضای آزاد نشان می‌دهد.
  • df -i روی IUse% عدد ۱۰۰ می‌دهد.
  • هر نوشتن روی دیسک شکست می‌خورد، حتی touch /tmp/test.

راه‌حل سریع، پیدا کردن دایرکتوری با بیشترین تعداد فایل است:

for d in /var/*; do echo -n "$d: "; find "$d" -xdev | wc -l; done

معمولاً مقصر /var/lib/php/sessions یا /var/spool/postfix است. اگر تعداد فایل‌ها در یک دایرکتوری از چند صد هزار بگذرد، حتی ls هم کند می‌شود و باید با find ... -delete پاک‌سازی کنی، نه rm -rf *.

پارتیشن، مانت و fstab

وقتی دیسک جدید اضافه می‌کنی، ترتیب کار مهم است. اول با lsblk -f ببین دیسک شناسایی شده یا نه. اگر خروجی خالی بود، مشکل از لایه‌ی مجازی‌سازی است نه از لینوکس. بعد پارتیشن‌بندی و فرمت:

parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary ext4 0% 100%
mkfs.ext4 -L data /dev/sdb1
mkdir -p /mnt/data
mount /dev/sdb1 /mnt/data

در /etc/fstab هرگز نام /dev/sdb1 را ننویس. روی سروری که دیسک‌ها جابه‌جا می‌شوند، این کار باعث می‌شود سرور در بوت بعدی وارد emergency mode شود. از UUID استفاده کن:

UUID=8f3c1a2e-... /mnt/data ext4 defaults,noatime 0 2

گزینه‌ی noatime را جدی بگیر. روی سرور پرترافیک، حذف به‌روزرسانی زمان دسترسی می‌تواند ده‌ها IOPS در ثانیه صرفه‌جویی کند. قبل از ریبوت، همیشه mount -a بزن و findmnt --verify بگیر. اگر خطا داد، ریبوت نکن.

بررسی سلامت دیسک با smartctl

دیسک‌ها قبل از مردن، خبر می‌دهند. کافی است گوش کنی:

smartctl -a /dev/sda
smartctl -H /dev/nvme0

به سه فیلد نگاه کن: Reallocated_Sector_Ct، Pending_Sector و Media_Wearout_Indirect روی SSD. اگر Pending_Sector از صفر بالاتر رفت، دیسک را جایگزین کن؛ این عدد برنمی‌گردد. برای NVMe، دستور nvme smart-log /dev/nvme0 درصد مصرف عمر را مستقیم می‌دهد.

یک تست کوتاه هم بزن: smartctl -t short /dev/sda و بعد از دو دقیقه smartctl -l selftest /dev/sda. اگر تست در ۹۰ درصد موارد پاس شود ولی یک بار fail بدهد، آن یک بار کافی است.

این‌جا اشتباه می‌کنند

رایج‌ترین اشتباهی که می‌بینم این است: کسی df -h می‌زند، می‌بیند / پر است، و بعد rm -rf /var/log/* می‌زند. نتیجه؟ لاگ‌ها پاک می‌شوند، فضا آزاد می‌شود، و دو هفته بعد همان اتفاق می‌افتد چون کسی logrotate را تنظیم نکرده. بدتر: بعضی سرویس‌ها مثل MySQL به دایرکتوری لاگ وابسته‌اند و حذف آن‌ها باعث خطای startup می‌شود.

علامتش این است: بعد از پاک‌سازی، سرویس بالا نمی‌آید و در journalctl -xe خطای permission denied روی یک فایل لاگ می‌بینی. راه درست، تنظیم logrotate با maxsize و rotate مشخص است، نه پاک‌سازی دستی.

کدام ابزار را انتخاب کنیم

وضعیتابزارچرا
فضا پر است، نمی‌دانم کجاdu -xhd1سریع، بدون عبور از مرز فایل‌سیستم
فضا آزاد است ولی نوشتن نمی‌شودdf -iinode تمام شده
فایل حذف شده، فضا برنگشتهlsof +L1پروسه فایل را باز نگه داشته
شک به خرابی سخت‌افزارsmartctl -aتنها منبع قابل اعتماد

اگر سرور روی زیرساخت ابری است و دیسک از طریق شبکه وصل می‌شود، اعداد du ممکن است با df نخوانند؛ این طبیعی است و به دلیل بلاک‌های رزروشده و لایه‌ی ذخیره‌سازی است. در این حالت به df اعتماد کن، نه du.

برای سرورهایی که بار سنگین دارند و I/O دیسک گلوگاه شده، قبل از هر تصمیمی درباره‌ی ارتقای سخت‌افزار، تشخیص علت لود بالای سرور را بخوان؛ خیلی وقت‌ها مشکل از دیسک نیست، از یک کوئری یا پروسه‌ی سرگردان است. اگر هم قصد جابه‌جایی داده‌ها را داری، انتقال فایل با scp و rsync روش درست را با حفظ permission و resume نشان می‌دهد.

و اگر روزی دسترسی به سیستم‌عامل را کامل از دست دادی، بازنصب سرور و کار با حالت rescue مسیر نجات داده‌ها را قدم‌به‌قدم توضیح می‌دهد. برای سرورهای تولیدی که نمی‌توانی ریسک کنی، سرور اختصاصی با دیسک NVMe و کنترل کامل روی پارتیشن‌بندی، انتخاب منطقی‌تری است؛ و اگر بار کاری متغیر داری، سرور ابری امکان بزرگ‌کردن دیسک بدون downtime را می‌دهد. برای راه‌اندازی اولیه هم هاست لینوکس نقطه‌ی شروع ساده‌ای است.

پرسش‌های پرتکرار

چرا df فضای آزاد نشان می‌دهد ولی نمی‌توانم فایل بسازم؟

تقریباً همیشه مشکل inode است. با df -i بررسی کن؛ اگر IUse% روی ۱۰۰ باشد، فایل‌سیستم ظرفیت ساخت فایل جدید را ندارد حتی با وجود فضای آزاد. راه‌حل، پیدا کردن دایرکتوری با فایل‌های ریز زیاد و پاک‌سازی آن‌هاست.

حالت دوم این است که فایل حذف شده ولی پروسه‌ای هنوز باز نگهش داشته. با lsof +L1 پروسه را پیدا کن و ری‌استارتش کن تا فضا آزاد شود.

تفاوت du و df در چیست و کدام دقیق‌تر است؟

df از دید فایل‌سیستم گزارش می‌دهد و du از دید فایل‌ها و دایرکتوری‌ها. هیچ‌کدام «دقیق‌تر» نیستند، چون دو چیز متفاوت را اندازه می‌گیرند. برای تصمیم درباره‌ی پر بودن دیسک، df مرجع است.

اختلاف عددی بین این دو معمولاً از بلاک‌های رزروشده، فایل‌های حذف‌شده‌ی باز، و فایل‌سیستم‌های تودرتو می‌آید.

چطور بفهمم دیسک در حال خراب شدن است؟

با smartctl -a /dev/sda و نگاه به فیلدهای Reallocated_Sector_Ct و Pending_Sector. هر مقدار غیرصفر در این دو، نشانه‌ی جدی است. روی NVMe، دستور nvme smart-log درصد مصرف عمر را نشان می‌دهد.

تست کوتاه smartctl -t short هم مفید است، اما نبود خطا در تست به معنی سالم بودن قطعی دیسک نیست.

آیا noatime روی همه سرورها توصیه می‌شود؟

برای اکثر سرورهای وب و دیتابیس، بله. حذف به‌روزرسانی زمان دسترسی، بار نوشتن روی دیسک را کم می‌کند و روی SSD عمر مفید را بالا می‌برد. تنها استثنا سرورهایی هستند که ابزاری مثل tmpwatch یا اسکریپت پشتیبان‌گیری بر اساس atime کار می‌کند.

در آن صورت به‌جای noatime از relatime استفاده کن که تعادل بین این دو است.

آیا این مطلب برایتان مفید بود؟