Percona XtraBackup: Бэкап отдельной таблицы или базы

Не всегда нужны архивные копии всего mysql сервера. Иногда достаточно отдельной базы данных или даже таблицы. Xtrabackup позволяет это сделать на отдельном сервере.

Не забываем проверить, чтобы был установлен параметр innodb_file_per_table в настройка сервера баз данных.

Архивируем только одну базу данных site.

xtrabackup --backup --databases "site" --target-dir=/root/backupdb/site

Восстановление отдельной базы mysql будет выглядеть так.

xtrabackup --prepare --databases "site" --target-dir=/root/backupdb/site
systemctl stop mysqld
mkdir -p /var/lib/mysql.old/site
mv /var/lib/mysql/site /var/lib/mysql.old
mv /root/backupdb/site/site /var/lib/mysql
chown -R mysql. /var/lib/mysql
systemctl start mysql

Мы по сути просто скопировали исходные файлы базы из бэкапа в рабочий каталог, предварительно сохранив предыдущую версию базы на всякий случай.

Теперь попробуем из полного бэкапа базы восстановить только одну таблицу. В примере на работающем сервере делается восстановление существующей таблицы из полного бэкапа. Если будете восстанавливать на другой сервер, то перед этим вам нужно будет воссоздать исходную структуру таблицы перед тем, как будете восстанавливать данные по предложенному методу.

Готовим бэкап к восстановлению:

xtrabackup --prepare --export --target-dir=/root/backupdb/full

Идем в консоль mysql и выбираем там таблицу для восстановления. В примере это будет таблица b_user_access из базы site. Смотрим, заполнена ли таблица данными.

mysql> SELECT COUNT(*) FROM site.b_user_access;
+----------+
| COUNT(*) |
+----------+
|   6 |
+----------+
1 row in set (0.00 sec)

Делаем DISCARD этой таблицы.

mysql> ALTER TABLE site.b_user_access DISCARD TABLESPACE;
Query OK, 0 rows affected (0.00 sec)

Discard означает, что будет удален ibd файл таблицы. Теперь нам его нужно скопировать из бэкапа и назначить права для mysql.

cp /root/backupdb/full/site/b_user_access.* /var/lib/mysql/site
chown mysql. /var/lib/mysql/site/b_user_access.*

Возвращаемся в консоль mysql и импортируем данные.

mysql> ALTER TABLE site.b_user_access IMPORT TABLESPACE;
Query OK, 0 rows affected (0.03 sec)

Смотрим, что получилось.

mysql > SELECT COUNT(*) FROM site.b_user_access;
+----------+
| COUNT(*) |
+----------+
|   6 |
+----------+
1 row in set (0.00 sec)

Данные восстановлены.