Postgres Pro Enterprise в Microsoft Azure

Руководство по созданию и использованию Postgres Pro Enterprise (VM) в Microsoft Azure

Для использования БД Postgres Pro Enterprise (VM) в облаке Microsoft Azure необходимо иметь доступ в Интернет и учетную запись в Microsoft Azure.

Для установки используем образ виртуальной машины Postgres Pro Enterprise 9.6/10/11/12/13/14 доступный в Microsoft Azure Marketplace.

Требуемое ПО:

  • Azure CLI 2.x для управления облачными ресурсами в Azure
  • 'psql' или 'Pgadmin' для доступа к БД

Используем кросс-платформенную утилиту Azure CLI 2.x.

Также можно использовать Azure Portal https://portal.azure.com или Azure PowerShell.

Установка Azure CLI 2.x описана в https://docs.microsoft.com/ru-ru/cli/azure/install-azure-cli

Основные команды Azure CLI 2.x описаны в https://docs.microsoft.com/ru-ru/cli/azure/get-started-with-azure-cli

Полный список команд Azure CLI 2.x можно найти на https://docs.microsoft.com/ru-ru/cli/azure

Установка и администрирование Linux Virtual Machine в Azure описаны в https://docs.microsoft.com/ru-ru/azure/virtual-machines/linux

Резервное копирование в Azure описано в https://docs.microsoft.com/ru-ru/azure/backup


Подключение к Azure и проверка окружения

  • Подключаемся к Microsoft Azure с помощью команды:
az login

или

az login --username <myusername>
  • Для удобства устанавливаем табличный формат вывода команд Azure CLI 2.x:
az configure
  • Проверяем установленную версию Azure CLI 2.x (рекомендуется последняя доступная версия):
az --version | head -1
  • Проверяем, зарегистрированы ли необходимые сервисы - Microsoft.Storage, Microsoft.Compute и Microsoft.Network:
az provider show --namespace Microsoft.Storage
az provider show --namespace Microsoft.Compute
az provider show --namespace Microsoft.Network
  • Если нет, то регистрируем их:
az provider register --namespace Microsoft.Storage
az provider register --namespace Microsoft.Compute
az provider register --namespace Microsoft.Network
  • Список географических регионов для размещения VM:
az account list-locations

Далее будем использовать географический регион ‘northeurope’.

  • Список доступных размеров VM в географическом регионе ‘northeurope’:
az vm list-sizes --location northeurope

Далее будем использовать размер VM ‘Standard_DS1_v2’ (доступен для ‘Free Trial’ подписки).

  • Получаем название издателя образа VM Postgres Pro в Microsoft Azure Marketplace в географическом регионе ‘northeurope’:
az vm image list-publishers \
--location northeurope \
--query "[?starts_with(name,'postgres')].{Name:name}"

Далее будем использовать название издателя образа VM ‘postgres-pro’.

  • Получаем названия образов VM Postgres Pro доступных в Microsoft Azure Marketplace от издателя ‘postgres-pro’ в географическом регионе ‘northeurope’:
az vm image list \
--publisher postgres-pro \
--location northeurope \
--all \
--query "[?contains(urn,'enterprise')].{Urn:urn}"
  • Далее будем использовать название образа VM:
urn_id='postgres-pro:postgres-pro-enterprise-96-vm:pgpro-ent-96-centos7-x64-hourly:latest'
или
urn_id='postgres-pro:postgres-pro-enterprise-10-vm:pgpro-ent-10-centos7-x64-hourly:latest'
или
urn_id='postgres-pro:postgres-pro-enterprise-11-vm:pgpro-ent-11-centos7-x64-hourly:latest'
или
urn_id='postgres-pro:postgres-pro-enterprise-12-vm:pgpro-ent-12-centos7-x64-hourly:latest'
или
urn_id='postgres-pro:postgres-pro-enterprise-13-vm:pgpro-ent-13-centos7-x64-hourly:latest'
или
urn_id='postgres-pro:postgres-pro-enterprise-14-vm:pgpro-ent-14-centos7-x64-hourly:latest'
  • Настраиваем программное развертывание VM:
az vm image terms accept --urn $urn_id
  • В директории ~/.ssh создаем пару private/public ssh-ключей для подключения к VM:
ssh-keygen -t rsa -b 2048


Создание VM

  • Создаем ресурсную группу:
az group create \
--name myresourcegroup \
--location northeurope
  • Создаем VM из образа доступного в Microsoft Azure Marketplace:
az vm create \
--name myvm-ent-xx \
--resource-group myresourcegroup \
--image $urn_id \
--location northeurope \
--size Standard_DS1_v2 \
--ssh-key-value ~/.ssh/id_rsa.pub \
--admin-username azureuser \
--authentication-type ssh \
--public-ip-address-dns-name myvm-ent-xx-dnsname \
--os-disk-name myvm-ent-xx-osdisk

Вместо ‘xx’ используем '01', '02', '03' и т.д.


Подключение к VM

В результате создается VM с полным доменным именем ‘myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com’ (полное доменное имя формируется из короткого доменного имени, задаваемого при создании VM, названия географического региона и ‘cloudapp.azure.com’) и с ОС-пользователем ‘azureuser’ (по умолчанию с правами ‘sudo’)

  • Подключаемся к VM:
ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com

Вместо ‘xx’ используем '01', '02', '03' и т.д.


Проверка статуса сервиса БД Postgres Pro

  • Проверяем статус сервиса БД Postgres Pro: 
sudo systemctl -l status postgrespro-ent-14.service
  • Чтобы остановить/стартовать сервис БД Postgres Pro используем команды:
sudo systemctl stop postgrespro-ent-14.service
sudo systemctl start postgrespro-ent-14.service


Подключение к БД Postgres Pro

  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Для подключения к БД Postgres Pro используем команду:
psql
  • Для выхода из ‘psql’ используем команду:
\q
  • Для возврата в интерфейс Azure CLI 2.x дважды выполняем команду 'exit'


Внешний доступ к VM

  • При необходимости внешнего подключения к БД Postgres Pro открываем порт 5433:
az vm open-port \
--name myvm-ent-xx \
--port 5433 \
--resource-group myresourcegroup \
--priority 1001
  • При необходимости внешнего подключения к серверу мониторинга БД открываем порты 80 и 443:
az vm open-port \
--name myvm-ent-xx \
--port 80 \
--resource-group myresourcegroup \
--priority 1002

az vm open-port \
--name myvm-ent-xx \
--port 443 \
--resource-group myresourcegroup \
--priority 1003

Вместо ‘xx’ используем '01', '02', '03' и т.д.


Внешнее подключение к БД Postgres Pro

  • Для внешнего подключения к БД Postgres Pro устанавливаем пароль пользователя 'postgres':
ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com

sudo su - postgres
psql -c "alter user postgres with encrypted password 'YOUR_POSTGRES_USER_PASSWORD'"
exit

exit
  • Для внешнего подключения к БД Postgres Pro с помощью 'psql' используем команду:
psql --host=myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com --port=5433 --username=postgres --dbname=postgres
  • Для внешнего подключения к БД Postgres Pro с помощью 'Pgadmin' при конфигурации сервера в меню ‘Pgadmin’ используем следующие параметры:
    • ‘mydb-xx’ для ‘Name'
    • ‘myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com’ для ‘Host’
    • '5433' для ‘Port’
    • ‘postgres’ для ‘Maintenance DB’
    • ‘postgres’ для ‘Username’

Вместо ‘xx’ используем '01', '02', '03' и т.д.


Внешнее подключение к серверу мониторинга БД

  • Для подключения к серверу мониторинга БД устанавливаем пароль пользователя 'Admin':
ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com

sudo su - postgres
source .pgsql_profile
psql --dbname=zabbix --username=zabbix -c "update users set passwd=md5('YOUR_ZABBIX_ADMIN_PASSWORD') where alias='Admin'"
exit

exit
  • Внешнее подключение к серверу мониторинга БД по ссылке:

https://myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com/zabbix

Вместо ‘xx’ используем '01', '02', '03' и т.д.


Изменение конфигурации VM

Рассмотрим варианты изменения конфигурации VM:

1) Необходимо изменить размер VM со ‘Standard_DS1_v2’ на ‘Standard_DS2_v2’ для увеличения вычислительной мощности VM

  • Для автоматического изменения значений параметров БД Postgres Pro перед увеличением размера VM нужно удалить файл $PGDATA/postgresql.tune.lock:
ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com

sudo su - postgres
cp $PGDATA/postgresql.auto.conf $PGDATA/postgresql.auto.conf.ORIG
rm $PGDATA/postgresql.tune.lock
exit

exit
  • Получаем список доступных размеров VM в географическом регионе ‘northeurope’ (выполнять команду ‘az vm deallocate’ не требуется):
az vm list-vm-resize-options \
--name myvm-ent-xx \
--resource-group myresourcegroup
  • Чтобы изменить размер VM, выполняем: 
az vm resize \
--name myvm-ent-xx \
--resource-group myresourcegroup \
--size Standard_DS2_v2

Вместо ‘xx’ используем '01', '02', '03' и т.д. 

2) Необходимо увеличить размер ОС-диска, например, до 80 ГБ

  • Получаем информацию об ОС-диске: 
az disk list \
--resource-group myresourcegroup \
--query "[?starts_with(name,'myvm-ent-xx-osdisk')].{Name:name,Gb:diskSizeGb}"
  • Временно отключаем VM: 
az vm deallocate \
--name myvm-ent-xx \
--resource-group myresourcegroup
  • Увеличиваем размер ОС-диска: 
az disk update \
--name myvm-ent-xx-osdisk \
--resource-group myresourcegroup \
--size-gb 80
  • Проверяем обновленную информацию об ОС-диске: 
az disk list \
--resource-group myresourcegroup \
--query "[?starts_with(name,'myvm-ent-xx-osdisk')].{Name:name,Gb:diskSizeGb}"
  • Стартуем VM: 
az vm start \
--name myvm-ent-xx \
--resource-group myresourcegroup
  • Подключаемся к VM: 
ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com
  • Увеличиваем размер раздела файловой системы ‘/’:
(echo d; echo 2; echo n; echo p; echo 2; echo ; echo ; echo w) | sudo fdisk /dev/sda
  • Выполняем перезагрузку VM:
sudo reboot
  • Подключаемся к VM: 
ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com
  • Увеличиваем размер файловой системы ‘/’:
sudo xfs_growfs -d /dev/sda2
  • Выполняем перезагрузку VM:
sudo reboot

Вместо ‘xx’ используем '01', '02', '03' и т.д. 

3) Необходимо использовать выделенный диск для хранения файлов БД Postgres Pro, например, с целью повышения производительности

  • Создаем новый диск размером 200 ГБ и подключаем его к VM:
az vm disk attach \
--disk myvm-ent-xx-datadisk \
--resource-group myresourcegroup \
--vm-name myvm-ent-xx \
--caching ReadOnly \
--lun 1 \
--new \
--size-gb 200
  • Подключаемся к VM:
ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com
  • Останавливаем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl stop postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Создаем точку монтирования новой файловой системы:
sudo mkdir /PGDATA
  • С помощью утилиты 'lsscsi' определяем имя устройства, назначенного новому диску (в нашем случае это /dev/sdc):
lsscsi
  • На этом диске создаем один раздел максимального размера, на разделе создаем файловую систему:
(echo n; echo p; echo 1; echo ; echo ; echo w) | sudo fdisk /dev/sdc
sudo mkfs -t ext4 /dev/sdc1
  • Для файловой системы раздела выделенного диска создаем запись в файле /etc/fstab и монтируем файловую систему:
sudo sh -c "echo '`sudo blkid -o export /dev/sdc1 | grep UUID` /PGDATA ext4 defaults,nofail,barrier=0 1 2' >> /etc/fstab"
sudo mount /PGDATA
  • Создаем директорию 'data' на новой файловой системе и устанавливаем для нее необходимые разрешения:
sudo mkdir /PGDATA/data
sudo chown postgres:postgres /PGDATA/data
sudo chmod 0700 /PGDATA/data
  • Переключаемся на пользователя ‘postgres’ и переносим файлы БД Postgres Pro на новую файловую систему:
sudo su - postgres
mv /var/lib/pgpro/ent-14/data/* /PGDATA/data; rmdir /var/lib/pgpro/ent-14/data; ln -s /PGDATA/data /var/lib/pgpro/ent-14/data
exit
  • Стартуем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl start postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Выполняем перезагрузку VM, проверяем автоматическое монтирование файловой системы и статус сервиса БД Postgres Pro:
sudo reboot

ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com

sudo mount | grep /PGDATA
sudo df -h /PGDATA

sudo systemctl -l status postgrespro-ent-14.service

Вместо ‘xx’ используем '01', '02', '03' и т.д.

4) Автоматический перезапуск сервиса базы данных в случае аварии

  • Добавляем настройку автоматического перезапуска сервиса базы данных в конфигурационном файле systemd и перезапускаем сервис базы данных:
sudo sed -i '/KillSignal=/a Restart=on-failure' /usr/lib/systemd/system/postgrespro-ent-14.service
sudo systemctl daemon-reload
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service


Резервное копирование VM

Рассмотрим вариант резервного копирования VM в Azure (более подробная информация на https://docs.microsoft.com/ru-ru/azure/backup/quick-backup-vm-cli).

  • Сначала создадим хранилище для резервных копий VM:
az backup vault create \
--name myvault-ent-xx \
--resource-group myresourcegroup \
--location northeurope

Далее будем использовать 'myvault-ent-xx' для названия хранилища.

  • Для обеспечения надежности по умолчанию резервные копии VM хранятся в двух географических регионах. Если в этом нет необходимости, храним резервные копии в пределах одного региона:
az backup vault backup-properties set \
--name myvault-ent-xx \
--resource-group myresourcegroup \
--backup-storage-redundancy LocallyRedundant
  • Для VM 'myvm-ent-xx' назначаем политику резервного копирования по умолчанию с периодичностью выполнения копии VM раз в сутки:
az backup protection enable-for-vm \
--vm myvm-ent-xx \
--vault-name myvault-ent-xx \
--policy-name DefaultPolicy \
--resource-group myresourcegroup
  • Запускаем создание первой резервной копии VM в ручном режиме, указав срок хранения резервной копии VM в хранилище в формате 'дд-мм-гггг'. В качестве аргумента для параметров '--item-name' и '--container-name' используем название VM 'myvm-ent-xx'.
az backup protection backup-now \
--item-name myvm-ent-xx \
--container-name myvm-ent-xx \
--vault-name myvault-ent-xx \
--resource-group myresourcegroup \
--retain-until 31-12-2022
  • Информация о ходе выполнения резервного копирования:
az backup job list \
--vault-name myvault-ent-xx \
--resource-group myresourcegroup
  • После успешного завершения резервного копирования VM используем резервную копию для восстановления диска VM, затем создадим VM из восстановленного диска. Для хранения восстановленных данных необходима учетная запись. Создадим ее, если она не существует:
az storage account create \
--name mystorageaccountent \
--resource-group myresourcegroup \
--location northeurope \
--sku Standard_LRS

Далее будем использовать 'mystorageaccountent' для названия учетной записи.

  • Для восстановления диска VM используем его самую последнюю доступную резервную копию:
rp_id=$(az backup recoverypoint list --item-name myvm-ent-xx --container-name myvm-ent-xx --vault-name myvault-ent-xx --resource-group myresourcegroup --query [0].name --output tsv)

az backup restore restore-disks \
--item-name myvm-ent-xx \
--container-name myvm-ent-xx \
--vault-name myvault-ent-xx \
--resource-group myresourcegroup \
--storage-account mystorageaccountent \
--rp-name $rp_id
  • Информация о ходе выполнения восстановления:
az backup job list \
--vault-name myvault-ent-xx \
--resource-group myresourcegroup
  • После успешного восстановления диска конвертируем его в формат managed disk:
container_id=$(az storage container list --account-name mystorageaccountent --query [0].name -o tsv)
blob_id=$(az storage blob list --container-name $container_id --account-name mystorageaccountent --query [0].name -o tsv)
uri_id=$(az storage blob url --name $blob_id --container-name $container_id --account-name mystorageaccountent -o tsv)

az disk create \
--name myrestoredvm-ent-xx-osdisk \
--resource-group myresourcegroup \
--source $uri_id
  • Создаем VM 'myrestoredvm-ent-xx' из восстановленного диска:
az vm create \
--name myrestoredvm-ent-xx \
--resource-group myresourcegroup \
--attach-os-disk myrestoredvm-ent-xx-osdisk \
--location northeurope \
--size Standard_DS1_v2 \
--public-ip-address-dns-name myrestoredvm-ent-xx-dnsname \
--os-type linux
  • Подключаемся к восстановленной VM:
ssh azureuser@myrestoredvm-ent-xx-dnsname.northeurope.cloudapp.azure.com

Вместо ‘xx’ используем '01', '02', '03' и т.д.


Резервное копирование БД Postgres Pro

Рассмотрим варианты резервного копирования БД Postgres Pro (более подробная информация на https://postgrespro.ru/docs/enterprise/14/backup).

  • Подключаемся к VM:
ssh azureuser@myvm-ent-xx-dnsname.northeurope.cloudapp.azure.com

Убедимся, что Azure CLI 2.x установлена внутри VM (более подробная информация на https://docs.microsoft.com/ru-ru/cli/azure/install-azure-cli?view=azure-cli-latest).

  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Выполняем подключение к Microsoft Azure и настройку окружения с помощью команд:
az login

az configure

echo 'export backup_home=$HOME/backup' >> .pgpro_profile
echo 'export file_date=$(date +"%Y%m%d-%H%M%S")' >> .pgpro_profile
echo 'export db_name=testdb' >> .pgpro_profile
echo 'export instance_name=myinstancename' >> .pgpro_profile
  • Создаём контейнер хранения для резервных копий БД:
az storage account create \
--name mystorageaccountent \
--resource-group myresourcegroup \
--location northeurope \
--sku Standard_LRS

az storage container create \
--name mydbbackup-ent-xx \
--account-name mystorageaccountent

exit

Далее будем использовать 'mydbbackup-ent-xx' для названия контейнера хранения.

1) Логическое резервное копирование

1a) с помощью 'pg_dump'

  • Стартуем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Выполняем настройку окружения (в качестве примера используем временную базу данных):
rm -rf $backup_home
mkdir $backup_home

psql -c "create database $db_name"

for ((i=1;i<=3;i++)); do
psql --dbname $db_name -c "create table test_table_0$i(id numeric)"
psql --dbname $db_name -c "insert into test_table_0$i select * from generate_series(1, 5)"
psql --dbname $db_name -c "select * from test_table_0$i"
done

db_owner=$(psql -c "\l $db_name" | grep $db_name | awk '{print $3}')
dump_backup_file=dump_$db_name-backup-$file_date.gz
  • Создаём дамп временной базы данных:
pg_dump $db_name | gzip > $backup_home/$dump_backup_file

ls $backup_home/$dump_backup_file

gzip -ltv $backup_home/$dump_backup_file
  • Сохраняем файл дампа временной базы данных в контейнере хранения:
az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$dump_backup_file \
--name $dump_backup_file

az storage blob list \
--account-name mystorageaccountent \
--container-name mydbbackup-ent-xx
  • Удаляем временную базу данных и файл дампа временной базы данных и восстанавливаем временную базу данных из контейнера хранения:
psql -c "drop database $db_name"

rm $backup_home/$dump_backup_file
ls $backup_home/$dump_backup_file

psql -c "create database $db_name"
psql -c "alter database $db_name owner to $db_owner"

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$dump_backup_file \
--name $dump_backup_file

ls $backup_home/$dump_backup_file

gzip -cdv $backup_home/$dump_backup_file | psql $db_name
  • Выполняем тестовый SQL-запрос к временной базе данных:
for ((i=1;i<=3;i++)); do
psql --dbname $db_name -c "select * from test_table_0$i"
done

exit

1b) с помощью 'pg_dumpall'

  • Стартуем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Выполняем настройку окружения (в качестве примера используем временную базу данных):
rm -rf $backup_home
mkdir $backup_home

psql -c "create database $db_name"

for ((i=1;i<=3;i++)); do
psql --dbname $db_name -c "create table test_table_0$i(id numeric)"
psql --dbname $db_name -c "insert into test_table_0$i select * from generate_series(1, 5)"
psql --dbname $db_name -c "select * from test_table_0$i"
done

dumpall_backup_file=dumpall-backup-$file_date.gz
  • Создаём дамп БД Postgres Pro:
pg_dumpall | gzip > $backup_home/$dumpall_backup_file

ls $backup_home/$dumpall_backup_file

gzip -ltv $backup_home/$dumpall_backup_file
  • Сохраняем файл дампа БД Postgres Pro в контейнере хранения:
az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$dumpall_backup_file \
--name $dumpall_backup_file

az storage blob list \
--account-name mystorageaccountent \
--container-name mydbbackup-ent-xx
  • Удаляем временную базу данных и файл дампа БД Postgres Pro и восстанавливаем БД Postgres Pro из контейнера хранения:
psql -c "drop database $db_name"

rm $backup_home/$dumpall_backup_file
ls $backup_home/$dumpall_backup_file

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$dumpall_backup_file \
--name $dumpall_backup_file

ls $backup_home/$dumpall_backup_file

gzip -cdv $backup_home/$dumpall_backup_file | psql postgres
  • Выполняем тестовый SQL-запрос к временной базе данных:
for ((i=1;i<=3;i++)); do
psql --dbname $db_name -c "select * from test_table_0$i"
done

exit

2) Резервное копирование на уровне файлов

2a) с помощью 'tar'

  • Останавливаем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl stop postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Выполняем настройку окружения:
rm -rf $backup_home
mkdir $backup_home

db_backup_file=db-backup-$file_date.tgz
  • Создаём резервную копию БД:
cd $PGDATA
tar -zcvf $backup_home/$db_backup_file *

ls $backup_home/$db_backup_file

tar -ztvf $backup_home/$db_backup_file
  • Сохраняем резервную копию БД в контейнере хранения:
az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$db_backup_file \
--name $db_backup_file

az storage blob list \
--account-name mystorageaccountent \
--container-name mydbbackup-ent-xx
  • Удаляем файлы БД и файл резервной копии БД и восстанавливаем БД из контейнера хранения:
rm -rf $PGDATA/*
ls $PGDATA/

rm $backup_home/$db_backup_file
ls $backup_home/$db_backup_file

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$db_backup_file \
--name $db_backup_file

ls $backup_home/$db_backup_file

cd $PGDATA
tar -zxvf $backup_home/$db_backup_file

ls $PGDATA

exit
  • Стартуем сервис БД Postgres Pro, проверяем его статус и выполняем тестовый SQL-запрос к БД:
sudo systemctl start postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su -l postgres -c "psql -c \"select pgpro_version(), pgpro_edition(), pgpro_build()\""

2b) с помощью 'pg_basebackup'

  • Стартуем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Выполняем настройку окружения:
rm -rf $backup_home
mkdir $backup_home

db_backup_file=db-backup-$file_date.tgz
wal_backup_file=wal-backup-$file_date.tgz
  • Создаём резервные копии БД и файлов WAL:
pg_basebackup \
--pgdata=$backup_home \
--format=tar \
--wal-method=stream \
--gzip \
--checkpoint=fast \
--label=$file_date \
--progress \
--verbose

ls $backup_home/base.tar.gz
ls $backup_home/pg_wal.tar.gz

tar -ztvf $backup_home/base.tar.gz
tar -ztvf $backup_home/pg_wal.tar.gz
  • Сохраняем резервные копии БД и файлов WAL в контейнере хранения:
az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/base.tar.gz \
--name $db_backup_file

az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/pg_wal.tar.gz \
--name $wal_backup_file

az storage blob list \
--account-name mystorageaccountent \
--container-name mydbbackup-ent-xx

exit
  • Останавливаем сервис БД Postgres Pro, удаляем файлы БД, файлы резервных копий БД и файлов WAL и восстанавливаем БД из контейнера хранения:
sudo systemctl stop postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su - postgres

rm -rf $PGDATA/*
ls $PGDATA/

rm -rf $backup_home
mkdir $backup_home

db_backup_file=$(az storage blob list --account-name mystorageaccountent --container-name mydbbackup-ent-xx | grep ^db-backup | tail -n 1 | awk {'print $1'})
wal_backup_file=$(az storage blob list --account-name mystorageaccountent --container-name mydbbackup-ent-xx | grep ^wal-backup | tail -n 1 | awk {'print $1'})

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$db_backup_file \
--name $db_backup_file

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$wal_backup_file \
--name $wal_backup_file

ls $backup_home/$db_backup_file
ls $backup_home/$wal_backup_file

cd $PGDATA
tar -zxvf $backup_home/$db_backup_file
cd $PGDATA/pg_wal
tar -zxvf $backup_home/$wal_backup_file

exit
  • Стартуем сервис БД Postgres Pro, проверяем его статус и выполняем тестовый SQL-запрос к БД:
sudo systemctl start postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su -l postgres -c "psql -c \"select pgpro_version(), pgpro_edition(), pgpro_build()\""

3) Непрерывное архивирование и восстановление на момент времени

3a) полное резервное копирование с помощью 'pg_basebackup'

  • Стартуем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Переключаем БД в режим архивирования файлов WAL:
psql -c "show archive_mode"
psql -c "show archive_command"

psql -c "alter system set archive_mode=on"
psql -c "alter system set archive_command='az storage blob upload --container-name mydbbackup-ent-xx --account-name mystorageaccountent --file %p --name %f'"

exit
  • Выполняем рестарт сервиса БД Postgres Pro, проверяем его статус и значение параметров 'archive_mode' и 'archive_command':
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su - postgres

psql -c "show archive_mode"
psql -c "show archive_command"
  • Выполняем настройку окружения:
rm -rf $backup_home
mkdir $backup_home

db_backup_file=db-backup-$file_date.tgz
wal_backup_file=wal-backup-$file_date.tgz
  • Создаём резервные копии БД и файлов WAL:
pg_basebackup \
--pgdata=$backup_home \
--format=tar \
--wal-method=stream \
--gzip \
--checkpoint=fast \
--label=$file_date \
--progress \
--verbose

ls $backup_home/base.tar.gz
ls $backup_home/pg_wal.tar.gz

tar -ztvf $backup_home/base.tar.gz
tar -ztvf $backup_home/pg_wal.tar.gz
  • Сохраняем резервные копии БД и файлов WAL в контейнере хранения:
az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/base.tar.gz \
--name $db_backup_file

az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/pg_wal.tar.gz \
--name $wal_backup_file

az storage blob list \
--account-name mystorageaccountent \
--container-name mydbbackup-ent-xx

exit
  • Останавливаем сервис БД Postgres Pro, удаляем файлы БД, файлы резервных копий БД и файлов WAL и восстанавливаем БД из контейнера хранения:
sudo systemctl stop postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su - postgres

rm -rf $PGDATA/*
ls $PGDATA/

rm -rf $backup_home
mkdir $backup_home

db_backup_file=$(az storage blob list --account-name mystorageaccountent --container-name mydbbackup-ent-xx | grep ^db-backup | tail -n 1 | awk {'print $1'})
wal_backup_file=$(az storage blob list --account-name mystorageaccountent --container-name mydbbackup-ent-xx | grep ^wal-backup | tail -n 1 | awk {'print $1'})

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$db_backup_file \
--name $db_backup_file

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $backup_home/$wal_backup_file \
--name $wal_backup_file

ls $backup_home/$db_backup_file
ls $backup_home/$wal_backup_file

cd $PGDATA
tar -zxvf $backup_home/$db_backup_file
cd $PGDATA/pg_wal
tar -zxvf $backup_home/$wal_backup_file

exit
  • Стартуем сервис БД Postgres Pro, проверяем его статус и выполняем тестовый SQL-запрос к БД:
sudo systemctl start postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su -l postgres -c "psql -c \"select pgpro_version(), pgpro_edition(), pgpro_build()\""

3b) полное резервное копирование с помощью 'pg_probackup'

  • Стартуем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Переключаем БД в режим архивирования файлов WAL:
psql -c "show archive_mode"
psql -c "show archive_command"

psql -c "alter system set archive_mode=on"
psql -c "alter system set archive_command='/opt/pgpro/ent-14/bin/pg_probackup archive-push -B $backup_home --instance $instance_name --wal-file-path %p --wal-file-name %f'"

exit
  • Выполняем рестарт сервиса БД Postgres Pro, проверяем его статус и значение параметров 'archive_mode' и 'archive_command':
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su - postgres

psql -c "show archive_mode"
psql -c "show archive_command"
  • Выполняем настройку окружения:
rm -rf $backup_home
mkdir $backup_home

db_backup_file=db-backup-$file_date.tgz

pg_probackup init -B $backup_home
pg_probackup add-instance -B $backup_home -D $PGDATA --instance $instance_name
pg_probackup show-config -B $backup_home --instance $instance_name
pg_probackup show -B $backup_home
  • Создаём полную резервную копию БД и резервную копию файлов WAL:
pg_probackup backup -B $backup_home --instance $instance_name -b FULL --progress
pg_probackup validate -B $backup_home --instance $instance_name
pg_probackup show -B $backup_home
  • Сохраняем резервные копии БД и файлов WAL в контейнере хранения:
cd $backup_home
tar -zcvf $HOME/$db_backup_file *

ls $HOME/$db_backup_file

tar -ztvf $HOME/$db_backup_file

az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $HOME/$db_backup_file \
--name $db_backup_file

az storage blob list \
--account-name mystorageaccountent \
--container-name mydbbackup-ent-xx

exit
  • Останавливаем сервис БД Postgres Pro, удаляем файлы БД, файл резервных копий БД и файлов WAL и восстанавливаем БД из контейнера хранения:
sudo systemctl stop postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su - postgres

rm -rf $PGDATA/*
ls $PGDATA/

rm -rf $backup_home
mkdir $backup_home

db_backup_file=$(az storage blob list --account-name mystorageaccountent --container-name mydbbackup-ent-xx | grep ^db-backup | tail -n 1 | awk {'print $1'})

rm $HOME/$db_backup_file
ls $HOME/$db_backup_file

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $HOME/$db_backup_file \
--name $db_backup_file

ls $HOME/$db_backup_file

cd $backup_home
tar -zxvf $HOME/$db_backup_file

backup_id=$(pg_probackup show -B $backup_home | grep $instance_name | grep FULL | awk '{print $3}')
pg_probackup restore -B $backup_home -D $PGDATA --instance $instance_name -i $backup_id --progress

exit
  • Стартуем сервис БД Postgres Pro, проверяем его статус и выполняем тестовый SQL-запрос к БД:
sudo systemctl start postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su -l postgres -c "psql -c \"select pgpro_version(), pgpro_edition(), pgpro_build()\""

3c) инкрементальное резервное копирование с помощью 'pg_probackup'

  • Стартуем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service
  • Переключаемся на пользователя ‘postgres’:
sudo su - postgres
  • Переключаем БД в режим архивирования файлов WAL:
psql -c "show archive_mode"
psql -c "show archive_command"

psql -c "alter system set archive_mode=on"
psql -c "alter system set archive_command='/opt/pgpro/ent-14/bin/pg_probackup archive-push -B $backup_home --instance $instance_name --wal-file-path %p --wal-file-name %f'"

exit
  • Выполняем рестарт сервиса БД Postgres Pro, проверяем его статус и значение параметров 'archive_mode' и 'archive_command':
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su - postgres

psql -c "show archive_mode"
psql -c "show archive_command"
  • Выполняем настройку окружения (в качестве примера используем временную базу данных):
rm -rf $backup_home
mkdir $backup_home

db_backup_file=db-backup-$file_date.tgz

pg_probackup init -B $backup_home
pg_probackup add-instance -B $backup_home -D $PGDATA --instance $instance_name
pg_probackup show-config -B $backup_home --instance $instance_name
pg_probackup show -B $backup_home
  • Создаём полную резервную копию БД и резервную копию файлов WAL:
pg_probackup backup -B $backup_home --instance $instance_name -b FULL --progress
pg_probackup validate -B $backup_home --instance $instance_name
pg_probackup show -B $backup_home
  • Создаем временную базу данных
psql -c "create database $db_name"

for ((i=1;i<=3;i++)); do
psql --dbname $db_name -c "create table test_table_0$i(id numeric)"
psql --dbname $db_name -c "insert into test_table_0$i select * from generate_series(1, 5)"
psql --dbname $db_name -c "select * from test_table_0$i"
done
  • Создаём инкрементальную резервную копию БД и резервную копию файлов WAL:
pg_probackup backup -B $backup_home --instance $instance_name -b PAGE --progress
pg_probackup validate -B $backup_home --instance $instance_name
pg_probackup show -B $backup_home
  • Сохраняем полную и инкрементальную резервные копии БД и резервную копию файлов WAL в контейнере хранения:
cd $backup_home
tar -zcvf $HOME/$db_backup_file *

ls $HOME/$db_backup_file

tar -ztvf $HOME/$db_backup_file

az storage blob upload \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $HOME/$db_backup_file \
--name $db_backup_file

az storage blob list \
--account-name mystorageaccountent \
--container-name mydbbackup-ent-xx

exit
  • Останавливаем сервис БД Postgres Pro, удаляем файлы БД, файл резервных копий БД и файлов WAL и восстанавливаем БД из контейнера хранения:
sudo systemctl stop postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su - postgres

rm -rf $PGDATA/*
ls $PGDATA/

rm -rf $backup_home
mkdir $backup_home

db_backup_file=$(az storage blob list --account-name mystorageaccountent --container-name mydbbackup-ent-xx | grep ^db-backup | tail -n 1 | awk {'print $1'})

rm $HOME/$db_backup_file
ls $HOME/$db_backup_file

az storage blob download \
--container-name mydbbackup-ent-xx \
--account-name mystorageaccountent \
--file $HOME/$db_backup_file \
--name $db_backup_file

ls $HOME/$db_backup_file

cd $backup_home
tar -zxvf $HOME/$db_backup_file

backup_id=$(pg_probackup show -B $backup_home | grep $instance_name | grep PAGE | awk '{print $3}')
pg_probackup restore -B $backup_home -D $PGDATA --instance $instance_name -i $backup_id --progress

exit
  • Стартуем сервис БД Postgres Pro, проверяем его статус и выполняем тестовый SQL-запрос к временной базе данных:
sudo systemctl start postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

sudo su - postgres

for ((i=1;i<=3;i++)); do
psql --dbname $db_name -c "select * from test_table_0$i"
done

exit

Вместо ‘xx’ используем '01', '02', '03' и т.д.


Высокая доступность БД Postgres Pro

Рассмотрим варианты обеспечения высокой доступности БД Postgres Pro (более подробная информация на https://postgrespro.ru/docs/enterprise/14/high-availability) на примере кластерного ПО Patroni (более подробная информация на https://github.com/zalando/patroni). Далее будем использовать следующие названия узлов кластера Patroni: 'myvm-ent-01', 'myvm-ent-02' и 'myvm-ent-03'.

  • Создаем ресурсную группу 'myresourcegroup':
az group create \
--name myresourcegroup \
--location northeurope
az vm availability-set create \
--name myavailabilityset \
--resource-group myresourcegroup \
--platform-fault-domain-count 3 \
--platform-update-domain-count 3
  • Создаем виртуальную локальную сеть 'myvnet' 10.0.0.0/8 и подсеть 'myvnetsubnet' 10.0.0.0/24:
az network vnet create \
--name myvnet \
--location northeurope \
--resource-group myresourcegroup \
--subnet-name myvnetsubnet \
--subnet-prefix 10.0.0.0/24 \
--address-prefixes 10.0.0.0/8
  • Создаем группу безопасности сети 'mynsg':
az network nsg create \
--name mynsg \
--location northeurope \
--resource-group myresourcegroup
  • Для группы безопасности сети 'mynsg' настраиваем правила для соответствующих TCP-портов 22 (ssh), 5433 (Postgres) и 80/443 (http/https):
array=(AllowInboundSsh 22 1000 AllowInboundPostgresql 5433 1001 AllowInboundHttp 80 1002 AllowInboundHttps 443 1003); for i in `echo 0 3 6 9`; do
az network nsg rule create \
--name "${array[$i]}" \
--resource-group myresourcegroup \
--nsg-name mynsg \
--access Allow \
--direction Inbound \
--protocol Tcp \
--destination-port-range "${array[$i+1]}" \
--priority "${array[$i+2]}"
done
  • Создаем динамические public IP-адреса для всех трех VM:
for i in `seq 1 3`; do
az network public-ip create \
--name myvm-ent-0$i-public-ip \
--location northeurope \
--resource-group myresourcegroup \
--dns-name myvm-ent-0$i-dnsname \
--sku Basic \
--allocation-method Dynamic
done
  • Создаем сетевые интерфейсы для всех трех VM и назначаем им динамические public и статические private IP-адреса:
for i in `seq 1 3`; do
az network nic create \
--name myvm-ent-0$i-nic \
--location northeurope \
--resource-group myresourcegroup \
--vnet-name myvnet \
--subnet myvnetsubnet \
--network-security-group mynsg \
--public-ip-address myvm-ent-0$i-public-ip \
--private-ip-address 10.0.0.10$i
done

Назначение private IP-адресов: 10.0.0.101 (myvm-ent-01), 10.0.0.102 (myvm-ent-02), 10.0.0.103 (myvm-ent-03).

  • Создаем три VM:
for i in `seq 1 3`; do
az vm create \
--name myvm-ent-0$i \
--resource-group myresourcegroup \
--availability-set myavailabilityset \
--image $urn_id \
--location northeurope \
--size Standard_DS1_v2 \
--ssh-key-value ~/.ssh/id_rsa.pub \
--admin-username azureuser \
--authentication-type ssh \
--nics myvm-ent-0$i-nic \
--public-ip-sku Basic \
--os-disk-name myvm-ent-0$i-osdisk
done
  • Подключаемся ко всем трем VM и выполняем одинаковый набор команд на каждой из них:
ssh azureuser@myvm-ent-01-dnsname.northeurope.cloudapp.azure.com
ssh azureuser@myvm-ent-02-dnsname.northeurope.cloudapp.azure.com
ssh azureuser@myvm-ent-03-dnsname.northeurope.cloudapp.azure.com
  • Конфигурируем сервисы БД Postgres Pro, Consul, haproxy и Patroni:
sudo systemctl disable postgrespro-ent-14.service

sudo sh -c "echo '' >> /etc/hosts"
for i in `seq 1 3`; do
sudo sh -c "echo '10.0.0.10$i myvm-ent-0$i' >> /etc/hosts"
done

sudo sed -i "/retry_join/s|\[\]|\[\"myvm-ent-01\", \"myvm-ent-02\", \"myvm-ent-03\"\]|" /etc/consul.d/consul.hcl
sudo sed -i "s|# retry_join|retry_join|" /etc/consul.d/consul.hcl

sudo systemctl daemon-reload; sudo systemctl enable consul.service; sudo systemctl start consul.service; sudo systemctl -l status consul.service

for i in `seq 1 3`; do
sudo sh -c "echo ' server myvm-ent-0$i 10.0.0.10$i:5433 maxconn 100 check port 8008' >> /etc/haproxy/haproxy.cfg"
done

sudo systemctl daemon-reload; sudo systemctl enable haproxy; sudo systemctl start haproxy; sudo systemctl -l status haproxy

sudo sed -i "s|# name:|name: $HOSTNAME|" /etc/patroni/config.yml
sudo sed -i "/connect_address/s|127.0.0.1|`hostname -i`|" /etc/patroni/config.yml
  • На первой VM выполняем следующие команды:
sudo su - postgres

psql -c "alter system set wal_level to 'replica'"
psql -c "alter system set hot_standby to 'on'"
psql -c "alter system set wal_keep_segments to '8'"
psql -c "alter system set max_wal_senders to '5'"
psql -c "alter system set max_replication_slots to '5'"
psql -c "alter system set checkpoint_timeout to '30'"

psql -c "create user patroni_replicator with replication encrypted password 'replicatorpassword'"
psql -c "create user patroni_superuser with superuser encrypted password 'superuserpassword'"

for i in `seq 1 3`; do
sed -i "/^host all.*md5/i host replication patroni_replicator myvm-ent-0$i md5" $PGDATA/pg_hba.conf
done

for i in `seq 1 3`; do
echo "myvm-ent-0$i:5433:replication:patroni_replicator:replicatorpassword" >> ~/.pgpass
done
chmod 0600 ~/.pgpass

exit

sudo systemctl restart postgrespro-ent-14.service
  • На второй и третьей VM выполняем следующие команды:
sudo systemctl stop postgrespro-ent-14.service

sudo su - postgres

rm -rf $PGDATA/*

for i in `seq 1 3`; do
echo "myvm-ent-0$i:5433:replication:patroni_replicator:replicatorpassword" >> ~/.pgpass
done
chmod 0600 ~/.pgpass

exit
  • На первой VM стартуем сервис Patroni:
sudo systemctl daemon-reload; sudo systemctl enable patroni.service; sudo systemctl start patroni.service; sudo systemctl -l status patroni.service
sudo patronictl -c /etc/patroni/config.yml restart mypatroni myvm-ent-01
  • На второй и третьей VM стартуем сервис Patroni:
sudo systemctl daemon-reload; sudo systemctl enable patroni.service; sudo systemctl start patroni.service; sudo systemctl -l status patroni.service
  • Для проверки состояния кластера Patroni и БД Postgres Pro следующие команды:
sudo patronictl -c /etc/patroni/config.yml list

psql 'postgres://patroni_superuser:superuserpassword@myvm-ent-01:5000/postgres' -x -c 'table pg_stat_replication'
psql 'postgres://patroni_superuser:superuserpassword@myvm-ent-02:5000/postgres' -x -c 'table pg_stat_replication'
psql 'postgres://patroni_superuser:superuserpassword@myvm-ent-03:5000/postgres' -x -c 'table pg_stat_replication'
  • Для возврата в интерфейс Azure CLI 2.x дважды выполняем команду 'exit'


Postgres Pro Enterprise Multimaster

Multimaster - это расширение Postgres Pro Enterprise, которое в сочетании с набором доработок ядра превращает Postgres Pro Enterprise в синхронный кластер без разделения ресурсов, обеспечивающий расширяемость OLTP для читающих транзакций, а также высокую доступность с автоматическим восстановлением после сбоев.

Более подробная информация о Multimaster доступна по ссылкам:

https://postgrespro.ru/docs/enterprise/14/multimaster

Рассмотрим процесс установки и настройки трехузлового Multimaster. Далее будем использовать следующие названия узлов Multimaster: 'myvm-ent-01', 'myvm-ent-02' и 'myvm-ent-03'.

  • Создаем ресурсную группу 'myresourcegroup':
az group create \
--name myresourcegroup \
--location northeurope
az vm availability-set create \
--name myavailabilityset \
--resource-group myresourcegroup \
--platform-fault-domain-count 3 \
--platform-update-domain-count 3
  • Создаем виртуальную локальную сеть 'myvnet' 10.0.0.0/8 и подсеть 'myvnetsubnet' 10.0.0.0/24:
az network vnet create \
--name myvnet \
--location northeurope \
--resource-group myresourcegroup \
--subnet-name myvnetsubnet \
--subnet-prefix 10.0.0.0/24 \
--address-prefixes 10.0.0.0/8
  • Создаем группу безопасности сети 'mynsg':
az network nsg create \
--name mynsg \
--location northeurope \
--resource-group myresourcegroup
  • Для группы безопасности сети 'mynsg' настраиваем правила для соответствующих TCP-портов 22 (ssh), 5433 (Postgres) и 80/443 (http/https):
array=(AllowInboundSsh 22 1000 AllowInboundPostgresql 5433 1001 AllowInboundHttp 80 1002 AllowInboundHttps 443 1003); for i in `echo 0 3 6 9`; do
az network nsg rule create \
--name "${array[$i]}" \
--resource-group myresourcegroup \
--nsg-name mynsg \
--access Allow \
--direction Inbound \
--protocol Tcp \
--destination-port-range "${array[$i+1]}" \
--priority "${array[$i+2]}"
done
  • Создаем динамические public IP-адреса для всех трех VM:
for i in `seq 1 3`; do
az network public-ip create \
--name myvm-ent-0$i-public-ip \
--location northeurope \
--resource-group myresourcegroup \
--dns-name myvm-ent-0$i-dnsname \
--sku Basic \
--allocation-method Dynamic
done
  • Создаем сетевые интерфейсы для всех трех VM и назначаем им динамические public и статические private IP-адреса:
for i in `seq 1 3`; do
az network nic create \
--name myvm-ent-0$i-nic \
--location northeurope \
--resource-group myresourcegroup \
--vnet-name myvnet \
--subnet myvnetsubnet \
--network-security-group mynsg \
--public-ip-address myvm-ent-0$i-public-ip \
--private-ip-address 10.0.0.10$i
done

Назначение private IP-адресов: 10.0.0.101 (myvm-ent-01), 10.0.0.102 (myvm-ent-02), 10.0.0.103 (myvm-ent-03).

  • Создаем три VM:
for i in `seq 1 3`; do
az vm create \
--name myvm-ent-0$i \
--resource-group myresourcegroup \
--availability-set myavailabilityset \
--image $urn_id \
--location northeurope \
--size Standard_DS1_v2 \
--ssh-key-value ~/.ssh/id_rsa.pub \
--admin-username azureuser \
--authentication-type ssh \
--nics myvm-ent-0$i-nic \
--public-ip-sku Basic \
--os-disk-name myvm-ent-0$i-osdisk
done
  • Подключаемся ко всем трем VM и выполняем одинаковый набор команд на каждой из них:
ssh azureuser@myvm-ent-01-dnsname.northeurope.cloudapp.azure.com
ssh azureuser@myvm-ent-02-dnsname.northeurope.cloudapp.azure.com
ssh azureuser@myvm-ent-03-dnsname.northeurope.cloudapp.azure.com
  • Конфигурируем реплицируемую БД 'mydb':
sudo su - postgres
psql -c "create user myuser with superuser encrypted password 'myuserpassword'"
psql --username=myuser -c "create database mydb"
sed -i 's/PGDATABASE=postgres/PGDATABASE=mydb/' .pgpro_profile
sed -i 's/PGUSER=postgres/PGUSER=myuser/' .pgpro_profile
source .pgpro_profile

for i in `seq 1 3`; do
echo "hostssl replication myuser myvm-ent-0$i md5" >> $PGDATA/pg_hba.conf
echo "myvm-ent-0$i:5433:mydb:myuser:myuserpassword" >> ~/.pgpass
done
chmod 0600 ~/.pgpass
pg_ctl reload

echo "" >> $PGDATA/postgresql.conf
echo "" >> $PGDATA/postgresql.conf
echo "#------------------------------------------------------------------------------" >> $PGDATA/postgresql.conf
echo "# MULTIMASTER SETTINGS" >> $PGDATA/postgresql.conf
echo "#------------------------------------------------------------------------------" >> $PGDATA/postgresql.conf
echo "" >> $PGDATA/postgresql.conf
echo "multimaster.max_nodes = 3" >> $PGDATA/postgresql.conf
echo "" >> $PGDATA/postgresql.conf
echo "" >> $PGDATA/postgresql.conf

psql -c "alter system set default_transaction_isolation to 'read committed'"
psql -c "alter system set wal_level to logical"
psql -c "alter system set max_connections to 100"
psql -c "alter system set max_prepared_transactions to 300"
psql -c "alter system set max_wal_senders to 10"
psql -c "alter system set max_replication_slots to 10"
psql -c "alter system set max_worker_processes to 250"
psql -c "alter system set shared_preload_libraries to multimaster,pg_stat_statements,pg_buffercache,pg_wait_sampling"

psql -c "alter system set wal_sender_timeout to 0"

exit
  • Конфигурируем агент mamonsu для БД 'mydb' и перезапускаем сервис mamonsu:
sudo sed -i 's|user = mamonsu|user = myuser|' /etc/mamonsu/agent.conf
sudo sed -i 's|database = mamonsu|database = mydb|' /etc/mamonsu/agent.conf
sudo systemctl restart mamonsu.service
  • Перезапускаем сервис БД Postgres Pro и проверяем его статус:
sudo systemctl restart postgrespro-ent-14.service
sudo systemctl -l status postgrespro-ent-14.service

exit
  • Подключаемся к первой VM:
ssh azureuser@myvm-ent-01-dnsname.northeurope.cloudapp.azure.com
  • и создаем расширение Multimaster:
sudo su - postgres
psql
create extension if not exists multimaster;
select mtm.init_cluster('dbname=mydb user=myuser host=myvm-ent-01 port=5433 sslmode=require','{"dbname=mydb user=myuser host=myvm-ent-02 port=5433 sslmode=require", "dbname=mydb user=myuser host=myvm-ent-03 port=5433 sslmode=require"}');
\q
  • Создаем другие расширения для сервиса mamonsu:
psql -c "create extension if not exists pg_buffercache"
psql -c "create extension if not exists pg_stat_statements"
psql -c "create extension if not exists pg_wait_sampling"
  • Проверяем, что все расширения были успешно созданы:
psql --host=myvm-ent-01 -c "select * from pg_extension"
psql --host=myvm-ent-02 -c "select * from pg_extension"
psql --host=myvm-ent-03 -c "select * from pg_extension"
  • Конфигурируем mamonsu для Multimaster:
mamonsu bootstrap --dbname mydb --username postgres --host 127.0.0.1 --port 5433 --mamonsu-username=myuser
psql --host=myvm-ent-01 -c "select mtm.make_table_local('mamonsu_config')"
psql --host=myvm-ent-01 -c "select mtm.make_table_local('mamonsu_timestamp_master_2_7_1')"
  • Для проверки состояния Multimaster используем следующие команды:
psql --host=myvm-ent-01 -x -c "select mtm.status()"
psql --host=myvm-ent-02 -x -c "select mtm.status()"
psql --host=myvm-ent-03 -x -c "select mtm.status()"

psql --host=myvm-ent-01 -x -c "select mtm.nodes()"
psql --host=myvm-ent-02 -x -c "select mtm.nodes()"
psql --host=myvm-ent-03 -x -c "select mtm.nodes()"
  • Для возврата в интерфейс Azure CLI 2.x дважды выполняем команду 'exit'


Внешнее подключение к БД Postgres Pro Enterprise Multimaster

Рассмотрим вариант подключения к БД Postgres Pro Enterprise Multimaster через балансировщик нагрузки Azure.

Более подробная информация о балансировщике нагрузки Azure доступна на https://docs.microsoft.com/ru-ru/azure/load-balancer/load-balancer-overview.

  • Сначала создаем публичный IP-адрес 'myvm-ent-lb-public-ip' и DNS-имя 'myvm-ent-lb-dnsname' для балансировщика:
az network public-ip create \
--name myvm-ent-lb-public-ip \
--dns-name myvm-ent-lb-dnsname \
--resource-group myresourcegroup
  • Создаем сам балансировщик 'myloadbalancer':
az network lb create \
--name myloadbalancer \
--resource-group myresourcegroup \
--frontend-ip-name myFrontEndPool \
--backend-pool-name myBackEndPool \
--public-ip-address myvm-ent-lb-public-ip
  • Создаем проверку 'PostgresqlHealthProbe' сервиса БД Postgres Pro для балансировщика:
az network lb probe create \
--name PostgresqlHealthProbe \
--lb-name myloadbalancer \
--resource-group myresourcegroup \
--protocol tcp \
--port 5433
  • Создаем правило балансировки нагрузки БД Postgres Pro 'PostgresqlLoadBalancerRule' между узлами Multimaster VM:
az network lb rule create \
--name PostgresqlLoadBalancerRule \
--lb-name myloadbalancer \
--probe-name PostgresqlHealthProbe \
--resource-group myresourcegroup \
--protocol tcp \
--frontend-port 5433 \
--backend-port 5433 \
--frontend-ip-name myFrontEndPool \
--backend-pool-name myBackEndPool
  • Добавляем узлы Multimaster к конфигурации балансировщика:
for i in `seq 1 3`; do
ipconfig_id=$(az network nic list --resource-group myresourcegroup --output tsv --query "[?starts_with(name,'myvm-ent-0$i')].[ipConfigurations[0].name]")
az network nic ip-config address-pool add \
--nic-name myvm-ent-0$i-nic \
--ip-config-name $ipconfig_id \
--lb-name myloadbalancer \
--resource-group myresourcegroup \
--address-pool myBackEndPool
done
  • Подключаемся к БД Postgres Pro Enterprise Multimaster через балансировщик:
psql --host=myvm-ent-lb-dnsname.northeurope.cloudapp.azure.com --port=5433 --user=myuser --dbname=mydb


Postgres Pro Enterprise Multimaster (2-х узловой кластер + голосующий узел)

3-х узловой Multimaster требует тройной объем дискового пространства для базы данных. Возможно использовать 2-х узловой Multimaster, назначив одному из узлов дополнительный голос на случай потери связи между узлами (multimaster.major_node=on), или, заменив один из узлов Multimaster на голосующий узел, требующий значительно меньший объем дискового пространства для базы данных.

Рассмотрим изменение конфигурации Multimaster из 3-х узлового в 2-х узловой кластер + голосующий узел.

  • Исключаем узел 'myvm-ent-03' из конфигурации Multimaster, удаляем все настройки, связанные с Multimster на этом узле и меняем настройки Multimster на узлах 'myvm-ent-01' и 'myvm-ent-02':
sudo su - postgres
sed -i '/multimaster/d' $PGDATA/postgresql.conf
psql --host=myvm-ent-03 -c "alter system set shared_preload_libraries to pg_stat_statements,pg_buffercache,pg_wait_sampling"
psql --host=myvm-ent-01 -c "select mtm.drop_node(3)"
psql --host=myvm-ent-01 -x -c "select mtm.nodes()"
psql --host=myvm-ent-01 -c "alter system set multimaster.referee_connstring = 'dbname=mydb user=myuser host=myvm-ent-03 port=5433 sslmode=require'"
psql --host=myvm-ent-02 -c "alter system set multimaster.referee_connstring = 'dbname=mydb user=myuser host=myvm-ent-03 port=5433 sslmode=require'"
exit

sudo systemctl restart postgrespro-ent-14.service

sudo su - postgres
psql --host=myvm-ent-03 -c "drop extension multimaster"
psql --host=myvm-ent-03 -c "drop publication if exists multimaster"
psql --host=myvm-ent-03 -c "create extension referee"
exit

sudo systemctl restart postgrespro-ent-14.service
  • Применяем новые настройки Multimster на узлах 'myvm-ent-01' и 'myvm-ent-02':
sudo systemctl restart postgrespro-ent-14.service
  • Удаляем слоты репликации и завершаем конфигурацию настроек на узле 'myvm-ent-03':
sudo su - postgres
sed -i '/^#/!d' $PGDATA/postgresql.auto.conf
echo "shared_preload_libraries = 'pg_stat_statements, pg_buffercache, pg_wait_sampling'" >> $PGDATA/postgresql.auto.conf
psql --host=myvm-ent-03 -c "select pg_drop_replication_slot('mtm_slot_1')"
psql --host=myvm-ent-03 -c "select pg_drop_replication_slot('mtm_filter_slot_1')"
psql --host=myvm-ent-03 -c "select pg_drop_replication_slot('mtm_slot_2')"
psql --host=myvm-ent-03 -c "select pg_drop_replication_slot('mtm_filter_slot_2')"
psql --host=myvm-ent-03 -c "select pg_replication_origin_drop('mtm_slot_1')"
psql --host=myvm-ent-03 -c "select pg_replication_origin_drop('mtm_slot_2')"
exit

sudo systemctl restart postgrespro-ent-14.service
  • Проверяем статус Multimaster на каждом узле:
sudo su - postgres
psql --dbname=mydb --username=myuser --host=myvm-ent-01 --port=5433 -x -c "select mtm.nodes()"
psql --dbname=mydb --username=myuser --host=myvm-ent-02 --port=5433 -x -c "select mtm.nodes()"
psql --dbname=mydb --username=myuser --host=myvm-ent-03 --port=5433 -c "select * from referee.decision"
exit


Postgres Pro Enterprise CFS (сжатая файловая система):

Для использования возможностей расширения Postgres Pro Enterprise CFS (сжатая файловая система) необходимо выполнить следующие действия.

  • На файловой системе создаем директорию для табличного пространства 'cfs_ts' и табличное пространство 'cfs_ts' в базе данных: 
sudo su - postgres
mkdir $PGDATA/../cfs_ts
chmod 0700 $PGDATA/../cfs_ts
psql -c "create tablespace cfs_ts location '/var/lib/pgpro/ent-14/cfs_ts' with (compression=true)"
exit
  • Проверяем, что табличное пространство 'cfs_ts' создано с опцией 'compression=true' option: 
sudo su - postgres
psql -c "select * from pg_tablespace"
exit

Используем табличное пространство 'cfs_ts' для новых объектов БД:

  • При создании объекта БД: 
sudo su - postgres
psql -c "create table t1 (t int) tablespace cfs_ts"
psql -c "select tablename, tablespace from pg_tables where schemaname = 'public'"
exit
  • Установив табличное пространство по умолчанию для текущего подключения к БД: 
sudo su - postgres
psql
set default_tablespace=cfs_ts;
show default_tablespace;
create table t2 (t int);
select tablename, tablespace from pg_tables where schemaname = 'public';
\q
exit
  • Установив табличное пространство по умолчанию для БД: 
sudo su - postgres
psql --dbname=postgres -c "alter database mydb set tablespace cfs_ts"
psql -c "select datname, dattablespace from pg_database"
exit
  • Установив табличное пространство по умолчанию для пользователя/роли: 
sudo su - postgres
psql --username=postgres -c "alter user myuser set default_tablespace to 'cfs_ts'"
psql -c "select usename, useconfig from pg_user"
psql -c "select rolname, rolconfig from pg_roles"
exit

Переносим существующие объекты БД из одного табличного пространства ('pg_default') в другое ('cfs_ts'):

  • По одному:
sudo su - postgres
psql -c "create table t3 (t int)"
psql -c "alter table t3 set tablespace cfs_ts"
psql -c "select tablename, tablespace from pg_tables where schemaname = 'public'"
exit
  • Все вместе:
sudo su - postgres
psql -c "alter table all in tablespace pg_default set tablespace cfs_ts"
psql -c "select tablename, tablespace from pg_tables where schemaname = 'public'"
exit

В зависимости от данных, хранимых в табличном пространстве 'cfs_ts', коэффициент сжатия может варьироваться.


Состав Postgres Pro Enterprise (VM):

ОС - Linux CentOS 7.x (64-бит)

  • учетная запись 'postgres'
  • учетная запись 'zabbix'
  • учетная запись 'mamonsu'

Размер ОС-диска - 30 ГБ

  • файловая система xfs ‘/boot’ (/dev/sda1) - 1 ГБ
  • файловая система xfs ‘/’ (/dev/sda2) - 29 ГБ

Основная БД Postgres Pro Enterprise

  • версия БД: 9.6/10/11/12/13/14
  • TCP-порт: 5433 (открыт на firewall)
  • конфигурация: /var/lib/pgsql/.pgpro_profile
  • учетная запись: 'postgres'

Мониторинг БД (сервер)

  • версия zabbix-server: 4.x
  • TCP-порты: 80/443 (открыт на firewall)
  • учетная запись: 'Admin'

Мониторинг БД (агент)

  • версия zabbix-agent: 4.x
  • версия mamonsu-agent: 2.x
  • конфигурация: /etc/mamonsu/agent.conf

Вспомогательная БД PostgreSQL (в качестве БД для zabbix-server)

  • версия БД: 10/11/12/13/14
  • TCP-порт: 5432
  • конфигурация: /var/lib/pgsql/.pgsql_profile
  • учетная запись: 'postgres'


Ссылки на документацию