[WingITs / Spring Boot] H2 → MySQL 전환 시 서버 재시작마다 DB 날아간다면?

Rose·2025년 6월 9일

개발 이슈 로그

목록 보기
2/2

로컬 개발 환경에서 H2 인메모리 DB를 사용하다가 MySQL로 전환하면서 발생했던 문제들과 그 해결 과정을 정리합니다. Docker와 TablePlus를 활용했으며, data.sql 자동 실행 및 application-test.yml 오작동 등 다양한 이슈들을 직접 해결했습니다.

❗️문제 정의

H2에서 MySQL로 데이터베이스를 전환한 후 회원가입을 하게 되면 정상적으로 데이터가 저장되지만, 서버를 재시작하면 저장된 데이터가 사라지는 문제가 발생했습니다.

문제 재현 절차

  1. IntelliJ에서 서버 실행

  2. 브라우저에서 회원가입 진행

  1. TablePlus에서 users 테이블 확인
    ▲ 회원가입 직후 TablePlus에 저장된 사용자 정보 확인 화면

  2. IntelliJ에서 서버 종료 (DemoApplication 수동 종료)

  3. Docker 컨테이너 종료

docker stop wingits-mysql
  1. Docker 컨테이너 다시 시작
docker start wingits-mysql
  1. IntelliJ에서 서버 재실행

  2. 다시 TablePlus에서 users 테이블 확인
    ▲ 서버 재실행 후 회원 정보가 사라진 상태


🔍 사실 수집

  • spring.jpa.hibernate.ddl-auto: update로 설정되어 있음
  • 회원가입은 성공했고, TablePlus에서도 데이터 확인됨
  • docker volume도 정상적으로 연결되어 있었음
  • CommandLineRunner 안에서 userRepository.deleteAll() 사용
  • data.sql 파일이 존재함
  • application-test.yml에서 mysql을 사용하도록 되어 있었다는 사실을 발견함

💡 원인 추론

  1. data.sql 자동 실행
    → Spring Boot는 서버 시작 시 data.sql이 존재하면 이를 실행함. 이로 인해 MySQL DB의 기존 데이터가 매번 초기화됨.

▲ MySQL로 전환한 뒤에도 data.sql 파일이 남아 있는 상태

  1. CommandLineRunner에서 deleteAll() 호출
    → 개발 중 테스트용 코드가 실서버에서도 동작하며 회원 데이터를 모두 삭제해 문제를 악화시킴.

  2. application-test.yml 설정이 제대로 분리되지 않음
    → 테스트 환경에서도 실제 MySQL을 참조하게 되어 의도치 않게 실DB에 영향을 줄 수 있는 구조였음.


해결 방법 결정

  1. 운영 환경에서 유저 데이터가 삭제되지 않도록
    • CommandLineRunner 내 userRepository.deleteAll() 코드 제거

  2. Spring Boot의 자동 SQL 실행 방지
    • data.sql, schema.sql 파일 완전 삭제

  3. 테스트 환경과 운영 환경의 설정 명확히 분리
    • 운영은 MySQL, 테스트는 H2를 사용
    • application.yml과 application-test.yml을 분리하고, 테스트에서는 아래와 같은 H2 설정만 유지

spring:
  datasource:
    url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
    driver-class-name: org.h2.Driver
    username: sa
    password:
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true
  h2:
    console:
      enabled: true
  1. 도커 볼륨 확인 및 MySQL 영속성 확보
    • Docker Volume이 /var/lib/mysql에 제대로 마운트되어 있는지 확인 (docker inspect 명령 사용)
    • 컨테이너 재시작 시 데이터가 유지되는지 테스트 완료

결론 요약

원인설명조치
data.sql 자동 실행서버 시작 시 실행되어 DB 초기화data.sql 삭제
CommandLineRunner.deleteAll()운영 환경에서도 모든 유저 삭제 실행됨해당 코드 제거 또는 조건 분기
application-test.yml 설정 오류테스트 DB가 MySQL로 설정됨H2로 수정하여 테스트 분리
Docker 볼륨 마운트 불확실데이터 유지가 안 되는 의심docker inspect로 확인, 문제 없음

실수를 줄이기 위한 팁

  • data.sql파일은 운영 환경에서 사용하지 않으면 삭제해두는 것이 좋습니다. (실수로 DB가 초기화될 수 있습니다.)
  • CommandLineRunner에서 초기화 코드(deleteAll() 등)는 테스트 전용 조건 분기 또는 @Profile("test") 설정으로 운영 환경과 분리하는 것이 좋습니다.
  • application.yml, application-test.yml의 설정을 명확히 구분하고, 테스트 환경에서는 반드시 H2 같은 인메모리 DB를 사용합시다.
  • docker inspect 명령어로 볼륨 마운트 상태를 꼭 확인해두면, 데이터 손실 여부를 빠르게 파악할 수 있습니다.
  • 중요한 설정(ddl-auto, datasource url 등)은 코드 리뷰 전 꼭 double-check!
profile
개발자를 꿈꾸며, 하루하루 쌓아가는 로제의 지식 아카이브입니다.

0개의 댓글