Percona Server и Percona XtraBackup в docker-контейнере
Jul 31, 2017 10:00 · 856 words · 5 minute read
Со стремительным ростом популярности docker-контейнеров уже никого не удивить, например, запуском Percona Server в docker’е. Однако на просторах Интернета не так уж много подробных инструкций о том, как делать резервные копии (и восстанавливаться из них), если ваш MySQL-сервер запущен в docker-контейнере.
Давайте разберемся с запуском Percona Server в docker’е и рассмотрим вариант создания бекапов с помощью утилиты Percona XtraBackup!
Итак, нам понадобятся два docker-контейнера — один непосредственно для MySQL-сервера, второй — для создания резервных копий. В качестве MySQL-сервера будем использовать Percona Server 5.7, контейнеры будем собирать самостоятельно — это несложно.
Создадим каталог, в котором будет находиться все необходимое для основного контейнера (назовем его percona):
mkdir /percona
В данном каталоге у нас будут находится инструкции по сборке контейнера (Dockerfile), конфигурационный файл для MySQL-сервера (my.cnf
), файл docker-compose.yml
для запуска контейнера (не люблю вводить длиннющие команды вида docker run ...
) и файл с переменными окружения, которые будут использоваться при запуске контейнера (.env
).
Давайте рассмотрим содержимое данных файлов, Dockerfile выглядит так:
FROM percona:5.7
RUN chown -R mysql:mysql /var/lib/mysql/
ADD my.cnf /etc/mysql/conf.d/my.cnf
CMD ["mysqld"]
EXPOSE 3306
Содержимое файла с настройками MySQL-сервера в моем случае такое (разумеется, для вашего случая подберите эти параметры индивидуально):
[client]
socket = /var/run/mysqld/mysqld.sock
[mysqld]
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
user = mysql
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /var/lib/mysql-tmp
sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
sysdate-is-now = 0
transaction-isolation = REPEATABLE-READ
default-storage-engine = InnoDB
event-scheduler = OFF
performance_schema = 0
collation-server = utf8_general_ci
character-set-server = utf8
### Percona specific general options
expand_fast_index_creation = OFF
userstat = OFF
thread_statistics = OFF
### Connectivity options
port = 3306
max_user_connections = 400
secure-auth = ON
back_log = 2048
skip-name-resolve = 0
max_connect_errors = 1000000
read_only = OFF
bind-address = ::
max_allowed_packet = 16777216
wait_timeout = 14400
max_connections = 500
thread_cache_size = 64
net_write_timeout = 60
net_read_timeout = 30
safe-user-create = 1
interactive_timeout = 14400
### General caches
key_buffer_size = 16777216
query_cache_size = 0
tmp_table_size = 16777216
max_heap_table_size = 16777216
table_open_cache = 8192
query_cache_type = 0
### InnoDB options
innodb_buffer_pool_size = 512M
innodb_open_files = 1024
innodb_flush_method = O_DIRECT
innodb_log_file_size = 64M
innodb_read_io_threads = 4
innodb_file_format = Barracuda
innodb_old_blocks_time = 1000
innodb_autoinc_lock_mode = 2
innodb_io_capacity = 200
innodb_log_buffer_size = 8M
innodb_stats_on_metadata = OFF
innodb_thread_concurrency = 0
innodb_support_xa = ON
innodb_buffer_pool_instances = 1
innodb_concurrency_tickets = 10000
innodb_write_io_threads = 4
innodb = force
innodb_file_per_table = ON
innodb_flush_log_at_trx_commit = 2
### Logging options
general_log_file = /var/log/mysql/mysql_general.log
log-error = /var/log/mysql/mysql_error.log
slow_query_log_file = /var/log/mysql/mysql_slow.log
log-warnings = 1
log-queries-not-using-indexes = ON
long_query_time = 2
log-slow-admin-statements = 1
log-slow-slave-statements = 1
general-log = OFF
slow-query-log = ON
### Percona specific logging options
log_slow_rate_type = session
slow_query_log_use_global_control = log_slow_filter,log_slow_rate_limit,log_slow_verbosity,long_query_time,min_examined_row_limit
log_slow_sp_statements = ON
log_slow_filter = ''
log_slow_verbosity = microtime,query_plan
log_slow_rate_limit = 1
slow_query_log_always_write_time = 10
[mysqld_safe]
log-error = /var/log/mysql/mysql_error.log
Файл с переменными окружения может выглядеть, например, так:
### Data Path for all storage systems.
DATA_SAVE_PATH=/srv
### Percona ############################################################################################################
PERCONA_DATABASE=test_db
PERCONA_USER=testuser
PERCONA_PASSWORD=testpassword
PERCONA_PORT=3306
PERCONA_ROOT_PASSWORD=rootpassword
И, наконец, docker-compose.yml
содержит такие строки:
version: '2'
services:
### Percona Container ########################################
percona:
container_name: percona
image: my-percona-test:latest
environment:
- MYSQL_DATABASE=${PERCONA_DATABASE}
- MYSQL_USER=${PERCONA_USER}
- MYSQL_PASSWORD=${PERCONA_PASSWORD}
- MYSQL_ROOT_PASSWORD=${PERCONA_ROOT_PASSWORD}
volumes:
- ${DATA_SAVE_PATH}/percona:/var/lib/mysql
ports:
- "${PERCONA_PORT}:3306"
Для сборки образа, находясь в каталоге /percona
, запускаем команду:
docker build -t my-percona-test:latest .
После успешной сборки контейнер можно запустить командой:
docker-compose up -d
Приступим к второму docker-контейнеру, с помощью которого мы будем делать резервные копии и восстанавливаться из них. Создадим каталог для него (назовем его xtrabackup
):
mkdir /xtrabackup
В данном каталоге у нас будут находиться инструкции по сборке контейнера (Dockerfile) и два скрипта — один для создания бекапа (make_backup.sh
), второй для восстановления данных (make_backup.sh
).
Содержимое Dockerfile следующее:
FROM percona:5.7
RUN apt-get update && \
apt-get install -y --no-install-suggests pigz percona-xtrabackup-24 && \
rm -rf /var/lib/apt/lists/*
RUN mkdir -p /backups
ADD make_backup.sh /make_backup.sh
ADD restore_backup.sh /restore_backup.sh
VOLUME ["/backups"]
Содержимое скрипта создания бекапа:
BACKUP="/usr/bin/innobackupex"
workdir="/backups/"
OPTIONS="--host=percona --port=3306 --user=root --password=rootpassword"
dump="mysql.tar"
# при распаковке использовать ключ -i, например tar -ixvf backup.tar
$BACKUP $OPTIONS --stream=tar ./ | pigz -p 5 > ${workdir}${dump}.gz
Скрипт для восстановления данных из резервной копии выглядит так:
backupdir="/backups/"
archive="mysql.tar.gz"
mysqldir="/var/lib/mysql/"
cd $mysqldir && rm -rf *
cd $backupdir && tar -ixvf $archive -C $mysqldir
cd $mysqldir && innobackupex --apply-log --ibbackup=xtrabackup ./
chown -R 999:999 $mysqldir
Собираем контейнер (находясь в каталоге с Dokerfile) командой:
docker build -t my-xtrabackup:latest .
После всех проделанных действий для создания резерной копии баз данных достаточно запустить следующую команду:
docker run -it --net=docker_default --link percona:percona --name=xtrabackup -v /srv/percona:/var/lib/mysql -v /srv/backups:/backups --rm my-xtrabackup:latest sh -c 'exec /make_backup.sh'
Даная команда запускает контейнер из собранного нами образа (my-xtrabackup:latest), присваивает ему имя xtrabackup, назначает ему такую же локальную сеть, как и в запущенного ранее контейнера с Percona Server, связывает контейнеры с помощью опции --link
, пробрасывает внутрь контейнера каталоги /srv/percona
и /srv/backups
с хост-машины (в одном находятся БД, второй используется для хранения бекапов) и выполняет скрипт make_backup.sh
. После после выполнения скрипта (когда бекап будет создан) контейнер будет удален, благодаря использованию опции --rm
.
Чтобы восстановить данные из резервной копии, следует использовать такую команду (контейнер с Percona Server должен быть выключен во избежание возможных конфликтов):
docker run -it --name=xtrabackup -v /srv/percona:/var/lib/mysql -v /srv/backups:/backups --rm my-xtrabackup:latest sh -c 'exec /restore_backup.sh'
Данная команда очень похожа на предыдущую, разница лишь в выполняемом скрипте и в отсутствии параметров --net=docker_default
--link percona:percona
— они нам не нужны, так как контейнер с MySQL-сервером выключен.