max_connections 제한에 도달하지 않았는데도 Amazon RDS for PostgreSQL에 연결할 때 “FATAL: remaining connection slots are reserved for non replicate superuser connections”(나머지 연결 슬롯은 비복제 수퍼유저 연결용으로 예약되어 있음) 오류가 표시되는 이유는 무엇입니까?

4분 분량
0

max_connections 제한에 도달하지 않았는데도 Amazon Relational Database Service(RDS) for PostgreSQL에 연결할 때 “FATAL: remaining connection slots are reserved for non replicate superuser connections”(나머지 연결 슬롯은 비복제 수퍼유저 연결용으로 예약되어 있음) 오류가 표시됩니다.

간략한 설명

Amazon RDS for PostgreSQL에서 수퍼유저가 아닌 사용자에게 사용 가능한 실제 최대 연결 수는 다음과 같이 계산됩니다.

max_connections - superuser_reserved_connections - rds.rds_superuser_reserved_connections.

superuser_reserved_connections의 기본값은 3이고 rds.rds_superuser_reserved_connections의 기본값은 2입니다.

예를 들어, max_connections 값을 100으로 설정하면 수퍼유저가 아닌 사용자가 사용할 수 있는 실제 연결 수는 다음과 같이 계산됩니다.

100-3-2=95.

Amazon CloudWatch 지표 DatabaseConnections는 운영 체제 수준에서 데이터베이스 인스턴스에 대한 클라이언트 네트워크 연결 수를 나타냅니다. 이 지표는 포트 5432에서 인스턴스에 대한 실제 TCP 연결 수를 측정하여 계산됩니다. 이 지표 값에 다음이 포함되지 않으므로 데이터베이스 세션 수가 이 지표 값보다 클 수 있습니다.

  • 더 이상 네트워크에 연결되어 있지 않지만 데이터베이스가 정리하지 않는 백엔드 프로세스 (예: 네트워크 문제로 인해 연결이 종료되었지만 데이터베이스는 클라이언트에게 출력 반환 시도를 하기 전까지는 해당 사항을 인식하지 못합니다.)
  • 데이터베이스 엔진 작업 스케줄러에 의해 생성된 백엔드 프로세스입니다. (예: pg_cron)
  • Amazon RDS 연결.

이 오류는 RDS for PostgreSQL 인스턴스에 연결하는 애플리케이션이 갑자기 연결을 생성하고 끊기 때문에 발생할 수 있습니다. 이로 인해 일정 시간 동안 백엔드 연결이 계속 열려 있을 수 있습니다. 이 상태로 인해 pg_stat_activity 뷰의 값과 CloudWatch 지표 DatabaseConnections 간에 불일치가 발생할 수 있습니다.

해결 방법

오류 문제 해결

이 오류 문제를 해결하려면 다음과 같은 확인을 수행합니다.

  • CloudWatch 지표 DatabaseConnections를 검토합니다.
  • 성능 개선 도우미를 사용하여 numbackends 카운터 지표를 봅니다. 이 값은 오류가 발생한 시점의 연결 수에 대한 정보를 제공합니다. 성능 개선 도우미를 켜지 않은 경우 인스턴스에 기본 사용자로 로그인하세요. 그런 다음, 다음 쿼리를 실행하여 백엔드 개수를 확인합니다.
SELECT count(*) FROM pg_stat_activity;

종료될 수 있는 유휴 연결을 발견하면 pg_terminate_backend() 함수를 사용하여 이러한 백엔드를 종료할 수 있습니다. 다음 쿼리를 실행하여 종료하려는 모든 유휴 연결을 볼 수 있습니다. 이 쿼리는 15분 이상 '유휴', '트랜잭션 유휴', '트랜잭션 유휴(중단됨)’ 및 '비활성화됨' 상태 중 하나인 백엔드 프로세스에 대한 정보를 표시합니다.

SELECT * FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled')
AND state_change < current_timestamp - INTERVAL '15' MINUTE;

참고: 사용 사례에 따라 쿼리를 업데이트해야 합니다.

반드시 종료해야 하는 모든 백엔드 프로세스를 식별한 후 다음 쿼리를 실행하여 해당 프로세스를 종료합니다.

참고: 이 예제 쿼리는 15분 이상 위와 같은 상태를 유지하는 모든 백엔드 프로세스를 종료합니다.

SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled')
AND state_change < current_timestamp - INTERVAL '15' MINUTE
AND usename != 'rdsadmin';

유휴 상태의 모든 백엔드 프로세스를 종료하려면 다음 쿼리를 실행합니다.

SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled')
AND usename != 'rdsadmin';

참고: rdsadmin으로 생성된 백엔드 프로세스는 종료할 수 없습니다. 따라서 종료에서 제외해야 합니다.

중요: rds_superuser 권한으로 RDS for PostgreSQL 인스턴스에 연결할 수 없는 경우 애플리케이션을 정상적으로 종료하여 일부 연결을 해제합니다.

데이터베이스 연결 수 관리

연결 풀링 사용

대부분의 경우 RDS 프록시 또는 서드 파티 연결 풀러와 같은 연결 풀러를 사용하여 지정된 시간에 열려 있는 연결 수를 관리할 수 있습니다. 예를 들어 RDS for PostgreSQL 인스턴스의 max_connections 값을 500으로 설정한 경우 최대 400개의 연결로 구성된 연결 풀러를 사용하여 max_connection과 관련된 오류를 방지할 수 있습니다.

max_connections 값 늘리기

사용 사례에 따라 max_connections의 값을 늘리는 것을 고려할 수 있습니다. 그러나 max_connections에 대해 너무 높은 값을 설정하면 데이터베이스 인스턴스의 워크로드 및 인스턴스 클래스에 따라 메모리 문제가 발생할 수 있습니다.

참고: max_connections의 값을 늘리는 경우 변경 사항을 적용하려면 인스턴스를 재부팅해야 합니다.

유휴 연결 종료

idle_in_transaction_session_timeout 파라미터를 사용 사례에 적합한 값으로 설정할 수 있습니다. 열린 트랜잭션 내에서 이 파라미터에 지정된 시간보다 오래 유휴 상태인 모든 세션이 종료됩니다. 예를 들어 이 파라미터를 10분으로 설정하면 트랜잭션에서 10분 이상 유휴 상태인 쿼리가 종료됩니다. 이 파라미터는 이 특정 상태에서 중단된 연결을 관리하는 데 도움이 됩니다.

PostgreSQL 버전 14 이상의 경우 idle_session_timeout 파라미터를 사용할 수 있습니다. 이 파라미터를 설정하면 지정된 시간 이상 유휴 상태이지만 열린 트랜잭션 내에서는 그렇지 않은 모든 세션이 종료됩니다.

PostgreSQL 버전 14 이상의 경우 client_connection_check_interval 파라미터를 사용할 수 있습니다. 이 파라미터를 사용하면 쿼리를 실행할 때 클라이언트 연결에 대한 선택적 검사 사이의 시간 간격을 설정할 수 있습니다. 이 검사는 소켓을 폴링하여 수행됩니다. 이 검사를 사용하면 커널이 연결 닫힘을 보고할 경우 오래 실행되는 쿼리가 더 빨리 종료될 수 있습니다. 이 파라미터는 PostgreSQL이 백엔드 프로세스와의 연결 끊김에 대해 알지 못하는 경우에 유용합니다.

rds.rds_superuser_reserved_connections 값 늘리기

rds.rds_superuser_reserved_connections 파라미터의 값을 늘리는 것을 고려할 수 있습니다. 이 파라미터의 기본값은 2로 설정됩니다. 이 파라미터의 값을 늘리면 rds_superuser 역할이 연결된 사용자로부터 더 많은 연결이 허용됩니다. 이 역할을 통해 사용자는 pg_terminate_backend() 명령을 사용하여 유휴 연결을 종료하는 등의 관리 작업을 실행할 수 있습니다.