SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor

df와 du 용량 차이 해결 방법: 삭제된 파일 찾기

df는 디스크가 꽉 찼다고 나오는데 du는 여유 공간이 충분한 상황을 해결합니다. 삭제된 파일을 붙잡고 있는 프로세스를 lsof로 찾아 재부팅 없이 디스크 공간을 확보하는 구체적인 방법을 설명합니다. inode 부족 및 마운트 지점 숨김 파일 등 다른 원인도 함께 다룹니다.

df 명령은 디스크가 꽉 찼다고 하는데 du 명령은 그렇지 않은 이유

df은 디스크가 가득 찼다고 보고하지만, du은 공간을 찾지 못하는 경우가 있습니다. 이는 삭제된 파일을 어떤 프로세스가 여전히 붙잡고 있기 때문입니다. 파일을 삭제하면 디렉터리에서 파일 이름만 제거됩니다. 해당 inode를 가리키는 마지막 열린 파일 디스크립터가 닫혀야만 데이터 블록이 비로소 해제됩니다. du는 파일 이름을 따라가며 계산하므로 삭제된 파일은 집계하지 않습니다. 반면 df은 파일 시스템에 할당된 블록 수를 직접 질의하므로, 이름이 사라진 파일도 여전히 용량에 포함합니다.

이 가이드에서는 별도의 설치 없이 Ubuntu VPS에 기본으로 포함된 도구들을 사용하여 해당 상황을 재현하고, /proc을 통해 파일을 붙잡고 있는 프로세스를 찾아 재부팅 없이 공간을 확보하는 방법을 설명합니다. 동일한 증상을 유발하는 다른 원인으로는 inode 테이블의 빈 항목 부족, 마운트 지점 아래에 숨겨진 파일, root 사용자를 위해 예약된 블록 등이 있습니다.

각 명령어를 직접 실행하고 출력 결과를 확인하십시오. 값은 사용 중인 디스크 환경에 따라 다르므로, 가이드에 적힌 수치와 비교하기보다 본인의 시스템에서 작업 전후의 변화를 직접 비교하시기 바랍니다.

df와 du가 계산하는 항목의 차이

df (disk free)는 마운트된 각 파일 시스템에 직접 할당된 블록 수, 사용 중인 블록 수, 여유 블록 수를 질의합니다. 이 명령은 디렉터리를 열지 않습니다. 따라서 디렉터리 항목이 가리키지 않는, 즉 이름이 없는 파일에 할당된 블록까지 포함하여 모든 할당 블록을 계산합니다.

du (disk usage)는 정반대로 동작합니다. 지정한 경로에서 시작하여 디렉터리를 읽고, 발견한 모든 항목의 상태를 확인(stat)하여 블록 수를 합산합니다. 따라서 이름이 없는 파일은 계산에서 제외됩니다. 읽기 권한이 없는 디렉터리 역시 계산할 수 없으므로, 일반 사용자가 실행하면 root가 실행했을 때보다 더 작은 합계가 나옵니다. 비교 결과를 결론짓기 전에 반드시 dusudo 권한으로 실행하십시오.

두 명령을 비교할 때 항상 고려해야 할 두 가지 옵션이 있습니다.

  • -xdu을 하나의 파일 시스템 내로 제한합니다. 이 옵션이 없으면 du // 아래에 마운트된 모든 파일 시스템을 순회하며, 결과적으로 df /이 측정하지 않는 영역까지 합산하게 됩니다.
  • -s은 디렉터리마다 한 줄씩 출력하는 대신 인자별로 요약된 한 줄만 출력합니다.

이 옵션들을 조합하면 관심 있는 파일 시스템에서 두 명령을 나란히 실행하여 비교할 수 있습니다.

df -h /
sudo du -xhs / 2>/dev/null

df는 즉시 결과를 반환합니다. 반면 du은 대규모 파일 시스템에서 모든 파일의 상태를 확인해야 하므로 수 분이 소요될 수 있습니다. 두 결과값의 차이가 크고, du를 root 권한으로 -x 옵션을 사용하여 실행했다면, 누락된 공간은 이름이 없는 파일에 할당된 상태일 가능성이 높습니다.

의도적으로 불일치 상황 재현하기

테스트 VPS에서 수행하십시오. 아래의 모든 내용은 bash와 coreutils를 사용하므로 별도의 설치가 필요하지 않습니다.

/var/tmp이 위치한 파일 시스템의 시작 상태를 기록합니다.

cd /var/tmp
df -h .
df --output=used -B1 .

두 번째 명령어는 반올림 없이 사용된 바이트를 출력하므로 마지막 확인 단계에서 정확한 값을 얻을 수 있습니다.

이제 파일을 생성합니다. 파일 크기는 시스템이 보고하는 여유 공간을 기준으로 하므로, 어떤 디스크 환경에서도 실습이 가능합니다.

free=$(df --output=avail -B1 . | tail -n 1)
fallocate -l $((free / 10)) ghost.bin
ls -l ghost.bin
df -h .

$(...)은 명령어 치환입니다. 셸이 내부 명령어를 실행하고 그 결과값이 free의 값이 됩니다. 이 문법이 생소하다면 bash의 명령어 치환에서 자세히 다룹니다. fallocate는 데이터를 실제로 쓰지 않고 실제 블록을 예약하므로 즉시 완료됩니다. 이를 지원하지 않는 파일 시스템에서는 명령어가 실패하며, 이때 head -c $((free / 10)) /dev/zero > ghost.bin을 사용하면 동일한 작업을 바이트를 직접 기록하는 방식으로 수행합니다.

df -h . 결과를 기록해 둔 결과와 비교하십시오. 사용된 용량 열은 증가했고 사용 가능한 용량 열은 감소했습니다.

이제 다른 프로세스에서 파일을 열어둔 상태로 유지한 뒤 삭제합니다.

sleep infinity < ghost.bin &
holder=$!
rm ghost.bin
ls -l ghost.bin
df -h .
sudo du -xhs . 2>/dev/null

리다이렉션이 이 작업의 핵심입니다. sleep infinity < ghost.bin &는 해당 파일을 표준 입력으로 사용하는 백그라운드 프로세스를 시작합니다. 셸이 파일을 열어 파일 디스크립터를 sleep에 전달하고, 이 프로세스가 파일을 계속 열어둡니다. $!는 해당 백그라운드 작업의 프로세스 ID를 보관합니다. 그 후 rm가 파일 디스크립터가 열려 있는 상태에서 파일 이름을 삭제합니다.

출력 결과를 확인하십시오. ls은 파일 이름을 찾을 수 없으므로 파일을 찾지 못합니다. du은 파일 이름을 따라 탐색하므로 시작 시점과 거의 동일한 상태로 돌아옵니다. df은 블록이 여전히 할당되어 있으므로 이동하지 않습니다. 이제 파일 시스템과 디렉터리 트리 간에 불일치가 발생했으며, 그 차이만큼의 공간이 방금 삭제한 파일이 차지하고 있는 영역입니다.

삭제된 파일을 점유 중인 프로세스 찾기

모든 열린 파일 디스크립터는 /proc/<pid>/fd/ 아래에 해당 파일을 가리키는 심볼릭 링크로 나타납니다. 파일이 언링크(unlink)되면 커널은 해당 링크의 대상을 삭제된 것으로 표시합니다. 따라서 점유자를 찾는다는 것은 삭제 표시가 된 대상을 가리키는 링크를 찾는다는 의미입니다.

sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null

-lname은 심볼릭 링크의 이름이 아닌 대상을 매칭하며, %p은 디스크립터 경로를 출력하고, %l는 해당 경로가 가리키는 대상을 출력합니다. 프로세스 ID는 출력된 경로의 두 번째 요소입니다. sudo 권한으로 실행하십시오. 그렇지 않으면 본인 소유의 프로세스에 대한 /proc/<pid>/fd만 읽을 수 있습니다. 표준 에러 리다이렉션은 find가 탐색하는 도중 종료되는 프로세스에서 발생하는 불필요한 메시지를 제거합니다.

바쁜 서버는 언제나 여러 개의 삭제된 파일을 점유하고 있으며, 대부분은 작고 무해합니다. 크기순으로 정렬하여 중요한 파일만 상단에 나타나도록 하십시오.

sudo bash -c 'for fd in /proc/[0-9]*/fd/*; do
  target=$(readlink "$fd" 2>/dev/null) || continue
  case "$target" in
    *"(deleted)") echo "$(stat -Lc %s "$fd" 2>/dev/null) $fd $target" ;;
  esac
done' | sort -rn | head

stat -L은 링크를 따라 아이노드(inode) 자체를 확인하므로, %s은 더 이상 이름이 없는 파일의 크기를 보고합니다. 이 숫자를 기준으로 정렬하면 가장 큰 파일이 맨 위로 올라옵니다.

그다음, 상위 디스크립터의 프로세스를 식별하십시오. 목록 상단의 경로에는 필요한 두 가지 숫자가 모두 포함되어 있으므로, 먼저 변수에 할당하십시오. 이때 PID와 N은 본인의 출력 결과에 나온 값으로 대체하십시오.

pid=PID
n=N
ps -o pid,user,etime,args -p "$pid"
sudo stat -L "/proc/$pid/fd/$n"

ps은 프로그램 이름을 명시하고 실행 시간을 보여줍니다. stat -L는 삭제된 아이노드의 크기와 할당된 블록 수를 출력합니다. 이 정보들을 종합하면 어떤 서비스가 이 파일을 유지하고 있는지 파악할 수 있습니다.

시스템에 이미 lsof이 설치되어 있다면, sudo lsof +L1을 사용하여 링크 카운트가 0으로 떨어진 열린 파일들을 표 형태로 크기와 함께 확인할 수 있습니다. 이 도구는 최소 설치된 Ubuntu 이미지에는 포함되어 있지 않으며, 여유 공간이 없는 파일 시스템에서는 패키지 설치 자체가 실패할 수 있으므로 /proc를 이용한 탐색 방식이 언제나 작동하는 방법입니다.

재부팅 없이 공간 확보하기

재부팅으로 문제를 해결할 수는 있지만, 이는 올바른 첫 번째 대응이 아닙니다. 서비스가 중단될 뿐만 아니라 증거가 인멸되기 때문입니다. 시도해야 할 순서대로 네 가지 더 안전한 방법이 있습니다.

데이터가 필요하다면 먼저 외부로 복사하십시오. 디스크립터 경로를 읽으면 현재 활성화된 inode를 읽을 수 있습니다.

sudo cp /proc/<pid>/fd/<n> /root/recovered.log

이것이 삭제된 파일을 쉽게 복구할 수 있는 유일한 경우이며, rm -rf로 삭제된 파일 복구하기에서 프로세스가 여전히 파일을 열고 있는지 먼저 확인하는 이유입니다. 마지막 디스크립터가 닫히면 해당 경로는 사라집니다.

둘째, 디스크립터를 통해 파일 내용을 비우십시오. /proc 경로는 동일한 inode를 가리키므로, 파일을 자르면(truncate) 프로세스가 계속 실행 중인 상태에서도 블록이 해제됩니다.

sudo truncate -s 0 "/proc/$pid/fd/$n"
df -h /

이 방법은 쓰기 프로세스가 파일을 append 모드로 열었을 때 깔끔하게 작동합니다. 모든 쓰기 작업이 파일의 현재 끝부분에서 이루어지기 때문입니다. 그렇지 않은 경우, 프로세스는 기존의 쓰기 오프셋을 유지하므로 다음 쓰기 작업이 파일의 훨씬 뒤쪽에서 수행되어 앞부분에 빈 공간(hole)이 생기게 됩니다. 빈 공간은 할당되지 않으므로 블록은 계속 비어 있고 df는 방금 반환한 공간을 유지합니다. 다시 늘어나는 것은 파일 크기뿐입니다. 프로세스가 쓰기를 수행한 후 sudo stat -L "/proc/$pid/fd/$n"를 다시 실행하면, 블록 개수와 일치하지 않는 이전 크기가 표시됩니다. 파일 크기까지 0부터 다시 시작하게 하려면 프로세스를 재시작하십시오.

셋째, 서비스에 로그 파일을 다시 열도록 요청하십시오. 로그 파일이 삭제된 데몬은 이 문제의 가장 흔한 실제 사례입니다. 많은 데몬이 시그널을 받으면 로그 파일을 다시 엽니다. nginx는 SIGUSR1을 사용하고 rsyslog는 SIGHUP을 사용합니다. 잘못된 시그널을 보내면 데몬이 중단될 수 있으므로, 추측하지 말고 해당 데몬의 문서를 확인하십시오.

sudo systemctl kill -s USR1 nginx

넷째, 유닛을 재시작하십시오. sudo systemctl restart <unit>은 이전 프로세스가 보유했던 모든 디스크립터를 닫으므로 블록이 확실하게 반환됩니다. 위 예시에서 파일을 점유한 주체는 직접 실행한 sleep이므로, 이를 종료하는 것만으로 충분합니다.

kill $holder
df -h .
df --output=used -B1 .
sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null

사용 중인 바이트 수를 파일을 생성하기 전에 기록해 둔 값과 비교하십시오. 두 값이 다시 일치하며 find은 더 이상 해당 디스크립터를 보고하지 않습니다. 문제를 발견했던 동일한 명령어로 확인하는 습관을 들이는 것이 좋습니다.

값을 수동으로 계속 확인하는 것보다 변화를 지켜보는 것이 더 쉽습니다. watch는 고정된 간격으로 명령어를 반복하여 출력을 제자리에 다시 표시하므로, df와 함께 사용하면 watch df -h /을 통해 공간이 확보됨에 따라 사용량 열이 변하는 것을 확인할 수 있습니다.

합계는 일치하지만 디스크가 여전히 가득 찬 경우

df과 루트 du -x의 결과가 일치한다면, 삭제된 파일로 인한 문제는 아닙니다. 남은 원인들은 성격이 다르며, 각각 별도의 확인 절차가 필요합니다.

블록은 남았으나 아이노드(inode)가 부족한 경우

아이노드는 파일 하나에 대한 메타데이터를 담고 있습니다. ext4는 파일시스템을 생성할 때 아이노드 개수를 고정하므로, 블록은 남아있어도 아이노드가 먼저 소진될 수 있습니다. 이 경우 df -h 명령어로 확인했을 때 여유 공간이 있어도 새로운 파일을 생성할 수 없습니다.

df -h /
df -i /

첫 번째 명령어는 블록을, 두 번째 명령어는 아이노드를 계산합니다. 각 결과의 사용량(use) 열을 비교하십시오. 블록 사용량은 낮지만 아이노드 사용량이 한계치에 도달했다면, 매우 작은 파일이 다수 생성된 것이 원인입니다.

df는 동일한 호출에서 -i--output을 동시에 사용할 수 없습니다. 따라서 원시 데이터를 읽거나 다른 명령어로 전달해야 할 때는 -i 옵션을 제외하고 아이노드 필드만 선택하십시오.

df --output=itotal,iused,iavail,ipcent /

이 열들은 df -i이 출력하는 것과 동일한 계정 정보를 담고 있으며, 파싱하기 쉬운 형태로 제공됩니다.

바이트 단위가 아닌 항목 개수를 세어 파일을 찾으십시오.

sudo du --inodes -x -d 1 / 2>/dev/null | sort -rn | head

가장 많은 항목이 나온 디렉터리를 대상으로 동일한 명령어를 하위 단계에서 반복하여, 파일을 생성하는 경로를 찾을 때까지 추적하십시오. 사용 중인 du--inodes 옵션을 지원하지 않는다면, sudo find /var -xdev -type f | wc -l을 사용하여 하위 트리를 느리게 계산할 수 있습니다.

해결책은 해당 파일들을 삭제하거나 이동하는 것입니다. 기존 ext4 파일시스템의 아이노드 개수는 mkfs 시점에 고정되므로 임의로 늘릴 수 없습니다. 아이노드 개수를 늘리려면 파일시스템을 다시 생성하고 백업에서 데이터를 복구해야 합니다. XFS는 필요에 따라 아이노드를 할당하므로 이와 같은 고정된 제한을 겪지 않습니다. 컨테이너를 실행하는 서버는 이미지 레이어에 작은 파일이 많아 두 제한 모두에 더 빨리 도달합니다. 해당 환경에서는 VPS에서 Docker 디스크 사용량 정리하기가 구체적인 해결책이며, 일반적인 파일시스템 정리보다 훨씬 많은 공간을 확보할 수 있습니다.

마운트 지점 아래에 숨겨진 공간

디렉터리에 무언가를 마운트하기 전에는 해당 디렉터리에 파일이 존재할 수 있습니다. 그 디렉터리 위에 파일 시스템을 마운트하면, 아래에 있던 파일들은 그대로 남습니다. 여전히 할당된 상태이며 df에 의해 용량도 계산되지만, 이름으로는 더 이상 접근할 수 없습니다. 마운트가 해당 경로를 덮어버리기 때문에 du는 그 파일들을 볼 수 없습니다.

별도의 디스크가 필요 없는 tmpfs를 사용하여 이를 확인해 봅니다. 이 과정은 마운트 권한이 있는 환경이 필요하므로 KVM VPS에서 수행할 수 있습니다.

sudo mkdir -p /srv/covered
sudo cp /etc/services /srv/covered/
ls /srv/covered
sudo mount -t tmpfs tmpfs /srv/covered
ls /srv/covered
sudo umount /srv/covered
ls /srv/covered

중간의 ls는 빈 디렉터리를 보여줍니다. 복사한 파일은 어디로 사라진 것이 아닙니다. 여전히 루트 파일 시스템에 남아 있으며, 마운트를 해제하는 즉시 다시 나타납니다. 누군가 볼륨을 마운트하기 전까지 한 달 동안 해당 경로에 로그를 기록하던 서비스를 상상해 보십시오.

운영 중인 서버에서 실제 파일을 찾으려면, 루트 파일 시스템을 다른 곳에 한 번 더 마운트하면 됩니다. 바인드 마운트는 내부에 마운트된 다른 파일 시스템을 제외하고 해당 파일 시스템만을 보여줍니다.

sudo mkdir -p /mnt/rootcheck
sudo mount --bind / /mnt/rootcheck
sudo du -xhs /mnt/rootcheck/* 2>/dev/null | sort -h
sudo umount /mnt/rootcheck

일반 경로에서는 보이지 않지만 해당 목록에 나타나는 모든 것은 마운트 지점 아래에 묻혀 있는 것입니다. 작업이 끝나면 바인드 마운트를 해제하십시오. 그렇지 않으면 -x 옵션이 없는 du은 동일한 파일을 두 번 계산하게 됩니다.

root 사용자를 위해 예약된 블록

ext4는 디스크가 가득 차더라도 root 사용자가 로그인하여 시스템을 복구할 수 있도록 블록의 일부를 예약해 둡니다. 일반 사용자로 실행되는 프로세스는 디스크가 꽉 차면 즉시 쓰기 오류가 발생하지만, df 명령을 실행하면 여전히 약간의 공간이 남아 있는 것으로 표시됩니다. 기본값을 가정하지 말고 자신의 파일 시스템 설정을 직접 확인하십시오.

dev=$(df --output=source / | tail -n 1)
sudo tune2fs -l "$dev" | grep -i 'block count'

tune2fs -l /dev/sda1 | grep -E 'Block count|Reserved block count'

이 명령은 전체 블록 수와 예약된 블록 수를 동일한 단위로 출력하므로, 두 값의 비율을 즉시 확인할 수 있습니다. df 명령은 일반 사용자가 사용할 수 있는 공간을 'available' 열에 표시하며, 이것이 바로 'used'와 'available'을 더한 값이 전체 크기보다 작게 나오는 이유입니다. 그 차이만큼이 예약된 공간입니다.

예약 공간을 변경하려면 sudo tune2fs -m <percent> "$dev" 명령을 사용하십시오. 변경 사항은 즉시 적용되며 리마운트가 필요하지 않습니다. 별도의 데이터 파일 시스템이라면 예약 공간을 줄이는 것이 합리적입니다. 하지만 루트 파일 시스템의 경우 root 사용자가 여전히 쓰기 작업을 수행할 수 있도록 충분한 공간을 남겨두어야 합니다. 루트 파일 시스템에 여유 공간이 전혀 없으면 복구가 훨씬 어렵기 때문입니다. tune2fs 명령은 ext2, ext3, ext4 파일 시스템에서 작동합니다. XFS에는 이와 대응하는 설정이 없습니다.

du 명령이 오해를 불러일으키는 경우

du의 네 가지 습관으로 인해 합계가 잘못된 것처럼 보일 수 있습니다.

  • 하드 링크: du은 여러 이름이 하나의 inode를 가리키더라도 해당 inode를 한 번만 계산합니다. 따라서 하드 링크가 가득 찬 트리는 실제 파일 크기의 합보다 작게 보고됩니다.
  • 스파스 파일: du는 실제로 할당된 블록을 보고하지만, ls -l는 명목상 크기를 보고합니다. 다른 수치를 확인하려면 --apparent-size을 추가하십시오.
  • 권한: 일반 사용자로 실행하면 du은 읽을 수 없는 파일을 건너뛰며, 결과값이 실제보다 적게 보고됩니다. 이때 출력되는 오류 메시지는 사용자가 흔히 /dev/null로 리다이렉트하여 무시해 버리는 내용입니다.
  • 파일 시스템 경계: -x 옵션이 없으면 du // 하위에 마운트된 모든 파일 시스템을 계산합니다. 따라서 그 합계가 df /의 보고 내용보다 클 수 있습니다.

df 또한 알아두어야 할 습관이 하나 있습니다. 이 명령은 각 파일 시스템을 별도로 보고하므로, 쓰기 실패가 발생한 정확한 경로를 대상으로 실행해야 합니다. 별도의 /boot는 커널 패키지가 누적됨에 따라 자체적인 일정에 맞춰 용량이 차오르며, Ubuntu에서 오래된 커널 제거하기/의 공간을 확보하는 작업과는 별개의 작업입니다.

실제 장애 발생 시 대응 절차

  1. 쓰기 실패가 발생한 대상 파일 시스템에서 df -h <path>df -i <path>을 실행하십시오. 반사적으로 /에서 실행해서는 안 됩니다.
  2. sudo du -xh -d 1 <mountpoint> 2>/dev/null | sort -h를 실행한 뒤, 가장 용량이 큰 디렉터리로 이동하십시오.
  3. du의 결과와 df이 보고하는 사용량이 일치하지 않는다면, /proc를 검색하여 삭제되었으나 여전히 열려 있는 파일을 찾으십시오.
  4. 두 도구의 결과가 일치한다면, 파일 시스템을 다른 경로에 바인드 마운트(bind mount)한 뒤 마운트 지점 아래에 숨겨진 파일이 있는지 확인하십시오.
  5. inode 사용량이 한계치에 도달했다면, 바이트 단위가 아닌 파일 개수를 세어 확인하십시오.

위의 각 단계는 출력 결과를 직접 읽을 수 있는 명령어로 구성되어 있습니다. 이것이 문제를 추측으로 해결하는 것과 명확하게 해결하는 것의 차이입니다.

FAQ

df 명령은 디스크가 꽉 찼다고 나오는데 du 명령은 훨씬 적게 사용하는 이유는 무엇입니까?

일반적인 원인은 프로세스가 파일을 열어둔 상태에서 해당 파일이 삭제되었기 때문입니다. 파일을 삭제하면 디렉터리 항목에서 제거되므로 du은 파일 이름을 찾을 수 없어 계산을 멈춥니다. 하지만 마지막 파일 기술자(descriptor)가 닫힐 때까지 inode와 데이터 블록은 할당된 상태로 유지되며, df는 할당된 블록을 모두 계산합니다. /proc/<pid>/fd에서 대상이 삭제된 것으로 표시된 심볼릭 링크를 검색하면 해당 파일과 이를 점유 중인 프로세스를 찾을 수 있습니다. 비교 결과를 신뢰하기 전에 du-x 옵션과 함께 root 권한으로 실행했는지 확인하십시오. 일반 사용자로 실행하면 읽기 권한이 없는 디렉터리는 조용히 건너뛰기 때문입니다.

lsof 없이 열려 있는 삭제된 파일을 어떻게 찾습니까?

커널이 관리하는 열린 기술자 기록을 사용하십시오. sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null은 이름이 없는 파일을 가리키는 모든 기술자를 나열하며, 출력되는 경로 안에 프로세스 ID가 포함되어 있습니다. 해당 기술자 경로 중 하나에 sudo stat -Lc %s를 실행하면 파일 크기를 확인할 수 있으므로, 이를 정렬하여 중요한 파일을 골라낼 수 있습니다. 이 방법은 별도의 패키지 설치가 필요 없으며, 디스크 공간이 부족하여 패키지 설치가 실패할 수 있는 상황에서 유용합니다.

프로세스를 종료하지 않고 공간을 확보할 수 있습니까?

가능할 때가 있습니다. sudo truncate -s 0 /proc/<pid>/fd/<n>은 기술자를 통해 동일한 inode에 접근하여 프로세스가 실행 중인 상태에서도 블록을 해제합니다. 프로세스가 파일을 append 모드로 열었다면 쓰기 작업이 항상 파일 끝에서 이루어지므로 가장 깔끔하게 처리됩니다. 그렇지 않은 경우 쓰기 오프셋이 그대로 유지되어, 다음 쓰기 작업 시 파일 앞부분에 빈 공간(hole)이 생기며 파일이 다시 생성됩니다. 이 경우 보고되는 크기는 다시 늘어나지만 빈 공간 아래의 블록은 계속 비어 있게 됩니다. 서비스를 재시작하거나, 문서에 명시된 신호를 보내 로그 파일을 다시 열도록 하는 것이 sparse 파일을 남기지 않는 올바른 해결책입니다.

df에서는 여유 공간이 있다고 나오는데 쓰기 작업이 실패하는 이유는 무엇입니까?

df -i을 사용하여 동일한 경로의 inode 상태를 확인하십시오. 빈 블록이 있더라도 빈 inode가 없으면 새 파일을 생성할 수 없습니다. root가 아닌 사용자가 ext4 파일시스템에 쓰기를 시도할 때 예약된 블록만 남은 상태일 수 있으며, 이는 장치에 sudo tune2fs -l를 실행하여 확인할 수 있습니다. 또한 쓰기 작업이 실제로 수행되는 파일시스템을 확인하십시오. 별도의 /boot이나 /var/와 독립적으로 용량이 차오르기 때문입니다.

왜 du가 df보다 더 큰 합계를 보고합니까?

du-x 옵션 없이 실행하면 지정한 경로 아래에 마운트된 모든 파일시스템으로 넘어가기 때문에 여러 파일시스템의 용량을 합산합니다. 반면 df은 하나의 파일시스템만 설명합니다. 바인드 마운트가 되어 있다면 동일한 파일이 각 경로마다 중복 계산되므로 문제가 더 심각해집니다. -x 옵션을 추가하여 du이 단일 파일시스템 내에 머물도록 하고, df에도 동일한 경로를 지정하여 두 명령이 같은 대상을 설명하도록 하십시오.