سایت بالا نمیآید، یا صفحه سفید است، یا بعد از یک آپدیت ناقص همهچیز به هم ریخته. اولین کاری که اکثر مدیرها میکنند این است که کل بکاپ دیروز را روی سایت امروز میریزند. این کار در نیمی از موارد وضعیت را بدتر میکند. بازگردانی بکاپ یک عملیات جراحی است، نه یک کپیپیست بزرگ. قبل از هر دستوری باید بدانید دقیقاً چه چیزی خراب شده و چه چیزی سالم است.
اول تشخیص بده، بعد بازگردانی کن
قبل از اینکه به فایلهای بکاپ دست بزنید، سه چیز را چک کنید. اول، لاگ خطای PHP را ببینید؛ اگر خطا از یک افزونه یا یک فایل خاص میآید، نیازی به بازیابی کل سایت نیست. دوم، ببینید دیتابیس پاسخ میدهد یا نه. سوم، بررسی کنید مشکل از DNS یا سرور است یا از خود کد. اگر دامنه به IP اشتباه اشاره میکند، هیچ بکاپی مشکل را حل نمیکند. برای این مرحله میتوانید از بررسی DNS و شبکه استفاده کنید و مطمئن شوید مشکل از رزولوشن است، نه از محتوا.
یک تست ساده: یک فایل test.php با محتوای <?php echo "ok"; بسازید و در مرورگر باز کنید. اگر «ok» را دیدید، وبسرور و PHP سالماند و مشکل در اپلیکیشن است. اگر 500 گرفتید، مشکل سمت سرور یا کانفیگ است. اگر صفحه سفید بود، احتمالاً خطای PHP دارید که نمایش داده نمیشود.
بازیابی کامل در برابر بازیابی جزئی
بازیابی کامل یعنی برگرداندن همه فایلها و کل دیتابیس به یک نقطه زمانی. این کار فقط در سه حالت منطقی است: هک شدن سایت، خرابی دیتابیس، یا مهاجرت به سرور جدید. در بقیه موارد، بازیابی جزئی هم سریعتر است و هم ریسک کمتری دارد.
| وضعیت | چه چیزی را برگردانیم | زمان تقریبی |
|---|---|---|
| آپدیت افزونه سایت را سفید کرد | فقط پوشه همان افزونه | ۲ تا ۵ دقیقه |
| جدول دیتابیس خراب شد | فقط همان جدول | ۵ تا ۱۵ دقیقه |
| فایل wp-config.php پاک شد | فقط همان فایل | کمتر از ۲ دقیقه |
| سایت هک شد | همه فایلها و کل دیتابیس | ۳۰ دقیقه تا چند ساعت |
در جدول بالا دقت کنید که ستون زمان به حجم سایت بستگی دارد. یک سایت ۵۰۰ مگابایتی با دیتابیس ۲۰۰ مگابایتی روی یک هاست اشتراکی معمولی، بازیابی کاملش میتواند بیش از یک ساعت طول بکشد، چون هم آپلود و هم استخراج فایلها زمان میبرد.
بازگردانی دیتابیس: دستورها و نکتههای عملی
فرض کنید فایل بکاپ دیتابیس را دارید: backup.sql که با mysqldump گرفته شده. برای بازگرداندن آن از خط فرمان SSH:
mysql -u dbuser -p dbname < backup.sql
اگر فایل با gzip فشرده شده، اول بازش کنید یا مستقیم بدهید به mysql:
gunzip < backup.sql.gz | mysql -u dbuser -p dbname
یک نکته که خیلیها نمیدانند: اگر بکاپ را با mysqldump --single-transaction گرفته باشید، فایل خروجی شامل DROP TABLE IF EXISTS نیست مگر اینکه --add-drop-table را هم اضافه کرده باشید. یعنی وقتی فایل را روی دیتابیس فعلی میریزید، جدولهای موجود دستنخورده میمانند و فقط رکوردها اضافه میشوند. نتیجهاش این است که بعد از بازیابی، سایت شما دو نسخه از هر نوشته دارد. اگر میخواهید دیتابیس کاملاً جایگزین شود، اول آن را خالی کنید:
mysql -u dbuser -p -e "DROP DATABASE dbname; CREATE DATABASE dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
سپس فایل را وارد کنید. اینجا اشتباه میکنند: خیلیها بدون خالی کردن دیتابیس، بکاپ را روی آن میریزند و بعد از دیدن رکوردهای تکراری فکر میکنند بکاپ خراب است. در واقع بکاپ سالم بوده، دیتابیس مقصد آماده نبوده.
بازیابی فقط یک جدول
اگر فقط یک جدول خراب شده، لازم نیست کل دیتابیس را برگردانید. از فایل SQL میتوانید فقط بخش مربوط به آن جدول را استخراج کنید. با sed یا awk میشود این کار را کرد، ولی سادهتر این است که با یک ابزار مثل phpMyAdmin جدول را انتخاب و ایمپورت کنید. اگر فایل بکاپ بزرگ است (بیش از ۵۰ مگابایت)، phpMyAdmin معمولاً تایماوت میدهد. در آن حالت از خط فرمان استفاده کنید یا فایل را تکهتکه کنید.
بازگردانی فایلها: چه چیزی را نگه داریم
قبل از اینکه پوشه public_html را با بکاپ جایگزین کنید، اینها را جدا کنید:
wp-config.phpفعلی، چون ممکن است اطلاعات دیتابیس یا کلیدهای امنیتی تغییر کرده باشد.- پوشه
uploadsاگر فایلهای جدیدتری از زمان بکاپ دارید. - فایل
.htaccessاگر ریدایرکتها یا تنظیمات خاصی در آن هست. - پوشه
wp-content/pluginsاگر افزونهای بعد از تاریخ بکاپ نصب کردهاید.
بعد از جایگزینی، مجوز فایلها را درست کنید. مجوز اشتباه یکی از دلایل رایج خطای 403 بعد از بازیابی است:
find /home/user/public_html -type d -exec chmod 755 {} \;
find /home/user/public_html -type f -exec chmod 644 {} \;
اگر سایت روی هاست اشتراکی است، تعداد فایلها هم مهم است. بازیابی یک بکاپ قدیمی که هزاران فایل اضافه دارد، میتواند شما را به سقف inode نزدیک کند. قبل از بازیابی، تعداد فایلهای فعلی و بکاپ را بشمارید. راهنمای محدودیت inode در هاست توضیح میدهد چه چیزی این عدد را مصرف میکند و چطور آن را بشمارید.
قبل از بازیابی، این سه کار را انجام بده
- از وضعیت فعلی بکاپ بگیرید، حتی اگر خراب است. ممکن است بعداً به یک فایل خاص از آن نیاز پیدا کنید.
- سایت را در حالت تعمیر قرار دهید تا کاربران وسط بازیابی با خطا مواجه نشوند.
- مطمئن شوید فضای دیسک کافی دارید. باز کردن یک بکاپ ۲ گیگابایتی روی هاستی که ۱ گیگابایت فضای خالی دارد، وسط کار متوقف میشود.
نکته سوم را جدی بگیرید. خطای No space left on device وسط استخراج فایل، سایت را در وضعیت نیمهبازیابی رها میکند که بدترین حالت ممکن است. اگر فضای کافی ندارید، اول فایلهای غیرضروری مثل لاگها و کشها را پاک کنید.
انتخاب بین بازیابی از پنل و خط فرمان
اگر بکاپ کمتر از ۱۰۰ مگابایت است و دیتابیس کوچک است، از پنل هاست استفاده کنید. سریعتر است و ریسک اشتباه دستوری ندارد. اگر بکاپ بزرگتر است، یا باید فقط یک جدول را برگردانید، یا سایت روی سرور اختصاصی است، خط فرمان انتخاب بهتری است. در خط فرمان کنترل کامل دارید و میتوانید وسط کار متوقف شوید یا فقط بخشی را بازیابی کنید.
یک محدودیت عملی که کمتر گفته میشود: روی هاست اشتراکی، فرایند بازیابی خودش منابع مصرف میکند. اگر بازیابی طول بکشد، ممکن است به سقف Entry Process بخورید و فرایند وسط کار kill شود. این را در توضیح Entry Process میتوانید دقیق ببینید. در چنین حالتی، بازیابی را در ساعات کمترافیک انجام دهید یا سایت را موقتاً از دسترس خارج کنید.
اگر سایت شما روی هاست لینوکس است و بکاپ بزرگ دارید، بهتر است فایل را مستقیم با wget یا scp روی سرور بگذارید، نه از طریق مرورگر. آپلود از مرورگر برای فایلهای بالای ۱۰۰ مگابایت معمولاً قطع میشود.
بعد از بازیابی چه چیزی را چک کنیم
بازیابی که تمام شد، سایت را باز نکنید و بگویید «خب، درست شد». اینها را چک کنید:
- آیا صفحه اصلی، یک نوشته، و یک صفحه ثابت درست باز میشوند؟
- آیا فرم تماس کار میکند؟ (بعضی افزونهها تنظیماتشان در دیتابیس است و ممکن است قدیمی باشد.)
- آیا لینکهای داخلی به فایلهای موجود اشاره میکنند؟
- آیا SSL هنوز فعال است؟ اگر بکاپ قدیمی باشد، ممکن است ریدایرکت HTTPS در
.htaccessنباشد. - آیا کش پاک شده؟ کش قدیمی میتواند نسخه قبلی صفحات را نشان دهد و شما فکر کنید بازیابی نشده.
اگر از وردپرس استفاده میکنید، بعد از بازیابی دیتابیس، آدرس سایت را در جدول wp_options چک کنید. اگر بکاپ از دامنه دیگری گرفته شده، آدرسها اشتباه خواهند بود و سایت به دامنه قدیمی ریدایرکت میشود. این را با یک کوئری ساده میتوانید ببینید:
SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl','home');
اگر مقدار اشتباه بود، با UPDATE اصلاحش کنید. اینجا اشتباه میکنند: خیلیها فکر میکنند مشکل از DNS است و شروع میکنند به تغییر نیمسرور، در حالی که مشکل فقط یک رکورد در دیتابیس است. اگر مطمئن نیستید مشکل از DNS است یا از دیتابیس، اول DNS را چک کنید. راهنمای اتصال دامنه به هاست تفاوت نیمسرور و رکورد A را توضیح میدهد و کمک میکند این دو را از هم جدا کنید.
پرسشهای پرتکرار
آیا میتوانم فقط دیتابیس را بازیابی کنم و فایلها را دست نزنم؟
بله، و در بسیاری از موارد این کار درستتر است. اگر مشکل از محتوا یا تنظیمات دیتابیس است و فایلهای سایت سالماند، فقط دیتابیس را برگردانید. فقط یادتان باشد که اگر افزونهای را آپدیت کردهاید و ساختار جدولهایش تغییر کرده، بازیابی دیتابیس قدیمی میتواند ناسازگاری ایجاد کند.
چرا بعد از بازگردانی بکاپ، سایت همچنان خطا میدهد؟
سه دلیل رایج: کش مرورگر یا کش سرور پاک نشده، مجوز فایلها بعد از استخراج تغییر کرده، یا نسخه PHP با کد بازیابیشده سازگار نیست. اگر بکاپ از یک سرور با PHP 7.4 گرفته شده و سرور فعلی PHP 8.2 دارد، ممکن است کد قدیمی خطا بدهد. برای بررسی تنظیمات، مرجع تنظیمات php.ini را ببینید.
بکاپ را با چه دستوری بگیرم که بازیابیاش راحت باشد؟
برای دیتابیس MySQL، دستور mysqldump -u user -p --single-transaction --routines --triggers dbname > backup.sql گزینههای ضروری را پوشش میدهد. برای فایلها، tar -czf backup.tar.gz public_html کافی است. اگر میخواهید بکاپ قابل بازیابی جزئی باشد، بهجای یک فایل tar بزرگ، پوشهها را جدا نگه دارید.
بازیابی کامل چقدر طول میکشد؟
به حجم بکاپ، سرعت دیسک و نوع هاست بستگی دارد. روی یک هاست اشتراکی با دیسک معمولی، هر گیگابایت فایل حدود ۵ تا ۱۵ دقیقه زمان میبرد. روی سرور با NVMe این عدد به کمتر از ۲ دقیقه برای هر گیگابایت میرسد. اگر زمان مهم است، بازیابی را در ساعات کمترافیک انجام دهید و از قبل فضای دیسک را چک کنید.
قبل از هر بازیابی، یک بکاپ از وضعیت فعلی بگیرید. این تنها کاری است که اگر اشتباه کنید، نجاتتان میدهد.