15.1 일반적인 에러 패턴
PostgreSQL 운영에서 자주 보는 에러를 패턴별로 정리합니다. 메시지·원인·즉시 대응·예방 절차를 함께.
1. FATAL: too many connections
FATAL: remaining connection slots are reserved for non-replication superuser connections| 원인 | 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/pg_temp}흔한 후보:
pg_wal/— archive 실패 또는 slot 정체base/pg_temp— 큰 정렬 temp filelog/— 로그 폭증
예방: 디스크 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_command 수동 실행합니다.
sudo -u postgres pgbackrest --stanza=main archive-push /tmp/test.walpg_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 = 25611. 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. database is being recovered
| 원인 | 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 설정
진단 워크플로
flowchart TD
ERR["에러 발생"]
LOG["PostgreSQL log 확인"]
CTX{"context"}
APP["application 측 진단<br/>(타입·SQL·로직)"]
CON["연결 측 진단<br/>(pg_hba, network)"]
DB["DB 측 진단<br/>(pg_stat_activity, pg_locks)"]
OS["OS 측 진단<br/>(메모리·디스크·dmesg)"]
ERR --> LOG --> CTX
CTX -- "application 메시지" --> APP
CTX -- "FATAL on connect" --> CON
CTX -- "ERROR in query" --> DB
CTX -- "PANIC·OOM" --> OS
classDef step fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
class ERR,LOG,APP,CON,DB,OS step
정리
- 모든 사고의 첫 단계 = PostgreSQL 로그
pg_stat_activity·pg_locks로 실시간 진단- 디스크 풀·OOM은 OS 도구로 확인
- 자주 보는 에러 20종은 원인 매핑 표로 외움 — 신속 대응
다음 절(15.2)에서는 느린 쿼리 진단의 표준 — 슬로우 쿼리 진단 워크플로우를 봅니다.