<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های محمدحسین کریمی</title><link>https://virgool.ir/feed/@mhkarimi1383</link><description>مهندس دوآپس و برنامه نویس علاقه مند به دنیای OpenSource</description><language>fa</language><pubDate>2026-11-12 10:08:39</pubDate><image><url>https://files.virgool.ir/upload/users/3441870/avatar/OteSNI.jpg</url><title>محمدحسین کریمی</title><link>https://virgool.ir/@mhkarimi1383</link></image><item><title>نجات MySQL از Corruption</title><link>https://virgool.ir/@mhkarimi1383/نجات-mysql-از-corruption-zv154yjlsdax</link><description>MySQL Logoخوب توی این مقاله به این اشاره شد که چه اتفاقی برای دیتابیس افتاد حالا اول دقیقتر بریم داخل سیستم ببینم چه بلایی سر دیتابیس اومدهموقع استارت شدن پروسس mysqld با خطاهای از قبیل خطای زیر مواجه میشدیم که حاکی از این بود که دیتابیس خود MySQL که دیتابیس مهمی هستش دچار مشکل شده (مثلا اینجا به جدولی که داره اطلاعات جداول رو نگهداری میکنه اشاره شده)[ERROR] [MY-012855] [InnoDB] Clustered record for sec rec not found index schema_id of table mysql.tablesInnoDB: sec index record PHYSICAL RECORD: n_fields 3; compact format; info bits 0و خوب راه حل هایی که معمولا پیدا میشدن به این اشاره میکردن که یه misconfiguration وجود داشته و عامل مموری لیک احتمالا شده یا یه سری پارامتر دیگه که طبق استفاده و نیاز تنظیم نشدن یا حتی بد موقع کرش کردهو خوب به تغییر کانفیگ یا force recovery توی لاگ استک تریس خود MySQL رو میگرفتیم که احتمال اتفاقاتی مثل مموری لیک رو بیشتر میکردمعمولا وقتی رخ میده که تو محیط های کلاود هستیم و دیتابیس از limit کانتینرش خبر نداره و خوب از کل مموری استفاده میکنه و برای جلوگیری ازش فقط باید دیتابیس رو بهینه کانفیگ کرد (مخصوصا موتور ذخیره سازی رو)تقریبا از استارت شدن دیتابیس نا امید شده بودیم چون دیتابیس اصلی mysql خراب شده بود و force recovery هم جواب نمیداد.بعد از گشتن توی ابزار های MySQL به یه ابزاری به اسم mysqlfrm پیدا کردیم که کارش این بوده که توی قبل از نسخه ۸ MySQL فایل های frm رو (که برای موتور ذخیره سازی MyISAM هستش) رو بخونه و دیتا رو بتونیم وارد کنیم. خوب دنبال یه همچین ابزاری برای نسخه ۸ بودیم (چون MyISAM دیگه استفاده نمیشد و جاشو به  InooDB داده بود) که خوشبختانه پیدا شد. به اسم idb2sdi که این کار رو برای موتور InnoDB انجام میداد.خوب حالا کار این ابزار چیه؟قبلش باید ببینیم که توی هر فایل idb چی ذخیره میشه؟ هر موتور ذخیره سازی توی MySQL به یه روشی داده ها و ساختار جداول رو نگهداری میکنه. موتور InnoDB از طریق sdi ساختار جداول رو و از طریق idb داده ها رو نگهداری میکنه ولی خوب به صورت پیشفرض برای هر جدول از ۱ فایل برای انجام این کار استفاده میکنه (اینکه به ازایه هر جدول فایل جدا استفاده یا نه هم قابل تنظیمه) یعنی توی فایل idb هم ساختار جدول (که میشه محتوای sdi) و هم داده ها رو ذخیره میکنهاین ابزار کارش جدا کردن اینا از  همه یعنی میتونیم به ساختار دیتابیس برسیم (البته خروجیش JSONعه) ولی میتونیم فایل روی Parse کنیم و جداول رو بازسازی کنیم)قدم بعدی برگردوندن دیتا هستشبه هر فایل idb ما میگیم tablespaceاول با این دستور tablespace پیشفرض مربوط به جدول رو از بین میبریم و به موتور دیتابیس میگیم که باهاش کاری نداشته باشهALTER TABLE `{tbl_name}` DISCARD TABLESPACE;و بعد از اون فایل idb رو توی یه همچین ادرسی کپی میکنیم:/var/lib/mysql/{databasename}/{tbl_name}.idbو با دستور زیر به موتور ذخیره سازی داده هامون میگیم که tablespace وارد شده رو لود کنه و ازش استفاده کنهALTER TABLE `{tbl_name}` IMPORT TABLESPACEو بعد از گذروندن این مراحل به ازایه هر جدول داده ها رو داریمنکته: اگه تو سرور قبلی ایندکس خراب داشته باشید اون ایندکس اینجا هم خرابه پس میتونیم اونا رو قبل شروع DROP کنیماین همه مرحله رو دستی انجام بدیم؟قطعا نه. مخصوصا وقتی که کلی جدول داریم و فرمت JSON مربوط به sdi باید کامل باهاش اشنا باشیم اونجا پر ENUM های داخلی مربوط به MySQL هستش و کلی چیز دیگه.بعد از کلی گشت و گذار توی گیت هاب یه ابزاری پیدا کردیم که این کار رو انجام میداد لینک گیتهاب قبل از استفاده ازش هم مطالعه کردیم که دقیقا همون کار رو انجام میده یا نه و هم اینکه توی یه محیط Sandbox تستش کردیم و دیدیم که ما رو به نتیجه دلخواه میرسونه.و از طریق اون دیتا رو تونستیم برگردونیم اما خوب یه مقدار اذیت کننده بود چون داکیومنت خوبی نداشت و باید کدشو میخوندیم و یه جاهایی هم حتی تغییر میدادیم که نتیجه دلخواه رو میدادالبته روز بعد تغییراتمون (که شامل پشتیبانی از یه سری فیلد خاص و داکیومنت بهتر و..) و همچنین پشتیبانی Docker و Kubernetes رو به این ابزار اضافه کردیم و تحت PR های متفاوت به کد اصلی اضافه کردیم.چیکار کنیم که اینجوری نشیم؟توی محیط هایی مثل K8s و Docker که محدودیت منابع تنظیم میکنید برای دیتابیس باید دیتابیس رو هم جوری کانفیگ بکنید که بیشتر از اون عدد مصرف نکنه (میتونید از Config Generator ها کمک بگیرید احتمالا) چون وقتی اطلاعات سیستم رو دیتابیس دریافت میکنه منابع هاست رو میبینه و خوب ممکنه دچار OOMKill بشید.حواستون حتما به GraceFullShutdown باشه (اگه حجم دیتابیس بالاست تایم اوتش رو هم زیاد کنیم که force kill نشه)</description><category>محمدحسین کریمی</category><author>محمدحسین کریمی</author><pubDate>Mon, 12 Aug 2024 22:54:51 +0330</pubDate></item></channel></rss>