خطای هارد دیسک پر شده یکی از آن فاجعه‌های خاموشی است که تا لحظه‌ی آخر هیچ صدایی نمی‌دهد، و بعد یک‌شبه همه‌چیز را می‌خواباند. کاربر سایت را باز می‌کند، صفحه‌ی سفید می‌بیند؛ پیشخوان وردپرس لود نمی‌شود؛ بکاپ شبانه ناقص ذخیره می‌شود بدون این‌که کسی متوجه شود؛ و دیتابیس MySQL از نوشتن هر رکورد جدید امتناع می‌کند. سال‌هاست روی سرورهای تولیدی با این خطا مواجه می‌شوم و در تجربه‌ام، اکثر مدیران سایت این خطا را با کندی یا مشکلات PHP اشتباه می‌گیرند و مسیر عیب‌یابی را از ابتدا اشتباه می‌روند.

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

پرشدن دیسک دقیقاً چه بلایی سر سایت می‌آورد؟

وقتی فضای دیسک سرور به سقف می‌رسد، زنجیره‌ای از خرابی‌ها به‌طور همزمان شروع می‌شود که هر کدام به‌تنهایی می‌توانند سایت را از کار بیندازند. اولین قربانی، معمولاً دیتابیس MySQL یا MariaDB است. دیتابیس برای هر تراکنش، به فضای موقت و فضای لاگ نیاز دارد. اگر این فضا در دسترس نباشد، MySQL از نوشتن امتناع می‌کند و خطای Disk full یا No space left on device برمی‌گرداند. وردپرس در مواجهه با این خطا، معمولاً به‌جای پیام واضح، یک خطای عمومی نمایش می‌دهد. مباحث پایه‌ای این سناریو در سرور چیست و چگونه کار می‌کند باز شده است.

دومین قربانی، سرویس PHP-FPM است. برای هر درخواست PHP، این سرویس به فضای موقت، فضای سشن و فضای لاگ نیاز دارد. اگر این فضا نباشد، PHP-FPM نمی‌تواند درخواست را پردازش کند و پیام‌های داخلی مثل Unable to write session data یا Failed to open stream در لاگ ظاهر می‌شود. در این حالت، سایت با خطای سفید یا 500 پاسخ می‌دهد. تجربه‌ی چندساله‌ام نشان داده که اکثر مدیران سایت در این مرحله به سراغ افزونه‌ها می‌روند، در حالی که ریشه در لایه‌ی زیرین است.

سومین قربانی، سیستم بکاپ‌گیری است. اگر فضای دیسک پر شده باشد، اسکریپت بکاپ نمی‌تواند فایل جدید را ذخیره کند و به‌جای هشدار، معمولاً بی‌سروصدا شکست می‌خورد. این پدیده یکی از خطرناک‌ترین رفتارهای بحران دیسک است؛ چون چند هفته بعد که می‌خواهید بکاپ را بازیابی کنید، متوجه می‌شوید هیچ بکاپ سالمی وجود ندارد. مباحث مرتبط با این حوزه در پشتیبان‌گیری از سایت وردپرس باز شده است.

چهارمین قربانی، سرویس ایمیل و صف‌های ارسال است. اگر سرور شما ایمیل ارسال می‌کند (مثل اعلان سفارش‌های ووکامرس)، پر شدن دیسک باعث می‌شود پیام‌ها در صف بمانند و ارسال نشوند. این سناریو در فروشگاه‌های اینترنتی که به‌سرعت سفارش می‌گیرند، می‌تواند به یک بحران اعتمادسازی تبدیل شود. مباحث مرتبط در رفع خطای درگاه پرداخت ووکامرس و رفع خطاهای رایج ووکامرس باز شده است.

هیچ خطای سروری به اندازه‌ی پرشدن دیسک، بی‌صدا و جامع نیست؛ چون هم‌زمان روی دیتابیس، PHP، بکاپ، ایمیل و کش اثر می‌گذارد.

نشانه‌های هشدار پیش از فاجعه

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

کندی تدریجی سایت

وقتی فضای دیسک به زیر ۱۵ درصد می‌رسد، سرعت I/O کاهش می‌یابد، چون فایل‌سیستم برای جا دادن داده‌های جدید دچار تکه‌تکه شدن (fragmentation) می‌شود. این کندی در ابتدا خفیف است ولی به‌مرور شدید می‌شود. مباحث مرتبط با این کندی در رفع کندی شدید سایت وردپرسی باز شده است.

خطاهای مکرر در لاگ

لاگ PHP و لاگ وب‌سرور معمولاً پیام‌های هشدار را ثبت می‌کنند: write failed: No space left on device، Unable to write to log file، یا Disk quota exceeded. اگر این پیام‌ها را در لاگ دیدید، بلافاصله فضای دیسک را بررسی کنید. روش دقیق خواندن لاگ در بررسی خطاهای سرور در لاگ‌ها باز شده است.

بکاپ‌های ناقص

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

کندی پیشخوان وردپرس

پیشخوان وردپرس به فضای دیسک برای ذخیره‌ی سشن، ترنزینت و کش نیاز دارد. اگر این فضا محدود شود، ذخیره‌ی یک نوشته یا آپدیت افزونه می‌تواند ثانیه‌ها طول بکشد یا شکست بخورد.

خطاهای ووکامرس در ثبت سفارش

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

ده مقصر اصلی پرشدن دیسک سرور

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

مقصر اول: لاگ‌های انباشته

شایع‌ترین دلیل. اگر logrotate در سرور به‌درستی تنظیم نشده باشد یا اگر افزونه‌ای لاگ‌های سطح debug ذخیره کند، حجم لاگ‌ها می‌تواند به چندین گیگابایت برسد. این سناریو در سایت‌هایی که افزونه‌ی debug فعال دارند یا در سرورهای بدون تنظیمات logrotate، شایع‌تر است.

مقصر دوم: بکاپ‌های یتیم و قدیمی

اگر تنظیم حذف بکاپ‌های قدیمی وجود نداشته باشد، این بکاپ‌ها به‌مرور انباشته می‌شوند و فضای دیسک را اشغال می‌کنند. یک بکاپ کامل ۱۰ گیگابایتی، در سه ماه می‌تواند به ۹۰ گیگابایت برسد. این سناریو در سایت‌های با فایل‌های رسانه‌ی زیاد، بحرانی‌تر است. مباحث مرتبط در بهترین افزونه‌های بکاپ وردپرس باز شده است.

مقصر سوم: فایل‌های cache

افزونه‌های کش وردپرس، فایل‌های HTML استاتیک را در پوشه‌ی wp-content/cache ذخیره می‌کنند. اگر این فایل‌ها به‌درستی پاک نشوند، می‌توانند فضای قابل توجهی اشغال کنند. مباحث مرتبط در بهترین افزونه‌های کش وردپرس باز شده است.

مقصر چهارم: ترنزینت‌های منقضی‌شده

در وردپرس، ترنزینت‌ها (transients) برای ذخیره‌ی موقت داده‌ها استفاده می‌شوند. اگر افزونه‌ای به‌درستی آن‌ها را پاک نکند، ردیف‌های منقضی‌شده در جدول wp_options انباشته می‌شوند و حجم دیتابیس را بالا می‌برند. این سناریو در سایت‌های با افزونه‌های زیاد، بحرانی‌تر است.

مقصر پنجم: پوشه‌ی uploads با رسانه‌های بی‌استفاده

هر فایل رسانه‌ای که در وردپرس آپلود می‌شود، در پوشه‌ی wp-content/uploads ذخیره می‌شود. اگر این فایل‌ها به‌موقع حذف نشوند یا اگر پلتفرم شما نسخه‌های متعدد از یک تصویر تولید کند، این پوشه می‌تواند به چند ده گیگابایت برسد. مباحث مرتبط در بهترین افزونه‌های بهینه‌سازی تصویر باز شده است.

مقصر ششم: فایل‌های binlog دیتابیس

در MySQL و MariaDB، فایل‌های binlog برای replication و بازیابی استفاده می‌شوند. اگر این فایل‌ها به‌درستی پاک نشوند، می‌توانند چندین گیگابایت فضای دیسک را اشغال کنند. این سناریو در سرورهای بدون تنظیم دقیق expire_logs_days شایع است. مباحث مرتبط در تأثیر دیتابیس بر سرعت سایت باز شده است.

مقصر هفتم: سشن‌های قدیمی

در بعضی پیکربندی‌ها، سشن‌های PHP روی دیسک ذخیره می‌شوند. اگر سشن‌های قدیمی به‌درستی پاک نشوند (garbage collection غیرفعال یا ناقص)، انباشته می‌شوند و فضای دیسک را اشغال می‌کنند. این سناریو در سرورهای با ترافیک بالا، بحرانی‌تر است.

مقصر هشتم: فایل‌های موقت آپلود

هر آپلود فایل در وردپرس، ابتدا در مسیر موقت (معمولاً /tmp) ذخیره می‌شود و سپس به مقصد نهایی منتقل می‌شود. اگر این فایل‌ها به‌دلیل خطا یا قطع فرآیند، پاک نشوند، انباشته می‌شوند. در سرورهایی که /tmp جداگانه محدود نشده، این پوشه می‌تواند سرریز شود.

مقصر نهم: فایل‌های هسته‌ی اضافی (core dumps)

اگر سرویسی روی سرور شما دچار crash شود، سیستم‌عامل ممکن است فایل core dump را برای تحلیل ذخیره کند. این فایل‌ها می‌توانند هر کدام چند صد مگابایت باشند و در پوشه‌ی کاری سرویس انباشته شوند.

مقصر دهم: ایمیل‌های صف‌مانده

اگر سرور شما از سرویس Mail Queue استفاده می‌کند و ایمیل‌های ارسال‌نشده در صف انباشته شوند (مثلاً به‌دلیل خطای SMTP یا اسپم)، این صف می‌تواند فضای دیسک را اشغال کند. این سناریو در فروشگاه‌های با اعلان‌های ایمیلی زیاد، شایع‌تر است.

پروتکل واکنش سریع در بحران

اگر سایت شما همین حالا با خطای پرشدن دیسک رو‌به‌رو است و کاربران نمی‌توانند به سایت دسترسی پیدا کنند، این پنج حرکت را به همین ترتیب اجرا کنید:

  1. تعیین سطح بحران: با دستور df -h ببینید چه درصدی از دیسک پر شده. اگر بالای ۹۵ درصد است، بحران فوری است. اگر بین ۸۰ و ۹۵ است، فرصت کوتاه اقدام دارید.
  2. یافتن سریع مقصر: با du -sh /* 2>/dev/null | sort -h | tail -20 می‌توانید بزرگ‌ترین پوشه‌های سطح ریشه را ببینید. این کار سریع‌ترین راه پیدا کردن مقصر است.
  3. پاک‌سازی سریع و ایمن: ابتدا لاگ‌های قدیمی، بکاپ‌های منقضی و کش‌ها را پاک کنید. اگر فایل‌های لاگ را پاک می‌کنید، به‌جای حذف کامل، حجم آن را با truncate صفر کنید تا سرویس‌های در حال نوشتن دچار مشکل نشوند.
  4. ری‌استارت سرویس‌های حیاتی: بعد از آزادسازی فضا، MySQL و PHP-FPM را ری‌استارت کنید تا سرویس‌ها فضای آزاد جدید را ببینند.
  5. بکاپ فوری: بلافاصله بعد از بازگردانی سرویس، یک بکاپ کامل بگیرید. بحران دیسک می‌تواند داده‌ها را در وضعیت نیمه‌نوشته رها کرده باشد.

نکته‌ی میدانی: در بحران دیسک، هیچ‌گاه به‌طور همزمان چند پوشه را پاک نکنید. اول پاک‌سازی کوچک انجام دهید و دوباره df -h بگیرید. این ترتیب، از حذف اشتباهی جلوگیری می‌کند و اجازه می‌دهد مقصر واقعی را پیدا کنید.

تشخیص دقیق با df و du و ncdu

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

df: نمای کلی دیسک

دستور df (disk free) نمای کلی فضای دیسک را نشان می‌دهد:

df -h
df -i

گزینه‌ی -h حجم را به‌صورت خوانا (human-readable) نشان می‌دهد و گزینه‌ی -i آمار inode را. اگر df -h نشان می‌دهد دیسک پر است ولی df -i نشان می‌دهد inode کم است، مشکل شما پرشدن inode است نه فضای دیسک. این تفکیک، در تشخیص خیلی مهم است.

du: حجم پوشه‌ها

دستور du (disk usage) حجم پوشه‌ها و فایل‌ها را نشان می‌دهد:

du -sh /var/log/*
du -sh /home/*/public_html/*
du -sh /var/lib/mysql/*

ترکیب du با sort و tail، سریع‌ترین راه پیدا کردن بزرگ‌ترین مقصر است:

du -sh /* 2>/dev/null | sort -h | tail -20

ncdu: بررسی تعاملی

ابزار ncdu (NCurses Disk Usage) نسخه‌ی تعاملی du است و اجازه می‌دهد با کلیدهای جهت‌دار در ساختار پوشه‌ها حرکت کنید و بزرگ‌ترین مقصر را پیدا کنید. برای نصب:

sudo apt install ncdu
ncdu /var

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

lsof: پیدا کردن فایل‌های حذف‌شده ولی باز

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

lsof | grep deleted

اگر فایل‌های حذف‌شده‌ی بزرگی دیدید، باید پروسه‌ی مربوطه را ری‌استارت کنید تا فایل آزاد شود.

لاگ‌های انباشته و تنظیم logrotate

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

پوشه‌های کلیدی لاگ

پنج پوشه‌ی کلیدی که باید بررسی کنید:

  • /var/log/: لاگ‌های سیستمی و سرویس‌ها
  • /var/log/nginx/ یا /var/log/apache2/: لاگ‌های وب‌سرور
  • /var/log/mysql/: لاگ‌های دیتابیس
  • /var/log/php*-fpm.log: لاگ‌های PHP-FPM
  • /var/log/mail.log: لاگ‌های ایمیل

تنظیم logrotate

ابزار logrotate به‌طور خودکار لاگ‌ها را می‌چرخاند و نسخه‌های قدیمی را حذف می‌کند. اگر این ابزار روی سرور شما نصب یا به‌درستی تنظیم نشده باشد، لاگ‌ها انباشته می‌شوند. نمونه‌ی یک فایل تنظیمات برای سایت وردپرسی:

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        /usr/sbin/nginx -s reload
    endscript
}

این تنظیمات، لاگ‌ها را روزانه می‌چرخاند، حداکثر ۱۴ نسخه نگه می‌دارد و نسخه‌های قدیمی را فشرده می‌کند. مباحث مرتبط در بررسی خطاهای سرور در لاگ‌ها باز شده است.

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

اگر می‌خواهید یک فایل لاگ بزرگ را پاک کنید، به‌جای حذف کامل، از دستور truncate استفاده کنید:

truncate -s 0 /var/log/nginx/access.log

این دستور، حجم فایل را صفر می‌کند ولی فایل را حذف نمی‌کند. اگر فایل را حذف کنید، سرویس در حال نوشتن دچار خطا می‌شود و ممکن است کرش کند.

بکاپ‌های یتیم و مدیریت آرشیو

بکاپ‌ها، دومین مقصر شایع پرشدن دیسک هستند. هر بکاپ کامل از سایت شما می‌تواند چند گیگابایت باشد و اگر تنظیم حذف خودکار نداشته باشید، به‌سرعت دیسک را پر می‌کنند.

بکاپ‌های محلی و بکاپ‌های بیرونی

نکته‌ی مهمی که در پروژه‌های واقعی بارها دیده‌ام این است که بکاپ‌ها نباید روی همان دیسکی ذخیره شوند که سایت روی آن اجرا می‌شود. اگر دیسک پر شود، هم سایت از کار می‌افتد و هم بکاپ آسیب می‌بیند. راه‌حل: انتقال بکاپ‌ها به فضای ذخیره‌سازی بیرونی مثل Object Storage، Google Drive یا سرور دیگر. مباحث مرتبط در افزونه‌های بکاپ وردپرس باز شده است.

تنظیم سیاست نگه‌داری

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

پاک‌سازی بکاپ‌های ناقص

در بحران دیسک، بکاپ‌های ناقصی که به‌دلیل کمبود فضا نیمه‌کاره ذخیره شده‌اند، باید سریعاً پاک شوند. برای پیدا کردن این فایل‌ها:

find /backup -type f -size -1M -mtime +1

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

کش، ترنزینت و سشن‌های قدیمی

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

پوشه‌ی کش وردپرس

پوشه‌ی wp-content/cache معمولاً حجم قابل توجهی دارد. اگر از افزونه‌ی کش استفاده می‌کنید، این پوشه باید به‌طور دوره‌ای پاک شود. مقدار پیشنهادی حجم این پوشه در سایت‌های متوسط، کمتر از ۱ گیگابایت است.

du -sh wp-content/cache/*
rm -rf wp-content/cache/*

ترنزینت‌ها در دیتابیس

ترنزینت‌های منقضی‌شده در جدول wp_options ذخیره می‌شوند. برای حذف آن‌ها، می‌توانید از این کوئری استفاده کنید:

DELETE FROM wp_options
WHERE option_name LIKE '_transient_%'
  AND option_value < UNIX_TIMESTAMP() - 604800;

توجه: این کوئری، ترنزینت‌های منقضی‌شده‌ی بیش از هفت روز را حذف می‌کند. قبل از اجرا، بکاپ دیتابیس بگیرید.

سشن‌های PHP

پوشه‌ی سشن‌های PHP معمولاً /var/lib/php/sessions/ است. برای بررسی حجم:

du -sh /var/lib/php/sessions/
find /var/lib/php/sessions/ -type f -mtime +7 -delete

این دستور، سشن‌های قدیمی‌تر از هفت روز را حذف می‌کند. تنظیم garbage collection PHP برای پاک‌سازی خودکار توصیه می‌شود.

پوشه‌ی uploads و رسانه‌های بی‌استفاده

پوشه‌ی wp-content/uploads معمولاً بزرگ‌ترین پوشه‌ی یک سایت وردپرسی است. هر فایل رسانه‌ای که آپلود می‌شود، در این پوشه ذخیره می‌شود و نسخه‌های متعدد آن (thumbnail, medium, large) نیز تولید می‌شوند.

شناسایی رسانه‌های بی‌استفاده

افزونه‌های زیادی برای شناسایی رسانه‌های بی‌استفاده وجود دارد که فایل‌هایی که در هیچ نوشته‌ای استفاده نشده‌اند را نشان می‌دهند. پاک‌سازی این فایل‌ها می‌تواند فضای قابل توجهی آزاد کند. مباحث مرتبط در اشتباهات رایج در بهینه‌سازی تصاویر باز شده است.

حذف فایل‌های موقت ویرایشگر

بعضی افزونه‌ها، فایل‌های موقت ویرایشگر (مثل -edited.jpg) در پوشه‌ی uploads ایجاد می‌کنند که بعد از ذخیره‌ی نهایی، باقی می‌مانند. پیدا کردن و حذف این فایل‌ها:

find /path/to/wordpress/wp-content/uploads/ -name '*-edited.jpg' -type f

دیتابیس و فایل‌های binlog

دیتابیس MySQL یا MariaDB، به‌طور پنهان می‌تواند حجم قابل توجهی از دیسک را اشغال کند. سه منبع اصلی:

فایل‌های binlog

فایل‌های binlog برای ثبت تغییرات دیتابیس استفاده می‌شوند. اگر این فایل‌ها به‌درستی پاک نشوند، می‌توانند چندین گیگابایت فضای دیسک را اشغال کنند. بررسی و تنظیم:

ls -lh /var/lib/mysql/*bin*
SHOW VARIABLES LIKE 'expire_logs_days';

برای تنظیم مدت زمان نگه‌داری binlog، می‌توانید در فایل my.cnf مقدار expire_logs_days را تنظیم کنید. مقدار پیشنهادی ۷ روز است.

جدول‌های بزرگ و ایندکس‌های اضافی

در سایت‌های چندساله، جدول wp_postmeta می‌تواند به چند گیگابایت برسد. برای بررسی حجم جدول‌ها:

SELECT table_name, table_rows, data_length, index_length
FROM information_schema.tables
WHERE table_schema = 'your_database_name'
ORDER BY data_length DESC
LIMIT 20;

پاک‌سازی داده‌های قدیمی و بهینه‌سازی جدول‌ها می‌تواند فضای قابل توجهی آزاد کند. مباحث مرتبط در تأثیر دیتابیس بر سرعت سایت باز شده است.

فایل‌های ibdata و ib\_logfile

در MySQL با موتور InnoDB، فایل‌های ibdata و ib_logfile می‌توانند به‌طور پیش‌فرض بزرگ باشند. این فایل‌ها به‌صورت خودکار بزرگ می‌شوند ولی هرگز کوچک نمی‌شوند. برای مدیریت آن‌ها، باید در فایل my.cnf مقدار innodb_file_per_table را فعال کنید.

پرشدن inode، قاتل خاموش دیسک

inode یکی از مفاهیم پایه‌ی فایل‌سیستم‌های لینوکسی است که تعداد فایل‌های مجاز روی دیسک را مشخص می‌کند. توضیح تکمیلی این مفهوم در ویکی‌پدیا موجود است، ولی جان ماجرا در این نکته است: می‌تواند دیسک شما پر نباشد ولی هیچ فایل جدیدی نتوانید بسازید، چون تمام inodeها مصرف شده‌اند.

تشخیص پرشدن inode

df -i

اگر ستون IUse% بالای ۹۰ درصد باشد، مشکل شما پرشدن inode است نه فضای دیسک. این سناریو معمولاً در سرورهایی که تعداد زیادی فایل کوچک تولید می‌کنند (مثل کش یا سشن) رخ می‌دهد.

پیدا کردن پوشه‌های پرفایل

for i in /var/* /home/*; do echo "$i: $(find $i -type f 2>/dev/null | wc -l)"; done

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

راه‌حل پرشدن inode

پاک‌سازی فایل‌های کوچک و بی‌استفاده، تنظیم garbage collection سشن‌ها، و در موارد نادر، افزایش تعداد inodeها در فایل‌سیستم (که نیاز به فرمت مجدد دارد).

محدودیت دیسک در هاست اشتراکی

در هاست‌های اشتراکی، فضای دیسک معمولاً به دو شکل محدود می‌شود: فضای کلی و فضای مصرفی به‌ازای هر کاربر. اگر مصرف شما از سهمیه (quota) بیشتر شود، هاست معمولاً خطای Disk quota exceeded برمی‌گرداند. مباحث مرتبط با این محدودیت‌ها در کاهش مصرف منابع هاست و تأثیر هاست بر سرعت سایت باز شده است.

بررسی quota

در هاست‌های cPanel، با دستور quota -s می‌توانید مصرف فعلی و سقف را ببینید:

quota -s

پاک‌سازی سریع در هاست اشتراکی

اگر در هاست اشتراکی با مشکل quota مواجه شده‌اید، سه کار سریع انجام دهید: پاک‌سازی بکاپ‌های قدیمی، حذف رسانه‌های بی‌استفاده، و کاهش حجم کش. اگر این کارها کافی نبود، ارتقا به پلن بالاتر یا VPS را بررسی کنید. مباحث مرتبط در بهترین هاست وردپرس باز شده است.

پاک‌سازی ایمن و اولویت‌بندی

بعد از پیدا کردن مقصر، نوبت به پاک‌سازی ایمن می‌رسد. ترتیب اولویت‌بندی من در پروژه‌های واقعی:

  1. اولویت اول: لاگ‌های قدیمی. اگر فضای دیسک بحرانی است، لاگ‌های قدیمی سریع‌ترین راه آزادسازی هستند. با truncate آن‌ها را صفر کنید.
  2. اولویت دوم: بکاپ‌های منقضی. بکاپ‌های قدیمی که در سیاست نگه‌داری شما نیستند، باید پاک شوند.
  3. اولویت سوم: کش و ترنزینت. پاک‌سازی کش و ترنزینت‌های منقضی، فضای قابل توجهی آزاد می‌کند.
  4. اولویت چهارم: رسانه‌های بی‌استفاده. این دسته نیاز به بررسی دقیق‌تر دارد و باید با افزونه انجام شود.
  5. اولویت پنجم: بهینه‌سازی دیتابیس. در نهایت، پاک‌سازی جدول‌های بزرگ و binlog‌ها.

نکته‌ی میدانی: در بحران دیسک، هیچ‌گاه به‌طور همزمان چند پوشه را پاک نکنید. اول پاک‌سازی کوچک انجام دهید و دوباره df -h بگیرید. این ترتیب، از حذف اشتباهی جلوگیری می‌کند.

پایش مستمر و پیشگیری

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

سطح اول: پایش روزانه‌ی دیسک

یک اسکریپت ساده می‌تواند هر روز فضای دیسک را بررسی کند و اگر از یک آستانه (مثلاً ۸۰ درصد) بیشتر شد، هشدار بدهد:

#!/bin/bash
THRESHOLD=80
CURRENT=$(df / | grep / | awk '{ print $5}' | sed 's/%//g')
if [ $CURRENT -gt $THRESHOLD ]; then
    echo "Disk usage is ${CURRENT}% on $(hostname)" | mail -s "Disk Alert" admin@example.com
fi

این اسکریپت را می‌توانید در cron روزانه قرار دهید. توجه داشته باشید که از ایمیل معتبر برای ارسال هشدار استفاده کنید.

سطح دوم: پایش inode

پایش df -i به‌همراه پایش فضای دیسک، از پرشدن inode جلوگیری می‌کند. اگر IUse% از ۸۰ درصد بیشتر شد، باید اقدام کنید.

سطح سوم: پایش لاگ‌ها

پایش هفتگی لاگ‌های وب‌سرور و PHP-FPM، از انباشت پنهان جلوگیری می‌کند. اگر لاگی به‌طور غیرعادی بزرگ شده، ریشه را بررسی کنید. مباحث مرتبط در بررسی خطاهای سرور در لاگ‌ها باز شده است.

سطح چهارم: پایش خارجی دیسک

سرویس‌های پایش سرور مثل Netdata، Zabbix یا Prometheus می‌توانند مصرف دیسک را در طول زمان نمایش دهند و ترند رشد را نشان دهند. اگر ترند رشد سریع بود، قبل از بحران اقدام کنید.

سطح پنجم: بکاپ روی فضای بیرونی

قاعده‌ی اصلی این است که بکاپ‌ها نباید روی همان دیسکی باشند که سایت روی آن اجرا می‌شود. اگر دیسک پر شود، بکاپ‌ها هم آسیب می‌بینند. راه‌حل: انتقال بکاپ‌ها به Object Storage مثل S3 یا Google Cloud Storage. مباحث مرتبط در افزونه‌های بکاپ وردپرس باز شده است.

پرسش‌های پرتکرار درباره پرشدن هارد سرور

چرا دیسک سرور بدون هیچ تغییری به‌طور ناگهانی پر می‌شود؟

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

تفاوت پرشدن دیسک و پرشدن inode چیست؟

پرشدن دیسک یعنی حجم فضای فیزیکی تمام شده است. پرشدن inode یعنی تعداد فایل‌های مجاز تمام شده، در حالی که هنوز فضای دیسک خالی است. در حالت دوم، نمی‌توانید فایل جدید بسازید ولی فایل‌های موجود سالم هستند. تشخیص با df -h و df -i انجام می‌شود.

آیا می‌توانم فایل‌های لاگ را با rm حذف کنم؟

خیر، حداقل به‌طور مستقیم. اگر فایل لاگ در حال نوشتن باشد و آن را حذف کنید، سرویس همچنان به فایل حذف‌شده می‌نویسد و فضای دیسک آزاد نمی‌شود. راه صحیح، استفاده از truncate -s 0 است که حجم فایل را صفر می‌کند بدون حذف آن.

چرا بکاپ‌ها روی دیسک انباشته می‌شوند؟

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

آیا پرشدن دیسک روی سئو تأثیر می‌گذارد؟

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

چگونه حجم جدول‌های دیتابیس را کاهش دهم؟

سه کار مؤثر: اول، پاک‌سازی ترنزینت‌های منقضی‌شده. دوم، حذف رکوردهای revision قدیمی. سوم، بهینه‌سازی جدول‌های InnoDB با OPTIMIZE TABLE. قبل از هر تغییری، بکاپ کامل دیتابیس بگیرید.

آیا می‌توانم پوشه‌ی wp-content را به دیسک دیگری منتقل کنم؟

بله، در سرورهای VPS یا اختصاصی، می‌توانید با mount کردن یک دیسک اضافی در پوشه‌ی uploads یا wp-content، فضای دیسک را گسترش دهید. این کار نیاز به تنظیمات دقیق دارد و قبل از اجرا باید بکاپ کامل بگیرید.

چرا در هاست اشتراکی، دیسک زودتر پر می‌شود؟

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

آیا logrotate به‌طور خودکار نصب می‌شود؟

در بیشتر توزیع‌های لینوکسی، logrotate به‌طور پیش‌فرض نصب است، ولی تنظیمات پیش‌فرض آن برای همه‌ی سرویس‌ها کافی نیست. باید برای سرویس‌های اختصاصی مثل Nginx، MySQL و PHP-FPM تنظیمات مجزا تعریف کنید.

چطور بفهمم کدام افزونه باعث پرشدن دیسک شده؟

سه روش: اول، پوشه‌های داخل wp-content/ را با du بررسی کنید. دوم، پوشه‌های کش، لاگ و backup افزونه‌ها را جداگانه چک کنید. سوم، لاگ PHP را برای خطاهای مکرر بررسی کنید؛ افزونه‌ای که در حلقه‌ای خطا تولید می‌کند، به‌سرعت دیسک را پر می‌کند. مباحث مرتبط در کاهش مصرف منابع هاست باز شده است.

نکته‌های میدانی از مدیریت بحران دیسک

در پایان این مقاله، چند نکته‌ای را می‌گویم که در مستندات رسمی کم‌تر به آن‌ها اشاره می‌شود ولی در پروژه‌های واقعی بارها به کارم آمده:

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

دوم: هیچ‌گاه بکاپ‌ها را روی دیسک اصلی نگه ندارید. اگر دیسک پر شود، بکاپ‌های شما هم ناپدید می‌شوند و بحران دو برابر می‌شود. انتقال بکاپ به فضای بیرونی، یکی از قواعد ثابت در همه‌ی پروژه‌های من است. مباحث مرتبط در افزونه‌های بکاپ وردپرس باز شده است.

سوم: پرشدن inode را جدی بگیرید. این نوع پرشدن بسیار فریبنده است چون df -h فضای کافی نشان می‌دهد ولی سایت نمی‌تواند فایل جدید بسازد. همیشه پایش دیسک را با پایش inode همراه کنید. تجربه‌ی من نشان داده که در سرورهای با ترافیک بالا، این نوع پرشدن شایع‌تر از پرشدن فضای دیسک است.

در تجربه‌ی چندساله‌ام روی سرورهای تولیدی و پروژه‌های وردپرسی، الگویی که بارها تکرار شده این است که خطای پرشدن دیسک تقریباً همیشه در یکی از پنج لایه ریشه دارد: لاگ‌های سرویس، بکاپ‌های منقضی، کش و ترنزینت، رسانه‌های بی‌استفاده، و binlog دیتابیس. تشخیص سریع این لایه، از هر راه‌حل آماده مؤثرتر است. اگر ابزارهای تشخیصی را در اختیار داشته باشید و لایه‌ها را به ترتیب بررسی کنید، این خطا از یک بحران ترسناک به یک تمرین روتین تبدیل می‌شود.

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