Случайная ошибка bad_object_header mnesia/dets
У меня очень странная ошибка с мнезией. У меня есть около 10 таблиц, которые Mnesia записывает, и обычно это работает нормально. Тем не менее, в определенном месте в моем коде, когда я пытаюсь прочитать из определенной таблицы (попытка чтения из других таблиц нормально), я получаю ошибку 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
линия, все работает отлично. Я попытался переделать схему и таблицы, и это не помогло. Это действительно странно, потому что мой код продолжает успешно использовать таблицу. Только если он используется из этого единственного места, он терпит неудачу.
Что может быть не так?
Обновить
Я экспериментировал еще немного, и кажется, что ошибка происходит только тогда, когда две из этих транзакций происходят (в разных процессах) почти одновременно. Разве Mnesia не должна использоваться таким образом?
Обновление 2
Оказалось, что проблема была решена путем понижения моей установки erlang на Arch Linux с R16B-6 до R16B-3. Надеюсь, эта ошибка будет исправлена в ближайшее время.
2 ответа
Симптомы означают, что либо файловая операция для чтения в определенной части файла заканчивается из памяти, либо вы пытаетесь прочитать из несуществующей позиции в файле. Так что, если у вас не хватает памяти (что вы должны были заметить), вполне вероятно, что в обработке этого файла с помощью 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,[]}]}
Я думаю, что это регрессия Эрланга, потому что я долгое время не менял код, и до обновления он работал нормально.
Я использую только DETS, а не Mnesia. У меня нет одновременного доступа к файлу.
Вот мой код, он очень прост: https://github.com/Ummon/D-LAN/blob/website/modules/erl/d_lan_db.erl#L103