Skip to content

Instantly share code, notes, and snippets.

@maxstarkov
Last active December 9, 2022 12:16
Show Gist options
  • Save maxstarkov/9b0d03a441639eba36fa754e4fa82fd9 to your computer and use it in GitHub Desktop.
Save maxstarkov/9b0d03a441639eba36fa754e4fa82fd9 to your computer and use it in GitHub Desktop.
ZFS + MS SQL on Linux / Postgres + Onec

Тестовый стенд "ZFS + MS SQL on Linux (PostgreSQL) + 1C"

Подготовка

Тестовый пример использует виртуальную машину на базе операционной системы ubuntu 20.04. Предполагается, что к виртуальной машине дополнительно подключены три виртуальных диска размером 5 ГБ каждый.

Создать подобную виртуальную машину можно вручную, с помощью любого гипервизора или облачного провайдера.

Особенно удобно использовать vagrant и гипервизор qemu-kvm. Пример Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  config.ssh.insert_key = false

  config.vm.define :ubuntu_zfs do |ubuntu_zfs|

    ubuntu_zfs.vm.box = "generic/ubuntu2004"

    ubuntu_zfs.vm.network :private_network, :ip => "192.168.111.10"

    ubuntu_zfs.vm.provider :libvirt do |lv|
      lv.memory = "4096"
      lv.cpus = 2
      lv.storage_pool_name = "vm"
      lv.storage :file, :size => '5G', :type => 'raw'
      lv.storage :file, :size => '5G', :type => 'raw'
      lv.storage :file, :size => '5G', :type => 'raw'
    end

  end

end

Перед выполнением следующих команд нужно подключиться к виртуальной машине через ssh.

Установка ZFS

В тестовой среде будем выполнять все действия от root'а:

sudo -i

Обновим данные репозиториев:

apt update

Установим ZFS:

apt install -y zfsutils-linux

Проверим установку:

zfs --version

zfs-0.8.3-1ubuntu12.13
zfs-kmod-0.8.3-1ubuntu12.12

lsmod | grep zfs

zfs                  4034560  6
...

Все пакеты и модуль ядра успешно установлены.

Создание простого raidz pool

К тестовой ВМ должны быть подключены три диска, каждый размером в 5 ГБ. Этого хватит для примера. Посмотрим на блочные устройства доступные в системе:

lsblk

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
vda    252:0    0   128G  0 disk 
├─vda1 252:1    0   487M  0 part /boot
├─vda2 252:2    0   1.9G  0 part [SWAP]
└─vda3 252:3    0 125.6G  0 part /
vdb    252:16   0     5G  0 disk 
vdc    252:32   0     5G  0 disk 
vdd    252:48   0     5G  0 disk

Имена блочных устройств (дисков) могут различаться в зависимости от гипервизора/облачного провайдера. В примере все команды выполняются в вирутальной машине созданной с помощью гипервизора qemu-kvm.

Блочные устройства vdb, vdc, vdd готовы для использования. Создадим из этих дисков простой pool с одним vdev вида raidz и укажем его имя storage:

zpool create storage raidz /dev/vdb /dev/vdc /dev/vdd

Проверим результат командой zpool list:

zpool list

NAME      SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
storage  14.5G   208K  14.5G        -         -     0%     0%  1.00x    ONLINE  -

Pool создан, проверим его статус командой zpool status:

zpool status

  pool: storage
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            vdb     ONLINE       0     0     0
            vdc     ONLINE       0     0     0
            vdd     ONLINE       0     0     0

errors: No known data errors

Pool уже готов для использования как dataset и примонтирован в корне файловой системы хоста.

Проверим datasets командой:

zfs list

NAME      USED  AVAIL     REFER  MOUNTPOINT
storage   113K  9.36G     30.6K  /storage

Понимание доступного и занятого пространства в zpool

Более подробно о показателях размера в выводе команд zpool и zfs:

  • SIZE в zpool это общая емкость пула, равная сумме емкостей всех виртуальных устройств верхнего уровня.
  • ALLOC в zpool это объем пространства, распределяемый между всеми наборами данных и внутренними метаданными. Следует отметить, что этот объем отличается от объема пространства на уровне файловой системы.
  • FREE в zpool это объем нераспределенного пространства в пуле. И оно отличается от AVAIL в zfs.
  • AVAIL в zfs показывает, сколько новых данных может быть записано в файловую систему (dataset или volume).

FREE в zpool обычно НЕ используется для точного определения доступного пространства, оно может быть больше AVAIL в zfs.

В колонке AVAIL команды zfs list выводится точное значение доступного пространства, но выделить можно больше - до FREE в zpool list. Однако выделить не значит фактически использовать для размещения данных.

В примере создан vdev raidz который почти аналогичен классическому raid-5. Три диска по 5 ГБ в raid-5 могут обеспечить примерно 10 ГБ доступного пространства ( 5 ГБ x 3 - 5 ГБ ). AVAIL в zfs равен 9,36 ГБ, что почти в точности равно предполагаемому размеру в 10 ГБ. Разница в 0.33 ГБ задействована для внутренних структур данных zfs. В тестовом примере разница существена из-за небольших размеров дисков - на реальных дисках доля служебных данных будет меньше.

Установка MS SQL on Linux

Для установки MS SQL on Linux нужно выполнить команды:

# Импортируйте открытые ключи GPG из репозитория:
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | apt-key add -

# Зарегистрируйте репозиторий Microsoft SQL Server Ubuntu для SQL Server 2019:
add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/20.04/mssql-server-2019.list)"

# Выполните следующие команды для установки SQL Server:
apt-get update
apt-get install -y mssql-server

# Выполните команду mssql-conf setup и следуйте указаниям, чтобы задать пароль системного администратора и выбрать выпуск:
/opt/mssql/bin/mssql-conf setup

При установке нужно выбрать developer edition. В текущем тестовом примере установим пароль 1qaZ@wsx для логина sa. Запишем пароль в переменную окружения:

export SA=1qaZ@wsx

Проверим, что установка выполнена успешно:

systemctl status mssql-server --no-pager

● mssql-server.service - Microsoft SQL Server Database Engine
     Loaded: loaded (/lib/systemd/system/mssql-server.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2021-11-01 18:52:19 UTC; 2min 17s ago
       Docs: https://docs.microsoft.com/en-us/sql/linux
   Main PID: 5713 (sqlservr)
      Tasks: 131
     Memory: 594.2M
     CGroup: /system.slice/mssql-server.service
             ├─5713 /opt/mssql/bin/sqlservr
             └─5789 /opt/mssql/bin/sqlservr

...

Установим утилиты командной строки (sqlcmd, bcp):

# Импортируйте открытые ключи GPG из репозитория.
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -

# Зарегистрируйте репозиторий Ubuntu для Майкрософт.
curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/msprod.list

# Обновите список источников и выполните команду установки с помощью пакета разработчика unixODBC.
apt-get update 
apt-get install -y mssql-tools unixodbc-dev

Проверим работоспособность MS SQL on Linux:

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA -Q 'select @@version;'

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2019 (RTM-CU13) (KB5005679) - 15.0.4178.1 (X64) 
        Sep 23 2021 16:47:49 
        Copyright (C) 2019 Microsoft Corporation
        Developer Edition (64-bit) on Linux (Ubuntu 20.04.3 LTS) <X64>                                                                                                      

(1 rows affected)

ZFS + MS SQL on Linux

MS SQL on Linux поддерживает работу только с файловыми системами ext и xfs. Поддержки zfs нет. Как быть?

ZFS позволяет выделить из pool так называемый volume. Volumes это блочные устройства которые можно разметить любой файловой системой и работать с ними как с обычными дисками.

В pool'е storage создадим volume mssql_src_db размером 2 ГБ:

zfs create -V 2G -b 8k storage/mssql_src_db

Флаг V в команде zfs create означает что будет создан volume размером 2 ГБ. Флаг b в команде zfs create означает что операции IO для volume будут выполняться блоками по 8 КБ. Имя volume - mssql_src_db. Имена volume и dataset указываются в формате ZPOOL_NAME/DATASET_OR_VOLUME_NAME.

Включим сжатие lz4 для volume mssql_src_db:

zfs set compression=lz4 storage/mssql_src_db

Разметим файловую систему ext4 на volume mssql_src_db:

mkfs.ext4 -b 4096 /dev/zvol/storage/mssql_src_db

Флаг b в команде mkfs.xfs означает размер блока файловой системы ext4, рекомендуемое значение 4096.

Проверим результат:

lsblk -f

NAME   FSTYPE LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINT
zd0    ext4         c7a3ae90-4108-4719-9c4f-0f6a77f4af98                
vda                                                                     
├─vda1 ext4         ef8245cf-baec-46c7-adc4-ad0ee0a6e2f7  222.1M    44% /boot
├─vda2 swap         68cef03d-e5b8-4d60-8a6c-9640fdb861f4                [SWAP]
└─vda3 ext4         13cb4f45-0200-4a2d-ae97-982912dde004  112.2G     4% /
vdb                                                                     
├─vdb1                                                                  
└─vdb9                                                                  
vdc                                                                     
├─vdc1                                                                  
└─vdc9                                                                  
vdd                                                                     
├─vdd1                                                                  
└─vdd9

Появилось новое блочное устройство zd0 размером 2 ГБ с файловой системой ext4. Его можно использовать как диск для MS SQL on Linux. Блочное устройство zd0 так же доступно в каталоге dev по пути /dev/zvol/storage/mssql_src_db. Работать с блочными устройствами по такому пути удобно - путь содержит имя pool'а и имя volume.

Создадим каталог /mnt/mssql/mssql_src_db в который примонтируем блочное устройство zd0:

mkdir -p /mnt/mssql/mssql_src_db

Смонтируем блочное устройство через systemd mount unit. Текст unitа:

[Unit]
Description=Mount zfs volume with ext4 filesystem

[Mount]
What=/dev/zvol/storage/mssql_src_db
Where=/mnt/mssql/mssql_src_db

Type=ext4

Options=noatime,nodiratime

[Install]
WantedBy=multi-user.target

Юниты в systemd имеют формат INI файлов. В секции Mount нужно указать что монтируем - What и куда монтируем - Where. В параметре Type указывается тип файловой системы - ext4. В параметре Options указываются дополнительные опции монтирования - для произодительности запретим обновление времени доступа к файлам и каталогам.

Для systemd важно называть mount-unit'ы по пути монтирования, заменяя символы "/" на "-".

Создаем файл юнита с помощью консольного редактора vim (можно использовать любой другой):

vim /etc/systemd/system/mnt-mssql-mssql_src_db.mount

Файл юнита должен иметь следующее содержание:

[Unit]
Description=Mount zfs volume with ext4 filesystem

[Mount]
What=/dev/zvol/storage/mssql_src_db
Where=/mnt/mssql/mssql_src_db

Type=ext4

Options=noatime,nodiratime

[Install]
WantedBy=multi-user.target

Запсукаем mount unit:

systemctl enable --now mnt-mssql-mssql_src_db.mount 

Created symlink /etc/systemd/system/multi-user.target.wants/mnt-mssql-mssql_src_db.mount → /etc/systemd/system/mnt-mssql-mssql_src_db.mount.

Проверяем успешность запуска mount unit:

systemctl status mnt-mssql-mssql_src_db.mount --no-pager 

● mnt-mssql-mssql_src_db.mount - Mount zfs volume with ext4 filesystem
     Loaded: loaded (/etc/systemd/system/mnt-mssql-mssql_src_db.mount; enabled; vendor preset: enabled)
     Active: active (mounted) since Tue 2021-11-02 14:27:55 UTC; 4min 41s ago
      Where: /mnt/mssql/mssql_src_db
       What: /dev/zd0
      Tasks: 0 (limit: 4617)
     Memory: 132.0K
     CGroup: /system.slice/mnt-mssql-mssql_src_db.mount

Nov 02 14:27:55 ubuntu2004.localdomain systemd[1]: Mounting Mount zfs volume with ext4 filesystem...
Nov 02 14:27:55 ubuntu2004.localdomain systemd[1]: Mounted Mount zfs volume with ext4 filesystem.

Проверяем результат монтирования:

lsblk -f

NAME   FSTYPE LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINT
zd0    ext4         c7a3ae90-4108-4719-9c4f-0f6a77f4af98    1.8G     0% /mnt/mssql/mssql_src_db

Проверяем параметры доступа к каталогу:

ls -la /mnt/mssql/mssql_src_db/
total 24
drwxr-xr-x 3 root root  4096 Nov  2 12:27 .
drwxr-xr-x 3 root root  4096 Nov  2 12:35 ..
drwx------ 2 root root 16384 Nov  2 12:27 lost+found

Необходимо исправить параметры доступа, так как работа выполнялась из под root'а. Сервис MS SQL on Linux работает от имени пользователя mssql, для которого есть группа mssql.

Изменим владельца каталога с root на mssql:

chown -R mssql:mssql /mnt/mssql/mssql_src_db/

Проверим изменение параметров доступа:

ls -la /mnt/mssql/mssql_src_db/
total 24
drwxr-xr-x 3 mssql mssql  4096 Nov  2 12:27 .
drwxr-xr-x 3 root  root   4096 Nov  2 12:35 ..
drwx------ 2 mssql mssql 16384 Nov  2 12:27 lost+found

Теперь нам доступен "диск" размером в 2 ГБ с файловой системой ext4, которая поддерживается MS SQL on Linux.

Cоздаем в каталоге /mnt/mssql/mssql_src_db пустую базу данных. Сделать это можно через SQL Server Managment Studio (SSMS), а можно скриптом через sqlcmd.

В консольном редакторе vim создадим скрипт:

vim create_src_db.sql

Файл скрипта должен иметь следующее содержание:

USE master;
GO

CREATE DATABASE [src_db]
ON
( NAME = src_db,
  FILENAME = N'/mnt/mssql/mssql_src_db/src_db.mdf',
  SIZE = 100 )
LOG ON
( NAME = src_db_log,
  FILENAME = N'/mnt/mssql/mssql_src_db/src_db_log.ldf',
  SIZE = 8 );
GO

ALTER DATABASE [src_db] SET RECOVERY SIMPLE;
GO

Выполним скрипт через sqlcmd:

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA -i create_src_db.sql

Проверим создание базы данных выполнив запрос через sqlcmd:

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA -Y 30 -Q "select name from sys.databases where name = 'src_db';"
name                          
------------------------------
src_db                        

(1 rows affected)

Проверим наличие файлов базы данных в каталоге /mnt/mssql/mssql_src_db:

ls -la /mnt/mssql/mssql_src_db/

total 1056796
drwxr-xr-x 3 mssql mssql       4096 Nov  2 14:54 .
drwxr-xr-x 3 root  root        4096 Nov  2 12:35 ..
drwx------ 2 mssql mssql      16384 Nov  2 12:27 lost+found
-rw-rw---- 1 mssql mssql    8388608 Nov  2 14:54 src_db_log.ldf
-rw-rw---- 1 mssql mssql 1073741824 Nov  2 14:54 src_db.mdf

База данных успешно создана.

ZFS + MS SQL on Linux + 1С

Подключим ранее созданную базу данных к серверу 1С под управлением операционной системы windows и загрузим в неё демонстрационную базу БСП.

Узнаем размер полученной базы данных с разных точек зрения.

В консольном редакторе vim создадим скрипт:

vim space_used_db.sql

Файл скрипта должен иметь следующее содержание:

USE src_db;  
GO  
EXEC sp_spaceused @updateusage = N'TRUE';  
GO

Выполним скрипт через sqlcmd:

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA -Y 30 -i space_used_db.sql

Changed database context to 'src_db'.
 
database_name                  database_size      unallocated space 
------------------------------ ------------------ ------------------
src_db                         428.00 MB          15.24 MB          
reserved           data               index_size         unused            
------------------ ------------------ ------------------ ------------------
348936 KB          151648 KB          53392 KB           143896 KB

С точки зрения MS SQL Server полный размер базы 428 МБ.

Выполнив следующую команду, узнаем размер базы данных относительно файловой системы ext4 на volume mssql_src_db:

ll /mnt/mssql/mssql_src_db/
total 438396
drwxr-xr-x 3 mssql mssql      4096 Nov  6 18:04 ./
drwxr-xr-x 3 root  root       4096 Nov  2 17:45 ../
drwx------ 2 mssql mssql     16384 Nov  6 18:03 lost+found/
-rw-rw---- 1 mssql mssql  75497472 Nov  6 18:12 src_db_log.ldf
-rw-rw---- 1 mssql mssql 373293056 Nov  6 18:11 src_db.mdf

Размеры сходятся - сумма файла данных и файла лога транзакций почти равна выводу скрипта.

Узнаем размер относительно zfs:

zfs list
NAME                   USED  AVAIL     REFER  MOUNTPOINT
storage               2.07G  7.29G     30.6K  /storage
storage/mssql_src_db  2.06G  9.17G      190M  -

В колонке REFER указывается фактический размер занятого пространства на volume или dataset. За счет сжатия было занято значительно меньше пространства.

Узнать коэффициенты и используемые алгоритмы сжатия можно командой:

zfs list -o name,compression,compressratio

NAME                  COMPRESS  RATIO
storage                    off  2.14x
storage/mssql_src_db       lz4  2.14x

Данные были сжаты почти в два раза.

ZFS + MS SQL on Linux + 1С + Snapshots + Clones

В zfs есть механизм квотирования и резервации пространства. По умолчанию, для volume или dataset зарезервировано пространство равное их первоначальному размеру:

zfs get refreservation storage/mssql_src_db

NAME                  PROPERTY        VALUE      SOURCE
storage/mssql_src_db  refreservation  2.06G      local

Для создания snapshots и clones нужно убрать это ограничение:

zfs set refreservation=none storage/mssql_src_db

Теперь можно переиспользовать пространство в zpool storage.

Для стабильной работы zfs требуется иметь в запасе примерно 80% от пространства zpool. Создать такой запас можно через квоту. Установим квоту в 7 ГБ для всего zpool storage:

zfs set quota=7G storage

Создадим snapshot volume'а mssql_src_db с именем snap1:

zfs snapshot storage/mssql_src_db@snap1

Имя снимка обязательно формируется по схеме ZPOOL_NAME/DATASET_OR_VOLUME_NAME@SNAPSHOT_NAME. Снимки являются основой для клонов, которые доступны в режиме read-write.

Создадим clone с именем clone_db1 на основе снимка storage/mssql_src_db@snap1:

zfs clone storage/mssql_src_db@snap1 storage/mssql_clone_db1

Можно включить сжатие и для клона:

zfs set compression=lz4 storage/mssql_clone_db1

Полный список созданных объектов и их параметры сжатия можно узнать следующей командой:

zfs list -t all -o name,available,used,refer,compression,compressratio

NAME                        AVAIL   USED     REFER  COMPRESS  RATIO
storage                     6.81G   191M     30.6K       off  2.14x
storage/mssql_clone_db1     6.81G  1.33K      190M       lz4  1.00x
storage/mssql_src_db        6.81G   190M      190M       lz4  2.14x
storage/mssql_src_db@snap1      -   392K      190M         -  2.14x

После снятия резервирования, в колонке USED указывается фактический размер занимаемый тем или иным объектом. Для истчника mssql_src_db этот размер равен значению в колонке REFER. Для снимка mssql_src_db@snap1 фактически используемый размер всего 392 КБ, но при этом он ссылается на 190 МБ данных из источника. Для клона mssql_clone_db1 фактически используемый размер всего 1,33 КБ и он также ссылается через снимок на 190 МБ данных источника.

На основе снимка можно создать много клонов - за счет copy on write они будут переиспользовать данные источника. Можно создать много снимков. Можно создать клон от снимка клона и так далее.

Понятно, что при активной работе с клоном его размер будет увеличиваться и со временем может достигнуть размера источника.

Подключим базу данных размещенную на клоне блочного устройства.

Для монтирования клона нужно создать каталог:

mkdir /mnt/mssql/mssql_clone_db1

Скопируем systemd mount unit источника и изменим его имя:

cp /etc/systemd/system/mnt-mssql-mssql_{src_db,clone_db1}.mount

Изменим в mount unit пути к клону и каталогу монтирования:

vim /etc/systemd/system/mnt-mssql-mssql_clone_db1.mount

Файл юнита должен иметь следующее содержание:

[Unit]
Description=Mount zfs volume with ext4 filesystem

[Mount]
What=/dev/zvol/storage/mssql_clone_db1
Where=/mnt/mssql/mssql_clone_db1

Type=ext4

Options=noatime,nodiratime

[Install]
WantedBy=multi-user.target

Запсукаем mount unit:

systemctl enable --now mnt-mssql-mssql_clone_db1.mount 
Created symlink /etc/systemd/system/multi-user.target.wants/mnt-mssql-mssql_clone_db1.mount → /etc/systemd/system/mnt-mssql-mssql_clone_db1.mount.

Проверяем успешность запуска mount unit:

systemctl status mnt-mssql-mssql_clone_db1.mount --no-pager 
● mnt-mssql-mssql_clone_db1.mount - Mount zfs volume with ext4 filesystem
     Loaded: loaded (/etc/systemd/system/mnt-mssql-mssql_clone_db1.mount; enabled; vendor preset: enabled)
     Active: active (mounted) since Sat 2021-11-06 19:00:31 UTC; 54s ago
      Where: /mnt/mssql/mssql_clone_db1
       What: /dev/zd16
      Tasks: 0 (limit: 4617)
     Memory: 9.6M
     CGroup: /system.slice/mnt-mssql-mssql_clone_db1.mount

Nov 06 19:00:31 ubuntu2004.localdomain systemd[1]: Mounting Mount zfs volume with ext4 filesystem...
Nov 06 19:00:31 ubuntu2004.localdomain systemd[1]: Mounted Mount zfs volume with ext4 filesystem.

Проверяем параметры доступа к каталогу:

ls -la /mnt/mssql/mssql_clone_db1/
total 438396
drwxr-xr-x 3 mssql mssql      4096 Nov  6 18:04 .
drwxr-xr-x 4 root  root       4096 Nov  6 18:55 ..
drwx------ 2 mssql mssql     16384 Nov  6 18:03 lost+found
-rw-rw---- 1 mssql mssql  75497472 Nov  6 18:30 src_db_log.ldf
-rw-rw---- 1 mssql mssql 373293056 Nov  6 18:13 src_db.mdf

Каталог и файлы доступны для пользователя mssql.

В консольном редакторе vim создадим скрипт подключения базы данных источника:

vim create_clone_db.sql

Файл скрипта должен иметь следующее содержание:

USE master;
GO

CREATE DATABASE [clone_db1]
ON
( FILENAME = N'/mnt/mssql/mssql_clone_db1/src_db.mdf' ),
( FILENAME = N'/mnt/mssql/mssql_clone_db1/src_db_log.ldf' )
FOR ATTACH;
GO

Выполним скрипт через sqlcmd:

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA -i create_clone_db.sql

Проверим создание базы данных выполнив запрос через sqlcmd:

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA -Y 30 -Q "select name from sys.databases where name = 'clone_db1';"
name                          
------------------------------
clone_db1                     

(1 rows affected)

Клон базы данных успешно подключен.

Добавим базу в кластере 1С Предприятие и убедимся в её работоспособности.

ZFS + Postgres + 1С + Snapshots + Clones

СУБД PostgreSQL работает с zfs напрямую. Нет необходимости создания volume и его разметки подходящей файловой системой.

PostgreSQL работает с кластером в котором может быть более одной базы и нет возможности создавать клоны отдельных баз. Клонируется сразу весь каталог кластера (вместе с настройками СУБД, которые возможно придется изменить в клоне). Запуска такого клона должен выполняться отдельным инстансом СУБД.

Для работы с 1С Предприятие потребует русская локаль. Локаль можно установить при необходимости:

apt install -y language-pack-ru

На виртуальной машине ubuntu_zfs установим PostgreSQL (13 версии от PostgresPro).

# Получение скрипта добавления репозитория:
curl -o apt-repo-add.sh https://repo.postgrespro.ru/pg1c-13/keys/apt-repo-add.sh

# Запуск скрипта и добавление репозитория:
sh apt-repo-add.sh

# Установка PostgreSQL без инициализации кластера:
apt install -y postgrespro-1c-13-contrib

Создадим dataset для размещения кластера PostgreSQL:

zfs create storage/pg_src_db

Включим сжатие:

zfs set compression=lz4 storage/pg_src_db

Для дополнительной производительности выключим запись отметки времени доступа к файлам:

zfs set atime=off storage/pg_src_db

zfs get atime storage/pg_src_db

NAME               PROPERTY  VALUE  SOURCE
storage/pg_src_db  atime     off    local

Для каталога установим владельца postgres:postgres и ограничим права:

chown postgres:postgres /storage/pg_src_db && chmod 700 /storage/pg_src_db

Для источника и его клонов потребуется запускать несколько инстансов PostgresPro. Это можно сделать с помощью шаблонов systemd service unit.

На основе исходного unit PostgresPro создадим шаблон:

cp /lib/systemd/system/postgrespro-1c-13.service /etc/systemd/system/postgrespro-1c-13@.service

Откроем скопированный шаблон в консольном редакторе vim:

vim /etc/systemd/system/postgrespro-1c-13@.service

Шаблон юнита должен выглядеть следующим образом:

[Unit]
Description=Postgres Pro 1c 13 database server
After=syslog.target
After=network.target

[Service]
Type=notify

User=postgres
Group=postgres

Environment=PATH=/opt/pgpro/1c-13/bin:/usr/sbin:/usr/bin:/bin:/sbin
# Location of database directory
EnvironmentFile=/etc/default/postgrespro-1c-13-%i

# Where to send early-startup messages from the server (before the logging
# options of postgresql.conf take effect)
# This is normally controlled by the global default set by systemd
# StandardOutput=syslog

# Disable OOM kill on the postmaster
OOMScoreAdjust=-1000

ExecStartPre=/opt/pgpro/1c-13/bin/check-db-dir ${PGDATA}
ExecStart=/opt/pgpro/1c-13/bin/postgres -p %i -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300

[Install]
WantedBy=multi-user.target

Отличие от исходного шаблона в строках: EnvironmentFile=/etc/default/postgrespro-1c-13-%i и ExecStart=/opt/pgpro/1c-13/bin/postgres -p %i -D ${PGDATA}.

При старте такого service unit'а, настройки переменных окружения будут читаться из файла /etc/default/postgrespro-1c-13-НОМЕР_ПОРТА_ИНСТАНСА_СУБД, а номер порта будет передаваться через наименование service unit'а - его следует указывать после символа @ в имени. Тогда в настройках юнита символ %i будет замещен номером порта.

С помощью консольного редактора vim создадим файл настроек переменных окружения для инстанса работающего на порту 5432 (стандартный порт PostgreSQL):

vim /etc/default/postgrespro-1c-13-5432

Файл должен иметь следующее содержимое:

PGDATA=/storage/pg_src_db

В файле настроек переменная окружения PGDATA указывает в подготовленный zfs dataset /storage/pg_src_db.

Вручную инициализируем кластер в zfs dataset /storage/pg_src_db выполняя команды от имени пользователя postgres:

sudo -i -u postgres /opt/pgpro/1c-13/bin/initdb --auth-host=md5 --locale=ru_RU.UTF-8 --pgdata /storage/pg_src_db

...
Success. You can now start the database server using:

    /opt/pgpro/1c-13/bin/pg_ctl -D /storage/pg_src_db -l logfile start

Можно выполнить "тюнинг" для работы с 1С Предприятие:

sudo -i -u postgres /opt/pgpro/1c-13/share/1c.tune >> /storage/pg_src_db/postgresql.conf

Разрешим подключения к СУБД на всех интерфейсах:

sudo -i -u postgres echo "host all all 0.0.0.0/0 md5" >> /storage/pg_src_db/pg_hba.conf

Можно запускать службу PostgreSQL на порту 5432 и каталогом кластера /storage/pg_src_db:

systemctl enable --now postgrespro-1c-13@5432.service

Created symlink /etc/systemd/system/multi-user.target.wants/postgrespro-1c-13@5432.service → /etc/systemd/system/postgrespro-1c-13@.service.

Проверим работу службы:

systemctl status postgrespro-1c-13@5432.service --no-pager 
● postgrespro-1c-13@5432.service - Postgres Pro 1c 13 database server
     Loaded: loaded (/etc/systemd/system/postgrespro-1c-13@.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2021-11-06 20:11:02 UTC; 40s ago
    Process: 137993 ExecStartPre=/opt/pgpro/1c-13/bin/check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 137998 (postgres)
      Tasks: 7 (limit: 4617)
     Memory: 50.8M
     CGroup: /system.slice/system-postgrespro\x2d1c\x2d13.slice/postgrespro-1c-13@5432.service
             ├─137998 /opt/pgpro/1c-13/bin/postgres -D /storage/pg_src_db
             ├─138018 postgres: checkpointer
             ├─138019 postgres: background writer
             ├─138020 postgres: walwriter
             ├─138021 postgres: autovacuum launcher
             ├─138022 postgres: stats collector
             └─138023 postgres: logical replication launcher

Nov 06 20:11:02 ubuntu2004.localdomain systemd[1]: Starting Postgres Pro 1c 13 database server...
Nov 06 20:11:02 ubuntu2004.localdomain postgres[137998]: 2021-11-06 20:11:02.294 UTC [137998] LOG:  starting PostgreSQL 13.4 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9…9.3.0, 64-bit
Nov 06 20:11:02 ubuntu2004.localdomain postgres[137998]: 2021-11-06 20:11:02.295 UTC [137998] LOG:  listening on IPv4 address "0.0.0.0", port 5432
Nov 06 20:11:02 ubuntu2004.localdomain postgres[137998]: 2021-11-06 20:11:02.295 UTC [137998] LOG:  listening on IPv6 address "::", port 5432
Nov 06 20:11:02 ubuntu2004.localdomain postgres[137998]: 2021-11-06 20:11:02.304 UTC [137998] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
Nov 06 20:11:02 ubuntu2004.localdomain postgres[138017]: 2021-11-06 20:11:02.312 UTC [138017] LOG:  database system was shut down at 2021-11-06 20:07:09 UTC
Nov 06 20:11:02 ubuntu2004.localdomain postgres[137998]: 2021-11-06 20:11:02.332 UTC [137998] LOG:  database system is ready to accept connections
Nov 06 20:11:02 ubuntu2004.localdomain systemd[1]: Started Postgres Pro 1c 13 database server.
Hint: Some lines were ellipsized, use -l to show in full.

Для пользователя postgres установим пароль подключения к СУБД:

sudo -i -u postgres /opt/pgpro/1c-13/bin/psql -c "alter user postgres with password '1qaZ@wsx';"

На сервере 1С Предприятие создаем пустую базу данных в PostgreSQL с русской локалью.

В пустую базу загружаем демонстрационную базу БСП.

Проверим состояние zfs:

zfs list -t all -o name,available,used,refer,compression,compressratio
NAME                        AVAIL   USED     REFER  COMPRESS  RATIO
storage                     6.66G   344M     30.6K       off  2.30x
storage/mssql_clone_db1     6.66G  3.08M      184M       lz4  9.70x
storage/mssql_src_db        6.66G   191M      190M       lz4  2.16x
storage/mssql_src_db@snap1      -  1.75M      190M         -  2.14x
storage/pg_src_db           6.66G   149M      149M       lz4  2.36x

Создадим снимок и клон dataset storage/pg_src_db:

zfs snapshot storage/pg_src_db@snap1

zfs clone storage/pg_src_db@snap1 storage/pg_clone_db1

zfs set compression=lz4 storage/pg_clone_db1

zfs set atime=off storage/pg_clone_db1

Скопируем файл переменных окружения для нового инстанса СУБД:

cp /etc/default/postgrespro-1c-13-{5432,5433}

В консольном редакторе vim исправим PGDATA указав путь к клону:

vim /etc/default/postgrespro-1c-13-5433

Файл должен иметь следующее содержимое:

PGDATA=/storage/pg_clone_db1

Так как клон сделан при работающем источнике, то нужно удалить файл postmaster.pid:

rm /storage/pg_clone_db1/postmaster.pid

Запустим инстанс PostgreSQL на основе клона источника:

systemctl enable --now postgrespro-1c-13@5433.service

Убедимся что запуск выполнен успешно:

systemctl status postgrespro-1c-13@5433.service --no-pager 
● postgrespro-1c-13@5433.service - Postgres Pro 1c 13 database server
     Loaded: loaded (/etc/systemd/system/postgrespro-1c-13@.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2021-11-06 20:41:45 UTC; 23s ago
    Process: 169670 ExecStartPre=/opt/pgpro/1c-13/bin/check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 169673 (postgres)
      Tasks: 7 (limit: 4617)
     Memory: 300.6M
     CGroup: /system.slice/system-postgrespro\x2d1c\x2d13.slice/postgrespro-1c-13@5433.service
             ├─169673 /opt/pgpro/1c-13/bin/postgres -p 5433 -D /storage/pg_clone_db1
             ├─170662 postgres: checkpointer
             ├─170663 postgres: background writer
             ├─170664 postgres: walwriter
             ├─170665 postgres: autovacuum launcher
             ├─170666 postgres: stats collector
             └─170667 postgres: logical replication launcher

Nov 06 20:41:38 ubuntu2004.localdomain postgres[169673]: 2021-11-06 20:41:38.986 UTC [169673] LOG:  listening on IPv4 address "0.0.0.0", port 5433
Nov 06 20:41:38 ubuntu2004.localdomain postgres[169673]: 2021-11-06 20:41:38.986 UTC [169673] LOG:  listening on IPv6 address "::", port 5433
Nov 06 20:41:39 ubuntu2004.localdomain postgres[169673]: 2021-11-06 20:41:39.001 UTC [169673] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5433"
Nov 06 20:41:39 ubuntu2004.localdomain postgres[169778]: 2021-11-06 20:41:39.030 UTC [169778] LOG:  database system was interrupted; last known up at 2021-11-06 20:16:25 UTC
Nov 06 20:41:39 ubuntu2004.localdomain postgres[169778]: 2021-11-06 20:41:39.185 UTC [169778] LOG:  database system was not properly shut down; automatic recovery in progress
Nov 06 20:41:39 ubuntu2004.localdomain postgres[169778]: 2021-11-06 20:41:39.203 UTC [169778] LOG:  redo starts at 0/15D2330
Nov 06 20:41:39 ubuntu2004.localdomain postgres[169778]: 2021-11-06 20:41:39.872 UTC [169778] LOG:  invalid record length at 0/DEE6318: wanted 24, got 0
Nov 06 20:41:39 ubuntu2004.localdomain postgres[169778]: 2021-11-06 20:41:39.872 UTC [169778] LOG:  redo done at 0/DEE62F0
Nov 06 20:41:45 ubuntu2004.localdomain postgres[169673]: 2021-11-06 20:41:45.203 UTC [169673] LOG:  database system is ready to accept connections
Nov 06 20:41:45 ubuntu2004.localdomain systemd[1]: Started Postgres Pro 1c 13 database server.

Клон можно подключить к серверу 1С Предприятие.

Если служба PostgreSQL работает на нестандартном порту, то порт указывается в параметрах подключения как 192.168.111.10 port=5433.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment