<productname>PostgreSQL</productname> tries not to make any assumptions about how
the archiving will be done. Instead, <productname>PostgreSQL</productname> lets
the administrator specify a shell command or an archive library to be executed to copy a
completed segment file to wherever it needs to go. This could be as simple
as a shell command that uses <literal>cp</literal>, or it could invoke a
complex C function — it's all up to you.
</para>
<para>
To enable WAL archiving, set the <xref linkend="guc-wal-level"/>
configuration parameter to <literal>replica</literal> or higher,
<xref linkend="guc-archive-mode"/> to <literal>on</literal>,
specify the shell command to use in the <xref
linkend="guc-archive-command"/> configuration parameter
or specify the library to use in the <xref
linkend="guc-archive-library"/> configuration parameter. In practice
these settings will always be placed in the
<filename>postgresql.conf</filename> file.
</para>
<para>
In <varname>archive_command</varname>,
<literal>%p</literal> is replaced by the path name of the file to
archive, while <literal>%f</literal> is replaced by only the file name.
(The path name is relative to the current working directory,
i.e., the cluster's data directory.)
Use <literal>%%</literal> if you need to embed an actual <literal>%</literal>
character in the command. The simplest useful command is something
like:
<programlisting>
archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' # Unix
archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows
</programlisting>
which will copy archivable WAL segments to the directory
<filename>/mnt/server/archivedir</filename>. (This is an example, not a
recommendation, and might not work on all platforms.) After the
<literal>%p</literal> and <literal>%f</literal> parameters have been replaced,
the actual command executed might look like this:
<programlisting>
test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065
</programlisting>
A similar command will be generated for each new file to be archived.
</para>
<para>
The archive command will be executed under the ownership of the same
user that the <productname>PostgreSQL</productname> server is running as. Since
the series of WAL files being archived contains effectively everything
in your database, you will want to be sure that the archived data is
protected from prying eyes; for example, archive into a directory that
does not have group or world read access.
</para>
<para>
It is important that the archive command return zero exit status if and
only if it succeeds. Upon getting a zero result,
<productname>PostgreSQL</productname> will assume that the file has been
successfully archived, and will remove or recycle it. However, a nonzero
status tells <productname>PostgreSQL</productname> that the file was not archived;
it will try again periodically until it succeeds.
</para>
<para>
Another way to archive is to use a custom archive module as the
<varname>archive_library</varname>. Since such modules are written in
<literal>C</literal>, creating your own may require considerably more effort
than writing a shell command. However, archive modules can be more
performant than archiving via shell, and they will have access to many
useful server resources. For more information about archive modules, see
<xref linkend="archive-modules"/>.
</para>
<para>
When the archive command is terminated by a signal (other than
<systemitem>SIGTERM</systemitem> that is used as part of a server
shutdown) or an error by the shell with an exit status greater than
125 (such as command not found), or if the