Development
Schema Migration by Liquibase
7/1/2025

์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ์ด ๋ญ๊ฐ์?
์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ Schema Migration์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐ ๋ฐ ์ด์ ๊ณผ์ ์ ๋ฐ์ํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ์ ์๊ธฐ๋ ๋ณ๊ฒฝ์ ์ฝ๋๋ก ๊ด๋ฆฌํ๋ ์ ์ฐจ๋ฅผ ์๋ฏธํฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง ๋ณ๊ฒฝ์๋ ํ ์ด๋ธ ์์ฑ, ์ปฌ๋ผ ์ถ๊ฐ ๋ฐ ์์ , ์ธ๋ฑ์ค ์์ฑ, ์ ์ฝ ์กฐ๊ฑด ์ถ๊ฐ ๋ฑ ๋ชจ๋ ๊ตฌ์กฐ์ ๋ณ๊ฒฝ์ด ํฌํจ๋ฉ๋๋ค.
์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ ๋ณ๊ฒฝ์ ์ฝ๋๋ก ๊ด๋ฆฌํ๊ฒ ํ๋ฉฐ, ์ด๋ ๋ฒ์ ๊ด๋ฆฌ ์์คํ ๊ณผ ํจ๊ป ์ฌ์ฉ๋์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ์ ์ ์ง์ ๋ณํ ๊ณผ์ ์ ์ถ์ ํ ์ ์๊ฒ ํฉ๋๋ค.
๋ชจ๋ DB ๋ณ๊ฒฝ์ โ๋ง์ด๊ทธ๋ ์ด์ โ์ผ๋ก ๊ด๋ฆฌ๋์ด์ผ ํ๋ค
ํ์์ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ์ ์ฌ์ฉํ๊ธฐ๋ก ํ๋ค๋ฉด ๋ชจ๋ ๊ตฌ์กฐ ๋ณ๊ฒฝ ์ฟผ๋ฆฌ๋ ์๋์ผ๋ก ์ด๋ฃจ์ด์ ธ์๋ ์๋ฉ๋๋ค.
๊ฐ๋ฐ์๊ฐ ์ ๊ท ๊ธฐ๋ฅ์ ์ํด ๋ก์ปฌ ์์ ๊ณต๊ฐ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ๋ฅผ ์์ ํ๊ณ ๊ทธ์ ๋ง๊ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๋ค๊ณ ํฉ์๋ค. ์ด๋ฅผ ํ๋ก๋์ ํ๊ฒฝ์ ๋ฐ์ํ๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ณ๊ฒฝ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋๋ฅผ ๋ฐฐํฌํ๊ณ , DB์ ๋ณ๊ฒฝ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ ๊ฒ์ ๋๋ค.
์ด ๋ฐฉ์์๋ ๋ช๊ฐ์ง ๋ฌธ์ ์ ์ด ์์ต๋๋ค. ๊ฐ๋ฐ์๊ฐ ์ด๋์์, ์ด๋ค ์์ ์, ์ด๋ค ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋์ง ์ถ์ ํ๊ธฐ๊ฐ ์ด๋ ต๊ณ , ์ค์๊ฐ ๋ฐ์ํ๋ค๋ฉด ๊ฐ๋ฐํ๊ฒฝ์ด๋ ์ด์ ํ๊ฒฝ์ ์คํค๋ง๊ฐ ๋ค๋ฅด๊ฒ ์ ์ง๋ ์ํ์ด ์กด์ฌํฉ๋๋ค. ๋ํ ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ด ๊ฐ๋ฐ ์ค ๋ก์ปฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉ์ค์ด์๋ค๋ฉด, ๋ชจ๋ ๊ฐ๋ฐ์๋ค์๊ฒ "pull ๋ฐ์ผ์ ์ดํ์ ์ด ์ฟผ๋ฆฌ๋ฅผ ์คํํด์ฃผ์ ์ผ ์ ๋์ํฉ๋๋ค"๋ผ๊ณ ๋งํด์ผ ํ ๊ฒ์ ๋๋ค.
์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋ฐฉ์์ ์ฑํํ ํ์์๋ ์ด์ DB๋ ๊ฐ๋ฐ DB์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ ๊ฒ ๋์ ์, ๋ณ๊ฒฝ ์ฌํญ์ ์ฝ์๋ ํด๋์ ๋ค์๊ณผ ๊ฐ์ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ๋ก ์์ฑํด์ผ ํฉ๋๋ค.
create table member_history (
id BIGINT not null,
email varchar(256) not null,
last_logined_at DATETIME not null,
timestamp BIGINT not null,
type varchar(20) not null,
)ํด๋น ํ์ผ์ด push๋ ์ดํ์ CI ์์คํ ์ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ฅผ ํ์ฉํ์ฌ ๋ณ๊ฒฝ์ฌํญ์ ๊ฐ๋ฐ ๋๋ ์ด์ DB์ ๋ฐ์ํฉ๋๋ค. DB์๋ ์ด๋ ํ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ๋ค์ด ๋ฐ์๋์ด์๋์ง์ ๋ํ ๊ธฐ๋ก์ด ๋จ์์์ต๋๋ค. ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ๋ค์ ์ํ์ค๋ฅผ ํ์ธํ์ฌ, DB์ ์์ง ์ ์ฉ๋์ง ์์ ๋ ๋์ ๋ฒ์ ์ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ด ์กด์ฌํ ๊ฒฝ์ฐ ์ด๋ฅผ ์๋์ผ๋ก ๋ฐ์ํฉ๋๋ค.
๋ก์ปฌ์์ ๊ฐ๋ฐ์ค์ธ ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค๋ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ฅผ ํ์ฉํ์ฌ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ๊ฐ๋ฐ ๋ธ๋์น์ ์ต์ ์ฝ๋๋ฅผ pull ๋ฐ์ ํ ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ฅผ ์คํํ๋ฉด, ํด๋น ๋ธ๋์น์ ํฌํจ๋ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ด ์๋์ผ๋ก ์ ์ฉ๋์ด ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์ ํธํ๋๋ ์ต์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ๋ฅผ ๊ฐ์ถ๊ฒ ๋ฉ๋๋ค.
ํ์ ๊ณผ์ ์์ ์ํ์ค ๋ฒํธ ๊ด๋ฆฌ
๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ ๋ณ๊ฒฝ์ ์๊ตฌํ๋ ๊ธฐ๋ฅ ๊ฐ๋ฐ์ ํ๋ ๊ณผ์ ์์ ๊ฐ๋ฐ์๋ ์ฃผ ๋ธ๋์น๋ก๋ถํฐ ๋ง๋ค์ด์ง feature ๋ธ๋์น์์ ์์ ์ ์ํํ ๊ฒ์ ๋๋ค. ์ฝ๋์์ ํ์ธํ ์ ์๋ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ ์ค ๊ฐ์ฅ ๋์ ๋ฒ์ ์ด V7 ์ด์๋ค๋ฉด, V8 ๋ฒ์ ์ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ๋ง๋ค์ด ๋ก์ปฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ณ๊ฒฝ์ฌํญ์ ๋ฐ์ํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋๋ฅผ ์์ ํฉ๋๋ค. ํ ์คํธ๊ฐ ์๋ฃ๋ ์ดํ ์ฃผ ๋ธ๋์น๊ฐ ๊ฐฑ์ ๋์ง ์์๋ค๋ฉด ์ฃผ ๋ธ๋์น์ ๋ณํฉ์ ์์ฒญํ๋ pr์ ์์ฑํฉ๋๋ค. ์ดํ pr์ด merge๋๋ค๋ฉด ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ ์ด ๋ณ๊ฒฝ์ฌํญ์ ๋ก์ปฌ์ ๋ฐ์์ค๊ณ , ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ๋ก ๊ฐ๋ฐ์ ์ด์ด๊ฐ ์ ์์ต๋๋ค.
๋ง์ฝ ๊ฐ๋ฐ์ ๋ง์ณค๋๋ฐ ๊ทธ ์ฌ์ด์ ์ฃผ ๋ธ๋์น๊ฐ ๊ฐฑ์ ๋ ์ํฉ์์๋ ์ฃผ ๋ธ๋์น๋ฅผ feature ๋ธ๋์น์ ๋ณํฉํ ๋ค ์ ๊ท ๊ธฐ๋ฅ๊ณผ ๊ฐ๋ฐ ์ค์ธ ๊ธฐ๋ฅ์ ์ถฉ๋์ด ์๋์ง ํ์ธํด์ผํฉ๋๋ค. ์ด ๋ ์ ๊ท ๊ธฐ๋ฅ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ ๋ณ๊ฒฝ์ ์ํด V8์ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ๋ง๋ค์๋ค๋ฉด, ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ ๋ฒ์ ์ด ์ถฉ๋ํ์์ ์๋ฆด ๊ฒ์ ๋๋ค.
์ด ๊ฒฝ์ฐ ๊ฐ๋ฐ์๋ ๊ธฐ์กด์ V8(๋ก์ปฌ ๊ฐ๋ฐ ์ค ๋ฐ์ํ ๋ณ๊ฒฝ)์ ๋กค๋ฐฑํ๊ณ , ์ ๊ท V8(ํ ๊ฐ๋ฐ์๊ฐ pushํ ๋ณ๊ฒฝ์ฌํญ)์ ๋ฐ์ํ ๋ค, ๊ธฐ์กด์ V8 ๋ฒ์ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ V9๋ก ๋ณ๊ฒฝํด์ผํฉ๋๋ค. ์ดํ ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ฅผ ์คํํ๋ฉด ์ ๊ท ๋ฒ์ ๊ณผ ๊ฐ๋ฐ์ค์ธ ๋ฒ์ ์ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ๊ฐ๊ฐ ์คํํ๊ฒ ๋ฉ๋๋ค.
์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ
์์์ ์ธ๊ธ๋ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ์ ๊ฐ์ฅ ํต์ฌ์ ์ธ ์๋ฌด๋ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ์์๋๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฉํ๋ ๊ฒ์ ๋๋ค. ์ด๋ฅผ ์ํด ๋๊ตฌ๋ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ด ์์นํ ๋๋ ํฐ๋ฆฌ ๊ฒฝ๋ก์ ํจ๊ป, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ํ๊ธฐ ์ํ ์ฃผ์, ์ฌ์ฉ์ ์ด๋ฆ, ๋น๋ฐ๋ฒํธ, ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ช ์ ์ค์ ๊ฐ์ผ๋ก ์๊ตฌํฉ๋๋ค.
๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๊ฐ ์คํ๋๋ฉด, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ์คํ ๋ฆฌ ํ ์ด๋ธ์ ํ์ธํ์ฌ ํ์ฌ๊น์ง ๋ช ๋ฒ์ ์ด ์ ์ฉ๋์๋์ง ํ์ ํ ๋ค, ์ง์ ๋ ๋๋ ํฐ๋ฆฌ์์ ํด๋น ๋ฒ์ ์ดํ์ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ํ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ํ์คํ ๋ฆฌ ํ ์ด๋ธ์ V7๊น์ง ์ ์ฉ๋ ์ํ๋ผ๋ฉด, ๋๊ตฌ๋ V8 ์ดํ์ ํ์ผ์ ์ ์ฉ ๋์์ผ๋ก ๊ฐ์ฃผํฉ๋๋ค. ๊ฐ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ์์ฐจ์ ์ผ๋ก ์คํ๋๋ฉฐ, ์ ์ฉ์ด ์๋ฃ๋๋ฉด ๋๊ตฌ๋ ํด๋น ์ ๋ณด๋ฅผ ํ์คํ ๋ฆฌ ํ ์ด๋ธ์ ๊ธฐ๋กํฉ๋๋ค.
์ผ๋ถ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ์ ๊ฒฝ์ฐ undo ์์ ์ ์ง์ํ๊ธฐ๋ ํฉ๋๋ค. undo ์์ ์ ์ง์ํ๋ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ์ ์ํด์ ๊ฐ๊ฐ์ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ์ ์ฉ ํํธup์ ๋กค๋ฐฑ ํํธdown์ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด์ฃผ์ด์ผ ํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ๋ง์ด๊ทธ๋ ์ด์ ์์ ์์๋ ์ ์ฉ ํํธ๋ง์ด ์ฌ์ฉ๋์ง๋ง, ํน์ ์ง์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ๋ฅผ ๋๋๋ฆฌ๋ ๋ช ๋ น์ ๋ฐ์ ๋์๋ ๋กค๋ฐฑ ํํธ๋ฅผ ์ญ์์ผ๋ก ์ํํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ๋ฅผ ๊ณผ๊ฑฐ ์์ ์ผ๋ก ๋๋ฆฝ๋๋ค. ์ด๋ ๊ฒ ๋กค๋ฐฑ์ ์ง์ํ๋ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋ฐฉ์์ ์๋ฐฉํฅ ๋ง์ด๊ทธ๋ ์ด์ Bidirectional Migration์ด๋ผ๊ณ ํฉ๋๋ค.
ํ ํธ ์ผ๋ถ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ undo ์์ ์ ์ง์ํ์ง ์์ต๋๋ค. ์ด ๋ฐฉ์์์ ๋กค๋ฐฑ์ ์ทจ์ ์์ ์ ์ํํ๋ ์๋ก์ด ๋ง์ด๊ทธ๋ ์ด์ ๋ฒ์ ์ ์์ฑํ๋ ๊ฒ์ผ๋ก ์ด๋ฃจ์ด์ง๋๋ค. ์ด๋ ๋ง์ด๊ทธ๋ ์ด์ ๋ฒ์ ์ด ํญ์ ๋จ๋ฐฉํฅ์ผ๋ก ๋ฐ์ ํ๊ธฐ์ ๋จ๋ฐฉํฅ ๋ง์ด๊ทธ๋ ์ด์ Unidirectional Migration์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
Liquibase

Liquibase๋ ์๋ฐฉํฅ ๋ง์ด๊ทธ๋ ์ด์ ์ ์ง์ํ๋ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ์ ๋๋ค. Pro ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ฉด ๋น์ฉ์ด ๋ค์ง๋ง, ์คํ ์์ค ๋ฒ์ ์ ๋ฌด๋ฃ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ดํ ๊ธ์์๋ Liquibase ์ค์น์ ๊ธฐ๋ณธ์ ์ธ ์ปค๋งจ๋๋ค์ ์๊ฐํฉ๋๋ค.
์ค์น ๋ฐ ์คํ


์ ๋งํฌ์์ liquibase๋ฅผ ์ค์นํ ์ ์์ต๋๋ค. ์ ๋ mac os ์ฉ cli ํ๋ก๊ทธ๋จ์ ์ค์นํ์ต๋๋ค.
์ค์น ์ดํ์๋ Liquibase๊ฐ ์ฌ์ฉํ ์ค์ ์ ๋ณด๊ฐ ์๋ ํ์ผ์ ๋ง๋ค์ด์ฃผ์ด์ผ ํฉ๋๋ค. ๋ฑ๋กํด์ผํ ์ ๋ณด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
# ๋ง์ด๊ทธ๋ ์ด์
ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ๋ฑ๋กํด์ค๋๋ค. liquibase๋ xml, json, yaml, sql์ ํ์ผ ํ์์ ์ง์ํฉ๋๋ค.
changeLogFile=migration.sql
# 'jdbc:'๋ก ์์ํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค url์ ์ง์ ํฉ๋๋ค.
liquibase.command.url=jdbc:postgresql://localhost:5432/mydb
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์์ ์ํ ์ ์ ๋ช
์
๋๋ค.
liquibase.command.username: pete
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์์ ์ํ ๋น๋ฐ๋ฒํธ์
๋๋ค.
liquibase.command.password: 1234์ค์ ํ์ผ์ liquibase ์ปค๋งจ๋๋ฅผ ์คํ์ํฌ ๋๋ ํฐ๋ฆฌ์ ์์น์ํต๋๋ค. ๋ ์์ธํ ๋ณ์๋ค์ ์ค์น๋ฅผ ํตํด ๋ฐ์ ํ์ผ ์ค /examples์ liquibase.properties์์ ํ์ธํ ์ ์์ต๋๋ค.
๋ง์ด๊ทธ๋ ์ด์ ํ์ผ ์์ฑ
Liquibase๊ฐ ํด์ํ ์ ์๋ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ์์ฑํด๋ด ์๋ค. Liquibase๋ ๋ง์ด๊ทธ๋ ์ด์ ๋จ์์ changeset์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
--liquibase formatted sql
--changeset pete:1-create-person-table
--comment: create person table
CREATE TABLE person (
id SERIAL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
address1 VARCHAR(50),
address2 VARCHAR(50),
city VARCHAR(30)
);
--rollback DROP TABLE person;๊ฐ๊ฐ์ changeset์ --changeset์ผ๋ก ์์ํ๋ฉฐ, ์ฌ๋ฌ๊ฐ์ง ์์ฑ์ ๋ถ์ฌํ ์ ์์ต๋๋ค. ์ฒซ ์ค์ ๋์ค๋ pete:1-create-person-table์ <author>:<id> ๊ผด๋ก ์์ฑ๋๋ changeset์ ์๋ณ์๋ก ํ์ ์์ฑ์
๋๋ค.
์ด์ ์ ์ค๋ช
ํ๋ฏ์ด Liquibase๋ ์๋ฐฉํฅ ๋ง์ด๊ทธ๋ ์ด์
์ ์ง์ํ๊ธฐ ๋๋ฌธ์ ๊ฐ ๋ง์ด๊ทธ๋ ์ด์
๋ง๋ค ํด๋น ๋ณ๊ฒฝ์ ๋๋๋ฆด ์ ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ํจ๊ป ์์ฑํด์ฃผ์ด์ผ ํฉ๋๋ค. --rollback์ ๋กค๋ฐฑ ์ ์ํํ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๋ ์์ฑ์
๋๋ค.
update
update ์ปค๋งจ๋๋ ๋ง์ด๊ทธ๋ ์ด์
ํ์ผ๊ณผ DB์ databasechangelog ํ
์ด๋ธ์ ๋น๊ตํ์ฌ ์ ํจํ changeset์ ์ ์ฉํ๋ ์คํฌ๋ฆฝํธ์
๋๋ค. ์์ ์์ฑํ ๋ง์ด๊ทธ๋ ์ด์
ํ์ผ์ ์ฌ๋ฐ๋ฅธ ๊ณณ์ ์์น์ํจ ๋ค update๋ฅผ ์คํํ๋ฉด 1-create-person-table์ ์คํฌ๋ฆฝํธ๊ฐ ์ํ๋๋ฉฐ, DB์ ํ์คํ ๋ฆฌ๊ฐ ์ ์ฅ๋ฉ๋๋ค.
โ liquibase update
...
UPDATE SUMMARY
Run: 1
Previously run: 0
Filtered out: 0
-------------------------------
Total change sets: 1
ย
Liquibase: Update has been successful. Rows affected: 1
Liquibase command 'update' was executed successfully.
migration.sql์ ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ด ์ถ๊ฐํฉ๋๋ค. 2-add-age-column์ person ํ ์ด๋ธ์ age ์์ฑ์ ์ถ๊ฐํ๋ฉฐ, 3-create-name-index์์๋ name ํ๋์ ์ธ๋ฑ์ค๋ฅผ ์์ฑํฉ๋๋ค.
--liquibase formatted sql
--changeset pete:1-create-person-table
--comment: create person table
CREATE TABLE person (
id SERIAL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
address1 VARCHAR(50),
address2 VARCHAR(50),
city VARCHAR(30)
);
--rollback DROP TABLE person;
--changeset pete:2-add-age-column
--comment: add 'age' column to person table
ALTER TABLE person ADD COLUMN age INT;
--rollback ALTER TABLE person DROP COLUMN age;
--changeset pete:3-create-name-index
--comment: create index on 'name' column of person table
CREATE INDEX idx_person_name ON person(name);
--rollback DROP INDEX idx_person_name;์ดํ update ์ปค๋งจ๋๋ฅผ ์ํํ๋ฉด, ์๋กญ๊ฒ ์ถ๊ฐ๋ ๋ ๊ฐ์ changeset์ด ์ํ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
โ liquibase update
...
UPDATE SUMMARY
Run: 2
Previously run: 1
Filtered out: 0
-------------------------------
Total change sets: 3
ย
Liquibase: Update has been successful. Rows affected: 2
Liquibase command 'update' was executed successfully.

rollback
๋ง์ฝ ์ค๊ฐ ๋จ๊ณ์ changeset๋ง ๋กค๋ฐฑํ๋ค๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง๊ฐ ๊นจ์ง ์ํ์ด ์์ต๋๋ค. ๋ฐ๋ผ์ liquibase๋ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋กค๋ฐฑ์ ์ ํํฉ๋๋ค.
1. rollback-count : ๊ฐ์ฅ ์ต๊ทผ์ ์ ์ฉ๋ n๊ฐ์ changeset์ ์ญ์์ผ๋ก ๋กค๋ฐฑํฉ๋๋ค.
2. rollback-to-date : ํน์ ์์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ ์ํ๊ฐ ๋๋๋ก ํด๋น ์ง์ ๊น์ง์ changeset์ ์ญ์์ผ๋ก ๋กค๋ฐฑํฉ๋๋ค.
์ด ์ค rollback-count์ ๋ํด๋ง ๊ฐ๋จํ๊ฒ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
โ liquibase rollback-count --count=2
Rolling Back Changeset: migration.sql::3-create-name-index::pete
Rolling Back Changeset: migration.sql::2-add-age-column::pete
Liquibase command 'rollback-count' was executed successfully.
์ ๋ช ๋ น์ด๋ 3๋ฒ๊ณผ 2๋ฒ ๋ณ๊ฒฝ์ฌํญ์ ๋๋๋ฆฌ๋ฉฐ, databasechangelog ํ ์ด๋ธ์ ๋ ์ฝ๋ ์ญ์ ์ง์๋๋ค.

๋ง๋ฌด๋ฆฌ
์ด๋ฒ ๊ธ์์๋ ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ์ ๊ฐ๋ ๊ณผ ํ์์ฑ, ๊ทธ๋ฆฌ๊ณ Liquibase๋ฅผ ํ์ฉํ ์ค์ต ๊ณผ์ ์ ๊ฐ๋จํ ์ดํด๋ณด์์ต๋๋ค. ์กฐ๋ง๊ฐ ํ ํ๋ก์ ํธ๋ฅผ ํ ๋์ Liquibase๋ฅผ ํตํด ์ ์์ผํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ๋ฅผ ํด๋ณผ ๊ธฐํ๊ฐ ์๊ฒผ์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค.