사이드 프로젝트를 하다가 데이터베이스 테이블 컬럼을 변경했는데, 예상치 못한 에러가 발생했던 경험이 있다. 특히 JPA와 Hibernate를 쓸 때는 ddl-auto 설정에 따라 결과가 완전히 달라지기 때문에, 이번 기회에 ddl-auto 옵션이 뭔지, 그리고 테이블 컬럼을 바꿨을 때 데이터베이스가 실제로 어떻게 동작하는지 정리해보려고 한다.
스키마 변경으로 겪었던 문제
최근 프로젝트에서 DB 테이블 컬럼 값을 변경했더니 에러가 났다. 예전에 다른 프로젝트에서는 JPA 설정을 ddl-auto: create로 해두니까 테이블이 자동으로 삭제되고 새로 만들어져서 별 문제가 없었는데, 만약 이런 설정이 운영 환경에서 그대로 쓰이면? 모든 데이터가 싹 날아가는 대참사가 벌어진다. 그래서 운영에서는 update나 validate처럼 좀 더 안전한 옵션을 써야 한다고 생각했는데, 이 경우엔 또 변경된 스키마가 자동으로 반영되지 않아서 SQL을 직접 써서 변경해야 하는 번거로움이 있다. 왜 이런 일이 생기는지, 데이터베이스 스키마가 바뀔 때 실제로 어떤 일이 일어나는지 궁금해서 이번에 제대로 공부해보았다.
JPA Hibernate의 ddl-auto 옵션 정리
- create : 애플리케이션 시작할 때 기존 테이블 싹 다 지우고 새로 만듦. 종료할 때는 테이블 그대로 둠.
- create-drop : create랑 비슷한데, 종료할 때 테이블도 같이 삭제함.
- update : 기존 테이블 구조를 유지하면서 변경된 스키마만 적용.
- validate : 엔티티와 테이블이 정상적으로 매핑됐는지만 확인하고, 불일치가 있으면 애플리케이션 실행 자체를 막음.
- none : 아무 작업도 안 함. 주로 운영 환경에서 기본값으로 씀.
update 옵션의 한계
update 옵션이 얼핏 보면 제일 좋아 보이지만, 실제로는 제약이 많다. 새로운 컬럼 추가 같은 단순한 변경만 반영되고, 기존 컬럼의 데이터 타입이나 nullable 여부 같은 건 변경이 안 된다.
운영 환경에서의 위험성
운영 환경에서 create나 create-drop을 쓰는 건 진짜 위험하다. 모든 데이터가 삭제되는 대형 사고가 일어날 수 있다. 특히 스프링 부트에서 여러 프로파일을 쓸 때, 공통 설정에 ddl-auto를 create로 두고 운영용 프로파일에서 따로 안 덮어쓰면, 운영에서도 create가 적용돼서 데이터가 몽땅 날아갈 수 있으니 반드시 주의해야 한다.
데이터베이스 스키마 변경 추적 기능
몇몇 DBMS는 스키마 변경을 추적하는 기능도 제공한다. 예를 들어 SQL Server는
- Change Data Capture (CDC) : 실제로 변경된 데이터까지 캡처
- Change Tracking : 행이 변경됐다는 사실만 캡처, 실제 변경 데이터는 캡처 안 함
이런 기능들이 있어서 스키마 변경 시 문제를 모니터링하고 대응하는 데 도움이 된다.
스키마 변경 시 데이터베이스 동작 방식
DB 테이블 구조가 바뀔 때 실제로 무슨 일이 일어날까?
- 관계형 DB의 스키마 변경 처리
- ALTER TABLE, CREATE INDEX, DROP COLUMN 같은 DDL 명령을 실행하면, 일부 DB는 변경 중에 테이블을 잠그고 일시적으로 쓰기를 막는다.
- 다운타임을 줄이기 위해 온라인 작업을 지원하는 DB도 있다.
- 트랜잭션으로 변경이 원자적으로 처리되도록 보장한다.
- 스키마 변경이 미치는 영향
- 성능 저하 : 인덱스나 데이터 타입 변경이 쿼리 성능에 직접 영향을 줄 수 있다. 대형 테이블에 컬럼 추가만 해도 성능이 떨어질 수 있다.
- 데이터 무결성 문제 : 컬럼 타입 변경이나 필수 컬럼 추가는 데이터 불일치를 야기할 수 있다.
- 다운스트림 프로세스 중단 : 스키마 구조에 의존하는 앱, 리포트, 분석 파이프라인 등이 실패할 수 있다.
스키마 변경 관리 모범 사례
안전하게 스키마를 바꾸려면 어떻게 해야 할까?
- 환경별 ddl-auto 설정
- 개발/로컬: create 또는 update
- 테스트 서버: update 또는 validate
- 스테이징/운영: validate 또는 none
(영한님 JPA 강의에서도 이렇게 추천!)
- 버전 관리 시스템 사용
- DB 변경사항도 버전 관리해서 이력 추적 & 롤백 가능하게 한다.
- 마이그레이션 도구 활용
- Liquibase, Flyway 같은 도구로 스키마 변경을 코드로 관리하고, 버전별로 점진적으로 적용한다.
- 데이터 일관성 보장
- 스키마 변경 전에 영향을 받는 테이블/컬럼을 꼼꼼히 점검하고, 필요하면 임시 테이블이나 병렬 처리 전략을 쓴다.
- 코드와 DB 변경 분리
- 애플리케이션 코드 배포와 DB 스키마 변경을 분리해서, 문제가 생기면 바로 롤백할 수 있게 한다.
- 철저한 테스트
- 스키마 변경 전에 비프로덕션 환경에서 충분히 테스트해서 문제를 미리 잡는다.
결론
DB 테이블 컬럼 변경은 겉보기엔 쉬워 보여도, 실제로는 신중하게 접근해야 하는 복잡한 작업이다. JPA의 ddl-auto 옵션은 개발할 땐 편하지만, 운영에서는 데이터 손실 위험이 크다.
안전하게 스키마를 바꾸려면 환경별로 옵션을 잘 나눠 쓰고, 마이그레이션 도구와 버전 관리를 적극 활용해야 한다.
그리고 코드 배포와 DB 변경을 분리해서, 문제가 생겨도 빠르게 대응할 수 있도록 하는 게 중요하다.
DB 스키마 변경은 단순한 기술 작업이 아니라, 시스템 전체의 안정성과 성능에 영향을 주는 중요한 과정이라는 걸 항상 기억해야 한다.
적절한 계획과 도구를 써서 스키마 변경을 관리하면, 위험을 줄이고 DB와 애플리케이션의 무결성을 잘 지킬 수 있을 것이다.
다음은 Flyway를 좀더 알아보고자 한다. ( 프로젝트에 적용되어있음 지금은 제거됨)
'개발일기 > TIL(Since24.04.19)' 카테고리의 다른 글
타임리프에서 SPA로? SSR과 CSR 개념 정리 (0) | 2025.04.21 |
---|---|
DB 변경 감지 (flyway) (0) | 2025.04.20 |
임베딩 된 값이 제대로 들어갔는지 확인해보자 (0) | 2025.04.18 |
@Repository (0) | 2025.04.17 |
멀티 모듈 방식이란? (0) | 2025.03.26 |