النسخ هو الجزء السهل — ما الذي يُسبِّب التوقف فعلياً
اسأل أي شخص عن المدة التي سيستغرقها ترحيله وسيقدِّر مدة النقل. مئتا غيغابايت عبر رابط بسرعة غيغابت، لنقل أربعين دقيقة، أضف ساعة للاحتياط. هذا الرقم صحيح عادةً وليس تقريباً أبداً الرقم المهم فعلاً، لأن النقل يحدث بينما لا يزال الخادم القديم يُجيب على الطلبات. لا أحد يكون معطَّلاً أثناء النسخ. الجميع يكون معطَّلاً خلال الفاصل الزمني بين أن يصبح الجهاز الجديد صحيحاً وبين أن يوافق الإنترنت على ذلك، وطول ذلك الفاصل تحدِّده ذاكرات تخزين مؤقت لا تتحكم أنت فيها.
أربعة أنماط فشل تُفسِّر معظم انقطاعات الترحيل الحقيقية، وليس عرض النطاق الترددي واحداً منها. سجل DNS كان زمن بقائه (TTL) لا يزال يوماً كاملاً حين غيَّرته، فتبقى نسبة معتبرة من العالم متصلة بجهاز أوقفته أنت بالفعل. قاعدة بيانات تلقَّت عمليات كتابة بعد أن أخذت تفريغها، فيبدأ المضيف الجديد حياته بنسخة قديمة بصمت، وتكتشف أي عشرين دقيقة مفقودة من شكوى أحد العملاء. شهادة TLS ومفتاح حساب ACME الخاص بها كانا موجودَين فقط على القرص القديم، فيُقدِّم المضيف الجديد عدم تطابق في الاسم لكل متصفح. وتكامل صادر — معالج دفع، أو نقطة إسقاط SFTP لدى بنك، أو واجهة برمجية لشريك، أو قاعدة بيانات لدى مزوِّد ثالث — كان مُدرَجاً في قائمة السماح حسب عنوان IP، فيفشل بصمت في أبعد نقطة ممكنة عن التغيير الذي تسبَّب فيه.
يستحق الأمر أن نكون صريحين بشأن العبارة التي يستخدمها الجميع. "ترحيل بلا توقف" تعني في الغالب دائماً بضع ثوانٍ من رفض الاتصالات لم يلاحظها أي إنسان، وهذه نتيجة جيدة تماماً تستحق أن تُستهدَف. أما الصفر الحقيقي فيتطلَّب أن يخدم الجهازان بشكل صحيح في الوقت نفسه، ما يتطلَّب تطبيقاً يتحمَّل أن يكون جهازَين: بلا حالة جلسة محلية، وبلا مجلد رفع محلي موجود لدى طرف واحد فقط، وقاعدة بيانات إما أنها تُنسَخ نسخاً متماثلاً أو تعيش في مكان آخر كلياً. معظم الأكداس ذاتية الاستضافة لا تستوفي هذا المعيار، والخطة الصادقة هي تجميد قصير ومضبوط وجرى التمرُّن عليه، لا مشروع بنية معمارية جديد لم تقصد الشروع فيه.
إذن شكل الترحيل الجيد ليس معقَّداً. ابنِ الجهاز الجديد باكراً وأثبِت أنه يعمل بينما لا يزال القديم يتحمَّل الحِمل. قلِّص الجزء غير القابل للتراجع إلى بضع دقائق من أوامر مكتوبة مسبقاً. غيِّر شيئاً واحداً في كل مرة. واحتفظ بالقدرة على الرجوع، مع تاريخ تتوقف فيه عن دفع ثمن تلك القدرة.
الجرد: أجزاء الخادم التي لا وجود لها في مستودعك
مستودع النشر لديك يصف التطبيق. إنه لا يصف الجهاز. في مكان ما بين أول أمر apt install واليوم، يتراكم على الخادم طبقة لم يرها نظام التحكم بالإصدارات قط: حزم ثُبِّتت يدوياً لحل مشكلة واحدة، ووحدة systemd كتبها أحدهم على عجل، ومهمة cron تحت حساب خدمة، وقواعد جدار حماية، وضبط sysctl، ولغة محلية، ومنطقة زمنية، وملف 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 الحالي لديك. بوابات دفع بقوائم سماح IP. قاعدة بيانات مُدارة لدى مزوِّد آخر تُسمِّي قواعد وصولها العنوان القديم. مُرحِّل SMTP يُصادق حسب الشبكة. خدمة مراقبة، ومُرسِل webhook لا يُرسِل إلا إلى عناوين معروفة، وجدار حماية عند زميل. ابحث بـ grep في إعداداتك وتوثيقك الخاصَين عن العنوان القديم، ثم تفقَّد لوحة تحكم كل خدمة خارجية تدفع مقابلها. هذه الأشياء تتعطَّل بعد التحويل، بشكل غير متزامن، في أي لحظة تُشغَّل فيها عملية التكامل تالياً — ولهذا كثيراً ما يُشخَّص عطلها بأنه "شيء آخر تعطَّل في الوقت نفسه".
أخيراً، التقط نطاق DNS نفسه. صدِّره، أو على الأقل سجِّل كل نوع سجل وقيمته وTTL الخاص به، لأن الترحيل هو بالضبط اللحظة التي يلاحظ فيها أحدهم سجلاً كان خاطئاً منذ عامين ويسارع مشكوراً إلى إصلاحه وسط كل شيء آخر يجري.
| ما الذي تجرده | أين يعيش | ما الذي يتعطَّل إن نسيته |
|---|---|---|
| حزم مثبَّتة يدوياً | قاعدة بيانات الحزم | تفشل خدمة في البدء على المضيف الجديد بسبب مكتبة مفقودة لا يتذكر أحد أنه أضافها. |
| وحدات ومؤقِّتات مفعَّلة | systemd | يتوقف العمل في الخلفية بصمت: لا نسخ احتياطي، ولا تجديد شهادات، ولا عامل طابور. |
| مهام cron لكل مستخدم | جداول crontab لكل حساب | تختفي المهام الليلية ولا يُلاحَظ ذلك إلا في نهاية الشهر. |
| مجموعة قواعد جدار الحماية | nftables أو ufw | إما أن يبقى منفذ مغلقاً فيبدو التطبيق معطَّلاً، أو يبقى كل شيء مفتوحاً. |
| شهادات TLS ومفتاح حساب ACME | مجلد الشهادات | تُظهر المتصفحات عدم تطابق في الاسم، وتبدأ عمليات التجديد حساباً جديداً من الصفر. |
| أدوار وصلاحيات قاعدة البيانات | متغيرات الخادم العامة، لا التفريغ | تُستعاد البيانات بلا مشكلة لكن التطبيق لا يستطيع تسجيل الدخول إليها. |
| قوائم سماح IP لدى أطراف خارجية | لوحات تحكم أشخاص آخرين | تفشل المدفوعات وwebhooks وواجهات الشركاء البرمجية بعد ساعات أو أيام. |
| نطاق DNS بقيم TTL | مزوِّد DNS الخاص بك | لا تستطيع معرفة أي السجلات لا يزال يحتاج إلى الانتقال، أو مدة تخزينها المؤقت. |
اخفض TTL في DNS أولاً — وافهم لماذا يجب أن يكون ذلك قبل أيام
يُخزِّن المحلل العودي الإجابة مؤقتاً لمدة زمن البقاء (TTL) الذي أُعطي له، وهو غير ملزَم بالسؤال مجدداً قبل أن تنتهي تلك المدة. لهذا نتيجة تُوقِع كل شخص تقريباً في المرة الأولى: خفض TTL لسجل من 86400 إلى 300 لا يُغيِّر أي شيء إطلاقاً لمحلل خزَّن الإجابة القديمة مؤقتاً قبل عشر دقائق. ذلك المحلل يحتفظ بالإجابة التي تدوم يوماً كاملاً لثلاث وعشرين ساعة وخمسين دقيقة أخرى، ولا يتعرَّف على TTL الجديد ذي الخمس دقائق إلا بعدها. لذلك يجب نشر قيمة TTL المنخفضة قبل مدة TTL القديمة الكاملة على الأقل من نيتك نقل أي شيء. إن كانت سجلاتك على TTL مدته يوم واحد، فإن أول إجراء في الترحيل يحدث قبل يومين من التحويل، وهو تغيير من سطر واحد.
افعل ذلك لكل سجل يُشير إلى الجهاز، لا فقط للسجل الذي تفكِّر فيه. سجل A وسجل AAAA — عنوان IPv6 تُرِك يُشير إلى المضيف القديم خلل مُربِك بشكل جميل، لأن عملاء dual-stack سيُفضِّلونه بصمت ولن يتأثر إلا بعض مستخدميك. سجلات MX. وأي CNAME أمامها، مع تذكُّر أن العميل الذي يتبع سلسلة يخضع لـTTL كل حلقة فيها، لذا فإن سجل A مدته خمس دقائق خلف CNAME مدته يوم كامل لا يزال فعلياً بمدة يوم. وإذا كنت ستُغيِّر مزوِّد DNS في الوقت نفسه أيضاً، فلا تفعل ذلك في الأسبوع نفسه: فتفويض خادم الأسماء وسجلات glue تُخزَّن مؤقتاً من قِبل النطاق الأصل وفق جدولها الزمني الخاص، والجمع بين التغييرَين يعني أنك حين يتعطَّل شيء لن تعرف أيهما كان السبب.
تحقَّق بدلاً من أن تفترض. dig +noall +answer example.com A يُظهر لك ما يحتفظ به المحلل حالياً والعد التنازلي المتبقي عليه؛ واستعلام خادمك المرجعي مباشرة بـdig @ns1.example.net example.com A يُظهر ما نشرته أنت فعلياً. إن اختلف الاثنان، فأنت تنظر إلى الذاكرة المؤقتة، والرقم المجاور للسجل هو بالضبط المدة التي عليك الانتظار بها.
ثمة دقيقتان تستحقان أن تُحسَبا في الحساب. بعض المحلِّلات تُقيِّد القيمة: فحصة من مُحوِّلات ISP والشركات تفرض حداً أدنى لـTTL بصرف النظر عمّا تنشره، وهذا أمر غير مستحسَن تقنياً لكنه حقيقي تماماً. وبموجب RFC 8767 يجوز لمحلل أن يُقدِّم عمداً إجابة مُتقادِمة حين يتعذَّر عليه الوصول إلى خوادمك المرجعية — سلوك ممتاز من أجل المتانة، لكنه مزعج في اليوم الذي تريد فيه أن ينتشر تغيير ما. بين الاثنَين، خطِّط لذيل طويل يُقاس بالساعات، وأحياناً بيوم كامل، بعد أن ينتقل معظم حركة المرور. الذيل ليس مشكلة طالما أن الجهاز القديم لا يزال يُجيب بشكل صحيح، وهذا هو السبب الكامل وراء إبقائه يعمل. RFC 2181 هو المرجع لكيفية تصرُّف قيم TTL المفترض حين تختلف التطبيقات.
| متى | الإجراء | لماذا حينها |
|---|---|---|
| T ناقص 7 أيام | جرد الخادم القديم؛ كتابة دفتر التشغيل | كل ما يُكتشَف هنا يُغيِّر الخطة، لذا يجب أن يحدث قبل أن تُثبَّت الخطة. |
| T ناقص 3 أيام | تجهيز VPS الجديد؛ أول استعادة؛ التمرين | يترك وقتاً لإعادة بناء الجهاز مرة ثانية حين يكتشف التمرين ثغرات. |
| T ناقص يومين | خفض TTL لسجلات A وAAAA وMX إلى 300 | يجب أن تمر مدة TTL القديمة كاملة قبل أن تصل القيمة المنخفضة إلى كل ذاكرة مؤقتة. |
| T ناقص يوم | أول تمريرة rsync؛ بدء النسخ المتماثل لقاعدة البيانات | طويلة وبلا إشراف، بينما لا يزال الخادم القديم يتحمَّل حركة مرور الإنتاج. |
| T صفر | تجميد الكتابة، مزامنة نهائية، تحقُّق، تبديل DNS | النافذة الوحيدة غير القابلة للتراجع؛ وهي قصيرة لأن كل ما سبق قد حدث بالفعل. |
| T زائد ساعة | مراقبة سجلَّي الوصول كليهما | تراجُع حركة المرور على المضيف القديم هو مقياسك الحقيقي لانتهاء صلاحية الذاكرة المؤقتة. |
| T زائد 7 أيام | إخراج المضيف القديم من الخدمة؛ إعادة رفع قيم TTL | انتهت صلاحية التراجع؛ وTTL دائم بمدة 300 ثانية يُكلِّف زمن استجابة دون أي فائدة. |
تمرَّن على الجهاز الجديد بينما لا يزال القديم يخدم
أثمن عادة في هذه العملية بأكملها هي أن يكون الجهاز الجديد موجوداً ويعمل قبل أن يهم ذلك بأيام. الـVPS هو إيجار بالساعة من الناحية العملية: على خططنا يصبح الخادم حياً خلال نحو ستين ثانية من تأكيد الدفع، بلا رسوم إعداد وبلا عقد، لذا فإن تمريناً لثلاثة أيام على شريحة بسعر 8.50$ يكلِّف نحو دولار واحد. هذه طريقة رخيصة بشكل لافت لتحويل كل مجهول في ترحيلك إلى معلوم قبل أن تبدأ الساعة بالعد.
اختبره باسم المضيف، لا بعنوان IP. تصفُّح عنوان الخادم الجديد مباشرة يمنحك المضيف الظاهري الافتراضي، وبلا تطابق SNI، وتحذير شهادة، ومجموعة مسارات قد لا تشبه الإنتاج إطلاقاً — وسيقنعك بسعادة أن شيئاً ما يعمل بينما هو لا يعمل. الأداة الصحيحة هي تجاوز عبر المحلل. curl --resolve يُثبِّت اسم مضيف واحد إلى عنوان واحد لأمر واحد فقط، لذا فإن curl --resolve example.com:443:203.0.113.10 https://example.com/ يُشغِّل الاسم الحقيقي، ومصافحة TLS الحقيقية، والمضيف الظاهري الحقيقي مقابل الجهاز الجديد بينما لا يزال بقية العالم يصل إلى القديم. للاختبار التفاعلي، سطر واحد في ملف hosts الخاص بمحطة عملك يؤدي المهمة نفسها للمتصفح.
ما يكتشفه التمرين بموثوقية هو الطبقة غير الموثَّقة المتراكمة من القسم السابق. خدمة (daemon) ظلت تعمل منذ ما قبل آخر إعادة تشغيل وهي في الواقع غير مُفعَّلة. مهمة cron تعتمد على ناقل بريد محلي للإبلاغ عن الأعطال. ملكية ملفات نجت من النسخ كأرقام لكنها تعني شيئاً مختلفاً على جهاز له /etc/passwd مختلف. عنوان مكتوب بشكل ثابت داخل ملف إعداد. قاعدة بيانات أُنشئت بترميز أحرف واحد على إصدار كان افتراضيه مختلفاً. إصدار فرعي من Python أو PHP أهمل شيئاً تستخدمه. كل واحدة من هذه تكلِّف عشر دقائق لإصلاحها أثناء التمرين وساعة كاملة لتشخيصها أثناء التحويل.
اختبار واحد يستحق أكثر من البقية: ابنِ الجهاز الجديد مرتَين. أعِد بناءه من الصفر معتمداً فقط على جردك ونسختك الاحتياطية، دون النظر إلى الخادم القديم. إن ظهر صحيحاً في المرة الثانية، فجردك حقيقي ودفتر تشغيلك قابل للتنفيذ. وإن لم يظهر كذلك، فقد وجدت للتو الثغرة في موقف لا يكلِّفك فيه اكتشافها شيئاً. خذ لقطة بمجرد أن يصبح صحيحاً — اللقطات كل ساعة بفترة احتفاظ سبعة أيام مُدرَجة في كل خطة، والاستعادة تستغرق نحو ثلاثين ثانية — بحيث تصبح أي تجربة لاحقة على الجهاز الجديد قابلة للتراجع هي الأخرى.
rsync مرتَين: تمريرة طويلة أثناء التشغيل، وأخرى قصيرة داخل النافذة
نمط التمريرتين هو ما يُبقي نافذة الصيانة قصيرة. تعمل التمريرة الأولى والخدمة حية بالكامل ويمكنها أن تستغرق ما تستغرقه — ساعات، طوال الليل، عبر عطلة نهاية أسبوع كاملة. تعمل التمريرة الثانية أثناء التجميد وتنقل فقط ما تغيَّر منذ الأولى، وهو على حِمل عمل عادي جزء صغير من البيانات وعدد دقائق يمكن التنبؤ به. أنت تستبدل نسخاً طويلاً بلا إشراف بنسخ قصير تحت إشراف، وهذه الصفقة تستحق العناء دائماً تقريباً.
الخيارات (flags) أهم مما يتوقع الناس. rsync -aHAX --numeric-ids هو خط الأساس: -a لوضع الأرشفة، و-H للحفاظ على الروابط الصلبة (hardlinks) — وهذا مهم جداً لمخازن Maildir ولأشجار النسخ الاحتياطي منزوعة التكرار، حيث يمكن لإسقاطها أن يُضاعِف استخدام قرصك — و-A لقوائم POSIX ACL، و-X للسمات الموسَّعة مثل تصنيفات SELinux وقدرات الملفات، و--numeric-ids بحيث يُنسَخ معرِّف المستخدم كرقم بدلاً من حله عبر قاعدة بيانات مستخدمي المصدر وإعادة حله عبر قاعدة مختلفة في الوجهة. أضف --info=progress2 للحصول على سطر تقدُّم واحد معقول، و--partial بحيث يستأنف النقل المنقطع بدلاً من إعادة البدء. اترك -z بلا تفعيل ما لم يكن الرابط بطيئاً فعلاً: فضغط وسائط مضغوطة أصلاً وأرشيفات مشفَّرة لا يفعل شيئاً سوى نقل عنق الزجاجة إلى المعالج.
استخدم --delete في التمريرة الثانية فقط. في التمريرة الأولى، هو رصاصة في قدمك بلا أي فائدة، لأنه لا يوجد على الوجهة شيء يحتاج إلى إزالة. في التمريرة الثانية هو ضروري: فبدونه، يبقى أي ملف حذفته على الخادم القديم بين التمريرتين حياً إلى الأبد على الجديد، وهكذا ينتهي الترحيل بخدمة محتوى أُزيل عمداً.
ما يجب ألا تفعله هو تنفيذ rsync لنظام الملفات الجذري بأكمله. إنه اختصار شائع وينتج عنه جهاز لا يستطيع أحد أن يفهم منطقه. حتى مع استثناء /proc و/sys و/dev و/run و/tmp، تنتهي بنظام جاء kernel وinitramfs الخاصان به من مضيف واحد، واشتُقت تسمية واجهة شبكته من عتاد مختلف، وأصبح /etc/machine-id الخاص به مُكرَّراً الآن عبر جهازَين حيَّين، وحافظت للتو مقابل ثمن دفعته على خمس سنوات متراكمة من انحراف الإعداد. رحِّل البيانات والإعداد اللذين جردتهما؛ ثبِّت نظام التشغيل من جديد من قالب. يستغرق ذلك ساعة إضافية، ويمنحك قاعدة حديثة نظيفة، ويعني أن الخادم الجديد جهاز تفهمه أنت بدلاً من أن يكون نسخة عن جهاز لم تفهمه.
تحقَّق من النسخ بدلاً من الثقة برمز الخروج. بعد التمريرتين كلتيهما، شغِّل الأمر نفسه مجدداً مع -n --checksum --itemize-changes: تشغيل تجريبي يقارن المحتوى بدلاً من الطوابع الزمنية ويطبع سطراً واحداً لكل اختلاف. الصمت هو النتيجة التي تريدها، وهي أقوى بكثير من مجرد تطابق du -s على الجانبَين.
قاعدة البيانات هي الجزء الذي لا يستطيع rsync مساعدتك فيه
نسخ مجلد قاعدة بيانات حية على مستوى الملفات يمنحك نسخة ممزَّقة: بعض الصفحات مكتوبة وبعضها ليس كذلك، ولا ضمان بأن أياً منها يُشكِّل حداً متسقاً للمعاملات. قد يتعافى InnoDB منها ويبدو سليماً، وهذا أسوأ من الفشل، لأنك لن تكتشف ذلك إلا في اليوم الذي لا ينجح فيه التعافي. هناك استراتيجيتان صادقتان بالضبط — أخذ تفريغ متسق معاملاتياً، أو النسخ المتماثل — والاختيار بينهما هو اختيار مقدار التوقف الذي تشتريه.
لمسار التفريغ على MySQL وMariaDB، يمنحك mysqldump --single-transaction --routines --triggers --events لقطة متسقة دون قفل الخادم بأكمله، مع تحذيرَين يستحقان المعرفة: فهو متسق فقط للجداول المعاملاتية، لذا فإن جدول MyISAM قديماً واحداً يكسر الضمان بصمت، وأي عبارة DDL تُنفَّذ أثناء التفريغ تكسره أيضاً. على PostgreSQL، يتولى pg_dump -Fc كل قاعدة بيانات على حدة، ويتولى pg_dumpall --globals-only النصف الذي ينساه الناس — الأدوار وكلمات المرور والصلاحيات ومساحات الجداول تعيش على مستوى العنقود، لا داخل أي قاعدة بيانات منفردة، لذا فإن الاستعادة بدونها تُنتج بيانات مثالية لا يستطيع التطبيق المصادقة للدخول إليها.
الرقم الذي يحدِّد نافذتك ليس حجم التفريغ، بل التفريغ زائد النقل زائد الاستعادة زائد إعادة بناء الفهارس، وآخر هذه العناصر عادةً هو الأكبر. قِسه أثناء التمرين على مجموعة البيانات الحقيقية بدلاً من تقديره. بضعة غيغابايتات تعني دقائق؛ ومئة غيغابايت مع فهرسة كبيرة يمكن أن تعني ساعات، وعندها يتوقف مسار التفريغ عن أن يكون قابلاً للتطبيق لخدمة حية، ويصبح النسخ المتماثل هو الإجابة لا مجرد تحسين.
مسار النسخ المتماثل يعكس التكلفة: تؤدي العمل مقدَّماً فيصبح التحويل تافهاً. أعِدَّ نسخة تابعة على المضيف الجديد قبل أيام — نسخ متماثل قائم على GTID لـMySQL وMariaDB، أو pg_basebackup ونسخة احتياطية متدفقة (streaming standby) لـPostgreSQL، أو النسخ المتماثل المنطقي حين تكون أيضاً بصدد عبور إصدار رئيسي. دعها تلحق بالركب وتبقى لاحقة به. عندها يصبح التحويل: أوقف الكتابة على النسخة الرئيسية، انتظر حتى تُبلِّغ النسخة التابعة عن تأخر صفري، رقِّها، ووجِّه التطبيق إليها. هذا يستغرق ثوانٍ، وهو النهج الوحيد الذي يستحق بصدق عبارة توقف شبه معدوم.
لا تنسَ الحالة التي ليست في قاعدة البيانات. تحتفظ Redis وValkey وMemcached بالجلسات وعدادات تحديد المعدَّل والطوابير؛ ويحتفظ فهرس بحث في Elasticsearch أو OpenSearch أو Meilisearch بنسخة مشتقة من بياناتك. لكل واحدة منها، قرِّر صراحةً إن كنت ستُرحِّلها أو تعيد بناءها. نسخة Redis تحمل جلسات تستحق النقل بـBGSAVE ونسخة من الملف الناتج، ما لم تكن راضياً بتسجيل خروج الجميع. فهرس البحث يكاد يكون دائماً أسرع في إعادة فهرسته على المضيف الجديد من نقله — لكن إعادة الفهرسة تستغرق وقتاً، لذا ابدأها أثناء التمرين لا أثناء التجميد.
| الاستراتيجية | توقف التحويل | العمل قبل النافذة | متى تكون الخيار الصحيح |
|---|---|---|---|
| نسخ ملفات لمجلد بيانات قيد التشغيل | لا شيء، وقد تكون البيانات تالفة | لا شيء | أبداً. مُدرَج هنا لأنه أول شيء يجربه الناس. |
| تفريغ متسق واستعادة | التفريغ زائد النقل زائد الاستعادة زائد إعادة الفهرسة | قِسه مرة واحدة أثناء التمرين | مجموعات بيانات صغيرة بما يكفي ليلائم الإجمالي المقيس نافذتك المحتملة. |
| تفريغ، ثم استعادة، ثم إعادة تشغيل الفرق (delta) | دقائق | استبقاء binlog أو WAL مُعدّ مسبقاً | مجموعات بيانات متوسطة الحجم حيث تكون نسخة تابعة كاملة إعداداً أكبر مما تريد. |
| ترقية نسخة تابعة عند التحويل | ثوانٍ | نسخ متماثل يعمل وبلا تأخر لأيام | أي شيء كبير، وأي شيء يكون فيه التجميد الطويل غير مقبول. |
| أوقف قاعدة البيانات، وانسخ الملفات وهي متوقفة | مدة النسخ | لا شيء | خدمات داخلية صغيرة حيث ساعة واحدة دون اتصال لا تُكلِّف فعلياً أي شيء. |
شهادات TLS ومفاتيح مضيف SSH والهويات التي لا يمكنك ببساطة إعادة إصدارها
إصدار الشهادات لديه مشكلة الدجاجة والبيضة في أسوأ لحظة ممكنة بالضبط. يُثبِت تحدي HTTP-01 التحكم بالاسم عبر جلب ملف من خلاله، وهذا يتطلَّب أن يكون الاسم مُحلَّلاً بالفعل إلى الجهاز الجاري التحقق منه — وقبل التحويل، هو ليس كذلك. هناك ثلاثة مخارج وعليك اختيار أحدها عن قصد. انسخ مجلد الشهادات كاملاً، وهذا يعمل فوراً ومشروع تماماً لأنه مفتاحك أنت. أو استخدم تحدي DNS-01 بدلاً من ذلك، الذي يتحقَّق عبر نشر سجل TXT وبالتالي يعمل على جهاز لا يُشير إليه شيء بعد، وهو الخيار الوحيد لشهادة wildcard على أي حال. أو اقبل نافذة قصيرة بعد تبديل DNS يطلب خلالها المضيف الجديد شهادته الخاصة، وهذا مقبول لموقع شخصي وغير مقبول لأي شيء له مستخدمون.
إن نسخت، انسخ كل شيء. الشهادات والمفاتيح الخاصة هي الجزء الواضح؛ أما مفتاح حساب ACME فهو الجزء الذي يُترَك خلفك، وبدونه يُسجِّل العميل على المضيف الجديد حساباً جديداً تماماً عند أول تجديد. يبدو كل شيء وكأنه يعمل، وتكون قد فقدت بصمت تاريخ الحساب وأي حالة مرتبطة به. حافظ على الملكية والصلاحيات أيضاً — المفاتيح الخاصة بصلاحية 600، ومجلد الأرشيف بصلاحية 700 — لأن نسخة تُوسِّع صلاحيات مفتاح هي نتيجة أسوأ من الترحيل الذي كنت قلقاً بشأنه.
لا تخطط لإعادة الإصدار مراراً لترى ما سيحدث. تضع حدود معدَّل Let's Encrypt سقفاً للشهادات المكرَّرة لمجموعة متطابقة من أسماء المضيفين في كل أسبوع، وتمرينان فاشلان زائد إصدار حقيقي طريقة سهلة بشكل مفاجئ للوصول إلى ذلك السقف في اليوم الوحيد الذي لا يمكنك تحمُّل الانتظار فيه. وجِّه التمارين نحو بيئة الاختبار؛ واحتفظ بنقطة نهاية الإنتاج للمرة الحقيقية.
مفاتيح مضيف SSH هي الهوية الأخرى المعنية هنا، والإجابة الصحيحة تعتمد فعلياً على سبب انتقالك. نسخ /etc/ssh/ssh_host_* يجعل الترحيل غير مرئي: يبقى known_hosts الخاص بكل عميل مطابقاً، ولا تتوقف أي أتمتة عند تحذير بصمة. هذا مريح، وهو الخيار الصحيح لانتقال روتيني بين مزوِّدين تثق بهما. إنه الخيار الخاطئ إن كان سبب رحيلك هو أنك لم تعد تثق بالمضيف القديم أو المزوِّد القديم — فأي شخص لديه وصول إلى ذلك القرص كان لديه مفتاح مضيفك الخاص، ونقله إلى الخادم الجديد ينقل المشكلة معه. في تلك الحالة، وَلِّد مفاتيح جديدة، وانشر البصمة الجديدة عبر قناة ليست الخادم نفسه، واجعل العملاء يُشغِّلون ssh-keygen -R ضد الإدخال القديم. راجع دليل OpenSSH sshd لمعرفة أين تعيش المفاتيح وكيف يجري اختيارها.
قاعدة واحدة مطلقة في كل الحالات: لا تُشغِّل الجهازَين في وقت واحد بنفس مفتاح المضيف ونفس اسم المضيف مُحلَّلاً إلى كليهما معاً. هذا إعداد لا يستطيع فيه العميل معرفة أي خادم وصل إليه، وهذه بالضبط الخاصية التي وُجدت مفاتيح المضيف لمنعها. أثناء نافذة التداخل، إما أن يحتفظ المضيف القديم بهويته ويكون للجديد هويته الخاصة، أو يُتقاعَد اسم المضيف القديم في اللحظة التي يتبنَّى فيها الجديد مفتاحه.
التحويل: الدقائق العشر التي تحتاج ترتيباً مكتوباً
كل ما سبق كان قابلاً للتراجع وغير مستعجَل. التحويل ليس كذلك على الإطلاق، وهذا هو الحجة الكاملة وراء كتابته مسبقاً: الارتجال تحت ضغط الوقت هو ما يُحوِّل نافذة خمس دقائق إلى حادثة تستغرق ساعتين. يجب أن يكون دفتر التشغيل أوامر حرفية بالترتيب، مع الناتج المتوقَّع بجانب كل واحد منها، بحيث يتطلَّب تنفيذه القراءة لا التفكير.
الترتيب الذي ينجح. أولاً، أوقف الكتابة على المضيف القديم — صفحة صيانة، أو وضع للقراءة فقط، أو ببساطة أوقف التطبيق بينما لا يزال خادم الويب يُجيب بصفحة انتظار. ثانياً، شغِّل تمريرة rsync النهائية مع --delete. ثالثاً، أنهِ خطوة قاعدة البيانات: إما تسلسل التفريغ-النقل-الاستعادة الذي قِسته، أو أوقف الكتابة على النسخة الرئيسية، وتأكَّد من تأخر نسخ متماثل صفري، ورقِّ النسخة التابعة. رابعاً، شغِّل الخدمات على المضيف الجديد وامنحها لحظة لتستقر — فمجمعات الاتصالات وعمال الطوابير وتحميل الشهادات كلها تستغرق وقتاً أطول عند بدء بارد مما تتذكر. خامساً، تحقَّق. سادساً، وفقط بعد أن يجتاز التحقُّق، غيِّر سجلات DNS. سابعاً، اترك المضيف القديم يعمل.
يجب أن يعني التحقُّق شيئاً فعلياً. جلب الصفحة الرئيسية يُثبِت أن خادم الويب يعمل ولا شيء آخر. استخدم curl --resolve مقابل اسم المضيف الحقيقي على مسار يلامس قاعدة البيانات ويُعيد شيئاً يمكنك التأكيد عليه — نقطة نهاية لفحص الصحة تتحقَّق من الاتصال بقاعدة البيانات، والاتصال بذاكرة التخزين المؤقت، والمساحة الحرة على القرص تستحق أن تُكتَب لهذا السبب وحده. ثم اقرأ سجل وصول المضيف الجديد وتأكَّد من وجود طلبك فيه. تبدو هذه الخطوة الأخيرة متحذلقة وهي الخطوة التي تكشف الحالة التي لم يسرِ فيها تجاوز المحلل لديك، وقد تحقَّقت للتو بعناية من الخادم القديم.
بعد تبديل DNS، راقب سجلَّي الوصول جنباً إلى جنب. حركة المرور على المضيف الجديد ترتفع؛ وحركة المرور على المضيف القديم تتراجع مع انتهاء صلاحية الذاكرات المؤقتة، ومنحنى ذلك التراجع هو المقياس الصادق الوحيد لطول الذيل فعلياً. حين يستوي سجل المضيف القديم قرب الصفر، يكون الترحيل قد انتهى. وحتى يحدث ذلك، يجب أن يستمر الجهاز القديم في التصرف بشكل صحيح للمستخدمين الذين لا يزالون يصلون إليه — ولهذا يبقى مُشغَّلاً وفي وضع القراءة فقط بدلاً من أن يُطفَأ في لحظة حماس. إن تعذَّر جعل التطبيق للقراءة فقط، فإن تقديم المضيف القديم بيانات مُتقادِمة لبضع ساعات عادةً ضرر أصغر من تقديمه رفضاً للاتصال، لكن ذلك حكم يجب اتخاذه مسبقاً لا في حينه.
غيِّر شيئاً واحداً. ليس إصدار نظام التشغيل الرئيسي والمضيف معاً. وليس مزوِّد DNS والسجلات معاً. وليس إصدار PHP والجهاز معاً. كل تغيير متزامن يُضاعِف الفرضيات التي سيتعيَّن عليك اختبارها حين يُسيء شيء ما التصرُّف في الثالثة صباحاً، والترقية التي أُغريت بدمجها ستبقى موجودة الأسبوع المقبل، على جهاز يمكنك الآن التراجع إليه.
البريد وrDNS والسمعة التي لا ترافقك
إن كان الخادم يُرسِل بريداً، فإن للترحيل نصفاً ثانياً لا علاقة له بالترحيل نفسه. عنوان IP يحمل سمعة إرسال، وتلك السمعة تُبنى على مدى أسابيع، ولا تأتي معك. هذه هي الطريقة الأكثر شيوعاً على الإطلاق التي ينتج بها ترحيل سليم تقنياً أسبوعاً من شكاوى المستخدمين، وكل إجراءات التخفيف يجب أن تبدأ قبل التحويل لا بعده.
السجل الذي يتعطَّل أولاً هو SPF. سياسة تحتوي على آلية ip4: تُسمِّي العنوان القديم تبدأ بالفشل لحظة إرسالك من العنوان الجديد، ولأن سياسات RFC 7208 هي سجلات DNS فلها TTL خاص بها يجب التخطيط حوله. أضف العنوان الجديد إلى SPF قبل التحويل، وأبقِ الاثنَين مُدرَجَين أثناء التداخل، وأزِل القديم حين تُخرِج الخادم من الخدمة. ينتقل DKIM بلا مشكلة طالما نسخت المفتاح الخاص مع بقية الإعداد، لأن النصف العام منشور بالفعل. لا يحتاج DMARC إلى أي تغيير، لكن يستحق التأكد من أن عنوان الإبلاغ لا يزال موجوداً على جهاز على وشك أن يُدمَّر.
الـDNS العكسي ليس اختيارياً لمضيف يُرسِل بريداً. يجب أن يوجد سجل PTR على العنوان الجديد ويجب أن يطابق الاسم الذي يُعلِنه الخادم في HELO أو EHLO الخاص به، وإلا رفضت حصة كبيرة من المستقبِلين لهذا السبب وحده. على خططنا، PTR قابل للتعديل من اللوحة، فهو خانة تُحدَّد لا تذكرة دعم — اضبطه أثناء التمرين، وتحقَّق من أنه يُحلَّل، وتأكَّد من أن السجل الأمامي يطابقه رجوعاً. ثم تحقَّق من العنوان الجديد مقابل قوائم الحظر الرئيسية قبل أن تُرسِل أي شيء إطلاقاً: العناوين المُعاد تدويرها تصل أحياناً وهي مُدرَجة بالفعل في القوائم، ومعرفة ذلك من رسالة اختبار خاصة بك لا تكلِّف شيئاً بينما معرفتها من عميل تكلِّف الكثير. Spamhaus هي الأهم من بينها جميعاً.
للاستقبال، أبقِ المضيفَين كليهما قابلَين للوصول. أضف الخادم الجديد كسجل MX بأولوية 10 واترك القديم بأولوية 20 لمدة أسبوع بدلاً من حذفه: فالمرسِلون يُعيدون المحاولة، وبعضهم خزَّن سجل MX الخاص بك مؤقتاً، وخادم بريد يقبل بصمت على المضيف القديم أفضل بكثير من ارتداد. ثم، قبل أن تُدمِّر الجهاز القديم، فرِّغ طابوره واستنزِفه — postqueue -f لإجبار محاولة تسليم وmailq للتأكُّد من أن النتيجة فارغة. الرسائل الجالسة في طابور على خادم توشك على حذفه ليست مؤجَّلة. إنها ذاهبة إلى الأبد. يغطي دليل خادم البريد ذاتي الاستضافة جانب قابلية التسليم بالكامل.
حين يكون المزوِّد القديم قد أوقف الجهاز بالفعل
ليس كل ترحيل مخطَّطاً له. تعليق بعد شكوى إساءة استخدام، أو بطاقة انتهت صلاحيتها، أو حساب مُقفَل لسبب لن يشرحه أحد — القاسم المشترك هو أنك الآن تُرحِّل من جهاز لا تستطيع تسجيل الدخول إليه، وترتيب العمليات المريح أعلاه لم يعد ينطبق. يستحق الأمر أن تعرف مسبقاً ما الذي يبقى ممكناً عادةً، لأن النافذة التي يكون فيها ذلك ممكناً غالباً ما تكون قصيرة.
بينما تكون النسخة مُعلَّقة ولم تُحذَف بعد، غالباً ما تبقى ثلاثة مسارات، بترتيب تنازلي حسب الفائدة. قد تظل لوحة التحكم تعرض تنزيل لقطة أو نسخة احتياطية، وهذا يحل المشكلة كاملة في خطوة واحدة. وقد لا يزال وضع الإنقاذ أو الاستعادة يُقلِع بصورة حية مع قرصك مُرفَقاً بها، فتسمح لك بتركيب نظام الملفات ونسخ ما يهم عبر الشبكة. وقد تظل طرفية الطوارئ تتصل حتى مع تعطيل الشبكة، وهذا يكفي لقراءة ملفات الإعداد، أو استرداد مفتاح، أو تدوين ما كان مثبَّتاً — لكنها ليست مساراً لقاعدة بيانات، فلا تخطط بالاعتماد عليها. جرِّبها بهذا الترتيب، وجرِّبها فوراً: فالاستبقاء بعد التعليق سياسة، لا حق مضمون، وغالباً ما يُقاس بالأيام.
هناك حد لا تحله أي تذكرة دعم، ويستحق أن يُذكَر بصراحة لأنه نتيجة مباشرة للنموذج الذي يبيعه هذا الموقع. على مضيف لم يجمع هوية قط — بما في ذلك هذا الموقع — لا توجد طريقة لإثبات أنك صاحب الحساب سوى حيازة بيانات اعتماد الحساب نفسها. هذا هو جوهر الاستضافة بدون KYC وهو أيضاً ثمنها: لا يستطيع أحد استعادة وصولك بناءً على صورة جواز سفر، لأنه لم يُرفَق جواز سفر بأي شيء قط. يغطي دليل الاستضافة بدون KYC هذه المقايضة بالكامل؛ والنتيجة التشغيلية ببساطة هي أن خطة الاسترداد لديك لا يمكن أن تمر عبر حسن نية أي شخص آخر.
التسلسل الطارئ هو التسلسل المخطَّط له نفسه بعد إزالة التداخل. أقِم المضيف الجديد من نسختك الاحتياطية الموجودة خارج الجهاز. تحقَّق منه بشكل صحيح باسم المضيف، لأن إغراء تخطي التحقُّق يكون في أشد قوته بالضبط حين تكون معطَّلاً بالفعل. ثم انقل DNS فوراً — لا يزال انضباط TTL ينطبق، إلا أنك الآن تدفع ذيل الذاكرة المؤقتة كانقطاع بدلاً من إنفاقه كتداخل، وهذه هي الحجة الأوضح على الإطلاق لإبقاء قيم TTL متواضعة كسياسة دائمة لا كخطوة ترحيل. توقَّع بريداً بجودة متدنية لفترة، وحذِّر الناس مبكراً بدلاً من أن تشرح لاحقاً.
الدرس يتجاوز هذا اليوم السيئ الواحد. النسخة الاحتياطية التي تعيش على الخادم نفسه ليست نسخة احتياطية؛ إنها نسخة ثانية من الشيء الذي أنت على وشك خسارته. الخاصية المهمة هي أن تكون النسخة في مكان آخر، ومشفَّرة قبل أن تغادر، وبوضع الإلحاق فقط بحيث لا يستطيع مضيف مخترَق أو مُعلَّق حذف تاريخه الخاص، و— الجزء الذي يتخطاه الجميع — أن تكون قد استُعيدت فعلياً مرة واحدة، إلى نسخة يمكن التخلص منها، لتعرف أن الاستعادة تعمل فعلاً. يغطي دليل التحصين إعداد ذلك على جهاز جديد؛ وإن كنت تقرأ هذا القسم لأن الوقت قد فات بالفعل، فأعِدَّ ذلك على الجهاز الذي تُرحِّل إليه، اليوم، قبل أي شيء آخر.
التراجع: حدِّد المُحفِّز وامنحه تاريخ انتهاء صلاحية
يقول الجميع تقريباً إن لديهم خطة تراجع، ولا أحد تقريباً كتب ما الذي سيُحفِّزها. بلا مُحفِّز، يُتَّخذ القرار في أسوأ لحظة من قِبل أكثر شخص إرهاقاً، والنتيجة المعتادة هي ألا يتراجع أحد لأن الشعور دائماً هو أن المشكلة الحالية على بُعد خمس دقائق من الحل. قرِّر مسبقاً: معدَّل خطأ أعلى من عتبة معينة لمدة معينة، أو وظيفة محدَّدة معطَّلة، أو ببساطة وقت محدَّد على الساعة تتوقف بعده عن التصحيح وترجع.
القيد الذي يحدِّد معنى التراجع أصلاً هو الكتابة. منذ اللحظة التي يقبل فيها المضيف الجديد أول عملية كتابة له، يعني الرجوع إما تجاهل تلك الكتابات أو إعادة تشغيلها على الجهاز القديم. فأنت في الحقيقة تختار بين منتجَين مختلفَين. التراجع الذي يُتَّخذ قبل أول كتابة هو مجرد تغيير DNS ويستغرق دقائق. أما التراجع الذي يُتَّخذ بعد يوم من حركة مرور الإنتاج فهو ترحيل بالاتجاه المعاكس، بكل الخطوات نفسها، ويستغرق بقدر ما يصفه هذا الدليل. اعرف أيهما لديك في أي لحظة، ولاحظ أن النوع الثاني أسهل بكثير إن أبقيت قاعدة بيانات الجهاز القديم قادرة على تلقي استعادة بدلاً من إعادة توظيف الجهاز لغرض آخر.
احتفظ بالخادم القديم لنحو أسبوع: مُشغَّلاً، وفي وضع القراءة فقط، وTTL في DNS لا يزال منخفضاً، والمراقبة لا تزال موجَّهة إليه. على أصغر خطة، يُكلِّف ذلك التأمين نحو دولارَين، وهذا ليس رقماً ينبغي أن يكون له دور في القرار. ما ينبغي أن يكون له دور هو أن أسبوعاً مدة كافية لمهام cron الأسبوعية، والتقارير شبه الشهرية، والتكامل الذي لا يعمل إلا يوم الجمعة، لتعمل جميعها مرة واحدة على الأقل على المضيف الجديد — هذه هي الأعطال التي تُفوِّتها نافذة يومَين كلياً.
ثم أخرِج الخادم من الخدمة عن قصد. تأكَّد من أن سجل وصول المضيف القديم كان مستوياً ليوم كامل. خذ نسخة احتياطية أخيرة منه واحتفظ بها لمدة أطول مما تظن أنك تحتاج. ألغِ كل ما كان يحمله: مفاتيح API، ومفاتيح النشر، ومستخدمي قاعدة البيانات، وإدخالاته في قوائم سماح IP لدى آخرين، وفحوصات مراقبته، وإدخاله في SPF، وسجل MX الخاص به. دمِّر النسخة. وأخيراً أعِد قيم TTL في DNS إلى شيء معقول — TTL دائم بمدة 300 ثانية يعني أن المحلِّلات تُعيد التحقُّق عشرين مرة في الساعة لبقية عمر الموقع، وهذا لا يمنحك شيئاً بعد انتهاء الترحيل ويُكلِّف قليلاً من زمن الاستجابة في كل بحث بارد. ساعة واحدة قيمة دائمة معقولة؛ ويوم كامل مناسب للسجلات التي لا تتوقع أبداً أن تتغيَّر بسرعة.
الترحيل، بالترتيب الذي تُنفِّذه به
قبل أسبوع، جرد الجهاز القديم واكتب دفتر التشغيل: الحزم، والوحدات المفعَّلة، وجداول crontab، وجدار الحماية، والمقابس المستمعة، وأدوار قاعدة البيانات، وكل طرف ثالث أدرج العنوان القديم في قائمة سماحه. قبل ثلاثة أيام، جهِّز VPS الجديد، واستعِد البيانات عليه، وتمرَّن على كل شيء باسم المضيف مع تجاوز للمحلل — ثم أعِد بناءه مرة واحدة من الجرد وحده لإثبات أن الجرد حقيقي. قبل يومين، اخفض TTL لسجلات A وAAAA وMX إلى 300 بحيث تمر مدة TTL القديمة كاملة قبل أن تحتاجها منخفضة.
قبل يوم واحد، شغِّل تمريرة rsync الأولى مع -aHAX --numeric-ids بينما يستمر الإنتاج، وشغِّل النسخ المتماثل لقاعدة البيانات أو قِس نافذة التفريغ على مجموعة البيانات الحقيقية. رتِّب أمر الشهادات في التمريرة نفسها — انسخ مجلد الشهادات متضمناً مفتاح حساب ACME، أو انتقل إلى DNS-01 — واضبط سجل PTR وإدخال SPF الجديد على العنوان الجديد قبل أن يُرسِل أي شيء بريداً منه.
عند النافذة: جمِّد الكتابة، ونفِّذ rsync نهائية مع --delete، وأنهِ قاعدة البيانات، وشغِّل الخدمات، وتحقَّق مقابل اسم المضيف الحقيقي على مسار يلامس قاعدة البيانات، وتأكَّد من وصول الطلب إلى سجل المضيف الجديد، وعندها فقط بدِّل DNS. اترك المضيف القديم مُشغَّلاً وفي وضع القراءة فقط. راقب سجلَّي الوصول كليهما حتى يستوي القديم.
بعد أسبوع: تأكَّد من أن المهام الأسبوعية عملت على المضيف الجديد، وخذ نسخة احتياطية أخيرة من القديم، وألغِ مفاتيحه وإدخالاته في قوائم السماح في كل مكان، ودمِّره، وأعِد رفع قيم TTL. إن أردت أن يكون الجهاز الجديد أفضل من الذي تركته لا مجرد أحدث منه، فإن الدقائق الخمس عشرة الأولى من التحصين هي الخطوة الطبيعية التالية، وتنفيذها أسهل بكثير على خادم لم يتراكم عليه بعد طبقته الخاصة غير الموثَّقة. وإن كنت لا تزال تختار أين تحطّ رحالك، فإن دليل اختيار الولاية القضائية يغطي ما يختلف فعلياً بين آيسلندا وهولندا ورومانيا وسويسرا — ويمكنك تشغيل الجهاز الهدف خلال نحو دقيقة لتبدأ التمرين اليوم.