본문 바로가기
Spring 7기 프로젝트/모임 플렛폼 프로젝트

Spring Boot MySQL 데이터베이스 설정 완벽 가이드

by JuNo_12 2025. 8. 9.

들어가며

중간 규모 트래픽을 처리하는 Spring Boot 애플리케이션에서 MySQL 데이터베이스 설정을 최적화하는 방법에 대해 정리하겠습니다. HikariCP 커넥션 풀, JPA/Hibernate, Flyway 마이그레이션까지 모든 설정을 상세히 다루어보겠습니다.


HikariCP 커넥션 풀 설정

기본 커넥션 풀 크기 설정

datasource:
  hikari:
    minimum-idle: 10
    maximum-pool-size: 20
    pool-name: "MainHikariPool"

-  minimum-idle: 최소 유지 커넥션 수를 10개로 설정합니다. 이는 갑작스러운 트래픽 증가에 대비하여 기본적인 커넥션을 미리 확보해두는 역할을 합니다.

-  maximum-pool-size: 최대 커넥션 수를 20개로 제한합니다. 중간 규모 애플리케이션에 적합한 수치이며, 데이터베이스 서버의 과부하를 방지합니다.

-  pool-name: 모니터링 도구에서 커넥션 풀을 식별하기 위한 이름을 지정합니다. Actuator와 연동할 때 유용합니다.

 

타임아웃 설정 최적화

datasource:
  hikari:
    connection-timeout: 20000
    idle-timeout: 600000
    max-lifetime: 1800000
    validation-timeout: 5000
    leak-detection-threshold: 300000

-  connection-timeout: 커넥션 풀에서 커넥션을 가져오기까지 대기하는 최대 시간을 20초로 설정합니다. 이는 적절한 응답 시간을 보장하면서도 시스템 안정성을 확보합니다.

-  idle-timeout: 유휴 커넥션이 풀에서 제거되기까지의 시간을 10분으로 설정합니다. 너무 짧으면 커넥션 생성 비용이 증가하고, 너무 길면 불필요한 리소스를 점유하게 됩니다.

-  max-lifetime: 커넥션의 최대 생존 시간을 30분으로 설정합니다. 이는 데이터베이스 서버의 타임아웃 설정보다 짧게 설정하여 예기치 않은 커넥션 끊김을 방지합니다.

-  validation-timeout: 커넥션 유효성 검사의 최대 대기 시간을 5초로 설정합니다.

-  leak-detection-threshold: 커넥션 누수를 감지하는 임계값을 5분으로 설정합니다. 이 시간을 초과하여 커넥션이 반환되지 않으면 로그에 경고를 출력합니다.

 

MySQL 최적화 설정

PreparedStatement 캐시 최적화

data-source-properties:
  cachePrepStmts: true
  prepStmtCacheSize: 250
  prepStmtCacheSqlLimit: 2048
  useServerPrepStmts: true

-  cachePrepStmts: PreparedStatement 캐싱을 활성화합니다. 반복적으로 실행되는 쿼리의 성능을 크게 향상시킵니다.

-  prepStmtCacheSize: 캐시할 PreparedStatement의 최대 개수를 250개로 설정합니다.

-  prepStmtCacheSqlLimit: 캐시할 SQL 문의 최대 길이를 2048자로 제한합니다.

-  useServerPrepStmts: 서버 사이드 PreparedStatement를 사용하여 성능을 최적화합니다.

 

배치 처리 최적화

data-source-properties:
  rewriteBatchedStatements: true
  useLocalSessionState: true
  cacheResultSetMetadata: true
  cacheServerConfiguration: true
  elideSetAutoCommits: true
  maintainTimeStats: false

-  rewriteBatchedStatements: 배치 INSERT/UPDATE 문을 단일 네트워크 호출로 최적화합니다. QueryDSL과 JPA의 배치 처리 성능을 크게 향상시킵니다.

-  useLocalSessionState: 세션 상태를 로컬에서 추적하여 불필요한 서버 통신을 줄입니다.

-  cacheResultSetMetadata: ResultSet 메타데이터를 캐싱하여 반복 쿼리의 성능을 향상시킵니다.

-  cacheServerConfiguration: 서버 설정 정보를 캐싱하여 초기화 시간을 단축합니다.

-  elideSetAutoCommits: 불필요한 autocommit 설정 호출을 제거하여 성능을 향상시킵니다.

-  maintainTimeStats: 시간 통계 수집을 비활성화하여 오버헤드를 줄입니다.

 

네트워크 및 문자셋 설정

data-source-properties:
  connectTimeout: 15000
  socketTimeout: 300000
  characterEncoding: UTF-8
  useUnicode: true
  serverTimezone: Asia/Seoul

-  connectTimeout: 데이터베이스 서버와의 연결 시도 시간을 15초로 제한합니다.

-  socketTimeout: 소켓 읽기 타임아웃을 5분으로 설정하여 긴 실행 시간이 필요한 쿼리를 지원합니다.

-  characterEncoding/useUnicode: UTF-8 인코딩을 명시적으로 설정하여 한글 처리를 보장합니다.

-  serverTimezone: 한국 시간대를 설정하여 날짜/시간 처리의 일관성을 보장합니다.


JPA/Hibernate 최적화 설정

기본 설정

jpa:
  hibernate:
    ddl-auto: none
  properties:
    hibernate:
      dialect: org.hibernate.dialect.MySQLDialect
      format_sql: true
      use_sql_comments: false
      generate_statistics: false

-  ddl-auto: Flyway를 사용하므로 Hibernate의 DDL 자동 생성을 비활성화합니다.

-  dialect: MySQL 방언을 명시적으로 설정하여 최적화된 SQL을 생성합니다.

-  format_sql: 개발 환경에서 SQL 로그의 가독성을 향상시킵니다. 운영 환경에서는 false로 설정하는 것이 좋습니다.

-  generate_statistics: 성능 통계 수집을 비활성화하여 오버헤드를 줄입니다.

 

배치 처리 최적화

properties:
  hibernate:
    jdbc:
      batch_size: 50
      batch_versioned_data: true
      order_inserts: true
      order_updates: true
      fetch_size: 50

-  batch_size: 배치 처리 시 한 번에 처리할 엔티티 수를 50개로 설정합니다.

-  batch_versioned_data: 버전 관리되는 엔티티도 배치 처리를 적용합니다.

-  order_inserts/order_updates: INSERT와 UPDATE 문을 정렬하여 데드락 위험을 줄이고 배치 효율성을 높입니다.

-  fetch_size: JDBC 드라이버 레벨에서 한 번에 가져올 행 수를 설정합니다.

 

쿼리 최적화

properties:
  hibernate:
    default_batch_fetch_size: 16
    query:
      in_clause_parameter_padding: true
      plan_cache_max_size: 128
      fail_on_pagination_over_collection_fetch: true

-  default_batch_fetch_size: N+1 문제를 완화하기 위한 배치 페치 크기를 16으로 설정합니다.

-  in_clause_parameter_padding: IN 절의 파라미터를 2의 거듭제곱으로 패딩하여 쿼리 캐시 효율성을 높입니다.

-  plan_cache_max_size: 쿼리 실행 계획 캐시의 최대 크기를 128개로 제한합니다.

-  fail_on_pagination_over_collection_fetch: 컬렉션 조인 페치와 페이징을 동시에 사용할 때 에러를 발생시켜 성능 문제를 예방합니다.

 

JPA 추가 설정

jpa:
  show-sql: true
  open-in-view: false
  defer-datasource-initialization: true

-  show-sql: SQL 로그를 출력합니다. 개발 환경에서 디버깅에 유용합니다.

-  open-in-view: OSIV(Open Session In View)를 비활성화하여 성능을 최적화하고 명확한 트랜잭션 경계를 설정합니다.

-  defer-datasource-initialization: Flyway 마이그레이션 완료 후 JPA를 초기화하도록 설정합니다.


Flyway 마이그레이션 설정

기본 설정

flyway:
  enabled: true
  locations: classpath:db/migration
  encoding: UTF-8
  baseline-on-migrate: true

-  enabled: Flyway를 활성화합니다.

-  locations: 마이그레이션 파일의 위치를 지정합니다.

-  encoding: 마이그레이션 파일의 인코딩을 UTF-8로 설정합니다.

-  baseline-on-migrate: 기존 데이터베이스에 Flyway를 처음 적용할 때 베이스라인을 생성합니다.

 

검증 및 보안 설정

flyway:
  validate-on-migrate: true
  out-of-order: false
  group: false
  mixed: false
  clean-disabled: false
  fail-on-missing-locations: true
  placeholder-replacement: false
  sql-migration-suffixes: [".sql"]

-  validate-on-migrate: 마이그레이션 실행 전 파일 무결성을 검증합니다.

-  out-of-order: 순서를 벗어난 마이그레이션을 허용하지 않습니다.

-  group: 각 마이그레이션을 개별 트랜잭션으로 실행합니다. 운영 환경에서는 true로 설정하는 것이 좋습니다.

-  mixed: SQL과 Java 마이그레이션의 혼용을 방지합니다.

-  clean-disabled: 데이터베이스 전체 삭제 기능을 비활성화합니다. 운영 환경에서는 반드시 true로 설정해야 합니다.

-  fail-on-missing-locations: 마이그레이션 위치가 존재하지 않을 때 실패하도록 설정합니다.

-  placeholder-replacement: 플레이스홀더 치환을 비활성화하여 보안을 강화합니다.

-  sql-migration-suffixes: SQL 마이그레이션 파일의 확장자를 명시적으로 지정합니다.


마무리

이러한 설정을 통해 중간 규모 트래픽을 안정적으로 처리할 수 있는 데이터베이스 환경을 구축할 수 있습니다. 각 설정값은 애플리케이션의 특성과 트래픽 패턴에 따라 조정이 필요할 수 있으므로, 모니터링을 통해 지속적으로 최적화하는 것이 중요합니다.

특히 HikariCP의 커넥션 풀 설정과 JPA의 배치 처리 설정은 성능에 직접적인 영향을 미치므로, 실제 운영 환경에서의 테스트를 통해 최적값을 찾아가시길 권장합니다.