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

53100
2026년 07월 15일 | DBMS Error 가이드

이 글에서 다루는 내용

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

53100 disk full 는?

PostgreSQL 에러 코드 53100 disk full은 데이터베이스 서버가 데이터를 디스크에 기록하려 할 때 저장 공간이 부족하여 작업을 완료할 수 없을 때 발생합니다. 이 에러는 테이블 데이터 저장, WAL(Write-Ahead Log) 기록, 임시 파일 생성 등 디스크 쓰기가 필요한 모든 상황에서 나타날 수 있으며, 발생 즉시 해당 트랜잭션이 롤백되고 심각한 경우 데이터베이스 전체가 중단될 수 있습니다. 특히 운영 환경에서 예고 없이 발생하면 서비스 장애로 직결되기 때문에 DBA라면 반드시 사전에 모니터링 체계를 갖추고 있어야 하는 치명적인 에러입니다.


주요 발생 원인

1. WAL(Write-Ahead Log) 파일의 과도한 누적

PostgreSQL은 데이터 무결성을 위해 모든 변경 사항을 WAL 파일에 먼저 기록합니다. 아카이빙이 활성화된 환경에서 아카이브 프로세스가 지연되거나 실패하면 pg_wal 디렉토리에 WAL 세그먼트 파일이 무한정 쌓이게 됩니다. 또한 wal_keep_size 설정값이 과도하게 크거나 레플리케이션 슬롯이 소비되지 않은 채 방치될 경우 수십 GB의 WAL 파일이 디스크를 가득 채울 수 있습니다.

2. 테이블 및 인덱스의 무분별한 팽창(Bloat)

대량의 UPDATE 또는 DELETE 작업이 반복되면 PostgreSQL의 MVCC 특성상 죽은 튜플(dead tuple)이 물리적으로 제거되지 않고 테이블과 인덱스 파일 내에 계속 누적됩니다. VACUUM 작업이 제때 실행되지 않거나 autovacuum이 비활성화된 경우, 또는 장시간 실행되는 트랜잭션이 VACUUM의 정리 작업을 막고 있는 경우에 테이블 bloat이 심각해집니다. 실제로 수백 MB여야 할 테이블이 수십 GB로 팽창하는 사례는 운영 현장에서 매우 흔하게 발생합니다.

3. 임시 파일(Temporary File)의 과도한 생성

복잡한 쿼리(대형 정렬, 해시 조인, 집계 연산 등)를 처리할 때 work_mem이 부족하면 PostgreSQL은 연산의 중간 결과를 디스크의 임시 파일(pgsql_tmp)에 기록합니다. 다수의 세션이 동시에 이러한 쿼리를 실행하면 임시 파일이 폭발적으로 증가하여 단시간에 수십 GB의 공간을 소진할 수 있습니다. 특히 배치 작업이나 데이터 분석 쿼리가 집중되는 시간대에 이 문제가 빈번하게 발생합니다.


해결 방법

원인 1: WAL 파일 누적 해결

먼저 현재 WAL 디렉토리 크기와 레플리케이션 슬롯 상태를 확인합니다.

-- WAL 디렉토리 크기 확인 (pg_wal 경로)
SELECT pg_size_pretty(sum(size)) AS wal_size
FROM pg_ls_waldir();

-- 레플리케이션 슬롯 상태 확인 (inactive 슬롯 위험)
SELECT slot_name, active, restart_lsn,
       pg_size_pretty(
           pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)
       ) AS retained_wal_size
FROM pg_replication_slots;

-- 사용하지 않는 레플리케이션 슬롯 삭제 (신중하게 실행)
SELECT pg_drop_replication_slot('사용안하는_슬롯명');

-- 아카이브 실패 시 강제로 WAL 체크포인트 수행
CHECKPOINT;

원인 2: 테이블 Bloat 해결

현재 가장 bloat이 심한 테이블을 찾아 VACUUM 또는 재구성 작업을 수행합니다.

-- 테이블별 dead tuple 현황 확인
SELECT schemaname,
       relname AS table_name,
       n_dead_tup,
       n_live_tup,
       round(n_dead_tup::numeric / nullif(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_ratio_pct,
       pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
       last_autovacuum,
       last_vacuum
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 20;

-- 특정 테이블 즉시 VACUUM FULL (테이블 잠금 발생 주의)
VACUUM FULL VERBOSE public.your_bloated_table;

-- 잠금 없이 재구성하려면 pg_repack 확장 사용 권장
-- pg_repack -t public.your_bloated_table -d your_database

-- autovacuum 임계값 조정 (특정 테이블에만 적용)
ALTER TABLE public.your_bloated_table
SET (autovacuum_vacuum_scale_factor = 0.01,
     autovacuum_vacuum_threshold = 100);

원인 3: 임시 파일 정리 및 방지

현재 임시 파일 사용 현황을 확인하고 work_mem을 적절히 조정합니다.

-- 임시 파일 사용량이 많은 쿼리 확인 (pg_stat_statements 필요)
SELECT query,
       calls,
       temp_blks_written,
       pg_size_pretty(temp_blks_written * 8192) AS temp_size_written
FROM pg_stat_statements
WHERE temp_blks_written > 0
ORDER BY temp_blks_written DESC
LIMIT 10;

-- 현재 세션별 임시 파일 현황
SELECT pid, query, state,
       (SELECT pg_size_pretty(sum(size))
        FROM pg_ls_tmpdir()
        WHERE name LIKE 'pgsql_tmp%') AS tmp_size
FROM pg_stat_activity
WHERE state = 'active';

-- 특정 세션에만 work_mem 늘려 임시 파일 최소화
SET work_mem = '256MB';

-- 문제 세션 강제 종료 (긴급 시)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'active'
  AND query_start < now() - interval '1 hour';

긴급 디스크 공간 확보

-- 불필요한 오래된 로그 파일 확인 후 삭제 (OS 레벨에서 수행)
-- 아래는 pg_log 디렉토리 파일 목록 확인용
SELECT name, modification, size
FROM pg_ls_logdir()
ORDER BY modification ASC
LIMIT 20;

-- 완료된 오래된 WAL 아카이브 파일 제거를 위한 pg_archivecleanup 활용 예시
-- (OS 쉘에서: pg_archivecleanup /mnt/archive 000000010000000A00000001)

예방 방법

1. 디스크 사용량 실시간 모니터링 및 알림 설정

디스크 사용률이 70%를 넘으면 경고, 85%를 넘으면 긴급 알림이 발송되도록 모니터링 시스템(Prometheus + node_exporter, Zabbix, Datadog 등)을 반드시 구성해야 합니다. PostgreSQL 내부에서도 아래 쿼리를 cron 또는 pg_cron으로 주기적으로 실행하여 테이블 bloat, WAL 크기, 임시 파일 사용량을 선제적으로 추적하는 습관을 들이십시오.

-- 주요 지표를 한 번에 확인하는 헬스체크 쿼리
SELECT
    (SELECT pg_size_pretty(sum(size)) FROM pg_ls_waldir()) AS wal_dir_size,
    (SELECT count(*) FROM pg_replication_slots WHERE NOT active) AS inactive_slots,
    (SELECT pg_size_pretty(pg_database_size(current_database()))) AS db_size,
    (SELECT sum(n_dead_tup) FROM pg_stat_user_tables) AS total_dead_tuples;

2. autovacuum 튜닝 및 정기적 유지보수 스케줄 운영

기본 autovacuum 설정은 소규모 데이터베이스에 맞게 보수적으로 설정되어 있어 대용량 환경에서는 충분하지 않습니다. postgresql.conf에서 autovacuum_vacuum_cost_delay를 낮추고, autovacuum_max_workers를 늘려 autovacuum이 더 적극적으로 동작하도록 설정하십시오. 또한 매주 업무 시간 외에 ANALYZEVACUUM을 수동으로 실행하는 유지보수 윈도우를 운영 계획에 반드시 포함시켜야 합니다.

-- autovacuum 적극적 설정 예시 (postgresql.conf 또는 ALTER SYSTEM)
ALTER SYSTEM SET autovacuum_vacuum_cost_delay = '2ms';
ALTER SYSTEM SET autovacuum_max_workers = 5;
ALTER SYSTEM SET autovacuum_vacuum_scale_factor = 0.02;
SELECT pg_reload_conf();

관련 에러

  • 53200 out_of_memory: 메모리 부족으로 인한 에러로, 53100과 함께 리소스 부족 클래스(53xxx)에 속합니다. 디스크 스왑 공간 부족 시 함께 발생하는 경우가 있습니다.
  • 58030 io_error: 디스크 풀 직후 I/O 오류로 이어지는 경우가 많으며, 파일시스템 손상을 의심해야 합니다.
  • 54011 too_many_columns54023 too_many_arguments: 직접적인 연관은 없지만 같은 리소스 한계 클래스로 분류됩니다.
  • XX000 internal_error: 디스크 풀로 인해 내부 임시 파일 생성이 실패할 때 이 에러가 동반되기도 합니다.
DBMS 에러 코드 시리즈

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

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

댓글 남기기