Random bad_object_header mnesia/dets error

2019-08-06 03:38发布

I am having a very weird error with mnesia. I have about 10 tables that mnesia is recording, and usually it works fine. However, in a certain place in my code, whenever I try to read from a particular table (trying to read from other tables is fine) I get a DETS error.

I reduced my code to

{atomic, ok} = mnesia:transaction(fun() ->
                                          [Entry] = mnesia:read(table_name, Key),
                                          ok
                                  end)

I have a try/catch block around the transaction, and the error I get is this:

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}]},
            ]}}}

Unfortunately I cannot reproduce the error with a short example. Even if I call the function from the REPL, it doesn't error. It only errors when it happens in my actual code. But it does happen reliably every time.

If I take out the mnesia:read line, everything works fine. I have tried remaking the schema and the tables, and that didn't help. It's really weird because my code goes on later to use the table successfully. It is only if it's used from this one place that it fails.

What could be going wrong?

Update

I experimented some more and it seems that the error only happens when two of these transactions happen (in different processes) nearly simultaneously. Isn't mnesia meant to be used in this way?

Update 2

Turned out that the problem was fixed by downgrading my erlang installation on Arch Linux to R16B-3 from R16B-6. Hopefully this bug will be ironed out soon.

2条回答
Animai°情兽
2楼-- · 2019-08-06 04:09

The symptoms means that either that the file operation to read at a specific part of the file runs out of memory or you are trying to read from an non existing position in the file. So if you do not run out of memory (which you should have noticed), it is likely that there is a race condition in the handling of that file by DETS.

查看更多
Melony?
3楼-- · 2019-08-06 04:28

I've got the same error from time to time. It occurs since I did an upgrade on my Debian server maybe one or two months ago.

Here is my error:

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,[]}]}

I think it's an Erlang regression because I didn't change the code for a long time and it was working fine before the upgrade.

I'm only using DETS, not Mnesia. I have no concurrent access to the file.

Here is my code, it's very simple: https://github.com/Ummon/D-LAN/blob/website/modules/erl/d_lan_db.erl#L103

查看更多
登录 后发表回答