
확인 기준: 2026년 8월 6일, MySQL 8.4 LTS입니다. 서버 연결 시 ERROR 1040 (HY000): Too many connections가 나타나면 허용된 연결 슬롯이 다른 클라이언트에 모두 사용 중이라는 뜻입니다. 서비스 복구가 급하더라도 max_connections부터 크게 올리기보다 연결을 누가 붙잡고 있는지 확인해야 재발을 줄일 수 있습니다.
빠른 결론
- CONNECTION_ADMIN 권한이 있는 관리자 계정으로 예비 연결 1개를 사용해 진단합니다.
- SHOW PROCESSLIST와 performance_schema.processlist로 Sleep·장기 실행 연결을 찾습니다.
- 커넥션 풀 누수와 느린 쿼리를 고친 뒤 메모리·OS 한도를 검토해 max_connections를 조정합니다.
먼저 확인할 상태값
| 확인 항목 | 명령 | 의미 |
|---|---|---|
| 현재 연결 수 | SHOW STATUS LIKE 'Threads_connected'; | 지금 열려 있는 연결 수 |
| 최대 사용 기록 | SHOW STATUS LIKE 'Max_used_connections'; | 서버 시작 후 동시 연결 최고치 |
| 한도 초과 거부 | SHOW STATUS LIKE 'Connection_errors_max_connections'; | 연결 한도 때문에 거부된 누적 횟수 |
| 현재 설정값 | SHOW VARIABLES LIKE 'max_connections'; | 허용된 최대 일반 연결 수 |
| 연결 상세 | SELECT * FROM performance_schema.processlist; | 사용자·호스트·명령·대기 시간을 확인 |
MySQL 1040 오류 해결 순서
- 관리자 진단 연결을 확보합니다. MySQL은 max_connections에 더해 CONNECTION_ADMIN 또는 더 이상 권장되지 않는 SUPER 권한 계정용 연결 1개를 예약합니다. 일반 애플리케이션 계정에는 이 권한을 주지 말고 장애 진단용 관리자 계정에만 둡니다.
- 전체 프로세스를 확인합니다.
SHOW FULL PROCESSLIST;또는SELECT * FROM performance_schema.processlist;를 실행합니다. 다른 계정의 모든 스레드를 보려면 PROCESS 권한이 필요하며, 없으면 자신의 스레드만 보입니다. - Sleep 연결을 분류합니다. Command가 Sleep이고 Time이 긴 행이 많다면 어느 user·host에서 왔는지 확인합니다. Sleep 자체가 곧 오류는 아니지만, 요청이 끝난 뒤 연결을 풀에 반환하지 않는 코드나 과도한 풀 크기가 없는지 점검할 단서입니다.
- 장기 쿼리와 잠금을 봅니다. Query 상태가 오래 지속되거나 특정 State에서 멈춘 연결은 느린 쿼리·잠금 대기일 수 있습니다. 쿼리와 트랜잭션 원인을 먼저 확인하고, 영향 범위를 파악한 경우에만
KILL 연결ID;를 사용합니다. - 커넥션 풀 총합을 계산합니다. HikariCP 등 애플리케이션 풀의 최대 크기에 인스턴스 수를 곱하고, 배치·모니터링·관리 도구의 직접 연결도 더합니다. 합계가 DB 한도를 항상 가득 채우지 않도록 운영 여유를 둡니다.
- 임시 완화가 필요한지 판단합니다. 자원이 충분하고 원인을 확인했다면
SET GLOBAL max_connections = 200;처럼 값을 조정할 수 있습니다. 이 변경은 새 연결에 적용되지만 서버 재시작 뒤 유지되지 않으므로 임시 조치로 기록합니다. - 영구 설정은 검토 후 반영합니다. MySQL 8.4에서는 권한과 운영 정책에 따라
SET PERSIST max_connections = 200;을 쓰거나 my.cnf·my.ini의 [mysqld]에 값을 기록할 수 있습니다. 설정 파일 위치와 재시작 절차는 운영체제·패키지마다 다릅니다. - 서버 자원 한도를 함께 확인합니다. 연결이 늘면 세션 버퍼와 스레드 자원 사용도 증가합니다. InnoDB 버퍼 풀과 OS 여유 메모리, open_files_limit·파일 디스크립터 제한을 확인해 실제 서버가 감당할 범위만 허용합니다.
주의사항
운영 서버에서 연결을 무작정 KILL하면 정상 요청이나 트랜잭션이 끊길 수 있습니다. max_connections를 매우 크게 올리면 메모리와 파일 디스크립터 부족으로 더 큰 장애가 날 수 있습니다. 변경 전 현재 값·최대 사용 기록·애플리케이션 풀 합계와 롤백 방법을 남기세요.
해결되지 않을 때 추가 점검
performance_schema.accounts로 user·host별 현재 및 누적 연결을 확인해 배치, BI 도구, 모니터링 같은 풀 밖의 접속을 찾습니다.- 느린 쿼리 로그와 잠금 대기를 확인해 연결이 오래 반환되지 않는 이유를 찾습니다.
- 리플리케이션이나 그룹 리플리케이션 연결, 관리자 도구용 연결도 전체 접속 예산에 포함합니다.
- DB 재시작은 진행 중인 트랜잭션과 서비스에 영향을 주므로 마지막 수단으로 보고 사전 공지·백업·복구 절차를 준비합니다.
자주 묻는 질문
Q1. max_connections만 올리면 해결되나요?
일시적으로 접속이 열릴 수는 있지만 누수, 과도한 풀, 느린 쿼리가 원인이면 다시 가득 찹니다. Threads_connected와 프로세스 목록을 먼저 확인한 뒤 자원이 충분할 때만 조정하세요.
Q2. SHOW PROCESSLIST와 performance_schema.processlist의 차이는 무엇인가요?
둘 다 서버 스레드 상태를 보여 줍니다. MySQL 8.4 공식 문서는 기존 INFORMATION_SCHEMA.PROCESSLIST 구현보다 Performance Schema 구현 사용을 권장합니다. 표 형태라 조건 필터와 집계에도 편리합니다.
Q3. 관리자 예비 연결은 root만 쓸 수 있나요?
root라는 이름 자체가 조건은 아닙니다. CONNECTION_ADMIN 또는 구형 SUPER 권한을 가진 계정이 max_connections 밖의 예비 연결 1개를 사용할 수 있습니다.
관련 글
공식 출처
'IT > DB' 카테고리의 다른 글
| MySQL Access denied for user 해결: 계정@호스트·비밀번호·SHOW GRANTS 점검 순서 (MySQL 8.4) (0) | 2026.09.04 |
|---|---|
| PostgreSQL remaining connection slots 오류 해결: pg_stat_activity로 원인 진단 (0) | 2026.08.10 |
| 오라클 기본자료형 (0) | 2020.02.26 |
| 이클립스 오라클 연동 OJDBC (0) | 2020.02.20 |
| Oracle 계정 활성화 방법, 비밀번호 기간 만료 해제(ORA-28002) (0) | 2020.02.17 |
댓글