بروزرسانی خودکار وردپرس (WordPress) یکی از مکانیزم‌های امنیتی و نگهداری کلیدی است که در نسخه‌های مدرن به‌طور پیش‌فرض فعال شده، اما در بسیاری از سایت‌های واقعی نیمه‌کاره می‌ماند و سایت را در وضعیتی نامعلوم رها می‌کند؛ نه کاملاً بروزرسانی‌شده، نه کاملاً قدیمی. این وضعیت خطرناک‌تر از آن است که تصور می‌شود، زیرا مدیر سایت تصور می‌کند بروزرسانی انجام شده، در حالی که فایل‌های نیمه‌کاره یا جداول دیتابیس ناهماهنگ، می‌توانند به خطاهای پنهان، شکست‌های امنیتی و رفتارهای غیرقابل پیش‌بینی منجر شوند. ریشه این مشکل در ترکیبی از محدودیت‌های سرور، تداخل با افزونه‌ها، مسائل مجوز فایل، timeout درخواست‌های HTTP و نبود پایش پس از بروزرسانی نهفته است. در این نوشتار، مکانیزم بروزرسانی خودکار وردپرس، دلایل نیمه‌کاره ماندن، روش‌های تشخیص وضعیت واقعی و راهکارهای عملی برای اطمینان از بروزرسانی کامل و قابل اتکا بررسی می‌شود.

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

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

بروزرسانی خودکار وردپرس یک مکانیزم داخلی است که از نسخه ۳.۷ (اکتبر ۲۰۱۳) معرفی شد و در نسخه ۵.۵ (مارس ۲۰۲۰) به‌صورت پیش‌فرض برای افزونه‌ها و قالب‌ها فعال شد. هدف این مکانیزم، رفع خودکار آسیب‌پذیری‌های امنیتی بدون نیاز به مداخله مدیر سایت است.

این مکانیزم از چند جزء اصلی تشکیل شده است:

  • WP-Cron: یک زمان‌بند داخلی که بر اساس بازدید کاربران فعال می‌شود.
  • API بروزرسانی: ارتباط با سرورهای وردپرس (api.wordpress.org) برای بررسی وجود نسخه جدید.
  • background-update.php: یک فایل داخلی که بروزرسانی را در پس‌زمینه انجام می‌دهد.
  • Core Upgrader: کلاس WP_Upgrader که فرآیند دانلود، استخراج و جایگزینی فایل‌ها را مدیریت می‌کند.
  • update-core.php: اسکریپت پیشخوان که بروزرسانی را راه‌اندازی می‌کند.

برای مطالعه بیشتر درباره WP-Cron، مقاله WP-Cron و زمان‌بندی خودکار در وردپرس را ببینید. همچنین برای درک ابزار خط فرمان وردپرس، مقاله WP-CLI و مدیریت وردپرس از خط فرمان مفید است.

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

چرخه اجرای یک بروزرسانی خودکار

چرخه اجرای بروزرسانی خودکار از چند مرحله تشکیل می‌شود:

  1. بررسی دوره‌ای: WP-Cron هر ۱۲ ساعت (پیش‌فرض) به سرورهای وردپرس متصل می‌شود.
  2. تشخیص نیاز: اگر نسخه جدیدی وجود داشته باشد، یک رویداد بروزرسانی ثبت می‌شود.
  3. دانلود بسته: فایل ZIP نسخه جدید از سرورهای وردپرس دانلود می‌شود.
  4. استخراج: فایل ZIP در پوشه موقت باز می‌شود.
  5. کپی: فایل‌های جدید روی فایل‌های قدیمی کپی می‌شوند.
  6. اجرای اسکریپت‌های بروزرسانی: توابعی مانند upgrade_xxx() اجرا می‌شوند.
  7. هماهنگ‌سازی دیتابیس: نسخه دیتابیس (db_version) به‌روزرسانی می‌شود.

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

انواع بروزرسانی خودکار در وردپرس

وردپرس از چند نوع بروزرسانی خودکار پشتیبانی می‌کند که هرکدام رفتار و تنظیمات خاص خود را دارند.

بروزرسانی‌های امنیتی هسته (Minor)

بروزرسانی‌های Minor (مانند ۶.۴.۱ به ۶.۴.۲) به‌طور پیش‌فرض خودکار هستند. این بروزرسانی‌ها معمولاً کوچک و امنیتی هستند و هدف آن‌ها رفع آسیب‌پذیری‌های سریع است.

// غیرفعال‌سازی بروزرسانی خودکار Minor
define('WP_AUTO_UPDATE_CORE', false);

// فعال‌سازی فقط برای Minor
define('WP_AUTO_UPDATE_CORE', 'minor');

// فعال‌سازی برای همه بروزرسانی‌ها
define('WP_AUTO_UPDATE_CORE', true);

این تنظیمات در فایل wp-config.php قرار می‌گیرند و رفتار پیش‌فرض وردپرس را تغییر می‌دهند.

بروزرسانی‌های اصلی هسته (Major)

بروزرسانی‌های Major (مانند ۶.۳ به ۶.۴) به‌طور پیش‌فرض خودکار نیستند، زیرا احتمال ناسازگاری با قالب‌ها و افزونه‌ها بالاست. اما می‌توان آن‌ها را از طریق فیلتر فعال کرد:

add_filter('allow_major_auto_core_updates', '__return_true');

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

بروزرسانی خودکار افزونه‌ها و قالب‌ها

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

// غیرفعال‌سازی سراسری
add_filter('auto_update_plugin', '__return_false');
add_filter('auto_update_theme', '__return_false');

// فعال‌سازی فقط برای افزونه‌های خاص
add_filter('auto_update_plugin', function($update, $item) {
    $auto_update_plugins = array('akismet', 'wordfence');
    if (in_array($item->slug, $auto_update_plugins, true)) {
        return true;
    }
    return $update;
}, 10, 2);

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

بروزرسانی خودکار ترجمه‌ها

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

چرا بروزرسانی خودکار نیمه‌کاره می‌ماند؟

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

محدودیت‌های سرور و timeout

شایع‌ترین دلیل، محدودیت‌های سرور است. هر سرور وب، محدودیت‌هایی برای اجرای اسکریپت‌های PHP دارد:

  • max_execution_time: حداکثر زمان اجرای یک اسکریپت (معمولاً ۳۰ ثانیه).
  • memory_limit: حداکثر حافظه قابل استفاده (معمولاً ۱۲۸ یا ۲۵۶ مگابایت).
  • post_max_size: حداکثر حجم داده ارسالی (معمولاً ۸ مگابایت).
  • upload_max_filesize: حداکثر حجم فایل آپلودی (معمولاً ۲ مگابایت).
  • max_input_time: حداکثر زمان پردازش ورودی (معمولاً ۶۰ ثانیه).

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

# بررسی محدودیت‌های فعلی PHP
php -i | grep -E "max_execution_time|memory_limit|post_max_size|upload_max_filesize"

برای افزایش این محدودیت‌ها، می‌توان از فایل .htaccess یا php.ini استفاده کرد:

# در .htaccess
php_value max_execution_time 300
php_value memory_limit 512M
php_value post_max_size 64M
php_value upload_max_filesize 64M

برای مطالعه بیشتر درباره این نوع خطاها، مقاله خطای Memory Limit در وردپرس چیست و چطور رفع می‌شود؟ را ببینید.

مسائل مجوز فایل و مالکیت

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

# مجوز توصیه‌شده برای پوشه‌ها
find /var/www/html -type d -exec chmod 755 {} ;

# مجوز توصیه‌شده برای فایل‌ها
find /var/www/html -type f -exec chmod 644 {} ;

# مالکیت
chown -R www-data:www-data /var/www/html

مشکل شایع دیگر، ترکیب مالکیت کاربر FTP و کاربر وب سرور است. اگر فایل‌ها به کاربر A تعلق داشته باشند اما PHP با کاربر B اجرا شود، نوشتن ممکن نیست. برای مطالعه بیشتر درباره این خطا، مقاله خطای دسترسی به فایل‌ها در وردپرس را ببینید.

خطای HTTP Loopback و مسدودسازی درخواست‌های داخلی

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

wp_remote_post(site_url('wp-cron.php'), array('timeout' => 0.01, 'blocking' => false));

اگر این درخواست مسدود شود، بروزرسانی آغاز نمی‌شود. دلایل مسدودسازی:

  • Basic Auth: اگر سایت با HTTP Basic Auth محافظت شده باشد.
  • فایروال: قوانینی که درخواست‌های localhost را مسدود می‌کنند.
  • DNS: اگر دامنه داخلی به IP خارجی resolve شود.
  • SSL verify: خطای تأیید SSL در سایت‌های self-signed.

راه‌حل، افزودن استثنا در فایروال یا غیرفعال کردن SSL verify برای درخواست‌های داخلی:

add_filter('https_local_ssl_verify', '__return_false');
add_filter('http_request_host_is_external', '__return_true');

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

تداخل با افزونه‌های امنیتی و کش

برخی افزونه‌ها با فرآیند بروزرسانی تداخل می‌کنند:

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

در برخی موارد، افزونه‌های امنیتی مانند Wordfence یا iThemes Security می‌توانند بروزرسانی خودکار را محدود کنند. برای مطالعه بیشتر درباره افزونه‌های امنیتی، مقاله بهترین افزونه‌های امنیتی وردپرس کدامند؟ را ببینید.

محدودیت حافظه PHP

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

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2097152 bytes)

این خطا در wp-content/debug.log ثبت می‌شود. راه‌حل، افزایش memory_limit در wp-config.php:

define('WP_MEMORY_LIMIT', '512M');
define('WP_MAX_MEMORY_LIMIT', '512M');

نوشتن ناقص فایل‌ها در دیسک

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

تشخیص این وضعیت با wp core verify-checksums امکان‌پذیر است:

wp core verify-checksums
wp plugin verify-checksums --all

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

ناهماهنگی دیتابیس پس از بروزرسانی

پس از بروزرسانی هسته، وردپرس باید جداول دیتابیس را هماهنگ کند. اگر این مرحله اجرا نشود، سایت ممکن است با خطاهای عجیب کار کند. تابع wp_upgrade() این کار را انجام می‌دهد:

require_once ABSPATH . 'wp-admin/includes/upgrade.php';
wp_upgrade();

برای بررسی نسخه دیتابیس:

SELECT option_value FROM wp_options WHERE option_name = 'db_version';

این مقدار باید با نسخه دیتابیس مورد انتظار وردپرس مطابقت داشته باشد. برای مطالعه بیشتر درباره بهینه‌سازی دیتابیس، مقاله Database Optimization و بهینه‌سازی دیتابیس وردپرس را ببینید.

نشانه‌های بروزرسانی نیمه‌کاره

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

شکست‌های پنهان در لاگ

وردپرس لاگ‌های بروزرسانی را در چند مکان ذخیره می‌کند:

  • wp-content/debug.log: اگر WP_DEBUG_LOG فعال باشد.
  • لاگ سرور (Apache یا Nginx): برای خطاهای HTTP.
  • لاگ PHP-FPM: برای خطاهای PHP.
  • گزینه auto_updater.lock در جدول wp_options: نشان می‌دهد که آیا بروزرسانی در حال اجراست.
SELECT * FROM wp_options WHERE option_name LIKE '%auto_updater%';

اگر گزینه auto_updater.lock وجود داشته باشد اما بروزرسانی مدتی است که اجرا نشده، ممکن است قفل معلق باقی مانده باشد. حذف آن می‌تواند بروزرسانی بعدی را آزاد کند.

ناهماهنگی نسخه‌ها

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

# نسخه اعلام‌شده در پیشخوان
wp core version

# نسخه واقعی در فایل wp-includes/version.php
grep wp_version wp-includes/version.php

# نسخه دیتابیس
wp db query "SELECT option_value FROM wp_options WHERE option_name = 'db_version'"

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

اعلان‌های متناقض در پیشخوان

وردپرس ممکن است اعلان‌های متناقضی نمایش دهد:

  • می‌گوید بروزرسانی موجود است، اما پس از کلیک، می‌گوید آخرین نسخه نصب است.
  • نشان می‌دهد بروزرسانی انجام شد، اما همچنان اعلان بروزرسانی نمایش داده می‌شود.
  • در صفحه update-core.php، نسخه‌ها ناهماهنگ هستند.

این اعلان‌ها نشانه کش کهنه یا بروزرسانی ناقص هستند.

رگرسیون‌های عملکردی

پس از بروزرسانی نیمه‌کاره، ممکن است رفتارهای غیرمنتظره ظاهر شوند:

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

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

روش‌های تشخیص وضعیت واقعی بروزرسانی

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

استفاده از WP-CLI برای بررسی نسخه‌ها

WP-CLI بهترین ابزار برای بررسی وضعیت بروزرسانی است:

# بررسی نسخه هسته
wp core version
wp core check-update

# بررسی وضعیت افزونه‌ها
wp plugin list --fields=name,status,version,update,auto_update

# بررسی وضعیت قالب‌ها
wp theme list --fields=name,status,version,update,auto_update

# بررسی وضعیت ترجمه‌ها
wp language core list --status=installed
wp language plugin list --all

خروجی این دستورات تصویر دقیقی از وضعیت واقعی ارائه می‌دهد.

بررسی checksum فایل‌های هسته و افزونه‌ها

این روش، موثرترین راه برای تشخیص فایل‌های ناقص است:

wp core verify-checksums
wp plugin verify-checksums --all
wp theme verify-checksums --all

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

بررسی نسخه دیتابیس

نسخه دیتابیس باید با نسخه هسته هماهنگ باشد:

wp db query "SELECT option_value FROM wp_options WHERE option_name = 'db_version'"

اگر نسخه دیتابیس کمتر از نسخه مورد انتظار باشد، باید wp core update-db اجرا شود:

wp core update-db

این دستور، توابع بروزرسانی دیتابیس را اجرا می‌کند و نسخه را هماهنگ می‌کند.

تحلیل debug.log و لاگ سرور

لاگ‌ها اغلب حاوی اطلاعات ارزشمندی هستند:

# بررسی خطاهای اخیر
tail -100 wp-content/debug.log | grep -i "update|upgrade"

# بررسی خطاهای Fatal
grep "Fatal error" wp-content/debug.log

# بررسی لاگ سرور
tail -1000 /var/log/nginx/error.log | grep -i "wp-admin/update"

الگوهای تکراری مانند timeout یا permission denied، ریشه مشکل را آشکار می‌کنند.

Query Monitor و بررسی هوک‌ها

افزونه Query Monitor می‌تواند نشان دهد که کدام هوک‌ها در فرآیند بروزرسانی اجرا شده‌اند و کدام شکست خورده‌اند. این ابزار به‌ویژه برای شناسایی تداخل افزونه‌ها مفید است.

راهکارهای رفع بروزرسانی نیمه‌کاره

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

بروزرسانی دستی به‌عنوان راهکار اضطراری

اگر بروزرسانی خودکار به‌طور مکرر شکست می‌خورد، بروزرسانی دستی امن‌ترین راهکار است:

  1. دانلود بسته وردپرس از wordpress.org/download/
  2. استخراج فایل ZIP
  3. حذف پوشه‌های wp-includes و wp-admin از سرور (نه wp-content)
  4. آپلود پوشه‌های جدید
  5. آپلود فایل‌های ریشه (به‌جز wp-config.php)
  6. اجرای wp-admin/upgrade.php از طریق مرورگر

این روش، اگرچه دستی است، اما کنترل کامل را فراهم می‌کند و احتمال شکست را کاهش می‌دهد.

بروزرسانی امن با WP-CLI

WP-CLI روش سریع‌تر و قابل اعتمادتری برای بروزرسانی است:

# خروجی دیتابیس
wp db export backup-$(date +%Y%m%d).sql

# بروزرسانی هسته
wp core update --minor
wp core update-db

# بروزرسانی افزونه‌ها
wp plugin update --all --minor

# پاک‌سازی کش
wp cache flush
wp rewrite flush

استفاده از --minor تضمین می‌کند که فقط بروزرسانی‌های امنیتی اعمال شوند، نه تغییرات Major که ممکن است ناسازگاری ایجاد کنند.

افزایش محدودیت‌های سرور

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

# در wp-config.php
define('WP_MEMORY_LIMIT', '512M');
define('WP_MAX_MEMORY_LIMIT', '512M');
define('AUTOSAVE_INTERVAL', 300);
define('WP_POST_REVISIONS', 5);

# در .htaccess
php_value max_execution_time 300
php_value memory_limit 512M
php_value post_max_size 64M
php_value upload_max_filesize 64M

در سرورهایی که از PHP-FPM استفاده می‌کنند، این تنظیمات در php.ini یا pool configuration انجام می‌شود.

اصلاح مجوز و مالکیت فایل‌ها

مجوزها باید به‌طور سیستماتیک اصلاح شوند:

# مالکیت صحیح
chown -R www-data:www-data /var/www/html

# مجوز پوشه‌ها
find /var/www/html -type d -exec chmod 755 {} ;

# مجوز فایل‌ها
find /var/www/html -type f -exec chmod 644 {} ;

# مجوز فایل wp-config.php
chmod 600 /var/www/html/wp-config.php

این تنظیمات، استاندارد امن و قابل نوشتن برای وردپرس هستند. برای مطالعه بیشتر درباره امنیت، مقاله چگونه امنیت وردپرس را تقویت کنیم؟ را ببینید.

غیرفعال‌سازی موقت افزونه‌های مداخله‌گر

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

# غیرفعال‌سازی همه افزونه‌ها
wp plugin deactivate --all

# بروزرسانی هسته
wp core update

# فعال‌سازی مجدد
wp plugin activate --all

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

تعمیر و هماهنگ‌سازی دیتابیس

اگر دیتابیس ناهماهنگ است، باید تعمیر شود:

# بررسی و تعمیر جداول
wp db check
wp db repair

# بهینه‌سازی
wp db optimize

# هماهنگ‌سازی نسخه
wp core update-db

این دستورات، دیتابیس را در وضعیت پایدار قرار می‌دهند.

استراتژی پیشگیری از بروزرسانی نیمه‌کاره

پیشگیری همیشه آسان‌تر از درمان است. چند اصل کلیدی برای جلوگیری از این مشکل:

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

برای مطالعه بیشتر درباره پشتیبان‌گیری، مقاله چرا بکاپ وردپرس بدون استراتژی بی‌فایده است؟ را ببینید.

پایش و هشداردهی خودکار

پایش خودکار، امکان شناسایی سریع بروزرسانی‌های نیمه‌کاره را فراهم می‌کند:

#!/bin/bash
# /usr/local/bin/wp-update-monitor.sh
SITE_PATH="/var/www/html"
cd $SITE_PATH

# بررسی نسخه هسته
CORE_VERSION=$(wp core version)
DB_VERSION=$(wp db query "SELECT option_value FROM wp_options WHERE option_name = 'db_version'" --skip-column-names)

# بررسی افزونه‌های قدیمی
OLD_PLUGINS=$(wp plugin list --update=available --format=count)

if [ "$OLD_PLUGINS" -gt 0 ]; then
    curl -X POST https://hooks.slack.com/... 
         -d "{"text": "Warning: $OLD_PLUGINS plugins need update on $HOSTNAME"}"
fi

# بررسی lock بروزرسانی
LOCK=$(wp option get auto_updater.lock --format=json 2>/dev/null)
if [ -n "$LOCK" ]; then
    LOCK_AGE=$(($(date +%s) - $(echo $LOCK | jq -r '.timestamp')))
    if [ "$LOCK_AGE" -gt 3600 ]; then
        curl -X POST https://hooks.slack.com/... 
             -d "{"text": "Warning: Stale auto-update lock on $HOSTNAME"}"
    fi
fi

این اسکریپت را می‌توان در Crontab قرار داد تا هر ساعت اجرا شود.

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

در این بخش، به پرسش‌های متداول پاسخ داده می‌شود. این ساختار برای بهینه‌سازی محتوا برای موتورهای پاسخگو (Answer Engines) نیز مفید است.

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

یک مکانیزم داخلی که از نسخه ۳.۷ برای هسته و از ۵.۵ برای افزونه‌ها و قالب‌ها فعال شده است. برای فعال‌سازی هسته، از define('WP_AUTO_UPDATE_CORE', true); و برای افزونه‌ها از فیلتر auto_update_plugin استفاده می‌شود.

چرا بروزرسانی خودکار وردپرس نیمه‌کاره می‌ماند؟

دلایل متعدد: محدودیت‌های سرور (timeout، memory limit)، مسائل مجوز فایل، خطای HTTP Loopback، تداخل افزونه‌ها، و ناهماهنگی دیتابیس. هر یک از این عوامل می‌تواند زنجیره بروزرسانی را در نیمه راه متوقف کند.

چگونه بفهمم بروزرسانی خودکار نیمه‌کاره مانده است؟

با wp core verify-checksums و wp plugin verify-checksums --all. اگر checksum فایلی مطابقت نداشته باشد، آن فایل ناقص است. همچنین بررسی نسخه دیتابیس با db_version و مقایسه با نسخه هسته مفید است.

آیا غیرفعال کردن بروزرسانی خودکار امن است؟

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

چگونه بروزرسانی خودکار را در محیط استیجینگ غیرفعال کنم؟

با افزودن کد زیر به wp-config.php در محیط استیجینگ:

define('AUTOMATIC_UPDATER_DISABLED', true);
define('WP_AUTO_UPDATE_CORE', false);
add_filter('auto_update_plugin', '__return_false');
add_filter('auto_update_theme', '__return_false');

آیا می‌توانم بروزرسانی خودکار را برای افزونه‌های خاص غیرفعال کنم؟

بله، با فیلتر auto_update_plugin:

add_filter('auto_update_plugin', function($update, $item) {
    $excluded = array('woocommerce', 'elementor');
    if (in_array($item->slug, $excluded, true)) {
        return false;
    }
    return $update;
}, 10, 2);

اگر بروزرسانی خودکار شکست خورد، چه اقدامی کنم؟

ابتدا لاگ‌ها را بررسی کنید. سپس با wp core verify-checksums وضعیت را تشخیص دهید. در صورت نیاز، بروزرسانی دستی با WP-CLI یا دانلود بسته رسمی انجام دهید. پیش از هر تغییر، پشتیبان بگیرید.

آیا بروزرسانی خودکار می‌تواند به ناسازگاری قالب منجر شود؟

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

آیا افزونه‌های امنیتی بروزرسانی خودکار را مسدود می‌کنند؟

برخی افزونه‌ها مانند Wordfence یا iThemes Security می‌توانند بروزرسانی خودکار را محدود کنند. توصیه می‌شود افزونه‌های ضروری را در لیست استثنا قرار دهید.

چگونه از بروزرسانی خودکار مطلع شوم؟

وردپرس برای هر بروزرسانی خودکار، ایمیلی به مدیر ارسال می‌کند. می‌توان این ایمیل‌ها را در بخش Settings > General فعال یا غیرفعال کرد. همچنین می‌توان از ابزارهای پایش خارجی استفاده کرد.

آیا بروزرسانی خودکار در سایت‌های پربازدید مشکلی ایجاد می‌کند؟

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

تفاوت بروزرسانی خودکار هسته و افزونه چیست؟

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

نکات پیشرفته برای مهندسان ارشد

برای مهندسان ارشد و تیم‌های DevOps، بروزرسانی خودکار یک مسئله چندلایه است. در این بخش، به نکات پیشرفته‌ای می‌پردازیم که در پروژه‌های بزرگ حیاتی می‌شوند.

تحلیل عمیق WP_Upgrader

کلاس WP_Upgrader قلب فرآیند بروزرسانی است. این کلاس چند متد کلیدی دارد:

  • run(): اجرای فرآیند با آرایه‌ای از گزینه‌ها.
  • download_package(): دانلود بسته از URL.
  • unpack_package(): استخراج بسته در پوشه موقت.
  • install_package(): کپی فایل‌ها به مقصد.
  • fs_connect(): بررسی دسترسی فایل‌سیستم.

درک این متدها، امکان اشکال‌زدایی دقیق را فراهم می‌کند. برای مثال، اگر fs_connect() شکست بخورد، مشکل در مجوز یا مالکیت است.

add_filter('upgrader_pre_install', function($response, $hook_extra) {
    error_log('Upgrader hook_extra: ' . print_r($hook_extra, true));
    return $response;
}, 10, 2);

این کد، اطلاعات دقیقی درباره فرآیند بروزرسانی در لاگ ثبت می‌کند.

Background Updates و مشکل Lock

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

// بررسی و حذف lock معلق
$lock = get_option('auto_updater.lock');
if ($lock && (time() - $lock['timestamp']) > 3600) {
    delete_option('auto_updater.lock');
    error_log('Stale auto-updater lock removed');
}

این کد می‌تواند در یک MU-Plugin قرار گیرد و به‌طور خودکار locks معلق را حذف کند.

Backward Compatibility و fallback

در پروژه‌های حرفه‌ای، باید برای شکست بروزرسانی برنامه‌ریزی کرد:

add_action('upgrader_process_complete', function($upgrader, $options) {
    if ($options['action'] === 'update' && $options['type'] === 'core') {
        // پاک‌سازی کش پس از بروزرسانی
        wp_cache_flush();
        opcache_reset();
        error_log('Core update completed successfully');
    }
}, 10, 2);

add_action('upgrader_overwrote_package', function($package, $type) {
    error_log(sprintf('Package %s overwritten for type %s', $package, $type));
}, 10, 2);

این هوک‌ها امکان پایش دقیق فرآیند بروزرسانی را فراهم می‌کنند.

پایش با Munin یا Prometheus

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

# metrics.sh - اسکریپت export معیار برای Prometheus
CORE_UPDATE=$(cd /var/www/html && wp core check-update --format=count)
PLUGIN_UPDATES=$(cd /var/www/html && wp plugin list --update=available --format=count)

echo "wordpress_core_update_available $CORE_UPDATE"
echo "wordpress_plugin_updates_available $PLUGIN_UPDATES"

این معیارها در داشبورد Grafana قابل نمایش هستند و امکان هشداردهی خودکار را فراهم می‌کنند.

Composer و مدیریت وابستگی

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

#!/bin/bash
# /usr/local/bin/composer-update.sh
cd /var/www/html

# بررسی آسیب‌پذیری‌ها
composer audit

# بروزرسانی وابستگی‌ها
composer update --with-dependencies

# پاک‌سازی کش
wp cache flush

# ثبت در لاگ
echo "$(date): Update completed" >> /var/log/composer-update.log

برای مطالعه بیشتر درباره Composer، مقاله Composer برای مدیریت وابستگی وردپرس را ببینید.

CI/CD برای بروزرسانی

در معماری CI/CD، بروزرسانی باید بخشی از pipeline باشد:

# .github/workflows/update.yml
name: WordPress Update
on:
  schedule:
    - cron: '0 3 * * 0'  # هر یکشنبه ساعت 3 بامداد

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Update WordPress
        run: |
          composer update --with-dependencies
          wp core update-db
      - name: Run Tests
        run: composer test

این رویکرد، بروزرسانی را قابل پیش‌بینی و قابل آزمون می‌کند. برای مطالعه بیشتر درباره CI/CD، مقاله CI/CD برای پروژه‌های وردپرسی را ببینید.

Atomic Updates و Rollback

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

  • Symlink-based Deployment: استفاده از symlink برای جابه‌جایی بین نسخه‌ها.
  • Container-based: استفاده از Docker image جدید برای هر بروزرسانی.
  • Blue-Green Deployment: اجرای دو محیط موازی و سوئیچ بین آن‌ها.
# نمونه deploy با symlink
RELEASE_DIR="/var/www/releases/$(date +%Y%m%d%H%M%S)"
mkdir -p $RELEASE_DIR
cp -r /var/www/current/* $RELEASE_DIR/
ln -sfn $RELEASE_DIR /var/www/html

این رویکرد، امکان rollback سریع را در صورت شکست فراهم می‌کند.

نکات کلیدی برای پایداری بلندمدت

در پایان، چند نکته کلیدی که باید در خاطر بماند:

  • پایش مستمر: وضعیت بروزرسانی به‌طور دوره‌ای بررسی شود.
  • پشتیبان خودکار: پیش از هر بروزرسانی، پشتیبان تهیه شود.
  • محیط استیجینگ: بروزرسانی ابتدا در استیجینگ تست شود.
  • افزایش محدودیت‌ها: timeout و memory limit در سطح مناسب تنظیم شوند.
  • مجوز صحیح: مجوزها و مالکیت فایل‌ها استاندارد باشند.
  • WP-CLI: به‌جای پیشخوان، از خط فرمان برای بروزرسانی استفاده شود.
  • حذف lock معلق: به‌طور خودکار locks قدیمی حذف شوند.
  • پاک‌سازی کش: پس از هر بروزرسانی، کش‌ها پاک شوند.
  • مستندسازی: هر بروزرسانی، موفق یا ناموفق، ثبت شود.
  • آموزش تیم: همه اعضا با فرآیند و بازیابی آشنا باشند.

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