[Flyway] Migration checksum mismatch 에러 해결

yeahdy_:)·2024년 6월 30일
post-thumbnail

docker-compose를 통해 mysql 컨테이너와 db를 마이그레이션 할 flyway 컨테이너를 올려놓았다.

테이블 마이그레이션을 위해 sql 파일에 CREATE 명령어를 작성 해 놓아서 컨테이너에 올라간 mysql 에 테이블이 정상적으로 생성되는 것까지 확인할 수 있었다.

그런데 테이블 칼럼명에 수정사항이 있어서 이미 마이그레이션한 sql 파일을 수정했더니 Flyway 에서 에러가 발생했다.

이슈

ERROR: Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 0
 -> Applied to database : 102434893
 -> Resolved locally    : -1325833510. Either revert the changes to the migration, or run repair to update the schema history.
 Need more flexibility with validation rules? Learn more: https://rd.gt/3AbJUZE

원인

원인은 Flyway의 마이그레이션 파일의 내용이 변경되었기 때문에 발생한 에러였다!

Flyway 는 마이그레이션에 대한 히스토리를 flyway_schema_history테이블에 기록 하는데,
flyway_schema_history 테이블 마이그레이션 파일의 내용을 기반으로 checksum 값을 계산하고, 이를 checksum칼럼의 데이터로 저장한다. 그리고 나중에 마이그레이션을 검증할 때, 파일의 현재 checksum 값과 flyway_schema_history테이블에 저장된 값이 일치하지 않으면 오류가 발생한다.

따라서 flyway_shcema_history테이블에 V0__init.sql 파일의 마이그레이션 내역이 이미 기록되어 있는데, V0__init.sql 파일의 내용을 로컬에서 변경해서 Flyway에 있는 V0__init.sql 파일과의 checksum이 맞지 않아 이슈가 발생했다.

(+ 단순히 공백이나 줄바꿈에 대한 수정사항은 에러가 발생하지 않고, SQL 명령문에 대한 변경사항이 있을 경우에만 checksum 에러가 발생했다.)


해결

수동으로 flyway_schema_history테이블에서 checksum 값을 맞춰주면 해결 가능하지 않을까 해서 checksum를 update 해봤지만 해결되지 않았다.

그래서 다시 마이그레이션이 되도록 flyway_schema_history 테이블에서 기존에 올려진 V0__init.sql 파일에 대한 레코드를 삭제했다.

그럼 Flyway는 V0__init.sql 파일을 마이그레이션한 내역이 flyway_schema_history테이블에 없기 때문에 다시 마이그레이션을 진행하고, 수정사항이 반영된 테이블로 생성된다.
(기존에 마이그레이션 된 테이블에 데이터가 없었기 때문에 새로 만들었다.)


Flyway 마이그레이션 성공 로그

Successfully validated 1 migration (execution time 00:00.024s)
Current version of schema `score`: 0
Schema `score` is up to date. No migration necessary.
Flyway Teams Edition 7.15.0 by Redgate
Database: jdbc:mysql://local-db/score (MySQL 8.0)

위 해결방법 외에 Flyway에서 repair 명령어로도 flyway_schema_history 테이블의 checksum 불일치 문제를 해결할 수 있다.


궁금증

그럼 스키마에 추가&수정 사항이 생기면 항상 새로운 버전의 파일을 만들고 마이그레이션을 진행해야하는 건가?

Flyway를 사용하는 목적은 데이터베이스의 버전관리를 통해 협업하는 개발자들 간에 데이터베이스의 변경사항을 체계적으로 관리할 수 있게 하기 위함이다.
따라서 Flyway는 Git과 같이 선형적인 버전 관리가 가능하기 때문에 개발자들이 데이터베이스 스키마 변경 사항을 순차적으로 적용할 수 있도록 지원한다.

그렇게 때문에 모든 팀원들이 동일한 데이터베이스 구조를 유지하고 변경 사항을 추적할 수 있도록 수정 사항이 생기면 V1__xxx.sql 과 같은 새로운 버전 파일을 만들어서 반영 해야 한다.


추가 SQL 파일 마이그레이션하기

/db/migration 경로에 새로운 sql 파일 생성

# V1__Alter_comment.sql
ALTER TABLE student_score MODIFY id BIGINT NOT NULL COMMENT '학생점수 고유키';
ALTER TABLE passed_exam MODIFY id BIGINT NOT NULL COMMENT '시험 합격 고유키';
ALTER TABLE failed_exam MODIFY id BIGINT NOT NULL COMMENT '시험 불합격 고유키';

docker-compose 에서 자동 마이그레이션이 되도록 설정 해 놓아서 flyway 에 바로 반영되는 것을 확인 할 수 있다.

flyway_schema_history 테이블 반영

passed_exam 테이블 comment 변경


Flyway 네이밍 규칙

사실 자동 마이그레이션을 하는데 작은 이슈가 하나 있었다.
분명히 docker-compose 파일에서 Flyway의 볼륨마운트와 자동 마이그레이션을 설정했는데, 반영이 안돼서 확인 해 보니 파일 네이밍이 문제였다.
(네이밍 규칙의 Separator 가 두 줄이 필수인걸 모르고 하나만 했다)


Flyway 네이밍 규칙 공식문서 기준

  1. Prefix
    파일의 종류를 결정하는 접두사
    버전 마이그레이션의 경우 ‘V’, 되돌리기 마이그레이션의 경우 ‘U’, 반복 마이그레이션의 경우 'R’을 사용한다.
  2. Version
    버전 번호로 점(.) 또는 밑줄(_)로 여러 부분을 구분할 수 있다.
    예를 들어 V2.0 __Create_Score_Table.sql
  3. Separator
    두 개의 밑줄(__)로 기능적인 파일 이름 부분과 설명 부분을 구분한다.
  4. Description
    밑줄(_) 또는 공백으로 단어를 구분하는 설명 부분이다.
  5. Suffix
    파일 확장자로 '.sql’을 사용한다.

규칙을 따르지 않으면 파일이 되어 제대로 반영되지 않을 수 있기 때문에 파일 이름을 정확하게 지정하는 것이 중요하다.

Flyway migration 참고 블로그에서 공식문서를 기준으로 설명을 잘 해놓으셔서 Flyway의 역할과 사용방법을 이해하는데 도움이 되었다.

profile
기억하기 위해 기록하고 있습니다. 포스트 중 잘못된 정보가 있다면 코멘트 남겨주세요🐰

0개의 댓글