84 lines
3.6 KiB
Erlang
84 lines
3.6 KiB
Erlang
%% ===================================================================
|
||
%% EventHub – утилита фрагментации больших таблиц Mnesia
|
||
%% ===================================================================
|
||
-module(infra_mnesia_fragmentation).
|
||
|
||
-export([
|
||
fragment_table/2,
|
||
defragment_table/1,
|
||
add_fragment/2,
|
||
info/1
|
||
]).
|
||
|
||
%% -------------------------------------------------------------------
|
||
%% @doc Включает фрагментацию для заданной таблицы.
|
||
%% Table - имя таблицы (atom)
|
||
%% FragCount - количество фрагментов (integer > 1)
|
||
%%
|
||
%% После вызова таблица будет автоматически распределена
|
||
%% по фрагментам. Новые записи будут попадать в нужный фрагмент
|
||
%% на основе хеша ключа.
|
||
%%
|
||
%% Пример:
|
||
%% infra_mnesia_fragmentation:fragment_table(event, 4).
|
||
%% -------------------------------------------------------------------
|
||
fragment_table(Table, FragCount) when FragCount > 1 ->
|
||
case mnesia:change_table_frag(Table, {activate, FragCount}) of
|
||
{atomic, ok} ->
|
||
io:format("Table ~p successfully fragmented into ~p fragments~n", [Table, FragCount]),
|
||
ok;
|
||
{aborted, Reason} ->
|
||
{error, {fragmentation_failed, Table, Reason}}
|
||
end;
|
||
|
||
fragment_table(_Table, FragCount) ->
|
||
{error, {invalid_frag_count, FragCount}}.
|
||
|
||
%% -------------------------------------------------------------------
|
||
%% @doc Отключает фрагментацию, возвращая таблицу к обычному виду.
|
||
%% Все данные остаются сохранными, но таблица перестаёт быть
|
||
%% фрагментированной. Может занять продолжительное время
|
||
%% на больших объёмах.
|
||
%% -------------------------------------------------------------------
|
||
defragment_table(Table) ->
|
||
case mnesia:change_table_frag(Table, deactivate) of
|
||
{atomic, ok} ->
|
||
io:format("Fragmentation removed for table ~p~n", [Table]),
|
||
ok;
|
||
{aborted, Reason} ->
|
||
{error, {defragmentation_failed, Table, Reason}}
|
||
end.
|
||
|
||
%% -------------------------------------------------------------------
|
||
%% @doc Добавляет новый фрагмент к уже фрагментированной таблице.
|
||
%% Полезно для постепенного масштабирования.
|
||
%% -------------------------------------------------------------------
|
||
add_fragment(Table, ExtraFrags) ->
|
||
case mnesia:add_table_fragment(Table, ExtraFrags) of
|
||
{atomic, ok} ->
|
||
io:format("Added ~p fragment(s) to table ~p~n", [ExtraFrags, Table]),
|
||
ok;
|
||
{aborted, Reason} ->
|
||
{error, {add_fragment_failed, Table, Reason}}
|
||
end.
|
||
|
||
%% -------------------------------------------------------------------
|
||
%% @doc Выводит информацию о фрагментации таблицы (если включена)
|
||
%% или о текущем состоянии.
|
||
%% -------------------------------------------------------------------
|
||
info(Table) ->
|
||
try
|
||
IsFrag = mnesia:table_info(Table, frag_property),
|
||
FragCount = case IsFrag of
|
||
[{n_fragments, N} | _] -> N;
|
||
_ -> 1
|
||
end,
|
||
io:format("Table ~p fragmentation: ~p fragments~n", [Table, FragCount]),
|
||
FragList = mnesia:table_info(Table, frag_dist),
|
||
io:format("Fragment distribution: ~p~n", [FragList]),
|
||
ok
|
||
catch
|
||
_:_ ->
|
||
io:format("Table ~p is not fragmented~n", [Table]),
|
||
ok
|
||
end. |