首页 > 解决方案 > mnesia:read 在 mnesia 中使用表碎片时返回空,但有记录

问题描述

mnesia:read在 mnesia 中使用表碎片时返回一个空列表,但我确实有一条记录:

我的代码是这样的:

F = fun() ->
     mnesia:dirty_read({offline_msg, <<0,0,0,0,0,0,0,11>>}) 
end.
Result = mnesia:activity(transaction, F, [],mnesia_frag).
Result is : 
[#offline_msg{userid = <<0,0,0,0,0,0,0,11>>,timestamp =1547039796317984,from = 123}]

F = fun() -> 
    mnesia:read({offline_msg, <<0,0,0,0,0,0,0,11>>}) 
end.
Result = mnesia:activity(transaction, F, [],mnesia_frag).

Result is  []

表信息:

PrimProps = [{n_fragments, 64}, {n_disc_only_copies, 1}, {node_pool, [node()]}],
mnesia:create_table(offline_msg,
 [{disc_only_copies, [node()]},{type, bag},{attributes, record_info(fields, offline_msg)}, {frag_properties, PrimProps}])

标签: erlangmnesia

解决方案


您是否使用 将记录写入表mnesia:dirty_write

“脏”函数(dirty_readdirty_write)绕过了 Mnesia 的表碎片,即使mnesia:activity在你的第一个示例中使用内部:它们总是访问表的第一个片段。所以我怀疑发生的事情是这样的:

  • 记录被写入第一个片段使用mnesia:dirty_write
  • 在您的第一个示例中,在第一个片段mnesia:dirty_read中查找记录,并找到它
  • 在您的 secord 示例中,mnesia:readinsidemnesia:activity使用了记录键的哈希来确定记录应该在哪个片段中,并查看该片段 - 但记录不存在,因为它被写入了错误的片段。

如果要对碎片表使用脏操作,请mnesia:activity使用sync_dirtyor调用async_dirty

mnesia:activity(sync_dirty, F, [],mnesia_frag).

例如,要将记录写入表:

OfflineMsg = #offline_msg{...},
F = fun() -> mnesia:write(OfflineMsg) end,
mnesia:activity(sync_dirty, F, [],mnesia_frag).

这将mnesia_frag确保记录被写入正确的表片段。


推荐阅读