자율 학습/에러 해결

[MySQL] DB 연결 host is blocked because of many connection errors

60cod 2025. 3. 13. 17:13

DB에 연결하려는데 갑자기 블락 알림창 뜨면서 연결할 수 없었다.

"Host {아이피} is blocked because of many connection errors"

 

 

 

 

[해결]

RDS DB 재시작 하면 초기화 된다고 하지만 함부로 할 수 없다.

 

 

1. max_connect_errors 조회

SHOW VARIABLES LIKE 'max_connect_errors';

 

하지만 DB에 붙을 수가 있어야 쿼리를 날리니까...

내 PC에서는 확인할 수가 없어서 다른 PC에서 실행해봤다.

 

 

AWS 콘솔에서도 확인은 할 수 있다.

  • RDS 데이터베이스 선택 > 구성 > 파라미터 그룹 선택 > 'max_connect_errors'

 

 

'-' 로 되어 있는 건 설정을 안 했다는 뜻이다.

그래서 기본값인 100으로 설정된 상황이다.

 

 

2. 호스트 캐시 초기화

-> 연속된 연결 오류 수 초기화

-> 호스트 차단 해제

FLUSH HOSTS;

 

근데 루트에서 실행해야 됨.

RELOAD 권한 없다고 에러 뜸.

SQL Error [1227] [42000]: Access denied; you need (at least one of) the RELOAD privilege(s) for this operation

 

방금은 RDS DB에 따로 설치한 DB를 연결해서 저 쿼리를 실행했었다.

다시 루트 DB에 연결해서 쿼리 실행해야 한다.

 

 

'FLUSH HOSTS' is deprecated and will be removed in a future release. Please use TRUNCATE TABLE performance_schema.host_cache instead

 

 

초기화가 되긴 됐는데 안내 메시지가 출력된다.

FLUSH HOSTS는 deprecated 되었기 때문에 MySQL 8.0.23 이상에서는 TRUNCATE를 사용하여 호스트 캐시를 초기화 하라고 한다.

TRUNCATE TABLE performance_schema.host_cache;

 

 

 

 

[원인 분석]

그럼 도대체 내 IP가 왜 차단되었을까..?

 

1. 호스트 캐시 확인

SELECT * FROM performance_schema.host_cache;

 

호스트별 에러 횟수를 확인할 수 있는 테이블이다.

 

예를 들어서, DB 연결할 때 비밀번호를 틀리면 COUNT_AUTHENTICATION_ERRORS 카운트가 올라간다.

 

 

 

그런데 이번 블락 원인은 핸드쉐이크 오류였다.

  • COUNT_HANDSHAKE_ERRORS : MySQL의 Handshake 프로토콜이 완료되지 않았을 때 증가

 

 

2. MySQL에 TCP연결 시 핸드쉐이크 오류 발생

알고보니까 DB 작업을 하면서 연결이 얼마나 오래 끊기는지 간단하게 확인하려고 만든 스크립트가 문제였다.

 

nc 명령어를 이용해서 1초 간격으로 TCP 연결을 확인하는 스크립트였는데, 

TCP 연결 후 핸드쉐이크 프로토콜을 완료하지 않아서 mysql이 핸드쉐이크 오류로 카운팅 해버리는 것이다.

 

즉, MySQL DB에 단순히 TCP 연결만 하고 넘어가면 오류가 발생한다.

(MySQL 버그 보고 : https://bugs.mysql.com/bug.php?id=93197)

 

 

 

3. 연속된 연결 오류 수가 max_connect_errors 초과하면 호스트 차단

호스트 캐시 테이블 보니까 COUNT_HANDSHAKE_ERRORS 증가할 때 SUM_CONNECT_ERRORS 값이 증가했다.

  • SUM_CONNECT_ERRORS : 차단으로 간주되는 연결 오류 수
    → 이 값이 max_connect_errors 초과하면 호스트가 차단된다.

 

그런데 연결 성공하면 SUM_CONNECT_ERRORS가 0으로 초기화 되었다.

찾아보니까 항상 초기화되지는 않는다고 한다. 

 

 

 

결론

연속해서 많은 TCP 연결을 시도하지 않도록 주의해야 하고,

필요한 경우 max_connect_errors 값을 크게 설정하면 되지만,

 

mysql에 TCP 연결은 웬만하면 하지 말 것..

 

 

 

 

참고