Liquibase 란
Liquibase는 데이터베이스 스키마 변경 관리 솔루션이며, 개발부터 프로덕션까지 데이터베이스 변경을 더 빠르고 안전하게 수정하고 배포하는 데 도움이 된다. SQL, XML, JSON, YAML과 같은 다양한 형식을 사용하여 데이터베이스 변경 내용을 정의하고 추적할 수 있다.
또한, Liquibase는 "rollback" 기능을 제공하여 변경사항을 쉽게 되돌릴 수 있다. 일부 변경사항은 자동으로 rollback SQL을 생성하지만, 테이블 삭제나 데이터 추가와 같은 변경사항은 직접 rollback 태그를 작성하여 구문을 지정해야 한다.
Liquibase는 주로 6가지 기본 커맨드를 제공한다: update, rollback, snapshot, diff, status, 그리고 utility 커맨드들이 있디. 또한, Liquibase는 변경사항을 배포할 때 두 개의 테이블, DATABASECHANGELOG와 DATABASECHANGELOGLOCK을 데이터베이스에 생성한다. DATABASECHANGELOG 테이블은 배포된 변경사항을 추적하는 데 사용되며, DATABASECHANGELOGLOCK 테이블은 동시에 여러 인스턴스의 Liquibase가 데이터베이스를 업데이트하는 것을 방지하는 데 사용된다.
마지막으로, Liquibase는 여러 가지 방법으로 데이터베이스 변경을 관리할 수 있다. 커맨드 라인 클라이언트를 실행하거나, 자바 API를 통해 애플리케이션에 통합하거나, Maven, Spring Boot, Ant, Jenkins, GitHub Actions 등의 CI/CD 도구를 사용하여 빌드 프로세스에 통합하거나, Docker와 같은 임시 환경에서 실행하는 등 다양한 방법이 있다.
Changeset
Liquibase는 "changeset"이라는 개념을 사용하여 데이터베이스 변경사항을 추적한다. Changeset은 고유한 ID와 author를 통해 식별된다. 다수의 changeset이 databaseChangeLog 태그 안에 작성될 수 있다.
ID는 식별을 위해서 사용되며, 변화의 순서를 의미하지 않으므로 숫자로 작성될 필요는 없다. DATABASECHANGELOG라는 테이블에서 id/author/filepath 로 changeset의 실행 여부를 확인한다.
각 changeset은 하나의 트랜잭션에서 실행되며, 성공적으로 완료되면 커밋되고, 에러가 발생하면 롤백된다. 그러나 데이터베이스에 따라서 auto commit이 될 수도 있으므로 하나의 changeset에는 하나의 변경사항만 작성하는 것을 권장한다. 또한, Liquibase는 다양한 속성을 제공하여 changeset의 동작을 세밀하게 제어할 수 있다.
Changeset의 속성
id | 필수 숫자와 알파벳으로 이루어진 식별자 |
author | 필수 체인지셋의 작성자 |
dbms | 사용될 데이터베이스의 타입을 명사한다. 마이그레이션이 수행될 때, 데이터베이스의 타입을 체크한다. 컴마로 다수의데이터베이스를 작성할 수 있고, ! 프리픽스로 특정 데이터베이스를 제외할 수 있다. |
runAlways | 체인지셋을 항상 실행한다. |
runOnChange | 체인지셋이 처음 등록이 되었을 때 실행하고, 이후에는 변경이 될 때마다 실행한다. |
Contexts | 런타임 세팅에 따라서 실행 여부를 조절한다. |
Labels | 런타인 세팅에 따라서 실행 여부를 조절한다. |
runInTransaction | 하나의 트랜잭션에서 실행할지 여부를 명시한다. 기본값은 true이다. |
failOnError |
실패하였을 때, 마이그레이션의 실패여부를 정의한다. 기본값은 true이다. |
objectQuotingStrategy |
어떤 방식으로 이름이 따옴표로 감싸질지 조정한다. |
runOrder |
체인지셋의 실행순서를 조정하고 싶을 때 사용한다. 처음에 실행되게 하고 싶은 경우는 first 마지막에 실행하고 싶은 경우는 last를 주면 된다. |
created |
|
ignore |
체인지셋이 실행되지 않도록 한다. |
logicalFilePath |
유일한 식별자를 위해서 파일 이름을 오버라이드한다. 체인지로그의 이름을 다시 짓거나 파일을 이동할 때 필요하다. |
Rollback
Liquibase로 changset으로 작성한 구분을 rollback을 해보면 Liquibase가 알라서 rollback SQL을 작성하는 것을 알 수 있다. 어디까지 자동으로 생성해주는 것일까?
도큐먼트를 확인해보니, 테이블 생성, 칼럼명 변경, 칼럼 추가와 같은 것들은 자동으로 rollback 구문을 생성해준다고 한다. 반면 테이블 삭제(drop table), 데이터 추가(insert data) 의 경우에는 rollback 구문을 생성해주지 못한다고 한다. 이 경우에는 changeset 태그 안에, rollback 태그를 작성하여 직접 구문을 작성해주면 된다.
Liquibase task 종류
gradle tasks 로 확인한 liquibase task들이다.
calculateCheckSum | Calculates and prints a checksum for the <liquibaseCommandValue> changeset with the given id in the format filepath::id::author. |
changelogSync | Mark all changes as executed in the database. |
changelogSyncSQL | Writes SQL to mark all changes as executed in the database to STDOUT. |
clearChecksums | Removes all saved checksums from the database. On next run checksums will be recomputed. Useful for "MD5Sum Check Failed" errors. |
dbDoc | Generates Javadoc-ike documentation based on current database and change log to the directory. |
diff | Writes description of differences to standard out. 레퍼런스 DB와 현재 DB의 차이를 출력한다. |
diffChangeLog | Writes Change Log to update the database to the reference database to standard out 레퍼런스 DB로 업데이트하기 위한 체인지 로그를 출력한다. |
dropAll | Drops all database objects owned by the user. Note that functions, procedures and packages are not dropped (Li quibase limitation) 함수와 프로시져 패키지는 제외한 DB 오브젝트드들을 drop 한다. |
executeSql | Executes SQL in the database given in in this format: -PliquibaseCommandValue="--sql=select 1" or -PliquibaseCommandValue="--sqlFile=myfile.sql" futureRollbackCountSQL - Writes SQL to roll back changes the database after the changes in the changelog have been applied. |
futureRollbackSQL | Writes SQL to roll back the database to the current state after the changes in the changeslog have b een applied. |
generateChangelog | Writes Change Log groovy to copy the current state of the database to standard out. |
listLocks | Lists who currently has locks on the database changelog. |
markNextChangesetRan | Mark the next change set as executed in the database. 다음 체인지 셋을 실행상태로 마크한다. |
markNextChangesetRanSQL | Writes SQL to mark the next change set as executed in the database to STDOUT. |
releaseLocks | Releases all locks on the database changelog. |
rollback | Rolls back the database to the state it was in when the <liquibaseCommandValue> tag was applied. liquibaseCommandValue로 지정된 태그의 위치로 DB를 롤백한다. |
rollbackCount | Rolls back the last <liquibaseCommandValue> change sets. <liquibaseCommandValue> 체인지셋 개수만큼 롤백한다. |
rollbackCountSQL | Writes SQL to roll back the last <liquibaseCommandValue> change sets to STDOUT. <liquibaseCommandValue>개의 체인지셋을 롤백시 적용되는 SQL를 출력한다. |
rollbackSQL | Writes SQL to roll back the database to the state it was in when the <liquibaseCommandValue> tag was appli ed to STDOUT. <liquibaseCommandValue> tag까지 롤백시에 적용되는 SQL를 출력한다. |
rollbackToDate | Rolls back the database to the state it was in at the <liquibaseCommandValue> date/time. |
rollbackToDateSQL | Writes SQL to roll back the database to the state it was in at the <liquibaseCommandValue> date/time to STDOUT. |
snapshot | Writes the current state of the database to standard out 현재 DB의 상태를 출력한다. |
snapshotReference | Writes the current state of the referenceUrl database to standard out 레퍼런스 DB의 상태를 출력한다. |
status | Outputs count (list if liquibaseCommandValue is "--verbose") of unrun change sets. 아직 실행되지 않은 change set의 개수를 출력한다. 만약 --verbose 옵션을 주면 list를 보여준다. |
tag | Tags the current database state with <liquibaseCommandValue> for future rollback. |
tagExists | Checks whether the tag given in <liquibaseCommandValue> is already existing |
unexpectedChangeSets | Outputs count (list if liquibaseCommandValue is "--verbose") of changesets run in the database th at do not exist in the changelog. |
update | Updates the database to the current version. |
updateCount | Applies the next <liquibaseCommandValue> change sets. |
updateCountSql | Writes SQL to apply the next <liquibaseCommandValue> change sets to STDOUT. |
updateSQL | Writes SQL to update the database to the current version to STDOUT. |
updateTestingRollback | Updates the database, then rolls back changes before updating again. |
updateToTag | Updates the database to the changeSet with the <liquibaseCommandValue> tag |
updateToTagSQL | Writes (to standard out) the SQL to update to the changeSet with the <liquibaseCommandValue> tag |
validate | Checks the changelog for errors. |