Ҷойгиркунии сифр ва пойгоҳи додаҳо

Ҷойгиркунии сифр ва пойгоҳи додаҳо

Ин мақола ба таври муфассал шарҳ медиҳад, ки чӣ гуна ҳалли масъалаҳои мутобиқати пойгоҳи додаҳо ҳангоми ҷойгиркунӣ. Мо ба шумо мегӯям, ки агар шумо кӯшиш кунед, ки бидуни омодагии пешакӣ ҷойгир кунед, бо барномаҳои истеҳсолии шумо чӣ рӯй дода метавонад. Сипас, мо марҳилаҳои давраи ҳаёти барномаро мегузарем, ки барои сифр вақти бекорӣ лозиманд (тақрибан. хатти: минбаъд - сифр бекористии). Натиҷаи амалиётҳои мо ин аст, ки тағир додани пойгоҳи додаҳои ба ақиб номувофиқ ба тарзи ба ақиб мувофиқ татбиқ карда шавад.

Агар шумо хоҳед, ки мисолҳои рамзро аз мақола бифаҳмед, шумо метавонед онҳоро дар ин ҷо пайдо кунед GitHub.

Муқаддима

Ҷойгиркунии бефосилаи сифр

Чӣ мистик ба кор андохтани бекористии сифр? Шумо метавонед бигӯед, ки ин вақте аст, ки барномаи шумо тавре ҷойгир карда мешавад, ки шумо метавонед версияи нави барномаро ба истеҳсолот бомуваффақият ҷорӣ кунед, дар ҳоле ки корбар мавҷуд набудани онро пайхас намекунад. Аз нуқтаи назари корбар ва ширкат, ин беҳтарин сенарияи густариши имконпазир аст, зеро он имкон медиҳад, ки хусусиятҳои нав ҷорӣ карда шаванд ва хатогиҳо бидуни халал ислоҳ карда шаванд.

Чӣ тавр ба ин ноил шудан мумкин аст? Якчанд роҳҳо вуҷуд доранд, яке аз онҳо ин аст:

  • версияи №1 хидмати худро ҷойгир кунед
  • интиқоли пойгоҳи додаҳоро иҷро кунед
  • Версияи №2-и хидмати худро дар баробари версияи №1 ҷойгир кунед
  • хамин ки шумо мебинед, ки версияи №2 ба таври лозима кор мекунад, версияи №1-ро хориҷ кунед
  • омода!

Осон, ҳамин тавр не? Мутаассифона, ин чандон оддӣ нест ва мо онро баъдтар муфассал баррасӣ хоҳем кард. Акнун биёед боз як раванди хеле маъмули ҷойгиркуниро тафтиш кунем - ҷойгиркунии сабзи кабуд.

Оё шумо ягон бор шунидаед ҷойгиркунии сабз кабуд? Cloud Foundry ин корро хеле осон мекунад. Танҳо нигоҳ кунед Ин мақола, ки мо инро муфассалтар тасвир мекунем. Барои мухтасар хулоса кардан, биёед ба шумо хотиррасон кунем, ки чӣ гуна ҷойгиркунии сабзи кабудро анҷом диҳед:

  • боварӣ ҳосил кунед, ки ду нусхаи коди истеҳсолии шумо («кабуд» ва «сабз») кор мекунад;
  • тамоми ҳаракати нақлиётро ба муҳити кабуд равона кунед, яъне. то ки URL-ҳои истеҳсолӣ ба он ҷо ишора кунанд;
  • ҳама тағйироти барномаро дар муҳити сабз ҷойгир ва санҷед;
  • urlҳоро аз муҳити кабуд ба муҳити сабз гузаронед

Ҷойгиркунии сабзи кабуд равишест, ки ба шумо имкон медиҳад ба осонӣ хусусиятҳои навро бидуни ташвиш дар бораи шикастани истеҳсолот ворид кунед. Ин ба он вобаста аст, ки ҳатто агар чизе рӯй диҳад, шумо метавонед ба осонӣ ба муҳити қаблӣ баргардед, ки танҳо бо пахш кардани тугмаи гузаред.

Пас аз хондани ҳама чизҳои дар боло зикршуда, шумо метавонед саволе диҳед: Бекоркунии сифр бо густариши кабуди сабз чӣ иртибот дорад?

Хуб, онҳо умумияти зиёде доранд, зеро нигоҳ доштани ду нусхаи як муҳит барои нигоҳ доштани онҳо дучанд кӯшишро талаб мекунад. Ин аст, ки баъзе дастаҳо даъво доранд Мартин Фаулер, як варианти ин равишро риоя кунед:

Варианти дигар ин истифода бурдани ҳамон як пойгоҳи додаҳо, эҷод кардани коммутаторҳои кабуд-сабз барои қабатҳои веб ва домен мебошад. Дар ин равиш, базаи маълумот метавонад аксар вақт мушкилот эҷод кунад, хусусан вақте ки шумо бояд схемаи онро барои дастгирии версияи нави нармафзор тағир диҳед.

Ва дар ин ҷо мо ба мушкилоти асосӣ дар ин мақола меоем. Пойгоҳи додаҳо. Биёед бори дигар ба ин ибора назар андозем.

интиқоли пойгоҳи додаҳоро иҷро кунед.

Акнун шумо бояд ба худ савол диҳед - чӣ мешавад, агар тағир додани пойгоҳи додаҳо ба ақиб мувофиқат накунад? Оё версияи якуми барнома вайрон намешавад? Дар асл, маҳз ҳамин чиз рӯй хоҳад дод...

Ҳамин тавр, ҳатто сарфи назар аз бартариҳои бузурги бекористии сифр / истихроҷи сабзи кабуд, ширкатҳо майл доранд, ки равандҳои бехатартари зеринро барои ҷойгиркунии замимаҳои худ риоя кунанд:

  • бастаро бо версияи нави барнома омода кунед
  • як барномаи коркунандаро қатъ кунед
  • скриптҳоро барои интиқол додани пойгоҳи додаҳо иҷро кунед
  • версияи нави барномаро ҷойгир ва оғоз кунед

Дар ин мақола, мо муфассал шарҳ медиҳем, ки чӣ гуна шумо метавонед бо пойгоҳи додаҳо ва коди худ кор кунед, то аз истихроҷи сифр вақти бекорӣ истифода баред.

Мушкилоти пойгоҳи додаҳо

Агар шумо як барномаи бидуни шаҳрвандӣ дошта бошед, ки ягон маълумотро дар пойгоҳи додаҳо нигоҳ намедорад, шумо метавонед дарҳол ҷойгиркунии вақти сифрро ба даст оред. Мутаассифона, аксари нармафзорҳо бояд маълумотро дар ҷое нигоҳ доранд. Ин аст, ки чаро шумо бояд пеш аз ворид кардани тағирот дар схема ду маротиба фикр кунед. Пеш аз он ки мо ба тафсилоти чӣ гуна тағир додани схема шинос шавем, то ҷобаҷогузории бефаъолият имконпазир бошад, биёед аввал ба схемаи нусхабардорӣ таваҷҷӯҳ кунем.

Схемаи версия

Дар ин мақола мо истифода хоҳем кард Роҳи парвоз ҳамчун воситаи идоракунии версия (тақрибан. Тарҷума: сухан дар бораи муҳоҷирати пойгоҳи додаҳо меравад). Табиист, ки мо инчунин як замимаи Spring Boot менависем, ки дорои дастгирии Flyway дарунсохта шудааст ва ҳангоми насб кардани контексти барнома муҳоҷирати схемаро иҷро мекунад. Ҳангоми истифодаи Flyway, шумо метавонед скриптҳои муҳоҷиратро дар ҷузвдони лоиҳаҳои худ нигоҳ доред (бо нобаёнӣ дар classpath:db/migration). Дар ин ҷо шумо метавонед як мисоли чунин файлҳои муҳоҷиратро бинед

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

Дар ин мисол мо 4 скрипти муҳоҷиратро мебинем, ки агар қаблан иҷро нашуда бошанд, пас аз оғози барнома яке паси дигар иҷро карда мешаванд. Биёед ба яке аз файлҳо назар кунем (V1__init.sql) хамчун мисол.

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

Ҳама чиз комилан фаҳмо аст: шумо метавонед SQL-ро истифода баред, то муайян кунед, ки пойгоҳи додаи шумо чӣ гуна бояд тағир дода шавад. Барои маълумоти бештар дар бораи Spring Boot ва Flyway, санҷед Ҳуҷҷатҳои баҳорӣ.

Бо истифода аз асбоби идоракунии манбаъ бо Spring Boot, шумо 2 бартариҳои калон мегиред:

  • шумо тағйироти пойгоҳи додаҳоро аз тағироти код ҷудо мекунед
  • Муҳоҷирати пойгоҳи додаҳо дар баробари паҳн кардани барномаи шумо, яъне. раванди ҷойгиркунии шумо содда карда шудааст

Бартараф кардани мушкилоти пойгоҳи додаҳо

Дар фасли навбатии мақола, мо ба баррасии ду равиш барои тағир додани пойгоҳи додаҳо тамаркуз хоҳем кард.

  • номувофиқӣ ба ақиб
  • мутобиқати ақиб

Якум ҳамчун огоҳӣ баррасӣ мешавад, ки шумо набояд бе тайёрии пешакӣ ҷойгиркунии бефосиларо анҷом диҳед... Дуюм роҳи ҳалли худро дар бораи он, ки чӣ гуна шумо метавонед ҷойгиркуниро бидуни бекоркунӣ иҷро кунед ва ҳамзамон мутобиқати ақибро нигоҳ доред.

Лоиҳаи мо, ки мо дар болои он кор хоҳем кард, як барномаи оддии Spring Boot Flyway хоҳад буд, ки дорои он аст Person с first_name и last_name дар базаи маълумот (тақрибан. тарҷума: Person миз аст ва first_name и last_name — ин майдонхо дар он мебошанд). Мо мехоҳем номашро иваз кунем last_name в surname.

Тахминхо

Пеш аз он ки мо ба тафсилот ворид шавем, мо бояд дар бораи замимаҳои худ як чанд фарзия ҳастем. Натиҷаи асосие, ки мо мехоҳем ба даст орем, раванди хеле содда хоҳад буд.

Эзоҳ. Business PRO-TIP. Соддасозии равандҳо метавонад ба шумо барои дастгирӣ пули зиёдеро сарфа кунад (ҳар қадаре ки шумо дар ширкати худ кор кунед, ҳамон қадар пулро сарфа карда метавонед)!

Баргардонидани пойгоҳи додаҳо лозим нест

Ин раванди густаришро осон мекунад (баъзе баргардонидани пойгоҳи додаҳо, ба монанди баргардонидани ҳазф, қариб ғайриимкон аст). Мо баргардонидани танҳо барномаҳоро бартарӣ медиҳем. Бо ин роҳ, ҳатто агар шумо пойгоҳи додаҳои гуногун дошта бошед (масалан, SQL ва NoSQL), лӯлаи густариши шумо якхела хоҳад буд.

Бозгашти як версияи барнома бояд Ҳамеша имконпазир бошад (на бештар)

Бозгашт бояд танҳо ҳангоми зарурат анҷом дода шавад. Агар дар версияи ҷорӣ хатое мавҷуд бошад, ки ба осонӣ ислоҳ карда нашавад, мо бояд ба версияи охирини корӣ баргардем. Мо тахмин мезанем, ки ин версияи охирини корӣ версияи қаблӣ аст. Нигоҳ доштани код ва мутобиқати пойгоҳи додаҳо барои зиёда аз як паҳнкунӣ хеле душвор ва гарон хоҳад буд.

Эзоҳ. Барои хониши бештар, дар ин мақола мо версияи асосии барномаро тағир медиҳем.

Қадами 1: Ҳолати ибтидоӣ

Нусхаи барнома: 1.0.0
Версияи DB: v1

шарҳ

Ин ҳолати ибтидоии барнома хоҳад буд.

Тағироти пойгоҳи додаҳо

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

Тағироти код

Барнома маълумоти шахсро дар 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
                + "]";
    }
}

Номгузории сутуни ба ақиб номувофиқ

Биёед мисоли тағир додани номи сутунро бубинем:

Диққат. Мисоли зерин қасдан чизҳоро вайрон мекунад. Мо инро барои нишон додани мушкилоти мутобиқати пойгоҳи додаҳо нишон медиҳем.

Нусхаи барнома: 2.0.0.BAD

Версияи DB: v2bad

шарҳ

Тағйироти ҷорӣ ба мо имкон намедиҳад, ки дар як вақт ду мисолро (кӯҳна ва нав) иҷро кунем. Ҳамин тариқ, ба даст овардани истинод ба сифр вақти бекорӣ душвор хоҳад буд (агар пиндоштҳо ба назар гирифта шаванд, ин воқеан ғайриимкон аст).

Санҷиши A/B

Вазъияти ҳозира ин аст, ки мо версияи барнома дорем 1.0.0, дар истехсолот чорй карда шуда, базаи v1. Мо бояд як нусхаи дуюми барнома, версияро ҷойгир кунем 2.0.0.BAD, ва базаи маълумотро навсозӣ кунед v2bad.

Қадамҳо:

  1. намунаи нави барномаи версия ҷойгир карда мешавад 2.0.0.BADки базаи маълумотро нав мекунад v2bad
  2. дар пойгоҳи додаҳо v2bad сутун last_name дигар вуҷуд надорад - он ба тағйир дода шуд surname
  3. Навсозии пойгоҳи додаҳо ва барномаҳо бомуваффақият анҷом ёфт ва баъзе мисолҳо иҷро мешаванд 1.0.0, дигарон - дар 2.0.0.BAD. Ҳама чиз ба базаи маълумот пайваст карда шудааст v2bad
  4. ҳама ҳолатҳои версия 1.0.0 ба партофтани хатогиҳо шурӯъ мекунанд, зеро онҳо кӯшиш мекунанд, ки маълумотро ба сутун ворид кунанд last_nameки дигар вучуд надорад
  5. ҳама ҳолатҳои версия 2.0.0.BAD бе мушкилот кор мекунад

Тавре ки шумо мебинед, агар мо ба пойгоҳи додаҳо ва барнома тағиротҳои ба ақиб номувофиқ ворид кунем, санҷиши A/B ғайриимкон аст.

Бозгашти барнома

Фарз мекунем, ки пас аз кӯшиши ҷойгиркунии A/B (тақрибан. per.: муаллиф эҳтимол дар ин ҷо санҷиши A/B-ро дар назар дошт) мо тасмим гирифтем, ки мо бояд барномаро ба версия баргардонем 1.0.0. Фарз мекунем, ки мо намехоҳем базаи маълумотро баргардонем.

Қадамҳо:

  1. мо намунаи барномаи версияро қатъ мекунем 2.0.0.BAD
  2. базаи маълумот хануз хам v2bad
  3. аз версия 1.0.0 намефаҳмад, ки ин чӣ аст surname, мо хатогиҳоро мебинем
  4. ҷаҳаннам фуҷур шуд, мо дигар баргашта наметавонем

Тавре ки шумо мебинед, агар мо ба пойгоҳи додаҳо ва барнома тағиротҳои ба ақиб номувофиқ ворид кунем, мо наметавонем ба версияи қаблӣ баргардем.

Сабти иҷрои скрипт

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

Тағироти пойгоҳи додаҳо

Скрипти муҳоҷират, ки номашро иваз мекунад last_name в surname

Скрипти манбаи 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');

Скрипт, ки номашро иваз мекунад last_name.

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

Тағироти код

Мо номи майдонро иваз кардем lastName ба surname.

Иваз кардани номи сутун бо роҳи ба ақиб мувофиқ

Ин ҳолати маъмултаринест, ки мо метавонем дучор шавем. Мо бояд тағиротҳои ба ақиб номувофиқ ворид кунем. Мо аллакай исбот карда будем, ки барои ҷойгиркунии вақти сифрӣ, мо набояд танҳо бе қадамҳои иловагӣ интиқоли пойгоҳи додаҳоро татбиқ кунем. Дар ин фасли мақола, мо 3 ҷобаҷогузории барномаро дар якҷоягӣ бо интиқоли пойгоҳи додаҳо анҷом медиҳем, то ба натиҷаи дилхоҳ ҳангоми нигоҳ доштани мутобиқати ақиб ноил гардем.

Эзоҳ. Ёдовар мешавем, ки мо базаи версия дорем v1. Он дорои сутунҳо мебошад first_name и last_name. Мо бояд тағир диҳем last_name ба surname. Мо инчунин версияи барнома дорем 1.0.0, ки хануз ба кор бурда нашудааст surname.

Қадами 2: Илова кардани насаб

Нусхаи барнома: 2.0.0
Версияи DB: v2

шарҳ

Бо илова кардани сутуни нав ва нусхабардории мундариҷаи он, мо тағиротҳои ба ақиб мувофиқи пойгоҳи додаҳоро эҷод мекунем. Дар айни замон, агар мо JAR-ро баргардонем ё JAR-и кӯҳна кор карда истода бошем, он дар вақти иҷро мешиканад.

Мо версияи навро мебарорем

Қадамҳо:

  1. интиқоли пойгоҳи додаҳо барои сохтани сутуни нав surname. Акнун версияи DB-и шумо v2
  2. нусхабардории маълумот аз last_name в surname. Диққат диҳедки агар шумо ин маълумотҳои зиёде дошта бошед, шумо бояд муҳоҷирати партияро баррасӣ кунед!
  3. рамзи дар куҷо истифода мешаванд, нависед ХАР ДУ и новыйва сола сутун. Акнун версияи барномаи шумо 2.0.0
  4. арзишро аз сутун хонед surname, агар не null, ё аз лast_name, агар surname муайян нашудааст. Шумо метавонед нест кунед getLastName() аз код, зеро он мебарояд null ҳангоми баргардонидани аризаи шумо аз 3.0.0 ба 2.0.0.

Агар шумо Spring Boot Flyway-ро истифода баред, ин ду қадам ҳангоми оғози версия иҷро карда мешаванд 2.0.0 барномаҳо. Агар шумо асбоби версияи пойгоҳи додаро дастӣ иҷро кунед, шумо бояд ду кори гуногунро иҷро кунед (аввал версияи db-ро дастӣ навсозӣ кунед ва сипас барномаи навро ҷойгир кунед).

Ин муҳим аст. Дар хотир доред, ки сутуни навтаъсис НАБОЯД бошад ҲАСТ НЕСТ. Агар шумо баргардонед, барномаи кӯҳна дар бораи сутуни нав намедонад ва онро дар давоми он насб намекунад Insert. Аммо агар шумо ин маҳдудиятро илова кунед ва DB шумо хоҳад буд v2, ин муқаррар кардани арзиши сутуни навро талаб мекунад. ки боиси вайрон шудани махдудиятхо мегардад.

Ин муҳим аст. Шумо бояд усулро хориҷ кунед getLastName(), зеро дар версия 3.0.0 Дар кодекс мафҳуми сутун вуҷуд надорад last_name. Ин маънои онро дорад, ки дар он ҷо нул муқаррар карда мешавад. Шумо метавонед усулро тарк кунед ва чекҳоро илова кунед null, аммо ҳалли хеле беҳтар мебуд боварӣ ҳосил кунед, ки дар мантиқ getSurname() шумо арзиши дурусти сифрро интихоб кардед.

Санҷиши A/B

Вазъияти ҳозира ин аст, ки мо версияи барнома дорем 1.0.0, дар истехсолот чорй карда шудааст ва базаи дар v1. Мо бояд як нусхаи дуюми барномаи версияро ҷойгир кунем 2.0.0ки базаи маълумотро ба v2.

Қадамҳо:

  1. намунаи нави барномаи версия ҷойгир карда мешавад 2.0.0ки базаи маълумотро нав мекунад v2
  2. дар айни замон баъзе дархостҳо аз ҷониби мисолҳои версия коркард карда шуданд 1.0.0
  3. навсозӣ бомуваффақият буд ва шумо якчанд мисолҳои иҷрокунандаи барномаи версия доред 1.0.0 ва версияҳои дигар 2.0.0. Ҳама бо пойгоҳи додаҳо муошират мекунанд v2
  4. версия 1.0.0 сутуни фамилияро дар база истифода намебарад, балки версияи 2.0.0 истифода мебарад. Онхо ба хамдигар халал намерасонанд ва набояд хато бошад.
  5. версия 2.0.0 маълумотро ҳам дар сутуни кӯҳна ва ҳам нав нигоҳ медорад ва мутобиқати ақибро таъмин мекунад

Ин муҳим аст. Агар шумо ягон дархосте дошта бошед, ки ашёро дар асоси арзишҳои сутуни кӯҳна/нав ҳисоб мекунанд, шумо бояд дар хотир доред, ки шумо ҳоло арзишҳои такрорӣ доред (эҳтимолияти онҳо ҳоло ҳам муҳоҷират мекунанд). Масалан, агар шумо хоҳед, ки шумораи корбаронеро ҳисоб кунед, ки насабашон (сутун чӣ ном дорад) бо ҳарф сар шудааст A, пас то ба анҷом расидани интиқоли маълумот (oldnew сутун) шумо метавонед маълумоти номувофиқ дошта бошед, агар шумо сутуни навро пурсед.

Бозгашти барнома

Ҳоло мо версияи барнома дорем 2.0.0 ва базаи маълумот дар v2.

Қадамҳо:

  1. барномаи худро ба версия баргардонед 1.0.0.
  2. версия 1.0.0 сутунро дар база истифода намебарад surname, Пас, бозгашт бояд муваффақ бошад

Тағироти DB

Дар базаи маълумот сутуни ном дорад last_name.

Скрипти манбаи 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');

Иловаи скрипт surname.

Диққат. Дар хотир доред, ки шумо наметавонед ба сутуне, ки шумо илова карда истодаед, ягон маҳдудияти NE NULL ИЛОВА НАМОЕД. Агар шумо JAR-ро баргардонед, версияи кӯҳна дар бораи сутуни иловашуда тасаввуроте надорад ва онро ба таври худкор ба NULL муқаррар мекунад. Агар чунин маҳдудият вуҷуд дошта бошад, барномаи кӯҳна танҳо вайрон мешавад.

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

Тағироти код

Мо маълумотро ҳамчун last_name, ва дар surname. Дар баробари ин мо аз 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;
    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
                + "]";
    }
}

Қадами 3: Хориҷ кардани насаб аз код

Нусхаи барнома: 3.0.0

Версияи DB:v3

шарҳ

Шарҳ пер.: Эҳтимол, дар мақолаи аслӣ муаллиф матни ин блокро иштибоҳан аз қадами 2 нусхабардорӣ кардааст. Дар ин марҳила, бояд дар коди барнома тағирот ворид карда шавад, ки ба бартараф кардани функсияе, ки сутунро истифода мебарад, равона карда шудааст. last_name.

Бо илова кардани сутуни нав ва нусхабардории мундариҷаи он, мо тағиротҳои ба ақиб мувофиқи пойгоҳи додаҳоро эҷод кардем. Инчунин, агар мо JAR-ро баргардонем ё JAR-и кӯҳна кор кунад, он ҳангоми иҷроиш шикаста намешавад.

Бозгашти барнома

Дар айни замон мо версияи барнома дорем 3.0.0 ва базаи маълумот v3. Версия 3.0.0 маълумотро захира намекунад last_name. Ин маънои онро дорад, ки дар surname маълумоти навтарин захира карда мешавад.

Қадамҳо:

  1. барномаи худро ба версия баргардонед 2.0.0.
  2. версия 2.0.0 истифода мебарад ва last_name и surname.
  3. версия 2.0.0 мегирад surname, агар он сифр набошад, дар акси ҳол -last_name

Тағироти пойгоҳи додаҳо

Дар базаи маълумот ягон тағйироти сохторӣ вуҷуд надорад. Барои анҷом додани интиқоли ниҳоии маълумоти кӯҳна скрипти зерин иҷро карда мешавад:

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

Тағироти код

Шарҳ пер.: Тавсифи ин блок низ аз ҷониби муаллиф иштибоҳан аз қадами 2 нусхабардорӣ шудааст. Мувофиқи мантиқи мақола, тағирот дар код дар ин марҳила бояд ба хориҷ кардани унсурҳое, ки бо сутун кор мекунанд, равона карда шаванд. last_name.

Мо маълумотро ҳамчун last_name, ва дар surname. Илова бар ин, мо аз сутун мехонем 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 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
                + "]";
    }
}

Қадами 4: Хориҷ кардани насаб аз базаи маълумот

Нусхаи барнома: 4.0.0

Версияи DB: v4

шарҳ

Аз сабаби он, ки рамзи версия 3.0.0 сутунро истифода набурд last_name, дар давоми иҷрои ягон чизи бад рӯй хоҳад дод, агар мо меғелонад бозгашт ба 3.0.0 пас аз нест кардани сутун аз базаи маълумот.

Сабти иҷрои скрипт

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

Нисбатан v3 мо танҳо сутунро хориҷ мекунем last_name ва маҳдудиятҳои гумшударо илова кунед.

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

Тағироти код

Дар код ягон тағйирот вуҷуд надорад.

хулоса

Мо бомуваффақият тағир додани номи сутуни ба ақиб номувофиқро тавассути иҷрои якчанд ҷойгиркунии ба ақиб мувофиқ татбиқ кардем. Дар зер хулосаи амалҳои иҷрошуда оварда шудааст:

  1. ҷойгиркунии версияи барнома 1.0.0 с v1 схемаи пойгоҳи додаҳо (номи сутун = last_name)
  2. ҷойгиркунии версияи барнома 2.0.0, ки маълумотро дар last_name и surname. Дар ариза аз last_name. Пойгоҳи маълумот дар версия аст v2дорои сутунҳои монанди last_name, ва surname. surname нусхаи лast_name. (ЭЗОҲ: Ин сутун набояд маҳдудияти нул надошта бошад)
  3. ҷойгиркунии версияи барнома 3.0.0, ки танҳо маълумотро дар surname ва аз насаб мехонад. Дар бораи базаи маълумот бошад, муҳоҷирати охирин сурат мегирад last_name в surname. Ҳамчунин маҳдудият ҲАСТ НЕСТ аз last_name. Пойгоҳи маълумот ҳоло дар версия аст v3
  4. ҷойгиркунии версияи барнома 4.0.0 - ба кодекс ягон тағйирот ворид карда намешавад. Ҷойгиркунии пойгоҳи додаҳо v4, ки хориҷ мекунад last_name. Дар ин ҷо шумо метавонед ҳама гуна маҳдудиятҳои гумшударо ба пойгоҳи додаҳо илова кунед.

Бо риояи ин равиш, шумо ҳамеша метавонед як версияро бе вайрон кардани мутобиқати пойгоҳи додаҳо/барномаҳо баргардонед.

рамз

Ҳама кодҳои дар ин мақола истифодашуда дар ин ҷо дастрасанд Github. Дар зер тавсифи иловагӣ оварда шудааст.

Лоиҳаҳо

Пас аз клон кардани анбор, шумо сохтори папкаи зеринро хоҳед дид.

├── boot-flyway-v1              - 1.0.0 version of the app with v1 of the schema
├── boot-flyway-v2              - 2.0.0 version of the app with v2 of the schema (backward-compatible - app can be rolled back)
├── boot-flyway-v2-bad          - 2.0.0.BAD version of the app with v2bad of the schema (backward-incompatible - app cannot be rolled back)
├── boot-flyway-v3              - 3.0.0 version of the app with v3 of the schema (app can be rolled back)
└── boot-flyway-v4              - 4.0.0 version of the app with v4 of the schema (app can be rolled back)

Скриптҳо

Шумо метавонед скриптҳои дар скриптҳои зер тавсифшударо иҷро кунед, ки тағиротҳои ба ақиб мувофиқ ва номувофиқро дар пойгоҳи додаҳо нишон медиҳанд.

Дидан парванда бо тағйироти ба ақиб мувофиқ, иҷро кунед:

./scripts/scenario_backward_compatible.sh

Ва дидан парванда бо тағйироти ба ақиб номувофиқ, иҷро кунед:

./scripts/scenario_backward_incompatible.sh

Намунаи парвози баҳорӣ

Ҳама мисолҳо аз он гирифта шудаанд Spring Boot Sample Flyway.

Шумо метавонед аз назар гузаронед http://localhost:8080/flyway, рӯйхати скриптҳо вуҷуд дорад.

Ин мисол инчунин консоли H2-ро дар бар мегирад (дар http://localhost:8080/h2-console) то шумо метавонед ҳолати пойгоҳи додаҳоро бубинед (URL-и пешфарз jdbc аст jdbc:h2:mem:testdb).

ба таври илова

Инчунин мақолаҳои дигарро дар блоги мо хонед:

Манбаъ: will.com

Илова Эзоҳ