باگ ۱۶ سالهٔ SQLite که شش ماه Tailscale رو زمین زد
خلاصهٔ کاملتر
تو یه پست از بلاگ Tailscale، تیم مهندسی این شرکت توضیح داده چرا آپتایمشون از اواخر پارسال بههم ریخت: در مجموع ۱۹ بار دیتابیس یکی از شاردهاشون خراب شد. کنترلپلین Tailscale به چند شارد تقسیم شده و هر شارد یه دیتابیس SQLite داره که فقط یه پروسهٔ Go بهش دسترسی داره — دقیقاً همون مدل تکنویسندهای که SQLite براش ساخته شده.
به گفتهٔ نویسنده، پیدا کردن باگ کابوس بود. هیچ عامل مشترکی بین حادثهها پیدا نشد؛ نه شارد خاصی، نه مشتری خاصی، نه ساعت یا بار مشخصی. چون قابل بازتولید نبود، مجبور شدن تلهمتری فارنزیک رو تو محیط زنده بذارن و منتظر بمونن. یه بازهٔ ششهفتهای هم اصلاً خرابی رخ نداد که کار رو سختتر کرد. آخرش سراغ قرارداد پشتیبانی حرفهای خود توسعهدهندههای SQLite رفتن.
سرنخ اصلی از یه پایپلاین لاگ تراکنش اومد: تو دو حادثه، دادهای که یه تراکنش نوشته و کامیت کرده بود برای تراکنشهای بعدی نامرئی بود — یه نوشتن که بدون هیچ خطایی غیب شده بود. بعد از اون، توسعهدهندههای SQLite یه شیم دیباگ روی لایهٔ virtual filesystem به اسم tmstmpvfs ساختن و Tailscale اونو تو پروداکشن دیپلوی کرد تا حادثهٔ بعدی رو مچ بگیره.
خود باگ یه data race بین چکپوینت و تراکنش نوشتنه. اگه نوشتن دقیقاً تو لحظهٔ خاصی از چکپوینت اتفاق بیفته، پروسهٔ چکپوینت خیال میکنه یه سری صفحه از فایل WAL به دیتابیس اصلی کپی شدن، ولی نشدن؛ اون دادهها برای همیشه از دست میرن و چون صفحههای دیگهای مثل ایندکس بهشون ارجاع میدن، فایل خراب میشه. فیکسش یه بررسی اضافه به تابع چکپوینته که تشخیص میده WAL توسط ترد دیگهای ریست شده.
انتشار فیکس هم بیدردسر نبود. نسخهٔ ۳.۵۲.۰ یه بهینهسازی داشت که رفتار گِرد کردن تبدیل متن به عدد اعشاری رو کمی عوض کرد و باعث شد ۱۳ دیتابیس اشتباهاً خراب گزارش بشن — مشکلی که به ایندکسهای عبارتی کهنه برمیگشت. اون نسخه پس گرفته شد و بهجاش ۳.۵۱.۳ فقط با فیکس WAL-Reset منتشر شد. نویسنده میگه درس اصلی اینه که استفادهٔ غیراستاندارد از یه فناوری کسلکننده و مطمئن، خودش یه ریسکه.
نکات کلیدی:
- ۱۹ بار خرابی دیتابیس تو شش ماه، همه از یه data race نادر بین چکپوینت و تراکنش نوشتن تو SQLite
- باگ WAL-Reset دستکم ۱۶ سال تو SQLite بوده و برای تست باید عمداً تریگر میشد
- شیم tmstmpvfs روی لایهٔ virtual filesystem ابزاری بود که آخرش باگ رو لو داد
- نسخهٔ ۳.۵۲.۰ بهخاطر مشکل ایندکس عبارتی کهنه پس گرفته شد؛ فیکس واقعی تو ۳.۵۱.۳ اومد
- درس اصلی: هرچقدر هم فناوریت مطمئن باشه، استفادهٔ غیراستاندارد ازش ریسک داره




