DB 형상관리에 대한 고민의 마지막 글 입니다!
1탄과 2탄을 참고해주세요!
Why?
- 스키마 변경사항을 dev_db, staging_db 에 마이그레이션 하기 위해서
- DB 스키마 변경 history를 기록을 위해서
- dev_db, staging_db 를 직접 수정하는 일이 없게 하기 위해서
git repository를 sql 파일 hub처럼 사용
Why?
- 마이그레이션 툴은 DB 변경사항의 이력들(sql파일)이 같은 디렉토리 안에 존재해야 다음 버전으로 업데이트 할 수 있다.
- 이전 버전이 반영되었는지 확인 후 새로 작성한 sql파일을 읽고 다음 버전으로 업데이트 하기 때문이다.
- MSA구조이지만 한개의 DB를 공유하기 때문에 각 프로젝트에서 마이그레이션 툴을 이용하려면, 다른 프로젝트에서 작성한 sql파일도 가지고 있어야 한다.
- Flyway에서 제공하는 Flyway hub는 프로젝트에서 데이터 마이그레이션 진행 시, 디렉토리에 sql 파일이 없어도 hub에 저장된 이전 버전의 sql파일을 읽고 다음 업데이트를 진행하게 된다. 그러나 아직 불완전한 서비스이므로 사용하지 않기로 했다.
- 그래서 git repository를 만들어 모든 sql파일들을 저장하여 Flyway hub처럼 사용하려고 한다.
대략적인 구조는 ^위와 같다.
git repository를 하나 만들어 sql hub처럼 사용한다.
Flyway
Why?
- 레퍼런스가 많고, 공식 문서가 잘 되어 있다.
- liquibase는 파일명이 자유로운 대신 마이그레이션 명령어를 실행할 때 특정 파일명도 기입해주어야 한다. 그래서 버전을 숫자 차례대로 저장하기 어렵다. 그래서 CI/CD 에서 자동화시키기 어렵다.
- 반면, flyway는 파일명의 규칙이 타이트한 대신, 버전을 숫자로 관리하기 쉽다.
파일명 규칙
- Prefix - V, U, R 중 하나를 입력하게 됩니다. V는 Verion, U는 undo, R은 Repeatable 입니다. 오늘은 V 만 사용하도록 하겠습니다.
- Version - 버전 정보입니다. 정수, 소수, 날짜 등이 가능합니다.
- Seperator - __ ( underscore 2개를 이용합니다. )
- Description - 추가되는 설명입니다. _ (underscore)가 space를 대신합니다.
서비스에 접목한다면, 서비스 이름과 DB변경사항 내용을 파일명으로 약속하면 될 것 같다.
ex) V1__Mamba_add_column.sql
ex) V2__Lama_new_table.sql
CI/CD 구현
전체 CI/CD 구조도는 ^위와 같다.
순서대로 살펴보면,
- 배포되는 브랜치일 경우에만 파이프라인이 돌아가도록 한다.
- 데이터 마이그레이션을 위한 sql 파일이 있는지 확인한다.
- 전체 sql 파일이 저장되어 있는 repository에서 sql 파일들을 clone하여 Shared Folder로 copy 한다.
- (모든 버전의 파일이 같은 작업공간에 존재해야 마이그레이션이 실행되기 때문이다.)
- Flyway를 도커에서 내에서 실행시키기위해 ECR에 올려둔 image를 pull 하여 가동시킨다.
- (도커에 flyway 공식 이미지가 있지만, 그것을 사용하려면 도커로그인 과정을 거쳐야 한다. 회사 공용계정이 없어 개인 계정으로 로그인 해야하기 때문에 공식 도커 이미지를 pull하는 것 보단, ECR에 이미지를 등록한 것이다.)
- flyway가 Shared Folder를 바라보고 실행되도록 bind mount 한다.
- flyway_schema_history에 올라와 있지 않은 새로운 버전의 sql파일이 있는지 확인한다.
- 있다면, 마이그레이션을 실행한다.
- 마이그레이션 도중 에러가 발생된다면, 배포되지 않도록 중단한다.
- DB 마이그레이션이 잘 실행되면 새로운 sql파일(마이그레이션 완료된)은 sql repository에 push 한다.
결과물
개발DB에 이 기능을 접목시킨다고 한다면,
개발 DB에 flyway_schema_history 테이블이 생성되고, sql 파일 history가 저장된다.
한가지 주의할점은, 최신 버전의 숫자보다 작은 숫자의 버전 sql 파일 실행 시 에러가 나지만,
최신 버전의 숫자보다 큰 숫자라면 바로 다음 숫자가 아니더라도 에러 없이 마이그레이션 된다.
그러므로 테이블을 확인하여 최신버전 숫자를 잘 기입해야 한다.
회고
- MSA 구조에서 DB를 한 개 사용하는 것은 매우 좋지 않은 방법이다.
- MSA 구조를 제대로 활용하지 못하고 있다.
- Human 에러를 줄일 수 있는 좋은 방법이다.
- DB도 서비스별로 분리시켰을 때, 더 고도화 해서 도입해보고 싶다.