다른 파일 시스템을 포함하는 파일이 왜 그렇게 조각화되어 있습니까?

다른 파일 시스템을 포함하는 파일이 왜 그렇게 조각화되어 있습니까?

내가 방금 발견한 것스파스 파일네, 그리고 그것들에 대해 몇 가지 실험을 하고 싶습니다. 위키에서 이러한 파일이 쉽게 조각화될 수 있다는 것을 읽을 수 있습니다. 얼마나 나쁜지 확인하고 싶었습니다. 다음을 통해 파일을 만들었습니다.

# truncate -s 10G sparse-file
# mkfs.ext4 -m 0 -L sparse ./sparse-file

제가 마운트한 것은 희소한 파일인데, 그 안에 600M 파일이 들어 있었습니다. 조각화 수준은 다음과 같습니다.

# filefrag -v "/media/Grafi/sparse-file"
Filesystem type is: ef53
File size of /media/Grafi/sparse-file is 10737418240 (2621440 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..    1032:      36864..     37896:   1033:
   1:     1043..    1043:      37907..     37907:      1:
   2:     1059..    1059:      37923..     37923:      1:
   3:     9251..    9256:      46115..     46120:      6:
   4:    32768..   32770:      51200..     51202:      3:      69632:
   5:    34816..   55295:      77824..     98303:  20480:      53248:
   6:    55296..   57343:     114688..    116735:   2048:      98304:
   7:    57344..   69631:     120832..    133119:  12288:     116736:
   8:    69632..   81919:     102400..    114687:  12288:     133120:
   9:    81920..   98303:     135168..    151551:  16384:     114688:
  10:    98304..   98306:      57344..     57346:      3:     151552:
  11:   100352..  112639:     151552..    163839:  12288:      59392:
  12:   112640..  145407:     165888..    198655:  32768:     163840:
  13:   145408..  163839:     198656..    217087:  18432:
  14:   163840..  163842:      40960..     40962:      3:     217088:
  15:   165888..  178175:     217088..    229375:  12288:      43008:
  16:   178176..  202751:     231424..    255999:  24576:     229376:
  17:   202752..  206847:     258048..    262143:   4096:     256000:
  18:   206848..  216756:     276480..    286388:   9909:     262144:
  19:   229376..  229378:      43008..     43010:      3:     299008:
  20:   294912..  294914:      53248..     53250:      3:     108544:
  21:   524288..  524288:      55296..     55296:      1:     282624:
  22:   819200..  819202:      61440..     61442:      3:     350208:
  23:   884736..  884738:      63488..     63490:      3:     126976:
  24:  1048576.. 1048577:      67584..     67585:      2:     227328:
  25:  1081344.. 1081391:      69632..     69679:     48:     100352:
  26:  1572864.. 1572864:      71680..     71680:      1:     561152:
  27:  1605632.. 1605634:      73728..     73730:      3:     104448:
  28:  2097152.. 2097152:      75776..     75776:      1:     565248:
  29:  2097167.. 2097167:      75791..     75791:      1:             last
/media/Grafi/sparse-file: 25 extents found

나는 이것이 "sparse" 기능 때문이라고 생각했는데, 다른 파일 시스템을 포함하는 모든 파일이 이런 식으로 조각화되는 것처럼 보입니다. 다음 예를 살펴보십시오.

모두 0으로 구성된 파일을 만듭니다.

# dd if=/dev/zero of=./zero bs=1M count=2048 

조각화 수준을 확인합니다.

# filefrag -v /media/Grafi/zero
Filesystem type is: ef53
File size of /media/Grafi/zero is 2147483648 (524288 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..   32767:    6172672..   6205439:  32768:
   1:    32768..   65535:    6205440..   6238207:  32768:
   2:    65536..   98303:    6238208..   6270975:  32768:
   3:    98304..  118783:    6270976..   6291455:  20480:
   4:   118784..  151551:    6324224..   6356991:  32768:    6291456:
   5:   151552..  184319:    6356992..   6389759:  32768:
   6:   184320..  217087:    6389760..   6422527:  32768:
   7:   217088..  249855:    6422528..   6455295:  32768:
   8:   249856..  282623:    6455296..   6488063:  32768:
   9:   282624..  315391:    6488064..   6520831:  32768:
  10:   315392..  348159:    6520832..   6553599:  32768:
  11:   348160..  380927:    6553600..   6586367:  32768:
  12:   380928..  413695:    6586368..   6619135:  32768:
  13:   413696..  446463:    6619136..   6651903:  32768:
  14:   446464..  479231:    6651904..   6684671:  32768:
  15:   479232..  511999:    6684672..   6717439:  32768:
  16:   512000..  524287:    6717440..   6729727:  12288:             last,eof
/media/Grafi/zero: 2 extents found

따라서 기본적으로 이 파일에는 17개의 범위가 있지만 사람의 관점에서 보면 파일에는 두 개의 블록이 있습니다.

이제 이 파일에 파일 시스템을 만듭니다.

# mkfs.ext4 -m 0 -L ext /media/Grafi/zero

조각을 다시 확인하세요.

# filefrag -v /media/Grafi/zero

Filesystem type is: ef53
File size of /media/Grafi/zero is 2147483648 (524288 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..     257:    5505024..   5505281:    258:
   1:      265..     265:    5505289..   5505289:      1:
   2:      272..     273:    5505296..   5505297:      2:
   3:      289..     289:    5505313..   5505313:      1:
   4:     8481..    8486:    5507361..   5507366:      6:    5513505:
   5:    32768..   32769:    5509120..   5509121:      2:    5531648:
   6:    98304..   98305:    5511168..   5511169:      2:    5574656:
   7:   163840..  163841:    5513216..   5513217:      2:    5576704:
   8:   229376..  229377:    5515264..   5515265:      2:    5578752:
   9:   262144..  262144:    5517312..   5517312:      1:    5548032:
  10:   294912..  294913:    5519360..   5519361:      2:    5550080: last
/media/Grafi/zero: 8 extents found

여기서 무슨 일이 일어나고 있는지 아는 사람 있나요? 파일 시스템을 생성한 후 파일이 조각화되는 이유는 무엇입니까? 무슨 일이에요 length?

다음에 추가:

mkfs.ext4매개변수는 -Enodiscard효과가 없습니다. 이 옵션을 사용하면 파일의 구조 filefrag(제로화된 블록)를 볼 수 있습니다. 그러나 이런 방식으로 생성된 파일 시스템을 사용하면 어떤 이유로든 파일이 조각화될 것입니다. 아마도 파일 시스템 메타데이터가 작성되어 0으로 지정된 파일에 어떤 작업을 수행했기 때문일 수 있습니다. 나는 모른다. 하지만 출력을 관찰하면 filefrag항상 +6 범위(2G 파일의 경우)가 있음을 알 수 있습니다. 아마도 슈퍼블록과 5개의 복제본 때문일까요? 그러나 전체 파일이 조각난 이유는 여전히 설명되지 않습니다. 여전히 동일한 파일입니다.

그리고 하나 더. 이 파일에서 파일 시스템을 다시 만들 때:

# mkfs.ext4 -Enodiscard /media/Grafi/zero
mke2fs 1.43 (17-May-2016)
/media/Grafi/zero contains a ext4 file system
        created on Thu Jun  2 13:02:28 2016
Proceed anyway? (y,n) y
Creating filesystem with 524288 4k blocks and 131072 inodes
Filesystem UUID: 6d58dddc-439b-4175-9af6-8628f0d2a278
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

추가된 범위가 마술처럼 사라집니다.

답변1

이는 inode 테이블의 공간을 사용하는 대신(사용하는 경우에도) mke2fs공간을 0으로 만드는 버그처럼 보입니다 .fallocate(fd, PUNCH_HOLE, ...)fallocate(fd, DISCARD_ZERO, ...)-E nodiscard

이 동작을 로컬에서 확인한 후 업스트림 메일링 리스트에 버그 보고서를 제출 [email protected]하고 한 시간 이내에 패치를 받았습니다. 제목은 다음과 같습니다.

e2fprogs: block zero/discard cleanups

e2fsprogs-1.45 버전에 포함되어야 하며,가능한1.44.x 유지 관리 릴리스. 벤더 릴리스에 표시되도록 하려면 e2fsprogs패치를 적용하고 e2fsprogs를 빌드하여 이것이 작동하는지 확인하고 성공을 보고하여 linux-ext4패치가 더 빨리 적용되도록 한 다음 선택한 배포판에 버그 보고서를 제출하여 업스트림할 것을 권장합니다. 패치를 해당 버전으로 가져옵니다.

답변2

$ /sbin/mkfs.ext4 test1
mke2fs 1.42.12 (29-Aug-2014)
Discarding device blocks: done
[...]

이제 힌트가 있습니다. 설명서에 나와 있는 내용을 살펴보겠습니다.

-E extended-options
discard
  Attempt  to  discard blocks at mkfs time (discarding blocks initially is useful
  on solid state devices and sparse / thin-provisioned storage). When the  device
  advertises that discard also zeroes data (any subsequent read after the discard
  and before write returns zero), then mark all not-yet-zeroed  inode  tables  as
  zeroed.  This significantly speeds up filesystem initialization. This is set as
  default.

따라서 기본적으로 mkfs는 기본 저장소의 이전 데이터가 더 이상 관련이 없다는 것을 알고 있으므로 이를 삭제할 수 있으며 기본 저장소는 이를 0으로 덮어쓰는 것보다 더 나은 방법을 가질 수 있습니다. 이를 통해 파일 시스템은 데이터 블록을 잊어버릴 수 있습니다.

그 후, mkfs는 임의 액세스 패턴으로 필요한 파일 시스템 구조를 구축하여 새로운 데이터 블록을 할당합니다. 파일이 다시 드물어지고 조각화되어 있습니다.

결과는 -Enodiscard예상한 대로일 수 있습니다.

$ /sbin/mkfs.ext4 -Enodiscard test2
$ /usr/sbin/filefrag test2
test2: 2 extents found

관련 정보