2013-06-24 31 views
0

我收到了一些簡單的mnesia代碼的不尋常的錯誤。這個問題是我的後續this other question,但現在我有代碼來重現這個問題。Mnesia bad_object_header錯誤

我用這二郎:

二郎R16B01(專家評審組-5.10.2)[來源] [64位] [SMP:4:4] [異步線程:10] [HIPE] [kernel-poll:false]在Arch Linux上的

如果我有這樣的代碼:

-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} 
              ]). 

在一個名爲test.erl文件,我開始erl並鍵入以下內容:

1> c(test). 
{ok,test} 
2> test:test(). 
{atomic,ok} 
3> test:tryread(). 
{atomic,{error,{bad_object_header,"/.../[email protected]/rec.DAT"}}} 

作爲一個方面說明,如果我退出erl並重新啓動它,並做mnesia:start(),我得到這個警告:

dets:文件「/.../[email protected]/rec.DAT」沒有正確關閉,修復...

這對我來說是非常可靠的行爲。我可以刪除整個數據庫,重新運行測試,並獲得完全相同的結果。

有一件事是,如果我把tryread的電話放在test函數的兩個事務之後,它就可以正常工作。它從REPL調用tryread導致錯誤。

如果我將我的erlang Arch安裝包從R16B01-1降級到R16B-3,我不會收到此錯誤。任何比此更新的版本都會產生此錯誤。

其他人可以重現此錯誤嗎?是什麼造成的?

+0

我無法在Windows環境中的R15B上重現它。 – Pascal

回答

1

我不能在我的機器上在R16B01上重現這一點。

有些事情看出來:逼搶的Mnesia時正確停止():

  • 你必須調用函數mnesia。如果你硬盤退出shell,磁盤上的DETS表需要修復,這可能是你正在經歷的。
  • 是否有任何特殊原因需要DETS通過disc_only_copies拷貝?事件disc_copies的速度會更快,因爲它們將數據集保存在內存中以及磁盤上的磁盤日誌中。對於純粹基於磁盤的存儲,根據我的經驗,還有其他選項通常比mnesia更好。
  • 我的猜測是,由於某種原因,最終會出現錯誤的錯誤配置方案。猜測可能是有權限的事情。 rec.DAT可能被破壞,但我不知道是什麼讓它朝這個方向傾斜。
+0

我不是在創建數據庫和使用它之間停止shell或mnesia,所以要點不能成爲問題。此外,「修復文件」消息只是第二個症狀,當嘗試執行mnesia:read時,更重要的是出現bad_object_header錯誤。感謝您提供關於'disc_only_copies'的建議。所有必需的權限都可用於shell,因此第三點也不會成爲問題。 –

+0

我的猜測有點接近。這個錯誤來自'dets_utils'行154和169。我們試圖執行'file:pread'分散/聚集讀取,並且我們得到了'einval'或'enomem'錯誤。 –

+0

有沒有方法可以檢查它是哪一個? –