so you still have the unmodified files if a
problem occurs and you have to start over.)
</para>
</listitem>
<listitem>
<para>
Set recovery configuration settings in
<filename>postgresql.conf</filename> (see <xref
linkend="runtime-config-wal-archive-recovery"/>) and create a file
<filename>recovery.signal</filename> in the cluster
data directory. You might
also want to temporarily modify <filename>pg_hba.conf</filename> to prevent
ordinary users from connecting until you are sure the recovery was successful.
</para>
</listitem>
<listitem>
<para>
Start the server. The server will go into recovery mode and
proceed to read through the archived WAL files it needs. Should the
recovery be terminated because of an external error, the server can
simply be restarted and it will continue recovery. Upon completion
of the recovery process, the server will remove
<filename>recovery.signal</filename> (to prevent
accidentally re-entering recovery mode later) and then
commence normal database operations.
</para>
</listitem>
<listitem>
<para>
Inspect the contents of the database to ensure you have recovered to
the desired state. If not, return to step 1. If all is well,
allow your users to connect by restoring <filename>pg_hba.conf</filename> to normal.
</para>
</listitem>
</orderedlist>
</para>
<para>
The key part of all this is to set up a recovery configuration that
describes how you want to recover and how far the recovery should
run. The one thing that you absolutely must specify is the <varname>restore_command</varname>,
which tells <productname>PostgreSQL</productname> how to retrieve archived
WAL file segments. Like the <varname>archive_command</varname>, this is
a shell command string. It can contain <literal>%f</literal>, which is
replaced by the name of the desired WAL file, and <literal>%p</literal>,
which is replaced by the path name to copy the WAL file to.
(The path name is relative to the current working directory,
i.e., the cluster's data directory.)
Write <literal>%%</literal> if you need to embed an actual <literal>%</literal>
character in the command. The simplest useful command is
something like:
<programlisting>
restore_command = 'cp /mnt/server/archivedir/%f %p'
</programlisting>
which will copy previously archived WAL segments from the directory
<filename>/mnt/server/archivedir</filename>. Of course, you can use something
much more complicated, perhaps even a shell script that requests the
operator to mount an appropriate tape.
</para>
<para>
It is important that the command return nonzero exit status on failure.
The command <emphasis>will</emphasis> be called requesting files that are not
present in the archive; it must return nonzero when so asked. This is not
an error condition. An exception is that if the command was terminated by
a signal (other than <systemitem>SIGTERM</systemitem>, which is used as
part of a database server shutdown) or an error by the shell (such as
command not found), then recovery will abort and the server will not start
up.
</para>
<para>
Not all of the requested files will be WAL segment
files; you should also expect requests for files with a suffix of
<literal>.history</literal>. Also be aware that
the base name of the <literal>%p</literal> path will be different from
<literal>%f</literal>; do not expect them to be interchangeable.
</para>
<para>
WAL segments that cannot be found in the archive will be sought in
<filename>pg_wal/</filename>; this allows use of recent un-archived segments.
However, segments that are available from the archive will be used in
preference to files in <filename>pg_wal/</filename>.
</para>
<para>
Normally, recovery will proceed through all