SQLite - arosh/arosh.github.com GitHub Wiki
https://www.sqlite.org/atomiccommit.html
- ディスクは 512 バイト(4Kn のことはいったん忘れる)のセクタ単位でしか読み書きできない。それより小さい部分を変更する場合には read modify write が必要
- セクタの書き換えはアトミックではないと仮定している。ただし 線形に (セクタの先頭から末尾に向かって、あるいはその逆向きで)書き換わると仮定している。この仮定は常に正しいとは限らないが妥当と考えている
- 一応、アトミックにセクタを書き換えることができるファイルシステム向けに拡張できる余地は残している。ZFS などでは使えるかもしれない
- 書き込みは buffered で、OS によってオペレーションの並べ替えが起きる可能性があることを想定している。また fsync はちゃんと動作することを前提としている
- ファイル長が大きくなった個所にゴミが残っている可能性があることを想定している。ファイル長が大きくなった後、その箇所に SQLite が書き込みを行う前に電源断が生じる可能性を考慮している
- ファイルの削除はアトミックであると仮定している。削除中に電源断が起きて、復旧後に中途半端な状態で残っていたとして、その中身がどうなっていたとしてもそれはファイルシステムが悪い
- bitrot の対策はしていない(読み取るデータが以前に書き込んだデータと同じであることを仮定する)
- 最近 checksum の機能が増えた https://www.sqlite.org/cksumvfs.html
読み取りでは read lock を取得する。書き込みのときは reserved lock というものをまず取得する。実際に書き換えるときには exclusive lock を取得する。
WAL モードではないロールバックモードでは、書き換え前に変更前の状態をロールバックジャーナルに書き込む。UNDO ログみたいな感じかな?
https://www.sqlite.org/howtocorrupt.html
1, 2 はユーザーレベルで不適切な使い方をした時に破損するという話(それはそう)。
3 は SYNC 操作がで実際にはディスクに永続化しない、嘘をついているようなデバイスを使った場合。SYNC 操作が write barrier 的な動作しかしないようなことがあり、durability が失われる(ただし consistency があるのが憎らしい)。
4 はハードレベルでの問題。Non-powersafe flash memory controllers では障害時に触っていないファイルが破損することがある。
5 はメモリ破損の問題。ECC を使いましょう。