From 9de5d40106135f1235b4c1b0b29448910a4b3c8a Mon Sep 17 00:00:00 2001 From: Patrick Birch <48594400+patrickbirch@users.noreply.github.com> Date: Fri, 5 Jun 2026 05:08:29 -0500 Subject: [PATCH] PXB-3803 [DOCS] - [feedback] PXB 8.4 Quickstart, Restore the backup new file: docs/docker-compose-tutorial.md modified: docs/docker.md modified: docs/quickstart-docker.md modified: docs/quickstart-exit.md modified: docs/quickstart-next-steps.md modified: docs/quickstart-overview.md modified: docs/quickstart-restore-back.md modified: mkdocs-base.yml --- docs/docker-compose-tutorial.md | 757 ++++++++++++++++++++++++++++++++ docs/docker.md | 4 + docs/quickstart-docker.md | 144 +++--- docs/quickstart-exit.md | 169 ++++--- docs/quickstart-next-steps.md | 41 +- docs/quickstart-overview.md | 112 +++-- docs/quickstart-restore-back.md | 405 +++++++++++------ mkdocs-base.yml | 1 + 8 files changed, 1353 insertions(+), 280 deletions(-) create mode 100644 docs/docker-compose-tutorial.md diff --git a/docs/docker-compose-tutorial.md b/docs/docker-compose-tutorial.md new file mode 100644 index 000000000..e81d6834c --- /dev/null +++ b/docs/docker-compose-tutorial.md @@ -0,0 +1,757 @@ +# Docker Compose backup and restore tutorial + +This tutorial demonstrates a production-ready approach to backing up, validating, and restoring Percona Server for MySQL using Percona XtraBackup in a Docker Compose environment. + +## Overview + +In a containerized environment, restoring a physical backup requires a strict sequence because you cannot overwrite data files while the database engine is running. Furthermore, physical files recovered by the `root` user cause permissions errors when the database tries to boot as the `mysql` user. + +This tutorial teaches you to: + +* Set up a complete Docker Compose environment with Percona Server and Percona XtraBackup +* Take and prepare a full backup +* Validate that the backup is functional before using it +* Simulate a disaster scenario +* Execute a complete restore operation +* Understand the critical role of file permissions in containerized restores + +## Prerequisites + +* [Docker :octicons-link-external-16:](https://docs.docker.com/engine/install/) installed on your system +* [Docker Compose :octicons-link-external-16:](https://docs.docker.com/compose/install/) installed (included with Docker Desktop) +* Basic familiarity with Docker concepts + +## Architecture + +This tutorial uses Docker Compose profiles to separate backup operations into distinct tasks: + +| Profile | Service | Purpose | +|---------|---------|---------| +| (default) | `psmysql` | Primary Percona Server for MySQL instance | +| `backup` | `pxb-backup` | Takes and prepares backups | +| `validate` | `pxb-validate` | Launches an isolated database from backup files | +| `restore` | `pxb-restore` | Restores backup files to the primary database | + +Using profiles ensures that backup, validation, and restore operations only run when explicitly invoked. + +## Step 1: Set up the project structure + +Create a project directory with the following structure: +{.power-number} + +1. Create the project directory and navigate to it: + + ```shell + mkdir pxb-tutorial && cd pxb-tutorial + ``` + + If the command executes successfully, the expected output is empty. You are now in the `pxb-tutorial` directory. + +2. Create the secrets directory: + + ```shell + mkdir secrets + ``` + + If the command executes successfully, the expected output is empty. + +3. Create the password file: + + ```shell + echo "YourSecurePassword123" > secrets/db_root_pwd.txt + ``` + + If the command executes successfully, the expected output is empty. + + !!! warning + + In production, use a strong, randomly generated password and secure the secrets directory with appropriate file permissions. + +4. Verify the project structure: + + ```shell + ls -la + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + total 0 + drwxr-xr-x 3 user staff 96 Jun 4 10:00 . + drwxr-xr-x 5 user staff 160 Jun 4 10:00 .. + drwxr-xr-x 3 user staff 96 Jun 4 10:00 secrets + ``` + +## Step 2: Create the Docker Compose file + +Create a file named `docker-compose.yml` in your project directory. Select the configuration for your system architecture: + +=== "AMD64 (Intel/AMD)" + + ```yaml + services: + # Main Database Engine + psmysql: + image: percona/percona-server:8.4 + container_name: psmysql + environment: + MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_pwd + volumes: + - mysql_data:/var/lib/mysql + ports: + - "3306:3306" + secrets: + - db_root_pwd + + # BACKUP & PREPARE TASK + pxb-backup: + image: percona/percona-xtrabackup:8.4 + container_name: pxb_backup + user: root + depends_on: + - psmysql + volumes: + - mysql_data:/var/lib/mysql:ro + - backupvol:/backup_84 + secrets: + - db_root_pwd + command: > + /bin/bash -c " + export MYSQL_PWD=$$(cat /run/secrets/db_root_pwd); + xtrabackup --backup --datadir=/var/lib/mysql/ --target-dir=/backup_84 --user=root; + xtrabackup --prepare --target-dir=/backup_84 + " + profiles: + - backup + + # RESTORE TASK (Destructive - Requires psmysql to be stopped) + pxb-restore: + image: percona/percona-xtrabackup:8.4 + container_name: pxb_restore + user: root + volumes: + - mysql_data:/var/lib/mysql + - backupvol:/backup_84 + command: > + /bin/bash -c " + echo '==> Clearing current database directory...'; + rm -rf /var/lib/mysql/* && + echo '==> Restoring physical data files from backupvol...'; + xtrabackup --copy-back --target-dir=/backup_84 --datadir=/var/lib/mysql/ && + echo '==> Fixing file permissions for Percona Server...'; + chown -R mysql:mysql /var/lib/mysql + " + profiles: + - restore + + # VALIDATION TASK (Launches an isolated, temporary DB from the backup) + pxb-validate: + image: percona/percona-server:8.4 + container_name: pxb_validate + environment: + MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_pwd + volumes: + - backupvol:/var/lib/mysql + ports: + - "3307:3306" + secrets: + - db_root_pwd + user: root + entrypoint: > + /bin/bash -c " + chown -R mysql:mysql /var/lib/mysql && + exec gosu mysql mysqld + " + profiles: + - validate + + volumes: + mysql_data: + backupvol: + + secrets: + db_root_pwd: + file: ./secrets/db_root_pwd.txt + ``` + +=== "ARM64 (Apple Silicon Macs)" + + ```yaml + services: + # Main Database Engine + psmysql: + image: percona/percona-server:8.4-aarch64 + container_name: psmysql + environment: + MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_pwd + volumes: + - mysql_data:/var/lib/mysql + ports: + - "3306:3306" + secrets: + - db_root_pwd + + # BACKUP & PREPARE TASK + pxb-backup: + image: percona/percona-xtrabackup:8.4-aarch64 + container_name: pxb_backup + user: root + depends_on: + - psmysql + volumes: + - mysql_data:/var/lib/mysql:ro + - backupvol:/backup_84 + secrets: + - db_root_pwd + command: > + /bin/bash -c " + export MYSQL_PWD=$$(cat /run/secrets/db_root_pwd); + xtrabackup --backup --datadir=/var/lib/mysql/ --target-dir=/backup_84 --user=root; + xtrabackup --prepare --target-dir=/backup_84 + " + profiles: + - backup + + # RESTORE TASK (Destructive - Requires psmysql to be stopped) + pxb-restore: + image: percona/percona-xtrabackup:8.4-aarch64 + container_name: pxb_restore + user: root + volumes: + - mysql_data:/var/lib/mysql + - backupvol:/backup_84 + command: > + /bin/bash -c " + echo '==> Clearing current database directory...'; + rm -rf /var/lib/mysql/* && + echo '==> Restoring physical data files from backupvol...'; + xtrabackup --copy-back --target-dir=/backup_84 --datadir=/var/lib/mysql/ && + echo '==> Fixing file permissions for Percona Server...'; + chown -R mysql:mysql /var/lib/mysql + " + profiles: + - restore + + # VALIDATION TASK (Launches an isolated, temporary DB from the backup) + pxb-validate: + image: percona/percona-server:8.4-aarch64 + container_name: pxb_validate + environment: + MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_pwd + volumes: + - backupvol:/var/lib/mysql + ports: + - "3307:3306" + secrets: + - db_root_pwd + user: root + entrypoint: > + /bin/bash -c " + chown -R mysql:mysql /var/lib/mysql && + exec gosu mysql mysqld + " + profiles: + - validate + + volumes: + mysql_data: + backupvol: + + secrets: + db_root_pwd: + file: ./secrets/db_root_pwd.txt + ``` + +!!! note "About the `$$` syntax" + + The `$$` in the YAML file escapes the `$` character for Docker Compose. Docker Compose interprets `$` as a variable, so `$$` produces a literal `$` in the command. + +### Key configuration details + +| Configuration | Explanation | +|---------------|-------------| +| `user: root` | Required for `pxb-backup` and `pxb-restore` to access MySQL data files and modify permissions | +| `mysql_data:/var/lib/mysql:ro` | The `:ro` flag mounts the volume as read-only for the backup service, ensuring data integrity | +| `chown -R mysql:mysql` | Resets file ownership after restore; MySQL refuses to start if files are owned by `root` | +| `profiles` | Services only start when their profile is explicitly activated | +| `gosu mysql mysqld` | Drops from `root` to `mysql` user before starting the database | + +## Step 3: Start the primary database and add test data + +Start the primary Percona Server instance and create some test data. +{.power-number} + +1. Start the primary database: + + ```shell + docker compose up -d psmysql + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Running 3/3 + ✔ Network pxb-tutorial_default Created + ✔ Volume "pxb-tutorial_mysql_data" Created + ✔ Container psmysql Started + ``` + +2. Wait for the database to initialize (about 30 seconds), then connect to it: + + ```shell + docker exec -it psmysql mysql -uroot -p + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + Enter password: + Welcome to the MySQL monitor. Commands end with ; or \g. + Your MySQL connection id is 8 + Server version: 8.4.2-2 Percona Server (GPL), Release 2, Revision b575402d + + Copyright (c) 2009-2024 Percona LLC and/or its affiliates + Copyright (c) 2000, 2024, Oracle and/or its affiliates. + + Oracle is a registered trademark of Oracle Corporation and/or its + affiliates. Other names may be trademarks of their respective + owners. + + Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + + mysql> + ``` + + Enter the password from your secrets file (`YourSecurePassword123`) when prompted. + +3. Create a test database and table: + + ```sql + CREATE DATABASE mydb; + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + Query OK, 1 row affected (0.01 sec) + ``` + + ```sql + USE mydb; + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + Database changed + ``` + + ```sql + CREATE TABLE employees ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(100), + email VARCHAR(100), + country VARCHAR(50) + ); + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + Query OK, 0 rows affected (0.03 sec) + ``` + + ```sql + INSERT INTO employees (name, email, country) VALUES + ('Erasmus Richardson', 'erasmus@example.com', 'England'), + ('Jenna French', 'jenna@example.com', 'Canada'), + ('Alfred Dejesus', 'alfred@example.com', 'Austria'); + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + Query OK, 3 rows affected (0.01 sec) + Records: 3 Duplicates: 0 Warnings: 0 + ``` + +4. Verify the data was inserted: + + ```sql + SELECT * FROM employees; + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + +----+--------------------+---------------------+---------+ + | id | name | email | country | + +----+--------------------+---------------------+---------+ + | 1 | Erasmus Richardson | erasmus@example.com | England | + | 2 | Jenna French | jenna@example.com | Canada | + | 3 | Alfred Dejesus | alfred@example.com | Austria | + +----+--------------------+---------------------+---------+ + 3 rows in set (0.00 sec) + ``` + +5. Exit the MySQL client: + + ```sql + exit + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + Bye + ``` + +## Step 4: Take and prepare a backup + +Run the backup service to create a full backup and prepare it for restoration. +{.power-number} + +1. Run the backup task: + + ```shell + docker compose run --rm pxb-backup + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + xtrabackup version 8.4.0-2 based on MySQL server 8.4.2 Linux (x86_64) + ... + [Note] [MY-011825] [Xtrabackup] Executing LOCK TABLES FOR BACKUP + ... + [Note] [MY-011825] [Xtrabackup] completed OK! + + [Note] [MY-011825] [Xtrabackup] recognized server arguments: --innodb_checksum_algorithm=crc32 + ... + [Note] [MY-011825] [Xtrabackup] completed OK! + ``` + + The backup service performs two operations: + + * `xtrabackup --backup`: Creates a physical copy of the database files + * `xtrabackup --prepare`: Applies transaction logs to make the backup consistent + +## Step 5: Validate the backup + +Before relying on a backup for disaster recovery, verify that it is functional. The validation service launches an independent, temporary Percona Server instance that boots directly from the backup files. + +!!! note "Why validate?" + + A backup that has not been tested for recovery provides no guarantee of data protection. Validation proves that backup files are functional before you need them in an emergency. + +Do the following to validate the backup: +{.power-number} + +1. Start the validation container: + + ```shell + docker compose up -d pxb-validate + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Running 1/1 + ✔ Container pxb_validate Started + ``` + +2. Check the container logs to ensure it initializes properly: + + ```shell + docker compose logs pxb-validate + ``` + + Look for `ready for connections` in the output. + + ??? example "Expected output" + + ```{.text .no-copy} + pxb_validate | [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4.2-2) starting as process 7 + ... + pxb_validate | [System] [MY-011323] [Server] X Plugin ready for connections. + pxb_validate | [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. + ``` + +3. Connect to the validation instance on port `3307` and verify your data: + + ```shell + docker exec -it pxb_validate mysql -uroot -p -e "SELECT * FROM mydb.employees;" + ``` + + Enter the password (`YourSecurePassword123`) when prompted. + + ??? example "Expected output" + + ```{.text .no-copy} + Enter password: + +----+--------------------+---------------------+---------+ + | id | name | email | country | + +----+--------------------+---------------------+---------+ + | 1 | Erasmus Richardson | erasmus@example.com | England | + | 2 | Jenna French | jenna@example.com | Canada | + | 3 | Alfred Dejesus | alfred@example.com | Austria | + +----+--------------------+---------------------+---------+ + ``` + +4. Stop the validation container when finished: + + ```shell + docker compose stop pxb-validate + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Stopping 1/1 + ✔ Container pxb_validate Stopped + ``` + +## Step 6: Simulate a disaster + +To practice restoration, simulate total data loss by stopping the primary database and wiping its data volume. + +!!! warning + + This step intentionally destroys all data in the primary database. In a real environment, you would only do this if data corruption or loss has already occurred. + +Do the following to simulate a disaster: +{.power-number} + +1. Stop the primary database container: + + ```shell + docker compose stop psmysql + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Stopping 1/1 + ✔ Container psmysql Stopped + ``` + +2. Wipe the production data directory (simulating drive failure or data corruption): + + ```shell + docker compose run --rm --user root psmysql bash -c "rm -rf /var/lib/mysql/*" + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Creating 1/0 + ✔ Container pxb-tutorial-psmysql-run-xxxxx Created + [+] Running 1/0 + ✔ Container pxb-tutorial-psmysql-run-xxxxx Started + ``` + + The command output shows a temporary container being created and run. After execution, no additional output appears because the `rm` command produces no output on success. + +3. Verify the database cannot start (optional): + + If you attempt to start the database now, it will fail because its data files are missing: + + ```shell + docker compose start psmysql + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Running 1/1 + ✔ Container psmysql Started + ``` + + ```shell + docker compose logs psmysql + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + psmysql | [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4.2-2) starting as process 1 + psmysql | [System] [MY-013576] [InnoDB] InnoDB initialization has started. + psmysql | [ERROR] [MY-012224] [InnoDB] Tablespace open failed for '"./ibdata1"' + psmysql | [ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error: Generic error. + psmysql | [ERROR] [MY-010334] [Server] Failed to initialize DD Storage Engine + psmysql | [ERROR] [MY-010020] [Server] Data Dictionary initialization failed. + psmysql | [ERROR] [MY-010119] [Server] Aborting + psmysql | [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.4.2-2) + ``` + + The logs show that MySQL cannot find its system tablespace (`ibdata1`) and fails to start. + +## Step 7: Execute the restore + +Run the restore service to copy the backup files back to the primary database volume and fix file permissions. +{.power-number} + +1. Stop the primary database if the container is running: + + ```shell + docker compose stop psmysql + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Stopping 1/1 + ✔ Container psmysql Stopped + ``` + +2. Run the restore task: + + ```shell + docker compose run --rm pxb-restore + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + ==> Clearing current database directory... + ==> Restoring physical data files from backupvol... + xtrabackup version 8.4.0-2 based on MySQL server 8.4.2 Linux (x86_64) + ... + [Note] [MY-011825] [Xtrabackup] completed OK! + ==> Fixing file permissions for Percona Server... + ``` + + The restore service performs three operations: + + * Clears any residual files from the data directory + * Runs `xtrabackup --copy-back` to restore backup files + * Runs `chown -R mysql:mysql` to fix file ownership + +## Step 8: Verify the restoration + +Start the primary database and confirm that your data has been recovered. +{.power-number} + +1. Start the primary database: + + ```shell + docker compose start psmysql + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Running 1/1 + ✔ Container psmysql Started + ``` + +2. Check the logs to ensure it starts successfully: + + ```shell + docker compose logs psmysql + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + psmysql | [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4.2-2) starting as process 1 + psmysql | [System] [MY-013576] [InnoDB] InnoDB initialization has started. + psmysql | [System] [MY-013577] [InnoDB] InnoDB initialization has ended. + psmysql | [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060 + psmysql | [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.4.2-2' socket: '/var/lib/mysql/mysql.sock' port: 3306 Percona Server (GPL), Release 2, Revision b575402d. + ``` + + Look for `ready for connections` in the output to confirm the server started successfully. + +3. Connect and verify your data is restored: + + ```shell + docker exec -it psmysql mysql -uroot -p -e "SELECT * FROM mydb.employees;" + ``` + + Enter the password (`YourSecurePassword123`) when prompted. + + ??? example "Expected output" + + ```{.text .no-copy} + Enter password: + +----+--------------------+---------------------+---------+ + | id | name | email | country | + +----+--------------------+---------------------+---------+ + | 1 | Erasmus Richardson | erasmus@example.com | England | + | 2 | Jenna French | jenna@example.com | Canada | + | 3 | Alfred Dejesus | alfred@example.com | Austria | + +----+--------------------+---------------------+---------+ + ``` + +Your database has been fully restored from the backup. + +## Understanding file permissions + +One of the most common issues when restoring backups in Docker environments is file permission errors. The following table explains why the `chown` command is critical: + +| Stage | File Owner | Explanation | +|-------|------------|-------------| +| After backup | `mysql` | Backup preserves original ownership | +| After `--copy-back` | `root` | Files are copied by root user in the restore container | +| After `chown` | `mysql` | Ownership restored; MySQL can start | + +If you skip the `chown -R mysql:mysql /var/lib/mysql` step, MySQL fails to start with permission errors similar to: + +```{.text .no-copy} +[ERROR] [MY-010187] [Server] Could not open file '/var/lib/mysql/ibdata1' for reading: Permission denied +``` + +## Clean up + +To remove all containers, volumes, and resources created by this tutorial: +{.power-number} + +1. Remove Docker containers and volumes: + + ```shell + docker compose down -v + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [+] Running 5/5 + ✔ Container pxb_validate Removed + ✔ Container psmysql Removed + ✔ Volume pxb-tutorial_mysql_data Removed + ✔ Volume pxb-tutorial_backupvol Removed + ✔ Network pxb-tutorial_default Removed + ``` + +2. Remove the secrets directory: + + ```shell + rm -rf secrets/ + ``` + + If the command executes successfully, the expected output is empty. + +3. Optionally, remove the project directory: + + ```shell + cd .. && rm -rf pxb-tutorial/ + ``` + + If the command executes successfully, the expected output is empty. + +## Key takeaways + +* **Separation of concerns**: Using Docker Compose profiles separates backup, validation, and restore into distinct operations, making each step explicit and auditable. + +* **Validation before restore**: Always validate backups by booting a temporary database instance from the backup files before relying on them for disaster recovery. + +* **The permission gotcha**: Physical backups restored by the `root` user must have ownership changed to `mysql:mysql` before the database can start. This is a common source of restore failures. + +* **Prepared backups**: Backups must be prepared with `xtrabackup --prepare` before they can be restored or used for validation. + +## Next steps + +* Learn about [incremental backups](create-incremental-backup.md) to reduce backup time and storage +* Explore [streaming backups](take-streaming-backup.md) for direct-to-cloud storage +* Review [backup encryption](encrypt-backups.md) for securing backup data diff --git a/docs/docker.md b/docs/docker.md index 9c45ad5a4..ad1e71585 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -105,3 +105,7 @@ sudo docker run --name percona-xtrabackup --volumes-from percona-server-mysql \ percona/percona-xtrabackup xtrabackup --backup --data-dir=/var/lib/mysql --target-dir=/backup --user=root --password=mysql ``` + +## Next step + +For a complete workflow including backup validation and disaster recovery, see the [Docker Compose tutorial](docker-compose-tutorial.md). diff --git a/docs/quickstart-docker.md b/docs/quickstart-docker.md index adb7aecac..bb2431b60 100644 --- a/docs/quickstart-docker.md +++ b/docs/quickstart-docker.md @@ -1,17 +1,44 @@ -# Start a Docker container and take a backup +# Take a backup with Docker -In this scenario, Percona XtraBackup works in combination with a MySQL-compatible database instance. To use the tool, you must run Percona XtraBackup in a separate Docker container and then connect the Percona XtraBackup container directly to the Percona Server for MySQL container. This connection lets the backup tool access the database for backup and restore operations. +This tutorial describes how to create a backup volume, run Percona XtraBackup in a Docker container, and take a prepared backup of a Percona Server for MySQL database. -The following steps create a Docker volume, start Percona XtraBackup in a Docker container, take and prepare a backup of Percona Server for MySQL database. -{.power-number} +## Learning objectives -## Create a Docker volume +This tutorial covers the following tasks: -The benefits of using a Docker volume are the following: +* Create a Docker volume to store backup files -* You can keep your data safe and accessible across different containers. For example, if you want to upgrade your database image to a newer version, you can stop the old container and start a new one with the same volume attached without losing any data. +* Connect Percona XtraBackup to a running Percona Server container -* You can quickly backup and restore your data using the `docker cp` command or mount the volume to another container. +* Take a full backup using `xtrabackup --backup` + +* Prepare the backup using `xtrabackup --prepare` + +## Prerequisites + +Complete the following steps before starting this tutorial: + +* [Install Docker :octicons-link-external-16:](https://docs.docker.com/engine/install/) on your system + +* [Start Percona Server in a Docker container :octicons-link-external-16:](https://docs.percona.com/percona-server/{{vers}}/quickstart-docker.html) - Creates the `psmysql` container with the `mydb` database and `employees` table + +## Architecture overview + +Percona XtraBackup runs in a separate Docker container and connects to the Percona Server for MySQL container. This connection allows the backup tool to access the database files for backup and restore operations. + +For more information about how Percona XtraBackup works, see [How Percona XtraBackup works](how-xtrabackup-works.md). + +## Step 1: Create a backup volume + +Docker volumes provide persistent storage that remains accessible across container restarts and updates. Creating a dedicated backup volume offers the following benefits: + +* Data persists independently of container lifecycle + +* Multiple containers can access the same backup data + +* Backup files remain available for restore operations + +Create the backup volume with the following command: ```shell docker volume create backupvol @@ -20,62 +47,53 @@ docker volume create backupvol ??? example "Expected output" ```{.text .no-copy} - backupvol + backupvol ``` -## Start Percona XtraBackup 8.4 in a container, take and prepare a backup +## Step 2: Take and prepare the backup -The `docker run` command creates and runs a new container from an image. The command modifies the container's behavior with options. +The backup process requires connecting the Percona XtraBackup container to the Percona Server container. The `--user root` option grants the necessary permissions to access the MySQL data directory. -In our example, the command has the following options: +### Understand the command options -| Option | Description | -|---|---| -| `--name` | Provides a name to the container. If you do not use this option, Docker adds a random name. | -| `--volumes-from` | Refers to Percona Server for MySQL and indicates that you intend to use the same data as the `psmysql` container.| -| `-it` | Interacts with the container and be a pseudo-terminal. | -| `--user root` | Sets the user to root inside the Percona XtraBackup container. This option is required to access the MySQL data directory and run the xtrabackup command. | -|`backup_84` |Indicates the directory inside the container where the backup files are stored. | -| `-v` | Mounts a volume from the host machine to volumes in another container that is being run. In our example, the `-v` option mounts a volume from the `psmysql` container to the `backupvol` volume on the host machine.| -| `backupvol` | Indicates the persistent storage for the database. | -| `psmysql` | Indicates the Percona Server for MySQL container. | -|`--password` | Prompts the user to enter the password for the root user. For convenience you can add the password for the root user to this option, for example, `--password=secret`. Then the password will be passed automatically when running the command. Note that if you specify the password with `--password=secret`, the password is visible in `docker ps`, `docker ps -a` (docker history) and regular ps command. | -| `8.4` | Use this tag to specify a specific version. Avoid using the `latest` tag.
In our example, we use the `8.4` tag. In Docker, a tag is a label assigned to an image and is used to maintain different versions of an image.| +The following table describes each option used in the backup command: -If you do not add a tag, Docker uses `latest` as the default tag and downloads the newest image from [percona/percona-xtrabackup on the Docker Hub :octicons-link-external-16:](https://hub.docker.com/r/percona/percona-xtrabackup). This image can be in a different series or version from what you expect since the latest image changes over time. If you are using Percona XtraBackup version prior to 8.4, use tags to ensure that you use [compatible versions](server-backup-version-comparison.md) of Percona Server for MySQL and Percona XtraBackup. +| Option | Description | +|--------|-------------| +| `--name pxb` | Assigns the name `pxb` to the container | +| `--volumes-from psmysql` | Mounts volumes from the `psmysql` container to access database files | +| `-v backupvol:/backup_84` | Mounts the `backupvol` volume at `/backup_84` inside the container | +| `-it` | Allocates a pseudo-terminal for interactive password entry | +| `--user root` | Runs the container as root to access the MySQL data directory | +| `--password` | Prompts for the MySQL root password | -The CPU architecture or platform for Percona Server for MySQL and Percona XtraBackup should be the same. If you want to use a different platform, you can add the following command: +### Run the backup command -| Platform | Description | -|--------------------------|-------------------------------------------------------------| -| --platform linux/amd64 | To run an AMD64 platform on an ARM64 computer. | -| --platform linux/arm64 | To run an ARM64 platform on an AMD64 computer. | +Select the command for your system architecture: -You can run the Docker ARM64 version of Percona XtraBackup. Use the `8.4-aarch64` tag instead of `8.4`. +=== "AMD64 (Intel/AMD)" -### Connect the Percona XtraBackup container to the Percona Server container + ```shell + docker run --name pxb --volumes-from psmysql -v backupvol:/backup_84 -it --user root percona/percona-xtrabackup:8.4 /bin/bash -c "xtrabackup --backup --datadir=/var/lib/mysql/ --target-dir=/backup_84 --user=root --password; xtrabackup --prepare --target-dir=/backup_84" + ``` -We recommend using the `–-user root` option in the Docker command. -Run a Docker container example +=== "ARM64 (Apple Silicon Macs)" -```shell -docker run --name pxb --volumes-from psmysql -v backupvol:/backup_84 -it --user root percona/percona-xtrabackup:8.4 /bin/bash -c "xtrabackup --backup --datadir=/var/lib/mysql/ --target-dir=/backup_84 --user=root --password; xtrabackup --prepare --target-dir=/backup_84" -``` + ```shell + docker run --name pxb --volumes-from psmysql -v backupvol:/backup_84 -it --user root percona/percona-xtrabackup:8.4-aarch64 /bin/bash -c "xtrabackup --backup --datadir=/var/lib/mysql/ --target-dir=/backup_84 --user=root --password; xtrabackup --prepare --target-dir=/backup_84" + ``` -You are prompted to enter the password. In our example, the password is `secret`. +Enter the password `secret` when prompted: ```{.text .no-copy} 2024-10-07T13:55:47.640100-00:00 0 [Note] [MY-011825] [Xtrabackup] recognized server arguments: --datadir=/var/lib/mysql/ 2024-10-07T13:55:47.641887-00:00 0 [Note] [MY-011825] [Xtrabackup] recognized client arguments: --backup=1 --target-dir=/backup_84 --user=root --password Enter password: ``` - -In this example of expected output, we provide the first and last section of the backup log and use ellipses instead of the entire backup log. ??? example "Expected output" ```{.text .no-copy} - xtrabackup version 8.4.0-1 based on MySQL server 8.4.0 Linux (x86_64) (revision id: 3792f907) 2024-10-07T13:55:51.255518-00:00 0 [Note] [MY-011825] [Xtrabackup] perl binary not found. Skipping the version check 2024-10-07T13:55:51.256080-00:00 0 [Note] [MY-011825] [Xtrabackup] Connecting to MySQL server host: localhost, user: root, password: set, port: not set, socket: not set @@ -87,23 +105,49 @@ In this example of expected output, we provide the first and last section of the 2024-10-07T13:55:55.550829-00:00 0 [Note] [MY-011825] [Xtrabackup] completed OK! ``` -The command runs a Docker container `pxb` from the `percona/percona-xtrabackup:8.4` image and mounts two volumes: one from another container named `psmysql`, which contains Percona Server data directory, and another named `backupvol`, which is where the backup files are stored. The command also sets the user to root and prompts the user to enter the password. +The command executes two xtrabackup operations: -The command then executes two steps: - -* Runs `xtrabackup` with the `--backup` option to copy the data files from `/var/lib/mysql/` to `/backup_84` - -* Runs `xtrabackup` with the `--prepare` option to apply the log files and make the backup consistent and ready for restore +* `xtrabackup --backup` - Copies data files from `/var/lib/mysql/` to `/backup_84` + +* `xtrabackup --prepare` - Applies transaction logs to make the backup consistent + +For more information about the backup and prepare process, see [Create a full backup](create-full-backup.md) and [Prepare a full backup](prepare-full-backup.md). + +!!! warning "Password visibility" + + Specifying the password directly with `--password=secret` exposes the password in `docker ps`, `docker history`, and system process listings. Use the interactive prompt for production environments. -You can check the Xtrabackup logs with the `docker container logs ` command. +## Step 3: Verify the backup -For example: +Check the backup container logs to confirm the backup completed: ```shell docker container logs pxb ``` +??? example "Expected output" + + ```{.text .no-copy} + ... + 2024-10-07T13:55:55.550829-00:00 0 [Note] [MY-011825] [Xtrabackup] completed OK! + ``` + +The message `completed OK!` confirms the backup and prepare operations finished. + +## Summary + +This tutorial covered the following completed tasks: + +* Created the `backupvol` Docker volume for backup storage + +* Connected the Percona XtraBackup container to the `psmysql` database container + +* Executed `xtrabackup --backup` to copy database files + +* Executed `xtrabackup --prepare` to make the backup consistent + +The backup stored in `backupvol` is ready for restoration. + ## Next steps [Restore the backup](quickstart-restore-back.md){.md-button} - diff --git a/docs/quickstart-exit.md b/docs/quickstart-exit.md index 9d3d20edd..26fc0d72f 100644 --- a/docs/quickstart-exit.md +++ b/docs/quickstart-exit.md @@ -1,17 +1,25 @@ -# Clean up +# Clean up quickstart resources -In this document you'll learn how to: +This tutorial describes how to remove the Docker containers, images, and volumes created during the quickstart. -* Exit the MySQL command client shell and the Docker container +## Resources to remove -* Remove the Docker container and the Docker image +The following table lists all resources created during the quickstart tutorials: -* Remove the Docker volume. +| Resource | Type | Created in | +|----------|------|------------| +| `psmysql` | Container | [Percona Server quickstart :octicons-link-external-16:](https://docs.percona.com/percona-server/{{vers}}/quickstart-docker.html) | +| `ps-restore-target` | Container | [Restore the backup](quickstart-restore-back.md) | +| `pxb` | Container | [Take a backup with Docker](quickstart-docker.md) | +| `backupvol` | Volume | [Take a backup with Docker](quickstart-docker.md) | +| `restore_data` | Volume | [Restore the backup](quickstart-restore-back.md) | -The steps are as follows: +## Step 1: Exit the MySQL client + +If the MySQL client session remains open, exit the session before removing containers. {.power-number} -1. To exit the MySQL command client shell in `psmysql2` container, we use `exit`. You can also use the `\q` or `quit` commands. The execution of the statement also closes the connection. +1. Exit the MySQL command client: ```sql exit @@ -23,73 +31,93 @@ The steps are as follows: Bye ``` -2. Remove docker containers and images, if you no longer need docker containers / images or want to free up disk space. To remove a docker container, use the command `docker rm` followed by the container name or the container ID. To remove a docker image, use the command `docker rmi` followed by the image ID or name and the tag. The example uses the `-f` option to force the removal. + Alternative commands: `\q` or `quit` + +## Step 2: Remove Docker containers + +Remove the containers created during the quickstart. The `-f` option forces removal of running containers. +{.power-number} - * Remove `psmysql2`, `psmysql` and `pxb` Docker containers: +1. Remove the restore target container: + + ```shell + docker container rm ps-restore-target -f + ``` - ```shell - docker container rm psmysql2 -f + ??? example "Expected output" + + ```{.text .no-copy} + ps-restore-target ``` - ??? example "Expected output" +2. Remove the Percona Server container: + + ```shell + docker container rm psmysql -f + ``` - ```{.text .no-copy} - psmysql2 - ``` + ??? example "Expected output" - ```shell - docker container rm psmysql -f + ```{.text .no-copy} + psmysql ``` - ??? example "Expected output" +3. Remove the Percona XtraBackup container: + + ```shell + docker container rm pxb -f + ``` + + ??? example "Expected output" - ```{.text .no-copy} - psmysql - ``` - - ```shell - docker container rm pxb -f + ```{.text .no-copy} + pxb ``` - ??? example "Expected output" +## Step 3: Remove Docker images (optional) + +Remove the Docker images to free disk space. Skip this step to retain images for future use. +{.power-number} - ```{.text .no-copy} - pxb - ``` +1. Remove the Percona Server image: - * Remove `percona/percona-server:8.0.34` and `percona/percona-xtrabackup:8.0.34` Docker images + ```shell + docker image rmi percona/percona-server:8.4 + ``` - ```shell - docker image rmi percona/percona-server:8.0.34 + ??? example "Expected output" + + ```{.text .no-copy} + Untagged: percona/percona-server:8.4 + Untagged: percona/percona-server@sha256:... + Deleted: sha256:... ``` - ??? example "Expected output" +2. Remove the Percona XtraBackup image: - ```{.text .no-copy} - Untagged: percona/percona-server:8.0.34 - ``` + ```shell + docker image rmi percona/percona-xtrabackup:8.4 + ``` - ```shell - docker image rmi percona/percona-xtrabackup:8.0.34 + ??? example "Expected output" + + ```{.text .no-copy} + Untagged: percona/percona-xtrabackup:8.4 + Untagged: percona/percona-xtrabackup@sha256:... + Deleted: sha256:... ``` - ??? example "Expected output" +## Step 4: Remove Docker volumes - ```{.text .no-copy} - Untagged: percona/percona-server:8.0.34 - Untagged: percona/percona-server@sha256:4944f9b365e0dc88f41b3b704ff2a02d1459fd07763d7d1a444b263db8498e1f - Deleted: sha256:b2588da614b1f382468fc9f44600863e324067a9cae57c204a30a2105d61d9d9 - Deleted: sha256:1ceaa6dc89e328281b426854a3b00509b5df13826a9618a09e819a830b752ebd - Deleted: sha256:77471692427a227eb16d06907357956c3bb43f0fdc3ecf6f8937e1acecae24fe - Deleted: sha256:8db06cc7b0430437edc7f118b139d2195cb65e2e8025f9a4517d16778f615384 - Deleted: sha256:e5a57a2fafec4ab9482240f28927651d56545c19626e344aceb8be3704c3c397 - Deleted: sha256:f86198f39b893674d44d424c958f23183bf919d2ced20e1f519714d0972d75ed - Deleted: sha256:db9672f7e12e374d5e9016b758a29d5444e8b0fd1246a6f1fc5c2b3c847dddcf - ``` +Remove the volumes that stored database and backup data. -3. Remove docker volume if a container does not use the volume, and you no longer need it +!!! warning "Permanent data loss" - Remove `backupvol` and `myvol2` Docker volumes: + Removing volumes permanently deletes all stored data. Verify the data is no longer needed before proceeding. + +{.power-number} + +1. Remove the backup volume: ```shell docker volume rm backupvol @@ -101,16 +129,49 @@ The steps are as follows: backupvol ``` +2. Remove the restore target volume: + ```shell - docker volume rm myvol2 + docker volume rm restore_data ``` ??? example "Expected output" ```{.text .no-copy} - myvol2 + restore_data ``` +## Verify resource removal + +Confirm all quickstart resources have been removed with the following commands: + +```shell +docker ps -a --filter "name=psmysql" --filter "name=ps-restore-target" --filter "name=pxb" +docker volume ls --filter "name=backupvol" --filter "name=restore_data" +``` + +??? example "Expected output" + + ```{.text .no-copy} + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + + DRIVER VOLUME NAME + ``` + +Empty results confirm resource removal completed. + +## Summary + +This tutorial covered the removal of the following quickstart resources: + +* Three Docker containers: `psmysql`, `ps-restore-target`, `pxb` + +* Two Docker images: `percona/percona-server:8.4`, `percona/percona-xtrabackup:8.4` + +* Two Docker volumes: `backupvol`, `restore_data` + +For information about running Percona XtraBackup in production environments, see [Installation](installation.md). + ## Next step -[Next steps](quickstart-next-steps.md){.md-button} \ No newline at end of file +[Explore next steps](quickstart-next-steps.md){.md-button} diff --git a/docs/quickstart-next-steps.md b/docs/quickstart-next-steps.md index bac378a3c..6a4d55cc7 100644 --- a/docs/quickstart-next-steps.md +++ b/docs/quickstart-next-steps.md @@ -1,32 +1,43 @@ # Next steps -After you take your first backup with Percona Xtrabackup, it's high time to expand your knowledge and skills in using Percona Xtrabackup. +This page provides recommendations for continuing your Percona XtraBackup learning after completing the quickstart. -Review the [Percona Xtrabackup documentation :octicons-link-external-16:](https://docs.percona.com/percona-xtrabackup/{{vers}}/) for more information. +## Continue learning Percona XtraBackup -## Learn more about other Percona products +The following resources expand on the concepts covered in the quickstart: -### For superior and optimized performance +| Topic | Description | +|-------|-------------| +| [Create incremental backups](create-incremental-backup.md) | Back up only changed data to reduce backup time and storage | +| [Create compressed backups](create-compressed-backup.md) | Reduce backup size with compression | +| [Encrypt backups](encrypt-backups.md) | Protect backup data with encryption | +| [Stream backups to cloud storage](xbcloud-binary-overview.md) | Send backups directly to S3, GCS, or Azure | -Percona Server for MySQL (PS) is a freely available, fully compatible, enhanced, and open source drop-in replacement for any MySQL database. It provides superior and optimized performance, greater scalability and availability, enhanced backups, increased visibility, and instrumentation. Percona Server for MySQL is trusted by thousands of enterprises to provide better performance and concurrency for their most demanding workloads. +## Docker Compose tutorial -Install [Percona Server for MySQL :octicons-link-external-16:](https://docs.percona.com/percona-server/{{vers}}/installation.html). +For a production-ready approach to backup validation and disaster recovery, follow the [Docker Compose backup and restore tutorial](docker-compose-tutorial.md). This tutorial covers the following topics: -### For high availability +* Configure Docker Compose with backup profiles -Percona XtraDB Cluster (PXC) is a 100% open source, enterprise-grade, highly available clustering solution for MySQL multi-master setups based on Galera. PXC helps enterprises minimize unexpected downtime and data loss, reduce costs, and improve performance and scalability of your database environments supporting your critical business applications in the most demanding public, private, and hybrid cloud environments. +* Validate backups before relying on them for recovery -Install [Percona XtraDB Cluster :octicons-link-external-16:](https://docs.percona.com/percona-xtradb-cluster/{{vers}}/install-index.html). +* Simulate and recover from a disaster scenario -### For Monitoring and Management +* Understand file permission requirements for containerized restores -Percona Monitoring and Management (PMM) monitors and provides actionable performance data for MySQL variants, including Percona Server for MySQL, Percona XtraDB Cluster, Oracle MySQL Community Edition, Oracle MySQL Enterprise Edition, and MariaDB. PMM captures metrics and data for the InnoDB, XtraDB, and MyRocks storage engines, and has specialized dashboards for specific engine details. +## Production installation -[Install PMM and connect your MySQL instances to it :octicons-link-external-16:](https://docs.percona.com/percona-monitoring-and-management/3/quickstart/quickstart.html#connect-database). +The quickstart uses Docker for demonstration purposes. For production environments, install Percona XtraBackup directly on the database server. -### Advanced command-line tools +See [Installation](installation.md) for package-based installation options. -Percona Toolkit is a collection of advanced command-line tools used by the Percona support staff to perform a variety of MySQL, MongoDB, and system tasks that are complex or difficult to perform manually. These tools are ideal alternatives to “one-off” scripts because they are professionally developed, formally tested, and documented. Each tool is self-contained, so installation is quick and easy and does not require installing libraries. +## Related Percona products -[Percona Toolkit documentation :octicons-link-external-16:](https://docs.percona.com/percona-toolkit/) +The following Percona products work with Percona XtraBackup: +| Product | Purpose | Documentation | +|---------|---------|---------------| +| Percona Server for MySQL | MySQL-compatible database with performance enhancements | [Installation :octicons-link-external-16:](https://docs.percona.com/percona-server/{{vers}}/installation.html) | +| Percona XtraDB Cluster | High-availability MySQL clustering with Galera | [Installation :octicons-link-external-16:](https://docs.percona.com/percona-xtradb-cluster/{{vers}}/install-index.html) | +| Percona Monitoring and Management | Database monitoring and performance analysis | [Quickstart :octicons-link-external-16:](https://docs.percona.com/percona-monitoring-and-management/3/quickstart/quickstart.html) | +| Percona Toolkit | Command-line tools for MySQL administration | [Documentation :octicons-link-external-16:](https://docs.percona.com/percona-toolkit/) | diff --git a/docs/quickstart-overview.md b/docs/quickstart-overview.md index be8701eaa..975ceb776 100644 --- a/docs/quickstart-overview.md +++ b/docs/quickstart-overview.md @@ -1,65 +1,101 @@ -# Quickstart Overview +# Quickstart overview -Percona XtraBackup is a 100% open source backup solution for all versions of Percona Server for MySQL and MySQL® that performs online non-blocking, tightly compressed, highly secure full backups on transactional systems. +Percona XtraBackup performs online, non-blocking physical backups for Percona Server for MySQL and MySQL databases. This quickstart guide uses Docker to demonstrate backup and restore operations. -To quickly start with Percona XtraBackup, we recommend using Docker. This Quickstart guide focuses on this installation method. You can explore alternative installation options in the [Install](installation.md) section. +For alternative installation methods, see [Installation](installation.md). -### Docker containers +## Why use Docker for this quickstart -Docker containers are built from Docker images, which are configuration snapshots needed to run applications. With Docker, you can build, deploy, run, update, and manage containers, which isolate applications from the host system. A Docker container lets you work with Percona XtraBackup without installing the product on a local drive. +Docker containers isolate applications from the host system. Running Percona XtraBackup in a container provides the following benefits: -Using Docker has benefits: +* No installation required on the host system -* Easily set up and use -* Doesn't change anything on your computer -* Simply remove it when you're done +* Consistent environment across different operating systems -## Quickstart Purpose +* Complete removal leaves no residual files -This section provides you with the basic steps to start Percona XtraBackup in a Docker container, take a backup, prepare a backup and restore a backup of Percona Server for MySQL database. +For production deployments, see [Installation](installation.md) for package-based installation options. -We use specific names in our examples, but feel free to change them if you want. Just remember that if you do, your results might be different from our guide. +## Supported configurations -When we talk about a "container," we mean the Docker container where Percona XtraBackup is running. When we say "instance," we're talking about the MySQL database server inside that container. +Verify your environment meets the following requirements before starting. -This guide will help you get started quickly, but there's a lot more to learn about database backups as you go along. +### Supported servers + +Percona XtraBackup {{vers}} supports the following MySQL-compatible servers: + +* MySQL Server + +* Percona Server for MySQL + +* Percona XtraDB Cluster + +### Supported storage engines + +Percona XtraBackup {{vers}} supports the following storage engines: + +* InnoDB + +* MyISAM + +* MyRocks + +* XtraDB + +### Version requirements + +Percona XtraBackup {{vers}} requires databases created with the {{vers}} series or later. Databases created with earlier MySQL, Percona Server for MySQL, or Percona XtraDB Cluster versions are not supported. + +For detailed version compatibility information, see [Server and backup version comparison](server-backup-version-comparison.md). ## Prerequisites -* [Install Docker :octicons-link-external-16:](https://docs.docker.com/engine/install/) on your system. +Both learning paths require [Docker :octicons-link-external-16:](https://docs.docker.com/engine/install/) installed on your system. Each tutorial includes specific setup instructions for Percona Server for MySQL. -To take a backup of Percona Server for MySQL, run Percona Server for MySQL in a Docker container and create a database, and a table. +## Choose your learning path -* [Start Percona Server in a Docker container :octicons-link-external-16:](https://docs.percona.com/percona-server/{{vers}}/quickstart-docker.html) -* [Create a database and table in Percona Server :octicons-link-external-16:](https://docs.percona.com/percona-server/{{vers}}/quickstart-docker.html#create-a-database) +This quickstart offers two paths based on your experience level and goals: -### Limitations +| Path | Best for | Time | Topics covered | +|------|----------|------|----------------| +| [Basic quickstart](quickstart-docker.md) | First-time users learning core concepts | 15-20 min | Single backup, restore, validation | +| [Docker Compose tutorial](docker-compose-tutorial.md) | Production-oriented users | 30-40 min | Backup profiles, validation testing, disaster recovery | -Percona XtraBackup {{vers}} does not support making backups of databases created in versions before the {{vers}} series of MySQL, Percona Server for MySQL, or Percona XtraDB Cluster. +### Basic quickstart -### Support servers and storage engines +The [basic quickstart](quickstart-docker.md) teaches core Percona XtraBackup operations using individual Docker commands: -Percona XtraBackup {{vers}} supports backing up data from various MySQL-compatible servers and storage engines. +* Create a backup volume -Supported Servers: +* Take and prepare a full backup -* MySQL Server -* Percona Server for MySQL -* Percona XtraDB Cluster +* Restore a backup to a new container -Supported Storage Engines: +* Validate restored data -* InnoDB -* XtraDB -* MyISAM -* MyRocks +### Docker Compose tutorial + +The [Docker Compose tutorial](docker-compose-tutorial.md) demonstrates a production-ready backup workflow with separate services for backup, validation, and restore: + +* Configure Docker Compose with backup profiles + +* Validate backups before relying on them for recovery + +* Simulate a disaster scenario + +* Execute a complete restore operation + +* Understand file permission requirements + +## Terminology -## Steps to perform +This quickstart uses the following terms: -In this Quickstart, you will learn how to: -{.power-number} +| Term | Definition | +|------|------------| +| Container | The Docker container running Percona XtraBackup or Percona Server | +| Instance | The MySQL database server process running inside a container | +| Volume | Docker persistent storage that survives container restarts | +| Prepared backup | A backup with transaction logs applied, ready for restoration | -1. [Start a Docker container and take a backup](quickstart-docker.md) -2. [Restore a backup](quickstart-restore-back.md) -3. [Clean up](quickstart-exit.md) -4. [Choose your next steps](quickstart-next-steps.md) +For additional terminology, see [Glossary](glossary.md). diff --git a/docs/quickstart-restore-back.md b/docs/quickstart-restore-back.md index 1c7f59079..d3469f655 100644 --- a/docs/quickstart-restore-back.md +++ b/docs/quickstart-restore-back.md @@ -1,76 +1,212 @@ # Restore the backup -The following steps describe how to restore your backup to another Percona Server container and check whether the data is available. +This tutorial describes how to restore a Percona XtraBackup backup to a new database container. The tutorial also covers validating the restored data. + +## Learning objectives + +This tutorial covers the following tasks: + +* Create a restore target container + +* Use `xtrabackup --copy-back` to restore physical backup files + +* Fix file permissions required for MySQL to start + +* Validate restored data accessibility + +## Prerequisites + +Complete the following quickstart steps before starting this tutorial: + +* [Start Percona Server in a Docker container :octicons-link-external-16:](https://docs.percona.com/percona-server/{{vers}}/quickstart-docker.html) - Creates the `psmysql` container with the `mydb` database + +* [Take a backup](quickstart-docker.md) - Creates the `backupvol` volume containing your prepared backup + +### Understanding host terminal vs container + +This tutorial requires running commands in two different places: + +| Location | Description | Prompt example | +|----------|-------------|----------------| +| Host terminal | Your computer's command line where you run `docker` commands | `$` or `%` | +| MySQL client | Inside a container, connected to the database | `mysql>` | + +Commands starting with `docker` always run on your host terminal. SQL commands like `SELECT` run inside the MySQL client. + +### Verify the backup volume + +Before proceeding, verify the backup volume exists. + +If you are still in the MySQL client from the previous tutorial, exit to return to your host terminal: + +```sql +exit +``` + +??? example "Expected output" + + ```{.text .no-copy} + Bye + ``` + +Run the following command on your host terminal to verify the backup volume: + +```shell +docker volume ls +``` + +??? example "Expected output" + + ```{.text .no-copy} + DRIVER VOLUME NAME + local backupvol + ``` + +Confirm `backupvol` appears in the list. If the volume does not exist, complete the [Take a backup](quickstart-docker.md) tutorial first. + +## Restore process overview + +Restoring a physical backup requires copying the backup files to a MySQL data directory. In Docker environments, the restore process requires the following steps: + +1. Create a target container - A Percona Server container receives the restored data + +2. Stop the target database - MySQL cannot run while the restore process overwrites data files + +3. Clear the data directory - The target directory must be empty before restoration + +4. Copy the backup files - The `xtrabackup --copy-back` command transfers the files + +5. Fix file permissions - Restored files have `root` ownership, but MySQL runs as the `mysql` user + +For more information about the restore process, see [Restore full, incremental, and compressed backups](restore-a-backup.md). + +## Step 1: Create a restore target container + +Create a second Percona Server container named `ps-restore-target` as the restore destination. This configuration simulates restoring to a different server, a common disaster recovery scenario. {.power-number} -1. Create another Docker volume +1. Create a Docker volume for the restore target: ```shell - docker volume create myvol2 + docker volume create restore_data ``` ??? example "Expected output" ```{.text .no-copy} - myvol2 + restore_data ``` -2. Run another Percona Server container to restore the backup to + This volume stores the restored database files. - | Option | Description | - |---|---| - | `--name` | Provides a name to the container. If you do not use this option, Docker adds a random name. | - | `-d` | Detaches the container. The container runs in the background. | - | `-e` | Adds an environmental variable. This example adds the ` MYSQL_ROOT_PASSWORD ` environment variable. The instance refuses to initialize if no environmental variable is added. Choose a more secure password, if needed. | - | `myvol2` | Indicates the persistent storage for the database. | - | `8.4` | Use this tag to specify a specific version. | +2. Start a Percona Server container: - You must provide at least one environment variable to access the database, such as `MYSQL_ROOT_PASSWORD`, `MYSQL_DATABASE`, `MYSQL_USER`, and `MYSQL_PASSWORD` or the instance refuses to initialize. + === "AMD64 (Intel/AMD)" - For this document, we are using the `8.4` tag. In Docker, a tag is a label assigned to an image. Tags are used to maintain different versions of an image. If we did not add a tag, Docker uses `latest` as the default tag and downloads the latest image from [percona/percona-server on the Docker Hub]. - - To use a Docker volume for persistent storage with a database, specify the path where the database stores its data inside the container, usually `/var/lib/mysql`. + ```shell + docker run -d -p 3307:3306 --name ps-restore-target -e MYSQL_ROOT_PASSWORD=secret -v restore_data:/var/lib/mysql percona/percona-server:8.4 + ``` - * Run a Docker container example + === "ARM64 (Apple Silicon Macs)" ```shell - docker run -d -p 3307:3306 --name psmysql2 -e MYSQL_ROOT_PASSWORD=secret -v myvol2:/var/lib/mysql percona/percona-server:8.4 + docker run -d -p 3307:3306 --name ps-restore-target -e MYSQL_ROOT_PASSWORD=secret -v restore_data:/var/lib/mysql percona/percona-server:8.4-aarch64 ``` ??? example "Expected output" ```{.text .no-copy} - 4501d5524461b4483d414bd218d49ed4f47599add7d7fb81e157951a7a52f3d1 ``` - -3. Stop `psmysql2` container + + The following table describes each option: + + | Option | Purpose | + |--------|---------| + | `-d` | Runs the container in background mode | + | `-p 3307:3306` | Maps to port 3307 to avoid conflicts with the original database on port 3306 | + | `--name ps-restore-target` | Assigns a descriptive container name | + | `-e MYSQL_ROOT_PASSWORD=secret` | Sets the root password, which MySQL requires for initialization | + | `-v restore_data:/var/lib/mysql` | Mounts the volume for data storage | + +3. Wait 30 seconds for container initialization, then verify the container status: ```shell - docker stop psmysql2 + docker ps --filter name=ps-restore-target ``` ??? example "Expected output" ```{.text .no-copy} - psmysql2 + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 4501d552446 percona/percona-server:8.4 "/docker-entrypoint.…" 30 seconds ago Up 29 seconds 33060/tcp, 0.0.0.0:3307->3306/tcp ps-restore-target ``` -4. Remove all created files in `myvol2` to allow xtrabackup restore data to `myvol2` +## Step 2: Prepare the target for restore + +Stop the database and clear the data directory before restoring. The `xtrabackup --copy-back` command requires an empty target directory. +{.power-number} - The `--rm` option automatically removes the temporary container created from percona/percona-xtrabackup:8.0.34 image after the container exits. +1. Stop the restore target container: ```shell - docker run --volumes-from psmysql2 -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4 /bin/bash -c "rm -rf /var/lib/mysql/*" + docker stop ps-restore-target ``` - If the command executes successfully, the expected output is empty. + ??? example "Expected output" + + ```{.text .no-copy} + ps-restore-target + ``` + + !!! warning "Database must be stopped" + + MySQL locks data files while running. Overwriting locked files causes corruption or errors. -5. Restore backup of `psmysql` from `backupvol` to a new `psmysql2` instance. +2. Clear the data directory: - ```shell - docker run --platform linux/amd64 --volumes-from psmysql2 -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4 /bin/bash -c "xtrabackup --copy-back --datadir=/var/lib/mysql/ --target-dir=/backup_84" - ``` + The `--rm` option creates a temporary container. Docker removes this container automatically after the command completes. + + === "AMD64 (Intel/AMD)" + + ```shell + docker run --volumes-from ps-restore-target -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4 /bin/bash -c "rm -rf /var/lib/mysql/*" + ``` + + === "ARM64 (Apple Silicon Macs)" + + ```shell + docker run --volumes-from ps-restore-target -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4-aarch64 /bin/bash -c "rm -rf /var/lib/mysql/*" + ``` + + If the command succeeds, the output is empty. + + This command performs the following actions: + + * Mounts the `restore_data` volume through `--volumes-from ps-restore-target` + + * Runs as `root` to obtain file deletion permissions + + * Removes all files from `/var/lib/mysql/` + +## Step 3: Restore the backup files + +Copy the backup files from `backupvol` to the restore target data directory. +{.power-number} + +1. Run the restore command: + + === "AMD64 (Intel/AMD)" + + ```shell + docker run --volumes-from ps-restore-target -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4 /bin/bash -c "xtrabackup --copy-back --datadir=/var/lib/mysql/ --target-dir=/backup_84" + ``` + + === "ARM64 (Apple Silicon Macs)" + + ```shell + docker run --volumes-from ps-restore-target -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4-aarch64 /bin/bash -c "xtrabackup --copy-back --datadir=/var/lib/mysql/ --target-dir=/backup_84" + ``` ??? example "Expected output" @@ -82,164 +218,187 @@ The following steps describe how to restore your backup to another Percona Serve ... - 2024-10-07T14:08:59.129407-00:00 0 1 [Note] [MY-011825] [Xtrabackup] Done: Copying ./ibtmp1 to /var/lib/mysql/ibtmp1 - - 2024-10-07T14:08:59.129407-00:00 0 [Note] [MY-011825] [Xtrabackup] completed OK! + 2024-10-07T14:08:59.129407-00:00 0 [Note] [MY-011825] [Xtrabackup] Done: Copying ./ibtmp1 to /var/lib/mysql/ibtmp1 + 2024-10-07T14:08:59.129407-00:00 0 [Note] [MY-011825] [Xtrabackup] completed OK! ``` - This command restores the backup files from the `backup_8034` volume to the `psmysql2` container. It uses the `percona/percona-xtrabackup:8.0.34` image to run a temporary container with root privileges. It executes the xtrabackup tool with the `--copy-back` option, which copies the files from the `backup_8034` volume to the /`var/lib/mysql/` directory in the `psmysql2` container. The command uses --rm option to delete the temporary container after it exits. - -## Validate the backup + The following table describes each xtrabackup option: -This section describes the backup validation steps assuming that you backed up `mydb` database with the `employees` table as we have in our example. The validation steps may vary depending on your data set. -{.power-number} - -1. Change the owner of the files in `myvol2` from `root` to `mysql` + | Option | Purpose | + |--------|---------| + | `--copy-back` | Copies backup files to the data directory; use `--move-back` to move files instead | + | `--datadir` | Specifies the destination directory for restored files | + | `--target-dir` | Specifies the source directory containing the prepared backup | - To avoid permission issues when running `psmysql2` container, you need to change the owner because the files were restored by `root` user and `psmysql2` will use `mysql` user. + For a complete list of options, see [xtrabackup option reference](xtrabackup-option-reference.md). - ```shell - docker run --volumes-from psmysql2 -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4 /bin/bash -c "chown -R mysql:mysql /var/lib/mysql/" - ``` +## Step 4: Fix file permissions - If the command executes successfully, the expected output is empty. - -2. Start the `psmysql2` container +The restored files have `root` ownership because the restore command ran as root. MySQL runs as the `mysql` user and cannot read files owned by root. +{.power-number} - ```shell - docker start psmysql2 - ``` +1. Change ownership of the restored files: - ??? example "Expected output" + === "AMD64 (Intel/AMD)" - ```{.text .no-copy} - psmysql2 + ```shell + docker run --volumes-from ps-restore-target -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4 /bin/bash -c "chown -R mysql:mysql /var/lib/mysql/" ``` -3. Connect to the database instance. - - For this example, we have the following options: - - | Option | Description | - | ---------- | ---------------------------------------------------------------------------------- | - | `it` | Interact with the container and be a pseudo-terminal | - | `psmysql2` | Running container name | - | `mysql` | Connects to a database instance | - | `-u` | Specifies the user account used to connect | - | `-p` | Use this password when connecting | + === "ARM64 (Apple Silicon Macs)" - * Connect to the database instance example - ```shell - docker exec -it psmysql2 mysql -uroot -p + docker run --volumes-from ps-restore-target -v backupvol:/backup_84 -it --rm --user root percona/percona-xtrabackup:8.4-aarch64 /bin/bash -c "chown -R mysql:mysql /var/lib/mysql/" ``` - You are prompted to enter the password, which is `secret`. + If the command succeeds, the output is empty. - ```{.text .no-copy} - Enter password: + !!! warning "Required step" + + Skipping the `chown` command causes MySQL to fail with permission errors: + + ```text + [ERROR] [MY-010187] [Server] Could not open file '/var/lib/mysql/ibdata1' for reading: Permission denied ``` - You should see the following result. + For more information about file permissions, see [Permissions](permissions.md). - ??? example "Expected output" +2. Start the restore target container: - ```{.text .no-copy} - Welcome to the MySQL monitor. Commands end with ; or \g. - Your MySQL connection id is 10 - Server version: 8.4.0-1 Percona Server (GPL), Release 1, Revision 238b3c02 - - Copyright (c) 2009-2024 Percona LLC and/or its affiliates - Copyright (c) 2000, 2024, Oracle and/or its affiliates. + ```shell + docker start ps-restore-target + ``` - Oracle is a registered trademark of Oracle Corporation and/or its - affiliates. Other names may be trademarks of their respective - owners. + ??? example "Expected output" - Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. - ``` + ```{.text .no-copy} + ps-restore-target + ``` -4. Check the list of databases to make sure, the backed up, `mydb` database is in the list. +3. Check the container logs to verify MySQL started: - ```sql - show databases; + ```shell + docker logs ps-restore-target 2>&1 | tail -5 ``` ??? example "Expected output" - + ```{.text .no-copy} - +--------------------+ + 2024-10-07T14:10:15.123456Z 0 [System] [MY-013576] [InnoDB] InnoDB initialization has started. + 2024-10-07T14:10:15.234567Z 0 [System] [MY-013577] [InnoDB] InnoDB initialization has ended. + 2024-10-07T14:10:15.345678Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. + 2024-10-07T14:10:15.345678Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.4.0-1' socket: '/var/lib/mysql/mysql.sock' port: 3306 Percona Server (GPL), Release 1, Revision 238b3c02. + ``` + + The message `ready for connections` confirms the server started. - | Database | +## Step 5: Validate the restored data - +--------------------+ +Connect to the restored database and verify data integrity. +{.power-number} - | information_schema | +1. Connect to the restored database: + + ```shell + docker exec -it ps-restore-target mysql -uroot -p + ``` - | mydb | + ??? example "Expected output" - | mysql | + ```{.text .no-copy} + Enter password: + Welcome to the MySQL monitor. Commands end with ; or \g. + Your MySQL connection id is 10 + Server version: 8.4.0-1 Percona Server (GPL), Release 1, Revision 238b3c02 - | performance_schema | + Copyright (c) 2009-2024 Percona LLC and/or its affiliates + Copyright (c) 2000, 2024, Oracle and/or its affiliates. - | sys | + Oracle is a registered trademark of Oracle Corporation and/or its + affiliates. Other names may be trademarks of their respective + owners. - +--------------------+ + Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. - 5 rows in set (0.03 sec) + mysql> ``` -5. Use the `mydb` database. + Enter the password `secret` when prompted. + +2. Verify the `mydb` database exists: ```sql - use mydb; + SHOW DATABASES; ``` ??? example "Expected output" ```{.text .no-copy} - Database changed + +--------------------+ + | Database | + +--------------------+ + | information_schema | + | mydb | + | mysql | + | performance_schema | + | sys | + +--------------------+ + 5 rows in set (0.03 sec) ``` -6. Check that your table contains data +3. Query the `employees` table data: - ```sql - SELECT * FROM employees; + ```sql + SELECT * FROM mydb.employees; ``` ??? example "Expected output" ```{.text .no-copy} - +----+--------------------+-----------------------------------+-------------+ - - | id | name | email | country | - - +----+--------------------+-----------------------------------+-------------+ + +----+--------------------+-----------------------------------+-------------+ + | id | name | email | country | + +----+--------------------+-----------------------------------+-------------+ + | 1 | Erasmus Richardson | posuere.cubilia.curae@outlook.net | England | + | 2 | Jenna French | rhoncus.donec@hotmail.couk | Canada | + | 3 | Alfred Dejesus | interdum@aol.org | Austria | + | 4 | Hamilton Puckett | dapibus.quam@outlook.com | Canada | + | 5 | Michal Brzezinski | magna@icloud.pl | Poland | + | 6 | Zofia Lis | zofial00@hotmail.pl | Poland | + | 7 | Aisha Yakubu | ayakubu80@outlook.com | Nigeria | + | 8 | Miguel Cardenas | euismod@yahoo.com | Peru | + | 9 | Luke Jansen | nibh@hotmail.edu | Netherlands | + | 10 | Roger Pettersen | nunc@protonmail.no | Norway | + +----+--------------------+-----------------------------------+-------------+ + 10 rows in set (0.00 sec) + ``` - | 1 | Erasmus Richardson | posuere.cubilia.curae@outlook.net | England | + The data restoration completed. - | 2 | Jenna French | rhoncus.donec@hotmail.couk | Canada | +4. Exit the MySQL client: - | 3 | Alfred Dejesus | interdum@aol.org | Austria | + ```sql + exit + ``` - | 4 | Hamilton Puckett | dapibus.quam@outlook.com | Canada | + ??? example "Expected output" - | 5 | Michal Brzezinski | magna@icloud.pl | Poland | + ```{.text .no-copy} + Bye + ``` - | 6 | Zofia Lis | zofial00@hotmail.pl | Poland | +## Summary - | 7 | Aisha Yakubu | ayakubu80@outlook.com | Nigeria | +This tutorial covered the following completed tasks: - | 8 | Miguel Cardenas | euismod@yahoo.com | Peru | +* Created a restore target container named `ps-restore-target` - | 9 | Luke Jansen | nibh@hotmail.edu | Netherlands | +* Prepared the target by stopping MySQL and clearing the data directory - | 10 | Roger Pettersen | nunc@protonmail.no | Norway | +* Restored backup files using `xtrabackup --copy-back` - +----+--------------------+-----------------------------------+-------------+ +* Fixed file permissions with `chown -R mysql:mysql` - 10 rows in set (0.00 sec) - ``` +* Validated data recovery ## Next steps diff --git a/mkdocs-base.yml b/mkdocs-base.yml index 22338f531..aa02102b5 100644 --- a/mkdocs-base.yml +++ b/mkdocs-base.yml @@ -267,6 +267,7 @@ nav: - compile-xtrabackup.md - Docker: - docker.md + - docker-compose-tutorial.md # - Upgrade: # - upgrade.md