No space left on device가 떴는데 df -h를 보면 용량이 멀쩡하게 남아 있습니다. 디스크가 안 찼는데 왜 공간이 없다고 할까요? 거의 항상 inode 고갈입니다. 파일 하나하나는 메타데이터를 담는 inode를 하나씩 소비하는데, 작은 파일이 너무 많으면 용량보다 inode가 먼저 바닥납니다.
진단 — 용량과 inode를 따로 본다
먼저 용량(df -h)과 inode(df -i)를 나란히 확인합니다.
df -h # 용량(블록) 사용률
df -i # inode 사용률
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 1310720 1310720 0 100% /
Use%(용량)는 40%인데 IUse%(inode)가 100%라면 진단 끝입니다. 용량은 남아도 빈 inode가 없어서 새 파일을 못 만드는 상태입니다. 이 경우 빈 파일 하나 만드는 touch조차 실패합니다.
범인 찾기 — 작은 파일이 몰린 디렉터리
inode는 파일 개수에 비례합니다. 따라서 "용량 큰 디렉터리"가 아니라 **"파일 개수 많은 디렉터리"**를 찾아야 합니다. 최상위부터 디렉터리별 파일 개수를 세어 내려갑니다.
# 1뎁스 디렉터리별 파일 개수 (내림차순)
for d in /*; do printf "%s\t" "$d"; find "$d" -xdev 2>/dev/null | wc -l; done | sort -k2 -rn | head
개수가 튀는 디렉터리로 들어가 같은 방식으로 반복하면 범인이 좁혀집니다. 흔한 원인은 세션 파일, 메일 큐(/var/spool), PHP 세션(/var/lib/php/sessions), 캐시 조각, 로그 로테이트 실패로 쌓인 수십만 개의 작은 파일입니다.
정리 — 오래된 작은 파일부터
원인 디렉터리를 확인했으면 오래된 파일을 골라 지웁니다. 인자 길이 초과(Argument list too long)를 피하려고 find의 -delete나 xargs를 씁니다.
| 상황 | 명령 |
|---|---|
| 30일 이상 된 세션 파일 정리 | find /var/lib/php/sessions -type f -mtime +30 -delete |
| 대량 파일 안전 삭제 | find /tmp/cache -type f -mtime +7 -print0 | xargs -0 rm -f |
| 디렉터리 통째 정리 | rm -rf /var/spool/old/* (대상 반드시 재확인) |
체크리스트
df -h # 용량은 남았나
df -i # inode가 100%인가 ← 핵심
for d in /*; do printf "%s\t" "$d"; \
find "$d" -xdev 2>/dev/null | wc -l; done | sort -k2 -rn | head
find <범인경로> -type f -mtime +30 -delete # 오래된 것부터
핵심은 단 하나입니다. No space인데 df -h가 멀쩡하면 무조건 df -i부터 보세요.
inode 같은 파일시스템 구조와 디스크 트러블슈팅을 직접 손으로 익히는 실습은 회원가입 없이 무료로 리눅스 트랙에서 할 수 있습니다.