- Published on
리눅스 디스크 100%인데 삭제해도 용량이 안 줄 때(lsof)
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서버에서 df -h는 100%를 가리키는데, 분명히 대용량 로그/덤프 파일을 rm로 삭제했음에도 사용량이 줄지 않는 상황은 운영에서 자주 만납니다. 이때 많은 경우 “파일은 삭제됐지만 프로세스가 아직 그 파일을 열고 있어서(파일 디스크립터 유지) 디스크 블록이 해제되지 않는” 전형적인 리눅스 동작을 밟고 있습니다.
이 글에서는 왜 이런 현상이 생기는지, lsof로 정확히 어떤 프로세스가 공간을 잡고 있는지 찾는 방법, 그리고 서비스 영향도를 최소화하면서 공간을 회수하는 방법을 단계별로 정리합니다.
> 관련 글: 같은 주제의 확장 버전은 리눅스 디스크 100% - 삭제해도 용량 안 줄 때에서도 확인할 수 있습니다.
증상: rm 했는데 df가 안 줄어드는 이유
리눅스/유닉스 파일 시스템에서 파일 삭제는 “디렉터리 엔트리 제거(링크 카운트 감소)”입니다. 하지만 어떤 프로세스가 해당 파일을 열어둔 상태라면(inode에 대한 참조가 남아 있음) 실제 데이터 블록은 즉시 해제되지 않습니다.
즉,
ls에서는 파일이 사라짐- 그런데 프로세스는 여전히 그 파일에 쓰거나 읽고 있음
- 파일은
(deleted)상태로 열린 채 유지 df는 블록이 여전히 사용 중이라 100%가 유지
이때 du로 디렉터리를 훑어도 안 잡히는 경우가 많습니다. du는 “디렉터리 트리에서 접근 가능한 파일”만 합산하기 때문에, 이미 이름이 사라진 (deleted) 파일은 보이지 않습니다.
1단계: df와 du가 왜 다르게 보이는지 빠르게 확인
먼저 파일 시스템 단위 사용량과 디렉터리 합계를 비교해 차이를 확인합니다.
# 파일시스템 사용량
sudo df -hT
# 특정 마운트(/) 아래에서 큰 디렉터리 찾기
sudo du -xhd1 / | sort -h
df는 높게 나오는데du로는 큰 파일이 안 보이면, 숨은 사용량(대표적으로 deleted-but-open 파일, 또는 다른 마운트/오버레이, reserved blocks 등)을 의심합니다.
2단계(핵심): lsof로 (deleted) 열린 파일 찾기
삭제된 파일을 잡고 있는 프로세스를 찾는 가장 확실한 도구가 lsof입니다.
옵션 A: (deleted)만 필터링
sudo lsof +L1
+L1은 링크 수가 1 미만(즉 0)인 파일, 흔히 “삭제되었지만 열린 파일”을 보여줍니다.
출력 예시는 대략 이런 형태입니다.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 1324 app 123w REG 253,0 2147483648 123456 /var/log/app/app.log (deleted)
nginx 901 root 10w REG 253,0 536870912 123999 /var/log/nginx/access.log.1 (deleted)
여기서 봐야 할 포인트:
PID: 어떤 프로세스가 잡고 있는지FD:123w처럼 쓰기(w)로 열려 있으면 계속 용량이 늘 수 있음SIZE/OFF: 현재 점유 중인 크기(대략적인 회수 가능 용량)NAME끝의(deleted)
옵션 B: 특정 마운트/경로에 한정해서 찾기
디스크가 꽉 찬 파티션이 /var라면 해당 경로에 한정하면 훨씬 빠릅니다.
sudo lsof +L1 /var
옵션 C: grep으로 빠르게 보기
sudo lsof | grep '(deleted)'
다만 이 방식은 불필요한 출력이 많을 수 있어 +L1을 권장합니다.
3단계: 어떤 프로세스를 어떻게 조치할지 결정
lsof +L1 결과에서 “용량을 크게 잡고 있는” 프로세스를 기준으로 조치합니다. 조치 방법은 크게 3가지입니다.
방법 1) 가장 안전: 서비스 재시작(프로세스가 FD를 닫게 하기)
대부분의 경우 프로세스를 재시작하면 열린 파일 디스크립터가 닫히며 즉시 공간이 회수됩니다.
# systemd 서비스라면
sudo systemctl restart nginx
sudo systemctl restart your-app.service
# 상태 확인
sudo systemctl status nginx --no-pager
재시작이 반복적으로 실패하는 상황이라면(디스크 100%로 인해 로그/임시파일 쓰기 실패 등) 먼저 원인을 빠르게 진단해야 합니다. 이 경우는 systemd 서비스 재시작 루프 10분 진단 가이드가 도움이 됩니다.
방법 2) 다운타임 없이: 해당 FD를 직접 truncate(주의 필요)
서비스를 내릴 수 없고, “삭제된 파일을 계속 쓰고 있는” 상황이라면 해당 파일 디스크립터를 직접 0으로 줄여 공간을 회수할 수 있습니다.
lsof 출력에서 PID와 FD 번호를 확인한 뒤 /proc/<pid>/fd/<fd>를 대상으로 truncate 합니다.
# 예: PID=1324, FD=123 (lsof에서 123w로 보였다고 가정)
sudo truncate -s 0 /proc/1324/fd/123
또는 셸 리다이렉션을 사용할 수도 있습니다.
sudo sh -c ': > /proc/1324/fd/123'
주의사항:
- 이 방법은 “프로세스가 현재 쓰고 있는 스트림”을 강제로 비우는 것이므로, 애플리케이션/로그 로테이션 정책에 따라 예상치 못한 동작이 있을 수 있습니다.
- 특히 데이터 파일(로그가 아닌 DB 파일 등)에 하면 장애로 이어질 수 있으니, 대상이 로그/임시파일인지 반드시 확인하세요.
방법 3) 로그 로테이션/재오픈 시그널로 해결(서버 소프트웨어별)
일부 데몬은 재시작 없이 로그 파일을 다시 열도록 시그널을 받을 수 있습니다.
예를 들어 nginx는 보통 USR1로 로그를 reopen 합니다(배포판/설정에 따라 다를 수 있으니 문서 확인 권장).
# nginx 마스터 PID를 찾아서
pid=$(cat /run/nginx.pid)
sudo kill -USR1 "$pid"
이 방식은 “삭제된 파일을 계속 쓰는” 문제를 완화하고, 새 로그 파일로 쓰기를 전환하게 합니다.
4단계: 공간이 실제로 회수됐는지 검증
조치 후 아래를 확인합니다.
sudo df -h
sudo lsof +L1 | head
df사용량이 내려가야 정상입니다.lsof +L1에서 대용량(deleted)항목이 사라졌는지도 확인합니다.
실전 팁: 용량 폭증의 흔한 원인 패턴
운영에서 자주 보이는 패턴을 몇 가지 정리합니다.
1) 애플리케이션 로그가 폭증 + logrotate 미동작
- 로그 파일을 삭제(
rm)해버리면, 프로세스는 기존 FD로 계속 쓰고 디스크는 안 줄어듭니다. - 정석은
logrotate로 rotate + (필요 시) 서비스에 reopen 시그널/재시작을 수행하는 것입니다.
점검:
sudo logrotate -d /etc/logrotate.conf
sudo logrotate -f /etc/logrotate.conf
2) 컨테이너/쿠버네티스 환경에서 노드 디스크가 가득 참
컨테이너 런타임 로그나 애플리케이션 로그가 노드 파일 시스템을 잠식할 수 있습니다. 특히 프로세스가 삭제된 로그 파일을 계속 잡고 있으면 노드에서 df만 100%로 유지됩니다.
- 노드에서
lsof +L1로 원인 프로세스(컨테이너 프로세스/런타임)를 찾고 - 필요 시 해당 파드/서비스 재시작으로 FD를 닫게 해야 합니다.
운영 중 파드가 계속 죽고 올라오며 로그가 남지 않는 상황도 섞일 수 있는데, 이때는 K8s CrashLoopBackOff - Readiness·Liveness 5분 진단 같은 체크리스트가 문제를 빠르게 좁히는 데 유용합니다.
3) DB/검색엔진의 대형 임시파일
정렬/머지/컴팩션 과정에서 임시파일이 커질 수 있습니다. 이 경우는 단순 truncate가 위험할 수 있으니, 프로세스 특성을 확인하고 “정상 절차(롤링 재시작, 설정 조정, 임시 디렉터리 분리)”로 접근해야 합니다.
운영 관점 체크리스트(재발 방지)
디스크 100%는 단발로 끝나지 않고 반복되는 경우가 많습니다. 아래를 함께 점검하면 재발 확률이 크게 줄어듭니다.
- 로그 정책
- 로그 디렉터리별 보관 기간/최대 용량 설정
logrotate에copytruncate를 쓸지(재시작 어려운 프로세스) vs reopen 시그널을 쓸지 결정
- 모니터링
- 파일 시스템 사용량(
df) 경보 - inode 사용량(
df -i) 경보(파일이 너무 많아도 장애)
- 파일 시스템 사용량(
- 장애 시 대응
- “rm로 지우기”보다 “원인 프로세스 확인(lsof) → 안전한 회수(재시작/FD truncate)” 절차를 런북화
결론
rm로 파일을 지웠는데도 df가 100%에서 내려오지 않는다면, 높은 확률로 “삭제되었지만 열린 파일(= (deleted) 상태)”이 디스크를 붙잡고 있습니다. 이 문제는 감으로 해결하기 어렵고, lsof +L1로 어떤 PID가 어떤 FD를 잡고 있는지를 확인하면 바로 풀립니다.
정리하면 실전 순서는 다음이 가장 안전합니다.
df -h로 대상 파티션 확인 → 2)lsof +L1로 deleted 파일 확인 → 3) 가능하면 서비스 재시작으로 FD 닫기 → 4) 불가하면/proc/<pid>/fd/<fd>truncate를 신중히 적용 → 5)df로 회수 확인
이 흐름만 익혀두면 “디스크 100%인데 용량이 안 줄어드는” 난감한 상황을 짧은 시간 안에 복구할 수 있습니다.