-
Notifications
You must be signed in to change notification settings - Fork 14
Open
Description
問題
CannyLS v0.9.3以前では、プロセスの異常終了後に再起動すると本来読み込めるべきでないデータが読み込めてしまう。
状況の詳述
以下のような計算の流れを考える:
(完全なコードについてはこのissueのためのリポジトリをご覧ください)
- 2つの異なるlumpid,
lump_id1とlump_id2を準備する。 - まず
lump_id1にデータ"hoge"をputする。- ここでジャーナル領域のディスクへの同期が行われる。
- 次に
lump_id1を削除する。 - 次に
lump_id2にデータ"foo"をputする。- この時、既にメモリアロケータは"hoge"のあった領域を再利用可能として認識してしまっているため、ここに"foo"を書き込んでしまう。
- プロセスがcrashして再起動する。
lump_id1からデータが読み込める。これだけであればロールバック的な挙動として容認できるが、読み出したデータが"foo"になってしまっている。
let lump_id1 = LumpId::new(1_111);
let lump_data1 = storage.allocate_lump_data_with_bytes(b"hoge").unwrap();
storage.put(&lump_id1, &lump_data1); // lump_id1に"hoge"を書き込む。
storage.journal_sync(); // ジャーナルのディスクへの同期を行う。
storage.delete(&lump_id1); // lump_id1を削除する。
let lump_id2 = LumpId::new(22_222_222);
let lump_data2 = storage.allocate_lump_data_with_bytes(b"foo").unwrap();
storage.put(&lump_id2, &lump_data2); // lump_id2に"foo"を書き込む。
// ここでプロセスがcrashする。
let nvm = track!(FileNvm::open(path))?;
let mut storage = track!(Storage::open(nvm))?;
println!("{:?}", storage.get(&lump_i1).unwrap()); // ===> "foo"回避策
deleteを行う際には毎回syncを行う。
より良い対応に向けて
上の回避策では大幅にパフォーマンスが低下するため、以下の何れかの条件のもとでより良いパフォーマンスを満たす対応策を打ち出したい:
- ロールバック的な挙動(すなわち、削除した後で読み込めても、確実に書き込んだ値が返ってくる)は許す
- アロケータにメモリ位置を解放した通知を行うタイミングを遅らせる(遅らせた分だけ空き容量が今より常に減ったように見えるかもしれない)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels