View
본 문서는 아래 버전을 사용하였음
liquibase-4.4.0
postgres 13.3
docker community
JHipster라는 자바 프로젝트 생성 툴을 사용했는데 자동으로 import해주는 여러 라이브러리들 중 모르는 것들이 많이 보여 그 중 하나인 liquibase가 어떤 것인지 찾아보았다.
Concept
데이터베이스의 스키마를 xml, sql, yaml, json으로 관리해주는 툴입니다. 원하는 데이터베이스의 스키마의 변화를 버전별로 관리할 수 있다.
예를들어 liquibase로 초기 데이터베이스부터 관리한다고 하면
liquibase 툴의 포맷에 맞는, 테이블 생성/컬럼 설정 등 create 관련된 작업들이 기록된 xml을 생성한다. 대략적인 양식은 아래와 같다.
<liqubase> <스키마 변화1> <테이블 생성> <컬럼1 생성/> <컬럼2 생성/> </테이블 생성> </스키마 변화1> </liqubase>
작업하다보니
컬럼3
이 필요하다고 판단되어 liqubase 설정 파일에컬럼3
을 추가했다.<liqubase> <스키마 변화1> <테이블1 생성> <컬럼1 생성/> <컬럼2 생성/> </테이블1 생성> </스키마 변화1> <스키마 변화2> <컬럼추가 타겟테이블="테이블1"> <추가할_컬럼 이름="컬럼3"/> </컬럼추가> </스키마 변화2> </liqubase>
위와같이 스키마의 변화, 데이터의 insert, update, delete를 기록할 수있으며 툴을 실행하여 어떤 변화
로 돌아갈 것인지, 새로운 데이터베이스를 구축했는데 어떤 단계의 변화
까지 실행할 것인지 툴을 통해 제어할 수 있다.
Community, Pro 두가지 버전을 제공하고 있다. 지원하는 데이터베이스 범위도 매우 넓어 NoSQL 등도 지원한다.
Test
먼저, 테스트를 위한 postgres docker를 실행하였다.
docker run --rm --name postgres-test -p 15432:5432 -e POSTGRES_PASSWORD=password -d postgres:latest
Liqubase download page에서 제공하는 zip 파일을을 받고 압축 파일을 푼다. , 해당 폴더에서 cmd 창을 실행하였다.
liquibase를 실행해서 데이터베이스 작업을 하려면 클래스패스에 jdbc와 같은 데이터베이스 드라이버 라이브러리가 있어야 하므로 maven repository에서 postgres jdbc를 다운로드받야 lib파일에 넣어두어야 한다.
동작에 필요한 다양한 정보들(데이터베이스의 url/user/password, liquibase의 다양한 설정들)은 liquibase.properteis
파일에 설정하는 방법이 있고, 명령어 실행 시 옵션을 입력하는 방법이 있는데 이번에는 간단한 테스트가 목적이라 바로 커맨드라인에서 입력하여 진행을 할 것이다.
스키마의 변경을 기록하는 작업 파일은 별도로 생성하여야 한다.
아직 데이터베이스에 아무것도 없는 상태이므로 스키마 생성을 위한 내용을 입력한다.
<?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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
<changeSet id="1" author="Liquibase">
<createTable tableName="test_table">
<column name="test_id" type="int">
<constraints primaryKey="true"/>
</column>
<column name="test_column" type="varchar"/>
</createTable>
</changeSet>
</databaseChangeLog>
chageSet이 변경점을 기록하는 point라고 보면 되고 그 아래로 하고자하는 행위가 기록된다. 위는 간단하게 test_table
이라는 테이블을 생성하는데 test_id
라는 int
형 컬럼을 생성하고 해당 컬럼을 private key
로 지정하였다. 추가로 test_column
이라는 컬럼도 같이 추가하였다.
해당 파일을 chage_log.xml
이라는 파일로 저장하고 updateSQL
을 실행시키면 liquibase
에서 실행하려고 하는 쿼리문을 확인할 수 있다.
.\liquibase --url jdbc:postgresql://localhost:15432/postgres `
--username=postgres `
--password=password `
--changeLogFile=changelog.xml `
updateSql
명령어의 구성을 보면 --
로 옵션을 입력하였고 맨 마지막에 행위에 대한 명령어를 입력하였다. updateSql
은 단순 쿼리만 출력하고 실제 실행은 하지 않으며 update
명령어를 입력하면 데이터베이스에 바로 적용된다.
.\liquibase --url jdbc:postgresql://localhost:15432/postgres `
--username=postgres `
--password=password `
--changeLogFile=changelog.xml `
update
위 명령어를 실행하고 데이터베이스를 확인하면 원하는 모양을 가진 test_table
이 생성된 것을 확인할 수 있다. 참고할 만한 것은 같은 위치에 databasechangelog
, databasechangeloglock
테이블이 자동으로 생성된 것을 확인할 수 있는데 이는 liquibase에서 기록을 저장하고 엑세스를 제어하는 테이블이다.
changeSet 생성하기
컬럼을 변경하기 위해 changeSet
을 하나 더 입력해보자.
<?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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
<changeSet id="1" author="Liquibase">
<createTable tableName="test_table">
<column name="test_id" type="int">
<constraints primaryKey="true"/>
</column>
<column name="test_column" type="varchar"/>
</createTable>
</changeSet>
<changeSet id="2" author="abcd">
<addColumn tableName="test_table">
<column name="name" type="varchar"></column>
</addColumn>
</changeSet>
</databaseChangeLog>
test_table
이라는 테이블에 name
이라는 컬럼을 추가하하고 update를 실행하면 컬럼이 하나 더 추가된 테이블을 확인할 수 있다.
.\liquibase --url jdbc:postgresql://localhost:15432/postgres `
--username=postgres `
--password=password `
--changeLogFile=changelog.xml `
update
이전 변경으로 돌아가고 싶을 때 chageSet
의 id
속성을 이용하 특정 포인트의 시점으로 바로 돌아갈 수 있다.
Caution
single side management
해당 작업들은 기존의 테이블, 칼럼에 영향을 미치지 않는다. 그리고 liquibase로 변경된 스키마 이외는 신경쓰지 않는다. 따라서 아래와 같은 상황이 발생할 수 있다.
- liquibase로 테이블 1, 컬럼 a, b, c를 만들었는데 이후에 liquibase를 사용하지 않고 DB 툴을 사용하여 컬럼 d를 추가하였다.
- 개발자는 liquibase의 xml 파일을 보고 테이블1의 컬럼이 a, b, c인줄 알았는데 실제로 확인해보니 컬럼 d도 있었다.
이와같은 특성으로 인해 liquibase로 변경하지 않는 변경과 섞여서 개발자가 원하지 않는 형태로 관리될 수 있으므로 한쪽으로만 관리가 필요하다.
Lock
자동으로 생성된 테이블 중 databasechangeloglock
테이블은 여러개의 liquibase 인스턴스가 동시에 작업하는 것을 막기 위한 lock 용도로 사용되는 테이블이다. kubernetes와 같은 환경에서 여러개의 liquibase가 하나의 데이터베이스에 접근할 경우 lock으로 인해 문제가 발생할 수 있다.
Conclusion
스프링의 경우 import.sql
, data.sql
또는 jpa의 ddl generation
등 스키마, 데이터를 관리할 수 있는 기능을 제공하지만 liquiside는 훨씬 더 넓은 범위에서 체계적으로 관리할 수 있는 데이터베이스 버저닝 관리 도구이다. 관련 정책, 개발 플로우등을 잘 적용해서 사용한다면 유용한 도구가 될 수 있을 것으로 판단된다.
Refer
'Database' 카테고리의 다른 글
PostgreSQL Document - Transactions, Transaction Isolation (0) | 2022.01.19 |
---|---|
PostgreSQL Document - The Path of a Query (0) | 2022.01.11 |