|
| 1 | +--- |
| 2 | +title: "Disaster Recovery" |
| 3 | +draft: false |
| 4 | +weight: 190 |
| 5 | +--- |
| 6 | + |
| 7 | +When using the PostgreSQL Operator, the answer to the question "do you take backups of your database" is automatically "yes!" |
| 8 | + |
| 9 | +The PostgreSQL Operator leverages a pgBackRest repository to facilitate the usage of the pgBackRest features in a PostgreSQL cluster. When a new PostgreSQL cluster is created, it simultaneously creates a pgBackRest repository as described in [creating a PostgreSQL cluster]({{< relref "tutorial/create-cluster.md" >}}) section. |
| 10 | + |
| 11 | +For more information on how disaster recovery in the PostgreSQL Operator works, please see the [disaster recovery architecture]({{< relref "architecture/disaster-recovery.md">}}) section. |
| 12 | + |
| 13 | +## Creating a Backup |
| 14 | + |
| 15 | +The PostgreSQL Operator uses the open source [pgBackRest](https://www.pgbackrest.org) backup and recovery utility for managing backups and PostgreSQL archives. pgBackRest has several types of backups that you can take: |
| 16 | + |
| 17 | +- Full: Back up the entire database |
| 18 | +- Differential: Create a backup of everything since the last full back up was taken |
| 19 | +- Incremental: Back up everything since the last backup was taken, whether it was full, differential, or incremental |
| 20 | + |
| 21 | +When a new PostgreSQL cluster is provisioned by the PostgreSQL Operator, a full pgBackRest backup is taken by default. |
| 22 | + |
| 23 | +To create a backup, you can run the following command: |
| 24 | + |
| 25 | +``` |
| 26 | +pgo backup hippo |
| 27 | +``` |
| 28 | + |
| 29 | +which by default, will create an incremental pgBackRest backup. The reason for this is that the PostgreSQL Operator initially creates a pgBackRest full backup when the cluster is initial provisioned, and pgBackRest will take incremental backups for each subsequent backup until a different backup type is specified. |
| 30 | + |
| 31 | +Most [pgBackRest options](https://pgbackrest.org/command.html#command-backup) are supported and can be passed in by the PostgreSQL Operator via the `--backup-opts` flag. |
| 32 | + |
| 33 | +### Creating a Full Backup |
| 34 | + |
| 35 | +You can create a full backup using the following command: |
| 36 | + |
| 37 | +``` |
| 38 | +pgo backup hippo --backup-opts="--type=full" |
| 39 | +``` |
| 40 | + |
| 41 | +### Creating a Differential Backup |
| 42 | + |
| 43 | +You can create a differential backup using the following command: |
| 44 | + |
| 45 | +``` |
| 46 | +pgo backup hippo --backup-opts="--type=diff" |
| 47 | +``` |
| 48 | + |
| 49 | +### Creating an Incremental Backup |
| 50 | + |
| 51 | +You can create a differential backup using the following command: |
| 52 | + |
| 53 | +``` |
| 54 | +pgo backup hippo --backup-opts="--type=incr" |
| 55 | +``` |
| 56 | + |
| 57 | +An incremental backup is created without specifying any options after a full or differential backup is taken. |
| 58 | + |
| 59 | +### Creating Backups in S3 |
| 60 | + |
| 61 | +The PostgreSQL Operator supports creating backups in S3 or any object storage system that uses the S3 protocol. For more information, please read the section on [PostgreSQL Operator Backups with S3]({{< relref "architecture/disaster-recovery.md">}}#using-s3) in the architecture section. |
| 62 | + |
| 63 | +## Set Backup Retention |
| 64 | + |
| 65 | +By default, pgBackRest will allow you to keep on creating backups until you run out of disk space. As such, it may be helpful to manage how many backups are retained. |
| 66 | + |
| 67 | +pgBackRest comes with several flags for managing how backups can be retained: |
| 68 | + |
| 69 | +- `--repo1-retention-full`: how many full backups to retain |
| 70 | +- `--repo1-retention-diff`: how many differential backups to retain |
| 71 | +- `--repo1-retention-archive`: how many sets of WAL archives to retain alongside the full and differential backups that are retained |
| 72 | + |
| 73 | +For example, to create a full backup and retain the previous 7 full backups, you would execute the following command: |
| 74 | + |
| 75 | +``` |
| 76 | +pgo backup hippo --backup-opts="--type=full --repo1-retention-full=7" |
| 77 | +``` |
| 78 | + |
| 79 | +pgBackRest also supports time-based retention. Please [review the pgBackRest documentation for more information](https://pgbackrest.org/command.html#command-backup). |
| 80 | + |
| 81 | +## Schedule Backups |
| 82 | + |
| 83 | +It is good practice to take backups regularly. The PostgreSQL Operator allows you to schedule backups to occur automatically. |
| 84 | + |
| 85 | +The PostgreSQL Operator comes with a scheduler is essentially a [cron](https://en.wikipedia.org/wiki/Cron) server that will run jobs that it is specified. Schedule commands use the cron syntax to set up scheduled tasks. |
| 86 | + |
| 87 | + |
| 88 | + |
| 89 | +For example, to schedule a full backup once a day at 1am, the following command can be used: |
| 90 | + |
| 91 | +``` |
| 92 | +pgo create schedule hippo --schedule="0 1 * * *" \ |
| 93 | + --schedule-type=pgbackrest --pgbackrest-backup-type=full |
| 94 | +``` |
| 95 | + |
| 96 | +To schedule an incremental backup once every 3 hours: |
| 97 | + |
| 98 | +``` |
| 99 | +pgo create schedule hippo --schedule="0 */3 * * *" \ |
| 100 | + --schedule-type=pgbackrest --pgbackrest-backup-type=incr |
| 101 | +``` |
| 102 | + |
| 103 | +You can also add the backup retention settings to these commands. |
| 104 | + |
| 105 | +## View Backups |
| 106 | + |
| 107 | +You can view all of the available backups in your pgBackRest repository with the `pgo show backup` command: |
| 108 | + |
| 109 | +``` |
| 110 | +pgo show backup hippo |
| 111 | +``` |
| 112 | + |
| 113 | +## Restores |
| 114 | + |
| 115 | +The PostgreSQL Operator supports the ability to perform a full restore on a PostgreSQL cluster (i.e. a "clone" or "copy") as well as a point-in-time-recovery. There are two types of ways to restore a cluster: |
| 116 | + |
| 117 | +- Restore to a new cluster using the `--restore-from` flag in the [`pgo create cluster`]({{< relref "/pgo-client/reference/pgo_create_cluster.md" >}}) command. This is effectively a [clone](#clone-a-postgresql-cluster) or a copy. |
| 118 | +- Restore in-place using the [`pgo restore`]({{< relref "/pgo-client/reference/pgo_restore.md" >}}) command. Note that this is **destructive**. |
| 119 | + |
| 120 | +It is typically better to perform a restore to a new cluster, particularly when performing a point-in-time-recovery, as it can allow you to more effectively manage your downtime and avoid making undesired changes to your production data. |
| 121 | + |
| 122 | +Additionally, the "restore to a new cluster" technique works so long as you have a pgBackRest repository available: the pgBackRest repository does not need to be attached to an active cluster! For example, if a cluster named `hippo` was deleted as such: |
| 123 | + |
| 124 | +``` |
| 125 | +pgo delete cluster hippo --keep-backups |
| 126 | +``` |
| 127 | + |
| 128 | +you can create a new cluster from the backups like so: |
| 129 | + |
| 130 | +``` |
| 131 | +pgo create cluster datalake --restore-from=hippo |
| 132 | +``` |
| 133 | + |
| 134 | +Below provides guidance on how to perform a restore to a new PostgreSQL cluster both as a full copy and to a specific point in time. Additionally, it also shows how to restore in place to a specific point in time. |
| 135 | + |
| 136 | +### Restore to a New Cluster (aka "copy" or "clone") |
| 137 | + |
| 138 | +Restoring to a new PostgreSQL cluster allows one to take a backup and create a new PostgreSQL cluster that can run alongside an existing PostgreSQL cluster. There are several scenarios where using this technique is helpful: |
| 139 | + |
| 140 | +- Creating a copy of a PostgreSQL cluster that can be used for other purposes. Another way of putting this is "creating a clone." |
| 141 | +- Restore to a point-in-time and inspect the state of the data without affecting the current cluster |
| 142 | + |
| 143 | +and more. |
| 144 | + |
| 145 | +#### Restore Everything |
| 146 | + |
| 147 | +To create a new PostgreSQL cluster from a backup and restore it fully, you can |
| 148 | +execute the following command: |
| 149 | + |
| 150 | +``` |
| 151 | +pgo create cluster datalake --restore-from=hippo |
| 152 | +``` |
| 153 | + |
| 154 | +#### Partial Restore / Point-in-time-Recovery (PITR) |
| 155 | + |
| 156 | +To create a new PostgreSQL cluster and restore it to specific point-in-time (e.g. before a key table was dropped), you can use the following command, substituting the time that you wish to restore to: |
| 157 | + |
| 158 | +``` |
| 159 | +pgo create cluster datalake \ |
| 160 | + --restore-from hippo \ |
| 161 | + --restore-opts "--type=time --target='2019-12-31 11:59:59.999999+00'" |
| 162 | +``` |
| 163 | + |
| 164 | +When the restore is complete, the cluster is immediately available for reads and writes. To inspect the data before allowing connections, add pgBackRest's `--target-action=pause` option to the `--restore-opts` parameter. |
| 165 | + |
| 166 | +The PostgreSQL Operator supports the full set of pgBackRest restore options, which can be passed into the `--backup-opts` parameter. For more information, please review the [pgBackRest restore options](https://pgbackrest.org/command.html#command-restore) |
| 167 | + |
| 168 | +### Restore in-place |
| 169 | + |
| 170 | +Restoring a PostgreSQL cluster in-place is a **destructive** action that will perform a recovery on your existing data directory. This is accomplished using the [`pgo restore`]({{< relref "/pgo-client/reference/pgo_restore.md" >}}) |
| 171 | +command. The most common scenario is to restore the database to a specific point in time. |
| 172 | + |
| 173 | +#### Point-in-time-Recovery (PITR) |
| 174 | + |
| 175 | +The more likely scenario when performing a PostgreSQL cluster restore is to recover to a particular point-in-time (e.g. before a key table was dropped). For example, to restore a cluster to December 31, 2019 at 11:59pm: |
| 176 | + |
| 177 | +``` |
| 178 | +pgo restore hippo --pitr-target="2019-12-31 11:59:59.999999+00" \ |
| 179 | + --backup-opts="--type=time" |
| 180 | +``` |
| 181 | + |
| 182 | +When the restore is complete, the cluster is immediately available for reads and writes. To inspect the data before allowing connections, add pgBackRest's `--target-action=pause` option to the `--backup-opts` parameter. |
| 183 | + |
| 184 | +The PostgreSQL Operator supports the full set of pgBackRest restore options, which can be passed into the `--backup-opts` parameter. For more information, please review the [pgBackRest restore options](https://pgbackrest.org/command.html#command-restore) |
| 185 | + |
| 186 | +## Next Steps |
| 187 | + |
| 188 | +There are cases where you may want to take [logical backups]({{< relref "tutorial/pgdump.md" >}}), aka `pg_dump` / `pg_dumpall`. Let's learn how to do that with the PostgreSQL Operator! |
0 commit comments