1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

Allow on-line enabling and disabling of data checksums

This makes it possible to turn checksums on in a live cluster, without
the previous need for dump/reload or logical replication (and to turn it
off).

Enabling checkusm starts a background process in the form of a
launcher/worker combination that goes through the entire database and
recalculates checksums on each and every page. Only when all pages have
been checksummed are they fully enabled in the cluster. Any failure of
the process will revert to checksums off and the process has to be
started.

This adds a new WAL record that indicates the state of checksums, so
the process works across replicated clusters.

Authors: Magnus Hagander and Daniel Gustafsson
Review: Tomas Vondra, Michael Banck, Heikki Linnakangas, Andrey Borodin
This commit is contained in:
Magnus Hagander
2018-04-05 21:57:26 +02:00
parent c39e903d51
commit 1fde38beaa
45 changed files with 2118 additions and 34 deletions

View File

@ -19540,6 +19540,71 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
</sect2>
<sect2 id="functions-admin-checksum">
<title>Data Checksum Functions</title>
<para>
The functions shown in <xref linkend="functions-checksums-table" /> can
be used to enable or disable data checksums in a running cluster.
See <xref linkend="checksums" /> for details.
</para>
<table id="functions-checksums-table">
<title>Checksum <acronym>SQL</acronym> Functions</title>
<tgroup cols="3">
<thead>
<row>
<entry>Function</entry>
<entry>Return Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<indexterm>
<primary>pg_enable_data_checksums</primary>
</indexterm>
<literal><function>pg_enable_data_checksums(<optional><parameter>cost_delay</parameter> <type>int</type>, <parameter>cost_limit</parameter> <type>int</type></optional>)</function></literal>
</entry>
<entry>
void
</entry>
<entry>
<para>
Initiates data checksums for the cluster. This will switch the data checksums mode
to <literal>in progress</literal> and start a background worker that will process
all data in the database and enable checksums for it. When all data pages have had
checksums enabled, the cluster will automatically switch to checksums
<literal>on</literal>.
</para>
<para>
If <parameter>cost_delay</parameter> and <parameter>cost_limit</parameter> are
specified, the speed of the process is throttled using the same principles as
<link linkend="runtime-config-resource-vacuum-cost">Cost-based Vacuum Delay</link>.
</para>
</entry>
</row>
<row>
<entry>
<indexterm>
<primary>pg_disable_data_checksums</primary>
</indexterm>
<literal><function>pg_disable_data_checksums()</function></literal>
</entry>
<entry>
void
</entry>
<entry>
Disables data checksums for the cluster.
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
<sect2 id="functions-admin-dbobject">
<title>Database Object Management Functions</title>

View File

@ -211,6 +211,7 @@ Complete list of usable sgml source files in this directory.
<!ENTITY pgResetwal SYSTEM "pg_resetwal.sgml">
<!ENTITY pgRestore SYSTEM "pg_restore.sgml">
<!ENTITY pgRewind SYSTEM "pg_rewind.sgml">
<!ENTITY pgVerifyChecksums SYSTEM "pg_verify_checksums.sgml">
<!ENTITY pgtestfsync SYSTEM "pgtestfsync.sgml">
<!ENTITY pgtesttiming SYSTEM "pgtesttiming.sgml">
<!ENTITY pgupgrade SYSTEM "pgupgrade.sgml">

View File

@ -195,9 +195,9 @@ PostgreSQL documentation
<para>
Use checksums on data pages to help detect corruption by the
I/O system that would otherwise be silent. Enabling checksums
may incur a noticeable performance penalty. This option can only
be set during initialization, and cannot be changed later. If
set, checksums are calculated for all objects, in all databases.
may incur a noticeable performance penalty. If set, checksums
are calculated for all objects, in all databases. See
<xref linkend="checksums" /> for details.
</para>
</listitem>
</varlistentry>

View File

@ -0,0 +1,112 @@
<!--
doc/src/sgml/ref/pg_verify_checksums.sgml
PostgreSQL documentation
-->
<refentry id="pgverifychecksums">
<indexterm zone="pgverifychecksums">
<primary>pg_verify_checksums</primary>
</indexterm>
<refmeta>
<refentrytitle><application>pg_verify_checksums</application></refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo>Application</refmiscinfo>
</refmeta>
<refnamediv>
<refname>pg_verify_checksums</refname>
<refpurpose>verify data checksums in an offline <productname>PostgreSQL</productname> database cluster</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>pg_verify_checksums</command>
<arg choice="opt"><replaceable class="parameter">option</replaceable></arg>
<arg choice="opt"><arg choice="opt"><option>-D</option></arg> <replaceable class="parameter">datadir</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id="r1-app-pg_verify_checksums-1">
<title>Description</title>
<para>
<command>pg_verify_checksums</command> verifies data checksums in a PostgreSQL
cluster. It must be run against a cluster that's offline.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<para>
The following command-line options are available:
<variablelist>
<varlistentry>
<term><option>-r <replaceable>relfilenode</replaceable></option></term>
<listitem>
<para>
Only validate checksums in the relation with specified relfilenode.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-f</option></term>
<listitem>
<para>
Force check even if checksums are disabled on cluster.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-d</option></term>
<listitem>
<para>
Enable debug output. Lists all checked blocks and their checksum.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-V</option></term>
<term><option>--version</option></term>
<listitem>
<para>
Print the <application>pg_verify_checksums</application> version and exit.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-?</option></term>
<term><option>--help</option></term>
<listitem>
<para>
Show help about <application>pg_verify_checksums</application> command line
arguments, and exit.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
Can only be run when the server is offline.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="checksums"/></member>
</simplelist>
</refsect1>
</refentry>

View File

@ -284,6 +284,7 @@
&pgtestfsync;
&pgtesttiming;
&pgupgrade;
&pgVerifyChecksums;
&pgwaldump;
&postgres;
&postmaster;

View File

@ -230,6 +230,87 @@
</para>
</sect1>
<sect1 id="checksums">
<title>Data checksums</title>
<indexterm>
<primary>checksums</primary>
</indexterm>
<para>
Data pages are not checksum protected by default, but this can optionally be enabled for a cluster.
When enabled, each data page will be assigned a checksum that is updated when the page is
written and verified every time the page is read. Only data pages are protected by checksums,
internal data structures and temporary files are not.
</para>
<para>
Checksums are normally enabled when the cluster is initialized using
<link linkend="app-initdb-data-checksums"><application>initdb</application></link>. They
can also be enabled or disabled at runtime. In all cases, checksums are enabled or disabled
at the full cluster level, and cannot be specified individually for databases or tables.
</para>
<para>
The current state of checksums in the cluster can be verified by viewing the value
of the read-only configuration variable <xref linkend="guc-data-checksums" /> by
issuing the command <command>SHOW data_checksums</command>.
</para>
<para>
When attempting to recover from corrupt data it may be necessary to bypass the checksum
protection in order to recover data. To do this, temporarily set the configuration parameter
<xref linkend="guc-ignore-checksum-failure" />.
</para>
<sect2 id="checksums-enable-disable">
<title>On-line enabling of checksums</title>
<para>
Checksums can be enabled or disabled online, by calling the appropriate
<link linkend="functions-admin-checksum">functions</link>.
Disabling of checksums takes effect immediately when the function is called.
</para>
<para>
Enabling checksums will put the cluster in <literal>inprogress</literal> mode.
During this time, checksums will be written but not verified. In addition to
this, a background worker process is started that enables checksums on all
existing data in the cluster. Once this worker has completed processing all
databases in the cluster, the checksum mode will automatically switch to
<literal>on</literal>.
</para>
<para>
The process will initially wait for all open transactions to finish before
it starts, so that it can be certain that there are no tables that have been
created inside a transaction that has not committed yet and thus would not
be visible to the process enabling checksums. It will also, for each database,
wait for all pre-existing temporary tables to get removed before it finishes.
If long-lived temporary tables are used in the application it may be necessary
to terminate these application connections to allow the process to complete.
Information about open transactions and connections with temporary tables is
written to log.
</para>
<para>
If the cluster is stopped while in <literal>inprogress</literal> mode, for
any reason, then this process must be restarted manually. To do this,
re-execute the function <function>pg_enable_data_checksums()</function>
once the cluster has been restarted. It is not possible to resume the work,
the process has to start over and re-process the cluster.
</para>
<note>
<para>
Enabling checksums can cause significant I/O to the system, as most of the
database pages will need to be rewritten, and will be written both to the
data files and the WAL.
</para>
</note>
</sect2>
</sect1>
<sect1 id="wal-intro">
<title>Write-Ahead Logging (<acronym>WAL</acronym>)</title>