2012-04-14 4 views
11

ВНИМАНИЕ: информация о фоновом режиме довольно длинная. Пропустите к концу, если вы считаете, что вам нужен вопрос перед фоновым сообщением. Цените время, которое это займет!Каков правильный способ резервного копирования/восстановления базы данных mnesia?

Я был повсюду в Интернете (читал google), и я не нашел хорошего ответа. ДА, есть много ссылок и ссылок на документацию Mnesia на сайте erlang.org, но даже эти ссылки страдают от версии itis.

Так что в простейшем случае, когда узел(), к которому вы в данный момент подключены, совпадает с владельцем таблицы, тогда резервное копирование/восстановление будет работать. Например:

$ 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)

Но здесь все осложняется. Хотя мои знакомые, которые являются экспертами erlang и mnesia, предполагают, что репликация mnesia сильно испорчена и что вы не должны ее использовать (в настоящее время нет никаких альтернатив, о которых я знаю, и каковы шансы, что вы собираетесь реализовать лучшую версию, а не вероятно)

Итак, у вас есть два узла(), которые реплицируют таблицы на основе бара и диска. Вы регулярно поддерживаете политику резервного копирования базы данных с помощью стандартной резервной копии с использованием BackupMod по умолчанию. И однажды менеджер попросит вас проверить резервные копии. Только при попытке восстановить базу данных вы получите:

{atomic,[]} 

И согласно документации это означает, что не было никаких ошибок ... и еще таблицы не были восстановлены.

Не желая запускать процедуру change_node, вы помните, что имя узла() и имя хоста должны совпадать, чтобы вы изменили имя хоста и параметр -sname, чтобы он соответствовал машине, на которой были скопированы данные. На этот раз, однако вы получите странную ошибку:

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

Еще не желая, чтобы запустить процедуру change_node я быстро клонировать восстановить мой сервер так, что у меня есть два подобных машин. Я называю тогда подходящим образом, чтобы соответствовать производственным серверам. И я начинаю процесс восстановления. Эврика! Теперь у меня есть реальные рабочие данные на серверах восстановления.

Я хотел бы сказать, что это был конец дороги ... но я еще не задал вопрос и что точка SO ... так вот оно?

ВОПРОС:, если я хочу, чтобы восстановить резервную копию, которая была взята из кластера тиражируемых узлов Mnesia, как я могу изменить файл (по аналогии с процедурой change_node), так что другие узлы либо игнорируются, либо удалены из резервное копирование?

Задано несколько иначе: Как восстановить базу данных masedia с репликацией-multi-node() на одном узле()?

+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). 

Наиболее важная часть здесь является манипулированием {schema, db_nodes, Nodes} кортежа, который позволит вам переименовать или заменить Db узлов.

BTW, я использовал эту функцию в прошлом, и одна вещь, которую я заметил, это то, что формат резервных копий изменяется между версиями mnesia, но, возможно, это просто я писал плохой код. Просто распечатайте журнал резервных копий для небольшой базы данных mnesia, чтобы проверить формат резервного копирования, если вы хотите быть уверенным.

Надеюсь, это поможет!

+0

У меня есть текст, и он ничего не говорит о поддержке или восстановлении кластера серверов mnesia. – Richard

+0

Вы упомянули в своем вопросе, что знаете о примере узла изменения, который также включен в документ, который я указал. Если я правильно понял ваш вопрос, в том же примере вы можете увидеть, что проверяются кортеж {схема, db_nodes, узлы}: этот кортеж содержит узлы, зарегистрированные для базы данных Mnesia. –

+0

Ах! Я пропустил это в коде change_node. (ваш ответ ничего не говорит об этом, однако change_node() был бы правильным ответом.) Спасибо. – Richard