MySQL wait_timeout 연결 시간 초과 문제 해결 방안

애플리케이션에서 장시간 유휴 상태인 데이터베이스 연결로 인해 발생하는 MySQL 연결 오류는 개발 환경에서 흔히 마주치는 문제 중 하나다. 대표적인 예외 메시지는 다음과 같다:

Nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 
The last packet successfully received from the server was X milliseconds ago, 
which is longer than the server's 'wait_timeout' setting. Connection failed.

이 메시지는 클라이언트가 마지막으로 서버와 통신한 지 X 밀리초가 경과했으며, 이 값이 MySQL 서버의 wait_timeout 설정보다 크기 때문에 연결이 끊어졌음을 의미한다. 일반적으로 MySQL은 특정 시간 동안 아무 작업이 없는 연결을 자동으로 종료하는데, 이 시간의 기본값은 8시간(28,800초)이다. 그러나 애플리케이션 측의 커넥션 풀(Connection Pool)은 해당 연결이 이미 폐기되었는지 모를 수 있어, 이후 요청 시 무효한 연결을 제공하면서 오류가 발생하게 된다.

문제 원인 분석

MySQL은 두 가지 타임아웃 변수를 통해 연결 유지 시간을 제어한다:

  • wait_timeout: 비대화형(non-interactive) 클라이언트 연결에 적용되는 유휴 시간 제한
  • interactive_timeout: 대화형(interactive) 클라이언트(예: MySQL CLI)에 적용

두 값 모두 기본적으로 28,800초(8시간)이며, 시스템 변수로 관리된다. 다음 명령어로 현재 값을 확인할 수 있다:

SHOW VARIABLES LIKE '%timeout%';

커넥션 풀이 관리하는 연결이 이 시간을 초과하여 MySQL 서버에 의해 닫히면, 풀 내에서는 여전히 유효한 연결로 간주되어 문제가 발생한다.

해결 전략

1. MySQL 서버 타임아웃 값 조정 (비권장)

서버 차원에서 wait_timeoutinteractive_timeout 값을 늘릴 수 있다. MySQL 설정 파일(my.cnf 또는 Windows의 my.ini)에 다음 항목을 추가하거나 수정한다:

[mysqld]
wait_timeout = 31536000
interactive_timeout = 31536000

변경 후 MySQL 서비스를 재시작해야 한다. 단, 이 방법은 모든 클라이언트에 영향을 주며, 과도한 연결 누수가 발생할 수 있으므로 권장되지 않는다.

2. 커넥션 풀의 최대 유휴 시간 단축

커넥션 풀 내 연결의 생존 기간이 MySQL의 wait_timeout보다 짧도록 설정하는 것이 더 안정적인 접근이다. 예를 들어, C3P0 풀을 사용할 경우:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="maxIdleTime" value="1800"/> <!-- 30분 -->
</bean>

이 설정은 1,800초(30분) 이상 사용되지 않은 연결을 자동으로 제거하므로, 서버의 타임아웃보다 먼저 정리되어 오류를 방지한다.

3. 유휴 연결 검사 및 유효성 테스트 활성화

커넥션 풀이 주기적으로 연결 상태를 점검하고, 실제 사용 전 유효성을 확인하도록 구성할 수 있다. C3P0 기준 예시:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="idleConnectionTestPeriod" value="1800"/> <!-- 30분마다 검사 -->
    <property name="preferredTestQuery" value="SELECT 1"/>
    <property name="testConnectionOnCheckout" value="true"/>
</bean>

또는 Apache DBCP를 사용하는 경우:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="validationQuery" value="SELECT 1"/>
    <property name="testWhileIdle" value="true"/>
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
    <property name="minEvictableIdleTimeMillis" value="300000"/>
</bean>

이러한 설정은 유휴 연결에 대해 주기적으로 SELECT 1 쿼리를 실행하여 연결이 살아 있는지 확인하며, 체크아웃 시에도 유효성을 검증함으로써 오류 가능성을 크게 줄인다.

요약

MySQL의 wait_timeout으로 인한 연결 오류는 서버 설정 변경보다는 애플리케이션 측 커넥션 풀의 적절한 구성으로 해결하는 것이 바람직하다. 특히 유효성 검사 활성화적절한 풀 수명 관리가 핵심이다. 이를 통해 장시간 실행되는 배치 처리나 저사용량 시스템에서도 안정적인 DB 연결을 유지할 수 있다.

태그: MySQL connection timeout wait_timeout connection pool C3P0

7월 6일 05:24에 게시됨