Получил "в наследство" систему, в которой в качестве СУБД используется PostgreSQL на CentOS. Резервное копирование реализовано с помощью PostgreSQL Backup, которая запускает ночью задание, делает бекап двух баз и отправляет на ftp.
Решил заморочиться отказоустойчивостью.
Просто опишу вкратце что и в какой последовательности делалось по результатам изучения интернета и документации (спасибо postgrespro.ru), то есть не буду тут выкладывать много теории о том как работает PostgreSQL, что такое WAL файлы и т.д.
0. УСТАНОВКА PostgreSQL
инструкция по установке PostgreSQL:
команды после # выполняются в системной консоли от пользователя root,
команды после postgres=# - в консоли СУБД от пользователя postgres.
Установить репозиторий и пакеты из него:
# sudo rpm -ivh http://1c.postgrespro.ru/keys/postgrespro-1c-centos96.noarch.rpm && sudo yum makecache && sudo yum install postgresql-pro-1c-9.6
Установить системную локаль в ru_RU.utf8:
# localectl set-locale LANG=ru_RU.utf8
Инициализировать кластер СУБД:
# service postgresql-9.6 initdb
Для подключения к базе по сети:
редактируем /var/lib/pgsql/9.6/data/pg_hba.conf :
(если не знаете как редактировать файл, то проще всего установить, если не установлена, программу похожую на far: # yum -y install mc и запустите # mc)
Закомментировать строку
host all all 0.0.0.0/0 ident
Добавить строку
host all all <client host ip> md5
где <client host ip> заменить на адрес машины (или подсети), из которой будете подключаться (ip сервера 1С Предприятие 8). Обязательно с маской
подсети, например: 192.168.1.11/32.
Запустить базу:
# service postgresql-9.6 start
Задать пароль пользователю СУБД postgres:
# sudo -u postgres psql
postgres=# alter user postgres password 'yoursecretpassword';\q
Разрешить на фаерволе подключения к СУБД:
# firewall-cmd --zone=public --add-port=5432/tcp --permanent ; firewall-cmd --reload
Теперь сервер базы данных доступен, можно на сервере 1С предприятия создавать базы и т.д.
1. ПОТОКОВАЯ РЕПЛИКАЦИЯ
Итак, теперь у нас есть работающая (боевая) СУБД PstgreSQL. Назовем ее MASTER, а сервер, на который будем реплицировать базу SLAVE.
Для обеспечения работы потоковой репликации на MASTER-е редактируем файл /var/lib/pgsql/9.6/data/postgresql.conf, добавляем следующие строки:
wal_level = hot_standby (прочитайте про этот параметр в интернете и про WAL файлы в принципе)
max_wal_senders = 4 (количество планируемых слейвов, число 4 - на всякий случай )
max_replication_slots = 4 ( здесь 4 - это количество replication slot'ов - равен максимальному количеству реплик)
hot_standby = on (разрешить запросы на реплике)
hot_standby_feedback = on (Определяет, будет ли сервер горячего резерва сообщать ведущему или вышестоящему резервному о запросах, которые он выполняет в данный момент)
Параметры hot_standby = on и hot_standby_feedback = on на MASTER-е не играют никакой роли, но мы их определим уже сейчас, так как на одном из следующих этапов при выстраивании потоковой репликации мы скопируем по сути вес data каталог с MASTER-а на SLAVE, в том числе и этот конфигурационный файл, так что установим эти параметры уже сейчас.
На MASTER-е создаем пользователя repluser под которым SLAVE будет подключаться к MASTER-у и таскать WAL из слотов репликации.
# sudo -u postgres psql
postgres=# CREATE ROLE repluser WITH REPLICATION PASSWORD 'супер-секретный-пароль' LOGIN;\q
На MASTER-е редактируем /var/lib/pgsql/9.6/data/pg_hba.conf, то есть, обеспечиваем, чтобы в этом файле были такие строчки
host all all <ip_MASTER>/32 md5
host all all <ip_SLAVE>/32 md5
host all all <ip_Сервера1С>/32 md5 (эта строчка уже есть, создана на этапе 0.)
host replication repluser <ip_MASTER>/32 md5
host replication repluser <ip_SLAVE>/32 md5 (разрешаем SLAVE-у подключаться к MASTER-у под пользователем repluser для осуществления потоковой репликации)
По сути, выше описанными разрешениями в файле pg_hba.conf мы разрешаем MASTER-у и SLAVE-у взаимно обращаться друг к другу, поэтому, как и в случае с файлом postgresql.conf, файл pg_hba.conf на обоих серверах может совпадать. Соответственно, в дальнейшем, при необходимости, MASTER может стать SLAVE-ом.
рестарт базы
# service postgresql-9.6 stop
# service postgresql-9.6 start
или
# service postgresql-9.6 restart
ПЕРЕХОДИМ на SLAVE
Выполняем все что в пункте 0. УСТАНОВКА PostgreSQL
Останавливаем базу
# service postgresql-9.6 stop
Удаляем все файлы в директории data:
# rm -rf /var/lib/pgsql/9.6/data/*
Копируем с MASTER-а базу (обратите внимание - запускаем pg_basebackup под пользователем postgres, под которым работает база)
# sudo -u postgres pg_basebackup --host=<ip_MASTER> --username=repluser --pgdata=/var/lib/pgsql/9.6/data --xlog-method=stream --write-recovery-conf
выше написанная команда делает следующее - подключается к MASTER-у под пользователем repluser (команда затребует пароль, его нужно ввести, скорей всего можно в команде этот пароль и прописать, но я не заморачивался), копирует целиком базу вместе с конфигурационными файлами, а так же создает минимально необходимый файл recovery.conf, в котором собственно прописано, что база работает в режиме реплики, а значит пока существует этот файл, то в режиме только для чтения!
Привожу текст файла recovery.conf:
standby_mode = 'on'
primary_conninfo = 'user=repluser password=супер-секретный-пароль host=ip_MASTER port=5432 sslmode=prefer sslcompression=1 krbsrvname=postgres'
Как я уже говорил выше, если остановить базу, и переименовать файл recovery.conf, и снова запустить, то база перестает быть репликой.
Запускаем базу
# service postgresql-9.6 start
все :), SLAVE в теперь реплика, и регулярно таскает печеньки данные с MASTER-а
Что можно добавить?
Эта репликация асинхронная. Есть возможность настройки синхронной потоковой репликации. А так же каскадной, а так же и т.д. и т.д. Читайте, изучайте.
Все что сделано выше решит ситуацию, когда у вас внезапно взрывается MASTER - у вас есть актуальная копия, реплика.
Примерный сценарий таков:
- останавливается SLAVE
- переименовывается recovery.conf
- запускается SLAVE
- на сервере 1С базы переподключаются к SLAVE-у, пользователи начинают работать, а вы решаете - что там случилось с MASTER-ом.
2. НЕПРЕРЫВНОЕ АРХИВИРОВАНИЕ
Предположим MASTER не взорвался, а просто кто-то умный запустил обработку, которая перепилила и перекорежила данные и все это торжественно перелетело в реплику на SLAVE (см. все что написано выше).
Решает организация непрерывного архивирования.
Обязательно прочитайте (спасибо postgrespro.ru):
https://postgrespro.ru/docs/postgresql/9.6/continuous-archiving
чтобы иметь представление о том что такое WAL, файлы-сегменты WAL и т.д.
Вкратце схема следующая:
- настраиваем непрерывное копирование WAL файлов
- делаем базовую резервную копию, после чего возникает возможность восстановить базу данных на любую временную точку после созданной базовой копии просто "накатывая" необходимое количество WAL файлов. Если базовая резервная копия сделана достаточно давно, то вам придется дольше по времени восстанавливать, накатывая большее количество файлов. Соответственно базовые резервные копии делайте чаще. Старые WAL файлы (созданные до "контрольной точки" сформированной очередной базовой резервной копии) можно "подчищать".
Опишу простейшую систему, когда архивируем на тот же дисковый массив, где и находится собственно база (что неправильно и вы конечно настройте копирование на другой диск, сервер, ftp и т.д.).
На MASTER-е редактируем /var/lib/pgsql/9.6/data/pg_hba.conf, добавляем следующую строчку (или убеждаемся что она уже есть):
local replication all trust
Создаем папку archive, в которую будем копировать WAL файлы (обратите внимание - выполняем mkdir под пользователем postgres, чтобы установились нужные права на папку, и база был к ней доступ)
# sudo -u postgres mkdir -p /var/lib/pgsql/9.6/backups/archive
Редактируем файл /var/lib/pgsql/9.6/data/postgresql.conf
archive_command = 'test ! -f /var/lib/pgsql/9.6/backups/archive/%f && cp %p /var/lib/pgsql/9.6/backups/archive/%f'
(
то есть, задаем желаемую команду оболочки в параметре archive_command. В archive_command символы %p заменяются полным путём к файлу, подлежащему архивации, а %f заменяются только именем файла. Поэтому когда WAL файл готов к копированию (заполнен) вызывается примерно следующая команда:
test ! -f /var/lib/pgsql/9.6/backups/archive/00000001000000A900000065 && cp pg_xlog/00000001000000A900000065 /var/lib/pgsql/9.6/backups/archive/00000001000000A900000065
)
# service postgresql-9.6 restart
Создаем папку basebackups, в которую положим заархивированную базовую резервную копию (обратите внимание - выполняем mkdir под пользователем postgres, чтобы установились нужные права на папку, и база был к ней доступ)
# sudo -u postgres mkdir -p /var/lib/pgsql/9.6/backups/basebackups
Делаем базовую резервную копию:
# pg_basebackup -U postgres -D /var/lib/pgsql/9.6/backups/basebackups -Ft -z -Xf -Pv
здесь делаем базовую резервную копию и архивируем все в один файл (в моем случае образовался файл с именем base.tar.gz). В общем изучите возможности pg_basebackup.
Если бы каталог basebackups был не пустой pg_basebackup, то выдаст ошибку:
pg_basebackup: каталог "/var/lib/pgsql/9.6/backups/basebackups" существует, но он не пуст
Поэтому, последующие базовые резервные копии я буду делать так:
# pg_basebackup -U postgres -D /var/lib/pgsql/9.6/backups/basebackups/имя_нового_каталога -Ft -z -Xf
(pg_basebackup сам создаст этот каталог, предварительно его создавать не нужно).
Кстати, по результатам работы pg_basebackup в папке, куда мы копируем WAL файлы, мы увидим подобный файл.
-rw------- 1 postgres postgres 308 окт 24 02:37 00000001000000150000006B.00000028.backup
по сути - это временная метка с которой можно восстанавливать базу из архива.
К сожалению процесс восстановления описать не могу, так как мне еще предстоит его протестировать, обкатать. Надеюсь найти время и дописать статью.
P.S. это моя первая статья, не судите строго