디스크 / 테이블스페이스 가득 참
'unable to extend', 'disk full', 'could not extend' 또는 'log full'이 발생했다. 당황하지 않는다: 먼저 무엇이 가득 찼는지 찾고, 안전하게 공간을 회수한 다음, 영구적으로 해결한다.
무엇이 가득 찼는가?
엉뚱한 곳을 정리해도 소용없다. 먼저 사용량을 측정한다: 데이터 파일인가, 트랜잭션 로그인가, archive/redo인가, temp인가, OS 디스크인가?
SELECT d.tablespace_name, ROUND((1-(d.alloc-NVL(f.free,0))/d.maxb)*100,1) AS pct_free
FROM (SELECT tablespace_name, SUM(bytes) alloc, SUM(GREATEST(bytes,maxbytes)) maxb FROM dba_data_files GROUP BY tablespace_name) d LEFT JOIN (SELECT tablespace_name, SUM(bytes) free FROM dba_free_space GROUP BY tablespace_name) f ON f.tablespace_name = d.tablespace_name ORDER BY pct_free;- 데이터 파일 / 테이블스페이스가 가득 참
- 트랜잭션 로그 / archive-redo가 가득 참
- temp / undo가 가득 참
- OS 디스크가 가득 참 (DB가 아님)
가장 큰 소비자는 무엇인가?
대부분 폭주한 단일 테이블/segment가 원인이다. 가장 큰 것들을 찾는다.
SELECT segment_name, segment_type, ROUND(bytes/1048576,1) AS mb FROM dba_segments ORDER BY bytes DESC FETCH FIRST 10 ROWS ONLY;- 예상치 못하게 큰/폭주한 테이블이 있다
- 정상 증가이며 공간이 실제로 부족하다
- dead row / bloat 과다
로그가 왜 커지는가?
가장 오래된 활성 트랜잭션/백업이 완료될 때까지 로그/아카이브를 정리할 수 없다. 왜 쌓였는가?
SELECT name, log_reuse_wait_desc FROM sys.databases WHERE name=DB_NAME(); -- why can it not be truncated?- MSSQL: 로그 백업이 수행되지 않음 (LOG_BACKUP)
- PG: 멈춘 replication slot이 WAL을 붙잡고 있음
- Oracle: 아카이브 로그 영역(FRA)이 가득 참
- 긴 열린 트랜잭션이 로그를 붙잡고 있음
근본 원인: 폭주한 테이블/segment
단일 객체가 예기치 않게 커졌다(통제되지 않는 insert, 정리되지 않는 큐/로그 테이블).
근본 원인: 실제 용량 필요
정상 증가이며 공간을 추가해야 한다.
근본 원인: bloat / dead row
삭제/수정된 행의 공간이 회수되지 않았다.
근본 원인: temp / undo 가득 참
큰 sort/hash나 긴 열린 트랜잭션이 임시 공간을 채웠다.
근본 원인: OS 디스크 가득 참
문제는 DB가 아니라 운영체제 디스크에 있다. 로그, core dump, 오래된 백업, trace 파일이 공간을 차지하고 있을 수 있다.
근본 원인: 로그 백업 미수행 (SQL Server)
FULL 복구 모델에서 로그 백업을 하지 않으면 로그가 무한히 커진다.
근본 원인: 방치된 replication slot (PG)
멈춘(비활성) slot이 WAL 삭제를 막아 pg_wal을 부풀린다.
근본 원인: 아카이브 로그 영역(FRA) 가득 참 (Oracle)
아카이브 로그가 쌓여 FRA가 가득 찼다. archiver가 멈추면 데이터베이스가 쓰기를 받지 못할 수 있다.
근본 원인: 긴 열린 트랜잭션
가장 오래된 활성 트랜잭션이 로그/undo 회수를 막고 있다.