[erlang-patches] Mnesia index becomes corrupted if deleting an nonexisting object
Bartłomiej Puzoń
bartlomiej@REDACTED
Thu Jun 28 21:22:57 CEST 2012
Dear OTP team,
======= Description
Let's have the following record:
-record(r, {key,index,data}).
test()-> mnesia:delete_table(r),
mnesia:create_table(r, [{type, bag},
{attributes, record_info(fields,r)}]),
mnesia:add_table_index(r, index),
%% Lets insert a random record to our table
Record1 = #r{key = k, index = i, data = 1},
mnesia:dirty_write(r, Record1),
%% This should return [{r,k,i,1}] and it does
mnesia:dirty_index_read(r, i, #r.index)
%% Now lets try to delete something that is not in the table, but
%% shares the same key and index
Record2 = #r{key = k, index = i, data = 2},
mnesia:dirty_delete_object(r, Record2),
%% And now our big finale. This call, which is exactly the same
%% as the previous index read, should give the same results
mnesia:dirty_index_read(r, i, #r.index).
%% BUT it returns [] instead. Somehow the index got changed even thoug
%% we never touched the table itself
After a period of witch-hunting the culprit turned out to be hiding in mnesia_index:
119 del_object_bag(Tab, Key, Obj, Pos, Ixt, undefined) ->
120 IxKey = element(Pos, Obj),
121 Old = [X || X <- mnesia_lib:db_get(Tab, Key), element(Pos, X) =:= IxKey],
122 del_object_bag(Tab, Key, Obj, Pos, Ixt, Old);
123 %% If Tab type is bag we need remove index identifier if Tab
124 %% contains less than 2 elements.
125 del_object_bag(_Tab, Key, Obj, Pos, Ixt, Old) when length(Old) < 2 ->
126 del_ixes(Ixt, [Obj], Pos, Key);
127 del_object_bag(_Tab, _Key, _Obj, _Pos, _Ixt, _Old) -> ok.
Our call to dirty_delete_object results in mnesia_index:del_object_bag being called as follows:
mnesia_index:del_object_bag(r,k,{r,k,i,2},3,{ram,14221431},[{r,k,i,1}])
As you can see, the object we are deleting and the object that is in the table (last argument) are
different. However, mnesia_index still happily deletes the index.
======= Links
Github: bpuzon/otp, branch: fix_mnesia_index_drop
Git command: git fetch git://github.com/bpuzon/otp.git fix_mnesia_index_drop
https://github.com/bpuzon/otp/compare/fix_mnesia_index_drop
https://github.com/bpuzon/otp/compare/fix_mnesia_index_drop.patch
Bartłomiej Puzoń
Erlang Solutions
More information about the erlang-patches
mailing list