MacのNotes.appで過って削除されたメモを復元する
tl;dr
Notes.appを使っているとき、sqlite3の書き込みがエラーになったようで、クラウド上への同期もとっていなかったことでNotes.appのメモがあらかた消えてしまった。サルベージを試みた記録を遺しておく。
What I have done
元のファイルのありかを特定しようとする
~/Library/Containers/com.apple.Notes/Data/Library/CoreData/ExternalRecords/NotesV4/{UUID}/ICNote/_records/{[0-9]+}
に拡張子がnotesexternalrecord
の謎のファイルが大量に残っているが、このファイルはあくまでSpotlightで検索するときに、メモに対して貼っているエイリアスのようなものであるために、そこに実体が残っているというわけではない。実際にファイルサイズは0byteであった。
sqliteの素のファイルを復元しようとする
~/Library/Group Containers/group.com.apple.notes/
にNoteStore.sqlite
とNoteStore.sqlite-shm
とNoteStore.sqlite-wal
が、また~/Library/Containers/com.apple.Notes/Data/Library/Notes
にNoteV4.sqlite
とNoteV4.sqlite-shm
とNoteV4.sqlite-wal
があった。
NoteStore.sqlite
に書き込みが失敗し、新しいファイルで上書きされてしまっているようだった。NoteStore.sqlite-wal
は数MBあるため、もしかしたらデータが残っているのではないかという期待があったが、strings
してバイナリを見る限りでは、メモの中身が見えるというわけではなかった。
ダメ元でsqlite3でこのデータベースに接続してみることで、ジャーナリングをリカバーしてくれるのではないかと考えたが、sqlite3 NoteStore.sqlite vaccum;
といったコマンドを叩いたところで、.sqlite-shm
と.sqlite-wal
ファイルが消えるのは確認できたが、.sqlite
ファイルのサイズが変わらず、ジャーナリングはそのまま失われたような挙動にみえた。
このことは、もとの.sqlite
ファイルが消されてしまったので、Notes.appを起動したときに新しい.sqlite
ファイルが作られて上書きされてしまったので、リカバリが実行できなかったのではないかというのが1つと、そもそもNotes.appでは、sqlite3の書き込みにログ先行書き込みを使っているようだが(Write-Ahead Logging)、ログ先行書き込みではログを書き出していることによってアンドゥ、リドゥができるので、実際の差分を.sqlite-wal
ファイルに書き出すことをしているわけではないと考えられる。これらのことから、.sqlite-wal
には実体が入っていないと思われる。
そこでsqliteファイルをリカバリして、Note.appのもとのメモを完璧な形で復元するということは諦めた。
キャッシュを探す
Spotlightで検索したとき、消えたはずのメモが検索結果に出ることから、どこかにテキスト情報としてキャッシュされているのではないかと考えた。そこで、Spotlightのキャッシュファイルのディレクトリから、メモの内容に一致するファイルを抜き出すことを考えた。
# cd /.Spotlight-V100/Store-V2/{UUID}/Cache/ # tree
ここに、文字としてキャッシュされたファイルが保存されている。
このまま普通に全文検索してしまうと、保存されているPDFなどの関係ないテキストデータが大量にひっかかってしまう。そこで、Markdownのように箇条書きで*
を列挙していくと、•
に変換してくれるというNotes.appの挙動を利用して、文字として•
を検索するということにした。
# find . -type f -print | xargs grep • | less -S
これを使って、•
が含まれるメモについてはある程度復元することができた。そうでないメモについては、頑張ってどんな内容が含まれていたのかを頑張って思い出して、ユニークそうな単語を検索することで発見するという操作を繰り返した。
Conclusion
iCloudなどと連携して、オンラインにバックアップを常にとっておくようにしよう。