زیرو ڈاؤن ٹائم تعیناتی اور ڈیٹا بیس

زیرو ڈاؤن ٹائم تعیناتی اور ڈیٹا بیس

یہ مضمون تفصیل سے بتاتا ہے کہ تعیناتی میں ڈیٹا بیس کی مطابقت کے مسائل کو کیسے حل کیا جائے۔ ہم آپ کو بتائیں گے کہ اگر آپ ابتدائی تیاری کے بغیر تعینات کرنے کی کوشش کرتے ہیں تو آپ کی پروڈکشن ایپلی کیشنز کا کیا ہو سکتا ہے۔ اس کے بعد ہم ایپلیکیشن لائف سائیکل کے مراحل سے گزریں گے جن کے لیے صفر ڈاؤن ٹائم ہونا ضروری ہے (تقریبا. لین: مزید - صفر ڈاؤن ٹائم)۔ ہماری کارروائیوں کا نتیجہ یہ ہو گا کہ پیچھے کی طرف متضاد ڈیٹا بیس کی تبدیلی کو پیچھے کی طرف مطابقت پذیر طریقے سے لاگو کیا جائے۔

اگر آپ مضمون سے کوڈ کی مثالوں کو سمجھنا چاہتے ہیں، تو آپ انہیں اس پر تلاش کر سکتے ہیں۔ GitHub کے.

تعارف

صفر ڈاؤن ٹائم تعیناتی۔

کیا صوفیانہ ہے۔ صفر ڈاؤن ٹائم تعیناتی? آپ یہ کہہ سکتے ہیں جب آپ کی ایپلیکیشن اس طرح سے لگائی جاتی ہے کہ آپ ایپلیکیشن کے نئے ورژن کو پروڈکشن میں کامیابی کے ساتھ متعارف کروا سکتے ہیں، جبکہ صارف اس کی عدم دستیابی کو محسوس نہیں کرتا ہے۔ صارف اور کمپنی کے نقطہ نظر سے، یہ تعیناتی کا بہترین ممکنہ منظر ہے کیونکہ یہ نئی خصوصیات کو متعارف کرانے اور کیڑے کو بغیر کسی رکاوٹ کے ٹھیک کرنے کی اجازت دیتا ہے۔

اس کو کیسے حاصل کیا جائے؟ کئی طریقے ہیں، ان میں سے ایک یہ ہے:

  • اپنی سروس کا ورژن نمبر 1 تعینات کریں۔
  • ڈیٹا بیس کی منتقلی کو انجام دیں۔
  • ورژن #2 کے متوازی طور پر اپنی سروس کا ورژن #1 تعینات کریں۔
  • جیسے ہی آپ دیکھیں کہ ورژن نمبر 2 جیسا کام کرنا چاہیے، ورژن نمبر 1 کو ہٹا دیں۔
  • تیار!

آسان، ہے نا؟ بدقسمتی سے، یہ اتنا آسان نہیں ہے، اور ہم اسے بعد میں تفصیل سے دیکھیں گے۔ اب آئیے ایک اور کافی عام تعیناتی کے عمل کو چیک کرتے ہیں - blue green deployment.

کیا آپ نے کبھی سنا ہے؟ نیلے سبز کی تعیناتی? کلاؤڈ فاؤنڈری اسے انتہائی آسان بناتی ہے۔ ذرا دیکھو اس مضمون، جہاں ہم اس کو مزید تفصیل سے بیان کرتے ہیں۔ مختصراً خلاصہ کرنے کے لیے، آئیے آپ کو یاد دلاتے ہیں کہ نیلے سبز کی تعیناتی کیسے کی جائے:

  • یقینی بنائیں کہ آپ کے پروڈکشن کوڈ کی دو کاپیاں ("نیلے" اور "سبز") کام کرتی ہیں؛
  • تمام ٹریفک کو نیلے ماحول کی طرف لے جائیں، یعنی تاکہ پروڈکشن یو آر ایل وہاں اشارہ کریں۔
  • ہرے ماحول میں ایپلیکیشن کی تمام تبدیلیوں کو تعینات اور جانچنا؛
  • یو آر ایل کو نیلے رنگ سے سبز ماحول میں تبدیل کریں۔

بلیو گرین ڈیپلائمنٹ ایک ایسا طریقہ ہے جو آپ کو پروڈکشن ٹوٹنے کی فکر کیے بغیر آسانی سے نئی خصوصیات متعارف کرانے کی اجازت دیتا ہے۔ یہ اس حقیقت کی وجہ سے ہے کہ یہاں تک کہ اگر کچھ ہو جاتا ہے، تو آپ آسانی سے "سوئچ کو ٹمٹما کر" پچھلے ماحول میں واپس جا سکتے ہیں۔

مندرجہ بالا سبھی کو پڑھنے کے بعد، آپ یہ سوال پوچھ سکتے ہیں: زیرو ڈاؤن ٹائم کا بلیو گرین تعیناتی سے کیا تعلق ہے؟

ٹھیک ہے، ان میں بہت کچھ مشترک ہے، کیونکہ ایک ہی ماحول کی دو کاپیاں برقرار رکھنے کے لیے انہیں برقرار رکھنے کے لیے دوگنی کوشش کی ضرورت ہوتی ہے۔ یہی وجہ ہے کہ کچھ ٹیمیں دعوی کرتی ہیں۔ مارٹن فولر، اس نقطہ نظر کی ایک تبدیلی کی پیروی کریں:

ایک اور آپشن ویب اور ڈومین لیئرز کے لیے نیلے سبز سوئچ بنا کر اسی ڈیٹا بیس کو استعمال کرنا ہے۔ اس نقطہ نظر میں، ڈیٹا بیس اکثر ایک مسئلہ ہو سکتا ہے، خاص طور پر جب آپ کو سافٹ ویئر کے نئے ورژن کو سپورٹ کرنے کے لیے اس کا سکیما تبدیل کرنے کی ضرورت ہو۔

اور یہاں ہم اس مضمون میں بنیادی مسئلہ کی طرف آتے ہیں۔ ڈیٹا بیس۔. آئیے اس جملے پر ایک اور نظر ڈالتے ہیں۔

ڈیٹا بیس کی منتقلی کو انجام دیں۔

اب آپ کو اپنے آپ سے سوال پوچھنا ہوگا - اگر ڈیٹا بیس کی تبدیلی پیچھے کی طرف مطابقت نہیں رکھتی ہے تو کیا ہوگا؟ کیا ایپ کا میرا پہلا ورژن نہیں ٹوٹے گا؟ درحقیقت ایسا ہی ہوگا...

لہٰذا، صفر ڈاؤن ٹائم/بلیو گرین تعیناتی کے بڑے فوائد کے باوجود، کمپنیاں اپنی درخواستوں کی تعیناتی کے لیے درج ذیل محفوظ طریقہ کار کی پیروی کرتی ہیں:

  • درخواست کے نئے ورژن کے ساتھ ایک پیکج تیار کریں۔
  • چلتی ہوئی ایپلیکیشن کو بند کریں۔
  • ڈیٹا بیس کو منتقل کرنے کے لیے سکرپٹ چلائیں۔
  • ایپلیکیشن کا نیا ورژن تعینات اور لانچ کریں۔

اس آرٹیکل میں، ہم تفصیل دیں گے کہ آپ اپنے ڈیٹا بیس اور کوڈ کے ساتھ کس طرح کام کر سکتے ہیں تاکہ صفر ڈاؤن ٹائم تعیناتی کا فائدہ اٹھایا جا سکے۔

ڈیٹا بیس کے مسائل

اگر آپ کے پاس اسٹیٹ لیس ایپلی کیشن ہے جو ڈیٹا بیس میں کوئی ڈیٹا اسٹور نہیں کرتی ہے، تو آپ فوراً صفر ڈاؤن ٹائم تعیناتی حاصل کر سکتے ہیں۔ بدقسمتی سے، زیادہ تر سافٹ ویئر کو ڈیٹا کو کہیں ذخیرہ کرنے کی ضرورت ہوتی ہے۔ اس لیے آپ کو سرکٹ میں کوئی تبدیلی کرنے سے پہلے دو بار سوچنا چاہیے۔ اس سے پہلے کہ ہم اسکیما کو تبدیل کرنے کے طریقہ کی تفصیلات میں جائیں تاکہ بغیر وقت کی تعیناتی ممکن ہو، آئیے پہلے ورژننگ اسکیما پر توجہ مرکوز کریں۔

ورژننگ اسکیم

اس مضمون میں ہم استعمال کریں گے۔ فلائی وے ورژن کنٹرول ٹول کے طور پر (تقریبا. ترجمہ: ہم ڈیٹا بیس کی منتقلی کے بارے میں بات کر رہے ہیں۔)۔ قدرتی طور پر، ہم اسپرنگ بوٹ ایپلی کیشن بھی لکھیں گے جس میں بلٹ ان فلائی وے سپورٹ ہے اور ایپلیکیشن سیاق و سباق کو ترتیب دیتے وقت اسکیما مائیگریشن کرے گا۔ فلائی وے استعمال کرتے وقت، آپ اپنے پروجیکٹس فولڈر میں مائیگریشن اسکرپٹس اسٹور کرسکتے ہیں (بطور ڈیفالٹ 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');

ہر چیز بالکل خود وضاحتی ہے: آپ ایس کیو ایل کو اس بات کی وضاحت کے لیے استعمال کر سکتے ہیں کہ آپ کے ڈیٹا بیس میں کس طرح ترمیم کی جانی چاہیے۔ اسپرنگ بوٹ اور فلائی وے کے بارے میں مزید معلومات کے لیے، چیک آؤٹ کریں۔ اسپرنگ بوٹ دستاویزات.

اسپرنگ بوٹ کے ساتھ سورس کنٹرول ٹول استعمال کرنے سے، آپ کو 2 بڑے فائدے ملتے ہیں:

  • آپ ڈیٹا بیس کی تبدیلیوں کو کوڈ کی تبدیلیوں سے الگ کرتے ہیں۔
  • ڈیٹا بیس کی منتقلی آپ کی درخواست کے رول آؤٹ کے ساتھ ہوتی ہے، یعنی آپ کی تعیناتی کے عمل کو آسان بنایا گیا ہے۔

ڈیٹا بیس کے مسائل کو حل کرنا

مضمون کے اگلے حصے میں، ہم ڈیٹا بیس کی تبدیلیوں کے لیے دو طریقوں پر توجہ مرکوز کریں گے۔

  • پسماندہ عدم مطابقت
  • پسماندہ مطابقت

پہلی کو ایک انتباہ کے طور پر سمجھا جائے گا کہ آپ کو ابتدائی تیاری کے بغیر صفر ڈاؤن ٹائم تعیناتی کو انجام نہیں دینا چاہئے... دوسرا ایک حل پیش کرتا ہے کہ آپ کس طرح ڈاؤن ٹائم کے بغیر تعیناتی انجام دے سکتے ہیں اور ساتھ ہی پسماندہ مطابقت کو برقرار رکھ سکتے ہیں۔

ہمارا پروجیکٹ جس پر ہم کام کر رہے ہیں ایک سادہ اسپرنگ بوٹ فلائی وے ایپلی کیشن ہوگی جس میں موجود ہے۔ Person с first_name и last_name ڈیٹا بیس میں (تقریبا. ترجمہ: Person ایک میز ہے اور first_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

ماخذ فلائی وے اسکرپٹ:

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. اب آپ کا 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 ایپلی کیشنز اگر آپ ڈیٹا بیس ورژننگ ٹول کو دستی طور پر چلاتے ہیں، تو آپ کو ایسا کرنے کے لیے دو مختلف کام کرنے ہوں گے (پہلے ڈی بی ورژن کو دستی طور پر اپ ڈیٹ کریں اور پھر نئی ایپلیکیشن کو تعینات کریں)۔

یہ ضروری ہے. یاد رہے کہ نو تخلیق شدہ کالم نہیں ہونا چاہیے ہو بالکل نہیں. اگر آپ رول بیک کرتے ہیں، تو پرانی ایپلیکیشن نئے کالم کے بارے میں نہیں جانتی ہے اور اس دوران اسے انسٹال نہیں کرے گی۔ 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 ڈیٹا بیس میں کنیت کے کالم کا استعمال نہیں کرتا، لیکن ورژن 2.0.0 استعمال کرتا ہے وہ ایک دوسرے کے ساتھ مداخلت نہیں کرتے ہیں، اور کوئی غلطی نہیں ہونا چاہئے.
  5. ورژن 2.0.0 پرانے اور نئے کالم دونوں میں ڈیٹا اسٹور کرتا ہے، پسماندہ مطابقت کو یقینی بناتا ہے۔

یہ ضروری ہے. اگر آپ کے پاس کوئی سوالات ہیں جو پرانے/نئے کالم کی اقدار کی بنیاد پر آئٹمز کو شمار کرتے ہیں، تو آپ کو یاد رکھنا چاہیے کہ اب آپ کے پاس ڈپلیکیٹ قدریں ہیں (زیادہ تر امکان ہے کہ وہ اب بھی منتقل ہو رہی ہیں)۔ مثال کے طور پر، اگر آپ ان صارفین کی تعداد گننا چاہتے ہیں جن کا آخری نام (جو بھی کالم کہا جاتا ہے) حرف سے شروع ہوا A، پھر ڈیٹا کی منتقلی مکمل ہونے تک (oldnew کالم) اگر آپ کسی نئے کالم سے استفسار کرتے ہیں تو آپ کے پاس متضاد ڈیٹا ہو سکتا ہے۔

ایپلیکیشن رول بیک

اب ہمارے پاس ایپ ورژن ہے۔ 2.0.0 اور ڈیٹا بیس میں v2.

اقدامات:

  1. اپنی ایپلیکیشن کو ورژن میں واپس کریں۔ 1.0.0.
  2. ورژن 1.0.0 ڈیٹا بیس میں کالم استعمال نہیں کرتا ہے۔ surname، لہذا رول بیک کامیاب ہونا چاہئے۔

ڈی بی تبدیلیاں

ڈیٹا بیس کا نام ایک کالم پر مشتمل ہے۔ 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');

اسکرپٹ شامل کریں۔ 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

تبصرہ

نوٹ فی: بظاہر، اصل مضمون میں مصنف نے غلطی سے اس بلاک کے متن کو مرحلہ 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: ڈیٹا بیس سے last_name کو ہٹانا

ایپ ورژن: 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 ایل کی ایک نقل ہے۔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 کنسول بھی شامل ہے (at http://localhost:8080/h2-console) تاکہ آپ ڈیٹا بیس کی حیثیت دیکھ سکیں (ڈیفالٹ jdbc URL ہے۔ jdbc:h2:mem:testdb).

اس کے علاوہ

ہمارے بلاگ پر دیگر مضامین بھی پڑھیں:

ماخذ: www.habr.com

نیا تبصرہ شامل کریں