[erlang-bugs] Funny behaviour of dirty_next in mnesia?
Ahmed Omar
spawn.think@REDACTED
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 <john.hughes@REDACTED> 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
> erlang-bugs@REDACTED
> 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.htm>
More information about the erlang-bugs
mailing list