Percona XtraBackup: Бэкап на удаленный сервер
Довольно часто встречается ситуация когда MySQL разросся до размеров в десятки и сотни гигабайт, место для резервной копии на сервере уже нет, а нужно создать копию всех баз и переместить ее на удаленный сервер. Иногда встречается ситуация, когда нужно развернуть полную копию MySQL на другом сервере.
Исходные данные: Ubuntu, MySQL 5.7
Задача: Создать горячую (hotbackup) резервную копию MySQL и переместить ее на удаленный сервер, при этом не сохраняя ее на текущем сервере, чтобы не занимать драгоценное место.
Для начала нам нужно установить Percona Xtrabackup и набор утилит qpress, socat, nc на оба сервера. Если все утилиты у Вас уже установлены, то пропустите этот шаг.
1. Скачиваем и устанавливаем пакет percona-release_latest, включаем репозитарий percona tools (release) и устанавливаем набор полезных утилит от Percona Toolkit, устанавливаем Percona Xtrabackup и вспомогательные утилиты qpress, socat
wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb && rm -f percona-release_latest.$(lsb_release -sc)_all.deb percona-release enable-only tools release apt-get update apt-get install -y percona-toolkit percona-xtrabackup-24 qpress socat screen
2. На сервере приемнике (куда будем копировать резервную копию) создаем каталог, куда будет загружаться резервная копия и запускаем socat + xbstream. Все действия выполняем находясь под пользователем root. Перед запуском Вы должны проверить, что на сервере-приемнике достаточно места на файловой системе для приема бэкапа. Запускать socat желательно в screen чтобы в случае обрыва ssh сессии процесс приема не прервался.
mkdir /root/mysqlbackup screen socat -u tcp-listen:9999,reuseaddr stdout 2>/tmp/socat.log | xbstream -x -C /root/mysqlbackup
на что следует обратить внимание:
- директива tcp-listen:9999 указывает, что мы будем принимать входящие подключения по протоколу TCP на порт 9999, не забудьте открыть порт на межсетевом экране;
- принятый поток будет передаваться xbstream, а тот будет сохранять данные в каталог /root/mysqlbackup, проверьте чтобы на диске было достаточно места для данных.
Сколько необходимо? Столько, сколько на источнике занимает каталог с данными MySQL, как правило это /var/lib/mysql, но он может меняться. Посмотрите на источнике в MySQL настройку datadir, она покажет каталог хранения данных.
3. На источнике запускаем xtrabackup в формат потокового резервного копирования xbstream. Запускать xtrabackup желательно в screen чтобы в случае обрыва ssh сессии процесс создания и передачи резервной копии не прервался.
screen ulimit -n 256000 && /usr/bin/xtrabackup --defaults-file=/etc/mysql/my.cnf --host=127.0.0.1 --port 3306 --user=root --password=mysqlrootpasswd --backup --no-backup-locks --no-lock --parallel=4 --stream=xbstream | socat - TCP4:172.16.0.1:9999
на что следует обратить внимание:
- директива –defaults-file указывает местоположение файла конфигурации MySQL, это директива должна быть самой первой в списке;
- директивы –рost, –port, –user и –password указывают соответствующие опции подключения к работающему MySQL, это у Вас они будут своими, как минимум пароль пользователя root;
- директива –no-backup-locks указывает, что не нужно делать блокировок при резервном копировании;
- директива –no-lock указывает, что не нужно делать блокировок таблиц при резервном копировании;
- директива –parallel указывает, во сколько потоков будет идти резервное копирование;
- директива –stream указывает формат потокового резервного копирования;
- директива для socat – TCP4:172.16.0.1:9999 — указывают протокол, IP адрес и порт приемника, это адрес сервера из п.2;
После запуска xtrabackup начнется процесс создания горячей резервной копии и одновременной передачи её на сервер-приемник.
Процедура восстановления состоит из нескольких простых шагов:
1. Подготовка нашей горячей резервной копии для восстановления.
Смысл подготовки в том, что файлы данных, которые мы копировали с исходного сервера, не согласованы на определенный момент времени, потому что они копировались в разное время во время работы xtrabackup и они могли быть изменены, когда это происходило. Если Вы попытаетесь запустить InnoDB с этими файлами данных, то он обнаружит повреждение и не запустится. Поэтому нужно запустить xtrabackup с опцией –prepare для подготовки и согласования файлов на один момент времени.
На этапе подготовки xtrabackup запускает встроенный в нее движок InnoDB с некоторыми отключенными опциями и запускает восстановление после сбоя скопированных файлов данных и журналов.
Если резервная копия была в сжатом виде, то в процессе подготовки все файлы будут распакованы, для этого используется утилита qpress. Следует знать, что на распаковку потребуется дополнительное место на сервере, поэтому будьте внимательны если у Вас большая резервная копия.
Так же следует знать, что если Вы намерены подготовить резервную копию которая основана на дополнительных инкрементных резервных копий, то Вам следует использовать xtrabackup с опцией –apply-log-only при подготовке, иначе Вы не сможете применять инкрементные резервные копии к ней.
ВАЖНО! В процессе подготовки не рекомендуется прерывать работу xtrabackup, т.к. это приведет к повреждению вашей горячей резервной копии и в дальнейшем к невозможности восстановления. Именно поэтому запускать xtrabackup лучше в сессии screen, чтобы в случае потери связи с сервером ваш сеанс работы xtrabackup не завершился.
Итак запускаем:
screen xtrabackup --prepare --target-dir=/root/mysqlbackup
В конце работы вы получите примерно такой вывод:
..... InnoDB: FTS optimize thread exiting. InnoDB: Starting shutdown... InnoDB: Shutdown completed; log sequence number 11306536 200408 22:28:31 completed OK!
Где цифра 11306536 будет уникальна для вашей системы — это LSN (log sequence number).
2. Далее нам нужно остановить MySQL на сервере-приемнике, переименовать каталог /var/lib/mysql, создать новый, выставить права, запустить восстановление и далее запустить уже восстановленный MySQL:
Останавливаем MySQL:
systemctl stop mysql
Проверим отсутствие процесса mysqld:
ps -auxw | grep [m]ysqld
Переименует каталог /var/lib/mysql, после восстановления его можно будет удалить:
mv /var/lib/mysql /var/lib/mysql_old
Создаем пустой каталог /var/lib/mysql и выставляем права:
mkdir -p /var/lib/mysql chmod 750 /var/lib/mysql
Запускаем процедуру восстановления из горячей резервной копии:
xtrabackup --copy-back --target-dir=/root/mysqlbackup
С опцией –copy-back утилита xtrabackup будет копировать резервную копию из /root/mysqlbackup в каталог /var/lib/mysql
Стоит отметить, что xtrabackup берет каталог-назначения (у нас это /var/lib/mysql) куда будет произведено копирование из файла настроек MySQL.
Так же есть опция –move-back при использовании которой данные будут перемещены, а не скопированы — это полезно при больших размерах резервной копии, тем самым Вы сэкономить место на сервере и, что еще лучше, ускорите процедуру восстановления, ведь перемещение в пределах одного раздела будет практически моментальным.
Процедура восстановления выглядит примерно так:
xtrabackup: recognized server arguments: --datadir=/var/lib/mysql --tmpdir=/tmp xtrabackup: recognized client arguments: --copy-back=1 --target-dir=/root/mysqlbackup xtrabackup version 2.4.19 based on MySQL server 5.7.26 Linux (x86_64) (revision id: c2d69da) 200408 22:29:44 [01] Copying ib_logfile0 to /var/lib/mysql/ib_logfile0 200408 22:29:45 [01] ...done 200408 22:29:46 [01] Copying ib_logfile1 to /var/lib/mysql/ib_logfile1 200408 22:29:46 [01] ...done 200408 22:29:48 [01] Copying ibdata1 to /var/lib/mysql/ibdata1 200408 22:29:50 [01] ...done 200408 22:29:51 [01] Copying ./ib_buffer_pool to /var/lib/mysql/ib_buffer_pool 200408 22:29:51 [01] ...done ... 200408 22:29:57 [01] ...done 200408 22:29:57 completed OK!
Вывод в конце completed OK! говорит о ее успешном завершении.
Далее устанавливаем владельца файлов, стандартно это пользователь mysql и группа mysql:
chown -R mysql:mysql /var/lib/mysql
И запускаем восстановленный MySQL:
systemctl start mysql
Посмотрим последние 20 строк лога error.log:
tail -n 20 /var/log/mysql/error.log .... 2020-04-08T17:30:17.391818Z 0 [Note] Generated uuid: '9d0e23cd-79be-11ea-ae96-000c29f8dd8e', server_start_time: 7308497771878576021, bytes_sent: 94787016996592 2020-04-08T17:30:17.391842Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 9d0e23cd-79be-11ea-ae96-000c29f8dd8e. 2020-04-08T17:30:17.423418Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them. 2020-04-08T17:30:17.423441Z 0 [Note] Skipping generation of SSL certificates as certificate files are present in data directory. 2020-04-08T17:30:17.424811Z 0 [Warning] CA certificate ca.pem is self signed. 2020-04-08T17:30:17.424850Z 0 [Note] Skipping generation of RSA key pair as key files are present in data directory. 2020-04-08T17:30:17.425936Z 0 [Note] Server hostname (bind-address): '*'; port: 3306 2020-04-08T17:30:17.425978Z 0 [Note] IPv6 is available. 2020-04-08T17:30:17.425985Z 0 [Note] - '::' resolves to '::'; 2020-04-08T17:30:17.426022Z 0 [Note] Server socket created on IP: '::'. 2020-04-08T17:30:17.492994Z 0 [Note] InnoDB: Buffer pool(s) load completed at 200408 22:30:17 2020-04-08T17:30:17.495342Z 0 [Note] Event Scheduler: Loaded 0 events 2020-04-08T17:30:17.496230Z 0 [Note] /usr/sbin/mysqld: ready for connections.
Мы видим, что MySQL успешно запустился, был создан новый UUID экземпляра и он может принимать подключения.