Current section

Files

Jump to
rocksdb test transaction_statistics.erl
Raw

test/transaction_statistics.erl

%% Copyright (c) 2025 Benoit Chesneau
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License. You may obtain
%% a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations
%% under the License.
-module(transaction_statistics).
-include_lib("eunit/include/eunit.hrl").
-define(rm_rf(Dir), rocksdb_test_util:rm_rf(Dir)).
txn_mutex_overhead_test() ->
?rm_rf("test_txn_stats"),
{ok, Stats} = rocksdb:new_statistics(),
{ok, Db, _} = rocksdb:open_pessimistic_transaction_db(
"test_txn_stats",
[{create_if_missing, true},
{statistics, Stats}],
[{"default", []}]),
try
%% Create and commit transactions to generate statistics
lists:foreach(
fun(I) ->
{ok, Txn} = rocksdb:pessimistic_transaction(Db, []),
Key = <<$t, (integer_to_binary(I))/binary>>,
Value = list_to_binary(lists:duplicate(50, $a)),
ok = rocksdb:pessimistic_transaction_put(Txn, Key, Value),
ok = rocksdb:pessimistic_transaction_commit(Txn),
ok = rocksdb:release_pessimistic_transaction(Txn)
end,
lists:seq(1, 20)),
%% Check txn_prepare_mutex_overhead is readable
{ok, PrepareMutex} = rocksdb:statistics_ticker(Stats, txn_prepare_mutex_overhead),
?assert(is_integer(PrepareMutex)),
?assert(PrepareMutex >= 0),
%% Check txn_old_commit_map_mutex_overhead is readable
{ok, CommitMapMutex} = rocksdb:statistics_ticker(Stats, txn_old_commit_map_mutex_overhead),
?assert(is_integer(CommitMapMutex)),
?assert(CommitMapMutex >= 0)
after
ok = rocksdb:close(Db),
ok = rocksdb:release_statistics(Stats),
?rm_rf("test_txn_stats")
end,
ok.
txn_duplicate_key_overhead_test() ->
?rm_rf("test_txn_dup_stats"),
{ok, Stats} = rocksdb:new_statistics(),
{ok, Db, _} = rocksdb:open_pessimistic_transaction_db(
"test_txn_dup_stats",
[{create_if_missing, true},
{statistics, Stats}],
[{"default", []}]),
try
%% Write duplicate keys in the same transaction
{ok, Txn} = rocksdb:pessimistic_transaction(Db, []),
lists:foreach(
fun(I) ->
Key = <<"dup_key">>,
Value = list_to_binary([I | lists:duplicate(49, $b)]),
ok = rocksdb:pessimistic_transaction_put(Txn, Key, Value)
end,
lists:seq(1, 10)),
ok = rocksdb:pessimistic_transaction_commit(Txn),
ok = rocksdb:release_pessimistic_transaction(Txn),
%% Check txn_duplicate_key_overhead is readable
{ok, DupKeyOverhead} = rocksdb:statistics_ticker(Stats, txn_duplicate_key_overhead),
?assert(is_integer(DupKeyOverhead)),
?assert(DupKeyOverhead >= 0)
after
ok = rocksdb:close(Db),
ok = rocksdb:release_statistics(Stats),
?rm_rf("test_txn_dup_stats")
end,
ok.
txn_snapshot_mutex_overhead_test() ->
?rm_rf("test_txn_snapshot_stats"),
{ok, Stats} = rocksdb:new_statistics(),
{ok, Db, _} = rocksdb:open_pessimistic_transaction_db(
"test_txn_snapshot_stats",
[{create_if_missing, true},
{statistics, Stats}],
[{"default", []}]),
try
%% Create transactions with snapshots
lists:foreach(
fun(I) ->
{ok, Txn} = rocksdb:pessimistic_transaction(Db, [{set_snapshot, true}]),
Key = <<$s, (integer_to_binary(I))/binary>>,
Value = list_to_binary(lists:duplicate(50, $c)),
ok = rocksdb:pessimistic_transaction_put(Txn, Key, Value),
ok = rocksdb:pessimistic_transaction_commit(Txn),
ok = rocksdb:release_pessimistic_transaction(Txn)
end,
lists:seq(1, 10)),
%% Check txn_snapshot_mutex_overhead is readable
{ok, SnapshotMutex} = rocksdb:statistics_ticker(Stats, txn_snapshot_mutex_overhead),
?assert(is_integer(SnapshotMutex)),
?assert(SnapshotMutex >= 0)
after
ok = rocksdb:close(Db),
ok = rocksdb:release_statistics(Stats),
?rm_rf("test_txn_snapshot_stats")
end,
ok.
txn_get_try_again_test() ->
?rm_rf("test_txn_try_again_stats"),
{ok, Stats} = rocksdb:new_statistics(),
{ok, Db, _} = rocksdb:open_pessimistic_transaction_db(
"test_txn_try_again_stats",
[{create_if_missing, true},
{statistics, Stats}],
[{"default", []}]),
try
%% Insert some initial data
{ok, Txn1} = rocksdb:pessimistic_transaction(Db, []),
ok = rocksdb:pessimistic_transaction_put(Txn1, <<"key1">>, <<"value1">>),
ok = rocksdb:pessimistic_transaction_commit(Txn1),
ok = rocksdb:release_pessimistic_transaction(Txn1),
%% Perform reads that might trigger try_again
{ok, Txn2} = rocksdb:pessimistic_transaction(Db, [{set_snapshot, true}]),
_ = rocksdb:pessimistic_transaction_get(Txn2, <<"key1">>, []),
ok = rocksdb:pessimistic_transaction_commit(Txn2),
ok = rocksdb:release_pessimistic_transaction(Txn2),
%% Check txn_get_try_again is readable
{ok, TryAgain} = rocksdb:statistics_ticker(Stats, txn_get_try_again),
?assert(is_integer(TryAgain)),
?assert(TryAgain >= 0)
after
ok = rocksdb:close(Db),
ok = rocksdb:release_statistics(Stats),
?rm_rf("test_txn_try_again_stats")
end,
ok.
all_transaction_tickers_readable_test() ->
?rm_rf("test_all_txn_tickers"),
{ok, Stats} = rocksdb:new_statistics(),
{ok, Db, _} = rocksdb:open_pessimistic_transaction_db(
"test_all_txn_tickers",
[{create_if_missing, true},
{statistics, Stats}],
[{"default", []}]),
try
%% Test that all transaction tickers are readable
Tickers = [
txn_prepare_mutex_overhead,
txn_old_commit_map_mutex_overhead,
txn_duplicate_key_overhead,
txn_snapshot_mutex_overhead,
txn_get_try_again
],
lists:foreach(
fun(Ticker) ->
{ok, Value} = rocksdb:statistics_ticker(Stats, Ticker),
?assert(is_integer(Value)),
?assert(Value >= 0)
end,
Tickers)
after
ok = rocksdb:close(Db),
ok = rocksdb:release_statistics(Stats),
?rm_rf("test_all_txn_tickers")
end,
ok.
num_op_per_transaction_histogram_test() ->
?rm_rf("test_txn_ops_hist"),
{ok, Stats} = rocksdb:new_statistics(),
{ok, Db, _} = rocksdb:open_pessimistic_transaction_db(
"test_txn_ops_hist",
[{create_if_missing, true},
{statistics, Stats}],
[{"default", []}]),
try
%% Create a transaction with multiple operations
{ok, Txn} = rocksdb:pessimistic_transaction(Db, []),
lists:foreach(
fun(I) ->
Key = <<$k, (integer_to_binary(I))/binary>>,
Value = list_to_binary(lists:duplicate(50, $v)),
ok = rocksdb:pessimistic_transaction_put(Txn, Key, Value)
end,
lists:seq(1, 10)),
ok = rocksdb:pessimistic_transaction_commit(Txn),
ok = rocksdb:release_pessimistic_transaction(Txn),
%% Check num_op_per_transaction histogram is readable
{ok, OpHist} = rocksdb:statistics_histogram(Stats, num_op_per_transaction),
?assert(is_map(OpHist)),
?assert(is_float(maps:get(median, OpHist))),
?assert(is_float(maps:get(percentile95, OpHist))),
?assert(is_float(maps:get(percentile99, OpHist))),
?assert(is_float(maps:get(average, OpHist))),
?assert(is_integer(maps:get(count, OpHist))),
?assert(is_integer(maps:get(sum, OpHist)))
after
ok = rocksdb:close(Db),
ok = rocksdb:release_statistics(Stats),
?rm_rf("test_txn_ops_hist")
end,
ok.