나만의 개발 로그 | 고민 로그
개발 서버 DB Connection Pool 장애 대응기 본문
최근 로컬 개발 환경에서 PostgreSQL을 Docker로 띄우고 프로젝트를 개발하던 중, 뜻밖의 장애를 마주했다. 테스트 서비스 일부에서 갑자기 500 Internal Server Error를 뱉기 시작한 것이다.
🧪 증상
에러 로그를 확인해보니 다음과 같은 메시지가 있었다
FATAL: sorry, too many clients already
🔍 원인 분석
PostgreSQL의 기본 설정은 다음과 같았고
- max_connections = 100
이 프로젝트 환경에서는 아래와 같은 조건이 겹쳤다:
- PostgreSQL 컨테이너 1개에 여러 명의 개발자가 로컬에서 동시에 접속
- 각 WAS에서 커넥션 풀 기본값인 10개 커넥션을 선점
- 결과적으로 DB 커넥션이 100개를 초과 → DB 접근 불가 → 500 에러 발생
🔧 1차 해결 방법: max_connections 수정
우선 해당 리눅스 서버에 들어가서 Docker로 띄운 PostgreSQL의 설정을 수정했다(임시 방편으로 max_connections 증가)
sudo docker exec -it 도커컨테이너id vi /var/lib/postgresql/data/postgresql.conf
⚠️ 하지만 무작정 max_connection만 증가시키는 게 "진짜 해결책"일까?
PostgreSQL 커넥션은 메모리를 잡아먹는다
PostgreSQL은 각 커넥션마다 별도의 OS 프로세스를 fork하는 구조이다.
- 커넥션 1개당 수 MB ~ 수십 MB의 메모리 사용
- 커넥션 200개 → 최소 수백 MB ~ 기가바이트 단위 메모리 사용
- 이게 Docker 컨테이너 안에서 발생하면?
⇒ 컨테이너 메모리 폭증
⇒ 개발 서버 전체에 OOM 발생 가능
실제로 어떤 식으로 터질 수 있나?
- 개발 서버 메모리가 가득 차면 운영체제가 가장 메모리를 많이 쓰는 PostgreSQL 프로세스를 강제 종료(OOM Kill)하게 됨
- => 이 순간 DB 전체가 다운되면서 다른 개발자나 테스트 서비스도 연결 불가 상태로 전이됨
✅ 추가 해결책
1. WAS 커넥션 풀 설정 조정
- 각자 기본 설정으로 10~20개로 잡혀있는 커넥션 수를 줄였다.
- 로컬 개발 환경이기 때문에 3개면 충분할 것이라고 판단했다.
예시 (Spring Boot + HikariCP):
spring.datasource.hikari.maximum-pool-size=3
2. DB 인스턴스 분리 or 개발 환경 분산
- 모든 개발자가 하나의 DB 인스턴스를 공유하는 구조는 위험하고 테스트 간섭 등의 문제가 발생하기 쉽다.
- 따라서 로컬 Docker 환경으로 따로 분리 가능한 경우 분리해서 개발하기로 결정 했다.
🧠 배운 점
- PostgreSQL은 커넥션당 별도 프로세스를 fork하기 때문에 max_connections은 곧 메모리 사용량이다.
- pg_stat_activity를 통해 현재 커넥션 상태를 확인하는 법을 알게 됐다.
- 이 경험을 통해 커넥션 풀과 DB 인프라에 대한 이해를 높이는 좋은 계기가 되었다..!
'DB' 카테고리의 다른 글
| DB 이것 저것 정리! (feat.SQL 실행순서..) (0) | 2024.01.19 |
|---|---|
| Docker PostgresSQL 컨테이너 Dump 후 로컬에서 복원하기(도커 컨테이너 -> 리눅스 서버(호스트) -> 로컬) (0) | 2023.12.08 |
| SQL -3 (0) | 2023.01.13 |
| SQL -2 (0) | 2023.01.13 |
| SQL -1 (0) | 2023.01.13 |
Comments