Tại sao mức độ phân mảnh rất lớn trong các tệp có chứa các hệ thống tệp khác?


8

Tôi vừa tìm ra những tập tin thưa thớt và muốn tiến hành một số thử nghiệm trên chúng. Trên wiki bạn có thể đọc rằng các tệp có thể bị phân mảnh dễ dàng. Tôi muốn kiểm tra xem nó tệ đến mức nào. Tôi đã tạo một tệp theo cách sau:

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

Tôi đã gắn tệp thưa thớt và tôi đặt tệp 600M vào đó. Mức độ phân mảnh trông như thế này:

# 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

Tôi nghĩ rằng đó là do tính năng "thưa thớt", nhưng có vẻ như tất cả các tệp có hệ thống tệp khác trong đó bị phân mảnh theo cách này. Hãy xem ví dụ sau:

Tạo một tệp đầy đủ các số 0:

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

Kiểm tra mức độ phân mảnh của nó:

# 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

Về cơ bản, tệp này có 17 phạm vi, nhưng từ góc độ con người, tệp có hai khối

Bây giờ tạo một hệ thống tập tin trong tập tin này:

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

Kiểm tra sự phân mảnh của nó một lần nữa:

# 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

Có ai biết những gì thực sự xảy ra ở đây? Tại sao tệp bị phân mảnh bằng cách tạo một hệ thống tệp trên đó? Điều gì đã xảy ra với length?

Thêm:

Các mkfs.ext4tham số -Enodiscardkhông hoạt động. Với tùy chọn này, tôi có thể thấy cấu trúc của tệp trong filefrag(các khối không). Nhưng sau khi tạo hệ thống tập tin theo cách này, tập tin sẽ bị phân mảnh vì một số lý do không có vấn đề gì. Có thể đó là do siêu dữ liệu của hệ thống tệp được viết và nó làm gì đó với tệp zeroed. Tôi không biết. Nhưng khi tôi xem đầu ra của filefrag, tôi có thể thấy rằng luôn có +6 phạm vi (trong trường hợp tệp 2G). Có lẽ đó là vì siêu khối và 5 bản sao của nó? Nhưng điều này vẫn không giải thích được tại sao toàn bộ tệp bị phân mảnh - nó vẫn là cùng một tệp.

Có một điều khác. Khi tôi tạo lại hệ thống tập tin trong tập tin này:

# 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

Các phạm vi được thêm vào biến mất một cách kỳ diệu.

Câu trả lời:


2

Có vẻ như đây là một lỗi mke2fskhiến nó sử dụng fallocate(fd, PUNCH_HOLE, ...)thay vì fallocate(fd, DISCARD_ZERO, ...)khi xóa hết khoảng trống trong các bảng inode (ngay cả khi-E nodiscard được sử dụng).

Tôi đã gửi báo cáo lỗi đến linux-ext4@vger.kernel.orgdanh sách gửi thư ngược dòng sau khi xác minh hành vi này cục bộ và nhận được một bản vá trong vòng một giờ, chủ đề:

e2fprogs: block zero/discard cleanups

Chúng nên được đưa vào bản phát hành e2fspross -1.45 và có khả năng là bản phát hành bảo trì 1.44.x. Nếu bạn muốn chúng trong e2fsprogsbản phát hành của nhà cung cấp , tôi khuyên bạn nên vá + xây dựng e2fspross để xác minh điều này có hiệu quả với bạn không, báo cáo thành công để linux-ext4các bản vá sẽ cập bến sớm hơn, sau đó gửi báo cáo lỗi cho bản phân phối của bạn để họ lựa chọn kéo các bản vá ngược dòng vào bản phát hành của họ.


Bạn đang nói về điều này? chắp
vá.ozlabs.org / cover / 899596

Đó là người ... Ted nói rằng nó cũng sẽ được đưa vào bản phát hành bảo trì 1.44.
LustreOne

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

Bây giờ có một gợi ý. Hãy xem hướng dẫn sử dụng nói:

-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.

Vì vậy, về cơ bản, mkfs biết rằng dữ liệu cũ trên bộ lưu trữ bên dưới không còn quan trọng nữa, vì vậy nó có thể bị loại bỏ và bộ lưu trữ bên dưới có thể có cách tốt hơn, chỉ bằng cách ghi đè bằng số không. Mà nó có, hệ thống tập tin ở đây chỉ có thể quên đi các khối dữ liệu.

Sau đó, mkfs xây dựng bất kỳ cấu trúc hệ thống tập tin nào mà nó cần, trong một mẫu truy cập hơi ngẫu nhiên, dẫn đến các khối dữ liệu mới được phân bổ. Các tập tin lại thưa thớt, và có một số phân mảnh.

Với -Enodiscardkết quả có lẽ là những gì bạn mong đợi:

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

Tôi chỉ cập nhật câu hỏi, xem nó để biết.
Mikhail Morfikov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.