2026년 05월 31일 | DBMS Error 가이드
이 글에서 다루는 내용
08004 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
08004 sqlserver rejected establishment of sqlconnection 는?
PostgreSQL 에러 코드 08004는 서버가 클라이언트의 연결 요청을 명시적으로 거부(reject) 했을 때 발생하는 연결 실패 에러입니다. 이 에러는 네트워크 레벨에서의 단순 연결 불가와는 다르게, PostgreSQL 서버가 요청을 수신하긴 했지만 인증, 권한, 또는 설정상의 이유로 의도적으로 거절한 상황을 의미합니다. 주로 pg_hba.conf 설정 오류, 데이터베이스 접근 권한 문제, 또는 최대 연결 수 초과 등의 상황에서 애플리케이션 서버나 DBA가 접속을 시도할 때 마주치게 됩니다.
주요 발생 원인
1. pg_hba.conf 설정에 의한 연결 거부
PostgreSQL은 클라이언트 인증을 pg_hba.conf 파일로 제어하며, 이 파일에 해당 클라이언트 IP, 사용자, 데이터베이스 조합이 허용되어 있지 않으면 서버는 연결을 즉시 거부합니다. 예를 들어 애플리케이션 서버의 IP가 화이트리스트에 없거나, 인증 방법이 reject로 명시되어 있는 경우가 대표적입니다. 실무에서 가장 빈번하게 발생하는 원인이며, 특히 서버 이전이나 신규 배포 환경 구성 시 놓치기 쉽습니다.
2. 데이터베이스 또는 사용자 레벨의 접근 권한 부재
PostgreSQL 서버 자체에 접근이 허용되더라도, 특정 데이터베이스에 대한 CONNECT 권한이 없거나 해당 사용자 계정이 비활성화(LOGIN 권한 없음)된 경우 연결이 거부됩니다. 이는 보안 정책 강화 이후 계정 정리 작업, 또는 신규 사용자 생성 시 권한 부여 절차를 누락했을 때 자주 발생합니다. pg_hba.conf는 통과하지만 PostgreSQL 내부 권한 체계에서 막히는 경우이므로 에러 메시지만 보고 원인을 혼동하는 경우가 많습니다.
3. 최대 연결 수(max_connections) 초과
postgresql.conf의 max_connections 파라미터에 도달하면 서버는 더 이상 새로운 연결을 받지 않고 거부합니다. 특히 슈퍼유저 전용으로 예약된 superuser_reserved_connections 슬롯을 제외한 일반 연결 슬롯이 모두 소진된 경우, 일반 사용자는 연결 자체가 불가능해집니다. 커넥션 풀링 없이 직접 연결을 사용하는 레거시 애플리케이션 환경이나 트래픽 급증 상황에서 특히 자주 발생합니다.
해결 방법
원인 1: pg_hba.conf 설정 수정
현재 pg_hba.conf 내용을 확인하고 적절한 접근 규칙을 추가해야 합니다.
-- 현재 pg_hba.conf 경로 확인
SHOW hba_file;
-- 현재 적용된 pg_hba 규칙 조회 (PostgreSQL 10 이상)
SELECT type, database, user_name, address, auth_method
FROM pg_hba_file_rules;
pg_hba.conf 파일에 아래와 같이 규칙을 추가합니다 (파일 직접 편집 필요):
-- pg_hba.conf 예시 (파일 편집 후 아래 명령으로 리로드)
-- TYPE DATABASE USER ADDRESS METHOD
-- host mydb myapp_user 192.168.1.100/32 scram-sha-256
-- host all all 10.0.0.0/8 scram-sha-256
파일 편집 후 서버 재시작 없이 반영하려면:
-- pg_hba.conf 변경사항 서버 재시작 없이 반영
SELECT pg_reload_conf();
-- 반영 결과 확인
SELECT * FROM pg_hba_file_rules WHERE error IS NOT NULL;
원인 2: 사용자 및 데이터베이스 권한 부여
-- 사용자 LOGIN 권한 확인
SELECT usename, usesuper, usecreatedb, usecreaterole, valuntil
FROM pg_user
WHERE usename = 'myapp_user';
-- 사용자에게 LOGIN 권한 부여
ALTER USER myapp_user WITH LOGIN;
-- 비밀번호 만료 여부 확인 및 재설정
ALTER USER myapp_user WITH PASSWORD 'new_secure_password' VALID UNTIL 'infinity';
-- 특정 데이터베이스에 대한 CONNECT 권한 확인
SELECT has_database_privilege('myapp_user', 'mydb', 'CONNECT');
-- CONNECT 권한 부여
GRANT CONNECT ON DATABASE mydb TO myapp_user;
-- 스키마 사용 권한 추가 부여
GRANT USAGE ON SCHEMA public TO myapp_user;
-- 필요시 기본 권한 설정
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO myapp_user;
원인 3: 연결 수 초과 진단 및 해결
-- 현재 연결 수 및 최대 연결 수 확인
SELECT
current_setting('max_connections')::int AS max_connections,
current_setting('superuser_reserved_connections')::int AS reserved,
COUNT(*) AS current_connections,
current_setting('max_connections')::int
- current_setting('superuser_reserved_connections')::int
- COUNT(*) AS available_slots
FROM pg_stat_activity;
-- 연결 상태별 상세 조회
SELECT
state,
wait_event_type,
wait_event,
COUNT(*) AS connection_count,
MAX(EXTRACT(EPOCH FROM (now() - state_change))) AS max_idle_seconds
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
GROUP BY state, wait_event_type, wait_event
ORDER BY connection_count DESC;
-- 유휴 상태가 오래된 연결 강제 종료 (idle 상태 10분 이상)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND state_change < NOW() - INTERVAL '10 minutes'
AND usename != 'postgres';
-- max_connections 임시 상향 (슈퍼유저만 가능, 재시작 필요)
-- postgresql.conf에서 수정 후 재시작 필요
-- max_connections = 200 → max_connections = 300
ALTER SYSTEM SET max_connections = 300;
-- 이후 pg_ctl restart 필요
예방 방법
1. 커넥션 풀러(PgBouncer) 도입으로 연결 수 관리
애플리케이션에서 PostgreSQL에 직접 연결하는 구조 대신 PgBouncer와 같은 커넥션 풀러를 중간에 배치하면 실제 DB 연결 수를 대폭 줄일 수 있습니다. PgBouncer의 transaction 모드를 사용하면 수천 개의 애플리케이션 연결을 수십 개의 실제 DB 연결로 처리할 수 있어 max_connections 초과 문제를 구조적으로 방지할 수 있습니다. 또한 연결 수 모니터링 알람을 설정하여 max_connections의 80% 도달 시 사전 경고를 받도록 구성하는 것이 권장됩니다.
-- 모니터링용 뷰 생성 (재사용 가능)
CREATE OR REPLACE VIEW v_connection_status AS
SELECT
datname AS database,
usename AS username,
COUNT(*) AS total_connections,
SUM(CASE WHEN state = 'active' THEN 1 ELSE 0 END) AS active,
SUM(CASE WHEN state = 'idle' THEN 1 ELSE 0 END) AS idle,
SUM(CASE WHEN state = 'idle in transaction' THEN 1 ELSE 0 END) AS idle_in_tx
FROM pg_stat_activity
GROUP BY datname, usename
ORDER BY total_connections DESC;
2. pg_hba.conf 변경 이력 관리 및 배포 자동화
pg_hba.conf는 인프라 코드(IaC)로 관리하여 Git과 같은 버전 관리 시스템에서 변경 이력을 추적해야 합니다. Ansible, Terraform 등의 도구로 배포를 자동화하고, 변경 전 반드시 pg_hba_file_rules 뷰를 통해 현재 규칙을 백업한 뒤 검증 절차를 거치는 것을 팀 표준으로 정립해야 합니다. 특히 신규 애플리케이션 배포 체크리스트에 DB 접근 권한 설정 확인 항목을 필수로 포함시키면 운영 중 연결 거부 사고를 크게 줄일 수 있습니다.
관련 에러
08001(sqlclient_unable_to_establish_sqlconnection): 클라이언트가 서버에 아예 도달하지 못한 경우로,08004와 달리 서버 측의 거부가 아닌 네트워크/방화벽 문제가 원인입니다.08006(connection_failure): 연결이 수립된 이후 예기치 않게 끊어진 경우 발생하며,08004는 연결 수립 전 거부라는 점에서 구분됩니다.28000(invalid_authorization_specification): 사용자 이름 자체가 존재하지 않거나 인증 방식이 잘못된 경우로, 권한은 있지만 인증 정보가 틀린28P01과 함께08004와 혼동되기 쉬운 에러입니다.53300(too_many_connections):max_connections초과 시 발생하는 에러로,08004의 원인 중 하나가 이 상태에서 비롯되기도 하므로 함께 확인해야 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.