11 Резервное копирование данных
Резервное копирование Luxms BI должно включать в себя, но не ограничиваться, следующим перечнем ресурсов:
- Конфигурационные файлы компонентов.
- Данные БД.
Периодичность снятия резервных копий определяется владельцем инсталляции Luxms BI в соответствии с внутренней политикой или отраслевыми стандартами. Мы можем только рекомендовать параметры резервирования.
Настройка резервного копирования конфигурации
Конфигурация компонентов Luxms BI консолидирована в папке /opt/luxmsbi/conf
файловой системы. Изменение конфигурации компонентов производится только в ручном режиме. Установка новых или возврат к старым версиям пакетов включает в себя функционал сохранения конфигурационных файлов.
Мы рекомендуем создание резервных копий конфигурационных файлов не реже одного раза в день. Период хранения резервных копий - не менее 7 дней.
Настройка резервного копирования БД
Настоятельно рекомендуем не хранить резервные копии локально, на той же машине, что и сама база.
Мы рекомендуем создание резервных копий данных БД не реже одного раза в день. Период хранения резервных копий - не менее 7 дней.
Рекомендуем учитывать при утверждении планов резервного копирования следующее:
“Временные затраты на восстановление журналов БД после восстановления резервной копии может быть существенно больше затрат на повторную загрузку данных из первичных источников.”
Настройка разрешений доступа к БД
Оптимальное решение - снятие резервной копии базы данных с внешнего хоста. Для настройки разрешений доступа к кластерной БД, управляемой с помощью Patroni, необходимо:
- На всех хостах кластера (т.к. роль Leader может быть передана любому члену кластера) добавить разрешение для доступа к БД для системы резервного копирования.
Нам требуется внести строчку с IP адресом хоста, который будет участвовать в резервировании, в массив postgresql.pg_hba
:
postgresql:
pgpass: /pgdata/.pgpass
listen: 0.0.0.0:5432
connect_address: "172.16.32.112:5432"
data_dir: /pgdata/data
bin_dir: /usr/pgsql-11/bin/
pg_rewind:
username: postgres
password: "password"
pg_hba:
- local all postgres peer
- host all all 0.0.0.0/0 md5
- host replication replicator 127.0.0.1/32 md5
- host replication replicator 172.16.32.112/32 md5
- host replication replicator 172.16.32.113/32 md5
- host replication replicator 172.16.32.155/32 md5 <--- добавить сюда хост, c которого будут делаться бэкап
replication:
username: replicator
password: "password"
superuser:
username: postgres
password: "password"
- Затем нужно дать команды сервису patroni, чтобы он перезапустил свою службу и обновил измененную конфигурацию на всех узлах кластера. Данные команды подаются на одном из узлов кластера и распространяются на все остальные узлы автоматически:
patronictl -c /opt/patroni/etc/patroni.yml reload db-main
| Cluster | Member | Host | Role | State | TL | Lag in MB |
|-------------|---------------------|---------------|--------|---------|----|-----------|
| db-main | bi-pg1 | 172.16.32.112 | Leader | running | 1 | |
| db-main | bi-pg2 | 172.16.32.113 | | running | 1 | 0 |
Are you sure you want to reload members bi-pg1, bi-pg2? [y/N]: y
Reload request received for member bi-pg1 and will be processed within 10 seconds
Reload request received for member bi-pg2 and will be processed within 10 seconds
- После обновления конфигурации перезапустим сервис patroni вместе с PostgreSQL:
[root@bi-pg1 ~]# patronictl -c /opt/patroni/etc/patroni.yml restart db-main
| Cluster | Member | Host | Role | State | TL | Lag in MB |
|-------------|---------------------|---------------|--------|---------|----|-----------|
| db-main | bi-pg1 | 172.16.32.112 | Leader | running | 1 | |
| db-main | bi-pg2 | 172.16.32.113 | | running | 1 | 0 |
When should the restart take place (e.g. 2021-03-15T14:38) [now]:
Are you sure you want to restart members bi-pg1, bi-pg2? [y/N]: y
Restart if the PostgreSQL version is less than provided (e.g. 9.5.2) []:
Success: restart on member bi-pg1
Success: restart on member bi-pg2
Снятие резервной копии
Для получения резервной копии БД необходимо выполнить команду:
pg_basebackup -d postgresql://replicator:password@172.16.32.113 \
--checkpoint=fast \
-D /backup \
-P -Ft -z -Xs
По окончании снятия резервной копии, получим следующие файлы:
[root@localhost backup]# ls -l
total 11848
-rw-------. 1 root root 12110482 Mar 15 15:50 base.tar.gz
-rw-------. 1 root root 18318 Mar 15 15:50 pg_wal.tar.gz
Используются следующие ключи:
-D
- директория, куда будут складываться бэкапы (должна быть пустой).-F
- формат выходного файла, в нашем случае tar архив.-z
- включаем gzip сжатие.-Xs
- передавать журнал предзаписи в процессе создания резервной копии.
Рекомендация по безопасности: вместо явного указания в строке подключения имени и пароля пользователя используйте параметр -U
и ввод пароля в командной строке.
Полученные файлы должны перемещаться на устройства долговременного хранения.
Команда pg_basebackup
рекомендована для быстрого создания резервных копий.
Вместо pg_basebackup
можно использовать команды pg_dump/pg_restore
, но они работают значительно медленнее.
Пример создания дампа базы:
pg_dump -d postgresql://bi:password@192.168.0.10/mi -Fc -C -c -f /tmp/mi.sqlc
Пример восстановления базы из дампа:
sudo -iu postgres pg_restore -C -d postgres /tmp/mi.sqlc
Восстановление данных из резервной копии
Останавливаем весь кластер PostgreSQL. Нужно выполнить на каждом хосте:
systemctl stop patroni
Чтобы убедиться, что все хосты остановлены выполняем команду на всех хостах кластера:
[root@bi-pg1 ~]# patronictl -c /opt/patroni/etc/patroni.yml list
Cluster | Member | Host | Role | State | TL | Lag in MB |
---|---|---|---|---|---|---|
db-main | bi-pg1 | 172.16.32.112 | stopped | 0 |
Копируем данные резервной копии на один из хостов кластера, на котором будет поднята роль Leader. И выполняем на нём следующие команды:
rm -rf /pgdata/data/*
tar -xzf base.tar.gz -C /pgdata/data/
tar -xzf pg_wal.tar.gz -C /pgdata/data/pg_wal/
Пробуем запустить хост с базой:
systemctl start patroni
Проверяем на ошибки лог файлы: /pgdata/data/log/postgredsql-*.log
.
При удачном восстановлении в лог файлах будут такие строчки:
2021-03-15 15:30:03.727 MSK [14685] LOG: archive recovery complete
2021-03-15 15:30:03.732 MSK [14682] LOG: database system is ready to accept connections
Если всё в порядке, то запускаем другие узлы кластера, через systemctl start patroni.
Проверяем, все ли работает правильно:
patronictl -c /opt/patroni/etc/patroni.yml list
| Cluster | Member | Host | Role | State | TL | Lag in MB |
|-------------|---------------------|---------------|--------|---------|----|-----------|
| db-main | bi-pg1 | 172.16.32.112 | Leader | running | 4 | |
| db-main | bi-pg2 | 172.16.32.113 | | running | 3 | 109 |
Видно, что после восстановления у нас появился Lag in 109MB, для того, чтобы реплика не расходилась с мастером, её нужно реинициализировать. После чего она догонит мастера.
patronictl -c /opt/patroni/etc/patroni.yml reinit db-main
| Cluster | Member | Host | Role | State | TL | Lag in MB |
|-------------|---------------------|---------------|--------|---------|----|-----------|
| rmr-db-main | rzd-skimcss-bi-pg-1 | 172.16.32.112 | Leader | running | 4 | |
| rmr-db-main | rzd-skimcss-bi-pg-2 | 172.16.32.113 | | running | 3 | 109 |
Which member do you want to reinitialize [bi-pg1, bi-pg-]? []: bi-pg2
Are you sure you want to reinitialize members bi-pg2? [y/N]: y
Success: reinitialize for member bi-pg2
Советы по проведению работ без остановки сервисов
Для восстановления из резервных копий требуется завершить все активные соединения в СУБД. Обычно для этого останавливают все сервисы, что приводит к отказу в обслуживании. Однако есть способы выполнять работы без останвки сервисов.
Сначала нужно зайти в базу как суперпользователь:
sudo -iu postgres psql -d mi
Затем нужно отключить всех пользователей от базы:
-- 1. запрещаем новые соединения в базу mi
UPDATE pg_database SET datallowconn=false WHERE datname='mi';
-- 2. обрываем все существующие соединения в базу, кроме нашего.
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'mi' AND pid <> pg_backend_pid();
-- 3. переименовываем базу mi
alter database mi rename to mi_backup;
На этом шаге нужно восстановить базу mi из резервной копии. Сессиию psql
можно не закрывать, но если закрыли, то новое соединение можно будет открыть запустив psql
повторно. А далее, снова разрешить соединения для пользователей:
-- 4. разрешаем новые соединения в базу mi
UPDATE pg_database SET datallowconn=true WHERE datname='mi';
-- 5. включаем поддержку LPE
ALTER DATABASE mi SET plv8.start_proc = '"lpe"."init"';