@@ -310,119 +310,7 @@ wait_for(stop) ->
310310
311311wait_for (tables ) ->
312312 Tables = mnesia :system_info (local_tables ),
313- case do_wait_for_tables (Tables ) of
314- {error , _ } = Error ->
315- Error ;
316- ok ->
317- case mnesia :system_info (db_nodes ) -- [node ()] of
318- [] -> ok ;
319- _OtherDBNodes ->
320- case ekka :env (skip_table_load_check , false ) of
321- true ->
322- logger :warning (" Skipping table load origin check because "
323- " 'skip_table_load_check' is set to true. "
324- " This may hide data inconsistency issues, "
325- " please unset this option after the node is up." ),
326- ok ;
327- false ->
328- % % Make sure we have loaded tables from a remote node,
329- % % or force-loaded from local copies by the user.
330- RemoteActiveReplicas = get_remote_active_replicas (),
331- case check_tables_load_from (Tables , RemoteActiveReplicas ) of
332- ok -> ok ;
333- {error , _ } = Error -> Error
334- end
335- end
336- end
337- end .
338-
339- check_tables_load_from ([], _ ) ->
340- ok ;
341- check_tables_load_from ([schema | Rest ], RemoteActiveReplicas ) ->
342- check_tables_load_from (Rest , RemoteActiveReplicas );
343- check_tables_load_from ([Tab | Rest ], RemoteActiveReplicas ) ->
344- LoadFrom = mnesia_lib :val ({Tab , load_node }),
345- LoadReason = mnesia_lib :val ({Tab , load_reason }),
346- case mnesia :table_info (Tab , local_content ) of
347- true ->
348- check_tables_load_from (Rest , RemoteActiveReplicas );
349- false ->
350- Self = node (),
351- RemoteReplicas = get_remote_replicas (Tab ),
352- case {LoadFrom , RemoteReplicas , RemoteActiveReplicas } of
353- {Self , [], _ } ->
354- % % we have no remote replica
355- check_tables_load_from (Rest , RemoteActiveReplicas );
356- {Self , [_ | _ ], []} ->
357- % % we have one or more remote replicas but we are loaded from local,
358- % % maybe force loaded by the user, as we have no active replicas other than current node.
359- logger :warning (
360- " Mnesia loaded table ~p from local copy while remote replicas ~p "
361- " exist but none are active (load_reason=~p ). "
362- " If you have intentionally force-loaded this table (e.g. after removing "
363- " remote nodes from the cluster), this warning can be safely ignored. "
364- " Otherwise, please check the network connectivity between cluster nodes, "
365- " ensure remote nodes are reachable, and restart EMQX." ,
366- [Tab , RemoteReplicas , LoadReason ]),
367- check_tables_load_from (Rest , RemoteActiveReplicas );
368- {Self , [_ | _ ], [_ | _ ]} ->
369- % % prevent the current node from starting as the table is loaded from local and there
370- % % are other active replicas in the cluster
371- logger :error (
372- " Mnesia loaded table ~p from local copy while remote active replicas ~p "
373- " are available (load_reason=~p ). "
374- " This is likely caused by a network partition or misconfiguration. "
375- " The node refuses to start to prevent data inconsistency. "
376- " Please fix the network connectivity between cluster nodes and restart EMQX." ,
377- [Tab , RemoteActiveReplicas , LoadReason ]),
378- {error , {tab_loaded_from_local_copy , Tab , LoadReason }};
379- {Self , unknown , _ } ->
380- logger :error (
381- " Mnesia loaded table ~p from local copy but this table only resides "
382- " on remote nodes (load_reason=~p ). "
383- " This is likely caused by a network partition during startup. "
384- " Please fix the network connectivity between cluster nodes and restart EMQX." ,
385- [Tab , LoadReason ]),
386- {error , {tab_loaded_from_local_copy , Tab , LoadReason }};
387- {_ , _ , _ } ->
388- check_tables_load_from (Rest , RemoteActiveReplicas )
389- end
390- end .
391-
392- % % @doc Get the remote nodes that are running emqx.
393- % %
394- % % Q: Why not use mnesia:table_info(Tab, active_replicas) -- [Self]?
395- % % A: Because it will cause a deadlock when all other nodes are restarting and waiting for
396- % % this node to start.
397- get_remote_active_replicas () ->
398- RunningNodes = ekka_mnesia :running_nodes () -- [node ()],
399- Result = erpc :multicall (RunningNodes , application , which_applications , [], 5000 ),
400- Zip = lists :zip (RunningNodes , Result ),
401- lists :filtermap (
402- fun
403- ({Node , {ok , Applications }}) ->
404- case lists :keymember (emqx , 1 , Applications ) of
405- true ->
406- {true , Node };
407- false ->
408- false
409- end ;
410- ({_ , {error , _ }}) ->
411- false
412- end ,
413- Zip
414- ).
415-
416- get_remote_replicas (Tab ) ->
417- case mnesia :table_info (Tab , storage_type ) of
418- unknown ->
419- unknown ;
420- _ ->
421- RamCopies = mnesia :table_info (Tab , ram_copies ),
422- DiscCopies = mnesia :table_info (Tab , disc_copies ),
423- DiscOnlyCopies = mnesia :table_info (Tab , disc_only_copies ),
424- lists :usort ((RamCopies ++ DiscCopies ++ DiscOnlyCopies ) -- [node ()])
425- end .
313+ do_wait_for_tables (Tables ).
426314
427315do_wait_for_tables (Tables ) ->
428316 case mnesia :wait_for_tables (Tables , 30000 ) of
0 commit comments