2012-04-14 10 views
11

警告:背景情報はかなり長いです。背景情報の前に質問が必要だと思われる場合は、最後にスキップしてください。これは時間がかかることを感謝します!mnesiaデータベースをバックアップ/復元する適切な方法は何ですか?

私はウェブ全体(Googleを読んでいます)に行ってきましたが、私は良い答えを見つけられませんでした。はい、erlang.orgサイトにはMnesiaのドキュメントへのリンクと参照がたくさんありますが、それらのリンクでさえバージョンアップに苦しんでいます。

したがって、現在接続しているnode()がテーブルセットの所有者と同じ場合、バックアップ/リストアが機能します。例:

$ erl -sname mydatabase 

> mnesia:start(). 
> mnesia:create_schema(...). 
> mnesia:create_table(...). 
> mnesia:backup("/tmp/backup.bup"). 
> mnesia:restore("/tmp/backup.bup", [{default_op, recreate_tables}]). 

こんにちは、これは素晴らしいです!

データベースは、実際に遠隔交配上)(リモートノード()またはリモートノード上で実行されている場合しかし、その後、あなたは、バックアップをこのように開始する必要があります。

$ erl -sname mydbadmin 

> rpc:call([email protected], mnesia, backup, ["/tmp/backup.bup"]). 
> rpc:call([email protected], mnesia, restore, ["/tmp/backup.bup", [{default_op, recreate_tables}]]). 

もちろん、これは簡単でしたあまりにも。ここに難しいことがあります....

  • あなたは毎日のバックアップをとっているとしましょう。そして、あなたはmnesiaデータベースサーバーが死んでしまい、ハードウェアの交換が強制されます。 DBをそのまま復元する場合は、新しいハードウェアの名前を以前と同じ名前で指定する必要があります。また、ノードの名前を同じにする必要があります。
  • ハードウェアおよび/またはノード(または)の名前を変更する場合や、別のマシンで復元する場合は、node_changeプロセスを実行する必要があります。 (hereとmnesia文書に記載されています)

しかし、ここでは状況が複雑になります。私の知り合いは、エルランと記憶喪失の専門家で、記憶喪失の複製に深刻な欠陥があり、それを使用すべきではないことを示唆しています(私が知っている選択肢はありません。おそらく)

したがって、RAMとディスクベースのテーブルを複製する2つのノード()があります。デフォルトのBackupModを使用して、標準バックアップを使用してデータベースを定期的にバックアップするポリシーを維持しています。そして、ある日、マネージャはあなたにバックアップの確認を依頼します。データベースを復元しようとした場合にのみ、あなたが得る:

{atomic,[]} 

とマニュアルに従って、これはそこにエラーが...なかったし、まだテーブルが復元されなかったことを意味します。

change_nodeプロシージャーを実行したくない場合は、データがバックアップされたマシンと一致するように、ホスト名と-snameパラメーターを変更するためにnode()とhostnameが一致しなければならないことを覚えておいてください。この時間は、しかし、あなたは奇妙なエラーが発生します:

{aborted,{'EXIT',{aborted,{bad_commit,{missing_lock,[email protected]}}}}} 

はまだ、私はすぐに私は2台の類似のマシンを持っているように、私のサーバーを復元するクローンchange_nodeの手順を実行したくありません。私はプロダクションサーバに合わせて適切な名前をつけます。私は復元プロセスを開始します。ユーレカ!私は今、復元サーバ上で実際の作業データを持っています。

これは道路の終わりだったと言いたいですが、まだ質問はしていませんし、SOのポイント....そうですね。

質問:私は、複製mnesiaノードのクラスタから取られたバックアップをリストアしたい場合は、私は(change_nodeの手順と同様)ファイルを変更しますどのように他のノードが無視されるか、またはから削除されるようにバックアップ?

尋ねた少し違う:どのように私は単一ノード()の複製マルチノード()mnesiaデータベースを復元するのですか?

+0

http://stackoverflow.com/questions/463400/how-to-rename-the-node-running-a-mnesia-databaseも参照してください。 –

答えて

7

私はこの問題は簡単なものに関連しているMnesia質問の広いカテゴリーに入ることを考える:あなたのDBは巨大でない場合は、

How do I rename a Mnesia node?

最初と最も簡単な解決策を、mnesiaを使用することです:traverse_backup関数(Mnesia User guideを参照)。続き はMnesiaのユーザーガイドからの例です:

change_node_name(Mod, From, To, Source, Target) -> 
    Switch = 
     fun(Node) when Node == From -> To; 
      (Node) when Node == To -> throw({error, already_exists}); 
      (Node) -> Node 
     end, 
    Convert = 
     fun({schema, db_nodes, Nodes}, Acc) -> 
       {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc}; 
      ({schema, version, Version}, Acc) -> 
       {[{schema, version, Version}], Acc}; 
      ({schema, cookie, Cookie}, Acc) -> 
       {[{schema, cookie, Cookie}], Acc}; 
      ({schema, Tab, CreateList}, Acc) -> 
       Keys = [ram_copies, disc_copies, disc_only_copies], 
       OptSwitch = 
        fun({Key, Val}) -> 
          case lists:member(Key, Keys) of 
           true -> {Key, lists:map(Switch, Val)}; 
           false-> {Key, Val} 
          end 
        end, 
       {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc}; 
      (Other, Acc) -> 
       {[Other], Acc} 
     end, 
    mnesia:traverse_backup(Source, Mod, Target, Mod, Convert, switched). 

view(Source, Mod) -> 
    View = fun(Item, Acc) -> 
        io:format("~p.~n",[Item]), 
        {[Item], Acc + 1} 
      end, 
    mnesia:traverse_backup(Source, Mod, dummy, read_only, View, 0). 

ここで最も重要な部分は、あなたが名前を変更したり、DBノードに代わっ{schema, db_nodes, Nodes}タプルの操作です。

私はこれまでこの機能を使用していましたが、私が気づいたのは、バックアップ用語の形式が記憶媒体のバージョン間で変更されていることです。確かめたいのであれば、小さな記憶媒体データベースのバックアップログを印刷して、バックアップ用語形式をチェックしてください。

希望すると便利です。

+0

私はテキストを持っており、mnesiaサーバーのクラスタをバックアップまたは復元することについて何も言及していません。 – Richard

+0

私が指摘した文書にも含まれている変更ノードの例について知っていることをあなたの質問で参考にしました。あなたの質問が正しく理解されていれば、同じ例でタプル{schema、db_nodes、Nodes}が調べられます:このタプルにはMnesiaデータベースに登録されたノードが含まれています。 –

+0

ああ!私はchange_nodeコードでそれを逃した。 (あなたの答えはそれについて何も言わないが、change_node()は正解であっただろう)。ありがとう。 – Richard

関連する問題