🎉✨ افتتاحیه ویژه! اولین سفارش شما = ۱۰٪ تخفیف 🎁 کد: NEW10 🛍️
راهنمای اضطراری Storage

رفع پرشدن فضای دیسک لینوکس
اول تشخیص، بعد پاک‌سازی هدفمند

خطای <code>No space left on device</code> همیشه به معنی یک فایل بزرگ نیست؛ ممکن است blockهای filesystem، inodeها، journal، لایه‌های Docker یا فایلی که حذف شده ولی هنوز توسط process باز است عامل باشند. پاک‌کردن تصادفی در <code>/var</code> می‌تواند دیتابیس یا سرویس را خراب کند. این راهنما عمداً با فرمان‌های فقط‌خواندنی شروع می‌شود و هیچ دستور پاک‌سازی کلی، اجباری یا بدون بازبینی ارائه نمی‌دهد.

۱) در وضعیت اضطراری، نوشتن را کم و شواهد را حفظ کنید

اگر filesystem صددرصد شده، سرویس‌ها ممکن است نتوانند log، PID، session یا فایل موقت بنویسند و رفتار زنجیره‌ای ایجاد شود. از کنسول وارد شوید، زمان شروع خطا و سرویس‌های متاثر را ثبت کنید و از اجرای upgrade، build، backup محلی یا restartهای پیاپی که نوشتن بیشتری ایجاد می‌کنند خودداری کنید.

date -Is
uptime
df -hT
df -ih
findmnt
lsblk -f

هدف نخست این است که مشخص شود کدام mount پر است. پرشدن /var با پرشدن /home یا filesystem ریشه یکسان نیست. اگر یک process با سرعت زیاد داده تولید می‌کند، قبل از توقف آن نقش سرویس، پیامد توقف و مسیر بازیابی را بررسی کنید؛ توقف کور دیتابیس یا queue می‌تواند خرابی بیشتری بسازد.

خط قرمز: فرمان‌هایی مثل rm -rf، find -delete، truncate کردن log فعال یا prune اجباری Docker را برای «خالی‌کردن سریع» اجرا نکنید. اول مالک داده و امکان بازگردانی را مشخص کنید.

۲) فرق block پر و inode پر را تشخیص دهید

df -hT ظرفیت blockها را برای هر filesystem و df -ih مصرف inodeها را نشان می‌دهد. ممکن است GiB آزاد داشته باشید اما inodeها به‌دلیل میلیون‌ها فایل کوچک تمام شده باشند؛ در این حالت حذف یک فایل چندگیگابایتی مسئله‌ی inode را توضیح نمی‌دهد.

df -hT /
df -ih /
findmnt -T /var
stat -f /var

ستون Mounted on را ملاک قرار دهید. du برای hierarchy دایرکتوری است و df وضعیت کل filesystem را می‌بیند؛ بنابراین عددهای آن‌ها الزاماً برابر نیست. reserved blockها، metadata، snapshotها و فایل حذف‌شده‌ی باز می‌توانند اختلاف بسازند.

اگر inode پر است، به‌جای جست‌وجوی «بزرگ‌ترین فایل»، directoryهای دارای تعداد بسیار زیاد فایل را پیدا کنید. شمارش کل filesystem می‌تواند I/O زیادی بسازد؛ از مسیر مظنون مانند cache، session، mail queue یا upload شروع و در ساعت کم‌بار عمیق‌تر شوید.

۳) مصرف را از mount به directory و فایل محدود کنید

برای جلوگیری از عبور به mountهای دیگر، گزینه‌ی -x را به du بدهید. اسکن root روی سرور بزرگ سنگین است؛ ابتدا سطح اول را ببینید و فقط وارد شاخه‌ی بزرگ شوید:

sudo du -xhd1 / 2>/dev/null | sort -h
sudo du -xhd1 /var 2>/dev/null | sort -h
sudo du -xhd1 /var/lib 2>/dev/null | sort -h
sudo du -xhd1 /var/log 2>/dev/null | sort -h

برای یافتن فایل‌های بزرگ در mount مظنون، جست‌وجو را به همان مسیر و filesystem محدود کنید. خروجی زیر فایل‌های بزرگ‌تر از 500 MiB را فهرست می‌کند و چیزی را حذف نمی‌کند:

sudo find /var -xdev -type f -size +500M -ls 2>/dev/null | sort -k7 -n

اندازه، زمان تغییر، مالک و نام فایل را کنار هم ببینید. یک فایل دیتابیس، image ماشین مجازی، WAL، backup یا object store صرفاً چون بزرگ است «اضافی» نیست. پیش از اقدام از stat FILE_PATH و ابزار خود برنامه برای شناخت داده استفاده کنید. اسکن را با nice یا در بازه کم‌بار اجرا کنید اگر latency دیسک برای سرویس حساس است.

۴) اختلاف df و du را با فایل حذف‌شده‌ی باز بررسی کنید

در Linux اگر یک فایل unlink شود اما process هنوز file descriptor آن را باز نگه دارد، نام فایل از directory ناپدید می‌شود و du آن را نمی‌بیند؛ بااین‌حال blockها تا بسته‌شدن descriptor آزاد نمی‌شوند و df همچنان مصرف را نشان می‌دهد. این یکی از علت‌های رایج اختلاف بزرگ df و du است.

sudo lsof +L1

ستون‌های COMMAND، PID، USER، SIZE/OFF و NAME را بررسی کنید. راه‌حل معمول این است که برنامه log را به‌درستی reopen کند یا سرویس مسئول در یک پنجره‌ی نگهداری controlled restart شود؛ کشتن PID ناشناس ممکن است باعث قطع سرویس یا recovery دیتابیس شود. ابتدا unit یا container مالک، کاربران متصل و امکان failover را مشخص کنید.

برای جلوگیری از تکرار، logrotate یا قابلیت rotation داخلی برنامه را تنظیم کنید تا پس از rename، process فایل تازه را باز کند. حذف دستی log درحالی‌که برنامه هنوز می‌نویسد هم شواهد را از بین می‌برد و هم لزوماً فضا را آزاد نمی‌کند.

۵) مصرف‌کننده‌های رایج را با ابزار خودشان اندازه بگیرید

systemd journal و logها: ابتدا حجم و تنظیم rotation را فقط بررسی کنید:

sudo journalctl --disk-usage
sudo du -xhd1 /var/log 2>/dev/null | sort -h
sudo logrotate --debug /etc/logrotate.conf

حالت --debug در logrotate تغییری اعمال نمی‌کند. گزینه‌های vacuum در journal فایل‌های archived را حذف می‌کنند؛ مقدار retention را از روی نیاز audit و رخداد امنیتی تعیین کنید و قبل از استفاده، اثر دقیق آن را در مستند رسمی بخوانید. این صفحه عمداً فرمان vacuum آماده‌ی کپی ارائه نمی‌دهد.

APT: اندازه‌ی cache و پیشنهادهای احتمالی را بدون حذف ببینید:

sudo du -sh /var/cache/apt/archives
sudo apt-get -s autoremove

-s شبیه‌سازی است. فهرست autoremove را خط‌به‌خط بازبینی کنید؛ packageای که برنامه‌ی خارج از package manager به آن وابسته است ممکن است از دید APT «خودکار» باشد.

Docker: ابتدا سهم image، container، volume و build cache را اندازه بگیرید:

sudo docker system df -v
sudo docker ps -a --size
sudo docker volume ls

volumeها می‌توانند دیتابیس و upload دائمی باشند. docker system prune و به‌ویژه volume prune عملیات حذف هستند؛ تا زمانی که وابستگی، label، backup و آزمون بازیابی هر مورد روشن نشده آن‌ها را اجرا نکنید.

۶) برای پاک‌سازی، تصمیم هدفمند و قابل‌بازگشت بسازید

پس از شناسایی مصرف‌کننده، به‌جای «پاک‌سازی لینوکس» یک تصمیم مشخص بنویسید: چه داده‌ای، متعلق به کدام سرویس، مربوط به چه بازه‌ای، با چه سیاست retention و با چه روش بازیابی. برای log قدیمی می‌توان rotation و retention تعریف کرد؛ برای artifact ساخت می‌توان نسخه‌های بلااستفاده را از registry یا ابزار build مدیریت کرد؛ برای دیتابیس باید از ابزار خود موتور و سیاست backup استفاده شود.

  1. با stat، package manager یا ابزار برنامه مالک داده را مشخص کنید.
  2. تأیید کنید داده live، snapshot، backup، transaction log یا volume فعال نیست.
  3. نسخه‌ی پشتیبان را خارج از همان filesystem نگه دارید و بازیابی نمونه را آزمایش کنید.
  4. کوچک‌ترین مجموعه‌ی لازم را انتخاب و تغییر را در پنجره‌ی نگهداری انجام دهید.
  5. پس از اقدام، df، سلامت سرویس، log و metric را دوباره کنترل کنید.

جابجایی فایل به directory دیگری روی همان filesystem فضا آزاد نمی‌کند. انتقال بین filesystemها نیز تا پایان کپی به فضای موقت نیاز دارد و قطع‌شدن آن می‌تواند حالت مبهم بسازد. برای داده‌ی فعال، روش export/archive خود برنامه امن‌تر از دست‌کاری مستقیم فایل‌هاست.

۷) از تکرار جلوگیری کنید یا ظرفیت را اصولی افزایش دهید

برای journal و logهای متنی سقف اندازه و زمان نگهداری متناسب با نیاز رخداد تعریف کنید؛ rotation را در حالت debug آزمایش و برای سرویس‌هایی که باید log را reopen کنند hook درست بگذارید. برای Docker، imageهای pinشده، build cache و log driver را پایش کنید. برای دیتابیس، رشد table، WAL/binlog و backup را جدا metric بگیرید. هشدار ظرفیت را پیش از 100٪، هم برای block و هم inode تنظیم کنید.

اگر داده واقعاً لازم است، حذف راه‌حل نیست و باید دیسک یا filesystem را گسترش داد. قبل از هر resize این خروجی‌ها را جمع کنید:

lsblk -f
findmnt
sudo pvs
sudo vgs
sudo lvs
df -hT

فرمان گسترش به partition table، LVM یا نبود LVM، نوع filesystem مانند ext4/XFS و محل فضای آزاد بستگی دارد. اجرای یک دستور عمومی روی device حدسی می‌تواند داده را از دسترس خارج کند؛ ابتدا دیسک مجازی را در لایه‌ی زیرساخت گسترش دهید، backup و کنسول داشته باشید و سپس راهنمای رسمی متناسب با layout واقعی را دنبال کنید.

بعد از افزایش ظرفیت نیز علت رشد را رفع کنید. دیسک بزرگ‌تر بدون retention و alert فقط زمان وقوع حادثه‌ی بعدی را عقب می‌اندازد.

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

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

چرا df دیسک را پر نشان می‌دهد ولی du فایل بزرگی پیدا نمی‌کند؟

df کل filesystem را می‌سنجد و du فقط hierarchy قابل مشاهده را. فایل حذف‌شده‌ای که process هنوز باز نگه داشته، reserved blocks، metadata، snapshot یا نبود دسترسی می‌تواند اختلاف بسازد. lsof +L1 را بررسی کنید.

خطای No space left on device با وجود فضای آزاد از چیست؟

ممکن است inodeها تمام شده باشند. df -ih را ببینید؛ میلیون‌ها فایل کوچک می‌توانند inode را پر کنند درحالی‌که هنوز block آزاد وجود دارد.

آیا پاک‌کردن فایل‌های /var/log امن است؟

نه به‌صورت کلی. برخی logها برای audit و عیب‌یابی لازم‌اند و فایل باز ممکن است با حذف هم فضا آزاد نکند. مالک سرویس، rotation، retention و نیاز نگهداری را مشخص کنید.

آیا docker system prune برای آزادکردن فضا مناسب است؟

این فرمان اشیای بلااستفاده از دید Docker را حذف می‌کند و بسته به گزینه‌ها می‌تواند container، image، cache یا volume را از بین ببرد. ابتدا docker system df -v و وابستگی هر مورد را بررسی و backup را آزمایش کنید.

چطور فایل‌های بزرگ را بدون حذف پیدا کنم؟

با du -x از سطح mount به directory بزرگ بروید و سپس find را با -xdev و حد اندازه روی همان مسیر اجرا کنید. خروجی فقط فهرست است؛ بزرگ‌بودن به معنی قابل‌حذف‌بودن نیست.

برای حل دائمی، پاک‌سازی بهتر است یا افزایش دیسک؟

داده‌ی زائد باید با retention هدفمند مدیریت شود؛ داده‌ی لازم به ظرفیت بیشتر نیاز دارد. در هر دو حالت علت رشد، alert و آزمون بازیابی ضروری است. resize باید مطابق layout واقعی LVM و filesystem انجام شود.

منابع

منابع رسمی و مطالعه بیشتر

منابع سرور را بر اساس رشد واقعی انتخاب کنید

مصرف دیسک، inode، log و داده‌ی ماندگار برنامه را اندازه بگیرید و برای رشد و بازیابی ظرفیت در نظر بگیرید.

صفحات مرتبط

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