aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2017-04-21 12:27:15 +0300
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2017-04-21 12:27:15 +0300
commit02790b105e66181c7c2089bac2d9df2615558cc3 (patch)
tree9cbd6392a7225f4f22fc31e79fbd1623a29b749d /src
parentUse new cache API in mod_shared_roster_ldap (diff)
Speedup Mnesia tables initialization
Diffstat (limited to 'src')
-rw-r--r--src/acl.erl2
-rw-r--r--src/ejabberd_app.erl25
-rw-r--r--src/ejabberd_commands.erl1
-rw-r--r--src/ejabberd_config.erl3
-rw-r--r--src/ejabberd_local.erl1
-rw-r--r--src/ejabberd_mnesia.erl88
-rw-r--r--src/ejabberd_oauth_mnesia.erl1
-rw-r--r--src/ejabberd_router_mnesia.erl1
-rw-r--r--src/ejabberd_router_multicast.erl1
-rw-r--r--src/ejabberd_s2s.erl1
-rw-r--r--src/ejabberd_sql_sup.erl1
-rw-r--r--src/mod_bosh_mnesia.erl3
-rw-r--r--src/mod_caps_mnesia.erl4
-rw-r--r--src/mod_carboncopy_mnesia.erl3
-rw-r--r--src/mod_muc_mnesia.erl1
-rw-r--r--src/mod_proxy65_mnesia.erl1
-rw-r--r--src/mod_register.erl2
-rw-r--r--src/shaper.erl1
18 files changed, 89 insertions, 51 deletions
diff --git a/src/acl.erl b/src/acl.erl
index 40ab682e5..0cdd7daa6 100644
--- a/src/acl.erl
+++ b/src/acl.erl
@@ -92,8 +92,6 @@ init([]) ->
[{ram_copies, [node()]},
{local_content, true},
{attributes, record_info(fields, access)}]),
- mnesia:add_table_copy(acl, node(), ram_copies),
- mnesia:add_table_copy(access, node(), ram_copies),
ejabberd_hooks:add(config_reloaded, ?MODULE, load_from_config, 20),
load_from_config(),
{ok, #state{}}.
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl
index 579696302..214c38b21 100644
--- a/src/ejabberd_app.erl
+++ b/src/ejabberd_app.erl
@@ -46,7 +46,7 @@ start(normal, _Args) ->
start_apps(),
start_elixir_application(),
ejabberd:check_app(ejabberd),
- db_init(),
+ ejabberd_mnesia:start(),
setup_if_elixir_conf_used(),
ejabberd_config:start(),
set_settings_from_config(),
@@ -87,29 +87,6 @@ stop(_State) ->
%%% Internal functions
%%%
-db_init() ->
- ejabberd_config:env_binary_to_list(mnesia, dir),
- MyNode = node(),
- DbNodes = mnesia:system_info(db_nodes),
- case lists:member(MyNode, DbNodes) of
- true ->
- ok;
- false ->
- ?CRITICAL_MSG("Node name mismatch: I'm [~s], "
- "the database is owned by ~p", [MyNode, DbNodes]),
- ?CRITICAL_MSG("Either set ERLANG_NODE in ejabberdctl.cfg "
- "or change node name in Mnesia", []),
- erlang:error(node_name_mismatch)
- end,
- case mnesia:system_info(extra_db_nodes) of
- [] ->
- mnesia:create_schema([node()]);
- _ ->
- ok
- end,
- ejabberd:start_app(mnesia, permanent),
- mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
-
connect_nodes() ->
Nodes = ejabberd_config:get_option(
cluster_nodes,
diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl
index d84a671d5..df0ce9123 100644
--- a/src/ejabberd_commands.erl
+++ b/src/ejabberd_commands.erl
@@ -297,7 +297,6 @@ init([]) ->
{local_content, true},
{attributes, record_info(fields, ejabberd_commands)},
{type, bag}]),
- mnesia:add_table_copy(ejabberd_commands, node(), ram_copies),
register_commands(get_commands_spec()),
ejabberd_access_permissions:register_permission_addon(?MODULE, fun permission_addon/0),
{ok, #state{}}.
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index 4b9e20f7a..bbef755a9 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -116,8 +116,7 @@ mnesia_init() ->
ejabberd_mnesia:create(?MODULE, local_config,
[{ram_copies, [node()]},
{local_content, true},
- {attributes, record_info(fields, local_config)}]),
- mnesia:add_table_copy(local_config, node(), ram_copies).
+ {attributes, record_info(fields, local_config)}]).
%% @doc Get the filename of the ejabberd configuration file.
%% The filename can be specified with: erl -config "/path/to/ejabberd.yml".
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index 00ce22274..c1b21d508 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -207,7 +207,6 @@ init([]) ->
ejabberd_mnesia:create(?MODULE, iq_response,
[{ram_copies, [node()]},
{attributes, record_info(fields, iq_response)}]),
- mnesia:add_table_copy(iq_response, node(), ram_copies),
{ok, #state{}}.
handle_call(_Request, _From, State) ->
diff --git a/src/ejabberd_mnesia.erl b/src/ejabberd_mnesia.erl
index c0f25131a..1a1a62a51 100644
--- a/src/ejabberd_mnesia.erl
+++ b/src/ejabberd_mnesia.erl
@@ -30,21 +30,82 @@
-module(ejabberd_mnesia).
-author('christophe.romain@process-one.net').
--export([create/3, reset/2, update/2]).
+
+-behaviour(gen_server).
+
+-export([start/0, create/3, reset/2, update/2]).
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
-define(STORAGE_TYPES, [disc_copies, disc_only_copies, ram_copies]).
-define(NEED_RESET, [local_content, type]).
-include("logger.hrl").
-create(Module, Name, TabDef)
+-record(state, {tables = #{} :: map()}).
+
+start() ->
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+
+create(Module, Name, TabDef) ->
+ gen_server:call(?MODULE, {create, Module, Name, TabDef},
+ timer:seconds(60)).
+
+init([]) ->
+ ejabberd_config:env_binary_to_list(mnesia, dir),
+ MyNode = node(),
+ DbNodes = mnesia:system_info(db_nodes),
+ case lists:member(MyNode, DbNodes) of
+ true ->
+ case mnesia:system_info(extra_db_nodes) of
+ [] -> mnesia:create_schema([node()]);
+ _ -> ok
+ end,
+ ejabberd:start_app(mnesia, permanent),
+ ?DEBUG("Waiting for Mnesia tables synchronization...", []),
+ mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity),
+ {ok, #state{}};
+ false ->
+ ?CRITICAL_MSG("Node name mismatch: I'm [~s], "
+ "the database is owned by ~p", [MyNode, DbNodes]),
+ ?CRITICAL_MSG("Either set ERLANG_NODE in ejabberdctl.cfg "
+ "or change node name in Mnesia", []),
+ {stop, node_name_mismatch}
+ end.
+
+handle_call({create, Module, Name, TabDef}, _From, State) ->
+ case maps:get(Name, State#state.tables, undefined) of
+ {TabDef, Result} ->
+ {reply, Result, State};
+ _ ->
+ Result = do_create(Module, Name, TabDef),
+ Tables = maps:put(Name, {TabDef, Result}, State#state.tables),
+ {reply, Result, #state{tables = Tables}}
+ end;
+handle_call(_Request, _From, State) ->
+ {noreply, State}.
+
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+do_create(Module, Name, TabDef)
when is_atom(Module), is_atom(Name), is_list(TabDef) ->
Path = os:getenv("EJABBERD_SCHEMA_PATH"),
Schema = schema(Path, Module, Name, TabDef),
{attributes, Attrs} = lists:keyfind(attributes, 1, Schema),
case catch mnesia:table_info(Name, attributes) of
{'EXIT', _} ->
- mnesia_op(create_table, [Name, TabDef]);
+ create(Name, TabDef);
Attrs ->
case need_reset(Name, Schema) of
true -> reset(Name, Schema);
@@ -61,7 +122,7 @@ create(Module, Name, TabDef)
reset(Name, TabDef)
when is_atom(Name), is_list(TabDef) ->
mnesia_op(delete_table, [Name]),
- mnesia_op(create_table, [Name, TabDef]).
+ create(Name, TabDef).
update(Name, TabDef)
when is_atom(Name), is_list(TabDef) ->
@@ -120,6 +181,25 @@ schema(Path, Module, Name, TabDef) ->
TabDef
end.
+create(Name, TabDef) ->
+ case mnesia_op(create_table, [Name, TabDef]) of
+ {atomic, ok} ->
+ add_table_copy(Name);
+ Err ->
+ Err
+ end.
+
+%% The table MUST exist, otherwise the function would fail
+add_table_copy(Name) ->
+ Type = mnesia:table_info(Name, storage_type),
+ Nodes = mnesia:table_info(Name, Type),
+ case lists:member(node(), Nodes) of
+ true ->
+ {atomic, ok};
+ false ->
+ mnesia_op(add_table_copy, [Name, node(), Type])
+ end.
+
merge(TabDef, CustomDef) ->
{CustomKeys, _} = lists:unzip(CustomDef),
CleanDef = lists:foldl(
diff --git a/src/ejabberd_oauth_mnesia.erl b/src/ejabberd_oauth_mnesia.erl
index 8a9997929..8908afd39 100644
--- a/src/ejabberd_oauth_mnesia.erl
+++ b/src/ejabberd_oauth_mnesia.erl
@@ -38,7 +38,6 @@ init() ->
[{disc_copies, [node()]},
{attributes,
record_info(fields, oauth_token)}]),
- mnesia:add_table_copy(oauth_token, node(), disc_copies),
ok.
store(R) ->
diff --git a/src/ejabberd_router_mnesia.erl b/src/ejabberd_router_mnesia.erl
index d8664fee9..76336d0b0 100644
--- a/src/ejabberd_router_mnesia.erl
+++ b/src/ejabberd_router_mnesia.erl
@@ -145,7 +145,6 @@ init([]) ->
[{ram_copies, [node()]},
{type, bag},
{attributes, record_info(fields, route)}]),
- mnesia:add_table_copy(route, node(), ram_copies),
mnesia:subscribe({table, route, simple}),
lists:foreach(
fun (Pid) -> erlang:monitor(process, Pid) end,
diff --git a/src/ejabberd_router_multicast.erl b/src/ejabberd_router_multicast.erl
index 39c119fbb..5d5acfcaa 100644
--- a/src/ejabberd_router_multicast.erl
+++ b/src/ejabberd_router_multicast.erl
@@ -120,7 +120,6 @@ init([]) ->
{type, bag},
{attributes,
record_info(fields, route_multicast)}]),
- mnesia:add_table_copy(route_multicast, node(), ram_copies),
mnesia:subscribe({table, route_multicast, simple}),
lists:foreach(
fun(Pid) ->
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index 717e85ae4..61d3b021b 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -303,7 +303,6 @@ init([]) ->
[{ram_copies, [node()]},
{type, bag},
{attributes, record_info(fields, s2s)}]),
- mnesia:add_table_copy(s2s, node(), ram_copies),
mnesia:subscribe(system),
ejabberd_commands:register_commands(get_commands_spec()),
ejabberd_mnesia:create(?MODULE, temporarily_blocked,
diff --git a/src/ejabberd_sql_sup.erl b/src/ejabberd_sql_sup.erl
index 995f90317..09aceafb4 100644
--- a/src/ejabberd_sql_sup.erl
+++ b/src/ejabberd_sql_sup.erl
@@ -53,7 +53,6 @@ start_link(Host) ->
[{ram_copies, [node()]}, {type, bag},
{local_content, true},
{attributes, record_info(fields, sql_pool)}]),
- mnesia:add_table_copy(sql_pool, node(), ram_copies),
F = fun () -> mnesia:delete({sql_pool, Host}) end,
mnesia:ets(F),
supervisor:start_link({local,
diff --git a/src/mod_bosh_mnesia.erl b/src/mod_bosh_mnesia.erl
index 5954cbe49..d018077cb 100644
--- a/src/mod_bosh_mnesia.erl
+++ b/src/mod_bosh_mnesia.erl
@@ -168,5 +168,4 @@ setup_database() ->
end,
ejabberd_mnesia:create(?MODULE, bosh,
[{ram_copies, [node()]}, {local_content, true},
- {attributes, record_info(fields, bosh)}]),
- mnesia:add_table_copy(bosh, node(), ram_copies).
+ {attributes, record_info(fields, bosh)}]).
diff --git a/src/mod_caps_mnesia.erl b/src/mod_caps_mnesia.erl
index 02ea9aaf0..30fbf766f 100644
--- a/src/mod_caps_mnesia.erl
+++ b/src/mod_caps_mnesia.erl
@@ -49,9 +49,7 @@ init(_Host, _Opts) ->
{local_content, true},
{attributes,
record_info(fields, caps_features)}]),
- update_table(),
- mnesia:add_table_copy(caps_features, node(),
- disc_only_copies).
+ update_table().
caps_read(_LServer, Node) ->
case mnesia:dirty_read({caps_features, Node}) of
diff --git a/src/mod_carboncopy_mnesia.erl b/src/mod_carboncopy_mnesia.erl
index 8b248a2de..589686c71 100644
--- a/src/mod_carboncopy_mnesia.erl
+++ b/src/mod_carboncopy_mnesia.erl
@@ -49,8 +49,7 @@ init(_Host, _Opts) ->
ejabberd_mnesia:create(?MODULE, carboncopy,
[{ram_copies, [node()]},
{attributes, record_info(fields, carboncopy)},
- {type, bag}]),
- mnesia:add_table_copy(carboncopy, node(), ram_copies).
+ {type, bag}]).
enable(LUser, LServer, LResource, NS) ->
mnesia:dirty_write(
diff --git a/src/mod_muc_mnesia.erl b/src/mod_muc_mnesia.erl
index 6a9adf4b5..8cbdfe6bd 100644
--- a/src/mod_muc_mnesia.erl
+++ b/src/mod_muc_mnesia.erl
@@ -318,7 +318,6 @@ init([Host, Opts]) ->
[{ram_copies, [node()]},
{type, ordered_set},
{attributes, record_info(fields, muc_online_room)}]),
- mnesia:add_table_copy(muc_online_room, node(), ram_copies),
catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]),
clean_table_from_bad_node(node(), MyHost),
mnesia:subscribe(system);
diff --git a/src/mod_proxy65_mnesia.erl b/src/mod_proxy65_mnesia.erl
index 2763fab6a..f2a7cc8d5 100644
--- a/src/mod_proxy65_mnesia.erl
+++ b/src/mod_proxy65_mnesia.erl
@@ -104,7 +104,6 @@ init([]) ->
ejabberd_mnesia:create(?MODULE, bytestream,
[{ram_copies, [node()]},
{attributes, record_info(fields, bytestream)}]),
- mnesia:add_table_copy(bytestream, node(), ram_copies),
{ok, #state{}}.
handle_call({activate_stream, SHA1, Initiator, MaxConnections}, _From, State) ->
diff --git a/src/mod_register.erl b/src/mod_register.erl
index d14d49358..e15165f77 100644
--- a/src/mod_register.erl
+++ b/src/mod_register.erl
@@ -57,8 +57,6 @@ start(Host, Opts) ->
ejabberd_mnesia:create(?MODULE, mod_register_ip,
[{ram_copies, [node()]}, {local_content, true},
{attributes, [key, value]}]),
- mnesia:add_table_copy(mod_register_ip, node(),
- ram_copies),
ok.
stop(Host) ->
diff --git a/src/shaper.erl b/src/shaper.erl
index cc1923f86..b4db64586 100644
--- a/src/shaper.erl
+++ b/src/shaper.erl
@@ -62,7 +62,6 @@ init([]) ->
[{ram_copies, [node()]},
{local_content, true},
{attributes, record_info(fields, shaper)}]),
- mnesia:add_table_copy(shaper, node(), ram_copies),
ejabberd_hooks:add(config_reloaded, ?MODULE, load_from_config, 20),
load_from_config(),
{ok, #state{}}.