[erlang-bugs] Funny behaviour of dirty_next in mnesia?
John Hughes
john.hughes@REDACTED
Tue May 17 18:57:38 CEST 2011
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20110517/08f44f60/attachment.htm>
More information about the erlang-bugs
mailing list