%% =================================================================== %% 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.