[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