「スパースファイル」の版間の差分
→スパースファイルの作成: 同期 |
Kusanaginoturugi (トーク | 投稿記録) 校正(でき・出来) |
||
| (3人の利用者による、間の9版が非表示) | |||
| 1行目: | 1行目: | ||
[[Category:ファイルシステム]] |
[[Category:ファイルシステム]] |
||
[[en:Sparse file]] |
[[en:Sparse file]] |
||
| ⚫ | [https://en.wikipedia.org/wiki/Sparse_file Wikipedia] によれば、コンピュータサイエンスにおいて、スパースファイルとはファイルに割り当てられたブロックが空の場合にファイルシステムの領域を効率よく使用するコンピュータファイルのことです。ブロックを実際に"空"の領域で埋めるのではなく、空のブロックであることを示す簡単な情報 (メタデータ) をディスクに書き込むことで、ディスクの使用量を減らします (すなわち、スパースファイルには存在を示すためのゼロブロックだけがあり、ディスク上には全く領域が割り当てられません)。ブロックに"本物"の (空ではない) データが現れたときに、実際にディスクにデータ容量分のブロックサイズが書き込まれます。 |
||
この記事ではスパースファイルについて、作成方法や管理方法、拡張の仕方などの情報を載せています。 |
|||
| ⚫ | |||
| ⚫ | |||
| ⚫ | [ |
||
スパースファイルを読み込んだときは、ファイルシステムによって、空ブロックを示すメタデータがゼロバイトで満たされた"本物"のブロックに透過的に変換されます。アプリケーションは実際はスパースファイルだということに気が付きません。 |
スパースファイルを読み込んだときは、ファイルシステムによって、空ブロックを示すメタデータがゼロバイトで満たされた"本物"のブロックに透過的に変換されます。アプリケーションは実際はスパースファイルだということに気が付きません。 |
||
ほとんどの近代的なファイルシステムはスパースファイルをサポートしています。主要な Unix ファイルシステムや NTFS などがそうです。ただし Apple の HFS+ は残念ながらサポートしていません。スパースファイルが使われるのは、ディスクイメージやデータベースのスナップショット、ログファイルや科学用アプリケーションなどが一般的です。 |
ほとんどの近代的なファイルシステムはスパースファイルをサポートしています。主要な Unix ファイルシステムや NTFS などがそうです。ただし Apple の HFS+ は残念ながらサポートしていません。スパースファイルが使われるのは、[[w:Disk image|ディスクイメージ]]([[w:Sparse image|スパースイメージ]] と混同しないでください)やデータベースのスナップショット、ログファイルや科学用アプリケーションなどが一般的です。 |
||
=== メリット === |
|||
スパースファイルの利点は、ストレージが使われるのは実際に必要になってからだということです: ディスク容量が節約されて、たとえファイルシステムに十分な空き容量が存在しない場合でも巨大なファイルを作成することができるようになります。 |
スパースファイルの利点は、ストレージが使われるのは実際に必要になってからだということです: ディスク容量が節約されて、たとえファイルシステムに十分な空き容量が存在しない場合でも巨大なファイルを作成することができるようになります。 |
||
=== デメリット === |
|||
スパースファイルは断片化することがあるという欠点が存在します。ファイルシステムからの偽の空き容量の報告が誤解を生む可能性があります。スパースファイルが含まれたファイルシステムを一杯にしてしまうと予期せぬ事態になるかもしれません。また、スパースファイルに対応していないプログラムでスパースファイルをコピーすると、ディスク上には存在しないゼロの領域 (スパース, 疎) まで完全にコピーしてしまうことが考えられます。これではスパースファイルにした意味がなくなってしまうでしょう。 |
スパースファイルは断片化することがあるという欠点が存在します。ファイルシステムからの偽の空き容量の報告が誤解を生む可能性があります。スパースファイルが含まれたファイルシステムを一杯にしてしまうと予期せぬ事態になるかもしれません。また、スパースファイルに対応していないプログラムでスパースファイルをコピーすると、ディスク上には存在しないゼロの領域 (スパース, 疎) まで完全にコピーしてしまうことが考えられます。これではスパースファイルにした意味がなくなってしまうでしょう。 |
||
| 24行目: | 14行目: | ||
''truncate'' ユーティリティでスパースファイルを作成できます。以下のコマンドは 512 MiB のスパースファイルを作成します: |
''truncate'' ユーティリティでスパースファイルを作成できます。以下のコマンドは 512 MiB のスパースファイルを作成します: |
||
$ truncate -s 512M file.img |
$ truncate -s 512M file.img |
||
''dd'' ユーティリティを使うことも可能です。例: |
''dd'' ユーティリティを使うことも可能です。例: |
||
$ dd if=/dev/zero of=file.img bs=1 count=0 seek=512M |
$ dd if=/dev/zero of=file.img bs=1 count=0 seek=512M |
||
0+0 records in |
|||
0+0 records out |
|||
0 bytes (0 B) copied, 2.4934e-05 s, 0.0 kB/s |
|||
スパースファイルには''外見上のファイルサイズ'' (拡大できる最大容量) と''実際のファイルサイズ'' (ディスク上のデータ容量) という2つのファイルサイズが存在します。ファイルの''外見上のサイズ''を確認するには、次を実行: |
スパースファイルには''外見上のファイルサイズ'' (拡大できる最大容量) と''実際のファイルサイズ'' (ディスク上のデータ容量) という2つのファイルサイズが存在します。ファイルの''外見上のサイズ''を確認するには、次を実行: |
||
{{hc| $ du -h --apparent-size file.img| |
|||
512M file.img |
512M file.img |
||
}} |
|||
そして、ディスク上のファイルの''実際のサイズ''を確認するには: |
そして、ディスク上のファイルの''実際のサイズ''を確認するには: |
||
{{hc| $ du -h file.img| |
|||
0 file.img |
0 file.img |
||
}} |
|||
上記の場合、ファイルの外見上の容量は 512 MiB となっていますが、"実際"の容量は完全にゼロです。スパースファイルでは、ファイルを保存するのに必要な最小容量まで自由にサイズが変えられます。 |
上記の場合、ファイルの外見上の容量は 512 MiB となっていますが、"実際"の容量は完全にゼロです。スパースファイルでは、ファイルを保存するのに必要な最小容量まで自由にサイズが変えられます。 |
||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
次のコマンドは、(スパース) ファイルを非スパースにコピーを作成します: |
|||
$ cp file.img copy.img --sparse=never |
|||
$ du -h copy.img |
|||
512M copy.img |
|||
=== ファイルシステムでファイルをフォーマット === |
=== ファイルシステムでファイルをフォーマット === |
||
| 59行目: | 70行目: | ||
# mount -o loop file.img folder |
# mount -o loop file.img folder |
||
ジャジャーン。''外見上''は 512 MiB もある情報を保存することが |
ジャジャーン。''外見上''は 512 MiB もある情報を保存することができました。 |
||
=== 起動時にファイルをマウント === |
=== 起動時にファイルをマウント === |
||
| 67行目: | 78行目: | ||
{{Warning|`loop' オプションを必ず指定して下さい -- 指定しなかった場合、マウントされません。}} |
{{Warning|`loop' オプションを必ず指定して下さい -- 指定しなかった場合、マウントされません。}} |
||
=== 既存のファイルをスパースファイルにする === |
|||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
== スパースファイルのコピー == |
== スパースファイルのコピー == |
||
| 166行目: | 165行目: | ||
This is a test to see if it works... |
This is a test to see if it works... |
||
== ツール == |
|||
中身は無事なようです。素晴らしい。 |
|||
* {{App|sparse-fio|ゼロ以外のデータがまばらに含まれるファイルを処理する [[dd]] のようなプログラム|https://github.com/anyc/sparse-fio|{{AUR|sparse-fio-git}}}} |
|||
* {{App|sparseutils|まばらに配置されたファイルを操作するためのユーティリティ。{{ic|mksparse.py}} と {{ic|sparsemap.py}} を提供し、[[pip]] でインストールできます。|https://pypi.org/project/sparseutils/}} |
|||
== 参照 == |
== 参照 == |
||
* |
* [[wikipedia:Sparse_file]] |
||
* http://www.apl.jhu.edu/Misc/Unix-info/tar/tar_85.html |
* https://web.archive.org/web/20121026035748/http://www.apl.jhu.edu/Misc/Unix-info/tar/tar_85.html |
||
2024年7月10日 (水) 20:26時点における最新版
Wikipedia によれば、コンピュータサイエンスにおいて、スパースファイルとはファイルに割り当てられたブロックが空の場合にファイルシステムの領域を効率よく使用するコンピュータファイルのことです。ブロックを実際に"空"の領域で埋めるのではなく、空のブロックであることを示す簡単な情報 (メタデータ) をディスクに書き込むことで、ディスクの使用量を減らします (すなわち、スパースファイルには存在を示すためのゼロブロックだけがあり、ディスク上には全く領域が割り当てられません)。ブロックに"本物"の (空ではない) データが現れたときに、実際にディスクにデータ容量分のブロックサイズが書き込まれます。
スパースファイルを読み込んだときは、ファイルシステムによって、空ブロックを示すメタデータがゼロバイトで満たされた"本物"のブロックに透過的に変換されます。アプリケーションは実際はスパースファイルだということに気が付きません。
ほとんどの近代的なファイルシステムはスパースファイルをサポートしています。主要な Unix ファイルシステムや NTFS などがそうです。ただし Apple の HFS+ は残念ながらサポートしていません。スパースファイルが使われるのは、ディスクイメージ(スパースイメージ と混同しないでください)やデータベースのスナップショット、ログファイルや科学用アプリケーションなどが一般的です。
スパースファイルの利点は、ストレージが使われるのは実際に必要になってからだということです: ディスク容量が節約されて、たとえファイルシステムに十分な空き容量が存在しない場合でも巨大なファイルを作成することができるようになります。
スパースファイルは断片化することがあるという欠点が存在します。ファイルシステムからの偽の空き容量の報告が誤解を生む可能性があります。スパースファイルが含まれたファイルシステムを一杯にしてしまうと予期せぬ事態になるかもしれません。また、スパースファイルに対応していないプログラムでスパースファイルをコピーすると、ディスク上には存在しないゼロの領域 (スパース, 疎) まで完全にコピーしてしまうことが考えられます。これではスパースファイルにした意味がなくなってしまうでしょう。
スパースファイルの作成
truncate ユーティリティでスパースファイルを作成できます。以下のコマンドは 512 MiB のスパースファイルを作成します:
$ truncate -s 512M file.img
dd ユーティリティを使うことも可能です。例:
$ dd if=/dev/zero of=file.img bs=1 count=0 seek=512M
スパースファイルには外見上のファイルサイズ (拡大できる最大容量) と実際のファイルサイズ (ディスク上のデータ容量) という2つのファイルサイズが存在します。ファイルの外見上のサイズを確認するには、次を実行:
$ du -h --apparent-size file.img
512M file.img
そして、ディスク上のファイルの実際のサイズを確認するには:
$ du -h file.img
0 file.img
上記の場合、ファイルの外見上の容量は 512 MiB となっていますが、"実際"の容量は完全にゼロです。スパースファイルでは、ファイルを保存するのに必要な最小容量まで自由にサイズが変えられます。
既存のファイルをスパースファイルにする
ファイルシステムがサポートされている場合 (XFS, ext4, tmpfs)、fallocate ユーティリティを使うことで既存のファイルをスパースファイルに変えることができます:
$ cp file.img copy.img --sparse=never $ du -h copy.img 512M copy.img
$ fallocate -d copy.img $ du -h copy.img 0 copy.img
既存のファイルを非スパースファイルにする
次のコマンドは、(スパース) ファイルを非スパースにコピーを作成します:
$ cp file.img copy.img --sparse=never $ du -h copy.img 512M copy.img
ファイルシステムでファイルをフォーマット
スパースファイルを作成したら、ファイルシステムでフォーマットしましょう。例えば ReiserFS を使う場合:
# mkfs.reiserfs -f -q file.img mkfs.reiserfs 3.6.21 (2009 www.namesys.com)
ファイルシステムのフォーマットによってどんな影響があったかサイズを確認してみます:
# du -h --apparent-size file.img 512M file.img
# du -h file.img 33M file.img
ご推察の通り、ファイルシステムでフォーマットすることで実際のサイズが大きくなりました。しかしながら外見上のサイズは変わっていません。次に、ディレクトリを作成してファイルをマウントしてみます:
# mkdir folder # mount -o loop file.img folder
ジャジャーン。外見上は 512 MiB もある情報を保存することができました。
起動時にファイルをマウント
スパースファイルを作成したら、起動時に自動的にマウントさせることが可能です。以下のように /etc/fstab にエントリを追加することでマウントできます:
/path/to/file.img /path/to/folder reiserfs loop,defaults 0 0
スパースファイルのコピー
`cp' でコピー
基本的に、`cp' はファイルがスパースであるかどうか検出することができるので、次を実行すると new_file.img はスパースになります:
cp file.img new_file.img
ただし、cp には --sparse=WHEN オプションが存在します。スパースファイルが実はスパースではない場合 (つまり、空のブロックがディスクに書き込まれている場合) に有用です。次を実行することでディスク領域を回収できます:
cp --sparse=always new_file.img recovered_file.img
`tar' で圧縮
ある日、あなたは長年の連れ添いであるスパースファイルをバックアップしようと思い立ちました。そこで `tar' ユーティリティを使おうと考えたあなたは、はたと問題に出くわします:
# du -h file.img 33M file.img
# tar -cf file.tar file.img
# du -h file.tar 513M file.tar
一見、スパースファイルの容量は 33 MB しかないのに、tar で圧縮すると巨大なファイルが作成されてしまったのです。しかしながら、あなたはツイています。tar には `--sparse' (`-S') フラグが存在するのです。`--create' (`-c') と一緒に使うことで、圧縮時にファイルがスパースでないか全てのファイルを調査します。ファイルがスパースであると tar が認識すると、アーカイブの中ではファイルの代わりにスパースが使われます。これは dbm ファイルなどをアーカイブ化するときに有用です。dbm ファイルは中身がほとんどヌルであり、アーカイブとして保存するときに必要な容量を劇的に減らすことができます。
# tar -Scf file.tar file.img # du -h file.tar 12K file.tar
晴れて問題は解決しました。
スパースファイルの容量の変更
ファイルのサイズを変更する前に、テスト用に小さいファイルを作成してみましょう:
# for f in {1..5}; do touch folder/file${f}; done
# ls folder/
file1 file2 file3 file4 file5
そして、ファイルに中身を追加します:
# echo "This is a test to see if it works..." >> folder/file1 # cat folder/file1 This is a test to see if it works...
ファイルの拡大
ファイルを拡大する必要がある場合、以下を実行します:
# umount folder # dd if=/dev/zero of=file.img bs=1 count=0 seek=1G 0+0 records in 0+0 records out 0 bytes (0 B) copied, 2.2978e-05 s, 0.0 kB/s
上記のコマンドでサイズが 1 Gb まで増大します。情報は損なわれません。次に、ファイルシステムのサイズを増加させてください:
# resize_reiserfs file.img resize_reiserfs 3.6.21 (2009 www.namesys.com) ReiserFS report: blocksize 4096 block count 262144 (131072) free blocks 253925 (122857) bitmap block count 8 (4) Syncing..done resize_reiserfs: Resizing finished successfully.
そして再マウント:
# mount -o loop file.img folder
容量を確認すると:
# du -h --apparent-size file.img 1.0G file.img
# du -h file.img 33M file.img
中身を確認すると:
# df -h folder Filesystem Size Used Avail Use% Mounted on /tmp/file.img 1.0G 33M 992M 4% /tmp/folder
# ls folder file1 file2 file3 file4 file5
# cat folder/file1 This is a test to see if it works...
ツール
- sparse-fio — ゼロ以外のデータがまばらに含まれるファイルを処理する dd のようなプログラム
- sparseutils — まばらに配置されたファイルを操作するためのユーティリティ。
mksparse.pyとsparsemap.pyを提供し、pip でインストールできます。
- https://pypi.org/project/sparseutils/ || パッケージが存在しないか AUR で検索