我有一个非常奇怪的错误记忆。我有大约10个表,失忆症正在记录,通常它工作得很好。然而,在代码的某个地方,每当我尝试从一个特定的表中读取(尝试从其他表中读取也可以),我就会得到一个DETS错误。
我将代码简化为
{atomic, ok} = mnesia:transaction(fun() ->
[Entry] = mnesia:read(table_name, Key),
ok
end)
我在交易周围有一个try
/catch
块,我得到的错误是:
error:{badmatch,
{aborted,
{{badmatch,
{error,
{bad_object_header,
"/path/to/table_name.DAT"}}},
[{callback,
'-handle/2-fun-0-',
1,
[{file,
"src/src.erl"},
{line,
234}]},
{mnesia_tm,
apply_fun,
3,
[{file,
"mnesia_tm.erl"},
{line,
830}]},
{mnesia_tm,
execute_transaction,
5,
[{file,
"mnesia_tm.erl"},
{line,
810}]},
]}}}
不幸的是,我不能用一个简短的例子重现这个错误。即使我从REPL调用函数,它也不会出错。只有在实际代码中发生时才会出错。但它确实每次都可靠地发生。
如果我拿出mnesia:read
线,一切工作正常。我试过重新制作模式和表格,但没有帮助。这真的很奇怪,因为我的代码后来成功地使用了这个表。只有从这一个地方使用,它才会失败。
出了什么问题?
更新我做了更多的实验,似乎只有当两个事务(在不同的进程中)几乎同时发生时才会发生错误。失忆症不是应该这样使用吗?
更新2
结果是,通过将我在Arch Linux上安装的erlang从R16B-6降级到R16B-3,问题得到了解决。
该症状表示要在文件的特定部分读取的文件操作耗尽了内存,或者您正在尝试从文件中不存在的位置读取。因此,如果您没有耗尽内存(您应该已经注意到这一点),则很可能在DETS处理该文件时存在竞争条件。
我经常遇到同样的错误。这是因为我在一两个月前升级了Debian服务器。
这是我的错误:
Error in process <0.84.0> on node 'yaws@overnux' with exit value: {{case_clause,{error,{bad_object_header,"/var/www/d-lan/db/d_lan_downloads_count.dets"}}},[{d_lan_db,loop,0,[]},{string,strip,1,[]}]}
我认为这是一个Erlang回归,因为我没有改变代码很长一段时间,它在升级之前工作得很好。
我只使用DETS,而不是记忆缺失。我没有并发访问文件的权限。
下面是我的代码,它很简单:https://github.com/Ummon/D-LAN/blob/website/modules/erl/d_lan_db.erl#L103