728x90
반응형
DB 형상 관리 - FlyWay
DB 형상관리
DB 형상관리(Database Version Control 또는 Database Source Control)는 데이터베이스의 스키마, 데이터 및 관련 객체를 버전 관
리하는 프로세스.
이를 통해 데이터베이스 변경 사항을 추적하고 관리하여 개발자 및 운영팀이 데이터베이스를 일관되게 유지할 수 있다.
Liquibase
Liquibase는 Java 기반의 오픈 소스 데이터베이스 마이그레이션 도구.
- XML 또는 YAML 과 같은 마크업 언어를 사용하여 데이터베이스 스키마 변경을 기술.
- 변경 사항을 버전 관리하여 데이터베이스를 업데이트.
- 데이터베이스의 변경 내역을 추적하는데 주로 사용됨.
Flyway
Flyway는 오픈 소스의 자동화된 데이터베이스 마이그레이션 도구.
- SQL 스크립트를 이용하여 데이터베이스 변경 사항을 버전 관리.
- 간단한 커맨드 라인 도구 및 Maven, Gradle 같은 빌드 도구와 통합되어 있어 사용 용이.
- 각 마이그레이션 파일의 적용 여부를 추적하는데 중점.
- 데이터베이스의 현재 상태를 버전 관리하여 스키마를 자동으로 업데이트.
Flyway
네이밍 규칙
Prefix : V, U, R 중 하나
Version : 버전정보 ( 정수 뿐만 아니라 소수, 날짜도 가능 )
Separator : 언더바 2개 __
Description : 파일 설명
파일명 예시 : V1__init.sql V20220104__insert_data.sql
Flyway 적용
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
spring.datasource.hikari.driver-class-name = org.postgresql.Driver
spring.datasource.hikari.jdbcUrl=jdbc:postgresql://<IP:Port>/<Schema>
spring.datasource.hikari.username=<User>
spring.datasource.hikari.password=<Password>
경로 및 flyway 옵션
디폴트로 src/main/resources/db/migration 폴더가 설정 되어 있음.
application.properteis 로 수정 가능.
# 마이그레이션 스크립트 위치 설정
flyway.locations=classpath:db/migration,filesystem:./src/main/resources/db/migration
# 마이그레이션 실행 여부 설정
flyway.enabled=true
# 스키마 버전 테이블명 설정
flyway.table=schema_version
# 마이그레이션 스크립트 파일명 접두사 설정
flyway.sql-migration-prefix=V
# 마이그레이션 스크립트 파일명 구분자 설정
flyway.sql-migration-separator=__
# 마이그레이션 스크립트 파일 확장자 설정
flyway.sql-migration-suffix=.sql
# 마이그레이션 스크립트 인코딩 설정
flyway.encoding=UTF-8
주의 사항
한 번 마이그레이션을 한 sql 파일은 절대로 수정하면 안 된다. (에러발생함)
따라서 DB 에 변경사항이 생겨서 DB에 수정작업을 해야한다면 버전업을 한 sql 파일을 새로 생성하게 다시 적용하는 수 밖에 없다.
서버 실행
- 서버 실행 시 위와 같은 로그로 location 경로에 있는 /db/migration/V20240611__init.sql` 이 적용 되었다는 로그
- 자동적으로 flyway_schema_history 라는 테이블이 생기게 되고, migration이 적용된 history가 기록되게 된다.
추가로 V20240611_02__user_add_column_gender.sql 파일을 추가하였을 경우
- 성공 로그와 함께 기록이 저장된 모습.
궁금증 1. DB 스키마는 변경하고 FlyWay 파일을 기록하지 않는다면?
-- test column 추가
ALTER TABLE users
ADD COLUMN test varchar(100);
create table users
(
id integer not null
primary key,
username text not null,
email text not null
unique,
test varchar(100)
);
- DB에 저장되어 있는 가장 최신 version을 먼저 찾게되고, 더 이상 추가된 버전 파일이 존재 하지 않게 되면 변경이 없음으로 판단.
- No migration necessary 라는 문구와 함께 히스토리 기록 X
궁금증 2. 테이블도 직접 변경하고, Version 파일도 생성하면?
ALTER TABLE users
ADD COLUMN test2 varchar(200);
create table users
(
id bigint not null
primary key,
username varchar(255) not null,
password varchar(255) not null,
email varchar(255) not null,
gender varchar(10),
test varchar(100),
test2 varchar(200)
);
V20240611_03__user_add_column_test2.sql
ALTER TABLE users
ADD COLUMN test2 varchar(200);
- 위의 사진과 같이 실패하게 되고 서버 실행 불가능.
- 실패에 대한 서버 로그는 추가되지 않음.
궁금증 3. [ 2 ] 의 궁금증에서 flyway.enbaled=false 를 하게 된다면?
- 아무런 동작을 하지 않게된다.
- 해당 옵션의 경우 flyway를 사용하지않게 된다.
- flyway 를 자동으로 사용하지 않을 경우에 사용하는 옵션.
궁금증 4. DB에 영향을 미치지 않고, History만 기록되는것은 가능한지?
[ 방법 - 1 ] 아무런 영향을 미치지 않는 SQL문 작성
- V20240611_03__user_add_column_test2.sql
SELECT 1
- 기존에 에러가 발생하던 flyway 파일임.
- SELECT 1 과 같이 DB에 아무런 영향을 주지 않는 파일을 작성.
- 정상적으로 실행은되나, 형상관리를 파일명과 description을 통해서만 진행해야 한다는 큰 단점이 존재.
[ 방법 - 2 ] 주석을 통해 실제 쿼리문은 수행되지 않고, 기록만 남기도록 수행
[ 방법 - 2.1 ] flyway의 placeholders 옵션을 이용한 주석
spring.flyway.placeholders.ignore=--
V20240611_05__user_add_column_test3.sql
${ignore} ALTER TABLE users ADD COLUMN test3 varchar(300);
- 해당 Placeholders 를 SQL 문에서 사용되는 주석 기호 –– 로 나타 냄으로써 실제 쿼리는 수행되지 않도록 진행.
[ 방법 - 2.2 ] ANSI SQL 의 주석 형식을 이용해 주석 처리
V20240611_06__user_add_column_test3.sql
/*
CREATE TABLE users (
id BIGINT PRIMARY KEY,
username VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL
);
*/
-- ALTER TABLE users ADD COLUMN test3 varchar(300);
- 두 가지 방법 모두 잘 적용됨.
- 이렇게 한다면 DB에 실제 쿼리 내용은 반영되지 않지만, 기록으로 남겨둘 수 있음.
- 단, 다른 사용자가 해당 버전들을 자신의 DB 혹은 다른 DB에 적용시킬 때 주석을 해제하고 실행시켜야 된다는 번거로움 존재.
[ 방법 - 3 ] 쿼리 본문 실행을 Transaction으로 감싸기
V20240611_07__user_add_column_test3.sql
DO $$
BEGIN
-- Start a transaction
BEGIN;
-- Your actual migration SQL (will not be executed)
ALTER TABLE users ADD COLUMN test2 varchar(200);
-- Intentional error to rollback the transaction
RAISE EXCEPTION 'Intentional error to rollback transaction';
-- Commit transaction (this line will never be reached)
COMMIT;
EXCEPTION WHEN OTHERS THEN
-- Rollback transaction
ROLLBACK;
END $$;
- 일부러 쿼리가 실행될 경우 실패할 구문을 넣음. (이미 존재하는 컬럼 추가 명령)
- 쿼리가 실패하면서 flyway의 동작에 문제가 생겨서 애플리케이션 실행 불가능. 히스토리 기록 X
728x90
반응형
'1.프로그래밍 > DB' 카테고리의 다른 글
[DB] DB 형상 관리 - Liquibase Best Practices (5) | 2024.09.01 |
---|---|
[DB] DB 형상관리 - Liquibase (0) | 2024.08.31 |
[DataSource] DataSource 설정 정리 (0) | 2023.03.23 |
[Redis] WRONGTYPE Operation against a key holding the wrong kind of value (0) | 2023.02.02 |
[MyBatis] org.apache.ibatis.binding.BindingException: Parameter 'userName' not found. Available parameters are [arg1, arg0, param1, param2] MyBatis 에러 (0) | 2022.11.23 |