리눅스 시스템에서 디스크 사용량을 확인할 때 du와 df 명령어를 자주 사용합니다. 하지만 두 명령어는 서로 다른 방식으로 디스크 사용량을 계산하기 때문에 결과가 일치하지 않는 경우가 많습니다.
예를 들어 다음과 같은 상황을 살펴보겠습니다:
# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 18G 1.7G 15G 11% /
tmpfs tmpfs 491M 0 491M 0% /dev/shm
/dev/sda1 ext4 239M 68M 159M 30% /boot
//192.168.0.124/win cifs 381G 243G 138G 64% /mnt
# du -sh / 2>/dev/null
244G /
위 예제에서는 df는 루트 디렉토리(/)의 사용량을 1.7GB로 표시하고 있지만, du는 244GB를 반환하고 있습니다. 이처럼 두 도구의 결과가 크게 다를 수 있습니다.
파일 저장 및 삭제 메커니즘 이해
두 도구의 차이를 이해하려면 파일 시스템 내부 작동 방식을 알아야 합니다.
새로운 파일이 생성될 때:
- inode 테이블에서 비어 있는 inode 번호를 할당받습니다.
- 해당 inode 번호는 사용 중으로 표시됩니다.
- 부모 디렉터리의 데이터 블록에 파일 이름과 inode 포인터를 추가합니다.
- 데이터 블록 맵(bmap)에서 빈 블록을 찾아 파일 내용을 기록합니다.
파일이 삭제될 때:
- inode 테이블에서 데이터 블록 포인터를 제거하여 외부 접근 불가능하게 만듭니다.
- inode 맵(imap)에서 해당 inode 번호를 미사용 상태로 변경합니다.
- 부모 디렉터리에서 파일 항목을 제거하여 파일을 보이지 않게 만듭니다.
- bmap에서 해당 데이터 블록들을 미사용 상태로 표시합니다.
만약 파일이 삭제되었지만 여전히 어떤 프로세스가 해당 파일을 열고 있다면, 파일은 더 이상 보이지 않지만 실제 데이터는 여전히 존재합니다. 왜냐하면 bmap에서는 아직 데이터 블록들이 미사용 상태로 표시되지 않았기 때문입니다.
du 명령어의 동작 원리
du는 각 파일과 하위 디렉터리에 대해 stat() 시스템 호출을 수행하여 공간 사용량을 누적합니다. 따라서 대상이 많을수록 느립니다.
du의 특징:
- 마운트된 다른 파일 시스템 포함: 특정 디렉터리를 스캔할 때 그 아래 마운트된 다른 파일 시스템도 함께 계산합니다.
- 삭제된 파일 무시: 이미 삭제되어
stat()으로 찾을 수 없는 파일은 집계하지 않습니다. - 크로스 파티션 지원: 여러 파티션에 걸쳐 있는 파일들의 총합을 계산할 수 있습니다.
예시:
# find / -type f -name "*.img" -print0 | xargs -0 du -csh
19M /boot/initramfs-2.6.32-504.el6.x86_64.img
13M /mnt/linux工具/cirros-0.3.4-x86_64-disk.img
31M total
df 명령어의 동작 원리
df는 각 파티션의 슈퍼블록(superblock) 정보를 읽어 사용 가능한 블록 수와 사용 중인 블록 수를 가져옵니다. 슈퍼블록 크기는 일반적으로 1KB이므로 매우 빠릅니다.
df의 특징:
- 개별 파티션 단위 통계: 마운트된 다른 파일 시스템은 별도로 취급하며, 포함하지 않습니다.
- 슈퍼블록 기반 계산: 지정된 파일이나 디렉터리는 해당 파티션 전체의 정보를 나타냅니다.
- 삭제되었으나 참조 중인 파일 포함: bmap이 업데이트되지 않은 파일도 사용량에 반영됩니다.
실제 예제:
# dd if=/dev/zero of=/temp_file bs=1M count=1000
# df -hT /
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 18G 2.7G 14G 17% /
# du -sh --exclude="/mnt" / 2>/dev/null
2.7G /
# tail -f /temp_file &
# rm -rf /temp_file
# du -sh --exclude="/mnt" / 2>/dev/null
1.8G /
# df -hT /
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 18G 2.7G 14G 17% /
파일이 삭제되었지만 프로세스가 계속 참조하고 있으므로 du에서는 제외되지만 df에서는 여전히 포함됩니다.
참조 중인 삭제된 파일을 확인하려면 다음 명령어를 사용할 수 있습니다:
# lsof | grep deleted
tail 14437 root 3r REG 8,2 1048576000 7171 /temp_file (deleted)
해당 프로세스를 종료하면 df도 정확한 값을 보여줍니다.
# kill %1
# df -hT /
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 18G 1.7G 15G 11% /