د صفر ډاؤن وخت ګمارنه او ډیټابیسونه

د صفر ډاؤن وخت ګمارنه او ډیټابیسونه

دا مقاله په تفصیل سره تشریح کوي چې څنګه په ګمارلو کې د ډیټابیس مطابقت مسلې حل کړئ. موږ به تاسو ته ووایو چې ستاسو د تولید غوښتنلیکونو سره څه پیښ کیدی شي که تاسو د لومړني چمتووالي پرته د ځای په ځای کولو هڅه وکړئ. بیا به موږ د غوښتنلیک د ژوند دورې مرحلو ته لاړ شو چې د صفر ځنډ وخت ته اړتیا لري (نږدې لین: نور - د صفر ځنډ وخت). زموږ د عملیاتو پایله به دا وي چې د شاته - متناسب ډیټابیس بدلون په شاته - مطابقت لرونکي ډول پلي کړئ.

که تاسو غواړئ د مقالې څخه د کوډ مثالونو پوه شئ، تاسو کولی شئ دوی ومومئ GitHub.

پېژندنه

د صفر ځنډ وخت ځای په ځای کول

څومره صوفیانه د صفر ځنډ وخت ځای په ځای کول؟ تاسو کولی شئ ووایاست دا هغه وخت دی کله چې ستاسو غوښتنلیک په داسې ډول ځای په ځای شوی وي چې تاسو کولی شئ په بریالیتوب سره تولید ته د غوښتنلیک نوې نسخه معرفي کړئ ، پداسې حال کې چې کارونکي د هغې شتون نه ګوري. د کارونکي او شرکت له نظره، دا د ځای پرځای کولو ترټولو غوره سناریو ده ځکه چې دا اجازه ورکوي چې نوي ځانګړتیاوې معرفي شي او بګونه پرته له خنډ څخه حل شي.

دا څنګه ترلاسه کول؟ ډیری لارې شتون لري، دلته یو له دوی څخه دی:

  • ستاسو د خدمت نسخه نمبر 1 ځای په ځای کړئ
  • د ډیټابیس مهاجرت ترسره کول
  • ستاسو د خدماتو # 2 نسخه د نسخه # 1 سره موازي ځای په ځای کړئ
  • هرڅومره ژر چې تاسو وګورئ چې دا نسخه نمبر 2 کار کوي لکه څنګه چې باید وي، نسخه نمبر 1 لرې کړئ
  • چمتو!

اسانه، دا نه ده؟ له بده مرغه، دا دومره ساده نه دی، او موږ به وروسته په تفصیل سره وګورو. اوس راځئ چې د ځای پرځای کولو بل خورا عام پروسه وګورو - blue green deployment.

ایا تاسو کله هم اوریدلي دي؟ نیلي شنه ځای پرځای کول؟ کلاوډ فاونډري دا خورا اسانه کوي. یوازې وګورئ دا مقاله، چیرې چې موږ دا په ډیر تفصیل سره تشریح کوو. د لنډیز کولو لپاره، اجازه راکړئ تاسو ته یادونه وکړو چې څنګه د نیلي شنه ګمارنې ترسره کول:

  • ډاډ ترلاسه کړئ چې ستاسو د تولید کوډ دوه کاپي ("نیلي" او "شین") کار کوي؛
  • ټول ترافیک نیلي چاپیریال ته مستقیم کړئ ، د بیلګې په توګه نو د تولید URLs هلته په ګوته کوي؛
  • په شنه چاپیریال کې د غوښتنلیک ټول بدلونونه ځای په ځای کول او ازموینه کول؛
  • یو آر ایل له نیلي څخه شنه چاپیریال ته بدل کړئ

د نیلي شنه ګمارنه یوه داسې طریقه ده چې تاسو ته اجازه درکوي په اسانۍ سره د تولید ماتولو په اړه اندیښنه پرته نوي ب featuresې معرفي کړئ. دا د دې حقیقت له امله دی چې حتی که یو څه پیښ شي ، تاسو کولی شئ په ساده ډول د "یو سویچ په وهلو" سره مخکیني چاپیریال ته بیرته راشئ.

د پورتنیو ټولو لوستلو وروسته ، تاسو ممکن پوښتنه وکړئ: د صفر کم وخت د نیلي شنه پلي کولو سره څه تړاو لري؟

ښه ، دوی خورا ډیر مشترک لري ، ځکه چې د ورته چاپیریال دوه کاپي ساتل د دوی ساتلو لپاره دوه چنده هڅې ته اړتیا لري. له همدې امله ځینې ټیمونه ادعا کوي مارتین فولرد دې طریقې یو توپیر تعقیب کړئ:

بل اختیار د ورته ډیټابیس کارولو لپاره دی، د ویب او ډومین پرتونو لپاره نیلي شنه سویچونه رامینځته کول. پدې طریقه کې، ډیټابیس اکثرا یوه ستونزه وي، په ځانګړې توګه کله چې تاسو د سافټویر نوې نسخه مالتړ لپاره د سکیما بدلولو ته اړتیا لرئ.

او دلته موږ په دې مقاله کې اصلي ستونزې ته راځو. ډیټابیس. راځئ چې دې جملې ته یو بل نظر وکړو.

د ډیټابیس مهاجرت ترسره کول.

اوس تاسو باید له ځانه پوښتنه وکړئ - څه شی که د ډیټابیس بدلون د شاته سره مطابقت نلري؟ ایا زما د اپلیکیشن لومړۍ نسخه نه ماتیږي؟ په حقیقت کې، دا هغه څه دي چې واقع کیږي ...

نو، حتی د صفر کم وخت / نیلي شنه ګمارنې لوی ګټو سره، شرکتونه د خپلو غوښتنلیکونو ځای پرځای کولو لپاره لاندې خوندي پروسې تعقیبوي:

  • د غوښتنلیک نوې نسخه سره بسته چمتو کړئ
  • یو روان غوښتنلیک بند کړئ
  • د ډیټابیس د لیږدولو لپاره سکریپټونه چلول
  • د غوښتنلیک نوې نسخه ځای په ځای کړئ او پیل کړئ

پدې مقاله کې ، موږ به توضیح کړو چې تاسو څنګه کولی شئ د خپل ډیټابیس او کوډ سره کار وکړئ ترڅو د صفر کم وخت ګمارنې څخه ګټه پورته کړئ.

د ډیټابیس مسلې

که تاسو بې ریاسته غوښتنلیک لرئ چې په ډیټابیس کې هیڅ معلومات نه ساتي، تاسو کولی شئ سمدلاسه د صفر ځنډ وخت ځای په ځای کړئ. له بده مرغه، ډیری سافټویر اړتیا لري چې ډاټا چیرته ذخیره کړي. له همدې امله تاسو باید په سرکټ کې کوم بدلون کولو دمخه دوه ځله فکر وکړئ. مخکې لدې چې موږ د سکیما بدلولو څرنګوالي په اړه توضیحاتو ته ورسیږو ترڅو د وخت نه ځنډول ممکن وي ، راځئ لومړی د نسخې سکیما باندې تمرکز وکړو.

د نسخې سکیم

پدې مقاله کې به موږ وکاروو الوتنه د نسخې کنټرول وسیلې په توګه (نږدې ژباړه: موږ د ډیټابیس مهاجرت په اړه خبرې کوو). په طبیعي ډول، موږ به د پسرلي بوټ غوښتنلیک هم ولیکئ چې د فلای وے ملاتړ یې جوړ کړی او د غوښتنلیک شرایط تنظیم کولو پرمهال به د سکیما مهاجرت ترسره کړي. کله چې د 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 and Flyway‎‏ پاڼې اړوند نور معلومات په فسبوک کې اوګورئ د پسرلي بوټ اسناد.

د پسرلي بوټ سره د سرچینې کنټرول وسیلې په کارولو سره ، تاسو 2 لوی ګټې ترلاسه کوئ:

  • تاسو د ډیټابیس بدلونونه د کوډ بدلونونو څخه جلا کوئ
  • د ډیټابیس مهاجرت ستاسو د غوښتنلیک رول آوټ سره پیښیږي ، د مثال په توګه ستاسو د ګمارلو پروسه ساده ده

د ډیټابیس ستونزې حل کول

د مقالې په راتلونکې برخه کې، موږ به د ډیټابیس بدلونونو لپاره دوه طریقو ته پام وکړو.

  • شاته نه مطابقت
  • شاته مطابقت

لومړی به د اخطار په توګه وګڼل شي چې تاسو باید له لومړني چمتووالي پرته د صفر ځنډ وخت ګمارنه ترسره نه کړئ ... دوهم یو حل وړاندې کوي چې تاسو څنګه کولی شئ پرته له ځنډ څخه ګمارنه ترسره کړئ او په ورته وخت کې شاته مطابقت وساتئ.

زموږ پروژه چې موږ به یې کار کوو د پسرلي بوټ فلای وی یو ساده غوښتنلیک وي چې لري Person с first_name и last_name په ډیټابیس کې (نږدې ژباړه: Person یو میز دی او first_name и last_name - دا په دې کې ساحې دي). موږ غواړو نوم بدل کړو last_name в surname.

انګیرنې

مخکې لدې چې موږ توضیحاتو ته ورسیږو ، دلته یو څو انګیرنې شتون لري چې موږ اړتیا لرو د خپلو غوښتنلیکونو په اړه جوړ کړو. اصلي پایله چې موږ یې ترلاسه کول غواړو خورا ساده پروسه وي.

نوټ. د سوداګرۍ 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

سرچینه فلای وی سکریپټ:

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، یا له l څخهast_nameکه surname معلوم نه ده. تاسو کولی شئ حذف کړئ getLastName() د کوډ څخه، ځکه چې دا به تولید شي null کله چې خپل غوښتنلیک بیرته راوباسئ 3.0.0 پورې 2.0.0.

که تاسو د پسرلي بوټ الوتنې کاروئ، دا دوه مرحلې به د نسخې پیل کولو پرمهال ترسره شي 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.

پاملرنه. په یاد ولرئ چې تاسو نشئ کولی په هغه کالم کې چې تاسو یې اضافه کوئ هیڅ غیر محدود محدودیتونه اضافه کړئ. که تاسو 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

تبصره

نوټ per.: په ښکاره ډول، په اصلي مقاله کې لیکوال په غلطۍ سره د دې بلاک متن له 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;

کوډ بدلونونه

نوټ پر. 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 د l یوه کاپي ده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

د پسرلي بوټ نمونه Flyway

ټول مثالونه ترې اخیستل شوي دي Spring Boot Sample Flyway.

تاسو کولی شئ یو نظر وګورئ http://localhost:8080/flyway، د سکریپټونو لیست شتون لري.

پدې مثال کې د H2 کنسول هم شامل دی (په http://localhost:8080/h2-console) نو تاسو کولی شئ د ډیټابیس حالت وګورئ (ډیفالټ jdbc URL دی jdbc:h2:mem:testdb).

برسیره

زموږ په بلاګ کې نورې مقالې هم ولولئ:

سرچینه: www.habr.com

Add a comment