Zero Downtime Deployment da Databases

Zero Downtime Deployment da Databases

Wannan labarin yayi bayani dalla-dalla yadda ake warware batutuwan dacewa da bayanai a cikin turawa. Za mu gaya muku abin da zai iya faruwa ga aikace-aikacen samarwa idan kun yi ƙoƙarin turawa ba tare da shiri na farko ba. Za mu shiga cikin matakan rayuwa na aikace-aikacen da ake buƙata don samun raguwar sifili (kusan layi: kara - zero downtime). Sakamakon ayyukanmu zai kasance yin amfani da canjin bayanan bayanan baya-marasa jituwa ta hanyar da ta dace da baya.

Idan kuna son fahimtar misalan lambar daga labarin, zaku iya samun su a GitHub.

Gabatarwar

Zazzage lokacin ragewa

Abin da wani sufi sifili downtime turawa? Kuna iya cewa wannan shine lokacin da aka tura aikace-aikacenku ta hanyar da za ku iya samun nasarar gabatar da sabon sigar aikace-aikacen don samarwa, yayin da mai amfani bai lura da rashin samuwansa ba. Daga mai amfani da hangen nesa na kamfani, wannan shine mafi kyawun yanayin tura aikin saboda yana ba da damar gabatar da sabbin abubuwa da kuma gyara kwari ba tare da tsangwama ba.

Yadda za a cimma wannan? Akwai hanyoyi da yawa, ga ɗaya daga cikinsu:

  • tura sigar No. 1 na sabis ɗin ku
  • yi gudun hijirar bayanai
  • Sanya sigar #2 na sabis ɗin ku a layi daya da sigar #1
  • da zarar ka ga wannan sigar No. 2 tana aiki yadda ya kamata, sai ka cire sigar No. 1
  • shirye!

Sauƙi, ko ba haka ba? Abin baƙin ciki, ba haka ba ne mai sauƙi, kuma za mu duba wannan dalla-dalla daga baya. Yanzu bari mu duba wani tsari gama gari gama gari - blue green deployment.

Shin kun taɓa ji shuɗi koren turawa? Cloud Foundry yana yin wannan mai sauƙin gaske. Kallo kawai wannan labarin, inda muka kwatanta wannan dalla-dalla. Don taƙaitawa, bari mu tunatar da ku yadda ake yin jigilar shuɗi koren:

  • tabbatar da cewa kwafi biyu na lambar samarwa ku ("blue" da "kore") suna aiki;
  • kai tsaye duk zirga-zirga zuwa yanayin shuɗi, watau. don haka samar da URLs suna nunawa a can;
  • tura da gwada duk canje-canjen aikace-aikacen a cikin yanayin kore;
  • canza urls daga shuɗi zuwa yanayin kore

Aiwatar da kore kore wata hanya ce wacce ke ba ku damar gabatar da sabbin abubuwa cikin sauƙi ba tare da damuwa game da karyewar samarwa ba. Wannan ya faru ne saboda gaskiyar cewa ko da wani abu ya faru, zaka iya komawa baya cikin sauƙi ta hanyar "juya wani canji."

Bayan karanta duk abubuwan da ke sama, zaku iya yin tambayar: Menene alakar lokacin raguwar sifili da tura shuɗin kore?

To, suna da abubuwa da yawa iri ɗaya, tun da kiyaye kwafi biyu na mahalli ɗaya yana buƙatar ninka ƙoƙarin kiyaye su. Wannan shine dalilin da ya sa wasu ƙungiyoyi ke ikirarin Martin Fowler, bi bambancin wannan hanyar:

Wani zaɓi shine a yi amfani da ma'ajin bayanai iri ɗaya, ƙirƙirar maɓalli mai shuɗi-kore don gidan yanar gizo da yadudduka na yanki. Ta wannan hanyar, yawancin bayanai na iya zama matsala, musamman lokacin da kake buƙatar canza tsarinsa don tallafawa sabuwar software.

Kuma a nan mun zo ga babbar matsala a cikin wannan labarin. Database. Bari mu sake duba wannan jimlar.

yi gudun hijirar bayanai.

Yanzu dole ne ku tambayi kanku tambayar - menene idan canjin bayanan bayanai bai dace da baya ba? Shin sigar farko ta app ba za ta karye ba? A gaskiya, wannan shine ainihin abin da zai faru ...

Don haka, duk da fa'idodin da aka samu na jigilar lokaci / shuɗi mai shuɗi, kamfanoni suna bin tsari mafi aminci don tura aikace-aikacen su:

  • shirya kunshin tare da sabon sigar aikace-aikacen
  • kashe aikace-aikacen da ke gudana
  • gudanar da scripts don ƙaura da database
  • tura da ƙaddamar da sabon sigar aikace-aikacen

A cikin wannan labarin, za mu ba da cikakken bayani game da yadda za ku iya aiki tare da bayananku da lambar don cin gajiyar ƙaddamar da lokacin raguwar sifili.

Matsalolin Database

Idan kana da aikace-aikacen da ba ta da jiha wacce ba ta adana kowane bayanai a cikin ma'ajin bayanai, za ka iya samun raguwar lokaci ba tare da bata lokaci ba nan take. Abin takaici, yawancin software suna buƙatar adana bayanai a wani wuri. Wannan shine dalilin da ya sa ya kamata ka yi tunani sau biyu kafin yin kowane canje-canje ga da'ira. Kafin mu shiga cikin cikakkun bayanai na yadda ake canza tsarin ta yadda ba za a iya tura lokaci ba, bari mu fara mai da hankali kan tsarin sigar.

Tsarin siga

A cikin wannan labarin za mu yi amfani Flyway a matsayin kayan aikin sarrafa sigar (kusan Fassara: muna magana ne game da ƙaura na bayanai). A zahiri, za mu kuma rubuta aikace-aikacen Boot na bazara wanda ke da ginanniyar tallafin Flyway kuma zai yi ƙaura mai ƙima yayin kafa mahallin aikace-aikacen. Lokacin amfani da Flyway, zaku iya adana rubutun ƙaura a cikin babban fayil ɗin ayyukanku (ta tsohuwar ciki classpath:db/migration). Anan zaka iya ganin misalin irin waɗannan fayilolin ƙaura

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

A cikin wannan misalin mun ga rubutun ƙaura 4 waɗanda, idan ba a aiwatar da su a baya ba, za a aiwatar da su ɗaya bayan ɗaya lokacin da aikace-aikacen ya fara. Bari mu kalli ɗaya daga cikin fayilolin (V1__init.sql) a matsayin misali.

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

Komai yana da cikakken bayanin kansa: zaku iya amfani da SQL don ayyana yadda yakamata a canza bayananku. Don ƙarin bayani game da Spring Boot da Flyway, duba Dokokin Boot na bazara.

Ta amfani da kayan aikin sarrafa tushe tare da Spring Boot, kuna samun manyan fa'idodi guda 2:

  • ka raba bayanai canje-canje daga code canje-canje
  • Shigewar bayanai yana faruwa tare da fitar da aikace-aikacen ku, watau. An sauƙaƙe tsarin tura ku

Gyara matsalolin bayanai

A cikin sashe na gaba na labarin, za mu mai da hankali kan kallon hanyoyi biyu na canje-canjen bayanai.

  • rashin jituwa na baya
  • baya dacewa

Za a yi la'akari da na farko a matsayin gargaɗin cewa kada ku yi jigilar sifili ba tare da shiri na farko ba ... Na biyu yana ba da bayani game da yadda za ku iya yin aiki ba tare da raguwa ba kuma a lokaci guda ku kula da dacewa da baya.

Aikin mu da za mu yi aiki da shi zai zama aikace-aikacen Boot Flyway mai sauƙi wanda ke da Person с first_name и last_name a cikin database (kusan fassarar: Person tebur ne kuma first_name и last_name - Waɗannan su ne filayen da ke cikinsa). Muna so mu sake suna last_name в surname.

Zato

Kafin mu shiga cikakkun bayanai, akwai wasu zato da ya kamata mu yi game da aikace-aikacen mu. Babban sakamakon da muke son cimma zai zama tsari mai sauƙi mai sauƙi.

Bayanan kula. Kasuwancin PRO-TIP. Sauƙaƙe matakai na iya ceton ku kuɗi mai yawa akan tallafi (yawan mutanen da kuke aiki da kamfanin ku, ƙarin kuɗin da zaku iya ajiyewa)!

Babu buƙatar mayar da bayanan bayanai

Wannan yana sauƙaƙa tsarin turawa (wasu bayanan sake dawo da bayanai kusan ba su yiwuwa, kamar gogewa rollback). Mun gwammace mu mayar da aikace-aikace kawai. Ta wannan hanyar, ko da kuna da mabambantan bayanai (misali, SQL da NoSQL), bututun turawa zai yi kama da haka.

Dole ne koyaushe ya kasance yana yiwuwa a mayar da aikace-aikacen siga ɗaya baya (babu)

Juyawa ya kamata a yi kawai lokacin da ya cancanta. Idan akwai bug a cikin sigar yanzu wanda ba a gyara shi cikin sauƙi, ya kamata mu iya komawa zuwa sabon sigar aiki. Muna ɗauka cewa wannan sabuwar sigar aiki ita ce ta baya. Tsayar da lambobi da daidaituwar bayanai na fiye da ɗaya na iya zama da wahala da tsada.

Bayanin. Don ƙarin karatu, a cikin wannan labarin za mu canza babban sigar aikace-aikacen.

Mataki 1: Jiha ta farko

Sigar manhaja: 1.0.0
Sigar DB: v1

comment

Wannan zai zama yanayin farko na aikace-aikacen.

Database canje-canje

DB ya ƙunshi 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');

Code canje-canje

Aikace-aikacen yana adana bayanan Mutum a ciki 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
                + "]";
    }
}

Sake suna a baya baya jituwa

Bari mu kalli misalin yadda ake canza sunan shafi:

Hankali. Misali na gaba zai karya abubuwa da gangan. Muna nuna wannan don nuna matsalar daidaita bayanai.

Sigar manhaja: 2.0.0.BAD

Sigar DB: v2bad

comment

Canje-canje na yanzu ba sa ƙyale mu mu gudanar da lokuta biyu (tsohuwa da sababbi) a lokaci guda. Don haka, ƙaddamar da lokacin raguwar sifili zai yi wuya a cimma (idan an yi la'akari da zato, hakika ba zai yiwu ba).

Gwajin A/B

Halin da ake ciki yanzu shine muna da sigar aikace-aikacen 1.0.0, da aka tura a samarwa, da kuma database v1. Muna buƙatar tura misali na biyu na aikace-aikacen, sigar 2.0.0.BAD, kuma sabunta bayanan zuwa v2bad.

Matakai:

  1. an tura sabon misali na sigar aikace-aikacen 2.0.0.BADwanda ke sabunta bayanan zuwa v2bad
  2. a cikin bayanan v2bad shafi last_name babu kuma - an canza shi zuwa surname
  3. Bayanan bayanan da sabuntawa sun yi nasara kuma wasu lokuta suna gudana 1.0.0, wasu - in 2.0.0.BAD. An haɗa komai da bayanan bayanai v2bad
  4. duk lokuta na sigar 1.0.0 za su fara jefa kurakurai saboda za su yi ƙoƙarin saka bayanai a cikin ginshiƙi last_namewanda babu kuma
  5. duk lokuta na sigar 2.0.0.BAD zai yi aiki ba tare da matsala ba

Kamar yadda kuke gani, idan muka yi sauye-sauye marasa jituwa a baya ga bayanan bayanai da aikace-aikacen, gwajin A/B ba zai yiwu ba.

Maimaita aikace-aikacen

Bari mu ɗauka cewa bayan ƙoƙarin yin jigilar A / B (kusan per.: Wataƙila marubucin yana nufin gwajin A/B anan) mun yanke shawarar cewa muna buƙatar mayar da aikace-aikacen zuwa sigar 1.0.0. Bari mu ce ba ma son mu mayar da bayanan.

Matakai:

  1. mun dakatar da misalin aikace-aikacen sigar 2.0.0.BAD
  2. database yana nan v2bad
  3. tun daga sigar 1.0.0 bai gane menene ba surname, za mu ga kurakurai
  4. Jahannama ta lalace, ba za mu iya komawa ba kuma

Kamar yadda kuke gani, idan muka yi sauye-sauye marasa jituwa a baya ga ma'ajin bayanai da aikace-aikacen, ba za mu iya komawa zuwa sigar da ta gabata ba.

Rubutun kisa

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

Database canje-canje

Rubutun ƙaura da ke sake suna last_name в surname

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

Rubutun da ke sake suna last_name.

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

Code canje-canje

Mun canza sunan filin lastName a kan surname.

Sake suna ginshiƙi a hanyar da ta dace da baya

Wannan shi ne yanayin da ya fi kowa iya fuskanta. Muna buƙatar yin sauye-sauye marasa jituwa a baya. Mun riga mun tabbatar da cewa don ƙaddamar da lokacin faɗuwar rana, bai kamata mu yi amfani da ƙaura ba kawai ba tare da ƙarin matakai ba. A cikin wannan sashe na labarin, za mu yi jigilar aikace-aikacen guda 3 tare da ƙaurawar bayanai don cimma sakamakon da ake so yayin da muke ci gaba da dacewa da baya.

Bayanan kula. Ka tuna cewa muna da bayanan bayanai v1. Ya ƙunshi ginshiƙai first_name и last_name. Dole ne mu canza last_name a kan surname. Muna kuma da app version 1.0.0, wanda har yanzu ba a yi amfani da shi ba surname.

Mataki 2: Ƙara sunan mahaifi

Sigar manhaja: 2.0.0
Sigar DB: v2

comment

Ta ƙara sabon shafi da kwafin abubuwan da ke cikinsa, muna ƙirƙirar canje-canje masu dacewa da bayanai na baya. A lokaci guda, idan muka sake jujjuya JAR ko kuma tsohuwar JAR tana gudana, ba zai karye ba yayin aiwatarwa.

Muna fitar da sabon siga

Matakai:

  1. yi ƙaura na bayanai don ƙirƙirar sabon shafi surname. Yanzu sigar DB ɗin ku v2
  2. kwafin bayanai daga last_name в surname. Kulacewa idan kuna da yawancin waɗannan bayanan, yakamata kuyi la'akari da ƙaura!
  3. rubuta code inda ake amfani da su DUKA и новыйkuma tsohuwar shafi. Yanzu sigar app ɗin ku 2.0.0
  4. karanta darajar daga ginshiƙi surname, idan ba haka ba nullko daga last_nameidan surname ba a kayyade ba. Kuna iya sharewa getLastName() daga code, tunda zai fita null lokacin da ake juyar da aikace-aikacenku daga 3.0.0 to 2.0.0.

Idan kana amfani da Spring Boot Flyway, waɗannan matakai biyu za a yi su yayin farawa sigar 2.0.0 aikace-aikace. Idan kun gudanar da kayan aikin sigar bayanai da hannu, za ku yi abubuwa daban-daban don yin wannan (da farko sabunta sigar db da hannu sannan ku tura sabon aikace-aikacen).

Yana da muhimmanci. Ka tuna cewa sabon ginshiƙi da aka ƙirƙira BAI KAMATA BA ya zama BA NULL ba. Если вы делаете откат, старое приложение не знает о новом столбце и не установит его во время Insert. Amma idan kun ƙara wannan ƙuntatawa kuma db ɗinku zai kasance v2, wannan zai buƙaci saita ƙimar sabon shafi. Wanda zai haifar da keta hani.

Yana da muhimmanci. Ya kamata ku cire hanyar getLastName(), saboda a cikin sigar 3.0.0 Babu ra'ayi na shafi a cikin lambar last_name. Wannan yana nufin za a saita null a can. Kuna iya barin hanyar kuma ƙara cak don null, amma mafi kyawun bayani zai kasance don tabbatar da cewa a cikin tunani getSurname() kun zaɓi madaidaicin ƙimar mara sifili.

Gwajin A/B

Halin da ake ciki yanzu shine muna da sigar aikace-aikacen 1.0.0, wanda aka tura akan samarwa, da kuma bayanan bayanai a ciki v1. Muna buƙatar tura misali na biyu na aikace-aikacen sigar 2.0.0wanda zai sabunta database zuwa v2.

Matakai:

  1. an tura sabon misali na sigar aikace-aikacen 2.0.0wanda ke sabunta bayanan zuwa v2
  2. A halin da ake ciki an sarrafa wasu buƙatun ta hanyar misalan sigar 1.0.0
  3. sabuntawar ya yi nasara kuma kuna da lokuta da yawa masu gudana na aikace-aikacen sigar 1.0.0 da sauran iri 2.0.0. Kowane mutum yana sadarwa tare da bayanan bayanai a ciki v2
  4. sigar 1.0.0 baya amfani da ginshiƙin sunan mahaifi a cikin bayanan, amma sigar 2.0.0 amfani. Ba sa tsoma baki a tsakanin juna, kuma kada a yi kuskure.
  5. sigar 2.0.0 tana adana bayanai a cikin tsohon da sabon shafi, yana tabbatar da dacewa da baya

Yana da muhimmanci. Idan kuna da wasu tambayoyin da ke ƙirga abubuwa dangane da ƙima daga tsohon/sabon ginshiƙi, ya kamata ku tuna cewa yanzu kuna da ƙima mai kwafi (wataƙila har yanzu suna ƙaura). Misali, idan kuna son kirga adadin masu amfani waɗanda sunansu na ƙarshe (duk abin da ake kira rukunin) ya fara da harafin. A, sannan har sai an kammala hijirar bayanai (oldnew shafi) kuna iya samun bayanan da ba daidai ba idan kun nemi sabon shafi.

Maimaita aikace-aikacen

Yanzu muna da app version 2.0.0 da database in v2.

Matakai:

  1. mayar da aikace-aikacen ku zuwa sigar 1.0.0.
  2. sigar 1.0.0 baya amfani da ginshiƙi a cikin bayanan surname, don haka jujjuyawar ya kamata a yi nasara

Canje-canje a cikin DB

Database ya ƙunshi shafi mai suna last_name.

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

Ƙara rubutun surname.

Hankali. Ka tuna cewa BA ZA KA IYA KARA KOWANE RA'AYI BA a kan ginshiƙin da kake ƙarawa. Idan kuka sake jujjuya JAR, tsohuwar sigar ba za ta sami masaniya game da ginshiƙin da aka ƙara ba kuma za ta saita shi ta atomatik zuwa NULL. Idan akwai irin wannan iyakancewa, tsohon aikace-aikacen zai karya kawai.

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

Code canje-canje

Muna adana bayanai kamar yadda last_name, da kuma cikin surname. A lokaci guda kuma mun karanta daga last_name, tunda wannan shafi ya fi dacewa. Yayin aikin turawa, wasu buƙatun ƙila an sarrafa su ta misalin aikace-aikacen da ba a sabunta ba tukuna.

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

Mataki 3: Cire last_name daga lambar

Sigar manhaja: 3.0.0

Sigar DB:v3

comment

Lura per.: A bayyane yake, a cikin ainihin labarin marubucin ya yi kuskure ya kwafi rubutun wannan block daga mataki na 2. A wannan mataki, ya kamata a yi canje-canje a cikin lambar aikace-aikacen da nufin cire ayyukan da ke amfani da shafi. last_name.

Ta ƙara sabon shafi da kwafin abin da ke cikinsa, mun ƙirƙiri sauye-sauyen bayanan bayanai masu jituwa a baya. Hakanan, idan muka sake jujjuya JAR ko kuma tsohuwar JAR tana gudana, ba zai karye ba yayin aiwatarwa.

Maimaita aikace-aikacen

A halin yanzu muna da app version 3.0.0 da database v3. Sigar 3.0.0 baya ajiye bayanai zuwa last_name. Wannan yana nufin cewa in surname ana adana bayanai na zamani.

Matakai:

  1. mayar da aikace-aikacen ku zuwa sigar 2.0.0.
  2. sigar 2.0.0 amfani da last_name и surname.
  3. sigar 2.0.0 zai dauka surname, idan ba sifili ba, in ba haka ba -last_name

Database canje-canje

Babu canje-canjen tsari a cikin bayanan. Ana aiwatar da rubutun mai zuwa don aiwatar da ƙaura na ƙarshe na tsoffin bayanai:

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

Code canje-canje

Lura per.: Marubucin ya kwafi kuskuren bayanin wannan toshe daga mataki na 2. Dangane da mahangar labarin, canje-canje a cikin lambar a wannan matakin ya kamata a yi niyya don cire abubuwan da ke aiki tare da ginshiƙi. last_name.

Muna adana bayanai kamar yadda last_name, da kuma cikin surname. Ƙari ga haka, mun karanta daga shafi last_name, tun da shi ne ya fi dacewa. Yayin aikin turawa, ana iya sarrafa wasu buƙatun ta misalin da ba a inganta ba tukuna.

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

Mataki 4: Cire last_name daga ma'ajin bayanai

Sigar manhaja: 4.0.0

Sigar DB: v4

comment

Из-за того, что код версии 3.0.0 bai yi amfani da ginshiƙi ba last_name, Babu wani mummunan abu da zai faru a lokacin kisa idan muka koma baya 3.0.0 bayan cire wani shafi daga rumbun adana bayanai.

Rubutun kisa

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

Canje-canje a cikin DB

Dangi v3 mu kawai cire ginshiƙi last_name kuma ƙara ƙuntatawa bace.

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

Code canje-canje

Babu canje-canje ga lambar.

ƙarshe

Mun yi nasarar aiwatar da canjin sunan shafi na baya-mara jituwa ta hanyar aiwatar da turawa da yawa masu dacewa da baya. A ƙasa akwai taƙaitaccen ayyukan da aka yi:

  1. tura nau'in aikace-aikacen 1.0.0 с v1 tsarin bayanai (sunan shafi = last_name)
  2. tura nau'in aikace-aikacen 2.0.0, wanda ke adana bayanai a ciki last_name и surname. Aikace-aikacen yana karantawa daga last_name. Database yana cikin sigar v2dauke da ginshiƙai kamar last_namekuma surname. surname kwafin last_name. (NOTE: Dole ne wannan rukunin ya kasance ba shi da ƙayyadaddun ƙayyadaddun ƙayatarwa)
  3. tura nau'in aikace-aikacen 3.0.0, wanda kawai ke adana bayanai a ciki surname kuma ya karanta daga sunan mahaifiya. Dangane da bayanan bayanai, ƙaura ta ƙarshe tana faruwa last_name в surname. Hakanan iyakance BA NULL ba cire daga last_name. Database yanzu yana cikin sigar v3
  4. tura nau'in aikace-aikacen 4.0.0 - ba a yi canje-canje ga lambar ba. Aiwatar da bayanai v4, wanda ke cirewa last_name. Anan za ku iya ƙara duk wani ƙuntatawa da ya ɓace zuwa bayanan bayanai.

Ta bin wannan hanyar, koyaushe zaka iya mirgine juzu'i ɗaya ba tare da karya daidaiton bayanai/aiki ba.

Lambar

Ana samun duk lambar da aka yi amfani da ita a wannan labarin a Github. A ƙasa akwai ƙarin bayanin.

Ayyuka

Bayan cloning wurin ajiya, za ku ga tsarin babban fayil mai zuwa.

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

Rubutun

Kuna iya gudanar da rubutun da aka kwatanta a cikin rubutun da ke ƙasa, waɗanda za su nuna baya-jituwa da canje-canje marasa jituwa ga bayanan.

A gani yanayin tare da canje-canje masu dacewa da baya, gudu:

./scripts/scenario_backward_compatible.sh

Kuma don gani yanayin tare da sauye-sauye marasa jituwa na baya, gudu:

./scripts/scenario_backward_incompatible.sh

Samfurin Jirgin Ruwa na bazara

Dukkan misalan an dauko su ne daga Spring Boot Sample Flyway.

Kuna iya dubawa http://localhost:8080/flyway, akwai jerin rubutun.

Wannan misalin kuma ya haɗa da na'urar wasan bidiyo na H2 (at http://localhost:8080/h2-console) don haka zaku iya duba matsayin bayanan (tsoho jdbc URL shine jdbc:h2:mem:testdb).

bugu da žari

Hakanan karanta wasu labarai akan shafinmu:

source: www.habr.com

Add a comment