[erlang-bugs] Funny behaviour of dirty_next in mnesia?

Ahmed Omar <>
Tue May 17 20:53:41 CEST 2011


I'm not a mnesia expert, but i THINK the race condition is in the test not
mnesia. transaction is still being committed and logged, when the dirty read
is issued. if you add a sleep in between or better if you use
mnesia:sync_transaction (
http://www.erlang.org/doc/man/mnesia.html#sync_transaction-3) instead of
mnesia:transaction, the test will fail, i.e the case disappear
isn't that the expected behavior or am i missing something?


On Tue, May 17, 2011 at 6:57 PM, John Hughes <> wrote:

>  QuickCheck turned up another case of odd behaviour at Klarna.
>
> The test runs mnesia on two nodes, creates a table on the OTHER node, then
> adds and deletes a record. After this the record is indeed not IN the table,
> but dirty_next finds its key anyway! Surely it shouldn't?
>
> Here's the test:
>
> test() ->
>     Slave = start_mnesia_with_slave(),
>     {atomic,ok} = mnesia:create_table(rec,[{type,set},
>         {disc_only_copies,[Slave]}]),
>     ok          = mnesia:dirty_write({rec,4,1}),
>     %% The next command MUST be done in a transaction, otherwise dirty_next
> works
>     {atomic,ok} = mnesia:transaction(fun()->mnesia:delete_object({rec,4,1})
> end),
>     %% Here's the problem: dirty_next returns 4, but this key is not in the
> table!
>     4           = mnesia:dirty_next(rec,0),
>     []          = mnesia:dirty_read(rec,4).
> I'm starting mnesia and the slave node like this:
>
> start_mnesia_with_slave() ->
>     {ok,Dir} = file:get_cwd(),
>     ok = error_logger:tty(false),
>     mnesia:stop(),
>     ok = error_logger:tty(true),
>     delete_file("mnesia"),
>     delete_file("slave"),
>     ok = file:make_dir("mnesia"),
>     ok = file:make_dir("slave"),
>     Slave = slave(),
>     ok = application:set_env(mnesia,dir,Dir++"/mnesia"),
>     ok = rpc:call(Slave,application,set_env,[mnesia,dir,Dir++"/slave"]),
>     ok = mnesia:create_schema([node(),Slave]),
>     ok = mnesia:start(),
>     ok = rpc:call(Slave,mnesia,start,[]),
>     Slave.
>
> slave() ->
>     case slave:start_link(net_adm:localhost(),"slave") of
>  {ok,Slave} ->
>      Slave;
>  {error,{already_running,Slave}} ->
>      Slave
>     end.
> I also have code to delete a file or directory, easy on Linux, darn
> difficult on Windows. You don't need this really, just run the test in an
> empty directory.
>
> delete_file(Name) ->
>     case filelib:is_dir(Name) of
>  true ->
>      [delete_file(Name++"/"++X) || X <- list_dir(Name)],
>      file:del_dir(Name),
>      delete_file(Name);
>  {error,eaccess} ->
>      delete_file(Name);
>  {error,enoent} ->
>      io:format("Could not find ~p\n",[Name]),
>      ok;
>  false ->
>      case file:delete(Name) of
>   {error,enoent} ->
>       ok;
>   {error,eacces} ->
>       io:format("Could not access ~p\n",[Name]),
>       delete_file(Name);
>   ok ->
>       delete_file(Name)
>      end
>     end.
>
> list_dir(Name) ->
>     case file:list_dir(Name) of
>  {ok,Files} ->
>      Files;
>  {error,eacces} ->
>      io:format("Could not list directory ~p\n",[Name]),
>      list_dir(Name);
>  {error,enoent} ->
>      io:format("Could not find directory ~p\n",[Name]),
>      []
>     end.
> John
>
> _______________________________________________
> erlang-bugs mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-bugs
>
>


-- 
Best Regards,
- Ahmed Omar
http://nl.linkedin.com/in/adiaa
Follow me on twitter
@spawn_think <http://twitter.com/#!/spawn_think>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20110517/922de05a/attachment.html>


More information about the erlang-bugs mailing list