|
|
(не показано 9 промежуточных версий этого же участника) |
Строка 1: |
Строка 1: |
− | '''Установка Percona XtraBackup'''
| |
| | | |
− | С установкой XtraBackup нет никаких проблем и нюансов. Под все популярные дистрибутивы есть готовые пакеты в официальном репозитории. В примере Debian Buster:<br/>
| |
− | # wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
| |
− | # dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
| |
− |
| |
− | Ставим сам пакет:
| |
− | # apt update && apt install percona-xtrabackup-80
| |
− |
| |
− |
| |
− | '''Полный бэкап Mysql-сервера'''
| |
− |
| |
− | Итак, база данных у нас работает, утилиту для бэкапа мы установили. Делаем полный backup всех баз данных сервера mysql.
| |
− | # xtrabackup --backup --user=root --password='RzDXcVUmIzwxaNBTN' --target-dir=/root/backupdb/full
| |
− |
| |
− | * backup - инициируем процедуру бэкапа<br/>
| |
− | * user - пользователь mysql<br/>
| |
− | * password - пароль пользователя, взятый в одинарные кавычки<br/>
| |
− | * target-dir - директория для создания полного бэкапа mysql
| |
− |
| |
− |
| |
− | В дальнейших примерах не будем указывать пользователя и пароль, чтобы упростить команды. Эти данные я указаны в файле ~/.my.cnf.
| |
− | [client]
| |
− | user=root
| |
− | password='RzDXcVUmIzwxaNBTN'
| |
− |
| |
− |
| |
− | Мы сделали полный архив всего mysql сервера. В таком виде данные не консистентны, так как они могли меняться во время архивации. Если восстановить их как есть, сервер mysql не запустится. Будет ругаться на поврежденные данные. Чтобы восстановить целостность данных, необходимо выполнить еще одну команду:
| |
− | # xtrabackup --prepare --target-dir=/root/backupdb/full
| |
− | После этого бэкап будет полностью работоспособен и готов к восстановлению. Обычно эту команду выполняют сразу же после бэкапа, но это не всегда возможно. К примеру, если захотим его сразу же сжать:
| |
− | # xtrabackup --backup --compress --target-dir=/root/backupdb/full
| |
− | В таком случае его сначала нужно будет распаковать, а потом подготовить. Делать это не обязательно сразу. Можно хранить бэкапы не подготовленными, а готовить только перед восстановлением, если это случится. Распаковывается бэкап следующим образом:
| |
− | # xtrabackup --decompress --target-dir=/root/backupdb/full
| |
− |
| |
− | Для того, чтобы команда decompress отработала без ошибки:
| |
− | sh: qpress: command not found
| |
− | cat: write error: Broken pipe
| |
− | Error: decrypt and decompress thread 0 failed.
| |
− | Необходимо установить пакет qpress.
| |
− |
| |
− |
| |
− | Большого смысла использовать ключи compress и decompress нет. Можно сделать полный бэкап, подготовить его, а потом сжать тем же gzip:
| |
− | # tar -czvf /root/backupdb/full.tar.gz -C /root/backupdb full
| |
− |
| |
− | На выходе получится тот же архив, только сжат лучше и нет необходимости ставить дополнительный софт. Gzip и tar обычно есть во всех дистрибутивах. К тому же архив в виде единого файла проще и быстрее передать на сервер бэкапов и там хранить.
| |
− |
| |
− |
| |
− | Пример скрипта для автоматизации процесса:
| |
− | #!/bin/bash
| |
− |
| |
− | DATA=`date +%Y-%m-%d`
| |
− |
| |
− | mkdir -p /root/backupdb/$DATA
| |
− | xtrabackup --backup --target-dir=/root/backupdb/$DATA/full
| |
− | xtrabackup --prepare --target-dir=/root/backupdb/$DATA/full
| |
− | tar -czvf /root/backupdb/$DATA/full.tar.gz -C /root/backupdb/$DATA/full
| |
− | rm -rf /root/backupdb/$DATA/full
| |
− | При выполнении этого скрипта раз в день, будем иметь отдельные папки с именем в виде даты, а внутри полный бэкап. Дальше мы в эти же папки будем класть инкрементные бэкапы.
| |
− |
| |
− |
| |
− | '''Инкрементный бэкап Mysql'''
| |
− |
| |
− | Основное удобство XtraBackup как раз в простых, быстрых и удобных инкрементных бэкапах для mysql. Допустим, по примеру выше, мы сделали полный бэкап, он должен быть не сжатый. Теперь на основе этого полного бэкапа, можно сделать инкрементный, где будут только изменения со времени полного бэкапа:
| |
− | # xtrabackup --backup --target-dir=/root/backupdb/inc1 --incremental-basedir=/root/backupdb/full
| |
− |
| |
− | Можно проверить, что конкретно в себя включает полный бэкап, а что инкремент. В директории с бэкапами есть файл xtrabackup_checkpoints примерно следующего содержания.
| |
− | backup_type = full-backuped
| |
− | from_lsn = 0
| |
− | to_lsn = 17687056
| |
− | last_lsn = 17687065
| |
− | compact = 0
| |
− | recover_binlog_info = 1
| |
− | flushed_lsn = 17687065
| |
− | LSN - log sequence number. Это регистрационные номера транзакций. В данном случае полный бэкап начинается с нулевой транзакции и заканчивается 17687056.<br/>
| |
− | Теперь смотрим этот же файл в директории inc1.
| |
− | backup_type = incremental
| |
− | from_lsn = 17687056
| |
− | to_lsn = 17710039
| |
− | last_lsn = 17710048
| |
− | compact = 0
| |
− | recover_binlog_info = 1
| |
− | flushed_lsn = 17710048
| |
− | Инкрементный бэкап базы начался с той транзакции, на которой закончился полный. Следующий инкрементный архив может быть создан опять на базе полного, либо уже инкрементного. То есть либо так:
| |
− | # xtrabackup --backup --target-dir=/root/backupdb/inc2 --incremental-basedir=/root/backupdb/full
| |
− | либо так:
| |
− | # xtrabackup --backup --target-dir=/root/backupdb/inc2 --incremental-basedir=/root/backupdb/inc1
| |
− |
| |
− |
| |
− | Пример скрипта для автоматизации процесса:
| |
− | #!/bin/bash
| |
− |
| |
− | DATA1=`date +%Y-%m-%d`
| |
− | DATA2=`date +%H-%M-%S`
| |
− |
| |
− | xtrabackup --backup --target-dir=/root/backupdb/$DATA1/inc-$DATA2 --incremental-basedir=/root/backupdb/$DATA1/full
| |
− |
| |
− |
| |
− | '''Восстановление из бэкапа'''
| |
− |
| |
− |
| |
− | Теперь восстановим данные из сделанного бэкапа. Если это тот же сервер, то все очень просто. Достаточно подготовить бэкап с помощью ключа prepare, как показано выше и заменить содержимое рабочей директории mysql на то, что хранится в архиве.
| |
− | # systemctl stop mysqld && rm -rf /var/lib/mysql/*
| |
− | # xtrabackup --copy-back --target-dir=/root/backupdb/full
| |
− | # chown -R mysql:mysql /var/lib/mysql
| |
− | # systemctl start mysqld
| |
− |
| |
− | Остановил mysql сервер и удалил все из ее рабочей директории.
| |
− | Восстановил данные из архивной копии xtrabackup. По факту он просто скопировал данные в рабочую директорию mysql сервера.
| |
− | Назначил пользователя mysql владельцем рабочей директории и всего ее содержимого.
| |
− | Запустил mysql сервер с восстановленными данными.
| |
− | После запуска mysql сервера проверяйте лог /var/log/mysql/error.log на предмет ошибок. Если увидите там такие ошибки:
| |
− |
| |
− | [ERROR] InnoDB: Page [page id: space=14, page number=4] log sequence number 17744745 is in the future! Current system log sequence number 9160744.
| |
− | Значит забыли выполнить подготовку архива перед восстановлением. Я частенько это забываю и расстраиваюсь, когда вижу ошибки. В общем случае ошибок после восстановления быть не должно.
| |
− |
| |
− | Если будете восстанавливать базу на другой сервер, то последовательность действий будет следующая. Подключаем репозиторий percona.
| |
− |
| |
− | # yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
| |
− | Ставим mysql server и xtrabackup нужной версии.
| |
− |
| |
− | # yum install Percona-Server-server-57 percona-xtrabackup-24
| |
− | Копируем на новый сервер архив сервера баз данных.
| |
− |
| |
− | # scp root@10.20.1.5:/root/backupdb/full.tar.gz ~
| |
− | Распаковываем его:
| |
− |
| |
− | # tar xzvf full.tar.gz
| |
− | Восстанавливаем данные и запускаем mysql сервер.
| |
− |
| |
− | # xtrabackup --copy-back --target-dir=~/full
| |
− | # chown -R mysql:mysql /var/lib/mysql
| |
− | # systemctl start mysqld
| |
− | Заходим в консоль mysql и проверяем список баз и пользователей.
| |
− |
| |
− | # mysql -u root -p
| |
− | mysql> show databases;
| |
− | mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;
| |
− | Восстановление mysql баз из бэкапа
| |
− |
| |
− | Все на месте, как и на исходном сервере.
| |
− |
| |
− | Это я показал восстановление из полного бэкапа. Теперь показываю, как восстановиться из инкрементной копии. Для начала нам надо подготовить полную копию для накатывания на нее инкремента.
| |
− |
| |
− | # xtrabackup --prepare --apply-log-only --target-dir=/root/backupdb/full
| |
− | Теперь добавляем туда данные из инкрементного бэкапа.
| |
− |
| |
− | # xtrabackup --prepare --apply-log-only --target-dir=/root/backupdb/full --incremental-dir=/root/backupdb/inc1
| |
− | И так для всех остальных инкрементных копий, если у вас из них выстроена цепочка. Контролировать состояние полного архива и сопоставлять с инкрементами можно по содержимому файлов xtrabackup_checkpoints. После того, как восстановили все инкрементные архивы, на последнем из них не нужно использовать ключ apply-log-only. Так же он не нужен, если у вас только одна инкрементная копия. Завершающий этап подготовки полной копии должен быть без него.
| |
− |
| |
− | После того, как восстановили всю цепочку инкрементов, с архивом можно работать как с обычным полным бэкапом.
| |
− |
| |
− | Бэкап отдельной таблицы или базы
| |
− | Не всегда нужны архивные копии всего mysql сервера. Иногда достаточно отдельной базы данных или даже таблицы. Xtrabackup позволяет это сделать. Архивируем только одну базу данных sitemanager.
| |
− |
| |
− | Для того, чтобы этот способ бэкапа отдельной базы mysql работал, необходим параметр innodb_file_per_table в настройка сервера баз данных.
| |
− | # xtrabackup --backup --databases "sitemanager" --target-dir=/root/backupdb/sitemanager
| |
− | Восстановление отдельной базы mysql будет выглядеть так.
| |
− |
| |
− | # xtrabackup --prepare --databases "sitemanager" --target-dir=/root/backupdb/sitemanager
| |
− | # systemctl stop mysqld
| |
− | # mkdir -p /var/lib/mysql.old/sitemanager
| |
− | # mv /var/lib/mysql/sitemanager /var/lib/mysql.old
| |
− | # mv /root/backupdb/sitemanager/sitemanager /var/lib/mysql
| |
− | # chown -R mysql. /var/lib/mysql
| |
− | # systemctl start mysql
| |
− | Мы по сути просто скопировали исходные файлы базы из бэкапа в рабочий каталог, предварительно сохранив предыдущую версию базы на всякий случай.
| |
− |
| |
− | Теперь попробуем из полного бэкапа базы восстановить только одну таблицу. В моем примере я на работающем сервере сделаю восстановление существующей таблицы из полного бэкапа. Если будете восстанавливать на другой сервер, то перед этим вам нужно будет воссоздать исходную структуру таблицы перед тем, как будете восстанавливать данные по предложенному методу.
| |
− |
| |
− | Готовим бэкап к восстановлению:
| |
− |
| |
− | # xtrabackup --prepare --export --target-dir=/root/backupdb/full
| |
− | Идем в консоль mysql и выбираем там таблицу для восстановления. В моем примере это будет таблица b_user_access из базы sitemanager. Смотрим, заполнена ли таблица данными.
| |
− |
| |
− | mysql> SELECT COUNT(*) FROM sitemanager.b_user_access;
| |
− | +----------+
| |
− | | COUNT(*) |
| |
− | +----------+
| |
− | | 6 |
| |
− | +----------+
| |
− | 1 row in set (0.00 sec)
| |
− | Делаем DISCARD этой таблицы.
| |
− |
| |
− | mysql> ALTER TABLE sitemanager.b_user_access DISCARD TABLESPACE;
| |
− | Query OK, 0 rows affected (0.00 sec)
| |
− | Discard означает, что будет удален ibd файл таблицы. Теперь нам его нужно скопировать из бэкапа и назначить права для mysql.
| |
− |
| |
− | # cp /root/backupdb/full/sitemanager/b_user_access.* /var/lib/mysql/sitemanager
| |
− | # chown mysql. /var/lib/mysql/sitemanager/b_user_access.*
| |
− | Возвращаемся в консоль mysql и импортируем данные.
| |
− |
| |
− | mysql> ALTER TABLE sitemanager.b_user_access IMPORT TABLESPACE;
| |
− | Query OK, 0 rows affected (0.03 sec)
| |
− | Смотрим, что получилось.
| |
− |
| |
− | > SELECT COUNT(*) FROM sitemanager.b_user_access;
| |
− | +----------+
| |
− | | COUNT(*) |
| |
− | +----------+
| |
− | | 6 |
| |
− | +----------+
| |
− | 1 row in set (0.00 sec)
| |
− | Данные восстановлены. Вернулись те же 6 строк, что и были до этого.
| |
− |
| |
− | Бэкап и восстановление mysql с помощью mysqldump
| |
− |
| |
− |
| |
− | Теперь просто для справки приведу примеры бэкапа и восстановления баз данных mysql с помощью mysqldump. Для небольших баз этого инструмента хватает за глаза и использовать что-то другое не имеет смысла. Преимущество xtrabackup в скорости работы и в возможности без проблем сделать инкрементный бэкап. Если он вам не нужен и база не большая, достаточно будет старого доброго mysqldump.
| |
− |
| |
− | Бэкап всех баз mysql сервера с его помощью:
| |
− |
| |
− | # /usr/bin/mysqldump -uroot -hlocalhost -p'password' --all-databases > /root/backupdb/all.sql
| |
− | Можно сразу же сжимать его.
| |
− |
| |
− | # /usr/bin/mysqldump -uroot -hlocalhost -p'password' --all-databases | /usr/bin/gzip -c > /root/backupdb/`date "+%Y-%m-%d"`sql.gz
| |
− | Бэкап конкретной базы данных.
| |
− |
| |
− | /usr/bin/mysqldump sitemanager -uroot -p'password' | /usr/bin/gzip -c > /root/backupdb/sitemanager_`date "+%Y-%m-%d"`sql.gz
| |
− | Мне чаще всего мешают в дампе команды на создание базы данных - CREATE DATABASE, поэтому я их убираю ключом no-create-db.
| |
− |
| |
− | /usr/bin/mysqldump --no-create-db sitemanager -uroot -p'password' | /usr/bin/gzip -c > /root/backupdb/sitemanager_`date "+%Y-%m-%d"`sql.gz
| |
− | Для того, чтобы восстановить базу данных из дампа, можно воспользоваться следующими командами. Выполняются из консоли mysql.
| |
− |
| |
− | # mysql -uroot -p
| |
− | mysql> use sitemanager;
| |
− | mysql> source /root/backupdb/sitemanager.sql;
| |
− | Если дамп без команды на создание базы данных и ее нет у вас на сервере, то не забудьте ее перед этим создать. Так же восстановить базу данных из дампа можно следующим образом.
| |
− |
| |
− | mysql> use sitemanager;
| |
− | mysql> \. /root/backupdb/sitemanager.sql
| |
− | Вот простенький скрипт, который позволяет забэкапить все базы данных сервера, при этом бэкап каждой базы будет в отдельном файле. Это удобнее, чем все базы единым файлом. Оттуда потом трудно доставать конкретную базу.
| |
− |
| |
− | #!/bin/bash
| |
− |
| |
− | for i in `mysql -uroot -p'password' -e'show databases;' | grep -v information_schema | grep -v Database`;
| |
− | do
| |
− | /usr/bin/mysqldump -uroot -p'password' $i | /usr/bin/gzip -c > /root/backupdb/`date +%Y-%m-%d`-$i.sql.gz;
| |
− | done
| |
− | Так же могу порекомендовать вот этот скрипт для бэкапа - https://github.com/adegtyarev/mysqlbackup. Описывать его не буду, по комментариям в скрипте понятен его функционал.
| |
− |
| |
− | Если вам нужно из полного бэкапа mysql восстановить отдельную таблицу, то ее можно выделить из полного дампа через обычный awk примерно вот так.
| |
− |
| |
− | # cat sitemanager.sql | /usr/bin/awk '/CREATE TABLE `b_catalog_discount`/,/UNLOCK TABLES/' > /tmp/b_catalog_discount.sql
| |
− | Дальше через source можно восстановить данные из этого дампа отдельной таблицы.
| |
− |
| |
− | Иногда бывает полезно сделать не просто полный backup базы данных, а разбить его сразу на таблицы. Тут поможет следующий скрипт.
| |
− |
| |
− | #!/bin/bash
| |
− |
| |
− | USER='root'
| |
− | PASS='R(zDXcVUmI[zwx%aNBTN'
| |
− |
| |
− | MYSQL="mysql --user=$USER --password=$PASS --skip-column-names";
| |
− | DIR="/root/backupdb"
| |
− |
| |
− | for s in mysql `$MYSQL -e "SHOW DATABASES"`;
| |
− | do
| |
− | mkdir $DIR/$s;
| |
− | for t in `$MYSQL -e "SHOW TABLES FROM $s"`;
| |
− | do
| |
− | /usr/bin/mysqldump --user="$USER" --password="$PASS" --opt $s $t | /usr/bin/gzip -c > $DIR/$s/$t.sql.gz;
| |
− | done
| |
− | done
| |
− | В таком варианте он сделает потабличный бэкап всех баз данных. Если вам не нужны все базы, то в цикле можете вместо предложенного перебора всех существующих баз указать одну конкретную.
| |
− |
| |
− | for s in mysql sitemanager;
| |
− | Восстановить потом всю базу из такого потабличного бэкапа можно таким образом.
| |
− |
| |
− | #!/bin/bash
| |
− | #
| |
− |
| |
− | DB=sitemanager;
| |
− | USER='root'
| |
− | PASS='R(zDXcVUmI[zwx%aNBTN'
| |
− | DIR="/root/backupdb/sitemanager"
| |
− |
| |
− | for s in `ls -1 $DIR`;
| |
− | do
| |
− | echo "--> $s restoring... ";
| |
− | zcat $DIR/$s | /usr/bin/mysql --user=$USER --password=$PASS $DB;
| |
− | done
| |
− | При использовании пароля в открытом виде в mysql или mysqldump, в консоль постоянно сыпятся предупреждения.
| |
− |
| |
− | mysql: [Warning] Using a password on the command line interface can be insecure.
| |
− | Чтобы их не было, перенесите, как я показывал выше, пароль в отдельный файл ~/.my.cnf, а из скрипта уберите авторизацию вообще.
| |
− |
| |
− | На этом, пожалуй, насчет бэкапа баз mysql сервера все. Поделился основными своими наработками.
| |
− |
| |
− | Заключение
| |
− | Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!
| |
− | Бэкап mysql баз во многом творческий процесс. Много различных инструментов, подходов, скриптов. Каждый бэкапит так, как ему больше нравится. Чаще всего мне хватает обычного mysqldump. Сложности возникают там, где база более ли менее большая и надо архивировать часто.
| |
− |
| |
− | К примеру, если работает интернет магазин или crm, делать бэкап раз в сутки по ночам не вариант. Надо намного чаще. Хотя бы каждые час-два. Полные дампы снимать не рационально в этом случае. Это и долго, и объем большой. Нужны инкрементные бэкапы.
| |
− |
| |
− |
| |
− | позаимствовано здесь<br/>
| |
− | https://serveradmin.ru/polnyj-i-inkrementnyj-backup-mysql/?utm_source=feedburner&utm_medium=email&utm_campaign=Feed%3A+serveradmin_ru+(Системное+администрирование)
| |