코코코딩공부

Flyway 적용해보기

Ocean_ 2023. 9. 23. 21:40

들어가며

프로젝트를 진행하며 중간중간 db 구조 및 인덱스 등등이 달라짐에 따라 db 버전관리를 해야할 필요를 느꼈다. db의 버전 관리를 자체 문서 등을 통해 실행할 수 있지만 실수의 여지가 많다고 판단되었고 누군가가 스키마 변경을 실행해놓고 기록해두지 않느다면 놓칠 가능성이 크기때문에 우리는 버전관리 flyway를 적용해보기로 하였다

flyway 란 ?

DDL, DML 등 스키마 변경을 정해둔 규칙에 따라 자동으로 DB에 적용해주는 DB 형상관리 툴이다.

동작 방식

flyway를 적용하면 flyway_history 테이블에 그 시점에 테이블 스키마에 대한 메타 데이터가 기록된다.

이후 flyway는 사용자가 정의한 sql 파일을 scan해서 migration의 버전과 작업을 인지한다.

만약 새로 정의한 sql 파일이 이미 적용된 버전의 이하(숫자) 라면 적용하지 않는다.

flyway 작명

flyway의 이름은 생각보다 중요하다.

V1__ADD_CAFE_TABLE.sql

위와 같은 sql이 있다고 가정하면

  • V 는 Flyway migration 쿼리 버전이다.
  • 1 은 버전을 뜻한다.
    • 자연수로 인식한다.
  • __는 분리자이다.
  • ADD_CAFE_TABLE는 설명을 의미한다.
U2_ADD_CAFE_TABLE.sql
  • U는 Flyway의 실행 취소 스크립트 파일이다.
    • 안타깝게도 유료버전이다.
R2_ADD_CAFE_TABLE.sql
  • R은 Flyway의 패치마다 반복실행되는 스크립트이다.

적용해보기

우리의 프로젝트 sql문이다.

create table if not exists `yozm-cafe`.cafe
(
    like_count  int default 0 not null,
    id          bigint auto_increment primary key,
    address     varchar(50)   not null,
    description text          null,
    map_url     varchar(512)  not null,
    name        varchar(20)   not null,
    phone       varchar(20)   null
);

create table if not exists `yozm-cafe`.cafe_available_times
(
    is_opened bit                                                                                 not null,
    cafe_id   bigint                                                                              not null,
    close     time(6)                                                                             null,
    open      time(6)                                                                             null,
    day       enum ('FRIDAY', 'MONDAY', 'SATURDAY', 'SUNDAY', 'THURSDAY', 'TUESDAY', 'WEDNESDAY') not null,
    constraint cafe_available_times_CAFE_ID
        foreign key (cafe_id) references cafe (id)
);

이를 V1__init.sql 파일로 만들겠다.

1 번 문제점

이렇게 진행하려다보니 갑작스럽게 문제점이 생각났다. 프로젝트를 진행하기 위해 각자 다양한 브랜치에서 작업을 진행하고 있다.

오션은 V2__add_a_table.sql 바다는 V2__add_b_table.sql 을 각자 브랜치에서 만들고 작업을 했다. 이후 merge 과정에서 같은 V 버전이므로 문제가 발생할 수 있다.

우리팀은 이 상황을

V20230901153300__init 와 같은 V버전 숫자를 현재시간으로 찍기로 하였다. 이경우에 오션과 바다는 겹칠일이 극히 드믈기 때문에 문제가 발생하지 않을 것이다.

2 번 문제점

이제 버전 숫자가 겹침에 따라 문제가 생길일은 없어졌다. 하지만 우리는 작업을 진행할 때 버전 별로 merge가 되는 것이 아니다.

위에서 이야기 했듯이 새로 정의한 sql 파일이 이미 적용된 버전의 이하(숫자) 라면 무시가 되는데 일찍 sql을 생성했지만 늦게 merge 될 경우 migration 작업이 무시되기 때문에 Out-Of-Order 라는 옵션을 이용한다.

다만 이 경우에는 flyway가 숫자로 순차적 버전관리를 해준다는 의미가 퇴색될 수 있다.

Prod 환경

나는 처음에 flyway를 확인하고 오! 이 기능 dev, prod 모두에서 사용하면 너무너무 좋겠다! 라고 생각했다.

하지만 prod 환경에서는 flyway를 사용하면 db를 날리는 등 위험할 수 있기 때문에 prod 환경에서 스키마 수정이 필요하면 직접 서버에 들어가서 ddl문을 작동시키기로 하였다. 휴먼 에러가 발생할 수도 있기 때문일까 ?

나가며

flyway를 통해 db 관리를 하게되었다. 코드 형상관리는 github, db 형상관리는 flyway~