Odo Downtime imuṣiṣẹ ati Databases

Odo Downtime imuṣiṣẹ ati Databases

Nkan yii ṣe alaye ni apejuwe bi o ṣe le yanju awọn ọran ibaramu data ni imuṣiṣẹ. A yoo sọ fun ọ kini o le ṣẹlẹ si awọn ohun elo iṣelọpọ rẹ ti o ba gbiyanju lati ran lọ laisi igbaradi alakoko. A yoo lọ nipasẹ awọn ipele igbesi aye ohun elo ti o nilo lati ni akoko idaduro odo (isunmọ. ona: siwaju - odo downtime). Abajade ti awọn iṣẹ wa yoo jẹ lati lo iyipada data data sẹhin-aiṣedeede ni ọna ibaramu sẹhin.

Ti o ba fẹ lati ni oye awọn apẹẹrẹ koodu lati nkan naa, o le rii wọn ni GitHub.

Ifihan

Odo downtime imuṣiṣẹ

Ohun ti a mystical odo downtime imuṣiṣẹ? O le sọ eyi ni nigbati ohun elo rẹ ti wa ni imuṣiṣẹ ni iru ọna ti o le ṣe agbekalẹ ẹya tuntun ti ohun elo naa ni aṣeyọri si iṣelọpọ, lakoko ti olumulo ko ṣe akiyesi wiwa rẹ. Lati wiwo olumulo ati ile-iṣẹ, eyi ni oju iṣẹlẹ imuṣiṣẹ ti o dara julọ nitori pe o gba awọn ẹya tuntun laaye lati ṣafihan ati awọn idun lati wa titi laisi idalọwọduro.

Bawo ni lati ṣaṣeyọri eyi? Awọn ọna pupọ lo wa, eyi ni ọkan ninu wọn:

  • ran awọn version No.. 1 ti iṣẹ rẹ
  • ṣe a database ijira
  • Mu ẹya #2 ti iṣẹ rẹ ṣiṣẹ ni afiwe pẹlu ẹya #1
  • ni kete ti o ba rii pe ẹya No.. 2 ṣiṣẹ bi o ti yẹ, yọ ẹya No
  • setan!

Rọrun, ṣe kii ṣe bẹ? Laanu, kii ṣe pe o rọrun, ati pe a yoo wo iyẹn ni awọn alaye nigbamii. Bayi jẹ ki a ṣayẹwo ilana imuṣiṣẹ ti o wọpọ miiran - blue green deployment .

Nje o ti gbo bulu alawọ ewe imuṣiṣẹ? Cloud Foundry jẹ ki eyi rọrun pupọ. Kan wo Arokọ yi, nibiti a ti ṣe apejuwe eyi ni awọn alaye diẹ sii. Lati ṣe akopọ ni ṣoki, jẹ ki a leti ọ bi o ṣe le ṣe imuṣiṣẹ alawọ ewe buluu:

  • rii daju pe awọn ẹda meji ti koodu iṣelọpọ rẹ (“bulu” ati “alawọ ewe”) ṣiṣẹ;
  • taara gbogbo awọn ijabọ si agbegbe buluu, i.e. ki awọn URL iṣelọpọ ntoka nibẹ;
  • gbejade ati idanwo gbogbo awọn ayipada ohun elo ni agbegbe alawọ ewe;
  • yipada awọn url lati buluu si agbegbe alawọ ewe

Imuṣiṣẹ alawọ ewe buluu jẹ ọna ti o fun ọ laaye lati ṣafihan awọn ẹya tuntun ni irọrun laisi aibalẹ nipa fifọ iṣelọpọ. Eyi jẹ nitori otitọ pe paapaa ti nkan kan ba ṣẹlẹ, o le ni rọọrun yi pada si agbegbe ti tẹlẹ nipa “fifọ kan yipada.”

Lẹhin kika gbogbo awọn ti o wa loke, o le beere ibeere naa: Kini akoko idaduro odo ni lati ṣe pẹlu imuṣiṣẹ alawọ ewe Blue?

Ó dára, wọ́n ní ọ̀pọ̀ nǹkan ní ìṣọ̀kan, níwọ̀n bí pípa ẹ̀dà méjì àyíká kan náà mọ́ sẹ́yìn ń béèrè ìsapá ìlọ́po méjì láti bójú tó wọn. Eyi ni idi ti diẹ ninu awọn ẹgbẹ sọ Martin Fowler, tẹle awọn iyatọ ti ọna yii:

Aṣayan miiran ni lati lo ibi ipamọ data kanna, ṣiṣẹda awọn iyipada alawọ-bulu fun wẹẹbu ati awọn ipele agbegbe. Ni ọna yii, ibi ipamọ data le jẹ iṣoro nigbagbogbo, paapaa nigbati o nilo lati yi eto rẹ pada lati ṣe atilẹyin ẹya tuntun ti sọfitiwia naa.

Ati pe nibi a wa si iṣoro akọkọ ni nkan yii. Aaye data. Ẹ jẹ́ ká tún wo gbólóhùn yìí.

ṣe a database ijira.

Bayi o ni lati beere ararẹ ibeere naa - kini ti iyipada data ko ba ni ibaramu sẹhin? Njẹ ẹya akọkọ mi ti app ko ni fọ bi? Ni otitọ, eyi ni pato ohun ti yoo ṣẹlẹ ...

Nitorinaa, paapaa laibikita awọn anfani nla ti imuṣiṣẹ odo downtime / alawọ ewe alawọ ewe, awọn ile-iṣẹ ṣọ lati tẹle ilana ailewu atẹle fun gbigbe awọn ohun elo wọn:

  • mura package pẹlu ẹya tuntun ti ohun elo
  • pa ohun elo nṣiṣẹ
  • ṣiṣe awọn iwe afọwọkọ lati jade ni database
  • ran lọ ki o si ṣe ifilọlẹ ẹya tuntun ti ohun elo

Ninu nkan yii, a yoo ṣe alaye bi o ṣe le ṣiṣẹ pẹlu data data rẹ ati koodu lati lo anfani ti imuṣiṣẹ akoko igbaduro odo.

Database oran

Ti o ba ni ohun elo ti ko ni ipinlẹ ti ko tọju data eyikeyi sinu ibi ipamọ data, o le gba imuṣiṣẹ akoko idaduro odo odo lẹsẹkẹsẹ. Laanu, ọpọlọpọ sọfitiwia nilo lati tọju data ni ibikan. Eyi ni idi ti o yẹ ki o ronu lẹẹmeji ṣaaju ṣiṣe eyikeyi awọn ayipada si Circuit. Ṣaaju ki a to wọle si awọn alaye ti bii o ṣe le yi ero-ọrọ naa pada ki imuṣiṣẹ akoko-akoko ko ṣee ṣe, jẹ ki a kọkọ dojukọ lori ero ti ikede naa.

Ilana ti ikede

Ninu nkan yii a yoo lo Flyway bi ohun elo iṣakoso ẹya (isunmọ. Itumọ: a n sọrọ nipa awọn iṣikiri data data). Nipa ti ara, a yoo tun kọ ohun elo Boot Orisun omi kan ti o ni atilẹyin Flyway ti a ṣe sinu ati pe yoo ṣe iṣilọ ero lakoko ti o ṣeto ipo ohun elo naa. Nigbati o ba nlo Flyway, o le tọju awọn iwe afọwọkọ ijira sinu folda awọn iṣẹ akanṣe rẹ (nipasẹ aiyipada ni classpath:db/migration). Nibi o le wo apẹẹrẹ ti iru awọn faili ijira

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

Ninu apẹẹrẹ yii a rii awọn iwe afọwọkọ ijira 4 ti, ti ko ba ṣe ni iṣaaju, yoo ṣiṣẹ ni ọkan lẹhin ekeji nigbati ohun elo ba bẹrẹ. Jẹ ki a wo ọkan ninu awọn faili (V1__init.sql) bi apẹẹrẹ.

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

Ohun gbogbo jẹ alaye ti ara ẹni ni pipe: o le lo SQL lati ṣalaye bi data data rẹ ṣe yẹ ki o yipada. Fun alaye siwaju sii nipa Orisun omi Boot ati Flyway, ṣayẹwo Orisun omi Boot Docs.

Nipa lilo ohun elo iṣakoso orisun pẹlu Boot Orisun omi, o gba awọn anfani nla 2:

  • o ya awọn iyipada data lati awọn iyipada koodu
  • Iṣilọ aaye data waye pẹlu yiyi ohun elo rẹ, i.e. ilana imuṣiṣẹ rẹ jẹ irọrun

Laasigbotitusita database isoro

Ni apakan atẹle ti nkan naa, a yoo dojukọ lori wiwo awọn ọna meji si awọn iyipada data data.

  • sẹhin incompatibility
  • sẹhin ibamu

Ni igba akọkọ ti yoo wa ni kà bi a ìkìlọ ti o yẹ ki o ko ṣe odo downtime imuṣiṣẹ lai igbaradi alakoko ... Awọn keji ọkan nfun a ojutu lori bi o ti le ṣe kan imuṣiṣẹ lai downtime ati ni akoko kanna bojuto sẹhin ibamu.

Ise agbese wa ti a yoo ṣiṣẹ lori yoo jẹ ohun elo orisun omi Boot Flyway ti o rọrun ti o ni Person с first_name и last_name ninu database (isunmọ. itumọ: Person jẹ tabili ati first_name и last_name - awọn wọnyi ni awọn aaye ninu rẹ). A fẹ lati fun lorukọ mii last_name в surname.

Awọn ero inu

Ṣaaju ki a to wọle si awọn alaye, awọn arosinu meji wa ti a nilo lati ṣe nipa awọn ohun elo wa. Abajade akọkọ ti a fẹ lati ṣaṣeyọri yoo jẹ ilana ti o rọrun.

Akọsilẹ naa. Iṣowo PRO-TIP. Awọn ilana mimu irọrun le ṣafipamọ owo pupọ fun ọ lori atilẹyin (awọn eniyan diẹ sii ti o ṣiṣẹ fun ile-iṣẹ rẹ, owo diẹ sii ti o le fipamọ)!

Ko si ye lati yi pada database

Eyi jẹ ki ilana imuṣiṣẹ ni irọrun (diẹ ninu awọn ipadasẹhin data jẹ eyiti ko ṣee ṣe, gẹgẹ bi yiyọ yiyọ kuro). A fẹ lati yi awọn ohun elo pada nikan. Ni ọna yii, paapaa ti o ba ni awọn apoti isura data oriṣiriṣi (fun apẹẹrẹ, SQL ati NoSQL), opo gigun ti imuṣiṣẹ rẹ yoo dabi kanna.

O gbọdọ nigbagbogbo ṣee ṣe lati yi ohun elo pada ẹya kan pada (ko si mọ)

Yipada sẹhin yẹ ki o ṣee ṣe nigbati o jẹ dandan. Ti kokoro kan ba wa ninu ẹya lọwọlọwọ ti ko ni irọrun ti o wa titi, o yẹ ki a ni anfani lati pada si ẹya iṣẹ tuntun. A ro pe ẹya iṣẹ tuntun yii jẹ ti iṣaaju. Mimu koodu ati ibaramu aaye data fun diẹ ẹ sii ju ọkan lọ yiyi yoo nira pupọ ati gbowolori.

Akọsilẹ naa. Fun kika kika nla, ninu nkan yii a yoo yi ẹya pataki ti ohun elo naa pada.

Igbesẹ 1: Ipinle Ibẹrẹ

Ẹya ohun elo: 1.0.0
Ẹya DB: v1

Ọrọìwòye

Eyi yoo jẹ ipo ibẹrẹ ti ohun elo naa.

Ayipada database

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

Awọn iyipada koodu

Ohun elo naa tọju data Eniyan sinu 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
                + "]";
    }
}

Ayipada ọwọn ti ko ni ibamu

Jẹ ki a wo apẹẹrẹ ti bi o ṣe le yi orukọ ọwọn pada:

Ifarabalẹ. Apẹẹrẹ atẹle yoo mọọmọ fọ awọn nkan. A ṣe afihan eyi lati ṣafihan iṣoro ti ibamu data data.

Ẹya ohun elo: 2.0.0.BAD

Ẹya DB: v2bad

Ọrọìwòye

Awọn iyipada lọwọlọwọ KO gba wa laaye lati ṣiṣe awọn iṣẹlẹ meji (ti atijọ ati tuntun) ni akoko kanna. Nitorinaa, imuṣiṣẹ akoko isinmi odo yoo nira lati ṣaṣeyọri (ti a ba gba awọn arosinu sinu akọọlẹ, ko ṣee ṣe).

A/B igbeyewo

Ipo lọwọlọwọ ni pe a ni ẹya ohun elo kan 1.0.0, ransogun ni gbóògì, ati database v1. A nilo lati ran apẹẹrẹ keji ti ohun elo naa, ẹya 2.0.0.BAD, ati imudojuiwọn database si v2bad.

Awọn igbesẹ:

  1. apere tuntun ti ohun elo ẹya ti wa ni ransogun 2.0.0.BADeyi ti o mu awọn database to v2bad
  2. ninu ibi ipamọ data v2bad ọwọn last_name ko si ohun to wa - o ti yi pada si surname
  3. Ipamọ data ati imudojuiwọn ohun elo jẹ aṣeyọri ati pe diẹ ninu awọn iṣẹlẹ nṣiṣẹ 1.0.0, awọn miran - ni 2.0.0.BAD. Ohun gbogbo ti sopọ si ibi ipamọ data v2bad
  4. gbogbo apeere ti ikede 1.0.0 yoo bẹrẹ jiju awọn aṣiṣe nitori wọn yoo gbiyanju lati fi data sii sinu iwe last_nametí kò sí mọ́
  5. gbogbo apeere ti ikede 2.0.0.BAD yoo ṣiṣẹ laisi awọn iṣoro

Bi o ṣe le rii, ti a ba ṣe awọn ayipada aibaramu sẹhin si ibi ipamọ data ati ohun elo, idanwo A/B ko ṣee ṣe.

Yipada ohun elo

Jẹ ki a ro pe lẹhin igbiyanju lati ṣe imuṣiṣẹ A/B (isunmọ. fun .: onkowe jasi túmọ A / B igbeyewo nibi) a pinnu pe a nilo lati yi ohun elo pada si ẹya naa 1.0.0. Jẹ ki a sọ pe a ko fẹ lati yi data data pada.

Awọn igbesẹ:

  1. a da apẹẹrẹ ohun elo version 2.0.0.BAD
  2. awọn database jẹ ṣi v2bad
  3. niwon awọn version 1.0.0 ko ye ohun ti o jẹ surname, a yoo ri awọn aṣiṣe
  4. apaadi ti baje, a ko le pada mọ

Bi o ṣe le rii, ti a ba ṣe awọn ayipada aibaramu sẹhin si ibi ipamọ data ati ohun elo, a ko le yi pada si ẹya ti tẹlẹ.

Awọn akosile ipaniyan iwe afọwọkọ

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

Ayipada database

Iwe afọwọkọ ijira ti o tunrukọ last_name в surname

Iwe afọwọkọ orisun 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');

Iwe afọwọkọ ti o tunrukọ last_name.

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

Awọn iyipada koodu

A ti yi orukọ aaye naa pada lastName on surname.

Fun lorukọ mii iwe kan ni ọna ti o ni ibaramu sẹhin

Eyi ni ipo ti o wọpọ julọ ti a le ba pade. A nilo lati ṣe awọn iyipada ti ko ni ibamu sẹhin. A ti fi idi rẹ mulẹ tẹlẹ pe fun imuṣiṣẹ akoko-akoko odo, a ko yẹ ki a lo ijira data nirọrun laisi awọn igbesẹ afikun. Ni apakan yii ti nkan naa, a yoo ṣe awọn imuṣiṣẹ 3 ti ohun elo pẹlu awọn iṣipopada data lati ṣaṣeyọri abajade ti o fẹ lakoko mimu ibaramu sẹhin.

Akọsilẹ naa. Ranti pe a ni aaye data ti ikede kan v1. O ni awọn ọwọn first_name и last_name. A ni lati yipada last_name on surname. A tun ni ẹya app 1.0.0, ti a ko tii lo surname.

Igbesẹ 2: Fi orukọ-idile kun

Ẹya ohun elo: 2.0.0
Ẹya DB: v2

Ọrọìwòye

Nipa fifi iwe tuntun kun ati didakọ awọn akoonu inu rẹ, a ṣẹda awọn iyipada data ibaramu sẹhin. Ni akoko kanna, ti a ba yi JAR pada tabi ni JAR atijọ ti nṣiṣẹ, kii yoo fọ lakoko ipaniyan.

A n yi ẹya tuntun jade

Awọn igbesẹ:

  1. ṣe iṣilọ data lati ṣẹda iwe tuntun kan surname. Bayi rẹ DB version v2
  2. daakọ data lati last_name в surname. San ifojusiwipe ti o ba ti o ba ni kan pupo ti yi data, o yẹ ki o ro ipele ijira!
  3. kọ awọn koodu ibi ti won ti wa ni lilo MEJEJI и новыйati arugbo ọwọn. Bayi ẹya app rẹ 2.0.0
  4. ka iye lati awọn iwe surname, ti ko ba si null, tabi lati last_name, ti o ba ti a surname lai so ni pato. O le parẹ getLastName() lati koodu, niwon o yoo jade null nigbati sẹsẹ pada rẹ elo lati 3.0.0 si 2.0.0.

Ti o ba nlo Flyway Boot Orisun omi, awọn igbesẹ meji wọnyi yoo ṣee ṣe lakoko ibẹrẹ ẹya 2.0.0 awọn ohun elo. Ti o ba ṣiṣẹ irinṣẹ ẹya data pẹlu ọwọ, iwọ yoo ni lati ṣe awọn ohun oriṣiriṣi meji lati ṣe eyi (ṣe imudojuiwọn ẹya db ni akọkọ pẹlu ọwọ ati lẹhinna ran ohun elo tuntun lọ).

O ṣe pataki. Ranti wipe awọn rinle da iwe KO GBODO jẹ KO NULL. Ti o ba ṣe yiyi pada, ohun elo atijọ ko mọ nipa iwe tuntun ati pe kii yoo fi sii lakoko Insert. Ṣugbọn ti o ba ṣafikun idiwọ yii ati pe db rẹ yoo jẹ v2, eyi yoo nilo ṣeto iye ti iwe tuntun. Eyi ti yoo ja si irufin awọn ihamọ.

O ṣe pataki. O yẹ ki o yọ ọna naa kuro getLastName(), nitori ninu awọn ti ikede 3.0.0 Ko si imọran ti iwe kan ninu koodu naa last_name. Eyi tumọ si pe asan yoo ṣeto nibẹ. O le lọ kuro ni ọna ati ṣafikun awọn sọwedowo fun null, ṣugbọn ojutu ti o dara julọ yoo jẹ lati rii daju pe ninu iṣaro getSurname() o yan iye ti kii-odo to pe.

A/B igbeyewo

Ipo lọwọlọwọ ni pe a ni ẹya ohun elo kan 1.0.0, ransogun lori isejade, ati awọn database ni v1. A nilo lati ran apẹẹrẹ keji ti ohun elo ẹya naa ṣiṣẹ 2.0.0eyi ti yoo mu awọn database to v2.

Awọn igbesẹ:

  1. apere tuntun ti ohun elo ẹya ti wa ni ransogun 2.0.0eyi ti o mu awọn database to v2
  2. Lakoko diẹ ninu awọn ibeere ni a ṣe ilana nipasẹ awọn apẹẹrẹ ti ikede 1.0.0
  3. imudojuiwọn naa ṣaṣeyọri ati pe o ni awọn iṣẹlẹ ṣiṣiṣẹ lọpọlọpọ ti ohun elo ẹya naa 1.0.0 ati awọn ẹya miiran 2.0.0. Gbogbo eniyan ni ibaraẹnisọrọ pẹlu database ni v2
  4. version 1.0.0 ko lo awọn orukọ-ìdílé ninu awọn database, ṣugbọn awọn ti ikede 2.0.0 nlo. Wọn ko dabaru pẹlu ara wọn, ati pe ko yẹ ki o jẹ awọn aṣiṣe.
  5. version 2.0.0 tọju data ni mejeeji atijọ ati iwe tuntun, ni idaniloju ibamu sẹhin

O ṣe pataki. Ti o ba ni awọn ibeere eyikeyi ti o ka awọn ohun kan ti o da lori awọn iye lati atijọ / iwe tuntun, o yẹ ki o ranti pe o ni awọn iye ẹda-iwe bayi (o ṣeese julọ wọn tun n ṣikiri). Fun apẹẹrẹ, ti o ba fẹ ka nọmba awọn olumulo ti orukọ ikẹhin (ohunkohun ti a pe ni iwe) bẹrẹ pẹlu lẹta naa A, lẹhinna titi gbigbe data yoo ti pari (oldnew iwe) o le ni data aisedede ti o ba beere iwe tuntun kan.

Yipada ohun elo

Bayi a ni app version 2.0.0 ati database ni v2.

Awọn igbesẹ:

  1. yi ohun elo rẹ pada si ẹya 1.0.0.
  2. version 1.0.0 ko lo iwe kan ninu database surname, ki awọn rollback yẹ ki o wa aseyori

DB ayipada

Awọn database ni a iwe ti a npè ni last_name.

Iwe afọwọkọ orisun 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');

Fi akosile kun surname.

Ifarabalẹ. Ranti pe o MAA ṢE ṢE ṢE ṢE ṢE ṢE ṢE ṢE ṢE awọn idiwọ NULL si ọwọn ti o n ṣafikun. Ti o ba yi JAR pada, ẹya atijọ kii yoo ni imọran nipa iwe ti a ṣafikun ati pe yoo ṣeto laifọwọyi si NULL. Ti iru aropin ba wa, ohun elo atijọ yoo fọ nirọrun.

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

Awọn iyipada koodu

A tọju data bi last_nameati ninu surname. Ni akoko kanna a ka lati last_name, niwon iwe yii jẹ pataki julọ. Lakoko ilana imuṣiṣẹ, diẹ ninu awọn ibeere le ti ni ilọsiwaju nipasẹ apẹẹrẹ ohun elo ti ko ti ni imudojuiwọn.

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

Igbesẹ 3: Yiyọ orukọ last_name kuro ninu koodu naa

Ẹya ohun elo: 3.0.0

Ẹya DB:v3

Ọrọìwòye

Akiyesi per .: Nkqwe, ninu atilẹba article onkowe asise daakọ awọn ọrọ ti yi Àkọsílẹ lati igbese 2. Ni yi igbese, awọn ayipada yẹ ki o wa ni ṣe ninu awọn ohun elo koodu Eleto yiyọ awọn iṣẹ-ṣiṣe ti o nlo awọn iwe. last_name.

Nipa fifi iwe tuntun kun ati didakọ awọn akoonu rẹ, a ṣẹda awọn iyipada data ibaramu sẹhin sẹhin. Paapaa, ti a ba yi JAR pada tabi ti nṣiṣẹ JAR atijọ, kii yoo fọ lakoko ipaniyan.

Yipada ohun elo

Lọwọlọwọ a ni app version 3.0.0 ati database v3. Ẹya 3.0.0 ko fi data pamọ si last_name. Eyi tumọ si pe ninu surname awọn julọ imudojuiwọn alaye ti wa ni ipamọ.

Awọn igbesẹ:

  1. yi ohun elo rẹ pada si ẹya 2.0.0.
  2. version 2.0.0 nlo ati last_name и surname.
  3. version 2.0.0 yoo gba surname, ti ko ba jẹ odo, bibẹẹkọ -last_name

Ayipada database

Ko si awọn ayipada igbekalẹ ninu aaye data. Iwe afọwọkọ atẹle yii jẹ ṣiṣe lati ṣe iṣilọ ikẹhin ti data atijọ:

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

Awọn iyipada koodu

Akiyesi fun .: Apejuwe ti bulọọki yii tun jẹ adakọ ni aṣiṣe nipasẹ onkọwe lati igbesẹ 2. Ni ibamu pẹlu ọgbọn ti nkan naa, awọn ayipada ninu koodu ni igbesẹ yii yẹ ki o ṣe ifọkansi lati yọkuro awọn eroja ti o ṣiṣẹ pẹlu ọwọn naa. last_name.

A tọju data bi last_nameati ninu surname. Ni afikun, a ka lati iwe last_name, niwon o jẹ pataki julọ. Lakoko ilana imuṣiṣẹ, diẹ ninu awọn ibeere le ni ilọsiwaju nipasẹ apẹẹrẹ ti ko ti ni igbegasoke.

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

Igbesẹ 4: Yiyọ orukọ kẹhin kuro ni ibi ipamọ data

Ẹya ohun elo: 4.0.0

Ẹya DB: v4

Ọrọìwòye

Nitori si ni otitọ wipe version koodu 3.0.0 ko lo ọwọn last_name, Ko si ohun buburu ti yoo ṣẹlẹ lakoko ipaniyan ti a ba yi pada si 3.0.0 lẹhin yiyọ iwe kan lati database.

Awọn akosile ipaniyan iwe afọwọkọ

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 ayipada

Ni ibatan v3 a kan yọ ọwọn naa kuro last_name ki o si fi sonu awọn ihamọ.

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

Awọn iyipada koodu

Ko si awọn ayipada si koodu.

ipari

A ṣaṣeyọri lo iyipada orukọ ọwọn ti ko ni ibaramu nipasẹ ṣiṣe ọpọlọpọ awọn imuṣiṣẹ sẹhin-ibaramu. Ni isalẹ ni akojọpọ awọn iṣe ti a ṣe:

  1. imuṣiṣẹ ẹya ohun elo 1.0.0 с v1 eto ibi ipamọ data (orukọ ọwọn = last_name)
  2. imuṣiṣẹ ẹya ohun elo 2.0.0, eyiti o tọju data sinu last_name и surname. Ohun elo naa ka lati last_name. Awọn database jẹ ninu version v2ti o ni awọn ọwọn bi last_name, ati surname. surname jẹ ẹda last_name. (AKIYESI: Oju-iwe yii ko gbọdọ ni idiwọ asan)
  3. imuṣiṣẹ ẹya ohun elo 3.0.0, eyiti o tọju data nikan sinu surname ati kika lati orukọ idile. Bi fun data data, ijira ti o kẹhin n waye last_name в surname. Tun kan aropin KO NULL yorawonkuro lati last_name. Awọn database ti wa ni bayi ni version v3
  4. imuṣiṣẹ ẹya ohun elo 4.0.0 - ko si ayipada ti wa ni ṣe si awọn koodu. Ibi ipamọ data v4, eyi ti o yọ kuro last_name. Nibi o le ṣafikun eyikeyi awọn idiwọ ti o padanu si ibi ipamọ data.

Nipa titẹle ọna yii, o le yi ẹya kan pada nigbagbogbo laisi fifọ data data / ibaramu ohun elo.

Koodu

Gbogbo koodu ti a lo ninu nkan yii wa ni Github. Ni isalẹ ni afikun apejuwe.

Awọn iṣẹ akanṣe

Lẹhin ti cloning awọn ibi ipamọ, o yoo ri awọn wọnyi folda be.

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

Awọn iwe afọwọkọ

O le ṣiṣe awọn iwe afọwọkọ ti a sapejuwe ninu awọn iwe afọwọkọ ni isalẹ, eyi ti yoo ṣe afihan sẹhin-ibaramu ati awọn iyipada ti ko ni ibamu si database.

Lati ri ọran naa pẹlu awọn iyipada ibaramu sẹhin, sure:

./scripts/scenario_backward_compatible.sh

Ati lati ri ọran pẹlu awọn iyipada ti ko ni ibamu sẹhin, sure:

./scripts/scenario_backward_incompatible.sh

Orisun omi Boot Ayẹwo Flyway

Gbogbo apẹẹrẹ ti wa ni ya lati Spring Boot Sample Flyway.

O le wo http://localhost:8080/flyway, akojọ awọn iwe afọwọkọ wa.

Apẹẹrẹ yii tun pẹlu console H2 (ni http://localhost:8080/h2-console) nitorina o le wo ipo data data (aiyipada jdbc URL jẹ jdbc:h2:mem:testdb).

Ti ni ilọsiwaju

Tun ka awọn nkan miiran lori bulọọgi wa:

orisun: www.habr.com

Fi ọrọìwòye kun