مشکلات رایج در ریپلیکیشن My Sql

انجام ریپلیکیشن و یا همان رپلیکیشن در دیتابیس MySQL کار آسانی می باشد اما مدیریت این کار در فرایند تولید هیچگاه کار آسانی نبوده است حتی با استفاده از موقعیت یابی خودکار GTID های جدید نیز در صورت ندانستن درست نحوه کار، ممکن است همه چیز اشتباه پیش رود. پس از تنظیم ریپلیکیشن ممکن است تمامی عملکرد شما به یکباره با مشکل مواجه شود و اشتباهات، پایان فاجعه باری را برای داده های شما رقم بزنند.در ادامه این مطلب به بررسی چند اشتباه در ریپلیکیشن MySQL می پردازیم و به شما آموزش خواهیم داد که چگونه از آن ها جلوگیری کنید.به هنگام تنظیم ریپلیکیشن باید بهترین داده ها را از دیتابیس زیر مجموعه که به آن slave نیز گفته می شود را به دیتابیس اصلی که master نام دارد منتقل سازید. Galera ( در MySQL به دسته بندی های چند عامله ای گفته می شود که بر اساس رپلیکیشن همزمان شکل گرفته اند) می تواند به صورت خودکار بر اساس روش انتخابی شما انجام می شود. برای رپلیکیشن MySQL شما باید خودتان این کار را انجام دهید پس بر طبق عادت از ابزار بکاپ گیری استاندارد خود استفاده می کنید.خب حالا یه سری دستکاری ها وجود دارد که میشه انجام داد تا ابزار Mysql Dump دقیق تر شود و بتوان راحت تر به آن اطمینان کرد. به عنوان مثال قرار دادن دامپ(Dump) به عنوان ترنزکشن واحد و یا استفاده از رویه و تریگر.mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > dumpfile.sqlیک تمرین خوب برای اینکه ببینید آیا دیتابیس زیر مجموعه شما 100 درصد مشابه دیتابیس مستر است یا نه قرار دادن pt-table-checksumبعد از رپلیکیشن می باشد.pt-table-checksum --replicate=test.checksums --ignore-databases mysql h=localhost,u=user,p=passاین ابزار برای هر جدول مستر یک چک سام محاسبه می کند سپس دستور آن را رونویسی می کند و در دیتابیس زیر مجموعه عملکرد مشابهی را برای چک سام تعریف می کند. اگر هر کدوم از جدول ها مشابه نبودن باید در جدول چک سام ها به صورت واضح مشخص باشد.استفاده از روش های اشتباه در رپلیکیشن MySQLروش پیش فرض در انجام ریپلیکیشن MySQLاصطلاحا statement-based ( دستور محور) می باشد. این روش دقیقا همون چیزیه که دنبالشیم. در این روش هر گزاره ای که بر روی دیتابیس مستر اجرا می شود و سپس بر روی زیر شاخه slaveنیز مجددا تکرار می شود. اگر چه که خود MySQLچند شاخه ای می باشد اما ریپلیکیشن آن این قابلیت را ندارد پس هر دستوری در آن ممکن است در ریپلیکیشن 100 درصد اجرا نشود. بنابراین اجرای یک دستور ریپلیکیشن شده در رپلیکیشن ممکن است نتیجه ای یکسان با دیتابیس مستر نداشته باشد و دقیقا همان فرمان را اجرا نکند.این اتفاق سبب میشود تا دیتابیس مستر و Slave(زیر مجموعه) شما با یکدیگر تفاوت داشته باشند چرا که در اصل داده ها به اشتباه ذخیره شده اند. این مساله در زمان های گذاشته هیچ گونه مشکلی را ایجاد نمی کرد چرا که هیچ کس MySQL را به صورت همزمان با چند راه حل دیگر استفاده نمی کرد اما امروزه به علت مهندسی مدرن چند پردازنده ای (multi-CPU) احتمال ایجاد مشکل با حجم کار روزمره بوجود آمده است.حالا راه حل جدید MySQLاستفاده از روشی است که اصطلاحا row-based(ردیف محور) خوانده می شود. رپلیکیشن ردیف محور در حقیقت ریپلیکیشن را هر زمانی که ممکن باشد انجام می دهد اما در برخی موارد استثنا همچنان از روش قدیمی Statement استفاده می شود. یک مثال خوب برای درک این مفهوم فایل (DLL (Dynamic Link Libraryتغییرات یک جدول است، بدین ترتیب در زمان ریپلیکیشن نیز برای ردیف جدول یک کپی ریپلیکیشن ثبت می شود. اما هنگامی که این روش موثر نباشد ریپلیکیشن بر اساس همون روش قدیمی Statement پیش میره.ریپلیکیشن ردیف محور نیز هر زمانی که تشخیص بده ذخیره داده ها به اشتباه داره انجام میشه رپلیکیشن رو در دیتابیس زیر مجموعه متوقف میکنه تا از ایجاد خطا جلوگیری کنه.یک روش دیگه هم برای انجام رپلیکیشن در MySQLوجود دارد که بین این دو روش نام برده است. و بهش روش مختلط یا mixed mode هم گفته میشه. در این روش داده ها به صورت گزاره ای رونویسی میشن به غیر از مواقعی که کوئری های تابع ()UUID، تریگر، رویه های ذخیره (SP) ها، UDFs و برخی دیگر از استثنائات در حال استفاده هستند. روش مختلط و دستور محور به هنگام بروز مشکل، ذخیره سازی داده ها را حل متوقف نمی کنند.چرخه رپلیکیشناگر شما چند دیتا سنتر مختلف در اطراف خود داشته باشید لازمه که رپلیکیشن MySQL خود را با چند دیتابیس مستر انجام دهید. چرا که فرایند رونویسی نمیتونه منتظر تایید دیتابیس مستر شما از دیتا سنترهای دیگر شود به همین دلیل یک دیتابیس مستر محلی رو ترجیح میده. به طور معمول auto incrementیا همان افزایش خودکار به منظور جلوگیری از برخورد مسترها صورت میگیرد. داشتن دو مستر برای نوشتن به این روش قابل قبول می باشد.?حالا اگر شما قرار باشه که از چند دیتاسنتر داخل یک دیتابیس بنویسید، باید چند تا مستر داشته باشید که دیتا خود رو در دیگری می نویسن. قبل از نسخه 5.7.6 MySQL هیچ روشی برای ریپلیکیشن شبکه ای وجود نداشت برای همین راه حلش اینکه که از یک چرخه برای انجام ریپلیکیشن استفاده کنید.?چرخه ریپلیکیشن ممکنه بنابر چند دلیل مشکل ساز باشه: تاخیر، دسترسی بالا و ذخیره سازی داده. برای نوشتن برخی از دیتا ها در سرور A باید از سه سرور دیگه بپره تا به سرور D برسه. از آنجایی که انجام ریپلیکیشن در MySQL قدیمی تک شاخه ای بوده هر نوع انتقال با فاصله زیاد ممکن است موجب اختلال در کل چرخه شود. همچنین اگر هر کدوم از سرورها داون بشه، این چرخه دچار شکست می شود و در حال حاضر هیچ گونه نرم افزار failover یا همان غلبه بر خرابی ای وجود ندارد که بتواند این مشکل ایجاد شده در چرخه را حل نماید. سپس هنگامی که داده ها در حال نوشته شدن بر روی سرور A هستند به صورت همزمان در سرور D و C نیز تغییر پیدا می کنند و ذخیره سازی دیتا به اشتباه صورت می گیرد.?در کل چرخه ریپلیکیشن در MySQLچندان کاربردی نیست و هر جایی نباید ازش استفاده شه. به جای آن Galera می تونه یک متناوب خوب در انجام رپلیکیشن باشه چون که با توجه به همین مساله طراحی شده است.کارهای دسته ای عموما چندین وظیفه را انجام می دهند به عنوان مثال از پاک کردن دیتاهای قدیمی گرفته تا محاسبه لایک های دریافت شده از منابع دیگر.در انجام رپلیکیشن دستور محور نیز کوئری های استفاده شده به صورت دقیق در عملیات دسته ای ریپلیکیشن می شوند بنابراین اگر انجام کوئری در مستر نیم ساعت زمان ببرد در زیر شاخه و یا همان slaveنیز حداقل به نیم ساعت زمان نیاز دارند. این یعنی دیتاهای دیگر نمی توانند رونویسی شوند و زیرشاخه ها پس از مستر شروع به ایجاد تاخیر می کنند. اگر این تاخیر از آستانه ابزار فیل اور (غلبه بر خرابی) و یا پروکسی شما تجاوز کرد، احتمالا زیرشاخه های شما از دیتاهای در دسترس خارج شده و به دسته ها و یا همان کلاستر ها پیوسته اند. اگر در حال استفاده از روش دستور محور رپلیکیشن هستید می توانید از این مشکل جلوگیری کنید تنها باید دیتاهای خود را به دسته های کوچکتری تقسیم کنید.حالا ممکنه فکر کنید که رپلیکیشن ردیف محور ممکنه تحت تاثیر این مشکل قرار نگیرد. چرا که در این روش اطلاعات ردیف به جای کوئری رونویسی می شود. میشه گفت که این باور تا حدودی درسته هنگامی که DDLها تغییر می کنند ریپلیکیشن ها به فرمت دستور محور تغییر پیدا می کنند. همچنین شمار زیادی از عملیات های (CRUD) کرود بر روی جریان رپلیکیشن تاثیر می گذارند. در بسیاری از موارد این کار همچنان یک عملیات تک شاخه ای است و به همین دلیل هر ترنزکشن (تراکنش) برای تراکنش قبلی خود صبر می کند تا توسط ریپلیکیشن دو مرتبه اجرا شود. این یعنی اگر شما در مستر خود هم یک همزمانی مناسبی را داشته باشید، در زیرشاخه به علت این اتفاق تا حدودی وقفه را خواهید داشت.برای جلوگیری از این اتفاق MySQL و MariaDB هر دو رونویسی همزمان را پیشنهاد می کنند که پیاده سازی آن در هر وندور و ورژنی متفاوت می باشد. MySQL5.6 رونویسی همزمان رو در طول جداسازی کوئری توسط اسکیماها ارائه می دهد. در MariaDB 10.0 و MySQL5.7 رونویسی همزمان در سراسر اسکیماها صورت می گیرند اما حدود دیگری نیز دارند. در مقیاس های بزرگ انجام کوئری ها و رونویسی همزمان در زیر شاخه ها میتواند به جریان رپلیکیشن شما سرعت ببخشد. اما اگر مقیاس اطلاعات چندان زیاد نیست بهتر است از همان روش رونویسی تک شاخه ای استفاده کنید.تغییرات اسکیماهاانجام تغییرات اسکیماها در هنگامی که تولید در حال تنظیم است کاری بسیار سخت می باشد. در حقیقت در فایل های DLLاغلب جدول ها را قفل می کنند و هنگامی این قفل باز می شود که تغییرات ایجاد شده باشند. هنگامی شرایط سخت تر می شود که بخواهید این تغییرات در DDL ها را با استفاده از رپلیکیشن MySQL رونویسی کنید یعنی دقیقا جایی که انجام این کار در پروسه رپلیکیشن وقفه ایجاد می کند. در این زمان اغلب کاری که انجام می شود این است که در ابتدا تغییرات اسکیماها را بر روی زیرشاخه ها اعمال می کنند. در روش دستور محور این کار موثر است اما در روش ردیف محور این کار تا به حدی پاسخگو می باشد. رپلیکیشن ردیف محور ستون های اضافی را در انتهای جدول قرار می دهد بنابراین تا جایی که بتواند در ستون اول چیزی نوشت استفاده از این روش موثر است. پس در ابتدا تغییرات را در تمامی زیر شاخه ها اعمال کنید و سپس تغییرات را به مستر انتقال دهید و آن ها را به عنوان یک زیر مجموعه به مستر متصل سازید. اگر تغییرات شما شامل افزودن یک ستون به میانه و یا ابتدای جدول شد این کار در روش ردیف محور نیز پاسخگو بوده است.ابزارهایی نیز وجود دارند که می توانند تغییرات اسکیماها را به صورت آنلاین و با دقت بالاتری انجام دهند. The Percona Online Schema Change که اصولا به صورت pt-oscشناخته می شود یک جدول مشابه با ساختار جدول قبلی می سازد و دیتاهای جدید را با استفاده از تریگر به آن می افزاید و در بکگراند مجدد داده ها را پر می کند. هنگامی که مراحل تولید جدول جدید تمام شد به سادگی آن را با جدول قدیمی جا به جا می کند. البته این کار در همه موارد پاسخگو نیست به خصوص در مواردی که جدول قدیمی شما از تریگر برخوردار باشد.?ابزار دیگر Gh-ost می باشد که در ابتدا از چیدمان حال حاضر جدول های شما یک نسخه کپی تهیه می کند سپس چیدمان جدول ها را تغییر می دهد و آن را به پروسه رونویسی در MySQLمتصل می کند. این ابزار، پروسه رونویسی را با یافتن ردیف های جدید که به جدول های قدیمی متصل شده اند مشغول می کند و به صورت همزمان جدول را پر می کند. به محض تمام شدن پر کردن جداول، جدول های قبلی و جدید تغییر می کنند.طبیعتا هر تغییری در جدول ها به جریان رونویسی هم منتقل می شود بنابراین ریپلیکیشن و تغییر به صورت همزمان صورت میگیرد.جدول های حافظه و رپلیکیشناز آنجایی که در این مطلب موضوع اصلی ما DDLها هستند، یک مشکل رایج ایجاد جدول های حافظه می باشد. جدول های حافظه، گذرا و یا به عبارتی نا مانا(non-persistent) میباشند. جدول های آن ها پس از ریست کردن MySQLباقی می ماند اما داده های درون این جدول ها پاک می شود. به هنگام ایجاد جدول حافظه در مستر و زیر مجموعه در هر دو یک جدول خالی دارند که به صورت بی نقصی کار می کند. اما به محض اینکه هر یک از آن ها ری استارت شود تمامی داده ها پاک می شود و ارور های رپلیکیشن بوجود می آیند. رپلیکیشن ردیف محور به هنگام ایجاد نتایج متفاوت در زیرمجموعه ها متوقف می شود و رپلیکیشن دستور محور نیز به هنگام تلاش برای ایجاد داده هایی که از پیش وجود دارند و در اصل تکراری می شوند متوقف خواهد شد. در جدول های حافظه این یکی از رایج ترین اتفاقاتی است که سبب توقف در پروسه رپلیکیشن می شود. اما درست کردن آن بسیار آسان می باشد. تنها نیاز است تا یک نسخه فرش از داده های خود تهیه کنید و موتور را به InnoDBتغییر دهید حال با خیال راحت به رونویسی دیتا خود مشغول شوید.متغییر read-only را بر روی True تنظیم کنیدهمانطور که پیش از این تاکید کردیم نداشتن دیتا مشابه در زیر مجموعه ها به سادگی می تواند سبب توقف رپلیکیشن شود. این اتفاق می تواند در اثر یک کار خاص و یا فرد خاصی که دیتا را در زیر مجموعه تغییر داده است اما در مستر این تغییر را ایجاد نکرده است، بوجود آید. به محض تغییر داده ها در مستر،این دیتا در زیر مجموعه نیز رونویسی می شوند و از آنجایی که در زیر مجموعه امکان تغییر وجود ندارد پروسه رپلیکیشن دچار مشکل شده و متوقف می شود.اما یک راه ساده برای جلوگیری از این اتفاق وجود دارد. شما باید متغییر read-only را بر روی True تنظیم کنید. با این کار شما به هیچ کس اجازه ایجاد تغییر در داده ها را نمی دهید بجز کاربران رپلیکیشن و روت. بسیاری از مدیران فیل اور (غلبه بر شکست) این علامت را به صورت خودکار بر روی گزینه True ست می کنند تا در هنگام فیل اور به صورت خودکار از ایجاد تغییر کاربران در مستری که از آن برای رونویسی استفاده می شود جلوگیری کنند و حتی بعضی ها بعد از انجام فیل اور نیز این تنظیم رو بهم نمی ریزن و حفظش می کند.این کار همچنان به کاربران روت اجازه می دهد تا بر روی کوئری های CRUD تغییرات ایجاد کنند اما در نسخه MySQL5.7.8 یک آپشن مجهزتر به نام super_read_onlyدر نظر گرفته شده که حتی دسترسی کاربران روت را برای ایجاد تغییرات نیز قفل می کند.فعال سازی GTIDبرای MySQLابزارهای مختلفی برای بکاپ گیری وجود دارد اما رایج ترین آن ها MySq Dump نام دارد که یک بکاپ کامل از دیتابیس مستر شما استخراج می کند. بدین ترتیب داده های شما به صورت یک کپی دوگانه نخواهند بود بلکه یک فایل بزرگ با کوئری های مختلف است که پایگاه داده های شما را از نو می سازد. در حالت عادی باید نسخه بکاپ مشابه نسخه اصلی باشد اما در برخی موارد متغیر است و این یعنی دیتابیس زیر مجموعه قبل از انجام رپلیکیشن نیز مانند دیتابیس مستر نبوده است.mysql> CHANGE MASTER TO MASTER_HOST='x.x.x.x',MASTER_USER='replication user', MASTER_PASSWORD='password', MASTER_LOG_FILE='master-bin.0001', MASTER_LOG_POS= 04;انتخاب نقطه اشتباه برای شروع رپلیکیشن عواقب فاجعه باری را همراه خواهد داشت: داده ها ممکن است دوبار نوشته شوند و یا آپدیت نشوند و این اتفاق سبب ایجاد ذخیره متفاوت داده ها در مستر و زیر مجموعه می شود.همچنین به هنگام انتقال داده ها از مستر به زیر مجموعه ها نیز پیدا کردن موقعیت درست برای جایگذاری و شناسایی مستر به عنوان یک هاست مناسب می باشد.به منظور حل این سری مشکلات Global Transaction Identifier یا همان GTIDتوسط پایگاه داده اوراکل و پایگاه داده محبوب برای طراحی وب یعنی MariaDB اجرا شده است. GTIDها به شما اجازه می دهند تا به صورت خودکار زیر مجموعه های خود را در یک سطح قرار دهید همچنین در هر دو MySQL و MariaDBسرور خود تشخیص می دهد که موقعیت درست کجاست. هر چند که هر دو با روش های متفاوت توسط GTID اجرا می شوند و متضاد یکدیگر می باشند. اگر نیاز است تا رپلیکیشن خود را از یکی به دیگری تغییر دهید این کار باید با استفاده از روش قدیمی رونویسی توسط موقعیت یابی binary log صورت گیرد. همچنین باید نرم افزار فیل اور خود را از این مساله که در این مورد نباید از GTIDاستفاده کند آگاه سازید.نتیجه گیریامیدواریم که در این مقاله به اندازه کافی آگاهی های لازم را دریافت کرده باشید تا در هنگام انجام رپلیکیشن با مشکل مواجه نشوید. تمامی مطالب گفته شده در این مطلب توسط متخصصین و در طی انجام کار و تلاش های گردآوری شده اند؛ امید است تا شما به سادگی از لذت کار با آن ها بهره مند شوید.