From 2451d150528d2b731814bd715c619bd7389524cc Mon Sep 17 00:00:00 2001 From: Mireia Perez Date: Mon, 10 Aug 2026 12:55:02 +0100 Subject: [PATCH] whpg-backup documentation for OSS --- docs/.vitepress/config.mts | 55 +- .../images/parallel_backup_restore.png | Bin 0 -> 247267 bytes docs/whpg-backup/incremental.md | 99 ++ docs/whpg-backup/index.md | 14 + docs/whpg-backup/installing.md | 72 ++ docs/whpg-backup/overview/architecture.md | 46 + docs/whpg-backup/overview/compatibility.md | 11 + docs/whpg-backup/overview/index.md | 10 + docs/whpg-backup/overview/known_issues.md | 24 + .../reference/gpbackup.md | 251 ++--- .../reference/gprestore.md | 201 ++-- docs/whpg-backup/reference/index.md | 9 + .../release_notes/1.31.0_rel_notes.md | 13 + .../release_notes/1.32.0_rel_notes.md | 16 + .../release_notes/1.32.1_rel_notes.md | 22 + .../release_notes/1.33.0_rel_notes.md | 17 + .../release_notes/1.33.1_rel_notes.md | 17 + docs/whpg-backup/release_notes/index.md | 14 + docs/whpg-backup/s3-plugin.md | 142 +++ docs/whpg-backup/using.md | 238 +++++ .../6x/admin_guide/backup_restore/index.md | 6 + docs/whpg/6x/admin_guide/index.md | 1 + .../6x/admin_guide/managing/backup-main.md | 4 +- .../utility_guide/reference/index.md | 4 +- .../admin_guide/backup_restore/incremental.md | 360 ------- .../7x/admin_guide/backup_restore/index.md | 971 +----------------- .../7x/admin_guide/managing/backup-main.md | 6 +- docs/whpg/7x/index.md | 2 +- .../utility_guide/reference/index.md | 10 +- 29 files changed, 1039 insertions(+), 1596 deletions(-) create mode 100644 docs/whpg-backup/images/parallel_backup_restore.png create mode 100644 docs/whpg-backup/incremental.md create mode 100644 docs/whpg-backup/index.md create mode 100644 docs/whpg-backup/installing.md create mode 100644 docs/whpg-backup/overview/architecture.md create mode 100644 docs/whpg-backup/overview/compatibility.md create mode 100644 docs/whpg-backup/overview/index.md create mode 100644 docs/whpg-backup/overview/known_issues.md rename docs/{whpg/7x/ref_guide/utility_guide => whpg-backup}/reference/gpbackup.md (50%) rename docs/{whpg/7x/ref_guide/utility_guide => whpg-backup}/reference/gprestore.md (66%) create mode 100644 docs/whpg-backup/reference/index.md create mode 100644 docs/whpg-backup/release_notes/1.31.0_rel_notes.md create mode 100644 docs/whpg-backup/release_notes/1.32.0_rel_notes.md create mode 100644 docs/whpg-backup/release_notes/1.32.1_rel_notes.md create mode 100644 docs/whpg-backup/release_notes/1.33.0_rel_notes.md create mode 100644 docs/whpg-backup/release_notes/1.33.1_rel_notes.md create mode 100644 docs/whpg-backup/release_notes/index.md create mode 100644 docs/whpg-backup/s3-plugin.md create mode 100644 docs/whpg-backup/using.md create mode 100644 docs/whpg/6x/admin_guide/backup_restore/index.md delete mode 100644 docs/whpg/7x/admin_guide/backup_restore/incremental.md diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index f25a983..57b812a 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -33,7 +33,8 @@ export default defineConfig( text: 'Docs', items: [ { text: '7.x', link: '/docs/7x' }, - { text: '6.x', link: '/docs/6x' } + { text: '6.x', link: '/docs/6x' }, + { text: 'Backup & restore', link: '/whpg-backup/' } ] }, { text: 'GitHub', link: 'https://github.com/warehouse-pg/warehouse-pg' }, @@ -45,22 +46,22 @@ export default defineConfig( sidebar: [ { - text: 'WHPG Documentation' + text: 'WHPG documentation' }, { text: "WHPG 7.x", link: "/docs/7x/" , collapsed: false, items: [ - { text: "Release Notes", link: "/docs/7x/release_notes" }, - { text: "Install Guide", link: "/docs/7x/install_guide/" }, - { text: "Admin Guide", link: "/docs/7x/admin_guide/" }, - { text: "Best Practices", link: "/docs/7x/best_practices/" }, - { text: "Utility Guide", link: "/docs/7x/ref_guide/utility_guide/" }, - { text: "Analytics Guide", link: "/docs/7x/admin_guide/analytics/" }, - { text: "Reference Guide", link: "/docs/7x/ref_guide/" }, - { text: "Security Guide", link: "/docs/7x/security_guide/" }, - { text: "Backup & Restore Guide", link: "/docs/7x/admin_guide/backup_restore/" } + { text: "Release notes", link: "/docs/7x/release_notes" }, + { text: "Install guide", link: "/docs/7x/install_guide/" }, + { text: "Admin guide", link: "/docs/7x/admin_guide/" }, + { text: "Best practices", link: "/docs/7x/best_practices/" }, + { text: "Utility guide", link: "/docs/7x/ref_guide/utility_guide/" }, + { text: "Analytics guide", link: "/docs/7x/admin_guide/analytics/" }, + { text: "Reference guide", link: "/docs/7x/ref_guide/" }, + { text: "Security guide", link: "/docs/7x/security_guide/" }, + { text: "Backup & restore guide", link: "/whpg-backup/" } @@ -73,17 +74,33 @@ export default defineConfig( link: "/docs/6x/index.html" , collapsed: true, items: [ - { text: "Release Notes", link: "/docs/6x/release_notes/" }, - { text: "Install Guide", link: "/docs/6x/install_guide/" }, - { text: "Admin Guide", link: "/docs/6x/admin_guide/" }, - { text: "Best Practices", link: "/docs/6x/best_practices/" }, - { text: "Utility Guide", link: "/docs/6x/ref_guide/utility_guide/" }, - { text: "Analytics Guide", link: "/docs/6x/admin_guide/analytics/" }, - { text: "Reference Guide", link: "/docs/6x/ref_guide/" }, - { text: "Security Guide", link: "/docs/6x/security-guide/" }, + { text: "Release notes", link: "/docs/6x/release_notes/" }, + { text: "Install guide", link: "/docs/6x/install_guide/" }, + { text: "Admin guide", link: "/docs/6x/admin_guide/" }, + { text: "Best practices", link: "/docs/6x/best_practices/" }, + { text: "Utility guide", link: "/docs/6x/ref_guide/utility_guide/" }, + { text: "Analytics guide", link: "/docs/6x/admin_guide/analytics/" }, + { text: "Reference guide", link: "/docs/6x/ref_guide/" }, + { text: "Security guide", link: "/docs/6x/security-guide/" }, ], + }, + { + text: "WHPG backup & restore", + link: "/whpg-backup/" , + collapsed: false, + items: [ + { + text: "Release notes", link: "/whpg-backup/release_notes/"}, + { text: "Overview", link: "/whpg-backup/overview/" }, + { text: "Installing", link: "/whpg-backup/installing" }, + { text: "Backing up and restoring", link: "/whpg-backup/using" }, + { text: "Creating incremental backups", link: "/whpg-backup/incremental" }, + { text: "Using the S3 storage plugin", link: "/whpg-backup/s3-plugin" }, + { text: "Reference", + link: "/whpg-backup/reference/" } + ], } ] diff --git a/docs/whpg-backup/images/parallel_backup_restore.png b/docs/whpg-backup/images/parallel_backup_restore.png new file mode 100644 index 0000000000000000000000000000000000000000..f05a6d1f276ede5f5c2cafe0abd580d3288f15f9 GIT binary patch literal 247267 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�TF|YN)ki;?yfjnDuY0&vdcp6N15vi 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 #XFJTIsZb5BLI|4lB|L?ogDw$pP}zd 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�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 literal 0 HcmV?d00001 diff --git a/docs/whpg-backup/incremental.md b/docs/whpg-backup/incremental.md new file mode 100644 index 0000000..e4a6889 --- /dev/null +++ b/docs/whpg-backup/incremental.md @@ -0,0 +1,99 @@ +--- +title: Creating incremental backups of append-optimized tables + +--- + +Use `gpbackup` and `gprestore` to create and restore incremental backups of append-optimized tables. Full backups contain every object in the database, making a restore, filtered or complete, straightforward, but they cost more in size and duration. Incremental backups reduce that cost when the total amount of changed append-optimized data is small compared to the data that hasn't changed since the last backup. + +`gpbackup` backs up an append-optimized table in an incremental backup only if one of these operations ran against the table after the last full or incremental backup: + +- `ALTER TABLE` +- `DELETE` +- `INSERT` +- `TRUNCATE` +- `UPDATE` +- `DROP` and then re-create the table + +An incremental backup always includes every specified heap table, and backs up an append-optimized table, including a column-oriented table, only if it's changed. An incremental backup set consists of a full backup, plus the incremental backups that capture changes to the database since that full backup. For example, a full backup on Sunday plus three daily incremental backups on Monday, Wednesday, and Friday together form one backup set. Restoring from an incremental backup requires the complete backup set, and every backup in a set must use consistent command-line options so that `gpbackup` can build on it and `gprestore` can restore from it. + +::: info Note +`gpbackup` always backs up a whole table when it includes it in an incremental backup, whether that's because it's a heap table or because an append-optimized table changed. It doesn't back up just the changed rows within a table. For a partitioned append-optimized table, though, `gpbackup` backs up only the leaf partitions that changed, not the entire table, so partitioning large append-optimized tables can substantially reduce the size of your incremental backups. +::: + +## Creating an incremental backup set + +Start an incremental backup set with a full backup, then add incremental backups on top of it using a few required options, plus optional ones for more control. `gpbackup` checks that later backups in the set stay consistent with the ones already there. + +```bash +gpbackup --dbname --incremental --backup-dir --leaf-partition-data +``` + +Include these options when you create an incremental backup: + +- **`--leaf-partition-data`**: Required for every backup in the set, including the full backup that serves as its base. +- **`--incremental`**: Required to create an incremental backup. Not compatible with `--data-only` or `--metadata-only`. +- **`--from-timestamp`** (optional): Use with `--incremental` to specify the timestamp of an existing backup, either an incremental backup or the initial full backup, to build on. The new backup must use the same command-line options as the backup specified. If you don't specify `--from-timestamp`, `gpbackup` looks for a compatible backup using the [backup history database](using.md#understanding-the-backup-history-database). + +When you add an incremental backup to a set, `gpbackup` checks that these options match across the full backup and all incremental backups in the set: + +- **`--dbname`**: The database must be the same. +- **`--backup-dir`**: The full backup and its incremental backups must be in the same location. +- **`--single-data-file`**: Must be either specified or absent for every backup in the set. +- **`--plugin-config`**: If specified, it must be specified for every backup in the set, referencing the same plugin binary. +- **`--include-table-file`, `--include-schema`**, and other [filtering options](using.md#filtering-backups-and-restores): Must be the same across the set. For schema filters, `gpbackup` checks only the schema names, not the objects they contain. +- **`--no-compression`**: If specified, it must be specified for every backup in the set. If the full backup uses compression, the incremental backups must too, though they can use different compression levels. The default compression level is 1. + +::: warning +If you try to add an incremental backup to a set and its command-line options aren't consistent with the rest of the set, the backup operation fails. +::: + +::: warning +Changing the WarehousePG segment configuration invalidates incremental backups. After you add or remove segment instances, create a full backup before creating another incremental backup. +::: + +## Planning your backup strategy + +Decide how many full and incremental backups to retain based on your organization's regulatory requirements for backups. Factor in your Recovery Point Objective (RPO), when you design your backup strategy. Combine `--incremental` backups, effective partitioning of append-optimized/column-oriented (AO/CO) tables, and the `--include` and `--exclude` filters for a flexible and performant backup strategy. + +When you archive incremental backups, archive the complete backup set, including all files created on the coordinator and all segments. + +The `--with-stats` option doesn't need to be consistent across a backup set. However, to restore statistics with the `gprestore --with-stats` option, the backup you restore from must have been taken with `--with-stats`. + +### Example + +This example follows a common strategy, combining a weekly full backup with daily incremental backups. Each backup's file name includes a timestamp, in `YYYYMMDDhhmmss` format, identifying when `gpbackup` created it. + +1. Create the first full backup of the set on Sunday: + + ```bash + gpbackup --dbname ww_sales --backup-dir /nfsmount/whpg_backups/ww_sales --leaf-partition-data + ``` + +1. Create an incremental backup based on that full backup each following day: + + ```bash + gpbackup --dbname ww_sales --incremental --backup-dir /nfsmount/whpg_backups/ww_sales --leaf-partition-data + ``` + +Continuing this pattern from Monday through Saturday results in a set of seven backups: one full backup and six incremental backups, each identified by its own timestamp. At the end of a week-long set like this, continue in one of two ways: + +- Run another full backup the next Sunday to start a new backup set and retire or archive the previous week's set. +- Aggregate the week into a single incremental backup using `--from-timestamp`, pointing at the previous Sunday's full backup: + + ```bash + gpbackup --dbname ww_sales --incremental --from-timestamp 20250518010000 --backup-dir /nfsmount/whpg_backups/ww_sales --leaf-partition-data + ``` + + This new backup captures the same changes as the whole week's incremental backups combined, since it's incremental from the same full backup they were. That makes the week's individual incremental backups redundant, and you can delete them to reclaim storage space, leaving just the full backup and this one aggregated incremental backup to cover the entire week. + +## Restoring incremental backup sets + +To restore to a point in the middle of an incremental backup set, specify that backup's timestamp with `gprestore --timestamp`. For example, to restore to Wednesday's incremental backup from the weekly set described above: + +```bash +gprestore --timestamp 20250521040000 --redirect-db ww_sales_pitr --create-db +``` + +Every earlier backup in the set, the Monday and Tuesday incremental backups and the Sunday full backup, must also be available for this restore to succeed. + +Restore operations can start from any backup in the set, but changes captured in incremental backups later than the one you restore from aren't restored. When restoring from an incremental backup set, `gprestore` restores each append-optimized table from its most recent version in the set. Heap tables are always restored from the latest backup in the set. diff --git a/docs/whpg-backup/index.md b/docs/whpg-backup/index.md new file mode 100644 index 0000000..c4d90bd --- /dev/null +++ b/docs/whpg-backup/index.md @@ -0,0 +1,14 @@ +--- +title: WarehousePG Backup and Restore + +--- + +Use WarehousePG Backup and Restore (`whpg-backup`) to create and restore logical backups of your WarehousePG tables in parallel. By default, backups are written to local disk on the coordinator and segment hosts, though you can consolidate them in a shared directory or write them directly to S3-compatible storage. `whpg-backup` writes the metadata and DDL for a backup to the coordinator host, while each segment writes its own table data to CSV files, so backup and restore performance scales with your cluster. + +## Key capabilities + +- Parallel backup and restore across the coordinator and all segment hosts +- Full database backups, plus [incremental backups](incremental.md) that include every heap table but back up append-optimized tables only if they changed +- [Filtering](using.md#filtering-backups-and-restores) backups and restores by schema, table, or leaf partition +- [Email notifications](using.md#setting-up-email-alerts) when a backup or restore completes +- Backing up directly to [Amazon S3 or S3-compatible storage](s3-plugin.md) diff --git a/docs/whpg-backup/installing.md b/docs/whpg-backup/installing.md new file mode 100644 index 0000000..c728ff4 --- /dev/null +++ b/docs/whpg-backup/installing.md @@ -0,0 +1,72 @@ +--- +title: Installing WarehousePG Backup and Restore + +--- + +`whpg-backup` provides the `gpbackup` and `gprestore` utilities. Build them from source, then install the binaries on every host in your WarehousePG cluster. + +## Prerequisites + +- **Build host:** [Go](https://go.dev/doc/install) 1.23 or later, plus `sqlite3`. Building directly on the WarehousePG coordinator avoids a cross-compile step, since it's already running the same OS as your segment hosts. If you build on a macOS workstation instead, use `make build_linux` to cross-compile for the cluster. +- **Every host in the cluster:** `sqlite3`. `gpbackup` splits work between the coordinator and every segment host, so the `sqlite3` runtime dependency needs to be present wherever `gpbackup`, `gprestore`, or `gpbackup_helper` runs, not just on the build host. + +## Building from source + +1. Clone the repository and change into it: + + ```bash + git clone https://github.com/warehouse-pg/whpg-backup.git + cd whpg-backup + ``` + +1. Build the `gpbackup`, `gprestore`, and `gpbackup_helper` binaries: + + ```bash + make depend + make build + ``` + + The binaries are placed in `$HOME/go/bin`. If you're cross-compiling from a macOS workstation, run `make build_linux` instead. + +:::: tip +Add `$HOME/go/bin` to your `PATH` so you can run the binaries directly from the build host: + +```bash +export PATH=$PATH:$HOME/go/bin +``` +:::: + +## Installing on the cluster + +1. Confirm `sqlite3` is installed on every host in the cluster, including the coordinator, standby coordinator, and all segment hosts. It's installed by default on many platforms, but install it if it's missing. + +1. On the coordinator, create a file `all_hosts` which lists all hosts in the WHPG cluster. For example: + + ```ini + cdw + scdw + sdw1 + sdw2 + sdw3 + ``` + +1. Transfer the binaries to all hosts in the cluster and place them on `$PATH`, for example in `$GPHOME/bin`. Use the `gpsync` utility on WarehousePG 7, or the `gpscp` utility on WarehousePG 6: + + ### WHPG 7 + + ```bash + gpsync -f all_hosts $HOME/go/bin/gpbackup $HOME/go/bin/gprestore $HOME/go/bin/gpbackup_helper =:$GPHOME/bin + ``` + + ### WHPG 6 + + ```bash + gpscp -f all_hosts $HOME/go/bin/gpbackup $HOME/go/bin/gprestore $HOME/go/bin/gpbackup_helper =:$GPHOME/bin + ``` + +1. Verify the installation by checking the `gpbackup` and `gprestore` versions: + + ```bash + gpbackup --version + gprestore --version + ``` diff --git a/docs/whpg-backup/overview/architecture.md b/docs/whpg-backup/overview/architecture.md new file mode 100644 index 0000000..d4d0af2 --- /dev/null +++ b/docs/whpg-backup/overview/architecture.md @@ -0,0 +1,46 @@ +--- +title: Architecture of WarehousePG Backup and Restore + +--- + +WarehousePG Backup and Restore (`whpg-backup`) provides the `gpbackup` and `gprestore` utilities, which create and restore logical backups of WarehousePG tables in parallel. Because a WarehousePG cluster spreads data across many segment hosts, `gpbackup` and `gprestore` split backup and restore work across the cluster, so throughput scales with the number of segments. By default, backup files stay on local disk on the coordinator and segment hosts, though you can point them at a shared directory instead or write them directly to [S3-compatible storage](../s3-plugin.md). + +![Parallel restore using parallel backup files](../images/parallel_backup_restore.png "Parallel restore using parallel backup files") + +## How it works + +`gpbackup` creates a full backup of a single database, splitting the work between the coordinator and every segment host. The coordinator writes the backup's metadata and DDL, while each segment writes its own table data to CSV files, using the `COPY ... ON SEGMENT` command. Files are compressed by default; use `--no-compression` to disable it. Each `gpbackup` task runs in a single transaction and acquires an `ACCESS SHARE` lock on each table it backs up. On completion, `gpbackup` returns the backup's timestamp, which identifies that backup for a later restore. + +The metadata files contain everything `gprestore` needs to reconstruct a full backup set in parallel, restoring the coordinator's schema and database objects alongside each segment's table data. Because table data is stored as CSV, other utilities, such as [`gpload`](../../whpg/7x/ref_guide/utility_guide/reference/gpload.md), can also load it, in the same cluster or a different one. + +`gprestore` restores the database objects from a backup by default. Restoring the WarehousePG cluster's global objects, such as roles and tablespaces, is optional. See [Objects included in a backup](#objects-included-in-a-backup) for the distinction. + +For the full walkthrough with example commands and output, see [Running a full backup](../using.md#running-a-full-backup) and [Restoring a full backup](../using.md#restoring-a-full-backup). + +## Objects included in a backup + +`gpbackup` and `gprestore` back up and restore two categories of objects: + +- **Database objects** for the database you specify with the `--dbname` option. They include: + - **Schema and storage objects:** schemas, tables, views, materialized views (DDL only), sequences, indexes, types, and domains. + - **Programmability objects:** functions, procedural language extensions, operators, operator families, and operator classes, casts, conversions, aggregates, and text search parsers, dictionaries, templates, and configurations. + - **Rules and triggers:** rules, and triggers (definitions only; WarehousePG doesn't support triggers). + - **External tables:** readable and writable external tables (DDL only), and protocols. + - **Metadata and configuration:** comments, owners, extensions, session-level configuration parameter settings, and table statistics (only with the `--with-stats` option). + + ::: info Note + `gpbackup` and `gprestore` never include these schemas in a backup set: `gp_toolkit`, `information_schema`, `pg_aoseg`, `pg_bitmapindex`, `pg_catalog`, `pg_toast*`, and `pg_temp*`. + ::: + +- **Global objects** are also backed up by default. They include: + - Databases + - Database-wide configuration parameter settings + - `GRANT` assignments of roles to databases + - Resource group definitions + - Resource queue definitions + - Roles + - Tablespaces + + ::: info Note + `gprestore` only restores global objects if you include the `--with-globals` option. Conversely, `gpbackup --without-globals` skips the backup of global objects. + ::: diff --git a/docs/whpg-backup/overview/compatibility.md b/docs/whpg-backup/overview/compatibility.md new file mode 100644 index 0000000..439690d --- /dev/null +++ b/docs/whpg-backup/overview/compatibility.md @@ -0,0 +1,11 @@ +--- +title: Compatibility for WarehousePG Backup and Restore + +--- + +The WarehousePG-provided `gpbackup` and `gprestore` utilities are compatible with the following WarehousePG versions: + +- WarehousePG 6.27.1 or later +- WarehousePG 7.2.1-WHPG or later + +`gpbackup` and `gprestore` support RHEL 7, 8, and 9, on `x86_64`. diff --git a/docs/whpg-backup/overview/index.md b/docs/whpg-backup/overview/index.md new file mode 100644 index 0000000..acf8c4c --- /dev/null +++ b/docs/whpg-backup/overview/index.md @@ -0,0 +1,10 @@ +--- +title: Overview of WarehousePG Backup and Restore + +--- + +WarehousePG Backup and Restore (`whpg-backup`) creates and restores WarehousePG backup sets in parallel across the coordinator and all segment hosts. + +- [Architecture](architecture.md): Learn how `whpg-backup` coordinates backups and restores across the coordinator and segment hosts. +- [Compatibility](compatibility.md): Check compatible WarehousePG versions and supported platforms. +- [Known issues](known_issues.md): Review current limitations before you deploy. diff --git a/docs/whpg-backup/overview/known_issues.md b/docs/whpg-backup/overview/known_issues.md new file mode 100644 index 0000000..cf234ea --- /dev/null +++ b/docs/whpg-backup/overview/known_issues.md @@ -0,0 +1,24 @@ +--- +title: Known issues + +--- + +These are the currently known issues and limitations of `gpbackup` and `gprestore`. Where applicable, workarounds are included to help mitigate the impact of these issues. + +- If you create an index on a parent partitioned table, `gpbackup` doesn't back up that same index on child partitioned tables of the parent, as creating the same index on a child would cause an error. However, if you exchange a partition, `gpbackup` doesn't detect that the index on the exchanged partition is inherited from the new parent table. In this case, `gpbackup` backs up conflicting `CREATE INDEX` statements, which causes an error when you restore the backup set. + +- You can execute multiple instances of `gpbackup`, but each execution requires a distinct timestamp. + +- Database object filtering is currently limited to schemas and tables. + +- When backing up a partitioned table where some or all leaf partitions are in different schemas from the root partition, the leaf partition table definitions, including the schemas, are backed up as metadata. This occurs even if the backup operation specifies that schemas containing the leaf partitions should be excluded. To control data being backed up for this type of partitioned table, use the `--leaf-partition-data` option. + +- If you use the `gpbackup --single-data-file` option to combine table backups into a single file per segment, you can't perform a parallel restore operation with `gprestore` (you can't set `--jobs` to a value higher than 1). + +- You can't use `--exclude-table-file` with `--leaf-partition-data`. Although you can specify leaf partition names in a file specified with `--exclude-table-file`, `gpbackup` ignores the partition names. + +- Backing up a database with `gpbackup` while simultaneously running DDL commands might cause `gpbackup` to fail, in order to ensure consistency within the backup set. For example, if a table is dropped after the start of the backup operation, `gpbackup` exits and displays the error `relation does not exist`. + +- `gpbackup` might fail when a table is dropped during a backup operation due to table locking issues. `gpbackup` generates a list of tables to back up and acquires an ACCESS SHARE lock on the tables. If an EXCLUSIVE LOCK is held on a table, `gpbackup` acquires the ACCESS SHARE lock after the existing lock is released. If the table no longer exists when `gpbackup` attempts to acquire a lock on the table, `gpbackup` exits with an error. For tables that might be dropped during a backup, exclude the tables from a backup with a `gpbackup` table filtering option such as `--exclude-table` or `--exclude-schema`. + +- A backup created with `gpbackup` can only be restored to a WarehousePG cluster with the same number of segment instances as the source cluster. If you run `gpexpand` to add segments to the cluster, backups made before starting the expansion can't be restored after the expansion completes. diff --git a/docs/whpg/7x/ref_guide/utility_guide/reference/gpbackup.md b/docs/whpg-backup/reference/gpbackup.md similarity index 50% rename from docs/whpg/7x/ref_guide/utility_guide/reference/gpbackup.md rename to docs/whpg-backup/reference/gpbackup.md index 23d78e2..2c19c9c 100644 --- a/docs/whpg/7x/ref_guide/utility_guide/reference/gpbackup.md +++ b/docs/whpg-backup/reference/gpbackup.md @@ -5,8 +5,6 @@ title: gpbackup Create backup metadata and data files of a WarehousePG cluster compatible with the `gprestore` utility - - ## Synopsis ``` @@ -41,247 +39,256 @@ gpbackup --dbname [--with-stats] [--without-globals] -gpbackup --help +gpbackup --help ``` - `gprestore` [reference](gprestore.md) - - +`gprestore` [reference](gprestore.md) ## Description -The `gpbackup` utility backs up the contents of a database into a collection of metadata files and data files that can be used to restore the database at a later time using gprestore. When you back up a database, you can specify table level and schema level filter options to back up specific tables. For example, you can combine schema level and table level options to back up all the tables in a schema except for a single table. - -By default, `gpbackup` backs up objects in the specified database as well as global WarehousePG system objects. Use `--without-globals` to omit global objects. gprestore does not restore global objects by default; use `--with-global`s to restore them. - -See Objects Included in a Backup or Restore for additional information. - -For materialized views, data is not backed up, only the materialized view definition is backed up. - -gpbackup stores the object metadata files and DDL files for a backup in the WarehousePG coordinator data directory by default. WarehousePG segments use the `COPY ... ON SEGMENT` command to store their data for backed-up tables in compressed CSV data files, located in each segment's data directory. See Understanding Backup Files for additional information. - -You can add the `--backup-dir` option to copy all backup files from the WarehousePG coordinator and segment hosts to an absolute path for later use. Additional options are provided to filter the backup set in order to include or exclude specific tables. - -You can create an incremental backup with the` --incremental` option. Incremental backups are efficient when the total amount of data in append-optimized tables or table partitions that changed is small compared to the data has not changed. See Creating and Using Incremental Backups with `gpbackup` and gprestore for information about incremental backups. +The `gpbackup` utility backs up a database into metadata and data files that `gprestore` can use to restore it later. For background on what gets backed up and how `gpbackup` and `gprestore` work together, see [Architecture](../overview/architecture.md). For a full walkthrough, see [Backing up and restoring your tables](../using.md) and [Creating incremental backups of append-optimized tables](../incremental.md). -With the default `--jobs` option (1 job), each `gpbackup` operation uses a single transaction on the WarehousePG coordinator host. The `COPY ... ON SEGMENT` command performs the backup task in parallel on each segment host. The backup process acquires an `ACCESS SHARE` lock on each table that is backed up. During the table locking process, the database should be in a quiescent state. - -When a back up operation completes, `gpbackup` returns a status code. See Return Codes. - -The `gpbackup` utility cannot be run while gpexpand is initializing new segments. Backups created before the expansion cannot be restored with gprestore after the cluster expansion is completed. - -`gpbackup` can send status email notifications after a back up operation completes. You specify when the utility sends the mail and the email recipients in a configuration file. See Configuring Email Notifications. - -:::info Note -This utility uses secure shell (SSH) connections between systems to perform its tasks. In large WarehousePG deployments, cloud deployments, or deployments with a large number of segments per host, this utility may exceed the host's maximum threshold for unauthenticated connections. Consider updating the `SSH MaxStartups` and` MaxSessions` configuration parameters to increase this threshold. For more information about SSH configuration options, refer to the SSH documentation for your Linux distribution. +::: info Note +- `gpbackup` cannot run while `gpexpand` is initializing new segments. Existing backup sets taken with a different cluster configuration may no longer be compatible after an expansion completes. To restore onto a cluster with a different number of segments, use `gprestore`'s `--resize-cluster` option. +- On completion, `gpbackup` returns a status code. See [Return codes](gprestore.md#return-codes). +- `gpbackup` can send status email notifications after it completes. See [Setting up email alerts](../using.md#setting-up-email-alerts). +- This utility uses SSH connections between hosts. In large or cloud deployments, it may exceed a host's maximum threshold for unauthenticated connections. Consider raising the SSH `MaxStartups` and `MaxSessions` configuration parameters. ::: - - -## Parallel Backup with gpbackup and gprestore - -![Parallel Restore Using Parallel Backup Files](../../../images/parallel_backup_restore.png "Parallel Restore Using Parallel Backup Files") - - - ## Options -`--dbname database_name`
+### --dbname database_name + Required. Specifies the database to back up. -`--backup-dir `
-Optional. Copies all required backup files (metadata files and data files) to the specified directory. You must specify directory as an absolute path (not relative). If you do not supply this option, metadata files are created on the WarehousePG coordinator host in the`$MASTER_DATA_DIRECTORY/backups/YYYYMMDD/YYYYMMDDhhmmss/` directory. Segment hosts create CSV data files in the `/backups/YYYYMMDD/YYYYMMDDhhmmss/` directory. When you specify a custom backup directory, files are copied to these paths in subdirectories of the backup directory. +### --backup-dir directory -When invoked together with the` --metadata-only` and `--no-history` options, a backup may have the same timestamp as another backup, provided that each of the two backups has a distinct `--backup-dir` location. +Optional. Copies all required backup files (metadata files and data files) to the specified directory. You must specify directory as an absolute path (not relative). If you do not supply this option, metadata files are created on the WarehousePG coordinator host in the `$COORDINATOR_DATA_DIRECTORY/backups/YYYYMMDD/YYYYMMDDhhmmss/` directory. Segment hosts create CSV data files in the `/backups/YYYYMMDD/YYYYMMDDhhmmss/` directory. When you specify a custom backup directory, files are copied to these paths in subdirectories of the backup directory. + +When invoked together with the `--metadata-only` and `--no-history` options, a backup may have the same timestamp as another backup, provided that each of the two backups has a distinct `--backup-dir` location. You cannot combine this option with the option `--plugin-config`. -`--compression-level `
-Optional. Specifies the compression level (from 1 to 9) used to compress data files. The default is 1. +### --compression-level level + +Optional. Specifies the compression level (from 1 to 9) used to compress data files. The default is 1. -:::info Note +::: info Note `gpbackup` uses compression by default. ::: -`--compression-type `
+### --compression-type type + Optional. Specifies the compression type (gzip or zstd) used to compress data files. The default is gzip. -:::info Note +::: info Note In order to use the zstd compression type, Zstandard must be installed in a `$PATH` accessible by the `gpadmin` user. ::: -`--copy-queue-size int`
-Optional. Specifies the number of `COPY` commands `gpbackup` should enqueue when backing up using the `--single-data-file` option. This option optimizes backup performance by reducing the amount of time spent initializing `COP`Y commands. If you do not set this option to 2 or greater, `gpbackup` enqueues 1 `COPY` command at a time. +### --copy-queue-size int + +Optional. Specifies the number of `COPY` commands `gpbackup` should enqueue when backing up using the `--single-data-file` option. This option optimizes backup performance by reducing the amount of time spent initializing `COPY` commands. If you don't set this option, `gpbackup` enqueues 1 `COPY` command at a time. If you do set it explicitly, the value must be 2 or greater. -:::info Note -This option must be used with the `--single-data-file` option and cannot be used with the `--jobs` option. +::: info Note +This option must be used with the `--single-data-file` option. ::: -`--data-only`
+### --data-only + Optional. Backs up only the table data into CSV files, but does not backup metadata files needed to recreate the tables and other database objects. -`--debug`
+You cannot combine this option with `--metadata-only`, `--incremental`, or `--leaf-partition-data`. + +### --debug + Optional. Displays verbose debug messages during operation. -`--exclude-schema `
+### --exclude-schema schema_name + Optional. Specifies a database schema to exclude from the backup. You can specify this option multiple times to exclude multiple schemas. You cannot combine this option with the option `--include-schema`, `--include-schema-file`, or a table filtering option such as `--include-table`. -[**See Filtering the Contents of a Backup or Restore for more information.**](../../../admin_guide/backup_restore/index.md#filter) +See [Filtering backups and restores](../using.md#filtering-backups-and-restores) for more information. -**See Requirements and Limitations for limitations when leaf partitions of a partitioned table are in different schemas from the root partition.** +### --exclude-schema-file file_name -`--exclude-schema-file `
Optional. Specifies a text file containing a list of schemas to exclude from the backup. Each line in the text file must define a single schema. The file must not include trailing lines. If a schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. You cannot combine this option with the option `--include-schema` or `--include-schema-file`, or a table filtering option such as `--include-table`. -[**See Filtering the Contents of a Backup or Restore for more information.**](../../../admin_guide/backup_restore/index.md#filter) +See [Filtering backups and restores](../using.md#filtering-backups-and-restores) for more information. -**See Requirements and Limitations for limitations when leaf partitions of a partitioned table are in different schemas from the root partition.** +### --exclude-table schema.table -`--exclude-table `
-Optional. Specifies a table to exclude from the backup. The table must be in the format `.`. If a table or schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. You can specify this option multiple times. You cannot combine this option with the option `--exclude-schema`, `--exclude-schema-file`, or another a table filtering option such as `--include-table`. +Optional. Specifies a table to exclude from the backup. The table must be in the format `.`. If a table or schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. You can specify this option multiple times. You cannot combine this option with the option `--exclude-schema`, `--exclude-schema-file`, or another table filtering option such as `--include-table`. If you specify a leaf partition name, `gpbackup` ignores the partition names. The leaf partition is not excluded. -[**See Filtering the Contents of a Backup or Restore for more information.**](../../../admin_guide/backup_restore/index.md#filter) +See [Filtering backups and restores](../using.md#filtering-backups-and-restores) for more information. + +### --exclude-table-file file_name + +Optional. Specifies a text file containing a list of tables to exclude from the backup. Each line in the text file must define a single table using the format `.`. The file must not include trailing lines. If a table or schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. You cannot combine this option with the option `--exclude-schema`, `--exclude-schema-file`, or another table filtering option such as `--include-table`. -`--exclude-table-file `
-Optional. Specifies a text file containing a list of tables to exclude from the backup. Each line in the text file must define a single table using the format `.`. The file must not include trailing lines. If a table or schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. You cannot combine this option with the option `--exclude-schema`, `--exclude-schema-file`, or another a table filtering option such as `--include-table`. +If you specify leaf partition names in a file that is used with `--exclude-table-file`, `gpbackup` ignores the partition names. The leaf partitions are not excluded. -If you specify leaf partition names in a file that is used with --exclude-table-file, `gpbackup` ignores the partition names. The leaf partitions are not excluded. +See [Filtering backups and restores](../using.md#filtering-backups-and-restores) for more information. -[**See Filtering the Contents of a Backup or Restore for more information.**](../../../admin_guide/backup_restore/index.md#filter) +### --include-schema schema_name -`--include-schema `
-Optional. Specifies a database schema to include in the backup. You can specify this option multiple times to include multiple schemas. If you specify this option, any schemas that are not included in subsequent `--include-schema` options are omitted from the backup set. You cannot combine this option with the options `--exclude-schema`, `--exclude-schema-file`,` --exclude-schema-file`, `--include-table`, or `--include-table-file`. See Filtering the Contents of a Backup or Restore for more information. +Optional. Specifies a database schema to include in the backup. You can specify this option multiple times to include multiple schemas. If you specify this option, any schemas that are not included in subsequent `--include-schema` options are omitted from the backup set. You cannot combine this option with the options `--exclude-schema`, `--exclude-schema-file`, `--include-table`, or `--include-table-file`. -`--include-schema-file `
-Optional. Specifies a text file containing a list of schemas to back up. Each line in the text file must define a single schema. The file must not include trailing lines. If a schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. +See [Filtering backups and restores](../using.md#filtering-backups-and-restores) for more information. -[**See Filtering the Contents of a Backup or Restore for more information.**](../../../admin_guide/backup_restore/index.md#filter) +### --include-schema-file file_name -`--include-table `
-Optional. Specifies a table to include in the backup. The table must be in the format `.`. +Optional. Specifies a text file containing a list of schemas to back up. Each line in the text file must define a single schema. The file must not include trailing lines. If a schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. -You can specify this option multiple times. You cannot combine this option with a schema filtering option such as` --include-schema`, or another table filtering option such as `--exclude-table-file`. +See [Filtering backups and restores](../using.md#filtering-backups-and-restores) for more information. + +### --include-table schema.table + +Optional. Specifies a table to include in the backup. The table must be in the format `.`. You can specify this option multiple times. You cannot combine this option with a schema filtering option such as `--include-schema`, or another table filtering option such as `--exclude-table-file`. You can also specify the qualified name of a sequence, a view, or a materialized view. -If you specify this option, the utility does not automatically back up dependent objects. You must also explicitly specify dependent objects that are Required. For example if you back up a view or a materialized view, you must also back up the tables that the view or materialized view uses. If you back up a table that uses a sequence, you must also back up the sequence. +If you specify this option, the utility does not automatically back up dependent objects. You must also explicitly specify dependent objects that are required. For example, if you back up a view or a materialized view, you must also back up the tables that the view or materialized view uses. If you back up a table that uses a sequence, you must also back up the sequence. + +You can optionally specify a table leaf partition name in place of the table name, to include only specific leaf partitions in a backup with the `--leaf-partition-data` option. When a leaf partition is backed up, the leaf partition data is backed up along with the metadata for the partitioned table. -You can optionally specify a table leaf partition name in place of the table name, to include only specific leaf partitions in a backup with the `--leaf-partition-dat`a option. When a leaf partition is backed up, the leaf partition data is backed up along with the metadata for the partitioned table. +See [Filtering backups and restores](../using.md#filtering-backups-and-restores) for more information. -### See Filtering the Contents of a Backup or Restore for more information. +### --include-table-file file_name -`--include-table-file `
-Optional. Specifies a text file containing a list of tables to include in the backup. Each line in the text file must define a single table using the format `.`. The file must not include trailing lines. For information on specifying special characters in schema and table names, see Schema and Table Names. +Optional. Specifies a text file containing a list of tables to include in the backup. Each line in the text file must define a single table using the format `.`. The file must not include trailing lines. If a table or schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. -Any tables not listed in this file are omitted from the backup set. You cannot combine this option with a schema filtering option such as `--include-schem`a, or another table filtering option such as `--exclude-table-file`. +Any tables not listed in this file are omitted from the backup set. You cannot combine this option with a schema filtering option such as `--include-schema`, or another table filtering option such as `--exclude-table-file`. You can also specify the qualified name of a sequence, a view, or a materialized view. -If you specify this option, the utility does not automatically back up dependent objects. You must also explicitly specify dependent objects that are Required. For example if you back up a view or a materialized view, you must also specify the tables that the view or the materialized view uses. If you specify a table that uses a sequence, you must also specify the sequence. +If you specify this option, the utility does not automatically back up dependent objects. You must also explicitly specify dependent objects that are required. For example, if you back up a view or a materialized view, you must also specify the tables that the view or the materialized view uses. If you specify a table that uses a sequence, you must also specify the sequence. You can optionally specify a table leaf partition name in place of the table name, to include only specific leaf partitions in a backup with the `--leaf-partition-data` option. When a leaf partition is backed up, the leaf partition data is backed up along with the metadata for the partitioned table. -### See Filtering the Contents of a Backup or Restore for more information. +See [Filtering backups and restores](../using.md#filtering-backups-and-restores) for more information. + +### --incremental -`--incremental`
Specify this option to add an incremental backup to an incremental backup set. A backup set is a full backup and one or more incremental backups. The backups in the set must be created with a consistent set of backup options to ensure that the backup set can be used in a restore operation. +You must specify `--leaf-partition-data` with this option. You cannot combine this option with `--data-only` or `--metadata-only`. + By default, `gpbackup` attempts to find the most recent existing backup with a consistent set of options. If the backup is a full backup, the utility creates a backup set. If the backup is an incremental backup, the utility adds the backup to the existing backup set. The incremental backup is added as the latest backup in the backup set. You can specify `--from-timestamp` to override the default behavior. -> `--from-timestamp `
-> Optional. Specifies the timestamp of a backup. The specified backup must have backup options that are consistent with the incremental backup that is >being created. If the specified backup is a full backup, the utility creates a backup set. If the specified backup is an incremental backup, the >utility adds the incremental backup to the existing backup set. -> -> You must specify `--leaf-partition-dat`a with this option. You cannot combine this option with` --data-only` or `--metadata-only`. -> -> A backup is not created and the utility returns an error if the backup cannot add the backup to an existing incremental backup set or cannot use the >backup to create a backup set. +See [Creating incremental backups of append-optimized tables](../incremental.md) for more information. + +#### --from-timestamp backup-timestamp -**For information about creating and using incremental backups, see Creating and Using Incremental Backups with gpbackup and gprestore.** +Optional. Specifies the timestamp of a backup. The specified backup must have backup options that are consistent with the incremental backup that is being created. If the specified backup is a full backup, the utility creates a backup set. If the specified backup is an incremental backup, the utility adds the incremental backup to the existing backup set. + +A backup is not created and the utility returns an error if the backup cannot add the backup to an existing incremental backup set or cannot use the backup to create a backup set. + +### --jobs int -`--jobs `
Optional. Specifies the number of jobs to run in parallel when backing up tables. By default, `gpbackup` uses 1 job (database connection). Increasing this number can improve the speed of backing up data. When running multiple jobs, each job backs up tables in separate transactions. Important: If you specify a value higher than 1, the database should be in a quiescent state while the utility acquires a lock on the tables that are being backed up. If the utility cannot acquire a lock on a table being backed up it will exit. -You cannot use this option in combination with the options `--metadata-only`,` --single-data-file`, or `--plugin-config`. +You cannot use this option in combination with the options `--metadata-only` or `--single-data-file`. -:::info Note -This option must be used with the `--single-data-file` option and cannot be used with the `--jobs` option. -When using the `--jobs` flag, there is a potential deadlock scenario to generate a WARNING message in the log files. During the metadata portion of the backup, the main worker process gathers Access Share locks on all the tables in the backup set. During the data portion of the backup, based on the value of the `--jobs` flag, additional workers are created that attempt to take additional Access Share locks on the tables they back up. - -Between the metadata backup and the data backup, if a third party process (operations like `TRUNCATE`, `DROP`, `ALTER`) attempts to access the same tables and obtain an `Exclusive` lock, the worker thread identifies the potential deadlock and hands off the table backup responsibilities to the main worker (that already has an `Access Share` lock on that particular table). A warning message is logged, similar to: `[WARNING]:-Worker 5 could not acquire AccessShareLock for table public.foo.` +::: info Note +If a third-party process (`TRUNCATE`, `DROP`, `ALTER`) takes an `Exclusive` lock on a table between the metadata and data phases, the worker hands that table off to the main worker instead of failing, and logs a warning like `[WARNING]:-Worker 5 could not acquire AccessShareLock for table public.foo.` ::: -`--leaf-partition-data`
-Optional. For partitioned tables, creates one data file per leaf partition instead of one data file for the entire table (the default). Using this option also enables you to specify individual leaf partitions to include in or exclude from a backup, with the `--include-table, `--include-table-file`, `--exclude-table`, and `--exclude-table-file\` options. +### --leaf-partition-data + +Optional. For partitioned tables, creates one data file per leaf partition instead of one data file for the entire table (the default). Using this option also enables you to specify individual leaf partitions to include in or exclude from a backup, with the `--include-table`, `--include-table-file`, `--exclude-table`, and `--exclude-table-file` options. + +### --metadata-only -`--metadata-only`
Optional. Creates only the metadata files (DDL) needed to recreate the database objects, but does not back up the actual table data. -`--no-compression`
+You cannot combine this option with `--data-only`, `--incremental`, or `--leaf-partition-data`. + +### --no-compression + Optional. Do not compress the table data CSV files. -`--no-history`
+### --no-history + Optional. When invoked, `gpbackup` does not write backup run metadata to the history database. This is useful if you prefer not to have an application-maintained SQLite database on your system. However, if you choose not to back up to the history database you lose access to the features of the gpbackup_manager utility. -`--no-inherits`
+### --no-inherits + Optional. Only works when invoked with either the `--include-table` option or the `--include-table-file` option. When invoked, only the metadata of the table itself is backed up, ignoring any inheritance relationships with other tables that would normally cause those tables to also be included in the backup set. -`--plugin-config `
+### --plugin-config config-file_location + Specify the location of the `gpbackup` plugin configuration file, a YAML-formatted text file. The file contains configuration information for the plugin application that `gpbackup` uses during the backup operation. If you specify the `--plugin-config` option when you back up a database, you must specify this option with configuration information for a corresponding plugin application when you restore the database from the backup. You cannot combine this option with the option `--backup-dir`. -### For information about using storage plugin applications, see Using gpbackup Storage Plugins. +See [Using the S3 storage plugin](../s3-plugin.md) for information about using a storage plugin. + +### --quiet -`--quiet`
Optional. Suppress all non-warning, non-error log messages. -`--single-backup-dir`
-Optional. Store all backup files on a given host in a single directory rather than in distinct per-segment subdirectories under the chosen backup directory. For example, files that were previously created in the `/gpseg0/backups//` or `/gpseg1/backups//` directories will now be created under `/backups//`. You may restore backups taken with this option as normal, but there will be a performance penalty when doing so on some systems. However, this protects you from having to manually reorganize files to the correct segment when you pass the `--resize-cluster` restore option to gprestore. +### --single-backup-dir + +Optional. Store all backup files on a given host in a single directory rather than in distinct per-segment subdirectories under the chosen backup directory. For example, files that were previously created in the `/gpseg0/backups//` or `/gpseg1/backups//` directories will now be created under `/backups//`. You may restore backups taken with this option as normal, but there will be a performance penalty when doing so on some systems. However, this protects you from having to manually reorganize files to the correct segment when you pass the `--resize-cluster` restore option to `gprestore`. + You must use the `--backup-dir` option with this option. -`--single-data-file`
+### --single-data-file + Optional. Create a single data file on each segment host for all tables backed up on that segment. By default, each `gpbackup` creates one compressed CSV file for each table that is backed up on the segment. -:::info Note +::: info Note If you use the `--single-data-file` option to combine table backups into a single file per segment, you cannot set the gprestore option `--jobs` to a value higher than 1 to perform a parallel restore operation. ::: -`--verbose`
+### --verbose + Optional. Print verbose log messages. -`--version`
+### --version + Optional. Print the version number and exit. -`--with-stats`
+### --with-stats + Optional. Include query plan statistics in the backup set. -`--without-globals`
+### --without-globals + Optional. Omit the global WarehousePG system objects during backup. -`--help`
-Displays the online help. +### --help - +Displays the online help. ## Examples -To create the database `test` using the default options: +To take a full backup: ``` -createdb test +gpbackup --dbname ww_sales --compression-type zstd ``` -To create the database `demo` using the WarehousePG coordinator on host `gpcoord`, port `54321`, using the `LATIN1` encoding scheme: +To take a full backup with a consolidated, single data file per segment: ``` -createdb -p 54321 -h gpcoord -E LATIN1 demo +gpbackup --dbname ww_sales --single-data-file --no-compression --backup-dir /tmp/single_file ``` -## See Also +To back up only the `emea_customer` schema: + +``` +gpbackup --dbname ww_sales --include-schema emea_customer +``` -[gprestore](gprestore.md) +To take an incremental backup, which requires `--leaf-partition-data`: + +``` +gpbackup --dbname ww_sales --incremental --backup-dir /nfsmount/whpg_backups/ww_sales --leaf-partition-data +``` diff --git a/docs/whpg/7x/ref_guide/utility_guide/reference/gprestore.md b/docs/whpg-backup/reference/gprestore.md similarity index 66% rename from docs/whpg/7x/ref_guide/utility_guide/reference/gprestore.md rename to docs/whpg-backup/reference/gprestore.md index c04f10c..aa273ac 100644 --- a/docs/whpg/7x/ref_guide/utility_guide/reference/gprestore.md +++ b/docs/whpg-backup/reference/gprestore.md @@ -3,9 +3,7 @@ title: gprestore --- -Restore a WarehousePG backup set that was created using the `gpbackup` utility. By default `gprestore` will read the metadata and DDL files located in the Coordinator host data directory, and will load the CSV formatted table data stored locally on each segment hosts. - - +Restore a WarehousePG backup set that was created using the `gpbackup` utility. By default `gprestore` will read the metadata and DDL files located in the Coordinator host data directory, and will load the CSV formatted table data stored locally on each segment hosts. ## Synopsis @@ -16,19 +14,21 @@ gprestore --timestamp [--create-db] [--data-only] [--debug] + [--exclude-extension [--exclude-extension ...]] [--exclude-schema [--exclude-schema ...]] [--exclude-schema-file ] [--exclude-table [--exclude-table ...]] [--exclude-table-file ] [--help] + [--ignore-plugin-config] [--include-schema [--include-schema ...]] [--include-schema-file ] [--include-table [--include-table ...]] [--include-table-file ] [--incremental] [--jobs ] - [--metadata-only] - [--on-error-continue] + [--metadata-only] + [--on-error-continue] [--plugin-config ] [--quiet] [--redirect-db ] @@ -47,99 +47,96 @@ gprestore --timestamp gprestore --help ``` - `gpbackup` [reference](gpbackup.md) - - +`gpbackup` [reference](gpbackup.md) ## Description -To use `gprestore` to restore from a backup set, you must include the `--timestamp` option to specify the exact timestamp value (`YYYYMMDDHHMMSS`) of the backup set to restore. If you specified a custom `--backup-dir` to consolidate the backup files, include the same `--backup-dir` option with `gprestore` to locate the backup files. - -If the backup you specify is an incremental backup, you need a complete set of backup files (a full backup and any required incremental backups). `gprestore` ensures that the complete backup set is available before attempting to restore a backup. - -Important: For incremental backup sets, the backups must be on a single device. For example, a backup set must all be on a Data Domain system. - -When restoring from a backup set, `gprestore` restores to a database with the same name as the name specified when creating the backup set. If the target database exists and a table being restored exists in the database, the restore operation fails. Include the `--create-db` option if the target database does not exist in the cluster. You can optionally restore a backup set to a different database by using the `--redirect-db` option. - -When restoring a backup set that contains data from some leaf partitions of a partitioned tables, the partitioned table is restored along with the data for the leaf partitions. For example, you create a backup with the `gpbackup` option `--include-table-file` and the text file lists some leaf partitions of a partitioned table. Restoring the backup creates the partitioned table and restores the data only for the leaf partitions listed in the file. - -By default, only database objects in the backup set are restored. WarehousePG system objects are automatically included in a `gpbackup` backup set, but these objects are only restored if you include the `--with-globals` option to `gprestore`. - -During a restore operation, automatic updating of table statistics is deactivated for the tables being restored. If you backed up query plan statistics using the `--with-stats` option, you can restore those statistics by providing `--with-stats` to `gprestore`. If you did not use `--with-stats` during a backup, or you want to collect current statistics during the restore operation, you can use the `--run-analyze` option to run `ANALYZE` on the restored tables. - -When a materialized view is restored, the data is not restored. To populate the materialized view with data, use `REFRESH MATERIALIZED VIEW`. The tables that are referenced by the materialized view definition must be available. The `gprestore` log file lists the materialized views that were restored and the `REFRESH MATERIALIZED VIEW` commands that are used to populate the materialized views with data. +To restore from a backup set, run `gprestore` with the `--timestamp` option to specify the exact timestamp (`YYYYMMDDHHMMSS`) of the backup set to restore. If the backup used a custom `--backup-dir`, include the same option here to locate the files. For a full walkthrough, see [Backing up and restoring your tables](../using.md). -Performance of restore operations can be improved by creating multiple parallel connections to restore table data and metadata. By default `gprestore` uses 1 connection, but you can increase this number with the `--jobs` option for large restore operations. - -When a restore operation completes, `gprestore` returns a status code. - -`gprestore` can send status email notifications after a back up operation completes. You specify when the utility sends the mail and the email recipients in a configuration file. - -Note: This utility uses secure shell (SSH) connections between systems to perform its tasks. In large WarehousePG deployments, cloud deployments, or deployments with a large number of segments per host, this utility may exceed the host's maximum threshold for unauthenticated connections. Consider updating the SSH `MaxStartups` and `MaxSessions` configuration parameters to increase this threshold. For more information about SSH configuration options, refer to the SSH documentation for your Linux distribution. - - +::: info Note +- If you're restoring an incremental backup, you need the complete backup set. See [Restoring incremental backup sets](../incremental.md#restoring-incremental-backup-sets). +- If the target database already exists and contains a table being restored, the restore operation fails. Include `--create-db` if the target database doesn't exist, or `--redirect-db` to restore into a different one. +- Leaf partition filtering affects what gets restored. See [Filtering backups by leaf partition](../using.md#filtering-backups-by-leaf-partition). +- On completion, `gprestore` returns a status code. See [Return codes](#return-codes). +- `gprestore` can send status email notifications after it completes. See [Setting up email alerts](../using.md#setting-up-email-alerts). +- This utility uses SSH connections between hosts, with the same considerations as [gpbackup](gpbackup.md#description). +::: ## Options -##### --timestamp YYYYMMDDHHMMSS +### --timestamp YYYYMMDDHHMMSS Required. Specifies the timestamp of the `gpbackup` backup set to restore. By default `gprestore` tries to locate metadata files for the timestamp on the WarehousePG Coordinator host in the $COORDINATOR_DATA_DIRECTORY/backups/YYYYMMDD/YYYYMMDDhhmmss/ directory, and CSV data files in the `/backups/YYYYMMDD/YYYYMMDDhhmmss/` directory of each segment host. -##### --backup-dir directory +### --backup-dir directory Optional. Sources all backup files (metadata files and data files) from the specified directory. You must specify directory as an absolute path (not relative). If you do not supply this option, `gprestore` tries to locate metadata files for the timestamp on the WarehousePG Coordinator host in the $COORDINATOR_DATA_DIRECTORY/backups/YYYYMMDD/YYYYMMDDhhmmss/ directory. CSV data files must be available on each segment in the `/backups/YYYYMMDD/YYYYMMDDhhmmss/` directory. Include this option when you specify a custom backup directory with `gpbackup`. You cannot combine this option with the option `--plugin-config`. -##### --copy-queue-size int +### --copy-queue-size int Optional. Specifies the number of `COPY` commands `gprestore` should enqueue when restoring a backup set. This option optimizes restore performance by reducing the amount of time spent initializing `COPY` commands. If you do not set this option to 2 or greater, `gprestore` enqueues 1 `COPY` command at a time. -##### --create-db +### --create-db Optional. Creates the database before restoring the database object metadata. The database is created by cloning the empty standard system database `template0`. -##### --data-only +You cannot combine this option with `--data-only`. + +### --data-only Optional. Restores table data from a backup created with the `gpbackup` utility, without creating the database tables. This option assumes the tables exist in the target database. To restore data for a specific set of tables from a backup set, you can specify an option to include tables or schemas or exclude tables or schemas. Specify the `--with-stats` option to restore table statistics from the backup. +You cannot combine this option with `--with-globals` or `--create-db`. Global metadata is not backed up in table-filtered or data-only backups. + The backup set must contain the table data to be restored. For example, a backup created with the `gpbackup` option `--metadata-only` does not contain table data. `SEQUENCE` values are updated to match the values taken at the time of the backup. To restore only database tables, without restoring the table data, see the option `--metadata-only`. -##### --debug +### --debug Optional. Displays verbose and debug log messages during a restore operation. -##### --exclude-schema schema_name +### --exclude-extension extension_name + +Optional. Skip restoring the specified extension. You can specify this option multiple times to exclude multiple extensions. Use this option when, for example, the extension's control file isn't installed on the target cluster. + +If the extension owns a schema of the same name in the backup set, `gprestore` also excludes that schema, since the schema exists only as a side effect of creating the extension. You cannot combine this option with `--redirect-schema`. -Optional. Specifies a database schema to exclude from the restore operation. You can specify this option multiple times. You cannot combine this option with the option `--include-schema`, `--include-schema-file`, or a table filtering option such as `--include-table`. +### --exclude-schema schema_name -##### --exclude-schema-file file_name +Optional. Specifies a database schema to exclude from the restore operation. You can specify this option multiple times. You cannot combine this option with the option `--include-schema`, `--include-schema-file`, or a table filtering option such as `--include-table`. + +### --exclude-schema-file file_name Optional. Specifies a text file containing a list of schemas to exclude from the backup. Each line in the text file must define a single schema. The file must not include trailing lines. If a schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. You cannot combine this option with the option `--include-schema` or `--include-schema-file`, or a table filtering option such as `--include-table`. -##### --exclude-table schema.table +### --exclude-table schema.table Optional. Specifies a table to exclude from the restore operation. You can specify this option multiple times. The table must be in the format `.`. If a table or schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. You can specify this option multiple times. If the table is not in the backup set, the restore operation fails. You cannot specify a leaf partition of a partitioned table. You cannot combine this option with the option `--exclude-schema`, `--exclude-schema-file`, or another a table filtering option such as `--include-table`. -##### --exclude-table-file file_name +### --exclude-table-file file_name Optional. Specifies a text file containing a list of tables to exclude from the restore operation. Each line in the text file must define a single table using the format `.`. The file must not include trailing lines. If a table or schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. If a table is not in the backup set, the restore operation fails. You cannot specify a leaf partition of a partitioned table. You cannot combine this option with the option `--exclude-schema`, `--exclude-schema-file`, or another a table filtering option such as `--include-table`. -##### --help +### --help Displays the online help. -##### --include-schema schema_name +### --ignore-plugin-config + +Optional. Restore from the local filesystem instead of the plugin recorded in the backup, for backups where the files are already reachable directly (for example, through a BoostFS mount). You cannot combine this option with `--plugin-config`. + +### --include-schema schema_name Optional. Specifies a database schema to restore. You can specify this option multiple times. If you specify this option, any schemas that you specify must be available in the backup set. Any schemas that are not included in subsequent `--include-schema` options are omitted from the restore operation. @@ -147,7 +144,7 @@ If a schema that you specify for inclusion exists in the database, the utility i You cannot use this option if objects in the backup set have dependencies on multiple schemas. -##### --include-schema-file file_name +### --include-schema-file file_name Optional. Specifies a text file containing a list of schemas to restore. Each line in the text file must define a single schema. The file must not include trailing lines. If a schema name uses any character other than a lowercase letter, number, or an underscore character, then you must include that name in double quotes. @@ -155,7 +152,7 @@ The schemas must exist in the backup set. Any schemas not listed in this file ar You cannot use this option if objects in the backup set have dependencies on multiple schemas. -##### --include-table schema.table +### --include-table schema.table Optional. Specifies a table to restore. The table must be in the format `.`. You can specify this option multiple times. You cannot specify a leaf partition of a partitioned table. @@ -165,7 +162,7 @@ If you specify this option, the utility does not automatically restore dependent You cannot combine this option with a schema filtering option such as `--include-schema`, or another table filtering option such as `--exclude-table-file`. -##### --include-table-file file_name +### --include-table-file file_name Optional. Specifies a text file containing a list of tables to restore. Each line in the text file must define a single table using the format `.`. The file must not include trailing lines. Any tables not listed in this file are omitted from the restore operation. You cannot specify a leaf partition of a partitioned table. @@ -177,9 +174,13 @@ For a materialized view, the data is not restored. To populate the materialized If you use the `--include-table-file` option, `gprestore` does not create roles or set the owner of the tables. The utility restores table indexes and rules. Triggers are also restored but are not supported in WarehousePG. -##### --incremental +### --incremental -Optional. Requires the `--data-only option`. Restores only the table data in the incremental backup specified by the `--timestamp` option. Table data is not restored from previous incremental backups in the backup set. **Warning:** This is a Beta feature and is not supported in a production environment. +Optional. Requires the `--data-only` option. Restores only the table data in the incremental backup specified by the `--timestamp` option. Table data is not restored from previous incremental backups in the backup set. + +::: warning +This is a beta feature and isn't supported in a production environment. +::: An incremental backup contains the following table data that can be restored. @@ -191,27 +192,21 @@ When this option is specified, `gprestore` restores table data by truncating the Before performing the restore operation, `gprestore` ensures that the tables being restored exist. If a table does not exist, `gprestore` returns an error and exits. If the `--on-error-continue` option is specified, `gprestore` logs missing tables and attempts to complete the restore operation. -:::info Warning -When this option is specified, `gpbackup` assumes that no changes have been made to the table definitions of the tables being restored, such as adding or removing columns.--truncate-table +::: warning +When this option is specified, `gprestore` assumes that no changes have been made to the table definitions of the tables being restored, such as adding or removing columns. ::: -Optional. Truncate data from a set of tables before restoring the table data from a backup. This option lets you replace table data with data from a backup. Otherwise, table data might be duplicated. - -You must specify the set of tables with either the option `--include-table` or `--include-table-file`. You must also specify `--data-only` to restore table data without creating the tables. - -You can use this option with the `--redirect-db` option. You cannot use this option with `--redirect-schema`. - -##### --jobs int +### --jobs int Optional. Specifies the number of parallel connections to use when restoring table data and metadata. By default, `gprestore` uses 1 connection. Increasing this number can improve the speed of restoring data. **Note:** If you used the `gpbackup --single-data-file` option to combine table backups into a single file per segment, you cannot set `--jobs` to a value higher than 1 to perform a parallel restore operation. -##### --metadata-only +### --metadata-only Optional. Creates database tables from a backup created with the `gpbackup` utility, but does not restore the table data. This option assumes the tables do not exist in the target database. To create a specific set of tables from a backup set, you can specify an option to include tables or schemas or exclude tables or schemas. Specify the option `--with-globals` to restore the WarehousePG system objects. The backup set must contain the DDL for tables to be restored. For example, a backup created with the `gpbackup` option `--data-only` does not contain the DDL for tables. -##### --on-error-continue +### --on-error-continue Optional. Specify this option to continue the restore operation if an SQL error occurs when creating database metadata (such as tables, roles, or functions) or restoring data. If another type of error occurs, the utility exits. The default is to exit on the first error. @@ -220,81 +215,81 @@ When this option is included, the utility displays an error summary and writes e - Tables with metadata errors - `gprestore___error_tables_metadata` - Tables with data errors - `gprestore___error_tables_data` -##### --plugin-config config-file_location +### --plugin-config config-file_location Specify the location of the `gpbackup` plugin configuration file, a YAML-formatted text file. The file contains configuration information for the plugin application that `gprestore` uses during the restore operation. If you specify the `--plugin-config` option when you back up a database, you must specify this option with configuration information for a corresponding plugin application when you restore the database from the backup. -You cannot combine this option with the option `--backup-dir`. +You cannot combine this option with the option `--backup-dir` or `--ignore-plugin-config`. -##### --quiet +### --quiet Optional. Suppress all non-warning, non-error log messages. -##### --redirect-db database_name +### --redirect-db database_name Optional. Restore to the specified database_name instead of to the database that was backed up. -##### --redirect-schema schema_name +### --redirect-schema schema_name Optional. Restore data in the specified schema instead of the original schemas. The specified schema must already exist. If the data being restored is in multiple schemas, all the data is redirected into the specified schema. This option must be used with an option that includes tables or schemas: `--include-table`, `--include-table-file`, `--include-schema`, or `--include-schema-file`. -You cannot use this option with an option that excludes schemas or tables such as `--exclude-schema` or `--exclude-table`. +You cannot use this option with an option that excludes schemas or tables, such as `--exclude-schema`, `--exclude-table`, or `--exclude-extension`. You can use this option with the `--metadata-only` or `--data-only` options. -##### --report-dir /path/to/report +### --report-dir /path/to/report Optional. The absolute path of the directory to which restore report and error tables will be written. -##### --resize-cluster +### --resize-cluster Optional. Invoke this option to enable restoring data to a cluster that has a different number of segments than the cluster from which the data was backed up. -Warning: This is a Beta feature and is not supported in a production environment. - -:::info Note -In order to enable the `--resize-cluster` feature for `gprestore`, the backup set must have been taking using using `gpbackup` 1.26 or later. +::: info Note +In order to enable the `--resize-cluster` feature for `gprestore`, the backup set must have been taken using `gpbackup` 1.26 or later. ::: -##### --run-analyze +### --run-analyze Optional. Run `ANALYZE` on the tables that are restored. For a partitioned table, `ANALYZE` is run on the root partitioned table. If `--with-stats` was specified for the backup, those statistics are ignored. You cannot use this option with `--with-stats`. If the backup being restored used the `gpbackup` option `--leaf-partition-data`, `gprestore` runs `ANALYZE` only on the individual leaf partitions that are restored, not the root partitioned table. -Depending the tables being restored, running `ANALYZE` on restored tables might increase the duration of the restore operation. +Depending on the tables being restored, running `ANALYZE` on restored tables might increase the duration of the restore operation. -##### --timestamp YYYYMMDDHHMMSS +### --truncate-table -Required. Specifies the timestamp of the `gpbackup` backup set to restore. By default `gprestore` tries to locate metadata files for the timestamp on the WarehousePG Coordinator host in the $COORDINATOR_DATA_DIRECTORY/backups/YYYYMMDD/YYYYMMDDhhmmss/ directory, and CSV data files in the `/backups/YYYYMMDD/YYYYMMDDhhmmss/` directory of each segment host. +Optional. Truncate data from a set of tables before restoring the table data from a backup. This option lets you replace table data with data from a backup. Otherwise, table data might be duplicated. -##### --truncate-table +You must specify at least one of `--include-table`, `--include-table-file`, or `--data-only`. You cannot combine this option with `--metadata-only` or `--incremental`. -Optional. Removes existing data from the tables being restored, to eliminate the chance of duplicate data. +You can use this option with the `--redirect-db` option. You cannot use this option with `--redirect-schema`. -##### --verbose +### --verbose -Optional. Displays verbose log messages during a restore operation.--versionOptional. Print the version number and exit. +Optional. Displays verbose log messages during a restore operation. -##### --version +### --version -Optional. Displays the verison of the gprestore utility. +Optional. Print the version number and exit. -##### --with-globals +### --with-globals Optional. Restores WarehousePG system objects in the backup set, in addition to database objects. -##### --with-stats +You cannot combine this option with `--data-only`. + +### --with-stats Optional. Restore query plan statistics from the backup set. If the backup set was not created with the `--with-stats` option, an error is returned. Restored tables will only have statistics from the backup. You cannot use this option with `--run-analyze`. To collect current statistics for the restored tables during the restore operation, use the `--run-analyze` option. As an alternative, you can run the `ANALYZE` command on the tables after the tables are restored. -## Return Codes +## Return codes One of these codes is returned after `gprestore` completes. @@ -302,62 +297,52 @@ One of these codes is returned after `gprestore` completes. - 1 -- Restore completed with non-fatal errors. See log file for more information. - 2 -- Restore failed with a fatal error. See log file for more information. - - ## Examples -Create the ww_customer database and restore all schemas and tables in the backup set for the indicated timestamp: +Restore all schemas and tables in the backup set for the specified timestamp, creating the target database: ``` -$ dropdb ww_customer -$ gprestore --timestamp 20250515182209 --create-db +gprestore --timestamp 20250515182209 --create-db ``` -Restore the backup set to the "customer" database instead of the "demo" database that was backed up: +Restore the backup set into the `customer` database instead of the database that was backed up: ``` -$ createdb customer -$ gprestore --timestamp 20250515182209 --redirect-db customer +gprestore --timestamp 20250515182209 --redirect-db customer ``` Restore global WarehousePG metadata and query plan statistics in addition to the database objects: ``` -$ gprestore --timestamp 20250515182209 --create-db --with-globals --with-stats +gprestore --timestamp 20250515182209 --create-db --with-globals --with-stats ``` -Restore, using backup files that were created in the /mnt/nfs/wwhpg_backups directory, creating 8 parallel connections: +Restore using backup files from a custom directory, with 8 parallel connections: ``` -$ gprestore --backup-dir /mnt/nfs/whpg_backups/ --timestamp 20250515182209 --create-db --jobs 8 +gprestore --backup-dir /mnt/nfs/whpg_backups/ --timestamp 20250515182209 --create-db --jobs 8 ``` Restore only the `emea_customer` schema included in the backup set: ``` -$ dropdb ww_customer -$ gprestore --include-schema emea_customer --backup-dir /mnt/nfs/whpg_backups/ --timestamp 20250515182209 --create-db +gprestore --include-schema emea_customer --backup-dir /mnt/nfs/whpg_backups/ --timestamp 20250515182209 --create-db ``` -If you restore from an incremental backup set, all the required files in the backup set must be available to `gprestore`. For example, the following timestamp keys specify an incremental backup set. 20250518010000 - is the full backup and the others are incremental backups. +If you restore from an incremental backup set, every earlier backup in the set must be available to `gprestore`. For example, this backup set has a full backup on Sunday and six incremental backups through Saturday: ``` 20250518010000 (full backup, Sunday 1am) 20250519020000 (incremental backup, Monday 2am) 20250520030000 (incremental backup, Tuesday 3am) -20250521040000 (incremental backup, Wedndesday 4am) +20250521040000 (incremental backup, Wednesday 4am) 20250522050000 (incremental backup, Thursday 5am) 20250523060000 (incremental backup, Friday 6am) 20250524070000 (incremental backup, Saturday 7am) ``` -The following `gprestore` command specifies the timestamp `20250521040000` (Wednesday). The incremental backup with the timestamps `20250520030000` (Tuesday), `20250519020000` (Monday) and the full backup `20250518010000` (Sunday) must be available to perform a restore. +Restoring the Wednesday timestamp requires the Monday and Tuesday incremental backups and the Sunday full backup to also be available: ``` -$ gprestore --timestamp 20250521040000 --redirect-db customer_incra --create-db +gprestore --timestamp 20250521040000 --redirect-db customer_incr --create-db ``` - -## See Also - -[gpbackup](gpbackup.md) diff --git a/docs/whpg-backup/reference/index.md b/docs/whpg-backup/reference/index.md new file mode 100644 index 0000000..adb5245 --- /dev/null +++ b/docs/whpg-backup/reference/index.md @@ -0,0 +1,9 @@ +--- +title: WarehousePG Backup and Restore reference + +--- + +Command reference for WarehousePG Backup and Restore. + +- [gpbackup](gpbackup.md) covers the `gpbackup` command and its options. +- [gprestore](gprestore.md) covers the `gprestore` command, its options, and the return codes shared by both utilities. diff --git a/docs/whpg-backup/release_notes/1.31.0_rel_notes.md b/docs/whpg-backup/release_notes/1.31.0_rel_notes.md new file mode 100644 index 0000000..2b38de5 --- /dev/null +++ b/docs/whpg-backup/release_notes/1.31.0_rel_notes.md @@ -0,0 +1,13 @@ +--- +title: WarehousePG Backup and Restore 1.31.0 release notes + +--- + +**Release date:** January 29, 2026 + +WarehousePG Backup and Restore 1.31.0 includes security fixes. + +## Security + +- Mitigated SQL injection risks by using parameterized queries. +- Fixed a security vulnerability. diff --git a/docs/whpg-backup/release_notes/1.32.0_rel_notes.md b/docs/whpg-backup/release_notes/1.32.0_rel_notes.md new file mode 100644 index 0000000..f2f828d --- /dev/null +++ b/docs/whpg-backup/release_notes/1.32.0_rel_notes.md @@ -0,0 +1,16 @@ +--- +title: WarehousePG Backup and Restore 1.32.0 release notes + +--- + +**Release date:** January 29, 2026 + +WarehousePG Backup and Restore 1.32.0 includes a change and an improvement. + +## Changes + +- **Extension-owned access methods:** `gpbackup` no longer includes extension-owned access methods in a backup. + +## Improvements + +- **Help text on empty invocation:** `gprestore` now prints help text when run without any options. diff --git a/docs/whpg-backup/release_notes/1.32.1_rel_notes.md b/docs/whpg-backup/release_notes/1.32.1_rel_notes.md new file mode 100644 index 0000000..dc7e30e --- /dev/null +++ b/docs/whpg-backup/release_notes/1.32.1_rel_notes.md @@ -0,0 +1,22 @@ +--- +title: WarehousePG Backup and Restore 1.32.1 release notes + +--- + +**Release date:** January 29, 2026 + +WarehousePG Backup and Restore 1.32.1 includes a change, an improvement, and bug fixes. + +## Changes + +- **External tables as foreign tables:** `gpbackup` now backs up external tables as foreign tables for WarehousePG 7 and later. + +## Improvements + +- **Batch processing and parallel restore:** Improved batch processing coordination and parallel restore performance. + +## Bug fixes + +- Fixed a bug where `gprestore` reported `ERROR: .() is not a function`. +- Fixed an issue restoring materialized views that use the append-optimized (AO) or append-optimized, column-oriented (AOCS) access method. +- Fixed an issue backing up external partitioned tables when using the `--leaf-partition-data` option. diff --git a/docs/whpg-backup/release_notes/1.33.0_rel_notes.md b/docs/whpg-backup/release_notes/1.33.0_rel_notes.md new file mode 100644 index 0000000..83208bd --- /dev/null +++ b/docs/whpg-backup/release_notes/1.33.0_rel_notes.md @@ -0,0 +1,17 @@ +--- +title: WarehousePG Backup and Restore 1.33.0 release notes + +--- + +**Release date:** April 22, 2026 + +WarehousePG Backup and Restore 1.33.0 includes new features and a bug fix. + +## Features + +- **PGAA table support:** `gpbackup` and `gprestore` now back up and restore databases that mix Postgres Analytics Accelerator (PGAA) tables with regular heap tables, capturing only PGAA metadata rather than the underlying object storage data. +- Added support for `pg_extension_config_dump` in `gpbackup`. + +## Bug fixes + +- Fixed a nil pointer dereference in `DoCleanup` when backup directory creation fails. diff --git a/docs/whpg-backup/release_notes/1.33.1_rel_notes.md b/docs/whpg-backup/release_notes/1.33.1_rel_notes.md new file mode 100644 index 0000000..c9727e2 --- /dev/null +++ b/docs/whpg-backup/release_notes/1.33.1_rel_notes.md @@ -0,0 +1,17 @@ +--- +title: WarehousePG Backup and Restore 1.33.1 release notes + +--- + +**Release date:** May 21, 2026 + +WarehousePG Backup and Restore 1.33.1 includes a new feature and bug fixes. + +## Features + +- **`--ignore-plugin-config` option for `gprestore`:** Lets `gprestore` read plugin-backed backup files directly, without requiring `--plugin-config` or a hand-edited config YAML. + +## Bug fixes + +- Fixed a hang when backing up with `--single-data-file`. `gpbackup` no longer assumes that tables to back up have sorted object IDs (OIDs) in this mode. Previously, if an extension config table had a lower OID than user tables, the backup helper crashed and hung the backup procedure indefinitely. +- Fixed a hang in `TerminateHangingCopySessions` on WarehousePG 6. After the `pgx/v5` upgrade, terminating a hanging `COPY` session on WarehousePG 6 caused the driver to silently retry the `COPY` on a new connection, creating an orphaned session that deadlocked cleanup. `gpbackup` now cancels the backend instead of terminating it, avoiding the retry. diff --git a/docs/whpg-backup/release_notes/index.md b/docs/whpg-backup/release_notes/index.md new file mode 100644 index 0000000..4f03326 --- /dev/null +++ b/docs/whpg-backup/release_notes/index.md @@ -0,0 +1,14 @@ +--- +title: WarehousePG Backup and Restore release notes + +--- + +The WarehousePG Backup and Restore documentation describes the latest version, including minor releases and patches. The release notes provide information on what was new in each release. + +| Version | Release date | +|---------|--------------| +| [1.33.1](1.33.1_rel_notes.md) | 21 May 2026 | +| [1.33.0](1.33.0_rel_notes.md) | 22 Apr 2026 | +| [1.32.1](1.32.1_rel_notes.md) | 29 Jan 2026 | +| [1.32.0](1.32.0_rel_notes.md) | 29 Jan 2026 | +| [1.31.0](1.31.0_rel_notes.md) | 29 Jan 2026 | diff --git a/docs/whpg-backup/s3-plugin.md b/docs/whpg-backup/s3-plugin.md new file mode 100644 index 0000000..6c490e6 --- /dev/null +++ b/docs/whpg-backup/s3-plugin.md @@ -0,0 +1,142 @@ +--- +title: Using the S3 storage plugin + +--- + +Use the S3 storage plugin to write WarehousePG (WHPG) backups directly to Amazon Simple Storage Service (S3) or any S3-compatible storage server, and restore them without storing large dump files on local segment disks. Run the `gpbackup` and `gprestore` commands with the `--plugin-config` option and a YAML configuration file, using the same configuration file for both backup and restore. + +::: tip Associated topics +- [gpbackup & gprestore user guide](index.md) +- [Incremental backups](incremental.md) +- [gpbackup syntax reference](reference/gpbackup.md) +- [gprestore syntax reference](reference/gprestore.md) +::: + +## Installing the plugin + +The S3 plugin is a separate package from `whpg-backup`, built from the [`warehouse-pg/whpg-backup-s3-plugin`](https://github.com/warehouse-pg/whpg-backup-s3-plugin) repository. + +### Prerequisites + +Build the plugin on a host that has Go installed, at the version given by the `go` directive in the repository's `go.mod` file, or later. The WarehousePG coordinator works well as a build host, since `make install` distributes the binary to your cluster's segment hosts directly from there. + +### Building and installing + +1. Clone the repository and change into it: + + ```shell + git clone https://github.com/warehouse-pg/whpg-backup-s3-plugin.git + cd whpg-backup-s3-plugin + ``` + +1. Build the `gpbackup_s3_plugin` binary: + + ```shell + make build + ``` + + The binary is placed in `$GOPATH/bin`, or `$HOME/go/bin` if `GOPATH` isn't set. + +1. With the WarehousePG environment sourced, install the binary on all segment hosts: + + ```shell + make install + ``` + + The plugin executable must reside in the exact same absolute path on every WarehousePG host (coordinator and segments). + +1. Verify that the binary is present and executable on every host, for example using `gpssh` with the `all_hosts` file described in [Installing WarehousePG Backup and Restore](installing.md): + + ```shell + gpssh -f all_hosts -e "test -x \$GPHOME/bin/gpbackup_s3_plugin && echo ok" + ``` + +## Configuring the plugin + +The plugin requires a YAML configuration file located on the coordinator host. The file supports the following options: + +```yaml +executablepath: +options: + region: + endpoint: + aws_access_key_id: + aws_secret_access_key: + bucket: + folder: + encryption: [on|off] + http_proxy: + backup_max_concurrent_requests: [int] + backup_multipart_chunksize: [string] + restore_max_concurrent_requests: [int] + restore_multipart_chunksize: [string] +``` + +Where: + +- `executablepath`: Absolute path to the plugin, for example `$GPHOME/bin/gpbackup_s3_plugin`. +- `region`: AWS region (ignored if `endpoint` is specified). +- `endpoint`: Custom S3-compatible endpoint. +- `aws_access_key_id`: Your AWS/S3 access key. +- `aws_secret_access_key`: Your AWS/S3 secret key. +- `bucket`: The target S3 bucket (must already exist). +- `folder`: The backup sub-location. Created automatically if missing. +- `encryption`: Enables SSL for the S3 connection. Default is `on`. +- `http_proxy`: (Optional) If your WarehousePG segments do not have direct internet access, provide the URL of your corporate proxy server (e.g., http://proxy.example.com:8080). +- `backup_max_concurrent_requests`: (Optional) Number of threads used to upload parts of a file simultaneously. Use this parameter in conjunction with the `gpbackup --jobs` option to increase your overall backup concurrency. +- `backup_multipart_chunksize`: (Optional) The size of each data chunk uploaded to the S3 bucket. Use this parameter along with the `gpbackup --jobs` option and the `backup_max_concurrent_requests` parameter to fine tune your backups. +- `restore_max_concurrent_requests`: (Optional) Number of threads used to download parts of a file during recovery. +- `restore_multipart_chunksize`: (Optional) The size of each data chunk for each individual part of a file during a multipart transfer from S3 to the segments. Use this parameter along with `restore_max_concurrent_requests` to fine tune your restores. + +::: info Note +- The S3 user you configure to run the backups via `aws_access_key_id` must have upload/delete permissions on that bucket for backups and open/download/view permissions for restores. +- All segment hosts must have network access to the S3 endpoint, or the proxy configured via `http_proxy`. +::: + +## Performing a backup + +To perform a backup, use the `gpbackup` command with the `--plugin-config` option and specify the path to your YAML file: + +```shell +gpbackup --dbname --plugin-config //s3-config.yaml +``` + +The plugin organizes backups files using the following directory structure: + +``` +bucket/folder/backups/YYYYMMDD/YYYYMMDDHHMMSS/ +``` + +## Performing a restore + +To restore a backup created with the S3 plugin, you must use the same `--plugin-config` file. You will also need the timestamp of the backup you wish to restore. + +```shell +gprestore --timestamp --plugin-config //s3-config.yaml +``` + +## Example + +1. Create a configuration file named `s3-test-config.yaml`: + + ```yaml + executablepath: $GPHOME/bin/gpbackup_s3_plugin + options: + region: us-west-2 + aws_access_key_id: test-s3-user + aws_secret_access_key: asdf1234asdf + bucket: gpdb-backup + folder: test/backup3 + ``` + +1. On the coordinator, run the backup: + + ```shell + gpbackup --dbname demo --single-data-file --plugin-config /home/gpadmin/s3-test-config.yaml + ``` + +1. Execute the restore (using the timestamp generated by the backup above): + + ``` + gprestore --timestamp 20260318120000 --plugin-config /home/gpadmin/s3-test-config.yaml + ``` diff --git a/docs/whpg-backup/using.md b/docs/whpg-backup/using.md new file mode 100644 index 0000000..c0d18e2 --- /dev/null +++ b/docs/whpg-backup/using.md @@ -0,0 +1,238 @@ +--- +title: Backing up and restoring your tables + +--- + +Use `gpbackup` and `gprestore` to take and restore full backups of a WarehousePG database, filtering what's included and getting notified by email when a run completes. For incremental backups of append-optimized tables, see [Creating incremental backups of append-optimized tables](incremental.md). For architecture background, see [Architecture](overview/architecture.md). For command syntax, see the [gpbackup](reference/gpbackup.md) and [gprestore](reference/gprestore.md) reference pages. + +## Running a full backup + +To take a full backup that includes metadata and user data, run `gpbackup` with the `--dbname` option. This example uses zstandard compression: + +```bash +gpbackup --dbname ww_sales --compression-type zstd +``` + +::: info Note +In order to use the zstd compression type, Zstandard must be installed in a `$PATH` accessible by the `gpadmin` user. +::: + +Specify the gzip compression level (1-9) with `--compression-level`, or disable compression entirely with `--no-compression`. If you don't specify a level, `gpbackup` uses level 1 by default. + +By default, `gpbackup` writes metadata files to the coordinator's backup directory while each segment writes its own table data locally, so the backup set ends up spread across every host in the cluster. To consolidate all backup files into a single directory, include the `--backup-dir` option with an absolute path. You can also add the `--single-data-file` option to write a single data file per segment instead of one file per table. Combining files this way is useful in situations where the overhead of managing many small files is a problem, such as with some third-party storage solutions: + +```bash +gpbackup --dbname ww_sales --single-data-file --no-compression --backup-dir /tmp/single_file +``` + +`gpbackup` reports progress as it runs, including a timestamped log line for each phase of the backup and a progress bar while it locks and backs up tables, ending with `Backup completed successfully`. + +### Inspecting backup files + +A complete backup set includes metadata files, supporting files, and CSV data files, each named with the timestamp of the backup. By default, metadata and supporting files are stored on the WarehousePG coordinator host, in `$COORDINATOR_DATA_DIRECTORY/backups/YYYYMMDD/YYYYMMDDHHMMSS/`, and each segment stores its own table data in the equivalent path in its data directory. If you specify a custom backup directory with `--backup-dir`, `gpbackup` creates this same path as a subdirectory of it. + +::: warning +`gpbackup` creates all metadata files with read-only permissions. Never delete or modify them. Doing so can make the backup set unusable. +::: + +#### Coordinator files + +The backup directory on the coordinator contains the following metadata files: + +- **`gpbackup__metadata.sql`** contains the DDL for the backup's global and database objects, split into what `gprestore` creates before and after the data is restored. See [Objects included in a backup](overview/architecture.md#objects-included-in-a-backup) for the full list. +- **`gpbackup__toc.yaml`** is the table of contents file. It records where each object's DDL is located in the metadata SQL file, along with the table names and OIDs used to locate the corresponding table data in the [segment data files](#segment-files). For example: + + ```yaml + dataentries: + - schema: public + name: customer + oid: 27289 + attributestring: (c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment) + rowscopied: 0 + partitionroot: "" + isreplicated: false + distbyenum: false + ``` + +- **`gpbackup__report`** contains the information used to populate the [notification email](#setting-up-email-alerts), including the command-line options used, the database backed up, the database version, and the backup type. +- **`gpbackup__config.yaml`** contains metadata about the backup task, including the `gpbackup` version, database name, WarehousePG version, and option settings such as `--no-compression`, `--compression-level`, `--metadata-only`, `--data-only`, and `--with-stats`. + +#### Segment files + +By default, each segment creates one compressed CSV file for each table it backs up, using the name format `gpbackup___.gz`, where `` is the segment's content ID, `` is the backup timestamp, and `` is the table's object ID. + +With `--single-data-file`, each segment instead writes all table data to a single file, `gpbackup__`, with a corresponding `gpbackup___toc.yaml`. The coordinator's `gpbackup__toc.yaml` file references each table's `` to locate its data in these segment files. + +### Understanding the backup history database + +Each time `gpbackup` runs, it records details of the operation, such as the timestamp, command-line options, incremental backup details, and status, in a SQLite database at `$COORDINATOR_DATA_DIRECTORY/gpbackup_history.db`. `gpbackup` doesn't back up `gpbackup_history.db` itself, but you can copy it to a secondary location if you want a backup copy. To skip recording a backup in the history database, include the `--no-history` option. + +`gpbackup` uses `gpbackup_history.db` to build the backup and restore plan for an incremental backup set when you run `gpbackup` with `--incremental` and don't specify `--from-timestamp` to indicate the base backup. See [Creating incremental backups](incremental.md) for details. + +## Restoring a full backup + +To restore from a backup set with `gprestore`, specify the exact timestamp `YYYYMMDDHHMMSS` of the backup with the `--timestamp` option. Add the `--create-db` option if the database doesn't already exist in the cluster. If you used a custom `--backup-dir` when creating the backup, include the same option when restoring it: + +```bash +gprestore --timestamp 20250515182209 --backup-dir /tmp/single_file --create-db +``` + +`gprestore` doesn't restore global metadata for the WarehousePG cluster by default. Include the `--with-globals` option if you need it. + +By default, `gprestore` uses one connection to restore table data and metadata. If your backup set is large and wasn't created with `--single-data-file`, you can reduce restore duration by specifying the number of parallel processes with the `--jobs` option, tuned to your available system resources and database size. + +When restoring to an existing database, `gprestore` assumes the public schema exists. When restoring to a new database with `--create-db`, `gprestore` creates the public schema automatically using the `CREATE DATABASE` command, based on the `template0` database that contains the public schema. + +`gprestore` reports its own progress in the same style as `gpbackup`, ending with `Restore completed successfully`. + +## Filtering backups and restores + +Filter backups and restores with schema-level or table-level options to include or exclude individual objects. Without a filter, `gpbackup` backs up all schemas and tables in the specified database. For the full option syntax, see the [gpbackup](reference/gpbackup.md#options) and [gprestore](reference/gprestore.md#options) reference pages. + +### Filtering backups by schema + +Use `--include-schema`, `--include-schema-file`, `--exclude-schema`, or `--exclude-schema-file` to filter by schema. For example: + +```bash +gpbackup --dbname ww_customer --exclude-schema na_customer +``` + +To filter multiple schemas, repeat `--include-schema` or `--exclude-schema` in the same command, for example: + +```bash +gpbackup --dbname ww_customer --include-schema apac_customer --include-schema emea_customer +``` + +Alternatively, use `--include-schema-file` or `--exclude-schema-file` with a text file that lists one schema per line and has no trailing blank lines: + +```bash +gpbackup --dbname ww_customer --include-schema-file /tmp/nw_states.schema +``` + +::: info Note +You can't combine `--include-schema` or `--include-schema-file` with `--exclude-schema` or `--exclude-schema-file`, or with a table filtering option such as `--include-table`. +::: + +### Filtering backups by table + +Filter tables using `--include-table`, `--exclude-table`, `--include-table-file`, and `--exclude-table-file`. These options take the `schema_name.table_name` format on the command line and in a text file. + +```bash +gpbackup --dbname ww_customer --include-table apac_customer.customer_fact +``` + +Enclose table and schema names that contain uppercase letters or spaces in double quotes, for example `na_customer."ZipCodes"` or `"WW_GEO"."time zones"`. + +When you specify `--include-table` or `--include-table-file`, `gpbackup` and `gprestore` don't automatically back up or restore dependent objects. You must list dependent objects in your filter explicitly. For example, if you back up or restore a view or materialized view, also list the tables it depends on. If you back up or restore a table that contains a sequence, also specify the sequence name. + +::: info Note +You can use the individual table-filtering options multiple times, but you can't use `--include-table` and `--exclude-table` in the same command, and you can't combine any table filtering option with a schema filtering option such as `--include-schema`. +::: + +### Filtering backups by leaf partition + +Use the `--leaf-partition-data` option to filter backups to specific leaf partitions, listing their names in the same `schema_name.table_name` format as for a standalone table. This option also changes how `gpbackup` writes data files, creating one file per leaf partition of a partitioned table instead of one file per table on a segment, which is the default. This per-leaf-partition file behavior doesn't apply if you also use `--single-data-file`, since that option writes a single data file per segment regardless of `--leaf-partition-data`. + +For example, given a partitioned table `ww_inventory` with child partitions named `ww_inventory_1_prt_1` through `ww_inventory_1_prt_30`, the file `/tmp/may_week1.include` lists the partitions for the first week of May to include in the backup: + +``` +"WW_GEO".ww_inventory_1_prt_1 +"WW_GEO".ww_inventory_1_prt_2 +"WW_GEO".ww_inventory_1_prt_3 +``` + +Combine `--include-table-file` with `--leaf-partition-data` to create one data file for each leaf partition listed in the file: + +```bash +gpbackup --dbname ww_sales --include-table-file /tmp/may_week1.include --leaf-partition-data +``` + +::: info Note +`--exclude-table-file` and `--leaf-partition-data` aren't compatible. You can specify leaf partition names in a file used with `--exclude-table-file`, but `gpbackup` ignores them. +::: + +### Filtering restores + +Filter what you restore from a backup set using the same schema and table filtering options as `gpbackup`, namely `--include-schema`, `--include-schema-file`, `--exclude-schema`, `--exclude-schema-file`, `--include-table`, `--include-table-file`, `--exclude-table`, and `--exclude-table-file`. These options work the same way as their `gpbackup` counterparts, with these restrictions: + +- The tables you're restoring must not already exist in the target database. +- The schema or table you're restoring must exist in the backup set, or `gprestore` fails. +- With `--include-schema`, `gprestore` can't restore objects that depend on multiple schemas. +- With `--include-table-file`, `gprestore` doesn't create roles or set table ownership, though it restores table indexes and rules. Triggers are also restored, even though WarehousePG doesn't support them. +- The file you specify with `--include-table-file` can't include a leaf partition name, unlike the equivalent `gpbackup` option. If you backed up specific leaf partitions, specify the partitioned table instead to restore their data. + +When you restore a backup set that contains data for only some leaf partitions of a partitioned table, `gprestore` creates the partitioned table and restores data only for the leaf partitions in the backup. + +## Setting up email alerts + +Enable email notifications through `sendmail` to alert you when a `gpbackup` or `gprestore` run completes, by creating a `gp_email_contacts.yaml` file in the home directory of the user running the utilities, or in the same directory as the utilities (`$GPHOME/bin`). If both exist, the one in the home directory takes precedence. If neither is present, or the file isn't configured correctly, the log records that no email was sent. + +The email subject line includes the utility name, timestamp, status, and the name of the WarehousePG coordinator. The email body contains the contents of a report file, which `gpbackup` and `gprestore` each generate when a run completes and place in the WarehousePG coordinator backup directory, named `gpbackup__report` or `gprestore___report`. For example: + +``` +WarehousePG Report + +timestamp key: 20250530234643 +gprestore version: 1.30.5 + +database name: test +command line: gprestore --timestamp 20250530234643 --redirect-db test --create-db + +backup segment count: 8 +restore segment count: 8 +duration: 0:00:42 + +restore status: Success +``` + +Use YAML indentation to define the structure of the `gp_email_contacts.yaml` file, with spaces rather than tabs. + +```yaml +contacts: + gpbackup: + - address: name@domain + status: + success: [true | false] + success_with_errors: [true | false] + failure: [true | false] + gprestore: + - address: name@domain + status: + success: [true | false] + success_with_errors: [true | false] + failure: [true | false] +``` + +The file has these sections: + +- **`contacts`** (required): Contains the `gpbackup` and `gprestore` sections. The file can contain one, or both. +- **`gpbackup`** (optional): Begins the `gpbackup` email section. +- **`address`** (required): At least one email address. You can specify multiple addresses, each with its own `status` section. +- **`status`** (required): Specifies when to send an email, based on the completion status of the operation. Specify at least one of these parameters, each at most once. The default is not to send email notifications. + - **`success`** (optional): Send an email if the operation completes without errors. Defaults to `false`. + - **`success_with_errors`** (optional): Send an email if the operation completes with errors. Defaults to `false`. + - **`failure`** (optional): Send an email if the operation fails. Defaults to `false`. +- **`gprestore`** (optional): Begins the `gprestore` email section, using the same `address` and `status` syntax as `gpbackup`. + +To send email to different addresses depending on whether a backup succeeds or fails, and to a single address for restore operations that succeed or complete with errors, use a configuration like this: + +```yaml +contacts: + gpbackup: + - address: dba_backup_success@whpg.io + status: + success: true + - address: dba_backup_failure@whpg.io + status: + success_with_errors: true + failure: true + gprestore: + - address: dba_restore_status@example.com + status: + success: true + success_with_errors: true +``` + +::: info Note +If a status parameter isn't specified correctly, `gpbackup` and `gprestore` don't issue a warning. For example, a misspelled `success` parameter that's set to `true` doesn't trigger a warning, and no email is sent after a successful operation. Test your email notification configuration to confirm it works as expected. +::: diff --git a/docs/whpg/6x/admin_guide/backup_restore/index.md b/docs/whpg/6x/admin_guide/backup_restore/index.md new file mode 100644 index 0000000..44da618 --- /dev/null +++ b/docs/whpg/6x/admin_guide/backup_restore/index.md @@ -0,0 +1,6 @@ +--- +title: Backing Up and Restoring Databases + +--- + +The `gpbackup` and `gprestore` documentation has moved to the [WarehousePG Backup and Restore](../../../../whpg-backup/index.md) section. diff --git a/docs/whpg/6x/admin_guide/index.md b/docs/whpg/6x/admin_guide/index.md index 87b270b..8610577 100644 --- a/docs/whpg/6x/admin_guide/index.md +++ b/docs/whpg/6x/admin_guide/index.md @@ -14,6 +14,7 @@ navigation: - load - performance - parallel_retrieve_cursor + - backup_restore redirects: - admin_guide - managing_data diff --git a/docs/whpg/6x/admin_guide/managing/backup-main.md b/docs/whpg/6x/admin_guide/managing/backup-main.md index d9041e5..8d47816 100644 --- a/docs/whpg/6x/admin_guide/managing/backup-main.md +++ b/docs/whpg/6x/admin_guide/managing/backup-main.md @@ -11,9 +11,7 @@ WarehousePG supports parallel and non-parallel methods for backing up and restor ## Parallel Backup with gpbackup and gprestore -`gpbackup` and `gprestore` are the recommended WarehousePG backup and restore utilities. `gpbackup` utilizes `ACCESS SHARE` locks at the individual table level, instead of `EXCLUSIVE` locks on the `pg_class` catalog table. This enables you to run DML statements during the backup, such as `CREATE`, `ALTER`, `DROP`, and `TRUNCATE` operations, as long as those operations do not target the current backup set. Backup files created with `gpbackup` are designed to provide future capabilities for restoring individual database objects along with their dependencies, such as functions and required user-defined datatypes. - -`gpbackup`, `gprestore`, and related utilities are provided as a separate download. +`gpbackup` and `gprestore` are the recommended WarehousePG backup and restore utilities, provided as a separate download. For documentation, see [WarehousePG Backup and Restore](../../../../whpg-backup/index.md). diff --git a/docs/whpg/6x/ref_guide/utility_guide/reference/index.md b/docs/whpg/6x/ref_guide/utility_guide/reference/index.md index 7a2ac2b..5cc5757 100644 --- a/docs/whpg/6x/ref_guide/utility_guide/reference/index.md +++ b/docs/whpg/6x/ref_guide/utility_guide/reference/index.md @@ -9,9 +9,9 @@ The command-line utilities provided with WarehousePG. WarehousePG uses the standard PostgreSQL client and server programs and provides additional management utilities for administering a distributed WarehousePG DBMS. -Several utilities are installed when you install the WarehousePG server. These utilities reside in `$GPHOME/bin`. Other utilities must be downloaded and installed separately. These include: +Several utilities are installed when you install the WarehousePG server. These utilities reside in `$GPHOME/bin`. -- The WarehousePG Backup and Restore utilities. +For the `gpbackup` and `gprestore` utilities, see [WarehousePG Backup and Restore](../../../../../whpg-backup/index.md). WarehousePG provides the following utility programs. Superscripts identify those utilities that require separate downloads, as well as those utilities that are also installed with the Client and Loader Tools Packages. (See the Note following the table.) All utilities are installed when you install the WarehousePG server, unless specifically identified by a superscript. diff --git a/docs/whpg/7x/admin_guide/backup_restore/incremental.md b/docs/whpg/7x/admin_guide/backup_restore/incremental.md deleted file mode 100644 index 3d6b168..0000000 --- a/docs/whpg/7x/admin_guide/backup_restore/incremental.md +++ /dev/null @@ -1,360 +0,0 @@ ---- -title: Incremental Backups using gpbackup and gprestore - ---- - -:::tip Associated Topics -- [gpbackup & gprestore user guide](index.md) -- [gpbackup syntax reference](../../ref_guide/utility_guide/reference/gpbackup.md) -- [gprestore syntax reference](../../ref_guide/utility_guide/reference/gprestore.md) -::: - -The [gpbackup](../../ref_guide/utility_guide/reference/gpbackup.md) and [gprestore](../../ref_guide/utility_guide/reference/gprestore.md) utilities support creating -incremental backups of append-optimized tables and restoring from incremental backups. An -incremental backup backs up all specified heap tables and backs up append-optimized tables -(including append-optimized, column-oriented tables) only if the tables have changed. - -For example, if a row of an append-optimized table has changed, the table is backed up. For -partitioned append-optimized tables, only the changed leaf partitions are backed up. - -Incremental backups are efficient when the total amount of data in append-optimized tables or -table partitions that changed is small compared to the data that has not changed since the -last backup. - -An incremental backup backs up an append-optimized table only if one of the following -operations was performed on the table after the last full or incremental backup: - -- `ALTER TABLE` -- `DELETE` -- `INSERT` -- `TRUNCATE` -- `UPDATE` -- `DROP` and then re-create the table - -Restoring data from incremental backups requires a complete incremental backup file set. - - - -## Understanding Incremental Backup Sets - -An incremental backup set includes the following backups: - -- A full backup. This is the full backup that the incremental backups are based on. -- The set of incremental backups that capture the changes to the database from the time - of the full backup. - -For example, you can create a full backup (Sunday) and then create three daily incremental backups(Monday, Wednesday, Friday). -The full backup and all three incremental backups are the backup set. - -:::tip Incremental Backup Set -- Full: Sunday -- Incremental: Monday -- Incremental: Wednesday -- Incremental: Friday -::: - -When you create or add to an incremental backup set, `gpbackup` ensures that the backups in the set are created with a consistent set of backup options to ensure that -the backup set can be used in a restore operation. - -When you create an incremental backup you include these options with the other -`gpbackup` options to create a backup: - -##### `--leaf-partition-data` - -- Required for all backups in the incremental backup set. -- Required when you create a full backup that will be the base backup for an - incremental backup set. - -##### `--incremental` - -- Required when you create an incremental backup. - -:::tip Note -`--data-only` and `--metadata-only` are not compatible with the `--incremental` option -::: - -##### `--from-timestamp` - -- Optional. This option can be used with `--incremental`. The timestamp you specify if of an existing backup. The - timestamp can be either an incremental backup or the initial full backup of the set. - -The backup being created -must be have the same command line options as the with the backup specified with the `--from-timestamp` -option. - -If you do not specify `--from-timestamp`, `gpbackup` attempts to find a compatible backup based on information -in the `gpbackup` history database. - -When you add an incremental backup to a backup set, `gpbackup` ensures that -the full backup and the incremental backups are consistent by checking these -`gpbackup` options: - -##### `--dbname` - The database must be the same. - -##### `--backup-dir` - The directory must be the same. The backup set, the - -full backup and the incremental backups, must be in the same location. - -##### `--single-data-file` - This option must be either specified or absent - -for all backups in the set. - -##### `--plugin-config` - If this option is specified, it must be specified - -for all backups in the backup set. The configuration must reference the same plugin -binary. - -##### `--include-table-file`, `--include-schema`, or any other - -options that filter tables and schemas must be the same. - -**When checking schema filters**, only the schema names are checked, not the objects contained in the -schemas. - -##### `--no-compression` - If this option is specified, it must be specified - -for all backups in the backup set. - -If compression is used on the on the full backup, -compression must be used on the incremental backups. Different compression levels are -allowed for the backups in the backup set. For a backup, the default is compression -level 1. - -:::warning -If you try to add an `--incremental` backup to a backup set, the backup operation fails if the -`gpbackup` command line options options are not consistent. -::: - -:::tip Associated Topics -- [gpbackup & gprestore user guide](index.md) -- [gpbackup syntax reference](../../ref_guide/utility_guide/reference/gpbackup.md) -- [gprestore syntax reference](../../ref_guide/utility_guide/reference/gprestore.md) -::: - - - -## Examples - -The following example shows a backup strategy using weekly Full + daily Incremental backups. - -The following command creates the first full backup of the backup set: - -### Sunday - -``` -$ gpbackup --dbname ww_sales --backup-dir /nfsmount/whpg_backups/ww_sales --leaf-partition-data -``` - -Resulting in the example backup set - -`20250518010000 (full backup, Sunday 1am)` - -:::tip -Each backup has a timestamp taken when the backup is created, and is used in the naming of the backup set files. - -`YYYYMMDDhhmmss` is the format. - -For example, a backup on May 18,2025 at 1:00:00am local time, the backup file names contain -`20250527` for the day and `010000` representing 1:00:00am. - -Resulting in a naming convention of `20250518010000` for the backup file set - -When you specify the `--backup-dir` option, the backups are created in the corresponding directory on each WarehousePG host, `/nfsmount/whpg_backups/ww_sales` in this example. -::: - -The next backup will be an incremental backup, based on the full backup above - -### Monday - -``` -$ gpbackup --dbname ww_sales --incremental --backup-dir /nfsmount/whpg_backups/ww_sales --leaf-partition-data -``` - -Resulting in a second backup belonging to the backup set. - -``` -20250518010000 (full backup, Sunday 1am) -20250519020000 (incremental backup, Monday 2am) -``` - -Subsequent backups are run on - -- **Tuesday** -- **Wednesday** -- **Thursday** -- **Friday** -- **Saturday** - -### resulting in this complete set. - -``` -20250518010000 (full backup, Sunday 1am) -20250519020000 (incremental backup, Monday 2am) -20250520030000 (incremental backup, Tuesday 3am) -20250521040000 (incremental backup, Wedndesday 4am) -20250522050000 (incremental backup, Thursday 5am) -20250523060000 (incremental backup, Friday 6am) -20250524070000 (incremental backup, Saturday 7am) -``` - -## Full vs Incremental Backup Strategy - -The advantage of Full backups is that they contain every object in the database, allowing for a simple restore (filtered, or complete). One disadvantage may be the size & duration of this backup. - -Incremental backups decrease the time and volume of data backed up, but they will backup `HEAP` tables every time. To mitigate this, using a partitioned `AO/CO` table approach will greatly reduce incremental backups to only those partitions which have seen changes since the previous backup. - -Given the Sunday-Saturday example above, the user has a choice of how to handle the next round of backups. - -## Weekly Full Backup + Incrementals Example - -The user / DBA may choose to run a full backup again on Sunday (no `--incremental` flag) - -``` -$ gpbackup --dbname ww_sales --backup-dir /nfsmount/whpg_backups/ww_sales --leaf-partition-data -``` - -Resulting in a new full backup. - -``` -20250518010000 (full backup, Sunday 1am) -20250519020000 (incremental backup, Monday 2am) -20250520030000 (incremental backup, Tuesday 3am) -20250521040000 (incremental backup, Wedndesday 4am) -20250522050000 (incremental backup, Thursday 5am) -20250523060000 (incremental backup, Friday 6am) -20250524070000 (incremental backup, Saturday 7am) -20250525010000 (full backup, Sunday 1am) -``` - -The choice then could be made to retain the prior seven backups, or purge the data to convserve disk space. - -## Aggregated Incrementals Example using --from-timestamp - -An alternative approach would be to take an incremental backup on the next Sunday using `--from-timestamp` which creates a single incremental backup set from the basis of the initial full backup on the previous Sunday. - -For example: - -``` -$ gpbackup --dbname ww_sales --incremental --from-timestamp 20250518010000 --backup-dir /nfsmount/whpg_backups/ww_sales --leaf-partition-data -``` - -Resulting in the following backup sets - -``` -20250518010000 (full backup, Sunday 1am) -20250519020000 (incremental backup, Monday 2am) -20250520030000 (incremental backup, Tuesday 3am) -20250521040000 (incremental backup, Wedndesday 4am) -20250522050000 (incremental backup, Thursday 5am) -20250523060000 (incremental backup, Friday 6am) -20250524070000 (incremental backup, Saturday 7am) -20250525010000 (incremental backup, Sunday 1am) -``` - -While this last backup was incremental, it was incremental from the last full backup's timestamp. -This means all the previous incremental backup sets are now redundant, and not required. - -:::tip redundant backup sets -These backup sets can now be deleted to reclaim storage space - -``` -20250519020000 (incremental backup, Monday 2am) -20250520030000 (incremental backup, Tuesday 3am) -20250521040000 (incremental backup, Wedndesday 4am) -20250522050000 (incremental backup, Thursday 5am) -20250523060000 (incremental backup, Friday 6am) -20250524070000 (incremental backup, Saturday 7am) -``` -::: - -Resulting in the following two backups covering the entire week - -``` -20250518010000 (full backup, Sunday 1am) -20250525010000 (incremental backup, Sunday 1am) -``` - - - -## Restoring Incremental Backup Sets - -Based on the previous examples of full and incremental backups - -``` -20250518010000 (full backup, Sunday 1am) -20250519020000 (incremental backup, Monday 2am) -20250520030000 (incremental backup, Tuesday 3am) -20250521040000 (incremental backup, Wedndesday 4am) -20250522050000 (incremental backup, Thursday 5am) -20250523060000 (incremental backup, Friday 6am) -20250524070000 (incremental backup, Saturday 7am) -``` - -The following `gprestore` command specifies the timestamp `20250521040000` (Wednesday) as the restore to point. - -``` -$ gprestore --timestamp 20250521040000 --redirect-db www_sales_pitr --create-db -``` - -The incremental backup with the timestamps - -- `20250520030000` (Tuesday) -- `20250519020000` (Monday) - -And the full backup - -- `20250518010000` (Sunday) - -**must be available to perform a succesful restore.** - - - -## Tips & Notes - -:::tip Choices -- The amount of backups (full or incremental) retained is a choice for each user. Some enterprises may have regulatory requirements to keep `x of days` of backups. - - -- `RPO` (Recovery Point Objective) 1 day, 1 week, 1 month for example, may play a role in how you develop your backup strategy. - -- Using `--incremental` backups, effective partitioning of `AO/CO` tables, and the use of the `--include` and `--exclude` table and schema filters, allow for a flexible and performant approach to your backup strategy. -::: - -To create an incremental backup, or to restore data from an incremental backup set, you -need the complete backup set. When you archive incremental backups, the complete backup -set must be archived. You must archive all the files created on the coordinator and all -segments. - -Each time `gpbackup` runs, the utility adds backup information to the -backup history database `gpbackup_history.db` located in the WarehousePG `$COORDINATORY_DATA_DIRECTORY`. -This sqlite database contains metadata details of the backup set, such as timestamp, flags used, object contents. -To bypass the inserting of this metadata into the history database, the `--no-history` flag can be included in your `gpbakcup` command. - -When using the `--incremental` flag without the `--from-timestamp` option, `gpbackup` will attempt to find the most recent backup with the same command line options, in the `gpbackup_history.db`. If `gpbackup` cannot find a backup with a consistent -set of options, `gpbackup` displays a warning indicating a full backup must be created before an incremental can be created. - -When using the `--from-timestamp` option with `--incremental`, `gpbackup` ensures that the command line options of the current backup match the options of the previously created incremental backup with the specified timestamp. - -The `gpbackup` option `--with-stats` is not required to be the same for all backups in the backup set. However, to perform a restore operation with -the `gprestore` option `--with-stats` to restore statistics, the backup you specify must have must have used the `--with-stats` when -taking the backup. - -Restore operations can be performed from any backup in the backup set. However, changes -captured in incremental backups later than the backup use to restore database data will -not be restored. - -When restoring from an incremental backup set, `gprestore` checks the -backups and restores each append-optimized table from the most recent version of the -append-optimized table in the backup set. - -Heap tables are always restored from the latest backup in the incremental backup set. - -The incremental back up set, a full backup and associated incremental backups, must be on -a single device. For example, the backups in a backup set must all be on the local filesystem, S3 compatible bucket or a NFS mount point accessible my all hosts in the WarehousePG cluster. - -:::warning -Changes to the WarehousePG segment configuration invalidate -incremental backups. After you change the segment configuration (add or remove segment -instances), you must create a full backup before you can create an incremental -backup. -::: diff --git a/docs/whpg/7x/admin_guide/backup_restore/index.md b/docs/whpg/7x/admin_guide/backup_restore/index.md index 4c41a93..44da618 100644 --- a/docs/whpg/7x/admin_guide/backup_restore/index.md +++ b/docs/whpg/7x/admin_guide/backup_restore/index.md @@ -1,973 +1,6 @@ --- -title: Backing up WarehousePG with gpbackup and gprestore +title: Backing Up and Restoring Databases --- -:::tip Associated Topics -- [Incremental backups](incremental.md) -- [gpbackup syntax reference](../../ref_guide/utility_guide/reference/gpbackup.md) -- [gprestore syntax reference](../../ref_guide/utility_guide/reference/gprestore.md) -::: - -[gpbackup](../../ref_guide/utility_guide/reference/gpbackup.md) and [gprestore](../../ref_guide/utility_guide/reference/gprestore.md) - are WarehousePG utilities that create and restore backup sets in parallel for WarehousePG. By default, `gpbackup` stores only the object metadata files and DDL files for a backup in the WarehousePG Coordinator data directory. WarehousePG segments use the `COPY ... ON SEGMENT` command to store their data for backed-up tables in compressed CSV data files, located in each segment’s backups directory. - - - -## Parallel Backup with gpbackup and gprestore - -![Parallel Restore Using Parallel Backup Files](../../images/parallel_backup_restore.png "Parallel Restore Using Parallel Backup Files") - -The backup metadata files contain all of the information that `gprestore` needs to restore a full backup set in parallel. Backup metadata also provides the framework for restoring only individual objects in the data set, along with any dependent objects, in future versions of `gprestore`. (See Understanding Backup Files for more information.) Storing the table data in CSV files also provides opportunities for using other restore utilities, such as gpload, to load the data either in the same cluster or another cluster. By default, one file is created for each table on the segment. You can specify the `--leaf-partition-data` option with `gpbackup` to create one data file per leaf partition of a partitioned table, instead of a single file. This option also enables you to filter backup sets by leaf partitions. - -Each `gpbackup` task uses a single transaction in WarehousePG. During this transaction, metadata is backed up on the Coordinator host, and data for each table on each segment host is written to CSV backup files using COPY ... ON SEGMENT commands in parallel. The backup process acquires an ACCESS SHARE lock on each table that is backed up. - -For additional documenation, visit the [gpbackup](../../ref_guide/utility_guide/reference/gpbackup.md) and [gprestore](../../ref_guide/utility_guide/reference/gprestore.md) cluster utilities reference page. - -- [Objects in a backup set](#objects) - -- [Backup and Restore Workflow](#workflow) - -- [Backup History Database](#db) - -- [Using the --include and --exclude filters](#filter) - -- [Setting Up Email Alerts](#email) - -- [Backup files layout](#files) - -- [Return Codes](#codes) - -- [Supported WHPG versions](#versions) - -- [Limitations](#limitations) - - - -## Objects in a backup set - -Objects Included in a Backup or Restore -The following table lists the objects that are backed up and restored with `gpbackup` and `gprestore`. - -**Database objects** are backed up for the database you specify with the `--dbname` option. - -**Global objects** (WarehousePG Cluster objects) are also backed up by default, but they are restored only if you include the `--with-globals option` when calling `gprestore`. Conversely, the `gpbackup --without-globals` will skip the backup of global objects - -### Objects that are backed up and restored - -| **Database objects** | | -| -------------------------------------------------- | ---------------------------------------------------------------- | -| Aggregates | Readable External Tables 1 | -| Casts | Rules | -| Comments | Schemas 4 | -| Conversions | Sequences | -| Domains | Session-level configuration parameter settings (GUCs) | -| Extensions | Table statistics 2 | -| Functions | Tables | -| Indexes | Text search parsers, dictionaries, templates, and configurations | -| Materialized Views 1 | Triggers 3 | -| Operators, operator families, and operator classes | Types | -| Owners | Views | -| Procedural language extensions | Writable External Tables 1 | -| Protocols | | - -1. DDL Only -2. when `--with-stats` flag is used -3. While WarehousePG does not support triggers, trigger definitions present in the database are backed up and restored -4. The following schemas are not part of the backup set: gp_toolkit, information_schema, pg_aoseg, pg_bitmapindex, pg_catalog, pg_toast*, pg_temp* - -| **Global objects** | \_ | -| ----------------------------------------------------- | -------------------------- | -| Databases | Resource queue definitions | -| Database-wide configuration parameter settings (GUCs) | Roles | -| GRANT assignments of roles to databases | Tablespaces | -| Resource group definitions | | - -When restoring to an existing database, `gprestore` assumes the public schema exists when restoring objects to the public schema. When restoring to a new database (with the --create-db option), `gprestore` creates the public schema automatically when creating a database with the CREATE DATABASE command. The command uses the template0 database that contains the public schema. - - - -## Backup and Restore Workflow - -### Full Backup - -This command will take a full backup (metadata and user data) using zstandard compression - -`$ gpbackup --dbname --compression-type zstd` - -
-Example: - -``` -[gpadmin@whpg_cdw ~]$ gpbackup --dbname ww_sales --compression-type zstd -20250514:20:27:13 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-gpbackup version = 1.30.5 -20250514:20:27:13 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Greenplum Database Version = 6.27.1 build commit:ab5a612bfdc355ad2d601860dfb70a47778c8dd7 -20250514:20:27:13 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Starting backup of database ww_sales -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Backup Timestamp = 20250514202713 -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Backup Database = ww_sales -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Gathering table state information -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Acquiring ACCESS SHARE locks on tables -Locks acquired: 57 / 57 [==============================================================] 100.00% 0s -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Gathering additional table metadata -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Getting partition definitions -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Getting storage information -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Getting child partitions with altered schema -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Metadata will be written to /data/coordinator/gpseg-1/backups/20250514/20250514202713/gpbackup_20250514202713_metadata.sql -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Writing global database metadata -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Global database metadata backup complete -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Writing pre-data metadata -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Pre-data metadata metadata backup complete -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Writing post-data metadata -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Post-data metadata backup complete -20250514:20:27:14 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Writing data to file -Tables backed up: 33 / 33 [============================================================] 100.00% 7s -20250514:20:27:22 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Data backup complete -20250514:20:27:22 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Skipped data backup of 24 external/foreign table(s). -20250514:20:27:22 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-See /home/gpadmin/gpAdminLogs/gpbackup_20250514.log for a complete list of skipped tables. -20250514:20:27:23 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-/home/gpadmin/gp_email_contacts.yaml list found, /data/coordinator/gpseg-1/backups/20250514/20250514202713/gpbackup_20250514202713_report will be sent -20250514:20:28:23 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Beginning cleanup -20250514:20:28:23 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Cleanup complete -20250514:20:28:23 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-Backup completed successfully - -``` - -The above command creates a file that contains global and database-specific metadata on the WarehousePG Coordinator host in the default directory, `$COORDINATOR_DATA_DIRECTORY/backups///`. - -
-For example: - -``` -[gpadmin@whpg_cdw 20250514202713]$ ls -ltr /data/coordinator/gpseg-1/backups/20250514/20250514202713 -total 2112 --r--r--r-- 1 gpadmin gpadmin 2114041 May 14 20:27 gpbackup_20250514202713_metadata.sql --r--r--r-- 1 gpadmin gpadmin 35787 May 14 20:27 gpbackup_20250514202713_toc.yaml --r--r--r-- 1 gpadmin gpadmin 1437 May 14 20:27 gpbackup_20250514202713_config.yaml --r--r--r-- 1 gpadmin gpadmin 1833 May 14 20:27 gpbackup_20250514202713_report -``` - -By default, each segment stores each table’s data for the backup in a separate compressed CSV file in `/backups///`: - -``` -[gpadmin@mdw 20250514202713]$ ls -ltr /data/primary/gpseg0/backups/20250514/20250514202713 -total 125764 --rw------- 1 gpadmin gpadmin 494 May 14 20:27 gpbackup_0_20250514202713_65582.zst --rw------- 1 gpadmin gpadmin 174123 May 14 20:27 gpbackup_0_20250514202713_67854.zst --rw------- 1 gpadmin gpadmin 3057086 May 14 20:27 gpbackup_0_20250514202713_67861.zst --rw------- 1 gpadmin gpadmin 32450223 May 14 20:27 gpbackup_0_20250514202713_70343.zst --rw------- 1 gpadmin gpadmin 1994875 May 14 20:27 gpbackup_0_20250514202713_71070.zst --rw------- 1 gpadmin gpadmin 475745 May 14 20:27 gpbackup_0_20250514202713_71077.zst --rw------- 1 gpadmin gpadmin 3006034 May 14 20:27 gpbackup_0_20250514202713_71084.zst --rw------- 1 gpadmin gpadmin 528895 May 14 20:27 gpbackup_0_20250514202713_71091.zst --rw------- 1 gpadmin gpadmin 8945 May 14 20:27 gpbackup_0_20250514202713_71098.zst --rw------- 1 gpadmin gpadmin 74 May 14 20:27 gpbackup_0_20250514202713_71105.zst --rw------- 1 gpadmin gpadmin 19507368 May 14 20:27 gpbackup_0_20250514202713_71112.zst --rw------- 1 gpadmin gpadmin 596995 May 14 20:27 gpbackup_0_20250514202713_71326.zst --rw------- 1 gpadmin gpadmin 4688 May 14 20:27 gpbackup_0_20250514202713_71333.zst --rw------- 1 gpadmin gpadmin 251 May 14 20:27 gpbackup_0_20250514202713_71340.zst --rw------- 1 gpadmin gpadmin 289 May 14 20:27 gpbackup_0_20250514202713_71347.zst --rw------- 1 gpadmin gpadmin 638 May 14 20:27 gpbackup_0_20250514202713_71354.zst --rw------- 1 gpadmin gpadmin 4729580 May 14 20:27 gpbackup_0_20250514202713_71361.zst --rw------- 1 gpadmin gpadmin 44197780 May 14 20:27 gpbackup_0_20250514202713_71575.zst --rw------- 1 gpadmin gpadmin 198475 May 14 20:27 gpbackup_0_20250514202713_73562.zst --rw------- 1 gpadmin gpadmin 224 May 14 20:27 gpbackup_0_20250514202713_73569.zst --rw------- 1 gpadmin gpadmin 634 May 14 20:27 gpbackup_0_20250514202713_73576.zst --rw------- 1 gpadmin gpadmin 1245122 May 14 20:27 gpbackup_0_20250514202713_73583.zst --rw------- 1 gpadmin gpadmin 16500913 May 14 20:27 gpbackup_0_20250514202713_73716.zst --rw------- 1 gpadmin gpadmin 1455 May 14 20:27 gpbackup_0_20250514202713_74227.zst --rw------- 1 gpadmin gpadmin 13 May 14 20:27 gpbackup_0_20250514202713_74306.zst --rw------- 1 gpadmin gpadmin 13 May 14 20:27 gpbackup_0_20250514202713_74312.zst --rw------- 1 gpadmin gpadmin 302 May 14 20:27 gpbackup_0_20250514202713_74318.zst --rw------- 1 gpadmin gpadmin 278 May 14 20:27 gpbackup_0_20250514202713_74324.zst --rw------- 1 gpadmin gpadmin 353 May 14 20:27 gpbackup_0_20250514202713_74330.zst --rw------- 1 gpadmin gpadmin 13 May 14 20:27 gpbackup_0_20250514202713_74336.zst --rw------- 1 gpadmin gpadmin 13 May 14 20:27 gpbackup_0_20250514202713_74342.zst --rw------- 1 gpadmin gpadmin 22 May 14 20:27 gpbackup_0_20250514202713_74348.zst --rw------- 1 gpadmin gpadmin 441 May 14 20:27 gpbackup_0_20250514202713_74351.zst -``` - -To consolidate all backup files into a single directory, include the `--backup-dir` option with an absolute path to the location you wish to backup to. Optionally, when performing a backup, the `--single-data-file` option may be used in situations where the additional overhead of multiple files might be prohibitive such as third party storage solutions. - -The command below shows both options in use - -``` - -[gpadmin@whpg_cdw ~]$ gpbackup --dbname ww_sales --single-data-file --no-compression --backup-dir /tmp/single_file -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-gpbackup version = 1.30.5 -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Greenplum Database Version = 6.27.1 build commit:ab5a612bfdc355ad2d601860dfb70a47778c8dd7 -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Starting backup of database ww_sales -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Backup Timestamp = 20250515182209 -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Backup Database = ww_sales -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Gathering table state information -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Acquiring ACCESS SHARE locks on tables -Locks acquired: 57 / 57 [==============================================================] 100.00% 0s -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Gathering additional table metadata -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Getting partition definitions -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Getting storage information -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Getting child partitions with altered schema -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Metadata will be written to /tmp/single_file/gpseg-1/backups/20250515/20250515182209/gpbackup_20250515182209_metadata.sql -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Writing global database metadata -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Global database metadata backup complete -20250515:18:22:09 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Writing pre-data metadata -20250515:18:22:10 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Pre-data metadata metadata backup complete -20250515:18:22:10 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Writing post-data metadata -20250515:18:22:10 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Post-data metadata backup complete -20250515:18:22:10 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Writing data to file -Tables backed up: 33 / 33 [============================================================] 100.00% 8s -20250515:18:22:18 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Data backup complete -20250515:18:22:18 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Skipped data backup of 24 external/foreign table(s). -20250515:18:22:18 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-See /home/gpadmin/gpAdminLogs/gpbackup_20250515.log for a complete list of skipped tables. -20250515:18:22:19 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Found neither /usr/local/greenplum-db-6.27.1/bin/gp_email_contacts.yaml nor /home/gpadmin/gp_email_contacts.yaml -20250515:18:22:19 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Email containing gpbackup report /tmp/single_file/gpseg-1/backups/20250515/20250515182209/gpbackup_20250515182209_report will not be sent -20250515:18:22:19 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Beginning cleanup -20250515:18:22:24 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Cleanup complete -20250515:18:22:24 gpbackup:gpadmin:whpg_cdw:032298-[INFO]:-Backup completed successfully -``` - -The contents of the corresponding backup directories show the single data file, and it's associated table of contents files (toc). Both files are required for a successful restore. - -``` -[gpadmin@whpg_cdw ~]$ ls -ltr /tmp/single_file/gp*/backups/*/* - -/tmp/single_file/gpseg0/backups/20250515/20250515182209: -total 407012 --rw-rw-r-- 1 gpadmin gpadmin 416771752 May 15 18:22 gpbackup_0_20250515182209 --r--r--r-- 1 gpadmin gpadmin 1864 May 15 18:22 gpbackup_0_20250515182209_toc.yaml - -/tmp/single_file/gpseg1/backups/20250515/20250515182209: -total 434396 --rw-rw-r-- 1 gpadmin gpadmin 444811433 May 15 18:22 gpbackup_1_20250515182209 --r--r--r-- 1 gpadmin gpadmin 1864 May 15 18:22 gpbackup_1_20250515182209_toc.yaml - -/tmp/single_file/gpseg2/backups/20250515/20250515182209: -total 407260 --rw-rw-r-- 1 gpadmin gpadmin 417025293 May 15 18:22 gpbackup_2_20250515182209 --r--r--r-- 1 gpadmin gpadmin 1864 May 15 18:22 gpbackup_2_20250515182209_toc.yaml - -/tmp/single_file/gpseg-1/backups/20250515/20250515182209: -total 2112 --r--r--r-- 1 gpadmin gpadmin 2114041 May 15 18:22 gpbackup_20250515182209_metadata.sql --r--r--r-- 1 gpadmin gpadmin 35787 May 15 18:22 gpbackup_20250515182209_toc.yaml --r--r--r-- 1 gpadmin gpadmin 1451 May 15 18:22 gpbackup_20250515182209_config.yaml --r--r--r-- 1 gpadmin gpadmin 1872 May 15 18:22 gpbackup_20250515182209_report -``` - -### Full Restore - -To use `gprestore` to restore from a backup set, you must use the `--timestamp` option to specify the exact timestamp value (YYYYMMDDHHMMSS) to restore. Include the `--create-db` option if the database does not exist in the cluster. If you specified a custom --backup-dir to consolidate the backup files, include the same `--backup-dir` option when using `gprestore` to locate the backup files. - -``` -[gpadmin@whpg_cdw ~]$ psql -c "DROP DATABASE ww_sales"; -DROP DATABASE -[gpadmin@whpg_cdw ~]$ -[gpadmin@whpg_cdw ~]$ gprestore --timestamp 20250515182209 --backup-dir /tmp/single_file --create-db -20250515:18:35:09 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Restore Key = 20250515182209 -20250515:18:35:09 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-gpbackup version = 1.30.5 -20250515:18:35:09 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-gprestore version = 1.30.5 -20250515:18:35:09 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Greenplum Database Version = 6.27.1 build commit:ab5a612bfdc355ad2d601860dfb70a47778c8dd7 -20250515:18:35:09 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Creating database -20250515:18:35:10 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Database creation complete for: ww_sales -20250515:18:35:10 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Restoring pre-data metadata -Pre-data objects restored: 153 / 153 [=================================================] 100.00% 3s -20250515:18:35:14 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Pre-data metadata restore complete -Tables restored: 33 / 33 [============================================================] 100.00% 38s -20250515:18:35:52 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Data restore complete -20250515:18:35:52 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Restoring post-data metadata -20250515:18:35:52 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Post-data metadata restore complete -20250515:18:35:52 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Found neither /usr/local/greenplum-db-6.27.1/bin/gp_email_contacts.yaml nor /home/gpadmin/gp_email_contacts.yaml -20250515:18:35:52 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Email containing gprestore report /tmp/single_file/gpseg-1/backups/20250515/20250515182209/gprestore_20250515182209_20250515183509_report will not be sent -20250515:18:35:52 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Beginning cleanup -20250515:18:36:00 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Cleanup complete -20250515:18:36:00 gprestore:gpadmin:whpg_cdw:032941-[INFO]:-Restore completed successfully -``` - -`gprestore` does not attempt to restore global metadata for the WarehousePG Cluster by default. If this is required, include the `--with-globals` option. - -By default, `gprestore` uses 1 connection to restore table data and metadata. If you have a large backup set which **did not use** the `--single-data-file` option, restore duration can be decreased by specifiying the number of parallel processes using the `--jobs` option. Depending on system resourceds and database size, this number can be tuned for each specific environment. - -``` -[gpadmin@whpg_cdw ~]$ psql -c "DROP DATABASE ww_sales"; -DROP DATABASE -[gpadmin@whpg_cdw ~]$ -[gpadmin@whpg_cdw ~]$ gprestore --timestamp 20250514202713 --create-db --jobs 4 -20250515:18:40:40 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Restore Key = 20250514202713 -20250515:18:40:40 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-gpbackup version = 1.30.5 -20250515:18:40:40 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-gprestore version = 1.30.5 -20250515:18:40:40 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Greenplum Database Version = 6.27.1 build commit:ab5a612bfdc355ad2d601860dfb70a47778c8dd7 -20250515:18:40:40 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Creating database -20250515:18:40:41 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Database creation complete for: ww_sales -20250515:18:40:41 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Restoring pre-data metadata -Pre-data objects restored: 153 / 153 [=================================================] 100.00% 2s -20250515:18:40:43 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Pre-data metadata restore complete -Tables restored: 33 / 33 [============================================================] 100.00% 16s -20250515:18:41:00 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Data restore complete -20250515:18:41:00 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Restoring post-data metadata -20250515:18:41:00 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Post-data metadata restore complete -20250515:18:41:00 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Found neither /usr/local/greenplum-db-6.27.1/bin/gp_email_contacts.yaml nor /home/gpadmin/gp_email_contacts.yaml -20250515:18:41:00 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Email containing gprestore report /data/coordinator/gpseg-1/backups/20250514/20250514202713/gprestore_20250514202713_20250515184040_report will not be sent -20250515:18:41:00 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Beginning cleanup -20250515:18:41:00 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Cleanup complete -20250515:18:41:00 gprestore:gpadmin:whpg_cdw:033527-[INFO]:-Restore completed successfully -[gpadmin@whpg_cdw ~]$ -``` - -### Report Files - -When performing a backup or restore operation, `gpbackup` and `gprestore` generate a report file. When email notification is configured, the email sent contains the contents of the report file. For information about email notification, see Configuring Email Notifications. - -The report file is placed in the WarehousePG Coordinator backup directory. The report file name contains the timestamp of the operation. These are the formats of the `gpbackup` and `gprestore` report file names. - -- `gpbackup__report` -- `gprestore___report` - -For these example report file names, `20250518010000` is the timestamp of the backup and `20250530234643` is the timestamp of the restore operation. - -**`gpbackup_20250518010000_report`** - -**`gprestore_20250518010000_20180213115426_report`** - -This backup directory on a WarehousePG Coordinator host contains both a `gpbackup` and `gprestore` report file. - -``` -[gpadmin@cdw 20250530234643]$ ls -ltr -total 2124 --r--r--r-- 1 gpadmin gpadmin 2120143 May 30 23:46 gpbackup_20250530234643_metadata.sql --r--r--r-- 1 gpadmin gpadmin 38064 May 30 23:46 gpbackup_20250530234643_toc.yaml --r--r--r-- 1 gpadmin gpadmin 1499 May 30 23:46 gpbackup_20250530234643_config.yaml --r--r--r-- 1 gpadmin gpadmin 1837 May 30 23:46 gpbackup_20250530234643_report --r--r--r-- 1 gpadmin gpadmin 539 May 31 00:05 gprestore_20250530234643_20250531000515_report - -``` - -The contents of the report files are similar. This is an example of the contents of a `gprestore` report file. - -``` -WarehosuePG Report - -timestamp key: 20250530234643 -gpdb version: 6.27.1 build commit:ab5a612bfdc355ad2d601860dfb70a47778c8dd7 -gprestore version: 1.30.5 - -database name: test -command line: gprestore --timestamp 20250530234643 --redirect-db test --create-db - -backup segment count: 8 -restore segment count: 8 -start time: Sat May 31 2025 00:05:15 -end time: Sat May 31 2025 00:05:57 -duration: 0:00:42 - -restore status: Success -``` - - - -## Backup History Database - -`gpbackup` stores details of each backup operation in a SQLite database found in `$COORDINATOR_DATA_DIRECTORY/gpbackup_history.db`. Details such as timestamps, command line options, incremental backup details and status are stored in this database. `gpbackup_history.db` is not backed up my `gpbackup`, but can be copied to a secondary location if a backup copy is desired. - -`gpbackup` uses the metadata in `gpbackup_history.db` to create the backup/restore plan for an incremental backup sets when you run `gpbackup` with the `--incremental` option and do not specify the `--from-timesamp` option to indicate the backup that you want to use as the base backup of the incremental backup set. For information about incremental backups, refer to [Incremental Backups with `gpbackup` and `gprestore`](incremental.md). - - - -## Filtering the Contents of a Backup or Restore - -`gpbackup` backs up all schemas and tables in the specified database, unless you exclude or include individual schema or table objects with schema level or table level filter options. - -The schema level options are - -- `--include-schema` -- `--include-schema-file` -- `--exclude-schema` -- `--exclude-schema-file` - command-line options to `gpbackup`. For example, if the `ww_customer` database contains three schemas, `na_customer`, `apac_customer`, `emea_customer`, the following commands back up only the `apac_customer` and `emea_customer` schemas: - -``` -$ gpbackup --dbname ww_customer --exclude-schema na_customer -``` - -Multiple `--include-schema` options may be used in a `gpbackup` or multiple `--exclude-schema` options to filter 2 or many schemas - -``` -$ gpbackup --dbname ww_customer --include-schema apac_customer --include-schema emea_customer -``` - -An alternative to multiple command line options is to use `--include-schema-file` or `--exclude-schema-file`. Each line in the file defines a single schema, and the file cannot contain trailing lines. - -`/tmp/nw_states.schema` contents - -``` -[gpadmin@whpg_cdw tmp]$ cat nw_states.schema -Washington -Oregon -Idaho -Montana -Wyoming -[gpadmin@whpg_cdw tmp]$ -``` - -Example of the command: - -``` -gpbackup --dbname ww_customer --include-schema-file /tmp/nw_states.schema -``` - -Filtering included or excluded tables is similar process to schemas. - -- `--include-table` -- `--exclude-table` -- `--include-table-file` -- `--exclude-table-file ` - -Options use the `schema-name.table-name` format as input on the command line, and in the text file. The individual table filtering options can be used multiple times, but `--include-table` and `--exclude-table` cannot both be used in the same command. - -You can create a list of qualified table names in a text file. Each line in the file defines a single `schema-name.table-name`, and the file cannot contain trailing lines. - -``` -gpbackup --dbname ww_customer --include-table apac_customer.customer_fact -``` - -or - -``` -gpbackup --dbname ww_customer --exclude-table-file /tmp/exclude_tables.file -``` - -where `/tmp/include_tables.file` contents - -``` -[gpadmin@whpg_cdw tmp]$ cat exclude_tables.file -emea_customer.customer_fact -na_customer.customer_fact -[gpadmin@whpg_cdw tmp]$ -``` - -Table and schema names containing upper case letters or spaces must be enclosed with double quotes. - -``` -[gpadmin@whpg_cdw tmp]$ cat exclude_tables_2.file -emea_customer.customer_fact -na_customer.customer_fact -na_customer."ZipCodes" -"WW_GEO".holidays -"WW_GEO"."time zones" -[gpadmin@whpg_cdw tmp]$ -``` - -When `--include-table` or `--include-table-file` is specified on the command line, dependent objects are not automatically backed up or restored. Depenedent objects must be specified in your filter string or file. For example, if you back up or restore a view or materialized view, you must also list the table(s) the view or the materialized view require. If you backup or restore a table containing a sequence, you must also specify the sequence name. - -### Filtering by Leaf Partition - -By default, `gpbackup` creates one file for each table on a data segment. When the `--leaf-partition-data` option is used, `gpbackup` will create one data file per leaf partition of a partitioned table, instead of a single file data file for the root table. You can also filter backups to specific leaf partitions by including the names of the leaf partitions names as you would a stand along table, using the `schema_name.table_name` format. - -``` -gpadmin=# \d+ ww_inventory - Table "WW_GEO.ww_inventory" - Column | Type | Modifiers | Storage | Stats target | Description ------------------------+-------------------+-----------+----------+--------------+------------- - prod_id | integer | | plain | | - prod_sku | character varying | | extended | | - prod_warehouse | character varying | | extended | | - prod_qty_on_hand | integer | | plain | | - prod_date_inventoried | date | | plain | | -Child tables: ww_inventory_1_prt_1, - ww_inventory_1_prt_10, - ww_inventory_1_prt_11, - ww_inventory_1_prt_12, - ww_inventory_1_prt_13, - ww_inventory_1_prt_14, - ww_inventory_1_prt_15, - ww_inventory_1_prt_16, - ww_inventory_1_prt_17, - ww_inventory_1_prt_18, - ww_inventory_1_prt_19, - ww_inventory_1_prt_2, - ww_inventory_1_prt_20, - ww_inventory_1_prt_21, - ww_inventory_1_prt_22, - ww_inventory_1_prt_23, - ww_inventory_1_prt_24, - ww_inventory_1_prt_25, - ww_inventory_1_prt_26, - ww_inventory_1_prt_27, - ww_inventory_1_prt_28, - ww_inventory_1_prt_29, - ww_inventory_1_prt_3, - ww_inventory_1_prt_30, - ww_inventory_1_prt_4, - ww_inventory_1_prt_5, - ww_inventory_1_prt_6, - ww_inventory_1_prt_7, - ww_inventory_1_prt_8, - ww_inventory_1_prt_9 -Distributed by: (prod_id) -Partition by: (prod_date_inventoried) -``` - -The following file `/tmp/may_week1.include` contains the partitions for the first week of May which will be included in our `gpbackup` - -``` -[gpadmin@whpg_cdw ~]$ cat /tmp/may_week1.include -"WW_GEO".ww_inventory_1_prt_1 -"WW_GEO".ww_inventory_1_prt_2 -"WW_GEO".ww_inventory_1_prt_3 -"WW_GEO".ww_inventory_1_prt_4 -"WW_GEO".ww_inventory_1_prt_5 -"WW_GEO".ww_inventory_1_prt_6 -"WW_GEO".ww_inventory_1_prt_7 -``` - -Using the `--include-table-file` and `--leaf-partition-data` options, `gpbackup` will create one data file for each leaf partition specified in the input file - -``` -$ gpbackup --dbname ww_sales --include-table-file /tmp/may_week1.include --leaf-partition-data -``` - -The `--exclude-table-file` option and `--leaf-partition-data` are not compatible. Although you can specify leaf partition names in a file specified with `--exclude-table-file`, `gpbackup` ignores the partition names. - -### Filtering with `gprestore` - -After creating a backup set with `gpbackup`, you can filter the schemas and tables that you want to restore from the backup set using the `gprestore --include-schema` and `--include-table-file` options. These options work in the same way as their `gpbackup` counterparts, but have the following restrictions: - -The tables that you attempt to restore must not already exist in the database. - -If you attempt to restore a schema or table that does not exist in the backup set, the `gprestore` does not run. - -If you use the `--include-schema` option, `gprestore` cannot restore objects that have dependencies on multiple schemas. - -If you use the `--include-table-file` option, `gprestore` does not create roles or set the owner of the tables. The utility restores table indexes and rules. Triggers are also restored but are not supported in WarehousePG. - -The file that you specify with `--include-table-file` cannot include a leaf partition name, as it can when you specify this option with `gpbackup`. If you specified leaf partitions in the backup set, specify the partitioned table to restore the leaf partition data. - -When restoring a backup set that contains data from some leaf partitions of a partitioned table, the partitioned table is restored along with the data for the leaf partitions. For example, you create a backup with the `gpbackup` option `--include-table-file` and the text file lists some leaf partitions of a partitioned table. Restoring the backup creates the partitioned table and restores the data only for the leaf partitions listed in the file. - - - -## Setting Up Email Alerts - -`gpbackup` and `gprestore` can send email notifications via `sendmail` after a backup or restore run completes. - -To have `gpbackup` or `gprestore` send out status email notifications, a `gp_email_contacts.yaml` file must exist in either home directory of the user running `gpbackup` or `gprestore` or the same directory as the utilities ($GPHOME/bin). - -If the `gp_email_contacts.yaml` file is not present, the gpbackup/gprestore log file will have a message similar to: - -``` -20250530:23:46:52 gpbackup:gpadmin:cdw:022290-[INFO]:-Data backup complete -20250530:23:46:52 gpbackup:gpadmin:cdw:022290-[INFO]:-Skipped data backup of 24 external/foreign table(s). -20250530:23:46:52 gpbackup:gpadmin:cdw:022290-[INFO]:-See /home/gpadmin/gpAdminLogs/gpbackup_20250530.log for a complete list of skipped tables. -20250530:23:46:53 gpbackup:gpadmin:cdw:022290-[INFO]:-Found neither /usr/local/greenplum-db-6.27.1/bin/gp_email_contacts.yaml nor /home/gpadmin/gp_email_contacts.yaml -20250530:23:46:53 gpbackup:gpadmin:cdw:022290-[INFO]:-Email containing gpbackup report /data/coordinator/gpseg-1/backups/20250530/20250530234643/gpbackup_20250530234643_report will not be sent -20250530:23:46:53 gpbackup:gpadmin:cdw:022290-[INFO]:-Beginning cleanup -20250530:23:46:53 gpbackup:gpadmin:cdw:022290-[INFO]:-Cleanup complete -20250530:23:46:53 gpbackup:gpadmin:cdw:022290-[INFO]:-Backup completed successfully -``` - -If the `gp_email_contacts.yaml` file is present, can configured properly, a similar message will be printed to the logs: - -```` -20250514:20:27:23 gpbackup:gpadmin:whpg_cdw:027069-[INFO]:-/home/gpadmin/gp_email_contacts.yaml list found, /data/coordinator/gpseg-1/backups/20250514/20250514202713/gpbackup_20250514202713_report will be sent``` -```` - -The `$HOME/gp_email_contacts.yaml` file will override any configurations found in the `$GPHOME/bin/gp_email_contacts.yaml` - -The email subject line includes the utility name, timestamp, status, and the name of the WarehousePG Coordinator. This is an example subject line for a `gpbackup` email. - -``` -gpbackup 20250514202713 on whpg_cdw completed: Success -``` - -or - -``` -gprestore 20250515182209 on whpg_cdw completed: Failure -``` - -The email contains summary information about the operation including options, duration, and number of objects backed up or restored. For information about the contents of a notification email, see Report Files. - -### gp_email_contacts.yaml file format - -The `gpbackup` and `gprestore` email notification YAML file gp_email_contacts.yaml uses indentation (spaces) to determine the document hierarchy and the relationships of the sections to one another. The use of white space is significant. White space should not be used simply for formatting purposes, and tabs should not be used at all. - -Note: If the status parameters are not specified correctly, the utility does not issue a warning. For example, if the success parameter is misspelled and is set to true, a warning is not issued and an email is not sent to the email address after a successful operation. To ensure email notification is configured correctly, run tests with email notifications configured. - -This is the format of the gp_email_contacts.yaml YAML file for `gpbackup` email notifications: - -``` -contacts: - gpbackup: - - address: name@domain - status: - success: [true | false] - success_with_errors: [true | false] - failure: [true | false] - gprestore: - - address: name@domain - status: - success: [true | false] - success_with_errors: [true | false] - failure: [true | false] -``` - -##### Email YAML File Sections - -**contacts:** Required. The section that contains the `gpbackup` and `gprestore` sections. The YAML file can contain a `gpbackup` section, a `gprestore` section, or one of each. - -**gpbackup** : Optional. Begins the gpbackup email section. - -**address** : Required. At least one email address must be specified. Multiple email address parameters can be specified. Each address requires a status section. - -:::tip Note -name@domainis a single, valid email address. -::: - -**status** : Required. Specify when the utility sends an email to the specified email address. The default is to not send email notification. - -You specify sending email notifications based on the completion status of a backup or restore operation. At least one of these parameters must be specified and each parameter can appear at most once. - -**success** : Optional. Specify if an email is sent if the operation completes without errors. If the value is true, an email is sent if the operation completes without errors. If the value is false (the default), an email is not sent. - -**success_with_errors** : Optional. Specify if an email is sent if the operation completes with errors. If the value is true, an email is sent if the operation completes with errors. If the value is false (the default), an email is not sent. - -**failure** : Optional. Specify if an email is sent if the operation fails. If the value is true, an email is sent if the operation fails. If the value is false (the default), an email is not sent. - -**gprestore** : Optional. Begins the gprestore email section. This section contains the address and status parameters that are used to send an email notification after a `gprestore` operation. The syntax is the same as the gpbackup section. - -#### Examples - -This example YAML file specifies sending email to email addresses depending on the success or failure of an operation. For a backup operation, an email is sent to a different address depending on the success or failure of the backup operation. For a restore operation, an email is sent to single address only when the operation succeeds or completes with errors. - -``` -contacts: - gpbackup: - - address: dba_backup_success@whpg.io - status: - success:true - - address: dba_backup_failure@whpg.io - status: - success_with_errors: true - failure: true - gprestore: - - address: dba_restore_status@example.com - status: - success: true - success_with_errors: true -``` - - - -## Backup Files Details - -A complete backup set for `gpbackup` includes multiple metadata files, supporting files, and CSV data files, each designated with the timestamp at which the backup was created. - -By default, metadata and supporting files are stored on the WarehousePG coordinator host in the directory `$COORDINATOR_DATA_DIRECTORY/backups/YYYYMMDD/YYYYMMDDHHMMSS/`. If you specify a custom backup directory, this same file path is created as a subdirectory of the backup directory. The following table describes the names and contents of the metadata and supporting files. - -:::tip Warning: -All `gpbackup` metadata files are created with read-only permissions. Never delete or modify the metadata files for a `gpbackup` backup set. Doing so may render the backup files non-functional. -::: - -### Coordinator Metadata Files - -#### `gpbackup__metadata.sql` - -Contains global and database-specific metadata: - -- DDL for objects that are global to the WarehousePG cluster, and not owned by a specific database within the cluster. -- DDL for objects in the backed-up database (specified with --dbname) that must be created before to restoring the actual data, and DDL for objects that must be created after restoring the data. - -##### Global objects include: - -- Tablespaces -- Databases -- Database-wide configuration parameter settings (GUCs) -- Resource group definitions -- Resource queue definitions -- Roles -- GRANT assignments of roles to databases - -:::tip Note -Note: Global metadata is not restored by default. You must include the --with-globals option to the `gprestore` command to restore global metadata. -::: - -**Database-specific objects** -that must be created before to restoring the actual data include: - -- Session-level configuration parameter settings (GUCs) -- Schemas -- Procedural language extensions -- Types -- Sequences -- Functions -- Tables -- Protocols -- Operators and operator classes -- Conversions -- Aggregates -- Casts -- Views -- Materialized Views (only view definition is backed up / restored, not data) -- Constraints -- Database-specific objects that must be created after restoring the actual data include: -- Indexes -- Rules -- Triggers. (While WarehousePG does not support triggers, any trigger definitions that are present are backed up and restored.) - -example: - -``` -CREATE TABLE uat.refund ( - returned_date_sk integer, - returned_time_sk integer, - item_sk integer, - refunded_customer_sk integer, - refunded_cdemo_sk integer, - refunded_hdemo_sk integer, -) DISTRIBUTED RANDOMLY; - -ALTER TABLE uat.refund OWNER TO gpadmin; - -CREATE INDEX item_sk_cr_fee_idx ON uat.refund USING btree (item_sk, fee); - -CREATE INDEX item_sk_idx ON uat.refund USING btree (item_sk); -``` - -#### `gpbackup__toc.yaml` - -Table of contents file, containing location information of the various object DDL in the `gpbackup__metadata.sql` files - -This file also contains the table names and OIDs used for locating the corresponding table data in CSV data files that are created on each segment. - -example: - -``` -- schema: tpcds - name: household_demographics - oid: 37231 - attributestring: (hd_demo_sk,hd_income_band_sk,hd_buy_potential,hd_dep_count,hd_vehicle_count) - rowscopied: 7200 - partitionroot: "" - isreplicated: false - distbyenum: false -- schema: tpcds - name: income_band - oid: 37238 - attributestring: (ib_income_band_sk,ib_lower_bound,ib_upper_bound) - rowscopied: 20 - partitionroot: "" - isreplicated: false - distbyenum: false -- schema: tpcds - name: inventory - oid: 37245 - attributestring: (inv_date_sk,inv_item_sk,inv_warehouse_sk,inv_quantity_on_hand) - rowscopied: 11745000 - partitionroot: "" - isreplicated: false - distbyenum: false -``` - -See [Segment Data Files](#segfiles) - -#### `gpbackup__report` - -Contains information about the backup operation that is used to populate the email notice (if configured) that is sent after the backup completes. This file contains information such as: - -- Command-line options that were provided -- Database that was backed up -- Database version -- Backup type - -example: - -``` -WarehousePG Backup Report - -timestamp key: 20250530232002 -gpdb version: 6.27.1 build commit:ab5a612bfdc355ad2d601860dfb70a47778c8dd7 -gpbackup version: 1.30.5 - -database name: whpg_tpcds -command line: gpbackup --dbname whpg_tpcds --no-compression --single-data-file --backup-dir /tmp/whpg_tpcds_backups -compression: None -plugin executable: None -backup section: All Sections -object filtering: None -includes statistics: No -data file format: Single Data File Per Segment -incremental: False - -start time: Fri May 30 2025 23:20:02 -end time: Fri May 30 2025 23:20:13 -duration: 0:00:11 - -backup status: Success - -database size: 1699 MB -segment count: 3 - -count of database objects in backup: -aggregates 0 -casts 0 -collations 0 -constraints 0 -conversions 0 -default privileges 0 -database gucs 1 -event triggers 0 -extensions 0 -foreign data wrappers 0 -foreign servers 0 -functions 0 -indexes 2 -``` - -See [Setting Up Email Alerts](#email) - -#### `gpbackup__config.yaml` - -Contains metadata about the execution of the particular backup task, including: - -- `gpbackup` version -- Database name -- WarehousePG version -- Additional option settings such as `--no-compression`,` --compression-level`, `--metadata-only`, `--data-only`, and `--with-stats`. - -example: - -``` -backupdir: /tmp/whpg_tpcds_backups -backupversion: 1.30.5 -compressed: false -compressiontype: gzip -databasename: whpg_tpcds -databaseversion: 6.27.1 build commit:ab5a612bfdc355ad2d601860dfb70a47778c8dd7 -segmentcount: 8 -dataonly: false -datedeleted: "" -excluderelations: [] -excludeschemafiltered: false -excludeschemas: [] -excludetablefiltered: false -includerelations: [] -includeschemafiltered: false -includeschemas: [] -includetablefiltered: false -incremental: false -leafpartitiondata: false -metadataonly: false -plugin: "" -pluginversion: "" -restoreplan: -- timestamp: "20250530232002" - tablefqns: - - tpcds.call_center - - tpcds.catalog_page - - tpcds.catalog_returns - - tpcds.catalog_sales - - tpcds.customer - - tpcds.customer_address - - tpcds.customer_demographics -``` - - - -### Segment Data Files - -By default, each segment creates one compressed CSV file for each table that is backed up on the segment. You can optionally specify the `--single-data-file` option to create a single data file on each segment. The files are stored in `/backups/YYYYMMDD/YYYYMMDDHHMMSS/`. - -If you specify a custom backup directory, segment data files are copied to this same file path as a subdirectory of the backup directory. If you include the `--leaf-partition-data` option, `gpbackup` creates one data file for each leaf partition of a partitioned table, instead of just one table for file. - -By default, each table is backed up into a distinct file on the segment hosts: -The file uses a name format `gpbackup___.gz` where: - -``is the content ID of the segment. -`` is the timestamp of the `gpbackup` operation. -`` is the object ID of the table. - -#### default multiple data file example - -``` --rw------- 1 gpadmin gpadmin 216 May 30 23:46 gpbackup_1_20250530234643_32812.zst --rw------- 1 gpadmin gpadmin 177641 May 30 23:46 gpbackup_1_20250530234643_32822.zst --rw------- 1 gpadmin gpadmin 3080557 May 30 23:46 gpbackup_1_20250530234643_32829.zst --rw------- 1 gpadmin gpadmin 32449514 May 30 23:46 gpbackup_1_20250530234643_36476.zst --rw------- 1 gpadmin gpadmin 1989827 May 30 23:46 gpbackup_1_20250530234643_37203.zst --rw------- 1 gpadmin gpadmin 475551 May 30 23:46 gpbackup_1_20250530234643_37210.zst --rw------- 1 gpadmin gpadmin 3002507 May 30 23:46 gpbackup_1_20250530234643_37217.zst --rw------- 1 gpadmin gpadmin 535332 May 30 23:46 gpbackup_1_20250530234643_37224.zst --rw------- 1 gpadmin gpadmin 8895 May 30 23:46 gpbackup_1_20250530234643_37231.zst --rw------- 1 gpadmin gpadmin 74 May 30 23:46 gpbackup_1_20250530234643_37238.zst --rw------- 1 gpadmin gpadmin 19518846 May 30 23:46 gpbackup_1_20250530234643_37245.zst --rw------- 1 gpadmin gpadmin 606613 May 30 23:46 gpbackup_1_20250530234643_37459.zst --rw------- 1 gpadmin gpadmin 4595 May 30 23:46 gpbackup_1_20250530234643_37466.zst --rw------- 1 gpadmin gpadmin 177 May 30 23:46 gpbackup_1_20250530234643_37473.zst --rw------- 1 gpadmin gpadmin 152 May 30 23:46 gpbackup_1_20250530234643_37480.zst --rw------- 1 gpadmin gpadmin 327 May 30 23:46 gpbackup_1_20250530234643_37487.zst --rw------- 1 gpadmin gpadmin 4710343 May 30 23:46 gpbackup_1_20250530234643_37494.zst -``` - - **`--single-data-file`** example - -All table data for a particular segment is written to a single file: - -- `gpbackup__` - -With a corresponding table of contents files: - -- `gpbackup___toc.yaml` - -``` --rw-rw-r-- 1 gpadmin gpadmin 417025744 May 30 23:20 gpbackup_0_20250530232002 --r--r--r-- 1 gpadmin gpadmin 2035 May 30 23:20 gpbackup_0_20250530232002_toc.yaml -``` - -The metadata file `gpbackup__toc.yaml` references this `` to locate the data for a specific table in a schema. - -You can optionally specify the gzip compression level (from 1-9) using the `--compression-level` option, or disable compression entirely with `--no-compression`. If you do not specify a compression level, `gpbackup` uses compression level 1 by default. - - - -## Return Codes - -One of these codes is returned after `gpbackup` or `gprestore` completes. - -0 – Backup or restore completed with no problems -1 – Backup or restore completed with non-fatal errors. See log file for more information. -2 – Backup or restore failed with a fatal error. See log file for more information. - - - -## Supported WHPG versions - -The WarehousePG provided `gpbackup` and `gprestore` utilities are compatible with WarehousePG versions - -- 6.27.1 or later -- 7.2.1-WHPG or later - - - -## Limitations - -`gpbackup` and `gprestore` have the following limitations: - -If you create an index on a parent partitioned table, `gpbackup` does not back up that same index on child partitioned tables of the parent, as creating the same index on a child would cause an error. However, if you exchange a partition, `gpbackup` does not detect that the index on the exchanged partition is inherited from the new parent table. In this case, `gpbackup` backs up conflicting CREATE INDEX statements, which causes an error when you restore the backup set. - -You can execute multiple instances of `gpbackup`, but each execution requires a distinct timestamp. - -Database object filtering is currently limited to schemas and tables. - -When backing up a partitioned table where some or all leaf partitions are in different schemas from the root partition, the leaf partition table definitions, including the schemas, are backed up as metadata. This occurs even if the backup operation specifies that schemas that contain the leaf partitions should be excluded. To control data being backed up for this type of partitioned table in this situation, use the `--leaf-partition-data` option. - -If the `--leaf-partition-data` option is not specified, the leaf partition data is also backed up even if the backup operation specifies that the leaf partition schemas should excluded. -If the `--leaf-partition-data` option is specified, the leaf partition data is not be backed up if the backup operation specifies that the leaf partition schemas should excluded. Only the metadata for leaf partition tables are backed up. -If you use the `gpbackup` --single-data-file option to combine table backups into a single file per segment, you cannot perform a parallel restore operation with `gprestore` (cannot set --jobs to a value higher than 1). - -You cannot use the `--exclude-table-file` with `--leaf-partition-data`. Although you can specify leaf partition names in a file specified with `--exclude-table-file`, `gpbackup` ignores the partition names. - -Backing up a database with `gpbackup` while simultaneously running DDL commands might cause `gpbackup` to fail, in order to ensure consistency within the backup set. For example, if a table is dropped after the start of the backup operation, `gpbackup` exits and displays the error message ERROR: relation `` does not exist. - -`gpbackup` might fail when a table is dropped during a backup operation due to table locking issues. `gpbackup` generates a list of tables to back up and acquires an ACCESS SHARED lock on the tables. If an `EXCLUSIVE LOCK` is held on a table, `gpbackup` acquires the `ACCESS SHARED` lock after the existing lock is released. If the table no longer exists when `gpbackup` attempts to acquire a lock on the table, `gpbackup` exits with the error message. - -For tables that might be dropped during a backup, you can exclude the tables from a backup with a `gpbackup` table filtering option such as `--exclude-table` or --exclude-schema. - -A backup created with `gpbackup` can only be restored to a WarehousePG cluster with the same number of segment instances as the source cluster. If you run gpexpand to add segments to the cluster, backups you made before starting the expand cannot be restored after the expansion has completed. - -**Parent topic:** [WarehousePG Administrator Guide](../index.md) +The `gpbackup` and `gprestore` documentation has moved to the [WarehousePG Backup and Restore](../../../../whpg-backup/index.md) section. diff --git a/docs/whpg/7x/admin_guide/managing/backup-main.md b/docs/whpg/7x/admin_guide/managing/backup-main.md index 7ed9c77..8d47816 100644 --- a/docs/whpg/7x/admin_guide/managing/backup-main.md +++ b/docs/whpg/7x/admin_guide/managing/backup-main.md @@ -11,11 +11,7 @@ WarehousePG supports parallel and non-parallel methods for backing up and restor ## Parallel Backup with gpbackup and gprestore -`gpbackup` and `gprestore` are the recommended WarehousePG backup and restore utilities. `gpbackup` utilizes `ACCESS SHARE` locks at the individual table level, instead of `EXCLUSIVE` locks on the `pg_class` catalog table. This enables you to run DML statements during the backup, such as `CREATE`, `ALTER`, `DROP`, and `TRUNCATE` operations, as long as those operations do not target the current backup set. Backup files created with `gpbackup` are designed to provide future capabilities for restoring individual database objects along with their dependencies, such as functions and required user-defined datatypes. - -`gpbackup`, `gprestore`, and related utilities are provided as a separate download - -![Parallel Restore Using Parallel Backup Files](../../images/parallel_backup_restore.png "Parallel Restore Using Parallel Backup Files") +`gpbackup` and `gprestore` are the recommended WarehousePG backup and restore utilities, provided as a separate download. For documentation, see [WarehousePG Backup and Restore](../../../../whpg-backup/index.md). diff --git a/docs/whpg/7x/index.md b/docs/whpg/7x/index.md index 36c4f0e..4714f41 100644 --- a/docs/whpg/7x/index.md +++ b/docs/whpg/7x/index.md @@ -35,4 +35,4 @@ WarehousePG is based on **PostgreSQL open-source technology**. It is essentially [Security Guide](/docs/7x/security_guide/index.md) -[Backup & Restore Guide](/docs/7x/admin_guide/backup_restore/index.md) +[Backup & Restore Guide](/whpg-backup/index.md) diff --git a/docs/whpg/7x/ref_guide/utility_guide/reference/index.md b/docs/whpg/7x/ref_guide/utility_guide/reference/index.md index 6cd72df..efbe8b3 100644 --- a/docs/whpg/7x/ref_guide/utility_guide/reference/index.md +++ b/docs/whpg/7x/ref_guide/utility_guide/reference/index.md @@ -10,7 +10,6 @@ navigation: - gpactivatestandby - gpaddmirrors - gpbackup_manager - - gpbackup - gpcheckcat - gpcheckperf - gpconfig @@ -26,7 +25,6 @@ navigation: - gpmovemirrors - gprecoverseg - gpreload - - gprestore - gpssh - gpssh-exkeys - gpstart @@ -49,7 +47,9 @@ WarehousePG uses the standard PostgreSQL client and server programs and provides Several utilities are installed when you install the WarehousePG server. These utilities reside in `$GPHOME/bin`. -Other utilities such as clients and backup/restore may be found at [Warehouse PG Github Repo](https://github.com/warehouse-pg) +For the `gpbackup` and `gprestore` utilities, see [WarehousePG Backup and Restore](../../../../../whpg-backup/index.md). + +Other utilities such as clients may be found at [Warehouse PG Github Repo](https://github.com/warehouse-pg) WarehousePG provides the following utility programs. Superscripts identify those utilities that require separate downloads, as well as those utilities that are also installed with the Client and Loader Tools Packages. (See the Note following the table.) All utilities are installed when you install the WarehousePG server, unless specifically identified by a superscript. @@ -61,7 +61,6 @@ WarehousePG provides the following utility programs. Superscripts identify those - [dropuser](dropuser.md)1 - [gpactivatestandby](gpactivatestandby.md) - [gpaddmirrors](gpaddmirrors.md) -- [gpbackup](gpbackup.md)2 - [gpcheckcat](gpcheckcat.md) - [gpcheckperf](gpcheckperf.md) - [gpconfig](gpconfig.md) @@ -75,7 +74,6 @@ WarehousePG provides the following utility programs. Superscripts identify those - [gpmovemirrors](gpmovemirrors.md) - [gprecoverseg](gprecoverseg.md) - [gpreload](gpreload.md) -- [gprestore](gprestore.md)2 - [gpssh](gpssh.md) - [gpssh-exkeys](gpssh-exkeys.md) - [gpstart](gpstart.md) @@ -97,8 +95,6 @@ WarehousePG provides the following utility programs. Superscripts identify those > 1 The utility program is also installed with the **WarehousePG Client and Loader Tools Package** -> 2 The utility program can be obtained from the **WarehousePG Backup and Restore** - Additional utilities may be found at [Warehouse PG Github Org Repo](https://github.com/warehouse-pg) **Parent topic:** [WarehousePG Utility Guide](index.md)