3.5.1. СУБД PostgreSQL

3.5.1.1. Полная копия базы данных

Примеры конфигурации будут приведены для базы данных PostgreSQL.

3.5.1.1.1. Создание копии

Войдите на сервер с базой данных и через эмулятор терминала выполните команду

export PGPASSWORD=********
pg_dump --format=c --host=localhost --username=sphere_user sphere_db > sphere_db.bk

«sphere_user» - Логин к базе данных, который вы указати владельцем базы данных при ее создании в кластере СУБД. Переменная PGPASSWORD задает пароль по умолчанию при операциях СУБД. Если ее не задать, то вы увидите запрос на ввод пароля в эмуляторе терминала.

После выполнения команды, будет создан файл «sphere_db.bk» в каталоге, в котором вы находитесь. Скопируйте его за пределы сервера на другую машину или в файловое хранилище.

3.5.1.1.2. Восстановления из копии

Пересоздайте базу данных, выполнив вход в эмулятор терминала под учетной записью супер-пользователя базы данных (по умолчанию «postgres»)

su postgres
psql

drop database sphere_db;  # Если база данных существует
create database sphere_db;

alter database sphere_db owner to sphere_user;
alter database sphere_db set timezone = 'UTC';
alter database sphere_db set default_transaction_isolation = 'read committed';
alter database sphere_db set client_encoding = 'UTF8';

После пересоздания, вы получите пустую базу данных. Развернем в нее сохраненную ранее версию

export PGPASSWORD=********
pg_restore --dbname=sphere_db --format=c --host=localhost --username=sphere_user < sphere_db.bk

3.5.1.1.3. Автоматизация

Чтобы создавать копии по расписанию, можно примонтировать в сервер внешний файловый ресурс, создать файл с набором команд и выполнять его через cron по расписанию.

echo "
    export PGPASSWORD=********
    pg_dump --format=c --host=localhost --username=sphere_user sphere_db > /mnt/bk/postgres/`date +"%Y-%m-%d_%H-%M"`_sphere_db.bk
" > ~/backup_me
chmod 755 ~/backup_me

cron -e
0 1 * * * /home/some_user/backup_me

3.5.1.2. Инкрементое копирование данных

Это более сложный способ и время восстановления будет существенно больше. Однако, он позволит получить наименьшие потери данных, связанные с отставанием времени создания последней копии от реальных данных на момент сбоя. Приступим.

3.5.1.2.1. Настройка

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

sudo mkdir /opt/wal/
sudo chown postgres:postgres /opt/wal/

sudo mkdir /mnt/bk/postgresql/
sudo mkdir /mnt/bk/postgresql/wals

su postgres
cron -e
*/10 * * * * rsync --verbose --recursive --remove-source-files /opt/wal /mnt/bk/postgresql

Внесем изменения в конфигурационный файл СУБД, переведя его в режим архивирования xlog-ов. Откроем файл настроек и внесем изменения в обозначенные опции

sudo nano /etc/postgresql/9.4/main/postgresql.conf

wal_level = archive
archive_mode = on
archive_command = 'test ! -f /opt/wal/%f && cp %p /opt/wal/%f'
archive_timeout = 1800  # если лог не заполнился за 30 минут, архивировуем его принудительно

Создадим в домашней директории пользователя postgres скрипты для создания базовой копии

su postgres
cd

echo " SELECT pg_start_backup(current_date::varchar); " > start_backup.sql

echo " SELECT pg_stop_backup(); " > stop_backup.sql

echo "
    psql -f start_backup.sql

    tar \
        --exclude=/var/lib/postgresql/9.4/main/pg_xlog \
        --exclude=/var/lib/postgresql/9.4/main/postmaster.opts \
        --exclude=/var/lib/postgresql/9.4/main/postmaster.pid \
        -cvzf base_backup.tar /var/lib/postgresql/9.4/

    psql -f stop_backup.sql
" > create_base_backup

chmod 755 create_base_backup

3.5.1.2.2. Создание базовой копии

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

su postgres
cd
./create_base_backup

После этого, в домашней директории будет создан файл «base_backup.tar». Перенесите его на другой сервер. Эту операцию можно делать довольно редко. Чем чаще вы обновляете состояние базовой копии, тем меньшее количество файлов журнала серверу нужно будет применить поверх базовой копии и тем быстрее будет процесс восстановления. К тому же, после обновления базовой копии, старые файлы журнала, которые были созданы до базовой копии, вам уже не нужны и вы можете их удалить, сэкономив место. При активной работе, список файлов журнала, сгенерированный в течении недели или 2-х может быть по размеру больше чем сама базовая копия.

3.5.1.2.3. Восстановление данных

Итак, случилось страшное и вам нужно восстановить данные. После восстановлении предварительно созданной копии виртуальной машины, входим в эмулятор терминала. Останавливаем сервер базы данных, удаляем каталог с данными, распаковываем базовую копию. Данных действий достаточно, чтобы после запуска, получить состояние базы данных на момент создания базовой копии.

service postgresql stop
rm -r /var/lib/postgresql/9.4/

su postgres
cd

cp /mnt/bk/postgresql/base_backup.tar ~/base_backup.tar
tar -xvzf base_backup.tar -C /

mkdir /var/lib/postgresql/9.4/main/pg_xlog
chmod 700 /var/lib/postgresql/9.4/main/pg_xlog

Чтобы после запуска, сервер начал восстанавливать данные из журналов, нужно ему сообщить о том, где он может их найти. Создаем файл с информацией о восстановлении. Данные лога будем забирать напрямую из примонтированного файлового ресурса. Запускаем сервер. Чтобы убедиться, что восстановление идет и получить информацию о том, какие файлы уже обработанны, смотрим в лог

echo "
restore_command = 'cp /mnt/bk/postgresql/wal/%f %p'
" > ~/9.4/main/recovery.conf

service postgresql start

tail /var/log/postgresql/postgresql-9.4-main.log