زيرو ڊائون ٽائم ڊيپلائيمينٽ ۽ ڊيٽابيس

زيرو ڊائون ٽائم ڊيپلائيمينٽ ۽ ڊيٽابيس

هي آرٽيڪل تفصيل سان بيان ڪري ٿو ته ڪيئن حل ڪجي ڊيٽابيس ۾ مطابقت جي مسئلن کي ترتيب ڏيڻ ۾. اسان توهان کي ٻڌائينداسين ته توهان جي پيداوار جي ايپليڪيشنن سان ڇا ٿي سگهي ٿو جيڪڏهن توهان ڪوشش ڪندا ته بغير ڪنهن ابتدائي تياري جي. اسان پوءِ ايپليڪيشن لائف سائيڪل مرحلن مان گذري وينداسين جيڪي ضروري آهن ته صفر ڊائون ٽائم (لڳ ڀڳ لين: اڳتي - صفر بند وقت). اسان جي عملن جو نتيجو اهو ٿيندو ته پٺاڻ-غير مطابقت واري ڊيٽابيس جي تبديلي کي پٺاڻ-مطابقت واري انداز ۾ لاڳو ڪيو وڃي.

جيڪڏھن توھان سمجھڻ چاھيو ٿا مضمون مان ڪوڊ جا مثال، توھان انھن کي ڳولي سگھوٿا GitHub.

تعارف

صفر بند وقت جي تعیناتي

ڇا هڪ صوفياتي صفر بند وقت جي مقرري؟ توهان اهو چئي سگهو ٿا ته اهو آهي جڏهن توهان جي ايپليڪيشن اهڙي طريقي سان ترتيب ڏني وئي آهي ته توهان ڪاميابيء سان ايپليڪيشن جو هڪ نئون نسخو پيش ڪري سگهو ٿا، جڏهن ته صارف ان جي غير موجودگي کي نوٽيس نٿو ڪري. صارف ۽ ڪمپني جي نقطه نظر کان، اهو بهترين ممڪن ترتيب ڏيڻ وارو منظر آهي ڇو ته اها اجازت ڏئي ٿي ته نوان خاصيتون متعارف ڪرايا وڃن ۽ بگ کي بغير ڪنهن رڪاوٽ جي مقرر ڪيو وڃي.

اهو ڪيئن حاصل ڪجي؟ اتي ڪيترائي طريقا آھن، انھن مان ھڪڙو ھتي آھي:

  • توهان جي خدمت جو نسخو نمبر 1 ترتيب ڏيو
  • ڊيٽابيس لڏپلاڻ انجام ڏيو
  • ورزن #2 سان متوازي طور تي توهان جي خدمت جو نسخو #1 ترتيب ڏيو
  • جيئن ئي توهان ڏسو ته اهو نسخو نمبر 2 ڪم ڪري ٿو جيئن ان کي گهرجي، نسخو نمبر 1 کي هٽائي ڇڏيو
  • تيار!

آسان، آهي نه؟ بدقسمتي سان، اهو ايترو سادو ناهي، ۽ اسان ان کي بعد ۾ تفصيل سان ڏسنداسين. ھاڻي اچو ته ھڪ ٻي عام طور تي مقرري واري عمل جي جانچ ڪريون - blue green deployment.

everا توھان ڪڏھن ofو آھي نيري سائي لڳائڻ؟ Cloud Foundry هن کي انتهائي آسان بڻائي ٿو. بس ڏسو اهو مضمون، جتي اسان هن کي وڌيڪ تفصيل سان بيان ڪريون ٿا. مختصر طور تي اختصار ڪرڻ لاء، اچو ته توهان کي ياد ڏياريون ته نيري سائي جي ترتيب کي ڪيئن ڪجي:

  • پڪ ڪريو ته توهان جي پيداوار ڪوڊ جون ٻه ڪاپيون ("نيرو" ۽ "سبز") ڪم ڪن؛
  • سموري ٽرئفڪ کي نيري ماحول ڏانهن سڌو ڪريو، يعني ته جيئن پيداوار URLs اتي اشارو؛
  • سائي ماحول ۾ سڀني ايپليڪيشن تبديلين کي ترتيب ۽ جانچ ڪريو؛
  • يو آر ايل کي نيري کان سائي ماحول ۾ تبديل ڪريو

نيري سائي جي جوڙجڪ هڪ طريقو آهي جيڪو توهان کي آساني سان نئين خاصيتون متعارف ڪرائڻ جي اجازت ڏئي ٿو بغير پيداوار جي ڀڃڪڙي بابت پريشان ٿيڻ جي. اهو ان حقيقت جي ڪري آهي ته جيتوڻيڪ ڪجهه ٿئي ٿو، توهان آساني سان "سوئچ کي ڇڪڻ" ذريعي پوئين ماحول ڏانهن واپس ڪري سگهو ٿا.

مٿين سڀني کي پڙهڻ کان پوء، توهان سوال پڇي سگهو ٿا: صفر ختم ٿيڻ جو ڇا آهي نيري سائي جي ترتيب سان؟

يقينن، انهن ۾ تمام گهڻو عام آهي، ڇاڪاڻ ته ساڳئي ماحول جي ٻن نقلن کي برقرار رکڻ لاء انهن کي برقرار رکڻ لاء ٻيڻو ڪوشش جي ضرورت آهي. اهو ئي سبب آهي ته ڪجهه ٽيمون دعوي ڪن ٿيون مارٽن فولرهن طريقي جي مختلف قسمن جي پيروي ڪريو:

ٻيو اختيار ساڳيو ڊيٽابيس استعمال ڪرڻ آهي، ويب ۽ ڊومين جي تہن لاء نيري-سائي سوئچ ٺاهڻ. هن طريقي ۾، ڊيٽابيس اڪثر ڪري هڪ مسئلو ٿي سگهي ٿو، خاص طور تي جڏهن توهان کي سافٽ ويئر جي نئين نسخي کي سپورٽ ڪرڻ لاء ان جي اسڪيما کي تبديل ڪرڻ جي ضرورت آهي.

۽ هتي اسان هن مضمون ۾ بنيادي مسئلي ڏانهن ايندا. ڊيٽابيس. اچو ته هن جملي تي هڪ ٻيو نظر وجهون.

ڊيٽابيس لڏپلاڻ انجام ڏيو.

ھاڻي توھان کي پنھنجو پاڻ کان سوال پڇڻو پوندو - ڇا جيڪڏھن ڊيٽابيس جي تبديلي پوئتي موٽڻ سان مطابقت نه رکي؟ ڇا منهنجو پهريون نسخو ايپ جو وقفو نه ٿيندو؟ حقيقت ۾، ائين ئي ٿيندو ...

تنهن ڪري، صفر ڊائون ٽائم / نيري سائي جي ترتيب جي وڏي فائدن جي باوجود، ڪمپنيون انهن جي ايپليڪيشنن کي ترتيب ڏيڻ لاء هيٺين محفوظ عمل جي پيروي ڪندا آهن:

  • ايپليڪيشن جي نئين ورزن سان هڪ پيڪيج تيار ڪريو
  • هلندڙ ايپليڪيشن کي بند ڪريو
  • ڊيٽابيس کي لڏڻ لاءِ اسڪرپٽ هلائيندا
  • انسٽال ڪريو ۽ ايپليڪيشن جو نئون ورزن لانچ ڪريو

هن آرٽيڪل ۾، اسان تفصيل ڏينداسين ته توهان پنهنجي ڊيٽابيس ۽ ڪوڊ سان ڪيئن ڪم ڪري سگهو ٿا صفر ڊائون ٽائم ڊيپلائيمينٽ جو فائدو وٺڻ لاءِ.

ڊيٽابيس مسئلا

جيڪڏهن توهان وٽ هڪ بي رياست ايپليڪيشن آهي جيڪا ڊيٽابيس ۾ ڪنهن به ڊيٽا کي ذخيرو نٿو ڪري، توهان حاصل ڪري سگهو ٿا صفر ڊائون لوڊ ٽائيم فوري طور تي. بدقسمتي سان، اڪثر سافٽ ويئر کي ڊيٽا کي ذخيرو ڪرڻ جي ضرورت آهي. انهي ڪري توهان کي سرڪٽ ۾ ڪا به تبديلي ڪرڻ کان پهريان ٻه ڀيرا سوچڻ گهرجي. ان کان اڳ جو اسان تفصيل ۾ وڃون ته اسڪيما کي ڪيئن تبديل ڪيو وڃي ته جيئن بغير وقت جي ترتيب ڏيڻ ممڪن نه هجي، اچو ته پهرين ورزننگ اسڪيما تي ڌيان ڏيون.

ورجننگ اسڪيم

هن آرٽيڪل ۾ اسان استعمال ڪنداسين اڏامندڙ رستو نسخي ڪنٽرول اوزار جي طور تي (لڳ ڀڳ ترجمو: اسان ڊيٽابيس لڏپلاڻ بابت ڳالهائي رهيا آهيون). قدرتي طور تي، اسان هڪ اسپرنگ بوٽ ايپليڪيشن پڻ لکنداسين جنهن ۾ فلائي وي سپورٽ شامل آهي ۽ ايپليڪيشن جي حوالي سان ترتيب ڏيڻ دوران اسڪيما لڏپلاڻ ڪندو. 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 استعمال ڪري سگهو ٿا وضاحت ڪرڻ لاءِ ته توهان جي ڊيٽابيس کي ڪيئن تبديل ڪيو وڃي. اسپرنگ بوٽ ۽ فلائي وي بابت وڌيڪ معلومات لاءِ، چيڪ ڪريو بهار بوٽ دستاويز.

اسپرنگ بوٽ سان سورس ڪنٽرول ٽول استعمال ڪندي، توهان 2 وڏا فائدا حاصل ڪندا:

  • توھان ڊيٽابيس جي تبديلين کي ڪوڊ تبديلين کان الڳ ڪريو ٿا
  • ڊيٽابيس لڏپلاڻ توهان جي ايپليڪيشن جي رول آئوٽ سان گڏ ٿيندي آهي، يعني. توهان جي لڳائڻ جي عمل کي آسان ڪيو ويو آهي

ڊيٽابيس جي مسئلن کي حل ڪرڻ

مضمون جي ايندڙ حصي ۾، اسان ڊيٽابيس جي تبديلين جي ٻن طريقن کي ڏسڻ تي ڌيان ڏينداسين.

  • پسمانده مطابقت
  • پوئتي مطابقت

پهرين کي هڪ ڊيڄاريندڙ سمجهيو ويندو ته توهان کي ابتدائي تياري کان سواءِ صفر ڊائون ٽائم ڊيپلائيمينٽ انجام نه ڏيڻ گهرجي... ٻيو هڪ حل پيش ڪري ٿو ته ڪيئن توهان بغير ڊائون ٽائم جي ڊيپلائيمينٽ انجام ڏئي سگهو ٿا ۽ ساڳئي وقت پٺتي پيل مطابقت برقرار رکو.

اسان جو پروجيڪٽ جنهن تي اسان ڪم ڪري رهيا آهيون هڪ سادي اسپرنگ بوٽ فلائي وي ايپليڪيشن هوندي جيڪا آهي Person с first_name и last_name ڊيٽابيس ۾ (لڳ ڀڳ ترجمو: Person هڪ ٽيبل آهي ۽ فirst_name и last_name - اهي هن جا ميدان آهن). اسان نالو تبديل ڪرڻ چاهيون ٿا last_name в surname.

مفروضو

ان کان اڳ جو اسان تفصيل ۾ وڃون، اتي ڪجھ مفروضا آھن جيڪي اسان کي اسان جي ايپليڪيشنن بابت ڪرڻ جي ضرورت آھي. بنيادي نتيجو جيڪو اسان حاصل ڪرڻ چاهيون ٿا اهو هڪ بلڪل سادو عمل هوندو.

نوٽ. ڪاروباري پرو-ٽيپ. آسان ڪرڻ وارا عمل توهان کي مدد تي تمام گهڻو پئسا بچائي سگهن ٿا (وڌيڪ ماڻهو توهان پنهنجي ڪمپني لاءِ ڪم ڪري رهيا آهيو، وڌيڪ پئسا توهان بچائي سگهو ٿا)!

ڊيٽابيس کي واپس ڪرڻ جي ڪا ضرورت ناهي

هي ترتيب ڏيڻ واري عمل کي آسان بڻائي ٿو (ڪجهه ڊيٽابيس رول بيڪ تقريبا ناممڪن آهي، جهڙوڪ ختم ڪرڻ وارو رول بيڪ). اسان صرف ايپليڪيشنن کي واپس آڻڻ کي ترجيح ڏيون ٿا. هن طريقي سان، جيتوڻيڪ توهان وٽ مختلف ڊيٽابيس آهن (مثال طور، SQL ۽ NoSQL)، توهان جي ترتيب واري پائپ لائن ساڳيا نظر ايندي.

اهو هميشه ممڪن آهي ته ايپليڪيشن کي هڪ ورزن واپس موٽايو (وڌيڪ نه)

رول بيڪ صرف ٿيڻ گهرجي جڏهن ضروري هجي. جيڪڏهن موجوده ورزن ۾ ڪو بگ آهي جيڪو آساني سان حل نه ڪيو ويو آهي، اسان کي تازو ڪم ڪندڙ ورزن ڏانهن موٽڻ جي قابل هوندو. اسان سمجهون ٿا ته هي تازو ڪم ڪندڙ نسخو اڳوڻو آهي. هڪ کان وڌيڪ رول آئوٽ لاءِ ڪوڊ ۽ ڊيٽابيس جي مطابقت کي برقرار رکڻ انتهائي مشڪل ۽ مهانگو هوندو.

نوٽ. وڌيڪ پڙهڻ جي قابليت لاءِ، هن آرٽيڪل ۾ اسين تبديلي ڪنداسين ايپليڪيشن جو وڏو ورزن.

قدم 1: شروعاتي رياست

ايپ جي جلد: 1.0.0
ڊي بي ورزن: v1

جو رايو آهي

اها اپليڪيشن جي شروعاتي حالت هوندي.

ڊيٽابيس تبديليون

ڊي بي تي مشتمل آهي 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

ڊي بي ورزن: 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
ڊي بي ورزن: v2

جو رايو آهي

نئين ڪالم کي شامل ڪرڻ ۽ ان جي مواد کي نقل ڪندي، اسان پوئتي موٽڻ سان مطابقت رکندڙ ڊيٽابيس تبديليون ٺاهيندا آهيون. ساڳئي وقت، جيڪڏهن اسان JAR کي واپس آڻينداسين يا هڪ پراڻو JAR هلندو آهي، اهو عمل جي دوران ڀڃي نه سگهندو.

اسان هڪ نئون ورزن ڪڍي رهيا آهيون

مرحلا:

  1. نئون ڪالم ٺاهڻ لاءِ ڊيٽابيس لڏپلاڻ ڪريو surname. هاڻي توهان جو ڊي بي نسخو v2
  2. مان ڊيٽا نقل ڪريو last_name в surname. ڌيان ڏيڻته جيڪڏھن توھان وٽ ھي ڊيٽا گھڻو آھي، توھان کي غور ڪرڻ گھرجي بيچ لڏپلاڻ!
  3. ڪوڊ لکو جتي اهي استعمال ڪيا ويا آهن ٻئي и новый۽ پراڻي ڪالم. هاڻي توهان جي ايپ جو نسخو 2.0.0
  4. ڪالم مان قدر پڙهو surname، جيڪڏهن اهو نه آهي null، يا ايل کانast_nameجيڪڏهن surname بيان نه ڪيو ويو آهي. توهان حذف ڪري سگهو ٿا getLastName() ڪوڊ مان، ڇو ته اھو ٻاھر نڪرندو null جڏهن توهان جي ايپليڪيشن کي واپس آڻيندي 3.0.0 ڪرڻ 2.0.0.

جيڪڏهن توهان اسپرنگ بوٽ فلائي وي استعمال ڪري رهيا آهيو، اهي ٻه مرحلا ورزن جي شروعات دوران ڪيا ويندا 2.0.0 ايپليڪيشنون. جيڪڏهن توهان ڊيٽابيس ورزننگ ٽول کي دستي طور تي هلائيندا آهيو، توهان کي اهو ڪرڻ لاءِ ٻه مختلف شيون ڪرڻيون پونديون (پهرين ڊي بي ورزن کي دستي طور تي اپڊيٽ ڪريو ۽ پوءِ نئين ايپليڪيشن کي ترتيب ڏيو).

اهو ضروري آهي. ياد رهي ته نئون ٺهيل ڪالمن نه گهرجي ٿيڻ گھرجي ڪوبه نه. جيڪڏهن توهان هڪ رول بيڪ ڪندا آهيو، پراڻي ايپليڪيشن کي نئين ڪالمن جي خبر ناهي ۽ ان کي انسٽال نه ڪندي Insert. پر جيڪڏهن توهان هن رڪاوٽ کي شامل ڪيو ۽ توهان جو ڊي بي ٿيندو v2، انهي کي نئين ڪالمن جي قيمت کي ترتيب ڏيڻ جي ضرورت پوندي. جنهن ڪري پابندين جي ڀڃڪڙي ٿيندي.

اهو ضروري آهي. توھان کي ھٽائڻ گھرجي طريقو getLastName()، ڇاڪاڻ ته نسخي ۾ 3.0.0 ڪوڊ ۾ ڪالمن جو ڪو تصور ناهي last_name. ان جو مطلب آهي ته اتي null مقرر ڪيو ويندو. توھان ڇڏي سگھوٿا طريقه ڪار ۽ شامل ڪريو چيڪ لاءِ 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 ڊيٽابيس ۾ surname ڪالم استعمال نه ڪندو آهي، پر نسخو 2.0.0 استعمال ڪري ٿو. اهي هڪ ٻئي سان مداخلت نه ڪندا آھن، ۽ ڪو به غلطيون نه هجڻ گهرجي.
  5. نسخ 2.0.0 ڊيٽا کي پراڻي ۽ نئين ڪالمن ۾ محفوظ ڪري ٿو، پسمانده مطابقت کي يقيني بڻائي ٿو

اهو ضروري آهي. جيڪڏھن توھان وٽ ڪي سوال آھن جيڪي شيون ڳڻن ٿيون پراڻن/نئين ڪالمن مان قدرن جي بنياد تي، توھان کي ياد رکڻ گھرجي ته توھان وٽ ھاڻي نقل ٿيل قدر آھن (گهڻو ڪري اھي اڃا لڏپلاڻ ڪري رھيا آھن). مثال طور، جيڪڏهن توهان استعمال ڪندڙن جو تعداد ڳڻڻ چاهيو ٿا جن جو آخري نالو (جيڪو به ڪالم سڏيو وڃي) خط سان شروع ٿيو A، پوءِ جيستائين ڊيٽا لڏپلاڻ مڪمل ٿي وڃي (oldnew ڪالم) جيڪڏهن توهان نئين ڪالم جي خلاف سوال ڪيو ته توهان وٽ متضاد ڊيٽا هجي.

ايپليڪيشن واپسي

هاڻي اسان وٽ ايپ جو نسخو آهي 2.0.0 ۽ ڊيٽابيس ۾ v2.

مرحلا:

  1. پنھنجي ايپليڪيشن کي ورجن ڏانھن واپس آڻيو 1.0.0.
  2. نسخ 1.0.0 ڊيٽابيس ۾ ڪالم استعمال نٿو ڪري surname، تنهنڪري رول بيڪ ڪامياب ٿيڻ گهرجي

ڊي بي تبديليون

ڊيٽابيس ۾ هڪ ڪالمن جو نالو آهي 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.

يان. ياد رکو ته توهان شامل نه ٿا ڪري سگهو ڪو به NOT 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: ڪوڊ مان last_name هٽائڻ

ايپ جي جلد: 3.0.0

ڊي بي ورزن: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;

ڪوڊ تبديليون

نوٽ per.: هن بلاڪ جي وضاحت پڻ غلطي سان ليکڪ طرفان 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

ڊي بي ورزن: 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"}

ڊي بي تبديليون

خاص طور تي 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 ۽ 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 ڪنسول پڻ شامل آھي (at http://localhost:8080/h2-console) تنهن ڪري توهان ڊيٽابيس جي حيثيت ڏسي سگهو ٿا (ڊفالٽ jdbc URL آهي jdbc:h2:mem:testdb).

وڌيڪ

اسان جي بلاگ تي ٻيا مضمون پڻ پڙهو:

جو ذريعو: www.habr.com

تبصرو شامل ڪريو