بکاپ سرور مجازی؛ چه چیزی، هر چند وقت و کجا
ساعت ۲ بامداد یک دستور اشتباه میزنید. یک rm -rf در مسیر عوضی، یک دیپلوی که دیتابیس را خالی میکند، یا سروری که دیگر بوت نمیشود. حالا دنبال بکاپ میگردید. اینجاست که خیلیها میفهمند چیزی که فکر میکردند بکاپ است، بکاپ نبوده.
این نوشته سه چیز را روشن میکند: از سرور مجازی چه چیزی بگیرید، هر چند وقت، و کجا نگه دارید. با دستور و مثال.
اسنپشات با بکاپ فرق دارد
اسنپشات عکسی لحظهای از وضعیت سرور است. سریع ساخته میشود و سریع هم برمیگرداندتان به همان لحظه. برای قبل از یک ارتقای پرریسک عالی است؛ اسنپشات بگیرید، MySQL را به MariaDB مهاجرت دهید، خراب شد یک کلیک برگردید عقب.
ولی اسنپشات معمولاً روی همان زیرساخت ذخیرهسازی سرور شما مینشیند و به دیسک اصلی وابسته است. اگر آن دیسک یا آن هاست از بین برود، اسنپشات هم با آن میرود. اسنپشاتها هم معمولاً کوتاهمدتاند و با حذف سرور پاک میشوند. طبق دانشنامهٔ TransIP، بکاپها روی سیستمی جدا و در محلی دیگر نگهداری میشوند، در حالی که اسنپشات نمیتواند خارج از خود سرور باشد.
جمعبندی ساده: اسنپشات برای «برگرداندن یک تغییر تازه» است، بکاپ برای «نجات از فاجعه». یکی جای دیگری را نمیگیرد.
چرا بکاپ روی همان سرور بکاپ نیست
یک فایل tar در /root/backups بکاپ نیست. همان دیسک، همان هاست، همان حساب کاربری. هر چیزی که سرور را بکشد، آن فایل را هم میکشد. آتشسوزی دیتاسنتر، خرابی دیسک، رمزگذاری باجافزار روی کل فایلسیستم، یا لو رفتن دسترسی پنل شما و پاک شدن همهچیز. بکاپ باید از مرگ چیزی که از آن بکاپ گرفته جان سالم به در ببرد.
این تنها معیار واقعی است. اگر یک حادثه بتواند هم نسخهٔ اصلی و هم نسخهٔ پشتیبان را با هم نابود کند، شما یک نسخه دارید، نه دو تا.
قاعدهٔ ۳-۲-۱
این قاعده سالهاست پایهٔ کار است و هنوز درستترین نقطهٔ شروع است:
- ۳ نسخه از داده: نسخهٔ اصلی بهاضافهٔ دو بکاپ.
- ۲ نوع رسانه یا مقصد متفاوت، تا یک خرابی هر دو را با هم نبرد.
- ۱ نسخه خارج از محل (offsite)، دور از دسترس یک فاجعهٔ محلی.
یک تلهٔ رایج ۲۰۲۵ را جدی بگیرید. سرویسهای همگامسازی ابری مثل یک فولدر Sync، شرط «نسخهٔ خارج از محل» را برآورده نمیکنند. چون همگامسازی دائمی است، اگر باجافزار دادهٔ اصلی را رمز کند، همان لحظه نسخهٔ ابری هم رمز میشود. Backblaze همین را میگوید: sync بکاپ نیست. یک باکت با نسخهبندی (versioning) یا حالت immutable که نشود فایل قدیمی را بازنویسی یا حذف کرد، همین حفره را میبندد.
چه چیزی را بکاپ بگیریم
کل تصویر دیسک راحت است ولی سنگین و کند. برای بیشتر سرورها ترکیب «فایلهای حیاتی + دیتابیس» بهتر جواب میدهد. این حداقلی است که نباید جا بیفتد:
| موردمسیر نمونهچرا | ||
| پیکربندی سیستم | /etc | کاربرها، nginx، ssh، cron، فایروال |
| فایلهای اپلیکیشن | /var/www، /srv | کد و آپلودهای کاربر |
| دادهٔ خانگی | /home | کلیدها، اسکریپتها، تنظیمات |
| دیتابیس | خروجی dump | کپی خام فایل دیتابیس روشن معمولاً خراب درمیآید |
| گواهی TLS و رازها | /etc/letsencrypt | بازسازی دستیشان وقت میبرد |
دیتابیس نکتهٔ ظریف دارد. کپیکردن فایلهای خام دیتابیسِ در حال اجرا اغلب یک نسخهٔ ناسازگار میدهد که موقع بازیابی خطا میدهد. برای MySQL/MariaDB با جدولهای InnoDB از dump سازگار استفاده کنید:
سوئیچ --single-transaction بدون قفلکردن جدولها یک نسخهٔ سازگار میگیرد. اما اگر جدول MyISAM قابلنوشتن دارید این سوئیچ کافی نیست و باید قفل بگیرید. راهنمای Percona تأکید میکند routines و events بهطور پیشفرض در خروجی نیستند و باید صریح اضافه شوند؛ و برای بازیابی نقطهبهنقطه باید binlogها را هم کنار dump نگه دارید. برای PostgreSQL معادلش pg_dump یا pg_dumpall است.
هر چند وقت: با RPO و RTO تصمیم بگیرید
عدد ثابتی برای همه وجود ندارد. دو پرسش جواب را میسازد:
- RPO (هدف نقطهٔ بازیابی): چقدر داده میتوانید از دست بدهید؟ اگر RPO شما یک ساعت است، یعنی حاضرید حداکثر یک ساعت داده را ببازید، پس باید دستکم ساعتی یکبار بکاپ بگیرید.
- RTO (هدف زمان بازیابی): چقدر میتوانید offline بمانید؟ این تعیین میکند بازیابی باید چقدر سریع باشد.
Veeam مثال روشنی میدهد: سیستمی میتواند RTO چهارساعته و RPO پانزدهدقیقهای داشته باشد؛ یعنی هر پانزده دقیقه بکاپ میگیرید و ظرف چهار ساعت برمیگردید بالا. یک وبلاگ ساکن با بکاپ روزانه مشکلی ندارد. یک دیتابیس سفارشها فرق میکند؛ آنجا بکاپ مکرر بهعلاوهٔ binlog منطقی است. عددتان را از روی ارزش داده انتخاب کنید، نه از روی عادت.
کجا نگه داریم
نسخهٔ خارج از محل باید جای دیگری باشد که با سرور شما نمیمیرد: یک object storage سازگار با S3، یک ارائهدهندهٔ دیگر، یا دستکم یک ریجن دیگر. سه شرط را رعایت کنید:
- پیش از آپلود رمزگذاری کنید تا دادهٔ حساس روی مقصد لو نرود.
- نسخهبندی یا حالت immutable را روشن کنید تا باجافزار نتواند بکاپها را بازنویسی کند.
- دسترسی کلید بکاپ را از سرور اصلی جدا نگه دارید.
عملی: با restic بکاپ رمزگذاریشده و خارج از محل
restic ابزار متنبازی است که هم رمزگذاری، هم deduplication و هم مقصد راه دور را با هم دارد. مسیر معمول این است:
سیاست forget بالا هفت نسخهٔ روزانه، چهار هفتگی و شش ماهانه را نگه میدارد و بقیه را حذف میکند. رمز مخزن را جایی جدا از سرور ذخیره کنید؛ بدون آن، بازیابی ممکن نیست.
بکاپی که تست نشده، بکاپ نیست
این مهمترین بخش نوشته است و همان بخشی است که همه رد میکنند. یک بکاپ که هیچوقت بازیابیاش را امتحان نکردهاید، بکاپ نیست؛ یک امید است. فایل ممکن است خراب باشد، رمز اشتباه باشد، یا dump ناقص باشد و شما فقط شب حادثه بفهمید.
یک تست ماهانه در تقویم بگذارید. سه قدم دارد:
- یکپارچگی مخزن را بسنجید. در restic دستور
restic check --read-dataعلاوه بر متادیتا، خودِ دادهها را هم میخواند و هش را وارسی میکند تا خرابی را پیش از روز مبادا بگیرد. - واقعاً بازیابی کنید. نسخه را در یک مسیر موقت برگردانید و فایلها را باز کنید:
restic -r <repo> restore latest --target /tmp/restore-test. میتوانید اول با--dry-run --verbose=2ببینید چه چیزی برمیگردد. - دیتابیس را واقعاً import کنید. dump را روی یک دیتابیس تازه بارگذاری کنید و چند کوئری بزنید. اگر بازیابی کامل تصویر دارید، سرور بازیابیشده را حداقل یکبار بوت کنید.
اگر میخواهید سرور را از پایه امنتر هم بچینید، راهنمای سختسازی سرور اوبونتو در ۳۰ دقیقه نقطهٔ خوبی برای شروع است، و برای انتخاب اندازهٔ درست دیسک و رم راهنمای سایزینگ سرور مجازی کمک میکند فضای بکاپتان را هم درست پیشبینی کنید.
یک قانون تصمیم برای شروع فردا
اگر فقط یک کار میخواهید امروز انجام دهید: یک بکاپ رمزگذاریشدهٔ روزانه روی یک مقصد خارج از محل بگذارید و ماه دیگر یکبار بازیابیاش را تست کنید. بقیهٔ چیزها، RPO دقیقتر و نسخهبندی و immutable، بعد از این پایه معنا پیدا میکنند. سروری که بکاپ تستشده دارد، ساعت ۲ بامداد سرور دیگری است.
منابع
- Restoring from backup — restic documentation (unknown)
- MySQL Backup and Recovery Best Practices (Percona, vendor) (unknown)
- RTO vs RPO: What They Mean and How To Set Targets (Veeam, vendor) (unknown)
- The 3-2-1 Backup Strategy (Backblaze, vendor) (unknown)
- Difference and similarities between a snapshot and a backup (TransIP) (unknown)
پرسشهای پرتکرار
اسنپشات جای بکاپ را میگیرد؟
نه. اسنپشات معمولاً روی همان زیرساخت سرور مینشیند و با از بین رفتن دیسک یا حساب کاربری از بین میرود. برای برگرداندن یک تغییر تازه خوب است، اما برای محافظت در برابر فاجعه باید بکاپ مستقل و خارج از محل داشته باشید.
چرا فایل بکاپ روی همان سرور کافی نیست؟
چون همان حادثهای که سرور را نابود میکند، آن فایل را هم نابود میکند: خرابی دیسک، آتشسوزی، باجافزار، یا لو رفتن پنل. بکاپ باید جایی باشد که با مرگ سرور اصلی نمیرد.
هر چند وقت یکبار باید بکاپ بگیرم؟
به RPO شما بستگی دارد، یعنی چقدر داده میتوانید از دست بدهید. یک وبلاگ ساکن با بکاپ روزانه مشکلی ندارد، اما یک دیتابیس تراکنشی به بکاپ مکرر و نگهداری binlog برای بازیابی نقطهبهنقطه نیاز دارد.
چطور از دیتابیس MySQL بکاپ سازگار بگیرم؟
برای جدولهای InnoDB از mysqldump با سوئیچ --single-transaction استفاده کنید تا بدون قفل، نسخهٔ سازگار بگیرید. سوئیچهای --routines و --events را هم اضافه کنید و برای بازیابی نقطهبهنقطه binlogها را کنار dump نگه دارید.
چطور مطمئن شوم بکاپم واقعاً کار میکند؟
بازیابی را تست کنید. ماهی یکبار یکپارچگی مخزن را بسنجید (مثلاً restic check --read-data)، نسخه را در یک مسیر موقت برگردانید و فایلها را باز کنید، و dump دیتابیس را روی یک دیتابیس تازه import کنید.