Обновление#

Данный раздел рассматривает процесс обновления СУБД Pangolin.

В составе дистрибутива (папка installer) расположены два скрипта, для установки обновления:

  • Скрипт-разведчик — скрипт проверки перед обновлением.

  • Скрипт-обновление — основной скрипт, при запуске которого происходит установка обновления.

Процесс разведки и обновления может осуществляться по различным алгоритмам, существенно различающимися по времени выполнения и сложности (зависит от объема и типа изменений между версиями):

  • Обновление, при котором осуществляется замена старых файлов (исполняемых, конфигурационных, файлов расширений) на их обновленные версии, либо добавляются новые утилиты, которые отсутствовали в предыдущих версиях. Характеризуется малым временем выполнения и возможностью обновления без прерывания работы сервиса.

  • Обновление, при котором, помимо обновления файлов, осуществляется изменение структуры или состава данных в системных каталогах обновляемых БД. Характеризуется дополнительным набором предварительным проверок, обновлением с прерыванием работы сервиса и рекомендацией по созданию резервной копии перед обновлением.

Примечание:

Под изменением структуры или состава данных понимается:

  • изменение состава системных таблиц;

  • изменение состава системных представлений;

  • изменение состава системных функций;

  • изменение списка встроенных типов данных;

  • изменение формата хранения данных (включая изменения в алгоритме шифрования).

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

Общая информация по обновлению СУБД Pangolin#

Перед началом обновления запустите скрипт-разведчик, который:

  • выводит список установленных extensions (в процессе обновления они не будут перенесены в новую версию СУБД Pangolin):

    • сторонние/не входящие в текущую версию продукта СУБД Pangolin;

    • запрещенные расширения;

    • расширения, несовместимые с новой версией СУБД Pangolin;

    • полный список ограничений, для администраторов автоматизированной системы (в случае их наличия).

  • проверяет:

    • возможность создания резервной копии (РК). Локальная РК является необходимым условием для работы механизма автоматического отката к исходной версии СУБД в случае возникновения любых внештатных ситуаций в процессе работы механизма обновления;

    • наличие дубликатов в конфигурационном файле patroni (postgres.yml);

    • наличие специальных символов в конфигурационных файлах postgres.yml, pg_hba.conf, postgresql.conf;

    • состояние БД на наличие близости к пороговому значению заморозки транзакций autovacuum_freeze_max_age;

    • количество транзакций с незавершенным статусом.

Внимание!

Если в настраиваемом конфигурационном слое параметр, отвечающий за создание резервного копирования, будет выключен, то в случае ошибок в процессе обновления ответственность за сохранность данных и восстановление исходной версии СУБД находится на стороне владельца настраиваемого конфигурационного слоя.

В процессе обновления будет обновлена СУБД Pangolin и версии всех утилит, входящих в состав продукта.

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

  • postgres.yml (в случае наличия patroni);

  • pgbouncer.ini (в случае наличия pgbouncer);

  • pg_hba.conf;

  • postgresql.conf.

В случае ошибки при обновлении срабатывает механизм прерывания работы обновления версии СУБД, позволяющий остановить процесс обновления и вернуть версию СУБД в состояние до обновления.

Схемы процесса обновления#

Схема процесса обновления СУБД Pangolin второго уровня сложности для конфигурации standalone: реализация внутренних процессов#

Схема обновления standalone

Схема процесса обновления СУБД Pangolin второго уровня сложности для конфигурации cluster: реализация внутренних процессов#

Схема обновления cluster

Список ограничений перед проведением обновления СУБД Pangolin#

  • WARNINGS (рекомендуется устранить, решение за пользователем):

    • проверьте наличие расширений, установленных в схему public или в системный каталог (рекомендуется: перенести в схему ext);

    • в случае использования конфигурации СУБД cluster-patroni-etcd-pgbouncer (версии СУБД Pangolin до 5.1.0) при обновлении, утилита confd будет автоматически удалена. Поэтому до обновления измените строку подключения к СУБД (проверьте значения портов) и убедитесь что в строке указаны оба узла кластера (active и standby). Например, если раньше было:

      jdbc:postgresql://127.0.0.1:6544,127.0.0.2:6544/dbname?prepareThreshold=0`
      

      исправьте на:

      jdbc:postgresql://127.0.0.1:6544,127.0.0.2:6544/dbname?targetServerType=master&prepareThreshold=0
      
  • ERRORS (обязательно должны быть устранены, иначе обновление не будет доступно):

    • проверьте, что в БД не используются данные следующих типов abstime, reltime, tinterval (рекомендуется: не использовать перечисленные типы данных):

      -- поиск устаревших типов данных // запускать необходимо для КАЖДОЙ БД
      SELECT format('%1$s.%2$s(%3$s)',ns.nspname,cl.relname,att.attname) tbl_fld
      FROM pg_attribute att
      JOIN pg_type tp ON att.atttypid =tp.oid
      JOIN pg_class cl ON att.attrelid =cl.oid
      JOIN pg_namespace ns ON cl.relnamespace = ns.oid
      WHERE tp.typname IN ('abstime','reltime','tinterval') AND NOT (ns.nspname SIMILAR TO '(pg_|information_schema)%');
      
    • в процедурах проверьте, что язык Python 2.х не используется (рекомендуется: использовать Python 3.x):

      -- Должен вернуться список процедур на python2u,pythonu // запускать необходимо для КАЖДОЙ БД
      SELECT format('%1$s.%2$s',ns.nspname,pp.proname) pr_name
      FROM pg_proc pp
      JOIN pg_catalog.pg_language pl ON pp.prolang =pl.oid
      JOIN pg_namespace ns ON pp.pronamespace =ns.oid AND pl.lanname SIMILAR TO 'plpython2?u%';
      
    • убедитесь, что значение параметра max_worker_process конфигурационного файла не превышает сумму количества баз данных на узле (включая системные template1, postgres) + 6. Например, если количество БД = 26, то значение параметра должно быть не меньше 32.

Список необходимых действий после завершения процесса обновления СУБД Pangolin#

  • WARNINGS (рекомендуется устранить, решение за пользователем):

    • необходимо учесть, что файл recovery.conf более не используются в логике работы СУБД (для кластерной конфигурации);

    • в работе автоматизированной системы (приложение работающее с СУБД Pangolin) необходимо учесть, что была расширена информация о клиентских сертификатах SSL в представлении pg_stat_ssl и колонка clientdn была переименована в client_dn;

    • в работе автоматизированной системы необходимо учесть, что были изменены параметры хранения и ротации WAL-файлов, параметр wal_keep_segments был объявлен устаревшим, поэтому необходимо перейти на использование параметра wal_keep_size;

    • обращаем внимание, что начиная с версии СУБД Pangolin 5.1.0 введено понятие TRUSTED EXTENSIONS, таким образом определенные расширения (список таких расширений можно получить с помощью запроса SELECT DISTINCT name FROM pg_available_extension_versions WHERE TRUSTED ORDER BY name;) в дальнейшем могут быть созданы пользователями с правами CREATE (пользователи входящие в as_admin группу) на уровне базы данных;

    • в работе автоматизированной системы необходимо учесть, что в новой версии СУБД Pangolin могли быть изменены некоторые вендорские процедуры, а именно, мог измениться состав или порядок аргументов для них (например, функции sec_admin, в которых убран аргумент current_database).

    Примечание:

    Перед началом обновления версии СУБД внимательно изучите Примечания к релизу новой версии.

Таблица поддерживаемых для обновления версий СУБД#

Обновление#

Данная таблица отражает поддерживаемые версии для обновления СУБД до версии 5.5.5.

Внимание!

Обновление стендов с разным набором СЗИ возможно только с версии 5.4.0 и выше.

Тип обновления

Исходная версия

Конфигурация

Обновление с переносом данных

5.4.0, 5.4.1

с СЗИ

Обновление с переносом данных

4.6.1, 4.6.2, 4.6.3, 4.6.4, 4.6.5, 4.6.6, 4.6.7, 5.2.0, 5.2.1, 5.2.2, 5.2.3, 5.2.4, 5.2.5, 5.2.6, 5.3.0, 5.3.2, 5.4.0, 5.4.1

без СЗИ

Обновление исполняемых файлов

5.5.0, 5.5.1, 5.5.2, 5.5.3, 5.5.4

без СЗИ

Обновление исполняемых файлов

5.5.0, 5.5.1, 5.5.2, 5.5.3, 5.5.4

с СЗИ

В остальных случаях (не отраженных в таблице) обновление невозможно.

Обозначение поля конфигурации

Тип конфигурации определен следующим образом:

  • с СЗИ – включено хотя бы одно из СЗИ (TDE, защита конфигурации, защита от привилегированных пользователей) включено;

  • без СЗИ – СЗИ отключены.

Как определить версию, установленную на сервере#

Для получения названия и версии продукта серверной части необходимо подключиться к серверу Pangolin и выполнить команды из таблицы ниже. Результат выполнения зависит от названия, номера версии и платформы, для которой была выполнена сборка.

Действие

Команда

Тип значения

Примеры выполнения команды

Название продукта

SELECT version();

Строковое значение

PostgreSQL 11.7 (PostgreSQL Sber Edition 4.1.0) on x86_64-apple-darwin19.4.0, compiled by Apple clang version 11.0.0 (clang-1100.0.33.17), 64-bit

Номер open-source версии

SHOW server_version;

Строковое значение

11.7

SHOW server_version_num;

Числовое значение

110007

Номер Pangolin версии

SHOW server_se_version;

Строковое значение

5.5.0

SELECT sber_version();

Строковое значение

5.5.0

Проверка готовности к обновлению#

Внимание!

В случае, если все пароли указывались в открытом виде, параметры --ask-vault-pass и --vault-password-file=название_файла_с_ключом добавлять не нужно!

Обязательным условием запуска скриптов обновления СУБД, является запуск скрипта-разведчика, в задачи которого входит выполнение ряда проверок, сбора информации о стенде, а также вычислении типа обновления версии СУБД, необходимого для перехода на новую версию СУБД Pangolin.

  1. Скачайте и распакуйте дистрибутив на сервере.

  2. Перейдите в каталог с распакованным дистрибутивом, а затем в каталог installer.

  3. Перед запуском обновления заполните файл hosts.ini, в зависимости от установленного решения, добавив информацию о хостах и учетных данных пользователя, которые будет использовать Ansible.

    Внимание!

    Данные должны содержать те же параметры, что и при установке. Примеры заполнения файлов описаны в разделе «Установка».

  4. Заполните настраиваемый конфигурационный файл custom_file_sample.yml.

  5. Заполните конфигурационный файл all.yml.

  6. Чтобы удостовериться в готовности к обновлению, используйте ansible-сценарий проверки. Пример команды:

    ansible-playbook playbook_scouting.yaml -i inventories/standalone/hosts.ini -t always,standalone --ask-vault-pass -vv --extra-vars "local_distr_path=${} segment=${} custom_config=${} stand=${}"
    

    Ниже приведены шаблоны сценариев для различных решений:

    • Проверка односерверного решения:

      ansible-playbook playbook_scouting.yaml \
      -i inventories/standalone/hosts.ini \
      -t always,standalone \
      --ask-vault-pass \
      -vv \
      --extra-vars "local_distr_path=${} \
      segment=${} \
      custom_config=${} \
      stand=${}"
      
    • Проверка кластерного решения:

      ansible-playbook playbook_scouting.yaml \
      -i inventories/cluster/hosts.ini \
      -t always,cluster \
      --ask-vault-pass \
      -vv \
      --extra-vars "local_distr_path=${} \
      segment=${} \
      custom_config=${} \
      stand=${}"
      

    Описание параметров:

    • custom_config — абсолютный путь к файлу конфигурации custom_file_template.yml;

    • local_distr_path — абсолютный путь к загруженному и распакованному дистрибутиву Pangolin;

    • segment — сегмент сети;

    • stand — стенд для тестирования или конечной инсталляции (dev или prom).

    Значения используемых в команде запуска Ansible ключей:

    • -i — путь к inventory-файла;

    • --extra-vars — переменные, которые по приоритету важнее переменных из inventory;

    • -t — теги для запуска;

    • -v — уровень логирования Ansible. Может быть, как пустым, так и -vvvvvv, где запуск без v - минимальное логирование;

    • --ask-vault-pass или --vault-password-file — расшифровка зашифрованных файлов во время выполнения.

      Внимание!

      Для шифрования паролей в примерах выше, использовался следующий ansible-vault пароль: postgreSQL_SE_654321.

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

Проверки и информационные сообщения процесса разведки#

Проверки начинаются с разблокировки пользователя postgres в OC и выставления бессрочного пароля на время работы скрипта.

Подготовительные действия#

Происходит загрузка custom_file_sample.yml и словаря update.yml, содержащего дополнительные переменные с информацией для выводимых сообщений и поддерживаемых расширений.

Проверка установленной версии ansible#

Если текущая версия ansible меньше поддерживаемой версии, то выводится блокирующая дальнейшее выполнение сценария ошибка:

Current ansible version: {{ hostvars['127.0.0.1'].ansible_version.full }}. Needed ansible version: {{ ansible_ver }} or higher

Проверка корректности конфигурационного файла postgresql.conf#

Если конфигурационный файл содержит какие-либо ошибки, то выводится сообщение:

"{{ control_name }}.FAIL__В кандидате на обновление для хоста {host} в конфигурационном файле postgresql.conf обнаружены ошибки заполнения.__{{ control_name }}.FAIL"

Проверка того, что для узлов master и/или replica существует только одно FQDN-имя#

Если для узлов master и/или replica существует более одного FQDN-имени, то выводится сообщение:

"{{ control_name }}.FAIL__В кандидате на обновление для хоста {ansible_fqdn} обнаружен дублирующий fqdn {double_fqdn}.__{{ control_name }}.FAIL"

Проверка того, что значение search_path всегда не пустое#

Если search_path для одной из ролей равен пустому значению (не заполнен), то выводится сообщение:

"{{ control_name }}.FAIL__В кандидате на обновление обнаружено незаполненное значение для поля search_path для следующих пользовательских ролей {roles}. Поле search_path не должно иметь пустое значение, это необходимо для корректного конфигурирования СУБД в процессе обновления.__{{ control_name }}.FAIL"

Проверка поддерживаемой версии к обновлению#

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

"{{ control_name }}.FAIL__Обновление невозможно при наличии включенных СЗИ (TDE, защита конфигурации, защита от привилегированных пользователей) в автоматическом режиме для версии (pg_current_version). Обратитесь к администраторам СУБД для осуществления обновления вручную.__{{ control_name }}.FAIL"

Для осуществления обновления вручную необходимо обратиться к администратору.

Проверка символьной ссылки до плагина, реализующего взаимодействие с физическим сервером VAULT#

В случае невозможности обновления по данной причине будет получено следующее сообщение:

"{{ control_name }}.FAIL__На стенде обнаружено использование VAULT заменителя. Произвести обновление будет невозможно. Необходимо перевести стенд на использование физического VAULT сервера и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка пароля postgres_db_pass, передаваемого в пользовательском конфигурационном файле#

Ожидается зашифрованное с помощью ansible-vault значение. В случае ошибки будет получено следующее сообщение:

"{{ control_name }}.FAIL__Для корректного обновления пароль от суперпользователя postgres должен быть задан в открытом виде, либо в виде ansible-хеша. Скорректируйте значение для параметра postgres_db_pass в пользовательском конфигурационном файле '{}' и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка корректной записи хеша пароля суперпользователя postgres во временный файл для корректной инициализации БД#

В случае ошибки будет получено сообщение вида:

"{{ control_name }}.FAIL__В процессе формирования хеша для пароля суперпользователя postgres что-то пошло не так. Пароль не был записан во временный файл '{}'. Инициализация БД невозможна. Произведите проверку корректно заполненного параметра postgres_db_pass в пользовательском конфигурационном файле '{}' и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка наличия пароля суперпользователя postgres в исходной БД#

При возникновении ошибки будет получено следующее сообщение:

"{{ control_name }}.FAIL__Пароль от суперпользователя postgres в исходной БД не задан. Произвести обновление будет невозможно. Скорректируйте значение для параметра postgres_db_pass в пользовательском конфигурационном файле '{}' и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка идентичности паролей суперпользователя postgres в исходной БД с паролем, переданным в пользовательском конфигурационном файле#

В случае, когда пароли не идентичны, будет выведена следующая ошибка:

"{{ control_name }}.FAIL__Пароль от суперпользователя postgres в пользовательском конфигурационном файле не совпадает с текущим паролем в БД. Скорректируйте значение параметра 'postgres_db_pass' в пользовательском конфигурационном файле '{}' и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка корректного расположения утилиты secret_storage_client#

Для осуществления проверки готовности защищенного хранилища VAULT к последующему обновлению, скрипты используют утилиту secret_storage_client, которая входит в состав дистрибутива.

Утилита расположена в папке utilities/secret_storage_client_bundle/bin/. При отсутствии утилиты будет выведено предупреждающее сообщение (процесс работы скриптов при этом не останавливается).

В случае если утилита не обнаружена, будет получено предупреждение:

"{{ control_name }}.WARNING__Утилита secret_storage_client не обнаружена. Проверки готовности защищенного хранилища VAULT к обновлению будут пропущены.__{{ control_name }}.WARNING"

Проверка наличия конфигурационного файла VAULT#

При отсутствии файла будет выведено сообщение:

"{{ control_name }}.FAIL__В кандидате на обновление не был обнаружен конфигурационный файл VAULT '{}'. Произведите проверку состояния стенда на предмет подключения к защищенному хранилищу VAULT и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка наличия успешного подключения к защищенному хранилищу VAULT#

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

"{{ control_name }}.FAIL__Не удалось обнаружить ни одного успешного подключения к защищенному(ым) хранилищу(ам) VAULT. Возникли следующие ошибки: {}. Произведите проверку состояния стенда на предмет подключения к защищенному хранилищу VAULT и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Получение общего списка параметров из защищенного хранилища VAULT#

В случае возникновения ошибок будет получено сообщение вида:

"{{ control_name }}.FAIL__В процессе получения списка параметров из защищенного хранилища VAULT возникли ошибки: '{}'. Причиной может быть отсутствие конфигурационного файла '{}' с параметрами подключения к защищенному хранилищу VAULT. Произведите проверку состояние подключения к VAULT серверу(ам) и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка корректного значения для параметра secure_config на защищенном хранилище VAULT#

Если состояние стенда показало, что защита конфигурации включена, ожидается значение on:

"{{ control_name }}.FAIL__Значение параметра secure_config на защищенном хранилище VAULT не соответствует полученным данным о состоянии стенда. При включенной защите параметров конфигурации значение для параметра secure_config должно быть 'on' на защищенном хранилище VAULT. Произведите проверку состояние стенда на наличие подключенных СЗИ и корректность сконфигурированного id на сервере VAULT. После повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

В случае отключенной защиты конфигурации значение параметра secure_config будет off:

"{{ control_name }}.FAIL__Значение параметра secure_config на защищенном хранилище VAULT не соответствует полученным данным о состоянии стенда. При выключенной защите параметров конфигурации значение для параметра secure_config должно быть 'off' на защищенном хранилище VAULT. Произведите проверку состояние стенда на наличие подключенных СЗИ и корректность сконфигурированного id на сервере VAULT. После повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка корректного значения для параметра is_tde_on на защищенном хранилище VAULT#

В случае, когда состояние стенда показало включенное TDE, ожидается значение on/true:

"{{ control_name }}.FAIL__Значение параметра is_tde_on на защищенном хранилище VAULT не соответствует полученным данным о состоянии стенда. При включенном прозрачном шифровании (TDE) значение для параметра is_tde_on должно быть 'on' на защищенном хранилище VAULT. Произведите проверку состояние стенда на наличие подключенных СЗИ и корректность сконфигурированного id на сервере VAULT. После повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

В случае, если TDE выключено, значение параметра is_tde_on будет соответствовать off/false:

"{{ control_name }}.FAIL__Значение параметра is_tde_on на защищенном хранилище VAULT не соответствует полученным данным о состоянии стенда. При выключенном прозрачном шифровании (TDE) значение для параметра is_tde_on должно быть 'off' на защищенном хранилище VAULT. Произведите проверку состояние стенда на наличие подключенных СЗИ и корректность сконфигурированного id на сервере VAULT. После повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка идентичности значений pg_ident на защищенном хранилище VAULT и в локальном конфигурационном файле#

В случае ошибки будет получено сообщение вида:

"{{ control_name }}.FAIL__Значение параметра pg_ident на защищенном хранилище VAULT должно соответствовать значению в локальном конфигурационном файле '{}/pg_ident.conf'. Произведите проверку на предмет корректно сконфигурированного id на сервере VAULT и повторите запуск скрипта разведчика.__{{ control_name }}.FAIL"

Проверка состояния параметра KillUserProcesses в файле /etc/systemd/logind.conf#

Если параметр KillUserProcesses в файле /etc/systemd/logind.conf находится в положении yes, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__На хосте host_name в файле /etc/systemd/logind.conf включен параметр KillUserProcesses=yes, для дальнейшей работы требуется переключить данный параметр в положение KillUserProcesses=no и перезапустить хост.__{{ control_name }}.FAIL

Проверка отсутствия неудачных попыток обновления#

Скрипт проверки осуществляет проверку предыдущих обновлений и фиксирует неудачные попытки. Если предыдущие попытки обновления были неуспешными, либо, если при неудачном обновлении был некорректно произведен автоматический откат, то скрипт прервется и создаст файл /home/postgres/.update_pgse/update_disallowed. Пользователю выведется сообщение:

{{ control_name }}.FAIL__Зафиксирована неудачная попытка обновления версии СУБД Pangolin. Перед повторным запуском сценария обновления, необходимо полностью восстановить состояние кластера предыдущей/исходной версии СУБД Pangolin. Обратитесь к администраторам БД__{{ control_name }}.FAIL

В этом случае необходимо вручную откатить стенд на исходное состояние (см. раздел «Откат»), удалить файл /home/postgres/.update_pgse/update_disallowed, а затем перезапустить разведку.

Проверка включения полного внутреннего резервного копирования данных#

Проверяется значение параметра is_inner_full_backup. Если параметр имеет значение false, то выводится информационное сообщение:

{{ control_name }}.INFO__За процедуру резервного копирования данных, на случай непредвиденных ошибок в процессе обновления, отвечает отдельная от Механизма обновления служба.__{{ control_name }}.INFO

Затем производится проверка необходимых linux-пакетов и, в случае отсутствия, их установка, подготовка виртуального окружения Python, определение текущего active и standby.

Проверка, что переданный адрес active соответствует действительности#

В случае, если мастер не соответствует переданному в конфигурации hosts.ini, скрипт прервется с ошибкой:

{{ control_name }}.FAIL__В кандидате на обновление текущий active в СУБД не соответствует значению, полученному на вход. На текущий момент обновление невозможно, необходимо выполнить switchover__{{ control_name }}.FAIL

Выполнение роли (checkup/prepare_update.yml) перед обновлением#

Роль получает текущее значение переменных, таких как:

  • pg_current_version;

  • PGDATA_OLD;

  • PGHOME_OLD;

  • PGPORT_OLD;

  • PGBOUNCERPORT_OLD;

  • CLNAME_OLD;

  • PGHOME_OLD_NAME.

Получение состояний компонентов для определения типа установленной конфигурации#

Если нет имени кластера, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Укажите актуальное имя кластера в .bash_profile в параметре '- export CLNAME= '__{{ control_name }}.FAIL

Если SSL настроен, но не включен, то выводится блокирующая дальнейшее выполнение сценария ошибка:

RLM.FAIL__SSL настроен, но выключен в конфигурации БД. Возможно в кандидате на обновление уже был ранее настроен SSL. Для продолжения обновления необходимо удалить настройки БД, связанные с ssl и повторить запуск обновления.__RLM.FAIL

Если SSL не был настроен корректно, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__SSL не был настроен корректно. Возможно в кандидате на обновление уже был ранее настроен SSL. Для продолжения обновления необходимо удалить настройки БД, связанные с ssl и повторить запуск обновления.__{{ control_name }}.FAIL

Если файлы сертификатов отсутствуют, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Файл сертификата {{ item }} не найден__{{ control_name }}.FAIL

Где item - 3 файла: ключ (например /home/postgres/ssl/client.key), сертификат (например /home/postgres/ssl/client.crt) и корневой сертификат (например /home/postgres/ssl/root.crt).

Проверка соответствия установленных компонентов кластера с текущим типом конфигурации#

Если не соответствует, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Текущий тип конфигурации согласно конфигурационному параметру СУБД {type_configuration}, при этом обнаружены несоответствующие конфигурации компоненты: {component}. Для продолжения обновления требуется удалить несоответствующие компоненты.__{{ control_name }}.FAIL

Проверка минимальной поддерживаемой версии Postgres SE, над которой может быть выполнен сценарий разведки/обновления#

Скрипт запрашивает информацию об установленной версии. Сравнивает версию с параметром, отвечающим за минимальную поддерживаемую версию, который, в свою очередь, берет информацию из матрицы версий. Если версия не поддерживается, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Обновление невозможно. Текущая версия (pg_current_version) не поддерживается. Минимальная поддерживаемая версия: min_actual_pangolin_ver__{{ control_name }}.FAIL

Матрица поддерживаемых версий:

list_versions_to_update: [ "4.6.1", "4.6.2", "4.6.3", "4.6.4", "4.6.5", "4.6.6", "5.2.0", "5.2.1", "5.2.2", "5.2.3", "5.2.4", "5.2.5", "5.2.6", "5.3.0", "5.3.2", "5.4.0", "5.4.1" ]

update_version_matrix: {
"table": [
{ "to": "5.5.0", "from": [ "5.4.0", "5.4.1" ], configure_ist: true, "update_type": "update_major", "pg_upgrade_mode": "hardlink" },
{ "to": "5.5.0", "from": [ "4.6.1", "4.6.2", "4.6.3", "4.6.4", "4.6.5", "4.6.6", "5.2.0", "5.2.1", "5.2.2", "5.2.3", "5.2.4", "5.2.5", "5.2.6", "5.3.0", "5.3.2", "5.4.0", "5.4.1" ], configure_ist: false, "update_type": "update_major", "pg_upgrade_mode": "hardlink" },
{ "to": "5.5.0", "from": [ "4.6.1", "4.6.2", "4.6.3", "4.6.4", "4.6.5", "4.6.6", "5.2.0", "5.2.1", "5.2.2", "5.2.3", "5.2.4", "5.2.5", "5.2.6", "5.3.0", "5.3.2" ], configure_ist: true, "update_type": "unsupported", "pg_upgrade_mode": "not defined" }
]
}

Проверка типа установленной конфигурации Pangolin#

Скрипт запрашивает информацию об установленном типе конфигурации и сравнивает его со списком неподдерживаемых. Если тип конфигурации не поддерживается, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Тип установленной конфигурации: tag. Процесс обновления для данного типа недоступен. Предварительно необходимо привести тип конфигурации к одному из поддерживаемых типов (как за счет чистой установки новой СУБД, так и за счет ручного изменения типа конфигурации)__{{ control_name }}.FAIL

Не поддерживаемые версии описаны в custom_file_template.yml в параметре not_support_type_installed_configuration:

not_support_type_installed_configuration: ['standalone-postgresql-only']

Определение типа обновления#

Скрипт проверки самостоятельно определяет тип обновления по своему алгоритму, без дополнительных действий от пользователя.

Алгоритм действий проверки. На текущей СУБД запрашивается информация:

  • текущая версия;

  • включена или нет функциональность «прозрачное шифрование данных (TDE)»;

  • включена или нет функциональность «защита от привилегированных пользователей (AP)»;

Если тип обновления равен unsupported для текущей версии, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Обновление невозможно. При включенной функциональности защиты от привилегированных пользователей (AP) обновление в автоматическом режиме не поддерживается для версии (pg_current_version). Обратитесь к администраторам СУБД для осуществления обновления вручную.__{{ control_name }}.FAIL

Если успешно получены параметры для определения типа обновления(update_complexity_level) из таблицы соответствия для текущей версии, то происходит анализ данных параметров и выводится сообщение:

RLM.ARGS__{\"update_complexity_level\": \"update_complexity_level_2\"}__RLM.ARGS

Проверка свободного места#

Проверка свободного места в точке монтирования PGBACKUP (пример: /pgarclogs/04). Требуется минимум 1 Гб. Если места не хватает, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Точка монтирования {{ PGBACKUP }} имеет {{ pgdata_mp_free }} Гб свободного пространства, но требуется не менее 1 Гб.__{{ control_name }}.FAIL
  • Для типов update_complexity_level_2/update_complexity_level_3 выполняется проверка размера СУБД. Если размер СУБД больше чем задано в параметре maximum_dbms_size_to_update (параметр максимальный размер СУБД для обновления в настраиваемом конфигурационном файле), то выводится блокирующая дальнейшее выполнение сценария ошибка:

    {{ control_name }}.FAIL__Автоматическое обновление ограничено размером кластера СУБД в maximum_dbms_size_to_update Гб. Текущая СУБД имеет размер current_dbms_size Гб.__{{ control_name }}.FAIL
    
  • Для типов update_complexity_level_2/update_complexity_level_3 и полного внутреннего резервного копирования данных проверяется наличие на active каталога local_backup_path (путь для локального резервного копирования), задающийся в настраиваемом конфигурационном файле или переданным на вход скрипта в виде extra vars. Если отсутствует, то выводится блокирующая дальнейшее выполнение сценария ошибка:

    {{ control_name }}.FAIL__Не найден каталог /pgarclogs, указанный в параметре local_backup_path.__{{ control_name }}.FAIL
    

Проверка свободного места для точки монтирования local_backup_path#

Проверка наличия свободного места для осуществления резервного копирования в директорию local_backup_path (отображается в логе как «локальный бэкап») складывается из следующих параметров:

  • Размер кластера СУБД (текущего каталога pgdata).

  • Вычисляется процент от размера кластера СУБД. Процент задается в параметре local_backup_coefficient в настраиваемом конфигурационном файле (по умолчанию равен 1%).

  • 1 Гб, если точка монтирования local_backup_path совпала с точкой монтирования для PGBACKUP.

Если в точке монтирования для local_backup_path не хватает места, то выводится ошибка:

{{ control_name }}.SPACE.FAIL__Не достаточно свободного места для локальной резервной копии в local_backup_path_folder. Доступно local_backup_path_free_mb Мб. Требуется >= local_size_backup_mb Мб.__{{ control_name }}.SPACE.FAIL

Проверка точек монтирования#

Производится проверка прав для записи в каталоги, которые могут быть точками монтирования - PGDATA, PGBACKUP и PGLOGS.

Если скриптам развертывания не удается выполнить запись в данные каталоги, то выводится ошибка:

"FAIL__Инсталлятор не может записать файлы в директорию dir. Проверьте маску директории или назначьте владельца postgres.__FAIL"

Проверка расположения виртуальных сред#

При проверке расположения заранее подготовленных виртуальных сред, в случае их расположения в директориях $PGHOME/postgresql_venv или /usr/patroni, выводится ошибка:

"{{ control_name }}.FAIL__В конфигурационном файле обнаружен недопустимый путь до {} данный путь не должен совпадать с корневым путем установки {} {}. Для продолжения установки/обновления требуется скорректировать данный путь в конфигурационном файле.__{{ control_name }}.FAIL"

Проверка консистентности виртуальных сред#

При проверке наличия виртуальных сред по путям, указанным в конфигурационном файле, а также консистентности установленных библиотек в данных виртуальных окружениях, в случае, если виртуального окружения не существует или в нем отсутствует какая-либо из зависимостей, будет выведено сообщение:

"INFO_Директория указанная в конфигурационном файле {} пуста или в ней отсутствуют пакеты для дальнейшей установки/обновления. Для дальнейшего процесса установки/обновления будет создано виртуальное окружение автоматически_INFO"

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

Проверка типа файловой системы для каталогов текущая PGDATA, новая PGDATA, PGBACKUP, local_backup_path#

Проверка в скрипте выполняется для типа обновления update_complexity_level_2/update_complexity_level_3.

Для каталогов запрашивается тип файловой системы. Список каталогов:

текущая pgdata (пример: /pgdata/04/data)
новая pgdata (пример:/pgdata/05/data)
pgbackup (пример: /pgarclogs/04)
local_backup_path (пример: /pgarclogs)

Для типов обновления update_complexity_level_2/update_complexity_level_3 типы файловой системы для каталогов должны совпадать. Если типы файловой системы не равны, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Для продолжения обновления необходимо, чтобы директории с текущей pgdata, новой pgdata, pgbackup и local_backup_path находились в одной файловой системе. Тип файловой системы: текущая pgdata: pgdata_old_file_system_type, новая pgdata: pgdata_file_system_type, pgbackup: pgbackup_file_system_type, local_backup_path: local_backup_path_file_system_type.__{{ control_name }}.FAIL

Проверка корректного расположения PGDATA#

Проверяется расположение PGDATA, с которой работает СУБД. В случае если расположение отличается от эталонного значения, то выводится ошибка:

{{ control_name }}.FAIL__В кандидате на обновление обнаружено некорректное расположение PGDATA. Сейчас - pgdata_real. Должно быть - pgdata_should_be__{{ control_name }}.FAIL

Для версии ниже 4.3.0 эталонное значение - /pgdata/11/data.

Для версии с 4.3.0 до 5.1.0 - /pgdata/<мажорная версия, пример 04>/data.

Для версии начиная с 5.1.0 и выше - /pgdata/<мажорная версия, пример 05>/data.

Проверка работоспособности клиентского сертификата postgres, который уже есть на стенде#

Проверяется возможность подключения к БД с использованием сертификата. При успешном подключении осуществляется выполнение тестового запроса на active:

SELECT version();

В случае возникновения ошибок распечатывается следующая инструкция и выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Локальный для {{ inventory_hostname }} пользователь postgres не может подключиться к БД используя сертификаты. Возможные причины: \
1.Проверьте валидность дат сертификатов командами: \
openssl x509 -in {{ pg_certs_pwd.postgres_cert }} -noout -enddate; \
openssl x509 -in {{ pg_certs_pwd.root_ca }} -noout -enddate; \
2.Проверить принадлежность сертификатов  к одному УЦ с помощью команд: \
openssl x509 -in {{ pg_certs_pwd.postgres_cert }} -noout -text; \
openssl x509 -in {{ pg_certs_pwd.root_ca }} -noout -text; \
openssl x509 -in <значение параметра ssl_cert_file из конфига postgresql.conf> -noout -text; \
3.Проверьте наличие строки подключения в pg_hba 'hostssl all postgres {{ ansible_default_ipv4.address }}/32 cert'__{{ control_name }}.FAIL

Проверка наличия библиотеки cracklib#

Осуществляется запрос проверки наличия библиотеки и словарей в каталоге PGHOME.

Список необходимых файлов:

libcrack.so
pw_dict.hwm
pw_dict.pwd
pw_dict.pwi

Если хотя бы один файл отсутствует, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Библиотека cracklib не найдена. Обратитесь к администраторам СУБД за решением__{{ control_name }}.FAIL

Если соединение с БД не установлено, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Не удалось осуществить тестовое соединение к БД на {{ inventory_hostname }}. Обратитесь к администраторам СУБД за помощью__{{ control_name }}.FAIL

Проверка использования KMS-заменителя#

Обновление стендов с включенным КМС-заменителем произвести будет невозможно. В скриптах разведчика организована проверка на случай таких стендов. Сообщение скрипта-разведчика будет выглядеть следующим образом:

{{ control_name }}.FAIL__На стенде обнаружено использования VAULT заменителя. Произвести обновление будет невозможно.__{{ control_name }}.FAIL

Проверка структуры каталогов PGDATA#

Скрипт запрашивает структуру каталогов на active и standby для кластерной конфигурации. Если структура каталогов отличается, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Разная структура каталогов в каталоге pgdata на серверах. Обратитесь к администраторам БД для анализа проблемы. Со структурой можно ознакомиться в логе задачи (имя таски: pgdata directory structure).__{{ control_name }}.FAIL

Проверка символических ссылок в PGDATA#

Скрипт запрашивает на active и standby список всех символических ссылок в каталоге PGDATA и определяет куда они направлены. Если символические ссылки отличаются, то выводится блокирующая дальнейшее выполнение сценария ошибка:

{{ control_name }}.FAIL__Отличаются символические ссылки в каталоге pgdata на серверах. Обратитесь к администраторам БД для анализа проблемы. Со списком символических ссылок можно ознакомиться в логе задачи (имя таски: symlinks in pgdata).__{{ control_name }}.FAIL

При обработке ошибки необходимо перейти в лог выполнения задачи и поиском найти задачу symlinks in pgdata. В задаче распечатана информация для анализа различий.

Проверка наличия записей в схеме public#

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

SELECT format('{{ item.datname }}.%1$s.%2$s',table_schema,table_name) data_public
FROM information_schema.tables
WHERE table_schema = 'public' AND table_name NOT LIKE 'pathman%' AND table_name NOT LIKE 'pg_stat_state%';

Если результат выполнения запроса не пустой, то выводится не блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Данные в схеме public существуют, необходимо руками их перенести в другую схему и повторить обновление. Список таблиц (<имя базы>.<имя схемы>.<имя таблицы>: table_name__{{ control_name }}.FAIL

Проверка установленных расширений с поддерживаемыми расширениями#

Под пользователем postgres выполняется запрос к БД:

SELECT format('{{ item.datname }}.%1$s.%2$s',nspname,extname) extname FROM pg_catalog.pg_extension ex
JOIN pg_namespace ns ON ex.extnamespace =ns.oid
WHERE ex.extname not in ({{ _list_extensions }}{{ additional_legal_ext }});

В запросе происходит сравнение установленных расширений с поддерживаемыми.

legal_extensions:
  contrib: "'adminpack', 'amcheck', 'auth_delay', 'auto_explain', 'autoinc', 'bloom', 'btree_gin', 'btree_gist', 'citext', 'cube', 'dblink', 'dict_int', 'dict_xsyn', \
            'earthdistance', 'file_fdw', 'fuzzystrmatch', 'hstore', 'hstore_plperl', 'hstore_plperlu', 'hstore_plpython2u', 'hstore_plpython3u', 'hstore_plpythonu', 'hstore_plpython', \
            'insert_username', 'intagg', 'intarray', 'isn', 'jsonb_plperl', 'jsonb_plperlu', 'jsonb_plpython2u', 'jsonb_plpython3u', 'jsonb_plpythonu', 'jsonb_plpython', 'lo', 'ltree', \
            'ltree_plpython2u', 'ltree_plpython3u', 'ltree_plpythonu', 'ltree_plpython', 'moddatetime', 'pageinspect', 'pg_buffercache', 'pg_freespacemap', 'pg_prewarm', 'pg_stat_statements', \
            'pg_trgm', 'pg_visibility', 'pgcrypto', 'pgrowlocks', 'pgstattuple', 'plperl', 'plperlu', 'plpgsql', 'plpython2u', 'plpythonu', 'pltcl', 'pltclu', 'postgres_fdw', \
            'refint', 'seg', 'sslinfo', 'tablefunc', 'tcn', 'tsm_system_rows', 'tsm_system_time', 'unaccent', 'uuid-ossp', 'xml2', 'bool_plperlu', 'bool_plperl', \
            'oid2name', 'online_analyze', 'pg_backup', 'pg_standby', 'protected_dump', 'pg_profile', 'orafce', 'pg_squeeze', 'pg_cron', 'pg_pathman', 'pg_repack', 'pgse_backup', 'pg_hint_plan', \
            'pg_outline', 'oracle_fdw', 'tds_fdw', 'psql_lockmon', 'pg_stat_kcache', 'psql_rotate_password', 'fasttrun', 'fulleq', 'mchar', 'psql_diagpack', \
            'pg_store_plans', 'pg_orphaned', 'pgcompacttable', 'timescaledb', 'rum', 'pg_variables'"

Внимание!

Расширения (pg_background, postgis, pgrouting), не входящие в состав Pangolin, не поддерживаются скриптами автоматического обновления.

Если в БД установлены расширения, не указанные в спискеcontrib, то для типа обновления update_complexity_level_1 выводится предупреждающее сообщение:

{{ control_name }}.WARNING__Текущая версия СУБД содержит следующие расширения, не входящие в состав Pangolin (<имя базы>.<имя схемы>.<имя расширения>): extension_name. Для дальнейшей работы данных расширений необходимо после обновления проверить их работоспособность.__{{ control_name }}.WARNING

Для типа обновления update_complexity_level_2/update_complexity_level_3 выводится не блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Текущая версия СУБД содержит следующие расширения, не входящие в состав Pangolin или для данных расширений обновление не поддерживается (<имя базы>.<имя схемы>.<имя расширения>): extension_name.__{{ control_name }}.FAIL

Проверяется, установлено ли расширение timescaledb. Если установленное расширение имеет версию 2.4.0 или 2.4.2 и распространяется под лицензией Apache 2.0, то подобным стендам доступны все типы обновлений в автоматическом режиме. В случае, если расширение поставляется с другой лицензией, выводится аналогичная ошибка.

Внимание!

При использовании расширения timescaledb реиндекс БД не может быть выполнен с флагом --concurrently.

При сценарии ручного мажорного обновления СУБД Pangolin с версий 4.х.х и 5.х.х до 5.5.latest, при использовании на кластере расширения timescaledb, требуется выполнение дополнительных шагов. Поддерживается обновление с timescaledb версии 2.4.0 и 2.4.2, распространяемым под лицензией Apache 2.0.

Проверка портов по умолчанию в БД, pgbouncer, HAProxy#

Выполняется скрипт для получения списка портов:

netstat -tulpn 2>/dev/null | grep -E "postgres|pgbouncer|haproxy" | awk '{print $4}' | awk -F ":" '{print $2}'

Если вывод отличается от значений портов в конфигурации, то будут показаны предупреждения:

{{ control_name }}.WARNING__В кандидате на обновление обнаружено использование старого порта > PGPORT = pgport_old, нерекомендуемого безопасностью.__{{ control_name }}.WARNING

{{ control_name }}.WARNING__В кандидате на обновление обнаружено использование старого pgbouncer > порта pgbouncerport_old, нерекомендуемого \безопасностью.__{{ control_name }}.WARNING

{{ control_name }}.WARNING__В кандидате на обновление обнаружено использование старого haproxy порта haproxyport_old, нерекомендуемого безопасностью.__{{ control_name }}.WARNING

Проверка соответствия списка учетных записей ролевой модели Pangolin#

Под пользователем postgres выполняется скрипт:

SELECT usename
FROM pg_user
WHERE usesysid != all
((SELECT grolist FROM pg_group WHERE groname = 'as_admin') ||
(SELECT grolist FROM pg_group WHERE groname = 'db_admin') ||
(SELECT grolist FROM pg_group WHERE groname = 'as_TUZ') ||
(SELECT grolist FROM pg_group WHERE groname = 'pg_read_all_settings') ||
(SELECT grolist FROM pg_group WHERE groname = 'as_admin_read') ||
(SELECT grolist FROM pg_group WHERE groname = 'all-sa-pam-group'))
AND usename NOT IN ('backup_user', 'postgres', 'auditor', 'pgbouncer', 'pstgcmdb',
'masteromni', 'patroni', 'cron', 'profile_tuz', 'sec_admin_backup', 'sec_admin')

Если скрипт вернет не пустое значение (список пользователей), то выводится предупреждение:

{{ control_name }}.WARNING__Пользователь {{ list_wrong_users | join(', ') }} не соответствует ролевой модели. Его настройка произведена не будет__{{ control_name }}.WARNING

Проверка, что в СРК используется УЗ backup_user (только для промышленной эксплуатации)#

Проверяется наличие скрипта manage_backup.sh и, если он отсутствует, то выводится блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Файл manage_backup.sh не существует. Обратитесь к администраторам БД__{{ control_name }}.FAIL

В случае, если на ПРОМ-стенде в инструменте резервного копирования обнаружено использование другой УЗ, то выводится блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Техническая учетная запись backup_user не используется в процессе резервного копирования. Обратитесь к администраторам БД__{{ control_name }}.FAIL

Проверка статуса состояния снятия РК (только для промышленной эксплуатации)#

Проверяется статус снятия РК через представление backup.history. При получении значений статуса, отличного от failed, complited или waiting_from_wal_backup, будет выведена ошибка, блокирующая выполнение сценария:

{{ control_name }}.FAIL__На текущий момент обновление невозможно так как активна сессия снятия РК. Дождитесь окончания снятия РК со стенда__{{ control_name }}.FAIL

Проверка доступности прав на выполнение некоторых функций для снятия РК переданному пользователю для резервного копирования (только для промышленной эксплуатации)#

Проверяется возможность пользователя, переданного на вход через параметр user_for_backup выполнять ряд функций для резервного копирования. Если у данного пользователя отсутствует возможность выполнить одну их функций, выводится предупреждение:

{{ control_name }}.WARNING__Пользователь {user_for_backup} не имеет прав на выполнение функции {fuction}. Для данного пользоватея необходимо будет добавить права на выполнение данной функции. В противном случае, служба СРК после обновления не сможет создавать РК в процессе своей работы.__{{ control_name }}.WARNING

Проверка confd#

Если установлен confd, то выводится предупреждающее сообщение:

{{ control_name }}.WARNING__В случае использования конфигурации СУБД cluster-patroni-etcd-pgbouncer (версии СУБД Pangolin до 5.1.0) \
при обновлении СУБД Pangolin версии 5.2.0, утилита confd будет автоматически удалена. Поэтому до обновления необходимо изменить строку подключения \
к СУБД (проверить значения портов) и убедиться что в строке указаны оба узла кластера (active и standby). Например, если раньше было \
«jdbc:postgresql://127.0.0.1:6544,127.0.0.2:6544/dbname?prepareThreshold=0», то необходимо исправить на «jdbc:postgresql://127.0.0.1\
:6544,127.0.0.2:6544/dbname?targetServerType=master&prepareThreshold=0»__{{ control_name }}.WARNING

Вывод информационного сообщения с набором действий, которые необходимо произвести после завершения процесса обновления СУБД#

{{ control_name }}.TODO.AFTER__Набор действий, необходимых произвести ПОСЛЕ завершения процесса обновления СУБД:

1) Необходимо учесть, что файл recovery.conf более не используются в логике работы СУБД (для кластерной конфигурации).
2) В работе автоматизированной системы необходимо учесть, что была расширена информация о клиентских сертификатах SSL в представлении pg_stat_ssl и колонка clientdn была переименована в client_dn.
3) В работе автоматизированной системы необходимо учесть, что были изменены параметры хранения и ротации WAL-файлов, параметр wal_keep_segments был объявлен устаревшим, поэтому необходимо перейти на использование параметра wal_keep_size.
4) Обращаем внимание, что начиная с версии СУБД Pangolin 5.1.0 введено понятие TRUSTED EXTENSIONS, таким образом определенные расширения (список таких расширений можно получить с помощью запроса SELECT DISTINCT name FROM pg_available_extension_versions WHERE TRUSTED ORDER BY name;) в дальнейшем могут быть созданы пользователями с правами CREATE (пользователи входящие в as_admin группу) на уровне базы данных.
5) В работе автоматизированной системы необходимо учесть, что в новой версии СУБД Pangolin могли быть изменены некоторые вендорские процедуры, а именно, мог измениться состав или порядок аргументов для них (например, функции sec_admin, в которых убран аргумент current_database).
Рекомендация: перед началом обновления версии СУБД необходимо внимательно изучить release notes новой версии.__{{ control_name }}.TODO.AFTER

Вывод информационного сообщения для типа обновления update_complexity_level_3#

Если тип обновления update_complexity_level_3, то выводится информационное сообщение:

{{ control_name }}.INFO__Для миграции данных БД используется специальная утилита pg_upgrade. В ходе миграции данные в новую версию БД будут перенесены в режиме копирования, что повлечет дополнительное увеличение времени обновления СУБД.__{{ control_name }}.INFO

Вывод информационного сообщения о недоступности СУБД#

{{ control_name }}.INFO__На время выполнения обновления база данных будет недоступна. Просим вас это учесть при проведении работ.__{{ control_name }}.INFO

Проверка расширений установленных в системный каталог или в схему public#

Выполняется запрос к БД:

SELECT format('%2$s.%1$s',extname,nspname) extname
FROM pg_catalog.pg_extension ex
JOIN pg_namespace ns ON ex.extnamespace =ns.oid
WHERE (ns.nspname='public') OR (ns.nspname SIMILAR TO '(pg_|information_schema)%' AND ex.extrelocatable);

Если результат запроса не пустой, то выводится предупреждающее сообщение:

{{ control_name }}.WARNING__Установка расширений в схему public или в системный каталог противоречит ВНД. Список расширений, установленных в них (<имя схемы>.<имя расширения>): extension_name__{{ control_name }}.WARNING

Проверка не поддерживаемых типов данных#

Выполняется запрос к БД:

SELECT format('%1$s.%2$s(%3$s)',ns.nspname,cl.relname,att.attname) tbl_fld
FROM pg_attribute att
JOIN pg_type tp ON att.atttypid =tp.oid
JOIN pg_class cl ON att.attrelid =cl.oid
JOIN pg_namespace ns ON cl.relnamespace = ns.oid
WHERE tp.typname IN ('abstime','reltime','tinterval') AND NOT (ns.nspname SIMILAR TO '(pg_|information_schema)%');

Если результат запроса не пустой, то выводится не блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Удалена поддержка типов данных abstime, reltime, tinterval. Список таблиц, использующих их (<имя схемы>.<имя таблицы>(<имя колонки>)): table_name__{{ control_name }}.FAIL

Проверка массива типов из information_schema#

Выполняется запрос к БД:

SELECT format('%1$s.%2$s(%3$s)',ns.nspname,cl.relname,att.attname) tbl_fld
FROM pg_attribute att
JOIN pg_type tp ON att.atttypid =tp.oid
JOIN pg_class cl ON att.attrelid =cl.oid
JOIN pg_namespace ns ON cl.relnamespace = ns.oid
WHERE tp.typname IN ('cardinal_number','character_data','sql_identifier','time_stamp','yes_or_no') AND NOT (ns.nspname SIMILAR TO '(pg_|information_schema)%');

Если результат запроса не пустой, то выводится не блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Не поддерживаются массивы типов из information_schema. Список таблиц, использующих их (<имя схемы>.<имя таблицы>(<имя колонки>)): table_name__{{ control_name }}.FAIL

Проверка наличия процедур с использованием Python 2.x#

Выполняется запрос к БД:

SELECT format('%1$s.%2$s',ns.nspname,pp.proname) pr_name
FROM pg_proc pp
JOIN pg_catalog.pg_language pl ON pp.prolang =pl.oid
JOIN pg_namespace ns ON pp.pronamespace =ns.oid AND pl.lanname SIMILAR TO 'plpython2?u%';

Если результат запроса не пустой, то выводится не блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Прекращена поддержка языка Python 2.х. Список процедур, использующих их (<имя схемы>.<имя процедуры>): procedure_name__{{ control_name }}.FAIL

Проверка наличия установленного RPM-пакета Pangolin на серверах#

Производится проверка установленного RPM-пакета Pangolin с новой версией, если пакет обнаружен, то выводится блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Найден установленный пакет package_name с версией на которую планируем обновляться. Обновление не может быть продолжено. Просьба удалить пакет и повторить попытку снова.__{{ control_name }}.FAIL

Удаление каталога для временных файлов#

{{ local_backup_path }}/scout_temp_data

Проверка наличия каталога для временных файлов#

{{ local_backup_path }}/scout_temp_data`

Проверка с помощью утилиты pg_upgrade#

Проверка возможности обновления с помощью утилиты pg_upgrade check.

Если проверка завершается с ошибкой, то выводится не блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Не прошла одна из проверок pg_upgrade. Обратитесь к администраторам БД для анализа проблемы. \С ошибками можно ознакомиться в логе задачи (имя таски: journal pg_upgrade).__{{ control_name }}.FAIL

При обработке ошибки необходимо перейти в лог выполнения задачи и поиском найти задачу journal pg_upgrade. В задаче распечатаны все лог-файлы утилиты pg_upgrade.

Проверка с помощью утилиты pg_dumpall#

Проверка осуществляется с помощью утилиты pg_dumpall --schema-only --no-tablespaces --no-privileges.

Проверка заключается в снятии дампа схемы на текущей БД и загрузка схемы в экземпляр основанный на новой версии

Во время выполнения будут выведены ошибки:

Если во время старта СУБД произошла неожиданная ошибка, то выводится блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Произошла неожиданная ошибка во время старта СУБД для проверки загрузки схемы данных. Обратитесь к администраторам БД для анализа проблемы. Список ошибок: list_errors.__{{ control_name }}.FAIL

Если во время загрузки схемы данных произошла неожиданная ошибка, то выводится блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Произошла неожиданная ошибка во время проверки загрузки схемы данных. Обратитесь к администраторам БД для анализа проблемы. Список ошибок: list_errors.__{{ control_name }}.FAIL

Если во время загрузки схемы данных происходит понятная ошибка, то выводится не блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__Найдены ошибки во время проверки загрузки схемы данных. Обратитесь к администраторам БД для анализа проблемы. Ссылка на схему данных в папке с логами: (ansible_fqdn)pg_scout_log_link/currentdb.sql. Список ошибок: list_errors. Если после анализа выявлено, что ошибка ложно положительная, то необходимо добавить эту ошибку в фильтр в переменную false_error_filter_for_data_schema настраиваемого конфигурационного файла.__{{ control_name }}.FAIL

Проверка минимальной конфигурации ЦПУ и ОЗУ на обновляемых стендах#

Проверка осуществляется путем сбора системных параметров стенда и сравнения с минимальными значениями, указанными в файле конфигурации custom_file_template.yml. Если проверка обнаружила несоответствие минимальным требованиям, будет выдана ошибка:

{{ control_name }}.FAIL__Хост {host_name} не соответствует минимальным требования по CPU. Минимальное значение {count_cpu}.__{{ control_name }}.FAIL
{{ control_name }}.FAIL__Хост {host_name} не соответствует минимальным требования по RAM. Минимальное значение {count_ram}.__{{ control_name }}.FAIL

Проверка наличия установленных пакетов Pangolin разной версии#

Происходит проверка наличия установленных пакетов platform-v-pangolin-dbms и postgresql-sber-edition, если они оба установлены, то будет выведено сообщение:

"{{ control_name }}.FAIL__На стенде установлено 2 разных пакета Pangolin - platform-v-pangolin-dbms и postgresql-sber-edition. Необходимо удалить неактуальный пакет__.{{ control_name }}.FAIL"

Проверка существования файлов блокирующих обновление#

Если во время повторного запуска обновления, были найдены файлы блокирующие обновление (disallow_update или .trigger_stop_update), то в зависимости от установленного рычага remove_block_update_tmp_files в конфигурационном файле они будут удалены. После удаления будет выведено сообщение об удалении данных файлов:

{{ control_name }}.INFO__Был найден и удален триггер прерывания обновления.__{{ control_name }}.INFO
{{ control_name }}.INFO__Был найден и удален файл предыдущего неудачного обновления.__{{ control_name }}.INFO

Проверка наличия логической репликации#

Происходит проверка наличия логической репликации в СУБД. Если она будет найдена, то будет выведено сообщение:

"{{ control_name }}.FAIL__На стенде {} обнаружено использование логической репликации, для продолжения обновления требуется удалить слот(ы) логической репликации: {}.__{{ control_name }}.FAIL"

Вывод информационного сообщения estimation_update_execution_time#

При успешном прохождении выше описанных проверок и наличия не пустого значения параметра estimation_update_execution_time в настраиваемом конфигурационном файле выводится информационное сообщение:

{{ control_name }}.INFO__{{ estimation_update_execution_time }}__{{ control_name }}.INFO

Проверка успешного завершения сценария#

При успешном прохождении выше описанных проверок выведется сообщение

{{ control_name }}.OK__Разведка перед обновлением успешно выполнена.__{{ control_name }}.OK

Обработка неизвестной ошибки#

В случае появления неожиданной ошибки, будет выводиться блокирующая выполнение сценария ошибка:

{{ control_name }}.FAIL__В процессе работы скрипта разведки произошла неожиданная ошибка. Обратитесь к администраторам БД для анализа проблемы.__{{ control_name }}.FAIL

Если проверка прошла успешно, то можно приступать к процессу обновления.

Проверка установленного пакета СУБД Pangolin версии, на которую планируется обновление#

Если скриптом-разведчиком будет обнаружен установленный rpm-пакет СУБД Pangolin версии, на которую планируется обновление, то выводится ошибка:

"FAIL__На стенде установлен пакет Pangolin версии 05.005.00, на которую планируется обновление. Необходимо удалить данный пакет.__FAIL"

Проверка каталога исполняемых файлов в кластере СУБД Pangolin#

Скрипт-разведчик выполняет сравнение каталогов с исполняемыми файлами на всех хостах с СУБД Pangolin и если они отличаются, то выводится ошибка, блокирующая дальнейшее выполнение сценария:

"FAIL__Зафиксировано несоответствие директории '/usr/pangolin-5.2.4', '/usr/pangolin-5.2.5' между узлами кластера. Необходимо произвести их корректировку.__FAIL"

Проверка состояния близости БД к порогу заморозки транзакций autovacuum_freeze_max_age#

Скрипт-разведчик получает возраст заморозки старейшей из баз, а также значение параметра autovacuum_freeze_max_age, установленного системно и для отдельных таблиц, TOAST-таблиц, после чего сравнивает возраст заморозки с наименьшим значением параметра autovacuum_freeze_max_age. Если возраст заморозки больше 80% от наименьшего значения autovacuum_freeze_max_age выводится предупреждение:

WARNING__:База данных близка к порогу принудительной заморозки транзакций. Перед обновлением необходимо предварительно либо выполнить vacuumdb -a -F -v (заморозка транзакций в кластере баз), либо увеличить значение параметра autovacuum_freeze_max_age для таблиц в БД, исходя из формулы max_frozen_age > 0.8 * autovacuum_freeze_max_age
Список таблиц:
{}.WARNING

WARNING__:База данных близка к порогу принудительной заморозки транзакций. Перед обновлением необходимо предварительно либо выполнить vacuumdb -a -F -v (заморозка транзакций в кластере баз), либо увеличить значение параметра autovacuum_freeze_max_age глобально, исходя из формулы max_frozen_age > 0.8 * autovacuum_freeze_max_age.WARNING

Проверка количества транзакций с незавершенным статусом#

Скрипт-разведчик выполняет поиск строк с незавершенным статусом транзакции, в случае превышения подобных транзакций свыше 3,15 млн будет выведено предупреждение:

{{ control_name }}.WARNING__Обнаружены базы данных с большим количеством транзакций с незавершенным статусом. Рекомендуется выполнить следующую команду перед запуском обновления: vacuumdb -v -d db_name  (запуск очистки базы данных ), где db_name - имя БД из списка. \n\
Список БД: {}.__{{ control_name }}.WARNING

Пороговое количество транзакций определено исходя из максимального количества записей, которые могут содержаться в одном журнале и количества самих журналов (эмпирически определено как 3).

Обновление Pangolin#

Внимание!

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

Чтобы выполнить обновление Pangolin:

  1. Скачайте и распакуйте дистрибутив на сервере.

  2. Перейдите в каталог с распакованным дистрибутивом, а затем в каталог installer.

  3. Перед запуском обновления заполните файл hosts.ini в зависимости от установленного решения добавив информацию о хостах и учетных данных пользователя, которые будет использовать Ansible.

    Внимание!

    Данные должны содержать те же параметры, что и при установке. Примеры заполнения файлов описаны в разделе «Установка».

  4. Заполните настраиваемый конфигурационный файл custom_file_sample.yml.

    Примечание:

    При обновлении в секции 3.1.HBA RULES не поддерживаются следующие параметры:

    • ldap_tls;

    • cert_dir;

    • openldap_config.

    Заполнять их нет необходимости.

  5. Заполните конфигурационный файл all.yml.

  6. Выполните ansible-сценарий.

    Ниже приведены шаблоны ansible-сценариев для обновления различных решений:

  • Обновление односерверного решения:

    ansible-playbook playbook_updates.yaml \
    -i inventories/standalone/hosts.ini  \
    -t always,standalone \
    --ask-vault-pass \
    -vv \
    -e '{"update_complexity_level": "update_complexity_level_2"}' \
    --extra-vars "local_distr_path=${} \
    segment=${} \
    custom_config=${} \
    stand=${}"
    
  • Обновление кластерного решения:

    ansible-playbook playbook_updates.yaml \
    -i inventories/cluster/hosts.ini  \
    -t always,cluster \
    --ask-vault-pass \
    -vv \
    -e '{"update_complexity_level": "update_complexity_level_2"}' \
    --extra-vars "local_distr_path=${} \
    segment=${} \
    custom_config=${} \
    stand=${}"
    

Описание параметров:

  • custom_config - абсолютный путь к файлу конфигурации custom_config_sample.yml;

  • local_distr_path - абсолютный путь к загруженному и распакованному дистрибутиву Pangolin;

  • segment - сегмент сети;

  • stand - стенд для тестирования или конечной инсталляции (dev или prom).

Значения используемых в команде запуска Ansible ключей:

  • -i - путь к inventory-файлу;

  • --extra-vars - переменные, которые по приоритету важнее переменных из inventory;

  • -t - теги для запуска;

  • -v - уровень логирования Ansible. Может быть, как пустым, так и -vvvvvv, где запуск без v - минимальное логирование.

После завершения обновления у пользователя postgres в его корневой директории будет сгенерирован файл с названием .process_work_statuses. В нем будет отображаться состояние корректности установленных обновлений. Ниже приведен пример данного файла с конфигурации продукта standalone-postgresql-pgbouncer:

Разведка перед обновлением СУБД Pangolin запущена, текущая конфигурация standalone-postgresql-pgbouncer , тип обновления update_major, режим обновления hardlink
Разведка перед обновлением СУБД Pangolin завершена, текущая конфигурация standalone-postgresql-pgbouncer , тип обновления update_major, режим обновления hardlink
Обновление СУБД Pangolin запущено, текущая конфигурация standalone-postgresql-pgbouncer , с версии 04.003.00 на версию 05.002.00, статус обновления: {u'aggregate': False, u'hosts': {u'replica': False, u'master': False, u'etcd': False}, u'components': {u'haproxy': False, u'pgbouncer': False, u'patroni': False, u'pg': False, u'etcd': False, u'configuration': False}, u'types': {u'etcd': {u'finally': False, u'main': False}, u'pg': {u'major_main_migrate_replica_db': False, u'remove_pgaudit': False, u'major_pre': False, u'major_post': False, u'bootstrap': False, u'role_switched': False, u'major_main_migrate_master_db': False, u'major_main_start_after_migrate_db': False, u'not_started_db': False, u'started_db': False}, u'patroni': {u'finally': False, u'main': False}}}, тип обновления update_major, режим обновления hardlink
Обновление СУБД Pangolin успешно завершено, текущая конфигурация standalone-postgresql-pgbouncer , с версии 04.003.00 на версию 05.002.00, статус обновления: {u'aggregate': False, u'hosts': {u'replica': False, u'master': False, u'etcd': False}, u'components': {u'haproxy': False, u'pgbouncer': False, u'patroni': False, u'pg': False, u'etcd': False, u'configuration': False}, u'types': {u'etcd': {u'finally': False, u'main': False}, u'pg': {u'major_main_migrate_replica_db': False, u'remove_pgaudit': False, u'major_pre': False, u'major_post': False, u'bootstrap': False, u'role_switched': False, u'major_main_migrate_master_db': False, u'major_main_start_after_migrate_db': False, u'not_started_db': False, u'started_db': False}, u'patroni': {u'finally': False, u'main': False}}}, тип обновления update_major, режим обновления hardlink

Проверки и информационные сообщения процесса обновления#

Проверка пароля через параметр postgres_db_pass#

Пароль исходной БД должен совпадать с паролем, переданным в пользовательский конфигурационный файл через параметр postgres_db_pass. В случае несовпадения в лог будет выведена ошибка, блокирующая дальнейшее обновление:

FAIL__Пароль от суперпользователя postgres в пользовательском конфигурационном файле не совпадает с текущим паролем в БД. Скорректируйте значение параметра 'postgres_db_pass' в пользовательском конфигурационном файле.__FAIL

Проверка шифрования параметра postgres_db_pass#

Значение параметра postgres_db_pass не должно быть в виде scram-sha-256 или md5. Если пароль для УЗ postgres передан не в зашифрованном с помощью ansible-vault виде, то выводится ошибка, блокирующая дальнейшее выполнение сценария:

"FAIL__Пароль от суперпользователя postgres не должен быть задан в виде хеша 'SCRAM-SHA-256' или 'md5'.__FAIL"

В случае успешного прохождения проверки будет выведено:

"INFO__Проверка пароля от суперпользователя postgres завершилась успешно.__INFO"

Проверки для определения наличия СЗИ#

К проверкам для определения наличия СЗИ в процессе обновления относятся:

  • проверка включенной защиты конфигурации (SHOW secure_config);

  • проверка включенного TDE (SELECT check_tde_is_on());

  • проверка включенной защиты от привилегированных пользователей (SELECT COUNT(1) FROM pg_catalog.pr_object WHERE datoid = 0 AND objoid = 0 AND objkind = 0).

Добавление новых параметров в локальный конфигурационный файл контролируется файлом diff.txt в скриптах развертывания/обновления. Данная доработка будет применяться к обновлению всех стендов независимо от наличия подключенных СЗИ; изменения коснулись только конфигурационных файлов СУБД (postgres.yml, postgresql.conf).

Пароль передается в момент инициализации, перед этим он переводится в хеш SCRAM-SHA-256. Строка запуска выглядит так:

# Установка
{{ PGHOME }}/bin/initdb -D {{ PGDATA }} -k -A scram-sha-256 --pwfile {{ postgres_pass }} --locale {{ locale }} --update-authid

# Обновление
{{ PGHOME }}/bin/initdb -D {{ PGDATA }} -k -A scram-sha-256 --pwfile {{ postgres_pass }} -E {{ old_postgres_encoding.query_result[0].server_encoding }} --update-authid --lc-collate {{ old_postgres_locale.settings.lc_collate.setting }} --lc-ctype {{ old_postgres_locale.settings.lc_ctype.setting }} --lc-messages {{ old_postgres_locale.settings.lc_messages.setting }} --lc-monetary {{ old_postgres_locale.settings.lc_monetary.setting }} --lc-numeric {{ old_postgres_locale.settings.lc_numeric.setting }} --lc-time {{ old_postgres_locale.settings.lc_time.setting }}

Примечание:

Значение параметра postgres_db_pass, отвечающего за проверку пароля, передаваемого в пользовательском конфигурационном файле, не должно быть в виде scram-sha-256 или md5.

Пароль суперпользователя (postgres) считывается в интерактивном режиме, а сам процесс миграции осуществляется с помощью SCRAM-SHA-256. Пароль будет считываться из параметра postgres_db_pass (старое название postgres_db_scram_pass) конфигурационного файла в зашифрованном ansible vault-виде.

Внимание!

Пароль исходной БД должен совпадать с паролем переданным в пользовательский конфигурационный файл через параметр postgres_db_pass. В случае несовпадения, продолжить процесс обновления будет невозможно.

Утилита secret_storage_client#

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

$ secret_storage_client -?
Usage:
  ./secret_storage_client <option>...
Options:
  --help             [-?]  this help
  --plugins-dir-path [-d]  path to directory containing plugins
  --plugin-log-level [-l]  plugin log level [DEBUG, LOG, INFO, NOTICE, WARNING (default), ERROR, FATAL, PANIC]
  --config                 use config file (/etc/postgres/enc_connection_settings.cfg) with settings
                           to connect to Secret storage [default]
  --interactive      [-i]  run in interactive mode
  --cluster          [-c]  cluster ID
  --host             [-h]  domain name or ip address of Secret storage
  --port             [-p]  secret storage server port
  --protocol               secret storage protocol [http (1), default: https (2)]
  --prefix           [-x]  secrets path prefix [default: kv]
  --suffix           [-s]  secrets path suffix [default: empty]
  --namespace        [-n]  secrets namespace [default: empty]
  --type             [-t]  auth type [userpass (1), approle (2)]
  --auth             [-a]  auth point [default: empty]
  --id               [-u]  login or role ID
  --root-ca          [-r]  file or folder with root certificate to check Secret storage server
  --skip-confirm     [-k]  input secret without confirmation

Pangolin product version information:
  --product_version        prints product name and version
  --product_build_info     prints product build number, date and hash
  --product_component_hash prints component hash string

The './secret_storage_client' utility is used to read secrets from Secret storage

Утилита поддерживает следующие варианты ввода параметров для подключения к хранилищу секретов:

  • Чтение параметров из файла /etc/postgres/enc_connection_settings.cfg (аргумент --config). Данный способ используется, если файл предварительно был создан утилитой setup_kms_credentials.

  • Интерактивный ввод параметров (аргумент --interactive).

  • Если параметр отсутствует в аргументах, то будет запрошен ввод его значения. Ввод пароля или secretID осуществляется только интерактивно (аргумент --interactive).

Утилита возвращает список значений всех защищаемых конфигурационных параметров, поддерживаемых СУБД Pangolin, в формате:

имя параметра|||вариант защиты|||статус параметра|||значение:::имя параметра|||вариант защиты параметра|||статус параметра|||значение

В приведенном выше формате варианту защиты может соответствовать одно из значений:

  • VST_ONLY_VAULT - параметру присваивается значение, полученное из хранилища секретов. В случае его отсутствия применяется значение по умолчанию для этого параметра;

  • VST_STRICT_VAULT - для параметра допустимо применение значения, полученного только из хранилища секретов;

  • VST_EITHER - параметру присваивается значение, полученное из хранилища секретов. В случае его отсутствия применяется значение из конфигурационного файла postgresql.conf;

  • VST_BOTH - значение параметра в хранилище секретов должно совпадать со значением в конфигурационном файле postgresql.conf. В случае отсутствия параметра в одном из источников применяется значение по умолчанию для этого параметра.

Статус параметра может быть установлен как:

  • present - присутствует в хранилище секретов;

  • absent - отсутствует в хранилище секретов;

  • null - присутствует в хранилище секретов, но значение не указано.

Ниже приведен пример:

secure_config|||VST_ONLY_VAULT|||present|||off:::password_encryption|||VST_ONLY_VAULT|||absent|||:::ssl|||VST_ONLY_VAULT|||present|||on:::allowed_servers|||VST_ONLY_VAULT|||absent|||:::ssl_ca_file|||VST_ONLY_VAULT|||absent|||:::ssl_ca_path|||VST_ONLY_VAULT|||absent|||:::ssl_cert_file|||VST_ONLY_VAULT|||absent|||:::ssl_crl_file|||VST_ONLY_VAULT|||absent|||:::ssl_crl_dir|||VST_ONLY_VAULT|||present|||/pg_ssl/crl/test/server:::ssl_key_file|||VST_ONLY_VAULT|||absent|||:::ssl_ciphers|||VST_ONLY_VAULT|||absent|||:::ssl_prefer_server_ciphers|||VST_ONLY_VAULT|||absent|||:::ssl_ecdh_curve|||VST_ONLY_VAULT|||absent|||:::ssl_dh_params_file|||VST_ONLY_VAULT|||absent|||:::ssl_passphrase_command|||VST_BOTH|||absent|||:::serverssl.pkcs12_config_path|||VST_ONLY_VAULT|||present|||/pg_ssl/server.p12.cfg:::pg_ident_conf|||VST_BOTH|||absent|||:::is_tde_on|||VST_ONLY_VAULT|||null|||:::password_policies_enable|||VST_ONLY_VAULT|||absent|||:::password_policy.deny_default|||VST_ONLY_VAULT|||absent|||:::password_policy.reuse_time|||VST_ONLY_VAULT|||absent|||:::password_policy.in_history|||VST_ONLY_VAULT|||absent|||:::password_policy.max_age|||VST_ONLY_VAULT|||absent|||:::password_policy.min_age|||VST_ONLY_VAULT|||absent|||:::password_policy.grace_login_limit|||VST_ONLY_VAULT|||absent|||:::password_policy.grace_login_time_limit|||VST_ONLY_VAULT|||absent|||:::password_policy.expire_warning|||VST_ONLY_VAULT|||absent|||:::password_policy.lockout|||VST_ONLY_VAULT|||absent|||:::password_policy.lockout_duration|||VST_ONLY_VAULT|||absent|||:::password_policy.max_failure|||VST_ONLY_VAULT|||absent|||:::password_policy.failure_count_interval|||VST_ONLY_VAULT|||absent|||:::password_policy.check_syntax|||VST_ONLY_VAULT|||absent|||:::password_policy.min_length|||VST_ONLY_VAULT|||absent|||:::password_policy.illegal_values|||VST_ONLY_VAULT|||absent|||:::password_policy.alpha_numeric|||VST_ONLY_VAULT|||absent|||:::password_policy.min_alpha_chars|||VST_ONLY_VAULT|||absent|||:::password_policy.min_special_chars|||VST_ONLY_VAULT|||absent|||:::password_policy.min_uppercase|||VST_ONLY_VAULT|||absent|||:::password_policy.min_lowercase|||VST_ONLY_VAULT|||absent|||:::password_policy.max_rpt_chars|||VST_ONLY_VAULT|||absent|||:::password_policy.track_login|||VST_ONLY_VAULT|||absent|||:::password_policy.max_inactivity|||VST_ONLY_VAULT|||absent|||:::password_policy.use_password_strength_estimator|||VST_ONLY_VAULT|||absent|||:::password_policy.password_strength_estimator_score|||VST_ONLY_VAULT|||absent|||:::password_policy.custom_function|||VST_ONLY_VAULT|||absent|||:::password_policy.allow_hashed_password|||VST_ONLY_VAULT|||absent|||:::psql_encrypt_password|||VST_ONLY_VAULT|||absent|||:::encrypt_new_tablespaces|||VST_ONLY_VAULT|||absent|||:::test_vst_both_restart_only|||VST_BOTH|||absent|||:::password_policy.transport_password_mark_automatic|||VST_ONLY_VAULT|||absent|||:::password_policy.transport_password_life_time|||VST_ONLY_VAULT|||absent|||:::performance_insights.masking|||VST_ONLY_VAULT|||absent|||:::masking_mode|||VST_ONLY_VAULT|||absent|||:::enabled_extra_auth_methods|||VST_ONLY_VAULT|||present|||trust,cert:::enabled_sec_admin_extra_auth_methods|||VST_ONLY_VAULT|||present|||trust

Ручное обновление с переносом данных#

Ручное обновление с переносом данных с установленным расширением timescaledb#

Обновление стендов, использующих расширение timescaledb, требует реализации особого подхода. В таблице ниже описаны сценарии возможного обновления стендов, в зависимости от версии расширения.

Варианты сценариев обновления:

Исходная версия Pangolin

Версия Pangolin после обновления

Исходная версия TimescaleDB

Версия TimescaleDB после обновления

Комментарий

4.x.x

5.x.x

< 2.4.0

-

Обновление невозможно

4.x.x

5.5.latest

2.4.0

2.4.0

В ходе обновления Pangolin не выполняется повышение версии расширения timescaledb

5.2.x - 5.5.latest-1

5.5.latest

2.4.2

2.4.2

В ходе обновления Pangolin не выполняется повышение версии расширения timescaledb

5.5.latest

5.5.latest

2.4.0

2.14

Обновление timescaledb в рамках одной версии Pangolin

5.5.latest

5.5.latest

2.4.2

2.14

Обновление timescaledb в рамках одной версии Pangolin

Подготовка к обновлению#

  1. Определите, какая версия timescaledb используется в вашей БД. Для этого выполните запрос:

    SELECT extname, extversion FROM pg_extension WHERE extname = 'timescaledb'
    

    Ожидаемый вывод команды:

       extname   | extversion 
    -------------+------------
     timescaledb | 2.11.1
    (1 row)
    
  2. Убедитесь, что применяемое расширение распространяется по лицензии Apache 2.0:

    SELECT name, reset_val FROM pg_settings WHERE name ~ 'timescaledb.license'
    

    Ожидаемый вывод команды:

            name         | reset_val 
    ---------------------+-----------
     timescaledb.license | apache
    (1 row)
    

Обновление версии СУБД#

Обновление СУБД Pangolin сопряжено с переносом данных посредством утилиты pg_upgrade. Особенность переноса данных timescaledb - необходимость соблюдения условий равенства версий расширения в БД-источнике и БД-приемнике. Выполняя обновление, по стандартной инструкции обновления с переносом данных, дойдите до пункта запуска миграции с помощью утилиты pg_upgrade.

В составе дистрибутива с новой версией найдите пакет timescaledb такой же версии, как и в БД-источнике. Установите пакет. При необходимости скорректируйте права на каталог /usr/pangolin-5.5.*/:

sudo yum install {{ /path/to/timescaledb.rpm }}

Продолжайте процедуру мажорного обновления, добавив в параметры запуска pg_upgrade дополнительный флаг -c timescaledb.restoring='on'.

Финальные действия#

После успешного обновления СУБД необходимо поднять версию расширения timescaledb до целевой. Для этого:

  1. Установите rpm-пакет с актуальной версией расширения из состава дистрибутива. При необходимости скорректируйте права на каталог /usr/pangolin-5.5.*/:

    sudo yum install {{ /path/to/timescaledb.rpm }}
    
  2. Обновите версию расширения. Выполните запрос:

    ALTER EXTENSION timescaledb UPDATE;
    

Ручное обновление исполняемых файлов#

Примечание:

В качестве примера указаны значения по умолчанию. При необходимости заменить их на актуальные значения со стенда.

Поскольку инструкция является универсальной для кластерной и standalone-архитектур, каждый пункт необходимо выполнить на основном узле и на реплике.

Подготовка#

Перед началом выполнения инструкции убедитесь, что yum-репозитории доступны.

Обновление СУБД осуществляется от пользователя с правами sudo и пользователя postgres.

Обновляются только компоненты, которые есть на исходном стенде. Для отсутствующих пропустите выполнение блока.

Перед началом обновления скачайте дистрибутив в рабочий каталог и распакуйте его. В инструкции рабочим каталогом считается ~/pangolin:

mkdir -p ~/pangolin
tar -xzvf pangolin_{major_version}.tar.gz  -C ~/pangolin

Обновление до версии 555#

В инструкции используются переменные для динамической настройки. Перед выполнением команд эти переменные будут экспортироваться. Перед экспортом необходимо заменить значение на актуальные для каждой переменной в соответствии с исходным стендом:

Параметр

Описание

Пример

PGDATA_OLD

Старый путь до PGDATA

/pgdata/05/data

PGDATA_NEW

Новый путь до PGDATA

/pgdata/data_tmp/data

PGHOME_OLD

Старый путь до PGHOME

/usr/pangolin-5.2.5/

PGHOME_NEW

Новый путь до PGHOME

/usr/pangolin-5.5.5/

backup_dir

Директория расположение созданных бэкапов

/pgarchlogs/backup

Distrib_path

Путь до дистрибутива хранящийся на конечных вирутальных машин

/home/pprb_dev/distrib_5.5.5

clustername

Название кластера

clustername

PGPASSWORD

Пароль от пользователя postgres в СУБД

test_pass

JOBS_RUNNING

Количество ядер для запуска утиилт во время обновления

6

scripts_path

Путь до sh скриптов

/home/postgres/scripts_update

Подготовительные действия#

  1. Создайте директорию:

    sudo mkdir -p /home/postgres/scripts_update
    sudo chmod 700 /home/postgres/scripts_update
    sudo chown postgres:postgres /home/postgres/scripts_update
    
  2. Создайте файл /home/postgres/scripts_update/parameters.sh с параметрами, которые будут использоваться в процедуре обновления:

    export PGDATA_OLD=/pgdata/05/data
    export PGDATA_NEW=/pgdata/data_tmp/data
    export PGHOME_OLD=/usr/pangolin-5.2.5
    export PGHOME_NEW=/usr/pangolin-5.5.5
    export backup_dir=/pgarclogs/backup
    export JOBS_RUNNING=6
    export clustername=clustername
    export PGPASSWORD='test_pass'
    export Distrib_path=/home/pprb_dev/distrib_5.5.5
    
  3. Перенесите дистрибутив pangolin-5.5.5 на целевые машины.

  4. Распакуйте дистрибутив на целевых машинах:

    tar -xzf pangolin_5.5.5.tar.gz -C $Distrib_path
    mkdir $Distrib_path/3rdparty/unpack
    tar -xzf $Distrib_path/3rdparty/3rdparty.tar.gz -C $Distrib_path/3rdparty/unpack/
    

Резервное копирование старой версии#

  1. Создайте скрипт init_backup_dir.sh:

    . /home/postgres/scripts_update/parameters.sh
    mkdir -p $backup_dir/{pgbouncer,patroni,pg_certs_rotate,pg_auth_reencrypt,pgprobackup,confd,pgdata,postgres_user,postgres_conf,pangolin}
    chown -R postgres:postgres $backup_dir
    chmod -R 700 $backup_dir
    
    if [ -e /etc/postgres ]; then
      cp -R /etc/postgres $backup_dir/postgres_conf
    fi
    
    if [ -e /opt/pangolin-common/bin/pg_certs_rotate ]; then
      cp -R /opt/pangolin-common/bin/pg_certs_rotate $backup_dir/pg_certs_rotate
      cp -R /etc/systemd/system/pg_certs_rotate_agent.service $backup_dir/pg_certs_rotate
    fi
    
    if [ -e /opt/pangolin-common/bin/pg_auth_reencrypt ]; then
      cp -R /opt/pangolin-common/bin/pg_auth_reencrypt $backup_dir/pg_auth_reencrypt
      cp -R /etc/systemd/system/pangolin_reencrypt@.service $backup_dir/pg_auth_reencrypt
    fi
    

    Запустите скрипт:

    sudo sh /home/postgres/scripts_update/init_backup_dir.sh
    
  2. Создайте скрипт для резервного копирования patroni /home/postgres/scripts_update/patroni_backup.sh :

    . /home/postgres/scripts_update/parameters.sh
    patroni_file="/etc/patroni/postgres.yml /etc/patroni/reload_pgbouncer.sh /usr/patroni/ /etc/systemd/system/patroni.service $PGDATA_OLD/patroni.dynamic.json"
    
    for path in $patroni_file; do
      if [ -e $path ]; then
     	cp -ra $path $backup_dir/patroni
      fi
    done
    

    Запустите скрипт:

    sudo sh /home/postgres/scripts_update/patroni_backup.sh
    
  3. Создайте скрипт для резервного копирования компонента pgbouncer /home/postgres/scripts_update/pgbouncer_backup.sh и после запустите его:

    . /home/postgres/scripts_update/parameters.sh
    pgbouncer_file="/etc/systemd/system/pgbouncer.service /etc/pgbouncer/pgbouncer.ini /etc/pgbouncer/userlist.txt /usr/local/bin/pgbouncer /usr/local/share/man/man1/pgbouncer.1"
    
    for path in $pgbouncer_file; do
      if [ -e $path ]; then
     	cp -ra $path $backup_dir/pgbouncer
      fi
    done
    

    Запустите скрипт:

    sudo sh /home/postgres/scripts_update/pgbouncer_backup.sh
    
  4. Создайте скрипт для резервного копирования конфигурационных файлов /home/postgres/scripts_update/backup_config_pg.sh:

    . /home/postgres/scripts_update/parameters.sh
    if [ -e $PGHOME_OLD ]; then
      cp -R $PGHOME_OLD $backup_dir/pangolin
    fi
    
    pgdata_file="$PGDATA_OLD/postgresql.conf $PGDATA_OLD/pg_hba.conf"
    
    for file in $pgdata_file; do
      if [ -e $file ]; then
     	cp -r $file $backup_dir/pgdata
      fi
    done
    
  5. Сделайте резервную копию через утилиту pg_probackup на узле, который является основным. Добавьте строку:

    host replication postgres 127.0.0.1/32 scram-sha-256
    

    В случае наличия patroni аналогичную стркоу добавить в файл /etc/patroni/postgres.yml в секцию pg_hba.

    В случае отсутствия patroni данную строку добавить в файл $PGDATA_OLD/pg_hba.conf.

  6. Выполните reload:

    • при наличии patroni:

    /usr/patroni/patroni_venv/bin/patronictl -c /etc/patroni/postgres.yml reload $clustername
    
    • при отсутствии patroni:

    $PGHOME_OLD/bin/pg_ctl reload -D $PGDATA_OLD
    
  7. Создайте скрипт для резервного копирования СУБД с помощью pg_probackup . /home/postgres/scripts_update/backup_pg_probackup.sh:

    . /home/postgres/scripts_update/parameters.sh
    $PGHOME_OLD/bin/pg_probackup init -B $backup_dir/pgprobackup
    $PGHOME_OLD/bin/pg_probackup add-instance -B $backup_dir/pgprobackup -D $PGDATA_OLD --instance $clustername
    $PGHOME_OLD/bin/pg_probackup backup -B $backup_dir/pgprobackup --instance $clustername -b FULL -h 127.0.0.1 -p 5433 -U postgres --compress-algorithm=zlib --compress-level=4 -j $JOBS_RUNNING --temp-slot --stream --progress -w
    

    Запустите его:

    sudo -u postgres /home/postgres/scripts_update/backup_pg_probackup.sh
    

    Удалите ранее созданную строку из pg_hba.

Обновление postgresql#

  1. Перед началом обновления в случае наличия patroni требуется приостановить его (pause):

    /usr/patroni/patroni_venv/bin/patronictl -c /etc/patroni/postgres.yml pause $clustername
    
  2. Создайте скрипт /home/postgres/scripts_update/install_pangolin.sh, который установит новую версию СУБД:

    . /home/postgres/scripts_update/parameters.sh
    rpm -ivh $Distrib_path/platform-v-pangolin-dbms-05.005.05-rhel7.9.x86_64.rpm
    cp -r $Distrib_path/3rdparty/unpack/cracklib/libcrack.so $PGHOME_NEW/lib/
    cp -r $Distrib_path/3rdparty/unpack/cracklib/pw_dict.hwm $PGHOME_NEW/lib/
    cp -r $Distrib_path/3rdparty/unpack/cracklib/pw_dict.pwd $PGHOME_NEW/lib/
    cp -r $Distrib_path/3rdparty/unpack/cracklib/pw_dict.pwi $PGHOME_NEW/lib/
    chown postgres:postgres $PGHOME_NEW/lib/libcrack.so
    chown postgres:postgres $PGHOME_NEW/lib/pw_dict.hwm
    chown postgres:postgres $PGHOME_NEW/lib/pw_dict.pwd
    chown postgres:postgres $PGHOME_NEW/lib/pw_dict.pwi
    chmod 0600 $PGHOME_NEW/lib/libcrack.so
    chmod 0600 $PGHOME_NEW/lib/pw_dict.hwm
    chmod 0600 $PGHOME_NEW/lib/pw_dict.pwd
    chmod 0600 $PGHOME_NEW/lib/pw_dict.pwi
    chmod 0701 $PGHOME_NEW
    chmod 0705 $PGHOME_NEW/lib
    

    Запустите:

    sudo sh /home/postgres/scripts_update/install_pangolin.sh
    
  3. Добавьте в $PGDATA_OLD/pg_hba.con строку:

    local all postgres trust
    
  4. Добавьте параметр enabled_extra_auth_methods в $PGDATA_OLD/postgresql.conf:

    enabled_extra_auth_methods = 'trust,certs'
    
  5. Сделайте reload:

    $PGHOME_OLD/bin/pg_ctl reload
    
  6. Остановите СУБД:

    • при наличии patroni:

    $PGHOME_OLD/bin/pg_ctl stop -D $PGDATA_OLD
    
    • при отсутствии patroni:

    sudo systemctl stop postgresql
    
  7. На основном узле проинициализируйте СУБД:

    PG_PLUGINS_PATH="/usr/pangolin-5.5.5/lib" LD_LIBRARY_PATH="/usr/pangolin-5.5.5/lib" /usr/pangolin-5.5.5/bin/pg_ctl -D /pgdata/data_tmp/data initdb -o --data-checksums -o '-E=UTF8'
    mv /pgdata/data_tmp/data/postgresql.conf /pgdata/data_tmp/data/postgresql.base.conf
    mv /pgdata/data_tmp/data/pg_hba.conf /pgdata/data_tmp/data/pg_hba.base.conf
    
  8. Создайте скрипт /home/postgres/scripts_update/pgdata_move.sh для перемещения файлов из PGDATA_OLD:

    . /home/postgres/scripts_update/parameters.sh
    cp -ra $PGDATA_OLD/postgresql.conf $PGDATA_NEW/postgresql.conf
    cp -ra $PGDATA_OLD/pg_hba.conf $PGDATA_NEW/pg_hba.conf
    
    if [ -e $PGHOME_OLD/pg_ident.conf ]; then
     cp -ra $PGDATA_OLD/pg_ident.conf $PGDATA_NEW/pg_ident.conf
    fi
    
    sed -i "s|/pgdata/05/data|/pgdata/data_tmp/data|" /pgdata/data_tmp/data/postgresql.conf
    sed -i "s/5.2.5/5.5.5/" /pgdata/data_tmp/data/postgresql.conf
    sed -i "s/5.2.5/5.5.5/" /etc/patroni/postgres.yml
    
    if [ -e /etc/systemd/system/patroni.service ]; then
     sed -i "s/5.2.5/5.5.5/" /etc/systemd/system/patroni.service
    else
     sed -i "s/5.2.5/5.5.5/" /etc/systemd/system/postgresql.service
    fi
    
    systemctl daemon-reload
    

    Запустите:

    sudo sh /home/postgres/scripts_update/pgdata_move.sh
    
  9. Создайте скрипт /home/postgres/scripts_update/pg_upgrade.sh для запуска утилиты pg_upgrade.:

    . /home/postgres/scripts_update/parameters.sh
    export PG_PLUGINS_PATH="$PGHOME_NEW/lib"
    export LD_LIBRARY_PATH="$PGHOME_NEW/lib"
    export PGHOST=127.0.0.1
    cd $backup_dir
    $PGHOME_NEW/bin/pg_upgrade -b $PGHOME_OLD/bin/ -B $PGHOME_NEW/bin/ -d $PGDATA_OLD -D $PGDATA_NEW -p 5433 -P 50433 -j $JOBS_RUNNING --link --retainexit
    

    Запустите:

    sudo sh /home/postgres/scripts_update/pg_upgrade.sh
    
  10. Перенесите смигрированные данные в старую директорию, а также скорректируйте ранее измененные параметры в postgresql.conf и pg_hba.con:

rm $PGDATA_OLD
mv $PGDATA_NEW $PGDATA_OLD
sed -i "s|/pgdata/data_tmp/data|/pgdata/05/data|" /pgdata/05/data/postgresql.conf

Действия при наличии patroni#

Внимание!

При отсутствии patroni не выполняйте шаги данного раздела и перейдите к следующему.

  1. Сгенерируйте ssh-ключ на основном узле и добавьте публичный ключ на реплику:

    ssh-keygen
    ssh-copy-id postgres@hostname
    
  2. Cмигрируйте данные на реплику при помощи rsync:

    rsync --archive --delete --hard-links --size-only --no-inc-recursive /pgdata/05/ postgres@hostname:/pgdata/05/
    
  3. Остановите patroni на основном узле и на реплике:

    sudo systemctl stop patroni
    
  4. Пересоздайте кластер patroni на основном узле:

    /usr/patroni/patroni_venv/bin/patronictl -c /etc/patroni/postgres.yml remove $clustername
    
  5. Запустите сначала основной узел, затем реплику:

    sudo systemctl start patroni
    

При отсутствии patroni#

Запустите СУБД:

sudo systemctl start postgresql

Действия после обновления СУБД#

  1. Запустите утилиту reindexdb:

    PG_PLUGINS_PATH="/usr/pangolin-5.5.5/lib" LD_LIBRARY_PATH="/usr/pangolin-5.5.5/lib" /usr/pangolin-5.5.5/bin/reindexdb -j $JOBS_RUNNING --all
    
  2. Запустите утилиту vaccumdb:

    PG_PLUGINS_PATH="/usr/pangolin-5.5.5/lib" LD_LIBRARY_PATH="/usr/pangolin-5.5.5/lib" /usr/pangolin-5.5.5/bin/vacuumdb -j $JOBS_RUNNING --analyze-in-stages --all
    
  3. Удалите старую версию СУБД:

    sudo yum remove platform-v-pangolin-dbms-05.002.05
    

Обновление pgbouncer#

  1. Остановите службу pgbouncer:

    sudo systemctl stop pgbouncer
    
  2. Перенесите бинарные файлы pgbouncer в директорию его расположения:

    sudo cp -r $Distrib_path/pgbouncer/usr/local/bin/pgbouncer/ /usr/local/bin/pgbouncer
    sudo chmod -R a+x /usr/local/bin/pgbouncer
    sudo chown -R root:root /usr/local/bin/pgbouncer
    
  3. Запустите pgbouncer:

    sudo systemctl start pgbouncer
    

Обновление patroni#

  1. Поставьте patroni на паузу:

    /usr/patroni/patroni_venv/bin/patronictl -c /etc/patroni/postgres.yml pause $clustername
    
  2. Остановите службу patroni:

    sudo systemctl stop patroni
    
  3. Удалите старую версию patroni:

    sudo rm -rf /usr/patroni/
    
  4. Создайте новое виртуальное окружение для patroni

    sudo mkdir -p /usr/patroni/
    sudo python3 -m venv /usr/patroni/patroni_venv
    sudo chown -R postgres:postgres /usr/patroni
    sudo chmod -R 700 /usr/patroni
    su - postgres
    source /usr/patroni/patroni_venv/bin/activate
    pip3 install -U "pip<22"
    pip3 install PyYAML==6.0.1 urllib3==1.26.* idna==3.7 certifi==2024.* charset-normalizer==2.0.* requests==2.27.* importlib-metadata==4.2.* zipp==3.6.* typing-extensions==4.0.* six==1.16.* pycodestyle==2.8.* mccabe==0.6.* pyflakes==2.4.* flake8==4.0.* lockfile==0.12.* docutils==0.18.* python-daemon==2.3.* psycopg2-binary==2.9.* kazoo==2.8.* boto==2.49.* python-dateutil==2.8.* dnspython==2.2.* python-etcd==0.4.* click==7.1.* wcwidth==0.2.* prettytable==2.2.* psutil==5.8.* cdiff==1.0 semantic-version==2.8.* setuptools-rust==1.1.*
    exit
    
  5. Создайте скрипт /home/postgres/scripts_update/patroni_update.sh для обновления patroni:

    . /home/postgres/scripts_update/parameters.sh
    
    tar -xzf $Distrib_path/patroni/patroni.tar.gz -C /usr/patroni/patroni_venv/bin/
    chown postgres:postgres /usr/patroni/patroni_venv/bin/{patroni,patronictl,patroni_raft_controller}
    chown -R postgres:postgres /usr/patroni/patroni_venv/bin/patroni_bin 
    chmod -R 700 /usr/patroni/patroni_venv/bin/patroni_bin
    
    tar -xzf $Distrib_path/patroni/postgresql_se_libs.tar.gz -C /usr/patroni/patroni_venv/lib/ 
    chown postgres:postgres /usr/patroni/patroni_venv/lib/postgresql_se_libs 
    chmod 700 /usr/patroni/patroni_venv/lib/postgresql_se_libs
    
    install -m 600 -o postgres -g postgres $Distrib_path/patroni/se_version /usr/patroni/patroni_venv/bin/se_version 
    install -m 600 -o postgres -g postgres $Distrib_path/patroni/version /usr/patroni/patroni_venv/bin/version
    

    Запустите:

    sudo sh /home/postgres/scripts_update/patroni_update.sh
    
  6. Запустите patroni:

    sudo systemctl start patroni
    
  7. Выведите из паузы patroni

    /usr/patroni/patroni_venv/bin/patronictl -c /etc/patroni/postgres.yml resume $clustername
    

Обновление утилиты перешифрования pangolin\_reencrypt в случае наличии#

  1. Остановите службу:

    sudo systemctl stop pangolin_reencrypt@postgres
    sudo systemctl stop pangolin_reencrypt@kmadmin_pg
    
  2. Обновите бинарный файлы pangolin_reencrypt:

    sudo cp $Distrib_path/utilities/pg_auth_reencrypt/opt/pangolin-common/bin/pg_auth_reencrypt /opt/pangolin-common/bin
    
  3. Обновите службу:

    sudo sed -i "s/5.2.5/5.5.5/" /etc/systemd/system/pangolin_reencrypt\@.service
    systemctl daemon-reload
    
  4. Запустите службу:

    sudo systemctl start pangolin_reencrypt@postgres
    sudo systemctl start pangolin_reencrypt@kmadmin_pg
    

Обновление утилиты ротации сертификатов pg\_certs\_rotate\_agent в случае наличия#

  1. Остановите службу:

    sudo systemctl stop pg_certs_rotate_agent.service
    
  2. Обновите бинарные файлы:

    sudo cp $Distrib_path/utilities/pg_certs_rotate/pg_certs_rotate_agent  /opt/pangolin-common/bin/pg_certs_rotate
    
  3. Обновите службу:

    sudo sed -i "s/5.2.5/5.5.5/" /etc/systemd/system/pg_certs_rotate_agent.service
    systemctl daemon-reload
    
  4. Запустите службу:

    sudo systemctl start pg_certs_rotate_agent.service
    

Изменение данных локализации при миграции с ОС Red Hat Enterprise Linux 7 на Red Hat Enterprise Linux 8 и Platform V SberLinux OS Server 8#

Данные языкового стандарта предоставляются библиотекой glibc. При мажорном обновлении с ОС Red Hat Enterprise Linux 7 происходит замена библиотеки с версии glibc-2.17 на glibc-2.28. В версии 2.28, выпущенной 2018-08-01, было включено крупное обновление данных локали, которое потенциально может повлиять на данные пользователей СУБД.

Далее рассмотрены сценарии корректного обновления.

Обновление с Red Hat Enterprise Linux 7 на Red Hat Enterprise Linux 8#

В данном случае необходимо учесть, что индексы, полученные скриптом, должны быть перестроены по завершении обновления в каждой БД до запуска промышленной нагрузки на СУБД:

SELECT DISTINCT indrelid::regclass::text, indexrelid::regclass::text, collname, pg_get_indexdef(indexrelid)
FROM (SELECT indexrelid, indrelid, indcollation[i] coll FROM pg_index, generate_subscripts(indcollation, 1) g(i)) s
  JOIN pg_collation c ON coll=c.oid
WHERE collprovider IN ('d', 'c') AND collname NOT IN ('C', 'POSIX');

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

#!/bin/bash
read -s -p "Введите пароль: " pass
echo
echo
# Получаем список баз данных
dblist=$(PGPASSWORD=$pass psql -t -c "select string_agg(datname, ' ')
  from pg_database where datname not in ('template0','template1');")
for i in $dblist
do
    # Получаем список индексов в БД
    dbidx=$(PGPASSWORD=$pass psql -d $i -t -c "\
      SELECT DISTINCT indexrelid::regclass::text idx_name \
      FROM (SELECT indexrelid, indcollation[i] coll FROM pg_index, generate_subscripts(indcollation, 1) g(i)) s \
        JOIN pg_collation c ON coll=c.oid \
      WHERE c.collprovider IN ('d', 'c') AND c.collname NOT IN ('C', 'POSIX') \
        AND indexrelid NOT IN (SELECT DISTINCT inhparent FROM pg_inherits);")
 
    echo "Текущая БД : $i"
    # Выполняем REINDEX для индексов
    for j in $dbidx
    do
        echo "Текущий обрабатываемый индекс : reindex index $j;"
        PGPASSWORD=$pass psql -d $i -c "reindex index $j;"
    done
    echo "------------------------------"
done

Обновление с Red Hat Enterprise Linux 8 на Platform V SberLinux OS Server 8#

Если обновление ОС Red Hat с 7 версии на 8 уже произошло и предыдущие шаги были пропущены, то рекомендуется перестроить потенциально поврежденные индексы в конкурентном режиме:

#!/bin/bash
read -s -p "Введите пароль: " pass
echo
echo
# Получаем список баз данных
dblist=$(PGPASSWORD=$pass psql -t -c "select string_agg(datname, ' ')
  from pg_database where datname not in ('template0','template1');")
for i in $dblist
do
    # Получаем список индексов в БД
    dbidx=$(PGPASSWORD=$pass psql -d $i -t -c "\
      SELECT DISTINCT indexrelid::regclass::text idx_name \
      FROM (SELECT indexrelid, indcollation[i] coll FROM pg_index, generate_subscripts(indcollation, 1) g(i)) s \
        JOIN pg_collation c ON coll=c.oid \
      WHERE c.collprovider IN ('d', 'c') AND c.collname NOT IN ('C', 'POSIX') \
        AND indexrelid not in (SELECT distinct inhparent FROM pg_inherits);")
     
    echo "Текущая БД : $i"
    # Выполняем REINDEX для индексов
    for j in $dbidx
    do
        echo "Текущий обрабатываемый индекс : reindex index concurrently $j;"
        PGPASSWORD=$pass psql -d $i -c "reindex index concurrently $j;"
    done
    echo "------------------------------"
done

Для проверки существующих индексов на возможные инварианты, включая расхождения в лексическом порядке с учетом правил сортировки, рекомендуется использовать скрипт на основе расширения amcheck. Для установки расширения amcheck выполните команду от суперпользователя в каждой БД:

CREATE EXTENSION amcheck SCHEMA ext;

Далее в каждой БД запустите скрипт:

do $$
declare stmt record;
declare ret record;
declare verbose_check_indexes boolean:=true; --для большого количества индексов рекомендуется установить в false для сокращения вывода
begin
    IF (select installed_version from pg_available_extensions where name='amcheck') is not null then
    for stmt in
        SELECT DISTINCT  indrelid::regclass::text as table_name,
        indexrelid::regclass::text as index_name,
        'select ext.bt_index_check('''||indexrelid::regclass::text||''');' as check_command
        ,'reindex index concurrently '||indexrelid::regclass::text||';' as reindex_command
        ,indexrelid as id
        FROM (SELECT indexrelid, indrelid, indcollation[i] coll FROM pg_index, generate_subscripts(indcollation, 1) g(i)) s
          JOIN pg_collation c ON coll=c.oid
        WHERE collprovider IN ('d', 'c') AND collname NOT IN ('C', 'POSIX') AND
          indexrelid NOT IN (SELECT distinct inhparent FROM pg_inherits)
    loop
        begin
        execute stmt.check_command  into ret;
        IF verbose_check_indexes then
            raise notice 'таблица % индекс % проверка прошла успешно',stmt.table_name,stmt.index_name ;
        END IF;
    exception when others then
            raise notice '--------------------------------------%ОШИБКА таблица % индекс %. %         Для полного текста ошибки выполните (%). %         Для реиндекса выполните (%)%         Размер индекса %. % %-----------------------------------------------',chr(10), stmt.table_name,stmt.index_name,chr(10),stmt.check_command,chr(10),stmt.reindex_command,chr(10),pg_size_pretty(pg_total_relation_size(stmt.index_named)),( select case when indisunique then 'Индекс уникален' else 'Индекс не уникален' end from pg_index where indexrelid=stmt.index_named ),chr(10) ;
        end;
    end loop;
    ELSE
        raise notice 'установите расширение amcheck';
    END IF;
end ; $$;

При отсутствии ошибок будет получено сообщение вида:

NOTICE:  таблица hint_plan.hints индекс hint_plan.hints_norm_and_app проверка прошла успешно

При возникновении ошибок:


NOTICE:  --------------------------------------
ОШИБКА таблица tron.products индекс tron.products_pkey.
         Для полного текста ошибки выполните (select ext.bt_index_check('tron.products_pkey');).
         Для реиндекса выполните (reindex index concurrently tron.products_pkey;)
         Размер индекса 0 bytes. Индекс уникален
-----------------------------------------------

Статус индекса можно узнать при помощи запроса:

select ext.bt_index_check('tron.products_pkey');

При наличии проблем для их устранения рекомендуется выполнить запрос:

reindex index concurrently tron.products_pkey;

При обнаружении в таблице дубликатов неактуальные повторные записи нужно удалить.

Внимание!

Учитывайте размер индекса и нагрузку на БД.