2012-04-14 6 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}]]). 

이 간단 물론 : 데이터베이스가 실제로 원격 노드() 또는 원격 짝짓기에 원격 노드()에서 실행되는 경우

그러나, 당신은 백업이 방법을 시작해야 너무. 이제 까다로운 것들이 있습니다 ....

  • 매일 백업을하고 있다고 가정 해 봅시다. 그리고 당신은 기억 상실 데이터베이스 서버가 죽고 당신은 하드웨어를 교체해야합니다. DB를 그대로 복원하려면 이전과 같은 이름으로 NEW 하드웨어의 이름을 지정해야하며 노드의 이름을 동일하게 지정해야합니다.
  • 하드웨어 및/또는 노드()의 이름을 변경하거나 다른 시스템에서 복원하려는 경우 node_change 프로세스를 수행해야합니다. (here과 mnesia 문서에 설명되어 있음)

하지만 여기에는 상황이 복잡해집니다. erlang 및 mnesia 전문가 인 광산의 지인들은 횡격막의 복제에 심각한 결함이 있으며 사용하지 말아야한다고 제안하지만 (현재 내가 알고있는 대안이없고 더 나은 버전을 구현할 가능성은 무엇입니까? 가능성이)

따라서 두 개의 노드()는 RAM 및 디스크 기반 테이블을 복제합니다. 기본 BackupMod를 사용하여 표준 백업을 사용하여 데이터베이스를 정기적으로 백업하는 정책을 유지 관리하고 있습니다. 그리고 어느 날 매니저가 백업 확인을 요청합니다. 데이터베이스를 복원하려고 할 때만 얻을 :

{atomic,[]} 

그리고 문서에 따라이 오류가 ... 없었다과 아직 테이블이 복원되지 않았 음을 의미한다.

change_node 프로 시저를 실행하지 않으려면 노드 이름과 -sname 매개 변수를 변경하여 데이터가 백업 된 시스템과 일치하도록 node()와 호스트 이름이 일치해야 함을 기억하십시오. 이 시간은 그러나 당신은 이상한 오류가 발생합니다 :

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

아직도 내가 빨리 나는 두 개의 유사한 기계를 가질 수 있도록 내 서버를 복원 복제하려면 change_node의 프로 시저를 실행하고 싶지 않다. 그런 다음 프로덕션 서버와 일치하도록 적절하게 이름을 지정합니다. 복원 과정을 시작합니다. 유레카! 이제 복원 서버에서 실제로 작동하는 데이터가 있습니다.

나는 이것이 길의 끝이었다고 말하고 싶다. 그러나 나는 아직 질문하지 않았다. 그리고 그 점은 .... 그래서 여기있다?

질문 : 복제 mnesia 노드의 클러스터에서 찍은 백업을 복원하려는 경우, I합니다 (change_node 절차와 유사) 파일을 수정 어떻게 다른 노드 중 하나를 무시되거나 제거되도록 백업?

약간 묻는 질문 : 단일 노드()에서 복제 된 다중 노드() mnesia 데이터베이스를 복원하려면 어떻게해야합니까?

+0

또한 http://stackoverflow.com/questions/463400/how-to-rename-the-node-running-a-mnesia-database를 참조하십시오. –

답변

7

나는이 문제가 단순한 하나의 관련된 Mnesia 질문의 폭 넓은 범주에 빠진다 생각 : 당신의 데시벨이 큰없는 경우

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

나는 본문을 읽었으며 흉고 진단 검사기 서버를 뒷받침하거나 복원하는 것에 관해서는 아무 말도하지 않는다. – Richard

+0

내가 지적한 문서에 포함되어있는 변경 노드 예제에 대해 알고 있다고 질문하셨습니다. 귀하의 질문을 정확하게 이해한다면 동일한 예에서 튜플 {스키마, db_ 노드, 노드}가 검사됨을 볼 수 있습니다 :이 튜플은 Mnesia 데이터베이스에 등록 된 노드를 포함합니다. –

+0

아! 나는 change_node 코드에서 그것을 놓쳤다. (귀하의 대답은 그것에 대해 아무 말도하지 않지만 change_node()는 정답이었을 것입니다.) 감사합니다. – Richard

관련 문제