ํ๋ก์ ํธ ๋ฐฐ๊ฒฝ
ํ์ฌ ๋ด๊ฐ ์ํ ํ์ ์ฌ๋ฌ ๊ฐ์ ์ค์ฟผ๋๋ก ๋๋์ด ์ด์๋๊ณ ์๋ค. ์ค์ฟผ๋์ ๊ฐ์๊ฐ ๊ฝค๋ ๋ง์๋ฐ ์ด ์ค 4๊ฐ ์ด์์ ์ค์ฟผ๋๊ฐ ๋์ผํ ๊ณตํต ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ณต์ ํด์ ์ฌ์ฉํ๊ณ ์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐฐํฌํ๊ฒฝ๋ ์ผ๋ฐ์ ์ธ ํ์ฌ๋ค๊ณผ ๋น์ทํ๊ฒ ์ฌ๋ฌ ํ๊ฒฝ์ผ๋ก ๋๋์ด์ ธ ์๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ๋ ์๋์ ๊ฐ์ด Git์ ํตํด ํ์๊ด๋ฆฌ๋๊ณ ์๋๋ฐ, ๊ฐ ์ค์ฟผ๋๋ ์คํ๋ฆฐํธ ๋จ์๋ก ๊ฐ๋ฐ์ ์งํํ๋ฉด์ ํ์ํ SQL ํ์ผ์ ์์ฑํ๊ณ ์ด๋ฅผ ํ๋ก์ ํธ์ changelog ํด๋์์ ๋ฒ์ ๋ณ๋ก ๊ด๋ฆฌํ๋ค. ๊ทธ๋ฆฌ๊ณ ์์ ํ๊ฒฝ์ผ๋ก ๋ฐฐํฌํ ๋๋ ํด๋น ๋ฒ์ ์ ํฌํจ๋ ์ฟผ๋ฆฌ๋ค์ ๊ฐ๋ฐ์๊ฐ ์๋์ผ๋ก ์คํํ์ฌ ๋ฐ์ํ๊ณ ์๋ค.
sql/
โโโ changelog/
โ โโโ A/ # A ์ค์ฟผ๋
โ โ โโโ v5.7.11.md
โ โ โโโ v5.7.12.md
โ โ โโโ v5.9.0.md
โ โ ...
โ โโโ B/ # B ์ค์ฟผ๋
โ โ โโโ v6.4.0_B.sql
โ โ โโโ v6.4.0_B_dml.sql
โ โ ...
โ โโโ C/ # C ์ค์ฟผ๋
โ โ โโโ v6.2.0_C_squard.sql
โ โ โโโ v6.2.0_dml_C_squard.sql
โ โ ...
โ โโโ D/ # D ์ค์ฟผ๋
โ โโโ v6.3.0_D_squard.md
โ โโโ v6.4.0_D_squard.md
โ ...
โโโ init.sql
โโโ schema.sql
๊ธฐ์กด ๋ฌธ์ ์
์ด๋ฐ ๋ฐฐ๊ฒฝ์์ ๊ธฐ์กด์ ๋ฐฉ์์์๋ ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๋ค์ด ๋ฐ์์ ํ๊ณ ์์๋ค.
- ๋ฐฐํฌ ์์ ์ฑ ์ ํ: ์ฌ๋ฌ ์ค์ฟผ๋๊ฐ ๋์ผํ ์คํ๋ฆฐํธ ๊ธฐ๊ฐ์ ๊ฐ๋ฐ์ ์งํํ๋ ์ํฉ์์ ๊ฐ ์ค์ฟผ๋๊ฐ ์์ ๋ค์ ์ฟผ๋ฆฌ๋ง์ ์ ํ์ ์ผ๋ก ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ณ , ์ด๋ก ์ธํด ํ์ ์ฟผ๋ฆฌ๊ฐ ๋๋ฝ๋์ด ์ค๋ฅ๊ฐ ๋น๋ฒํ๊ฒ ๋ฐ์ํ๋ค.
- ๋ณ๊ฒฝ ์ด๋ ฅ ์ถ์ ์ ์ด๋ ค์: Git์ ํตํด ๋๊ฐ ํด๋นํ๋ ์ฟผ๋ฆฌ๋ฅผ ๋๊ฐ ์์ฑํ๋์ง ๊น์ง๋ ์ ์ ์์ง๋ง, ์ค์ ๋ก ์ฟผ๋ฆฌ๊ฐ ๋ฐ์๋ ์์ ์ด๋ ๋ด๋น์๋ฅผ ์ถ์ ํ๊ธฐ ์ด๋ ต๋ค.
- ํ๊ฒฝ๋ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง ๋ถ์ผ์น: ์ฟผ๋ฆฌ ๋ฐ์ ๊ณผ์ ์์ ๋ฐ์ํ๋ ๋๋ฝ์ผ๋ก ์ธํด ํ๊ฒฝ๋ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ ๊ตฌ์กฐ๊ฐ ์ผ์นํ์ง ์๋ ๊ฒ๋ค์ด ๋งค์ฐ ๋ง๋ค.
์ค์ ๋ก ๋ฐฐํฌ ์์ ์ฑ๊ณผ ํจ์จ์ฑ์ ์ ํ์ํฌ ๋ฟ๋ง ์๋๋ผ, ๊ฐ๋ฐ์ ๊ฐ ์ํต ๋น์ฉ์ ์ฆ๊ฐ์ํค๊ณ ์์๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ์ ๊ด๋ฆฌ ๋๊ตฌ ๋์ ์ ๊ณ ๋ คํ๊ณ Liquibase์ Flyway ์ค ๊ณ ๋ฏผ์ ํ๋ค๊ฐ ํ์ต ๊ณก์ ์ด ๋ฎ๊ณ , SQL ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋จํ ์์ฑ ๊ฐ๋ฅํ๋ฉฐ ๊ธฐ์กด ๋ฐฉ์๊ณผ์ ์ ์ฌ์ฑ์ด ๋์ Flyway๋ฅผ ์ ํํ๋ค.
๊ทธ๋ฌ๋ ๋จ์ํ Flyway๋ง ๋์ ํ์ ์ ๋ฌธ์ ์
ํ์ง๋ง Flyway ๋์ ์ ์ํด ์ฌ๋ฌ ์ํฉ์ ๊ณ ๋ คํ๋ฉฐ ๋์ ๋ฌธ์๋ฅผ ์์ฑํ๋ ๊ณผ์ ์์ ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๋ค์ด ๊ณ ๋ ค๋์๋ค.
1. installed_by๊ฐ ํญ์ ๋์ผํ ์ฌ์ฉ์๋ก ํ์
Flyway๋ ๊ธฐ๋ณธ์ ์ผ๋ก flyway_schema_history๋ผ๋ ํ ์ด๋ธ์ ์์ฑํ์ฌ DB ํ์์ ๊ด๋ฆฌํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ํ ์ด๋ธ์๋ installed_by ์ปฌ๋ผ์ด ์์ด ๋๊ฐ ์ฟผ๋ฆฌ๋ฅผ ์ ์ฉํ๋์ง ํ์ธํ ์ ์๋ค. ํ์ง๋ง ์ค์ ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ DB Connection์ ๋์ผํ ๊ณ์ ์ผ๋ก ๋งบ๊ณ ์๊ณ , Flyway๋ ํธ์์ ๋์ผํ ๊ณ์ ์ ์ฌ์ฉํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ Flyway๋ฅผ ํตํด ์์ ํ๋ฉด installed_by๊ฐ ํญ์ ๋์ผํ ์ฌ์ฉ์๋ก ๊ธฐ๋ก๋์ด ์ค์ ๋ก ๋๊ฐ ํด๋น ์ฟผ๋ฆฌ๋ฅผ ์ํํ๋์ง ์ถ์ ํ๊ธฐ๊ฐ ์ด๋ ต๋ค. SQL ํ์ผ์ ์์ฑํ๋ฉด Git์ ํตํด ๋ณ๊ฒฝ ์ด๋ ฅ์ ํ์ธํ ์๋ ์๋ค์ง๋ง, ํ์ฌ๋ SQL์ด๋ MD ํ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ฉด์ ์ ๋ ฌ ์์ ์ ์ํํ์ง ์๋ ์ฌ๋๋ค์ด ์ข ์ข ์์ด ์ด๋ก ์ธํด ๋๊ตฐ๊ฐ ์ ๋ ฌ์ ์คํํ ๋๋ง๋ค ๋ณ๊ฒฝ ์ด๋ ฅ์ด ๊ธฐ๋ก๋์ด ์ค์ ์์ฑ์๋ฅผ ์ ํํ ํ์ ํ๊ธฐ ์ด๋ ค์ด ์ํฉ์ด์๋ค.
2. ๋นํจ์จ์ ์ธ ๋ฐ์ ํ๋ก์ธ์ค
Flyway๋ ๊ธฐ๋ณธ์ ์ผ๋ก src/main/resources/db/migration ํด๋์ ์ ์ฅ๋ .sql ํ์ผ์ ๊ธฐ์ค์ผ๋ก ์์ ์ ์ํํ๋ค. ๊ทธ๋ฆฌ๊ณ ํ์ผ๋ช ๊ท์น์ ๋ฐ๋ผ ์์ฑ๋ ์ฟผ๋ฆฌ ํ์ผ๋ค์ ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์ ์๋์ผ๋ก ์ ์ฉ๋๋ฉฐ ์คํจ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ค์ง๋๋ค.
์ด๋ฐ ๋์ ๋ฐฉ์์ ๋จ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ์ํ๋ ค๋ ์์ ์กฐ์ฐจ ๋งค๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฐฐํฌํด์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ด ๋ฐ์ํ๋ค. ํนํ ์ฐ๋ฆฌ๋ ๋ก์ปฌ ํ๊ฒฝ์์ ๊ฐ๋ฐ์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ง์ ์ฐ๊ฒฐํด ์์ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ, ๋งค๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํด์ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ์ํด์ผ ํ๋ค๋ฉด ๊ฐ๋ฐ ์์ฐ์ฑ์ด ์ ํ๋ ๊ฐ๋ฅ์ฑ์ด ๋์๋ค.
๋ฌผ๋ก .. 'Flyway๋ CLI ๋๊ตฌ๋ ์ ๊ณตํด์ ์ ํ๋ฆฌ์ผ์ด์ ์ฌ๋ฐฐํฌ ์์ด๋ ๋ง์ด๊ทธ๋ ์ด์ ์ ์ํํ ์ ์์ง๋ง.. ๊ณผ์ฐ ์ด๊ฒ ๋ ํธํ ๊น?'๋ ์๋ฌธ์ด๋ค.
3. ์๊ฒฉํ ๋ค์ด๋ฐ ๊ท์น์ผ๋ก ์ธํ ํ์ต ํ์
Flyway๋ ํ์ผ๋ช ์ ๊ธฐ๋ฐ์ผ๋ก ๋ฒ์ ์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด ํ์ผ๋ช ์ ์๊ฒฉํ ๊ท์น์ ๋ฐ๋ผ ์์ฑํด์ผ ํ๋ค.
๊ทธ๋ ๊ธฐ์ ํ ์ ์ฒด ๊ฐ๋ฐ์๋ค์ด ์ด๋ฐ ๋ค์ด๋ฐ ๊ท์น์ ์ค์ํ๊ธฐ ์ํด ํ์ต์ ํด์ผ ํ๋ ์ถ๊ฐ ๋น์ฉ์ด ๋ฐ์ํ๋ค. ์ฐธ๊ณ ๋ก Flyway๋ก ํจ๊ป ์ผํ๊ธฐ, ๋ฒ์ ์ถฉ๋ ํผํ๊ธฐ ๊ฐ์ ์ํฐํด์์ ์ธ๊ธ๋ ์ฌ๋ก๋ค ์ญ์ ์ถฉ๋ถํ ๊ณ ๋ คํด์ผ ํ๋ ๋ฌธ์ ์ด๊ธฐ ๋๋ฌธ์, ๋ค์ด๋ฐ ๊ท์น์ด ๋์ฑ ๋ณต์กํด์ง๋ค.
4. ๋ง์ด๊ทธ๋ ์ด์ ์คํจ ์ ๋ณต์กํ ๋ณต๊ตฌ ์ ์ฐจ
Flyway ๋ง์ด๊ทธ๋ ์ด์ ์ด ์คํจํ์ ๊ฒฝ์ฐ ๋ณต๊ตฌ ์ ์ฐจ๊ฐ ๊ฐ๋จํ์ง ์์๋ฐ, repair ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ flyway_schema_history ํ ์ด๋ธ์์ ์คํจํ ํญ๋ชฉ(success = FALSE)์ ์๋์ผ๋ก ์ ๊ฑฐํ ๋ค ๋ค์ ์คํํด์ผ ํ๋ค. ๊ทธ๋ ๊ธฐ์ ์ด๋ฌํ ์ ์ฐจ ๋ํ ํ์ต์ด ํ์ํด ํ์๋ค์๊ฒ ์ถ๊ฐ์ ์ธ ์๊ฐ ๋น์ฉ์ ์ ๋ฐํ๋ค.
5. ์ฌํ ์ฟผ๋ฆฌ ๊ด๋ฆฌ์ ์ด์ค์ฑ
๋ฐฐํฌ ํ ๋ณ๋๋ก ์คํํด์ผ ํ๋ ์ฌํ ์ฟผ๋ฆฌ๋ Flyway๋ก ๊ด๋ฆฌ๋์ง ์๊ธฐ ๋๋ฌธ์, ๊ฒฐ๊ตญ ์ฌํ ์ฟผ๋ฆฌ๋ ๋ณ๋๋ก ๊ด๋ฆฌํด์ผ ํ๋ฏ๋ก ์ด์ค์ ์ธ ๊ด๋ฆฌ๊ฐ ๋์ด ๊ด๋ฆฌํฌ์ธํธ๊ฐ ๋์ด๋๋ค.
๋ณ๋๋ก afterMigrate๋ก ๋ง์ด๊ทธ๋ ์ด์ ์ด ์ ๋ถ ์๋ฃ๋ ์งํ ์๋์ผ๋ก ์ํ๋๊ฒ ํ ์๋ ์์ง๋ง ์คํ ์์ ์ ์์๋ก ์ง์ ํ ์๋ ์๊ธฐ์ ์ด๋ฐ ๊ธฐ๋ฅ์ ๊ณ ๋ คํ์ง ์์๋ค.
6. ๋ณ๊ฒฝ ์ด๋ ฅ์ ํ์ ์ด๋ ค์
์๊น 1๋ฒ์์ flyway_schema_history ํ ์ด๋ธ์ ์ปฌ๋ผ๋ค ๊ฐ์ ๋ดค๋ฏ์ด script ์ปฌ๋ผ์ ๊ฒฝ์ฐ ๋ฐ์ํ ์ฟผ๋ฆฌ๋ฅผ ์ ์ฅํ๋ ๊ฒ์ด ์๋ ํ์ผ๋ช ์ ์ ์ฅํ๋ค. ๊ทธ๋ ๊ธฐ์ ๊ฐ ํ๊ฒฝ์์ ์ด๋ค ์ฟผ๋ฆฌ๊ฐ ๋ฐ์๋์๋์ง ํ์ธํ๊ธฐ ์ํด์๋ ๋ฐ์๋ SQL ํ์ผ์ ์ง์ ์ฐพ์์ ์ด์ด๋ด์ผ ํ๋ ๋ถํธํจ์ด ์กด์ฌํ๋ค.
์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด DB ํ์ ๊ด๋ฆฌ ์น ๊ตฌ์ถ
๊ฒฐ๊ตญ ๊ธฐ์กด๋ณด๋ค ๋ ํธ๋ฆฌํ๊ฒ ๋ฐฐํฌ์ ๊ด๋ฆฌ๋ฅผ ์ํํ๊ณ ์ ๋์ ์ ๊ฒํ ํ Flyway๋ ์คํ๋ ค ์๋ก์ด ํ์ต ๋น์ฉ๊ณผ ์๊ฒฉํ ์ง์ผ์ผ ํ ๊ท์น๋ค์ด ์ถ๊ฐ๋จ์ผ๋ก์จ, ๊ธฐ์กด ๋ฐฉ์๋ณด๋ค ๋ ํฐ ๋ถํธ์ ์ด๋ํ ๊ฐ๋ฅ์ฑ์ด ๋์๋ค. ๊ทธ๋์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ง์ ๊ณ ๋ฏผ ๋์ Flyway์ ๊ฐ์ ์ ์ ์งํ๋ ๋จ์ ๋ค์ ๋ณด์ํ ์ ์๋ ์น ๊ธฐ๋ฐ์ ๊ด๋ฆฌ ์์คํ ์ ๊ตฌ์ถํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ค. ์ง๊ธ๋ถํฐ๋ ํธ์์ฑ์ ์ํด DMM(Database Migration Manager)์ผ๋ก ๋ถ๋ฅด๊ฒ ๋ค.
์ฐธ๊ณ ๋ก ํ๋ฉด์ ํ์๋ฆฌํ๋ก ๊ทธ๋ ธ๋๋ฐ Cursor์ ๋์์ ๋ง์ด ๋ฐ์๋ค. ์์ ์ฒ์ ๋ง๋ค์ด๋ณด๋ ํ๋ฉด์ธ๋ฐ๋ ๊ฝค๋ ํ๋ฆฌํฐ๊ฐ ์ ๋์๋ค.
1. ๋ก๊ทธ์ธ ํ๋ฉด
- ํ๊ฒฝ ์ ํ ์ง์: ์ ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๊ฒฝ ์ ํ
- ID/PW: ์ค์ DB ์ ๊ทผ ์ ์ฌ์ฉํ๋ ๋ฐ๊ธ๋ฐ์ ๋ณธ์ธ์ ๊ณ์ ์ ๋ ฅ
- ์คํค๋ง: ์ ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง ์ด๋ฆ ์ ๋ ฅ
- ๋ก๊ทธ์ธ ์ ๋ณด ๊ธฐ์ต: 30์ผ๊ฐ ๋ธ๋ผ์ฐ์ ์๋ก๊ณ ์นจ ํ์๋ ์ ๋ ฅ์ ๋ณด๋ฅผ ์ ์ง
์ฌ๊ธฐ์ ๋ก๊ทธ์ธํ ๊ณ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด DB Connection์ ๋งบ์ด๋๋๋ค.
private final Map<String, DataSource> userDataSources = new ConcurrentHashMap<>();
private final Map<String, JdbcTemplate> userJdbcTemplates = new ConcurrentHashMap<>();
public boolean connection(String dbEnv, String dbId, String dbPassword, String schema) {
// ํ๊ฒฝ์ ๋ง๋ JDBC URL ์์ฑ
String jdbcUrl = buildJdbcUrl(dbEnv, schema);
// ์ฌ์ฉ์ ๊ณ ์ ํค ์์ฑ
String userKey = generateUserKey(dbId, dbEnv, schema);
try {
// ๊ธฐ์กด ์ฐ๊ฒฐ์ด ์๋ค๋ฉด ์ ๋ฆฌ
cleanupExistingConnection(userKey);
// ์๋ก์ด ์ฐ๊ฒฐ ์์ฑ
DataSource newDataSource = createDataSource(jdbcUrl, dbId, dbPassword);
JdbcTemplate newJdbcTemplate = new JdbcTemplate(newDataSource);
try (Connection connection = newDataSource.getConnection()) {
// ์ฐ๊ฒฐ ์ฑ๊ณต ์ ์ฌ์ฉ์๋ณ ์ ๋ณด ์ ์ฅ
userDataSources.put(userKey, newDataSource);
userJdbcTemplates.put(userKey, newJdbcTemplate);
return true;
}
} catch (SQLException e) {
throw new RuntimeException("๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์คํจ: " + e.getMessage());
}
}
๊ทธ๋ฆฌ๊ณ ๋ณ๋์ DB๊ฐ ์๋ ๋ก๊ทธ์ธํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์คํค๋ง์ ์๋ flyway_schema_history ํ ์ด๋ธ์ ์ฌ์ฉํ๋ค. DMM ํ๋ก์ ํธ ๋ง๊ณ ๋ Flyway๋ฅผ ์ ํ ์์กดํ๊ณ ์์ง ์๊ธฐ ๋๋ฌธ์ ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์ Flyway ๊ด๋ จ ํ ์ด๋ธ์ด ์๋์ผ๋ก ์์ฑ๋์ง ์๋๋ค.
๋ฐ๋ผ์ DMM์์๋ ๋ก๊ทธ์ธ ์, ์ ์ํ ์คํค๋ง์ flyway_schema_history ํ ์ด๋ธ์ด ์กด์ฌํ๋์ง ํ์ธํ๋ฉฐ, ํด๋น ํ ์ด๋ธ์ด ์์ ๊ฒฝ์ฐ ์๋์ผ๋ก ์์ฑํ ๋ค ์ง์ ํ ์ ์๋๋ก ๋ค์๊ณผ ๊ฐ์ด ์๋ด ๋ฌธ๊ตฌ๋ฅผ ํ์ํ๋๋ก ํ์ฌ ์๋ก์ด ์คํค๋ง์์๋ ์ธ์ ๋ ์ง ์ฌ์ฉํ ์ ์๋๋ก ํ๋ค.
2. ๋ง์ด๊ทธ๋ ์ด์ ์ด๋ ฅ ์กฐํ ๋ฐ ๊ด๋ฆฌ
๋ก๊ทธ์ธํ๋ฉด ๋ณด์ด๋ ๋ฉ์ธ ํ์ด์ง๋ค. ํน์ ํ๊ฒฝ์์ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ์ํ๊ณ , ๋ฐ์ ๋ด์ญ์ ๋ชจ๋ํฐ๋งํ๋ ๋ฐ ์ ์ฉํ๊ฒ ํ์ฉํ ์ ์๋ค. ๋์ถฉ ํ์ฌ ํ๋ฉด ํ๋๋ง ๋ด๋ ์ด๋ค ๊ธฐ๋ฅ์ ํ๋์ง ํ์ ํ ์ ์๋ค.
์ค์๊ฐ ๋ง์ด๊ทธ๋ ์ด์ ์ด๋ ฅ ์กฐํ
- ๋ฆฌ์คํธ์์ ์ํ๋ ํ(row)์ ํด๋ฆญํ๊ฑฐ๋ ํค๋ณด๋ ํ์ดํ๋ฅผ ์ฌ์ฉํด ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์๋ค.
- ์ ํํ ํ์ ๋ฐ์๋ SQL์ด ํ๋จ์ ์๋์ผ๋ก ํ์๋๋ค.
- ํ์ด์ง๋ค์ด์ , ์ ๋ ฌ, ๊ฒ์ ๊ธฐ๋ฅ์ ํตํด ์ด๋ ฅ์ ํจ์จ์ ์ผ๋ก ์กฐํํ ์ ์๋ค.
์ฐ์ธก ์๋จ์ + Migration ๊ด๋ฆฌ ๋ฒํผ
- ์ ๊ท Migration ๋ฑ๋ก
- ํ๊ฒฝ ๊ฐ Migration ๋น๊ต
- ์คํค๋ง ๋น๊ต
์ฐ์ธก ์๋จ์ + Migration ๊ด๋ฆฌ ๋ฒํผ์์ ์ ๊ณตํด ์ฃผ๋ ๊ธฐ๋ฅ๋ค์ ๋ํด์ ์์๋ณด๊ฒ ๋ค.
3. ์ ๊ท Migration(์ฟผ๋ฆฌ) ๋ฑ๋ก
DB ์ฟผ๋ฆฌ๋ฅผ ๋ฐ์ํ ์ ์๋ค. ์ฐธ๊ณ ๋ก ๊ธฐ์กด์๋ ๊ฐ์ DBMS๋ฅผ ์ฌ์ฉํด์ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ์ํ์ง๋ง DMM์ด ๋์ ๋๊ณ ๋ ์ดํ๋ถํฐ๋ ๋ชจ๋ ์กฐํ ์ฟผ๋ฆฌ๋ฅผ ์ ์ธํ ๋ชจ๋ DML ๋ฐ DDL ์ฟผ๋ฆฌ๋ฐ์์ ์ฌ๊ธฐ์ ๋ฐ์์ ํ๋๋ก ํ ๋ด ์ฟผ๋ฆฌ ๋ฐ์ ํ๋ก์ธ์ค๋ฅผ ๋ณ๊ฒฝํ๋ค.
SQL ํ์ผ ์ ๋ก๋ ๋๋ ์ง์ ์ ๋ ฅ ๋ฐฉ์์ ๋ชจ๋ ์ง์ํ๋ฉฐ, ์ ๋ ฅ๋ SQL์ ํ์ผ๋ก ์์ฑ๋ ํ S3 ์ ์ฅ์์ ์ ๋ก๋๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ดํ Flyway๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์๋๋ค.(์ฐธ๊ณ ๋ก Flyway์ S3 ์ง์์ Flyway v7.0๋ถํฐ ์ ๊ณต๋๋ค.)
๋ง์ฝ Flyway๋ง ๋จ์ํ ๋์ ํ์ฌ ์ฌ์ฉํ๋ค๋ฉด ํ๋ก์ ํธ๋ง๋ค Flyway ์์กด์ฑ์ ์ถ๊ฐํ๊ณ src/main/resources/db/migration ๊ฒฝ๋ก์ SQL ํ์ผ์ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ์งํ๋์์ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ DMM ๋๋ถ์ ๊ฐ ํ๋ก์ ํธ์์๋ Flyway์ ๋ํด ์ ํ ์ ํ์๊ฐ ์๊ฒ ๋์๋ค.
๊ทธ๋ฆฌ๊ณ Flyway๋ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ์ ๋ณด์ ๋ฐ๋ผ ์ํ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ฟผ๋ฆฌ ๋ฐ์ ์๋ง๋ค ๋งค๋ฒ ์๋ก์ด Flyway ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ์คํํ๋ค.
/**
* Flyway๋ฅผ ์ฌ์ฉํ์ฌ ๋ง์ด๊ทธ๋ ์ด์
์ ์คํ
* ์ฃผ์: ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ DB ์ ๋ณด๋ก ๋ง์ด๊ทธ๋ ์ด์
์ด ์คํ๋จ
*/
private void executeMigration(JdbcTemplate jdbcTemplate, String env, String dbId) {
Flyway flyway = createFlywayInstance(jdbcTemplate, env, dbId);
try {
flyway.migrate();
logger.info("Migration applied successfully");
} catch (Exception e) {
logger.error("Migration failed", e);
throw e;
}
}
/**
* Flyway ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ์ค์
*/
private Flyway createFlywayInstance(JdbcTemplate jdbcTemplate, String env, String dbId) {
String schema = getSchemaFromSession();
/**
* S3 URL ํ์: s3:<bucket>(/optionalfolder/subfolder)
* https://documentation.red-gate.com/fd/locations-224919725.html
*/
String s3Location = String.format("s3:%s/%s/%s",
getBucketName(env),
MIGRATION_BASE_PATH,
schema);
return Flyway.configure()
.dataSource(jdbcTemplate.getDataSource())
.installedBy(dbId)
.locations(s3Location)
.baselineOnMigrate(true)
.outOfOrder(true)
.schemas(schema)
.load();
}
์คํฌ๋ฆฝํธ์ ๋ฒ์ ์ ํ์์คํฌํ ํ์์ผ๋ก ์๋ ์์ฑ๋๋ฉฐ, ์์ ์ด ๋ถ๊ฐ๋ฅํ๋๋ก ํ์ฌ ๋ฒ์ ์ถฉ๋์ ๋ฐฉ์งํ๋ค. ํ์์คํฌํ ๊ธฐ๋ฐ์ผ๋ก ์๋์ผ๋ก ๋ฒ์ ์ด ์์ฑ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๊ฐ ์ง์ ๋ฒ์ ์ ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋๋๋ก ํ์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฒ์ ๋ช ๋ค์ ๋ถ์ ๋ค์ด๋ฐ์๋ '์ค์ฟผ๋๋ช '๊ณผ '์คํ๋ฆฐํธ ๋ฒ์ '์ ๊ธฐ์ ํ๋๋ก ํ์ฌ ํ์ ์กฐํ ํ๋ฉด์์ ํํฐ๋ง์ ํตํด ์ฝ๊ฒ ๊ฒ์ํ ์ ์๋๋ก ์ ๋ํ๋ค.
์ฟผ๋ฆฌ ๋ฐ์ ์ฑ๊ณต
์ฟผ๋ฆฌ ๋ฐ์์ด ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋ฉด, ๋ฆฌ์คํธ์ ๋ฐฉ๊ธ ์ถ๊ฐํ ํญ๋ชฉ์ด ๋ฐ์๋๋ค.
์ฟผ๋ฆฌ ๋ฐ์ ์คํจ
์ฟผ๋ฆฌ ๋ฐ์์ ์คํจํ๋ฉด, ์คํจ ์์ธ์ ๋ํ ์๋ฆผ๊ณผ ํจ๊ป ํด๋น ์ํ๊ฐ ์คํจ๋ก ๊ธฐ๋ก๋๋ค. ์คํจํ ๊ธฐ๋ก์ ์ญ์ ํ์ง ์์ผ๋ฉด Flyway์ ํน์ฑ์ ์ดํ ๋ชจ๋ SQL ๋ฐ์ ์๋๊ฐ ์คํจํ๊ฒ ๋๋ค. ์คํจํ ๊ธฐ๋ก์ ํด์งํต ์์ด์ฝ์ ํด๋ฆญํ์ฌ ์์ฝ๊ฒ ์ญ์ ํ ์ ์๋ค.
Flyway๋ง ์ฌ์ฉํ๋ค๋ฉด, flyway_schema_history ํ ์ด๋ธ์ ๊ธฐ๋ก๋ ์คํจ ์ํ๋ฅผ ์๋์ผ๋ก ์ญ์ ํ๊ณ , SQL์ ์์ ํ ํ ์ฌ๋ฐฐํฌํด์ผ ํ์ ๊ฒ์ด์ง๋ง ํด๋ฆญ ํ ๋ฒ์ผ๋ก ์คํจ ๊ธฐ๋ก์ ์ญ์ ํ ์ ์์ด, ๋ณต์กํ ๊ณผ์ ์ ๊ฐ์ํํ๊ณ ๊ฐ๋ฐ์ ํธ์์ฑ์ ํฌ๊ฒ ํฅ์์์ผฐ๋ค.
๋๊ตฐ๊ฐ ๋ฐ์ ์ค์ผ ๊ฒฝ์ฐ
Flyway ์์ ์ด ์งํ ์ค์ผ ๋ ๋ค๋ฅธ ์์ ์ด ๋์์ ๋ฐ์๋๋ฉด ํ์ผ ์์ฑ ์์์ ๋ฐ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค. ๋ฐ๋ผ์ ์์ ์ ํ์ ๋ฝ์ ๊ฑธ์ด ๋ชจ๋ ์์ ์ด ์๋ฃ๋ ํ์ ๋์ํ๋๋ก ๊ตฌํํ์๋ค.(์ฐธ๊ณ ๋ก ์ด๋ฅผ ์ํด 1๋ฒ์์ ๋ก๊ทธ์ธ ์์ flyway_schema_history ๋ง๊ณ ๋ lock ๊ด๋ จ ํ ์ด๋ธ์ ํ๋ ๋ ์์ฑํ๋ค.)
4. ํ๊ฒฝ ๊ฐ Migration ๋น๊ต ๋ฐ ์ ์ฉ
์ฌ์ค์ DMM์ ํ๊ฒ ๋ ์ด์ ์ด์ ํต์ฌ ๊ธฐ๋ฅ์ด๋ค. ํน์ ํ๊ฒฝ์์ ๊ฐ๋ฐ์ด ์๋ฃ๋ ํ, ๋ค๋ฅธ ํ๊ฒฝ์ผ๋ก ๋ฐฐํฌํ ๋ ์ ์ฉํ๊ฒ ํ์ฉํ ์ ์๋ค. ์๋ฅผ ๋ค์ด ํ์ฌ DEV ํ๊ฒฝ์๋ ๊ฐ๋ฐ์๊ฐ ์์ฑํ ์ฟผ๋ฆฌ๊ฐ ๋ฐ์๋์ด ์์ง๋ง, QA ํ๊ฒฝ์๋ ๋ฐ์๋์ง ์์ ๊ฒฝ์ฐ ๋๋ฝ๋ ์ฟผ๋ฆฌ๋ฅผ ๋น ๋ฅด๊ฒ ํ์ธํ๊ณ ์ผ๊ด์ ์ผ๋ก ์ ์ฉํ ์ ์๋ค.
์ฌ๋ฌ ๋ฐฐํฌ ํ๊ฒฝ๊ณผ ๋น๊ตํ์ ๋ ํ์ฌ ํ๊ฒฝ์์ ๋ฐ์๋์ง ์์ ์ฟผ๋ฆฌ๋ค์ ํ๋์ ํ์ธํ ์ ์๋ค. ๊ฐ ํ๊ฒฝ๋ณ DB์ flyway_schema_history๋ฅผ ๋น๊ตํด ๋ฒ์ ์ด ์ผ์นํ์ง ์์ ๊ฒ๋ค์ ๋ณด์ฌ์ค๋ค.
ํ์ธ๋ ๋๋ฝ๋ ์ฟผ๋ฆฌ๋ค์ ์ ํ ํ ํ ๋ฒ์ ํด๋น ํ๊ฒฝ์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์ ์ ์งํํ ์ ์๋ค. ์ฐธ๊ณ ๋ก ์ ํํ ๋๋ฝ๋ ์ฟผ๋ฆฌ๋ ์ ํ ์์์ ๊ด๊ณ์์ด ๋ฒ์ ์์๋๋ก ์๋ ์ ์ฉ๋๋ฏ๋ก, ์ ์ฉ ์์๋ก ์ธํด ๋ฐ์ํ๋ ๋ฌธ์ ๋ฅผ ์ด๊ธฐ์ ๋ฐฉ์งํ๊ณ ๊ฐ๋ฐ ํธ์์ฑ์ ํฌ๊ฒ ํฅ์์์ผฐ๋ค.
๊ฐ์ฅ ํฐ ๋์์ด ๋๋ ๊ธฐ๋ฅ์ผ๋ก, ๊ฐ๋ฐ ํน์ฑ์ DEV ํ๊ฒฝ์์ ๊ผญ ์ฐ์ ์ ์ผ๋ก ์ฟผ๋ฆฌ ๋ฐ์์ด ์ผ์ด๋์ผ ํ๋ค๊ฑฐ๋ ํ์ง๋ ์๋๋ค. QA ํ๊ฒฝ์ ๋ฐฐํฌ๋ ์ดํ bugfix ๊ณผ์ ์์ QA ํ๊ฒฝ์๋ง ์ฟผ๋ฆฌ๋ฅผ ๋ฐ์ํ๊ณ ๋ค๋ฅธ ์ฌ๋ฌ ์คํ ์ด์ง ๋๋ ๊ฐ๋ฐ ํ๊ฒฝ์๋ ๋ฐ์ํ์ง ์๊ฑฐ๋, ๋ฐ๋๋ก ๊ฐ๋ฐ ํ๊ฒฝ์๋ง ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ ๋ง์๋ค. ๊ทธ๋ฆฌ๊ณ ๋น์ฅ์ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์ผ๋ฉด ํด๋น ์ฟผ๋ฆฌ ๋ฐ์์ด ๋๋ฝ๋์์์ ๋๊น์ง ๋์น์ฑ์ง ๋ชปํ๋ ์ผ์ด ํํ๋ค. ํ์ง๋ง ์ด ๊ธฐ๋ฅ์ ํตํด ๋๋ฝ๋ ์ฟผ๋ฆฌ๋ค์ ์์ฝ๊ฒ ์ฐพ๊ณ ๋ฐ์ํ ์ ์๊ฒ ๋์๋ค.
5. ์คํค๋ง ๋น๊ต
ํ๊ฒฝ๋ณ ์คํค๋ง ํ ์ด๋ธ ๊ตฌ์กฐ์ ์ฐจ์ด๋ฅผ ํ๋์ ํ์ธํ ์ ์๋ ๊ธฐ๋ฅ์ด๋ค. ๊ธฐ์กด์ ํ๊ฒฝ๋ณ๋ก ๋๋ฝ๋ ์ฟผ๋ฆฌ๊ฐ ๋ง์ ์ ํฉ์ฑ์ ๋ง์ถ๋ ๋ฐ ๋์์ ์ฃผ๊ธฐ ์ํด ๋ง๋ค์์ผ๋ฉฐ, ์ดํ์๋ ์ฃผ๊ธฐ์ ์ผ๋ก ํ์ธํ๋ฉด์ ์คํค๋ง์ ์ ํฉ์ฑ์ ์ ์งํ๋ ๋ฐ ์ ์ฉํ๊ฒ ํ์ฉํ ์ ์์ ๊ฒ์ด๋ผ ์๊ฐ๋์ด ๋ง๋ค์๋ค.
์์ ๊ฐ์ด ํธํ๊ฒ ํ์ธํ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ณ๊ฒฝ๋ ํ ์ด๋ธ์ ๋ํด์๋ ์๋ก ์ผ์น์ํค๊ธฐ ์ํ DDL์ ์๋์ผ๋ก ์์ฑํ์ฌ ์ ํฉ์ฑ์ ๋ง์ถ๋ ๋ฐ ๋์์ ์ฃผ๊ณ ์ ํ์๋ค.
๊ฒฐ๋ก
ํ๋ก์ ํธ ๋์ ์ดํ ์กฐํ ์ฟผ๋ฆฌ๋ฅผ ์ ์ธํ ๋ชจ๋ DML ๋ฐ DDL ์์ ์ DMM์ ํตํด ๋ฐ์ํ๋๋ก DB ๋ฐ์ ํ๋ก์ธ์ค๋ฅผ ์๋กญ๊ฒ ์๋ฆฝํ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ค์ ๋ก ์คํ๋ฆฐํธ๋ฅผ ํ ์ฌ์ดํด ๋๋ ค๋ณธ ๊ฒฐ๊ณผ ํฐ ๋ฌธ์ ์์ด ์์ ์ ์ผ๋ก ํ๋ก์ธ์ค๊ฐ ์ ๋ฆฝ๋์๋ค. DMM ๋๋ถ์ ๊ธฐ์กด์๋ ๊ฐ์๊ฐ DBMS๋ฅผ ํตํด ์ฟผ๋ฆฌ๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ๋ฐ์ํ๋ฉด์, ํด๋น ํ๊ฒฝ์ ์ฟผ๋ฆฌ๊ฐ ์ ๋๋ก ๋ฐ์๋์๋์ง ํ์ธํ๊ธฐ๊ฐ ์ด๋ ค์ ์ง๋ง ์ด์ ๋ ํ๋์ ๋ฐ์ ์ํ๋ฅผ ํ์ ํ ์ ์๊ฒ ๋์๊ณ , ํ๊ฒฝ ๊ฐ ๋๋ฝ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฝ๊ฒ ํ์ธํ ์ ์๊ฒ ๋์๋ค.
๊ทธ๋ฆฌ๊ณ ๋๋ฝ๋ ๋ง์ด๊ทธ๋ ์ด์ ์ผ๋ก ์ธํด ์ฑ ์ ์์ฌ๋ฅผ ๋ฐ์ง๊ธฐ ์ํ ๋ถํ์ํ ์ํต๋ ์ค์๋ค. ๊ธฐ์กด์๋ ์ฟผ๋ฆฌ๊ฐ ๋๋ฝ๋์์ ๊ฐ๋ฅ์ฑ์ด ์๋๋ผ๋ "์ด๊ฑฐ ๋ฐ์๋ ๊ฑธ๊น?", "๋ฐ์ํด๋ ๋ ๊น?", "๊ดํ ํ๋ค๊ฐ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉด ๋ด๊ฐ ์ฑ ์์ ธ์ผ ํ ๊ฒ ๊ฐ์๋ฐ, ๋ค๋ฅธ ์ฌ๋์ด ํด์ฃผ๊ฒ ์ง"์ ๊ฐ์ ์๊ฐ ๋๋ฌธ์ ์ ๋ป ๋ฐ์ํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์ง๋ง ์ด์ ๋ ๋๋ฝ๋ ์ฟผ๋ฆฌ๋ฅผ ๋ช ํํ ์ธ์งํ ์ ์์ด ํ์ธํ ์ฌ๋์ด ๋ฐ๋ก ๋ฐ์๋ง ํ๋ฉด ๋๊ฒ ๋์๋ค.
ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ํญ์ ๋จธ๋ฆฟ์์ ๊ฐ์ง๊ณ ์์๋ ์๊ฐ์ '์๋ก์ด ํ๋ก์ธ์ค๋ฅผ ์ ๋ฆฝํ๋ ๊ฒ์ด ๊ธฐ์กด๋ณด๋ค ๋ ๋ณต์กํ๊ฑฐ๋ ์ด๋ ต์ง ์์์ผ ํ๋ค.'์๋ค. ๊ทธ๋ ๊ธฐ์ ๋จ์ํ Flyway๋ฅผ ๋์ ํ๋ ๋ฐ ๊ทธ์น์ง ์๊ณ , ํ์๋ค์ด ๋ณ๋๋ก Flyway ๊ท์น์ ํ์ตํ์ง ์์๋ ๋๋ ์์คํ ์ ์ค๊ณํ๊ณ ์ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ธฐํ๋ถํฐ ๋์์ธ(?), ํ๋ก ํธ์๋, ๋ฐฑ์๋๊น์ง ์ ๋ฐ์ ์ผ๋ก ํผ์ ์งํํด ๋ณด์๋๋ฐ ๋ง์กฑ์ค๋ฌ์ด ์ฑ๊ณผ๊ฐ ๋์จ ๊ฒ ๊ฐ๋ค.
'ํ๊ธฐ๐ฅ > ํ๊ณ ๋ก' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
NextStep DDD ์ธ๋ ๋๋ฐ ์๋ฃ ํ๊ธฐ (2) | 2024.07.15 |
---|---|
AWS Solution Architect Associate(SAA-C03) ์ทจ๋ ํ๊ธฐ (6) | 2024.05.06 |
์ธ๋ถ API๋ฅผ ์ฐ๋ํ ๋ ๊ณ ๋ คํ๋ฉด ์ข์ ์ ๋ค (2) | 2024.02.24 |
[๋ญํน ์๊ณ ๋ฆฌ์ฆ] - Hacker News Algorithm (3) | 2024.01.16 |
2023๋ ํ๊ณ (10) | 2024.01.14 |
๊ธฐ์ ์ ๋ณด๋ฅผ ์์งํ๋ ๋ฐฉ๋ฒ (4) | 2023.12.28 |
๋๊ธ