
Bu məqalədə depolama zamanı verilənlər bazası uyğunluğu ilə əlaqədar problemləri necə həll etmək olar, ətraflı izah olunur. Ön hazırlıq olmadan yerləşdirmə həyata keçirəndə istehsal mühiti üçün tətbiqlərinizin başına nələr gələ biləcəyini müzakirə edəcəyik. Sonra sıfır müddət dayanıqlığı üçün lazım olan tətbiq həyat dövrünün mərhələlərinə baxacağıq (qeyd: daha sonra — sıfır dayanıqlıq). İşlərimizin nəticəsi olaraq, uyğunsuz verilənlər bazası dəyişikliyini geri uyumlu bir şəkildə tətbiq edəcəyik.
Məqalədəki kod nümunələri ilə tanış olmaq istəyirsinizsə, onları .
Giriş
Sıfır dayanıqlıq ilə yerləşdirmə
Mistik nədir? sıfır dayanıqlıq ilə yerləşdirmə? Можно сказать, это когда ваше приложение развернуто так, что вы можете успешно вводить новую версию приложения на продакшн, в то время как пользователь не замечает его недоступности. С точки зрения пользователя и компании, это наилучший из возможных сценариев деплоя, поскольку таким образом можно вводить новые функции и устранять ошибки без перебоев в работе.
Buna necə nail olmaq olar? Bir neçə yol var, bunlardan biri budur:
- Xidmətinizin №1 versiyasını yerləşdirin
- Verilənlər bazası mühacirəti edin
- Xidmətinizin №2 versiyasını №1 versiyası ilə paralel olaraq yerləşdirin
- №2 versiyasının düzgün işlədiyini gördüyünüz an, №1 versiyasını silin
- Hazır!
Asan, deyilmi? Təəssüf ki, bu, bu qədər sadə deyil, bunu sonra ətraflı müzakirə edəcəyik. İndi isə daha bir çox yayılmış yerləşdirmə prosesi – mavi yaşıl yerləşdirməni yoxlayaq.
Mavi yaşıl yerləşdirmə barədə heç eşitmisiniz? ? С Cloud Foundry это чрезвычайно легко сделать. Просто гляньте на , burada biz onu daha da ətraflı təsvir edirik. Qısaca xatırladaq ki, mavi yaşıl yerləşdirməni necə etməliyik:
- İstehsal kodunun iki nüsxəsinin (“mavi” və “yaşıl”) işlədiyini təmin edin;
- Bütün trafiki mavi mühitə yönəldin, yəni istehsal URL-ləri ora yönəldilməlidir;
- Bütün tətbiq dəyişiklərini yaşıl mühitdə yerləşdirin və test edin;
- URL-ləri mavi mühitdən yaşıl mühitə dəyişdirin
Mavi yaşıl yerləşdirmə – yeni funksiyalar təqdim etməyinizi asanlaşdıran bir yanaşmadır, istehsalın pozulmasından narahat olmadan. Bu, baş verən bir problem olduğu halda, əvvəlki mühitə qayıtmağın asan olduğu gerçəyi ilə əlaqədardır, sadəcə "düyməni dəyişməklə".
Yuxarıda qeyd olunanları oxuduqdan sonra, sual verə bilərsiniz: Sıfır dayanıqlığın mavi yaşıl yerləşdirmə ilə nə əlaqəsi var?
Bunun çox oxşar olduğunu söyləyə bilərəm, çünki eyni mühitin iki nüsxəsini dəstəkləmək onların saxlanılması üçün ikili səylər tələb edir. Bunun səbəbini bəzi komandalar, Martin Fowler-in iddiasına görə Başqa bir variant, eyni verilənlər bazasından istifadə edərək veb və domen təbəqələri üçün mavi-yaşıl dəyişikliklər etməkdir. Bu yanaşmada verilənlər bazaları, xüsusilə proqram təminatının yeni versiyasını dəstəkləmək üçün sxemini dəyişdirmək lazım olduğunda problem yarada bilər.
Elə burada məqaləmizin əsas problemi ilə qarşılaşırıq.
Verilənlər bazası. Yenidən bu frazaya nəzər salaq.Verilənlər bazası mühacirəti edin.
İndi sizə bir sual verməlisiniz – əgər verilənlər bazasında geri uyuşmaz bir dəyişiklik varsa? İlk tətbiq versiyam pozulmayacaqmı? Əslində, bu baş verəcək...
Теперь вы должны задать себе вопрос — что, если изменение базы данных обратно несовместимо? Разве моя первая версия приложения не сломается? На самом деле, именно это и случится…
Beləliklə, sıfır dayanıqlığı / mavi-yaşıl yerləşdirmənin böyük üstünlüklərinə baxmayaraq, şirkətlər daha təhlükəsiz olan tətbiq yerləşdirmə prosesinə meyl edirlər:
- yeni tətbiq versiyası üçün paket hazırlamaq
- işləyən tətbiqi söndürmək
- veritabanı miqrasiyaları üçün skriptləri işə salmaq
- tətbiqin yeni versiyasını yerləşdirmək və işə salmaq
Bu yazıda siz verilənlər bazası və kodla necə işləməyi öyrənəcəksiniz ki, sıfır dayanıqlığı olan yerləşdirmənin üstünlüklərindən yararlanasan.
Verilənlər bazası ilə bağlı problemlər
Əgər sıfır vəziyyəti olan bir tətbiqiniz varsa ki, verilənlər bazasında heç bir məlumat saxlamır, dərhal sıfır dayanıqlığı olan yerləşdirməyə nail ola bilərsiniz. Təəssüf ki, əksər proqram təminatı haradasa məlumat saxlamaq məcburiyyətindədir. Buna görə də şemanı dəyişməzdən əvvəl iki dəfə düşünməlisiniz. Şemanı sıfır dayanıqlığı olan yerləşdirməyə imkan vermək üçün necə dəyişdirmək lazım olduğunu dərindən müzakirə etməzdən əvvəl, gəlin versiya idarəetmə sxeminə diqqət yetirək.
Versiya idarəetmə sxemi
Bu yazıda istifadə edəcəyik versiya idarəetmə alatı olaraq (Qeyd: bu, verilənlər bazası miqrasiyaları ilə bağlıdır). Təbii ki, Flyway dəstəyinə malik olan Spring Boot tətbiqi yazacağıq və tətbiq kontekstini quraşdırarkən şema miqrasiyasını həyata keçirəcəyik. Flyway istifadə edərkən, miqrasiya skriptlərini layihə qovluğunuzda saxlaya bilərsiniz (səhvən olaraq classpath:db/migration). Burada bu cür miqrasiya fayllarının nümunəsini görə bilərsiniz
└── db
└── migration
├── V1__init.sql
├── V2__Add_surname.sql
├── V3__Final_migration.sql
└── V4__Remove_lastname.sqlBu nümunədə 4 miqrasiya senarisi görürük ki, əgər daha əvvəl yerinə yetirilməyibsə, tətbiq işə salındıqda bir-birinin ardınca həyata keçiriləcək. Gəlin nümunə olaraq bir faylı (V1__init.sql) nəzərdən keçirək.
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');Hər şey özünü çox yaxşı ifadə edir: verilənlər bazanızın necə dəyişdiriləcəyini müəyyən etmək üçün SQL istifadə edə bilərsiniz. Spring Boot və Flyway haqqında daha ətraflı məlumat üçün .
Spring Boot ilə versiya idarəetmə alətindən istifadə edərək, 2 böyük üstünlük əldə edirsiniz:
- verilənlər bazası dəyişikliklərini kod dəyişiklərindən ayırırsınız
- verilənlər bazası miqrasiyası tətbiqinizin yerləşdirilməsi ilə baş verir, yəni yerləşdirmə prosesiniz asanlaşır
Verilənlər bazası problemlərinin həlli
Məqalənin növbəti bölməsində biz verilənlər bazası dəyişiklərinə iki yanaşma ilə məşğul olacağıq.
- geriyə uyğunsuzluq
- geriyə uyğunsuzluq
Birincisi, zero downtime deployment'un ön hazırlık olmadan yapılmaması gerektiği konusunda bir uyarı olarak ele alınacaktır... İkincisi, kesinti olmadan nasıl dağıtım yapılabileceğine ve aynı zamanda geriye dönük uyumluluğun nasıl sağlanacağına dair bir çözüm sunmaktadır.
Üzerinde çalışacağımız projemiz, içerisinde olan basit bir Spring Boot Flyway uygulaması olacaktır. Kişi c isim və soyisim veritabanında (not: Kişi bir tablodur ve first_name və soyisim — onun içindeki alanlardır). Yeniden adlandırmak istiyoruz soyisim daxilindədir. soyadı.
Varsayımlar
Ayrıntılara girmeden önce, uygulamalarımız ile ilgili birkaç varsayıma işaret etmek gerekir. Ulaşmak istediğimiz temel sonuç oldukça basit bir süreçtir.
Not. İş PRO-TİP. Süreçleri basitleştirmek, destek için size çok para kazandırabilir (şirketinizde daha fazla insan çalıştıkça, tasarruf edebileceğiniz para miktarı artar)!
Veritabanını geri almanıza gerek yok
Bu, dağıtım sürecini basitleştirir (bazı veritabanı geri almaları hemen hemen imkansızdır, örneğin silme geri alması). Biz yalnızca uygulamaları geri almayı tercih ediyoruz. Böylece, SQL ve NoSQL gibi farklı veritabanlarınız olsa bile, dağıtım hattınız aynı görünecektir.
Her zaman uygulamayı bir sürüm geriye alabilme imkanı olmalıdır (birden fazla değil)
Geri alma yalnızca gerekli olduğunda yapılmalıdır. Mevcut versiyonda kolayca giderilemeyen bir hata varsa, çalışır durumdaki son versiyona dönebilmeliyiz. Son çalışır versiyonun bir önceki versiyon olduğunu varsayıyoruz. Kod ve veritabanı uyumluluğunu birden fazla sürüm için sağlamak son derece zor ve maliyetli olacaktır.
Qeyd. Daha fazla okunabilirlik için, bu makale kapsamında uygulamanın ana sürüm numarasını değiştireceğiz.
Adım 1: Başlangıç durumu
Uygulama sürümü: 1.0.0
Veritabanı sürümü: v1
: Sonuncunu görmək üçün, mənim halımda, icra etdikdən sonra təxminən 10 dəqiqə gözləmək lazım idi
Bu, uygulamanın başlangıç durumu olacaktır.
Veritabanı değişiklikleri
Veritabanı, soyadı.
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');Kod değişiklikleri
Uygulama, Person verilerini kaydeder. soyisim:
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastname) {
this.lastName = lastname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName
+ "]";
}
}Geriyelenmeye uyumsuz sütun ismi değişikliği
Bir sütun ismini değiştirme örneğine bakalım:
Dikkat. Aşağıdaki örnek, kasıtlı olarak bir bozulmaya yol açacaktır. Bu durumu, veritabanı uyumluluğu sorununu göstermek amacıyla sunuyoruz.
Uygulama sürümü: 2.0.0.BAD
Veritabanı sürümü: v2bad
: Sonuncunu görmək üçün, mənim halımda, icra etdikdən sonra təxminən 10 dəqiqə gözləmək lazım idi
Mevcut değişiklikler, iki örneği (eski ve yeni) aynı anda çalıştırmamıza izin vermemektedir. Dolayısıyla, zero downtime deployment'ı sağlamak zor olacaktır (varsayımları dikkate alırsak, bu aslında imkansızdır).
A/B testi
Mevcut durum, canlıda dağıtılan 1.0.0, uygulamanın sürümüdür ve veritabanı v1. İkinci örneği dağıtmalıyız. 2.0.0.BAD, və verilənlər bazasını yeniləyin v2bad.
Addımlar:
- çevrilmiş yeni tətbiq nümunəsi versiyası
2.0.0.BAD, bu da verilənlər bazasını yeniləyirv2bad - verilənlər bazasında
v2badsütunsoyisimartıq mövcud deyil — o, dəyişdirilibsoyadı - verilənlər bazasını və tətbiqi yeniləmək başa çatdı və bəzi nümunələr
1.0.0, digər nümunələr isə2.0.0.BAD. Hamısı DB ilə bağlıdırv2bad - verilənlər bazasının bütün nümunələri
1.0.0xətalar verməyə başlayacaqlar, çünki onlarsoyisimartıq olmayan sütuna məlumat daxil etməyə çalışacaqlar - verilənlər bazasının bütün nümunələri
2.0.0.BADproblemsiz işləyəcək
Gördüyünüz kimi, əgər biz tətbiq və DB-də uyğunsuz dəyişikliklər etsək, A/B testi mümkün olmayacaq.
Tətbiqin geri dönməsi
Gəlin fərz edək ki, A/B yayımını (qey. red.: burda müəllifin A/B testi nəzərdə tutduğu güman olunur) sınaqdan keçirdikdən sonra tətbiqi 1.0.0. geri qaytarmaq istəyirik.
Addımlar:
- tətbiq nümunəsini dayandırırıq
2.0.0.BAD - verilənlər bazası hələ də
v2bad - çünki versiya
1.0.0nə olduğunu başa düşmürsoyadı, xətalarla qarşılaşacağıq - cəhənnəm azad oldu, geri dönə bilmirik
Gördüyünüz kimi, əgər biz DB və tətbiqdə geri uyğunsuz dəyişikliklər etsək, əvvəlki versiyaya geri dönə bilmirik.
Skripti icraetmə jurnalı
Geri uyğunsuz ssenari:
01) 1.0.0 versiyasını çalışdırın
02) Tətbiqi (1.0.0) yüklənməsini gözləyin
03) POST localhost:9991/person çağıraraq 1.0.0 versiyasında bir insan yaradın
04) 2.0.0.BAD versiyasını çalışdırın
05) Tətbiqi (2.0.0.BAD) yüklənməsini gözləyin
06) POST localhost:9991/person çağıraraq 1.0.0 versiyasında bir insan yaradın <-- bu uğursuz olmalıdır
07) POST localhost:9992/person çağıraraq 2.0.0.BAD versiyasında bir insan yaradın <-- bu uğurlu olmalıdır
1.0.0 versiyasında tətbiqi başlamaq
1.0.0 versiyasında bir insan yaradın
127.0.0.1:9991/person ünvanına post göndəririk. Bu cavabdır:
{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}
2.0.0.BAD versiyasında tətbiqi başlamaq
1.0.0 versiyasında bir insan yaradın
127.0.0.1:9991/person ünvanına post göndəririk. Bu cavabdır:
curl: (22) İstənilən URL xətası qaytardı: 500 Daxili Server Xətası
2.0.0.BAD versiyasında bir insan yaradın
127.0.0.1:9995/person ünvanına post göndəririk. Bu cavabdır:
{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}Veritabanı değişiklikleri
Adı dəyişdirən köçürmə skripti soyisim daxilindədir. soyadı
Mənbə Flyway skripti:
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');Dəyişiklik edən skript soyisim.
-- Bu dəyişiklik geri uyğunsuzdur - A/B testi edə bilməzsiniz
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;Kod değişiklikleri
Sütun adını dəyişdirdik lastName buna soyadı.
Sütunu geri uyğun bir şəkildə dəyişdirmək
Bu, qarşılaşa biləcəyimiz ən yaygın situasiyadır. Geri uyğunsuz dəyişiklikləri həyata keçirməliyik. Biz artıq sübut etdik ki, hətta kəsilmədən yayım üçün verilənlər bazası köçürmələrini yalnız tətbiq etmək kifayət deyil. Bu bölmə ərzində biz verilənlər bazası köçürməylə birlikdə tətbiqin 3 yayımını həyata keçirmək və istədiyimiz nəticəyə nail olmaq üçün geri uyğunsuzluğu qorumaq üçün çalışacağıq.
Not. Yadınıza salaq ki, bizdə var
v1versiyalı DBisimvəsoyisim. O, sütunlar ehtiva edirsoyisimbunasoyadı. Biz1.0.0,dəyişdirməliyik.soyadı.
Bizdə
Uygulama sürümü: 2.0.0
Veritabanı sürümü: v2
: Sonuncunu görmək üçün, mənim halımda, icra etdikdən sonra təxminən 10 dəqiqə gözləmək lazım idi
Yeni bir sütun ekleyip içeriğini kopyalayarak veritabanında geriye dönük uyumlu değişiklikler yapıyoruz. Aynı zamanda, JAR'ı geri alırsak veya çalışan bir eski JAR'ımız olursa, çalışma sırasında bozulma olmayacaktır.
Yeni sürüm yayımlıyoruz
Addımlar:
- veritabanını yeni sütunu oluşturmak için göç ettirin
soyadı. Artık veritabanınızın sürümüv2 - veriler kopyalayın
soyisimdaxilindədir.soyadı. Qeyd edin, eğer bu verilerin çokluğu varsa, toplu göç düşünmelisiniz! - kullanılan yerlerde kod yazın HER İKİ və yeniilə imzalanmalıdır, eski sütun. Artık uygulamanızın sürümü
2.0.0 - sütundan bir değeri okuyun
soyadı, eğer bu yoksanull, veya last_name, eğersoyadıbelirtilmemişse. Bunu kaldırabilirsinizgetLastName()koddan, çünkü geri alındığındanulluygulamanızla birlikte3.0.0ile2.0.0.
Eğer Spring Boot Flyway kullanıyorsanız, bu iki adım uygulama sürümü başlatıldığında gerçekleştirilecektir. Eğer veritabanı sürüm yönetim aracını manuel olarak çalıştırıyorsanız, bunun için iki ayrı işlem yapmanız gerekecek (önce db sürümünü manuel olarak güncelleyin ve sonra yeni uygulamayı dağıtın). 2.0.0 Önemlidir.
Yeni oluşturulan sütun OLMAMALIDIR NOT NULL olmak . Eğer geri alıyorsanız, eski uygulama yeni sütunun varlığından haberdar değildir ve bunuInsert.
Ama bu kısıtlamayı eklerseniz ve veritabanınız, bu yeni sütunun değerinin ayarlanmasını gerektirecektir. Bu da kısıtlama ihlallerine yol açar.v2Bu metodu kaldırmalısınızYeni oluşturulan sütun , çünkü sürümde
getLastName()kodda sütun kavramı yoktur3.0.0. Bu, orada null değerlerin ayarlanacağı anlamına gelir. Bu metodu bırakabilir ve kontrol ekleyebilirsiniz, fakat çok daha iyi bir çözüm, mantıktasoyisimgetSurname()nulldoğru null olmayan bir değeri seçtiğinizden emin olmaktır., üretimde dağıtılan ve veritabanında. Veritabanını güncelleyecek olan
A/B testi
Mevcut durum, canlıda dağıtılan 1.0.0sürüm uygulamasının ikinci bir örneğini dağıtmalıyız v1, o esnada bazı isteklerin sürüm örnekleri tarafından işlenmişti. 2.0.0güncelleme başarıyla geçti ve uygulamanızın birkaç çalışan örneği var v2.
Addımlar:
- çevrilmiş yeni tətbiq nümunəsi versiyası
2.0.0, bu da verilənlər bazasını yeniləyirv2 - ve diğer sürümler
1.0.0 - Hepsi veritabanıyla iletişim kuruyor
1.0.0veritabanında soyad sütununu kullanmıyor, ancak sürüm2.0.0.kullanıyor. Birbirlerine engel olmazlar ve hata olmamalıdır.v2 - versiya
1.0.0verileri hem eski hem de yeni sütunda saklar, böylece geriye dönük uyuşabilirlik sağlar2.0.0Eğer, değerleri eski / yeni sütundan sayan her hangi bir isteğiniz varsa, artık bir değer kopyası olduğuna dikkat etmelisiniz (büyük olasılıkla hala göç ediyorlar). Örneğin, soyadı (sütun ne olarak adlandırılırsa adlandırılsın) harfi ile başlayan kullanıcı sayısını saymak istiyorsanız, verilerin göçü tamamlanmadan önce ( - versiya
2.0.0old
Yeni oluşturulan sütun yeni sütun) yeni sütunu sorguluyorsanız tutarsız verilerle karşılaşabilirsiniz.
AŞimdi elimizde sürüm uygulaması varve veritabanı→uygulamanızı sürüme geri alıngeçmişteki verileri koruyarak
Tətbiqin geri dönməsi
görmeyi unutmayın. 2.0.0 Ayrıca, seçtiğiniz sütunun sürümü v2.
Addımlar:
- uygulamanızın yeni sürümüne geri dönmek isteyebilirsiniz.
1.0.0. - versiya
1.0.0DB-də sütun istifadə etmirsoyadı, buna görə geri qaytarma uğurlu olmalıdır
DB Dəyişiklikləri
DB-də adlandırılmış bir sütun var soyisim.
Flyway-nin orijinal skripti:
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');Əlavə etmə skripti soyadı.
Dikkat. Unutmayın ki, əlavə edilən sütuna NOLMAQ şərti götürülsün. JAR geri qaytarılırsa, köhnə versiya bu əlavə olunan sütunu bilməyəcək və avtomatik NULL dəyərini verəcək. Belə bir şərt varsa, köhnə tətbiq sıradan çıxacaq.
-- Qeyd: Bu sahə NOT NULL şərtin olmasına icazə verilmir, çünki geri qaytaranda köhnə versiya bu sahəni bilməyəcək
-- və həmişə NULL dəyərini verəcək
ALTER TABLE PERSON ADD surname varchar(255);
-- TEZ MİQRASİYA ETDİYİMİZİ GÖZLƏYİRİK - ƏKS TƏQDİRDƏ, BİZ PARTİYALARA MİQRASİYA ETMƏLİYİK
UPDATE PERSON SET PERSON.surname = PERSON.last_nameKod değişiklikleri
Məlumatları soyisim-fayllar. soyadı. Bu zaman soyisim, çünki bu sütun ən aktualdır. Təqdim prosesində bəzi sorğular hələ də yenilənməmiş tətbiq nümunəsi tərəfindən emal oluna bilər.
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
private String surname;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Reading from the new column if it's set. If not the from the old one.
*
* When migrating from version 1.0.0 -> 2.0.0 this can lead to a possibility that some data in
* the surname column is not up to date (during the migration process lastName could have been updated).
* In this case one can run yet another migration script after all applications have been deployed in the
* new version to ensure that the surname field is updated.
*
* However it makes sense since when looking at the migration from 2.0.0 -> 3.0.0. In 3.0.0 we no longer
* have a notion of lastName at all - so we don't update that column. If we rollback from 3.0.0 -> 2.0.0 if we
* would be reading from lastName, then we would have very old data (since not a single datum was inserted
* to lastName in version 3.0.0).
*/
public String getSurname() {
return this.surname != null ? this.surname : this.lastName;
}
/**
* Storing both FIRST_NAME and SURNAME entries
*/
public void setSurname(String surname) {
this.lastName = surname;
this.surname = surname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName + ", surname=" + this.surname
+ "]";
}
}3-cü addım: last_name-ı koddan silmək
Uygulama sürümü: 3.0.0
Veritabanı sürümü:v3
: Sonuncunu görmək üçün, mənim halımda, icra etdikdən sonra təxminən 10 dəqiqə gözləmək lazım idi
Qeyd: Görünür ki, orijinal məqalədə müəllif bu blokun mətnini 2-ci addımdan səhvən kopyalayıb. Bu addımda kodda last_name sütunundan istifadə edən funksionallığı silmək üçün dəyişikliklər edilməlidir. soyisim.
Yeni bir sütun əlavə edərək və onun məzmununu kopyalayaraq geriyə uyğun dəyişikliklər yaratdıq. Həmçinin, əgər JAR-ı geri qaytararsaq və ya işlətdiyimiz köhnə JAR varsa, icra zamanı sıradan çıxmayacaq.
Tətbiqin geri dönməsi
Hal-hazırda bizdə tətbiq versiyası var 3.0.0 və baza məlumatları v3. Versiya 3.0.0 məlumatları soyisim. Bu o deməkdir ki, soyadı ən aktual məlumatlar saxlanılır.
Addımlar:
- uygulamanızın yeni sürümüne geri dönmek isteyebilirsiniz.
2.0.0. - versiya
2.0.0istifadə edir vəsoyisimvəsoyadı. - versiya
2.0.0alacaqsoyadı, əgər null deyilsə, əks halda -soyisim
Veritabanı değişiklikleri
DB-də struktur dəyişikliyi yoxdur. Köhnə məlumatların son mqi̇rasiyası həyata keçirən skript icra olunur:
-- TEZ MİQRASİYA ETDİYİMİZİ GÖZLƏYİRİK - ƏKS TƏQDİRDƏ, BİZ PARTİYALARA MİQRASİYA ETMƏLİYİK
-- HƏMÇİNİN, MÖVCUD GİRMƏLƏRİ TƏKRAR ETMƏYİMİZİ YOXLAYIRIK. BİZ GİRMƏ VERSİYALARI KOMPENSASİYA ETMƏLİYİK
-- Əgər artıq daha yüksək versiya nömrəsi olan girilmiş bir qeyd varsa
-- BİZ ONU TƏKRAR ETMƏYƏCƏYİK.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;
-- NOT NULL ŞƏRTİNİ QALDIRMAQ; ƏKS HALDA LAST_NAME-ın NULL DƏYƏRİNİ GİRMƏYƏ CƏHD EDƏCƏKSİNİZ
-- NOT_NULL ŞƏRTİ ilə.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;Kod değişiklikleri
Qeyd: Bu blokun təsvirinin də səhvən 2-ci addımdan müəllif tərəfindən kopyalandığı görünür. Məqalənin hekayəsinin loqikasına uyğun olaraq, bu addımda kodda last_name sütunundan istifadə edən elementlərin silinməsi üçün dəyişikliklər edilməlidir. soyisim.
Məlumatları olaraq saxlayırıq soyisim-fayllar. surname. Bundan əlavə, biz soyisimsütunundan oxuyuruq, çünki bu ən aktualdır. Yayılma prosesi zamanı bəzi sorğular hələ də yenilənməmiş instansiya tərəfindən emal oluna bilər.
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String surname;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return this.surname;
}
public void setSurname(String lastname) {
this.surname = lastname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", surname=" + this.surname
+ "]";
}
}4-cü addım: last_name-ı DB-dən silmək
Uygulama sürümü: 4.0.0
Veritabanı sürümü: v4
: Sonuncunu görmək üçün, mənim halımda, icra etdikdən sonra təxminən 10 dəqiqə gözləmək lazım idi
Versiya kodunun 3.0.0 sütununu istifadə etmədiyi üçün, icra zamanı geri qaytarma zamanı xətalı bir şey baş verməyəcək soyisim, DB-dən sütunu silmədən sonra. 3.0.0 после удаления столбца из базы данных.
Skripti icraetmə jurnalı
Bunu aşağıdakı şəkildə edəcəyik:
01) 1.0.0 versiyasını işə sal
02) tətbiqin (1.0.0) yüklənməsini gözlə
03) POST localhost:9991/person çağıraraq 1.0.0 versiyasına bir şəxs yaradın
04) 2.0.0 versiyasını işə sal
05) tətbiqin (2.0.0) yüklənməsini gözlə
06) POST localhost:9991/person çağıraraq 1.0.0 versiyasına bir şəxs yaradın
07) POST localhost:9992/person çağıraraq 2.0.0 versiyasına bir şəxs yaradın
08) tətbiqi (1.0.0) öldür
09) 3.0.0 versiyasını işə sal
10) tətbiqin (3.0.0) yüklənməsini gözlə
11) POST localhost:9992/person çağıraraq 2.0.0 versiyasına bir şəxs yaradın
12) POST localhost:9993/person çağıraraq 3.0.0 versiyasına bir şəxs yaradın
13) tətbiqi (3.0.0) öldür
14) 4.0.0 versiyasını işə sal
15) tətbiqin (4.0.0) yüklənməsini gözlə
16) POST localhost:9993/person çağıraraq 3.0.0 versiyasına bir şəxs yaradın
17) POST localhost:9994/person çağıraraq 4.0.0 versiyasına bir şəxs yaradın
Tətbiqi 1.0.0 versiyasında işə salır
1.0.0 versiyasında bir şəxs yaradın
127.0.0.1:9991/person ünvanına post göndərilir. Bu cavabdır:
{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}
Tətbiqi 2.0.0 versiyasında işə salır
1.0.0 versiyasında bir şəxs yaradın
127.0.0.1:9991/person ünvanına post göndərilir. Bu cavabdır:
{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}
2.0.0 versiyasında bir şəxs yaradın
127.0.0.1:9992/person ünvanına post göndərilir. Bu cavabdır:
{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}
Tətbiqi 1.0.0 öldürür
Tətbiqi 3.0.0 versiyasında işə salır
2.0.0 versiyasında bir şəxs yaradın
127.0.0.1:9992/person ünvanına post göndərilir. Bu cavabdır:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}
3.0.0 versiyasında bir şəxs yaradın
127.0.0.1:9993/person ünvanına post göndərilir. Bu cavabdır:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}
Tətbiqi 2.0.0 öldürür
Tətbiqi 4.0.0 versiyasında işə salır
3.0.0 versiyasında bir şəxs yaradın
127.0.0.1:9993/person ünvanına post göndərilir. Bu cavabdır:
{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}
4.0.0 versiyasında bir şəxs yaradın
127.0.0.1:9994/person ünvanına post göndərilir. Bu cavabdır:
{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}DB Dəyişiklikləri
Münasibətdə v3 sadəcə sütunu silirik soyisim və itkin olan məhdudiyyətləri əlavə edirik.
-- SÜTUNU SİL
ALTER TABLE PERSON DROP last_name;
-- MEHDUDİYYƏTLƏRİ ƏLAVƏ ET
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;Kod değişiklikleri
Koddakı dəyişiklik yoxdur.
Çıktı
Bir neçə arxa uyğun quraşdırmanı həyata keçirmək yolu ilə sütun adını dəyişdirməkdə geri uyğun gəlməz dəyişiklik tətbiq etdik. Aşağıda həyata keçirilən fəaliyyətlərin xülasəsi:
- tətbiq versiyasında yayımlama
1.0.0cv1DB sxemləri (sütun adı =soyisim) - tətbiq versiyasında yayımlama
2.0.0,məlumatları saxlayırsoyisimvəsoyadı. Tətbiq oxuyursoyisim. DB hal-hazırda versiyadadırv2, içərisində aşağıdakı sütunlar varsoyisim, həm dəsurname. surnamel-nin surətidirast_name. (QEYD: bu sütun not null məhdudiyyətinə malik olmamalıdır) - tətbiq versiyasında yayımlama
3.0.0, yalnız məlumatları saxlayırsoyadıvə surname-dən oxuyur. DB-lə bağlı sonuncu miqrasiya baş verirsoyisimdaxilindədir.soyadı. Həmçinin məhdudiyyət . Eğer geri alıyorsanız, eski uygulama yeni sütunun varlığından haberdar değildir ve bunu şu yerdə götürülürsoyisim. DB indi versiyadadırv3 - tətbiq versiyasında yayımlama
4.0.0— kodda heç bir dəyişiklik yoxdur. DB yayımıv4, hansı ki, silinmişdirsoyisim. Burada DB-yə istənilən itkin olan məhdudiyyətləri əlavə edə bilərsiniz.
Bu yanaşmanı izləyərək, bir versiya geri qayıda bilərsiniz, məlumat bazası/applikasiyanı pozmadan.
Kod
Məqalədə istifadə olunan bütün kodlar . Aşağıda əlavə izahat.
Layihələr
Repo klonlandıqdan sonra, aşağıdakı qovluq strukturunu görəcəksiniz.
├── boot-flyway-v1 - 1.0.0 versiyası olan tətbiq v1 sxeması ilə
├── boot-flyway-v2 - 2.0.0 versiyası olan tətbiq v2 sxeması ilə (geriyə uyumlu - tətbiq geri qaytarıla bilər)
├── boot-flyway-v2-bad - 2.0.0.BAD versiyası olan tətbiq v2bad sxeması ilə (geriyə uyumlu deyil - tətbiq geri qaytarıla bilməz)
├── boot-flyway-v3 - 3.0.0 versiyası olan tətbiq v3 sxeması ilə (tətbiq geri qaytarıla bilər)
└── boot-flyway-v4 - 4.0.0 versiyası olan tətbiq v4 sxeması ilə (tətbiq geri qaytarıla bilər)Skripti
Aşağıda təsvir olunan skriptləri işə sala bilərsiniz, bu, geriyə uyumlu və uyğunsuz dəyişiklikləri DB-də nümayiş etdirmək üçün.
Görmək üçün geriyə uyumlu dəyişikliklər halı, işə salın:
.\/scripts\/scenario_backward_compatible.shVə geriyə uyumsuz dəyişikliklər halını görmək üçün .\/scripts\/scenario_backward_incompatible.sh, işə salın:
Spring Boot Sample FlywayBütün nümunələr
Spring Boot Sample Flyway-dan götürülüb. Siz
baxmaq üçün, orada skriptlərin siyahısı var. http://localhost:8080/flywayBu nümunə həmçinin H2 konsolunu (ünvan üzrə
), sizə verilənlər bazasının vəziyyətini izləməyə imkan tanıyır (varsayılan jdbc URL — http://localhost:8080/h2-consolejdbc:h2:mem:testdb Verilənlər bazası dəyişdirilməsi nümunələri).
Əlavə olaraq
Tekton Pipeline — Kubernetes-ə native pipelines
Mənbə: habr.com
