چگونه با استفاده از Liquibase به پای خود شلیک نکنید؟

هرگز اتفاق نیفتاد و دوباره اینجاست!

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

این مقاله شامل نکات مفید و توضیحاتی در مورد سه مورد از بدیهی ترین مشکلاتی است که می توانید هنگام کار با ابزارهای مهاجرت پایگاه داده رابطه ای، به ویژه Liquibase، در آن قرار بگیرید. برای توسعه دهندگان جاوا در سطح جونیور و متوسط ​​طراحی شده است، برای توسعه دهندگان با تجربه تر ممکن است برای ساختاردهی و تکرار آنچه به احتمال زیاد قبلاً شناخته شده است جالب باشد.

چگونه با استفاده از Liquibase به پای خود شلیک نکنید؟

Liquibase و Flyway فناوری‌های رقیب اصلی برای حل مشکلات کنترل نسخه ساختارهای رابطه‌ای در دنیای جاوا هستند. اولین مورد کاملاً رایگان است ، در عمل بیشتر برای استفاده انتخاب می شود ، به همین دلیل Liquibase به عنوان قهرمان انتشار انتخاب شد. با این حال، بسته به معماری برنامه شما، ممکن است برخی از روش های توصیف شده عمومی باشند.

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

من در توضیح فناوری و دستورالعمل های اضافه کردن کتابخانه به پروژه شما نمی پردازم، مقالات کافی در این زمینه نوشته شده است:

علاوه بر این، قبلاً یک مقاله عالی با موضوع نکات مفید وجود داشت:

Советы

می‌خواهم توصیه‌ها و نظراتم را که با عرق و خون و درد حل مشکلات مهاجرت به دنیا آمد، به اشتراک بگذارم.

1. قبل از شروع، باید بخش بهترین روش ها را بخوانید کاربران آنلاین حاضر در سایت " Liquibase

در آنجا چیزهای ساده اما بسیار مهمی توضیح داده شده است که بدون آنها استفاده از کتابخانه می تواند زندگی شما را پیچیده کند. به عنوان مثال، یک رویکرد غیر ساختاری برای مدیریت تغییرات دیر یا زود منجر به سردرگمی و مهاجرت های شکسته می شود. اگر به طور همزمان تغییرات وابسته به دو طرف را در ساختار پایگاه داده و منطق سرویس ها ایجاد نکنید، احتمال زیادی وجود دارد که منجر به تست های قرمز یا یک محیط خراب شود. علاوه بر این، توصیه‌هایی برای استفاده از Liquibase در وب‌سایت رسمی شامل یک پاراگراف در مورد توسعه و تأیید اسکریپت‌های برگشتی به همراه اسکریپت‌های مهاجرت اصلی است. خوب، در مقاله https://habr.com/ru/post/178665/ نمونه هایی از کد مربوط به مهاجرت و مکانیسم بازگشت وجود دارد.

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

به قول معروف: «یک بار پرسیل، همیشه پرسیل». اگر پایه برنامه شما توسط ابزارهای Liquibase مدیریت می شود، هر گونه تغییر دستی فوراً منجر به یک حالت ناسازگار می شود و سطح اعتماد به تغییرات مجموعه صفر می شود. خطرات احتمالی - چندین ساعت صرف بازیابی پایگاه داده، در بدترین حالت - یک سرور مرده. اگر تیم شما یک معمار DBA "مدرسه قدیمی" دارد، با حوصله و متفکرانه به او توضیح دهید که اگر فقط پایگاه داده را به روش خودش از SQL Developer شرطی ویرایش کند، اوضاع چقدر بد خواهد بود.

3. اگر مجموعه تغییرات قبلاً به مخزن منتقل شده است، از ویرایش خودداری کنید

اگر توسعه‌دهنده دیگری تغییر مجموعه‌ای را کشیده و اعمال کند که بعداً ویرایش می‌شود، هنگام شروع برنامه، قطعاً شما را با یک کلمه مهربان به یاد می‌آورد. اگر ویرایش تغییرات به نحوی در توسعه ظاهر شود، باید از شیب لغزنده رفع‌های فوری پایین بروید. ماهیت مشکل بر اعتبار سنجی تغییرات با مجموع هش است - مکانیسم اصلی Liquibase. هنگام ویرایش کد تغییرات مجموعه، مجموع هش تغییر می کند. ویرایش تغییرات فقط زمانی امکان پذیر است که امکان استقرار کل پایگاه داده از ابتدا بدون از دست دادن داده ها وجود داشته باشد. در این حالت، برعکس، تغییر کد SQL یا XML می‌تواند زندگی را آسان‌تر کند، مهاجرت‌ها را خواناتر کند. یک مثال می تواند موقعیتی باشد که در شروع برنامه، طرح پایگاه داده منبع در تیم هماهنگ شده بود.

4. در صورت امکان پشتیبان‌گیری از پایگاه داده را تأیید کنید

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

5. در صورت امکان از پشتیبان گیری از پایگاه داده تایید شده در توسعه استفاده کنید

اگر این با قراردادها و حریم خصوصی تناقض نداشته باشد، هیچ داده شخصی در پایگاه داده وجود ندارد، و وزن آن مانند دو خورشید نیست - قبل از اعمال آن در سرورهای مهاجرت زنده، می توانید نحوه عملکرد آن را در دستگاه توسعه دهنده بررسی کنید و تقریباً 100٪ از مشکلات احتمالی در طول مهاجرت را محاسبه کنید.

6. با توسعه دهندگان دیگر تیم چت کنید

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

7. فکر کن چه کار می کنی!

توصیه های ظاهرا بدیهی قابل اجرا در هر موقعیتی. با این حال، اگر توسعه‌دهنده یک بار دیگر آنچه را که انجام می‌دهد و چه چیزی ممکن است تأثیر بگذارد، تجزیه و تحلیل می‌کرد، می‌توان از بسیاری از مشکلات جلوگیری کرد. کار با مهاجرت همیشه نیاز به توجه و دقت بیشتری دارد.

تله ها

بیایید اکنون نگاهی به تله‌های معمولی بیندازیم که اگر توصیه‌های بالا را رعایت نکنید، می‌توانید در آن گرفتار شوید و در واقع چه باید کرد؟

موقعیت 1. دو توسعه دهنده در تلاش هستند تا تغییرات جدیدی را به طور همزمان اضافه کنند

چگونه با استفاده از Liquibase به پای خود شلیک نکنید؟
Vasya و Petya می خواهند بدون اینکه از یکدیگر اطلاعی داشته باشند یک تغییر مجموعه نسخه 4 ایجاد کنند. آنها تغییراتی را در ساختار پایگاه داده ایجاد کردند و یک درخواست کشش را با فایل های تغییرات مختلف ارائه کردند. مکانیسم زیر در زیر پیشنهاد شده است:

چگونه حل کنیم

  1. به نحوی، همکاران باید در مورد ترتیبی که تغییرات آنها باید انجام شود، توافق کنند، فرض کنید ابتدا باید Petin اعمال شود.
  2. یک نفر باید دیگری را بریزد و تغییرات Vasya را با نسخه 5 علامت گذاری کند. این کار را می توان از طریق Cherry Pick یا یک ادغام منظم انجام داد.
  3. پس از تغییرات، حتما صحت اقدامات انجام شده را بررسی کنید.
    در واقع، مکانیسم‌های Liquibase به شما این امکان را می‌دهند که دو مجموعه تغییرات نسخه 4 را در مخزن داشته باشید، بنابراین می‌توانید همه چیز را همانطور که هست رها کنید. یعنی شما به سادگی دو نسخه از نسخه 4 را با نام های مختلف خواهید داشت. با این رویکرد، مرور نسخه های پایگاه داده بعداً بسیار دشوار می شود.

علاوه بر این، Liquibase، مانند خانه های هابیت ها، اسرار زیادی را حفظ می کند. یکی از آنها کلید validCheckSum است که از نسخه 1.7 ظاهر شده است و به شما امکان می دهد بدون توجه به آنچه در پایگاه داده ذخیره شده است، یک مقدار هش معتبر برای یک مجموعه تغییرات خاص مشخص کنید. مستندات https://www.liquibase.org/documentation/changeset.html زیر می گوید:

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

بله، این توصیه نمی شود. اما گاهی اوقات یک شعبده باز نور قوی به تکنیک های تاریک نیز تسلط دارد.

مورد 2: مهاجرت مبتنی بر داده

چگونه با استفاده از Liquibase به پای خود شلیک نکنید؟

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

در واقع این امکان پذیر است و هیچکس از این امر مصون نیست. این در صورتی اتفاق می افتد که تغییرات در ساختار جدول به نحوی با داده های خاصی از پایگاه داده مرتبط باشد. بدیهی است که اگر پایگاه داده Petya فقط با داده های آزمایشی پر شود، ممکن است همه موارد مشکل را پوشش ندهد. به عنوان مثال، هنگام حذف یک جدول، معلوم می شود که رکوردهایی در جداول دیگر توسط کلید خارجی مرتبط با رکوردهایی در جدول در حال حذف وجود دارد. یا هنگام تغییر نوع ستون، معلوم می شود که 100% داده ها را نمی توان به نوع جدید تبدیل کرد.

چگونه حل کنیم

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

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

وضعیت 3. Liquibase پس از تولید شروع به استفاده می کند

فرض کنید رهبر تیم از Petya خواسته است که Liquibase را در پروژه قرار دهد، اما پروژه در حال حاضر در حال تولید است و یک ساختار پایگاه داده از قبل موجود است.

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

چگونه حل کنیم

همچنین چندین راه وجود دارد:

  • اولین و واضح ترین آن داشتن یک اسکریپت مجزا است که باید به صورت دستی در هنگام راه اندازی یک محیط جدید اعمال شود.
  • دومی که کمتر واضح است، داشتن یک مهاجرت Liquibase است که در یک زمینه Liquibase متفاوت است و آن را اعمال می‌کند. در اینجا می توانید اطلاعات بیشتری در مورد Liquibase Context بخوانید: https://www.liquibase.org/documentation/contexts.html. به طور کلی، این یک مکانیسم جالب است که می تواند با موفقیت به عنوان مثال برای آزمایش استفاده شود.
  • مسیر سوم از چند مرحله تشکیل شده است. ابتدا باید یک مهاجرت برای جداول موجود ایجاد شود. سپس باید در محیطی اعمال شود و به این ترتیب مجموع هش آن به دست می آید. گام بعدی این است که جداول Liquibase خالی را روی سرور غیرخالی خود مقداردهی کنیم و می‌توانید به صورت دستی یک رکورد از یک مجموعه تغییرات "مانند اعمال" را با تغییراتی که قبلا در پایگاه داده وجود دارد را در جدولی با سابقه اعمال تغییرات قرار دهید. بنابراین، در یک سرور از قبل موجود، تاریخچه از نسخه 2 شروع می شود و همه محیط های جدید یکسان رفتار می کنند.
    چگونه با استفاده از Liquibase به پای خود شلیک نکنید؟

سناریوی 4: مهاجرت ها بسیار زیاد می شوند و نمی توانند ادامه پیدا کنند

در ابتدای توسعه سرویس، به عنوان یک قاعده، Liquibase به عنوان یک وابستگی خارجی استفاده می شود و همه مهاجرت ها هنگام شروع برنامه پردازش می شوند. با این حال، با گذشت زمان، ممکن است به موارد زیر برخورد کنید:

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

چگونه حل کنیم

در چنین مواردی، پروژه شما در حال حاضر بزرگ است، شاید حتی یک بزرگسال، و Liquibase به عنوان یک ابزار خارجی جداگانه عمل می کند. واقعیت این است که Liquibase، به عنوان یک کتابخانه، در یک فایل jar مونتاژ می شود و می تواند به عنوان یک وابستگی در پروژه و همچنین به صورت مستقل کار کند.

به‌صورت آفلاین، می‌توانید اعمال مهاجرت‌ها را به محیط CI/CD خود یا به شانه‌های قوی sysadmin/deployer خود واگذار کنید. برای این کار به خط فرمان Liquibase نیاز دارید https://www.liquibase.org/documentation/command_line.html. در این حالت، پس از انجام تمام مهاجرت های لازم، راه اندازی برنامه امکان پذیر می شود.

نتیجه

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

منبع: www.habr.com

اضافه کردن نظر