Zero Downtime Deployment and Databases

Zero Downtime Deployment and Databases

Lesi sihloko sichaza ngokuningiliziwe indlela yokuxazulula izinkinga zokuhambisana nesizindalwazi ekusetshenzisweni. Sizokutshela ukuthi yini engenzeka ezinhlelweni zakho zokukhiqiza uma uzama ukuphakela ngaphandle kokulungiselela kokuqala. Sizobe sesidlulela ezigabeni zomjikelezo wempilo wohlelo lokusebenza okudingeka ukuthi ube nesikhathi sokuphumula esinguziro (cishe. umzila: okunye - isikhathi sokuphumula se-zero). Umphumela wemisebenzi yethu uzoba ukusebenzisa ushintsho lwesizindalwazi olungahambelani nomuva ngendlela ehambisana nokubuyela emuva.

Uma ufuna ukuqonda izibonelo zekhodi evela esihlokweni, ungazithola kokuthi GitHub.

Isingeniso

I-Zero isikhathi sokungasebenzi

Yeka imfihlakalo i-zero downtime deployment? Ungasho ukuthi lokhu kulapho uhlelo lwakho lokusebenza lusetshenziswa ngendlela yokuthi ungakwazi ukwethula ngempumelelo inguqulo entsha yohlelo lokusebenza emkhiqizweni, kuyilapho umsebenzisi engaboni ukungatholakali kwalo. Ngokombono womsebenzisi nenkampani, lesi yisimo esingcono kakhulu esingakhona sokuthunyelwa ngoba sivumela izici ezintsha ukuthi zethulwe futhi iziphazamisi zilungiswe ngaphandle kokuphazamiseka.

Ukufeza kanjani lokhu? Kunezindlela eziningana, nansi enye yazo:

  • sebenzisa inguqulo No. 1 yesevisi yakho
  • yenza ukuthutha kwedathabheyisi
  • Sebenzisa inguqulo engu-#2 yesevisi yakho ngokuhambisana nenguqulo #1
  • ngokushesha nje lapho ubona leyo nguqulo No. 2 isebenza ngendlela efanele, susa inguqulo No. 1
  • ngomumo!

Kulula, akunjalo? Ngeshwa, akulula kangako, futhi sizokubheka ngokuningiliziwe kamuva. Manje ake sihlole enye inqubo evamile yokuphakelwa - ukuthunyelwa okuluhlaza okwesibhakabhaka.

Wake wezwa ukuthunyelwa okuluhlaza okwesibhakabhaka? I-Cloud Foundry yenza lokhu kube lula kakhulu. Bheka nje le ndatshana, lapho sichaza lokhu ngokuningiliziwe. Ukufingqa kafushane, ake sikukhumbuze ukuthi ungakwenza kanjani ukukhishwa okuluhlaza okwesibhakabhaka:

  • qinisekisa ukuthi amakhophi amabili ekhodi yakho yokukhiqiza (“luhlaza okwesibhakabhaka” kanye “nohlaza”) ayasebenza;
  • uqondise yonke ithrafikhi endaweni eluhlaza okwesibhakabhaka, i.e. ukuze ama-URL okukhiqiza akhombe lapho;
  • sebenzisa futhi uhlole zonke izinguquko zohlelo endaweni eluhlaza;
  • shintsha ama-url ukusuka eluhlaza okwesibhakabhaka ukuya endaweni eluhlaza

Ukukhishwa okuluhlaza okwesibhakabhaka kuyindlela ekuvumela ukuthi wethule kalula izici ezintsha ngaphandle kokukhathazeka ngokuphulwa kokukhiqiza. Lokhu kungenxa yokuthi noma kwenzeka okuthile, ungakwazi ukubuyela emuva kalula endaweni yangaphambilini ngokumane “ucime iswishi.”

Ngemva kokufunda konke lokhu okungenhla, ungase ubuze umbuzo: Ingabe i-zero downtime ihlangene ngani nokuthunyelwa okuluhlaza okuluhlaza?

Nokho, kuningi abafana ngakho, njengoba ukulondoloza amakhophi amabili endawo efanayo kudinga umzamo ophindwe kabili ukuwagcina. Yingakho amanye amaqembu ethi UMartin Fowler, landela okuhlukile kwale ndlela:

Enye inketho ukusebenzisa i-database efanayo, udale ukushintsha okuluhlaza okwesibhakabhaka kwezendlalelo zewebhu nezesizinda. Ngale ndlela, i-database ingaba yinkinga, ikakhulukazi uma udinga ukushintsha i-schema yayo ukuze usekele inguqulo entsha yesofthiwe.

Futhi lapha sifika enkingeni enkulu kulesi sihloko. Isizindalwazi. Ake siphinde sibheke lesi sisho.

yenza ukuthutha kwedathabheyisi.

Manje kufanele uzibuze umbuzo - kuthiwani uma ukuguqulwa kwedathabheyisi kungahambelani emuva? Ngeke yini inguqulo yami yokuqala yohlelo lokusebenza iphuke? Eqinisweni, yilokhu okuzokwenzeka...

Ngakho-ke, naphezu kwezinzuzo ezinkulu ze-zero downtime / blue green deployment, izinkampani zivame ukulandela le nqubo ephephile elandelayo yokuthumela izicelo zazo:

  • lungisa iphakheji ngenguqulo entsha yohlelo lokusebenza
  • vala uhlelo lokusebenza olusebenzayo
  • sebenzisa imibhalo ukuze uthuthe isizindalwazi
  • sebenzisa futhi uqalise inguqulo entsha yohlelo lokusebenza

Kulesi sihloko, sizocacisa ukuthi ungasebenzisa kanjani idatha yakho egciniwe kanye nekhodi ukuze usebenzise ithuba lokungasebenzi kahle.

Izinkinga zesizindalwazi

Uma unohlelo lokusebenza olungenasisekelo olungagcini noma iyiphi idatha kusizindalwazi, ungathola ukukhishwa kwe-zero yesikhathi sokuphumula ngokushesha. Ngeshwa, isofthiwe eminingi idinga ukugcina idatha ndawana thize. Yingakho kufanele ucabange kabili ngaphambi kokwenza noma yiziphi izinguquko kusekethe. Ngaphambi kokuthi singene emininingwaneni yokuthi singasishintsha kanjani i-schema ukuze kungabi bikho ukuthunyelwa kwe-downtime, ake siqale sigxile ku-schema sokuhumusha.

Uhlelo lokuhumusha

Kulesi sihloko sizosebenzisa I-Flyway njengethuluzi lokulawula inguqulo (cishe. Ukuhumusha: sikhuluma ngokufuduka kwesizindalwazi). Ngokwemvelo, sizophinde sibhale uhlelo lokusebenza lwe-Spring Boot olunosekelo olwakhelwe ngaphakathi lwe-Flyway futhi luzokwenza ukuthutha kwe-schema ngenkathi sisetha umongo wohlelo lokusebenza. Uma usebenzisa i-Flyway, ungagcina imibhalo yokuthuthela kufolda yephrojekthi yakho (ngokuzenzakalelayo ku- classpath:db/migration). Lapha ungabona isibonelo samafayela okuthutha anjalo

└── db
 └── migration
     ├── V1__init.sql
     ├── V2__Add_surname.sql
     ├── V3__Final_migration.sql
     └── V4__Remove_lastname.sql

Kulesi sibonelo sibona imibhalo engu-4 yokuthuthela, okuthi, uma ingazange isetshenziswe ngaphambilini, izosetshenziswa ngokulandelana lapho uhlelo luqala. Ake sibheke elinye lamafayela (V1__init.sql) njengesibonelo.

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');

Yonke into iyazichaza ngokwayo: ungasebenzisa i-SQL ukuchaza ukuthi isizindalwazi sakho kufanele siguqulwe kanjani. Ukuze uthole ukwaziswa okwengeziwe mayelana Spring Boot and Flyway, hlola I-Spring Boot Amadokhumenti.

Ngokusebenzisa ithuluzi lokulawula umthombo nge-Spring Boot, uthola izinzuzo ezinkulu ezi-2:

  • uhlukanisa izinguquko zesizindalwazi ezinguqukweni zekhodi
  • Ukuthutha kwesizindalwazi kwenzeka kanye nokukhishwa kohlelo lwakho lokusebenza, i.e. inqubo yakho yokusebenzisa yenziwe lula

Ukuxazulula izinkinga zesizindalwazi

Esigabeni esilandelayo sendatshana, sizogxila ekubhekeni izindlela ezimbili zokushintsha isizindalwazi.

  • ukungahambisani emuva
  • ukuhambisana emuva

Eyokuqala izobhekwa njengesexwayiso sokuthi akufanele wenze ukuthunyelwa kwe-zero isikhathi sokuphumula ngaphandle kokulungiswa kokuqala ... Owesibili unikeza isisombululo sendlela ongayenza ngayo ukuthunyelwa ngaphandle kwesikhathi sokuphumula futhi ngesikhathi esifanayo ugcine ukuhambisana emuva.

Iphrojekthi yethu esizosebenza kuyo kuzoba uhlelo olulula lwe-Spring Boot Flyway olunayo Person с first_name и last_name ku-database (cishe. ukuhumusha: Person itafula kanye first_name и last_name - lawa amasimu kuwo). Sifuna ukuqamba kabusha last_name в surname.

Ukuqagela

Ngaphambi kokuthi singene emininingwaneni, kunemibono embalwa okudingeka siyenze mayelana nezicelo zethu. Umphumela oyinhloko esifuna ukuwufinyelela uzoba inqubo elula.

Inothi. Ibhizinisi PRO-TIP. Izinqubo zokwenza lula zingakongela imali eningi ekusekelweni (lapho unabantu abaningi osebenzela inkampani yakho, imali eningi ongayonga)!

Asikho isidingo sokuhlehlisa isizindalwazi

Lokhu kwenza inqubo yokusebenzisa ibe lula (okunye ukubuyisela emuva kwesizindalwazi cishe akunakwenzeka, njengokuhlehlisa ukususa). Sincamela ukuhlehlisa izinhlelo zokusebenza kuphela. Ngale ndlela, ngisho noma unesizindalwazi esihlukile (isibonelo, i-SQL ne-NoSQL), ipayipi lakho lokuthumela lizobukeka lifana.

KUFANELE KUHLALE kwenzeke ukuhlehlisa uhlelo lokusebenza inguqulo eyodwa emuva (akusekho)

Ukubuyisela emuva kufanele kwenziwe kuphela uma kunesidingo. Uma kukhona iphutha enguqulweni yamanje engalungiseki kalula, kufanele sikwazi ukubuyela enguqulweni yakamuva yokusebenza. Sicabanga ukuthi le nguqulo yakamuva yokusebenza ingeyangaphambili. Ukugcina ikhodi nokuhambisana kwesizindalwazi sokukhishwa okungaphezu kokukodwa kungaba nzima kakhulu futhi kubize kakhulu.

Inothi. Ukuze ufundeke kakhulu, kulesi sihloko sizoshintsha inguqulo enkulu yohlelo lokusebenza.

Isinyathelo 1: Isimo sokuqala

Uhlobo lohlelo lokusebenza: 1.0.0
Inguqulo ye-DB: v1

Amazwana

Lesi kuzoba yisimo sokuqala sohlelo lokusebenza.

Izinguquko zesizindalwazi

I-DB iqukethe last_name.

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');

Ikhodi iyashintsha

Uhlelo lokusebenza lugcina idatha yomuntu last_name:

/*
 * 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
                + "]";
    }
}

Ukuqamba kabusha ikholomu engemuva okungahambelani

Ake sibheke isibonelo sendlela yokushintsha igama lekholomu:

Ukunakwa. Isibonelo esilandelayo sizophula izinto ngamabomu. Sibonisa lokhu ukuze sibonise inkinga yokuhambisana nesizindalwazi.

Uhlobo lohlelo lokusebenza: 2.0.0.BAD

Inguqulo ye-DB: v2bad

Amazwana

Izinguquko zamanje AZISIvumeli ukuthi senze izimo ezimbili (ezindala nezintsha) ngesikhathi esisodwa. Ngakho-ke, ukuthunyelwa kwe-zero downtime kuyoba nzima ukufeza (uma ukucabangela kucatshangelwa, empeleni akunakwenzeka).

Ukuhlolwa kwe-A/B

Isimo samanje ukuthi sinenguqulo yohlelo lokusebenza 1.0.0, kutshalwe emkhiqizweni, kanye nesizindalwazi v1. Sidinga ukusebenzisa isibonelo sesibili sohlelo lokusebenza, inguqulo 2.0.0.BAD, futhi ubuyekeze isizindalwazi ukuze v2bad.

Izinyathelo:

  1. isenzakalo esisha sohlelo lokusebenza lwenguqulo siyasetshenziswa 2.0.0.BADebuyekeza isizindalwazi ukuze v2bad
  2. ku-database v2bad ikholomu last_name ayisekho - yashintshwa yaba surname
  3. Isizindalwazi kanye nokubuyekezwa kohlelo lokusebenza kube yimpumelelo futhi ezinye izimo ziyasebenza 1.0.0, abanye - phakathi 2.0.0.BAD. Konke kuxhunywe kusizindalwazi v2bad
  4. zonke izimo zenguqulo 1.0.0 izoqala ukuphonsa amaphutha ngoba izozama ukufaka idatha kukholomu last_nameongasekho
  5. zonke izimo zenguqulo 2.0.0.BAD izosebenza ngaphandle kwezinkinga

Njengoba ubona, uma senza izinguquko ezibuyela emuva ezingahambelani kusizindalwazi nakuhlelo lokusebenza, ukuhlolwa kwe-A/B akunakwenzeka.

Ukubuyisela emuva isicelo

Ake sicabange ukuthi ngemuva kokuzama ukwenza ukuthunyelwa kwe-A/B (cishe. ngokwe.: umbhali cishe ubeqonde ukuhlolwa kwe-A/B lapha) sinqume ukuthi sidinga ukuhlehlisa uhlelo lokusebenza enguqulweni 1.0.0. Ake sithi asifuni ukuhlehlisa isizindalwazi.

Izinyathelo:

  1. simisa isibonelo sohlelo lokusebenza lwenguqulo 2.0.0.BAD
  2. i-database isekhona v2bad
  3. kusukela inguqulo 1.0.0 akaqondi ukuthi kuyini surname, sizobona amaphutha
  4. isihogo sephukile, ngeke sisabuyela emuva

Njengoba ubona, uma senza izinguquko ezibuyela emuva ezingahambelani kusizindalwazi kanye nohlelo lokusebenza, asikwazi ukubuyela emuva enguqulweni yangaphambilini.

Amalogi wokwenza iskripthi

Backward incompatible scenario:

01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0.BAD
05) Wait for the app (2.0.0.BAD) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0 <-- this should fail
07) Generate a person by calling POST localhost:9992/person to version 2.0.0.BAD <-- this should pass

Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}

Starting app in version 2.0.0.BAD
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

curl: (22) The requested URL returned error: 500 Internal Server Error

Generate a person in version 2.0.0.BAD
Sending a post to 127.0.0.1:9995/person. This is the response:

{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}

Izinguquko zesizindalwazi

Iskripthi sokuthutha esiqamba kabusha last_name в surname

Iskripthi somthombo we-Flyway:

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');

Iskripthi esiqamba kabusha last_name.

-- This change is backward incompatible - you can't do A/B testing
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;

Ikhodi iyashintsha

Sishintshe igama lenkundla lastName on surname.

Ukuqamba kabusha ikholomu ngendlela ehambisana nemuva

Lesi yisimo esivame kakhulu esingase sibhekane naso. Kudingeka senze izinguquko ezibuyela emuva ezingahambelani. Sesivele sifakazele ukuthi ekusetshenzisweni kwe-zero-downtime, akufanele sivele sisebenzise ukuthuthwa kwesizindalwazi ngaphandle kwezinyathelo ezengeziwe. Kulesi sigaba se-athikili, sizokwenza ukusetshenziswa okungu-3 kohlelo lokusebenza kanye nokuthuthwa kwesizindalwazi ukuze sithole umphumela oyifunayo kuyilapho sigcina ukusebenzisana okubuyela emuva.

Inothi. Khumbula ukuthi sinesizinda solwazi senguqulo v1. Iqukethe amakholomu first_name и last_name. Kufanele sishintshe last_name on surname. Siphinde sibe nenguqulo yohlelo lokusebenza 1.0.0, okungakasetshenziswa surname.

Isinyathelo sesi-2: Faka isibongo

Uhlobo lohlelo lokusebenza: 2.0.0
Inguqulo ye-DB: v2

Amazwana

Ngokungeza ikholomu entsha nokukopisha ekuqukethe, sidala izinguquko zesizindalwazi ezihambisanayo ezibuyela emuva. Ngesikhathi esifanayo, uma sibuyisela emuva i-JAR noma sine-JAR endala esebenzayo, ngeke iphuke ngesikhathi sokuyikhipha.

Senza inguqulo entsha

Izinyathelo:

  1. yenza ukuthutha kwesizindalwazi ukuze udale ikholomu entsha surname. Manje inguqulo yakho ye-DB v2
  2. kopisha idatha kusuka last_name в surname. Nakaniukuthi uma unale datha eningi, kufanele ucabangele ukufuduka kweqoqo!
  3. bhala ikhodi lapho zisetshenziswa khona KOKUBILI и новыйfuthi ezindala ikholomu. Manje inguqulo yakho yohlelo lokusebenza 2.0.0
  4. funda inani elikukholomu surname, uma kungenjalo null, noma kusuka ku-last_name, uma surname akucacisiwe. Ungakwazi ukususa getLastName() kusuka kukhodi, ngoba izokhipha null lapho ubuyisela isicelo sakho emuva 3.0.0 ukuze 2.0.0.

Uma usebenzisa i-Spring Boot Flyway, lezi zinyathelo ezimbili zizokwenziwa ngesikhathi sokuqalisa inguqulo 2.0.0 izicelo. Uma usebenzisa ithuluzi lokuguqulela lesizindalwazi ngesandla, kuzodingeka wenze izinto ezimbili ezihlukene ukwenza lokhu (qala ubuyekeze inguqulo ye-db mathupha bese usebenzisa uhlelo olusha lokusebenza).

Kubalulekile. Khumbula ukuthi ikholomu esanda kwakhiwa AKUFANELE быть HHAYI NULL. Uma wenza ukubuyisela emuva, uhlelo lokusebenza oludala alwazi mayelana nekholomu entsha futhi ngeke luyifake phakathi Insert. Kepha uma ungeza lesi sivimbelo futhi i-db yakho izoba v2, lokhu kuzodinga ukusetha inani lekholomu entsha. Okuzoholela ekwephuleni imikhawulo.

Kubalulekile. Kufanele ususe indlela getLastName(), ngoba enguqulweni 3.0.0 Awukho umqondo wekholomu kukhodi last_name. Lokhu kusho ukuthi i-null izosethwa lapho. Ungashiya indlela bese wengeza amasheke null, kodwa isisombululo esingcono kakhulu kungaba ukuqinisekisa ukuthi ku-logic getSurname() ukhethe inani elilungile elingelona uziro.

Ukuhlolwa kwe-A/B

Isimo samanje ukuthi sinenguqulo yohlelo lokusebenza 1.0.0, isetshenziswe ekukhiqizeni, kanye nesizindalwazi ku v1. Sidinga ukuphakela isibonelo sesibili sohlelo lokusebenza lwenguqulo 2.0.0ezobuyekeza isizindalwazi ukuze v2.

Izinyathelo:

  1. isenzakalo esisha sohlelo lokusebenza lwenguqulo siyasetshenziswa 2.0.0ebuyekeza isizindalwazi ukuze v2
  2. Okwamanje ezinye izicelo zacutshungulwa yizinguqulo 1.0.0
  3. isibuyekezo sibe yimpumelelo futhi unezimo eziningi ezisebenzayo zohlelo lokusebenza lwenguqulo 1.0.0 nezinye izinguqulo 2.0.0. Wonke umuntu uxhumana nesizindalwazi ku v2
  4. inguqulo 1.0.0 ayisebenzisi ikholomu yesibongo kusizindalwazi, kodwa inguqulo 2.0.0 isebenzisa. Azigxambukeli, futhi akufanele kube namaphutha.
  5. inguqulo 2.0.0 igcina idatha kukholamu endala nentsha, iqinisekisa ukuhambisana okusemuva

Kubalulekile. Uma unanoma yimiphi imibuzo ebala izinto ngokusekelwe kumanani asuka kukholomu endala/entsha, kufanele ukhumbule ukuthi manje usunamanani ayimpinda (okungenzeka ukuthi asafuduka). Isibonelo, uma ufuna ukubala inombolo yabasebenzisi isibongo sabo (noma ngabe ikholomu ibizwa ngani) iqale ngohlamvu A, bese kuze kuqedwe ukuthuthwa kwedatha (oldnew column) ungase ube nedatha engahambisani uma ubuza ikholomu entsha.

Ukubuyisela emuva isicelo

Manje sinenguqulo yohlelo lokusebenza 2.0.0 kanye ne-database ku v2.

Izinyathelo:

  1. buyisela uhlelo lwakho lokusebenza enguqulweni 1.0.0.
  2. inguqulo 1.0.0 ayisebenzisi ikholomu kusizindalwazi surname, ngakho ukubuyisela emuva kufanele kuphumelele

Ukushintsha kwe-DB

Isizindalwazi siqukethe ikholomu enegama last_name.

Isikripthi somthombo we-Flyway:

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');

Engeza umbhalo surname.

Ukunakwa. Khumbula ukuthi AWUKWAZI UKUNGEZA noma yiziphi izithiyo EZINGABE ZILILI kukholomu oyingezayo. Uma ubuyisela emuva i-JAR, inguqulo endala ngeke ibe nombono mayelana nekholomu eyengeziwe futhi izoyisetha ngokuzenzakalelayo ukuze ithi NULL. Uma kunomkhawulo onjalo, isicelo esidala sizomane sephule.

-- NOTE: This field can't have the NOT NULL constraint cause if you rollback, the old version won't know about this field
-- and will always set it to NULL
ALTER TABLE PERSON ADD surname varchar(255);

-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
UPDATE PERSON SET PERSON.surname = PERSON.last_name

Ikhodi iyashintsha

Sigcina idatha njenge last_name, futhi surname. Ngesikhathi esifanayo sifunda kusukela last_name, njengoba le kholomu ifaneleka kakhulu. Phakathi nenqubo yokuthunyelwa, ezinye izicelo kungenzeka zicutshungulwe isibonelo esingakabuyekezwa.

/*
 * 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
                + "]";
    }
}

Isinyathelo sesi-3: Ukukhipha isibongo_igama kukhodi

Uhlobo lohlelo lokusebenza: 3.0.0

Inguqulo ye-DB:v3

Amazwana

Qaphela nge. last_name.

Ngokungeza ikholomu entsha nokukopisha ekuqukethe, sidale izinguquko zesizindalwazi ezihambisanayo ezibuyela emuva. Futhi, uma sibuyisela emuva i-JAR noma sine-JAR endala esebenzayo, ngeke iphuke ngesikhathi sokuyikhipha.

Ukubuyisela emuva isicelo

Okwamanje sinenguqulo yohlelo lokusebenza 3.0.0 kanye nesizindalwazi v3. Inguqulo 3.0.0 ayilondolozi idatha kuyo last_name. Lokhu kusho ukuthi ku surname ulwazi lwakamuva kakhulu lugcinwa.

Izinyathelo:

  1. buyisela uhlelo lwakho lokusebenza enguqulweni 2.0.0.
  2. inguqulo 2.0.0 ukusetshenziswa kanye last_name и surname.
  3. inguqulo 2.0.0 izothatha surname, uma kungeyena uziro, kungenjalo -last_name

Izinguquko zesizindalwazi

Azikho izinguquko zesakhiwo kusizindalwazi. Isikripthi esilandelayo sisetshenziswa ukuze kwenziwe ukuthutha kokugcina kwedatha endala:

-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
-- ALSO WE'RE NOT CHECKING IF WE'RE NOT OVERRIDING EXISTING ENTRIES. WE WOULD HAVE TO COMPARE
-- ENTRY VERSIONS TO ENSURE THAT IF THERE IS ALREADY AN ENTRY WITH A HIGHER VERSION NUMBER
-- WE WILL NOT OVERRIDE IT.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;

-- DROPPING THE NOT NULL CONSTRAINT; OTHERWISE YOU WILL TRY TO INSERT NULL VALUE OF THE LAST_NAME
-- WITH A NOT_NULL CONSTRAINT.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;

Ikhodi iyashintsha

Qaphela ngokwe.: Incazelo yaleli bhulokhi nayo ikopishwe ngephutha ngumbhali kusukela esinyathelweni sesi-2. Ngokuhambisana nokucabanga kwe-athikili, izinguquko kukhodi kulesi sinyathelo kufanele zihloselwe ukususa kuyo izici ezisebenza nekholomu. last_name.

Sigcina idatha njenge last_name, futhi surname. Ukwengeza, sifunda kukholamu last_name, njengoba ifaneleka kakhulu. Phakathi nenqubo yokuthunyelwa, ezinye izicelo zingase zicutshungulwe yisibonelo esingakathuthukiswa.

/*
 * 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
                + "]";
    }
}

Isinyathelo sesi-4: Ukukhipha last_name kusizindalwazi

Uhlobo lohlelo lokusebenza: 4.0.0

Inguqulo ye-DB: v4

Amazwana

Ngenxa yokuthi ikhodi yenguqulo 3.0.0 akazange asebenzise ikholomu last_name, akukho okubi okuzokwenzeka ngesikhathi sokubulawa uma sibuyela emuva 3.0.0 ngemva kokukhipha ikholomu kusizindalwazi.

Amalogi wokwenza iskripthi

We will do it in the following way:

01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0
05) Wait for the app (2.0.0) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0
07) Generate a person by calling POST localhost:9992/person to version 2.0.0
08) Kill app (1.0.0)
09) Run 3.0.0
10) Wait for the app (3.0.0) to boot
11) Generate a person by calling POST localhost:9992/person to version 2.0.0
12) Generate a person by calling POST localhost:9993/person to version 3.0.0
13) Kill app (3.0.0)
14) Run 4.0.0
15) Wait for the app (4.0.0) to boot
16) Generate a person by calling POST localhost:9993/person to version 3.0.0
17) Generate a person by calling POST localhost:9994/person to version 4.0.0

Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}

Starting app in version 2.0.0

Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}

Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:

{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}

Killing app 1.0.0

Starting app in version 3.0.0

Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}

Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}

Killing app 2.0.0

Starting app in version 4.0.0

Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:

{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}

Generate a person in version 4.0.0
Sending a post to 127.0.0.1:9994/person. This is the response:

{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}

Ukushintsha kwe-DB

Ngokuqhathaniswa v3 sivele sisuse ikholomu last_name bese wengeza imikhawulo engekho.

-- REMOVE THE COLUMN
ALTER TABLE PERSON DROP last_name;

-- ADD CONSTRAINTS
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;

Ikhodi iyashintsha

Azikho izinguquko kukhodi.

isiphetho

Sisebenzise ngempumelelo ukuguqulwa kwegama lekholomu eya emuva-elingahambisani ngokwenza ukusetshenziswa okuningana okuhambisana nokubuyela emuva. Ngezansi isifinyezo sezenzo ezenziwe:

  1. ukuthunyelwa kwenguqulo yohlelo lokusebenza 1.0.0 с v1 i-schema sedathabhesi (igama lekholomu = last_name)
  2. ukuthunyelwa kwenguqulo yohlelo lokusebenza 2.0.0, egcina idatha kuyo last_name и surname. Isicelo sifundeka ku- last_name. Isizindalwazi sikunguqulo v2equkethe amakholomu afana last_name, futhi surname. surname ikhophi ye-last_name. (QAPHELA: Le kholomu akufanele ibe nesivimbelo esingelona ize)
  3. ukuthunyelwa kwenguqulo yohlelo lokusebenza 3.0.0, egcina idatha kuphela surname futhi ufunda esibongo. Ngokuqondene nesizindalwazi, ukufuduka kokugcina kuyenzeka last_name в surname. Futhi umkhawulo HHAYI NULL kukhishwe last_name. Isizindalwazi manje sesisenguqulweni v3
  4. ukuthunyelwa kwenguqulo yohlelo lokusebenza 4.0.0 - azikho izinguquko ezenziwa kukhodi. Ukuthunyelwa kwesizindalwazi v4, esusayo last_name. Lapha ungakwazi ukwengeza noma yiziphi izithiyo ezingekho kusizindalwazi.

Ngokulandela le ndlela, ungakwazi njalo ukubuyisela emuva inguqulo eyodwa ngaphandle kokwephula isizindalwazi/ukuhambisana kohlelo lokusebenza.

Ikhodi

Wonke amakhodi asetshenziswe kulesi sihloko atholakala ku- I-Github. Ngezansi kunencazelo eyengeziwe.

Amaphrojekthi

Ngemva kokuhlanganisa indawo yokugcina, uzobona isakhiwo sefolda esilandelayo.

├── boot-flyway-v1              - 1.0.0 version of the app with v1 of the schema
├── boot-flyway-v2              - 2.0.0 version of the app with v2 of the schema (backward-compatible - app can be rolled back)
├── boot-flyway-v2-bad          - 2.0.0.BAD version of the app with v2bad of the schema (backward-incompatible - app cannot be rolled back)
├── boot-flyway-v3              - 3.0.0 version of the app with v3 of the schema (app can be rolled back)
└── boot-flyway-v4              - 4.0.0 version of the app with v4 of the schema (app can be rolled back)

Imibhalo

Ungaqalisa izikripthi ezichazwe emibhalweni engezansi, ezobonisa izinguquko ezihambisana nokubuyela emuva nezingahambisani kusizindalwazi.

Ukubona icala elinezinguquko eziya emuva ezihambisanayo, gijima:

./scripts/scenario_backward_compatible.sh

Futhi ukubona icala elinezinguquko ezibuyela emuva ezingahambelani, gijima:

./scripts/scenario_backward_incompatible.sh

I-Flyway yesampula ye-Spring Boot

Zonke izibonelo zithathwe kuyo Spring Boot Sample Flyway.

Ungabheka http://localhost:8080/flyway, kunohlu lwemibhalo.

Lesi sibonelo sihlanganisa ne-H2 console (at http://localhost:8080/h2-console) ukuze ukwazi ukubuka isimo sesizindalwazi (i-URL ezenzakalelayo ye-jdbc jdbc:h2:mem:testdb).

Okuthuthukisiwe

Funda nezinye izindatshana kubhulogi yethu:

Source: www.habr.com

Engeza amazwana