문제 인식
운영 중인 서비스의 DB 서버에서 메모리 사용량이 지속적으로 증가하고, Swap 메모리까지 사용하는 현상이 확인되었습니다.
Grafana 대시보드에서 메모리 사용량이 우상향하는 패턴이 관찰되었고, Swap 사용량도 함께 증가하고 있었습니다.

프로세스 분석
ps aux --sort=-%mem 명령어로 메모리 점유 프로세스를 확인한 결과, MariaDB 프로세스(mariadb -u root -p)가 20개 이상 실행 중이었습니다.
각 프로세스가 약 2.3~2.5%의 메모리를 점유하고 있었으며, 이들의 합산이 전체 메모리의 상당 부분을 차지하고 있었습니다.
DB 세션 확인
운영 DB
MariaDB [(none)]> SHOW PROCESSLIST;
운영 DB의 세션 수는 약 10개로, 모두 Sleep 상태였지만 정상 범위 내였습니다.
개발 DB
MariaDB [(none)]> SHOW FULL PROCESSLIST;
개발 DB의 세션 수는 40개 이상으로, 운영 대비 4배나 많았습니다. 대부분 Sleep 상태로 유휴 커넥션이 반환되지 않고 누적되어 있었습니다.
원인 분석 — HikariCP 커넥션 풀 설정
애플리케이션의 DB 커넥션 풀 설정(HikariCP)을 확인했습니다.

hikari:
pool-name: jpa-hikari-pool
maximum-pool-size: 30
minimum-idle: 10
idle-timeout: 30000
max-lifetime: 1800000
connection-timeout: 30000
auto-commit: false| 설정 | 값 | 의미 |
|---|---|---|
| maximum-pool-size | 30 | 최대 커넥션 수 |
| minimum-idle | 10 | 최소 유휴 커넥션 수 |
| idle-timeout | 30,000ms (30초) | 유휴 커넥션 제거 대기 시간 |
| max-lifetime | 1,800,000ms (30분) | 커넥션 최대 수명 |
운영 vs 개발 세션 수 차이 원인
- 운영: 트래픽이 일정하고,
max-lifetime(30분) 경과 후 커넥션이 갱신되면서minimum-idle(10개) 수준으로 유지 - 개발: 여러 개발자가 동시에 접속하거나 테스트를 반복하면서 커넥션이
maximum-pool-size(30개) 근처까지 생성되고, 유휴 상태로 누적
max-lifetime: 1800000(30분)이 지나면 커넥션이 갱신되면서 10개 수준으로 줄어드는 패턴이 확인되었습니다.
근본적 문제 — 개발/운영 DB 동일 서버
포트를 분리하여 운영 DB와 개발 DB를 같은 서버에서 운영하고 있었지만, 개발 DB의 세션 누적이 운영 DB 서버의 메모리에 직접적인 영향을 주고 있었습니다.
이는 운영 안정성 관점에서 리스크가 큰 구조입니다.
대응 방향
- 개발 DB 분리: 개발 DB를 별도 테스트 서버로 이전하여 운영 서버 메모리 영향 제거
- 커넥션 풀 최적화: 개발 환경의
maximum-pool-size를 줄이고,idle-timeout을 더 짧게 설정 - 모니터링 강화: DB 세션 수 추이를 지속적으로 모니터링하여 비정상 누적 조기 감지
- Swap 사용량 알람: Swap 사용이 일정 수준을 넘으면 알람 발생하도록 설정
마무리
"메모리가 왜 차지?"에서 시작해 ps aux → SHOW PROCESSLIST → HikariCP 설정 확인 순서로 원인을 추적했습니다.
DB 서버의 메모리 문제는 단순히 쿼리 성능만의 문제가 아니라, 커넥션 풀 설정과 환경 분리 같은 인프라 구조적 요소에서 비롯될 수 있다는 점을 확인한 케이스였습니다.