A logical backup makes schema changes, accidental deletes, and failed upgrades recoverable without rebuilding data by hand. A recent dump file is often the fastest path to a clean restore point for testing, rollback, or disaster recovery.
Current MySQL releases use mysqldump, while current MariaDB releases use mariadb-dump for the same job. Both clients connect to the server and write SQL statements for tables, views, triggers, routines, and events, and piping the output through gzip produces one compressed archive that is easier to move, retain, and verify.
Consistency and permissions still matter. --single-transaction creates a consistent snapshot for transactional tables such as InnoDB, but non-transactional tables such as MyISAM or MEMORY can still change during the dump. A restrictive umask keeps the archive private, --no-tablespaces avoids extra tablespace metadata and the extra MySQL privilege it can require, and full-instance dumps should keep --routines and --events explicit because current MySQL releases no longer include them automatically with --all-databases.
$ sudo install --directory --owner=root --group=root --mode=0700 /var/backups/mysql
$ DUMP_CMD="$(command -v mariadb-dump >/dev/null 2>&1 && echo mariadb-dump || echo mysqldump)" $ printf '%s\n' "$DUMP_CMD" mariadb-dump
Current MariaDB releases use mariadb-dump, and current MySQL releases still use mysqldump. MariaDB 11 removed the mysqldump symlink from the official image, so choosing the binary explicitly avoids a stale command name.
$ umask 077
Files created after this command default to mode 600 in the current shell session, which keeps the dump readable only by the current user unless permissions are changed later.
$ date +%F_%H%M%S 2026-04-09_170422
Reuse the timestamp output in the filenames below to keep backups sortable.
$ "$DUMP_CMD" --user=dbbackup --password --single-transaction --quick --routines --events --triggers --no-tablespaces --databases appdb | gzip --stdout > /var/backups/mysql/appdb-2026-04-09_170422.sql.gz Enter password:
Avoid putting passwords on the command line with --password=secret or -psecret, since process listings and shell history can expose them.
--databases adds CREATE DATABASE and USE statements so the dump can recreate the named schema during restore.
If the backup includes MyISAM or other non-transactional tables, plan a quiet write window or use a lock-based dump instead of relying on --single-transaction alone.
$ "$DUMP_CMD" --user=dbbackup --password --single-transaction --quick --triggers --no-tablespaces appdb orders | gzip --stdout > /var/backups/mysql/appdb.orders-2026-04-09_170422.sql.gz Enter password:
Table-level dumps usually do not contain CREATE DATABASE or USE statements, so restore them into an existing target database.
$ "$DUMP_CMD" --user=dbbackup --password --single-transaction --quick --routines --events --triggers --no-tablespaces --databases appdb inventory | gzip --stdout > /var/backups/mysql/multiple-databases-2026-04-09_170422.sql.gz Enter password:
$ "$DUMP_CMD" --user=dbbackup --password --single-transaction --quick --routines --events --triggers --no-tablespaces --all-databases | gzip --stdout > /var/backups/mysql/all-databases-2026-04-09_170422.sql.gz Enter password:
Keep --routines and --events explicit here. Current MySQL releases do not include them automatically with --all-databases.
--all-databases includes system schemas and account metadata, so store the resulting archive with the same care as a credential backup.
$ ls -lh /var/backups/mysql/appdb-2026-04-09_170422.sql.gz -rw------- 1 root root 1.8K Apr 9 17:04 /var/backups/mysql/appdb-2026-04-09_170422.sql.gz
If several dump commands were run, list the whole directory with ls -lh /var/backups/mysql to review every archive written in the session.
$ gzip --test /var/backups/mysql/appdb-2026-04-09_170422.sql.gz
No output indicates the gzip stream is readable. A non-zero exit status indicates a truncated or corrupt archive.
$ gzip --decompress --stdout /var/backups/mysql/appdb-2026-04-09_170422.sql.gz | head -n 18 /*M!999999\- enable the sandbox mode */ -- MariaDB dump 10.19-12.2.2-MariaDB, for osx10.21 (arm64) -- -- Host: 127.0.0.1 Database: appdb -- ------------------------------------------------------ -- Server version 11.8.6-MariaDB-ubu2404 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */;
Recent MariaDB dumps begin with a sandbox-mode comment. Restore those dumps with mariadb or another MariaDB-compatible import path, not an older MySQL client that does not understand the header.
MySQL dumps begin with a -- MySQL dump header instead, but the same validation pattern still works.
$ gzip --decompress --stdout /var/backups/mysql/appdb-2026-04-09_170422.sql.gz | grep -nE 'TRIGGER|EVENT|PROCEDURE' 67:/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER orders_before_insert 96:/*!50106 DROP EVENT IF EXISTS `order_cleanup_demo` */; 122:/*!50003 DROP PROCEDURE IF EXISTS `order_count` */;
No matches can mean the database does not use those object types, or that the dump command omitted options such as --routines or --events.