Перейти к содержанию

Это многостраничная версия текущего раздела для печати. .

Вернуться к обычному виду страницы.

Документация Patroni 4.1.5

Обзор документации Patroni по высокой доступности PostgreSQL.
Предупреждение

Работа Patroni на системах с ограниченной памятью и Python 3.11+

Если Patroni работает в системе со строгими ограничениями памяти, например с vm.overcommit_memory=2 (рекомендуется для PostgreSQL), и используется Python 3.11 или новее, может наблюдаться неожиданное поведение:

  • Patroni выглядит исправным
  • PostgreSQL продолжает работать
  • REST API Patroni перестаёт отвечать
  • Операционная система сообщает, что Patroni прослушивает порт REST API
  • Журналы Patroni выглядят нормально, однако однократно могут появиться сообщения Exception ignored in thread started by: <object repr() failed>, MemoryError
  • Журналы ядра могут содержать сообщения наподобие not enough memory for the allocation

Это поведение вызвано ошибкой в Python 3.11+ . При строгих ограничениях памяти запуск нового потока может зависнуть на неопределённое время, если свободной памяти недостаточно.

В последних выпусках Patroni (4.1.1+, 4.0.8+) влияние этой проблемы уменьшено: все необходимые потоки запускаются на раннем этапе запуска, прежде чем система окажется под давлением нехватки памяти.

Дополнительные рекомендации (Linux, glibc)

При работе с vm.overcommit_memory=2 (рекомендуется для PostgreSQL) также рекомендуется запускать Patroni со следующими переменными окружения:

  • MALLOC_ARENA_MAX=1 — уменьшает объём виртуальной памяти, выделяемой glibc для многопоточных приложений
  • PG_MALLOC_ARENA_MAX= — сбрасывает значение MALLOC_ARENA_MAX для процессов PostgreSQL, запускаемых Patroni.

Кроме того, можно настроить следующие параметры конфигурации Patroni:

  • thread_stack_size — размер стека потоков, запускаемых Patroni. Уменьшение этого значения сокращает потребление памяти процессом Patroni. Значение по умолчанию, заданное Patroni, — 512kB. Увеличьте thread_stack_size, если Patroni аварийно завершается из-за проблем со стеком; в противном случае значения по умолчанию достаточно.
  • thread_pool_size — размер пула потоков, используемого Patroni для асинхронных задач и связи по REST API с другими участниками во время выбора лидера или отказоустойчивых проверок. Значение по умолчанию — 5, чего достаточно для кластеров из трёх узлов.
  • restapi.thread_pool_size — размер пула потоков для обработки запросов REST API. Значение по умолчанию — 5, что позволяет параллельно обрабатывать до пяти запросов REST API. Обратите внимание: запросы, включающие SQL-запросы, фактически выполняются последовательно, поскольку используется одно соединение с базой данных, поэтому увеличение этого значения обычно не даёт преимуществ.

Patroni — шаблон для решений высокой доступности (HA) PostgreSQL на Python. Для максимальной применимости Patroni поддерживает различные распределённые хранилища конфигурации, такие как ZooKeeper , etcd , Consul и Kubernetes . Он будет полезен инженерам баз данных, администраторам баз данных, инженерам DevOps и SRE, которым необходимо быстро развернуть PostgreSQL высокой доступности в центрах обработки данных или где-либо ещё.

Мы называем Patroni «шаблоном», потому что это далеко не универсальная или готовая к работе система репликации. У неё есть свои особенности. Используйте её осмотрительно. Существует множество способов обеспечить высокую доступность PostgreSQL; их список приведён в документации PostgreSQL .

Поддерживаемые в настоящее время версии PostgreSQL: от 9.3 до 18.

Примечание для пользователей Citus: начиная с версии 3.0 Patroni хорошо интегрируется с расширением базы данных Citus для Postgres. Дополнительные сведения об использовании высокой доступности Patroni вместе с распределённым кластером Citus см. на странице поддержки Citus в документации Patroni.

Примечание для пользователей Kubernetes: Patroni может работать непосредственно поверх Kubernetes. См. главу Kubernetes документации Patroni.

изображение

1 - Введение

Введение в Patroni, быстрый старт и основные концепции высокой доступности.

Patroni — шаблон решений высокой доступности (HA) PostgreSQL на Python. Patroni возник как ответвление проекта Governor от Compose и содержит множество новых возможностей.

Дополнительные вводные материалы:


Состояние разработки

Patroni активно разрабатывается и принимает вклады сообщества. Подробнее см. раздел Участие в разработке ниже.

Сведения о новых выпусках публикуются здесь .


Технические требования и установка

Рекомендации по установке и обновлению Patroni на различных платформах приведены здесь .


Планирование количества узлов PostgreSQL

Узлы Patroni/PostgreSQL отделены от узлов DCS, кроме случая, когда Patroni самостоятельно реализует RAFT, поэтому требований к минимальному количеству узлов нет. Кластер из одного первичного и одного резервного сервера вполне работоспособен. Позднее можно добавить дополнительные резервные узлы.

Кластеры из 2 узлов (первичный и резервный сервер) широко распространены и обеспечивают автоматическое переключение при отказе с высокой доступностью. Учтите, что во время переключения избыточность временно отсутствует, пока отказавший узел не присоединится снова.

Требования к DCS: для надлежащего консенсуса и отказоустойчивости DCS (etcd, ZooKeeper, Consul) должен работать на 3 или 5 узлах. Один кластер DCS может хранить сведения о сотнях или тысячах кластеров Patroni с разными сочетаниями пространства имён и области действия.


Запуск и настройка

В следующем разделе предполагается, что репозиторий Patroni клонирован с https://github.com/patroni/patroni . Потребуются примеры файлов конфигурации postgres0.yml и postgres1.yml. Если Patroni установлен через pip, получите эти файлы из репозитория git и замените ниже ./patroni.py командой patroni.

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

> etcd --data-dir=data/etcd --enable-v2=true
> ./patroni.py postgres0.yml
> ./patroni.py postgres1.yml

После этого запустится кластер высокой доступности. Проверьте различные параметры файлов YAML и наблюдайте, как меняется поведение кластера. Завершите некоторые компоненты, чтобы увидеть реакцию системы.

Чтобы создать более крупный кластер, добавьте файлы postgres*.yml.

Patroni предоставляет конфигурацию HAProxy , которая даёт приложению единую конечную точку для подключения к лидеру кластера. Для настройки выполните:

> haproxy -f haproxy.cfg

> psql --host 127.0.0.1 --port 5000 postgres

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

Полные сведения о параметрах etcd, consul и ZooKeeper приведены здесь . Пример см. в postgres0.yml .


Конфигурация через окружение

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


Выбор режима репликации

Patroni использует потоковую репликацию Postgres, которая по умолчанию асинхронна. В конфигурации асинхронной репликации Patroni можно задать maximum_lag_on_failover. Этот параметр не допускает переключение при отказе, если последователь отстаёт от лидера более чем на указанное число байтов. Значение следует повышать или понижать в соответствии с требованиями бизнеса. Для более строгих гарантий долговечности можно также использовать синхронную репликацию. Подробнее см. документацию по режимам репликации .


Приложения не должны использовать суперпользователей

При подключении из приложения всегда используйте пользователя без прав суперпользователя. Для правильной работы Patroni нужен доступ к базе данных. Использование суперпользователя в приложении может занять весь пул соединений, включая зарезервированные для суперпользователей параметром superuser_reserved_connections. Если Patroni не сможет обратиться к первичному серверу из-за заполненного пула, поведение окажется нежелательным.


Тестирование решения HA

Тестирование решения HA — длительный процесс со множеством переменных, особенно для кроссплатформенного приложения. Для этой работы нужен подготовленный системный администратор или консультант; подробно рассмотреть её в документации невозможно.

Обязательно протестируйте следующие элементы инфраструктуры:

  • Сеть (как сеть перед системой, так и сами физические или виртуальные сетевые интерфейсы)
  • Дисковый ввод-вывод
  • Ограничения файлов (nofile в Linux)
  • RAM. Даже при отключённом oomkiller нехватка RAM может вызвать проблемы.
  • CPU
  • Конкуренция за ресурсы виртуализации (переподписка гипервизора)
  • Любые ограничения cgroup, вероятно связанные с предыдущим пунктом
  • kill -9 любого процесса postgres, кроме postmaster. Это приемлемая имитация ошибки сегментации.

Не следует выполнять kill -9 для процесса postmaster: это не имитирует реальный сценарий. Если инфраструктура настолько небезопасна, что злоумышленник может выполнить kill -9, никакие механизмы HA не исправят ситуацию. Злоумышленник просто снова завершит процесс или нарушит работу иным способом.

2 - Установка

Инструкции по установке и обновлению Patroni на поддерживаемых платформах.


Предварительные требования для Mac OS

Чтобы установить необходимые компоненты на Mac, выполните:

brew install postgresql etcd haproxy libyaml python


Psycopg

Начиная с psycopg2-2.8 двоичная версия psycopg2 больше не устанавливается по умолчанию. Для установки из исходного кода необходим компилятор C и пакеты разработки postgres и python. Поскольку в экосистеме Python нельзя указать зависимость как psycopg2 OR psycopg2-binary, способ установки нужно выбрать самостоятельно.

Доступны следующие варианты:

  1. Использовать диспетчер пакетов дистрибутива
sudo apt-get install python3-psycopg2  # install psycopg2 module on Debian/Ubuntu
sudo yum install python3-psycopg2      # install psycopg2 on RedHat/Fedora/CentOS
  1. При установке Patroni через pip указать psycopg, psycopg2 или psycopg2-binary в списке зависимостей .


Общая установка через pip

Patroni можно установить с помощью pip:

pip install patroni[dependencies]

где dependencies может быть пустым либо содержать один или несколько следующих вариантов:

etcd или etcd3
модуль python-etcd для использования Etcd как распределённого хранилища конфигурации (DCS)

consul
модуль py-consul для использования Consul как DCS

zookeeper
модуль kazoo для использования Zookeeper как DCS

exhibitor
модуль kazoo для использования Exhibitor как DCS (зависимости те же, что и для Zookeeper)

kubernetes
модуль kubernetes для использования Kubernetes как DCS в Patroni

raft
модуль pysyncobj для использования реализации Raft на Python как DCS

aws
boto3 для использования обратных вызовов AWS

jsonlogger
модуль python-json-logger для включения ведения журнала в формате json

systemd
systemd-python для интеграции с sd_notify

all
всё перечисленное выше, кроме семейства psycopg

psycopg3
модуль psycopg\[binary\]\>=3.0.0

psycopg2
модуль psycopg2\>=2.5.4

psycopg2-binary
модуль psycopg2-binary

Например, для установки Patroni вместе с psycopg3, зависимостями Etcd как DCS и обратными вызовами AWS выполните:

pip install patroni[psycopg3,etcd3,aws]

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


Установка пакетов в Linux

Для операционной системы могут быть доступны пакеты Patroni, подготовленные сообществом Postgres для:

  • RHEL, RockyLinux и AlmaLinux;
  • Debian и Ubuntu;
  • SUSE Enterprise Linux.

Также доступны пакеты прямых зависимостей Patroni, например модулей Python, которых может не быть в официальных репозиториях операционной системы.

Подробнее см. документацию репозитория PGDG .

В производной от RedHat Enterprise Linux операционной системе могут также потребоваться пакеты EPEL; см. документацию репозитория EPEL .

После подключения репозитория PGDG для своей ОС можно установить Patroni.

Примечание

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

Установка в производных Debian

После подключения репозитория PGDG, как описано выше , установите Patroni через apt:

apt-get install patroni

Установка в производных RedHat

После подключения репозитория PGDG, как описано выше , установите Patroni с DCS etcd через dnf в RHEL 9 и производных:

dnf install patroni patroni-etcd

Если производный дистрибутив RedHat не предоставляет пакеты, etcd можно установить из PGDG. На узлах DCS выполните:

dnf install 'dnf-command(config-manager)'
dnf config-manager --enable pgdg-rhel9-extras
dnf install etcd

При необходимости замените версию RHEL в репозитории на 8, получив pgdg-rhel8-extras. В RockyLinux, AlmaLinux, Oracle Linux и других имя репозитория по-прежнему имеет вид pgdg-rhelN-extras.

Установка в SUSE Enterprise Linux

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

В SLES 15 с подключённым репозиторием PGDG, как описано выше , Patroni можно установить командой:

zypper install patroni patroni-etcd

При включённом репозитории SUSE PackageHub можно также установить etcd:

SUSEConnect -p PackageHub/15.5/x86_64
zypper install etcd

Обновление

Обновление Patroni очень просто: обновите установленное программное обеспечение и перезапустите демон Patroni на каждом узле кластера.

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

Чтобы перевести кластер в режим обслуживания, выполните следующую команду на одном из узлов Patroni:

patronictl pause --wait

Затем на каждом узле кластера обновите пакеты способом, предусмотренным вашей ОС:

apt-get update && apt-get install patroni patroni-etcd

Перезапустите процесс демона Patroni на каждом узле:

systemctl restart patroni

Наконец, возобновите мониторинг Postgres через Patroni, чтобы вывести кластер из режима обслуживания:

patronictl resume --wait

Теперь кластер полностью работоспособен с новой версией Patroni.

3 - Patroni конфигурация

Patroni модель конфигурации, правила приоритета и инструменты валидации.

Существует 3 типов конфигурации Patroni:

  • Глобальная динамическая конфигурация .
    Эти параметры хранятся в DCS (распределённое хранилище конфигурации) и применяются ко всем узлам кластера. Динамическая конфигурация может быть установлена в любой момент с помощью инструмента patronictl_edit_config или Patroni REST API . Если изменённые параметры не входят в начальную конфигурацию, они применяются асинхронно (при следующем цикле пробуждения) на каждом узле, после чего узел перезагружается. Если узлу требуется перезапуск для применения конфигурации (для параметров PostgreSQL с контекстом postmaster, если их значения изменились), в members.data JSON устанавливается специальный флаг pending_restart. Кроме того, состояние узла указывает на это, отображая "restart_pending": true.

  • Локальный файл конфигурации (patroni.yml).
    Эти параметры определяются в файле конфигурации и имеют приоритет перед динамической конфигурацией. patroni.yml можно изменить и повторно загрузить во время выполнения (без перезапуска Patroni), отправив SIGHUP процессу Patroni, выполнив запрос POST /reload REST-API или команду patronictl_reload . Локальная конфигурация может представлять собой один файл YAML или каталог. Если указан каталог, все файлы YAML в нём загружаются по одному в отсортированном порядке. Если ключ определён в нескольких файлах, приоритет имеет его значение в последнем файле.

  • Конфигурация среды .
    Возможна установка/переопределение некоторых параметров конфигурации «Локальная» с помощью переменных среды. Конфигурация среды особенно полезна при работе в динамической среде, когда некоторые параметры заранее неизвестны (например, невозможно определить внешний IP-адрес при запуске внутри docker).


Важные правила

Параметры PostgreSQL, контролируемые Patroni

Некоторые параметры PostgreSQL должны иметь одинаковые значения на первичном сервере и репликах. Для этих параметров значения, установленные либо в локальных файлах конфигурации Patroni, либо через переменные среды, не влияют. Чтобы изменить или установить их значения, необходимо изменить общую конфигурацию в DCS. Ниже приведён список таких параметров вместе с их значениями по умолчанию и минимальными значениями:

  • max_connections: значение по умолчанию 100, минимальное значение 25
  • max_locks_per_transaction: значение по умолчанию 64, минимальное значение 32
  • max_worker_processes: значение по умолчанию 8, минимальное значение 2
  • max_prepared_transactions: значение по умолчанию 0, минимальное значение 0
  • wal_level: значение по умолчанию hot_standby, допустимые значения: hot_standby, реплика, логическая
  • track_commit_timestamp: значение по умолчанию off

Для параметров, указанных ниже, PostgreSQL не требует одинаковых значений между первичным сервером и всеми репликами. Однако с учётом возможности превращения реплики в первичный сервер в любой момент, установка различных значений не имеет смысла; следовательно, Patroni ограничивает установку их значений в динамическую конфигурацию .

  • max_wal_senders: значение по умолчанию 10, минимальное значение 3
  • max_replication_slots: значение по умолчанию 10, минимальное значение 4
  • wal_keep_segments: значение по умолчанию 8, минимальное значение 1
  • wal_keep_size: значение по умолчанию 128MB, минимальное значение 16MB
  • wal_log_hints: включено

Эти параметры проверяются на корректность или соответствие минимальному значению.

Существуют и другие параметры Postgres, контролируемые Patroni:

  • listen_addresses — устанавливается либо из переменной среды postgresql.listen, либо из переменной среды PATRONI_POSTGRESQL_LISTEN
  • port — устанавливается либо из переменной среды postgresql.listen, либо из переменной среды PATRONI_POSTGRESQL_LISTEN
  • cluster_name — устанавливается либо из переменной среды scope, либо из переменной среды PATRONI_SCOPE
  • hot_standby: on

Для обеспечения безопасности параметры из приведённых выше списков записываются в postgresql.conf и передаются в виде списка аргументов в postgres, что придаёт им наибольший приоритет (за исключением wal_keep_segments и wal_keep_size), даже выше, чем у ALTER SYSTEM

Существуют также некоторые параметры, такие как postgresql.listen, postgresql.data_dir, которые можно задать только локально, i.e. в файле конфигурации Patroni config или с помощью переменной окружения configuration . В большинстве случаев локальная конфигурация переопределяет динамическую конфигурацию.

При применении параметров локальной или динамической конфигурации выполняются следующие действия:

  • Узел сначала проверяет наличие файла postgresql.base.conf или установку параметра custom_conf.
  • Если параметр custom_conf установлен, файл, который он указывает, используется в качестве базовой конфигурации, при этом игнорируются postgresql.base.conf и postgresql.conf.
  • Если параметр custom_conf не установлен и существует postgresql.base.conf, то он содержит переименованную «исходную» конфигурацию и используется в качестве базовой конфигурации.
  • Если отсутствуют как custom_conf, так и postgresql.base.conf, исходная postgresql.conf переименовывается в postgresql.base.conf и используется в качестве базовой конфигурации.
  • Динамические параметры (за исключением перечисленных выше) записываются в postgresql.conf, а в postgresql.conf устанавливается включение базовой конфигурации (либо postgresql.base.conf, либо файл по пути custom_conf). Таким образом, можно применять новые параметры без повторного чтения файла конфигурации для проверки наличия включения.
  • Некоторые параметры, необходимые для управления кластером Patroni, переопределяются с помощью командной строки.
  • Если изменён параметр, требующий перезапуска (необходимо учитывать контекст в pg_settings и фактические значения этих параметров), на этом узле устанавливается флаг pending_restart. Этот флаг сбрасывается при любом перезапуске.

Параметры будут применены в следующем порядке (параметры времени выполнения имеют наивысший приоритет):

  1. загрузить параметры из файла postgresql.base.conf (или из файла custom_conf, если задано)
  2. загрузить параметры из файла postgresql.conf
  3. загрузить параметры из файла postgresql.auto.conf
  4. параметр времени выполнения с использованием -o --name=value

Это позволяет задавать конфигурацию для всех узлов (2), конфигурацию конкретного узла с использованием ALTER SYSTEM (3) и обеспечивает принудительное применение параметров, критически важных для работы Patroni (4), а также оставляет место для инструментов конфигурации, управляющих postgresql.conf напрямую без участия Patroni (1).

Параметры PostgreSQL, влияющие на общую память

PostgreSQL имеет некоторые параметры, определяющие размер общей памяти, используемой ими:

  • max_connections
  • max_prepared_transactions
  • max_locks_per_transaction
  • max_wal_senders
  • max_worker_processes

Изменение этих параметров требует перезапуска PostgreSQL для применения, и их структуры общей памяти не могут быть меньше на резервных серверах, чем на первичном сервере.

Как уже объяснялось ранее, Patroni ограничивает изменение их значений через динамическую конфигурацию , которая обычно состоит из:

  1. Применение изменений через patronictl_edit_config (или через конечную точку REST API /config)
  2. Перезапуск узлов через patronictl_restart (или через конечную точку REST API /restart)

Примечание: имейте в виду, что перезапуск узлов PostgreSQL следует выполнять с помощью команды patronictl_restart или через конечную точку REST API /restart. Попытка перезапуска PostgreSQL путём перезапуска демона Patroni, e.g. путём выполнения команды systemctl restart patroni, может привести к переключению при отказе в кластере, если перезапускается первичный сервер.

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

  • Если вы хотите увеличить значение одного из этих параметров:
  1. Сначала перезапустите все резервные серверы
  2. Затем перезапустите первичный сервер
  • Если вы хотите уменьшить значение одного из этих параметров:
  1. Перезапустите первичный сервер сначала
  2. Затем перезапустите все резервные серверы

Примечание: если вы попытаетесь перезапустить все узлы одновременно после уменьшения значения любого из этих параметров, Patroni проигнорирует изменение и перезапустит резервный сервер с исходным значением параметра, что потребует последующего повторного перезапуска резервных серверов. Patroni поступает так, чтобы предотвратить попадание резервного сервера в бесконечный цикл сбоев, поскольку PostgreSQL завершается с сообщением FATAL, если попытаться установить любой из этих параметров на значение ниже, чем то, что отображается в pg_controldata на узле резервного сервера. Иными словами, мы можем уменьшить значение параметра на резервном сервере только после того, как его pg_controldata будет синхронизировано с первичным сервером относительно этих изменений на первичном сервере.

Дополнительную информацию об этом можно найти в Обзоре администратора PostgreSQL .

Patroni параметры конфигурации

Также следующие параметры конфигурации Patroni могут быть изменены только динамически:

  • ttl: 30
  • loop_wait: 10
  • retry_timeout: 10
  • maximum_lag_on_failover: 1048576
  • max_timelines_history: 0
  • check_timeline: false
  • postgresql.use_slots: true

При изменении этих параметров Patroni прочитает соответствующий раздел конфигурации, хранящийся в DCS, и изменит их значения в режиме выполнения.

Узлы Patroni сохраняют состояние параметров DCS на диск при каждом изменении конфигурации в файл patroni.dynamic.json, расположенном в каталоге данных PostgreSQL. Восстановление этих параметров из дампа на диске разрешено только лидеру, если они полностью отсутствуют в DCS или являются недопустимыми.


Генерация и проверка конфигурации

Patroni предоставляет интерфейсы командной строки для генерации и проверки локальной конфигурации Patroni local configuration . С помощью исполняемого файла patroni вы можете:

  • Создайте образец локальной конфигурации Patroni;
  • Создайте файл конфигурации Patroni для локально запущенного экземпляра PostgreSQL (e.g в качестве подготовительного шага к интеграции с Patroni );
  • Проверьте заданный файл конфигурации Patroni.

Пример конфигурации Patroni

patroni --generate-sample-config [configfile]

Описание

Создайте образец файла конфигурации Patroni в формате yaml. Значения параметров задаются с помощью конфигурации Environment , в противном случае, если не заданы, используются значения по умолчанию в Patroni или #FIXME строка для значений, которые должны быть определены позже пользователем.

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

  • postgresql.listen: IP-адрес, возвращаемый вызовом gethostname для хостнейма текущей машины и стандартного порта 5432.
  • postgresql.connect_address: IP-адрес, возвращаемый вызовом gethostname для хостнейма текущей машины и стандартного порта 5432.
  • postgresql.authentication.rewind: определяется только если версия PostgreSQL может быть определена из бинарного файла и версия составляет 11 или новее.
  • restapi.listen: IP-адрес, возвращаемый вызовом gethostname для хостнейма текущей машины и стандартного порта 8008.
  • restapi.connect_address: IP-адрес, возвращаемый вызовом gethostname для хостнейма текущей машины и стандартного порта 8008.

Параметры

configfile — полный путь к файлу конфигурации, используемому для хранения результата. Если не указан, результат отправляется в stdout.

Patroni конфигурация для работающего экземпляра

patroni --generate-config [--dsn DSN] [configfile]

Описание

Создайте конфигурацию Patroni в формате yaml для локально запущенного экземпляра PostgreSQL. Для соединения с PostgreSQL будет использоваться либо указанный DSN (он имеет приоритет), либо переменные окружения PostgreSQL. Если пароль не указан, его следует ввести по запросу.

Все не внутренние параметры GUC, определённые в исходном экземпляре PostgreSQL, независимо от того, были ли они установлены через файл конфигурации, через командную строку postmaster или через переменные среды, будут использованы в качестве источника для следующих параметров конфигурации Patroni:

  • scope: cluster_name GUC значение;
  • postgresql.listen: listen_addresses и port GUC значения;
  • postgresql.datadir: data_directory GUC значение;
  • postgresql.parameters: archive_command, restore_command, archive_cleanup_command, recovery_end_command, ssl_passphrase_command, hba_file, ident_file, config_file GUC значения;
  • bootstrap.dcs: все остальные собранные параметры GUC PostgreSQL.

Если параметр scope, postgresql.listen или postgresql.datadir не задан через GUC PostgreSQL, используется соответствующее значение конфигурации Environment .

Другие правила, применяемые для определения значений:

  • name: значение переменной среды PATRONI_NAME, если установлена, иначе имя хоста текущей машины.
  • postgresql.bin_dir: путь к бинарным файлам PostgreSQL, извлечённый из работающего экземпляра.
  • postgresql.connect_address: IP-адрес, возвращённый вызовом gethostname для имени хоста текущей машины, и порт, используемый для соединения с экземпляром, или значение port GUC.
  • postgresql.authentication.superuser: конфигурация, используемая для соединения с экземпляром;
  • postgresql.pg_hba: строки, извлечённые из hba_file исходного экземпляра.
  • postgresql.pg_ident: строки, извлечённые из ident_file исходного экземпляра.
  • restapi.listen: IP-адрес, возвращённый вызовом gethostname для имени хоста текущей машины, и стандартный порт 8008.
  • restapi.connect_address: IP-адрес, возвращённый вызовом gethostname для имени хоста текущей машины, и стандартный порт 8008.

Другие параметры, определённые с помощью Конфигурация среды , также включаются в конфигурацию.

Параметры

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

dsn
Необязательная строка DSN для локального экземпляра PostgreSQL, из которого будут получены значения GUC.

Проверка конфигурации Patroni

patroni --validate-config [configfile] [--ignore-listen-port | -i]

Описание

Проверьте указанную конфигурацию Patroni и выведите сведения о неудавшихся проверках.

Параметры

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

--ignore-listen-port | -i
Необязательный флаг для игнорирования ошибок привязки к портам listen, которые уже заняты при проверке configfile.

--print | -p
Необязательный флаг для вывода локальной конфигурации (включая переопределения конфигурации из переменных среды) после её успешной валидации.

3.1 - YAML Параметры конфигурации

Полная справка по параметрам и разделам конфигурации Patroni YAML.


Глобальный/Всемирный

  • thread_pool_size: размер пула потоков, используемый Patroni для выполнения асинхронных задач и обмена данными по REST API с другими участниками во время выбора лидера или проверок в аварийном режиме. Минимальное значение — 5, значение по умолчанию — 5.
  • thread_stack_size: указывает размер стека, используемый для потоков, запускаемых Patroni. Значение должно быть выровнено по 64kB. Минимальное значение — 64kB, значение по умолчанию (устанавливается Patroni) — 512kB.
  • name: имя хоста. Должно быть уникальным для кластера. Значение __patroni_strict_sync_replica_placeholder__ зарезервировано для внутреннего использования Patroni и не может использоваться в качестве имени узла.
  • namespace: путь внутри хранилища конфигурации, где Patroni будет хранить информацию о кластере. Значение по умолчанию: “/service”
  • scope: имя кластера


Журнал

  • type: задаёт формат логов. Может быть либо plain, либо json. Для использования формата json необходимо установить jsonlogger . Значение по умолчанию — plain.
  • level: устанавливает общий уровень ведения журнала. Значение по умолчанию — INFO (см. документацию по ведению журнала в Python )
  • traceback_level: задаёт уровень, на котором будут видны трассировки. Значение по умолчанию — ERROR. Установите значение DEBUG, если хотите видеть трассировки только при включённом log.level=DEBUG.
  • format: задаёт строку форматирования журнала. Если тип журнала — plain, формат журнала должен быть строкой. См. атрибуты LogRecord для получения списка доступных атрибутов. Если тип журнала — json, формат журнала может быть списком в дополнение к строке. Каждый элемент списка должен соответствовать атрибуту LogRecord. Будьте осторожны: требуется только имя поля, а обрамляющие символы %( и ) опускаются. Если необходимо вывести поле журнала с другим именем ключа, используйте словарь, где ключ словаря — это поле журнала, а значение — имя поля, которое должно быть выведено в журнале. Значение по умолчанию: %(asctime)s %(levelname)s: %(message)s
  • dateformat: устанавливает строку форматирования даты и времени. (см. документацию formatTime() )
  • static_fields: добавить дополнительные поля в лог. Этот параметр доступен только при установке типа лога в json.
  • max_queue_size: Patroni использует двухэтапное ведение журнала. Записи журнала записываются в очереди в оперативной памяти, а отдельный поток извлекает их из очереди и записывает в stderr или файл. Максимальный размер внутренней очереди по умолчанию ограничен 1000 записями, что достаточно для хранения журналов за последние 1 час 20 минут.
  • dir: Каталог для записи журналов приложения. Каталог должен существовать и быть доступен для записи пользователем, запускающим Patroni. Если задать это значение, приложение по умолчанию будет сохранять журналы 4 25MB. Значения хранения можно настроить с помощью file_num и file_size (см. ниже).
  • mode: Права доступа к файлам журнала (например, 0644). Если не указано, права будут установлены на основе текущего значения umask.
  • file_num: Количество журналов приложений, которые необходимо сохранить.
  • file_size: Размер файла patroni.log (в байтах), при достижении которого происходит смена лог-файла.
  • loggers: Этот раздел позволяет переопределять уровень ведения журнала для каждого модуля Python
    • patroni.postmaster: WARNING
    • urllib3: DEBUG
  • deduplicate_heartbeat_logs: При значении true последовательные логи heartbeat, одинаковые по содержанию, не выводятся. Значение по умолчанию — false.
Предупреждение

Время выполнения цикла высокой доступности может быть очень полезной информацией при диагностике переключений при отказе из-за нехватки ресурсов и подобных проблем. Когда deduplicate_heartbeat_logs установлен в true, журналы не будут содержать записи о выполнении цикла высокой доступности (если только не произойдёт смена лидера), и, таким образом, эта потенциально полезная информация станет недоступной в журналах.

Вот пример настройки Patroni для вывода логов в формате JSON.

log:
   type: json
   format:
      - message
      - module
      - asctime: '@timestamp'
      - levelname: level
   static_fields:
      app: patroni


Конфигурация начальной инициализации

Примечание

После того как Patroni впервые прошла начальную инициализацию кластера и настройки были сохранены в DCS, все последующие изменения в разделе bootstrap.dcs конфигурации YAML не будут иметь никакого эффекта! Чтобы изменить их, используйте либо patronictl_edit_config , либо REST API Patroni REST API .

  • начальная инициализация:
    • dcs: Этот раздел будет записан в /<namespace>/<scope>/config хранилища конфигурации после начальной инициализации нового кластера. Глобальная динамическая конфигурация кластера. Вы можете разместить любые из параметров, описанных в разделе Динамическая конфигурация , под ключом bootstrap.dcs, и после того, как Patroni завершит инициализацию (bootstrap) нового кластера, он запишет этот раздел в /<namespace>/<scope>/config хранилища конфигурации.

    • method: пользовательский скрипт для использования при первоначальной настройке этого кластера.

      См. документацию по пользовательским методам начальной инициализации для получения подробной информации. При указании initdb возвращается к команде по умолчанию initdb. initdb также запускается, если в файле конфигурации отсутствует параметр method.

    • initdb: (необязательно) список параметров, передаваемых команде initdb.

      • - data-checksums: Должен быть включён при необходимости pg_rewind на 9.3.
      • - encoding: UTF8: кодировка по умолчанию для новых баз данных.
      • - locale: UTF8: язык по умолчанию для новых баз данных.
    • post_bootstrap или post_init: Дополнительный скрипт, который будет выполнен после начальной инициализации кластера. Скрипт получает строку соединения URL (с именем суперпользователя кластера в качестве имени пользователя). Переменная PGPASSFILE устанавливается в расположение файла pgpass.


Citus

Включает интеграцию Patroni с Citus . При настройке Patroni будет отвечать за регистрацию узлов-работников Citus на координаторе. Дополнительную информацию о поддержке Citus можно найти здесь .

  • group: идентификатор группы Citus, целое число. Используйте 0 для координатора и 1, 2 и т.д. для воркеров
  • database: база данных, в которой должен быть создан расширение citus . Должна быть одинаковой на координаторе и всех воркерах. В настоящее время поддерживается только одна база данных.


Consul

Большинство параметров необязательны, но необходимо указать один из параметров host или url

  • host: хост:порт для локального агента Consul.
  • url: URL для локального агента Consul в формате: http(s)://host:port.
  • port: (необязательно) порт Consul.
  • scheme: (необязательно) http или https, по умолчанию — http.
  • token: (необязательно) токен ACL.
  • verify: (необязательно) проверять ли сертификат SSL для запросов HTTPS.
  • cacert: (необязательно) Сертификат CA. При наличии включает проверку подлинности.
  • cert: (необязательно) файл с сертификатом клиента.
  • key: (необязательно) файл с ключом клиента. Может быть пустым, если ключ содержится в cert.
  • dc: (необязательно) Дата-центр для связи. По умолчанию используется дата-центр хоста.
  • consistency: (необязательно) Выберите режим согласованности Consul. Допустимые значения: default, consistent или stale (подробнее в справочнике Consul API )
  • checks: (необязательно) список проверок состояния Consul, используемых для сессии. По умолчанию используется пустой список.
  • register_service: (необязательно) указывает, следует ли регистрировать службу с именем, определённым параметром scope, и тегом master, primary, replica или standby-leader в зависимости от роли узла. По умолчанию — false.
  • service_tags: (необязательно) дополнительные статические теги, добавляемые к сервису Consul помимо роли (primary/replica/standby-leader). По умолчанию используется пустой список.
  • service_check_interval: (необязательно) как часто выполнять проверку работоспособности для зарегистрированного URL. Значение по умолчанию — ‘5s’.
  • service_check_tls_server_name: (необязательно) переопределить хост SNI при подключении через TLS, см. также ссылку на проверку агента Consul API .

Для token необходимо наличие следующих разрешений ACL:

service_prefix "${scope}" {
    policy = "write"
}
key_prefix "${namespace}/${scope}" {
    policy = "write"
}
session_prefix "" {
    policy = "write"
}

Etcd

Большинство параметров необязательны, но необходимо указать один из параметров host, hosts, url, proxy или srv

  • host: хост:порт для конечной точки etcd.
  • hosts: список конечных точек etcd в формате host1:port1,host2:port2,и т.д. Может быть указан в виде строки, разделённой запятыми, или фактического списка YAML.
  • use_proxies: Если этот параметр установлен в значение true, Patroni будет рассматривать hosts как список прокси-серверов и не будет выполнять обнаружение топологии кластера etcd.
  • url: URL для etcd.
  • proxy: URL прокси для etcd. Если вы подключаетесь к etcd через прокси, используйте этот параметр вместо url.
  • srv: Домен для поиска записей SRV при автодиагностике кластера. Patroni будет пытаться запросить эти имена служб SRV для указанного домена (в указанном порядке до первого успешного результата): _etcd-client-ssl, _etcd-client, _etcd-ssl, _etcd, _etcd-server-ssl, _etcd-server. Если будут получены записи SRV для _etcd-server-ssl или _etcd-server, то будет использован протокол peer ETCD для запроса ETCD о доступных участниках. В противном случае будут использованы хосты из записей SRV.
  • srv_suffix: Задаёт суффикс к имени SRV, который запрашивается при обнаружении. Используйте этот флаг для различия между несколькими кластерами etcd в рамках одного домена. Работает только в сочетании с srv. Например, если установлены srv_suffix: foo и srv: example.org, выполняется следующий запрос DNS SRV:_etcd-client-ssl-foo._tcp.example.com (и так далее для каждого возможного имени службы ETCD SRV).
  • protocol: (необязательно) http или https, если не указано — используется http. Если указан url или proxy — протокол берётся из них.
  • username: (необязательно) имя пользователя для аутентификации в etcd.
  • password: (необязательно) пароль для аутентификации в etcd.
  • cacert: (необязательно) Сертификат CA. При наличии включает проверку подлинности.
  • cert: (необязательно) файл с сертификатом клиента.
  • key: (необязательно) файл с ключом клиента. Может быть пустым, если ключ содержится в cert.

Etcdv3

Если вы хотите, чтобы Patroni работал с кластером etcd через версию протокола 3, необходимо использовать раздел etcd3 в файле конфигурации Patroni. Все параметры конфигурации остаются такими же, как и для etcd.

Предупреждение

Ключи, созданные с использованием версии протокола 2, недоступны при использовании версии протокола 3, и наоборот, поэтому невозможно переключиться с etcd на etcd3 просто путём обновления файла конфигурации Patroni. Кроме того, Patroni использует gRPC-gateway (прокси) etcd для взаимодействия с V3 API, что означает, что аутентификация по общему имени TLS невозможна.


ZooKeeper

  • hosts: Список участников кластера ZooKeeper в формате: ′host1:port1′,′host2:port2′,′etc...′'host1:port1', 'host2:port2', 'etc...'.
  • use_ssl: (необязательно) Указывает, используется ли SSL или нет. Значение по умолчанию — false. Если установлено в false, игнорируются все параметры, специфичные для SSL.
  • cacert: (необязательно) Сертификат ЦС. При наличии включает проверку подлинности.
  • cert: (необязательно) Файл с сертификатом клиента.
  • key: (необязательно) Файл с ключом клиента.
  • key_password: (необязательно) Пароль ключа клиента.
  • verify: (необязательно) Указывает, проверять ли сертификат или нет. Значение по умолчанию — true.
  • set_acls: (необязательно) Если задано, настраивает Kazoo на применение по умолчанию ACL к каждому ZNode, который он создаёт. ACL могут использовать схему x509 (по умолчанию) или другие поддерживаемые схемы ZooKeeper, такие как digest. Они должны указываться как словарь, где ключ — полное имя субъекта (опционально с префиксом схемы), а значение — список разрешений. Разрешения могут быть одним или несколькими из CREATE, READ, WRITE, DELETE, ADMIN, или ALL. Например, set_acls: {CN=principal1: [CREATE, READ], digest:principal2:+pjROuBuuwNNSujKyH8dGcEnFPQ=: [ALL]}.
  • auth_data: (необязательно) Учетные данные аутентификации для использования при соединении. Должно быть словарем в формате, где scheme — ключ, а credential — значение. По умолчанию — пустой словарь.
Примечание

Необходимо установить kazoo>=2.6.0 для поддержки SSL.


Выставщик

  • hosts: начальный список узлов Exhibitor (ZooKeeper) в формате: ‘host1,host2,etc…’. Этот список обновляется автоматически при изменении топологии кластера Exhibitor (ZooKeeper).
  • poll_interval: с какой частотой следует обновлять список узлов ZooKeeper и Exhibitor из Exhibitor.
  • port: Порт выставки.


Kubernetes

  • bypass_api_service: (необязательно) При взаимодействии с Kubernetes API Patroni обычно полагается на сервис kubernetes , адрес которого экспортируется в подах через переменную окружения KUBERNETES_SERVICE_HOST. Если установлено значение bypass_api_service, равное true, Patroni будет разрешать список узлов API за этим сервисом и подключаться к ним напрямую.
  • namespace: (необязательно) пространство имён Kubernetes, в котором выполняется под Patroni. Значение по умолчанию — default.
  • labels: Метки в формате {label1: value1, label2: value2}. Эти метки будут использоваться для поиска существующих объектов (Pod’ов и либо Endpoints, либо ConfigMaps), связанных с текущим кластером. Также Patroni установит их на каждый объект (Endpoint или ConfigMap), который создаст.
  • scope_label: (необязательно) имя метки, содержащей имя кластера. Значение по умолчанию — cluster-name.
  • bootstrap_labels: (необязательно) Метки в формате {label1: value1, label2: value2}. Эти метки будут присвоены поду Patroni, когда его состояние будет равно initializing new cluster, running custom bootstrap script, starting after custom bootstrap или creating replica.
  • role_label: (необязательно) имя метки, содержащей роль (primary, replica или другое пользовательское значение). Patroni установит эту метку в поде, в котором выполняется. Значение по умолчанию — role.
  • leader_label_value: (необязательно) значение метки пода при роли Postgres primary. Значение по умолчанию — primary.
  • follower_label_value: (необязательно) значение метки пода при роли Postgres replica. Значение по умолчанию — replica.
  • standby_leader_label_value: (необязательно) значение метки пода при роли Postgres standby_leader. Значение по умолчанию — primary.
  • tmp_role_label: (необязательно) имя временной метки, содержащей роль (primary или replica). Значение этой метки всегда будет использовать значение по умолчанию, соответствующее роли. Устанавливать только при необходимости.
  • use_endpoints: (необязательно) если установлено в true, Patroni будет использовать Endpoints вместо ConfigMaps для проведения выборов лидера и хранения состояния кластера.
  • pod_ip: (необязательно) IP-адрес пода, в котором работает Patroni. Это значение необходимо, когда включён use_endpoints, и используется для заполнения подмножеств конечных точек лидера при повышении пода PostgreSQL до роли лидера.
  • ports: (необязательно) если у объекта Service указано имя порта, то это же имя должно присутствовать в объекте Endpoint, иначе сервис не будет работать. Например, если ваш сервис определён как {Kind: Service, spec: {ports: [{name: postgresql, port: 5432, targetPort: 5432}]}}, необходимо установить kubernetes.ports: [{"name": "postgresql", "port": 5432}], и Patroni будет использовать его для обновления подмножеств лидера Endpoint. Этот параметр используется только в случае, если установлено kubernetes.use_endpoints.
  • cacert: (необязательно) Указывает файл с CA_BUNDLE файлом сертификатов доверенных ЦС, используемых при проверке сертификатов Kubernetes API SSL. Если не указано, Patroni будет использовать значение, предоставленное секретом ServiceAccount.
  • retriable_http_codes: (необязательно) список кодов состояния HTTP от K8s API, при которых следует повторить попытку. По умолчанию Patroni повторяет попытку при кодах 500, 503 и 504, либо если ответ K8s API содержит заголовок retry-after HTTP.


Raft (устаревший)

  • self_addr: ip:port для прослушивания соединений Raft. self_addr должен быть доступен с других узлов кластера. Если не задан, узел не будет участвовать в согласовании.

  • bind_addr: (необязательно) ip:port для прослушивания соединений Raft. Если не указано, будет использован self_addr.

  • partner_addrs: список других узлов Patroni в кластере в формате:

    ′ip1:port′,′ip2:port′,′etc...′'ip1:port', 'ip2:port', 'etc...'
  • data_dir: каталог для хранения журнала Raft и снимков. Если не указан, используется текущий рабочий каталог.

  • password: (необязательно) Шифровать трафик Raft с помощью указанного пароля, требуется модуль cryptography python.

  • min_timeout: (необязательно) минимальный тайм-аут выборов в секундах для лежащей в основе реализации Raft pysyncobj. Должен быть больше 3 * append_entries_period. Значение по умолчанию: 0.4.

  • max_timeout: (необязательно) максимальный тайм-аут голосования в секундах для лежащей в основе реализации Raft pysyncobj. Должен быть больше, чем min_timeout. Значение по умолчанию: 1.4.

  • connection_timeout: (необязательно) время в секундах, по истечении которого соединение без полученных данных считается неработоспособным. Должно быть больше или равно max_timeout. Значение по умолчанию: 3.5.

  • append_entries_period: (необязательно) интервал в секундах для отправки команды heartbeat (append_entries). Должен быть меньше одной трети min_timeout. Значение по умолчанию: 0.1.

  • connection_retry_time: (необязательно) интервал в секундах между попытками повторного подключения к оффлайн-узлам. По умолчанию: 5.0.

  • leader_fallback_timeout: (необязательно) время в секундах, по истечении которого лидер, не получивший ответ от большинства, возвращается в состояние последователя. Должно быть больше, чем append_entries_period. Значение по умолчанию: 30.0.

Примечание

Эти параметры тайм-аута полезны в сетях с высокой задержкой, где значения тайм-аутов по умолчанию для pysyncobj слишком агрессивны. Должны выполняться следующие ограничения: min_timeout > 3 * append_entries_period, max_timeout > min_timeout, connection_timeout >= max_timeout, и leader_fallback_timeout > append_entries_period. Patroni проверяет эти условия при запуске и откажется запускаться при их нарушении. Эти значения нельзя изменить во время работы и требуют перезапуска.

[!WARNING] Эти параметры влияют только на тайм-ауты выбора и соединения в pysyncobj; они не увеличивают предельное время выполнения команд, применяемое Patroni к операциям Raft. Каждая команда Raft (обновление блокировки лидера, запись состояния кластера) должна завершиться в течение retry_timeout (по умолчанию 10). При очень высокой задержке — примерно выше нескольких секунд времени отклика — одна команда может превысить retry_timeout даже при увеличении connection_timeout значительно выше RTT, поэтому DCS может стать недоступным, и первичный сервер может быть понижен. В таких условиях необходимо также увеличить retry_timeout и ttl соответственно, сохраняя loop_wait + 2 * retry_timeout <= ttl.

Кратко о реализации Raft FAQ

  • Вопрос: Как вывести список всех узлов, обеспечивающих согласованность?

    A: syncobj_admin -conn host:port -status, где host:port — это адрес одного из узлов кластера

  • Вопрос: Узел, который участвовал в консенсусе, покинул кластер, и я не могу повторно использовать тот же IP-адрес для другого узла. Как удалить этот узел из консенсуса?

    A: syncobj_admin -conn host:port -remove host2:port2, где host2:port2 — это адрес узла, который необходимо удалить из консенсуса.

  • Q: Откуда получить утилиту syncobj_admin?

    A: Устанавливается вместе с модулем pysyncobj (реализация python RAFT), который является зависимостью Patroni.

  • Q: возможно ли запуск узла Patroni без добавления в консенсус?

    A: Да, просто закомментируйте или удалите raft.self_addr из конфигурации Patroni.

  • В: Можно ли запускать Patroni и PostgreSQL только на двух узлах?

    A: Да, на третьем узле можно запустить patroni_raft_controller (без Patroni и PostgreSQL). При таком подходе можно временно потерять один узел, не затронув первичный сервер.


PostgreSQL

  • postgresql:
    • authentication:

      • superuser:
        • username: имя суперпользователя, задаётся при инициализации (initdb) и позже используется Patroni для подключения к postgres.
        • password: пароль для суперпользователя, устанавливается во время инициализации (initdb).
        • sslmode: (необязательно) соответствует параметру соединения sslmode , позволяющему клиенту указать тип режима согласования TLS с сервером. Дополнительную информацию о работе каждого режима см. в документации PostgreSQL . Режим по умолчанию — prefer.
        • sslkey: (необязательно) соответствует параметру соединения sslkey , который указывает расположение секретного ключа, используемого с сертификатом клиента.
        • sslpassword: (необязательно) соответствует параметру соединения sslpassword , который указывает пароль для секретного ключа, указанного в sslkey.
        • sslcert: (необязательно) соответствует параметру соединения sslcert , который указывает расположение сертификата клиента.
        • sslrootcert: (необязательно) соответствует параметру соединения sslrootcert , который указывает расположение файла, содержащего один или несколько сертификатов центров сертификации (CA), которые клиент будет использовать для проверки сертификата сервера.
        • sslcrl: (необязательно) соответствует параметру соединения sslcrl , который указывает расположение файла, содержащего список отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
        • sslcrldir: (необязательно) соответствует параметру соединения sslcrldir , который указывает расположение каталога, содержащего файлы со списками отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого содержится в этом списке.
        • sslnegotiation: (необязательно) соответствует параметру соединения sslnegotiation , управляющему процессом согласования SSL шифрования с сервером, если используется SSL.
        • gssencmode: (необязательно) соответствует параметру соединения gssencmode , определяющему, будет ли устанавливаться защищённое соединение GSS TCP/IP с сервером, и с какой приоритетностью
        • channel_binding: (необязательно) отображается на параметр соединения channel_binding , управляющий использованием клиентом привязки канала.
      • replication:
        • username: имя пользователя для репликации; пользователь будет создан во время инициализации. Реплики будут использовать этого пользователя для доступа к источнику репликации через потоковую репликацию
        • password: пароль репликации; пользователь будет создан во время инициализации.
        • sslmode: (необязательно) соответствует параметру соединения sslmode , позволяющему клиенту указать тип режима согласования TLS с сервером. Дополнительную информацию о работе каждого режима см. в документации PostgreSQL . Режим по умолчанию — prefer.
        • sslkey: (необязательно) соответствует параметру соединения sslkey , который указывает расположение секретного ключа, используемого с сертификатом клиента.
        • sslpassword: (необязательно) соответствует параметру соединения sslpassword , который указывает пароль для секретного ключа, указанного в sslkey.
        • sslcert: (необязательно) соответствует параметру соединения sslcert , который указывает расположение сертификата клиента.
        • sslrootcert: (необязательно) соответствует параметру соединения sslrootcert , который указывает расположение файла, содержащего один или несколько сертификатов центров сертификации (CA), которые клиент будет использовать для проверки сертификата сервера.
        • sslcrl: (необязательно) соответствует параметру соединения sslcrl , который указывает расположение файла, содержащего список отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
        • sslcrldir: (необязательно) соответствует параметру соединения sslcrldir , который указывает расположение каталога, содержащего файлы со списками отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого содержится в этом списке.
        • sslnegotiation: (необязательно) соответствует параметру соединения sslnegotiation , управляющему процессом согласования SSL шифрования с сервером, если используется SSL.
        • gssencmode: (необязательно) соответствует параметру соединения gssencmode , определяющему, будет ли устанавливаться защищённое соединение GSS TCP/IP с сервером, и с какой приоритетностью
        • channel_binding: (необязательно) отображается на параметр соединения channel_binding , управляющий использованием клиентом привязки канала.
      • rewind:
        • username: (необязательно) имя пользователя для pg_rewind; пользователь будет создан при инициализации postgres 11+ и будут выданы все необходимые разрешения .
        • password: (необязательно) пароль для пользователя для pg_rewind; пользователь будет создан при инициализации.
        • sslmode: (необязательно) соответствует параметру соединения sslmode , позволяющему клиенту указать тип режима согласования TLS с сервером. Дополнительную информацию о работе каждого режима см. в документации PostgreSQL . Режим по умолчанию — prefer.
        • sslkey: (необязательно) соответствует параметру соединения sslkey , который указывает расположение секретного ключа, используемого с сертификатом клиента.
        • sslpassword: (необязательно) соответствует параметру соединения sslpassword , который указывает пароль для секретного ключа, указанного в sslkey.
        • sslcert: (необязательно) соответствует параметру соединения sslcert , который указывает расположение сертификата клиента.
        • sslrootcert: (необязательно) соответствует параметру соединения sslrootcert , который указывает расположение файла, содержащего один или несколько сертификатов центров сертификации (CA), которые клиент будет использовать для проверки сертификата сервера.
        • sslcrl: (необязательно) соответствует параметру соединения sslcrl , который указывает расположение файла, содержащего список отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
        • sslcrldir: (необязательно) соответствует параметру соединения sslcrldir , который указывает расположение каталога, содержащего файлы со списками отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого содержится в этом списке.
        • sslnegotiation: (необязательно) соответствует параметру соединения sslnegotiation , управляющему процессом согласования SSL шифрования с сервером, если используется SSL.
        • gssencmode: (необязательно) соответствует параметру соединения gssencmode , определяющему, будет ли устанавливаться защищённое соединение GSS TCP/IP с сервером, и с какой приоритетностью
        • channel_binding: (необязательно) отображается на параметр соединения channel_binding , управляющий использованием клиентом привязки канала.
    • callbacks: скрипты обратного вызова, выполняемые при выполнении определённых действий. Patroni передаёт действие, роль и имя кластера. (См. scripts/aws.py как пример написания таких скриптов.)

      • on_reload: выполните этот скрипт при срабатывании перезагрузки конфигурации.
      • on_restart: запустите этот скрипт при перезапуске postgres (без изменения роли).
      • on_role_change: запустите этот скрипт при повышении или понижении уровня postgres.
      • on_start: запустите этот скрипт при запуске postgres.
      • on_stop: запустите этот скрипт при остановке postgres.
    • connect_address: IP-адрес + порт, через которые PostgreSQL доступен с других узлов и приложений.

    • proxy_address: IP-адрес + порт, через которые доступен пул соединений (e.g. PgBouncer), работающий рядом с Postgres. Значение записывается в ключ участник в DCS как proxy_url и может быть полезно для обнаружения сервисов.

    • create_replica_methods: упорядоченный список методов создания для преобразования узла Patroni в новую реплику. Метод “basebackup” используется по умолчанию; другие методы предполагают указание скриптов, каждый из которых настраивается как отдельный элемент конфигурации. Дополнительные сведения см. в документации по настраиваемым методам создания реплик .

    • data_dir: Расположение каталога данных PostgreSQL, либо существующего , либо подлежащего инициализации Patroni.

    • config_dir: Расположение каталога конфигурации PostgreSQL, по умолчанию — каталог данных. Должен быть доступен для записи Patroni.

    • bin_dir: (необязательно) Путь к исполняемым файлам PostgreSQL (pg_ctl, initdb, pg_controldata, pg_basebackup, postgres, pg_isready, pg_rewind). Если не указан или пустая строка, для поиска исполняемых файлов будет использоваться переменная среды PATH.

    • bin_name: (необязательно) Позволяет переопределить имена бинарных файлов Postgres, если используется пользовательская сборка Postgres:

      • pg_ctl: (необязательно) Пользовательское имя для бинарного файла pg_ctl.
      • initdb: (необязательно) Собственное имя для бинарного файла initdb.
      • pgcontroldata: (необязательно) Собственное имя для бинарного файла pg_controldata.
      • pg_basebackup: (необязательно) Пользовательское имя для бинарного файла pg_basebackup.
      • postgres: (необязательно) Пользовательское имя для бинарного файла postgres.
      • pg_isready: (необязательно) Пользовательское имя для бинарного файла pg_isready.
      • pg_rewind: (необязательно) Пользовательское имя для бинарного файла pg_rewind.
    • listen: IP-адрес и порт, на которых слушает PostgreSQL; должен быть доступен с других узлов кластера, если используется потоковая репликация. Разрешено несколько адресов, разделённых запятыми, при условии, что компонент порта указывается после последнего адреса через двоеточие, i.e. listen: 127.0.0.1,127.0.0.2:5432. Patroni будет использовать первый адрес из этого списка для установления локальных соединений с узлом PostgreSQL.

    • use_unix_socket: указывает, что Patroni должен предпочитать использование Unix-сокетов для подключения к кластеру. Значение по умолчанию — false. Если задано unix_socket_directories, Patroni будет использовать первое подходящее значение из него для подключения к кластеру и перейдёт на tcp, если ни одно значение не подходит. Если unix_socket_directories не указано в postgresql.parameters, Patroni предположит, что следует использовать значение по умолчанию, и опустит host из параметров соединения.

    • use_unix_socket_repl: указывает, что Patroni должен предпочитать использование Unix-сокетов для соединения с кластером пользователя репликации. Значение по умолчанию — false. Если задано unix_socket_directories, Patroni будет использовать первое подходящее значение из него для подключения к кластеру и перейдёт на tcp, если ни одно значение не подходит. Если unix_socket_directories не указано в postgresql.parameters, Patroni предположит, что следует использовать значение по умолчанию, и опустит host из параметров соединения.

    • pgpass: путь к файлу паролей .pgpass . Patroni создаёт этот файл перед выполнением pg_basebackup, скрипта post_init, а также при некоторых других обстоятельствах. Расположение должно быть доступно для записи Patroni.

    • recovery_conf: дополнительные параметры конфигурации, записываемые в recovery.conf при настройке последователя.

    • custom_conf : путь к необязательному файлу postgresql.conf, который будет использован вместо postgresql.base.conf. Файл должен существовать на всех узлах кластера, быть доступным для чтения PostgreSQL и будет включён из его расположения в реальном postgresql.conf. Обратите внимание, что Patroni не будет отслеживать изменения в этом файле, ни резервировать его. Однако его настройки всё ещё могут быть переопределены средствами конфигурации Patroni — см. динамическая конфигурация для подробностей.

    • parameters: параметры конфигурации (GUC) для Postgres в формате {ssl: "on", ssl_cert_file: "cert_file"}.

    • parameters_primary: (необязательно) переопределения параметров, специфичных для роли, для первичного сервера. Эти значения объединяются с базовыми parameters и переопределяют их.

    • parameters_replica: (необязательно) переопределения параметров, специфичных для роли реплики. Эти значения объединяются с базовыми parameters и переопределяют их.

    • parameters_standby_leader: (необязательно) переопределения параметров, специфичных для роли, для standby_leader. Эти значения объединяются с базовыми parameters и переопределяют их.

    • pg_hba: список строк, которые Patroni будет использовать для генерации pg_hba.conf. Patroni игнорирует этот параметр, если параметр PostgreSQL hba_file установлен в непо умолчанию значение. Вместе с динамической конфигурацией этот параметр упрощает управление pg_hba.conf.

      • - host all all 0.0.0.0/0 md5
      • - host replication replicator 127.0.0.1/32 md5: Такая строка обязательна для репликации.
    • pg_hba_primary: (необязательно) записи pg_hba, специфичные для роли, для первичного сервера. Они полностью заменяют pg_hba (слияние не производится). Если не определены, используется pg_hba.

    • pg_hba_replica: (необязательно) записи pg_hba, специфичные для роли, для реплики. Они полностью заменяют pg_hba (слияние не происходит). Если не определены, используется pg_hba.

    • pg_hba_standby_leader: (необязательно) записи pg_hba, специфичные для роли, для standby_leader. Они полностью заменяют pg_hba (слияние не происходит). Если не определены, используется pg_hba.

    • pg_ident: список строк, которые Patroni будет использовать для генерации pg_ident.conf. Patroni игнорирует этот параметр, если параметр PostgreSQL ident_file установлен в непо умолчанию значение. Вместе с динамической конфигурацией этот параметр упрощает управление pg_ident.conf.

      • - mapname1 systemname1 pguser1
      • - mapname1 systemname2 pguser2
    • pg_ident_primary: (необязательно) записи pg_ident, специфичные для роли, для первичного сервера. Они полностью заменяют pg_ident (слияние не происходит). Если не определены, используется pg_ident.

    • pg_ident_replica: (необязательно) записи pg_ident, специфичные для роли, для реплики. Они полностью заменяют pg_ident (слияние не происходит). Если не определены, используется pg_ident.

    • pg_ident_standby_leader: (необязательно) записи pg_ident, специфичные для роли, для standby_leader. Они полностью заменяют pg_ident (слияние не происходит). Если не определены, используется pg_ident.

    • pg_ctl_timeout: Сколько времени pg_ctl должен ждать при выполнении start, stop или restart. Значение по умолчанию — 60 секунд.

    • use_pg_rewind: попытайтесь использовать pg_rewind на бывшем лидере при его подключении к кластеру в качестве реплики. Либо кластер должен быть инициализирован с использованием data page checksums (опция --data-checksums для initdb) и/или должно быть установлено значение wal_log_hints, равное on, иначе pg_rewind не будет работать.

    • rewind: (необязательно) пользовательские параметры для передачи команде pg_rewind. Может быть указан как список строк и/или словарей с одним ключом-значением. Запрещённые параметры: target-pgdata, source-pgdata, source-server, write-recovery-conf, dry-run, restore-target-wal, config-file, no-ensure-shutdown, version, и help. Пример использования:

      postgresql:
        rewind:
          - debug
          - progress
          - sync-method: fsync
    • remove_data_directory_on_rewind_failure: Если этот параметр включён, Patroni удалит каталог данных PostgreSQL и повторно создаст реплику. В противном случае будет пытаться следовать новому лидеру. Значение по умолчанию — false.

    • remove_data_directory_on_diverged_timelines: Patroni удалит каталог данных PostgreSQL и повторно создаст реплику, если обнаружит расхождение временных шкал и прежний первичный сервер не сможет начать потоковую передачу от нового первичного сервера. Эта опция полезна, когда невозможно использовать pg_rewind. При проверке расхождения временных шкал в PostgreSQL версий 10 и ранее Patroni попытается подключиться с учётными данными репликации к базе данных «postgres». Следовательно, такой доступ должен быть разрешён в файле pg_hba.conf. Значение по умолчанию — false.

    • replica_method: для каждой create_replica_methods, кроме basebackup, следует добавить секцию конфигурации с тем же именем. В минимальном случае она должна содержать параметр “command” с полным путём к исполняемому скрипту. Остальные параметры конфигурации будут переданы скрипту в виде “параметр=значение”.

    • pre_promote: скрипт fencing, выполняемый при переключении при отказе после получения блокировки лидера, но до повышения реплики в статус лидера. Если скрипт завершается с ненулевым кодом, Patroni не повышает реплику в статус лидера и удаляет ключ лидера из DCS.

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


REST API

  • restapi:
    • thread_pool_size: размер пула потоков, используемого Patroni для обработки запросов REST API. Минимальное значение — 5, значение по умолчанию — 5.
    • connect_address: IP-адрес (или имя хоста) и порт для доступа к REST API Patroni REST API . Все участники кластера должны иметь возможность подключиться к этому адресу, поэтому, если настройка Patroni не предназначена для демонстрации в пределах localhost, этот адрес должен быть не “localhost” и не адресом петли (например, “localhost” или “127.0.0.1”). Он может использоваться в качестве конечной точки для проверок работоспособности HTTP (см. ниже параметр “listen” REST API), а также для запросов пользователей (напрямую или через REST API), а также для проверок работоспособности, выполняемых участниками кластера во время выборов лидера (например, для определения, продолжает ли лидер работу, или существует ли узел с WAL позицией, опережающей ту, по которой выполняется запрос; и т.д.). connect_address помещается в ключ участника в DCS, что позволяет преобразовать имя участника в адрес для подключения к его REST API.
    • listen: IP-адрес (или имя хоста) и порт, на которых Patroni будет слушать REST API — для обеспечения проверок работоспособности и обмена сообщениями между узлами кластера, как описано выше, а также для предоставления информации о работоспособности HAProxy (или любому другому балансировщику нагрузки, способному выполнять проверки HTTP «OPTION» или «GET»).
    • authentication: (необязательно)
      • username: имя пользователя для аутентификации по методу Basic-auth для защиты небезопасных конечных точек REST API.
      • password: Пароль для аутентификации Basic для защиты небезопасных конечных точек REST API.
    • certfile: (необязательно): Указывает файл с сертификатом в формате PEM. Если certfile не указан или оставлен пустым, сервер API будет работать без SSL.
    • keyfile: (необязательно): Указывает файл с секретным ключом в формате PEM.
    • keyfile_password: (необязательно): Указывает пароль для расшифровки ключевого файла.
    • cafile: (необязательно): Указывает файл с CA_BUNDLE, содержащий сертификаты доверенных ЦС, используемые при проверке сертификатов клиентов.
    • ciphers: (необязательно): указывает разрешённые наборы шифров (e.g. “ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:!SSLv1:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1”)
    • verify_client: (необязательно): none (по умолчанию), optional или required. При установке none REST API проверка сертификатов клиентов не выполняется. При установке required для всех вызовов REST API требуется сертификат клиента. При установке optional для всех небезопасных конечных точек REST API требуется сертификат клиента. При использовании required аутентификация клиента считается успешной, если проверка подписи сертификата прошла успешно. Для optional сертификат клиента проверяется только для запросов PUT, POST, PATCH и DELETE.
    • allowlist: (необязательно): Задаёт набор хостов, которым разрешено вызывать небезопасные конечные точки REST API. Единственный элемент может быть именем хоста, IP-адресом или сетевым адресом в формате CIDR. По умолчанию используется allow all. Если установлены allowlist или allowlist_include_members, то всё, что не включено, отклоняется.
    • allowlist_include_members: (необязательно): если установлено в true, позволяет получать доступ к небезопасным конечным точкам REST API с других участников кластера, зарегистрированных в DCS (IP-адрес или имя хоста берётся из участников api_url). Будьте осторожны — возможно, что ОС будет использовать другой IP-адрес для исходящих соединений.
    • http_extra_headers: (необязательно): заголовки HTTP позволяют серверу REST API передавать дополнительную информацию в ответе HTTP.
    • https_extra_headers: (необязательно): заголовки HTTPS позволяют серверу REST API передавать дополнительную информацию в ответе HTTP при включённом TLS. Это также передаст дополнительную информацию, заданную в http_extra_headers.
    • request_queue_size: (необязательно): устанавливает размер очереди запросов для сокета TCP, используемого Patroni REST API. Как только очередь заполнена, последующие запросы получают ошибку «Соединение отклонено». Значение по умолчанию — 5.
    • server_tokens: (необязательно): настраивает значение заголовка Server HTTP.
      • Minimal: В заголовке будет содержаться только версия Patroni, e.g. Patroni/4.0.0.
      • ProductOnly: Заголовок будет содержать только имя продукта, e.g. Patroni.
      • Original (по умолчанию): заголовок покажет исходное поведение и отобразит версии BaseHTTP и Python, e.g. BaseHTTP/0.6 Python/3.12.3.

Вот пример как http_extra_headers, так и https_extra_headers:

restapi:
  listen: <listen>
  connect_address: <connect_address>
  authentication:
    username: <username>
    password: <password>
  http_extra_headers:
    'X-Frame-Options': 'SAMEORIGIN'
    'X-XSS-Protection': '1; mode=block'
    'X-Content-Type-Options': 'nosniff'
  cafile: <ca file>
  certfile: <cert>
  keyfile: <key>
  https_extra_headers:
    'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'

Предупреждение

  • restapi.connect_address должен быть доступен со всех узлов заданного кластера Patroni. Внутри Patroni он используется во время выбора лидера для определения узлов с минимальной задержкой репликации.
  • Если включена проверка сертификатов клиентов (значение restapi.verify_client установлено в required), также обязательно предоставить действительные сертификаты клиентов в ctl.certfile, ctl.keyfile, ctl.keyfile_password. Если они не предоставлены, Patroni будет работать некорректно.


CTL

  • ctl: (необязательно)
    • authentication:
      • username: имя пользователя для аутентификации по методу Basic-auth при доступе к защищённым конечным точкам REST API. Если не указано, patronictl будет использовать значение, указанное для параметра “username” REST API.
      • password: Пароль для аутентификации Basic-auth при доступе к защищённым конечным точкам REST API. Если не указан, patronictl будет использовать значение, указанное для параметра “password” REST API.
    • insecure: Разрешить соединения с REST API без проверки сертификатов SSL.
    • cacert: Указывает файл с CA_BUNDLE файлом или каталогом сертификатов доверенных ЦС, используемых при проверке REST API SSL сертификатов. Если не указано, patronictl будет использовать значение, заданное для параметра REST API “cafile”.
    • certfile: Указывает файл с клиентским сертификатом в формате PEM.
    • keyfile: Указывает файл с секретным ключом клиента в формате PEM.
    • keyfile_password: Указывает пароль для расшифровки ключевого файла клиента.

Сторожевой таймер

  • mode: off, automatic или required. При off сторожевой таймер отключён. При automatic сторожевой таймер будет использоваться, если доступен, но игнорируется, если недоступен. При required узел не станет лидером, если не удастся успешно включить сторожевой таймер.
  • device: Путь к устройству сторожевого таймера. По умолчанию /dev/watchdog.
  • safety_margin: Количество секунд резерва безопасности между срабатыванием сторожевого таймера и истечением срока ключа лидера.


Теги

  • clonefrom: true или false. Если установлено значение true, другие узлы могут предпочесть использовать этот узел для начальной инициализации (взять pg_basebackup из). Если несколько узлов имеют тег clonefrom, установленный в true, узел для начальной инициализации будет выбран случайным образом. Значение по умолчанию — false.
  • noloadbalance: true или false. Если установлено true, узел вернёт код состояния HTTP 503 при проверке работоспособности GET /replica REST API и потому будет исключён из балансировки нагрузки. По умолчанию — false.
  • replicatefrom: Имя другой реплики, от которой производится репликация. Используется для поддержки каскадной репликации.
  • nosync: true или false. Если установлено значение true, узел никогда не будет выбран в качестве синхронной реплики.
  • sync_priority: целое число, определяет приоритет данного узла при выборе синхронной реплики, когда synchronous_mode установлено в on. Узлы с более высоким приоритетом предпочтительнее, чем узлы с более низким приоритетом. Если sync_priority равен 0 или отрицательно — такой узел не может быть записан в параметр PostgreSQL synchronous_standby_names (аналогично nosync: true). Имейте в виду, что это параметр имеет противоположное значение по сравнению со значением sync_priority, отображаемым в представлении pg_stat_replication.
  • nofailover: true или false, управляет тем, может ли данный узел участвовать в выборе лидера и стать лидером. Значение по умолчанию — false, что означает, что данный узел может участвовать в выборе лидера.
  • failover_priority: целое число, определяет приоритет данного узла при переключении при отказе. Узлы с более высоким приоритетом предпочтительнее, чем узлы с более низким приоритетом, если они получили/воспроизвели одинаковое количество WAL. Однако узлы с более высокими значениями receive/replay LSN предпочтительнее независимо от их приоритета. Если failover_priority равен 0 или отрицательно — такой узел не может участвовать в выборе лидера и не может стать лидером (аналогично nofailover: true). Известен ограничение: failover_priority в настоящее время не работает с кворумной синхронной репликацией .
  • nostream: true или false. Если установлено значение true, узел не будет использовать протокол репликации для потоковой передачи WAL. Вместо этого он будет полагаться на восстановление из архива (если настроено restore_command) и опрос pg_wal/pg_xlog. Также отключается копирование и синхронизация постоянных слотов репликации на самом узле и всех его каскадных реплик. Установка этого тега на первичном сервере не оказывает эффекта.
Предупреждение

Укажите только один из nofailover или failover_priority. Указание nofailover: true эквивалентно указанию failover_priority: 0, а указание nofailover: false присваивает узлу приоритет 1.

Помимо этих заранее определённых тегов, вы также можете добавлять свои:

  • key1: true
  • key2: false
  • key3: 1.4
  • key4: "RandomString"

Метки видны в REST API и patronictl_list . Также можно проверить состояние экземпляра с помощью этих меток. Если метка не определена для экземпляра или значение не соответствует запрашиваемому, будет возвращён код состояния HTTP 503.

3.2 - Настройки динамической конфигурации

Настройки динамической конфигурации, хранящиеся в DCS, применяются ко всему кластеру.

Динамическая конфигурация хранится в DCS (распределённое хранилище конфигурации) и применяется ко всем узлам кластера.

Чтобы изменить динамическую конфигурацию, можно использовать либо инструмент patronictl_edit_config , либо Patroni REST API .

  • loop_wait: количество секунд, в течение которых цикл будет спать. Значение по умолчанию: 10, минимально возможное значение: 1
  • ttl: TTL для получения блокировки лидера (в секундах). Представьте это как продолжительность времени до начала процесса автоматического переключения при отказе. Значение по умолчанию: 30, минимально возможное значение: 20
  • retry_timeout: тайм-аут повторных попыток операций DCS и PostgreSQL (в секундах). DCS или сетевые проблемы, короче этого времени, не приведут к демотированию лидера. Значение по умолчанию: 10, минимально возможное значение: 3
Предупреждение

при изменении значений loop_wait, retry_timeout или ttl необходимо соблюдать следующее правило:

loop_wait + 2 * retry_timeout <= ttl
  • maximum_lag_on_failover: максимальное количество байт, на которое последовательный узел может отставать, чтобы участвовать в выборах лидера.
  • primary_race_backoff: откладывает выбор лидера на резервных серверах на primary_race_backoff секунд, если репликация WAL с первичного сервера всё ещё продвигается. Это позволяет свести к минимуму ненужные переключения при отказе, вызванные кратковременной недоступностью Patroni. Значение по умолчанию: 0 (отключено).
  • maximum_lag_on_syncnode: максимальное количество байт, на которое синхронная реплика может отставать, прежде чем она будет считаться нездоровым кандидатом на замену здоровой асинхронной репликой. Patroni использует максимальный LSN реплики, если имеется более одной реплики, в противном случае используется текущий LSN лидера WAL. Значение по умолчанию — -1; при установке значения 0 или ниже Patroni не будет предпринимать действия по замене синхронной нездоровой реплики. Установите значение достаточно высоким, чтобы Patroni не заменял синхронную реплику слишком часто при высокой нагрузке на транзакции.
  • max_timelines_history: максимальное количество элементов истории временной шкалы, сохраняемых в DCS. Значение по умолчанию: 0. При установке в 0 история сохраняется полностью в DCS.
  • primary_start_timeout: количество времени, в течение которого первичный сервер может восстановиться после сбоев, прежде чем будет запущено переключение при отказе (в секундах). Значение по умолчанию — 300 секунд. При установке значения 0 переключение при отказе выполняется немедленно после обнаружения сбоя, если это возможно. При асинхронной репликации переключение при отказе может привести к потере транзакций. Максимальное время переключения при отказе первичного сервера: loop_wait + primary_start_timeout + loop_wait, если primary_start_timeout не равно нулю; в противном случае — loop_wait. Установите значение с учётом баланса между надёжностью и доступностью.
  • primary_stop_timeout: Количество секунд, в течение которых Patroni может ждать остановку Postgres, действует только при включённом synchronous_mode. При значении > 0 и включённом synchronous_mode Patroni отправляет SIGKILL постмейстеру, если операция остановки выполняется дольше значения, установленного в primary_stop_timeout. Установите значение с учётом компромисса между надёжностью и доступностью. Если параметр не задан или установлен <= 0, primary_stop_timeout не применяется.
  • synchronous_mode: включает режим синхронной репликации. Допустимые значения: off, on, quorum. В этом режиме лидер отвечает за управление synchronous_standby_names, и в выборе лидера могут участвовать только последний известный лидер или одна из синхронных реплик. Режим синхронной репликации гарантирует, что успешно завершённые транзакции не будут потеряны при переключении при отказе, ценой потери доступности для записи, когда Patroni не может обеспечить неотказоустойчивость транзакций. Подробности см. в документации по режимам репликации .
  • synchronous_mode_strict: запрещает отключение синхронной репликации при отсутствии синхронных реплик, блокируя все операции записи клиента на первичном сервере. При установке этого параметра и отсутствии доступной реплики, которая ведёт потоковую передачу, Patroni сохраняет synchronous_standby_names, указывающий на последний известный синхронный узел из ключа /sync DCS, либо использует внутренний заполнитель __patroni_strict_sync_replica_placeholder__, если до этого не существовало состояния синхронизации. Узел name в patroni.yaml не должен быть установлен в __patroni_strict_sync_replica_placeholder__. Подробности см. в документации по режимам репликации .
  • synchronous_node_count: если включена опция synchronous_mode , этот параметр используется Patroni для управления точным количеством синхронных реплик и корректировки состояния в DCS и параметра synchronous_standby_names в PostgreSQL при подключении и отключении участников. Если значение параметра превышает количество допустимых узлов, оно будет автоматически скорректировано. Значение по умолчанию — 1.
  • failsafe_mode: включает отказоустойчивый режим DCS . По умолчанию — false.
  • postgresql:
    • use_pg_rewind: использовать ли pg_rewind. Значение по умолчанию — false. Обратите внимание, что кластер должен быть инициализирован с использованием data page checksums (опция --data-checksums для initdb) и/или должно быть установлено значение wal_log_hints, равное on, иначе pg_rewind не будет работать.
    • use_slots: использовать ли слоты репликации. По умолчанию true при PostgreSQL 9.4+.
    • recovery_conf: дополнительные параметры конфигурации, записываемые в recovery.conf при настройке последователя. В PostgreSQL 12 больше нет recovery.conf, однако вы можете продолжать использовать этот раздел, поскольку Patroni обрабатывает его прозрачно.
    • parameters: параметры конфигурации (GUC) для Postgres в формате {max_connections: 100, wal_level: "replica", max_wal_senders: 10, wal_log_hints: "on"}. Многие из них необходимы для работы репликации.
    • parameters_primary: (необязательно) переопределения параметров, специфичных для роли, для первичного сервера. Эти значения объединяются с базовыми parameters и переопределяют их.
    • parameters_replica: (необязательно) переопределения параметров, специфичных для роли реплики. Эти значения объединяются с базовыми parameters и переопределяют их.
    • parameters_standby_leader: (необязательно) переопределения параметров, специфичных для роли, для standby_leader. Эти значения объединяются с базовыми parameters и переопределяют их.
    • pg_hba: список строк, которые Patroni будет использовать для генерации pg_hba.conf. Patroni игнорирует этот параметр, если параметр PostgreSQL hba_file установлен в непо умолчанию значение.
      • - host all all 0.0.0.0/0 md5
      • - host replication replicator 127.0.0.1/32 md5: Такая строка обязательна для репликации.
    • pg_hba_primary: (необязательно) записи pg_hba, специфичные для роли, для первичного сервера. Они полностью заменяют pg_hba (слияние не производится). Если не определены, используется pg_hba.
    • pg_hba_replica: (необязательно) записи pg_hba, специфичные для роли, для реплики. Они полностью заменяют pg_hba (слияние не происходит). Если не определены, используется pg_hba.
    • pg_hba_standby_leader: (необязательно) записи pg_hba, специфичные для роли, для standby_leader. Они полностью заменяют pg_hba (слияние не происходит). Если не определены, используется pg_hba.
    • pg_ident: список строк, которые Patroni будет использовать для генерации pg_ident.conf. Patroni игнорирует этот параметр, если параметр PostgreSQL ident_file установлен в непо умолчанию значение.
      • - mapname1 systemname1 pguser1
      • - mapname1 systemname2 pguser2
    • pg_ident_primary: (необязательно) записи pg_ident, специфичные для роли, для первичного сервера. Они полностью заменяют pg_ident (слияние не происходит). Если не определены, используется pg_ident.
    • pg_ident_replica: (необязательно) записи pg_ident, специфичные для роли, для реплики. Они полностью заменяют pg_ident (слияние не происходит). Если не определены, используется pg_ident.
    • pg_ident_standby_leader: (необязательно) записи pg_ident, специфичные для роли, для standby_leader. Они полностью заменяют pg_ident (слияние не происходит). Если не определены, используется pg_ident.
  • standby_cluster: если этот раздел определён, необходимо выполнить начальную инициализацию резервного сервера кластера.
    • host: адрес удалённого узла
    • port: порт удалённого узла
    • primary_slot_name: указывает, какой slot на удаленном узле использовать для репликации. Этот параметр необязателен, значение по умолчанию извлекается из имени экземпляра (см. функцию slot_name_from_member_name).
    • create_replica_methods: упорядоченный список методов, которые могут быть использованы для начальной инициализации резервного сервера из удалённого первичного сервера, может отличаться от списка, определённого в postgresql_settings
    • restore_command: команда для восстановления записей WAL с удалённого первичного сервера на узлы резервного кластера, может отличаться от списка, определённого в postgresql_settings
    • archive_cleanup_command: команда очистки для резервного сервера-лидера
    • recovery_min_apply_delay: время ожидания перед фактическим применением записей WAL на резервном сервере, который является лидером
  • member_slots_ttl: время удержания физических слотов репликации для реплик при их остановке. Значение по умолчанию: 30min. Установите значение 0, если хотите сохранить прежнее поведение (когда ключ участника истекает в DCS, слот удаляется немедленно). Данная функция работает только начиная с PostgreSQL 11.
  • slots: определяет постоянные слоты репликации. Эти слоты сохраняются при плановом переключении/переключении при отказе. Постоянные слоты, которые отсутствуют, будут созданы Patroni. Начиная с PostgreSQL 11 постоянные физические слоты создаются на всех узлах, и их позиция обновляется каждые loop_wait секунд. Для версий PostgreSQL, более старых, чем 11, постоянные физические слоты репликации поддерживаются только на текущем первичном сервере. Логические слоты копируются с первичного сервера на резервный сервер при перезапуске, после чего их позиция обновляется каждые loop_wait секунд (при необходимости). Копирование файлов логических слотов выполняется через соединение libpq с использованием либо параметров rewind, либо суперпользователя (см. раздел postgresql.authentication). Всегда существует вероятность, что позиция логического слота на реплике немного отстает от бывшего первичного сервера, поэтому приложение должно быть готово к тому, что некоторые сообщения могут быть получены повторно после переключения при отказе. Самый простой способ решения — отслеживание confirmed_flush_lsn. Включение постоянных слотов репликации требует установки postgresql.use_slots в значение true. Если определены постоянные логические слоты репликации, Patroni автоматически включает hot_standby_feedback. Поскольку переключение при отказе логических слотов репликации является небезопасным в PostgreSQL 9.6 и более старых версиях, а версия PostgreSQL 10 отсутствует некоторые важные функции, эта функция работает только с PostgreSQL 11 и новее.
    • my_slot_name: имя постоянного слота репликации. Если имя постоянного слота совпадает с именем текущего узла, он не будет создан на этом узле. Если добавить постоянный физический слот репликации, имя которого совпадает с именем участника Patroni, Patroni обеспечит сохранение этого слота даже в случае, когда соответствующий участник станет недоступным, что в обычных условиях привело бы к удалению слота Patroni. Хотя это может быть полезно в некоторых ситуациях, например, при необходимости сохранения слотов репликации участников во время временных сбоев или при импорте существующих участников в новый кластер Patroni (см. Преобразование автономного узла в кластер Patroni для подробностей), оператору следует проявлять осторожность, чтобы избежать сохранения таких конфликтов имён в DCS, когда слот больше не требуется, поскольку это может повлиять на нормальную работу Patroni.
      • type: тип слота. Может быть physical или logical. Если слот логический, необходимо дополнительно задать database и plugin. Если слот физический, можно необязательно задать cluster_type.
      • database: имя базы данных, в которой должны быть созданы логические слоты.
      • plugin: имя плагина для логического слота.
      • cluster_type: тип кластера (primary или standby), на котором должен быть создан слот, иначе слот не будет создан или будет удалён уже существующий слот.
  • ignore_slots: список наборов свойств слота репликации, для которых Patroni должен игнорировать совпадающие слоты. Эта конфигурация/функция полезна в тех случаях, когда некоторые слоты репликации управляются вне Patroni. Любое подмножество совпадающих свойств приведёт к игнорированию слота.
    • name: имя слота репликации.
    • type: тип слота. Может быть physical или logical. Если слот логический, можно дополнительно задать database и/или plugin.
    • database: имя базы данных (при совпадении с slot logical).
    • plugin: плагин логического декодирования (при совпадении с slot logical).

Примечание: slots — это хешмапа, а ignore_slots — массив. Например:

slots:
  permanent_logical_slot_name:
    type: logical
    database: my_db
    plugin: test_decoding
  permanent_physical_slot_name:
    type: physical
  ...
ignore_slots:
  - name: ignored_logical_slot_name
    type: logical
    database: my_db
    plugin: test_decoding
  - name: ignored_physical_slot_name
    type: physical
  ...

Примечание: при работе с PostgreSQL версии 11 или новее Patroni поддерживает физические слоты репликации на всех узлах, которые потенциально могут стать лидером, чтобы реплики сохраняли зарезервированными WAL сегментов, если они потребуются другим узлам. В случае, если узел отсутствует и его ключ участника в DCS истек, соответствующий слот репликации удаляется после member_slots_ttl (значение по умолчанию 30min). Вы можете увеличить или уменьшить срок хранения в зависимости от своих потребностей. Альтернативно, если топология кластера статична (фиксированное количество узлов, имена которых никогда не меняются), можно настроить постоянные физические слоты репликации с именами, соответствующими именам узлов, чтобы избежать удаления слотов и повторного использования файлов WAL при временной недоступности реплики:

slots:
  node_name1:
    type: physical
  node_name2:
    type: physical
  node_name3:
    type: physical
  ...
Предупреждение

Постоянные слоты репликации синхронизируются только от primary/standby_leader к репликам. Это означает, что приложения должны использовать их только на лидере. Использование их на репликах приведёт к неограниченному росту pg_wal на всех остальных узлах кластера. Исключением из этого правила являются физические слоты, соответствующие именам участников Patroni (создаваемые и поддерживаемые Patroni). Они синхронизируются между всеми узлами, поскольку используются для репликации между ними.

Предупреждение

Установка тега nostream на резервном сервере отключает копирование и синхронизацию постоянных слотов репликации на самом узле и на всех его каскадных репликах, если таковые имеются.

3.3 - Настройки конфигурации среды

Переменные среды для переопределения параметров конфигурации Patroni.

Возможно переопределить некоторые параметры конфигурации, определённые в файле конфигурации Patroni, с помощью переменных среды системы. В данном документе перечислены все переменные среды, обрабатываемые Patroni. Значения, установленные с помощью этих переменных, всегда имеют приоритет перед значениями, заданными в файле конфигурации Patroni.


Глобальный/Всемирный

  • PATRONI_CONFIGURATION: конфигурацию Patroni целиком можно задать с помощью переменной среды PATRONI_CONFIGURATION . В этом случае никакие другие переменные среды не будут учитываться!
  • PATRONI_THREAD_POOL_SIZE: размер пула потоков, используемый Patroni для выполнения асинхронных задач и обмена данными по REST API с другими участниками во время выбора лидера или проверок в аварийном режиме. Минимальное значение — 5, значение по умолчанию — 5.
  • PATRONI_THREAD_STACK_SIZE: указывает размер стека, используемый для потоков, запускаемых Patroni. Значение должно быть выровнено по 64kB. Минимальное значение — 64kB, значение по умолчанию (устанавливается Patroni) — 512kB.
  • PATRONI_NAME: имя узла, на котором выполняется текущая инстанция Patroni. Должно быть уникальным для кластера. Значение __patroni_strict_sync_replica_placeholder__ зарезервировано для внутреннего использования Patroni и не может использоваться в качестве имени узла.
  • PATRONI_NAMESPACE: путь в хранилище конфигурации, где Patroni будет хранить информацию о кластере. Значение по умолчанию: “/service”
  • PATRONI_SCOPE: имя кластера
  • PG_MALLOC_ARENA_MAX: пользовательское значение переменной среды MALLOC_ARENA_MAX для процесса postmaster. Если не задано, postmaster унаследует значение MALLOC_ARENA_MAX.

Журнал

  • PATRONI_LOG_TYPE: задаёт формат логов. Может быть либо plain, либо json. Для использования формата json необходимо установить jsonlogger . Значение по умолчанию — plain.
  • PATRONI_LOG_LEVEL: задаёт уровень ведения журнала. Значение по умолчанию — INFO (см. документацию по ведению журнала в Python )
  • PATRONI_LOG_TRACEBACK_LEVEL: задаёт уровень, на котором будут видны трассировки. Значение по умолчанию — ERROR. Установите значение DEBUG, если хотите видеть трассировки только при включении PATRONI_LOG_LEVEL=DEBUG.
  • PATRONI_LOG_FORMAT: задаёт строку форматирования журнала. Если тип журнала — plain, формат журнала должен быть строкой. См. атрибуты LogRecord для получения списка доступных атрибутов. Если тип журнала — json, формат журнала может быть списком, помимо строки. Каждый элемент списка должен соответствовать атрибуту LogRecord. Будьте осторожны: требуется только имя поля, а символы %( и ) опускаются. Если необходимо вывести поле журнала с другим именем ключа, используйте словарь, где ключ словаря — это поле журнала, а значение — имя поля, которое должно быть выведено в журнале. Значение по умолчанию: %(asctime)s %(levelname)s: %(message)s
  • PATRONI_LOG_DATEFORMAT: задаёт строку форматирования даты и времени. (см. документацию formatTime() )
  • PATRONI_LOG_STATIC_FIELDS: добавить дополнительные поля в лог. Этот параметр доступен только при установке типа лога в json. Пример PATRONI_LOG_STATIC_FIELDS="{app: patroni}"
  • PATRONI_LOG_MAX_QUEUE_SIZE: Patroni использует двухэтапное ведение журнала. Записи журнала записываются в очереди в оперативной памяти, а отдельный поток извлекает их из очереди и записывает в stderr или файл. Максимальный размер внутренней очереди по умолчанию ограничен 1000 записями, что достаточно для хранения журналов за последние 1 час 20 минут.
  • PATRONI_LOG_DIR: Каталог для записи журналов приложения. Каталог должен существовать и быть доступен для записи пользователем, запускающим Patroni. Если задан этот параметр среды, приложение по умолчанию сохраняет журналы 4 25MB. Значения хранения можно настроить с помощью PATRONI_LOG_FILE_NUM и PATRONI_LOG_FILE_SIZE (см. ниже).
  • PATRONI_LOG_MODE: Разрешения для файлов журнала (например, 0644). Если не указано, разрешения будут установлены на основе текущего значения umask.
  • PATRONI_LOG_FILE_NUM: Количество журналов приложений, которые необходимо сохранить.
  • PATRONI_LOG_FILE_SIZE: Размер файла patroni.log (в байтах), при достижении которого происходит смена лог-файла.
  • PATRONI_LOG_LOGGERS: Переопределение уровня ведения журнала для каждого модуля Python. Пример PATRONI_LOG_LOGGERS="{patroni.postmaster: WARNING, urllib3: DEBUG}"
  • PATRONI_LOG_DEDUPLICATE_HEARTBEAT_LOGS: Если установлено в true, последовательные журналы heartbeat, одинаковые по содержанию, не будут выводиться. Значение по умолчанию — false.
Предупреждение

Время выполнения цикла высокой доступности может быть очень полезной информацией при диагностике переключений при отказе из-за нехватки ресурсов и подобных проблем. Когда PATRONI_LOG_DEDUPLICATE_HEARTBEAT_LOGS установлен в true, журналы не будут содержать записи о выполнении цикла высокой доступности (если только не произойдёт смена лидера), и, таким образом, эта потенциально полезная информация станет недоступной в журналах.


Citus

Включает интеграцию Patroni с Citus . При настройке Patroni будет отвечать за регистрацию узлов-работников Citus на координаторе. Дополнительную информацию о поддержке Citus можно найти здесь .

  • PATRONI_CITUS_GROUP: идентификатор группы Citus, целое число. Используйте 0 для координатора и 1, 2 и т.д. для воркеров
  • PATRONI_CITUS_DATABASE: база данных, в которой должен быть создан расширение citus . Должен быть одинаковым на координаторе и всех воркерах. В настоящее время поддерживается только одна база данных.

Consul

  • PATRONI_CONSUL_HOST: хост:порт для локального агента Consul.
  • PATRONI_CONSUL_URL: URL для локального агента Consul в формате: http(s)://host:port
  • PATRONI_CONSUL_PORT: (необязательно) порт Consul
  • PATRONI_CONSUL_SCHEME: (необязательно) http или https, значение по умолчанию — http
  • PATRONI_CONSUL_TOKEN: (необязательно) токен ACL
  • PATRONI_CONSUL_VERIFY: (необязательно) проверять ли сертификат SSL для запросов HTTPS
  • PATRONI_CONSUL_CACERT: (необязательно) Сертификат CA. При наличии включает проверку подлинности.
  • PATRONI_CONSUL_CERT: (необязательно) Файл с клиентским сертификатом
  • PATRONI_CONSUL_KEY: (необязательно) Файл с ключом клиента. Может быть пустым, если ключ входит в сертификат.
  • PATRONI_CONSUL_DC: (необязательно) Центр обработки данных для связи. По умолчанию используется центр обработки данных хоста.
  • PATRONI_CONSUL_CONSISTENCY: (необязательно) выберите режим согласованности Consul. Допустимые значения: default, consistent или stale (подробнее в справочнике API Consul )
  • PATRONI_CONSUL_CHECKS: (необязательно) список проверок состояния Consul, используемых для сессии. По умолчанию используется пустой список.
  • PATRONI_CONSUL_REGISTER_SERVICE: (необязательно) указывает, следует ли регистрировать службу с именем, определённым параметром scope, и тегом master, primary, replica или standby-leader в зависимости от роли узла. По умолчанию — false
  • PATRONI_CONSUL_SERVICE_TAGS: (необязательно) дополнительные статические теги, добавляемые к сервису Consul помимо роли (primary/replica/standby-leader). По умолчанию используется пустой список.
  • PATRONI_CONSUL_SERVICE_CHECK_INTERVAL: (необязательно) как часто выполнять проверку состояния для зарегистрированного URL
  • PATRONI_CONSUL_SERVICE_CHECK_TLS_SERVER_NAME: (необязательно) переопределить хост SNI при подключении через TLS, см. также справочник проверки агента Consul API .

Etcd

  • PATRONI_ETCD_PROXY: URL прокси для etcd. Если вы подключаетесь к etcd через прокси, используйте этот параметр вместо PATRONI_ETCD_URL
  • PATRONI_ETCD_URL: URL для etcd в формате: http(s)://(username:password@)хост:порт
  • PATRONI_ETCD_HOSTS: список конечных точек etcd в формате ‘хост1:порт1’,‘хост2:порт2’, и т.д.
  • PATRONI_ETCD_USE_PROXIES: Если этот параметр установлен в значение true, Patroni будет считать hosts списком прокси-серверов и не будет выполнять обнаружение топологии кластера etcd, а будет использовать фиксированный список hosts.
  • PATRONI_ETCD_PROTOCOL: http или https, если не указано — используется http. Если указан url или proxy — протокол берётся из них.
  • PATRONI_ETCD_HOST: хост:порт для конечной точки etcd.
  • PATRONI_ETCD_SRV: Домен для поиска записи(ей) SRV при автодиагностике кластера. Patroni будет пытаться запросить эти имена служб SRV для указанного домена (в указанном порядке до первого успешного результата): _etcd-client-ssl, _etcd-client, _etcd-ssl, _etcd, _etcd-server-ssl, _etcd-server. Если будут получены записи SRV для _etcd-server-ssl или _etcd-server, то будет использован протокол peer ETCD для запроса ETCD о доступных участниках. В противном случае будут использованы хосты из записей SRV.
  • PATRONI_ETCD_SRV_SUFFIX: Настраивает суффикс к имени SRV, который запрашивается при обнаружении. Используйте этот флаг для различия между несколькими кластерами etcd в рамках одного домена. Работает только в сочетании с PATRONI_ETCD_SRV. Например, если установлены PATRONI_ETCD_SRV_SUFFIX=foo и PATRONI_ETCD_SRV=example.org, выполняется следующий запрос DNS SRV:_etcd-client-ssl-foo._tcp.example.com (и так далее для каждого возможного имени службы ETCD SRV).
  • PATRONI_ETCD_USERNAME: имя пользователя для аутентификации в etcd.
  • PATRONI_ETCD_PASSWORD: пароль для аутентификации в etcd.
  • PATRONI_ETCD_CACERT: Сертификат CA. При его наличии будет включена проверка.
  • PATRONI_ETCD_CERT: Файл сертификата клиента.
  • PATRONI_ETCD_KEY: Файл с ключом клиента. Может быть пустым, если ключ входит в сертификат.

Etcdv3

Имена переменных окружения для Etcdv3 аналогичны именам для etcd, вам нужно просто использовать ETCD3 вместо ETCD в имени переменной. Пример: PATRONI_ETCD3_HOST, PATRONI_ETCD3_CACERT и так далее.

Предупреждение

Ключи, созданные с использованием версии протокола 2, недоступны при использовании версии протокола 3, и наоборот, поэтому невозможно переключиться с etcd на Etcdv3 просто путём обновления конфигурации Patroni. Кроме того, Patroni использует gRPC-шлюз (прокси) etcd для взаимодействия с V3 API, что означает, что аутентификация по общему имени TLS невозможна.


ZooKeeper

  • PATRONI_ZOOKEEPER_HOSTS: Список участников кластера ZooKeeper, разделённый запятыми: “‘host1:port1’,‘host2:port2’,’etc…’”. Важно заключать каждый элемент в кавычки!
  • PATRONI_ZOOKEEPER_USE_SSL: (необязательно) Указывает, используется ли SSL. Значение по умолчанию — false. Если установлено в false, все параметры, специфичные для SSL, игнорируются.
  • PATRONI_ZOOKEEPER_CACERT: (необязательно) Сертификат ЦС. При наличии включает проверку подлинности.
  • PATRONI_ZOOKEEPER_CERT: (необязательно) Файл с клиентским сертификатом.
  • PATRONI_ZOOKEEPER_KEY: (необязательно) Файл с ключом клиента.
  • PATRONI_ZOOKEEPER_KEY_PASSWORD: (необязательно) Пароль ключа клиента.
  • PATRONI_ZOOKEEPER_VERIFY: (необязательно) Проверять сертификат или нет. Значение по умолчанию — true.
  • PATRONI_ZOOKEEPER_SET_ACLS: (необязательно) Если задано, настраивает Kazoo на применение по умолчанию ACL к каждому ZNode, который он создаёт. ACL могут использовать схему x509 (по умолчанию) или другие поддерживаемые схемы ZooKeeper, такие как digest. Они должны указываться как словарь, где ключ — полное имя субъекта (опционально с префиксом схемы), а значение — список разрешений. Разрешения могут быть одним или несколькими из CREATE, READ, WRITE, DELETE, ADMIN, или ALL. Например, set_acls: {CN=principal1: [CREATE, READ], digest:principal2:+pjROuBuuwNNSujKyH8dGcEnFPQ=: [ALL]}.
  • PATRONI_ZOOKEEPER_AUTH_DATA: (необязательно) Учетные данные аутентификации для использования при соединении. Должно быть словарем в формате, где scheme — ключ, а credential — значение. По умолчанию — пустой словарь.
Примечание

Необходимо установить kazoo>=2.6.0 для поддержки SSL.


Выставщик

  • PATRONI_EXHIBITOR_HOSTS: начальный список узлов Exhibitor (ZooKeeper) в формате: ‘host1,host2,etc…’. Этот список обновляется автоматически при изменении топологии кластера Exhibitor (ZooKeeper).
  • PATRONI_EXHIBITOR_PORT: Порт выставки.


Kubernetes

  • PATRONI_KUBERNETES_BYPASS_API_SERVICE: (необязательно) При взаимодействии с Kubernetes API Patroni обычно полагается на сервис kubernetes , адрес которого доступен в подах через переменную KUBERNETES_SERVICE_HOST. Если установлено значение PATRONI_KUBERNETES_BYPASS_API_SERVICE, равное true, Patroni будет разрешать список API узлов за сервисом и подключаться к ним напрямую.
  • PATRONI_KUBERNETES_NAMESPACE: (необязательно) пространство имён Kubernetes, в котором выполняется под Patroni. Значение по умолчанию — default.
  • PATRONI_KUBERNETES_LABELS: Метки в формате {label1: value1, label2: value2}. Эти метки будут использоваться для поиска существующих объектов (Pod’ов и либо Endpoints, либо ConfigMaps), связанных с текущим кластером. Также Patroni будет устанавливать их на каждый объект (Endpoint или ConfigMap), который создаёт.
  • PATRONI_KUBERNETES_SCOPE_LABEL: (необязательно) имя метки, содержащей имя кластера. Значение по умолчанию — cluster-name.
  • PATRONI_KUBERNETES_BOOTSTRAP_LABELS: (необязательно) Метки в формате {label1: value1, label2: value2}. Эти метки будут присвоены поду Patroni, когда его состояние будет initializing new cluster, running custom bootstrap script, starting after custom bootstrap или creating replica.
  • PATRONI_KUBERNETES_ROLE_LABEL: (необязательно) имя метки, содержащей роль (primary, replica или другое пользовательское значение). Patroni установит эту метку в поде, в котором выполняется. Значение по умолчанию — role.
  • PATRONI_KUBERNETES_LEADER_LABEL_VALUE: (необязательно) значение метки пода при роли Postgres primary. Значение по умолчанию — primary.
  • PATRONI_KUBERNETES_FOLLOWER_LABEL_VALUE: (необязательно) значение метки пода при роли Postgres replica. Значение по умолчанию — replica.
  • PATRONI_KUBERNETES_STANDBY_LEADER_LABEL_VALUE: (необязательно) значение метки пода при роли Postgres standby_leader. Значение по умолчанию — primary.
  • PATRONI_KUBERNETES_TMP_ROLE_LABEL: (необязательно) имя временной метки, содержащей роль (primary или replica). Значение этой метки всегда будет использовать значение по умолчанию, соответствующее роли. Устанавливать только при необходимости.
  • PATRONI_KUBERNETES_USE_ENDPOINTS: (необязательно) если установлено в true, Patroni будет использовать Endpoints вместо ConfigMaps для проведения выборов лидера и хранения состояния кластера.
  • PATRONI_KUBERNETES_POD_IP: (необязательно) IP-адрес пода, в котором запущен Patroni. Это значение необходимо, когда включён PATRONI_KUBERNETES_USE_ENDPOINTS, и используется для заполнения подмножеств конечной точки лидера при повышении пода PostgreSQL до роли лидера.
  • PATRONI_KUBERNETES_PORTS: (необязательно) если у объекта Service указано имя порта, то такое же имя должно присутствовать в объекте Endpoint, иначе сервис не будет работать. Например, если ваш сервис определён как {Kind: Service, spec: {ports: [{name: postgresql, port: 5432, targetPort: 5432}]}}, необходимо установить PATRONI_KUBERNETES_PORTS='[{"name": "postgresql", "port": 5432}]', и Patroni будет использовать его для обновления подмножеств лидера Endpoint. Этот параметр используется только в том случае, если установлено PATRONI_KUBERNETES_USE_ENDPOINTS.
  • PATRONI_KUBERNETES_CACERT: (необязательно) Указывает файл с CA_BUNDLE файлом сертификатов доверенных ЦС, используемых при проверке сертификатов Kubernetes API SSL. Если не указано, Patroni использует значение, предоставленное секретом ServiceAccount.
  • PATRONI_RETRIABLE_HTTP_CODES: (необязательно) список кодов состояния HTTP от K8s API, на которых следует повторять попытку. По умолчанию Patroni повторяет попытки при кодах 500, 503 и 504, либо если ответ K8s API содержит заголовок retry-after HTTP.

Raft (устаревший)

  • PATRONI_RAFT_SELF_ADDR: ip:port для прослушивания соединений Raft. self_addr должен быть доступен с других узлов кластера. Если не задан, узел не будет участвовать в согласовании.
  • PATRONI_RAFT_BIND_ADDR: (необязательно) ip:port для прослушивания соединений Raft. Если не указано, будет использован self_addr.
  • PATRONI_RAFT_PARTNER_ADDRS: список других узлов Patroni в кластере в формате "'ip1:port1','ip2:port2'". Важно заключать каждый элемент в кавычки!
  • PATRONI_RAFT_DATA_DIR: каталог для хранения журнала Raft и снимков. Если не указан, используется текущий рабочий каталог.
  • PATRONI_RAFT_PASSWORD: (необязательно) Шифрование трафика Raft с указанным паролем, требует модуля cryptography Python.
  • PATRONI_RAFT_MIN_TIMEOUT: (необязательно) минимальный тайм-аут выборов в секундах для базовой реализации Raft pysyncobj. Должен быть больше 3 * PATRONI_RAFT_APPEND_ENTRIES_PERIOD. Значение по умолчанию: 0.4.
  • PATRONI_RAFT_MAX_TIMEOUT: (необязательно) максимальный тайм-аут голосования в секундах для базовой реализации Raft pysyncobj. Должен быть больше, чем PATRONI_RAFT_MIN_TIMEOUT. Значение по умолчанию: 1.4.
  • PATRONI_RAFT_CONNECTION_TIMEOUT: (необязательно) время в секундах, по истечении которого соединение без полученных данных считается неработоспособным. Должно быть больше или равно PATRONI_RAFT_MAX_TIMEOUT. Значение по умолчанию: 3.5.
  • PATRONI_RAFT_APPEND_ENTRIES_PERIOD: (необязательно) интервал в секундах для отправки команд heartbeat. Должен быть меньше одной трети PATRONI_RAFT_MIN_TIMEOUT. Значение по умолчанию: 0.1.
  • PATRONI_RAFT_CONNECTION_RETRY_TIME: (необязательно) интервал в секундах между попытками повторного подключения к оффлайн-узлам. По умолчанию: 5.0.
  • PATRONI_RAFT_LEADER_FALLBACK_TIMEOUT: (необязательно) время в секундах, по истечении которого лидер, не получивший ответ от большинства, возвращается в состояние последователя. Должно быть больше, чем PATRONI_RAFT_APPEND_ENTRIES_PERIOD. Значение по умолчанию: 30.0.
Примечание

Patroni проверяет эти ограничения при запуске и откажется запускаться, если они нарушены. Эти значения нельзя изменить во время выполнения и требуют перезапуска. Подробности см. в настройках Raft , включая ограничение на высокую задержку.


PostgreSQL

  • PATRONI_POSTGRESQL_LISTEN: IP-адрес + порт, на которых слушает Postgres. Допускается указывать несколько адресов, разделённых запятыми, при условии, что компонент порта указывается после последнего адреса через двоеточие, i.e. listen: 127.0.0.1,127.0.0.2:5432. Patroni будет использовать первый адрес из этого списка для установления локальных соединений с узлом PostgreSQL.
  • PATRONI_POSTGRESQL_CONNECT_ADDRESS: IP-адрес + порт, через которые Postgres доступен из других узлов и приложений.
  • PATRONI_POSTGRESQL_PROXY_ADDRESS: IP-адрес + порт, через которые доступен пул соединений (e.g. PgBouncer), работающий рядом с Postgres. Значение записывается в ключ участник в DCS как proxy_url и может быть полезно для обнаружения сервисов.
  • PATRONI_POSTGRESQL_DATA_DIR: Расположение каталога данных PostgreSQL, существующего или подлежащего инициализации Patroni.
  • PATRONI_POSTGRESQL_CONFIG_DIR: Расположение каталога конфигурации PostgreSQL, по умолчанию — каталог данных. Должен быть доступен для записи Patroni.
  • PATRONI_POSTGRESQL_BIN_DIR: Путь к бинарным файлам PostgreSQL. (pg_ctl, initdb, pg_controldata, pg_basebackup, postgres, pg_isready, pg_rewind) Значение по умолчанию — пустая строка, что означает использование переменной среды PATH для поиска исполняемых файлов.
  • PATRONI_POSTGRESQL_BIN_PG_CTL: (необязательно) Пользовательское имя для бинарного файла pg_ctl.
  • PATRONI_POSTGRESQL_BIN_INITDB: (необязательно) Пользовательское имя для бинарного файла initdb.
  • PATRONI_POSTGRESQL_BIN_PG_CONTROLDATA: (необязательно) Пользовательское имя для бинарного файла pg_controldata.
  • PATRONI_POSTGRESQL_BIN_PG_BASEBACKUP: (необязательно) Пользовательское имя для бинарного файла pg_basebackup.
  • PATRONI_POSTGRESQL_BIN_POSTGRES: (необязательно) Пользовательское имя для бинарного файла postgres.
  • PATRONI_POSTGRESQL_BIN_IS_READY: (необязательно) Пользовательское имя для бинарного файла pg_isready.
  • PATRONI_POSTGRESQL_BIN_PG_REWIND: (необязательно) Пользовательское имя для бинарного файла pg_rewind.
  • PATRONI_POSTGRESQL_PGPASS: путь к файлу паролей .pgpass . Patroni создаёт этот файл перед выполнением pg_basebackup и при некоторых других обстоятельствах. Расположение должно быть доступно для записи Patroni.
  • PATRONI_REPLICATION_USERNAME: имя пользователя репликации; пользователь будет создан во время инициализации. Реплики будут использовать этого пользователя для доступа к источнику репликации через потоковую репликацию
  • PATRONI_REPLICATION_PASSWORD: пароль репликации; пользователь будет создан во время инициализации.
  • PATRONI_REPLICATION_SSLMODE: (необязательно) отображается на параметр соединения sslmode , позволяющий клиенту указать тип TLS режима согласования с сервером. Подробнее о том, как работает каждый режим, см. в документации PostgreSQL . Значение по умолчанию — prefer.
  • PATRONI_REPLICATION_SSLKEY: (необязательно) отображается на параметр соединения sslkey , который указывает расположение закрытого ключа, используемого с сертификатом клиента.
  • PATRONI_REPLICATION_SSLPASSWORD: (необязательно) отображается на параметр соединения sslpassword , который указывает пароль для секретного ключа, указанного в PATRONI_REPLICATION_SSLKEY.
  • PATRONI_REPLICATION_SSLCERT: (необязательно) отображается на параметр соединения sslcert , который указывает расположение сертификата клиента.
  • PATRONI_REPLICATION_SSLROOTCERT: (необязательно) отображается на параметр соединения sslrootcert , который указывает расположение файла, содержащего один или несколько сертификатов удостоверяющих центров (CA), которые клиент будет использовать для проверки сертификата сервера.
  • PATRONI_REPLICATION_SSLCRL: (необязательно) отображается на параметр соединения sslcrl , указывающий путь к файлу, содержащему список отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
  • PATRONI_REPLICATION_SSLCRLDIR: (необязательно) отображается на параметр соединения sslcrldir , указывающий путь к каталогу, содержащему файлы со списками отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
  • PATRONI_REPLICATION_SSLNEGOTIATION: (необязательно) отображается на параметр соединения sslnegotiation , управляющий процессом согласования SSL шифрования с сервером, если используется SSL.
  • PATRONI_REPLICATION_GSSENCMODE: (необязательно) отображается на параметр соединения gssencmode , определяющий, будет ли устанавливаться защищённое соединение GSS TCP/IP с сервером, и с какой приоритетностью
  • PATRONI_REPLICATION_CHANNEL_BINDING: (необязательно) отображается на параметр соединения channel_binding , управляющий использованием клиентом привязки канала.
  • PATRONI_SUPERUSER_USERNAME: имя суперпользователя, задаётся во время инициализации (initdb) и затем используется Patroni для подключения к postgres. Также этот пользователь используется pg_rewind.
  • PATRONI_SUPERUSER_PASSWORD: пароль суперпользователя, устанавливаемый при инициализации (initdb).
  • PATRONI_SUPERUSER_SSLMODE: (необязательно) отображается на параметр соединения sslmode , позволяющий клиенту указать тип TLS режима согласования с сервером. Подробнее о том, как работает каждый режим, см. в документации PostgreSQL . Значение по умолчанию — prefer.
  • PATRONI_SUPERUSER_SSLKEY: (необязательно) отображается на параметр соединения sslkey , который указывает расположение закрытого ключа, используемого вместе с сертификатом клиента.
  • PATRONI_SUPERUSER_SSLPASSWORD: (необязательно) отображается на параметр соединения sslpassword , который указывает пароль для секретного ключа, указанного в PATRONI_SUPERUSER_SSLKEY.
  • PATRONI_SUPERUSER_SSLCERT: (необязательно) отображается на параметр соединения sslcert , который указывает расположение сертификата клиента.
  • PATRONI_SUPERUSER_SSLROOTCERT: (необязательно) отображается на параметр соединения sslrootcert , который указывает путь к файлу, содержащему один или несколько сертификатов центров сертификации (CA), которые клиент будет использовать для проверки сертификата сервера.
  • PATRONI_SUPERUSER_SSLCRL: (необязательно) отображается на параметр соединения sslcrl , который указывает расположение файла, содержащего список отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
  • PATRONI_SUPERUSER_SSLCRLDIR: (необязательно) отображается на параметр соединения sslcrldir , указывающий путь к каталогу, содержащему файлы со списками отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
  • PATRONI_SUPERUSER_SSLNEGOTIATION: (необязательно) отображается на параметр соединения sslnegotiation , управляющий процессом согласования SSL шифрования с сервером, если используется SSL.
  • PATRONI_SUPERUSER_GSSENCMODE: (необязательно) отображается на параметр соединения gssencmode , определяющий, будет ли устанавливаться защищённое соединение GSS TCP/IP с сервером, и с какой приоритетностью
  • PATRONI_SUPERUSER_CHANNEL_BINDING: (необязательно) отображается на параметр соединения channel_binding , управляющий использованием клиентом привязки канала.
  • PATRONI_REWIND_USERNAME: (необязательно) имя пользователя для pg_rewind; пользователь будет создан при инициализации postgres 11+ и будут выданы все необходимые разрешения .
  • PATRONI_REWIND_PASSWORD: (необязательно) пароль для пользователя для pg_rewind; пользователь будет создан при инициализации.
  • PATRONI_REWIND_SSLMODE: (необязательно) отображается на параметр соединения sslmode , позволяющий клиенту указать тип TLS режима согласования с сервером. Подробнее о том, как работает каждый режим, см. в документации PostgreSQL . Значение по умолчанию — prefer.
  • PATRONI_REWIND_SSLKEY: (необязательно) отображается на параметр соединения sslkey , который указывает расположение закрытого ключа, используемого с сертификатом клиента.
  • PATRONI_REWIND_SSLPASSWORD: (необязательно) отображается на параметр соединения sslpassword , который указывает пароль для секретного ключа, указанного в PATRONI_REWIND_SSLKEY.
  • PATRONI_REWIND_SSLCERT: (необязательно) отображается на параметр соединения sslcert , который указывает расположение сертификата клиента.
  • PATRONI_REWIND_SSLROOTCERT: (необязательно) отображается на параметр соединения sslrootcert , который указывает расположение файла, содержащего один или несколько сертификатов центров сертификации (CA), которые клиент будет использовать для проверки сертификата сервера.
  • PATRONI_REWIND_SSLCRL: (необязательно) отображается на параметр соединения sslcrl , указывающий путь к файлу, содержащему список отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
  • PATRONI_REWIND_SSLCRLDIR: (необязательно) отображается на параметр соединения sslcrldir , который указывает расположение каталога, содержащего файлы со списками отозванных сертификатов. Клиент откажет в подключении к любому серверу, сертификат которого находится в этом списке.
  • PATRONI_REWIND_SSLNEGOTIATION: (необязательно) отображается на параметр соединения sslnegotiation , управляющий процессом согласования SSL шифрования с сервером, если используется SSL.
  • PATRONI_REWIND_GSSENCMODE: (необязательно) отображается на параметр соединения gssencmode , определяющий, будет ли устанавливаться защищённое соединение GSS TCP/IP с сервером, и с какой приоритетностью
  • PATRONI_REWIND_CHANNEL_BINDING: (необязательно) отображается на параметр соединения channel_binding , управляющий использованием клиентом привязки канала.

REST API

  • PATRONI_RESTAPI_THREAD_POOL_SIZE: размер пула потоков, используемого Patroni для обработки запросов REST API. Минимальное значение — 5, значение по умолчанию — 5.
  • PATRONI_RESTAPI_CONNECT_ADDRESS: IP-адрес и порт для доступа к REST API.
  • PATRONI_RESTAPI_LISTEN: IP-адрес и порт, на которых Patroni будет слушать, чтобы предоставлять информацию о состоянии для HAProxy.
  • PATRONI_RESTAPI_USERNAME: имя пользователя для аутентификации по базовой схеме для защиты небезопасных конечных точек REST API.
  • PATRONI_RESTAPI_PASSWORD: Пароль аутентификации по базе для защиты небезопасных конечных точек REST API.
  • PATRONI_RESTAPI_CERTFILE: Указывает файл сертификата в формате PEM. Если параметр certfile не указан или оставлен пустым, сервер API будет работать без SSL.
  • PATRONI_RESTAPI_KEYFILE: Указывает файл с секретным ключом в формате PEM.
  • PATRONI_RESTAPI_KEYFILE_PASSWORD: Указывает пароль для расшифровки ключевого файла.
  • PATRONI_RESTAPI_CAFILE: Указывает файл с CA_BUNDLE, содержащий сертификаты доверенных ЦС, используемые при проверке сертификатов клиентов.
  • PATRONI_RESTAPI_CIPHERS: (необязательно) Задаёт разрешённые наборы шифров (e.g. “ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:!SSLv1:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1”)
  • PATRONI_RESTAPI_VERIFY_CLIENT: none (по умолчанию), optional или required. При none REST API проверка сертификатов клиентов не выполняется. При required для всех вызовов REST API требуется сертификат клиента. При optional для всех небезопасных конечных точек REST API требуется сертификат клиента. При required аутентификация клиента считается успешной, если проверка подписи сертификата прошла успешно. Для optional сертификат клиента проверяется только для запросов PUT, POST, PATCH и DELETE.
  • PATRONI_RESTAPI_ALLOWLIST: (необязательно): указывает набор хостов, которые могут вызывать небезопасные конечные точки REST API. Единственный элемент может быть именем хоста, IP-адресом или сетевым адресом в нотации CIDR. По умолчанию используется allow all. Если установлены allowlist или allowlist_include_members, то всё, что не включено, отклоняется.
  • PATRONI_RESTAPI_ALLOWLIST_INCLUDE_MEMBERS: (необязательно): если установлено в true, позволяет получать доступ к небезопасным конечным точкам REST API с других участников кластера, зарегистрированных в DCS (IP-адрес или имя хоста берётся из участников api_url). Будьте осторожны, возможна ситуация, при которой ОС может использовать другой IP-адрес для исходящих соединений.
  • PATRONI_RESTAPI_HTTP_EXTRA_HEADERS: (необязательно) заголовки HTTP позволяют серверу REST API передавать дополнительную информацию в ответе HTTP.
  • PATRONI_RESTAPI_HTTPS_EXTRA_HEADERS: (необязательно) заголовки HTTPS позволяют серверу REST API передавать дополнительную информацию в ответе HTTP при включённом TLS. Это также передаст дополнительную информацию, установленную в http_extra_headers.
  • PATRONI_RESTAPI_REQUEST_QUEUE_SIZE: (необязательно): устанавливает размер очереди запросов для сокета TCP, используемого Patroni REST API. Как только очередь заполнена, последующие запросы получают ошибку «Соединение запрещено». Значение по умолчанию — 5.
  • PATRONI_RESTAPI_SERVER_TOKENS: (необязательно) Настраивает значение заголовка Server HTTP. Original (по умолчанию) сохраняет исходное поведение и отображает версии BaseHTTP и Python, e.g. BaseHTTP/0.6 Python/3.12.3. Minimal: заголовок будет содержать только версию Patroni, e.g. Patroni/4.0.0. ProductOnly: заголовок будет содержать только имя продукта, e.g. Patroni.

Предупреждение

  • PATRONI_RESTAPI_CONNECT_ADDRESS должен быть доступен со всех узлов заданного кластера Patroni. Внутри Patroni он используется во время выбора лидера для определения узлов с минимальной задержкой репликации.
  • Если включена проверка сертификатов клиентов (значение PATRONI_RESTAPI_VERIFY_CLIENT установлено в required), также обязательно предоставить действительные сертификаты клиентов в PATRONI_CTL_CERTFILE, PATRONI_CTL_KEYFILE, PATRONI_CTL_KEYFILE_PASSWORD. Если они не предоставлены, Patroni будет работать некорректно.

CTL

  • PATRONICTL_CONFIG_FILE: (необязательно) расположение файла конфигурации.
  • PATRONI_CTL_USERNAME: (необязательно) Имя пользователя для аутентификации по базовой схеме при доступе к защищённым конечным точкам REST API. Если не указано, patronictl будет использовать значение, указанное для параметра “username” REST API.
  • PATRONI_CTL_PASSWORD: (необязательно) Пароль для аутентификации по методу Basic-auth при доступе к защищённым конечным точкам REST API. Если не указан, patronictl будет использовать значение, указанное для параметра “password” REST API.
  • PATRONI_CTL_INSECURE: (необязательно) Разрешить соединения с REST API без проверки сертификатов SSL.
  • PATRONI_CTL_CACERT: (необязательно) Указывает файл с CA_BUNDLE файлом или каталогом сертификатов доверенных ЦС, используемых при проверке REST API SSL сертификатов. Если не указано, patronictl будет использовать значение, заданное для параметра REST API “cafile”.
  • PATRONI_CTL_CERTFILE: (необязательно) Указывает файл сертификата клиента в формате PEM.
  • PATRONI_CTL_KEYFILE: (необязательно) Указывает файл с секретным ключом клиента в формате PEM.
  • PATRONI_CTL_KEYFILE_PASSWORD: (необязательно) Указывает пароль для расшифровки ключевого файла клиента.

4 - Patroni REST API

Справочник по конечным точкам REST API Patroni и их рабочему поведению.

Patroni предоставляет обширный REST API. Сам Patroni использует его во время выбора лидера, инструмент patronictl — для аварийных и плановых переключений, повторной инициализации, перезапусков и перезагрузки конфигурации, а HAProxy и другие балансировщики — для проверок работоспособности HTTP. API также можно применять для мониторинга. Ниже перечислены конечные точки REST API Patroni.


Конечные точки проверки работоспособности

На все запросы проверки GET Patroni возвращает документ JSON с состоянием узла и код состояния HTTP. Если документ JSON не нужен, вместо GET можно использовать метод HEAD или OPTIONS.

  • Следующие запросы REST API Patroni возвращают код HTTP 200, только когда узел Patroni работает как первичный сервер и владеет блокировкой лидера:

    • GET /
    • GET /primary
    • GET /read-write
  • GET /standby-leader: возвращает код HTTP 200, только когда узел Patroni является лидером резервного кластера .

  • GET /leader: возвращает код HTTP 200, когда узел Patroni владеет блокировкой лидера. Главное отличие от двух предыдущих конечных точек — не учитывается, работает ли PostgreSQL как primary или standby_leader.

  • GET /replica: конечная точка проверки реплики. Возвращает код HTTP 200, только когда узел Patroni находится в состоянии running, его роль — replica, а тег noloadbalance не задан.

  • GET /replica?replication_state=<required state>: конечная точка проверки реплики. Помимо проверок replica она проверяет соответствие состояния репликации требуемому. Особенно полезна с replication_state=streaming, чтобы исключить реплики, которые ещё догоняют кластер при восстановлении из архива.

  • GET /replica?lag=<max-lag>: конечная точка проверки реплики. Помимо проверок replica она проверяет отставание репликации и возвращает код 200, только если оно меньше заданного значения. Для повышения производительности ключ cluster.last_leader_operation из DCS используется как позиция wal лидера при вычислении отставания реплики. max-lag задаётся в байтах целым числом или понятным человеку значением, например 16kB, 64MB, 1GB.

    • GET /replica?lag=1048576
    • GET /replica?lag=1024kB
    • GET /replica?lag=10MB
    • GET /replica?lag=1GB
  • GET /replica?tag_key1=value1&tag_key2=value2: конечная точка проверки реплики. Дополнительно проверяет пользовательские теги key1 и key2 и их значения в разделе tags конфигурации yaml. Если тег не определён для экземпляра или его значение не совпадает со значением запроса, возвращается код HTTP 503.

    В следующих запросах проверяется состояние leader или standby-leader, поэтому Patroni игнорирует все пользовательские теги.

    • GET /?tag_key1=value1&tag_key2=value2
    • GET /leader?tag_key1=value1&tag_key2=value2
    • GET /primary?tag_key1=value1&tag_key2=value2
    • GET /read-write?tag_key1=value1&tag_key2=value2
    • GET /standby_leader?tag_key1=value1&tag_key2=value2
    • GET /standby-leader?tag_key1=value1&tag_key2=value2
  • GET /read-only: аналогична предыдущей конечной точке, но также включает первичный сервер.

  • GET /synchronous или GET /sync: возвращает код HTTP 200, только когда узел Patroni работает как синхронный резервный сервер.

  • GET /read-only-sync: аналогична предыдущей конечной точке, но также включает первичный сервер.

  • GET /quorum: возвращает код HTTP 200, только когда этот узел Patroni указан как узел кворума в synchronous_standby_names первичного сервера.

  • GET /read-only-quorum: аналогична предыдущей конечной точке, но также включает первичный сервер.

  • GET /asynchronous или GET /async: возвращает код HTTP 200, только когда узел Patroni работает как асинхронный резервный сервер.

  • GET /asynchronous?lag=<max-lag> или GET /async?lag=<max-lag>: конечная точка проверки асинхронного резервного сервера. Помимо проверок asynchronous или async она проверяет отставание репликации и возвращает код 200, только если оно меньше заданного значения. Для повышения производительности ключ cluster.last_leader_operation из DCS используется как позиция wal лидера при вычислении отставания реплики. max-lag задаётся в байтах целым числом или понятным человеку значением, например 16kB, 64MB, 1GB.

    • GET /async?lag=1048576
    • GET /async?lag=1024kB
    • GET /async?lag=10MB
    • GET /async?lag=1GB
  • GET /health: возвращает код HTTP 200, только когда PostgreSQL запущен и работает.

  • GET /liveness: возвращает код HTTP 200, если цикл сигналов активности Patroni работает правильно, и 503, если последняя итерация на первичном сервере была более ttl секунд назад или более 2*ttl назад на реплике. Можно использовать для livenessProbe.

  • GET /readiness?lag=<max-lag>&mode=apply|write: возвращает код HTTP 200, когда узел Patroni является лидером либо когда PostgreSQL запущен, реплицируется и не слишком отстаёт от лидера. Параметр lag задаёт допустимое отставание резервного сервера и по умолчанию равен maximum_lag_on_failover. Lag можно указать в байтах или понятных человеку значениях, например 16kB, 64MB или 1GB. Mode определяет, должен ли WAL быть воспроизведён (apply) или только получен (write). По умолчанию используется apply.

    При использовании как readinessProbe Kubernetes конечная точка допускает готовность недавно запущенных подов только после того, как они догнали лидера. В сочетании с PodDisruptionBudget это защищает от слишком раннего завершения лидера при скользящем перезапуске узлов. Кроме того, не успевающие за репликацией реплики не обслуживают трафик только для чтения. Конечную точку можно использовать для readinessProbe, когда конечные точки Kubernetes нельзя применять для выборов лидера (OpenShift).

Конечная точка liveness очень легковесна и не выполняет SQL. Проверки следует настроить так, чтобы они начинали завершаться ошибкой примерно к моменту истечения ключа лидера. При значении ttl по умолчанию 30s пример выглядит так:

readinessProbe:
  httpGet:
    scheme: HTTP
    path: /readiness
    port: 8008
  initialDelaySeconds: 3
  periodSeconds: 10
  timeoutSeconds: 5
  successThreshold: 1
  failureThreshold: 3
livenessProbe:
  httpGet:
    scheme: HTTP
    path: /liveness
    port: 8008
  initialDelaySeconds: 3
  periodSeconds: 10
  timeoutSeconds: 5
  successThreshold: 1
  failureThreshold: 3

Конечная точка мониторинга

Patroni использует GET /patroni при выборе лидера. Её также может использовать система мониторинга. Создаваемый этой конечной точкой документ JSON имеет ту же структуру, что и документы конечных точек проверки работоспособности.

Пример: исправный кластер

$ curl -s http://localhost:8008/patroni | jq .
{
  "state": "running",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "role": "primary",
  "server_version": 160004,
  "xlog": {
    "location": 67395656
  },
  "timeline": 1,
  "replication": [
    {
      "usename": "replicator",
      "application_name": "patroni2",
      "client_addr": "10.89.0.6",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    },
    {
      "usename": "replicator",
      "application_name": "patroni3",
      "client_addr": "10.89.0.2",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    }
  ],
  "dcs_last_seen": 1692356718,
  "tags": {
    "clonefrom": true
  },
  "database_system_identifier": "7268616322854375442",
  "patroni": {
    "version": "4.0.0",
    "scope": "demo",
    "name": "patroni1"
  }
}

Пример: кластер без блокировки

$ curl -s http://localhost:8008/patroni  | jq .
{
  "state": "running",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "role": "replica",
  "server_version": 160004,
  "xlog": {
    "received_location": 67419744,
    "replayed_location": 67419744,
    "replayed_timestamp": null,
    "paused": false
  },
  "timeline": 1,
  "replication": [
    {
      "usename": "replicator",
      "application_name": "patroni2",
      "client_addr": "10.89.0.6",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    },
    {
      "usename": "replicator",
      "application_name": "patroni3",
      "client_addr": "10.89.0.2",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    }
  ],
  "cluster_unlocked": true,
  "dcs_last_seen": 1692356928,
  "tags": {
    "clonefrom": true
  },
  "database_system_identifier": "7268616322854375442",
  "patroni": {
    "version": "4.0.0",
    "scope": "demo",
    "name": "patroni1"
  }
}

Пример: кластер без блокировки с включённым отказоустойчивым режимом DCS

$ curl -s http://localhost:8008/patroni  | jq .
{
  "state": "running",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "role": "replica",
  "server_version": 160004,
  "xlog": {
    "location": 67420024
  },
  "timeline": 1,
  "replication": [
    {
      "usename": "replicator",
      "application_name": "patroni2",
      "client_addr": "10.89.0.6",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    },
    {
      "usename": "replicator",
      "application_name": "patroni3",
      "client_addr": "10.89.0.2",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    }
  ],
  "cluster_unlocked": true,
  "failsafe_mode_is_active": true,
  "dcs_last_seen": 1692356928,
  "tags": {
    "clonefrom": true
  },
  "database_system_identifier": "7268616322854375442",
  "patroni": {
    "version": "4.0.0",
    "scope": "demo",
    "name": "patroni1"
  }
}

Пример: кластер с включённым режимом паузы

$ curl -s http://localhost:8008/patroni  | jq .
{
  "state": "running",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "role": "replica",
  "server_version": 160004,
  "xlog": {
    "location": 67420024
  },
  "timeline": 1,
  "replication": [
    {
      "usename": "replicator",
      "application_name": "patroni2",
      "client_addr": "10.89.0.6",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    },
    {
      "usename": "replicator",
      "application_name": "patroni3",
      "client_addr": "10.89.0.2",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    }
  ],
  "pause": true,
  "dcs_last_seen": 1724874295,
  "tags": {
    "clonefrom": true
  },
  "database_system_identifier": "7268616322854375442",
  "patroni": {
    "version": "4.0.0",
    "scope": "demo",
    "name": "patroni1"
  }
}

Получите метрики Patroni в формате Prometheus через конечную точку GET /metrics.

$ curl http://localhost:8008/metrics

# HELP patroni_version Patroni semver without periods. \
# TYPE patroni_version gauge
patroni_version{scope="batman",name="patroni1"} 040000
# HELP patroni_postgres_running Value is 1 if Postgres is running, 0 otherwise.
# TYPE patroni_postgres_running gauge
patroni_postgres_running{scope="batman",name="patroni1"} 1
# HELP patroni_postmaster_start_time Epoch seconds since Postgres started.
# TYPE patroni_postmaster_start_time gauge
patroni_postmaster_start_time{scope="batman",name="patroni1"} 1724873966.352526
# HELP patroni_primary Value is 1 if this node is the leader, 0 otherwise.
# TYPE patroni_primary gauge
patroni_primary{scope="batman",name="patroni1"} 1
# HELP patroni_xlog_location Current location of the Postgres transaction log, 0 if this node is not the leader.
# TYPE patroni_xlog_location counter
patroni_xlog_location{scope="batman",name="patroni1"} 22320573386952
# HELP patroni_standby_leader Value is 1 if this node is the standby_leader, 0 otherwise.
# TYPE patroni_standby_leader gauge
patroni_standby_leader{scope="batman",name="patroni1"} 0
# HELP patroni_replica Value is 1 if this node is a replica, 0 otherwise.
# TYPE patroni_replica gauge
patroni_replica{scope="batman",name="patroni1"} 0
# HELP patroni_sync_standby Value is 1 if this node is a sync standby replica, 0 otherwise.
# TYPE patroni_sync_standby gauge
patroni_sync_standby{scope="batman",name="patroni1"} 0
# HELP patroni_quorum_standby Value is 1 if this node is a quorum standby replica, 0 otherwise.
# TYPE patroni_quorum_standby gauge
patroni_quorum_standby{scope="batman",name="patroni1"} 0
# HELP patroni_xlog_received_location Current location of the received Postgres transaction log, 0 if this node is not a replica.
# TYPE patroni_xlog_received_location counter
patroni_xlog_received_location{scope="batman",name="patroni1"} 0
# HELP patroni_xlog_replayed_location Current location of the replayed Postgres transaction log, 0 if this node is not a replica.
# TYPE patroni_xlog_replayed_location counter
patroni_xlog_replayed_location{scope="batman",name="patroni1"} 0
# HELP patroni_xlog_replayed_timestamp Current timestamp of the replayed Postgres transaction log, 0 if null.
# TYPE patroni_xlog_replayed_timestamp gauge
patroni_xlog_replayed_timestamp{scope="batman",name="patroni1"} 0
# HELP patroni_xlog_paused Value is 1 if the Postgres xlog is paused, 0 otherwise.
# TYPE patroni_xlog_paused gauge
patroni_xlog_paused{scope="batman",name="patroni1"} 0
# HELP patroni_postgres_streaming Value is 1 if Postgres is streaming, 0 otherwise.
# TYPE patroni_postgres_streaming gauge
patroni_postgres_streaming{scope="batman",name="patroni1"} 1
# HELP patroni_postgres_in_archive_recovery Value is 1 if Postgres is replicating from archive, 0 otherwise.
# TYPE patroni_postgres_in_archive_recovery gauge
patroni_postgres_in_archive_recovery{scope="batman",name="patroni1"} 0
# HELP patroni_postgres_server_version Version of Postgres (if running), 0 otherwise.
# TYPE patroni_postgres_server_version gauge
patroni_postgres_server_version{scope="batman",name="patroni1"} 160004
# HELP patroni_cluster_unlocked Value is 1 if the cluster is unlocked, 0 if locked.
# TYPE patroni_cluster_unlocked gauge
patroni_cluster_unlocked{scope="batman",name="patroni1"} 0
# HELP patroni_failsafe_mode_is_active Value is 1 if failsafe mode is active, 0 otherwise.
# TYPE patroni_failsafe_mode_is_active gauge
patroni_failsafe_mode_is_active{scope="batman",name="patroni1"} 0
# HELP patroni_failsafe_mode_enabled Value is 1 if failsafe_mode is enabled, 0 otherwise.
# TYPE patroni_failsafe_mode_enabled gauge
patroni_failsafe_mode_enabled{scope="batman",name="patroni1"} 0
# HELP patroni_failsafe_member Value is 1 if this node is a member of failsafe, 0 otherwise.
# TYPE patroni_failsafe_member gauge
patroni_failsafe_member{scope="batman",name="patroni1"} 0
# HELP patroni_postgres_timeline Postgres timeline of this node (if running), 0 otherwise.
# TYPE patroni_postgres_timeline gauge
patroni_postgres_timeline{scope="batman",name="patroni1"} 24
# HELP patroni_dcs_last_seen Epoch timestamp when DCS was last contacted successfully by Patroni.
# TYPE patroni_dcs_last_seen gauge
patroni_dcs_last_seen{scope="batman",name="patroni1"} 1724874235
# HELP patroni_pending_restart Value is 1 if the node needs a restart, 0 otherwise.
# TYPE patroni_pending_restart gauge
patroni_pending_restart{scope="batman",name="patroni1"} 1
# HELP patroni_is_paused Value is 1 if auto failover is disabled, 0 otherwise.
# TYPE patroni_is_paused gauge
patroni_is_paused{scope="batman",name="patroni1"} 1
# HELP patroni_postgres_state Numeric representation of Postgres state.
# Values: 0=initdb, 1=initdb_failed, 2=custom_bootstrap, 3=custom_bootstrap_failed, 4=creating_replica, 5=running, 6=starting, 7=bootstrap_starting, 8=start_failed, 9=restarting, 10=restart_failed, 11=stopping, 12=stopped, 13=stop_failed, 14=crashed
# TYPE patroni_postgres_state gauge
patroni_postgres_state{scope="batman",name="patroni1"} 5
# HELP patroni_failover_priority Failover priority of this node.
# TYPE patroni_failover_priority gauge
patroni_failover_priority{scope="batman",name="patroni1"} 1

Значения состояния PostgreSQL

Метрика patroni_postgres_state предоставляет числовое представление текущего состояния экземпляра PostgreSQL. Это полезно системам мониторинга и оповещений, отслеживающим изменения состояния во времени. Числовые значения создаются статическим методом PostgresqlState.get_metrics_description().

ЗначениеИмя состоянияОписание
0initdbИнициализация нового кластера
1initdb_failedОшибка инициализации нового кластера
2custom_bootstrapВыполнение пользовательского сценария инициализации
3custom_bootstrap_failedОшибка пользовательского сценария инициализации
4creating_replicaСоздание реплики с первичного сервера
5runningPostgreSQL работает нормально
6startingPostgreSQL запускается
7bootstrap_startingЗапуск после пользовательской инициализации
8start_failedОшибка запуска PostgreSQL
9restartingPostgreSQL перезапускается
10restart_failedОшибка перезапуска PostgreSQL
11stoppingPostgreSQL останавливается
12stoppedPostgreSQL остановлен
13stop_failedОшибка остановки PostgreSQL
14crashedPostgreSQL аварийно завершился

Значения состояния PostgreSQL

Примечание

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


Конечные точки состояния кластера

  • Конечная точка GET /cluster создаёт документ JSON с текущей топологией и состоянием кластера:
$ curl -s http://localhost:8008/cluster | jq .
{
  "members": [
    {
      "name": "patroni1",
      "role": "leader",
      "state": "running",
      "api_url": "http://10.89.0.4:8008/patroni",
      "host": "10.89.0.4",
      "port": 5432,
      "timeline": 5,
      "tags": {
        "clonefrom": true
      }
    },
    {
      "name": "patroni2",
      "role": "replica",
      "state": "streaming",
      "api_url": "http://10.89.0.6:8008/patroni",
      "host": "10.89.0.6",
      "port": 5433,
      "timeline": 5,
      "tags": {
        "clonefrom": true
      },
      "receive_lag": 0,
      "receive_lsn": "0/4000060",
      "replay_lag": 0,
      "replay_lsn": "0/4000060",
      "lag": 0,
      "lsn": "0/4000060"
    }
  ],
  "scope": "demo",
  "scheduled_switchover": {
    "at": "2023-09-24T10:36:00+02:00",
    "from": "patroni1",
    "to": "patroni3"
  }
}
  • Конечная точка GET /history показывает историю плановых и аварийных переключений кластера. Формат очень похож на содержимое файлов истории в каталоге pg_wal; единственное отличие — поле времени создания новой временной шкалы.
$ curl -s http://localhost:8008/history | jq .
[
  [
    1,
    25623960,
    "no recovery target specified",
    "2019-09-23T16:57:57+02:00"
  ],
  [
    2,
    25624344,
    "no recovery target specified",
    "2019-09-24T09:22:33+02:00"
  ],
  [
    3,
    25624752,
    "no recovery target specified",
    "2019-09-24T09:26:15+02:00"
  ],
  [
    4,
    50331856,
    "no recovery target specified",
    "2019-09-24T09:35:52+02:00"
  ]
]


Конечная точка конфигурации

GET /config: получить текущую версию динамической конфигурации:

$ curl -s http://localhost:8008/config | jq .
{
  "ttl": 30,
  "loop_wait": 10,
  "retry_timeout": 10,
  "maximum_lag_on_failover": 1048576,
  "postgresql": {
    "use_slots": true,
    "use_pg_rewind": true,
    "parameters": {
      "hot_standby": "on",
      "wal_level": "hot_standby",
      "max_wal_senders": 5,
      "max_replication_slots": 5,
      "max_connections": "100"
    }
  }
}

PATCH /config: изменить существующую конфигурацию.

$ curl -s -XPATCH -d \
    '{"loop_wait":5,"ttl":20,"postgresql":{"parameters":{"max_connections":"101"}}}' \
    http://localhost:8008/config | jq .
{
  "ttl": 20,
  "loop_wait": 5,
  "maximum_lag_on_failover": 1048576,
  "retry_timeout": 10,
  "postgresql": {
    "use_slots": true,
    "use_pg_rewind": true,
    "parameters": {
      "hot_standby": "on",
      "wal_level": "hot_standby",
      "max_wal_senders": 5,
      "max_replication_slots": 5,
      "max_connections": "101"
    }
  }
}

Приведённый вызов REST API изменяет существующую конфигурацию и возвращает новую.

Проверим, что узел обработал конфигурацию. Сначала он должен начать выводить строки журнала каждые 5 секунд (loop_wait=5). Изменение “max_connections” требует перезапуска, поэтому должен появиться флаг “pending_restart”:

$ curl -s http://localhost:8008/patroni | jq .
{
  "database_system_identifier": "6287881213849985952",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "xlog": {
    "location": 2197818976
  },
  "timeline": 1,
  "dcs_last_seen": 1724874545,
  "database_system_identifier": "7408277255830290455",
  "pending_restart": true,
  "pending_restart_reason": {
    "max_connections": {
      "old_value": "100",
      "new_value": "101"
    }
  },
  "patroni": {
    "version": "4.0.0",
    "scope": "batman",
    "name": "patroni1"
  },
  "state": "running",
  "role": "primary",
  "server_version": 160004
}

Удаление параметров:

Чтобы удалить или сбросить параметр, измените его на null:

$ curl -s -XPATCH -d \
    '{"postgresql":{"parameters":{"max_connections":null}}}' \
    http://localhost:8008/config | jq .
{
  "ttl": 20,
  "loop_wait": 5,
  "retry_timeout": 10,
  "maximum_lag_on_failover": 1048576,
  "postgresql": {
    "use_slots": true,
    "use_pg_rewind": true,
    "parameters": {
      "hot_standby": "on",
      "unix_socket_directories": ".",
      "wal_level": "hot_standby",
      "max_wal_senders": 5,
      "max_replication_slots": 5
    }
  }
}

Приведённый вызов удаляет postgresql.parameters.max_connections из динамической конфигурации.

PUT /config: также можно безусловно полностью перезаписать существующую динамическую конфигурацию:

$ curl -s -XPUT -d \
    '{"maximum_lag_on_failover":1048576,"retry_timeout":10,"postgresql":{"use_slots":true,"use_pg_rewind":true,"parameters":{"hot_standby":"on","wal_level":"hot_standby","unix_socket_directories":".","max_wal_senders":5}},"loop_wait":3,"ttl":20}' \
    http://localhost:8008/config | jq .
{
  "ttl": 20,
  "maximum_lag_on_failover": 1048576,
  "retry_timeout": 10,
  "postgresql": {
    "use_slots": true,
    "parameters": {
      "hot_standby": "on",
      "unix_socket_directories": ".",
      "wal_level": "hot_standby",
      "max_wal_senders": 5
    },
    "use_pg_rewind": true
  },
  "loop_wait": 3
}

Конечные точки планового и аварийного переключения

Плановое переключение

Конечная точка /switchover работает только в исправном кластере с лидером. Она также позволяет запланировать переключение на заданное время.

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

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

В зависимости от ситуации запросы возвращают разные коды и тела HTTP. Код 200 означает успешное завершение планового или аварийного переключения. При успешном планировании Patroni возвращает код HTTP 202. При ошибке возвращается один из кодов 400, 412 или 503 с подробностями в теле ответа.

DELETE /switchover удаляет текущее запланированное переключение.

Пример: переключение на любой исправный резервный сервер

$ curl -s http://localhost:8008/switchover -XPOST -d '{"leader":"postgresql1"}'
Successfully switched over to "postgresql2"

Пример: переключение на определённый узел

$ curl -s http://localhost:8008/switchover -XPOST -d \
    '{"leader":"postgresql1","candidate":"postgresql2"}'
Successfully switched over to "postgresql2"

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

$ curl -s http://localhost:8008/switchover -XPOST -d \
    '{"leader":"postgresql0","scheduled_at":"2019-09-24T12:00+00"}'
Switchover scheduled

Аварийное переключение

Конечная точка /failover выполняет ручное аварийное переключение при отсутствии исправных узлов, например на асинхронный резервный сервер, если все синхронные недостаточно исправны для повышения. Однако отсутствие лидера не является обязательным условием: аварийное переключение можно запустить и в исправном кластере.

В теле JSON запроса POST необходимо указать поле candidate. Если задано поле leader, вместо этого запускается плановое переключение.

Пример:

$ curl -s http://localhost:8008/failover -XPOST -d '{"candidate":"postgresql1"}'
Successfully failed over to "postgresql1"
Предупреждение

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

Конечные точки POST /switchover и POST /failover используются соответственно patronictl_switchover и patronictl_failover .

DELETE /switchover используется командой patronictl flush cluster-name switchover .

Аварийное переключениеПлановое переключение
Требуется указать лидеранетда
Требуется указать кандидатаданет
Можно выполнить в паузедада (только на заданного кандидата)
Можно запланироватьнетда (если кластер не на паузе)

Сравнение аварийного и планового переключения

Исправный резервный сервер

Чтобы участвовать в выборах лидера при плановом переключении или стать лидером как кандидат аварийного либо планового переключения, участник должен пройти несколько проверок:

  • быть доступным через API Patroni;
  • не иметь тег nofailover, равный true;
  • иметь полностью работоспособный сторожевой таймер, если того требует конфигурация;
  • при плановом переключении в исправном кластере или автоматическом аварийном переключении не превышать максимальное отставание репликации (параметр конфигурации maximum_lag_on_failover);
  • при плановом переключении в исправном кластере или автоматическом аварийном переключении не иметь номер временной шкалы меньше шкалы кластера, если параметр конфигурации check_timeline равен true;
  • в синхронном режиме :
    • при плановом переключении с кандидатом или без него быть перечисленным среди участников ключа /sync;
    • при аварийном переключении как в исправном, так и в неисправном кластере эта проверка пропускается.
Предупреждение

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


Конечная точка перезапуска

  • POST /restart: перезапускает Postgres на определённом узле вызовом POST /restart. В теле JSON запроса POST можно необязательно указать условия перезапуска:
    • restart_pending: логическое значение; при true Patroni перезапускает PostgreSQL только при ожидающем перезапуске для применения изменений конфигурации.
    • role: выполнять перезапуск, только если текущая роль узла совпадает с ролью запроса POST.
    • postgres_version: выполнять перезапуск, только если текущая версия postgres меньше указанной в запросе POST.
    • timeout: время ожидания начала приёма соединений PostgreSQL. Переопределяет primary_start_timeout.
    • schedule: временная метка с часовым поясом для планирования перезапуска в будущем.
  • DELETE /restart: удаляет запланированный перезапуск

Конечные точки POST /restart и DELETE /restart используются соответственно patronictl_restart и patronictl flush cluster-name restart .


Конечная точка перезагрузки конфигурации

Вызов POST /reload требует от Patroni повторно прочитать и применить файл конфигурации. Это эквивалентно отправке процессу Patroni сигнала SIGHUP. Если изменены параметры Postgres, требующие перезапуска, например shared_buffers, Postgres всё равно нужно явно перезапустить через конечную точку POST /restart или patronictl_restart .

Конечная точка перезагрузки используется patronictl_reload .


Конечная точка повторной инициализации

POST /reinitialize: повторно инициализирует каталог данных PostgreSQL на заданном узле. Разрешено выполнять только на репликах. Вызов удаляет каталог данных и запускает pg_basebackup либо другой метод создания реплики .

Вызов может завершиться ошибкой, если Patroni циклически пытается восстановить или перезапустить отказавший Postgres. Чтобы обойти проблему, укажите {"force":true} в теле запроса.

В теле запроса можно указать {“from-leader”:true}, чтобы получить basebackup непосредственно с узла-лидера. Это полезно при повторной инициализации после отказа всех узлов-реплик.

Конечная точка повторной инициализации используется patronictl_reinit .

5 - patronictl

Справочник по конфигурации, синтаксису и подкомандам patronictl.

Patroni предоставляет интерфейс командной строки patronictl , предназначенный главным образом для взаимодействия с REST API Patroni и DCS. Он упрощает операции с кластером и удобен как людям, так и сценариям.


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

patronictl использует 3 раздела конфигурации:

  • ctl: способ аутентификации в REST API Patroni и проверки подлинности сервера. Подробнее см. параметры ctl ;
  • restapi: способ аутентификации в REST API Patroni и проверки подлинности сервера. Используется, только если конфигурации ctl недостаточно. patronictl в основном использует раздел restapi.authentication, если отсутствует ctl.authentication, и параметр restapi.cafile, если отсутствует ctl.cacert. Подробнее см. параметры REST API ;
  • DCS, например etcd: способ подключения и аутентификации в DCS, используемом Patroni.

Эти параметры можно получить из переменных окружения или файла конфигурации. Способы их задания описаны в соответствующих разделах Параметров конфигурации окружения и Параметров конфигурации YAML .

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

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

  • Mac OS X: ~/Library/Application Support/patroni
  • Mac OS X (POSIX): ~/.patroni
  • Unix: ~/.config/patroni
  • Unix (POSIX): ~/.patroni
  • Windows (roaming): C:\Users\<user>\AppData\Roaming\patroni
  • Windows (not roaming): C:\Users\<user>\AppData\Local\patroni

Поведение можно переопределить одним из способов:

  • задать переменной окружения PATRONICTL_CONFIG_FILE путь к пользовательскому файлу конфигурации;
  • передать путь к пользовательскому файлу в аргументе командной строки -c / --config-file команды patronictl .
Примечание

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


Использование

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

Перед рассмотрением подкоманд patronictl обратите внимание на аргументы командной строки самой patronictl :

-c / --config-file
Как описано выше, задаёт путь к файлу конфигурации patronictl .

-d / --dcs-url / --dcs
Задаёт строку подключения к DCS, используемому Patroni.

Аргумент переопределяет параметры DCS и namespace из конфигурации patronictl либо задаёт их, если они отсутствуют.

Значение должно иметь формат DCS://HOST:PORT/NAMESPACE. Например, etcd3://localhost:2379/service подключается к etcd v3 на localhost, где кластер Patroni хранится в пространстве имён service. Отсутствующие части заменяются значениями конфигурации или значениями по умолчанию.

-k / --insecure
Флаг пропуска проверки сертификата SSL сервера REST API.

Синтаксис запуска команды patronictl :

patronictl [ { -c | --config-file } CONFIG_FILE ]
  [ { -d | --dcs-url | --dcs } DCS_URL ] 
  [ { -k | --insecure } ]
  SUBCOMMAND
Примечание

В описании синтаксиса используются следующие правила:

  • Параметры в квадратных скобках необязательны;
  • Параметры в фигурных скобках означают выбор одного из набора;
  • Параметры с [, ... ] можно указывать несколько раз;
  • Элементы в верхнем регистре — литералы, которым нужно передать значение.

Тот же синтаксис применяется к подкомандам patronictl в следующих подразделах. Синтаксис каждой подкоманды следует рассматривать как замену SUBCOMMAND в описании выше.

В следующих подразделах описаны все команды patronictl . В примерах используются файлы конфигурации из репозитория Patroni на GitHub: postgres0.yml, postgres1.yml и postgres2.yml.

patronictl demote-cluster

Синтаксис

demote-cluster
  [ CLUSTER_NAME ]
  [ --host HOST ]
  [ --port PORT ]
  [ --restore-command RESTORE_COMMAND ]
  [ --primary-slot-name PRIMARY_SLOT_NAME ]
  [ --force ]

Описание

patronictl demote-cluster преобразует обычный кластер Patroni в резервный кластер .

Команда добавляет в динамическую конфигурацию раздел standby_cluster, сформированный из параметров подключения к удалённому первичному серверу, а затем ждёт запуска лидера в роли резервного лидера. Перед изменением она выводит текущую топологию кластера и запрашивает подтверждение, если не используется --force.

Необходимо указать хотя бы один из параметров --host, --port или --restore-command.

Параметры

CLUSTER_NAME: имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--host: адрес удалённого узла.

--port: порт удалённого узла.

--restore-command: команда восстановления записей WAL с удалённого первичного сервера.

--primary-slot-name: имя слота репликации на удалённом узле.

--force: флаг пропуска подтверждений при понижении кластера.

Полезно для сценариев.

Примеры

Преобразовать кластер в резервный, следующий за удалённой конечной точкой первичного сервера:

$ patronictl -c postgres0.yml demote-cluster batman --host 192.0.2.10 --port 5432 --primary-slot-name batman --force

patronictl dsn

Синтаксис

dsn
  [ CLUSTER_NAME ]
  [ { { -r | --role } { leader | primary | standby-leader | replica | standby | any } | { -m | --member } MEMBER_NAME } ]
  [ --group CITUS_GROUP ]

Описание

patronictl dsn получает строку подключения к одному участнику кластера Patroni.

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

Параметры

CLUSTER_NAME: имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

-r / --role
Выбрать участника с заданной ролью.

Допустимые роли:

  • leader: лидер обычного или резервного кластера Patroni; либо
  • primary: лидер обычного кластера Patroni; либо
  • standby-leader: лидер резервного кластера Patroni; либо
  • replica: реплика кластера Patroni; либо
  • standby: то же, что replica; либо
  • any: любая роль. Эквивалентно отсутствию параметра; либо

-m / --member
Выбрать участника кластера с заданным именем.

MEMBER_NAME — имя участника.

--group
Выбрать участника заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

Примеры

Получить DSN первичного узла:

$ patronictl -c postgres0.yml dsn batman -r primary
host=127.0.0.1 port=5432

Получить DSN узла postgresql1:

$ patronictl -c postgres0.yml dsn batman --member postgresql1
host=127.0.0.1 port=5433

patronictl edit-config

Синтаксис

edit-config
  [ CLUSTER_NAME ]
  [ --group CITUS_GROUP ]
  [ { -q | --quiet } ]
  [ { -s | --set } CONFIG="VALUE" [, ... ] ]
  [ { -p | --pg } PG_CONFIG="PG_VALUE" [, ... ] ]
  [ { --apply | --replace } CONFIG_FILE ]
  [ --force ]

Описание

patronictl edit-config изменяет динамическую конфигурацию кластера и обновляет DCS.

Примечание

При вызове из TTY команда пытается показать различия динамической конфигурации через средство постраничного просмотра. По умолчанию используется less или more. Для другого средства задайте переменной окружения PAGER нужное значение.

Параметры

CLUSTER_NAME: имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Изменить динамическую конфигурацию заданной группы Citus.

Если не задано, patronictl попытается получить значение из citus.group, если оно существует.

CITUS_GROUP — идентификатор группы Citus.

-q / --quiet
Флаг пропуска показа различий конфигурации.

-s / --set
Задать указанному параметру динамической конфигурации указанное значение.

CONFIG — путь динамической конфигурации в дереве YAML, уровни которого соединены ..

VALUE — значение CONFIG. Если оно равно null, CONFIG удаляется из динамической конфигурации.

-p / --pg
Задать указанному динамическому параметру Postgres указанное значение.

Это сокращение для --s / --set, где к CONFIG добавляется префикс postgresql.parameters..

PG_CONFIG — имя задаваемого параметра Postgres.

PG_VALUE — значение PG_CONFIG. Если оно равно null, PG_CONFIG удаляется из динамической конфигурации.

--apply
Применить динамическую конфигурацию из заданного файла.

Аналогично нескольким параметрам -s / --set, по одному для каждого параметра из CONFIG_FILE.

CONFIG_FILE — путь к файлу применяемой динамической конфигурации в формате YAML. Для чтения из stdin используйте -.

--replace
Заменить динамическую конфигурацию в DCS конфигурацией из заданного файла.

CONFIG_FILE — путь к файлу новой динамической конфигурации в формате YAML. Для чтения из stdin используйте -.

--force
Флаг пропуска подтверждений при изменении динамической конфигурации.

Полезно для сценариев.

Примеры

Изменить GUC Postgres max_connections:

patronictl -c postgres0.yml edit-config batman --pg max_connections="150" --force
---
+++
@@ -1,6 +1,8 @@
loop_wait: 10
maximum_lag_on_failover: 1048576
postgresql:
+  parameters:
+    max_connections: 150
  pg_hba:
  - host replication replicator 127.0.0.1/32 md5
  - host all all 0.0.0.0/0 md5

Configuration changed

Изменить параметры loop_wait и ttl:

patronictl -c postgres0.yml edit-config batman --set loop_wait="15" --set ttl="45" --force
---
+++
@@ -1,4 +1,4 @@
-loop_wait: 10
+loop_wait: 15
maximum_lag_on_failover: 1048576
postgresql:
  pg_hba:
@@ -6,4 +6,4 @@
  - host all all 0.0.0.0/0 md5
  use_pg_rewind: true
retry_timeout: 10
-ttl: 30
+ttl: 45

Configuration changed

Удалить maximum_lag_on_failover из динамической конфигурации:

patronictl -c postgres0.yml edit-config batman --set maximum_lag_on_failover="null" --force
---
+++
@@ -1,5 +1,4 @@
loop_wait: 10
-maximum_lag_on_failover: 1048576
postgresql:
  pg_hba:
  - host replication replicator 127.0.0.1/32 md5

Configuration changed

patronictl failover

Синтаксис

failover
  [ CLUSTER_NAME ]
  [ --group CITUS_GROUP ]
  --candidate CANDIDATE_NAME
  [ --force ]

Описание

patronictl failover выполняет ручное аварийное переключение в кластере.

Команда предназначена для неисправного кластера, например когда:

  • отсутствует лидер; либо
  • в синхронном кластере нет доступного синхронного резервного сервера.

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

Примечание

patronictl failover можно запустить и в исправном кластере, однако в таком случае рекомендуется patronictl switchover.

Предупреждение

Аварийное переключение может привести к потере данных в зависимости от отставания повышаемой реплики от первичного сервера.

Параметры

CLUSTER_NAME: имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Выполнить аварийное переключение в заданной группе Citus.

CITUS_GROUP — идентификатор группы Citus.

--candidate
Узел, повышаемый при аварийном переключении.

CANDIDATE_NAME — имя повышаемого узла.

--force
Флаг пропуска подтверждений при аварийном переключении.

Полезно для сценариев.

Примеры

Выполнить аварийное переключение на узел postgresql2:

$ patronictl -c postgres0.yml failover batman --candidate postgresql2 --force
Current cluster topology
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  3 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  3 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  3 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
2023-09-12 11:52:27.50978 Successfully failed over to "postgresql2"
+ Cluster: batman (7277694203142172922) -+---------+----+-------------+---------+------------+---------+
| Member      | Host           | Role    | State   | TL | Receive LSN |     Lag | Replay LSN |     Lag |
+-------------+----------------+---------+---------+----+-------------+---------+------------+---------+
| postgresql0 | 127.0.0.1:5432 | Replica | stopped |    |     unknown | unknown |    unknown | unknown |
| postgresql1 | 127.0.0.1:5433 | Replica | running |  3 |   0/4000188 |       0 |  0/4000188 |       0 |
| postgresql2 | 127.0.0.1:5434 | Leader  | running |  3 |             |         |            |         |
+-------------+----------------+---------+---------+----+-------------+---------+------------+---------+

patronictl flush

Синтаксис

flush
  CLUSTER_NAME
  [ MEMBER_NAME [, ... ] ]
  { restart | switchover }
  [ --group CITUS_GROUP ]
  [ { -r | --role } { leader | primary | standby-leader | replica | standby | any } ]
  [ --force ]

Описание

patronictl flush удаляет запланированные события, если они есть.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

MEMBER_NAME
Удалить запланированные события заданных участников Patroni.

Можно указать несколько участников. Если участники не заданы, рассматриваются все.

Примечание

Используется только при удалении запланированных перезапусков.

restart
Удалить запланированные перезапуски.

switchover
Удалить запланированное плановое переключение.

--group
Удалить запланированные события заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

-r / --role
Удалить запланированные события участников с заданной ролью.

Допустимые роли:

  • leader: лидер обычного или резервного кластера Patroni; либо
  • primary: лидер обычного кластера Patroni; либо
  • standby-leader: лидер резервного кластера Patroni; либо
  • replica: реплика кластера Patroni; либо
  • standby: то же, что replica; либо
  • any: любая роль. Эквивалентно отсутствию параметра.
Примечание

Используется только при удалении запланированных перезапусков.

--force
Флаг пропуска подтверждений при удалении событий.

Полезно для сценариев.

Примеры

Удалить запланированное плановое переключение:

$ patronictl -c postgres0.yml flush batman switchover --force
Success: scheduled switchover deleted

Удалить запланированный перезапуск всех резервных узлов:

$ patronictl -c postgres0.yml flush batman restart -r replica --force
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+---------------------------+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag | Scheduled restart         |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+---------------------------+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     | 2025-03-23T18:00:00-03:00 |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/4000400 |   0 |  0/4000400 |   0 | 2025-03-23T18:00:00-03:00 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/4000400 |   0 |  0/4000400 |   0 | 2025-03-23T18:00:00-03:00 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+---------------------------+
Success: flush scheduled restart for member postgresql1
Success: flush scheduled restart for member postgresql2

Удалить запланированный перезапуск узлов postgresql0 и postgresql1:

$ patronictl -c postgres0.yml flush batman postgresql0 postgresql1 restart --force
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+---------------------------+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag | Scheduled restart         |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+---------------------------+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     | 2025-03-23T18:00:00-03:00 |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/4000400 |   0 |  0/4000400 |   0 | 2025-03-23T18:00:00-03:00 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/4000400 |   0 |  0/4000400 |   0 | 2025-03-23T18:00:00-03:00 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+---------------------------+
Success: flush scheduled restart for member postgresql0
Success: flush scheduled restart for member postgresql1

patronictl history

Синтаксис

history
  [ CLUSTER_NAME ]
  [ --group CITUS_GROUP ]
  [ { -f | --format } { pretty | tsv | json | yaml } ]

Описание

patronictl history показывает историю аварийных и плановых переключений кластера, если они были.

Вывод содержит следующие сведения:

TL
Временная шкала Postgres, на которой произошло событие.

LSN
LSN Postgres, на котором произошло событие.

Reason
Причина из файла Postgres .history.

Timestamp
Время события.

New Leader
Участник Patroni, повышенный во время события.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Показать историю событий заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

Если не задано, patronictl попытается получить значение из citus.group, если оно существует.

-f / --format
Способ форматирования списка событий в выводе.

Допустимые форматы:

  • pretty: выводит историю как форматированную таблицу; либо
  • tsv: выводит табличные сведения со столбцами, разделёнными \t; либо
  • json: выводит историю в формате JSON; либо
  • yaml: выводит историю в формате YAML.

По умолчанию используется pretty.

--force
Флаг пропуска подтверждений при удалении событий.

Полезно для сценариев.

Примеры

Показать историю событий:

$ patronictl -c postgres0.yml history batman
+----+----------+------------------------------+----------------------------------+-------------+
| TL |      LSN | Reason                       | Timestamp                        | New Leader  |
+----+----------+------------------------------+----------------------------------+-------------+
|  1 | 24392648 | no recovery target specified | 2023-09-11T22:11:27.125527+00:00 | postgresql0 |
|  2 | 50331864 | no recovery target specified | 2023-09-12T11:34:03.148097+00:00 | postgresql0 |
|  3 | 83886704 | no recovery target specified | 2023-09-12T11:52:26.948134+00:00 | postgresql2 |
|  4 | 83887280 | no recovery target specified | 2023-09-12T11:53:09.620136+00:00 | postgresql0 |
+----+----------+------------------------------+----------------------------------+-------------+

Показать историю событий в формате YAML:

$ patronictl -c postgres0.yml history batman -f yaml
- LSN: 24392648
  New Leader: postgresql0
  Reason: no recovery target specified
  TL: 1
  Timestamp: '2023-09-11T22:11:27.125527+00:00'
- LSN: 50331864
  New Leader: postgresql0
  Reason: no recovery target specified
  TL: 2
  Timestamp: '2023-09-12T11:34:03.148097+00:00'
- LSN: 83886704
  New Leader: postgresql2
  Reason: no recovery target specified
  TL: 3
  Timestamp: '2023-09-12T11:52:26.948134+00:00'
- LSN: 83887280
  New Leader: postgresql0
  Reason: no recovery target specified
  TL: 4
  Timestamp: '2023-09-12T11:53:09.620136+00:00'

patronictl list

Синтаксис

list
  [ CLUSTER_NAME [, ... ] ]
  [ --group CITUS_GROUP ]
  [ { -e | --extended } ]
  [ { -t | --timestamp } ]
  [ { -f | --format } { pretty | tsv | json | yaml } ]
  [ { -W | { -w | --watch } TIME } ]

Описание

patronictl list показывает сведения о кластере Patroni и его участниках.

Вывод содержит следующие сведения:

Cluster
Имя кластера Patroni.

Member
Имя участника Patroni.

Host
Узел, на котором находится участник.

Role
Текущая роль участника.

Возможные значения:

  • Leader: текущий лидер обычного кластера Patroni; либо
  • Standby Leader: текущий лидер резервного кластера Patroni; либо
  • Sync Standby: синхронный резервный сервер кластера Patroni с включённым синхронным режимом; либо
  • Replica: обычный резервный сервер кластера Patroni.

State
Текущее состояние Postgres на участнике Patroni.

Примеры возможных состояний:

  • running: Postgres запущен и работает;
  • streaming: участник является репликой, и Postgres передаёт WAL потоком с первичного узла;
  • in archive recovery: участник является репликой, и Postgres получает WAL из архива;
  • stopped: Postgres остановлен;
  • crashed: Postgres аварийно завершился.

TL
Текущая временная шкала Postgres на участнике Patroni.

Receive LSN
Последняя позиция журнала предзаписи, полученная потоковой репликацией участника и синхронизированная с диском (pg_catalog.pg_last_(xlog|wal)_receive_(location|lsn)()).

Receive Lag
Отставание репликации между позицией участника Receive LSN и вышестоящим узлом в MB.

Replay LSN
Последняя позиция журнала предзаписи, воспроизведённая при восстановлении участника (pg_catalog.pg_last_(xlog|wal)_replay_(location|lsn)()).

Replay Lag
Отставание репликации между позицией участника Replay LSN и вышестоящим узлом в MB.

Кроме того, вывод может содержать:

System identifier
Системный идентификатор Postgres.

Примечание

Показывается в заголовке таблицы.

Только для формата вывода pretty.

Group
Идентификатор группы Citus.

Примечание

Показывается в заголовке таблицы.

Только для кластера Citus.

Pending restart
* означает, что для применения конфигурации Postgres узлу требуется перезапуск. Пустое значение означает, что перезапуск не требуется.

Примечание

Показывается как атрибут участника.

Shown if:

  • При выводе в формате pretty или tsv с включённым расширенным выводом; либо
  • Если узлу требуется перезапуск.

Scheduled restart
Время запланированного перезапуска экземпляра Postgres под управлением участника Patroni. Пустое значение означает отсутствие запланированного перезапуска.

Примечание

Показывается как атрибут участника.

Shown if:

  • При выводе в формате pretty или tsv с включённым расширенным выводом; либо
  • Если у узла есть запланированный перезапуск.

Tags
Содержит теги участника Patroni. Пустое значение означает, что теги не настроены либо имеют значения по умолчанию.

Примечание

Показывается как атрибут участника.

Shown if:

  • При выводе в формате pretty или tsv с включённым расширенным выводом; либо
  • Если у узла есть пользовательские теги или теги по умолчанию с нестандартными значениями.

Scheduled switchover
Время запланированного планового переключения кластера Patroni, если оно есть.

Примечание

Показывается в нижнем колонтитуле таблицы.

Только при наличии запланированного переключения и формате вывода pretty.

Maintenance mode

Мониторинг кластера в настоящее время приостановлен.

Примечание

Показывается в нижнем колонтитуле таблицы.

Только если кластер на паузе и формат вывода — pretty.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Показать сведения об участниках заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

-e / --extended
Показать расширенные сведения.

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

Примечание

Применяется только к форматам вывода pretty и tsv.

-t / --timestamp
Вывести временную метку перед сведениями о кластере и участниках.

-f / --format
Способ форматирования списка событий в выводе.

Допустимые форматы:

  • pretty: выводит историю как форматированную таблицу; либо
  • tsv: выводит табличные сведения со столбцами, разделёнными \t; либо
  • json: выводит историю в формате JSON; либо
  • yaml: выводит историю в формате YAML.

По умолчанию используется pretty.

-W
Автоматически обновлять сведения каждые 2 секунды.

-w / --watch
Автоматически обновлять сведения с заданным интервалом.

TIME — интервал между обновлениями в секундах.

Примеры

Показать сведения о кластере в формате pretty:

$ patronictl -c postgres0.yml list batman
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+

Показать сведения о кластере в формате pretty с расширенными столбцами:

$ patronictl -c postgres0.yml list batman -e
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+-----------------+------------------------+-------------------+------+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag | Pending restart | Pending restart reason | Scheduled restart | Tags |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+-----------------+------------------------+-------------------+------+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     |                 |                        |                   |      |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |                 |                        |                   |      |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |                 |                        |                   |      |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+-----------------+------------------------+-------------------+------+

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

$ patronictl -c postgres0.yml list batman -f yaml -t
2023-09-12 13:30:48
- Cluster: batman
  Host: 127.0.0.1:5432
  Member: postgresql0
  Role: Leader
  State: running
  TL: 5
- Cluster: batman
  Host: 127.0.0.1:5433
  Receive LSN: 0/40004E8
  Receive Lag: 0
  Replay LSN: 0/40004E8
  Replay Lag: 0
  Member: postgresql1
  Role: Replica
  State: streaming
  TL: 5
- Cluster: batman
  Host: 127.0.0.1:5434
  Receive LSN: 0/40004E8
  Receive Lag: 0
  Replay LSN: 0/40004E8
  Replay Lag: 0
  Member: postgresql2
  Role: Replica
  State: streaming
  TL: 5

patronictl pause

Синтаксис

pause
  [ CLUSTER_NAME ]
  [ --group CITUS_GROUP ]
  [ --wait ]

Описание

patronictl pause временно переводит кластер Patroni в режим обслуживания и отключает автоматическое переключение при отказе.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Приостановить заданную группу Citus.

CITUS_GROUP — идентификатор группы Citus.

Если не задано, patronictl попытается получить значение из citus.group, если оно существует.

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

Примеры

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

$ patronictl -c postgres0.yml pause batman --wait
'pause' request sent, waiting until it is recognized by all nodes
Success: cluster management is paused

patronictl promote-cluster

Синтаксис

promote-cluster
  [ CLUSTER_NAME ]
  [ --force ]

Описание

patronictl promote-cluster преобразует резервный кластер в обычный кластер Patroni.

Команда удаляет раздел standby_cluster из динамической конфигурации и ждёт запуска лидера в роли первичного сервера. Перед изменением она выводит текущую топологию кластера и запрашивает подтверждение, если не используется --force.

Параметры

CLUSTER_NAME: имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--force: флаг пропуска подтверждений при повышении кластера.

Полезно для сценариев.

Примеры

Повысить резервный кластер до обычного кластера Patroni:

$ patronictl -c postgres0.yml promote-cluster batman --force

patronictl query

Синтаксис

query
  [ CLUSTER_NAME ]
  [ --group CITUS_GROUP ]
  [ { { -r | --role } { leader | primary | standby-leader | replica | standby | any } | { -m | --member } MEMBER_NAME } ]
  [ { -d | --dbname } DBNAME ]
  [ { -U | --username } USERNAME ]
  [ --password ]
  [ --format { pretty | tsv | json | yaml } ]
  [ { { -f | --file } FILE_NAME | { -c | --command } SQL_COMMAND } ]
  [ --delimiter ]
  [ { -W | { -w | --watch } TIME } ]

Описание

patronictl query выполняет команду или сценарий SQL на участнике кластера Patroni.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Выполнить запрос к заданной группе Citus.

CITUS_GROUP — идентификатор группы Citus.

-r / --role
Выбрать участника с заданной ролью.

Допустимые роли:

  • leader: лидер обычного или резервного кластера Patroni; либо
  • primary: лидер обычного кластера Patroni; либо
  • standby-leader: лидер резервного кластера Patroni; либо
  • replica: реплика кластера Patroni; либо
  • standby: то же, что replica; либо
  • any: любая роль. Эквивалентно отсутствию параметра.

-m / --member
Выбрать участника с заданным именем.

MEMBER_NAME — имя выбираемого участника.

-d / --dbname
База данных для подключения и выполнения запроса.

DBNAME — имя базы данных. Если не задано, по умолчанию используется USERNAME.

-U / --username
Пользователь для подключения к базе данных.

USERNAME — имя пользователя. Если не задано, по умолчанию используется пользователь операционной системы, запустивший patronictl query.

--password
Запросить пароль подключающегося пользователя.

Поскольку Patroni использует libpq, вместо этого можно создать файл ~/.pgpass или задать переменную окружения PGPASSWORD.

--format
Способ форматирования вывода запроса.

Допустимые форматы:

  • pretty: выводит результат как форматированную таблицу; либо
  • tsv: выводит табличные сведения со столбцами, разделёнными \t; либо
  • json: выводит результат в формате JSON; либо
  • yaml: выводит результат в формате YAML.

По умолчанию используется tsv.

-f / --file
Использовать файл как источник команд запросов.

FILE_NAME — путь к исходному файлу.

-c / --command
Выполнить заданную команду SQL.

SQL_COMMAND — выполняемая команда SQL.

--delimiter
Разделитель при выводе в формате tsv; если не задан, используется \t.

-W
Автоматически повторять запрос каждые 2 секунды.

-w / --watch
Автоматически повторять запрос с заданным интервалом.

TIME — интервал между повторами в секундах.

Примеры

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

$ patronictl -c postgres0.yml query batman -U postgres --password -c "SELECT now()"
Password:
now
2023-09-12 18:10:53.228084+00:00

Выполнить команду SQL от пользователя postgres, получив пароль из переменной окружения libpq:

$ PGPASSWORD=patroni patronictl -c postgres0.yml query batman -U postgres -c "SELECT now()"
now
2023-09-12 18:11:37.639500+00:00

Выполнять команду SQL каждые 2 секунды и выводить результат в формате pretty:

$ patronictl -c postgres0.yml query batman -c "SELECT now()" --format pretty -W
+----------------------------------+
| now                              |
+----------------------------------+
| 2023-09-12 18:12:16.716235+00:00 |
+----------------------------------+
+----------------------------------+
| now                              |
+----------------------------------+
| 2023-09-12 18:12:18.732645+00:00 |
+----------------------------------+
+----------------------------------+
| now                              |
+----------------------------------+
| 2023-09-12 18:12:20.750573+00:00 |
+----------------------------------+

Выполнить команду SQL в базе test и вывести результат в формате YAML:

$ patronictl -c postgres0.yml query batman -d test -c "SELECT now() AS column_1, 'test' AS column_2" --format yaml
- column_1: 2023-09-12 18:14:22.052060+00:00
  column_2: test

Выполнить команду SQL на участнике postgresql2:

$ patronictl -c postgres0.yml query batman -m postgresql2 -c "SHOW port"
port
5434

Выполнить команду SQL на любом резервном сервере:

$ patronictl -c postgres0.yml query batman -r replica -c "SHOW port"
port
5433

patronictl reinit

Синтаксис

reinit
  CLUSTER_NAME
  [ MEMBER_NAME [, ... ] ]
  [ --group CITUS_GROUP ]
  [ --wait ]
  [ --force ]
  [ --from-leader ]

Описание

patronictl reinit перестраивает резервный экземпляр Postgres под управлением участника-реплики кластера Patroni.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

MEMBER_NAME
Имя участника-реплики, экземпляр Postgres которого будет перестроен.

Можно указать несколько участников-реплик. Если участники не заданы, команда ничего не делает.

--group
Перестроить участника-реплику заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

--wait
Дождаться завершения повторной инициализации резервных узлов Postgres.

--force
Флаг пропуска подтверждений при перестроении резервных экземпляров Postgres.

--from-leader
Флаг получения basebackup непосредственно с лидера.

Полезно для сценариев.

Примеры

Запросить перестроение всех участников-реплик кластера Patroni и немедленно вернуть управление вызывающей стороне:

$ patronictl -c postgres0.yml reinit batman postgresql1 postgresql2 --force
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Success: reinitialize for member postgresql1
Success: reinitialize for member postgresql2

Запросить перестроение postgresql2 и дождаться завершения:

$ patronictl -c postgres0.yml reinit batman postgresql2 --wait --force
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Success: reinitialize for member postgresql2
Waiting for reinitialize to complete on: postgresql2
Reinitialize is completed on: postgresql2

Запросить перестроение postgresql2 с получением basebackup непосредственно с лидера:

$ patronictl -c postgres0.yml reinit batman postgresql2 --from-leader
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Success: reinitialize for member postgresql2

patronictl reload

Синтаксис

reload
  CLUSTER_NAME
  [ MEMBER_NAME [, ... ] ]
  [ --group CITUS_GROUP ]
  [ { -r | --role } { leader | primary | standby-leader | replica | standby | any } ]
  [ --force ]

Описание

patronictl reload запрашивает перезагрузку локальной конфигурации одного или нескольких участников Patroni.

Она также запускает pg_ctl reload на управляемом экземпляре Postgres, даже если ничего не изменилось.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

MEMBER_NAME
Запросить перезагрузку локальной конфигурации заданных участников Patroni.

Можно указать несколько участников. Если участники не заданы, рассматриваются все.

--group
Запросить перезагрузку участников заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

-r / --role
Выбрать участников с заданной ролью.

Допустимые роли:

  • leader: лидер обычного или резервного кластера Patroni; либо
  • primary: лидер обычного кластера Patroni; либо
  • standby-leader: лидер резервного кластера Patroni; либо
  • replica: реплика кластера Patroni; либо
  • standby: то же, что replica; либо
  • any: любая роль. Эквивалентно отсутствию параметра.

--force
Флаг пропуска подтверждений при запросе перезагрузки локальной конфигурации.

Полезно для сценариев.

Примеры

Запросить перезагрузку локальной конфигурации всех участников кластера Patroni:

$ patronictl -c postgres0.yml reload batman --force
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Reload request received for member postgresql0 and will be processed within 10 seconds
Reload request received for member postgresql1 and will be processed within 10 seconds
Reload request received for member postgresql2 and will be processed within 10 seconds

patronictl remove

Синтаксис

remove
  CLUSTER_NAME
  [ --group CITUS_GROUP ]
  [ { -f | --format } { pretty | tsv | json | yaml } ]

Описание

patronictl remove удаляет сведения о кластере из DCS.

Это интерактивное действие.

Предупреждение

Операция уничтожает сведения о кластере Patroni в DCS.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

--group
Удалить сведения о кластере Patroni, относящиеся к заданной группе Citus.

CITUS_GROUP — идентификатор группы Citus.

-f / --format
Способ форматирования списка участников в выводе при запросе подтверждения.

Допустимые форматы:

  • pretty: выводит участников как форматированную таблицу; либо
  • tsv: выводит участников как табличные сведения со столбцами, разделёнными \t; либо
  • json: выводит участников в формате JSON; либо
  • yaml: выводит участников в формате YAML.

По умолчанию используется pretty.

Примеры

Удалить сведения о кластере Patroni batman из DCS:

$ patronictl -c postgres0.yml remove batman
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  5 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  5 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Please confirm the cluster name to remove: batman
You are about to remove all information in DCS for batman, please type: "Yes I am aware": Yes I am aware
This cluster currently is healthy. Please specify the leader name to continue: postgresql0

patronictl restart

Синтаксис

restart
  CLUSTER_NAME
  [ MEMBER_NAME [, ...] ]
  [ --group CITUS_GROUP ]
  [ { -r | --role } { leader | primary | standby-leader | replica | standby | any } ]
  [ --any ]
  [ --pg-version PG_VERSION ]
  [ --pending ]
  [ --timeout TIMEOUT ]
  [ --scheduled TIMESTAMP ]
  [ --force ]

Описание

patronictl restart запрашивает перезапуск экземпляра Postgres под управлением участника кластера Patroni.

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

Параметры

CLUSTER_NAME
Имя кластера Patroni.

--group
Перезапустить кластер Patroni, относящийся к заданной группе Citus.

CITUS_GROUP — идентификатор группы Citus.

-r / --role
Выбрать участников с заданной ролью.

Допустимые роли:

  • leader: лидер обычного или резервного кластера Patroni; либо
  • primary: лидер обычного кластера Patroni; либо
  • standby-leader: лидер резервного кластера Patroni; либо
  • replica: реплика кластера Patroni; либо
  • standby: то же, что replica; либо
  • any: любая роль. Эквивалентно отсутствию параметра.

--any
Перезапустить один случайный узел среди соответствующих фильтрам.

--pg-version
Выбрать только участников, версия управляемого экземпляра Postgres которых старше заданной.

PG_VERSION — версия Postgres для сравнения.

--pending
Выбрать только участников с флагом Pending restart.

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

TIMEOUT — количество секунд ожидания до прерывания перезапуска.

--scheduled
Запланировать перезапуск на заданное время.

TIMESTAMP — время перезапуска. Укажите его в однозначном формате, желательно с часовым поясом. Для немедленного перезапуска можно использовать литерал now.

--force
Флаг пропуска подтверждений при запросе перезапуска.

Полезно для сценариев.

Примеры

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

$ patronictl -c postgres0.yml restart batman --force
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  6 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  6 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  6 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Success: restart on member postgresql0
Success: restart on member postgresql1
Success: restart on member postgresql2

Немедленно перезапустить случайного участника кластера:

$ patronictl -c postgres0.yml restart batman --any --force
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  6 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  6 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  6 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Success: restart on member postgresql1

Запланировать перезапуск на 2023-09-13T18:00-03:00:

$ patronictl -c postgres0.yml restart batman --scheduled 2023-09-13T18:00-03:00 --force
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  6 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  6 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  6 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Success: restart scheduled on member postgresql0
Success: restart scheduled on member postgresql1
Success: restart scheduled on member postgresql2

patronictl resume

Синтаксис

resume
  [ CLUSTER_NAME ]
  [ --group CITUS_GROUP ]
  [ --wait ]

Описание

patronictl resume выводит кластер Patroni из режима обслуживания и снова включает автоматическое переключение при отказе.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Возобновить работу заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

Если не задано, patronictl попытается получить значение из citus.group, если оно существует.

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

Примеры

Вывести кластер из режима обслуживания:

$ patronictl -c postgres0.yml resume batman --wait
'resume' request sent, waiting until it is recognized by all nodes
Success: cluster management is resumed

patronictl show-config

Синтаксис

show-config
  [ CLUSTER_NAME ]
  [ --group CITUS_GROUP ]

Описание

patronictl show-config показывает динамическую конфигурацию кластера, хранящуюся в DCS.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Показать динамическую конфигурацию заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

Если не задано, patronictl попытается получить значение из citus.group, если оно существует.

Примеры

Показать динамическую конфигурацию кластера batman:

$ patronictl -c postgres0.yml show-config batman
loop_wait: 10
postgresql:
  parameters:
    max_connections: 250
  pg_hba:
  - host replication replicator 127.0.0.1/32 md5
  - host all all 0.0.0.0/0 md5
  use_pg_rewind: true
retry_timeout: 10
ttl: 30

patronictl switchover

Синтаксис

switchover
  [ CLUSTER_NAME ]
  [ --group CITUS_GROUP ]
  [ { --leader | --primary } LEADER_NAME ]
  --candidate CANDIDATE_NAME
  [ --force ]

Описание

patronictl switchover выполняет плановое переключение в кластере.

Команда предназначена для исправного кластера, например когда:

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

Для неисправного кластера может лучше подойти patronictl failover.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Выполнить плановое переключение в заданной группе Citus.

CITUS_GROUP — идентификатор группы Citus.

--leader / --primary
Указать лидера, который будет понижен при переключении.

LEADER_NAME должно совпадать с именем текущего лидера кластера.

--candidate
Узел, повышаемый при переключении до роли первичного сервера.

CANDIDATE_NAME — имя повышаемого узла.

--scheduled
Запланировать переключение на заданное время.

TIMESTAMP — время переключения. Укажите его в однозначном формате, желательно с часовым поясом. Для немедленного переключения можно использовать литерал now.

--force
Флаг пропуска подтверждений при плановом переключении.

Полезно для сценариев.

Примеры

Выполнить плановое переключение на узел postgresql2:

$ patronictl -c postgres0.yml switchover batman --leader postgresql0 --candidate postgresql2 --force
Current cluster topology
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  6 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  6 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  6 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
2023-09-13 14:15:23.07497 Successfully switched over to "postgresql2"
+ Cluster: batman (7277694203142172922) -+---------+----+-------------+---------+------------+---------+
| Member      | Host           | Role    | State   | TL | Receive LSN |     Lag | Replay LSN |     Lag |
+-------------+----------------+---------+---------+----+-------------+---------+------------+---------+
| postgresql0 | 127.0.0.1:5432 | Replica | stopped |    |     unknown | unknown |    unknown | unknown |
| postgresql1 | 127.0.0.1:5433 | Replica | running |  6 |   0/4000188 |       0 |  0/4000188 |       0 |
| postgresql2 | 127.0.0.1:5434 | Leader  | running |  6 |             |         |            |         |
+-------------+----------------+---------+---------+----+-------------+---------+------------+---------+

Запланировать переключение между postgresql0 и postgresql2 на 2023-09-13T18:00:00-03:00:

$ patronictl -c postgres0.yml switchover batman --leader postgresql0 --candidate postgresql2 --scheduled 2023-09-13T18:00-03:00 --force
Current cluster topology
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  8 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  8 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  8 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
2023-09-13 14:18:11.20661 Switchover scheduled
+ Cluster: batman (7277694203142172922) -+-----------+----+-------------+-----+------------+-----+
| Member      | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0 | 127.0.0.1:5432 | Leader  | running   |  8 |             |     |            |     |
| postgresql1 | 127.0.0.1:5433 | Replica | streaming |  8 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| postgresql2 | 127.0.0.1:5434 | Replica | streaming |  8 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+-------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
Switchover scheduled at: 2023-09-13T18:00:00-03:00
                    from: postgresql0
                    to: postgresql2

patronictl topology

Синтаксис

topology
  [ CLUSTER_NAME [, ... ] ]
  [ --group CITUS_GROUP ]
  [ { -W | { -w | --watch } TIME } ]

Описание

patronictl topology показывает сведения о кластере Patroni и его участниках в виде дерева.

Вывод содержит следующие сведения:

Cluster
Имя кластера Patroni.

Примечание

Показывается в заголовке таблицы.

System identifier
Системный идентификатор Postgres.

Примечание

Показывается в заголовке таблицы.

Member
Имя участника Patroni.

Примечание

Сведения в столбце показываются как дерево участников по соединениям репликации.

Host
Узел, на котором находится участник.

Role
Текущая роль участника.

Возможные значения:

  • Leader: текущий лидер обычного кластера Patroni; либо
  • Standby Leader: текущий лидер резервного кластера Patroni; либо
  • Sync Standby: синхронный резервный сервер кластера Patroni с включённым синхронным режимом; либо
  • Replica: обычный резервный сервер кластера Patroni.

State
Текущее состояние Postgres на участнике Patroni.

Примеры возможных состояний:

  • running: Postgres запущен и работает;
  • streaming: участник является репликой, и Postgres передаёт WAL потоком с первичного узла;
  • in archive recovery: участник является репликой, и Postgres получает WAL из архива;
  • stopped: Postgres остановлен;
  • crashed: Postgres аварийно завершился.

TL
Текущая временная шкала Postgres на участнике Patroni.

Receive LSN
Последняя позиция журнала предзаписи, полученная потоковой репликацией участника и синхронизированная с диском (pg_catalog.pg_last_(xlog|wal)_receive_(location|lsn)()).

Receive Lag
Отставание репликации между позицией участника Receive LSN и вышестоящим узлом в MB.

Replay LSN
Последняя позиция журнала предзаписи, воспроизведённая при восстановлении участника (pg_catalog.pg_last_(xlog|wal)_replay_(location|lsn)()).

Replay Lag
Отставание репликации между позицией участника Replay LSN и вышестоящим узлом в MB.

Кроме того, вывод может содержать:

Group
Идентификатор группы Citus.

Примечание

Показывается в заголовке таблицы.

Только для кластера Citus.

Pending restart
* означает, что для применения конфигурации Postgres узлу требуется перезапуск. Пустое значение означает, что перезапуск не требуется.

Примечание

Показывается как атрибут участника.

Показывается, если узлу требуется перезапуск.

Scheduled restart
Время запланированного перезапуска экземпляра Postgres под управлением участника Patroni. Пустое значение означает отсутствие запланированного перезапуска.

Примечание

Показывается как атрибут участника.

Показывается, если у узла есть запланированный перезапуск.

Tags
Содержит теги участника Patroni. Пустое значение означает, что теги не настроены либо имеют значения по умолчанию.

Примечание

Показывается как атрибут участника.

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

Scheduled switchover
Время запланированного планового переключения кластера Patroni, если оно есть.

Примечание

Показывается в нижнем колонтитуле таблицы.

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

Maintenance mode

Мониторинг кластера в настоящее время приостановлен.

Примечание

Показывается в нижнем колонтитуле таблицы.

Показывается только при паузе кластера.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

Если не задано, patronictl попытается получить его из параметра scope, если тот существует.

--group
Показать сведения об участниках заданной группы Citus.

CITUS_GROUP — идентификатор группы Citus.

-W
Автоматически обновлять сведения каждые 2 секунды.

-w / --watch
Автоматически обновлять сведения с заданным интервалом.

TIME — интервал между обновлениями в секундах.

Примеры

Показать топологию кластера batman, где postgresql1 и postgresql2 реплицируются с postgresql0:

$ patronictl -c postgres0.yml topology batman
+ Cluster: batman (7277694203142172922) ---+-----------+----+-------------+-----+------------+-----+
| Member        | Host           | Role    | State     | TL | Receive LSN | Lag | Replay LSN | Lag |
+---------------+----------------+---------+-----------+----+-------------+-----+------------+-----+
| postgresql0   | 127.0.0.1:5432 | Leader  | running   |  8 |             |     |            |     |
| + postgresql1 | 127.0.0.1:5433 | Replica | streaming |  8 |   0/40004E8 |   0 |  0/40004E8 |   0 |
| + postgresql2 | 127.0.0.1:5434 | Replica | streaming |  8 |   0/40004E8 |   0 |  0/40004E8 |   0 |
+---------------+----------------+---------+-----------+----+-------------+-----+------------+-----+

patronictl version

Синтаксис

version
  [ CLUSTER_NAME [, ... ] ]
  [ MEMBER_NAME [, ... ] ]
  [ --group CITUS_GROUP ]

Описание

patronictl version получает версию приложения patronictl . Кроме того, вывод может содержать версии кластеров Patroni и их участников.

Параметры

CLUSTER_NAME
Имя кластера Patroni.

MEMBER_NAME
Имя участника кластера Patroni.

--group
Рассматривать кластер Patroni с заданной группой Citus.

CITUS_GROUP — идентификатор группы Citus.

Примеры

Получить только версию patronictl :

$ patronictl -c postgres0.yml version
patronictl version 4.0.0

Получить версию patronictl и всех участников кластера batman:

$ patronictl -c postgres0.yml version batman
patronictl version 4.0.0

postgresql0: Patroni 4.0.0 PostgreSQL 16.4
postgresql1: Patroni 4.0.0 PostgreSQL 16.4
postgresql2: Patroni 4.0.0 PostgreSQL 16.4

Получить версию patronictl и участников postgresql1 и postgresql2 кластера batman:

$ patronictl -c postgres0.yml version batman postgresql1 postgresql2
patronictl version 4.0.0

postgresql1: Patroni 4.0.0 PostgreSQL 16.4
postgresql2: Patroni 4.0.0 PostgreSQL 16.4

6 - Создание образов реплик и начальная инициализация

Создание образов реплик, начальная инициализация и пользовательские процессы создания реплик.

Patroni позволяет настраивать создание новой реплики и определять действия при начальной инициализации нового пустого кластера. Различие строго определено: Patroni создаёт реплики, только если для кластера в DCS присутствует ключ initialize. Если ключа initialize нет, Patroni выполняет начальную инициализацию исключительно на первом узле, получившем блокировку ключа initialize.


Начальная инициализация

PostgreSQL предоставляет команду initdb для инициализации нового кластера, и Patroni вызывает её по умолчанию. В некоторых случаях, особенно при создании нового кластера как копии существующего, встроенный метод необходимо заменить пользовательскими действиями. Patroni поддерживает сценарии пользователя для начальной инициализации новых кластеров и передаёт им обязательные аргументы, например имя кластера и путь к каталогу данных. Это настраивается в разделе bootstrap конфигурации Patroni. Например:

bootstrap:
    method: <custom_bootstrap_method_name>
    <custom_bootstrap_method_name>:
        command: <path_to_custom_bootstrap_script> [param1 [, ...]]
        keep_existing_recovery_conf: False
        no_params: False
        recovery_conf:
            recovery_target_action: promote
            recovery_target_timeline: latest
            restore_command: <method_specific_restore_command>

Каждый метод начальной инициализации должен определить как минимум name и command. Специальный метод initdb запускает поведение по умолчанию; в этом случае параметр method можно полностью опустить. command задаётся абсолютным путём либо путём относительно расположения команды patroni. Помимо фиксированных параметров файла конфигурации Patroni передаёт два параметра конкретного кластера:

--scope
Имя инициализируемого кластера

--datadir
Путь к каталогу данных инициализируемого экземпляра кластера

Передачу этих двух дополнительных флагов можно отключить, задав специальному параметру no_params значение True.

Если сценарий начальной инициализации возвращает 0, Patroni пытается настроить и запустить созданный им экземпляр PostgreSQL. Если промежуточный шаг завершается ошибкой либо сценарий возвращает ненулевое значение, Patroni считает инициализацию неудачной, очищает созданные данные и освобождает блокировку initialize, позволяя другому узлу выполнить инициализацию.

Если в том же разделе, что и пользовательский метод, определён блок recovery_conf, Patroni перед запуском нового экземпляра создаёт recovery.conf либо задаёт параметры восстановления в конфигурации Postgres для PostgreSQL >= 12. Обычно такая конфигурация должна содержать хотя бы один параметр recovery_target_* вместе с recovery_target_action, равным promote.

Если keep_existing_recovery_conf определён и равен True, Patroni не удаляет существующий recovery.conf в PostgreSQL <= 11. Аналогично, Patroni не удаляет существующие recovery.signal или standby.signal и не переопределяет настроенные параметры восстановления в PostgreSQL >= 12. Это полезно при начальной инициализации из резервной копии инструментом наподобие pgBackRest, который самостоятельно создаёт подходящую конфигурацию восстановления.

Кроме того, дополнительные пары «ключ — значение» из конфигурации пользовательского метода передаются как аргументы command в формате --name=value. Например:

bootstrap:
    method: <custom_bootstrap_method_name>
    <custom_bootstrap_method_name>:
        command: <path_to_custom_bootstrap_script>
        arg1: value1
        arg2: value2

Настроенная command будет дополнительно вызвана с аргументами командной строки --arg1=value1 --arg2=value2.

Примечание

Методы начальной инициализации не объединяются в цепочку, и при ошибке основного метода возврат к методу по умолчанию не выполняется

Например, новый кластер Patroni можно инициализировать из резервной копии Barman со следующей конфигурацией:

bootstrap:
    method: barman
    barman:
        keep_existing_recovery_conf: true
        command: patroni_barman --api-url https://barman-host:7480 recover
        barman-server: my_server
        ssh-command: ssh postgres@patroni-host
Примечание

Для patroni_barman recover на узле Barman должны быть настроены Barman и pg-backup-api, чтобы удалённо выполнять barman recover через API резервного копирования. В примере выше используется часть доступных параметров. Дополнительные сведения выводит команда patroni_barman recover --help.


Создание реплик

Для создания новых реплик Patroni использует проверенный pg_basebackup. Его недостатки — необходимость работающего узла-лидера, отсутствие сжатия резервных данных «на лету» и встроенной очистки устаревших файлов копий. Некоторые предпочитают другие решения, например WAL-E, pgBackRest, Barman, либо собственные сценарии. Для этих случаев Patroni поддерживает пользовательские сценарии клонирования новой реплики. Они настраиваются в блоке postgresql:

postgresql:
    create_replica_methods:
        - <method name>
    <method name>:
        command: <command name>
        keep_data: True
        no_params: True
        no_leader: 1

пример: wal_e

postgresql:
    create_replica_methods:
        - wal_e
        - basebackup
    wal_e:
        command: patroni_wale_restore
        no_leader: 1
        envdir: '{{WALE_ENV_DIR}}'
        use_iam: 1
    basebackup:
        max-rate: '100M'

пример: pgbackrest

postgresql:
    create_replica_methods:
        - pgbackrest
        - basebackup
    pgbackrest:
        command: /usr/bin/pgbackrest --stanza=<scope> --delta restore
        keep_data: True
        no_params: True
    basebackup:
        max-rate: '100M'

пример: Barman

postgresql:
    create_replica_methods:
        - barman
        - basebackup
    barman:
        command: patroni_barman --api-url https://barman-host:7480 recover
        barman-server: my_server
        ssh-command: ssh postgres@patroni-host
    basebackup:
        max-rate: '100M'
Примечание

Для patroni_barman recover на узле Barman должны быть настроены Barman и pg-backup-api, чтобы удалённо выполнять barman recover через API резервного копирования. В примере выше используется часть доступных параметров. Дополнительные сведения выводит команда patroni_barman recover --help.

create_replica_methods определяет доступные методы создания реплик и порядок их выполнения. Patroni останавливается на первом методе, вернувшем 0. Для каждого метода следует определить отдельный раздел файла конфигурации с выполняемой командой и передаваемыми ей пользовательскими параметрами. Все параметры передаются в формате --name=value. Помимо параметров пользователя Patroni передаёт несколько параметров конкретного кластера:

--scope
Кластер, которому принадлежит реплика

--datadir
Путь к каталогу данных реплики

--role
Всегда ‘replica’

--connstring
Строка подключения к участнику кластера, с которого выполняется клонирование (первичному серверу или другой реплике). Пользователь из строки подключения может выполнять команды SQL и протокола репликации.

Специальный параметр no_leader, если он определён, позволяет Patroni вызывать метод создания реплики даже при отсутствии работающего лидера или реплик. В таком случае передаётся пустая строка подключения. Это полезно для восстановления ранее работавшего кластера из двоичной резервной копии.

Специальный параметр keep_data, если он определён, запрещает Patroni очищать каталог PGDATA перед вызовом восстановления.

Специальный параметр no_params, если он определён, запрещает передачу параметров пользовательской команде.

Метод basebackup — особый случай: он используется, если create_replica_methods пуст, хотя его можно явно перечислить среди методов create_replica_methods. Метод инициализирует новую реплику с помощью pg_basebackup. Базовая резервная копия берётся с лидера, если нет реплик с тегом clonefrom; в противном случае источником pg_basebackup служит одна из таких реплик. Метод работает без конфигурации, но можно определить раздел basebackup. Применяются те же правила, что и для других методов: следует указывать только длинные параметры с –. Не все параметры имеют смысл: если переопределить строку подключения или запросить архивированную tar либо сжатую базовую копию, Patroni не сможет создать из неё реплику. Имена и значения параметров раздела basebackup не проверяются. Если для каталога WAL используются символические ссылки, пользователь должен указать правильный путь --waldir, чтобы ссылка сохранилась после создания или повторной инициализации реплики. Этот параметр поддерживается только начиная с v10.

Параметры basebackup можно задать как отображение пар «ключ — значение» либо как список элементов, каждый из которых является парой или отдельным ключом для параметров без значений, например --verbose. Рассмотрим 2 примера:

postgresql:
    basebackup:
        max-rate: '100M'
        checkpoint: 'fast'

и

postgresql:
    basebackup:
        - verbose
        - max-rate: '100M'
        - waldir: /pg-wal-mount/external-waldir

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

7 - Режимы репликации

Асинхронные и синхронные режимы репликации под управлением Patroni.

Patroni использует потоковую репликацию PostgreSQL. Подробнее см. документацию Postgres . По умолчанию Patroni настраивает PostgreSQL на асинхронную репликацию. Выбор схемы репликации зависит от требований бизнеса. Изучите асинхронную и синхронную репликацию, а также другие решения HA, чтобы выбрать подходящий вариант.


Долговечность в асинхронном режиме

В асинхронном режиме ради доступности кластер может потерять часть зафиксированных транзакций. При отказе или недоступности первичного сервера Patroni автоматически повышает достаточно исправный резервный сервер до первичного. Транзакции, не реплицированные на этот резервный сервер, остаются в «ответвившейся временной шкале» первичного и фактически невосстановимы1.

Объём транзакций, которые могут быть потеряны, контролируется параметром maximum_lag_on_failover. Поскольку позиция журнала транзакций первичного сервера не измеряется в реальном времени, в худшем случае при переключении теряется maximum_lag_on_failover байтов журнала плюс объём, записанный за последние ttl секунд (в среднем за loop_wait/2 секунд). Однако типичная задержка репликации в стабильном состоянии значительно меньше секунды.

По умолчанию при выборах лидера Patroni не учитывает текущую временную шкалу реплик, что иногда нежелательно. Чтобы узел с временной шкалой, отличной от прежнего первичного сервера, не стал новым лидером, задайте параметру check_timeline значение true.


Синхронная репликация PostgreSQL

С Patroni можно использовать синхронную репликацию Postgres. Она обеспечивает согласованность кластера, подтверждая запись на вторичный сервер до возврата успешного результата подключённому клиенту. Цена синхронной репликации — повышенная задержка и сниженная пропускная способность записи, полностью зависящая от производительности сети.

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

Для простого теста синхронной репликации добавьте следующие строки в раздел parameters файлов конфигурации YAML:

synchronous_commit: "on"
synchronous_standby_names: "*"

При синхронной репликации PostgreSQL используйте не менее трёх узлов данных Postgres, чтобы сохранить доступность записи при отказе одного узла.

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


Синхронный режим

Для сценариев, где потеря зафиксированных транзакций недопустима, включите synchronous_mode Patroni. При включённом synchronous_mode Patroni не повышает резервный сервер, пока не убедится, что тот содержит все транзакции, для которых клиент мог получить успешный статус фиксации2. Поэтому система может быть недоступна для записи, хотя часть серверов работает. Системные администраторы всё ещё могут вручную переключить резервный сервер при отказе, даже если это приведёт к потере транзакций.

Включение synchronous_mode не гарантирует долговечность фиксаций на нескольких узлах при любых обстоятельствах. Если подходящего резервного сервера нет, первичный всё равно принимает записи, но не гарантирует их репликацию. При отказе первичного сервера в этом режиме резервный сервер не повышается. Когда прежний первичный узел возвращается, он повышается автоматически, если системный администратор не выполнил ручное переключение. Благодаря этому синхронный режим применим в кластерах из 2 узлов.

Если при включённом synchronous_mode резервный сервер отказывает, фиксации блокируются до следующей итерации Patroni, которая переводит первичный сервер в автономный режим (задержка записи в худшем случае — ttl секунд, в среднем — loop_wait/2 секунд). Ручная остановка или перезапуск резервного сервера не прерывает службу фиксации: до остановки PostgreSQL резервный сервер сообщает первичному, что освобождается от обязанностей синхронной реплики.

Если необходимо гарантировать долговечное хранение каждой записи как минимум на двух узлах, в дополнение к synchronous_mode включите synchronous_mode_strict. Этот параметр не позволяет Patroni отключать синхронную репликацию на первичном сервере при отсутствии подходящих резервных кандидатов, если только транзакция Postgres явно не отключила synchronous_commit; все клиентские запросы записи блокируются до появления хотя бы одной синхронной реплики.

Когда synchronous_mode_strict включён и активные соединения репликации не удовлетворяют минимальному коэффициенту репликации, Patroni определяет synchronous_standby_names следующим образом:

  1. Последние известные синхронные узлы доступны в ключе /sync DCS: Patroni задаёт или сохраняет в synchronous_standby_names указанные там узлы. Например, если /sync содержит leader=node1, sync_standby=node2,node3 и оба резервных сервера прекращают потоковую передачу, Patroni продолжает использовать:

    synchronous_standby_names = 'node2,node3'

    Эти узлы последними получили последнюю известную фиксацию. Фиксации блокируются, пока хотя бы один из них не подключится снова.

  2. Ручное переключение на асинхронный узел: когда повышается узел, которого не было в ключе /sync, например через patronictl failover --force, значение synchronous_standby_names устанавливается равным прежнему первичному серверу, поскольку только он гарантированно содержит последние зафиксированные данные.

  3. Ключ /sync пуст: например, строгий режим только что включён или кластер недавно инициализирован и ещё не имеет реплик. Patroni задаёт:

    synchronous_standby_names = '__patroni_strict_sync_replica_placeholder__'

    Это встроенное сторожевое значение, не совпадающее ни с одним реальным именем узла. Оно блокирует все записи, пока подходящая реплика не начнёт потоковую передачу с первичного сервера. Заполнитель заменяет прежний шаблон *, который мог непреднамеренно позволить неподходящему узлу выполнить требование синхронизации.

Предупреждение

Значение __patroni_strict_sync_replica_placeholder__ зарезервировано Patroni и не должно использоваться как name узла Patroni в patroni.yaml. С таким именем Patroni откажется запускаться.

При активном строгом режиме Patroni выдаёт предупреждение журнала: "No active replication connections and synchronous_mode_strict is requested. Commits will be delayed." Оно выводится один раз на событие активации, а не при каждой итерации цикла HA.

Чтобы резервный сервер никогда не становился синхронным, задайте тегу nosync значение true. Это рекомендуется для резервных серверов за медленными сетевыми соединениями, которые снизили бы производительность в роли синхронной реплики. Тег nostream, равный true, даёт тот же эффект.

Синхронный режим можно включать и отключать командой patronictl edit-config или через REST-интерфейс Patroni. Инструкции приведены в разделе динамическая конфигурация .

Примечание: из-за реализации синхронной репликации в PostgreSQL транзакции можно потерять даже с synchronous_mode_strict. Если бэкенд PostgreSQL отменён в ожидании подтверждения репликации, например из-за отмены пакета при тайм-ауте клиента или отказе бэкенда, изменения транзакции становятся видимыми другим бэкендам. Они ещё не реплицированы и могут быть потеряны при повышении резервного сервера.


Коэффициент синхронной репликации

Параметр synchronous_node_count управляет количеством синхронных резервных баз данных в Patroni. По умолчанию он равен 1 и не действует, если synchronous_mode равен off. При включении Patroni поддерживает точное количество синхронных резервных баз по synchronous_node_count и корректирует состояние в DCS и synchronous_standby_names PostgreSQL при присоединении и выходе участников. Если значение превышает количество подходящих узлов, Patroni автоматически его уменьшает.


Максимальное отставание синхронного узла

По умолчанию Patroni сохраняет узлы, объявленные synchronous согласно представлению pg_stat_replication, даже если другие узлы опережают их. Это уменьшает количество изменений synchronous_standby_names. Поведение можно изменить параметром maximum_lag_on_syncnode, который определяет допустимое отставание реплики, всё ещё считающейся «синхронной».

Если резервных серверов несколько, Patroni использует максимальный LSN реплики, иначе — текущий LSN wal лидера. По умолчанию значение равно -1; при значении 0 или меньше Patroni не заменяет неисправный синхронный резервный сервер. Задайте достаточно высокое значение, чтобы Patroni не менял синхронные реплики слишком часто при большом объёме транзакций.


Реализация синхронного режима

В синхронном режиме Patroni хранит в DCS, в ключе /sync, состояние синхронизации с последним первичным сервером и текущими синхронными резервными базами. Состояние обновляется со строгими ограничениями порядка, обеспечивая следующие инварианты:

  • Узел должен быть отмечен как последний лидер всякий раз, когда он может принимать транзакции записи. Отказ Patroni или незавершённая остановка PostgreSQL могут нарушить этот инвариант.
  • Узел должен быть задан синхронным резервным сервером PostgreSQL, пока он опубликован как синхронный резервный сервер в ключе /sync DCS.
  • Узел, не являющийся лидером или текущим синхронным резервным сервером, не может автоматически повысить себя.

Patroni назначает в synchronous_standby_names один или несколько синхронных резервных узлов только на основе параметра synchronous_node_count.

На каждой итерации цикла HA Patroni заново оценивает выбор синхронных резервных узлов. Если узлы текущего списка подключены и не запросили снятие синхронного статуса, список сохраняется. Иначе выбираются доступные для синхронизации участники кластера, сильнее всего продвинувшиеся в репликации.

Пример:

Ключ /config в DCS

synchronous_mode: on
synchronous_node_count: 2
...

Ключ /sync в DCS

{
    "leader": "node0",
    "sync_standby": "node1,node2"
}

postgresql.conf

synchronous_standby_names = 'FIRST 2 (node1,node2)'

В приведённых примерах только узлы node1 и node2 считаются синхронными и могут быть автоматически повышены при отказе первичного сервера (node0).


Режим фиксации по кворуму

Начиная с PostgreSQL v10 Patroni поддерживает синхронную репликацию на основе кворума.

В этом режиме Patroni хранит в DCS состояние синхронизации с последним известным первичным сервером, количеством узлов для кворума и узлами, имеющими право голоса. В стабильном состоянии голосующие узлы — лидер и все синхронные резервные серверы. Состояние обновляется со строгими ограничениями порядка повышения узлов и synchronous_standby_names, чтобы любое способное достичь кворума подмножество голосующих всегда содержало хотя бы один узел с последней успешной фиксацией.

На каждой итерации цикла HA Patroni заново оценивает выбор синхронных резервных серверов и кворум по доступности узлов и запрошенной конфигурации кластера. В версиях PostgreSQL выше 9.6 все подходящие узлы добавляются как синхронные резервные серверы, как только их репликация догоняет лидера.

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

Синхронный режим на основе кворума включается установкой synchronous_mode в quorum командой patronictl edit-config или через REST-интерфейс Patroni. Инструкции приведены в разделе динамическая конфигурация .

Остальные параметры, включая synchronous_node_count, maximum_lag_on_syncnode и synchronous_mode_strict, работают так же, как при synchronous_mode=on.

Если в режиме фиксации по кворуму с synchronous_mode_strict нет активных реплик, Patroni задаёт synchronous_standby_names как ANY N (<last known voters>), сохраняя последних известных голосующих из /sync, либо как ANY 1 (__patroni_strict_sync_replica_placeholder__), если в ключе /sync нет голосующих.

Пример:

Ключ /config в DCS

synchronous_mode: quorum
synchronous_node_count: 2
...

Ключ /sync в DCS

{
    "leader": "node0",
    "sync_standby": "node1,node2,node3",
    "quorum": 1
}

postgresql.conf

synchronous_standby_names = 'ANY 2 (node1,node2,node3)'

При отказе первичного сервера (node0) в приведённом примере два узла из node1, node2, node3 получат последнюю транзакцию, но неизвестно какие. Чтобы определить, получил ли её node1, нужно сравнить его LSN с LSN как минимум одного узла (quorum=1 в ключе /sync) из node2 и node3. Если node1 не отстаёт хотя бы от одного из них, можно гарантировать отсутствие видимой пользователю потери данных при повышении node1.


  1. Данные всё ещё существуют, но для их извлечения требуется ручная работа специалистов по восстановлению. Если Patroni разрешено перематывать состояние с use_pg_rewind, ответвившаяся временная шкала автоматически удаляется, чтобы снова присоединить отказавший первичный сервер к кластеру. Для правильной работы use_pg_rewind кластер должен быть инициализирован с data page checksums (параметр --data-checksums для initdb) и/или wal_log_hints должен быть равен on. ↩︎

  2. Клиенты могут изменять поведение отдельных транзакций параметром PostgreSQL synchronous_commit. Транзакции со значениями synchronous_commit off и local могут быть потеряны при переключении, но не блокируются задержкой репликации. ↩︎

8 - Резервный кластер

Настройка резервного кластера, поведение и репликация из удалённого первичного сервера.

Patroni также поддерживает настройку каскадной репликации на удалённый центр обработки данных (регион) с использованием функции, называемой «резервный кластер». Такие кластеры обладают следующими характеристиками:

  • «резервный лидер», который ведёт себя примерно как обычный лидер кластера, за исключением того, что реплицирует данные с удалённого узла.
  • каскадные реплики, которые реплицируют данные с резервного сервера.

Резервный сервер-лидер удерживает и обновляет блокировку лидера в DCS. Если блокировка лидера истекает, каскадные реплики выполнят голосование для выбора другого лидера из резервных серверов.

Между резервным кластером и первичным кластером, от которого он воспроизводит данные, отсутствует какая-либо дополнительная связь, в частности, они не должны использовать один и тот же DCS при использовании одного и того же DCS. Они не знают друг о друге ничего, кроме информации репликации. Кроме того, резервный кластер не отображается в выводе patronictl_list или patronictl_topology на первичном кластере.

В целях гибкости вы можете указать методы создания реплики и восстановления WAL записей при работе кластера в режиме «резервный сервер», задав ключ create_replica_methods в разделе standby_cluster . Это отличается от создания реплик, когда кластер отсоединен и функционирует как обычный кластер, управление которым осуществляется с помощью create_replica_methods в разделе postgresql. Оба ключа ссылок «резервный сервер» и «обычный» create_replica_methods находятся в разделе postgresql.

Для настройки такого кластера необходимо указать раздел standby_cluster в конфигурации Patroni:

bootstrap:
    dcs:
        standby_cluster:
            host: 1.2.3.4
            port: 5432
            primary_slot_name: patroni
            create_replica_methods:
            - basebackup

Примечание. Эти параметры будут применены только один раз при начальной инициализации кластера, и единственный способ изменить их позже — через DCS.

Patroni ожидает найти postgresql.conf или postgresql.conf.backup в PGDATA первичного сервера и не запустится, если не найдет его после выполнения basebackup. Если первичный сервер хранит свой postgresql.conf в другом месте, то копирование его в PGDATA является вашей ответственностью.

Если вы используете слоты репликации в резервном кластере, вы также должны создать соответствующий слот репликации в первичном кластере. Это не будет выполнено автоматически реализацией резервного сервера. Вы можете использовать функцию постоянных слотов репликации Patroni в первичном кластере для поддержания слота репликации с тем же именем, что и primary_slot_name, или со значением по умолчанию, если primary_slot_name не указано.

В случае, если удалённый сайт не предоставляет единый конечный пункт, подключающийся к первичному серверу, можно перечислить все хосты исходного кластера в разделе standby_cluster.host. Когда в standby_cluster.host указано несколько хостов, разделённых запятыми, Patroni будет:

  • добавьте target_session_attrs=read-write в primary_conninfo на резервном лидере.
  • используйте target_session_attrs=read-write при попытке определить, нужно ли запускать pg_rewind, или при выполнении pg_rewind на всех узлах резервного кластера.
  • примечание: для корректной работы pg_rewind кластер должен быть инициализирован с использованием data page checksums (опция --data-checksums для initdb) и/или должно быть установлено значение wal_log_hints, равное on. В противном случае pg_rewind не будет работать должным образом.

Также существует возможность репликации резервного кластера из другого резервного кластера или из резервного участника первичного кластера: для этого необходимо указать один хост в разделе standby_cluster.host. Однако следует учитывать, что в этом случае pg_rewind не сможет выполниться в резервном кластере.

Предупреждение

Имена участников (поле name в конфигурации Patroni каждого узла) должны быть уникальными во всём первичном кластере и во всех резервных кластерах, подключённых к нему.

Patroni устанавливает synchronous_standby_names на первичном сервере с использованием имён участников, которые также становятся application_name каждого соединения репликации в pg_stat_replication. Если узел резервного кластера имеет то же имя, что и участник первичного кластера, PostgreSQL увидит два соединения с одинаковыми значениями application_name. Такая неоднозначность может привести к тому, что PostgreSQL выполнит требование синхронной репликации с использованием соединения резервного кластера вместо намеченного участника первичного кластера, что вызовет преждевременное подтверждение транзакций как синхронно завершённых, хотя они не являются надёжными на соответствующем резервном сервере. Это скрытый сбой: репликация продолжается, ошибки не регистрируются, но кластер фактически работает без валидной синхронной реплики, что создаёт потенциальную угрозу потери данных при сбое первичного сервера.

9 - Поддержка сторожевого таймера

Рассмотрение интеграции сторожевого таймера и fencing для кластеров Patroni.

Запуск нескольких серверов PostgreSQL в качестве первичных может привести к потере транзакций из-за расхождения временных шкал. Такая ситуация также называется проблемой расщепленного мозга. Чтобы избежать проблемы расщепленного мозга, Patroni должен обеспечить, чтобы PostgreSQL не принимал никаких подтверждений транзакций после истечения срока действия ключа лидера в DCS. В нормальных условиях Patroni пытается достичь этого, останавливая PostgreSQL при неудаче обновления блокировки лидера по любой причине. Однако это может не произойти по различным причинам:

  • Patroni аварийно завершил работу из-за ошибки, нехватки памяти или был случайно завершён системным администратором.
  • Остановка PostgreSQL происходит слишком медленно.
  • Patroni не успевает запуститься из-за высокой нагрузки на систему, приостановки виртуальной машины гипервизором или других проблем инфраструктуры.

Чтобы гарантировать корректное поведение в этих условиях, Patroni поддерживает сторожевые таймеры. Сторожевые таймеры — это программные или аппаратные механизмы, которые перезагружают всю систему, если в течение заданного промежутка времени не получают сигнал keepalive. Это добавляет дополнительный уровень отказоустойчивости в случае, если обычные механизмы защиты Patroni от разделения мозгов не сработают.

Patroni попытается активировать сторожевой таймер перед повышением PostgreSQL до первичного сервера. Если активация сторожевого таймера не удалась, а режим сторожевого таймера — required, узел откажется стать лидером. При решении участвовать в голосовании за лидерство Patroni также проверит, позволит ли конфигурация сторожевого таймера стать лидером. После понижения PostgreSQL (например, из-за ручного переключения при отказе) Patroni снова отключит сторожевой таймер. Сторожевой таймер также будет отключён во время нахождения Patroni в состоянии остановки.

По умолчанию Patroni настраивает сторожевой таймер так, чтобы он истек на 5 секунд раньше, чем истекает TTL. При настройке по умолчанию loop_wait=10 и ttl=30 это даёт HA-циклу не менее 15 секунд (ttl - safety_margin - loop_wait) на завершение до принудительного перезапуска системы. По умолчанию время ожидания доступа к DCS настраивается на 10 секунд. Это означает, что при недоступности DCS, например из-за сетевых проблем, у Patroni и PostgreSQL будет не менее 5 секунд (ttl - safety_margin - loop_wait - retry_timeout) для перехода в состояние, при котором все соединения клиентов будут завершены.

Запас безопасности — это время, которое Patroni выделяет между обновлением ключа лидера и отправкой keepalive сторожевого таймера. Patroni попытается отправить keepalive немедленно после подтверждения обновления ключа лидера. Если процесс Patroni будет приостановлен на длительное время в самый подходящий момент, keepalive может быть задержан более чем на запас безопасности без срабатывания сторожевого таймера. Это создаёт окно времени, в течение которого сторожевой таймер не сработает до истечения срока действия ключа лидера, что нарушает гарантию. Чтобы абсолютно гарантировать срабатывание сторожевого таймера в любых условиях, настройте сторожевой таймер на истечение через половину TTL, установив safety_margin в -1, чтобы установить тайм-аут сторожевого таймера на ttl // 2. Если вам нужна такая гарантия, вероятно, следует увеличить ttl и/или уменьшить loop_wait и retry_timeout.

В настоящее время сторожевые таймеры поддерживаются только через интерфейс устройства сторожевого таймера Linux.


Настройка программного сторожевого таймера в Linux

По умолчанию конфигурация Patroni попытается использовать /dev/watchdog в Linux, если он доступен для Patroni. Для большинства случаев использования программного сторожевого таймера, встроенного в ядро Linux, этого достаточно.

Чтобы включить программный сторожевой таймер, выполните следующие команды от имени root перед запуском Patroni:

modprobe softdog
# Replace postgres with the user you will be running patroni under
chown postgres /dev/watchdog

Для тестирования может быть полезно отключить перезагрузку, добавив soft_noboot=1 в строку команды modprobe. В этом случае сторожевой таймер будет просто записывать строку в буфер ядра, доступный через dmesg.

Patroni будет записывать информацию о сторожевом таймере при его успешном включении.

10 - Режим приостановки/возобновления для кластера

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


Цель

В некоторых случаях Patroni должен временно прекратить управление кластером, сохраняя при этом состояние кластера в DCS. Возможные сценарии использования — редкие операции с кластером, такие как обновление до новой версии или восстановление после повреждения. В ходе таких операций узлы часто запускаются и останавливаются по причинам, неизвестным Patroni, некоторые узлы могут даже временно повышаться до статуса первичного сервера, что нарушает предположение о наличии только одного первичного сервера. Поэтому Patroni должен уметь «отключаться» от работающего кластера, реализуя эквивалент режима обслуживания, как в Pacemaker.


Реализация

Когда Patroni работает в режиме паузы, он не изменяет состояние PostgreSQL, за исключением следующих случаев:

  • Для каждого узла ключ участника в DCS обновляется с текущей информацией о кластере. Это заставляет Patroni выполнять запросы только на чтение на узле-участнике, если участник работает.
  • Для первичного сервера PostgreSQL с блокировкой лидера Patroni обновляет блокировку. Если узел с блокировкой лидера перестаёт быть первичным сервером (i.e. демотирован вручную), Patroni освободит блокировку вместо того, чтобы снова повысить узел до статуса первичного.
  • Разрешены ручной неплановый перезапуск, ручное неплановое переключение при отказе/плановое переключение и повторная инициализация. Плановые действия запрещены. Плановое переключение разрешено только в том случае, если указан узел, на который нужно переключиться.
  • Если Patroni обнаруживает «параллельные» первичные серверы, он выдаёт предупреждение, но не демотирует первичный сервер без блокировки лидера.
  • Если в кластере отсутствует блокировка лидера, первичный сервер, работающий в данный момент, получает блокировку. Если существует более одного первичного сервера, то первым получившим блокировку первичным сервером побеждает. Если первичных серверов вообще нет, Patroni не пытается повышать реплики до статуса первичного. Исключение из этого правила: если блокировка лидера отсутствует из-за того, что старый первичный сервер сам понизил свой статус в результате ручного повышения, то блокировку лидера может получить только узел-кандидат, упомянутый в запросе на повышение. После выдачи новой блокировки лидера (i.e. после ручного повышения реплики) Patroni обеспечивает, что реплики, которые ранее стримили данные с предыдущего лидера, переключатся на новый лидер.
  • При остановке Postgres Patroni не пытается запустить его. При остановке Patroni не пытается остановить экземпляр Postgres, которым управляет.
  • Patroni не будет пытаться удалять слоты репликации, которые не представляют участников другого кластера или не указаны в конфигурации постоянных слотов.

Руководство пользователя

patronictl поддерживает команды pause и resume .

Можно также отправить запрос PATCH на ключ {namespace}/{cluster}/config с {"pause": true/false/null}

11 - DCS Отказоустойчивый режим

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


Проблема

Patroni активно использует распределённое хранилище конфигурации (DCS) для решения задачи выбора лидера и обнаружения сетевых разделений. Узел может запускать PostgreSQL как первичный сервер только в том случае, если ему удаётся обновить блокировку лидера в DCS. В случае неудачи обновления блокировки лидера PostgreSQL немедленно понижается до режима только для чтения. Вероятность возникновения «проблемы» зависит от используемого DCS. Например, при использовании etcd, который применяется исключительно для Patroni, вероятность близка к нулю, тогда как при использовании K8s API (основанного на etcd) такая ситуация может возникать чаще.


Причины текущей реализации

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

  1. Разделение сети
  2. DCS недоступен

Вообще невозможно различить эти два случая на основе одного узла, поэтому Patroni исходит из худшего сценария — разделения сети. В случае разделения сети другие узлы кластера Patroni могут успешно получить блокировку лидера и повысить Postgres до первичного сервера. Чтобы избежать состояния split-brain, старый первичный сервер понижается в статусе до завершения срока действия блокировки лидера.


DCS Отказоустойчивый режим

Вводится новая специальная опция — failsafe_mode. Она может быть включена только через глобальную динамическую конфигурацию , хранящуюся в ключе DCS /config. Если включён отказоустойчивый режим и обновление блокировки лидера в DCS не удалось по причинам, отличным от несоответствия версии/значения/индекса, PostgreSQL может продолжать работу в качестве первичного сервера, если имеет доступ ко всем известным участникам кластера через Patroni REST API.


Детали низкоуровневой реализации

  • Вводится новый постоянный ключ в DCS, называемый /failsafe.
  • Ключ /failsafe содержит всех известных участников заданного кластера Patroni на данный момент.
  • Текущий лидер сохраняет ключ /failsafe.
  • Участник может участвовать в выборе лидера и стать новым лидером только в том случае, если он присутствует в ключе /failsafe.
  • Если кластер состоит из одного узла, ключ /failsafe будет содержать одного участника.
  • В случае DCS «сбоя» первичный сервер подключается ко всем участникам, перечисленным в ключе /failsafe, через REST API POST /failsafe REST API, и может продолжать работу как первичный сервер, если все реплики подтверждают его состояние.
  • Если один из участников не отвечает, первичный сервер понижается в статусе.
  • Реплики используют входящие запросы POST /failsafe REST API в качестве индикатора того, что первичный сервер всё ещё активен. Эта информация кэшируется на ttl секунд.

F.A.Q.

  • Почему MUST текущий первичный сервер видит ALL других участников? Разве здесь нельзя полагаться на кворум?

    Это отличный вопрос! Проблема в том, что взгляд на кворум может различаться с точки зрения DCS и Patroni. Хотя узлы DCS должны равномерно распределяться по зонам доступности, для Patroni такого правила не существует, и, что более важно, отсутствует механизм введения и обеспечения соблюдения такого правила. Если большинство узлов Patroni окажется в проигравшей части разорванной сети (включая первичный сервер), а меньшинство — в выигравшей, первичный сервер должен быть понижен. Только проверка ALL других участников позволяет выявить такую ситуацию.

  • Что будет, если узел/под будет завершён при недоступности DCS?

    Если DCS недоступен, проверка «доступны ли другие участники кластера ALL» выполняется каждый цикл цикла опроса состояния (каждые loop_wait секунд). Если под/узел завершается, проверка завершится неудачно, и PostgreSQL будет понижен до режима только для чтения и не восстановится до тех пор, пока DCS не будет восстановлен.

  • Что будет, если все участники кластера Patroni будут потеряны во время простоя DCS?

    Patroni может быть настроен на создание новой реплики из резервной копии даже тогда, когда кластер не имеет лидера. Однако, если новый участник отсутствует в ключе /failsafe, он не сможет получить блокировку лидера и произвести повышение.

  • Что произойдёт, если первичный сервер потеряет доступ к DCS, а реплики — нет?

    Первичный сервер выполнит код аварийной защиты и свяжется со всеми известными репликами. Эти реплики воспримут эту информацию как признак того, что первичный сервер работает, и не начнут выбор лидера, даже если блокировка лидера в DCS истекла.

  • Как включить отказоустойчивый режим?

    Перед включением failsafe_mode убедитесь, что версия Patroni на всех участниках обновлена. Затем вы можете использовать либо PATCH /config REST API , либо patronictl edit-config -s failsafe_mode=true

12 - Использование Patroni с Kubernetes

Использование Patroni с объектами Kubernetes, метками и обнаружением сервисов.

Patroni может использовать объекты Kubernetes для хранения состояния кластера и управления ключом лидера. Это позволяет работать с Postgres в среде Kubernetes без дополнительного хранилища согласованности, то есть не требуется запуск отдельного развёртывания etcd. Patroni может использовать два различных типа объектов Kubernetes для хранения ключей лидера и конфигурации, которые настраиваются с помощью переменной среды kubernetes.use_endpoints или PATRONI_KUBERNETES_USE_ENDPOINTS.


Используйте конечные точки

Несмотря на то что этот режим рекомендуется, по соображениям совместимости он отключён по умолчанию. Когда он включён, Patroni хранит конфигурацию кластера и ключ лидера в полях metadata: annotations соответствующих Endpoints, которые он создаёт. Смена лидера безопаснее, чем при использовании ConfigMaps, поскольку одновременно обновляются и аннотации, содержащие информацию о лидере, и фактические адреса, указывающие на запущенный под-лидер.


Используйте ConfigMaps

В этом режиме Patroni будет создавать ConfigMaps вместо Endpoints и хранить ключи внутри метаданных этих ConfigMaps. Смена лидера требует как минимум два обновления: одно — для ConfigMap лидера, другое — для соответствующего Endpoint.

Чтобы направить трафик на лидера Postgres, необходимо настроить сервис Postgres в Kubernetes для использования селектора меток с role_label (настроено в конфигурации Patroni).

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


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

Настройки Kubernetes для Patroni и переменные окружения описаны в общих главах документации.

Настройка метки роли

По умолчанию Patroni будет устанавливать соответствующие метки в поде, в котором выполняется, на основе роли узла, например role=primary. Ключ и значение метки можно настроить с помощью kubernetes.role_label, kubernetes.leader_label_value, kubernetes.follower_label_value и kubernetes.standby_leader_label_value.

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

  1. Добавьте временный метку, используя исходное значение роли, для пода с kubernetes.tmp_role_label (например, tmp_role). После перезапуска подов Patroni установит следующие метки:
labels:
  cluster-name: foo
  role: primary
  tmp_role: primary
  1. После обновления всех подов измените селектор сервиса так, чтобы он выбирал временный метку.
selector:
  cluster-name: foo
  tmp_role: primary
  1. Добавьте метку пользовательской роли (e.g, установите kubernetes.leader_label_value=primary). После перезапуска подов Patroni установит следующие новые метки:
labels:
  cluster-name: foo
  role: primary
  tmp_role: primary
  1. После того как все поды будут обновлены повторно, измените селектор сервиса для использования нового значения роли.
selector:
  cluster-name: foo
  role: primary
  1. Наконец, удалите временный метку из вашей конфигурации и обновите все поды.
labels:
  cluster-name: foo
  role: primary

Примеры

  • Папка kubernetes репозитория Patroni содержит примеры образа Docker и манифеста Kubernetes для тестирования настройки Patroni в Kubernetes. Примечание: в текущем состоянии невозможно использовать PersistentVolumes из-за проблем с разрешениями.
  • Полнофункциональный образ Docker, способный использовать PersistentVolumes, можно найти в проекте Spilo .
  • Также доступен Helm-чарт для развертывания образа Spilo, настроенного на работу с Patroni в Kubernetes.
  • Для масштабного развертывания кластеров баз данных с использованием Patroni и Spilo обратите внимание на проект postgres-operator . Он реализует паттерн оператора для управления кластерами Spilo.

13 - Поддержка Citus

Patroni сведения об интеграции для групп координаторов и рабов Citus.

Patroni делает развертывание кластеров Multi-Node Citus чрезвычайно простым.


TL;DR

Существует лишь несколько простых правил, которым необходимо следовать:

  1. Расширение базы данных Citus для PostgreSQL должно быть доступно на всех узлах. Абсолютно минимальная поддерживаемая версия Citus — 10.0, но для использования всех преимуществ прозрачных плановых переключений и перезапусков рабочих узлов рекомендуется как минимум Citus 11.2.
  2. Имя кластера (scope) должно быть одинаковым для всех узлов Citus!
  3. Учётные данные суперпользователя должны быть одинаковыми на координаторе и всех рабочих узлах, а pg_hba.conf должен разрешать доступ суперпользователя между всеми узлами.
  4. REST API доступ должен быть разрешён с узлов-работников к координатору. E.g, учётные данные должны быть одинаковыми, и, если настроены, клиентские сертификаты с узлов-работников должны быть приняты координатором.
  5. Добавьте следующий раздел в patroni.yaml:
citus:
  group: X  # 0 for coordinator and 1, 2, 3, etc for workers
  database: citus  # must be the same on all nodes

После этого вам нужно просто запустить Patroni, и он сам займётся остальным:

  1. Patroni установит bootstrap.dcs.synchronous_mode в quorum , если значение не задано явно другим образом.
  2. Расширение citus будет автоматически добавлено в shared_preload_libraries.
  3. Если max_prepared_transactions не задано явно в глобальной динамической конфигурации , Patroni автоматически установит его в 2*max_connections.
  4. Значение citus.local_hostname GUC будет скорректировано с localhost на значение, используемое Patroni для подключения к локальному экземпляру PostgreSQL. Значение иногда должно отличаться от localhost, поскольку PostgreSQL может не слушать на нём.
  5. Узел citus.database будет автоматически создан после CREATE EXTENSION citus.
  6. Текущие учётные данные суперпользователя credentials будут добавлены в таблицу pg_dist_authinfo для обеспечения взаимодействия между узлами. Не забудьте обновить их, если позже вы решите изменить имя пользователя/пароль/sslcert/sslkey суперпользователя!
  7. Координирующий первичный узел автоматически обнаружит рабочие первичные узлы и добавит их в таблицу pg_dist_node с использованием функции citus_add_node().
  8. Patroni также будет поддерживать pg_dist_node в случае переключения при отказе/планового переключения в координирующем или рабочем кластерах.

patronictl

Координаторские и рабочие кластеры — это физически разные кластеры PostgreSQL/Patroni, которые логически объединены с помощью расширения базы данных Citus для PostgreSQL. Следовательно, в большинстве случаев невозможно управлять ими как единым целым.

Это приводит к двум основным различиям в поведении patronictl при наличии секции patroni.yaml с citus по сравнению со стандартным поведением:

  1. Параметры list и topology по умолчанию выводят всех участников формирования Citus (координаторов и рабочих). Новая колонка Group указывает, к какой группе Citus они принадлежат.
  2. Для всех команд patronictl введён новый параметр, называемый --group. Для некоторых команд значение по умолчанию для группы может быть взято из patroni.yaml. Например, команда patronictl_pause по умолчанию включит режим обслуживания для group, указанного в секции citus , но, например, для patronictl_switchover или patronictl_remove группа должна быть указана явно.

Пример вывода patronictl_list для кластера Citus:

postgres@coord1:~$ patronictl list demo
+ Citus cluster: demo ----------+----------------+---------+----+-------------+-----+------------+-----+
| Group | Member  | Host        | Role           | State   | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------+---------+-------------+----------------+---------+----+-------------+-----+------------+-----+
|     0 | coord1  | 172.27.0.10 | Replica        | running |  1 |   0/41C0368 |   0 |  0/41C0368 |   0 |
|     0 | coord2  | 172.27.0.6  | Quorum Standby | running |  1 |   0/41C0368 |   0 |  0/41C0368 |   0 |
|     0 | coord3  | 172.27.0.4  | Leader         | running |  1 |             |     |            |     |
|     1 | work1-1 | 172.27.0.8  | Quorum Standby | running |  1 |   0/31D3198 |   0 |  0/31D3198 |   0 |
|     1 | work1-2 | 172.27.0.2  | Leader         | running |  1 |             |     |            |     |
|     2 | work2-1 | 172.27.0.5  | Quorum Standby | running |  1 |   0/31CDFC0 |   0 |  0/31CDFC0 |   0 |
|     2 | work2-2 | 172.27.0.7  | Leader         | running |  1 |             |     |            |     |
+-------+---------+-------------+----------------+---------+----+-------------+-----+------------+-----+

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

postgres@coord1:~$ patronictl list demo --group 0
+ Citus cluster: demo (group: 0, 7179854923829112860) -+-------------+-----+------------+-----+
| Member | Host        | Role           | State   | TL | Receive LSN | Lag | Replay LSN | Lag |
+--------+-------------+----------------+---------+----+-------------+-----+------------+-----+
| coord1 | 172.27.0.10 | Replica        | running |  1 |   0/41C0368 |   0 |  0/41C0368 |   0 |
| coord2 | 172.27.0.6  | Quorum Standby | running |  1 |   0/41C0368 |   0 |  0/41C0368 |   0 |
| coord3 | 172.27.0.4  | Leader         | running |  1 |             |     |            |     |
+--------+-------------+----------------+---------+----+-------------+-----+------------+-----+

postgres@coord1:~$ patronictl list demo --group 1
+ Citus cluster: demo (group: 1, 7179854923881963547) -+-------------+-----+------------+-----+
| Member  | Host       | Role           | State   | TL | Receive LSN | Lag | Replay LSN | Lag |
+---------+------------+----------------+---------+----+-------------+-----+------------+-----+
| work1-1 | 172.27.0.8 | Quorum Standby | running |  1 |   0/31D3198 |   0 |  0/31D3198 |   0 |
| work1-2 | 172.27.0.2 | Leader         | running |  1 |             |     |            |     |
+---------+------------+----------------+---------+----+-------------+-----+------------+-----+

Плановое переключение рабочего узла Citus

Когда для рабочего узла Citus выполняется плановое переключение, Citus позволяет сделать его практически прозрачным для приложения. Приложение подключается к координатору, а тот — к рабочим узлам, поэтому Citus может приостановить трафик SQL на координаторе для шардов, размещённых на рабочем узле. Затем плановое переключение выполняется, пока трафик удерживается на координаторе, и возобновляется, как только новый первичный рабочий узел будет готов принимать запросы на чтение и запись.

Пример patronictl_switchover на рабочем кластере:

postgres@coord1:~$ patronictl switchover demo
+ Citus cluster: demo ----------+----------------+---------+----+-------------+-----+------------+-----+
| Group | Member  | Host        | Role           | State   | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------+---------+-------------+----------------+---------+----+-------------+-----+------------+-----+
|     0 | coord1  | 172.27.0.10 | Replica        | running |  1 |   0/41C0368 |   0 |  0/41C0368 |   0 |
|     0 | coord2  | 172.27.0.6  | Quorum Standby | running |  1 |   0/41C0368 |   0 |  0/41C0368 |   0 |
|     0 | coord3  | 172.27.0.4  | Leader         | running |  1 |             |     |            |     |
|     1 | work1-1 | 172.27.0.8  | Leader         | running |  1 |             |     |            |     |
|     1 | work1-2 | 172.27.0.2  | Quorum Standby | running |  1 |   0/31D3198 |   0 |  0/31D3198 |   0 |
|     2 | work2-1 | 172.27.0.5  | Quorum Standby | running |  1 |   0/31CDFC0 |   0 |  0/31CDFC0 |   0 |
|     2 | work2-2 | 172.27.0.7  | Leader         | running |  1 |             |     |            |     |
+-------+---------+-------------+----------------+---------+----+-------------+-----+------------+-----+
Citus group: 2
Primary [work2-2]:
Candidate ['work2-1'] []:
When should the switchover take place (e.g. 2024-08-26T08:02 )  [now]:
Current cluster topology
+ Citus cluster: demo (group: 2, 7179854924063375386) -+-------------+-----+------------+-----+
| Member  | Host       | Role           | State   | TL | Receive LSN | Lag | Replay LSN | Lag |
+---------+------------+----------------+---------+----+-------------+-----+------------+-----+
| work2-1 | 172.27.0.5 | Quorum Standby | running |  1 |   0/31CDFC0 |   0 |  0/31CDFC0 |   0 |
| work2-2 | 172.27.0.7 | Leader         | running |  1 |             |     |            |     |
+---------+------------+----------------+---------+----+-------------+-----+------------+-----+
Are you sure you want to switchover cluster demo, demoting current primary work2-2? [y/N]: y
2024-08-26 07:02:40.33003 Successfully switched over to "work2-1"
+ Citus cluster: demo (group: 2, 7179854924063375386) --------+---------+------------+---------+
| Member  | Host       | Role    | State   | TL | Receive LSN |     Lag | Replay LSN |     Lag |
+---------+------------+---------+---------+----+-------------+---------+------------+---------+
| work2-1 | 172.27.0.5 | Leader  | running |  1 |             |         |            |         |
| work2-2 | 172.27.0.7 | Replica | stopped |    |     unknown | unknown |    unknown | unknown |
+---------+------------+---------+---------+----+-------------+---------+------------+---------+

postgres@coord1:~$ patronictl list demo
+ Citus cluster: demo ----------+----------------+---------+----+-------------+-----+------------+-----+
| Group | Member  | Host        | Role           | State   | TL | Receive LSN | Lag | Replay LSN | Lag |
+-------+---------+-------------+----------------+---------+----+-------------+-----+------------+-----+
|     0 | coord1  | 172.27.0.10 | Replica        | running |  1 |   0/41C0368 |   0 |  0/41C0368 |   0 |
|     0 | coord2  | 172.27.0.6  | Quorum Standby | running |  1 |   0/41C0368 |   0 |  0/41C0368 |   0 |
|     0 | coord3  | 172.27.0.4  | Leader         | running |  1 |             |     |            |     |
|     1 | work1-1 | 172.27.0.8  | Leader         | running |  1 |             |     |            |     |
|     1 | work1-2 | 172.27.0.2  | Quorum Standby | running |  1 |   0/31D3198 |   0 |  0/31D3198 |   0 |
|     2 | work2-1 | 172.27.0.5  | Leader         | running |  2 |             |     |            |     |
|     2 | work2-2 | 172.27.0.7  | Quorum Standby | running |  2 |   0/31CDFC0 |   0 |  0/31CDFC0 |   0 |
+-------+---------+-------------+----------------+---------+----+-------------+-----+------------+-----+

И так выглядит это со стороны координатора:

# The worker primary notifies the coordinator that it is going to execute "pg_ctl stop".
2024-08-26 07:02:38,636 DEBUG: query(BEGIN, ())
2024-08-26 07:02:38,636 DEBUG: query(SELECT pg_catalog.citus_update_node(%s, %s, %s, true, %s), (3, '172.19.0.7-demoted', 5432, 10000))
# From this moment all application traffic on the coordinator to the worker group 2 is paused.

# The old worker primary is assigned as a secondary.
2024-08-26 07:02:40,084 DEBUG: query(SELECT pg_catalog.citus_update_node(%s, %s, %s, true, %s), (7, '172.19.0.7', 5432, 10000))

# The future worker primary notifies the coordinator that it acquired the leader lock in DCS and about to run "pg_ctl promote".
2024-08-26 07:02:40,085 DEBUG: query(SELECT pg_catalog.citus_update_node(%s, %s, %s, true, %s), (3, '172.19.0.5', 5432, 10000))

# The new worker primary just finished promote and notifies coordinator that it is ready to accept read-write traffic.
2024-08-26 07:02:41,485 DEBUG: query(COMMIT, ())
# From this moment the application traffic on the coordinator to the worker group 2 is unblocked.

Вторичные узлы

Начиная с Patroni v4.0.0 вторичные узлы Citus без noloadbalance тега также регистрируются в pg_dist_node. Однако для использования вторичных узлов в запросах только для чтения приложениям необходимо изменить citus.use_secondary_nodes GUC.


Загляните в DCS

Кластер Citus (координатор и рабочие узлы) хранится в DCS в виде флота кластеров Patroni, логически объединённых вместе:

/service/batman/              # scope=batman
/service/batman/0/            # citus.group=0, coordinator
/service/batman/0/initialize
/service/batman/0/leader
/service/batman/0/members/
/service/batman/0/members/m1
/service/batman/0/members/m2
/service/batman/1/            # citus.group=1, worker
/service/batman/1/initialize
/service/batman/1/leader
/service/batman/1/members/
/service/batman/1/members/m3
/service/batman/1/members/m4
...

Такой подход был выбран потому, что для большинства DCS становится возможным получить весь кластер Citus с помощью одного рекурсивного запроса на чтение. Только координирующие узлы Citus читают всю дерево, поскольку им необходимо обнаружить рабочие узлы. Рабочие узлы читают только поддерево для собственной группы, а в некоторых случаях — поддерево группы координатора.


Citus на Kubernetes

Поскольку Kubernetes не поддерживает иерархические структуры, нам пришлось включить группу citus во все объекты K8s, которые создает Patroni:

batman-0-leader  # the leader config map for the coordinator
batman-0-config  # the config map holding initialize, config, and history "keys"
...
batman-1-leader  # the leader config map for worker group 1
batman-1-config
...

I.e., шаблон имён имеет вид: ${scope}-${citus.group}-${type}.

Patroni обнаруживает все объекты Kubernetes с помощью селектора меток , поэтому все Pods с Patroni&Citus, а также Endpoints/ConfigMaps должны иметь одинаковые метки, а Patroni необходимо настроить на их использование через параметры Kubernetes или environment variables <kubernetes_environment>.

Несколько примеров конфигурации Patroni с использованием переменных среды Pod:

  1. для кластера-координатора
apiVersion: v1
kind: Pod
metadata:
  labels:
    application: patroni
    citus-group: "0"
    citus-type: coordinator
    cluster-name: citusdemo
  name: citusdemo-0-0
  namespace: default
spec:
  containers:
  - env:
    - name: PATRONI_SCOPE
      value: citusdemo
    - name: PATRONI_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    - name: PATRONI_KUBERNETES_POD_IP
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: status.podIP
    - name: PATRONI_KUBERNETES_NAMESPACE
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
    - name: PATRONI_KUBERNETES_LABELS
      value: '{application: patroni}'
    - name: PATRONI_CITUS_DATABASE
      value: citus
    - name: PATRONI_CITUS_GROUP
      value: "0"
  1. для рабочего кластера из группы 2
apiVersion: v1
kind: Pod
metadata:
  labels:
    application: patroni
    citus-group: "2"
    citus-type: worker
    cluster-name: citusdemo
  name: citusdemo-2-0
  namespace: default
spec:
  containers:
  - env:
    - name: PATRONI_SCOPE
      value: citusdemo
    - name: PATRONI_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    - name: PATRONI_KUBERNETES_POD_IP
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: status.podIP
    - name: PATRONI_KUBERNETES_NAMESPACE
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
    - name: PATRONI_KUBERNETES_LABELS
      value: '{application: patroni}'
    - name: PATRONI_CITUS_DATABASE
      value: citus
    - name: PATRONI_CITUS_GROUP
      value: "2"

Как вы могли заметить, в обоих примерах установлен метка citus-group. Эта метка позволяет Patroni определять объект как принадлежащий определённой группе Citus. Кроме того, существует также переменная среды PATRONI_CITUS_GROUP, значение которой совпадает со значением метки citus-group. При создании новых объектов Kubernetes — ConfigMaps или Endpoints — Patroni автоматически добавляет им метку citus-group: ${env.PATRONI_CITUS_GROUP}:

apiVersion: v1
kind: ConfigMap
metadata:
  name: citusdemo-0-leader  # Is generated as ${env.PATRONI_SCOPE}-${env.PATRONI_CITUS_GROUP}-leader
  labels:
    application: patroni    # Is set from the ${env.PATRONI_KUBERNETES_LABELS}
    cluster-name: citusdemo # Is automatically set from the ${env.PATRONI_SCOPE}
    citus-group: '0'        # Is automatically set from the ${env.PATRONI_CITUS_GROUP}

Вы можете найти полный пример развёртывания Patroni на Kubernetes с поддержкой Citus в папке kubernetes репозитория Patroni.

Для вас существуют два важных файла:

  1. Dockerfile.citus
  2. citus_k8s.yaml

Обновление Citus и обновление PostgreSQL версии

Сначала ознакомьтесь с обновлением версии Citus в документации . В процессе имеется незначительное изменение. При выполнении обновления необходимо использовать patronictl_restart вместо systemctl restart для перезапуска PostgreSQL.

Обновление основной версии PostgreSQL с использованием Citus требует более сложных действий. Вам необходимо объединить методы, описанные в документации Citus по обновлению основных версий, и документации Patroni по PostgreSQL major upgrade<major_upgrade>. Учитывайте, что кластер Citus состоит из множества кластеров Patroni (координаторов и рабочих узлов), и каждый из них должен быть обновлён независимо.

14 - Преобразование отдельного экземпляра в кластер Patroni

Процедура преобразования существующих данных PostgreSQL в кластер Patroni.

В этом разделе описано преобразование отдельного экземпляра PostgreSQL в кластер Patroni.

Чтобы развернуть кластер Patroni без существующего экземпляра PostgreSQL, обратитесь к разделу Запуск и настройка .


Процедура

Ниже приведён обзор преобразования существующего кластера Postgres в кластер под управлением Patroni. Предполагается, что все узлы существующего кластера работают и во время миграции вы не намерены менять конфигурацию Postgres. Выполните следующие действия:

  1. Создайте пользователей Postgres, как описано в разделе аутентификации конфигурации Patroni. В блоке SQL ниже приведены примеры команд; замените имена пользователей и пароли в соответствии со своим окружением. Если необходимые пользователи уже существуют, пропустите этот шаг.

    -- Patroni superuser
    -- Replace PATRONI_SUPERUSER_USERNAME and PATRONI_SUPERUSER_PASSWORD accordingly
    CREATE USER PATRONI_SUPERUSER_USERNAME WITH SUPERUSER ENCRYPTED PASSWORD 'PATRONI_SUPERUSER_PASSWORD';
    
    -- Patroni replication user
    -- Replace PATRONI_REPLICATION_USERNAME and PATRONI_REPLICATION_PASSWORD accordingly
    CREATE USER PATRONI_REPLICATION_USERNAME WITH REPLICATION ENCRYPTED PASSWORD 'PATRONI_REPLICATION_PASSWORD';
    
    -- Patroni rewind user, if you intend to enable use_pg_rewind in your Patroni configuration
    -- Replace PATRONI_REWIND_USERNAME and PATRONI_REWIND_PASSWORD accordingly
    CREATE USER PATRONI_REWIND_USERNAME WITH ENCRYPTED PASSWORD 'PATRONI_REWIND_PASSWORD';
    GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO PATRONI_REWIND_USERNAME;
    GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO PATRONI_REWIND_USERNAME;
    GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO PATRONI_REWIND_USERNAME;
    GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO PATRONI_REWIND_USERNAME;
  2. Выполните следующие действия на всех узлах Postgres. Завершите все шаги на одном узле, прежде чем переходить к следующему. Начните с первичного узла, затем обработайте каждый резервный узел:

    1. Если Postgres запускается через systemd, отключите модуль systemd Postgres, поскольку запуском и остановкой демона Postgres будет управлять Patroni.
    2. Создайте файл конфигурации YAML Patroni. Для этого можно использовать средства создания и проверки конфигурации Patroni .
      • Примечание для первичного узла: если слоты репликации используются между участниками кластера, рекомендуется включить use_slots и настроить существующие слоты как постоянные через элемент конфигурации slots. При включённом use_slots Patroni автоматически создаёт слоты для репликации между участниками и удаляет неизвестные ему слоты. Постоянные слоты позволяют сохранить существующие слоты на время миграции к Patroni. Подробнее см. Параметры динамической конфигурации .
    3. Запустите Patroni с помощью модуля службы systemd patroni. Он автоматически обнаружит, что Postgres уже работает, и начнёт мониторинг экземпляра.
  3. Передайте Patroni процедуру запуска Postgres. Для этого перезапустите участников кластера командой patronictl restart cluster-name member-name . Чтобы свести простой к минимуму, можно разделить шаг на две части:

    1. Немедленный перезапуск резервных узлов.
    2. Запланированный перезапуск первичного узла в окно обслуживания.
  4. Если на шаге 1.2. настроены постоянные слоты, удалите их из конфигурации slots командой patronictl edit-config cluster-name , когда restart_lsn созданных Patroni слотов догонит restart_lsn исходных слотов соответствующих участников. После удаления слотов из конфигурации slots Patroni сможет удалить исходные слоты из кластера, когда они перестанут быть нужны. Ниже приведён пример запроса для сравнения restart_lsn пары слотов:

    -- Assume original_slot_for_member_x is the name of the slot in your original
    -- cluster for replicating changes to member X, and slot_for_member_x is the
    -- slot created by Patroni for that purpose. You need restart_lsn of
    -- slot_for_member_x to be >= restart_lsn of original_slot_for_member_x
    SELECT slot_name,
           restart_lsn
    FROM pg_replication_slots
    WHERE slot_name IN (
        'original_slot_for_member_x',
        'slot_for_member_x'
    )

Обновление основной версии PostgreSQL

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

  1. Остановите Patroni
  2. Обновите двоичные файлы PostgreSQL и выполните pg_upgrade на первичном узле
  3. Обновите patroni.yml
  4. Удалите ключ initialize из DCS либо полностью очистите состояние кластера в DCS. Второй вариант выполняется командой patronictl remove cluster-name . Это необходимо, поскольку pg_upgrade запускает initdb, фактически создающий новую базу данных с новым системным идентификатором PostgreSQL.
  5. Если на предыдущем шаге состояние кластера очищено, можно скопировать patroni.dynamic.json из старого каталога данных в новый. Это поможет сохранить некоторые ранее заданные параметры PostgreSQL.
  6. Запустите Patroni на первичном узле.
  7. Обновите двоичные файлы PostgreSQL и patroni.yml, затем очистите data_dir на резервных узлах.
  8. Запустите Patroni на резервных узлах и дождитесь завершения репликации.

PostgreSQL не поддерживает запуск pg_upgrade на резервных узлах. Если вы уверены в своих действиях, вместо очистки data_dir можно попробовать процедуру rsync, описанную в https://www.postgresql.org/docs/current/pgupgrade.html . Однако безопаснее всего позволить Patroni реплицировать данные.


Часто задаваемые вопросы

  • При запуске Patroni сообщает, что не может привязаться к порту PostgreSQL.

    Проверьте listen_addresses и port в postgresql.conf, а также postgresql.listen в patroni.yml. Не забудьте, что pg_hba.conf должен разрешать такой доступ.

  • После запроса Patroni на перезапуск узла PostgreSQL выводит ошибку could not open configuration file "/etc/postgresql/10/main/pg_hba.conf": No such file or directory

    Значение зависит от способа управления конфигурацией PostgreSQL. Если указан postgresql.config_dir, Patroni создаёт pg_hba.conf по параметрам раздела bootstrap только при начальной инициализации нового кластера. В этом сценарии PGDATA не был пуст, поэтому инициализация не выполнялась. Файл должен существовать заранее.

15 - Интеграция с другими инструментами

Интеграция Patroni с внешними инструментами резервного копирования и оркестрации.

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


Barman

Patroni предоставляет приложение с именем patroni_barman, в котором реализована логика взаимодействия с pg-backup-api, что позволяет выполнять операции Barman удалённо.

У данного приложения в настоящее время имеется несколько подкоманд: recover и config-switch.

patroni_barman восстановить

Подкоманда recover может использоваться в качестве пользовательской процедуры начальной инициализации или пользовательского метода создания реплики. Дополнительную информацию об этом см. в replica_imaging_and_bootstrap .

patroni_barman config-switch

Подкоманда config-switch предназначена для использования в качестве обратного вызова on_role_change в Patroni. Например, предположим, что вы передаёте WAL-логи с текущего первичного сервера на хост Barman. В случае переключения при отказе в кластере вы можете захотеть начать передачу WAL-логов с нового первичного сервера. Это можно реализовать, используя patroni_barman config-switch в качестве on_role_change обратного вызова.

Примечание

Эта подкоманда зависит от команды barman config-switch, отвечающей за переопределение конфигурации сервера Barman путём применения заранее определённой модели поверх текущей конфигурации. Эта команда доступна начиная с Barman 3.10. Дополнительные сведения см. в документации Barman.

Вот пример того, как можно настроить Patroni для применения модели конфигурации в случае повышения данного узла до первичного сервера:

postgresql:
    callbacks:
        on_role_change: >
            patroni_barman
                --api-url YOUR_API_URL
                config-switch
                --barman-server YOUR_BARMAN_SERVER_NAME
                --barman-model YOUR_BARMAN_MODEL_NAME
                --switch-when promoted
Примечание

patroni_barman config-switch требует, чтобы на хосте Barman были настроены как Barman, так и pg-backup-api, чтобы можно было выполнить удалённую barman config-switch через резервную копию API. Кроме того, требуется, чтобы были предварительно настроены модели Barman для применения. В приведённом примере используется подмножество доступных параметров. Дополнительную информацию можно получить, выполнив patroni_barman config-switch --help, а также, ознакомившись с документацией Barman.

16 - Аспекты безопасности

Вопросы безопасности для DCS, REST API и обработка учетных данных.

Кластер Patroni имеет два интерфейса, которые необходимо защитить от несанкционированного доступа: хранилище распределённой конфигурации (DCS) и REST API Patroni (REST) (API).


Защита DCS

Patroni и patronictl хранят и извлекают данные из DCS.

Несмотря на то что DCS не содержит никакой конфиденциальной информации, он позволяет изменять часть конфигурации Patroni/Postgres. Поэтому первым делом необходимо защитить DCS.

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

Общая рекомендация заключается в том, чтобы включать TLS для всех сообщений DCS.


Защита REST API

Защита REST API представляет собой более сложную задачу.

Patroni REST API используется самим Patroni во время выбора лидера, инструментом patronictl для выполнения переключений при отказе, плановых переключений, повторной инициализации, перезапуска и перезагрузки, HAProxy или любым другим балансировщиком нагрузки для выполнения проверок работоспособности HTTP, а также, разумеется, может использоваться для мониторинга.

С точки зрения безопасности, REST API содержит безопасные (запросы GET, только извлечение информации) и небезопасные (запросы PUT, POST, PATCH и DELETE, изменяющие состояние узлов) конечные точки.

Небезопасные конечные точки могут быть защищены с помощью базовой аутентификации HTTP путём установки параметров restapi.authentication.username и restapi.authentication.password. Невозможно защитить безопасные конечные точки без включения TLS.

Когда TLS для REST API включён и установлено соединение PKI, взаимная аутентификация сервера API и клиента API возможна для всех конечных точек.

Параметры раздела restapi включают аутентификацию клиента на сервере по TLS. В зависимости от значения параметра verify_client сервер API требует успешной проверки сертификата клиента для безопасных и небезопасных вызовов API (verify_client: required), только для небезопасных вызовов API (verify_client: optional) либо не требует её ни для каких вызовов API (verify_client: none).

Параметры раздела ctl позволяют серверу TLS аутентифицировать клиента (инструмент patronictl , использующий тот же конфигурационный файл, что и Patroni). Установите insecure: true для отключения проверки сертификата сервера клиентом. Подробное описание параметров TLS клиента см. в настройках .

Защита базы данных PostgreSQL от несанкционированного доступа выходит за рамки настоящего документа и рассматривается в https://www.postgresql.org/docs/current/client-authentication.html

17 - HA-кластер с несколькими центрами обработки данных

Многоцентровые схемы обеспечения высокой доступности с репликацией Patroni.

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

В обоих случаях важно четко понимать следующие понятия:

  • PostgreSQL может работать в качестве первичного сервера или резервного сервера-лидера только тогда, когда он владеет ключом лидера и может обновлять этот ключ.
  • Рекомендуется запускать нечётное количество узлов etcd, ZooKeeper или Consul: 3 или 5!

Синхронная репликация

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

Схема архитектуры будет следующей:

образ

Необходимо развернуть кластер etcd, ZooKeeper или Consul через разные зоны доступности, с минимальным количеством 3 узлов, по одному в каждой зоне.

Что касается postgres, необходимо развернуть не менее 2 узлов в разных ЦОД. Затем следует задать synchronous_mode: true в глобальной динамической конфигурации .

Это включает синхронную репликацию, при этом первичный сервер выберет один из узлов в качестве синхронного.


Асинхронная репликация

При наличии только двух центров обработки данных предпочтительнее иметь два независимых кластера etcd и запускать в втором центре обработки данных резервный сервер Patroni standby cluster . Если первый сайт выйдет из строя, вы можете MANUALLY вручную повысить привилегии standby_cluster .

Схема архитектуры будет следующей:

образ

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

В этом сценарии следует не использовать pg_ctl promote, необходимо вручную повысить приоритет работоспособного кластера, удалив раздел standby_cluster из динамической конфигурации .

Предупреждение

Если исходный кластер по-прежнему работает, а вы повышаете резервный сервер до основного, возникает состояние split-brain.

В случае, если вы хотите вернуться в «исходное» состояние, существует только два способа его устранения:

  • Добавьте секцию standby_cluster обратно — это вызовет pg_rewind; однако для корректной работы pg_rewind кластер должен быть инициализирован с использованием data page checksums (опция --data-checksums для initdb) и/или значение wal_log_hints должно быть установлено в on, но даже при этом возможны случаи сбоя pg_rewind из-за других факторов.
  • Перестройте резервный сервер с нуля.

Перед повышением резервного сервера в кластере необходимо вручную убедиться, что исходный кластер выключен (STONITH). Когда DC1 восстановится, кластер должен быть преобразован в резервный сервер.

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

После извлечения вы также можете вручную применить эти изменения к кластеру в DC2.

18 - Часто задаваемые вопросы

Часто задаваемые вопросы об эксплуатации Patroni и устранении неполадок.

В этом разделе приведены ответы на самые частые вопросы о Patroni. Каждый подраздел посвящён отдельной категории вопросов.

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


Сравнение с другими решениями HA

Почему Patroni требует отдельный кластер узлов DCS, а другие решения наподобие repmgr — нет?
Решения HA можно реализовать разными способами, каждый со своими преимуществами и недостатками.

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

Patroni, напротив, опирается на состояние в DCS. Для Patroni DCS служит источником истины при выборе действий.

Отдельный кластер DCS усложняет архитектуру, но снижает вероятность расщепления кластера Postgres.

Чем Patroni отличается от других решений HA в управлении Postgres?
Patroni управляет не только высокой доступностью кластера Postgres, но и самим Postgres.

Если узлов Postgres ещё нет, Patroni выполняет начальную инициализацию первичного и резервных узлов и управляет их конфигурацией Postgres. Если узлы уже существуют, Patroni принимает управление кластером.

Кроме того, Patroni поддерживает самовосстановление. При отказе первичного узла он не только переключается на реплику, но и пытается присоединить прежний первичный узел как реплику нового. Аналогично, при отказе реплики Patroni пытается присоединить её снова.

Поэтому Patroni называется «шаблоном решений HA». Он не ограничивается управлением физической репликацией, а управляет Postgres целиком.


DCS

Можно ли использовать один кластер etcd для данных двух или нескольких кластеров Patroni?
Да.

Сведения о кластере Patroni хранятся в DCS по пути с префиксом из параметров Patroni namespace и scope.

Пока сочетания namespace и scope разных кластеров Patroni не конфликтуют, один кластер DCS может хранить сведения о нескольких кластерах Patroni.

Что произойдёт при использовании одного сочетания namespace и scope разными кластерами Patroni, подключёнными к одному DCS?
Второй кластер Patroni не сможет управлять Postgres: в DCS уже будут сведения с тем же сочетанием, но несовместимым системным идентификатором Postgres. Из-за несовпадения Patroni прекращает управление вторым кластером, считая его другим кластером и конфигурацию пользователя ошибочной.

Для разных кластеров Patroni с общим DCS обязательно используйте разные namespace / scope.

Что произойдёт при потере кластера DCS?
DCS в основном хранит состояние и динамическую конфигурацию кластера Patroni.

Первое последствие: все зависящие от этого DCS кластеры Patroni переходят в режим только для чтения, если не включён dcs_failsafe_mode .

Что делать при потере кластера DCS?
Возможны три исхода:

  1. Кластер DCS полностью восстановлен: действия со стороны Patroni не требуются. После восстановления DCS Patroni также должен восстановиться;
  2. Кластер DCS пересоздан на прежнем месте с теми же конечными точками. Изменения со стороны Patroni не требуются;
  3. Создан новый кластер DCS с другими конечными точками. Нужно обновить конечные точки DCS в конфигурации каждого узла Patroni.

В сценарии 2. или 3. Patroni заново создаёт сведения о состоянии по текущему состоянию кластера и восстанавливает динамическую конфигурацию в DCS из резервного файла patroni.dynamic.json, хранящегося в каталоге данных Postgres каждого участника.

Что произойдёт при потере большинства в кластере DCS?
DCS перестанет отвечать, и Patroni понизит текущий узел Postgres для чтения и записи.

Помните: при действиях с кластером Patroni опирается на состояние DCS.

Ситуацию можно смягчить с помощью dcs_failsafe_mode .


patronictl

Нужно ли запускать patronictl на узле Patroni?
Нет.

Запускать patronictl на узле Patroni удобно при наличии доступа: приложение patronictl может использовать тот же файл конфигурации, что и агент patroni.

Однако patronictl является клиентом и может запускаться на удалённых машинах. Достаточно настроить ему доступ к DCS и REST API участников Patroni.

Почему сведения об одном участнике Patroni исчезли из вывода команды patronictl_list ?
Вывод patronictl_list основан на содержимом DCS.

Если сведения об участнике исчезли из DCS, вероятнее всего агент Patroni на этом узле больше не работает или не может связаться с DCS.

Поскольку участник не обновляет сведения, они в итоге истекают в DCS, и участник больше не показывается в выводе patronictl_list .

Почему сведения об одном участнике Patroni в выводе команды patronictl_list неактуальны?
Вывод patronictl_list основан на содержимом DCS.

По умолчанию Patroni обновляет эти сведения примерно каждые loop_wait секунд. Даже при нормальной работе данные в DCS могут «задерживаться» до loop_wait секунд.

Однако это не строгое правило: некоторые операции Patroni немедленно обновляют сведения в DCS.


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

Чем различаются динамическая и локальная конфигурации?
Динамическая, или глобальная, конфигурация хранится в DCS и применяется ко всем участникам кластера Patroni. В основном конфигурацию следует хранить именно там.

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

Подробнее см. в разделе конфигурация .

Какие типы конфигурации есть в Patroni и каков их приоритет?
Доступны следующие типы:

  • Динамическая конфигурация: применяется ко всем участникам;
  • Локальная конфигурация: применяется к локальному участнику и переопределяет динамическую;
  • Конфигурация окружения: применяется к локальному участнику и переопределяет динамическую и локальную конфигурации.

Примечание: некоторые GUC Postgres можно задать только глобально, то есть через динамическую конфигурацию. Кроме того, для части GUC Patroni принудительно устанавливает жёстко заданное значение.

Подробнее см. в разделе конфигурация .

Есть ли средство для создания файла конфигурации Patroni?
Да.

Команды patroni --generate-sample-config и patroni --generate-config создают соответственно пример конфигурации Patroni и конфигурацию на основе существующего экземпляра Postgres.

Подробнее см. generate_sample_config и generate_config .

Я изменил параметры в bootstrap.dcs, но Patroni не применяет их к участникам. В чём проблема?
Значения bootstrap.dcs используются только при начальной инициализации нового кластера и записываются в DCS во время неё.

После завершения начальной инициализации динамическую конфигурацию можно изменять только через DCS.

Подробнее см. следующий вопрос.

Как изменить динамическую конфигурацию?
Нужно изменить конфигурацию в DCS одним из способов:

Как изменить локальную конфигурацию?
Измените файл конфигурации соответствующего участника Patroni и отправьте агенту Patroni сигнал SIHGUP. Это можно сделать одним из способов:

  • отправить запрос POST к REST API reload_endpoint ; либо

  • выполнить patronictl_reload ; либо

  • локально отправить процессу Patroni сигнал SIGHUP:

    • Если Patroni запущен через systemd, используйте systemctl reload PATRONI_UNIT.service, где PATRONI_UNIT — имя службы Patroni; либо
    • Если Patroni запущен иначе, найдите процесс patroni и выполните kill -s HUP PID, где PID — идентификатор процесса patroni.

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

  • Истёкшие сертификаты REST API: проблему можно смягчить параметром -k команды patronictl ;
  • Неверные учётные данные: например, когда в файле конфигурации изменены учётные данные restapi или ctl, а один файл используется для Patroni и patronictl .

Как изменить конфигурацию окружения?
Patroni читает конфигурацию окружения только при запуске.

Поэтому после изменения конфигурации окружения соответствующий агент Patroni необходимо перезапустить.

Не допустите переключения при отказе в кластере. Возможно, пригодится patronictl_pause .

Как сократить повторяющиеся строки сигналов активности в журнале при нормальной работе?

Если журнал засорён повторяющимися строками наподобие Lock owner: ... и no action. I am ..., задайте log.deduplicate_heartbeat_logs: true.

Параметр задаётся в файле YAML Patroni (настройки журнала ) либо через PATRONI_LOG_DEDUPLICATE_HEARTBEAT_LOGS=true.

Это уменьшает объём журнала, подавляя повторные сообщения активности, но также убирает видимость сигналов каждой итерации, полезную при диагностике переключения.

Что произойдёт при изменении GUC Postgres, требующего перезагрузки конфигурации?
При изменении динамической или локальной конфигурации описанным выше способом Patroni сам перезагрузит конфигурацию Postgres.

Что произойдёт при изменении GUC Postgres, требующего перезапуска?
Patroni отметит затронутых участников флагом pending restart.

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

Примечание: некоторые GUC Postgres требуют особого порядка перезапуска узлов. Подробнее см. shared_memory_gucs .

Чем различаются etcd и etcd3 в конфигурации Patroni?
etcd использует API версии 2 etcd, а etcd3 — API версии 3 etcd.

Сведениями, сохранёнными через API версии 2, нельзя управлять через API версии 3, и наоборот.

Рекомендуется настраивать etcd3 вместо etcd, поскольку:

  • API версии 2 по умолчанию отключён начиная с Etcd v3.4;
  • API версии 2 будет полностью удалён в Etcd v3.6.

В конфигурации Patroni включён use_slots, но когда участник некоторое время находится вне сети, его слот репликации удаляется на вышестоящем узле. Как этого избежать?
Доступны два варианта:

  1. Настроить member_slots_ttl (по умолчанию 30min, доступно начиная с Patroni 4.0.0 и PostgreSQL 11). Слоты отсутствующих участников не удаляются, если простой короче заданного порога.
  2. Настроить для участников постоянные физические слоты репликации.

Начиная с Patroni 3.2.0 слоты участников могут быть постоянными слотами под управлением Patroni.

Patroni создаёт постоянные физические слоты на всех узлах, не удаляет их и продвигает LSN слотов на всех узлах в соответствии с LSN, использованным участником.

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

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

Примечание: даже в Patroni 3.2.0 возможна небольшая гонка. Сразу после создания слот на реплике может опережать тот же слот лидера, а если слот никто не использует, после переключения часть файлов может отсутствовать. Поэтому рекомендуется настроить непрерывное архивирование, позволяющее восстановить необходимые WAL или выполнить PITR.

Чем различаются loop_wait, retry_timeout и ttl?
Patroni периодически выполняет так называемый цикл HA. В каждом цикле он проверяет работоспособность кластера и в зависимости от состояния может предпринимать действия, например переключаться на резервный сервер.

loop_wait определяет в секундах, сколько Patroni ждёт до следующего цикла проверок HA.

retry_timeout задаёт тайм-аут повторных операций с DCS и Postgres. Например, если DCS не отвечает более retry_timeout секунд, Patroni может в целях безопасности понизить первичный узел.

ttl задаёт срок аренды блокировки leader в DCS. Если текущий лидер не может обновить аренду в циклах HA дольше ttl, аренда истекает и запускает в кластере leader race.

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


Управление Postgres

Можно ли менять GUC Postgres непосредственно в конфигурации Postgres?
Можно, но этого следует избегать.

Конфигурацией Postgres управляет Patroni, поэтому попытки редактировать файлы могут оказаться бесполезными: Patroni способен их перезаписать.

Управление Patroni можно обойти несколькими способами:

  • изменять GUC Postgres через $PGDATA/postgresql.base.conf; либо
  • определить postgresql.custom_conf, используемый вместо postgresql.base.conf, и управлять им извне; либо
  • изменять GUC с помощью ALTER SYSTEM / ALTER DATABASE / ALTER USER.

Подробнее см. раздел important_configuration_rules .

В любом случае рекомендуется управлять всей конфигурацией Postgres через Patroni. Это централизует управление и упрощает отладку Patroni.

Можно ли перезапускать узлы Postgres напрямую?
Нет, не следует пытаться управлять Postgres напрямую.

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

Управляйте сервером Postgres только предоставленными Patroni способами.

Может ли Patroni принять управление существующим кластером Postgres?
Да.

Подробные инструкции приведены в existing_data .

Как Patroni управляет Postgres?
Patroni запускает и останавливает Postgres, выполняя двоичные файлы Postgres, такие как pg_ctl и postgres.

Поэтому ОБЯЗАТЕЛЬНО отключите все другие средства управления кластерами Postgres, например модули systemd вроде postgresql.service. Только Patroni должен запускать, останавливать и повышать экземпляры Postgres в кластере. Иначе возможно расщепление: например, если первичный узел отказал, включённый модуль postgresql.service может снова запустить Postgres и вызвать расщепление.


Концепции и требования

Какие приложения входят в Patroni?
Patroni поставляет два основных приложения:

  • patroni: агент Patroni, управляющий узлом Postgres;
  • patronictl : утилита командной строки для взаимодействия с кластером Patroni — плановых переключений, перезапусков, изменений конфигурации и т. д. Подробнее см. patronictl .

Что такое standby cluster в Patroni?
Это кластер без работающего первичного узла Postgres, то есть без участника для чтения и записи.

Такие кластеры реплицируют данные из другого кластера и обычно полезны для репликации между центрами обработки данных.

Лидером кластера является резервный сервер, реплицирующий изменения с удалённого узла Postgres. Остальные резервные серверы настраиваются на каскадную репликацию от этого лидера.

Примечание: резервный кластер ничего не знает об исходном кластере, с которого реплицируется. Он может использовать restore_command вместо потоковой передачи WAL и совершенно независимый кластер DCS.

Подробнее см. standby_cluster .

Что такое leader в Patroni?
leader в Patroni — своего рода координатор кластера.

В обычном кластере Patroni leader является узлом для чтения и записи.

В резервном кластере Patroni leader, также называемый standby leader, реплицирует данные с удалённого узла Postgres и каскадно передаёт изменения остальным участникам резервного кластера.

Требует ли Patroni минимального количества узлов Postgres в кластере?
Нет, Patroni может работать с любым количеством узлов Postgres.

Помните: Patroni отделён от DCS.

Что означает пауза в Patroni?
Пауза — операция Patroni, позволяющая пользователю временно ослабить управление Postgres.

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

Подробнее см. пауза .


Автоматическое переключение при отказе

Как работает механизм автоматического переключения Patroni?
Автоматическое переключение Patroni основано на механизме leader race.

Patroni хранит состояние кластера в DCS, включая блокировку leader с именем участника Patroni, являющегося текущим leader кластера.

Блокировка leader имеет срок жизни. Если узел leader не обновляет её аренду вовремя, ключ в итоге истекает в DCS.

Истечение блокировки leader запускает leader race: все узлы выполняют проверки, определяя лучшего кандидата на роль leader. Часть проверок включает обращения к REST API всех остальных участников Patroni.

Все участники Patroni, считающие себя лучшим кандидатом, пытаются получить блокировку leader. Первый получивший блокировку leader участник повышает себя до узла чтения и записи либо standby leader, а остальные настраиваются следовать за ним.

Можно ли временно отключить автоматическое переключение в кластере Patroni?
Да.

Для этого временно приостановите кластер. Обычно это полезно при обслуживании.

Чтобы возобновить автоматическое переключение, снимите кластер с паузы.

Подробнее см. пауза .


Начальная инициализация и создание резервных серверов

Как Patroni создаёт первичный и резервный узлы Postgres?
По умолчанию Patroni использует initdb для начальной инициализации нового кластера и pg_basebackup для создания резервных узлов из копии участника leader.

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

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

Подробнее см. custom_bootstrap и custom_replica_creation .


Мониторинг

Как отслеживать кластер Patroni?
Patroni предоставляет несколько удобных конечных точек в rest_api :

  • /metrics: предоставляет метрики мониторинга в формате для Prometheus;
  • /patroni: предоставляет состояние кластера в формате JSON. Сведения очень похожи на вывод конечной точки /metrics.

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

19 - Примечания к выпускам

Хронологические примечания к выпускам Patroni и история изменений.


Версия 4.1.5

Выпущено 2026-08-12

Улучшения совместимости

  • Совместимость с PostgreSQL 14.24, 15.19, 16.15, 17.11, 18.6 (Alexander Kukushkin)

    Добавьте новый output_plugin_libraries GUC, который ограничивает вывод плагинов логического декодирования.

Улучшения

  • Записывать REST предупреждения о сбросе API соединений в DEBUG вместо WARNING (Kyle McLaren)

    Убедитесь, что распространенные варианты “клиент неожиданно завершил операцию записи” не влияют на обработку реальных (не связанных с соединением) ошибок.

Исправления ошибок

  • Исправить выравнивание при проверке thread_stack_size (Sundong Kim)

    Исправьте значение aligned из 65535 в 65536 в записи схемы thread_stack_size. Ранее, patroni --validate-config отклонял практически каждое реалистичное значение, включая значение по умолчанию, применяемое самим демоном 524288.

  • Предоставьте возможность проверки synchronous_mode для принятия 'quorum' и строковых значений, похожих на булевы (Eray Araz)

    patroni --validate-config ранее отклонял значения synchronous_mode, такие как quorum, и строковые представления булевых значений, принятые во время выполнения.

Версия 4.1.4

Выпущено 2026-07-07

Исправления ошибок

  • Проверьте переменную окружения NOTIFY_SOCKET перед использованием пакета systemd (Polina Bungina)

    Попытайтесь импортировать и использовать пакет только тогда, когда переменная окружения NOTIFY_SOCKET установлена, чтобы избежать исключения FileNotFoundError: [Errno 2] No such file or directory.

  • Объединить pg_replication_slots запрос (Polina Bungina)

    Неправильная обработка значений failover и synced приводила к возникновению исключений KeyError при удалении неверных слотов логической репликации.

  • Рассмотрите параметры аутентификации, специфичные для версии, при создании конфигурации (Polina Bungina)

    В команде patroni --generate-config, удалите все не относящиеся к делу параметры аутентификации, которые были случайно получены из окружения, на основе версии, полученной от соединения с PostgreSQL.

  • Обрабатывать pg_rewind во время запуска экземпляра PostgreSQL в качестве резервного сервера (Alexander Kukushkin)

    Использовать информацию pg_controldata в случае, когда экземпляр PostgreSQL работает, но еще не принимает соединения.

  • Исправить тип метрики Prometheus для patroni_postgres_timeline (Huseyin Demir)

    Объявить метрику patroni_postgres_timeline как gauge вместо counter, поскольку она не всегда возрастает монотонно (e.g., может сбрасываться в 0, если экземпляр PostgreSQL не запущен).

  • Не останавливайте сторожевой таймер, пока все клиентские бэкенды не будут полностью остановлены (Alexander Kukushkin)

    Ранее, если primary_stop_timeout был меньше минимального тайм-аута сторожевого таймера, и тайм-аут остановки фактически истек, Patroni отключал сторожевой таймер до того, как все клиентские бэкенды завершились.

  • Обработка ошибки превышения времени ожидания для запроса мониторинга (Alexander Kukushkin)

    В случае возникновения ошибки превышения таймаута, используйте кэшированную роль в качестве резервного варианта, чтобы избежать понижения первичного сервера. Кроме того, принудительно установите pg_stat_statements.track в none для запроса мониторинга, чтобы избежать дорогостоящих операций сборки мусора pg_stat_statements.

  • Удаление слотов репликации, управляемых Patroni с wal_status=lost (Alexander Kukushkin)

    Слоты репликации с wal_status=lost больше не используются. Patroni теперь удаляет такие слоты и создает их заново при необходимости.

  • Исправить представление роли в ошибке проверки участника в patronictl (Polina Bungina)

    Обеспечивает использование правильного строкового представления в сообщении об исключении, предотвращая форматирование ошибок в соответствии с Error: No CtlPostgresqlRole.REPLICA among provided members.

Версия 4.1.3

Выпущено 2026-05-05

Повышение стабильности

  • Правильно обрабатывать ошибки etcd с неправильной меткой (Ants Aasma)

    Текущие версии etcd выдают ошибку Unknown, когда лидер etcd теряется во время обновления аренды. Patroni теперь переопределяет отчётный код ошибки на Unavailable.

Исправления ошибок

  • Используйте двоичную версию, когда файл PG_VERSION отсутствует (Polina Bungina)

    В некоторых случаях, например, при использовании пользовательской начальной инициализации, файл PG_VERSION может отсутствовать в каталоге данных. В этом случае Patroni считал версию равной 0.0, что приводило к проблемам с логикой, специфичной для определенной версии. С этой поправкой Patroni будет пытаться получить версию из бинарного файла в таких случаях.

  • Переработать инициализацию логгера, чтобы избежать пропущенных ранних сообщений (Alexander Kukushkin)

    Создайте PatroniLogger до загрузки Config для захвата ранних сообщений в логах.

  • Включите MONOTONIC_USEC в уведомление systemd RELOADING=1 (Alexander Kukushkin)

    systemd 257+ требует MONOTONIC_USEC вместе с RELOADING=1 для Type=notify-reload служб. Без этого systemctl reload висит бесконечно.

Улучшения

  • Пропускать восстановление после сбоя для одного пользователя, когда backup_label присутствует (Vadim Ponomarev)

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

  • Предупреждать при работе под systemd без пакета python-systemd (Alexander Kukushkin)

    Вместо ведения журнала “интеграция с systemd не поддерживается” при запуске, проверьте NOTIFY_SOCKET и выдавайте предупреждение только тогда, когда система фактически работает под systemd без установленного пакета python-systemd.

Версия 4.1.2

Выпущено 2026-04-21

Улучшения поддержки systemd

  • Добавить поддержку типа системного юнита notify-reload (Ronan Dunklau)

    Позволяет systemctl reload дождаться, пока Patroni фактически обработает перезагрузку конфигурации, отправляя уведомления RELOADING=1 и READY=1 в systemd.

  • Отправить уведомление STOPPING=1 в systemd при завершении работы (Alexander Kukushkin)

    Patroni теперь правильно уведомляет systemd о завершении работы, следуя протоколу systemd notify.

  • Не позволяйте PostgreSQL отправлять уведомления systemd (Alexander Kukushkin)

    Удалите NotifyAccess=all из примера файла юнита systemd. Фильтруйте NOTIFY_SOCKET из переменных окружения при запуске PostgreSQL, чтобы оно не отправляло READY=1 или STOPPING=1 в systemd. При переходе к PostgreSQL, который был запущен до Patroni и уже имеет NOTIFY_SOCKET, повторно установите READY=1 при завершении PostgreSQL, чтобы нейтрализовать его STOPPING=1.

Версия 4.1.1

Выпущено 2026-04-08

Повышение стабильности

  • Совместимость с изменениями в многопоточности в Python 3.11+ (Alexander Kukushkin)

    Избегайте запуска/остановки потоков во время выполнения. Используйте пулы потоков для REST API и для выполнения асинхронных задач. Предусмотрите возможность настройки глобальных thread_pool_size и restapi.thread_pool_size.

  • Совместимость с python 3.14 (Alexander Kukushkin)

    Выполните тесты против python 3.14 и устраните проблемы совместимости.

  • Совместимость с исправлениями безопасности etcd в v3.6.9, v3.5.28 и v3.4.42 (Alexander Kukushkin)

    Эти релизы etcd устранили уязвимости и изменили поведение, так что чтение топологии кластера и поддержание активности арен не разрешены без аутентификации. Patroni теперь обрабатывает это, аутентифицируя в путях обнаружения участников и поддержания активности арен, повторно аутентифицируя при неудачах аутентификации и соответствующим образом повторяя запросы.

  • Улучшения обработки ошибок в Etcd3 (Alexander Kukushkin)

    Обрабатывать недействительные ответы JSON, обеспечивать гибкость в парсинге ошибок JSON, и улучшать отчетность об внутренних ошибках etcd.

Исправления ошибок

  • Повторить обновление лидера при временной ошибке в Kubernetes 403 (Sophia Ruan, Alexander Kukushkin)

    Когда узел Kubernetes API временно возвращается 403 Permission Denied (например, во время временных проблем RBAC), Patroni теперь проверяет, по-прежнему ли текущий узел является лидером, и повторяет попытку обновления лидера в течение retry_timeout, а не немедленно понижает его.

  • Устранить проблему с переименованием узла-лидера в режиме синхронизации и паузы (Alexander Kukushkin)

    /sync ключ не был обновлён после переименования узла-лидера с перезапуском Patroni в режиме паузы (без перезапуска Postgres). Это препятствовало продвижению Patroni после следующего перезапуска без паузы.

  • Запускать проверку pg_rewind при увеличении временной шкалы первичным сервером (Alexander Kukushkin)

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

  • Указывайте только пароль суперпользователя во время initdb начальной инициализации, если он не пуст (Michael Banck)

    Указание пустого пароля в процессе initdb начальной инициализации вызывало проблемы.

  • Исправить ошибку, связанную с failover_priority, используя synchronous_mode=on (Alexander Kukushkin)

    значения tag.failover_priority игнорировались, когда synchronous_node_count > 1.

  • Исправить ошибку с сравнением пароля primary_conninfo (Alexander Kukushkin)

    Начиная с PostgreSQL 10, Patroni использует passfile в primary_conninfo и не обновляет passfile после обновления пароля репликации в конфигурации YAML-файла при перезагрузке.

  • Не перезапускайте реплику с меткой nofailover в режиме паузы (Alexander Kukushkin)

    Patroni ранее запускал PostgreSQL реплику в режиме паузы вручную, когда для нее был установлен тег nofailover со значением true.

  • Исправить check_recovery_conf(), когда PostgreSQL находится в начальном состоянии (Alexander Kukushkin)

    Для PostgreSQL v12 и более новых, pg_settings невозможно запросить, пока сервер еще не запускается и не начинает принимать соединения. Отсутствующие параметры восстановления теперь добавляются в внутреннее состояние при записи postgresql.conf. Кроме того, восстановите проверку Postgresql.is_starting() в Ha.is_healthiest_node().

  • Проверьте параметры пользователя в формате словаря для initdb/basebackup (m4rrypro)

    Когда опции initdb или basebackup предоставлялись в виде словаря (вместо списка), проверка option_is_allowed() была пропущена, что позволяло использовать заблокированные опции.

  • Разрешить сжатие данных на стороне basebackup (m4rrypro)

    Опция compress была полностью отключена для basebackup, но начиная с PostgreSQL 15, сжатие на стороне сервера является полезным и работает прозрачно в формате без сжатия. Сжатие на стороне клиента по-прежнему не поддерживается.

  • Не перезагружайте конфигурацию PostgreSQL во время выполнения пользовательской начальной инициализации (Alexander Kukushkin)

    Настраиваемая начальная инициализация может быть сложной и включать в себя запуск и остановку PostgreSQL несколько раз. Перезагрузка конфигурации PostgreSQL в процессе может привести к неожиданному поведению.

  • Убедитесь, что postgresql.parameters является словарем (Alexander Kukushkin)

    Отбросить новую конфигурацию, если postgresql.parameters не является словарем.

Версия 4.1.0

Выпущено 2025-09-23

Новые возможности

  • Добавьте поддержку типа юнита “notify” от systemd (Ronan Dunklau)

    Без указания типа единицы уведомления, возможно запустить Patroni и сразу отправить ему сигнал SIGHUP с помощью systemd, что фактически приведет к его завершению до того, как оно успеет настроить обработчики сигналов.

  • Предоставлять информацию о получении и воспроизведении LSN/задержке в API и ctl (Polina Bungina)

    Patroni REST API /cluster endpoint и команда patronictl list теперь предоставляют информацию о получении LSN, воспроизведении LSN, задержке получения и задержке воспроизведения для каждого участника-реплики.

  • Обеспечьте чистое понижение до резервного кластера (Polina Bungina)

    Убедитесь, что введение раздела standby_cluster в динамической конфигурации приводит к чистому понижению кластера.

  • Реализуйте команды patronictl demote-cluster и promote-cluster (Polina Bungina)

    Новые команды для понижения и повышения статуса кластера обрабатывают как редактирование и проверку статуса динамической конфигурации.

  • Реализовать тег sync_priority (Polina Bungina)

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

  • Реализуйте опцию --print для --validate-config (Polina Bungina)

    Вывести локальную конфигурацию (включая переопределения конфигурации окружения) после успешной её проверки.

  • Реализовать kubernetes.bootstrap_labels (Polina Bungina)

    Эта функция позволяет определить метки, которые будут назначены участнику, когда он находится в состоянии initializing new cluster, running custom bootstrap script, starting after custom bootstrap или creating replica.

  • Добавьте конфигурационную опцию для подавления дублирующих логов о сердцебинии (Michael Morris)

    Если установлено значение true, то последовательные логи о сердечных сигналах, которые идентичны, не должны выводиться.

  • Добавьте необязательное свойство cluster_type для постоянных слотов репликации (Michael Banck)

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

  • Сделать HTTP конфигурацию заголовка сервера (David Grierson)

    Внедрите параметр restapi.server_tokens конфигурации, который позволяет ограничить информацию, раскрываемую в заголовке HTTP Server.

  • Реализуйте проверки готовности API для репликации на участниках (Ants Aasma)

    Предыдущая реализация считала реплики готовыми сразу после запуска PostgreSQL. С этой модификацией, реплика считается готовой только тогда, когда PostgreSQL выполняет репликацию и не отстает слишком сильно от лидера.

Улучшения

  • Уменьшить уровень логирования при ошибках конфигурации сторожевого таймера (Ants Aasma)

    Показывать строку журнала Could not activate Linux watchdog device на уровне отладочного ведения журнала, если сторожевой таймер не настроен в режиме required. Ранее она отображалась на уровне информационного ведения журнала.

  • Воспользуйтесь written_lsn и latest_end_lsn, предоставленными pg_stat_wal_receiver (Alexander Kukushkin)

    written_lsn, фактический записываемый LSN, теперь предпочтительнее того, который возвращается pg_last_wal_receive_lsn(), который на самом деле является сбросом LSN. latest_end_lsn указывает на сброс WAL на исходном хосте. В случае первичного сервера это позволяет более точно рассчитывать задержку воспроизведения, поскольку значения, хранящиеся в DCS, обновляются только каждые loop_wait секунд.

  • Избегайте взаимодействия со слотами, создаными с использованием опции failover=true (Alexander Kukushkin)

    Данное изменение необходимо для обеспечения полной функциональности логической функции переключения при отказе.

  • Добавьте состояние PostgreSQL в конечную точку /metrics REST API (Ivan Filianin)

    Информация о состоянии экземпляра PostgreSQL теперь доступна в формате выходных данных Prometheus от /metrics REST API конечной точки.


Версия 4.0.7

Выпущено 2025-09-22

Новые возможности

  • Добавьте поддержку PostgreSQL 18 RC1 (Alexander Kukushkin)

    Правила валидации для GUC были расширены. Patroni теперь правильно обрабатывает новый фоновый процесс ввода-вывода.

Исправления ошибок

  • Устраните потенциальную проблему, связанную с разрешением localhost на IPv6 в Windows (András Váczi)

    При настройке listen_addresses в PostgreSQL, использование 0.0.0.0 или 127.0.0.1 приведет к ограничению прослушивания только IPv4, исключая IPv6. Однако, на типичных системах Windows, localhost часто разрешает использование IPv6 адреса ::1 по умолчанию. Чтобы обеспечить совместимость, Patroni теперь настраивает PostgreSQL для прослушивания на 127.0.0.1, вместо localhost, на системах Windows.

  • Вернуть глобальную конфигурацию только в том случае, когда ключ /config существует в DCS (Alexander Kukushkin)

    Patroni REST API возвращал пустую конфигурацию вместо вызова ошибки, если ключ /config отсутствовал в DCS.

  • Устраните проблему, при которой режим отказоустойчивости не активируется в случае недоступности etcd (Alexander Kukushkin)

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

  • Устранить проблему блокировки из-за повторного вызова обработчика сигнала (Waynerv)

    Patroni, работающий в контейнере Docker с PID=1, в некоторых особых случаях испытывал взаимоблокировку после получения SIGCHLD.

  • Восстановить (постоянно) физическое место при отсутствии резервирования WAL (Israel Barth Rubio)

    Постоянные физические слоты репликации, созданные вне области действия Patroni без резервирования WAL, вызывали ошибку replication slot cannot be advanced. Чтобы этого избежать, Patroni теперь воссоздает такие слоты.

  • Обрабатывать сообщения об отмене наблюдения etcd3 корректно (Alexander Kukushkin)

    Когда etcd3 отправляет сообщение о отмене запроса в канал наблюдения, это не закрывает соединение. Это приводит к тому, что Patroni использует устаревшие данные. Patroni теперь решает эту проблему, прерывая цикл чтения фрагментированных ответов и закрывая соединение с стороны Patroni.

  • Обработка случая, когда сокет HTTPConnection обернут в pyopenssl (Alexander Kukushkin)

    Patroni некорректно использовал pyopenssl интерфейсы, которые были определены в python-etcd.

Улучшения документации

  • Улучшить руководство для кластера, состоящего из узлов 2 (Nikolay Samokhvalov)

    Уточнить поведение при переключении при отказе и требования к DCS.


Версия 4.0.6

Выпущено 2025-06-06

Исправления ошибок

  • Исправить ошибку в переключении при отказе от лидера с более высоким приоритетом (Alexander Kukushkin)

    Убедитесь, что Patroni игнорирует прежнего лидера с более высоким приоритетом, когда он сообщает о том же LSN, что и текущий узел.

  • Устранить разрешения для файла postgresql.conf, созданного вне PGDATA (Michael Banck)

    Учитывайте системное значение umask при создании файла postgresql.conf вне каталога PGDATA.

  • Исправить ошибку, связанную с плановым переключением synchronous_mode=quorum (Alexander Kukushkin)

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

  • Игнорировать устаревшие узлы etcd путем сравнения термина кластера (Alexander Kukushkin)

    Запомните последнее известное состояние “raft_term” кластера etcd, и при выполнении клиентских запросов сравнивайте его со значением “raft_term”, которое сообщает узел etcd.

  • Обновляйте файлы конфигурации PostgreSQL в SIGHUP (Alexander Kukushkin)

    Ранее Patroni заменял только файлы конфигурации PostgreSQL, если обнаруживалась какая-либо смена глобальной или локальной конфигурации.

  • Правильно обрабатывать исключение Unavailable, возникающее в результате работы etcd3 (Alexander Kukushkin)

    Patroni ранее пытался повторить такие запросы на том же etcd3 узле, в то время как переключение на другой узел является более эффективной стратегией.

  • Улучшить обработку etcd3 (Alexander Kukushkin)

    Убедитесь, что Patroni обновляет etcd3 в течение как минимум одного цикла обеспечения высокой доступности.

  • Проверьте аннотации статуса 409 при попытке получить блокировку лидера (Alexander Kukushkin)

    Реализуйте такое же поведение, как и для объекта «лидер», который был прочитан в Patroni версии 4.0.3.

  • Учитывайте replay_lsn при продвижении слотов (Polina Bungina)

    Не пытайтесь продвигать слоты на репликах за пределы replay_lsn. Кроме того, продвигайте слот до позиции replay_lsn, если он уже находится за confirmed_flush_lsn данного слота на реплике, но реплика еще не воспроизвела фактический LSN, на котором находится этот слот на первичном сервере.

  • Убедитесь, что CHECKPOINT выполняется после повышения (Alexander Kukushkin)

    Возможно, задача сохранения не была перезапущена при понижении, поскольку CHECKPOINT еще не завершилась. Это привело к использованию устаревшей result при последующем повышении.

  • Избегайте одновременного выполнения “офлайн” понижения (Alexander Kukushkin)

    В случае медленного завершения работы, может произойти ситуация, когда следующий цикл обработки сердечных сигналов снова столкнется с методом обработки ошибок DCS, что приведет к выдаче предупреждения AsyncExecutor is busy, demoting from the main thread и повторному запуску демотации в автономном режиме.

  • Нормализовать значение data_dir перед переименованием каталога данных при неудачной инициализации (Waynerv)

    Предотвратите появление обратного слеша в значении параметра data_dir, чтобы избежать сбоя процесса переименования после сбоя инициализации.

  • Убедитесь, что synchronous_standby_names содержит ожидаемое значение (Alexander Kukushkin)

    Ранее механизм, реализующий машину состояний для несинхронной репликации, не проверял фактическое значение synchronous_standby_names, что приводило к использованию устаревшего значения synchronous_standby_names, когда pg_stat_replication является подмножеством synchronous_standby_names.


Версия 4.0.5

Выпущено 2025-02-20

Повышение стабильности

  • Совместимость с python-json-logger>=3.1 (Alexander Kukushkin)

    Удалите предупреждения, возникающие при использовании API.

  • Совместимость с Python 3.13 (Alexander Kukushkin)

    Запустите тесты против Python 3.13.

  • Совместимость с pyinstaller>=4.4 (Joe Jensen)

    Переключитесь на значение по умолчанию iter_modules, если атрибут pyinstaller toc отсутствует.

  • Устранить проблемы с поддержкой PostgreSQL 9.5 (Alexander Kukushkin)

    • Правильно обрабатывайте формат вывода pg_rewind.
    • Учитывайте, что формат synchronous_standby_names не поддерживает указание “num”.
  • Совместимость с последними изменениями в urlparse (Alexander Kukushkin)

    urlparse больше не принимает несколько хостов с символом [] в URL. Для решения этой проблемы рекомендуется использовать нативные обёртки PQconninfoParse() из libpq, когда это возможно, и использовать нашу реализацию только для старых версий psycopg2, которые связаны с устаревшей версией libpq.

Исправления ошибок

  • Показать только участников, которые необходимо перезапустить после подтверждения перезапуска (András Váczi)

    Ранее, при выполнении patronictl restart <clustername> --pending, в списке подтверждения отображались все участники, независимо от того, требуется ли перезапуск для каждого из них.

  • Отмена длительных задач при остановке Patroni и удаление каталога данных при неудачной начальной инициализации реплики (Alexander Kukushkin)

    Ранее Patroni мог выполнять начальную инициализацию реплик, одновременно с выполнением pg_basebackup / wal-g / pgBackRest / barman или аналогичных задач.

  • Правильно обрабатывать имена кластеров, содержащие символ “/” patronictl edit-config (Antoni Mur)

    Замените символ слеша cluster_name на символ подчеркивания.

  • Избегайте преждевременного освобождения физических слотов (Alexander Kukushkin)

    Отложите удаление физических слотов репликации, содержащих xmin после переключения при отказе: на новом первичном сервере — до тех пор, пока этот участник не будет повышен до статуса лидера, на репликах — до тех пор, пока в кластере не будет определен лидер.

  • Обрабатывать все исключения, возникающие в дочернем процессе controldata() (Alexander Kukushkin)

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

  • Исправить ошибку, при которой слот для бывшего лидера не сохранялся при переключении (Alexander Kukushkin)

    Не следует ошибочно полагаться на то, что участники находятся в DCS, в то время как при переключении /member ключ для бывшего лидера истекает точно в одно и то же время.

  • Исправить несколько ошибок в машине состояния кворума (Alexander Kukushkin)

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

Улучшения

  • Улучшить обработку ошибок при пустом или неверном файле конфигурации (Julian)

    Выбрасывать более явную исключение при проверке, содержит ли файл Mapping конфигурации Patroni валидный объект.


Версия 4.0.4

Выпущено 2024-11-22

Повышение стабильности

  • Добавить совместимость с модулем py-consul (Alexander Kukushkin)

    Модуль python-consul давно не поддерживается, в то время как py-consul является официальной заменой. Обеспечивается обратная совместимость с python-consul.

  • Добавить совместимость с модулем prettytable>=3.12.0 (Alexander Kukushkin)

    Устраните предупреждения об устаревших адресах.

  • Совместимость с ydiff==1.4.2 (Alexander Kukushkin)

    Исправьте несовместимости для последней версии, ограничьте версию в requirements.txt, и внедрите тест совместимости для последней версии.

Исправления ошибок

  • Запустить функцию обратного вызова on_role_change после неудачного восстановления первичного сервера (Polina Bungina, Alexander Kukushkin)

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

  • Устранить утечку потоков в patronictl list -W (Alexander Kukushkin)

    Кэшировать объект экземпляра DCS для предотвращения утечки потоков.

  • Убедитесь, что в строку соединения записываются только поддерживаемые параметры (Alexander Kukushkin)

    Patroni ранее передавал параметры, введенные в новых версиях, в строку соединения, что приводило к ошибкам соединения.


Версия 4.0.3

Выпущено 2024-10-18

Исправления ошибок

  • Отключить pgaudit при создании пользователей, чтобы не раскрывать пароль (kviset)

    Patroni фиксировал superuser, replication и rewind пароли при их создании, когда был включен расширение pgaudit.

  • Устранить проблему с смешанными конфигурациями: первичный сервер на версии Patroni до v4 и реплики на версии v4+ (Alexander Kukushkin)

    Используйте значение xlog_location, извлеченное из ключа /members, вместо попытки получить позицию слота участника из ключа /status, если версия Patroni, работающая на лиде, является более ранней, чем 4.0.0. В противном случае это приводит к накоплению WAL на репликах.

  • Не игнорируйте допустимые параметры GUC PostgreSQL, которые не имеют валидатора Patroni (Polina Bungina)

    Проверьте также, соответствует ли postgres --describe-config, если GUC не имеет валидатора Patroni, но фактически является допустимым GUC.

Улучшения

  • Проверьте аннотации статуса 409 при чтении объекта лидера в K8s (Alexander Kukushkin)

    Избегайте дополнительного обновления, если запрос PATCH был отменен Patroni, при этом запрос успешно обновил целевой ресурс.

  • Добавьте поддержку опции соединения sslnegotiation на стороне клиента (Alexander Kukushkin)

    Добавлена sslnegotiation в финальный выпуск PostgreSQL 17.


Версия 4.0.2

Выпущено 2024-09-17

Исправления ошибок

  • Обработка исключений при обнаружении файлов конфигурации проверки (Alexander Kukushkin)

    Пропускать каталоги, для которых Patroni не имеет достаточных прав для выполнения операций перечисления.

  • Убедитесь, что неактивные физические слоты репликации не содержат xmin (Alexander Kukushkin, Polina Bungina)

    Начиная с версии 3.2.0, Patroni создает физические слоты репликации для всех участников на репликах и периодически перемещает их, используя функцию pg_replication_slot_advance(). Однако, если по какой-либо причине hot_standby_feedback включено, и первичный сервер понижается до статуса реплики, то неактивные слоты получают значение NOT NULL xmin, которое распространяется на новый первичный сервер. Это приводит к тому, что горизонт xmin не перемещается вперед, и невозможно выполнить очистку мертвых записей. С этой поправкой Patroni создает физические слоты репликации, которые должны быть неактивными, но имеют значение NOT NULL xmin.

  • Устранить не обработанные DCSError во время фазы запуска (Waynerv)

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

  • Явно включайте параметры конфигурации CMDLINE_OPTIONS при запросе к pg_settings (Alexander Kukushkin)

    Убедитесь, что все GUC, которые передаются postmaster в качестве параметров командной строки, восстанавливаются при присоединении Patroni к работающему резервному серверу. Это продолжение работы над ошибкой, исправленной в Patroni 3.2.2.

  • Исправить ошибку в логике каутирования synchronous_standby_names (Alexander Kukushkin)

    Согласно документации PostgreSQL, ключевые слова ANY и FIRST должны быть заключены в двойные кавычки, что Patroni ранее не делал.

  • Исправить проблему с неверным диапазоном соединения keepalive (hadizamani021)

    Убедитесь, что значение опции keepalive, рассчитанное на основе набора ttl, не превышает максимально допустимое значение для текущей платформы.


Версия 4.0.1

Выпущено 2024-08-30

Исправление ошибки

  • Patroni создавал избыточные слоты репликации для себя (Alexander Kukushkin)

    Это происходит, если name содержит заглавные буквы или специальные символы.


Версия 4.0.0

Выпущено 2024-08-29

Предупреждение
  • В этом выпуске завершена работа по отказу от термина «master» в пользу «primary». Это означает несколько изменений, несовместимых с предыдущими версиями, внимательно ознакомьтесь с примечаниями к выпуску. Обновление до Patroni 4+ будет работать надёжно только при условии, что Patroni работает в версии 3.1.0 или новее. Обновление с более старой версии напрямую до 4+ возможно, но может привести к неожиданному поведению, если первичный сервер выйдет из строя, а остальные узлы работают на других версиях Patroni.

Изменения, нарушающие совместимость

  • В процессе устранения неинклюзивного термина «master» в коде Patroni были внесены следующие изменения, нарушающие обратную совместимость:
    • На Kubernetes Patroni по умолчанию устанавливает метку role в значение primary. В случае, если вы хотите сохранить прежнее поведение и избежать простоев или сложных длительных миграций, можно настроить параметры kubernetes.leader_label_value и kubernetes.standby_leader_label_value на значение master. Подробнее здесь .
    • Роль Patroni записывается в DCS как primary вместо master.
    • Роль Patroni, возвращаемая Patroni REST API, была изменена с master на primary.
    • Patroni REST API больше не принимает role=master в запросах к конечным точкам /switchover, /failover, /restart.
    • Конечная точка /metrics REST API больше не будет отчитываться о метрике patroni_master.
    • Команда patronictl больше не принимает опцию --master ни для одной команды. Вместо этого следует использовать опции --leader или --primary.
    • Опция no_master в декларативной конфигурации методов создания пользовательских реплик больше не рассматривается как специальная опция, используйте вместо неё no_leader.
    • Скрипт patroni_wale_restore больше не принимает опцию --no_master.
    • Скрипт patroni_barman больше не принимает опцию --role=master.
    • Все скрипты обратного вызова выполняются с опцией role=primary, вместо role=master.
  • patronictl failover больше не принимает опцию --leader, которая была объявлена устаревшей начиная с Patroni 3.2.0.
  • Функциональность создания пользователей (раздел bootstrap.users конфигурации) была удалена начиная с Patroni 3.2.0.

Новые возможности

  • Переключение при отказе, основанное на кворуме (Ants Aasma, Alexander Kukushkin)

    Эта функция реализует синхронную репликацию на основе кворума (доступна с PostgreSQL v10), которая помогает снизить худшие случаи задержек, даже в нормальной эксплуатации, поскольку более высокая задержка репликации на один резервный сервер может быть компенсирована другими резервными серверами. Patroni реализует дополнительные меры предосторожности для предотвращения любых видимых пользователю потерь данных путем выбора кандидата на переключение на основе самой последней полученной транзакции.

  • Зарегистрируйте вторичные узлы Citus в pg_dist_node (Alexander Kukushkin)

    Patroni теперь поддерживает список узлов с role==replica, state==running и без noloadbalance -тега в pg_dist_node.

  • Настраиваемое хранение слотов репликации участников (Alexander Kukushkin)

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

  • Сделать права доступа к файлам журналов, созданным Patroni, настраиваемыми (Alexander Kukushkin)

    Позволяет установить конкретные разрешения для файлов журналов, созданных Patroni. Если разрешения не указаны, они устанавливаются на основе текущего umask значения.

  • Совместимость с PostgreSQL 17 бета3 (Alexander Kukushkin)

    Правила валидации для GUC были расширены. Patroni обрабатывает все новые вспомогательные бэкенды во время завершения работы и устанавливает dbname в primary_conninfo, поскольку это необходимо для синхронизации логических слотов репликации.

  • Реализуйте опцию --ignore-listen-port для проверки конфигурации Patroni (Sahil Naphade)

    Предусмотреть возможность игнорировать уже занятые порты при работе с patroni --validate-config.

Улучшения

  • Сделайте wal_log_hints настраиваемым (Paul_Kim)

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

  • Записывать команду pg_basebackup в журнал с уровнем DEBUG (Waynerv)

    Облегчает отладку при неудачной инициализации.

Исправления ошибок

  • Обеспечение постоянных слотов для каскадных узлов при работе в режиме отказоустойчивости (Alexander Kukushkin)

    Убедитесь, что слоты для реплик, создаваемых в результате, правильно продвигаются на первичном сервере при активации отказоустойчивого режима. Это достигается путем расширения ответа реплик с помощью запроса POST /failsafe REST API и их xlog_location.

  • Не позволяйте текущему узлу быть выбранным в качестве синхронного (Alexander Kukushkin)

    Возможно, происходит “нечто”, передаваемое с текущего первичного сервера application_name, которое соответствует имени текущего первичного сервера. Patroni не обрабатывал эту ситуацию должным образом, что могло привести к тому, что первичный сервер был бы объявлен как синхронный узел, и, следовательно, блокировал бы переключения.

  • Игнорировать restapi.allowlist_include_members для POST /failsafe (Alexander Kukushkin)

  • Улучшить проверку GUCs (Polina Bungina)

    Благодаря дополнительной проверке, осуществляемой посредством выполнения postgres --describe-config, ранее не было возможно устанавливать параметры конфигурации GUC, не указанные в нём, через конфигурацию Patroni. Это ограничение теперь снято.

  • Добавьте строку с localhost в файл .pgpass при обнаружении Unix-сокет (Alexander Kukushkin)

    Patroni добавит дополнительную строку в файл .pgpass, если параметр host начинается с символа /. Это позволяет обработать особый случай, когда host соответствует стандартному пути к сокету.

  • Устранить проблемы с ведением журнала (Waynerv)

    Определена корректная запись запроса URL в журналах обработки ошибок и исправлен порядок времени в журнале проверки Postmaster.


Версия 3.3.2

Выпущено 2024-07-11

Исправления ошибок

  • Устранить синхронный режим репликации для Postgres (Israel Barth Rubio)

    После внедрения synchronous_mode в Patroni, стандартное синхронное репликация Postgres не работала. С помощью этого исправления, Patroni устанавливает значение synchronous_standby_names, если оно было сконфигурировано пользователем, когда synchronous_mode отключено.

  • Обработка логических слотов, когда они становятся недействительными на резервном сервере (Polina Bungina)

    Поскольку PG16 логические слоты репликации на резервном сервере могут быть недействительными из-за горизонта: начиная с текущего момента, Patroni обязательно выполняет копирование (i.e, создание) недействительных слотов.

  • Устранить условие гонки с логическим продвижением слота и копированием (Alexander Kukushkin)

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


Версия 3.3.1

Выпущено 2024-06-17

Повышение стабильности

  • Совместимость с Python 3.12 (Alexander Kukushkin)

    Обработать новое свойство, добавленное в logging.LogRecord.

Исправления ошибок

  • Исправить бесконечную рекурсию при обработке тегов replicatefrom (Alexander Kukushkin)

    Как часть этой исправления, также улучшите проверку is_physical_slot() и обновите документацию.

  • Исправить некорректное отображение ролей в резервных кластерах (Alexander Kukushkin)

    synchronous_standby_names и синхронное репликация работают только на реальном первичном узле, и в случае каскадной репликации просто игнорируются Postgres. До этого исправления, patronictl list и GET /cluster ошибочно сообщали о некоторых узлах как о синхронных.

  • Обеспечить доступность allow_in_place_tablespaces GUC (Polina Bungina)

    allow_in_place_tablespaces не только было добавлено в PostgreSQL 15, но также было применено патчинг к PostgreSQL 10-14.


Версия 3.3.0

Выпущено 2024-04-04

Предупреждение

Все более старые версии Partoni несовместимы с ydiff>=1.3.

Существуют следующие варианты решения проблемы:

  1. обновите Patroni до последней версии
  2. установите ydiff<1.3 после установки Patroni
  3. установите модуль cdiff

Новые возможности

  • Добавьте возможность передачи auth_data в клиент Zookeeper (Aras Mumcuyan)

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

  • Добавьте скрипт из дополнения для интеграции с Barman (Israel Barth Rubio)

    Предоставьте приложение patroni_barman, которое позволяет выполнять Barman операции удаленно и может использоваться в качестве пользовательской начальной инициализации/пользовательского метода реплики или в качестве on_role_change callback. Пожалуйста, ознакомьтесь с здесь для получения дополнительной информации.

  • Поддержка формата журнала JSON (alisalemmi)

    Помимо plain (по умолчанию), Patroni теперь также поддерживает формат журнала json. Требуется установка библиотеки python-json-logger>=2.0.2.

  • Показать информацию pending_restart_reason (Polina Bungina)

    Предоставьте подробную информацию о параметрах PostgreSQL, которые вызвали установку флага pending_restart. Оба конечных пункта patronictl list и /patroni, а также REST и API теперь отображают имена параметров и их “разницу” в формате pending_restart_reason.

  • Реализовать тег nostream (Grigory Smolkin)

    Если тег nostream установлен в значение true, узел не будет использовать протокол репликации для потоковой передачи WAL, а вместо этого будет полагаться на восстановление из архива (если restore_command настроено). Это также отключает копирование и синхронизацию постоянных логических слотов репликации на самом узле и всех его дочерних репликах.

Улучшения

  • Реализовать проверку раздела log (Alexander Kukushkin)

    До настоящего времени валидатор не проверял правильность предоставленной конфигурации ведения журнала.

  • Улучшить ведение журнала для изменений параметров PostgreSQL (Polina Bungina)

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

Исправления ошибок

  • Правильно отфильтровать недопустимые pg_basebackup опции (Israel Barth Rubio)

    Из-за ошибки, Patroni не фильтровал правильно нежелательные опции, сконфигурированные для начальной инициализации basebackup, когда они предоставлялись в формате - setting: value.

  • Исправить ошибку обработки аутентификации etcd3 (Alexander Kukushkin)

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

  • Улучшить логику обнаружения файлов валидатора (Waynerv)

    Используйте библиотеку importlib для обнаружения файлов с доступными параметрами конфигурации, когда это возможно (для Python 3.9+). Эта реализация более стабильна и не нарушает Patroni-распределения, основанные на архивах zip.

  • Используйте target_session_attrs только в том случае, когда в разделе указано несколько хостов standby_cluster (Alexander Kukushkin)

    Теперь target_session_attrs=read-write добавляется в primary_conninfo на узле резервного сервера только в том случае, если раздел standby_cluster.host содержит несколько хостов, разделенных запятыми.

  • Добавьте код совместимости для библиотеки версии ydiff и 1.3+ (Alexander Kukushkin)

    Patroni использует некоторую API из ydiff, которая является закрытой, поскольку она предназначена только для использования в командной строке, а не в виде модуля Python. К сожалению, изменение API в 1.3 привело к несовместимости со старыми версиями Patroni.


Версия 3.2.2

Выпущено 2024-01-17

Исправления ошибок

  • Не позволяйте реплике выполнить инициализацию ключа, когда DCS было удалено (Alexander Kukushkin)

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

  • Используйте последовательное чтение при извлечении только обновленного ключа синхронизации из Consul (Alexander Kukushkin)

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

  • Перезагрузите конфигурацию Postgres, если параметр, требующий перезапуска, был сброшен к исходному значению (Polina Bungina)

    Ранее Patroni не обновлял конфигурацию, а только сбрасывал pending_restart.

  • Исправить ошибочную логику сообщения подтверждения при переключении на асинхронного кандидата в синхронном режиме (Polina Bungina)

    Проблема существовала только в patronictl .

  • Исключить лидер из кандидатов на переключение при отказе в patronictl (Polina Bungina)

    Если кластер находится в здоровом состоянии, переключение на существующего лидера не имеет никакого эффекта.

  • Создайте базу данных Citus и расширение, обеспечивая атомарность операций (Alexander Kukushkin, Zhao Junwang)

    Это позволит создавать их в скрипте post_bootstrap в случае, если необходимо добавить дополнительные зависимости в базу данных Citus.

  • Не фильтруйте наш тег nofailover (Polina Bungina)

    Установленная на узле конфигурация {nofailover: false, failover_priority: 0} не позволяла ему участвовать в гонке, хотя это должно было быть, поскольку тег nofailover должен был иметь приоритет.

  • Устранен проблема с замерзшим исполняемым файлом, созданным с помощью PyInstaller (Sophia Ruan)

    Конфигурация freeze_support() была применена после argparse, и в результате Patroni не смог запустить Postgres.

  • Исправлена ошибка в генераторе конфигурации для patronictl и Citus (Israel Barth Rubio)

    Это предотвращало запись параметров конфигурации patronictl и Citus , установленных через переменные окружения, в сгенерированную конфигурацию.

  • Восстановить параметры GUC и некоторые параметры, управляемые Patroni, при присоединении к работающему резервному серверу (Alexander Kukushkin)

    Patroni не удавалось перезапустить Postgres с версии 12 и выше, выдавая ошибку о том, что отсутствует port в одной из внутренних структур.

  • Исправления, связанные с флагом pending_restart (Polina Bungina)

    Не раскрывайте pending_restart при использовании пользовательской начальной инициализации с recovery_target_action = promote или когда кто-то изменил hot_standby или wal_log_hints, например, с использованием ALTER SYSTEM.


Версия 3.2.1

Выпущено 2023-11-30

Исправления ошибок

  • Ограничить допустимые значения аргумента --format в patronictl (Alexander Kukushkin)

    Ранее он принимал любое произвольное значение и не выдавал никакого результата, если значение не было распознано.

  • Убедитесь, что узлы-реплики получили контрольную точку LSN при выключении, прежде чем освободить ключ лидера (Alexander Kukushkin)

    Ранее в некоторых случаях мы использовали LSN из записи SWITCH, за которой следовал CHECKPOINT (если включен режим архивирования). В результате, первичный сервер иногда должен был выполнять pg_rewind, но при этом данные не терялись.

  • Выполняйте реальный запрос HTTP при проверке уникальности имени узла (Alexander Kukushkin)

    При работе с Patroni в контейнерах возможно, что трафик маршрутизируется через docker-proxy, который прослушивает порт и принимает входящие соединения. Это приводило к ложным срабатываниям.

  • Установлена фиксированная поддержка Citus с etcd v2 (Alexander Kukushkin)

    Patroni не удавалось развернуть новый кластер Citus с использованием etcd v2.

  • Исправлено поведение pg_rewind с PostgreSQL v16+ (Alexander Kukushkin)

    Формат сообщения об ошибках pg_waldump изменился в версии 16, что привело к тому, что Patroni вызывал pg_rewind даже в тех случаях, когда это было не требуется.

  • Исправлена ошибка с пользовательской начальной инициализацией (Alexander Kukushkin)

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

  • Устраненная проблема с конечными точками проверки работоспособности REST API (Sophia Ruan)

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

  • Кэшировать результаты postgres --describe-config (Waynerv)

    Они используются для определения, какие параметры конфигурации PostgreSQL доступны для проверки, и мы не ожидаем, что этот список будет изменяться во время работы Patroni.


Версия 3.2.0

Выпущено 2023-10-25

Уведомление об устаревании

  • Поддержка bootstrap.users будет удалена в версии 4.0.0. Если вам необходимо создавать пользователей после развертывания нового кластера, пожалуйста, используйте bootstrap.post_bootstrap хук для этого.

Изменения, нарушающие совместимость

  • Обеспечить выполнение правила loop_wait + 2*retry_timeout <= ttl и жестко закодировать минимально возможные значения (Alexander Kukushkin)

    Минимальные значения: loop_wait=2, retry_timeout=3, ttl=20. В случае, если значения меньше или нарушают правило, они корректируются, и в логах Patroni записывается предупреждение.

Новые возможности

  • Приоритет переключения при отказе (Mark Pekala)

    С помощью tags.failover_priority теперь возможно сделать узел более предпочтительным во время выбора лидера. Подробности в документации (ссылки).

  • Реализованы patroni --generate-config [--dsn DSN] и patroni --generate-sample-config (Polina Bungina)

    Она позволяет сгенерировать файл конфигурации для работающего кластера PostgreSQL или пример файла конфигурации для нового кластера Patroni.

  • Используйте выделенное соединение с Postgres для Patroni REST API (Alexander Kukushkin)

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

  • Расширить некоторые конечные точки с использованием name узла (sskserk)

    Для конечной точки мониторинга добавляется name рядом с scope, а для конечной точки метрик добавляется name в теги.

  • Обеспечить строкое различие между переключением при отказе и плановым переключением (Polina Bungina)

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

  • Обеспечить, чтобы физические слоты репликации работали аналогично логическим слотам (Alexander Kukushkin)

    Создайте постоянные физические слоты репликации на всех узлах, которые разрешено использовать в качестве лидера, и используйте функцию pg_replication_slot_advance() для продвижения restart_lsn для слотов на резервных серверах.

  • Добавьте возможность указания пространства имен через аргумент --dcs в команде patronictl (Israel Barth Rubio)

    Было бы полезно, если patronictl использовался без файла конфигурации.

  • Добавьте поддержку дополнительных параметров в пользовательской конфигурации начальной инициализации (Israel Barth Rubio)

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

Улучшения

  • Установите citus.local_hostname и GUC в одно и то же значение, которое используется Patroni для подключения к базе данных Postgres (Alexander Kukushkin)

    Существуют случаи, когда Citus хочет иметь соединение с локальной Postgres. По умолчанию оно использует localhost, которое не всегда доступно.

Исправления ошибок

  • Игнорировать настройку synchronous_mode в резервном кластере (Polina Bungina)

    PostgreSQL не поддерживает каскадное синхронное репликацию и игнорирование synchronous_mode приводило к сбоям при плановом переключении в резервном кластере.

  • Обработка SIGCHLD для обратного вызова on_reload (Alexander Kukushkin)

    Не выполнение этого приведет к созданию “живого” процесса, который завершается только при выполнении следующего on_reload.

  • Обрабатывать ошибку AuthOldRevision при работе с etcd v3 (Alexander Kukushkin, Kenny Do)

    Ошибка возникает, если etcd настроен для использования JWT и когда база данных пользователей в etcd обновляется.


Версия 3.1.2

Выпущено 2023-09-26

Исправления ошибок

  • Исправлена ошибка с проверками wal_keep_size (Alexander Kukushkin)

    wal_keep_size представляет собой GUC, который обычно имеет единицу, и Patroni не мог преобразовать его значение в int. В результате значение bootstrap.dcs не было записано в ключ /config после этого.

  • Обнаружение и устранение несоответствий между /sync и synchronous_standby_names (Alexander Kukushkin)

    Обычно Patroni обновляет /sync и synchronous_standby_names в определенном порядке, но в случае возникновения ошибки или при ручном сбросе synchronous_standby_names, Patroni переходил в несогласованное состояние. В результате могло произойти переключение на несинхронный узел.

  • Прочитать значения GUC при объединении работающих экземпляров Postgres (Alexander Kukushkin)

    При перезапуске в режиме паузы , Patroni удалял synchronous_standby_names GUC из postgresql.conf. Чтобы решить эту проблему и избежать подобных ситуаций, Patroni будет считывать значение GUC, если он присоединяется к уже работающей Postgres.

  • Устранено отображение назойливых предупреждений при проверке уникальности узла (Alexander Kukushkin)

    Предупреждение WARNING генерируется urllib3, если Patroni перезапускается слишком быстро.


Версия 3.1.1

Выпущено 2023-09-20

Исправления ошибок

  • Сброс состояния резервного копирования при повышении (ChenChangAo)

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

  • Игнорировать ненужные предупреждения в patronictl (Alexander Kukushkin)

    Если patronictl использует тот же patroni.yaml файл, что и Patroni, и имеет доступ к PGDATA каталогу, оно может выдавать навязчивые предупреждения об неправильных значениях в глобальной конфигурации.

  • Явно включить синхронный режим для редкого случая (Alexander Kukushkin)

    Синхронный режим эффективно не активируется, если нет реплик, получающих данные от первичного сервера.

  • Исправлена ошибка с проверкой целочисленных значений 0 (Israel Barth Rubio)

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

  • Не возвращайте логические слоты для резервного кластера (Alexander Kukushkin)

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

  • Избегайте отображения строки документации в patronictl --help (Israel Barth Rubio)

    Модуль click должен получить специальное указание для этого.

  • Исправлена ошибка, связанная с kubernetes.standby_leader_label_value (Alexander Kukushkin)

    Эта функция фактически никогда не работала.

  • Вернул идентификатор системы кластера в patronictl list (Polina Bungina)

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

  • Переопределите метод write_leader_optime в реализации для Kubernetes (Alexander Kukushkin)

    Метод должен записывать команду остановки LSN на конечную точку/ConfigMap, когда нет доступных здоровых реплик, которые могли бы стать новым первичным сервером.

  • Не запускайте остановленный PostgreSQL в режиме ожидания (Alexander Kukushkin)

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

  • Исправлена ошибка в команде patronictl query (Israel Barth Rubio)

    Не работало, когда предоставлялся только аргумент -m, или когда не предоставлялись ни -r, ни -m.

  • Правильно обрабатывать целочисленные параметры, используемые в командной строке для запуска PostgreSQL (Polina Bungina)

    Если значения передаются в виде строк и не преобразуются в целые числа, это приводило к неверному расчету max_prepared_transactions, основанному на max_connections для кластеров Citus.

  • Не полагайтесь на pg_stat_wal_receiver при принятии решения о pg_rewind (Alexander Kukushkin)

    Возможно, что информация received_tli, предоставленная pg_stat_wal_receiver, будет опережать фактическую временную шкалу, в то время как временная шкала, предоставленная DENTIFY_SYSTEM через соединение репликации, всегда будет корректной.


Версия 3.1.0

Выпущено 2023-08-03

Изменения, нарушающие совместимость

  • Изменили семантику restapi.keyfile и restapi.certfile (Alexander Kukushkin)

    Ранее Patroni использовал restapi.keyfile и restapi.certfile в качестве сертификатов клиента в качестве резервного варианта, если соответствующие параметры конфигурации отсутствовали в разделе ctl.

Предупреждение

Если включена проверка клиентских сертификатов (restapi.verify_client имеет значение required), также обязательно предоставьте действительные клиентские сертификаты в ctl.certfile, ctl.keyfile, ctl.keyfile_password. Без них Patroni не будет работать правильно.

Новые возможности

  • Сделать возможность настройки роли Pod (Waynerv)

    Значения можно было настроить с помощью параметров kubernetes.leader_label_value, kubernetes.follower_label_value и kubernetes.standby_leader_label_value. Эта функция будет очень полезна, когда мы изменим роль master на primary. Вы можете узнать больше о функции и шагах миграции здесь .

Улучшения

  • Различные улучшения patroni --validate-config (Alexander Kukushkin)

    Улучшена проверка параметров для различных DCS, bootstrap.dcs, ctl, restapi и сегментов, а также для .

  • Запускать PostgreSQL без режима восстановления, если он завершился во время восстановления, пока работает Patroni (Alexander Kukushkin)

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

  • Избегайте ненужных обновлений ключа /status (Alexander Kukushkin)

    Когда отсутствуют постоянные логические слоты, Patroni обновлял /status на каждом цикле проверки работоспособности, даже когда LSN на первичном сервере не продвигался вперед.

  • Не допускайте, чтобы устаревший первичный сервер выиграл выбор лидера (Alexander Kukushkin)

    Если Patroni зависал в течение длительного времени из-за нехватки ресурсов, он дополнительно проверяет, не были ли другие узлы повышены в статус лидера Postgres до получения блокировки лидера.

  • Реализована возможность проверки определенных параметров PostgreSQL (Alexander Kukushkin, Feike Steenbergen)

    Если проверка max_connections, max_wal_senders, max_prepared_transactions, max_locks_per_transaction, max_replication_slots или max_worker_processes завершилась неудачей, Patroni использовал какое-то разумное значение по умолчанию. Теперь, помимо этого, он также отобразит предупреждение.

  • Установите разрешения для файлов и каталогов, созданных в PGDATA (Alexander Kukushkin)

    Все файлы, созданные Patroni, имели только права владельца на чтение и запись. Это поведение нарушало работу инструментов резервного копирования, которые выполнялись от другого пользователя и полагались на права группы на чтение. Теперь Patroni соблюдает права доступа к PGDATA и правильно устанавливает права доступа ко всем каталогам и файлам, которые он создает внутри PGDATA.

Исправления ошибок

  • Запустите archive_command через оболочку (Waynerv)

    Patroni мог архивировать некоторые сегменты WAL перед аварийным восстановлением в однопользовательском режиме или перед pg_rewind. Если archive_command содержала операторы оболочки, например &&, она не работала с Patroni.

  • Устранены ошибки при проверках завершения работы “в процессе переключения” (Polina Bungina)

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

  • Исправлена проверка “является ли первичным сервером” (Alexander Kukushkin)

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

  • Исправлена patronictl list (Alexander Kukushkin)

    Поле «Название кластера» отсутствовало в форматах вывода tsv, json и yaml.

  • Исправлено поведение pg_rewind после паузы (Alexander Kukushkin)

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

  • Исправлена ошибка в реализации etcd v3 (Alexander Kukushkin)

    Недействительновать внутренний кэш KV, если обновление ключа выполнено с использованием поля create_revision/mod_revision из-за несоответствия версий.

  • Фиксированное поведение реплик в резервном кластере в режиме паузы (Alexander Kukushkin)

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


Версия 3.0.4

Выпущено 2023-07-13

Новые возможности

  • Сделать статус репликации резервных узлов видимым (Alexander Kukushkin)

    Для PostgreSQL 9.6+ Patroni сообщит о состоянии репликации как streaming, когда резервный сервер получает данные от другого узла, или in archive recovery, когда нет соединения репликации и установлено значение restore_command. Состояние видно в ключах member в DCS, в выводе REST API и в patronictl list.

Улучшения

  • Улучшенные сообщения об ошибках с использованием etcd v3 (Alexander Kukushkin)

    Когда кластер etcd v3 недоступен, Patroni сообщал, что не может получить доступ к конечным точкам /v2.

  • Используйте режим чтения с кворумом patronictl , если это возможно (Alexander Kukushkin)

    Кластеры etcd или Consul могут быть приведены в режим только для чтения, но с точки зрения patronictl всё было нормально. Сейчас произойдет сбой с ошибкой.

  • Предотвратить разделение на две части из-за дублирования имен в конфигурации (Mark Pekala)

    При запуске Patroni будет проверено, зарегистрирован ли узел с таким же именем в DCS, и будет предпринята попытка запросить его REST API. Если REST API доступно, Patroni завершится с ошибкой. Это поможет защититься от человеческих ошибок.

  • Запустить Postgres без режима восстановления, если он завершился во время работы Patroni (Alexander Kukushkin)

    Это может сократить время восстановления и поможет избежать ненужных изменений временной шкалы.

Исправления ошибок

  • REST API SSL сертификат не был перезагружен при получении SIGHUP (Israel Barth Rubio)

    Ошибку было внесено в 3.0.3.

  • Фиксированная проверка целочисленных параметров GUC, таких как max_connections (Feike Steenbergen)

    Patroni не воспринимал значения, заключенные в кавычках. Ошибка была внесена в 3.0.3.

  • Устранить проблему, связанную с , synchronous_mode, (Alexander Kukushkin)

    Выполните txid_current() с использованием synchronous_commit=off, чтобы избежать случайного ожидания отсутствующих синхронных резервных серверов при включении synchronous_mode_strict.


Версия 3.0.3

Выпущено 2023-06-22

Новые возможности

  • Совместимость с PostgreSQL 16 бета1 (Alexander Kukushkin)

    Расширьте правила валидации для GUC.

  • Сделайте валидатор PostgreSQL GUC расширяемым (Israel Barth Rubio)

    Правила валидации загружаются из файлов YAML, расположенных в каталоге patroni/postgresql/available_parameters/. Файлы располагаются в алфавитном порядке и применяются последовательно. Это позволяет использовать пользовательские правила валидации для нестандартных дистрибутивов PostgreSQL.

  • Добавлена опция restapi.request_queue_size (Andrey Zhidenkov, Aleksei Sukhov)

    Устанавливает размер очереди запросов для сокета TCP, используемого Patroni REST API. После заполнения очереди, дальнейшие запросы получают ошибку “Соединение отклонено”. Значение по умолчанию равно 5.

  • Вызывайте initdb напрямую при инициализации нового кластера (Matt Baker)

    Ранее это осуществлялось через pg_ctl, что требовало специального кастинга параметров, передаваемых в initdb.

  • Добавлено до точки останова (Le Duane)

    Этот хук можно настроить через postgresql.before_stop и выполняется непосредственно перед pg_ctl stop. Код завершения не влияет на процесс остановки.

  • Добавлена поддержка пользовательских имен для исполняемых файлов Postgres (Israel Barth Rubio, Polina Bungina)

    При использовании пользовательской версии Postgres может оказаться, что бинарные файлы Postgres были скомпилированы с другими именами, отличными от именами, используемых в общедоступной версии Postgres. Имена пользовательских бинарных файлов можно настроить с помощью переменных окружения postgresql.bin_name.* и PATRONI_POSTGRESQL_BIN_*.

Улучшения

  • Различные улучшения patroni --validate-config (Polina Bungina)

    • Сделать bootstrap.initdb необязательным. Оно требуется только для новых кластеров, но patroni --validate-config выдавала ошибку, если оно отсутствовало в конфигурации.
    • Не выдавать ошибку, когда postgresql.bin_dir пусто или не установлено. Сначала попытайтесь найти бинарные файлы Postgres в стандартном месте PATH.
    • Сделать раздел postgresql.authentication.rewind необязательным. Если он отсутствует, Patroni использует учетную запись суперпользователя.
  • Улучшенная отчетность об ошибках в patronictl (Israel Barth Rubio)

    Символ \n отображался в том виде, в котором он есть, вместо фактического символа новой строки.

Исправления ошибок

  • Устраненная проблема в поддержке Citus (Alexander Kukushkin)

    Если вызов REST API от продвинутого рабочего к координатору завершился неудачно во время планового переключения, это приводило к блокировке указанной группы Citus в течение неопределенного времени.

  • Разрешить etcd3 URL в опции --dcs-url команды patronictl (Israel Barth Rubio)

    Если пользователи попытаются передать etcd3 URL через опцию --dcs-url программы patronictl , они столкнутся с исключением.


Версия 3.0.2

Выпущено 2023-03-24

Предупреждение

В версии 3.0.2 поддержка Python версий старше 3.6 прекращена.

Новые возможности

  • Добавлена синхронизация статуса резервного сервера в конечную точку /metrics (Thomas von Dein, Alexander Kukushkin)

    Ранее осуществлялось только отслеживание primary/standby_leader/replica.

  • Удобное управление PAGER в patronictl (Israel Barth Rubio)

    Оно позволяет настраивать вывод постранично через переменную окружения PAGER, которая переопределяет значения по умолчанию less и more.

  • Сделать код состояния K8s, подлежащий повторной попытке HTTP, настраиваемым (Alexander Kukushkin)

    На некоторых управляемых платформах возможно получить код статуса 401 Unauthorized, который иногда разрешается после нескольких повторных попыток.

Улучшения

  • Установите hot_standby в значение off только при выполнении пользовательской начальной инициализации, если recovery_target_action установлено в значение promote (Alexander Kukushkin)

    Необходимо было обеспечить корректную работу recovery_target_action=pause.

  • Не разрешайте on_reload вызывать другие callback-функции для завершения работы. (Alexander Kukushkin)

    on_start/on_stop/on_role_change обычно используются для добавления/удаления виртуального IP, и on_reload не должны влиять на них.

  • Переключено на IMDSFetcher в примере скрипта обратного вызова для AWS (Polina Bungina)

    Для IMDSv2 требуется токен для работы, а IMDSFetcher обрабатывает его автоматически.

Исправления ошибок

  • Устранена ошибка patronictl switchover в кластере Citus, работающем на Kubernetes (Lukáš Lalinský)

    Это не работало для пространств имен, отличных от default.

  • Не записывайте данные в PGDATA, если основная версия неизвестна (Alexander Kukushkin)

    Если сразу после запуска PGDATA был пустым (возможно, еще не был смонтирован), Patroni делал ложное предположение о версии PostgreSQL и ошибочно создавал файл recovery.conf даже в том случае, если фактическая основная версия составляет v10+ или выше.

  • Исправлена ошибка с метаданными Citus после переключения координатора (Alexander Kukushkin)

    Вызов citus_set_coordinator_host() не вызывает синхронизацию метаданных, и изменение было незаметным на узлах-рабочих. Проблема решается путем перехода на citus_update_node().

  • Используйте хосты etcd, указанные в файле конфигурации, в качестве резервного варианта, когда все узлы etcd “не удалось” (Alexander Kukushkin)

    Кластер etcd может изменять свою топологию со временем, и Patroni пытается следить за этим. Если в какой-то момент все узлы становятся недоступными, Patroni будет использовать комбинацию узлов из конфигурации, а также последнюю известную топологию, при попытке повторного подключения.


Версия 3.0.1

Выпущено 2023-02-16

Исправления ошибок

  • Передайте правильное имя роли в on_role_change скрипт обратного вызова. (Alexander Kukushkin, Polina Bungina)

    Patroni ранее ошибочно передавал роли promoted обратному вызову on_role_change при повышении. Имя передаваемой роли было возвращено к master. Этот регресс был введён в 3.0.0.


Версия 3.0.0

Выпущено 2023-01-30

Эта версия добавляет интеграцию с Citus и позволяет продолжать работу при временных DCS отказах без понижения первичного сервера.

Предупреждение
  • Выпуск 3.0.0 является последним выпуском, поддерживающим Python 2.7. Следующий выпуск прекратит поддержку версий Python, более старых, чем 3.7.

  • Поддержка RAFT устарела. Мы сделаем всё возможное для её поддержания, но не гарантируем и не несём ответственности за возможные проблемы.

  • Этот выпуск является первым шагом по отказу от термина «master» в пользу «primary». Обновление до следующего мажорного выпуска будет работать надёжно только в том случае, если вы используете не менее 3.0.0.

Новые возможности

  • DCS отказоустойчивый режим (Alexander Kukushkin, Polina Bungina)

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

  • Поддержка Citus (Alexander Kukushkin, Polina Bungina, Jelte Fennema)

    Patroni обеспечивает простое развёртывание и управление кластерами Citus с высокой доступностью. Пожалуйста, ознакомьтесь со страницей здесь для получения дополнительной информации.

Улучшения

  • Подавление повторяющихся ошибок при удалении неизвестных, но активных слотов репликации (Michael Banck)

    Patroni по-прежнему будет создавать эти логи, но только в DEBUG.

  • Запускать только один запрос мониторинга в каждом цикле HA (Alexander Kukushkin)

    Это не относится к случаю, когда включена синхронная репликация.

  • Сохранить последнюю неудачную директорию данных (William Albertus Dembo)

    Если начальная инициализация завершилась неудачно, Patroni использовал для переименования папки PGDATA с суффиксом временной метки. С этого момента суффикс будет .failed, и если такая папка существует, она удаляется перед переименованием.

  • Улучшенная проверка соединений для синхронной репликации (Alexander Kukushkin)

    Когда новый хост добавляется в synchronous_standby_names, он устанавливается как синхронный в DCS только в том случае, если он успешно синхронизируется с первичным сервером, а также pg_stat_replication.sync_state = 'sync'.

Удалённые возможности

  • Удалите patronictl scaffold (Alexander Kukushkin)

    Единственная причина для его использования заключалась в неэффективном способе управления резервными кластерами.


Версия 2.1.7

Выпущено 2023-01-04

Исправления ошибок

  • Устранены незначительные несовместимости с устаревшими Python-модулями (Alexander Kukushkin)

    Они предотвратили установку/запуск Patroni на Debian Buster/Ubuntu Bionic.


Версия 2.1.6

Выпущено 2022-12-30

Улучшения

  • Устраните раздражающие исключения при завершении соединения SSL (Alexander Kukushkin)

    HAProxy закрывает соединения, как только получает код статуса HTTP, не оставляя Patroni время для корректного завершения SSL соединения.

  • Настройте пример Dockerfile для архитектуры arm64 (Polina Bungina)

    Удалите явные amd64 и x86_64, не удаляйте libnss_files.so.*.

Улучшения безопасности

  • Обеспечить search_path=pg_catalog для соединений, не участвующих в репликации (Alexander Kukushkin)

    Поскольку Patroni в значительной степени полагается на соединения с правами суперпользователя, мы хотим защитить его от возможных атак, осуществляемых с использованием пользовательских функций и/или операторов в схеме public с тем же именем и сигнатурой, что и соответствующие объекты в pg_catalog. Для этого обеспечивается search_path=pg_catalog для всех соединений, созданных Patroni (кроме соединений репликации).

  • Предотвратить запись паролей в pg_stat_statements (Feike Steenbergen)

    Это достигается путем установки pg_stat_statements.track_utility=off при создании пользователей.

Исправления ошибок

  • Объявить proxy_address как необязательный (Denis Laxalde)

    Поскольку это, по сути, необязательная опция.

  • Улучшить поведение опции «insecure» (Alexander Kukushkin)

    Опция insecure Ctl не работала должным образом, когда использовались клиентские сертификаты для REST API запросов.

  • Получите конфигурацию сторожевого таймера из bootstrap.dcs при начальной инициализации нового кластера (Matt Baker)

    Patroni ранее использовал для начальной инициализации кластера значения по умолчанию для сторожевого таймера, вместо использования конфигурации, которая использовалась для инициализации DCS.

  • Исправьте способ обработки расширений файлов при поиске исполняемых файлов WIN32 (Martín Marqués)

    Добавляйте .exe в имя файла только в том случае, если у файла еще нет расширения.

  • Исправить настройку Consul TTL (Alexander Kukushkin)

    Мы использовали ttl/2.0 при установке значения в классе HTTPClient, но забыли умножить текущее значение на 2 в свойстве класса. Это приводило к тому, что Consul TTL получал неверные данные в два раза.

Удалённые возможности

  • Удалите patronictl configure (Polina Bungina)

    Не требуется создавать отдельный patronictl конфигурационный файл.


Версия 2.1.5

Выпущено 2022-11-28

Эта версия улучшает совместимость с PostgreSQL 15 и объявляет о готовности к использованию etcd v3 в производственной среде. Patroni на Raft остается в статусе Бета.

Новые возможности

  • Улучшить patroni --validate-config (Denis Laxalde)

    Завершить работу с кодом 1, если конфигурация недействительна, и вывести сообщения об ошибках в stderr.

  • Не удаляйте слоты репликации в режиме паузы (Alexander Kukushkin)

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

  • Поддержка метода запроса HEAD для мониторинговых конечных точек (Robert Cutajar)

    Если использовать GET вместо него, Patroni вернет только код статуса HTTP.

  • Обеспечить поддержку тестов поведения в Windows (Alexander Kukushkin)

    Имитировать корректный выход Patroni (SIGTERM) в Windows путем внедрения нового REST API конечного POST /sigterm.

  • Введение postgresql.proxy_address (Alexander Kukushkin)

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

Повышение стабильности

  • Выполните pg_replication_slot_advance() из потока (Alexander Kukushkin)

    В загруженных кластерах с большим количеством логических слотов репликации вызов pg_replication_slot_advance() влиял на основной цикл обеспечения высокой доступности и мог приводить к истечению срока действия ключа участника.

  • Архив может содержать отсутствующие WAL, перед вызовом pg_rewind на старый первичный сервер (Polina Bungina)

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

  • Игнорировать ошибки 403 при попытке создания Kubernetes Service (Nick Hudson, Polina Bungina)

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

  • Улучшить проверку работоспособности (Alexander Kukushkin)

    Проблема с доступностью начнет возникать, если цикл проверки работоспособности работает дольше ttl на первичном сервере или 2\*ttl на реплике. Это позволит использовать его в качестве альтернативы watchdog в Kubernetes.

  • Убедитесь, что только узел, отвечающий за синхронизацию, пытается получить блокировку во время планового переключения (Alexander Kukushkin, Polina Bungina)

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

  • Избегайте клонирования во время начальной инициализации (Ants Aasma)

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

  • Совместимость с kazoo 2.9.0 (Alexander Kukushkin)

    В зависимости от версии Python, метод SequentialThreadingHandler.select() может вызывать исключения TypeError и IOError, если метод select() вызывается на закрытом сокете.

  • Явно завершить SSL соединение перед завершением работы сокета (Alexander Kukushkin)

    Не выполнение этого привело к возникновению unexpected eof while reading ошибок с использованием OpenSSL 3.0.

  • Совместимость с prettytable\>=2.2.0 (Alexander Kukushkin)

    В связи с внутренними API изменениями заголовок кластера отображался на неправильной строке.

Исправления ошибок

  • Обработать истекший токен для etcd lease_grant (monsterxx03)

    В случае возникновения ошибки получите новый токен и повторите запрос.

  • Исправить ошибку в GET /read-only-sync (Alexander Kukushkin)

    Оно было введено в предыдущем выпуске и фактически никогда не работало.

  • Обработка случая, когда директория хранения данных исчезла (Alexander Kukushkin)

    Patroni периодически проверяет, что PGDATA существует и не является пустым, но в случае возникновения проблем со хранилищем, os.listdir() генерирует исключение OSError, прерывая цикл мониторинга.

  • Применять master_stop_timeout при ожидании закрытия пользовательских бэкендов (Alexander Kukushkin)

    Что-то, похожее на пользовательский бэкенд, на самом деле может быть фоновым процессом (e.g, Citus Maintenance Daemon), который не может быть остановлен.

  • Принять *:<port> для postgresql.listen (Denis Laxalde)

    Система patroni --validate-config сообщала об этом.

  • Исправление тайм-аутов в Raft (Alexander Kukushkin)

    Когда Patroni или patronictl запускаются, они пытаются получить топологию кластера Raft от известных участников. Эти вызовы выполнялись без надлежащих тайм-аутов.

  • Принудительное обновление сервиса consul, если был изменен токен (John A. Lotoski)

    В этом случае возникают ошибки “ошибка вызова RPC: ошибка вызова RPC: ACL не найдено”.


Версия 2.1.4

Выпущено 2022-06-01

Новые возможности

  • Улучшить поведение pg_rewind на типичных системах Debian/Ubuntu (Gunnar “Nick” Bluth)

    В конфигурациях PostgreSQL, в которых postgresql.conf находится вне каталога данных (e.g. пакеты Ubuntu/Debian), pg_rewind --restore-target-wal не может определить значение restore_command.

  • Разрешить установку TLSServerName на проверки сервисов Consul (Michael Gmelin)

    Полезно, когда проверки выполняются по IP-адресам, и Consul node_name не является FQDN.

  • Добавлена поддержка ppc64le в сторожевом таймере (Jean-Michel Scheiwiler)

    И реализована поддержка сторожевого таймера на некоторых платформах, отличных от x86.

  • Перенесен вызов aws.py из boto в boto3 (Alexander Kukushkin)

boto 2.x устарел с 2018 и завершается с ошибкой python 3.9.

  • Периодически обновляйте токен учетной записи сервиса в K8s (Haitao Li)

    Поскольку токены учётных записей службы Kubernetes v1.21 истекают через 1 час.

  • Добавлен конечный пункт мониторинга /read-only-sync (Dennis4b)

    Это аналогично /read-only, но включает только синхронные реплики.

Повышение стабильности

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

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

  • Особые правила обработки параметров конфигурации восстановления для PostgreSQL v12+ (Alexander Kukushkin)

    При запуске в режиме реплики Patroni должен уметь обновлять postgresql.conf и перезапускаться/перезагружаться, если адрес лидера изменился, используя кэшированные значения параметров вместо запросов к pg_settings.

  • Улучшенная обработка IPv6-адресов в параметрах postgresql.listen (Alexander Kukushkin)

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

  • Используйте учетные данные replication при выполнении проверки на соответствие только для PostgreSQL v10 и более ранних версий (Alexander Kukushkin)

    Если включено rewind, Patroni снова будет использовать либо учетные данные superuser, либо rewind в новых версиях Postgres.

Исправления ошибок

  • Исправлена отсутствующая импорт dateutil.parser (Wesley Mendes)

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

  • Убедитесь, что аннотация optime является строкой (Sebastian Hasler)

    В определенных случаях Patroni пытался интерпретировать это как число.

  • Улучшенная обработка неудачной попытки pg_rewind (Alexander Kukushkin)

    Если первичный сервер станет недоступным в течение pg_rewind, $PGDATA останется в нерабочем состоянии. Впоследствии Patroni удалит каталог данных, даже если это не разрешено конфигурацией.

  • Не удаляйте slots аннотации с лидера ConfigMap/Endpoint, когда PostgreSQL еще не готов (Alexander Kukushkin)

    Если значение slots не передано, аннотация будет использовать текущее значение.

  • Решение проблемы конкурентности с помощью наблюдателей K8s API (Alexander Kukushkin)

    В некоторых (неизвестных) условиях наблюдатели могут стать устаревшими; в результате метод attempt_to_acquire_leader() может завершиться сбоем из-за кода состояния HTTP 409. В таком случае мы сбрасываем соединения наблюдателей и начинаем сначала.


Версия 2.1.3

Выпущено 2022-02-18

Новые возможности

  • Добавлена поддержка для зашифрованных ключей TLS для patronictl (Alexander Kukushkin)

    Его можно было настроить через ctl.keyfile_password или переменную окружения PATRONI_CTL_KEYFILE_PASSWORD.

  • Добавлены дополнительные метрики в конечную точку /metrics (Alexandre Pereira)

    В частности, patroni_pending_restart и patroni_is_paused.

  • Предусмотреть возможность указания нескольких хостов в конфигурации резервного кластера (Michael Banck)

    Если резервный кластер реплицирует данные из кластера Patroni, может быть удобно использовать переключение при отказе на стороне клиента, доступное в libpq начиная с PostgreSQL v10. То есть, настройка primary_conninfo на резервном лидере и параметр pg_rewind в строке подключения target_session_attrs=read-write. Файл pgpass будет сгенерирован с несколькими строками (по одной строке на хост), и вместо вызова CHECKPOINT на узлах первичного кластера резервный кластер будет ждать обновления pg_control.

Повышение стабильности

  • Совместимость со старыми системами psycopg2 (Alexander Kukushkin)

    Например, psycopg2, установленный из пакетов Ubuntu 18.04, пока не имеет исключения UndefinedFile.

  • Перезапустите etcd3, если все узлы etcd не отвечают (Alexander Kukushkin)

    Если наблюдатель активен, метод get_cluster() продолжает возвращать устаревшую информацию, даже если все узлы etcd выходят из строя.

  • Не удаляйте блокировку лидера в резервном кластере во время приостановки (Alexander Kukushkin)

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

Исправления ошибок

  • Исправлена ошибка в начальной инициализации с резервным сервером (Alexander Kukushkin)

    Patroni рассматривал начальную инициализацию как неудачную, если Postgres не начинал принимать соединения после 60 секунд. Ошибка была внесена в релизе 2.1.2.

  • Исправлена ошибка с переключением на резервный сервер в случае отказов (Alexander Kukushkin)

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

  • Устранены мелкие проблемы в валидаторе конфигурации Postgres (Alexander Kukushkin)

    Целые параметры, представленные в PostgreSQL версии 14, не проходили валидацию, поскольку минимальные и максимальные значения были заключены в кавычки в validator.py

  • Используйте учетные данные для репликации при проверке статуса лидера (Alexander Kukushkin)

    Возможно, что remove_data_directory_on_diverged_timelines установлено, но rewind_credentials не определено, и доступ суперпользователя между узлами не разрешен.

  • Исправлена ошибка “порт уже используется” при замене сертификатов REST API (Ants Aasma)

    При переключении сертификатов возникала гонка условий с одновременным API запросом. Если один активен в период замены, то замена завершится неудачей с ошибкой “порт занят”, и Patroni окажется в состоянии без активного API сервера.

  • Исправлена ошибка в начальной инициализации кластера, если пароли содержат % символы (Bastien Wirtz)

    Метод начальной инициализации выполняет блок DO, при этом все параметры должны быть правильно заключены в кавычки, но метод cursor.execute() не принимает пустой список с переданными параметрами.

  • Исправлена ошибка “AttributeError: no attribute ’leader’” (Hrvoje Milković)

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

  • Исправить ошибку в проверке временной шкалы при расхождениях (Alexander Kukushkin)

    Patroni ошибочно предполагал, что временные шкалы разошлись. Для pg_rewind это не создавало проблем, но если pg_rewind запрещено и remove_data_directory_on_diverged_timelines установлено, это приводило к повторной инициализации предыдущего лидера.


Версия 2.1.2

Выпущено 2021-12-03

Новые возможности

  • Совместимость с psycopg>=3.0 (Alexander Kukushkin)

    По умолчанию используется psycopg2. psycopg\>=3.0 будет использоваться только в том случае, если psycopg2 недоступен или его версия слишком устарела.

  • Добавьте поле dcs_last_seen в REST API (Michael Banck)

    Это поле указывает на последний момент времени (в формате Unix epoch), когда участник кластера успешно взаимодействовал с DCS. Это полезно для выявления и/или анализа сетевых разрывов.

  • Освободите блокировку лидера, когда pg_controldata сообщает о завершении работы (Alexander Kukushkin)

    Для решения проблемы медленного переключения/выключения в случае, когда archive_command работает медленно/неисправно, Patroni удалит ключ лидера сразу после того, как pg_controldata начнет сообщать, что PGDATA является shut down, и подтвердит, что есть хотя бы одна реплика, получившая все изменения. Если нет реплик, удовлетворяющих этому условию, ключ лидера не удаляется, и сохраняется прежнее поведение, i.e. Patroni продолжит обновлять замок.

  • Добавьте поддержку параметра sslcrldir «соединение» (Kostiantyn Nemchenko)

    Новый параметр соединения был введен в PostgreSQL v14.

  • Предоставление возможности настройки ACL для ZNodes в Zookeeper (Alwyn Davis)

    Внедрите новую опцию конфигурации zookeeper.set_acls, чтобы Kazoo применял значение по умолчанию ACL для каждого ZNode, который он создает.

Повышение стабильности

  • Отложите следующий попытку восстановления до следующего цикла HA (Alexander Kukushkin)

    Если PostgreSQL вышли из-за нехватки дискового пространства (например) и не может запуститься из-за этого, Patroni слишком активно пытается его восстановить, что приводит к переполнению логов.

  • Добавьте запись в журнал перед понижением, что может занять некоторое время (Michael Banck)

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

  • Улучшить сообщения статуса “I am” (Michael Banck)

    Сравнение no action. I am a secondary ({0}) и no action. I am ({0}), a secondary

  • Преобразовать в целое число wal_keep_segments при преобразовании в wal_keep_size (Jorge Solórzano)

    Возможно указать wal_keep_segments в виде строки в глобальной динамической конфигурации , и поскольку Python является динамически типизированным языком, строка была просто умножена. Пример: wal_keep_segments: "100" была преобразована в 100100100100100100100100100100100100100100100100MB.

  • Разрешить плановое переключение только к синхронным узлам, когда включена синхронная репликация (Alexander Kukushkin)

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

  • Используйте кэшированную роль в качестве резервного варианта, когда Postgres работает медленно (Alexander Kukushkin)

    В некоторых крайних случаях Postgres может работать настолько медленно, что обычный запрос мониторинга не завершается в течение нескольких секунд. Неправильная обработка statement_timeout может привести к ситуации, когда Postgres не понижается в статусе вовремя, когда истек срок действия ключа лидера или произошла ошибка обновления. В случае возникновения такой ошибки Patroni использует кэшированное role для определения, работает ли Postgres в качестве первичного сервера.

  • Избегайте ненужных обновлений узла члена (Alexander Kukushkin)

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

  • Оптимизировать контрольную точку после повышения (Alexander Kukushkin)

    Избегайте выполнения CHECKPOINT, если последняя временная шкала уже хранится в pg_control. Это помогает избежать ненужных CHECKPOINT сразу после инициализации нового кластера с initdb.

  • Предпочитайте участники, у которых отсутствует nofailover, при выборе узлов для синхронизации (Alexander Kukushkin)

    Ранее узлы для синхронизации выбирались только на основе отставания в репликации, поэтому узел с меткой nofailover имел такие же шансы стать синхронизированным, как и любой другой узел. Это поведение было запутанным и опасным одновременно, поскольку в случае отказа первичного сервера переключение не могло произойти автоматически.

  • Удалите дублирующиеся хосты из кэша etcd на машине (Michael Banck)

    Указанные в кластере etcd URL-адреса клиентов могут быть неправильно настроены. Удаление дубликатов в Patroni в этом случае – это простой и эффективный способ.

Исправления ошибок

  • Пропускать временные слоты репликации при управлении слотами (Alexander Kukushkin)

    Начиная с версии 10 pg_basebackup создает временный слот репликации для потоковой передачи данных WAL, и Patroni пытался его удалить, поскольку имя слота выглядит неизвестным. Чтобы это исправить, мы игнорируем все временные слоты при запросе представления pg_stat_replication_slots.

  • Убедитесь, что pg_replication_slot_advance() не истекает (Alexander Kukushkin)

    Patroni использовал значение по умолчанию statement_timeout в данном случае, и после того, как вызов завершился неудачно, существует очень высокая вероятность, что он никогда не сможет восстановиться, что приведет к увеличению размера pg_wal и pg_catalog.

  • Обновление /status не было выполнено при понижении (Alexander Kukushkin)

    После демотирования PostgreSQL старый лидер обновляет последний LSN в DCS. Начиная с 2.1.0 был введён новый ключ /status, но optime по-прежнему записывался в /optime/leader.

  • Обрабатывать исключения DCS при понижении (Alexander Kukushkin)

    При понижении мастера из-за невозможности обновления блокировки лидера, может произойти ситуация, когда DCS полностью выходит из строя, и вызов get_cluster() вызывает исключение. Если это не обрабатывается должным образом, это приводит к тому, что Postgres остается в остановленном состоянии до восстановления DCS.

  • В некоторых случаях use_unix_socket_repl не функционировал (Alexander Kukushkin)

    В частности, если postgresql.unix_socket_directories не установлено. В этом случае Patroni должен использовать значение по умолчанию из libpq.

  • Устранить несколько проблем в Patroni REST API (Alexander Kukushkin)

    clusters_unlocked иногда не определялся, что приводило к исключениям в конечной точке GET /metrics. Кроме того, механизм обработки ошибок предполагал, что кортеж connect_address всегда содержит два элемента, в то время как в случае IPv6 их может быть больше.

  • Дождитесь завершения восстановления нового узла перед принятием решения о перемотке (Alexander Kukushkin)

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

  • Обрабатывать отсутствующие временные шкалы в файле истории при принятии решения о перемотке (Alexander Kukushkin)

    Если текущая временная шкала реплики отсутствует в файле истории на первичном сервере, реплика ошибочно предполагала, что перемотка не требуется.


Версия 2.1.1

Выпущено 2021-08-19

Новые возможности

  • Поддержка суффикса имени ETCD SRV (David Pavlicek)

    etcd позволяет различать несколько кластеров etcd, находящихся в той же зоне доменного имени, и теперь Patroni также поддерживает это.

  • Расширьте историю с новым лидером (huiyalin525)

    Оно добавляет новую колонку в patronictl history вывод.

  • Сделайте CA-пакет настраиваемым для конфигурации Kubernetes внутри кластера (Aron Parsons)

    По умолчанию Patroni использует /var/run/secrets/kubernetes.io/serviceaccount/ca.crt, и эта новая функция позволяет указать пользовательское kubernetes.cacert.

  • Поддержка динамической регистрации/отписки в качестве сервиса Consul и изменения тегов (Tommy Li)

    Ранее требовалась перезагрузка Patroni.

Исправления ошибок

  • Избегайте ненужного перезапуска REST API (Alexander Kukushkin)

    Предыдущий выпуск добавил функцию перезагрузки REST API сертификатов в случае их изменения на диске. К сожалению, перезагрузка происходила автоматически сразу после запуска.

  • Не разрешайте участники кластера, когда установлено etcd.use_proxies (Alexander Kukushkin)

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

  • Пропускать строки, содержащие значения NULL в столбце pg_stat_replication (Alexander Kukushkin)

    Кажется, что представление pg_stat_replication может содержать значения NULL в полях replay_lsn, flush_lsn или write_lsn, даже когда state = 'streaming'.


Версия 2.1.0

Выпущено 2021-07-06

Эта версия добавляет совместимость с PostgreSQL v14, обеспечивает выживание слотов репликации при переключении, реализует поддержку списка разрешенных REST API, а также уменьшает количество записей в логах до одной строки на сердечный ритм.

Новые возможности

  • Совместимость с PostgreSQL v14 (Alexander Kukushkin)

    Возобновить WAL воспроизведение, если Patroni не находится в режиме “паузы” самостоятельно. Это может быть вызвано изменением определенных параметров, например, max_connections на первичном сервере.

  • Логические слоты для переключения при отказе (Alexander Kukushkin)

    Обеспечьте логическое существование слотов репликации при переключении при отказе/плановом переключении в PostgreSQL v11+. Функция pg_replication_slot_advance() используется для перемещения слота репликации из первичного сервера на реплику после перезапуска, чтобы он был уже создан до переключения. В результате, слот должен существовать заранее, и никаких событий не должно быть потеряно, но существует вероятность, что некоторые события могут быть доставлены несколько раз.

  • Реализована система разрешений для Patroni REST API (Alexander Kukushkin)

    Если настроено, то только IP-адреса, соответствующие правилам, будут разрешены для вызова небезопасных конечных точек. Кроме того, возможно автоматически добавить IP-адреса участников кластера в список.

  • Добавлена поддержка соединения через Unix-сокет (Mohamad El-Rifai)

    Ранее Patroni всегда использовал TCP для соединения с репликацией, что могло вызывать некоторые проблемы с проверкой SSL. Использование Unix-сокет позволяет исключить необходимость проверки учетной записи репликации SSL.

  • Проверка работоспособности по пользовательски определенным тегам (Arman Jafari Tehrani)

    Вместе с предопределенными тегами: можно указать любое количество пользовательских тегов, которые становятся доступными в выводе patronictl list и в REST API. С этого момента пользовательские теги можно использовать в проверках работоспособности.

  • Добавлен конечный /metrics для Prometheus (Mark Mercado, Michael Banck)

    Точка входа, предоставляющая те же метрики, что и /patroni.

  • Уменьшение объема логов Patroni (Alexander Kukushkin)

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

Изменения, нарушающие совместимость

  • Старая функция permanent logical replication slots больше не будет работать с PostgreSQL v10 и более ранними версиями (Alexander Kukushkin)

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

  • Конечная точка /leader всегда возвращает 200, если узел удерживает блокировку (Alexander Kukushkin)

    Для продвижения резервного кластера необходимо обновить проверки работоспособности балансировщика нагрузки, что не очень удобно и легко забывается. Чтобы это решить, мы изменяем поведение конечной точки проверки работоспособности /leader. Она будет возвращать 200, не учитывая, является ли кластер нормальным или нет, и standby_cluster .

Улучшения поддержки Raft

  • Надежная поддержка шифрования трафика Raft (Alexander Kukushkin)

    Из-за различных проблем в PySyncObj поддержка шифрования была очень нестабильной

  • Обработка проблем DNS в реализации Raft (Alexander Kukushkin)

    Если self_addr и/или partner_addrs настроены с использованием имени DNS вместо IP-адреса, то PySyncObj фактически выполнял разрешение только один раз при создании объекта. Это приводило к проблемам, когда один и тот же узел восстанавливался и имел другой IP-адрес.

Повышение стабильности

  • Совместимость с psycopg2-2.9+ (Alexander Kukushkin)

    В psycopg2, autocommit = True игнорируется в блоке with connection, что приводит к разрыву соединений протокола репликации.

  • Устранение избыточных операций HA с использованием Zookeeper (Alexander Kukushkin)

    Обновление ZNodes участника приводило к цепной реакции и приводило к многократному запуску циклов HA.

  • Обновите конфигурацию, если сертификат REST API был изменен на диске (Michael Todorovic)

    Если файл сертификата REST API был обновлен на месте, Patroni не выполнил перезагрузку.

  • Не создавайте каталог pgpass, если используется аутентификация Kerberos (Kostiantyn Nemchenko)

    Аутентификация с использованием Kerberos и пароля несовместима.

  • Устранены незначительные проблемы с пользовательской начальной инициализацией (Alexander Kukushkin)

    Начните работу с PostgreSQL, используя hot_standby=off, только когда выполняется PITR, и перезапустите его после завершения PITR.

Исправления ошибок

  • Совместимость с kazoo-2.7+ (Alexander Kukushkin)

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

  • Явно указывать версию кластера etcd v3 при подключении через прокси (Alexander Kukushkin)

    Patroni работает с кластером etcd v3 через gPRC-шлюз, и в зависимости от версии кластера необходимо использовать различные конечные точки /v3, /v3beta или /v3alpha. Версия была определена только совместно с топологией кластера, но поскольку последняя никогда не определялась при подключении через прокси.


Версия 2.0.2

Выпущено 2021-02-22

Новые возможности

  • Возможность игнорировать репликационные слоты, управляемые извне (James Coleman)

    Patroni пытается удалить любой слот репликации, который ему неизвестен, но существуют случаи, когда слоты репликации следует управлять вне Patroni. Теперь возможно настроить слоты, которые не следует удалять.

  • Добавлена поддержка ограничения на выбор набора шифров для REST API (Gunnar “Nick” Bluth)

    Его можно было настроить через restapi.ciphers или переменную окружения PATRONI_RESTAPI_CIPHERS.

  • Добавлена поддержка для зашифрованных TLS ключей для REST API (Jonathan S. Katz)

    Его можно было настроить через restapi.keyfile_password или переменную окружения PATRONI_RESTAPI_KEYFILE_PASSWORD.

  • Сравнение учетных данных REST и API с постоянной задержкой (Alex Brasetvik)

    Используйте hmac.compare_digest() вместо ==, который подвержен атакам, основанным на времени.

  • Выбирайте узлы, работающие в синхронном режиме, на основе отставания в репликации (Krishna Sarabu)

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

Повышение стабильности

  • Запустите PostgreSQL с hot_standby = off при выполнении пользовательской начальной инициализации (Igor Yanchenko)

    Во время пользовательской начальной инициализации Patroni восстанавливает резервную копию, запускает PostgreSQL и ожидает завершения восстановления. Некоторые параметры PostgreSQL на резервном сервере не должны быть меньше, чем на первичном, и если новое значение (восстановленное из WAL) больше, чем сконфигурированное, PostgreSQL падает и останавливается. Чтобы избежать такого поведения, мы выполним пользовательскую начальную инициализацию без режима hot_standby.

  • Предупредить пользователя, если требуемый сторожевой таймер не работает (Nicolas Thauvin)

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

  • Улучшенная детализация процесса восстановления в однопользовательском режиме (Alexander Kukushkin)

    Если Patroni обнаружит, что PostgreSQL не был завершен корректно, в определенных случаях выполняется восстановление путем запуска PostgreSQL в однопользовательском режиме. Возможно, что восстановление завершится неудачно (например, из-за нехватки места на диске), но ошибки будут проигнорированы.

  • Добавлена совместимость с python-consul2 (Alexander Kukushkin, Wilfried Roset)

    Старая, но проверенная python-consul уже несколько лет не поддерживается, поэтому кто-то создал форк с новыми функциями и исправлениями ошибок.

  • Не используйте bypass_api_service при выполнении patronictl (Alexander Kukushkin)

    Когда под K8s выполняется в не default пространстве имён, у него может не хватать прав для запроса к конечной точке kubernetes . В этом случае Patroni выводит предупреждение и игнорирует настройку bypass_api_service. В случае patronictl это предупреждение было немного раздражающим.

  • Создать raft.data_dir, если он не существует, или убедиться, что он доступен для записи (Mark Mercado)

    Улучшает удобство использования и понятность для пользователя.

Исправления ошибок

  • Не прерывайте перезапуск или продвижение, если потеряна блокировка лидера в режиме ожидания (Alexander Kukushkin)

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

  • Устраненная проблема с shutdown_request() в REST API (Nicolas Limage)

    Для улучшения обработки SSL соединений и отсрочки рукопожатия до запуска потока, Patroni переопределяет несколько методов в HTTPServer. Метод shutdown_request() был упущен.

  • Устранен проблема со временем сна при использовании Zookeeper (Alexander Kukushkin)

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

  • Исправлена некорректная работа os.symlink() при перемещении каталога данных после неудачной начальной инициализации (Andrew L’Ecuyer)

    Если начальная инициализация завершилась неудачно, Patroni переименовывает каталог данных, pg_wal, и все таблицы. Затем она обновляет символические ссылки, чтобы файловая система оставалась согласованной. Создание символических ссылок не удавалось из-за перепутанных аргументов src и dst.

  • Исправлена ошибка в методе post_bootstrap (Alexander Kukushkin)

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

  • Исправлена проблема pg_rewind в резервном кластере (Alexander Kukushkin)

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

  • Выход должен осуществляться только в случае явного неуспеха аутентификации с использованием etcd v3 (Alexander Kukushkin)

    При запуске Patroni выполняет обнаружение топологии кластера etcd и аутентификацию, если это необходимо. Возможно, один из серверов etcd недоступен, и Patroni пытается выполнить аутентификацию на этом сервере, но не удается, вместо этого Patroni не пытается выполнить аутентификацию на следующем узле.

  • Обработка случая, когда cmdline() возвращает пустой список (Alexander Kukushkin)

    Зомби-процессы по-прежнему являются дочерними процессами postmaster, но у них отсутствует cmdline()

  • Рассматривайте переменную окружения PATRONI_KUBERNETES_USE_ENDPOINTS как логическое значение (Alexander Kukushkin)

    Не это приводило к невозможному отключению kubernetes.use_endpoints через переменные окружения.

  • Улучшить обработку ошибок при одновременном обновлении конечных точек (Alexander Kukushkin)

    Patroni явно запросит текущий объект конечной точки, убедится, что текущий под действительно удерживает блокировку лидера, и повторит обновление.


Версия 2.0.1

Выпущено 2020-10-01

Новые возможности

  • Используйте more в качестве пейджера в patronictl edit-config, если less недоступен (Pavel Golub)

    На Windows это будет more.com. Кроме того, cdiff был изменён на ydiff в requirements.txt, однако patronictl по-прежнему поддерживает оба варианта ради совместимости.

  • Добавлена поддержка raft, bind_addr и password (Alexander Kukushkin)

    raft.bind_addr может быть полезен при работе за NAT. raft.password включает шифрование трафика (требует модуля cryptography).

  • Добавлена поддержка параметра sslpassword “соединение” (Kostiantyn Nemchenko)

    Параметр соединения был введен в PostgreSQL 13.

Повышение стабильности

  • Изменили поведение в режиме паузы (Alexander Kukushkin)

    1. Patroni не будет вызывать метод bootstrap, если каталог PGDATA отсутствует или пуст.
    2. Patroni не завершит работу при несовпадении sysid в режиме паузы, а только запишет предупреждение.
    3. Узел не будет пытаться захватить ключ лидера в режиме паузы, если Postgres работает не в режиме восстановления (принимает записи), но sysid не совпадает с ключом initialize.
  • Применять master_start_timeout при выполнении восстановления после сбоя (Alexander Kukushkin)

    Если PostgreSQL упал на узле, являющемся лидером, Patroni выполняет восстановление после сбоя, запуская PostgreSQL в однопользовательском режиме. Во время восстановления после сбоя обновляется блокировка лидера. Если восстановление после сбоя не завершится в течение master_start_timeout секунд, Patroni прервет его и освободит блокировку лидера.

  • Удалено из требований urllib3 лишнее secure (Alexander Kukushkin)

    Единственная причина добавления его туда заключалась в необходимости ipaddress для Python 2.7.

Исправления ошибок

  • Исправлена ошибка в Kubernetes.update_leader() (Alexander Kukushkin)

    Необработанное исключение препятствовало понижению первичного сервера, когда завершение обновления объекта лидера завершилось неудачно.

  • Исправлена проблема с зависанием patronictl при использовании RAFT (Alexander Kukushkin)

    При использовании patronictl с конфигурацией Patroni, необходимо добавить self_addr в partner_addrs.

  • Исправлена ошибка get_guc_value() (Alexander Kukushkin)

    Patroni не мог получить значение restore_command в PostgreSQL 12, поэтому попытки восстановить отсутствующие WAL-файлы pg_rewind не увенчались успехом.


Версия 2.0.0

Выпущено 2020-09-02

Эта версия улучшает совместимость с PostgreSQL 13, добавляет поддержку нескольких синхронных резервных серверов, имеет значительные улучшения в обработке pg_rewind, добавляет поддержку etcd v3 и Patroni на чистом RAFT (без etcd, Consul или Zookeeper), и позволяет опционально вызывать скрипт pre_promote (защиты).

Поддержка PostgreSQL 13

  • Не запускайте on_reload при переходе в режим лидера standby_leader на PostgreSQL 13+ (Alexander Kukushkin)

    Когда мы повышаем standby_leader, мы изменяем primary_conninfo, обновляем роль и перезагружаем Postgres. Поскольку on_role_change и on_reload по сути являются одинаковыми, Patroni будет вызывать только on_role_change.

  • Добавлена поддержка параметров gssencmode и channel_binding для соединения (Alexander Kukushkin)

    PostgreSQL 12 ввел параметры gssencmode и 13 channel_binding, и теперь они могут использоваться, если определены в разделе postgresql.authentication.

  • Обработка переименования wal_keep_segments в wal_keep_size (Alexander Kukushkin)

    В случае неправильной конфигурации (на wal_keep_segments и 13, а также на wal_keep_size в старых версиях) Patroni автоматически скорректирует конфигурацию.

  • Используйте pg_rewind в сочетании с --restore-target-wal в 13, если это возможно (Alexander Kukushkin)

    На PostgreSQL 13 Patroni проверяет, настроена ли restore_command, и сообщает pg_rewind о необходимости её использования.

Новые возможности

  • BETABETA

    Реализована поддержка Patroni на чистом RAFT (Alexander Kukushkin)

    Это позволяет запускать Patroni без сторонних зависимостей (3rd party), таких как Etcd, Consul или Zookeeper. Для высокой доступности потребуется либо три узла Patroni, либо два узла Patroni и один узел с patroni_raft_controller. Дополнительные сведения приведены в документации .

  • BETABETA

    Реализована поддержка протокола etcd v3 через gPRC-gateway (Alexander Kukushkin)

    etcd 3.0 был выпущен более чем четыре года назад, а etcd 3.4 имеет отключенную версию 2 по умолчанию. Также существует вероятность полного удаления версии 2 из etcd, поэтому мы реализовали поддержку etcd v3 в Patroni. Чтобы начать её использовать, необходимо явно создать раздел etcd3 в файле конфигурации Patroni.

  • Поддержка нескольких синхронных резервных серверов (Krishna Sarabu)

    Это позволяет запускать кластер с несколькими синхронными репликами. Максимальное количество синхронных реплик контролируется новым параметром synchronous_node_count. По умолчанию он установлен в 1 и не оказывает никакого влияния, когда synchronous_mode установлено в off.

  • Добавлена возможность вызова скрипта pre_promote (Sergey Dudoladov)

    В отличие от обратных вызовов, сценарий pre_promote вызывается синхронно после получения блокировки лидера, но до повышения Postgres. Если сценарий завершается с ошибкой или выходит с ненулевым кодом возврата, текущий узел освободит блокировку лидера.

  • Добавлена поддержка каталогов конфигурации (Floris van Nee)

    YAML файлы в каталоге загружаются и применяются в алфавитном порядке.

  • Продвинутая проверка параметров PostgreSQL (Alexander Kukushkin)

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

  • Активируйте основной поток при завершении принудительной проверки после повышения (Alexander Kukushkin)

    Реплики ожидают указания о точке контроля через ключ участника лидера в DCS. Ключ обычно обновляется только один раз в каждом цикле обеспечения высокой доступности. Без пробуждения основного потока, реплики должны ждать до loop_wait секунд дольше, чем необходимо.

  • Использование представления pg_stat_wal_receiver в 9.6+ (Alexander Kukushkin)

    Вид содержит актуальные значения primary_conninfo и primary_slot_name, в то время как содержимое recovery.conf может быть устаревшим.

  • Улучшенная обработка IPv6-адресов в файле конфигурации Patroni (Mateusz Kowalski)

    IPv6-адрес должен быть заключен в квадратные скобки, но Patroni ожидал получить его в виде обычного текста. Теперь поддерживаются оба формата.

  • Добавлена конфигурационная опция Consul service_tags (Robert Edström)

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

  • Реализована поддержка SSL для Zookeeper (Kostiantyn Nemchenko)

    Для этого требуется kazoo>=2.6.0.

  • Реализована опция no_params для пользовательского метода начальной инициализации (Kostiantyn Nemchenko)

    Оно позволяет вызывать wal-g, pgBackRest и другие инструменты резервного копирования, не используя оболочные скрипты.

  • Переместите WAL и пространства таблиц после неудачной инициализации (Feike Steenbergen)

    При выполнении reinit Patroni уже удалял не только PGDATA, но и символические ссылки на WAL, а также каталоги таблиц и таблицы. Теперь метод move_data_directory() будет выполнять аналогичную задачу, i.e. переименовывает WAL каталоги и таблицы, а также обновляет символические ссылки в PGDATA.

Улучшена поддержка pg_rewind

  • Улучшена проверка на расхождение временных шкал (Alexander Kukushkin)

    Не требуется перемотка, когда место, которое необходимо воспроизвести, на реплике находится позади точки отката или конец записи контрольной точки на бывшем первичном сервере совпадает с точкой отката. Для получения конца записи контрольной точки используется pg_waldump и её вывод.

  • Попытайтесь получить отсутствующий WAL, если pg_rewind сообщает о проблеме (Alexander Kukushkin)

    Возможно, что сегмент WAL, необходимый для pg_rewind, больше не находится в каталоге pg_wal, и, следовательно, pg_rewind не может найти местоположение контрольной точки до точки разрыва. Начиная с PostgreSQL 13 pg_rewind можно использовать restore_command для получения отсутствующих WAL. Для более старых версий PostgreSQL Patroni анализирует ошибки неудачной попытки перемотки и пытается получить отсутствующие WAL, вызывая restore_command самостоятельно.

  • Обнаружить новую временную шкалу в резервном кластере и инициировать перемотку/переинициализацию, если это необходимо (Alexander Kukushkin)

    Кластер standby_cluster отвязан от первичного кластера и поэтому не сразу узнаёт о выборах лидера и смене временных шкал. Чтобы обнаружить факт смены, standby_leader периодически проверяет наличие новых файлов истории в pg_wal.

  • Укоротить и улучшить вывод журнала истории (Alexander Kukushkin)

    Когда Patroni пытается определить необходимость pg_rewind, он может извлечь содержимое файла истории с первичного сервера и записать его в лог. Файл истории увеличивается с каждым переключением/плановым переключением и в конечном итоге занимает слишком много строк, большинство из которых не являются полезными. Вместо отображения исходных данных, Patroni отобразит только 3 строк до текущей временной шкалы реплики и 2 строк после нее.

Улучшения для K8s

  • Удалите модуль kubernetes для Python (Alexander Kukushkin)

    Официальный клиент Python для Kubernetes содержит много автогенерируемого кода и, следовательно, очень тяжёлый. Patroni использует лишь небольшую часть конечных точек K8s API, и реализация поддержки для них не представляла сложности.

  • Обеспечить возможность обхода Kubernetes сервиса (Alexander Kukushkin)

    Когда Patroni работает в K8s, он обычно взаимодействует с K8s API через сервис kubernetes , адрес которого указывается в переменной окружения KUBERNETES_SERVICE_HOST. Как и любой другой сервис, сервис kubernetes управляется kube-proxy, который, в свою очередь, в зависимости от конфигурации, либо использует пользовательскую программу, либо iptables для маршрутизации трафика. Пренебрегая промежуточным компонентом и подключаясь напрямую к узлам K8s master, мы можем реализовать более эффективную стратегию повторных попыток и снизить риски деградации Postgres при обновлении узлов K8s master.

  • Синхронизация циклов высокой доступности всех подов кластера Patroni (Alexander Kukushkin)

    Не это приводило к увеличению времени обнаружения сбоев с ttl до ttl + loop_wait.

  • Заполните references и nodename в подмножествах адресов на K8s (Alexander Kukushkin)

    Некоторые балансировщики нагрузки используют эту информацию.

  • Устранить возможные условия гонки в update_leader() (Alexander Kukushkin)

    Одновременное обновление конфигурации лидера или конечной точки, происходящее вне Patroni, может привести к неудаче вызова update_leader(). В этом случае Patroni проверяет, что текущий узел по-прежнему владеет блокировкой лидера, и повторяет обновление.

  • Явно запретить обновление конфигурации несуществующих файлов (Alexander Kukushkin)

    Для DCS, отличного от kubernetes , вызов PATCH завершается с исключением из-за того, что cluster.config является None, но в Kubernetes он успешно создавал аннотацию конфигурации и запрещал запись конфигурации начальной инициализации после завершения начальной инициализации.

  • Исправлена ошибка в pause (Alexander Kukushkin)

    Реплики удаляли primary_conninfo и перезапускали PostgreSQL, когда отсутствовал ключ лидера, но они должны были ничего не делать.

Улучшения REST API

  • Отложить установку TLS до запуска потока рабочего процесса (Alexander Kukushkin, Ben Harris)

    Если рукопожатие TLS было выполнено в потоке API, и клиент не отправлял никаких данных, то поток API был заблокирован (что создавало риск DoS).

  • Проверьте basic-auth независимо от сертификата клиента в REST API (Alexander Kukushkin)

    Ранее проверялась только сертификат клиента. Независимая проверка двух параметров является абсолютно допустимым сценарием использования.

  • Добавьте двойной CRLF после заголовков HTTP запроса OPTIONS (Sergey Burladyan)

    HAProxy был доволен одним CRLF, в то время как проверка состояния Consul жаловалась на разорванное соединение и неожиданный EOF.

  • GET /cluster отображал устаревшую информацию об участниках кластера Zookeeper (Alexander Kukushkin)

    Этот эндпоинт использовал внутренний вид кластера Patroni. Для самого Patroni это не вызывало никаких проблем, но при экспозиции во внешний мир необходимо отображать актуальную информацию, особенно отставание репликации.

  • Фиксированные проверки работоспособности для кластера резервных серверов (Alexander Kukushkin)

    Ошибочно отвечали GET /standby-leader для мастера и GET /master для standby_leader с 200.

  • Реализовано DELETE /switchover (Alexander Kukushkin)

    Вызов REST API удаляет запланированное переключение.

  • Созданы конечные точки /readiness и /liveness (Alexander Kukushkin)

    Они могут быть полезны для удаления «нездоровых» подов из подмножества адресов при использовании сервиса K8s с выборками по меткам.

  • Улучшены GET /replica и GET /async REST API проверки работоспособности (Krishna Sarabu, Alexander Kukushkin)

    Проверки теперь поддерживают необязательный ключевое слово ?lag=<max-lag> и будут отвечать 200 только в том случае, если отставание меньше указанного значения. Если вы используете эту функцию, пожалуйста, обратите внимание, что информация о позиции WAL на лидере обновляется только каждые loop_wait секунд!

  • Добавлена поддержка пользовательских заголовков HTTP в ответах REST API (Yogesh Sharma)

    Эта функция может оказаться полезной, если запросы поступают из браузера.

Улучшения patronictl

  • Не пытайтесь обращаться к несуществующему лидеру patronictl pause (Alexander Kukushkin)

    При приостановке кластера без лидера в K8s, patronictl выводил предупреждения о том, что участник “None” недоступен.

  • Обработать ситуацию, когда участник conn_url отсутствует (Alexander Kukushkin)

    На K8s возможно, что у пода отсутствуют необходимые аннотации, поскольку Patroni ещё не запущен. Это приводило к сбою patronictl .

  • Добавлена возможность вывода топологии ASCII кластера (Maxim Fedotov, Alexander Kukushkin)

    Очень полезно получить обзор кластера с каскадным репликацией.

  • Реализовать patronictl flush switchover (Alexander Kukushkin)

    До этого patronictl flush поддерживал только отмену запланированных перезапусков.

Исправления ошибок

  • Ошибка атрибута во время начальной инициализации кластера с существующим PGDATA (Krishna Sarabu)

    При попытке создать/обновить ключ /history, Patroni обращался к объекту ClusterConfig, который ещё не был создан в DCS.

  • Улучшена обработка исключений в Consul (Alexander Kukushkin)

    Необработанное исключение в методе touch_member() привело к аварийному завершению всего процесса Patroni.

  • Обеспечить выполнение synchronous_commit=local для скрипта post_init (Alexander Kukushkin)

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

  • Увеличение maxsize в менеджере пула Consul (ponvenkates)

    Со значением по умолчанию size=1 были сгенерированы предупреждения.

  • Patroni некорректно сообщал о запуске Postgres (Alexander Kukushkin)

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

  • Поместите * в pgpass вместо отсутствующих или пустых значений (Alexander Kukushkin)

    Если, например, standby_cluster.port не указан, то файл pgpass был создан некорректно.

  • Пропускать создание слота репликации на узле-лидере, если он содержит специальные символы (Krishna Sarabu)

    Patroni создаёт спящий слот (когда slots определено) для узла-лидера, когда имя содержит специальные символы, такие как ‘-’, (для e.g, например, “abc-us-1”).

  • Избегайте удаления несуществующих pg_hba.conf в пользовательской начальной инициализации (Krishna Sarabu)

    Patroni завершался неудачно, если pg_hba.conf находился за пределами директории pgdata после пользовательской начальной инициализации.


Версия 1.6.5

Выпущено 2020-08-23

Новые возможности

  • Тайм-аут остановки мастера (Krishna Sarabu)

    Количество секунд, которое Patroni может ожидать при остановке Postgres. Действует только при включении , synchronous_mode, . Если установлено значение больше 0 и включено , synchronous_mode, , Patroni отправляет SIGKILL в postmaster, если операция остановки выполняется дольше, чем значение, установленное master_stop_timeout. Установите значение в соответствии с вашим соотношением надежности/доступности. Если параметр не установлен или имеет значение, не равное нулю, master_stop_timeout не оказывает никакого эффекта.

  • Не создавайте постоянный физический слот с именем первичного сервера (Alexander Kukushkin)

    Это распространенная проблема, когда первичный сервер перераспределяет WAL сегменты, в то время как реплика находится в неактивном состоянии. Теперь у нас есть хорошее решение для статических кластеров с фиксированным количеством узлов и именами, которые никогда не меняются. Вам просто нужно перечислить имена всех узлов в slots, чтобы первичный сервер не удалял сегмент, когда узел не зарегистрирован в DCS.

  • Первый вариант конфигурационного валидатора (Igor Yanchenko)

    Используйте patroni --validate-config patroni.yaml для проверки конфигурации Patroni.

  • Возможность настроить максимальную длину истории временной шкалы (Krishna Sarabu)

    Patroni записывает историю переключений при отказе/планового переключения в ключ /history в DCS. Со временем размер этого ключа становится большим, но в большинстве случаев интересны только последние несколько строк. Параметр max_timelines_history позволяет указать максимальное количество элементов временной шкалы, которые необходимо хранить в DCS.

  • Совместимость с Kazoo 2.7.0 (Danyal Prout)

    Некоторые внутренние методы в Kazoo изменили свои сигнатуры, но Patroni продолжал их использовать.

Улучшения patronictl

  • Показать теги участников (Kostiantyn Nemchenko, Alexander Kukushkin)

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

  • Улучшить вывод участников (Alexander Kukushkin)

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

$ patronictl list
+ Cluster: batman (6813309862653668387) +---------+----+-----------+---------------------+
|    Member   |      Host      |  Role  |  State  | TL | Lag in MB | Tags                |
+-------------+----------------+--------+---------+----+-----------+---------------------+
| postgresql0 | 127.0.0.1:5432 | Leader | running |  3 |           | clonefrom: true     |
|             |                |        |         |    |           | noloadbalance: true |
|             |                |        |         |    |           | nosync: true        |
+-------------+----------------+--------+---------+----+-----------+---------------------+
| postgresql1 | 127.0.0.1:5433 |        | running |  3 |       0.0 |                     |
+-------------+----------------+--------+---------+----+-----------+---------------------+
  • Выдавать ошибку, если указан файл конфигурации, но он не найден (Kaarel Moppel)

    Ранее patronictl сообщал только об одном DEBUG сообщении.

  • Устранена проблема с непроинициализированным K8s-подом, приводящим к сбоям patronictl (Alexander Kukushkin)

    Patroni опирается на определенные аннотации для контейнеров в K8s. Когда один из контейнеров Patroni останавливается или запускается, соответствующих аннотаций еще нет, и patronictl выдавал исключение.

Повышение стабильности

  • Применить задержку 1 при неудаче вызова сервера K8s LIST API (Alexander Kukushkin)

    В основном необходимо избегать перегрузки логов, но также это помогает предотвратить зависание основного потока.

  • Повторите попытку, если возвращается retry-after HTTP заголовок от K8s API (Alexander Kukushkin)

    Если сервер K8s API перегружен запросами, он может запросить повторную попытку.

  • Очистите KUBERNETES_ окружение от почтового сервера (Feike Steenbergen)

    Переменные окружения KUBERNETES_ не требуются для PostgreSQL, однако их раскрытие для postmaster также раскрывает их для бэкендов и обычных пользователей базы данных (например, с использованием pl/perl).

  • Очистка табличных пространств при повторном инициализации (Krishna Sarabu)

    Во время повторной инициализации Patroni удалял только PGDATA и оставлял пользовательские каталоги таблиц. Это приводило к тому, что Patroni зацикливался при повторной инициализации. Предыдущее решение этой проблемы заключалось в реализации пользовательского скрипта для начальной инициализации .

  • Непосредственно выполнить CHECKPOINT после продвижения (Alexander Kukushkin)

    Это помогает сократить время, необходимое для использования нового первичного сервера pg_rewind.

  • Умное обновление участников etcd (Alexander Kukushkin)

    В случае, если Patroni не смог выполнить запрос на всех участниках кластера etcd, Patroni будет повторно проверять A или SRV записи на предмет изменений IP-адресов/хостов перед повторной попыткой.

  • Пропускать отсутствующие значения из pg_controldata (Feike Steenbergen)

    Значения отсутствуют при попытке использовать бинарные файлы версии, которая не соответствует PGDATA. Patroni попытается запустить Postgres, и Postgres сообщит, что основная версия не соответствует, и завершит работу с ошибкой.

Исправления ошибок

  • Отключить проверку SSL для Consul при необходимости (Julien Riou)

    Начиная с определенной версии urllib3, необходимо явно установить cert_reqs в значение ssl.CERT_NONE, чтобы эффективно отключить проверку SSL.

  • Избегайте открытия соединения репликации на каждом цикле цикла отказоустойчивости (Alexander Kukushkin)

    Ошибку было внесено в 1.6.4.

  • Вызвать обратный вызов on_role_change при отказе первичного сервера (Alexander Kukushkin)

    В определенных случаях это может привести к тому, что виртуальный IP-адрес останется привязанным к старому первичному серверу. Ошибка была внесена в 1.4.5.

  • Сбросить состояние отката, если PostgreSQL был запущен после успешного pg_rewind (Alexander Kukushkin)

    В результате этой ошибки Patroni запускался, при этом PostgreSQL автоматически отключался в режиме паузы.

  • Преобразуйте recovery_min_apply_delay в ms при проверке recovery.conf

    Patroni непрерывно перезапускал реплику, если recovery_min_apply_delay было настроено в PostgreSQL, выпущенной до 12.

  • Совместимость с PyInstaller (Alexander Kukushkin)

    PyInstaller создает (упаковывает) приложения Python в автономные исполняемые файлы. Совместимость была нарушена, когда мы перешли от метода spawn вместо fork для multiprocessing.


Версия 1.6.4

Выпущено 2020-01-27

Новые возможности

  • Реализована опция --wait для patronictl reinit (Igor Yanchenko)

    Patronictl будет ждать завершения reinit, если используется опция --wait.

  • Дальнейшее улучшение поддержки Windows (Igor Yanchenko, Alexander Kukushkin)

    1. Все скрипты оболочки, используемые для интеграционных тестов, переписываются на Python.
    2. Команда pg_ctl kill будет использоваться для остановки PostgreSQL на не-POSIX системах.
    3. Не пытайтесь использовать сокеты Unix-домена.

Повышение стабильности

  • Убедитесь, что unix_socket_directories и stats_temp_directory существуют (Igor Yanchenko)

    При запуске Patroni и Postgres убедитесь, что unix_socket_directories и stats_temp_directory существуют, или попробуйте их создать. Patroni завершится, если не удастся их создать.

  • Убедитесь, что postgresql.pgpass находится в месте, где Patroni имеет права на запись (Igor Yanchenko)

    В случае, если у Patroni отсутствует доступ для записи, он завершится с исключением.

  • Отключить проверку Consul serfHealth по умолчанию (Kostiantyn Nemchenko)

    Даже в случае незначительных проблем с сетью, неисправный serfHealth приводит к недействительности всех сессий, связанных с узлом. Следовательно, ключ лидера теряется гораздо раньше, чем ttl, что приводит к нежелательным перезапускам реплик и, возможно, понижению первичного сервера.

  • Настроить keepalives для TCP-соединений с K8s API (Alexander Kukushkin)

    В случае, если мы не получим никакой информации от сокета после TTL секунд, его можно считать неактивным.

  • Избегайте ведения журнала паролей при создании пользователя (Alexander Kukushkin)

    Если пароль отклонен или ведение журнала настроено на подробный режим или вообще не настроено, то пароль может быть записан в логи PostgreSQL. Чтобы этого избежать, Patroni изменит log_statement, log_min_duration_statement и log_min_error_statement на безопасные значения перед попыткой создания/обновления пользователя.

Исправления ошибок

  • Используйте restore_command из конфигурации standby_cluster для создания реплик в кластере (Alexander Kukushkin)

    Функция standby_leader уже была реализована изначально, и эта функция существовала. Отсутствие её реализации на репликах может помешать им синхронизироваться с резервным лидером.

  • Обновить временную шкалу, предоставленную резервным кластером (Alexander Kukushkin)

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

  • Предоставьте возможность определять определенные параметры восстановления в custom_conf (Alexander Kukushkin)

    Когда выполняется проверка параметров восстановления на реплике Patroni, будут пропущены archive_cleanup_command, promote_trigger_file, recovery_end_command, recovery_min_apply_delay и restore_command, если они не определены в конфигурации Patroni, но определены в других файлах, отличных от postgresql.auto.conf и postgresql.conf.

  • Улучшить обработку параметров PostgreSQL, содержащих точку в их имени (Alexander Kukushkin)

    Такие параметры могут быть определены с помощью расширений, где единица не обязательно является строкой. Изменение значения может потребовать перезапуска (например, pg_stat_statements.max).

  • Улучшить обработку исключений при завершении работы (Alexander Kukushkin)

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


Версия 1.6.3

Выпущено 2019-12-05

Исправления ошибок

  • Не раскрывайте пароль при запуске pg_rewind (Alexander Kukushkin)

    Ошибка была внесена в #1301

  • Применить параметры соединения, указанные в postgresql.authentication, к pg_basebackup и использовать собственные методы создания реплик (Alexander Kukushkin)

    Они полагались на строку соединения, похожую на URL, и, следовательно, параметры никогда не применялись.


Версия 1.6.2

Выпущено 2019-12-05

Новые возможности

  • Реализовано patroni --version (Igor Yanchenko)

    Отображает текущую версию Patroni и завершает работу.

  • Установите заголовок user-agent HTTP для всех HTTP-запросов (Alexander Kukushkin)

    Patroni взаимодействует с Consul, etcd и Kubernetes API посредством протокола http. Использование специально разработанного user-agent (например, Patroni/1.6.2 Python/3.6.8 Linux) может быть полезным для отладки и мониторинга.

  • Обеспечить возможность настройки уровня логирования для трассировок исключений (Igor Yanchenko)

    Если вы установите log.traceback_level=DEBUG, то трассировки будут видны только при log.level=DEBUG. По умолчанию поведение остается прежним.

Повышение стабильности

  • Избегайте импорта всех DCS модулей при поиске модуля, требуемого файлом конфигурации (Alexander Kukushkin)

    Не требуется импортировать модули для etcd, Consul и Kubernetes, если нам необходимо только e.g. Zookeeper. Это помогает снизить потребление памяти и решить проблему, связанную с сообщениями INFO и Failed to import smth.

  • Удалено модуль python requests из явных требований (Alexander Kukushkin)

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

  • Улучшить обработку etcd.hosts, представленного в виде строки, разделенной запятыми, вместо массива YAML (Igor Yanchenko)

    Ранее возникали ошибки при записи в формате host1:port1, host2:port2 (пробел после запятой).

Улучшения удобства использования

  • Не заставляйте пользователей выбирать участников из пустого списка в patronictl (Igor Yanchenko)

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

  • Сделайте сообщение об ошибке более информативным, если REST API не могут быть сопоставлены (Igor Yanchenko)

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

Исправления ошибок

  • Исправить расчет wal_buffers (Alexander Kukushkin)

    Единица измерения была изменена с 8 kB блоков на байты в PostgreSQL 11.

  • Используйте passfile в primary_conninfo только в PostgreSQL 10+ (Alexander Kukushkin)

    На старых версиях нет гарантии, что passfile будет работать, если установлена последняя версия libpq.


Версия 1.6.1

Выпущено 2019-11-15

Новые возможности

  • Добавлена переменная окружения PATRONICTL_CONFIG_FILE (msvechla)

    Это позволяет настраивать аргумент --config-file для patronictl из окружения.

  • Реализовать patronictl history (Alexander Kukushkin)

    Отображает историю переключений при отказе/планового переключения.

  • Передавайте -c statement_timeout=0 в PGOPTIONS при выполнении pg_rewind (Alexander Kukushkin)

    Оно защищает от ситуации, когда statement_timeout на сервере установлено на какое-то небольшое значение, и одно из утверждений, выполняемых pg_rewind, отменяется.

  • Разрешить использование более низких значений для конфигурации PostgreSQL (Soulou)

    Patroni не позволял устанавливать некоторые параметры конфигурации PostgreSQL ниже определенных фиксированных значений. Теперь минимально допустимые значения стали меньше, значения по умолчанию не были изменены.

  • Предусмотрите возможность аутентификации на основе сертификатов (Jonathan S. Katz)

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

  • Используйте passfile в primary_conninfo вместо пароля (Alexander Kukushkin)

    Это позволяет избежать установки разрешений 600 на postgresql.conf

  • Выполнять pg_ctl reload независимо от изменений конфигурации (Alexander Kukushkin)

    Возможно, некоторые файлы конфигурации не управляются Patroni. Когда кто-либо выполняет перечитывание конфигурации через REST API или отправляет SIGHUP процессу Patroni, обычно ожидается, что будет перечитан и Postgres. Ранее этого не происходило, когда в секции postgresql конфигурации Patroni не было изменений.

  • Сравните все параметры восстановления, включая primary_conninfo (Alexander Kukushkin)

    Ранее метод check_recovery_conf() проверял только, изменилось ли primary_conninfo, не учитывая при этом все остальные параметры восстановления.

  • Обеспечить возможность применения некоторых параметров восстановления без перезапуска (Alexander Kukushkin)

    Начиная с PostgreSQL 12, следующие параметры восстановления можно изменять без перезапуска: archive_cleanup_command, promote_trigger_file, recovery_end_command и recovery_min_apply_delay. В будущих версиях PostgreSQL этот список будет расширен, и Patroni автоматически его поддержит.

  • Обеспечить возможность изменения use_slots в режиме онлайн (Alexander Kukushkin)

    Ранее требовалось перезапускать Patroni и удалять слоты вручную.

  • Удалять только переменные окружения, начинающиеся с PATRONI_ при запуске Postgres (Cody Coons)

    Это решит многие проблемы, связанные с работой различных внешних драйверов данных.

Повышение стабильности

  • Используйте LIST и WATCH при работе с K8s API (Alexander Kukushkin)

    Позволяет эффективно получать изменения объектов (поды, эндпоинты, конфигмапы) и снижает нагрузку на узлы-мастера K8s.

  • Улучшить рабочий процесс, когда PGDATA не является пустым во время начальной инициализации (Alexander Kukushkin)

    Согласно исходному коду initdb, он может считать, что значение PGDATA является пустым, когда в нем присутствуют только lost+found и .dotfiles. В настоящее время Patroni делает то же самое. Если PGDATA не является пустым, и при этом не соответствует требованиям pg_controldata, Patroni выдаст ошибку и завершится работу.

  • Следует избегать вызова дорогостоящих операций os.listdir() на каждом цикле обеспечения высокой доступности (Alexander Kukushkin)

    Когда система испытывает нагрузку на ввод-вывод, os.listdir() может занимать несколько секунд (или даже минут), что негативно влияет на цикл отказоустойчивости Patroni. Это может даже привести к исчезновению ключа лидера из DCS из-за отсутствия обновлений. Существует более эффективный и экономичный способ проверить, что PGDATA не пуст. Сейчас мы проверяем наличие файла global/pg_control в PGDATA.

  • Некоторые улучшения в инфраструктуре ведения журнала (Alexander Kukushkin)

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

  • Используйте метод запуска multiprocessing spawn в Python 3.4+ (Maciej Kowalczyk)

    Это известная проблема в Python, что многопоточность и многопроцессорность плохо сочетаются. Переход от стандартного метода fork к spawn является рекомендуемым способом решения. Если этого не сделать, процесс Postmaster может зависнуть, а Patroni будет непрерывно сообщать об ошибке INFO: restarting after failure in progress, в то время как Postgres фактически работает.

Улучшения REST API

  • Обеспечить возможность проверки клиентских сертификатов в REST API (Alexander Kukushkin)

    Если verify_client установлено в required, Patroni будет проверять сертификаты клиентов для всех REST API вызовов. Когда оно установлено в optional, сертификаты клиентов проверяются для всех небезопасных REST API конечных точек.

  • Возвращайте код ответа 503 для запроса проверки работоспособности GET /replica, если PostgreSQL не запущен (Alexander Anikin)

    PostgreSQL может тратить значительное время на восстановление, прежде чем начать принимать соединения от клиентов.

  • Реализуйте конечные точки /history и /cluster (Alexander Kukushkin)

    Конечная точка /history отображает содержимое ключа history в DCS. Конечная точка /cluster отображает всех участников кластера и некоторую информацию о сервисах, такую как запланированные перезапуски или переключения.

Улучшения поддержки Etcd

  • Повторить операцию при внутренней ошибке etcd RAFT (Alexander Kukushkin)

    Когда узел etcd завершает работу, он отправляет response code=300, data='etcdserver: server stopped', что приводило к понижению первичного сервера в Patroni.

  • Не прекращайте попытки повторного запроса к etcd слишком рано (Alexander Kukushkin)

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

Исправления ошибок

  • Отключить synchronous_commit при предоставлении прав выполнения пользователю pg_rewind (kremius)

    Если начальная инициализация выполняется с использованием synchronous_mode_strict: true, то оператор GRANT EXECUTE оставался в ожидании неопределенно долго из-за того, что узлы были недоступны.

  • Устранить утечку памяти в Python 3.7 (Alexander Kukushkin)

    Patroni использует ThreadingMixIn для обработки запросов REST API и создает потоки на основе python 3.7, которые по умолчанию не являются демонными.

  • Устранить условия гонки в асинхронных операциях (Alexander Kukushkin)

    Существовала вероятность, что patronictl reinit --force может быть перезаписано в результате попытки восстановить остановленный Postgres. Это привело к ситуации, когда Patroni пытался запустить Postgres во время выполнения операции резервного копирования.

  • Исправить условие гонки в методе postmaster_start_time() (Alexander Kukushkin)

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

  • Устраните проблему, связанную с отсутствием продвижения резервного сервера, имеющего имя, содержащее заглавные буквы (Alexander Kukushkin)

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

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

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

  • Устранить проблему «не удалось запустить» (Alexander Kukushkin)

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


Версия 1.6.0

Выпущено 2019-08-05

Эта версия добавляет совместимость с PostgreSQL 12, позволяет запускать pg_rewind без привилегий суперпользователя на PostgreSQL 11 и более новых версиях, а также обеспечивает поддержку IPv6.

Новые возможности

  • Пакет Psycopg2 был удален из списка зависимостей и должен быть установлен отдельно (Alexander Kukushkin)

    Начиная с 2.8.0, psycopg2 было разделено на два различных пакета, psycopg2 и psycopg2-binary, которые можно было установить одновременно в одном месте файловой системы. Чтобы уменьшить проблему зависимостей, мы предоставили пользователю возможность самостоятельно выбирать способ установки. Доступно несколько вариантов, пожалуйста, обратитесь к документации .

  • Совместимость с PostgreSQL 12 (Alexander Kukushkin)

    Начиная с PostgreSQL 12, параметр recovery.conf больше не существует, и все предыдущие параметры восстановления преобразованы в , GUC, . Чтобы защититься от ALTER SYSTEM SET primary_conninfo или подобных ситуаций, Patroni будет анализировать postgresql.auto.conf и удалять все параметры резервного копирования и восстановления из него. Конфигурация Patroni остается обратно совместимой. Например, несмотря на то, что restore_command является GUC, вы все еще можете указать его в разделе postgresql.recovery_conf.restore_command, и Patroni запишет его в postgresql.conf для PostgreSQL 12.

  • Обеспечить возможность использования pg_rewind без прав суперпользователя в PostgreSQL 11 и более новых версиях (Alexander Kukushkin)

    Если вы хотите использовать эту функцию, пожалуйста, определите username и password в разделе postgresql.authentication.rewind конфигурационного файла Patroni. Для уже существующего кластера вам потребуется создать пользователя вручную и предоставить ему GRANT EXECUTE разрешения на несколько функций. Подробную информацию можно найти в документации PostgreSQL .

  • Проведите интеллектуальное сравнение фактических и желаемых значений primary_conninfo на репликах (Alexander Kukushkin)

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

  • Поддержка IPv6 (Alexander Kukushkin)

    Существовали две основные проблемы. Сервис Patroni REST API работал только с адресами 0.0.0.0 и IPv6, а IP-адреса, используемые в api_url и conn_url, не были правильно оформлены.

  • Поддержка Kerberos (Ajith Vilas, Alexander Kukushkin)

    Это позволяет использовать аутентификацию Kerberos между узлами Postgres вместо определения паролей в файле конфигурации Patroni.

  • Управление pg_ident.conf (Alexander Kukushkin)

    Эта функциональность работает аналогично pg_hba.conf: если postgresql.pg_ident определено в файле конфигурации или DCS, Patroni запишет его значение в pg_ident.conf, однако, если определено postgresql.parameters.ident_file, Patroni предполагает, что pg_ident управляется извне и не обновляет файл.

Улучшения REST API

  • Добавлен конечный /health (Wilfried Roset)

    Оно вернет код статуса HTTP только в том случае, если PostgreSQL работает

  • Добавлены конечные точки /read-only и /read-write (Julien Riou)

    Конечная точка /read-only обеспечивает сбалансированный доступ к чтению для реплик и первичного сервера. Конечная точка /read-write является псевдонимом для /primary, /leader и /master.

  • Используйте SSLContext для обертывания сокета REST API (Julien Riou)

    Использование ssl.wrap_socket() устарело и все еще позволяло использовать протоколы, которые вскоре будут объявлены устаревшими, такие как TLS и 1.1.

Улучшения ведения журнала

  • Двухэтапное ведение журнала (Alexander Kukushkin)

    Все сообщения журнала сначала записываются в оперативную очередь, а затем асинхронно выгружаются в stderr или файл отдельным потоком. Максимальный размер очереди ограничен (настраивается). Если лимит достигнут, Patroni начнет терять сообщения журнала, что все равно лучше, чем блокировать цикл обеспечения высокой доступности.

  • Включите ведение журнала отладки для вызовов GET/OPTIONS API вместе с задержкой (Jan Tomsa)

    Это поможет в отладке проверок работоспособности, выполняемых HAProxy, Consul или другими инструментами, которые определяют, какой узел является первичным/репликой.

  • Логировать исключения, которые были перехвачены в Retry (Daniel Kucera)

    Записывайте окончательное исключение, когда достигнуто либо количество попыток, либо тайм-аут. Это, вероятно, поможет в отладке некоторых проблем, когда связь с DCS не удается.

Улучшения patronictl

  • Улучшить диалоги для запланированного переключения и перезапуска (Rafia Sabih)

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

  • Проверьте, существует ли файл конфигурации (Wilfried Roset)

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

  • Добавьте резервное значение для EDITOR (Wilfried Roset)

    Когда переменная окружения EDITOR не была определена, patronictl edit-config завершалась с ошибкой PatroniCtlException. Новая стратегия заключается в попытке editor, а затем vi, которые должны быть доступны на большинстве систем.

Улучшения поддержки Consul

  • Предоставьте возможность указать режим согласованности Consul (Jan Tomsa)

    Вы можете узнать больше о режиме согласованности здесь .

  • Перезагрузите конфигурацию Consul SIGHUP (Cameron Daniel Kucera, Alexander Kukushkin)

    Особенно полезно, когда кто-то изменяет значение token.

Исправления ошибок

  • Исправить краевой случай при переключении/резервировании (Sharoon Thomas)

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

  • Откройте доступ для доверия к localhost pg_hba.conf во время пользовательской начальной инициализации (Alexander Kukushkin)

    Ранее доступ был открыт только для unix_socket, что приводило к большому количеству ошибок: FATAL: no pg_hba.conf entry for replication connection from host "127.0.0.1", user "replicator"

  • Рассматривайте синхронный узел как здоровый, даже когда предыдущий лидер находится впереди (Alexander Kukushkin)

    Если первичный узел теряет доступ к DCS, он перезапускает Postgres в режиме только для чтения, но может случиться, что другие узлы все еще могут получить доступ к старому первичному через REST API. Такая ситуация приводила к тому, что синхронная реплика не продвигалась, поскольку старый первичный сообщал о положении WAL, опережающем синхронную реплику.

  • Исправление ошибок в резервном кластере (Alexander Kukushkin)

    Обеспечить возможность начальной инициализации реплики в резервном кластере, когда standby_leader недоступен, и внести несколько других незначительных исправлений.


Версия 1.5.6

Выпущено 2019-08-03

Новые возможности

  • Обеспечить работу с кластером etcd с помощью набора прокси (Alexander Kukushkin)

    Возможно, кластер etcd недоступен напрямую, но через набор прокси. В этом случае Patroni не будет выполнять обнаружение топологии etcd, а будет просто использовать круговую маршрутизацию через хосты прокси. Поведение контролируется etcd.use_proxies.

  • Изменили поведение обратных вызовов при изменении роли на узле (Alexander Kukushkin)

    Если роль была изменена с master или standby_leader на replica или с replica на standby_leader, on_restart не будет вызывать, а вместо этого будет вызывать on_role_change.

  • Измените способ запуска PostgreSQL (Alexander Kukushkin)

    Используйте multiprocessing.Process вместо непосредственного выполнения, и multiprocessing.Pipe для передачи идентификатора процесса postmaster в процесс Patroni. Ранее мы использовали каналы, что приводило к тому, что процесс postmaster терял доступ к стандартному вводу.

Исправления ошибок

  • Исправить роль, возвращаемую REST API для резервного лидера (Alexander Kukushkin)

    Оно некорректно возвращало replica вместо standby_leader

  • Дождитесь завершения вызова, если он не может быть завершен (Julien Tachoires)

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

  • Уменьшить время удержания блокировки, затрачиваемое методом dcs.get_cluster (Alexander Kukushkin)

    Из-за того, что блокировка удерживалась, замедлялась работа, что влияло на DCS, вызывая ложные срабатывания проверок REST и API.

  • Улучшить очистку PGDATA, когда pg_wal/pg_xlog\ является символической ссылкой (Julien Tachoires)

    В этом случае Patroni явно удалит файлы из целевой директории.

  • Удалить избыточное использование os.path.relpath (Ants Aasma)

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

  • Не следует применять конкретную версию SSL при взаимодействии с etcd (Alexander Kukushkin)

    Для некоторых неизвестных причин, python3-etcd в Debian и Ubuntu не основан на последней версии пакета и, следовательно, применяет TLSv1, который не поддерживается etcd v3. Мы решили эту проблему на стороне Patroni.


Версия 1.5.5

Выпущено 2019-02-15

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

Новые возможности

  • Добавьте поддержку переменных окружения PATRONI_ETCD_PROTOCOL, PATRONI_ETCD_USERNAME и PATRONI_ETCD_PASSWORD (Étienne M)

    Раньше было возможно настраивать их только в файле конфигурации или как часть PATRONI_ETCD_URL, что не всегда удобно.

  • Обеспечить автоматическую перезагрузку предыдущего мастера (Alexander Kukushkin)

    Если pg_rewind отключён или недоступен, прежний мастер может не запуститься в качестве новой реплики из-за расхождения временных шкал. В этом случае единственное решение — очистка каталога данных и повторная инициализация. Это поведение можно изменить, установив postgresql.remove_data_directory_on_diverged_timelines. При установленном параметре Patroni автоматически очистит каталог данных и повторно инициализирует прежнего мастера.

  • Показать информацию о временных шкалах в списке patronictl (Alexander Kukushkin)

    Оно помогает обнаруживать устаревшие реплики. Кроме того, Host будет включать ‘: {порт}’, если значение порта не является стандартным или на одном хосте работает несколько участников.

  • Создайте headless-сервис, связанный с конечной точкой $SCOPE-config (Alexander Kukushkin)

    “config”-ный эндпоинт хранит информацию о конфигурации Patroni и Postgres для всего кластера, историю файлов и, самое главное, содержит ключ initialize. При перезапуске или обновлении узла Kubernetes мастер, он удаляет эндпоинты без сервисов. Головная служба предотвратит это.

Исправления ошибок

  • Настройте тайм-аут для запроса, блокирующего ожидание лидер-мониторинга (Alexander Kukushkin)

    Согласно документации Consul, фактический тайм-аут ответа увеличивается на небольшое случайное дополнительное время ожидания, которое добавляется к указанному максимальному времени ожидания, чтобы распределить время пробуждения любых одновременных запросов. Это добавляет wait / 16 дополнительное время к максимальной продолжительности. В нашем случае мы добавляем wait / 15 или 1 секунд, в зависимости от того, что больше.

  • Всегда используйте replication=1 при подключении по протоколу репликации к postgres (Alexander Kukushkin)

    Начиная с Postgres 10, строка в файле pg_hba.conf с указанием database=replication не принимает соединения с параметром replication=database.

  • Не записывайте primary_conninfo в recovery.conf для кластера резервного сервера, использующего только WAL (Alexander Kukushkin)

    Несмотря на отсутствие host и port в конфигурации standby_cluster , Patroni пытался установить primary_conninfo в recovery.conf, что бесполезно и приводит к большому количеству ошибок.


Версия 1.5.4

Выпущено 2019-01-15

Эта версия реализует гибкое ведение журнала и устраняет ряд ошибок.

Новые возможности

  • Улучшения в инфраструктуре ведения журнала (Alexander Kukushkin, Lucas Capistrant, Alexander Anikin)

    Конфигурация ведения журнала может быть настроена не только через переменные окружения, но и через файл конфигурации Patroni. Это позволяет изменять конфигурацию ведения журнала во время выполнения путем обновления конфигурации и перезагрузки или отправки SIGHUP в процесс Patroni. По умолчанию Patroni записывает журналы в stderr, но теперь стало возможным записывать журналы непосредственно в файл и выполнять их ротацию при достижении определенного размера. Кроме того, была добавлена поддержка пользовательского формата даты и возможность тонкой настройки уровня логирования для каждого Python-модуля.

  • Обеспечить возможность учитывать текущую временную шкалу при выборах лидера (Alexander Kukushkin)

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

  • Смягченные требования к учетным данным суперпользователя

    Libpq позволяет открывать соединения без явного указания имени пользователя и пароля. В зависимости от ситуации, оно использует либо файл pgpass, либо метод аутентификации “доверие” в pg_hba.conf. Поскольку pg_rewind также использует libpq, оно будет работать аналогично.

  • Реализована возможность настройки интервала проверки регистрации сервиса Consul через переменные окружения (Alexander Kukushkin)

    Регистрация сервиса в Consul была добавлена в 1.5.0, но на данный момент это было возможно только через patroni.yaml.

Повышение стабильности

  • Установите archive_mode в положение «выключено» во время пользовательской начальной инициализации (Alexander Kukushkin)

    Мы хотим избежать архивирования WAL и файлов истории до тех пор, пока кластер полностью не будет функционировать. Это действительно помогает, если пользовательская начальная инициализация включает pg_upgrade.

  • Применять задержку в пять секунд при загрузке глобальной конфигурации при запуске (Alexander Kukushkin)

    Это помогает избежать перегрузки DCS при запуске Patroni.

  • Уменьшить количество генерируемых сообщений об ошибках при завершении работы (Alexander Kukushkin)

    Они были безвредными, но довольно назойливыми и иногда пугающими.

  • Явно задать права доступа для чтения/записи recovery.conf при создании (Lucas Capistrant)

    Мы не хотим, чтобы кто-либо, кроме пользователей Patroni/postgres, читал этот файл, поскольку он содержит учетные данные для репликации.

  • Перенаправление исключений HTTPServer в логгер (Julien Riou)

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

Исправления ошибок

  • Удалена перенаправка stderr в stdout для процесса pg_ctl (Cody Coons)

    Наследование stderr от основного процесса Patroni позволяет видеть все логи Postgres, а также все логи Patroni. Это очень полезно в контейнерной среде, поскольку логи Patroni и Postgres можно использовать с помощью стандартных инструментов (docker logs, kubectl и т.д.). Кроме того, эта модификация устраняет ошибку, при которой Patroni не мог перехватывать PID postmaster, когда Postgres записывал предупреждения в stderr.

  • Установите тайм-аут отмены проверки сервиса Consul в формате времени Go (Pavel Kirillov)

    Без явной регистрации единицы времени, регистрация завершалась неудачно.

  • Ослабьте проверки standby_cluster кластера (Dmitry Dolgov, Alexander Kukushkin)

    Оно принимало только строки в качестве допустимых значений, и поэтому не было возможно указать порт как целое число и create_replica_methods в виде списка.


Версия 1.5.3

Выпущено 2018-12-03

Совместимость и выпуск с исправлением ошибок.

  • Улучшить стабильность при работе с python3 против zookeeper (Alexander Kukushkin)

    Изменение loop_wait приводило к тому, что Patroni отключался от zookeeper и не восстанавливал соединение.

  • Устранить несовместимость с postgres 9.3 (Alexander Kukushkin)

    При установлении соединения для репликации необходимо указать replication=1, поскольку 9.3 не поддерживает replication=‘database’

  • Убедитесь, что мы обновляем сессию Consul как минимум один раз в каждом цикле отказоустойчивости, и улучшаем обработку исключений, связанных с сессиями Consul (Alexander Kukushkin)

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


Версия 1.5.2

Выпущено 2018-11-26

Совместимость и выпуск с исправлением ошибок.

  • Совместимость с kazoo 2.6.0 (Alexander Kukushkin)

    Чтобы убедиться, что запросы выполняются с соответствующим тайм-аутом, Patroni переопределяет метод create_connection из модуля python-kazoo. Последняя версия kazoo незначительно изменила способ вызова метода create_connection.

  • Исправить сбой Patroni при потере лидерности в кластере Consul (Alexander Kukushkin)

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


Версия 1.5.1

Выпущено 2018-11-01

Эта версия реализует поддержку постоянных слотов репликации, добавляет поддержку pgBackRest и устраняет ряд ошибок.

Новые возможности

  • Постоянные слоты репликации (Alexander Kukushkin)

    Постоянные слоты репликации сохраняются при переключении при отказе/плановом переключении, то есть Patroni на новом первичном сервере создаст сконфигурированные слоты репликации сразу после повышения. Слоты можно сконфигурировать с помощью patronictl edit-config. Начальная конфигурация также может быть выполнена в bootstrap.dcs .

  • Добавьте поддержку pgBackRest (Yogesh Sharma)

    pgBackRest может выполнять восстановление в существующую папку $PGDATA, что позволяет ускорить процесс восстановления, поскольку файлы, которые не изменились с момента последней резервной копии, пропускаются. Для поддержки этой функции был введён новый параметр keep_data. Дополнительные примеры см. в разделе метод создания реплики .

Исправления ошибок

  • Несколько исправлений ошибок в рабочем процессе с “резервным кластером” (Alexander Kukushkin)

    Пожалуйста, обратитесь к https://github.com/patroni/patroni/pull/823 для получения дополнительной информации.

  • Исправление проверки работоспособности REST API при приостановленном управлении кластером и недоступности DCS (Alexander Kukushkin)

    Ошибку было внесено в https://github.com/patroni/patroni/commit/90cf930036a9d5249265af15d2b787ec7517cf57


Версия 1.5.0

Выпущено 2018-09-20

Эта версия позволяет кластеру Patroni в режиме высокой доступности работать в режиме ожидания, предоставляет экспериментальную поддержку для работы в Windows и предоставляет новый параметр конфигурации для регистрации сервиса PostgreSQL в Consul.

Новые возможности

  • Резервный кластер (Dmitry Dolgov)

    Один или несколько узлов Patroni могут образовать резервный кластер, работающий параллельно с первичным кластером (i.e, в другом центре обработки данных), состоящий из резервных узлов, которые реплицируют данные с мастера в первичном кластере. Все узлы PostgreSQL в резервном кластере являются репликами; одна из этих реплик сама выбирает себя для репликации непосредственно с удалённого мастера, в то время как остальные реплицируют данные от неё по каскадной схеме. Подробное описание этой функции и примеры конфигурации можно найти в здесь .

  • Регистрация сервисов в Consul (Pavel Kirillov, Alexander Kukushkin)

    Если параметр register_service в конфигурации Consul включён, узел зарегистрирует службу с именем scope и тегом master, replica или standby-leader.

  • Экспериментальная поддержка Windows (Pavel Golub)

    С этого момента возможно запустить Patroni в Windows, хотя поддержка Windows является новой и не получила столько практических тестов, как поддержка Linux. Мы приветствуем ваши отзывы!

Улучшения patronictl

  • Добавьте флаг -k/–insecure patronictl и поддержку сертификата для REST API (Wilfried Roset)

    Ранее, если REST API был защищён самоподписными сертификатами, patronictl не мог их проверить. Существовало невозможность отключить эту проверку. Теперь можно настроить patronictl на пропуск проверки сертификатов или указать сертификаты CA и клиента в разделе ctl: конфигурации.

  • Исключить участники, у которых отсутствует тег «nofollower», из вывода patronictl при переключении/переключении при отказе (Alexander Anikin)

    Ранее, эти участники ошибочно предлагались в качестве кандидатов при выполнении интерактивного переключения или переключения при отказе с использованием patronictl.

Повышение стабильности

  • Избегайте парсинга строк вывода, не являющихся ключами-значениями pg_controldata (Alexander Anikin)

    При определенных обстоятельствах pg_controldata генерирует строки без символа двоеточия. Это может вызвать ошибку в коде Patroni, который обрабатывает вывод pg_controldata, скрывая реальную проблему; часто такие строки выводятся в виде предупреждения, отображаемого pg_controldata перед основным выводом, i.e. когда версия бинарного файла не соответствует версии каталога данных PostgreSQL.

  • Добавить имя участника в сообщение об ошибке во время выборов лидера (Jan Mussler)

    Во время выбора лидера, Patroni подключается ко всем известным участникам кластера и запрашивает их статус. Этот статус записывается в лог Patroni и включает в себя имя участника. Ранее, если участник был недоступен, сообщение об ошибке не содержало его имя, а содержало только URL.

  • Немедленно зарезервируйте позицию WAL при создании слота репликации (Alexander Kukushkin)

    Начиная с 9.6, функция pg_create_physical_replication_slot предоставляет дополнительный булевый параметр immediately_reserve. Когда он установлен в false, который также является значением по умолчанию, слот не резервирует позицию WAL до получения первого соединения от клиента, что может привести к потере некоторых сегментов, необходимых клиенту, в течение временного интервала между созданием слота и первым соединением.

  • Исправить ошибку в строгой синхронной репликации (Alexander Kukushkin)

    При работе с synchronous_mode_strict: true, в некоторых случаях Patroni помещает \* в synchronous_standby_names, изменяя состояние синхронизации для большинства соединений репликации на potential. Ранее Patroni не мог выбрать синхронного кандидата в таких обстоятельствах, поскольку он рассматривал только те, у которых состояние было async.


Версия 1.4.6

Выпущено 2018-08-14

Исправления ошибок и повышение стабильности

В этом выпуске исправлена критическая ошибка, при которой конечная точка Patroni API /master возвращала 200 для узла, не являющегося мастером. Это ошибка отчетности, реального разделения мозгов нет, однако в определённых условиях клиенты могут быть направлены на узел только для чтения.

  • Сбросить статус is_leader при понижении (Alexander Kukushkin, Oleksii Kliukin)

    Убедитесь, что участник кластера, пониженный в статусе, перестает отвечать кодом 200 в результате вызова /master API.

  • Добавьте новое поле “cluster_unlocked” в вывод API (Dmitry Dolgov)

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


Версия 1.4.5

Выпущено 2018-08-03

Новые возможности

  • Улучшить ведение журнала при применении новой конфигурации PostgreSQL (Don Seiler)

    Patroni регистрирует изменения в именах и значениях параметров.

  • Совместимость с Python 3.7 (Christoph Berg)

    async является зарезервированным ключевым словом в python3.7

  • Установите состояние на “остановлено” в DCS, когда участник завершает работу (Tony Sorrentino)

    Это демонстрирует состояние участника как “остановлено” в команде “patronictl list”.

  • Улучшить сообщение, которое записывается, когда устаревший postmaster.pid совпадает с работающим процессом (Ants Aasma)

    Предыдущий был совершенно непонятным.

  • Реализовать функциональность перезагрузки patronictl (Don Seiler)

    Ранее это было возможно только путем перезагрузки конфигурации, вызвав REST, API или отправив сигнал SIGHUP процессу Patroni.

  • Возьмите и примените некоторые параметры из controldata при запуске в качестве реплики (Alexander Kukushkin)

    Значение max_connections и некоторые другие параметры, установленные в глобальной конфигурации, могут быть ниже, чем значение, используемое первичным сервером; в этом случае реплика не может запуститься и требует ручной корректировки. Patroni теперь решает эту проблему, считывая и применяя значение из pg_controldata, запуская PostgreSQL и устанавливая флаг pending_restart.

  • Если установлено, использовать LD_LIBRARY_PATH при запуске PostgreSQL (Chris Fraser)

    При запуске Postgres, Patroni передавал переменные окружения PATH, LC_ALL и LANG, если они были установлены. Сейчас он делает то же самое с LD_LIBRARY_PATH. Это может помочь, если PostgreSQL был установлен в нестандартное место.

  • Переименовать create_replica_method в create_replica_methods (Dmitry Dolgov)

    Чтобы было ясно, что это действительно массив. Старое имя по-прежнему поддерживается для обратной совместимости.

Исправления ошибок и повышение стабильности

  • Устранить условие для запуска реплики в случае, когда она находится в состоянии «приостановлено» из-за pg_rewind (Oleksii Kliukin)

    Избегайте запуска реплики, которая уже выполнила pg_rewind ранее.

  • Отвечать 200 на запрос о состоянии только от мастера, если update_lock был выполнен успешно (Alexander Kukushkin)

    Предотвратите, чтобы Patroni считал себя мастером на ранее пониженном сервере, если DCS разделен.

  • Обеспечить совместимость с новым модулем consul (Alexander Kukushkin)

    Начиная с v1.1.0 python-consul изменил внутреннюю реализацию API и начал использовать list вместо dict для передачи параметров запроса.

  • Перехватывать исключения, возникающие в потоках Patroni REST API во время завершения работы (Alexander Kukushkin)

    Эти необработанные исключения продолжали поддерживать работу PostgreSQL при завершении.

  • Восстанавливайте систему только тогда, когда Postgres работает в режиме мастера (Alexander Kukushkin)

    Необходимо, чтобы pg_controldata сообщал о состоянии «в производственной среде», «переводе в режим выключения» или «восстановлении после сбоя». В остальных случаях восстановление не требуется.

  • Улучшить обработку ошибок конфигурации (Henning Jacobs, Alexander Kukushkin)

    Возможно изменить множество параметров во время выполнения (включая restapi.listen), обновив файл конфигурации Patroni и отправив SIGHUP в процесс Patroni. Это исправление устраняет неочевидные исключения из потока ‘restapi’, когда некоторые параметры получают неверные значения.


Версия 1.4.4

Выпущено 2018-05-22

Повышение стабильности

  • Устранить условие гонки в poll_failover_result (Alexander Kukushkin)

    Это напрямую не влияло ни на аварийное, ни на плановое переключение, но в некоторых редких случаях система слишком рано сообщала об успехе, когда прежний лидер освобождал блокировку, выдавая сообщение ‘Failed over to “None”’ вместо ‘Failed over to “desired-node”’.

  • Обращайтесь к параметрам Postgres как к нечувствительным к регистру (Alexander Kukushkin)

    Большинство параметров Postgres имеют snake_case имена, но существуют три исключения из этого правила: DateStyle, IntervalStyle и TimeZone. Postgres принимает эти параметры независимо от регистра (e.g. timezone = ‘some/tzn’); однако Patroni не мог найти соответствия с игнорированием регистра для имён этих параметров в pg_settings и в результате игнорировал такие параметры.

  • Прекратить запуск, если происходит подключение к работающему PostgreSQL и кластер не инициализирован (Alexander Kukushkin)

    Patroni может подключиться к уже работающей инстанции Postgres. Крайне важно начать запуск Patroni на узле-мастере, прежде чем переходить к репликам.

  • Исправьте поведение шаблона patronictl (Alexander Kukushkin)

    Передавайте объект dict в touch_member вместо строки JSON-encoded; реализация DCS сама выполнит её кодирование.

  • Не понижайте мастер, если не удалось обновить ключ лидера в режиме паузы (Alexander Kukushkin)

    Во время обслуживания узел DCS может начать отклонять запросы на запись, продолжая отвечать на запросы на чтение. В этом случае Patroni использовал помещать мастер-узел Postgres в режим только для чтения после того, как не смог обновить блокировку лидера DCS.

  • Синхронизируйте слоты репликации, когда Patroni обнаруживает новый процесс postmaster (Alexander Kukushkin)

    Если PostgreSQL был перезапущен, Patroni должен убедиться, что список слотов репликации соответствует его ожиданиям.

  • Проверьте sysid и слоты репликации после выхода из режима приостановки (Alexander Kukushkin)

    Во время режима maintenance может произойти ситуация, когда каталог данных был полностью переписан, и, следовательно, необходимо убедиться, что Database system identifier принадлежит к нашему кластеру, и слоты репликации находятся в синхронизации с ожиданиями Patroni.

  • Устранить возможную проблему с запуском Postgres в каталоге данных при наличии файла блокировки postmaster (Alexander Kukushkin)

    Обнаружение повторного использования PID из файла блокировки почтового ящика. Вероятность возникновения такой проблемы выше, если вы запускаете Patroni и Postgres в контейнере Docker.

  • Улучшить защиту DCS от случайного удаления (Alexander Kukushkin)

    Patroni содержит значительную логику для предотвращения переключения при отказе в таких случаях; он также может восстановить все ключи; однако, до внесения этого изменения, случайное удаление ключа /config отключало цикл HA для 1.

  • Не выходить, если возникает ошибка с недействительным идентификатором системы (Oleksii Kliukin)

    Не завершайте работу системы, когда идентификатор кластера пуст или не проходит проверку. В этом случае кластер, скорее всего, требует переинициализации; укажите это в сообщении результата. Избегайте завершения работы Patroni, так как в противном случае переинициализация невозможна.

Совместимость с Kubernetes 1.10+

  • Добавлена проверка на пустые подмножества (Cody Coons)

    Kubernetes 1.10.0+ начал возвращать Endpoints.subsets, установленный в None, вместо \[\].

Улучшения начальной инициализации

  • Сделайте удаление recovery.conf необязательным (Brad Nicholson)

    Если bootstrap.<custom_bootstrap_method_name>.keep_existing_recovery_conf определено и установлено в True, Patroni не удаляет существующий recovery.conf файл. Это полезно при начальной инициализации из резервной копии с использованием таких инструментов, как pgBackRest, которые генерируют соответствующие recovery.conf.

  • Предоставьте возможность указывать параметры для встроенного метода built-in в basebackup (Oleksii Kliukin)

    Сейчас возможно указывать параметры для встроенного метода basebackup, определяя раздел basebackup в конфигурации, подобно тому, как это делается для методов создания пользовательских реплик. Различие заключается в формате, который принимает раздел basebackup: поскольку pg_basebackup принимает параметры --key=value и --key, содержимое раздела может быть либо словарем пар ключ-значение, либо списком из словарей с одним элементом или просто ключей (для параметров, которые не принимают значения). Обратитесь к разделу “метод создания реплики” для дополнительных примеров.


Версия 1.4.3

Выпущено 2018-03-05

Улучшения ведения журнала

  • Сделать уровень логирования настраиваемым через переменные окружения (Andy Newton, Keyvan Hedayati)

    PATRONI_LOGLEVEL — устанавливает общий уровень ведения журнала PATRONI_REQUESTS_LOGLEVEL — устанавливает уровень ведения журнала для всех запросов HTTP e.g. Kubernetes API обращается к See документации для Python logging https://docs.python.org/3.6/library/logging.html#levels\ , чтобы узнать имена возможных уровней ведения журнала

Повышение стабильности и исправления ошибок

  • Не переоценивайте топологию кластера etcd при истечении времени ожидания (Alexander Kukushkin)

    Если в конфигурации etcd есть только один узел, и этот узел недоступен, Patroni начинает обнаружение топологии кластера и не может этого сделать. Вместо этого, Patroni должен просто перейти к следующему доступному узлу.

  • Записать содержимое bootstrap.pg_hba в файл pg_hba.conf после выполнения пользовательской начальной инициализации (Alexander Kukushkin)

    Теперь оно ведет себя аналогично обычной начальной инициализации initdb

  • Режим с одним пользователем ожидал ввода от пользователя и никогда не завершался (Alexander Kukushkin)

    Ошибку было внесено в https://github.com/patroni/patroni/pull/576


Версия 1.4.2

Выпущено 2018-01-30

Улучшения patronictl

  • Переименовать запланированное переключение при отказе в запланированное переключение (Alexander Kukushkin)

    Функции переключения при отказе и планового переключения были разделены в версии 1.4, но patronictl list все еще сообщал о Scheduled failover вместо Scheduled switchover.

  • Показать информацию о ожидающих перезапусках (Alexander Kukushkin)

    Для применения некоторых изменений конфигурации иногда необходимо перезапустить PostgreSQL. Patroni уже давал соответствующее предупреждение в REST API, а также при записи статуса узлов в DCS, но не было простого способа отобразить эту информацию.

  • Сделайте использование show-config для работы с cluster_name из конфигурационного файла (Alexander Kukushkin)

    Оно работает аналогично patronictl edit-config

Повышение стабильности

  • Избегайте вызова pg_controldata во время начальной инициализации (Alexander Kukushkin)

    Во время initdb или пользовательской начальной инициализации существует временной интервал, когда pgdata не пуст, но pg_controldata ещё не был записан. В таком случае вызов pg_controldata завершался с сообщениями об ошибках.

  • Обрабатывать исключения, возникающие из-за psutil (Alexander Kukushkin)

    Команда из командной строки считывается и анализируется каждый раз, когда вызывается метод cmdline(). Возможно, что процесс, который рассматривается, уже исчез, в этом случае возникает исключение NoSuchProcess.

Улучшения поддержки Kubernetes

  • Не подавляйте ошибки из k8s API (Alexander Kukushkin)

    Вызов Kubernetes API может завершиться неудачно по различным причинам. В некоторых случаях такой вызов следует повторить, в других – необходимо записать сообщение об ошибке и трассировку стека исключений. Эта модификация поможет в отладке проблем с разрешениями Kubernetes.

  • Обновите пример Dockerfile для Kubernetes, чтобы установить Patroni из основной ветки (Maciej Szulik)

    Ранее использовалась feature/k8s, но она устарела.

  • Добавьте соответствующий RBAC для запуска Patroni в k8s (Maciej Szulik)

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


Версия 1.4.1

Выпущено 2018-01-17

Исправления в patronictl

  • Не отображать текущего лидера в предложенном списке участников для переключения при отказе. (Alexander Kukushkin)

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

  • Сделать patronictl плановым переключением совместимым со старым API Patroni (Alexander Kukushkin)

    Если вызов REST API POST /switchover завершится с кодом состояния 501, он будет повторён, но уже для конечной точки /failover вместо исходной.


Версия 1.4

Выпущено 2018-01-10

Эта версия добавляет поддержку использования Kubernetes в качестве DCS, позволяя запускать Patroni как облачное средство в Kubernetes без каких-либо дополнительных развёртываний etcd, Zookeeper или Consul.

Уведомление об обновлении

Установка Patroni через pip больше не будет автоматически устанавливать зависимости (такие как библиотеки для etcd, Zookeeper, Consul или Kubernetes, или поддержку AWS). Чтобы их включить, необходимо указать их явно в команде pip install, например, pip install patroni\[etcd,kubernetes\].

Поддержка Kubernetes

Реализуйте DCS, основанную на Kubernetes систему. Данные метаданных используются для хранения конфигурации и ключа лидера. Поле метаданных внутри определения подов используется для хранения данных, связанных с участником. Кроме использования Endpoints, Patroni поддерживает ConfigMaps. Вы можете найти дополнительную информацию об этой функции в главе «Kubernetes» документации .

Повышение стабильности

  • Выделить процесс postmaster в отдельный объект (Ants Aasma)

    Этот объект идентифицирует запущенный процесс postmaster по идентификатору процесса и времени запуска, упрощая обнаружение (и устранение) ситуаций, когда postmaster был перезапущен без нашего ведома или когда каталог PostgreSQL исчез из файловой системы.

  • Минимизировать количество SELECT, которое Patroni выпускает на каждом цикле обеспечения высокой доступности (Alexander Kukushkin)

    На каждой итерации цикла обеспечения высокой доступности Patroni должен знать статус восстановления и абсолютную позицию WAL. С этого момента Patroni будет использовать только один SELECT для получения этой информации, вместо двух на реплике и трех на основном сервере.

  • Удалять ключ «leader» при выключении только тогда, когда у нас есть блокировка (Ants Aasma)

    Безоговорочное удаление приводило к возникновению ненужных и вводящих в заблуждение исключений.

Улучшения patronictl

  • Добавьте команду версии в patronictl (Ants Aasma)

    Отобразит версию установленного Patroni и версии запущенных экземпляров Patroni (если указано имя кластера).

  • Предоставьте возможность указывать необязательный аргумент cluster_name для некоторых команд patronictl (Alexander Kukushkin, Ants Aasma)

    Это будет работать, если patronictl использует стандартный файл конфигурации Patroni, в котором определено scope.

  • Показать информацию о запланированном переключении и режиме обслуживания (Alexander Kukushkin)

    Ранее эта информация можно было получить только из логов Patroni или непосредственно из DCS.

  • Улучшить patronictl reinit (Alexander Kukushkin)

    Иногда patronictl reinit отказывался продолжать работу, когда Patroni был занят другими действиями, а именно попытками запуска postgres. patronictl не предоставлял никаких команд для отмены таких длительных операций, и единственным (опасным) обходным решением было ручное удаление каталога данных. Новая реализация reinit принудительно отменяет другие длительные операции перед выполнением reinit.

  • Реализовать флаг --wait в patronictl pause и patronictl resume (Alexander Kukushkin)

    Это обеспечит, чтобы patronictl ждал, пока запрошенное действие будет подтверждено всеми узлами в кластере. Такое поведение достигается путем предоставления флага pause для каждого узла в DCS и через REST API.

  • Переименовать patronictl failover в patronictl switchover (Alexander Kukushkin)

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

  • Измените поведение patronictl failover (Alexander Kukushkin)

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

Предоставление сведений о временной шкале и истории

  • Отображать текущую временную шкалу в DCS и через API (Alexander Kukushkin)

    Храните информацию о текущей временной шкале для каждого участника кластера. Эта информация доступна через API и хранится в DCS

  • Сохранять историю рекламных акций в ключе /history в DCS (Alexander Kukushkin)

    Кроме того, сохраните историю изменений, обогащенную временной меткой соответствующего продвижения, в ключе /history в DCS, и обновляйте его при каждом продвижении.

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

  • Добавьте новые конечные точки /sync и /async (Alexander Kukushkin, Oleksii Kliukin)

Эти конечные точки (также доступные как /synchronous и /asynchronous) возвращают 200 только для синхронных и асинхронных реплик соответственно (исключая те, которые помечены как noloadbalance).

Разрешено несколько узлов Etcd

  • Добавьте новый параметр hosts в конфигурацию etcd (Alexander Kukushkin)

    Этот параметр должен содержать начальный список хостов, которые будут использоваться для обнаружения и заполнения списка участников работающего кластера etcd. Если по какой-либо причине в процессе работы этот список обнаруженных хостов исчерпан (нет доступных хостов из этого списка), Patroni вернется к исходному списку из параметра hosts.


Версия 1.3.6

Выпущено 2017-11-10

Повышение стабильности

  • Проверьте время запуска процесса при проверке, запущен ли PostgreSQL. (Ants Aasma)

    После сбоя, который не приводит к очистке postmaster.pid, может появиться новый процесс с тем же идентификатором, что приведет к ложному срабатыванию is_running(), что, в свою очередь, вызовет различные нежелательные последствия.

  • Остановить PostgreSQL перед начальной инициализацией, когда потеряна директория данных (ainlolcat)

    Когда каталог данных на основном сервере удаляется насильственным способом, процесс PostgreSQL может продолжать работать в течение некоторого времени и препятствовать запуску или репликации реплики, созданной на месте бывшего основного сервера. Исправление позволяет Patroni кэшировать PID процесса postmaster и его время запуска, и завершать старый процесс postmaster, если он все еще работает после удаления соответствующего каталога данных.

  • Выполните восстановление после сбоя в режиме однопользовательского режима, если мастер PostgreSQL выходит из строя (Alexander Kukushkin)

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

Улучшения Consul

  • Обеспечить возможность предоставления конфигурации дата-центра для Consul (Vilius Okockis, Alexander Kukushkin)

    Ранее Patroni всегда взаимодействовал с дата-центром хоста, на котором он работал.

  • Всегда отправляйте токен в заголовке HTTP X-Consul-Token (Alexander Kukushkin)

    Если consul.token определено в конфигурации Patroni, мы всегда будем отправлять его в заголовке HTTP ‘X-Consul-Token’. Модуль python-consul пытается быть “согласованным” с Consul REST API, который не принимает токен в качестве параметра запроса для сессии API , но он все равно работает с заголовком ‘X-Consul-Token’.

  • Настроить сеанс TTL, если предоставленное значение меньше минимально допустимого (Stas Fomin, Alexander Kukushkin)

    Возможно, значение TTL, предоставленное в конфигурации Patroni, окажется меньше минимального значения, поддерживаемого Consul. В этом случае агент Consul не может создать новую сессию. Без сессии Patroni не может создать ключи участника и лидера в хранилище Consul KV, что приводит к нездоровому состоянию кластера.

Другие улучшения

  • Определите пользовательский формат логов через переменную окружения PATRONI_LOGFORMAT (Stas Fomin)

    Разрешить отключение временных меток и других аналогичных полей в логах Patroni, если они уже добавлены системным логгером (обычно, когда Patroni работает как сервис).


Версия 1.3.5

Выпущено 2017-10-12

Исправление ошибки

  • Установите роль в значение ‘uninitialized’, если каталог данных был удален (Alexander Kukushkin)

    Если узел работал в качестве мастера, это предотвращало переключение при отказе.

Повышение стабильности

  • Попробуйте запустить postmaster в однопользовательском режиме, если мы попытались запустить PostgreSQL, но потерпели неудачу (Alexander Kukushkin)

    Обычно такая проблема возникает, когда узел, работающий в качестве мастера, был завершен, и временные шкалы разошлись. Если recovery.conf определено restore_command, то существует высокая вероятность того, что PostgreSQL завершит запуск и оставит данные конфигурации без изменений. Это делает невозможным использование pg_rewind, которое требует чистого завершения работы.

Улучшения Consul

  • Предусмотреть возможность указания проверок работоспособности при создании сессии (Alexander Kukushkin)

    Если не указано, Consul будет использовать “serfHealth”. С одной стороны, это позволяет быстро обнаружить изолированный мастер; с другой стороны, это делает невозможным для Patroni принятие кратковременных задержек в сети.

Исправление ошибки

  • Устранить проблему со сторожевым таймером в Python 3 (Ants Aasma)

    Неправильное понимание интерфейса вызова ioctl(). Если mutable=False, то fcntl.ioctl() фактически возвращает буфер аргументов. Это случайно работало в Python2, поскольку сравнение типов int и str не вызывало ошибку. Отчет об ошибках фактически генерируется путем вызова исключения IOError в Python2 и OSError в Python3.


Версия 1.3.4

Выпущено 2017-09-08

Различные улучшения Consul

  • Передайте токен Consul в качестве заголовка (Andrew Colin Kissa)

    Заголовки теперь являются предпочтительным способом передачи токена в Consul API .

  • Продвинутая конфигурация для Consul (Alexander Kukushkin)

    возможность указать scheme, token, клиентские и CA-сертификаты подробности .

  • совместимость с python-consul-0.7.1 и выше (Alexander Kukushkin)

    Новый модуль python-consul изменил сигнатуру некоторых методов

  • Сообщение «Не удалось получить TTL блокировку» никогда не регистрировалось (Alexander Kukushkin)

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

Заключение synchronous_standby_names в кавычки с помощью quote_ident

  • При записи synchronous_standby_names в postgresql.conf, его значение должно быть заключено в кавычки (Alexander Kukushkin)

    Если запрос не оформлен должным образом, PostgreSQL фактически отключит синхронную репликацию и продолжит работу.

Различные исправления ошибок, связанные с состоянием паузы, в основном, связанные со сторожевым таймером (Александр Кукушкин)

  • Не отправлять сигналы “keepalive”, если сторожевой таймер не активен
  • Избегать активации сторожевого таймера в режиме паузы
  • Установить правильное состояние PostgreSQL в режиме паузы
  • Не пытаться выполнять запросы из API, если PostgreSQL остановлен

Версия 1.3.3

Выпущено 2017-08-04

Исправления ошибок

  • синхронное резервное копирование было отключено вскоре после повышения, даже когда synchronous_mode_strict было включено (Alexander Kukushkin)
  • создать пустой файл pg_ident.conf, если он отсутствует после восстановления из резервной копии (Alexander Kukushkin)
  • открыть доступ в pg_hba.conf ко всем базам данных, а не только к PostgreSQL (Franco Bellagamba)

Версия 1.3.2

Выпущено 2017-07-31

Исправление ошибки

  • Редактирование конфигурации с помощью Patroni.ctl не работает с ZooKeeper (Alexander Kukushkin)

Версия 1.3.1

Выпущено 2017-07-28

Исправление ошибки

  • Переключение при отказе, осуществляемое с помощью API, перестало работать из-за изменений в _MemberStatus (Alexander Kukushkin)

Версия 1.3

Выпущено 2017-07-27

Версия 1.3 добавляет возможность пользовательской начальной инициализации, значительно улучшает поддержку pg_rewind, расширяет поддержку синхронного режима, добавляет возможность редактирования конфигурации через patronictl и реализует поддержку сторожевого таймера в Linux. Кроме того, это первая версия, которая корректно работает с PostgreSQL 10.

Уведомление об обновлении

Существует нет известных проблем совместимости с новой версией Patroni. Конфигурация из версии 1.2 должна работать без каких-либо изменений. Обновление возможно путем установки новых пакетов и последующего перезапуска Patroni (что приведёт к перезапуску PostgreSQL), либо путём сначала перевода Patroni в режим паузы , а затем перезапуска Patroni на всех узлах кластера (Patroni в режиме паузы не будет пытаться остановить/запустить PostgreSQL), после чего возобновления работы из режима паузы.

Пользовательская начальная инициализация

  • Сделайте процесс инициализации кластера настраиваемым (Alexander Kukushkin)

    Разрешить использование пользовательских скриптов начальной инициализации вместо initdb при инициализации первого узла в кластере. Команда начальной инициализации получает имя кластера и путь к каталогу данных. Полученный кластер может быть настроен для выполнения восстановления, что позволяет инициализировать из резервной копии и выполнять восстановление в определенный момент времени. Обратитесь к странице документации для получения более подробного описания этой функции.

Более интеллектуальная поддержка pg_rewind

  • Определите, следует ли запускать pg_rewind, изучив различия во временной шкале по сравнению с текущим мастером (Alexander Kukushkin)

    Ранее Patroni имел фиксированный набор условий для запуска pg_rewind, а именно при запуске бывшего мастера, при переключении на узел, назначенный для каждого узла в кластере, или при наличии реплики с тегом “nofollow”. Все эти случаи имеют общим признаком возможность того, что какая-либо реплика может опережать новый мастер. В некоторых случаях pg_rewind не выполнялся, в других – не работал, когда это было необходимо. Вместо того, чтобы полагаться на этот ограниченный список правил, Patroni должен сравнивать позиции мастера и реплики WAL (используя протокол потоковой репликации), чтобы надежно определить, требуется ли перемотка для реплики.

Строгий режим синхронной репликации

  • Улучшить поддержку синхронной репликации путем добавления режима строгой проверки (James Sewell, Alexander Kukushkin)

    Обычно, когда , synchronous_mode и включены, и нет реплик, подключенных к мастеру, Patroni отключает синхронное репликацию, чтобы мастер оставался доступным для записи. Опция synchronous_mode_strict изменяет это: когда она установлена, Patroni не отключает синхронную репликацию в отсутствие реплик, что фактически блокирует всех клиентов, пытающихся записывать данные в мастер. Кроме гарантии предотвращения потери данных из-за автоматического переключения при отказе, строгий режим обеспечивает, что каждая запись либо надежно сохраняется на двух узлах, либо не происходит вообще, если в кластере только один узел.

Редактирование конфигурации с помощью patronictl

  • Добавьте возможность редактирования конфигурации через patronictl (Ants Aasma, Alexander Kukushkin)

    Добавьте возможность редактирования динамической конфигурации кластера, хранящейся в DCS, с использованием patronictl. Поддерживайте указание параметров/значений из командной строки, вызов $EDITOR, или применение конфигурации из файла YAML.

Поддержка сторожевого таймера Linux

  • Реализуйте поддержку сторожевого таймера для Linux (Ants Aasma)

    Поддержка программного сторожевого таймера Linux позволяет перезагрузить узел, на котором не работает Patroni или на который не отвечает (e.g, например, из-за высокой нагрузки). Программный сторожевой таймер Linux перезагружает неработающий узел. Можно настроить устройство сторожевого таймера (/dev/watchdog по умолчанию) и режим (on, automatic, off) в разделе watchdog конфигурации Patroni. Дополнительную информацию можно найти в документации по сторожевому таймеру .

Добавлена поддержка PostgreSQL 10

  • Patroni совместим со всеми выпущенными ранее бета-версиями PostgreSQL 10, и мы ожидаем, что он будет совместим с PostgreSQL 10, когда она будет выпущена.

Небольшие улучшения, связанные с PostgreSQL

  • Определите pg_hba через файл конфигурации Patroni или динамическую конфигурацию в DCS (Alexander Kukushkin)

    Разрешить определение содержимого pg_hba.conf в подразделе pg_hba раздела postgresql конфигурации. Это упрощает управление pg_hba.conf на нескольких узлах, поскольку необходимо определить его только один раз в DCS вместо ведения журнала на каждом узле, ручного изменения и перезагрузки конфигурации.

    Когда определено, содержимое этого раздела полностью заменит текущее pg_hba.conf. Patroni игнорирует его, если параметр PostgreSQL hba_file установлен.

  • Поддержка подключения через сокет UNIX к локальному кластеру PostgreSQL (Alexander Kukushkin)

    Добавьте опцию use_unix_socket в раздел postgresql конфигурации Patroni. При установке в значение true и при условии, что опция PostgreSQL unix_socket_directories не пуста, Patroni использует первое значение из неё для подключения к локальному кластеру PostgreSQL. Если unix_socket_directories не определено, Patroni предполагает его значение по умолчанию и полностью опускает параметр host в строке подключения к PostgreSQL.

  • Поддержка изменения учетных данных суперпользователя и репликации при перезагрузке (Alexander Kukushkin)

  • Поддержка хранения файлов конфигурации вне каталога данных PostgreSQL (@jouir)

    Добавьте новый параметр конфигурации postgresql config_dir. По умолчанию он указывает на каталог данных и должен быть доступен для записи Patroni.

Исправления ошибок и повышение стабильности

  • Обрабатывать исключения EtcdEventIndexCleared и EtcdWatcherCleared (Alexander Kukushkin)

    Более быстрое восстановление при завершении операции наблюдения etcd, избегая ненужных повторных попыток.

  • Устранить вращение индикатора ошибки при сбое etcd и уменьшить количество шума в логах (Ants Aasma)

    Избегайте немедленных повторных попыток и вывода трассировок в лог при повторных сбоях соединения с etcd на втором и последующих этапах.

  • Экспортируйте переменные локали при создании процессов PostgreSQL (Oleksii Kliukin)

    Избегайте postmaster became multithreaded during startup критической ошибки при использовании неанглийских локалей для PostgreSQL, собранной с NLS.

  • Дополнительные проверки при удалении слота репликации (Alexander Kukushkin)

    В некоторых случаях Patroni не может удалить слот репликации из-за WAL.

  • Укоротить имя слота репликации до 63 символов (NAMEDATALEN – 1) для соответствия правилам именования PostgreSQL (Nick Scott)

  • Устранить ситуацию гонки, в результате которой Patroni открывает избыточные соединения к кластеру PostgreSQL (Alexander Kukushkin)

  • Освободите ключ лидера, когда узел перезапускается с пустой директорией данных (Alex Kerney)

  • Установить состояние “занято” для асинхронного исполнителя при выполнении начальной инициализации без лидера (Alexander Kukushkin)

    Невыполнение этого требования могло привести к ошибкам, указывающим на то, что узел принадлежит другому кластеру. Patroni продолжал работать в обычном режиме, выполняя начальную инициализацию методом, который не требует присутствия лидера в кластере.

  • Улучшить способ создания WAL-E реплик (Joar Wandborg, Alexander Kukushkin).

    • Используйте csv.DictReader при обработке базовой резервной копии WAL-E, принимая даты ISO в формате с разделением даты и времени пробелом.
    • Поддержка получения текущей позиции WAL с реплики для оценки объёма WAL, подлежащего восстановлению. Ранее код вызывал системные функции информации, доступные только на основном узле.

Версия 1.2

Выпущено 2016-12-13

Эта версия вносит значительные улучшения в обработку синхронной репликации, делает процесс запуска и переключения более надежным, добавляет поддержку PostgreSQL 9.6 и устраняет множество ошибок. Кроме того, документация, включая эти примечания к релизу, была перемещена в .

Синхронная репликация

  • Добавьте поддержку синхронной репликации. (Ants Aasma)

    Добавляет новую переменную конфигурации synchronous_mode . При включении, Patroni будет управлять synchronous_standby_names для обеспечения синхронной репликации, когда доступны здоровые резервные серверы. При включении синхронного режима, Patroni автоматически переключается только на резервный сервер, который осуществлял синхронную репликацию в момент отказа основного сервера. Это означает, что в таком случае никакие транзакции, видимые пользователю, не будут потеряны. Подробное описание и сведения об реализации смотрите в документации к данной функции .

Повышение надёжности

  • Не пытайтесь обновлять положение лидера, хранящееся в ключе leader optime, когда PostgreSQL не находится в состоянии 100% здоровья. Немедленно понижайте при неудаче обновления ключа лидера. (Alexander Kukushkin)

  • Исключить нездоровые узлы из списка целевых для клонирования новой реплики. (Alexander Kukushkin)

  • Реализуйте стратегию повторных попыток и тайм-аута для Consul, аналогичную той, которая используется для etcd. (Alexander Kukushkin)

  • Применить --dcs и --config-file ко всем опциям в patronictl . (Alexander Kukushkin)

  • Запишите все параметры PostgreSQL в postgresql.conf. (Alexander Kukushkin)

    Оно позволяет запустить PostgreSQL, настроенный с помощью Patroni, используя только pg_ctl.

  • Избегайте исключений, когда в конфигурации нет пользователей. (Kirill Pushkin)

  • Разрешить приостановку неработоспособного кластера. До этого исправления patronictl завершался с ошибкой, если узел, на котором выполнялась команда приостановки, был неработоспособным. (Alexander Kukushkin)

  • Улучшить функциональность мониторинга лидера. (Alexander Kukushkin)

    Ранее реплики постоянно следили за ключом лидера (ожидая истечения тайм-аута или изменения ключа лидера). С этой модификацией они отслеживают состояние только тогда, когда PostgreSQL реплики находится в состоянии running, а не когда PostgreSQL останавливается/запускается или перезапускается.

  • Избегайте возникновения гонок состояний при обработке SIGCHILD как PID 1. (Alexander Kukushkin)

    Ранее могла возникать ситуация гонки при работе внутри контейнеров Docker, поскольку один и тот же процесс в Patroni одновременно создавал новые процессы и обрабатывал сигналы от них. Эта модификация использует fork/exec для Patroni и оставляет исходный процесс SIGCHILD PID 1 ответственным за обработку сигналов от дочерних процессов.

  • Исправить WAL-E восстановление. (Oleksii Kliukin)

    Ранее WAL-E восстановление использовало флаг no_master для полного избегания обращения к мастеру, что заставляло Patroni всегда выбирать восстановление из WAL через pg_basebackup. Данное изменение возвращает no_master исходное значение, а именно: восстановление WAL-E может быть выбрано в качестве метода репликации, если мастер не запущен. Проверка этого условия осуществляется путём анализа строки соединения, переданной методу. Кроме того, механизм повторных попыток стал более устойчивым, а также обрабатываются и другие нюансы.

  • Реализуйте асинхронный DNS кэш для разрешения. (Alexander Kukushkin)

    Избегайте сбоев, когда DNS временно недоступен (например, из-за чрезмерного трафика, поступающего на узел).

  • Реализовать начальное состояние и тайм-аут запуска мастера. (Ants Aasma, Alexander Kukushkin)

    Ранее pg_ctl ждал истечения таймаута и затем считал, что PostgreSQL работает. Это приводило к тому, что PostgreSQL отображался как работающий, хотя на самом деле он был не активен, и вызывало гонку, в результате которой происходило либо переключение при отказе, либо восстановление, либо восстановление, прерванное переключением, и пропуск операции перемотки. Этот изменения добавляет параметр master_start_timeout и вводит новое состояние для основного цикла HA: starting. Когда master_start_timeout имеет значение 0, мы немедленно переключаемся на резервный сервер при отказе основного сервера, как только появляется кандидат на переключение. В противном случае Patroni будет ожидать после попытки запуска PostgreSQL на основном сервере в течение таймаута; при истечении таймаута, если это возможно, происходит переключение. Ручные запросы на переключение будут выполнены даже при отказе основного сервера до истечения таймаута.

    Внедрите параметр timeout в конечную точку restart, API и patronictl . Когда он установлен, и перезапуск занимает больше времени, чем тайм-аут, PostgreSQL считается нездоровым, и другие узлы становятся доступными для получения блокировки лидера.

  • Исправить поведение pg_rewind в режиме паузы. (Ants Aasma)

    Избегайте необоснованных перезапусков в режиме паузы, когда Patroni считает необходимым выполнить откат, но откат невозможен (i.e. pg_rewind отсутствует). Возвращайтесь к значениям по умолчанию libpq для superuser (пользователь ОС по умолчанию), если отсутствует аутентификация superuser в разделе конфигурации Patroni, связанном с pg_rewind.

  • Сериализовать выполнение обратного вызова. Завершить предыдущий обратный вызов того же типа перед запуском нового. Устранить проблему возникновения “зомби” процессов при выполнении обратных вызовов. (Alexander Kukushkin)

  • Не рекомендуется назначать прежнего лидера, когда ключ лидера установлен в DCS, но обновление до этого ключа не удается. (Alexander Kukushkin)

    Это позволяет избежать ситуации, когда текущий мастер продолжает выполнять свою роль, даже когда он разделен вместе с небольшим количеством узлов в etcd и других DCS, которые позволяют “несогласованные чтения”.

Разное

  • Добавьте опцию post_init конфигурации на начальной инициализации. (Alejandro Martínez)

    Patroni вызовет аргумент скрипта этой опции сразу после выполнения initdb и запуска PostgreSQL для нового кластера. Скрипт получает соединение URL с superuser и устанавливает PGPASSFILE для указания на файл .pgpass, содержащий пароль. Если скрипт завершится неудачно, инициализация Patroni также завершится неудачно. Это полезно для добавления новых пользователей или создания расширений в новом кластере.

  • Реализовать поддержку PostgreSQL 9.6. (Alexander Kukushkin)

    Используйте wal_level = replica в качестве синонима для hot_standby, избегая флага pending_restart при переключении между ними. (Александр Кукушкин)

Улучшения документации

  • Добавьте диаграмму основного цикла работы Patroni loop workflow diagram . (Alejandro Martínez, Alexander Kukushkin)

  • Улучшить README, добавив Helm-шаблон и ссылки на примечания к релизу. (Lauri Apple)

  • Переместите документацию Patroni в Read the Docs. Актуальная документация доступна по адресу . (Oleksii Kliukin)

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

  • Перенесите пакет в систему версионирования по семантике. (Oleksii Kliukin)

    Patroni будет следовать схеме major.minor.patch версий, чтобы избежать выпуска новой версии с небольшими, но критическими исправлениями ошибок. Мы будем публиковать только примечания к выпуску для этой версии, которые будут включать все исправления.


Версия 1.1

Выпущено 2016-09-07

Этот выпуск улучшает управление кластером Patroni путем введения режима паузы, улучшает обслуживание с помощью запланированных и условных перезапусков, делает взаимодействие Patroni с etcd или Zookeeper более надежным и значительно улучшает patronictl.

Уведомление об обновлении

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

Режим паузы

  • Внедрите режим паузы для временного отсоединения Patroni от управления экземпляром PostgreSQL (Murat Kabilov, Alexander Kukushkin, Oleksii Kliukin).

    Ранее, для остановки Patroni без завершения работы PostgreSQL, необходимо было отправить сигнал SIGKILL. Новый режим паузы отключает Patroni от кластера PostgreSQL без завершения работы Patroni. Он аналогичен режиму обслуживания в Pacemaker. Patroni по-прежнему отвечает за обновление ключей участника и лидера DCS, но не будет запускать, останавливать или перезапускать сервер PostgreSQL в процессе. Существуют некоторые исключения, например, ручные переключения, перезагрузки и перезапуски все еще разрешены. Вы можете ознакомиться с подробным описанием этой функции .

Кроме того, patronictl поддерживает новые команды pause и resume для переключения режима паузы.

Запланированные и условные перезапуски

  • Добавьте условия к команде перезапуска API (Oleksii Kliukin)

    Эта модификация улучшает перезапуск Patroni путем добавления нескольких условий, которые можно проверить для выполнения перезапуска. Среди этих условий — перезапуск, когда роль PostgreSQL является либо мастером, либо репликой, проверка номера версии PostgreSQL или перезапуск только в случае необходимости применения изменений конфигурации.

  • Добавьте запланированные перезапуски (Oleksii Kliukin)

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

  • Добавить поддержку условных и запланированных перезапусков для patronictl (Мурат Кабилов).

    patronictl restart поддерживает несколько новых опций. Также существует команда patronictl flush для очистки запланированных действий.

Надёжное взаимодействие с DCS

  • Установите значения тайм-аута для Kazoo в соответствии с loop_wait (Alexander Kukushkin)

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

    Данный набор изменений устанавливает значения тайм-аута для операций ping и соединения равными половине значения loop_wait, что ускоряет обнаружение проблем с соединением и оставляет достаточно времени для повторной попытки соединения, прежде чем потеряется блокировка.

  • Обновлять топологию etcd только после успешного выполнения исходного запроса (Alexander Kukushkin)

    Отложите обновление топологии кластера, известной клиенту, до завершения исходного запроса. При получении топологии кластера, реализуйте тайм-ауты повторных попыток, в зависимости от известного количества узлов в кластере etcd. Это позволяет нашему клиенту отдавать предпочтение получению результатов запроса, а не актуальному списку узлов.

    Оба изменения делают соединения Patroni с DCS более надежными в условиях проблем с сетью.

Patronictl, мониторинг и конфигурация

  • Предоставлять информацию о потоковых репликах через API (Feike Steenbergen)

Ранее не существовало надёжного способа запросить у Patroni сведения об экземплярах PostgreSQL, которым не удаётся передавать изменения потоком, например из-за проблем с соединением. Теперь содержимое pg_stat_replication предоставляется через конечную точку /patroni REST API.

  • Добавить команду Patroni-ctl scaffold (Oleksii Kliukin)

    Добавьте команду для создания структуры кластера в etcd. Кластер создается с использованием указанного пользователем sysid и лидера, а также ключи “лидер” и “участник” становятся постоянными. Эта команда полезна для создания конфигураций, называемых “мастер-мене”, где кластер Patroni, состоящий только из реплик, реплицируется от внешнего мастер-узла, который не использует Patroni. Впоследствии можно удалить ключ “лидер”, повысив один из узлов Patroni и заменив исходный мастер-узел кластером Patroni с высокой доступностью.

  • Добавьте опцию конфигурации bin_dir для определения местоположения исполняемых файлов PostgreSQL (Ants Aasma)

    Будет полезно указывать местоположение исполняемых файлов PostgreSQL явно, когда используются дистрибутивы Linux, поддерживающие одновременную установку нескольких версий PostgreSQL.

  • Разрешить переопределение пути к файлу конфигурации с помощью custom_conf (Alejandro Martínez)

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

Исправления ошибок и улучшения кода

  • Сделайте Patroni совместимым с новой схемой версии в PostgreSQL 10 и выше (Feike Steenbergen)

    Убедитесь, что Patroni правильно распознает номера версий в формате 2 при выполнении условного перезапуска на основе версии PostgreSQL.

  • Используйте pkgutil для поиска DCS модулей (Alexander Kukushkin)

    Используйте специализированный модуль Python вместо ручного обхода каталогов для поиска DCS модулей.

  • Всегда вызывайте функцию обратного вызова on_start при запуске Patroni (Alexander Kukushkin)

    Ранее Patroni не вызывал никаких обратных вызовов при подключении к уже работающему узлу с правильной ролью. Так как обратные вызовы часто используются для маршрутизации клиентских соединений, что может привести к неудаче регистрации работающего узла в схеме маршрутизации соединений. С этой поправкой Patroni вызывает on_start обратный вызов даже при подключении к уже работающему узлу.

  • Не удаляйте активные слоты репликации (Murat Kabilov, Oleksii Kliukin)

    Избегайте удаления активных слотов репликации на основном сервере. PostgreSQL не может удалить такие слоты. Эта модификация позволяет запускать реплики/потребителей, управляемые не Patroni, на основном сервере.

  • Закрывайте соединения Patroni при запуске экземпляра PostgreSQL (Alexander Kukushkin)

    Принуждает Patroni закрывать все предыдущие соединения при запуске узла PostgreSQL. Предотвращает ситуацию, когда старые соединения используются повторно, если процесс postmaster был завершен SIGKILL.

  • Заменять недопустимые символы при создании имен слотов на основе имен участников (Ants Aasma)

    Убедитесь, что имена резервных серверов, которые не соответствуют правилам именования слотов, не приводят к неудаче создания слота и запуска резервного сервера. Замените дефисы в именах слотов на подчеркивания, а все остальные символы, не разрешенные в именах слотов, на их Unicode-коды.


Версия 1.0

Выпущено 2016-07-05

Этот выпуск представляет глобальную динамическую конфигурацию, которая позволяет динамически изменять параметры конфигурации PostgreSQL и Patroni для всего кластера высокой доступности. Он также содержит многочисленные исправления ошибок.

Уведомление об обновлении

При обновлении с версии v0.90 или ниже, всегда обновляйте все реплики перед основным сервером. Поскольку мы больше не храним учетные данные для репликации в DCS, старая реплика не сможет подключиться к новому основному серверу.

Динамическая конфигурация

  • Реализуйте динамическую глобальную конфигурацию (Alexander Kukushkin)

    Внедрите новый конечный REST API эндпоинт /config для предоставления параметров конфигурации PostgreSQL и Patroni, которые должны быть установлены глобально для всего кластера HA (мастера и всех реплик). Эти параметры устанавливаются в DCS и, во многих случаях, могут быть применены без нарушения работы PostgreSQL или Patroni. Patroni устанавливает специальный флаг под названием “ожидающий перезапуск”, который отображается через API, когда некоторые значения требуют перезапуска PostgreSQL. В этом случае, перезапуск следует инициировать вручную через API.

    Patroni SIGHUP или POST для /reload заставит перечитать файл конфигурации.

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

    Формат файла конфигурации изменился с v0.90. Patroni по-прежнему совместим с устаревшими файлами конфигурации, но для использования параметров начальной инициализации необходимо их изменить. Пользователям рекомендуется обновить файлы, обратившись к странице документации по динамической конфигурации .

Более гибкая конфигурация*

  • Сделайте конфигурацию PostgreSQL и имя базы данных, к которой подключается Patroni, настраиваемыми (Misja Hoebe)

    Внедрите параметры database и config_base_name конфигурации. В частности, это позволяет запускать Patroni с PipelineDB и другими версиями PostgreSQL.

  • Реализовать возможность настраивать некоторые параметры конфигурации Patroni через переменные окружения (Alexander Kukushkin)

    Сюда входят область действия, имя узла и пространство имён, а также секреты, что упрощает запуск Patroni в динамической среде, i.e. Kubernetes. Подробности см. в поддерживаемых переменных среды .

  • Обновите встроенный контейнер Patroni, чтобы использовать конфигурацию, основанную на окружении (Feike Steenbergen).

  • Добавьте поддержку Zookeeper в образе Docker Patroni (Alexander Kukushkin)

  • Разделите параметры конфигурации Zookeeper и Exhibitor (Alexander Kukushkin)

  • Сделайте, чтобы patronictl использовал код из Patroni для чтения конфигурации (Alexander Kukushkin)

    Это позволяет patronictl использовать конфигурацию, основанную на окружении.

  • Установите имя приложения равным имени узла в primary_conninfo (Alexander Kukushkin)

    Это упрощает идентификацию и настройку синхронной репликации для данного узла.

Повышение стабильности, безопасности и удобства использования

  • Сбросьте sysid и не вызывайте pg_controldata во время восстановления резервной копии (Alexander Kukushkin)

    Эта модификация уменьшает количество шума, генерируемого проверками состояния Patroni API во время длительной инициализации данного узла из резервной копии.

  • Исправить ряд краевых случаев pg_rewind (Alexander Kukushkin)

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

    Кроме того, избегайте удаления каталога данных при неудачной перемотке, если параметр remove_data_directory_on_rewind_failure не установлен в значение true. По умолчанию он установлен в значение false.

  • Удалите пароли из строки соединения для репликации DCS (Alexander Kukushkin)

    Ранее Patroni всегда использовал учетные данные для репликации из Postgres URL в DCS. Теперь используется учетные данные, указанные в конфигурации Patroni. Секреты (имя пользователя и пароль для репликации) больше не хранятся в DCS.

  • Устраните асинхронные механизмы, связанные с вызовом demote (Alexander Kukushkin)

    Функция Demote теперь полностью асинхронно выполняется, не блокируя DCS взаимодействия.

  • Убедитесь, что patronictl всегда отправляет заголовок авторизации, если это настроено (Alexander Kukushkin)

    Это позволяет patronictl отправлять “защищенные” запросы, i.e, а также перезапускать или переинициализировать Patroni, когда Patroni настроен на требование авторизации для этих операций.

  • Обрабатывать исключение SystemExit корректно (Alexander Kukushkin)

    Избегает проблем, связанных с неправильным завершением работы Patroni при получении SIGTERM

  • Образцы конфигурационных файлов для confd (Alexander Kukushkin)

    Генерирует и динамически изменяет конфигурацию HAProxy на основе состояния Patroni, используя Confide DCS

  • Улучшить и перестроить документацию, чтобы она была более понятной для новых пользователей (Lauri Apple)

  • API необходимо сообщать значение role=master во время остановки pg_ctl (Alexander Kukushkin)

    Делает вызовы обратного вызова более надежными, особенно в случае остановки кластера. Кроме того, вводит опцию pg_ctl_timeout для установки тайм-аута для вызовов старта, остановки и перезапуска через pg_ctl.

  • Исправьте логику повторных попыток в etcd (Alexander Kukushkin)

    Сделайте повторные попытки более предсказуемыми и надежными.

  • Сделайте код Zookeeper более устойчивым к кратковременным проблемам в сети (Alexander Kukushkin)

    Уменьшите время ожидания соединения, чтобы делать попытки соединения с Zookeeper чаще.


Версия 0.90

Выпущено 2016-04-27

Этот выпуск добавляет поддержку Consul, включает новую метку noloadbalance, изменяет поведение метки clonefrom, улучшает обработку pg_rewind и улучшает контроль программы patronictl.

Поддержка Consul

  • Реализовать поддержку Consul (Alexander Kukushkin)

    Patroni работает с Consul, а также с etcd и Zookeeper. Параметры соединения можно настроить в файле YAML.

Новые и улучшенные теги

  • Реализовать тег noloadbalance (Alexander Kukushkin)

    Этот тег заставляет Patroni всегда возвращать информацию о том, что реплика недоступна для балансировщика нагрузки.

  • Измените реализацию тега clonefrom (Alexander Kukushkin)

    Ранее требовалось указывать имя узла для команды clonefrom, что приводило к тому, что тегированная реплика клонировалась именно с указанного узла. Новая реализация делает clonefrom булевым тегом: если он установлен в значение true, реплика становится кандидатом для клонирования с других реплик. При наличии нескольких кандидатов, реплики выбирают один случайным образом.

Повышение стабильности и безопасности

  • Множество улучшений в области надежности (Alexander Kukushkin)

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

  • Улучшить скрипт системы, чтобы избежать завершения процессов Patroni при остановке (Jan Keirse, Alexander Kukushkin)

    Ранее, при остановке Patroni, systemd также отправлял сигнал в PostgreSQL. Поскольку Patroni также пытался остановить PostgreSQL самостоятельно, это приводило к отправке различных запросов на завершение работы (умное завершение, за которым следовало быстрое завершение). Это приводило к преждевременному отключению реплик и невозможности восстановления бывшего мастера после понижения. Исправление, предложенное Jan, с предварительными исследованиями Александра.

  • Устранить некоторые случаи, когда предыдущий мастер не мог вызвать pg_rewind перед повторным присоединением в качестве реплики (Oleksii Kliukin)

    Ранее мы вызывали pg_rewind только в случае, когда предыдущий мастер вышел из строя. Измените это, чтобы всегда запускать pg_rewind для предыдущего мастера, при условии, что pg_rewind присутствует в системе. Это устраняет ситуацию, когда мастер завершается до того, как реплики получают последние изменения (i.e во время “умного” завершения работы).

  • Значительные улучшения в тестах, включая тесты для единиц и приемки, в частности, позволяют использовать Zookeeper и Consul (Александр Кукушкин).

  • Сделать Travis CI более быстрым и реализовать поддержку выполнения тестов против Zookeeper (Exhibitor) и Consul (Alexander Kukushkin)

    Оба теста, проверки соответствия и приемки, выполняются автоматически против etcd, Zookeeper и Consul при каждой коммитке или запросе на слияние.

  • Убедитесь, что переменные окружения установлены правильно, прежде чем выполнять команды PostgreSQL через Patroni (Feike Steenbergen)

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

Изменения конфигурации и управления

  • Объединить конфигурацию patronictl и Patroni (Feike Steenbergen)

    patronictl может использовать ту же конфигурацию, что и Patroni.

  • Включить Patroni для чтения конфигурации из переменных окружения (Oleksii Kliukin)

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

  • Включите идентификатор системы баз данных в информацию, возвращаемую API (Feike Steenbergen)

  • Реализуйте delete_cluster для всех доступных кластеров (Alexander Kukushkin)

    Включает поддержку DCS, отличных от etcd, в patronictl.


Версия 0.80

Выпущено 2016-03-14

Этот выпуск добавляет поддержку распределенной репликации и упрощает управление Patroni, предоставляя плановое переключение. Можно использовать более старые версии Patroni (в частности, 0.78) в сочетании с этой, чтобы перейти на новую версию. Примечание: функции, связанные с плановым переключением и распределенной репликацией, будут работать только с Patroni 0.80 и выше.

Каскадная репликация

  • Добавить поддержку тегов replicatefrom и clonefrom для узла Patroni (Олексий Клиукин).

Тег replicatefrom позволяет реплике использовать произвольный узел в качестве источника, не обязательно основной. Тег clonefrom делает то же самое для первоначальной резервной копии. Вместе они позволяют Patroni полностью поддерживать каскадное реплицирование.

  • Добавить поддержку запуска методов репликации для инициализации реплики даже без активного соединения для репликации (Олексий Клиукин).

Это полезно для создания реплик из снимков, хранящихся в S3 или FTP. Метод репликации, который не требует активного соединения для репликации, должен содержать no_master: true в конфигурации YAML. Эти скрипты будут вызываться, если соединение для репликации присутствует.

Улучшения Patronictl, API и DCS

  • Реализуйте запланированные переключения при отказе (Feike Steenbergen).

    Переключения при отказе могут быть запланированы на определённое время в будущем с помощью patronictl или вызовов API.

  • Добавьте поддержку параметров dbuser и password в команде patronictl (Feike Steenbergen).

  • Добавить версию PostgreSQL в вывод проверки работоспособности (Feike Steenbergen).

  • Улучшить поддержку Zookeeper в patronictl (Oleksandr Shulgin)

  • Перейти на python-etcd 0.43 (Alexander Kukushkin)

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

  • Добавить пример скрипта конфигурации для Patroni (Jan Keirse).
  • Исправить проблему, при которой Patroni игнорирует имя суперпользователя, указанное в файле конфигурации для соединений с базой данных (Alexander Kukushkin).
  • Исправить обработку CTRL-C путем создания отдельного идентификатора сессии и группы процессов для postmaster, запущенного Patroni (Alexander Kukushkin).

Тесты

  • Добавьте тесты на приемлемость с использованием behave, чтобы проверить реальные сценарии работы Patroni (Александр Кукушкин, Алексей Клиукин).

    Тесты можно запускать вручную с помощью команды behave. Они также запускаются автоматически для запросов на слияние и после коммитов.

    Информация о выпуске для некоторых старых версий может быть найдена на странице проекта в GitHub .

20 - Рекомендации по участию в разработке

Рабочий процесс внесения изменений, каналы поддержки и рекомендации по разработке.


Общение

Если у вас есть вопрос, нужна интерактивная помощь в устранении неполадок или хочется пообщаться с другими пользователями Patroni, присоединяйтесь к каналу #patroni в PostgreSQL Slack .


Сообщение об ошибках

Перед сообщением об ошибке обязательно воспроизведите её в последней версии Patroni. Также проверьте, не зарегистрирована ли проблема в нашем трекере .


Запуск тестов

Требования для запуска тестов behave:

  1. Должны быть установлены пакеты PostgreSQL, включая модули contrib .
  2. Двоичные файлы PostgreSQL должны быть доступны в PATH. Возможно, их потребуется добавить командой наподобие PATH=/usr/lib/postgresql/11/bin:\$PATH python -m behave.
  3. Для тестирования с внешними DCS, например Etcd, Consul и Zookeeper, необходимо установить пакеты и запустить соответствующие службы, принимающие незашифрованные и незащищённые соединения на localhost и порту по умолчанию. Для Etcd или Consul набор тестов behave может запустить службы самостоятельно, если двоичные файлы доступны в PATH.

Установите зависимости:

# You may want to use Virtualenv or specify pip3.
pip install -r requirements.txt
pip install -r requirements.dev.txt

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

# You may want to use Virtualenv or specify python3.

# Run flake8 to check syntax and formatting:
python setup.py flake8

# Run the pytest suite in tests/:
python setup.py test

# Moreover, you may want to run tests in different scopes for debugging purposes,
# the -s option include print output during test execution.
# Tests in pytest typically follow the pattern: FILEPATH::CLASSNAME::TESTNAME.
pytest -s tests/test_api.py
pytest -s tests/test_api.py::TestRestApiHandler
pytest -s tests/test_api.py::TestRestApiHandler::test_do_GET

# Run the behave (https://behave.readthedocs.io/en/latest/) test suite in features/;
# modify DCS as desired (raft has no dependencies so is the easiest to start with):
DCS=raft python -m behave

Тестирование с tox

Для запуска тестов tox нужно установить только одну зависимость помимо Python:

pip install tox>=4

Для запуска тестов behave также необходим docker.

Конфигурация Tox в tox.ini содержит «окружения» для следующих задач:

  • lint: проверка кода Python с помощью flake8
  • test: модульные тесты со всеми доступными интерпретаторами Python через pytest; создаёт отчёты XML или HTML при обнаружении TTY
  • dep: обнаружение конфликтов зависимостей пакетов с помощью pipdeptree
  • type: статическая проверка типов с помощью pyright
  • black: форматирование кода с помощью black
  • docker-build: сборка образа docker для окружения behave
  • docker-cmd: выполнение произвольной команды с созданным образом
  • docker-behave-etcd: запуск tox для тестов behave с созданным образом
  • py*behave: запуск behave с доступными интерпретаторами Python без docker, хотя именно он вызывается внутри контейнеров docker
  • docs: сборка документации с помощью sphinx

Запуск tox

Чтобы запустить список окружений по умолчанию — dep, lint, test и docs, выполните:

tox

Окружения test можно запустить с меткой `test`:

tox -m test

Тесты docker behave можно запустить с меткой `behave`:

tox -m behave

Аналогично, документация имеет метку docs.

Остальные окружения запускаются по соответствующим именам:

tox -e lint
tox -e py39-test-lin

Частичные списки окружений можно выбирать с помощью factors. Например, для запуска всех окружений Python 3.10:

tox -f py310

Это эквивалентно запуску всех перечисленных ниже окружений:

$ tox -l -f py310
py310-test-lin
py310-test-mac
py310-test-win
py310-type-lin
py310-type-mac
py310-type-win
py310-behave-etcd-lin
py310-behave-etcd-win
py310-behave-etcd-mac

Все настроенные сочетания окружений tox (>=v4) можно вывести так:

tox l

Окружения test и docs после завершения задания пытаются открыть выходные файлы HTML, если tox запущен в активном терминале. Это удобно разработчику при локальном запуске: на mac выполняется open, а в Linux — xdg-open. Чтобы использовать другую команду, задайте переменной окружения OPEN_CMD имя или путь команды. Неудача этого шага не приводит к неудаче всего запуска. Чтобы отключить возможность, задайте OPEN_CMD команду-пустышку :.

OPEN_CMD=: tox -m docs

Тесты behave

Тесты behave с -m behave собирают образы docker на основе версий PG_MAJOR с 11 по 16, а затем запускают все тесты behave. Это может занять много времени, поэтому область проверки можно ограничить выбранной версией Postgres, определённым набором возможностей или шагами.

Чтобы указать версию postgres, включите полное имя нужного зависимого окружения сборки образа, а затем имя окружения behave. Например, для Postgres 14 используйте:

tox -e pg14-docker-build,pg14-docker-behave-etcd-lin

Чтобы протестировать определённую возможность, можно передать behave позиционные аргументы. Следующая команда запускает сценарий тестирования функции watchdog со всеми версиями Postgres.

tox -m behave -- features/watchdog.feature

Разумеется, оба подхода можно сочетать.


Отправка pull request

  1. Создайте ответвление репозитория, разработайте и протестируйте изменения кода.
  2. Отразите изменения в пользовательской документации.
  3. Отправьте pull request с ясным описанием цели изменений. При необходимости добавьте ссылку на существующую проблему.

Обратная связь по pull request будет предоставлена как можно скорее.

Успешной разработки Patroni ;-)