Zewo D' Deplwaman ak baz done

Zewo D' Deplwaman ak baz done

Atik sa a eksplike an detay ki jan yo rezoud pwoblèm konpatibilite baz done nan deplwaman. Nou pral di w sa ki ka rive aplikasyon pwodiksyon ou yo si ou eseye deplwaye san preparasyon preliminè. Lè sa a, nou pral ale nan etap sik lavi aplikasyon yo ki oblije gen zewo D '(approx. liy: pi lwen - zewo D '). Rezilta operasyon nou yo pral aplike chanjman baz done enkonpatib bak nan yon fason ki konpatib bak.

Si ou vle konprann egzanp kòd ki soti nan atik la, ou ka jwenn yo nan GitHub.

Entwodiksyon

Zewo deplwaman D '

Ala yon mistik zewo D' deplwaman? Ou ka di sa a se lè aplikasyon w lan deplwaye nan yon fason ke ou ka avèk siksè prezante yon nouvo vèsyon aplikasyon an nan pwodiksyon, pandan y ap itilizatè a pa remake indisponibilite li yo. Soti nan yon pèspektiv itilizatè ak konpayi, sa a se pi bon senaryo deplwaman posib paske li pèmèt nouvo karakteristik yo dwe prezante ak pinèz yo dwe fiks san dezòd.

Ki jan yo reyalize sa a? Gen plizyè fason, isit la se youn nan yo:

  • deplwaye vèsyon nimewo 1 nan sèvis ou a
  • fè yon migrasyon baz done
  • Deplwaye vèsyon #2 nan sèvis ou an paralèl ak vèsyon #1
  • le pli vit ke ou wè ke vèsyon No 2 ap travay jan li ta dwe, retire vèsyon No 1
  • fè!

Fasil, pa vre? Malerezman, li pa senp, e nou pral gade an detay pita. Koulye a, kite a tcheke yon lòt pwosesis deplwaman jistis komen - deplwaman ble vèt.

Eske ou janm tande pale de deplwaman ble vèt? Cloud Foundry fè sa trè fasil. Jis gade atik sa a, kote nou dekri sa a an plis detay. Pou fè yon rezime yon ti tan, kite nou raple w ki jan fè deplwaman ble vèt:

  • asire ke de kopi kòd pwodiksyon ou ("ble" ak "vèt") travay;
  • dirije tout trafik nan anviwònman an ble, i.e. pou ke URL pwodiksyon pwen la;
  • deplwaye ak teste tout chanjman aplikasyon yo nan yon anviwònman vèt;
  • chanje URL soti nan anviwònman ble a vèt

Deplwaman ble vèt se yon apwòch ki pèmèt ou fasilman prezante nouvo karakteristik san yo pa enkyete sou pwodiksyon kraze. Sa a se akòz lefèt ke menm si yon bagay rive, ou ka fasilman retounen nan anviwònman anvan an pa senpleman "flike yon switch."

Apre ou fin li tout sa ki anwo yo, ou ka poze kesyon an: Ki sa zewo D' gen pou wè ak Blue green deplwaman?

Oke, yo gen anpil bagay an komen, depi kenbe de kopi nan menm anviwònman an mande pou double efò pou kenbe yo. Se poutèt sa kèk ekip reklame Martin Fowler, swiv yon varyasyon nan apwòch sa a:

Yon lòt opsyon se sèvi ak menm baz done a, kreye switch ble-vèt pou wèb la ak kouch domèn. Nan apwòch sa a, baz done a ka souvan yon pwoblèm, espesyalman lè ou bezwen chanje chema li yo sipòte yon nouvo vèsyon nan lojisyèl an.

Ak isit la nou rive nan pwoblèm prensipal la nan atik sa a. Baz done. Ann pran yon lòt gade nan fraz sa a.

fè yon migrasyon baz done.

Koulye a, ou dwe poze tèt ou kesyon an - e si chanjman baz done a pa konpatib bak? Èske premye vèsyon mwen an nan aplikasyon an pa pral kraze? An reyalite, sa a se egzakteman sa ki pral rive ...

Se konsa, menm malgre gwo benefis ki genyen nan zewo D '/deplwaman ble vèt, konpayi yo gen tandans swiv pwosesis sa a ki pi an sekirite pou deplwaye aplikasyon yo:

  • prepare yon pake ak yon nouvo vèsyon aplikasyon an
  • fèmen yon aplikasyon kap kouri
  • kouri scripts pou imigre baz done a
  • deplwaye ak lanse yon nouvo vèsyon aplikasyon an

Nan atik sa a, nou pral detaye ki jan ou ka travay avèk baz done ou ak kòd pou pran avantaj de deplwaman zewo D '.

Pwoblèm baz done yo

Si ou gen yon aplikasyon apatrid ki pa estoke okenn done nan baz done a, ou ka jwenn zewo deplwaman tan D' touswit. Malerezman, pifò lojisyèl bezwen sere done yon kote. Se poutèt sa ou ta dwe reflechi de fwa anvan ou fè nenpòt chanjman nan kous la. Anvan nou antre nan detay yo sou fason pou chanje chema a pou deplwaman pa gen tan an posib, ann premye konsantre sou chema vèsyon an.

Konplo vèsyon

Nan atik sa a nou pral itilize Flyway kòm yon zouti kontwòl vèsyon (approx. Tradiksyon: n ap pale de migrasyon baz done yo). Natirèlman, nou pral ekri tou yon aplikasyon Spring Boot ki gen sipò Flyway entegre epi li pral fè migrasyon chema pandan y ap mete kontèks aplikasyon an. Lè w ap itilize Flyway, ou ka estoke scripts migrasyon yo nan katab pwojè ou yo (pa default nan classpath:db/migration). Isit la ou ka wè yon egzanp dosye migrasyon sa yo

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

Nan egzanp sa a nou wè 4 script migrasyon ki, si yo pa egzekite deja, yo pral egzekite youn apre lòt lè aplikasyon an kòmanse. Ann gade youn nan fichye yo (V1__init.sql) kòm yon egzanp.

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

Tout bagay pafètman pwòp tèt ou-eksplikasyon: ou ka itilize SQL defini ki jan baz done ou ta dwe modifye. Pou plis enfòmasyon sou Spring Boot ak Flyway, tcheke deyò Spring Boot Docs.

Lè w itilize yon zouti kontwòl sous ak Spring Boot, ou jwenn 2 gwo avantaj:

  • ou separe chanjman baz done ak chanjman kòd
  • Migrasyon baz done fèt ansanm ak deplwaye aplikasyon w lan, sa vle di. pwosesis deplwaman ou senplifye

Depanaj pwoblèm baz done

Nan pwochen seksyon atik la, nou pral konsantre sou gade de apwòch nan chanjman baz done.

  • enkonpatibilite bak
  • konpatibilite bak

Premye a pral konsidere kòm yon avètisman ke ou pa ta dwe fè zewo deplwaman D 'san preparasyon preliminè... Dezyèm lan ofri yon solisyon sou ki jan ou ka fè yon deplwaman san D 'e an menm tan kenbe konpatibilite bak.

Pwojè nou an nou pral travay sou yo pral yon senp aplikasyon Spring Boot Flyway ki genyen Person с first_name и last_name nan baz done a (approx. tradiksyon: Person se yon tab ak first_name и last_name - sa yo se jaden yo nan li). Nou vle chanje non last_name в surname.

Sipozisyon

Anvan nou antre nan detay yo, gen yon koup nan sipozisyon nou bezwen fè sou aplikasyon nou yo. Rezilta prensipal nou vle reyalize yo pral yon pwosesis san patipri senp.

Nòt la. Biznis PRO-TIP. Senplifye pwosesis yo ka sove ou anpil lajan sou sipò (plis moun ou genyen k ap travay pou konpayi ou, plis lajan ou ka ekonomize)!

Pa bezwen rollback baz done a

Sa senplifye pwosesis deplwaman an (kèk rollback baz done yo prèske enposib, tankou sipresyon rollback). Nou prefere retire aplikasyon sèlman. Nan fason sa a, menm si ou gen baz done diferan (pa egzanp, SQL ak NoSQL), tiyo deplwaman ou a ap sanble menm bagay la.

Li dwe TOUJOU posib pou fè aplikasyon an tounen yon vèsyon tounen (pa plis)

Rollback ta dwe fèt sèlman lè sa nesesè. Si gen yon ensèk nan vèsyon aktyèl la ki pa fasil ranje, nou ta dwe kapab retounen nan dènye vèsyon k ap travay la. Nou sipoze ke dènye vèsyon travay sa a se youn anvan an. Kenbe kòd ak baz done konpatibilite pou plis pase yon lanse ta trè difisil ak chè.

Nòt la. Pou plis lizibilite, nan atik sa a nou pral chanje vèsyon prensipal aplikasyon an.

Etap 1: Eta Inisyal

App vèsyon: 1.0.0
DB vèsyon: v1

Kòmantè

Sa a pral premye eta aplikasyon an.

Chanjman nan baz done yo

DB gen ladan l 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');

Kòd chanjman

Aplikasyon an estoke done moun nan 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
                + "]";
    }
}

Enkonpatib chanje non kolòn bak

Ann gade yon egzanp sou fason pou chanje non yon kolòn:

Atansyon. Egzanp sa a pral fè entansyonèlman kraze bagay sa yo. Nou montre sa pou demontre pwoblèm konpatibilite baz done a.

App vèsyon: 2.0.0.BAD

DB vèsyon: v2bad

Kòmantè

Chanjman aktyèl yo PA pèmèt nou kouri de ka (ansyen ak nouvo) an menm tan. Kidonk, deplwaman zewo D 'ap difisil pou reyalize (si sipozisyon yo pran an kont, li se aktyèlman enposib).

Tès A/B

Sitiyasyon aktyèl la se ke nou gen yon vèsyon aplikasyon an 1.0.0, deplwaye nan pwodiksyon, ak baz done v1. Nou bezwen deplwaye yon dezyèm egzanp aplikasyon an, vèsyon an 2.0.0.BAD, epi mete ajou baz done a v2bad.

Etap:

  1. yon nouvo egzanp aplikasyon vèsyon an deplwaye 2.0.0.BADki mete ajou baz done a v2bad
  2. nan baz done a v2bad kolòn last_name pa egziste ankò - li te chanje an surname
  3. Mizajou baz done a ak aplikasyon an te reyisi epi kèk ka ap kouri 1.0.0, lòt moun - nan 2.0.0.BAD. Tout bagay konekte ak baz done a v2bad
  4. tout ka nan vèsyon an 1.0.0 pral kòmanse voye erè paske yo pral eseye mete done nan kolòn nan last_nameki pa egziste ankò
  5. tout ka nan vèsyon an 2.0.0.BAD pral travay san pwoblèm

Kòm ou ka wè, si nou fè bak chanjman enkonpatib nan baz done a ak aplikasyon an, tès A/B enposib.

Rollback aplikasyon

Ann sipoze ke apre yo fin eseye fè deplwaman A/B (approx. per.: otè a pwobableman vle di tès A / B isit la) nou deside ke nou bezwen woule tounen aplikasyon an nan vèsyon an 1.0.0. Ann di nou pa vle rollback baz done a.

Etap:

  1. nou sispann egzanp aplikasyon vèsyon an 2.0.0.BAD
  2. baz done a toujou v2bad
  3. depi vèsyon an 1.0.0 pa konprann sa li ye surname, nou pral wè erè
  4. lanfè te kase, nou pa ka tounen ankò

Kòm ou ka wè, si nou fè bak chanjman enkonpatib nan baz done a ak aplikasyon an, nou pa ka retounen nan vèsyon anvan an.

Script ekzekisyon journaux

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

Chanjman nan baz done yo

Script migrasyon ki chanje non last_name в surname

Sous Flyway script:

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 ki chanje non last_name.

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

Kòd chanjman

Nou te chanje non jaden an lastName sou surname.

Chanje non yon kolòn nan yon fason ki konpatib bak

Sa a se sitiyasyon ki pi komen nou ka rankontre. Nou bezwen fè bak chanjman enkonpatib. Nou te deja pwouve ke pou deplwaman zewo-downtime, nou pa ta dwe tou senpleman aplike migrasyon baz done san etap adisyonèl. Nan seksyon sa a nan atik la, nou pral fè 3 deplwaman aplikasyon an ansanm ak migrasyon baz done yo reyalize rezilta a vle pandan w ap kenbe konpatibilite bak.

Nòt la. Sonje byen ke nou gen yon baz done vèsyon v1. Li gen kolòn first_name и last_name. Nou dwe chanje last_name sou surname. Nou gen tou vèsyon aplikasyon an 1.0.0, ki poko itilize surname.

Etap 2: Ajoute ti non

App vèsyon: 2.0.0
DB vèsyon: v2

Kòmantè

Lè nou ajoute yon nouvo kolòn epi kopye sa ki ladan l, nou kreye chanjman baz done konpatib bak. An menm tan an, si nou rollback JAR a oswa gen yon ansyen JAR kouri, li p ap kraze pandan ekzekisyon.

Nou ap woule soti yon nouvo vèsyon

Etap:

  1. fè yon migrasyon baz done pou kreye yon nouvo kolòn surname. Koulye a, vèsyon DB ou a v2
  2. kopye done ki soti nan last_name в surname. Peye atansyonke si ou gen anpil nan done sa yo, ou ta dwe konsidere migrasyon pakèt!
  3. ekri kòd kote yo itilize yo Tou de и nouvo, Ak ansyen an kolòn. Koulye a, vèsyon app ou a 2.0.0
  4. li valè a nan kolòn nan surname, si se pa sa null, oswa soti nan last_name, si surname pa espesifye. Ou ka efase getLastName() soti nan kòd la, depi li pral pwodiksyon null lè w ap retounen aplikasyon w lan 3.0.0 до 2.0.0.

Si w ap itilize Spring Boot Flyway, de etap sa yo pral fèt pandan demaraj vèsyon an 2.0.0 aplikasyon yo. Si ou kouri zouti vèsyon baz done a manyèlman, w ap oblije fè de bagay diferan pou fè sa (premye mete ajou vèsyon an db manyèlman epi deplwaye nouvo aplikasyon an).

Li enpòtan. Sonje ke kolòn ki fèk kreye a PA TA DWE gen PA NIL. Si ou fè yon rollback, ansyen aplikasyon an pa konnen sou nouvo kolòn nan epi li pa pral enstale li pandan Insert. Men, si ou ajoute kontrent sa a ak db ou yo pral v2, sa pral mande pou mete valè nouvo kolòn nan. Ki ap mennen nan vyolasyon restriksyon yo.

Li enpòtan. Ou ta dwe retire metòd la getLastName(), paske nan vèsyon an 3.0.0 Pa gen okenn konsèp nan yon kolòn nan kòd la last_name. Sa vle di ke nil pral mete la. Ou ka kite metòd la epi ajoute chèk pou null, men yon solisyon pi bon ta dwe asire w ke nan lojik la getSurname() ou chwazi valè ki pa zewo ki kòrèk la.

Tès A/B

Sitiyasyon aktyèl la se ke nou gen yon vèsyon aplikasyon an 1.0.0, deplwaye sou pwodiksyon, ak baz done a nan v1. Nou bezwen deplwaye yon dezyèm egzanp aplikasyon vèsyon an 2.0.0ki pral mete ajou baz done a v2.

Etap:

  1. yon nouvo egzanp aplikasyon vèsyon an deplwaye 2.0.0ki mete ajou baz done a v2
  2. nan entre-temps la kèk demann yo te trete pa ka vèsyon 1.0.0
  3. aktyalizasyon a te reyisi epi ou gen plizyè ka kouri nan aplikasyon an vèsyon 1.0.0 и остальные версии 2.0.0. Tout moun kominike ak baz done a nan v2
  4. vèsyon 1.0.0 pa sèvi ak kolòn ti non nan baz done a, men vèsyon an 2.0.0 itilize. Yo pa entèfere youn ak lòt, epi pa ta dwe gen okenn erè.
  5. vèsyon 2.0.0 estoke done nan tou de ansyen ak nouvo kolòn, asire konpatibilite bak

Li enpòtan. Si ou gen nenpòt demann ki konte atik ki baze sou valè ki soti nan ansyen / nouvo kolòn nan, ou ta dwe sonje ke ou kounye a gen valè kopi (gen plis chans yo toujou ap emigre). Pa egzanp, si ou vle konte kantite itilizatè ki gen siyati (kèlkeswa sa yo rele kolòn nan) te kòmanse avèk lèt ​​la. A, Lè sa a, jiskaske migrasyon done yo fini (oldnew kolòn) ou ka gen done enkonsistan si ou mande yon nouvo kolòn.

Rollback aplikasyon

Koulye a, nou gen vèsyon aplikasyon an 2.0.0 ak baz done nan v2.

Etap:

  1. retounen aplikasyon w lan nan vèsyon an 1.0.0.
  2. vèsyon 1.0.0 pa sèvi ak yon kolòn nan baz done a surname, se konsa rollback a ta dwe gen siksè

DB chanje

Baz done a gen yon kolòn ki rele last_name.

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

Ajoute script surname.

Atansyon. Sonje ke ou PA KAPAB AJOUTE okenn kontrent NON NULL nan kolòn w ap ajoute a. Si ou rollback JAR la, ansyen vèsyon an pa pral gen okenn lide sou kolòn nan ajoute epi yo pral otomatikman mete li nan NULL. Si gen yon limit konsa, ansyen aplikasyon an pral tou senpleman kraze.

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

Kòd chanjman

Nou estoke done kòm last_name, ak nan surname. An menm tan nou li nan last_name, depi kolòn sa a se pi enpòtan an. Pandan pwosesis deplwaman an, kèk demann ka te trete pa yon egzanp aplikasyon ki poko mete ajou.

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

Etap 3: Retire last_name nan kòd la

App vèsyon: 3.0.0

DB vèsyon:v3

Kòmantè

Remak per.: Aparamman, nan atik orijinal la otè a erè kopye tèks la nan blòk sa a soti nan etap 2. Nan etap sa a, chanjman yo ta dwe fèt nan kòd aplikasyon an ki vize a retire fonksyonalite a ki sèvi ak kolòn nan. last_name.

Lè nou ajoute yon nouvo kolòn epi kopye sa ki ladan l yo, nou te kreye chanjman baz done konpatib bak. Epitou, si nou rollback JAR la oswa gen yon ansyen JAR kouri, li pa pral kraze pandan ekzekisyon.

Rollback aplikasyon

Kounye a nou gen vèsyon aplikasyon an 3.0.0 ak baz done v3. Version 3.0.0 pa sove done yo last_name. Sa vle di ke nan surname se enfòmasyon ki pi ajou yo estoke.

Etap:

  1. retounen aplikasyon w lan nan vèsyon an 2.0.0.
  2. vèsyon 2.0.0 itilize ak last_name и surname.
  3. vèsyon 2.0.0 pral pran surname, si li pa zewo, otreman -last_name

Chanjman nan baz done yo

Pa gen okenn chanjman estriktirèl nan baz done a. Se script sa a egzekite pou fè migrasyon final la nan ansyen done yo:

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

Kòd chanjman

Remak per.: Te deskripsyon an nan blòk sa a tou erè kopye pa otè a soti nan etap 2. An akò ak lojik la nan atik la, chanjman nan kòd la nan etap sa a ta dwe vize a retire nan li eleman ki travay ak kolòn nan. last_name.

Nou estoke done kòm last_name, ak nan surname. Anplis de sa, nou li nan kolòn nan last_name, depi li se pi enpòtan an. Pandan pwosesis deplwaman an, kèk demann ka trete pa yon egzanp ki poko modènize.

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

Etap 4: Retire last_name nan baz done a

App vèsyon: 4.0.0

DB vèsyon: v4

Kòmantè

Akòz lefèt ke kòd vèsyon an 3.0.0 pa t sèvi ak kolòn nan last_name, pa gen anyen move ki pral rive pandan ekzekisyon si nou woule tounen nan 3.0.0 apre yo fin retire yon kolòn nan baz done a.

Script ekzekisyon journaux

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 chanje

Relativman v3 nou jis retire kolòn nan last_name epi ajoute restriksyon ki manke yo.

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

Kòd chanjman

Pa gen okenn chanjman nan kòd la.

Sòti

Nou aplike avèk siksè yon chanjman non kolòn enkonpatib bak lè nou fè plizyè deplwaman konpatib bak. Anba a se yon rezime aksyon yo fè:

  1. deplwaman vèsyon aplikasyon an 1.0.0 с v1 chema baz done (non kolòn = last_name)
  2. deplwaman vèsyon aplikasyon an 2.0.0, ki estoke done nan last_name и surname. Aplikasyon an li soti nan last_name. Baz done a se nan vèsyon v2ki gen kolòn tankou last_nameAk surname. surname se yon kopi last_name. (NÒT: Kolòn sa a pa dwe genyen yon kontrent ki pa nil)
  3. deplwaman vèsyon aplikasyon an 3.0.0, ki sèlman estoke done nan surname epi li soti nan ti non. Kòm pou baz done a, dènye migrasyon an ap fèt last_name в surname. Epitou yon limit PA NIL retire nan last_name. Baz done a se kounye a nan vèsyon v3
  4. deplwaman vèsyon aplikasyon an 4.0.0 - pa gen okenn chanjman ki fèt nan kòd la. Deplwaman baz done v4, ki retire last_name. Isit la ou ka ajoute nenpòt ki kontrent ki manke nan baz done a.

Lè w swiv apwòch sa a, ou ka toujou woule tounen yon vèsyon san kraze konpatibilite baz done/aplikasyon.

Kòd

Tout kòd yo itilize nan atik sa a disponib nan Github. Anba a se deskripsyon adisyonèl.

Pwojè

Apre klonaj repozitwa a, ou pral wè estrikti katab sa a.

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

Scripts

Ou ka kouri scripts ki dekri nan scripts ki pi ba yo, ki pral demontre chanjman ki konpatib ak enkonpatib nan baz done a.

ka a ak chanjman konpatib bak, kouri:

./scripts/scenario_backward_compatible.sh

Epi yo wè ka ak chanjman bak enkonpatib, kouri:

./scripts/scenario_backward_incompatible.sh

Spring Boot Sample Flyway

Tout egzanp yo pran nan Spring Boot Sample Flyway.

Ou ka pran yon gade nan http://localhost:8080/flyway, gen yon lis scripts.

Egzanp sa a gen ladan tou konsole H2 a (at http://localhost:8080/h2-console) pou ou ka wè estati baz done a (default jdbc URL se jdbc:h2:mem:testdb).

Anplis de sa

Epitou li lòt atik sou blog nou an:

Sous: www.habr.com

Add nouvo kòmantè