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');
Yokutanga ichaonekwa senyevero yokuti iwe haufaniri kuita zero downtime deployment pasina kugadzirira kwekutanga ... Yechipiri inopa mhinduro pamusoro pekuti iwe ungaita sei kushandiswa pasina nguva uye panguva imwechete uchengetedze kuwirirana kumashure.
Yedu purojekiti yatichange tichishanda pairi ichave iri nyore Spring Boot Flyway application ine Person с first_name и last_name mu database (approx. shandura Person iri tafura uye first_name и last_name - iyi ndiyo minda mairi) Tinoda kutumidza zita last_name в surname.
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');
Kuchinja kwekodhi
Iyo application inochengeta Yemunhu data mukati 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
+ "]";
}
}
Sezvauri kuona, kana tikaita shanduko kumashure dzisingaenderane kune dhatabhesi uye mashandisiro, hatigone kudzoreredza kushanduro yapfuura.
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"}
Database shanduko
Migration script inotumidza mazita last_name в surname
Kwakabva 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 inotumidza mazita last_name.
-- This change is backward incompatible - you can't do A/B testing
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;
Nekuwedzera koramu nyowani uye kukopa zvirimo, isu tinogadzira kumashure inoenderana dhatabhesi shanduko. Panguva imwecheteyo, kana tikadzosera iyo JAR kana kuita yekare JAR ichimhanya, haityoke panguva yekuurayiwa.
Tiri kuburitsa shanduro itsva
Matanho:
ita dhatabhesi kutama kuti ugadzire chinyorwa chitsva surname. Iye zvino DB yako vhezheni v2
kopira data kubva last_name в surname. Ngwarirakuti kana uine yakawanda data iyi, iwe unofanirwa kufunga nezve batch kutama!
nyora kodhi padzinoshandiswa VESE и новыйuye yekare column. Iye zvino vhezheni yako yeapp 2.0.0
verenga kukosha kubva pa column surname, kana zvisiri null, kana kubva kulast_name, kana surname zvisina kutaurwa. Unogona kudzima getLastName() kubva kune kodhi, sezvo ichabuda null paunenge uchidzosera application yako kubva 3.0.0 up to 2.0.0.
Kana uri kushandisa Spring Boot Flyway, aya matanho maviri achaitwa panguva yekutanga shanduro 2.0.0 applications. Kana iwe uchimhanyisa dhatabhesi yekushandura chishandiso nemaoko, uchafanirwa kuita zvinhu zviviri zvakasiyana kuti uite izvi (kutanga gadziridza iyo db vhezheni nemawoko wozotumira chishandiso chitsva).
Zvinokosha. Rangarira kuti iyo ichangobva kugadzirwa column HAZVIFANIRIRE kuva HAPANA. Kana iwe ukaita kudzoreredza, iyo yekare application haizive nezvekoromo itsva uye haizoiise panguva Insert. Asi kana iwe ukawedzera ichi chinomanikidza uye db yako ichave v2, izvi zvinoda kuisa kukosha kwekoramu itsva. Izvo zvinozoita kuti kutyorwe kwezvirambidzo.
Zvinokosha. Unofanira kubvisa nzira getLastName(), nokuti mushanduro 3.0.0 Iko hakuna pfungwa yekoramu mukodhi last_name. Izvi zvinoreva kuti null ichaiswa ipapo. Iwe unogona kusiya nzira uye kuwedzera cheki ye null, asi mhinduro iri nani ndeye kuve nechokwadi chekuti mune logic getSurname() wakasarudza chaiyo isiri zero kukosha.
version 1.0.0 haishandise surname column mudhatabhesi, asi shanduro 2.0.0 inoshandisa. Havapindirani, uye hapafaniri kuva nekukanganisa.
version 2.0.0 inochengetedza data mune zvese zvekare uye nyowani column, kuve nechokwadi chekudzokera kumashure
Zvinokosha. Kana iwe uine chero mibvunzo inoverenga zvinhu zvichibva pane yekare / nyowani koramu, iwe unofanirwa kuyeuka kuti iwe ikozvino une zvakapetwa maitiro (zvingangoita ivo vachiri kutama). Semuenzaniso, kana iwe uchida kuverenga nhamba yevashandisi vane zita rekupedzisira (chero iyo column inodaidzwa) yakatanga netsamba A, zvino kusvikira kutama kwedata kwapera (old → new column) unogona kunge uine data risingaenderane kana ukabvunza koramu itsva.
Anwendung rollback
Iye zvino tave neshanduro yeapp 2.0.0 uye database in v2.
Matanho:
dzosera application yako kune vhezheni 1.0.0.
version 1.0.0 haishandise koramu mudhatabhesi surname, saka rollback inofanira kubudirira
DB kuchinja
Database rine column ine zita last_name.
Flyway source 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');
Wedzera script surname.
Attention. Rangarira kuti HAUGONE KUWEDZERA chero ZVINHU ZVINOGONESA kukoramu yauri kuwedzera. Kana iwe ukadzoreredza iyo JAR, iyo yekare vhezheni haizove neruzivo nezve iyo yakawedzerwa koramu uye inozoisa otomatiki kuNULL. Kana paine muganhu wakadaro, iyo yekare application inongoputsika.
-- 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
Kuchinja kwekodhi
Isu tinochengeta data se last_nameuye mukati surname. Panguva imwe chete tinoverenga kubva last_name, sezvo koramu iyi ndiyo inonyanya kukosha. Munguva yekuendesa, zvimwe zvikumbiro zvinogona kunge zvakagadziriswa nechiitiko chekunyorera icho chisati chavandudzwa.
/*
* 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
+ "]";
}
}
Nhanho 3: Kubvisa last_name kubva kukodhi
Shanduro yeApp: 3.0.0
DB shanduro:v3
komenda
Cherechedza pa. last_name.
Nekuwedzera koramu nyowani uye kukopa zvirimo, isu takagadzira kumashure inoenderana dhatabhesi shanduko. Zvakare, kana tikadzosera iyo JAR kana kuita yekare JAR ichimhanya, haityoke panguva yekuurayiwa.
Anwendung rollback
Parizvino tine app version 3.0.0 uye database v3. Version 3.0.0 haichengetedze data kune last_name. Izvi zvinoreva kuti mu surname ruzivo rwechizvino-zvino rwakachengetwa.
Matanho:
dzosera application yako kune vhezheni 2.0.0.
version 2.0.0 inoshandisa uye last_name и surname.
version 2.0.0 achatora surname, kana isiri zero, neimwe nzira -last_name
Database shanduko
Iko hakuna shanduko yezvimiro mudhatabhesi. Iyo inotevera script inoitwa kuti iite kutama kwekupedzisira kweiyo data yekare:
-- 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;
Kuchinja kwekodhi
Cherechedza pa. last_name.
Isu tinochengeta data se last_nameuye mukati surname. Uyezve, tinoverenga kubva muchikamu last_name, sezvo iri iyo inonyanya kukosha. Panguva yekuendesa, zvimwe zvikumbiro zvinogona kugadziriswa nechiitiko chisati chavandudzwa.
/*
* 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
+ "]";
}
}
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"}
-- 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;
Mushure mekuvhara iyo repository, iwe uchaona inotevera folda chimiro.
├── 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)
Zvinyorwa
Iwe unogona kumhanya zvinyorwa zvinotsanangurwa muzvinyorwa pazasi, izvo zvicharatidza kumashure-inoenderana uye isingaenderane shanduko kune dhatabhesi.
Kuona iyo nyaya ine kumashure inoenderana shanduko, run:
./scripts/scenario_backward_compatible.sh
Uye kuona nyaya ine kumashure isingaenderane shanduko, run:
./scripts/scenario_backward_incompatible.sh
Spring Boot Muenzaniso Flyway
Mienzaniso yese inotorwa kubva Spring Boot Sample Flyway.