pg_combinebackup: Detect checksum mismatches and document limitation.
authorRobert Haas <[email protected]>
Thu, 25 Apr 2024 18:58:59 +0000 (14:58 -0400)
committerRobert Haas <[email protected]>
Thu, 25 Apr 2024 18:58:59 +0000 (14:58 -0400)
If not all backups have the same checksum status, but the final backup
has checksums enabled, then the output directory may include pages
with invalid checksums. Document this limitation and explain how to
work around it.

In a future release, we may want to teach pg_combinebackup to
recompute page checksums when required, but as feature freeze has come
and gone, it seems a bit too late to do that for this release.

Patch by me, reviewed by Daniel Gustafsson

Discussion: http://postgr.es/m/CA+TgmoZugzOSmgkx97u3pc0M7U8LycWvugqoyWBv6j15a4hE5g@mail.gmail.com

doc/src/sgml/backup.sgml
doc/src/sgml/ref/pg_combinebackup.sgml
src/bin/pg_combinebackup/pg_combinebackup.c

index b3468eea3cb999f8121e89379fb71de69c41273b..91da3c26ba03ed67362098c852d91ffdc42c87a0 100644 (file)
@@ -892,7 +892,11 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 &amp;&amp; cp pg_wal/0
     only the incremental backup itself but also all earlier backups that
     are required to supply the blocks omitted from the incremental backup.
     See <xref linkend="app-pgcombinebackup"/> for further information about
-    this requirement.
+    this requirement. Note that there are restrictions on the use of
+    <literal>pg_combinebackup</literal> when the checksum status of the
+    cluster has been changed; see
+    <link linkend="app-pgcombinebackup-limitations">pg_combinebackup
+    limitations</link>.
    </para>
 
    <para>
index 96df3d81f15a0180e7b8f2ff0bc8fa34571ca882..d1f70ba23583a570b81a3662b9c6a4534808ec22 100644 (file)
@@ -261,6 +261,26 @@ PostgreSQL documentation
 
  </refsect1>
 
+ <refsect1 id="app-pgcombinebackup-limitations">
+  <title>Limitations</title>
+
+  <para>
+   <literal>pg_combinebackup</literal> does not recompute page checksums when
+   writing the output directory. Therefore, if any of the backups used for
+   reconstruction were taken with checksums disabled, but the final backup was
+   taken with checksums enabled, the resulting directory may contain pages
+   with invalid checksums.
+  </para>
+
+  <para>
+   To avoid this problem, taking a new full backup after changing the checksum
+   state of the cluster using <xref linkend="app-pgchecksums "/> is
+   recommended. Otherwise, you can disable and then optionally reenable
+   checksums on the directory produced by <literal>pg_combinebackup</literal>
+   in order to correct the problem.
+  </para>
+ </refsect1>
+
  <refsect1>
   <title>Environment</title>
 
index 4958372653be1aef18fd85c34fa03bd00773fdae..232ba5b06977a54b67ea5e5c7b1f08b039fb7f49 100644 (file)
@@ -583,6 +583,8 @@ check_control_files(int n_backups, char **backup_dirs)
 {
    int         i;
    uint64      system_identifier = 0;  /* placate compiler */
+   uint32      data_checksum_version = 0;  /* placate compiler */
+   bool        data_checksum_mismatch = false;
 
    /* Try to read each control file in turn, last to first. */
    for (i = n_backups - 1; i >= 0; --i)
@@ -612,6 +614,16 @@ check_control_files(int n_backups, char **backup_dirs)
                     controlpath, (unsigned long long) system_identifier,
                     (unsigned long long) control_file->system_identifier);
 
+       /*
+        * Detect checksum mismatches, but only if the last backup in the
+        * chain has checksums enabled.
+        */
+       if (i == n_backups - 1)
+           data_checksum_version = control_file->data_checksum_version;
+       else if (data_checksum_version != 0 &&
+                data_checksum_version != control_file->data_checksum_version)
+           data_checksum_mismatch = true;
+
        /* Release memory. */
        pfree(control_file);
        pfree(controlpath);
@@ -624,6 +636,16 @@ check_control_files(int n_backups, char **backup_dirs)
    pg_log_debug("system identifier is %llu",
                 (unsigned long long) system_identifier);
 
+   /*
+    * Warn the user if not all backups are in the same state with regards to
+    * checksums.
+    */
+   if (data_checksum_mismatch)
+   {
+       pg_log_warning("only some backups have checksums enabled");
+       pg_log_warning_hint("disable, and optionally reenable, checksums on the output directory to avoid failures");
+   }
+
    return system_identifier;
 }