I-Zero yokuPhathwa kweXesha lokuPhuhliswa kunye neDathabase

I-Zero yokuPhathwa kweXesha lokuPhuhliswa kunye neDathabase

Eli nqaku lichaza ngokweenkcukacha indlela yokusombulula imiba yokuhambelana kwedatha ekuhanjisweni. Siza kukuxelela into enokwenzeka kwizicelo zakho zemveliso ukuba uzama ukuhambisa ngaphandle kokulungiselela kwangaphambili. Emva koko siya kudlula kwisigaba sobomi besicelo esifunekayo ukuba ube nexesha lokuphumla (malunga. umzila: phambili - zero ixesha lokuphumla). Isiphumo semisebenzi yethu iya kuba kukusebenzisa umva-ongahambelaniyo notshintsho lwesiseko sedatha ngendlela ehambelana nomva.

Ukuba ufuna ukuqonda imizekelo yekhowudi ephuma kwinqaku, unokuzifumana kuyo GitHub.

Intshayelelo

Zero downtime deployment

Yintoni engaqondakaliyo zero downtime deployment? Unokuthi oku kuxa isicelo sakho sibekwe ngendlela yokuba ukwazi ukwazisa ngempumelelo inguqulelo entsha yesicelo kwimveliso, ngelixa umsebenzisi engaboni ukungafumaneki kwayo. Ukusuka kumbono womsebenzisi kunye nenkampani, le yeyona meko ingcono yokusasazwa kuba ivumela ukuba kuqaliswe izinto ezintsha kwaye iibugs zilungiswe ngaphandle kokuphazamiseka.

Indlela yokuphumeza oku? Kukho iindlela ezininzi, nantsi enye yazo:

  • deploy version No. 1 yenkonzo yakho
  • yenza ufuduko lwedatabase
  • Sebenzisa inguqulo #2 yenkonzo yakho ngokuhambelana nenguqulo #1
  • kamsinya nje ukuba ubona loo nguqulo No. 2 isebenza njengoko kufanele, susa uguqulelo No
  • lungile!

Kulula, akunjalo? Ngelishwa, akulula kangako, kwaye siza kujonga oko ngokweenkcukacha kamva. Ngoku makhe sijonge enye inkqubo eqhelekileyo yokusasazwa - ukusasazwa okuluhlaza okwesibhakabhaka.

Wakhe weva blue blue deployment? Cloud Foundry yenza oku kube lula kakhulu. Jonga nje Oku kubhaliwe, apho sichaza oku ngokubanzi. Ukushwankathela ngokufutshane, masikukhumbuze indlela yokwenza ukusasazwa okuluhlaza okwesibhakabhaka:

  • qinisekisa ukuba iikopi ezimbini zekhowudi yakho yokuvelisa (“blue” kunye “noluhlaza”) ziyasebenza;
  • uqondise yonke i-traffic kwindawo eluhlaza okwesibhakabhaka, okt. ukuze ii-URL zemveliso zikhombe apho;
  • sebenzisa kwaye uvavanye lonke utshintsho lwesicelo kwindawo eluhlaza;
  • tshintsha ii-urls ukusuka eluhlaza ukuya kwindawo eluhlaza

Ukusasazwa okuluhlaza okuluhlaza yindlela ekuvumela ukuba ungenise lula izinto ezintsha ngaphandle kokukhathazeka malunga nokuqhekeka kwemveliso. Oku kungenxa yokuba nokuba kukho into eyenzekayo, unokubuyela umva kwindawo yangaphambili ngokulula “ngokucofa iswitshi.”

Emva kokufunda konke oku kungasentla, unokubuza umbuzo: Ingaba i-zero downtime inento yokwenza neBlue green deployment?

Ewe, zininzi kakhulu abafana ngazo, kuba ukugcina iikopi ezimbini zendawo enye kufuna umgudu ophindwe kabini ukuzigcina. Yiloo nto amanye amaqela ebanga UMartin Fowler, landela ukwahluka kwale ndlela:

Enye inketho kukusebenzisa i-database efanayo, udala iiswitshi eziluhlaza okwesibhakabhaka kwiwebhu kunye ne-domain layers. Kule ndlela, i-database ingaba yingxaki, ngakumbi xa ufuna ukutshintsha i-schema yayo ukuxhasa inguqulelo entsha yesoftware.

Kwaye apha siza kwingxaki ephambili kweli nqaku. Indawo yedatha. Masiphinde sijonge eli binzana.

yenza ufuduko lwedatabase.

Ngoku kufuneka uzibuze umbuzo - kuthekani ukuba utshintsho lwedatha aluhambisani ngasemva? Ngaba uguqulelo lwam lokuqala lwe-app aluyi kuqhawuka? Enyanisweni, oku kuya kwenzeka kanye ...

Ke, nangona izibonelelo ezinkulu ze-zero downtime / blue green deployment, iinkampani zihlala zilandela le nkqubo ikhuselekileyo yokuthumela izicelo zazo:

  • lungisa ipakethe ngoguqulelo olutsha lwesicelo
  • cima usetyenziso olusebenzayo
  • sebenzisa izikripthi ukufudusa idatabase
  • sebenzisa kwaye uqalise uguqulelo olutsha lwesicelo

Kweli nqaku, siza kuchaza indlela onokusebenza ngayo kunye nedatha yakho kunye nekhowudi ukuze uthathe ithuba lokusebenzisa ixesha lokuphumla.

Imiba yeDatabase

Ukuba unesicelo esingenammiselo esingagcini nayiphi na idatha kwisiseko sedatha, unokufumana i-zero downtime deployment ngoko nangoko. Ngelishwa, uninzi lwesoftware kufuneka lugcine idatha kwenye indawo. Kungenxa yoko le nto kufuneka ucinge kabini phambi kokuba wenze naluphi na utshintsho kwisekethe. Ngaphambi kokuba singene kwiinkcukacha zendlela yokutshintsha i-schema ukuze kungabikho xesha lokuphumla linokwenzeka, masiqale sigxile kwi-schema yoguqulelo.

Iskimu soguqulelo

Kweli nqaku siza kusebenzisa Flyway njengesixhobo solawulo loguqulelo (malunga. Uguqulo: sithetha ngokufuduswa kwedatha). Ngokwendalo, siya kubhala kwakhona isicelo se-Spring Boot esakhelwe-kwi-Flyway inkxaso kwaye siya kwenza ukufuduka kwe-schema ngelixa siseta umxholo wesicelo. Xa usebenzisa iFlyway, ungagcina izikripthi zokufuduka kwifolda yeeprojekthi zakho (ngokungagqibekanga kwi classpath:db/migration). Apha unokubona umzekelo weefayile zokufuduka ezinjalo

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

Kulo mzekelo sibona izikripthi ezi-4 zokufuduka, ukuba azizange zenziwe ngaphambili, ziya kuphunyezwa enye emva kwenye xa isicelo siqala. Makhe sijonge enye yeefayile (V1__init.sql) njengomzekelo.

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 ngokugqibeleleyo: ungasebenzisa iSQL ukuchaza ukuba isiseko sakho sedatha kufuneka siguqulwe njani. Ngolwazi oluthe kratya malunga neSpring Boot kunye neFlyway, jonga I-Spring Boot Docs.

Ngokusebenzisa isixhobo sokulawula umthombo nge-Spring Boot, ufumana izibonelelo ezi-2 ezinkulu:

  • Uzahlula iinguqu zesiseko sedata kwiinguqu zekhowudi
  • Ukufuduka kwedatha kwenzeka kunye nokukhutshwa kwesicelo sakho, okt. inkqubo yakho yokuthunyelwa yenziwe lula

Ukusombulula iingxaki zedatabase

Kwicandelo elilandelayo lenqaku, siza kugxila ekujongeni iindlela ezimbini zokutshintsha kwedatha.

  • ukungahambelani ngasemva
  • ukuhambelana komva

Eyokuqala iya kuthathwa njengesilumkiso sokuba akufanele wenze i-zero downtime deployment ngaphandle kokulungiswa kwangaphambili ... Owesibini unika isisombululo malunga nendlela ongayenza ngayo ukuthunyelwa ngaphandle kwexesha lokuphumla kwaye ngexesha elifanayo ugcine ukuhambelana ngasemva.

Iprojekthi yethu esiza kusebenza kuyo iya kuba sisicelo esilula se-Spring Boot Flyway esinayo Person с first_name и last_name kuvimba weenkcukacha (malunga. inguqulelo: Person yitafile kunye first_name и last_name - ezi ngamasimi kuyo). Sifuna ukuthiya ngokutsha last_name в surname.

Iingqikelelo

Ngaphambi kokuba singene kwiinkcukacha, kukho iingqikelelo ezimbalwa ekufuneka sizenze malunga nezicelo zethu. Isiphumo esiphambili esifuna ukusifumana siya kuba yinkqubo elula.

Zametka. Ishishini PRO-TIP. Ukwenza lula iinkqubo kunokukongela imali eninzi kwinkxaso (xa abantu abaninzi usebenza kwinkampani yakho, imali eninzi onokuyigcina)!

Akukho mfuneko yokubuyisela umva isiseko sedatha

Oku kuyenza lula inkqubo yokusasazwa (ezinye ii-rollbacks zesiseko sedatha ziphantse zingenzeki, ezifana nokucima umva). Sikhetha ukubuyisela umva kuphela izicelo. Ngale ndlela, nokuba unesiseko sedatha ezahlukeneyo (umzekelo, iSQL kunye neNoSQL), umbhobho wakho wokuhanjiswa uya kujongeka ngokufanayo.

Kufuneka KUHLALE kusenzeka ukuqengqeleka umva isicelo uguqulelo olunye emva (akusekho)

Ukubuyisela umva kufuneka kwenziwe kuphela xa kuyimfuneko. Ukuba kukho isiphene kuguqulelo lwangoku olungalungiseki lula, kufuneka sikwazi ukubuyela kuguqulelo olusebenzayo lwamva nje. Sicinga ukuba le nguqulo yamva nje yokusebenza yile yangaphambili. Ukugcina ikhowudi kunye nokuhambelana kwesiseko sedatha kukhuko olungaphezulu kwesinye kuya kuba nzima kakhulu kwaye kuyabiza.

Inqaku. Ukufundela ngakumbi, kweli nqaku siza kutshintsha inguqulelo enkulu yesicelo.

Inyathelo 1: Ilizwe lokuqala

Inguqulelo yeapp: 1.0.0
Inguqulelo yeDB: v1

Inkcazo

Oku kuya kuba yimeko yokuqala yesicelo.

Utshintsho lwesiseko sedatha

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

Iikhowudi ziyatshintsha

Isicelo sigcina idatha yoMntu ngaphakathi 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
                + "]";
    }
}

Ukubuyisela ngasemva ukutshintshwa kwekholamu engahambelaniyo

Makhe sijonge umzekelo wendlela yokutshintsha igama lekholamu:

Ingqalelo. Lo mzekelo ulandelayo uya kwaphula izinto ngabom. Sibonisa oku ukubonisa ingxaki yokuhambelana kwedatha.

Inguqulelo yeapp: 2.0.0.BAD

Inguqulelo yeDB: v2bad

Inkcazo

Utshintsho lwangoku AKUSIvumeli ukuba siqhube iimeko ezimbini (ezindala nezintsha) ngexesha elinye. Ngaloo ndlela, ukuthunyelwa kwe-zero downtime kuya kuba nzima ukufezekisa (ukuba ukucinga kuthathelwa ingqalelo, akunakwenzeka ngokwenene).

Uvavanyo lwe-A/B

Imeko yangoku kukuba sinenguqulelo yesicelo 1.0.0, zibekwe kwimveliso, kunye nedathabheyisi v1. Kufuneka sisebenzise umzekelo wesibini wesicelo, inguqulelo 2.0.0.BAD, kwaye uhlaziye idatabase ukuba v2bad.

Amanyathelo:

  1. Umzekelo omtsha wesicelo soguqulelo ubekiwe 2.0.0.BADehlaziya isiseko sedatha kuyo v2bad
  2. kwiziko ledatha v2bad ikholamu last_name ayisekho - yatshintshwa yaba surname
  3. Ugcino lwedatha kunye nohlaziyo lwesicelo lube yimpumelelo kwaye eminye imizekelo iyasebenza 1.0.0, abanye - ngaphakathi 2.0.0.BAD. Yonke into iqhagamshelwe kwi-database v2bad
  4. yonke imizekelo yenguqulelo 1.0.0 iyakuqala ukuphosa iimpazamo kuba baya kuzama ukufaka idatha kwikholamu last_nameongasekhoyo
  5. yonke imizekelo yenguqulelo 2.0.0.BAD iya kusebenza ngaphandle kweengxaki

Njengoko ubona, ukuba senza umva utshintsho olungahambelaniyo kwisiseko sedatha kunye nesicelo, uvavanyo lwe-A / B alunakwenzeka.

Ukubuyisela umva isicelo

Makhe sicinge ukuba emva kokuzama ukwenza ukuthunyelwa kwe-A/B (malunga. ngokwe.: umbhali mhlawumbi wayethetha uvavanyo lwe-A/B apha) sigqibe ekubeni kufuneka sibuyisele umva isicelo kuguqulelo 1.0.0. Masithi asifuni kukubuyisela umva isiseko sedatha.

Amanyathelo:

  1. simisa umzekelo wesicelo soguqulelo 2.0.0.BAD
  2. uvimba weenkcukacha usekho v2bad
  3. ukususela kwinguqulelo 1.0.0 ayiqondi ukuba yintoni na surname, siza kubona iimpazamo
  4. isihogo siqhawukile, asinakubuyela emva

Njengoko ubona, ukuba senza umva utshintsho olungahambelaniyo kwisiseko sedatha kunye nesicelo, asinakubuyela umva kuguqulelo lwangaphambili.

Iilogi zokwenziwa kweSikripthi

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"}

Utshintsho lwesiseko sedatha

Iskripthi sokufuduka esithiya ngokutsha last_name в surname

Umthombo weskripthi seFlyway:

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

Ushicilelo oluthiya ngokutsha last_name.

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

Iikhowudi ziyatshintsha

Sitshintshe igama lendawo lastName phezu surname.

Ukuthiya ngokutsha ikholamu ngendlela ehambelana nomva

Le yeyona meko ixhaphakileyo esinokudibana nayo. Kufuneka senze umva utshintsho olungahambelaniyo. Sele sibonisile ukuba kwi-zero-downtime deployment, akufuneki sisebenzise ukufuduka kwedatha ngaphandle kwamanyathelo ongezelelweyo. Kweli candelo lenqaku, siya kwenza ukusetyenziswa kwe-3 kwesicelo kunye nokufuduka kwedatha ukufikelela kwisiphumo esifunekayo ngelixa sigcina ukuhambelana komva.

Zametka. Khumbula ukuba sinesiseko sedatha yenguqulelo v1. Iqulethe iikholamu first_name и last_name. Kufuneka sitshintshe last_name phezu surname. Sikwanayo nenguqulelo ye-app 1.0.0, engekasetyenziswa surname.

Inyathelo lesi-2: Yongeza ifani

Inguqulelo yeapp: 2.0.0
Inguqulelo yeDB: v2

Inkcazo

Ngokongeza ikholamu entsha kunye nokukopisha imixholo yayo, senza utshintsho oluhambelanayo lwedatha. Kwangaxeshanye, ukuba sibuyisela umva i-JAR okanye sine-JAR endala eqhubayo, ayizukwaphuka ngexesha lokubulawa.

Sikhupha inguqulelo entsha

Amanyathelo:

  1. yenza ufuduko lwesiseko sedata ukwenza umhlathi omtsha surname. Ngoku inguqulelo yakho yeDB v2
  2. khuphela idatha evela last_name в surname. Nika ingqaleloukuba ubuninzi bale datha, kuya kufuneka ucinge ngokufuduka kwebhetshi!
  3. bhala ikhowudi apho zisetyenziswe khona ZOMBINI и entshakwaye indala ikholam. Ngoku inguqulelo yeapp yakho 2.0.0
  4. funda ixabiso kuluhlu surname, ukuba akunjalo null, okanye ukusuka ku-last_name, ukuba surname ayichazwanga ngqo. Ungacima getLastName() ukusuka kwikhowudi, kuba iya kukhupha null xa ubuyisela umva isicelo sakho 3.0.0 до 2.0.0.

Ukuba usebenzisa iSpring Boot Flyway, la manyathelo mabini aya kwenziwa ngexesha loqalo loguqulelo 2.0.0 izicelo. Ukuba usebenzisa isixhobo soguqulelo lwedatha ngesandla, kuya kufuneka wenze izinto ezimbini ezahlukeneyo ukwenza oku (kuqala uhlaziye uguqulelo lwe-db ngesandla kwaye usebenzise isicelo esitsha).

Kubalulekile. Khumbula ukuba ikholamu entsha eyenziwe UNGA ukuba AKUKHO NULL. Ukuba wenza ukubuyisela umva, isicelo esidala asazi malunga nekholamu entsha kwaye asiyi kuyifaka ngexesha Insert. Kodwa ukuba wongeza esi sithintelo kwaye idb yakho iya kuba v2, oku kuyakufuna ukuseta ixabiso lomhlathi omtsha. Okuya kubangela ukuphulwa kwezithintelo.

Kubalulekile. Kufuneka ususe indlela getLastName(), kuba kwinguqulelo 3.0.0 Akukho ngcamango yekholamu kwikhowudi last_name. Oku kuthetha ukuba i-null iya kusekwa apho. Ungayishiya indlela kwaye wongeze iitshekhi ze null, kodwa isisombululo esingcono kakhulu siya kuba kukuqinisekisa ukuba kwingqiqo getSurname() ukhethe ixabiso elichanekileyo elingengo-zero.

Uvavanyo lwe-A/B

Imeko yangoku kukuba sinenguqulelo yesicelo 1.0.0, isetyenziswe kwimveliso, kunye nedathabheyisi kwi v1. Kufuneka sisebenzise umzekelo wesibini wosetyenziso lwenguqulelo 2.0.0eya kuhlaziya isiseko sedatha v2.

Amanyathelo:

  1. Umzekelo omtsha wesicelo soguqulelo ubekiwe 2.0.0ehlaziya isiseko sedatha kuyo v2
  2. Ngeli xesha ezinye izicelo zaqwalaselwa ngokwemizekelo yenguqulelo 1.0.0
  3. uhlaziyo lube yimpumelelo kwaye unemizekelo emininzi esebenzayo yesicelo soguqulelo 1.0.0 kunye nezinye iinguqulelo 2.0.0. Wonke umntu unxibelelana nedatabase kwi v2
  4. версия 1.0.0 ayisebenzisi ikholamu yefani kwisiseko sedatha, kodwa uguqulelo 2.0.0 usebenzisa. Abaphazamisani omnye nomnye, kwaye akufanele kubekho iimpazamo.
  5. версия 2.0.0 igcina idata kuluhlu oludala kunye nolutsha, iqinisekisa ukuhambelana komva

Kubalulekile. Ukuba unayo nayiphi na imibuzo ebala izinto ezisekwe kumaxabiso ukusuka kumhlathi omdala/omtsha, kuya kufuneka ukhumbule ukuba ngoku unamaxabiso aphindwayo (kunokwenzeka ukuba basafuduka). Umzekelo, ukuba ufuna ukubala inani labasebenzisi abanegama lokugqibela (nokuba ikholamu ebizwa ngokuba yintoni na) iqale ngonobumba A, ngoko de ukuhanjiswa kwedatha kugqitywe (oldnew column) unokuba nedatha engangqinelaniyo ukuba ubuza umhlathi omtsha.

Ukubuyisela umva isicelo

Ngoku sinenguqulelo ye-app 2.0.0 kunye ne-database kwi v2.

Amanyathelo:

  1. buyisela isicelo sakho kuguqulelo 1.0.0.
  2. версия 1.0.0 ayisebenzisi ikholamu kwisiseko sedatha surname, ngoko ke ukubuyisela umva kufuneka kuphumelele

DB utshintsho

Uluhlu lwedatha luqulethe ikholamu enegama last_name.

Umbhalo womthombo weFlyway:

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

Yongeza iskripthi surname.

Ingqalelo. Khumbula ukuba AWUKONZE nayiphi na imiqobo ENGAYI NULL kwikholamu owongezayo. Ukuba ubuyisela umva i-JAR, uguqulelo oludala aluyi kuba nombono malunga nekholamu eyongeziweyo kwaye iya kuyibeka ngokuzenzekelayo ku-NULL. Ukuba kukho umda onjalo, isicelo esidala siyakuphuka nje.

-- 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

Iikhowudi ziyatshintsha

Sigcina idatha njenge last_name, nangaphakathi surname. Kwangaxeshanye sifunda ukusuka last_name, ekubeni le kholamu yeyona ifanelekileyo. Ngexesha lenkqubo yokusasazwa, ezinye izicelo zinokuthi ziqwalaselwe ngokwemeko yesicelo engekahlaziywa.

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

Inyathelo lesi-3: Ukususa igama_lokugqibela kwikhowudi

Inguqulelo yeapp: 3.0.0

Inguqulelo yeDB:v3

Inkcazo

Phawula Ngalinye: Kuyabonakala ukuba, kwinqaku lokuqala umbhali ukopishe ngempazamo umbhalo wale block ukusuka kwinqanaba 2. Kweli nyathelo, utshintsho kufuneka lwenziwe kwikhowudi yesicelo ejolise ekususeni umsebenzi osebenzisa ikholamu. last_name.

Ngokongeza ikholamu entsha kunye nokukopa imixholo yayo, senze utshintsho oluhambelanayo lwedatha. Kwakhona, ukuba sibuyisela umva i-JAR okanye sine-JAR endala esebenzayo, ayizukwaphuka ngexesha lokubulawa.

Ukubuyisela umva isicelo

Okwangoku sinenguqulelo ye-app 3.0.0 kunye nedathabheyisi v3. Inguqulelo 3.0.0 ayigcini idatha kuyo last_name. Oku kuthetha ukuba kwi surname olona lwazi lusexesheni luyagcinwa.

Amanyathelo:

  1. buyisela isicelo sakho kuguqulelo 2.0.0.
  2. версия 2.0.0 sebenzisa kunye last_name и surname.
  3. версия 2.0.0 iya kuthatha surname, ukuba ayingoziro, kungenjalo -last_name

Utshintsho lwesiseko sedatha

Akukho lutshintsho lwesakhiwo kwisiseko sedatha. Le script ilandelayo yenziwe ukwenza ufuduko lokugqibela lwedatha 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;

Iikhowudi ziyatshintsha

Phawula nganye last_name.

Sigcina idatha njenge last_name, nangaphakathi surname. Ukongeza, sifunda kwikholamu last_name, ekubeni yeyona ifanelekileyo. Ngexesha lenkqubo yokusasazwa, ezinye izicelo zinokusetyenzwa ngomzekelo ongekaphuculwa.

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

Inyathelo lesi-4: Ukususa i-last_name kwiziko ledatha

Inguqulelo yeapp: 4.0.0

Inguqulelo yeDB: v4

Inkcazo

Ngenxa yokuba ikhowudi yoguqulelo 3.0.0 khange isebenzise ikholamu last_name, akukho nto imbi iya kwenzeka ngexesha lokubulawa ukuba sibuyela emva 3.0.0 emva kokususa ikholamu kwisiseko sedatha.

Iilogi zokwenziwa kweSikripthi

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"}

DB utshintsho

Ngokukodwa v3 sisusa nje ikholamu last_name kwaye wongeze izithintelo ezingekhoyo.

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

Iikhowudi ziyatshintsha

Akukho lutshintsho kwikhowudi.

isiphelo

Sisebenzise ngempumelelo umva-ongahambelaniyo notshintsho lwegama lekholamu ngokwenza izinto ezininzi ezibuyela ngasemva ezihambelanayo. Ngezantsi sisishwankathelo sezenzo ezenziweyo:

  1. ukusasazwa koguqulelo lwesicelo 1.0.0 с v1 I-schema yesiseko sedatha (igama lekholamu = last_name)
  2. ukusasazwa koguqulelo lwesicelo 2.0.0, egcina idatha kuyo last_name и surname. Isicelo sifundeka kwi last_name. Uvimba weenkcukacha ukwinguqulelo v2equlathe imiqolo efana last_name, kwaye surname. surname yikopi ye-last_name. (QAPHELA: lo mhlathi mawungabinasithintelo esingenamsebenzi)
  3. ukusasazwa koguqulelo lwesicelo 3.0.0, egcina kuphela idatha kuyo surname kwaye ufunda kwifani. Ngokubhekiselele kwisiseko sedatha, ukufuduka kokugqibela kuyenzeka last_name в surname. Kwakhona umda AKUKHO NULL isusiwe kwi last_name. Isiseko sedatha ngoku sikwinguqulelo v3
  4. ukusasazwa koguqulelo lwesicelo 4.0.0 - akukho lutshintsho lwenziwayo kwikhowudi. Ukusasazwa kweDatabase v4, esusa last_name. Apha unokongeza nayiphi na imiqobo elahlekileyo kwisiseko sedatha.

Ngokulandela le ndlela, unokuhlala ubuyisela umva inguqulelo enye ngaphandle kokwaphula isiseko sedatha / ukuhambelana kwesicelo.

Ikhowudi

Yonke ikhowudi esetyenziswe kweli nqaku ifumaneka kwi Github. Ngezantsi inkcazo eyongezelelweyo.

Iiprojekthi

Emva kokudibanisa indawo yokugcina, uya kubona ulwakhiwo lwefolda elandelayo.

├── 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)

Izikripthi

Ungaqhuba izikripthi ezichazwe kwizikripthi ezingezantsi, eziza kubonisa utshintsho olubuyela umva oluhambelanayo kunye nolungahambisaniyo kwisiseko sedatha.

Ukubona imeko kunye neenguqu ezihambelana nomva, baleka:

./scripts/scenario_backward_compatible.sh

Kwaye ukubona icala elinotshintsho olungahambelaniyo ngasemva, baleka:

./scripts/scenario_backward_incompatible.sh

I-Flyway yeSampuli ye-Boot yaseNtwasahlobo

Yonke imizekelo ithathwe kuyo Spring Boot Sample Flyway.

Ungajonga kwi http://localhost:8080/flyway, kukho uluhlu lwezikripti.

Lo mzekelo uquka i-console ye-H2 (at http://localhost:8080/h2-console) ukuze ukwazi ukujonga ubume bedatabase (ehlala ikho i-jdbc URL jdbc:h2:mem:testdb).

Ephakamileyo

Funda namanye amanqaku kwibhlog yethu:

umthombo: www.habr.com

Yongeza izimvo