Github Action을 활용한 MySQL DB Migration 자동화

Kyle·2022년 8월 17일
0
post-custom-banner

참고

Github Actions으로 배포 자동화하기 : NHN Cloud Meetup

Automating MySQL schema migrations with GitHub Actions and more

github api 사용방법

조사하게 된 배경

  • 현재 개발팀 상황

    • Pull Request 진행 시 배포가 필요한 Query를 직접 입력하여 요청
    • 배포 담당자는 Code Review를 진행하고, 이슈가 없는 경우 DB 변경내용을 운영 DB에서 직접 실행
    • PR Merge 진행
  • 개선 방향

    • 어떠한 방식으로든 상관없이 배포에 필요한 Query 입력 (DDL, DML)
    • Code Review 후 Merge 진행
    • Github Action에서 Merge감지 후 해당 Query 즉시 실행. (쿼리 배포 자동화)
  • django 환경이라면 django의 migration 명령어를 통해 서버 배포 스크립트에 run migration 스크립트를 포함시켜 DB migration 자동화를 진행할 수 있을거라고 생각한다. (django는 DB migration 관련이 python코드로 관리되고있고 동료 개발자도 해당 migration 파일을 확인해서 리뷰를 할 수 있다.)

  • 해당 기능을 제공하지 않은 프레임워크 / 서비스에서 개발하는 경우를 생각해서 조사를 진행해봤다. ( 현재 자동화를 고려하는 서비스가 django 기반이 아니기 때문에 제외했다. )

Github Action ?

Github에서 제공하는 workflow 를 자동화하도록 도와주는 도구
테스트, 빌드, 배포등 다양한 작업들을 자동화하여 처리함

기본적인 CI/CD 플로우

  1. 작업중인 브랜치에서 develop 에 Pull Request open
  2. PR 확인되면 Gtihub Action 동작
  3. Test 실행
  4. 테스트 통과시 develop 브랜치에 push
    1. push 발생하면 github Actions 동작
  5. 테스트 실패시 코드 미반영

Mysql Schema Migration 자동화

전제

  1. 스키마디자인은 코드로 관리되어야한다.
  2. 해당 스키마를 버저닝하여 어떤 버전과 연결되는지 명시되어야 한다.
  3. 일반적인 github 흐름인 commit, push, open pull request , review, approve, merge 흐름을 기본전제로 한다.

Skeema

Skeema.io
오픈소스 스키마 관리툴, git과 호환성이 좋다. github API를 통해 repository에 접근한다.

git diff로는 Skeema 의 변경점을 제대로 잡아낼 수 없는 점을 감안하여 만들어진 유틸리티

  • 대표적 기능
    • skeema diff
      • 기존 데이터베이스 스키마를 파일 시스템에 정의된 스키마로 변환하는 SQL 문을 생성한다. CREATE , ALTERDROP TABLE 등으로 생성된다.
    • skeema push
      • 스키마가 파일 시스템의 스키마와 일치하도록 실제로 데이터베이스 서버에 변경 사항을 적용한다.
    • skeema pull
      • MySQL 서버의 기존 스키마를 기반으로 파일 시스템 스키마를 다시 작성한다.
  • Skeema 의 skeema diff 를 사용하면 스키마 변경에 대해 아래와 같이 반환을 한다.
USE `test`;
ALTER TABLE `some_table` ADD COLUMN `time_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, DROP KEY `hostname`;

git diff 의 경우는 아래와 같이 나타난다.

  • 기존 tabe schema
    CREATE TABLE some_table (
      id int(10) unsigned NOT NULL AUTO_INCREMENT,
      hostname varchar(128) NOT NULL,
      PRIMARY KEY (id),
      KEY (hostname)
    );
  • 변경 schema
    • time_created 라는 새로운 column을 생성하고, hostname index를 삭제함

      CREATE TABLE some_table (
        id int(10) unsigned NOT NULL AUTO_INCREMENT,
        hostname varchar(128) NOT NULL,
        time_created TIMESTAMP NOT NULL,
        PRIMARY KEY (id)
      );
  • git diff
    • skeema diff 와의 차이점을 살펴보자

      @@ -1,6 +1,6 @@
       CREATE TABLE some_table (
         id int(10) unsigned NOT NULL DEFAULT 0,
         hostname varchar(128) NOT NULL,
        -  PRIMARY KEY (id),
        -  KEY (hostname)
        +  time_created TIMESTAMP NOT NULL,
        +  PRIMARY KEY (id)
       );

위 예시처럼 git diff는 실제 schema 의 변경점을 확실하게 잡지 못하기 때문에, 코드 확인에 불편함을 겪게된다.

Github Action

일반적인 CI/CD 작업을 참고하여 auto migration action 작업을 구상한다.

  1. Fetch Schema binary
  2. checkout master branch
  3. skeema push 를 통해 master branch의 schema 로 MySQL 서버에 적용한다.
  4. checkout PR branch
  5. skeema diff 를 사용하여 MySQL 서버와 현재 branch의 schema 차이점을 확인한다.
  6. diff 결과를 Pull Request comment에 추가한다.
  7. Schema 변화를 확인할 수 있도록 PR에 라벨을 추가한다.
  • 예시

이러한 작업과정에서 확인해야 할 점은, 이 모든 과정이 git repository로 제한된다는 것이다.

git repository는 schema 가 어디로 배포되야 할 지 정보를 갖고있지않으며, 이는 git repo의 범위를 벗어나는 정보이다. schema가 production에 도달하게 하기 위해선 어떻게 해야할까?

Skeefree

gh-mysql-tools/skeefree at master · github/gh-mysql-tools

  • 스키프리는 위의 과정에 필요한 서비스이다.
  • 스키마를 통해 DB 마이그레이션을 진행하기 위해서는 다양한 고려사항이 필요하다.
  • skeefree는 저장소를 인식하고, pull request와 통신하여 migration을 호출하는 orchestrating service 이다.

skeefree는 Github API를 사용하여 pull request, github 내부 저장소 및 검색서비스와 상호작용하여 프로덕션에서 클러스터를 찾아 gh-ost를 사용하여 마이그레이션을 실행한다.

아래 설명할 schema migration flow를 통해 skeefree가 어떻게 동작하는지 대략적으로 확인할 수 있다.

Schema Migration Flow ( Skeefree 활용 )

  1. 스키마를 변경하려는 개발자가 PR을 open한다.
  2. git action은 open PR을 인식하여 skeema diff 를 실행하여 스키마 변경을 확인한다. pull request 에서 스키마 변경이 발견되지 않으면 아무행동도 취하지 않는다. 스키마 변경이 있는 경우, action은 skeema 를 통해 변경점을 확인하고, pull request에 comment 추가 및 migration:skeema:diff 라벨을 추가한다. ( 위 프로세스는 github API를 통해 수행한다. )
  3. 개발자는 변경사항을 보고 팀원에게 review를 요청한다. 라벨은 migration:for:review 로 변경한다.
  4. skeefree 는 github API를 사용하여 migration:skeema:diff migration:for:review 라벨을 주기적으로 확인하여, 최소한 한 명의 개발자가 승인한 pull reqeust 를 탐색한다.
  5. 적절한 PR이 탐색되면 skeefree는 pull request 를 확인하고, action에 의해 생성된 스키마 변경 comment를 확인한다. 그 후 schema/repository 에서 schema/production cluster로 매핑을 시도하고, 저장소 및 검색서비스를 이용하여 클러스터가 샤딩되었는지를 확인한다.
  6. 정상적으로 프로세스가 진행되면 아래처럼 comment를 남기게된다. 이 comment 이 PR이 승인될시 실행 될 action을 뜻한다. 이 comment를 보고 개발자는 최종 확인을 한다.
  7. 승인이 되면 migration작업을 queue 대기열에 위치시킨다
  8. skeefree는 타겟 클러스터에서 관련 작업이 진행되고있는지 확인을 한 후 migration을 진행한다. 이 때 pull request 에 migration이 시작됐다는 comment가 생성된다.
  9. migration이 완료되면 PR comment에 완료됐다는 내용이 등록된다. 실패의 경우도 동일하다.

적용 가능성

Database migration 자동화에 대해 찾아본 결과 생각보다 참고 자료를 찾을 수가 없었다. 위의 내용 역시 검색을 하면서 DB migration 자동화에 고민을 하고, 관련 프로젝트를 구현하여 소개하는 블로그의 글을 인용한것이 전부이다. skeefree를 이용한 schema migration 자동화에 대해 좀 더 찾아보려했으나 참고할 정보들이 매우 적었다.

Database migration 작업은 운영에 영향을 미치는 민감한 작업이다보니 테스트서버에서 조사한 부분들을 충분한 기간동안 적용시켜본 후, 해당 프로젝트의 개발자들이 사용성이 좋다고 판단됐을때 적용하는 것이 좋아보인다.

위 내용들은 찾아보면서 단순히 schema에 대한 지식뿐만아니라 전반적인 프로젝트의 운영, github flow, git action에 대한 폭넓은 이해가 필요하다고 생각된다.

profile
깔끔하게 코딩하고싶어요
post-custom-banner

2개의 댓글

comment-user-thumbnail
2022년 12월 20일

유익한 포스팅이네요. 좋은 글 감사합니다

1개의 답글