|  | 
|  | 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