logo
banner

Yawsで分散データベースMnesiaを使う



目次

同じホストでレプリケーションする。

本来、異なるホスト間でデータベースのレプリケーションをすることが目的になりますが、練習として、同じホスト内で複数のノードを立ち上げて、レプリケーションのテストを行ってみます。
DSAS開発者の部屋に類似の記事があるので、参考にしてみてください。

yaws.confの準備

同じホストで2つめのyawsのインスタンスを立ち上げるには、yaws.confにidを指定する必要があります。使用中のファイル C:\Documents and Settings\ユーザー名\Application Data\yaws-1.74\yaws.conf 中の id = の行を有効にし、適当なidを指定してください。
また、2つめのyaws用に元のyaws.confをコピーします。ここでは/work/appsにコピーしてます。コピーしたyaws.confを開き、idとサーバのポート番号を変更します。ここではpポート番号は8001にしました。もとのyawsは再起動し、さらに、次のように設定ファイルを指定して、2つめのyawsを立ち上げます。2つめのノード(win2)のデータベースは/work/apps/db2に作成します。

>mkdir C:\work\apps\db2
>yaws -w -c /work/apps/yaws2.conf -sname win2  -M /work/apps/db2

データベースを接続する

まだ、元のノード(win)に接続していないときのmnesia:info()です。

(win2@PC-114)1> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
schema         : with 1        records occupying 388      words of mem
===> System info in version "4.4", debug level = none <===
opt_disc. Directory "c:/work/apps/db2" is NOT used.
use fallback at restart = false
running db nodes   = ['win2@PC-114']
stopped db nodes   = []
master node tables = []
remote             = []
ram_copies         = [schema]
disc_copies        = []
disc_only_copies   = []
[{'win2@PC-114',ram_copies}] = [schema]
2 transactions committed, 0 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok

mnesia:change_config()で次のようにextra_db_nodesを指定すると、データベースが接続され、remoteにテーブルがあることが確認できます。また、この状態で http://localhost:8001/music/musician をブラウザで開くとデータベースが接続されていることが確認できます。

(win2@PC-114)2> mnesia:change_config(extra_db_nodes, ['win@PC-114']).
{ok,['win@PC-114']}
(win2@PC-114)3> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
schema         : with 3        records occupying 731      words of mem
===> System info in version "4.4", debug level = none <===
opt_disc. Directory "c:/work/apps/db2" is used.
use fallback at restart = false
running db nodes   = ['win@PC-114','win2@PC-114']
stopped db nodes   = []
master node tables = []
remote             = [counter,musician]
ram_copies         = [schema]
disc_copies        = []
disc_only_copies   = []
[{'win2@PC-114',ram_copies},{'win@PC-114',disc_copies}] = [schema]
[{'win@PC-114',disc_copies}] = [counter,musician]
4 transactions committed, 0 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok

スキーマがRAM上にありますが、mnesia:change_table_copy_type()でスキーマをディスクにコピーするようにすると再起動時には接続した状態で立ち上がります。

(win2@PC-114)4>  mnesia:change_table_copy_type(schema, node(), disc_copies).
{atomic,ok}

この状態では、通常のデータベースエンジンに接続するように一箇所で動作しているデータベースにアクセスしていることになるので、winを落とすと、データベースに接続できないのでwin2 はエラーになります。また、win を起動すれば、win2は正常に動作します。

データベースをRAMに保存する

次にwin2上にデータベースのコピーをRAM上に持つようにしてみます。これは、mnesia:add_table_copy()でテーブルをram_copiesに指定します。


(win2@PC-114)2> mnesia:add_table_copy(counter, node(), ram_copies).
{atomic,ok}
(win2@PC-114)3> mnesia:add_table_copy(musician, node(), ram_copies).
{atomic,ok}
(win2@PC-114)4> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
musician       : with 3        records occupying 425      words of mem
counter        : with 1        records occupying 291      words of mem
schema         : with 3        records occupying 749      words of mem
===> System info in version "4.4", debug level = none <===
opt_disc. Directory "c:/work/apps/db2" is used.
use fallback at restart = false
running db nodes   = ['win@PC-114','win2@PC-114']
stopped db nodes   = []
master node tables = []
remote             = []
ram_copies         = [counter,musician]
disc_copies        = [schema]
disc_only_copies   = []
[{'win2@PC-114',disc_copies},{'win@PC-114',disc_copies}] = [schema]
[{'win2@PC-114',ram_copies},{'win@PC-114',disc_copies}] = [counter,musician]
6 transactions committed, 1 aborted, 0 restarted, 2 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok

この状態だと、winを落としてもwin2は正常に動作します。
winが停止中にwin2でデータを変更し、winを立ち上げると変更が反映されます。
win2のデータはRAM上に保持されているので、win2で行われた変更はwinが停止中に win2が落ちると失われます。

データベースをディスクに保存する

RAM上のデータをディスクに保存するようにします。まだ、リモートにデータベースがあるときは、mnesia:add_table_copy()でdisc_copiesを指定してデータベースをディスクに保存するようにすることができます。ここでは、RAM上にすでにテーブルがあるので、mnesia:change_table_copy_type()でテーブルのコピータイプをdisc_copiesに変更します。

(win2@PC-114)7> mnesia:change_table_copy_type(counter, node(), disc_copies).
{atomic,ok}
(win2@PC-114)8> mnesia:change_table_copy_type(musician, node(), disc_copies).
{atomic,ok}
(win2@PC-114)9> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
musician       : with 3        records occupying 427      words of mem
counter        : with 1        records occupying 291      words of mem
schema         : with 3        records occupying 749      words of mem
===> System info in version "4.4", debug level = none <===
opt_disc. Directory "c:/work/apps/db2" is used.
use fallback at restart = false
running db nodes   = ['win@PC-114','win2@PC-114']
stopped db nodes   = []
master node tables = []
remote             = []
ram_copies         = []
disc_copies        = [counter,musician,schema]
disc_only_copies   = []
[{'win2@PC-114',disc_copies},{'win@PC-114',disc_copies}] = [schema,counter,
                                                            musician]
21 transactions committed, 1 aborted, 0 restarted, 4 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok

3つめのノード

3つめのノードを立ち上げてみます。手順をまとめると次のようになります。

  • yaws.confをコピーしてidとポート番号を変更する。
  • yawsを起動するときに次の3つを指定する
    • 新しいdbの保存場所
    • 新しい.confファイル
    • 新しいsname 名
(win3@PC-114)2> mnesia:change_config(extra_db_nodes, ['win@PC-114','win2@PC-114'
]).
{ok,['win2@PC-114','win@PC-114']}
(win3@PC-114)3> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
schema         : with 3        records occupying 751      words of mem
===> System info in version "4.4", debug level = none <===
opt_disc. Directory "c:/work/apps/db3" is NOT used.
use fallback at restart = false
running db nodes   = ['win2@PC-114','win@PC-114','win3@PC-114']
stopped db nodes   = []
master node tables = []
remote             = [counter,musician]
ram_copies         = [schema]
disc_copies        = []
disc_only_copies   = []
[{'win2@PC-114',disc_copies},
 {'win3@PC-114',ram_copies},
 {'win@PC-114',disc_copies}] = [schema]
[{'win2@PC-114',disc_copies},{'win@PC-114',disc_copies}] = [musician,counter]
4 transactions committed, 0 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok

このあと、実現したいデータベースの構成に合わせてテーブルのコピータイプを変更します。

Copyright (C) 2007 KLab Inc. All Rights Reserved.