書いて覚えるSwift入門

第32回 APFSの研究

この記事を読むのに必要な時間:およそ 5 分

最低限文化的なマカーのためのAPFS入門

iOSでは10.3以降,問答無用でHFS+を置き換えたAPFSが,macOS High SierraでいよいよMacにもやって来ました。利用にあたってファイルシステムを意識する必要が事実上皆無で,外付けストレージをマウントすることもほとんどないiPhoneやiPadやApple WatchやApple TVと異なり,外付けストレージもNASもごく当然に利用し,Boot CampなどでOSすらmacOS以外のものをサポートしているMacを利用する以上,ファイルシステムというものをまったく意識しないということは不可能です。今回はSwiftを意識しつつも,Swiftの開発において事実上必須である,macOSの新メインファイルシステムたるAPFSをあらためて見ていきます。

なぜ,

  • APFSは事実上問答無用で現在サポートされているApple製品すべてで採用されたのか
  • Fusion DriveやHDDを内蔵するMacはその例外となったのか
  • 開発者たる我々はどのような点に気を付けたら良いのか

本記事を読めば,これらの点にも納得がいくはずです。

Copy-on-Write=SwiftとAPFSの共通点

APFSの最大の特長は,それがCopy-on-Write(CoW)なファイルシステムであるということです。公式ページにも真っ先にそれが示されています。

CoWとはいったい何なのでしょうか? 実はSwiftもCoWを採用しています。そのことを確認してみましょう。

extension String {
    func peek() {
        let type = (UInt, UInt, UInt).self
        let (u0, u1, u2) = unsafeBitCast(self, to:type)
        debugPrint(u0, u1, u2)
    }
}

let orig = "Hello, playground"
var copy = orig
orig.peek()
copy.peek()
copy += " string"
orig.peek()
copy.peek()

SwiftのStringは抽象化されていて,その構造を直接見ることは本来できないのですが,ここでは無理やりunsafeBitCastを使って覗いています。最初にpeek()したときにはorigcopyも同一だったのが,copy"string"を追記したあとは内容が変わっていることが確認できます。

SwiftのString構造体は常に24bit=ポインタ3つ分。この値が固定であることからも,文字列の内容は構造体そのものではなく構造体の中のポインタが示すアドレスに格納されていることが察せられます。それが最初にcopy = origした時点では変わらず,copyに変更が加えられたあとに変わったというのはどういうことか。内容に変更がなされるときに初めてデータが複製され,その複製されたデータに対して変更が行われたのです。Copy-on-Writeすなわち「複製は書き込み時」というわけです。

別の見方をすると,CoWにおいてはデータの上書きというのは存在せず,必ずコピーされたデータを変更するということになります。たとえ1バイトでも変更されたら,元のデータとは違う領域に変更後のデータが保存されるということです。

これが何を意味するのか。元のデータへのポインタさえ残っていれば,変更前のデータが必ず取り出せるということです。APFSを含め,CoWなファイルシステムにおけるスナップショット(snapshot)とは,このもとのデータへのポインタのことなのです。先ほどのSwiftのコードのorigに相当します。

スナップショットがあると何がうれしいか。まず,Undoが超簡単になります。Swiftの例であれば,もう一度copy = origするだけです。それがファイルシステム全体に対して行えるのです。

実際にやってみましょう。macOSにはv10.5以来Time Machineというバックアップ用インターフェースが用意されています。賢明なる読者のみなさんはすでに使っていらっしゃるはずですが,High Sierraよりこれはスナップショットへのインターフェースともなっています。

まずは念のためにTime Machineを有効にしておきましょう図1)⁠バックアップ先は用意しなくてもOKです。システム設定の自動バックアップにチェックを入れてもOKですし,Terminalからsudo tmutil enableを実行してもOKです。

図1 Time Machineを有効にしておく

図1 Time Machineを有効にしておく

これだけで,1時間おきに自動でスナップショットが作られるのですが,tmutil snap shotで手動でスナップショットを取ることもできます。完了は一瞬です。CoWではデータの複製は書き込み時なのですから,⁠ここがスナップショット」以上の情報は書き込まないのですから当然です。

$ tmutil localsnapshot
Created local snapshot with date: 2017-10-17-165216

スナップショットのリストは,tmutil listlocalsnapshotsのあとにマウントポイントを指定して見ることができます。

% tmutil listlocalsnapshots /
com.apple.TimeMachine.2017-10-18-150407
com.apple.TimeMachine.2017-10-18-160303
com.apple.TimeMachine.2017-10-18-170437
com.apple.TimeMachine.2017-10-18-180253
com.apple.TimeMachine.2017-10-18-190345
com.apple.TimeMachine.2017-10-18-200341
com.apple.TimeMachine.2017-10-18-210231
com.apple.TimeMachine.2017-10-18-220244
com.apple.TimeMachine.2017-10-18-230916
com.apple.TimeMachine.2017-10-19-000459
com.apple.TimeMachine.2017-10-19-010440
com.apple.TimeMachine.2017-10-19-021104
com.apple.TimeMachine.2017-10-19-030708
com.apple.TimeMachine.2017-10-19-040243
com.apple.TimeMachine.2017-10-19-050420
com.apple.TimeMachine.2017-10-19-070312
com.apple.TimeMachine.2017-10-19-080249
com.apple.TimeMachine.2017-10-19-090235
com.apple.TimeMachine.2017-10-19-111504
com.apple.TimeMachine.2017-10-19-122825
com.apple.TimeMachine.2017-10-19-133025
com.apple.TimeMachine.2017-10-19-142826

著者プロフィール

小飼弾(こがいだん)

1969年生まれ,東京都出身。元ライブドア取締役の肩書きよりも,最近はPokemon GOのガチトレーナーのほうが有名になりつつある……かもしれない永遠のエンジニアオヤジ。

活躍の場はIT業界だけでなく,サブカルからアカデミックまで多方面にわたり,ネットからの情報発信は気の向くまま毎日毎秒! https://twitter.com/dankogai,ニコニコチャンネルは,http://ch.nicovideo.jp/dankogai,blogはhttp://blog.livedoor.jp/dankogai/

当社刊行書籍は『小飼弾のアルファギークに逢ってきた』『小飼弾のコードなエッセイ』など。他にも著書多数。

コメント

コメントの記入