MySQL Too many connections 에러 해결 완벽 가이드 max_connections 설정부터 커넥션 풀 최적화까지

MySQL 운영 중 'Too many connections' 에러로 서비스가 중단된 경험이 있다면, 이 글은 필독입니다. 단순히 max_connections 값만 올리는 임시방편이 아니라, 영구 설정 방법과 커넥션 풀 최적화까지 실전 트러블슈팅 관점에서 정리했습니다. 재발 방지를 위한 구체적인 파라미터 설정과 점검 명령어를 지금 바로 확인하십시오.


MySQL Too many connections 에러 해결 완벽 가이드 max_connections 설정부터 커넥션 풀 최적화




1. 'Too many connections' 에러 진단 및 즉시 대응

서비스 중단 상황에서는 원인 분석보다 복구가 우선입니다. 아래 명령어로 현재 상태를 빠르게 파악하십시오.

  • 현재 접속 목록 확인: SHOW PROCESSLIST;
  • 최대 접속 허용값 확인: SHOW VARIABLES LIKE 'max_connections'; (기본값: 151)
  • 현재 접속 수: SHOW STATUS LIKE 'Threads_connected';
  • 실제 동작 중인 커넥션: SHOW STATUS LIKE 'Threads_running';

즉시 복구가 필요하다면 임시로 최대 접속 수를 늘려 서비스를 정상화하십시오:

SET GLOBAL max_connections = 1000;

주의: 이 명령은 MySQL 재시작 시 초기화됩니다. 영구 적용은 다음 섹션에서 다룹니다.

2. my.cnf 영구 설정 및 경로 확인

SET GLOBAL로 변경한 값은 서버 재시작 시 사라지므로 반드시 설정 파일에 기록해야 합니다.

설정 파일 위치 확인

  • Linux/Unix: /etc/my.cnf, /etc/mysql/my.cnf, /usr/local/mysql/etc/my.cnf
  • Windows(기본 설치): C:\Program Files\MySQL\MySQL Server X.X\my.ini
  • Windows(MSI 설치): %PROGRAMDATA%\MySQL\MySQL Server X.X\my.ini

Windows에서 ProgramData 경로를 모른다면 명령 프롬프트에서 echo %PROGRAMDATA%로 확인하십시오. basedir를 확인하려면 MySQL에서 SHOW VARIABLES LIKE '%dir';를 실행하면 됩니다.

my.cnf 설정 예시

[mysqld]
max_connections = 500
max_user_connections = 50
wait_timeout = 600
interactive_timeout = 600

설정 후 반드시 MySQL을 재시작해야 적용됩니다:

# MySQL
sudo systemctl restart mysqld

# MariaDB
sudo systemctl restart mariadb

재시작 후 SHOW VARIABLES LIKE 'max_connections';로 값이 정상 반영되었는지 검증하십시오.

3. 유휴 세션 정리 및 사용자별 접속 제한

max_connections만 늘리는 것은 근본 해결이 아닙니다. 불필요한 커넥션이 쌓이는 것을 방지해야 재발을 막을 수 있습니다.

유휴 세션 자동 종료

  • wait_timeout: 비활성 커넥션이 종료되기까지의 시간(초). MySQL 기본값은 28800초(8시간)로 과도하게 깁니다.
  • interactive_timeout: 대화형 클라이언트(mysql CLI 등)의 타임아웃.

실전에서는 600초(10분) 정도로 낮추는 것을 권장합니다. 애플리케이션이 커넥션 풀을 사용한다면 더 짧게 설정해도 무방합니다.

[mysqld]
wait_timeout = 600
interactive_timeout = 600

사용자당 접속 제한

특정 계정이 과도하게 커넥션을 점유하는 것을 막으려면 max_user_connections를 설정하십시오:

[mysqld]
max_user_connections = 50

이 설정을 초과하면 ERROR 1226 (42000): User 'user_name' has exceeded the 'max_user_connections' resource 에러가 발생합니다. 이는 정상적인 방어 메커니즘입니다.

4. 애플리케이션 레벨: 커넥션 풀 최적화

DB 서버 설정만큼 중요한 것이 WAS의 커넥션 풀 설정입니다. 매 요청마다 커넥션을 새로 생성하면 TCP 핸드셰이크, 인증, 세션 초기화 등의 오버헤드가 발생합니다. 커넥션 풀은 이를 제거하고 한정된 DB 자원을 효율적으로 사용하게 합니다.

HikariCP 주요 파라미터 (Spring Boot 2.x 기본 풀)

  • maximumPoolSize: 최대 풀 크기. 기본값 10은 대부분 환경에서 부족합니다. 부하 테스트로 적정값을 찾으십시오.
  • connectionTimeout: 커넥션 대기 시간. 기본 30초는 과도하게 깁니다. 0.5~3초로 설정해 빠르게 에러를 반환하도록 하십시오.
  • maxLifetime: 커넥션 최대 수명. MySQL의 wait_timeout보다 작게 설정해야 합니다. (예: wait_timeout이 600초면 maxLifetime은 580초)
  • minimumIdle: 유지할 최소 유휴 커넥션 수. 설정하지 않으면 maximumPoolSize와 동일하게 동작합니다.
  • keepaliveTime: 유휴 커넥션 유효성 확인 주기. 기본값 0(비활성)이며, 설정 시 주기적으로 연결을 검증합니다.

풀 크기 계산 공식

우아한형제들 기술 블로그에서 제시한 공식:

pool size = Tn × (Cm - 1) + 1
Tn = 전체 Thread 수
Cm = 한 Task에서 동시에 필요한 Connection 수

실전 사례에서는 MySQL 600명 동시 접속 환경에서 15~20개 커넥션으로 충분했다는 보고도 있습니다. 과도한 풀 크기는 메모리 낭비와 DB 리소스 낭비를 초래하므로, 부하 테스트를 통해 최소한의 값을 찾는 것이 핵심입니다.

Spring Boot application.yml 설정 예시

spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      connection-timeout: 3000
      max-lifetime: 580000
      minimum-idle: 10
      keepalive-time: 30000

핵심 팁: connectionTimeout을 짧게 설정하면 풀이 고갈되었을 때 즉시 에러를 반환해 장애 전파를 막을 수 있습니다. 긴 타임아웃은 요청이 대기열에 쌓여 전체 시스템을 느리게 만듭니다.

5. 트러블슈팅 체크리스트

문제 발생 시 아래 순서로 점검하십시오:

  1. 즉시 복구: SET GLOBAL max_connections로 임시 증설
  2. 원인 파악: SHOW PROCESSLIST로 비정상 세션 확인 (Sleep 상태가 과도하게 많은지 등)
  3. 영구 설정: my.cnf에 max_connections, wait_timeout, max_user_connections 반영 후 재시작
  4. 애플리케이션 점검: 커넥션 풀 설정 확인 (maximumPoolSize, connectionTimeout, maxLifetime)
  5. 모니터링 설정: Threads_connected, Threads_running 메트릭을 주기적으로 수집해 임계치 알림 구성

주의할 에러 메시지:

  • ERROR 1040 (HY000): Too many connections → max_connections 초과
  • ERROR 1226 (42000): User 'user_name' has exceeded the 'max_user_connections' resource → max_user_connections 초과

마무리: 지금 바로 실행할 것

이 글에서 다룬 내용을 요약하면, Too many connections 에러는 DB 서버 설정(max_connections, wait_timeout)과 애플리케이션 커넥션 풀 설정(maximumPoolSize, connectionTimeout)을 함께 최적화해야 근본적으로 해결됩니다. 임시 대응으로 SET GLOBAL을 사용하되, 반드시 my.cnf에 영구 반영하고, 유휴 세션 정리 파라미터를 설정해 재발을 방지하십시오.

Action Item: 지금 당장 운영 중인 MySQL 서버에서 SHOW STATUS LIKE 'Threads_connected';SHOW VARIABLES LIKE 'max_connections';를 실행해 현재 사용률을 확인하십시오. 사용률이 80%를 넘는다면 이 글의 설정을 즉시 적용할 것을 권장합니다.


#함께 읽으면 좋은 글

Cloudflare CDN 설정으로 웹사이트 속도 2배 올리기 및 SSL 무료 적용법 : 바로보기

댓글