Description
Is your feature request related to a problem? Please describe.
Proper MVCC transactions make use of a snapshot that represent the state of the database. As mutations (put & delete) build up, they apply to the snapshot. This makes it easier to build up a transaction by composing procedures/functions that mutate a transaction object. It means you get read-after-write consistency within the snapshot. Where you may have an operation that depends on the state of the database. Like let's say a counter increment. But if the prior mutation to the transaction already incremented the same counter, it would be incoherent for the subsequent mutation to plus 1 to the counter thinking the counter hasn't already been incremented.
Right now leveldb already supports snapshots natively. However it's not exposed via the JS wrapper. There are pre-existing issues.
If we could have snapshot isolated transactions, it would simplify some of our algorithms here for inodes especially since we have counter increment operations that result from linking and unlinking the inodes.
Describe the solution you'd like
Have a snapshot ability for the leveldb that we can expose through our DB
abstraction. Similar to the python library of leveldb: https://plyvel.readthedocs.io/en/latest/api.html#snapshot
Note that a snapshot by itself is not sufficient to provide snapshot-isolated transactions. A combination of a "mutating" snapshot and the batching object which can overlay changes on top of the leveldb database can produce snapshot-isolated transactions.
This would mean an API like:
# it's very similar to https://github.com/Level/level#dbbatch-chained-form
const t = await this.db.transaction();
t.put(...);
t.get(...); // get will get the actual value determined by the snapshot (with overlayed in-memory values)
t.del(...);
t.commit();
In fact I suspect it would be possible to just extend the Batch
object to have this.
Additional context
- Snapshots Level/leveldown#486 (comment)
- http://www.bailis.org/blog/linearizability-versus-serializability/ - linearizable operations vs serializable transactions