MariaDB started as a fork of MySQL, but its backup tooling has diverged: it ships its own physical backup tool, its own client names and different defaults. This article covers consistent logical dumps, physical backups with mariadb-backup, scheduling, binary logs and how to validate that your backups really restore.

Know your tools and their names

Since MariaDB 10.5, client programs use mariadb- names. The old MySQL-style names still exist as symlinks on most distributions, but documentation and new options follow the MariaDB names.

PurposeMariaDB nameOlder / MySQL-compatible name
Logical dumpmariadb-dumpmysqldump
Physical hot backupmariadb-backupmariabackup
Command-line clientmariadbmysql
Binary log readermariadb-binlogmysqlbinlog
Table checksmariadb-checkmysqlcheck

Do not use Percona XtraBackup with recent MariaDB versions: the InnoDB implementations have diverged and mariadb-backup is the supported tool.

Strategy 1: consistent logical backups with mariadb-dump

For InnoDB tables, a single-transaction dump is consistent without blocking writes:

mariadb-dump --single-transaction --quick --routines --events --triggers \
  --master-data=2 --all-databases -u backup -p \
  | zstd -q -o /srv/backups/mariadb-all-$(date +%F_%H%M).sql.zst

The --master-data=2 option records the binary log coordinates as a comment, which you need for point-in-time recovery. It requires binary logging to be enabled and the RELOAD privilege for the brief global lock used to read a consistent position.

Logical dumps are portable across versions and allow restoring a single database or table, but restoring them means re-executing every INSERT and rebuilding indexes, which becomes slow for large datasets. They also cannot provide consistency for non-transactional engines such as MyISAM or Aria; plan a short lock or engine conversion for those tables.

Strategy 2: physical backups with mariadb-backup

mariadb-backup copies data files while the server runs and keeps track of the redo log produced in the meantime. A backup has three phases.

# 1. Backup (server running)
mariadb-backup --backup --target-dir=/srv/backups/full-2026-10-19 \
  --user=backup --password=***

# 2. Prepare: apply the redo log so the files are consistent
mariadb-backup --prepare --target-dir=/srv/backups/full-2026-10-19

# 3. Restore (server stopped, empty datadir)
systemctl stop mariadb
mariadb-backup --copy-back --target-dir=/srv/backups/full-2026-10-19
chown -R mysql:mysql /var/lib/mysql
systemctl start mariadb

The backup user needs privileges such as RELOAD, PROCESS, LOCK TABLES and BINLOG MONITOR (called REPLICATION CLIENT before 10.5); check the documentation for your version. Use a mariadb-backup binary from the same MariaDB release as the server: version mismatches are a common cause of failures.

Incremental physical backups

mariadb-backup can copy only the pages changed since a previous backup:

mariadb-backup --backup --target-dir=/srv/backups/inc-2026-10-20 \
  --incremental-basedir=/srv/backups/full-2026-10-19 --user=backup --password=***

Before restoring, the full backup is prepared and each incremental is applied in order with --prepare --incremental-dir. Incrementals save time and space but add steps and dependencies to the restore: if one increment in the chain is damaged, later ones are unusable. Keep chains short, for example a weekly full plus daily incrementals.

Choosing between logical and physical

Criterionmariadb-dumpmariadb-backup
Database sizeSmall to mediumMedium to very large
Restore speedSlow (replays SQL)Fast (copies files)
Restore a single tableEasyPossible with partial restore, more steps
Cross-version restoreYesSame version only
Storage sizeSmall after compressionSimilar to data size

Many teams use both: a nightly physical backup for fast full recovery and a logical dump for single-table restores and long-term archives.

Binary logs for point-in-time recovery

Unlike MySQL 8, MariaDB does not enable binary logging by default. Enable it explicitly:

[mariadb]
log_bin = /var/lib/mysql/binlog
binlog_format = ROW
expire_logs_days = 14
server_id = 1

Keep logs longer than the interval between full backups and copy them offsite frequently. To recover, restore the last full backup, then replay binary logs from the recorded position up to the chosen moment with mariadb-binlog --start-position=... --stop-datetime=..., as described in the MySQL guide. For physical backups, the binary log position is recorded in a file inside the backup directory: xtrabackup_binlog_info in many versions, renamed with a mariadb_backup_ prefix in newer releases. Check which one your version writes.

Galera clusters and replicas

In a Galera cluster, every node holds the full dataset, so you can back up from one node, ideally one that does not receive application traffic. mariadb-backup works with Galera; enable --galera-info to record the cluster position. With asynchronous replication, back up from a replica after checking that it is not lagging and has no replication errors (SHOW REPLICA STATUS).

Scheduling with systemd

Systemd timers give you logs and a clear failed state:

# /etc/systemd/system/mariadb-backup.service
[Unit]
Description=Nightly MariaDB backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mariadb-backup-nightly.sh

# /etc/systemd/system/mariadb-backup.timer
[Unit]
Description=Run MariaDB backup every night

[Timer]
OnCalendar=*-*-* 02:15:00
Persistent=true

[Install]
WantedBy=timers.target

Enable it with systemctl enable --now mariadb-backup.timer and alert when the service fails or when no successful run happened in the last 24 hours. Store credentials in an option file readable only by root (for example /root/.my.cnf with mode 0600) instead of the command line.

Validation

A backup that completed is not necessarily usable. Build validation into the routine:

  • Physical backups: a successful --prepare is the first check. Preparing a copy of each backup right after it is taken detects many problems early.
  • Logical dumps: check that the file ends with the "Dump completed" comment and is not truncated.
  • Restore tests: regularly restore into a temporary instance, run mariadb-check --all-databases, and compare row counts or checksums of important tables with production.
  • Record durations: the time a full restore takes defines your real recovery time (see RPO vs RTO).

Common mistakes

  • Leaving binary logging disabled and discovering after an incident that point-in-time recovery is impossible.
  • Using XtraBackup or a mismatched mariadb-backup version.
  • Restoring a physical backup without running --prepare.
  • Keeping long incremental chains without periodic full backups.
  • Storing backups and binary logs only on the database server.

Next steps

  1. Enable binary logging with a retention longer than your full backup interval.
  2. Set up a nightly mariadb-backup with prepare and an offsite copy.
  3. Add a logical dump for single-table restores.
  4. Schedule a monthly restore test and keep a written procedure.

Backnix is designed to automate consistent MariaDB backups with encryption and offsite storage; follow the status on the database backup page. For containerized MariaDB, see Docker backup best practices.

References

Topics: MariaDBmariadb-backupmariadb-dump