From 70373f8cb0a3fe404c1e51e0ade0c98b83aa0014 Mon Sep 17 00:00:00 2001
From: Dan Gudmundsson <dgud@erlang.org>
Date: Wed, 12 Feb 2014 14:50:49 +0100
Subject: mnesia: Add explicit sync_log command

For performance reasons the file data is not synced to disk in mnesia,
data loss can happen between each dump.

mnesia:dump_log() can be used explicitly to ensure data is written to disk.
But that can take a long time, so mnesia:sync_log() which just
sync the log have been added.
---
 lib/mnesia/doc/src/mnesia.xml                 | 26 ++++++++++++++++++++++----
 lib/mnesia/src/mnesia.erl                     |  6 +++++-
 lib/mnesia/src/mnesia_monitor.erl             |  7 +++++++
 lib/mnesia/test/mnesia_nice_coverage_test.erl |  3 ++-
 4 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index 914ec77721..72e9bd7e8f 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -4,7 +4,7 @@
 <erlref>
   <header>
     <copyright>
-      <year>1996</year><year>2013</year>
+      <year>1996</year><year>2014</year>
       <holder>Ericsson AB. All Rights Reserved.</holder>
     </copyright>
     <legalnotice>
@@ -1204,7 +1204,11 @@ mnesia:create_table(person,
       <desc>
         <p>Performs a user initiated dump of the local log file.
           This is usually not necessary since Mnesia, by default,
-          manages this automatically.</p>
+          manages this automatically.
+	  See configuration parameters
+	  <seealso marker="#dump_log_time_threshold">dump_log_time_threshold</seealso> and
+	   <seealso marker="#dump_log_write_threshold">dump_log_write_threshold</seealso>.
+	</p>
       </desc>
     </func>
     <func>
@@ -2207,6 +2211,18 @@ mnesia:create_table(employee,
           Mnesia User's Guide for more details.</p>
       </desc>
     </func>
+    <func>
+      <name>sync_log() -> ok | {error, Reason} </name>
+      <fsummary>Perform a file sync of the local log file.</fsummary>
+      <desc>
+        <p>Ensures that the local transaction log file is synced to disk.
+	On a single node system data written to disk tables, since the last dump,
+	can be lost in case of a power outage.
+	See <seealso marker="#dump_log/0">dump_log/0</seealso>.
+	</p>
+      </desc>
+    </func>
+
     <func>
       <name>sync_transaction(Fun, [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun} </name>
       <fsummary>Synchronously execute a transaction.</fsummary>
@@ -2445,7 +2461,7 @@ mnesia:create_table(employee,
       <name>table(Tab [,[Option]]) -> QueryHandle </name>
       <fsummary>Return a QLC query handle.</fsummary>
       <desc>
-        <p>          <marker id="qlc_table"></marker>
+        <p><marker id="qlc_table"></marker>
 Returns a QLC (Query List Comprehension) query handle, see
           <seealso marker="stdlib:qlc">qlc(3)</seealso>.The module <c>qlc</c> implements a query language, it
           can use mnesia tables as sources of data. Calling
@@ -3015,6 +3031,7 @@ raise(Name, Amount) ->
           performed on the original data file. The default is <c>true</c></p>
       </item>
       <item>
+	<marker id=" dump_log_write_threshold"></marker>
         <p><c>-mnesia dump_log_write_threshold Max</c>, where
           <c>Max</c> is an integer which specifies the maximum number of writes
           allowed to the transaction log before a new dump of the log
@@ -3022,13 +3039,14 @@ raise(Name, Amount) ->
           </p>
       </item>
       <item>
+	<marker id=" dump_log_time_threshold"></marker>
         <p><c>-mnesia dump_log_time_threshold Max</c>,
           where <c>Max</c> is an integer which
           specifies the dump log interval in milliseconds. It defaults
           to 3 minutes. If a dump has not been performed within
           <c>dump_log_time_threshold</c> milliseconds, then a new dump is
           performed regardless of how many writes have been
-          performed. 
+          performed.
           </p>
       </item>
       <item>
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 70466d10d7..b791e1221f 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -104,7 +104,8 @@
 	 set_master_nodes/1, set_master_nodes/2,
 
 	 %% Misc admin
-	 dump_log/0, subscribe/1, unsubscribe/1, report_event/1,
+	 dump_log/0, sync_log/0,
+	 subscribe/1, unsubscribe/1, report_event/1,
 
 	 %% Snmp
 	 snmp_open_table/2, snmp_close_table/1,
@@ -2554,6 +2555,9 @@ set_master_nodes(Tab, Nodes) ->
 dump_log() ->
     mnesia_controller:sync_dump_log(user).
 
+sync_log() ->
+    mnesia_monitor:sync_log(latest_log).
+
 subscribe(What) ->
     mnesia_subscr:subscribe(self(), What).
 
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index c7b905a1bf..7b56613ad7 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.erl
@@ -44,6 +44,7 @@
 	 set_env/2,
 	 start/0,
 	 start_proc/4,
+	 sync_log/1,
 	 terminate_proc/3,
 	 unsafe_close_dets/1,
 	 unsafe_close_log/1,
@@ -118,6 +119,9 @@ open_log(Args) ->
 reopen_log(Name, Fname, Head) ->
     unsafe_call({reopen_log, Name, Fname, Head}).
 
+sync_log(Name) ->
+    unsafe_call({sync_log, Name}).
+
 close_log(Name) ->
     unsafe_call({close_log, Name}).
 
@@ -382,6 +386,9 @@ handle_call({reopen_log, Name, Fname, Head}, _From, State) ->
  	    {noreply, State}
     end;
 
+handle_call({sync_log, Name}, _From, State) ->
+    {reply, disk_log:sync(Name), State};
+
 handle_call({close_log, Name}, _From, State) ->
     case disk_log:close(Name) of
 	ok ->
diff --git a/lib/mnesia/test/mnesia_nice_coverage_test.erl b/lib/mnesia/test/mnesia_nice_coverage_test.erl
index 78eab67b11..4b28ac634f 100644
--- a/lib/mnesia/test/mnesia_nice_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_nice_coverage_test.erl
@@ -1,7 +1,7 @@
 %%
 %% %CopyrightBegin%
 %%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
 %%
 %% The contents of this file are subject to the Erlang Public License,
 %% Version 1.1, (the "License"); you may not use this file except in
@@ -189,6 +189,7 @@ adm(Attrs, Node1, Node2) ->
     ?match({atomic, ok}, mnesia:move_table_copy(nice_tab, Node2, Node1)), 
 
     ?match(yes, mnesia:force_load_table(nice_counter_tab)), 
+    ?match(ok, mnesia:sync_log()),
     ?match(dumped, mnesia:dump_log()),
     ok.
 
-- 
cgit v1.2.3