본문 바로가기
DataBase/🦭Maria

Maria DB / HikariCP Connection 누수 개선 (Too many connections)

by 발개발자 2023. 1. 20.
반응형

  이슈 발생

현재 Maria DB를 사용하면서 Connection에 대한 이슈가 발생했다.

많은 개발자들이 DB에 달라 붙다보니 당연히 DB Connection Session이 늘어나게 된다. 

그러면서 이제 1차적인 문제가 발생했다.

 

Too many connections 

 

 

  DB Setting을 통한 1차 해결

 

현재 DB 세팅은 max-pool-size가 150이며 Connection의 유휴상태(sleep)에서 default대기 시간이 8시간이다.

 

-- max pool size 확인
show variables like '%max_connect%';

-- connection timeout 확인
show variables like 'wait_timeout';

 

즉, 150개의 요청의 세션이 sleep상태로 살아있다면 위와 같은 Too many connections라는 에러를 뱉게 된다.

불필요한 요청 세션이 살아있더라도 pool-size가 줄어들어 Too many connections 를 발생하게 된다는 것이다.

 

먼저, 해결하기 위해 wait_timeout을 줄였다. 

8시간이라는 수치는 너무 많기 때문에 일단 테스트겸 30초로 줄였다.

 

 set global wait_timeout=30;

 

그 후 아래의 명령어를 통해 사용자들의 유휴 세션이 정상적으로 제거되는것을 확인했다.

-- DB의 connection list 조회
SHOW processlist;

 

흠 ez하네..?

 

30초는 너무 짧았지? 하고 wait_timeout을 수정하려는 순간 다른 에러가 발생한다. 역시 자만은 필패의 원인이다.

java.sql.SQLNonTransientConnectionException: (conn=2691) Socket error

??? 이게 뭐시영.. ???

 

 

보고 추론하건데, Server에서 DB Connection 맺어놓은 것을 DB단에서 30초 지나 제거해서 발생하는 오류로 추정했다.

즉, 아래의 프로세스로 흘렀을 것이라고 추정한다.

 

1. HikariCP에서 MariaDB와 Connection을 맺음.
2. MariaDB에서도 해당 Connection 생성.
3. MariaDB쪽에서는 일정 시간이 자나 Connection을 제거.
4. HikariCP에서는 현재 Connection을 유지 중.
5. 서버에서 해당 HikariCP의 Connection을 가져와 사용 요청.
6. DB에서 Connection이 제거 되어있기 때문에 Connection 실패 에러 발생.

 

음..

그러면 HikariCP에서도 일정시간이 지나면 Connection을 반납하고 재생성하는 설정이 있지않을까?

그래 있다. 원래 본인이 생각하는 모든 것들은 이 세상에 있기 마련이다.

 

  HikariCP 수정을 통한 2차 해결

 

application.yml

    hikari:
      max-lifetime: 15000
logging:
  level:
    jdbc.connection : INFO
    com.zaxxer.hikari.HikariDataSource: INFO

max-lifetime은 Connection이 Connection Pool 에서 최대 살아있을 수 있는 시간이다.

 

max-lifetime이 DB단의 wait_timeout을 넘어가면 안되니 15000(15초)로 테스트를 진행해봤다.

 

ㄷㄱㄷㄱㄷㄱ..

 

본인 애창곡...

아무일도 없었다..

max-lifetime이 지나면 Connection 반납하는거 아니었어..?

로그를 뒤지던 와중 친절한 가이드를 만났다.

 

2023/01/20 13:26:42,217 [WARN ] [com.zaxxer.hikari.HikariConfig] [restartedMain]- HikariPool-1 - maxLifetime is less than 30000ms, setting to default 1800000ms.

 

아하.. 15000(15초)는 너무 짧아서 안된다고 친절히 로그가 남았다. 

기본이 30000(30초)기 때문에 넉넉하게 60초로 변경하고 DB의 wait_timeout도 이것보다 길어야하기 wait_timeout도 63초로 변경하였다.

 

application.yml

    hikari:
      max-lifetime: 60000

 

SQL

 set global wait_timeout=63;

 

ㄷㄱㄷㄱㄷㄱㄷㄱㄷㄱ...

다시 재도전한 결과 무사히 서버단에서도 1분 마다 Connection을 반납하고 재생성하는 것을 확인할 수 있었다.

 

Log

2023/01/20 14:38:00,895 [INFO ] [jdbc.connection] [HikariPool-1 connection adder]- 39. Connection opened 2023/01/20 14:38:00,987 [INFO ] [jdbc.connection] [HikariPool-1 connection closer]- 17. Connection closed 2023/01/20 14:38:01,001 [INFO ] [jdbc.connection] [HikariPool-1 connection adder]- 40. Connection opened 2023/01/20 14:38:58,121 [INFO ] [jdbc.connection] [HikariPool-1 connection closer]- 21. Connection closed 2023/01/20 14:38:58,145 [INFO ] [jdbc.connection] [HikariPool-1 connection adder]- 41. Connection opened 2023/01/20 14:38:58,375 [INFO ] [jdbc.connection] [HikariPool-1 connection closer]- 22. Connection closed

 

 

  개선사항

해당 세팅을 통해 아래와 같이 개선할 수 있었다.

 

1. HikariCP에서 MariaDB와 Connection을 맺음.
2. MariaDB에서도 해당 Connection 생성.
3. HikariCP에서 1분이 지난 미사용중인 Conneciton closed.
4. MariaDB에서도 해당 Connection이 제거됨.
5. MariaDB에서 다른 커넥션 중 63초가 지난 유휴 Connection 제거.

 

따라서 DB내에서 sleep으로 잡아먹는  불필요한 Connection을 제거해서 누수를 방지하고 서버 CP에서 발생한 누수문제를 해결할 수 있었다.

 

끗.

 

 

참고

GitHub - brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.

 

GitHub - brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.

光 HikariCP・A solid, high-performance, JDBC connection pool at last. - GitHub - brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.

github.com

 

 

반응형

'DataBase > 🦭Maria' 카테고리의 다른 글

[MariaDB] Mysql Shell Script로 매일 자동 백업하기  (0) 2023.01.03

댓글