Zero Downtime Deployment thiab Databases

Zero Downtime Deployment thiab Databases

Kab lus no piav qhia meej txog yuav ua li cas los daws cov teeb meem database compatibility hauv kev xa tawm. Peb yuav qhia koj txog dab tsi tuaj yeem tshwm sim rau koj daim ntawv thov kev tsim khoom yog tias koj sim siv yam tsis muaj kev npaj ua ntej. Peb mam li mus dhau ntawm daim ntawv thov lub voj voog theem uas yuav tsum muaj xoom downtime (kwv yees. txoj kab: ntxiv - xoom downtime). Qhov tshwm sim ntawm peb cov haujlwm yuav yog los siv cov ntaub ntawv rov qab-tsis sib haum xeeb hloov hauv qhov rov qab-tshaj tawm.

Yog tias koj xav nkag siab cov lej piv txwv los ntawm kab lus, koj tuaj yeem nrhiav lawv ntawm GitHub.

Taw qhia

Zero downtime deployment

Dab tsi yog mystical xoom downtime deployment? Koj tuaj yeem hais tias qhov no yog thaum koj daim ntawv thov raug xa mus rau hauv txoj hauv kev uas koj tuaj yeem ua tiav qhov tshiab ntawm daim ntawv thov rau kev tsim khoom, thaum tus neeg siv tsis pom nws qhov tsis muaj. Los ntawm tus neeg siv thiab lub tuam txhab kev xav, qhov no yog qhov zoo tshaj plaws kev xa tawm scenario vim tias nws tso cai rau cov yam ntxwv tshiab los qhia thiab kab laum kom kho yam tsis muaj kev cuam tshuam.

Yuav ua li cas kom ua tiav qhov no? Muaj ntau txoj hauv kev, ntawm no yog ib qho ntawm lawv:

  • xa tawm version No. 1 ntawm koj qhov kev pabcuam
  • ua ib tug database migration
  • Tso tawm version # 2 ntawm koj qhov kev pabcuam nyob rau hauv parallel nrog version # 1
  • sai li sai tau thaum koj pom tias version No. 2 ua haujlwm raws li nws yuav tsum, tshem tawm version No. 1
  • ua tiav!

Yooj yim, tsis yog nws? Hmoov tsis, nws tsis yog qhov yooj yim, thiab peb yuav saib qhov ntawd hauv kev nthuav dav tom qab. Tam sim no cia saib lwm txoj kev xa tawm ncaj ncees - xiav ntsuab xa tawm.

Koj puas tau hnov ​​dua xiav ntsuab deployment? Huab Foundry ua qhov no yooj yim heev. Cia li saib kab lus no, qhov twg peb piav qhov no nyob rau hauv kom meej ntxiv. Yuav kom luv luv, cia peb nco ntsoov koj yuav ua li cas ua xiav ntsuab xa mus:

  • xyuas kom meej tias ob daim ntawv luam ntawm koj cov cai ntau lawm ("xiav" thiab "ntsuab") ua haujlwm;
  • direct tag nrho cov tsheb mus rau xiav ib puag ncig, i.e. yog li ntawd cov khoom URLs taw tes rau ntawd;
  • xa thiab sim txhua daim ntawv thov hloov pauv hauv ib puag ncig ntsuab;
  • hloov urls los ntawm xiav rau ntsuab ib puag ncig

Blue ntsuab xa tawm yog ib txoj hauv kev uas tso cai rau koj kom yooj yim qhia cov yam ntxwv tshiab yam tsis muaj kev txhawj xeeb txog kev rhuav tshem ntau lawm. Qhov no yog vim qhov tseeb tias txawm tias muaj ib yam dab tsi tshwm sim, koj tuaj yeem yooj yim yob rov qab mus rau qhov chaw yav dhau los los ntawm kev yooj yim "flicking hloov."

Tom qab nyeem tag nrho cov saum toj no, koj tuaj yeem nug cov lus nug: Dab tsi yog xoom downtime yuav ua li cas nrog Blue ntsuab xa tawm?

Zoo, lawv muaj ntau yam sib xws, txij li kev tswj hwm ob daim ntawv theej ntawm tib ib puag ncig yuav tsum tau siv zog ob npaug los tswj lawv. Qhov no yog vim li cas qee pawg neeg thov Martin Fowler, ua raws li kev hloov pauv ntawm qhov kev qhia no:

Lwm qhov kev xaiv yog siv tib lub database, tsim xiav-ntsuab keyboards rau lub vev xaib thiab cov txheej txheem sau npe. Nyob rau hauv txoj kev no, cov ntaub ntawv feem ntau tuaj yeem yog qhov teeb meem, tshwj xeeb tshaj yog thaum koj xav tau hloov nws cov schema los txhawb cov software tshiab.

Thiab ntawm no peb tuaj rau qhov teeb meem tseem ceeb hauv kab lus no. Database. Cia wb mus saib lwm nqe lus no.

ua ib tug database migration.

Tam sim no koj yuav tsum nug koj tus kheej cov lus nug - yuav ua li cas yog tias cov ntaub ntawv hloov pauv tsis rov qab sib haum? Yuav tsis yog kuv thawj version ntawm lub app so? Qhov tseeb, qhov no yog qhov yuav tshwm sim ...

Yog li, txawm tias cov txiaj ntsig loj ntawm xoom downtime / xiav ntsuab xa tawm, cov tuam txhab nyiam ua raws li cov txheej txheem hauv qab no muaj kev nyab xeeb dua rau kev xa lawv cov ntawv thov:

  • npaj ib pob nrog ib tug tshiab version ntawm daim ntawv thov
  • kaw ib daim ntawv thov khiav
  • khiav scripts mus migrate lub database
  • deploy thiab tso ib tug tshiab version ntawm daim ntawv thov

Hauv tsab xov xwm no, peb yuav piav qhia yuav ua li cas koj tuaj yeem ua haujlwm nrog koj cov ntaub ntawv thiab cov lej kom tau txais txiaj ntsig zoo ntawm xoom downtime xa tawm.

Database teeb meem

Yog tias koj muaj daim ntawv thov tsis muaj lub xeev uas tsis khaws cov ntaub ntawv hauv cov ntaub ntawv, koj tuaj yeem tau txais xoom downtime xa tawm tam sim ntawd. Hmoov tsis zoo, feem ntau cov software xav tau khaws cov ntaub ntawv rau qhov chaw. Qhov no yog vim li cas koj yuav tsum xav txog ob zaug ua ntej yuav hloov pauv hauv Circuit Court. Ua ntej peb nkag mus rau hauv cov ntsiab lus ntawm yuav ua li cas hloov lub schema thiaj li tsis muaj-downtime deployment yog ua tau, cia peb xub tsom mus rau lub versioning schema.

Versioning tswvyim

Hauv kab lus no peb yuav siv Flyway raws li ib tug version tswj cuab tam (kwv yees. Kev txhais lus: peb tab tom tham txog database migrations). Lawm, peb kuj tseem yuav sau daim ntawv thov Caij Nplooj Ntoos Hlav uas muaj kev txhawb nqa Flyway thiab yuav ua schema tsiv teb tsaws thaum teeb tsa cov ntsiab lus ntawm daim ntawv thov. Thaum siv Flyway, koj tuaj yeem khaws cov ntawv tsiv teb tsaws chaw hauv koj qhov project folder (los ntawm lub neej ntawd hauv classpath:db/migration). Ntawm no koj tuaj yeem pom ib qho piv txwv ntawm cov ntaub ntawv tsiv teb tsaws chaw

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

Hauv qhov piv txwv no peb pom 4 cov ntawv tsiv teb tsaws chaw uas, yog tias tsis ua tiav yav dhau los, yuav raug tua ib qho tom qab lwm qhov thaum daim ntawv thov pib. Cia peb saib ib qho ntawm cov ntaub ntawv (V1__init.sql) ua piv txwv.

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

Txhua yam zoo kawg nkaus rau tus kheej piav qhia: koj tuaj yeem siv SQL los txhais seb koj cov ntaub ntawv yuav tsum tau hloov pauv li cas. Yog xav paub ntxiv txog Spring Boot thiab Flyway, mus saib Spring Boot Docs.

Los ntawm kev siv lub cuab yeej tswj hwm nrog Spring Boot, koj tau txais 2 cov txiaj ntsig loj:

  • koj cais cov ntaub ntawv hloov pauv ntawm cov lej hloov pauv
  • Database migration tshwm sim nrog rau kev nthuav tawm ntawm koj daim ntawv thov, i.e. koj cov txheej txheem xa tawm yog yooj yim

Troubleshooting teeb meem database

Hauv seem tom ntej ntawm tsab xov xwm, peb yuav tsom mus saib ob txoj hauv kev rau kev hloov pauv cov ntaub ntawv.

  • rov qab incompatibility
  • rov qab compatibility

Thawj qhov yuav raug suav hais tias yog lus ceeb toom tias koj yuav tsum tsis txhob ua xoom downtime deployment yam tsis muaj kev npaj ua ntej... Qhov thib ob yog ib qho kev daws teeb meem uas koj tuaj yeem ua tiav kev xa mus yam tsis muaj downtime thiab tib lub sijhawm tswj kev rov qab sib raug zoo.

Peb qhov project peb yuav ua haujlwm yuav yog qhov yooj yim Spring Boot Flyway daim ntawv thov uas muaj Person с first_name и last_name hauv database (kwv yees. txhais: Person yog lub rooj thiab first_name и last_name - Cov no yog cov teb hauv nws). Peb xav hloov npe last_name в surname.

Kev xav

Ua ntej peb nkag mus rau hauv cov ntsiab lus, muaj ob peb qhov kev xav uas peb yuav tsum tau ua rau peb cov ntawv thov. Cov txiaj ntsig tseem ceeb uas peb xav ua kom tiav yuav yog txheej txheem yooj yim.

Daim ntawv. Kev lag luam PRO-TIP. Cov txheej txheem yooj yim tuaj yeem txuag koj nyiaj ntau ntawm kev txhawb nqa (ntau tus neeg koj tau ua haujlwm rau koj lub tuam txhab, nyiaj ntau koj tuaj yeem txuag tau)!

Tsis tas yuav rollback lub database

Qhov no ua kom yooj yim rau cov txheej txheem xa tawm (qee cov ntaub ntawv rollbacks yuav luag tsis yooj yim sua, xws li tshem tawm rollback). Peb xav thim rov qab tsuas yog daim ntawv thov. Txoj kev no, txawm tias koj muaj cov ntaub ntawv sib txawv (piv txwv li, SQL thiab NoSQL), koj cov kav dej xa mus yuav zoo ib yam.

Nws yuav tsum IB TUG TIAS tuaj yeem thim rov qab daim ntawv thov ib version rov qab (tsis muaj ntxiv)

Rollback yuav tsum tsuas yog ua thaum tsim nyog. Yog hais tias muaj kab mob nyob rau hauv lub tam sim no version uas tsis yooj yim kho, peb yuav tsum tau rov qab mus rau qhov tseeb ua hauj lwm version. Peb xav tias qhov kev ua haujlwm tshiab kawg no yog qhov dhau los. Kev tuav cov cai thiab cov ntaub ntawv sib raug zoo rau ntau tshaj ib qho kev nthuav tawm yuav nyuaj heev thiab kim.

Daim ntawv. Rau kev nyeem tau ntau dua, hauv kab lus no peb yuav hloov pauv qhov loj ntawm daim ntawv thov.

Kauj Ruam 1: Pib Lub Xeev

App version: 1.0.0
DB version: v1

saib

Qhov no yuav yog thawj lub xeev ntawm daim ntawv thov.

Cov ntaub ntawv hloov pauv

DB muaj 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 hloov

Daim ntawv thov khaws neeg cov ntaub ntawv hauv 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
                + "]";
    }
}

Backwards incompatible kem renaming

Cia peb saib ib qho piv txwv ntawm yuav ua li cas hloov lub npe kab:

Ua tib zoo mloog. Cov piv txwv hauv qab no yuav txhob txwm ua txhaum tej yam. Peb qhia qhov no los qhia qhov teeb meem ntawm database compatibility.

App version: 2.0.0.BAD

DB version: v2bad

saib

Cov kev hloov pauv tam sim no TSIS tso cai rau peb khiav ob qhov xwm txheej (qub thiab tshiab) tib lub sijhawm. Yog li, xoom downtime xa mus yuav nyuaj rau kev ua tiav (yog tias qhov kev xav tau coj mus rau hauv tus account, nws yog qhov ua tsis tau).

Kev xeem A/B

Qhov xwm txheej tam sim no yog tias peb muaj daim ntawv thov version 1.0.0, deployed nyob rau hauv ntau lawm, thiab database v1. Peb yuav tsum xa ib qho piv txwv thib ob ntawm daim ntawv thov, version 2.0.0.BAD, thiab hloov kho cov ntaub ntawv rau v2bad.

Cov kauj ruam:

  1. ib qho piv txwv tshiab ntawm daim ntawv thov version raug xa mus 2.0.0.BADuas hloov tshiab database rau v2bad
  2. hauv cov chaw khaws ntaub ntawv v2bad kem last_name tsis muaj lawm - nws tau hloov mus rau surname
  3. Cov ntaub ntawv thiab daim ntawv thov hloov tshiab tau ua tiav thiab qee qhov ua haujlwm tau ua haujlwm 1.0.0,lwm - in 2.0.0.BAD. Txhua yam yog txuas nrog lub database v2bad
  4. tag nrho cov piv txwv ntawm lub version 1.0.0 yuav pib pov qhov yuam kev vim lawv yuav sim ntxig cov ntaub ntawv rau hauv kab last_nameleej twg tsis muaj lawm
  5. tag nrho cov piv txwv ntawm lub version 2.0.0.BAD yuav ua haujlwm yam tsis muaj teeb meem

Raws li koj tuaj yeem pom, yog tias peb ua qhov hloov pauv tsis sib xws rau cov ntaub ntawv thiab daim ntawv thov, kev sim A / B tsis tuaj yeem.

Daim ntawv thov rov qab

Cia peb xav tias tom qab sim ua A / B xa tawm (kwv yees. per.: tus sau tej zaum txhais tau tias kev xeem A/B ntawm no) peb txiav txim siab tias peb yuav tsum tau rov qab daim ntawv thov mus rau lub version 1.0.0. Cia peb hais tias peb tsis xav rollback lub database.

Cov kauj ruam:

  1. peb tso tseg cov ntawv thov version piv txwv 2.0.0.BAD
  2. lub database tseem v2bad
  3. txij li lub version 1.0.0 tsis nkag siab nws yog dab tsi surname, peb yuav pom qhov yuam kev
  4. ntuj txiag teb tsaus tau tawg lawm, peb rov qab mus tsis tau lawm

Raws li koj tuaj yeem pom, yog tias peb ua qhov hloov pauv tsis sib xws rau cov ntaub ntawv thiab daim ntawv thov, peb tsis tuaj yeem thim rov qab mus rau yav dhau los version.

Script execution logs

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

Cov ntaub ntawv hloov pauv

Migration script uas renames last_name в surname

Source Flyway tsab ntawv:

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 uas renames last_name.

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

Code hloov

Peb tau hloov lub npe teb lastName rau surname.

Renaming ib kem nyob rau hauv ib tug rov qab-tshaj txoj kev

Nov yog qhov xwm txheej uas peb yuav ntsib. Peb yuav tsum ua kom rov qab hloov tsis tau. Peb twb tau ua pov thawj tias rau xoom-downtime deployment, peb yuav tsum tsis txhob tsuas siv database migration yam tsis muaj cov kauj ruam ntxiv. Hauv seem ntawm tsab xov xwm no, peb yuav ua 3 kev xa tawm ntawm daim ntawv thov nrog rau cov ntaub ntawv tsiv teb tsaws chaw kom ua tiav cov txiaj ntsig xav tau thaum tswj kev rov qab sib raug zoo.

Daim ntawv. Nco qab tias peb muaj ib tug version database v1. Nws muaj kab first_name и last_name. Peb yuav tsum hloov last_name rau surname. Peb kuj muaj app version 1.0.0, uas tseem tsis tau siv surname.

Kauj ruam 2: Ntxiv lub npe

App version: 2.0.0
DB version: v2

saib

Los ntawm kev ntxiv ib kem tshiab thiab luam nws cov ntsiab lus, peb tsim rov qab tau tshaj cov ntaub ntawv hloov pauv. Tib lub sijhawm, yog tias peb thim rov qab JAR lossis muaj JAR qub khiav, nws yuav tsis tawg thaum ua tiav.

Peb tab tom dov tawm ib tug tshiab version

Cov kauj ruam:

  1. ua ib tug database migration los tsim ib kab tshiab surname. Tam sim no koj DB version v2
  2. luam cov ntaub ntawv los ntawm last_name в surname. Tshem nyiajtias yog tias koj muaj ntau cov ntaub ntawv no, koj yuav tsum xav txog batch migration!
  3. sau tus lej uas lawv siv ob leeg и tshiabthiab cov laus kem. Tam sim no koj app version 2.0.0
  4. nyeem tus nqi ntawm kab surname, yog tsis yog null, los ntawm last_nameyog surname tsis tau teev tseg. Koj tuaj yeem rho tawm getLastName() los ntawm code, vim nws yuav tso zis null thaum dov rov qab koj daim ntawv thov los ntawm 3.0.0 rau 2.0.0.

Yog tias koj siv Spring Boot Flyway, ob kauj ruam no yuav raug ua thaum pib ua haujlwm 2.0.0 daim ntawv thov. Yog tias koj khiav lub database versioning tool manually, koj yuav tau ua ob yam sib txawv los ua qhov no (thawj hloov tshiab db version manually thiab tom qab ntawd xa daim ntawv thov tshiab).

Nws tseem ceeb heev. Nco ntsoov tias kab ntawv tshiab tsim TSIS MUAJ yuav tsum TSIS TXHOB. Yog tias koj ua rollback, daim ntawv thov qub tsis paub txog kab tshiab thiab yuav tsis nruab nws thaum lub sijhawm Insert. Tab sis yog tias koj ntxiv qhov txwv no thiab koj db yuav yog v2, qhov no yuav xav tau kev teeb tsa tus nqi ntawm kab ntawv tshiab. Uas yuav ua rau ua txhaum txoj cai txwv.

Nws tseem ceeb heev. Koj yuav tsum tshem tawm txoj kev getLastName(), vim nyob rau hauv lub version 3.0.0 Tsis muaj lub tswv yim ntawm kab hauv kab last_name. Qhov no txhais tau hais tias null yuav raug teem rau ntawd. Koj tuaj yeem tawm ntawm txoj kev thiab ntxiv cov tshev rau null, tab sis ib qho kev daws teeb meem zoo dua yuav ua kom paub tseeb tias nyob rau hauv lub logic getSurname() koj xaiv qhov tseeb tsis yog xoom tus nqi.

Kev xeem A/B

Qhov xwm txheej tam sim no yog tias peb muaj daim ntawv thov version 1.0.0, deployed nyob rau hauv ntau lawm, thiab lub database nyob rau hauv v1. Peb yuav tsum xa ib qho piv txwv thib ob ntawm daim ntawv thov version 2.0.0uas yuav hloov kho cov ntaub ntawv rau v2.

Cov kauj ruam:

  1. ib qho piv txwv tshiab ntawm daim ntawv thov version raug xa mus 2.0.0uas hloov tshiab database rau v2
  2. nyob rau hauv lub sijhawm no qee qhov kev thov tau ua tiav los ntawm qhov piv txwv version 1.0.0
  3. qhov hloov tshiab tau ua tiav thiab koj muaj ntau qhov kev khiav haujlwm ntawm daim ntawv thov version 1.0.0 thiab lwm yam versions 2.0.0. Txhua tus neeg sib txuas lus nrog cov database hauv v2
  4. version 1.0.0 tsis siv lub xeem kab nyob rau hauv lub database, tab sis lub version 2.0.0 siv. Lawv tsis cuam tshuam rau ib leeg, thiab yuav tsum tsis muaj qhov yuam kev.
  5. version 2.0.0 khaws cov ntaub ntawv nyob rau hauv ob lub qub thiab tshiab kem, kom ntseeg tau rov qab compatibility

Nws tseem ceeb heev. Yog tias koj muaj cov lus nug uas suav cov khoom raws li qhov muaj nuj nqis los ntawm kab qub / tshiab, koj yuav tsum nco ntsoov tias tam sim no koj muaj qhov sib npaug (feem ntau lawv tseem tab tom tsiv). Piv txwv li, yog tias koj xav suav tus naj npawb ntawm cov neeg siv uas nws lub xeem (txawm lub npe hu ua ke) pib nrog tsab ntawv A, ces kom txog thaum cov ntaub ntawv tsiv teb tsaws tiav (oldnew kem) tej zaum koj yuav muaj cov ntaub ntawv tsis sib haum yog tias koj nug ib kab tshiab.

Daim ntawv thov rov qab

Tam sim no peb muaj app version 2.0.0 thiab database hauv v2.

Cov kauj ruam:

  1. yob rov qab koj daim ntawv thov mus rau version 1.0.0.
  2. version 1.0.0 tsis siv kab ke hauv database surname, yog li qhov rollback yuav tsum ua tiav

DB pauv

Lub database muaj ib kab npe last_name.

Flyway source tsab ntawv:

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

Ntxiv tsab ntawv surname.

Ua tib zoo mloog. Nco ntsoov tias koj tsis tuaj yeem ntxiv ib qho TSIS NULL txwv rau kab koj ntxiv. Yog tias koj rollback lub JAR, cov qub version yuav tsis muaj lub tswv yim txog cov kab ntxiv thiab yuav cia li muab tso rau NULL. Yog tias muaj qhov txwv zoo li no, daim ntawv thov qub yuav tsuas tawg.

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

Peb khaws cov ntaub ntawv raws li last_name, thiab nyob rau hauv surname. Tib lub sijhawm peb nyeem los ntawm last_name, txij li kab ntawv no yog qhov tseem ceeb tshaj plaws. Thaum lub sij hawm xa mus, qee qhov kev thov yuav raug ua tiav los ntawm cov ntawv thov piv txwv uas tseem tsis tau hloov kho.

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

Kauj ruam 3: Tshem tawm lub xeem_name los ntawm tus lej

App version: 3.0.0

DB version:v3

saib

Nco tseg per .: Thaj, nyob rau hauv thawj tsab xov xwm tus sau yuam kev luam cov ntawv ntawm qhov thaiv no los ntawm kauj ruam 2. Nyob rau hauv cov kauj ruam no, yuav tsum tau hloov nyob rau hauv daim ntawv thov code aimed ntawm tshem tawm cov functionality uas siv lub kem. last_name.

Los ntawm kev ntxiv ib kab tshiab thiab luam tawm nws cov ntsiab lus, peb tsim rov qab hloov pauv cov ntaub ntawv sib xws. Tsis tas li, yog tias peb thim rov qab JAR lossis muaj JAR qub khiav, nws yuav tsis tawg thaum ua tiav.

Daim ntawv thov rov qab

Tam sim no peb muaj app version 3.0.0 thiab database v3. Version 3.0.0 tsis txuag cov ntaub ntawv rau last_name. Qhov no txhais tau tias hauv surname cov ntaub ntawv tshiab tshaj plaws yog khaws cia.

Cov kauj ruam:

  1. yob rov qab koj daim ntawv thov mus rau version 2.0.0.
  2. version 2.0.0 siv thiab last_name и surname.
  3. version 2.0.0 yuav coj surname, yog tias nws tsis yog xoom, txwv tsis pub -last_name

Cov ntaub ntawv hloov pauv

Tsis muaj cov qauv kev hloov pauv hauv cov ntaub ntawv. Cov ntawv hauv qab no raug tua los ua qhov kawg ntawm kev tsiv teb tsaws ntawm cov ntaub ntawv qub:

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

Nco tseg per .: Cov lus piav qhia ntawm qhov thaiv no kuj tau ua yuam kev los ntawm tus sau los ntawm kauj ruam 2. Raws li lub logic ntawm tsab xov xwm, kev hloov pauv hauv cov cai ntawm cov kauj ruam no yuav tsum tau tsom rau tshem tawm ntawm nws cov ntsiab lus uas ua haujlwm nrog kab ntawv. last_name.

Peb khaws cov ntaub ntawv raws li last_name, thiab nyob rau hauv surname. Tsis tas li ntawd, peb nyeem los ntawm kab ntawv last_name, vim nws yog qhov tseem ceeb tshaj plaws. Thaum lub sijhawm xa tawm, qee qhov kev thov tuaj yeem ua tiav los ntawm qhov piv txwv uas tseem tsis tau hloov kho.

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

Kauj ruam 4: Tshem tawm lub xeem_name los ntawm lub database

App version: 4.0.0

DB version: v4

saib

Vim lub fact tias lub version code 3.0.0 tsis tau siv kab last_name, tsis muaj dab tsi phem yuav tshwm sim thaum ua tiav yog tias peb rov qab mus rau 3.0.0 tom qab tshem ib kab los ntawm lub database.

Script execution logs

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 pauv

Txheeb ze v3 peb tsuas yog tshem cov kab last_name thiab ntxiv cov kev txwv uas ploj lawm.

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

Tsis muaj kev hloov pauv rau tus lej.

xaus

Peb tau ua tiav qhov rov qab-tsis sib haum lub npe hloov pauv los ntawm kev ua ntau qhov rov qab-tshaj xa mus. Hauv qab no yog cov ntsiab lus ntawm cov kev ua tau ua:

  1. deployment ntawm daim ntawv thov version 1.0.0 с v1 database schema (kem npe = last_name)
  2. deployment ntawm daim ntawv thov version 2.0.0, uas khaws cov ntaub ntawv hauv last_name и surname. Daim ntawv thov nyeem los ntawm last_name. Lub database yog nyob rau hauv version v2muaj kab zoo li last_name, thiab surname. surname yog ib daim last_name. (CEEB TOOM: Cov kab no yuav tsum tsis muaj qhov txwv tsis pub muaj)
  3. deployment ntawm daim ntawv thov version 3.0.0, uas tsuas yog khaws cov ntaub ntawv hauv surname thiab nyeem los ntawm lub npe. Raws li rau lub database, qhov kawg migration yog tshwm sim last_name в surname. Kuj muaj kev txwv TSIS TXHOB thim tawm ntawm last_name. Lub database tam sim no nyob rau hauv version v3
  4. deployment ntawm daim ntawv thov version 4.0.0 - tsis muaj kev hloov pauv rau tus lej. Database deployment v4, uas tshem tawm last_name. Ntawm no koj tuaj yeem ntxiv cov kev txwv uas ploj lawm rau hauv database.

Los ntawm kev ua raws li txoj hauv kev no, koj tuaj yeem thim rov qab ib qho version yam tsis muaj kev cuam tshuam cov ntaub ntawv / daim ntawv thov kev sib raug zoo.

code

Txhua tus lej siv hauv kab lus no muaj nyob ntawm github. Hauv qab no yog cov lus piav qhia ntxiv.

Tej Hauj Lwm

Tom qab cloning lub repository, koj yuav pom cov qauv hauv qab no.

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

Sau ntawv

Koj tuaj yeem khiav cov ntawv sau uas tau piav qhia hauv cov ntawv sau hauv qab no, uas yuav ua rau pom rov qab-tshaj tawm thiab hloov pauv tsis haum rau cov ntaub ntawv.

Kom pom rooj plaub nrog rov qab tau hloov pauv, khiav:

./scripts/scenario_backward_compatible.sh

Thiab pom rooj plaub nrog rov qab incompatible hloov, khiav:

./scripts/scenario_backward_incompatible.sh

Spring Boot Sample Flyway

Tag nrho cov piv txwv raug coj los ntawm Spring Boot Sample Flyway.

Koj tuaj yeem saib xyuas http://localhost:8080/flyway, muaj ib daim ntawv teev cov ntawv sau.

Qhov piv txwv no kuj suav nrog H2 console (ntawm http://localhost:8080/h2-console) yog li koj tuaj yeem saib cov xwm txheej database (default jdbc URL yog jdbc:h2:mem:testdb).

ntxiv

Kuj nyeem lwm cov ntawv hauv peb blog:

Tau qhov twg los: www.hab.com

Ntxiv ib saib