XFS는 CoW(기록 중 복사)를 지원하므로 du
일부 바이트가 파일 간에 공유되는 경우 어떤 일이 발생하는지 완전히 명확하지 않습니다. 공유 바이트를 여러 번 계산하지 않고 폴더가 사용하는 디스크 공간, 즉 디스크의 실제 사용량을 확인하는 방법을 찾고 싶습니다.
xfs_estimate
du
둘 다 내가 필요한 것을 수행하지 않는 것 같습니다 .
$ mkdir testfolder
$ cd testfolder
$ dd if=/dev/zero of=testfile bs=1M count=500 status=progress
500+0 records in
500+0 records out
524288000 bytes (524 MB, 500 MiB) copied, 0,158889 s, 3,3 GB/s
$ cp --reflink=always testfile testfile2
$ xfs_estimate .
. will take about 1004,4 megabytes
$ du -hs .
1000M .
내가 기대하는 것은 일부 도구에서 폴더가 500MB만 사용하고 있다고 말하는 것입니다.
df
cp
plain을 사용 하면 디스크 여유 공간이 500MB 적게 표시되지만, cp --reflink=always
다시 연결하면 작동하는 것처럼 보이지만 df
디스크가 상당히 크고 다소 작은 폴더의 실제 크기를 확인하고 싶었기 때문에 실제로는 도움이 되지 않습니다.
나는 이것이 BTRFS에도 유효한 질문이라고 생각합니다. 하지만 제 경우에는 XFS와 호환되는 솔루션이 필요합니다.
답변1
기본적으로 이 작업을 수행하는 도구가 있어야 할 것 같지만 그런 도구가 있는지 기억이 나지 않습니다.
filefrag
(일반, FIEMAP ioctl) 또는 (XFS 특정)을 사용하여 xfs_bmap
파일 범위를 쿼리 할 수 있습니다 . 이렇게 하면 커뮤니티(중복)를 한 번만 계산하거나 전혀 계산하지 않도록 선택할 수 있습니다.
# filefrag -e -k testfile
Filesystem type is: 58465342
File size of testfile is 5242880 (5120 blocks of 1024 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 5119: 96.. 5215: 5120: last,shared,eof
testfile: 1 extent found
이 예에서 filefrag
범위가 공유된다는 것을 알고 표시하는 것은(반드시 해당 디렉토리 내일 필요는 없지만 파일 시스템의 어느 곳에서나) 다음을 xfs_bmap
수행하지 않습니다.
# xfs_bmap -l testfile
testfile:
0: [0..10239]: 192..10431 10240 blocks
그러나 기본적으로 이는 자신만의 스크립트를 작성하는 데 사용할 수 있는 핵심 요소입니다.
가능한 모든 공유 범위를 표시합니다.
# find . -xdev -type f -exec filefrag -e -k {} + | grep shared
0: 0.. 5119: 96.. 5215: 5120: last,shared,eof
0: 0.. 5119: 5216.. 10335: 5120: last,shared,eof
0: 0.. 5119: 96.. 5215: 5120: last,shared,eof
공유(디렉토리 내 중복) 범위 사용법 xfs_bmap
:
# find . -xdev -type f -exec xfs_bmap -l {} + | grep 'blocks$' | grep -v ': hole' | sort | uniq -d
0: [0..10239]: 192..10431 10240 blocks
각 블록 은 1024바이트( 옵션 포함) 또는 파일 시스템 블록 크기(예: 4096바이트) xfs_bmap
가 아닌 512바이트를 사용합니다 .filefrag
-k
다음을 사용하여 반복 범위를 공유합니다 filefrag
.
# find . -xdev -type f -exec filefrag -ek {} + | grep shared | sort | uniq -d
0: 0.. 5119: 96.. 5215: 5120: last,shared,eof
따라서 이 경우 du -cks .
결과에서 5120을 빼야 합니다.
답변2
내 파일이 실제로 얼마나 많은 공간을 사용하고 있는지, 다른 파일과 얼마나 많은 공간을 공유하고 있는지 알아보려고 합니다. 다음과 비교하여 일부 바이트에서 "총계"가 다른 이유가 무엇인지 잘 모르겠습니다 du
.
file="/mnt/cache/domains/Windows 10/vdisk1-backup.img"
du -h "$file"
mapfile -t fragments < <( filefrag -ek "$file" | tail -n +4 | cut -d ":" -f 4 | grep -oP "[0-9]+" )
sum=$(IFS=+; echo "$((${fragments[*]}))")
sum=$((sum * 1024))
sum=$(echo "$sum" | numfmt --to=iec)
echo "$sum total"
mapfile -t fragments < <( filefrag -ek "$file" | tail -n +4 | grep "shared" | cut -d ":" -f 4 | grep -oP "[0-9]+" )
sum=$(IFS=+; echo "$((${fragments[*]}))")
sum=$((sum * 1024))
sum=$(echo "$sum" | numfmt --to=iec)
echo "$sum shared"
mapfile -t fragments < <( filefrag -ek "$file" | tail -n +4 | grep -v "shared" | cut -d ":" -f 4 | grep -oP "[0-9]+" )
sum=$(IFS=+; echo "$((${fragments[*]}))")
sum=$((sum * 1024))
sum=$(echo "$sum" | numfmt --to=iec)
echo "$sum unique"
산출:
15G /mnt/cache/domains/Windows 10/vdisk1-backup.img
15G total
8.3G shared
6.8G unique
답변3
저는 Veeam 커뮤니티 페이지에서 이에 대한 솔루션을 제안했습니다.
고유한:
(Veeam) CloudConnect를 사용하는 고객의 실제 디스크 사용량을 기준으로 요금을 청구하므로 기존 보고서는 보고 및 청구에 사용할 수 없습니다(사전 중복 제거/재연결 데이터 보고). 그것을 알아내는 데 시간이 좀 걸렸지만 불변 저장소의 각 디렉터리가 사용하는 실제 디스크 공간을 계산하는 방법이 있습니다.
해결책:
불변 저장소에서 각 폴더(IE: 클라이언트)의 디스크 사용량을 제공하는 스크립트를 추론했습니다. 이는 "사용된 데이터"가 아니며 Veeam의 보고입니다. 이것은 "사용된 디스크"입니다. 참조 연결 후 디스크의 실제 크기(중복 데이터는 한 번만 계산됨)
이 스크립트에 대한 참고 사항은 원래 블로그 항목의 청크 크기가 잘못된 것 같습니다. 그들은 이를 4096으로 간주합니다... 이는 디스크에서는 정확하지만... 사용된 유틸리티는 명시적으로 블록 크기를 512로 제공합니다. https://linux.die.net/man/8/xfs_bmap "512바이트 블록 단위"
이 스크립트를 사용하기 위해 cron 작업을 사용하고 출력을 저장소 자체의 메일 클라이언트로 파이프합니다(예: script.bash 2>&1 | mail -s "$HOSTNAME에 대한 Immutable Storage Report"[이메일 보호됨])
#!/bin/bash
for clientDir in `find /backups/disk-01/backups/ -mindepth 1 -maxdepth 1 -type d`
do
echo $clientDir
clientSpaceUsed=$(find $clientDir/*/* -xdev -type f -exec xfs_bmap -l {} + | awk '{ print $3 " " $4 }' | sort -k 1 | uniq | awk '{ print $2 }' | grep -Eo '[0-9]{1,7}' | paste -sd+ | bc | awk '{print $1*512/1024/1024/1024}')
#block sizes of 512 bytes. Divided by 1024 for KB. Divided by 1024 for MB. Divided by 1024 for GB.
echo "$clientSpaceUsed GB"
done
작동 방식을 분석하면 다음과 같습니다.
"/backups/disk-01/backups/"의 각 클라이언트 디렉터리에 대해
보고되는 디렉터리를 출력합니다.
xfs_bmap -l 실행(문제의 블록에 대한 모든 것을 알려줍니다) 열 3과 4 가져오기(이제 열 1과 2가 되고 나머지는 삭제됨) 열 1별로 정렬 데이터의 중복 행 제거(빠른 복제를 위한 참조 링크; 유지 계산 목적으로 데이터의 단일 복사본) 열 2만 선택(현재 열 1)
숫자를 제외하고 모두 제거
이 숫자들을 함께 더하세요
블록 크기를 곱합니다(512).
1024로 나눕니다(현재 KB).
1024로 나눕니다(현재 MB 단위).
1024로 나눕니다(현재 GB 단위).
출력 텍스트
답변4
와 유사한 실제 여유 공간을 알고 싶다면 을 df
사용하십시오 xfs_spaceman
.
예를 들어:
xfs_spaceman -c 'freesp -s -m4096' /path/to/xfs/mount
계산은 느릴 수 있지만 보고된 "총 여유 블록 수"는 참조 링크/중복 제거 데이터에 대해 정확하며 블록 크기를 곱하여 실제 여유 공간(바이트)을 얻을 수 있습니다.