서버 운영
Linux inode가 먼저 바닥났을 때 디스크 용량만 보던 습관을 고친 순서
df -h가 여유 있다고 나오는데 파일 생성이 실패했던 VPS에서 inode와 작은 파일을 확인하고 정리한 과정입니다.
40GB가 남았는데 파일을 만들 수 없었다
새 배포가 임시 디렉터리에 파일을 쓰는 순간 No space left on device가 발생했다. 먼저 df -h를 실행했더니 루트 파티션 사용량은 68%였다. 디스크가 남았다는 숫자만 믿고 Docker 이미지부터 지우려던 것이 첫 번째 실수였다.
이번에는 블록 용량이 아니라 파일 개수(inode)가 부족한 상황이었다. 예전에 디버그 옵션을 켜 둔 작은 Node 작업이 요청마다 파일 하나를 남기고 있었고, 수십만 개의 파일이 한 디렉터리에 쌓였다.
용량과 inode를 분리해서 본 명령
df -h /
df -i /
sudo du -xhd1 /var | sort -h
df -h는 실제 저장 공간을, df -i는 생성 가능한 파일의 남은 개수를 보여준다. 두 번째 명령에서 IUse%가 100%에 가까우면 큰 로그 파일을 찾는 것보다 작은 파일 묶음을 먼저 의심해야 한다.
sudo find /var/tmp/my-worker -xdev -type f -printf '%T@ %p\n' \
| sort -n | head -20
sudo find /var/tmp/my-worker -xdev -type f | wc -l
삭제 전에는 애플리케이션이 해당 경로를 현재 사용 중인지 확인했다. 실행 중인 프로세스가 파일을 열고 있으면 파일을 지워도 프로세스가 종료될 때까지 공간이 돌아오지 않을 수 있다.
sudo lsof +L1
재발 방지 기준
원인은 로그 로테이션 설정이 아니라 로그처럼 쓰던 임시 파일이었다. 파일을 생성하는 코드를 날짜별 한 파일로 바꾸고, 7일이 지난 작업 결과는 배치로 제거했다. systemd timer에서 삭제 작업이 실패해도 본 작업의 종료 상태를 가리지 않도록 별도 서비스로 분리했다.
체크리스트는 다음처럼 남겼다.
- 장애 시
df -h와df -i를 항상 같이 실행한다 /var,/tmp, Docker 저장소를 파티션별로 나눠 확인한다- 수동 삭제 전
find결과의 경로와 개수를 출력한다 - 작은 파일을 만드는 작업에는 보존 기간과 최대 개수를 둔다
lsof +L1로 삭제됐지만 열린 파일을 확인한다
숫자 하나로 판단하지 않기
이번 일 이후 “디스크가 찼다”라는 문장을 바로 믿지 않는다. 블록이 부족한지 inode가 부족한지에 따라 조사 순서와 정리 방법이 완전히 달라진다. 운영 중에는 지우는 속도보다 무엇을 지우는지 확인하는 속도가 더 중요했다.