Zero Downtime Deployment and Databases

Zero Downtime Deployment and Databases

E wehewehe kikoʻī ana kēia ʻatikala pehea e hoʻoholo ai i nā pilikia pili i ka waihona i ka hoʻolaha ʻana. E haʻi aku mākou iā ʻoe i ka mea e hiki ke hana i kāu mau noi hana inā hoʻāʻo ʻoe e kau me ka ʻole o ka hoʻomākaukau mua ʻana. A laila e hele mākou i nā kaʻina ola ola noi e koi ʻia e loaʻa ka zero downtime (kokoke. ala: ʻoi aku - zero downtime). ʻO ka hopena o kā mākou hana, ʻo ia ka hoʻohana ʻana i ka hoʻololi ʻikepili hope-like ʻole ma ke ʻano kūpono i hope.

Inā makemake ʻoe e hoʻomaopopo i nā hiʻohiʻona code mai ka ʻatikala, hiki iā ʻoe ke loaʻa iā lākou ma GitHub.

Hōʻike

ʻO ka hoʻolaha ʻana i ka wā haʻahaʻa

He mea pohihihi ʻaʻohe hoʻokuʻu manawa haʻahaʻa? Hiki iā ʻoe ke ʻōlelo i kēia ke kau ʻia kāu noi i ke ala e hiki ai iā ʻoe ke hoʻolauna i kahi mana hou o ka noi i ka hana ʻana, ʻoiai ʻaʻole ʻike ka mea hoʻohana i kona loaʻa ʻole. Mai ka hiʻohiʻona mea hoʻohana a me ka ʻoihana, ʻo ia ka hiʻohiʻona hoʻonohonoho maikaʻi loa no ka mea hiki ke hoʻokomo ʻia nā hiʻohiʻona hou a hoʻopaʻa ʻia nā pōpoki me ka ʻole o ka pilikia.

Pehea e hoʻokō ai i kēia? Nui nā ala, eia kekahi o lākou:

  • e kau i ka mana helu 1 o kāu lawelawe
  • hana i ka neʻe ʻana i ka waihona
  • E hoʻolālā i ka mana #2 o kāu lawelawe e like me ka mana #1
  • ke ʻike koke ʻoe i ka hana ʻana o ka mana No. 2 e like me ka pono, e wehe i ka mana No. 1
  • hana!

Maʻalahi, ʻaʻole anei? ʻO ka mea pōʻino, ʻaʻole ia maʻalahi, a e nānā mākou i kēlā me ka kikoʻī ma hope. I kēia manawa, e nānā kākou i kekahi kaʻina hana hoʻolaha maʻamau - blue green deployment.

Ua lohe paha ʻoe i hoʻolaha ʻōmaʻomaʻo uliuli? ʻO Cloud Foundry ka mea maʻalahi loa. E nana wale aku kēia ʻatikala, kahi e wehewehe nui aku ai mākou i kēia. No ka hōʻuluʻulu pōkole, e hoʻomanaʻo mākou iā ʻoe pehea e hana ai i ka hoʻolaha ʻōmaʻomaʻo uliuli:

  • e hōʻoia i ʻelua kope o kāu code production (“blue” a me “green”);
  • kuhikuhi i nā kaʻa a pau i ke kaiapuni uliuli, i.e. i kuhikuhi ai nā URL hana i laila;
  • hoʻolālā a hoʻāʻo i nā hoʻololi noi āpau i kahi ʻōmaʻomaʻo;
  • e hoʻololi i nā URL mai ka uliuli a i ka ʻōmaʻomaʻo

ʻO ka hoʻolālā ʻōmaʻomaʻo uliuli kahi ala e hiki ai iā ʻoe ke hoʻolauna maʻalahi i nā hiʻohiʻona hou me ka hopohopo ʻole e pili ana i ka haki ʻana o ka hana. ʻO kēia ma muli o ka ʻoiaʻiʻo inā hiki mai kekahi mea, hiki iā ʻoe ke hoʻi maʻalahi i ke kaiapuni mua ma ka "paʻi ʻana i kahi kī."

Ma hope o ka heluhelu ʻana i nā mea a pau i luna, e nīnau paha ʻoe i ka nīnau: He aha ka pili o ka zero downtime me ka hoʻolaha ʻana o Blue green?

ʻAe, he nui nā mea maʻamau, no ka mea, ʻo ka mālama ʻana i ʻelua kope o ke kaiapuni like e koi pālua i ka hoʻoikaika ʻana e mālama iā lākou. ʻO kēia ke kumu e koi ai kekahi mau hui Martin Fowler, e hahai i kekahi hoʻololi o kēia ala:

ʻO kahi koho ʻē aʻe, ʻo ia ka hoʻohana ʻana i ka waihona waihona like, e hana ana i nā hoʻololi polū-'ōmaʻomaʻo no ka pūnaewele a me nā papa inoa. Ma kēia ala, hiki i ka ʻikepili ke pilikia pinepine, ʻoiai inā pono ʻoe e hoʻololi i kāna schema e kākoʻo i kahi mana hou o ka polokalamu.

A eia mākou i ka pilikia nui ma kēia ʻatikala. Database. E nānā hou kākou i kēia ʻōlelo.

hana i ka neʻe ʻana i ka waihona.

I kēia manawa pono ʻoe e nīnau iā ʻoe iho i ka nīnau - pehea inā ʻaʻole kūpono ka hoʻololi ʻikepili i hope? ʻAʻole anei e haki kaʻu mana mua o ka polokalamu? ʻOiaʻiʻo, ʻo kēia ka mea e hiki mai ana ...

No laila, ʻoiai nā pōmaikaʻi nui o ka zero downtime / blue green deployment, makemake nā ʻoihana e hahai i kēia kaʻina hana palekana no ka lawe ʻana i kā lākou noi:

  • hoʻomākaukau i kahi pūʻolo me kahi mana hou o ka noi
  • pani i kahi noi e holo ana
  • holo palapala e neʻe i ka waihona
  • kau a hoʻomaka i kahi mana hou o ka noi

Ma kēia ʻatikala, e kikoʻī mākou pehea e hiki ai iā ʻoe ke hana me kāu waihona a me kāu code e hoʻohana pono ai i ka hoʻolaha ʻana i ka wā hoʻomaha.

Pilikia waihona

Inā loaʻa iā ʻoe kahi noi mokuʻāina ʻaʻole mālama i nā ʻikepili i loko o ka waihona, hiki iā ʻoe ke loaʻa ka zero downtime deployment koke. ʻO ka mea pōʻino, pono ka hapa nui o nā polokalamu e mālama i ka ʻikepili ma kahi. ʻO ia ke kumu e noʻonoʻo ʻelua ma mua o ka hoʻololi ʻana i ke kaapuni. Ma mua o ko mākou komo ʻana i nā kikoʻī o ke ʻano o ka hoʻololi ʻana i ka schema i hiki ai ke hoʻokuʻu ʻole i ka manawa hoʻomaha, e kālele mua kākou i ka manaʻo hoʻololi.

Hoʻolālā hoʻololi

Ma kēiaʻatikala e hoʻohana mākou Alanui lele ma ke ʻano he mea hana mana mana (kokoke. Unuhi: ke kamaʻilio nei mākou e pili ana i ka neʻe ʻana o ka waihona). Ma keʻano maʻamau, e kākau pū mākou i kahi noi Spring Boot i kūkulu ʻia i ke kākoʻo Flyway a e hana i ka neʻe schema i ka wā e hoʻonohonoho ana i ka pōʻaiapili noi. Ke hoʻohana nei ʻo Flyway, hiki iā ʻoe ke mālama i nā palapala neʻe i loko o kāu waihona papahana (ma ka paʻamau ma classpath:db/migration). Maanei hiki iā ʻoe ke ʻike i kahi laʻana o ia mau faila migration

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

Ma kēia hiʻohiʻona, ʻike mākou i nā palapala neʻe 4, inā ʻaʻole i hoʻokō ʻia ma mua, e hoʻokō ʻia kekahi ma hope o kekahi ke hoʻomaka ka noi. E nānā kākou i kekahi o nā faila (V1__init.sql) i laʻana.

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

He wehewehe pono nā mea a pau: hiki iā ʻoe ke hoʻohana iā SQL e wehewehe i ke ʻano o ka hoʻololi ʻana i kāu waihona. No ka ʻike hou aku e pili ana i ka Spring Boot a me Flyway, e nānā Nā Docs Boot Spring.

Ma ka hoʻohana ʻana i kahi mea hoʻokele kumu me Spring Boot, loaʻa iā ʻoe nā pōmaikaʻi nui 2:

  • hoʻokaʻawale ʻoe i nā loli waihona mai nā hoʻololi code
  • Hiki mai ka neʻe ʻana o ka waihona me ka hoʻopuka ʻana o kāu noi, ʻo ia hoʻi. ua maʻalahi kāu kaʻina hana

Hoʻoponopono i nā pilikia waihona

Ma ka ʻāpana aʻe o ka ʻatikala, e kālele mākou i ka nānā ʻana i ʻelua ala e hoʻololi ai i ka waihona.

  • ka launa ʻole hope
  • hoʻokuʻi hope

E noʻonoʻo ʻia ka mea mua ma ke ʻano he ʻōlelo aʻo ʻaʻole pono ʻoe e hana i ka zero downtime deployment me ka ʻole o ka hoʻomākaukau mua ʻana.

ʻO kā mākou papahana a mākou e hana ai, he polokalamu maʻalahi ia no ka Spring Boot Flyway Person с first_name и last_name ma ka waihona (kokoke. unuhi: Person he papaaina a me first_name и last_name - ʻo ia nā māla i loko). Makemake mākou e inoa hou last_name в surname.

Nā manaʻo manaʻo

Ma mua o ko mākou komo ʻana i nā kikoʻī, aia kekahi mau manaʻo e pono ai mākou e hana e pili ana i kā mākou noi. ʻO ka hopena nui a mākou e makemake ai e hoʻokō he hana maʻalahi.

ʻO ka leka. ʻOihana PRO-TIP. Hiki i nā kaʻina hana maʻalahi ke mālama iā ʻoe i ke kālā he nui ma ke kākoʻo (ʻo ka nui o nā poʻe āu e hana nei no kāu ʻoihana, ʻoi aku ka nui o ke kālā āu e mālama ai)!

ʻAʻole pono e rollback i ka waihona

Hoʻomaʻamaʻa kēia i ke kaʻina hana (ʻaneʻane hiki ʻole ke hoʻihoʻi i ka waihona waihona, e like me ka rollback holoi ʻana). Makemake mākou e ʻōwili i hope i nā noi wale nō. Ma kēia ala, ʻoiai inā loaʻa iā ʻoe nā ʻikepili ʻokoʻa (e like me SQL a me NoSQL), e like ke ʻano o kāu pipeline deployment.

Pono e hiki ke hoʻihoʻi i ka noi i hoʻokahi mana i hope (ʻaʻole hou)

Pono e hana hou i ka wā e pono ai. Inā loaʻa kahi pahu i ka mana o kēia manawa ʻaʻole hiki ke hoʻopaʻa maʻalahi, hiki iā mākou ke hoʻi i ka mana hana hou loa. Manaʻo mākou ʻo kēia ʻano hana hou ka mea ma mua. ʻO ka mālama ʻana i ka code a me ka hoʻohālikelike ʻana i ka waihona no ka ʻoi aku o hoʻokahi rollout e paʻakikī loa a pipiʻi.

ʻO ka leka. No ka heluhelu ʻoi aku, ma kēia ʻatikala e hoʻololi mākou i ka mana nui o ka noi.

KaʻAnuʻu 1: Moku'āina mua

Mana Manaʻo: 1.0.0
Mana DB: v1

manaʻo hoʻopuka

ʻO kēia ke kūlana mua o ka noi.

Hoʻololi ʻikepili

Aia i loko o DB 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');

Hoʻololi code

Mālama ka palapala noi i ka ʻikepili kanaka i loko 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
                + "]";
    }
}

Hoʻihoʻi hou i ka inoa kolamu kūpono ʻole

E nānā kākou i kekahi laʻana o ka hoʻololi ʻana i ka inoa kolamu:

Nānā. ʻO ka laʻana ma lalo nei e uhaʻi i nā mea. Hōʻike mākou i kēia e hōʻike i ka pilikia o ka hoʻohālikelike ʻana i ka waihona.

Mana Manaʻo: 2.0.0.BAD

Mana DB: v2bad

manaʻo hoʻopuka

ʻAʻole ʻae nā loli o kēia manawa iā mākou e holo i ʻelua mau manawa (kahiko a me ka mea hou) i ka manawa like. No laila, paʻakikī ke hoʻokō ʻana i ka hoʻoheheʻe ʻana i ka wā hoʻomaha (inā e noʻonoʻo ʻia nā manaʻo, ʻaʻole hiki ʻole).

Hoʻāʻo A/B

ʻO ke kūlana o kēia manawa he mana noi kā mākou 1.0.0, deployed i ka hana, a me ka waihona v1. Pono mākou e kau i kahi lua o ka noi, version 2.0.0.BAD, a hōʻano hou i ka waihona i v2bad.

Nā Kūlana:

  1. ua kau ʻia kahi mea hou o ka palapala noi 2.0.0.BADka mea e hoʻohou i ka waihona i v2bad
  2. i ka waihona pūnaewele v2bad kolamu last_name ʻaʻole ola hou - ua hoʻololi ʻia i surname
  3. Ua holomua ka ʻikepili a me ka hoʻopiʻi noiʻi a ke holo nei kekahi mau manawa 1.0.0, 'ē aʻe - ma 2.0.0.BAD. Pili nā mea a pau i ka waihona v2bad
  4. nā manawa a pau o ka mana 1.0.0 e hoʻomaka e hoʻolei hewa no ka mea e hoʻāʻo lākou e hoʻokomo i ka ʻikepili i loko o ke kolamu last_nameka mea e noho hou ana
  5. nā manawa a pau o ka mana 2.0.0.BAD e hana me ka pilikia ole

E like me kāu e ʻike ai, inā hana mākou i nā hoʻololi like ʻole i hope i ka waihona a me ka noi, hiki ʻole ke hoʻāʻo A/B.

Hoʻihoʻi ʻia ka noi

E noʻonoʻo kākou ma hope o ka hoʻāʻo ʻana e hana i ka deployment A/B (kokoke. per.: manaʻo paha ka mea kākau i ka hoʻāʻo A/B ma aneʻi) ua hoʻoholo mākou e pono e hoʻihoʻi i ka noi i ka mana 1.0.0. E ʻōlelo mākou ʻaʻole makemake mākou e hoʻohuli i ka waihona.

Nā Kūlana:

  1. Hoʻopau mākou i ka laʻana palapala noi 2.0.0.BAD
  2. ua mau ka waihona v2bad
  3. mai ka mana 1.0.0 ʻaʻole maopopo ia mea surname, e ike kakou i na hewa
  4. Ua haki ka po, ʻaʻole hiki iā mākou ke hoʻi hou

E like me kāu e ʻike ai, inā hana mākou i nā hoʻololi like ʻole i hope i ka waihona a me ka noi, ʻaʻole hiki iā mākou ke hoʻi i ka mana mua.

Nā moʻolelo hoʻokō palapala

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

Hoʻololi ʻikepili

Palapala hoʻoneʻe e hoʻololi i ka inoa last_name в surname

Ka palapala ʻo Flyway Source:

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

Palapala e hoʻololi i ka inoa last_name.

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

Hoʻololi code

Ua hoʻololi mākou i ka inoa kahua lastName maluna o surname.

Ka inoa hou ʻana i kahi kolamu ma ke ʻano kūpono i hope

ʻO kēia ke kūlana maʻamau a mākou e hālāwai ai. Pono mākou e hana i nā hoʻololi like ʻole i hope. Ua hōʻoia mua mākou no ka hoʻokuʻu ʻana i ka zero-downtime, ʻaʻole pono mākou e hoʻopili wale i ka neʻe ʻana i ka waihona me ka ʻole o nā hana hou. Ma kēia ʻāpana o ka ʻatikala, e hana mākou i 3 hoʻolālā o ka noi me ka neʻe ʻana o ka waihona e hoʻokō i ka hopena i makemake ʻia me ka mālama ʻana i ka hoʻohālikelike hope.

ʻO ka leka. E hoʻomanaʻo he waihona waihona kā mākou v1. Aia nā kolamu first_name и last_name. Pono mākou e hoʻololi last_name maluna o surname. Loaʻa iā mākou ka mana app 1.0.0, ʻaʻole i hoʻohana ʻia surname.

KaʻAnuʻu 2: Hoʻohui i ka inoa inoa

Mana Manaʻo: 2.0.0
Mana DB: v2

manaʻo hoʻopuka

Ma ka hoʻohui ʻana i kahi kolamu hou a me ke kope ʻana i kāna mau ʻike, hana mākou i nā loli ʻikepili kūpono i hope. I ka manawa like, inā e hoʻihoʻi mākou i ka JAR a i ʻole kahi JAR kahiko e holo ana, ʻaʻole ia e haki i ka wā e hoʻokō ai.

Ke hoʻopuka nei mākou i kahi mana hou

Nā Kūlana:

  1. hana i ka neʻe ʻana i ka waihona no ka hana ʻana i kolamu hou surname. I kēia manawa kāu mana DB v2
  2. kope ʻikepili mai last_name в surname. E hoʻoloheinā he nui kāu o kēia ʻikepili, pono ʻoe e noʻonoʻo i ka neʻe ʻana o ka hui!
  3. e kākau i ke code kahi i hoʻohana ʻia ai NA LUA и houa ka mea kahiko kolamu. I kēia manawa i kāu mana polokalamu 2.0.0
  4. heluhelu i ka waiwai mai ke kolamu surname, ina aole null, a mai last_name, inā surname ʻaʻole i kuhikuhi ʻia. Hiki iā ʻoe ke holoi getLastName() mai ke code, no ka mea e puka mai ana null i ka wā e hoʻihoʻi ai i kāu noi mai 3.0.0 i luna 2.0.0.

Inā ʻoe e hoʻohana ana i ka Spring Boot Flyway, e hana ʻia kēia mau ʻanuʻu ʻelua i ka wā o ka hoʻomaka ʻana o ka mana 2.0.0 nā noi. Inā holo lima ʻoe i ka hāmeʻa hoʻololi waihona waihona, pono ʻoe e hana i ʻelua mau mea like ʻole e hana ai i kēia (e hoʻohou mua i ka mana db me ka lima a laila e kau i ka noi hou).

He mea nui. E hoʻomanaʻo i ke kolamu hou i hana ʻia AOLE PONO e lilo AOLE NULU. Inā hana ʻoe i ka rollback, ʻaʻole ʻike ka palapala noi kahiko i ke kolamu hou a ʻaʻole e hoʻokomo iā ia i ka wā Insert. Akā inā ʻoe e hoʻohui i kēia kaohi a ʻo kāu db v2, pono kēia e hoʻonohonoho i ka waiwai o ke kolamu hou. ʻO ia ka mea e alakaʻi ai i ka uhaki i nā kapu.

He mea nui. Pono ʻoe e wehe i ke ʻano getLastName(), no ka mea ma ka mana 3.0.0 ʻAʻohe manaʻo o kahi kolamu ma ke code last_name. 'O ia ho'i, e ho'onoho 'ia ka null ma laila. Hiki iā ʻoe ke haʻalele i ke ʻano a hoʻohui i nā loiloi no null, akā, ʻoi aku ka maikaʻi o ka hoʻonā ʻana e hōʻoia i ka loina getSurname() ua koho ʻoe i ka waiwai kūpono ʻole ʻole.

Hoʻāʻo A/B

ʻO ke kūlana o kēia manawa he mana noi kā mākou 1.0.0, deployed on production, and the database in v1. Pono mākou e kau i kahi lua o ka palapala noi 2.0.0ka mea e hōʻano hou i ka waihona i v2.

Nā Kūlana:

  1. ua kau ʻia kahi mea hou o ka palapala noi 2.0.0ka mea e hoʻohou i ka waihona i v2
  2. i kēia manawa ua hana ʻia kekahi mau noi e nā hiʻohiʻona mana 1.0.0
  3. ua kūleʻa ka hoʻohou a loaʻa iā ʻoe nā manawa holo o ka noi mana 1.0.0 a me nā mana ʻē aʻe 2.0.0. Kūkākūkā nā mea a pau me ka waihona ma v2
  4. ʻike 1.0.0 ʻaʻole hoʻohana i ka kolamu inoa ma ka waihona, akā ʻo ka mana 2.0.0 hoʻohana. ʻAʻole lākou e keʻakeʻa kekahi i kekahi, ʻaʻole pono e hewa.
  5. ʻike 2.0.0 mālama i ka ʻikepili ma ke kolamu kahiko a me ka kolamu hou, e hōʻoia ana i ka hoʻokō ʻana i hope

He mea nui. Inā he mau nīnau kāu e helu ai i nā mea e pili ana i nā waiwai mai ka kolamu kahiko/hou, pono ʻoe e hoʻomanaʻo he mau helu pālua kāu i kēia manawa (ʻoi aku paha lākou e neʻe nei). No ka laʻana, inā makemake ʻoe e helu i ka helu o nā mea hoʻohana nona ka inoa hope (ʻo ke kolamu i kapa ʻia) i hoʻomaka me ka leka A, a laila a pau ka neʻe ʻana o ka ʻikepili (oldnew kolamu) loaʻa paha iā ʻoe ka ʻikepili like ʻole inā e nīnau ʻoe i kahi kolamu hou.

Hoʻihoʻi ʻia ka noi

I kēia manawa ua loaʻa iā mākou ka mana app 2.0.0 a me ka waihona ma v2.

Nā Kūlana:

  1. e hoʻihoʻi i kāu palapala noi i ka mana 1.0.0.
  2. ʻike 1.0.0 ʻaʻole hoʻohana i kahi kolamu ma ka waihona surname, no laila e holomua ka rollback

Hoʻololi DB

Aia ka waihona i kahi kolamu i kapa ʻia last_name.

ʻO ka palapala kumu lele lele:

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

Hoʻohui palapala surname.

Nānā. E hoʻomanaʻo ʻaʻole hiki iā ʻoe ke hoʻohui i nā koi NOT NULL i ke kolamu āu e hoʻohui nei. Inā ʻoe e hoʻihoʻi i ka JAR, ʻaʻohe manaʻo o ka mana kahiko e pili ana i ke kolamu i hoʻohui ʻia a hoʻonohonoho pono iā ia i NULL. Inā loaʻa kēlā palena, e haki wale ka noi kahiko.

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

Hoʻololi code

Mālama mākou i ka ʻikepili e like me last_name, a iloko surname. Ma ka manawa like mākou heluhelu mai last_name, no ka mea pili loa kēia kolamu. I ka wā o ke kaʻina hana, ua hana ʻia paha kekahi mau noi e kahi laʻana noi i hoʻonui ʻole ʻia.

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

KaʻAnuʻu Hana 3: Wehe i hope_name mai ke code

Mana Manaʻo: 3.0.0

Mana DB:v3

manaʻo hoʻopuka

Nānā per.: Me he mea lā, i loko o ka ʻatikala kumu, ua kope hewa ka mea kākau i ka kikokikona o kēia poloka mai ka ʻanuʻu 2. Ma kēia ʻanuʻu, pono e hoʻololi ʻia i ka code noi e kuhikuhi ana i ka wehe ʻana i ka hana e hoʻohana ana i ke kolamu. last_name.

Ma ka hoʻohui ʻana i kahi kolamu hou a me ke kope ʻana i kāna mau ʻike, ua hana mākou i nā loli ʻikepili kūpono i hope. Eia kekahi, inā e hoʻihoʻi mākou i ka JAR a i ʻole e holo ana ka JAR kahiko, ʻaʻole ia e haki i ka wā e hoʻokō ai.

Hoʻihoʻi ʻia ka noi

I kēia manawa, loaʻa iā mākou ka mana app 3.0.0 a me ka waihona v3. Manao 3.0.0 ʻaʻole mālama i ka ʻikepili i last_name. ʻO ia hoʻi i loko surname mālama ʻia ka ʻike hou loa.

Nā Kūlana:

  1. e hoʻihoʻi i kāu palapala noi i ka mana 2.0.0.
  2. ʻike 2.0.0 hoʻohana a last_name и surname.
  3. ʻike 2.0.0 e lawe surname, inā ʻaʻole ia he zero, inā ʻaʻole -last_name

Hoʻololi ʻikepili

ʻAʻohe hoʻololi hoʻololi i ka waihona. Hoʻokō ʻia kēia ʻatikala e hana i ka neʻe hope o ka ʻikepili kahiko:

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

Hoʻololi code

Nānā per.: Ua kope hewa ʻia ka wehewehe ʻana o kēia poloka e ka mea kākau mai ka ʻanuʻu 2. E like me ke kumu o ka ʻatikala, pono e hoʻololi i ka code ma kēia ʻanuʻu i ka wehe ʻana i nā mea hana me ke kolamu. last_name.

Mālama mākou i ka ʻikepili e like me last_name, a iloko surname. Eia hou, heluhelu mākou mai ke kolamu last_name, ʻoiai ʻo ia ka mea pili loa. I ka wā o ke kaʻina hana, hiki ke hoʻokō ʻia kekahi mau noi e kahi laʻana i hoʻomaikaʻi ʻole ʻia.

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

KaʻAnuʻu Hana 4: Wehe last_name mai ka waihona

Mana Manaʻo: 4.0.0

Mana DB: v4

manaʻo hoʻopuka

Ma muli o ke ʻano o ka code version 3.0.0 ʻaʻole hoʻohana i ke kolamu last_name, ʻaʻohe mea ʻino e hiki mai i ka wā o ka hoʻokō inā hoʻi mākou i 3.0.0 ma hope o ka wehe ʻana i kahi kolamu mai ka waihona.

Nā moʻolelo hoʻokō palapala

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

Hoʻololi DB

Pili v3 wehe wale mākou i ke kolamu last_name a hoʻohui i nā kapu i nalowale.

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

Hoʻololi code

ʻAʻohe hoʻololi i ke code.

hopena

Ua hoʻohana maikaʻi mākou i ka hoʻololi ʻana i ka inoa kolamu hiki ʻole i hope ma o ka hana ʻana i kekahi mau hoʻolaʻa ʻana i hope. Aia ma lalo kahi hōʻuluʻulu o nā hana i hana ʻia:

  1. hoʻolaha ʻana o ka mana noi 1.0.0 с v1 hoʻolālā waihona (inoa kolamu = last_name)
  2. hoʻolaha ʻana o ka mana noi 2.0.0, kahi e mālama ai i ka ʻikepili i loko last_name и surname. Heluhelu mai ka palapala noi mai last_name. Aia ka waihona ma ka mana v2loaʻa nā kolamu like last_name, a surname. surname he kope o last_name. (E MANAʻO: ʻAʻole pono e loaʻa i kēia kolamu ka palena ʻole)
  3. hoʻolaha ʻana o ka mana noi 3.0.0, ka mea mālama i ka ʻikepili i loko surname a heluhelu mai ka inoa inoa. No ka waihona, ke hana nei ka neʻe hope loa last_name в surname. Also palena AOLE NULU wehe ʻia mai last_name. Aia ka waihona i kēia manawa i ka mana v3
  4. hoʻolaha ʻana o ka mana noi 4.0.0 - ʻaʻohe hoʻololi i ke code. Hoʻolaha waihona v4, e wehe ana last_name. Ma ʻaneʻi hiki iā ʻoe ke hoʻohui i nā mea i nalowale i ka waihona.

Ma ka hahai ʻana i kēia ala, hiki iā ʻoe ke ʻōwili i hope i hoʻokahi mana me ka ʻole o ka haki ʻana i ka waihona waihona/noi.

kuhi

Loaʻa nā code āpau i hoʻohana ʻia ma kēia ʻatikala ma Github. Aia ma lalo iho kahi wehewehe hou.

Nā Pāhana

Ma hope o ka cloning i ka waihona, e ʻike ʻoe i ke ʻano o ka waihona.

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

Nā Kūlana

Hiki iā ʻoe ke holo i nā palapala i hōʻike ʻia ma nā palapala ma lalo nei, e hōʻike ana i nā hoʻololi hope-kūpono a kūpono ʻole i ka waihona.

E 'ike ka hihia me nā loli kūpono i hope, holo:

./scripts/scenario_backward_compatible.sh

A e ike hihia me nā hoʻololi like ʻole i hope, holo:

./scripts/scenario_backward_incompatible.sh

Laʻana Laʻana Boot Spring

Lawe ʻia nā laʻana a pau mai Spring Boot Sample Flyway.

Hiki iā ʻoe ke nānā http://localhost:8080/flyway, aia kahi papa inoa o nā palapala.

Aia pū kēia hiʻohiʻona i ka console H2 (ma http://localhost:8080/h2-console) no laila hiki iā ʻoe ke nānā i ke kūlana waihona (ʻo ka jdbc URL jdbc:h2:mem:testdb).

aiiieieoaeuii

E heluhelu pū i nā ʻatikala ʻē aʻe ma kā mākou blog:

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka