0

I am getting an unusual error with some simple mnesia code. This question is a followup to this other question of mine, but now I have code to reproduce the issue.

I am using this erlang:

Erlang R16B01 (erts-5.10.2) [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

on Arch Linux.

If I have this code:

-module(test).

-export([test/0, tryread/0]).

-record(rec, { a, b }).

test() ->
    install(),

    {atomic, ok} = mnesia:transaction(fun() -> mnesia:write({rec, y, y}) end),
    {atomic, ok} = mnesia:transaction(fun() -> mnesia:write({rec, z, z}) end).

tryread() ->
    mnesia:transaction(fun() ->
                               mnesia:read(rec, y)
                       end).

install() ->
    mnesia:create_schema([node()]),

    ok = mnesia:start(),

    {atomic, ok} = mnesia:create_table(rec, [
                                             {attributes,       record_info(fields, rec)},
                                             {disc_only_copies, [node()]},
                                             {type,             set}
                                            ]).

in a file called test.erl and I start erl and type the following in:

1> c(test).
{ok,test}
2> test:test().
{atomic,ok}
3> test:tryread().
{atomic,{error,{bad_object_header,"/.../Mnesia.nonode@nohost/rec.DAT"}}}

As a side note, if I exit erl and restart it, and do mnesia:start(), I get this warning:

dets: file "/.../Mnesia.nonode@nohost/rec.DAT" not properly closed, repairing ...

This is very reliable behaviour for me. I can delete the entire database, rerun the test, and get the exact same results.

One thing is that if I put the call to tryread inside the test function right after the two transactions, it works fine. It is calling tryread from the REPL that causes the error.

If I downgrade my erlang Arch installation package to R16B-3 from R16B01-1, I do not get this error. Any version newer than that gives this error.

Can anyone else reproduce this error? What is causing it?

Community
  • 1
  • 1
Johnny Test
  • 107
  • 1
  • 7

1 Answers1

1

I cannot reproduce this on R16B01 on my machine.

Some things to look out for:

  • You must call mnesia:stop() properly when closing down mnesia. If you hard-exit the shell, your DETS tables on disk will need repair, which is probably what you are experiencing.
  • Is there any particular reason you want DETS copies through disc_only_copies ? Event disc_copies is way faster since they keep the data set in memory as well as on a disk log on the disk. For purely disk-based storage, there are other options which usually fares better than mnesia in my experience.
  • My guess is that you end up with a wrong misconfigured scheme for some reason. A guess could be something with permissions. rec.DAT could be corrupted, but I don't know what is making it tilt in that direction.
I GIVE CRAP ANSWERS
  • 18,739
  • 3
  • 42
  • 47
  • I am not stopping the shell or mnesia between creating the database and using it, so bullet point one cannot be the problem. Furthermore, the "repairing file" message is only a second symptom, the more important one is the `bad_object_header` error when trying to do `mnesia:read`. Thank you for the recommendation about `disc_only_copies`. All the required permissions are available to the shell so bullet point three can't be the problem either. – Johnny Test Jun 24 '13 at 17:18
  • My guess is somewhat close. The error comes from `dets_utils` lines 154 and 169. We are trying to execute a `file:pread` scatter/gather read and we are getting either an `einval` or `enomem` error back. – I GIVE CRAP ANSWERS Jun 24 '13 at 18:22
  • Is there a way I can check which one it is? – Johnny Test Jun 24 '13 at 18:54
  • No, not apart from recompiling the code or adding tracing to the file:pread call from within the correct `dets` process. – I GIVE CRAP ANSWERS Jun 25 '13 at 14:43