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테이블에 기록 하는데,
마이그레이션 파일의 내용을 기반으로 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 과 같은 새로운 버전 파일을 만들어서 반영 해야 한다.
/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 변경

사실 자동 마이그레이션을 하는데 작은 이슈가 하나 있었다.
분명히 docker-compose 파일에서 Flyway의 볼륨마운트와 자동 마이그레이션을 설정했는데, 반영이 안돼서 확인 해 보니 파일 네이밍이 문제였다.
(네이밍 규칙의 Separator 가 두 줄이 필수인걸 모르고 하나만 했다)
규칙을 따르지 않으면 파일이 되어 제대로 반영되지 않을 수 있기 때문에 파일 이름을 정확하게 지정하는 것이 중요하다.
Flyway migration 참고 블로그에서 공식문서를 기준으로 설명을 잘 해놓으셔서 Flyway의 역할과 사용방법을 이해하는데 도움이 되었다.