2026년 07월 15일 | DBMS Error 가이드
이 글에서 다루는 내용
53000 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
53000 insufficient resources 는?
PostgreSQL 에러 코드 53000 insufficient resources는 데이터베이스 서버가 쿼리나 작업을 수행하는 데 필요한 시스템 자원(메모리, 파일 디스크립터, 프로세스 슬롯 등)이 부족할 때 발생하는 에러입니다. 이 에러는 53000 계열의 상위 카테고리 에러로, 실제 현장에서는 53100 disk_full, 53200 out_of_memory, 53300 too_many_connections 같은 더 구체적인 하위 에러로 자주 나타납니다. 갑작스러운 트래픽 폭증, 잘못된 서버 설정, 또는 장기간 방치된 리소스 누수가 주요 원인이며, 방치할 경우 서비스 전체 중단으로 이어질 수 있어 즉각적인 대응이 필요합니다.
주요 발생 원인
1. 커넥션 수 초과 (Too Many Connections)
PostgreSQL은 max_connections 파라미터로 동시 접속 수를 제한합니다. 애플리케이션에서 커넥션 풀링 없이 무분별하게 연결을 생성하거나, 장기 미사용 커넥션이 반환되지 않고 쌓이면 허용된 슬롯을 모두 소진하게 됩니다. 이 상태가 되면 신규 연결 시도 자체가 실패하며 53300 too_many_connections 에러와 함께 53000이 트리거됩니다.
2. 디스크 공간 부족 (Disk Full)
테이블스페이스가 위치한 디스크의 여유 공간이 0에 가까워지면 WAL(Write-Ahead Log) 파일 쓰기, 임시 파일 생성, Vacuum 작업 등 거의 모든 쓰기 작업이 불가능해집니다. 특히 대용량 COPY 작업, 인덱스 재생성, 또는 통제되지 않은 테이블 팽창(table bloat)이 주된 원인이 됩니다. 디스크가 꽉 차면 데이터베이스는 읽기 전용 상태로 전환되거나 완전히 응답 불능 상태에 빠질 수 있습니다.
3. 메모리 부족 (Out of Memory)
PostgreSQL 서버 프로세스나 OS 레벨에서 사용 가능한 메모리가 소진되면 쿼리 실행 중 메모리 할당에 실패하게 됩니다. work_mem 설정이 과도하게 높거나, 복잡한 정렬·해시 조인을 동시에 많이 실행할 때 각 프로세스가 대량의 메모리를 점유하여 OS의 OOM Killer가 PostgreSQL 프로세스를 강제 종료하는 상황이 발생합니다. 메모리 부족은 53200 out_of_memory 에러와 함께 나타나며 서버 크래시로 이어질 수 있어 가장 위험한 원인 중 하나입니다.
해결 방법
1. 커넥션 수 초과 해결
현재 커넥션 상태를 먼저 확인한 후, 유휴 커넥션을 정리하고 설정을 조정합니다.
-- 현재 커넥션 수 및 상태 확인
SELECT state, count(*) AS connection_count
FROM pg_stat_activity
GROUP BY state
ORDER BY connection_count DESC;
-- max_connections 현재 설정값 확인
SHOW max_connections;
-- 오래된 유휴 커넥션 강제 종료 (idle 상태 30분 초과)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND state_change < NOW() - INTERVAL '30 minutes'
AND pid <> pg_backend_pid();
-- 특정 사용자의 max 커넥션 수 제한 설정
ALTER ROLE app_user CONNECTION LIMIT 50;
-- postgresql.conf 에서 max_connections 조정 (재시작 필요)
-- max_connections = 200 → 필요시 증가
-- 단, PgBouncer 같은 커넥션 풀러 도입을 강력 권장
> 실무 팁: 커넥션 수를 무한정 늘리는 것은 해결책이 아닙니다. 반드시 PgBouncer 또는 pgpool-II 같은 커넥션 풀러를 도입하세요.
2. 디스크 공간 부족 해결
-- 데이터베이스별 크기 확인
SELECT datname,
pg_size_pretty(pg_database_size(datname)) AS size
FROM pg_database
ORDER BY pg_database_size(datname) DESC;
-- 가장 큰 테이블 확인 (상위 10개)
SELECT schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS total_size
FROM pg_tables
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC
LIMIT 10;
-- 테이블 bloat 확인 및 VACUUM으로 공간 회수
VACUUM FULL ANALYZE schema_name.table_name;
-- 불필요한 오래된 파티션 또는 아카이브 테이블 삭제
DROP TABLE IF EXISTS archive.logs_2021;
-- 임시 파일 점유 확인 (pg_temp 스키마)
SELECT pg_size_pretty(sum(size)) AS temp_file_size
FROM pg_catalog.pg_ls_tmpdir();
-- WAL 아카이브 디렉토리 확인 후 오래된 WAL 정리
-- (archive_cleanup_command 설정 또는 수동 삭제)
SELECT pg_walfile_name(pg_current_wal_lsn());
3. 메모리 부족 해결
-- 현재 메모리 관련 설정 확인
SHOW work_mem;
SHOW shared_buffers;
SHOW maintenance_work_mem;
-- 세션별 메모리 사용이 높은 쿼리 확인
SELECT pid,
usename,
application_name,
state,
query,
now() - query_start AS duration
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY duration DESC
LIMIT 10;
-- work_mem 세션 레벨에서 임시 축소 (대용량 정렬 쿼리 전)
SET work_mem = '64MB';
-- 메모리 집약적인 쿼리에 대한 실행 계획 확인
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT *
FROM large_table
ORDER BY created_at DESC
LIMIT 1000;
-- shared_buffers 및 work_mem 조정 예시 (postgresql.conf)
-- shared_buffers = '4GB' -- 전체 RAM의 25% 권장
-- work_mem = '64MB' -- 너무 높게 설정 금지
-- maintenance_work_mem = '512MB' -- VACUUM, 인덱스 생성용
예방 방법
1. 모니터링 및 알림 시스템 구축
리소스 고갈은 예고 없이 찾아오지 않습니다. 반드시 Prometheus + pg_exporter 또는 Datadog, Zabbix 같은 도구로 다음 지표를 실시간 모니터링하고 임계값 초과 시 즉시 알림을 받도록 설정하세요. 커넥션 사용률이 80% 초과 시, 디스크 사용률이 70% 초과 시, 메모리 사용률이 85% 초과 시 경고 알림을 설정하는 것이 실무 표준입니다.
-- 커넥션 사용률 모니터링 쿼리 (Cron 또는 모니터링 툴에서 주기적 실행)
SELECT
max_conn,
used_conn,
ROUND(used_conn::numeric / max_conn * 100, 2) AS usage_pct
FROM
(SELECT setting::int AS max_conn FROM pg_settings WHERE name = 'max_connections') mc,
(SELECT count(*) AS used_conn FROM pg_stat_activity) uc;
2. 정기적인 Autovacuum 튜닝 및 유지보수 스케줄링
테이블 bloat와 디스크 낭비를 예방하기 위해 Autovacuum 설정을 워크로드에 맞게 튜닝하고, 정기 유지보수 작업을 스케줄링하세요. 특히 쓰기 작업이 많은 테이블은 autovacuum_vacuum_scale_factor를 낮게 설정하여 더 자주 Vacuum이 실행되도록 해야 합니다.
-- 특정 테이블에 autovacuum 공격적 설정 적용
ALTER TABLE high_write_table SET (
autovacuum_vacuum_scale_factor = 0.01,
autovacuum_analyze_scale_factor = 0.005,
autovacuum_vacuum_cost_delay = 2
);
-- autovacuum 실행 현황 확인
SELECT schemaname,
tablename,
last_autovacuum,
last_autoanalyze,
n_dead_tup,
n_live_tup
FROM pg_stat_user_tables
WHERE n_dead_tup > 10000
ORDER BY n_dead_tup DESC;
관련 에러
| 에러 코드 | 에러명 | 설명 |
|—|—|—|
| 53100 | disk_full | 디스크 공간이 완전히 소진된 경우 |
| 53200 | out_of_memory | 서버 메모리 할당 실패 |
| 53300 | too_many_connections | max_connections 한계 초과 |
| 53400 | configuration_limit_exceeded | 설정된 자원 한계 초과 |
| 57P03 | cannot_connect_now | 서버 시작 중 또는 복구 중으로 접속 불가 |
53000은 이 모든 하위 에러들의 상위 카테고리이므로, 실제 운영 환경에서 이 에러를 마주쳤다면 PostgreSQL 로그(pg_log)에서 더 구체적인 하위 에러 메시지를 반드시 확인하여 정확한 원인을 파악해야 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.