Flyway’dan amalda foydalanish

Flyway’dan amalda foydalanish

- Yuklab olinadigan va yangilanadigan ilovalar uchun ma’lumotlar bazasi migratsiyalarini boshqarish -

1. Kirish

Ilovani ishlab chiqayotganingizda, funksiyalar o‘zgarishi bilan birga ma’lumotlar bazasi sxemasi ham o‘zgarishda davom etadi. Siz yangi jadvallar qo‘shishingiz, mavjud ustunlar turlarini o‘zgartirishingiz yoki ma’lumotlar tuzilmasining o‘zini o‘zgartirish jarayonida mavjud ma’lumotlarni yangi tuzilmaga ko‘chirishingiz kerak bo‘lishi mumkin.

Odatdagi veb-xizmat uchun ma’lumotlar bazasidagi bu o‘zgarishlarni joylashtirish jarayonining bir qismi sifatida boshqarish mumkin. Agar ishlab chiqish jamoasi server va ma’lumotlar bazasi muhitlarini ham boshqarsa, ilovani joylashtirish bilan birga zarur SQL so‘rovlarini ham bajarishi mumkin.

Biroq men ishlab chiqayotgan Vizend Platform uchun talablar biroz boshqacha.

Vizend ilovasi faqat bitta markaziy serverda ishlamaydi; foydalanuvchilar uni o‘z muhitlariga yuklab olib, o‘rnatishlari mumkin. O‘rnatilgandan so‘ng, yangi versiya chiqarilganda ilovani yana yuklab olishlari yoki yangilashlari mumkin.

Boshqacha qilib aytganda, ilova Yuklab olinadiganva ayni vaqtda Yangilanadigan.

Bunday tuzilmada faqat ilova kodini yangilash yetarli emas. Agar kodning yangi versiyasi yangi ma’lumotlar bazasi sxemasini talab qilsa, ilovani yangilash jarayonining bir qismi sifatida ma’lumotlar bazasi sxemasi ham o‘zgartirilishi kerak.

Masalan, ilovaning 7.1 versiyasi quyidagi jadvaldan foydalanadi, deb faraz qilaylik.

user

├─ id

└─ name

Agar 7.2 versiyasida yangi funksiya qo‘shilsa va ilova status ustunidan foydalanadigan qilib o‘zgartirilsa, quyidagi sxema talab qilinadi.

user

├─ id

├─ name

└─ status

Agar ma’lumotlar bazasi 7.1 versiyasi holatida qolgan paytda faqat ilova 7.2 versiyasiga yangilansa, ilova muvaffaqiyatli ishga tushgan taqdirda ham normal ishlay olmaydi.

Oxir-oqibat, biz uchun ilovani yangilash quyidagi ikki narsani birgalikda anglatardi.

Ilovani yangilash

        │

      ├─ Ilova versiyasini yangilash

       │

      └─ Ma’lumotlar bazasi sxemasini yangilash

Eng muhimi, ishlab chiquvchilar foydalanuvchilar ilovani o‘rnatgan har bir muhitdagi ma’lumotlar bazalariga bevosita kira olmaydi va SQL so‘rovlarini bajara olmaydi.

Shuning uchun, agar ilova o‘zini o‘zi yangilay olsa, ushbu ilova talab qiladigan ma’lumotlar bazasi sxemasi ham Runtime vaqtida avtomatik yangilana olishi kerak.

Bu muammoni hal qilish uchun Flyway’ni joriy qildik va ilova Runtime’iga ma’lumotlar bazasi migratsiyasini kiritdik.

Ushbu maqolada Flyway’dan foydalanish usuliga e’tibor qaratish o‘rniga, Flyway’ni haqiqiy loyihaga qo‘llashda duch kelgan muammolarimiz va shu jarayon davomida shakllantirgan migratsiya tamoyillarimizga e’tibor qarataman.

2. Flyway bilan tanishish

Flyway’ni birinchi marta joriy qilganimizda, uning vazifasi nisbatan sodda bo‘ladi, deb kutgandik.

Biz ma’lumotlar bazasidagi har bir o‘zgarishga Versiya beradigan migratsiya skriptlarini yozardik va ilova ishga tushganda, u hali bajarilmagan migratsiyalarni avtomatik qo‘llardi.

Masalan, migratsiya skriptlarini quyidagicha yozamiz.

V7_1_1__Create_User.sql
V7_1_2__Modify_User.sql
V7_1_3__Create_Position.sql

Flyway allaqachon bajarilgan va hali bajarilmagan migratsiyalarni ajratish uchun ma’lumotlar bazasidagi flyway_schema_history jadvalini tekshiradi.

Shu sababli, ilovaning yangi versiyasi ishga tushganda, zarur sxema o‘zgarishlari ham bir vaqtning o‘zida qo‘llanishi mumkin.

Spring Boot ilovamizda Flyway’ni yoqdik va Hibernate’ni sxemani bevosita o‘zgartirmasdan, faqat uni tekshiradigan qilib sozladik.

spring:
  flyway:
    enabled: true
  jpa:
    hibernate:
      ddl-auto: validate

Shu tariqa, Flyway ma’lumotlar bazasi sxemasini o‘zgartirish uchun, Hibernate esa Entity’lar va amaldagi ma’lumotlar bazasi sxemasi o‘rtasidagi muvofiqlikni tekshirish uchun javobgar bo‘ladi.

Dastlab, buning o‘zi ma’lumotlar bazasi migratsiyasi bilan bog‘liq muammolarning aksariyatini hal qiladi, deb o‘ylagandik.

Biroq haqiqiy xizmatni ishlab chiqib, bir nechta Versiya yangilanishlarini amalga oshirar ekanmiz, faqat “SQL so‘rovlarini tartib bilan avtomatik bajarish”asosida xavfsiz migratsiya yaratish qiyinligini angladik.

Ushbu jarayon davomida migratsiya yozishda quyidagi uchta jihatni eng muhim deb hisoblay boshladik.

Xuddi shu migratsiya yana bir marta bajarilsa, bu xavfsiz bo‘ladimi?

Muammo yuzaga kelsa, avvalgi holatga qaytarish mumkinmi?

Avvalgi holatga qaytish uchun zarur ma’lumotlar saqlab qolinganmi?

Har bir Idempotentlik, qaytarish, zaxiralash... bilan bog‘liq muammo

3. Migratsiyaning birinchi tamoyili: idempotentlik

Flyway’ning versiyalangan migratsiyasi muvaffaqiyatli yakunlangandan so‘ng o‘sha migratsiyani qayta bajarmaydi.

Bu migratsiya uchun SQL’ni haqiqatan ham idempotent tarzda yozish zarurmi, degan savolni tug‘dirishi mumkin.

Haqiqiy ishlab chiqarish muhitlarida Flyway har doim mukammal darajada izchil holatdan ishga tushadi, deb taxmin qilish qiyin.

Migratsiya jarayonida ayrim SQL operatorlari bajarilgandan so‘ng xatolik yuz berishi yoki hodisadan tiklanish vaqtida muayyan SQL operatorini qo‘lda qayta bajarish zarur bo‘lishi mumkin. Bundan tashqari, yuklab olinadigan ilovaning o‘ziga xos xususiyatlari tufayli turli o‘rnatish muhitlaridagi ma’lumotlar bazasi kutilgan holatdan biroz farq qilishi ehtimolini ham hisobga olishimiz kerak edi.

Agar bunday vaziyatlarda o‘sha SQL qayta bajarilganda yana bir xatolik yuz bersa, tiklanish jarayoni yanada qiyinlashadi.

Shuning uchun, imkon qadar barcha migratsiyalar uchun idempotentlikni kafolatlashni asosiy tamoyil sifatida belgiladik.

Biz foydalanadigan eng asosiy usullar — IF EXISTS va IF NOT EXISTS.

Jadval yaratishda uni quyidagicha yozamiz.

CREATE TABLE IF NOT EXISTS user_history (
    id BIGINT PRIMARY KEY,
    user_id BIGINT NOT NULL
);

Ustun qo‘shishda ham imkon qadar quyidagicha yozamiz.

ALTER TABLE user
ADD COLUMN IF NOT EXISTS status VARCHAR(20);

O‘chirish amallari uchun esa IF EXISTS’dan foydalanamiz.

DROP TABLE IF EXISTS user_history;

Ma’lumotlar bazasi IF EXISTS yoki IF NOT EXISTS’ni bevosita taqdim etmaydigan DDL operatorlari uchun ham xuddi shu tarzda ishlash imkonini beradigan alohida funksiyalar yaratdik.

Biroq amalga oshirish jarayonida e’tibor berish kerak bo‘lgan yana bir jihatni ham o‘rgandik.

IF NOT EXISTS mavjudligi migratsiyaning idempotentligini to‘liq kafolatlamaydi.

Masalan, quyidagi SQL mavjud, deb faraz qilaylik.

ALTER TABLE user
ADD COLUMN IF NOT EXISTS status VARCHAR(20);

Agar status ustuni ma’lumotlar bazasida allaqachon mavjud bo‘lsa, SQL xatoliksiz yakunlanadi.

Biroq haqiqiy ustun quyidagicha yaratilgan bo‘lishi mumkin.

기대 상태
status VARCHAR(20)
실제 상태
status INTEGER

SQL muvaffaqiyatli bajarildi, ammo ma’lumotlar bazasi ilova kutgan holatda emas.

Shuning uchun biz idempotentlikni SQL ikki marta bajarilganda shunchaki xatolik yuz bermasligi deb hisoblamaymiz.

Yakuniy ma’lumotlar bazasi holati bir xil bo‘lishimigratsiya bir yoki bir necha marta bajarilganidan qat’i nazar

— biz baholashda foydalanadigan mezondir. IF EXISTS va IF NOT EXISTS buni amalga oshirish vositalaridir.

4. Faqat oldinga migratsiyaning o‘zi yetarli emas edi

Migratsiyalarni ilk bor yozishni boshlaganimizda, asosan ma’lumotlar bazasini yangi versiyaga qanday o‘zgartirishga e’tibor qaratdik.

Biroq ilovani ishlatishda yangi versiyada muammo yuzaga kelib, avvalgi versiyaga qaytarish zarur bo‘ladigan holatlarni ham hisobga olishimiz kerak.

Agar faqat ilova avvalgi versiyaga qaytarilib, ma’lumotlar bazasi sxemasi yangi versiya holatida qolsa, avvalgi ilova to‘g‘ri ishlamasligi mumkin.

Shuning uchun faqat oldinga migratsiya yozish yetarli emas edi.

Hozirda inkremental migratsiya yozayotganda tegishli qaytarish skriptini bir vaqtning o‘zida yozish tamoyiliga amal qilamiz.

Masalan, bizda quyidagiga o‘xshash migratsiya bo‘lsa,

postgresql/V7_1/
└─ V7_1_3__Modify_User.sql

tegishli qaytarish skriptini ham alohida katalogda boshqaramiz.

rollback/postgresql/V7_1/
└─ V7_1_3__Modify_User_Rollback.sql

Qaytarish skripti Flyway tomonidan avtomatik bajarilmaydi.

U alohida boshqariladi, shunda ilovani qaytarish yoki hodisadan tiklanish zarur bo‘lganda mas’ul shaxs o‘zgarishlarni ko‘rib chiqishi va bajarishi mumkin.

Oddiy ustun qo‘shish uchun oldinga migratsiyani quyidagicha yozishimiz mumkin.

ALTER TABLE user
ADD COLUMN IF NOT EXISTS status VARCHAR(20);

Qaytarish skriptida esa ustunni olib tashlaymiz.

ALTER TABLE user
DROP COLUMN IF EXISTS status;

Dastlab bu qaytarish uchun yetarli tayyorgarlikdek ko‘rinishi mumkin.

Biroq haqiqiy ma’lumotlarni o‘zgartiradigan migratsiyalarda faqat sxemani qaytarish tizimni avvalgi holatiga keltirmaydi.

5. Qaytarish skriptini yaratishdan oldin zaxiralashni ko‘rib chiqing

Biz belgilagan eng muhim tamoyillardan biri zaxiralash va qaytarishni yagona operatsiya sifatida ko‘rib chiqishdir.

Masalan, mavjud ustunni o‘chirib tashladik, deb faraz qilaylik.

ALTER TABLE user
DROP COLUMN legacy_code;

Agar ilovada muammo yuz berib, avvalgi versiyaga qaytishimiz kerak bo‘lsa, ustunni quyidagicha qayta yaratishimiz mumkin.

ALTER TABLE user
ADD COLUMN legacy_code VARCHAR(100);

Faqat ma’lumotlar bazasi sxemasiga qaralganda, u dastlabki holatiga qaytgandek ko‘rinadi.

Biroq mavjud legacy_code ustunida saqlangan ma’lumotlar allaqachon yo‘qolgan bo‘ladi.

Boshqacha aytganda,

sxemani qaytarish va ma’lumotlarni qaytarish — alohida muammolardir.

Shu tajribadan so‘ng mavjud ma’lumotlarni o‘zgartirishi yoki o‘chirishi mumkin bo‘lgan har qanday migratsiya bilan birga zaxiralashni hamisha ko‘rib chiqishga qaror qildik.

Masalan, agar mavjud ustunni o‘zgartirish kerak bo‘lsa, uni darhol o‘chirib tashlash o‘rniga mavjud ustunni Backup ustuni sifatida qoldirishingiz mumkin.

ALTER TABLE sample
RENAME COLUMN A TO A_7_1_3;

ALTER TABLE sample
ADD COLUMN A VARCHAR(255);

UPDATE sample
SET A = A_7_1_3;

Mavjud A ustuni A_7_1_3 nomi ostida saqlanadi.

Agar yangi versiyada muammo yuzaga kelsa, yangidan yaratilgan ustunni olib tashlang va mavjud ustunni tiklang.

ALTER TABLE sample
DROP COLUMN IF EXISTS A;

ALTER TABLE sample
RENAME COLUMN A_7_1_3 TO A;

Agar butun jadvalning Backup nusxasi kerak bo‘lsa, Backup Table yarating.

CREATE TABLE user_7_1_3 AS
SELECT *
FROM user;

Rollback vaqtida undan asl jadvalni tiklash uchun foydalanishingiz mumkin.

DROP TABLE IF EXISTS user;

ALTER TABLE user_7_1_3
RENAME TO user;

Shuningdek, Backup Object nomiga Migration Version ni qo‘shadigan qoidadan foydalanamiz.

<column>_<major>_<minor>_<patch>

<table>_<major>_<minor>_<patch>

Masalan, u quyidagicha bo‘ladi.

email_7_1_3
user_7_1_3

Bu Backup qaysi Migration uchun yaratilganini aniqlash imkonini beradi.

Oxir-oqibat, hozirda biz bitta Migration vazifasini quyidagi uch qismdan iborat deb hisoblaymiz.

Migratsiya

     │

    ├─ Zaxiralash

    ├─ Oldinga migratsiya

    └─ Orqaga qaytarish

Xususan, Migrationni yozishda avval Forward Migrationni yaratib, keyin Rollbackni qanday amalga oshirish haqida o‘ylashdan ko‘ra, Rollback va Backupni birgalikda loyihalash muhim edi

Buning sababi shundaki, Migration tugallangandan keyingina Rollbackni qanday amalga oshirish haqida o‘ylay boshlasangiz, kerakli ma’lumotlar allaqachon o‘chirib yuborilgan bo‘lishi mumkin.

Joriy qo‘llanmada ustun nomlarini o‘zgartirish, ma’lumot turlarini o‘zgartirish, ma’lumotlarni tahrirlash, jadval tuzilmalarini o‘zgartirish va ma’lumotlarni o‘chirish kabi amallar uchun ham Backup yozish talab etiladi.

6. Birinchi sinov va xatolar: Baselineni boshqarish

Yuklab olinadigan ilova nafaqat mavjud muhitlarni yangilashni, balki yangi muhitlarda yangidan o‘rnatishni ham qo‘llab-quvvatlashi kerak.

Muammo shundaki, ilova vaqt o‘tishi bilan ishlashda davom etar ekan, Migration Scriptlar soni tobora ko‘payib boradi.

Masalan, quyidagicha o‘nlab Migrationlar mavjud bo‘lishi mumkin.

V7_0_1
V7_0_2
V7_0_3
...
V7_1_1
V7_1_2
V7_1_3
...

Yangi muhitni o‘rnatishda barcha Migrationlarni dastlabki versiyadan boshlab ketma-ket ishga tushirish juda ko‘p keraksiz ishni talab qiladi.

Bitta Migrationda jadval yaratilishi, so‘ngra bir necha versiyadan keyin o‘chirilishi mumkin. Yangi o‘rnatishda yakuniy tuzilma allaqachon ma’lum bo‘lsa ham, ushbu tarixiy o‘zgarishlarning barchasi baribir qo‘llanilishi kerak.

Dastlab, bu muammoni hal qilish uchun har bir Minor Version uchun yakuniy Schemaga mos keladigan alohida Baseline SQL fayllarini boshqardik.

baseline/

└─ postgresql/

    ├─ 7.0.sql

    └─ 7.1.sql

Baselineda ushbu Minor Version uchun yakuniy Schema, jumladan barcha Tables, Indexes, Constraints va boshqalar belgilangan.

Boshqacha aytganda, Flyway Migrationdan alohida yana bitta Snapshotni boshqardik.

Dastlab, buning afzalligi yangi o‘rnatishlarni soddalashtirish edi.

Biroq vaqt o‘tishi bilan uning muammolari ham ayon bo‘ldi.

Eng katta muammo aslida bir xil Database Schemani ikki joyda boshqarishimizga to‘g‘ri kelganida edi.

Inkremental migratsiya

    → Mavjud DB qanday o‘zgaradi

Bazaviy holat

    → Yangi DB qanday holatda yaratiladi

Agar dasturchi yangi Migration yozib, Baseline’ni ham o‘zgartirmasa, muammolar yuzaga keladi.

Mavjud Databaseni yangilash natijasi bilan yangi Databaseni o‘rnatish natijasi farq qilishi mumkin.

Oxir-oqibat, ushbu tuzilma amaldagi Migration tarixi bilan Snapshot Baseline o‘rtasidagi izchillikni doimiy ravishda saqlab turishni talab qildi.

Flyway yordamida avtomatlashtirish jarayonida biz amalda qo‘lda boshqarilishi kerak bo‘lgan yana bir elementni yaratib qo‘ydik.

7. Baseline tuzilmasi Initial Migrationga o‘zgartirildi

Ushbu muammoni yaxshilash uchun Baseline tuzilmasini qayta tashkil etdik.

Biz alohida Baseline Snapshot fayllarini olib tashladik va jarayonni shunday o‘zgartirdikki, har bir Minor Version uchun birinchi Migration o‘sha versiyaning to‘liq Schema DDLini o‘z ichiga oladi.

Masalan, 7.1 uchun quyidagi fayl mavjud bo‘lishi kerak.

V7_1_0__Initial.sql

Tegishli kichik versiya uchun Patch Version 0 dan dastlabki migratsiya sifatida foydalaning.

Umumiy tuzilma quyidagicha.

postgresql/

├─ V7_1/

│ ├─ V7_1_0__Initial.sql

│ ├─ V7_1_1__Create_User.sql

│ └─ V7_1_2__Modify_User.sql

└─ V7_2/

   ├─ V7_2_0__Initial.sql

   ├─ V7_2_1__Create_History.sql

   └─ V7_2_2__Modify_User.sql

7.1-versiyani noldan o‘rnatish uchun zarur bo‘lgan to‘liq Schema DDL kodini V7_1_0__Initial.sql fayliga yozing.

7.1 ishlab chiqilishi davomida Incremental Migrationlar qo‘shilganda va 7.2 ishlab chiqilishi boshlanganda, V7_2_0__Initial.sql faylini 7.1 ning yakuniy Database Schema’si asosida yozing.

V7_1_0__Initial

       ↓

V7_1_1

       ↓

V7_1_2

       ↓

7.1 Final Schema

       ↓

V7_2_0__Initial

Bu har bir kichik versiya uchun yangi o‘rnatishda mustaqil boshlang‘ich nuqtaga ega bo‘lish imkonini beradi.

Shuningdek, alohida Baseline Snapshot va Incremental Migrationlar o‘rtasidagi izchillikni boshqarish zaruratini kamaytiradi.

Albatta, mavjud 7.1 Database’ini 7.2 ga yangilashda butun V7_2_0__Initial.sql faylini mavjud Schema ustida qayta bajarmasligingiz kerak.

Shu sababli yangi o‘rnatishlar va mavjud muhitni yangilashlar uchun qaysi fayllar bajarilishi kerakligini ajratib ko‘rsatish uchun alohida strategiya talab etiladi.

Bu qism, shuningdek, Migration dizayni shunchaki SQL fayllarini yaratish bilangina yakunlanmasligini ko‘rsatdi; bu yangi o‘rnatish yo‘li va yangilash yo‘lini bir vaqtning o‘zida hisobga olish zarurligini namoyish etgan holat edi.

8. Ikkinchi sinov va xatolar: bir nechta dasturchi Migrationlar yozganda

Kutilganidan ko‘ra tez-tez yuzaga kelgan yana bir muammo Migration Versionlarini boshqarish edi.

Agar barcha Migrationlarni bir kishi ketma-ket yozsa, Versionlarni boshqarish qiyin emas.

Biroq amaldagi loyihalarda bir nechta dasturchi turli Feature Branchlarda bir vaqtning o‘zida ishlaydi.

Masalan, hozirgi eng so‘nggi Migration quyidagicha deb faraz qilaylik.

V7_2_2

Developer A va Developer B o‘zlarining tegishli Branchlarida Schema’ni bir vaqtning o‘zida o‘zgartiradilar.

Developer A quyidagi Migrationni yaratadi.

V7_2_3__Create_User.sql

Developer B ham quyidagi Migrationni yaratadi, chunki ular ishlashni boshlagan paytdagi eng so‘nggi Version V7_2_2 edi.

V7_2_3__Create_Position.sql

Ikkala Branchda ham hech qanday muammo yuzaga kelmaydi.

Muammo ikkala Branch Main Branchga birlashtirilganda yuzaga keladi.

V7_2_3__Create_User.sql
V7_2_3__Create_Position.sql

Endi bir xil Versionga ega ikkita Migration mavjud bo‘ladi.

Agar Migration hali hech qaysi muhitda bajarilmagan bo‘lsa, muammoni nisbatan oson hal qilish mumkin.

Main Branchning eng so‘nggi holatini olgach, keyinroq birlashtirilgan Migrationning Versionini o‘zgartiring.

Biroq Migration ishlab chiqish yoki umumiy muhitda allaqachon bajarilgan bo‘lsa, oddiy Rename yetarli bo‘lmasligi mumkin.

Buning sababi Flyway Migration Versioni va bajarilish natijasini flyway_schema_history’da qayd etishidir.

Ushbu muammoga duch kelganimizdan so‘ng, quyidagi qoidani belgiladik: Migration Versionlari Script yozilganda emas, balki Main Branchga birlashtirilganda ham qayta tekshirilishi kerak.

Hozirda ularni quyidagi jarayon asosida boshqaramiz.

Funksiyani ishlab chiqish

    ↓

Migratsiyani yozish

    ↓

Asosiy branchni yangilash

    ↓

Eng so‘nggi migratsiyani tekshirish

    ↓

Takroriy versiyalarni tekshirish

    ↓

Zarur bo‘lsa, versiyani qayta moslashtirish

    ↓

Asosiy merge

9. Yuqoriroq versiyalarning avval bajarilishi muammosi

Bir xil versiyalar bilan bog‘liq ziddiyatlardan tashqari, migratsiyalarning bajarilish tartibi chalkashib ketgan holatlarga ham duch keldik.

Faraz qilaylik, bizda ikkita migratsiya bor.

V7_2_7
V7_2_8

Faqat versiyalarga qarab, tabiiy ravishda quyidagi tartibni kutamiz.

V7_2_7

   ↓

V7_2_8

Biroq ikkala migratsiya turli branchlardan ishlab chiqilib, deploy qilinganda, haqiqiy merge yoki release tartibi boshqacha bo‘lishi mumkin.

Yuqoriroq versiya — V7_2_8 — muayyan muhitga avval qo‘llanadigan vaziyat yuzaga kelishi mumkin.

V7_2_6

   ↓

V7_2_8

Agar keyin V7_2_7 Repositoryga qo‘shilsa, Repository kutayotgan migratsiya tartibi haqiqiy Database’da qayd etilgan bajarilish tarixidan farq qiladi.

Bu vaziyatni fayllar nomini o‘zgartirish yoki Historyni tahrirlash orqali shunchaki hal qilish xavfli.

Chunki allaqachon bajarilgan migratsiyalar amaldagi Database Schema o‘zgarishlari bilan bog‘langan.

Ushbu tajriba orqali men Migratsiya versiyalarini shunchaki fayllarni saralash mezoni sifatida emas, balki Database Schema o‘zgarishlari amalda qaysi tartibda bajarilganini ifodalovchi operatsion ma’lumot sifatida ko‘rish kerakligini angladim.

Shu sababli hozirda ularni quyidagi tamoyillar asosida boshqaramiz.

  • Migratsiyani o‘z ichiga olgan branchni merge qilishdan oldin eng so‘nggi Migratsiya versiyasini tekshiramiz.

  • Bir xil versiya mavjud yoki mavjud emasligini tekshiramiz.

  • Pastroq versiya hali deploy qilinmagan paytda yuqoriroq versiya avval deploy qilinmasligini ta’minlaymiz.

  • Allaqachon bajarilgan Migratsiyaning versiyasi yoki tarkibini o‘zboshimchalik bilan o‘zgartirmaymiz.

  • Deploy qilishdan oldin Pending Migratsiyalar va ularning bajarilish tartibini tekshiramiz.

  • Muammo yuzaga kelganda, versiyalarni shunchaki tartibga solish uchun repairdan foydalanmaymiz.

Flywaydan foydalanish davomida bu tajriba bizga texnik SQL yozishdan tashqari, Git branchlari va Release Process ham Database Migrationning bir qismi ekanini anglatdi.

10. Amalga oshirilgandan keyin belgilangan migratsiya tamoyillari

Flywayni ilk bor joriy qilganimizda, quyidagicha o‘ylagan edik.

Migration
    =
Application 실행 시 자동으로 수행할 SQL

Bir nechta versiyani amalda yangilab, sinov va xatolar orqali o‘tgach, hozir biroz boshqacha fikrdaman.

Migratsiya

    =

Database’ni qanday o‘zgartirish

+ Takroriy bajarilish xavfsizligi

+ Ma’lumotlarni qanday saqlab qolish

+ Muvaffaqiyatsizlik yuz berganda tiklash usullari

+ Versiya va bajarilish tartibini boshqarish

Migratsiya yozishda hozirda quyidagi bandlarni tekshiraman.

Yangi o‘rnatish

  • Kichik versiya uchun Initial Migration mavjudligini tekshiring.

  • Ushbu versiya uchun standart sxema faqat Initial Migration yordamida yaratilishi mumkin bo‘lishi kerak.

  • Yangi o‘rnatishdan so‘ng ilova normal ishlashi kerak.

Bosqichma-bosqich migratsiya

  • Uni mavjud ishlab chiqarish ma’lumotlar bazasining holatiga asoslanib yozing.

  • Imkon qadar idempotentlikni ta’minlang.

  • Allaqachon bajarilgan migratsiyani o‘zgartirmang.

  • Ma’lumotlar bazasidagi o‘zgarishlar mavjud ma’lumotlarga ta’sir qiladimi-yo‘qmi, tekshiring.

Zaxiralash va ortga qaytarish

  • Oldinga yo‘naltirilgan migratsiyani yozayotganda, u bilan birga ortga qaytarish skriptini ham yozing.

  • Agar ma’lumotlar o‘zgartirilsa yoki o‘chirilsa, avval zaxiralash usulini aniqlang.

  • Ortga qaytarishdan so‘ng nafaqat sxemani, balki ma’lumotlarni ham tiklash mumkinligini tekshiring.

Versiyalarni boshqarish

  • Asosiy branchga birlashtirishdan oldin eng so‘nggi migratsiya versiyasini tekshiring.

  • Takroriy versiyalar mavjudligini tekshiring.

  • Amaldagi joylashtirish tartibi migratsiya versiyalari tartibiga mos keladimi-yo‘qmi, tekshiring.

  • Allaqachon bajarilgan migratsiya versiyasini o‘zboshimchalik bilan o‘zgartirmang.

Joriy loyihada biz ushbu bandlarni migratsiyalarni yozish va tekshirish bo‘yicha qo‘llanmaga jamladik va undan shunga muvofiq foydalanamiz.

11. Xulosa

Flyway’ni joriy etishning bevosita sababi Vizend ilovasining tabiati edi.

Foydalanuvchilar ilovani o‘zlari yuklab olishi, o‘rnatishi va yangi versiyaga yangilashi mumkin bo‘lgani sababli, ma’lumotlar bazasi sxemasi ham ilova yangilanishi bilan birga avtomatik ravishda yangilanishi kerak edi.

Flyway ushbu talablarni amalga oshirish uchun yaxshi asos bo‘lib xizmat qildi.

Biroq amaliy joriy etish jarayonida shuni angladimki, Flyway’dan foydalanish ma’lumotlar bazasi migratsiyasini avtomatik ravishda xavfsiz qilmaydi.

Flyway qaysi migratsiyalar bajarilganini qayd etadi va hali qo‘llanmagan migratsiyalarni oldindan belgilangan tartibda ishga tushiradi.

Biroq Flyway migratsiyani qayta-qayta ishga tushirish xavfsizmi, o‘zgartirilgan ma’lumotlarni tiklash mumkinmi yoki ortga qaytarish usuli mavjudmi — bularni sizning nomingizdan aniqlamaydi.

Bundan tashqari, bir nechta dasturchi bir vaqtning o‘zida migratsiyalar yozadigan muhitda Git branchlarini birlashtirish tartibi va relizlar tartibini ham hisobga olishimiz kerak edi.

Oxir-oqibat, Flyway’dan haqiqiy loyihada ishonchli foydalanish uchun eng muhim narsa vositaning o‘z imkoniyatlari emas, balki jamoaning migratsiyalarni qanday yozish va boshqarish bo‘yicha qoidalari edi.

Migratsiya yozishda hozirda tekshiradigan dastlabki uchta narsa quyidagilar.

Uni qayta ishga tushirish xavfsizmi?

Muammo yuzaga kelsa, uni ortga qaytarish mumkinmi?

Ortga qaytarish uchun zarur ma’lumotlar hali ham mavjudmi?

Dastlab Flyway’ni SQL’ni avtomatik ishga tushirish uchun joriy etgan edik, biroq undan amalda foydalanish tajribasi orqali ma’lumotlar bazasidagi o‘zgarishlar ham xuddi ilova kodi kabi nafaqat o‘zgarishlarni qanday amalga oshirishni, balki xatolar va tiklanish jarayonlarini qanday boshqarishni ham o‘z ichiga oladigan tarzda loyihalashtirilishi kerak bo‘lgan narsa ekanini.

Manbalar

Ushbu maqolada keltirilgan Flyway migratsiyalarini yozish va ishlatish qoidalari hozirda haqiqiy loyihada qo‘llanadigan ichki qo‘llanma asosida tuzilgan.

  • Flyway asosidagi DB migratsiyasi bo‘yicha qo‘llanma

https://vizend.notion.site/Flyway-DB-Migration-2e635bc54c138022a9d0f6c6c3b47695?pvs=74

David

Site footer