2009-05-04 9 views
10

J'ai un groupe de nœuds erlang qui répliquent leurs données via les "noeuds_supplémentaires" de Mnesia ... J'ai besoin de mettre à niveau le matériel et le logiciel, donc je dois détacher certains nœuds au fur et à mesure nœud à nœud.comment puis-je supprimer un noeud supplémentaire

Comment supprimer un nœud tout en conservant les données insérées? [Update] supprimer des nœuds est aussi important que de les ajouter. Au fil du temps, lorsque votre cluster se développe, il doit également se contracter. Si ce n'est pas le cas, Mnesia va être occupé à essayer d'envoyer des données à des noeuds inexistants pour remplir les files d'attente et maintenir le réseau occupé.

[mise à jour finale] après avoir versé le code source erlang/mnesia, j'ai pu déterminer qu'il n'était pas possible de dissocier complètement les nœuds. Tandis que del_table_copy supprime le lien entre les tables, il est incomplet. Je voudrais fermer cette question, mais aucune des descriptions proches ne sont adéquates.

+0

chances de pirates Erlang passant ici? faible. Mais j'ai trouvé la question intrigante, et je suis en train de regarder erlang et mnesia, alors quand je l'aurai appris, je pourrais revenir dans un an ou deux et donner une réponse! merci pour le poste intéressant – Will

+0

bien, il y a 19 questions de mnesia, donc les chances ne sont pas si bas. Plus la question est précise, plus vous aurez de temps à attendre pour obtenir une réponse, c'est tout. –

+0

C'est juste une question de temps avant que j'écrase le code et que je me cherche. J'aurai amplement de temps la semaine prochaine lorsque ma mise à pied sera définitive. – Richard

Répondre

0

Si vous avez répliqué la table (copies de table ajoutées) sur des noeuds autres que celui que vous supprimez, alors vous êtes déjà bien - il suffit de retirer le noeud.

Si vous souhaitez être légèrement plus rangé, supprimez les copies de table du nœud que vous êtes sur le point de supprimer en premier via mnesia:del_table_copy/2. En général, Mnesia gère avec élégance la perte de noeud et détecte le noeud rejoint (les noeuds redémarrés obtiennent de nouvelles copies de table à partir de noeuds maintenus, les noeuds qui n'ont pas redémarré sont détectés en tant qu'événement de partition réseau). Mnesia ne consomme pas de trafic CPU ou réseau pour les nœuds qui sont tombés. Je pense, bien que je ne l'ai pas confirmé dans la source, la mnesia ne se reconnectera pas aux noeuds qui sont descendus automatiquement - le noeud qui descend devrait redémarrer (mnesia) et se reconnecter.

mnesia:add_table_copy/3, mnesia:move_table_copy/3 et mnesia:del_table_copy/2 sont les fonctions que vous devez rechercher pour la gestion de schéma en temps réel.

Ce paramètre ne doit être utilisé que lors de l'initialisation d'un nouveau noeud de base de données.

+0

Je suis sur la clôture avec cette réponse. J'aime les informations générales, cependant, ce n'est pas courant. Les trois méthodes que vous mentionnez ne sont pas incluses dans la version R13B. Une recherche du code R13A n'a révélé aucune méthode similaire. – Richard

+0

Poursuivant ma recherche de la source j'ai trouvé une indication qu'il y a un appel à mnesia_controller: add_list/2 qui est utilisé lors de l'ajout du noeud supplémentaire. Il y a un commentaire qui suggère d'appeler mnesia_recover: disconnect_nodes/1, cependant, cette méthode n'existe nulle part et pourrait simplement être une faute de frappe; mnesia_recover: disconnect/1 existe. – Richard

+0

J'ai dit delete_table_copy au lieu de del_table copy, mais en dehors de cela, ces méthodes sont présentes, documentées et à jour. Vous ne devriez pas avoir à déconnecter les nœuds à la main - Mnesia gère la déconnexion des nœuds par lui-même. Il suffit d'éteindre les nœuds indésirables. Ou utilisez net_kernel: disconnect/1 pour le forcer. – archaelus

1

J'ai certainement utilisé cette méthode pour effectuer ceci (supportant le mnesia: del_table_copy/2 use). Voir removeNode/1 ci-dessous:

-module(tool_bootstrap). 

-export([bootstrapNewNode/1, closedownNode/0, 
    finalBootstrap/0, removeNode/1]). 

-include_lib("records.hrl"). 

-include_lib("stdlib/include/qlc.hrl"). 

bootstrapNewNode(Node) -> 
    %% Make the given node part of the family and start the cloud on it 
    mnesia:change_config(extra_db_nodes, [Node]), 
    %% Now make the other node set things up 
    rpc:call(Node, tool_bootstrap, finalBootstrap, []). 

removeNode(Node) -> 
    rpc:call(Node, tool_bootstrap, closedownNode, []), 
    mnesia:del_table_copy(schema, Node). 

finalBootstrap() -> 
    %% Code removed to actually copy over my tables etc... 
    application:start(cloud). 

closedownNode() -> 
    application:stop(cloud), mnesia:stop(). 
+0

alors que ce code peut sembler fonctionner, il ne nettoie pas toutes les données. del_table_copy ne supprime pas le noeud de la liste extra_db_node.En fait, il n'y a pas de code dans la source qui supprime complètement le noeud. – Richard

+0

Oui, vous avez raison. J'ai supprimé tout le code spécifique à mon application pour plus de clarté ... –

+0

Le code source dont je parlais est dans la bibliothèque Mnesia. – Richard

2

Je suis très en retard à la fête, mais suis tombé sur cette information dans le document lors de la recherche d'une solution au même problème:

« L'appel de fonction mnesia:.. del_table_copy (schéma, mynode @ hôte) supprime le nœud 'mynode @ host' du système Mnesia l'appel échoue si mnesia est en cours d'exécution sur 'mynode @ host' les autres nœuds de Mnesia ne seront jamais essayer pour se connecter à nouveau à ce nœud . ote, s'il y a un schéma de résident sur le nœud 'mynode @ host', le répertoire complet de mnesia doit être supprimé. Cela peut être fait avec mnesia: delete_schema/1. Si mnesia est démarré à nouveau sur le nœud « mynode @ host » et le répertoire n'a pas été effacé, le comportement de mnesia est indéfini. » (http://www.erlang.org/doc/apps/mnesia/ Mnesia_chap5.html # id74278)

Je pense que ce qui suit pourrait faire ce que vous désirez:

AllTables = mnesia:system_info(tables), 
DataTables = lists:filter(fun(Table) -> Table =/= schema end, 
          AllTables), 

RemoveTableCopy = fun(Table,Node) -> 
    Nodes = mnesia:table_info(Table,ram_copies) ++ 
      mnesia:table_info(Table,disc_copies) ++ 
      mnesia:table_info(Table,disc_only_copies), 
    case lists:is_member(Node,Nodes) of 
    true -> mnesia:del_table_copy(Table,Node); 
    false -> ok 
    end 
end, 

[RemoveTableCopy(Tbl,'[email protected]_host') || Tbl <- DataTables]. 

rpc:call('[email protected]_host',mnesia,stop,[]), 
rpc:call('[email protected]_host',mnesia,delete_schema,[SchemaDir]), 
RemoveTablecopy(schema,'[email protected]_host'). 

Bien que, je l'ai pas testé depuis mon scénario est légèrement différent.

Questions connexes