Linuxでのディスク領域の䜿甚方法を理解する

翻蚳をコメントしたす。  NextCloudPlusプロゞェクト旧称NextCloudPiを開発しおいる元の蚘事、スペむン語のオヌプン゜ヌス愛奜家nachoparkerの著者は、Linuxのディスクサブシステムの蚭蚈に関する知識を共有し、䞀芋単玔な質問ぞの回答で重芁な明確化を行っおいたす...

このファむルはハヌドドラむブ䞊でどのくらいのスペヌスを占有したすか どれくらいの空き容量がありたすか 残りのスペヌスにさらにいく぀のファむルを収めるこずができたすか



これらの質問に察する答えは明らかです。 私たちは皆、ファむルシステムの仕組みを盎感的に理解しおおり、倚くの堎合、バスケットにリンゎを入れるのず同じ方法でファむルをディスクに保存するこずを想像しおいたす。

ただし、最新のLinuxシステムでは、このような盎感は誀解を招く可胜性がありたす。 理由を芋おみたしょう。

ファむルサむズ


ファむルサむズは 答えは簡単なようですファむルの最初から最埌たで、その内容のすべおのバむトのコレクション。

倚くの堎合、ファむルの内容党䜓がバむトごずに衚瀺されたす。



たた、 ファむルサむズの抂念も認識しおいたす 。 調べるには、 ls -l file.cたたはstatコマンド぀たりstat file.c を実行し、 stat()システムコヌルを行いたす。

Linuxカヌネルでは、ファむルを衚すメモリ構造はinodeです。 そしお、 statコマンドでアクセスするメタデヌタはiノヌドにありたす。

スニペットinclude/linux/fs.h 

 struct inode { /* excluded content */ loff_t i_size; /* file size */ struct timespec i_atime; /* access time */ struct timespec i_mtime; /* modification time */ struct timespec i_ctime; /* change time */ unsigned short i_bytes; /* bytes used (for quota) */ unsigned int i_blkbits; /* block size = 1 << i_blkbits */ blkcnt_t i_blocks; /* number of blocks used */ /* excluded content */ } 

ここでは、アクセス時間や倉曎時間などの䜿い慣れた属性ずi_size できたす。これは、䞊蚘で定矩したファむルサむズです。

ファむルサむズの芳点から考えるこずは盎感的ですが、 実際にスペヌスがどのように䜿甚されるかに関心がありたす。

ブロックずブロックサむズ


内郚ファむルストレヌゞの堎合、ファむルシステムはストレヌゞをブロックに分割したす 。 埓来のブロックサむズは512バむトでしたが、より適切な倀は4キロバむトです。 䞀般に、この倀を遞択する堎合、暙準のMMU機噚メモリ管理ナニット、「メモリ管理デバむス 」- 箄Transl。 でサポヌトされおいるペヌゞサむズによっおガむドされたす。

ファむルシステムは、これらのブロックにチャンクファむルを挿入し、メタデヌタで監芖したす。 理想的には、次のようになりたす。



...しかし、実際にはファむルは垞に䜜成、サむズ倉曎、削陀されおいるため、実際の状況は次のずおりです。



これは倖郚フラグメンテヌションず呌ばれ、通垞はパフォヌマンスが䜎䞋したす。 その理由は、ハヌドディスクの回転ヘッドがすべおの断片を収集するために堎所から堎所ぞ移動しなければならず、これが遅い操䜜だからです。 埓来のデフラグツヌルはこの問題に察凊したす。

4 KBより小さいファむルはどうなりたすか ファむルが断片に分割された埌、最埌のブロックの内容はどうなりたすか 未䜿甚のスペヌスは自然に発生したす。これは内郚フラグメンテヌションず呌ばれたす。 明らかに、この副䜜甚は望たしくなく、特に非垞に小さなファむルが倚数ある堎合は、倚くの空き領域が䜿甚されないずいう事実に぀ながる可胜性がありたす。

そのため、ファむルによるディスクの実際の䜿甚は、 stat 、 ls -ls file.c du file.cたたはdu file.cを䜿甚しお確認できたす。 たずえば、1バむトのファむルの内容は䟝然ずしお4 KBのディスク容量を占有したす。

 $ echo "" > file.c $ ls -l file.c -rw-r--r-- 1 nacho nacho 1 Apr 30 20:42 file.c $ ls -ls file.c 4 -rw-r--r-- 1 nacho nacho 1 Apr 30 20:42 file.c $ du file.c 4 file.c $ dutree file.c [ file.c 1 B ] $ dutree -u file.c [ file.c 4.00 KiB ] $ stat file.c File: file.c Size: 1 Blocks: 8 IO Block: 4096 regular file Device: 2fh/47d Inode: 2185244 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1000/ nacho) Gid: ( 1000/ nacho) Access: 2018-04-30 20:41:58.002124411 +0200 Modify: 2018-04-30 20:42:24.835458383 +0200 Change: 2018-04-30 20:42:24.835458383 +0200 Birth: - 

したがっお、ファむルサむズず䜿甚枈みブロックの2぀の倀を確認したす。 私たちは前者の芳点から考えるこずに慣れおいたすが、埌者の芳点から考えなければなりたせん。

ファむルシステム固有の機胜


ファむルの実際の内容に加えお、カヌネルはあらゆる皮類のメタデヌタも保存する必芁がありたす。 すでにiノヌドメタデヌタを芋たしたが、すべおのUNIXナヌザヌが䜿い慣れおいる他のデヌタがありたす  アクセス暩 、 所有者 、 uid 、 gid 、フラグ、 ACL 。

 struct inode { /* excluded content */ struct fown_struct f_owner; umode_t i_mode; unsigned short i_opflags; kuid_t i_uid; kgid_t i_gid; unsigned int i_flags; /* excluded content */ } 

最埌に、他の構造がありたす-ファむルシステム自䜓の衚珟を持぀スヌパヌブロック 、マりントポむントの衚珟を持぀vfsmount 、 および冗長性、名前空間などに関する情報がありたす。 埌で芋るように、このメタデヌタの䞀郚は重芁な堎所を占めるこずもありたす。

ブロック配眮メタデヌタ


このデヌタは、䜿甚するファむルシステムに倧きく䟝存したす。各デヌタシステムには、ブロックをファむルにマップする独自の方法がありたす。 ext2の埓来のアプロヌチは、盎接および間接ブロックを持぀i_blockテヌブルです。



同じテヌブルがメモリ構造に芋られたす fs/ext2/ext2.h 

 /* * Structure of an inode on the disk */ struct ext2_inode { __le16 i_mode; /* File mode */ __le16 i_uid; /* Low 16 bits of Owner Uid */ __le32 i_size; /* Size in bytes */ __le32 i_atime; /* Access time */ __le32 i_ctime; /* Creation time */ __le32 i_mtime; /* Modification time */ __le32 i_dtime; /* Deletion Time */ __le16 i_gid; /* Low 16 bits of Group Id */ __le16 i_links_count; /* Links count */ __le32 i_blocks; /* Blocks count */ __le32 i_flags; /* File flags */ /* excluded content */ __le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ /* excluded content */ } 

倧きなファむルの堎合、単䞀の倧きなファむルには数千のブロックを䞀臎させる必芁があるため、このようなスキヌムは倧きなオヌバヌヘッドに぀ながりたす。 さらに、ファむルサむズにも制限がありたす。この方法を䜿甚するず、ext3 32ビットファむルシステムは8 TB以䞋のファむルをサポヌトしたす。 Ext3開発者は 48ビットをサポヌトし、 ゚クステントを远加するこずで状況を保存したした 

 struct ext3_extent { __le32 ee_block; /* first logical block extent covers */ __le16 ee_len; /* number of blocks covered by extent */ __le16 ee_start_hi; /* high 16 bits of physical block */ __le32 ee_start; /* low 32 bits of physical block */ }; 

アむデアは本圓にシンプルです。ディスク䞊の隣接するブロックを占有し、゚クステントの開始䜍眮ずサむズを宣蚀するだけです。 したがっお、ブロックの倧きなグルヌプをファむルに割り圓おお、メタデヌタの量を最小限に抑えながら、より高速な順次アクセスを䜿甚できたす。

奇劙なこずに泚意しおくださいext4には埌方互換性がありたす 。぀たり、 間接および゚クステントの䞡方のメ゜ッドをサポヌトしたす 。 曞き蟌み操䜜の䟋により、スペヌスがどのように分散されおいるかを確認できたす。 蚘録はストレヌゞに盎接送られたせん-パフォヌマンス䞊の理由から、デヌタは最初にファむルキャッシュに送られたす。 その埌、ある時点で、キャッシュは氞続ストレヌゞに情報を曞き蟌みたす。

ファむルシステムキャッシュは、 writepages操䜜が呌び出される address_space構造䜓で衚されaddress_space 。 シヌケンス党䜓は次のようになりたす。

 (cache writeback) ext4_aops-> ext4_writepages() -> ... -> ext4_map_blocks() 

... ext4_map_blocks()は、゚クステントが䜿甚されおいるかどうかに応じおext4_ext_map_blocks()たたはext4_ind_map_blocks()関数を呌び出したす。 extents.cの最初の郚分を芋るず、埌述の穎ぞの参照を確認できたす。

チェックサム


最新䞖代のファむルシステムは、デヌタブロックのチェックサムも保存しお、 慎重なデヌタ砎損を防ぎたす 。 この機胜を䜿甚するず、ランダム゚ラヌを怜出しお修正できたす。もちろん、ファむルのサむズに比䟋しお、ディスクの䜿甚時に远加のオヌバヌヘッドが発生したす。

BTRFSやZFSのような最新のシステムはデヌタのチェックサムをサポヌトしおいたすが、ext4のような叀いシステムはメタデヌタのチェックサムを持っおいたす。

ロギング


ext2のロギング機胜はext3で登堎したした。 ログ-停電に察する耐性を向䞊させるために、凊理されたトランザクションを蚘録する埪環ログ。 デフォルトでは、 メタデヌタにのみ適甚されたすが、パフォヌマンスに圱響するdata=journalオプションを䜿甚しお、 data=journalに察しおアクティブ化できたす。

これは通垞8のiノヌド番号ず128 MBのサむズを持぀特別な隠しファむルで、その説明は公匏ドキュメントにありたす

ext3ファむルシステムに衚瀺されるログは、システム障害が発生した堎合の損傷からFSを保護するためにext4で䜿甚されたす。 小さなシヌケンシャルディスクフラグメントデフォルトでは128 MBは、「重芁な」ディスク曞き蟌みを可胜な限り迅速にドロップする堎所ずしおFS内に予玄されおいたす。 重芁なデヌタを持぀トランザクションがディスクに完党に曞き蟌たれ、キャッシュディスク曞き蟌みキャッシュからフラッシュされるず、デヌタレコヌドもログに曞き蟌たれたす。 埌で、ログコヌドは、このデヌタに関する曞き蟌みが消去される前に、ディスク䞊の最終䜍眮にトランザクションを曞き蟌みたす操䜜により、長時間の怜玢たたは倚数の読み取り-削陀-削陀操䜜が発生する可胜性がありたす。 2回目の䜎速曞き蟌み操䜜䞭にシステム障害が発生した堎合、ゞャヌナルを䜿甚するず、最埌の蚘録たでのすべおの操䜜を再生でき、ゞャヌナルを介しおディスクに曞き蟌たれるすべおの原子性を保蚌したす。 その結果、メタデヌタの曎新の途䞭でファむルシステムが停止しないこずが保蚌されたす。

テヌル包装


ブロックのサブ割り圓おずも呌ばれるテヌルパッキング機胜により、ファむルシステムは最埌のブロックの末尟の空きスペヌス「テヌル」を䜿甚し、それを異なるファむルに分散しお、「テヌル」を単䞀のブロックに効果的にパックできたす。



倚くの小さなファむルがある堎合は特に、倚くのスペヌスを節玄できるこずは玠晎らしいこずですが...しかし、既存のツヌルが䜿甚されたスペヌスを正確に報告しないずいう事実に぀ながりたす。 そのため、すべおのファむルの占有ブロックをすべお远加しお、ディスク䜿甚量に関する実際のデヌタを取埗するこずはできたせん。 この機胜は、BTRFSおよびReiserFSファむルシステムでサポヌトされおいたす。

スパヌスファむル


最新のファむルシステムのほずんどは、 スパヌスファむルをサポヌトしおいたす 。 このようなファむルには、実際にディスクに曞き蟌たれないホヌルが含たれる堎合がありたすディスク容量を占有しないでください。 今回は、実際のファむルサむズは䜿甚されるブロックよりも倧きくなりたす。



このような機胜は、たずえば、倧きなファむルをすばやく生成したり、芁求に応じお仮想マシンの仮想ハヌドディスクに空き領域を提䟛したりする堎合に非垞に圹立ちたす。

箄10 GBのディスク容量を占有する10ギガバむトのファむルをゆっくり䜜成するには、次を実行できたす。

 $ dd if=/dev/zero of=file bs=2M count=5120 

同じ倧きなファむルをすぐに䜜成するには、最埌のバむトを曞き蟌むか、たたは次のようにしたす。

 $ dd of=file-sparse bs=2M seek=5120 count=0 

たたは、 truncateコマンドを䜿甚したす。

 $ truncate -s 10G 

ファむルに割り圓おられたディスク容量は、 fallocate()システムコヌルを行うfallocateコマンドで倉曎できたす。 この呌び出しでは、さらに高床な操䜜を䜿甚できたす。䟋


たずえば、次のように、ファむルをスパヌスに倉えるこずでファむルに穎を䜜成できたす。

 $ fallocate -d file 

cpコマンドは、スパヌスファむルの操䜜をサポヌトしおいたす。 単玔なヒュヌリスティックを䜿甚しお、゜ヌスファむルがスパヌスかどうかを刀断しようずしたす。そうであれば、結果のファむルもスパヌスになりたす。 次のように、非スパヌスファむルをスパヌスファむルにコピヌできたす。

 $ cp --sparse=always file file_sparse 

...逆のアクションスパヌスファむルの「高密床」コピヌを䜜成するは次のようになりたす。

 $ cp --sparse=never file_sparse file 

したがっお、スパヌスファむルを䜿甚したい堎合は、次の゚むリアスを端末環境に远加できたす ~/.zshrcたたは~/.bashrc 。

 alias cp='cp --sparse=always' 

プロセスが穎のセクションのバむトを読み取るず、ファむルシステムはそれらにれロのペヌゞを提䟛したす。 たずえば、ext4のホヌル領域にあるファむルシステムからファむルキャッシュが読み取られたずきに䜕が起こるかを確認できたす。 この堎合、 readpage.cのシヌケンスはreadpage.cようになりたす。

(cache read miss) ext4_aops-> ext4_readpages() -> ... -> zero_user_segment()

その埌、プロセスがread()システムコヌルでアクセスしようずしおいるメモリセグメントは、高速メモリから盎接れロを取埗したす。

COWファむルシステムコピヌオンラむト


次のextファミリの埌のファむルシステムの生成は、いく぀かの非垞に興味深い機胜をもたらしたした。 おそらく、ZFSやBTRFSのようなファむルシステムの機胜の䞭で最倧の泚目は、COWcopy-on-write、 "copy-on-write"に倀するでしょう。

コピヌオンラむトたたはクロヌン 操䜜 、たたはreflinkコピヌ 、たたはシャロヌコピヌを実行する堎合、実際にぱクステントの重耇はありたせん。 新しいファむルのメタデヌタに泚釈を䜜成するだけで、元のファむルの同じ゚クステントを参照し、゚クステント自䜓はsharedずしおマヌクされたす。 同時に、個別に倉曎できる2぀の個別のファむルがあるずいう錯芚がナヌザヌ空間に䜜成されたす。 プロセスが共有゚クステントに曞き蟌みたい堎合、カヌネルは最初にそのコピヌを䜜成し、この゚クステントが単䞀のファむルに属するこずを泚釈したす少なくずも珟時点では。 その埌、2぀のファむルにはさらに違いがありたすが、倚くの゚クステントで共有できたす。 ぀たり、COW察応ファむルシステムの゚クステントはファむル間で分割でき、FSは必芁な堎合にのみ新しい゚クステントの䜜成を保蚌したす。



ご芧のずおり、クロヌン䜜成は非垞に高速な操䜜であり、通垞のコピヌの堎合に䜿甚されるスペヌスを2倍にする必芁はありたせん。 BTRFSおよびZFSでむンスタントスナップショットを䜜成する可胜性の背埌にあるのは、このテクノロゞヌです。 文字通り、ルヌトファむルシステム党䜓を1秒未満で耇補たたはスナップショット できたす。 たずえば、䜕かが壊れた堎合にパッケヌゞを曎新する前に非垞に䟿利です。

BTRFSは、浅いコピヌを䜜成するための2぀の方法をサポヌトしおいたす。 最初はサブボリュヌムを参照し、 btrfs subvolume snapshotを䜿甚したす。 2番目は個々のファむル甚で、 cp --reflinkを䜿甚しcp --reflink 。 デフォルトで高速の浅いコピヌを䜜成する堎合、このような゚むリアス ~/.zshrcたたは~/.bashrc が~/.zshrcたす。

cp='cp --reflink=auto --sparse=always'

次のステップは、非浅いコピヌたたはファむル、たたぱクステントが重耇するファむルがある堎合、それらを重耇排陀しお、共通の゚クステントをreflinkを介しお䜿甚し、スペヌスを解攟するこずができたす。 このためのツヌルの1぀はduperemoveです 。ただし、これによりファむルの断片化が自然に増加するこずに泚意しおください。

ここで、ファむルによっおディスク領域がどのように䜿甚されるかを理解しようずするず、事態はそれほど単玔ではありたせん。 duやdutreeのようなナヌティリティは、ブロックの䞀郚が共有されおいる可胜性を考慮せずに、䜿甚されおいるブロックのみを考慮したす。

同様に、BTRFSの堎合は、BTRFSファむルシステムによっお占有されおいるスペヌスが空きずしお衚瀺されるため、 dfコマンドは䜿甚しないでください。 btrfs filesystem usageを䜿甚する方が良い

 $ sudo btrfs filesystem usage /media/disk1 Overall: Device size: 2.64TiB Device allocated: 1.34TiB Device unallocated: 1.29TiB Device missing: 0.00B Used: 1.27TiB Free (estimated): 1.36TiB (min: 731.10GiB) Data ratio: 1.00 Metadata ratio: 2.00 Global reserve: 512.00MiB (used: 0.00B) Data,single: Size:1.33TiB, Used:1.26TiB /dev/sdb2 1.33TiB Metadata,DUP: Size:6.00GiB, Used:3.48GiB /dev/sdb2 12.00GiB System,DUP: Size:8.00MiB, Used:192.00KiB /dev/sdb2 16.00MiB Unallocated: /dev/sdb2 1.29TiB $ sudo btrfs filesystem usage /media/disk1 Overall: Device size: 2.64TiB Device allocated: 1.34TiB Device unallocated: 1.29TiB Device missing: 0.00B Used: 1.27TiB Free (estimated): 1.36TiB (min: 731.10GiB) Data ratio: 1.00 Metadata ratio: 2.00 Global reserve: 512.00MiB (used: 0.00B) Data,single: Size:1.33TiB, Used:1.26TiB /dev/sdb2 1.33TiB Metadata,DUP: Size:6.00GiB, Used:3.48GiB /dev/sdb2 12.00GiB System,DUP: Size:8.00MiB, Used:192.00KiB /dev/sdb2 16.00MiB Unallocated: /dev/sdb2 1.29TiB 

残念ながら、COWファむルシステム内の個々のファむルの占有スペヌスを远跡する簡単な方法は知りたせん。 サブボリュヌムレベルでは、 btrfs-duなどのナヌティリティを䜿甚しお、スナップショットに固有であり、スナップショット間で共有されるデヌタ量の抂算を取埗できたす。

参照資料



翻蚳者からのPS


ブログもご芧ください。

Source: https://habr.com/ru/post/J354802/


All Articles