A physical backup copies the files that MySQL uses (tablespaces, redo logs, system files), not the SQL that creates the data. Backups and restores are much faster than a dump, which matters for databases of tens or hundreds of gigabytes. The price is portability: a physical backup is for the same major version (and usually the same operating system and architecture).
Never copy the data directory of a running server
Copying /var/lib/mysql with cp or rsync while MySQL is running gives a corrupted, inconsistent copy: pages change while they are being copied. The server must be stopped cleanly, or you must use a tool that handles the live server. The options:
| Tool | Edition | How |
|---|---|---|
| CLONE plugin | MySQL Community (built in since 8.0.17) | A built-in SQL statement that copies a consistent InnoDB snapshot |
| Percona XtraBackup | Free, open source | Copies files while tracking the redo log, supports incremental backups and compression |
| MySQL Enterprise Backup | Commercial MySQL Enterprise Edition | Oracle’s hot backup tool |
| Filesystem or cloud snapshots (LVM, ZFS, EBS, VM snapshots) | Any | Instant snapshot of the volume. Consistent for InnoDB only when the data and logs are on one volume, and recovery then runs like crash recovery |
| Cold backup | Any | Stop mysqld, copy the directory, start again. Simple, but it means downtime |
The CLONE plugin, for real
CLONE makes a consistent copy of all InnoDB data while the server keeps running. It needs a plugin, installed once (this is the Windows library name, on Linux it is mysql_clone.so):
INSTALL PLUGIN clone SONAME 'mysql_clone.dll';
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM information_schema.PLUGINS WHERE PLUGIN_NAME = 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone | ACTIVE |
+-------------+---------------+
Then clone to a new directory (it must not exist yet, and the MySQL server’s operating system user must be able to create it):
CLONE LOCAL DATA DIRECTORY = '/backups/clone-2026-10-05';
SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status;
+-----------+----------+---------------+
| STATE | ERROR_NO | ERROR_MESSAGE |
+-----------+----------+---------------+
| Completed | 0 | |
+-----------+----------+---------------+
On a real MySQL 8.4 test server the clone directory afterwards contained a complete data directory:
#clone #innodb_redo ib_buffer_pool ibdata1 learn mysql mysql.ibd shop sys undo_001 undo_002
To prove it is a real, working backup, a second MySQL server was started on the cloned directory (on another port), and it contained the data:
mysqld --datadir=/backups/clone-2026-10-05 --port=3399
SELECT @@port AS port, (SELECT COUNT(*) FROM shop.orders) AS orders, (SELECT COUNT(*) FROM shop.customers) AS customers;
+------+--------+-----------+
| port | orders | customers |
+------+--------+-----------+
| 3399 | 6 | 5 |
+------+--------+-----------+
(Values from the real test; the table layout is shortened.) A few important points:
CLONEcopies InnoDB data. Other engines’ files are copied only partly (MyISAM tables are not consistent), and configuration files and the binary logs are not included.- A remote clone (
CLONE INSTANCE FROM 'user'@'host':3306 IDENTIFIED BY '...') copies from one server to another over the network. It is a fast way to build a new replica. - It needs the account to have the
BACKUP_ADMINprivilege (on the donor), andCLONE_ADMINon a recipient. - Cloning blocks some DDL (
ALTER TABLE,DROP TABLE) on the donor while it runs. - After restoring a clone, the server runs crash recovery on start, like after a power cut. That is normal for hot backups.
XtraBackup
Percona XtraBackup is the common free tool for hot physical backups:
# take a full backup
xtrabackup --backup --user=backup --password --target-dir=/backups/full-2026-10-05
# prepare it (apply the redo log so the files are consistent)
xtrabackup --prepare --target-dir=/backups/full-2026-10-05
# restore: with MySQL stopped and an empty data directory
xtrabackup --copy-back --target-dir=/backups/full-2026-10-05
chown -R mysql:mysql /var/lib/mysql
The three phases are always backup, prepare, restore. An unprepared backup is not consistent. XtraBackup also offers incremental backups (only pages changed since the last one), compression and encryption. Use the XtraBackup version that matches your MySQL version.
Snapshots
Cloud disks and storage systems can take an instant snapshot. For MySQL:
- Keep data and redo logs on the same volume, so that one snapshot is consistent.
- InnoDB recovers from the snapshot as from a crash, which works because InnoDB is crash-safe.
- With
sync_binlog = 1andinnodb_flush_log_at_trx_commit = 1(the safe defaults), no committed transaction is lost. - For a more controlled snapshot, run
FLUSH TABLES WITH READ LOCK, snapshot, thenUNLOCK TABLES. That blocks writes for a moment. - Test a restore from a snapshot like any other backup.
Choosing
| Situation | Choice |
|---|---|
| Small database (up to a few GB), simple needs | mysqldump nightly + binary logs |
| Large database, short RTO | Physical backup (XtraBackup, CLONE, snapshots) + binary logs |
| Upgrading across versions, moving platforms | mysqldump or MySQL Shell dump |
| Building a replica | CLONE, XtraBackup, or a snapshot |
| Managed cloud database | The provider’s automated backups and point-in-time restore. Also keep an independent logical dump |
Physical backups and the binary log together give you point-in-time recovery: restore the files, then replay the log from the position stored in the backup (Point-in-Time Recovery).