6

I have an erlang application currently running on four nodes with a replicated mnesia db that stores minimal data regarding connected clients. The mnesia replication has been working seamlessly in the past (as far as I know anyway) but a client recently noticed that one of the nodes is missing some ids related to his application.

I'm not really sure how this happened. Our network may have had a hiccup at the time. Maybe? But, of more urgency at the moment is getting the data into a good state across all nodes. Is there a way to tell mnesia to replicate from a known-good node?

4

2 回答 2

3

Mnesia 在这个问题上很有传奇色彩。这是一个巨大的皮塔饼。

从 CAP 定理的角度来看,大多数使用 Mnesia 构建的系统最终都是 CA(无分区容错的一致性可用性)系统。在大多数情况下,您拥有(并且严重依赖)它的硬一致性。然后发生网络分区......它仍然可用于写入,但这些写入破坏了一致性。后来,Mnesia 没有自动数据修复的机制。

在集群中使用 Mnesia 的每个人都应该熟悉这些权衡。您的问题清楚地表明使用 Mnesia 是一个糟糕的选择。如果此数据对您很重要,请加倍。

我也以这种方式使用 Mnesia(有时我们都需要速度,你知道的)。但我确保只使用它来存储我可以轻松重建的数据。一般来说,如果你需要将它存储在磁盘上,Mnesia 并不好,除了玩具项目。

我确保始终拥有此功能:

reinit_mnesia_cluster() ->
    rpc:multicall(mnesia, stop, []),
    AllNodes = [node() | nodes()],
    mnesia:delete_schema(AllNodes),
    mnesia:create_schema(AllNodes),
    rpc:multicall(mnesia, start, []).

只有在解决了网络分区并且所有节点都可以访问后才能使用它。这将清除所有 Mnesia 副本并重新启动它。同样,如果你不能忍受它的作用,那么使用 Mnesia 是一个糟糕的选择。

对于需要硬一致性的重要数据,使用 SQL。对于需要可用性的重要数据,请使用 Riak。对于需要速度的共享状态,请使用 Redis。Mnesia 不能替代这些系统,尽管起初看起来确实如此。

在 2014-11-16 上编辑:这是一篇关于该主题的更好的文章,详细解释了我上面所说的https://medium.com/@jlouis666/mnesia-and-cap-d2673a92850

于 2014-01-01T08:25:27.363 回答
1

老实说,我认为从已知良好节点复制不同步的 Mnesia 最简单的方法是关闭坏节点上的应用程序,并删除其所有 Mnesia 数据库文件,然后执行以下操作。

编写一个脚本,使用“坏”节点名称和 Mnesia 目录独立启动 Mnesia,从已知的好节点复制表,然后关闭 Mnesia。在坏节点上运行该脚本。

复制表并优雅地关闭 Mnesia 的行为使节点重新与集群同步。然后,当您在坏节点上启动应用程序时,它将加入并与集群保持同步。

当然,这个描述缺乏精确的细节,但这就是它的要点。这样做肯定有更少的蛮力方法,但除非你有大量数据要复制,否则我认为这种方法是最快和最干净的。

于 2015-06-20T03:26:48.697 回答