Linux backups

Keep a tested way back.

PXM can make daily backups of its managed databases and store encrypted portable copies in an S3-compatible bucket, including Cloudflare R2. Each portable copy includes the signed database engine, data and connection credentials needed to recover on the same CPU architecture.

These are consistent cold physical snapshots. PXM stops one selected database cleanly, copies its files, and restores its previous running state before encryption and upload. Schedule the job during a maintenance window. The interruption depends on database size and shutdown time. Selected databases are copied sequentially; a multi-service plan is not a single atomic snapshot across databases.

Configure storage and encryption

Create a private S3 credential file outside PXM_HOME:

json
{
  "accessKeyId": "YOUR_S3_ACCESS_KEY_ID",
  "secretAccessKey": "YOUR_S3_SECRET_ACCESS_KEY"
}

Use chmod 600 on the file and keep its parent directory private. Temporary AWS credentials may also include sessionToken. PXM does not print these values or accept them as command-line arguments. Expiring credentials must be replaced before their expiration.

The bucket must already exist. Restrict the credential to the intended bucket and prefix, with permission to list, read, write, delete and manage multipart uploads. Use the R2 S3 API endpoint https://ACCOUNT_ID.r2.cloudflarestorage.com and region auto, or the HTTPS origin and region supplied by your storage provider. Plain HTTP, embedded URL credentials and redirects are rejected.

Create a separate encryption key:

Terminal
pxm backup key /home/pxm/private/backup-recovery.key

Keep a secure copy of this key off the server. It is required to decrypt the backups. Changing the key affects future copies; retain previous keys for older copies. Neither the object-store credential nor the PXM license replaces the recovery key.

Terminal
pxm backup set nightly \
  --services mysql,postgresql,redis \
  --at 03:00 \
  --keep 7 \
  --local-keep 2 \
  --endpoint https://ACCOUNT_ID.r2.cloudflarestorage.com \
  --region auto \
  --bucket server-backups \
  --prefix production/primary \
  --credentials-file /home/pxm/private/s3.json \
  --key-file /home/pxm/private/backup-recovery.key

Replace service names with your registered PXM services. The schedule uses UTC, runs inside the PXM daemon, and requires the daemon to be running. Enable PXM startup separately for unattended server operation. A missed run is attempted when the daemon next runs after that day's scheduled time. Failed attempts retry with a delay starting at 15 minutes, capped at six hours. An individual scheduled attempt has a 24-hour cancellation budget; PXM still waits for any owned database shutdown/recovery to complete safely.

Run and inspect

Terminal
pxm backup run nightly
pxm backup status nightly --json
pxm backup list
pxm backup remote-list nightly
pxm backup disable nightly

A failed manual run exits unsuccessfully. Status shows the last attempt, last success, error, retry time and recent verified objects. Scheduled failures also appear in the daemon log. Disabling a schedule retains existing backups. One plan cannot overlap itself; service snapshot operations are serialized with other PXM database management operations.

Retention and integrity

PXM encrypts the complete portable archive with a fresh per-bundle key derived from your 256-bit recovery key. AES-256-GCM authenticates each ordered frame and a mandatory final frame. Wrong keys, modified frames, reordered data, truncated objects and appended data are rejected.

Uploads use signed S3 requests and multipart upload for large objects. PXM downloads the entire committed ciphertext and compares its size and SHA-256 hash before considering it verified. This readback consumes storage-provider bandwidth.

Retention starts only after every selected service has a verified new offsite copy. --keep controls verified remote copies per service. --local-keep controls snapshots created by this automation. Local snapshots referenced by a rollback or active recovery transaction are retained even beyond that count. Manual backups, unknown files, another plan's namespace, and copies belonging to an old destination or encryption key are not automatically deleted.

Failed attempts preserve prior backups. A crash or uncertain network response can leave an unrecorded remote object or a local snapshot. Inspect failures before manually cleaning these up. A bucket lifecycle rule for abandoned multipart uploads can bound incomplete upload storage. PXM does not silently delete unverified objects to satisfy a retention count.

Encrypted objects and recovery archives are limited to 5 TiB and one million archive entries. Recovery requires space for both the downloaded ciphertext and extracted portable copy, plus at least a 64 MiB reserve. Creating a backup also needs space for the local snapshot, portable engine/data copy and encrypted upload. Budget disk capacity for these copies, not just retained history.

Recover a database

For a saved plan:

Terminal
pxm backup remote-list nightly --all-namespaces
pxm backup download nightly \
  production/primary/pxm/NAMESPACE/SERVICE/OBJECT.pxmbak \
  /home/pxm/recovery/portable

On a fresh server with no saved plan, use the separately retained key and object-store credential:

Terminal
pxm backup recover \
  production/primary/pxm/NAMESPACE/SERVICE/OBJECT.pxmbak \
  /home/pxm/recovery/portable \
  --endpoint https://ACCOUNT_ID.r2.cloudflarestorage.com \
  --region auto \
  --bucket server-backups \
  --prefix production/primary \
  --credentials-file /home/pxm/private/s3.json \
  --key-file /home/pxm/private/backup-recovery.key

pxm service backup-import /home/pxm/recovery/portable \
  --name recovered-database --port 13306

The destination must be new, outside PXM_HOME, with an existing safe parent. Decryption publishes the portable directory only after the entire encrypted stream and archive paths validate. service backup-import then verifies the signed engine inventory, snapshot and credentials, and validates a fresh database generation. It creates a stopped service and leaves existing services untouched. Use the same CPU architecture as the original backup. Start the restored service after checking its settings.

The decrypted portable directory contains database credentials and must stay private. Keep a tested recovery copy and exercise restores periodically. Backup, download and existing-data recovery do not require a currently active license lease.