그래도 db 연결이 안 돼요... (Public Key Retrieval 에러)

elive7·2025년 8월 5일

개발노트

목록 보기
4/11
post-thumbnail

배경

이전 글에서는 새로 만든 컨테이너에서 호스트에 설치된 MySQL까지 성공적으로 연결을 확인했다. 그래서 자신 있게 애플리케이션을 다시 배포했지만…

그래도 연결이 안 돼요...

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)

계속해서 db 연결에 실패하는 모습을 찾아볼 수 있었다. 🥹

로그레벨 조정

logging:
  level:
    org.springframework.jdbc.datasource: DEBUG
    org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl: DEBUG
    com.zaxxer.hikari.pool.HikariPool: DEBUG
    org.hibernate.SQL: DEBUG
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE

조금 더 자세한 로그를 보기 위해 yml 파일에 다음을 추가해주었다.

Spring Boot 로깅 설정 각 항목 설명

항목설명로그 레벨
org.springframework.jdbc.datasource스프링 JDBC 데이터소스 관련 동작 (커넥션 획득, 반환 등) 로그DEBUG
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl하이버네이트가 JDBC 커넥션을 드라이버 매니저로부터 얻는 과정DEBUG
com.zaxxer.hikari.pool.HikariPoolHikariCP 커넥션 풀의 상태 및 커넥션 생성, 반환, 종료 관련 로그DEBUG
org.hibernate.SQL하이버네이트가 실행하는 SQL 쿼리 로그DEBUG
org.hibernate.type.descriptor.sql.BasicBinder하이버네이트의 SQL 쿼리 파라미터 바인딩 과정 (매우 상세 로그)TRACE

로그 레벨 설명

로그 레벨설명
TRACE가장 상세한 로그. 함수 호출, 변수 상태 등 세밀한 정보 포함
DEBUG개발 및 디버깅 목적의 상세 정보
INFO일반적인 실행 정보 (기본 로그 레벨)
WARN주의가 필요한 경고 메시지
ERROR심각한 오류 및 예외 메시지

Public Key Retrieval 에러

로그 레벨을 설정한 후 로그를 보니 아래와 같은 에러가 발생한 것을 볼 수 있었다.

java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)

java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed 에러는 MySQL 8.0 이상에서 기본 인증 방법(caching_sha2_password)으로 접속 시, 드라이버가 서버의 공개키를 받아오지 못해 발생하는 보안 관련 예외이다.

해결 방법

1. JDBC URL에 allowPublicKeyRetrieval=true 추가하기

spring:
  datasource:
    url: jdbc:mysql://172.17.0.1:3306/<db명>?serverTimezone=UTC&useSSL=false&characterEncoding=UTF-8&allowPublicKeyRetrieval=true

위와 같이 allowPublicKeyRetrieval=true 옵션을 추가해주면 MySQL 서버의 공개 키를 안전하게 받아올 수 있어 보안 오류를 우회할 수 있다.

2. MySQL 사용자 인증 플러그인 확인 및 변경 (MySQL 서버 설정)

ALTER USER '<계정명>'@'%' IDENTIFIED WITH mysql_native_password BY '<비밀번호>';
FLUSH PRIVILEGES;

대부분의 경우 1번 설정만으로 문제가 해결되지만, 내 경우에는 추가로 인증 방식을 변경해야 했다. 따라서 mysql 사용자의 인증 방법을 mysql_native_password로 변경하였더니 드디어 연결에 성공할 수 있었다. 이렇게 하면 1번처럼 JDBC URL에 allowPublicKeyRetrieval=true을 추가할 필요가 없다. (mysql_native_password는 공개키 기반 인증이 아니기 때문에 드라이버가 공개키 요청을 하지 않아서 allowPublicKeyRetrieval=true 옵션을 설정해도 무시된다.)

이렇게 JDBC URL 설정과 사용자 인증 방식을 함께 조정해 주면서, 드디어 애플리케이션에서 호스트 MySQL에 정상적으로 연결될 수 있었다.

참고

profile
펠리컨적 사고 "일단 시도함"

0개의 댓글