Zero Downtime Deployment and Databases

Zero Downtime Deployment and Databases

Ity lahatsoratra ity dia manazava amin'ny antsipiriany ny fomba hamahana ny olana mifanentana amin'ny angon-drakitra amin'ny fametrahana. Holazainay aminao izay mety hitranga amin'ny rindranasa famokarana anao raha manandrana mametraka tsy misy fanomanana mialoha ianao. Avy eo isika dia handeha amin'ny dingan'ny tsingerin'ny androm-piainany izay takiana amin'ny tsy fisian'ny fotoana fialan-tsasatra (eo ho eo lalana: lavidavitra kokoa - zero downtime). Ny vokatry ny asa ataontsika dia ny hampihatra ny fanovana angon-drakitra tsy mifanaraka amin'ny lamosina amin'ny fomba mihemotra.

Raha te-hahatakatra ny ohatra kaody avy amin'ny lahatsoratra ianao dia afaka mahita azy ireo ao amin'ny GitHub.

fampidirana

Fametrahana ny fotoana tsy miato

Tena mistika fametrahana aotra midina? Azonao atao ny milaza fa rehefa apetraka amin'ny fomba mahomby ny fampiharanao ny fampiharana anao amin'ny famokarana, dia tsy hitan'ny mpampiasa ny tsy fisiany. Avy amin'ny fomba fijerin'ny mpampiasa sy ny orinasa, ity no scenario fandefasana tsara indrindra satria mamela ireo endri-javatra vaovao hampidirina sy hamboarina tsy misy fanelingelenana.

Ahoana no hanatratrarana izany? Misy fomba maro, ity ny iray amin'izy ireo:

  • apetraho ny kinova laharana 1 amin'ny serivisinao
  • manao fifindra-monina angona
  • Ampifanaraho amin'ny kinova #2 ny kinova #1 amin'ny serivisinao
  • raha vao hitanao fa miasa araka ny tokony ho izy ny version No. 2 dia esory ny version No. 1
  • vonona!

Mora, sa tsy izany? Indrisy anefa fa tsy dia tsotra izany, ary hojerentsika amin'ny antsipiriany izany any aoriana. Andeha hojerentsika ny dingana fametrahana mahazatra hafa - blue green deployment.

Efa nandre momba izany ve ianao fametrahana maitso manga? Cloud Foundry dia manamora izany. Jereo fotsiny ity lahatsoratra ity, izay ilazanay amin'ny antsipiriany bebe kokoa izany. Mba hamintinana fohifohy, avelao izahay hampahatsiahy anao ny fomba hanaovana ny fametrahana manga maitso:

  • ho azo antoka fa miasa ny dika roa amin'ny kaody famokarana anao (“manga” sy “maitso”);
  • mivantana ny fifamoivoizana rehetra mankany amin'ny tontolo manga, i.e. ka ny URL famokarana dia manondro eo;
  • mametraka sy andramo ny fanovana rehetra amin'ny fampiharana amin'ny tontolo maitso;
  • manova ny url avy amin'ny tontolo manga ho maitso

Ny fametrahana maitso manga dia fomba iray ahafahanao mampiditra mora foana ireo endri-javatra vaovao tsy manahy momba ny fahatapahan'ny famokarana. Izany dia noho ny zava-misy fa na dia misy zava-mitranga aza, dia afaka miverina mora foana amin'ny tontolo teo aloha ianao amin'ny alàlan'ny "flickering switch".

Rehefa avy mamaky ireo rehetra voalaza etsy ambony ireo ianao dia mety hanontany ny fanontaniana hoe: Inona no ifandraisan'ny zero downtime amin'ny fametrahana Blue Green?

Be dia be ny zavatra iraisan'izy ireo, satria mitaky ezaka avo roa heny ny fikojakojana azy ireny. Izany no mahatonga ny ekipa sasany milaza Martin Fowler, araho ny fiovaovan'ity fomba fiasa ity:

Safidy iray hafa dia ny fampiasana angon-drakitra mitovy, mamorona switch manga-maitso ho an'ny tranonkala sy ny sehatra sehatra. Amin'ity fomba ity dia mety ho olana matetika ny angon-drakitra, indrindra rehefa mila manova ny schema ianao hanohanana dikan-teny vaovao amin'ny rindrambaiko.

Ary tonga amin'ny olana lehibe ato amin'ity lahatsoratra ity isika. banky angona. Andeha hojerentsika indray ity fehezanteny ity.

manao fifindra-monina angona.

Ankehitriny dia mila manontany tena ny fanontaniana ianao - ahoana raha tsy mifanaraka amin'ny lamosina ny fiovan'ny angon-drakitra? Tsy ho tapaka ve ny dikan-teny voalohany amin'ny app? Raha ny marina, izany indrindra no hitranga...

Noho izany, na dia eo aza ny tombony lehibe amin'ny fametrahana zero downtime / manga maitso, ny orinasa dia manaraka ny dingana azo antoka kokoa amin'ny fametrahana ny fampiharana azy ireo:

  • manomana fonosana misy dikan-teny vaovao amin'ny fampiharana
  • atsaharo ny fampiharana mandeha
  • mihazakazaka scripts hamindra ny angon-drakitra
  • manaparitaka sy manangana dikan-teny vaovao amin'ny fampiharana

Ato amin'ity lahatsoratra ity dia hazavainay amin'ny antsipiriany ny fomba ahafahanao miara-miasa amin'ny angon-drakitrao sy ny kaody mba hanararaotra ny fametrahana tsy misy fiatoana.

Olana amin'ny angon-drakitra

Raha manana fampiharana tsy misy fanjakana ianao izay tsy mitahiry angon-drakitra ao amin'ny angon-drakitra, dia azonao atao avy hatrany ny fametrahana aotra midina. Indrisy anefa fa mila mitahiry angona any ho any ny ankamaroan'ny rindrambaiko. Izany no antony tokony hieritreretana indroa alohan'ny hanaovana fanovana amin'ny circuit. Alohan'ny hidirantsika amin'ny antsipirihan'ny fomba hanovana ny tetika mba ahafahana mametraka tsy misy fiatoana dia andao aloha hifantoka amin'ny tetika famoahana.

Tetika famoahana

Amin'ity lahatsoratra ity dia hampiasaintsika Flyway ho fitaovana fanaraha-maso dikan-(eo ho eo Fandikan-teny: miresaka momba ny fifindra-monina angona isika). Mazava ho azy fa hanoratra rindranasa Lohataona Boot izay manana fanohanana Flyway ao anatiny ary hanao fifindra-monina schema mandritra ny fametrahana ny tontolon'ny fampiharana. Rehefa mampiasa Flyway ianao dia afaka mitahiry ny script fifindra-monina ao amin'ny lahatahiry tetikasanao (amin'ny alàlan'ny default in classpath:db/migration). Eto ianao dia afaka mahita ohatra momba ny fifindra-monina toy izany

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

Amin'ity ohatra ity dia mahita script fifindra-monina 4 isika izay, raha tsy vita teo aloha, dia hotanterahina manaraka rehefa manomboka ny fampiharana. Andeha hojerentsika ny iray amin'ireo rakitra (V1__init.sql) ho ohatra.

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

Ny zava-drehetra dia mazava tsara: azonao atao ny mampiasa SQL hamaritana ny fomba tokony hanovana ny angonao. Raha mila fanazavana fanampiny momba ny Spring Boot sy Flyway, jereo Lohataona Boot Docs.

Amin'ny fampiasana fitaovana fanaraha-maso loharano miaraka amin'ny Spring Boot dia mahazo tombony lehibe 2 ianao:

  • manasaraka ny fanovana angon-drakitra amin'ny fanovana code ianao
  • Mitranga miaraka amin'ny fandefasana ny fampiharanao ny fifindra-monina, izany hoe. tsotsotra ny fizotran'ny fametrahanao

Famahana olana amin'ny database

Ao amin'ny fizarana manaraka amin'ny lahatsoratra, hifantoka amin'ny fijerena fomba roa amin'ny fanovana angon-drakitra isika.

  • tsy mifanaraka aoriana
  • fifanarahana mihemotra

Ny voalohany dia ho raisina ho toy ny fampitandremana fa tsy tokony hanao zero downtime deployment raha tsy misy fanomanana mialoha... Ny faharoa dia manolotra vahaolana amin'ny fomba ahafahanao manao deployment tsy misy fiatoana ary miaraka amin'izay koa mitazona ny fifanarahana miverina.

Ny tetikasanay izay hiasa dia ho fampiharana tsotra amin'ny Spring Boot Flyway izay manana Person с first_name и last_name ao amin'ny database (eo ho eo fandikana: Person dia latabatra sy first_name и last_name - ireo no saha ao anatiny). Te hanova anarana izahay last_name в surname.

tombantombana

Alohan'ny hidirantsika amin'ny antsipiriany dia misy vinavina roa tokony hataontsika momba ny fampiharana ataontsika. Ny vokatra lehibe tiantsika hotratrarina dia dingana tsotra.

Ny naoty. Business PRO-TIP. Ny fanatsorana ny dingana dia afaka mitahiry vola be anao amin'ny fanohanana (arakaraka ny mahabetsaka ny olona miasa ho an'ny orinasanao, ny vola azonao voatahiry)!

Tsy mila mamerina ny angon-drakitra

Manamora ny fizotry ny fametrahana izany (saika tsy azo atao ny famerenana ny angon-drakitra sasany, toy ny famerenana famafana). Aleonay mamerina ny fampiharana ihany. Amin'izany fomba izany, na dia manana angon-drakitra samihafa aza ianao (ohatra, SQL sy NoSQL), dia hitovy ny fijery ny fantsona fandefasana anao.

Tsy maintsy azo atao foana ny mamerina ny fampiharana amin'ny dikan-teny iray (tsy misy intsony)

Ny famerenana dia tokony hatao raha ilaina ihany. Raha misy bug ao amin'ny kinova ankehitriny izay tsy mora raikitra, dia tokony ho afaka hiverina amin'ny dikan-teny miasa farany isika. Heverintsika fa io dikan-teny miasa farany io no teo aloha. Ny fitazonana ny kaody sy ny angon-drakitra mifanaraka amin'ny fandefasana mihoatra ny iray dia ho sarotra sy lafo tokoa.

Ny naoty. Ho an'ny famakiana bebe kokoa, ato amin'ity lahatsoratra ity dia hanova ny dikan-teny lehibe amin'ny fampiharana isika.

Dingana 1: Fanjakana voalohany

App Version: 1.0.0
DB version: v1

fanehoan-kevitra

Izany no toetry ny fampiharana voalohany.

Fanovana ny angon-drakitra

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

Fiovana kaody

Ny fampiharana dia mitahiry ny angon'ny olona ao 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
                + "]";
    }
}

Famerenana anarana tsanganana mihemotra tsy mifanaraka

Andeha hojerentsika ny ohatra iray amin'ny fanovana anarana tsanganana:

Fiheverana. Ity ohatra manaraka ity dia minia handrava zavatra. Asehonay izany mba hampisehoana ny olana momba ny fampifanarahana ny angon-drakitra.

App Version: 2.0.0.BAD

DB version: v2bad

fanehoan-kevitra

Ny fanovana ankehitriny dia TSY mamela antsika handefa fotoana roa (antitra sy vaovao) miaraka. Noho izany, ho sarotra ny hahatratra ny fametrahana ny fotoana tsy misy fetra (raha raisina ny fiheverana dia tsy azo atao izany).

Fitsapana A/B

Ny zava-misy amin'izao fotoana izao dia manana version of application isika 1.0.0, napetraka amin'ny famokarana, ary ny database v1. Mila mametraka ohatra faharoa amin'ny fampiharana isika, version 2.0.0.BAD, ary manavao ny angon-drakitra amin'ny v2bad.

dingana:

  1. misy ohatra vaovao amin'ny rindranasa kinova no apetraka 2.0.0.BADizay manavao ny angon-drakitra amin'ny v2bad
  2. ao amin'ny tahiry v2bad tsanganana last_name tsy misy intsony - novaina ho surname
  3. Nahomby ny fanavaozam-baovao sy ny fampiharana ary mandeha ny fotoana sasany 1.0.0, hafa - in 2.0.0.BAD. Ny zava-drehetra dia mifandray amin'ny angon-drakitra v2bad
  4. ohatra rehetra amin'ny dikan-teny 1.0.0 dia hanomboka hanipy fahadisoana satria hiezaka ny hampiditra angona ao amin'ny tsanganana last_nameizay tsy misy intsony
  5. ohatra rehetra amin'ny dikan-teny 2.0.0.BAD hiasa tsy misy olana

Araka ny hitanao, raha manao fanovana tsy mifanaraka amin'ny angon-drakitra sy fampiharana isika dia tsy azo atao ny fitiliana A/B.

Famerenana ny fampiharana

Andao atao hoe rehefa avy nanandrana nanao A/B deployment (eo ho eo per.: A/B test angamba no tian'ny mpanoratra holazaina eto) nanapa-kevitra izahay fa mila mamerina ny fampiharana amin'ny dikan-teny 1.0.0. Andeha atao hoe tsy te-hamerenana ny angon-drakitra.

dingana:

  1. ajanonay ny ohatra fampiharana version 2.0.0.BAD
  2. ny angon-drakitra dia mbola v2bad
  3. hatramin'ny version 1.0.0 tsy azoko hoe inona izany surname, dia hahita fahadisoana isika
  4. rava ny helo, tsy afaka miverina intsony isika

Araka ny hitanao, raha manao fanovana tsy mifanaraka amin'ny angon-drakitra sy fampiharana izahay dia tsy afaka miverina amin'ny dikan-teny teo aloha.

Logs famonoana script

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

Fanovana ny angon-drakitra

Script fifindra-monina izay manova anarana last_name в surname

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

Script izay manova anarana last_name.

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

Fiovana kaody

Novainay ny anaran'ny saha lastName amin'ny surname.

Fanovana ny anaran'ny tsanganana amin'ny fomba mihemotra

Io no toe-javatra mahazatra indrindra mety sendra antsika. Mila manao fanovana tsy mifanaraka amin'ny lamosina isika. Efa noporofoinay fa ho an'ny fametrahana zero-downtime dia tsy tokony hampihatra fotsiny ny fifindran'ny database tsy misy dingana fanampiny. Ato amin'ity fizarana amin'ny lahatsoratra ity, dia hanao fametrahana 3 amin'ny fampiharana miaraka amin'ny fifindra-monina amin'ny angon-drakitra izahay mba hahatratrarana ny vokatra tadiavina nefa mitazona ny fifanarahana miverina.

Ny naoty. Tsarovy fa manana database version izahay v1. Misy tsanganana izy io first_name и last_name. Tsy maintsy miova isika last_name amin'ny surname. Manana version app koa izahay 1.0.0, izay tsy mbola ampiasaina surname.

Dingana 2: Ampio anarana

App Version: 2.0.0
DB version: v2

fanehoan-kevitra

Amin'ny fampidirana tsanganana vaovao sy fanaovana kopia ny atiny, dia mamorona fanovana angon-drakitra mifanaraka amin'ny aoriana. Amin'izay fotoana izay ihany koa, raha mihodina ny JAR na manana JAR taloha mandeha isika, dia tsy ho tapaka izany mandritra ny famonoana.

Mamoaka dikan-teny vaovao izahay

dingana:

  1. manaova fifindrana angona mba hamoronana tsanganana vaovao surname. Ankehitriny ny version DB anao v2
  2. kopia angona avy amin'ny last_name в surname. Mitandremafa raha manana data be dia be ianao dia tokony handinika ny fifindra-monina batch!
  3. soraty ny kaody ampiasana azy ROA и новыйary ny antitra tsanganana. Izao ny dikan-teninao 2.0.0
  4. vakio ny sanda avy amin'ny tsanganana surname, raha tsy izany null, na avy amin'ny last_name, raha a surname tsy voasoritra. Afaka mamafa ianao getLastName() avy amin'ny kaody, satria hivoaka null rehefa mamerina ny fangatahanao avy amin'ny 3.0.0 до 2.0.0.

Raha mampiasa Spring Boot Flyway ianao, ireo dingana roa ireo dia hatao mandritra ny fanombohana ny dikan-teny 2.0.0 fampiharana. Raha toa ianao ka mihazakazaka ny fitaovana fanokafana angon-drakitra amin'ny tanana, dia tsy maintsy manao zavatra roa samy hafa ianao mba hanaovana izany (fanavaozana voalohany ny dikan-db amin'ny tanana ary avy eo ampidiro ny fampiharana vaovao).

Zava-dehibe izany. Tsarovy fa ny tsanganana vao noforonina TSY TOKONY to be TSY NOLO. Raha manao rollback ianao, ny fampiharana taloha dia tsy mahafantatra momba ny tsanganana vaovao ary tsy hametraka izany mandritra ny fotoana Insert. Fa raha ampianao io teritery io dia ho ny db-nao v2, izany dia mitaky ny fametrahana ny sandan'ny tsanganana vaovao. Izay hitarika amin'ny fanitsakitsahana ny fameperana.

Zava-dehibe izany. Tokony esorinao ny fomba getLastName(), satria amin'ny dikan-teny 3.0.0 Tsy misy hevitra momba ny tsanganana ao amin'ny kaody last_name. Midika izany fa hapetraka eo ny null. Azonao atao ny miala amin'ny fomba ary manampy fanamarinana null, fa ny vahaolana tsara kokoa dia ny hahazoana antoka fa amin'ny lojika getSurname() nifidy ny sanda tsy aotra marina ianao.

Fitsapana A/B

Ny zava-misy amin'izao fotoana izao dia manana version of application isika 1.0.0, napetraka amin'ny famokarana, ary ny angon-drakitra ao v1. Mila mametraka ohatra faharoa amin'ny rindranasa kinova isika 2.0.0izay hanavao ny angon-drakitra amin'ny v2.

dingana:

  1. misy ohatra vaovao amin'ny rindranasa kinova no apetraka 2.0.0izay manavao ny angon-drakitra amin'ny v2
  2. Mandritra izany fotoana izany, ny fangatahana sasany dia nokarakaraina tamin'ny alàlan'ny dikan-teny 1.0.0
  3. nahomby ny fanavaozana ary manana tranga maro mandeha amin'ny rindranasa kinova ianao 1.0.0 ary dikan-teny hafa 2.0.0. Ny tsirairay dia mifandray amin'ny angon-drakitra ao v2
  4. Malagasy Bible 1.0.0 tsy mampiasa ny tsanganana anaram-bositra ao amin'ny tahiry, fa ny dikan-teny 2.0.0 fampiasana. Tsy mifanalavitra izy ireo, ary tsy tokony hisy fahadisoana.
  5. Malagasy Bible 2.0.0 mitahiry angona ao amin'ny tsanganana taloha sy vaovao, miantoka ny fifanarahana miverina

Zava-dehibe izany. Raha manana fanontaniana ianao izay manisa singa mifototra amin'ny soatoavina avy amin'ny tsanganana taloha/vaovao, dia tokony ho tsaroanao fa manana soatoavina dika mitovy ianao (azo inoana fa mbola mifindra monina izy ireo). Ohatra, raha te-hanisa ny isan'ny mpampiasa ny anarany (na inona na inona iantsoana ny tsanganana) dia nanomboka tamin'ny taratasy A, dia mandra-pahavitan'ny fifindra-monina (oldnew tsanganana) mety manana angona tsy mifanaraka ianao raha manontany tsanganana vaovao.

Famerenana ny fampiharana

Manana version app izahay izao 2.0.0 ary database in v2.

dingana:

  1. avereno amin'ny version ny fampiharanao 1.0.0.
  2. Malagasy Bible 1.0.0 tsy mampiasa tsanganana ao anaty angon-drakitra surname, noho izany dia tokony hahomby ny famerenana

DB fiovana

Ny tahiry dia misy tsanganana antsoina hoe last_name.

Lahatsoratra momba ny loharanon'ny 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');

Ampio script surname.

Fiheverana. Tsarovy fa TSY AFAKA ATAONAO izay teritery NOT NULL amin'ny tsanganana ampianao. Raha averinao indray ny JAR dia tsy hanan-kevitra momba ny tsanganana fanampiny ny dikan-teny taloha ary hametraka azy ho azy ho NULL. Raha misy famerana toy izany dia tapaka fotsiny ny fampiharana taloha.

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

Fiovana kaody

Mitahiry angona toy ny last_name, ary ao surname. Amin'izay fotoana izay ihany koa dia mamaky avy amin'ny last_name, satria ity tsanganana ity no tena manan-danja indrindra. Nandritra ny dingan'ny fametrahana dia mety efa nokarakarain'ny ohatra fampiharana izay mbola tsy nohavaozina ny fangatahana sasany.

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

Dingana 3: Esory ny anarana farany amin'ny code

App Version: 3.0.0

DB version:v3

fanehoan-kevitra

Fanamarihana per.: Raha ny fahitana azy, tao amin'ny lahatsoratra tany am-boalohany dia diso nandika ny lahatsoratr'ity sakana ity avy amin'ny dingana 2 ny mpanoratra. Amin'ity dingana ity, dia tokony hatao ny fanovana ao amin'ny fehezan-dalàna fampiharana mikendry ny hanesorana ny fiasa izay mampiasa ny tsanganana. last_name.

Tamin'ny fampidirana tsanganana vaovao sy ny fanaovana kopia ny ao anatiny, dia namorona fanovana angon-drakitra mifanaraka amin'ny aoriana izahay. Ary koa, raha mamerina ny JAR isika na manana JAR taloha mandeha, dia tsy ho tapaka izany mandritra ny famonoana.

Famerenana ny fampiharana

Amin'izao fotoana izao dia manana version app izahay 3.0.0 ary database v3. Malagasy Bible 3.0.0 tsy mitahiry data ho last_name. Midika izany fa in surname voatahiry ny vaovao farany indrindra.

dingana:

  1. avereno amin'ny version ny fampiharanao 2.0.0.
  2. Malagasy Bible 2.0.0 fampiasana ary last_name и surname.
  3. Malagasy Bible 2.0.0 handray surname, raha tsy aotra izany, raha tsy izany -last_name

Fanovana ny angon-drakitra

Tsy misy fiovana ara-drafitra ao amin'ny tahiry. Ity script manaraka ity dia tanterahina hanatanterahana ny fifindra-monina farany amin'ny angona taloha:

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

Fiovana kaody

Fanamarihana per.: Ny filazalazana an'ity sakana ity dia nadika tamin'ny fomba diso ihany koa ny mpanoratra avy amin'ny dingana 2. Mifanaraka amin'ny lojikan'ny lahatsoratra, ny fanovana ny code amin'ity dingana ity dia tokony ho entina hanesorana azy ireo singa miasa miaraka amin'ny tsanganana. last_name.

Mitahiry angona toy ny last_name, ary ao surname. Ankoatra izany, mamaky avy amin'ny tsanganana isika last_name, satria io no manan-danja indrindra. Mandritra ny dingan'ny fametrahana, ny fangatahana sasany dia azo karakaraina amin'ny ohatra mbola tsy nohavaozina.

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

Dingana 4: Esory ny anarana farany amin'ny angon-drakitra

App Version: 4.0.0

DB version: v4

fanehoan-kevitra

Noho ny zava-misy fa ny dikan-kaody 3.0.0 tsy nampiasa ny tsanganana last_name, tsy hisy zavatra ratsy hitranga mandritra ny famonoana raha miverina amin'ny 3.0.0 rehefa avy nanala tsanganana iray tao amin'ny tahiry.

Logs famonoana script

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 fiovana

somary v3 esory fotsiny ny tsanganana last_name ary ampio fameperana tsy hita.

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

Fiovana kaody

Tsy misy fiovana amin'ny kaody.

famaranana

Nahomby izahay nampihatra fanovana anarana tsanganana mihemotra tsy mifanentana amin'ny alalan'ny fanaparitahana maromaro mifanentana. Ity ambany ity ny famintinana ny hetsika natao:

  1. fametrahana ny version application 1.0.0 с v1 schema database (anaran'ny tsanganana = last_name)
  2. fametrahana ny version application 2.0.0, izay mitahiry data ao last_name и surname. Ny fampiharana dia mamaky avy amin'ny last_name. Ny angon-drakitra dia amin'ny dikan-teny v2misy tsanganana toy ny last_name, ary surname. surname dia dika mitovy amin'ny last_name. ( FANAMARIHANA: Ity tsanganana ity dia tsy tokony hanana teritery tsy misy dikany)
  3. fametrahana ny version application 3.0.0, izay mitahiry angona ao anaty surname ary mamaky avy amin'ny anarana. Raha ny angon-drakitra dia misy ny fifindra-monina farany last_name в surname. Famerana ihany koa TSY NOLO nesorina tamin'ny last_name. Amin'izao fotoana izao ny angona angona v3
  4. fametrahana ny version application 4.0.0 - tsy misy fiovana atao amin'ny kaody. Fametrahana angona v4, izay manala last_name. Eto ianao dia afaka manampy izay teritery tsy hita ao amin'ny angon-drakitra.

Amin'ny fanarahana an'io fomba fiasa io dia azonao atao ny mamerina ny dikan-teny iray tsy misy fanitsakitsahana ny fampifanarahana amin'ny database/application.

fehezan-dalàna

Ny kaody rehetra ampiasaina amin'ity lahatsoratra ity dia azo jerena ao amin'ny Github. Ity ambany ity ny famaritana fanampiny.

tetikasa

Aorian'ny fametahana ny tahiry dia ho hitanao ity rafitra fampirimana manaraka ity.

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

soratra

Azonao atao ny mampandeha ireo sora-baventy voalaza ao amin'ny script etsy ambany, izay hampiseho fiovana mihemotra sy tsy mifanaraka amin'ny angon-drakitra.

To see ny tranga misy fiovana mifanaraka aoriana, mihazakazaka:

./scripts/scenario_backward_compatible.sh

Ary mba hahita tranga misy fiovana mihemotra tsy mifanaraka, mihazakazaka:

./scripts/scenario_backward_incompatible.sh

Lohataona Boot Sample Flyway

Ny ohatra rehetra dia nalaina avy amin'ny Spring Boot Sample Flyway.

Azonao atao ny mijery ny http://localhost:8080/flyway, misy lisitry ny script.

Ity ohatra ity dia misy koa ny console H2 (amin'ny http://localhost:8080/h2-console) mba hahafahanao mijery ny satan'ny database (ny URL jdbc default dia jdbc:h2:mem:testdb).

Fanampin'izany

Vakio ihany koa lahatsoratra hafa ao amin'ny bilaoginay:

Source: www.habr.com

Add a comment