Установка и настройка PostgreSQL на Linux в режиме кластера, и заметки по использованию этого решения в качестве СУБД для 1С Сервера.

Хочу предупредить, что статья на сайте родилась после написания инструкции на английском, поэтому в тексте ниже будет встречаться английский.
Перед тем, как говорить о кластеризации PostgreSQL, выделим три основных вида кластеров СУБД:

Кластеры SQL

  1. Несколько экземпляров- нод кластера СУБД, каждая из которых использует одну Систему Хранения Данных (СХД).
    Достоинства: простая реализация
    Недостатки: СХД — единственная точка отказа. Пока СХД не будет кластеризована своими инструментами, СУБД-кластер нельзя назвать полностью отказоустойчивым именно по этой причине.
  2. Синхронная репликация. Когда несколько нод кластера имеют собственную систему хранения данных (локальные диски, или у каждого свой NAS). Система может работать в режиме «Актив — Актив» (когда каждая нода может принимать подключения от клиентов и проводить транзакции с базами), и «Актив-Пассив» (когда одна из нод кластера принимает транзакции и осуществляет работу с базами данных, при этом «пассивная» нода переходит в состояние «активной» при неисправности первой ноды, или по запросу администратора). Вне зависимости от режима работы, каждая транзакция гарантированно реплицируется на все ноды кластера, что влияет на гарантированно надежный способ репликации над кластера. Осуществляется это просто: клиент отправляет запрос базе данных >> активная нода принимает запрос, отправляет копию запроса на остальные ноды кластера и после этого сама выполняет запрос >> остальные ноды кластера, получив запрос, выполняют его и только после его выполнения и записи изменений в базу данных отправляют активной ноде кластера сообщение об успешном завершении транзакции >> активная нода кластера, убедившись, что все запросы на всех нодах (в том числе и сама) выполнены успешно, отправляет клиенту сообщение об успешном выполнении запроса. Такая схема вынуждает клиента ждать, пока все ноды кластера получат запросы и их обработают. Если одна из нод «тормозит» — то весь кластер будет работать медленно. Поэтому такой способ кластеризации хоть и самый надежных в плане синхронности базы данных всех реплик, но еще самый медленный.
    Достоинства: самый надежный способ репликации, исключена рассинхронизация нод.
    Недостатки: низкая производительность, падение пассивной ноды вызывает «лаг» — прекращение транзакций, пока кластер по таймауту не поймет, что нода кластера упала. Высокие требования к сетевой скорости между нодами кластера.
  3. Асинхронная репликация. Когда несколько нод кластера имеют собственную систему хранения данных (локальные диски, или у каждого свой NAS). Система может работать в режиме «Актив-Пассив», когда одна из нод кластера принимает транзакции и осуществляет работу с базами данных, при этом «пассивная» нода переходит в состояние «активной» при неисправности первой ноды, или по запросу администратора). В отличие от синхронной репликации, асинхронная репликация не гарантирует полную идентичность баз данных на всех нодах кластера. Объясняется это просто:: клиент отправляет запрос базе данных >> активная нода принимает запрос, отправляет копию запроса на остальные ноды кластера и после этого сама выполняет запрос >> как только активная нода сама выполнила запрос, она отправляет клиенту сообщение об успешном выполнении запроса (не дожидаясь сообщений об успешном выполнении транзакции от остальных нод кластера). На этом этапе клиент уже выполнил транзакции, и шлет новые в очередь активной ноды СУБД. Однако остальные ноды кластера на данный момент могут не выполнить транзакции! Конечно, получив запрос, пассивные ноды выполняют его и сообщают активной ноде о результатах выполнения, однако для клиента СУБД эта информация уже не важна, т.к. он получил ответ об успешной записи в базу данных намного раньше. Асинхронная репликация потому и называется, что пассивные ноды несколько «отстают» от активной. Их базы данных могут быть рассинхронизированными на момент падения активной ноды. В момент выхода из строя активной ноды, есть вероятность потерь данных (небольшой ее части, но потери есть).
    Достоинства: высокая производительность, падение пассивной ноды не отражается на работе, меньшие требования к скорости сети между нодами (пассивную ноду можно подключить через интернет для синхронизации по узкому каналу, когда на конечную производительность клиентов это не повлияет)
    Недостатки: нет гарантий рассинхронизации нод кластера (в момент падения активной ноды, вторая нода может не успеть ссинхронизировать последние изменения баз данных с активной ноды до ее падения).

Кластеризация PostgreSQL может быть реализована несколькими способами:

  1. Streaming Replication. С версии 9.0 PostgreSQL научилась своими средствами синхронизировать файлы транзакции WAL между нодами одного кластера. Кластер работает точно также, как и MS SQL кластер. А именно: одна из нод кластера собирает запросы SQL, выполняя их записывает все записывает в логи транзакции, которые далее синхронизирует с остальными нодами. Остальные ноды, получая обновленные данные из логов транзакций, выполняют их на своей стороне, записывая изменения в свои базы данных.
    Достоинства: работа из коробки без посредников и кода третьих лиц.
    Недостатки: необходимо отрабатывать реализацию переключения клиента на вторую ноду PostgreSQL кластера, когда первая выходит из строя. Ноды реплицируют все базы данных без исключения
  2. Slony. Асинхронная репликация. Тоже самое что Streaming Replication, только внешнее решение, сильно нагружающее мастер-ноду и позволяющую более гибко настроить синхронизацию (по отдельным базам и нодам).
    Достоинства: более гибкая в настройке чем Streaming Replication
    Недостатки: внешнее решение, сложная настройка, высокая нагрузка на мастер-сервер, самому slony нужна отказоустойчивость
  3. Pgpool-II. Посредник между pqSQL и клиентом. Является распределителем нагрузки чтения из базы данных, пуллером, однако задачи записи и удаления рассылает всем нодам кластера и ожидает успешного выполнения данных операций на каждой ноде (т.е. синхронная репликация).
    Достоинства: распределение нагрузки чтения, синхронная репликация нод.
    Недостатки: работает не из коробки, самому pgpool-II нужна отказоустойчивость.

Остальные способы кластеризации не интересны по причинам активной разработке PostgreSQL-XC, устаревших решений и сомнительных реализаций с недостаточной практикой в мире.

1С Сервер на PostgreSQL

Я перечислю некоторые факты относительно реализации PostgreSQL в качестве СУБД для 1С Сервера:

  1. Да, это работает, и pgsql бесплатен.
  2. Для 1С Сервера публикуется специальный пропатченный релиз PostgreSQL. Его использование обязательно для 1С Сервера. Уже пропатченный pgsql распространяется самим 1С, при этом релизы сильно отстают от актуальных версий postgreSQL.
  3. Пропатченный postgreSQL можно скачать как для Windows-платформы, так и для Linux.
  4. Важно! Кластеризация пропатченного PostgreSQL для 1С Сервера будет работать только в случае установки PostgreSQL на Linux! Для 1С Сервера единственный рабочий способ кластеризации pgsql — это Streaming Replication, который в пропатченной версии работает только на Linux-версии pgsql 9.1
  5. Скорость работы postgreSQL на Windows в сочетании с 1С Сервером намного ниже, по сравнению с PostgreSQL на Линукс-платформе.

Установка и настройка PostgreSQL

В данной статье я буду рассматривать реализацию SQL-кластера для использования с 1С Сервером. Ниже можно увидеть, как я устанавливаю пропатченную 1С-ом (один-эсом) версию PostgreSQL, однако становка от обычной версии pgsql ничем не отличается. Кроме того, в статье я использую систему виртуализации Hyper-V, можно увидеть установку компонентов интеграции LinuxIC for Linux RedHat (прекрасно работает на CentOS, Scentific Linux и другие rpm-дистрибутивы, производные от RedHat).

В итоге статьи, Вы получаете:

  1. Две ноды кластера с асинхронной синхронизацией Streaming Replication — новая фича, доступная с PostgreSQL 9.0 и выше.
  2. Одна из нод активна, вторая — пассивная. В момент падения активной ноды необходимо каждому клиенту SQL переписать адрес подключения к СУБД. Функция автоматического переключения клиентов на вторую ноду при падении первой не рассматриватся в данной статье.
  3. Т.к. статья родилась из документации внедренного решения, где пассивная вторая нода находится на удаленной площадке с медленным интернетом(а вместе с ним и второй 1С Сервер), клиент постгри (в данном случае 1С Сервер) необходимо настраивать «ручками» при выходе из строя активной ноды. В ТЗ было много условностей и в связи с допустимыми интервалами простоя 1С (сутки), была принята такая архитектура. На 1С Сервере в качестве sql-сервера указано имя sql01.itisok.ru. Это имя во внутреннем DNS с помощью А-записи ссылается на ip-адрес одной из нод PostgreSQL. Поэтому, при «смене» активной ноды Постгри, необходимо обновить DNS-запись и сбросить DNS-кэш на 1С Сервере командой ipconfig /flushdns. Перенастраивать все информационные базы в консоли Управления 1С Сервера, не требуется.

Prepare server

  • Virtual Machine Hyper-V v2 in Hyper-V Server 2008R2 SP1
  • 4096 Mb RAM
  • 30 Gb IDE Virtual HDD
  • First Network Interface (modern, not legacy), network LAN, static MAC 00:15:5D:2d:51:61, this NIC will be eth0
  • CentOS 6.3 x86_64 minimal
  • Language: english
  • Location: Moscow
  • Time: system clock don’t uses UTC
  • Disk partition by default

Install CentOS 6.3

Minimal installation by default.

Install Hyper-V Integration Components to CentOS 6.3

Эта операция уже не требуется для CentOS 6.4, т.к. в последней версии компоненты интеграции Гипер-В уже присутствуют в системе из коробки! :mrgreen:

Insert LinucIC v3.3 iso in virtual CD-ROM, install, then reboot system:

# mount /dev/cdrom /media && rpm -Uvh --nodeps /media/kmod-microsoft-hyper-v-rhel63.3-4.20120605.x86_64.rpm microsoft-hyper-v-rhel63.3-4.20120605.x86_64.rpm && reboot

Configure Network Settings, update OS

Config NICs:

# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
HWADDR="00:15:5D:2d:51:61"
NM_CONTROLLED="no"
ONBOOT="yes"
BOOTPROTO="static"
IPADDR="192.168.47.8"
NETMASK="255.255.252.0"
USERCTL="no"

Config DNS and other network settings:

# vi /etc/resolv.conf
domain itisok.ru
nameserver 192.168.47.1
nameserver 192.168.47.2
# vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=srv08.itisok.ru
GATEWAY=192.168.45.253
# service network restart

Set hostname and check it:

# hostname –v srv08.itisok.ru
# hostname –v
srv08.itisok.ru
# hostname -s
srv08

Setup NTP service for time synchronization. Install ntp, then config it:

# yum install -y ntp && vi /etc/ntp.conf
#server 0.centos.pool.ntp.org ### comment this line
#server 1.centos.pool.ntp.org ### comment this line
#server 2.centos.pool.ntp.org ### comment this line
server ntp01.itisok.ru ## add this line
server ntp02.itisok.ru ## add this line

Config autosynchronization, then OS booting:

# vi /etc/rc.local
/usr/sbin/ntpdate -u ntp01.itisok.ru ntp02.itisok.ru ## add this line to file

Configure ntp daemon autoload and force sync time, check time:

# chkconfig ntpd on && ntpdate -u ntp01.itisok.ru ntp02.itisok.ru && service ntpd start && date -u && date

Disable SELinux:

vi /etc/sysconfig/selinux
SELINUX=disabled ##change this line

Reboot:

# reboot

Update operating system and reboot:

# yum update -y && reboot

Configure netflow/iptables

Configure iptables file policy:

# vi /etc/sysconfig/iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
#
### For PostgreSQL
-A INPUT -m state --state NEW -m tcp -p tcp --dport 5432 -j ACCEPT
###
#
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT

Restart iptables:

# service iptables restart

Install Postgresql (patched and publicated by 1C)

Configure additional virtual hard drive for store SQL databases

Я люблю отделять мух от котлет. Система с Постгри пускай работает на одном виртуальном жестком диске, а вот базы SQL хочу, чтобы хранились на отдельном виртуальном жестком диске. Тогда его переполнение не будет зависеть от переполнения системного диска. Кроме того, всегда удобно скопировать виртуальный жесткий диск для другой виртуалки, и заставить работать обновленный/восстановленный/тестовый PostgreSQL за пару кликов.

Shutdown virtual machine:

# shutdown -P now

Create additional virtual hard disk (virtual scsi disk) in Hyper-V console and start virtual machine.

List partitions in OS:

# fdisk -l

List physical volumes of LVM:

# pvdisplay

List logical volumes of LVM:

# lvdisplay

Create physical volume of LVM on new virtual disk:

# pvcreate /dev/sdb
# pvscan
# pvdisplay

Create volume group of LVM on new physical volume of your new virtual disk:

# vgcreate vg_srv08_store01 /dev/sdb

Check results:

# pvdisplay
--- Physical volume ---
PV Name               /dev/sdb
VG Name               vg_srv08_store01
PV Size               500.00 GiB / not usable 4.00 MiB
Allocatable           yes
PE Size               4.00 MiB
Total PE              127999
Free PE               127999
Allocated PE          0
PV UUID               viTFB6-j5fs-mDRT-4unM-U04N-RAqQ-JBCC8b

Create logical volume of LVM on new volume group in your physical volume of new virtual disk. Logical volume creates on all free space (see pvdisplay command output bellow, «Free PE» count):

# lvcreate -n lv_store01 -l 127999 vg_srv08_store01

List your changes:

# fdisk -l
# pvdisplay
# lvdisplay

Format you logical volume:

# mkfs.ext4 /dev/vg_srv08_store01/lv_store01

Create mount point folder and config automounting new logical volume to OS:

# mkdir /store01
# vi /etc/fstab
# Created by anaconda on Sat Sep  8 01:35:13 2012
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/vg_srv08-lv_root /                       ext4    defaults        1 1
UUID=30219c25-3c35-4761-91d8-8edc82500d3c /boot      ext4    defaults        1 2
/dev/mapper/vg_srv08-lv_swap swap                    swap    defaults        0 0
tmpfs                        /dev/shm                tmpfs   defaults        0 0
devpts                       /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                        /sys                    sysfs   defaults        0 0
proc                         /proc                   proc    defaults        0 0
/dev/mapper/vg_srv08_store01-lv_store01   /store01   ext4    defaults        1 3

Reboot:

# reboot

Install and configure PostgreSQL patched by 1C

Copy rpm distribs of Postgresql with WinSCP in /root directory. Then install this rpm-s:

# cd /root/1C8_postgresql_9_2_1_rpm_x86_64/
# yum install -y postgresql91-server-9.1.2-1.1C.x86_64.rpm postgresql91-libs-9.1.2-1.1C.x86_64.rpm postgresql91-contrib-9.1.2-1.1C.x86_64.rpm postgresql91-9.1.2-1.1C.x86_64.rpm

Setup autoload service of postgresql

# chkconfig postgresql-9.1 on

Initialise postgre’s data folder with russian locale:

# mkdir /store01/pgsql_data01 && chown postgres:postgres /store01/pgsql_data01 && su postgres -c '/usr/pgsql-9.1/bin/initdb -D /store01/pgsql_data01 --locale=ru_RU.UTF-8'

Set new database folder path in init-scripts of postgresql. Change defaults for configuration variable PGDATA:

# vi /etc/rc.d/init.d/postgresql-9.1
PGDATA=/store01/pgsql_data01 ## change this line

Start postgreSQL for change postgres’ password:

# service postgresql-9.1 start
# psql -U postgres
postgres=# ALTER USER postgres with password 'your_password';
ALTER ROLE
postgres=# \q

Set password for postgres user in Linux:

# passwd postgres
Changing password for user postgres.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

Config access to postgresql:

# vi /store01/pgsql_data01/pg_hba.conf
#TYPE  DATABASE     USER         ADDRESS             METHOD

# "local" is for Unix domain socket connections only
local all          all                        md5
# IPv4 local connections:
host   all          all          127.0.0.1/32        md5
host   all          all          192.168.47.8/32     md5
host   all          all          192.168.47.9/32     md5
# IPv6 local connections:
host   all          all          ::1/128             md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication   postgres                          md5
host   replication postgres     127.0.0.1/32        md5
host   replication postgres     ::1/128             md5
host   replication postgres     192.168.47.8/32     md5
host   replication postgres     192.168.47.9/32     md5

Reboot server and check installed services:

# reboot
# service postgresql-9.1 status

PostgreSQL clusterisation

For 1C Enterprise we will using build-in PostgreSQL Streaming Replication.

Next steps must be set in primary node

Configure PostgreSQL by change settings in /store01/pgsql_data01/postgresql.conf:

# vi /store01/pgsql_data01/postgresql.conf
wal_level = hot_standby
max_wal_senders = 1
hot_standby = on

Copy your copy databases in secondary host, then PostgreSQL stopped by using rsync:

# yum install -y rsync openssh-clients
# service postgresql-9.1 stop
# rsync -a /store01/pgsql_data01/ 192.168.47.9:/store01/pgsql_data01/ --exclude postmaster.pid
# service postgresql-9.1 start

Next steps must be set in secondary node

Create /store01/pgsql_data01/recovery.conf file with this configuration:

# vi /store01/pgsql_data01/recovery.conf
standby_mode = 'on'
primary_conninfo = 'host=192.168.47.8 port=5432 user=postgres password=your_pass_of_postgres'
trigger_file = '/store01/pgsql_data01/master-trigger'

Start\restart PostgreSQL on second node:

# service postgresql-9.1 restart

Next steps must be set in all nodes

Check replication:

# ps aux | grep wal

For primary node normal output:

postgres  2174  0.0  0.1 200564  2768 ?        Ss   20:09   0:00 postgres: wal sender process postgres 192.168.47.9(40792) streaming 0/3001980

For secondary node normal output:

postgres  2333  0.0  0.1 204024  2484 ?        Ss   20:09   0:00 postgres: wal receiver process   streaming 0/3001980

На этом настройка Постргри может считаться завершенной.