ዜሮ የእረፍት ጊዜ ማሰማራት እና የውሂብ ጎታዎች

ዜሮ የእረፍት ጊዜ ማሰማራት እና የውሂብ ጎታዎች

ይህ ጽሑፍ የውሂብ ጎታ ተኳሃኝነት ጉዳዮችን በማሰማራት ላይ እንዴት እንደሚፈታ በዝርዝር ያብራራል። ያለ ቅድመ ዝግጅት ለማሰማራት ከሞከሩ የማምረቻ ማመልከቻዎችዎ ላይ ምን ሊፈጠር እንደሚችል እንነግርዎታለን። ከዚያ ዜሮ ማቆያ ጊዜ እንዲኖረን የሚፈለጉትን የመተግበሪያውን የህይወት ኡደት ደረጃዎችን እናልፋለን።በግምት ሌይን: ተጨማሪ - ዜሮ የእረፍት ጊዜ). የክወናዎቻችን ውጤት ከኋላ-ተኳሃኝ ያልሆነውን የውሂብ ጎታ ለውጥ ወደ ኋላ-ተኳሃኝ በሆነ መልኩ መተግበር ይሆናል።

የኮድ ምሳሌዎችን ከጽሁፉ ለመረዳት ከፈለጉ በ ላይ ሊያገኟቸው ይችላሉ። የፊልሙ.

መግቢያ

የእረፍት ጊዜ ማሰማራት ዜሮ

ምን አይነት ሚስጥራዊ ነው። ዜሮ የእረፍት ጊዜ ማሰማራት? ይህ ማለት የእርስዎ መተግበሪያ አዲስ የመተግበሪያውን ስሪት በተሳካ ሁኔታ ወደ ምርት ለማስተዋወቅ በሚያስችል መንገድ ሲሰራጭ ነው፣ ተጠቃሚው ግን አለመኖሩን አያስተውለውም። ከተጠቃሚ እና ከኩባንያ እይታ፣ ይህ አዲስ ባህሪያትን ለማስተዋወቅ እና ሳንካዎች ሳይስተጓጎል እንዲስተካከሉ ስለሚያስችል በጣም ጥሩው የስምሪት ሁኔታ ነው።

ይህንን እንዴት ማሳካት ይቻላል? ብዙ መንገዶች አሉ ፣ ከመካከላቸው አንዱ እዚህ አለ

  • የእርስዎን አገልግሎት ስሪት ቁጥር 1 ያሰማሩ
  • የውሂብ ጎታ ፍልሰትን ያከናውኑ
  • የእርስዎን አገልግሎት ስሪት #2 ከስሪት #1 ጋር በትይዩ ያሰማሩ
  • ስሪቱ ቁጥር 2 ልክ እንደ ሚሰራው ሲያዩ፣ ቁጥር 1ን ያስወግዱ
  • ተጠናቅቋል!

ቀላል አይደል? እንደ አለመታደል ሆኖ ነገሩ ቀላል አይደለም፣ እና በኋላ ላይ በዝርዝር እንመለከታለን። አሁን ሌላ በጣም የተለመደ የማሰማራት ሂደትን እንፈትሽ - ሰማያዊ አረንጓዴ ማሰማራት።

ሰምተህ ታውቃለህ ሰማያዊ አረንጓዴ ማሰማራት? Cloud Foundry ይህን እጅግ በጣም ቀላል ያደርገዋል። ብቻ ተመልከት ይህ ዓምድ, ይህንን በበለጠ ዝርዝር የምንገልጽበት. በአጭሩ ለማጠቃለል፣ እንዴት ሰማያዊ አረንጓዴ ማሰማራት እንደሚችሉ እናስታውስዎ፡-

  • የምርት ኮድዎ ("ሰማያዊ" እና "አረንጓዴ") ሁለት ቅጂዎች መስራታቸውን ያረጋግጡ;
  • ሁሉንም ትራፊክ ወደ ሰማያዊ አካባቢ ይምሩ፣ ማለትም የምርት ዩአርኤሎች ወደዚያ እንዲጠቁሙ;
  • በአረንጓዴ አካባቢ ውስጥ ሁሉንም የመተግበሪያ ለውጦች ማሰማራት እና መሞከር;
  • ዩአርኤሎችን ከሰማያዊ ወደ አረንጓዴ አካባቢ ይቀይሩ

ሰማያዊ አረንጓዴ ማሰማራት ስለ ምርት መበላሸት ሳይጨነቁ አዳዲስ ባህሪያትን በቀላሉ ለማስተዋወቅ የሚያስችል አቀራረብ ነው። ይህ የሆነበት ምክንያት የሆነ ነገር ቢፈጠር እንኳን በቀላሉ "ማብሪያና ማጥፊያ" በማንከባለል ወደ ቀድሞው አካባቢ መመለስ ስለሚቻል ነው።

ከላይ ያሉትን ሁሉ ካነበቡ በኋላ, ጥያቄውን መጠየቅ ይችላሉ-ዜሮ ማቆያ ጊዜ ከሰማያዊ አረንጓዴ ማሰማራት ጋር ምን ግንኙነት አለው?

አንድ ዓይነት አካባቢ ሁለት ቅጂዎችን ጠብቆ ማቆየት እነሱን ለማቆየት ሁለት ጊዜ ጥረት ስለሚጠይቅ ብዙ የሚያመሳስላቸው ነገር አለ። ለዚህም ነው አንዳንድ ቡድኖች የሚናገሩት። ማርቲን ፎለር, የዚህ አቀራረብ ልዩነት ይከተሉ:

ሌላው አማራጭ ተመሳሳይ የውሂብ ጎታ መጠቀም ነው, ለድር እና ለጎራ ንብርብሮች ሰማያዊ-አረንጓዴ መቀየሪያዎችን መፍጠር. በዚህ አቀራረብ, የውሂብ ጎታ ብዙውን ጊዜ ችግር ሊሆን ይችላል, በተለይም አዲሱን የሶፍትዌር ስሪት ለመደገፍ ስልቱን መቀየር ሲፈልጉ.

እና እዚህ በዚህ ጽሑፍ ውስጥ ወደ ዋናው ችግር እንመጣለን. የውሂብ ጎታ. ይህን ሐረግ ሌላ እንመልከት።

የውሂብ ጎታ ፍልሰትን ያከናውኑ.

አሁን ጥያቄውን እራስዎን መጠየቅ አለብዎት - የውሂብ ጎታ ለውጡ ወደ ኋላ የማይጣጣም ከሆነስ? የእኔ የመጀመሪያ የመተግበሪያው ስሪት አይሰበርም? እንደ እውነቱ ከሆነ ይህ በትክክል ይሆናል ...

ስለዚህ፣ የዜሮ ማቆያ/ሰማያዊ አረንጓዴ ማሰማራት ትልቅ ጥቅም ቢኖረውም፣ ኩባንያዎች ማመልከቻዎቻቸውን ለማሰማራት የሚከተለውን ደህንነቱ የተጠበቀ ሂደት ይከተላሉ፡

  • ከአዲሱ የመተግበሪያው ስሪት ጋር ጥቅል ያዘጋጁ
  • አሂድ መተግበሪያን ዝጋ
  • የውሂብ ጎታውን ለማዛወር ስክሪፕቶችን ያሂዱ
  • አዲስ የመተግበሪያውን ስሪት ማሰማራት እና ማስጀመር

በዚህ ጽሑፍ ውስጥ ከዜሮ ማቆያ ጊዜ ጥቅም ለማግኘት ከመረጃ ቋትዎ እና ኮድዎ ጋር እንዴት እንደሚሠሩ በዝርዝር እንገልጻለን።

የውሂብ ጎታ ችግሮች

በመረጃ ቋቱ ውስጥ ምንም አይነት መረጃ የማያከማች ሀገር-አልባ አፕሊኬሽን ካለህ፣ ወዲያውኑ ዜሮ የማቆያ ጊዜ ልታገኝ ትችላለህ። እንደ አለመታደል ሆኖ አብዛኛው ሶፍትዌሮች ውሂብን የሆነ ቦታ ማከማቸት አለባቸው። ለዚህም ነው በወረዳው ላይ ማንኛውንም ለውጥ ከማድረግዎ በፊት ሁለት ጊዜ ማሰብ አለብዎት. ምንም የእረፍት ጊዜ ማሰማራት እንዳይቻል እቅዱን እንዴት መለወጥ እንደሚቻል በዝርዝር ከመግባታችን በፊት በመጀመሪያ በሥሪት ሥሪት ላይ እናተኩር።

የሥሪት ሥሪት

በዚህ ጽሑፍ ውስጥ እንጠቀማለን ፍላይዌይ እንደ ስሪት መቆጣጠሪያ መሳሪያ (በግምት ትርጉም፡ እየተነጋገርን ያለነው ስለ ዳታቤዝ ፍልሰት ነው።). በተፈጥሮ፣ አብሮ የተሰራ የ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 ን መጠቀም ትችላለህ። ስለ ስፕሪንግ ቡት እና ፍላይዌይ የበለጠ መረጃ ለማግኘት ይመልከቱ የፀደይ ቡት ሰነዶች.

ከSፕሪንግ ቡት ጋር የምንጭ መቆጣጠሪያ መሳሪያን በመጠቀም 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

አስተያየት

የአሁኑ ለውጦች ሁለት አጋጣሚዎችን (አሮጌ እና አዲስ) በአንድ ጊዜ እንድናሄድ አይፈቅዱልንም። ስለዚህ, ዜሮ የእረፍት ጊዜ ማሰማራት አስቸጋሪ ይሆናል (ግምቶች ከግምት ውስጥ ከገቡ, በእውነቱ የማይቻል ነው).

ኤ/ቢ ሙከራ

አሁን ያለው ሁኔታ የመተግበሪያ ስሪት አለን 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ወይም ከ Last_name, ከሆነ surname አልተገለጸም። መሰረዝ ይችላሉ። getLastName() ከኮዱ, ስለሚወጣ null ማመልከቻዎን ከ 3.0.0 ወደ 2.0.0.

ስፕሪንግ ቡት ፍላይዌይን እየተጠቀሙ ከሆነ፣ እነዚህ ሁለት እርምጃዎች በስሪት ጅምር ጊዜ ይከናወናሉ። 2.0.0 መተግበሪያዎች. የዳታቤዝ ሥሪት መገልገያውን እራስዎ ካስኬዱ ይህንን ለማድረግ ሁለት የተለያዩ ነገሮችን ማድረግ አለብዎት (መጀመሪያ የዲቢ ሥሪቱን እራስዎ ያዘምኑ እና አዲሱን መተግበሪያ ያሰማሩ)።

አስፈላጊ ነው. አዲስ የተፈጠረ አምድ መሆኑን አስታውስ መሆን የለበትም ለመሆን ሙሉ በሙሉ አይደለም. መልሶ መመለሻ ካደረጉ አሮጌው መተግበሪያ ስለ አዲሱ አምድ አያውቅም እና በዚህ ጊዜ አይጭነውም። Insert. ግን ይህን ገደብ ካከሉ እና የእርስዎ ዲቢ ይሆናል v2, ይህ የአዲሱን አምድ ዋጋ ማዘጋጀት ያስፈልገዋል. ወደ እገዳዎች መጣስ የሚመራው.

አስፈላጊ ነው. ዘዴውን ማስወገድ አለብዎት getLastName(), ምክንያቱም በስሪት ውስጥ 3.0.0 በኮዱ ውስጥ የአንድ አምድ ፅንሰ-ሀሳብ የለም። last_name. ይህ ማለት ባዶ እዛ ይዘጋጃል ማለት ነው። ዘዴውን ትተው ቼኮችን ማከል ይችላሉ nullነገር ግን በጣም የተሻለው መፍትሄ በሎጂክ ውስጥ መሆኑን ማረጋገጥ ነው getSurname() ትክክለኛውን ዜሮ ያልሆነ ዋጋ መርጠዋል።

ኤ/ቢ ሙከራ

አሁን ያለው ሁኔታ የመተግበሪያ ስሪት አለን 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.

የ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

ዲቢ ስሪት፡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 እና ከአባት ስም ያነባል። የውሂብ ጎታውን በተመለከተ የመጨረሻው ፍልሰት እየተካሄደ ነው። last_name в surname. እንዲሁም ገደብ ሙሉ በሙሉ አይደለም ከ ተወግዷል last_name. የውሂብ ጎታው አሁን በስሪት ውስጥ ነው። v3
  4. የመተግበሪያ ስሪት መዘርጋት 4.0.0 - በኮዱ ላይ ምንም ለውጦች አይደረጉም. የውሂብ ጎታ ማሰማራት v4, ይህም ያስወግዳል last_name. እዚህ ምንም የጎደሉ ገደቦችን ወደ ዳታቤዝ ማከል ይችላሉ።

ይህን አካሄድ በመከተል የውሂብ ጎታ/አፕሊኬሽን ተኳኋኝነትን ሳትሰብር ሁልጊዜ አንድ እትም መመለስ ትችላለህ።

ኮድ

በዚህ ጽሑፍ ውስጥ ጥቅም ላይ የዋለው ሁሉም ኮድ በ ላይ ይገኛል። የፊልሙ. ከዚህ በታች ተጨማሪ መግለጫ ነው.

ፕሮጀክቶች

ማከማቻውን ከዘጉ በኋላ የሚከተለውን የአቃፊ መዋቅር ያያሉ።

├── 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) ስለዚህ የውሂብ ጎታውን ሁኔታ ማየት ይችላሉ (ነባሪ jdbc URL ነው። jdbc:h2:mem:testdb).

በተጨማሪም

በብሎጋችን ላይ ሌሎች ጽሑፎችን ያንብቡ፡-

ምንጭ: hab.com

አስተያየት ያክሉ