Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 1002

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css">
<title>Erlang -- Mnesia System Information</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/mnesia-4.7.1.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>Mnesia</strong><br><strong>User's Guide</strong><br><small>Version 4.7.1</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../../../../doc/js/flipmenu">
<li id="no" title="Introduction" expanded="false">Introduction<ul>
<li><a href="Mnesia_chap1.html">
              Top of chapter
            </a></li>
<li title="About Mnesia"><a href="Mnesia_chap1.html#id57488">About Mnesia</a></li>
<li title="The Mnesia DataBase Management System (DBMS)"><a href="Mnesia_chap1.html#id57481">The Mnesia DataBase Management System (DBMS)</a></li>
</ul>
</li>
<li id="no" title="Getting Started with Mnesia" expanded="false">Getting Started with Mnesia<ul>
<li><a href="Mnesia_chap2.html">
              Top of chapter
            </a></li>
<li title="Starting Mnesia for the first time"><a href="Mnesia_chap2.html#id61530">Starting Mnesia for the first time</a></li>
<li title="An Introductory Example"><a href="Mnesia_chap2.html#id62101">An Introductory Example</a></li>
</ul>
</li>
<li id="no" title="Building A Mnesia Database" expanded="false">Building A Mnesia Database<ul>
<li><a href="Mnesia_chap3.html">
              Top of chapter
            </a></li>
<li title="Defining a Schema"><a href="Mnesia_chap3.html#id67814">Defining a Schema</a></li>
<li title="The Data Model"><a href="Mnesia_chap3.html#id68070">The Data Model</a></li>
<li title="Starting Mnesia"><a href="Mnesia_chap3.html#id68125">Starting Mnesia</a></li>
<li title="Creating New Tables"><a href="Mnesia_chap3.html#id72288">Creating New Tables</a></li>
</ul>
</li>
<li id="no" title="Transactions and Other Access Contexts" expanded="false">Transactions and Other Access Contexts<ul>
<li><a href="Mnesia_chap4.html">
              Top of chapter
            </a></li>
<li title="Transaction Properties"><a href="Mnesia_chap4.html#id72980">Transaction Properties</a></li>
<li title="Locking"><a href="Mnesia_chap4.html#id73193">Locking</a></li>
<li title="Dirty Operations"><a href="Mnesia_chap4.html#id73653">Dirty Operations</a></li>
<li title="Record Names versus Table Names"><a href="Mnesia_chap4.html#id74026">Record Names versus Table Names</a></li>
<li title="Activity Concept and Various Access Contexts"><a href="Mnesia_chap4.html#id74114">Activity Concept and Various Access Contexts</a></li>
<li title="Nested transactions"><a href="Mnesia_chap4.html#id74404">Nested transactions</a></li>
<li title="Pattern Matching"><a href="Mnesia_chap4.html#id74476">Pattern Matching</a></li>
<li title="Iteration"><a href="Mnesia_chap4.html#id74822">Iteration</a></li>
</ul>
</li>
<li id="no" title="Miscellaneous Mnesia Features" expanded="false">Miscellaneous Mnesia Features<ul>
<li><a href="Mnesia_chap5.html">
              Top of chapter
            </a></li>
<li title="Indexing"><a href="Mnesia_chap5.html#id75164">Indexing</a></li>
<li title="Distribution and Fault Tolerance"><a href="Mnesia_chap5.html#id75284">Distribution and Fault Tolerance</a></li>
<li title="Table Fragmentation"><a href="Mnesia_chap5.html#id75432">Table Fragmentation</a></li>
<li title="Local Content Tables"><a href="Mnesia_chap5.html#id76375">Local Content Tables</a></li>
<li title="Disc-less Nodes"><a href="Mnesia_chap5.html#id76402">Disc-less Nodes</a></li>
<li title="More Schema Management"><a href="Mnesia_chap5.html#id76560">More Schema Management</a></li>
<li title="Mnesia Event Handling"><a href="Mnesia_chap5.html#id76675">Mnesia Event Handling</a></li>
<li title="Debugging Mnesia Applications"><a href="Mnesia_chap5.html#id77250">Debugging Mnesia Applications</a></li>
<li title="Concurrent Processes in Mnesia"><a href="Mnesia_chap5.html#id77395">Concurrent Processes in Mnesia</a></li>
<li title="Prototyping"><a href="Mnesia_chap5.html#id77432">Prototyping</a></li>
<li title="Object Based Programming with Mnesia"><a href="Mnesia_chap5.html#id77546">Object Based Programming with Mnesia</a></li>
</ul>
</li>
<li id="loadscrollpos" title="Mnesia System Information" expanded="true">Mnesia System Information<ul>
<li><a href="Mnesia_chap7.html">
              Top of chapter
            </a></li>
<li title="Database Configuration Data"><a href="Mnesia_chap7.html#id77779">Database Configuration Data</a></li>
<li title="Core Dumps"><a href="Mnesia_chap7.html#id77817">Core Dumps</a></li>
<li title="Dumping Tables"><a href="Mnesia_chap7.html#id77838">Dumping Tables</a></li>
<li title="Checkpoints"><a href="Mnesia_chap7.html#id77873">Checkpoints</a></li>
<li title="Files"><a href="Mnesia_chap7.html#id78113">Files</a></li>
<li title="Loading of Tables at Start-up"><a href="Mnesia_chap7.html#id78474">Loading of Tables at Start-up</a></li>
<li title="Recovery from Communication Failure"><a href="Mnesia_chap7.html#id78632">Recovery from Communication Failure</a></li>
<li title="Recovery of Transactions"><a href="Mnesia_chap7.html#id78755">Recovery of Transactions</a></li>
<li title="Backup, Fallback, and Disaster Recovery"><a href="Mnesia_chap7.html#id78876">Backup, Fallback, and Disaster Recovery</a></li>
</ul>
</li>
<li id="no" title="Combining Mnesia with SNMP" expanded="false">Combining Mnesia with SNMP<ul>
<li><a href="Mnesia_chap8.html">
              Top of chapter
            </a></li>
<li title="Combining Mnesia and SNMP "><a href="Mnesia_chap8.html#id79691">Combining Mnesia and SNMP </a></li>
</ul>
</li>
<li id="no" title="Appendix A: Mnesia Error Messages" expanded="false">Appendix A: Mnesia Error Messages<ul>
<li><a href="Mnesia_App_A.html">
              Top of chapter
            </a></li>
<li title="Errors in Mnesia"><a href="Mnesia_App_A.html#id79834">Errors in Mnesia</a></li>
</ul>
</li>
<li id="no" title="Appendix B: The Backup Call Back Interface" expanded="false">Appendix B: The Backup Call Back Interface<ul>
<li><a href="Mnesia_App_B.html">
              Top of chapter
            </a></li>
<li title="mnesia_backup callback behavior"><a href="Mnesia_App_B.html#id80051">mnesia_backup callback behavior</a></li>
</ul>
</li>
<li id="no" title="Appendix C: The Activity Access Call Back Interface" expanded="false">Appendix C: The Activity Access Call Back Interface<ul>
<li><a href="Mnesia_App_C.html">
              Top of chapter
            </a></li>
<li title="mnesia_access callback behavior"><a href="Mnesia_App_C.html#id80172">mnesia_access callback behavior</a></li>
</ul>
</li>
<li id="no" title="Appendix D: The Fragmented Table Hashing Call Back Interface" expanded="false">Appendix D: The Fragmented Table Hashing Call Back Interface<ul>
<li><a href="Mnesia_App_D.html">
              Top of chapter
            </a></li>
<li title="mnesia_frag_hash callback behavior"><a href="Mnesia_App_D.html#id80315">mnesia_frag_hash callback behavior</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>6 Mnesia System Information</h1>
  

  <h3><a name="id77779">6.1 
        Database Configuration Data</a></h3>
    
    <p>The following two functions can be used to retrieve system
      information. They are described in detail in the reference manual.
      </p>
    <ul>
      <li>
<span class="code">mnesia:table_info(Tab, Key) -&gt;</span><span class="code">Info | exit({aborted,  Reason})</span>. 
       Returns information about one table. Such as the
       current size of the table, on which nodes it resides etc.
      </li>
      <li>
<span class="code">mnesia:system_info(Key) -&gt; </span><span class="code">Info | exit({aborted, Reason})</span>.
       Returns information about the Mnesia system. For example, transaction
       statistics, db_nodes, configuration parameters etc. 
      </li>
    </ul>
  

  <h3><a name="id77817">6.2 
        Core Dumps</a></h3>
    
    <p>If Mnesia malfunctions, system information is dumped to a file
      named <span class="code">MnesiaCore.Node.When</span>. The type of system
      information contained in this file can also be generated with
      the function <span class="code">mnesia_lib:coredump()</span>. If a Mnesia system
      behaves strangely, it is recommended that a Mnesia core dump
      file be included in the bug report.</p>
  

  <h3><a name="id77838">6.3 
        Dumping Tables</a></h3>
    
    <p>Tables of type <span class="code">ram_copies</span> are by definition stored in
      memory only. It is possible, however, to dump these tables to
      disc, either at regular intervals, or before the system is
      shutdown. The function <span class="code">mnesia:dump_tables(TabList)</span> dumps
      all replicas of a set of RAM tables to disc. The tables can be
      accessed while being dumped to disc. To dump the tables to 
      disc all replicas must have the storage type <span class="code">ram_copies</span>.
      </p>
    <p>The table content is placed in a .DCD file on the
      disc. When the Mnesia system is started, the RAM table will
      initially be loaded with data from its .DCD file. 
      </p>
  

  <h3><a name="id77873">6.4 
        Checkpoints</a></h3>
    <a name="checkpoints"></a>
    
    <p>A checkpoint is a transaction consistent state that spans over
      one or more tables. When a checkpoint is activated, the system
      will remember the current content of the set of tables.  The
      checkpoint retains a transaction consistent state of the tables,
      allowing the tables to be read and updated while the checkpoint
      is active.  A checkpoint is typically used to
      back up tables to external media, but they are also used
      internally in Mnesia for other purposes. Each checkpoint is
      independent and a table may be involved in several checkpoints
      simultaneously.
      </p>
    <p>Each table retains its old contents in a checkpoint retainer
      and for performance critical applications, it may be important
      to realize the processing overhead associated with checkpoints.
      In a worst case scenario, the checkpoint retainer will consume
      even more memory than the table itself. Each update will also be
      slightly slower on those nodes where checkpoint
      retainers are attached to the tables.
      </p>
    <p>For each table it is possible to choose if there should be one
      checkpoint retainer attached to all replicas of the table, or if
      it is enough to have only one checkpoint retainer attached to a
      single replica. With a single checkpoint retainer per table, the
      checkpoint will consume less memory, but it will be vulnerable
      to node crashes. With several redundant checkpoint retainers the
      checkpoint will survive as long as there is at least one active
      checkpoint retainer attached to each table.
      </p>
    <p>Checkpoints may be explicitly deactivated with the function
      <span class="code">mnesia:deactivate_checkpoint(Name)</span>, where <span class="code">Name</span> is
      the name of an active checkpoint. This function returns
      <span class="code">ok</span> if successful, or <span class="code">{error, Reason}</span> in the case
      of an error. All tables in a checkpoint must be attached to at
      least one checkpoint retainer. The checkpoint is automatically
      de-activated by Mnesia, when any table lacks a checkpoint
      retainer. This may happen when a node goes down or when a
      replica is deleted. Use the <span class="code">min</span> and
      <span class="code">max</span> arguments described below, to control the degree of
      checkpoint retainer redundancy.
      </p>
    <p>Checkpoints are activated with the function       <a name="mnesia:chkpt(Args)"></a>
<span class="code">mnesia:activate_checkpoint(Args)</span>,
      where <span class="code">Args</span> is a list of the following tuples:
      </p>
    <ul>
      <li>
<span class="code">{name,Name}</span>. <span class="code">Name</span> specifies a temporary name
       of the checkpoint. The name may be re-used when the checkpoint
       has been de-activated. If no name is specified, a name is
       generated automatically.
      </li>
      <li>
<span class="code">{max,MaxTabs}</span>. <span class="code">MaxTabs</span> is a list of tables
       which will be included in the checkpoint. The default is
      <span class="code">[]</span> (an empty list). For these tables, the redundancy
       will be maximized. The old contents of the table will be
       retained in the checkpoint retainer when the main table is
       updated by the applications. The checkpoint becomes more fault
       tolerant if the tables have several replicas. When new
       replicas are added by means of the schema manipulation
       function <span class="code">mnesia:add_table_copy/3</span>, it will also
       attach a local checkpoint retainer.
      </li>
      <li>
<span class="code">{min,MinTabs}</span>. <span class="code">MinTabs</span> is a list of tables
       that should be included in the checkpoint. The default is
      <span class="code">[]</span>. For these tables, the redundancy will be minimized,
       and there will be a single checkpoint retainer per table,
       preferably at the local node.
      </li>
      <li>
<span class="code">{allow_remote,Bool}</span>. <span class="code">false</span> means that all
       checkpoint retainers must be local. If a table does not reside
       locally, the checkpoint cannot be activated. <span class="code">true</span>
       allows checkpoint retainers to be allocated on any node. The
       defaults is <span class="code">true</span>.
      </li>
      <li>
<span class="code">{ram_overrides_dump,Bool}</span>. This argument only
       applies to tables of type <span class="code">ram_copies</span>. <span class="code">Bool</span>
       specifies if the table state in RAM should override the table
       state on disc. <span class="code">true</span> means that the latest committed
       records in RAM are included in the checkpoint retainer. These
       are the records that the application accesses. <span class="code">false</span>
       means that the records on the disc .DAT file are
       included in the checkpoint retainer. These are the records
       that will be loaded on start-up. Default is <span class="code">false</span>.</li>
    </ul>
    <p>The <span class="code">mnesia:activate_checkpoint(Args)</span> returns one of the
      following values:
      </p>
    <ul>
      <li><span class="code">{ok, Name, Nodes}</span></li>
      <li>
<span class="code">{error, Reason}</span>.</li>
    </ul>
    <p><span class="code">Name</span> is the name of the checkpoint, and <span class="code">Nodes</span> are
      the nodes where the checkpoint is known.
      </p>
    <p>A list of active checkpoints can be obtained with the following
      functions:
      </p>
    <ul>
      <li>
<span class="code">mnesia:system_info(checkpoints)</span>. This function
       returns all active checkpoints on the current node.</li>
      <li>
<span class="code">mnesia:table_info(Tab,checkpoints)</span>. This function
       returns active checkpoints on a specific table.</li>
    </ul>
  

  <h3><a name="id78113">6.5 
        Files</a></h3>
    
    <p>This section describes the internal files which are created and maintained by the Mnesia system,
      in particular, the workings of the Mnesia log is described.
      </p>

    <h4>Start-Up Files</h4>
      
    
    <p>In Chapter 3 we detailed the following pre-requisites for
      starting Mnesia (refer Chapter 3: <span class="bold_code"><a href="Mnesia_chap3.html#start_mnesia">Starting Mnesia</a></span>:
      </p>
    <ul>
      <li>We must start an Erlang session and specify a Mnesia
       directory for our database.  
      </li>
      <li>We must initiate a database schema, using the function
      <span class="code">mnesia:create_schema/1</span>.
      </li>
    </ul>
    <p>The following example shows how these tasks are performed:
      </p>
    <ul>
      <li>
        <div class="example"><pre>
% <span class="bold_code">erl  -sname klacke -mnesia dir '"/ldisc/scratch/klacke"'</span>        </pre></div>
      </li>
      <li>
        <div class="example"><pre>
Erlang (BEAM) emulator version 4.9
 
Eshell V4.9  (abort with ^G)
(klacke@gin)1&gt; <span class="bold_code">mnesia:create_schema([node()]).</span>
ok
(klacke@gin)2&gt; 
<span class="bold_code">^Z</span>
Suspended        </pre></div>
        <p>We can inspect the Mnesia directory to see what files have been created. Enter the following command:
          </p>
        <div class="example"><pre>
% <span class="bold_code">ls -l /ldisc/scratch/klacke</span>
-rw-rw-r--   1 klacke   staff       247 Aug 12 15:06 FALLBACK.BUP        </pre></div>
        <p>The response shows that the file FALLBACK.BUP has been created. This is called a backup file, and it contains an initial schema. If we had specified more than one node in the <span class="code">mnesia:create_schema/1</span> function, identical backup files would have been created on all nodes.
          </p>
      </li>
      <li>
        <p>Continue by starting Mnesia:</p>
        <div class="example"><pre>
(klacke@gin)3&gt;<span class="bold_code">mnesia:start( ).</span>
ok        </pre></div>
        <p>We can now see the following listing in the Mnesia directory:
          </p>
        <div class="example"><pre>
-rw-rw-r--   1 klacke   staff         86 May 26 19:03 LATEST.LOG
-rw-rw-r--   1 klacke   staff      34507 May 26 19:03 schema.DAT        </pre></div>
        <p>The schema in the backup file FALLBACK.BUP has been used to generate the file <span class="code">schema.DAT.</span> Since we have no other disc resident tables than the schema, no other data files were created. The file FALLBACK.BUP was removed after the successful "restoration". We also see a number of files that are for internal use by Mnesia.       
          </p>
      </li>
      <li>
        <p>Enter the following command to create a table:</p>
        <div class="example"><pre>
(klacke@gin)4&gt; <span class="bold_code">mnesia:create_table(foo,[{disc_copies, [node()]}]).</span>
{atomic,ok}        </pre></div>
        <p>We can now see the following listing in the Mnesia directory:
          </p>
        <div class="example"><pre>
% <span class="bold_code">ls -l /ldisc/scratch/klacke</span>
-rw-rw-r-- 1 klacke staff    86 May 26 19:07 LATEST.LOG
-rw-rw-r-- 1 klacke staff    94 May 26 19:07 foo.DCD
-rw-rw-r-- 1 klacke staff  6679 May 26 19:07 schema.DAT        </pre></div>
        <p>Where a file <span class="code">foo.DCD</span> has been created. This file will eventually store
          all data that is written into the <span class="code">foo</span> table.</p>
      </li>
    </ul>

    <h4>The Log File</h4>
      
      <p>When starting Mnesia, a .LOG file called <span class="code">LATEST.LOG</span>
        was created and placed in the database directory. This file is
        used by Mnesia to log disc based transactions. This includes all
        transactions that write at least one record in a table which is
        of storage type <span class="code">disc_copies</span>, or
        <span class="code">disc_only_copies</span>. It also includes all operations which
        manipulate the schema itself, such as creating new tables. The
        format of the log can vary with different implementations of
        Mnesia. The Mnesia log is currently implemented with the
        standard library module <span class="code">disc_log</span>.
        </p>
      <p>The log file will grow continuously and must be dumped at
        regular intervals. "Dumping the log file" means that Mnesia will
        perform all the operations listed in the log and place the
        records in the corresponding .DAT, .DCD and .DCL data files. For
        example, if the operation "write record <span class="code">{foo, 4, elvis,  6}</span>" 
        is listed in the log, Mnesia inserts the operation into the
        file <span class="code">foo.DCL</span>, later when Mnesia thinks the .DCL has become to large
        the data is moved to the .DCD file.
        The dumping operation can be time consuming
        if the log is very large. However, it is important to realize
        that the Mnesia system continues to operate during log dumps.
        </p>
      <p>By default Mnesia either dumps the log whenever 100 records have
        been written in the log or when 3 minutes have passed. 
        This is controlled by the two application parameters
        <span class="code">-mnesia dump_log_write_threshold WriteOperations</span> and
        <span class="code">-mnesia dump_log_time_threshold MilliSecs</span>.
        </p>
      <p>Before the log is dumped, the file <span class="code">LATEST.LOG</span> is
        renamed to <span class="code">PREVIOUS.LOG</span>, and a new <span class="code">LATEST.LOG</span> file
        is created. Once the log has been successfully dumped, the file
        <span class="code">PREVIOUS.LOG</span> is deleted.
        </p>
      <p>The log is also dumped at start-up and whenever a schema
        operation is performed.
        </p>
    

    <h4>The Data Files</h4>
      
      <p>The directory listing also contains one .DAT file. This contain
        the schema itself, contained in the <span class="code">schema.DAT</span>
        file. The DAT files are indexed files, and it is efficient to
        insert and search for records in these files with a specific
        key. The .DAT files are used for the schema and for <span class="code">disc_only_copies</span>
        tables. The Mnesia data files are currently implemented with the
        standard library module <span class="code">dets</span>, and all operations which
        can be performed on <span class="code">dets</span> files can also be performed on
        the Mnesia data files.  For example, <span class="code">dets</span> contains a
        function <span class="code">dets:traverse/2</span> which can be used to view the
        contents of a Mnesia DAT file. However, this can only be done
        when Mnesia is not running. So, to view a our schema file, we
        can:  </p>
      <div class="example"><pre>
{ok, N} = dets:open_file(schema, [{file, "./schema.DAT"},{repair,false}, 
{keypos, 2}]),
F = fun(X) -&gt; io:format("~p~n", [X]), continue end,
dets:traverse(N, F),
dets:close(N).      </pre></div>
      <div class="note">
<div class="label">Note</div>
<div class="content"><p>
        <p>Refer to the Reference Manual, <span class="code">std_lib</span> for information about <span class="code">dets</span>.</p>
      </p></div>
</div>
      <div class="warning">
<div class="label">Warning</div>
<div class="content"><p>
        <p>The DAT files must always be opened with the <span class="code">{repair, false}</span>
          option. This ensures that these files are not
          automatically repaired. Without this option, the database may
          become inconsistent, because Mnesia may 
          believe that the files were properly closed. Refer to the reference
          manual for information about the configuration parameter
          <span class="code">auto_repair</span>.</p>
      </p></div>
</div>
      <div class="warning">
<div class="label">Warning</div>
<div class="content"><p>
        <p>It is recommended that Data files are not tampered with while Mnesia is
          running. While not prohibited, the behavior of Mnesia is unpredictable.         </p>
      </p></div>
</div>
      <p>The <span class="code">disc_copies</span> tables are stored on disk with .DCL and .DCD files,
        which are standard disk_log files.
        </p>
    
  

  <h3><a name="id78474">6.6 
        Loading of Tables at Start-up</a></h3>
    
    <p>At start-up Mnesia loads tables in order to make them accessible
      for its applications. Sometimes Mnesia decides to load all tables
      that reside locally, and sometimes the tables may not be
      accessible until Mnesia brings a copy of the table
      from another node.
      </p>
    <p>To understand the behavior of Mnesia at start-up it is
      essential to understand how Mnesia reacts when it loses contact
      with Mnesia on another node.  At this stage, Mnesia cannot distinguish
      between a communication failure and a "normal" node down.      <br>

      When this happens, Mnesia  will assume that the other node is no longer running.
      Whereas, in reality, the communication between the nodes has merely failed.
      </p>
    <p>To overcome this situation, simply try to restart the ongoing transactions that are
      accessing tables on the failing node, and write a <span class="code">mnesia_down</span> entry to a log file.
      </p>
    <p>At start-up, it must be noted that all tables residing on nodes 
      without a <span class="code">mnesia_down</span> entry, may have fresher replicas. 
      Their replicas may have been updated after the termination
      of Mnesia on the current node. In order to catch up with the latest
      updates, transfer a copy of the table from one of these other
      "fresh" nodes. If you are unlucky, other nodes may be down
      and you must wait for the table to be
      loaded on one of these nodes before receiving a fresh copy of
      the table.
      </p>
    <p>Before an application makes its first access to a table,
      <span class="code">mnesia:wait_for_tables(TabList, Timeout)</span> ought to be executed
      to ensure that the table is accessible from the local node. If
      the function times out the application may choose to force a
      load of the local replica with
      <span class="code">mnesia:force_load_table(Tab)</span> and deliberately lose all
      updates that may have been performed on the other nodes while
      the local node was down.  If
      Mnesia already has loaded the table on another node or intends
      to do so, we will copy the table from that node in order to
      avoid unnecessary inconsistency.
      </p>
    <div class="warning">
<div class="label">Warning</div>
<div class="content"><p>
      <p>Keep in mind that it is only
        one table that is loaded by <span class="code">mnesia:force_load_table(Tab)</span>
        and since committed transactions may have caused updates in
        several tables, the tables may now become inconsistent due to
        the forced load.</p>
    </p></div>
</div>
    <p>The allowed <span class="code">AccessMode</span> of a table may be defined to
      either be <span class="code">read_only</span> or <span class="code">read_write</span>. And it may be
      toggled with the function <span class="code">mnesia:change_table_access_mode(Tab, AccessMode)</span> in runtime. <span class="code">read_only</span> tables and
      <span class="code">local_content</span> tables will always be loaded locally, since
      there are no need for copying the table from other nodes.  Other
      tables will primary be loaded remotely from active replicas on
      other nodes if the table already has been loaded there, or if
      the running Mnesia already has decided to load the table there.
      </p>
    <p>At start up, Mnesia will assume that its local replica is the 
      most recent version and load the table from disc if either
      situation is detected:
      </p>
    <ul>
      <li>
<span class="code">mnesia_down</span> is returned from all other nodes that holds a disc
       resident replica of the table; or,</li>
      <li>if all replicas are <span class="code">ram_copies</span>
</li>
    </ul>
    <p>This is normally a wise decision, but it may turn out to
      be disastrous if the nodes have been disconnected due to a
      communication failure, since Mnesia's normal table load
      mechanism does not cope with communication failures.
      </p>
    <p>When Mnesia is loading many tables the default load
      order. However, it is possible to
      affect the load order by explicitly changing the
      <span class="code">load_order</span> property for the tables, with the function
      <span class="code">mnesia:change_table_load_order(Tab, LoadOrder)</span>. The
      <span class="code">LoadOrder</span> is by default <span class="code">0</span> for all tables, but it
      can be set to any integer. The table with the highest
      <span class="code">load_order</span> will be loaded first. Changing load order is
      especially useful for applications that need to ensure early
      availability of fundamental tables. Large peripheral
      tables should have a low load order value, perhaps set
      below 0.
      </p>
  

  <h3><a name="id78632">6.7 
        Recovery from Communication Failure</a></h3>
    
    <p>There are several occasions when Mnesia may detect that the
      network has been partitioned due to a communication failure.
      </p>
    <p>One is when Mnesia already is up and running and the Erlang
      nodes gain contact again. Then Mnesia will try to contact Mnesia
      on the other node to see if it also thinks that the network has
      been partitioned for a while. If Mnesia on both nodes has logged
      <span class="code">mnesia_down</span> entries from each other, Mnesia generates a
      system event, called <span class="code">{inconsistent_database, running_partitioned_network, Node}</span> which is sent to Mnesia's
      event handler and other possible subscribers. The default event
      handler reports an error to the error logger.
      </p>
    <p>Another occasion when Mnesia may detect that the network has
      been partitioned due to a communication failure, is at start-up.
      If Mnesia detects that both the local node and another node received
      <span class="code">mnesia_down</span> from each other it generates a
      <span class="code">{inconsistent_database, starting_partitioned_network, Node}</span> system event and acts as described above.
      </p>
    <p>If the application detects that there has been a communication
      failure which may have caused an inconsistent database, it may
      use the function <span class="code">mnesia:set_master_nodes(Tab, Nodes)</span> to
      pinpoint from which nodes each table may be loaded.</p>
    <p>At start-up Mnesia's normal table load algorithm will be
      bypassed and the table will be loaded from one of the master
      nodes defined for the table, regardless of potential
      <span class="code">mnesia_down</span> entries in the log. The <span class="code">Nodes</span> may only
      contain nodes where the table has a replica and if it is empty,
      the master node recovery mechanism for the particular table will
      be reset and the normal load mechanism will be used when next
      restarting.
      </p>
    <p>The function <span class="code">mnesia:set_master_nodes(Nodes)</span> sets master
      nodes for all tables. For each table it will determine its
      replica nodes and invoke <span class="code">mnesia:set_master_nodes(Tab, TabNodes)</span> with those replica nodes that are included in the
      <span class="code">Nodes</span> list (i.e. <span class="code">TabNodes</span> is the intersection of
      <span class="code">Nodes</span> and the replica nodes of the table). If the
      intersection is empty the master node recovery mechanism for the
      particular table will be reset and the normal load mechanism
      will be used at next restart.
      </p>
    <p>The functions <span class="code">mnesia:system_info(master_node_tables)</span> and
      <span class="code">mnesia:table_info(Tab, master_nodes)</span> may be used to
      obtain information about the potential master nodes.
      </p>
    <p>Determining which data to keep after communication failure is outside
    the scope of Mnesia. One approach would be to determine which "island"
    contains a majority of the nodes. Using the <span class="code">{majority,true}</span> option
    for critical tables can be a way of ensuring that nodes that are not part
    of a "majority island" are not able to update those tables. Note that this
    constitutes a reduction in service on the minority nodes. This would be
    a tradeoff in favour of higher consistency guarantees.</p>
    <p>The function <span class="code">mnesia:force_load_table(Tab)</span> may be used to
      force load the table regardless of which table load mechanism
      is activated.
      </p>
  

  <h3><a name="id78755">6.8 
        Recovery of Transactions</a></h3>
    
    <p>A Mnesia table may reside on one or more nodes. When a table is
      updated, Mnesia will ensure that the updates will be replicated
      to all nodes where the table resides.  If a replica happens to be
      inaccessible for some reason (e.g. due to a temporary node down),
      Mnesia will then perform the  replication  later.
      </p>
    <p>On the node where the application is started, there will be a
      transaction coordinator process. If the transaction is
      distributed, there will also be a transaction participant process on
      all the other nodes where commit work needs to be performed.
      </p>
    <p>Internally Mnesia uses several commit protocols. The selected 
      protocol depends on which table that has been updated in
      the transaction. If all the involved tables are symmetrically
      replicated, (i.e. they all have the same <span class="code">ram_nodes</span>,
      <span class="code">disc_nodes</span> and <span class="code">disc_only_nodes</span> currently
      accessible from the coordinator node), a lightweight transaction
      commit protocol is used.
      </p>
    <p>The number of messages that the
      transaction coordinator and its participants needs to exchange
      is few, since Mnesia's table load mechanism takes care of the
      transaction recovery if the commit protocol gets
      interrupted. Since all involved tables are replicated
      symmetrically the transaction will automatically be recovered by
      loading the involved tables from the same node at start-up of a
      failing node. We do not really care if the transaction was
      aborted or committed as long as we can ensure the ACID
      properties. The lightweight commit protocol is non-blocking,
      i.e. the surviving participants and their coordinator will
      finish the transaction, regardless of some node crashes in the
      middle of the commit protocol or not.
      </p>
    <p>If a node goes down in the middle of a dirty operation the
      table load mechanism will ensure that the update will be
      performed on all replicas or none. Both asynchronous dirty
      updates and synchronous dirty updates use the same recovery
      principle as lightweight transactions.
      </p>
    <p>If a transaction involves updates of asymmetrically replicated
      tables or updates of the schema table, a heavyweight commit
      protocol will be used. The heavyweight commit protocol is able
      to finish the transaction regardless of how the tables are
      replicated. The typical usage of a heavyweight transaction is
      when we want to move a replica from one node to another. Then we
      must ensure that the replica either is entirely moved or left as
      it was. We must never end up in a situation with replicas on both
      nodes or no node at all. Even if a node crashes in the middle of
      the commit protocol, the transaction must be guaranteed to be
      atomic. The heavyweight commit protocol involves more messages
      between the transaction coordinator and its participants than
      a lightweight protocol and it will perform recovery work at
      start-up in order to finish the abort or commit work.
      </p>
    <p>The heavyweight commit protocol is also non-blocking,
      which allows the surviving participants and their coordinator to
      finish the transaction regardless (even if a node crashes in the
      middle of the commit protocol). When a node fails at start-up, 
      Mnesia will determine the outcome of the transaction and
      recover it. Lightweight protocols,  heavyweight protocols and dirty updates, are 
      dependent on other nodes to be up and running in order to make the
      correct heavyweight transaction recovery decision.
      </p>
    <p>If Mnesia has not started on some of the nodes that are involved in the
      transaction AND neither the local node or any of the already
      running nodes know the outcome of the transaction, Mnesia will
      by default wait for one.  In the worst case scenario all  other
      involved nodes must start before Mnesia can make the correct decision
      about the transaction and finish its start-up. 
      </p>
    <p>This means that Mnesia (on one node)may hang  if a double fault occurs, i.e. when two nodes crash simultaneously
      and one attempts to start when the other  refuses to
      start e.g. due to a hardware error.
      </p>
    <p>It is possible to specify the maximum time that Mnesia
      will wait for  other nodes to respond with a transaction
      recovery decision. The configuration parameter
      <span class="code">max_wait_for_decision</span> defaults to infinity (which may
      cause the indefinite hanging as mentioned above) but if it is
      set to a definite time period (eg.three minutes), Mnesia will then enforce a
      transaction recovery decision if needed, in order to allow
      Mnesia to continue with its start-up procedure. </p>
    <p>The downside of an enforced transaction recovery decision, is that the decision may be
      incorrect, due to insufficient information regarding the other nodes'
      recovery decisions. This may result in an
      inconsistent database where Mnesia has committed the transaction
      on some nodes but aborted it on others. </p>
    <p>In fortunate cases the inconsistency will only appear in tables belonging to a specific
      application, but if a schema transaction has been inconsistently
      recovered due to the enforced transaction recovery decision, the
      effects of the inconsistency can be fatal. 
      However, if the higher priority is availability rather than
      consistency, then it may be worth the risk. </p>
    <p>If Mnesia
      encounters a inconsistent transaction decision a
      <span class="code">{inconsistent_database, bad_decision, Node}</span> system event
      will be generated in order to give the application a chance to
      install a fallback or other appropriate measures to resolve the inconsistency. The default
      behavior of the Mnesia event handler is the same as if the
      database became inconsistent as a result of partitioned network (see
      above).
      </p>
  

  <h3><a name="id78876">6.9 
        Backup, Fallback, and Disaster Recovery</a></h3>
    
    <p>The following functions are used to backup data, to install a
      backup as fallback, and for disaster recovery.
      </p>
    <ul>
      <li>
<span class="code">mnesia:backup_checkpoint(Name, Opaque, [Mod])</span>. This
       function performs a backup of the tables included in the
       checkpoint.
      </li>
      <li>
<span class="code">mnesia:backup(Opaque, [Mod])</span>. This function
       activates a new checkpoint which covers all Mnesia tables and
       performs a backup. It is performed with maximum degree of
       redundancy (also refer to the function <span class="bold_code"><a href="#checkpoints">mnesia:activate_checkpoint(Args)</a></span>,
      <span class="code">{max, MaxTabs} and {min, MinTabs}).</span>
</li>
      <li>
<span class="code">mnesia:traverse_backup(Source,[SourceMod,]</span><span class="code">Target,[TargetMod,]Fun,Ac)</span>. This function can be used
       to read an existing backup, create a new backup from an
       existing one, or to copy a backup from one type media to
       another.
      </li>
      <li>
<span class="code">mnesia:uninstall_fallback()</span>. This function removes
       previously installed fallback files.
      </li>
      <li>
<span class="code">mnesia:restore(Opaque, Args)</span>. This function
       restores a set of tables from a previous backup.
      </li>
      <li>
<span class="code">mnesia:install_fallback(Opaque, [Mod])</span>. This
       function can be configured to restart the Mnesia and reload data
       tables, and possibly schema tables, from an existing
       backup. This function is typically used for disaster recovery
       purposes, when data or schema tables are corrupted.</li>
    </ul>
    <p>These functions are explained in the following
      sub-sections. Also refer to the the section <span class="bold_code"><a href="#checkpoints">Checkpoints</a></span> in this chapter, which
      describes the two functions used to activate and de-activate
      checkpoints.
      </p>

    <h4>Backup</h4>
      
      <p>Backup operation are performed with the following functions:
        </p>
      <ul>
        <li><span class="code">mnesia:backup_checkpoint(Name, Opaque, [Mod])</span></li>
        <li><span class="code">mnesia:backup(Opaque, [Mod])</span></li>
        <li>
<span class="code">mnesia:traverse_backup(Source, [SourceMod,],</span><span class="code">Target,[TargetMod,]Fun,Acc)</span>.</li>
      </ul>
      <p>By default, the actual access to the backup media is
        performed via the <span class="code">mnesia_backup</span> module for both read
        and write. Currently <span class="code">mnesia_backup</span> is implemented with
        the standard library module <span class="code">disc_log</span>, but it is possible to write
        your own module with the same interface as
        <span class="code">mnesia_backup</span> and configure Mnesia so the alternate
        module performs the actual accesses to the backup media. This
        means that the user may put the backup on medias that Mnesia
        does not know about, possibly on hosts where Erlang is not
        running. Use the configuration parameter <span class="code">-mnesia backup_module &lt;module&gt;</span> for this purpose.  </p>
      <p>The source
        for a backup is an activated checkpoint. The backup function
        most commonly used is <span class="code">mnesia:backup_checkpoint(Name, Opaque,[Mod])</span>.  This function returns either <span class="code">ok</span>, or
        <span class="code">{error,Reason}</span>. It has the following arguments:
        </p>
      <ul>
        <li>
<span class="code">Name</span> is the name of an activated
         checkpoint. Refer to the section <span class="bold_code"><a href="#checkpoints">Checkpoints</a></span> in this chapter, the
         function <span class="code">mnesia:activate_checkpoint(ArgList)</span> for
         details on how to include table names in checkpoints.
        </li>
        <li>
<span class="code">Opaque</span>. Mnesia does not interpret this argument,
         but it is forwarded to the backup module. The Mnesia default
         backup module, <span class="code">mnesia_backup</span> interprets this argument
         as a local file name.
        </li>
        <li>
<span class="code">Mod</span>. The name of an alternate backup module. 
        </li>
      </ul>
      <p>The function <span class="code">mnesia:backup(Opaque[, Mod])</span> activates a
        new checkpoint which covers all Mnesia tables with maximum
        degree of redundancy and  performs a backup. Maximum
        redundancy means that each table replica has a checkpoint
        retainer. Tables with the <span class="code">local_contents</span> property are
        backed up as they
        look on the current node.
        </p>
      <p>It is possible to iterate over a backup, either for the
        purpose of transforming it into a new backup, or just reading
        it. The function <span class="code">mnesia:traverse_backup(Source, [SourceMod,]</span><span class="code">Target, [TargeMod,] Fun, Acc)</span> which normally returns <span class="code">{ok, LastAcc}</span>, is used for both of these purposes.   
        </p>
      <p>Before the traversal starts, the source backup media is
        opened with <span class="code">SourceMod:open_read(Source)</span>, and the target
        backup media is opened with
        <span class="code">TargetMod:open_write(Target)</span>. The arguments are: 
        </p>
      <ul>
        <li>
<span class="code">SourceMod</span> and <span class="code">TargetMod</span> are module names.
        </li>
        <li>
<span class="code">Source</span> and <span class="code">Target</span> are opaque data used
         exclusively by the modules <span class="code">SourceMod</span> and
        <span class="code">TargetMod</span> for the purpose of initializing the backup
         medias.
        </li>
        <li>
<span class="code">Acc</span> is an initial accumulator value.
        </li>
        <li>
<span class="code">Fun(BackupItems, Acc)</span> is applied to each item in
         the backup. The Fun must return a tuple <span class="code">{ValGoodBackupItems, NewAcc}</span>, where <span class="code">ValidBackupItems</span> is a list of valid
         backup items, and <span class="code">NewAcc</span> is a new accumulator value.
         The <span class="code">ValidBackupItems</span> are written to the target backup
         with the function <span class="code">TargetMod:write/2</span>.
        </li>
        <li>
<span class="code">LastAcc</span> is the last accumulator value. I.e.
         the last <span class="code">NewAcc</span> value that was returned by <span class="code">Fun</span>.
        </li>
      </ul>
      <p>It is also possible to perform a read-only traversal of the
        source backup without updating a target backup. If
        <span class="code">TargetMod==read_only</span>, then no target backup is accessed
        at all.
        </p>
      <p>By setting <span class="code">SourceMod</span> and <span class="code">TargetMod</span> to different
        modules it is possible to copy a backup from one kind of backup
        media to another.
        </p>
      <p>Valid <span class="code">BackupItems</span> are the following tuples:
        </p>
      <ul>
        <li>
<span class="code">{schema, Tab}</span> specifies a table to be deleted.
        </li>
        <li>
<span class="code">{schema, Tab, CreateList}</span> specifies a table to be
         created. See <span class="code">mnesia_create_table/2</span> for more
         information about <span class="code">CreateList</span>.
        </li>
        <li>
<span class="code">{Tab, Key}</span> specifies the full identity of a record
         to be deleted. 
        </li>
        <li>
<span class="code">{Record}</span> specifies a record to be inserted. It
         can be a tuple with <span class="code">Tab</span> as first field. Note that the
         record name is set to the table name regardless of what
        <span class="code">record_name</span> is set to.
        </li>
      </ul>
      <p>The backup data is divided into two sections. The first
        section contains information related to the schema. All schema
        related items are tuples where the first field equals the atom
        schema. The second section is the record section. It is not
        possible to mix schema records with other records and all schema
        records must be located first in the backup.
        </p>
      <p>The schema itself is a table and will possibly be included in
        the backup. All nodes where the schema table resides are
        regarded as a <span class="code">db_node</span>.
        </p>
      <p>The following example illustrates how
        <span class="code">mnesia:traverse_backup</span> can be used to rename a db_node in
        a backup file:
        </p>
<div class="example"><pre>

change_node_name(Mod, From, To, Source, Target) -&gt;
    Switch =
        fun(Node) when Node == From -&gt; To;
           (Node) when Node == To -&gt; throw({error, already_exists});
           (Node) -&gt; Node
        end,
    Convert =
        fun({schema, db_nodes, Nodes}, Acc) -&gt;
                {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc};
           ({schema, version, Version}, Acc) -&gt;
                {[{schema, version, Version}], Acc};
           ({schema, cookie, Cookie}, Acc) -&gt;
                {[{schema, cookie, Cookie}], Acc};
           ({schema, Tab, CreateList}, Acc) -&gt;
                Keys = [ram_copies, disc_copies, disc_only_copies],
                OptSwitch =
                    fun({Key, Val}) -&gt;
                            case lists:member(Key, Keys) of
                                true -&gt; {Key, lists:map(Switch, Val)};
                                false-&gt; {Key, Val}
                            end
                    end,
                {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc};
           (Other, Acc) -&gt;
                {[Other], Acc}
        end,
    mnesia:traverse_backup(Source, Mod, Target, Mod, Convert, switched).

view(Source, Mod) -&gt;
    View = fun(Item, Acc) -&gt;
                   io:format("~p.~n",[Item]),
                   {[Item], Acc + 1}
           end,
    mnesia:traverse_backup(Source, Mod, dummy, read_only, View, 0).</pre></div>    

    <h4>Restore</h4>
      
      <p>Tables can be restored on-line from a backup without
        restarting Mnesia. A restore is performed with the function
        <span class="code">mnesia:restore(Opaque,Args)</span>,  where <span class="code">Args</span> can
        contain  the following tuples: 
        </p>
      <ul>
        <li>
<span class="code">{module,Mod}</span>. The backup module <span class="code">Mod</span> is
         used to access the backup media. If omitted, the default
         backup module will be used.</li>
        <li>
<span class="code">{skip_tables, TableList}</span> Where <span class="code">TableList</span>
         is a list of tables which should not be read from the backup.</li>
        <li>
<span class="code">{clear_tables, TableList}</span> Where <span class="code">TableList</span>
         is a list of tables which should be cleared, before the
         records from the backup are inserted, i.e. all records in
         the tables are deleted before the tables are restored.
         Schema information about the tables is not cleared or read
         from backup.</li>
        <li>
<span class="code">{keep_tables, TableList}</span> Where <span class="code">TableList</span>
         is a list of tables which should be not be cleared, before
         the  records from the backup are inserted, i.e. the records
         in the backup will be added to the records in the table.
         Schema information about the tables is not cleared or read
         from backup.</li>
        <li>
<span class="code">{recreate_tables, TableList}</span> Where <span class="code">TableList</span>
         is a list of tables which should be re-created, before the
         records from the backup are inserted. The tables are first 
         deleted and then created with the schema information from the 
         backup. All the nodes in the backup needs to be up and running.</li>
        <li>
<span class="code">{default_op, Operation}</span> Where <span class="code">Operation</span> is
         one of the following operations <span class="code">skip_tables</span>, 
        <span class="code">clear_tables</span>, <span class="code">keep_tables</span> or
        <span class="code">recreate_tables</span>. The default operation specifies
         which operation should be used on tables from the backup
         which are not specified in any of the lists above.
         If omitted, the operation <span class="code">clear_tables</span> will be used.     </li>
      </ul>
      <p>The argument <span class="code">Opaque</span> is forwarded to the backup module.
        It returns <span class="code">{atomic, TabList}</span> if successful, or the
        tuple <span class="code">{aborted, Reason}</span> in the case of an error.
        <span class="code">TabList</span> is a list of the restored tables. Tables which
        are restored are write locked for the duration of the restore
        operation. However, regardless of any  lock conflict caused by
        this, applications can continue to do their work during the
        restore operation.
        </p>
      <p>The restoration is performed as a single transaction. If the
        database is very large, it may not be possible to restore it
        online. In such a case the old database must be restored by
        installing a fallback, and then restart.
        </p>
    

    <h4>Fallbacks</h4>
      
      <p>The function <span class="code">mnesia:install_fallback(Opaque, [Mod])</span> is
        used to install a backup as fallback. It uses the backup module
        <span class="code">Mod</span>, or the default backup module, to access the backup
        media. This function returns <span class="code">ok</span> if successful, or
        <span class="code">{error, Reason}</span> in the case of an error.
        </p>
      <p>Installing a fallback is a distributed operation that is
        <strong>only</strong> performed on all <span class="code">db_nodes</span>. The fallback
        is used to restore the database the next time the system is
        started. If a Mnesia node with a fallback installed detects that
        Mnesia on another node has died for some reason, it will
        unconditionally terminate itself.
        </p>
      <p>A fallback is typically used when a system upgrade is
        performed. A system typically involves the installation of new
        software versions, and Mnesia tables are often transformed into
        new layouts.  If the system crashes during an upgrade, it is
        highly probable re-installation  of  the old
        applications will be required and restoration of the database
        to its previous state. This can be done if a backup is performed and
        installed as a fallback before the system upgrade begins.
        </p>
      <p>If the system upgrade fails, Mnesia must be restarted on all
        <span class="code">db_nodes</span> in order to restore the old database. The
        fallback will be automatically de-installed after a successful
        start-up. The function <span class="code">mnesia:uninstall_fallback()</span> may
        also be used to de-install the fallback after a
        successful system upgrade. Again, this is a distributed
        operation that is either performed on all <span class="code">db_nodes</span>, or
        none. Both the installation and de-installation of fallbacks
        require Erlang to be up and running on all <span class="code">db_nodes</span>, but
        it does not matter if Mnesia is running or not.
        </p>
    

    <h4>Disaster Recovery</h4>
      
      <p>The system may become inconsistent as a result of a power
        failure. The UNIX <span class="code">fsck</span> feature can possibly repair the
        file system, but there is no guarantee that the file contents
        will be consistent.
        </p>
      <p>If Mnesia detects that a file has not been properly closed,
        possibly as a result of a power failure, it will attempt to
        repair the bad file in a similar manner. Data may be lost, but
        Mnesia can be restarted even if the data is inconsistent. The
        configuration parameter <span class="code">-mnesia auto_repair &lt;bool&gt;</span> can be
        used to control the behavior of Mnesia at start-up. If
        <span class="code">&lt;bool&gt;</span> has the value <span class="code">true</span>, Mnesia will attempt to
        repair the file; if <span class="code">&lt;bool&gt;</span> has the value <span class="code">false</span>,
        Mnesia will not restart if it detects a suspect file. This
        configuration parameter affects the repair behavior of log
        files, DAT files, and the default backup media.
        </p>
      <p>The configuration parameter <span class="code">-mnesia dump_log_update_in_place &lt;bool&gt;</span> controls the safety level of
        the <span class="code">mnesia:dump_log()</span> function. By default, Mnesia will
        dump the transaction log directly into the DAT files. If a power
        failure happens during the dump, this may cause the randomly
        accessed DAT files to become corrupt. If the parameter is set to
        <span class="code">false</span>, Mnesia will copy the DAT files and target the dump
        to the new temporary files. If the dump is successful, the
        temporary files will be renamed to their normal DAT
        suffixes. The possibility for unrecoverable inconsistencies in
        the data files will be much smaller with this strategy. On the
        other hand, the actual dumping of the transaction log will be
        considerably slower. The system designer must decide whether
        speed or safety is the higher priority.
        </p>
      <p>Replicas of type <span class="code">disc_only_copies</span> will only be
        affected by this parameter during the initial dump of the log
        file at start-up. When designing applications which have
        <strong>very</strong> high requirements, it may be appropriate not to
        use <span class="code">disc_only_copies</span> tables at all. The reason for this
        is the random access nature of normal operating system files. If
        a node goes down for reason for a reason such as a power
        failure, these files may be corrupted because they are not
        properly closed. The DAT files for <span class="code">disc_only_copies</span> are
        updated on a per transaction basis.
        </p>
      <p>If a disaster occurs and the Mnesia database has been
        corrupted, it can be reconstructed from a backup. This should be
        regarded as a last resort, since the backup contains old data. The
        data is hopefully consistent, but data will definitely be lost
        when an old backup is used to restore the database.
        </p>
    
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>