mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Update point-in-time recovery documentation for PostgreSQL >= 13.
PITR changed in PostgreSQL 13 to error when the recovery target is not reached. Update the documentation to work with PostgreSQL >= 13 as well as < 13. Also update the versions built for RHEL and Debian since PostgreSQL 11 is now EOL.
This commit is contained in:
parent
dcf0781987
commit
eb69e2ee63
@ -48,6 +48,14 @@
|
||||
|
||||
<p>Document maintainer options.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-contributor id="david.steele"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Update point-in-time recovery documentation for <postgres/> >= 13.</p>
|
||||
</release-item>
|
||||
</release-feature-list>
|
||||
|
||||
<release-development-list>
|
||||
|
@ -14,8 +14,8 @@
|
||||
<variable key="os-rhel-title">RHEL</variable>
|
||||
|
||||
<!-- Base PostgreSQL versions -->
|
||||
<variable key="os-debian-pg-version">12</variable>
|
||||
<variable key="os-rhel-pg-version">11</variable>
|
||||
<variable key="os-debian-pg-version">15</variable>
|
||||
<variable key="os-rhel-pg-version">12</variable>
|
||||
|
||||
<!-- User-defined package to use in documentation (use "apt" to install the current PGDG apt package) -->
|
||||
<variable key="package">none</variable>
|
||||
@ -73,8 +73,8 @@
|
||||
<variable key="wal-level" if="{[pg-version]} < 9.6">hot_standby</variable>
|
||||
<variable key="wal-level" if="{[pg-version]} >= 9.6">replica</variable>
|
||||
|
||||
<variable key="pg-version-upgrade" if="{[os-type-is-debian]}">14</variable>
|
||||
<variable key="pg-version-upgrade" if="{[os-type-is-rhel]}">12</variable>
|
||||
<variable key="pg-version-upgrade" if="{[os-type-is-debian]}">16</variable>
|
||||
<variable key="pg-version-upgrade" if="{[os-type-is-rhel]}">13</variable>
|
||||
<variable key="pg-version-upgrade-nodot" eval="y">my $version = '{[pg-version-upgrade]}'; $version =~ s/\.//g; return $version;</variable>
|
||||
|
||||
<variable key="pg-bin-path" if="{[os-type-is-debian]}">/usr/lib/postgresql/{[pg-version]}/bin</variable>
|
||||
@ -2145,14 +2145,10 @@
|
||||
|
||||
<p><link section="/quickstart/perform-restore">Restore a Backup</link> in <link section="/quickstart">Quick Start</link> performed default recovery, which is to play all the way to the end of the WAL stream. In the case of a hardware failure this is usually the best choice but for data corruption scenarios (whether machine or human in origin) Point-in-Time Recovery (PITR) is often more appropriate.</p>
|
||||
|
||||
<p>Point-in-Time Recovery (PITR) allows the WAL to be played from the last backup to a specified lsn, time, transaction id, or recovery point. For common recovery scenarios time-based recovery is arguably the most useful. A typical recovery scenario is to restore a table that was accidentally dropped or data that was accidentally deleted. Recovering a dropped table is more dramatic so that's the example given here but deleted data would be recovered in exactly the same way.</p>
|
||||
<p>Point-in-Time Recovery (PITR) allows the WAL to be played from a backup to a specified lsn, time, transaction id, or recovery point. For common recovery scenarios time-based recovery is arguably the most useful. A typical recovery scenario is to restore a table that was accidentally dropped or data that was accidentally deleted. Recovering a dropped table is more dramatic so that's the example given here but deleted data would be recovered in exactly the same way.</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Backup the {[postgres-cluster-demo]} cluster and create a table with very important data</title>
|
||||
|
||||
<execute user="postgres">
|
||||
<exe-cmd>{[project-exe]} {[dash]}-stanza={[postgres-cluster-demo]} --type=diff backup</exe-cmd>
|
||||
</execute>
|
||||
<title>Create a table with very important data</title>
|
||||
|
||||
<execute user="postgres" output="y">
|
||||
<exe-cmd>
|
||||
@ -2200,15 +2196,87 @@
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p>Now the restore can be performed with time-based recovery to bring back the missing table.</p>
|
||||
<p>If the wrong backup is selected for restore then recovery to the required time target will fail. To demonstrate this a new incremental backup is performed where <id>important_table</id> does not exist.</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Stop <postgres/>, restore the {[postgres-cluster-demo]} cluster to <id>{[time-recovery-timestamp]}</id>, and display <file>{[pg-recovery-file-demo]}</file></title>
|
||||
<title>Perform an incremental backup</title>
|
||||
|
||||
<execute user="postgres">
|
||||
<exe-cmd>{[project-exe]} {[dash]}-stanza={[postgres-cluster-demo]} {[dash]}-type=incr backup</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres" show="n" variable-key="backup-last">
|
||||
<exe-cmd>{[cmd-backup-last]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres" output="y">
|
||||
<exe-cmd>{[project-exe]} info</exe-cmd>
|
||||
<exe-highlight>{[backup-last]}</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p>It will not be possible to recover the lost table from this backup since <postgres/> can only play forward, not backward.</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Attempt recovery from an incorrect backup</title>
|
||||
|
||||
<execute user="root">
|
||||
<exe-cmd>{[pg-cluster-stop]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres">
|
||||
<exe-cmd>
|
||||
{[project-exe]} {[dash]}-stanza={[postgres-cluster-demo]} {[dash]}-delta
|
||||
{[dash]}-set={[backup-last]} {[dash]}-target-timeline=current
|
||||
{[dash]}-type=time "{[dash]}-target={[time-recovery-timestamp]}" {[dash]}-target-action=promote restore
|
||||
</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="root" show="n">
|
||||
<exe-cmd>rm {[postgres-log-demo]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute if="{[pg-version]} > 12" user="root" output="y" err-expect="1">
|
||||
<exe-cmd>{[pg-cluster-start]}</exe-cmd>
|
||||
<exe-highlight>recovery ended before configured recovery target was reached</exe-highlight>
|
||||
</execute>
|
||||
|
||||
<execute if="{[pg-version]} <= 12" user="root">
|
||||
<exe-cmd>{[pg-cluster-start]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute if="{[pg-version]} <= 12" user="postgres" show="n">
|
||||
<exe-cmd>{[pg-cluster-wait]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute if="{[pg-version]} <= 12" user="postgres" output="y" err-expect="1">
|
||||
<exe-cmd>psql -c "select * from important_table"</exe-cmd>
|
||||
<exe-highlight>does not exist</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p if="{[pg-version]} <= 12">Looking at the log output it's not obvious that recovery failed to restore the table. The key is to look for the presence of the <quote>recovery stopping before...</quote> and <quote>last completed transaction...</quote> log messages. If they are not present then the recovery to the specified point-in-time was not successful.</p>
|
||||
|
||||
<execute-list if="{[pg-version]} <= 12" host="{[host-pg1]}">
|
||||
<title>Examine the <postgres/> log output to discover the recovery was not successful</title>
|
||||
|
||||
<execute user="postgres" output="y">
|
||||
<exe-cmd>cat {[postgres-log-demo]}</exe-cmd>
|
||||
<exe-highlight>starting point-in-time recovery|consistent recovery state reached</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p>A reliable method is to allow <backrest/> to automatically select a backup capable of recovery to the time target, i.e. a backup that ended before the specified time.</p>
|
||||
|
||||
<admonition type="note"><backrest/> cannot automatically select a backup when the restore type is <id>xid</id> or <id>name</id>.</admonition>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Restore the {[postgres-cluster-demo]} cluster to <id>{[time-recovery-timestamp]}</id></title>
|
||||
|
||||
<execute if="{[pg-version]} <= 12" user="root">
|
||||
<exe-cmd>{[pg-cluster-stop]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres">
|
||||
<exe-cmd>{[project-exe]} {[dash]}-stanza={[postgres-cluster-demo]} {[dash]}-delta
|
||||
{[dash]}-type=time "{[dash]}-target={[time-recovery-timestamp]}"
|
||||
@ -2225,7 +2293,7 @@
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p><backrest/> has automatically generated the recovery settings in <file>{[pg-recovery-file-demo]}</file> so <postgres/> can be started immediately. <id>%f</id> is how <postgres/> specifies the WAL segment it needs and <id>%p</id> is the location where it should be copied. Once <postgres/> has finished recovery the table will exist again and can be queried.</p>
|
||||
<p><backrest/> has generated the recovery settings in <file>{[pg-recovery-file-demo]}</file> so <postgres/> can be started immediately. <id>%f</id> is how <postgres/> specifies the WAL segment it needs and <id>%p</id> is the location where it should be copied. Once <postgres/> has finished recovery the table will exist again and can be queried.</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Start <postgres/> and check that the important table exists</title>
|
||||
@ -2254,127 +2322,6 @@
|
||||
<exe-highlight>recovery stopping before|last completed transaction|starting point-in-time recovery</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p>This example was rigged to give the correct result. If a backup after the required time is chosen then <postgres/> will not be able to recover the lost table. <postgres/> can only play forward, not backward. To demonstrate this the important table must be dropped (again).</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Drop the important table (again)</title>
|
||||
|
||||
<execute user="postgres" output="y" err-expect="1">
|
||||
<exe-cmd>psql -c "begin;
|
||||
drop table important_table;
|
||||
commit;
|
||||
select * from important_table;"</exe-cmd>
|
||||
<exe-highlight>does not exist</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p>Now take a new backup and attempt recovery from the new backup by specifying the <br-option>{[dash]}-set</br-option> option. The <cmd>info</cmd> command can be used to find the new backup label.</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Perform a backup and get backup info</title>
|
||||
|
||||
<execute user="postgres">
|
||||
<exe-cmd>{[project-exe]} {[dash]}-stanza={[postgres-cluster-demo]} {[dash]}-type=incr backup</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres" show="n" variable-key="backup-last">
|
||||
<exe-cmd>{[cmd-backup-last]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres" filter="n" output="y">
|
||||
<exe-cmd>{[project-exe]} info</exe-cmd>
|
||||
<exe-highlight>{[backup-last]}</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Attempt recovery from the specified backup</title>
|
||||
|
||||
<execute user="root">
|
||||
<exe-cmd>{[pg-cluster-stop]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres">
|
||||
<exe-cmd>{[project-exe]} {[dash]}-stanza={[postgres-cluster-demo]} {[dash]}-delta
|
||||
{[dash]}-set={[backup-last]}
|
||||
{[dash]}-type=time "{[dash]}-target={[time-recovery-timestamp]}" {[dash]}-target-action=promote restore</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="root" show="n">
|
||||
<exe-cmd>rm {[postgres-log-demo]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="root">
|
||||
<exe-cmd>{[pg-cluster-start]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres" show="n">
|
||||
<exe-cmd>{[pg-cluster-wait]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres" output="y" err-expect="1">
|
||||
<exe-cmd>psql -c "select * from important_table"</exe-cmd>
|
||||
<exe-highlight>does not exist</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p>Looking at the log output it's not obvious that recovery failed to restore the table. The key is to look for the presence of the <quote>recovery stopping before...</quote> and <quote>last completed transaction...</quote> log messages. If they are not present then the recovery to the specified point-in-time was not successful.</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Examine the <postgres/> log output to discover the recovery was not successful</title>
|
||||
|
||||
<execute user="postgres" output="y">
|
||||
<exe-cmd>cat {[postgres-log-demo]}</exe-cmd>
|
||||
<exe-highlight>starting point-in-time recovery|consistent recovery state reached</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p>The default behavior for time-based restore, if the <br-option>{[dash]}-set</br-option> option is not specified, is to attempt to discover an earlier backup to play forward from. If a backup set cannot be found, then restore will default to the latest backup which, as shown earlier, may not give the desired result.</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Stop <postgres/>, restore from auto-selected backup, and start <postgres/></title>
|
||||
|
||||
<execute user="root">
|
||||
<exe-cmd>{[pg-cluster-stop]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres">
|
||||
<exe-cmd>
|
||||
{[project-exe]} {[dash]}-stanza={[postgres-cluster-demo]} {[dash]}-delta
|
||||
{[dash]}-type=time "{[dash]}-target={[time-recovery-timestamp]}"
|
||||
{[dash]}-target-action=promote restore
|
||||
</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="root" show="n">
|
||||
<exe-cmd>rm {[postgres-log-demo]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="root">
|
||||
<exe-cmd>{[pg-cluster-start]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres" show="n">
|
||||
<exe-cmd>{[pg-cluster-wait]}</exe-cmd>
|
||||
</execute>
|
||||
|
||||
<execute user="postgres" output="y">
|
||||
<exe-cmd>psql -c "select * from important_table"</exe-cmd>
|
||||
<exe-highlight>{[test-table-data]}</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<p>Now the log output will contain the expected <quote>recovery stopping before...</quote> and <quote>last completed transaction...</quote> messages showing that the recovery was successful.</p>
|
||||
|
||||
<execute-list host="{[host-pg1]}">
|
||||
<title>Examine the <postgres/> log output for log messages indicating success</title>
|
||||
|
||||
<execute user="postgres" output="y">
|
||||
<exe-cmd>cat {[postgres-log-demo]}</exe-cmd>
|
||||
<exe-highlight>recovery stopping before|last completed transaction|starting point-in-time recovery</exe-highlight>
|
||||
</execute>
|
||||
</execute-list>
|
||||
</section>
|
||||
|
||||
<!-- ======================================================================================================================= -->
|
||||
|
Loading…
Reference in New Issue
Block a user