From 6d8f02d0d45e658ca7d102f4d28276ef4f033c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9=20=D0=A1=D0=B0?= =?UTF-8?q?=D0=B1=D0=B8=D0=BB=D0=B8=D0=BD?= Date: Thu, 16 Jul 2026 20:52:31 +0300 Subject: [PATCH] fix(mnesia): add local ram_copies on joining nodes for verification/session. Joining replicas hit already_exists without add_table_copy, so register/verify crashed with no_exists on node2. Refs EventHub/EventHubBack#30 Co-authored-by: Cursor --- src/infra/infra_mnesia.erl | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/infra/infra_mnesia.erl b/src/infra/infra_mnesia.erl index 8f05075..88ebbf2 100644 --- a/src/infra/infra_mnesia.erl +++ b/src/infra/infra_mnesia.erl @@ -24,6 +24,8 @@ ]). -define(DISC_TABLES, ?TABLES -- [session, verification, admin_session, node_metric]). +%% ram_copies: joining nodes must add_table_copy — create_table already_exists skips it. +-define(RAM_TABLES, [session, verification, admin_session]). -define(TABLE_WAIT_TIMEOUT, 5000). -define(CLEANUP_INTERVAL, 30000). % 30 секунд @@ -105,6 +107,7 @@ handle_call(init_tables, _From, State) -> ok = join_cluster(ExtraNodes) end, lists:foreach(fun create_table/1, ?TABLES), + lists:foreach(fun add_local_ram_copy/1, ?RAM_TABLES), % Принудительное создание node_metric на каждом узле case mnesia:create_table(node_metric, [ {disc_copies, [node()]}, % хранить на диске @@ -175,7 +178,8 @@ join_cluster(Nodes) -> mnesia:start(), ensure_schema_disc(), wait_for_tables_available(), - lists:foreach(fun add_local_disc_copy/1, ?DISC_TABLES). + lists:foreach(fun add_local_disc_copy/1, ?DISC_TABLES), + lists:foreach(fun add_local_ram_copy/1, ?RAM_TABLES). do_add_nodes(Nodes) -> ExtraNodes = application:get_env(eventhub, extra_db_nodes, []), @@ -183,7 +187,8 @@ do_add_nodes(Nodes) -> {ok, _} = mnesia:change_config(extra_db_nodes, Nodes), ensure_schema_disc(), wait_for_tables_available(), - lists:foreach(fun add_local_disc_copy/1, ?DISC_TABLES). + lists:foreach(fun add_local_disc_copy/1, ?DISC_TABLES), + lists:foreach(fun add_local_ram_copy/1, ?RAM_TABLES). ensure_schema_disc() -> case lists:member(node(), mnesia:table_info(schema, disc_copies)) of @@ -210,6 +215,19 @@ add_local_disc_copy(Tab) -> true -> ok end. +add_local_ram_copy(Tab) -> + case lists:member(node(), mnesia:table_info(Tab, ram_copies)) of + false -> + io:format("Adding local ram copy of table ~p...~n", [Tab]), + case mnesia:add_table_copy(Tab, node(), ram_copies) of + {atomic, ok} -> ok; + {aborted, {already_exists, _}} -> ok; + {aborted, Reason} -> + io:format("Could not add ram copy for ~p: ~p~n", [Tab, Reason]) + end; + true -> ok + end. + wait_for_tables_available() -> lists:foreach(fun(Tab) -> wait_for_table(Tab) end, ?DISC_TABLES).