TechEarl

How to Export All MySQL Databases with mysqldump

Back up every MySQL (and MariaDB) database in one command with mysqldump, including --single-transaction for InnoDB consistency, gzip compression, restore steps, and the modern alternatives (MySQL Shell, Percona XtraBackup).

Ishan Karunaratne⏱️ 11 min readUpdated
Share thisCopied
Back up every MySQL database with mysqldump in one command. Covers --single-transaction, --routines, --events, --hex-blob, gzip compression, restoring from the dump, cron schedules, and modern alternatives (MySQL Shell, Percona XtraBackup).

mysqldump --all-databases > all.sql writes every database on the server to a single .sql file, schema and data both included. That's the entire one-liner you need for a basic backup. The flags that matter beyond that are --single-transaction (for InnoDB consistency without locking writes), --routines and --events (stored programs are not dumped by default), --hex-blob (for binary-safe BLOB columns), --quick (for large tables that don't fit in RAM), and --source-data (for replication-ready dumps). Below is the full reference with the production-grade command, the restore process, gzip compression, a cron-friendly script, and notes on when to reach for MySQL Shell or Percona XtraBackup instead.

What does mysqldump do and when should I use it?

mysqldump is the official command-line tool for logical backups of MySQL — it generates a .sql file containing CREATE TABLE, INSERT, and (with flags) CREATE PROCEDURE, CREATE EVENT, and CREATE TRIGGER statements that recreate every database when replayed. It's the right tool for moves between servers, point-in-time exports, schema-only dumps, and developer-machine seeding. It's the wrong tool for very large databases (>100GB), production hot backups, or anything that needs to be fast. For those, reach for MySQL Shell's dump utilities (util.dumpInstance(), which does parallel, compressed logical dumps and is the supported successor to the now-removed mysqlpump) or Percona XtraBackup (physical block-level backups, no read lock on InnoDB). MySQL Enterprise Backup and cloud-provider volume snapshots are the other production-grade options. For most installations under ~50GB, mysqldump with --single-transaction is the safest, most portable choice.

A note on mysqlpump: older guides recommend it as the parallel alternative to mysqldump. Do not. Oracle deprecated mysqlpump in MySQL 8.0.34 and removed it entirely in MySQL 8.4. On a current server it is simply not there. MySQL Shell's dump utilities are its replacement.

This works identically on MariaDB 10.x+, where the binary is now mariadb-dump with mysqldump kept as a deprecated symlink, so every command and flag below applies unchanged.

Jump to:

Basic command: back up all databases

bash
mysqldump -u root -p --all-databases > all-databases.sql

That writes every user database plus the mysql system database (accounts, grants, time zones) to all-databases.sql. It does not include information_schema, performance_schema, or sys: mysqldump skips those by default, which is correct, because they are server-generated and not meant to be restored. You'll be prompted for the password. Same syntax works on Linux, macOS, and Windows (PowerShell or cmd).

To target a remote server, add -h hostname and -P port:

bash
mysqldump -h db.example.com -P 3306 -u admin -p --all-databases > all.sql

Don't put the password on the command line. mysqldump -u root -p'mysecret' leaks the password to anyone running ps or reading shell history. Use the prompt (-p with no value), or a ~/.my.cnf credentials file:

ini
# ~/.my.cnf — chmod 600
[client]
user=backup_user
password=...
host=db.example.com

Then just mysqldump --all-databases > all.sql.

Production command: InnoDB-consistent + complete

The basic command misses several things you almost always want. The production-grade form:

bash
mysqldump \
  --single-transaction \
  --routines \
  --events \
  --triggers \
  --hex-blob \
  --quick \
  --all-databases \
  > all-databases.sql

What each flag does:

  • --single-transaction — wraps the dump in a single repeatable-read transaction. Gives you a consistent snapshot of all InnoDB tables without locking writes. Critical for production. Does NOT work for MyISAM (which is uncommon in 2026). One caveat: the snapshot only isolates DML. If another connection runs DDL (ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE) on a table while the dump is in progress, the dump can become inconsistent or fail outright. Schedule dumps away from migrations, or pause schema changes for the dump window.
  • --routines — include stored procedures and functions. Not the default. Forgetting this is the most common backup gap.
  • --events — include scheduled events. Not the default.
  • --triggers — include triggers. Actually the default, but I keep it explicit so the command is self-documenting.
  • --hex-blob — dump BLOB and BINARY columns as hex literals. Survives charset and line-ending mangling that pure binary doesn't.
  • --quick — stream rows from the server directly to the output instead of buffering an entire table in RAM. Required for very large tables.

This is the command I run on every production server.

Essential mysqldump flags

FlagPurposeWhen you need it
--single-transactionInnoDB-consistent snapshot without lockingAlways, for InnoDB
--routinesInclude stored procs and functionsAlways (not default)
--eventsInclude scheduled eventsAlways (not default)
--triggersInclude triggersDefault, keep explicit
--hex-blobDump binary as hex literalsWhen tables have BLOB/BINARY
--quickStream rows instead of bufferingLarge tables
--no-dataSchema only, no INSERTsCloning structure for staging
--no-create-infoData only, no CREATE TABLERestoring data to existing schema
--source-data=2Include CHANGE MASTER TO as commentSetting up a replica from the dump
--master-data (deprecated 8.0+)Older name for --source-dataMySQL 5.7 and earlier
--compactSuppress extra commentsSmaller output, less context
--extended-insertMulti-row INSERTs (default)Faster restore, slightly less readable
--complete-insertColumn names in every INSERTSchema-resilient restores
--max-allowed-packet=512MPer-statement size limitRestoring rows with very large BLOBs
--default-character-set=utf8mb4Dump in utf8mb4Avoiding character-set drift

Run mysqldump --help for the full list.

Compress the dump as you write it

A .sql dump from mysqldump is plain text and compresses well — typically 5-10× with gzip, more with zstd. Pipe directly instead of writing then compressing:

bash
# gzip (universally available)
mysqldump --single-transaction --routines --events --all-databases \
  | gzip > all-databases.sql.gz

# zstd (faster, better ratio — install with apt/brew install zstd)
mysqldump --single-transaction --routines --events --all-databases \
  | zstd -T0 > all-databases.sql.zst

zstd -T0 uses all CPU cores for compression and is typically 5-10× faster than gzip at the same ratio.

Restoring from a mysqldump backup

The dump is a sequence of SQL statements. Replay it with the mysql client:

bash
# Uncompressed
mysql -u root -p < all-databases.sql

# gzip
gunzip -c all-databases.sql.gz | mysql -u root -p

# zstd
zstdcat all-databases.sql.zst | mysql -u root -p

To pull a single database out of an --all-databases dump, the --one-database flag restores only statements for the named database:

bash
mysql -u root -p --one-database myapp < all-databases.sql

Treat this as a convenience, not a precise extractor. --one-database filters statements by tracking the current USE database, so it handles ordinary table data well but is unreliable for stored routines, events, triggers, and any cross-database statements, which can be missed or leak through. If you know in advance that you will need to restore one database at a time, the dependable answer is to take per-database dumps in the first place (mysqldump --databases db1 db2), not to carve them out of a full dump afterward.

For a faster restore, disable a few InnoDB checks during the import (re-enable after):

bash
mysql -u root -p <<EOF
SET unique_checks=0;
SET foreign_key_checks=0;
source all-databases.sql;
SET unique_checks=1;
SET foreign_key_checks=1;
EOF

This is 3-10× faster on data-heavy restores. Note that this does not make the restore atomic: a full dump is full of DDL (CREATE TABLE and friends), and DDL triggers an implicit commit in MySQL, so the import cannot be wrapped in a single transaction and rolled back as one unit. Treat the speed-up purely as relaxed integrity checking during the load. Only do it when you trust the dump (you generated it yourself with consistent flags); skipping foreign_key_checks on a hand-edited dump can leave the database in an inconsistent state.

Excluding specific databases or tables

--all-databases is all-or-nothing. To skip the system databases or a particular table, use a custom list:

bash
# Dump only a specific set of databases
mysqldump -u root -p --databases myapp myapp_logs > selected.sql

# Or build a list dynamically, skipping system databases
DBS=$(mysql -u root -p -e "SHOW DATABASES;" | grep -Ev "^(Database|information_schema|performance_schema|mysql|sys)$")
mysqldump -u root -p --single-transaction --routines --events --databases $DBS > user-databases.sql

To skip a single huge table while including its database:

bash
mysqldump -u root -p --single-transaction --routines --events \
  --ignore-table=myapp.event_log \
  --databases myapp > myapp.sql

Cron-friendly nightly backup script

mysql-backup-all.shDump every MySQL database to a timestamped, gzipped file, then prune anything older than KEEP_DAYS.Download
bash
#!/usr/bin/env bash
# mysql-backup-all.sh, dump every MySQL database to a timestamped, gzipped file,
# then prune anything older than KEEP_DAYS.
# Source: https://techearl.com/export-or-backup-all-mysql-databases
# Site:   https://techearl.com/
set -euo pipefail

BACKUP_DIR="/var/backups/mysql"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
KEEP_DAYS=14

mkdir -p "$BACKUP_DIR"

# Dump + compress in one pipe
mysqldump \
  --defaults-file=/root/.my.cnf \
  --single-transaction \
  --routines \
  --events \
  --triggers \
  --hex-blob \
  --quick \
  --all-databases \
  | zstd -T0 > "$BACKUP_DIR/mysql-$TIMESTAMP.sql.zst"

# Prune backups older than KEEP_DAYS
find "$BACKUP_DIR" -name "mysql-*.sql.zst" -mtime "+$KEEP_DAYS" -delete

echo "$(date -Iseconds) Backup complete: $BACKUP_DIR/mysql-$TIMESTAMP.sql.zst"

Save as /usr/local/bin/mysql-backup.sh, chmod +x, and schedule:

cron
# /etc/cron.d/mysql-backup
30 2 * * * root /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1

That runs at 2:30 AM nightly, writes a timestamped compressed dump, and prunes anything older than 14 days. Add an S3/R2 upload step at the end for off-server backups:

bash
aws s3 cp "$BACKUP_DIR/mysql-$TIMESTAMP.sql.zst" "s3://backups/mysql/mysql-$TIMESTAMP.sql.zst"

When mysqldump is the wrong tool

For databases over ~100GB, or production servers where a full-table-scan dump would dominate I/O for hours, switch to:

  • MySQL Shell dump utilities (mysqlsh with util.dumpInstance(), util.dumpSchemas(), util.dumpTables()). The modern logical-backup tooling: parallel, chunked, compressed dumps that are dramatically faster than mysqldump on multi-database servers, restored with util.loadDump(). This is the supported replacement for the old mysqlpump, which Oracle removed in MySQL 8.4.
  • Percona XtraBackup (free, open source). Physical block-level backup of the InnoDB data files. Doesn't read every row — it copies the data files and replays the redo log. Production-grade hot backup for large InnoDB installations.
  • MySQL Enterprise Backup (commercial). Oracle's equivalent of XtraBackup, requires a MySQL Enterprise license.
  • Cloud-provider snapshots. RDS automated snapshots, Cloud SQL exports, Azure Database for MySQL backups — block-level, point-in-time, often the easiest answer.

For schema migration without data, mysqldump --no-data --routines --events --triggers --all-databases produces a structure-only file in seconds even on huge databases.

What to do next

FAQ

mysqldump -u root -p --all-databases > all.sql dumps every database on the server to a single file. For production use add --single-transaction --routines --events --triggers --hex-blob --quick to get an InnoDB-consistent snapshot with stored procedures, events, triggers, and binary-safe BLOB columns included.

Pipe through gzip or zstd to compress as you write: mysqldump --all-databases | zstd > all.sql.zst.

Not by default. Add --routines to include stored procedures and functions, and --events to include scheduled events. Triggers are included by default but the --triggers flag keeps the command self-documenting.

Forgetting --routines is the single most common mistake with mysqldump.

Wraps the entire dump in a single REPEATABLE READ transaction so every InnoDB table is read from a consistent snapshot — without taking a write lock. Reads and writes continue normally on the database while the dump runs.

It's essential for production InnoDB backups. It does NOT work for MyISAM (which uses table-level locks and doesn't participate in transactions), but MyISAM is rare in 2026.

Pipe the dump into the mysql client: mysql -u root -p < all.sql. For a compressed dump, decompress on the fly: gunzip -c all.sql.gz | mysql -u root -p or zstdcat all.sql.zst | mysql -u root -p.

To restore a single database from an --all-databases dump, add --one-database dbname on the mysql command.

Roughly 50-100 GB per hour on typical hardware for a logical dump, including compression. The bottleneck is usually disk I/O on the database server (reading every row sequentially) and CPU on the receiving side (gzip or zstd compression).

For databases over ~100GB where a 2+ hour dump is unacceptable, switch to Percona XtraBackup (physical block-level backup, typically 10-20× faster) or MySQL Shell's dump utilities (parallel logical dump, several times faster than mysqldump).

--all-databases is all-or-nothing. To skip specific databases, build a list dynamically and pass it to --databases:

DBS=$(mysql -e "SHOW DATABASES;" | grep -Ev "^(Database|information_schema|performance_schema|mysql|sys)$"); mysqldump --databases $DBS > user.sql

To skip a single table while keeping the rest of its database, use --ignore-table=dbname.tablename.

Add --hex-blob. This dumps BLOB and BINARY column values as hexadecimal literals like 0xDEADBEEF instead of raw binary, which survives any charset transcoding, line-ending conversion, or text-mode file transfers in the middle of the pipeline.

Without --hex-blob, an SCP transfer or a vim edit can silently corrupt the dump.

mysqldump for everything under ~50GB, schema-only dumps, and developer-machine seeding. Universally available, deterministic output, easy to inspect.

MySQL Shell's dump utilities (util.dumpInstance() and friends) for multi-database servers in the 50-500GB range where parallelism helps. This is the modern logical-dump tool and the replacement for the removed mysqlpump.

Percona XtraBackup for production databases over ~100GB, especially when you need hot backups without read-load impact. Physical block-level copy, replays the redo log. Free and open-source.

Sources

Authoritative references this article was fact-checked against.

TagsMySQLBackupmysqldumpCommand LineLinuxRestoreReplication

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Software Systems Architect · Senior Software Engineer · Engineering Leadership

Software systems architect and senior software engineer with more than two decades designing, building, and running production software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Now a CTO, though what I write here is drawn from the full arc of that work, across architecture, engineering, and operations, not any single job.

Keep reading

Related posts

Macro photograph of a printed spreadsheet ledger on a dark slate desk, neat columns of numbers in monospaced print, single warm side lamp grazing the page edge

How to Export a MySQL Table to CSV

Export a MySQL table to CSV using SELECT INTO OUTFILE, mysqldump --tab, the mysql client with a piped redirect, or a no-privilege one-liner that works on hosts where FILE is disabled.

Import a CSV into MySQL with LOAD DATA INFILE, LOAD DATA LOCAL INFILE, or mysqlimport. Handle headers, character encoding, FILE privilege, and broken CSVs.

How to Import a CSV File Into MySQL

Import a CSV into MySQL using LOAD DATA INFILE, LOAD DATA LOCAL INFILE, or the mysqlimport command. Covers header rows, encoding, the FILE privilege, and broken CSVs.