본문으로 건너뛰기

15.1 일반적인 에러 패턴

PostgreSQL 운영에서 마주치는 에러는 대부분 몇 가지 패턴 안에 들어옵니다. 메시지와 원인, 즉시 대응, 예방 절차를 묶어 정리했습니다.

1. FATAL: sorry, too many clients already​

FATAL: sorry, too many clients already
-- 예약 슬롯까지 찬 경우 (PG 15 이하)
FATAL: remaining connection slots are reserved for non-replication superuser connections
-- PG 16+
FATAL: remaining connection slots are reserved for roles with the SUPERUSER attribute

원인: max_connections 초과

즉시 대응:

-- 가장 idle한 backend 종료
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND now() - state_change > interval '10 min';

예방:

  • pgBouncer 도입 (13.4)
  • application connection leak 점검
  • max_connections은 OS·메모리 한계까지만

2. ERROR: could not extend file ...: No space left on device​

원인: 디스크 풀

즉시 대응:

df -h
# 어떤 디렉토리가 찼나
du -sh /var/lib/pgsql/17/data/{base,pg_wal,log,base/pgsql_tmp}

흔한 후보:

  • pg_wal/ — archive 실패 또는 slot 정체
  • base/pgsql_tmp — 큰 정렬 temp file
  • log/ — 로그 폭증

예방: 디스크 80% 알람, slot 모니터링, log rotation.

3. FATAL: the database system is starting up​

FATAL: the database system is starting up

원인: crash recovery 또는 starting

대응: 기다립니다. pg_stat_activity로 진행 상황을 확인합니다.

SELECT pg_is_in_recovery(), pg_last_wal_replay_lsn();

WAL 재생 길어지면 restartpoint 체크포인트 빈도 확인합니다. 매우 길면 recovery_target 점검합니다.

4. WARNING: archive_command failed​

LOG: archive command failed with exit code 1
DETAIL: The failed archive command was: ...

원인: archive 저장소 접근 실패 (네트워크·권한·full)

즉시 대응: 외부 저장소를 확인하고 archive 경로를 점검합니다.

sudo -u postgres pgbackrest --stanza=main check

pg_wal/ 가득 차기 전에 해결 필수입니다.

예방: pg_stat_archiver.last_failed_time 알람을 받습니다.

5. ERROR: deadlock detected​

ERROR: deadlock detected
DETAIL: Process 1234 waits for ShareLock on transaction 5678; blocked by process ...

원인: 두 트랜잭션이 서로의 락 대기

대응: application 재시도 + 락 순서 일관성(14.4).

-- 데드락 통계 추적
SELECT datname, deadlocks FROM pg_stat_database;

6. canceling statement due to conflict with recovery​

원인: hot standby에서 vacuum cleanup 충돌 (12.3)

대응: application 재시도. 자주 발생하면 max_standby_streaming_delay 또는 hot_standby_feedback.

7. WARNING: there is no transaction in progress​

WARNING: there is no transaction in progress

원인: COMMIT 또는 ROLLBACK을 트랜잭션 없이

대응: application 로직 점검합니다. autocommit 모드 확인합니다.

8. ERROR: current transaction is aborted, commands ignored until end of transaction block​

ERROR: current transaction is aborted

원인: 이전 SQL이 error → 트랜잭션 abort 상태, 추가 SQL은 모두 무시. ROLLBACK 또는 COMMIT 필요

대응:

try:
cur.execute("BAD SQL")
except:
conn.rollback() # 명시

ORM은 자동 ROLLBACK이 일반적이지만 raw connection은 아님.

9. OperationalError: server closed the connection unexpectedly​

원인: 서버 측 backend가 종료 — crash, OOM, idle timeout, pg_terminate_backend

대응:

  • PostgreSQL 로그에서 종료 원인 확인
  • OOM이면 dmesg | grep -i oom
  • application은 connection retry

10. ERROR: out of shared memory​

ERROR: out of shared memory
HINT: You might need to increase max_locks_per_transaction.

원인: 락·prepared statement 등 shared 영역의 슬롯 부족 — 흔히 많은 파티션 + 한 트랜잭션이 모든 파티션 락

대응:

max_locks_per_transaction = 256 # restart 필요
max_pred_locks_per_transaction = 256

11. ERROR: cannot execute UPDATE in a read-only transaction​

원인: hot standby 또는 default_transaction_read_only = on

대응: 쓰기는 primary로 라우팅. HAProxy·풀러 설정 확인합니다.

12. ERROR: relation "..." does not exist​

원인: 테이블 없음, 잘못된 search_path, 다른 스키마

대응:

SHOW search_path;
SELECT schemaname, tablename FROM pg_tables WHERE tablename = 'orders';

13. ERROR: permission denied for table ...​

원인: GRANT 없음

대응:

-- 권한 확인
SELECT grantee, privilege_type
FROM information_schema.table_privileges
WHERE table_name = 'orders';

pg_monitor·pg_read_all_data 같은 미리 정의 역할 활용합니다.

14. ERROR: invalid input syntax for integer: "..."​

원인: application이 잘못된 타입 전달 — 또는 SQL injection 시도

대응: parameterized query 사용합니다.

15. ERROR: missing chunk number ... for toast value ...​

원인: TOAST corruption — 매우 심각

대응:

-- 영향 받는 row 식별
SELECT id FROM big_table WHERE big_col IS NOT NULL ORDER BY id;
-- 오류 발생하는 직전 id를 추적

-- 영향 row 제외하고 다른 곳으로 export
SELECT * FROM big_table WHERE ctid::text NOT LIKE '(<bad>,%)';

복구 한계 — 백업에서 PITR 검토합니다.

16. the database system is in recovery mode​

원인: startup process가 WAL 재생 중

대응: 기다립니다. pg_last_wal_replay_lsn으로 진행 상황을 확인합니다.

17. pg_hba.conf rejects connection for ...​

FATAL: pg_hba.conf rejects connection for host "203.0.113.5", user "alice", database "app", no encryption

원인: 명시적 reject 또는 매칭 행 없음 (9.2)

대응: pg_hba.conf 점검합니다.

SELECT * FROM pg_hba_file_rules;

18. WAL contains references to invalid pages​

PANIC 또는 ERROR. 페이지 손상 가능성이 있습니다.

대응:

  • data_checksums 켜져 있으면 자세한 정보
  • pg_basebackup으로 새로 복원
  • 데이터 손상 — 백업·전문가 자문

19. lock not available​

ERROR: could not obtain lock on relation "..."

원인: lock_timeout 만료 또는 NOWAIT

대응: 락 잡고 있는 세션 식별 후 결정합니다.

20. application 로그에 EOF detected / Connection reset by peer​

원인: network 또는 PostgreSQL 측 종료

대응:

  • application retry
  • PostgreSQL 로그에서 server 측 사유 확인
  • TCP keepalive 설정

진단 워크플로​

정리​

  • 모든 사고의 첫 단계 = PostgreSQL 로그
  • pg_stat_activity·pg_locks로 실시간 진단
  • 디스크 풀·OOM은 OS 도구로 확인
  • 자주 보는 에러 20종은 원인 매핑 표로 외움 — 신속 대응