Установка и настройка PostgreSQL на Linux в режиме кластера, и заметки по использованию этого решения в качестве СУБД для 1С Сервера.
Хочу предупредить, что статья на сайте родилась после написания инструкции на английском, поэтому в тексте ниже будет встречаться английский.
Перед тем, как говорить о кластеризации PostgreSQL, выделим три основных вида кластеров СУБД:
Кластеры SQL
- Несколько экземпляров- нод кластера СУБД, каждая из которых использует одну Систему Хранения Данных (СХД).
Достоинства: простая реализация
Недостатки: СХД — единственная точка отказа. Пока СХД не будет кластеризована своими инструментами, СУБД-кластер нельзя назвать полностью отказоустойчивым именно по этой причине. - Синхронная репликация. Когда несколько нод кластера имеют собственную систему хранения данных (локальные диски, или у каждого свой NAS). Система может работать в режиме «Актив — Актив» (когда каждая нода может принимать подключения от клиентов и проводить транзакции с базами), и «Актив-Пассив» (когда одна из нод кластера принимает транзакции и осуществляет работу с базами данных, при этом «пассивная» нода переходит в состояние «активной» при неисправности первой ноды, или по запросу администратора). Вне зависимости от режима работы, каждая транзакция гарантированно реплицируется на все ноды кластера, что влияет на гарантированно надежный способ репликации над кластера. Осуществляется это просто: клиент отправляет запрос базе данных >> активная нода принимает запрос, отправляет копию запроса на остальные ноды кластера и после этого сама выполняет запрос >> остальные ноды кластера, получив запрос, выполняют его и только после его выполнения и записи изменений в базу данных отправляют активной ноде кластера сообщение об успешном завершении транзакции >> активная нода кластера, убедившись, что все запросы на всех нодах (в том числе и сама) выполнены успешно, отправляет клиенту сообщение об успешном выполнении запроса. Такая схема вынуждает клиента ждать, пока все ноды кластера получат запросы и их обработают. Если одна из нод «тормозит» — то весь кластер будет работать медленно. Поэтому такой способ кластеризации хоть и самый надежных в плане синхронности базы данных всех реплик, но еще самый медленный.
Достоинства: самый надежный способ репликации, исключена рассинхронизация нод.
Недостатки: низкая производительность, падение пассивной ноды вызывает «лаг» — прекращение транзакций, пока кластер по таймауту не поймет, что нода кластера упала. Высокие требования к сетевой скорости между нодами кластера. - Асинхронная репликация. Когда несколько нод кластера имеют собственную систему хранения данных (локальные диски, или у каждого свой NAS). Система может работать в режиме «Актив-Пассив», когда одна из нод кластера принимает транзакции и осуществляет работу с базами данных, при этом «пассивная» нода переходит в состояние «активной» при неисправности первой ноды, или по запросу администратора). В отличие от синхронной репликации, асинхронная репликация не гарантирует полную идентичность баз данных на всех нодах кластера. Объясняется это просто:: клиент отправляет запрос базе данных >> активная нода принимает запрос, отправляет копию запроса на остальные ноды кластера и после этого сама выполняет запрос >> как только активная нода сама выполнила запрос, она отправляет клиенту сообщение об успешном выполнении запроса (не дожидаясь сообщений об успешном выполнении транзакции от остальных нод кластера). На этом этапе клиент уже выполнил транзакции, и шлет новые в очередь активной ноды СУБД. Однако остальные ноды кластера на данный момент могут не выполнить транзакции! Конечно, получив запрос, пассивные ноды выполняют его и сообщают активной ноде о результатах выполнения, однако для клиента СУБД эта информация уже не важна, т.к. он получил ответ об успешной записи в базу данных намного раньше. Асинхронная репликация потому и называется, что пассивные ноды несколько «отстают» от активной. Их базы данных могут быть рассинхронизированными на момент падения активной ноды. В момент выхода из строя активной ноды, есть вероятность потерь данных (небольшой ее части, но потери есть).
Достоинства: высокая производительность, падение пассивной ноды не отражается на работе, меньшие требования к скорости сети между нодами (пассивную ноду можно подключить через интернет для синхронизации по узкому каналу, когда на конечную производительность клиентов это не повлияет)
Недостатки: нет гарантий рассинхронизации нод кластера (в момент падения активной ноды, вторая нода может не успеть ссинхронизировать последние изменения баз данных с активной ноды до ее падения).
Кластеризация PostgreSQL может быть реализована несколькими способами:
- Streaming Replication. С версии 9.0 PostgreSQL научилась своими средствами синхронизировать файлы транзакции WAL между нодами одного кластера. Кластер работает точно также, как и MS SQL кластер. А именно: одна из нод кластера собирает запросы SQL, выполняя их записывает все записывает в логи транзакции, которые далее синхронизирует с остальными нодами. Остальные ноды, получая обновленные данные из логов транзакций, выполняют их на своей стороне, записывая изменения в свои базы данных.
Достоинства: работа из коробки без посредников и кода третьих лиц.
Недостатки: необходимо отрабатывать реализацию переключения клиента на вторую ноду PostgreSQL кластера, когда первая выходит из строя. Ноды реплицируют все базы данных без исключения - Slony. Асинхронная репликация. Тоже самое что Streaming Replication, только внешнее решение, сильно нагружающее мастер-ноду и позволяющую более гибко настроить синхронизацию (по отдельным базам и нодам).
Достоинства: более гибкая в настройке чем Streaming Replication
Недостатки: внешнее решение, сложная настройка, высокая нагрузка на мастер-сервер, самому slony нужна отказоустойчивость - Pgpool-II. Посредник между pqSQL и клиентом. Является распределителем нагрузки чтения из базы данных, пуллером, однако задачи записи и удаления рассылает всем нодам кластера и ожидает успешного выполнения данных операций на каждой ноде (т.е. синхронная репликация).
Достоинства: распределение нагрузки чтения, синхронная репликация нод.
Недостатки: работает не из коробки, самому pgpool-II нужна отказоустойчивость.
Остальные способы кластеризации не интересны по причинам активной разработке PostgreSQL-XC, устаревших решений и сомнительных реализаций с недостаточной практикой в мире.
1С Сервер на PostgreSQL
Я перечислю некоторые факты относительно реализации PostgreSQL в качестве СУБД для 1С Сервера:
- Да, это работает, и pgsql бесплатен.
- Для 1С Сервера публикуется специальный пропатченный релиз PostgreSQL. Его использование обязательно для 1С Сервера. Уже пропатченный pgsql распространяется самим 1С, при этом релизы сильно отстают от актуальных версий postgreSQL.
- Пропатченный postgreSQL можно скачать как для Windows-платформы, так и для Linux.
- Важно! Кластеризация пропатченного PostgreSQL для 1С Сервера будет работать только в случае установки PostgreSQL на Linux! Для 1С Сервера единственный рабочий способ кластеризации pgsql — это Streaming Replication, который в пропатченной версии работает только на Linux-версии pgsql 9.1
- Скорость работы postgreSQL на Windows в сочетании с 1С Сервером намного ниже, по сравнению с PostgreSQL на Линукс-платформе.
Установка и настройка PostgreSQL
В данной статье я буду рассматривать реализацию SQL-кластера для использования с 1С Сервером. Ниже можно увидеть, как я устанавливаю пропатченную 1С-ом (один-эсом) версию PostgreSQL, однако становка от обычной версии pgsql ничем не отличается. Кроме того, в статье я использую систему виртуализации Hyper-V, можно увидеть установку компонентов интеграции LinuxIC for Linux RedHat (прекрасно работает на CentOS, Scentific Linux и другие rpm-дистрибутивы, производные от RedHat).
В итоге статьи, Вы получаете:
- Две ноды кластера с асинхронной синхронизацией Streaming Replication — новая фича, доступная с PostgreSQL 9.0 и выше.
- Одна из нод активна, вторая — пассивная. В момент падения активной ноды необходимо каждому клиенту SQL переписать адрес подключения к СУБД. Функция автоматического переключения клиентов на вторую ноду при падении первой не рассматриватся в данной статье.
- Т.к. статья родилась из документации внедренного решения, где пассивная вторая нода находится на удаленной площадке с медленным интернетом(а вместе с ним и второй 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, т.к. в последней версии компоненты интеграции Гипер-В уже присутствуют в системе из коробки!
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
На этом настройка Постргри может считаться завершенной.