آموزش شبکه

فرایند به‌روزرسانی Stack Overflow از ویندوز سرور 2012 چگونه انجام شد؟

وب‌سایت پرطرفدار استک‌ اورفلو (Stack Overflow) که منبع آموزشی و جامعه‌ای مهم برای برنامه‌نویس‌ها محسوب می‌شود، سال گذشته به‌روزرسانی جامعی در سمت سرور تجربه کرد.

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

تیم فنی استک اورفلو سال گذشته تصمیم گرفت تا زیرساخت نرم‌افزاری سمت سرور خود را از ویندوز سرور ۲۰۱۲ به ویندوز سرور ۲۰۱۹ ارتقا دهد؛ فرایندی که دشواری‌های خاص خود را داشت و حتی تلاش شبانه‌روزی اعضای گروه را طلب می‌کرد. با وجود تمام مشکلات، بالاخره فرایند مهاجرت پایان یافت. تارین پرات، مدیر دیتابیس استک اورفلو، در پستی وبلاگی به شرح فرایند مهاجرت به ویندوز سرور ۲۰۱۹ پرداخته است که در ادامه‌ی این مطلب زومیت، چگونگی روند جابه‌جایی را از زبان او می‌خوانیم. شایان ذکر است در مقاله‌ی پیش‌رو شاهد اصطلاحات و تعاریف تخصصی شبکه و سرور خواهیم بود که شاید برای کاربر عادی جذاب نباشد.

ما سال گذشته زیرساخت دیتابیس خود را به SQL Server 2017 تغییر دادیم، اما تغییری در سیستم‌عامل سرور یا سرورهای محصول اصلی اعمال نکردیم. سیستم‌عامل اصلی، ویندوز سرور ۲۰۱۲ بود. البته ما حتی از نسخه‌ی R2 نیز استفاده نمی‌کردیم. ما می‌دانستیم که تغییر سیستم‌عامل فرایندی بسیار دشوار خواهد بود؛ فرایندی که به تغییر ساختاری کلاسترها نیاز داشت و درنتیجه زمان اکار (غیرفعال بودن سرور) را افزایش می‌داد

من در زمانی‌که پروژه‌‌های سال ۲۰۱۹ شرکت را برنامه‌ریزی می‌کردم، تغییر سیستم‌عامل از نسخه‌ی ۲۰۱۲ به ۲۰۱۹ را در اولویت بالای فهرستم قرار دادم. این کار باید واقعا انجام می‌شد، ما در سال ۲۰۱۹ هستیم و دیگر زمان گذر از سیستم‌عامل هفت ساله فرا رسیده بود. از همان ابتدا می‌دانستیم که فرایند پیچیده‌ای را در پیش خواهیم داشت. به‌ هر حال اجرای پروژه از هر لحاظ منطقی به‌نظر می‌رسید. ما با شروع مهاجرت به ویندوز سرور ۲۰۱۹، پروژه‌ای پیچیده و جذاب را در ابتدای سال شروع می‌کردیم که بعدا امکان استفاده از SQL Server 2019 را نیز فراهم می‌کرد.

فرایند جابه‌جایی از ویندوز سرور ۲۰۱۲ به ۲۰۱۹ برای خود من هم پروژه‌ای کاملا جدید و ناشناخته بود. قبلا چنین کاری انجام نداده بودم و در ماه ژانویه، بالاخره نقشه‌ی راه جابه‌جایی به سیستم‌عامل جدید را طراحی کردم. در این مقاله تمامی مراحل جابه‌جایی اعم از برنامه‌ریزی، آزمایش، مشکلات پیش‌بینی‌نشده و پیاده‌سازی نهایی را شرح می‌دهد.

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

یکی از مزیت‌های اصلی به‌روزرسانی در توان عملیاتی ما در لاگ گروهی سرور بود. خوشه‌های (کلاسترها) کنونی سرورهای ما متشکل از سه نود هستند. دو نود اصلی و ثانویه‌ی محلی در نیویورک سیتی و یک نوت ثانویه‌ی دسترسی از راه دور در کلرادو واقع هستند. ما در کلرادو تأخیرهای قابل‌توجهی تجربه می‌کردیم و دیتابیس به‌خوبی و با سرعت مناسب هماهنگ نمی‌شد.

به‌روزرسانی از ویندوز سرور ۲۰۱۲ به نسخه‌های پس از سال ۲۰۱۶ فوایدی در کارایی سرورها ایجاد می‌کرد و همچنین برخی از مشکلات هماهنگی بین آن‌ها را از بین می‌برد. بهبودهای مذکور برای من ارزش بالایی داشتند، چون دیگر شاهد مشکلاتی همچون تصویر زیر نمی‌شدم:

Not Synchronizing databases | Stack Overflow
Not Synchronizing databases | Stack Overflow

فاز اول: آزمایش

من محیطی آزمایشگاهی برای بررسی ایده‌ها و برنامه‌ها دارم که مزایای بسیار زیادی در پروژه‌ها دارد. در ابتدای این پروژه، دو کلاستر آزمایشی Windows Server Failover Clusters (یا WSFC) داشتم. هریک از آن‌ها دو نود شبکه داشت که مجهز به ویندوز سرور ۲۰۱۶ و SQL Server 2017 بودند. به‌علاوه هر کلاستر مجهز به Availability Group بود و بین دو کلاستر نیز Distributed Availability Group پیاده‌سازی می‌شد. به‌هرحال من نمی‌‌خواستم که برای آزمایش، کلاسترهای موجود را تغییر دهم و درنتیجه سرورهای جدیدی برای آزمایش ایجاد کردم.

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

Stack Overflow Windows 2012 Clusters
Stack Overflow Windows 2012 Clusters

سرورهای پروداکشن هرکدام دو WSFC داشتند که مجوز به ویندوز سرور ۲۰۱۲ بود و هرکدام سه نود داشت. هر دو کلاستر یک Availability Group و یک Distributed Availability Group داشتند که به کلاستری دیگر متصل بود. پس از اتمام پروژه، کلاسترهای جدید ظاهر شبیه به هم پیدا می‌کردند، اما سیستم‌عامل و نام آن‌ها تغییر می‌کرد. در پایان SQL Server اصلی هر یک در گروه‌های مربوطه هم به دیتابیس NY Secondary تبدیل می‌شود.

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

در مرحله‌‌ی نهایی سه کلاستر جدید ۲۰۱۲ داشتم که هرکدام سه نود داشتند (دو نود در نیویورک و یکی در کلرادو). همه‌ی کلاسترها از SQL Server 2017 استفاده می‌کردند و دو گروه AG در آن‌ها طراحی شد. یکی از گروه‌های AG محدود به کلاستر بود و دومی به DAG کلاستر دیگر متصل می‌شد.

آزمایش کاربردپذیری

پیش از آن که کلاستر آزمایشی را بررسی کنیم، ایده‌ی ساخت سروری دیگر با ویندوز سرور ۲۰۱۹ مطرح شد تا امکان کار کردن آن با کلاستر آزمایشگاهی بررسی شود. درواقع ما می‌خواستیم هماهنگی داده میان سرورها را بررسی کنیم. من یک سرور دیگر راه‌اندازی کردم و این بار سیستم‌عاملی کاملا جدید یعنی ویندوز سرور ۲۰۱۹ اجرا می‌شد که در SQL Server 2017 روی آن نصب بود. هدف نهایی، اضافه کردن نسخه‌ی ۲۰۱۹ در کنار ویندوز سرور ۲۰۱۲ بود تا دریافت داده از نسخه‌ی قدیمی بررسی شود. پیکربندی مورد نظر، شبیه به دیاگرام زیر می‌شد:

Lab Cluster - single 2019 server | Stack Overflow
Lab Cluster – single 2019 server | Stack Overflow

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

  • اضافه کردن سرور ۲۰۱۹ به کلاستر ۲۰۱۲ موجود که طبق پیش‌بینی‌ها موفق نشد. دلیل شکست نیز تفاوت سیستم‌های عامل بود.
  • تلاش برای اضافه کردن سرور به AG موجود که باز هم به‌خاطر عدم عضویت در کلاستر موفق نشد.
  • ایجاد یک کلاستر نود مجزا برای سرور ۲۰۱۹ و تلاش برای اضافه کردن آن به‌عنوان عضوی دوم در AG که باز هم موفق نبود.
    وقتی آزمایش‌های بالا و بسیاری بررسی‌های دیگر ناموفق شدند، درباره‌ی چگونگی انجام نهایی پروژه نگران شدم. آزمایش بعدی ایجاد DAG برای همه‌ی AG‌های موجود بود تا شاید بتوان سرور ۲۰۱۹ را به ترکیب جدید اضافه کرد. درنهایت به نتیجه‌ای رسیدم که برای یک سرور تکی جوابگو بود. پس از آن که یک DAG بین کلاستر ۲۰۱۹ و ۲۰۱۲ ایجاد کردم، داده‌ها بین دو کلاستر با سیستم‌های عامل متفاوت جابه‌جا و هماهنگ شدند.

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

سرور آزمایشی پروداکشن

وقتی به این نتیجه رسیدیم که می‌توان کلاسترهایی با سیستم‌عامل گوناگون داشت و داده را با استفاده از AG توزیع‌شده هماهنگ کرد، زمان آزمایش کلاستر آزمایشگاهی ۲۰۱۲ فرا رسید. از آنجایی که کلاستر مذکور به‌صورت یک کلاستر مستقل با SQL Server در حال کار بود، باید آزمایشی کاملا نزدیک به شرایط واقعی و مورد نظر سرور پروداکشن نهایی طراحی می‌کردیم. ابتدا باید یک کپی از کلاستر گزارش‌دهی ایجاد می‌کردم. در این مرحله از یک کلاستر ۲۰۱۶ استفاده کردم که در محیط آزمایشگاهی در دسترس بود.

برنامه‌ی آزمایش مرحله‌ی جدید، شامل ایجاد DAG بین کلاستر ۲۰۱۲ موجود و کلاستر آزمایشگاهی ۲۰۱۶ بود. چنین تنظیماتی شبیه به طراحی موجود در سرور پروداکشن می‌شد که دیاگرام زیر نشان‌دهنده‌ی طراحی آن است:

Lab Cluster - 2012 to 2016 | Stack Overflow
Lab Cluster – 2012 to 2016 | Stack Overflow

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

  1. جدا کردن سرور از کلاستر موجود ۲۰۱۲
  2. بازسازی با ویندوز سرور ۲۰۱۹
  3. ساخت WSFC جدید با یک نود
  4. نصب SQL Server 2017
  5. پیاده‌سازی AG توزیع‌شده‌ی جدید از کلاستر قدیمی به کلاستر جدید برای همگام‌سازی دیتابیس

پس از پیاده‌سازی مراحل بالا، قصد داشتم تا همین فرایند را برای سرور ثانویه‌ی کلرادو با کلاستر ۲۰۱۲ هم انجام دهم. تفاوت فرایند برای کلاستر CO این بود که آن را به‌صورت یک نود جدید به WSFC اضافه می‌کردم تا به‌صورت یک کپی از AG به کلاستر جدید افزوده شود. در این مرحله از فرایند یک کلاستر قدیمی ۲۰۱۲ داشتیم و یک سرور تکی نیز داده را به دو کلاستر ارسال می‌کرد. به‌ بیان‌ دیگر یک کلاستر گزارش‌دهی ۲۰۱۶ و یک کلاستر ۲۰۱۹ جدید ایجاد شد که طرحی شبیه به دیاگرام زیر داشت:

Lab Cluster - 2012 to 2016 and 2019 | Stack Overflow
Lab Cluster – 2012 to 2016 and 2019 | Stack Overflow

پیش‌ از به‌روزرسانی سرور ۲۰۱۲ نهایی، باید فرایند Failover (به زبان ساده جابه‌جایی یک سرور به سروری دیگر) را برای AG توزیع‌شده از کلاستر ۲۰۱۲ به کلاستر ۲۰۱۹ جدید انجام می‌دادم. برای پیاده‌سازی فرایند مذکور یک مشکل اساسی داشتم که در کلاستر گزارش‌دهی دیده می‌شد. اگر failover را از AG توزیع‌شده به کلاستر ۲۰۱۹ جدید انجام می‌دادم، فرایند دریافت داده متوقف می‌شد. درنتیجه دو گزینه پیش رو داشتیم:

  1. پیاده‌سازی failover و خارج کردن کلاستر گزارش و سپس انتظار برای بازگشت شرایط همگام‌سازی داده
  2. جابه‌جایی کلاستر گزارشی و AGهای توزیع‌شده‌ی آن پیش از فرایند failover به کلاستر ۲۰۱۹ و امیدواری به همگام‌سازی مجدد داده‌ها

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

پس از انتخاب گزینه‌ی اجرایی، پیاده‌سازی فرایند در محیط آزمایشگاهی دشواری زیادی نداشت. تنها یک سرور در کلاستر قدیمی باقی ماند و باید AGهای توزیع‌شده را به کلاستر ۲۰۱۹ جدید منتقل می‌کردیم (فرایند failover). در مراحل بعدی باید کلاستر ۲۰۱۲ از بین می‌رفت و سرور جدید با ویندوز ۲۰۱۹ ساخته می‌شد. مراحل نهایی شامل اضافه کردن سرور جدید به WSFC 2019، نصب SQL Server و اضافه کردن مجموعه به‌عنوان یک کپی به همه‌ی AGها بود.

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

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

  • ۲ سیستم WSFC
  • ۶ سرور با سیستم‌عامل جدید و نسخه‌های تازه‌ی SQL Server
  • ۵ گروه AG با ۳۸۵ دیتابیس
  • ۵ گروه AG توزیع‌شده‌ی موقت که در کنار AGهای بالا قرار می‌گرفتند

با توجه به مراحل بالا به این نتیجه می‌رسیم که به آدرس‌های IP جدید برای کلاسترها هم نیاز داشتیم. به‌علاوه AG Listener و نام‌ جدید باید برای کلاسترها، AGها و DAGها انتخاب می‌شد. در فرایند آزمایش متوجه شدیم که نمی‌توان نام‌های مشابهی برای موارد مذکور انتخاب کرد. حتی با وجود متفاوت بودن سرورها، نام‌های مشابه انتخاب مناسبی نبود؛ چرا که فرایند جابه‌جایی به سرور پروداکشن را بسیار دشوار و زمان‌بر می‌کرد. به‌ هر حال همه‌ی شرایط برای فرایند نهایی آماده به نظر می‌رسید.

فاز دوم: پیاده‌سازی اولیه

تقریبا تمامی ماه ژوئیه به بررسی و آزمایش فرایند برای اجرا در سرور پروداکشن اختصاص یافت. ابتدا ماه فوریه را برای اجرای نهایی انتخاب کردم که گزینه‌ی اشتباهی بود. درواقع در مراحل پایانی آزمایش پیشنهاد به‌روزرسانی به سرور ۲۰۱۹ در چند سرور توسعه‌ای مطرح شد تا هرگونه اشکال احتمالی در جابه‌جایی سرور پروداکشن بررسی شود. سرورهای توسعه‌ای اصلی ما که برای بخش پرسش و پاسخ اصلی استفاده می‌شوند، سخت‌افزار و تنظیمات مشابه دارند، اما هیچ‌گونه AG با آن‌ها در ارتباط نیست. درواقع سرورهای مذکور تنها کپی‌هایی از دیتابیس دارند که برای فرایند توسعه استفاده می‌شود.

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

سندی ۳۵ صفحه‌ای به‌عنوان دستورالعمل به‌روزرسانی آماده شد

برای اجرای فرایند آزمایشی روی سرورهای توسعه‌ای، به سرور نیاز داشتم. دو ماشین مجازی و یک سرور فیزیکی انتخاب شدند. ما از سرویس Foreman برای بازسازی خودکار سرورها استفاده می‌کنیم که فرایند پیاده‌سازی و بازسازی سرورها را بسیار دشوار می‌کرد. از آنجایی که ویندوز سرور ۲۰۱۹ هیچ‌گاه پیاده‌سازی نشده بود، در فورمن به آن دسترسی نداشتیم. درنتیجه باید سرورها را به‌صورت دستی به‌روزرسانی می‌کردم. به‌روزرسانی ابتدا روی دو ماشین مجازی انجام شد. به‌جز چند مشکل جزئی، سایر فرایند به‌خوبی انجام شد. سیستم‌عامل به‌خوبی پیاده‌سازی و نصب SQL Server هم در ادامه‌ی آن انجام شد. درنهایت سرورها در عرض چند ساعت به چرخه‌ی عملیات بازگشتند.

مرحله‌ی بعدی پیاده‌سازی ویندوز سرور ۲۰۱۹ در سرور فیزیکی بود که چالش‌های اصلی را به‌همراه داشت. همان‌طور که قبلا گفتم، سرورهای توسعه‌ای ما سخت‌افزار و پیکربندی کاملا مشابهی با سرورهای پروداکشن دارند. درواقع با یک درایو برای سیستم‌عامل، درایوی برای SQL مجهز به NVMe/PCIe و عموما درایو سومی مجهز به دیسک‌های چرخنده داریم. سرور فیزیکی که برای آزمایش سیستم‌عامل جدید انتخاب شد، هر سه درایو مذکور را داشت. من فرایند بازسازی را شروع کردم و دو ساعت پس از آن، با صفحه‌ی آبی مرگ روبه‌رو شدم:

BSOD | Stack Overflow
BSOD | Stack Overflow

مشکل عملیاتی بسیار سریع کشف شد. درایوهای NVMe با ویندوز سرور ۲۰۱۹ هماهنگ نبودند. به کمک اعضای عالی تیمم فرایند دیباگ را شروع کردیم. پس از بحث‌های متعدد به این نتیجه رسیدیم که درایو را به‌روزرسانی کنیم. یکی از درایوهای NVMe ابتدا در ظاهر از کار افتاد و سپس مجددا آنلاین شد. ما توانستیم سرور را مجددا به حالت پیش از به‌روزرسانی ۲۰۱۶ بازگردانیم.

فرایند بالا اصلا در مسیر اصلی پیاده‌سازی نبود. ما می‌خواستیم به نسخه‌ی ۲۰۱۹ به‌روزرسانی کنیم، اما درایور جدید با NVMe RAID هماهنگ نبود. درنتیجه باید با شرکت‌های سازنده یعنی اینتل و دل تماس می‌گرفتیم. شاید به کمک آن‌ها می‌توانستیم درایور و نرم‌افزار مورد نیاز را برای درایوهای NVMe RAID خود پیدا کنیم. درنهایت توانستیم تجهیزات را آماده کرده و درایورهای مورد نیاز را با نرم‌افزاری نصب کنیم که توانایی شناسایی RAID ما را داشت. در مرحله‌ی بعد باید یک پیاده‌سازی دیگر را برای نسخه‌ی ۲۰۱۹ آزمایش می‌کردیم. پس از گذشت دو ساعت از فرایند بازسازی، به وضعیت ۴۵ درصد پیشروی در به‌روزرسانی رسیدم:

Upgrade Progress | Stack Overflow
Upgrade Progress | Stack Overflow

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

وقتی فرایند سوم بازسازی شروع شد، همه‌چیز عادی به‌نظر می‌رسید. پس از اتمام فرایند و بارگذاری سیستم، ویندوز سرور ۲۰۱۶ بارگذاری شد! در این مرحله ما یک پارتیشن دو ترابایتی NVMe داشتیم که هیچ اطلاعاتی در آن نبود. به‌ بیان‌ دیگر تمامی داده‌های SQL ما در درایوهای NVMe پاک شده بودند. به‌هرحال زمان برای آزمایش چهارم فرا رسیده بود. در این مرحله همه‌ی درگاه‌های PCIe را در بایوس غیرفعال کردیم.

پس از رخ دادن مشکلات متعدد بالا، ما اعتماد به نفس خود را برای به‌روزرسانی به ویندوز سرور ۲۰۱۹ از دست داده بودیم. به‌ هر حال و صرف‌نظر از همه‌ی چالش‌ها، باید اجرایی بودن پروژه را بررسی می‌‌کردیم. تلاش چهارم بالاخره به نصب ویندوز سرور ۲۰۱۹ انجامید، اما باز هم مشکلی دیگر داشتیم. وقتی درگاه‌های PCIe مجددا فعال شدند، تنها دو دیسک در بخش مدیریت RSTe بخش مدیریت دیسک سرور نمایان بود. البته در بخش دیوایس منیجر همه‌ی دستگاه‌ها قابل مشاهده بودند. چرا گزارش‌ها با هم هماهنگ نبود؟ واقعا با مشکلاتی عجیب در سرور روبه‌رو بودیم.

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

در مرحله‌ی بعدی تلاش کردیم تا سرور را به حالت ۲۰۱۶ بازگردانیم و از درایورهای قدیمی برای SSDها استفاده کنیم تا شاید سرور به مرحله‌ی پیش از به‌روزرسانی به ۲۰۱۹ برگردد. ما امیدوار بودیم که در صورت بازگرداندن درایورها به وضعیت قبلی، درگاه‌های PCIe مجددا شناخته شوند و درایوها به چرخه بازگردند. آزمایش جدید هم با شکست روبه‌رو شد چون پیاده‌سازی سیستم‌عامل توانایی پیوند دادن سرور به دامین‌ها را نداشت و درنهایت ورود به سرور ممکن نبود.

تلاش‌های ما برای بازسازی سرور به مرحله‌ی ششم رسید. مرحله‌ای که بتوانیم با استفاده از ویندوز سرور ۲۰۱۶ و درایورهای قدیمی، سرور را به دامین متصل کنیم و SSD هم به‌خوبی کار کند. باز هم موفق نبودیم و فرایند اتصال به دامین مشکل داشت. مجددا هم‌تیمی‌های من تلاش کردند تا سرور را به شبکه بازگردانند. پس از اتصال به دامین، با مشکل عجیب دیگری مواجه شدیم:

Rebuild 7 Failure | Stack Overflow
Rebuild 7 Failure | Stack Overflow

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

مارک هندرسن، همکار من در زمان انتظار برای ارسال درایوهای جدید از سوی اینتل، بهینه‌سازی فرایند فورمن را انجام داد تا با نسخه‌ی ۲۰۱۹ هماهنگ شود. به‌‌علاوه او درایوهای NVMe را هم از فرایند خارج کرد تا در زمان نصب سیستم‌عامل، مزاحمتی ایجاد نکنند. همه‌ی مراحل مذکور، یعنی باید باز هم بازسازی انجام می‌دادیم. درواقع سه فرایند بازسازی در پیش داشتیم. یکی بازسازی به ۲۰۱۶، دیگری به ۲۰۱۹ و سپس مجددا بازگشت به ۲۰۱۶ که مجموعا به ۹ بازسازی روی یک سرور می‌انجامید. شاید این سؤال ایجاد شود که چرا پس از بازسازی به نسخه‌ی ۲۰۱۹، مجددا به نسخه‌ی ۲۰۱۶ بازگشتیم؟

فرایند بالا به این دلیل انجام شد که ما دیگر به‌نوعی اعتماد به‌نفسی برای استفاده از نسخه‌ی ۲۰۱۹ با SSDهای موجود نداشتیم. اینتل هم دیگر درایورهای عمومی نداشت و ما را به دل ارجاع داد. به‌هرحال ما در فرایندی رفت‌وبرگشتی گرفتار شدیم که در وضعیت مذکور، اصلا جالب نبود.

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

تلاش‌های متعدد و شکست‌ها و از دست دادن سخت‌افزار، ما را به‌نوعی از به‌روزرسانی سرورهای پروداکشن به ویندوز ۲۰۱۹ ناامید کرده بود. درواقع نمی‌توانستیم ریسک از بین رفتن درایوهای SSD به‌خاطر نصب ویندوز را بپذیریم. مطمئن بودیم که نسخه‌ی ۲۰۱۶ مشکلی برای آن‌ها ایجاد نمی‌کند چون سرور توسعه‌ای سال‌ها از آن استفاده می‌کرد. درنهایت تصمیم گرفتیم تا ویندوز سرور ۲۰۱۹ را تاحدودی از برنامه‌ها خارج کنیم.

پس از دو هفته بالاخره درایوهای ذخیره‌ساز جدید رسیدند و زمان نصب و آزمایش مجدد فرا رسید. در آن زمان ما بازسازی را برای دهمین مرتبه انجام می‌دادیم. برای نصب نسخه‌ی جدیدی از ویندوز ۲۰۱۶ آماده بودیم که باز هم فرایند بازسازی شکست خورد!

ابزار Puppet، رویکرد دیگری است که ما در کنار فورمن برای رساندن سرورها به حالت پایدار استفاده می‌کنیم. شکست در بازسازی آخر به‌خاطر اشکالی در پاپت بود و البته گزارشی هم در لاگ خطاها دیده نمی‌شد. به‌ هر حال فرایندها باز هم شکست خوردند و رسیدن به نسخه‌ای پایدار بدون هیچ‌گونه خطا، تا مرحله‌ی ۱۴ بازسازی طول کشید. پس از رد شدن از همه‌ی چالش‌ها، بالاخره نسخه‌ای پایدار و تمیز از سرور توسعه‌ای داشتیم. ویندوز سرور ۲۰۱۶ به‌خوبی نصب شده بود و نوبت به نصب SQL Server رسید که در ظاهر دشواری چندانی نداشت.

سرور تحت آزمایش، مشکلات بسیار متعددی داشت. SQL Server 2017 برای نصب انتخاب شده بود که همیشه با چند دستور PowerShell به‌راحتی پیاده می‌شد، اما در سرور مذکور باز هم به چالش برخوردیم. در نصب ماژول SqlServer و سپس SPNها، مشکلات زیادی داشتیم و روند به‌خوبی پیش نمی‌رفت. به‌هرحال همه‌ی چالش‌ها به ترتیب حل شدند و درنهایت یک سرور توسعه‌ای با تمامی دیتابیس‌ها راه‌اندازی شد.

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

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

فاز سوم: سرور پروداکشن

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

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

  • پشتیبان‌گیری لاگ تراکنش‌ها را در سرور اصلی متوقف کنید
  • روتینگ فقط-خواندن را از AG بردارید
  • اتصالات را در اپلیکیشن فلاش کنید
  • پشتیبان‌گیری کامل را در سرور اصلی قطع کنید
  • سرور را از AGهای موجود در سرور اصلی حذف کنید
  • سرور را از کلاستر کنونی حذف کنید
  • سرور را برای پیاده‌سازی نسخه‌ی ۲۰۱۶ به فورمن وارد کرده و فرایند بازسازی را شروع کنید
  • مطمئن شوید که پس از بازسازی، پاپت اجرا شده و مشغول به کار باشد
  • پس از بازسازی، نقش Failover Cluster را به سرور اضافه کنید (سرور ریبوت می‌شود)
  • یک WSFC جدید بسازید
  • وقتی Cluster Object در AD ایجاد شد، اگر نیاز بود آن را به OU منتقل کنید
  • وقتی کلاستر آبجکت ایجاد شد، آرس‌های IP را بررسی کرده و آن‌ها را ویرایش کنید
  • مطمئن شوید که کلاستر آبجکت در WSFC مجوز ساختن و پاک کردن آبجکت‌های کامپیوتری را در AD دارد
  • ابزارهای Dell NVMe را نصب کنید
  • SQL Server را نصب کنید (اگر tempdb هنوز در پوشه‌ی D:\Data بود، ابتدا همه‌ی فایل‌ها را پاک کنید)
  • حالت Trace Flags را فعال و سرویس SQL را مجددا بارگذاری کنید
  • اسکریپت‌های مربوطه برای اضافه کردن اطلاعات ورود، کاربران و موارد دیگر را اجرا کنید
  • AG جدید بسازید
  • برای هر AG یک AG توزیع‌شده‌ی موقت (TAG) ایجاد کنید که ابتدا در سرور اولیه و سپس ثانویه پیاده شوند
  • در این مرحله همه‌ی داده‌ها باید به‌خوبی با سرور جدید همگام‌سازی شوند که سروری مجزا در کلاستر اختصاصی خود خواهد بود
  • جاب‌های sql را بازسازی کنید
  • جاب پشتیبان‌گیری را برای دیتابیس کاربران غیرفعال کنید
  • جاب پشتیبان‌گیری را در سرور اولیه‌ی کلاستر قدیمی مجددا راه‌اندازی کنید

اگرچه مراحل پیاده‌سازی برای هر سرور منحصربه‌فرد است، اما فرایندهای بالا به‌نوعی پایه‌های اجرایی همه‌ی آن‌ها محسوب می‌شوند. اگر همه‌ی برنامه‌ها به‌خوبی پیش می‌رفت، تا پایان چهارشنبه ۱۷ آوریل ۲۰۱۹ سه سرور را به کلاسترهای جدید جابه‌جا کرده بودیم و SQL Server روی همه‌ی آن‌ها نصب شده بود. درنتیجه فرایند همگام‌سازی هم به‌درستی انجام می‌شد و به دیاگرامی شبیه به تصویر زیر می‌رسیدیم:

Goal by Day 3 | Stack Overflow
Goal by Day 3 | Stack Overflow

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

روز اول

روز اول، برنامه‌ی مخصوص سرور اول یعنی NY-SQL-03 را اجرا کردیم که سرور ثانویه‌ی کلاستر NY بود. همه‌ی موارد طبق برنامه پیش رفتند. ویندوز و SQL Server نصب شدند، کلاستر آماده شد و همه‌ی چهار TAG مورد نظر پیکربندی شدند. همه‌ی دیتابیس‌ها فرایند همگام‌سازی را انجام می‌دادند و در Opserver وضعیت سبز داشتند. به‌هرحال روز اول با موفقیت پیش رفت و پنج سرور دیگر در صف تغییرات بودند.

روز دوم

فعالیت روز دوم زودتر و جدی‌تر پیگیری شد، چون تصمیم داشتیم تا دو سرور را تغییر دهیم. NY-SQL-01 و CO-SQL-03 در برنامه‌ی روز دوم بودند. فرایند بازسازی را به‌صورت هم‌زمان روی دو سرور انجام دادیم. NY-SQL-01 پس از چند ساعت به فرایند کاری بازگشت، اما سرور دیگر دشواری‌هایی را به‌همراه داشت.

سرور دوم یا CO در فرایند بازسازی مشکلات عجیبی را نشان می‌داد. این سرور تنها نود کلاستر ۲۰۱۶ جدید بود. سیستم دارای ۳۷۵ دیتابیس بود که در چهار AG قرار داشتند و همچنین چهار DAG هم برای همگام‌سازی داده‌ها بین سرورهای ۲۰۱۲ و ۲۰۱۶ استفاده می‌شدند.

  • AG-NYOnly – 6 databases syncing via distributed AG – NYOnly_TAG
  • AG-Misc – 10 databases syncing via distributed AG – Misc_TAG
  • AG-Chat – 3 databases syncing via distributed AG – Chat_TAG
  • AG-SENetwork – 354 databases syncing via distributed AG – SENetwork_TAG

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

سرورهای پروداکشن باید در سریع‌ترین زمان آماده می‌شدند

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

برای رفع مشکلات ابتدا تصمیم گرفتیم که سرویس SQL Server را مجددا راه‌اندازی کنیم. سپس متوقف کردن AG در WSFC را انجام دادیم و لاگ خطاها، باز هم مشکل را در AG نشان می‌داد. با بررسی فرایندهای متعدد تصمیم گرفتیم که بکاپ جدیدی از دیتابیس در AG داشته باشیم و آن را به NY-SQL-03 بازگردانیم و سپس با اتصال آن به AG فرایند همگام‌سازی را مجددا شروع کنیم.

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

Wait stats | Stack Overflow
Wait stats | Stack Overflow

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

روزهای سوم تا هفتم

فرایندهای انتقال دیتابیس به‌خوبی ادامه پیدا کردند، اما باز هم تأخیرهایی در آن‌ها وجود داشت. ما حتی در انجمن‌های استک‌اکسچنج خود با کاربران برای رفع مشکل مشورت کردیم و یک نفر غیرفعال کردن Parallel Redo را در SQL Server پیشنهاد داد. به‌هرحال همه‌ی راهکارهای ممکن را امتحان کردیم، اما چالش‌هایی که در DMV و همچنین تأخیرهای مکرر داشتیم، نتیجه‌گیری را دشوار می‌کرد. درنهایت مجبور شدیم تا در یک تیکت پشتیبانی از مایکروسافت درخواست کمک کنیم.

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

پس از دریافت پاسخ تیکت از سوی مایکروسافت، با یکی از کاربران متخصص دیتابیس به‌نام شان گالاردی مشاوره کردم که کارمند مایکروسافت هم بود. در این مرحله باید به فرایند دشوار به‌روزرسانی برمی‌گشتیم و شان پیشنهاد داد که فرایند auto-seeding (فرایندی برای راه‌اندازی AG) را SENetwork_TAG غیرفعال کنیم. درنتیجه کد زیر را اجرا کردیم:

ALTER AVAILABILITY GROUP [SENetwork_TAG] MODIFY REPLICA ON 'NY-SQL03' WITH (SEEDING_MODE = MANUAL)
کد بالا فرایند سید خودکار دیتابیس را متوقف کرد، اما مشکل به قوت خود باقی بود. ما هنوز نمی‌توانستیم دیتابیس را در کلاستر جدید همگام‌سازی کنیم و هنوز مشکلات متعدد کوچکی در NY-SQL-03 وجود داشت. درنهایت مشورت من و نیک و شان به راهکار زیر ختم شد:
  1. TAG مرتبط با SENetwork را حذف کنیم چون به‌خاطر مشکل اصلی ایجاد شده بود.
  2. AG موجود در کلاستر جدید را حذف کنیم.
  3. دیتابیس‌ها را به‌صورت دستی در وضعیت بازیابی NY-SQL03 و CO-SQL03 بازیابی کنیم.
  4. TAG مورد نظر برای SENetwork را بازسازی کنیم.
  5. به‌آرامی هر دیتابیس را به AG در هر دو سرور NY-SQL03 و CO-SQL03 اضافه کنیم تا فرایند همگام‌سازی انجام شود.

درنتیجه مجددا فرایند آهسته‌ای شروع شد که در هر مرتبه دو تا چهار دیتابیس را وارد روند بالا می‌کردیم. برای آهسته بودن فرایند همین بس که باید ۳۵۴ دیتابیس را جابه‌جا می‌کردیم. مشکل اصلی ما، باگی در SQL Server بود که در زمان افزایش دیتابیس‌های یک AG از ۱۵ عدد رخ می‌دهد. DAG ما شامل ۳۵۴ دیتابیس بود و به‌همین دلیل نمی‌توانست این تعداد را مدیریت کند.

با ادامه دادن روند بالا تا آخر هفته ما دو کلاستر جدید داشتیم که داده را از کلاسترهای قدیمی ۲۰۱۲ دریافت می‌کردند. درنهایت زمان آن رسیده بود که فرایند انتقال (failover) را از TAGها انجام دهیم. با وجود همه‌‌ی زمان‌هایی که در دیباگ کردن از دست دادیم، درنهایت به وضعیتی پایدار رسیده بودیم و برنامه‌ریزی زمان انتقال ممکن بود. تا پایان هفته سرورها به وضعیت زیر رسیده بودند:

Week 1 State of Servers | Stack Overflow
Week 1 State of Servers | Stack Overflow

در پایان هفته و پس از چند مشکل جزئی دیگر، برای اجرای نهایی فرایند آماده بودیم.

روز هشتم

هفته‌ی جدید شروع شده بود و ما به‌جز سه سرور باقی‌مانده، یک فرایند انتقال بزرگ در پیش داشتیم. البته همه‌ی باگ‌‌ها از بین رفته بودند و مسیری مستقیم تا پایان خط داشتیم. روز هشتم را با جدا کردن CO-SQL01 از کلاستر قدیمی و فرایند بازسازی شروع کردم. باز هم مشکلاتی پیش آمد. فرایند خودکار فورمن به‌خوبی کار نمی‌کرد و مدام باید بهینه‌سازی‌هایی در آن انجام می‌دادیم. به‌علاوه فرایند به‌روزرسانی ویندوز هم دچار مشکل شد. بالاخره توانستم SQL Server را نصب کنم و بکاپ‌ها را در وضعیت NORECOVERY بازیابی کنم. سپس پیاده‌سازی لاگ‌ها انجام شد تا دیتابیس به وضعیت کنونی برسد و درنهایت، همگام‌سازی داده شروع شد. درنهایت چهار سرور در کلاسترهای جدید داشتیم که همه در وضعیت سبز کار می‌کردند.

روز نهم: اجرای فرایند failover

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

تغییر در اپلیکیشن‌ها به‌‌خاطر ایجاد کلاسترهای جدید با AG و DAG جدید بود که همه باید به آدرس‌های IP جدید متصل می‌شدند. به‌علاوه در کنار حساسیتی که در اجرای فرایندها در روز failover داشتیم، اولویت اجرای آن‌ها نیز بسیار مهم بود. اولین دیتابیس در دسته‌ی Exceptions قرار می‌گرفت که به‌نام NY.Exceptions می‌شناسیم. این دیتابیس برای ذخیره‌ی خطاهایی استفاده می‌شود که در شبکه ظاهر می‌شوند. ابتدا دیتابیس مذکور را از AG در کلاسترهای قدیمی و جدید حذف کرده و قابلیت نوشتن روی آن را نیز بررسی کردیم. به‌علاوه هر دو دیتابیس را به فرایند نظارتی Opserver اضافه کردیم تا اپلیکیشن‌های با مقاصد اتصالی غلط، حین فرایند شناسایی شوند. چنین رویکردی امکان ردگیری خطاها را فراهم می‌‌کرد.

باگ موجود در SQL Server فرایند را با چالشی بزرگ روبه‌رو کرد

مرحله‌ی بعدی، اعمال تغییرات اپلیکیشن‌ها به پروداکشن بود. ما از Team City برای پیاده‌سازی اپلیکیشن‌ها استفاده می‌کنیم که یک دیتابیس روی SQL Server دارد. باید پیش از ادامه‌ی فرایند از آماده بودن تیم سیتی مطمئن می‌شدیم. درنتیجه برای اولین اقدام جابه‌جایی، NYOnly_AG را انتخاب کردیم و کانکشن استرینگ را از SQL-NYOnly_AG به SQLAG-NYOnly تغییر دادیم. سپس اپلیکیشن ساخته شد و مرحله‌ی بعدی، جابه‌جایی DAG بود.

طبق اسناد مایکروسافت برای failover یک DAG باید از فرایندی دستی استفاده کرد. کد مورد نظر ابتدا باید در سرور کنونی اولیه اجرا شود و پس از تأیید شدن، کدهای بیشتر اجرا شوند و این فرایند چندین بار ادامه پیدا می‌کند. در سند راهنمای انتقال، همه‌ی کدهای لازم نوشته شد و اکنون زمان اجرا بود. درنهایت با اجرای کدهای مرحله‌ی اول، اولین DAG جابه‌جا شده بود و همه‌ی موارد نیز قابل نوشتن بودند. تنها چهار دسته‌ی دیگر باقی ماند.

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

پیش از اجرای فرایند جابه‌جایی نهایی، DAG قدیمی بین کلاستر ۲۰۱۲ و کلاستر گزارش‌دهی حذف شد. درواقع ما می‌دانستیم که همگام‌سازی داده‌ها در زمان جابه‌جایی نهایی متوقف می‌شود و از بین برد DAG فرایندی اجتناب‌ناپذیر بود. پس از اینکه HighAvailability_DAG پاک شد، بخش جابز در سایت را به فقط-خواندن تغییر دادیم. سپس کانکشن استرینگ در همه‌ی اپلیکیشن‌ها جایگزین شد و مجددا آن‌ها را ساختیم. سپس نوبت به فرایند انتقال نهایی DAG جدید رسید که به‌نام Misc_TAG شناخته می‌شد. این بخش هم بدون مشکل پیش رفت و دیتابیس Careers مجددا قابل نوشتن شد. درنهایت جابز را از حالت فقط-خواندن خارج کردیم و همه‌چیز برای ادامه‌ی راه فراهم شد.

انتقال‌ها یا failoverهای نهایی مربوط به StackOverflow_TAG بو SENetwork_TAG بودند. با توجه به نام گرو‌های می‌دانیم که جابه‌جایی آن‌ها منجر به قطعی موقت می‌شد. به‌هرحال باید فرایند را با سرعت هرچه بیشتر انجام می‌دادیم. DAGهای مذکور تمامی دیتابیس‌های شبکه‌ی سایت‌ها را مدیریت می‌کنند و جابه‌جایی سریع آن‌ها منجر به کاهش زمان قطعی می‌شد.

اولین فرایند failover مربوط به StackOverflow_TAG بود که تنها پنج دیتابیس داشت و به تصور ما، جابه‌جایی آن سریع‌تر انجام می‌شد (دیگری قطعا با ۳۵۴ دیتابیس، مشکلات بیشتری ایجاد می‌کرد). ابتدا DAG قدیمی که به کلاستر گزارش‌دهی می‌رفت را حذف کردم و سپس فرایند failover برای گروه مذکور شروع شد و بدون هیچ مشکلی پایان یافت. گروه دوم نیز با وجود تمام استرس گروه به‌خوبی جابه‌جایی شد و سپس فرایند تأیید LSNها صورت گرفت.

تأیید LSNها با اجرای چند خط دستور و بررسی ۳۵۴ دیتابیس با هم انجام می‌شد که قطعا فرایندی پیچیده و دشوار بود. فرایند تأیید و بررسی چندین بار انجام می‌شد تا از هماهنگ بودن همه چیز مطمئن شویم. مدتی طول کشید تا از عالی بودن همه چیز مطمئن شویم. هدف ما از دست دادن حداقل داده بود و در این‌ مسیر به‌نوعی با همه‌ی‌ دیتابیس‌ها درگیر می‌شدیم.

پس از بررسی همه‌ی دیتابیس‌ها به مرحله‌ی پایانی failover برای SENetwork_TAG رسیدیم. کدهای مربوطه اجرا شدند و درنهایت سرور اصلی NY-SQL03 جدید شروع به کار کرد. بالاخره انتقال همه‌ی TAGها انجام شد و همه‌ی سایت‌ها در حالت آنلاین بودند. همه به این تصور رسیدیم که فرایند failover تمام شده است.

پس از پایان فرایند انتقال دیتابیس‌ها، سرور اصلی NY-SQL04 دچار مشکل شد و به نوعی پاسخگویی مناسبی در برابر دستورها نداشت. همه‌ی دیتابیس‌های آن قفل شده بودند و پردازنده با شدت بالایی کار می‌کرد. تا ۲۵ دقیقه هیچ پاسخی از سرور نداشتیم. به‌هرحال یک سرور جدید داشتیم و می‌توانستیم آن را کاملا به ویندوز سرور ۲۰۱۶ بازسازی کنیم. درنهایت تصمیم گرفتیم تا زمان بازسازی، SQL Server را متوقف کنیم.

پس از رفع چالش‌ها فوق، کل فرایند انتقال پایان یافت و همه‌ی سیستم‌ها در کلاستر ویندوز سرور ۲۰۱۶ طبق دیاگرام زیر مشغول به فعالیت بودند:

Post Failover Night State of Servers | Stack Overflow
Post Failover Night State of Servers | Stack Overflow

هنوز دو سرور در کلاستر ۲۰۱۲ فعال بودند. NY-SQL04 به‌‌صورت SQL Server فعالیت نمی‌کرد چون سرویس اس‌کیو‌ال را پس از فرایند انتقال قطع کرده بودیم. به‌علاوه NY-SQL02 عضو گروه TAG بود که به‌تازگی منتقل کرده بودیم. به‌هرحال سرورهای مذکور را در روز بعد بازسازی می‌کردیم و در روز دهن تنها روی کلاستر گزارش‌دهی متمرکز بودیم. این کلاستر برای کاربردهای داخلی اپلیکیشن‌ها استفاده می‌شود و باید هرچه سریع‌تر آن را آنلاین می‌کردیم.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
-- run this on NY-SQL03
CREATE AVAILABILITY GROUP [Misc_DAG] 
   WITH (DISTRIBUTED)  
   AVAILABILITY GROUP ON 
       'AG-Misc' WITH   
       (  
           LISTENER_URL = '<listener>',   
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,  
           FAILOVER_MODE = MANUAL,  
           SEEDING_MODE = AUTOMATIC  
       ),  
       'HighAvailability_RAG' WITH   
       (  
           LISTENER_URL = '<listener>',  
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,  
           FAILOVER_MODE = MANUAL,  
           SEEDING_MODE = AUTOMATIC  
       );   
GO 

-- run this on NY-RPTSQL01
ALTER AVAILABILITY GROUP [Misc_DAG] 
   JOIN  
   AVAILABILITY GROUP ON 
       'AG-Misc' WITH   
       (  
           LISTENER_URL = '<listener>',   
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,  
           FAILOVER_MODE = MANUAL,  
           SEEDING_MODE = AUTOMATIC  
       ),  
       'HighAvailability_RAG' WITH   
       (  
           LISTENER_URL = '<listener>',  
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,  
           FAILOVER_MODE = MANUAL,  
           SEEDING_MODE = AUTOMATIC  
       );   
GO 

-- run this on NY-SQL01
CREATE AVAILABILITY GROUP [StackOverflow_DAG] 
   WITH (DISTRIBUTED)  
   AVAILABILITY GROUP ON 
       'AG-StackOverflow' WITH   
       (  
           LISTENER_URL = '<listener>',   
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,  
           FAILOVER_MODE = MANUAL,  
           SEEDING_MODE = AUTOMATIC  
       ),  
       'StackOverflow_RAG' WITH   
       (  
           LISTENER_URL = '<listener>',  
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,  
           FAILOVER_MODE = MANUAL,  
           SEEDING_MODE = AUTOMATIC  
       );   
GO
-- run this on NY-RPTSQL01
ALTER AVAILABILITY GROUP [StackOverflow_DAG] 
   JOIN  
   AVAILABILITY GROUP ON 
       'AG-StackOverflow' WITH   
       (  
           LISTENER_URL = '<listener>',   
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,  
           FAILOVER_MODE = MANUAL,  
           SEEDING_MODE = AUTOMATIC  
       ),  
       'StackOverflow_RAG' WITH   
       (  
           LISTENER_URL = '<listener>',  
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,  
           FAILOVER_MODE = MANUAL,  
           SEEDING_MODE = AUTOMATIC  
       );   
GO 

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

Alter Database [database_name] Set HADR Availability Group = [distributed_AG_Name];

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

روز دهم: اصلاحات نهایی

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

  • بازیابی دیتابیس‌ها به CO-RPTSQL01 و اجرای فرایند همگام‌سازی در AG‌ و AGهای توزیع‌شده در کلاستر گزارش‌دهی
  • حذف AGهای توزیع‌شده‌ی موقتی در کلاسترهای جدید ۲۰۱۶
  • بازسازی NY-SQL04 و NY-SQL02 که آخرین سرورهای موجود در کلاستر ۲۰۱۲ بودند
  • وارد کردن سرورهای جدید به کلاسترهای جدید ویندوز ۲۰۱۶، نصب SQL Server و اضافه کردن آن‌ها به AG
  • روشن کردن همه‌ی فرایندهای بکاپ گیری t-log و بکاپ‌های کامل روزانه
  • اضافه کردن مسیردهی فقط خواندن در همه‌ی AGها

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

جداسازی و وصل کردن دیتابیس‌ها
اجرای t-logs برای همگام‌سازی به وضعیت کنونی
در مرحله‌ی نهایی احتمالا با اجرای چند فرمان SQL در AGها، فرایند همگام‌سازی شروع می‌شد
همه‌ی فرایندهای بالا برای کلاستر گزارش‌دهی اولیه‌ی NY-RPTSQL01 انجام شد و سپس باید برای CO-RPTSQL01 نیز آن‌ها را اجرا می‌کردیم. نیک روی سرورهای گزارش‌دهی نیویورک و کلرادو متمرکز شد و من هم بازسازی دو سرور نهایی یعنی NY-SQL04 و NY-SQL02 را بر عهده گرفتم. بازسازی سرورها به‌خوبی انجام شد و در مرحله‌ی اضافه کردن به AG، بکاپ‌های جدید از سرورهای اولیه گرفته و به سرورهای جدید منتقل شد. انجام فرایند مذکور به این خاطر بود که یک AG با ۳۵۴ دیتابیس (با حجم ۳/۵ ترابایت) را به‌صورت خودکار جابه‌جا نکنیم. درواقع قصد داشتیم تا حداقل T-log برای راه‌اندازی و تنظیم دیتابیس‌ها به وضعیت آنلاین اجرا شوند. درنهایت Opserver در همه‌ی بخش‌ها گزارش عملکرد موفق می‌داد:

Final State - All Done | Stack Overflow
Final State – All Done | Stack Overflow

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

صحبت نهایی

فرایند به‌روزرسانی سرورها یکی از پیچیده‌ترین پروژه‌های من بود که از لحاظ پیچیدگی با به‌روزرسانی SQL Server 2017 در سال گذشته برابری می‌کرد. پروژه‌ای که شامل کلنجار رفتن‌های متعدد با سرورها، دیتابیس‌ها و AGهای متعدد می‌شد و باید در حداقل زمان در دسترس نبودن سایت انجام می‌گرفت. کل فرایند تنها منجر به ۱۰ الی ۱۵ دقیقه در دسترس نبودن عمومی سایت شد که از نظر من رکورد قابل‌‌توجهی بود.

در پایان نتایج و نکاتی که از این پروژه آموختم را به‌صورت خلاصه ارائه می‌کنم:

  • آزمایش کنید، آزمایش کنید و این روند را چند بار اجرا کنید. برنامه‌ی اولیه شامل اجرای نهایی پس از آزمایش‌های اولیه بود و تغییر در سرورهای توسعه‌ای ناگهان به پروژه اضافه شد. تصور نمی‌کردیم که فرایند منجر به ایجاد خلل در محیط توسعه شود، اما به‌هرحال چالش‌های مذکور باگ‌های متعددی را به ما نشان دادند. اگر آزمایش انجام نمی‌شد، احتمال بروز باگ‌ها در پیاده‌سازی سرور پروداکشن وجود داشت.
  • در صورت امکان همیشه یک محیط آزمایشی داشته باشید. من با استفاده از محیط‌های آزمایشگاهی تقریبا همه‌ی چالش‌های احتمالی در روند پروژه را پیش‌بینی و تجربه کردم. البته قابلیت آزمایش کردن در مقیاس واقعی را نداشتم، اما به‌هرحال از کارساز بودن مراحل برنامه‌ریزی تاحدودی مطمئن شدم.
  • به تیم خود اعتماد کنید. اگرچه من مدیر و مسئول اصلی دیتابیس در استک‌ اورفلو هستم، برخی اوقات در اجرای روندها در فورمن یا پاپت به مشکل بر می‌خوردم. واقعا باید از کمک‌های اعضای تیم در حل چالش‌ها قدردانی کنم.
  • فراموش نکنید که با وجود همه‌ی برنامه‌ریزی‌ها، باز هم رخدادهای غیرقابل پیش‌بینی اتفاق می‌افتد. من دستورالعملی ۳۵ صفحه‌ای داشتم، اما در زمان وقوع باگ هیچ‌یک از بخش‌های آن کارآمد نبود.
  • در زمان خارج شدن اوضاع از کنترل، تحت استرس قرار نگیرید. چالش‌های متعددی در پروژه‌ی ما رخ داد و من از خستگی تیمم ناراحت می‌شدم. به‌هرحال فرایند به‌جای یک ماه، چهار ماه طول کشید و تأثیر منفی زیادی روی اعتماد به نفس ما داشت. با وجود همه‌ی مشکلات، ما به جلو پیش رفتیم و روند خود را بهبود دادیم. درنهایت حفظ چشم‌انداز از دستاورد نهایی، در عبور از چالش‌های فنی بسیار کارساز خواهد بود.
  • در زمان انجام فرایندهای پیاده‌سازی شبیه به پروژ‌ه‌ی ما، همیشه یادداشت‌برداری کنید. هر روز یادداشتی از رخدادها داشته باشید و همه‌ی اتفاق‌های مثبت و منفی رخ داده را بررسی کنید. در نوشتن این مقاله هم از همان یادداشت‌ها استفاده شد.

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

گرد آورنده
tarynpivots
منبع
zoomit.ir

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا