본문 바로가기

Development/DB, JPA

DBCP maxLIfeTime Issue

Error Msg

Failed to validate connection com.mysql.cj.jdbc.ConnectionImpl@17061015 (No operations allowed after connection closed.)Possibly consider using a shorter maxLifetime value.

 

즉, Pool 내의 Connection을 validate 해보니, DB에서 이미 해당 커넥션을 종료시켰기 때문에 발생하는 에러이다.

 

public class HikariConfig implements HikariConfigMXBean
{
   private static final Logger LOGGER = LoggerFactory.getLogger(HikariConfig.class);

   private static final char[] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
   private static final long CONNECTION_TIMEOUT = SECONDS.toMillis(30);
   private static final long VALIDATION_TIMEOUT = SECONDS.toMillis(5);
   private static final long IDLE_TIMEOUT = MINUTES.toMillis(10);
   private static final long MAX_LIFETIME = MINUTES.toMillis(30);
   private static final int DEFAULT_POOL_SIZE = 10;

...

 

위와 같이 Hiakri CP 의 기본 maxLifeTime은 30분으로 잡혀있다.

그러면 예상되는 시나리오는 DB의 wait_timeout이 30분 보다 짧기 때문에 먼저 커넥션을 끊어 버리고, 끊어진 걸 Hikari CP에서는 10분간 살아있는 커넥션을 사용(검증)하려다고 하는 경우일 것이다.

그런데?

DB의 wait_timeout이 8시간으로 잡혀있네 ?. 여기서 부터 미궁속으로.

 


도대체 원인을 찾을 수가 없었는데,,,

ㅎㅎㅎ..

잠시만! show variables ?? 이건 sequel pro의 connection에 해당 되는 값이다.. wait_timeout 을 잘못 찾았다. session의 wait_timeout이 아닌 global wait_timeout을 조회 했어야했다.

그럼 그렇지, 5분으로 잡혀있다.

 

조치

  • DB global wait_timeoutDBCP maxLIfeTime 에 맞추던지
  • DBCP maxLIfeTimeDB global wait_timeout 에 맞추던지

난 Hikari CP 의 설정을 변경하는 것으로 마무리

hikari:
      pool-name: my-dbcp
      connection-timeout: 10000
      maximum-pool-size: 16
      max-lifetime: 240000

추가적으로

idleTimeout is close to or more than maxLifetime, disabling it. 의 Warning이 떴는데 이는, IDLE_TIMEOUT 은 기본값 10분으로 잡혀 있기 때문이다.

 

Config Validation 중에 다음과 같은 코드가 있다.

 

if (idleTimeout + SECONDS.toMillis(1) > maxLifetime && maxLifetime > 0) {
         LOGGER.warn("{} - idleTimeout is close to or more than maxLifetime, disabling it.", poolName);
         idleTimeout = 0;
}

 

즉, idleTimout 을 사용하려면, maxLifetime 보다 1초 이상 적게 잡아야한다.