BitVPS
مهاجرت سرور به VPS جدید بدون قطعی: گذار، DNS و برنامهٔ بازگشت
راهنمای مهاجرت

مهاجرت سرور به VPS جدید بدون قطعی: گذار، DNS و برنامهٔ بازگشت

تقریباً هر برنامهٔ مهاجرتی زمانش را صرف چیز اشتباهی می‌کند. کپی‌کردنِ داده همان بخشی است که مردم تمرین می‌کنند، و همان بخشی است که به‌ندرت شکست می‌خورد. قطعی از جای دیگری می‌آید: یک resolver که یک روز بعد از تغییرِ رکورد هنوز آدرسِ قدیمی را می‌دهد، پایگاه‌داده‌ای که بعد از گرفتنِ dump بی‌سروصدا بیست دقیقه نوشتن پذیرفته، گواهی‌ای که فقط روی دیسکی وجود داشته که در حالِ نابودکردنش هستید، دروازهٔ پرداختی که یک IP را allowlist کرده که هیچ‌کس یادداشتش نکرده. هیچ‌کدام از این‌ها مسئلهٔ سختی نیستند. همه‌شان مسئلهٔ زمان‌بندی‌اند، و همه‌شان با انجام‌دادنِ کارها به ترتیبی حل می‌شوند که جایی برای عقب‌نشینی برایتان باقی بگذارد. این راهنما همان ترتیب است — تمرین روی ماشینِ جدید درحالی‌که قدیمی هنوز سرویس می‌دهد، گذار بر اساسِ یک runbook مکتوب، و نگه‌داشتنِ یک بازگشت که تاریخ انقضا دارد، نه یک امید.

بدون KYC، هرگز DMCA نادیده گرفته می‌شود بدون لاگ ترافیک در 60 ثانیه فعال

کپی‌کردن بخشِ آسان است — چیزی که واقعاً باعثِ قطعی می‌شود

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

چهار حالتِ شکست مسئولِ بیشترِ قطعی‌های واقعیِ مهاجرت‌اند، و هیچ‌کدامشان پهنای‌باند نیست. یک رکوردِ DNS که time-to-live اش هنگامِ تغییردادن هنوز یک روز بوده، پس بخشِ قابل‌توجهی از دنیا همچنان به ماشینی وصل می‌شود که از قبل خاموشش کرده‌اید. پایگاه‌داده‌ای که بعد از گرفتنِ dump از آن نوشتن پذیرفته، پس میزبانِ جدید زندگی‌اش را با یک نسخهٔ بی‌سروصدا کهنه شروع می‌کند و شما فقط از شکایتِ یک مشتری می‌فهمید کدام بیست دقیقه کم است. یک گواهیِ TLS و کلیدِ حسابِ ACME اش که فقط روی دیسکِ قدیمی وجود داشته، پس میزبانِ جدید برای هر مرورگری یک نامِ ناهم‌خوان سرو می‌کند. و یک یکپارچه‌سازیِ خروجی — یک پردازشگرِ پرداخت، یک دراپِ SFTP بانکی، یک API شریک، یک پایگاه‌داده روی یک ارائه‌دهندهٔ سوم — که با آدرسِ IP allowlist شده، و درست در دورترین نقطهٔ ممکن از تغییری که باعثش شده، بی‌سروصدا شکست می‌خورد.

ارزش دارد دربارهٔ عبارتی که همه به کار می‌برند صریح باشیم. «مهاجرتِ بدون قطعی» تقریباً همیشه یعنی چند ثانیه اتصالِ ردشده که هیچ انسانی متوجهش نشده، و این هدفی کاملاً خوب برای نشانه‌گیری است. صفرِ واقعی نیازمندِ این است که هر دو ماشین هم‌زمان درست سرویس بدهند، که خودش نیازمندِ اپلیکیشنی است که تحملِ دو-ماشین‌بودن را داشته باشد: بدون وضعیتِ نشستِ محلی، بدون دایرکتوریِ آپلودِ محلی که فقط یک طرف داردش، و پایگاه‌داده‌ای که یا replicate می‌شود یا جای کاملاً دیگری زندگی می‌کند. بیشترِ استک‌های self-hosted به آن استاندارد نمی‌رسند، و برنامهٔ صادقانه یک توقفِ کوتاه، کنترل‌شده و تمرین‌شده است، نه یک پروژهٔ معماری که قصدِ شروعش را نداشتید.

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

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

مخزنِ دیپلویِ شما اپلیکیشن را توصیف می‌کند. ماشین را توصیف نمی‌کند. یک‌جایی بینِ اولین apt install و امروز، سرور لایه‌ای انباشته می‌کند که هیچ کنترلِ نسخه‌ای هرگز آن را ندیده: بسته‌هایی که دستی برای رفعِ یک مشکل نصب شده‌اند، یک واحدِ systemd که کسی با عجله نوشته، یک کارِ cron زیرِ یک حسابِ سرویس، قوانینِ فایروال، تنظیماتِ sysctl، یک locale، یک منطقهٔ زمانی، یک فایلِ swap، گواهی‌های TLS، کلیدهای میزبانِ SSH، نقش‌ها و مجوزهای پایگاه‌داده، و یک دایرکتوریِ رسانه که دقیقاً به این دلیل در مخزن نیست که کاربران آن‌جا گذاشته‌اندش. مهاجرت‌دادن یعنی بازتولیدِ عامدانهٔ آن لایه، و تنها راهِ عامدانه انجام‌دادنش این است که اول آن را یادداشت کنید.

پنج دستور بیشترِ آن را ثبت می‌کنند. dpkg --get-selections روی Debian و Ubuntu، یا dnf repoquery --userinstalled روی Rocky و Alma، مجموعهٔ بسته‌ها را به شما می‌دهد. systemctl list-unit-files --state=enabled هر چیزی را که برای اجرا در زمانِ بوت پیکربندی شده به شما می‌دهد، که پرسشِ بهتری از «چه چیزی در حالِ اجراست» است، چون چیزی را هم که الان کرش کرده شامل می‌شود. crontab -l -u برای هر حساب در /etc/passwd، به‌همراه محتوای /etc/cron.d و هر واحدِ .timer، کارِ زمان‌بندی‌شده را به شما می‌دهد. nft list ruleset یا ufw status numbered فایروال را به شما می‌دهد. و ss -tulpn چیزی را که واقعاً در حالِ گوش‌دادن است به شما می‌دهد، که این‌طوری سرویسی را که فراموش کرده بودید وجود دارد کشف می‌کنید. هر پنج‌تا را در فایل بنویسید و از روی ماشین کپی‌شان کنید بیرون، نه رویش.

بعد فهرستی هست که هیچ‌کس یادداشتش نمی‌کند، و همان است که هفته‌ها بعد نیش می‌زند: هر چیزی، هر جایی، که به آدرسِ IP فعلیِ شما اعتماد می‌کند. دروازه‌های پرداخت با allowlistهای IP. یک پایگاه‌دادهٔ managed روی یک ارائه‌دهندهٔ دیگر که قوانینِ دسترسی‌اش آدرسِ قدیمی را نام می‌برد. یک relay ی SMTP که بر اساسِ شبکه احراز هویت می‌کند. یک سرویسِ مانیتورینگ، یک فرستندهٔ webhook که فقط به آدرس‌های شناخته‌شده پست می‌کند، فایروالِ یک همکار. پیکربندی و مستنداتِ خودتان را برای آدرسِ قدیمی grep کنید، بعد پنلِ کنترلِ هر سرویسِ شخصِ‌ثالثی را که پولش را می‌دهید بررسی کنید. این‌ها بعد از گذار، ناهم‌زمان، در هر لحظه‌ای که یکپارچه‌سازی بعداً اجرا شود می‌شکنند — و دقیقاً به همین دلیل است که این‌قدر زیاد به‌عنوانِ «هم‌زمان یک چیزِ دیگر هم خراب شد» تشخیص داده می‌شوند.

در نهایت، خودِ ناحیهٔ DNS را هم ثبت کنید. آن را export کنید، یا دستِ‌کم نوع، مقدار و TTLِ هر رکورد را یادداشت کنید، چون مهاجرت دقیقاً همان لحظه‌ای است که یک نفر متوجهِ رکوردی می‌شود که دو سال اشتباه بوده و از سرِ لطف، وسطِ همه‌چیزِ دیگر درستش می‌کند.

چه چیزی را فهرست‌برداری کنیدکجا زندگی می‌کنداگر فراموشش کنید چه چیزی می‌شکند
بسته‌های نصب‌شده به‌صورت دستیپایگاه‌دادهٔ بسته‌هایک سرویس روی میزبانِ جدید به‌خاطرِ یک کتابخانهٔ گم‌شده که هیچ‌کس افزودنش را به‌یاد ندارد، از شروع سر باز می‌زند.
واحدها و تایمرهای فعال‌شدهsystemdکارِ پس‌زمینه بی‌سروصدا متوقف می‌شود: بدون پشتیبان‌گیری، بدون تمدیدِ گواهی، بدون کارگرِ صف.
کارهای cron به‌ازای هر کاربرcrontabهای هر حسابکارهای شبانه ناپدید می‌شوند و در پایانِ ماه متوجهشان می‌شوید.
مجموعه‌قوانینِ فایروالnftables یا ufwیا یک پورت بسته می‌ماند و اپ خراب به‌نظر می‌رسد، یا همه‌چیز باز است.
گواهی‌های TLS و کلیدِ حسابِ ACMEدایرکتوریِ گواهیمرورگرها یک ناهم‌خوانیِ نام نشان می‌دهند، و تمدیدها یک حسابِ تازه شروع می‌کنند.
نقش‌ها و مجوزهای پایگاه‌دادهتنظیماتِ سراسریِ سرور، نه dumpداده به‌خوبی بازیابی می‌شود اما اپلیکیشن نمی‌تواند واردش شود.
allowlistهای IP شخصِ‌ثالثپنل‌های افرادِ دیگرپرداخت‌ها، webhookها و APIهای شریک ساعت‌ها یا روزها بعد شکست می‌خورند.
ناحیهٔ DNS با TTLهاارائه‌دهندهٔ DNS شمانمی‌توانید بگویید کدام رکوردها هنوز باید جابه‌جا شوند، یا چقدر کش شده‌اند.

اول TTLِ DNS را پایین بیاورید — و بفهمید چرا باید روزها زودتر این کار را کرد

یک resolver بازگشتی، پاسخ را برای همان time-to-live ی که دریافت کرده کش می‌کند، و هیچ الزامی ندارد پیش از انقضای آن دوباره بپرسد. این پیامدی دارد که تقریباً همه را بارِ اول گیر می‌اندازد: پایین‌آوردنِ TTLِ یک رکورد از 86400 به 300 برای resolver ای که پاسخِ قدیمی را ده دقیقه پیش کش کرده، مطلقاً هیچ کاری نمی‌کند. آن resolver پاسخِ یک‌روزه را برای بیست‌وسه ساعت و پنجاه دقیقهٔ دیگر نگه می‌دارد، و فقط بعد از آن از TTLِ پنج‌دقیقه‌ایِ جدیدِ شما باخبر می‌شود. پس TTLِ پایین باید دستِ‌کم یک TTLِ کاملِ قدیمی پیش‌تر منتشر شود، پیش از این‌که قصدِ جابه‌جاییِ چیزی را داشته باشید. اگر رکوردهای شما روی TTLِ یک‌روزه‌اند، اولین اقدامِ مهاجرت دو روز پیش از گذار رخ می‌دهد، و فقط یک تغییرِ یک‌خطی است.

این کار را برای هر رکوردی که به ماشین اشاره می‌کند انجام دهید، نه فقط همانی که در ذهن دارید. رکوردِ A و رکوردِ AAAA — یک آدرسِ IPv6 که به میزبانِ قدیمی اشاره‌کردنش باقی مانده یک باگِ به‌زیبایی گیج‌کننده است، چون کلاینت‌های dual-stack بی‌سروصدا آن را ترجیح می‌دهند و فقط بخشی از کاربرانتان تحتِ تأثیر قرار می‌گیرند. رکوردهای MX. هر CNAME ای که جلوترشان است — به‌یاد داشته باشید که یک کلاینتِ دنبال‌کنندهٔ یک زنجیره، تابعِ TTLِ تک‌تکِ حلقه‌های آن است، پس یک رکوردِ A پنج‌دقیقه‌ای پشتِ یک CNAME یک‌روزه هنوز عملاً یک روز است. و اگر همزمان دارید ارائه‌دهندهٔ DNS را هم عوض می‌کنید، این کار را در همان هفته انجام ندهید: تفویضِ nameserver و رکوردهای glue توسط ناحیهٔ والد طبقِ زمان‌بندیِ خودشان کش می‌شوند، و ترکیب‌کردنِ این دو تغییر یعنی وقتی چیزی می‌شکند، نمی‌فهمید کدام‌یک باعثش شده.

فرض نکنید، تأیید کنید. dig +noall +answer example.com A نشان می‌دهد یک resolver الان چه چیزی را نگه داشته و چه شمارشِ معکوسی رویش مانده؛ پرس‌وجوی مستقیمِ سرورِ authoritative خودتان با dig @ns1.example.net example.com A نشان می‌دهد واقعاً چه چیزی منتشر کرده‌اید. اگر این دو با هم توافق نداشتند، دارید به کش نگاه می‌کنید، و عددِ کنارِ رکورد دقیقاً همان مدتی است که باید صبر کنید.

ارزش دارد بودجه‌ای برای دو ظرافت کنار بگذارید. برخی resolverها clamp می‌کنند: بخشی از forwarderهای ISP و سازمانی صرف‌نظر از چیزی که منتشر می‌کنید یک TTLِ حداقلی را اجرا می‌کنند، که از نظرِ فنی نکوهیده اما کاملاً واقعی است. و طبقِ RFC 8767، یک resolver ممکن است وقتی نمی‌تواند به سرورهای authoritative شما برسد، عمداً یک پاسخِ کهنه سرو کند — رفتاری عالی برای تاب‌آوری، اما همان روزی که می‌خواهید یک تغییر منتشر شود آزاردهنده است. رویِ‌هم‌رفته، برای یک دُمِ بلند که با ساعت، گاهی یک روز، اندازه‌گیری می‌شود، پس از جابه‌جاییِ بیشترِ ترافیک برنامه‌ریزی کنید. آن دُم مشکلی نیست تا وقتی ماشینِ قدیمی همچنان درست پاسخ می‌دهد، که دقیقاً به همین دلیل روشن نگهش می‌دارید. RFC 2181 مرجعِ این است که TTLها وقتی پیاده‌سازی‌ها با هم توافق ندارند باید چطور رفتار کنند.

چه زمانیاقدامچرا همان زمان
T منهای 7 روزفهرست‌برداری از سرورِ قدیمی؛ نوشتنِ runbookهر چیزی که این‌جا پیدا می‌شود برنامه را تغییر می‌دهد، پس باید پیش از قطعی‌شدنِ برنامه رخ دهد.
T منهای 3 روزتأمینِ VPS جدید؛ اولین بازیابی؛ تمرینوقت باقی می‌گذارد تا وقتی تمرین شکاف‌هایی پیدا کرد، ماشین بارِ دوم بازسازی شود.
T منهای 2 روزپایین‌آوردنِ TTLهای A، AAAA و MX به 300باید یک TTLِ کاملِ قدیمی بگذرد تا مقدارِ پایین در همهٔ کش‌ها بنشیند.
T منهای 1 روزاولین پاسِ rsync؛ شروعِ replication پایگاه‌دادهطولانی و بدونِ نظارت، درحالی‌که سرورِ قدیمی هنوز ترافیکِ تولید را حمل می‌کند.
T صفرتوقفِ نوشتن‌ها، sync نهایی، تأیید، تعویضِ DNSتنها پنجرهٔ غیرقابل‌بازگشت؛ کوتاه است چون همهٔ موارد بالا از قبل رخ داده‌اند.
T به‌علاوهٔ 1 ساعتهر دو لاگِ دسترسی را تماشا کنیدافتِ ترافیک روی میزبانِ قدیمی، اندازه‌گیریِ واقعیِ شما از انقضای کش است.
T به‌علاوهٔ 7 روزاز رده خارج‌کردنِ میزبانِ قدیمی؛ بالابردنِ دوبارهٔ TTLهابازگشت منقضی شده؛ یک TTLِ دائمیِ 300 ثانیه‌ای بدونِ هیچ سودی، فقط تأخیر هزینه می‌کند.

روی جعبهٔ جدید تمرین کنید درحالی‌که قدیمی هنوز سرویس می‌دهد

باارزش‌ترین عادت در کلِ این فرایند این است که ماشینِ جدید روزها پیش از این‌که اهمیت پیدا کند وجود دارد و کار می‌کند. یک VPS از نظرِ عملی یک اجارهٔ ساعتی است: روی پلن‌های ما یک سرور تقریباً شصت ثانیه بعد از تأییدِ پرداخت زنده می‌شود، بدون هزینهٔ راه‌اندازی و بدون قرارداد، پس یک تمرینِ سه‌روزه روی یک پلنِ $8.50 چیزی حدودِ یک دلار هزینه دارد. این راهی به‌طرزِ چشمگیری ارزان برای تبدیلِ هر مجهولِ مهاجرتتان به یک معلوم، پیش از آن‌که ساعت شروع به شمردن کند.

آن را با hostname تست کنید، نه با IP. مرور به آدرسِ سرورِ جدید، virtual host پیش‌فرض، بدون تطبیقِ SNI، یک هشدارِ گواهی و مجموعه‌مسیرهایی می‌دهد که ممکن است اصلاً شبیهِ production نباشند — و با کمالِ میل شما را متقاعد می‌کند چیزی کار می‌کند درحالی‌که نمی‌کند. ابزارِ درست یک override برای resolver است. curl --resolve یک hostname را برای یک دستور به یک آدرس سنجاق می‌کند، پس curl --resolve example.com:443:203.0.113.10 https://example.com/ نامِ واقعی، دست‌دهیِ واقعیِ TLS و virtual host واقعی را روی ماشینِ جدید به کار می‌گیرد درحالی‌که بقیهٔ دنیا هنوز به قدیمی می‌رسد. برای تستِ تعاملی، یک خط در فایلِ hosts ایستگاهِ کاریِ شما همان کار را برای یک مرورگر انجام می‌دهد.

چیزی که تمرین به‌طورِ قابل‌اعتماد گیر می‌اندازد، همان لایهٔ مستندنشدهٔ انباشته‌شده از بخشِ قبل است. دیمنی که از پیش از آخرین ریبوت در حالِ اجرا بوده و در واقع فعال نیست. کارِ cron ای که برای گزارشِ شکست‌ها به یک transport ایمیلِ محلی وابسته است. مالکیتِ فایلی که به‌صورتِ عدد از کپی جان سالم به‌در برده اما روی ماشینی با /etc/passwd ای متفاوت معنیِ دیگری دارد. یک آدرسِ hardcode شده در یک فایلِ پیکربندی. پایگاه‌داده‌ای که با یک character set روی نسخه‌ای ساخته شده که پیش‌فرضش فرق داشته. یک نسخهٔ فرعیِ Python یا PHP که چیزی را که استفاده می‌کنید deprecated کرده. تعمیرِ هرکدام از این‌ها در طولِ تمرین ده دقیقه هزینه دارد و تشخیصش در طولِ گذار یک ساعت.

یک تست بیشتر از بقیه ارزش دارد: ماشینِ جدید را دوبار بسازید. آن را از صفر، فقط با استفاده از فهرست و پشتیبانتان، بدونِ نگاه‌کردن به سرورِ قدیمی، بازسازی کنید. اگر بارِ دوم درست بالا آمد، فهرستتان واقعی است و runbook تان قابلِ‌اجراست. اگر نیامد، همین الان شکاف را در موقعیتی پیدا کرده‌اید که پیداکردنش هیچ هزینه‌ای ندارد. وقتی درست شد یک اسنپ‌شات بگیرید — اسنپ‌شات‌های ساعتی با نگه‌داریِ هفت‌روزه روی هر پلن گنجانده شده‌اند، و بازیابی تقریباً سی ثانیه طول می‌کشد — تا هر آزمایشِ بعدی روی جعبهٔ جدید هم قابلِ‌بازگشت باشد.

دوبار rsync: یک پاسِ طولانی درحالی‌که در حالِ اجراست، یک پاسِ کوتاه در پنجره

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

فلگ‌ها بیشتر از آن‌چه مردم انتظار دارند اهمیت دارند. rsync -aHAX --numeric-ids خطِ پایه است: -a برای حالتِ archive، -H برای حفظِ hardlinkها — که برای ذخیره‌سازی‌های Maildir و درخت‌های پشتیبانِ deduplicate شده به‌شدت اهمیت دارد، چون حذفشان می‌تواند مصرفِ دیسکتان را چندبرابر کند — -A برای ACLهای POSIX، -X برای صفت‌های گسترده مثلِ برچسب‌های SELinux و قابلیت‌های فایل، و --numeric-ids تا شناسهٔ کاربری به‌جای این‌که از پایگاه‌دادهٔ کاربریِ مبدأ resolve و دوباره روی یک پایگاه‌دادهٔ متفاوت در مقصد resolve شود، به‌صورتِ عدد کپی شود. برای یک خطِ پیشرفتِ معقول --info=progress2 را اضافه کنید و --partial را هم، تا انتقالِ قطع‌شده به‌جای شروعِ دوباره، از همان‌جا ادامه یابد. -z را نگذارید مگر این‌که لینک واقعاً کند باشد: فشرده‌کردنِ رسانه‌های از‌قبل‌فشرده و آرشیوهای رمزنگاری‌شده فقط گلوگاه را به CPU منتقل می‌کند.

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

کاری که نباید بکنید rsync کردنِ کلِ فایل‌سیستمِ root است. این یک میان‌بُرِ محبوب است و ماشینی تولید می‌کند که هیچ‌کس نمی‌تواند دربارهاش استدلال کند. حتی با excludeکردنِ /proc، /sys، /dev، /run و /tmp، به سیستمی می‌رسید که کرنل و initramfs اش از یک میزبان آمده، نام‌گذاریِ اینترفیسِ شبکه‌اش از سخت‌افزاری متفاوت مشتق شده، /etc/machine-id اش حالا روی دو ماشینِ زنده تکراری شده، و پنج سالِ انباشته‌شدهٔ drift پیکربندی‌اش را همین الان پول داده‌اید حفظش کنید. داده و پیکربندی‌ای را که فهرست‌برداری کرده‌اید مهاجرت دهید؛ سیستم‌عامل را تازه از یک template نصب کنید. یک ساعتِ اضافه می‌گیرد، یک پایهٔ مدرن و تمیز به شما می‌دهد، و یعنی سرورِ جدید ماشینی است که می‌فهمیدش، نه کپیِ ماشینی که نمی‌فهمیدش.

به‌جای اعتمادکردن به exit code، خودِ کپی را تأیید کنید. بعد از هر دو پاس، همان دستور را دوباره با -n --checksum --itemize-changes اجرا کنید: یک dry run که محتوا را به‌جای timestamp مقایسه می‌کند و به‌ازای هر تفاوت یک خط چاپ می‌کند. سکوت همان نتیجه‌ای است که می‌خواهید، و ادعایی به‌مراتب قوی‌تر از یکسان‌بودنِ du -s روی هر دو طرف است.

پایگاه‌داده همان بخشی است که rsync نمی‌تواند در آن کمکتان کند

کپی‌کردنِ دایرکتوریِ یک پایگاه‌دادهٔ زنده در سطحِ فایل، یک کپیِ پاره‌شده به شما می‌دهد: بعضی صفحه‌ها نوشته شده، بعضی نه، بدونِ هیچ تضمینی که کدام‌بخشش یک مرزِ تراکنشیِ سازگار می‌سازد. InnoDB ممکن است کاملاً از پسش بربیاید و سالم به‌نظر برسد، که این از شکست‌خوردن هم بدتر است، چون فقط روزی می‌فهمید که بازیابی کار نمی‌کند. دقیقاً دو استراتژیِ صادقانه وجود دارد — گرفتنِ یک dump سازگار از نظرِ تراکنشی، یا replicateکردن — و انتخاب بینِ آن دو، انتخابی است دربارهٔ این‌که چقدر قطعی می‌خرید.

برای مسیرِ dump روی MySQL و MariaDB، mysqldump --single-transaction --routines --triggers --events بدونِ قفل‌کردنِ کلِ سرور یک snapshot سازگار می‌دهد، با دو نکتهٔ هشدارآمیز که ارزشِ دانستن دارند: فقط برای جدول‌های تراکنشی سازگار است، پس یک جدولِ قدیمیِ MyISAM به‌تنهایی بی‌سروصدا این تضمین را می‌شکند، و هر عبارتِ DDL ای که در طولِ dump اجرا شود هم همین کار را می‌کند. روی PostgreSQL، pg_dump -Fc هر پایگاه‌داده را مدیریت می‌کند، و pg_dumpall --globals-only همان نیمه‌ای را مدیریت می‌کند که مردم فراموشش می‌کنند — نقش‌ها، رمزهای عبور، مجوزها و tablespaceها در سطحِ cluster زندگی می‌کنند، نه داخلِ یک پایگاه‌دادهٔ تکی، پس بازیابی بدونِ آن‌ها داده‌ای بی‌نقص تولید می‌کند که اپلیکیشن نمی‌تواند به آن احراز هویت کند.

عددی که پنجرهٔ شما را تعیین می‌کند اندازهٔ dump نیست، بلکه dump به‌علاوهٔ انتقال به‌علاوهٔ بازیابی به‌علاوهٔ بازسازیِ index است، و آخری معمولاً بزرگ‌ترین است. آن را در طولِ تمرین روی dataset واقعی اندازه بگیرید، نه این‌که تخمین بزنید. چند گیگابایت یعنی چند دقیقه؛ صد گیگابایت با indexگذاریِ قابل‌توجه می‌تواند ساعت‌ها شود، و در آن نقطه مسیرِ dump برای یک سرویسِ زنده دیگر عملی نیست و replication پاسخ است، نه یک بهینه‌سازی.

مسیرِ replication هزینه را وارونه می‌کند: کار را از قبل انجام می‌دهید و گذار پیش‌پاافتاده می‌شود. روزها زودتر یک replica روی میزبانِ جدید راه بیندازید — replication مبتنی‌بر GTID برای MySQL و MariaDB، pg_basebackup و یک standby استریمینگ برای PostgreSQL، یا logical replication وقتی همزمان دارید از یک نسخهٔ اصلی هم عبور می‌کنید. بگذارید به‌روز برسد و به‌روز بماند. گذار آن‌وقت این است: نوشتن روی primary را متوقف کنید، صبر کنید تا replica صفر تأخیر گزارش کند، آن را promote کنید، اپلیکیشن را به‌سمتش بگردانید. این چند ثانیه است، و تنها روشی است که صادقانه شایستهٔ عبارتِ «قطعیِ نزدیک‌به‌صفر» است.

وضعیتی را که در پایگاه‌داده نیست فراموش نکنید. Redis، Valkey و Memcached نشست‌ها، شمارنده‌های rate-limit و صف‌ها را نگه می‌دارند؛ یک search index در Elasticsearch، OpenSearch یا Meilisearch یک نسخهٔ مشتق‌شده از داده‌تان را نگه می‌دارد. برای هرکدام، صریحاً تصمیم بگیرید آیا مهاجرتش می‌دهید یا بازسازیش می‌کنید. یک نمونهٔ Redis که نشست‌ها را نگه داشته، ارزشِ جابه‌جایی با یک BGSAVE و یک کپی از فایلِ حاصل را دارد، مگر این‌که راضی باشید همه را از سیستم خارج کنید. یک search index تقریباً همیشه reindexکردنش روی میزبانِ جدید سریع‌تر از انتقال‌دادنش است — اما reindexکردن زمان می‌برد، پس آن را در طولِ تمرین شروع کنید، نه در طولِ توقف.

استراتژیقطعیِ گذارکار پیش از پنجرهچه زمانی انتخابِ درستی است
کپیِ فایلیِ یک دایرکتوریِ دادهٔ در حالِ اجراهیچ، و ممکن است داده خراب باشدهیچهرگز. این‌جا آورده شده چون اولین چیزی است که مردم امتحان می‌کنند.
dump و بازیابیِ سازگارdump به‌علاوهٔ انتقال به‌علاوهٔ بازیابی به‌علاوهٔ reindexیک‌بار در طولِ تمرین اندازه‌گیری کنیدDataset هایی به‌اندازهٔ کافی کوچک که مجموعِ اندازه‌گیری‌شده در تحملِ شما جا بگیرد.
dump، بازیابی، سپس بازپخشِ deltaدقیقه‌هانگه‌داریِ binlog یا WAL از قبل پیکربندی‌شدهDatasetهای میان‌اندازه که یک replica کامل بیش از چیزی است که می‌خواهید راه بیندازید.
replica ای که در گذار promote می‌شودثانیه‌هاreplication در حالِ اجرا و بدونِ تأخیر برای چند روزهر چیزِ بزرگ، و هر چیزی که یک توقفِ طولانی در آن غیرقابل‌قبول است.
پایگاه‌داده را متوقف کنید، فایل‌ها را سرد کپی کنیدطولِ خودِ کپیهیچسرویس‌های داخلیِ کوچک که یک ساعت آفلاین‌بودن واقعاً هیچ هزینه‌ای ندارد.

گواهی‌های TLS، کلیدهای میزبانِ SSH و هویت‌هایی که نمی‌توانید فقط دوباره صادرشان کنید

صدورِ گواهی دقیقاً در بدترین لحظهٔ ممکن یک مسئلهٔ مرغ‌و‌تخم‌مرغ دارد. چالشِ HTTP-01 کنترلِ یک نام را با گرفتنِ یک فایل از روی همان نام اثبات می‌کند، که نیازمندِ این است که نام از قبل به ماشینِ در حالِ اعتبارسنجی resolve شود — و پیش از گذار، نمی‌شود. سه راهِ خروج هست و باید عامدانه یکی را انتخاب کنید. دایرکتوریِ گواهی را آن‌طرف کپی کنید، که بلافاصله کار می‌کند و چون کلیدِ خودتان است کاملاً مشروع است. به‌جایش از چالشِ DNS-01 استفاده کنید، که با انتشارِ یک رکوردِ TXT اعتبارسنجی می‌کند و به همین دلیل روی ماشینی هم که هنوز چیزی به‌سمتش اشاره نمی‌کند کار می‌کند، و به‌هرحال تنها گزینه برای یک گواهیِ wildcard است. یا یک پنجرهٔ کوتاه بعد از تعویضِ DNS را بپذیرید که در طولِ آن میزبانِ جدید گواهیِ خودش را درخواست می‌کند، که برای یک سایتِ شخصی خوب است و برای هر چیزی که کاربر دارد خوب نیست.

اگر کپی می‌کنید، کلِ آن را کپی کنید. گواهی‌ها و کلیدهای خصوصی بخشِ بدیهی‌اند؛ کلیدِ حسابِ ACME همان بخشی است که جا می‌ماند، و بدونش، کلاینتِ روی میزبانِ جدید در اولین تمدید یک حسابِ کاملاً تازه ثبت می‌کند. همه‌چیز به‌نظر کار می‌کند، و شما بی‌سروصدا تاریخچهٔ حساب و هر وضعیتِ مختصِ آن حساب را از دست داده‌اید. مالکیت و مجوزها را هم حفظ کنید — کلیدهای خصوصی روی 600، دایرکتوریِ آرشیو روی 700 — چون کپی‌ای که مجوزهای یک کلید را گسترده‌تر کند، نتیجه‌اش از خودِ مهاجرتی که نگرانش بودید هم بدتر است.

برنامه‌ریزی نکنید که بارها دوباره صادر کنید و ببینید چه می‌شود. محدودیت‌های نرخِ Let's Encrypt گواهی‌های تکراری برای یک مجموعهٔ یکسان از hostnameها را در هفته سقف می‌زنند، و دو تمرینِ ناموفق به‌علاوهٔ یک صدورِ واقعی، راهی به‌طرزِ شگفت‌آوری آسان برای رسیدن به سقف است، درست همان روزی که نمی‌توانید صبر کنید. تمرین‌ها را به‌سمتِ محیطِ staging بگردانید؛ endpoint تولید را برای کارِ واقعی نگه دارید.

کلیدهای میزبانِ SSH آن هویتِ دیگرِ درگیر در بازی‌اند، و این‌جا پاسخِ درست واقعاً به این بستگی دارد که چرا دارید جابه‌جا می‌شوید. کپی‌کردنِ /etc/ssh/ssh_host_* مهاجرت را نامرئی می‌کند: known_hosts ی هر کلاینت همچنان تطبیق دارد، و هیچ اتوماسیونی با یک هشدارِ fingerprint متوقف نمی‌شود. این راحت است، و برای یک جابه‌جاییِ روتین بینِ ارائه‌دهنده‌هایی که به آن‌ها اعتماد دارید انتخابِ درستی است. اگر دلیلِ ترک‌کردنتان این است که دیگر به میزبان یا ارائه‌دهندهٔ قدیمی اعتماد ندارید، انتخابِ اشتباهی است — هرکس که به آن دیسک دسترسی داشته کلیدِ خصوصیِ میزبانِ شما را هم داشته، و بردنش به سرورِ جدید یعنی بردنِ همان مشکل به همراهش. در آن حالت کلیدهای تازه بسازید، fingerprint جدید را از کانالی که خودِ سرور نیست منتشر کنید، و از کلاینت‌ها بخواهید ssh-keygen -R را روی ورودیِ قدیمی اجرا کنند. برای این‌که کلیدها کجا زندگی می‌کنند و چطور انتخاب می‌شوند، مرجعِ sshd در OpenSSH را ببینید.

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

گذار: ده دقیقه‌ای که به یک دستورِ مکتوب نیاز دارد

تا این‌جا همه‌چیز قابلِ‌بازگشت و بدونِ عجله بود. گذار هیچ‌کدام از این دو نیست، و دقیقاً همین کلِ استدلال برای از‌پیش‌نوشتنش است: بداهه‌سازی زیرِ فشارِ زمان همان چیزی است که یک پنجرهٔ پنج‌دقیقه‌ای را به یک حادثهٔ دوساعته تبدیل می‌کند. runbook باید دستوراتِ عینی و به‌ترتیب باشد، با خروجیِ موردِ انتظار کنارِ هرکدام، طوری که اجرایش نیازمندِ خواندن باشد، نه فکرکردن.

ترتیبی که کار می‌کند. اول، نوشتن روی میزبانِ قدیمی را متوقف کنید — یک صفحهٔ تعمیر و نگهداری، یک فلگِ read-only، یا به‌سادگی متوقف‌کردنِ اپلیکیشن درحالی‌که وب‌سرور همچنان با یک صفحهٔ نگه‌دارنده پاسخ می‌دهد. دوم، پاسِ نهاییِ rsync را با --delete اجرا کنید. سوم، مرحلهٔ پایگاه‌داده را تمام کنید: یا همان dump-انتقال-بازیابیِ اندازه‌گیری‌شده، یا نوشتن روی primary را متوقف کنید، صفربودنِ تأخیرِ replication را تأیید کنید و replica را promote کنید. چهارم، سرویس‌ها را روی میزبانِ جدید شروع کنید و کمی مهلت بدهید تا جا بیفتند — connection poolها، کارگرهای صف و بارگذاریِ گواهی، همه روی یک شروعِ سرد بیش از آن‌چه به‌یاد دارید طول می‌کشند. پنجم، تأیید کنید. ششم، و فقط بعد از عبورِ تأیید، رکوردهای DNS را تغییر دهید. هفتم، میزبانِ قدیمی را روشن بگذارید.

تأیید باید معنایی داشته باشد. گرفتنِ صفحهٔ اصلی فقط ثابت می‌کند وب‌سرور روشن است و نه چیزِ دیگری. از curl --resolve روی hostname واقعی، روی مسیری که پایگاه‌داده را لمس می‌کند و چیزی برمی‌گرداند که بتوانید رویش assert کنید استفاده کنید — یک health endpoint که اتصالِ پایگاه‌داده، اتصالِ کش و فضای آزادِ دیسک را چک می‌کند فقط به همین دلیل ارزشِ نوشتن دارد. بعد لاگِ دسترسیِ میزبانِ جدید را بخوانید و تأیید کنید درخواستتان در آن هست. این قدمِ آخر شاید عجیب‌غریب به‌نظر برسد، اما همان قدمی است که موقعیتی را می‌گیرد که override ی resolver شما اثر نکرده و شما فقط با دقت سرورِ قدیمی را تأیید کرده‌اید.

بعد از تعویضِ DNS، هر دو لاگِ دسترسی را کنارِ هم تماشا کنید. ترافیک روی میزبانِ جدید بالا می‌رود؛ ترافیک روی میزبانِ قدیمی با انقضای کش‌ها افت می‌کند، و آن منحنیِ افت تنها اندازه‌گیریِ صادقانه از این است که دُم واقعاً چقدر طول می‌کشد. وقتی لاگِ میزبانِ قدیمی نزدیکِ صفر تخت شد، مهاجرت تمام شده. تا وقتی این اتفاق نیفتاده، ماشینِ قدیمی باید برای کاربرانی که هنوز به آن می‌رسند درست رفتار کند — و دقیقاً به همین دلیل روشن و read-only می‌ماند، نه این‌که در یک لحظهٔ شور‌وشوق خاموش شود. اگر اپلیکیشن نمی‌تواند read-only شود، معمولاً سرو‌کردنِ دادهٔ کهنه توسط میزبانِ قدیمی برای چند ساعت آسیبِ کوچک‌تری است تا سروکردنِ connection refused توسط میزبانِ قدیمی، اما این قضاوتی است که باید از قبل بگیرید، نه در همان لحظه.

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

ایمیل، rDNS و اعتباری که همراهتان سفر نمی‌کند

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

اولین رکوردی که می‌شکند SPF است. یک سیاست شاملِ یک مکانیزمِ ip4: که آدرسِ قدیمی را نام می‌برد، همان لحظه‌ای که از آدرسِ جدید ارسال می‌کنید شروع به شکست‌خوردن می‌کند، و چون سیاست‌های RFC 7208 رکوردهای DNS هستند، TTLِ خودشان را دارند که باید دورش برنامه‌ریزی کنید. آدرسِ جدید را پیش از گذار به SPF اضافه کنید، در طولِ همپوشانی هر دو را فهرست‌شده نگه دارید، و وقتی از رده خارجش می‌کنید قدیمی را حذف کنید. DKIM بدونِ مشکل سفر می‌کند، تا وقتی کلیدِ خصوصی را همراهِ بقیهٔ پیکربندی کپی کنید، چون نیمهٔ عمومی از قبل منتشر شده. DMARC نیازی به تغییر ندارد، اما ارزش دارد تأیید کنید آدرسِ گزارش‌دهی هنوز روی ماشینی که در آستانهٔ نابودشدن است وجود دارد.

DNS معکوس برای یک میزبانِ فرستنده اختیاری نیست. رکوردِ PTR روی آدرسِ جدید باید وجود داشته باشد و باید با نامی که سرور در HELO یا EHLO اش اعلام می‌کند تطبیق داشته باشد، وگرنه سهمِ بزرگی از گیرنده‌ها فقط به همین دلیل رد می‌کنند. روی پلن‌های ما PTR از پنل قابلِ‌ویرایش است، پس یک تیک‌زدن است، نه یک تیکت — آن را در طولِ تمرین تنظیم کنید، تأیید کنید resolve می‌شود، و تأیید کنید رکوردِ forward هم برمی‌گردد و تطبیق دارد. بعد پیش از این‌که اصلاً چیزی بفرستید، آدرسِ جدید را در برابرِ فهرست‌های سیاهِ اصلی چک کنید: آدرس‌های بازیافتی گاهی از قبل لیست‌شده از راه می‌رسند، و فهمیدنش از پیامِ تستِ خودتان هیچ هزینه‌ای ندارد درحالی‌که فهمیدنش از یک مشتری هزینهٔ زیادی دارد. Spamhaus همانی است که بیشترین اهمیت را دارد.

برای دریافت، هر دو میزبان را در‌دسترس نگه دارید. سرورِ جدید را به‌عنوانِ MX با اولویتِ 10 اضافه کنید و قدیمی را برای یک هفته روی اولویتِ 20 نگه دارید، به‌جای این‌که حذفش کنید: فرستنده‌ها دوباره تلاش می‌کنند، بعضی‌هایشان رکوردِ MX شما را کش کرده‌اند، و یک میل‌سرور که بی‌سروصدا روی میزبانِ قدیمی می‌پذیرد، بسیار بهتر از یک bounce است. بعد، پیش از این‌که ماشینِ قدیمی را نابود کنید، صفش را flush و خالی کنید — postqueue -f برای اجبارِ یک تلاشِ تحویل و mailq برای تأییدِ این‌که نتیجه خالی است. پیام‌هایی که روی صفِ سروری که در آستانهٔ حذفش هستید نشسته‌اند، تأخیر نخورده‌اند. رفته‌اند. راهنمای میل‌سرورِ self-hosted سمتِ deliverability را کامل پوشش می‌دهد.

وقتی ارائه‌دهندهٔ قدیمی از قبل ماشین را خاموش کرده

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

درحالی‌که یک نمونه معلق است اما هنوز حذف نشده، اغلب سه مسیر باقی می‌ماند، به‌ترتیبِ نزولیِ سودمندی. پنلِ کنترل ممکن است هنوز دانلودِ یک اسنپ‌شات یا پشتیبان را پیشنهاد دهد، که کلِ مسئله را در یک قدم حل می‌کند. یک حالتِ rescue یا recovery ممکن است هنوز یک ایمیجِ زنده را با دیسکِ شما متصل بوت کند، و به شما اجازه دهد فایل‌سیستم را mount کنید و چیزهایی که اهمیت دارند را از روی شبکه کپی کنید بیرون. و کنسولِ اضطراری ممکن است حتی وقتی شبکه غیرفعال است هنوز متصل شود، که برای خواندنِ فایل‌های پیکربندی، بازیابیِ یک کلید، یا یادداشت‌کردنِ چیزی که نصب شده بود کافی است — اما مسیری برای پایگاه‌داده نیست، پس رویش برنامه‌ریزی نکنید. آن‌ها را به همان ترتیب امتحان کنید، و بلافاصله امتحانشان کنید: نگه‌داری بعد از تعلیق یک سیاست است، نه یک حق، و اغلب با روز اندازه‌گیری می‌شود.

محدودیتی هست که هیچ تیکتِ پشتیبانی حلش نمی‌کند، و ارزش دارد صریح بیانش کنیم چون پیامدِ مستقیمِ همان مدلی است که این سایت می‌فروشد. روی میزبانی که هرگز هویتی جمع‌آوری نکرده — از جمله همین‌جا — هیچ راهی برای اثباتِ این‌که صاحبِ حساب هستید وجود ندارد، جز در‌اختیار‌داشتنِ اعتبارنامه‌های حساب. این همان نکتهٔ هاستینگِ no-KYC است و همان صورت‌حسابش هم هست: هیچ‌کس نمی‌تواند دسترسیِ شما را بر اساسِ یک عکسِ پاسپورت بازگرداند، چون هیچ پاسپورتی هرگز به چیزی وصل نبوده. راهنمای هاستینگِ no-KYC این مبادله را کامل پوشش می‌دهد؛ پیامدِ عملیاتی‌اش به‌سادگی این است که برنامهٔ بازیابیِ شما نمی‌تواند از خیرخواهیِ کسِ دیگری عبور کند.

توالیِ اضطراری همان توالیِ برنامه‌ریزی‌شده است با همپوشانیِ حذف‌شده. میزبانِ جدید را از پشتیبانِ خارج‌از‌ماشینتان بالا بیاورید. آن را درست‌وحسابی با hostname تأیید کنید، چون وسوسهٔ رد‌کردنِ تأیید دقیقاً وقتی قوی‌ترین است که از قبل قطعی هستید. بعد بلافاصله DNS را جابه‌جا کنید — انضباطِ TTL همچنان اعمال می‌شود، با این تفاوت که حالا دارید دُمِ کش را به‌عنوانِ قطعی می‌پردازید، نه این‌که آن را به‌عنوانِ همپوشانی خرج کنید، که این خودش روشن‌ترین استدلال برای پایین‌نگه‌داشتنِ TTLها به‌عنوانِ یک سیاستِ دائمی است، نه فقط یک قدمِ مهاجرت. برای مدتی منتظرِ ایمیلِ افت‌کیفیت‌یافته باشید و زود به مردم هشدار دهید، نه این‌که بعداً توضیح دهید.

این درس فراتر از همین یک روزِ بد هم تعمیم پیدا می‌کند. پشتیبانی که روی خودِ سرور زندگی می‌کند پشتیبان نیست؛ یک نسخهٔ دومِ همان چیزی است که در آستانهٔ از‌دست‌دادنش هستید. ویژگی‌ای که اهمیت دارد این است که کپی جای دیگری باشد، پیش از خروج رمزنگاری شده باشد، append-only باشد تا میزبانِ به‌خطرافتاده یا معلق نتواند تاریخچهٔ خودش را حذف کند، و — بخشی که همه ردش می‌کنند — واقعاً یک‌بار، در یک نمونهٔ یک‌بارمصرف، بازیابی شده باشد، تا بدانید بازیابی کار می‌کند. چک‌لیستِ سخت‌سازی راه‌اندازیِ آن روی یک ماشینِ جدید را پوشش می‌دهد؛ اگر این بخش را می‌خوانید چون از قبل خیلی دیر شده، همین امروز، پیش از هر چیزِ دیگری، آن را روی ماشینی که به آن مهاجرت می‌کنید راه بیندازید.

بازگشت: trigger را تعریف کنید، و به آن تاریخِ انقضا بدهید

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

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

سرورِ قدیمی را برای حدودِ یک هفته نگه دارید: روشن، read-only، TTLِ DNS همچنان پایین، مانیتورینگ همچنان به‌سمتش. روی کوچک‌ترین پلن، آن بیمه چیزی حدودِ دو دلار هزینه دارد، که عددی نیست که باید در تصمیم نقش داشته باشد. چیزی که باید نقش داشته باشد این است که یک هفته به‌اندازهٔ کافی طولانی است تا کارهای cron هفتگی، گزارش‌های تقریباً‌ماهانه، و یکپارچه‌سازی‌ای که فقط جمعه‌ها فعال می‌شود، دستِ‌کم یک‌بار روی میزبانِ جدید اجرا شده باشند — این‌ها همان شکست‌هایی‌اند که یک پنجرهٔ دوروزه کاملاً از قلم می‌اندازد.

بعد عامدانه از رده خارجش کنید. تأیید کنید لاگِ دسترسیِ میزبانِ قدیمی برای یک روز تخت بوده. یک پشتیبانِ نهایی از آن بگیرید و بیشتر از آن‌چه فکر می‌کنید لازم است نگهش دارید. هر چیزی را که نگه داشته باطل کنید: کلیدهای API، کلیدهای deploy، کاربرانِ پایگاه‌داده، ورودی‌هایش در allowlistهای IP افرادِ دیگر، چک‌های مانیتورینگش، ورودیِ SPF اش، رکوردِ MX اش. نمونه را نابود کنید. و در آخر TTLهای DNS را به چیزی معقول برگردانید — یک TTLِ دائمیِ 300 ثانیه‌ای یعنی resolverها برای بقیهٔ عمرِ سایت بیست بار در ساعت دوباره اعتبارسنجی می‌کنند، که بعد از تمام‌شدنِ مهاجرت هیچ سودی برایتان ندارد و روی هر lookup سردی کمی تأخیر هزینه می‌کند. یک ساعت مقدارِ دائمیِ معقولی است؛ یک روز هم برای رکوردهایی که هرگز انتظار ندارید سریع تغییر کنند خوب است.

مهاجرت، به همان ترتیبی که باید اجرایش کنید

یک هفته مانده، ماشینِ قدیمی را فهرست‌برداری کنید و runbook را بنویسید: بسته‌ها، واحدهای فعال‌شده، crontabها، فایروال، ساکت‌های در حالِ گوش‌دادن، نقش‌های پایگاه‌داده، و هر شخصِ‌ثالثی که آدرسِ قدیمی را allowlist کرده. سه روز مانده، VPS جدید را تأمین کنید، رویش بازیابی کنید، و کلِ کار را با hostname و یک override برای resolver تمرین کنید — بعد یک‌بار فقط از روی فهرست بازسازیش کنید تا ثابت شود فهرست واقعی است. دو روز مانده، TTLهای A، AAAA و MX را به 300 پایین بیاورید تا پیش از این‌که نیازشان داشته باشید پایین باشند، یک TTLِ کاملِ قدیمی بگذرد.

یک روز مانده، اولین پاسِ rsync را با -aHAX --numeric-ids درحالی‌که تولید ادامه دارد اجرا کنید، و replication پایگاه‌داده را راه بیندازید یا پنجرهٔ dump را روی dataset واقعی اندازه بگیرید. گواهی‌ها را هم در همین پاس سروسامان دهید — دایرکتوریِ گواهی شاملِ کلیدِ حسابِ ACME را کپی کنید، یا به DNS-01 سوییچ کنید — و رکوردِ PTR و ورودیِ جدیدِ SPF را روی آدرسِ جدید تنظیم کنید، پیش از این‌که چیزی از آن ایمیل بفرستد.

در پنجره: نوشتن‌ها را متوقف کنید، rsync نهایی را با --delete اجرا کنید، پایگاه‌داده را تمام کنید، سرویس‌ها را شروع کنید، در برابرِ hostname واقعی روی مسیری که پایگاه‌داده را لمس می‌کند تأیید کنید، تأیید کنید درخواست در لاگِ میزبانِ جدید نشسته، و فقط بعد از آن DNS را تعویض کنید. میزبانِ قدیمی را روشن و read-only بگذارید. هر دو لاگِ دسترسی را تماشا کنید تا قدیمی تخت شود.

یک هفته بعد: تأیید کنید کارهای هفتگی روی میزبانِ جدید اجرا شده‌اند، یک پشتیبانِ نهایی از قدیمی بگیرید، کلیدها و ورودی‌های allowlist اش را همه‌جا باطل کنید، نابودش کنید، و TTLها را دوباره بالا ببرید. اگر می‌خواهید ماشینِ جدید بهتر از آن‌که ترک کردید باشد، نه فقط تازه‌تر، پانزده دقیقهٔ اولِ سخت‌سازی قدمِ بعدیِ طبیعی است، و انجامش روی سروری که هنوز لایهٔ مستندنشدهٔ خودش را انباشته نکرده خیلی ساده‌تر است. اگر هنوز دارید انتخاب می‌کنید کجا فرود بیایید، راهنمای حوزهٔ قضایی این‌که واقعاً بینِ ایسلند، هلند، رومانی و سوئیس چه فرقی هست را پوشش می‌دهد — و می‌توانید ماشینِ مقصد را در حدودِ یک دقیقه روشن داشته باشید تا همین امروز تمرین را شروع کنید.

پاسخ‌های سریع

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

مهاجرتِ یک VPS واقعاً چقدر قطعی دارد؟
برای یک سایتِ کوچک با پایگاه‌داده‌ای که در عرضِ چند دقیقه dump می‌شود، یک گذارِ تمرین‌شده معمولاً دو تا ده دقیقه نوشتنِ متوقف‌شده است، و به‌دنبالش یک دُمِ چند‌ساعته که در طولش بعضی resolverها هنوز ترافیک را به ماشینِ قدیمی می‌فرستند. با یک replica ی پایگاه‌داده که promote شده به‌جای dump‌شدن، پنجرهٔ توقف چند ثانیه است. متغیری که غالب است پهنای‌باندِ شما نیست، این است که آیا TTLِ DNS را به‌اندازهٔ کافی از قبل پایین آورده‌اید و آیا سرورِ قدیمی را در طولِ دُم پاسخگو نگه داشته‌اید.
واقعاً باید اول TTLِ DNS را پایین بیاورم، یا می‌توانم فقط رکورد را تغییر دهم؟
می‌توانید رکورد را هر زمان تغییر دهید، اما resolverهایی که از قبل پاسخِ قدیمی را کش کرده‌اند تا پایانِ همان TTL ای که به آن‌ها داده شده به استفاده از آن ادامه می‌دهند — که روی یک رکوردِ پیش‌فرضِ یک‌روزه یعنی تا بیست‌وچهار ساعت ترافیک همچنان به ماشینِ قدیمی می‌رسد. پایین‌آوردنِ TTL فقط وقتی کمک می‌کند که دستِ‌کم یک TTLِ کاملِ قدیمی پیش از تغییر منتشر شده باشد، پس اولین اقدامِ مهاجرت است، نه آخری. اگر نمی‌توانید صبر کنید، تغییر همچنان کار می‌کند؛ فقط دُمِ کش را به‌شکلِ یک همپوشانیِ طولانی‌تر می‌پردازید، که تا وقتی میزبانِ قدیمی روشن بماند مشکلی نیست.
می‌توانم فقط کلِ فایل‌سیستمِ root را به VPS جدید rsync کنم؟
می‌توانید، و معمولاً بوت هم می‌شود، و همچنان رویکردِ اشتباهی است. به ماشینی می‌رسید که کرنل و initramfs اش از سخت‌افزارِ متفاوتی آمده، نام‌گذاریِ اینترفیسش ممکن است تطبیق نداشته باشد، /etc/machine-id اش حالا با یک سرورِ زنده مشترک است، و هر تکه drift پیکربندی‌ای که جعبهٔ قدیمی انباشته را با خودش حمل می‌کند. سیستم‌عامل را تازه از یک template نصب کنید و داده و پیکربندی‌ای را که فهرست‌برداری کرده‌اید rsync کنید. آن ساعتِ اضافه، سروری به شما می‌دهد که واقعاً می‌توانید دربارهاش استدلال کنید.
چطور یک پایگاه‌دادهٔ MySQL یا PostgreSQL را بدونِ از‌دست‌دادنِ نوشتن‌ها جابه‌جا کنم؟
دو گزینه. یک dump سازگار بگیرید — mysqldump --single-transaction برای InnoDB، یا pg_dump به‌علاوهٔ pg_dumpall --globals-only برای نقش‌ها و مجوزهایی که داخلِ هیچ پایگاه‌داده‌ای نیستند — و توقفی را بپذیرید که به‌اندازهٔ dump به‌علاوهٔ انتقال به‌علاوهٔ بازیابی به‌علاوهٔ reindex طول می‌کشد. یا روزها زودتر یک replica روی میزبانِ جدید راه بیندازید، بعد نوشتن‌ها را متوقف کنید، منتظرِ صفرشدنِ تأخیر بمانید و آن را promote کنید، که توقف را به چند ثانیه کاهش می‌دهد. هرگز یک دایرکتوریِ دادهٔ در حالِ اجرا را در سطحِ فایل کپی نکنید: نتیجه یک snapshot پاره‌شده است که ممکن است به‌نظر کار کند.
آیا باید کلیدهای میزبانِ SSH و گواهی‌های TLS ام را به سرورِ جدید کپی کنم؟
گواهی‌ها، بله — کلِ دایرکتوری را شاملِ کلیدِ حسابِ ACME کپی کنید، کلیدهای خصوصی را روی 600 نگه دارید، یا به چالشِ DNS-01 سوییچ کنید تا میزبانِ جدید پیش از این‌که DNS به‌سمتش اشاره کند بتواند صادر کند. کلیدهای میزبان یک قضاوت است: کپی‌کردنشان جابه‌جایی را برای کلاینت‌ها و اتوماسیون نامرئی می‌کند، که برای یک مهاجرتِ روتین درست است، اما اگر دارید ترک می‌کنید چون دیگر به ارائه‌دهندهٔ قدیمی اعتماد ندارید اشتباه است، چون هرکس آن دیسک را داشته کلید را هم داشته. هرکدام را که انتخاب کنید، هرگز نگذارید هر دو ماشین هم‌زمان با کلیدِ میزبانِ یکسان و نامِ میزبانِ یکسانی که به هر دو resolve می‌شود زنده باشند.
وقتی به یک آدرسِ IP جدید جابه‌جا می‌شوم، آیا ایمیلم می‌شکند؟
deliverability افت می‌کند، چون اعتبار متعلق به خودِ آدرس است، نه به شما. پیش از گذار، SPF را طوری به‌روزرسانی کنید که آدرسِ جدید را هم شامل شود و در طولِ همپوشانی هر دو را فهرست‌شده نگه دارید، کلیدِ خصوصیِ DKIM را کپی کنید تا کلیدِ عمومیِ منتشرشده همچنان معتبر بماند، رکوردِ PTR را روی آدرسِ جدید طوری تنظیم کنید که با نامِ HELO تان تطبیق داشته باشد، و پیش از فرستادنِ هر چیزی آدرس را در برابرِ فهرست‌های سیاهِ اصلی چک کنید. میزبانِ قدیمی را برای حدودِ یک هفته به‌عنوانِ یک MX با اولویتِ پایین‌تر نگه دارید تا تلاش‌های دوباره و lookupهای کش‌شده هنوز جایی فرود بیایند، و پیش از نابودکردنش صفش را خالی کنید.
ارائه‌دهندهٔ قدیمی‌ام پیش از این‌که پشتیبان بگیرم سرور را معلق کرد — آیا چیزی قابلِ‌بازیابی است؟
گاهی، و پنجره کوتاه است. تا وقتی نمونه معلق است و نه حذف‌شده، به این ترتیب امتحان کنید: دانلودِ یک اسنپ‌شات یا پشتیبان از پنل، یک بوتِ rescue یا recovery که دیسکتان را mount می‌کند، و کنسولِ اضطراری، که اغلب حتی وقتی شبکه خاموش است متصل می‌شود و برای بازیابیِ پیکربندی و کلیدها کافی است اما نه یک پایگاه‌داده. چیزی که هیچ ارائه‌دهنده‌ای که هرگز هویتی جمع‌آوری نکرده نمی‌تواند انجام دهد — از جمله ما — این است که تأیید کند شما که هستید و حساب را برگرداند، چون هرگز هویتی برای تأییدشدن وصل نبوده. به همین دلیل است که پشتیبان باید جایی غیر از خودِ سرور زندگی کند.
چه‌مدت باید سرورِ قدیمی را نگه دارم، و آیا می‌توانم بعداً بینِ حوزه‌های قضایی جابه‌جا شوم؟
آن را حدودِ یک هفته، روشن و read-only نگه دارید، تا کارهای cron هفتگی و یکپارچه‌سازی‌ای که فقط جمعه‌ها اجرا می‌شود، هرکدام دستِ‌کم یک‌بار روی میزبانِ جدید فعال شده باشند. روی کوچک‌ترین پلن این چیزی حدودِ چند دلار هزینه دارد. جابه‌جایی بینِ حوزه‌های قضایی بعداً دقیقاً به همین شکل کار می‌کند: چهار منطقهٔ ما — ایسلند، هلند، رومانی و سوئیس — همان پلن‌ها را با همان قیمت‌ها ارائه می‌دهند، پس تغییرِ حوزهٔ قضایی یک مهاجرت بینِ دو تا از سرورهای خودتان است، بدونِ قراردادی برای فسخ‌کردن و بدونِ هزینه‌ای برای پرداختن.
اعمال کنید

بارهای کاری که این راهنما برای آن‌ها اعمال می‌شود

هر کارت یک صفحه مخصوص بار کاری با توصیه‌های اندازه‌گیری و FAQ sysadmin باز می‌کند.

ادامه مطالعه

راهنماهای دیگر

مطالعه‌های همراه که از جایی که این یکی متوقف می‌شود ادامه می‌دهند.

چک‌لیست امنیتی چک‌لیست سخت‌سازی VPS: پانزده دقیقهٔ اول با یک سرور لینوکسی جدید

چک‌لیست سخت‌سازی VPS: پانزده دقیقهٔ اول با یک سرور لینوکسی جدید

هشت تغییری که واقعاً ریسک یک VPS تازه را کم می‌کنند، به ترتیب درست انجامشان — و اینکه چرا قفل‌کردن خودتان بیرون از سرور خیلی محتمل‌تر از نفوذی است که نگرانش هستید.

16 دقیقه مطالعه راهنما را بخوانید
راهنمای تحویل‌پذیری ایمیل میل سرور شخصی روی VPS: پورت 25، PTR و چرا ایمیل شما در اسپم می‌افتد

میل سرور شخصی روی VPS: پورت 25، PTR و چرا ایمیل شما در اسپم می‌افتد

نصب میل سرور شخصی دیگر سخت نیست؛ تحویل ایمیل هنوز سخت است. ترتیب بررسی گیرنده‌ها، اهمیت IP، هم‌ترازی واقعی SPF، DKIM و DMARC، و کی self-hosting اشتباه است را بشناسید.

15 دقیقه مطالعه راهنما را بخوانید
ابزار تصمیم‌گیری انتخاب حوزه قضایی: ایسلند، هلند، رومانی، سوئیس

انتخاب حوزه قضایی: ایسلند، هلند، رومانی، سوئیس

مقایسه مستقیم چهار موقعیت offshore ما بر اساس ابعادی که واقعاً اهمیت دارند — تحمل DMCA، قوانین نگهداری داده، دسترسی peering، تأخیر و قیمت.

8 دقیقه مطالعه راهنما را بخوانید
راهنمای خریدار VPS در مقابل bare-metal dedicated: چه زمانی تغییر دهید

VPS در مقابل bare-metal dedicated: چه زمانی تغییر دهید

تحلیل کاربردی از زمانی که KVM دیگر کافی نیست و bare-metal شروع به ارزش‌آفرینی می‌کند — با آستانه‌های دقیق، نه تبلیغات بازاریابی.

9 دقیقه مطالعه راهنما را بخوانید
مرجع معنی واقعی «هاستینگ بدون KYC» در ۲۰۲۶

معنی واقعی «هاستینگ بدون KYC» در ۲۰۲۶

A precise explainer on the term every privacy-focused hosting site uses — what KYC is, where it came from, what no-KYC providers do not collect, and the honest limits of the model.

8 دقیقه مطالعه راهنما را بخوانید

کافی خواندید؟ در ۶۰ ثانیه استقرار دهید

بدون تأیید ایمیل، بدون شناسه، بدون حساب. یک پلن انتخاب کنید، با هر ارز دیجیتالی پرداخت کنید، root بگیرید.