본문 바로가기
데이터베이스

Liquibase (리퀴베이스) 사용기

by 성건희 2022. 7. 8.
반응형

회사 데일리 스크럼에서 팀장님이 리퀴베이스에 대해 말씀해주셨는데, 처음 듣는 단어여서 뭔지 궁금했다.
그래서 실습을 해보면서 리퀴베이스가 뭔지 익혀보기로 했다!

리퀴베이스란?

우리는 소스코드 형상관리를 위해서 GIT 을 주로 사용한다.
코드는 GIT으로 형상관리 하는데.. DB 는..?
DB 를 형상관리하는 것리퀴베이스다.

실습해보기

Spring-boot, JPA, liquibase, h2 DB 로 실습을 해보았다.

Dependencies 추가

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.liquibase:liquibase-core'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

그 후 application.yml 을 아래와 같이 설정한다.

spring:
  datasource:
    url: jdbc:h2:tcp://localhost/~/springbook
    username: sa
    password:
    driver-class-name: org.h2.Driver

  jpa:
    hibernate:
      ddl-auto: create
    show-sql: true
    database-platform: org.hibernate.dialect.H2Dialect

  liquibase:
    change-log: classpath:/db/changelog/db.changelog-master.xml

리퀴베이스를 사용하면 DB 의 변경점을 기록해주어야 하는데,
위 설정에서 change-log 에 xml 파일이 그 역할을 한다. 이것으로 변경점을 계속 기록하여 형상관리 하는 듯 하다.
리퀴베이스 설정을 하지 않으면 어플리케이션 실행 시 에러가 발생하니 주의하자.
xml 이외에 yaml, json 으로도 사용할 수 있다.


db.changelog-master.xml 은 아래와 같이 만들어 주었다.

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
    http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <changeSet id="changelog-1.0" author="geonhee">
        <createTable tableName="test-table">
            <column name="id" type="BIGINT" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="name" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="reg_date" type="TIMESTAMP(6) WITHOUT TIME ZONE" defaultValue="now()">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>

</databaseChangeLog>

changeSet 태그는 하나의 변경 이력을 나타낸다. id 를 기준으로 스키마 변경 내역이 구분된다.
author 는 변경 이력을 추가한 사람을 넣어주면 된다.
createTable 은 테이블 생성을 정의한다. 테이블 이름은 test-table 로 지었다.
column 은 테이블을 구성하는 컬럼을 정의한다. constraints 태그로 제약을 줄 수 있다.


위 처럼 만들어 두고 어플리케이션을 실행하면..?

3 개의 테이블이 만들어진다.
맨 밑의 test-table 은 우리가 만들었다는 건 알겠는데...
그 위에 DATABASECHANGELOG, DATABASECHANGELOGLOCK 테이블은 뭘까..?

DatabaseChageLog 와 DatabaseChangeLogLock

DatabaseChageLog변경 이력을 저장하는 테이블이다.


DatabaseChangeLogLock문제가 발생하면 DB 에 락을 거는 테이블이다.

락이 걸리면 LOCKED 컬럼이 FALSE 에서 TRUE 로 바뀌는데, 이를 다시 FALSE 로 바꾸면 정상 작동하게 된다.

JPA DDL create 사용해보기

이왕 JPA 를 추가했으니 Team 엔티티를 추가해보자.

@Entity
public class Team {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "team_id")
    private Long id;

    private String name;
}

위 상태에서 JPA 의 DDL 옵션을 create 로 바꾸고 실행한다면..?
정상적으로 JPA 가 team 테이블을 만들어준다.
하지만 DatabaseChageLog 테이블에 변경 이력이 기록되지는 않았다.
리퀴베이스가 만든게 아닌 JPA 가 만든것이기 때문이다.


여기서 알 수 있는 사실은.. 리퀴베이스를 쓰기로 했다면 직접적으로 스키마를 수정하면 안된다는 것이다.
변경 이력이 남지 않기 때문에, 반드시 리퀴베이스 설정 파일에서 변경 이력을 등록하여 사용하길 권장한다.


(JPA create 가 안되면 어떻게 기록하나요? 라고 질문할 수 있지만 실제 현업에서 create 를 사용하는 것은 기존 데이터를 다 날려버리는 어메이징한 행위이기 때문에, 보통 현업에서는 none 으로 사용하니 큰 문제는 아니다. 리퀴베이스를 통해 잘 기록하자!)

컬럼 수정하기

리퀴베이스로 만든 기존 테이블에서 컬럼을 하나 제거하고 싶다면 어떻게 해야할까?

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
    http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <changeSet id="changelog-1.0" author="geonhee">
        <createTable tableName="test-table">
            <column name="id" type="BIGINT" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="name" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="reg_date" type="TIMESTAMP(6) WITHOUT TIME ZONE" defaultValue="now()">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>

    <changeSet id="changelog-1.1" author="geonhee">
        <dropColumn tableName="test-table" columnName="reg_date"/>
    </changeSet>

</databaseChangeLog>

위처럼 changeSet 을 하나 추가해서 dropColumn 태그로 날려주면 된다.
dropColumn 이외에도 다양한 태그가 있으니 필요한 태그를 찾아서 사용하면 될 것 같다.


추가한 뒤 어플리케이션을 실행해보자.


reg_date 컬럼이 제거되었다는 로그가 찍히고, DatabaseChageLog 테이블을 확인해보면..


changelog-1.1 의 DESCRIPTION 컬럼에서 test-table 테이블의 reg_date 컬럼을 제거했다는 내역이 추가됨을 확인할 수 있다.

회고

실습을 진행해보니 확실히 리퀴베이스를 사용해서 형상 관리를 하니 언제 테이블 변경이 이루어졌는지 파악하기 수월하다는 장점이 있는 것 같다. 리퀴베이스플라이웨이가 DB 형상관리를 한다는 점에서 역할이 비슷한 것 같은데..
사실 플라이웨이도 들어만봤지 써보진 않아서 명확한 차이는 잘 모르겠다. 기회가 되면 학습해봐야지~

참고

반응형

'데이터베이스' 카테고리의 다른 글

대용량의 데이터로 MySQL 학습하기  (0) 2022.01.12
인덱스란?  (0) 2019.10.17
데이터베이스  (2) 2019.05.16
MySQL 데이터 저장 시 한글 깨짐 현상  (2) 2019.04.08

댓글