
Selles artiklis selgitatakse üksikasjalikult, kuidas lahendada andmebaasi ühilduvuse probleeme juurutamise ajal. Räägime sellest, mis võib juhtuda teie toodetud rakendustega, kui proovite juurutamist teha ilma eelneva ettevalmistuseta. Seejärel käime läbi rakenduse elutsükli etapid, mis on vajalikud, et saavutada null seisaku aeg (märkus: edaspidi - zero downtime). Meie tegevuse tulemusena rakendatakse tagurpidi ühilduvaid andmebaasi muudatusi ühilduval viisil.
Kui soovite artiklist koodinäidete üle vaadata, leiate need aadressilt .
Sissejuhatus
Zero downtime deployment
Mis on see müstiline zero downtime deployment? Можно сказать, это когда ваше приложение развернуто так, что вы можете успешно вводить новую версию приложения на продакшн, в то время как пользователь не замечает его недоступности. С точки зрения пользователя и компании, это наилучший из возможных сценариев деплоя, поскольку таким образом можно вводить новые функции и устранять ошибки без перебоев в работе.
Kuidas seda saavutada? On mitu viisi, siin on üks:
- juuruta versioon nr 1 oma teenusest
- teosta andmebaasi migratsioon
- juuruta versioon nr 2 oma teenusest paralleelselt versiooniga nr 1
- kui näete, et versioon nr 2 töötab nagu peab, eemaldage versioon nr 1
- valmis!
Lihtne, eks? Kahjuks ei ole see nii lihtne ja me käsitleme seda hiljem üksikasjalikult. Aga praegu kontrollime veel ühte üsna levinud juurutamisprotsessi - blue green deployment.
Kas olete kunagi kuulnud ? С Cloud Foundry это чрезвычайно легко сделать. Просто гляньте на , kus me kirjeldame seda põhjalikumalt. Lühidalt kokkuvõttes tuletame meelde, kuidas teha blue green deployment:
- tagada, et teie tootmisvõi koodil oleks kaks koopiat ("blue" ja "green");
- suunata kogu liiklus blue keskkonda, st et tootmis URL-id suunaksid sinna;
- juurutada ja testida kõik rakenduse muudatused green keskkonnas;
- vahetada URL-id blue keskkonnast green keskkonda
Blue green deployment on lähenemine, mis võimaldab teil hõlpsasti uusi funktsioone sisse tuua, muretsedes, et tootmine katki läheb. See tuleneb asjaolust, et isegi kui midagi juhtub, saate hõlpsasti naasta eelmisse keskkonda, lihtsalt "lülitades".
Kõike ülalpool loetletut lugedes võite küsida: Milline seos on zero downtime'il blue green juurutamisega?
Noh, neil on üsna palju ühist, kuna kahe sama keskkonna koopia toetamine nõuab nende hooldamiseks topeltpingutust. Just seetõttu, nagu väidab , järgivad mõned meeskonnad selle lähenemise variatsiooni:
teise variandi kasutamine seisneb sama andmebaasi kasutamises, luues sinise ja rohelise lülitid veebi ja domeeni kihtide jaoks. Sellise lähenemise korral võivad andmebaasid sageli probleemiks osutuda, eriti kui peate muutma selle skeemi, et toetada uut tarkvaraversiooni.
Ja siin jõuame selle artikli peamise probleemini. Andmebaas. Vaatame seda lauset veel kord.
tehke andmebaasi migratsioon.
Nüüd peaksite endalt küsima — mis siis, kui andmebaasi muutmine ei ole tagasi ühilduv? Kas minu esimene rakenduse versioon ei purune? Tegelikult just see juhtubki...
Nii et isegi vaatamata zero downtime / sinise ja rohelise juurutamise tohututele eelistele kalduvad ettevõtted järgima järgmisi turvalisemaid rakenduste juurutamisprotsesse:
- valmistage ette uus rakenduse versioon
- lülitage välja töötav rakendus
- käivitage andmebaasi migratsiooni skriptid
- juurutage ja käivitage uus rakenduse versioon
Selles artiklis kirjeldame üksikasjalikult, kuidas saate andmebaasi ja koodi töötlemise etapid nullvaheaja juurutamise eeliste nautimiseks.
Andmebaasi probleemid
Kui teil on staateless rakendus, mis ei salvesta andmeid andmebaasi, võite saavutada zero downtime juurutamise kohe. Kahjuks peab enamik tarkvarast andmeid kuskil salvestama. Just seetõttu peate enne skeemi muutmist kaks korda mõtlema. Enne kui süveneme detailidesse, kuidas skeemi muuta, et saada võimalus juurutamiseks ilma seisakuta, keskendume kõigepealt versioonihalduse skeemile.
Versioonihalduse skeem
Selles artiklis kasutame versioonihaldusvahendina (märkus tõlkijalt: räägime andmebaasi migratsioonidest). Loomulikult kirjutame ka Spring Boot rakenduse, millel on sisseehitatud Flyway tugi ja mis teostab skeemi migratsiooni rakenduse konteksti seadistamise ajal. Flyway kasutamisel saate salvestada migratsiooniskeemid oma projektikaustades (vaikesätete kohaselt classpath:db/migration). Siin näete selliste migratsioonifailide näidet
└── db
└── migration
├── V1__init.sql
├── V2__Add_surname.sql
├── V3__Final_migration.sql
└── V4__Remove_lastname.sqlSelles näites näeme 4 migratsioonistsenaariumi, mis, kui neid varem ei teostatud, viiakse järjestikku ellu rakenduse käivitamisel. Vaatame ühte faili (V1__init.sql) näitena.
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');Kõik on selge: saate kasutada SQL-i, et määrata, kuidas teie andmebaasi tuleks muuta. Lisainformatsiooni saamiseks Spring Booti ja Flyway kohta tutvuge .
Kasutades versioonihaldustööriista koos Spring Bootiga, saate kaks suurt eelist:
- eristate andmebaasi muudatused koodimuudatustest
- andmebaasi migratsioon toimub koos teie rakenduse käivitamisega, st teie juurutamisprotsess lihtsustub
Andmebaasi probleemide lahendamine
Artikli järgmises osas keskendume kahe lähenemise uurimisele andmebaasi muudatustele.
- tagasiviidavus
- tagasiühilduvus
Esimene käsitletakse hoiatuseks, et mitte teha nullseisaku juurutamist ettevalmistuseta... Teine pakub lahendust, kuidas juurutamist teha ja samal ajal tagada tagasiühilduvus.
Meie projekt, millega me tegelema hakkame, on lihtne Spring Boot Flyway rakendus, kus on ei pane tähele, need kuuluvad domeeni ja ei ole testi raames käsitletud. Seega, sellise graafilise struktuuri puhul näeks otsinguahelate päring välja nagu: jot first_name ja last_name andmebaasis (märk: ei pane tähele, need kuuluvad domeeni ja ei ole testi raames käsitletud. Seega, sellise graafilise struktuuri puhul näeks otsinguahelate päring välja nagu: on tabel ja first_name ja last_name — need on väljad;). Soovime ümber nimetada last_name ja perekonnanimi.
Eeldused
Enne kui süveneme üksikasjadesse, on oluline märkida paar eeldust meie rakenduste kohta. Peamine tulemus, mida soovime saavutada, on üsna lihtne protsess.
Märkus. Business PRO-TIP. Protsesside lihtsustamine võib teile palju raha säästa (mida rohkem inimesi teie ettevõttes töötab, seda rohkem saate säästa)!
Andmebaasi tagasivõtmine ei ole vajalik
See lihtsustab juurutamisprotsessi (mõned andmebaasi tagasivõtmised on praktiliselt võimatud, näiteks kustutamise tagasivõtmine). Eelistame tagasi võtta ainult rakendusi. Nii et isegi kui teil on erinevad andmebaasid (näiteks SQL ja NoSQL), näeb teie juurutamise toru välja sama.
Rakenduse tagasivõtmine peaks alati olema võimalus tagasiviimiseks ühe versiooni võrra (mitte rohkem)
Tagasi pööramine tuleks teha ainult vajaduse korral. Kui praeguses versioonis on viga, mida on keeruline eemaldada, peaksime suutma naasta viimase töökorras versiooni juurde. Eeldame, et see viimane töökorras versioon on eelnev. Toetamine mitme versiooni koodi ja andmebaasi ühilduvusele oleks äärmiselt keeruline ja kulukas.
Note. Suurema loetavuse nimel muudame käesolevas artiklis rakenduse peaversiooni.
Samm 1: Algne seisund
Rakenduse versioon: 1.0.0
Andmebaasi versioon: v1
Kommentaar
See on rakenduse algne seisund.
Andmebaasi muudatused
Andmebaas sisaldab last_name.
LOO TABEL PERSON (
id BIGINT LOODUD ALATI KUI IDENTITY,
first_name varchar(255) mitte null,
last_name varchar(255) mitte null
);
sisesta PERSON (first_name, last_name) väärtused ('Dave', 'Syer');Koodimuudatused
Rakendus salvestab Person andmeid 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
+ "]";
}
}Tagasi ühilduvuste muutmine veeru nimi
Vaadakem näidet, kuidas muuta veeru nime:
Tähelepanu. Järgmine näide toob meelega kaasa rikke. Näitame seda, et demonstreerida andmebaasi ühilduvuse probleemi.
Rakenduse versioon: 2.0.0.BAD
Andmebaasi versioon: v2bad
Kommentaar
Praegused muudatused EI LUBA meil käivitada kahte eksemplari (vana ja uus) korraga. Seega on null-kuna seadistamine raske saavutada (kui arvestada eeldusi, on see tegelikult võimatu).
A/B testimine
Praegune olukord on see, et meil on rakendus versioon 1.0.0, , mis on produtseeritud, ja andmebaas v1. Me peame rakendama teise eksemplari rakendust, versioon 2.0.0.BAD, ja värskendama andmebaasi versioonini v2bad.
Sammud:
- on ette nähtud uus eksemplar rakenduse versioonist
2.0.0.BAD, mis värskendab andmebaasi versiooniniv2bad - andmebaasis
v2badveerglast_nameei eksisteeri enam — see on muudetud nimeksperekonnanimi - andmebaasi ja rakenduse uuendamine õnnestus ning mõned eksemplarid töötavad
1.0.0, teised —2.0.0.BAD. Kõik on seotud andmebaasigav2bad - kõik eksemplarid versioon
1.0.0algavad vigade andmine, kuna nad proovivad sisestada andmeid veergulast_name, mida enam ei ole - kõik eksemplarid versioon
2.0.0.BADtöötavad probleemideta
Nagu näete, kui teeme tagasi ühilduvaid muudatusi andmebaasis ja rakenduses, on A/B testimine võimatu.
Rakenduse tagasipööramine
Oletame, et pärast A/B seadistuskatse tegemist (tõlke märk: autoril võib-olla oli mõte A/B testimine) otsustasime, et peame rakenduse tagasi pöörama versioonile 1.0.0. Oletame, et me ei soovi andmebaasi tagasi pöörata.
Sammud:
- me peatame rakenduse versiooni
2.0.0.BAD - andmebaas on endiselt
v2bad - kuna versioon
1.0.0ei mõista, mis onperekonnanimi, näeme vigu - põrgu on vabanenud, me ei saa enam tagasi minna
Nagu näete, kui teeme andmebaasi ja rakenduse vahel tagasi ühilduvaid muudatusi, ei saa me tagasi minna eelmisele versioonile.
Skripti täitmise logid
Tagasi ühilduv stsenaarium:
01) Käivita 1.0.0
02) Oota, kuni rakendus (1.0.0) käivitub
03) Loo inimene, kutsudes POST localhost:9991/person versioonile 1.0.0
04) Käivita 2.0.0.BAD
05) Oota, kuni rakendus (2.0.0.BAD) käivitub
06) Loo inimene, kutsudes POST localhost:9991/person versioonile 1.0.0 <-- see peaks ebaõnnestuma
07) Loo inimene, kutsudes POST localhost:9992/person versioonile 2.0.0.BAD <-- see peaks edenduma
Käivitame rakenduse versioonis 1.0.0
Loodame inimesi versioonis 1.0.0
Postitus 127.0.0.1:9991/person. See on vastus:
{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}
Käivitame rakenduse versioonis 2.0.0.BAD
Loodame inimesi versioonis 1.0.0
Postitus 127.0.0.1:9991/person. See on vastus:
curl: (22) Taotletud URL tagastas vea: 500 Sisemine serveri viga
Loodame inimesi versioonis 2.0.0.BAD
Postitus 127.0.0.1:9995/person. See on vastus:
{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}Andmebaasi muudatused
Migratsiooniskript, mis ümber nimetab last_name ja perekonnanimi
Algne Flyway skript:
LOO TABEL PERSON (
id BIGINT LOODUD ALATI KUI IDENTITY,
first_name varchar(255) mitte null,
last_name varchar(255) mitte null
);
sisesta PERSON (first_name, last_name) väärtused ('Dave', 'Syer');Skript, mis ümber nimetab last_name.
-- See muudatus on tagasi ühilduv - A/B testimist ei saa läbi viia
ALTER TABLE PERSON MUUDA last_name surname VARCHAR;Koodimuudatused
Muutisime välja nime lastName . Tundub, et perekonnanimi.
Veeru ümbernimetamine tagasi ühilduval viisil
See on kõige tavalisem olukord, millega me silmitsi seisame. Peame tegema tagasi ühilduvaid muudatusi. Oleme juba tõestanud, et katkestusteta juurutamiseks ei tohi me lihtsalt andmebaasi migratsiooni rakendada ilma lisategevusteta. Selle artikli jaotises teostame 3 rakenduse juurutust koos andmebaasi migratsioonidega, et saavutada soovitud tulemus ja samal ajal säilitada tagasipöördumise ühilduvus.
Märkus. Meenutame, et meil on andmebaas versiooniga
v1. See sisaldab veergefirst_namejalast_name. Peame muutmalast_name. Tundub, etperekonnanimi. Meil on ka rakendus versiooniga1.0.0,, mis ei kasuta veelperekonnanimi.
Samm 2: Lisame surname
Rakenduse versioon: 2.0.0
Andmebaasi versioon: v2
Kommentaar
Uue veeru lisamise ja selle sisu kopeerimisega loome tagasi ühilduvad andmebaasi muudatused. Samal ajal, kui me tagasi JAR-i pöörame või meil on töötav vana JAR, ei riku see täitmist.
Käivitame uue versiooni
Sammud:
- tehke andmebaasi migratsioon, et luua uus veerg
perekonnanimi. Nüüd on teie andmebaas versioonigav2 - kopeerige andmed
last_namejaperekonnanimi. Pange tähele, mis, kui teil on palju neid andmeid, peate arvestama paketihalduse migratsiooniga! - kirjutage kood, kus kasutatakse KUMMADKI ja uus, ja vana veerg. Nüüd on teie rakenduse versioon
2.0.0 - lugeda veerus olevat väärtust
perekonnanimi, kui see ei olenull, või last_name, kuiperekonnanimipole määratud. Võite eemaldadagetLastName()koodist, kuna see annabnullrakenduse versiooni tagasipööramisel3.0.0kuni2.0.0.
Kui kasutate Spring Boot Flyway't, siis need kaks sammu tehakse rakenduse versiooni käivitamisel. 2.0.0 Kui käitate andmebaasi versioonide haldusvahendit käsitsi, peate selle jaoks tegema kaks erinevat toimingut (esiteks uuendage DB versioon käsitsi ja seejärel juurutage uus rakendus).
Oluline. Pidage meeles, et uus veerg EI TOHI olla NOT NULL. Kui teete tagasi pöördumise, ei tea vana rakendus uuest veerust ja ei määra seda ajal
Insert.Aga kui lisate selle piirangu ja teie DB onv2, siis vajate uue veeru väärtuse seadistamiseks. See põhjustab piirangu rikkumist.Oluline. Peaksite eemaldama meetodi
getLastName(), kuna versioonis3.0.0koodis ei ole veeru mõistetlast_name. See tähendab, et sinna seatakse null. Saate meetodi jätta ja lisada kontrollidnull, kuid palju parem lahendus oleks veenduda, et teie loogikasgetSurname()valisite õige mitte-null väärtuse.
A/B testimine
Praegune olukord on see, et meil on rakendus versioon 1.0.0, mis on juurutatud tootmises, ja DB on v1. Peame juurutama teise rakenduse versiooni 2.0.0, mis uuendab andmebaasi kuni v2.
Sammud:
- on ette nähtud uus eksemplar rakenduse versioonist
2.0.0, mis värskendab andmebaasi versiooniniv2 - samal ajal, kui mõned päringud töötlesid versiooni eksemplare
1.0.0 - uuendamine õnnestus ja teil on mitu töötavat versiooni eksemplari
1.0.0ja teised versioonid2.0.0.Kõik suhtlevad DB-gav2 - ICQ.com veebilehest dateeritud 1997. aasta aprilli, ja siis kuulus domeen hoopis teisele organisatsioonile — mingi mõõteseadmete tootjate ja kasutajate ühingule. Aasta
1.0.0ei kasuta andmebaasis veergu surname, kuid versioon2.0.0kasutab. Nad ei sega üksteist ja vigu ei tohiks olla. - ICQ.com veebilehest dateeritud 1997. aasta aprilli, ja siis kuulus domeen hoopis teisele organisatsioonile — mingi mõõteseadmete tootjate ja kasutajate ühingule. Aasta
2.0.0salvestab andmed nii vanas kui ka uues veerus, mis tagab ühilduvuse
Oluline. Kui teil on mingeid päringuid, mis loendavad elemente vanade / uute veergude väärtuste põhjal, peate meeles pidama, et nüüd on teil väärtuste dubleerimine (tõenäoliselt nad kõik veel migreeruvad). Näiteks kui soovite lugeda kasutajate arvu, kelle perekonnanimi (olgu see veeru nimi kuidas tahes) algas tähega
A, siis andmete migreerimise lõpuni (old→uusveerg) võivad teil olla mittekooskõlalised andmed, kui teete päringu uuele veerule.
Rakenduse tagasipööramine
Praegu on meil rakenduse versioon 2.0.0 ja andmebaas on v2.
Sammud:
- tagasi pöörake oma rakendus versiooni
1.0.0. - ICQ.com veebilehest dateeritud 1997. aasta aprilli, ja siis kuulus domeen hoopis teisele organisatsioonile — mingi mõõteseadmete tootjate ja kasutajate ühingule. Aasta
1.0.0ei kasuta andmebaasis veerguperekonnanimi, seega peab tagasivõtt olema edukas
Andmebaasi muudatused
DB sisaldab veergu nimega last_name.
Algne Flyway skript:
LOO TABEL PERSON (
id BIGINT LOODUD ALATI KUI IDENTITY,
first_name varchar(255) mitte null,
last_name varchar(255) mitte null
);
sisesta PERSON (first_name, last_name) väärtused ('Dave', 'Syer');Lisamise skript perekonnanimi.
Tähelepanu. Pidage meeles, et ei TOHI LISADA mingeid NOT NULL piiranguid lisatavasse veergu. Kui teie JAR-i tagasi võtate, ei tea vana versioon uue veeru olemasolust ja seab selle automaatselt NULL-iks. Sellise piirangu korral puruneb vana rakendus lihtsalt.
-- MÄRKUS: See väli ei saa olla NOT NULL piirang, kuna kui te tagasi võtate, ei tea vana versioon selle välja kohta
-- ja seab selle alati NULL-iks
ALTER TABLE PERSON ADD surname varchar(255);
-- EELDAME, ET SEE ON KIIRE MIGRATSIOON - MUU SELLES TÕSTAMISEKS PEAME MIGREERIMA PARTIIDES
UPDATE PERSON SET PERSON.surname = PERSON.last_nameKoodimuudatused
Salvestame andmed nii last_name, kui ka perekonnanimi. Samal ajal loeme last_name, kuna see veerg on kõige asjakohasem. Deployimise käigus võis mõningaid päringuid töödelda rakendusäkkide, mis pole veel uuendatud.
/*
* 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
+ "]";
}
}Samm 3: last_name eemaldamine koodist
Rakenduse versioon: 3.0.0
Andmebaasi versioon:v3
Kommentaar
Märk. tõlk.: Tundub, et algses artiklis on autor ekslikult kopeerinud selle ploki sisu sammust 2. Antud sammu käigus tuleb teha koodis muudatusi, et eemaldada funktsionaalsus, mis kasutab veergu last_name.
Uue veeru lisamise ja selle sisu kopeerimisega oleme loonud tagurpidi ühilduvad andmebaasi muudatused. Samuti, kui me tagastame JAR-i või kui meil on töötav vana JAR, ei purune see täitmise käigus.
Rakenduse tagasipööramine
Praegu on meil rakenduse versioon 3.0.0 ja andmebaas v3. Versioon 3.0.0 ei salvesta andmeid last_name. See tähendab, et perekonnanimi hoiab kõige ajakohasemat teavet.
Sammud:
- tagasi pöörake oma rakendus versiooni
2.0.0. - ICQ.com veebilehest dateeritud 1997. aasta aprilli, ja siis kuulus domeen hoopis teisele organisatsioonile — mingi mõõteseadmete tootjate ja kasutajate ühingule. Aasta
2.0.0kasutab jalast_namejaperekonnanimi. - ICQ.com veebilehest dateeritud 1997. aasta aprilli, ja siis kuulus domeen hoopis teisele organisatsioonile — mingi mõõteseadmete tootjate ja kasutajate ühingule. Aasta
2.0.0võtabperekonnanimi, kui see ei ole null, vastasel juhul —last_name
Andmebaasi muudatused
Andmebaasis ei ole struktuuri muudatusi. Käivitatakse järgmine skript, mis viib lõpule vanade andmete migratsiooni:
-- EELDAME, ET SEE ON KIIRE MIGRATSIOON - MUU SELLES TÕSTAMISEKS PEAME MIGREERIMA PARTIIDES
-- KA ME EI KONTROLLI, KAS ME EI ÜLEVIIE OLEVAT SISUST. ME PEAME VÕRRENDAMA
-- SISU VERSIOONE, ET KINNITADA, ET KUI ON JUBA SISU, MILLEL ON KÕRGEM VERSIOONINUMBER
-- ME EI KATKESTAMA SEDA.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;
-- EEMALDAMINE NOT NULL PIIRANG, MU otherwise PROOVITE SISSE LÜÜA NULL VÄÄRTUS LAST_NAME
-- NOT_NULL PIIRANGUGA.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;Koodimuudatused
Märk. tõlk.: Selle ploki kirjeldus on samuti vale, kopeeritud autori poolt sammust 2. Artikli narratiivi loogika kohaselt peaks selle sammu koodimuudatused olema suunatud eemaldades elemente, mis tegelevad veeruga last_name.
Salvestame andmed nii last_name, kui ka surname. Lisaks loeme veerust last_name, kuna see on kõige asjakohasem. Paigaldamise ajal võivad mõned päringud olla töödeldud eksemplari poolt, mis ei ole veel uuendatud.
/*
* 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
+ "]";
}
}Samm 4: last_name eemaldamine andmebaasist
Rakenduse versioon: 4.0.0
Andmebaasi versioon: v4
Kommentaar
Kuna versiooni kood 3.0.0 ei kasutanud veergu last_name, siis täitmise ajal ei juhtu midagi halba, kui tagasi pöördume 3.0.0 pärast veeru eemaldamist andmebaasist.
Skripti täitmise logid
Teeme seda järgmiselt:
01) Käivita 1.0.0
02) Oota, kuni rakendus (1.0.0) käivitub
03) Genereeri isik, helistades POST localhost:9991/person versioonile 1.0.0
04) Käivita 2.0.0
05) Oota, kuni rakendus (2.0.0) käivitub
06) Genereeri isik, helistades POST localhost:9991/person versioonile 1.0.0
07) Genereeri isik, helistades POST localhost:9992/person versioonile 2.0.0
08) Lõpeta rakendus (1.0.0)
09) Käivita 3.0.0
10) Oota, kuni rakendus (3.0.0) käivitub
11) Genereeri isik, helistades POST localhost:9992/person versioonile 2.0.0
12) Genereeri isik, helistades POST localhost:9993/person versioonile 3.0.0
13) Lõpeta rakendus (3.0.0)
14) Käivita 4.0.0
15) Oota, kuni rakendus (4.0.0) käivitub
16) Genereeri isik, helistades POST localhost:9993/person versioonile 3.0.0
17) Genereeri isik, helistades POST localhost:9994/person versioonile 4.0.0
Käivitamine rakenduses versioonis 1.0.0
Generatsiooni isik versioonis 1.0.0
Postitamine aadressile 127.0.0.1:9991/person. See on vastus:
{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}
Käivitamine rakenduses versioonis 2.0.0
Generatsiooni isik versioonis 1.0.0
Postitamine aadressile 127.0.0.1:9991/person. See on vastus:
{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}
Generatsiooni isik versioonis 2.0.0
Postitamine aadressile 127.0.0.1:9992/person. See on vastus:
{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}
Rakenduse 1.0.0 lõpetamine
Käivitamine rakenduses versioonis 3.0.0
Generatsiooni isik versioonis 2.0.0
Postitamine aadressile 127.0.0.1:9992/person. See on vastus:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}
Generatsiooni isik versioonis 3.0.0
Postitamine aadressile 127.0.0.1:9993/person. See on vastus:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}
Rakenduse 2.0.0 lõpetamine
Käivitamine rakenduses versioonis 4.0.0
Generatsiooni isik versioonis 3.0.0
Postitamine aadressile 127.0.0.1:9993/person. See on vastus:
{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}
Generatsiooni isik versioonis 4.0.0
Postitamine aadressile 127.0.0.1:9994/person. See on vastus:
{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}Andmebaasi muudatused
Seoses v3 eemaldame veeru last_name ja lisame puuduvad piirangud.
-- EEMALDA VEERG
ALTER TABLE PERSON DROP last_name;
-- LISAGE PIIRANGUD
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;Koodimuudatused
Koodimuudatusi pole.
Kokkuvõte
Oleme tagasi pöördunud ühilduvuse muutuse nime veeru, tehes mitu tagasi ühilduvat juurutust. Allpool on kokkuvõte tehtud toimingutest:
- rakenduse versiooni juurutamine
1.0.0jotv1andmebaasi skeem (veeru nimi =last_name) - rakenduse versiooni juurutamine
2.0.0,mis salvestab andmeidlast_namejaperekonnanimi. Rakendus loeblast_name. Andmebaas on versioonisv2, mille veerud on nagulast_name, kui kaperekonnanimi. perekonnanimion koopia last_name. (MÄRKUS: see veerg ei tohi omada not null piirangut) - rakenduse versiooni juurutamine
3.0.0, mis salvestab andmeid ainultperekonnanimija loeb perekonnanimest. Andmebaasi osas toimub viimane migratsioonlast_namejaperekonnanimi. Samuti tühistatakse piirang NOT NULL veeru pealtlast_name. Andmebaas on nüüd versioonisv3 - rakenduse versiooni juurutamine
4.0.0— koodis ei tehta mingeid muudatusi. Andmebaasi juurutaminev4, mis eemaldablast_name. Siia võite lisada kõik puuduvad piirangud andmebaasi.
Järgides seda lähenemist, saate alati tagasi ühe versiooni võrra tagasi pöörduda, häirimata andmebaasi / rakenduse ühilduvust.
Kood
Kogu selle artikli jooksul kasutatav kood on saadaval aadressil . Allpool on lisateave.
Projektid
Pärast repositooriumi kloonimist näete järgmist kataloogistruktuuri.
├── boot-flyway-v1 - rakenduse 1.0.0 versioon koos skeemi v1
├── boot-flyway-v2 - rakenduse 2.0.0 versioon koos skeemi v2 (tagasiühilduv - rakendust saab tagasi pöörata)
├── boot-flyway-v2-bad - rakenduse 2.0.0.BAD versioon koos skeemi v2bad (tagasiühilduvust rikkumine - rakendust ei saa tagasi pöörata)
├── boot-flyway-v3 - rakenduse 3.0.0 versioon koos skeemi v3 (rakendust saab tagasi pöörata)
└── boot-flyway-v4 - rakenduse 4.0.0 versioon koos skeemi v4 (rakendust saab tagasi pöörata)Skripti
Saate käivitada allpool kirjeldatud skripte, mis demonstreerivad tagasiühilduvaid ja ühilduvust rikkuvaid muudatusi andmebaasis.
Küsimiseks juhtum tagasiühilduvate muudatustega, käivitage:
.\/scripts\/scenario_backward_compatible.shJa et näha juhtum tagasiühipidamatute muudatustega, käivitage:
.\/scripts\/scenario_backward_incompatible.shSpring Boot Näidis Flyway
Kõik näited on võetud Spring Boot Näidis Flyway.
Võite vaadata http://localhost:8080/flyway, seal on skriptide loend.
See näide sisaldab ka H2 konsooli (aadressil http://localhost:8080/h2-console), et saaksite vaadata andmebaasi olekut (URL jdbc vaikimisi - jdbc:h2:mem:testdb).
Lisaks
Vaata ka teisi artikleid meie blogis:
Allikas: habr.com
