Mnesiaノードを追加する
私のLAN上にある第3のマシンはnemoです。以下のコマンドでErlangノード「third@nemo」を起動してから、そのノード上でMnesiaを起動します。
erl -sname third -setcookie AXHMTYGVJDNJIFGYADNJ
このシステムは非常に柔軟なので、他の2つのノードのいずれかから、以下のコマンドでノードを追加することができます。
(first@charlie)15> mnesia:change_config(extra_db_nodes,[third@nemo]).
前述のとおり、Mnesiaスキーマは特殊なテーブルですが、突き詰めていけば他のテーブルと変わりはありません。従って、上記のコマンドを実行すると、スキーマテーブルのRAMコピーがthird@nemoに追加されます。この操作を行った後で、first@charlieおよびsecond@deltaのリモートテーブルtable1およびtable2にthird@nemoからアクセスできます。実際に、nemo上のMnesiaシステムに関する情報を問い合わせると、次のような結果が表示されます。
(third@nemo)4> mnesia:system_info(). ... running db nodes = [first@charlie,second@delta,third@nemo] ... remote = [table1] ram_copies = [schema] ...
テーブルコピーを追加する
もちろん、以下のコマンドを使用して、third@nemoのスキーマテーブルの性質をその場で変更することもできます。
(first@charlie)16> mnesia:add_table_copy(schema, third@nemo, disc_copies).
スキーマの新しいコピーの追加とその性質の変更は動的な操作であり、Mnesiaスキーマのすべてのテーブルに適用できます。
ここまでの説明でお分かりのとおり、ノードを起動し、ノード上にMnesiaエンジンを作成し、サービスをまったく停止せず完全に透過的にノードを追加することがごく簡単にできます。パフォーマンスを向上させ、高度な冗長性を実現するために、各ノードはスキーマとその他のテーブルの複製をそれぞれ独自に持つことができます。
トランザクション
Mnesiaが真の分散DBMSである(スキーマのいずれかのコピーに対して操作を実行すると、他の複製とフラグメントすべてに自動的に伝播される)ことは明らかですが、トランザクションデータベースとも言えるのでしょうか? 一連の操作をトランザクション、すなわち原子性、首尾一貫性、独立性、耐久性(ACID)という特質を持つ作業単位にまとめ、その作業単位でMnesiaデータベースに対して操作を実行することはできるのでしょうか? 答えはイエスです。このセクションの残りの部分では、トランザクションを実行する方法について説明します。
データベースに対して「すべてか無か」の操作を実行しなければならない場合を考えてみましょう。例えば、以下の関数atomic_op
に示すように、既存のレコード(#1)を削除して、新規レコード(#5)を挿入したいとします。
atomic_op() -> Row = #table1{table1_id=5, name="record5", color="black", number=4598}, mnesia:delete({table1,1}), mnesia:write(Row).
ただし、レコード#5を挿入できなかった場合は、レコード#1を削除したくありません。さらに、私が削除と挿入を行っているあいだ、他の誰かがレコード#1に対して何らかの操作を実行しないようにしたいと思います。つまり、関係するすべてのノード上で、2つの操作の原子性と独立性を維持したいということです。このために私が行わなければならないのは、以下に示すように、先ほど作成したatomic_op
関数をmnesia:transaction
関数に引き渡すことだけです。
op() -> F = fun atomic_op/0, {atomic, Val} = mnesia:transaction(F), Val.
この例では、Erlangのメカニズムによって、関数atomic_op
を変数F
にバインドし、それを引数としてmnesia:transaction
に渡しています。これで、削除と挿入という2つの操作の原子性と独立性だけでなく、首尾一貫性と耐久性も保証されます。
mnesia:transaction
関数は、ロックの設定と解放など、トランザクションに影響を与える並列処理の問題をすべて管理します。ユーザーがこの種の問題を管理する必要はありません。Mnesiaは、ロックの取得に成功しなかったトランザクションを保留し、既に取得していたロックをすべて解放させることによって、デッドロックも回避します。画面上への出力(io:format
)など副次的な悪影響をもたらすコードがトランザクションに含まれている場合は、トランザクションが成功するまで多数のメッセージが標準出力に繰り返し表示されることがあります。