.. _mnesia_cluster: 从头建立mnesia集群 '''''''''''''''''''''''''' 启动3个erlang节点并ping通:: erl -name a@host1 -setcookie abc erl -name b@host1 -setcookie abc (a@host1)1> net_adm:ping('b@host1'). pong 创建schema:: (a@host1)3> NL = [node()|nodes()]. [a@host1,b@host1] (a@host1)4> mnesia:create_schema(NL). ok 注: 这个时候在文件浏览器中可以看到,3个数据库的文件夹都出现了。 启动3个节点上的mnesia数据库: (a@host1)5> mnesia:start(). ok (b@host1)1> mnesia:start(). ok 查看一下数据库是不是都启动了: (a@host1)6> mnesia:system_info(running_db_nodes). [a@host1] 建表:: 先创建一个record,作为表结构使用: (a@host1)7> rd(, {key, value}).
建表的属性参数设置: (a@host1)9> TablePropList = [{attributes, record_info(fields,
)}]. [{attributes,[key,value]}] 建表: (a@host1)10> mnesia:create_table(
,TablePropList). {atomic,ok} (a@host1)12> mnesia:info(). ...... running db nodes = [b@host1,a@host1] stopped db nodes = [] master node tables = [] remote = [] ram_copies = [
] disc_copies = [schema] disc_only_copies = [] [{a@host1,disc_copies}, {b@host1,disc_copies}] = [schema] [{a@host1,ram_copies}] = [
] ...... 往表里插入1000条数据:: (a@host1)17> Write = fun(Keys) -> [mnesia:write({dictionary,K,K}) || K <- Keys], ok end. #Fun (a@host1)18> mnesia:activity(sync_dirty, Write, [lists:seq(1, 1000)], mnesia_frag). ok 修改表的属性:: // 把dictionary表在a节点的存储方式改成disc_copies: (a@host1)23> mnesia:change_table_copy_type(dictionary, node(), disc_copies). {atomic,ok} (a@host1)24> mnesia:info(). ...... [{a@host1,disc_copies}] = [dictionary] ...... 在现在mnesia集群中增加1个结点 '''''''''''''''''''''''''''''' 启动一个新结点,并启动mnesia,ping通网络:: erl -name d@host1 -setcookie abc (d@host1)1> mnesia:start(). ok (a@host1)48> net_adm:ping('d@host1'). pong 添加mnesia节点:: (a@host1)49> mnesia:change_config(extra_db_nodes, [d@host1]). {ok,[d@host1]} 查看mnesia集群属性:: (a@host1)50> mnesia:info(). .... .... [{a@host1,disc_copies}, {b@host1,disc_copies}, {d@host1,ram_copies}] = [schema] [{a@host1,disc_copies}] = [dictionary] .... .... 在d上再备份一下a节点的数据:: (a@host1)52> mnesia:add_table_copy(
, 'd@host1', ram_copies). {atomic,ok} 方案1: 在d节点改一下dictionary的备份属性: (d@host1)4> mnesia:change_table_copy_type(
, node(), disc_copies). {atomic,ok} 方案2: 拷贝创建本schema mnesia:change_table_copy_type(schema, node(), disc_copies). Tables = [
]. [mnesia:add_table_copy(T, node(), ram_copies)||T<-L]. 其他 '''''''''' 激活表格的分片:: (a@host1)25> mnesia:change_table_frag(dictionary, {activate, []}). {atomic,ok} 查看分辨是否激活了:: (a@host1)26> mnesia:table_info(dictionary, frag_properties). [{base_table,dictionary}, {foreign_key,undefined}, {hash_module,mnesia_frag_hash}, {hash_state,{hash_state,1,1,0,phash2}}, {n_fragments,1}, {node_pool,[a@localhost,b@localhost,c@localhost]}] 创建一个函数,这个函数的作用是获得表的frag_dist:: (a@host1)28> GetTableInfo = fun(Item) -> mnesia:table_info(dictionary, Item) end. #Fun (a@host1)29> GetFragNodes = fun()-> mnesia:activity(sync_dirty, GetTableInfo, [frag_dist], mnesia_frag) end. #Fun 测试一下:: (a@host1)30> GetFragNodes(). [{b@host1,0},{{a@host1,1}] 添加一个分片了,通过GetFragNodes返回的节点列表,mnesia可以负载均衡的把新的分片添加到相对空闲的节点上:: (a@localhost)35> mnesia:change_table_frag(dictionary, {add_frag, GetFragNodes()}). {atomic,ok} (a@localhost)36> mnesia:table_info(dictionary, frag_properties). [{base_table,dictionary}, {foreign_key,undefined}, {hash_module,mnesia_frag_hash}, {hash_state,{hash_state,2,1,1,phash2}}, {n_fragments,2}, {node_pool,[a@localhost,b@localhost,c@localhost]} ] 看到了 {n_fragments,2},增加到2个了 新的分片分派到哪个节点了:: (a@localhost)37> GetFragNodes(). [{c@localhost,0},{a@localhost,1},{b@localhost,1}] 节点数据备份: * 给a节点的dictionary表增加一个备份节点(选择在c节点):: (a@localhost)40> mnesia:add_table_copy(dictionary, 'c@localhost', disc_copies). {atomic,ok} * 我们再插入1000条数据,看看c节点是不是和a节点同时插入数据:: (a@localhost)43> mnesia:activity(sync_dirty, Write, [lists:seq(1001, 2000)], mnesia_frag). ok 結果:在c结点上, dictionary表中dictionary分片保存了1014条,dictionary_frag2分片保存了0条(因为没有对b结点备份) * 在c节点备份b节点的dictionary_frag2这个分片的数据:: (b@localhost)6> mnesia:add_table_copy(dictionary_frag2, 'c@localhost', disc_copies). {atomic,ok} 結果:在c结点上, dictionary表中dictionary分片保存了1014条,dictionary_frag2分片保存了986条(对b结点备份了) * 看到n_disc_copies属性是2:: (a@localhost)47> mnesia:activity(sync_dirty, GetTableInfo, [n_disc_copies], mnesia_frag). 2 * a节点的dictionary分片表在a、c、d上已经有了3份拷贝,现在,我们查一下dictionary的拷贝数量:: (a@localhost)67> mnesia:activity(sync_dirty, GetTableInfo, [n_disc_copies], mnesia_frag). 3 * 去掉一个表的备份节点(把d节点的dictionary分片表的备份去掉):: (a@localhost)68> mnesia:del_table_copy(dictionary, 'd@localhost'). {atomic,ok} (a@localhost)69> mnesia:activity(sync_dirty, GetTableInfo, [n_disc_copies], mnesia_frag). 2