Mid-level access API for Mnesia-managed rocksdb tables
This module implements access functions for the mnesia_rocksdb backend plugin. The functions are designed to also support direct access to rocksdb with little overhead. Such direct access will maintain existing indexes, but not support replication.
Each table has a metadata structure stored as a persistent term for fast access. The structure of the metadata is as follows:
#{ name := <Logical table name> , db_ref := <Rocksdb database Ref> , cf_handle := <Rocksdb column family handle> , activity := Ongoing batch or transaction, if any (map()) , attr_pos := #{AttrName := Pos} , mode := <Set to 'mnesia' for mnesia access flows> , properties := <Mnesia table props in map format> , type := column_family | standalone }
Helper functions like as_batch(Ref, fun(R) -> ... end)
and
with_iterator(Ref, fun(I) -> ... end)
add some extra
convenience on top of the rocksdb
API.
mrdb
updates will
not be replicated.
activity() = tx_activity() | batch_activity()
activity_type() = mrdb_activity_type() | mnesia_activity_type()
admin_tab() = {admin, alias()}
alias() = atom()
attr_pos() = #{atom() := pos()}
batch_activity() = #{type := batch, handle := batch_handle()}
batch_handle() = rocksdb:batch_handle()
cf_handle() = rocksdb:cf_handle()
db_handle() = rocksdb:db_handle()
db_ref() = #{name => table(), alias => atom(), vsn => non_neg_integer(), db_ref := db_handle(), cf_handle := cf_handle(), semantics := semantics(), encoding := encoding(), attr_pos := attr_pos(), type := column_family | standalone, status := open | closed | pre_existing, properties := properties(), mode => mnesia, ix_vals_f => fun((tuple()) -> [any()]), activity => activity(), term() => term()}
encoding() = raw | sext | term | {key_encoding(), val_encoding()}
error() = {error, any()}
index() = {tab_name(), index, any()}
index_position() = atom() | pos()
inner() = non_neg_integer()
iterator_action() = first | last | next | prev | binary() | {seek, binary()} | {seek_for_prev, binary()}
itr_handle() = rocksdb:itr_handle()
key() = any()
key_encoding() = raw | sext | term
mnesia_activity_type() = transaction | sync_transaction | async_dirty | sync_dirty
mrdb_activity_type() = tx | {tx, tx_options()} | batch
mrdb_iterator() = #mrdb_iter{i = itr_handle(), ref = db_ref()}
obj() = tuple()
outer() = non_neg_integer()
pos() = non_neg_integer()
properties() = #{record_name := atom(), attributes := [atom()], index := [{pos(), bag | ordered}]}
read_options() = [{verify_checksums, boolean()} | {fill_cache, boolean()} | {iterate_upper_bound, binary()} | {iterate_lower_bound, binary()} | {tailing, boolean()} | {total_order_seek, boolean()} | {prefix_same_as_start, boolean()} | {snapshot, snapshot_handle()}]
ref_or_tab() = table() | db_ref()
retainer() = {tab_name(), retainer, any()}
retries() = outer() | {inner(), outer()}
semantics() = bag | set
snapshot_handle() = rocksdb:snapshot_handle()
tab_name() = atom()
table() = atom() | admin_tab() | index() | retainer()
tx_activity() = #{type := tx, handle := tx_handle(), attempt := undefined | retries()}
tx_handle() = rocksdb:transaction_handle()
tx_options() = #{retries => retries(), no_snapshot => boolean()}
val_encoding() = {value | object, term | raw} | raw
write_options() = [{sync, boolean()} | {disable_wal, boolean()} | {ignore_missing_column_families, boolean()} | {no_slowdown, boolean()} | {low_pri, boolean()}]
abort(Reason) -> any()
Aborts an ongoing activity/2
activity(Type::activity_type(), Alias::alias(), F::fun(() -> Res)) -> Res
Run an activity (similar to //mnesia/mnesia:activity/2
).
transaction
- An optimistic rocksdb
transaction{tx, TxOpts}
- A rocksdb
transaction with sligth modificationsbatch
- A rocksdb
batch operationBy default, transactions are combined with a snapshot with 1 retry.
The snapshot ensures that writes from concurrent transactions don't leak into the transaction context.
A transaction will be retried if it detects that the commit set conflicts with recent changes.
A mutex is used to ensure that only one of potentially conflicting mrdb
transactions is run at a time.
The re-run transaction may still fail, if new transactions, or non-transaction writes interfere with
the commit set. It will then be re-run again, until the retry count is exhausted.
For finer-grained retries, it's possible to set retries => {Inner, Outer}
. Setting the retries to a
single number, Retries
, is analogous to {0, Retries}`. Each outer retry requests a
mutex lock' by
waiting in a FIFO queue. Once it receives the lock, it will try the activity once + as many retries
as specified by Inner
. If these fail, the activity again goes to the FIFO queue (ending up last
in line) if there are outer retries remaining. When all retries are exhaused, the activity aborts
with retry_limit
. Note that transactions, being optimistic, do not request a lock on the first
attempt, but only on outer retries (the first retry is always an outer retry).
Valid TxOpts
are #{no_snapshot => boolean(), retries => retries()}
.
tx | transaction | sync_transaction
are synonyms, and
batch | async_dirty | sync_dirty
are synonyms.
alias_of(Tab::ref_or_tab()) -> alias()
Returns the alias of a given table or table reference.
as_batch(Tab::ref_or_tab(), F::fun((db_ref()) -> Res)) -> Res
Creates a rocksdb
batch context and executes the fun F
in it.
as_batch(Tab, F, Opts) -> any()
as as_batch/2
, but with the ability to pass Opts
to rocksdb:write_batch/2
batch_write(Tab, L) -> any()
batch_write(Tab, L, Opts) -> any()
clear_table(Tab) -> any()
current_context() -> any()
delete(Tab::ref_or_tab(), Key::key()) -> ok
delete(Tab::ref_or_tab(), Key::key(), Opts::write_options()) -> ok
delete_object(Tab, Obj) -> any()
delete_object(Tab, Obj, Opts) -> any()
ensure_ref(R::ref_or_tab()) -> db_ref()
ensure_ref(Ref, R) -> any()
first(Tab::ref_or_tab()) -> key() | '$end_of_table'
first(Tab::ref_or_tab(), Opts::read_options()) -> key() | '$end_of_table'
fold(Tab, Fun, Acc) -> any()
fold(Tab, Fun, Acc, MatchSpec) -> any()
fold(Tab, Fun, Acc, MatchSpec, Limit) -> any()
get_batch(X1) -> any()
index_read(Tab, Val, Ix) -> any()
insert(Tab::ref_or_tab(), Obj::obj()) -> ok
insert(Tab::ref_or_tab(), Obj0::obj(), Opts::write_options()) -> ok
iterator(Tab::ref_or_tab()) -> {ok, mrdb_iterator()} | {error, term()}
iterator(Tab::ref_or_tab(), Opts::read_options()) -> {ok, mrdb_iterator()} | {error, term()}
iterator_close(Mrdb_iter::mrdb_iterator()) -> ok
iterator_move(Mrdb_iter::mrdb_iterator(), Dir::iterator_action()) -> {ok, tuple()} | {error, any()}
last(Tab::ref_or_tab()) -> key() | '$end_of_table'
last(Tab::ref_or_tab(), Opts::read_options()) -> key() | '$end_of_table'
match_delete(Tab, Pat) -> any()
new_tx(Tab::ref_or_tab(), Opts::write_options()) -> db_ref()
next(Tab::ref_or_tab(), K::key()) -> key() | '$end_of_table'
next(Tab::ref_or_tab(), K::key(), Opts::read_options()) -> key() | '$end_of_table'
prev(Tab::ref_or_tab(), K::key()) -> key() | '$end_of_table'
prev(Tab::ref_or_tab(), K::key(), Opts::read_options()) -> key() | '$end_of_table'
rdb_delete(R, K) -> any()
rdb_delete(R, K, Opts) -> any()
rdb_fold(Tab, Fun, Acc, Prefix) -> any()
rdb_fold(Tab, Fun, Acc, Prefix, Limit) -> any()
rdb_get(R, K) -> any()
rdb_get(R, K, Opts) -> any()
rdb_iterator(R) -> any()
rdb_iterator(R, Opts) -> any()
rdb_iterator_move(I, Dir) -> any()
rdb_put(R, K, V) -> any()
rdb_put(R, K, V, Opts) -> any()
read(Tab, Key) -> any()
read(Tab, Key, Opts) -> any()
read_info(Tab) -> any()
read_info(Tab, K) -> any()
release_snapshot(SHandle::snapshot_handle()) -> ok | error()
release a snapshot created by snapshot/1
.
select(Cont) -> any()
select(Tab, Pat) -> any()
select(Tab, Pat, Limit) -> any()
snapshot(Name::alias() | ref_or_tab()) -> {ok, snapshot_handle()} | error()
Create a snapshot of the database instance associated with the table reference, table name or alias.
Snapshots provide consistent read-only views over the entire state of the key-value store.tx_commit(TxH::tx_handle() | db_ref()) -> ok
tx_ref(Tab::ref_or_tab() | db_ref() | db_ref(), TxH::tx_handle()) -> db_ref()
update_counter(Tab, C, Val) -> any()
update_counter(Tab, C, Val, Opts) -> any()
with_iterator(Tab::ref_or_tab(), Fun::fun((mrdb_iterator()) -> Res)) -> Res
with_iterator(Tab::ref_or_tab(), Fun::fun((mrdb_iterator()) -> Res), Opts::read_options()) -> Res
with_rdb_iterator(Tab::ref_or_tab(), Fun::fun((itr_handle()) -> Res)) -> Res
with_rdb_iterator(Tab::ref_or_tab(), Fun::fun((itr_handle()) -> Res), Opts::read_options()) -> Res
write_info(Tab, K, V) -> any()
Generated by EDoc