Ubuntu 11.04でファイルをコピーする際に、断片化を出来るだけ抑えるにはどうしたらいいのか探ってみた

結論。ファイルシステムext4・XFSならfallocateを使え、ntfsならftruncateを使え、他は知らん。

Windows用ソフトのFastCopyは、SetFilePointer() + SetEndOfFile() で連続領域を確保することでファイルの断片化を防止していると知って、snowcpでもいくつかの方法でコピー前の領域確保を試してみたりしたが、それらの方法が断片化に対してどの程度の効果があるのか確認したことは無かったので、今回それぞれの方法で多数のファイルをコピーしてみて、実際にどの程度断片化するのか調べてみた。

確認は以下のように行った。

  • コピーするファイルの総数は6960個、約450GB。ファイルの種類は、数100KB〜数MBのswf、数MB〜数100MBのflv・mp4・avi、数100MB〜2GBのzip(iso)。
  • 外付けHDD(USB2.0)から内蔵HDDへコピー。コピー速度は約30MiB/s。
  • ファイルシステムext4
  • 断片化率はfsckを実行して確認。

以下、結果。

  • pwrite(fd, "", 1, file_size - 1);
    • h860: 7224/57851904 files (27.0% non-contiguous), 122131915/231390208 blocks
  • ftruncate(fd, file_size);
    • h860: 7224/57851904 files (26.7% non-contiguous), 122131373/231390208 blocks
  • 事前の領域確保無し。
    • h860: 7224/57851904 files (26.5% non-contiguous), 122131381/231390208 blocks
  • posix_fallocate(fd, 0, file_size)
    • h860: 7224/57851904 files (6.3% non-contiguous), 122131777/231390208 blocks
  • fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, file_size)
    • h860: 7224/57851904 files (6.0% non-contiguous), 122131784/231390208 blocks

pwriteは意味無し。ftruncateでSparse File化するのも、断片化防止の効果は無し。

fallocateのFALLOC_FL_KEEP_SIZEモードとposix_fallocateはある程度効果はあるが、断片化を完全に防ぐことは出来ない。

ついでにWindowsでフォーマットしたntfsなパーティションにもファイル(2395個、890MB)をコピーして、Defragglerというデフラグソフトで断片化を確認してみたところ、pwriteだと断片化しまくりで、ftruncateだとそこそこ断片化を抑えられていた。

今回はかなり大きなサイズのファイルばかりコピーしたので断片化しまくりだが、小さなファイルだけなら特に何もしなくてもそこそこ断片化を抑えられるのではないだろうか。と、/の断片化率を見て思った(わずか0.3%)。

  • /dev/sdd1: 186489/1835008 files (0.3% non-contiguous), 1207504/7328000 blocks

参考:sync_file_range用の領域を確保する。