如果我在Erlang中运行多个Web服务器(负载均衡)并且Mnesia用于后端数据库,那么将整个系统升级到更新版本的最佳方法是什么?
我在mnesia中有一个表,我需要更新其中的记录中的各个字段.根据Erlang:Mnesia:如果我执行以下操作,则连续更新单个字段值:
update_a(Tab, Key, Value) ->
fun() ->
[P] = mnesia:wread({Tab, Key}),
mnesia:write(Tab, P#rec{a=Value}, write)
end.
Run Code Online (Sandbox Code Playgroud)
根据我的理解,上面的代码读取P基于a的记录Key,获取记录上的写锁定,以便在读取和写回(或简称,更新)时,没有其他事务修改此记录.到现在为止还挺好.
现在我的要求是我需要能够根据Key表中的另一个字段读取记录,然后对其执行更新.这个查找的功能是mnesia:match_object.现在的问题是,根据http://www.erlang.org/doc/man/mnesia.html#match_object-3,该函数仅支持读锁,而不支持写锁.
这样做的结果是,假设在上面的函数中我使用的是mnesia:match_object,我将获得一组(一组)记录,所有记录都带有读锁.在我读取记录之后,我需要对检索到的数据执行一些检查,然后仅在条件满足时写回更新的记录.现在,假设有两个并行事务T1和T2由两个不同的源运行启动.T1和T2都同时访问相同的记录.由于它们被读锁定,因此T1和T2都能够并行读取记录.T1和T2都将对同一记录执行相同的检查,如果条件匹配,则两者都将继续执行更新.但是,在我的代码中,如果T1和T2已经连续执行,T1将对记录进行更改,在T2中,它将读取这些已更改的记录,并且条件将失败并且不会进行更新.
简而言之,我需要编写由mnesia:match_object返回的锁记录.文档明确指出只支持读锁定.有没有其他选择?
更新: 我一直在尝试一点,我认为可能的解决方案是使用复合键.假设我将数据写入表中,如:
mnesia:transaction(fun() -> mnesia:write(mytable, #rec{i={1,2}, a=2, b=3}, write) end).
Run Code Online (Sandbox Code Playgroud)
有没有办法查找条目,使用不关心?
我尝试了这些,但都返回了空结果:
mnesia:transaction(fun()-> mnesia:read(mytable, {1,'_'}, read) end).
mnesia:transaction(fun()-> mnesia:read(mytable, {1,_}, read) end).
Run Code Online (Sandbox Code Playgroud) 如何在不使用mnesia命令行传递"dir"参数的情况下指定工作目录?
换句话说,我可以在调用`mnesia:start()'之前为mnesia指定一个"工作目录"吗?
我尝试将Mnesia与更传统的数据库进行比较.
据我所知,Mnesia中的表可以找到(参见Mnesia的内存消耗):
ram_copies- 存储表ets,因此没有ACID中的持久性.disc_copies- 表位于ets和dets,所以表不能大于可用内存?如果表是碎片,数据库不能大于可用内存?disc_only_copies- 表位于dets,因此内存中没有缓存,性能更差.并且表的大小限制为大小dets或表必须分段.因此,如果我想要从RAM执行读取的性能以及写入磁盘的持久性,那么与传统的RDBMS(如MySQL或PostgreSQL)相比,表的大小非常有限.
我知道Mnesia并不是要取代传统的RDBMS:s,但它可以用作大型RDBMS还是我必须寻找另一个数据库?
我将使用的服务器是内存有限的VPS,大约512MB,但我想要良好的数据库性能.
disc_copiesMnesia中的其他类型的表格是否如我所理解的那样有限?数据库不能部分在内存和光盘上的完整副本吗?
我已经问了一个问题,关于一个简单的容错软实时网络比萨饼店交付应用.

我在那里得到了非常好的评论和答案,但我不同意这是一个真正的网络服务.它不仅仅是一种网络服务,它更像是一个实时系统来接受客户的订单,控制这些订单的调度并控制实时交付这些订单的车辆.
此外,与"真正的"网络服务不同,这个系统不是为了拥有许多用户 - 只有少数调度员(电话运营商)和一些将使用它的交付驱动程序(因为现在我没有要求提供直接访问)为实际客户提供服务;只有调度员和交付司机才能直接访问).
因此这个问题有点笼统.
我发现,为了做出正确的选择,为我所要做的这个应用程序的第一件事NoSQL数据存储选项之间做出选择CA,PA并CP根据CAP定理.
现在,使用Erlang构建Web应用程序的书称"虽然它[Mnesia]不是SQL数据库,但它是一个像SQL数据库一样的CA数据库.它不会处理网络分区".同一本书说CouchDB数据库是一个PA数据库.
考虑到这一点,我认为我需要对我的应用程序做的第一件事是确定"容错"术语对CAP的意义.
我的简单要求是使应用程序24/7(R1)可用.另一个是没有必要扩展,应用程序将拥有非常适量的用户(可能无法拥有数千个调度程序)(R2).
现在,R1是否要求应用程序提供一致性,可用性和分区容差以及具有哪些优先级?
什么类型的数据存储选项将更好地处理以下问题:
总结一下:什么样的数据存储(CA,PA或CP)将更好地适应上述系统?什么样的数据存储能更好地满足R1要求?
例如,我保存{id, name}在mnesia并希望更新到{id, name, age},transform_table每次更改架构时是否必须调用?
我有一个当前在四个节点上运行的erlang应用程序,其中有一个复制的mnesia db,它存储有关已连接客户端的最小数据.mnesia复制过去一直在无缝工作(据我所知),但客户最近注意到其中一个节点缺少与他的应用程序相关的一些ID.
我不确定这是怎么发生的.我们的网络当时可能已经打了个嗝.也许?但是,目前更紧迫的是使数据在所有节点上都处于良好状态.有没有办法告诉mnesia从一个已知良好的节点复制?
我正在尝试使用Elixir编写程序来访问mnesia.我在亚马逊linux中运行iex shell.我尝试使用连接另一个节点
Node.connect(:'hello@abc.com')
Run Code Online (Sandbox Code Playgroud)
返回true,然后我想在这个远程节点上运行mnesia命令,我发出
:mneisa.info
Run Code Online (Sandbox Code Playgroud)
但是,它只返回本地节点的mnesia信息.如何访问连接的远程节点的mnesia数据库?
我试过rpc_call,它有效.但它是否有更直接的方法从远程节点mnesia获取数据.
有没有办法直接在erl中使用记录?无论我尝试什么,它总是说它无法找到记录.我正在尝试进行mnesia交易,没有我的记录,我不能走得太远.非常感谢任何帮助 - 谢谢!
我有一个包含不同表的mnesia数据库.
我希望能够从不同的Linux终端访问表.
我有一个调用的函数add_record,这需要几个参数,说name和id.我想能够add_record打开node1和add record打开,node2但我想从不同的位置更新同一个表.
我读了几个来源,我发现的唯一一件事就是我应该使用net_adm:ping(node2).但不知何故,我无法从表中访问数据.
mnesia ×10
erlang ×9
database ×2
cap ×1
couchdb ×1
distributed ×1
elixir ×1
erl ×1
erlang-otp ×1