قطعی GitHub: وقتی محافظ دیتابیس به متریک اشتباه نگاه میکرد
خلاصهٔ کاملتر
لورین هاکستاین که دربارهٔ تابآوری سیستمها (resilience) مینویسه، این بار گزارش قطعی ۱۳ سپتامبر GitHub رو بررسی کرده. به گفتهٔ اون GitHub داره تاوان رونق AI رو میده، چون توسعهدهندههای بیشتری با ابزارهای AI فشار بیشتری روی سیستمش میارن. ماجرا از یه job پاکسازی دیتا شروع شد که ساعت 07:33 UTC شروع کرد به نوشتن روی یه کلاستر دیتابیس مشترک. این کلاستر دادههای دسترسی (permission) رو نگه میداره که تقریباً تو هر درخواست لاگینشده خونده میشه.
سرعت این job رو یه safeguard کنترل میکرد، یعنی سیستمی که اگه دیتابیس ناسالم به نظر برسه سرعت کوئریها رو کم میکنه. مشکل این بود که فقط replica lag رو نگاه میکرد (یعنی اینکه کپیهای فقطخوندنی چقدر از سرور اصلی عقبن). replicaها سالم بودن، ولی خود primary که همهٔ نوشتنها رو انجام میده به سقف کانکشن رسید. تو MySQL این سقف با max_connections تعیین میشه و بعدش هر کانکشن جدید خطای Too many connections میگیره.
از اینجا دو چیز اوضاع رو بدتر کرد. اول، درخواستهای وب سریع fail نمیشدن و چون timeoutشون طولانی بود منتظر میموندن؛ این درخواستهای معطل روی هم تلنبار شدن و خود وبسرورها رو اشباع کردن و خطا کل سایت رو گرفت. دوم، یه حلقهٔ retry تو بخش ساخت توکن مدام نوشتنهای شکستخورده رو دوباره میفرستاد و نمیذاشت دیتابیس نفس بکشه. حادثه ساعت 08:50 اعلام شد و با کمکردن بار داخلی و متوقفکردن job، همهٔ سرویسها تا 10:44 برگشتن.
نویسنده این رو یه نمونهٔ کلاسیک gray failure میدونه، یعنی وقتی مانیتورینگ داخلی میگه همهچیز سالمه ولی کاربرا ناراضیان. به گفتهٔ اون هیچوقت دقیق نمیدونیم مرز امن سیستم کجاست تا وقتی ازش رد بشیم، و اونقدر محدودیت تو سیستم هست که احتمال جاافتادن یکی از مانیتورینگ بالاست. نویسنده یادآوری میکنه پاکسازی دولبهست: نگهداشتن چیزای بلااستفاده ریسکه، ولی خود پاکسازی هم یه تغییر پرریسکه.
نکتهٔ جالب دیگه، عدم تقارن timeoutهاست. timeout کوتاه رو زود میفهمی چون تو کار عادی خطا میده، ولی timeout طولانی معمولاً تا وقتی تو یه حادثه نقش بازی نکنه دیده نمیشه. retry هم همینطوره: خطاهای گذرا رو از کاربر پنهون میکنه، ولی موقع اشباع میتونه به retry storm تبدیل بشه. نویسنده توصیه میکنه از قبل ابزاری بسازید که وسط حادثه بشه سریع فهمید بار از کدوم کوئریها و از طرف کی میاد و دستی جلوشون رو گرفت.
راهحلهای GitHub شامل rate limit پیشفرض برای jobهای پسزمینه روی دیتابیسهای مشترک، مکث و هشدار خودکار بر اساس بار primary، timeout در سطح درخواست، محدودکردن retry در مسیر صدور توکن و شکستن این کلاستر تو دو هفتهٔ آیندهست. نویسنده همهشون رو خوب میدونه، ولی میگه همهشون پیچیدگی اضافه میکنن؛ یعنی خطاهای شناختهشده رو حذف میکنن و در عوض خطاهای تازه میارن.
نکات کلیدی:
- job پاکسازی ساعت 07:33 UTC شروع شد، حادثه 08:50 اعلام شد و سرویسها تا 10:44 UTC برگشتن.
- safeguard فقط replica lag رو نگاه میکرد و فشار روی primary رو نمیدید.
- primary به سقف max_connections رسید و timeoutهای طولانی خطا رو به کل سایت کشوند.
- retry پشتسرهم تو ساخت توکن، دیتابیس رو اشباع نگه داشت.
- GitHub قراره دادههای authorization رو ظرف دو هفته از این کلاستر مشترک جدا کنه.




