Devin.KR
로그인

리눅스 df 명령어 사용법 - 디스크 용량 확인과 inode 고갈 점검

개발자 조회 2

이 명령어를 언제 쓰는가

"디스크 사용률 90%" 알림을 받았을 때 가장 먼저 치는 명령이다. 서버 전체가 아니라 마운트된 파일시스템별로 얼마나 남았는지 보여 주기 때문에, 루트가 찬 건지 로그 파티션만 찬 건지 데이터 볼륨이 찬 건지를 구분할 수 있다.

애플리케이션이 "No space left on device" 에러를 뱉는데 df에는 여유가 있어 보일 때도 df로 확인해야 한다. 이 경우 대개 용량이 아니라 inode가 고갈된 것이고, df -i로만 보인다.

기본 형식

df [옵션] [경로]

경로를 주면 그 경로가 속한 파일시스템 한 줄만 나온다. 경로가 어느 마운트에 속하는지 헷갈릴 때 유용하다. 경로를 생략하면 마운트된 전부를 보여 준다.

자주 쓰는 옵션

옵션의미예시
-h사람이 읽는 단위(G, M)로 표시. 사실상 항상 붙인다df -h
-T파일시스템 타입(ext4, xfs, overlay) 표시df -hT
-i용량 대신 inode 사용량 표시df -i
-x 타입해당 타입 제외. tmpfs 노이즈를 걷어낼 때df -h -x tmpfs
-t 타입해당 타입만df -h -t ext4
-PPOSIX 포맷. 한 항목이 반드시 한 줄로 나온다df -P /data
--total맨 아래에 합계 행 추가df -h --total
-a크기 0인 가상 파일시스템까지 전부df -a

실전 예제

1) 노이즈를 걷어내고 실제 디스크만 본다. 요즘 배포판은 tmpfs 마운트가 열 개 넘게 잡혀서 그냥 df -h를 치면 정작 볼 게 안 보인다.

df -hT -x tmpfs -x devtmpfs -x squashfs
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/vda1      ext4       49G   38G  8.6G  82% /
/dev/vdb1      xfs       197G   61G  137G  31% /data

2) 특정 디렉터리가 어느 파일시스템에 있는지 확인한다. DB 데이터 경로가 별도 볼륨인지 루트에 있는지 확인할 때 쓴다.

df -hT /var/lib/mysql

3) inode 고갈을 점검한다. 세션 파일이나 캐시 파일이 수백만 개 쌓이면 용량은 남아도 파일을 못 만든다. IUse%가 100%면 이게 원인이다.

df -i -x tmpfs
Filesystem      Inodes   IUsed  IFree IUse% Mounted on
/dev/vda1      3211264 3211264      0  100% /

4) 임계치를 넘은 파일시스템만 골라낸다. 크론에 넣어 알림용으로 쓴다. awk에서 int($5)는 "82%" 같은 문자열에서 숫자만 취한다.

df -hP -x tmpfs -x devtmpfs | awk 'NR>1 && int($5) >= 80 {print $6, $5}'

5) 지웠는데 용량이 안 도는 파일을 찾는다. df와 du의 합계가 크게 다르면 이걸 의심한다.

sudo lsof -nP +L1 2>/dev/null | grep -i deleted

함정과 주의점

큰 로그 파일을 rm 했는데 용량이 그대로다. 가장 자주 겪는 사고다. 리눅스는 파일을 참조하는 프로세스가 남아 있으면 디렉터리 엔트리만 지우고 데이터 블록은 유지한다. 애플리케이션이 그 로그 파일을 계속 열어 두고 있으면 30GB짜리를 지워도 df 수치는 1바이트도 안 줄어든다. 해결책은 해당 프로세스를 재시작하거나(정석), 급하면 파일 디스크립터를 통해 내용을 비우는 것이다.

# 애초에 rm 대신 이렇게 비우면 이 문제가 생기지 않는다
: > /var/log/myapp/app.log

Use%가 100%인데 Avail이 0이 아니고 Size와도 안 맞는다. ext4는 기본적으로 전체 블록의 5%를 root 전용으로 예약한다. 일반 사용자에게는 이미 꽉 찬 것으로 보이지만 root는 아직 쓸 수 있다. 1TB 볼륨이면 50GB가 묶여 있는 셈이라, 데이터 전용 볼륨에서는 tune2fs -m 1 /dev/vdc1처럼 줄이는 것이 보통이다. 단 tune2fs는 ext2/3/4 전용이라 위 예시의 xfs 볼륨(/dev/vdb1)에는 쓸 수 없고, xfs에는 이런 예약 블록 자체가 없다. 다만 루트 파일시스템에서는 이 예약이 시스템 복구 여지를 남겨 주므로 함부로 0으로 만들지 않는다.

디바이스 이름이 길면 출력이 두 줄로 접힌다. LVM이나 iSCSI 경로처럼 이름이 긴 경우 첫 컬럼만 한 줄을 차지하고 나머지가 다음 줄로 넘어간다. awk '{print $5}' 같은 파싱이 조용히 깨진다. 스크립트에서는 반드시 -P를 붙인다.

컨테이너 안의 df는 참고용이다. overlay 파일시스템으로 표시되는 값은 호스트 디스크 상황을 반영하므로, 컨테이너에 걸어 둔 스토리지 쿼터와는 다르다.

함께 보면 좋은 명령어

  • du — df로 어느 마운트가 찼는지 알아낸 다음, 그 안에서 범인 디렉터리를 찾는다. 항상 짝으로 쓴다.
  • lsof — 지웠지만 열려 있는 파일을 찾아낸다. df와 du가 안 맞을 때의 해답.
  • ncdu — 디렉터리 용량을 대화형으로 파고든다. 별도 설치가 필요하지만 원인 추적이 훨씬 빠르다.