정렬된 목록에서 디스크를 채울 파일 수 결정

정렬된 목록에서 디스크를 채울 파일 수 결정

이것은 나를 혼란스럽게 만듭니다. 나는 이것이 쉬울 것이라고 생각했지만 결과가 일관되지 않기 때문에 뭔가 빠진 것 같습니다.

저는 rsync를 사용하여 긴 파일 목록을 여러 디스크에 백업하고 있으며, 가장 오래된 파일이 첫 번째 디스크에 있고 나중에 파일이 두 번째 디스크에 있도록 시간순으로 정렬된 목록을 사용하고 있습니다.

목록을 살펴보고 파일 크기(4k 블록 단위)를 합산한 다음, 맞는 마지막 파일의 날짜를 기록해 둡니다. 그런 다음 "find -not -newer and -newer"를 사용하여 목록을 만듭니다.

STARTDATE="-newer /tmp/filedate.1"
ENDDATE="-not -newer /tmp/filedate.2"
find $SRC -type f ${STARTDATE} ${ENDDATE} -printf '%P\n' | sort > ${TEMPFILE}

그리고 "--files-from"을 사용하여 rsync에 공급하여 실제로 복사합니다.

rsync -a --progress --verbose --prune-empty-dirs --files-from=${TEMPFILE} ${SRC} ${TARGET}

디스크가 꽉 차도록 파일이 분할된 위치를 정확히 알고 싶습니다.

내가 지금 가지고 있는 것:

#%T is the modification time, @ is seconds, 
#%p is the path less the command line part, and %k is disk usage in 1k blocks
#MAXSIZE is number of 4k blocks available on disk
    find $SRC -printf "%T@\t%p\t%k\n" | sort -n | \
    awk -vMS="$MAXSIZE"  '
      BEGIN { FS = "\t";fnumber = 0 }
      {rtot+=int(($3+3)/4); #edit; changed to ceiling on AlexP's advice
       if (rtot<MS) {final=$2;filesize=rtot;}
       else {
            rtot=int(($3+3)/4); #edit; changed to ceiling on AlexP's advice
            fnumber++;
            printf "touch -r \"%s\" /tmp/filedate.%s\n", final, fnumber | "/bin/sh"
            print "Found point " fnumber ". (" final ") 4096 Blocks:"  filesize " Space Left:" (MS-filesize)*4
            }
      }
    '

디스크 세부정보는 다음과 같습니다.

    #tune2fs -l /dev/sdzc1
    tune2fs 1.41.4 (27-Jan-2009)
    Filesystem volume name:   <none>
    Last mounted on:          /share/external/sdzc1
    Filesystem UUID:          f3f2e855-b198-4d47-b76f-6526d16b0820
    Filesystem magic number:  0xEF53
    Filesystem revision #:    1 (dynamic)
    Filesystem features:      has_journal ext_attr resize_inode filetype needs_recovery extent flex_bg sparse_super large_file
huge_file uninit_bg dir_nlink extra_isize
    Filesystem flags:         signed_directory_hash
    Default mount options:    (none)
    Filesystem state:         clean
    Errors behavior:          Continue
    Filesystem OS type:       Linux
    Inode count:              122101760
    Block count:              488378007
    Reserved block count:     0
    Free blocks:              89451
    Free inodes:              122088914
    First block:              0
    Block size:               4096
    Fragment size:            4096
    Reserved GDT blocks:      907
    Blocks per group:         32768
    Fragments per group:      32768
    Inodes per group:         8192
    Inode blocks per group:   512
    Flex block group size:    16
    Filesystem created:       Sun May 11 13:45:08 2014
    Last mount time:          Wed Dec  7 11:44:24 2016
    Last write time:          Wed Dec  7 11:44:24 2016
    Mount count:              68
    Maximum mount count:      28
    Last checked:             Fri Feb 20 02:06:42 2015
    Check interval:           15552000 (6 months)
    Next check after:         Wed Aug 19 02:06:42 2015
    Reserved blocks uid:      0 (user admin)
    Reserved blocks gid:      0 (group administrators)
    First inode:              11
    Inode size:               256
    Required extra isize:     28
    Desired extra isize:      28
    Journal inode:            8
    First orphan inode:       75890825
    Default directory hash:   half_md4
    Directory Hash Seed:      1c7f838c-8614-4af0-8506-cd3659e1e5ac
    Directory Magic Number:   0x514E4150
    Journal backup:           inode blocks

그래서 제 생각에는 488378007개의 4096바이트 블록과 122101760개의 256바이트 inode가 있는 것 같습니다. 따라서 쓰기 가능한 바이트는 (488378007 x 4096) - (122101760 x 256)바이트 여야 합니다. 이는 1,969,138,264,064 또는 1,922,986,586kB입니다.

df는 총 1,922,858,380개의 1k 블록(128,206개의 차이) = 480,714,595개의 4k 블록을 보여줍니다.

그럼에도 불구하고 최종 결과는 실제로 파일을 복사할 때 awk 출력에 의해 보고된 "남은 공간"이 실제 남은 공간과 같지 않다는 것입니다. 아래 이미지를 시작점으로 사용하더라도 다음과 같습니다.수량이 다릅니다, 때로는 공간이 완전히 부족할 때도 있습니다.

내 논리에 무슨 문제가 있습니까? MAXSIZE를 줄여서 퍼지할 수 있다는 것을 알고 있지만 제가 무엇을 놓치고 있는지 정말 알고 싶습니다!

PS 나는 이것을 루트로 실행하고 있으므로 예약된 공간은 관련이 없습니다.

실제 질문을 명확히 하기 위해 파일 및 디렉터리 크기(전체 4k 블록)를 합산하여 총 디스크 사용량을 얻을 수 있어야 합니까?

추가 편집: 더 혼란스럽게 하기 위해 방금 드라이브를 채웠고(?) df -k에서 이것을 얻었습니다.

Filesystem      1K-blocks       Used Available Use% Mounted on
/dev/sdzb1     2927209048 2925317912         0 100% /share/external/sdzb1

2927209048-2925317912=1891136 학창시절 쓰던거랑 똑같네요!

답변1

두 가지 관찰:

  • 파일이 사용하는 블록 수를 줄이는 것이 아니라 반올림해야 합니다. 파일 길이가 8192+1바이트인 경우 마지막 바이트에는 4KiB 블록이 할당됩니다. ("조각 크기"가 4KiB이기 때문입니다.)

  • 파일에 필요한 디스크 공간은 파일의 바이트 수를 보유하는 데 필요한 데이터 블록 수와 반드시 같지는 않습니다. 이는 약간 더 클 수도 있고(할당된 블록을 매핑하기 위해 더 많은 메타데이터가 필요한 큰 파일의 경우) 약간 더 작을 수도 있습니다(inode에 완전히 저장할 수 있는 매우 작은 파일의 경우). 또한 Stephen Kitt 사용자가 언급했듯이 전체 질문은 다음과 같습니다.스파스 파일, 이는 디스크에서 차지하는 공간보다 훨씬 클 수 있으며 다른 파일 시스템에 보관하거나 복사할 때 흥미로운 문제를 일으킬 수 있습니다.

  • 일부 파일 시스템은 자체 목적으로 일부 디스크 공간을 사용할 수 있습니다. 또한 사용된 디스크 공간이 용량에 가까워지면 파일 시스템이 실패하는 경향이 있습니다. 실제로 디스크를 98% 또는 99% 이하로 꽉 채울 계획을 세워야 합니다.

답변2

나는 내 생각에 기여하고 지도해 준 모든 사람에게 감사하면서 내 자신의 질문에 답할 것입니다.

디스크에 쓸 때 공간이 할당되는 방식은 파일 크기와 유형, 희소 파일 등에 따라 다르기 때문에 실제로 얼마나 많은 공간을 차지하게 될지 미리 정확하게 예측하는 것은 불가능하지는 않더라도 매우 어렵습니다.

삭제된 파일의 디렉터리는 처음 생성되었을 때보다 더 커질 수 있으며, 이 공간은 복구되지 않습니다. (디렉토리를 삭제하고 다시 생성하지 않는 한) 빈 디렉토리는 공간을 차지합니다.

Find는 특별히 요청하지 않는 한 디렉토리를 보고하지 않습니다.

공간은 전체 블록으로 기록되며 블록 크기는 디스크마다 다를 수 있으며 e2fsdump에서 읽을 수 있습니다.

'df'는 여유 공간보다 사용된 블록이 적다고 보고하더라도 약 98% 이후에는 여유 공간이 없다고 보고합니다.

# df -B4k --sync
Filesystem      4K-blocks       Used Available Use% Mounted on
/dev/sdzb1      731802262  731493169         0 100% /share/external/sdzb1
/dev/sdzc1      731802262  717225328         0 100% /share/external/sdzc1

'du'는 'df'와 다른 사용법을 보고합니다.

# du -B4k -s /share/external/sdzb1 /share/external/sdzc1
731441722       /share/external/sdzb1
717173881       /share/external/sdzc1

그럼에도 불구하고 사용 가능한 공간을 사용하여 초기 시작점이 가능합니다.

Space = (Total blocks x blocksize) - (Total inodes x inode size)

그리고 상당히 정확한 결과를 얻으려면 300,000~500,000의 블록 마진을 허용하십시오. (약 1% 이내)

관련 정보