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?

4

1 に答える 1

1

私のマシンの R16B01 でこれを再現できません。

注意すべき点:

  • mnesia を閉じるときは、mnesia:stop() を適切に呼び出す必要があります。シェルをハード終了すると、ディスク上の DETS テーブルを修復する必要があります。これは、おそらくあなたが経験していることです。
  • DETS コピーが必要な特定の理由はありますdisc_only_copiesか? イベントdisc_copiesは、データセットをメモリとディスク上のディスクログに保持するため、はるかに高速です。純粋にディスクベースのストレージの場合、私の経験では通常 mnesia よりもうまくいく他のオプションがあります。
  • 私の推測では、何らかの理由で誤って設定されたスキームになってしまうと思います。推測は、許可のあるものである可能性があります。rec.DAT が破損している可能性がありますが、何がその方向に傾いているのかわかりません。
于 2013-06-24T13:47:53.817 に答える