Backup a MySQL database
This recipe shows how to back up a MySQL database using mysqldump. The dump is streamed to STDOUT, encrypted locally by the Backup Verified agent, uploaded as an encrypted backup, and later available for download, decryption, and restore.
What this recipe is for
This recipe is a practical starting point for backing up a MySQL database with a logical dump. It works well for many common applications where a portable SQL-based backup is more useful than a raw disk copy.
The basic idea is simple: mysqldump writes the backup data to STDOUT, the Backup Verified agent reads that stream, encrypts it locally, and uploads only the encrypted result.
This keeps the workflow clean and scriptable while still giving you a later path to download, decrypt, and restore the backup when needed.
Good fit for
- Application databases
- Routine logical backups
- Portable dump-based recovery workflows
- Scheduled daily or frequent backups
Not ideal for
- Very large environments that require physical backup tooling
- Cases where a consistent dump cannot be achieved without more database-specific planning
Before you begin
- Install the Backup Verified agent.
- Make sure mysqldump is installed and available on your system.
- Create or obtain your bv-agent.yml config.
- Use a MySQL account with permission to read the database you want to back up.
Why this works
mysqldump writes its output to STDOUT by default, which makes it a natural fit for Backup Verified. There is no need to first dump to a local file unless you specifically want that extra step.
The agent reads the stream, encrypts it locally, and uploads the encrypted result to Managed Storage. That gives you a clean backup workflow without exposing plaintext data during storage.
The recipe
Use a logical dump command that is safe for many common MySQL workloads and keeps the output on STDOUT.
Step 1: Use this dump command
mysqldump \
--single-transaction \
--quick \
--skip-lock-tables \
--no-tablespaces \
--routines --triggers --events \
--set-gtid-purged=OFF \
-u USER \
DB_NAME
Replace USER and DB_NAME with values for your environment.
Step 2: Keep credentials out of the command line when possible
Avoid placing passwords directly in the backup command. Use your database client’s recommended secure credential method so the command itself stays clean and easier to manage.
The goal here is not just to make the backup work once. It is to make it repeatable and safe enough to schedule.
Suggested BV config
This example uses mysqldump as the backup command and gives the backup a clear identity inside Backup Verified.
# bv-agent.yml
bv:
api_base: "https://backupverified.com"
timeout_seconds: 30
work_timeout_seconds: 0
upload_timeout_seconds: 0
agent_key: "YOUR_AGENT_KEY"
client_encryption_key_b64: "YOUR_CLIENT_ENCRYPTION_KEY_B64"
backup:
source_key: "mysql_app_db"
name: "MySQL App Database"
description: "Logical dump of MySQL database"
delete_after_days: 0
source:
type: "mysql"
backup_command: >
mysqldump
--single-transaction
--quick
--skip-lock-tables
--no-tablespaces
--routines --triggers --events
--set-gtid-purged=OFF
-u USER
DB_NAME
The > after backup_command: is YAML formatting for multi-line text. It is not shell output redirection.
How to run it
bv-agent validate-config -config bv-agent.yml
bv-agent backup -config bv-agent.yml
Validate first, then run the backup. If the dump command succeeds and the upload completes, the encrypted backup should appear in your portal.
What success looks like
- The agent completes without error.
- Your MySQL backup appears in the Backup Verified portal.
- You can later download the encrypted file and decrypt it locally.
- The decrypted output is a logical dump you can inspect or restore.
What could go wrong
Logical database backups are powerful, but there are a few common failure points worth watching closely.
Credential problems
If the MySQL user cannot connect or lacks permission to read the database, the dump will fail before the backup can succeed.
Wrong database name
A typo in DB_NAME can lead to an immediate failure or a backup of the wrong target.
Assuming success without testing restore
A backup is more trustworthy when you have actually downloaded, decrypted, and validated the dump at least once.
The goal is not just to produce a backup file. It is to build confidence that your backup exists, can be retrieved later, and can be turned back into useful data.
How to download it later
- 1. Sign in to your Backup Verified portal.
- 2. Open the MySQL backup entry you want.
- 3. Use the download option to retrieve the encrypted backup file.
- 4. Save it somewhere convenient for the decrypt step.
The downloaded file is still encrypted. That is expected.
Why that matters
Your dump is stored encrypted. Backup Verified does not need the plaintext database contents in order to store the backup.
Decryption happens locally with your own key material, which keeps control in your hands.
How to decrypt it locally
Once you have downloaded the encrypted backup file, use the agent to decrypt it locally.
bv-agent decrypt --in backup.bin.enc --out ./restore/ -config bv-agent.yml
Replace backup.bin.enc with your actual downloaded filename. The --out path is where the decrypted result will be written.
Then inspect the output
ls -lah ./restore/
Confirm that the decrypted output is present and looks like a valid dump for the database you intended to protect.
Good habit
Early on, do a real download-and-decrypt test instead of assuming everything is fine. That simple habit builds real confidence.
What restore means for this recipe
For a MySQL logical dump, restore usually means importing the decrypted dump back into MySQL. The exact restore command depends on how you manage your environment and where you want the data restored.
In practice, many people first decrypt the backup, inspect the dump, and then restore it into a test or recovery database before using it in production.
mysql -u USER -p DB_NAME < decrypted_dump.sql
The exact filename and restore target will depend on your environment and workflow.
Related recipes
These are natural next steps once this workflow is in place.