[erlang-patches] Mnesia index becomes corrupted if deleting an nonexisting object
Henrik Nord
henrik@REDACTED
Fri Jul 6 15:12:14 CEST 2012
Thank you for your contribution, I have added your patch to 'pu'
On 06/28/2012 09:22 PM, Bartłomiej Puzoń wrote:
> 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
>
>
> _______________________________________________
> erlang-patches mailing list
> erlang-patches@REDACTED
> http://erlang.org/mailman/listinfo/erlang-patches
--
/Henrik Nord Erlang/OTP
More information about the erlang-patches
mailing list