PostgreSQL 58000 오류 원인과 해결 방법 완벽 가이드

58000
2026년 07월 20일 | DBMS Error 가이드

이 글에서 다루는 내용

58000 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

58000 system error 는?

PostgreSQL 에러 코드 58000은 system error로, 데이터베이스 서버가 운영체제 수준의 시스템 호출(system call)에서 예기치 않은 오류를 만났을 때 발생합니다. 이 에러는 PostgreSQL 내부 로직의 문제가 아니라, 파일 시스템, 메모리, 네트워크, 디스크 I/O 등 외부 환경에서 비롯된 저수준 오류를 의미합니다. 일반적으로 서버 로그에는 ERROR: could not read file, could not write to file, 또는 out of memory 같은 구체적인 시스템 메시지가 함께 출력되므로, 해당 메시지를 반드시 확인해야 합니다.


주요 발생 원인

1. 디스크 공간 부족 또는 파일 시스템 오류

PostgreSQL은 WAL(Write-Ahead Log), 임시 파일, 테이블스페이스 등 다양한 파일을 지속적으로 읽고 씁니다. 디스크가 가득 차거나 파일 시스템에 불량 섹터(bad sector)가 발생하면, OS 레벨의 write() 또는 read() 시스템 콜이 실패하여 58000 에러가 트리거됩니다. 특히 대용량 배치 작업이나 VACUUM 도중 디스크가 가득 차는 경우가 실무에서 가장 빈번하게 발생합니다.

2. 운영체제 메모리 부족 (OOM)

PostgreSQL 프로세스가 shared_buffers, work_mem, maintenance_work_mem 등의 메모리를 과도하게 사용하거나, 서버 전체의 메모리가 부족해지면 Linux OOM Killer가 PostgreSQL 백엔드 프로세스를 강제 종료할 수 있습니다. 이때 갑작스러운 프로세스 종료로 인해 진행 중이던 쿼리나 트랜잭션이 58000 에러를 발생시킵니다. /var/log/syslog 또는 dmesg 명령으로 OOM 킬 이벤트를 확인할 수 있습니다.

3. 파일 디스크립터(File Descriptor) 한도 초과

운영체제는 프로세스당 열 수 있는 파일의 수를 제한합니다. 많은 연결(connection)이 동시에 활성화되어 있거나, 다수의 파티션 테이블, 대형 인덱스를 사용할 경우 파일 디스크립터가 고갈될 수 있습니다. 이 경우 PostgreSQL이 새로운 파일을 열지 못해 시스템 오류가 발생하며, SHOW max_connections; 및 OS의 ulimit -n 값을 점검해야 합니다.


해결 방법

원인 1: 디스크 공간 부족 해결

우선 PostgreSQL 데이터 디렉터리의 디스크 사용량을 확인합니다.

-- PostgreSQL 내에서 데이터베이스별 크기 확인
SELECT
    datname AS database_name,
    pg_size_pretty(pg_database_size(datname)) AS db_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;

-- 불필요한 임시 테이블 정리
DROP TABLE IF EXISTS temp_staging_data;

-- 비대해진 테이블 VACUUM으로 공간 회수
VACUUM FULL ANALYZE your_large_table;

OS 레벨에서도 디스크 사용량을 점검하고, 오래된 로그 파일 및 아카이브 WAL을 정리합니다.

-- pg_waldump를 통해 WAL 사용 현황 확인 (psql 외부에서)
-- SELECT * FROM pg_ls_waldir() ORDER BY modification DESC LIMIT 20;

-- 오래된 아카이브 WAL 확인
SELECT * FROM pg_ls_archive_statusdir();

원인 2: 메모리 부족 해결

메모리 설정을 점검하고 적절히 조정합니다.

-- 현재 메모리 관련 설정값 확인
SHOW shared_buffers;
SHOW work_mem;
SHOW maintenance_work_mem;

-- 현재 활성 세션과 메모리 사용 상황 확인
SELECT
    pid,
    usename,
    application_name,
    state,
    query_start,
    left(query, 80) AS query_snippet
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY query_start;

-- work_mem을 세션 레벨에서 임시 조정 (대용량 쿼리 실행 전)
SET work_mem = '64MB';

-- 설정 파일에서 전역 조정 (postgresql.conf)
-- shared_buffers = '4GB'         -- 전체 RAM의 25% 권장
-- work_mem = '32MB'              -- 연결 수 * 쿼리 복잡도 고려
-- maintenance_work_mem = '512MB'

원인 3: 파일 디스크립터 한도 초과 해결

-- PostgreSQL이 현재 열고 있는 파일 수 확인
SELECT count(*) FROM pg_stat_file('pg_wal');  -- 간접 확인

-- 현재 연결 수 및 최대 연결 수 확인
SELECT
    count(*) AS current_connections,
    (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_connections,
    (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') - count(*) AS available_connections
FROM pg_stat_activity;

-- 불필요한 유휴 연결 강제 종료
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
  AND query_start < now() - interval '1 hour'
  AND pid != pg_backend_pid();

OS 레벨에서 파일 디스크립터 한도를 늘립니다.

# /etc/security/limits.conf 에 추가
# postgres  soft  nofile  65536
# postgres  hard  nofile  65536

# 현재 postgres 프로세스의 fd 한도 확인 (bash)
# cat /proc/$(pgrep -u postgres postmaster)/limits | grep "open files"

예방 방법

1. 디스크 및 시스템 리소스 모니터링 자동화

디스크 사용률이 80%를 초과하면 즉시 알림을 받을 수 있는 모니터링 체계를 구축해야 합니다. Prometheus + pg_exporter 조합이나 Zabbix, Datadog 같은 도구를 활용하여 디스크 I/O, 메모리 사용률, 파일 디스크립터 수를 실시간으로 추적하세요. 아래 쿼리를 cron 또는 모니터링 도구에 등록하여 주기적으로 점검하는 것을 권장합니다.

-- 디스크 여유 공간 부족 징후 조기 감지 (pg_tablespace 기준)
SELECT
    spcname AS tablespace_name,
    pg_tablespace_location(oid) AS location,
    pg_size_pretty(pg_tablespace_size(oid)) AS size
FROM pg_tablespace
WHERE pg_tablespace_location(oid) != '';

2. Connection Pooling 및 리소스 제한 설정

PgBouncer와 같은 커넥션 풀러를 도입하여 실제 PostgreSQL 백엔드 연결 수를 최소화해야 합니다. 또한 postgresql.conf에서 max_connections를 실제 필요한 수준으로 제한하고, 역할(role)별로 CONNECTION LIMIT를 설정해 특정 사용자가 연결을 독점하지 못하도록 제어하세요.

-- 특정 사용자의 연결 수 제한 설정
ALTER ROLE reporting_user CONNECTION LIMIT 10;

-- 연결 제한 확인
SELECT rolname, rolconnlimit FROM pg_roles WHERE rolconnlimit != -1;

관련 에러

  • 53100 (disk_full): 디스크가 완전히 가득 찬 경우 발생하며, 58000보다 더 구체적인 디스크 관련 에러입니다.
  • 53200 (out_of_memory): 메모리 할당 실패 시 발생하는 에러로, 58000과 함께 로그에 나타나는 경우가 많습니다.
  • 58030 (io_error): 파일 I/O 작업 중 발생하는 에러로, 58000의 하위 분류에 해당합니다. 디스크 불량이나 NFS 마운트 문제 시 자주 목격됩니다.
  • 57P01 (admin_shutdown) / 57P02 (crash_shutdown): 서버 비정상 종료 시 발생하며, OOM Killer에 의한 58000 이후 재시작 과정에서 연쇄적으로 나타날 수 있습니다.
DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기