릴리즈 1.0 기반 flyway 도입기

찬디·2025년 8월 19일

우테코

목록 보기
13/18

개요

flyway가 왜 필요할까?
ddl-auto도 쓰지 못하게 되는데..

[우테코 팀플 4차 스프린트 요구사항]

flyway가 필요한 이유

상황

  • 운영 디비에 ddl-auto : validate가 걸려져있다고 가정합시다.
    행성이가 이번에 새로운 기능을 만들며 엔티티를 수정하게되었고, 운영 디비를 수정하게 되었다고 합시다.

직접 운영 디비를 수정하면 어떤 문제가 생길까요?
drop 테이블을 막았더라도 다음과 같은 문제가 생길 수 있습니다.

사라진 name 컬럼

여기 개발팀의 흔한 하루가 있습니다.

짱성 (사수): "아, member 테이블의 name 컬럼을 user_name으로 바꾸는 게 더 명확하겠어." 짱성이는 바로 운영 DB에 접속해 ALTER 쿼리를 실행합니다.

행성 (부사수): "name 컬럼을 사용하는 새로운 기능을 개발해야겠다"

결과는 어떨까요? 행성이가 만든 기능은 name 컬럼을 찾지 못해 장애를 일으킵니다.

  • 테스트하면 되지 않을까요?
    • 행성이의 로컬, dev 서버에서는 잘 동작했지만, prod 서버와 환경이 달라지는 문제가 발생합니다.
    • 두 서버 모두 잘 적용하더라도, 이력이 남지않아 파악하기가 매우 힘듭니다.

이런 문제는 왜 발생할까요? 바로 모든 개발자가 운영 DB에 직접 쿼리를 날려 스키마를 수정하고, 그 변경 사항이 아무에게도 공유되지 않기 때문입니다. 모든 개발자는 언제, 누가, 무엇을 바꿨는지 알 수 없어 항상 최신 스키마를 외우고 다녀야 하는 불안한 상황에 놓입니다.

Flyway는 'Git'입니다.

Flyway는 데이터베이스의 Git이라고 생각되더라고요.

만약 여러 개발자가 하나의 중요한 main.java 파일을 공유 폴더에 놓고 각자 수정한다고 상상해 보세요. 누가 최신 버전을 덮어쓸지 몰라 불안할 겁니다. 그래서 우리는 Git으로 버전을 관리하고, commit 메시지로 변경 사항을 기록하며, pull을 통해 모두가 최신 버전을 유지합니다.

Flyway는 데이터베이스 스키마를 위한 Git입니다.

버전 관리

깃에서 커밋으로 버전을 관리하는것처럼 flyway는 다음과 같이 버전을 관리합니다.

V1__create_member_table.sql

V2__rename_name_to_user_name.sql

V3__add_email_column.sql

버전을 통해 변경 순서를 보장하며,
어떤 스크립트가 언제, 누구에 의해 적용되었는지 flyway_schema_history 테이블에 모두 기록됩니다.

Flyway 도입을 하면 해야할일

  • 운영 DB에 직접 접속하는 대신, 새로운 버전의 SQL 마이그레이션 파일을 작성하여 Git에 올립니다. 그러면 모든 팀원과 모든 서버(개발, 운영)의 DB 스키마는 항상 동일한 최신 상태로 자동 동기화됩니다.

  • 번거롭기는 하지만, 예기치 못한 운영서버의 문제를 막을 수 있습니다.

  • 운영 서버에 ddl auto를 update하는것은 예기치 못한 에러를 발생시킬 수 있습니다.

    • 엔티티 코드상 이름만 바뀌어도, 테이블 전체가 바뀌는 경우 등!(직접 겪은적이 있습니다)

만약 데이터베이스 스키마가 존재하는 상태라면?

  • 이부분이 이번에 flyway를 도입하면서 가장 고민을 많이 한 부분입니다. 헷갈리기도 하고요.

V1 스크립트가 없는 경우

  • 우선 아무런 설정,스크립트 없이 실행하면 애초에 에러가 납니다

V1 스크립트가 있는 경우

  • 만약 CREATE TABLE과 같은 스크립트를 넣었고, 운영 서버 DB에 존재하는 경우, ALREADY EXIST 같은 SQL 에러가 발생하게 됩니다.
  • 만약 충돌이 나지 않으면, 통과됩니다.
    • 그러나 V1 스크립트는 현재 운영 디비의 스키마를 모두 파악할 수 있게 작성하는 것이 좋습니다. 로컬,dev에서는 데이터베이스를 날린뒤 V1 스크립트가 실행되는 경우가 많이 있기 때문입니다.

해결방법 : baseline 설정

  • baseline 설정을 통해 지금 DB에 있는 스키마가 문제가 없다는것을 flyway에게 알려주면, flyway는 history에 저장을합니다. 그리고 V1 스크립트는 실행하지않습니다.

어차피 V1 스크립트 실행안되는데 그냥 작성안하면 안됨?

아까 언급했지만, 운영 디비의 스키마가 모두 녹아져있는것이 문서화 관점에서 좋습니다.

현재 운영 디비의 스키마를 모두 파악할 수 있게 작성하는 것이 좋습니다. 로컬,dev에서는 데이터베이스를 날린뒤 실행하고, 이 때 V1 스크립트가 실행되는 경우가 있다면 로컬,dev에서 작업하기가 힘든 상황이 생깁니다.

application.yml 예시

  flyway:
    enabled: true
    baseline-on-migrate: true # 마이그레이션 시 베이스라인이 없으면 자동으로 생성
    baseline-version: "1"     # V1을 베이스라인 버전으로 설정
    baseline-description: "Initial schema baseline"

flyway 도입 시점

  • flyway는, 초기 1.0.0 릴리즈전까지는 도입하지 않는것이 낫다는 제 개인적인 의견입니다.
    1.0.0 배포전에는, 기능을 빠르게 내면서 요구사항이 수정되는 것이 많은데
    flyway를 먼저 도입해버린다면 빠른 개발 속도를 내지 못하기 때문입니다.

  • flyway는 DB 안정성을 챙기는 선택이며 이는 프로젝트 초기에는 필요하지 않을 수 있습니다.

profile
깃허브에서 velog로 블로그를 이전했습니다.

0개의 댓글