[erlang-questions] mnesia sync_transactions not fsynced?

Emile Joubert emile@REDACTED
Thu Oct 27 13:17:55 CEST 2011


The docs for mnesia:sync_transactions say that it will wait until data
have been committed and logged to disk (if disk is used). (R14B04)

That appears not to be the case, as a test script illustrates. Repeated
execution of the script (containing paired writes and deletes) should
leave an empty table, but every so often the database starts up
non-empty, indicating that a previous delete was not recorded on disk.

Inserting "disk_log:sync(latest_log)" seems to work around the problem
in the single-node case, but doesn't help when multiple nodes are
involved. What is the recommended approach to guarantee that
transactions are on disk, in both single and multiple node situations?

A previous message on this list appears to indicate that transactions
cannot be made safe in the way that I need:
http://erlang.2086793.n4.nabble.com/Mnesia-disk-logging-and-synchronous-disk-logging-td2087144.html
Is that information still accurate?



-Emile





---- 8< ----- 8< ----- 8< ----- 8< ----- 8< ----- 8< ----- 8< -----
#!/usr/bin/env escript
%%! -sname testnode -mnesia debug verbose

-record(testrec, {id, val=''}).

main([]) ->
    main(["200"]);
main([Arg]) ->
    mnesia_setup(),
    Ids = mnesia:dirty_select(testtab,
                             [{#testrec{id='$1',val='_'},[],['$1']}]),
    io:format("~w entries found: ~w~n", [length(Ids), Ids]),
    runtest(list_to_integer(Arg)).

mnesia_setup() ->
    mnesia:create_schema([node()]),
    mnesia:start(),
    mnesia:create_table(testtab,
                        [{disc_copies, [node()]},
                         {record_name, testrec},
                         {attributes, record_info(fields, testrec)}]),
    mnesia:wait_for_tables([testtab], 1000).

runtest(0) ->
    %disk_log:sync(latest_log),
    halt();
runtest(N) ->
    mnesia:sync_transaction(
        fun () -> mnesia:write(testtab, #testrec{id = N}, write) end),
    mnesia:sync_transaction(fun () -> mnesia:delete({testtab, N}) end),
    runtest(N-1).



More information about the erlang-questions mailing list